diff --git a/.dockerignore b/.dockerignore index f6906185ff..4a7598c925 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ docker-machine* -.git +*.log +bin +cover \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..4ba6becf0c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ + + +## Description + + + +## Related issue(s) + + diff --git a/.gitignore b/.gitignore index 5c68393170..f20d3a6e6a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -docker-machine* +*.log +*.iml +.idea/ +/bin/ +cover diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..0fa77afb25 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,49 @@ +image: docker + +stages: +- validate +- build + +services: +- docker:dind + +variables: + USE_CONTAINER: "true" + DOCKER_HOST: tcp://docker:2375 + DOCKER_DRIVER: overlay + +before_script: +- apk add -U make bash + +.build_base: &build_base + stage: build + before_script: + - apk add -U make bash + - export TARGET_OS=$(echo $CI_JOB_NAME | cut -d ' ' -f 1) + - export TARGET_ARCH=$(echo $CI_JOB_NAME | cut -d ' ' -f 2) + after_script: + - "[[ \"$(find bin -type f -name docker-machine*)\" != \"\" ]]" + artifacts: + paths: + - bin/ + expire_in: 1 week + tags: + - docker + - privileged + +.build_validate: &build_validate + <<: *build_base + stage: validate + script: make build validate + +.build_x: &build_x + <<: *build_base + script: make build-x + +darwin amd64: *build_x +linux amd64: *build_validate +openbsd amd64: *build_x +windows amd64: *build_x +linux arm: *build_x +linux arm64: *build_x + diff --git a/.travis.yml b/.travis.yml index 7ce858ba9c..1bfa1de604 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,15 @@ -language: go -sudo: false -go: -- 1.3 +sudo: required +dist: trusty +language: bash +services: docker +env: + matrix: + - TARGET_OS=darwin TARGET_ARCH=amd64 TARGETS="build-x" + - TARGET_OS=linux TARGET_ARCH=amd64 TARGETS="build validate" + - TARGET_OS=openbsd TARGET_ARCH=amd64 TARGETS="build-x" + - TARGET_OS=windows TARGET_ARCH=amd64 TARGETS="build-x" + - TARGET_OS=linux TARGET_ARCH=arm TARGETS="build-x" + - TARGET_OS=linux TARGET_ARCH=arm64 TARGETS="build-x" script: -- script/validate-dco -- script/validate-gofmt -- go test -v -short ./... + - USE_CONTAINER=true make "$TARGETS" + - "[[ \"$(find bin -type f -name docker-machine*)\" != \"\" ]]" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..42fc3a6b9a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,892 @@ +# Changelog + +# 0.16.0 (2018-11-08) + +### General + +- The default storage driver has been updated to `overlay2` for several systems +- Improved error reporting for the `ssh` subcommand when using the `--native-ssh` flag + +### Drivers + +**amazonec2** + +- Improved handling of VPC errors + +**openstack** + +- Machine removal no longer fails upon attempting to delete a non-existing keypair + +# 0.15.0 (2018-06-12) + +## General + +- `docker-machine` can now be installed using `go install`. +- Now built with go 1.10 +- Added keep-alive to SSH connections (#4450) + +## Drivers + +### amazonec2 + +- Updated default AMIs to mitigate Meltdown and Spectre +- Added `--amazonec2-security-group-readonly` flag to prevent mutating security groups + +### exoscale + +- Updated driver to v0.9.23 + +### hyperv + +- Fixed Hyper-V pre-create issues (#4426) +- Added the ability to disable Hyper-V dynamic memory management during VM creation (`--hyperv-disable-dynamic-memory`) + +### vmwarefusion + +- Improved shell checks (#4491) + + +# 0.14.0 (2018-03-06) + +## General + +* Added `--client-certs` flag to the `docker-machine regenerate-certs` command. +* Improved OpenBSD support +* Fixed a bug with `scp` commands issued from a Windows host. +* Enabled progress output by default for `scp` commands using `rsync` +* Added `--quiet` flag to `scp` to suppress progress output +* Machine now uses the `ss` command to detect connectivity when `netstat` is unavailable +* Added bash completion for `docker-machine mount` +* Improved provisioning resilience on Debian-based hosts + +## Drivers + +`amazonec2` +* Added support for `eu-west-3` region +* Upon failure, the `create` command now ensures dangling resources are cleaned up before exiting +* Machine creation no longer fails when waiting on spot instance readiness + +`digitalocean` +* Added `--digitalocean-monitoring` flag +* Increased the default droplet size + +`exoscale` +* Updated driver library +* Several improvements and fixes to the default machine template +* Added support for user-provided SSH key (`--exoscale-ssh-key`) +* Added support for arbitrary disk size + +`google` +* Enabled disk auto-deletion on newly created machines +* Fixed a bug preventing the removal of a machine if it had already been removed remotely. +* Added support for fully qualified network and subnetwork names + +`hyperv` +* Fixed potential cmdlet collision with VMWare powercli +* Fixed a bug with virtual switch selection +* Machine now correctly detects if the user is a Hyper-V administrator when using a localized version of Windows + +`openstack` +* Added `--openstack-config-drive` flag +* Fixed an issue causing some user-uploaded keypairs to be removed when removing the associated machine. +* Fixed a bug preventing the removal of a machine if it had already been removed remotely. + +`virtualbox` +* Added OpenBSD support + +`vmwarefusion` +* Improved error detection and reporting when creating a new instance + +`vmwarevsphere` +* Added `--vmwarevsphere-folder` flag + + +# 0.13.0 (2017-10-12) + +General + +- Added new `docker-machine mount` command for mounting machine directories over SSHFS +- Improved some logging messages +- Fixed a bug with the `scp` command when using an identity file. +- Fixed a parsing error that caused the boot2docker ISO cache to malfunction, forcing a new download everytime. + +Drivers + +- `azure` + - `docker-machine rm` now also cleans up the associated storage account if it has no remaining storage containers. + - The creation process will no longer recreate the associated subnet if it already it exists. +- `exoscale` + - Updated driver + - Removed default `docker-machine` affinity group if no other affinity group was specified +- `virtualbox` + - Fixed a bug where the machine would sometimes be assigned an invalid IP address at creation time. +- `vmwaresphere` + - Added support for multiple networks + +# 0.12.2 (2017-7-12) + +General + +* The `scp` sub-command now allows to provide an optional `user@` to the address. +* Fixed bash completion on OS X + +Drivers + +* `amazonec2` + * Updated default AMIs to the latest version of Ubuntu 16.04 LTS + * Fixed a bug preventing proper machine removal +* `vmwarevsphere` + * Creating VMs on a DRS-enabled cluster should now work properly + * Fixed a bug that prevented provisioning +* `vmwarefusion` + * Fixed a bug that prevented provisioning +* `exoscale` + * Updated library + +# 0.12.1 (2017-6-30) + +General + +- Fixed an issue with the version comparison function that prevented machines created with Engine 17.06.0 from starting properly. + +# 0.12.0 (2017-6-5) + +General + +- Various bash completion improvements +- Bump Go to version 1.8.3 + +Drivers + +- `openstack` + - Enable `HTTP_PROXY` +- `digitalocean` + - Add support for tagging +- `virtualbox` + - Scope DHCP address range based on CIDR +- `generic` + - Increase default timeout +- `google` + - Add subnetwork support + +Provisioners + +- Remove restriction on `--engine-install-url` in default-to-boot2docker drivers (`virtualbox`, `vmwarefusion`, etc.) +- Reduce provisioning time of SUSE/openSUSE systems + +# 0.11.0 (2017-4-25) + +General + +- Various bugfixes and updated library dependencies +- new `docker-machine scp --delta` to invoke `rsync` behind the scenes for more efficient transfer + +Drivers + +- `digitalocean` + - Add support for tagging DigitalOcean instances. +- `google` + - Add support for subnetworks + +# 0.10.0 (2017-2-27) + +General + +- Various improvements to shell tab completion +- Add support for compiling on ARM64 architecture + +Drivers + +- Make `virtualbox` default driver +- `amazonec2` + - Update AMIs to latest version of Ubuntu 16.04 LTS +- `virtualbox` + - Fix parsing of `--virtualbox-share-folder` on Windows +- `google` + - Add `--google-open-port` flag to specify additional ports to open + +Provisioners + +- Machine now uses systemd drop-in files instead of over-writing the system units +- Add support for upgrade to new Docker versioning scheme +- Use `dockerd` only in Docker versions where it is available +- Support multiple architectures in SUSE provisioner + +# 0.9.0 (2017-1-17) + +General +- On Windows, the `COMPOSE_CONVERT_WINDOWS_PATHS` environment variable is now set by `docker-machine env` to improve Compose usability. +- Docker Machine can now be built on FreeBSD +- `docker-machine scp` non-22 port support +- `scp` supports SSH agent +- Bump Go version to 1.7.4 + +Drivers +- `amazonec2` + - Credentials can now be loaded from IAM instance profiles + - Add `--amazonec2-userdata` flag + - Add `--amazonec2-block-duration-minutes` flag + - Add support for `us-east-2` (Ohio) + - Update base images to Ubuntu 16.04 +- `azure` + - Add `--azure-dns` flag for specifying DNS names + - Add `--azure-storage-type` flag + - Allow using vnets from another resource group + - Add AzureGermanCloud support + - Add support for custom data + - Support Service Principal authentication + - Update base images to Ubuntu 16.04 +- `digitalocean` + - Add ability to speicify the private SSH key path +- `gce` + - Update base images to Ubuntu 16.04 +- `virtualbox` + - Shared folder location can be specified instead of "hardcoded" to `C:\Users` or `/Users` +- `openstack` + - Add support for `OS_CACERT` + +Provisioners +- OpenSUSE provisioner refactored to use properly supported 3rd party code + + +# 0.8.2 (2016-8-26) + +- Update Go version to 1.7.1 + +# 0.8.1 (2016-8-20) + +Provisioners +- Fix issue with generated systemd service file on RedHat family distros +Drivers +- `azure` + - Bump Ubuntu image to 16.04 + - Update docs with updated default parameters + - Change logging slightly + +# 0.8.0 (2016-6-14) + +General +- Fix issue with plugin heartbeat log repeating on disconnect +- Add `tcsh` support to `env --shell` +- Add `zsh` completion scripts +- Bump Go version to 1.6.2 + +Drivers +- `amazonec2` + - Workaround to prevent orphaned SSH keys +- `virtualbox` + - Add option for VM UI type (`--virtualbox-ui-type`) +- `vmwarefusion` + - Fix CPU option inconsistency +- `openstack` + - Expose user data parameter (`--openstack-user-data-file`) +- `generic` + - Copy public key to created Machine directory + +Provisioners +- Add Oracle Enterprise Linux support +- Fix port binding of Swarm master +- Add ability to create a manager instance which does not get scheduled on +- Introduce `--swarm-join-opt` to pass options to agent nodes +- Various SSH-related fixes +- Fix state for upgrade path + +# 0.7.0 (2016-4-13) + +General +- `DRIVER` environment variable now supported to supply value for `create --driver` flag +- Update to Go 1.6.1 +- SSH client has been refactored +- RC versions of Machine will now create and upgrade to boot2docker RCs instead + of stable versions if available + +Drivers +- `azure` + - Driver has been completely re-written to use resource templates and a significantly easier-to-use authentication model +- `digitalocean` + - New `--digitalocean-ssh-key-fingerprint` for using existing SSH keys instead of creating new ones +- `virtualbox` + - Fix issue with `bootlocal.sh` + - New `--virtualbox-nictype` flag to set driver for NAT network + - More robust host-only interface collision detection + - Add support for running VirtualBox on a Windows 32 bit host + - Change default DNS passthrough handling +- `amazonec2` + - Specifying multiple security groups to use is now supported +- `exoscale` + - Add support for user-data +- `hyperv` + - Machines can now be created by a non-administrator +- `rackspace` + - New `--rackspace-active-timeout` parameter +- `vmwarefusion` + - Bind mount shared folder directory by default +- `google` + - New `--google-use-internal-ip-only` parameter + +Provisioners +- General + - Support for specifying Docker engine port in some cases +- CentOS + - Now defaults to using upstream `get.docker.com` script instead of custom RPMs. +- boot2docker + - More robust eth* interface detection +- Swarm + - Add `--swarm-experimental` parameter to enable experimental Swarm features + + +# 0.6.0 (2016-02-04) + ++ Fix SSH wait before provisioning issue + +# 0.6.0-rc4 (2016-02-03) + +General + ++ `env` + + Fix shell auto detection + +Drivers + ++ `exoscale` + + Fix configuration of exoscale endpoint + +# 0.6.0-rc3 (2016-02-01) + +- Exit with code 3 if error is during pre-create check + +# 0.6.0-rc2 (2016-01-28) + +- Fix issue creating Swarms +- Fix `ls` header issue +- Add code to wait for Docker daemon before returning from `start` / `restart` +- Start porting integration tests to Go from BATS +- Add Appveyor for Windows tests +- Update CoreOS provisioner to use `docker daemon` +- Various documentation and error message fixes +- Add ability to create GCE machine using existing VM + +# 0.6.0-rc1 (2016-01-18) + +General + +- Update to Go 1.5.3 +- Short form of command invocations is now supported + - `docker-machine start`, `docker-machine stop` and others will now use + `default` as the machine name argument if one is not specified +- Fix issue with panics in drivers +- Machine now returns exit code 3 if the pre-create check fails. + - This is potentially useful for scripting `docker-machine`. +- `docker-machine provision` command added to allow re-running of provisioning + on instances. + - This allows users to re-run provisioning if it fails during `create` + instead of needing to completely start over. + +Provisioning + +- Most provisioners now use `docker daemon` instead of `docker -d` +- Swarm masters now run with replication enabled +- If `/var/lib` is a BTRFS partition, `btrfs` will now be used as the storage + driver for the instance + +Drivers + +- Amazon EC2 + - Default VPC will be used automatically if none is specified + - Credentials are now be read from the conventional `~/.aws/credentials` + file automatically + - Fix a few issues such as nil pointer dereferences +- VMware Fusion + - Try to get IP from multiple DHCP lease files +- OpenStack + - Only derive tenant ID if tenant name is supplied + +# 0.5.6 (2016-01-11) + +General + +- `create` + - Set swarm master to advertise on port 3376 + - Fix swarm restart policy + - Stop asking for ssh key passwords interactively +- `env` + - Improve documentation + - Fix bash on windows + - Automatic shell detection on Windows +- `help` + - Don't show the full path to `docker-machine.exe` on windows +- `ls` + - Allow custom format + - Improve documentation +- `restart` + - Improve documentation +- `rm` + - Improve documentation + - Better user experience when removing multiple hosts +- `version` + - Don't show the full path to `docker-machine.exe` on windows +- `start`, `stop`, `restart`, `kill` + - Better logs and homogeneous behaviour across all drivers + +Build + +- Introduce CI tests for external binary compatibility +- Add amazon EC2 integration test + +Misc + +- Improve BugSnags reports: better shell detection, better windows version detection +- Update DockerClient dependency +- Improve bash-completion script +- Improve documentation for bash-completion + +Drivers + +- Amazon EC2 + - Improve documentation + - Support optional tags + - Option to create EbsOptimized instances +- Google + - Fix remove when instance is stopped +- Openstack + - Flags to import and reuse existing nova keypairs +- VirtualBox + - Fix multiple bugs related to host-only adapters + - Retry commands when `VBoxManage` is not ready + - Reject VirtualBox versions older that 4.3 + - Fail with a clear message when Hyper-v installation prevents VirtualBox from working + - Print a warning for Boot2Docker v1.9.1, which is known to have an issue with AUFS +- Vmware Fusion + - Support soft links in VM paths + +Libmachine + +- Fix code sample that uses libmachine +- libmachine can be used in external applications + + +# 0.5.5 (2015-12-28) + +General + +- `env` + - Better error message if swarm is down + - Add quotes to command if there are spaces in the path + - Fix Powershell env hints + - Default to cmd shell on windows + - Detect fish shell +- `scp` + - Ignore empty ssh key +- `stop`, `start`, `kill` + - Add feedback to the user +- `rm` + - Now works when `config.json` is not found +- `ssh` + - Disable ControlPath + - Log which SSH client is used +- `ls` + - Listing is now faster by reducing calls to the driver + - Shows if the active machine is a swarm cluster + +Build + +- Automate 90% of the release process +- Upgrade to Go 1.5.2 +- Don't build 32bits binaries for Linux and OSX +- Prevent makefile from defaulting to using containers + +Misc + +- Update docker-machine version +- Updated the bash completion with new options added +- Bugsnag: Retrieve windows version on non-English OS + +Drivers + +- Amazon EC2 + - Convert API calls to official SDK + - Make DeviceName configurable +- Digital Ocean + - Custom SSH port support +- Generic + - Don't support `kill` since `stop` is not supported +- Google + - Coreos provisionning +- Hyper-V + - Lot's of code simplifications + - Pre-Check that the user is an Administrator + - Pre-Check that the virtual switch exists + - Add Environment variables for each flag + - Fix how Powershell is detected + - VSwitch name should be saved to config.json + - Add a flag to set the CPU count + - Close handle after copying boot2docker.iso into vm folder - will otherwise keep hyper-v from starting vm + - Update Boot2Docker cache in PreCreateCheck phase +- OpenStack + - Filter floating IPs by tenant ID +- Virtualbox + - Reject duplicate hostonlyifs Name/IP with clear message + - Detect when hostonlyif can't be created. Point to known working version of VirtualBox + - Don't create the VM if no hardware virtualization is available and add a flag to force create + - Add `VBox.log` to bugsnag crashreport + - Update Boot2Docker cache in PreCreateCheck phase + - Detect Incompatibility with Hyper-v +- VSphere + - Rewrite driver to work with govmomi instead of wrapping govc +- All + - Change host restart to use the driver implementation + - Fix truncated logs + - Increase heartbeat interval and timeout + +Provisioners + +- Download latest Boot2Docker if it is out-of-date +- Add swarm config to coreos +- All provisioners now honor `engine-install-url` + +# 0.5.4 (2015-12-28) + +This is a patch release to fix a regression with STDOUT/STDERR behavior (#2587). + +# 0.5.3 (2015-12-14) + +**Please note**: With this release Machine will be reverting back to distribution in a single binary, which is more efficient on bandwidth and hard disk space. All the core driver plugins are now included in the main binary. You will want to delete the old driver binaries that you might have in your path. + +e.g.: + +```console +$ rm /usr/local/bin/docker-machine-driver-{amazonec2,azure,digitalocean,exoscale,generic,google,hyperv,none,openstack,rackspace,softlayer,virtualbox,vmwarefusion,vmwarevcloudair,vmwarevsphere} +``` + +Non-core driver plugins should still work as intended (in externally distributed binaries of the form `docker-machine-driver-name`. Please report any issues you encounter them with externally loaded plugins. + +General + +- Optionally report crashes to Bugsnag to help us improve docker-machine +- Fix multiple nil dereferences in `docker-machine ls` command +- Improve the build and CI +- `docker-machine env` now supports emacs +- Run Swarm containers in provisioning step using Docker API instead of SSH/shell +- Show docker daemon version in `docker-machine ls` +- `docker-machine ls` can filter by engine label +- `docker-machine ls` filters are case insensitive +- `--timeout` flag for `docker-machine ls` +- Logs use `logrus` library +- Swarm container network is now `host` +- Added advertise flag to Swarm manager template +- Fix `help` flag for `docker-machine ssh` +- Add confirmation `-y` flag to `docker-machine rm` +- Fix `docker-machine config` for fish +- Embed all core drivers in `docker-machine` binary to reduce the bundle from 120M to 15M + +Drivers + +- Generic + - Support password protected ssh keys though ssh-agent + - Support DNS names +- Virtualbox + - Show a warning if virtualbox is too old + - Recognize yet another Hardware Virtualization issue pattern + - Fix Hardware Virtualization on Linux/AMD + - Add the `--virtualbox-host-dns-resolver` flag + - Allow virtualbox DNSProxy override +- Google + - Open firewall port for Swarm when needed +- VMware Fusion + - Explicitly set umask before invoking vmrun in vmwarefusion + - Activate the plugin only on OSX + - Add id/gid option to mount when using vmhgfs + - Fix for vSphere driver boot2docker ISO issues +- Digital Ocean + - Support for creating Droplets with Cloud-init User Data +- Openstack + - Sanitize keynames by replacing dots with underscores +- All + - Most base images are now set to `Ubuntu 15.10` + - Fix compatibility with drivers developed with docker-machine 0.5.0 + - Better error report for broken/incompatible drivers + - Don't break `config.json` configuration when the disk is full + +Provisioners + +- Increase timeout for installing boot2docker +- Support `Ubuntu 15.10` + +Misc + +- Improve the documentation +- Update known drivers list + +# 0.5.2 (2015-11-30) + +General + +- Bash autocompletion and helpers fixed +- Remove `RawDriver` from `config.json` - Driver parameters can now be edited + directly again in this file. +- Change fish `env` variable setting to be global +- Add `docker-machine version` command +- Move back to normal `codegangsta/cli` upstream +- `--tls-san` flag for extra SANs + +Drivers + +- Fix `GetURL` IPv6 compatibility +- Add documentation page for available 3rd party drivers +- VirtualBox + - Support for shared folders and virtualization detection on Linux hosts + - Improved detection of invalid host-only interface settings +- Google + - Update default images +- VMware Fusion + - Add option to disable shared folder +- Generic + - New environment variables for flags + +Provisioners + +- Support for Ubuntu >=15.04. This means Ubuntu machines can be created which + work with `overlay` driver of lib network. +- Fix issue with current netstat / daemon availability checking + +# 0.5.1 (2015-11-16) + +- Fixed boot2docker VM import regression +- Fix regression breaking `docker-machine env -u` to unset environment variables +- Enhanced virtualization capability detection and `VBoxManage` path detection +- Properly lock VirtualBox access when running several commands concurrently +- Allow plugins to write to STDOUT without `--debug` enabled +- Fix Rackspace driver regression +- Support colons in `docker-machine scp` filepaths +- Pass environment variables for provisioned Engines to Swarm as well +- Various enhancements around boot2docker ISO upgrade (progress bar, increased timeout) + +# 0.5.0 (2015-11-1) + +- General + - Add pluggable driver model + - Clean up code to be more modular and reusable in `libmachine` + - Add `--github-api-token` for situations where users are getting rate limited + by GitHub attempting to get the current `boot2docker.iso` version + - Various enhancements around the Makefile and build toolchain (still an active WIP) + - Disable SSH multiplex explicitly in commands run with the "External" client + - Show "-" for "inactive" machines instead of nothing + - Make daemon status detection more robust +- Provisioners + - New CoreOS, SUSE, and Arch Linux provisioners + - Fixes around package installation / upgrade code on Debian and Ubuntu +- CLI + - Support for regular expression pattern matching and matching by names in `ls --filter` + - `--no-proxy` flag for `env` (sets `NO_PROXY` in addition to other environment variables) +- Drivers + - `openstack` + - `--openstack-ip-version` parameter + - `--openstack-active-timeout` parameter + - `google` + - fix destructive behavior of `start` / `stop` + - `hyperv` + - fix issues with PowerShell + - `vmwarefusion` + - some issues with shared folders fixed + - `--vmwarefusion-configdrive-url` option for configuration via `cloud-init` + - `amazonec2` + - `--amazonec2-use-private-address` option to use private networking + - `virtualbox` + - Enhancements around robustness of the created host-only network + - Fix IPv6 network mask prefix parsing + - `--virtualbox-no-share` option to disable the automatic home directory mount + - `--virtualbox-hostonly-nictype` and `--virtualbox-hostonly-nicpromisc` for controlling settings around the created hostonly NIC + +# 0.4.1 (2015-08) + +- Fixes `upgrade` functionality on Debian based systems +- Fixes `upgrade` functionality on Ubuntu based systems + +# 0.4.0 (2015-08-11) + +## Updates + +- HTTP Proxy support for Docker Engine +- RedHat distros now use Docker Yum repositories +- Ability to set environment variables in the Docker Engine +- Internal libmachine updates for stability + +## Drivers + +- Google: + - Preemptible instances + - Static IP support + +## Fixes + +- Swarm Discovery Flag is verified +- Timeout added to `ls` command to prevent hangups +- SSH command failure now reports information about error +- Configuration migration updates + +# 0.3.0 (2015-06-18) + +## Features + +- Engine option configuration (ability to configure all engine options) +- Swarm option configuration (ability to configure all swarm options) +- New Provisioning system to allow for greater flexibility and stability for installing and configuring Docker +- New Provisioners + - Rancher OS + - RedHat Enterprise Linux 7.0+ (experimental) + - Fedora 21+ (experimental) + - Debian 8+ (experimental) +- PowerShell support (configure Windows Docker CLI) +- Command Prompt (cmd.exe) support (configure Windows Docker CLI) +- Filter command help by driver +- Ability to import Boot2Docker instances +- Boot2Docker CLI migration guide (experimental) +- Format option for `inspect` command +- New logging output format to improve readability and display across platforms +- Updated "active" machine concept - now is implicit according to `DOCKER_HOST` environment variable. Note: this removes the implicit "active" machine and can no longer be specified with the `active` command. You change the "active" host by using the `env` command instead. +- Specify Swarm version (`--swarm-image` flag) + +## Drivers + +- New: Exoscale Driver +- New: Generic Driver (provision any host with supported base OS and SSH) +- Amazon EC2 + - SSH user is configurable + - Support for Spot instances + - Add option to use private address only + - Base AMI updated to 20150417 +- Google + - Support custom disk types + - Updated base image to v20150316 +- Openstack + - Support for Keystone v3 domains +- Rackspace + - Misc fixes including environment variable for Flavor Id and stability +- Softlayer + - Enable local disk as provisioning option + - Fixes for SSH access errors + - Fixed bug where public IP would always be returned when requesting private + - Add support for specifying public and private VLAN IDs +- VirtualBox + - Use Intel network interface driver (adds great stability) + - Stability fixes for NAT access + - Use DNS pass through + - Default CPU to single core for improved performance + - Enable shared folder support for Windows hosts +- VMware Fusion + - Boot2Docker ISO updated + - Shared folder support + +## Fixes + +- Provisioning improvements to ensure Docker is available +- SSH improvements for provisioning stability +- Fixed SSH key generation bug on Windows +- Help formatting for improved readability + +## Breaking Changes + +- "Short-Form" name reference no longer supported Instead of "docker-machine " implying the active host you must now use docker-machine +- VMware shared folders require Boot2Docker 1.7 + +## Special Thanks + +We would like to thank all contributors. Machine would not be where it is +without you. We would also like to give special thanks to the following +contributors for outstanding contributions to the project: + +- @frapposelli for VMware updates and fixes +- @hairyhenderson for several improvements to Softlayer driver, inspect formatting and lots of fixes +- @ibuildthecloud for rancher os provisioning +- @sthulb for portable SSH library +- @vincentbernat for exoscale +- @zchee for Amazon updates and great doc updates + +# 0.2.0 (2015-04-16) + +Core Stability and Driver Updates + +## Core + +- Support for system proxy environment +- New command to regenerate TLS certificates + - Note: this will restart the Docker engine to apply +- Updates to driver operations (create, start, stop, etc) for better reliability +- New internal `libmachine` package for internal api (not ready for public usage) +- Updated Driver Interface + - [Driver Spec](https://github.com/docker/machine/blob/master/docs/DRIVER_SPEC.md) + - Removed host provisioning from Drivers to enable a more consistent install + - Removed SSH commands from each Driver for more consistent operations +- Swarm: machine now uses Swarm default binpacking strategy + +## Driver Updates + +- All drivers updated to new Driver interface +- Amazon EC2 + - Better checking for subnets on creation + - Support for using Private IPs in VPC + - Fixed bug with duplicate security group authorization with Swarm + - Support for IAM instance profile + - Fixed bug where IP was not properly detected upon stop +- DigitalOcean + - IPv6 support + - Backup option + - Private Networking +- Openstack / Rackspace + - Gophercloud updated to latest version + - New insecure flag to disable TLS (use with caution) +- Google + - Google source image updated + - Ability to specify auth token via file +- VMware Fusion + - Paravirtualized driver for disk (pvscsi) + - Enhanced paravirtualized NIC (vmxnet3) + - Power option updates + - SSH keys persistent across reboots + - Stop now gracefully stops VM + - vCPUs now match host CPUs +- SoftLayer + - Fixed provision bug where `curl` was not present +- VirtualBox + - Correct power operations with Saved VM state + - Fixed bug where image option was ignored + +## CLI + +- Auto-regeneration of TLS certificates when TLS error is detected + - Note: this will restart the Docker engine to apply +- Minor UI updates including improved sorting and updated command docs +- Bug with `config` and `env` with spaces fixed + - Note: you now must use `eval $(docker-machine env machine)` to load environment settings +- Updates to better support `fish` shell +- Use `--tlsverify` for both `config` and `env` commands +- Commands now use eval for better interoperability with shell + +## Testing + +- New integration test framework (bats) + +# 0.1.0 (2015-02-26) + +Initial beta release. + +- Provision Docker Engines using multiple drivers +- Provide light management for the machines + - Create, Start, Stop, Restart, Kill, Remove, SSH +- Configure the Docker Engine for secure communication (TLS) +- Easily switch target machine for fast configuration of Docker Engine client +- Provision Swarm clusters (experimental) + +## Included drivers + +- Amazon EC2 +- Digital Ocean +- Google +- Microsoft Azure +- Microsoft Hyper-V +- Openstack +- Rackspace +- VirtualBox +- VMware Fusion +- VMware vCloud Air +- VMware vSphere diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 27311e6466..1516e9d3b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,10 @@ # Contributing to machine +[![GoDoc](https://godoc.org/github.com/docker/machine?status.png)](https://godoc.org/github.com/docker/machine) +[![Build Status](https://travis-ci.org/docker/machine.svg?branch=master)](https://travis-ci.org/docker/machine) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/docker/machine?svg=true)](https://ci.appveyor.com/project/dmp42/machine-fp5u5) +[![Coverage Status](https://coveralls.io/repos/docker/machine/badge.svg?branch=master&service=github)](https://coveralls.io/github/docker/machine?branch=master) + Want to hack on Machine? Awesome! Here are instructions to get you started. @@ -7,7 +12,258 @@ Machine is a part of the [Docker](https://www.docker.com) project, and follows the same rules and principles. If you're already familiar with the way Docker does things, you'll feel right at home. -Otherwise, go read -[Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md). +Otherwise, please read [Docker's contributions +guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md). + +# Building + +The requirements to build Machine are: + +1. A running instance of Docker or a Golang 1.10 development environment +2. The `bash` shell +3. [Make](https://www.gnu.org/software/make/) + +## Build using Docker containers + +To build the `docker-machine` binary using containers, simply run: + + $ export USE_CONTAINER=true + $ make build + +## Local Go development environment + +Make sure the source code directory is under a correct directory structure; +Example of cloning and preparing the correct environment `GOPATH`: + + $ mkdir docker-machine + $ cd docker-machine + $ export GOPATH="$PWD" + $ go get github.com/docker/machine + $ cd src/github.com/docker/machine + +If you want to use your existing workspace, make sure your `GOPATH` is set to +the directory that contains your `src` directory, e.g.: + + $ export GOPATH=/home/yourname/work + $ mkdir -p $GOPATH/src/github.com/docker + $ cd $GOPATH/src/github.com/docker && git clone git@github.com:docker/machine.git + $ cd machine + +At this point, simply run: + + $ make build + +## Built binary + +After the build is complete a `bin/docker-machine` binary will be created. + +You may call: + + $ make clean + +to clean-up build results. + +## Tests and validation + +We use the usual `go` tools for this, to run those commands you need at least the linter which you can +install with `go get -u golang.org/x/lint/golint` + +To run basic validation (dco, fmt), and the project unit tests, call: + + $ make test + +If you want more indepth validation (vet, lint), and all tests with race detection, call: + + $ make validate + +If you make a pull request, it is highly encouraged that you submit tests for +the code that you have added or modified in the same pull request. + +## Code Coverage + +To generate an html code coverage report of the Machine codebase, run: + + make coverage-serve + +And navigate to (hit `CTRL+C` to stop the server). + +### Native build + +Alternatively, if you are building natively, you can simply run: + + make coverage-html + + +## List of all targets + +### High-level targets + + make clean + make build + make test + make validate + +### Advanced build targets + +Build for all supported OSes and architectures (binaries will be in the `bin` project subfolder): + + make build-x + +Build for a specific list of OSes and architectures: + + TARGET_OS=linux TARGET_ARCH="amd64 arm" make build-x + +You can further control build options through the following environment variables: + + DEBUG=true # enable debug build + STATIC=true # build static (note: when cross-compiling, the build is always static) + VERBOSE=true # verbose output + PREFIX=folder # put binaries in another folder (not the default `./bin`) + +Scrub build results: + + make build-clean + +### Coverage targets + + make coverage-html + make coverage-serve + make coverage-send + make coverage-generate + make coverage-clean + +### Tests targets + + make test-short + make test-long + make test-integration + +### Validation targets + + make fmt + make vet + make lint + make dco + +### Managing dependencies + +When you make a fresh copy of the repo, all the dependencies are in `vendor/` directory for the build to work. +This project uses [golang/dep](https://github.com/golang/dep) as vendor management tool. Please refer to `dep` documentation +for further details. + +4. Verify the changes in your repo, commit and submit a pull request + +## Integration Tests + +### Setup + +We use [BATS](https://github.com/sstephenson/bats) for integration testing, so, +first make sure to [install it](https://github.com/sstephenson/bats#installing-bats-from-source). + +### Basic Usage + +You first need to build, calling `make build`. + +You can then invoke integration tests calling `DRIVER=foo make test-integration TESTSUITE`, where `TESTSUITE` is +one of the `test/integration` subfolder, and `foo` is the specific driver you want to test. + +Examples: + +```console +$ DRIVER=virtualbox make test-integration test/integration/core/core-commands.bats + ✓ virtualbox: machine should not exist + ✓ virtualbox: create + ✓ virtualbox: ls + ✓ virtualbox: run busybox container + ✓ virtualbox: url + ✓ virtualbox: ip + ✓ virtualbox: ssh + ✓ virtualbox: docker commands with the socket should work + ✓ virtualbox: stop + ✓ virtualbox: machine should show stopped after stop + ✓ virtualbox: machine should now allow upgrade when stopped + ✓ virtualbox: start + ✓ virtualbox: machine should show running after start + ✓ virtualbox: kill + ✓ virtualbox: machine should show stopped after kill + ✓ virtualbox: restart + ✓ virtualbox: machine should show running after restart + +17 tests, 0 failures +Cleaning up machines... +Successfully removed bats-virtualbox-test +``` + +To invoke a directory of tests recursively: + +```console +$ DRIVER=virtualbox make test-integration test/integration/core/ +... +``` + +### Extra Create Arguments + +In some cases, for instance to test the creation of a specific base OS (e.g. +RHEL) as opposed to the default with the common tests, you may want to run +common tests with different create arguments than you get out of the box. + +Keep in mind that Machine supports environment variables for many of these +flags. So, for instance, you could run the command (substituting, of course, +the proper secrets): + + $ DRIVER=amazonec2 \ + AWS_VPC_ID=vpc-xxxxxxx \ + AWS_SECRET_ACCESS_KEY=yyyyyyyyyyyyy \ + AWS_ACCESS_KEY_ID=zzzzzzzzzzzzzzzz \ + AWS_AMI=ami-12663b7a \ + AWS_SSH_USER=ec2-user \ + make test-integration test/integration/core + +in order to run the core tests on Red Hat Enterprise Linux on Amazon. + +### Layout + +The `test/integration` directory is laid out to divide up tests based on the +areas which the test. If you are uncertain where to put yours, we are happy to +guide you. + +At the time of writing, there is: + +1. A `core` directory which contains tests that are applicable to all drivers. +2. A `drivers` directory which contains tests that are applicable only to + specific drivers with sub-directories for each provider. +3. A `cli` directory which is meant for testing functionality of the command + line interface, without much regard for driver-specific details. + +### Guidelines + +The best practices for writing integration tests on Docker Machine are still a +work in progress, but here are some general guidelines from the maintainers: + +1. Ideally, each test file should have only one concern. +2. Tests generally should not spin up more than one machine unless the test is + deliberately testing something which involves multiple machines, such as an `ls` + test which involves several machines, or a test intended to create and check + some property of a Swarm cluster. +3. BATS will print the output of commands executed during a test if the test + fails. This can be useful, for instance to dump the magic `$output` variable + that BATS provides and/or to get debugging information. +4. It is not strictly needed to clean up the machines as part of the test. The + BATS wrapper script has a hook to take care of cleaning up all created machines + after each test. + +# Drivers + +Docker Machine has several included drivers that supports provisioning hosts +in various providers. If you wish to contribute a driver, we ask the following +to ensure we keep the driver in a consistent and stable state: + +- Address issues filed against this driver in a timely manner +- Review PRs for the driver +- Be responsible for maintaining the infrastructure to run unit tests + and integration tests on the new supported environment +- Participate in a weekly driver maintainer meeting + -Happy hacking! +Note: even if those are met does not guarantee a driver will be accepted. +If you have questions, please do not hesitate to contact us on IRC. diff --git a/Dockerfile b/Dockerfile index 48a1e09de5..53871b0028 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,18 @@ -FROM golang:1.3-cross -RUN apt-get update && apt-get install -y --no-install-recommends openssh-client -RUN go get github.com/mitchellh/gox -RUN go get github.com/aktau/github-release -RUN go get github.com/tools/godep -ENV GOPATH /go/src/github.com/docker/machine/Godeps/_workspace:/go -ENV MACHINE_BINARY /go/src/github.com/docker/machine/docker-machine +FROM golang:1.12.9 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + openssh-client \ + rsync \ + fuse \ + sshfs \ + && rm -rf /var/lib/apt/lists/* + +RUN go get golang.org/x/lint/golint \ + github.com/mattn/goveralls \ + golang.org/x/tools/cover + +ENV USER root WORKDIR /go/src/github.com/docker/machine -ADD . /go/src/github.com/docker/machine + +COPY . ./ +RUN mkdir bin diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json deleted file mode 100644 index 12ebcec841..0000000000 --- a/Godeps/Godeps.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "ImportPath": "github.com/docker/machine", - "GoVersion": "go1.3.3", - "Deps": [ - { - "ImportPath": "code.google.com/p/goauth2/oauth", - "Comment": "weekly-56", - "Rev": "afe77d958c701557ec5dc56f6936fcc194d15520" - }, - { - "ImportPath": "github.com/MSOpenTech/azure-sdk-for-go", - "Comment": "v1.1-14-g814812a", - "Rev": "515f3ec74ce6a5b31e934cefae997c97bd0a1b1e" - }, - { - "ImportPath": "github.com/Sirupsen/logrus", - "Comment": "v0.6.1", - "Rev": "1f2ba2c6317323dd667bd266c1e8ebffc4a4c62f" - }, - { - "ImportPath": "github.com/codegangsta/cli", - "Comment": "1.2.0-64-ge1712f3", - "Rev": "e1712f381785e32046927f64a7c86fe569203196" - }, - { - "ImportPath": "github.com/digitalocean/godo", - "Comment": "v0.5.0", - "Rev": "5478aae80694de1d2d0e02c386bbedd201266234" - }, - { - "ImportPath": "github.com/docker/docker/api", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/dockerversion", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/engine", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/archive", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/fileutils", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/ioutils", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/parsers", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/pools", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/promise", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/system", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/term", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/timeutils", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/units", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/pkg/version", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/utils", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar", - "Comment": "v1.2.0-1619-g831d09f", - "Rev": "831d09f8b535a1e2939bdacb02032d238e8dd249" - }, - { - "ImportPath": "github.com/docker/libtrust", - "Rev": "6b7834910dcbb3021adc193411d01f65595445fb" - }, - { - "ImportPath": "github.com/google/go-querystring/query", - "Rev": "30f7a39f4a218feb5325f3aebc60c32a572a8274" - }, - { - "ImportPath": "github.com/smartystreets/go-aws-auth", - "Rev": "1f0db8c0ee6362470abe06a94e3385927ed72a4b" - }, - { - "ImportPath": "github.com/mitchellh/mapstructure", - "Rev": "740c764bc6149d3f1806231418adb9f52c11bcbf" - }, - { - "ImportPath": "github.com/racker/perigee", - "Comment": "v0.0.0-18-g0c00cb0", - "Rev": "0c00cb0a026b71034ebc8205263c77dad3577db5" - }, - { - "ImportPath": "github.com/rackspace/gophercloud", - "Comment": "v1.0.0-232-g2e7ab37", - "Rev": "2e7ab378257b8723e02cbceac7410be4db286436" - }, - { - "ImportPath": "github.com/tent/http-link-go", - "Rev": "ac974c61c2f990f4115b119354b5e0b47550e888" - }, - { - "ImportPath": "github.com/vmware/govcloudair", - "Comment": "v0.0.1-1-g9672590", - "Rev": "9672590d5e5795b2d29fce97084fd5810665fc27" - }, - { - "ImportPath": "golang.org/x/crypto/ssh", - "Rev": "1fbbd62cfec66bd39d91e97749579579d4d3037e" - }, - { - "ImportPath": "google.golang.org/api/compute/v1", - "Rev": "aa91ac681e18e52b1a0dfe29b9d8354e88c0dcf5" - }, - { - "ImportPath": "google.golang.org/api/googleapi", - "Rev": "aa91ac681e18e52b1a0dfe29b9d8354e88c0dcf5" - } - ] -} diff --git a/Godeps/Readme b/Godeps/Readme deleted file mode 100644 index 4cdaa53d56..0000000000 --- a/Godeps/Readme +++ /dev/null @@ -1,5 +0,0 @@ -This directory tree is generated automatically by godep. - -Please do not edit. - -See https://github.com/tools/godep for more information. diff --git a/Godeps/_workspace/.gitignore b/Godeps/_workspace/.gitignore deleted file mode 100644 index f037d684ef..0000000000 --- a/Godeps/_workspace/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/pkg -/bin diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/example/oauthreq.go b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/example/oauthreq.go deleted file mode 100644 index f9651bd090..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/example/oauthreq.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2011 The goauth2 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This program makes a call to the specified API, authenticated with OAuth2. -// a list of example APIs can be found at https://code.google.com/oauthplayground/ -package main - -import ( - "flag" - "fmt" - "io" - "log" - "os" - - "code.google.com/p/goauth2/oauth" -) - -var ( - clientId = flag.String("id", "", "Client ID") - clientSecret = flag.String("secret", "", "Client Secret") - scope = flag.String("scope", "https://www.googleapis.com/auth/userinfo.profile", "OAuth scope") - redirectURL = flag.String("redirect_url", "oob", "Redirect URL") - authURL = flag.String("auth_url", "https://accounts.google.com/o/oauth2/auth", "Authentication URL") - tokenURL = flag.String("token_url", "https://accounts.google.com/o/oauth2/token", "Token URL") - requestURL = flag.String("request_url", "https://www.googleapis.com/oauth2/v1/userinfo", "API request") - code = flag.String("code", "", "Authorization Code") - cachefile = flag.String("cache", "cache.json", "Token cache file") -) - -const usageMsg = ` -To obtain a request token you must specify both -id and -secret. - -To obtain Client ID and Secret, see the "OAuth 2 Credentials" section under -the "API Access" tab on this page: https://code.google.com/apis/console/ - -Once you have completed the OAuth flow, the credentials should be stored inside -the file specified by -cache and you may run without the -id and -secret flags. -` - -func main() { - flag.Parse() - - // Set up a configuration. - config := &oauth.Config{ - ClientId: *clientId, - ClientSecret: *clientSecret, - RedirectURL: *redirectURL, - Scope: *scope, - AuthURL: *authURL, - TokenURL: *tokenURL, - TokenCache: oauth.CacheFile(*cachefile), - } - - // Set up a Transport using the config. - transport := &oauth.Transport{Config: config} - - // Try to pull the token from the cache; if this fails, we need to get one. - token, err := config.TokenCache.Token() - if err != nil { - if *clientId == "" || *clientSecret == "" { - flag.Usage() - fmt.Fprint(os.Stderr, usageMsg) - os.Exit(2) - } - if *code == "" { - // Get an authorization code from the data provider. - // ("Please ask the user if I can access this resource.") - url := config.AuthCodeURL("") - fmt.Print("Visit this URL to get a code, then run again with -code=YOUR_CODE\n\n") - fmt.Println(url) - return - } - // Exchange the authorization code for an access token. - // ("Here's the code you gave the user, now give me a token!") - token, err = transport.Exchange(*code) - if err != nil { - log.Fatal("Exchange:", err) - } - // (The Exchange method will automatically cache the token.) - fmt.Printf("Token is cached in %v\n", config.TokenCache) - } - - // Make the actual request using the cached token to authenticate. - // ("Here's the token, let me in!") - transport.Token = token - - // Make the request. - r, err := transport.Client().Get(*requestURL) - if err != nil { - log.Fatal("Get:", err) - } - defer r.Body.Close() - - // Write the response to standard output. - io.Copy(os.Stdout, r.Body) - - // Send final carriage return, just to be neat. - fmt.Println() -} diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.client_secrets.json b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.client_secrets.json deleted file mode 100644 index 2ea86f2fc2..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.client_secrets.json +++ /dev/null @@ -1 +0,0 @@ -{"web":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"XXXXXXXXXXXX@developer.gserviceaccount.com","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXX@developer.gserviceaccount.com","client_id":"XXXXXXXXXXXX.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}} diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.pem b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.pem deleted file mode 100644 index 8f78b922d6..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.pem +++ /dev/null @@ -1,20 +0,0 @@ -Bag Attributes - friendlyName: privatekey - localKeyID: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Key Attributes: ------BEGIN PRIVATE KEY----- -XXXXxyXXXXXXXxxyxxxX9y0XXYXXXXYXXxXyxxXxXxXXXyXXXXx4yx1xy1xyYxxY -1XxYy38YxXxxxyXxyyxx+xxxxyx1Y1xYx7yx2/Y1XyyXYYYxY5YXxX0xY/Y642yX -zYYxYXzXYxY0Y8y9YxyYXxxX40YyXxxXX4XXxx7XxXxxXyXxYYXxXyxX5XY0Yy2X -1YX0XXyy6YXyXx9XxXxyXX9XXYXxXxXXXXXXxYXYY3Y8Yy311XYYY81XyY14Xyyx -xXyx7xxXXXxxxxyyyX4YYYXyYyYXyxX4XYXYyxXYyx9xy23xXYyXyxYxXxx1XXXY -y98yX6yYxyyyX4Xyx1Xy/0yxxYxXxYYx2xx7yYXXXxYXXXxyXyyYYxx5XX2xxyxy -y6Yyyx0XX3YYYyx9YYXXXX7y0yxXXy+90XYz1y2xyx7yXxX+8X0xYxXXYxxyxYYy -YXx8Yy4yX0Xyxxx6yYX92yxy1YYYzyyyyxy55x/yyXXXYYXYXXzXXxYYxyXY8XXX -+y9+yXxX7XxxyYYxxXYxyY623xxXxYX59x5Y6yYyXYY4YxXXYXXXYxXYxXxXXx6x -YXX7XxXX2X0XY7YXyYy1XXxYXxXxYY1xXXxxxyy+07zXYxYxxXyyxxyxXx1XYy5X -5XYzyxYxXXYyX9XX7xX8xXxx+XXYyYXXXX5YY1x8Yxyx54Xy/1XXyyYXY5YxYyxY -XyyxXyX/YxxXXXxXXYXxyxx63xX/xxyYXXyYzx0XY+YxX5xyYyyxxxXXYX/94XXy -Xx63xYxXyXY3/XXxyyXX15XXXyz08XYY5YYXY/YXy/96x68XyyXXxYyXy4xYXx5x -7yxxyxxYxXxyx3y= ------END PRIVATE KEY----- diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/main.go b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/main.go deleted file mode 100644 index 2256e9c621..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/main.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2011 The goauth2 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This program makes a read only call to the Google Cloud Storage API, -// authenticated with OAuth2. A list of example APIs can be found at -// https://code.google.com/oauthplayground/ -package main - -import ( - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "log" - "net/http" - "strings" - - "code.google.com/p/goauth2/oauth/jwt" -) - -const scope = "https://www.googleapis.com/auth/devstorage.read_only" - -var ( - secretsFile = flag.String("s", "", "JSON encoded secrets for the service account") - pemFile = flag.String("k", "", "private pem key file for the service account") -) - -const usageMsg = ` -You must specify -k and -s. - -To obtain client secrets and pem, see the "OAuth 2 Credentials" section under -the "API Access" tab on this page: https://code.google.com/apis/console/ - -Google Cloud Storage must also be turned on in the API console. -` - -func main() { - flag.Parse() - - if *secretsFile == "" || *pemFile == "" { - flag.Usage() - fmt.Println(usageMsg) - return - } - - // Read the secret file bytes into the config. - secretBytes, err := ioutil.ReadFile(*secretsFile) - if err != nil { - log.Fatal("error reading secerets file:", err) - } - var config struct { - Web struct { - ClientEmail string `json:"client_email"` - ClientID string `json:"client_id"` - TokenURI string `json:"token_uri"` - } - } - err = json.Unmarshal(secretBytes, &config) - if err != nil { - log.Fatal("error unmarshalling secerets:", err) - } - - // Get the project ID from the client ID. - projectID := strings.SplitN(config.Web.ClientID, "-", 2)[0] - - // Read the pem file bytes for the private key. - keyBytes, err := ioutil.ReadFile(*pemFile) - if err != nil { - log.Fatal("error reading private key file:", err) - } - - // Craft the ClaimSet and JWT token. - t := jwt.NewToken(config.Web.ClientEmail, scope, keyBytes) - t.ClaimSet.Aud = config.Web.TokenURI - - // We need to provide a client. - c := &http.Client{} - - // Get the access token. - o, err := t.Assert(c) - if err != nil { - log.Fatal("assertion error:", err) - } - - // Refresh token will be missing, but this access_token will be good - // for one hour. - fmt.Printf("access_token = %v\n", o.AccessToken) - fmt.Printf("refresh_token = %v\n", o.RefreshToken) - fmt.Printf("expires %v\n", o.Expiry) - - // Form the request to list Google Cloud Storage buckets. - req, err := http.NewRequest("GET", "https://storage.googleapis.com/", nil) - if err != nil { - log.Fatal("http.NewRequest:", err) - } - req.Header.Set("Authorization", "OAuth "+o.AccessToken) - req.Header.Set("x-goog-api-version", "2") - req.Header.Set("x-goog-project-id", projectID) - - // Make the request. - r, err := c.Do(req) - if err != nil { - log.Fatal("API request error:", err) - } - defer r.Body.Close() - - // Write the response to standard output. - res, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Fatal("error reading API request results:", err) - } - fmt.Printf("\nRESULT:\n%s\n", res) -} diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt.go b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt.go deleted file mode 100644 index 61bf5ce936..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt.go +++ /dev/null @@ -1,511 +0,0 @@ -// Copyright 2012 The goauth2 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// The jwt package provides support for creating credentials for OAuth2 service -// account requests. -// -// For examples of the package usage please see jwt_test.go. -// Example usage (error handling omitted for brevity): -// -// // Craft the ClaimSet and JWT token. -// iss := "XXXXXXXXXXXX@developer.gserviceaccount.com" -// scope := "https://www.googleapis.com/auth/devstorage.read_only" -// t := jwt.NewToken(iss, scope, pemKeyBytes) -// -// // We need to provide a client. -// c := &http.Client{} -// -// // Get the access token. -// o, _ := t.Assert(c) -// -// // Form the request to the service. -// req, _ := http.NewRequest("GET", "https://storage.googleapis.com/", nil) -// req.Header.Set("Authorization", "OAuth "+o.AccessToken) -// req.Header.Set("x-goog-api-version", "2") -// req.Header.Set("x-goog-project-id", "XXXXXXXXXXXX") -// -// // Make the request. -// result, _ := c.Do(req) -// -// For info on OAuth2 service accounts please see the online documentation. -// https://developers.google.com/accounts/docs/OAuth2ServiceAccount -// -package jwt - -import ( - "bytes" - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/base64" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "code.google.com/p/goauth2/oauth" -) - -// These are the default/standard values for this to work for Google service accounts. -const ( - stdAlgorithm = "RS256" - stdType = "JWT" - stdAssertionType = "http://oauth.net/grant_type/jwt/1.0/bearer" - stdGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" - stdAud = "https://accounts.google.com/o/oauth2/token" -) - -var ( - ErrInvalidKey = errors.New("Invalid Key") -) - -// base64Encode returns and Base64url encoded version of the input string with any -// trailing "=" stripped. -func base64Encode(b []byte) string { - return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") -} - -// base64Decode decodes the Base64url encoded string -func base64Decode(s string) ([]byte, error) { - // add back missing padding - switch len(s) % 4 { - case 2: - s += "==" - case 3: - s += "=" - } - return base64.URLEncoding.DecodeString(s) -} - -// The JWT claim set contains information about the JWT including the -// permissions being requested (scopes), the target of the token, the issuer, -// the time the token was issued, and the lifetime of the token. -// -// Aud is usually https://accounts.google.com/o/oauth2/token -type ClaimSet struct { - Iss string `json:"iss"` // email address of the client_id of the application making the access token request - Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests - Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional). - Prn string `json:"prn,omitempty"` // email for which the application is requesting delegated access (Optional). - Exp int64 `json:"exp"` - Iat int64 `json:"iat"` - Typ string `json:"typ,omitempty"` - Sub string `json:"sub,omitempty"` // Add support for googleapi delegation support - - // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3 - // This array is marshalled using custom code (see (c *ClaimSet) encode()). - PrivateClaims map[string]interface{} `json:"-"` - - exp time.Time - iat time.Time -} - -// setTimes sets iat and exp to time.Now() and iat.Add(time.Hour) respectively. -// -// Note that these times have nothing to do with the expiration time for the -// access_token returned by the server. These have to do with the lifetime of -// the encoded JWT. -// -// A JWT can be re-used for up to one hour after it was encoded. The access -// token that is granted will also be good for one hour so there is little point -// in trying to use the JWT a second time. -func (c *ClaimSet) setTimes(t time.Time) { - c.iat = t - c.exp = c.iat.Add(time.Hour) -} - -var ( - jsonStart = []byte{'{'} - jsonEnd = []byte{'}'} -) - -// encode returns the Base64url encoded form of the Signature. -func (c *ClaimSet) encode() string { - if c.exp.IsZero() || c.iat.IsZero() { - c.setTimes(time.Now()) - } - if c.Aud == "" { - c.Aud = stdAud - } - c.Exp = c.exp.Unix() - c.Iat = c.iat.Unix() - - b, err := json.Marshal(c) - if err != nil { - panic(err) - } - - if len(c.PrivateClaims) == 0 { - return base64Encode(b) - } - - // Marshal private claim set and then append it to b. - prv, err := json.Marshal(c.PrivateClaims) - if err != nil { - panic(fmt.Errorf("Invalid map of private claims %v", c.PrivateClaims)) - } - - // Concatenate public and private claim JSON objects. - if !bytes.HasSuffix(b, jsonEnd) { - panic(fmt.Errorf("Invalid JSON %s", b)) - } - if !bytes.HasPrefix(prv, jsonStart) { - panic(fmt.Errorf("Invalid JSON %s", prv)) - } - b[len(b)-1] = ',' // Replace closing curly brace with a comma. - b = append(b, prv[1:]...) // Append private claims. - - return base64Encode(b) -} - -// Header describes the algorithm and type of token being generated, -// and optionally a KeyID describing additional parameters for the -// signature. -type Header struct { - Algorithm string `json:"alg"` - Type string `json:"typ"` - KeyId string `json:"kid,omitempty"` -} - -func (h *Header) encode() string { - b, err := json.Marshal(h) - if err != nil { - panic(err) - } - return base64Encode(b) -} - -// A JWT is composed of three parts: a header, a claim set, and a signature. -// The well formed and encoded JWT can then be exchanged for an access token. -// -// The Token is not a JWT, but is is encoded to produce a well formed JWT. -// -// When obtaining a key from the Google API console it will be downloaded in a -// PKCS12 encoding. To use this key you will need to convert it to a PEM file. -// This can be achieved with openssl. -// -// $ openssl pkcs12 -in -nocerts -passin pass:notasecret -nodes -out -// -// The contents of this file can then be used as the Key. -type Token struct { - ClaimSet *ClaimSet // claim set used to construct the JWT - Header *Header // header used to construct the JWT - Key []byte // PEM printable encoding of the private key - pKey *rsa.PrivateKey - - header string - claim string - sig string - - useExternalSigner bool - signer Signer -} - -// NewToken returns a filled in *Token based on the standard header, -// and sets the Iat and Exp times based on when the call to Assert is -// made. -func NewToken(iss, scope string, key []byte) *Token { - c := &ClaimSet{ - Iss: iss, - Scope: scope, - Aud: stdAud, - } - h := &Header{ - Algorithm: stdAlgorithm, - Type: stdType, - } - t := &Token{ - ClaimSet: c, - Header: h, - Key: key, - } - return t -} - -// Signer is an interface that given a JWT token, returns the header & -// claim (serialized and urlEncoded to a byte slice), along with the -// signature and an error (if any occured). It could modify any data -// to sign (typically the KeyID). -// -// Example usage where a SHA256 hash of the original url-encoded token -// with an added KeyID and secret data is used as a signature: -// -// var privateData = "secret data added to hash, indexed by KeyID" -// -// type SigningService struct{} -// -// func (ss *SigningService) Sign(in *jwt.Token) (newTokenData, sig []byte, err error) { -// in.Header.KeyID = "signing service" -// newTokenData = in.EncodeWithoutSignature() -// dataToSign := fmt.Sprintf("%s.%s", newTokenData, privateData) -// h := sha256.New() -// _, err := h.Write([]byte(dataToSign)) -// sig = h.Sum(nil) -// return -// } -type Signer interface { - Sign(in *Token) (tokenData, signature []byte, err error) -} - -// NewSignerToken returns a *Token, using an external signer function -func NewSignerToken(iss, scope string, signer Signer) *Token { - t := NewToken(iss, scope, nil) - t.useExternalSigner = true - t.signer = signer - return t -} - -// Expired returns a boolean value letting us know if the token has expired. -func (t *Token) Expired() bool { - return t.ClaimSet.exp.Before(time.Now()) -} - -// Encode constructs and signs a Token returning a JWT ready to use for -// requesting an access token. -func (t *Token) Encode() (string, error) { - var tok string - t.header = t.Header.encode() - t.claim = t.ClaimSet.encode() - err := t.sign() - if err != nil { - return tok, err - } - tok = fmt.Sprintf("%s.%s.%s", t.header, t.claim, t.sig) - return tok, nil -} - -// EncodeWithoutSignature returns the url-encoded value of the Token -// before signing has occured (typically for use by external signers). -func (t *Token) EncodeWithoutSignature() string { - t.header = t.Header.encode() - t.claim = t.ClaimSet.encode() - return fmt.Sprintf("%s.%s", t.header, t.claim) -} - -// sign computes the signature for a Token. The details for this can be found -// in the OAuth2 Service Account documentation. -// https://developers.google.com/accounts/docs/OAuth2ServiceAccount#computingsignature -func (t *Token) sign() error { - if t.useExternalSigner { - fulldata, sig, err := t.signer.Sign(t) - if err != nil { - return err - } - split := strings.Split(string(fulldata), ".") - if len(split) != 2 { - return errors.New("no token returned") - } - t.header = split[0] - t.claim = split[1] - t.sig = base64Encode(sig) - return err - } - ss := fmt.Sprintf("%s.%s", t.header, t.claim) - if t.pKey == nil { - err := t.parsePrivateKey() - if err != nil { - return err - } - } - h := sha256.New() - h.Write([]byte(ss)) - b, err := rsa.SignPKCS1v15(rand.Reader, t.pKey, crypto.SHA256, h.Sum(nil)) - t.sig = base64Encode(b) - return err -} - -// parsePrivateKey converts the Token's Key ([]byte) into a parsed -// rsa.PrivateKey. If the key is not well formed this method will return an -// ErrInvalidKey error. -func (t *Token) parsePrivateKey() error { - block, _ := pem.Decode(t.Key) - if block == nil { - return ErrInvalidKey - } - parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - return err - } - } - var ok bool - t.pKey, ok = parsedKey.(*rsa.PrivateKey) - if !ok { - return ErrInvalidKey - } - return nil -} - -// Assert obtains an *oauth.Token from the remote server by encoding and sending -// a JWT. The access_token will expire in one hour (3600 seconds) and cannot be -// refreshed (no refresh_token is returned with the response). Once this token -// expires call this method again to get a fresh one. -func (t *Token) Assert(c *http.Client) (*oauth.Token, error) { - var o *oauth.Token - t.ClaimSet.setTimes(time.Now()) - u, v, err := t.buildRequest() - if err != nil { - return o, err - } - resp, err := c.PostForm(u, v) - if err != nil { - return o, err - } - o, err = handleResponse(resp) - return o, err -} - -// buildRequest sets up the URL values and the proper URL string for making our -// access_token request. -func (t *Token) buildRequest() (string, url.Values, error) { - v := url.Values{} - j, err := t.Encode() - if err != nil { - return t.ClaimSet.Aud, v, err - } - v.Set("grant_type", stdGrantType) - v.Set("assertion", j) - return t.ClaimSet.Aud, v, nil -} - -// Used for decoding the response body. -type respBody struct { - IdToken string `json:"id_token"` - Access string `json:"access_token"` - Type string `json:"token_type"` - ExpiresIn time.Duration `json:"expires_in"` -} - -// handleResponse returns a filled in *oauth.Token given the *http.Response from -// a *http.Request created by buildRequest. -func handleResponse(r *http.Response) (*oauth.Token, error) { - o := &oauth.Token{} - defer r.Body.Close() - if r.StatusCode != 200 { - return o, errors.New("invalid response: " + r.Status) - } - b := &respBody{} - err := json.NewDecoder(r.Body).Decode(b) - if err != nil { - return o, err - } - o.AccessToken = b.Access - if b.IdToken != "" { - // decode returned id token to get expiry - o.AccessToken = b.IdToken - s := strings.Split(b.IdToken, ".") - if len(s) < 2 { - return nil, errors.New("invalid token received") - } - d, err := base64Decode(s[1]) - if err != nil { - return o, err - } - c := &ClaimSet{} - err = json.NewDecoder(bytes.NewBuffer(d)).Decode(c) - if err != nil { - return o, err - } - o.Expiry = time.Unix(c.Exp, 0) - return o, nil - } - o.Expiry = time.Now().Add(b.ExpiresIn * time.Second) - return o, nil -} - -// Transport implements http.RoundTripper. When configured with a valid -// JWT and OAuth tokens it can be used to make authenticated HTTP requests. -// -// t := &jwt.Transport{jwtToken, oauthToken} -// r, _, err := t.Client().Get("http://example.org/url/requiring/auth") -// -// It will automatically refresh the OAuth token if it can, updating in place. -type Transport struct { - JWTToken *Token - OAuthToken *oauth.Token - - // Transport is the HTTP transport to use when making requests. - // It will default to http.DefaultTransport if nil. - Transport http.RoundTripper -} - -// Creates a new authenticated transport. -func NewTransport(token *Token) (*Transport, error) { - oa, err := token.Assert(new(http.Client)) - if err != nil { - return nil, err - } - return &Transport{ - JWTToken: token, - OAuthToken: oa, - }, nil -} - -// Client returns an *http.Client that makes OAuth-authenticated requests. -func (t *Transport) Client() *http.Client { - return &http.Client{Transport: t} -} - -// Fetches the internal transport. -func (t *Transport) transport() http.RoundTripper { - if t.Transport != nil { - return t.Transport - } - return http.DefaultTransport -} - -// RoundTrip executes a single HTTP transaction using the Transport's -// OAuthToken as authorization headers. -// -// This method will attempt to renew the token if it has expired and may return -// an error related to that token renewal before attempting the client request. -// If the token cannot be renewed a non-nil os.Error value will be returned. -// If the token is invalid callers should expect HTTP-level errors, -// as indicated by the Response's StatusCode. -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - // Sanity check the two tokens - if t.JWTToken == nil { - return nil, fmt.Errorf("no JWT token supplied") - } - if t.OAuthToken == nil { - return nil, fmt.Errorf("no OAuth token supplied") - } - // Refresh the OAuth token if it has expired - if t.OAuthToken.Expired() { - if oa, err := t.JWTToken.Assert(new(http.Client)); err != nil { - return nil, err - } else { - t.OAuthToken = oa - } - } - // To set the Authorization header, we must make a copy of the Request - // so that we don't modify the Request we were given. - // This is required by the specification of http.RoundTripper. - req = cloneRequest(req) - req.Header.Set("Authorization", "Bearer "+t.OAuthToken.AccessToken) - - // Make the HTTP request. - return t.transport().RoundTrip(req) -} - -// cloneRequest returns a clone of the provided *http.Request. -// The clone is a shallow copy of the struct and its Header map. -func cloneRequest(r *http.Request) *http.Request { - // shallow copy of the struct - r2 := new(http.Request) - *r2 = *r - // deep copy of the Header - r2.Header = make(http.Header) - for k, s := range r.Header { - r2.Header[k] = s - } - return r2 -} diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt_test.go b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt_test.go deleted file mode 100644 index 622843e168..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt_test.go +++ /dev/null @@ -1,486 +0,0 @@ -// Copyright 2012 The goauth2 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// For package documentation please see jwt.go. -// -package jwt - -import ( - "bytes" - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/json" - "encoding/pem" - "io/ioutil" - "net/http" - "testing" - "time" -) - -const ( - stdHeaderStr = `{"alg":"RS256","typ":"JWT"}` - iss = "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com" - scope = "https://www.googleapis.com/auth/prediction" - exp = 1328554385 - iat = 1328550785 // exp + 1 hour -) - -// Base64url encoded Header -const headerEnc = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9" - -// Base64url encoded ClaimSet -const claimSetEnc = "eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ" - -// Base64url encoded Signature -const sigEnc = "olukbHreNiYrgiGCTEmY3eWGeTvYDSUHYoE84Jz3BRPBSaMdZMNOn_0CYK7UHPO7OdvUofjwft1dH59UxE9GWS02pjFti1uAQoImaqjLZoTXr8qiF6O_kDa9JNoykklWlRAIwGIZkDupCS-8cTAnM_ksSymiH1coKJrLDUX_BM0x2f4iMFQzhL5vT1ll-ZipJ0lNlxb5QsyXxDYcxtHYguF12-vpv3ItgT0STfcXoWzIGQoEbhwB9SBp9JYcQ8Ygz6pYDjm0rWX9LrchmTyDArCodpKLFtutNgcIFUP9fWxvwd1C2dNw5GjLcKr9a_SAERyoJ2WnCR1_j9N0wD2o0g" - -// Base64url encoded Token -const tokEnc = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.olukbHreNiYrgiGCTEmY3eWGeTvYDSUHYoE84Jz3BRPBSaMdZMNOn_0CYK7UHPO7OdvUofjwft1dH59UxE9GWS02pjFti1uAQoImaqjLZoTXr8qiF6O_kDa9JNoykklWlRAIwGIZkDupCS-8cTAnM_ksSymiH1coKJrLDUX_BM0x2f4iMFQzhL5vT1ll-ZipJ0lNlxb5QsyXxDYcxtHYguF12-vpv3ItgT0STfcXoWzIGQoEbhwB9SBp9JYcQ8Ygz6pYDjm0rWX9LrchmTyDArCodpKLFtutNgcIFUP9fWxvwd1C2dNw5GjLcKr9a_SAERyoJ2WnCR1_j9N0wD2o0g" - -// Private key for testing -const privateKeyPem = `-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj -7wZgkdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/ -xmVU1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYs -SliS5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18 -pe+zpyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xk -SBc//fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABAoIBAQDGGHzQxGKX+ANk -nQi53v/c6632dJKYXVJC+PDAz4+bzU800Y+n/bOYsWf/kCp94XcG4Lgsdd0Gx+Zq -HD9CI1IcqqBRR2AFscsmmX6YzPLTuEKBGMW8twaYy3utlFxElMwoUEsrSWRcCA1y -nHSDzTt871c7nxCXHxuZ6Nm/XCL7Bg8uidRTSC1sQrQyKgTPhtQdYrPQ4WZ1A4J9 -IisyDYmZodSNZe5P+LTJ6M1SCgH8KH9ZGIxv3diMwzNNpk3kxJc9yCnja4mjiGE2 -YCNusSycU5IhZwVeCTlhQGcNeV/skfg64xkiJE34c2y2ttFbdwBTPixStGaF09nU -Z422D40BAoGBAPvVyRRsC3BF+qZdaSMFwI1yiXY7vQw5+JZh01tD28NuYdRFzjcJ -vzT2n8LFpj5ZfZFvSMLMVEFVMgQvWnN0O6xdXvGov6qlRUSGaH9u+TCPNnIldjMP -B8+xTwFMqI7uQr54wBB+Poq7dVRP+0oHb0NYAwUBXoEuvYo3c/nDoRcZAoGBAOWl -aLHjMv4CJbArzT8sPfic/8waSiLV9Ixs3Re5YREUTtnLq7LoymqB57UXJB3BNz/2 -eCueuW71avlWlRtE/wXASj5jx6y5mIrlV4nZbVuyYff0QlcG+fgb6pcJQuO9DxMI -aqFGrWP3zye+LK87a6iR76dS9vRU+bHZpSVvGMKJAoGAFGt3TIKeQtJJyqeUWNSk -klORNdcOMymYMIlqG+JatXQD1rR6ThgqOt8sgRyJqFCVT++YFMOAqXOBBLnaObZZ -CFbh1fJ66BlSjoXff0W+SuOx5HuJJAa5+WtFHrPajwxeuRcNa8jwxUsB7n41wADu -UqWWSRedVBg4Ijbw3nWwYDECgYB0pLew4z4bVuvdt+HgnJA9n0EuYowVdadpTEJg -soBjNHV4msLzdNqbjrAqgz6M/n8Ztg8D2PNHMNDNJPVHjJwcR7duSTA6w2p/4k28 -bvvk/45Ta3XmzlxZcZSOct3O31Cw0i2XDVc018IY5be8qendDYM08icNo7vQYkRH -504kQQKBgQDjx60zpz8ozvm1XAj0wVhi7GwXe+5lTxiLi9Fxq721WDxPMiHDW2XL -YXfFVy/9/GIMvEiGYdmarK1NW+VhWl1DC5xhDg0kvMfxplt4tynoq1uTsQTY31Mx -BeF5CT/JuNYk3bEBF0H/Q3VGO1/ggVS+YezdFbLWIRoMnLj6XCFEGg== ------END RSA PRIVATE KEY-----` - -// Public key to go with the private key for testing -const publicKeyPem = `-----BEGIN CERTIFICATE----- -MIIDIzCCAgugAwIBAgIJAMfISuBQ5m+5MA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV -BAMTCnVuaXQtdGVzdHMwHhcNMTExMjA2MTYyNjAyWhcNMjExMjAzMTYyNjAyWjAV -MRMwEQYDVQQDEwp1bml0LXRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj7wZgkdmM -7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/xmVU1Wer -uQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYsSliS5qQp -gyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18pe+zpyl4 -+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xkSBc//fy3 -ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABo3YwdDAdBgNVHQ4EFgQU2RQ8yO+O -gN8oVW2SW7RLrfYd9jEwRQYDVR0jBD4wPIAU2RQ8yO+OgN8oVW2SW7RLrfYd9jGh -GaQXMBUxEzARBgNVBAMTCnVuaXQtdGVzdHOCCQDHyErgUOZvuTAMBgNVHRMEBTAD -AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBRv+M/6+FiVu7KXNjFI5pSN17OcW5QUtPr -odJMlWrJBtynn/TA1oJlYu3yV5clc/71Vr/AxuX5xGP+IXL32YDF9lTUJXG/uUGk -+JETpKmQviPbRsvzYhz4pf6ZIOZMc3/GIcNq92ECbseGO+yAgyWUVKMmZM0HqXC9 -ovNslqe0M8C1sLm1zAR5z/h/litE7/8O2ietija3Q/qtl2TOXJdCA6sgjJX2WUql -ybrC55ct18NKf3qhpcEkGQvFU40rVYApJpi98DiZPYFdx1oBDp/f4uZ3ojpxRVFT -cDwcJLfNRCPUhormsY7fDS9xSyThiHsW9mjJYdcaKQkwYZ0F11yB ------END CERTIFICATE-----` - -var ( - privateKeyPemBytes = []byte(privateKeyPem) - publicKeyPemBytes = []byte(publicKeyPem) - stdHeader = &Header{Algorithm: stdAlgorithm, Type: stdType} -) - -// Testing the urlEncode function. -func TestUrlEncode(t *testing.T) { - enc := base64Encode([]byte(stdHeaderStr)) - b := []byte(enc) - if b[len(b)-1] == 61 { - t.Error("TestUrlEncode: last chat == \"=\"") - } - if enc != headerEnc { - t.Error("TestUrlEncode: enc != headerEnc") - t.Errorf(" enc = %s", enc) - t.Errorf(" headerEnc = %s", headerEnc) - } -} - -// Test that the times are set properly. -func TestClaimSetSetTimes(t *testing.T) { - c := &ClaimSet{ - Iss: iss, - Scope: scope, - } - iat := time.Unix(iat, 0) - c.setTimes(iat) - if c.exp.Unix() != exp { - t.Error("TestClaimSetSetTimes: c.exp != exp") - t.Errorf(" c.Exp = %d", c.exp.Unix()) - t.Errorf(" exp = %d", exp) - } -} - -// Given a well formed ClaimSet, test for proper encoding. -func TestClaimSetEncode(t *testing.T) { - c := &ClaimSet{ - Iss: iss, - Scope: scope, - exp: time.Unix(exp, 0), - iat: time.Unix(iat, 0), - } - enc := c.encode() - re, err := base64Decode(enc) - if err != nil { - t.Fatalf("error decoding encoded claim set: %v", err) - } - - wa, err := base64Decode(claimSetEnc) - if err != nil { - t.Fatalf("error decoding encoded expected claim set: %v", err) - } - - if enc != claimSetEnc { - t.Error("TestClaimSetEncode: enc != claimSetEnc") - t.Errorf(" enc = %s", string(re)) - t.Errorf(" claimSetEnc = %s", string(wa)) - } -} - -// Test that claim sets with private claim names are encoded correctly. -func TestClaimSetWithPrivateNameEncode(t *testing.T) { - iatT := time.Unix(iat, 0) - expT := time.Unix(exp, 0) - - i, err := json.Marshal(iatT.Unix()) - if err != nil { - t.Fatalf("error marshaling iatT value of %v: %v", iatT.Unix(), err) - } - iatStr := string(i) - e, err := json.Marshal(expT.Unix()) - if err != nil { - t.Fatalf("error marshaling expT value of %v: %v", expT.Unix(), err) - } - - expStr := string(e) - - testCases := []struct { - desc string - input map[string]interface{} - want string - }{ - // Test a simple int field. - { - "single simple field", - map[string]interface{}{"amount": 22}, - `{` + - `"iss":"` + iss + `",` + - `"scope":"` + scope + `",` + - `"aud":"` + stdAud + `",` + - `"exp":` + expStr + `,` + - `"iat":` + iatStr + `,` + - `"amount":22` + - `}`, - }, - { - "multiple simple fields", - map[string]interface{}{"tracking_code": "axZf", "amount": 22}, - `{` + - `"iss":"` + iss + `",` + - `"scope":"` + scope + `",` + - `"aud":"` + stdAud + `",` + - `"exp":` + expStr + `,` + - `"iat":` + iatStr + `,` + - `"amount":22,` + - `"tracking_code":"axZf"` + - `}`, - }, - { - "nested struct fields", - map[string]interface{}{ - "tracking_code": "axZf", - "purchase": struct { - Description string `json:"desc"` - Quantity int32 `json:"q"` - Time int64 `json:"t"` - }{ - "toaster", - 5, - iat, - }, - }, - `{` + - `"iss":"` + iss + `",` + - `"scope":"` + scope + `",` + - `"aud":"` + stdAud + `",` + - `"exp":` + expStr + `,` + - `"iat":` + iatStr + `,` + - `"purchase":{"desc":"toaster","q":5,"t":` + iatStr + `},` + - `"tracking_code":"axZf"` + - `}`, - }, - } - - for _, testCase := range testCases { - c := &ClaimSet{ - Iss: iss, - Scope: scope, - Aud: stdAud, - iat: iatT, - exp: expT, - PrivateClaims: testCase.input, - } - cJSON, err := base64Decode(c.encode()) - if err != nil { - t.Fatalf("error decoding claim set: %v", err) - } - if string(cJSON) != testCase.want { - t.Errorf("TestClaimSetWithPrivateNameEncode: enc != want in case %s", testCase.desc) - t.Errorf(" enc = %s", cJSON) - t.Errorf(" want = %s", testCase.want) - } - } -} - -// Test the NewToken constructor. -func TestNewToken(t *testing.T) { - tok := NewToken(iss, scope, privateKeyPemBytes) - if tok.ClaimSet.Iss != iss { - t.Error("TestNewToken: tok.ClaimSet.Iss != iss") - t.Errorf(" tok.ClaimSet.Iss = %s", tok.ClaimSet.Iss) - t.Errorf(" iss = %s", iss) - } - if tok.ClaimSet.Scope != scope { - t.Error("TestNewToken: tok.ClaimSet.Scope != scope") - t.Errorf(" tok.ClaimSet.Scope = %s", tok.ClaimSet.Scope) - t.Errorf(" scope = %s", scope) - } - if tok.ClaimSet.Aud != stdAud { - t.Error("TestNewToken: tok.ClaimSet.Aud != stdAud") - t.Errorf(" tok.ClaimSet.Aud = %s", tok.ClaimSet.Aud) - t.Errorf(" stdAud = %s", stdAud) - } - if !bytes.Equal(tok.Key, privateKeyPemBytes) { - t.Error("TestNewToken: tok.Key != privateKeyPemBytes") - t.Errorf(" tok.Key = %s", tok.Key) - t.Errorf(" privateKeyPemBytes = %s", privateKeyPemBytes) - } -} - -// Make sure the private key parsing functions work. -func TestParsePrivateKey(t *testing.T) { - tok := &Token{ - Key: privateKeyPemBytes, - } - err := tok.parsePrivateKey() - if err != nil { - t.Errorf("TestParsePrivateKey:tok.parsePrivateKey: %v", err) - } -} - -// Test that the token signature generated matches the golden standard. -func TestTokenSign(t *testing.T) { - tok := &Token{ - Key: privateKeyPemBytes, - claim: claimSetEnc, - header: headerEnc, - } - err := tok.parsePrivateKey() - if err != nil { - t.Errorf("TestTokenSign:tok.parsePrivateKey: %v", err) - } - err = tok.sign() - if err != nil { - t.Errorf("TestTokenSign:tok.sign: %v", err) - } - if tok.sig != sigEnc { - t.Error("TestTokenSign: tok.sig != sigEnc") - t.Errorf(" tok.sig = %s", tok.sig) - t.Errorf(" sigEnc = %s", sigEnc) - } -} - -// Test that the token expiration function is working. -func TestTokenExpired(t *testing.T) { - c := &ClaimSet{} - tok := &Token{ - ClaimSet: c, - } - now := time.Now() - c.setTimes(now) - if tok.Expired() != false { - t.Error("TestTokenExpired: tok.Expired != false") - } - // Set the times as if they were set 2 hours ago. - c.setTimes(now.Add(-2 * time.Hour)) - if tok.Expired() != true { - t.Error("TestTokenExpired: tok.Expired != true") - } -} - -// Given a well formed Token, test for proper encoding. -func TestTokenEncode(t *testing.T) { - c := &ClaimSet{ - Iss: iss, - Scope: scope, - exp: time.Unix(exp, 0), - iat: time.Unix(iat, 0), - } - tok := &Token{ - ClaimSet: c, - Header: stdHeader, - Key: privateKeyPemBytes, - } - enc, err := tok.Encode() - if err != nil { - t.Errorf("TestTokenEncode:tok.Assertion: %v", err) - } - if enc != tokEnc { - t.Error("TestTokenEncode: enc != tokEnc") - t.Errorf(" enc = %s", enc) - t.Errorf(" tokEnc = %s", tokEnc) - } -} - -// Given a well formed Token we should get back a well formed request. -func TestBuildRequest(t *testing.T) { - c := &ClaimSet{ - Iss: iss, - Scope: scope, - exp: time.Unix(exp, 0), - iat: time.Unix(iat, 0), - } - tok := &Token{ - ClaimSet: c, - Header: stdHeader, - Key: privateKeyPemBytes, - } - u, v, err := tok.buildRequest() - if err != nil { - t.Errorf("TestBuildRequest:BuildRequest: %v", err) - } - if u != c.Aud { - t.Error("TestBuildRequest: u != c.Aud") - t.Errorf(" u = %s", u) - t.Errorf(" c.Aud = %s", c.Aud) - } - if v.Get("grant_type") != stdGrantType { - t.Error("TestBuildRequest: grant_type != stdGrantType") - t.Errorf(" grant_type = %s", v.Get("grant_type")) - t.Errorf(" stdGrantType = %s", stdGrantType) - } - if v.Get("assertion") != tokEnc { - t.Error("TestBuildRequest: assertion != tokEnc") - t.Errorf(" assertion = %s", v.Get("assertion")) - t.Errorf(" tokEnc = %s", tokEnc) - } -} - -// Given a well formed access request response we should get back a oauth.Token. -func TestHandleResponse(t *testing.T) { - rb := &respBody{ - Access: "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", - Type: "Bearer", - ExpiresIn: 3600, - } - b, err := json.Marshal(rb) - if err != nil { - t.Errorf("TestHandleResponse:json.Marshal: %v", err) - } - r := &http.Response{ - Status: "200 OK", - StatusCode: 200, - Body: ioutil.NopCloser(bytes.NewReader(b)), - } - o, err := handleResponse(r) - if err != nil { - t.Errorf("TestHandleResponse:handleResponse: %v", err) - } - if o.AccessToken != rb.Access { - t.Error("TestHandleResponse: o.AccessToken != rb.Access") - t.Errorf(" o.AccessToken = %s", o.AccessToken) - t.Errorf(" rb.Access = %s", rb.Access) - } - if o.Expired() { - t.Error("TestHandleResponse: o.Expired == true") - } -} - -// passthrough signature for test -type FakeSigner struct{} - -func (f FakeSigner) Sign(tok *Token) ([]byte, []byte, error) { - block, _ := pem.Decode(privateKeyPemBytes) - pKey, _ := x509.ParsePKCS1PrivateKey(block.Bytes) - ss := headerEnc + "." + claimSetEnc - h := sha256.New() - h.Write([]byte(ss)) - b, _ := rsa.SignPKCS1v15(rand.Reader, pKey, crypto.SHA256, h.Sum(nil)) - return []byte(ss), b, nil -} - -// Given an external signer, get back a valid and signed JWT -func TestExternalSigner(t *testing.T) { - tok := NewSignerToken(iss, scope, FakeSigner{}) - enc, _ := tok.Encode() - if enc != tokEnc { - t.Errorf("TestExternalSigner: enc != tokEnc") - t.Errorf(" enc = %s", enc) - t.Errorf(" tokEnc = %s", tokEnc) - } -} - -func TestHandleResponseWithNewExpiry(t *testing.T) { - rb := &respBody{ - IdToken: tokEnc, - } - b, err := json.Marshal(rb) - if err != nil { - t.Errorf("TestHandleResponse:json.Marshal: %v", err) - } - r := &http.Response{ - Status: "200 OK", - StatusCode: 200, - Body: ioutil.NopCloser(bytes.NewReader(b)), - } - o, err := handleResponse(r) - if err != nil { - t.Errorf("TestHandleResponse:handleResponse: %v", err) - } - if o.Expiry != time.Unix(exp, 0) { - t.Error("TestHandleResponse: o.Expiry != exp") - t.Errorf(" o.Expiry = %s", o.Expiry) - t.Errorf(" exp = %s", time.Unix(exp, 0)) - } -} - -// Placeholder for future Assert tests. -func TestAssert(t *testing.T) { - // Since this method makes a call to BuildRequest, an htttp.Client, and - // finally HandleResponse there is not much more to test. This is here - // as a placeholder if that changes. -} - -// Benchmark for the end-to-end encoding of a well formed token. -func BenchmarkTokenEncode(b *testing.B) { - b.StopTimer() - c := &ClaimSet{ - Iss: iss, - Scope: scope, - exp: time.Unix(exp, 0), - iat: time.Unix(iat, 0), - } - tok := &Token{ - ClaimSet: c, - Key: privateKeyPemBytes, - } - b.StartTimer() - for i := 0; i < b.N; i++ { - tok.Encode() - } -} diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth.go b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth.go deleted file mode 100644 index 6f1b6c1888..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth.go +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright 2011 The goauth2 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package oauth supports making OAuth2-authenticated HTTP requests. -// -// Example usage: -// -// // Specify your configuration. (typically as a global variable) -// var config = &oauth.Config{ -// ClientId: YOUR_CLIENT_ID, -// ClientSecret: YOUR_CLIENT_SECRET, -// Scope: "https://www.googleapis.com/auth/buzz", -// AuthURL: "https://accounts.google.com/o/oauth2/auth", -// TokenURL: "https://accounts.google.com/o/oauth2/token", -// RedirectURL: "http://you.example.org/handler", -// } -// -// // A landing page redirects to the OAuth provider to get the auth code. -// func landing(w http.ResponseWriter, r *http.Request) { -// http.Redirect(w, r, config.AuthCodeURL("foo"), http.StatusFound) -// } -// -// // The user will be redirected back to this handler, that takes the -// // "code" query parameter and Exchanges it for an access token. -// func handler(w http.ResponseWriter, r *http.Request) { -// t := &oauth.Transport{Config: config} -// t.Exchange(r.FormValue("code")) -// // The Transport now has a valid Token. Create an *http.Client -// // with which we can make authenticated API requests. -// c := t.Client() -// c.Post(...) -// // ... -// // btw, r.FormValue("state") == "foo" -// } -// -package oauth - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "mime" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" -) - -// OAuthError is the error type returned by many operations. -// -// In retrospect it should not exist. Don't depend on it. -type OAuthError struct { - prefix string - msg string -} - -func (oe OAuthError) Error() string { - return "OAuthError: " + oe.prefix + ": " + oe.msg -} - -// Cache specifies the methods that implement a Token cache. -type Cache interface { - Token() (*Token, error) - PutToken(*Token) error -} - -// CacheFile implements Cache. Its value is the name of the file in which -// the Token is stored in JSON format. -type CacheFile string - -func (f CacheFile) Token() (*Token, error) { - file, err := os.Open(string(f)) - if err != nil { - return nil, OAuthError{"CacheFile.Token", err.Error()} - } - defer file.Close() - tok := &Token{} - if err := json.NewDecoder(file).Decode(tok); err != nil { - return nil, OAuthError{"CacheFile.Token", err.Error()} - } - return tok, nil -} - -func (f CacheFile) PutToken(tok *Token) error { - file, err := os.OpenFile(string(f), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return OAuthError{"CacheFile.PutToken", err.Error()} - } - if err := json.NewEncoder(file).Encode(tok); err != nil { - file.Close() - return OAuthError{"CacheFile.PutToken", err.Error()} - } - if err := file.Close(); err != nil { - return OAuthError{"CacheFile.PutToken", err.Error()} - } - return nil -} - -// Config is the configuration of an OAuth consumer. -type Config struct { - // ClientId is the OAuth client identifier used when communicating with - // the configured OAuth provider. - ClientId string - - // ClientSecret is the OAuth client secret used when communicating with - // the configured OAuth provider. - ClientSecret string - - // Scope identifies the level of access being requested. Multiple scope - // values should be provided as a space-delimited string. - Scope string - - // AuthURL is the URL the user will be directed to in order to grant - // access. - AuthURL string - - // TokenURL is the URL used to retrieve OAuth tokens. - TokenURL string - - // RedirectURL is the URL to which the user will be returned after - // granting (or denying) access. - RedirectURL string - - // TokenCache allows tokens to be cached for subsequent requests. - TokenCache Cache - - // AccessType is an OAuth extension that gets sent as the - // "access_type" field in the URL from AuthCodeURL. - // See https://developers.google.com/accounts/docs/OAuth2WebServer. - // It may be "online" (the default) or "offline". - // If your application needs to refresh access tokens when the - // user is not present at the browser, then use offline. This - // will result in your application obtaining a refresh token - // the first time your application exchanges an authorization - // code for a user. - AccessType string - - // ApprovalPrompt indicates whether the user should be - // re-prompted for consent. If set to "auto" (default) the - // user will be prompted only if they haven't previously - // granted consent and the code can only be exchanged for an - // access token. - // If set to "force" the user will always be prompted, and the - // code can be exchanged for a refresh token. - ApprovalPrompt string -} - -// Token contains an end-user's tokens. -// This is the data you must store to persist authentication. -type Token struct { - AccessToken string - RefreshToken string - Expiry time.Time // If zero the token has no (known) expiry time. - - // Extra optionally contains extra metadata from the server - // when updating a token. The only current key that may be - // populated is "id_token". It may be nil and will be - // initialized as needed. - Extra map[string]string -} - -// Expired reports whether the token has expired or is invalid. -func (t *Token) Expired() bool { - if t.AccessToken == "" { - return true - } - if t.Expiry.IsZero() { - return false - } - return t.Expiry.Before(time.Now()) -} - -// Transport implements http.RoundTripper. When configured with a valid -// Config and Token it can be used to make authenticated HTTP requests. -// -// t := &oauth.Transport{config} -// t.Exchange(code) -// // t now contains a valid Token -// r, _, err := t.Client().Get("http://example.org/url/requiring/auth") -// -// It will automatically refresh the Token if it can, -// updating the supplied Token in place. -type Transport struct { - *Config - *Token - - // mu guards modifying the token. - mu sync.Mutex - - // Transport is the HTTP transport to use when making requests. - // It will default to http.DefaultTransport if nil. - // (It should never be an oauth.Transport.) - Transport http.RoundTripper -} - -// Client returns an *http.Client that makes OAuth-authenticated requests. -func (t *Transport) Client() *http.Client { - return &http.Client{Transport: t} -} - -func (t *Transport) transport() http.RoundTripper { - if t.Transport != nil { - return t.Transport - } - return http.DefaultTransport -} - -// AuthCodeURL returns a URL that the end-user should be redirected to, -// so that they may obtain an authorization code. -func (c *Config) AuthCodeURL(state string) string { - url_, err := url.Parse(c.AuthURL) - if err != nil { - panic("AuthURL malformed: " + err.Error()) - } - q := url.Values{ - "response_type": {"code"}, - "client_id": {c.ClientId}, - "state": condVal(state), - "scope": condVal(c.Scope), - "redirect_uri": condVal(c.RedirectURL), - "access_type": condVal(c.AccessType), - "approval_prompt": condVal(c.ApprovalPrompt), - }.Encode() - if url_.RawQuery == "" { - url_.RawQuery = q - } else { - url_.RawQuery += "&" + q - } - return url_.String() -} - -func condVal(v string) []string { - if v == "" { - return nil - } - return []string{v} -} - -// Exchange takes a code and gets access Token from the remote server. -func (t *Transport) Exchange(code string) (*Token, error) { - if t.Config == nil { - return nil, OAuthError{"Exchange", "no Config supplied"} - } - - // If the transport or the cache already has a token, it is - // passed to `updateToken` to preserve existing refresh token. - tok := t.Token - if tok == nil && t.TokenCache != nil { - tok, _ = t.TokenCache.Token() - } - if tok == nil { - tok = new(Token) - } - err := t.updateToken(tok, url.Values{ - "grant_type": {"authorization_code"}, - "redirect_uri": {t.RedirectURL}, - "scope": {t.Scope}, - "code": {code}, - }) - if err != nil { - return nil, err - } - t.Token = tok - if t.TokenCache != nil { - return tok, t.TokenCache.PutToken(tok) - } - return tok, nil -} - -// RoundTrip executes a single HTTP transaction using the Transport's -// Token as authorization headers. -// -// This method will attempt to renew the Token if it has expired and may return -// an error related to that Token renewal before attempting the client request. -// If the Token cannot be renewed a non-nil os.Error value will be returned. -// If the Token is invalid callers should expect HTTP-level errors, -// as indicated by the Response's StatusCode. -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - accessToken, err := t.getAccessToken() - if err != nil { - return nil, err - } - // To set the Authorization header, we must make a copy of the Request - // so that we don't modify the Request we were given. - // This is required by the specification of http.RoundTripper. - req = cloneRequest(req) - req.Header.Set("Authorization", "Bearer "+accessToken) - - // Make the HTTP request. - return t.transport().RoundTrip(req) -} - -func (t *Transport) getAccessToken() (string, error) { - t.mu.Lock() - defer t.mu.Unlock() - - if t.Token == nil { - if t.Config == nil { - return "", OAuthError{"RoundTrip", "no Config supplied"} - } - if t.TokenCache == nil { - return "", OAuthError{"RoundTrip", "no Token supplied"} - } - var err error - t.Token, err = t.TokenCache.Token() - if err != nil { - return "", err - } - } - - // Refresh the Token if it has expired. - if t.Expired() { - if err := t.Refresh(); err != nil { - return "", err - } - } - if t.AccessToken == "" { - return "", errors.New("no access token obtained from refresh") - } - return t.AccessToken, nil -} - -// cloneRequest returns a clone of the provided *http.Request. -// The clone is a shallow copy of the struct and its Header map. -func cloneRequest(r *http.Request) *http.Request { - // shallow copy of the struct - r2 := new(http.Request) - *r2 = *r - // deep copy of the Header - r2.Header = make(http.Header) - for k, s := range r.Header { - r2.Header[k] = s - } - return r2 -} - -// Refresh renews the Transport's AccessToken using its RefreshToken. -func (t *Transport) Refresh() error { - if t.Token == nil { - return OAuthError{"Refresh", "no existing Token"} - } - if t.RefreshToken == "" { - return OAuthError{"Refresh", "Token expired; no Refresh Token"} - } - if t.Config == nil { - return OAuthError{"Refresh", "no Config supplied"} - } - - err := t.updateToken(t.Token, url.Values{ - "grant_type": {"refresh_token"}, - "refresh_token": {t.RefreshToken}, - }) - if err != nil { - return err - } - if t.TokenCache != nil { - return t.TokenCache.PutToken(t.Token) - } - return nil -} - -// AuthenticateClient gets an access Token using the client_credentials grant -// type. -func (t *Transport) AuthenticateClient() error { - if t.Config == nil { - return OAuthError{"Exchange", "no Config supplied"} - } - if t.Token == nil { - t.Token = &Token{} - } - return t.updateToken(t.Token, url.Values{"grant_type": {"client_credentials"}}) -} - -// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL -// implements the OAuth2 spec correctly -// See https://code.google.com/p/goauth2/issues/detail?id=31 for background. -// In summary: -// - Reddit only accepts client secret in the Authorization header -// - Dropbox accepts either it in URL param or Auth header, but not both. -// - Google only accepts URL param (not spec compliant?), not Auth header -func providerAuthHeaderWorks(tokenURL string) bool { - if strings.HasPrefix(tokenURL, "https://accounts.google.com/") || - strings.HasPrefix(tokenURL, "https://github.com/") || - strings.HasPrefix(tokenURL, "https://api.instagram.com/") || - strings.HasPrefix(tokenURL, "https://www.douban.com/") { - // Some sites fail to implement the OAuth2 spec fully. - return false - } - - // Assume the provider implements the spec properly - // otherwise. We can add more exceptions as they're - // discovered. We will _not_ be adding configurable hooks - // to this package to let users select server bugs. - return true -} - -// updateToken mutates both tok and v. -func (t *Transport) updateToken(tok *Token, v url.Values) error { - v.Set("client_id", t.ClientId) - bustedAuth := !providerAuthHeaderWorks(t.TokenURL) - if bustedAuth { - v.Set("client_secret", t.ClientSecret) - } - client := &http.Client{Transport: t.transport()} - req, err := http.NewRequest("POST", t.TokenURL, strings.NewReader(v.Encode())) - if err != nil { - return err - } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - if !bustedAuth { - req.SetBasicAuth(t.ClientId, t.ClientSecret) - } - r, err := client.Do(req) - if err != nil { - return err - } - defer r.Body.Close() - if r.StatusCode != 200 { - return OAuthError{"updateToken", "Unexpected HTTP status " + r.Status} - } - var b struct { - Access string `json:"access_token"` - Refresh string `json:"refresh_token"` - ExpiresIn int64 `json:"expires_in"` // seconds - Id string `json:"id_token"` - } - - body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20)) - if err != nil { - return err - } - - content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type")) - switch content { - case "application/x-www-form-urlencoded", "text/plain": - vals, err := url.ParseQuery(string(body)) - if err != nil { - return err - } - - b.Access = vals.Get("access_token") - b.Refresh = vals.Get("refresh_token") - b.ExpiresIn, _ = strconv.ParseInt(vals.Get("expires_in"), 10, 64) - b.Id = vals.Get("id_token") - default: - if err = json.Unmarshal(body, &b); err != nil { - return fmt.Errorf("got bad response from server: %q", body) - } - } - if b.Access == "" { - return errors.New("received empty access token from authorization server") - } - tok.AccessToken = b.Access - // Don't overwrite `RefreshToken` with an empty value - if b.Refresh != "" { - tok.RefreshToken = b.Refresh - } - if b.ExpiresIn == 0 { - tok.Expiry = time.Time{} - } else { - tok.Expiry = time.Now().Add(time.Duration(b.ExpiresIn) * time.Second) - } - if b.Id != "" { - if tok.Extra == nil { - tok.Extra = make(map[string]string) - } - tok.Extra["id_token"] = b.Id - } - return nil -} diff --git a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth_test.go b/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth_test.go deleted file mode 100644 index 9fadc61990..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth_test.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2011 The goauth2 Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package oauth - -import ( - "io" - "io/ioutil" - "net/http" - "net/http/httptest" - "net/url" - "os" - "path/filepath" - "runtime" - "testing" - "time" -) - -var requests = []struct { - path, query, auth string // request - contenttype, body string // response -}{ - { - path: "/token", - query: "grant_type=authorization_code&code=c0d3&client_id=cl13nt1d", - contenttype: "application/json", - auth: "Basic Y2wxM250MWQ6czNjcjN0", - body: ` - { - "access_token":"token1", - "refresh_token":"refreshtoken1", - "id_token":"idtoken1", - "expires_in":3600 - } - `, - }, - {path: "/secure", auth: "Bearer token1", body: "first payload"}, - { - path: "/token", - query: "grant_type=refresh_token&refresh_token=refreshtoken1&client_id=cl13nt1d", - contenttype: "application/json", - auth: "Basic Y2wxM250MWQ6czNjcjN0", - body: ` - { - "access_token":"token2", - "refresh_token":"refreshtoken2", - "id_token":"idtoken2", - "expires_in":3600 - } - `, - }, - {path: "/secure", auth: "Bearer token2", body: "second payload"}, - { - path: "/token", - query: "grant_type=refresh_token&refresh_token=refreshtoken2&client_id=cl13nt1d", - contenttype: "application/x-www-form-urlencoded", - body: "access_token=token3&refresh_token=refreshtoken3&id_token=idtoken3&expires_in=3600", - auth: "Basic Y2wxM250MWQ6czNjcjN0", - }, - {path: "/secure", auth: "Bearer token3", body: "third payload"}, - { - path: "/token", - query: "grant_type=client_credentials&client_id=cl13nt1d", - contenttype: "application/json", - auth: "Basic Y2wxM250MWQ6czNjcjN0", - body: ` - { - "access_token":"token4", - "expires_in":3600 - } - `, - }, - {path: "/secure", auth: "Bearer token4", body: "fourth payload"}, -} - -func TestOAuth(t *testing.T) { - // Set up test server. - n := 0 - handler := func(w http.ResponseWriter, r *http.Request) { - if n >= len(requests) { - t.Errorf("too many requests: %d", n) - return - } - req := requests[n] - n++ - - // Check request. - if g, w := r.URL.Path, req.path; g != w { - t.Errorf("request[%d] got path %s, want %s", n, g, w) - } - want, _ := url.ParseQuery(req.query) - for k := range want { - if g, w := r.FormValue(k), want.Get(k); g != w { - t.Errorf("query[%s] = %s, want %s", k, g, w) - } - } - if g, w := r.Header.Get("Authorization"), req.auth; w != "" && g != w { - t.Errorf("Authorization: %v, want %v", g, w) - } - - // Send response. - w.Header().Set("Content-Type", req.contenttype) - io.WriteString(w, req.body) - } - server := httptest.NewServer(http.HandlerFunc(handler)) - defer server.Close() - - config := &Config{ - ClientId: "cl13nt1d", - ClientSecret: "s3cr3t", - Scope: "https://example.net/scope", - AuthURL: server.URL + "/auth", - TokenURL: server.URL + "/token", - } - - // TODO(adg): test AuthCodeURL - - transport := &Transport{Config: config} - _, err := transport.Exchange("c0d3") - if err != nil { - t.Fatalf("Exchange: %v", err) - } - checkToken(t, transport.Token, "token1", "refreshtoken1", "idtoken1") - - c := transport.Client() - resp, err := c.Get(server.URL + "/secure") - if err != nil { - t.Fatalf("Get: %v", err) - } - checkBody(t, resp, "first payload") - - // test automatic refresh - transport.Expiry = time.Now().Add(-time.Hour) - resp, err = c.Get(server.URL + "/secure") - if err != nil { - t.Fatalf("Get: %v", err) - } - checkBody(t, resp, "second payload") - checkToken(t, transport.Token, "token2", "refreshtoken2", "idtoken2") - - // refresh one more time, but get URL-encoded token instead of JSON - transport.Expiry = time.Now().Add(-time.Hour) - resp, err = c.Get(server.URL + "/secure") - if err != nil { - t.Fatalf("Get: %v", err) - } - checkBody(t, resp, "third payload") - checkToken(t, transport.Token, "token3", "refreshtoken3", "idtoken3") - - transport.Token = &Token{} - err = transport.AuthenticateClient() - if err != nil { - t.Fatalf("AuthenticateClient: %v", err) - } - checkToken(t, transport.Token, "token4", "", "") - resp, err = c.Get(server.URL + "/secure") - if err != nil { - t.Fatalf("Get: %v", err) - } - checkBody(t, resp, "fourth payload") -} - -func checkToken(t *testing.T, tok *Token, access, refresh, id string) { - if g, w := tok.AccessToken, access; g != w { - t.Errorf("AccessToken = %q, want %q", g, w) - } - if g, w := tok.RefreshToken, refresh; g != w { - t.Errorf("RefreshToken = %q, want %q", g, w) - } - if g, w := tok.Extra["id_token"], id; g != w { - t.Errorf("Extra['id_token'] = %q, want %q", g, w) - } - if tok.Expiry.IsZero() { - t.Errorf("Expiry is zero; want ~1 hour") - } else { - exp := tok.Expiry.Sub(time.Now()) - const slop = 3 * time.Second // time moving during test - if (time.Hour-slop) > exp || exp > time.Hour { - t.Errorf("Expiry = %v, want ~1 hour", exp) - } - } -} - -func checkBody(t *testing.T, r *http.Response, body string) { - b, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Errorf("reading reponse body: %v, want %q", err, body) - } - if g, w := string(b), body; g != w { - t.Errorf("request body mismatch: got %q, want %q", g, w) - } -} - -func TestCachePermissions(t *testing.T) { - if runtime.GOOS == "windows" { - // Windows doesn't support file mode bits. - return - } - - td, err := ioutil.TempDir("", "oauth-test") - if err != nil { - t.Fatalf("ioutil.TempDir: %v", err) - } - defer os.RemoveAll(td) - tempFile := filepath.Join(td, "cache-file") - - cf := CacheFile(tempFile) - if err := cf.PutToken(new(Token)); err != nil { - t.Fatalf("PutToken: %v", err) - } - fi, err := os.Stat(tempFile) - if err != nil { - t.Fatalf("os.Stat: %v", err) - } - if fi.Mode()&0077 != 0 { - t.Errorf("Created cache file has mode %#o, want non-accessible to group+other", fi.Mode()) - } -} - -func TestTokenExpired(t *testing.T) { - tests := []struct { - token Token - expired bool - }{ - {Token{AccessToken: "foo"}, false}, - {Token{AccessToken: ""}, true}, - {Token{AccessToken: "foo", Expiry: time.Now().Add(-1 * time.Hour)}, true}, - {Token{AccessToken: "foo", Expiry: time.Now().Add(1 * time.Hour)}, false}, - } - for _, tt := range tests { - if got := tt.token.Expired(); got != tt.expired { - t.Errorf("token %+v Expired = %v; want %v", tt.token, got, !got) - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/README.md b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/README.md deleted file mode 100644 index b8aa4d5422..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Azure SDK for Golang -This project provides a Golang package that makes it easy to consume and manage Microsoft Azure Services. - -# Installation -- Install Golang: https://golang.org/doc/install -- Get Azure SDK package: - -```sh -go get github.com/MSOpenTech/azure-sdk-for-go -``` -- Install: - -```sh -go install github.com/MSOpenTech/azure-sdk-for-go -``` - -# Usage - -Create linux VM: - -```C -package main - -import ( - "fmt" - "os" - - azure "github.com/MSOpenTech/azure-sdk-for-go" - "github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient" -) - -func main() { - dnsName := "test-vm-from-go" - location := "West US" - vmSize := "Small" - vmImage := "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB" - userName := "testuser" - userPassword := "Test123" - sshCert := "" - sshPort := 22 - - err := azure.ImportPublishSettings(SUBSCRIPTION_ID, SUBSCRIPTION_CERTIFICATE) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - vmConfig, err := vmClient.CreateAzureVMConfiguration(dnsName, vmSize, vmImage, location) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - vmConfig, err = vmClient.AddAzureLinuxProvisioningConfig(vmConfig, userName, userPassword, sshCert, sshPort) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = vmClient.CreateAzureVM(vmConfig, dnsName, location) - if err != nil { - fmt.Println(err) - os.Exit(1) - } -} -``` - -# License -[Apache 2.0](LICENSE-2.0.txt) diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient/entities.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient/entities.go deleted file mode 100644 index 6af657522d..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient/entities.go +++ /dev/null @@ -1,22 +0,0 @@ -package imageClient - -import ( - "encoding/xml" -) - -type ImageList struct { - XMLName xml.Name `xml:"Images"` - Xmlns string `xml:"xmlns,attr"` - OSImages []OSImage `xml:"OSImage"` -} - -type OSImage struct { - Category string - Label string - LogicalSizeInGB string - Name string - OS string - Eula string - Description string - Location string -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient/imageClient.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient/imageClient.go deleted file mode 100644 index 8042709f9e..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient/imageClient.go +++ /dev/null @@ -1,50 +0,0 @@ -package imageClient - -import ( - "encoding/xml" - "errors" - "fmt" - azure "github.com/MSOpenTech/azure-sdk-for-go" -) - -const ( - azureImageListURL = "services/images" - invalidImageError = "Can not find image %s in specified subscription, please specify another image name." -) - -func GetImageList() (ImageList, error) { - imageList := ImageList{} - - response, err := azure.SendAzureGetRequest(azureImageListURL) - if err != nil { - return imageList, err - } - - err = xml.Unmarshal(response, &imageList) - if err != nil { - return imageList, err - } - - return imageList, err -} - -func ResolveImageName(imageName string) error { - if len(imageName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "imageName") - } - - imageList, err := GetImageList() - if err != nil { - return err - } - - for _, image := range imageList.OSImages { - if image.Name != imageName && image.Label != imageName { - continue - } - - return nil - } - - return errors.New(fmt.Sprintf(invalidImageError, imageName)) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient/entities.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient/entities.go deleted file mode 100644 index 7571726f66..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient/entities.go +++ /dev/null @@ -1,17 +0,0 @@ -package locationClient - -import ( - "encoding/xml" -) - -type LocationList struct { - XMLName xml.Name `xml:"Locations"` - Xmlns string `xml:"xmlns,attr"` - Locations []Location `xml:"Location"` -} - -type Location struct { - Name string - DisplayName string - AvailableServices []string `xml:"AvailableServices>AvailableService"` -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient/locationClient.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient/locationClient.go deleted file mode 100644 index 9b37a41d90..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient/locationClient.go +++ /dev/null @@ -1,57 +0,0 @@ -package locationClient - -import ( - "bytes" - "encoding/xml" - "errors" - "fmt" - azure "github.com/MSOpenTech/azure-sdk-for-go" - "strings" -) - -const ( - azureLocationListURL = "locations" - invalidLocationError = "Invalid location: %s. Available locations: %s" -) - -func ResolveLocation(location string) error { - if len(location) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "location") - } - - locations, err := GetLocationList() - if err != nil { - return err - } - - for _, existingLocation := range locations.Locations { - if existingLocation.Name != location { - continue - } - - return nil - } - - var availableLocations bytes.Buffer - for _, existingLocation := range locations.Locations { - availableLocations.WriteString(existingLocation.Name + ", ") - } - - return errors.New(fmt.Sprintf(invalidLocationError, location, strings.Trim(availableLocations.String(), ", "))) -} - -func GetLocationList() (LocationList, error) { - locationList := LocationList{} - - response, err := azure.SendAzureGetRequest(azureLocationListURL) - if err != nil { - return locationList, err - } - - err = xml.Unmarshal(response, &locationList) - if err != nil { - return locationList, err - } - - return locationList, nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient/entities.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient/entities.go deleted file mode 100644 index 4b703e3a06..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient/entities.go +++ /dev/null @@ -1,49 +0,0 @@ -package storageServiceClient - -import ( - "encoding/xml" -) - -type StorageServiceList struct { - XMLName xml.Name `xml:"StorageServices"` - Xmlns string `xml:"xmlns,attr"` - StorageServices []StorageService `xml:"StorageService"` -} - -type StorageService struct { - Url string - ServiceName string - StorageServiceProperties StorageServiceProperties -} - -type StorageServiceProperties struct { - Description string - Location string - Label string - Status string - Endpoints []string `xml:"Endpoints>Endpoint"` - GeoReplicationEnabled string - GeoPrimaryRegion string -} - -type StorageServiceDeployment struct { - XMLName xml.Name `xml:"CreateStorageServiceInput"` - Xmlns string `xml:"xmlns,attr"` - ServiceName string - Description string - Label string - AffinityGroup string `xml:",omitempty"` - Location string `xml:",omitempty"` - GeoReplicationEnabled bool - ExtendedProperties ExtendedPropertyList - SecondaryReadEnabled bool -} - -type ExtendedPropertyList struct { - ExtendedProperty []ExtendedProperty -} - -type ExtendedProperty struct { - Name string - Value string -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient/storageServiceClient.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient/storageServiceClient.go deleted file mode 100644 index 29b4123978..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient/storageServiceClient.go +++ /dev/null @@ -1,128 +0,0 @@ -package storageServiceClient - -import ( - "encoding/base64" - "encoding/xml" - "errors" - "fmt" - azure "github.com/MSOpenTech/azure-sdk-for-go" - "strings" -) - -const ( - azureXmlns = "http://schemas.microsoft.com/windowsazure" - azureStorageServiceListURL = "services/storageservices" - azureStorageServiceURL = "services/storageservices/%s" - - blobEndpointNotFoundError = "Blob endpoint was not found in storage serice %s" -) - -func GetStorageServiceList() (*StorageServiceList, error) { - storageServiceList := new(StorageServiceList) - - response, err := azure.SendAzureGetRequest(azureStorageServiceListURL) - if err != nil { - return nil, err - } - - err = xml.Unmarshal(response, storageServiceList) - if err != nil { - return storageServiceList, err - } - - return storageServiceList, nil -} - -func GetStorageServiceByName(serviceName string) (*StorageService, error) { - if len(serviceName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "serviceName") - } - - storageService := new(StorageService) - requestURL := fmt.Sprintf(azureStorageServiceURL, serviceName) - response, err := azure.SendAzureGetRequest(requestURL) - if err != nil { - return nil, err - } - - err = xml.Unmarshal(response, storageService) - if err != nil { - return nil, err - } - - return storageService, nil -} - -func GetStorageServiceByLocation(location string) (*StorageService, error) { - if len(location) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "location") - } - - storageService := new(StorageService) - storageServiceList, err := GetStorageServiceList() - if err != nil { - return storageService, err - } - - for _, storageService := range storageServiceList.StorageServices { - if storageService.StorageServiceProperties.Location != location { - continue - } - - return &storageService, nil - } - - return nil, nil -} - -func CreateStorageService(name, location string) (*StorageService, error) { - if len(name) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "name") - } - if len(location) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "location") - } - - storageDeploymentConfig := createStorageServiceDeploymentConf(name, location) - deploymentBytes, err := xml.Marshal(storageDeploymentConfig) - if err != nil { - return nil, err - } - - requestId, err := azure.SendAzurePostRequest(azureStorageServiceListURL, deploymentBytes) - if err != nil { - return nil, err - } - - azure.WaitAsyncOperation(requestId) - storageService, err := GetStorageServiceByName(storageDeploymentConfig.ServiceName) - if err != nil { - return nil, err - } - - return storageService, nil -} - -func GetBlobEndpoint(storageService *StorageService) (string, error) { - for _, endpoint := range storageService.StorageServiceProperties.Endpoints { - if !strings.Contains(endpoint, ".blob.core") { - continue - } - - return endpoint, nil - } - - return "", errors.New(fmt.Sprintf(blobEndpointNotFoundError, storageService.ServiceName)) -} - -func createStorageServiceDeploymentConf(name, location string) StorageServiceDeployment { - storageServiceDeployment := StorageServiceDeployment{} - - storageServiceDeployment.ServiceName = name - label := base64.StdEncoding.EncodeToString([]byte(name)) - storageServiceDeployment.Label = label - storageServiceDeployment.Location = location - storageServiceDeployment.Xmlns = azureXmlns - - return storageServiceDeployment -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient/entities.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient/entities.go deleted file mode 100644 index e8f1c52817..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient/entities.go +++ /dev/null @@ -1,176 +0,0 @@ -package vmClient - -import ( - "encoding/xml" -) - -type VMDeployment struct { - XMLName xml.Name `xml:"Deployment"` - Xmlns string `xml:"xmlns,attr"` - Name string - DeploymentSlot string - Status string `xml:",omitempty"` - Label string - Url string `xml:",omitempty"` - RoleList RoleList - RoleInstanceList RoleInstanceList `xml:",omitempty"` -} - -type HostedServiceDeployment struct { - XMLName xml.Name `xml:"CreateHostedService"` - Xmlns string `xml:"xmlns,attr"` - ServiceName string - Label string - Description string - Location string -} - -type RoleList struct { - Role []*Role -} - -type RoleInstanceList struct { - RoleInstance []*RoleInstance -} - -type RoleInstance struct { - RoleName string - InstanceName string - InstanceStatus string - InstanceSize string - PowerState string -} - -type Role struct { - RoleName string - RoleType string - ConfigurationSets ConfigurationSets - ResourceExtensionReferences ResourceExtensionReferences `xml:",omitempty"` - OSVirtualHardDisk OSVirtualHardDisk - RoleSize string - ProvisionGuestAgent bool - UseCertAuth bool `xml:"-"` - CertPath string `xml:"-"` -} - -type ConfigurationSets struct { - ConfigurationSet []ConfigurationSet -} - -type ResourceExtensionReferences struct { - ResourceExtensionReference []ResourceExtensionReference -} - -type InputEndpoints struct { - InputEndpoint []InputEndpoint -} - -type ResourceExtensionReference struct { - ReferenceName string - Publisher string - Name string - Version string - ResourceExtensionParameterValues ResourceExtensionParameterValues `xml:",omitempty"` - State string -} - -type ResourceExtensionParameterValues struct { - ResourceExtensionParameterValue []ResourceExtensionParameter -} - -type ResourceExtensionParameter struct { - Key string - Value string - Type string -} - -type OSVirtualHardDisk struct { - MediaLink string - SourceImageName string - HostCaching string `xml:",omitempty"` - DiskName string `xml:",omitempty"` - OS string `xml:",omitempty"` -} - -type ConfigurationSet struct { - ConfigurationSetType string - HostName string `xml:",omitempty"` - UserName string `xml:",omitempty"` - UserPassword string `xml:",omitempty"` - DisableSshPasswordAuthentication bool - InputEndpoints InputEndpoints `xml:",omitempty"` - SSH SSH `xml:",omitempty"` -} - -type SSH struct { - PublicKeys PublicKeyList -} - -type PublicKeyList struct { - PublicKey []PublicKey -} - -type PublicKey struct { - Fingerprint string - Path string -} - -type InputEndpoint struct { - LocalPort int - Name string - Port int - Protocol string - Vip string -} - -type ServiceCertificate struct { - XMLName xml.Name `xml:"CertificateFile"` - Xmlns string `xml:"xmlns,attr"` - Data string - CertificateFormat string - Password string `xml:",omitempty"` -} - -type StartRoleOperation struct { - Xmlns string `xml:"xmlns,attr"` - OperationType string -} - -type ShutdownRoleOperation struct { - Xmlns string `xml:"xmlns,attr"` - OperationType string -} - -type RestartRoleOperation struct { - Xmlns string `xml:"xmlns,attr"` - OperationType string -} - -type AvailabilityResponse struct { - Xmlns string `xml:"xmlns,attr"` - Result bool - Reason string -} - -type RoleSizeList struct { - XMLName xml.Name `xml:"RoleSizes"` - Xmlns string `xml:"xmlns,attr"` - RoleSizes []RoleSize `xml:"RoleSize"` -} - -type RoleSize struct { - Name string - Label string - Cores int - MemoryInMb int - SupportedByWebWorkerRoles bool - SupportedByVirtualMachines bool - MaxDataDiskCount int - WebWorkerResourceDiskSizeInMb int - VirtualMachineResourceDiskSizeInMb int -} - -type dockerPublicConfig struct { - DockerPort int `json:"dockerport"` - Version int `json:"version"` -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient/vmClient.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient/vmClient.go deleted file mode 100644 index 3d6f538e7e..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient/vmClient.go +++ /dev/null @@ -1,859 +0,0 @@ -package vmClient - -import ( - "bytes" - "crypto/sha1" - "encoding/base64" - "encoding/json" - "encoding/pem" - "encoding/xml" - "errors" - "fmt" - "io/ioutil" - "strings" - "time" - "unicode" - - azure "github.com/MSOpenTech/azure-sdk-for-go" - "github.com/MSOpenTech/azure-sdk-for-go/clients/imageClient" - "github.com/MSOpenTech/azure-sdk-for-go/clients/locationClient" - "github.com/MSOpenTech/azure-sdk-for-go/clients/storageServiceClient" -) - -const ( - azureXmlns = "http://schemas.microsoft.com/windowsazure" - azureDeploymentListURL = "services/hostedservices/%s/deployments" - azureHostedServiceListURL = "services/hostedservices" - deleteAzureHostedServiceURL = "services/hostedservices/%s?comp=media" - azureHostedServiceAvailabilityURL = "services/hostedservices/operations/isavailable/%s" - azureDeploymentURL = "services/hostedservices/%s/deployments/%s" - deleteAzureDeploymentURL = "services/hostedservices/%s/deployments/%s?comp=media" - azureRoleURL = "services/hostedservices/%s/deployments/%s/roles/%s" - azureOperationsURL = "services/hostedservices/%s/deployments/%s/roleinstances/%s/Operations" - azureCertificatListURL = "services/hostedservices/%s/certificates" - azureRoleSizeListURL = "rolesizes" - - osLinux = "Linux" - osWindows = "Windows" - dockerPublicConfigVersion = 2 - - provisioningConfDoesNotExistsError = "You should set azure VM provisioning config first" - invalidCertExtensionError = "Certificate %s is invalid. Please specify %s certificate." - invalidOSError = "You must specify correct OS param. Valid values are 'Linux' and 'Windows'" - invalidDnsLengthError = "The DNS name must be between 3 and 25 characters." - invalidPasswordLengthError = "Password must be between 4 and 30 characters." - invalidPasswordError = "Password must have at least one upper case, lower case and numeric character." - invalidRoleSizeError = "Invalid role size: %s. Available role sizes: %s" -) - -//Region public methods starts - -func CreateAzureVM(azureVMConfiguration *Role, dnsName, location string) error { - if azureVMConfiguration == nil { - return fmt.Errorf(azure.ParamNotSpecifiedError, "azureVMConfiguration") - } - if len(dnsName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "dnsName") - } - if len(location) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "location") - } - - err := verifyDNSname(dnsName) - if err != nil { - return err - } - - requestId, err := CreateHostedService(dnsName, location) - if err != nil { - return err - } - - azure.WaitAsyncOperation(requestId) - - if azureVMConfiguration.UseCertAuth { - err = uploadServiceCert(dnsName, azureVMConfiguration.CertPath) - if err != nil { - DeleteHostedService(dnsName) - return err - } - } - - vMDeployment := createVMDeploymentConfig(azureVMConfiguration) - vMDeploymentBytes, err := xml.Marshal(vMDeployment) - if err != nil { - DeleteHostedService(dnsName) - return err - } - - requestURL := fmt.Sprintf(azureDeploymentListURL, azureVMConfiguration.RoleName) - requestId, err = azure.SendAzurePostRequest(requestURL, vMDeploymentBytes) - if err != nil { - DeleteHostedService(dnsName) - return err - } - - azure.WaitAsyncOperation(requestId) - - return nil -} - -func CreateHostedService(dnsName, location string) (string, error) { - if len(dnsName) == 0 { - return "", fmt.Errorf(azure.ParamNotSpecifiedError, "dnsName") - } - if len(location) == 0 { - return "", fmt.Errorf(azure.ParamNotSpecifiedError, "location") - } - - err := verifyDNSname(dnsName) - if err != nil { - return "", err - } - - result, reason, err := CheckHostedServiceNameAvailability(dnsName) - if err != nil { - return "", err - } - if !result { - return "", fmt.Errorf("%s Hosted service name: %s", reason, dnsName) - } - - err = locationClient.ResolveLocation(location) - if err != nil { - return "", err - } - - hostedServiceDeployment := createHostedServiceDeploymentConfig(dnsName, location) - hostedServiceBytes, err := xml.Marshal(hostedServiceDeployment) - if err != nil { - return "", err - } - - requestURL := azureHostedServiceListURL - requestId, err := azure.SendAzurePostRequest(requestURL, hostedServiceBytes) - if err != nil { - return "", err - } - - return requestId, nil -} - -func CheckHostedServiceNameAvailability(dnsName string) (bool, string, error) { - if len(dnsName) == 0 { - return false, "", fmt.Errorf(azure.ParamNotSpecifiedError, "dnsName") - } - - err := verifyDNSname(dnsName) - if err != nil { - return false, "", err - } - - requestURL := fmt.Sprintf(azureHostedServiceAvailabilityURL, dnsName) - response, err := azure.SendAzureGetRequest(requestURL) - if err != nil { - return false, "", err - } - - availabilityResponse := new(AvailabilityResponse) - err = xml.Unmarshal(response, availabilityResponse) - if err != nil { - return false, "", err - } - - return availabilityResponse.Result, availabilityResponse.Reason, nil -} - -func DeleteHostedService(dnsName string) error { - if len(dnsName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "dnsName") - } - - err := verifyDNSname(dnsName) - if err != nil { - return err - } - - requestURL := fmt.Sprintf(deleteAzureHostedServiceURL, dnsName) - requestId, err := azure.SendAzureDeleteRequest(requestURL) - if err != nil { - return err - } - - azure.WaitAsyncOperation(requestId) - return nil -} - -func CreateAzureVMConfiguration(dnsName, instanceSize, imageName, location string) (*Role, error) { - if len(dnsName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "dnsName") - } - if len(instanceSize) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "instanceSize") - } - if len(imageName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "imageName") - } - if len(location) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "location") - } - - err := verifyDNSname(dnsName) - if err != nil { - return nil, err - } - - err = locationClient.ResolveLocation(location) - if err != nil { - return nil, err - } - - err = ResolveRoleSize(instanceSize) - if err != nil { - return nil, err - } - - role, err := createAzureVMRole(dnsName, instanceSize, imageName, location) - if err != nil { - return nil, err - } - - return role, nil -} - -func AddAzureLinuxProvisioningConfig(azureVMConfiguration *Role, userName, password, certPath string, sshPort int) (*Role, error) { - if azureVMConfiguration == nil { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "azureVMConfiguration") - } - if len(userName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "userName") - } - - configurationSets := ConfigurationSets{} - provisioningConfig, err := createLinuxProvisioningConfig(azureVMConfiguration.RoleName, userName, password, certPath) - if err != nil { - return nil, err - } - - configurationSets.ConfigurationSet = append(configurationSets.ConfigurationSet, provisioningConfig) - - networkConfig, networkErr := createNetworkConfig(osLinux, sshPort) - if networkErr != nil { - return nil, err - } - - configurationSets.ConfigurationSet = append(configurationSets.ConfigurationSet, networkConfig) - - azureVMConfiguration.ConfigurationSets = configurationSets - - if len(certPath) > 0 { - azureVMConfiguration.UseCertAuth = true - azureVMConfiguration.CertPath = certPath - } - - return azureVMConfiguration, nil -} - -func SetAzureVMExtension(azureVMConfiguration *Role, name string, publisher string, version string, referenceName string, state string, publicConfigurationValue string, privateConfigurationValue string) (*Role, error) { - if azureVMConfiguration == nil { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "azureVMConfiguration") - } - if len(name) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "name") - } - if len(publisher) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "publisher") - } - if len(version) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "version") - } - if len(referenceName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "referenceName") - } - - extension := ResourceExtensionReference{} - extension.Name = name - extension.Publisher = publisher - extension.Version = version - extension.ReferenceName = referenceName - extension.State = state - - if len(privateConfigurationValue) > 0 { - privateConfig := ResourceExtensionParameter{} - privateConfig.Key = "ignored" - privateConfig.Value = base64.StdEncoding.EncodeToString([]byte(privateConfigurationValue)) - privateConfig.Type = "Private" - - extension.ResourceExtensionParameterValues.ResourceExtensionParameterValue = append(extension.ResourceExtensionParameterValues.ResourceExtensionParameterValue, privateConfig) - } - - if len(publicConfigurationValue) > 0 { - publicConfig := ResourceExtensionParameter{} - publicConfig.Key = "ignored" - publicConfig.Value = base64.StdEncoding.EncodeToString([]byte(publicConfigurationValue)) - publicConfig.Type = "Public" - - extension.ResourceExtensionParameterValues.ResourceExtensionParameterValue = append(extension.ResourceExtensionParameterValues.ResourceExtensionParameterValue, publicConfig) - } - - azureVMConfiguration.ResourceExtensionReferences.ResourceExtensionReference = append(azureVMConfiguration.ResourceExtensionReferences.ResourceExtensionReference, extension) - - return azureVMConfiguration, nil -} - -func SetAzureDockerVMExtension(azureVMConfiguration *Role, dockerPort int, version string) (*Role, error) { - if azureVMConfiguration == nil { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "azureVMConfiguration") - } - - if len(version) == 0 { - version = "0.3" - } - - err := addDockerPort(azureVMConfiguration.ConfigurationSets.ConfigurationSet, dockerPort) - if err != nil { - return nil, err - } - - publicConfiguration, err := createDockerPublicConfig(dockerPort) - if err != nil { - return nil, err - } - - privateConfiguration := "{}" - - azureVMConfiguration, err = SetAzureVMExtension(azureVMConfiguration, "DockerExtension", "MSOpenTech.Extensions", version, "DockerExtension", "enable", publicConfiguration, privateConfiguration) - return azureVMConfiguration, nil -} - -func GetVMDeployment(cloudserviceName, deploymentName string) (*VMDeployment, error) { - if len(cloudserviceName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - - deployment := new(VMDeployment) - - requestURL := fmt.Sprintf(azureDeploymentURL, cloudserviceName, deploymentName) - response, azureErr := azure.SendAzureGetRequest(requestURL) - if azureErr != nil { - return nil, azureErr - } - - err := xml.Unmarshal(response, deployment) - if err != nil { - return nil, err - } - - return deployment, nil -} - -func DeleteVMDeployment(cloudserviceName, deploymentName string) error { - if len(cloudserviceName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - - requestURL := fmt.Sprintf(deleteAzureDeploymentURL, cloudserviceName, deploymentName) - requestId, err := azure.SendAzureDeleteRequest(requestURL) - if err != nil { - return err - } - - azure.WaitAsyncOperation(requestId) - - return nil -} - -func GetRole(cloudserviceName, deploymentName, roleName string) (*Role, error) { - if len(cloudserviceName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - if len(roleName) == 0 { - return nil, fmt.Errorf(azure.ParamNotSpecifiedError, "roleName") - } - - role := new(Role) - - requestURL := fmt.Sprintf(azureRoleURL, cloudserviceName, deploymentName, roleName) - response, azureErr := azure.SendAzureGetRequest(requestURL) - if azureErr != nil { - return nil, azureErr - } - - err := xml.Unmarshal(response, role) - if err != nil { - return nil, err - } - - return role, nil -} - -func StartRole(cloudserviceName, deploymentName, roleName string) error { - if len(cloudserviceName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - if len(roleName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "roleName") - } - - startRoleOperation := createStartRoleOperation() - - startRoleOperationBytes, err := xml.Marshal(startRoleOperation) - if err != nil { - return err - } - - requestURL := fmt.Sprintf(azureOperationsURL, cloudserviceName, deploymentName, roleName) - requestId, azureErr := azure.SendAzurePostRequest(requestURL, startRoleOperationBytes) - if azureErr != nil { - return azureErr - } - - azure.WaitAsyncOperation(requestId) - return nil -} - -func ShutdownRole(cloudserviceName, deploymentName, roleName string) error { - if len(cloudserviceName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - if len(roleName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "roleName") - } - - shutdownRoleOperation := createShutdowRoleOperation() - - shutdownRoleOperationBytes, err := xml.Marshal(shutdownRoleOperation) - if err != nil { - return err - } - - requestURL := fmt.Sprintf(azureOperationsURL, cloudserviceName, deploymentName, roleName) - requestId, azureErr := azure.SendAzurePostRequest(requestURL, shutdownRoleOperationBytes) - if azureErr != nil { - return azureErr - } - - azure.WaitAsyncOperation(requestId) - return nil -} - -func RestartRole(cloudserviceName, deploymentName, roleName string) error { - if len(cloudserviceName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - if len(roleName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "roleName") - } - - restartRoleOperation := createRestartRoleOperation() - - restartRoleOperationBytes, err := xml.Marshal(restartRoleOperation) - if err != nil { - return err - } - - requestURL := fmt.Sprintf(azureOperationsURL, cloudserviceName, deploymentName, roleName) - requestId, azureErr := azure.SendAzurePostRequest(requestURL, restartRoleOperationBytes) - if azureErr != nil { - return azureErr - } - - azure.WaitAsyncOperation(requestId) - return nil -} - -func DeleteRole(cloudserviceName, deploymentName, roleName string) error { - if len(cloudserviceName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "cloudserviceName") - } - if len(deploymentName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "deploymentName") - } - if len(roleName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "roleName") - } - - requestURL := fmt.Sprintf(azureRoleURL, cloudserviceName, deploymentName, roleName) - requestId, azureErr := azure.SendAzureDeleteRequest(requestURL) - if azureErr != nil { - return azureErr - } - - azure.WaitAsyncOperation(requestId) - return nil -} - -func GetRoleSizeList() (RoleSizeList, error) { - roleSizeList := RoleSizeList{} - - response, err := azure.SendAzureGetRequest(azureRoleSizeListURL) - if err != nil { - return roleSizeList, err - } - - err = xml.Unmarshal(response, &roleSizeList) - if err != nil { - return roleSizeList, err - } - - return roleSizeList, err -} - -func ResolveRoleSize(roleSizeName string) error { - if len(roleSizeName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "roleSizeName") - } - - roleSizeList, err := GetRoleSizeList() - if err != nil { - return err - } - - for _, roleSize := range roleSizeList.RoleSizes { - if roleSize.Name != roleSizeName { - continue - } - - return nil - } - - var availableSizes bytes.Buffer - for _, existingSize := range roleSizeList.RoleSizes { - availableSizes.WriteString(existingSize.Name + ", ") - } - - return errors.New(fmt.Sprintf(invalidRoleSizeError, roleSizeName, strings.Trim(availableSizes.String(), ", "))) -} - -//Region public methods ends - -//Region private methods starts - -func createStartRoleOperation() StartRoleOperation { - startRoleOperation := StartRoleOperation{} - startRoleOperation.OperationType = "StartRoleOperation" - startRoleOperation.Xmlns = azureXmlns - - return startRoleOperation -} - -func createShutdowRoleOperation() ShutdownRoleOperation { - shutdownRoleOperation := ShutdownRoleOperation{} - shutdownRoleOperation.OperationType = "ShutdownRoleOperation" - shutdownRoleOperation.Xmlns = azureXmlns - - return shutdownRoleOperation -} - -func createRestartRoleOperation() RestartRoleOperation { - startRoleOperation := RestartRoleOperation{} - startRoleOperation.OperationType = "RestartRoleOperation" - startRoleOperation.Xmlns = azureXmlns - - return startRoleOperation -} - -func createDockerPublicConfig(dockerPort int) (string, error) { - config := dockerPublicConfig{DockerPort: dockerPort, Version: dockerPublicConfigVersion} - configJson, err := json.Marshal(config) - if err != nil { - return "", err - } - - return string(configJson), nil -} - -func addDockerPort(configurationSets []ConfigurationSet, dockerPort int) error { - if len(configurationSets) == 0 { - return errors.New(provisioningConfDoesNotExistsError) - } - - for i := 0; i < len(configurationSets); i++ { - if configurationSets[i].ConfigurationSetType != "NetworkConfiguration" { - continue - } - - dockerEndpoint := createEndpoint("docker", "tcp", dockerPort, dockerPort) - configurationSets[i].InputEndpoints.InputEndpoint = append(configurationSets[i].InputEndpoints.InputEndpoint, dockerEndpoint) - } - - return nil -} - -func createHostedServiceDeploymentConfig(dnsName, location string) HostedServiceDeployment { - deployment := HostedServiceDeployment{} - deployment.ServiceName = dnsName - label := base64.StdEncoding.EncodeToString([]byte(dnsName)) - deployment.Label = label - deployment.Location = location - deployment.Xmlns = azureXmlns - - return deployment -} - -func createVMDeploymentConfig(role *Role) VMDeployment { - deployment := VMDeployment{} - deployment.Name = role.RoleName - deployment.Xmlns = azureXmlns - deployment.DeploymentSlot = "Production" - deployment.Label = role.RoleName - deployment.RoleList.Role = append(deployment.RoleList.Role, role) - - return deployment -} - -func createAzureVMRole(name, instanceSize, imageName, location string) (*Role, error) { - config := new(Role) - config.RoleName = name - config.RoleSize = instanceSize - config.RoleType = "PersistentVMRole" - config.ProvisionGuestAgent = true - var err error - config.OSVirtualHardDisk, err = createOSVirtualHardDisk(name, imageName, location) - if err != nil { - return nil, err - } - - return config, nil -} - -func createOSVirtualHardDisk(dnsName, imageName, location string) (OSVirtualHardDisk, error) { - oSVirtualHardDisk := OSVirtualHardDisk{} - - err := imageClient.ResolveImageName(imageName) - if err != nil { - return oSVirtualHardDisk, err - } - - oSVirtualHardDisk.SourceImageName = imageName - oSVirtualHardDisk.MediaLink, err = getVHDMediaLink(dnsName, location) - if err != nil { - return oSVirtualHardDisk, err - } - - return oSVirtualHardDisk, nil -} - -func getVHDMediaLink(dnsName, location string) (string, error) { - - storageService, err := storageServiceClient.GetStorageServiceByLocation(location) - if err != nil { - return "", err - } - - if storageService == nil { - - uuid, err := azure.NewUUID() - if err != nil { - return "", err - } - - serviceName := "portalvhds" + uuid - storageService, err = storageServiceClient.CreateStorageService(serviceName, location) - if err != nil { - return "", err - } - } - - blobEndpoint, err := storageServiceClient.GetBlobEndpoint(storageService) - if err != nil { - return "", err - } - - vhdMediaLink := blobEndpoint + "vhds/" + dnsName + "-" + time.Now().Local().Format("20060102150405") + ".vhd" - return vhdMediaLink, nil -} - -func createLinuxProvisioningConfig(dnsName, userName, userPassword, certPath string) (ConfigurationSet, error) { - provisioningConfig := ConfigurationSet{} - - disableSshPasswordAuthentication := false - if len(userPassword) == 0 { - disableSshPasswordAuthentication = true - // We need to set dummy password otherwise azure API will throw an error - userPassword = "P@ssword1" - } else { - err := verifyPassword(userPassword) - if err != nil { - return provisioningConfig, err - } - } - - provisioningConfig.DisableSshPasswordAuthentication = disableSshPasswordAuthentication - provisioningConfig.ConfigurationSetType = "LinuxProvisioningConfiguration" - provisioningConfig.HostName = dnsName - provisioningConfig.UserName = userName - provisioningConfig.UserPassword = userPassword - - if len(certPath) > 0 { - var err error - provisioningConfig.SSH, err = createSshConfig(certPath, userName) - if err != nil { - return provisioningConfig, err - } - } - - return provisioningConfig, nil -} - -func uploadServiceCert(dnsName, certPath string) error { - certificateConfig, err := createServiceCertDeploymentConf(certPath) - if err != nil { - return err - } - - certificateConfigBytes, err := xml.Marshal(certificateConfig) - if err != nil { - return err - } - - requestURL := fmt.Sprintf(azureCertificatListURL, dnsName) - requestId, azureErr := azure.SendAzurePostRequest(requestURL, certificateConfigBytes) - if azureErr != nil { - return azureErr - } - - err = azure.WaitAsyncOperation(requestId) - return err -} - -func createServiceCertDeploymentConf(certPath string) (ServiceCertificate, error) { - certConfig := ServiceCertificate{} - certConfig.Xmlns = azureXmlns - data, err := ioutil.ReadFile(certPath) - if err != nil { - return certConfig, err - } - - certData := base64.StdEncoding.EncodeToString(data) - certConfig.Data = certData - certConfig.CertificateFormat = "pfx" - - return certConfig, nil -} - -func createSshConfig(certPath, userName string) (SSH, error) { - sshConfig := SSH{} - publicKey := PublicKey{} - - err := checkServiceCertExtension(certPath) - if err != nil { - return sshConfig, err - } - - fingerprint, err := getServiceCertFingerprint(certPath) - if err != nil { - return sshConfig, err - } - - publicKey.Fingerprint = fingerprint - publicKey.Path = "/home/" + userName + "/.ssh/authorized_keys" - - sshConfig.PublicKeys.PublicKey = append(sshConfig.PublicKeys.PublicKey, publicKey) - return sshConfig, nil -} - -func getServiceCertFingerprint(certPath string) (string, error) { - certData, readErr := ioutil.ReadFile(certPath) - if readErr != nil { - return "", readErr - } - - block, rest := pem.Decode(certData) - if block == nil { - return "", errors.New(string(rest)) - } - - sha1sum := sha1.Sum(block.Bytes) - fingerprint := fmt.Sprintf("%X", sha1sum) - return fingerprint, nil -} - -func checkServiceCertExtension(certPath string) error { - certParts := strings.Split(certPath, ".") - certExt := certParts[len(certParts)-1] - - acceptedExtension := "pem" - if certExt != acceptedExtension { - return errors.New(fmt.Sprintf(invalidCertExtensionError, certPath, acceptedExtension)) - } - - return nil -} - -func createNetworkConfig(os string, sshPort int) (ConfigurationSet, error) { - networkConfig := ConfigurationSet{} - networkConfig.ConfigurationSetType = "NetworkConfiguration" - - var endpoint InputEndpoint - if os == osLinux { - endpoint = createEndpoint("ssh", "tcp", sshPort, 22) - } else if os == osWindows { - //!TODO add rdp endpoint - } else { - return networkConfig, errors.New(fmt.Sprintf(invalidOSError)) - } - - networkConfig.InputEndpoints.InputEndpoint = append(networkConfig.InputEndpoints.InputEndpoint, endpoint) - - return networkConfig, nil -} - -func createEndpoint(name string, protocol string, extertalPort int, internalPort int) InputEndpoint { - endpoint := InputEndpoint{} - endpoint.Name = name - endpoint.Protocol = protocol - endpoint.Port = extertalPort - endpoint.LocalPort = internalPort - - return endpoint -} - -func verifyDNSname(dns string) error { - if len(dns) < 3 || len(dns) > 25 { - return fmt.Errorf(invalidDnsLengthError) - } - - return nil -} - -func verifyPassword(password string) error { - if len(password) < 4 || len(password) > 30 { - return fmt.Errorf(invalidPasswordLengthError) - } - -next: - for _, classes := range map[string][]*unicode.RangeTable{ - "upper case": {unicode.Upper, unicode.Title}, - "lower case": {unicode.Lower}, - "numeric": {unicode.Number, unicode.Digit}, - } { - for _, r := range password { - if unicode.IsOneOf(classes, r) { - continue next - } - } - return fmt.Errorf(invalidPasswordError) - } - return nil -} - -//Region private methods ends diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmDiskClient/vmDiskClient.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmDiskClient/vmDiskClient.go deleted file mode 100644 index d8ebcbf342..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/clients/vmDiskClient/vmDiskClient.go +++ /dev/null @@ -1,29 +0,0 @@ -package vmDiskClient - -import ( - "fmt" - azure "github.com/MSOpenTech/azure-sdk-for-go" -) - -const ( - azureVMDiskURL = "services/disks/%s" -) - -//Region public methods starts - -func DeleteDisk(diskName string) error { - if len(diskName) == 0 { - return fmt.Errorf(azure.ParamNotSpecifiedError, "diskName") - } - - requestURL := fmt.Sprintf(azureVMDiskURL, diskName) - requestId, err := azure.SendAzureDeleteRequest(requestURL) - if err != nil { - return err - } - - azure.WaitAsyncOperation(requestId) - return nil -} - -//Region public methods ends diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/common.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/common.go deleted file mode 100644 index 4d164f7fd1..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/common.go +++ /dev/null @@ -1,293 +0,0 @@ -package azureSdkForGo - -import ( - "bytes" - "crypto/rand" - "encoding/xml" - "errors" - "fmt" - "github.com/MSOpenTech/azure-sdk-for-go/core/http" - "github.com/MSOpenTech/azure-sdk-for-go/core/tls" - "io" - "os/exec" - "strings" - "time" -) - -const ( - ParamNotSpecifiedError = "Parameter %s is not specified." - - azureManagementDnsName = "https://management.core.windows.net" - msVersionHeader = "x-ms-version" - msVersionHeaderValue = "2014-05-01" - contentHeader = "Content-Type" - contentHeaderValue = "application/xml" - requestIdHeader = "X-Ms-Request-Id" -) - -//Region public methods starts - -func SendAzureGetRequest(url string) ([]byte, error) { - if len(url) == 0 { - return nil, fmt.Errorf(ParamNotSpecifiedError, "url") - } - - response, err := SendAzureRequest(url, "GET", nil) - if err != nil { - return nil, err - } - - responseContent := getResponseBody(response) - return responseContent, nil -} - -func SendAzurePostRequest(url string, data []byte) (string, error) { - if len(url) == 0 { - return "", fmt.Errorf(ParamNotSpecifiedError, "url") - } - - response, err := SendAzureRequest(url, "POST", data) - if err != nil { - return "", err - } - - requestId := response.Header[requestIdHeader] - return requestId[0], nil -} - -func SendAzureDeleteRequest(url string) (string, error) { - if len(url) == 0 { - return "", fmt.Errorf(ParamNotSpecifiedError, "url") - } - - response, err := SendAzureRequest(url, "DELETE", nil) - if err != nil { - return "", err - } - - requestId := response.Header[requestIdHeader] - return requestId[0], nil -} - -func SendAzureRequest(url string, requestType string, data []byte) (*http.Response, error) { - if len(url) == 0 { - return nil, fmt.Errorf(ParamNotSpecifiedError, "url") - } - if len(requestType) == 0 { - return nil, fmt.Errorf(ParamNotSpecifiedError, "requestType") - } - - client := createHttpClient() - - response, err := sendRequest(client, url, requestType, data, 7) - if err != nil { - return nil, err - } - - return response, nil -} - -func ExecuteCommand(command string, input []byte) ([]byte, error) { - if len(command) == 0 { - return nil, fmt.Errorf(ParamNotSpecifiedError, "command") - } - - parts := strings.Fields(command) - head := parts[0] - parts = parts[1:len(parts)] - - cmd := exec.Command(head, parts...) - if input != nil { - cmd.Stdin = bytes.NewReader(input) - } - - out, err := cmd.Output() - if err != nil { - return nil, err - } - - return out, nil -} - -func GetOperationStatus(operationId string) (*Operation, error) { - if len(operationId) == 0 { - return nil, fmt.Errorf(ParamNotSpecifiedError, "operationId") - } - - operation := new(Operation) - url := "operations/" + operationId - response, azureErr := SendAzureGetRequest(url) - if azureErr != nil { - return nil, azureErr - } - - err := xml.Unmarshal(response, operation) - if err != nil { - return nil, err - } - - return operation, nil -} - -func WaitAsyncOperation(operationId string) error { - if len(operationId) == 0 { - return fmt.Errorf(ParamNotSpecifiedError, "operationId") - } - - status := "InProgress" - operation := new(Operation) - err := errors.New("") - for status == "InProgress" { - time.Sleep(2000 * time.Millisecond) - operation, err = GetOperationStatus(operationId) - if err != nil { - return err - } - - status = operation.Status - } - - if status == "Failed" { - return errors.New(operation.Error.Message) - } - - return nil -} - -func CheckStringParams(url string) ([]byte, error) { - if len(url) == 0 { - return nil, fmt.Errorf(ParamNotSpecifiedError, "url") - } - - response, err := SendAzureRequest(url, "GET", nil) - if err != nil { - return nil, err - } - - responseContent := getResponseBody(response) - return responseContent, nil -} - -// NewUUID generates a random UUID according to RFC 4122 -func NewUUID() (string, error) { - uuid := make([]byte, 16) - n, err := io.ReadFull(rand.Reader, uuid) - if n != len(uuid) || err != nil { - return "", err - } - // variant bits; see section 4.1.1 - uuid[8] = uuid[8]&^0xc0 | 0x80 - // version 4 (pseudo-random); see section 4.1.3 - uuid[6] = uuid[6]&^0xf0 | 0x40 - - //return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil - return fmt.Sprintf("%x", uuid[10:]), nil -} - -//Region public methods ends - -//Region private methods starts - -func sendRequest(client *http.Client, url string, requestType string, data []byte, numberOfRetries int) (*http.Response, error) { - request, reqErr := createAzureRequest(url, requestType, data) - if reqErr != nil { - return nil, reqErr - } - - response, err := client.Do(request) - if err != nil { - if numberOfRetries == 0 { - return nil, err - } - - return sendRequest(client, url, requestType, data, numberOfRetries-1) - } - - if response.StatusCode > 299 { - responseContent := getResponseBody(response) - azureErr := getAzureError(responseContent) - if azureErr != nil { - if numberOfRetries == 0 { - return nil, azureErr - } - - return sendRequest(client, url, requestType, data, numberOfRetries-1) - } - } - - return response, nil -} - -func getAzureError(responseBody []byte) error { - error := new(AzureError) - err := xml.Unmarshal(responseBody, error) - if err != nil { - return err - } - - return error -} - -func createAzureRequest(url string, requestType string, data []byte) (*http.Request, error) { - var request *http.Request - var err error - - url = fmt.Sprintf("%s/%s/%s", azureManagementDnsName, GetPublishSettings().SubscriptionID, url) - if data != nil { - body := bytes.NewBuffer(data) - request, err = http.NewRequest(requestType, url, body) - } else { - request, err = http.NewRequest(requestType, url, nil) - } - - if err != nil { - return nil, err - } - - request.Header.Add(msVersionHeader, msVersionHeaderValue) - request.Header.Add(contentHeader, contentHeaderValue) - - return request, nil -} - -func createHttpClient() *http.Client { - cert, _ := tls.X509KeyPair(GetPublishSettings().SubscriptionCert, GetPublishSettings().SubscriptionKey) - - ssl := &tls.Config{} - ssl.Certificates = []tls.Certificate{cert} - - client := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: ssl, - }, - } - - return client -} - -func getResponseBody(response *http.Response) []byte { - - responseBody := make([]byte, response.ContentLength) - io.ReadFull(response.Body, responseBody) - return responseBody -} - -//Region private methods ends - -type AzureError struct { - XMLName xml.Name `xml:"Error"` - Code string - Message string -} - -func (e *AzureError) Error() string { - return fmt.Sprintf("Code: %s, Message: %s", e.Code, e.Message) -} - -type Operation struct { - XMLName xml.Name `xml:"Operation"` - ID string - Status string - HttpStatusCode string - Error AzureError -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/child.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/child.go deleted file mode 100644 index 45fc2e57cd..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/child.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements CGI from the perspective of a child -// process. - -package cgi - -import ( - "bufio" - "crypto/tls" - "errors" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "strconv" - "strings" -) - -// Request returns the HTTP request as represented in the current -// environment. This assumes the current program is being run -// by a web server in a CGI environment. -// The returned Request's Body is populated, if applicable. -func Request() (*http.Request, error) { - r, err := RequestFromMap(envMap(os.Environ())) - if err != nil { - return nil, err - } - if r.ContentLength > 0 { - r.Body = ioutil.NopCloser(io.LimitReader(os.Stdin, r.ContentLength)) - } - return r, nil -} - -func envMap(env []string) map[string]string { - m := make(map[string]string) - for _, kv := range env { - if idx := strings.Index(kv, "="); idx != -1 { - m[kv[:idx]] = kv[idx+1:] - } - } - return m -} - -// RequestFromMap creates an http.Request from CGI variables. -// The returned Request's Body field is not populated. -func RequestFromMap(params map[string]string) (*http.Request, error) { - r := new(http.Request) - r.Method = params["REQUEST_METHOD"] - if r.Method == "" { - return nil, errors.New("cgi: no REQUEST_METHOD in environment") - } - - r.Proto = params["SERVER_PROTOCOL"] - var ok bool - r.ProtoMajor, r.ProtoMinor, ok = http.ParseHTTPVersion(r.Proto) - if !ok { - return nil, errors.New("cgi: invalid SERVER_PROTOCOL version") - } - - r.Close = true - r.Trailer = http.Header{} - r.Header = http.Header{} - - r.Host = params["HTTP_HOST"] - - if lenstr := params["CONTENT_LENGTH"]; lenstr != "" { - clen, err := strconv.ParseInt(lenstr, 10, 64) - if err != nil { - return nil, errors.New("cgi: bad CONTENT_LENGTH in environment: " + lenstr) - } - r.ContentLength = clen - } - - if ct := params["CONTENT_TYPE"]; ct != "" { - r.Header.Set("Content-Type", ct) - } - - // Copy "HTTP_FOO_BAR" variables to "Foo-Bar" Headers - for k, v := range params { - if !strings.HasPrefix(k, "HTTP_") || k == "HTTP_HOST" { - continue - } - r.Header.Add(strings.Replace(k[5:], "_", "-", -1), v) - } - - // TODO: cookies. parsing them isn't exported, though. - - uriStr := params["REQUEST_URI"] - if uriStr == "" { - // Fallback to SCRIPT_NAME, PATH_INFO and QUERY_STRING. - uriStr = params["SCRIPT_NAME"] + params["PATH_INFO"] - s := params["QUERY_STRING"] - if s != "" { - uriStr += "?" + s - } - } - - // There's apparently a de-facto standard for this. - // http://docstore.mik.ua/orelly/linux/cgi/ch03_02.htm#ch03-35636 - if s := params["HTTPS"]; s == "on" || s == "ON" || s == "1" { - r.TLS = &tls.ConnectionState{HandshakeComplete: true} - } - - if r.Host != "" { - // Hostname is provided, so we can reasonably construct a URL. - rawurl := r.Host + uriStr - if r.TLS == nil { - rawurl = "http://" + rawurl - } else { - rawurl = "https://" + rawurl - } - url, err := url.Parse(rawurl) - if err != nil { - return nil, errors.New("cgi: failed to parse host and REQUEST_URI into a URL: " + rawurl) - } - r.URL = url - } - // Fallback logic if we don't have a Host header or the URL - // failed to parse - if r.URL == nil { - url, err := url.Parse(uriStr) - if err != nil { - return nil, errors.New("cgi: failed to parse REQUEST_URI into a URL: " + uriStr) - } - r.URL = url - } - - // Request.RemoteAddr has its port set by Go's standard http - // server, so we do here too. We don't have one, though, so we - // use a dummy one. - r.RemoteAddr = net.JoinHostPort(params["REMOTE_ADDR"], "0") - - return r, nil -} - -// Serve executes the provided Handler on the currently active CGI -// request, if any. If there's no current CGI environment -// an error is returned. The provided handler may be nil to use -// http.DefaultServeMux. -func Serve(handler http.Handler) error { - req, err := Request() - if err != nil { - return err - } - if handler == nil { - handler = http.DefaultServeMux - } - rw := &response{ - req: req, - header: make(http.Header), - bufw: bufio.NewWriter(os.Stdout), - } - handler.ServeHTTP(rw, req) - rw.Write(nil) // make sure a response is sent - if err = rw.bufw.Flush(); err != nil { - return err - } - return nil -} - -type response struct { - req *http.Request - header http.Header - bufw *bufio.Writer - headerSent bool -} - -func (r *response) Flush() { - r.bufw.Flush() -} - -func (r *response) Header() http.Header { - return r.header -} - -func (r *response) Write(p []byte) (n int, err error) { - if !r.headerSent { - r.WriteHeader(http.StatusOK) - } - return r.bufw.Write(p) -} - -func (r *response) WriteHeader(code int) { - if r.headerSent { - // Note: explicitly using Stderr, as Stdout is our HTTP output. - fmt.Fprintf(os.Stderr, "CGI attempted to write header twice on request for %s", r.req.URL) - return - } - r.headerSent = true - fmt.Fprintf(r.bufw, "Status: %d %s\r\n", code, http.StatusText(code)) - - // Set a default Content-Type - if _, hasType := r.header["Content-Type"]; !hasType { - r.header.Add("Content-Type", "text/html; charset=utf-8") - } - - r.header.Write(r.bufw) - r.bufw.WriteString("\r\n") - r.bufw.Flush() -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/child_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/child_test.go deleted file mode 100644 index 075d8411bc..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/child_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests for CGI (the child process perspective) - -package cgi - -import ( - "testing" -) - -func TestRequest(t *testing.T) { - env := map[string]string{ - "SERVER_PROTOCOL": "HTTP/1.1", - "REQUEST_METHOD": "GET", - "HTTP_HOST": "example.com", - "HTTP_REFERER": "elsewhere", - "HTTP_USER_AGENT": "goclient", - "HTTP_FOO_BAR": "baz", - "REQUEST_URI": "/path?a=b", - "CONTENT_LENGTH": "123", - "CONTENT_TYPE": "text/xml", - "REMOTE_ADDR": "5.6.7.8", - } - req, err := RequestFromMap(env) - if err != nil { - t.Fatalf("RequestFromMap: %v", err) - } - if g, e := req.UserAgent(), "goclient"; e != g { - t.Errorf("expected UserAgent %q; got %q", e, g) - } - if g, e := req.Method, "GET"; e != g { - t.Errorf("expected Method %q; got %q", e, g) - } - if g, e := req.Header.Get("Content-Type"), "text/xml"; e != g { - t.Errorf("expected Content-Type %q; got %q", e, g) - } - if g, e := req.ContentLength, int64(123); e != g { - t.Errorf("expected ContentLength %d; got %d", e, g) - } - if g, e := req.Referer(), "elsewhere"; e != g { - t.Errorf("expected Referer %q; got %q", e, g) - } - if req.Header == nil { - t.Fatalf("unexpected nil Header") - } - if g, e := req.Header.Get("Foo-Bar"), "baz"; e != g { - t.Errorf("expected Foo-Bar %q; got %q", e, g) - } - if g, e := req.URL.String(), "http://example.com/path?a=b"; e != g { - t.Errorf("expected URL %q; got %q", e, g) - } - if g, e := req.FormValue("a"), "b"; e != g { - t.Errorf("expected FormValue(a) %q; got %q", e, g) - } - if req.Trailer == nil { - t.Errorf("unexpected nil Trailer") - } - if req.TLS != nil { - t.Errorf("expected nil TLS") - } - if e, g := "5.6.7.8:0", req.RemoteAddr; e != g { - t.Errorf("RemoteAddr: got %q; want %q", g, e) - } -} - -func TestRequestWithTLS(t *testing.T) { - env := map[string]string{ - "SERVER_PROTOCOL": "HTTP/1.1", - "REQUEST_METHOD": "GET", - "HTTP_HOST": "example.com", - "HTTP_REFERER": "elsewhere", - "REQUEST_URI": "/path?a=b", - "CONTENT_TYPE": "text/xml", - "HTTPS": "1", - "REMOTE_ADDR": "5.6.7.8", - } - req, err := RequestFromMap(env) - if err != nil { - t.Fatalf("RequestFromMap: %v", err) - } - if g, e := req.URL.String(), "https://example.com/path?a=b"; e != g { - t.Errorf("expected URL %q; got %q", e, g) - } - if req.TLS == nil { - t.Errorf("expected non-nil TLS") - } -} - -func TestRequestWithoutHost(t *testing.T) { - env := map[string]string{ - "SERVER_PROTOCOL": "HTTP/1.1", - "HTTP_HOST": "", - "REQUEST_METHOD": "GET", - "REQUEST_URI": "/path?a=b", - "CONTENT_LENGTH": "123", - } - req, err := RequestFromMap(env) - if err != nil { - t.Fatalf("RequestFromMap: %v", err) - } - if req.URL == nil { - t.Fatalf("unexpected nil URL") - } - if g, e := req.URL.String(), "/path?a=b"; e != g { - t.Errorf("URL = %q; want %q", g, e) - } -} - -func TestRequestWithoutRequestURI(t *testing.T) { - env := map[string]string{ - "SERVER_PROTOCOL": "HTTP/1.1", - "HTTP_HOST": "example.com", - "REQUEST_METHOD": "GET", - "SCRIPT_NAME": "/dir/scriptname", - "PATH_INFO": "/p1/p2", - "QUERY_STRING": "a=1&b=2", - "CONTENT_LENGTH": "123", - } - req, err := RequestFromMap(env) - if err != nil { - t.Fatalf("RequestFromMap: %v", err) - } - if req.URL == nil { - t.Fatalf("unexpected nil URL") - } - if g, e := req.URL.String(), "http://example.com/dir/scriptname/p1/p2?a=1&b=2"; e != g { - t.Errorf("URL = %q; want %q", g, e) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/host.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/host.go deleted file mode 100644 index ec95a972c1..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/host.go +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements the host side of CGI (being the webserver -// parent process). - -// Package cgi implements CGI (Common Gateway Interface) as specified -// in RFC 3875. -// -// Note that using CGI means starting a new process to handle each -// request, which is typically less efficient than using a -// long-running server. This package is intended primarily for -// compatibility with existing systems. -package cgi - -import ( - "bufio" - "fmt" - "io" - "log" - "net/http" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" -) - -var trailingPort = regexp.MustCompile(`:([0-9]+)$`) - -var osDefaultInheritEnv = map[string][]string{ - "darwin": {"DYLD_LIBRARY_PATH"}, - "freebsd": {"LD_LIBRARY_PATH"}, - "hpux": {"LD_LIBRARY_PATH", "SHLIB_PATH"}, - "irix": {"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"}, - "linux": {"LD_LIBRARY_PATH"}, - "openbsd": {"LD_LIBRARY_PATH"}, - "solaris": {"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"}, - "windows": {"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"}, -} - -// Handler runs an executable in a subprocess with a CGI environment. -type Handler struct { - Path string // path to the CGI executable - Root string // root URI prefix of handler or empty for "/" - - // Dir specifies the CGI executable's working directory. - // If Dir is empty, the base directory of Path is used. - // If Path has no base directory, the current working - // directory is used. - Dir string - - Env []string // extra environment variables to set, if any, as "key=value" - InheritEnv []string // environment variables to inherit from host, as "key" - Logger *log.Logger // optional log for errors or nil to use log.Print - Args []string // optional arguments to pass to child process - - // PathLocationHandler specifies the root http Handler that - // should handle internal redirects when the CGI process - // returns a Location header value starting with a "/", as - // specified in RFC 3875 § 6.3.2. This will likely be - // http.DefaultServeMux. - // - // If nil, a CGI response with a local URI path is instead sent - // back to the client and not redirected internally. - PathLocationHandler http.Handler -} - -// removeLeadingDuplicates remove leading duplicate in environments. -// It's possible to override environment like following. -// cgi.Handler{ -// ... -// Env: []string{"SCRIPT_FILENAME=foo.php"}, -// } -func removeLeadingDuplicates(env []string) (ret []string) { - n := len(env) - for i := 0; i < n; i++ { - e := env[i] - s := strings.SplitN(e, "=", 2)[0] - found := false - for j := i + 1; j < n; j++ { - if s == strings.SplitN(env[j], "=", 2)[0] { - found = true - break - } - } - if !found { - ret = append(ret, e) - } - } - return -} - -func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - root := h.Root - if root == "" { - root = "/" - } - - if len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" { - rw.WriteHeader(http.StatusBadRequest) - rw.Write([]byte("Chunked request bodies are not supported by CGI.")) - return - } - - pathInfo := req.URL.Path - if root != "/" && strings.HasPrefix(pathInfo, root) { - pathInfo = pathInfo[len(root):] - } - - port := "80" - if matches := trailingPort.FindStringSubmatch(req.Host); len(matches) != 0 { - port = matches[1] - } - - env := []string{ - "SERVER_SOFTWARE=go", - "SERVER_NAME=" + req.Host, - "SERVER_PROTOCOL=HTTP/1.1", - "HTTP_HOST=" + req.Host, - "GATEWAY_INTERFACE=CGI/1.1", - "REQUEST_METHOD=" + req.Method, - "QUERY_STRING=" + req.URL.RawQuery, - "REQUEST_URI=" + req.URL.RequestURI(), - "PATH_INFO=" + pathInfo, - "SCRIPT_NAME=" + root, - "SCRIPT_FILENAME=" + h.Path, - "REMOTE_ADDR=" + req.RemoteAddr, - "REMOTE_HOST=" + req.RemoteAddr, - "SERVER_PORT=" + port, - } - - if req.TLS != nil { - env = append(env, "HTTPS=on") - } - - for k, v := range req.Header { - k = strings.Map(upperCaseAndUnderscore, k) - joinStr := ", " - if k == "COOKIE" { - joinStr = "; " - } - env = append(env, "HTTP_"+k+"="+strings.Join(v, joinStr)) - } - - if req.ContentLength > 0 { - env = append(env, fmt.Sprintf("CONTENT_LENGTH=%d", req.ContentLength)) - } - if ctype := req.Header.Get("Content-Type"); ctype != "" { - env = append(env, "CONTENT_TYPE="+ctype) - } - - if h.Env != nil { - env = append(env, h.Env...) - } - - envPath := os.Getenv("PATH") - if envPath == "" { - envPath = "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin" - } - env = append(env, "PATH="+envPath) - - for _, e := range h.InheritEnv { - if v := os.Getenv(e); v != "" { - env = append(env, e+"="+v) - } - } - - for _, e := range osDefaultInheritEnv[runtime.GOOS] { - if v := os.Getenv(e); v != "" { - env = append(env, e+"="+v) - } - } - - env = removeLeadingDuplicates(env) - - var cwd, path string - if h.Dir != "" { - path = h.Path - cwd = h.Dir - } else { - cwd, path = filepath.Split(h.Path) - } - if cwd == "" { - cwd = "." - } - - internalError := func(err error) { - rw.WriteHeader(http.StatusInternalServerError) - h.printf("CGI error: %v", err) - } - - cmd := &exec.Cmd{ - Path: path, - Args: append([]string{h.Path}, h.Args...), - Dir: cwd, - Env: env, - Stderr: os.Stderr, // for now - } - if req.ContentLength != 0 { - cmd.Stdin = req.Body - } - stdoutRead, err := cmd.StdoutPipe() - if err != nil { - internalError(err) - return - } - - err = cmd.Start() - if err != nil { - internalError(err) - return - } - if hook := testHookStartProcess; hook != nil { - hook(cmd.Process) - } - defer cmd.Wait() - defer stdoutRead.Close() - - linebody := bufio.NewReaderSize(stdoutRead, 1024) - headers := make(http.Header) - statusCode := 0 - headerLines := 0 - sawBlankLine := false - for { - line, isPrefix, err := linebody.ReadLine() - if isPrefix { - rw.WriteHeader(http.StatusInternalServerError) - h.printf("cgi: long header line from subprocess.") - return - } - if err == io.EOF { - break - } - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - h.printf("cgi: error reading headers: %v", err) - return - } - if len(line) == 0 { - sawBlankLine = true - break - } - headerLines++ - parts := strings.SplitN(string(line), ":", 2) - if len(parts) < 2 { - h.printf("cgi: bogus header line: %s", string(line)) - continue - } - header, val := parts[0], parts[1] - header = strings.TrimSpace(header) - val = strings.TrimSpace(val) - switch { - case header == "Status": - if len(val) < 3 { - h.printf("cgi: bogus status (short): %q", val) - return - } - code, err := strconv.Atoi(val[0:3]) - if err != nil { - h.printf("cgi: bogus status: %q", val) - h.printf("cgi: line was %q", line) - return - } - statusCode = code - default: - headers.Add(header, val) - } - } - if headerLines == 0 || !sawBlankLine { - rw.WriteHeader(http.StatusInternalServerError) - h.printf("cgi: no headers") - return - } - - if loc := headers.Get("Location"); loc != "" { - if strings.HasPrefix(loc, "/") && h.PathLocationHandler != nil { - h.handleInternalRedirect(rw, req, loc) - return - } - if statusCode == 0 { - statusCode = http.StatusFound - } - } - - if statusCode == 0 && headers.Get("Content-Type") == "" { - rw.WriteHeader(http.StatusInternalServerError) - h.printf("cgi: missing required Content-Type in headers") - return - } - - if statusCode == 0 { - statusCode = http.StatusOK - } - - // Copy headers to rw's headers, after we've decided not to - // go into handleInternalRedirect, which won't want its rw - // headers to have been touched. - for k, vv := range headers { - for _, v := range vv { - rw.Header().Add(k, v) - } - } - - rw.WriteHeader(statusCode) - - _, err = io.Copy(rw, linebody) - if err != nil { - h.printf("cgi: copy error: %v", err) - // And kill the child CGI process so we don't hang on - // the deferred cmd.Wait above if the error was just - // the client (rw) going away. If it was a read error - // (because the child died itself), then the extra - // kill of an already-dead process is harmless (the PID - // won't be reused until the Wait above). - cmd.Process.Kill() - } -} - -func (h *Handler) printf(format string, v ...interface{}) { - if h.Logger != nil { - h.Logger.Printf(format, v...) - } else { - log.Printf(format, v...) - } -} - -func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Request, path string) { - url, err := req.URL.Parse(path) - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - h.printf("cgi: error resolving local URI path %q: %v", path, err) - return - } - // TODO: RFC 3875 isn't clear if only GET is supported, but it - // suggests so: "Note that any message-body attached to the - // request (such as for a POST request) may not be available - // to the resource that is the target of the redirect." We - // should do some tests against Apache to see how it handles - // POST, HEAD, etc. Does the internal redirect get the same - // method or just GET? What about incoming headers? - // (e.g. Cookies) Which headers, if any, are copied into the - // second request? - newReq := &http.Request{ - Method: "GET", - URL: url, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(http.Header), - Host: url.Host, - RemoteAddr: req.RemoteAddr, - TLS: req.TLS, - } - h.PathLocationHandler.ServeHTTP(rw, newReq) -} - -func upperCaseAndUnderscore(r rune) rune { - switch { - case r >= 'a' && r <= 'z': - return r - ('a' - 'A') - case r == '-': - return '_' - case r == '=': - // Maybe not part of the CGI 'spec' but would mess up - // the environment in any case, as Go represents the - // environment as a slice of "key=value" strings. - return '_' - } - // TODO: other transformations in spec or practice? - return r -} - -var testHookStartProcess func(*os.Process) // nil except for some tests diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/host_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/host_test.go deleted file mode 100644 index 8c16e6897f..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/host_test.go +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests for package cgi - -package cgi - -import ( - "bufio" - "fmt" - "io" - "net" - "net/http" - "net/http/httptest" - "os" - "os/exec" - "path/filepath" - "runtime" - "strconv" - "strings" - "testing" - "time" -) - -func newRequest(httpreq string) *http.Request { - buf := bufio.NewReader(strings.NewReader(httpreq)) - req, err := http.ReadRequest(buf) - if err != nil { - panic("cgi: bogus http request in test: " + httpreq) - } - req.RemoteAddr = "1.2.3.4" - return req -} - -func runCgiTest(t *testing.T, h *Handler, httpreq string, expectedMap map[string]string) *httptest.ResponseRecorder { - rw := httptest.NewRecorder() - req := newRequest(httpreq) - h.ServeHTTP(rw, req) - - // Make a map to hold the test map that the CGI returns. - m := make(map[string]string) - m["_body"] = rw.Body.String() - linesRead := 0 -readlines: - for { - line, err := rw.Body.ReadString('\n') - switch { - case err == io.EOF: - break readlines - case err != nil: - t.Fatalf("unexpected error reading from CGI: %v", err) - } - linesRead++ - trimmedLine := strings.TrimRight(line, "\r\n") - split := strings.SplitN(trimmedLine, "=", 2) - if len(split) != 2 { - t.Fatalf("Unexpected %d parts from invalid line number %v: %q; existing map=%v", - len(split), linesRead, line, m) - } - m[split[0]] = split[1] - } - - for key, expected := range expectedMap { - got := m[key] - if key == "cwd" { - // For Windows. golang.org/issue/4645. - fi1, _ := os.Stat(got) - fi2, _ := os.Stat(expected) - if os.SameFile(fi1, fi2) { - got = expected - } - } - if got != expected { - t.Errorf("for key %q got %q; expected %q", key, got, expected) - } - } - return rw -} - -var cgiTested, cgiWorks bool - -func check(t *testing.T) { - if !cgiTested { - cgiTested = true - cgiWorks = exec.Command("./testdata/test.cgi").Run() == nil - } - if !cgiWorks { - // No Perl on Windows, needed by test.cgi - // TODO: make the child process be Go, not Perl. - t.Skip("Skipping test: test.cgi failed.") - } -} - -func TestCGIBasicGet(t *testing.T) { - check(t) - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - expectedMap := map[string]string{ - "test": "Hello CGI", - "param-a": "b", - "param-foo": "bar", - "env-GATEWAY_INTERFACE": "CGI/1.1", - "env-HTTP_HOST": "example.com", - "env-PATH_INFO": "", - "env-QUERY_STRING": "foo=bar&a=b", - "env-REMOTE_ADDR": "1.2.3.4", - "env-REMOTE_HOST": "1.2.3.4", - "env-REQUEST_METHOD": "GET", - "env-REQUEST_URI": "/test.cgi?foo=bar&a=b", - "env-SCRIPT_FILENAME": "testdata/test.cgi", - "env-SCRIPT_NAME": "/test.cgi", - "env-SERVER_NAME": "example.com", - "env-SERVER_PORT": "80", - "env-SERVER_SOFTWARE": "go", - } - replay := runCgiTest(t, h, "GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) - - if expected, got := "text/html", replay.Header().Get("Content-Type"); got != expected { - t.Errorf("got a Content-Type of %q; expected %q", got, expected) - } - if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected { - t.Errorf("got a X-Test-Header of %q; expected %q", got, expected) - } -} - -func TestCGIBasicGetAbsPath(t *testing.T) { - check(t) - pwd, err := os.Getwd() - if err != nil { - t.Fatalf("getwd error: %v", err) - } - h := &Handler{ - Path: pwd + "/testdata/test.cgi", - Root: "/test.cgi", - } - expectedMap := map[string]string{ - "env-REQUEST_URI": "/test.cgi?foo=bar&a=b", - "env-SCRIPT_FILENAME": pwd + "/testdata/test.cgi", - "env-SCRIPT_NAME": "/test.cgi", - } - runCgiTest(t, h, "GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -func TestPathInfo(t *testing.T) { - check(t) - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - expectedMap := map[string]string{ - "param-a": "b", - "env-PATH_INFO": "/extrapath", - "env-QUERY_STRING": "a=b", - "env-REQUEST_URI": "/test.cgi/extrapath?a=b", - "env-SCRIPT_FILENAME": "testdata/test.cgi", - "env-SCRIPT_NAME": "/test.cgi", - } - runCgiTest(t, h, "GET /test.cgi/extrapath?a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -func TestPathInfoDirRoot(t *testing.T) { - check(t) - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/myscript/", - } - expectedMap := map[string]string{ - "env-PATH_INFO": "bar", - "env-QUERY_STRING": "a=b", - "env-REQUEST_URI": "/myscript/bar?a=b", - "env-SCRIPT_FILENAME": "testdata/test.cgi", - "env-SCRIPT_NAME": "/myscript/", - } - runCgiTest(t, h, "GET /myscript/bar?a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -func TestDupHeaders(t *testing.T) { - check(t) - h := &Handler{ - Path: "testdata/test.cgi", - } - expectedMap := map[string]string{ - "env-REQUEST_URI": "/myscript/bar?a=b", - "env-SCRIPT_FILENAME": "testdata/test.cgi", - "env-HTTP_COOKIE": "nom=NOM; yum=YUM", - "env-HTTP_X_FOO": "val1, val2", - } - runCgiTest(t, h, "GET /myscript/bar?a=b HTTP/1.0\n"+ - "Cookie: nom=NOM\n"+ - "Cookie: yum=YUM\n"+ - "X-Foo: val1\n"+ - "X-Foo: val2\n"+ - "Host: example.com\n\n", - expectedMap) -} - -func TestPathInfoNoRoot(t *testing.T) { - check(t) - h := &Handler{ - Path: "testdata/test.cgi", - Root: "", - } - expectedMap := map[string]string{ - "env-PATH_INFO": "/bar", - "env-QUERY_STRING": "a=b", - "env-REQUEST_URI": "/bar?a=b", - "env-SCRIPT_FILENAME": "testdata/test.cgi", - "env-SCRIPT_NAME": "/", - } - runCgiTest(t, h, "GET /bar?a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -func TestCGIBasicPost(t *testing.T) { - check(t) - postReq := `POST /test.cgi?a=b HTTP/1.0 -Host: example.com -Content-Type: application/x-www-form-urlencoded -Content-Length: 15 - -postfoo=postbar` - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - expectedMap := map[string]string{ - "test": "Hello CGI", - "param-postfoo": "postbar", - "env-REQUEST_METHOD": "POST", - "env-CONTENT_LENGTH": "15", - "env-REQUEST_URI": "/test.cgi?a=b", - } - runCgiTest(t, h, postReq, expectedMap) -} - -func chunk(s string) string { - return fmt.Sprintf("%x\r\n%s\r\n", len(s), s) -} - -// The CGI spec doesn't allow chunked requests. -func TestCGIPostChunked(t *testing.T) { - check(t) - postReq := `POST /test.cgi?a=b HTTP/1.1 -Host: example.com -Content-Type: application/x-www-form-urlencoded -Transfer-Encoding: chunked - -` + chunk("postfoo") + chunk("=") + chunk("postbar") + chunk("") - - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - expectedMap := map[string]string{} - resp := runCgiTest(t, h, postReq, expectedMap) - if got, expected := resp.Code, http.StatusBadRequest; got != expected { - t.Fatalf("Expected %v response code from chunked request body; got %d", - expected, got) - } -} - -func TestRedirect(t *testing.T) { - check(t) - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - rec := runCgiTest(t, h, "GET /test.cgi?loc=http://foo.com/ HTTP/1.0\nHost: example.com\n\n", nil) - if e, g := 302, rec.Code; e != g { - t.Errorf("expected status code %d; got %d", e, g) - } - if e, g := "http://foo.com/", rec.Header().Get("Location"); e != g { - t.Errorf("expected Location header of %q; got %q", e, g) - } -} - -func TestInternalRedirect(t *testing.T) { - check(t) - baseHandler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - fmt.Fprintf(rw, "basepath=%s\n", req.URL.Path) - fmt.Fprintf(rw, "remoteaddr=%s\n", req.RemoteAddr) - }) - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - PathLocationHandler: baseHandler, - } - expectedMap := map[string]string{ - "basepath": "/foo", - "remoteaddr": "1.2.3.4", - } - runCgiTest(t, h, "GET /test.cgi?loc=/foo HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -// TestCopyError tests that we kill the process if there's an error copying -// its output. (for example, from the client having gone away) -func TestCopyError(t *testing.T) { - check(t) - if runtime.GOOS == "windows" { - t.Skipf("skipping test on %q", runtime.GOOS) - } - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - ts := httptest.NewServer(h) - defer ts.Close() - - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - req, _ := http.NewRequest("GET", "http://example.com/test.cgi?bigresponse=1", nil) - err = req.Write(conn) - if err != nil { - t.Fatalf("Write: %v", err) - } - - res, err := http.ReadResponse(bufio.NewReader(conn), req) - if err != nil { - t.Fatalf("ReadResponse: %v", err) - } - - pidstr := res.Header.Get("X-CGI-Pid") - if pidstr == "" { - t.Fatalf("expected an X-CGI-Pid header in response") - } - pid, err := strconv.Atoi(pidstr) - if err != nil { - t.Fatalf("invalid X-CGI-Pid value") - } - - var buf [5000]byte - n, err := io.ReadFull(res.Body, buf[:]) - if err != nil { - t.Fatalf("ReadFull: %d bytes, %v", n, err) - } - - childRunning := func() bool { - return isProcessRunning(t, pid) - } - - if !childRunning() { - t.Fatalf("pre-conn.Close, expected child to be running") - } - conn.Close() - - tries := 0 - for tries < 25 && childRunning() { - time.Sleep(50 * time.Millisecond * time.Duration(tries)) - tries++ - } - if childRunning() { - t.Fatalf("post-conn.Close, expected child to be gone") - } -} - -func TestDirUnix(t *testing.T) { - check(t) - if runtime.GOOS == "windows" { - t.Skipf("skipping test on %q", runtime.GOOS) - } - cwd, _ := os.Getwd() - h := &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - Dir: cwd, - } - expectedMap := map[string]string{ - "cwd": cwd, - } - runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) - - cwd, _ = os.Getwd() - cwd = filepath.Join(cwd, "testdata") - h = &Handler{ - Path: "testdata/test.cgi", - Root: "/test.cgi", - } - expectedMap = map[string]string{ - "cwd": cwd, - } - runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -func TestDirWindows(t *testing.T) { - if runtime.GOOS != "windows" { - t.Skip("Skipping windows specific test.") - } - - cgifile, _ := filepath.Abs("testdata/test.cgi") - - var perl string - var err error - perl, err = exec.LookPath("perl") - if err != nil { - t.Skip("Skipping test: perl not found.") - } - perl, _ = filepath.Abs(perl) - - cwd, _ := os.Getwd() - h := &Handler{ - Path: perl, - Root: "/test.cgi", - Dir: cwd, - Args: []string{cgifile}, - Env: []string{"SCRIPT_FILENAME=" + cgifile}, - } - expectedMap := map[string]string{ - "cwd": cwd, - } - runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) - - // If not specify Dir on windows, working directory should be - // base directory of perl. - cwd, _ = filepath.Split(perl) - if cwd != "" && cwd[len(cwd)-1] == filepath.Separator { - cwd = cwd[:len(cwd)-1] - } - h = &Handler{ - Path: perl, - Root: "/test.cgi", - Args: []string{cgifile}, - Env: []string{"SCRIPT_FILENAME=" + cgifile}, - } - expectedMap = map[string]string{ - "cwd": cwd, - } - runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) -} - -func TestEnvOverride(t *testing.T) { - cgifile, _ := filepath.Abs("testdata/test.cgi") - - var perl string - var err error - perl, err = exec.LookPath("perl") - if err != nil { - t.Skipf("Skipping test: perl not found.") - } - perl, _ = filepath.Abs(perl) - - cwd, _ := os.Getwd() - h := &Handler{ - Path: perl, - Root: "/test.cgi", - Dir: cwd, - Args: []string{cgifile}, - Env: []string{ - "SCRIPT_FILENAME=" + cgifile, - "REQUEST_URI=/foo/bar"}, - } - expectedMap := map[string]string{ - "cwd": cwd, - "env-SCRIPT_FILENAME": cgifile, - "env-REQUEST_URI": "/foo/bar", - } - runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/matryoshka_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/matryoshka_test.go deleted file mode 100644 index 18c4803e71..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/matryoshka_test.go +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests a Go CGI program running under a Go CGI host process. -// Further, the two programs are the same binary, just checking -// their environment to figure out what mode to run in. - -package cgi - -import ( - "bytes" - "errors" - "fmt" - "io" - "net/http" - "net/http/httptest" - "os" - "runtime" - "testing" - "time" -) - -// This test is a CGI host (testing host.go) that runs its own binary -// as a child process testing the other half of CGI (child.go). -func TestHostingOurselves(t *testing.T) { - if runtime.GOOS == "nacl" { - t.Skip("skipping on nacl") - } - - h := &Handler{ - Path: os.Args[0], - Root: "/test.go", - Args: []string{"-test.run=TestBeChildCGIProcess"}, - } - expectedMap := map[string]string{ - "test": "Hello CGI-in-CGI", - "param-a": "b", - "param-foo": "bar", - "env-GATEWAY_INTERFACE": "CGI/1.1", - "env-HTTP_HOST": "example.com", - "env-PATH_INFO": "", - "env-QUERY_STRING": "foo=bar&a=b", - "env-REMOTE_ADDR": "1.2.3.4", - "env-REMOTE_HOST": "1.2.3.4", - "env-REQUEST_METHOD": "GET", - "env-REQUEST_URI": "/test.go?foo=bar&a=b", - "env-SCRIPT_FILENAME": os.Args[0], - "env-SCRIPT_NAME": "/test.go", - "env-SERVER_NAME": "example.com", - "env-SERVER_PORT": "80", - "env-SERVER_SOFTWARE": "go", - } - replay := runCgiTest(t, h, "GET /test.go?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) - - if expected, got := "text/html; charset=utf-8", replay.Header().Get("Content-Type"); got != expected { - t.Errorf("got a Content-Type of %q; expected %q", got, expected) - } - if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected { - t.Errorf("got a X-Test-Header of %q; expected %q", got, expected) - } -} - -type customWriterRecorder struct { - w io.Writer - *httptest.ResponseRecorder -} - -func (r *customWriterRecorder) Write(p []byte) (n int, err error) { - return r.w.Write(p) -} - -type limitWriter struct { - w io.Writer - n int -} - -func (w *limitWriter) Write(p []byte) (n int, err error) { - if len(p) > w.n { - p = p[:w.n] - } - if len(p) > 0 { - n, err = w.w.Write(p) - w.n -= n - } - if w.n == 0 { - err = errors.New("past write limit") - } - return -} - -// If there's an error copying the child's output to the parent, test -// that we kill the child. -func TestKillChildAfterCopyError(t *testing.T) { - if runtime.GOOS == "nacl" { - t.Skip("skipping on nacl") - } - - defer func() { testHookStartProcess = nil }() - proc := make(chan *os.Process, 1) - testHookStartProcess = func(p *os.Process) { - proc <- p - } - - h := &Handler{ - Path: os.Args[0], - Root: "/test.go", - Args: []string{"-test.run=TestBeChildCGIProcess"}, - } - req, _ := http.NewRequest("GET", "http://example.com/test.cgi?write-forever=1", nil) - rec := httptest.NewRecorder() - var out bytes.Buffer - const writeLen = 50 << 10 - rw := &customWriterRecorder{&limitWriter{&out, writeLen}, rec} - - donec := make(chan bool, 1) - go func() { - h.ServeHTTP(rw, req) - donec <- true - }() - - select { - case <-donec: - if out.Len() != writeLen || out.Bytes()[0] != 'a' { - t.Errorf("unexpected output: %q", out.Bytes()) - } - case <-time.After(5 * time.Second): - t.Errorf("timeout. ServeHTTP hung and didn't kill the child process?") - select { - case p := <-proc: - p.Kill() - t.Logf("killed process") - default: - t.Logf("didn't kill process") - } - } -} - -// Test that a child handler writing only headers works. -// golang.org/issue/7196 -func TestChildOnlyHeaders(t *testing.T) { - if runtime.GOOS == "nacl" { - t.Skip("skipping on nacl") - } - - h := &Handler{ - Path: os.Args[0], - Root: "/test.go", - Args: []string{"-test.run=TestBeChildCGIProcess"}, - } - expectedMap := map[string]string{ - "_body": "", - } - replay := runCgiTest(t, h, "GET /test.go?no-body=1 HTTP/1.0\nHost: example.com\n\n", expectedMap) - if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected { - t.Errorf("got a X-Test-Header of %q; expected %q", got, expected) - } -} - -// golang.org/issue/7198 -func Test500WithNoHeaders(t *testing.T) { want500Test(t, "/immediate-disconnect") } -func Test500WithNoContentType(t *testing.T) { want500Test(t, "/no-content-type") } -func Test500WithEmptyHeaders(t *testing.T) { want500Test(t, "/empty-headers") } - -func want500Test(t *testing.T, path string) { - h := &Handler{ - Path: os.Args[0], - Root: "/test.go", - Args: []string{"-test.run=TestBeChildCGIProcess"}, - } - expectedMap := map[string]string{ - "_body": "", - } - replay := runCgiTest(t, h, "GET "+path+" HTTP/1.0\nHost: example.com\n\n", expectedMap) - if replay.Code != 500 { - t.Errorf("Got code %d; want 500", replay.Code) - } -} - -type neverEnding byte - -func (b neverEnding) Read(p []byte) (n int, err error) { - for i := range p { - p[i] = byte(b) - } - return len(p), nil -} - -// Note: not actually a test. -func TestBeChildCGIProcess(t *testing.T) { - if os.Getenv("REQUEST_METHOD") == "" { - // Not in a CGI environment; skipping test. - return - } - switch os.Getenv("REQUEST_URI") { - case "/immediate-disconnect": - os.Exit(0) - case "/no-content-type": - fmt.Printf("Content-Length: 6\n\nHello\n") - os.Exit(0) - case "/empty-headers": - fmt.Printf("\nHello") - os.Exit(0) - } - Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - rw.Header().Set("X-Test-Header", "X-Test-Value") - req.ParseForm() - if req.FormValue("no-body") == "1" { - return - } - if req.FormValue("write-forever") == "1" { - io.Copy(rw, neverEnding('a')) - for { - time.Sleep(5 * time.Second) // hang forever, until killed - } - } - fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n") - for k, vv := range req.Form { - for _, v := range vv { - fmt.Fprintf(rw, "param-%s=%s\n", k, v) - } - } - for _, kv := range os.Environ() { - fmt.Fprintf(rw, "env-%s\n", kv) - } - })) - os.Exit(0) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/plan9_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/plan9_test.go deleted file mode 100644 index c8235831b0..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/plan9_test.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build plan9 - -package cgi - -import ( - "os" - "strconv" - "testing" -) - -func isProcessRunning(t *testing.T, pid int) bool { - _, err := os.Stat("/proc/" + strconv.Itoa(pid)) - return err == nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/posix_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/posix_test.go deleted file mode 100644 index 5ff9e7d5eb..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/posix_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !plan9 - -package cgi - -import ( - "os" - "syscall" - "testing" -) - -func isProcessRunning(t *testing.T, pid int) bool { - p, err := os.FindProcess(pid) - if err != nil { - return false - } - return p.Signal(syscall.Signal(0)) == nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/testdata/test.cgi b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/testdata/test.cgi deleted file mode 100644 index 3214df6f00..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cgi/testdata/test.cgi +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/perl -# Copyright 2011 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Test script run as a child process under cgi_test.go - -use strict; -use Cwd; - -binmode STDOUT; - -my $q = MiniCGI->new; -my $params = $q->Vars; - -if ($params->{"loc"}) { - print "Location: $params->{loc}\r\n\r\n"; - exit(0); -} - -print "Content-Type: text/html\r\n"; -print "X-CGI-Pid: $$\r\n"; -print "X-Test-Header: X-Test-Value\r\n"; -print "\r\n"; - -if ($params->{"bigresponse"}) { - # 17 MB, for OS X: golang.org/issue/4958 - for (1..(17 * 1024)) { - print "A" x 1024, "\r\n"; - } - exit 0; -} - -print "test=Hello CGI\r\n"; - -foreach my $k (sort keys %$params) { - print "param-$k=$params->{$k}\r\n"; -} - -foreach my $k (sort keys %ENV) { - my $clean_env = $ENV{$k}; - $clean_env =~ s/[\n\r]//g; - print "env-$k=$clean_env\r\n"; -} - -# NOTE: msys perl returns /c/go/src/... not C:\go\.... -my $dir = getcwd(); -if ($^O eq 'MSWin32' || $^O eq 'msys') { - if ($dir =~ /^.:/) { - $dir =~ s!/!\\!g; - } else { - my $cmd = $ENV{'COMSPEC'} || 'c:\\windows\\system32\\cmd.exe'; - $cmd =~ s!\\!/!g; - $dir = `$cmd /c cd`; - chomp $dir; - } -} -print "cwd=$dir\r\n"; - -# A minimal version of CGI.pm, for people without the perl-modules -# package installed. (CGI.pm used to be part of the Perl core, but -# some distros now bundle perl-base and perl-modules separately...) -package MiniCGI; - -sub new { - my $class = shift; - return bless {}, $class; -} - -sub Vars { - my $self = shift; - my $pairs; - if ($ENV{CONTENT_LENGTH}) { - $pairs = do { local $/; }; - } else { - $pairs = $ENV{QUERY_STRING}; - } - my $vars = {}; - foreach my $kv (split(/&/, $pairs)) { - my ($k, $v) = split(/=/, $kv, 2); - $vars->{_urldecode($k)} = _urldecode($v); - } - return $vars; -} - -sub _urldecode { - my $v = shift; - $v =~ tr/+/ /; - $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; - return $v; -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/chunked.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/chunked.go deleted file mode 100644 index 749f29d326..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/chunked.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// The wire protocol for HTTP's "chunked" Transfer-Encoding. - -// This code is duplicated in net/http and net/http/httputil. -// Please make any changes in both files. - -package http - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" -) - -const maxLineLength = 4096 // assumed <= bufio.defaultBufSize - -var ErrLineTooLong = errors.New("header line too long") - -// newChunkedReader returns a new chunkedReader that translates the data read from r -// out of HTTP "chunked" format before returning it. -// The chunkedReader returns io.EOF when the final 0-length chunk is read. -// -// newChunkedReader is not needed by normal applications. The http package -// automatically decodes chunking when reading response bodies. -func newChunkedReader(r io.Reader) io.Reader { - br, ok := r.(*bufio.Reader) - if !ok { - br = bufio.NewReader(r) - } - return &chunkedReader{r: br} -} - -type chunkedReader struct { - r *bufio.Reader - n uint64 // unread bytes in chunk - err error - buf [2]byte -} - -func (cr *chunkedReader) beginChunk() { - // chunk-size CRLF - var line []byte - line, cr.err = readLine(cr.r) - if cr.err != nil { - return - } - cr.n, cr.err = parseHexUint(line) - if cr.err != nil { - return - } - if cr.n == 0 { - cr.err = io.EOF - } -} - -func (cr *chunkedReader) chunkHeaderAvailable() bool { - n := cr.r.Buffered() - if n > 0 { - peek, _ := cr.r.Peek(n) - return bytes.IndexByte(peek, '\n') >= 0 - } - return false -} - -func (cr *chunkedReader) Read(b []uint8) (n int, err error) { - for cr.err == nil { - if cr.n == 0 { - if n > 0 && !cr.chunkHeaderAvailable() { - // We've read enough. Don't potentially block - // reading a new chunk header. - break - } - cr.beginChunk() - continue - } - if len(b) == 0 { - break - } - rbuf := b - if uint64(len(rbuf)) > cr.n { - rbuf = rbuf[:cr.n] - } - var n0 int - n0, cr.err = cr.r.Read(rbuf) - n += n0 - b = b[n0:] - cr.n -= uint64(n0) - // If we're at the end of a chunk, read the next two - // bytes to verify they are "\r\n". - if cr.n == 0 && cr.err == nil { - if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil { - if cr.buf[0] != '\r' || cr.buf[1] != '\n' { - cr.err = errors.New("malformed chunked encoding") - } - } - } - } - return n, cr.err -} - -// Read a line of bytes (up to \n) from b. -// Give up if the line exceeds maxLineLength. -// The returned bytes are a pointer into storage in -// the bufio, so they are only valid until the next bufio read. -func readLine(b *bufio.Reader) (p []byte, err error) { - if p, err = b.ReadSlice('\n'); err != nil { - // We always know when EOF is coming. - // If the caller asked for a line, there should be a line. - if err == io.EOF { - err = io.ErrUnexpectedEOF - } else if err == bufio.ErrBufferFull { - err = ErrLineTooLong - } - return nil, err - } - if len(p) >= maxLineLength { - return nil, ErrLineTooLong - } - return trimTrailingWhitespace(p), nil -} - -func trimTrailingWhitespace(b []byte) []byte { - for len(b) > 0 && isASCIISpace(b[len(b)-1]) { - b = b[:len(b)-1] - } - return b -} - -func isASCIISpace(b byte) bool { - return b == ' ' || b == '\t' || b == '\n' || b == '\r' -} - -// newChunkedWriter returns a new chunkedWriter that translates writes into HTTP -// "chunked" format before writing them to w. Closing the returned chunkedWriter -// sends the final 0-length chunk that marks the end of the stream. -// -// newChunkedWriter is not needed by normal applications. The http -// package adds chunking automatically if handlers don't set a -// Content-Length header. Using newChunkedWriter inside a handler -// would result in double chunking or chunking with a Content-Length -// length, both of which are wrong. -func newChunkedWriter(w io.Writer) io.WriteCloser { - return &chunkedWriter{w} -} - -// Writing to chunkedWriter translates to writing in HTTP chunked Transfer -// Encoding wire format to the underlying Wire chunkedWriter. -type chunkedWriter struct { - Wire io.Writer -} - -// Write the contents of data as one chunk to Wire. -// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has -// a bug since it does not check for success of io.WriteString -func (cw *chunkedWriter) Write(data []byte) (n int, err error) { - - // Don't send 0-length data. It looks like EOF for chunked encoding. - if len(data) == 0 { - return 0, nil - } - - if _, err = fmt.Fprintf(cw.Wire, "%x\r\n", len(data)); err != nil { - return 0, err - } - if n, err = cw.Wire.Write(data); err != nil { - return - } - if n != len(data) { - err = io.ErrShortWrite - return - } - _, err = io.WriteString(cw.Wire, "\r\n") - - return -} - -func (cw *chunkedWriter) Close() error { - _, err := io.WriteString(cw.Wire, "0\r\n") - return err -} - -func parseHexUint(v []byte) (n uint64, err error) { - for _, b := range v { - n <<= 4 - switch { - case '0' <= b && b <= '9': - b = b - '0' - case 'a' <= b && b <= 'f': - b = b - 'a' + 10 - case 'A' <= b && b <= 'F': - b = b - 'A' + 10 - default: - return 0, errors.New("invalid byte in chunk length") - } - n |= uint64(b) - } - return -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/chunked_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/chunked_test.go deleted file mode 100644 index 34544790af..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/chunked_test.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code is duplicated in net/http and net/http/httputil. -// Please make any changes in both files. - -package http - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "strings" - "testing" -) - -func TestChunk(t *testing.T) { - var b bytes.Buffer - - w := newChunkedWriter(&b) - const chunk1 = "hello, " - const chunk2 = "world! 0123456789abcdef" - w.Write([]byte(chunk1)) - w.Write([]byte(chunk2)) - w.Close() - - if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\n0\r\n"; g != e { - t.Fatalf("chunk writer wrote %q; want %q", g, e) - } - - r := newChunkedReader(&b) - data, err := ioutil.ReadAll(r) - if err != nil { - t.Logf(`data: "%s"`, data) - t.Fatalf("ReadAll from reader: %v", err) - } - if g, e := string(data), chunk1+chunk2; g != e { - t.Errorf("chunk reader read %q; want %q", g, e) - } -} - -func TestChunkReadMultiple(t *testing.T) { - // Bunch of small chunks, all read together. - { - var b bytes.Buffer - w := newChunkedWriter(&b) - w.Write([]byte("foo")) - w.Write([]byte("bar")) - w.Close() - - r := newChunkedReader(&b) - buf := make([]byte, 10) - n, err := r.Read(buf) - if n != 6 || err != io.EOF { - t.Errorf("Read = %d, %v; want 6, EOF", n, err) - } - buf = buf[:n] - if string(buf) != "foobar" { - t.Errorf("Read = %q; want %q", buf, "foobar") - } - } - - // One big chunk followed by a little chunk, but the small bufio.Reader size - // should prevent the second chunk header from being read. - { - var b bytes.Buffer - w := newChunkedWriter(&b) - // fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes, - // the same as the bufio ReaderSize below (the minimum), so even - // though we're going to try to Read with a buffer larger enough to also - // receive "foo", the second chunk header won't be read yet. - const fillBufChunk = "0123456789a" - const shortChunk = "foo" - w.Write([]byte(fillBufChunk)) - w.Write([]byte(shortChunk)) - w.Close() - - r := newChunkedReader(bufio.NewReaderSize(&b, 16)) - buf := make([]byte, len(fillBufChunk)+len(shortChunk)) - n, err := r.Read(buf) - if n != len(fillBufChunk) || err != nil { - t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk)) - } - buf = buf[:n] - if string(buf) != fillBufChunk { - t.Errorf("Read = %q; want %q", buf, fillBufChunk) - } - - n, err = r.Read(buf) - if n != len(shortChunk) || err != io.EOF { - t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk)) - } - } - - // And test that we see an EOF chunk, even though our buffer is already full: - { - r := newChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n"))) - buf := make([]byte, 3) - n, err := r.Read(buf) - if n != 3 || err != io.EOF { - t.Errorf("Read = %d, %v; want 3, EOF", n, err) - } - if string(buf) != "foo" { - t.Errorf("buf = %q; want foo", buf) - } - } -} - -func TestChunkReaderAllocs(t *testing.T) { - if testing.Short() { - t.Skip("skipping in short mode") - } - var buf bytes.Buffer - w := newChunkedWriter(&buf) - a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc") - w.Write(a) - w.Write(b) - w.Write(c) - w.Close() - - readBuf := make([]byte, len(a)+len(b)+len(c)+1) - byter := bytes.NewReader(buf.Bytes()) - bufr := bufio.NewReader(byter) - mallocs := testing.AllocsPerRun(100, func() { - byter.Seek(0, 0) - bufr.Reset(byter) - r := newChunkedReader(bufr) - n, err := io.ReadFull(r, readBuf) - if n != len(readBuf)-1 { - t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1) - } - if err != io.ErrUnexpectedEOF { - t.Fatalf("read error = %v; want ErrUnexpectedEOF", err) - } - }) - if mallocs > 1.5 { - t.Errorf("mallocs = %v; want 1", mallocs) - } -} - -func TestParseHexUint(t *testing.T) { - for i := uint64(0); i <= 1234; i++ { - line := []byte(fmt.Sprintf("%x", i)) - got, err := parseHexUint(line) - if err != nil { - t.Fatalf("on %d: %v", i, err) - } - if got != i { - t.Errorf("for input %q = %d; want %d", line, got, i) - } - } - _, err := parseHexUint([]byte("bogus")) - if err == nil { - t.Error("expected error on bogus input") - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/client.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/client.go deleted file mode 100644 index a5a3abe613..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/client.go +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP client. See RFC 2616. -// -// This is the high-level Client interface. -// The low-level implementation is in transport.go. - -package http - -import ( - "encoding/base64" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net/url" - "strings" - "sync" - "time" -) - -// A Client is an HTTP client. Its zero value (DefaultClient) is a -// usable client that uses DefaultTransport. -// -// The Client's Transport typically has internal state (cached TCP -// connections), so Clients should be reused instead of created as -// needed. Clients are safe for concurrent use by multiple goroutines. -// -// A Client is higher-level than a RoundTripper (such as Transport) -// and additionally handles HTTP details such as cookies and -// redirects. -type Client struct { - // Transport specifies the mechanism by which individual - // HTTP requests are made. - // If nil, DefaultTransport is used. - Transport RoundTripper - - // CheckRedirect specifies the policy for handling redirects. - // If CheckRedirect is not nil, the client calls it before - // following an HTTP redirect. The arguments req and via are - // the upcoming request and the requests made already, oldest - // first. If CheckRedirect returns an error, the Client's Get - // method returns both the previous Response and - // CheckRedirect's error (wrapped in a url.Error) instead of - // issuing the Request req. - // - // If CheckRedirect is nil, the Client uses its default policy, - // which is to stop after 10 consecutive requests. - CheckRedirect func(req *Request, via []*Request) error - - // Jar specifies the cookie jar. - // If Jar is nil, cookies are not sent in requests and ignored - // in responses. - Jar CookieJar - - // Timeout specifies a time limit for requests made by this - // Client. The timeout includes connection time, any - // redirects, and reading the response body. The timer remains - // running after Get, Head, Post, or Do return and will - // interrupt reading of the Response.Body. - // - // A Timeout of zero means no timeout. - // - // The Client's Transport must support the CancelRequest - // method or Client will return errors when attempting to make - // a request with Get, Head, Post, or Do. Client's default - // Transport (DefaultTransport) supports CancelRequest. - Timeout time.Duration -} - -// DefaultClient is the default Client and is used by Get, Head, and Post. -var DefaultClient = &Client{} - -// RoundTripper is an interface representing the ability to execute a -// single HTTP transaction, obtaining the Response for a given Request. -// -// A RoundTripper must be safe for concurrent use by multiple -// goroutines. -type RoundTripper interface { - // RoundTrip executes a single HTTP transaction, returning - // the Response for the request req. RoundTrip should not - // attempt to interpret the response. In particular, - // RoundTrip must return err == nil if it obtained a response, - // regardless of the response's HTTP status code. A non-nil - // err should be reserved for failure to obtain a response. - // Similarly, RoundTrip should not attempt to handle - // higher-level protocol details such as redirects, - // authentication, or cookies. - // - // RoundTrip should not modify the request, except for - // consuming and closing the Body, including on errors. The - // request's URL and Header fields are guaranteed to be - // initialized. - RoundTrip(*Request) (*Response, error) -} - -// Given a string of the form "host", "host:port", or "[ipv6::address]:port", -// return true if the string includes a port. -func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") } - -// Used in Send to implement io.ReadCloser by bundling together the -// bufio.Reader through which we read the response, and the underlying -// network connection. -type readClose struct { - io.Reader - io.Closer -} - -func (c *Client) send(req *Request) (*Response, error) { - if c.Jar != nil { - for _, cookie := range c.Jar.Cookies(req.URL) { - req.AddCookie(cookie) - } - } - resp, err := send(req, c.transport()) - if err != nil { - return nil, err - } - if c.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - c.Jar.SetCookies(req.URL, rc) - } - } - return resp, err -} - -// Do sends an HTTP request and returns an HTTP response, following -// policy (e.g. redirects, cookies, auth) as configured on the client. -// -// An error is returned if caused by client policy (such as -// CheckRedirect), or if there was an HTTP protocol error. -// A non-2xx response doesn't cause an error. -// -// When err is nil, resp always contains a non-nil resp.Body. -// -// Callers should close resp.Body when done reading from it. If -// resp.Body is not closed, the Client's underlying RoundTripper -// (typically Transport) may not be able to re-use a persistent TCP -// connection to the server for a subsequent "keep-alive" request. -// -// The request Body, if non-nil, will be closed by the underlying -// Transport, even on errors. -// -// Generally Get, Post, or PostForm will be used instead of Do. -func (c *Client) Do(req *Request) (resp *Response, err error) { - if req.Method == "GET" || req.Method == "HEAD" { - return c.doFollowingRedirects(req, shouldRedirectGet) - } - if req.Method == "POST" || req.Method == "PUT" { - return c.doFollowingRedirects(req, shouldRedirectPost) - } - return c.send(req) -} - -func (c *Client) transport() RoundTripper { - if c.Transport != nil { - return c.Transport - } - return DefaultTransport -} - -// send issues an HTTP request. -// Caller should close resp.Body when done reading from it. -func send(req *Request, t RoundTripper) (resp *Response, err error) { - if t == nil { - req.closeBody() - return nil, errors.New("http: no Client.Transport or DefaultTransport") - } - - if req.URL == nil { - req.closeBody() - return nil, errors.New("http: nil Request.URL") - } - - if req.RequestURI != "" { - req.closeBody() - return nil, errors.New("http: Request.RequestURI can't be set in client requests.") - } - - // Most the callers of send (Get, Post, et al) don't need - // Headers, leaving it uninitialized. We guarantee to the - // Transport that this has been initialized, though. - if req.Header == nil { - req.Header = make(Header) - } - - if u := req.URL.User; u != nil { - username := u.Username() - password, _ := u.Password() - req.Header.Set("Authorization", "Basic "+basicAuth(username, password)) - } - resp, err = t.RoundTrip(req) - if err != nil { - if resp != nil { - log.Printf("RoundTripper returned a response & error; ignoring response") - } - return nil, err - } - return resp, nil -} - -// See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt -// "To receive authorization, the client sends the userid and password, -// separated by a single colon (":") character, within a base64 -// encoded string in the credentials." -// It is not meant to be urlencoded. -func basicAuth(username, password string) string { - auth := username + ":" + password - return base64.StdEncoding.EncodeToString([]byte(auth)) -} - -// True if the specified HTTP status code is one for which the Get utility should -// automatically redirect. -func shouldRedirectGet(statusCode int) bool { - switch statusCode { - case StatusMovedPermanently, StatusFound, StatusSeeOther, StatusTemporaryRedirect: - return true - } - return false -} - -// True if the specified HTTP status code is one for which the Post utility should -// automatically redirect. -func shouldRedirectPost(statusCode int) bool { - switch statusCode { - case StatusFound, StatusSeeOther: - return true - } - return false -} - -// Get issues a GET to the specified URL. If the response is one of the following -// redirect codes, Get follows the redirect, up to a maximum of 10 redirects: -// -// 301 (Moved Permanently) -// 302 (Found) -// 303 (See Other) -// 307 (Temporary Redirect) -// -// An error is returned if there were too many redirects or if there -// was an HTTP protocol error. A non-2xx response doesn't cause an -// error. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -// -// Get is a wrapper around DefaultClient.Get. -func Get(url string) (resp *Response, err error) { - return DefaultClient.Get(url) -} - -// Get issues a GET to the specified URL. If the response is one of the -// following redirect codes, Get follows the redirect after calling the -// Client's CheckRedirect function. -// -// 301 (Moved Permanently) -// 302 (Found) -// 303 (See Other) -// 307 (Temporary Redirect) -// -// An error is returned if the Client's CheckRedirect function fails -// or if there was an HTTP protocol error. A non-2xx response doesn't -// cause an error. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -func (c *Client) Get(url string) (resp *Response, err error) { - req, err := NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - return c.doFollowingRedirects(req, shouldRedirectGet) -} - -func (c *Client) doFollowingRedirects(ireq *Request, shouldRedirect func(int) bool) (resp *Response, err error) { - var base *url.URL - redirectChecker := c.CheckRedirect - if redirectChecker == nil { - redirectChecker = defaultCheckRedirect - } - var via []*Request - - if ireq.URL == nil { - ireq.closeBody() - return nil, errors.New("http: nil Request.URL") - } - - var reqmu sync.Mutex // guards req - req := ireq - - var timer *time.Timer - if c.Timeout > 0 { - type canceler interface { - CancelRequest(*Request) - } - tr, ok := c.transport().(canceler) - if !ok { - return nil, fmt.Errorf("net/http: Client Transport of type %T doesn't support CancelRequest; Timeout not supported", c.transport()) - } - timer = time.AfterFunc(c.Timeout, func() { - reqmu.Lock() - defer reqmu.Unlock() - tr.CancelRequest(req) - }) - } - - urlStr := "" // next relative or absolute URL to fetch (after first request) - redirectFailed := false - for redirect := 0; ; redirect++ { - if redirect != 0 { - nreq := new(Request) - nreq.Method = ireq.Method - if ireq.Method == "POST" || ireq.Method == "PUT" { - nreq.Method = "GET" - } - nreq.Header = make(Header) - nreq.URL, err = base.Parse(urlStr) - if err != nil { - break - } - if len(via) > 0 { - // Add the Referer header. - lastReq := via[len(via)-1] - if lastReq.URL.Scheme != "https" { - nreq.Header.Set("Referer", lastReq.URL.String()) - } - - err = redirectChecker(nreq, via) - if err != nil { - redirectFailed = true - break - } - } - reqmu.Lock() - req = nreq - reqmu.Unlock() - } - - urlStr = req.URL.String() - if resp, err = c.send(req); err != nil { - break - } - - if shouldRedirect(resp.StatusCode) { - // Read the body if small so underlying TCP connection will be re-used. - // No need to check for errors: if it fails, Transport won't reuse it anyway. - const maxBodySlurpSize = 2 << 10 - if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize { - io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize) - } - resp.Body.Close() - if urlStr = resp.Header.Get("Location"); urlStr == "" { - err = errors.New(fmt.Sprintf("%d response missing Location header", resp.StatusCode)) - break - } - base = req.URL - via = append(via, req) - continue - } - if timer != nil { - resp.Body = &cancelTimerBody{timer, resp.Body} - } - return resp, nil - } - - method := ireq.Method - urlErr := &url.Error{ - Op: method[0:1] + strings.ToLower(method[1:]), - URL: urlStr, - Err: err, - } - - if redirectFailed { - // Special case for Go 1 compatibility: return both the response - // and an error if the CheckRedirect function failed. - // See http://golang.org/issue/3795 - return resp, urlErr - } - - if resp != nil { - resp.Body.Close() - } - return nil, urlErr -} - -func defaultCheckRedirect(req *Request, via []*Request) error { - if len(via) >= 10 { - return errors.New("stopped after 10 redirects") - } - return nil -} - -// Post issues a POST to the specified URL. -// -// Caller should close resp.Body when done reading from it. -// -// Post is a wrapper around DefaultClient.Post -func Post(url string, bodyType string, body io.Reader) (resp *Response, err error) { - return DefaultClient.Post(url, bodyType, body) -} - -// Post issues a POST to the specified URL. -// -// Caller should close resp.Body when done reading from it. -// -// If the provided body is also an io.Closer, it is closed after the -// request. -func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) { - req, err := NewRequest("POST", url, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", bodyType) - return c.doFollowingRedirects(req, shouldRedirectPost) -} - -// PostForm issues a POST to the specified URL, with data's keys and -// values URL-encoded as the request body. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -// -// PostForm is a wrapper around DefaultClient.PostForm -func PostForm(url string, data url.Values) (resp *Response, err error) { - return DefaultClient.PostForm(url, data) -} - -// PostForm issues a POST to the specified URL, -// with data's keys and values urlencoded as the request body. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) { - return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} - -// Head issues a HEAD to the specified URL. If the response is one of the -// following redirect codes, Head follows the redirect after calling the -// Client's CheckRedirect function. -// -// 301 (Moved Permanently) -// 302 (Found) -// 303 (See Other) -// 307 (Temporary Redirect) -// -// Head is a wrapper around DefaultClient.Head -func Head(url string) (resp *Response, err error) { - return DefaultClient.Head(url) -} - -// Head issues a HEAD to the specified URL. If the response is one of the -// following redirect codes, Head follows the redirect after calling the -// Client's CheckRedirect function. -// -// 301 (Moved Permanently) -// 302 (Found) -// 303 (See Other) -// 307 (Temporary Redirect) -func (c *Client) Head(url string) (resp *Response, err error) { - req, err := NewRequest("HEAD", url, nil) - if err != nil { - return nil, err - } - return c.doFollowingRedirects(req, shouldRedirectGet) -} - -type cancelTimerBody struct { - t *time.Timer - rc io.ReadCloser -} - -func (b *cancelTimerBody) Read(p []byte) (n int, err error) { - n, err = b.rc.Read(p) - if err == io.EOF { - b.t.Stop() - } - return -} - -func (b *cancelTimerBody) Close() error { - err := b.rc.Close() - b.t.Stop() - return err -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/client_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/client_test.go deleted file mode 100644 index 6392c1baf3..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/client_test.go +++ /dev/null @@ -1,1038 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests for client.go - -package http_test - -import ( - "bytes" - "crypto/tls" - "crypto/x509" - "encoding/base64" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net" - . "net/http" - "net/http/httptest" - "net/url" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "testing" - "time" -) - -var robotsTxtHandler = HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Last-Modified", "sometime") - fmt.Fprintf(w, "User-agent: go\nDisallow: /something/") -}) - -// pedanticReadAll works like ioutil.ReadAll but additionally -// verifies that r obeys the documented io.Reader contract. -func pedanticReadAll(r io.Reader) (b []byte, err error) { - var bufa [64]byte - buf := bufa[:] - for { - n, err := r.Read(buf) - if n == 0 && err == nil { - return nil, fmt.Errorf("Read: n=0 with err=nil") - } - b = append(b, buf[:n]...) - if err == io.EOF { - n, err := r.Read(buf) - if n != 0 || err != io.EOF { - return nil, fmt.Errorf("Read: n=%d err=%#v after EOF", n, err) - } - return b, nil - } - if err != nil { - return b, err - } - } -} - -type chanWriter chan string - -func (w chanWriter) Write(p []byte) (n int, err error) { - w <- string(p) - return len(p), nil -} - -func TestClient(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(robotsTxtHandler) - defer ts.Close() - - r, err := Get(ts.URL) - var b []byte - if err == nil { - b, err = pedanticReadAll(r.Body) - r.Body.Close() - } - if err != nil { - t.Error(err) - } else if s := string(b); !strings.HasPrefix(s, "User-agent:") { - t.Errorf("Incorrect page body (did not begin with User-agent): %q", s) - } -} - -func TestClientHead(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(robotsTxtHandler) - defer ts.Close() - - r, err := Head(ts.URL) - if err != nil { - t.Fatal(err) - } - if _, ok := r.Header["Last-Modified"]; !ok { - t.Error("Last-Modified header not found.") - } -} - -type recordingTransport struct { - req *Request -} - -func (t *recordingTransport) RoundTrip(req *Request) (resp *Response, err error) { - t.req = req - return nil, errors.New("dummy impl") -} - -func TestGetRequestFormat(t *testing.T) { - defer afterTest(t) - tr := &recordingTransport{} - client := &Client{Transport: tr} - url := "http://dummy.faketld/" - client.Get(url) // Note: doesn't hit network - if tr.req.Method != "GET" { - t.Errorf("expected method %q; got %q", "GET", tr.req.Method) - } - if tr.req.URL.String() != url { - t.Errorf("expected URL %q; got %q", url, tr.req.URL.String()) - } - if tr.req.Header == nil { - t.Errorf("expected non-nil request Header") - } -} - -func TestPostRequestFormat(t *testing.T) { - defer afterTest(t) - tr := &recordingTransport{} - client := &Client{Transport: tr} - - url := "http://dummy.faketld/" - json := `{"key":"value"}` - b := strings.NewReader(json) - client.Post(url, "application/json", b) // Note: doesn't hit network - - if tr.req.Method != "POST" { - t.Errorf("got method %q, want %q", tr.req.Method, "POST") - } - if tr.req.URL.String() != url { - t.Errorf("got URL %q, want %q", tr.req.URL.String(), url) - } - if tr.req.Header == nil { - t.Fatalf("expected non-nil request Header") - } - if tr.req.Close { - t.Error("got Close true, want false") - } - if g, e := tr.req.ContentLength, int64(len(json)); g != e { - t.Errorf("got ContentLength %d, want %d", g, e) - } -} - -func TestPostFormRequestFormat(t *testing.T) { - defer afterTest(t) - tr := &recordingTransport{} - client := &Client{Transport: tr} - - urlStr := "http://dummy.faketld/" - form := make(url.Values) - form.Set("foo", "bar") - form.Add("foo", "bar2") - form.Set("bar", "baz") - client.PostForm(urlStr, form) // Note: doesn't hit network - - if tr.req.Method != "POST" { - t.Errorf("got method %q, want %q", tr.req.Method, "POST") - } - if tr.req.URL.String() != urlStr { - t.Errorf("got URL %q, want %q", tr.req.URL.String(), urlStr) - } - if tr.req.Header == nil { - t.Fatalf("expected non-nil request Header") - } - if g, e := tr.req.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; g != e { - t.Errorf("got Content-Type %q, want %q", g, e) - } - if tr.req.Close { - t.Error("got Close true, want false") - } - // Depending on map iteration, body can be either of these. - expectedBody := "foo=bar&foo=bar2&bar=baz" - expectedBody1 := "bar=baz&foo=bar&foo=bar2" - if g, e := tr.req.ContentLength, int64(len(expectedBody)); g != e { - t.Errorf("got ContentLength %d, want %d", g, e) - } - bodyb, err := ioutil.ReadAll(tr.req.Body) - if err != nil { - t.Fatalf("ReadAll on req.Body: %v", err) - } - if g := string(bodyb); g != expectedBody && g != expectedBody1 { - t.Errorf("got body %q, want %q or %q", g, expectedBody, expectedBody1) - } -} - -func TestClientRedirects(t *testing.T) { - defer afterTest(t) - var ts *httptest.Server - ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - n, _ := strconv.Atoi(r.FormValue("n")) - // Test Referer header. (7 is arbitrary position to test at) - if n == 7 { - if g, e := r.Referer(), ts.URL+"/?n=6"; e != g { - t.Errorf("on request ?n=7, expected referer of %q; got %q", e, g) - } - } - if n < 15 { - Redirect(w, r, fmt.Sprintf("/?n=%d", n+1), StatusFound) - return - } - fmt.Fprintf(w, "n=%d", n) - })) - defer ts.Close() - - c := &Client{} - _, err := c.Get(ts.URL) - if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { - t.Errorf("with default client Get, expected error %q, got %q", e, g) - } - - // HEAD request should also have the ability to follow redirects. - _, err = c.Head(ts.URL) - if e, g := "Head /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { - t.Errorf("with default client Head, expected error %q, got %q", e, g) - } - - // Do should also follow redirects. - greq, _ := NewRequest("GET", ts.URL, nil) - _, err = c.Do(greq) - if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { - t.Errorf("with default client Do, expected error %q, got %q", e, g) - } - - var checkErr error - var lastVia []*Request - c = &Client{CheckRedirect: func(_ *Request, via []*Request) error { - lastVia = via - return checkErr - }} - res, err := c.Get(ts.URL) - if err != nil { - t.Fatalf("Get error: %v", err) - } - res.Body.Close() - finalUrl := res.Request.URL.String() - if e, g := "", fmt.Sprintf("%v", err); e != g { - t.Errorf("with custom client, expected error %q, got %q", e, g) - } - if !strings.HasSuffix(finalUrl, "/?n=15") { - t.Errorf("expected final url to end in /?n=15; got url %q", finalUrl) - } - if e, g := 15, len(lastVia); e != g { - t.Errorf("expected lastVia to have contained %d elements; got %d", e, g) - } - - checkErr = errors.New("no redirects allowed") - res, err = c.Get(ts.URL) - if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr { - t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err) - } - if res == nil { - t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)") - } - res.Body.Close() - if res.Header.Get("Location") == "" { - t.Errorf("no Location header in Response") - } -} - -func TestPostRedirects(t *testing.T) { - defer afterTest(t) - var log struct { - sync.Mutex - bytes.Buffer - } - var ts *httptest.Server - ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - log.Lock() - fmt.Fprintf(&log.Buffer, "%s %s ", r.Method, r.RequestURI) - log.Unlock() - if v := r.URL.Query().Get("code"); v != "" { - code, _ := strconv.Atoi(v) - if code/100 == 3 { - w.Header().Set("Location", ts.URL) - } - w.WriteHeader(code) - } - })) - defer ts.Close() - tests := []struct { - suffix string - want int // response code - }{ - {"/", 200}, - {"/?code=301", 301}, - {"/?code=302", 200}, - {"/?code=303", 200}, - {"/?code=404", 404}, - } - for _, tt := range tests { - res, err := Post(ts.URL+tt.suffix, "text/plain", strings.NewReader("Some content")) - if err != nil { - t.Fatal(err) - } - if res.StatusCode != tt.want { - t.Errorf("POST %s: status code = %d; want %d", tt.suffix, res.StatusCode, tt.want) - } - } - log.Lock() - got := log.String() - log.Unlock() - want := "POST / POST /?code=301 POST /?code=302 GET / POST /?code=303 GET / POST /?code=404 " - if got != want { - t.Errorf("Log differs.\n Got: %q\nWant: %q", got, want) - } -} - -var expectedCookies = []*Cookie{ - {Name: "ChocolateChip", Value: "tasty"}, - {Name: "First", Value: "Hit"}, - {Name: "Second", Value: "Hit"}, -} - -var echoCookiesRedirectHandler = HandlerFunc(func(w ResponseWriter, r *Request) { - for _, cookie := range r.Cookies() { - SetCookie(w, cookie) - } - if r.URL.Path == "/" { - SetCookie(w, expectedCookies[1]) - Redirect(w, r, "/second", StatusMovedPermanently) - } else { - SetCookie(w, expectedCookies[2]) - w.Write([]byte("hello")) - } -}) - -func TestClientSendsCookieFromJar(t *testing.T) { - tr := &recordingTransport{} - client := &Client{Transport: tr} - client.Jar = &TestJar{perURL: make(map[string][]*Cookie)} - us := "http://dummy.faketld/" - u, _ := url.Parse(us) - client.Jar.SetCookies(u, expectedCookies) - - client.Get(us) // Note: doesn't hit network - matchReturnedCookies(t, expectedCookies, tr.req.Cookies()) - - client.Head(us) // Note: doesn't hit network - matchReturnedCookies(t, expectedCookies, tr.req.Cookies()) - - client.Post(us, "text/plain", strings.NewReader("body")) // Note: doesn't hit network - matchReturnedCookies(t, expectedCookies, tr.req.Cookies()) - - client.PostForm(us, url.Values{}) // Note: doesn't hit network - matchReturnedCookies(t, expectedCookies, tr.req.Cookies()) - - req, _ := NewRequest("GET", us, nil) - client.Do(req) // Note: doesn't hit network - matchReturnedCookies(t, expectedCookies, tr.req.Cookies()) - - req, _ = NewRequest("POST", us, nil) - client.Do(req) // Note: doesn't hit network - matchReturnedCookies(t, expectedCookies, tr.req.Cookies()) -} - -// Just enough correctness for our redirect tests. Uses the URL.Host as the -// scope of all cookies. -type TestJar struct { - m sync.Mutex - perURL map[string][]*Cookie -} - -func (j *TestJar) SetCookies(u *url.URL, cookies []*Cookie) { - j.m.Lock() - defer j.m.Unlock() - if j.perURL == nil { - j.perURL = make(map[string][]*Cookie) - } - j.perURL[u.Host] = cookies -} - -func (j *TestJar) Cookies(u *url.URL) []*Cookie { - j.m.Lock() - defer j.m.Unlock() - return j.perURL[u.Host] -} - -func TestRedirectCookiesJar(t *testing.T) { - defer afterTest(t) - var ts *httptest.Server - ts = httptest.NewServer(echoCookiesRedirectHandler) - defer ts.Close() - c := &Client{ - Jar: new(TestJar), - } - u, _ := url.Parse(ts.URL) - c.Jar.SetCookies(u, []*Cookie{expectedCookies[0]}) - resp, err := c.Get(ts.URL) - if err != nil { - t.Fatalf("Get: %v", err) - } - resp.Body.Close() - matchReturnedCookies(t, expectedCookies, resp.Cookies()) -} - -func matchReturnedCookies(t *testing.T, expected, given []*Cookie) { - if len(given) != len(expected) { - t.Logf("Received cookies: %v", given) - t.Errorf("Expected %d cookies, got %d", len(expected), len(given)) - } - for _, ec := range expected { - foundC := false - for _, c := range given { - if ec.Name == c.Name && ec.Value == c.Value { - foundC = true - break - } - } - if !foundC { - t.Errorf("Missing cookie %v", ec) - } - } -} - -func TestJarCalls(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - pathSuffix := r.RequestURI[1:] - if r.RequestURI == "/nosetcookie" { - return // dont set cookies for this path - } - SetCookie(w, &Cookie{Name: "name" + pathSuffix, Value: "val" + pathSuffix}) - if r.RequestURI == "/" { - Redirect(w, r, "http://secondhost.fake/secondpath", 302) - } - })) - defer ts.Close() - jar := new(RecordingJar) - c := &Client{ - Jar: jar, - Transport: &Transport{ - Dial: func(_ string, _ string) (net.Conn, error) { - return net.Dial("tcp", ts.Listener.Addr().String()) - }, - }, - } - _, err := c.Get("http://firsthost.fake/") - if err != nil { - t.Fatal(err) - } - _, err = c.Get("http://firsthost.fake/nosetcookie") - if err != nil { - t.Fatal(err) - } - got := jar.log.String() - want := `Cookies("http://firsthost.fake/") -SetCookie("http://firsthost.fake/", [name=val]) -Cookies("http://secondhost.fake/secondpath") -SetCookie("http://secondhost.fake/secondpath", [namesecondpath=valsecondpath]) -Cookies("http://firsthost.fake/nosetcookie") -` - if got != want { - t.Errorf("Got Jar calls:\n%s\nWant:\n%s", got, want) - } -} - -// RecordingJar keeps a log of calls made to it, without -// tracking any cookies. -type RecordingJar struct { - mu sync.Mutex - log bytes.Buffer -} - -func (j *RecordingJar) SetCookies(u *url.URL, cookies []*Cookie) { - j.logf("SetCookie(%q, %v)\n", u, cookies) -} - -func (j *RecordingJar) Cookies(u *url.URL) []*Cookie { - j.logf("Cookies(%q)\n", u) - return nil -} - -func (j *RecordingJar) logf(format string, args ...interface{}) { - j.mu.Lock() - defer j.mu.Unlock() - fmt.Fprintf(&j.log, format, args...) -} - -func TestStreamingGet(t *testing.T) { - defer afterTest(t) - say := make(chan string) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.(Flusher).Flush() - for str := range say { - w.Write([]byte(str)) - w.(Flusher).Flush() - } - })) - defer ts.Close() - - c := &Client{} - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - var buf [10]byte - for _, str := range []string{"i", "am", "also", "known", "as", "comet"} { - say <- str - n, err := io.ReadFull(res.Body, buf[0:len(str)]) - if err != nil { - t.Fatalf("ReadFull on %q: %v", str, err) - } - if n != len(str) { - t.Fatalf("Receiving %q, only read %d bytes", str, n) - } - got := string(buf[0:n]) - if got != str { - t.Fatalf("Expected %q, got %q", str, got) - } - } - close(say) - _, err = io.ReadFull(res.Body, buf[0:1]) - if err != io.EOF { - t.Fatalf("at end expected EOF, got %v", err) - } -} - -type writeCountingConn struct { - net.Conn - count *int -} - -func (c *writeCountingConn) Write(p []byte) (int, error) { - *c.count++ - return c.Conn.Write(p) -} - -// TestClientWrites verifies that client requests are buffered and we -// don't send a TCP packet per line of the http request + body. -func TestClientWrites(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - })) - defer ts.Close() - - writes := 0 - dialer := func(netz string, addr string) (net.Conn, error) { - c, err := net.Dial(netz, addr) - if err == nil { - c = &writeCountingConn{c, &writes} - } - return c, err - } - c := &Client{Transport: &Transport{Dial: dialer}} - - _, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - if writes != 1 { - t.Errorf("Get request did %d Write calls, want 1", writes) - } - - writes = 0 - _, err = c.PostForm(ts.URL, url.Values{"foo": {"bar"}}) - if err != nil { - t.Fatal(err) - } - if writes != 1 { - t.Errorf("Post request did %d Write calls, want 1", writes) - } -} - -func TestClientInsecureTransport(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Write([]byte("Hello")) - })) - errc := make(chanWriter, 10) // but only expecting 1 - ts.Config.ErrorLog = log.New(errc, "", 0) - defer ts.Close() - - // TODO(bradfitz): add tests for skipping hostname checks too? - // would require a new cert for testing, and probably - // redundant with these tests. - for _, insecure := range []bool{true, false} { - tr := &Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: insecure, - }, - } - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - res, err := c.Get(ts.URL) - if (err == nil) != insecure { - t.Errorf("insecure=%v: got unexpected err=%v", insecure, err) - } - if res != nil { - res.Body.Close() - } - } - - select { - case v := <-errc: - if !strings.Contains(v, "TLS handshake error") { - t.Errorf("expected an error log message containing 'TLS handshake error'; got %q", v) - } - case <-time.After(5 * time.Second): - t.Errorf("timeout waiting for logged error") - } - -} - -func TestClientErrorWithRequestURI(t *testing.T) { - defer afterTest(t) - req, _ := NewRequest("GET", "http://localhost:1234/", nil) - req.RequestURI = "/this/field/is/illegal/and/should/error/" - _, err := DefaultClient.Do(req) - if err == nil { - t.Fatalf("expected an error") - } - if !strings.Contains(err.Error(), "RequestURI") { - t.Errorf("wanted error mentioning RequestURI; got error: %v", err) - } -} - -func newTLSTransport(t *testing.T, ts *httptest.Server) *Transport { - certs := x509.NewCertPool() - for _, c := range ts.TLS.Certificates { - roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1]) - if err != nil { - t.Fatalf("error parsing server's root cert: %v", err) - } - for _, root := range roots { - certs.AddCert(root) - } - } - return &Transport{ - TLSClientConfig: &tls.Config{RootCAs: certs}, - } -} - -func TestClientWithCorrectTLSServerName(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.TLS.ServerName != "127.0.0.1" { - t.Errorf("expected client to set ServerName 127.0.0.1, got: %q", r.TLS.ServerName) - } - })) - defer ts.Close() - - c := &Client{Transport: newTLSTransport(t, ts)} - if _, err := c.Get(ts.URL); err != nil { - t.Fatalf("expected successful TLS connection, got error: %v", err) - } -} - -func TestClientWithIncorrectTLSServerName(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) - defer ts.Close() - errc := make(chanWriter, 10) // but only expecting 1 - ts.Config.ErrorLog = log.New(errc, "", 0) - - trans := newTLSTransport(t, ts) - trans.TLSClientConfig.ServerName = "badserver" - c := &Client{Transport: trans} - _, err := c.Get(ts.URL) - if err == nil { - t.Fatalf("expected an error") - } - if !strings.Contains(err.Error(), "127.0.0.1") || !strings.Contains(err.Error(), "badserver") { - t.Errorf("wanted error mentioning 127.0.0.1 and badserver; got error: %v", err) - } - select { - case v := <-errc: - if !strings.Contains(v, "TLS handshake error") { - t.Errorf("expected an error log message containing 'TLS handshake error'; got %q", v) - } - case <-time.After(5 * time.Second): - t.Errorf("timeout waiting for logged error") - } -} - -// Test for golang.org/issue/5829; the Transport should respect TLSClientConfig.ServerName -// when not empty. -// -// tls.Config.ServerName (non-empty, set to "example.com") takes -// precedence over "some-other-host.tld" which previously incorrectly -// took precedence. We don't actually connect to (or even resolve) -// "some-other-host.tld", though, because of the Transport.Dial hook. -// -// The httptest.Server has a cert with "example.com" as its name. -func TestTransportUsesTLSConfigServerName(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Write([]byte("Hello")) - })) - defer ts.Close() - - tr := newTLSTransport(t, ts) - tr.TLSClientConfig.ServerName = "example.com" // one of httptest's Server cert names - tr.Dial = func(netw, addr string) (net.Conn, error) { - return net.Dial(netw, ts.Listener.Addr().String()) - } - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - res, err := c.Get("https://some-other-host.tld/") - if err != nil { - t.Fatal(err) - } - res.Body.Close() -} - -func TestResponseSetsTLSConnectionState(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Write([]byte("Hello")) - })) - defer ts.Close() - - tr := newTLSTransport(t, ts) - tr.TLSClientConfig.CipherSuites = []uint16{tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA} - tr.Dial = func(netw, addr string) (net.Conn, error) { - return net.Dial(netw, ts.Listener.Addr().String()) - } - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - res, err := c.Get("https://example.com/") - if err != nil { - t.Fatal(err) - } - defer res.Body.Close() - if res.TLS == nil { - t.Fatal("Response didn't set TLS Connection State.") - } - if got, want := res.TLS.CipherSuite, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA; got != want { - t.Errorf("TLS Cipher Suite = %d; want %d", got, want) - } -} - -// Verify Response.ContentLength is populated. http://golang.org/issue/4126 -func TestClientHeadContentLength(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if v := r.FormValue("cl"); v != "" { - w.Header().Set("Content-Length", v) - } - })) - defer ts.Close() - tests := []struct { - suffix string - want int64 - }{ - {"/?cl=1234", 1234}, - {"/?cl=0", 0}, - {"", -1}, - } - for _, tt := range tests { - req, _ := NewRequest("HEAD", ts.URL+tt.suffix, nil) - res, err := DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - if res.ContentLength != tt.want { - t.Errorf("Content-Length = %d; want %d", res.ContentLength, tt.want) - } - bs, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if len(bs) != 0 { - t.Errorf("Unexpected content: %q", bs) - } - } -} - -func TestEmptyPasswordAuth(t *testing.T) { - defer afterTest(t) - gopher := "gopher" - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - auth := r.Header.Get("Authorization") - if strings.HasPrefix(auth, "Basic ") { - encoded := auth[6:] - decoded, err := base64.StdEncoding.DecodeString(encoded) - if err != nil { - t.Fatal(err) - } - expected := gopher + ":" - s := string(decoded) - if expected != s { - t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected) - } - } else { - t.Errorf("Invalid auth %q", auth) - } - })) - defer ts.Close() - c := &Client{} - req, err := NewRequest("GET", ts.URL, nil) - if err != nil { - t.Fatal(err) - } - req.URL.User = url.User(gopher) - resp, err := c.Do(req) - if err != nil { - t.Fatal(err) - } - defer resp.Body.Close() -} - -func TestBasicAuth(t *testing.T) { - defer afterTest(t) - tr := &recordingTransport{} - client := &Client{Transport: tr} - - url := "http://My%20User:My%20Pass@dummy.faketld/" - expected := "My User:My Pass" - client.Get(url) - - if tr.req.Method != "GET" { - t.Errorf("got method %q, want %q", tr.req.Method, "GET") - } - if tr.req.URL.String() != url { - t.Errorf("got URL %q, want %q", tr.req.URL.String(), url) - } - if tr.req.Header == nil { - t.Fatalf("expected non-nil request Header") - } - auth := tr.req.Header.Get("Authorization") - if strings.HasPrefix(auth, "Basic ") { - encoded := auth[6:] - decoded, err := base64.StdEncoding.DecodeString(encoded) - if err != nil { - t.Fatal(err) - } - s := string(decoded) - if expected != s { - t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected) - } - } else { - t.Errorf("Invalid auth %q", auth) - } -} - -func TestClientTimeout(t *testing.T) { - if testing.Short() { - t.Skip("skipping in short mode") - } - defer afterTest(t) - sawRoot := make(chan bool, 1) - sawSlow := make(chan bool, 1) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.URL.Path == "/" { - sawRoot <- true - Redirect(w, r, "/slow", StatusFound) - return - } - if r.URL.Path == "/slow" { - w.Write([]byte("Hello")) - w.(Flusher).Flush() - sawSlow <- true - time.Sleep(2 * time.Second) - return - } - })) - defer ts.Close() - const timeout = 500 * time.Millisecond - c := &Client{ - Timeout: timeout, - } - - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - - select { - case <-sawRoot: - // good. - default: - t.Fatal("handler never got / request") - } - - select { - case <-sawSlow: - // good. - default: - t.Fatal("handler never got /slow request") - } - - errc := make(chan error, 1) - go func() { - _, err := ioutil.ReadAll(res.Body) - errc <- err - res.Body.Close() - }() - - const failTime = timeout * 2 - select { - case err := <-errc: - if err == nil { - t.Error("expected error from ReadAll") - } - // Expected error. - case <-time.After(failTime): - t.Errorf("timeout after %v waiting for timeout of %v", failTime, timeout) - } -} - -func TestClientRedirectEatsBody(t *testing.T) { - defer afterTest(t) - saw := make(chan string, 2) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - saw <- r.RemoteAddr - if r.URL.Path == "/" { - Redirect(w, r, "/foo", StatusFound) // which includes a body - } - })) - defer ts.Close() - - res, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - _, err = ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - res.Body.Close() - - var first string - select { - case first = <-saw: - default: - t.Fatal("server didn't see a request") - } - - var second string - select { - case second = <-saw: - default: - t.Fatal("server didn't see a second request") - } - - if first != second { - t.Fatal("server saw different client ports before & after the redirect") - } -} - -// eofReaderFunc is an io.Reader that runs itself, and then returns io.EOF. -type eofReaderFunc func() - -func (f eofReaderFunc) Read(p []byte) (n int, err error) { - f() - return 0, io.EOF -} - -func TestClientTrailers(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Connection", "close") - w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B") - w.Header().Add("Trailer", "Server-Trailer-C") - - var decl []string - for k := range r.Trailer { - decl = append(decl, k) - } - sort.Strings(decl) - - slurp, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Errorf("Server reading request body: %v", err) - } - if string(slurp) != "foo" { - t.Errorf("Server read request body %q; want foo", slurp) - } - if r.Trailer == nil { - io.WriteString(w, "nil Trailer") - } else { - fmt.Fprintf(w, "decl: %v, vals: %s, %s", - decl, - r.Trailer.Get("Client-Trailer-A"), - r.Trailer.Get("Client-Trailer-B")) - } - - // TODO: golang.org/issue/7759: there's no way yet for - // the server to set trailers without hijacking, so do - // that for now, just to test the client. Later, in - // Go 1.4, it should be implicit that any mutations - // to w.Header() after the initial write are the - // trailers to be sent, if and only if they were - // previously declared with w.Header().Set("Trailer", - // ..keys..) - w.(Flusher).Flush() - conn, buf, _ := w.(Hijacker).Hijack() - t := Header{} - t.Set("Server-Trailer-A", "valuea") - t.Set("Server-Trailer-C", "valuec") // skipping B - buf.WriteString("0\r\n") // eof - t.Write(buf) - buf.WriteString("\r\n") // end of trailers - buf.Flush() - conn.Close() - })) - defer ts.Close() - - var req *Request - req, _ = NewRequest("POST", ts.URL, io.MultiReader( - eofReaderFunc(func() { - req.Trailer["Client-Trailer-A"] = []string{"valuea"} - }), - strings.NewReader("foo"), - eofReaderFunc(func() { - req.Trailer["Client-Trailer-B"] = []string{"valueb"} - }), - )) - req.Trailer = Header{ - "Client-Trailer-A": nil, // to be set later - "Client-Trailer-B": nil, // to be set later - } - req.ContentLength = -1 - res, err := DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - if err := wantBody(res, err, "decl: [Client-Trailer-A Client-Trailer-B], vals: valuea, valueb"); err != nil { - t.Error(err) - } - want := Header{ - "Server-Trailer-A": []string{"valuea"}, - "Server-Trailer-B": nil, - "Server-Trailer-C": []string{"valuec"}, - } - if !reflect.DeepEqual(res.Trailer, want) { - t.Errorf("Response trailers = %#v; want %#v", res.Trailer, want) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookie.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookie.go deleted file mode 100644 index dc60ba87f5..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookie.go +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bytes" - "fmt" - "log" - "net" - "strconv" - "strings" - "time" -) - -// This implementation is done according to RFC 6265: -// -// http://tools.ietf.org/html/rfc6265 - -// A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an -// HTTP response or the Cookie header of an HTTP request. -type Cookie struct { - Name string - Value string - Path string - Domain string - Expires time.Time - RawExpires string - - // MaxAge=0 means no 'Max-Age' attribute specified. - // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0' - // MaxAge>0 means Max-Age attribute present and given in seconds - MaxAge int - Secure bool - HttpOnly bool - Raw string - Unparsed []string // Raw text of unparsed attribute-value pairs -} - -// readSetCookies parses all "Set-Cookie" values from -// the header h and returns the successfully parsed Cookies. -func readSetCookies(h Header) []*Cookie { - cookies := []*Cookie{} - for _, line := range h["Set-Cookie"] { - parts := strings.Split(strings.TrimSpace(line), ";") - if len(parts) == 1 && parts[0] == "" { - continue - } - parts[0] = strings.TrimSpace(parts[0]) - j := strings.Index(parts[0], "=") - if j < 0 { - continue - } - name, value := parts[0][:j], parts[0][j+1:] - if !isCookieNameValid(name) { - continue - } - value, success := parseCookieValue(value) - if !success { - continue - } - c := &Cookie{ - Name: name, - Value: value, - Raw: line, - } - for i := 1; i < len(parts); i++ { - parts[i] = strings.TrimSpace(parts[i]) - if len(parts[i]) == 0 { - continue - } - - attr, val := parts[i], "" - if j := strings.Index(attr, "="); j >= 0 { - attr, val = attr[:j], attr[j+1:] - } - lowerAttr := strings.ToLower(attr) - val, success = parseCookieValue(val) - if !success { - c.Unparsed = append(c.Unparsed, parts[i]) - continue - } - switch lowerAttr { - case "secure": - c.Secure = true - continue - case "httponly": - c.HttpOnly = true - continue - case "domain": - c.Domain = val - continue - case "max-age": - secs, err := strconv.Atoi(val) - if err != nil || secs != 0 && val[0] == '0' { - break - } - if secs <= 0 { - c.MaxAge = -1 - } else { - c.MaxAge = secs - } - continue - case "expires": - c.RawExpires = val - exptime, err := time.Parse(time.RFC1123, val) - if err != nil { - exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val) - if err != nil { - c.Expires = time.Time{} - break - } - } - c.Expires = exptime.UTC() - continue - case "path": - c.Path = val - continue - } - c.Unparsed = append(c.Unparsed, parts[i]) - } - cookies = append(cookies, c) - } - return cookies -} - -// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers. -func SetCookie(w ResponseWriter, cookie *Cookie) { - w.Header().Add("Set-Cookie", cookie.String()) -} - -// String returns the serialization of the cookie for use in a Cookie -// header (if only Name and Value are set) or a Set-Cookie response -// header (if other fields are set). -func (c *Cookie) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value)) - if len(c.Path) > 0 { - fmt.Fprintf(&b, "; Path=%s", sanitizeCookiePath(c.Path)) - } - if len(c.Domain) > 0 { - if validCookieDomain(c.Domain) { - // A c.Domain containing illegal characters is not - // sanitized but simply dropped which turns the cookie - // into a host-only cookie. A leading dot is okay - // but won't be sent. - d := c.Domain - if d[0] == '.' { - d = d[1:] - } - fmt.Fprintf(&b, "; Domain=%s", d) - } else { - log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute", - c.Domain) - } - } - if c.Expires.Unix() > 0 { - fmt.Fprintf(&b, "; Expires=%s", c.Expires.UTC().Format(time.RFC1123)) - } - if c.MaxAge > 0 { - fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge) - } else if c.MaxAge < 0 { - fmt.Fprintf(&b, "; Max-Age=0") - } - if c.HttpOnly { - fmt.Fprintf(&b, "; HttpOnly") - } - if c.Secure { - fmt.Fprintf(&b, "; Secure") - } - return b.String() -} - -// readCookies parses all "Cookie" values from the header h and -// returns the successfully parsed Cookies. -// -// if filter isn't empty, only cookies of that name are returned -func readCookies(h Header, filter string) []*Cookie { - cookies := []*Cookie{} - lines, ok := h["Cookie"] - if !ok { - return cookies - } - - for _, line := range lines { - parts := strings.Split(strings.TrimSpace(line), ";") - if len(parts) == 1 && parts[0] == "" { - continue - } - // Per-line attributes - parsedPairs := 0 - for i := 0; i < len(parts); i++ { - parts[i] = strings.TrimSpace(parts[i]) - if len(parts[i]) == 0 { - continue - } - name, val := parts[i], "" - if j := strings.Index(name, "="); j >= 0 { - name, val = name[:j], name[j+1:] - } - if !isCookieNameValid(name) { - continue - } - if filter != "" && filter != name { - continue - } - val, success := parseCookieValue(val) - if !success { - continue - } - cookies = append(cookies, &Cookie{Name: name, Value: val}) - parsedPairs++ - } - } - return cookies -} - -// validCookieDomain returns wheter v is a valid cookie domain-value. -func validCookieDomain(v string) bool { - if isCookieDomainName(v) { - return true - } - if net.ParseIP(v) != nil && !strings.Contains(v, ":") { - return true - } - return false -} - -// isCookieDomainName returns whether s is a valid domain name or a valid -// domain name with a leading dot '.'. It is almost a direct copy of -// package net's isDomainName. -func isCookieDomainName(s string) bool { - if len(s) == 0 { - return false - } - if len(s) > 255 { - return false - } - - if s[0] == '.' { - // A cookie a domain attribute may start with a leading dot. - s = s[1:] - } - last := byte('.') - ok := false // Ok once we've seen a letter. - partlen := 0 - for i := 0; i < len(s); i++ { - c := s[i] - switch { - default: - return false - case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z': - // No '_' allowed here (in contrast to package net). - ok = true - partlen++ - case '0' <= c && c <= '9': - // fine - partlen++ - case c == '-': - // Byte before dash cannot be dot. - if last == '.' { - return false - } - partlen++ - case c == '.': - // Byte before dot cannot be dot, dash. - if last == '.' || last == '-' { - return false - } - if partlen > 63 || partlen == 0 { - return false - } - partlen = 0 - } - last = c - } - if last == '-' || partlen > 63 { - return false - } - - return ok -} - -var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-") - -func sanitizeCookieName(n string) string { - return cookieNameSanitizer.Replace(n) -} - -// http://tools.ietf.org/html/rfc6265#section-4.1.1 -// cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) -// cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E -// ; US-ASCII characters excluding CTLs, -// ; whitespace DQUOTE, comma, semicolon, -// ; and backslash -// We loosen this as spaces and commas are common in cookie values -// but we produce a quoted cookie-value in when value starts or ends -// with a comma or space. -// See http://golang.org/issue/7243 for the discussion. -func sanitizeCookieValue(v string) string { - v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v) - if len(v) == 0 { - return v - } - if v[0] == ' ' || v[0] == ',' || v[len(v)-1] == ' ' || v[len(v)-1] == ',' { - return `"` + v + `"` - } - return v -} - -func validCookieValueByte(b byte) bool { - return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\' -} - -// path-av = "Path=" path-value -// path-value = -func sanitizeCookiePath(v string) string { - return sanitizeOrWarn("Cookie.Path", validCookiePathByte, v) -} - -func validCookiePathByte(b byte) bool { - return 0x20 <= b && b < 0x7f && b != ';' -} - -func sanitizeOrWarn(fieldName string, valid func(byte) bool, v string) string { - ok := true - for i := 0; i < len(v); i++ { - if valid(v[i]) { - continue - } - log.Printf("net/http: invalid byte %q in %s; dropping invalid bytes", v[i], fieldName) - ok = false - break - } - if ok { - return v - } - buf := make([]byte, 0, len(v)) - for i := 0; i < len(v); i++ { - if b := v[i]; valid(b) { - buf = append(buf, b) - } - } - return string(buf) -} - -func parseCookieValue(raw string) (string, bool) { - // Strip the quotes, if present. - if len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' { - raw = raw[1 : len(raw)-1] - } - for i := 0; i < len(raw); i++ { - if !validCookieValueByte(raw[i]) { - return "", false - } - } - return raw, true -} - -func isCookieNameValid(raw string) bool { - return strings.IndexFunc(raw, isNotToken) < 0 -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookie_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookie_test.go deleted file mode 100644 index f78f37299f..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookie_test.go +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bytes" - "encoding/json" - "fmt" - "log" - "os" - "reflect" - "strings" - "testing" - "time" -) - -var writeSetCookiesTests = []struct { - Cookie *Cookie - Raw string -}{ - { - &Cookie{Name: "cookie-1", Value: "v$1"}, - "cookie-1=v$1", - }, - { - &Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600}, - "cookie-2=two; Max-Age=3600", - }, - { - &Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"}, - "cookie-3=three; Domain=example.com", - }, - { - &Cookie{Name: "cookie-4", Value: "four", Path: "/restricted/"}, - "cookie-4=four; Path=/restricted/", - }, - { - &Cookie{Name: "cookie-5", Value: "five", Domain: "wrong;bad.abc"}, - "cookie-5=five", - }, - { - &Cookie{Name: "cookie-6", Value: "six", Domain: "bad-.abc"}, - "cookie-6=six", - }, - { - &Cookie{Name: "cookie-7", Value: "seven", Domain: "127.0.0.1"}, - "cookie-7=seven; Domain=127.0.0.1", - }, - { - &Cookie{Name: "cookie-8", Value: "eight", Domain: "::1"}, - "cookie-8=eight", - }, - // The "special" cookies have values containing commas or spaces which - // are disallowed by RFC 6265 but are common in the wild. - { - &Cookie{Name: "special-1", Value: "a z"}, - `special-1=a z`, - }, - { - &Cookie{Name: "special-2", Value: " z"}, - `special-2=" z"`, - }, - { - &Cookie{Name: "special-3", Value: "a "}, - `special-3="a "`, - }, - { - &Cookie{Name: "special-4", Value: " "}, - `special-4=" "`, - }, - { - &Cookie{Name: "special-5", Value: "a,z"}, - `special-5=a,z`, - }, - { - &Cookie{Name: "special-6", Value: ",z"}, - `special-6=",z"`, - }, - { - &Cookie{Name: "special-7", Value: "a,"}, - `special-7="a,"`, - }, - { - &Cookie{Name: "special-8", Value: ","}, - `special-8=","`, - }, - { - &Cookie{Name: "empty-value", Value: ""}, - `empty-value=`, - }, -} - -func TestWriteSetCookies(t *testing.T) { - defer log.SetOutput(os.Stderr) - var logbuf bytes.Buffer - log.SetOutput(&logbuf) - - for i, tt := range writeSetCookiesTests { - if g, e := tt.Cookie.String(), tt.Raw; g != e { - t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, e, g) - continue - } - } - - if got, sub := logbuf.String(), "dropping domain attribute"; !strings.Contains(got, sub) { - t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got) - } -} - -type headerOnlyResponseWriter Header - -func (ho headerOnlyResponseWriter) Header() Header { - return Header(ho) -} - -func (ho headerOnlyResponseWriter) Write([]byte) (int, error) { - panic("NOIMPL") -} - -func (ho headerOnlyResponseWriter) WriteHeader(int) { - panic("NOIMPL") -} - -func TestSetCookie(t *testing.T) { - m := make(Header) - SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-1", Value: "one", Path: "/restricted/"}) - SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600}) - if l := len(m["Set-Cookie"]); l != 2 { - t.Fatalf("expected %d cookies, got %d", 2, l) - } - if g, e := m["Set-Cookie"][0], "cookie-1=one; Path=/restricted/"; g != e { - t.Errorf("cookie #1: want %q, got %q", e, g) - } - if g, e := m["Set-Cookie"][1], "cookie-2=two; Max-Age=3600"; g != e { - t.Errorf("cookie #2: want %q, got %q", e, g) - } -} - -var addCookieTests = []struct { - Cookies []*Cookie - Raw string -}{ - { - []*Cookie{}, - "", - }, - { - []*Cookie{{Name: "cookie-1", Value: "v$1"}}, - "cookie-1=v$1", - }, - { - []*Cookie{ - {Name: "cookie-1", Value: "v$1"}, - {Name: "cookie-2", Value: "v$2"}, - {Name: "cookie-3", Value: "v$3"}, - }, - "cookie-1=v$1; cookie-2=v$2; cookie-3=v$3", - }, -} - -func TestAddCookie(t *testing.T) { - for i, tt := range addCookieTests { - req, _ := NewRequest("GET", "http://example.com/", nil) - for _, c := range tt.Cookies { - req.AddCookie(c) - } - if g := req.Header.Get("Cookie"); g != tt.Raw { - t.Errorf("Test %d:\nwant: %s\n got: %s\n", i, tt.Raw, g) - continue - } - } -} - -var readSetCookiesTests = []struct { - Header Header - Cookies []*Cookie -}{ - { - Header{"Set-Cookie": {"Cookie-1=v$1"}}, - []*Cookie{{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}}, - }, - { - Header{"Set-Cookie": {"NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"}}, - []*Cookie{{ - Name: "NID", - Value: "99=YsDT5i3E-CXax-", - Path: "/", - Domain: ".google.ch", - HttpOnly: true, - Expires: time.Date(2011, 11, 23, 1, 5, 3, 0, time.UTC), - RawExpires: "Wed, 23-Nov-2011 01:05:03 GMT", - Raw: "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly", - }}, - }, - { - Header{"Set-Cookie": {".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}}, - []*Cookie{{ - Name: ".ASPXAUTH", - Value: "7E3AA", - Path: "/", - Expires: time.Date(2012, 3, 7, 14, 25, 6, 0, time.UTC), - RawExpires: "Wed, 07-Mar-2012 14:25:06 GMT", - HttpOnly: true, - Raw: ".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly", - }}, - }, - { - Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly"}}, - []*Cookie{{ - Name: "ASP.NET_SessionId", - Value: "foo", - Path: "/", - HttpOnly: true, - Raw: "ASP.NET_SessionId=foo; path=/; HttpOnly", - }}, - }, - // Make sure we can properly read back the Set-Cookie headers we create - // for values containing spaces or commas: - { - Header{"Set-Cookie": {`special-1=a z`}}, - []*Cookie{{Name: "special-1", Value: "a z", Raw: `special-1=a z`}}, - }, - { - Header{"Set-Cookie": {`special-2=" z"`}}, - []*Cookie{{Name: "special-2", Value: " z", Raw: `special-2=" z"`}}, - }, - { - Header{"Set-Cookie": {`special-3="a "`}}, - []*Cookie{{Name: "special-3", Value: "a ", Raw: `special-3="a "`}}, - }, - { - Header{"Set-Cookie": {`special-4=" "`}}, - []*Cookie{{Name: "special-4", Value: " ", Raw: `special-4=" "`}}, - }, - { - Header{"Set-Cookie": {`special-5=a,z`}}, - []*Cookie{{Name: "special-5", Value: "a,z", Raw: `special-5=a,z`}}, - }, - { - Header{"Set-Cookie": {`special-6=",z"`}}, - []*Cookie{{Name: "special-6", Value: ",z", Raw: `special-6=",z"`}}, - }, - { - Header{"Set-Cookie": {`special-7=a,`}}, - []*Cookie{{Name: "special-7", Value: "a,", Raw: `special-7=a,`}}, - }, - { - Header{"Set-Cookie": {`special-8=","`}}, - []*Cookie{{Name: "special-8", Value: ",", Raw: `special-8=","`}}, - }, - - // TODO(bradfitz): users have reported seeing this in the - // wild, but do browsers handle it? RFC 6265 just says "don't - // do that" (section 3) and then never mentions header folding - // again. - // Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}}, -} - -func toJSON(v interface{}) string { - b, err := json.Marshal(v) - if err != nil { - return fmt.Sprintf("%#v", v) - } - return string(b) -} - -func TestReadSetCookies(t *testing.T) { - for i, tt := range readSetCookiesTests { - for n := 0; n < 2; n++ { // to verify readSetCookies doesn't mutate its input - c := readSetCookies(tt.Header) - if !reflect.DeepEqual(c, tt.Cookies) { - t.Errorf("#%d readSetCookies: have\n%s\nwant\n%s\n", i, toJSON(c), toJSON(tt.Cookies)) - continue - } - } - } -} - -var readCookiesTests = []struct { - Header Header - Filter string - Cookies []*Cookie -}{ - { - Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}}, - "", - []*Cookie{ - {Name: "Cookie-1", Value: "v$1"}, - {Name: "c2", Value: "v2"}, - }, - }, - { - Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}}, - "c2", - []*Cookie{ - {Name: "c2", Value: "v2"}, - }, - }, - { - Header{"Cookie": {"Cookie-1=v$1; c2=v2"}}, - "", - []*Cookie{ - {Name: "Cookie-1", Value: "v$1"}, - {Name: "c2", Value: "v2"}, - }, - }, - { - Header{"Cookie": {"Cookie-1=v$1; c2=v2"}}, - "c2", - []*Cookie{ - {Name: "c2", Value: "v2"}, - }, - }, -} - -func TestReadCookies(t *testing.T) { - for i, tt := range readCookiesTests { - for n := 0; n < 2; n++ { // to verify readCookies doesn't mutate its input - c := readCookies(tt.Header, tt.Filter) - if !reflect.DeepEqual(c, tt.Cookies) { - t.Errorf("#%d readCookies:\nhave: %s\nwant: %s\n", i, toJSON(c), toJSON(tt.Cookies)) - continue - } - } - } -} - -func TestCookieSanitizeValue(t *testing.T) { - defer log.SetOutput(os.Stderr) - var logbuf bytes.Buffer - log.SetOutput(&logbuf) - - tests := []struct { - in, want string - }{ - {"foo", "foo"}, - {"foo;bar", "foobar"}, - {"foo\\bar", "foobar"}, - {"foo\"bar", "foobar"}, - {"\x00\x7e\x7f\x80", "\x7e"}, - {`"withquotes"`, "withquotes"}, - {"a z", "a z"}, - {" z", `" z"`}, - {"a ", `"a "`}, - } - for _, tt := range tests { - if got := sanitizeCookieValue(tt.in); got != tt.want { - t.Errorf("sanitizeCookieValue(%q) = %q; want %q", tt.in, got, tt.want) - } - } - - if got, sub := logbuf.String(), "dropping invalid bytes"; !strings.Contains(got, sub) { - t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got) - } -} - -func TestCookieSanitizePath(t *testing.T) { - defer log.SetOutput(os.Stderr) - var logbuf bytes.Buffer - log.SetOutput(&logbuf) - - tests := []struct { - in, want string - }{ - {"/path", "/path"}, - {"/path with space/", "/path with space/"}, - {"/just;no;semicolon\x00orstuff/", "/justnosemicolonorstuff/"}, - } - for _, tt := range tests { - if got := sanitizeCookiePath(tt.in); got != tt.want { - t.Errorf("sanitizeCookiePath(%q) = %q; want %q", tt.in, got, tt.want) - } - } - - if got, sub := logbuf.String(), "dropping invalid bytes"; !strings.Contains(got, sub) { - t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/jar.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/jar.go deleted file mode 100644 index 389ab58e41..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/jar.go +++ /dev/null @@ -1,497 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cookiejar implements an in-memory RFC 6265-compliant http.CookieJar. -package cookiejar - -import ( - "errors" - "fmt" - "net" - "net/http" - "net/url" - "sort" - "strings" - "sync" - "time" -) - -// PublicSuffixList provides the public suffix of a domain. For example: -// - the public suffix of "example.com" is "com", -// - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and -// - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us". -// -// Implementations of PublicSuffixList must be safe for concurrent use by -// multiple goroutines. -// -// An implementation that always returns "" is valid and may be useful for -// testing but it is not secure: it means that the HTTP server for foo.com can -// set a cookie for bar.com. -// -// A public suffix list implementation is in the package -// code.google.com/p/go.net/publicsuffix. -type PublicSuffixList interface { - // PublicSuffix returns the public suffix of domain. - // - // TODO: specify which of the caller and callee is responsible for IP - // addresses, for leading and trailing dots, for case sensitivity, and - // for IDN/Punycode. - PublicSuffix(domain string) string - - // String returns a description of the source of this public suffix - // list. The description will typically contain something like a time - // stamp or version number. - String() string -} - -// Options are the options for creating a new Jar. -type Options struct { - // PublicSuffixList is the public suffix list that determines whether - // an HTTP server can set a cookie for a domain. - // - // A nil value is valid and may be useful for testing but it is not - // secure: it means that the HTTP server for foo.co.uk can set a cookie - // for bar.co.uk. - PublicSuffixList PublicSuffixList -} - -// Jar implements the http.CookieJar interface from the net/http package. -type Jar struct { - psList PublicSuffixList - - // mu locks the remaining fields. - mu sync.Mutex - - // entries is a set of entries, keyed by their eTLD+1 and subkeyed by - // their name/domain/path. - entries map[string]map[string]entry - - // nextSeqNum is the next sequence number assigned to a new cookie - // created SetCookies. - nextSeqNum uint64 -} - -// New returns a new cookie jar. A nil *Options is equivalent to a zero -// Options. -func New(o *Options) (*Jar, error) { - jar := &Jar{ - entries: make(map[string]map[string]entry), - } - if o != nil { - jar.psList = o.PublicSuffixList - } - return jar, nil -} - -// entry is the internal representation of a cookie. -// -// This struct type is not used outside of this package per se, but the exported -// fields are those of RFC 6265. -type entry struct { - Name string - Value string - Domain string - Path string - Secure bool - HttpOnly bool - Persistent bool - HostOnly bool - Expires time.Time - Creation time.Time - LastAccess time.Time - - // seqNum is a sequence number so that Cookies returns cookies in a - // deterministic order, even for cookies that have equal Path length and - // equal Creation time. This simplifies testing. - seqNum uint64 -} - -// Id returns the domain;path;name triple of e as an id. -func (e *entry) id() string { - return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name) -} - -// shouldSend determines whether e's cookie qualifies to be included in a -// request to host/path. It is the caller's responsibility to check if the -// cookie is expired. -func (e *entry) shouldSend(https bool, host, path string) bool { - return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure) -} - -// domainMatch implements "domain-match" of RFC 6265 section 5.1.3. -func (e *entry) domainMatch(host string) bool { - if e.Domain == host { - return true - } - return !e.HostOnly && hasDotSuffix(host, e.Domain) -} - -// pathMatch implements "path-match" according to RFC 6265 section 5.1.4. -func (e *entry) pathMatch(requestPath string) bool { - if requestPath == e.Path { - return true - } - if strings.HasPrefix(requestPath, e.Path) { - if e.Path[len(e.Path)-1] == '/' { - return true // The "/any/" matches "/any/path" case. - } else if requestPath[len(e.Path)] == '/' { - return true // The "/any" matches "/any/path" case. - } - } - return false -} - -// hasDotSuffix reports whether s ends in "."+suffix. -func hasDotSuffix(s, suffix string) bool { - return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix -} - -// byPathLength is a []entry sort.Interface that sorts according to RFC 6265 -// section 5.4 point 2: by longest path and then by earliest creation time. -type byPathLength []entry - -func (s byPathLength) Len() int { return len(s) } - -func (s byPathLength) Less(i, j int) bool { - if len(s[i].Path) != len(s[j].Path) { - return len(s[i].Path) > len(s[j].Path) - } - if !s[i].Creation.Equal(s[j].Creation) { - return s[i].Creation.Before(s[j].Creation) - } - return s[i].seqNum < s[j].seqNum -} - -func (s byPathLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// Cookies implements the Cookies method of the http.CookieJar interface. -// -// It returns an empty slice if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) { - return j.cookies(u, time.Now()) -} - -// cookies is like Cookies but takes the current time as a parameter. -func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) { - if u.Scheme != "http" && u.Scheme != "https" { - return cookies - } - host, err := canonicalHost(u.Host) - if err != nil { - return cookies - } - key := jarKey(host, j.psList) - - j.mu.Lock() - defer j.mu.Unlock() - - submap := j.entries[key] - if submap == nil { - return cookies - } - - https := u.Scheme == "https" - path := u.Path - if path == "" { - path = "/" - } - - modified := false - var selected []entry - for id, e := range submap { - if e.Persistent && !e.Expires.After(now) { - delete(submap, id) - modified = true - continue - } - if !e.shouldSend(https, host, path) { - continue - } - e.LastAccess = now - submap[id] = e - selected = append(selected, e) - modified = true - } - if modified { - if len(submap) == 0 { - delete(j.entries, key) - } else { - j.entries[key] = submap - } - } - - sort.Sort(byPathLength(selected)) - for _, e := range selected { - cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value}) - } - - return cookies -} - -// SetCookies implements the SetCookies method of the http.CookieJar interface. -// -// It does nothing if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) { - j.setCookies(u, cookies, time.Now()) -} - -// setCookies is like SetCookies but takes the current time as parameter. -func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) { - if len(cookies) == 0 { - return - } - if u.Scheme != "http" && u.Scheme != "https" { - return - } - host, err := canonicalHost(u.Host) - if err != nil { - return - } - key := jarKey(host, j.psList) - defPath := defaultPath(u.Path) - - j.mu.Lock() - defer j.mu.Unlock() - - submap := j.entries[key] - - modified := false - for _, cookie := range cookies { - e, remove, err := j.newEntry(cookie, now, defPath, host) - if err != nil { - continue - } - id := e.id() - if remove { - if submap != nil { - if _, ok := submap[id]; ok { - delete(submap, id) - modified = true - } - } - continue - } - if submap == nil { - submap = make(map[string]entry) - } - - if old, ok := submap[id]; ok { - e.Creation = old.Creation - e.seqNum = old.seqNum - } else { - e.Creation = now - e.seqNum = j.nextSeqNum - j.nextSeqNum++ - } - e.LastAccess = now - submap[id] = e - modified = true - } - - if modified { - if len(submap) == 0 { - delete(j.entries, key) - } else { - j.entries[key] = submap - } - } -} - -// canonicalHost strips port from host if present and returns the canonicalized -// host name. -func canonicalHost(host string) (string, error) { - var err error - host = strings.ToLower(host) - if hasPort(host) { - host, _, err = net.SplitHostPort(host) - if err != nil { - return "", err - } - } - if strings.HasSuffix(host, ".") { - // Strip trailing dot from fully qualified domain names. - host = host[:len(host)-1] - } - return toASCII(host) -} - -// hasPort reports whether host contains a port number. host may be a host -// name, an IPv4 or an IPv6 address. -func hasPort(host string) bool { - colons := strings.Count(host, ":") - if colons == 0 { - return false - } - if colons == 1 { - return true - } - return host[0] == '[' && strings.Contains(host, "]:") -} - -// jarKey returns the key to use for a jar. -func jarKey(host string, psl PublicSuffixList) string { - if isIP(host) { - return host - } - - var i int - if psl == nil { - i = strings.LastIndex(host, ".") - if i == -1 { - return host - } - } else { - suffix := psl.PublicSuffix(host) - if suffix == host { - return host - } - i = len(host) - len(suffix) - if i <= 0 || host[i-1] != '.' { - // The provided public suffix list psl is broken. - // Storing cookies under host is a safe stopgap. - return host - } - } - prevDot := strings.LastIndex(host[:i-1], ".") - return host[prevDot+1:] -} - -// isIP reports whether host is an IP address. -func isIP(host string) bool { - return net.ParseIP(host) != nil -} - -// defaultPath returns the directory part of an URL's path according to -// RFC 6265 section 5.1.4. -func defaultPath(path string) string { - if len(path) == 0 || path[0] != '/' { - return "/" // Path is empty or malformed. - } - - i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1. - if i == 0 { - return "/" // Path has the form "/abc". - } - return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/". -} - -// newEntry creates an entry from a http.Cookie c. now is the current time and -// is compared to c.Expires to determine deletion of c. defPath and host are the -// default-path and the canonical host name of the URL c was received from. -// -// remove records whether the jar should delete this cookie, as it has already -// expired with respect to now. In this case, e may be incomplete, but it will -// be valid to call e.id (which depends on e's Name, Domain and Path). -// -// A malformed c.Domain will result in an error. -func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) { - e.Name = c.Name - - if c.Path == "" || c.Path[0] != '/' { - e.Path = defPath - } else { - e.Path = c.Path - } - - e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain) - if err != nil { - return e, false, err - } - - // MaxAge takes precedence over Expires. - if c.MaxAge < 0 { - return e, true, nil - } else if c.MaxAge > 0 { - e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second) - e.Persistent = true - } else { - if c.Expires.IsZero() { - e.Expires = endOfTime - e.Persistent = false - } else { - if !c.Expires.After(now) { - return e, true, nil - } - e.Expires = c.Expires - e.Persistent = true - } - } - - e.Value = c.Value - e.Secure = c.Secure - e.HttpOnly = c.HttpOnly - - return e, false, nil -} - -var ( - errIllegalDomain = errors.New("cookiejar: illegal cookie domain attribute") - errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute") - errNoHostname = errors.New("cookiejar: no host name available (IP only)") -) - -// endOfTime is the time when session (non-persistent) cookies expire. -// This instant is representable in most date/time formats (not just -// Go's time.Time) and should be far enough in the future. -var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC) - -// domainAndType determines the cookie's domain and hostOnly attribute. -func (j *Jar) domainAndType(host, domain string) (string, bool, error) { - if domain == "" { - // No domain attribute in the SetCookie header indicates a - // host cookie. - return host, true, nil - } - - if isIP(host) { - // According to RFC 6265 domain-matching includes not being - // an IP address. - // TODO: This might be relaxed as in common browsers. - return "", false, errNoHostname - } - - // From here on: If the cookie is valid, it is a domain cookie (with - // the one exception of a public suffix below). - // See RFC 6265 section 5.2.3. - if domain[0] == '.' { - domain = domain[1:] - } - - if len(domain) == 0 || domain[0] == '.' { - // Received either "Domain=." or "Domain=..some.thing", - // both are illegal. - return "", false, errMalformedDomain - } - domain = strings.ToLower(domain) - - if domain[len(domain)-1] == '.' { - // We received stuff like "Domain=www.example.com.". - // Browsers do handle such stuff (actually differently) but - // RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in - // requiring a reject. 4.1.2.3 is not normative, but - // "Domain Matching" (5.1.3) and "Canonicalized Host Names" - // (5.1.2) are. - return "", false, errMalformedDomain - } - - // See RFC 6265 section 5.3 #5. - if j.psList != nil { - if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) { - if host == domain { - // This is the one exception in which a cookie - // with a domain attribute is a host cookie. - return host, true, nil - } - return "", false, errIllegalDomain - } - } - - // The domain must domain-match host: www.mycompany.com cannot - // set cookies for .ourcompetitors.com. - if host != domain && !hasDotSuffix(host, domain) { - return "", false, errIllegalDomain - } - - return domain, false, nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/jar_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/jar_test.go deleted file mode 100644 index 3aa601586e..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/jar_test.go +++ /dev/null @@ -1,1267 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cookiejar - -import ( - "fmt" - "net/http" - "net/url" - "sort" - "strings" - "testing" - "time" -) - -// tNow is the synthetic current time used as now during testing. -var tNow = time.Date(2013, 1, 1, 12, 0, 0, 0, time.UTC) - -// testPSL implements PublicSuffixList with just two rules: "co.uk" -// and the default rule "*". -type testPSL struct{} - -func (testPSL) String() string { - return "testPSL" -} -func (testPSL) PublicSuffix(d string) string { - if d == "co.uk" || strings.HasSuffix(d, ".co.uk") { - return "co.uk" - } - return d[strings.LastIndex(d, ".")+1:] -} - -// newTestJar creates an empty Jar with testPSL as the public suffix list. -func newTestJar() *Jar { - jar, err := New(&Options{PublicSuffixList: testPSL{}}) - if err != nil { - panic(err) - } - return jar -} - -var hasDotSuffixTests = [...]struct { - s, suffix string -}{ - {"", ""}, - {"", "."}, - {"", "x"}, - {".", ""}, - {".", "."}, - {".", ".."}, - {".", "x"}, - {".", "x."}, - {".", ".x"}, - {".", ".x."}, - {"x", ""}, - {"x", "."}, - {"x", ".."}, - {"x", "x"}, - {"x", "x."}, - {"x", ".x"}, - {"x", ".x."}, - {".x", ""}, - {".x", "."}, - {".x", ".."}, - {".x", "x"}, - {".x", "x."}, - {".x", ".x"}, - {".x", ".x."}, - {"x.", ""}, - {"x.", "."}, - {"x.", ".."}, - {"x.", "x"}, - {"x.", "x."}, - {"x.", ".x"}, - {"x.", ".x."}, - {"com", ""}, - {"com", "m"}, - {"com", "om"}, - {"com", "com"}, - {"com", ".com"}, - {"com", "x.com"}, - {"com", "xcom"}, - {"com", "xorg"}, - {"com", "org"}, - {"com", "rg"}, - {"foo.com", ""}, - {"foo.com", "m"}, - {"foo.com", "om"}, - {"foo.com", "com"}, - {"foo.com", ".com"}, - {"foo.com", "o.com"}, - {"foo.com", "oo.com"}, - {"foo.com", "foo.com"}, - {"foo.com", ".foo.com"}, - {"foo.com", "x.foo.com"}, - {"foo.com", "xfoo.com"}, - {"foo.com", "xfoo.org"}, - {"foo.com", "foo.org"}, - {"foo.com", "oo.org"}, - {"foo.com", "o.org"}, - {"foo.com", ".org"}, - {"foo.com", "org"}, - {"foo.com", "rg"}, -} - -func TestHasDotSuffix(t *testing.T) { - for _, tc := range hasDotSuffixTests { - got := hasDotSuffix(tc.s, tc.suffix) - want := strings.HasSuffix(tc.s, "."+tc.suffix) - if got != want { - t.Errorf("s=%q, suffix=%q: got %v, want %v", tc.s, tc.suffix, got, want) - } - } -} - -var canonicalHostTests = map[string]string{ - "www.example.com": "www.example.com", - "WWW.EXAMPLE.COM": "www.example.com", - "wWw.eXAmple.CoM": "www.example.com", - "www.example.com:80": "www.example.com", - "192.168.0.10": "192.168.0.10", - "192.168.0.5:8080": "192.168.0.5", - "2001:4860:0:2001::68": "2001:4860:0:2001::68", - "[2001:4860:0:::68]:8080": "2001:4860:0:::68", - "www.bücher.de": "www.xn--bcher-kva.de", - "www.example.com.": "www.example.com", - "[bad.unmatched.bracket:": "error", -} - -func TestCanonicalHost(t *testing.T) { - for h, want := range canonicalHostTests { - got, err := canonicalHost(h) - if want == "error" { - if err == nil { - t.Errorf("%q: got nil error, want non-nil", h) - } - continue - } - if err != nil { - t.Errorf("%q: %v", h, err) - continue - } - if got != want { - t.Errorf("%q: got %q, want %q", h, got, want) - continue - } - } -} - -var hasPortTests = map[string]bool{ - "www.example.com": false, - "www.example.com:80": true, - "127.0.0.1": false, - "127.0.0.1:8080": true, - "2001:4860:0:2001::68": false, - "[2001::0:::68]:80": true, -} - -func TestHasPort(t *testing.T) { - for host, want := range hasPortTests { - if got := hasPort(host); got != want { - t.Errorf("%q: got %t, want %t", host, got, want) - } - } -} - -var jarKeyTests = map[string]string{ - "foo.www.example.com": "example.com", - "www.example.com": "example.com", - "example.com": "example.com", - "com": "com", - "foo.www.bbc.co.uk": "bbc.co.uk", - "www.bbc.co.uk": "bbc.co.uk", - "bbc.co.uk": "bbc.co.uk", - "co.uk": "co.uk", - "uk": "uk", - "192.168.0.5": "192.168.0.5", -} - -func TestJarKey(t *testing.T) { - for host, want := range jarKeyTests { - if got := jarKey(host, testPSL{}); got != want { - t.Errorf("%q: got %q, want %q", host, got, want) - } - } -} - -var jarKeyNilPSLTests = map[string]string{ - "foo.www.example.com": "example.com", - "www.example.com": "example.com", - "example.com": "example.com", - "com": "com", - "foo.www.bbc.co.uk": "co.uk", - "www.bbc.co.uk": "co.uk", - "bbc.co.uk": "co.uk", - "co.uk": "co.uk", - "uk": "uk", - "192.168.0.5": "192.168.0.5", -} - -func TestJarKeyNilPSL(t *testing.T) { - for host, want := range jarKeyNilPSLTests { - if got := jarKey(host, nil); got != want { - t.Errorf("%q: got %q, want %q", host, got, want) - } - } -} - -var isIPTests = map[string]bool{ - "127.0.0.1": true, - "1.2.3.4": true, - "2001:4860:0:2001::68": true, - "example.com": false, - "1.1.1.300": false, - "www.foo.bar.net": false, - "123.foo.bar.net": false, -} - -func TestIsIP(t *testing.T) { - for host, want := range isIPTests { - if got := isIP(host); got != want { - t.Errorf("%q: got %t, want %t", host, got, want) - } - } -} - -var defaultPathTests = map[string]string{ - "/": "/", - "/abc": "/", - "/abc/": "/abc", - "/abc/xyz": "/abc", - "/abc/xyz/": "/abc/xyz", - "/a/b/c.html": "/a/b", - "": "/", - "strange": "/", - "//": "/", - "/a//b": "/a/", - "/a/./b": "/a/.", - "/a/../b": "/a/..", -} - -func TestDefaultPath(t *testing.T) { - for path, want := range defaultPathTests { - if got := defaultPath(path); got != want { - t.Errorf("%q: got %q, want %q", path, got, want) - } - } -} - -var domainAndTypeTests = [...]struct { - host string // host Set-Cookie header was received from - domain string // domain attribute in Set-Cookie header - wantDomain string // expected domain of cookie - wantHostOnly bool // expected host-cookie flag - wantErr error // expected error -}{ - {"www.example.com", "", "www.example.com", true, nil}, - {"127.0.0.1", "", "127.0.0.1", true, nil}, - {"2001:4860:0:2001::68", "", "2001:4860:0:2001::68", true, nil}, - {"www.example.com", "example.com", "example.com", false, nil}, - {"www.example.com", ".example.com", "example.com", false, nil}, - {"www.example.com", "www.example.com", "www.example.com", false, nil}, - {"www.example.com", ".www.example.com", "www.example.com", false, nil}, - {"foo.sso.example.com", "sso.example.com", "sso.example.com", false, nil}, - {"bar.co.uk", "bar.co.uk", "bar.co.uk", false, nil}, - {"foo.bar.co.uk", ".bar.co.uk", "bar.co.uk", false, nil}, - {"127.0.0.1", "127.0.0.1", "", false, errNoHostname}, - {"2001:4860:0:2001::68", "2001:4860:0:2001::68", "2001:4860:0:2001::68", false, errNoHostname}, - {"www.example.com", ".", "", false, errMalformedDomain}, - {"www.example.com", "..", "", false, errMalformedDomain}, - {"www.example.com", "other.com", "", false, errIllegalDomain}, - {"www.example.com", "com", "", false, errIllegalDomain}, - {"www.example.com", ".com", "", false, errIllegalDomain}, - {"foo.bar.co.uk", ".co.uk", "", false, errIllegalDomain}, - {"127.www.0.0.1", "127.0.0.1", "", false, errIllegalDomain}, - {"com", "", "com", true, nil}, - {"com", "com", "com", true, nil}, - {"com", ".com", "com", true, nil}, - {"co.uk", "", "co.uk", true, nil}, - {"co.uk", "co.uk", "co.uk", true, nil}, - {"co.uk", ".co.uk", "co.uk", true, nil}, -} - -func TestDomainAndType(t *testing.T) { - jar := newTestJar() - for _, tc := range domainAndTypeTests { - domain, hostOnly, err := jar.domainAndType(tc.host, tc.domain) - if err != tc.wantErr { - t.Errorf("%q/%q: got %q error, want %q", - tc.host, tc.domain, err, tc.wantErr) - continue - } - if err != nil { - continue - } - if domain != tc.wantDomain || hostOnly != tc.wantHostOnly { - t.Errorf("%q/%q: got %q/%t want %q/%t", - tc.host, tc.domain, domain, hostOnly, - tc.wantDomain, tc.wantHostOnly) - } - } -} - -// expiresIn creates an expires attribute delta seconds from tNow. -func expiresIn(delta int) string { - t := tNow.Add(time.Duration(delta) * time.Second) - return "expires=" + t.Format(time.RFC1123) -} - -// mustParseURL parses s to an URL and panics on error. -func mustParseURL(s string) *url.URL { - u, err := url.Parse(s) - if err != nil || u.Scheme == "" || u.Host == "" { - panic(fmt.Sprintf("Unable to parse URL %s.", s)) - } - return u -} - -// jarTest encapsulates the following actions on a jar: -// 1. Perform SetCookies with fromURL and the cookies from setCookies. -// (Done at time tNow + 0 ms.) -// 2. Check that the entries in the jar matches content. -// (Done at time tNow + 1001 ms.) -// 3. For each query in tests: Check that Cookies with toURL yields the -// cookies in want. -// (Query n done at tNow + (n+2)*1001 ms.) -type jarTest struct { - description string // The description of what this test is supposed to test - fromURL string // The full URL of the request from which Set-Cookie headers where received - setCookies []string // All the cookies received from fromURL - content string // The whole (non-expired) content of the jar - queries []query // Queries to test the Jar.Cookies method -} - -// query contains one test of the cookies returned from Jar.Cookies. -type query struct { - toURL string // the URL in the Cookies call - want string // the expected list of cookies (order matters) -} - -// run runs the jarTest. -func (test jarTest) run(t *testing.T, jar *Jar) { - now := tNow - - // Populate jar with cookies. - setCookies := make([]*http.Cookie, len(test.setCookies)) - for i, cs := range test.setCookies { - cookies := (&http.Response{Header: http.Header{"Set-Cookie": {cs}}}).Cookies() - if len(cookies) != 1 { - panic(fmt.Sprintf("Wrong cookie line %q: %#v", cs, cookies)) - } - setCookies[i] = cookies[0] - } - jar.setCookies(mustParseURL(test.fromURL), setCookies, now) - now = now.Add(1001 * time.Millisecond) - - // Serialize non-expired entries in the form "name1=val1 name2=val2". - var cs []string - for _, submap := range jar.entries { - for _, cookie := range submap { - if !cookie.Expires.After(now) { - continue - } - cs = append(cs, cookie.Name+"="+cookie.Value) - } - } - sort.Strings(cs) - got := strings.Join(cs, " ") - - // Make sure jar content matches our expectations. - if got != test.content { - t.Errorf("Test %q Content\ngot %q\nwant %q", - test.description, got, test.content) - } - - // Test different calls to Cookies. - for i, query := range test.queries { - now = now.Add(1001 * time.Millisecond) - var s []string - for _, c := range jar.cookies(mustParseURL(query.toURL), now) { - s = append(s, c.Name+"="+c.Value) - } - if got := strings.Join(s, " "); got != query.want { - t.Errorf("Test %q #%d\ngot %q\nwant %q", test.description, i, got, query.want) - } - } -} - -// basicsTests contains fundamental tests. Each jarTest has to be performed on -// a fresh, empty Jar. -var basicsTests = [...]jarTest{ - { - "Retrieval of a plain host cookie.", - "http://www.host.test/", - []string{"A=a"}, - "A=a", - []query{ - {"http://www.host.test", "A=a"}, - {"http://www.host.test/", "A=a"}, - {"http://www.host.test/some/path", "A=a"}, - {"https://www.host.test", "A=a"}, - {"https://www.host.test/", "A=a"}, - {"https://www.host.test/some/path", "A=a"}, - {"ftp://www.host.test", ""}, - {"ftp://www.host.test/", ""}, - {"ftp://www.host.test/some/path", ""}, - {"http://www.other.org", ""}, - {"http://sibling.host.test", ""}, - {"http://deep.www.host.test", ""}, - }, - }, - { - "Secure cookies are not returned to http.", - "http://www.host.test/", - []string{"A=a; secure"}, - "A=a", - []query{ - {"http://www.host.test", ""}, - {"http://www.host.test/", ""}, - {"http://www.host.test/some/path", ""}, - {"https://www.host.test", "A=a"}, - {"https://www.host.test/", "A=a"}, - {"https://www.host.test/some/path", "A=a"}, - }, - }, - { - "Explicit path.", - "http://www.host.test/", - []string{"A=a; path=/some/path"}, - "A=a", - []query{ - {"http://www.host.test", ""}, - {"http://www.host.test/", ""}, - {"http://www.host.test/some", ""}, - {"http://www.host.test/some/", ""}, - {"http://www.host.test/some/path", "A=a"}, - {"http://www.host.test/some/paths", ""}, - {"http://www.host.test/some/path/foo", "A=a"}, - {"http://www.host.test/some/path/foo/", "A=a"}, - }, - }, - { - "Implicit path #1: path is a directory.", - "http://www.host.test/some/path/", - []string{"A=a"}, - "A=a", - []query{ - {"http://www.host.test", ""}, - {"http://www.host.test/", ""}, - {"http://www.host.test/some", ""}, - {"http://www.host.test/some/", ""}, - {"http://www.host.test/some/path", "A=a"}, - {"http://www.host.test/some/paths", ""}, - {"http://www.host.test/some/path/foo", "A=a"}, - {"http://www.host.test/some/path/foo/", "A=a"}, - }, - }, - { - "Implicit path #2: path is not a directory.", - "http://www.host.test/some/path/index.html", - []string{"A=a"}, - "A=a", - []query{ - {"http://www.host.test", ""}, - {"http://www.host.test/", ""}, - {"http://www.host.test/some", ""}, - {"http://www.host.test/some/", ""}, - {"http://www.host.test/some/path", "A=a"}, - {"http://www.host.test/some/paths", ""}, - {"http://www.host.test/some/path/foo", "A=a"}, - {"http://www.host.test/some/path/foo/", "A=a"}, - }, - }, - { - "Implicit path #3: no path in URL at all.", - "http://www.host.test", - []string{"A=a"}, - "A=a", - []query{ - {"http://www.host.test", "A=a"}, - {"http://www.host.test/", "A=a"}, - {"http://www.host.test/some/path", "A=a"}, - }, - }, - { - "Cookies are sorted by path length.", - "http://www.host.test/", - []string{ - "A=a; path=/foo/bar", - "B=b; path=/foo/bar/baz/qux", - "C=c; path=/foo/bar/baz", - "D=d; path=/foo"}, - "A=a B=b C=c D=d", - []query{ - {"http://www.host.test/foo/bar/baz/qux", "B=b C=c A=a D=d"}, - {"http://www.host.test/foo/bar/baz/", "C=c A=a D=d"}, - {"http://www.host.test/foo/bar", "A=a D=d"}, - }, - }, - { - "Creation time determines sorting on same length paths.", - "http://www.host.test/", - []string{ - "A=a; path=/foo/bar", - "X=x; path=/foo/bar", - "Y=y; path=/foo/bar/baz/qux", - "B=b; path=/foo/bar/baz/qux", - "C=c; path=/foo/bar/baz", - "W=w; path=/foo/bar/baz", - "Z=z; path=/foo", - "D=d; path=/foo"}, - "A=a B=b C=c D=d W=w X=x Y=y Z=z", - []query{ - {"http://www.host.test/foo/bar/baz/qux", "Y=y B=b C=c W=w A=a X=x Z=z D=d"}, - {"http://www.host.test/foo/bar/baz/", "C=c W=w A=a X=x Z=z D=d"}, - {"http://www.host.test/foo/bar", "A=a X=x Z=z D=d"}, - }, - }, - { - "Sorting of same-name cookies.", - "http://www.host.test/", - []string{ - "A=1; path=/", - "A=2; path=/path", - "A=3; path=/quux", - "A=4; path=/path/foo", - "A=5; domain=.host.test; path=/path", - "A=6; domain=.host.test; path=/quux", - "A=7; domain=.host.test; path=/path/foo", - }, - "A=1 A=2 A=3 A=4 A=5 A=6 A=7", - []query{ - {"http://www.host.test/path", "A=2 A=5 A=1"}, - {"http://www.host.test/path/foo", "A=4 A=7 A=2 A=5 A=1"}, - }, - }, - { - "Disallow domain cookie on public suffix.", - "http://www.bbc.co.uk", - []string{ - "a=1", - "b=2; domain=co.uk", - }, - "a=1", - []query{{"http://www.bbc.co.uk", "a=1"}}, - }, - { - "Host cookie on IP.", - "http://192.168.0.10", - []string{"a=1"}, - "a=1", - []query{{"http://192.168.0.10", "a=1"}}, - }, - { - "Port is ignored #1.", - "http://www.host.test/", - []string{"a=1"}, - "a=1", - []query{ - {"http://www.host.test", "a=1"}, - {"http://www.host.test:8080/", "a=1"}, - }, - }, - { - "Port is ignored #2.", - "http://www.host.test:8080/", - []string{"a=1"}, - "a=1", - []query{ - {"http://www.host.test", "a=1"}, - {"http://www.host.test:8080/", "a=1"}, - {"http://www.host.test:1234/", "a=1"}, - }, - }, -} - -func TestBasics(t *testing.T) { - for _, test := range basicsTests { - jar := newTestJar() - test.run(t, jar) - } -} - -// updateAndDeleteTests contains jarTests which must be performed on the same -// Jar. -var updateAndDeleteTests = [...]jarTest{ - { - "Set initial cookies.", - "http://www.host.test", - []string{ - "a=1", - "b=2; secure", - "c=3; httponly", - "d=4; secure; httponly"}, - "a=1 b=2 c=3 d=4", - []query{ - {"http://www.host.test", "a=1 c=3"}, - {"https://www.host.test", "a=1 b=2 c=3 d=4"}, - }, - }, - { - "Update value via http.", - "http://www.host.test", - []string{ - "a=w", - "b=x; secure", - "c=y; httponly", - "d=z; secure; httponly"}, - "a=w b=x c=y d=z", - []query{ - {"http://www.host.test", "a=w c=y"}, - {"https://www.host.test", "a=w b=x c=y d=z"}, - }, - }, - { - "Clear Secure flag from a http.", - "http://www.host.test/", - []string{ - "b=xx", - "d=zz; httponly"}, - "a=w b=xx c=y d=zz", - []query{{"http://www.host.test", "a=w b=xx c=y d=zz"}}, - }, - { - "Delete all.", - "http://www.host.test/", - []string{ - "a=1; max-Age=-1", // delete via MaxAge - "b=2; " + expiresIn(-10), // delete via Expires - "c=2; max-age=-1; " + expiresIn(-10), // delete via both - "d=4; max-age=-1; " + expiresIn(10)}, // MaxAge takes precedence - "", - []query{{"http://www.host.test", ""}}, - }, - { - "Refill #1.", - "http://www.host.test", - []string{ - "A=1", - "A=2; path=/foo", - "A=3; domain=.host.test", - "A=4; path=/foo; domain=.host.test"}, - "A=1 A=2 A=3 A=4", - []query{{"http://www.host.test/foo", "A=2 A=4 A=1 A=3"}}, - }, - { - "Refill #2.", - "http://www.google.com", - []string{ - "A=6", - "A=7; path=/foo", - "A=8; domain=.google.com", - "A=9; path=/foo; domain=.google.com"}, - "A=1 A=2 A=3 A=4 A=6 A=7 A=8 A=9", - []query{ - {"http://www.host.test/foo", "A=2 A=4 A=1 A=3"}, - {"http://www.google.com/foo", "A=7 A=9 A=6 A=8"}, - }, - }, - { - "Delete A7.", - "http://www.google.com", - []string{"A=; path=/foo; max-age=-1"}, - "A=1 A=2 A=3 A=4 A=6 A=8 A=9", - []query{ - {"http://www.host.test/foo", "A=2 A=4 A=1 A=3"}, - {"http://www.google.com/foo", "A=9 A=6 A=8"}, - }, - }, - { - "Delete A4.", - "http://www.host.test", - []string{"A=; path=/foo; domain=host.test; max-age=-1"}, - "A=1 A=2 A=3 A=6 A=8 A=9", - []query{ - {"http://www.host.test/foo", "A=2 A=1 A=3"}, - {"http://www.google.com/foo", "A=9 A=6 A=8"}, - }, - }, - { - "Delete A6.", - "http://www.google.com", - []string{"A=; max-age=-1"}, - "A=1 A=2 A=3 A=8 A=9", - []query{ - {"http://www.host.test/foo", "A=2 A=1 A=3"}, - {"http://www.google.com/foo", "A=9 A=8"}, - }, - }, - { - "Delete A3.", - "http://www.host.test", - []string{"A=; domain=host.test; max-age=-1"}, - "A=1 A=2 A=8 A=9", - []query{ - {"http://www.host.test/foo", "A=2 A=1"}, - {"http://www.google.com/foo", "A=9 A=8"}, - }, - }, - { - "No cross-domain delete.", - "http://www.host.test", - []string{ - "A=; domain=google.com; max-age=-1", - "A=; path=/foo; domain=google.com; max-age=-1"}, - "A=1 A=2 A=8 A=9", - []query{ - {"http://www.host.test/foo", "A=2 A=1"}, - {"http://www.google.com/foo", "A=9 A=8"}, - }, - }, - { - "Delete A8 and A9.", - "http://www.google.com", - []string{ - "A=; domain=google.com; max-age=-1", - "A=; path=/foo; domain=google.com; max-age=-1"}, - "A=1 A=2", - []query{ - {"http://www.host.test/foo", "A=2 A=1"}, - {"http://www.google.com/foo", ""}, - }, - }, -} - -func TestUpdateAndDelete(t *testing.T) { - jar := newTestJar() - for _, test := range updateAndDeleteTests { - test.run(t, jar) - } -} - -func TestExpiration(t *testing.T) { - jar := newTestJar() - jarTest{ - "Expiration.", - "http://www.host.test", - []string{ - "a=1", - "b=2; max-age=3", - "c=3; " + expiresIn(3), - "d=4; max-age=5", - "e=5; " + expiresIn(5), - "f=6; max-age=100", - }, - "a=1 b=2 c=3 d=4 e=5 f=6", // executed at t0 + 1001 ms - []query{ - {"http://www.host.test", "a=1 b=2 c=3 d=4 e=5 f=6"}, // t0 + 2002 ms - {"http://www.host.test", "a=1 d=4 e=5 f=6"}, // t0 + 3003 ms - {"http://www.host.test", "a=1 d=4 e=5 f=6"}, // t0 + 4004 ms - {"http://www.host.test", "a=1 f=6"}, // t0 + 5005 ms - {"http://www.host.test", "a=1 f=6"}, // t0 + 6006 ms - }, - }.run(t, jar) -} - -// -// Tests derived from Chromium's cookie_store_unittest.h. -// - -// See http://src.chromium.org/viewvc/chrome/trunk/src/net/cookies/cookie_store_unittest.h?revision=159685&content-type=text/plain -// Some of the original tests are in a bad condition (e.g. -// DomainWithTrailingDotTest) or are not RFC 6265 conforming (e.g. -// TestNonDottedAndTLD #1 and #6) and have not been ported. - -// chromiumBasicsTests contains fundamental tests. Each jarTest has to be -// performed on a fresh, empty Jar. -var chromiumBasicsTests = [...]jarTest{ - { - "DomainWithTrailingDotTest.", - "http://www.google.com/", - []string{ - "a=1; domain=.www.google.com.", - "b=2; domain=.www.google.com.."}, - "", - []query{ - {"http://www.google.com", ""}, - }, - }, - { - "ValidSubdomainTest #1.", - "http://a.b.c.d.com", - []string{ - "a=1; domain=.a.b.c.d.com", - "b=2; domain=.b.c.d.com", - "c=3; domain=.c.d.com", - "d=4; domain=.d.com"}, - "a=1 b=2 c=3 d=4", - []query{ - {"http://a.b.c.d.com", "a=1 b=2 c=3 d=4"}, - {"http://b.c.d.com", "b=2 c=3 d=4"}, - {"http://c.d.com", "c=3 d=4"}, - {"http://d.com", "d=4"}, - }, - }, - { - "ValidSubdomainTest #2.", - "http://a.b.c.d.com", - []string{ - "a=1; domain=.a.b.c.d.com", - "b=2; domain=.b.c.d.com", - "c=3; domain=.c.d.com", - "d=4; domain=.d.com", - "X=bcd; domain=.b.c.d.com", - "X=cd; domain=.c.d.com"}, - "X=bcd X=cd a=1 b=2 c=3 d=4", - []query{ - {"http://b.c.d.com", "b=2 c=3 d=4 X=bcd X=cd"}, - {"http://c.d.com", "c=3 d=4 X=cd"}, - }, - }, - { - "InvalidDomainTest #1.", - "http://foo.bar.com", - []string{ - "a=1; domain=.yo.foo.bar.com", - "b=2; domain=.foo.com", - "c=3; domain=.bar.foo.com", - "d=4; domain=.foo.bar.com.net", - "e=5; domain=ar.com", - "f=6; domain=.", - "g=7; domain=/", - "h=8; domain=http://foo.bar.com", - "i=9; domain=..foo.bar.com", - "j=10; domain=..bar.com", - "k=11; domain=.foo.bar.com?blah", - "l=12; domain=.foo.bar.com/blah", - "m=12; domain=.foo.bar.com:80", - "n=14; domain=.foo.bar.com:", - "o=15; domain=.foo.bar.com#sup", - }, - "", // Jar is empty. - []query{{"http://foo.bar.com", ""}}, - }, - { - "InvalidDomainTest #2.", - "http://foo.com.com", - []string{"a=1; domain=.foo.com.com.com"}, - "", - []query{{"http://foo.bar.com", ""}}, - }, - { - "DomainWithoutLeadingDotTest #1.", - "http://manage.hosted.filefront.com", - []string{"a=1; domain=filefront.com"}, - "a=1", - []query{{"http://www.filefront.com", "a=1"}}, - }, - { - "DomainWithoutLeadingDotTest #2.", - "http://www.google.com", - []string{"a=1; domain=www.google.com"}, - "a=1", - []query{ - {"http://www.google.com", "a=1"}, - {"http://sub.www.google.com", "a=1"}, - {"http://something-else.com", ""}, - }, - }, - { - "CaseInsensitiveDomainTest.", - "http://www.google.com", - []string{ - "a=1; domain=.GOOGLE.COM", - "b=2; domain=.www.gOOgLE.coM"}, - "a=1 b=2", - []query{{"http://www.google.com", "a=1 b=2"}}, - }, - { - "TestIpAddress #1.", - "http://1.2.3.4/foo", - []string{"a=1; path=/"}, - "a=1", - []query{{"http://1.2.3.4/foo", "a=1"}}, - }, - { - "TestIpAddress #2.", - "http://1.2.3.4/foo", - []string{ - "a=1; domain=.1.2.3.4", - "b=2; domain=.3.4"}, - "", - []query{{"http://1.2.3.4/foo", ""}}, - }, - { - "TestIpAddress #3.", - "http://1.2.3.4/foo", - []string{"a=1; domain=1.2.3.4"}, - "", - []query{{"http://1.2.3.4/foo", ""}}, - }, - { - "TestNonDottedAndTLD #2.", - "http://com./index.html", - []string{"a=1"}, - "a=1", - []query{ - {"http://com./index.html", "a=1"}, - {"http://no-cookies.com./index.html", ""}, - }, - }, - { - "TestNonDottedAndTLD #3.", - "http://a.b", - []string{ - "a=1; domain=.b", - "b=2; domain=b"}, - "", - []query{{"http://bar.foo", ""}}, - }, - { - "TestNonDottedAndTLD #4.", - "http://google.com", - []string{ - "a=1; domain=.com", - "b=2; domain=com"}, - "", - []query{{"http://google.com", ""}}, - }, - { - "TestNonDottedAndTLD #5.", - "http://google.co.uk", - []string{ - "a=1; domain=.co.uk", - "b=2; domain=.uk"}, - "", - []query{ - {"http://google.co.uk", ""}, - {"http://else.co.com", ""}, - {"http://else.uk", ""}, - }, - }, - { - "TestHostEndsWithDot.", - "http://www.google.com", - []string{ - "a=1", - "b=2; domain=.www.google.com."}, - "a=1", - []query{{"http://www.google.com", "a=1"}}, - }, - { - "PathTest", - "http://www.google.izzle", - []string{"a=1; path=/wee"}, - "a=1", - []query{ - {"http://www.google.izzle/wee", "a=1"}, - {"http://www.google.izzle/wee/", "a=1"}, - {"http://www.google.izzle/wee/war", "a=1"}, - {"http://www.google.izzle/wee/war/more/more", "a=1"}, - {"http://www.google.izzle/weehee", ""}, - {"http://www.google.izzle/", ""}, - }, - }, -} - -func TestChromiumBasics(t *testing.T) { - for _, test := range chromiumBasicsTests { - jar := newTestJar() - test.run(t, jar) - } -} - -// chromiumDomainTests contains jarTests which must be executed all on the -// same Jar. -var chromiumDomainTests = [...]jarTest{ - { - "Fill #1.", - "http://www.google.izzle", - []string{"A=B"}, - "A=B", - []query{{"http://www.google.izzle", "A=B"}}, - }, - { - "Fill #2.", - "http://www.google.izzle", - []string{"C=D; domain=.google.izzle"}, - "A=B C=D", - []query{{"http://www.google.izzle", "A=B C=D"}}, - }, - { - "Verify A is a host cookie and not accessible from subdomain.", - "http://unused.nil", - []string{}, - "A=B C=D", - []query{{"http://foo.www.google.izzle", "C=D"}}, - }, - { - "Verify domain cookies are found on proper domain.", - "http://www.google.izzle", - []string{"E=F; domain=.www.google.izzle"}, - "A=B C=D E=F", - []query{{"http://www.google.izzle", "A=B C=D E=F"}}, - }, - { - "Leading dots in domain attributes are optional.", - "http://www.google.izzle", - []string{"G=H; domain=www.google.izzle"}, - "A=B C=D E=F G=H", - []query{{"http://www.google.izzle", "A=B C=D E=F G=H"}}, - }, - { - "Verify domain enforcement works #1.", - "http://www.google.izzle", - []string{"K=L; domain=.bar.www.google.izzle"}, - "A=B C=D E=F G=H", - []query{{"http://bar.www.google.izzle", "C=D E=F G=H"}}, - }, - { - "Verify domain enforcement works #2.", - "http://unused.nil", - []string{}, - "A=B C=D E=F G=H", - []query{{"http://www.google.izzle", "A=B C=D E=F G=H"}}, - }, -} - -func TestChromiumDomain(t *testing.T) { - jar := newTestJar() - for _, test := range chromiumDomainTests { - test.run(t, jar) - } - -} - -// chromiumDeletionTests must be performed all on the same Jar. -var chromiumDeletionTests = [...]jarTest{ - { - "Create session cookie a1.", - "http://www.google.com", - []string{"a=1"}, - "a=1", - []query{{"http://www.google.com", "a=1"}}, - }, - { - "Delete sc a1 via MaxAge.", - "http://www.google.com", - []string{"a=1; max-age=-1"}, - "", - []query{{"http://www.google.com", ""}}, - }, - { - "Create session cookie b2.", - "http://www.google.com", - []string{"b=2"}, - "b=2", - []query{{"http://www.google.com", "b=2"}}, - }, - { - "Delete sc b2 via Expires.", - "http://www.google.com", - []string{"b=2; " + expiresIn(-10)}, - "", - []query{{"http://www.google.com", ""}}, - }, - { - "Create persistent cookie c3.", - "http://www.google.com", - []string{"c=3; max-age=3600"}, - "c=3", - []query{{"http://www.google.com", "c=3"}}, - }, - { - "Delete pc c3 via MaxAge.", - "http://www.google.com", - []string{"c=3; max-age=-1"}, - "", - []query{{"http://www.google.com", ""}}, - }, - { - "Create persistent cookie d4.", - "http://www.google.com", - []string{"d=4; max-age=3600"}, - "d=4", - []query{{"http://www.google.com", "d=4"}}, - }, - { - "Delete pc d4 via Expires.", - "http://www.google.com", - []string{"d=4; " + expiresIn(-10)}, - "", - []query{{"http://www.google.com", ""}}, - }, -} - -func TestChromiumDeletion(t *testing.T) { - jar := newTestJar() - for _, test := range chromiumDeletionTests { - test.run(t, jar) - } -} - -// domainHandlingTests tests and documents the rules for domain handling. -// Each test must be performed on an empty new Jar. -var domainHandlingTests = [...]jarTest{ - { - "Host cookie", - "http://www.host.test", - []string{"a=1"}, - "a=1", - []query{ - {"http://www.host.test", "a=1"}, - {"http://host.test", ""}, - {"http://bar.host.test", ""}, - {"http://foo.www.host.test", ""}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Domain cookie #1", - "http://www.host.test", - []string{"a=1; domain=host.test"}, - "a=1", - []query{ - {"http://www.host.test", "a=1"}, - {"http://host.test", "a=1"}, - {"http://bar.host.test", "a=1"}, - {"http://foo.www.host.test", "a=1"}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Domain cookie #2", - "http://www.host.test", - []string{"a=1; domain=.host.test"}, - "a=1", - []query{ - {"http://www.host.test", "a=1"}, - {"http://host.test", "a=1"}, - {"http://bar.host.test", "a=1"}, - {"http://foo.www.host.test", "a=1"}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Host cookie on IDNA domain #1", - "http://www.bücher.test", - []string{"a=1"}, - "a=1", - []query{ - {"http://www.bücher.test", "a=1"}, - {"http://www.xn--bcher-kva.test", "a=1"}, - {"http://bücher.test", ""}, - {"http://xn--bcher-kva.test", ""}, - {"http://bar.bücher.test", ""}, - {"http://bar.xn--bcher-kva.test", ""}, - {"http://foo.www.bücher.test", ""}, - {"http://foo.www.xn--bcher-kva.test", ""}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Host cookie on IDNA domain #2", - "http://www.xn--bcher-kva.test", - []string{"a=1"}, - "a=1", - []query{ - {"http://www.bücher.test", "a=1"}, - {"http://www.xn--bcher-kva.test", "a=1"}, - {"http://bücher.test", ""}, - {"http://xn--bcher-kva.test", ""}, - {"http://bar.bücher.test", ""}, - {"http://bar.xn--bcher-kva.test", ""}, - {"http://foo.www.bücher.test", ""}, - {"http://foo.www.xn--bcher-kva.test", ""}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Domain cookie on IDNA domain #1", - "http://www.bücher.test", - []string{"a=1; domain=xn--bcher-kva.test"}, - "a=1", - []query{ - {"http://www.bücher.test", "a=1"}, - {"http://www.xn--bcher-kva.test", "a=1"}, - {"http://bücher.test", "a=1"}, - {"http://xn--bcher-kva.test", "a=1"}, - {"http://bar.bücher.test", "a=1"}, - {"http://bar.xn--bcher-kva.test", "a=1"}, - {"http://foo.www.bücher.test", "a=1"}, - {"http://foo.www.xn--bcher-kva.test", "a=1"}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Domain cookie on IDNA domain #2", - "http://www.xn--bcher-kva.test", - []string{"a=1; domain=xn--bcher-kva.test"}, - "a=1", - []query{ - {"http://www.bücher.test", "a=1"}, - {"http://www.xn--bcher-kva.test", "a=1"}, - {"http://bücher.test", "a=1"}, - {"http://xn--bcher-kva.test", "a=1"}, - {"http://bar.bücher.test", "a=1"}, - {"http://bar.xn--bcher-kva.test", "a=1"}, - {"http://foo.www.bücher.test", "a=1"}, - {"http://foo.www.xn--bcher-kva.test", "a=1"}, - {"http://other.test", ""}, - {"http://test", ""}, - }, - }, - { - "Host cookie on TLD.", - "http://com", - []string{"a=1"}, - "a=1", - []query{ - {"http://com", "a=1"}, - {"http://any.com", ""}, - {"http://any.test", ""}, - }, - }, - { - "Domain cookie on TLD becomes a host cookie.", - "http://com", - []string{"a=1; domain=com"}, - "a=1", - []query{ - {"http://com", "a=1"}, - {"http://any.com", ""}, - {"http://any.test", ""}, - }, - }, - { - "Host cookie on public suffix.", - "http://co.uk", - []string{"a=1"}, - "a=1", - []query{ - {"http://co.uk", "a=1"}, - {"http://uk", ""}, - {"http://some.co.uk", ""}, - {"http://foo.some.co.uk", ""}, - {"http://any.uk", ""}, - }, - }, - { - "Domain cookie on public suffix is ignored.", - "http://some.co.uk", - []string{"a=1; domain=co.uk"}, - "", - []query{ - {"http://co.uk", ""}, - {"http://uk", ""}, - {"http://some.co.uk", ""}, - {"http://foo.some.co.uk", ""}, - {"http://any.uk", ""}, - }, - }, -} - -func TestDomainHandling(t *testing.T) { - for _, test := range domainHandlingTests { - jar := newTestJar() - test.run(t, jar) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/punycode.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/punycode.go deleted file mode 100644 index ea7ceb5ef3..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/punycode.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cookiejar - -// This file implements the Punycode algorithm from RFC 3492. - -import ( - "fmt" - "strings" - "unicode/utf8" -) - -// These parameter values are specified in section 5. -// -// All computation is done with int32s, so that overflow behavior is identical -// regardless of whether int is 32-bit or 64-bit. -const ( - base int32 = 36 - damp int32 = 700 - initialBias int32 = 72 - initialN int32 = 128 - skew int32 = 38 - tmax int32 = 26 - tmin int32 = 1 -) - -// encode encodes a string as specified in section 6.3 and prepends prefix to -// the result. -// -// The "while h < length(input)" line in the specification becomes "for -// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes. -func encode(prefix, s string) (string, error) { - output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) - copy(output, prefix) - delta, n, bias := int32(0), initialN, initialBias - b, remaining := int32(0), int32(0) - for _, r := range s { - if r < 0x80 { - b++ - output = append(output, byte(r)) - } else { - remaining++ - } - } - h := b - if b > 0 { - output = append(output, '-') - } - for remaining != 0 { - m := int32(0x7fffffff) - for _, r := range s { - if m > r && r >= n { - m = r - } - } - delta += (m - n) * (h + 1) - if delta < 0 { - return "", fmt.Errorf("cookiejar: invalid label %q", s) - } - n = m - for _, r := range s { - if r < n { - delta++ - if delta < 0 { - return "", fmt.Errorf("cookiejar: invalid label %q", s) - } - continue - } - if r > n { - continue - } - q := delta - for k := base; ; k += base { - t := k - bias - if t < tmin { - t = tmin - } else if t > tmax { - t = tmax - } - if q < t { - break - } - output = append(output, encodeDigit(t+(q-t)%(base-t))) - q = (q - t) / (base - t) - } - output = append(output, encodeDigit(q)) - bias = adapt(delta, h+1, h == b) - delta = 0 - h++ - remaining-- - } - delta++ - n++ - } - return string(output), nil -} - -func encodeDigit(digit int32) byte { - switch { - case 0 <= digit && digit < 26: - return byte(digit + 'a') - case 26 <= digit && digit < 36: - return byte(digit + ('0' - 26)) - } - panic("cookiejar: internal error in punycode encoding") -} - -// adapt is the bias adaptation function specified in section 6.1. -func adapt(delta, numPoints int32, firstTime bool) int32 { - if firstTime { - delta /= damp - } else { - delta /= 2 - } - delta += delta / numPoints - k := int32(0) - for delta > ((base-tmin)*tmax)/2 { - delta /= base - tmin - k += base - } - return k + (base-tmin+1)*delta/(delta+skew) -} - -// Strictly speaking, the remaining code below deals with IDNA (RFC 5890 and -// friends) and not Punycode (RFC 3492) per se. - -// acePrefix is the ASCII Compatible Encoding prefix. -const acePrefix = "xn--" - -// toASCII converts a domain or domain label to its ASCII form. For example, -// toASCII("bücher.example.com") is "xn--bcher-kva.example.com", and -// toASCII("golang") is "golang". -func toASCII(s string) (string, error) { - if ascii(s) { - return s, nil - } - labels := strings.Split(s, ".") - for i, label := range labels { - if !ascii(label) { - a, err := encode(acePrefix, label) - if err != nil { - return "", err - } - labels[i] = a - } - } - return strings.Join(labels, "."), nil -} - -func ascii(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - return false - } - } - return true -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/punycode_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/punycode_test.go deleted file mode 100644 index 0301de14e4..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/cookiejar/punycode_test.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cookiejar - -import ( - "testing" -) - -var punycodeTestCases = [...]struct { - s, encoded string -}{ - {"", ""}, - {"-", "--"}, - {"-a", "-a-"}, - {"-a-", "-a--"}, - {"a", "a-"}, - {"a-", "a--"}, - {"a-b", "a-b-"}, - {"books", "books-"}, - {"bücher", "bcher-kva"}, - {"Hello世界", "Hello-ck1hg65u"}, - {"ü", "tda"}, - {"üý", "tdac"}, - - // The test cases below come from RFC 3492 section 7.1 with Errata 3026. - { - // (A) Arabic (Egyptian). - "\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" + - "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F", - "egbpdaj6bu4bxfgehfvwxn", - }, - { - // (B) Chinese (simplified). - "\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587", - "ihqwcrb4cv8a8dqg056pqjye", - }, - { - // (C) Chinese (traditional). - "\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587", - "ihqwctvzc91f659drss3x8bo0yb", - }, - { - // (D) Czech. - "\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074" + - "\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D" + - "\u0065\u0073\u006B\u0079", - "Proprostnemluvesky-uyb24dma41a", - }, - { - // (E) Hebrew. - "\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8" + - "\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2" + - "\u05D1\u05E8\u05D9\u05EA", - "4dbcagdahymbxekheh6e0a7fei0b", - }, - { - // (F) Hindi (Devanagari). - "\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D" + - "\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939" + - "\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947" + - "\u0939\u0948\u0902", - "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd", - }, - { - // (G) Japanese (kanji and hiragana). - "\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092" + - "\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B", - "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa", - }, - { - // (H) Korean (Hangul syllables). - "\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774" + - "\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74" + - "\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C", - "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j" + - "psd879ccm6fea98c", - }, - { - // (I) Russian (Cyrillic). - "\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E" + - "\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440" + - "\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A" + - "\u0438", - "b1abfaaepdrnnbgefbadotcwatmq2g4l", - }, - { - // (J) Spanish. - "\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070" + - "\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070" + - "\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061" + - "\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070" + - "\u0061\u00F1\u006F\u006C", - "PorqunopuedensimplementehablarenEspaol-fmd56a", - }, - { - // (K) Vietnamese. - "\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B" + - "\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068" + - "\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067" + - "\u0056\u0069\u1EC7\u0074", - "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g", - }, - { - // (L) 3B. - "\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F", - "3B-ww4c5e180e575a65lsy2b", - }, - { - // (M) -with-SUPER-MONKEYS. - "\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074" + - "\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D" + - "\u004F\u004E\u004B\u0045\u0059\u0053", - "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n", - }, - { - // (N) Hello-Another-Way-. - "\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F" + - "\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D" + - "\u305D\u308C\u305E\u308C\u306E\u5834\u6240", - "Hello-Another-Way--fc4qua05auwb3674vfr0b", - }, - { - // (O) 2. - "\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032", - "2-u9tlzr9756bt3uc0v", - }, - { - // (P) MajiKoi5 - "\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" + - "\u308B\u0035\u79D2\u524D", - "MajiKoi5-783gue6qz075azm5e", - }, - { - // (Q) de - "\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0", - "de-jg4avhby1noc0d", - }, - { - // (R) - "\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067", - "d9juau41awczczp", - }, - { - // (S) -> $1.00 <- - "\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020" + - "\u003C\u002D", - "-> $1.00 <--", - }, -} - -func TestPunycode(t *testing.T) { - for _, tc := range punycodeTestCases { - if got, err := encode("", tc.s); err != nil { - t.Errorf(`encode("", %q): %v`, tc.s, err) - } else if got != tc.encoded { - t.Errorf(`encode("", %q): got %q, want %q`, tc.s, got, tc.encoded) - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/doc.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/doc.go deleted file mode 100644 index b1216e8daf..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/doc.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package http provides HTTP client and server implementations. - -Get, Head, Post, and PostForm make HTTP (or HTTPS) requests: - - resp, err := http.Get("http://example.com/") - ... - resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf) - ... - resp, err := http.PostForm("http://example.com/form", - url.Values{"key": {"Value"}, "id": {"123"}}) - -The client must close the response body when finished with it: - - resp, err := http.Get("http://example.com/") - if err != nil { - // handle error - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - // ... - -For control over HTTP client headers, redirect policy, and other -settings, create a Client: - - client := &http.Client{ - CheckRedirect: redirectPolicyFunc, - } - - resp, err := client.Get("http://example.com") - // ... - - req, err := http.NewRequest("GET", "http://example.com", nil) - // ... - req.Header.Add("If-None-Match", `W/"wyzzy"`) - resp, err := client.Do(req) - // ... - -For control over proxies, TLS configuration, keep-alives, -compression, and other settings, create a Transport: - - tr := &http.Transport{ - TLSClientConfig: &tls.Config{RootCAs: pool}, - DisableCompression: true, - } - client := &http.Client{Transport: tr} - resp, err := client.Get("https://example.com") - -Clients and Transports are safe for concurrent use by multiple -goroutines and for efficiency should only be created once and re-used. - -ListenAndServe starts an HTTP server with a given address and handler. -The handler is usually nil, which means to use DefaultServeMux. -Handle and HandleFunc add handlers to DefaultServeMux: - - http.Handle("/foo", fooHandler) - - http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) - }) - - log.Fatal(http.ListenAndServe(":8080", nil)) - -More control over the server's behavior is available by creating a -custom Server: - - s := &http.Server{ - Addr: ":8080", - Handler: myHandler, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, - MaxHeaderBytes: 1 << 20, - } - log.Fatal(s.ListenAndServe()) -*/ -package http diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/example_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/example_test.go deleted file mode 100644 index 88b97d9e3d..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/example_test.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "fmt" - "io/ioutil" - "log" - "net/http" -) - -func ExampleHijacker() { - http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) { - hj, ok := w.(http.Hijacker) - if !ok { - http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError) - return - } - conn, bufrw, err := hj.Hijack() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - // Don't forget to close the connection: - defer conn.Close() - bufrw.WriteString("Now we're speaking raw TCP. Say hi: ") - bufrw.Flush() - s, err := bufrw.ReadString('\n') - if err != nil { - log.Printf("error reading string: %v", err) - return - } - fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s) - bufrw.Flush() - }) -} - -func ExampleGet() { - res, err := http.Get("http://www.google.com/robots.txt") - if err != nil { - log.Fatal(err) - } - robots, err := ioutil.ReadAll(res.Body) - res.Body.Close() - if err != nil { - log.Fatal(err) - } - fmt.Printf("%s", robots) -} - -func ExampleFileServer() { - // Simple static webserver: - log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc")))) -} - -func ExampleFileServer_stripPrefix() { - // To serve a directory on disk (/tmp) under an alternate URL - // path (/tmpfiles/), use StripPrefix to modify the request - // URL's path before the FileServer sees it: - http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp")))) -} - -func ExampleStripPrefix() { - // To serve a directory on disk (/tmp) under an alternate URL - // path (/tmpfiles/), use StripPrefix to modify the request - // URL's path before the FileServer sees it: - http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp")))) -} - -type apiHandler struct{} - -func (apiHandler) ServeHTTP(http.ResponseWriter, *http.Request) {} - -func ExampleServeMux_Handle() { - mux := http.NewServeMux() - mux.Handle("/api/", apiHandler{}) - mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { - // The "/" pattern matches everything, so we need to check - // that we're at the root here. - if req.URL.Path != "/" { - http.NotFound(w, req) - return - } - fmt.Fprintf(w, "Welcome to the home page!") - }) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/export_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/export_test.go deleted file mode 100644 index 960563b240..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/export_test.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Bridge package to expose http internals to tests in the http_test -// package. - -package http - -import ( - "net" - "time" -) - -func NewLoggingConn(baseName string, c net.Conn) net.Conn { - return newLoggingConn(baseName, c) -} - -var ExportAppendTime = appendTime - -func (t *Transport) NumPendingRequestsForTesting() int { - t.reqMu.Lock() - defer t.reqMu.Unlock() - return len(t.reqCanceler) -} - -func (t *Transport) IdleConnKeysForTesting() (keys []string) { - keys = make([]string, 0) - t.idleMu.Lock() - defer t.idleMu.Unlock() - if t.idleConn == nil { - return - } - for key := range t.idleConn { - keys = append(keys, key.String()) - } - return -} - -func (t *Transport) IdleConnCountForTesting(cacheKey string) int { - t.idleMu.Lock() - defer t.idleMu.Unlock() - if t.idleConn == nil { - return 0 - } - for k, conns := range t.idleConn { - if k.String() == cacheKey { - return len(conns) - } - } - return 0 -} - -func (t *Transport) IdleConnChMapSizeForTesting() int { - t.idleMu.Lock() - defer t.idleMu.Unlock() - return len(t.idleConnCh) -} - -func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler { - f := func() <-chan time.Time { - return ch - } - return &timeoutHandler{handler, f, ""} -} - -func ResetCachedEnvironment() { - httpProxyEnv.reset() - noProxyEnv.reset() -} - -var DefaultUserAgent = defaultUserAgent diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/child.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/child.go deleted file mode 100644 index a3beaa33a8..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/child.go +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package fcgi - -// This file implements FastCGI from the perspective of a child process. - -import ( - "errors" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/http/cgi" - "os" - "strings" - "sync" - "time" -) - -// request holds the state for an in-progress request. As soon as it's complete, -// it's converted to an http.Request. -type request struct { - pw *io.PipeWriter - reqId uint16 - params map[string]string - buf [1024]byte - rawParams []byte - keepConn bool -} - -func newRequest(reqId uint16, flags uint8) *request { - r := &request{ - reqId: reqId, - params: map[string]string{}, - keepConn: flags&flagKeepConn != 0, - } - r.rawParams = r.buf[:0] - return r -} - -// parseParams reads an encoded []byte into Params. -func (r *request) parseParams() { - text := r.rawParams - r.rawParams = nil - for len(text) > 0 { - keyLen, n := readSize(text) - if n == 0 { - return - } - text = text[n:] - valLen, n := readSize(text) - if n == 0 { - return - } - text = text[n:] - key := readString(text, keyLen) - text = text[keyLen:] - val := readString(text, valLen) - text = text[valLen:] - r.params[key] = val - } -} - -// response implements http.ResponseWriter. -type response struct { - req *request - header http.Header - w *bufWriter - wroteHeader bool -} - -func newResponse(c *child, req *request) *response { - return &response{ - req: req, - header: http.Header{}, - w: newWriter(c.conn, typeStdout, req.reqId), - } -} - -func (r *response) Header() http.Header { - return r.header -} - -func (r *response) Write(data []byte) (int, error) { - if !r.wroteHeader { - r.WriteHeader(http.StatusOK) - } - return r.w.Write(data) -} - -func (r *response) WriteHeader(code int) { - if r.wroteHeader { - return - } - r.wroteHeader = true - if code == http.StatusNotModified { - // Must not have body. - r.header.Del("Content-Type") - r.header.Del("Content-Length") - r.header.Del("Transfer-Encoding") - } else if r.header.Get("Content-Type") == "" { - r.header.Set("Content-Type", "text/html; charset=utf-8") - } - - if r.header.Get("Date") == "" { - r.header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) - } - - fmt.Fprintf(r.w, "Status: %d %s\r\n", code, http.StatusText(code)) - r.header.Write(r.w) - r.w.WriteString("\r\n") -} - -func (r *response) Flush() { - if !r.wroteHeader { - r.WriteHeader(http.StatusOK) - } - r.w.Flush() -} - -func (r *response) Close() error { - r.Flush() - return r.w.Close() -} - -type child struct { - conn *conn - handler http.Handler - - mu sync.Mutex // protects requests: - requests map[uint16]*request // keyed by request ID -} - -func newChild(rwc io.ReadWriteCloser, handler http.Handler) *child { - return &child{ - conn: newConn(rwc), - handler: handler, - requests: make(map[uint16]*request), - } -} - -func (c *child) serve() { - defer c.conn.Close() - var rec record - for { - if err := rec.read(c.conn.rwc); err != nil { - return - } - if err := c.handleRecord(&rec); err != nil { - return - } - } -} - -var errCloseConn = errors.New("fcgi: connection should be closed") - -var emptyBody = ioutil.NopCloser(strings.NewReader("")) - -func (c *child) handleRecord(rec *record) error { - c.mu.Lock() - req, ok := c.requests[rec.h.Id] - c.mu.Unlock() - if !ok && rec.h.Type != typeBeginRequest && rec.h.Type != typeGetValues { - // The spec says to ignore unknown request IDs. - return nil - } - - switch rec.h.Type { - case typeBeginRequest: - if req != nil { - // The server is trying to begin a request with the same ID - // as an in-progress request. This is an error. - return errors.New("fcgi: received ID that is already in-flight") - } - - var br beginRequest - if err := br.read(rec.content()); err != nil { - return err - } - if br.role != roleResponder { - c.conn.writeEndRequest(rec.h.Id, 0, statusUnknownRole) - return nil - } - req = newRequest(rec.h.Id, br.flags) - c.mu.Lock() - c.requests[rec.h.Id] = req - c.mu.Unlock() - return nil - case typeParams: - // NOTE(eds): Technically a key-value pair can straddle the boundary - // between two packets. We buffer until we've received all parameters. - if len(rec.content()) > 0 { - req.rawParams = append(req.rawParams, rec.content()...) - return nil - } - req.parseParams() - return nil - case typeStdin: - content := rec.content() - if req.pw == nil { - var body io.ReadCloser - if len(content) > 0 { - // body could be an io.LimitReader, but it shouldn't matter - // as long as both sides are behaving. - body, req.pw = io.Pipe() - } else { - body = emptyBody - } - go c.serveRequest(req, body) - } - if len(content) > 0 { - // TODO(eds): This blocks until the handler reads from the pipe. - // If the handler takes a long time, it might be a problem. - req.pw.Write(content) - } else if req.pw != nil { - req.pw.Close() - } - return nil - case typeGetValues: - values := map[string]string{"FCGI_MPXS_CONNS": "1"} - c.conn.writePairs(typeGetValuesResult, 0, values) - return nil - case typeData: - // If the filter role is implemented, read the data stream here. - return nil - case typeAbortRequest: - println("abort") - c.mu.Lock() - delete(c.requests, rec.h.Id) - c.mu.Unlock() - c.conn.writeEndRequest(rec.h.Id, 0, statusRequestComplete) - if !req.keepConn { - // connection will close upon return - return errCloseConn - } - return nil - default: - b := make([]byte, 8) - b[0] = byte(rec.h.Type) - c.conn.writeRecord(typeUnknownType, 0, b) - return nil - } -} - -func (c *child) serveRequest(req *request, body io.ReadCloser) { - r := newResponse(c, req) - httpReq, err := cgi.RequestFromMap(req.params) - if err != nil { - // there was an error reading the request - r.WriteHeader(http.StatusInternalServerError) - c.conn.writeRecord(typeStderr, req.reqId, []byte(err.Error())) - } else { - httpReq.Body = body - c.handler.ServeHTTP(r, httpReq) - } - r.Close() - c.mu.Lock() - delete(c.requests, req.reqId) - c.mu.Unlock() - c.conn.writeEndRequest(req.reqId, 0, statusRequestComplete) - - // Consume the entire body, so the host isn't still writing to - // us when we close the socket below in the !keepConn case, - // otherwise we'd send a RST. (golang.org/issue/4183) - // TODO(bradfitz): also bound this copy in time. Or send - // some sort of abort request to the host, so the host - // can properly cut off the client sending all the data. - // For now just bound it a little and - io.CopyN(ioutil.Discard, body, 100<<20) - body.Close() - - if !req.keepConn { - c.conn.Close() - } -} - -// Serve accepts incoming FastCGI connections on the listener l, creating a new -// goroutine for each. The goroutine reads requests and then calls handler -// to reply to them. -// If l is nil, Serve accepts connections from os.Stdin. -// If handler is nil, http.DefaultServeMux is used. -func Serve(l net.Listener, handler http.Handler) error { - if l == nil { - var err error - l, err = net.FileListener(os.Stdin) - if err != nil { - return err - } - defer l.Close() - } - if handler == nil { - handler = http.DefaultServeMux - } - for { - rw, err := l.Accept() - if err != nil { - return err - } - c := newChild(rw, handler) - go c.serve() - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/fcgi.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/fcgi.go deleted file mode 100644 index 06bba0488a..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/fcgi.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package fcgi implements the FastCGI protocol. -// Currently only the responder role is supported. -// The protocol is defined at http://www.fastcgi.com/drupal/node/6?q=node/22 -package fcgi - -// This file defines the raw protocol and some utilities used by the child and -// the host. - -import ( - "bufio" - "bytes" - "encoding/binary" - "errors" - "io" - "sync" -) - -// recType is a record type, as defined by -// http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S8 -type recType uint8 - -const ( - typeBeginRequest recType = 1 - typeAbortRequest recType = 2 - typeEndRequest recType = 3 - typeParams recType = 4 - typeStdin recType = 5 - typeStdout recType = 6 - typeStderr recType = 7 - typeData recType = 8 - typeGetValues recType = 9 - typeGetValuesResult recType = 10 - typeUnknownType recType = 11 -) - -// keep the connection between web-server and responder open after request -const flagKeepConn = 1 - -const ( - maxWrite = 65535 // maximum record body - maxPad = 255 -) - -const ( - roleResponder = iota + 1 // only Responders are implemented. - roleAuthorizer - roleFilter -) - -const ( - statusRequestComplete = iota - statusCantMultiplex - statusOverloaded - statusUnknownRole -) - -const headerLen = 8 - -type header struct { - Version uint8 - Type recType - Id uint16 - ContentLength uint16 - PaddingLength uint8 - Reserved uint8 -} - -type beginRequest struct { - role uint16 - flags uint8 - reserved [5]uint8 -} - -func (br *beginRequest) read(content []byte) error { - if len(content) != 8 { - return errors.New("fcgi: invalid begin request record") - } - br.role = binary.BigEndian.Uint16(content) - br.flags = content[2] - return nil -} - -// for padding so we don't have to allocate all the time -// not synchronized because we don't care what the contents are -var pad [maxPad]byte - -func (h *header) init(recType recType, reqId uint16, contentLength int) { - h.Version = 1 - h.Type = recType - h.Id = reqId - h.ContentLength = uint16(contentLength) - h.PaddingLength = uint8(-contentLength & 7) -} - -// conn sends records over rwc -type conn struct { - mutex sync.Mutex - rwc io.ReadWriteCloser - - // to avoid allocations - buf bytes.Buffer - h header -} - -func newConn(rwc io.ReadWriteCloser) *conn { - return &conn{rwc: rwc} -} - -func (c *conn) Close() error { - c.mutex.Lock() - defer c.mutex.Unlock() - return c.rwc.Close() -} - -type record struct { - h header - buf [maxWrite + maxPad]byte -} - -func (rec *record) read(r io.Reader) (err error) { - if err = binary.Read(r, binary.BigEndian, &rec.h); err != nil { - return err - } - if rec.h.Version != 1 { - return errors.New("fcgi: invalid header version") - } - n := int(rec.h.ContentLength) + int(rec.h.PaddingLength) - if _, err = io.ReadFull(r, rec.buf[:n]); err != nil { - return err - } - return nil -} - -func (r *record) content() []byte { - return r.buf[:r.h.ContentLength] -} - -// writeRecord writes and sends a single record. -func (c *conn) writeRecord(recType recType, reqId uint16, b []byte) error { - c.mutex.Lock() - defer c.mutex.Unlock() - c.buf.Reset() - c.h.init(recType, reqId, len(b)) - if err := binary.Write(&c.buf, binary.BigEndian, c.h); err != nil { - return err - } - if _, err := c.buf.Write(b); err != nil { - return err - } - if _, err := c.buf.Write(pad[:c.h.PaddingLength]); err != nil { - return err - } - _, err := c.rwc.Write(c.buf.Bytes()) - return err -} - -func (c *conn) writeBeginRequest(reqId uint16, role uint16, flags uint8) error { - b := [8]byte{byte(role >> 8), byte(role), flags} - return c.writeRecord(typeBeginRequest, reqId, b[:]) -} - -func (c *conn) writeEndRequest(reqId uint16, appStatus int, protocolStatus uint8) error { - b := make([]byte, 8) - binary.BigEndian.PutUint32(b, uint32(appStatus)) - b[4] = protocolStatus - return c.writeRecord(typeEndRequest, reqId, b) -} - -func (c *conn) writePairs(recType recType, reqId uint16, pairs map[string]string) error { - w := newWriter(c, recType, reqId) - b := make([]byte, 8) - for k, v := range pairs { - n := encodeSize(b, uint32(len(k))) - n += encodeSize(b[n:], uint32(len(v))) - if _, err := w.Write(b[:n]); err != nil { - return err - } - if _, err := w.WriteString(k); err != nil { - return err - } - if _, err := w.WriteString(v); err != nil { - return err - } - } - w.Close() - return nil -} - -func readSize(s []byte) (uint32, int) { - if len(s) == 0 { - return 0, 0 - } - size, n := uint32(s[0]), 1 - if size&(1<<7) != 0 { - if len(s) < 4 { - return 0, 0 - } - n = 4 - size = binary.BigEndian.Uint32(s) - size &^= 1 << 31 - } - return size, n -} - -func readString(s []byte, size uint32) string { - if size > uint32(len(s)) { - return "" - } - return string(s[:size]) -} - -func encodeSize(b []byte, size uint32) int { - if size > 127 { - size |= 1 << 31 - binary.BigEndian.PutUint32(b, size) - return 4 - } - b[0] = byte(size) - return 1 -} - -// bufWriter encapsulates bufio.Writer but also closes the underlying stream when -// Closed. -type bufWriter struct { - closer io.Closer - *bufio.Writer -} - -func (w *bufWriter) Close() error { - if err := w.Writer.Flush(); err != nil { - w.closer.Close() - return err - } - return w.closer.Close() -} - -func newWriter(c *conn, recType recType, reqId uint16) *bufWriter { - s := &streamWriter{c: c, recType: recType, reqId: reqId} - w := bufio.NewWriterSize(s, maxWrite) - return &bufWriter{s, w} -} - -// streamWriter abstracts out the separation of a stream into discrete records. -// It only writes maxWrite bytes at a time. -type streamWriter struct { - c *conn - recType recType - reqId uint16 -} - -func (w *streamWriter) Write(p []byte) (int, error) { - nn := 0 - for len(p) > 0 { - n := len(p) - if n > maxWrite { - n = maxWrite - } - if err := w.c.writeRecord(w.recType, w.reqId, p[:n]); err != nil { - return nn, err - } - nn += n - p = p[n:] - } - return nn, nil -} - -func (w *streamWriter) Close() error { - // send empty record to close the stream - return w.c.writeRecord(w.recType, w.reqId, nil) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/fcgi_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/fcgi_test.go deleted file mode 100644 index 6c7e1a9ce8..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fcgi/fcgi_test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package fcgi - -import ( - "bytes" - "errors" - "io" - "testing" -) - -var sizeTests = []struct { - size uint32 - bytes []byte -}{ - {0, []byte{0x00}}, - {127, []byte{0x7F}}, - {128, []byte{0x80, 0x00, 0x00, 0x80}}, - {1000, []byte{0x80, 0x00, 0x03, 0xE8}}, - {33554431, []byte{0x81, 0xFF, 0xFF, 0xFF}}, -} - -func TestSize(t *testing.T) { - b := make([]byte, 4) - for i, test := range sizeTests { - n := encodeSize(b, test.size) - if !bytes.Equal(b[:n], test.bytes) { - t.Errorf("%d expected %x, encoded %x", i, test.bytes, b) - } - size, n := readSize(test.bytes) - if size != test.size { - t.Errorf("%d expected %d, read %d", i, test.size, size) - } - if len(test.bytes) != n { - t.Errorf("%d did not consume all the bytes", i) - } - } -} - -var streamTests = []struct { - desc string - recType recType - reqId uint16 - content []byte - raw []byte -}{ - {"single record", typeStdout, 1, nil, - []byte{1, byte(typeStdout), 0, 1, 0, 0, 0, 0}, - }, - // this data will have to be split into two records - {"two records", typeStdin, 300, make([]byte, 66000), - bytes.Join([][]byte{ - // header for the first record - {1, byte(typeStdin), 0x01, 0x2C, 0xFF, 0xFF, 1, 0}, - make([]byte, 65536), - // header for the second - {1, byte(typeStdin), 0x01, 0x2C, 0x01, 0xD1, 7, 0}, - make([]byte, 472), - // header for the empty record - {1, byte(typeStdin), 0x01, 0x2C, 0, 0, 0, 0}, - }, - nil), - }, -} - -type nilCloser struct { - io.ReadWriter -} - -func (c *nilCloser) Close() error { return nil } - -func TestStreams(t *testing.T) { - var rec record -outer: - for _, test := range streamTests { - buf := bytes.NewBuffer(test.raw) - var content []byte - for buf.Len() > 0 { - if err := rec.read(buf); err != nil { - t.Errorf("%s: error reading record: %v", test.desc, err) - continue outer - } - content = append(content, rec.content()...) - } - if rec.h.Type != test.recType { - t.Errorf("%s: got type %d expected %d", test.desc, rec.h.Type, test.recType) - continue - } - if rec.h.Id != test.reqId { - t.Errorf("%s: got request ID %d expected %d", test.desc, rec.h.Id, test.reqId) - continue - } - if !bytes.Equal(content, test.content) { - t.Errorf("%s: read wrong content", test.desc) - continue - } - buf.Reset() - c := newConn(&nilCloser{buf}) - w := newWriter(c, test.recType, test.reqId) - if _, err := w.Write(test.content); err != nil { - t.Errorf("%s: error writing record: %v", test.desc, err) - continue - } - if err := w.Close(); err != nil { - t.Errorf("%s: error closing stream: %v", test.desc, err) - continue - } - if !bytes.Equal(buf.Bytes(), test.raw) { - t.Errorf("%s: wrote wrong content", test.desc) - } - } -} - -type writeOnlyConn struct { - buf []byte -} - -func (c *writeOnlyConn) Write(p []byte) (int, error) { - c.buf = append(c.buf, p...) - return len(p), nil -} - -func (c *writeOnlyConn) Read(p []byte) (int, error) { - return 0, errors.New("conn is write-only") -} - -func (c *writeOnlyConn) Close() error { - return nil -} - -func TestGetValues(t *testing.T) { - var rec record - rec.h.Type = typeGetValues - - wc := new(writeOnlyConn) - c := newChild(wc, nil) - err := c.handleRecord(&rec) - if err != nil { - t.Fatalf("handleRecord: %v", err) - } - - const want = "\x01\n\x00\x00\x00\x12\x06\x00" + - "\x0f\x01FCGI_MPXS_CONNS1" + - "\x00\x00\x00\x00\x00\x00\x01\n\x00\x00\x00\x00\x00\x00" - if got := string(wc.buf); got != want { - t.Errorf(" got: %q\nwant: %q\n", got, want) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/filetransport.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/filetransport.go deleted file mode 100644 index 821787e0c4..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/filetransport.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "fmt" - "io" -) - -// fileTransport implements RoundTripper for the 'file' protocol. -type fileTransport struct { - fh fileHandler -} - -// NewFileTransport returns a new RoundTripper, serving the provided -// FileSystem. The returned RoundTripper ignores the URL host in its -// incoming requests, as well as most other properties of the -// request. -// -// The typical use case for NewFileTransport is to register the "file" -// protocol with a Transport, as in: -// -// t := &http.Transport{} -// t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) -// c := &http.Client{Transport: t} -// res, err := c.Get("file:///etc/passwd") -// ... -func NewFileTransport(fs FileSystem) RoundTripper { - return fileTransport{fileHandler{fs}} -} - -func (t fileTransport) RoundTrip(req *Request) (resp *Response, err error) { - // We start ServeHTTP in a goroutine, which may take a long - // time if the file is large. The newPopulateResponseWriter - // call returns a channel which either ServeHTTP or finish() - // sends our *Response on, once the *Response itself has been - // populated (even if the body itself is still being - // written to the res.Body, a pipe) - rw, resc := newPopulateResponseWriter() - go func() { - t.fh.ServeHTTP(rw, req) - rw.finish() - }() - return <-resc, nil -} - -func newPopulateResponseWriter() (*populateResponse, <-chan *Response) { - pr, pw := io.Pipe() - rw := &populateResponse{ - ch: make(chan *Response), - pw: pw, - res: &Response{ - Proto: "HTTP/1.0", - ProtoMajor: 1, - Header: make(Header), - Close: true, - Body: pr, - }, - } - return rw, rw.ch -} - -// populateResponse is a ResponseWriter that populates the *Response -// in res, and writes its body to a pipe connected to the response -// body. Once writes begin or finish() is called, the response is sent -// on ch. -type populateResponse struct { - res *Response - ch chan *Response - wroteHeader bool - hasContent bool - sentResponse bool - pw *io.PipeWriter -} - -func (pr *populateResponse) finish() { - if !pr.wroteHeader { - pr.WriteHeader(500) - } - if !pr.sentResponse { - pr.sendResponse() - } - pr.pw.Close() -} - -func (pr *populateResponse) sendResponse() { - if pr.sentResponse { - return - } - pr.sentResponse = true - - if pr.hasContent { - pr.res.ContentLength = -1 - } - pr.ch <- pr.res -} - -func (pr *populateResponse) Header() Header { - return pr.res.Header -} - -func (pr *populateResponse) WriteHeader(code int) { - if pr.wroteHeader { - return - } - pr.wroteHeader = true - - pr.res.StatusCode = code - pr.res.Status = fmt.Sprintf("%d %s", code, StatusText(code)) -} - -func (pr *populateResponse) Write(p []byte) (n int, err error) { - if !pr.wroteHeader { - pr.WriteHeader(StatusOK) - } - pr.hasContent = true - if !pr.sentResponse { - pr.sendResponse() - } - return pr.pw.Write(p) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/filetransport_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/filetransport_test.go deleted file mode 100644 index 6f1a537e2e..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/filetransport_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -func checker(t *testing.T) func(string, error) { - return func(call string, err error) { - if err == nil { - return - } - t.Fatalf("%s: %v", call, err) - } -} - -func TestFileTransport(t *testing.T) { - check := checker(t) - - dname, err := ioutil.TempDir("", "") - check("TempDir", err) - fname := filepath.Join(dname, "foo.txt") - err = ioutil.WriteFile(fname, []byte("Bar"), 0644) - check("WriteFile", err) - defer os.Remove(dname) - defer os.Remove(fname) - - tr := &Transport{} - tr.RegisterProtocol("file", NewFileTransport(Dir(dname))) - c := &Client{Transport: tr} - - fooURLs := []string{"file:///foo.txt", "file://../foo.txt"} - for _, urlstr := range fooURLs { - res, err := c.Get(urlstr) - check("Get "+urlstr, err) - if res.StatusCode != 200 { - t.Errorf("for %s, StatusCode = %d, want 200", urlstr, res.StatusCode) - } - if res.ContentLength != -1 { - t.Errorf("for %s, ContentLength = %d, want -1", urlstr, res.ContentLength) - } - if res.Body == nil { - t.Fatalf("for %s, nil Body", urlstr) - } - slurp, err := ioutil.ReadAll(res.Body) - check("ReadAll "+urlstr, err) - if string(slurp) != "Bar" { - t.Errorf("for %s, got content %q, want %q", urlstr, string(slurp), "Bar") - } - } - - const badURL = "file://../no-exist.txt" - res, err := c.Get(badURL) - check("Get "+badURL, err) - if res.StatusCode != 404 { - t.Errorf("for %s, StatusCode = %d, want 404", badURL, res.StatusCode) - } - res.Body.Close() -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fs.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fs.go deleted file mode 100644 index 8576cf844a..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fs.go +++ /dev/null @@ -1,549 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP file system request handler - -package http - -import ( - "errors" - "fmt" - "io" - "mime" - "mime/multipart" - "net/textproto" - "net/url" - "os" - "path" - "path/filepath" - "strconv" - "strings" - "time" -) - -// A Dir implements http.FileSystem using the native file -// system restricted to a specific directory tree. -// -// An empty Dir is treated as ".". -type Dir string - -func (d Dir) Open(name string) (File, error) { - if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 || - strings.Contains(name, "\x00") { - return nil, errors.New("http: invalid character in file path") - } - dir := string(d) - if dir == "" { - dir = "." - } - f, err := os.Open(filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))) - if err != nil { - return nil, err - } - return f, nil -} - -// A FileSystem implements access to a collection of named files. -// The elements in a file path are separated by slash ('/', U+002F) -// characters, regardless of host operating system convention. -type FileSystem interface { - Open(name string) (File, error) -} - -// A File is returned by a FileSystem's Open method and can be -// served by the FileServer implementation. -// -// The methods should behave the same as those on an *os.File. -type File interface { - io.Closer - io.Reader - Readdir(count int) ([]os.FileInfo, error) - Seek(offset int64, whence int) (int64, error) - Stat() (os.FileInfo, error) -} - -func dirList(w ResponseWriter, f File) { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - fmt.Fprintf(w, "
\n")
-	for {
-		dirs, err := f.Readdir(100)
-		if err != nil || len(dirs) == 0 {
-			break
-		}
-		for _, d := range dirs {
-			name := d.Name()
-			if d.IsDir() {
-				name += "/"
-			}
-			// name may contain '?' or '#', which must be escaped to remain
-			// part of the URL path, and not indicate the start of a query
-			// string or fragment.
-			url := url.URL{Path: name}
-			fmt.Fprintf(w, "%s\n", url.String(), htmlReplacer.Replace(name))
-		}
-	}
-	fmt.Fprintf(w, "
\n") -} - -// ServeContent replies to the request using the content in the -// provided ReadSeeker. The main benefit of ServeContent over io.Copy -// is that it handles Range requests properly, sets the MIME type, and -// handles If-Modified-Since requests. -// -// If the response's Content-Type header is not set, ServeContent -// first tries to deduce the type from name's file extension and, -// if that fails, falls back to reading the first block of the content -// and passing it to DetectContentType. -// The name is otherwise unused; in particular it can be empty and is -// never sent in the response. -// -// If modtime is not the zero time, ServeContent includes it in a -// Last-Modified header in the response. If the request includes an -// If-Modified-Since header, ServeContent uses modtime to decide -// whether the content needs to be sent at all. -// -// The content's Seek method must work: ServeContent uses -// a seek to the end of the content to determine its size. -// -// If the caller has set w's ETag header, ServeContent uses it to -// handle requests using If-Range and If-None-Match. -// -// Note that *os.File implements the io.ReadSeeker interface. -func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker) { - sizeFunc := func() (int64, error) { - size, err := content.Seek(0, os.SEEK_END) - if err != nil { - return 0, errSeeker - } - _, err = content.Seek(0, os.SEEK_SET) - if err != nil { - return 0, errSeeker - } - return size, nil - } - serveContent(w, req, name, modtime, sizeFunc, content) -} - -// errSeeker is returned by ServeContent's sizeFunc when the content -// doesn't seek properly. The underlying Seeker's error text isn't -// included in the sizeFunc reply so it's not sent over HTTP to end -// users. -var errSeeker = errors.New("seeker can't seek") - -// if name is empty, filename is unknown. (used for mime type, before sniffing) -// if modtime.IsZero(), modtime is unknown. -// content must be seeked to the beginning of the file. -// The sizeFunc is called at most once. Its error, if any, is sent in the HTTP response. -func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) { - if checkLastModified(w, r, modtime) { - return - } - rangeReq, done := checkETag(w, r) - if done { - return - } - - code := StatusOK - - // If Content-Type isn't set, use the file's extension to find it, but - // if the Content-Type is unset explicitly, do not sniff the type. - ctypes, haveType := w.Header()["Content-Type"] - var ctype string - if !haveType { - ctype = mime.TypeByExtension(filepath.Ext(name)) - if ctype == "" { - // read a chunk to decide between utf-8 text and binary - var buf [sniffLen]byte - n, _ := io.ReadFull(content, buf[:]) - ctype = DetectContentType(buf[:n]) - _, err := content.Seek(0, os.SEEK_SET) // rewind to output whole file - if err != nil { - Error(w, "seeker can't seek", StatusInternalServerError) - return - } - } - w.Header().Set("Content-Type", ctype) - } else if len(ctypes) > 0 { - ctype = ctypes[0] - } - - size, err := sizeFunc() - if err != nil { - Error(w, err.Error(), StatusInternalServerError) - return - } - - // handle Content-Range header. - sendSize := size - var sendContent io.Reader = content - if size >= 0 { - ranges, err := parseRange(rangeReq, size) - if err != nil { - Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) - return - } - if sumRangesSize(ranges) > size { - // The total number of bytes in all the ranges - // is larger than the size of the file by - // itself, so this is probably an attack, or a - // dumb client. Ignore the range request. - ranges = nil - } - switch { - case len(ranges) == 1: - // RFC 2616, Section 14.16: - // "When an HTTP message includes the content of a single - // range (for example, a response to a request for a - // single range, or to a request for a set of ranges - // that overlap without any holes), this content is - // transmitted with a Content-Range header, and a - // Content-Length header showing the number of bytes - // actually transferred. - // ... - // A response to a request for a single range MUST NOT - // be sent using the multipart/byteranges media type." - ra := ranges[0] - if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil { - Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) - return - } - sendSize = ra.length - code = StatusPartialContent - w.Header().Set("Content-Range", ra.contentRange(size)) - case len(ranges) > 1: - for _, ra := range ranges { - if ra.start > size { - Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) - return - } - } - sendSize = rangesMIMESize(ranges, ctype, size) - code = StatusPartialContent - - pr, pw := io.Pipe() - mw := multipart.NewWriter(pw) - w.Header().Set("Content-Type", "multipart/byteranges; boundary="+mw.Boundary()) - sendContent = pr - defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish. - go func() { - for _, ra := range ranges { - part, err := mw.CreatePart(ra.mimeHeader(ctype, size)) - if err != nil { - pw.CloseWithError(err) - return - } - if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil { - pw.CloseWithError(err) - return - } - if _, err := io.CopyN(part, content, ra.length); err != nil { - pw.CloseWithError(err) - return - } - } - mw.Close() - pw.Close() - }() - } - - w.Header().Set("Accept-Ranges", "bytes") - if w.Header().Get("Content-Encoding") == "" { - w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10)) - } - } - - w.WriteHeader(code) - - if r.Method != "HEAD" { - io.CopyN(w, sendContent, sendSize) - } -} - -// modtime is the modification time of the resource to be served, or IsZero(). -// return value is whether this request is now complete. -func checkLastModified(w ResponseWriter, r *Request, modtime time.Time) bool { - if modtime.IsZero() { - return false - } - - // The Date-Modified header truncates sub-second precision, so - // use mtime < t+1s instead of mtime <= t to check for unmodified. - if t, err := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modtime.Before(t.Add(1*time.Second)) { - h := w.Header() - delete(h, "Content-Type") - delete(h, "Content-Length") - w.WriteHeader(StatusNotModified) - return true - } - w.Header().Set("Last-Modified", modtime.UTC().Format(TimeFormat)) - return false -} - -// checkETag implements If-None-Match and If-Range checks. -// The ETag must have been previously set in the ResponseWriter's headers. -// -// The return value is the effective request "Range" header to use and -// whether this request is now considered done. -func checkETag(w ResponseWriter, r *Request) (rangeReq string, done bool) { - etag := w.Header().get("Etag") - rangeReq = r.Header.get("Range") - - // Invalidate the range request if the entity doesn't match the one - // the client was expecting. - // "If-Range: version" means "ignore the Range: header unless version matches the - // current file." - // We only support ETag versions. - // The caller must have set the ETag on the response already. - if ir := r.Header.get("If-Range"); ir != "" && ir != etag { - // TODO(bradfitz): handle If-Range requests with Last-Modified - // times instead of ETags? I'd rather not, at least for - // now. That seems like a bug/compromise in the RFC 2616, and - // I've never heard of anybody caring about that (yet). - rangeReq = "" - } - - if inm := r.Header.get("If-None-Match"); inm != "" { - // Must know ETag. - if etag == "" { - return rangeReq, false - } - - // TODO(bradfitz): non-GET/HEAD requests require more work: - // sending a different status code on matches, and - // also can't use weak cache validators (those with a "W/ - // prefix). But most users of ServeContent will be using - // it on GET or HEAD, so only support those for now. - if r.Method != "GET" && r.Method != "HEAD" { - return rangeReq, false - } - - // TODO(bradfitz): deal with comma-separated or multiple-valued - // list of If-None-match values. For now just handle the common - // case of a single item. - if inm == etag || inm == "*" { - h := w.Header() - delete(h, "Content-Type") - delete(h, "Content-Length") - w.WriteHeader(StatusNotModified) - return "", true - } - } - return rangeReq, false -} - -// name is '/'-separated, not filepath.Separator. -func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) { - const indexPage = "/index.html" - - // redirect .../index.html to .../ - // can't use Redirect() because that would make the path absolute, - // which would be a problem running under StripPrefix - if strings.HasSuffix(r.URL.Path, indexPage) { - localRedirect(w, r, "./") - return - } - - f, err := fs.Open(name) - if err != nil { - // TODO expose actual error? - NotFound(w, r) - return - } - defer f.Close() - - d, err1 := f.Stat() - if err1 != nil { - // TODO expose actual error? - NotFound(w, r) - return - } - - if redirect { - // redirect to canonical path: / at end of directory url - // r.URL.Path always begins with / - url := r.URL.Path - if d.IsDir() { - if url[len(url)-1] != '/' { - localRedirect(w, r, path.Base(url)+"/") - return - } - } else { - if url[len(url)-1] == '/' { - localRedirect(w, r, "../"+path.Base(url)) - return - } - } - } - - // use contents of index.html for directory, if present - if d.IsDir() { - index := name + indexPage - ff, err := fs.Open(index) - if err == nil { - defer ff.Close() - dd, err := ff.Stat() - if err == nil { - name = index - d = dd - f = ff - } - } - } - - // Still a directory? (we didn't find an index.html file) - if d.IsDir() { - if checkLastModified(w, r, d.ModTime()) { - return - } - dirList(w, f) - return - } - - // serverContent will check modification time - sizeFunc := func() (int64, error) { return d.Size(), nil } - serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f) -} - -// localRedirect gives a Moved Permanently response. -// It does not convert relative paths to absolute paths like Redirect does. -func localRedirect(w ResponseWriter, r *Request, newPath string) { - if q := r.URL.RawQuery; q != "" { - newPath += "?" + q - } - w.Header().Set("Location", newPath) - w.WriteHeader(StatusMovedPermanently) -} - -// ServeFile replies to the request with the contents of the named file or directory. -func ServeFile(w ResponseWriter, r *Request, name string) { - dir, file := filepath.Split(name) - serveFile(w, r, Dir(dir), file, false) -} - -type fileHandler struct { - root FileSystem -} - -// FileServer returns a handler that serves HTTP requests -// with the contents of the file system rooted at root. -// -// To use the operating system's file system implementation, -// use http.Dir: -// -// http.Handle("/", http.FileServer(http.Dir("/tmp"))) -func FileServer(root FileSystem) Handler { - return &fileHandler{root} -} - -func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) { - upath := r.URL.Path - if !strings.HasPrefix(upath, "/") { - upath = "/" + upath - r.URL.Path = upath - } - serveFile(w, r, f.root, path.Clean(upath), true) -} - -// httpRange specifies the byte range to be sent to the client. -type httpRange struct { - start, length int64 -} - -func (r httpRange) contentRange(size int64) string { - return fmt.Sprintf("bytes %d-%d/%d", r.start, r.start+r.length-1, size) -} - -func (r httpRange) mimeHeader(contentType string, size int64) textproto.MIMEHeader { - return textproto.MIMEHeader{ - "Content-Range": {r.contentRange(size)}, - "Content-Type": {contentType}, - } -} - -// parseRange parses a Range header string as per RFC 2616. -func parseRange(s string, size int64) ([]httpRange, error) { - if s == "" { - return nil, nil // header not present - } - const b = "bytes=" - if !strings.HasPrefix(s, b) { - return nil, errors.New("invalid range") - } - var ranges []httpRange - for _, ra := range strings.Split(s[len(b):], ",") { - ra = strings.TrimSpace(ra) - if ra == "" { - continue - } - i := strings.Index(ra, "-") - if i < 0 { - return nil, errors.New("invalid range") - } - start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:]) - var r httpRange - if start == "" { - // If no start is specified, end specifies the - // range start relative to the end of the file. - i, err := strconv.ParseInt(end, 10, 64) - if err != nil { - return nil, errors.New("invalid range") - } - if i > size { - i = size - } - r.start = size - i - r.length = size - r.start - } else { - i, err := strconv.ParseInt(start, 10, 64) - if err != nil || i > size || i < 0 { - return nil, errors.New("invalid range") - } - r.start = i - if end == "" { - // If no end is specified, range extends to end of the file. - r.length = size - r.start - } else { - i, err := strconv.ParseInt(end, 10, 64) - if err != nil || r.start > i { - return nil, errors.New("invalid range") - } - if i >= size { - i = size - 1 - } - r.length = i - r.start + 1 - } - } - ranges = append(ranges, r) - } - return ranges, nil -} - -// countingWriter counts how many bytes have been written to it. -type countingWriter int64 - -func (w *countingWriter) Write(p []byte) (n int, err error) { - *w += countingWriter(len(p)) - return len(p), nil -} - -// rangesMIMESize returns the number of bytes it takes to encode the -// provided ranges as a multipart response. -func rangesMIMESize(ranges []httpRange, contentType string, contentSize int64) (encSize int64) { - var w countingWriter - mw := multipart.NewWriter(&w) - for _, ra := range ranges { - mw.CreatePart(ra.mimeHeader(contentType, contentSize)) - encSize += ra.length - } - mw.Close() - encSize += int64(w) - return -} - -func sumRangesSize(ranges []httpRange) (size int64) { - for _, ra := range ranges { - size += ra.length - } - return -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fs_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fs_test.go deleted file mode 100644 index f968565f9b..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/fs_test.go +++ /dev/null @@ -1,858 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "mime" - "mime/multipart" - "net" - . "net/http" - "net/http/httptest" - "net/url" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "regexp" - "runtime" - "strconv" - "strings" - "testing" - "time" -) - -const ( - testFile = "testdata/file" - testFileLen = 11 -) - -type wantRange struct { - start, end int64 // range [start,end) -} - -var itoa = strconv.Itoa - -var ServeFileRangeTests = []struct { - r string - code int - ranges []wantRange -}{ - {r: "", code: StatusOK}, - {r: "bytes=0-4", code: StatusPartialContent, ranges: []wantRange{{0, 5}}}, - {r: "bytes=2-", code: StatusPartialContent, ranges: []wantRange{{2, testFileLen}}}, - {r: "bytes=-5", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 5, testFileLen}}}, - {r: "bytes=3-7", code: StatusPartialContent, ranges: []wantRange{{3, 8}}}, - {r: "bytes=20-", code: StatusRequestedRangeNotSatisfiable}, - {r: "bytes=0-0,-2", code: StatusPartialContent, ranges: []wantRange{{0, 1}, {testFileLen - 2, testFileLen}}}, - {r: "bytes=0-1,5-8", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, 9}}}, - {r: "bytes=0-1,5-", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, testFileLen}}}, - {r: "bytes=5-1000", code: StatusPartialContent, ranges: []wantRange{{5, testFileLen}}}, - {r: "bytes=0-,1-,2-,3-,4-", code: StatusOK}, // ignore wasteful range request - {r: "bytes=0-" + itoa(testFileLen-2), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}}, - {r: "bytes=0-" + itoa(testFileLen-1), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}}, - {r: "bytes=0-" + itoa(testFileLen), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}}, -} - -func TestServeFile(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - ServeFile(w, r, "testdata/file") - })) - defer ts.Close() - - var err error - - file, err := ioutil.ReadFile(testFile) - if err != nil { - t.Fatal("reading file:", err) - } - - // set up the Request (re-used for all tests) - var req Request - req.Header = make(Header) - if req.URL, err = url.Parse(ts.URL); err != nil { - t.Fatal("ParseURL:", err) - } - req.Method = "GET" - - // straight GET - _, body := getBody(t, "straight get", req) - if !bytes.Equal(body, file) { - t.Fatalf("body mismatch: got %q, want %q", body, file) - } - - // Range tests -Cases: - for _, rt := range ServeFileRangeTests { - if rt.r != "" { - req.Header.Set("Range", rt.r) - } - resp, body := getBody(t, fmt.Sprintf("range test %q", rt.r), req) - if resp.StatusCode != rt.code { - t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, resp.StatusCode, rt.code) - } - if rt.code == StatusRequestedRangeNotSatisfiable { - continue - } - wantContentRange := "" - if len(rt.ranges) == 1 { - rng := rt.ranges[0] - wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen) - } - cr := resp.Header.Get("Content-Range") - if cr != wantContentRange { - t.Errorf("range=%q: Content-Range = %q, want %q", rt.r, cr, wantContentRange) - } - ct := resp.Header.Get("Content-Type") - if len(rt.ranges) == 1 { - rng := rt.ranges[0] - wantBody := file[rng.start:rng.end] - if !bytes.Equal(body, wantBody) { - t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody) - } - if strings.HasPrefix(ct, "multipart/byteranges") { - t.Errorf("range=%q content-type = %q; unexpected multipart/byteranges", rt.r, ct) - } - } - if len(rt.ranges) > 1 { - typ, params, err := mime.ParseMediaType(ct) - if err != nil { - t.Errorf("range=%q content-type = %q; %v", rt.r, ct, err) - continue - } - if typ != "multipart/byteranges" { - t.Errorf("range=%q content-type = %q; want multipart/byteranges", rt.r, typ) - continue - } - if params["boundary"] == "" { - t.Errorf("range=%q content-type = %q; lacks boundary", rt.r, ct) - continue - } - if g, w := resp.ContentLength, int64(len(body)); g != w { - t.Errorf("range=%q Content-Length = %d; want %d", rt.r, g, w) - continue - } - mr := multipart.NewReader(bytes.NewReader(body), params["boundary"]) - for ri, rng := range rt.ranges { - part, err := mr.NextPart() - if err != nil { - t.Errorf("range=%q, reading part index %d: %v", rt.r, ri, err) - continue Cases - } - wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen) - if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w { - t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w) - } - body, err := ioutil.ReadAll(part) - if err != nil { - t.Errorf("range=%q, reading part index %d body: %v", rt.r, ri, err) - continue Cases - } - wantBody := file[rng.start:rng.end] - if !bytes.Equal(body, wantBody) { - t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody) - } - } - _, err = mr.NextPart() - if err != io.EOF { - t.Errorf("range=%q; expected final error io.EOF; got %v", rt.r, err) - } - } - } -} - -var fsRedirectTestData = []struct { - original, redirect string -}{ - {"/test/index.html", "/test/"}, - {"/test/testdata", "/test/testdata/"}, - {"/test/testdata/file/", "/test/testdata/file"}, -} - -func TestFSRedirect(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(StripPrefix("/test", FileServer(Dir(".")))) - defer ts.Close() - - for _, data := range fsRedirectTestData { - res, err := Get(ts.URL + data.original) - if err != nil { - t.Fatal(err) - } - res.Body.Close() - if g, e := res.Request.URL.Path, data.redirect; g != e { - t.Errorf("redirect from %s: got %s, want %s", data.original, g, e) - } - } -} - -type testFileSystem struct { - open func(name string) (File, error) -} - -func (fs *testFileSystem) Open(name string) (File, error) { - return fs.open(name) -} - -func TestFileServerCleans(t *testing.T) { - defer afterTest(t) - ch := make(chan string, 1) - fs := FileServer(&testFileSystem{func(name string) (File, error) { - ch <- name - return nil, errors.New("file does not exist") - }}) - tests := []struct { - reqPath, openArg string - }{ - {"/foo.txt", "/foo.txt"}, - {"//foo.txt", "/foo.txt"}, - {"/../foo.txt", "/foo.txt"}, - } - req, _ := NewRequest("GET", "http://example.com", nil) - for n, test := range tests { - rec := httptest.NewRecorder() - req.URL.Path = test.reqPath - fs.ServeHTTP(rec, req) - if got := <-ch; got != test.openArg { - t.Errorf("test %d: got %q, want %q", n, got, test.openArg) - } - } -} - -func TestFileServerEscapesNames(t *testing.T) { - defer afterTest(t) - const dirListPrefix = "
\n"
-	const dirListSuffix = "\n
\n" - tests := []struct { - name, escaped string - }{ - {`simple_name`, `simple_name`}, - {`"'<>&`, `"'<>&`}, - {`?foo=bar#baz`, `?foo=bar#baz`}, - {`?foo`, `<combo>?foo`}, - } - - // We put each test file in its own directory in the fakeFS so we can look at it in isolation. - fs := make(fakeFS) - for i, test := range tests { - testFile := &fakeFileInfo{basename: test.name} - fs[fmt.Sprintf("/%d", i)] = &fakeFileInfo{ - dir: true, - modtime: time.Unix(1000000000, 0).UTC(), - ents: []*fakeFileInfo{testFile}, - } - fs[fmt.Sprintf("/%d/%s", i, test.name)] = testFile - } - - ts := httptest.NewServer(FileServer(&fs)) - defer ts.Close() - for i, test := range tests { - url := fmt.Sprintf("%s/%d", ts.URL, i) - res, err := Get(url) - if err != nil { - t.Fatalf("test %q: Get: %v", test.name, err) - } - b, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("test %q: read Body: %v", test.name, err) - } - s := string(b) - if !strings.HasPrefix(s, dirListPrefix) || !strings.HasSuffix(s, dirListSuffix) { - t.Errorf("test %q: listing dir, full output is %q, want prefix %q and suffix %q", test.name, s, dirListPrefix, dirListSuffix) - } - if trimmed := strings.TrimSuffix(strings.TrimPrefix(s, dirListPrefix), dirListSuffix); trimmed != test.escaped { - t.Errorf("test %q: listing dir, filename escaped to %q, want %q", test.name, trimmed, test.escaped) - } - res.Body.Close() - } -} - -func mustRemoveAll(dir string) { - err := os.RemoveAll(dir) - if err != nil { - panic(err) - } -} - -func TestFileServerImplicitLeadingSlash(t *testing.T) { - defer afterTest(t) - tempDir, err := ioutil.TempDir("", "") - if err != nil { - t.Fatalf("TempDir: %v", err) - } - defer mustRemoveAll(tempDir) - if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil { - t.Fatalf("WriteFile: %v", err) - } - ts := httptest.NewServer(StripPrefix("/bar/", FileServer(Dir(tempDir)))) - defer ts.Close() - get := func(suffix string) string { - res, err := Get(ts.URL + suffix) - if err != nil { - t.Fatalf("Get %s: %v", suffix, err) - } - b, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("ReadAll %s: %v", suffix, err) - } - res.Body.Close() - return string(b) - } - if s := get("/bar/"); !strings.Contains(s, ">foo.txt<") { - t.Logf("expected a directory listing with foo.txt, got %q", s) - } - if s := get("/bar/foo.txt"); s != "Hello world" { - t.Logf("expected %q, got %q", "Hello world", s) - } -} - -func TestDirJoin(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping test on windows") - } - wfi, err := os.Stat("/etc/hosts") - if err != nil { - t.Skip("skipping test; no /etc/hosts file") - } - test := func(d Dir, name string) { - f, err := d.Open(name) - if err != nil { - t.Fatalf("open of %s: %v", name, err) - } - defer f.Close() - gfi, err := f.Stat() - if err != nil { - t.Fatalf("stat of %s: %v", name, err) - } - if !os.SameFile(gfi, wfi) { - t.Errorf("%s got different file", name) - } - } - test(Dir("/etc/"), "/hosts") - test(Dir("/etc/"), "hosts") - test(Dir("/etc/"), "../../../../hosts") - test(Dir("/etc"), "/hosts") - test(Dir("/etc"), "hosts") - test(Dir("/etc"), "../../../../hosts") - - // Not really directories, but since we use this trick in - // ServeFile, test it: - test(Dir("/etc/hosts"), "") - test(Dir("/etc/hosts"), "/") - test(Dir("/etc/hosts"), "../") -} - -func TestEmptyDirOpenCWD(t *testing.T) { - test := func(d Dir) { - name := "fs_test.go" - f, err := d.Open(name) - if err != nil { - t.Fatalf("open of %s: %v", name, err) - } - defer f.Close() - } - test(Dir("")) - test(Dir(".")) - test(Dir("./")) -} - -func TestServeFileContentType(t *testing.T) { - defer afterTest(t) - const ctype = "icecream/chocolate" - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - switch r.FormValue("override") { - case "1": - w.Header().Set("Content-Type", ctype) - case "2": - // Explicitly inhibit sniffing. - w.Header()["Content-Type"] = []string{} - } - ServeFile(w, r, "testdata/file") - })) - defer ts.Close() - get := func(override string, want []string) { - resp, err := Get(ts.URL + "?override=" + override) - if err != nil { - t.Fatal(err) - } - if h := resp.Header["Content-Type"]; !reflect.DeepEqual(h, want) { - t.Errorf("Content-Type mismatch: got %v, want %v", h, want) - } - resp.Body.Close() - } - get("0", []string{"text/plain; charset=utf-8"}) - get("1", []string{ctype}) - get("2", nil) -} - -func TestServeFileMimeType(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - ServeFile(w, r, "testdata/style.css") - })) - defer ts.Close() - resp, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - resp.Body.Close() - want := "text/css; charset=utf-8" - if h := resp.Header.Get("Content-Type"); h != want { - t.Errorf("Content-Type mismatch: got %q, want %q", h, want) - } -} - -func TestServeFileFromCWD(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - ServeFile(w, r, "fs_test.go") - })) - defer ts.Close() - r, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - r.Body.Close() - if r.StatusCode != 200 { - t.Fatalf("expected 200 OK, got %s", r.Status) - } -} - -func TestServeFileWithContentEncoding(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Encoding", "foo") - ServeFile(w, r, "testdata/file") - })) - defer ts.Close() - resp, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - resp.Body.Close() - if g, e := resp.ContentLength, int64(-1); g != e { - t.Errorf("Content-Length mismatch: got %d, want %d", g, e) - } -} - -func TestServeIndexHtml(t *testing.T) { - defer afterTest(t) - const want = "index.html says hello\n" - ts := httptest.NewServer(FileServer(Dir("."))) - defer ts.Close() - - for _, path := range []string{"/testdata/", "/testdata/index.html"} { - res, err := Get(ts.URL + path) - if err != nil { - t.Fatal(err) - } - b, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal("reading Body:", err) - } - if s := string(b); s != want { - t.Errorf("for path %q got %q, want %q", path, s, want) - } - res.Body.Close() - } -} - -func TestFileServerZeroByte(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(FileServer(Dir("."))) - defer ts.Close() - - res, err := Get(ts.URL + "/..\x00") - if err != nil { - t.Fatal(err) - } - b, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal("reading Body:", err) - } - if res.StatusCode == 200 { - t.Errorf("got status 200; want an error. Body is:\n%s", string(b)) - } -} - -type fakeFileInfo struct { - dir bool - basename string - modtime time.Time - ents []*fakeFileInfo - contents string -} - -func (f *fakeFileInfo) Name() string { return f.basename } -func (f *fakeFileInfo) Sys() interface{} { return nil } -func (f *fakeFileInfo) ModTime() time.Time { return f.modtime } -func (f *fakeFileInfo) IsDir() bool { return f.dir } -func (f *fakeFileInfo) Size() int64 { return int64(len(f.contents)) } -func (f *fakeFileInfo) Mode() os.FileMode { - if f.dir { - return 0755 | os.ModeDir - } - return 0644 -} - -type fakeFile struct { - io.ReadSeeker - fi *fakeFileInfo - path string // as opened - entpos int -} - -func (f *fakeFile) Close() error { return nil } -func (f *fakeFile) Stat() (os.FileInfo, error) { return f.fi, nil } -func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) { - if !f.fi.dir { - return nil, os.ErrInvalid - } - var fis []os.FileInfo - - limit := f.entpos + count - if count <= 0 || limit > len(f.fi.ents) { - limit = len(f.fi.ents) - } - for ; f.entpos < limit; f.entpos++ { - fis = append(fis, f.fi.ents[f.entpos]) - } - - if len(fis) == 0 && count > 0 { - return fis, io.EOF - } else { - return fis, nil - } -} - -type fakeFS map[string]*fakeFileInfo - -func (fs fakeFS) Open(name string) (File, error) { - name = path.Clean(name) - f, ok := fs[name] - if !ok { - return nil, os.ErrNotExist - } - return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil -} - -func TestDirectoryIfNotModified(t *testing.T) { - defer afterTest(t) - const indexContents = "I am a fake index.html file" - fileMod := time.Unix(1000000000, 0).UTC() - fileModStr := fileMod.Format(TimeFormat) - dirMod := time.Unix(123, 0).UTC() - indexFile := &fakeFileInfo{ - basename: "index.html", - modtime: fileMod, - contents: indexContents, - } - fs := fakeFS{ - "/": &fakeFileInfo{ - dir: true, - modtime: dirMod, - ents: []*fakeFileInfo{indexFile}, - }, - "/index.html": indexFile, - } - - ts := httptest.NewServer(FileServer(fs)) - defer ts.Close() - - res, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - b, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if string(b) != indexContents { - t.Fatalf("Got body %q; want %q", b, indexContents) - } - res.Body.Close() - - lastMod := res.Header.Get("Last-Modified") - if lastMod != fileModStr { - t.Fatalf("initial Last-Modified = %q; want %q", lastMod, fileModStr) - } - - req, _ := NewRequest("GET", ts.URL, nil) - req.Header.Set("If-Modified-Since", lastMod) - - res, err = DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - if res.StatusCode != 304 { - t.Fatalf("Code after If-Modified-Since request = %v; want 304", res.StatusCode) - } - res.Body.Close() - - // Advance the index.html file's modtime, but not the directory's. - indexFile.modtime = indexFile.modtime.Add(1 * time.Hour) - - res, err = DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - if res.StatusCode != 200 { - t.Fatalf("Code after second If-Modified-Since request = %v; want 200; res is %#v", res.StatusCode, res) - } - res.Body.Close() -} - -func mustStat(t *testing.T, fileName string) os.FileInfo { - fi, err := os.Stat(fileName) - if err != nil { - t.Fatal(err) - } - return fi -} - -func TestServeContent(t *testing.T) { - defer afterTest(t) - type serveParam struct { - name string - modtime time.Time - content io.ReadSeeker - contentType string - etag string - } - servec := make(chan serveParam, 1) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - p := <-servec - if p.etag != "" { - w.Header().Set("ETag", p.etag) - } - if p.contentType != "" { - w.Header().Set("Content-Type", p.contentType) - } - ServeContent(w, r, p.name, p.modtime, p.content) - })) - defer ts.Close() - - type testCase struct { - // One of file or content must be set: - file string - content io.ReadSeeker - - modtime time.Time - serveETag string // optional - serveContentType string // optional - reqHeader map[string]string - wantLastMod string - wantContentType string - wantStatus int - } - htmlModTime := mustStat(t, "testdata/index.html").ModTime() - tests := map[string]testCase{ - "no_last_modified": { - file: "testdata/style.css", - wantContentType: "text/css; charset=utf-8", - wantStatus: 200, - }, - "with_last_modified": { - file: "testdata/index.html", - wantContentType: "text/html; charset=utf-8", - modtime: htmlModTime, - wantLastMod: htmlModTime.UTC().Format(TimeFormat), - wantStatus: 200, - }, - "not_modified_modtime": { - file: "testdata/style.css", - modtime: htmlModTime, - reqHeader: map[string]string{ - "If-Modified-Since": htmlModTime.UTC().Format(TimeFormat), - }, - wantStatus: 304, - }, - "not_modified_modtime_with_contenttype": { - file: "testdata/style.css", - serveContentType: "text/css", // explicit content type - modtime: htmlModTime, - reqHeader: map[string]string{ - "If-Modified-Since": htmlModTime.UTC().Format(TimeFormat), - }, - wantStatus: 304, - }, - "not_modified_etag": { - file: "testdata/style.css", - serveETag: `"foo"`, - reqHeader: map[string]string{ - "If-None-Match": `"foo"`, - }, - wantStatus: 304, - }, - "not_modified_etag_no_seek": { - content: panicOnSeek{nil}, // should never be called - serveETag: `"foo"`, - reqHeader: map[string]string{ - "If-None-Match": `"foo"`, - }, - wantStatus: 304, - }, - "range_good": { - file: "testdata/style.css", - serveETag: `"A"`, - reqHeader: map[string]string{ - "Range": "bytes=0-4", - }, - wantStatus: StatusPartialContent, - wantContentType: "text/css; charset=utf-8", - }, - // An If-Range resource for entity "A", but entity "B" is now current. - // The Range request should be ignored. - "range_no_match": { - file: "testdata/style.css", - serveETag: `"A"`, - reqHeader: map[string]string{ - "Range": "bytes=0-4", - "If-Range": `"B"`, - }, - wantStatus: 200, - wantContentType: "text/css; charset=utf-8", - }, - } - for testName, tt := range tests { - var content io.ReadSeeker - if tt.file != "" { - f, err := os.Open(tt.file) - if err != nil { - t.Fatalf("test %q: %v", testName, err) - } - defer f.Close() - content = f - } else { - content = tt.content - } - - servec <- serveParam{ - name: filepath.Base(tt.file), - content: content, - modtime: tt.modtime, - etag: tt.serveETag, - contentType: tt.serveContentType, - } - req, err := NewRequest("GET", ts.URL, nil) - if err != nil { - t.Fatal(err) - } - for k, v := range tt.reqHeader { - req.Header.Set(k, v) - } - res, err := DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - io.Copy(ioutil.Discard, res.Body) - res.Body.Close() - if res.StatusCode != tt.wantStatus { - t.Errorf("test %q: status = %d; want %d", testName, res.StatusCode, tt.wantStatus) - } - if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e { - t.Errorf("test %q: content-type = %q, want %q", testName, g, e) - } - if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e { - t.Errorf("test %q: last-modified = %q, want %q", testName, g, e) - } - } -} - -// verifies that sendfile is being used on Linux -func TestLinuxSendfile(t *testing.T) { - defer afterTest(t) - if runtime.GOOS != "linux" { - t.Skip("skipping; linux-only test") - } - if _, err := exec.LookPath("strace"); err != nil { - t.Skip("skipping; strace not found in path") - } - - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatal(err) - } - lnf, err := ln.(*net.TCPListener).File() - if err != nil { - t.Fatal(err) - } - defer ln.Close() - - var buf bytes.Buffer - child := exec.Command("strace", "-f", "-q", "-e", "trace=sendfile,sendfile64", os.Args[0], "-test.run=TestLinuxSendfileChild") - child.ExtraFiles = append(child.ExtraFiles, lnf) - child.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...) - child.Stdout = &buf - child.Stderr = &buf - if err := child.Start(); err != nil { - t.Skipf("skipping; failed to start straced child: %v", err) - } - - res, err := Get(fmt.Sprintf("http://%s/", ln.Addr())) - if err != nil { - t.Fatalf("http client error: %v", err) - } - _, err = io.Copy(ioutil.Discard, res.Body) - if err != nil { - t.Fatalf("client body read error: %v", err) - } - res.Body.Close() - - // Force child to exit cleanly. - Get(fmt.Sprintf("http://%s/quit", ln.Addr())) - child.Wait() - - rx := regexp.MustCompile(`sendfile(64)?\(\d+,\s*\d+,\s*NULL,\s*\d+\)\s*=\s*\d+\s*\n`) - rxResume := regexp.MustCompile(`<\.\.\. sendfile(64)? resumed> \)\s*=\s*\d+\s*\n`) - out := buf.String() - if !rx.MatchString(out) && !rxResume.MatchString(out) { - t.Errorf("no sendfile system call found in:\n%s", out) - } -} - -func getBody(t *testing.T, testName string, req Request) (*Response, []byte) { - r, err := DefaultClient.Do(&req) - if err != nil { - t.Fatalf("%s: for URL %q, send error: %v", testName, req.URL.String(), err) - } - b, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Fatalf("%s: for URL %q, reading body: %v", testName, req.URL.String(), err) - } - return r, b -} - -// TestLinuxSendfileChild isn't a real test. It's used as a helper process -// for TestLinuxSendfile. -func TestLinuxSendfileChild(*testing.T) { - if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { - return - } - defer os.Exit(0) - fd3 := os.NewFile(3, "ephemeral-port-listener") - ln, err := net.FileListener(fd3) - if err != nil { - panic(err) - } - mux := NewServeMux() - mux.Handle("/", FileServer(Dir("testdata"))) - mux.HandleFunc("/quit", func(ResponseWriter, *Request) { - os.Exit(0) - }) - s := &Server{Handler: mux} - err = s.Serve(ln) - if err != nil { - panic(err) - } -} - -type panicOnSeek struct{ io.ReadSeeker } diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/header.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/header.go deleted file mode 100644 index 153b94370f..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/header.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "io" - "net/textproto" - "sort" - "strings" - "sync" - "time" -) - -var raceEnabled = false // set by race.go - -// A Header represents the key-value pairs in an HTTP header. -type Header map[string][]string - -// Add adds the key, value pair to the header. -// It appends to any existing values associated with key. -func (h Header) Add(key, value string) { - textproto.MIMEHeader(h).Add(key, value) -} - -// Set sets the header entries associated with key to -// the single element value. It replaces any existing -// values associated with key. -func (h Header) Set(key, value string) { - textproto.MIMEHeader(h).Set(key, value) -} - -// Get gets the first value associated with the given key. -// If there are no values associated with the key, Get returns "". -// To access multiple values of a key, access the map directly -// with CanonicalHeaderKey. -func (h Header) Get(key string) string { - return textproto.MIMEHeader(h).Get(key) -} - -// get is like Get, but key must already be in CanonicalHeaderKey form. -func (h Header) get(key string) string { - if v := h[key]; len(v) > 0 { - return v[0] - } - return "" -} - -// Del deletes the values associated with key. -func (h Header) Del(key string) { - textproto.MIMEHeader(h).Del(key) -} - -// Write writes a header in wire format. -func (h Header) Write(w io.Writer) error { - return h.WriteSubset(w, nil) -} - -func (h Header) clone() Header { - h2 := make(Header, len(h)) - for k, vv := range h { - vv2 := make([]string, len(vv)) - copy(vv2, vv) - h2[k] = vv2 - } - return h2 -} - -var timeFormats = []string{ - TimeFormat, - time.RFC850, - time.ANSIC, -} - -// ParseTime parses a time header (such as the Date: header), -// trying each of the three formats allowed by HTTP/1.1: -// TimeFormat, time.RFC850, and time.ANSIC. -func ParseTime(text string) (t time.Time, err error) { - for _, layout := range timeFormats { - t, err = time.Parse(layout, text) - if err == nil { - return - } - } - return -} - -var headerNewlineToSpace = strings.NewReplacer("\n", " ", "\r", " ") - -type writeStringer interface { - WriteString(string) (int, error) -} - -// stringWriter implements WriteString on a Writer. -type stringWriter struct { - w io.Writer -} - -func (w stringWriter) WriteString(s string) (n int, err error) { - return w.w.Write([]byte(s)) -} - -type keyValues struct { - key string - values []string -} - -// A headerSorter implements sort.Interface by sorting a []keyValues -// by key. It's used as a pointer, so it can fit in a sort.Interface -// interface value without allocation. -type headerSorter struct { - kvs []keyValues -} - -func (s *headerSorter) Len() int { return len(s.kvs) } -func (s *headerSorter) Swap(i, j int) { s.kvs[i], s.kvs[j] = s.kvs[j], s.kvs[i] } -func (s *headerSorter) Less(i, j int) bool { return s.kvs[i].key < s.kvs[j].key } - -var headerSorterPool = sync.Pool{ - New: func() interface{} { return new(headerSorter) }, -} - -// sortedKeyValues returns h's keys sorted in the returned kvs -// slice. The headerSorter used to sort is also returned, for possible -// return to headerSorterCache. -func (h Header) sortedKeyValues(exclude map[string]bool) (kvs []keyValues, hs *headerSorter) { - hs = headerSorterPool.Get().(*headerSorter) - if cap(hs.kvs) < len(h) { - hs.kvs = make([]keyValues, 0, len(h)) - } - kvs = hs.kvs[:0] - for k, vv := range h { - if !exclude[k] { - kvs = append(kvs, keyValues{k, vv}) - } - } - hs.kvs = kvs - sort.Sort(hs) - return kvs, hs -} - -// WriteSubset writes a header in wire format. -// If exclude is not nil, keys where exclude[key] == true are not written. -func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error { - ws, ok := w.(writeStringer) - if !ok { - ws = stringWriter{w} - } - kvs, sorter := h.sortedKeyValues(exclude) - for _, kv := range kvs { - for _, v := range kv.values { - v = headerNewlineToSpace.Replace(v) - v = textproto.TrimString(v) - for _, s := range []string{kv.key, ": ", v, "\r\n"} { - if _, err := ws.WriteString(s); err != nil { - return err - } - } - } - } - headerSorterPool.Put(sorter) - return nil -} - -// CanonicalHeaderKey returns the canonical format of the -// header key s. The canonicalization converts the first -// letter and any letter following a hyphen to upper case; -// the rest are converted to lowercase. For example, the -// canonical key for "accept-encoding" is "Accept-Encoding". -func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) } - -// hasToken reports whether token appears with v, ASCII -// case-insensitive, with space or comma boundaries. -// token must be all lowercase. -// v may contain mixed cased. -func hasToken(v, token string) bool { - if len(token) > len(v) || token == "" { - return false - } - if v == token { - return true - } - for sp := 0; sp <= len(v)-len(token); sp++ { - // Check that first character is good. - // The token is ASCII, so checking only a single byte - // is sufficient. We skip this potential starting - // position if both the first byte and its potential - // ASCII uppercase equivalent (b|0x20) don't match. - // False positives ('^' => '~') are caught by EqualFold. - if b := v[sp]; b != token[0] && b|0x20 != token[0] { - continue - } - // Check that start pos is on a valid token boundary. - if sp > 0 && !isTokenBoundary(v[sp-1]) { - continue - } - // Check that end pos is on a valid token boundary. - if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) { - continue - } - if strings.EqualFold(v[sp:sp+len(token)], token) { - return true - } - } - return false -} - -func isTokenBoundary(b byte) bool { - return b == ' ' || b == ',' || b == '\t' -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/header_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/header_test.go deleted file mode 100644 index 9dcd591fa0..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/header_test.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bytes" - "runtime" - "testing" - "time" -) - -var headerWriteTests = []struct { - h Header - exclude map[string]bool - expected string -}{ - {Header{}, nil, ""}, - { - Header{ - "Content-Type": {"text/html; charset=UTF-8"}, - "Content-Length": {"0"}, - }, - nil, - "Content-Length: 0\r\nContent-Type: text/html; charset=UTF-8\r\n", - }, - { - Header{ - "Content-Length": {"0", "1", "2"}, - }, - nil, - "Content-Length: 0\r\nContent-Length: 1\r\nContent-Length: 2\r\n", - }, - { - Header{ - "Expires": {"-1"}, - "Content-Length": {"0"}, - "Content-Encoding": {"gzip"}, - }, - map[string]bool{"Content-Length": true}, - "Content-Encoding: gzip\r\nExpires: -1\r\n", - }, - { - Header{ - "Expires": {"-1"}, - "Content-Length": {"0", "1", "2"}, - "Content-Encoding": {"gzip"}, - }, - map[string]bool{"Content-Length": true}, - "Content-Encoding: gzip\r\nExpires: -1\r\n", - }, - { - Header{ - "Expires": {"-1"}, - "Content-Length": {"0"}, - "Content-Encoding": {"gzip"}, - }, - map[string]bool{"Content-Length": true, "Expires": true, "Content-Encoding": true}, - "", - }, - { - Header{ - "Nil": nil, - "Empty": {}, - "Blank": {""}, - "Double-Blank": {"", ""}, - }, - nil, - "Blank: \r\nDouble-Blank: \r\nDouble-Blank: \r\n", - }, - // Tests header sorting when over the insertion sort threshold side: - { - Header{ - "k1": {"1a", "1b"}, - "k2": {"2a", "2b"}, - "k3": {"3a", "3b"}, - "k4": {"4a", "4b"}, - "k5": {"5a", "5b"}, - "k6": {"6a", "6b"}, - "k7": {"7a", "7b"}, - "k8": {"8a", "8b"}, - "k9": {"9a", "9b"}, - }, - map[string]bool{"k5": true}, - "k1: 1a\r\nk1: 1b\r\nk2: 2a\r\nk2: 2b\r\nk3: 3a\r\nk3: 3b\r\n" + - "k4: 4a\r\nk4: 4b\r\nk6: 6a\r\nk6: 6b\r\n" + - "k7: 7a\r\nk7: 7b\r\nk8: 8a\r\nk8: 8b\r\nk9: 9a\r\nk9: 9b\r\n", - }, -} - -func TestHeaderWrite(t *testing.T) { - var buf bytes.Buffer - for i, test := range headerWriteTests { - test.h.WriteSubset(&buf, test.exclude) - if buf.String() != test.expected { - t.Errorf("#%d:\n got: %q\nwant: %q", i, buf.String(), test.expected) - } - buf.Reset() - } -} - -var parseTimeTests = []struct { - h Header - err bool -}{ - {Header{"Date": {""}}, true}, - {Header{"Date": {"invalid"}}, true}, - {Header{"Date": {"1994-11-06T08:49:37Z00:00"}}, true}, - {Header{"Date": {"Sun, 06 Nov 1994 08:49:37 GMT"}}, false}, - {Header{"Date": {"Sunday, 06-Nov-94 08:49:37 GMT"}}, false}, - {Header{"Date": {"Sun Nov 6 08:49:37 1994"}}, false}, -} - -func TestParseTime(t *testing.T) { - expect := time.Date(1994, 11, 6, 8, 49, 37, 0, time.UTC) - for i, test := range parseTimeTests { - d, err := ParseTime(test.h.Get("Date")) - if err != nil { - if !test.err { - t.Errorf("#%d:\n got err: %v", i, err) - } - continue - } - if test.err { - t.Errorf("#%d:\n should err", i) - continue - } - if !expect.Equal(d) { - t.Errorf("#%d:\n got: %v\nwant: %v", i, d, expect) - } - } -} - -type hasTokenTest struct { - header string - token string - want bool -} - -var hasTokenTests = []hasTokenTest{ - {"", "", false}, - {"", "foo", false}, - {"foo", "foo", true}, - {"foo ", "foo", true}, - {" foo", "foo", true}, - {" foo ", "foo", true}, - {"foo,bar", "foo", true}, - {"bar,foo", "foo", true}, - {"bar, foo", "foo", true}, - {"bar,foo, baz", "foo", true}, - {"bar, foo,baz", "foo", true}, - {"bar,foo, baz", "foo", true}, - {"bar, foo, baz", "foo", true}, - {"FOO", "foo", true}, - {"FOO ", "foo", true}, - {" FOO", "foo", true}, - {" FOO ", "foo", true}, - {"FOO,BAR", "foo", true}, - {"BAR,FOO", "foo", true}, - {"BAR, FOO", "foo", true}, - {"BAR,FOO, baz", "foo", true}, - {"BAR, FOO,BAZ", "foo", true}, - {"BAR,FOO, BAZ", "foo", true}, - {"BAR, FOO, BAZ", "foo", true}, - {"foobar", "foo", false}, - {"barfoo ", "foo", false}, -} - -func TestHasToken(t *testing.T) { - for _, tt := range hasTokenTests { - if hasToken(tt.header, tt.token) != tt.want { - t.Errorf("hasToken(%q, %q) = %v; want %v", tt.header, tt.token, !tt.want, tt.want) - } - } -} - -var testHeader = Header{ - "Content-Length": {"123"}, - "Content-Type": {"text/plain"}, - "Date": {"some date at some time Z"}, - "Server": {DefaultUserAgent}, -} - -var buf bytes.Buffer - -func BenchmarkHeaderWriteSubset(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - buf.Reset() - testHeader.WriteSubset(&buf, nil) - } -} - -func TestHeaderWriteSubsetAllocs(t *testing.T) { - if testing.Short() { - t.Skip("skipping alloc test in short mode") - } - if raceEnabled { - t.Skip("skipping test under race detector") - } - if runtime.GOMAXPROCS(0) > 1 { - t.Skip("skipping; GOMAXPROCS>1") - } - n := testing.AllocsPerRun(100, func() { - buf.Reset() - testHeader.WriteSubset(&buf, nil) - }) - if n > 0 { - t.Errorf("allocs = %g; want 0", n) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/example_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/example_test.go deleted file mode 100644 index 42a0ec953b..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/example_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httptest_test - -import ( - "fmt" - "io/ioutil" - "log" - "net/http" - "net/http/httptest" -) - -func ExampleResponseRecorder() { - handler := func(w http.ResponseWriter, r *http.Request) { - http.Error(w, "something failed", http.StatusInternalServerError) - } - - req, err := http.NewRequest("GET", "http://example.com/foo", nil) - if err != nil { - log.Fatal(err) - } - - w := httptest.NewRecorder() - handler(w, req) - - fmt.Printf("%d - %s", w.Code, w.Body.String()) - // Output: 500 - something failed -} - -func ExampleServer() { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "Hello, client") - })) - defer ts.Close() - - res, err := http.Get(ts.URL) - if err != nil { - log.Fatal(err) - } - greeting, err := ioutil.ReadAll(res.Body) - res.Body.Close() - if err != nil { - log.Fatal(err) - } - - fmt.Printf("%s", greeting) - // Output: Hello, client -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/recorder.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/recorder.go deleted file mode 100644 index 5451f54234..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/recorder.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package httptest provides utilities for HTTP testing. -package httptest - -import ( - "bytes" - "net/http" -) - -// ResponseRecorder is an implementation of http.ResponseWriter that -// records its mutations for later inspection in tests. -type ResponseRecorder struct { - Code int // the HTTP response code from WriteHeader - HeaderMap http.Header // the HTTP response headers - Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to - Flushed bool - - wroteHeader bool -} - -// NewRecorder returns an initialized ResponseRecorder. -func NewRecorder() *ResponseRecorder { - return &ResponseRecorder{ - HeaderMap: make(http.Header), - Body: new(bytes.Buffer), - Code: 200, - } -} - -// DefaultRemoteAddr is the default remote address to return in RemoteAddr if -// an explicit DefaultRemoteAddr isn't set on ResponseRecorder. -const DefaultRemoteAddr = "1.2.3.4" - -// Header returns the response headers. -func (rw *ResponseRecorder) Header() http.Header { - m := rw.HeaderMap - if m == nil { - m = make(http.Header) - rw.HeaderMap = m - } - return m -} - -// Write always succeeds and writes to rw.Body, if not nil. -func (rw *ResponseRecorder) Write(buf []byte) (int, error) { - if !rw.wroteHeader { - rw.WriteHeader(200) - } - if rw.Body != nil { - rw.Body.Write(buf) - } - return len(buf), nil -} - -// WriteHeader sets rw.Code. -func (rw *ResponseRecorder) WriteHeader(code int) { - if !rw.wroteHeader { - rw.Code = code - } - rw.wroteHeader = true -} - -// Flush sets rw.Flushed to true. -func (rw *ResponseRecorder) Flush() { - if !rw.wroteHeader { - rw.WriteHeader(200) - } - rw.Flushed = true -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/recorder_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/recorder_test.go deleted file mode 100644 index 2b563260c7..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/recorder_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httptest - -import ( - "fmt" - "net/http" - "testing" -) - -func TestRecorder(t *testing.T) { - type checkFunc func(*ResponseRecorder) error - check := func(fns ...checkFunc) []checkFunc { return fns } - - hasStatus := func(wantCode int) checkFunc { - return func(rec *ResponseRecorder) error { - if rec.Code != wantCode { - return fmt.Errorf("Status = %d; want %d", rec.Code, wantCode) - } - return nil - } - } - hasContents := func(want string) checkFunc { - return func(rec *ResponseRecorder) error { - if rec.Body.String() != want { - return fmt.Errorf("wrote = %q; want %q", rec.Body.String(), want) - } - return nil - } - } - hasFlush := func(want bool) checkFunc { - return func(rec *ResponseRecorder) error { - if rec.Flushed != want { - return fmt.Errorf("Flushed = %v; want %v", rec.Flushed, want) - } - return nil - } - } - - tests := []struct { - name string - h func(w http.ResponseWriter, r *http.Request) - checks []checkFunc - }{ - { - "200 default", - func(w http.ResponseWriter, r *http.Request) {}, - check(hasStatus(200), hasContents("")), - }, - { - "first code only", - func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(201) - w.WriteHeader(202) - w.Write([]byte("hi")) - }, - check(hasStatus(201), hasContents("hi")), - }, - { - "write sends 200", - func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("hi first")) - w.WriteHeader(201) - w.WriteHeader(202) - }, - check(hasStatus(200), hasContents("hi first"), hasFlush(false)), - }, - { - "flush", - func(w http.ResponseWriter, r *http.Request) { - w.(http.Flusher).Flush() // also sends a 200 - w.WriteHeader(201) - }, - check(hasStatus(200), hasFlush(true)), - }, - } - r, _ := http.NewRequest("GET", "http://foo.com/", nil) - for _, tt := range tests { - h := http.HandlerFunc(tt.h) - rec := NewRecorder() - h.ServeHTTP(rec, r) - for _, check := range tt.checks { - if err := check(rec); err != nil { - t.Errorf("%s: %v", tt.name, err) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/server.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/server.go deleted file mode 100644 index 7f265552f5..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/server.go +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Implementation of Server - -package httptest - -import ( - "crypto/tls" - "flag" - "fmt" - "net" - "net/http" - "os" - "sync" -) - -// A Server is an HTTP server listening on a system-chosen port on the -// local loopback interface, for use in end-to-end HTTP tests. -type Server struct { - URL string // base URL of form http://ipaddr:port with no trailing slash - Listener net.Listener - - // TLS is the optional TLS configuration, populated with a new config - // after TLS is started. If set on an unstarted server before StartTLS - // is called, existing fields are copied into the new config. - TLS *tls.Config - - // Config may be changed after calling NewUnstartedServer and - // before Start or StartTLS. - Config *http.Server - - // wg counts the number of outstanding HTTP requests on this server. - // Close blocks until all requests are finished. - wg sync.WaitGroup -} - -// historyListener keeps track of all connections that it's ever -// accepted. -type historyListener struct { - net.Listener - sync.Mutex // protects history - history []net.Conn -} - -func (hs *historyListener) Accept() (c net.Conn, err error) { - c, err = hs.Listener.Accept() - if err == nil { - hs.Lock() - hs.history = append(hs.history, c) - hs.Unlock() - } - return -} - -func newLocalListener() net.Listener { - if *serve != "" { - l, err := net.Listen("tcp", *serve) - if err != nil { - panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err)) - } - return l - } - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - if l, err = net.Listen("tcp6", "[::1]:0"); err != nil { - panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err)) - } - } - return l -} - -// When debugging a particular http server-based test, -// this flag lets you run -// go test -run=BrokenTest -httptest.serve=127.0.0.1:8000 -// to start the broken server so you can interact with it manually. -var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks") - -// NewServer starts and returns a new Server. -// The caller should call Close when finished, to shut it down. -func NewServer(handler http.Handler) *Server { - ts := NewUnstartedServer(handler) - ts.Start() - return ts -} - -// NewUnstartedServer returns a new Server but doesn't start it. -// -// After changing its configuration, the caller should call Start or -// StartTLS. -// -// The caller should call Close when finished, to shut it down. -func NewUnstartedServer(handler http.Handler) *Server { - return &Server{ - Listener: newLocalListener(), - Config: &http.Server{Handler: handler}, - } -} - -// Start starts a server from NewUnstartedServer. -func (s *Server) Start() { - if s.URL != "" { - panic("Server already started") - } - s.Listener = &historyListener{Listener: s.Listener} - s.URL = "http://" + s.Listener.Addr().String() - s.wrapHandler() - go s.Config.Serve(s.Listener) - if *serve != "" { - fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL) - select {} - } -} - -// StartTLS starts TLS on a server from NewUnstartedServer. -func (s *Server) StartTLS() { - if s.URL != "" { - panic("Server already started") - } - cert, err := tls.X509KeyPair(localhostCert, localhostKey) - if err != nil { - panic(fmt.Sprintf("httptest: NewTLSServer: %v", err)) - } - - existingConfig := s.TLS - s.TLS = new(tls.Config) - if existingConfig != nil { - *s.TLS = *existingConfig - } - if s.TLS.NextProtos == nil { - s.TLS.NextProtos = []string{"http/1.1"} - } - if len(s.TLS.Certificates) == 0 { - s.TLS.Certificates = []tls.Certificate{cert} - } - tlsListener := tls.NewListener(s.Listener, s.TLS) - - s.Listener = &historyListener{Listener: tlsListener} - s.URL = "https://" + s.Listener.Addr().String() - s.wrapHandler() - go s.Config.Serve(s.Listener) -} - -func (s *Server) wrapHandler() { - h := s.Config.Handler - if h == nil { - h = http.DefaultServeMux - } - s.Config.Handler = &waitGroupHandler{ - s: s, - h: h, - } -} - -// NewTLSServer starts and returns a new Server using TLS. -// The caller should call Close when finished, to shut it down. -func NewTLSServer(handler http.Handler) *Server { - ts := NewUnstartedServer(handler) - ts.StartTLS() - return ts -} - -// Close shuts down the server and blocks until all outstanding -// requests on this server have completed. -func (s *Server) Close() { - s.Listener.Close() - s.wg.Wait() - s.CloseClientConnections() - if t, ok := http.DefaultTransport.(*http.Transport); ok { - t.CloseIdleConnections() - } -} - -// CloseClientConnections closes any currently open HTTP connections -// to the test Server. -func (s *Server) CloseClientConnections() { - hl, ok := s.Listener.(*historyListener) - if !ok { - return - } - hl.Lock() - for _, conn := range hl.history { - conn.Close() - } - hl.Unlock() -} - -// waitGroupHandler wraps a handler, incrementing and decrementing a -// sync.WaitGroup on each request, to enable Server.Close to block -// until outstanding requests are finished. -type waitGroupHandler struct { - s *Server - h http.Handler // non-nil -} - -func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - h.s.wg.Add(1) - defer h.s.wg.Done() // a defer, in case ServeHTTP below panics - h.h.ServeHTTP(w, r) -} - -// localhostCert is a PEM-encoded TLS cert with SAN IPs -// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end -// of ASN.1 time). -// generated from src/pkg/crypto/tls: -// go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h -var localhostCert = []byte(`-----BEGIN CERTIFICATE----- -MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD -bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj -bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa -IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA -AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud -EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA -AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk -Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA== ------END CERTIFICATE-----`) - -// localhostKey is the private key for localhostCert. -var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0 -0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV -NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d -AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW -MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD -EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA -1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE= ------END RSA PRIVATE KEY-----`) diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/server_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/server_test.go deleted file mode 100644 index 501cc8a999..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httptest/server_test.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httptest - -import ( - "io/ioutil" - "net/http" - "testing" - "time" -) - -func TestServer(t *testing.T) { - ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("hello")) - })) - defer ts.Close() - res, err := http.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - got, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if string(got) != "hello" { - t.Errorf("got %q, want hello", string(got)) - } -} - -func TestIssue7264(t *testing.T) { - for i := 0; i < 1000; i++ { - func() { - inHandler := make(chan bool, 1) - ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - inHandler <- true - })) - defer ts.Close() - tr := &http.Transport{ - ResponseHeaderTimeout: time.Nanosecond, - } - defer tr.CloseIdleConnections() - c := &http.Client{Transport: tr} - res, err := c.Get(ts.URL) - <-inHandler - if err == nil { - res.Body.Close() - } - }() - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/chunked.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/chunked.go deleted file mode 100644 index 9632bfd19d..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/chunked.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// The wire protocol for HTTP's "chunked" Transfer-Encoding. - -// This code is duplicated in net/http and net/http/httputil. -// Please make any changes in both files. - -package httputil - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" -) - -const maxLineLength = 4096 // assumed <= bufio.defaultBufSize - -var ErrLineTooLong = errors.New("header line too long") - -// newChunkedReader returns a new chunkedReader that translates the data read from r -// out of HTTP "chunked" format before returning it. -// The chunkedReader returns io.EOF when the final 0-length chunk is read. -// -// newChunkedReader is not needed by normal applications. The http package -// automatically decodes chunking when reading response bodies. -func newChunkedReader(r io.Reader) io.Reader { - br, ok := r.(*bufio.Reader) - if !ok { - br = bufio.NewReader(r) - } - return &chunkedReader{r: br} -} - -type chunkedReader struct { - r *bufio.Reader - n uint64 // unread bytes in chunk - err error - buf [2]byte -} - -func (cr *chunkedReader) beginChunk() { - // chunk-size CRLF - var line []byte - line, cr.err = readLine(cr.r) - if cr.err != nil { - return - } - cr.n, cr.err = parseHexUint(line) - if cr.err != nil { - return - } - if cr.n == 0 { - cr.err = io.EOF - } -} - -func (cr *chunkedReader) chunkHeaderAvailable() bool { - n := cr.r.Buffered() - if n > 0 { - peek, _ := cr.r.Peek(n) - return bytes.IndexByte(peek, '\n') >= 0 - } - return false -} - -func (cr *chunkedReader) Read(b []uint8) (n int, err error) { - for cr.err == nil { - if cr.n == 0 { - if n > 0 && !cr.chunkHeaderAvailable() { - // We've read enough. Don't potentially block - // reading a new chunk header. - break - } - cr.beginChunk() - continue - } - if len(b) == 0 { - break - } - rbuf := b - if uint64(len(rbuf)) > cr.n { - rbuf = rbuf[:cr.n] - } - var n0 int - n0, cr.err = cr.r.Read(rbuf) - n += n0 - b = b[n0:] - cr.n -= uint64(n0) - // If we're at the end of a chunk, read the next two - // bytes to verify they are "\r\n". - if cr.n == 0 && cr.err == nil { - if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil { - if cr.buf[0] != '\r' || cr.buf[1] != '\n' { - cr.err = errors.New("malformed chunked encoding") - } - } - } - } - return n, cr.err -} - -// Read a line of bytes (up to \n) from b. -// Give up if the line exceeds maxLineLength. -// The returned bytes are a pointer into storage in -// the bufio, so they are only valid until the next bufio read. -func readLine(b *bufio.Reader) (p []byte, err error) { - if p, err = b.ReadSlice('\n'); err != nil { - // We always know when EOF is coming. - // If the caller asked for a line, there should be a line. - if err == io.EOF { - err = io.ErrUnexpectedEOF - } else if err == bufio.ErrBufferFull { - err = ErrLineTooLong - } - return nil, err - } - if len(p) >= maxLineLength { - return nil, ErrLineTooLong - } - return trimTrailingWhitespace(p), nil -} - -func trimTrailingWhitespace(b []byte) []byte { - for len(b) > 0 && isASCIISpace(b[len(b)-1]) { - b = b[:len(b)-1] - } - return b -} - -func isASCIISpace(b byte) bool { - return b == ' ' || b == '\t' || b == '\n' || b == '\r' -} - -// newChunkedWriter returns a new chunkedWriter that translates writes into HTTP -// "chunked" format before writing them to w. Closing the returned chunkedWriter -// sends the final 0-length chunk that marks the end of the stream. -// -// newChunkedWriter is not needed by normal applications. The http -// package adds chunking automatically if handlers don't set a -// Content-Length header. Using newChunkedWriter inside a handler -// would result in double chunking or chunking with a Content-Length -// length, both of which are wrong. -func newChunkedWriter(w io.Writer) io.WriteCloser { - return &chunkedWriter{w} -} - -// Writing to chunkedWriter translates to writing in HTTP chunked Transfer -// Encoding wire format to the underlying Wire chunkedWriter. -type chunkedWriter struct { - Wire io.Writer -} - -// Write the contents of data as one chunk to Wire. -// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has -// a bug since it does not check for success of io.WriteString -func (cw *chunkedWriter) Write(data []byte) (n int, err error) { - - // Don't send 0-length data. It looks like EOF for chunked encoding. - if len(data) == 0 { - return 0, nil - } - - if _, err = fmt.Fprintf(cw.Wire, "%x\r\n", len(data)); err != nil { - return 0, err - } - if n, err = cw.Wire.Write(data); err != nil { - return - } - if n != len(data) { - err = io.ErrShortWrite - return - } - _, err = io.WriteString(cw.Wire, "\r\n") - - return -} - -func (cw *chunkedWriter) Close() error { - _, err := io.WriteString(cw.Wire, "0\r\n") - return err -} - -func parseHexUint(v []byte) (n uint64, err error) { - for _, b := range v { - n <<= 4 - switch { - case '0' <= b && b <= '9': - b = b - '0' - case 'a' <= b && b <= 'f': - b = b - 'a' + 10 - case 'A' <= b && b <= 'F': - b = b - 'A' + 10 - default: - return 0, errors.New("invalid byte in chunk length") - } - n |= uint64(b) - } - return -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/chunked_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/chunked_test.go deleted file mode 100644 index a7a5774688..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/chunked_test.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code is duplicated in net/http and net/http/httputil. -// Please make any changes in both files. - -package httputil - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "strings" - "testing" -) - -func TestChunk(t *testing.T) { - var b bytes.Buffer - - w := newChunkedWriter(&b) - const chunk1 = "hello, " - const chunk2 = "world! 0123456789abcdef" - w.Write([]byte(chunk1)) - w.Write([]byte(chunk2)) - w.Close() - - if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\n0\r\n"; g != e { - t.Fatalf("chunk writer wrote %q; want %q", g, e) - } - - r := newChunkedReader(&b) - data, err := ioutil.ReadAll(r) - if err != nil { - t.Logf(`data: "%s"`, data) - t.Fatalf("ReadAll from reader: %v", err) - } - if g, e := string(data), chunk1+chunk2; g != e { - t.Errorf("chunk reader read %q; want %q", g, e) - } -} - -func TestChunkReadMultiple(t *testing.T) { - // Bunch of small chunks, all read together. - { - var b bytes.Buffer - w := newChunkedWriter(&b) - w.Write([]byte("foo")) - w.Write([]byte("bar")) - w.Close() - - r := newChunkedReader(&b) - buf := make([]byte, 10) - n, err := r.Read(buf) - if n != 6 || err != io.EOF { - t.Errorf("Read = %d, %v; want 6, EOF", n, err) - } - buf = buf[:n] - if string(buf) != "foobar" { - t.Errorf("Read = %q; want %q", buf, "foobar") - } - } - - // One big chunk followed by a little chunk, but the small bufio.Reader size - // should prevent the second chunk header from being read. - { - var b bytes.Buffer - w := newChunkedWriter(&b) - // fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes, - // the same as the bufio ReaderSize below (the minimum), so even - // though we're going to try to Read with a buffer larger enough to also - // receive "foo", the second chunk header won't be read yet. - const fillBufChunk = "0123456789a" - const shortChunk = "foo" - w.Write([]byte(fillBufChunk)) - w.Write([]byte(shortChunk)) - w.Close() - - r := newChunkedReader(bufio.NewReaderSize(&b, 16)) - buf := make([]byte, len(fillBufChunk)+len(shortChunk)) - n, err := r.Read(buf) - if n != len(fillBufChunk) || err != nil { - t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk)) - } - buf = buf[:n] - if string(buf) != fillBufChunk { - t.Errorf("Read = %q; want %q", buf, fillBufChunk) - } - - n, err = r.Read(buf) - if n != len(shortChunk) || err != io.EOF { - t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk)) - } - } - - // And test that we see an EOF chunk, even though our buffer is already full: - { - r := newChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n"))) - buf := make([]byte, 3) - n, err := r.Read(buf) - if n != 3 || err != io.EOF { - t.Errorf("Read = %d, %v; want 3, EOF", n, err) - } - if string(buf) != "foo" { - t.Errorf("buf = %q; want foo", buf) - } - } -} - -func TestChunkReaderAllocs(t *testing.T) { - if testing.Short() { - t.Skip("skipping in short mode") - } - var buf bytes.Buffer - w := newChunkedWriter(&buf) - a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc") - w.Write(a) - w.Write(b) - w.Write(c) - w.Close() - - readBuf := make([]byte, len(a)+len(b)+len(c)+1) - byter := bytes.NewReader(buf.Bytes()) - bufr := bufio.NewReader(byter) - mallocs := testing.AllocsPerRun(100, func() { - byter.Seek(0, 0) - bufr.Reset(byter) - r := newChunkedReader(bufr) - n, err := io.ReadFull(r, readBuf) - if n != len(readBuf)-1 { - t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1) - } - if err != io.ErrUnexpectedEOF { - t.Fatalf("read error = %v; want ErrUnexpectedEOF", err) - } - }) - if mallocs > 1.5 { - t.Errorf("mallocs = %v; want 1", mallocs) - } -} - -func TestParseHexUint(t *testing.T) { - for i := uint64(0); i <= 1234; i++ { - line := []byte(fmt.Sprintf("%x", i)) - got, err := parseHexUint(line) - if err != nil { - t.Fatalf("on %d: %v", i, err) - } - if got != i { - t.Errorf("for input %q = %d; want %d", line, got, i) - } - } - _, err := parseHexUint([]byte("bogus")) - if err == nil { - t.Error("expected error on bogus input") - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/dump.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/dump.go deleted file mode 100644 index 2a7a413d01..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/dump.go +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httputil - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "strings" - "time" -) - -// One of the copies, say from b to r2, could be avoided by using a more -// elaborate trick where the other copy is made during Request/Response.Write. -// This would complicate things too much, given that these functions are for -// debugging only. -func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) { - var buf bytes.Buffer - if _, err = buf.ReadFrom(b); err != nil { - return nil, nil, err - } - if err = b.Close(); err != nil { - return nil, nil, err - } - return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil -} - -// dumpConn is a net.Conn which writes to Writer and reads from Reader -type dumpConn struct { - io.Writer - io.Reader -} - -func (c *dumpConn) Close() error { return nil } -func (c *dumpConn) LocalAddr() net.Addr { return nil } -func (c *dumpConn) RemoteAddr() net.Addr { return nil } -func (c *dumpConn) SetDeadline(t time.Time) error { return nil } -func (c *dumpConn) SetReadDeadline(t time.Time) error { return nil } -func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil } - -type neverEnding byte - -func (b neverEnding) Read(p []byte) (n int, err error) { - for i := range p { - p[i] = byte(b) - } - return len(p), nil -} - -// DumpRequestOut is like DumpRequest but includes -// headers that the standard http.Transport adds, -// such as User-Agent. -func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { - save := req.Body - dummyBody := false - if !body || req.Body == nil { - req.Body = nil - if req.ContentLength != 0 { - req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength)) - dummyBody = true - } - } else { - var err error - save, req.Body, err = drainBody(req.Body) - if err != nil { - return nil, err - } - } - - // Since we're using the actual Transport code to write the request, - // switch to http so the Transport doesn't try to do an SSL - // negotiation with our dumpConn and its bytes.Buffer & pipe. - // The wire format for https and http are the same, anyway. - reqSend := req - if req.URL.Scheme == "https" { - reqSend = new(http.Request) - *reqSend = *req - reqSend.URL = new(url.URL) - *reqSend.URL = *req.URL - reqSend.URL.Scheme = "http" - } - - // Use the actual Transport code to record what we would send - // on the wire, but not using TCP. Use a Transport with a - // custom dialer that returns a fake net.Conn that waits - // for the full input (and recording it), and then responds - // with a dummy response. - var buf bytes.Buffer // records the output - pr, pw := io.Pipe() - dr := &delegateReader{c: make(chan io.Reader)} - // Wait for the request before replying with a dummy response: - go func() { - http.ReadRequest(bufio.NewReader(pr)) - dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n") - }() - - t := &http.Transport{ - Dial: func(net, addr string) (net.Conn, error) { - return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil - }, - } - defer t.CloseIdleConnections() - - _, err := t.RoundTrip(reqSend) - - req.Body = save - if err != nil { - return nil, err - } - dump := buf.Bytes() - - // If we used a dummy body above, remove it now. - // TODO: if the req.ContentLength is large, we allocate memory - // unnecessarily just to slice it off here. But this is just - // a debug function, so this is acceptable for now. We could - // discard the body earlier if this matters. - if dummyBody { - if i := bytes.Index(dump, []byte("\r\n\r\n")); i >= 0 { - dump = dump[:i+4] - } - } - return dump, nil -} - -// delegateReader is a reader that delegates to another reader, -// once it arrives on a channel. -type delegateReader struct { - c chan io.Reader - r io.Reader // nil until received from c -} - -func (r *delegateReader) Read(p []byte) (int, error) { - if r.r == nil { - r.r = <-r.c - } - return r.r.Read(p) -} - -// Return value if nonempty, def otherwise. -func valueOrDefault(value, def string) string { - if value != "" { - return value - } - return def -} - -var reqWriteExcludeHeaderDump = map[string]bool{ - "Host": true, // not in Header map anyway - "Content-Length": true, - "Transfer-Encoding": true, - "Trailer": true, -} - -// dumpAsReceived writes req to w in the form as it was received, or -// at least as accurately as possible from the information retained in -// the request. -func dumpAsReceived(req *http.Request, w io.Writer) error { - return nil -} - -// DumpRequest returns the as-received wire representation of req, -// optionally including the request body, for debugging. -// DumpRequest is semantically a no-op, but in order to -// dump the body, it reads the body data into memory and -// changes req.Body to refer to the in-memory copy. -// The documentation for http.Request.Write details which fields -// of req are used. -func DumpRequest(req *http.Request, body bool) (dump []byte, err error) { - save := req.Body - if !body || req.Body == nil { - req.Body = nil - } else { - save, req.Body, err = drainBody(req.Body) - if err != nil { - return - } - } - - var b bytes.Buffer - - fmt.Fprintf(&b, "%s %s HTTP/%d.%d\r\n", valueOrDefault(req.Method, "GET"), - req.URL.RequestURI(), req.ProtoMajor, req.ProtoMinor) - - host := req.Host - if host == "" && req.URL != nil { - host = req.URL.Host - } - if host != "" { - fmt.Fprintf(&b, "Host: %s\r\n", host) - } - - chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" - if len(req.TransferEncoding) > 0 { - fmt.Fprintf(&b, "Transfer-Encoding: %s\r\n", strings.Join(req.TransferEncoding, ",")) - } - if req.Close { - fmt.Fprintf(&b, "Connection: close\r\n") - } - - err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump) - if err != nil { - return - } - - io.WriteString(&b, "\r\n") - - if req.Body != nil { - var dest io.Writer = &b - if chunked { - dest = NewChunkedWriter(dest) - } - _, err = io.Copy(dest, req.Body) - if chunked { - dest.(io.Closer).Close() - io.WriteString(&b, "\r\n") - } - } - - req.Body = save - if err != nil { - return - } - dump = b.Bytes() - return -} - -// errNoBody is a sentinel error value used by failureToReadBody so we can detect -// that the lack of body was intentional. -var errNoBody = errors.New("sentinel error value") - -// failureToReadBody is a io.ReadCloser that just returns errNoBody on -// Read. It's swapped in when we don't actually want to consume the -// body, but need a non-nil one, and want to distinguish the error -// from reading the dummy body. -type failureToReadBody struct{} - -func (failureToReadBody) Read([]byte) (int, error) { return 0, errNoBody } -func (failureToReadBody) Close() error { return nil } - -var emptyBody = ioutil.NopCloser(strings.NewReader("")) - -// DumpResponse is like DumpRequest but dumps a response. -func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) { - var b bytes.Buffer - save := resp.Body - savecl := resp.ContentLength - - if !body { - resp.Body = failureToReadBody{} - } else if resp.Body == nil { - resp.Body = emptyBody - } else { - save, resp.Body, err = drainBody(resp.Body) - if err != nil { - return - } - } - err = resp.Write(&b) - if err == errNoBody { - err = nil - } - resp.Body = save - resp.ContentLength = savecl - if err != nil { - return nil, err - } - return b.Bytes(), nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/dump_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/dump_test.go deleted file mode 100644 index e1ffb3935a..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/dump_test.go +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httputil - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "runtime" - "strings" - "testing" -) - -type dumpTest struct { - Req http.Request - Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body - - WantDump string - WantDumpOut string - NoBody bool // if true, set DumpRequest{,Out} body to false -} - -var dumpTests = []dumpTest{ - - // HTTP/1.1 => chunked coding; body; empty trailer - { - Req: http.Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "www.google.com", - Path: "/search", - }, - ProtoMajor: 1, - ProtoMinor: 1, - TransferEncoding: []string{"chunked"}, - }, - - Body: []byte("abcdef"), - - WantDump: "GET /search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("abcdef") + chunk(""), - }, - - // Verify that DumpRequest preserves the HTTP version number, doesn't add a Host, - // and doesn't add a User-Agent. - { - Req: http.Request{ - Method: "GET", - URL: mustParseURL("/foo"), - ProtoMajor: 1, - ProtoMinor: 0, - Header: http.Header{ - "X-Foo": []string{"X-Bar"}, - }, - }, - - WantDump: "GET /foo HTTP/1.0\r\n" + - "X-Foo: X-Bar\r\n\r\n", - }, - - { - Req: *mustNewRequest("GET", "http://example.com/foo", nil), - - WantDumpOut: "GET /foo HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Accept-Encoding: gzip\r\n\r\n", - }, - - // Test that an https URL doesn't try to do an SSL negotiation - // with a bytes.Buffer and hang with all goroutines not - // runnable. - { - Req: *mustNewRequest("GET", "https://example.com/foo", nil), - - WantDumpOut: "GET /foo HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Accept-Encoding: gzip\r\n\r\n", - }, - - // Request with Body, but Dump requested without it. - { - Req: http.Request{ - Method: "POST", - URL: &url.URL{ - Scheme: "http", - Host: "post.tld", - Path: "/", - }, - ContentLength: 6, - ProtoMajor: 1, - ProtoMinor: 1, - }, - - Body: []byte("abcdef"), - - WantDumpOut: "POST / HTTP/1.1\r\n" + - "Host: post.tld\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Content-Length: 6\r\n" + - "Accept-Encoding: gzip\r\n\r\n", - - NoBody: true, - }, -} - -func TestDumpRequest(t *testing.T) { - numg0 := runtime.NumGoroutine() - for i, tt := range dumpTests { - setBody := func() { - if tt.Body == nil { - return - } - switch b := tt.Body.(type) { - case []byte: - tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b)) - case func() io.ReadCloser: - tt.Req.Body = b() - } - } - setBody() - if tt.Req.Header == nil { - tt.Req.Header = make(http.Header) - } - - if tt.WantDump != "" { - setBody() - dump, err := DumpRequest(&tt.Req, !tt.NoBody) - if err != nil { - t.Errorf("DumpRequest #%d: %s", i, err) - continue - } - if string(dump) != tt.WantDump { - t.Errorf("DumpRequest %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDump, string(dump)) - continue - } - } - - if tt.WantDumpOut != "" { - setBody() - dump, err := DumpRequestOut(&tt.Req, !tt.NoBody) - if err != nil { - t.Errorf("DumpRequestOut #%d: %s", i, err) - continue - } - if string(dump) != tt.WantDumpOut { - t.Errorf("DumpRequestOut %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDumpOut, string(dump)) - continue - } - } - } - if dg := runtime.NumGoroutine() - numg0; dg > 4 { - t.Errorf("Unexpectedly large number of new goroutines: %d new", dg) - } -} - -func chunk(s string) string { - return fmt.Sprintf("%x\r\n%s\r\n", len(s), s) -} - -func mustParseURL(s string) *url.URL { - u, err := url.Parse(s) - if err != nil { - panic(fmt.Sprintf("Error parsing URL %q: %v", s, err)) - } - return u -} - -func mustNewRequest(method, url string, body io.Reader) *http.Request { - req, err := http.NewRequest(method, url, body) - if err != nil { - panic(fmt.Sprintf("NewRequest(%q, %q, %p) err = %v", method, url, body, err)) - } - return req -} - -var dumpResTests = []struct { - res *http.Response - body bool - want string -}{ - { - res: &http.Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 50, - Header: http.Header{ - "Foo": []string{"Bar"}, - }, - Body: ioutil.NopCloser(strings.NewReader("foo")), // shouldn't be used - }, - body: false, // to verify we see 50, not empty or 3. - want: `HTTP/1.1 200 OK -Content-Length: 50 -Foo: Bar`, - }, - - { - res: &http.Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 3, - Body: ioutil.NopCloser(strings.NewReader("foo")), - }, - body: true, - want: `HTTP/1.1 200 OK -Content-Length: 3 - -foo`, - }, - - { - res: &http.Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: -1, - Body: ioutil.NopCloser(strings.NewReader("foo")), - TransferEncoding: []string{"chunked"}, - }, - body: true, - want: `HTTP/1.1 200 OK -Transfer-Encoding: chunked - -3 -foo -0`, - }, -} - -func TestDumpResponse(t *testing.T) { - for i, tt := range dumpResTests { - gotb, err := DumpResponse(tt.res, tt.body) - if err != nil { - t.Errorf("%d. DumpResponse = %v", i, err) - continue - } - got := string(gotb) - got = strings.TrimSpace(got) - got = strings.Replace(got, "\r", "", -1) - - if got != tt.want { - t.Errorf("%d.\nDumpResponse got:\n%s\n\nWant:\n%s\n", i, got, tt.want) - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/httputil.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/httputil.go deleted file mode 100644 index 74fb6c6556..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/httputil.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package httputil provides HTTP utility functions, complementing the -// more common ones in the net/http package. -package httputil - -import "io" - -// NewChunkedReader returns a new chunkedReader that translates the data read from r -// out of HTTP "chunked" format before returning it. -// The chunkedReader returns io.EOF when the final 0-length chunk is read. -// -// NewChunkedReader is not needed by normal applications. The http package -// automatically decodes chunking when reading response bodies. -func NewChunkedReader(r io.Reader) io.Reader { - return newChunkedReader(r) -} - -// NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP -// "chunked" format before writing them to w. Closing the returned chunkedWriter -// sends the final 0-length chunk that marks the end of the stream. -// -// NewChunkedWriter is not needed by normal applications. The http -// package adds chunking automatically if handlers don't set a -// Content-Length header. Using NewChunkedWriter inside a handler -// would result in double chunking or chunking with a Content-Length -// length, both of which are wrong. -func NewChunkedWriter(w io.Writer) io.WriteCloser { - return newChunkedWriter(w) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/persist.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/persist.go deleted file mode 100644 index 987bcc96ba..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/persist.go +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package httputil - -import ( - "bufio" - "errors" - "io" - "net" - "net/http" - "net/textproto" - "sync" -) - -var ( - ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"} - ErrClosed = &http.ProtocolError{ErrorString: "connection closed by user"} - ErrPipeline = &http.ProtocolError{ErrorString: "pipeline error"} -) - -// This is an API usage error - the local side is closed. -// ErrPersistEOF (above) reports that the remote side is closed. -var errClosed = errors.New("i/o operation on closed connection") - -// A ServerConn reads requests and sends responses over an underlying -// connection, until the HTTP keepalive logic commands an end. ServerConn -// also allows hijacking the underlying connection by calling Hijack -// to regain control over the connection. ServerConn supports pipe-lining, -// i.e. requests can be read out of sync (but in the same order) while the -// respective responses are sent. -// -// ServerConn is low-level and old. Applications should instead use Server -// in the net/http package. -type ServerConn struct { - lk sync.Mutex // read-write protects the following fields - c net.Conn - r *bufio.Reader - re, we error // read/write errors - lastbody io.ReadCloser - nread, nwritten int - pipereq map[*http.Request]uint - - pipe textproto.Pipeline -} - -// NewServerConn returns a new ServerConn reading and writing c. If r is not -// nil, it is the buffer to use when reading c. -// -// ServerConn is low-level and old. Applications should instead use Server -// in the net/http package. -func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn { - if r == nil { - r = bufio.NewReader(c) - } - return &ServerConn{c: c, r: r, pipereq: make(map[*http.Request]uint)} -} - -// Hijack detaches the ServerConn and returns the underlying connection as well -// as the read-side bufio which may have some left over data. Hijack may be -// called before Read has signaled the end of the keep-alive logic. The user -// should not call Hijack while Read or Write is in progress. -func (sc *ServerConn) Hijack() (c net.Conn, r *bufio.Reader) { - sc.lk.Lock() - defer sc.lk.Unlock() - c = sc.c - r = sc.r - sc.c = nil - sc.r = nil - return -} - -// Close calls Hijack and then also closes the underlying connection -func (sc *ServerConn) Close() error { - c, _ := sc.Hijack() - if c != nil { - return c.Close() - } - return nil -} - -// Read returns the next request on the wire. An ErrPersistEOF is returned if -// it is gracefully determined that there are no more requests (e.g. after the -// first request on an HTTP/1.0 connection, or after a Connection:close on a -// HTTP/1.1 connection). -func (sc *ServerConn) Read() (req *http.Request, err error) { - - // Ensure ordered execution of Reads and Writes - id := sc.pipe.Next() - sc.pipe.StartRequest(id) - defer func() { - sc.pipe.EndRequest(id) - if req == nil { - sc.pipe.StartResponse(id) - sc.pipe.EndResponse(id) - } else { - // Remember the pipeline id of this request - sc.lk.Lock() - sc.pipereq[req] = id - sc.lk.Unlock() - } - }() - - sc.lk.Lock() - if sc.we != nil { // no point receiving if write-side broken or closed - defer sc.lk.Unlock() - return nil, sc.we - } - if sc.re != nil { - defer sc.lk.Unlock() - return nil, sc.re - } - if sc.r == nil { // connection closed by user in the meantime - defer sc.lk.Unlock() - return nil, errClosed - } - r := sc.r - lastbody := sc.lastbody - sc.lastbody = nil - sc.lk.Unlock() - - // Make sure body is fully consumed, even if user does not call body.Close - if lastbody != nil { - // body.Close is assumed to be idempotent and multiple calls to - // it should return the error that its first invocation - // returned. - err = lastbody.Close() - if err != nil { - sc.lk.Lock() - defer sc.lk.Unlock() - sc.re = err - return nil, err - } - } - - req, err = http.ReadRequest(r) - sc.lk.Lock() - defer sc.lk.Unlock() - if err != nil { - if err == io.ErrUnexpectedEOF { - // A close from the opposing client is treated as a - // graceful close, even if there was some unparse-able - // data before the close. - sc.re = ErrPersistEOF - return nil, sc.re - } else { - sc.re = err - return req, err - } - } - sc.lastbody = req.Body - sc.nread++ - if req.Close { - sc.re = ErrPersistEOF - return req, sc.re - } - return req, err -} - -// Pending returns the number of unanswered requests -// that have been received on the connection. -func (sc *ServerConn) Pending() int { - sc.lk.Lock() - defer sc.lk.Unlock() - return sc.nread - sc.nwritten -} - -// Write writes resp in response to req. To close the connection gracefully, set the -// Response.Close field to true. Write should be considered operational until -// it returns an error, regardless of any errors returned on the Read side. -func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error { - - // Retrieve the pipeline ID of this request/response pair - sc.lk.Lock() - id, ok := sc.pipereq[req] - delete(sc.pipereq, req) - if !ok { - sc.lk.Unlock() - return ErrPipeline - } - sc.lk.Unlock() - - // Ensure pipeline order - sc.pipe.StartResponse(id) - defer sc.pipe.EndResponse(id) - - sc.lk.Lock() - if sc.we != nil { - defer sc.lk.Unlock() - return sc.we - } - if sc.c == nil { // connection closed by user in the meantime - defer sc.lk.Unlock() - return ErrClosed - } - c := sc.c - if sc.nread <= sc.nwritten { - defer sc.lk.Unlock() - return errors.New("persist server pipe count") - } - if resp.Close { - // After signaling a keep-alive close, any pipelined unread - // requests will be lost. It is up to the user to drain them - // before signaling. - sc.re = ErrPersistEOF - } - sc.lk.Unlock() - - err := resp.Write(c) - sc.lk.Lock() - defer sc.lk.Unlock() - if err != nil { - sc.we = err - return err - } - sc.nwritten++ - - return nil -} - -// A ClientConn sends request and receives headers over an underlying -// connection, while respecting the HTTP keepalive logic. ClientConn -// supports hijacking the connection calling Hijack to -// regain control of the underlying net.Conn and deal with it as desired. -// -// ClientConn is low-level and old. Applications should instead use -// Client or Transport in the net/http package. -type ClientConn struct { - lk sync.Mutex // read-write protects the following fields - c net.Conn - r *bufio.Reader - re, we error // read/write errors - lastbody io.ReadCloser - nread, nwritten int - pipereq map[*http.Request]uint - - pipe textproto.Pipeline - writeReq func(*http.Request, io.Writer) error -} - -// NewClientConn returns a new ClientConn reading and writing c. If r is not -// nil, it is the buffer to use when reading c. -// -// ClientConn is low-level and old. Applications should use Client or -// Transport in the net/http package. -func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn { - if r == nil { - r = bufio.NewReader(c) - } - return &ClientConn{ - c: c, - r: r, - pipereq: make(map[*http.Request]uint), - writeReq: (*http.Request).Write, - } -} - -// NewProxyClientConn works like NewClientConn but writes Requests -// using Request's WriteProxy method. -// -// New code should not use NewProxyClientConn. See Client or -// Transport in the net/http package instead. -func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn { - cc := NewClientConn(c, r) - cc.writeReq = (*http.Request).WriteProxy - return cc -} - -// Hijack detaches the ClientConn and returns the underlying connection as well -// as the read-side bufio which may have some left over data. Hijack may be -// called before the user or Read have signaled the end of the keep-alive -// logic. The user should not call Hijack while Read or Write is in progress. -func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader) { - cc.lk.Lock() - defer cc.lk.Unlock() - c = cc.c - r = cc.r - cc.c = nil - cc.r = nil - return -} - -// Close calls Hijack and then also closes the underlying connection -func (cc *ClientConn) Close() error { - c, _ := cc.Hijack() - if c != nil { - return c.Close() - } - return nil -} - -// Write writes a request. An ErrPersistEOF error is returned if the connection -// has been closed in an HTTP keepalive sense. If req.Close equals true, the -// keepalive connection is logically closed after this request and the opposing -// server is informed. An ErrUnexpectedEOF indicates the remote closed the -// underlying TCP connection, which is usually considered as graceful close. -func (cc *ClientConn) Write(req *http.Request) (err error) { - - // Ensure ordered execution of Writes - id := cc.pipe.Next() - cc.pipe.StartRequest(id) - defer func() { - cc.pipe.EndRequest(id) - if err != nil { - cc.pipe.StartResponse(id) - cc.pipe.EndResponse(id) - } else { - // Remember the pipeline id of this request - cc.lk.Lock() - cc.pipereq[req] = id - cc.lk.Unlock() - } - }() - - cc.lk.Lock() - if cc.re != nil { // no point sending if read-side closed or broken - defer cc.lk.Unlock() - return cc.re - } - if cc.we != nil { - defer cc.lk.Unlock() - return cc.we - } - if cc.c == nil { // connection closed by user in the meantime - defer cc.lk.Unlock() - return errClosed - } - c := cc.c - if req.Close { - // We write the EOF to the write-side error, because there - // still might be some pipelined reads - cc.we = ErrPersistEOF - } - cc.lk.Unlock() - - err = cc.writeReq(req, c) - cc.lk.Lock() - defer cc.lk.Unlock() - if err != nil { - cc.we = err - return err - } - cc.nwritten++ - - return nil -} - -// Pending returns the number of unanswered requests -// that have been sent on the connection. -func (cc *ClientConn) Pending() int { - cc.lk.Lock() - defer cc.lk.Unlock() - return cc.nwritten - cc.nread -} - -// Read reads the next response from the wire. A valid response might be -// returned together with an ErrPersistEOF, which means that the remote -// requested that this be the last request serviced. Read can be called -// concurrently with Write, but not with another Read. -func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error) { - // Retrieve the pipeline ID of this request/response pair - cc.lk.Lock() - id, ok := cc.pipereq[req] - delete(cc.pipereq, req) - if !ok { - cc.lk.Unlock() - return nil, ErrPipeline - } - cc.lk.Unlock() - - // Ensure pipeline order - cc.pipe.StartResponse(id) - defer cc.pipe.EndResponse(id) - - cc.lk.Lock() - if cc.re != nil { - defer cc.lk.Unlock() - return nil, cc.re - } - if cc.r == nil { // connection closed by user in the meantime - defer cc.lk.Unlock() - return nil, errClosed - } - r := cc.r - lastbody := cc.lastbody - cc.lastbody = nil - cc.lk.Unlock() - - // Make sure body is fully consumed, even if user does not call body.Close - if lastbody != nil { - // body.Close is assumed to be idempotent and multiple calls to - // it should return the error that its first invocation - // returned. - err = lastbody.Close() - if err != nil { - cc.lk.Lock() - defer cc.lk.Unlock() - cc.re = err - return nil, err - } - } - - resp, err = http.ReadResponse(r, req) - cc.lk.Lock() - defer cc.lk.Unlock() - if err != nil { - cc.re = err - return resp, err - } - cc.lastbody = resp.Body - - cc.nread++ - - if resp.Close { - cc.re = ErrPersistEOF // don't send any more requests - return resp, cc.re - } - return resp, err -} - -// Do is convenience method that writes a request and reads a response. -func (cc *ClientConn) Do(req *http.Request) (resp *http.Response, err error) { - err = cc.Write(req) - if err != nil { - return - } - return cc.Read(req) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/reverseproxy.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/reverseproxy.go deleted file mode 100644 index 48ada5f5fd..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/reverseproxy.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP reverse proxy handler - -package httputil - -import ( - "io" - "log" - "net" - "net/http" - "net/url" - "strings" - "sync" - "time" -) - -// onExitFlushLoop is a callback set by tests to detect the state of the -// flushLoop() goroutine. -var onExitFlushLoop func() - -// ReverseProxy is an HTTP Handler that takes an incoming request and -// sends it to another server, proxying the response back to the -// client. -type ReverseProxy struct { - // Director must be a function which modifies - // the request into a new request to be sent - // using Transport. Its response is then copied - // back to the original client unmodified. - Director func(*http.Request) - - // The transport used to perform proxy requests. - // If nil, http.DefaultTransport is used. - Transport http.RoundTripper - - // FlushInterval specifies the flush interval - // to flush to the client while copying the - // response body. - // If zero, no periodic flushing is done. - FlushInterval time.Duration -} - -func singleJoiningSlash(a, b string) string { - aslash := strings.HasSuffix(a, "/") - bslash := strings.HasPrefix(b, "/") - switch { - case aslash && bslash: - return a + b[1:] - case !aslash && !bslash: - return a + "/" + b - } - return a + b -} - -// NewSingleHostReverseProxy returns a new ReverseProxy that rewrites -// URLs to the scheme, host, and base path provided in target. If the -// target's path is "/base" and the incoming request was for "/dir", -// the target request will be for /base/dir. -func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { - targetQuery := target.RawQuery - director := func(req *http.Request) { - req.URL.Scheme = target.Scheme - req.URL.Host = target.Host - req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) - if targetQuery == "" || req.URL.RawQuery == "" { - req.URL.RawQuery = targetQuery + req.URL.RawQuery - } else { - req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery - } - } - return &ReverseProxy{Director: director} -} - -func copyHeader(dst, src http.Header) { - for k, vv := range src { - for _, v := range vv { - dst.Add(k, v) - } - } -} - -// Hop-by-hop headers. These are removed when sent to the backend. -// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html -var hopHeaders = []string{ - "Connection", - "Keep-Alive", - "Proxy-Authenticate", - "Proxy-Authorization", - "Te", // canonicalized version of "TE" - "Trailers", - "Transfer-Encoding", - "Upgrade", -} - -func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - transport := p.Transport - if transport == nil { - transport = http.DefaultTransport - } - - outreq := new(http.Request) - *outreq = *req // includes shallow copies of maps, but okay - - p.Director(outreq) - outreq.Proto = "HTTP/1.1" - outreq.ProtoMajor = 1 - outreq.ProtoMinor = 1 - outreq.Close = false - - // Remove hop-by-hop headers to the backend. Especially - // important is "Connection" because we want a persistent - // connection, regardless of what the client sent to us. This - // is modifying the same underlying map from req (shallow - // copied above) so we only copy it if necessary. - copiedHeaders := false - for _, h := range hopHeaders { - if outreq.Header.Get(h) != "" { - if !copiedHeaders { - outreq.Header = make(http.Header) - copyHeader(outreq.Header, req.Header) - copiedHeaders = true - } - outreq.Header.Del(h) - } - } - - if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { - // If we aren't the first proxy retain prior - // X-Forwarded-For information as a comma+space - // separated list and fold multiple headers into one. - if prior, ok := outreq.Header["X-Forwarded-For"]; ok { - clientIP = strings.Join(prior, ", ") + ", " + clientIP - } - outreq.Header.Set("X-Forwarded-For", clientIP) - } - - res, err := transport.RoundTrip(outreq) - if err != nil { - log.Printf("http: proxy error: %v", err) - rw.WriteHeader(http.StatusInternalServerError) - return - } - defer res.Body.Close() - - for _, h := range hopHeaders { - res.Header.Del(h) - } - - copyHeader(rw.Header(), res.Header) - - rw.WriteHeader(res.StatusCode) - p.copyResponse(rw, res.Body) -} - -func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader) { - if p.FlushInterval != 0 { - if wf, ok := dst.(writeFlusher); ok { - mlw := &maxLatencyWriter{ - dst: wf, - latency: p.FlushInterval, - done: make(chan bool), - } - go mlw.flushLoop() - defer mlw.stop() - dst = mlw - } - } - - io.Copy(dst, src) -} - -type writeFlusher interface { - io.Writer - http.Flusher -} - -type maxLatencyWriter struct { - dst writeFlusher - latency time.Duration - - lk sync.Mutex // protects Write + Flush - done chan bool -} - -func (m *maxLatencyWriter) Write(p []byte) (int, error) { - m.lk.Lock() - defer m.lk.Unlock() - return m.dst.Write(p) -} - -func (m *maxLatencyWriter) flushLoop() { - t := time.NewTicker(m.latency) - defer t.Stop() - for { - select { - case <-m.done: - if onExitFlushLoop != nil { - onExitFlushLoop() - } - return - case <-t.C: - m.lk.Lock() - m.dst.Flush() - m.lk.Unlock() - } - } -} - -func (m *maxLatencyWriter) stop() { m.done <- true } diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/reverseproxy_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/reverseproxy_test.go deleted file mode 100644 index e9539b44b6..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/httputil/reverseproxy_test.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Reverse proxy tests. - -package httputil - -import ( - "io/ioutil" - "net/http" - "net/http/httptest" - "net/url" - "strings" - "testing" - "time" -) - -const fakeHopHeader = "X-Fake-Hop-Header-For-Test" - -func init() { - hopHeaders = append(hopHeaders, fakeHopHeader) -} - -func TestReverseProxy(t *testing.T) { - const backendResponse = "I am the backend" - const backendStatus = 404 - backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if len(r.TransferEncoding) > 0 { - t.Errorf("backend got unexpected TransferEncoding: %v", r.TransferEncoding) - } - if r.Header.Get("X-Forwarded-For") == "" { - t.Errorf("didn't get X-Forwarded-For header") - } - if c := r.Header.Get("Connection"); c != "" { - t.Errorf("handler got Connection header value %q", c) - } - if c := r.Header.Get("Upgrade"); c != "" { - t.Errorf("handler got Upgrade header value %q", c) - } - if g, e := r.Host, "some-name"; g != e { - t.Errorf("backend got Host header %q, want %q", g, e) - } - w.Header().Set("X-Foo", "bar") - w.Header().Set("Upgrade", "foo") - w.Header().Set(fakeHopHeader, "foo") - w.Header().Add("X-Multi-Value", "foo") - w.Header().Add("X-Multi-Value", "bar") - http.SetCookie(w, &http.Cookie{Name: "flavor", Value: "chocolateChip"}) - w.WriteHeader(backendStatus) - w.Write([]byte(backendResponse)) - })) - defer backend.Close() - backendURL, err := url.Parse(backend.URL) - if err != nil { - t.Fatal(err) - } - proxyHandler := NewSingleHostReverseProxy(backendURL) - frontend := httptest.NewServer(proxyHandler) - defer frontend.Close() - - getReq, _ := http.NewRequest("GET", frontend.URL, nil) - getReq.Host = "some-name" - getReq.Header.Set("Connection", "close") - getReq.Header.Set("Upgrade", "foo") - getReq.Close = true - res, err := http.DefaultClient.Do(getReq) - if err != nil { - t.Fatalf("Get: %v", err) - } - if g, e := res.StatusCode, backendStatus; g != e { - t.Errorf("got res.StatusCode %d; expected %d", g, e) - } - if g, e := res.Header.Get("X-Foo"), "bar"; g != e { - t.Errorf("got X-Foo %q; expected %q", g, e) - } - if c := res.Header.Get(fakeHopHeader); c != "" { - t.Errorf("got %s header value %q", fakeHopHeader, c) - } - if g, e := len(res.Header["X-Multi-Value"]), 2; g != e { - t.Errorf("got %d X-Multi-Value header values; expected %d", g, e) - } - if g, e := len(res.Header["Set-Cookie"]), 1; g != e { - t.Fatalf("got %d SetCookies, want %d", g, e) - } - if cookie := res.Cookies()[0]; cookie.Name != "flavor" { - t.Errorf("unexpected cookie %q", cookie.Name) - } - bodyBytes, _ := ioutil.ReadAll(res.Body) - if g, e := string(bodyBytes), backendResponse; g != e { - t.Errorf("got body %q; expected %q", g, e) - } -} - -func TestXForwardedFor(t *testing.T) { - const prevForwardedFor = "client ip" - const backendResponse = "I am the backend" - const backendStatus = 404 - backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("X-Forwarded-For") == "" { - t.Errorf("didn't get X-Forwarded-For header") - } - if !strings.Contains(r.Header.Get("X-Forwarded-For"), prevForwardedFor) { - t.Errorf("X-Forwarded-For didn't contain prior data") - } - w.WriteHeader(backendStatus) - w.Write([]byte(backendResponse)) - })) - defer backend.Close() - backendURL, err := url.Parse(backend.URL) - if err != nil { - t.Fatal(err) - } - proxyHandler := NewSingleHostReverseProxy(backendURL) - frontend := httptest.NewServer(proxyHandler) - defer frontend.Close() - - getReq, _ := http.NewRequest("GET", frontend.URL, nil) - getReq.Host = "some-name" - getReq.Header.Set("Connection", "close") - getReq.Header.Set("X-Forwarded-For", prevForwardedFor) - getReq.Close = true - res, err := http.DefaultClient.Do(getReq) - if err != nil { - t.Fatalf("Get: %v", err) - } - if g, e := res.StatusCode, backendStatus; g != e { - t.Errorf("got res.StatusCode %d; expected %d", g, e) - } - bodyBytes, _ := ioutil.ReadAll(res.Body) - if g, e := string(bodyBytes), backendResponse; g != e { - t.Errorf("got body %q; expected %q", g, e) - } -} - -var proxyQueryTests = []struct { - baseSuffix string // suffix to add to backend URL - reqSuffix string // suffix to add to frontend's request URL - want string // what backend should see for final request URL (without ?) -}{ - {"", "", ""}, - {"?sta=tic", "?us=er", "sta=tic&us=er"}, - {"", "?us=er", "us=er"}, - {"?sta=tic", "", "sta=tic"}, -} - -func TestReverseProxyQuery(t *testing.T) { - backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("X-Got-Query", r.URL.RawQuery) - w.Write([]byte("hi")) - })) - defer backend.Close() - - for i, tt := range proxyQueryTests { - backendURL, err := url.Parse(backend.URL + tt.baseSuffix) - if err != nil { - t.Fatal(err) - } - frontend := httptest.NewServer(NewSingleHostReverseProxy(backendURL)) - req, _ := http.NewRequest("GET", frontend.URL+tt.reqSuffix, nil) - req.Close = true - res, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("%d. Get: %v", i, err) - } - if g, e := res.Header.Get("X-Got-Query"), tt.want; g != e { - t.Errorf("%d. got query %q; expected %q", i, g, e) - } - res.Body.Close() - frontend.Close() - } -} - -func TestReverseProxyFlushInterval(t *testing.T) { - const expected = "hi" - backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(expected)) - })) - defer backend.Close() - - backendURL, err := url.Parse(backend.URL) - if err != nil { - t.Fatal(err) - } - - proxyHandler := NewSingleHostReverseProxy(backendURL) - proxyHandler.FlushInterval = time.Microsecond - - done := make(chan bool) - onExitFlushLoop = func() { done <- true } - defer func() { onExitFlushLoop = nil }() - - frontend := httptest.NewServer(proxyHandler) - defer frontend.Close() - - req, _ := http.NewRequest("GET", frontend.URL, nil) - req.Close = true - res, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("Get: %v", err) - } - defer res.Body.Close() - if bodyBytes, _ := ioutil.ReadAll(res.Body); string(bodyBytes) != expected { - t.Errorf("got body %q; expected %q", bodyBytes, expected) - } - - select { - case <-done: - // OK - case <-time.After(5 * time.Second): - t.Error("maxLatencyWriter flushLoop() never exited") - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/jar.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/jar.go deleted file mode 100644 index 5c3de0dad2..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/jar.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "net/url" -) - -// A CookieJar manages storage and use of cookies in HTTP requests. -// -// Implementations of CookieJar must be safe for concurrent use by multiple -// goroutines. -// -// The net/http/cookiejar package provides a CookieJar implementation. -type CookieJar interface { - // SetCookies handles the receipt of the cookies in a reply for the - // given URL. It may or may not choose to save the cookies, depending - // on the jar's policy and implementation. - SetCookies(u *url.URL, cookies []*Cookie) - - // Cookies returns the cookies to send in a request for the given URL. - // It is up to the implementation to honor the standard cookie use - // restrictions such as in RFC 6265. - Cookies(u *url.URL) []*Cookie -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/lex.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/lex.go deleted file mode 100644 index cb33318f49..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/lex.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -// This file deals with lexical matters of HTTP - -var isTokenTable = [127]bool{ - '!': true, - '#': true, - '$': true, - '%': true, - '&': true, - '\'': true, - '*': true, - '+': true, - '-': true, - '.': true, - '0': true, - '1': true, - '2': true, - '3': true, - '4': true, - '5': true, - '6': true, - '7': true, - '8': true, - '9': true, - 'A': true, - 'B': true, - 'C': true, - 'D': true, - 'E': true, - 'F': true, - 'G': true, - 'H': true, - 'I': true, - 'J': true, - 'K': true, - 'L': true, - 'M': true, - 'N': true, - 'O': true, - 'P': true, - 'Q': true, - 'R': true, - 'S': true, - 'T': true, - 'U': true, - 'W': true, - 'V': true, - 'X': true, - 'Y': true, - 'Z': true, - '^': true, - '_': true, - '`': true, - 'a': true, - 'b': true, - 'c': true, - 'd': true, - 'e': true, - 'f': true, - 'g': true, - 'h': true, - 'i': true, - 'j': true, - 'k': true, - 'l': true, - 'm': true, - 'n': true, - 'o': true, - 'p': true, - 'q': true, - 'r': true, - 's': true, - 't': true, - 'u': true, - 'v': true, - 'w': true, - 'x': true, - 'y': true, - 'z': true, - '|': true, - '~': true, -} - -func isToken(r rune) bool { - i := int(r) - return i < len(isTokenTable) && isTokenTable[i] -} - -func isNotToken(r rune) bool { - return !isToken(r) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/lex_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/lex_test.go deleted file mode 100644 index 6d9d294f70..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/lex_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "testing" -) - -func isChar(c rune) bool { return c <= 127 } - -func isCtl(c rune) bool { return c <= 31 || c == 127 } - -func isSeparator(c rune) bool { - switch c { - case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t': - return true - } - return false -} - -func TestIsToken(t *testing.T) { - for i := 0; i <= 130; i++ { - r := rune(i) - expected := isChar(r) && !isCtl(r) && !isSeparator(r) - if isToken(r) != expected { - t.Errorf("isToken(0x%x) = %v", r, !expected) - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/npn_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/npn_test.go deleted file mode 100644 index 98b8930d06..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/npn_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "bufio" - "crypto/tls" - "fmt" - "io" - "io/ioutil" - . "net/http" - "net/http/httptest" - "strings" - "testing" -) - -func TestNextProtoUpgrade(t *testing.T) { - ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { - fmt.Fprintf(w, "path=%s,proto=", r.URL.Path) - if r.TLS != nil { - w.Write([]byte(r.TLS.NegotiatedProtocol)) - } - if r.RemoteAddr == "" { - t.Error("request with no RemoteAddr") - } - if r.Body == nil { - t.Errorf("request with nil Body") - } - })) - ts.TLS = &tls.Config{ - NextProtos: []string{"unhandled-proto", "tls-0.9"}, - } - ts.Config.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){ - "tls-0.9": handleTLSProtocol09, - } - ts.StartTLS() - defer ts.Close() - - tr := newTLSTransport(t, ts) - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - // Normal request, without NPN. - { - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if want := "path=/,proto="; string(body) != want { - t.Errorf("plain request = %q; want %q", body, want) - } - } - - // Request to an advertised but unhandled NPN protocol. - // Server will hang up. - { - tr.CloseIdleConnections() - tr.TLSClientConfig.NextProtos = []string{"unhandled-proto"} - _, err := c.Get(ts.URL) - if err == nil { - t.Errorf("expected error on unhandled-proto request") - } - } - - // Request using the "tls-0.9" protocol, which we register here. - // It is HTTP/0.9 over TLS. - { - tlsConfig := newTLSTransport(t, ts).TLSClientConfig - tlsConfig.NextProtos = []string{"tls-0.9"} - conn, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig) - if err != nil { - t.Fatal(err) - } - conn.Write([]byte("GET /foo\n")) - body, err := ioutil.ReadAll(conn) - if err != nil { - t.Fatal(err) - } - if want := "path=/foo,proto=tls-0.9"; string(body) != want { - t.Errorf("plain request = %q; want %q", body, want) - } - } -} - -// handleTLSProtocol09 implements the HTTP/0.9 protocol over TLS, for the -// TestNextProtoUpgrade test. -func handleTLSProtocol09(srv *Server, conn *tls.Conn, h Handler) { - br := bufio.NewReader(conn) - line, err := br.ReadString('\n') - if err != nil { - return - } - line = strings.TrimSpace(line) - path := strings.TrimPrefix(line, "GET ") - if path == line { - return - } - req, _ := NewRequest("GET", path, nil) - req.Proto = "HTTP/0.9" - req.ProtoMajor = 0 - req.ProtoMinor = 9 - rw := &http09Writer{conn, make(Header)} - h.ServeHTTP(rw, req) -} - -type http09Writer struct { - io.Writer - h Header -} - -func (w http09Writer) Header() Header { return w.h } -func (w http09Writer) WriteHeader(int) {} // no headers diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/pprof/pprof.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/pprof/pprof.go deleted file mode 100644 index 0c7548e3ef..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/pprof/pprof.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package pprof serves via its HTTP server runtime profiling data -// in the format expected by the pprof visualization tool. -// For more information about pprof, see -// http://code.google.com/p/google-perftools/. -// -// The package is typically only imported for the side effect of -// registering its HTTP handlers. -// The handled paths all begin with /debug/pprof/. -// -// To use pprof, link this package into your program: -// import _ "net/http/pprof" -// -// If your application is not already running an http server, you -// need to start one. Add "net/http" and "log" to your imports and -// the following code to your main function: -// -// go func() { -// log.Println(http.ListenAndServe("localhost:6060", nil)) -// }() -// -// Then use the pprof tool to look at the heap profile: -// -// go tool pprof http://localhost:6060/debug/pprof/heap -// -// Or to look at a 30-second CPU profile: -// -// go tool pprof http://localhost:6060/debug/pprof/profile -// -// Or to look at the goroutine blocking profile: -// -// go tool pprof http://localhost:6060/debug/pprof/block -// -// To view all available profiles, open http://localhost:6060/debug/pprof/ -// in your browser. -// -// For a study of the facility in action, visit -// -// http://blog.golang.org/2011/06/profiling-go-programs.html -// -package pprof - -import ( - "bufio" - "bytes" - "fmt" - "html/template" - "io" - "log" - "net/http" - "os" - "runtime" - "runtime/pprof" - "strconv" - "strings" - "time" -) - -func init() { - http.Handle("/debug/pprof/", http.HandlerFunc(Index)) - http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline)) - http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile)) - http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol)) -} - -// Cmdline responds with the running program's -// command line, with arguments separated by NUL bytes. -// The package initialization registers it as /debug/pprof/cmdline. -func Cmdline(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - fmt.Fprintf(w, strings.Join(os.Args, "\x00")) -} - -// Profile responds with the pprof-formatted cpu profile. -// The package initialization registers it as /debug/pprof/profile. -func Profile(w http.ResponseWriter, r *http.Request) { - sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64) - if sec == 0 { - sec = 30 - } - - // Set Content Type assuming StartCPUProfile will work, - // because if it does it starts writing. - w.Header().Set("Content-Type", "application/octet-stream") - if err := pprof.StartCPUProfile(w); err != nil { - // StartCPUProfile failed, so no writes yet. - // Can change header back to text content - // and send error code. - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err) - return - } - time.Sleep(time.Duration(sec) * time.Second) - pprof.StopCPUProfile() -} - -// Symbol looks up the program counters listed in the request, -// responding with a table mapping program counters to function names. -// The package initialization registers it as /debug/pprof/symbol. -func Symbol(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - - // We have to read the whole POST body before - // writing any output. Buffer the output here. - var buf bytes.Buffer - - // We don't know how many symbols we have, but we - // do have symbol information. Pprof only cares whether - // this number is 0 (no symbols available) or > 0. - fmt.Fprintf(&buf, "num_symbols: 1\n") - - var b *bufio.Reader - if r.Method == "POST" { - b = bufio.NewReader(r.Body) - } else { - b = bufio.NewReader(strings.NewReader(r.URL.RawQuery)) - } - - for { - word, err := b.ReadSlice('+') - if err == nil { - word = word[0 : len(word)-1] // trim + - } - pc, _ := strconv.ParseUint(string(word), 0, 64) - if pc != 0 { - f := runtime.FuncForPC(uintptr(pc)) - if f != nil { - fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name()) - } - } - - // Wait until here to check for err; the last - // symbol will have an err because it doesn't end in +. - if err != nil { - if err != io.EOF { - fmt.Fprintf(&buf, "reading request: %v\n", err) - } - break - } - } - - w.Write(buf.Bytes()) -} - -// Handler returns an HTTP handler that serves the named profile. -func Handler(name string) http.Handler { - return handler(name) -} - -type handler string - -func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - debug, _ := strconv.Atoi(r.FormValue("debug")) - p := pprof.Lookup(string(name)) - if p == nil { - w.WriteHeader(404) - fmt.Fprintf(w, "Unknown profile: %s\n", name) - return - } - p.WriteTo(w, debug) - return -} - -// Index responds with the pprof-formatted profile named by the request. -// For example, "/debug/pprof/heap" serves the "heap" profile. -// Index responds to a request for "/debug/pprof/" with an HTML page -// listing the available profiles. -func Index(w http.ResponseWriter, r *http.Request) { - if strings.HasPrefix(r.URL.Path, "/debug/pprof/") { - name := strings.TrimPrefix(r.URL.Path, "/debug/pprof/") - if name != "" { - handler(name).ServeHTTP(w, r) - return - } - } - - profiles := pprof.Profiles() - if err := indexTmpl.Execute(w, profiles); err != nil { - log.Print(err) - } -} - -var indexTmpl = template.Must(template.New("index").Parse(` - -/debug/pprof/ - -/debug/pprof/
-
- -profiles:
- -{{range .}} -
{{.Count}}{{.Name}} -{{end}} -
-
-full goroutine stack dump
- - -`)) diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/proxy_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/proxy_test.go deleted file mode 100644 index b6aed3792b..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/proxy_test.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "net/url" - "os" - "testing" -) - -// TODO(mattn): -// test ProxyAuth - -var UseProxyTests = []struct { - host string - match bool -}{ - // Never proxy localhost: - {"localhost:80", false}, - {"127.0.0.1", false}, - {"127.0.0.2", false}, - {"[::1]", false}, - {"[::2]", true}, // not a loopback address - - {"barbaz.net", false}, // match as .barbaz.net - {"foobar.com", false}, // have a port but match - {"foofoobar.com", true}, // not match as a part of foobar.com - {"baz.com", true}, // not match as a part of barbaz.com - {"localhost.net", true}, // not match as suffix of address - {"local.localhost", true}, // not match as prefix as address - {"barbarbaz.net", true}, // not match because NO_PROXY have a '.' - {"www.foobar.com", false}, // match because NO_PROXY includes "foobar.com" -} - -func TestUseProxy(t *testing.T) { - ResetProxyEnv() - os.Setenv("NO_PROXY", "foobar.com, .barbaz.net") - for _, test := range UseProxyTests { - if useProxy(test.host+":80") != test.match { - t.Errorf("useProxy(%v) = %v, want %v", test.host, !test.match, test.match) - } - } -} - -var cacheKeysTests = []struct { - proxy string - scheme string - addr string - key string -}{ - {"", "http", "foo.com", "|http|foo.com"}, - {"", "https", "foo.com", "|https|foo.com"}, - {"http://foo.com", "http", "foo.com", "http://foo.com|http|"}, - {"http://foo.com", "https", "foo.com", "http://foo.com|https|foo.com"}, -} - -func TestCacheKeys(t *testing.T) { - for _, tt := range cacheKeysTests { - var proxy *url.URL - if tt.proxy != "" { - u, err := url.Parse(tt.proxy) - if err != nil { - t.Fatal(err) - } - proxy = u - } - cm := connectMethod{proxy, tt.scheme, tt.addr} - if got := cm.key().String(); got != tt.key { - t.Fatalf("{%q, %q, %q} cache key = %q; want %q", tt.proxy, tt.scheme, tt.addr, got, tt.key) - } - } -} - -func ResetProxyEnv() { - for _, v := range []string{"HTTP_PROXY", "http_proxy", "NO_PROXY", "no_proxy"} { - os.Setenv(v, "") - } - ResetCachedEnvironment() -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/race.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/race.go deleted file mode 100644 index 766503967c..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/race.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build race - -package http - -func init() { - raceEnabled = true -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/range_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/range_test.go deleted file mode 100644 index ef911af7b0..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/range_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "testing" -) - -var ParseRangeTests = []struct { - s string - length int64 - r []httpRange -}{ - {"", 0, nil}, - {"", 1000, nil}, - {"foo", 0, nil}, - {"bytes=", 0, nil}, - {"bytes=7", 10, nil}, - {"bytes= 7 ", 10, nil}, - {"bytes=1-", 0, nil}, - {"bytes=5-4", 10, nil}, - {"bytes=0-2,5-4", 10, nil}, - {"bytes=2-5,4-3", 10, nil}, - {"bytes=--5,4--3", 10, nil}, - {"bytes=A-", 10, nil}, - {"bytes=A- ", 10, nil}, - {"bytes=A-Z", 10, nil}, - {"bytes= -Z", 10, nil}, - {"bytes=5-Z", 10, nil}, - {"bytes=Ran-dom, garbage", 10, nil}, - {"bytes=0x01-0x02", 10, nil}, - {"bytes= ", 10, nil}, - {"bytes= , , , ", 10, nil}, - - {"bytes=0-9", 10, []httpRange{{0, 10}}}, - {"bytes=0-", 10, []httpRange{{0, 10}}}, - {"bytes=5-", 10, []httpRange{{5, 5}}}, - {"bytes=0-20", 10, []httpRange{{0, 10}}}, - {"bytes=15-,0-5", 10, nil}, - {"bytes=1-2,5-", 10, []httpRange{{1, 2}, {5, 5}}}, - {"bytes=-2 , 7-", 11, []httpRange{{9, 2}, {7, 4}}}, - {"bytes=0-0 ,2-2, 7-", 11, []httpRange{{0, 1}, {2, 1}, {7, 4}}}, - {"bytes=-5", 10, []httpRange{{5, 5}}}, - {"bytes=-15", 10, []httpRange{{0, 10}}}, - {"bytes=0-499", 10000, []httpRange{{0, 500}}}, - {"bytes=500-999", 10000, []httpRange{{500, 500}}}, - {"bytes=-500", 10000, []httpRange{{9500, 500}}}, - {"bytes=9500-", 10000, []httpRange{{9500, 500}}}, - {"bytes=0-0,-1", 10000, []httpRange{{0, 1}, {9999, 1}}}, - {"bytes=500-600,601-999", 10000, []httpRange{{500, 101}, {601, 399}}}, - {"bytes=500-700,601-999", 10000, []httpRange{{500, 201}, {601, 399}}}, - - // Match Apache laxity: - {"bytes= 1 -2 , 4- 5, 7 - 8 , ,,", 11, []httpRange{{1, 2}, {4, 2}, {7, 2}}}, -} - -func TestParseRange(t *testing.T) { - for _, test := range ParseRangeTests { - r := test.r - ranges, err := parseRange(test.s, test.length) - if err != nil && r != nil { - t.Errorf("parseRange(%q) returned error %q", test.s, err) - } - if len(ranges) != len(r) { - t.Errorf("len(parseRange(%q)) = %d, want %d", test.s, len(ranges), len(r)) - continue - } - for i := range r { - if ranges[i].start != r[i].start { - t.Errorf("parseRange(%q)[%d].start = %d, want %d", test.s, i, ranges[i].start, r[i].start) - } - if ranges[i].length != r[i].length { - t.Errorf("parseRange(%q)[%d].length = %d, want %d", test.s, i, ranges[i].length, r[i].length) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/readrequest_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/readrequest_test.go deleted file mode 100644 index ffdd6a892d..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/readrequest_test.go +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bufio" - "bytes" - "fmt" - "io" - "net/url" - "reflect" - "testing" -) - -type reqTest struct { - Raw string - Req *Request - Body string - Trailer Header - Error string -} - -var noError = "" -var noBody = "" -var noTrailer Header = nil - -var reqTests = []reqTest{ - // Baseline test; All Request fields included for template use - { - "GET http://www.techcrunch.com/ HTTP/1.1\r\n" + - "Host: www.techcrunch.com\r\n" + - "User-Agent: Fake\r\n" + - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + - "Accept-Language: en-us,en;q=0.5\r\n" + - "Accept-Encoding: gzip,deflate\r\n" + - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + - "Keep-Alive: 300\r\n" + - "Content-Length: 7\r\n" + - "Proxy-Connection: keep-alive\r\n\r\n" + - "abcdef\n???", - - &Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "www.techcrunch.com", - Path: "/", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{ - "Accept": {"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}, - "Accept-Language": {"en-us,en;q=0.5"}, - "Accept-Encoding": {"gzip,deflate"}, - "Accept-Charset": {"ISO-8859-1,utf-8;q=0.7,*;q=0.7"}, - "Keep-Alive": {"300"}, - "Proxy-Connection": {"keep-alive"}, - "Content-Length": {"7"}, - "User-Agent": {"Fake"}, - }, - Close: false, - ContentLength: 7, - Host: "www.techcrunch.com", - RequestURI: "http://www.techcrunch.com/", - }, - - "abcdef\n", - - noTrailer, - noError, - }, - - // GET request with no body (the normal case) - { - "GET / HTTP/1.1\r\n" + - "Host: foo.com\r\n\r\n", - - &Request{ - Method: "GET", - URL: &url.URL{ - Path: "/", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: false, - ContentLength: 0, - Host: "foo.com", - RequestURI: "/", - }, - - noBody, - noTrailer, - noError, - }, - - // Tests that we don't parse a path that looks like a - // scheme-relative URI as a scheme-relative URI. - { - "GET //user@host/is/actually/a/path/ HTTP/1.1\r\n" + - "Host: test\r\n\r\n", - - &Request{ - Method: "GET", - URL: &url.URL{ - Path: "//user@host/is/actually/a/path/", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: false, - ContentLength: 0, - Host: "test", - RequestURI: "//user@host/is/actually/a/path/", - }, - - noBody, - noTrailer, - noError, - }, - - // Tests a bogus abs_path on the Request-Line (RFC 2616 section 5.1.2) - { - "GET ../../../../etc/passwd HTTP/1.1\r\n" + - "Host: test\r\n\r\n", - nil, - noBody, - noTrailer, - "parse ../../../../etc/passwd: invalid URI for request", - }, - - // Tests missing URL: - { - "GET HTTP/1.1\r\n" + - "Host: test\r\n\r\n", - nil, - noBody, - noTrailer, - "parse : empty url", - }, - - // Tests chunked body with trailer: - { - "POST / HTTP/1.1\r\n" + - "Host: foo.com\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - "3\r\nfoo\r\n" + - "3\r\nbar\r\n" + - "0\r\n" + - "Trailer-Key: Trailer-Value\r\n" + - "\r\n", - &Request{ - Method: "POST", - URL: &url.URL{ - Path: "/", - }, - TransferEncoding: []string{"chunked"}, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - ContentLength: -1, - Host: "foo.com", - RequestURI: "/", - }, - - "foobar", - Header{ - "Trailer-Key": {"Trailer-Value"}, - }, - noError, - }, - - // CONNECT request with domain name: - { - "CONNECT www.google.com:443 HTTP/1.1\r\n\r\n", - - &Request{ - Method: "CONNECT", - URL: &url.URL{ - Host: "www.google.com:443", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: false, - ContentLength: 0, - Host: "www.google.com:443", - RequestURI: "www.google.com:443", - }, - - noBody, - noTrailer, - noError, - }, - - // CONNECT request with IP address: - { - "CONNECT 127.0.0.1:6060 HTTP/1.1\r\n\r\n", - - &Request{ - Method: "CONNECT", - URL: &url.URL{ - Host: "127.0.0.1:6060", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: false, - ContentLength: 0, - Host: "127.0.0.1:6060", - RequestURI: "127.0.0.1:6060", - }, - - noBody, - noTrailer, - noError, - }, - - // CONNECT request for RPC: - { - "CONNECT /_goRPC_ HTTP/1.1\r\n\r\n", - - &Request{ - Method: "CONNECT", - URL: &url.URL{ - Path: "/_goRPC_", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: false, - ContentLength: 0, - Host: "", - RequestURI: "/_goRPC_", - }, - - noBody, - noTrailer, - noError, - }, - - // SSDP Notify request. golang.org/issue/3692 - { - "NOTIFY * HTTP/1.1\r\nServer: foo\r\n\r\n", - &Request{ - Method: "NOTIFY", - URL: &url.URL{ - Path: "*", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{ - "Server": []string{"foo"}, - }, - Close: false, - ContentLength: 0, - RequestURI: "*", - }, - - noBody, - noTrailer, - noError, - }, - - // OPTIONS request. Similar to golang.org/issue/3692 - { - "OPTIONS * HTTP/1.1\r\nServer: foo\r\n\r\n", - &Request{ - Method: "OPTIONS", - URL: &url.URL{ - Path: "*", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{ - "Server": []string{"foo"}, - }, - Close: false, - ContentLength: 0, - RequestURI: "*", - }, - - noBody, - noTrailer, - noError, - }, -} - -func TestReadRequest(t *testing.T) { - for i := range reqTests { - tt := &reqTests[i] - var braw bytes.Buffer - braw.WriteString(tt.Raw) - req, err := ReadRequest(bufio.NewReader(&braw)) - if err != nil { - if err.Error() != tt.Error { - t.Errorf("#%d: error %q, want error %q", i, err.Error(), tt.Error) - } - continue - } - rbody := req.Body - req.Body = nil - diff(t, fmt.Sprintf("#%d Request", i), req, tt.Req) - var bout bytes.Buffer - if rbody != nil { - _, err := io.Copy(&bout, rbody) - if err != nil { - t.Fatalf("#%d. copying body: %v", i, err) - } - rbody.Close() - } - body := bout.String() - if body != tt.Body { - t.Errorf("#%d: Body = %q want %q", i, body, tt.Body) - } - if !reflect.DeepEqual(tt.Trailer, req.Trailer) { - t.Errorf("#%d. Trailers differ.\n got: %v\nwant: %v", i, req.Trailer, tt.Trailer) - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/request.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/request.go deleted file mode 100644 index a67092066a..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/request.go +++ /dev/null @@ -1,875 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP Request reading and parsing. - -package http - -import ( - "bufio" - "bytes" - "crypto/tls" - "errors" - "fmt" - "io" - "io/ioutil" - "mime" - "mime/multipart" - "net/textproto" - "net/url" - "strconv" - "strings" - "sync" -) - -const ( - maxValueLength = 4096 - maxHeaderLines = 1024 - chunkSize = 4 << 10 // 4 KB chunks - defaultMaxMemory = 32 << 20 // 32 MB -) - -// ErrMissingFile is returned by FormFile when the provided file field name -// is either not present in the request or not a file field. -var ErrMissingFile = errors.New("http: no such file") - -// HTTP request parsing errors. -type ProtocolError struct { - ErrorString string -} - -func (err *ProtocolError) Error() string { return err.ErrorString } - -var ( - ErrHeaderTooLong = &ProtocolError{"header too long"} - ErrShortBody = &ProtocolError{"entity body too short"} - ErrNotSupported = &ProtocolError{"feature not supported"} - ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"} - ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"} - ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"} - ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"} -) - -type badStringError struct { - what string - str string -} - -func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) } - -// Headers that Request.Write handles itself and should be skipped. -var reqWriteExcludeHeader = map[string]bool{ - "Host": true, // not in Header map anyway - "User-Agent": true, - "Content-Length": true, - "Transfer-Encoding": true, - "Trailer": true, -} - -// A Request represents an HTTP request received by a server -// or to be sent by a client. -// -// The field semantics differ slightly between client and server -// usage. In addition to the notes on the fields below, see the -// documentation for Request.Write and RoundTripper. -type Request struct { - // Method specifies the HTTP method (GET, POST, PUT, etc.). - // For client requests an empty string means GET. - Method string - - // URL specifies either the URI being requested (for server - // requests) or the URL to access (for client requests). - // - // For server requests the URL is parsed from the URI - // supplied on the Request-Line as stored in RequestURI. For - // most requests, fields other than Path and RawQuery will be - // empty. (See RFC 2616, Section 5.1.2) - // - // For client requests, the URL's Host specifies the server to - // connect to, while the Request's Host field optionally - // specifies the Host header value to send in the HTTP - // request. - URL *url.URL - - // The protocol version for incoming requests. - // Client requests always use HTTP/1.1. - Proto string // "HTTP/1.0" - ProtoMajor int // 1 - ProtoMinor int // 0 - - // A header maps request lines to their values. - // If the header says - // - // accept-encoding: gzip, deflate - // Accept-Language: en-us - // Connection: keep-alive - // - // then - // - // Header = map[string][]string{ - // "Accept-Encoding": {"gzip, deflate"}, - // "Accept-Language": {"en-us"}, - // "Connection": {"keep-alive"}, - // } - // - // HTTP defines that header names are case-insensitive. - // The request parser implements this by canonicalizing the - // name, making the first character and any characters - // following a hyphen uppercase and the rest lowercase. - // - // For client requests certain headers are automatically - // added and may override values in Header. - // - // See the documentation for the Request.Write method. - Header Header - - // Body is the request's body. - // - // For client requests a nil body means the request has no - // body, such as a GET request. The HTTP Client's Transport - // is responsible for calling the Close method. - // - // For server requests the Request Body is always non-nil - // but will return EOF immediately when no body is present. - // The Server will close the request body. The ServeHTTP - // Handler does not need to. - Body io.ReadCloser - - // ContentLength records the length of the associated content. - // The value -1 indicates that the length is unknown. - // Values >= 0 indicate that the given number of bytes may - // be read from Body. - // For client requests, a value of 0 means unknown if Body is not nil. - ContentLength int64 - - // TransferEncoding lists the transfer encodings from outermost to - // innermost. An empty list denotes the "identity" encoding. - // TransferEncoding can usually be ignored; chunked encoding is - // automatically added and removed as necessary when sending and - // receiving requests. - TransferEncoding []string - - // Close indicates whether to close the connection after - // replying to this request (for servers) or after sending - // the request (for clients). - Close bool - - // For server requests Host specifies the host on which the - // URL is sought. Per RFC 2616, this is either the value of - // the "Host" header or the host name given in the URL itself. - // It may be of the form "host:port". - // - // For client requests Host optionally overrides the Host - // header to send. If empty, the Request.Write method uses - // the value of URL.Host. - Host string - - // Form contains the parsed form data, including both the URL - // field's query parameters and the POST or PUT form data. - // This field is only available after ParseForm is called. - // The HTTP client ignores Form and uses Body instead. - Form url.Values - - // PostForm contains the parsed form data from POST or PUT - // body parameters. - // This field is only available after ParseForm is called. - // The HTTP client ignores PostForm and uses Body instead. - PostForm url.Values - - // MultipartForm is the parsed multipart form, including file uploads. - // This field is only available after ParseMultipartForm is called. - // The HTTP client ignores MultipartForm and uses Body instead. - MultipartForm *multipart.Form - - // Trailer specifies additional headers that are sent after the request - // body. - // - // For server requests the Trailer map initially contains only the - // trailer keys, with nil values. (The client declares which trailers it - // will later send.) While the handler is reading from Body, it must - // not reference Trailer. After reading from Body returns EOF, Trailer - // can be read again and will contain non-nil values, if they were sent - // by the client. - // - // For client requests Trailer must be initialized to a map containing - // the trailer keys to later send. The values may be nil or their final - // values. The ContentLength must be 0 or -1, to send a chunked request. - // After the HTTP request is sent the map values can be updated while - // the request body is read. Once the body returns EOF, the caller must - // not mutate Trailer. - // - // Few HTTP clients, servers, or proxies support HTTP trailers. - Trailer Header - - // RemoteAddr allows HTTP servers and other software to record - // the network address that sent the request, usually for - // logging. This field is not filled in by ReadRequest and - // has no defined format. The HTTP server in this package - // sets RemoteAddr to an "IP:port" address before invoking a - // handler. - // This field is ignored by the HTTP client. - RemoteAddr string - - // RequestURI is the unmodified Request-URI of the - // Request-Line (RFC 2616, Section 5.1) as sent by the client - // to a server. Usually the URL field should be used instead. - // It is an error to set this field in an HTTP client request. - RequestURI string - - // TLS allows HTTP servers and other software to record - // information about the TLS connection on which the request - // was received. This field is not filled in by ReadRequest. - // The HTTP server in this package sets the field for - // TLS-enabled connections before invoking a handler; - // otherwise it leaves the field nil. - // This field is ignored by the HTTP client. - TLS *tls.ConnectionState -} - -// ProtoAtLeast reports whether the HTTP protocol used -// in the request is at least major.minor. -func (r *Request) ProtoAtLeast(major, minor int) bool { - return r.ProtoMajor > major || - r.ProtoMajor == major && r.ProtoMinor >= minor -} - -// UserAgent returns the client's User-Agent, if sent in the request. -func (r *Request) UserAgent() string { - return r.Header.Get("User-Agent") -} - -// Cookies parses and returns the HTTP cookies sent with the request. -func (r *Request) Cookies() []*Cookie { - return readCookies(r.Header, "") -} - -var ErrNoCookie = errors.New("http: named cookie not present") - -// Cookie returns the named cookie provided in the request or -// ErrNoCookie if not found. -func (r *Request) Cookie(name string) (*Cookie, error) { - for _, c := range readCookies(r.Header, name) { - return c, nil - } - return nil, ErrNoCookie -} - -// AddCookie adds a cookie to the request. Per RFC 6265 section 5.4, -// AddCookie does not attach more than one Cookie header field. That -// means all cookies, if any, are written into the same line, -// separated by semicolon. -func (r *Request) AddCookie(c *Cookie) { - s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value)) - if c := r.Header.Get("Cookie"); c != "" { - r.Header.Set("Cookie", c+"; "+s) - } else { - r.Header.Set("Cookie", s) - } -} - -// Referer returns the referring URL, if sent in the request. -// -// Referer is misspelled as in the request itself, a mistake from the -// earliest days of HTTP. This value can also be fetched from the -// Header map as Header["Referer"]; the benefit of making it available -// as a method is that the compiler can diagnose programs that use the -// alternate (correct English) spelling req.Referrer() but cannot -// diagnose programs that use Header["Referrer"]. -func (r *Request) Referer() string { - return r.Header.Get("Referer") -} - -// multipartByReader is a sentinel value. -// Its presence in Request.MultipartForm indicates that parsing of the request -// body has been handed off to a MultipartReader instead of ParseMultipartFrom. -var multipartByReader = &multipart.Form{ - Value: make(map[string][]string), - File: make(map[string][]*multipart.FileHeader), -} - -// MultipartReader returns a MIME multipart reader if this is a -// multipart/form-data POST request, else returns nil and an error. -// Use this function instead of ParseMultipartForm to -// process the request body as a stream. -func (r *Request) MultipartReader() (*multipart.Reader, error) { - if r.MultipartForm == multipartByReader { - return nil, errors.New("http: MultipartReader called twice") - } - if r.MultipartForm != nil { - return nil, errors.New("http: multipart handled by ParseMultipartForm") - } - r.MultipartForm = multipartByReader - return r.multipartReader() -} - -func (r *Request) multipartReader() (*multipart.Reader, error) { - v := r.Header.Get("Content-Type") - if v == "" { - return nil, ErrNotMultipart - } - d, params, err := mime.ParseMediaType(v) - if err != nil || d != "multipart/form-data" { - return nil, ErrNotMultipart - } - boundary, ok := params["boundary"] - if !ok { - return nil, ErrMissingBoundary - } - return multipart.NewReader(r.Body, boundary), nil -} - -// Return value if nonempty, def otherwise. -func valueOrDefault(value, def string) string { - if value != "" { - return value - } - return def -} - -// NOTE: This is not intended to reflect the actual Go version being used. -// It was changed from "Go http package" to "Go 1.1 package http" at the -// time of the Go 1.1 release because the former User-Agent had ended up -// on a blacklist for some intrusion detection systems. -// See https://codereview.appspot.com/7532043. -const defaultUserAgent = "Go 1.1 package http" - -// Write writes an HTTP/1.1 request -- header and body -- in wire format. -// This method consults the following fields of the request: -// Host -// URL -// Method (defaults to "GET") -// Header -// ContentLength -// TransferEncoding -// Body -// -// If Body is present, Content-Length is <= 0 and TransferEncoding -// hasn't been set to "identity", Write adds "Transfer-Encoding: -// chunked" to the header. Body is closed after it is sent. -func (r *Request) Write(w io.Writer) error { - return r.write(w, false, nil) -} - -// WriteProxy is like Write but writes the request in the form -// expected by an HTTP proxy. In particular, WriteProxy writes the -// initial Request-URI line of the request with an absolute URI, per -// section 5.1.2 of RFC 2616, including the scheme and host. -// In either case, WriteProxy also writes a Host header, using -// either r.Host or r.URL.Host. -func (r *Request) WriteProxy(w io.Writer) error { - return r.write(w, true, nil) -} - -// extraHeaders may be nil -func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header) error { - host := req.Host - if host == "" { - if req.URL == nil { - return errors.New("http: Request.Write on Request with no Host or URL set") - } - host = req.URL.Host - } - - ruri := req.URL.RequestURI() - if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" { - ruri = req.URL.Scheme + "://" + host + ruri - } else if req.Method == "CONNECT" && req.URL.Path == "" { - // CONNECT requests normally give just the host and port, not a full URL. - ruri = host - } - // TODO(bradfitz): escape at least newlines in ruri? - - // Wrap the writer in a bufio Writer if it's not already buffered. - // Don't always call NewWriter, as that forces a bytes.Buffer - // and other small bufio Writers to have a minimum 4k buffer - // size. - var bw *bufio.Writer - if _, ok := w.(io.ByteWriter); !ok { - bw = bufio.NewWriter(w) - w = bw - } - - fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri) - - // Header lines - fmt.Fprintf(w, "Host: %s\r\n", host) - - // Use the defaultUserAgent unless the Header contains one, which - // may be blank to not send the header. - userAgent := defaultUserAgent - if req.Header != nil { - if ua := req.Header["User-Agent"]; len(ua) > 0 { - userAgent = ua[0] - } - } - if userAgent != "" { - fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent) - } - - // Process Body,ContentLength,Close,Trailer - tw, err := newTransferWriter(req) - if err != nil { - return err - } - err = tw.WriteHeader(w) - if err != nil { - return err - } - - err = req.Header.WriteSubset(w, reqWriteExcludeHeader) - if err != nil { - return err - } - - if extraHeaders != nil { - err = extraHeaders.Write(w) - if err != nil { - return err - } - } - - io.WriteString(w, "\r\n") - - // Write body and trailer - err = tw.WriteBody(w) - if err != nil { - return err - } - - if bw != nil { - return bw.Flush() - } - return nil -} - -// ParseHTTPVersion parses a HTTP version string. -// "HTTP/1.0" returns (1, 0, true). -func ParseHTTPVersion(vers string) (major, minor int, ok bool) { - const Big = 1000000 // arbitrary upper bound - switch vers { - case "HTTP/1.1": - return 1, 1, true - case "HTTP/1.0": - return 1, 0, true - } - if !strings.HasPrefix(vers, "HTTP/") { - return 0, 0, false - } - dot := strings.Index(vers, ".") - if dot < 0 { - return 0, 0, false - } - major, err := strconv.Atoi(vers[5:dot]) - if err != nil || major < 0 || major > Big { - return 0, 0, false - } - minor, err = strconv.Atoi(vers[dot+1:]) - if err != nil || minor < 0 || minor > Big { - return 0, 0, false - } - return major, minor, true -} - -// NewRequest returns a new Request given a method, URL, and optional body. -// -// If the provided body is also an io.Closer, the returned -// Request.Body is set to body and will be closed by the Client -// methods Do, Post, and PostForm, and Transport.RoundTrip. -func NewRequest(method, urlStr string, body io.Reader) (*Request, error) { - u, err := url.Parse(urlStr) - if err != nil { - return nil, err - } - rc, ok := body.(io.ReadCloser) - if !ok && body != nil { - rc = ioutil.NopCloser(body) - } - req := &Request{ - Method: method, - URL: u, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(Header), - Body: rc, - Host: u.Host, - } - if body != nil { - switch v := body.(type) { - case *bytes.Buffer: - req.ContentLength = int64(v.Len()) - case *bytes.Reader: - req.ContentLength = int64(v.Len()) - case *strings.Reader: - req.ContentLength = int64(v.Len()) - } - } - - return req, nil -} - -// SetBasicAuth sets the request's Authorization header to use HTTP -// Basic Authentication with the provided username and password. -// -// With HTTP Basic Authentication the provided username and password -// are not encrypted. -func (r *Request) SetBasicAuth(username, password string) { - r.Header.Set("Authorization", "Basic "+basicAuth(username, password)) -} - -// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts. -func parseRequestLine(line string) (method, requestURI, proto string, ok bool) { - s1 := strings.Index(line, " ") - s2 := strings.Index(line[s1+1:], " ") - if s1 < 0 || s2 < 0 { - return - } - s2 += s1 + 1 - return line[:s1], line[s1+1 : s2], line[s2+1:], true -} - -var textprotoReaderPool sync.Pool - -func newTextprotoReader(br *bufio.Reader) *textproto.Reader { - if v := textprotoReaderPool.Get(); v != nil { - tr := v.(*textproto.Reader) - tr.R = br - return tr - } - return textproto.NewReader(br) -} - -func putTextprotoReader(r *textproto.Reader) { - r.R = nil - textprotoReaderPool.Put(r) -} - -// ReadRequest reads and parses a request from b. -func ReadRequest(b *bufio.Reader) (req *Request, err error) { - - tp := newTextprotoReader(b) - req = new(Request) - - // First line: GET /index.html HTTP/1.0 - var s string - if s, err = tp.ReadLine(); err != nil { - return nil, err - } - defer func() { - putTextprotoReader(tp) - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - }() - - var ok bool - req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s) - if !ok { - return nil, &badStringError{"malformed HTTP request", s} - } - rawurl := req.RequestURI - if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok { - return nil, &badStringError{"malformed HTTP version", req.Proto} - } - - // CONNECT requests are used two different ways, and neither uses a full URL: - // The standard use is to tunnel HTTPS through an HTTP proxy. - // It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is - // just the authority section of a URL. This information should go in req.URL.Host. - // - // The net/rpc package also uses CONNECT, but there the parameter is a path - // that starts with a slash. It can be parsed with the regular URL parser, - // and the path will end up in req.URL.Path, where it needs to be in order for - // RPC to work. - justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/") - if justAuthority { - rawurl = "http://" + rawurl - } - - if req.URL, err = url.ParseRequestURI(rawurl); err != nil { - return nil, err - } - - if justAuthority { - // Strip the bogus "http://" back off. - req.URL.Scheme = "" - } - - // Subsequent lines: Key: value. - mimeHeader, err := tp.ReadMIMEHeader() - if err != nil { - return nil, err - } - req.Header = Header(mimeHeader) - - // RFC2616: Must treat - // GET /index.html HTTP/1.1 - // Host: www.google.com - // and - // GET http://www.google.com/index.html HTTP/1.1 - // Host: doesntmatter - // the same. In the second case, any Host line is ignored. - req.Host = req.URL.Host - if req.Host == "" { - req.Host = req.Header.get("Host") - } - delete(req.Header, "Host") - - fixPragmaCacheControl(req.Header) - - err = readTransfer(req, b) - if err != nil { - return nil, err - } - - return req, nil -} - -// MaxBytesReader is similar to io.LimitReader but is intended for -// limiting the size of incoming request bodies. In contrast to -// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a -// non-EOF error for a Read beyond the limit, and Closes the -// underlying reader when its Close method is called. -// -// MaxBytesReader prevents clients from accidentally or maliciously -// sending a large request and wasting server resources. -func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser { - return &maxBytesReader{w: w, r: r, n: n} -} - -type maxBytesReader struct { - w ResponseWriter - r io.ReadCloser // underlying reader - n int64 // max bytes remaining - stopped bool -} - -func (l *maxBytesReader) Read(p []byte) (n int, err error) { - if l.n <= 0 { - if !l.stopped { - l.stopped = true - if res, ok := l.w.(*response); ok { - res.requestTooLarge() - } - } - return 0, errors.New("http: request body too large") - } - if int64(len(p)) > l.n { - p = p[:l.n] - } - n, err = l.r.Read(p) - l.n -= int64(n) - return -} - -func (l *maxBytesReader) Close() error { - return l.r.Close() -} - -func copyValues(dst, src url.Values) { - for k, vs := range src { - for _, value := range vs { - dst.Add(k, value) - } - } -} - -func parsePostForm(r *Request) (vs url.Values, err error) { - if r.Body == nil { - err = errors.New("missing form body") - return - } - ct := r.Header.Get("Content-Type") - // RFC 2616, section 7.2.1 - empty type - // SHOULD be treated as application/octet-stream - if ct == "" { - ct = "application/octet-stream" - } - ct, _, err = mime.ParseMediaType(ct) - switch { - case ct == "application/x-www-form-urlencoded": - var reader io.Reader = r.Body - maxFormSize := int64(1<<63 - 1) - if _, ok := r.Body.(*maxBytesReader); !ok { - maxFormSize = int64(10 << 20) // 10 MB is a lot of text. - reader = io.LimitReader(r.Body, maxFormSize+1) - } - b, e := ioutil.ReadAll(reader) - if e != nil { - if err == nil { - err = e - } - break - } - if int64(len(b)) > maxFormSize { - err = errors.New("http: POST too large") - return - } - vs, e = url.ParseQuery(string(b)) - if err == nil { - err = e - } - case ct == "multipart/form-data": - // handled by ParseMultipartForm (which is calling us, or should be) - // TODO(bradfitz): there are too many possible - // orders to call too many functions here. - // Clean this up and write more tests. - // request_test.go contains the start of this, - // in TestParseMultipartFormOrder and others. - } - return -} - -// ParseForm parses the raw query from the URL and updates r.Form. -// -// For POST or PUT requests, it also parses the request body as a form and -// put the results into both r.PostForm and r.Form. -// POST and PUT body parameters take precedence over URL query string values -// in r.Form. -// -// If the request Body's size has not already been limited by MaxBytesReader, -// the size is capped at 10MB. -// -// ParseMultipartForm calls ParseForm automatically. -// It is idempotent. -func (r *Request) ParseForm() error { - var err error - if r.PostForm == nil { - if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" { - r.PostForm, err = parsePostForm(r) - } - if r.PostForm == nil { - r.PostForm = make(url.Values) - } - } - if r.Form == nil { - if len(r.PostForm) > 0 { - r.Form = make(url.Values) - copyValues(r.Form, r.PostForm) - } - var newValues url.Values - if r.URL != nil { - var e error - newValues, e = url.ParseQuery(r.URL.RawQuery) - if err == nil { - err = e - } - } - if newValues == nil { - newValues = make(url.Values) - } - if r.Form == nil { - r.Form = newValues - } else { - copyValues(r.Form, newValues) - } - } - return err -} - -// ParseMultipartForm parses a request body as multipart/form-data. -// The whole request body is parsed and up to a total of maxMemory bytes of -// its file parts are stored in memory, with the remainder stored on -// disk in temporary files. -// ParseMultipartForm calls ParseForm if necessary. -// After one call to ParseMultipartForm, subsequent calls have no effect. -func (r *Request) ParseMultipartForm(maxMemory int64) error { - if r.MultipartForm == multipartByReader { - return errors.New("http: multipart handled by MultipartReader") - } - if r.Form == nil { - err := r.ParseForm() - if err != nil { - return err - } - } - if r.MultipartForm != nil { - return nil - } - - mr, err := r.multipartReader() - if err != nil { - return err - } - - f, err := mr.ReadForm(maxMemory) - if err != nil { - return err - } - for k, v := range f.Value { - r.Form[k] = append(r.Form[k], v...) - } - r.MultipartForm = f - - return nil -} - -// FormValue returns the first value for the named component of the query. -// POST and PUT body parameters take precedence over URL query string values. -// FormValue calls ParseMultipartForm and ParseForm if necessary. -// To access multiple values of the same key use ParseForm. -func (r *Request) FormValue(key string) string { - if r.Form == nil { - r.ParseMultipartForm(defaultMaxMemory) - } - if vs := r.Form[key]; len(vs) > 0 { - return vs[0] - } - return "" -} - -// PostFormValue returns the first value for the named component of the POST -// or PUT request body. URL query parameters are ignored. -// PostFormValue calls ParseMultipartForm and ParseForm if necessary. -func (r *Request) PostFormValue(key string) string { - if r.PostForm == nil { - r.ParseMultipartForm(defaultMaxMemory) - } - if vs := r.PostForm[key]; len(vs) > 0 { - return vs[0] - } - return "" -} - -// FormFile returns the first file for the provided form key. -// FormFile calls ParseMultipartForm and ParseForm if necessary. -func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) { - if r.MultipartForm == multipartByReader { - return nil, nil, errors.New("http: multipart handled by MultipartReader") - } - if r.MultipartForm == nil { - err := r.ParseMultipartForm(defaultMaxMemory) - if err != nil { - return nil, nil, err - } - } - if r.MultipartForm != nil && r.MultipartForm.File != nil { - if fhs := r.MultipartForm.File[key]; len(fhs) > 0 { - f, err := fhs[0].Open() - return f, fhs[0], err - } - } - return nil, nil, ErrMissingFile -} - -func (r *Request) expectsContinue() bool { - return hasToken(r.Header.get("Expect"), "100-continue") -} - -func (r *Request) wantsHttp10KeepAlive() bool { - if r.ProtoMajor != 1 || r.ProtoMinor != 0 { - return false - } - return hasToken(r.Header.get("Connection"), "keep-alive") -} - -func (r *Request) wantsClose() bool { - return hasToken(r.Header.get("Connection"), "close") -} - -func (r *Request) closeBody() { - if r.Body != nil { - r.Body.Close() - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/request_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/request_test.go deleted file mode 100644 index b9fa3c2bfc..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/request_test.go +++ /dev/null @@ -1,610 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - . "net/http" - "net/http/httptest" - "net/url" - "os" - "reflect" - "regexp" - "strings" - "testing" -) - -func TestQuery(t *testing.T) { - req := &Request{Method: "GET"} - req.URL, _ = url.Parse("http://www.google.com/search?q=foo&q=bar") - if q := req.FormValue("q"); q != "foo" { - t.Errorf(`req.FormValue("q") = %q, want "foo"`, q) - } -} - -func TestPostQuery(t *testing.T) { - req, _ := NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not", - strings.NewReader("z=post&both=y&prio=2&empty=")) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") - - if q := req.FormValue("q"); q != "foo" { - t.Errorf(`req.FormValue("q") = %q, want "foo"`, q) - } - if z := req.FormValue("z"); z != "post" { - t.Errorf(`req.FormValue("z") = %q, want "post"`, z) - } - if bq, found := req.PostForm["q"]; found { - t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq) - } - if bz := req.PostFormValue("z"); bz != "post" { - t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz) - } - if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) { - t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs) - } - if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) { - t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both) - } - if prio := req.FormValue("prio"); prio != "2" { - t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio) - } - if empty := req.FormValue("empty"); empty != "" { - t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty) - } -} - -func TestPatchQuery(t *testing.T) { - req, _ := NewRequest("PATCH", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not", - strings.NewReader("z=post&both=y&prio=2&empty=")) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") - - if q := req.FormValue("q"); q != "foo" { - t.Errorf(`req.FormValue("q") = %q, want "foo"`, q) - } - if z := req.FormValue("z"); z != "post" { - t.Errorf(`req.FormValue("z") = %q, want "post"`, z) - } - if bq, found := req.PostForm["q"]; found { - t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq) - } - if bz := req.PostFormValue("z"); bz != "post" { - t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz) - } - if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) { - t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs) - } - if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) { - t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both) - } - if prio := req.FormValue("prio"); prio != "2" { - t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio) - } - if empty := req.FormValue("empty"); empty != "" { - t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty) - } -} - -type stringMap map[string][]string -type parseContentTypeTest struct { - shouldError bool - contentType stringMap -} - -var parseContentTypeTests = []parseContentTypeTest{ - {false, stringMap{"Content-Type": {"text/plain"}}}, - // Empty content type is legal - shoult be treated as - // application/octet-stream (RFC 2616, section 7.2.1) - {false, stringMap{}}, - {true, stringMap{"Content-Type": {"text/plain; boundary="}}}, - {false, stringMap{"Content-Type": {"application/unknown"}}}, -} - -func TestParseFormUnknownContentType(t *testing.T) { - for i, test := range parseContentTypeTests { - req := &Request{ - Method: "POST", - Header: Header(test.contentType), - Body: ioutil.NopCloser(strings.NewReader("body")), - } - err := req.ParseForm() - switch { - case err == nil && test.shouldError: - t.Errorf("test %d should have returned error", i) - case err != nil && !test.shouldError: - t.Errorf("test %d should not have returned error, got %v", i, err) - } - } -} - -func TestParseFormInitializeOnError(t *testing.T) { - nilBody, _ := NewRequest("POST", "http://www.google.com/search?q=foo", nil) - tests := []*Request{ - nilBody, - {Method: "GET", URL: nil}, - } - for i, req := range tests { - err := req.ParseForm() - if req.Form == nil { - t.Errorf("%d. Form not initialized, error %v", i, err) - } - if req.PostForm == nil { - t.Errorf("%d. PostForm not initialized, error %v", i, err) - } - } -} - -func TestMultipartReader(t *testing.T) { - req := &Request{ - Method: "POST", - Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}}, - Body: ioutil.NopCloser(new(bytes.Buffer)), - } - multipart, err := req.MultipartReader() - if multipart == nil { - t.Errorf("expected multipart; error: %v", err) - } - - req.Header = Header{"Content-Type": {"text/plain"}} - multipart, err = req.MultipartReader() - if multipart != nil { - t.Error("unexpected multipart for text/plain") - } -} - -func TestParseMultipartForm(t *testing.T) { - req := &Request{ - Method: "POST", - Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}}, - Body: ioutil.NopCloser(new(bytes.Buffer)), - } - err := req.ParseMultipartForm(25) - if err == nil { - t.Error("expected multipart EOF, got nil") - } - - req.Header = Header{"Content-Type": {"text/plain"}} - err = req.ParseMultipartForm(25) - if err != ErrNotMultipart { - t.Error("expected ErrNotMultipart for text/plain") - } -} - -func TestRedirect(t *testing.T) { - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - switch r.URL.Path { - case "/": - w.Header().Set("Location", "/foo/") - w.WriteHeader(StatusSeeOther) - case "/foo/": - fmt.Fprintf(w, "foo") - default: - w.WriteHeader(StatusBadRequest) - } - })) - defer ts.Close() - - var end = regexp.MustCompile("/foo/$") - r, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - r.Body.Close() - url := r.Request.URL.String() - if r.StatusCode != 200 || !end.MatchString(url) { - t.Fatalf("Get got status %d at %q, want 200 matching /foo/$", r.StatusCode, url) - } -} - -func TestSetBasicAuth(t *testing.T) { - r, _ := NewRequest("GET", "http://example.com/", nil) - r.SetBasicAuth("Aladdin", "open sesame") - if g, e := r.Header.Get("Authorization"), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; g != e { - t.Errorf("got header %q, want %q", g, e) - } -} - -func TestMultipartRequest(t *testing.T) { - // Test that we can read the values and files of a - // multipart request with FormValue and FormFile, - // and that ParseMultipartForm can be called multiple times. - req := newTestMultipartRequest(t) - if err := req.ParseMultipartForm(25); err != nil { - t.Fatal("ParseMultipartForm first call:", err) - } - defer req.MultipartForm.RemoveAll() - validateTestMultipartContents(t, req, false) - if err := req.ParseMultipartForm(25); err != nil { - t.Fatal("ParseMultipartForm second call:", err) - } - validateTestMultipartContents(t, req, false) -} - -func TestMultipartRequestAuto(t *testing.T) { - // Test that FormValue and FormFile automatically invoke - // ParseMultipartForm and return the right values. - req := newTestMultipartRequest(t) - defer func() { - if req.MultipartForm != nil { - req.MultipartForm.RemoveAll() - } - }() - validateTestMultipartContents(t, req, true) -} - -func TestMissingFileMultipartRequest(t *testing.T) { - // Test that FormFile returns an error if - // the named file is missing. - req := newTestMultipartRequest(t) - testMissingFile(t, req) -} - -// Test that FormValue invokes ParseMultipartForm. -func TestFormValueCallsParseMultipartForm(t *testing.T) { - req, _ := NewRequest("POST", "http://www.google.com/", strings.NewReader("z=post")) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") - if req.Form != nil { - t.Fatal("Unexpected request Form, want nil") - } - req.FormValue("z") - if req.Form == nil { - t.Fatal("ParseMultipartForm not called by FormValue") - } -} - -// Test that FormFile invokes ParseMultipartForm. -func TestFormFileCallsParseMultipartForm(t *testing.T) { - req := newTestMultipartRequest(t) - if req.Form != nil { - t.Fatal("Unexpected request Form, want nil") - } - req.FormFile("") - if req.Form == nil { - t.Fatal("ParseMultipartForm not called by FormFile") - } -} - -// Test that ParseMultipartForm errors if called -// after MultipartReader on the same request. -func TestParseMultipartFormOrder(t *testing.T) { - req := newTestMultipartRequest(t) - if _, err := req.MultipartReader(); err != nil { - t.Fatalf("MultipartReader: %v", err) - } - if err := req.ParseMultipartForm(1024); err == nil { - t.Fatal("expected an error from ParseMultipartForm after call to MultipartReader") - } -} - -// Test that MultipartReader errors if called -// after ParseMultipartForm on the same request. -func TestMultipartReaderOrder(t *testing.T) { - req := newTestMultipartRequest(t) - if err := req.ParseMultipartForm(25); err != nil { - t.Fatalf("ParseMultipartForm: %v", err) - } - defer req.MultipartForm.RemoveAll() - if _, err := req.MultipartReader(); err == nil { - t.Fatal("expected an error from MultipartReader after call to ParseMultipartForm") - } -} - -// Test that FormFile errors if called after -// MultipartReader on the same request. -func TestFormFileOrder(t *testing.T) { - req := newTestMultipartRequest(t) - if _, err := req.MultipartReader(); err != nil { - t.Fatalf("MultipartReader: %v", err) - } - if _, _, err := req.FormFile(""); err == nil { - t.Fatal("expected an error from FormFile after call to MultipartReader") - } -} - -var readRequestErrorTests = []struct { - in string - err error -}{ - {"GET / HTTP/1.1\r\nheader:foo\r\n\r\n", nil}, - {"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF}, - {"", io.EOF}, -} - -func TestReadRequestErrors(t *testing.T) { - for i, tt := range readRequestErrorTests { - _, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.in))) - if err != tt.err { - t.Errorf("%d. got error = %v; want %v", i, err, tt.err) - } - } -} - -func TestNewRequestHost(t *testing.T) { - req, err := NewRequest("GET", "http://localhost:1234/", nil) - if err != nil { - t.Fatal(err) - } - if req.Host != "localhost:1234" { - t.Errorf("Host = %q; want localhost:1234", req.Host) - } -} - -func TestNewRequestContentLength(t *testing.T) { - readByte := func(r io.Reader) io.Reader { - var b [1]byte - r.Read(b[:]) - return r - } - tests := []struct { - r io.Reader - want int64 - }{ - {bytes.NewReader([]byte("123")), 3}, - {bytes.NewBuffer([]byte("1234")), 4}, - {strings.NewReader("12345"), 5}, - // Not detected: - {struct{ io.Reader }{strings.NewReader("xyz")}, 0}, - {io.NewSectionReader(strings.NewReader("x"), 0, 6), 0}, - {readByte(io.NewSectionReader(strings.NewReader("xy"), 0, 6)), 0}, - } - for _, tt := range tests { - req, err := NewRequest("POST", "http://localhost/", tt.r) - if err != nil { - t.Fatal(err) - } - if req.ContentLength != tt.want { - t.Errorf("ContentLength(%T) = %d; want %d", tt.r, req.ContentLength, tt.want) - } - } -} - -var parseHTTPVersionTests = []struct { - vers string - major, minor int - ok bool -}{ - {"HTTP/0.9", 0, 9, true}, - {"HTTP/1.0", 1, 0, true}, - {"HTTP/1.1", 1, 1, true}, - {"HTTP/3.14", 3, 14, true}, - - {"HTTP", 0, 0, false}, - {"HTTP/one.one", 0, 0, false}, - {"HTTP/1.1/", 0, 0, false}, - {"HTTP/-1,0", 0, 0, false}, - {"HTTP/0,-1", 0, 0, false}, - {"HTTP/", 0, 0, false}, - {"HTTP/1,1", 0, 0, false}, -} - -func TestParseHTTPVersion(t *testing.T) { - for _, tt := range parseHTTPVersionTests { - major, minor, ok := ParseHTTPVersion(tt.vers) - if ok != tt.ok || major != tt.major || minor != tt.minor { - type version struct { - major, minor int - ok bool - } - t.Errorf("failed to parse %q, expected: %#v, got %#v", tt.vers, version{tt.major, tt.minor, tt.ok}, version{major, minor, ok}) - } - } -} - -type logWrites struct { - t *testing.T - dst *[]string -} - -func (l logWrites) WriteByte(c byte) error { - l.t.Fatalf("unexpected WriteByte call") - return nil -} - -func (l logWrites) Write(p []byte) (n int, err error) { - *l.dst = append(*l.dst, string(p)) - return len(p), nil -} - -func TestRequestWriteBufferedWriter(t *testing.T) { - got := []string{} - req, _ := NewRequest("GET", "http://foo.com/", nil) - req.Write(logWrites{t, &got}) - want := []string{ - "GET / HTTP/1.1\r\n", - "Host: foo.com\r\n", - "User-Agent: " + DefaultUserAgent + "\r\n", - "\r\n", - } - if !reflect.DeepEqual(got, want) { - t.Errorf("Writes = %q\n Want = %q", got, want) - } -} - -func testMissingFile(t *testing.T, req *Request) { - f, fh, err := req.FormFile("missing") - if f != nil { - t.Errorf("FormFile file = %v, want nil", f) - } - if fh != nil { - t.Errorf("FormFile file header = %q, want nil", fh) - } - if err != ErrMissingFile { - t.Errorf("FormFile err = %q, want ErrMissingFile", err) - } -} - -func newTestMultipartRequest(t *testing.T) *Request { - b := strings.NewReader(strings.Replace(message, "\n", "\r\n", -1)) - req, err := NewRequest("POST", "/", b) - if err != nil { - t.Fatal("NewRequest:", err) - } - ctype := fmt.Sprintf(`multipart/form-data; boundary="%s"`, boundary) - req.Header.Set("Content-type", ctype) - return req -} - -func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) { - if g, e := req.FormValue("texta"), textaValue; g != e { - t.Errorf("texta value = %q, want %q", g, e) - } - if g, e := req.FormValue("textb"), textbValue; g != e { - t.Errorf("textb value = %q, want %q", g, e) - } - if g := req.FormValue("missing"); g != "" { - t.Errorf("missing value = %q, want empty string", g) - } - - assertMem := func(n string, fd multipart.File) { - if _, ok := fd.(*os.File); ok { - t.Error(n, " is *os.File, should not be") - } - } - fda := testMultipartFile(t, req, "filea", "filea.txt", fileaContents) - defer fda.Close() - assertMem("filea", fda) - fdb := testMultipartFile(t, req, "fileb", "fileb.txt", filebContents) - defer fdb.Close() - if allMem { - assertMem("fileb", fdb) - } else { - if _, ok := fdb.(*os.File); !ok { - t.Errorf("fileb has unexpected underlying type %T", fdb) - } - } - - testMissingFile(t, req) -} - -func testMultipartFile(t *testing.T, req *Request, key, expectFilename, expectContent string) multipart.File { - f, fh, err := req.FormFile(key) - if err != nil { - t.Fatalf("FormFile(%q): %q", key, err) - } - if fh.Filename != expectFilename { - t.Errorf("filename = %q, want %q", fh.Filename, expectFilename) - } - var b bytes.Buffer - _, err = io.Copy(&b, f) - if err != nil { - t.Fatal("copying contents:", err) - } - if g := b.String(); g != expectContent { - t.Errorf("contents = %q, want %q", g, expectContent) - } - return f -} - -const ( - fileaContents = "This is a test file." - filebContents = "Another test file." - textaValue = "foo" - textbValue = "bar" - boundary = `MyBoundary` -) - -const message = ` ---MyBoundary -Content-Disposition: form-data; name="filea"; filename="filea.txt" -Content-Type: text/plain - -` + fileaContents + ` ---MyBoundary -Content-Disposition: form-data; name="fileb"; filename="fileb.txt" -Content-Type: text/plain - -` + filebContents + ` ---MyBoundary -Content-Disposition: form-data; name="texta" - -` + textaValue + ` ---MyBoundary -Content-Disposition: form-data; name="textb" - -` + textbValue + ` ---MyBoundary-- -` - -func benchmarkReadRequest(b *testing.B, request string) { - request = request + "\n" // final \n - request = strings.Replace(request, "\n", "\r\n", -1) // expand \n to \r\n - b.SetBytes(int64(len(request))) - r := bufio.NewReader(&infiniteReader{buf: []byte(request)}) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := ReadRequest(r) - if err != nil { - b.Fatalf("failed to read request: %v", err) - } - } -} - -// infiniteReader satisfies Read requests as if the contents of buf -// loop indefinitely. -type infiniteReader struct { - buf []byte - offset int -} - -func (r *infiniteReader) Read(b []byte) (int, error) { - n := copy(b, r.buf[r.offset:]) - r.offset = (r.offset + n) % len(r.buf) - return n, nil -} - -func BenchmarkReadRequestChrome(b *testing.B) { - // https://github.com/felixge/node-http-perf/blob/master/fixtures/get.http - benchmarkReadRequest(b, `GET / HTTP/1.1 -Host: localhost:8080 -Connection: keep-alive -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17 -Accept-Encoding: gzip,deflate,sdch -Accept-Language: en-US,en;q=0.8 -Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 -Cookie: __utma=1.1978842379.1323102373.1323102373.1323102373.1; EPi:NumberOfVisits=1,2012-02-28T13:42:18; CrmSession=5b707226b9563e1bc69084d07a107c98; plushContainerWidth=100%25; plushNoTopMenu=0; hudson_auto_refresh=false -`) -} - -func BenchmarkReadRequestCurl(b *testing.B) { - // curl http://localhost:8080/ - benchmarkReadRequest(b, `GET / HTTP/1.1 -User-Agent: curl/7.27.0 -Host: localhost:8080 -Accept: */* -`) -} - -func BenchmarkReadRequestApachebench(b *testing.B) { - // ab -n 1 -c 1 http://localhost:8080/ - benchmarkReadRequest(b, `GET / HTTP/1.0 -Host: localhost:8080 -User-Agent: ApacheBench/2.3 -Accept: */* -`) -} - -func BenchmarkReadRequestSiege(b *testing.B) { - // siege -r 1 -c 1 http://localhost:8080/ - benchmarkReadRequest(b, `GET / HTTP/1.1 -Host: localhost:8080 -Accept: */* -Accept-Encoding: gzip -User-Agent: JoeDog/1.00 [en] (X11; I; Siege 2.70) -Connection: keep-alive -`) -} - -func BenchmarkReadRequestWrk(b *testing.B) { - // wrk -t 1 -r 1 -c 1 http://localhost:8080/ - benchmarkReadRequest(b, `GET / HTTP/1.1 -Host: localhost:8080 -`) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/requestwrite_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/requestwrite_test.go deleted file mode 100644 index dc0e204cac..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/requestwrite_test.go +++ /dev/null @@ -1,565 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "net/url" - "strings" - "testing" -) - -type reqWriteTest struct { - Req Request - Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body - - // Any of these three may be empty to skip that test. - WantWrite string // Request.Write - WantProxy string // Request.WriteProxy - - WantError error // wanted error from Request.Write -} - -var reqWriteTests = []reqWriteTest{ - // HTTP/1.1 => chunked coding; no body; no trailer - { - Req: Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "www.techcrunch.com", - Path: "/", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{ - "Accept": {"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}, - "Accept-Charset": {"ISO-8859-1,utf-8;q=0.7,*;q=0.7"}, - "Accept-Encoding": {"gzip,deflate"}, - "Accept-Language": {"en-us,en;q=0.5"}, - "Keep-Alive": {"300"}, - "Proxy-Connection": {"keep-alive"}, - "User-Agent": {"Fake"}, - }, - Body: nil, - Close: false, - Host: "www.techcrunch.com", - Form: map[string][]string{}, - }, - - WantWrite: "GET / HTTP/1.1\r\n" + - "Host: www.techcrunch.com\r\n" + - "User-Agent: Fake\r\n" + - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + - "Accept-Encoding: gzip,deflate\r\n" + - "Accept-Language: en-us,en;q=0.5\r\n" + - "Keep-Alive: 300\r\n" + - "Proxy-Connection: keep-alive\r\n\r\n", - - WantProxy: "GET http://www.techcrunch.com/ HTTP/1.1\r\n" + - "Host: www.techcrunch.com\r\n" + - "User-Agent: Fake\r\n" + - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + - "Accept-Encoding: gzip,deflate\r\n" + - "Accept-Language: en-us,en;q=0.5\r\n" + - "Keep-Alive: 300\r\n" + - "Proxy-Connection: keep-alive\r\n\r\n", - }, - // HTTP/1.1 => chunked coding; body; empty trailer - { - Req: Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "www.google.com", - Path: "/search", - }, - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - TransferEncoding: []string{"chunked"}, - }, - - Body: []byte("abcdef"), - - WantWrite: "GET /search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("abcdef") + chunk(""), - - WantProxy: "GET http://www.google.com/search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("abcdef") + chunk(""), - }, - // HTTP/1.1 POST => chunked coding; body; empty trailer - { - Req: Request{ - Method: "POST", - URL: &url.URL{ - Scheme: "http", - Host: "www.google.com", - Path: "/search", - }, - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: true, - TransferEncoding: []string{"chunked"}, - }, - - Body: []byte("abcdef"), - - WantWrite: "POST /search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Connection: close\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("abcdef") + chunk(""), - - WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Connection: close\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("abcdef") + chunk(""), - }, - - // HTTP/1.1 POST with Content-Length, no chunking - { - Req: Request{ - Method: "POST", - URL: &url.URL{ - Scheme: "http", - Host: "www.google.com", - Path: "/search", - }, - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Close: true, - ContentLength: 6, - }, - - Body: []byte("abcdef"), - - WantWrite: "POST /search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Connection: close\r\n" + - "Content-Length: 6\r\n" + - "\r\n" + - "abcdef", - - WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Connection: close\r\n" + - "Content-Length: 6\r\n" + - "\r\n" + - "abcdef", - }, - - // HTTP/1.1 POST with Content-Length in headers - { - Req: Request{ - Method: "POST", - URL: mustParseURL("http://example.com/"), - Host: "example.com", - Header: Header{ - "Content-Length": []string{"10"}, // ignored - }, - ContentLength: 6, - }, - - Body: []byte("abcdef"), - - WantWrite: "POST / HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Content-Length: 6\r\n" + - "\r\n" + - "abcdef", - - WantProxy: "POST http://example.com/ HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Content-Length: 6\r\n" + - "\r\n" + - "abcdef", - }, - - // default to HTTP/1.1 - { - Req: Request{ - Method: "GET", - URL: mustParseURL("/search"), - Host: "www.google.com", - }, - - WantWrite: "GET /search HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "\r\n", - }, - - // Request with a 0 ContentLength and a 0 byte body. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 0, // as if unset by user - }, - - Body: func() io.ReadCloser { return ioutil.NopCloser(io.LimitReader(strings.NewReader("xx"), 0)) }, - - // RFC 2616 Section 14.13 says Content-Length should be specified - // unless body is prohibited by the request method. - // Also, nginx expects it for POST and PUT. - WantWrite: "POST / HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Content-Length: 0\r\n" + - "\r\n", - - WantProxy: "POST / HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Content-Length: 0\r\n" + - "\r\n", - }, - - // Request with a 0 ContentLength and a 1 byte body. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 0, // as if unset by user - }, - - Body: func() io.ReadCloser { return ioutil.NopCloser(io.LimitReader(strings.NewReader("xx"), 1)) }, - - WantWrite: "POST / HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("x") + chunk(""), - - WantProxy: "POST / HTTP/1.1\r\n" + - "Host: example.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - chunk("x") + chunk(""), - }, - - // Request with a ContentLength of 10 but a 5 byte body. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 10, // but we're going to send only 5 bytes - }, - Body: []byte("12345"), - WantError: errors.New("http: Request.ContentLength=10 with Body length 5"), - }, - - // Request with a ContentLength of 4 but an 8 byte body. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 4, // but we're going to try to send 8 bytes - }, - Body: []byte("12345678"), - WantError: errors.New("http: Request.ContentLength=4 with Body length 8"), - }, - - // Request with a 5 ContentLength and nil body. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 5, // but we'll omit the body - }, - WantError: errors.New("http: Request.ContentLength=5 with nil Body"), - }, - - // Request with a 0 ContentLength and a body with 1 byte content and an error. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 0, // as if unset by user - }, - - Body: func() io.ReadCloser { - err := errors.New("Custom reader error") - errReader := &errorReader{err} - return ioutil.NopCloser(io.MultiReader(strings.NewReader("x"), errReader)) - }, - - WantError: errors.New("Custom reader error"), - }, - - // Request with a 0 ContentLength and a body without content and an error. - { - Req: Request{ - Method: "POST", - URL: mustParseURL("/"), - Host: "example.com", - ProtoMajor: 1, - ProtoMinor: 1, - ContentLength: 0, // as if unset by user - }, - - Body: func() io.ReadCloser { - err := errors.New("Custom reader error") - errReader := &errorReader{err} - return ioutil.NopCloser(errReader) - }, - - WantError: errors.New("Custom reader error"), - }, - - // Verify that DumpRequest preserves the HTTP version number, doesn't add a Host, - // and doesn't add a User-Agent. - { - Req: Request{ - Method: "GET", - URL: mustParseURL("/foo"), - ProtoMajor: 1, - ProtoMinor: 0, - Header: Header{ - "X-Foo": []string{"X-Bar"}, - }, - }, - - WantWrite: "GET /foo HTTP/1.1\r\n" + - "Host: \r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "X-Foo: X-Bar\r\n\r\n", - }, - - // If no Request.Host and no Request.URL.Host, we send - // an empty Host header, and don't use - // Request.Header["Host"]. This is just testing that - // we don't change Go 1.0 behavior. - { - Req: Request{ - Method: "GET", - Host: "", - URL: &url.URL{ - Scheme: "http", - Host: "", - Path: "/search", - }, - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{ - "Host": []string{"bad.example.com"}, - }, - }, - - WantWrite: "GET /search HTTP/1.1\r\n" + - "Host: \r\n" + - "User-Agent: Go 1.1 package http\r\n\r\n", - }, - - // Opaque test #1 from golang.org/issue/4860 - { - Req: Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "www.google.com", - Opaque: "/%2F/%2F/", - }, - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - }, - - WantWrite: "GET /%2F/%2F/ HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n\r\n", - }, - - // Opaque test #2 from golang.org/issue/4860 - { - Req: Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "x.google.com", - Opaque: "//y.google.com/%2F/%2F/", - }, - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - }, - - WantWrite: "GET http://y.google.com/%2F/%2F/ HTTP/1.1\r\n" + - "Host: x.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n\r\n", - }, - - // Testing custom case in header keys. Issue 5022. - { - Req: Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: "www.google.com", - Path: "/", - }, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{ - "ALL-CAPS": {"x"}, - }, - }, - - WantWrite: "GET / HTTP/1.1\r\n" + - "Host: www.google.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "ALL-CAPS: x\r\n" + - "\r\n", - }, -} - -func TestRequestWrite(t *testing.T) { - for i := range reqWriteTests { - tt := &reqWriteTests[i] - - setBody := func() { - if tt.Body == nil { - return - } - switch b := tt.Body.(type) { - case []byte: - tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b)) - case func() io.ReadCloser: - tt.Req.Body = b() - } - } - setBody() - if tt.Req.Header == nil { - tt.Req.Header = make(Header) - } - - var braw bytes.Buffer - err := tt.Req.Write(&braw) - if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.WantError); g != e { - t.Errorf("writing #%d, err = %q, want %q", i, g, e) - continue - } - if err != nil { - continue - } - - if tt.WantWrite != "" { - sraw := braw.String() - if sraw != tt.WantWrite { - t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantWrite, sraw) - continue - } - } - - if tt.WantProxy != "" { - setBody() - var praw bytes.Buffer - err = tt.Req.WriteProxy(&praw) - if err != nil { - t.Errorf("WriteProxy #%d: %s", i, err) - continue - } - sraw := praw.String() - if sraw != tt.WantProxy { - t.Errorf("Test Proxy %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantProxy, sraw) - continue - } - } - } -} - -type closeChecker struct { - io.Reader - closed bool -} - -func (rc *closeChecker) Close() error { - rc.closed = true - return nil -} - -// TestRequestWriteClosesBody tests that Request.Write does close its request.Body. -// It also indirectly tests NewRequest and that it doesn't wrap an existing Closer -// inside a NopCloser, and that it serializes it correctly. -func TestRequestWriteClosesBody(t *testing.T) { - rc := &closeChecker{Reader: strings.NewReader("my body")} - req, _ := NewRequest("POST", "http://foo.com/", rc) - if req.ContentLength != 0 { - t.Errorf("got req.ContentLength %d, want 0", req.ContentLength) - } - buf := new(bytes.Buffer) - req.Write(buf) - if !rc.closed { - t.Error("body not closed after write") - } - expected := "POST / HTTP/1.1\r\n" + - "Host: foo.com\r\n" + - "User-Agent: Go 1.1 package http\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - // TODO: currently we don't buffer before chunking, so we get a - // single "m" chunk before the other chunks, as this was the 1-byte - // read from our MultiReader where we stiched the Body back together - // after sniffing whether the Body was 0 bytes or not. - chunk("m") + - chunk("y body") + - chunk("") - if buf.String() != expected { - t.Errorf("write:\n got: %s\nwant: %s", buf.String(), expected) - } -} - -func chunk(s string) string { - return fmt.Sprintf("%x\r\n%s\r\n", len(s), s) -} - -func mustParseURL(s string) *url.URL { - u, err := url.Parse(s) - if err != nil { - panic(fmt.Sprintf("Error parsing URL %q: %v", s, err)) - } - return u -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/response.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/response.go deleted file mode 100644 index a8c64ba633..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/response.go +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP Response reading and parsing. - -package http - -import ( - "bufio" - "bytes" - "errors" - "github.com/MSOpenTech/azure-sdk-for-go/core/tls" - "io" - "net/textproto" - "net/url" - "strconv" - "strings" -) - -var respExcludeHeader = map[string]bool{ - "Content-Length": true, - "Transfer-Encoding": true, - "Trailer": true, -} - -// Response represents the response from an HTTP request. -// -type Response struct { - Status string // e.g. "200 OK" - StatusCode int // e.g. 200 - Proto string // e.g. "HTTP/1.0" - ProtoMajor int // e.g. 1 - ProtoMinor int // e.g. 0 - - // Header maps header keys to values. If the response had multiple - // headers with the same key, they may be concatenated, with comma - // delimiters. (Section 4.2 of RFC 2616 requires that multiple headers - // be semantically equivalent to a comma-delimited sequence.) Values - // duplicated by other fields in this struct (e.g., ContentLength) are - // omitted from Header. - // - // Keys in the map are canonicalized (see CanonicalHeaderKey). - Header Header - - // Body represents the response body. - // - // The http Client and Transport guarantee that Body is always - // non-nil, even on responses without a body or responses with - // a zero-length body. It is the caller's responsibility to - // close Body. - // - // The Body is automatically dechunked if the server replied - // with a "chunked" Transfer-Encoding. - Body io.ReadCloser - - // ContentLength records the length of the associated content. The - // value -1 indicates that the length is unknown. Unless Request.Method - // is "HEAD", values >= 0 indicate that the given number of bytes may - // be read from Body. - ContentLength int64 - - // Contains transfer encodings from outer-most to inner-most. Value is - // nil, means that "identity" encoding is used. - TransferEncoding []string - - // Close records whether the header directed that the connection be - // closed after reading Body. The value is advice for clients: neither - // ReadResponse nor Response.Write ever closes a connection. - Close bool - - // Trailer maps trailer keys to values, in the same - // format as the header. - Trailer Header - - // The Request that was sent to obtain this Response. - // Request's Body is nil (having already been consumed). - // This is only populated for Client requests. - Request *Request - - // TLS contains information about the TLS connection on which the - // response was received. It is nil for unencrypted responses. - // The pointer is shared between responses and should not be - // modified. - TLS *tls.ConnectionState -} - -// Cookies parses and returns the cookies set in the Set-Cookie headers. -func (r *Response) Cookies() []*Cookie { - return readSetCookies(r.Header) -} - -var ErrNoLocation = errors.New("http: no Location header in response") - -// Location returns the URL of the response's "Location" header, -// if present. Relative redirects are resolved relative to -// the Response's Request. ErrNoLocation is returned if no -// Location header is present. -func (r *Response) Location() (*url.URL, error) { - lv := r.Header.Get("Location") - if lv == "" { - return nil, ErrNoLocation - } - if r.Request != nil && r.Request.URL != nil { - return r.Request.URL.Parse(lv) - } - return url.Parse(lv) -} - -// ReadResponse reads and returns an HTTP response from r. -// The req parameter optionally specifies the Request that corresponds -// to this Response. If nil, a GET request is assumed. -// Clients must call resp.Body.Close when finished reading resp.Body. -// After that call, clients can inspect resp.Trailer to find key/value -// pairs included in the response trailer. -func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) { - tp := textproto.NewReader(r) - resp := &Response{ - Request: req, - } - - // Parse the first line of the response. - line, err := tp.ReadLine() - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - return nil, err - } - f := strings.SplitN(line, " ", 3) - if len(f) < 2 { - return nil, &badStringError{"malformed HTTP response", line} - } - reasonPhrase := "" - if len(f) > 2 { - reasonPhrase = f[2] - } - resp.Status = f[1] + " " + reasonPhrase - resp.StatusCode, err = strconv.Atoi(f[1]) - if err != nil { - return nil, &badStringError{"malformed HTTP status code", f[1]} - } - - resp.Proto = f[0] - var ok bool - if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok { - return nil, &badStringError{"malformed HTTP version", resp.Proto} - } - - // Parse the response headers. - mimeHeader, err := tp.ReadMIMEHeader() - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - return nil, err - } - resp.Header = Header(mimeHeader) - - fixPragmaCacheControl(resp.Header) - - err = readTransfer(resp, r) - if err != nil { - return nil, err - } - - return resp, nil -} - -// RFC2616: Should treat -// Pragma: no-cache -// like -// Cache-Control: no-cache -func fixPragmaCacheControl(header Header) { - if hp, ok := header["Pragma"]; ok && len(hp) > 0 && hp[0] == "no-cache" { - if _, presentcc := header["Cache-Control"]; !presentcc { - header["Cache-Control"] = []string{"no-cache"} - } - } -} - -// ProtoAtLeast reports whether the HTTP protocol used -// in the response is at least major.minor. -func (r *Response) ProtoAtLeast(major, minor int) bool { - return r.ProtoMajor > major || - r.ProtoMajor == major && r.ProtoMinor >= minor -} - -// Writes the response (header, body and trailer) in wire format. This method -// consults the following fields of the response: -// -// StatusCode -// ProtoMajor -// ProtoMinor -// Request.Method -// TransferEncoding -// Trailer -// Body -// ContentLength -// Header, values for non-canonical keys will have unpredictable behavior -// -// Body is closed after it is sent. -func (r *Response) Write(w io.Writer) error { - // Status line - text := r.Status - if text == "" { - var ok bool - text, ok = statusText[r.StatusCode] - if !ok { - text = "status code " + strconv.Itoa(r.StatusCode) - } - } - protoMajor, protoMinor := strconv.Itoa(r.ProtoMajor), strconv.Itoa(r.ProtoMinor) - statusCode := strconv.Itoa(r.StatusCode) + " " - text = strings.TrimPrefix(text, statusCode) - if _, err := io.WriteString(w, "HTTP/"+protoMajor+"."+protoMinor+" "+statusCode+text+"\r\n"); err != nil { - return err - } - - // Clone it, so we can modify r1 as needed. - r1 := new(Response) - *r1 = *r - if r1.ContentLength == 0 && r1.Body != nil { - // Is it actually 0 length? Or just unknown? - var buf [1]byte - n, err := r1.Body.Read(buf[:]) - if err != nil && err != io.EOF { - return err - } - if n == 0 { - // Reset it to a known zero reader, in case underlying one - // is unhappy being read repeatedly. - r1.Body = eofReader - } else { - r1.ContentLength = -1 - r1.Body = struct { - io.Reader - io.Closer - }{ - io.MultiReader(bytes.NewReader(buf[:1]), r.Body), - r.Body, - } - } - } - // If we're sending a non-chunked HTTP/1.1 response without a - // content-length, the only way to do that is the old HTTP/1.0 - // way, by noting the EOF with a connection close, so we need - // to set Close. - if r1.ContentLength == -1 && !r1.Close && r1.ProtoAtLeast(1, 1) && !chunked(r1.TransferEncoding) { - r1.Close = true - } - - // Process Body,ContentLength,Close,Trailer - tw, err := newTransferWriter(r1) - if err != nil { - return err - } - err = tw.WriteHeader(w) - if err != nil { - return err - } - - // Rest of header - err = r.Header.WriteSubset(w, respExcludeHeader) - if err != nil { - return err - } - - // contentLengthAlreadySent may have been already sent for - // POST/PUT requests, even if zero length. See Issue 8180. - contentLengthAlreadySent := tw.shouldSendContentLength() - if r1.ContentLength == 0 && !chunked(r1.TransferEncoding) && !contentLengthAlreadySent { - if _, err := io.WriteString(w, "Content-Length: 0\r\n"); err != nil { - return err - } - } - - // End-of-header - if _, err := io.WriteString(w, "\r\n"); err != nil { - return err - } - - // Write body and trailer - err = tw.WriteBody(w) - if err != nil { - return err - } - - // Success - return nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/response_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/response_test.go deleted file mode 100644 index 4b8946f7ae..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/response_test.go +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bufio" - "bytes" - "compress/gzip" - "crypto/rand" - "fmt" - "io" - "io/ioutil" - "net/url" - "reflect" - "regexp" - "strings" - "testing" -) - -type respTest struct { - Raw string - Resp Response - Body string -} - -func dummyReq(method string) *Request { - return &Request{Method: method} -} - -func dummyReq11(method string) *Request { - return &Request{Method: method, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1} -} - -var respTests = []respTest{ - // Unchunked response without Content-Length. - { - "HTTP/1.0 200 OK\r\n" + - "Connection: close\r\n" + - "\r\n" + - "Body here\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("GET"), - Header: Header{ - "Connection": {"close"}, // TODO(rsc): Delete? - }, - Close: true, - ContentLength: -1, - }, - - "Body here\n", - }, - - // Unchunked HTTP/1.1 response without Content-Length or - // Connection headers. - { - "HTTP/1.1 200 OK\r\n" + - "\r\n" + - "Body here\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Request: dummyReq("GET"), - Close: true, - ContentLength: -1, - }, - - "Body here\n", - }, - - // Unchunked HTTP/1.1 204 response without Content-Length. - { - "HTTP/1.1 204 No Content\r\n" + - "\r\n" + - "Body should not be read!\n", - - Response{ - Status: "204 No Content", - StatusCode: 204, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: Header{}, - Request: dummyReq("GET"), - Close: false, - ContentLength: 0, - }, - - "", - }, - - // Unchunked response with Content-Length. - { - "HTTP/1.0 200 OK\r\n" + - "Content-Length: 10\r\n" + - "Connection: close\r\n" + - "\r\n" + - "Body here\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("GET"), - Header: Header{ - "Connection": {"close"}, - "Content-Length": {"10"}, - }, - Close: true, - ContentLength: 10, - }, - - "Body here\n", - }, - - // Chunked response without Content-Length. - { - "HTTP/1.1 200 OK\r\n" + - "Transfer-Encoding: chunked\r\n" + - "\r\n" + - "0a\r\n" + - "Body here\n\r\n" + - "09\r\n" + - "continued\r\n" + - "0\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{}, - Close: false, - ContentLength: -1, - TransferEncoding: []string{"chunked"}, - }, - - "Body here\ncontinued", - }, - - // Chunked response with Content-Length. - { - "HTTP/1.1 200 OK\r\n" + - "Transfer-Encoding: chunked\r\n" + - "Content-Length: 10\r\n" + - "\r\n" + - "0a\r\n" + - "Body here\n\r\n" + - "0\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{}, - Close: false, - ContentLength: -1, - TransferEncoding: []string{"chunked"}, - }, - - "Body here\n", - }, - - // Chunked response in response to a HEAD request - { - "HTTP/1.1 200 OK\r\n" + - "Transfer-Encoding: chunked\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("HEAD"), - Header: Header{}, - TransferEncoding: []string{"chunked"}, - Close: false, - ContentLength: -1, - }, - - "", - }, - - // Content-Length in response to a HEAD request - { - "HTTP/1.0 200 OK\r\n" + - "Content-Length: 256\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("HEAD"), - Header: Header{"Content-Length": {"256"}}, - TransferEncoding: nil, - Close: true, - ContentLength: 256, - }, - - "", - }, - - // Content-Length in response to a HEAD request with HTTP/1.1 - { - "HTTP/1.1 200 OK\r\n" + - "Content-Length: 256\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("HEAD"), - Header: Header{"Content-Length": {"256"}}, - TransferEncoding: nil, - Close: false, - ContentLength: 256, - }, - - "", - }, - - // No Content-Length or Chunked in response to a HEAD request - { - "HTTP/1.0 200 OK\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("HEAD"), - Header: Header{}, - TransferEncoding: nil, - Close: true, - ContentLength: -1, - }, - - "", - }, - - // explicit Content-Length of 0. - { - "HTTP/1.1 200 OK\r\n" + - "Content-Length: 0\r\n" + - "\r\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{ - "Content-Length": {"0"}, - }, - Close: false, - ContentLength: 0, - }, - - "", - }, - - // Status line without a Reason-Phrase, but trailing space. - // (permitted by RFC 2616) - { - "HTTP/1.0 303 \r\n\r\n", - Response{ - Status: "303 ", - StatusCode: 303, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("GET"), - Header: Header{}, - Close: true, - ContentLength: -1, - }, - - "", - }, - - // Status line without a Reason-Phrase, and no trailing space. - // (not permitted by RFC 2616, but we'll accept it anyway) - { - "HTTP/1.0 303\r\n\r\n", - Response{ - Status: "303 ", - StatusCode: 303, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("GET"), - Header: Header{}, - Close: true, - ContentLength: -1, - }, - - "", - }, - - // golang.org/issue/4767: don't special-case multipart/byteranges responses - { - `HTTP/1.1 206 Partial Content -Connection: close -Content-Type: multipart/byteranges; boundary=18a75608c8f47cef - -some body`, - Response{ - Status: "206 Partial Content", - StatusCode: 206, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{ - "Content-Type": []string{"multipart/byteranges; boundary=18a75608c8f47cef"}, - }, - Close: true, - ContentLength: -1, - }, - - "some body", - }, - - // Unchunked response without Content-Length, Request is nil - { - "HTTP/1.0 200 OK\r\n" + - "Connection: close\r\n" + - "\r\n" + - "Body here\n", - - Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.0", - ProtoMajor: 1, - ProtoMinor: 0, - Header: Header{ - "Connection": {"close"}, // TODO(rsc): Delete? - }, - Close: true, - ContentLength: -1, - }, - - "Body here\n", - }, -} - -func TestReadResponse(t *testing.T) { - for i, tt := range respTests { - resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request) - if err != nil { - t.Errorf("#%d: %v", i, err) - continue - } - rbody := resp.Body - resp.Body = nil - diff(t, fmt.Sprintf("#%d Response", i), resp, &tt.Resp) - var bout bytes.Buffer - if rbody != nil { - _, err = io.Copy(&bout, rbody) - if err != nil { - t.Errorf("#%d: %v", i, err) - continue - } - rbody.Close() - } - body := bout.String() - if body != tt.Body { - t.Errorf("#%d: Body = %q want %q", i, body, tt.Body) - } - } -} - -func TestWriteResponse(t *testing.T) { - for i, tt := range respTests { - resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request) - if err != nil { - t.Errorf("#%d: %v", i, err) - continue - } - err = resp.Write(ioutil.Discard) - if err != nil { - t.Errorf("#%d: %v", i, err) - continue - } - } -} - -var readResponseCloseInMiddleTests = []struct { - chunked, compressed bool -}{ - {false, false}, - {true, false}, - {true, true}, -} - -// TestReadResponseCloseInMiddle tests that closing a body after -// reading only part of its contents advances the read to the end of -// the request, right up until the next request. -func TestReadResponseCloseInMiddle(t *testing.T) { - for _, test := range readResponseCloseInMiddleTests { - fatalf := func(format string, args ...interface{}) { - args = append([]interface{}{test.chunked, test.compressed}, args...) - t.Fatalf("on test chunked=%v, compressed=%v: "+format, args...) - } - checkErr := func(err error, msg string) { - if err == nil { - return - } - fatalf(msg+": %v", err) - } - var buf bytes.Buffer - buf.WriteString("HTTP/1.1 200 OK\r\n") - if test.chunked { - buf.WriteString("Transfer-Encoding: chunked\r\n") - } else { - buf.WriteString("Content-Length: 1000000\r\n") - } - var wr io.Writer = &buf - if test.chunked { - wr = newChunkedWriter(wr) - } - if test.compressed { - buf.WriteString("Content-Encoding: gzip\r\n") - wr = gzip.NewWriter(wr) - } - buf.WriteString("\r\n") - - chunk := bytes.Repeat([]byte{'x'}, 1000) - for i := 0; i < 1000; i++ { - if test.compressed { - // Otherwise this compresses too well. - _, err := io.ReadFull(rand.Reader, chunk) - checkErr(err, "rand.Reader ReadFull") - } - wr.Write(chunk) - } - if test.compressed { - err := wr.(*gzip.Writer).Close() - checkErr(err, "compressor close") - } - if test.chunked { - buf.WriteString("0\r\n\r\n") - } - buf.WriteString("Next Request Here") - - bufr := bufio.NewReader(&buf) - resp, err := ReadResponse(bufr, dummyReq("GET")) - checkErr(err, "ReadResponse") - expectedLength := int64(-1) - if !test.chunked { - expectedLength = 1000000 - } - if resp.ContentLength != expectedLength { - fatalf("expected response length %d, got %d", expectedLength, resp.ContentLength) - } - if resp.Body == nil { - fatalf("nil body") - } - if test.compressed { - gzReader, err := gzip.NewReader(resp.Body) - checkErr(err, "gzip.NewReader") - resp.Body = &readerAndCloser{gzReader, resp.Body} - } - - rbuf := make([]byte, 2500) - n, err := io.ReadFull(resp.Body, rbuf) - checkErr(err, "2500 byte ReadFull") - if n != 2500 { - fatalf("ReadFull only read %d bytes", n) - } - if test.compressed == false && !bytes.Equal(bytes.Repeat([]byte{'x'}, 2500), rbuf) { - fatalf("ReadFull didn't read 2500 'x'; got %q", string(rbuf)) - } - resp.Body.Close() - - rest, err := ioutil.ReadAll(bufr) - checkErr(err, "ReadAll on remainder") - if e, g := "Next Request Here", string(rest); e != g { - g = regexp.MustCompile(`(xx+)`).ReplaceAllStringFunc(g, func(match string) string { - return fmt.Sprintf("x(repeated x%d)", len(match)) - }) - fatalf("remainder = %q, expected %q", g, e) - } - } -} - -func diff(t *testing.T, prefix string, have, want interface{}) { - hv := reflect.ValueOf(have).Elem() - wv := reflect.ValueOf(want).Elem() - if hv.Type() != wv.Type() { - t.Errorf("%s: type mismatch %v want %v", prefix, hv.Type(), wv.Type()) - } - for i := 0; i < hv.NumField(); i++ { - hf := hv.Field(i).Interface() - wf := wv.Field(i).Interface() - if !reflect.DeepEqual(hf, wf) { - t.Errorf("%s: %s = %v want %v", prefix, hv.Type().Field(i).Name, hf, wf) - } - } -} - -type responseLocationTest struct { - location string // Response's Location header or "" - requrl string // Response.Request.URL or "" - want string - wantErr error -} - -var responseLocationTests = []responseLocationTest{ - {"/foo", "http://bar.com/baz", "http://bar.com/foo", nil}, - {"http://foo.com/", "http://bar.com/baz", "http://foo.com/", nil}, - {"", "http://bar.com/baz", "", ErrNoLocation}, -} - -func TestLocationResponse(t *testing.T) { - for i, tt := range responseLocationTests { - res := new(Response) - res.Header = make(Header) - res.Header.Set("Location", tt.location) - if tt.requrl != "" { - res.Request = &Request{} - var err error - res.Request.URL, err = url.Parse(tt.requrl) - if err != nil { - t.Fatalf("bad test URL %q: %v", tt.requrl, err) - } - } - - got, err := res.Location() - if tt.wantErr != nil { - if err == nil { - t.Errorf("%d. err=nil; want %q", i, tt.wantErr) - continue - } - if g, e := err.Error(), tt.wantErr.Error(); g != e { - t.Errorf("%d. err=%q; want %q", i, g, e) - continue - } - continue - } - if err != nil { - t.Errorf("%d. err=%q", i, err) - continue - } - if g, e := got.String(), tt.want; g != e { - t.Errorf("%d. Location=%q; want %q", i, g, e) - } - } -} - -func TestResponseStatusStutter(t *testing.T) { - r := &Response{ - Status: "123 some status", - StatusCode: 123, - ProtoMajor: 1, - ProtoMinor: 3, - } - var buf bytes.Buffer - r.Write(&buf) - if strings.Contains(buf.String(), "123 123") { - t.Errorf("stutter in status: %s", buf.String()) - } -} - -func TestResponseContentLengthShortBody(t *testing.T) { - const shortBody = "Short body, not 123 bytes." - br := bufio.NewReader(strings.NewReader("HTTP/1.1 200 OK\r\n" + - "Content-Length: 123\r\n" + - "\r\n" + - shortBody)) - res, err := ReadResponse(br, &Request{Method: "GET"}) - if err != nil { - t.Fatal(err) - } - if res.ContentLength != 123 { - t.Fatalf("Content-Length = %d; want 123", res.ContentLength) - } - var buf bytes.Buffer - n, err := io.Copy(&buf, res.Body) - if n != int64(len(shortBody)) { - t.Errorf("Copied %d bytes; want %d, len(%q)", n, len(shortBody), shortBody) - } - if buf.String() != shortBody { - t.Errorf("Read body %q; want %q", buf.String(), shortBody) - } - if err != io.ErrUnexpectedEOF { - t.Errorf("io.Copy error = %#v; want io.ErrUnexpectedEOF", err) - } -} - -func TestReadResponseUnexpectedEOF(t *testing.T) { - br := bufio.NewReader(strings.NewReader("HTTP/1.1 301 Moved Permanently\r\n" + - "Location: http://example.com")) - _, err := ReadResponse(br, nil) - if err != io.ErrUnexpectedEOF { - t.Errorf("ReadResponse = %v; want io.ErrUnexpectedEOF", err) - } -} - -func TestNeedsSniff(t *testing.T) { - // needsSniff returns true with an empty response. - r := &response{} - if got, want := r.needsSniff(), true; got != want { - t.Errorf("needsSniff = %t; want %t", got, want) - } - // needsSniff returns false when Content-Type = nil. - r.handlerHeader = Header{"Content-Type": nil} - if got, want := r.needsSniff(), false; got != want { - t.Errorf("needsSniff empty Content-Type = %t; want %t", got, want) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/responsewrite_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/responsewrite_test.go deleted file mode 100644 index 585b13b850..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/responsewrite_test.go +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bytes" - "io/ioutil" - "strings" - "testing" -) - -type respWriteTest struct { - Resp Response - Raw string -} - -func TestResponseWrite(t *testing.T) { - respWriteTests := []respWriteTest{ - // HTTP/1.0, identity coding; no trailer - { - Response{ - StatusCode: 503, - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("abcdef")), - ContentLength: 6, - }, - - "HTTP/1.0 503 Service Unavailable\r\n" + - "Content-Length: 6\r\n\r\n" + - "abcdef", - }, - // Unchunked response without Content-Length. - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 0, - Request: dummyReq("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("abcdef")), - ContentLength: -1, - }, - "HTTP/1.0 200 OK\r\n" + - "\r\n" + - "abcdef", - }, - // HTTP/1.1 response with unknown length and Connection: close - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("abcdef")), - ContentLength: -1, - Close: true, - }, - "HTTP/1.1 200 OK\r\n" + - "Connection: close\r\n" + - "\r\n" + - "abcdef", - }, - // HTTP/1.1 response with unknown length and not setting connection: close - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq11("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("abcdef")), - ContentLength: -1, - Close: false, - }, - "HTTP/1.1 200 OK\r\n" + - "Connection: close\r\n" + - "\r\n" + - "abcdef", - }, - // HTTP/1.1 response with unknown length and not setting connection: close, but - // setting chunked. - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq11("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("abcdef")), - ContentLength: -1, - TransferEncoding: []string{"chunked"}, - Close: false, - }, - "HTTP/1.1 200 OK\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - "6\r\nabcdef\r\n0\r\n\r\n", - }, - // HTTP/1.1 response 0 content-length, and nil body - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq11("GET"), - Header: Header{}, - Body: nil, - ContentLength: 0, - Close: false, - }, - "HTTP/1.1 200 OK\r\n" + - "Content-Length: 0\r\n" + - "\r\n", - }, - // HTTP/1.1 response 0 content-length, and non-nil empty body - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq11("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("")), - ContentLength: 0, - Close: false, - }, - "HTTP/1.1 200 OK\r\n" + - "Content-Length: 0\r\n" + - "\r\n", - }, - // HTTP/1.1 response 0 content-length, and non-nil non-empty body - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq11("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("foo")), - ContentLength: 0, - Close: false, - }, - "HTTP/1.1 200 OK\r\n" + - "Connection: close\r\n" + - "\r\nfoo", - }, - // HTTP/1.1, chunked coding; empty trailer; close - { - Response{ - StatusCode: 200, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{}, - Body: ioutil.NopCloser(strings.NewReader("abcdef")), - ContentLength: 6, - TransferEncoding: []string{"chunked"}, - Close: true, - }, - - "HTTP/1.1 200 OK\r\n" + - "Connection: close\r\n" + - "Transfer-Encoding: chunked\r\n\r\n" + - "6\r\nabcdef\r\n0\r\n\r\n", - }, - - // Header value with a newline character (Issue 914). - // Also tests removal of leading and trailing whitespace. - { - Response{ - StatusCode: 204, - ProtoMajor: 1, - ProtoMinor: 1, - Request: dummyReq("GET"), - Header: Header{ - "Foo": []string{" Bar\nBaz "}, - }, - Body: nil, - ContentLength: 0, - TransferEncoding: []string{"chunked"}, - Close: true, - }, - - "HTTP/1.1 204 No Content\r\n" + - "Connection: close\r\n" + - "Foo: Bar Baz\r\n" + - "\r\n", - }, - - // Want a single Content-Length header. Fixing issue 8180 where - // there were two. - { - Response{ - StatusCode: StatusOK, - ProtoMajor: 1, - ProtoMinor: 1, - Request: &Request{Method: "POST"}, - Header: Header{}, - ContentLength: 0, - TransferEncoding: nil, - Body: nil, - }, - "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n", - }, - } - - for i := range respWriteTests { - tt := &respWriteTests[i] - var braw bytes.Buffer - err := tt.Resp.Write(&braw) - if err != nil { - t.Errorf("error writing #%d: %s", i, err) - continue - } - sraw := braw.String() - if sraw != tt.Raw { - t.Errorf("Test %d, expecting:\n%q\nGot:\n%q\n", i, tt.Raw, sraw) - continue - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/serve_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/serve_test.go deleted file mode 100644 index 9e4d226bfe..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/serve_test.go +++ /dev/null @@ -1,2848 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// End-to-end serving tests - -package http_test - -import ( - "bufio" - "bytes" - "crypto/tls" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net" - . "net/http" - "net/http/httptest" - "net/http/httputil" - "net/url" - "os" - "os/exec" - "reflect" - "runtime" - "strconv" - "strings" - "sync" - "sync/atomic" - "syscall" - "testing" - "time" -) - -type dummyAddr string -type oneConnListener struct { - conn net.Conn -} - -func (l *oneConnListener) Accept() (c net.Conn, err error) { - c = l.conn - if c == nil { - err = io.EOF - return - } - err = nil - l.conn = nil - return -} - -func (l *oneConnListener) Close() error { - return nil -} - -func (l *oneConnListener) Addr() net.Addr { - return dummyAddr("test-address") -} - -func (a dummyAddr) Network() string { - return string(a) -} - -func (a dummyAddr) String() string { - return string(a) -} - -type noopConn struct{} - -func (noopConn) LocalAddr() net.Addr { return dummyAddr("local-addr") } -func (noopConn) RemoteAddr() net.Addr { return dummyAddr("remote-addr") } -func (noopConn) SetDeadline(t time.Time) error { return nil } -func (noopConn) SetReadDeadline(t time.Time) error { return nil } -func (noopConn) SetWriteDeadline(t time.Time) error { return nil } - -type rwTestConn struct { - io.Reader - io.Writer - noopConn - - closeFunc func() error // called if non-nil - closec chan bool // else, if non-nil, send value to it on close -} - -func (c *rwTestConn) Close() error { - if c.closeFunc != nil { - return c.closeFunc() - } - select { - case c.closec <- true: - default: - } - return nil -} - -type testConn struct { - readBuf bytes.Buffer - writeBuf bytes.Buffer - closec chan bool // if non-nil, send value to it on close - noopConn -} - -func (c *testConn) Read(b []byte) (int, error) { - return c.readBuf.Read(b) -} - -func (c *testConn) Write(b []byte) (int, error) { - return c.writeBuf.Write(b) -} - -func (c *testConn) Close() error { - select { - case c.closec <- true: - default: - } - return nil -} - -// reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters, -// ending in \r\n\r\n -func reqBytes(req string) []byte { - return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n") -} - -type handlerTest struct { - handler Handler -} - -func newHandlerTest(h Handler) handlerTest { - return handlerTest{h} -} - -func (ht handlerTest) rawResponse(req string) string { - reqb := reqBytes(req) - var output bytes.Buffer - conn := &rwTestConn{ - Reader: bytes.NewReader(reqb), - Writer: &output, - closec: make(chan bool, 1), - } - ln := &oneConnListener{conn: conn} - go Serve(ln, ht.handler) - <-conn.closec - return output.String() -} - -func TestConsumingBodyOnNextConn(t *testing.T) { - conn := new(testConn) - for i := 0; i < 2; i++ { - conn.readBuf.Write([]byte( - "POST / HTTP/1.1\r\n" + - "Host: test\r\n" + - "Content-Length: 11\r\n" + - "\r\n" + - "foo=1&bar=1")) - } - - reqNum := 0 - ch := make(chan *Request) - servech := make(chan error) - listener := &oneConnListener{conn} - handler := func(res ResponseWriter, req *Request) { - reqNum++ - ch <- req - } - - go func() { - servech <- Serve(listener, HandlerFunc(handler)) - }() - - var req *Request - req = <-ch - if req == nil { - t.Fatal("Got nil first request.") - } - if req.Method != "POST" { - t.Errorf("For request #1's method, got %q; expected %q", - req.Method, "POST") - } - - req = <-ch - if req == nil { - t.Fatal("Got nil first request.") - } - if req.Method != "POST" { - t.Errorf("For request #2's method, got %q; expected %q", - req.Method, "POST") - } - - if serveerr := <-servech; serveerr != io.EOF { - t.Errorf("Serve returned %q; expected EOF", serveerr) - } -} - -type stringHandler string - -func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) { - w.Header().Set("Result", string(s)) -} - -var handlers = []struct { - pattern string - msg string -}{ - {"/", "Default"}, - {"/someDir/", "someDir"}, - {"someHost.com/someDir/", "someHost.com/someDir"}, -} - -var vtests = []struct { - url string - expected string -}{ - {"http://localhost/someDir/apage", "someDir"}, - {"http://localhost/otherDir/apage", "Default"}, - {"http://someHost.com/someDir/apage", "someHost.com/someDir"}, - {"http://otherHost.com/someDir/apage", "someDir"}, - {"http://otherHost.com/aDir/apage", "Default"}, - // redirections for trees - {"http://localhost/someDir", "/someDir/"}, - {"http://someHost.com/someDir", "/someDir/"}, -} - -func TestHostHandlers(t *testing.T) { - defer afterTest(t) - mux := NewServeMux() - for _, h := range handlers { - mux.Handle(h.pattern, stringHandler(h.msg)) - } - ts := httptest.NewServer(mux) - defer ts.Close() - - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - defer conn.Close() - cc := httputil.NewClientConn(conn, nil) - for _, vt := range vtests { - var r *Response - var req Request - if req.URL, err = url.Parse(vt.url); err != nil { - t.Errorf("cannot parse url: %v", err) - continue - } - if err := cc.Write(&req); err != nil { - t.Errorf("writing request: %v", err) - continue - } - r, err := cc.Read(&req) - if err != nil { - t.Errorf("reading response: %v", err) - continue - } - switch r.StatusCode { - case StatusOK: - s := r.Header.Get("Result") - if s != vt.expected { - t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected) - } - case StatusMovedPermanently: - s := r.Header.Get("Location") - if s != vt.expected { - t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected) - } - default: - t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode) - } - } -} - -var serveMuxRegister = []struct { - pattern string - h Handler -}{ - {"/dir/", serve(200)}, - {"/search", serve(201)}, - {"codesearch.google.com/search", serve(202)}, - {"codesearch.google.com/", serve(203)}, - {"example.com/", HandlerFunc(checkQueryStringHandler)}, -} - -// serve returns a handler that sends a response with the given code. -func serve(code int) HandlerFunc { - return func(w ResponseWriter, r *Request) { - w.WriteHeader(code) - } -} - -// checkQueryStringHandler checks if r.URL.RawQuery has the same value -// as the URL excluding the scheme and the query string and sends 200 -// response code if it is, 500 otherwise. -func checkQueryStringHandler(w ResponseWriter, r *Request) { - u := *r.URL - u.Scheme = "http" - u.Host = r.Host - u.RawQuery = "" - if "http://"+r.URL.RawQuery == u.String() { - w.WriteHeader(200) - } else { - w.WriteHeader(500) - } -} - -var serveMuxTests = []struct { - method string - host string - path string - code int - pattern string -}{ - {"GET", "google.com", "/", 404, ""}, - {"GET", "google.com", "/dir", 301, "/dir/"}, - {"GET", "google.com", "/dir/", 200, "/dir/"}, - {"GET", "google.com", "/dir/file", 200, "/dir/"}, - {"GET", "google.com", "/search", 201, "/search"}, - {"GET", "google.com", "/search/", 404, ""}, - {"GET", "google.com", "/search/foo", 404, ""}, - {"GET", "codesearch.google.com", "/search", 202, "codesearch.google.com/search"}, - {"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"}, - {"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"}, - {"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"}, - {"GET", "images.google.com", "/search", 201, "/search"}, - {"GET", "images.google.com", "/search/", 404, ""}, - {"GET", "images.google.com", "/search/foo", 404, ""}, - {"GET", "google.com", "/../search", 301, "/search"}, - {"GET", "google.com", "/dir/..", 301, ""}, - {"GET", "google.com", "/dir/..", 301, ""}, - {"GET", "google.com", "/dir/./file", 301, "/dir/"}, - - // The /foo -> /foo/ redirect applies to CONNECT requests - // but the path canonicalization does not. - {"CONNECT", "google.com", "/dir", 301, "/dir/"}, - {"CONNECT", "google.com", "/../search", 404, ""}, - {"CONNECT", "google.com", "/dir/..", 200, "/dir/"}, - {"CONNECT", "google.com", "/dir/..", 200, "/dir/"}, - {"CONNECT", "google.com", "/dir/./file", 200, "/dir/"}, -} - -func TestServeMuxHandler(t *testing.T) { - mux := NewServeMux() - for _, e := range serveMuxRegister { - mux.Handle(e.pattern, e.h) - } - - for _, tt := range serveMuxTests { - r := &Request{ - Method: tt.method, - Host: tt.host, - URL: &url.URL{ - Path: tt.path, - }, - } - h, pattern := mux.Handler(r) - rr := httptest.NewRecorder() - h.ServeHTTP(rr, r) - if pattern != tt.pattern || rr.Code != tt.code { - t.Errorf("%s %s %s = %d, %q, want %d, %q", tt.method, tt.host, tt.path, rr.Code, pattern, tt.code, tt.pattern) - } - } -} - -var serveMuxTests2 = []struct { - method string - host string - url string - code int - redirOk bool -}{ - {"GET", "google.com", "/", 404, false}, - {"GET", "example.com", "/test/?example.com/test/", 200, false}, - {"GET", "example.com", "test/?example.com/test/", 200, true}, -} - -// TestServeMuxHandlerRedirects tests that automatic redirects generated by -// mux.Handler() shouldn't clear the request's query string. -func TestServeMuxHandlerRedirects(t *testing.T) { - mux := NewServeMux() - for _, e := range serveMuxRegister { - mux.Handle(e.pattern, e.h) - } - - for _, tt := range serveMuxTests2 { - tries := 1 - turl := tt.url - for tries > 0 { - u, e := url.Parse(turl) - if e != nil { - t.Fatal(e) - } - r := &Request{ - Method: tt.method, - Host: tt.host, - URL: u, - } - h, _ := mux.Handler(r) - rr := httptest.NewRecorder() - h.ServeHTTP(rr, r) - if rr.Code != 301 { - if rr.Code != tt.code { - t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code) - } - break - } - if !tt.redirOk { - t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url) - break - } - turl = rr.HeaderMap.Get("Location") - tries-- - } - if tries < 0 { - t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url) - } - } -} - -// Tests for http://code.google.com/p/go/issues/detail?id=900 -func TestMuxRedirectLeadingSlashes(t *testing.T) { - paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"} - for _, path := range paths { - req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n"))) - if err != nil { - t.Errorf("%s", err) - } - mux := NewServeMux() - resp := httptest.NewRecorder() - - mux.ServeHTTP(resp, req) - - if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected { - t.Errorf("Expected Location header set to %q; got %q", expected, loc) - return - } - - if code, expected := resp.Code, StatusMovedPermanently; code != expected { - t.Errorf("Expected response code of StatusMovedPermanently; got %d", code) - return - } - } -} - -func TestServerTimeouts(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - reqNum := 0 - ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) { - reqNum++ - fmt.Fprintf(res, "req=%d", reqNum) - })) - ts.Config.ReadTimeout = 250 * time.Millisecond - ts.Config.WriteTimeout = 250 * time.Millisecond - ts.Start() - defer ts.Close() - - // Hit the HTTP server successfully. - tr := &Transport{DisableKeepAlives: true} // they interfere with this test - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - r, err := c.Get(ts.URL) - if err != nil { - t.Fatalf("http Get #1: %v", err) - } - got, _ := ioutil.ReadAll(r.Body) - expected := "req=1" - if string(got) != expected { - t.Errorf("Unexpected response for request #1; got %q; expected %q", - string(got), expected) - } - - // Slow client that should timeout. - t1 := time.Now() - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - buf := make([]byte, 1) - n, err := conn.Read(buf) - latency := time.Since(t1) - if n != 0 || err != io.EOF { - t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF) - } - if latency < 200*time.Millisecond /* fudge from 250 ms above */ { - t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond) - } - - // Hit the HTTP server successfully again, verifying that the - // previous slow connection didn't run our handler. (that we - // get "req=2", not "req=3") - r, err = Get(ts.URL) - if err != nil { - t.Fatalf("http Get #2: %v", err) - } - got, _ = ioutil.ReadAll(r.Body) - expected = "req=2" - if string(got) != expected { - t.Errorf("Get #2 got %q, want %q", string(got), expected) - } - - if !testing.Short() { - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer conn.Close() - go io.Copy(ioutil.Discard, conn) - for i := 0; i < 5; i++ { - _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")) - if err != nil { - t.Fatalf("on write %d: %v", i, err) - } - time.Sleep(ts.Config.ReadTimeout / 2) - } - } -} - -// golang.org/issue/4741 -- setting only a write timeout that triggers -// shouldn't cause a handler to block forever on reads (next HTTP -// request) that will never happen. -func TestOnlyWriteTimeout(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - var conn net.Conn - var afterTimeoutErrc = make(chan error, 1) - ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) { - buf := make([]byte, 512<<10) - _, err := w.Write(buf) - if err != nil { - t.Errorf("handler Write error: %v", err) - return - } - conn.SetWriteDeadline(time.Now().Add(-30 * time.Second)) - _, err = w.Write(buf) - afterTimeoutErrc <- err - })) - ts.Listener = trackLastConnListener{ts.Listener, &conn} - ts.Start() - defer ts.Close() - - tr := &Transport{DisableKeepAlives: false} - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - errc := make(chan error) - go func() { - res, err := c.Get(ts.URL) - if err != nil { - errc <- err - return - } - _, err = io.Copy(ioutil.Discard, res.Body) - errc <- err - }() - select { - case err := <-errc: - if err == nil { - t.Errorf("expected an error from Get request") - } - case <-time.After(5 * time.Second): - t.Fatal("timeout waiting for Get error") - } - if err := <-afterTimeoutErrc; err == nil { - t.Error("expected write error after timeout") - } -} - -// trackLastConnListener tracks the last net.Conn that was accepted. -type trackLastConnListener struct { - net.Listener - last *net.Conn // destination -} - -func (l trackLastConnListener) Accept() (c net.Conn, err error) { - c, err = l.Listener.Accept() - *l.last = c - return -} - -// TestIdentityResponse verifies that a handler can unset -func TestIdentityResponse(t *testing.T) { - defer afterTest(t) - handler := HandlerFunc(func(rw ResponseWriter, req *Request) { - rw.Header().Set("Content-Length", "3") - rw.Header().Set("Transfer-Encoding", req.FormValue("te")) - switch { - case req.FormValue("overwrite") == "1": - _, err := rw.Write([]byte("foo TOO LONG")) - if err != ErrContentLength { - t.Errorf("expected ErrContentLength; got %v", err) - } - case req.FormValue("underwrite") == "1": - rw.Header().Set("Content-Length", "500") - rw.Write([]byte("too short")) - default: - rw.Write([]byte("foo")) - } - }) - - ts := httptest.NewServer(handler) - defer ts.Close() - - // Note: this relies on the assumption (which is true) that - // Get sends HTTP/1.1 or greater requests. Otherwise the - // server wouldn't have the choice to send back chunked - // responses. - for _, te := range []string{"", "identity"} { - url := ts.URL + "/?te=" + te - res, err := Get(url) - if err != nil { - t.Fatalf("error with Get of %s: %v", url, err) - } - if cl, expected := res.ContentLength, int64(3); cl != expected { - t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl) - } - if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected { - t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl) - } - if tl, expected := len(res.TransferEncoding), 0; tl != expected { - t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)", - url, expected, tl, res.TransferEncoding) - } - res.Body.Close() - } - - // Verify that ErrContentLength is returned - url := ts.URL + "/?overwrite=1" - res, err := Get(url) - if err != nil { - t.Fatalf("error with Get of %s: %v", url, err) - } - res.Body.Close() - - // Verify that the connection is closed when the declared Content-Length - // is larger than what the handler wrote. - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("error dialing: %v", err) - } - _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n")) - if err != nil { - t.Fatalf("error writing: %v", err) - } - - // The ReadAll will hang for a failing test, so use a Timer to - // fail explicitly. - goTimeout(t, 2*time.Second, func() { - got, _ := ioutil.ReadAll(conn) - expectedSuffix := "\r\n\r\ntoo short" - if !strings.HasSuffix(string(got), expectedSuffix) { - t.Errorf("Expected output to end with %q; got response body %q", - expectedSuffix, string(got)) - } - }) -} - -func testTCPConnectionCloses(t *testing.T, req string, h Handler) { - defer afterTest(t) - s := httptest.NewServer(h) - defer s.Close() - - conn, err := net.Dial("tcp", s.Listener.Addr().String()) - if err != nil { - t.Fatal("dial error:", err) - } - defer conn.Close() - - _, err = fmt.Fprint(conn, req) - if err != nil { - t.Fatal("print error:", err) - } - - r := bufio.NewReader(conn) - res, err := ReadResponse(r, &Request{Method: "GET"}) - if err != nil { - t.Fatal("ReadResponse error:", err) - } - - didReadAll := make(chan bool, 1) - go func() { - select { - case <-time.After(5 * time.Second): - t.Error("body not closed after 5s") - return - case <-didReadAll: - } - }() - - _, err = ioutil.ReadAll(r) - if err != nil { - t.Fatal("read error:", err) - } - didReadAll <- true - - if !res.Close { - t.Errorf("Response.Close = false; want true") - } -} - -// TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive. -func TestServeHTTP10Close(t *testing.T) { - testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { - ServeFile(w, r, "testdata/file") - })) -} - -// TestClientCanClose verifies that clients can also force a connection to close. -func TestClientCanClose(t *testing.T) { - testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { - // Nothing. - })) -} - -// TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close, -// even for HTTP/1.1 requests. -func TestHandlersCanSetConnectionClose11(t *testing.T) { - testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Connection", "close") - })) -} - -func TestHandlersCanSetConnectionClose10(t *testing.T) { - testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Connection", "close") - })) -} - -func TestSetsRemoteAddr(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - fmt.Fprintf(w, "%s", r.RemoteAddr) - })) - defer ts.Close() - - res, err := Get(ts.URL) - if err != nil { - t.Fatalf("Get error: %v", err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("ReadAll error: %v", err) - } - ip := string(body) - if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") { - t.Fatalf("Expected local addr; got %q", ip) - } -} - -func TestChunkedResponseHeaders(t *testing.T) { - defer afterTest(t) - log.SetOutput(ioutil.Discard) // is noisy otherwise - defer log.SetOutput(os.Stderr) - - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted - w.(Flusher).Flush() - fmt.Fprintf(w, "I am a chunked response.") - })) - defer ts.Close() - - res, err := Get(ts.URL) - if err != nil { - t.Fatalf("Get error: %v", err) - } - defer res.Body.Close() - if g, e := res.ContentLength, int64(-1); g != e { - t.Errorf("expected ContentLength of %d; got %d", e, g) - } - if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) { - t.Errorf("expected TransferEncoding of %v; got %v", e, g) - } - if _, haveCL := res.Header["Content-Length"]; haveCL { - t.Errorf("Unexpected Content-Length") - } -} - -// Test304Responses verifies that 304s don't declare that they're -// chunking in their response headers and aren't allowed to produce -// output. -func Test304Responses(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.WriteHeader(StatusNotModified) - _, err := w.Write([]byte("illegal body")) - if err != ErrBodyNotAllowed { - t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err) - } - })) - defer ts.Close() - res, err := Get(ts.URL) - if err != nil { - t.Error(err) - } - if len(res.TransferEncoding) > 0 { - t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Error(err) - } - if len(body) > 0 { - t.Errorf("got unexpected body %q", string(body)) - } -} - -// TestHeadResponses verifies that all MIME type sniffing and Content-Length -// counting of GET requests also happens on HEAD requests. -func TestHeadResponses(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - _, err := w.Write([]byte("")) - if err != nil { - t.Errorf("ResponseWriter.Write: %v", err) - } - - // Also exercise the ReaderFrom path - _, err = io.Copy(w, strings.NewReader("789a")) - if err != nil { - t.Errorf("Copy(ResponseWriter, ...): %v", err) - } - })) - defer ts.Close() - res, err := Head(ts.URL) - if err != nil { - t.Error(err) - } - if len(res.TransferEncoding) > 0 { - t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) - } - if ct := res.Header.Get("Content-Type"); ct != "text/html; charset=utf-8" { - t.Errorf("Content-Type: %q; want text/html; charset=utf-8", ct) - } - if v := res.ContentLength; v != 10 { - t.Errorf("Content-Length: %d; want 10", v) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Error(err) - } - if len(body) > 0 { - t.Errorf("got unexpected body %q", string(body)) - } -} - -func TestTLSHandshakeTimeout(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) - errc := make(chanWriter, 10) // but only expecting 1 - ts.Config.ReadTimeout = 250 * time.Millisecond - ts.Config.ErrorLog = log.New(errc, "", 0) - ts.StartTLS() - defer ts.Close() - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer conn.Close() - goTimeout(t, 10*time.Second, func() { - var buf [1]byte - n, err := conn.Read(buf[:]) - if err == nil || n != 0 { - t.Errorf("Read = %d, %v; want an error and no bytes", n, err) - } - }) - select { - case v := <-errc: - if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") { - t.Errorf("expected a TLS handshake timeout error; got %q", v) - } - case <-time.After(5 * time.Second): - t.Errorf("timeout waiting for logged error") - } -} - -func TestTLSServer(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.TLS != nil { - w.Header().Set("X-TLS-Set", "true") - if r.TLS.HandshakeComplete { - w.Header().Set("X-TLS-HandshakeComplete", "true") - } - } - })) - ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) - defer ts.Close() - - // Connect an idle TCP connection to this server before we run - // our real tests. This idle connection used to block forever - // in the TLS handshake, preventing future connections from - // being accepted. It may prevent future accidental blocking - // in newConn. - idleConn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer idleConn.Close() - goTimeout(t, 10*time.Second, func() { - if !strings.HasPrefix(ts.URL, "https://") { - t.Errorf("expected test TLS server to start with https://, got %q", ts.URL) - return - } - noVerifyTransport := &Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - } - client := &Client{Transport: noVerifyTransport} - res, err := client.Get(ts.URL) - if err != nil { - t.Error(err) - return - } - if res == nil { - t.Errorf("got nil Response") - return - } - defer res.Body.Close() - if res.Header.Get("X-TLS-Set") != "true" { - t.Errorf("expected X-TLS-Set response header") - return - } - if res.Header.Get("X-TLS-HandshakeComplete") != "true" { - t.Errorf("expected X-TLS-HandshakeComplete header") - } - }) -} - -type serverExpectTest struct { - contentLength int // of request body - chunked bool - expectation string // e.g. "100-continue" - readBody bool // whether handler should read the body (if false, sends StatusUnauthorized) - expectedResponse string // expected substring in first line of http response -} - -func expectTest(contentLength int, expectation string, readBody bool, expectedResponse string) serverExpectTest { - return serverExpectTest{ - contentLength: contentLength, - expectation: expectation, - readBody: readBody, - expectedResponse: expectedResponse, - } -} - -var serverExpectTests = []serverExpectTest{ - // Normal 100-continues, case-insensitive. - expectTest(100, "100-continue", true, "100 Continue"), - expectTest(100, "100-cOntInUE", true, "100 Continue"), - - // No 100-continue. - expectTest(100, "", true, "200 OK"), - - // 100-continue but requesting client to deny us, - // so it never reads the body. - expectTest(100, "100-continue", false, "401 Unauthorized"), - // Likewise without 100-continue: - expectTest(100, "", false, "401 Unauthorized"), - - // Non-standard expectations are failures - expectTest(0, "a-pony", false, "417 Expectation Failed"), - - // Expect-100 requested but no body (is apparently okay: Issue 7625) - expectTest(0, "100-continue", true, "200 OK"), - // Expect-100 requested but handler doesn't read the body - expectTest(0, "100-continue", false, "401 Unauthorized"), - // Expect-100 continue with no body, but a chunked body. - { - expectation: "100-continue", - readBody: true, - chunked: true, - expectedResponse: "100 Continue", - }, -} - -// Tests that the server responds to the "Expect" request header -// correctly. -func TestServerExpect(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - // Note using r.FormValue("readbody") because for POST - // requests that would read from r.Body, which we only - // conditionally want to do. - if strings.Contains(r.URL.RawQuery, "readbody=true") { - ioutil.ReadAll(r.Body) - w.Write([]byte("Hi")) - } else { - w.WriteHeader(StatusUnauthorized) - } - })) - defer ts.Close() - - runTest := func(test serverExpectTest) { - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer conn.Close() - - // Only send the body immediately if we're acting like an HTTP client - // that doesn't send 100-continue expectations. - writeBody := test.contentLength != 0 && strings.ToLower(test.expectation) != "100-continue" - - go func() { - contentLen := fmt.Sprintf("Content-Length: %d", test.contentLength) - if test.chunked { - contentLen = "Transfer-Encoding: chunked" - } - _, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+ - "Connection: close\r\n"+ - "%s\r\n"+ - "Expect: %s\r\nHost: foo\r\n\r\n", - test.readBody, contentLen, test.expectation) - if err != nil { - t.Errorf("On test %#v, error writing request headers: %v", test, err) - return - } - if writeBody { - var targ io.WriteCloser = struct { - io.Writer - io.Closer - }{ - conn, - ioutil.NopCloser(nil), - } - if test.chunked { - targ = httputil.NewChunkedWriter(conn) - } - body := strings.Repeat("A", test.contentLength) - _, err = fmt.Fprint(targ, body) - if err == nil { - err = targ.Close() - } - if err != nil { - if !test.readBody { - // Server likely already hung up on us. - // See larger comment below. - t.Logf("On test %#v, acceptable error writing request body: %v", test, err) - return - } - t.Errorf("On test %#v, error writing request body: %v", test, err) - } - } - }() - bufr := bufio.NewReader(conn) - line, err := bufr.ReadString('\n') - if err != nil { - if writeBody && !test.readBody { - // This is an acceptable failure due to a possible TCP race: - // We were still writing data and the server hung up on us. A TCP - // implementation may send a RST if our request body data was known - // to be lost, which may trigger our reads to fail. - // See RFC 1122 page 88. - t.Logf("On test %#v, acceptable error from ReadString: %v", test, err) - return - } - t.Fatalf("On test %#v, ReadString: %v", test, err) - } - if !strings.Contains(line, test.expectedResponse) { - t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse) - } - } - - for _, test := range serverExpectTests { - runTest(test) - } -} - -// Under a ~256KB (maxPostHandlerReadBytes) threshold, the server -// should consume client request bodies that a handler didn't read. -func TestServerUnreadRequestBodyLittle(t *testing.T) { - conn := new(testConn) - body := strings.Repeat("x", 100<<10) - conn.readBuf.Write([]byte(fmt.Sprintf( - "POST / HTTP/1.1\r\n"+ - "Host: test\r\n"+ - "Content-Length: %d\r\n"+ - "\r\n", len(body)))) - conn.readBuf.Write([]byte(body)) - - done := make(chan bool) - - ls := &oneConnListener{conn} - go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { - defer close(done) - if conn.readBuf.Len() < len(body)/2 { - t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len()) - } - rw.WriteHeader(200) - rw.(Flusher).Flush() - if g, e := conn.readBuf.Len(), 0; g != e { - t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e) - } - if c := rw.Header().Get("Connection"); c != "" { - t.Errorf(`Connection header = %q; want ""`, c) - } - })) - <-done -} - -// Over a ~256KB (maxPostHandlerReadBytes) threshold, the server -// should ignore client request bodies that a handler didn't read -// and close the connection. -func TestServerUnreadRequestBodyLarge(t *testing.T) { - conn := new(testConn) - body := strings.Repeat("x", 1<<20) - conn.readBuf.Write([]byte(fmt.Sprintf( - "POST / HTTP/1.1\r\n"+ - "Host: test\r\n"+ - "Content-Length: %d\r\n"+ - "\r\n", len(body)))) - conn.readBuf.Write([]byte(body)) - conn.closec = make(chan bool, 1) - - ls := &oneConnListener{conn} - go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { - if conn.readBuf.Len() < len(body)/2 { - t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len()) - } - rw.WriteHeader(200) - rw.(Flusher).Flush() - if conn.readBuf.Len() < len(body)/2 { - t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len()) - } - })) - <-conn.closec - - if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") { - t.Errorf("Expected a Connection: close header; got response: %s", res) - } -} - -func TestTimeoutHandler(t *testing.T) { - defer afterTest(t) - sendHi := make(chan bool, 1) - writeErrors := make(chan error, 1) - sayHi := HandlerFunc(func(w ResponseWriter, r *Request) { - <-sendHi - _, werr := w.Write([]byte("hi")) - writeErrors <- werr - }) - timeout := make(chan time.Time, 1) // write to this to force timeouts - ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout)) - defer ts.Close() - - // Succeed without timing out: - sendHi <- true - res, err := Get(ts.URL) - if err != nil { - t.Error(err) - } - if g, e := res.StatusCode, StatusOK; g != e { - t.Errorf("got res.StatusCode %d; expected %d", g, e) - } - body, _ := ioutil.ReadAll(res.Body) - if g, e := string(body), "hi"; g != e { - t.Errorf("got body %q; expected %q", g, e) - } - if g := <-writeErrors; g != nil { - t.Errorf("got unexpected Write error on first request: %v", g) - } - - // Times out: - timeout <- time.Time{} - res, err = Get(ts.URL) - if err != nil { - t.Error(err) - } - if g, e := res.StatusCode, StatusServiceUnavailable; g != e { - t.Errorf("got res.StatusCode %d; expected %d", g, e) - } - body, _ = ioutil.ReadAll(res.Body) - if !strings.Contains(string(body), "Timeout") { - t.Errorf("expected timeout body; got %q", string(body)) - } - - // Now make the previously-timed out handler speak again, - // which verifies the panic is handled: - sendHi <- true - if g, e := <-writeErrors, ErrHandlerTimeout; g != e { - t.Errorf("expected Write error of %v; got %v", e, g) - } -} - -// Verifies we don't path.Clean() on the wrong parts in redirects. -func TestRedirectMunging(t *testing.T) { - req, _ := NewRequest("GET", "http://example.com/", nil) - - resp := httptest.NewRecorder() - Redirect(resp, req, "/foo?next=http://bar.com/", 302) - if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e { - t.Errorf("Location header was %q; want %q", g, e) - } - - resp = httptest.NewRecorder() - Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302) - if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e { - t.Errorf("Location header was %q; want %q", g, e) - } -} - -func TestRedirectBadPath(t *testing.T) { - // This used to crash. It's not valid input (bad path), but it - // shouldn't crash. - rr := httptest.NewRecorder() - req := &Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Path: "not-empty-but-no-leading-slash", // bogus - }, - } - Redirect(rr, req, "", 304) - if rr.Code != 304 { - t.Errorf("Code = %d; want 304", rr.Code) - } -} - -// TestZeroLengthPostAndResponse exercises an optimization done by the Transport: -// when there is no body (either because the method doesn't permit a body, or an -// explicit Content-Length of zero is present), then the transport can re-use the -// connection immediately. But when it re-uses the connection, it typically closes -// the previous request's body, which is not optimal for zero-lengthed bodies, -// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF. -func TestZeroLengthPostAndResponse(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { - all, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Fatalf("handler ReadAll: %v", err) - } - if len(all) != 0 { - t.Errorf("handler got %d bytes; expected 0", len(all)) - } - rw.Header().Set("Content-Length", "0") - })) - defer ts.Close() - - req, err := NewRequest("POST", ts.URL, strings.NewReader("")) - if err != nil { - t.Fatal(err) - } - req.ContentLength = 0 - - var resp [5]*Response - for i := range resp { - resp[i], err = DefaultClient.Do(req) - if err != nil { - t.Fatalf("client post #%d: %v", i, err) - } - } - - for i := range resp { - all, err := ioutil.ReadAll(resp[i].Body) - if err != nil { - t.Fatalf("req #%d: client ReadAll: %v", i, err) - } - if len(all) != 0 { - t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all)) - } - } -} - -func TestHandlerPanicNil(t *testing.T) { - testHandlerPanic(t, false, nil) -} - -func TestHandlerPanic(t *testing.T) { - testHandlerPanic(t, false, "intentional death for testing") -} - -func TestHandlerPanicWithHijack(t *testing.T) { - testHandlerPanic(t, true, "intentional death for testing") -} - -func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) { - defer afterTest(t) - // Unlike the other tests that set the log output to ioutil.Discard - // to quiet the output, this test uses a pipe. The pipe serves three - // purposes: - // - // 1) The log.Print from the http server (generated by the caught - // panic) will go to the pipe instead of stderr, making the - // output quiet. - // - // 2) We read from the pipe to verify that the handler - // actually caught the panic and logged something. - // - // 3) The blocking Read call prevents this TestHandlerPanic - // function from exiting before the HTTP server handler - // finishes crashing. If this text function exited too - // early (and its defer log.SetOutput(os.Stderr) ran), - // then the crash output could spill into the next test. - pr, pw := io.Pipe() - log.SetOutput(pw) - defer log.SetOutput(os.Stderr) - defer pw.Close() - - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if withHijack { - rwc, _, err := w.(Hijacker).Hijack() - if err != nil { - t.Logf("unexpected error: %v", err) - } - defer rwc.Close() - } - panic(panicValue) - })) - defer ts.Close() - - // Do a blocking read on the log output pipe so its logging - // doesn't bleed into the next test. But wait only 5 seconds - // for it. - done := make(chan bool, 1) - go func() { - buf := make([]byte, 4<<10) - _, err := pr.Read(buf) - pr.Close() - if err != nil && err != io.EOF { - t.Error(err) - } - done <- true - }() - - _, err := Get(ts.URL) - if err == nil { - t.Logf("expected an error") - } - - if panicValue == nil { - return - } - - select { - case <-done: - return - case <-time.After(5 * time.Second): - t.Fatal("expected server handler to log an error") - } -} - -func TestNoDate(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header()["Date"] = nil - })) - defer ts.Close() - res, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - _, present := res.Header["Date"] - if present { - t.Fatalf("Expected no Date header; got %v", res.Header["Date"]) - } -} - -func TestStripPrefix(t *testing.T) { - defer afterTest(t) - h := HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("X-Path", r.URL.Path) - }) - ts := httptest.NewServer(StripPrefix("/foo", h)) - defer ts.Close() - - res, err := Get(ts.URL + "/foo/bar") - if err != nil { - t.Fatal(err) - } - if g, e := res.Header.Get("X-Path"), "/bar"; g != e { - t.Errorf("test 1: got %s, want %s", g, e) - } - res.Body.Close() - - res, err = Get(ts.URL + "/bar") - if err != nil { - t.Fatal(err) - } - if g, e := res.StatusCode, 404; g != e { - t.Errorf("test 2: got status %v, want %v", g, e) - } - res.Body.Close() -} - -func TestRequestLimit(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - t.Fatalf("didn't expect to get request in Handler") - })) - defer ts.Close() - req, _ := NewRequest("GET", ts.URL, nil) - var bytesPerHeader = len("header12345: val12345\r\n") - for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ { - req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i)) - } - res, err := DefaultClient.Do(req) - if err != nil { - // Some HTTP clients may fail on this undefined behavior (server replying and - // closing the connection while the request is still being written), but - // we do support it (at least currently), so we expect a response below. - t.Fatalf("Do: %v", err) - } - defer res.Body.Close() - if res.StatusCode != 413 { - t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status) - } -} - -type neverEnding byte - -func (b neverEnding) Read(p []byte) (n int, err error) { - for i := range p { - p[i] = byte(b) - } - return len(p), nil -} - -type countReader struct { - r io.Reader - n *int64 -} - -func (cr countReader) Read(p []byte) (n int, err error) { - n, err = cr.r.Read(p) - atomic.AddInt64(cr.n, int64(n)) - return -} - -func TestRequestBodyLimit(t *testing.T) { - defer afterTest(t) - const limit = 1 << 20 - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - r.Body = MaxBytesReader(w, r.Body, limit) - n, err := io.Copy(ioutil.Discard, r.Body) - if err == nil { - t.Errorf("expected error from io.Copy") - } - if n != limit { - t.Errorf("io.Copy = %d, want %d", n, limit) - } - })) - defer ts.Close() - - nWritten := new(int64) - req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200)) - - // Send the POST, but don't care it succeeds or not. The - // remote side is going to reply and then close the TCP - // connection, and HTTP doesn't really define if that's - // allowed or not. Some HTTP clients will get the response - // and some (like ours, currently) will complain that the - // request write failed, without reading the response. - // - // But that's okay, since what we're really testing is that - // the remote side hung up on us before we wrote too much. - _, _ = DefaultClient.Do(req) - - if atomic.LoadInt64(nWritten) > limit*100 { - t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d", - limit, nWritten) - } -} - -// TestClientWriteShutdown tests that if the client shuts down the write -// side of their TCP connection, the server doesn't send a 400 Bad Request. -func TestClientWriteShutdown(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) - defer ts.Close() - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - err = conn.(*net.TCPConn).CloseWrite() - if err != nil { - t.Fatalf("Dial: %v", err) - } - donec := make(chan bool) - go func() { - defer close(donec) - bs, err := ioutil.ReadAll(conn) - if err != nil { - t.Fatalf("ReadAll: %v", err) - } - got := string(bs) - if got != "" { - t.Errorf("read %q from server; want nothing", got) - } - }() - select { - case <-donec: - case <-time.After(10 * time.Second): - t.Fatalf("timeout") - } -} - -// Tests that chunked server responses that write 1 byte at a time are -// buffered before chunk headers are added, not after chunk headers. -func TestServerBufferedChunking(t *testing.T) { - conn := new(testConn) - conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n")) - conn.closec = make(chan bool, 1) - ls := &oneConnListener{conn} - go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { - rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length - rw.Write([]byte{'x'}) - rw.Write([]byte{'y'}) - rw.Write([]byte{'z'}) - })) - <-conn.closec - if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) { - t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q", - conn.writeBuf.Bytes()) - } -} - -// Tests that the server flushes its response headers out when it's -// ignoring the response body and waits a bit before forcefully -// closing the TCP connection, causing the client to get a RST. -// See http://golang.org/issue/3595 -func TestServerGracefulClose(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - Error(w, "bye", StatusUnauthorized) - })) - defer ts.Close() - - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - defer conn.Close() - const bodySize = 5 << 20 - req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize)) - for i := 0; i < bodySize; i++ { - req = append(req, 'x') - } - writeErr := make(chan error) - go func() { - _, err := conn.Write(req) - writeErr <- err - }() - br := bufio.NewReader(conn) - lineNum := 0 - for { - line, err := br.ReadString('\n') - if err == io.EOF { - break - } - if err != nil { - t.Fatalf("ReadLine: %v", err) - } - lineNum++ - if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") { - t.Errorf("Response line = %q; want a 401", line) - } - } - // Wait for write to finish. This is a broken pipe on both - // Darwin and Linux, but checking this isn't the point of - // the test. - <-writeErr -} - -func TestCaseSensitiveMethod(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.Method != "get" { - t.Errorf(`Got method %q; want "get"`, r.Method) - } - })) - defer ts.Close() - req, _ := NewRequest("get", ts.URL, nil) - res, err := DefaultClient.Do(req) - if err != nil { - t.Error(err) - return - } - res.Body.Close() -} - -// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1 -// request (both keep-alive), when a Handler never writes any -// response, the net/http package adds a "Content-Length: 0" response -// header. -func TestContentLengthZero(t *testing.T) { - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {})) - defer ts.Close() - - for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} { - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("error dialing: %v", err) - } - _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version) - if err != nil { - t.Fatalf("error writing: %v", err) - } - req, _ := NewRequest("GET", "/", nil) - res, err := ReadResponse(bufio.NewReader(conn), req) - if err != nil { - t.Fatalf("error reading response: %v", err) - } - if te := res.TransferEncoding; len(te) > 0 { - t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te) - } - if cl := res.ContentLength; cl != 0 { - t.Errorf("For version %q, Content-Length = %v; want 0", version, cl) - } - conn.Close() - } -} - -func TestCloseNotifier(t *testing.T) { - defer afterTest(t) - gotReq := make(chan bool, 1) - sawClose := make(chan bool, 1) - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - gotReq <- true - cc := rw.(CloseNotifier).CloseNotify() - <-cc - sawClose <- true - })) - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("error dialing: %v", err) - } - diec := make(chan bool) - go func() { - _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") - if err != nil { - t.Fatal(err) - } - <-diec - conn.Close() - }() -For: - for { - select { - case <-gotReq: - diec <- true - case <-sawClose: - break For - case <-time.After(5 * time.Second): - t.Fatal("timeout") - } - } - ts.Close() -} - -func TestCloseNotifierChanLeak(t *testing.T) { - defer afterTest(t) - req := reqBytes("GET / HTTP/1.0\nHost: golang.org") - for i := 0; i < 20; i++ { - var output bytes.Buffer - conn := &rwTestConn{ - Reader: bytes.NewReader(req), - Writer: &output, - closec: make(chan bool, 1), - } - ln := &oneConnListener{conn: conn} - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - // Ignore the return value and never read from - // it, testing that we don't leak goroutines - // on the sending side: - _ = rw.(CloseNotifier).CloseNotify() - }) - go Serve(ln, handler) - <-conn.closec - } -} - -func TestOptions(t *testing.T) { - uric := make(chan string, 2) // only expect 1, but leave space for 2 - mux := NewServeMux() - mux.HandleFunc("/", func(w ResponseWriter, r *Request) { - uric <- r.RequestURI - }) - ts := httptest.NewServer(mux) - defer ts.Close() - - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - defer conn.Close() - - // An OPTIONS * request should succeed. - _, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) - if err != nil { - t.Fatal(err) - } - br := bufio.NewReader(conn) - res, err := ReadResponse(br, &Request{Method: "OPTIONS"}) - if err != nil { - t.Fatal(err) - } - if res.StatusCode != 200 { - t.Errorf("Got non-200 response to OPTIONS *: %#v", res) - } - - // A GET * request on a ServeMux should fail. - _, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) - if err != nil { - t.Fatal(err) - } - res, err = ReadResponse(br, &Request{Method: "GET"}) - if err != nil { - t.Fatal(err) - } - if res.StatusCode != 400 { - t.Errorf("Got non-400 response to GET *: %#v", res) - } - - res, err = Get(ts.URL + "/second") - if err != nil { - t.Fatal(err) - } - res.Body.Close() - if got := <-uric; got != "/second" { - t.Errorf("Handler saw request for %q; want /second", got) - } -} - -// Tests regarding the ordering of Write, WriteHeader, Header, and -// Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the -// (*response).header to the wire. In Go 1.1, the actual wire flush is -// delayed, so we could maybe tack on a Content-Length and better -// Content-Type after we see more (or all) of the output. To preserve -// compatibility with Go 1, we need to be careful to track which -// headers were live at the time of WriteHeader, so we write the same -// ones, even if the handler modifies them (~erroneously) after the -// first Write. -func TestHeaderToWire(t *testing.T) { - tests := []struct { - name string - handler func(ResponseWriter, *Request) - check func(output string) error - }{ - { - name: "write without Header", - handler: func(rw ResponseWriter, r *Request) { - rw.Write([]byte("hello world")) - }, - check: func(got string) error { - if !strings.Contains(got, "Content-Length:") { - return errors.New("no content-length") - } - if !strings.Contains(got, "Content-Type: text/plain") { - return errors.New("no content-length") - } - return nil - }, - }, - { - name: "Header mutation before write", - handler: func(rw ResponseWriter, r *Request) { - h := rw.Header() - h.Set("Content-Type", "some/type") - rw.Write([]byte("hello world")) - h.Set("Too-Late", "bogus") - }, - check: func(got string) error { - if !strings.Contains(got, "Content-Length:") { - return errors.New("no content-length") - } - if !strings.Contains(got, "Content-Type: some/type") { - return errors.New("wrong content-type") - } - if strings.Contains(got, "Too-Late") { - return errors.New("don't want too-late header") - } - return nil - }, - }, - { - name: "write then useless Header mutation", - handler: func(rw ResponseWriter, r *Request) { - rw.Write([]byte("hello world")) - rw.Header().Set("Too-Late", "Write already wrote headers") - }, - check: func(got string) error { - if strings.Contains(got, "Too-Late") { - return errors.New("header appeared from after WriteHeader") - } - return nil - }, - }, - { - name: "flush then write", - handler: func(rw ResponseWriter, r *Request) { - rw.(Flusher).Flush() - rw.Write([]byte("post-flush")) - rw.Header().Set("Too-Late", "Write already wrote headers") - }, - check: func(got string) error { - if !strings.Contains(got, "Transfer-Encoding: chunked") { - return errors.New("not chunked") - } - if strings.Contains(got, "Too-Late") { - return errors.New("header appeared from after WriteHeader") - } - return nil - }, - }, - { - name: "header then flush", - handler: func(rw ResponseWriter, r *Request) { - rw.Header().Set("Content-Type", "some/type") - rw.(Flusher).Flush() - rw.Write([]byte("post-flush")) - rw.Header().Set("Too-Late", "Write already wrote headers") - }, - check: func(got string) error { - if !strings.Contains(got, "Transfer-Encoding: chunked") { - return errors.New("not chunked") - } - if strings.Contains(got, "Too-Late") { - return errors.New("header appeared from after WriteHeader") - } - if !strings.Contains(got, "Content-Type: some/type") { - return errors.New("wrong content-length") - } - return nil - }, - }, - { - name: "sniff-on-first-write content-type", - handler: func(rw ResponseWriter, r *Request) { - rw.Write([]byte("some html")) - rw.Header().Set("Content-Type", "x/wrong") - }, - check: func(got string) error { - if !strings.Contains(got, "Content-Type: text/html") { - return errors.New("wrong content-length; want html") - } - return nil - }, - }, - { - name: "explicit content-type wins", - handler: func(rw ResponseWriter, r *Request) { - rw.Header().Set("Content-Type", "some/type") - rw.Write([]byte("some html")) - }, - check: func(got string) error { - if !strings.Contains(got, "Content-Type: some/type") { - return errors.New("wrong content-length; want html") - } - return nil - }, - }, - { - name: "empty handler", - handler: func(rw ResponseWriter, r *Request) { - }, - check: func(got string) error { - if !strings.Contains(got, "Content-Type: text/plain") { - return errors.New("wrong content-length; want text/plain") - } - if !strings.Contains(got, "Content-Length: 0") { - return errors.New("want 0 content-length") - } - return nil - }, - }, - { - name: "only Header, no write", - handler: func(rw ResponseWriter, r *Request) { - rw.Header().Set("Some-Header", "some-value") - }, - check: func(got string) error { - if !strings.Contains(got, "Some-Header") { - return errors.New("didn't get header") - } - return nil - }, - }, - { - name: "WriteHeader call", - handler: func(rw ResponseWriter, r *Request) { - rw.WriteHeader(404) - rw.Header().Set("Too-Late", "some-value") - }, - check: func(got string) error { - if !strings.Contains(got, "404") { - return errors.New("wrong status") - } - if strings.Contains(got, "Some-Header") { - return errors.New("shouldn't have seen Too-Late") - } - return nil - }, - }, - } - for _, tc := range tests { - ht := newHandlerTest(HandlerFunc(tc.handler)) - got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org") - if err := tc.check(got); err != nil { - t.Errorf("%s: %v\nGot response:\n%s", tc.name, err, got) - } - } -} - -// goTimeout runs f, failing t if f takes more than ns to complete. -func goTimeout(t *testing.T, d time.Duration, f func()) { - ch := make(chan bool, 2) - timer := time.AfterFunc(d, func() { - t.Errorf("Timeout expired after %v", d) - ch <- true - }) - defer timer.Stop() - go func() { - defer func() { ch <- true }() - f() - }() - <-ch -} - -type errorListener struct { - errs []error -} - -func (l *errorListener) Accept() (c net.Conn, err error) { - if len(l.errs) == 0 { - return nil, io.EOF - } - err = l.errs[0] - l.errs = l.errs[1:] - return -} - -func (l *errorListener) Close() error { - return nil -} - -func (l *errorListener) Addr() net.Addr { - return dummyAddr("test-address") -} - -func TestAcceptMaxFds(t *testing.T) { - log.SetOutput(ioutil.Discard) // is noisy otherwise - defer log.SetOutput(os.Stderr) - - ln := &errorListener{[]error{ - &net.OpError{ - Op: "accept", - Err: syscall.EMFILE, - }}} - err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {}))) - if err != io.EOF { - t.Errorf("got error %v, want EOF", err) - } -} - -func TestWriteAfterHijack(t *testing.T) { - req := reqBytes("GET / HTTP/1.1\nHost: golang.org") - var buf bytes.Buffer - wrotec := make(chan bool, 1) - conn := &rwTestConn{ - Reader: bytes.NewReader(req), - Writer: &buf, - closec: make(chan bool, 1), - } - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - conn, bufrw, err := rw.(Hijacker).Hijack() - if err != nil { - t.Error(err) - return - } - go func() { - bufrw.Write([]byte("[hijack-to-bufw]")) - bufrw.Flush() - conn.Write([]byte("[hijack-to-conn]")) - conn.Close() - wrotec <- true - }() - }) - ln := &oneConnListener{conn: conn} - go Serve(ln, handler) - <-conn.closec - <-wrotec - if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w { - t.Errorf("wrote %q; want %q", g, w) - } -} - -func TestDoubleHijack(t *testing.T) { - req := reqBytes("GET / HTTP/1.1\nHost: golang.org") - var buf bytes.Buffer - conn := &rwTestConn{ - Reader: bytes.NewReader(req), - Writer: &buf, - closec: make(chan bool, 1), - } - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - conn, _, err := rw.(Hijacker).Hijack() - if err != nil { - t.Error(err) - return - } - _, _, err = rw.(Hijacker).Hijack() - if err == nil { - t.Errorf("got err = nil; want err != nil") - } - conn.Close() - }) - ln := &oneConnListener{conn: conn} - go Serve(ln, handler) - <-conn.closec -} - -// http://code.google.com/p/go/issues/detail?id=5955 -// Note that this does not test the "request too large" -// exit path from the http server. This is intentional; -// not sending Connection: close is just a minor wire -// optimization and is pointless if dealing with a -// badly behaved client. -func TestHTTP10ConnectionHeader(t *testing.T) { - defer afterTest(t) - - mux := NewServeMux() - mux.Handle("/", HandlerFunc(func(resp ResponseWriter, req *Request) {})) - ts := httptest.NewServer(mux) - defer ts.Close() - - // net/http uses HTTP/1.1 for requests, so write requests manually - tests := []struct { - req string // raw http request - expect []string // expected Connection header(s) - }{ - { - req: "GET / HTTP/1.0\r\n\r\n", - expect: nil, - }, - { - req: "OPTIONS * HTTP/1.0\r\n\r\n", - expect: nil, - }, - { - req: "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", - expect: []string{"keep-alive"}, - }, - } - - for _, tt := range tests { - conn, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal("dial err:", err) - } - - _, err = fmt.Fprint(conn, tt.req) - if err != nil { - t.Fatal("conn write err:", err) - } - - resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"}) - if err != nil { - t.Fatal("ReadResponse err:", err) - } - conn.Close() - resp.Body.Close() - - got := resp.Header["Connection"] - if !reflect.DeepEqual(got, tt.expect) { - t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect) - } - } -} - -// See golang.org/issue/5660 -func TestServerReaderFromOrder(t *testing.T) { - defer afterTest(t) - pr, pw := io.Pipe() - const size = 3 << 20 - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path - done := make(chan bool) - go func() { - io.Copy(rw, pr) - close(done) - }() - time.Sleep(25 * time.Millisecond) // give Copy a chance to break things - n, err := io.Copy(ioutil.Discard, req.Body) - if err != nil { - t.Errorf("handler Copy: %v", err) - return - } - if n != size { - t.Errorf("handler Copy = %d; want %d", n, size) - } - pw.Write([]byte("hi")) - pw.Close() - <-done - })) - defer ts.Close() - - req, err := NewRequest("POST", ts.URL, io.LimitReader(neverEnding('a'), size)) - if err != nil { - t.Fatal(err) - } - res, err := DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - all, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - res.Body.Close() - if string(all) != "hi" { - t.Errorf("Body = %q; want hi", all) - } -} - -// Issue 6157, Issue 6685 -func TestCodesPreventingContentTypeAndBody(t *testing.T) { - for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} { - ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.URL.Path == "/header" { - w.Header().Set("Content-Length", "123") - } - w.WriteHeader(code) - if r.URL.Path == "/more" { - w.Write([]byte("stuff")) - } - })) - for _, req := range []string{ - "GET / HTTP/1.0", - "GET /header HTTP/1.0", - "GET /more HTTP/1.0", - "GET / HTTP/1.1", - "GET /header HTTP/1.1", - "GET /more HTTP/1.1", - } { - got := ht.rawResponse(req) - wantStatus := fmt.Sprintf("%d %s", code, StatusText(code)) - if !strings.Contains(got, wantStatus) { - t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, wantStatus, req, got) - } else if strings.Contains(got, "Content-Length") { - t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got) - } else if strings.Contains(got, "stuff") { - t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got) - } - } - } -} - -func TestContentTypeOkayOn204(t *testing.T) { - ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Length", "123") // suppressed - w.Header().Set("Content-Type", "foo/bar") - w.WriteHeader(204) - })) - got := ht.rawResponse("GET / HTTP/1.1") - if !strings.Contains(got, "Content-Type: foo/bar") { - t.Errorf("Response = %q; want Content-Type: foo/bar", got) - } - if strings.Contains(got, "Content-Length: 123") { - t.Errorf("Response = %q; don't want a Content-Length", got) - } -} - -// Issue 6995 -// A server Handler can receive a Request, and then turn around and -// give a copy of that Request.Body out to the Transport (e.g. any -// proxy). So then two people own that Request.Body (both the server -// and the http client), and both think they can close it on failure. -// Therefore, all incoming server requests Bodies need to be thread-safe. -func TestTransportAndServerSharedBodyRace(t *testing.T) { - defer afterTest(t) - - const bodySize = 1 << 20 - - unblockBackend := make(chan bool) - backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - io.CopyN(rw, req.Body, bodySize/2) - <-unblockBackend - })) - defer backend.Close() - - backendRespc := make(chan *Response, 1) - proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - if req.RequestURI == "/foo" { - rw.Write([]byte("bar")) - return - } - req2, _ := NewRequest("POST", backend.URL, req.Body) - req2.ContentLength = bodySize - - bresp, err := DefaultClient.Do(req2) - if err != nil { - t.Errorf("Proxy outbound request: %v", err) - return - } - _, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/4) - if err != nil { - t.Errorf("Proxy copy error: %v", err) - return - } - backendRespc <- bresp // to close later - - // Try to cause a race: Both the DefaultTransport and the proxy handler's Server - // will try to read/close req.Body (aka req2.Body) - DefaultTransport.(*Transport).CancelRequest(req2) - rw.Write([]byte("OK")) - })) - defer proxy.Close() - - req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize)) - res, err := DefaultClient.Do(req) - if err != nil { - t.Fatalf("Original request: %v", err) - } - - // Cleanup, so we don't leak goroutines. - res.Body.Close() - close(unblockBackend) - (<-backendRespc).Body.Close() -} - -// Test that a hanging Request.Body.Read from another goroutine can't -// cause the Handler goroutine's Request.Body.Close to block. -func TestRequestBodyCloseDoesntBlock(t *testing.T) { - t.Skipf("Skipping known issue; see golang.org/issue/7121") - if testing.Short() { - t.Skip("skipping in -short mode") - } - defer afterTest(t) - - readErrCh := make(chan error, 1) - errCh := make(chan error, 2) - - server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - go func(body io.Reader) { - _, err := body.Read(make([]byte, 100)) - readErrCh <- err - }(req.Body) - time.Sleep(500 * time.Millisecond) - })) - defer server.Close() - - closeConn := make(chan bool) - defer close(closeConn) - go func() { - conn, err := net.Dial("tcp", server.Listener.Addr().String()) - if err != nil { - errCh <- err - return - } - defer conn.Close() - _, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n")) - if err != nil { - errCh <- err - return - } - // And now just block, making the server block on our - // 100000 bytes of body that will never arrive. - <-closeConn - }() - select { - case err := <-readErrCh: - if err == nil { - t.Error("Read was nil. Expected error.") - } - case err := <-errCh: - t.Error(err) - case <-time.After(5 * time.Second): - t.Error("timeout") - } -} - -func TestResponseWriterWriteStringAllocs(t *testing.T) { - ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.URL.Path == "/s" { - io.WriteString(w, "Hello world") - } else { - w.Write([]byte("Hello world")) - } - })) - before := testing.AllocsPerRun(50, func() { ht.rawResponse("GET / HTTP/1.0") }) - after := testing.AllocsPerRun(50, func() { ht.rawResponse("GET /s HTTP/1.0") }) - if int(after) >= int(before) { - t.Errorf("WriteString allocs of %v >= Write allocs of %v", after, before) - } -} - -func TestAppendTime(t *testing.T) { - var b [len(TimeFormat)]byte - t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60)) - res := ExportAppendTime(b[:0], t1) - t2, err := ParseTime(string(res)) - if err != nil { - t.Fatalf("Error parsing time: %s", err) - } - if !t1.Equal(t2) { - t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res)) - } -} - -func TestServerConnState(t *testing.T) { - defer afterTest(t) - handler := map[string]func(w ResponseWriter, r *Request){ - "/": func(w ResponseWriter, r *Request) { - fmt.Fprintf(w, "Hello.") - }, - "/close": func(w ResponseWriter, r *Request) { - w.Header().Set("Connection", "close") - fmt.Fprintf(w, "Hello.") - }, - "/hijack": func(w ResponseWriter, r *Request) { - c, _, _ := w.(Hijacker).Hijack() - c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) - c.Close() - }, - "/hijack-panic": func(w ResponseWriter, r *Request) { - c, _, _ := w.(Hijacker).Hijack() - c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) - c.Close() - panic("intentional panic") - }, - } - ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { - handler[r.URL.Path](w, r) - })) - defer ts.Close() - - var mu sync.Mutex // guard stateLog and connID - var stateLog = map[int][]ConnState{} - var connID = map[net.Conn]int{} - - ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) - ts.Config.ConnState = func(c net.Conn, state ConnState) { - if c == nil { - t.Errorf("nil conn seen in state %s", state) - return - } - mu.Lock() - defer mu.Unlock() - id, ok := connID[c] - if !ok { - id = len(connID) + 1 - connID[c] = id - } - stateLog[id] = append(stateLog[id], state) - } - ts.Start() - - mustGet(t, ts.URL+"/") - mustGet(t, ts.URL+"/close") - - mustGet(t, ts.URL+"/") - mustGet(t, ts.URL+"/", "Connection", "close") - - mustGet(t, ts.URL+"/hijack") - mustGet(t, ts.URL+"/hijack-panic") - - // New->Closed - { - c, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - c.Close() - } - - // New->Active->Closed - { - c, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil { - t.Fatal(err) - } - c.Close() - } - - // New->Idle->Closed - { - c, err := net.Dial("tcp", ts.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { - t.Fatal(err) - } - res, err := ReadResponse(bufio.NewReader(c), nil) - if err != nil { - t.Fatal(err) - } - if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { - t.Fatal(err) - } - c.Close() - } - - want := map[int][]ConnState{ - 1: []ConnState{StateNew, StateActive, StateIdle, StateActive, StateClosed}, - 2: []ConnState{StateNew, StateActive, StateIdle, StateActive, StateClosed}, - 3: []ConnState{StateNew, StateActive, StateHijacked}, - 4: []ConnState{StateNew, StateActive, StateHijacked}, - 5: []ConnState{StateNew, StateClosed}, - 6: []ConnState{StateNew, StateActive, StateClosed}, - 7: []ConnState{StateNew, StateActive, StateIdle, StateClosed}, - } - logString := func(m map[int][]ConnState) string { - var b bytes.Buffer - for id, l := range m { - fmt.Fprintf(&b, "Conn %d: ", id) - for _, s := range l { - fmt.Fprintf(&b, "%s ", s) - } - b.WriteString("\n") - } - return b.String() - } - - for i := 0; i < 5; i++ { - time.Sleep(time.Duration(i) * 50 * time.Millisecond) - mu.Lock() - match := reflect.DeepEqual(stateLog, want) - mu.Unlock() - if match { - return - } - } - - mu.Lock() - t.Errorf("Unexpected events.\nGot log: %s\n Want: %s\n", logString(stateLog), logString(want)) - mu.Unlock() -} - -func mustGet(t *testing.T, url string, headers ...string) { - req, err := NewRequest("GET", url, nil) - if err != nil { - t.Fatal(err) - } - for len(headers) > 0 { - req.Header.Add(headers[0], headers[1]) - headers = headers[2:] - } - res, err := DefaultClient.Do(req) - if err != nil { - t.Errorf("Error fetching %s: %v", url, err) - return - } - _, err = ioutil.ReadAll(res.Body) - defer res.Body.Close() - if err != nil { - t.Errorf("Error reading %s: %v", url, err) - } -} - -func TestServerKeepAlivesEnabled(t *testing.T) { - defer afterTest(t) - ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) - ts.Config.SetKeepAlivesEnabled(false) - ts.Start() - defer ts.Close() - res, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - defer res.Body.Close() - if !res.Close { - t.Errorf("Body.Close == false; want true") - } -} - -// golang.org/issue/7856 -func TestServerEmptyBodyRace(t *testing.T) { - defer afterTest(t) - var n int32 - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - atomic.AddInt32(&n, 1) - })) - defer ts.Close() - var wg sync.WaitGroup - const reqs = 20 - for i := 0; i < reqs; i++ { - wg.Add(1) - go func() { - defer wg.Done() - res, err := Get(ts.URL) - if err != nil { - t.Error(err) - return - } - defer res.Body.Close() - _, err = io.Copy(ioutil.Discard, res.Body) - if err != nil { - t.Error(err) - return - } - }() - } - wg.Wait() - if got := atomic.LoadInt32(&n); got != reqs { - t.Errorf("handler ran %d times; want %d", got, reqs) - } -} - -func TestServerConnStateNew(t *testing.T) { - sawNew := false // if the test is buggy, we'll race on this variable. - srv := &Server{ - ConnState: func(c net.Conn, state ConnState) { - if state == StateNew { - sawNew = true // testing that this write isn't racy - } - }, - Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant - } - srv.Serve(&oneConnListener{ - conn: &rwTestConn{ - Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"), - Writer: ioutil.Discard, - }, - }) - if !sawNew { // testing that this read isn't racy - t.Error("StateNew not seen") - } -} - -func BenchmarkClientServer(b *testing.B) { - b.ReportAllocs() - b.StopTimer() - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { - fmt.Fprintf(rw, "Hello world.\n") - })) - defer ts.Close() - b.StartTimer() - - for i := 0; i < b.N; i++ { - res, err := Get(ts.URL) - if err != nil { - b.Fatal("Get:", err) - } - all, err := ioutil.ReadAll(res.Body) - res.Body.Close() - if err != nil { - b.Fatal("ReadAll:", err) - } - body := string(all) - if body != "Hello world.\n" { - b.Fatal("Got body:", body) - } - } - - b.StopTimer() -} - -func BenchmarkClientServerParallel4(b *testing.B) { - benchmarkClientServerParallel(b, 4) -} - -func BenchmarkClientServerParallel64(b *testing.B) { - benchmarkClientServerParallel(b, 64) -} - -func benchmarkClientServerParallel(b *testing.B, parallelism int) { - b.ReportAllocs() - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { - fmt.Fprintf(rw, "Hello world.\n") - })) - defer ts.Close() - b.ResetTimer() - b.SetParallelism(parallelism) - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - res, err := Get(ts.URL) - if err != nil { - b.Logf("Get: %v", err) - continue - } - all, err := ioutil.ReadAll(res.Body) - res.Body.Close() - if err != nil { - b.Logf("ReadAll: %v", err) - continue - } - body := string(all) - if body != "Hello world.\n" { - panic("Got body: " + body) - } - } - }) -} - -// A benchmark for profiling the server without the HTTP client code. -// The client code runs in a subprocess. -// -// For use like: -// $ go test -c -// $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof -// $ go tool pprof http.test http.prof -// (pprof) web -func BenchmarkServer(b *testing.B) { - b.ReportAllocs() - // Child process mode; - if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" { - n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N")) - if err != nil { - panic(err) - } - for i := 0; i < n; i++ { - res, err := Get(url) - if err != nil { - log.Panicf("Get: %v", err) - } - all, err := ioutil.ReadAll(res.Body) - res.Body.Close() - if err != nil { - log.Panicf("ReadAll: %v", err) - } - body := string(all) - if body != "Hello world.\n" { - log.Panicf("Got body: %q", body) - } - } - os.Exit(0) - return - } - - var res = []byte("Hello world.\n") - b.StopTimer() - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { - rw.Header().Set("Content-Type", "text/html; charset=utf-8") - rw.Write(res) - })) - defer ts.Close() - b.StartTimer() - - cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer") - cmd.Env = append([]string{ - fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N), - fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL), - }, os.Environ()...) - out, err := cmd.CombinedOutput() - if err != nil { - b.Errorf("Test failure: %v, with output: %s", err, out) - } -} - -func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) { - b.ReportAllocs() - req := reqBytes(`GET / HTTP/1.0 -Host: golang.org -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17 -Accept-Encoding: gzip,deflate,sdch -Accept-Language: en-US,en;q=0.8 -Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 -`) - res := []byte("Hello world!\n") - - conn := &testConn{ - // testConn.Close will not push into the channel - // if it's full. - closec: make(chan bool, 1), - } - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - rw.Header().Set("Content-Type", "text/html; charset=utf-8") - rw.Write(res) - }) - ln := new(oneConnListener) - for i := 0; i < b.N; i++ { - conn.readBuf.Reset() - conn.writeBuf.Reset() - conn.readBuf.Write(req) - ln.conn = conn - Serve(ln, handler) - <-conn.closec - } -} - -// repeatReader reads content count times, then EOFs. -type repeatReader struct { - content []byte - count int - off int -} - -func (r *repeatReader) Read(p []byte) (n int, err error) { - if r.count <= 0 { - return 0, io.EOF - } - n = copy(p, r.content[r.off:]) - r.off += n - if r.off == len(r.content) { - r.count-- - r.off = 0 - } - return -} - -func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) { - b.ReportAllocs() - - req := reqBytes(`GET / HTTP/1.1 -Host: golang.org -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17 -Accept-Encoding: gzip,deflate,sdch -Accept-Language: en-US,en;q=0.8 -Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 -`) - res := []byte("Hello world!\n") - - conn := &rwTestConn{ - Reader: &repeatReader{content: req, count: b.N}, - Writer: ioutil.Discard, - closec: make(chan bool, 1), - } - handled := 0 - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - handled++ - rw.Header().Set("Content-Type", "text/html; charset=utf-8") - rw.Write(res) - }) - ln := &oneConnListener{conn: conn} - go Serve(ln, handler) - <-conn.closec - if b.N != handled { - b.Errorf("b.N=%d but handled %d", b.N, handled) - } -} - -// same as above, but representing the most simple possible request -// and handler. Notably: the handler does not call rw.Header(). -func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) { - b.ReportAllocs() - - req := reqBytes(`GET / HTTP/1.1 -Host: golang.org -`) - res := []byte("Hello world!\n") - - conn := &rwTestConn{ - Reader: &repeatReader{content: req, count: b.N}, - Writer: ioutil.Discard, - closec: make(chan bool, 1), - } - handled := 0 - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - handled++ - rw.Write(res) - }) - ln := &oneConnListener{conn: conn} - go Serve(ln, handler) - <-conn.closec - if b.N != handled { - b.Errorf("b.N=%d but handled %d", b.N, handled) - } -} - -const someResponse = "some response" - -// A Response that's just no bigger than 2KB, the buffer-before-chunking threshold. -var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse)) - -// Both Content-Type and Content-Length set. Should be no buffering. -func BenchmarkServerHandlerTypeLen(b *testing.B) { - benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Type", "text/html") - w.Header().Set("Content-Length", strconv.Itoa(len(response))) - w.Write(response) - })) -} - -// A Content-Type is set, but no length. No sniffing, but will count the Content-Length. -func BenchmarkServerHandlerNoLen(b *testing.B) { - benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Type", "text/html") - w.Write(response) - })) -} - -// A Content-Length is set, but the Content-Type will be sniffed. -func BenchmarkServerHandlerNoType(b *testing.B) { - benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Length", strconv.Itoa(len(response))) - w.Write(response) - })) -} - -// Neither a Content-Type or Content-Length, so sniffed and counted. -func BenchmarkServerHandlerNoHeader(b *testing.B) { - benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { - w.Write(response) - })) -} - -func benchmarkHandler(b *testing.B, h Handler) { - b.ReportAllocs() - req := reqBytes(`GET / HTTP/1.1 -Host: golang.org -`) - conn := &rwTestConn{ - Reader: &repeatReader{content: req, count: b.N}, - Writer: ioutil.Discard, - closec: make(chan bool, 1), - } - handled := 0 - handler := HandlerFunc(func(rw ResponseWriter, r *Request) { - handled++ - h.ServeHTTP(rw, r) - }) - ln := &oneConnListener{conn: conn} - go Serve(ln, handler) - <-conn.closec - if b.N != handled { - b.Errorf("b.N=%d but handled %d", b.N, handled) - } -} - -func BenchmarkServerHijack(b *testing.B) { - b.ReportAllocs() - req := reqBytes(`GET / HTTP/1.1 -Host: golang.org -`) - h := HandlerFunc(func(w ResponseWriter, r *Request) { - conn, _, err := w.(Hijacker).Hijack() - if err != nil { - panic(err) - } - conn.Close() - }) - conn := &rwTestConn{ - Writer: ioutil.Discard, - closec: make(chan bool, 1), - } - ln := &oneConnListener{conn: conn} - for i := 0; i < b.N; i++ { - conn.Reader = bytes.NewReader(req) - ln.conn = conn - Serve(ln, h) - <-conn.closec - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/server.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/server.go deleted file mode 100644 index eae097eb8e..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/server.go +++ /dev/null @@ -1,2052 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP server. See RFC 2616. - -package http - -import ( - "bufio" - "crypto/tls" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net" - "net/url" - "os" - "path" - "runtime" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" -) - -// Errors introduced by the HTTP server. -var ( - ErrWriteAfterFlush = errors.New("Conn.Write called after Flush") - ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body") - ErrHijacked = errors.New("Conn has been hijacked") - ErrContentLength = errors.New("Conn.Write wrote more than the declared Content-Length") -) - -// Objects implementing the Handler interface can be -// registered to serve a particular path or subtree -// in the HTTP server. -// -// ServeHTTP should write reply headers and data to the ResponseWriter -// and then return. Returning signals that the request is finished -// and that the HTTP server can move on to the next request on -// the connection. -type Handler interface { - ServeHTTP(ResponseWriter, *Request) -} - -// A ResponseWriter interface is used by an HTTP handler to -// construct an HTTP response. -type ResponseWriter interface { - // Header returns the header map that will be sent by WriteHeader. - // Changing the header after a call to WriteHeader (or Write) has - // no effect. - Header() Header - - // Write writes the data to the connection as part of an HTTP reply. - // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK) - // before writing the data. If the Header does not contain a - // Content-Type line, Write adds a Content-Type set to the result of passing - // the initial 512 bytes of written data to DetectContentType. - Write([]byte) (int, error) - - // WriteHeader sends an HTTP response header with status code. - // If WriteHeader is not called explicitly, the first call to Write - // will trigger an implicit WriteHeader(http.StatusOK). - // Thus explicit calls to WriteHeader are mainly used to - // send error codes. - WriteHeader(int) -} - -// The Flusher interface is implemented by ResponseWriters that allow -// an HTTP handler to flush buffered data to the client. -// -// Note that even for ResponseWriters that support Flush, -// if the client is connected through an HTTP proxy, -// the buffered data may not reach the client until the response -// completes. -type Flusher interface { - // Flush sends any buffered data to the client. - Flush() -} - -// The Hijacker interface is implemented by ResponseWriters that allow -// an HTTP handler to take over the connection. -type Hijacker interface { - // Hijack lets the caller take over the connection. - // After a call to Hijack(), the HTTP server library - // will not do anything else with the connection. - // It becomes the caller's responsibility to manage - // and close the connection. - Hijack() (net.Conn, *bufio.ReadWriter, error) -} - -// The CloseNotifier interface is implemented by ResponseWriters which -// allow detecting when the underlying connection has gone away. -// -// This mechanism can be used to cancel long operations on the server -// if the client has disconnected before the response is ready. -type CloseNotifier interface { - // CloseNotify returns a channel that receives a single value - // when the client connection has gone away. - CloseNotify() <-chan bool -} - -// A conn represents the server side of an HTTP connection. -type conn struct { - remoteAddr string // network address of remote side - server *Server // the Server on which the connection arrived - rwc net.Conn // i/o connection - sr liveSwitchReader // where the LimitReader reads from; usually the rwc - lr *io.LimitedReader // io.LimitReader(sr) - buf *bufio.ReadWriter // buffered(lr,rwc), reading from bufio->limitReader->sr->rwc - tlsState *tls.ConnectionState // or nil when not using TLS - - mu sync.Mutex // guards the following - clientGone bool // if client has disconnected mid-request - closeNotifyc chan bool // made lazily - hijackedv bool // connection has been hijacked by handler -} - -func (c *conn) hijacked() bool { - c.mu.Lock() - defer c.mu.Unlock() - return c.hijackedv -} - -func (c *conn) hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) { - c.mu.Lock() - defer c.mu.Unlock() - if c.hijackedv { - return nil, nil, ErrHijacked - } - if c.closeNotifyc != nil { - return nil, nil, errors.New("http: Hijack is incompatible with use of CloseNotifier") - } - c.hijackedv = true - rwc = c.rwc - buf = c.buf - c.rwc = nil - c.buf = nil - c.setState(rwc, StateHijacked) - return -} - -func (c *conn) closeNotify() <-chan bool { - c.mu.Lock() - defer c.mu.Unlock() - if c.closeNotifyc == nil { - c.closeNotifyc = make(chan bool, 1) - if c.hijackedv { - // to obey the function signature, even though - // it'll never receive a value. - return c.closeNotifyc - } - pr, pw := io.Pipe() - - readSource := c.sr.r - c.sr.Lock() - c.sr.r = pr - c.sr.Unlock() - go func() { - _, err := io.Copy(pw, readSource) - if err == nil { - err = io.EOF - } - pw.CloseWithError(err) - c.noteClientGone() - }() - } - return c.closeNotifyc -} - -func (c *conn) noteClientGone() { - c.mu.Lock() - defer c.mu.Unlock() - if c.closeNotifyc != nil && !c.clientGone { - c.closeNotifyc <- true - } - c.clientGone = true -} - -// A switchReader can have its Reader changed at runtime. -// It's not safe for concurrent Reads and switches. -type switchReader struct { - io.Reader -} - -// A switchWriter can have its Writer changed at runtime. -// It's not safe for concurrent Writes and switches. -type switchWriter struct { - io.Writer -} - -// A liveSwitchReader is a switchReader that's safe for concurrent -// reads and switches, if its mutex is held. -type liveSwitchReader struct { - sync.Mutex - r io.Reader -} - -func (sr *liveSwitchReader) Read(p []byte) (n int, err error) { - sr.Lock() - r := sr.r - sr.Unlock() - return r.Read(p) -} - -// This should be >= 512 bytes for DetectContentType, -// but otherwise it's somewhat arbitrary. -const bufferBeforeChunkingSize = 2048 - -// chunkWriter writes to a response's conn buffer, and is the writer -// wrapped by the response.bufw buffered writer. -// -// chunkWriter also is responsible for finalizing the Header, including -// conditionally setting the Content-Type and setting a Content-Length -// in cases where the handler's final output is smaller than the buffer -// size. It also conditionally adds chunk headers, when in chunking mode. -// -// See the comment above (*response).Write for the entire write flow. -type chunkWriter struct { - res *response - - // header is either nil or a deep clone of res.handlerHeader - // at the time of res.WriteHeader, if res.WriteHeader is - // called and extra buffering is being done to calculate - // Content-Type and/or Content-Length. - header Header - - // wroteHeader tells whether the header's been written to "the - // wire" (or rather: w.conn.buf). this is unlike - // (*response).wroteHeader, which tells only whether it was - // logically written. - wroteHeader bool - - // set by the writeHeader method: - chunking bool // using chunked transfer encoding for reply body -} - -var ( - crlf = []byte("\r\n") - colonSpace = []byte(": ") -) - -func (cw *chunkWriter) Write(p []byte) (n int, err error) { - if !cw.wroteHeader { - cw.writeHeader(p) - } - if cw.res.req.Method == "HEAD" { - // Eat writes. - return len(p), nil - } - if cw.chunking { - _, err = fmt.Fprintf(cw.res.conn.buf, "%x\r\n", len(p)) - if err != nil { - cw.res.conn.rwc.Close() - return - } - } - n, err = cw.res.conn.buf.Write(p) - if cw.chunking && err == nil { - _, err = cw.res.conn.buf.Write(crlf) - } - if err != nil { - cw.res.conn.rwc.Close() - } - return -} - -func (cw *chunkWriter) flush() { - if !cw.wroteHeader { - cw.writeHeader(nil) - } - cw.res.conn.buf.Flush() -} - -func (cw *chunkWriter) close() { - if !cw.wroteHeader { - cw.writeHeader(nil) - } - if cw.chunking { - // zero EOF chunk, trailer key/value pairs (currently - // unsupported in Go's server), followed by a blank - // line. - cw.res.conn.buf.WriteString("0\r\n\r\n") - } -} - -// A response represents the server side of an HTTP response. -type response struct { - conn *conn - req *Request // request for this response - wroteHeader bool // reply header has been (logically) written - wroteContinue bool // 100 Continue response was written - - w *bufio.Writer // buffers output in chunks to chunkWriter - cw chunkWriter - sw *switchWriter // of the bufio.Writer, for return to putBufioWriter - - // handlerHeader is the Header that Handlers get access to, - // which may be retained and mutated even after WriteHeader. - // handlerHeader is copied into cw.header at WriteHeader - // time, and privately mutated thereafter. - handlerHeader Header - calledHeader bool // handler accessed handlerHeader via Header - - written int64 // number of bytes written in body - contentLength int64 // explicitly-declared Content-Length; or -1 - status int // status code passed to WriteHeader - - // close connection after this reply. set on request and - // updated after response from handler if there's a - // "Connection: keep-alive" response header and a - // Content-Length. - closeAfterReply bool - - // requestBodyLimitHit is set by requestTooLarge when - // maxBytesReader hits its max size. It is checked in - // WriteHeader, to make sure we don't consume the - // remaining request body to try to advance to the next HTTP - // request. Instead, when this is set, we stop reading - // subsequent requests on this connection and stop reading - // input from it. - requestBodyLimitHit bool - - handlerDone bool // set true when the handler exits - - // Buffers for Date and Content-Length - dateBuf [len(TimeFormat)]byte - clenBuf [10]byte -} - -// requestTooLarge is called by maxBytesReader when too much input has -// been read from the client. -func (w *response) requestTooLarge() { - w.closeAfterReply = true - w.requestBodyLimitHit = true - if !w.wroteHeader { - w.Header().Set("Connection", "close") - } -} - -// needsSniff reports whether a Content-Type still needs to be sniffed. -func (w *response) needsSniff() bool { - _, haveType := w.handlerHeader["Content-Type"] - return !w.cw.wroteHeader && !haveType && w.written < sniffLen -} - -// writerOnly hides an io.Writer value's optional ReadFrom method -// from io.Copy. -type writerOnly struct { - io.Writer -} - -func srcIsRegularFile(src io.Reader) (isRegular bool, err error) { - switch v := src.(type) { - case *os.File: - fi, err := v.Stat() - if err != nil { - return false, err - } - return fi.Mode().IsRegular(), nil - case *io.LimitedReader: - return srcIsRegularFile(v.R) - default: - return - } -} - -// ReadFrom is here to optimize copying from an *os.File regular file -// to a *net.TCPConn with sendfile. -func (w *response) ReadFrom(src io.Reader) (n int64, err error) { - // Our underlying w.conn.rwc is usually a *TCPConn (with its - // own ReadFrom method). If not, or if our src isn't a regular - // file, just fall back to the normal copy method. - rf, ok := w.conn.rwc.(io.ReaderFrom) - regFile, err := srcIsRegularFile(src) - if err != nil { - return 0, err - } - if !ok || !regFile { - return io.Copy(writerOnly{w}, src) - } - - // sendfile path: - - if !w.wroteHeader { - w.WriteHeader(StatusOK) - } - - if w.needsSniff() { - n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen)) - n += n0 - if err != nil { - return n, err - } - } - - w.w.Flush() // get rid of any previous writes - w.cw.flush() // make sure Header is written; flush data to rwc - - // Now that cw has been flushed, its chunking field is guaranteed initialized. - if !w.cw.chunking && w.bodyAllowed() { - n0, err := rf.ReadFrom(src) - n += n0 - w.written += n0 - return n, err - } - - n0, err := io.Copy(writerOnly{w}, src) - n += n0 - return n, err -} - -// noLimit is an effective infinite upper bound for io.LimitedReader -const noLimit int64 = (1 << 63) - 1 - -// debugServerConnections controls whether all server connections are wrapped -// with a verbose logging wrapper. -const debugServerConnections = false - -// Create new connection from rwc. -func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) { - c = new(conn) - c.remoteAddr = rwc.RemoteAddr().String() - c.server = srv - c.rwc = rwc - if debugServerConnections { - c.rwc = newLoggingConn("server", c.rwc) - } - c.sr = liveSwitchReader{r: c.rwc} - c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader) - br := newBufioReader(c.lr) - bw := newBufioWriterSize(c.rwc, 4<<10) - c.buf = bufio.NewReadWriter(br, bw) - return c, nil -} - -var ( - bufioReaderPool sync.Pool - bufioWriter2kPool sync.Pool - bufioWriter4kPool sync.Pool -) - -func bufioWriterPool(size int) *sync.Pool { - switch size { - case 2 << 10: - return &bufioWriter2kPool - case 4 << 10: - return &bufioWriter4kPool - } - return nil -} - -func newBufioReader(r io.Reader) *bufio.Reader { - if v := bufioReaderPool.Get(); v != nil { - br := v.(*bufio.Reader) - br.Reset(r) - return br - } - return bufio.NewReader(r) -} - -func putBufioReader(br *bufio.Reader) { - br.Reset(nil) - bufioReaderPool.Put(br) -} - -func newBufioWriterSize(w io.Writer, size int) *bufio.Writer { - pool := bufioWriterPool(size) - if pool != nil { - if v := pool.Get(); v != nil { - bw := v.(*bufio.Writer) - bw.Reset(w) - return bw - } - } - return bufio.NewWriterSize(w, size) -} - -func putBufioWriter(bw *bufio.Writer) { - bw.Reset(nil) - if pool := bufioWriterPool(bw.Available()); pool != nil { - pool.Put(bw) - } -} - -// DefaultMaxHeaderBytes is the maximum permitted size of the headers -// in an HTTP request. -// This can be overridden by setting Server.MaxHeaderBytes. -const DefaultMaxHeaderBytes = 1 << 20 // 1 MB - -func (srv *Server) maxHeaderBytes() int { - if srv.MaxHeaderBytes > 0 { - return srv.MaxHeaderBytes - } - return DefaultMaxHeaderBytes -} - -func (srv *Server) initialLimitedReaderSize() int64 { - return int64(srv.maxHeaderBytes()) + 4096 // bufio slop -} - -// wrapper around io.ReaderCloser which on first read, sends an -// HTTP/1.1 100 Continue header -type expectContinueReader struct { - resp *response - readCloser io.ReadCloser - closed bool -} - -func (ecr *expectContinueReader) Read(p []byte) (n int, err error) { - if ecr.closed { - return 0, ErrBodyReadAfterClose - } - if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked() { - ecr.resp.wroteContinue = true - ecr.resp.conn.buf.WriteString("HTTP/1.1 100 Continue\r\n\r\n") - ecr.resp.conn.buf.Flush() - } - return ecr.readCloser.Read(p) -} - -func (ecr *expectContinueReader) Close() error { - ecr.closed = true - return ecr.readCloser.Close() -} - -// TimeFormat is the time format to use with -// time.Parse and time.Time.Format when parsing -// or generating times in HTTP headers. -// It is like time.RFC1123 but hard codes GMT as the time zone. -const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT" - -// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat)) -func appendTime(b []byte, t time.Time) []byte { - const days = "SunMonTueWedThuFriSat" - const months = "JanFebMarAprMayJunJulAugSepOctNovDec" - - t = t.UTC() - yy, mm, dd := t.Date() - hh, mn, ss := t.Clock() - day := days[3*t.Weekday():] - mon := months[3*(mm-1):] - - return append(b, - day[0], day[1], day[2], ',', ' ', - byte('0'+dd/10), byte('0'+dd%10), ' ', - mon[0], mon[1], mon[2], ' ', - byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ', - byte('0'+hh/10), byte('0'+hh%10), ':', - byte('0'+mn/10), byte('0'+mn%10), ':', - byte('0'+ss/10), byte('0'+ss%10), ' ', - 'G', 'M', 'T') -} - -var errTooLarge = errors.New("http: request too large") - -// Read next request from connection. -func (c *conn) readRequest() (w *response, err error) { - if c.hijacked() { - return nil, ErrHijacked - } - - if d := c.server.ReadTimeout; d != 0 { - c.rwc.SetReadDeadline(time.Now().Add(d)) - } - if d := c.server.WriteTimeout; d != 0 { - defer func() { - c.rwc.SetWriteDeadline(time.Now().Add(d)) - }() - } - - c.lr.N = c.server.initialLimitedReaderSize() - var req *Request - if req, err = ReadRequest(c.buf.Reader); err != nil { - if c.lr.N == 0 { - return nil, errTooLarge - } - return nil, err - } - c.lr.N = noLimit - - req.RemoteAddr = c.remoteAddr - req.TLS = c.tlsState - - w = &response{ - conn: c, - req: req, - handlerHeader: make(Header), - contentLength: -1, - } - w.cw.res = w - w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize) - return w, nil -} - -func (w *response) Header() Header { - if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader { - // Accessing the header between logically writing it - // and physically writing it means we need to allocate - // a clone to snapshot the logically written state. - w.cw.header = w.handlerHeader.clone() - } - w.calledHeader = true - return w.handlerHeader -} - -// maxPostHandlerReadBytes is the max number of Request.Body bytes not -// consumed by a handler that the server will read from the client -// in order to keep a connection alive. If there are more bytes than -// this then the server to be paranoid instead sends a "Connection: -// close" response. -// -// This number is approximately what a typical machine's TCP buffer -// size is anyway. (if we have the bytes on the machine, we might as -// well read them) -const maxPostHandlerReadBytes = 256 << 10 - -func (w *response) WriteHeader(code int) { - if w.conn.hijacked() { - w.conn.server.logf("http: response.WriteHeader on hijacked connection") - return - } - if w.wroteHeader { - w.conn.server.logf("http: multiple response.WriteHeader calls") - return - } - w.wroteHeader = true - w.status = code - - if w.calledHeader && w.cw.header == nil { - w.cw.header = w.handlerHeader.clone() - } - - if cl := w.handlerHeader.get("Content-Length"); cl != "" { - v, err := strconv.ParseInt(cl, 10, 64) - if err == nil && v >= 0 { - w.contentLength = v - } else { - w.conn.server.logf("http: invalid Content-Length of %q", cl) - w.handlerHeader.Del("Content-Length") - } - } -} - -// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader. -// This type is used to avoid extra allocations from cloning and/or populating -// the response Header map and all its 1-element slices. -type extraHeader struct { - contentType string - connection string - transferEncoding string - date []byte // written if not nil - contentLength []byte // written if not nil -} - -// Sorted the same as extraHeader.Write's loop. -var extraHeaderKeys = [][]byte{ - []byte("Content-Type"), - []byte("Connection"), - []byte("Transfer-Encoding"), -} - -var ( - headerContentLength = []byte("Content-Length: ") - headerDate = []byte("Date: ") -) - -// Write writes the headers described in h to w. -// -// This method has a value receiver, despite the somewhat large size -// of h, because it prevents an allocation. The escape analysis isn't -// smart enough to realize this function doesn't mutate h. -func (h extraHeader) Write(w *bufio.Writer) { - if h.date != nil { - w.Write(headerDate) - w.Write(h.date) - w.Write(crlf) - } - if h.contentLength != nil { - w.Write(headerContentLength) - w.Write(h.contentLength) - w.Write(crlf) - } - for i, v := range []string{h.contentType, h.connection, h.transferEncoding} { - if v != "" { - w.Write(extraHeaderKeys[i]) - w.Write(colonSpace) - w.WriteString(v) - w.Write(crlf) - } - } -} - -// writeHeader finalizes the header sent to the client and writes it -// to cw.res.conn.buf. -// -// p is not written by writeHeader, but is the first chunk of the body -// that will be written. It is sniffed for a Content-Type if none is -// set explicitly. It's also used to set the Content-Length, if the -// total body size was small and the handler has already finished -// running. -func (cw *chunkWriter) writeHeader(p []byte) { - if cw.wroteHeader { - return - } - cw.wroteHeader = true - - w := cw.res - keepAlivesEnabled := w.conn.server.doKeepAlives() - isHEAD := w.req.Method == "HEAD" - - // header is written out to w.conn.buf below. Depending on the - // state of the handler, we either own the map or not. If we - // don't own it, the exclude map is created lazily for - // WriteSubset to remove headers. The setHeader struct holds - // headers we need to add. - header := cw.header - owned := header != nil - if !owned { - header = w.handlerHeader - } - var excludeHeader map[string]bool - delHeader := func(key string) { - if owned { - header.Del(key) - return - } - if _, ok := header[key]; !ok { - return - } - if excludeHeader == nil { - excludeHeader = make(map[string]bool) - } - excludeHeader[key] = true - } - var setHeader extraHeader - - // If the handler is done but never sent a Content-Length - // response header and this is our first (and last) write, set - // it, even to zero. This helps HTTP/1.0 clients keep their - // "keep-alive" connections alive. - // Exceptions: 304/204/1xx responses never get Content-Length, and if - // it was a HEAD request, we don't know the difference between - // 0 actual bytes and 0 bytes because the handler noticed it - // was a HEAD request and chose not to write anything. So for - // HEAD, the handler should either write the Content-Length or - // write non-zero bytes. If it's actually 0 bytes and the - // handler never looked at the Request.Method, we just don't - // send a Content-Length header. - if w.handlerDone && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) { - w.contentLength = int64(len(p)) - setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10) - } - - // If this was an HTTP/1.0 request with keep-alive and we sent a - // Content-Length back, we can make this a keep-alive response ... - if w.req.wantsHttp10KeepAlive() && keepAlivesEnabled { - sentLength := header.get("Content-Length") != "" - if sentLength && header.get("Connection") == "keep-alive" { - w.closeAfterReply = false - } - } - - // Check for a explicit (and valid) Content-Length header. - hasCL := w.contentLength != -1 - - if w.req.wantsHttp10KeepAlive() && (isHEAD || hasCL) { - _, connectionHeaderSet := header["Connection"] - if !connectionHeaderSet { - setHeader.connection = "keep-alive" - } - } else if !w.req.ProtoAtLeast(1, 1) || w.req.wantsClose() { - w.closeAfterReply = true - } - - if header.get("Connection") == "close" || !keepAlivesEnabled { - w.closeAfterReply = true - } - - // Per RFC 2616, we should consume the request body before - // replying, if the handler hasn't already done so. But we - // don't want to do an unbounded amount of reading here for - // DoS reasons, so we only try up to a threshold. - if w.req.ContentLength != 0 && !w.closeAfterReply { - ecr, isExpecter := w.req.Body.(*expectContinueReader) - if !isExpecter || ecr.resp.wroteContinue { - n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1) - if n >= maxPostHandlerReadBytes { - w.requestTooLarge() - delHeader("Connection") - setHeader.connection = "close" - } else { - w.req.Body.Close() - } - } - } - - code := w.status - if bodyAllowedForStatus(code) { - // If no content type, apply sniffing algorithm to body. - _, haveType := header["Content-Type"] - if !haveType { - setHeader.contentType = DetectContentType(p) - } - } else { - for _, k := range suppressedHeaders(code) { - delHeader(k) - } - } - - if _, ok := header["Date"]; !ok { - setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now()) - } - - te := header.get("Transfer-Encoding") - hasTE := te != "" - if hasCL && hasTE && te != "identity" { - // TODO: return an error if WriteHeader gets a return parameter - // For now just ignore the Content-Length. - w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d", - te, w.contentLength) - delHeader("Content-Length") - hasCL = false - } - - if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) { - // do nothing - } else if code == StatusNoContent { - delHeader("Transfer-Encoding") - } else if hasCL { - delHeader("Transfer-Encoding") - } else if w.req.ProtoAtLeast(1, 1) { - // HTTP/1.1 or greater: use chunked transfer encoding - // to avoid closing the connection at EOF. - // TODO: this blows away any custom or stacked Transfer-Encoding they - // might have set. Deal with that as need arises once we have a valid - // use case. - cw.chunking = true - setHeader.transferEncoding = "chunked" - } else { - // HTTP version < 1.1: cannot do chunked transfer - // encoding and we don't know the Content-Length so - // signal EOF by closing connection. - w.closeAfterReply = true - delHeader("Transfer-Encoding") // in case already set - } - - // Cannot use Content-Length with non-identity Transfer-Encoding. - if cw.chunking { - delHeader("Content-Length") - } - if !w.req.ProtoAtLeast(1, 0) { - return - } - - if w.closeAfterReply && (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) { - delHeader("Connection") - if w.req.ProtoAtLeast(1, 1) { - setHeader.connection = "close" - } - } - - w.conn.buf.WriteString(statusLine(w.req, code)) - cw.header.WriteSubset(w.conn.buf, excludeHeader) - setHeader.Write(w.conn.buf.Writer) - w.conn.buf.Write(crlf) -} - -// statusLines is a cache of Status-Line strings, keyed by code (for -// HTTP/1.1) or negative code (for HTTP/1.0). This is faster than a -// map keyed by struct of two fields. This map's max size is bounded -// by 2*len(statusText), two protocol types for each known official -// status code in the statusText map. -var ( - statusMu sync.RWMutex - statusLines = make(map[int]string) -) - -// statusLine returns a response Status-Line (RFC 2616 Section 6.1) -// for the given request and response status code. -func statusLine(req *Request, code int) string { - // Fast path: - key := code - proto11 := req.ProtoAtLeast(1, 1) - if !proto11 { - key = -key - } - statusMu.RLock() - line, ok := statusLines[key] - statusMu.RUnlock() - if ok { - return line - } - - // Slow path: - proto := "HTTP/1.0" - if proto11 { - proto = "HTTP/1.1" - } - codestring := strconv.Itoa(code) - text, ok := statusText[code] - if !ok { - text = "status code " + codestring - } - line = proto + " " + codestring + " " + text + "\r\n" - if ok { - statusMu.Lock() - defer statusMu.Unlock() - statusLines[key] = line - } - return line -} - -// bodyAllowed returns true if a Write is allowed for this response type. -// It's illegal to call this before the header has been flushed. -func (w *response) bodyAllowed() bool { - if !w.wroteHeader { - panic("") - } - return bodyAllowedForStatus(w.status) -} - -// The Life Of A Write is like this: -// -// Handler starts. No header has been sent. The handler can either -// write a header, or just start writing. Writing before sending a header -// sends an implicitly empty 200 OK header. -// -// If the handler didn't declare a Content-Length up front, we either -// go into chunking mode or, if the handler finishes running before -// the chunking buffer size, we compute a Content-Length and send that -// in the header instead. -// -// Likewise, if the handler didn't set a Content-Type, we sniff that -// from the initial chunk of output. -// -// The Writers are wired together like: -// -// 1. *response (the ResponseWriter) -> -// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes -// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type) -// and which writes the chunk headers, if needed. -// 4. conn.buf, a bufio.Writer of default (4kB) bytes -// 5. the rwc, the net.Conn. -// -// TODO(bradfitz): short-circuit some of the buffering when the -// initial header contains both a Content-Type and Content-Length. -// Also short-circuit in (1) when the header's been sent and not in -// chunking mode, writing directly to (4) instead, if (2) has no -// buffered data. More generally, we could short-circuit from (1) to -// (3) even in chunking mode if the write size from (1) is over some -// threshold and nothing is in (2). The answer might be mostly making -// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal -// with this instead. -func (w *response) Write(data []byte) (n int, err error) { - return w.write(len(data), data, "") -} - -func (w *response) WriteString(data string) (n int, err error) { - return w.write(len(data), nil, data) -} - -// either dataB or dataS is non-zero. -func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) { - if w.conn.hijacked() { - w.conn.server.logf("http: response.Write on hijacked connection") - return 0, ErrHijacked - } - if !w.wroteHeader { - w.WriteHeader(StatusOK) - } - if lenData == 0 { - return 0, nil - } - if !w.bodyAllowed() { - return 0, ErrBodyNotAllowed - } - - w.written += int64(lenData) // ignoring errors, for errorKludge - if w.contentLength != -1 && w.written > w.contentLength { - return 0, ErrContentLength - } - if dataB != nil { - return w.w.Write(dataB) - } else { - return w.w.WriteString(dataS) - } -} - -func (w *response) finishRequest() { - w.handlerDone = true - - if !w.wroteHeader { - w.WriteHeader(StatusOK) - } - - w.w.Flush() - putBufioWriter(w.w) - w.cw.close() - w.conn.buf.Flush() - - // Close the body (regardless of w.closeAfterReply) so we can - // re-use its bufio.Reader later safely. - w.req.Body.Close() - - if w.req.MultipartForm != nil { - w.req.MultipartForm.RemoveAll() - } - - if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written { - // Did not write enough. Avoid getting out of sync. - w.closeAfterReply = true - } -} - -func (w *response) Flush() { - if !w.wroteHeader { - w.WriteHeader(StatusOK) - } - w.w.Flush() - w.cw.flush() -} - -func (c *conn) finalFlush() { - if c.buf != nil { - c.buf.Flush() - - // Steal the bufio.Reader (~4KB worth of memory) and its associated - // reader for a future connection. - putBufioReader(c.buf.Reader) - - // Steal the bufio.Writer (~4KB worth of memory) and its associated - // writer for a future connection. - putBufioWriter(c.buf.Writer) - - c.buf = nil - } -} - -// Close the connection. -func (c *conn) close() { - c.finalFlush() - if c.rwc != nil { - c.rwc.Close() - c.rwc = nil - } -} - -// rstAvoidanceDelay is the amount of time we sleep after closing the -// write side of a TCP connection before closing the entire socket. -// By sleeping, we increase the chances that the client sees our FIN -// and processes its final data before they process the subsequent RST -// from closing a connection with known unread data. -// This RST seems to occur mostly on BSD systems. (And Windows?) -// This timeout is somewhat arbitrary (~latency around the planet). -const rstAvoidanceDelay = 500 * time.Millisecond - -// closeWrite flushes any outstanding data and sends a FIN packet (if -// client is connected via TCP), signalling that we're done. We then -// pause for a bit, hoping the client processes it before `any -// subsequent RST. -// -// See http://golang.org/issue/3595 -func (c *conn) closeWriteAndWait() { - c.finalFlush() - if tcp, ok := c.rwc.(*net.TCPConn); ok { - tcp.CloseWrite() - } - time.Sleep(rstAvoidanceDelay) -} - -// validNPN reports whether the proto is not a blacklisted Next -// Protocol Negotiation protocol. Empty and built-in protocol types -// are blacklisted and can't be overridden with alternate -// implementations. -func validNPN(proto string) bool { - switch proto { - case "", "http/1.1", "http/1.0": - return false - } - return true -} - -func (c *conn) setState(nc net.Conn, state ConnState) { - if hook := c.server.ConnState; hook != nil { - hook(nc, state) - } -} - -// Serve a new connection. -func (c *conn) serve() { - origConn := c.rwc // copy it before it's set nil on Close or Hijack - defer func() { - if err := recover(); err != nil { - const size = 64 << 10 - buf := make([]byte, size) - buf = buf[:runtime.Stack(buf, false)] - c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf) - } - if !c.hijacked() { - c.close() - c.setState(origConn, StateClosed) - } - }() - - if tlsConn, ok := c.rwc.(*tls.Conn); ok { - if d := c.server.ReadTimeout; d != 0 { - c.rwc.SetReadDeadline(time.Now().Add(d)) - } - if d := c.server.WriteTimeout; d != 0 { - c.rwc.SetWriteDeadline(time.Now().Add(d)) - } - if err := tlsConn.Handshake(); err != nil { - c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err) - return - } - c.tlsState = new(tls.ConnectionState) - *c.tlsState = tlsConn.ConnectionState() - if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) { - if fn := c.server.TLSNextProto[proto]; fn != nil { - h := initNPNRequest{tlsConn, serverHandler{c.server}} - fn(c.server, tlsConn, h) - } - return - } - } - - for { - w, err := c.readRequest() - if c.lr.N != c.server.initialLimitedReaderSize() { - // If we read any bytes off the wire, we're active. - c.setState(c.rwc, StateActive) - } - if err != nil { - if err == errTooLarge { - // Their HTTP client may or may not be - // able to read this if we're - // responding to them and hanging up - // while they're still writing their - // request. Undefined behavior. - io.WriteString(c.rwc, "HTTP/1.1 413 Request Entity Too Large\r\n\r\n") - c.closeWriteAndWait() - break - } else if err == io.EOF { - break // Don't reply - } else if neterr, ok := err.(net.Error); ok && neterr.Timeout() { - break // Don't reply - } - io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\n\r\n") - break - } - - // Expect 100 Continue support - req := w.req - if req.expectsContinue() { - if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 { - // Wrap the Body reader with one that replies on the connection - req.Body = &expectContinueReader{readCloser: req.Body, resp: w} - } - req.Header.Del("Expect") - } else if req.Header.get("Expect") != "" { - w.sendExpectationFailed() - break - } - - // HTTP cannot have multiple simultaneous active requests.[*] - // Until the server replies to this request, it can't read another, - // so we might as well run the handler in this goroutine. - // [*] Not strictly true: HTTP pipelining. We could let them all process - // in parallel even if their responses need to be serialized. - serverHandler{c.server}.ServeHTTP(w, w.req) - if c.hijacked() { - return - } - w.finishRequest() - if w.closeAfterReply { - if w.requestBodyLimitHit { - c.closeWriteAndWait() - } - break - } - c.setState(c.rwc, StateIdle) - } -} - -func (w *response) sendExpectationFailed() { - // TODO(bradfitz): let ServeHTTP handlers handle - // requests with non-standard expectation[s]? Seems - // theoretical at best, and doesn't fit into the - // current ServeHTTP model anyway. We'd need to - // make the ResponseWriter an optional - // "ExpectReplier" interface or something. - // - // For now we'll just obey RFC 2616 14.20 which says - // "If a server receives a request containing an - // Expect field that includes an expectation- - // extension that it does not support, it MUST - // respond with a 417 (Expectation Failed) status." - w.Header().Set("Connection", "close") - w.WriteHeader(StatusExpectationFailed) - w.finishRequest() -} - -// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter -// and a Hijacker. -func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) { - if w.wroteHeader { - w.cw.flush() - } - // Release the bufioWriter that writes to the chunk writer, it is not - // used after a connection has been hijacked. - rwc, buf, err = w.conn.hijack() - if err == nil { - putBufioWriter(w.w) - w.w = nil - } - return rwc, buf, err -} - -func (w *response) CloseNotify() <-chan bool { - return w.conn.closeNotify() -} - -// The HandlerFunc type is an adapter to allow the use of -// ordinary functions as HTTP handlers. If f is a function -// with the appropriate signature, HandlerFunc(f) is a -// Handler object that calls f. -type HandlerFunc func(ResponseWriter, *Request) - -// ServeHTTP calls f(w, r). -func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { - f(w, r) -} - -// Helper handlers - -// Error replies to the request with the specified error message and HTTP code. -// The error message should be plain text. -func Error(w ResponseWriter, error string, code int) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.WriteHeader(code) - fmt.Fprintln(w, error) -} - -// NotFound replies to the request with an HTTP 404 not found error. -func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) } - -// NotFoundHandler returns a simple request handler -// that replies to each request with a ``404 page not found'' reply. -func NotFoundHandler() Handler { return HandlerFunc(NotFound) } - -// StripPrefix returns a handler that serves HTTP requests -// by removing the given prefix from the request URL's Path -// and invoking the handler h. StripPrefix handles a -// request for a path that doesn't begin with prefix by -// replying with an HTTP 404 not found error. -func StripPrefix(prefix string, h Handler) Handler { - if prefix == "" { - return h - } - return HandlerFunc(func(w ResponseWriter, r *Request) { - if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) { - r.URL.Path = p - h.ServeHTTP(w, r) - } else { - NotFound(w, r) - } - }) -} - -// Redirect replies to the request with a redirect to url, -// which may be a path relative to the request path. -func Redirect(w ResponseWriter, r *Request, urlStr string, code int) { - if u, err := url.Parse(urlStr); err == nil { - // If url was relative, make absolute by - // combining with request path. - // The browser would probably do this for us, - // but doing it ourselves is more reliable. - - // NOTE(rsc): RFC 2616 says that the Location - // line must be an absolute URI, like - // "http://www.google.com/redirect/", - // not a path like "/redirect/". - // Unfortunately, we don't know what to - // put in the host name section to get the - // client to connect to us again, so we can't - // know the right absolute URI to send back. - // Because of this problem, no one pays attention - // to the RFC; they all send back just a new path. - // So do we. - oldpath := r.URL.Path - if oldpath == "" { // should not happen, but avoid a crash if it does - oldpath = "/" - } - if u.Scheme == "" { - // no leading http://server - if urlStr == "" || urlStr[0] != '/' { - // make relative path absolute - olddir, _ := path.Split(oldpath) - urlStr = olddir + urlStr - } - - var query string - if i := strings.Index(urlStr, "?"); i != -1 { - urlStr, query = urlStr[:i], urlStr[i:] - } - - // clean up but preserve trailing slash - trailing := strings.HasSuffix(urlStr, "/") - urlStr = path.Clean(urlStr) - if trailing && !strings.HasSuffix(urlStr, "/") { - urlStr += "/" - } - urlStr += query - } - } - - w.Header().Set("Location", urlStr) - w.WriteHeader(code) - - // RFC2616 recommends that a short note "SHOULD" be included in the - // response because older user agents may not understand 301/307. - // Shouldn't send the response for POST or HEAD; that leaves GET. - if r.Method == "GET" { - note := "" + statusText[code] + ".\n" - fmt.Fprintln(w, note) - } -} - -var htmlReplacer = strings.NewReplacer( - "&", "&", - "<", "<", - ">", ">", - // """ is shorter than """. - `"`, """, - // "'" is shorter than "'" and apos was not in HTML until HTML5. - "'", "'", -) - -func htmlEscape(s string) string { - return htmlReplacer.Replace(s) -} - -// Redirect to a fixed URL -type redirectHandler struct { - url string - code int -} - -func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) { - Redirect(w, r, rh.url, rh.code) -} - -// RedirectHandler returns a request handler that redirects -// each request it receives to the given url using the given -// status code. -func RedirectHandler(url string, code int) Handler { - return &redirectHandler{url, code} -} - -// ServeMux is an HTTP request multiplexer. -// It matches the URL of each incoming request against a list of registered -// patterns and calls the handler for the pattern that -// most closely matches the URL. -// -// Patterns name fixed, rooted paths, like "/favicon.ico", -// or rooted subtrees, like "/images/" (note the trailing slash). -// Longer patterns take precedence over shorter ones, so that -// if there are handlers registered for both "/images/" -// and "/images/thumbnails/", the latter handler will be -// called for paths beginning "/images/thumbnails/" and the -// former will receive requests for any other paths in the -// "/images/" subtree. -// -// Note that since a pattern ending in a slash names a rooted subtree, -// the pattern "/" matches all paths not matched by other registered -// patterns, not just the URL with Path == "/". -// -// Patterns may optionally begin with a host name, restricting matches to -// URLs on that host only. Host-specific patterns take precedence over -// general patterns, so that a handler might register for the two patterns -// "/codesearch" and "codesearch.google.com/" without also taking over -// requests for "http://www.google.com/". -// -// ServeMux also takes care of sanitizing the URL request path, -// redirecting any request containing . or .. elements to an -// equivalent .- and ..-free URL. -type ServeMux struct { - mu sync.RWMutex - m map[string]muxEntry - hosts bool // whether any patterns contain hostnames -} - -type muxEntry struct { - explicit bool - h Handler - pattern string -} - -// NewServeMux allocates and returns a new ServeMux. -func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} } - -// DefaultServeMux is the default ServeMux used by Serve. -var DefaultServeMux = NewServeMux() - -// Does path match pattern? -func pathMatch(pattern, path string) bool { - if len(pattern) == 0 { - // should not happen - return false - } - n := len(pattern) - if pattern[n-1] != '/' { - return pattern == path - } - return len(path) >= n && path[0:n] == pattern -} - -// Return the canonical path for p, eliminating . and .. elements. -func cleanPath(p string) string { - if p == "" { - return "/" - } - if p[0] != '/' { - p = "/" + p - } - np := path.Clean(p) - // path.Clean removes trailing slash except for root; - // put the trailing slash back if necessary. - if p[len(p)-1] == '/' && np != "/" { - np += "/" - } - return np -} - -// Find a handler on a handler map given a path string -// Most-specific (longest) pattern wins -func (mux *ServeMux) match(path string) (h Handler, pattern string) { - var n = 0 - for k, v := range mux.m { - if !pathMatch(k, path) { - continue - } - if h == nil || len(k) > n { - n = len(k) - h = v.h - pattern = v.pattern - } - } - return -} - -// Handler returns the handler to use for the given request, -// consulting r.Method, r.Host, and r.URL.Path. It always returns -// a non-nil handler. If the path is not in its canonical form, the -// handler will be an internally-generated handler that redirects -// to the canonical path. -// -// Handler also returns the registered pattern that matches the -// request or, in the case of internally-generated redirects, -// the pattern that will match after following the redirect. -// -// If there is no registered handler that applies to the request, -// Handler returns a ``page not found'' handler and an empty pattern. -func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) { - if r.Method != "CONNECT" { - if p := cleanPath(r.URL.Path); p != r.URL.Path { - _, pattern = mux.handler(r.Host, p) - url := *r.URL - url.Path = p - return RedirectHandler(url.String(), StatusMovedPermanently), pattern - } - } - - return mux.handler(r.Host, r.URL.Path) -} - -// handler is the main implementation of Handler. -// The path is known to be in canonical form, except for CONNECT methods. -func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) { - mux.mu.RLock() - defer mux.mu.RUnlock() - - // Host-specific pattern takes precedence over generic ones - if mux.hosts { - h, pattern = mux.match(host + path) - } - if h == nil { - h, pattern = mux.match(path) - } - if h == nil { - h, pattern = NotFoundHandler(), "" - } - return -} - -// ServeHTTP dispatches the request to the handler whose -// pattern most closely matches the request URL. -func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { - if r.RequestURI == "*" { - if r.ProtoAtLeast(1, 1) { - w.Header().Set("Connection", "close") - } - w.WriteHeader(StatusBadRequest) - return - } - h, _ := mux.Handler(r) - h.ServeHTTP(w, r) -} - -// Handle registers the handler for the given pattern. -// If a handler already exists for pattern, Handle panics. -func (mux *ServeMux) Handle(pattern string, handler Handler) { - mux.mu.Lock() - defer mux.mu.Unlock() - - if pattern == "" { - panic("http: invalid pattern " + pattern) - } - if handler == nil { - panic("http: nil handler") - } - if mux.m[pattern].explicit { - panic("http: multiple registrations for " + pattern) - } - - mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern} - - if pattern[0] != '/' { - mux.hosts = true - } - - // Helpful behavior: - // If pattern is /tree/, insert an implicit permanent redirect for /tree. - // It can be overridden by an explicit registration. - n := len(pattern) - if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit { - // If pattern contains a host name, strip it and use remaining - // path for redirect. - path := pattern - if pattern[0] != '/' { - // In pattern, at least the last character is a '/', so - // strings.Index can't be -1. - path = pattern[strings.Index(pattern, "/"):] - } - mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(path, StatusMovedPermanently), pattern: pattern} - } -} - -// HandleFunc registers the handler function for the given pattern. -func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { - mux.Handle(pattern, HandlerFunc(handler)) -} - -// Handle registers the handler for the given pattern -// in the DefaultServeMux. -// The documentation for ServeMux explains how patterns are matched. -func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } - -// HandleFunc registers the handler function for the given pattern -// in the DefaultServeMux. -// The documentation for ServeMux explains how patterns are matched. -func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { - DefaultServeMux.HandleFunc(pattern, handler) -} - -// Serve accepts incoming HTTP connections on the listener l, -// creating a new service goroutine for each. The service goroutines -// read requests and then call handler to reply to them. -// Handler is typically nil, in which case the DefaultServeMux is used. -func Serve(l net.Listener, handler Handler) error { - srv := &Server{Handler: handler} - return srv.Serve(l) -} - -// A Server defines parameters for running an HTTP server. -// The zero value for Server is a valid configuration. -type Server struct { - Addr string // TCP address to listen on, ":http" if empty - Handler Handler // handler to invoke, http.DefaultServeMux if nil - ReadTimeout time.Duration // maximum duration before timing out read of the request - WriteTimeout time.Duration // maximum duration before timing out write of the response - MaxHeaderBytes int // maximum size of request headers, DefaultMaxHeaderBytes if 0 - TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS - - // TLSNextProto optionally specifies a function to take over - // ownership of the provided TLS connection when an NPN - // protocol upgrade has occurred. The map key is the protocol - // name negotiated. The Handler argument should be used to - // handle HTTP requests and will initialize the Request's TLS - // and RemoteAddr if not already set. The connection is - // automatically closed when the function returns. - TLSNextProto map[string]func(*Server, *tls.Conn, Handler) - - // ConnState specifies an optional callback function that is - // called when a client connection changes state. See the - // ConnState type and associated constants for details. - ConnState func(net.Conn, ConnState) - - // ErrorLog specifies an optional logger for errors accepting - // connections and unexpected behavior from handlers. - // If nil, logging goes to os.Stderr via the log package's - // standard logger. - ErrorLog *log.Logger - - disableKeepAlives int32 // accessed atomically. -} - -// A ConnState represents the state of a client connection to a server. -// It's used by the optional Server.ConnState hook. -type ConnState int - -const ( - // StateNew represents a new connection that is expected to - // send a request immediately. Connections begin at this - // state and then transition to either StateActive or - // StateClosed. - StateNew ConnState = iota - - // StateActive represents a connection that has read 1 or more - // bytes of a request. The Server.ConnState hook for - // StateActive fires before the request has entered a handler - // and doesn't fire again until the request has been - // handled. After the request is handled, the state - // transitions to StateClosed, StateHijacked, or StateIdle. - StateActive - - // StateIdle represents a connection that has finished - // handling a request and is in the keep-alive state, waiting - // for a new request. Connections transition from StateIdle - // to either StateActive or StateClosed. - StateIdle - - // StateHijacked represents a hijacked connection. - // This is a terminal state. It does not transition to StateClosed. - StateHijacked - - // StateClosed represents a closed connection. - // This is a terminal state. Hijacked connections do not - // transition to StateClosed. - StateClosed -) - -var stateName = map[ConnState]string{ - StateNew: "new", - StateActive: "active", - StateIdle: "idle", - StateHijacked: "hijacked", - StateClosed: "closed", -} - -func (c ConnState) String() string { - return stateName[c] -} - -// serverHandler delegates to either the server's Handler or -// DefaultServeMux and also handles "OPTIONS *" requests. -type serverHandler struct { - srv *Server -} - -func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) { - handler := sh.srv.Handler - if handler == nil { - handler = DefaultServeMux - } - if req.RequestURI == "*" && req.Method == "OPTIONS" { - handler = globalOptionsHandler{} - } - handler.ServeHTTP(rw, req) -} - -// ListenAndServe listens on the TCP network address srv.Addr and then -// calls Serve to handle requests on incoming connections. If -// srv.Addr is blank, ":http" is used. -func (srv *Server) ListenAndServe() error { - addr := srv.Addr - if addr == "" { - addr = ":http" - } - ln, err := net.Listen("tcp", addr) - if err != nil { - return err - } - return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) -} - -// Serve accepts incoming connections on the Listener l, creating a -// new service goroutine for each. The service goroutines read requests and -// then call srv.Handler to reply to them. -func (srv *Server) Serve(l net.Listener) error { - defer l.Close() - var tempDelay time.Duration // how long to sleep on accept failure - for { - rw, e := l.Accept() - if e != nil { - if ne, ok := e.(net.Error); ok && ne.Temporary() { - if tempDelay == 0 { - tempDelay = 5 * time.Millisecond - } else { - tempDelay *= 2 - } - if max := 1 * time.Second; tempDelay > max { - tempDelay = max - } - srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay) - time.Sleep(tempDelay) - continue - } - return e - } - tempDelay = 0 - c, err := srv.newConn(rw) - if err != nil { - continue - } - c.setState(c.rwc, StateNew) // before Serve can return - go c.serve() - } -} - -func (s *Server) doKeepAlives() bool { - return atomic.LoadInt32(&s.disableKeepAlives) == 0 -} - -// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. -// By default, keep-alives are always enabled. Only very -// resource-constrained environments or servers in the process of -// shutting down should disable them. -func (s *Server) SetKeepAlivesEnabled(v bool) { - if v { - atomic.StoreInt32(&s.disableKeepAlives, 0) - } else { - atomic.StoreInt32(&s.disableKeepAlives, 1) - } -} - -func (s *Server) logf(format string, args ...interface{}) { - if s.ErrorLog != nil { - s.ErrorLog.Printf(format, args...) - } else { - log.Printf(format, args...) - } -} - -// ListenAndServe listens on the TCP network address addr -// and then calls Serve with handler to handle requests -// on incoming connections. Handler is typically nil, -// in which case the DefaultServeMux is used. -// -// A trivial example server is: -// -// package main -// -// import ( -// "io" -// "net/http" -// "log" -// ) -// -// // hello world, the web server -// func HelloServer(w http.ResponseWriter, req *http.Request) { -// io.WriteString(w, "hello, world!\n") -// } -// -// func main() { -// http.HandleFunc("/hello", HelloServer) -// err := http.ListenAndServe(":12345", nil) -// if err != nil { -// log.Fatal("ListenAndServe: ", err) -// } -// } -func ListenAndServe(addr string, handler Handler) error { - server := &Server{Addr: addr, Handler: handler} - return server.ListenAndServe() -} - -// ListenAndServeTLS acts identically to ListenAndServe, except that it -// expects HTTPS connections. Additionally, files containing a certificate and -// matching private key for the server must be provided. If the certificate -// is signed by a certificate authority, the certFile should be the concatenation -// of the server's certificate followed by the CA's certificate. -// -// A trivial example server is: -// -// import ( -// "log" -// "net/http" -// ) -// -// func handler(w http.ResponseWriter, req *http.Request) { -// w.Header().Set("Content-Type", "text/plain") -// w.Write([]byte("This is an example server.\n")) -// } -// -// func main() { -// http.HandleFunc("/", handler) -// log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/") -// err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil) -// if err != nil { -// log.Fatal(err) -// } -// } -// -// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem. -func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error { - server := &Server{Addr: addr, Handler: handler} - return server.ListenAndServeTLS(certFile, keyFile) -} - -// ListenAndServeTLS listens on the TCP network address srv.Addr and -// then calls Serve to handle requests on incoming TLS connections. -// -// Filenames containing a certificate and matching private key for -// the server must be provided. If the certificate is signed by a -// certificate authority, the certFile should be the concatenation -// of the server's certificate followed by the CA's certificate. -// -// If srv.Addr is blank, ":https" is used. -func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error { - addr := srv.Addr - if addr == "" { - addr = ":https" - } - config := &tls.Config{} - if srv.TLSConfig != nil { - *config = *srv.TLSConfig - } - if config.NextProtos == nil { - config.NextProtos = []string{"http/1.1"} - } - - var err error - config.Certificates = make([]tls.Certificate, 1) - config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return err - } - - ln, err := net.Listen("tcp", addr) - if err != nil { - return err - } - - tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config) - return srv.Serve(tlsListener) -} - -// TimeoutHandler returns a Handler that runs h with the given time limit. -// -// The new Handler calls h.ServeHTTP to handle each request, but if a -// call runs for longer than its time limit, the handler responds with -// a 503 Service Unavailable error and the given message in its body. -// (If msg is empty, a suitable default message will be sent.) -// After such a timeout, writes by h to its ResponseWriter will return -// ErrHandlerTimeout. -func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler { - f := func() <-chan time.Time { - return time.After(dt) - } - return &timeoutHandler{h, f, msg} -} - -// ErrHandlerTimeout is returned on ResponseWriter Write calls -// in handlers which have timed out. -var ErrHandlerTimeout = errors.New("http: Handler timeout") - -type timeoutHandler struct { - handler Handler - timeout func() <-chan time.Time // returns channel producing a timeout - body string -} - -func (h *timeoutHandler) errorBody() string { - if h.body != "" { - return h.body - } - return "Timeout

Timeout

" -} - -func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) { - done := make(chan bool, 1) - tw := &timeoutWriter{w: w} - go func() { - h.handler.ServeHTTP(tw, r) - done <- true - }() - select { - case <-done: - return - case <-h.timeout(): - tw.mu.Lock() - defer tw.mu.Unlock() - if !tw.wroteHeader { - tw.w.WriteHeader(StatusServiceUnavailable) - tw.w.Write([]byte(h.errorBody())) - } - tw.timedOut = true - } -} - -type timeoutWriter struct { - w ResponseWriter - - mu sync.Mutex - timedOut bool - wroteHeader bool -} - -func (tw *timeoutWriter) Header() Header { - return tw.w.Header() -} - -func (tw *timeoutWriter) Write(p []byte) (int, error) { - tw.mu.Lock() - timedOut := tw.timedOut - tw.mu.Unlock() - if timedOut { - return 0, ErrHandlerTimeout - } - return tw.w.Write(p) -} - -func (tw *timeoutWriter) WriteHeader(code int) { - tw.mu.Lock() - if tw.timedOut || tw.wroteHeader { - tw.mu.Unlock() - return - } - tw.wroteHeader = true - tw.mu.Unlock() - tw.w.WriteHeader(code) -} - -// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted -// connections. It's used by ListenAndServe and ListenAndServeTLS so -// dead TCP connections (e.g. closing laptop mid-download) eventually -// go away. -type tcpKeepAliveListener struct { - *net.TCPListener -} - -func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) { - tc, err := ln.AcceptTCP() - if err != nil { - return - } - tc.SetKeepAlive(true) - tc.SetKeepAlivePeriod(3 * time.Minute) - return tc, nil -} - -// globalOptionsHandler responds to "OPTIONS *" requests. -type globalOptionsHandler struct{} - -func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) { - w.Header().Set("Content-Length", "0") - if r.ContentLength != 0 { - // Read up to 4KB of OPTIONS body (as mentioned in the - // spec as being reserved for future use), but anything - // over that is considered a waste of server resources - // (or an attack) and we abort and close the connection, - // courtesy of MaxBytesReader's EOF behavior. - mb := MaxBytesReader(w, r.Body, 4<<10) - io.Copy(ioutil.Discard, mb) - } -} - -type eofReaderWithWriteTo struct{} - -func (eofReaderWithWriteTo) WriteTo(io.Writer) (int64, error) { return 0, nil } -func (eofReaderWithWriteTo) Read([]byte) (int, error) { return 0, io.EOF } - -// eofReader is a non-nil io.ReadCloser that always returns EOF. -// It has a WriteTo method so io.Copy won't need a buffer. -var eofReader = &struct { - eofReaderWithWriteTo - io.Closer -}{ - eofReaderWithWriteTo{}, - ioutil.NopCloser(nil), -} - -// Verify that an io.Copy from an eofReader won't require a buffer. -var _ io.WriterTo = eofReader - -// initNPNRequest is an HTTP handler that initializes certain -// uninitialized fields in its *Request. Such partially-initialized -// Requests come from NPN protocol handlers. -type initNPNRequest struct { - c *tls.Conn - h serverHandler -} - -func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) { - if req.TLS == nil { - req.TLS = &tls.ConnectionState{} - *req.TLS = h.c.ConnectionState() - } - if req.Body == nil { - req.Body = eofReader - } - if req.RemoteAddr == "" { - req.RemoteAddr = h.c.RemoteAddr().String() - } - h.h.ServeHTTP(rw, req) -} - -// loggingConn is used for debugging. -type loggingConn struct { - name string - net.Conn -} - -var ( - uniqNameMu sync.Mutex - uniqNameNext = make(map[string]int) -) - -func newLoggingConn(baseName string, c net.Conn) net.Conn { - uniqNameMu.Lock() - defer uniqNameMu.Unlock() - uniqNameNext[baseName]++ - return &loggingConn{ - name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]), - Conn: c, - } -} - -func (c *loggingConn) Write(p []byte) (n int, err error) { - log.Printf("%s.Write(%d) = ....", c.name, len(p)) - n, err = c.Conn.Write(p) - log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err) - return -} - -func (c *loggingConn) Read(p []byte) (n int, err error) { - log.Printf("%s.Read(%d) = ....", c.name, len(p)) - n, err = c.Conn.Read(p) - log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err) - return -} - -func (c *loggingConn) Close() (err error) { - log.Printf("%s.Close() = ...", c.name) - err = c.Conn.Close() - log.Printf("%s.Close() = %v", c.name, err) - return -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/sniff.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/sniff.go deleted file mode 100644 index 68f519b054..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/sniff.go +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bytes" - "encoding/binary" -) - -// The algorithm uses at most sniffLen bytes to make its decision. -const sniffLen = 512 - -// DetectContentType implements the algorithm described -// at http://mimesniff.spec.whatwg.org/ to determine the -// Content-Type of the given data. It considers at most the -// first 512 bytes of data. DetectContentType always returns -// a valid MIME type: if it cannot determine a more specific one, it -// returns "application/octet-stream". -func DetectContentType(data []byte) string { - if len(data) > sniffLen { - data = data[:sniffLen] - } - - // Index of the first non-whitespace byte in data. - firstNonWS := 0 - for ; firstNonWS < len(data) && isWS(data[firstNonWS]); firstNonWS++ { - } - - for _, sig := range sniffSignatures { - if ct := sig.match(data, firstNonWS); ct != "" { - return ct - } - } - - return "application/octet-stream" // fallback -} - -func isWS(b byte) bool { - return bytes.IndexByte([]byte("\t\n\x0C\r "), b) != -1 -} - -type sniffSig interface { - // match returns the MIME type of the data, or "" if unknown. - match(data []byte, firstNonWS int) string -} - -// Data matching the table in section 6. -var sniffSignatures = []sniffSig{ - htmlSig("' { - return "" - } - return "text/html; charset=utf-8" -} - -type mp4Sig int - -func (mp4Sig) match(data []byte, firstNonWS int) string { - // c.f. section 6.1. - if len(data) < 8 { - return "" - } - boxSize := int(binary.BigEndian.Uint32(data[:4])) - if boxSize%4 != 0 || len(data) < boxSize { - return "" - } - if !bytes.Equal(data[4:8], []byte("ftyp")) { - return "" - } - for st := 8; st < boxSize; st += 4 { - if st == 12 { - // minor version number - continue - } - seg := string(data[st : st+3]) - switch seg { - case "mp4", "iso", "M4V", "M4P", "M4B": - return "video/mp4" - /* The remainder are not in the spec. - case "M4A": - return "audio/mp4" - case "3gp": - return "video/3gpp" - case "jp2": - return "image/jp2" // JPEG 2000 - */ - } - } - return "" -} - -type textSig int - -func (textSig) match(data []byte, firstNonWS int) string { - // c.f. section 5, step 4. - for _, b := range data[firstNonWS:] { - switch { - case 0x00 <= b && b <= 0x08, - b == 0x0B, - 0x0E <= b && b <= 0x1A, - 0x1C <= b && b <= 0x1F: - return "" - } - } - return "text/plain; charset=utf-8" -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/sniff_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/sniff_test.go deleted file mode 100644 index 24ca27afc1..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/sniff_test.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "log" - . "net/http" - "net/http/httptest" - "reflect" - "strconv" - "strings" - "testing" -) - -var sniffTests = []struct { - desc string - data []byte - contentType string -}{ - // Some nonsense. - {"Empty", []byte{}, "text/plain; charset=utf-8"}, - {"Binary", []byte{1, 2, 3}, "application/octet-stream"}, - - {"HTML document #1", []byte(`blah blah blah`), "text/html; charset=utf-8"}, - {"HTML document #2", []byte(``), "text/html; charset=utf-8"}, - {"HTML document #3 (leading whitespace)", []byte(` ...`), "text/html; charset=utf-8"}, - {"HTML document #4 (leading CRLF)", []byte("\r\n..."), "text/html; charset=utf-8"}, - - {"Plain text", []byte(`This is not HTML. It has ☃ though.`), "text/plain; charset=utf-8"}, - - {"XML", []byte("\nhi") - })) - defer ts.Close() - - resp, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - - got := resp.Header["Content-Type"] - want := []string{""} - if !reflect.DeepEqual(got, want) { - t.Errorf("Content-Type = %q; want %q", got, want) - } - resp.Body.Close() -} - -func TestContentTypeWithCopy(t *testing.T) { - defer afterTest(t) - - const ( - input = "\n\n\t\n" - expected = "text/html; charset=utf-8" - ) - - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - // Use io.Copy from a bytes.Buffer to trigger ReadFrom. - buf := bytes.NewBuffer([]byte(input)) - n, err := io.Copy(w, buf) - if int(n) != len(input) || err != nil { - t.Errorf("io.Copy(w, %q) = %v, %v want %d, nil", input, n, err, len(input)) - } - })) - defer ts.Close() - - resp, err := Get(ts.URL) - if err != nil { - t.Fatalf("Get: %v", err) - } - if ct := resp.Header.Get("Content-Type"); ct != expected { - t.Errorf("Content-Type = %q, want %q", ct, expected) - } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - t.Errorf("reading body: %v", err) - } else if !bytes.Equal(data, []byte(input)) { - t.Errorf("data is %q, want %q", data, input) - } - resp.Body.Close() -} - -func TestSniffWriteSize(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - size, _ := strconv.Atoi(r.FormValue("size")) - written, err := io.WriteString(w, strings.Repeat("a", size)) - if err != nil { - t.Errorf("write of %d bytes: %v", size, err) - return - } - if written != size { - t.Errorf("write of %d bytes wrote %d bytes", size, written) - } - })) - defer ts.Close() - for _, size := range []int{0, 1, 200, 600, 999, 1000, 1023, 1024, 512 << 10, 1 << 20} { - res, err := Get(fmt.Sprintf("%s/?size=%d", ts.URL, size)) - if err != nil { - t.Fatalf("size %d: %v", size, err) - } - if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { - t.Fatalf("size %d: io.Copy of body = %v", size, err) - } - if err := res.Body.Close(); err != nil { - t.Fatalf("size %d: body Close = %v", size, err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/status.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/status.go deleted file mode 100644 index d253bd5cb5..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/status.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -// HTTP status codes, defined in RFC 2616. -const ( - StatusContinue = 100 - StatusSwitchingProtocols = 101 - - StatusOK = 200 - StatusCreated = 201 - StatusAccepted = 202 - StatusNonAuthoritativeInfo = 203 - StatusNoContent = 204 - StatusResetContent = 205 - StatusPartialContent = 206 - - StatusMultipleChoices = 300 - StatusMovedPermanently = 301 - StatusFound = 302 - StatusSeeOther = 303 - StatusNotModified = 304 - StatusUseProxy = 305 - StatusTemporaryRedirect = 307 - - StatusBadRequest = 400 - StatusUnauthorized = 401 - StatusPaymentRequired = 402 - StatusForbidden = 403 - StatusNotFound = 404 - StatusMethodNotAllowed = 405 - StatusNotAcceptable = 406 - StatusProxyAuthRequired = 407 - StatusRequestTimeout = 408 - StatusConflict = 409 - StatusGone = 410 - StatusLengthRequired = 411 - StatusPreconditionFailed = 412 - StatusRequestEntityTooLarge = 413 - StatusRequestURITooLong = 414 - StatusUnsupportedMediaType = 415 - StatusRequestedRangeNotSatisfiable = 416 - StatusExpectationFailed = 417 - StatusTeapot = 418 - - StatusInternalServerError = 500 - StatusNotImplemented = 501 - StatusBadGateway = 502 - StatusServiceUnavailable = 503 - StatusGatewayTimeout = 504 - StatusHTTPVersionNotSupported = 505 - - // New HTTP status codes from RFC 6585. Not exported yet in Go 1.1. - // See discussion at https://codereview.appspot.com/7678043/ - statusPreconditionRequired = 428 - statusTooManyRequests = 429 - statusRequestHeaderFieldsTooLarge = 431 - statusNetworkAuthenticationRequired = 511 -) - -var statusText = map[int]string{ - StatusContinue: "Continue", - StatusSwitchingProtocols: "Switching Protocols", - - StatusOK: "OK", - StatusCreated: "Created", - StatusAccepted: "Accepted", - StatusNonAuthoritativeInfo: "Non-Authoritative Information", - StatusNoContent: "No Content", - StatusResetContent: "Reset Content", - StatusPartialContent: "Partial Content", - - StatusMultipleChoices: "Multiple Choices", - StatusMovedPermanently: "Moved Permanently", - StatusFound: "Found", - StatusSeeOther: "See Other", - StatusNotModified: "Not Modified", - StatusUseProxy: "Use Proxy", - StatusTemporaryRedirect: "Temporary Redirect", - - StatusBadRequest: "Bad Request", - StatusUnauthorized: "Unauthorized", - StatusPaymentRequired: "Payment Required", - StatusForbidden: "Forbidden", - StatusNotFound: "Not Found", - StatusMethodNotAllowed: "Method Not Allowed", - StatusNotAcceptable: "Not Acceptable", - StatusProxyAuthRequired: "Proxy Authentication Required", - StatusRequestTimeout: "Request Timeout", - StatusConflict: "Conflict", - StatusGone: "Gone", - StatusLengthRequired: "Length Required", - StatusPreconditionFailed: "Precondition Failed", - StatusRequestEntityTooLarge: "Request Entity Too Large", - StatusRequestURITooLong: "Request URI Too Long", - StatusUnsupportedMediaType: "Unsupported Media Type", - StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable", - StatusExpectationFailed: "Expectation Failed", - StatusTeapot: "I'm a teapot", - - StatusInternalServerError: "Internal Server Error", - StatusNotImplemented: "Not Implemented", - StatusBadGateway: "Bad Gateway", - StatusServiceUnavailable: "Service Unavailable", - StatusGatewayTimeout: "Gateway Timeout", - StatusHTTPVersionNotSupported: "HTTP Version Not Supported", - - statusPreconditionRequired: "Precondition Required", - statusTooManyRequests: "Too Many Requests", - statusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large", - statusNetworkAuthenticationRequired: "Network Authentication Required", -} - -// StatusText returns a text for the HTTP status code. It returns the empty -// string if the code is unknown. -func StatusText(code int) string { - return statusText[code] -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/file b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/file deleted file mode 100644 index 11f11f9be3..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/file +++ /dev/null @@ -1 +0,0 @@ -0123456789 diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/index.html b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/index.html deleted file mode 100644 index da8e1e93d1..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/index.html +++ /dev/null @@ -1 +0,0 @@ -index.html says hello diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/style.css b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/style.css deleted file mode 100644 index 208d16d421..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/testdata/style.css +++ /dev/null @@ -1 +0,0 @@ -body {} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transfer.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transfer.go deleted file mode 100644 index 7f63686528..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transfer.go +++ /dev/null @@ -1,730 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "net/textproto" - "sort" - "strconv" - "strings" - "sync" -) - -type errorReader struct { - err error -} - -func (r *errorReader) Read(p []byte) (n int, err error) { - return 0, r.err -} - -// transferWriter inspects the fields of a user-supplied Request or Response, -// sanitizes them without changing the user object and provides methods for -// writing the respective header, body and trailer in wire format. -type transferWriter struct { - Method string - Body io.Reader - BodyCloser io.Closer - ResponseToHEAD bool - ContentLength int64 // -1 means unknown, 0 means exactly none - Close bool - TransferEncoding []string - Trailer Header -} - -func newTransferWriter(r interface{}) (t *transferWriter, err error) { - t = &transferWriter{} - - // Extract relevant fields - atLeastHTTP11 := false - switch rr := r.(type) { - case *Request: - if rr.ContentLength != 0 && rr.Body == nil { - return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength) - } - t.Method = rr.Method - t.Body = rr.Body - t.BodyCloser = rr.Body - t.ContentLength = rr.ContentLength - t.Close = rr.Close - t.TransferEncoding = rr.TransferEncoding - t.Trailer = rr.Trailer - atLeastHTTP11 = rr.ProtoAtLeast(1, 1) - if t.Body != nil && len(t.TransferEncoding) == 0 && atLeastHTTP11 { - if t.ContentLength == 0 { - // Test to see if it's actually zero or just unset. - var buf [1]byte - n, rerr := io.ReadFull(t.Body, buf[:]) - if rerr != nil && rerr != io.EOF { - t.ContentLength = -1 - t.Body = &errorReader{rerr} - } else if n == 1 { - // Oh, guess there is data in this Body Reader after all. - // The ContentLength field just wasn't set. - // Stich the Body back together again, re-attaching our - // consumed byte. - t.ContentLength = -1 - t.Body = io.MultiReader(bytes.NewReader(buf[:]), t.Body) - } else { - // Body is actually empty. - t.Body = nil - t.BodyCloser = nil - } - } - if t.ContentLength < 0 { - t.TransferEncoding = []string{"chunked"} - } - } - case *Response: - if rr.Request != nil { - t.Method = rr.Request.Method - } - t.Body = rr.Body - t.BodyCloser = rr.Body - t.ContentLength = rr.ContentLength - t.Close = rr.Close - t.TransferEncoding = rr.TransferEncoding - t.Trailer = rr.Trailer - atLeastHTTP11 = rr.ProtoAtLeast(1, 1) - t.ResponseToHEAD = noBodyExpected(t.Method) - } - - // Sanitize Body,ContentLength,TransferEncoding - if t.ResponseToHEAD { - t.Body = nil - if chunked(t.TransferEncoding) { - t.ContentLength = -1 - } - } else { - if !atLeastHTTP11 || t.Body == nil { - t.TransferEncoding = nil - } - if chunked(t.TransferEncoding) { - t.ContentLength = -1 - } else if t.Body == nil { // no chunking, no body - t.ContentLength = 0 - } - } - - // Sanitize Trailer - if !chunked(t.TransferEncoding) { - t.Trailer = nil - } - - return t, nil -} - -func noBodyExpected(requestMethod string) bool { - return requestMethod == "HEAD" -} - -func (t *transferWriter) shouldSendContentLength() bool { - if chunked(t.TransferEncoding) { - return false - } - if t.ContentLength > 0 { - return true - } - // Many servers expect a Content-Length for these methods - if t.Method == "POST" || t.Method == "PUT" { - return true - } - if t.ContentLength == 0 && isIdentity(t.TransferEncoding) { - return true - } - - return false -} - -func (t *transferWriter) WriteHeader(w io.Writer) error { - if t.Close { - if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil { - return err - } - } - - // Write Content-Length and/or Transfer-Encoding whose values are a - // function of the sanitized field triple (Body, ContentLength, - // TransferEncoding) - if t.shouldSendContentLength() { - if _, err := io.WriteString(w, "Content-Length: "); err != nil { - return err - } - if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil { - return err - } - } else if chunked(t.TransferEncoding) { - if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil { - return err - } - } - - // Write Trailer header - if t.Trailer != nil { - keys := make([]string, 0, len(t.Trailer)) - for k := range t.Trailer { - k = CanonicalHeaderKey(k) - switch k { - case "Transfer-Encoding", "Trailer", "Content-Length": - return &badStringError{"invalid Trailer key", k} - } - keys = append(keys, k) - } - if len(keys) > 0 { - sort.Strings(keys) - // TODO: could do better allocation-wise here, but trailers are rare, - // so being lazy for now. - if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil { - return err - } - } - } - - return nil -} - -func (t *transferWriter) WriteBody(w io.Writer) error { - var err error - var ncopy int64 - - // Write body - if t.Body != nil { - if chunked(t.TransferEncoding) { - cw := newChunkedWriter(w) - _, err = io.Copy(cw, t.Body) - if err == nil { - err = cw.Close() - } - } else if t.ContentLength == -1 { - ncopy, err = io.Copy(w, t.Body) - } else { - ncopy, err = io.Copy(w, io.LimitReader(t.Body, t.ContentLength)) - if err != nil { - return err - } - var nextra int64 - nextra, err = io.Copy(ioutil.Discard, t.Body) - ncopy += nextra - } - if err != nil { - return err - } - if err = t.BodyCloser.Close(); err != nil { - return err - } - } - - if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy { - return fmt.Errorf("http: Request.ContentLength=%d with Body length %d", - t.ContentLength, ncopy) - } - - // TODO(petar): Place trailer writer code here. - if chunked(t.TransferEncoding) { - // Write Trailer header - if t.Trailer != nil { - if err := t.Trailer.Write(w); err != nil { - return err - } - } - // Last chunk, empty trailer - _, err = io.WriteString(w, "\r\n") - } - return err -} - -type transferReader struct { - // Input - Header Header - StatusCode int - RequestMethod string - ProtoMajor int - ProtoMinor int - // Output - Body io.ReadCloser - ContentLength int64 - TransferEncoding []string - Close bool - Trailer Header -} - -// bodyAllowedForStatus reports whether a given response status code -// permits a body. See RFC2616, section 4.4. -func bodyAllowedForStatus(status int) bool { - switch { - case status >= 100 && status <= 199: - return false - case status == 204: - return false - case status == 304: - return false - } - return true -} - -var ( - suppressedHeaders304 = []string{"Content-Type", "Content-Length", "Transfer-Encoding"} - suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"} -) - -func suppressedHeaders(status int) []string { - switch { - case status == 304: - // RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers" - return suppressedHeaders304 - case !bodyAllowedForStatus(status): - return suppressedHeadersNoBody - } - return nil -} - -// msg is *Request or *Response. -func readTransfer(msg interface{}, r *bufio.Reader) (err error) { - t := &transferReader{RequestMethod: "GET"} - - // Unify input - isResponse := false - switch rr := msg.(type) { - case *Response: - t.Header = rr.Header - t.StatusCode = rr.StatusCode - t.ProtoMajor = rr.ProtoMajor - t.ProtoMinor = rr.ProtoMinor - t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header) - isResponse = true - if rr.Request != nil { - t.RequestMethod = rr.Request.Method - } - case *Request: - t.Header = rr.Header - t.ProtoMajor = rr.ProtoMajor - t.ProtoMinor = rr.ProtoMinor - // Transfer semantics for Requests are exactly like those for - // Responses with status code 200, responding to a GET method - t.StatusCode = 200 - default: - panic("unexpected type") - } - - // Default to HTTP/1.1 - if t.ProtoMajor == 0 && t.ProtoMinor == 0 { - t.ProtoMajor, t.ProtoMinor = 1, 1 - } - - // Transfer encoding, content length - t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header) - if err != nil { - return err - } - - realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) - if err != nil { - return err - } - if isResponse && t.RequestMethod == "HEAD" { - if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil { - return err - } else { - t.ContentLength = n - } - } else { - t.ContentLength = realLength - } - - // Trailer - t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) - if err != nil { - return err - } - - // If there is no Content-Length or chunked Transfer-Encoding on a *Response - // and the status is not 1xx, 204 or 304, then the body is unbounded. - // See RFC2616, section 4.4. - switch msg.(type) { - case *Response: - if realLength == -1 && - !chunked(t.TransferEncoding) && - bodyAllowedForStatus(t.StatusCode) { - // Unbounded body. - t.Close = true - } - } - - // Prepare body reader. ContentLength < 0 means chunked encoding - // or close connection when finished, since multipart is not supported yet - switch { - case chunked(t.TransferEncoding): - if noBodyExpected(t.RequestMethod) { - t.Body = eofReader - } else { - t.Body = &body{src: newChunkedReader(r), hdr: msg, r: r, closing: t.Close} - } - case realLength == 0: - t.Body = eofReader - case realLength > 0: - t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close} - default: - // realLength < 0, i.e. "Content-Length" not mentioned in header - if t.Close { - // Close semantics (i.e. HTTP/1.0) - t.Body = &body{src: r, closing: t.Close} - } else { - // Persistent connection (i.e. HTTP/1.1) - t.Body = eofReader - } - } - - // Unify output - switch rr := msg.(type) { - case *Request: - rr.Body = t.Body - rr.ContentLength = t.ContentLength - rr.TransferEncoding = t.TransferEncoding - rr.Close = t.Close - rr.Trailer = t.Trailer - case *Response: - rr.Body = t.Body - rr.ContentLength = t.ContentLength - rr.TransferEncoding = t.TransferEncoding - rr.Close = t.Close - rr.Trailer = t.Trailer - } - - return nil -} - -// Checks whether chunked is part of the encodings stack -func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" } - -// Checks whether the encoding is explicitly "identity". -func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" } - -// Sanitize transfer encoding -func fixTransferEncoding(requestMethod string, header Header) ([]string, error) { - raw, present := header["Transfer-Encoding"] - if !present { - return nil, nil - } - - delete(header, "Transfer-Encoding") - - encodings := strings.Split(raw[0], ",") - te := make([]string, 0, len(encodings)) - // TODO: Even though we only support "identity" and "chunked" - // encodings, the loop below is designed with foresight. One - // invariant that must be maintained is that, if present, - // chunked encoding must always come first. - for _, encoding := range encodings { - encoding = strings.ToLower(strings.TrimSpace(encoding)) - // "identity" encoding is not recorded - if encoding == "identity" { - break - } - if encoding != "chunked" { - return nil, &badStringError{"unsupported transfer encoding", encoding} - } - te = te[0 : len(te)+1] - te[len(te)-1] = encoding - } - if len(te) > 1 { - return nil, &badStringError{"too many transfer encodings", strings.Join(te, ",")} - } - if len(te) > 0 { - // Chunked encoding trumps Content-Length. See RFC 2616 - // Section 4.4. Currently len(te) > 0 implies chunked - // encoding. - delete(header, "Content-Length") - return te, nil - } - - return nil, nil -} - -// Determine the expected body length, using RFC 2616 Section 4.4. This -// function is not a method, because ultimately it should be shared by -// ReadResponse and ReadRequest. -func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { - - // Logic based on response type or status - if noBodyExpected(requestMethod) { - return 0, nil - } - if status/100 == 1 { - return 0, nil - } - switch status { - case 204, 304: - return 0, nil - } - - // Logic based on Transfer-Encoding - if chunked(te) { - return -1, nil - } - - // Logic based on Content-Length - cl := strings.TrimSpace(header.get("Content-Length")) - if cl != "" { - n, err := parseContentLength(cl) - if err != nil { - return -1, err - } - return n, nil - } else { - header.Del("Content-Length") - } - - if !isResponse && requestMethod == "GET" { - // RFC 2616 doesn't explicitly permit nor forbid an - // entity-body on a GET request so we permit one if - // declared, but we default to 0 here (not -1 below) - // if there's no mention of a body. - return 0, nil - } - - // Body-EOF logic based on other methods (like closing, or chunked coding) - return -1, nil -} - -// Determine whether to hang up after sending a request and body, or -// receiving a response and body -// 'header' is the request headers -func shouldClose(major, minor int, header Header) bool { - if major < 1 { - return true - } else if major == 1 && minor == 0 { - if !strings.Contains(strings.ToLower(header.get("Connection")), "keep-alive") { - return true - } - return false - } else { - // TODO: Should split on commas, toss surrounding white space, - // and check each field. - if strings.ToLower(header.get("Connection")) == "close" { - header.Del("Connection") - return true - } - } - return false -} - -// Parse the trailer header -func fixTrailer(header Header, te []string) (Header, error) { - raw := header.get("Trailer") - if raw == "" { - return nil, nil - } - - header.Del("Trailer") - trailer := make(Header) - keys := strings.Split(raw, ",") - for _, key := range keys { - key = CanonicalHeaderKey(strings.TrimSpace(key)) - switch key { - case "Transfer-Encoding", "Trailer", "Content-Length": - return nil, &badStringError{"bad trailer key", key} - } - trailer[key] = nil - } - if len(trailer) == 0 { - return nil, nil - } - if !chunked(te) { - // Trailer and no chunking - return nil, ErrUnexpectedTrailer - } - return trailer, nil -} - -// body turns a Reader into a ReadCloser. -// Close ensures that the body has been fully read -// and then reads the trailer if necessary. -type body struct { - src io.Reader - hdr interface{} // non-nil (Response or Request) value means read trailer - r *bufio.Reader // underlying wire-format reader for the trailer - closing bool // is the connection to be closed after reading body? - - mu sync.Mutex // guards closed, and calls to Read and Close - closed bool -} - -// ErrBodyReadAfterClose is returned when reading a Request or Response -// Body after the body has been closed. This typically happens when the body is -// read after an HTTP Handler calls WriteHeader or Write on its -// ResponseWriter. -var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body") - -func (b *body) Read(p []byte) (n int, err error) { - b.mu.Lock() - defer b.mu.Unlock() - if b.closed { - return 0, ErrBodyReadAfterClose - } - return b.readLocked(p) -} - -// Must hold b.mu. -func (b *body) readLocked(p []byte) (n int, err error) { - n, err = b.src.Read(p) - - if err == io.EOF { - // Chunked case. Read the trailer. - if b.hdr != nil { - if e := b.readTrailer(); e != nil { - err = e - } - b.hdr = nil - } else { - // If the server declared the Content-Length, our body is a LimitedReader - // and we need to check whether this EOF arrived early. - if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 { - err = io.ErrUnexpectedEOF - } - } - } - - // If we can return an EOF here along with the read data, do - // so. This is optional per the io.Reader contract, but doing - // so helps the HTTP transport code recycle its connection - // earlier (since it will see this EOF itself), even if the - // client doesn't do future reads or Close. - if err == nil && n > 0 { - if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 { - err = io.EOF - } - } - - return n, err -} - -var ( - singleCRLF = []byte("\r\n") - doubleCRLF = []byte("\r\n\r\n") -) - -func seeUpcomingDoubleCRLF(r *bufio.Reader) bool { - for peekSize := 4; ; peekSize++ { - // This loop stops when Peek returns an error, - // which it does when r's buffer has been filled. - buf, err := r.Peek(peekSize) - if bytes.HasSuffix(buf, doubleCRLF) { - return true - } - if err != nil { - break - } - } - return false -} - -var errTrailerEOF = errors.New("http: unexpected EOF reading trailer") - -func (b *body) readTrailer() error { - // The common case, since nobody uses trailers. - buf, err := b.r.Peek(2) - if bytes.Equal(buf, singleCRLF) { - b.r.ReadByte() - b.r.ReadByte() - return nil - } - if len(buf) < 2 { - return errTrailerEOF - } - if err != nil { - return err - } - - // Make sure there's a header terminator coming up, to prevent - // a DoS with an unbounded size Trailer. It's not easy to - // slip in a LimitReader here, as textproto.NewReader requires - // a concrete *bufio.Reader. Also, we can't get all the way - // back up to our conn's LimitedReader that *might* be backing - // this bufio.Reader. Instead, a hack: we iteratively Peek up - // to the bufio.Reader's max size, looking for a double CRLF. - // This limits the trailer to the underlying buffer size, typically 4kB. - if !seeUpcomingDoubleCRLF(b.r) { - return errors.New("http: suspiciously long trailer after chunked body") - } - - hdr, err := textproto.NewReader(b.r).ReadMIMEHeader() - if err != nil { - if err == io.EOF { - return errTrailerEOF - } - return err - } - switch rr := b.hdr.(type) { - case *Request: - mergeSetHeader(&rr.Trailer, Header(hdr)) - case *Response: - mergeSetHeader(&rr.Trailer, Header(hdr)) - } - return nil -} - -func mergeSetHeader(dst *Header, src Header) { - if *dst == nil { - *dst = src - return - } - for k, vv := range src { - (*dst)[k] = vv - } -} - -func (b *body) Close() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.closed { - return nil - } - var err error - switch { - case b.hdr == nil && b.closing: - // no trailer and closing the connection next. - // no point in reading to EOF. - default: - // Fully consume the body, which will also lead to us reading - // the trailer headers after the body, if present. - _, err = io.Copy(ioutil.Discard, bodyLocked{b}) - } - b.closed = true - return err -} - -// bodyLocked is a io.Reader reading from a *body when its mutex is -// already held. -type bodyLocked struct { - b *body -} - -func (bl bodyLocked) Read(p []byte) (n int, err error) { - if bl.b.closed { - return 0, ErrBodyReadAfterClose - } - return bl.b.readLocked(p) -} - -// parseContentLength trims whitespace from s and returns -1 if no value -// is set, or the value if it's >= 0. -func parseContentLength(cl string) (int64, error) { - cl = strings.TrimSpace(cl) - if cl == "" { - return -1, nil - } - n, err := strconv.ParseInt(cl, 10, 64) - if err != nil || n < 0 { - return 0, &badStringError{"bad Content-Length", cl} - } - return n, nil - -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transfer_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transfer_test.go deleted file mode 100644 index 48cd540b9f..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transfer_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "bufio" - "io" - "strings" - "testing" -) - -func TestBodyReadBadTrailer(t *testing.T) { - b := &body{ - src: strings.NewReader("foobar"), - hdr: true, // force reading the trailer - r: bufio.NewReader(strings.NewReader("")), - } - buf := make([]byte, 7) - n, err := b.Read(buf[:3]) - got := string(buf[:n]) - if got != "foo" || err != nil { - t.Fatalf(`first Read = %d (%q), %v; want 3 ("foo")`, n, got, err) - } - - n, err = b.Read(buf[:]) - got = string(buf[:n]) - if got != "bar" || err != nil { - t.Fatalf(`second Read = %d (%q), %v; want 3 ("bar")`, n, got, err) - } - - n, err = b.Read(buf[:]) - got = string(buf[:n]) - if err == nil { - t.Errorf("final Read was successful (%q), expected error from trailer read", got) - } -} - -func TestFinalChunkedBodyReadEOF(t *testing.T) { - res, err := ReadResponse(bufio.NewReader(strings.NewReader( - "HTTP/1.1 200 OK\r\n"+ - "Transfer-Encoding: chunked\r\n"+ - "\r\n"+ - "0a\r\n"+ - "Body here\n\r\n"+ - "09\r\n"+ - "continued\r\n"+ - "0\r\n"+ - "\r\n")), nil) - if err != nil { - t.Fatal(err) - } - want := "Body here\ncontinued" - buf := make([]byte, len(want)) - n, err := res.Body.Read(buf) - if n != len(want) || err != io.EOF { - t.Logf("body = %#v", res.Body) - t.Errorf("Read = %v, %v; want %d, EOF", n, err, len(want)) - } - if string(buf) != want { - t.Errorf("buf = %q; want %q", buf, want) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transport.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transport.go deleted file mode 100644 index 144b01e33b..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transport.go +++ /dev/null @@ -1,1208 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// HTTP client implementation. See RFC 2616. -// -// This is the low-level Transport implementation of RoundTripper. -// The high-level interface is in client.go. - -package http - -import ( - "bufio" - "compress/gzip" - "errors" - "fmt" - "github.com/MSOpenTech/azure-sdk-for-go/core/tls" - "io" - "log" - "net" - "net/url" - "os" - "strings" - "sync" - "time" -) - -// DefaultTransport is the default implementation of Transport and is -// used by DefaultClient. It establishes network connections as needed -// and caches them for reuse by subsequent calls. It uses HTTP proxies -// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and -// $no_proxy) environment variables. -var DefaultTransport RoundTripper = &Transport{ - Proxy: ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, -} - -// DefaultMaxIdleConnsPerHost is the default value of Transport's -// MaxIdleConnsPerHost. -const DefaultMaxIdleConnsPerHost = 2 - -// Transport is an implementation of RoundTripper that supports http, -// https, and http proxies (for either http or https with CONNECT). -// Transport can also cache connections for future re-use. -type Transport struct { - idleMu sync.Mutex - idleConn map[connectMethodKey][]*persistConn - idleConnCh map[connectMethodKey]chan *persistConn - reqMu sync.Mutex - reqCanceler map[*Request]func() - altMu sync.RWMutex - altProto map[string]RoundTripper // nil or map of URI scheme => RoundTripper - - // Proxy specifies a function to return a proxy for a given - // Request. If the function returns a non-nil error, the - // request is aborted with the provided error. - // If Proxy is nil or returns a nil *URL, no proxy is used. - Proxy func(*Request) (*url.URL, error) - - // Dial specifies the dial function for creating TCP - // connections. - // If Dial is nil, net.Dial is used. - Dial func(network, addr string) (net.Conn, error) - - // TLSClientConfig specifies the TLS configuration to use with - // tls.Client. If nil, the default configuration is used. - TLSClientConfig *tls.Config - - // TLSHandshakeTimeout specifies the maximum amount of time waiting to - // wait for a TLS handshake. Zero means no timeout. - TLSHandshakeTimeout time.Duration - - // DisableKeepAlives, if true, prevents re-use of TCP connections - // between different HTTP requests. - DisableKeepAlives bool - - // DisableCompression, if true, prevents the Transport from - // requesting compression with an "Accept-Encoding: gzip" - // request header when the Request contains no existing - // Accept-Encoding value. If the Transport requests gzip on - // its own and gets a gzipped response, it's transparently - // decoded in the Response.Body. However, if the user - // explicitly requested gzip it is not automatically - // uncompressed. - DisableCompression bool - - // MaxIdleConnsPerHost, if non-zero, controls the maximum idle - // (keep-alive) to keep per-host. If zero, - // DefaultMaxIdleConnsPerHost is used. - MaxIdleConnsPerHost int - - // ResponseHeaderTimeout, if non-zero, specifies the amount of - // time to wait for a server's response headers after fully - // writing the request (including its body, if any). This - // time does not include the time to read the response body. - ResponseHeaderTimeout time.Duration - - // TODO: tunable on global max cached connections - // TODO: tunable on timeout on cached connections -} - -// ProxyFromEnvironment returns the URL of the proxy to use for a -// given request, as indicated by the environment variables -// $HTTP_PROXY and $NO_PROXY (or $http_proxy and $no_proxy). -// An error is returned if the proxy environment is invalid. -// A nil URL and nil error are returned if no proxy is defined in the -// environment, or a proxy should not be used for the given request. -// -// As a special case, if req.URL.Host is "localhost" (with or without -// a port number), then a nil URL and nil error will be returned. -func ProxyFromEnvironment(req *Request) (*url.URL, error) { - proxy := httpProxyEnv.Get() - if proxy == "" { - return nil, nil - } - if !useProxy(canonicalAddr(req.URL)) { - return nil, nil - } - proxyURL, err := url.Parse(proxy) - if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") { - // proxy was bogus. Try prepending "http://" to it and - // see if that parses correctly. If not, we fall - // through and complain about the original one. - if proxyURL, err := url.Parse("http://" + proxy); err == nil { - return proxyURL, nil - } - } - if err != nil { - return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err) - } - return proxyURL, nil -} - -// ProxyURL returns a proxy function (for use in a Transport) -// that always returns the same URL. -func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) { - return func(*Request) (*url.URL, error) { - return fixedURL, nil - } -} - -// transportRequest is a wrapper around a *Request that adds -// optional extra headers to write. -type transportRequest struct { - *Request // original request, not to be mutated - extra Header // extra headers to write, or nil -} - -func (tr *transportRequest) extraHeaders() Header { - if tr.extra == nil { - tr.extra = make(Header) - } - return tr.extra -} - -// RoundTrip implements the RoundTripper interface. -// -// For higher-level HTTP client support (such as handling of cookies -// and redirects), see Get, Post, and the Client type. -func (t *Transport) RoundTrip(req *Request) (resp *Response, err error) { - if req.URL == nil { - req.closeBody() - return nil, errors.New("http: nil Request.URL") - } - if req.Header == nil { - req.closeBody() - return nil, errors.New("http: nil Request.Header") - } - if req.URL.Scheme != "http" && req.URL.Scheme != "https" { - t.altMu.RLock() - var rt RoundTripper - if t.altProto != nil { - rt = t.altProto[req.URL.Scheme] - } - t.altMu.RUnlock() - if rt == nil { - req.closeBody() - return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme} - } - return rt.RoundTrip(req) - } - if req.URL.Host == "" { - req.closeBody() - return nil, errors.New("http: no Host in request URL") - } - treq := &transportRequest{Request: req} - cm, err := t.connectMethodForRequest(treq) - if err != nil { - req.closeBody() - return nil, err - } - - // Get the cached or newly-created connection to either the - // host (for http or https), the http proxy, or the http proxy - // pre-CONNECTed to https server. In any case, we'll be ready - // to send it requests. - pconn, err := t.getConn(req, cm) - if err != nil { - t.setReqCanceler(req, nil) - req.closeBody() - return nil, err - } - - return pconn.roundTrip(treq) -} - -// RegisterProtocol registers a new protocol with scheme. -// The Transport will pass requests using the given scheme to rt. -// It is rt's responsibility to simulate HTTP request semantics. -// -// RegisterProtocol can be used by other packages to provide -// implementations of protocol schemes like "ftp" or "file". -func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) { - if scheme == "http" || scheme == "https" { - panic("protocol " + scheme + " already registered") - } - t.altMu.Lock() - defer t.altMu.Unlock() - if t.altProto == nil { - t.altProto = make(map[string]RoundTripper) - } - if _, exists := t.altProto[scheme]; exists { - panic("protocol " + scheme + " already registered") - } - t.altProto[scheme] = rt -} - -// CloseIdleConnections closes any connections which were previously -// connected from previous requests but are now sitting idle in -// a "keep-alive" state. It does not interrupt any connections currently -// in use. -func (t *Transport) CloseIdleConnections() { - t.idleMu.Lock() - m := t.idleConn - t.idleConn = nil - t.idleConnCh = nil - t.idleMu.Unlock() - for _, conns := range m { - for _, pconn := range conns { - pconn.close() - } - } -} - -// CancelRequest cancels an in-flight request by closing its -// connection. -func (t *Transport) CancelRequest(req *Request) { - t.reqMu.Lock() - cancel := t.reqCanceler[req] - t.reqMu.Unlock() - if cancel != nil { - cancel() - } -} - -// -// Private implementation past this point. -// - -var ( - httpProxyEnv = &envOnce{ - names: []string{"HTTP_PROXY", "http_proxy"}, - } - noProxyEnv = &envOnce{ - names: []string{"NO_PROXY", "no_proxy"}, - } -) - -// envOnce looks up an environment variable (optionally by multiple -// names) once. It mitigates expensive lookups on some platforms -// (e.g. Windows). -type envOnce struct { - names []string - once sync.Once - val string -} - -func (e *envOnce) Get() string { - e.once.Do(e.init) - return e.val -} - -func (e *envOnce) init() { - for _, n := range e.names { - e.val = os.Getenv(n) - if e.val != "" { - return - } - } -} - -// reset is used by tests -func (e *envOnce) reset() { - e.once = sync.Once{} - e.val = "" -} - -func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) { - cm.targetScheme = treq.URL.Scheme - cm.targetAddr = canonicalAddr(treq.URL) - if t.Proxy != nil { - cm.proxyURL, err = t.Proxy(treq.Request) - } - return cm, nil -} - -// proxyAuth returns the Proxy-Authorization header to set -// on requests, if applicable. -func (cm *connectMethod) proxyAuth() string { - if cm.proxyURL == nil { - return "" - } - if u := cm.proxyURL.User; u != nil { - username := u.Username() - password, _ := u.Password() - return "Basic " + basicAuth(username, password) - } - return "" -} - -// putIdleConn adds pconn to the list of idle persistent connections awaiting -// a new request. -// If pconn is no longer needed or not in a good state, putIdleConn -// returns false. -func (t *Transport) putIdleConn(pconn *persistConn) bool { - if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 { - pconn.close() - return false - } - if pconn.isBroken() { - return false - } - key := pconn.cacheKey - max := t.MaxIdleConnsPerHost - if max == 0 { - max = DefaultMaxIdleConnsPerHost - } - t.idleMu.Lock() - - waitingDialer := t.idleConnCh[key] - select { - case waitingDialer <- pconn: - // We're done with this pconn and somebody else is - // currently waiting for a conn of this type (they're - // actively dialing, but this conn is ready - // first). Chrome calls this socket late binding. See - // https://insouciant.org/tech/connection-management-in-chromium/ - t.idleMu.Unlock() - return true - default: - if waitingDialer != nil { - // They had populated this, but their dial won - // first, so we can clean up this map entry. - delete(t.idleConnCh, key) - } - } - if t.idleConn == nil { - t.idleConn = make(map[connectMethodKey][]*persistConn) - } - if len(t.idleConn[key]) >= max { - t.idleMu.Unlock() - pconn.close() - return false - } - for _, exist := range t.idleConn[key] { - if exist == pconn { - log.Fatalf("dup idle pconn %p in freelist", pconn) - } - } - t.idleConn[key] = append(t.idleConn[key], pconn) - t.idleMu.Unlock() - return true -} - -// getIdleConnCh returns a channel to receive and return idle -// persistent connection for the given connectMethod. -// It may return nil, if persistent connections are not being used. -func (t *Transport) getIdleConnCh(cm connectMethod) chan *persistConn { - if t.DisableKeepAlives { - return nil - } - key := cm.key() - t.idleMu.Lock() - defer t.idleMu.Unlock() - if t.idleConnCh == nil { - t.idleConnCh = make(map[connectMethodKey]chan *persistConn) - } - ch, ok := t.idleConnCh[key] - if !ok { - ch = make(chan *persistConn) - t.idleConnCh[key] = ch - } - return ch -} - -func (t *Transport) getIdleConn(cm connectMethod) (pconn *persistConn) { - key := cm.key() - t.idleMu.Lock() - defer t.idleMu.Unlock() - if t.idleConn == nil { - return nil - } - for { - pconns, ok := t.idleConn[key] - if !ok { - return nil - } - if len(pconns) == 1 { - pconn = pconns[0] - delete(t.idleConn, key) - } else { - // 2 or more cached connections; pop last - // TODO: queue? - pconn = pconns[len(pconns)-1] - t.idleConn[key] = pconns[:len(pconns)-1] - } - if !pconn.isBroken() { - return - } - } -} - -func (t *Transport) setReqCanceler(r *Request, fn func()) { - t.reqMu.Lock() - defer t.reqMu.Unlock() - if t.reqCanceler == nil { - t.reqCanceler = make(map[*Request]func()) - } - if fn != nil { - t.reqCanceler[r] = fn - } else { - delete(t.reqCanceler, r) - } -} - -func (t *Transport) dial(network, addr string) (c net.Conn, err error) { - if t.Dial != nil { - return t.Dial(network, addr) - } - return net.Dial(network, addr) -} - -// getConn dials and creates a new persistConn to the target as -// specified in the connectMethod. This includes doing a proxy CONNECT -// and/or setting up TLS. If this doesn't return an error, the persistConn -// is ready to write requests to. -func (t *Transport) getConn(req *Request, cm connectMethod) (*persistConn, error) { - if pc := t.getIdleConn(cm); pc != nil { - return pc, nil - } - - type dialRes struct { - pc *persistConn - err error - } - dialc := make(chan dialRes) - - handlePendingDial := func() { - if v := <-dialc; v.err == nil { - t.putIdleConn(v.pc) - } - } - - cancelc := make(chan struct{}) - t.setReqCanceler(req, func() { close(cancelc) }) - - go func() { - pc, err := t.dialConn(cm) - dialc <- dialRes{pc, err} - }() - - idleConnCh := t.getIdleConnCh(cm) - select { - case v := <-dialc: - // Our dial finished. - return v.pc, v.err - case pc := <-idleConnCh: - // Another request finished first and its net.Conn - // became available before our dial. Or somebody - // else's dial that they didn't use. - // But our dial is still going, so give it away - // when it finishes: - go handlePendingDial() - return pc, nil - case <-cancelc: - go handlePendingDial() - return nil, errors.New("net/http: request canceled while waiting for connection") - } -} - -func (t *Transport) dialConn(cm connectMethod) (*persistConn, error) { - conn, err := t.dial("tcp", cm.addr()) - if err != nil { - if cm.proxyURL != nil { - err = fmt.Errorf("http: error connecting to proxy %s: %v", cm.proxyURL, err) - } - return nil, err - } - - pa := cm.proxyAuth() - - pconn := &persistConn{ - t: t, - cacheKey: cm.key(), - conn: conn, - reqch: make(chan requestAndChan, 1), - writech: make(chan writeRequest, 1), - closech: make(chan struct{}), - writeErrCh: make(chan error, 1), - } - - switch { - case cm.proxyURL == nil: - // Do nothing. - case cm.targetScheme == "http": - pconn.isProxy = true - if pa != "" { - pconn.mutateHeaderFunc = func(h Header) { - h.Set("Proxy-Authorization", pa) - } - } - case cm.targetScheme == "https": - connectReq := &Request{ - Method: "CONNECT", - URL: &url.URL{Opaque: cm.targetAddr}, - Host: cm.targetAddr, - Header: make(Header), - } - if pa != "" { - connectReq.Header.Set("Proxy-Authorization", pa) - } - connectReq.Write(conn) - - // Read response. - // Okay to use and discard buffered reader here, because - // TLS server will not speak until spoken to. - br := bufio.NewReader(conn) - resp, err := ReadResponse(br, connectReq) - if err != nil { - conn.Close() - return nil, err - } - if resp.StatusCode != 200 { - f := strings.SplitN(resp.Status, " ", 2) - conn.Close() - return nil, errors.New(f[1]) - } - } - - if cm.targetScheme == "https" { - // Initiate TLS and check remote host name against certificate. - cfg := t.TLSClientConfig - if cfg == nil || cfg.ServerName == "" { - host := cm.tlsHost() - if cfg == nil { - cfg = &tls.Config{ServerName: host} - } else { - clone := *cfg // shallow clone - clone.ServerName = host - cfg = &clone - } - } - plainConn := conn - tlsConn := tls.Client(plainConn, cfg) - errc := make(chan error, 2) - var timer *time.Timer // for canceling TLS handshake - if d := t.TLSHandshakeTimeout; d != 0 { - timer = time.AfterFunc(d, func() { - errc <- tlsHandshakeTimeoutError{} - }) - } - go func() { - err := tlsConn.Handshake() - if timer != nil { - timer.Stop() - } - errc <- err - }() - if err := <-errc; err != nil { - plainConn.Close() - return nil, err - } - if !cfg.InsecureSkipVerify { - if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { - plainConn.Close() - return nil, err - } - } - cs := tlsConn.ConnectionState() - pconn.tlsState = &cs - pconn.conn = tlsConn - } - - pconn.br = bufio.NewReader(noteEOFReader{pconn.conn, &pconn.sawEOF}) - pconn.bw = bufio.NewWriter(pconn.conn) - go pconn.readLoop() - go pconn.writeLoop() - return pconn, nil -} - -// useProxy returns true if requests to addr should use a proxy, -// according to the NO_PROXY or no_proxy environment variable. -// addr is always a canonicalAddr with a host and port. -func useProxy(addr string) bool { - if len(addr) == 0 { - return true - } - host, _, err := net.SplitHostPort(addr) - if err != nil { - return false - } - if host == "localhost" { - return false - } - if ip := net.ParseIP(host); ip != nil { - if ip.IsLoopback() { - return false - } - } - - no_proxy := noProxyEnv.Get() - if no_proxy == "*" { - return false - } - - addr = strings.ToLower(strings.TrimSpace(addr)) - if hasPort(addr) { - addr = addr[:strings.LastIndex(addr, ":")] - } - - for _, p := range strings.Split(no_proxy, ",") { - p = strings.ToLower(strings.TrimSpace(p)) - if len(p) == 0 { - continue - } - if hasPort(p) { - p = p[:strings.LastIndex(p, ":")] - } - if addr == p { - return false - } - if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) { - // no_proxy ".foo.com" matches "bar.foo.com" or "foo.com" - return false - } - if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' { - // no_proxy "foo.com" matches "bar.foo.com" - return false - } - } - return true -} - -// connectMethod is the map key (in its String form) for keeping persistent -// TCP connections alive for subsequent HTTP requests. -// -// A connect method may be of the following types: -// -// Cache key form Description -// ----------------- ------------------------- -// |http|foo.com http directly to server, no proxy -// |https|foo.com https directly to server, no proxy -// http://proxy.com|https|foo.com http to proxy, then CONNECT to foo.com -// http://proxy.com|http http to proxy, http to anywhere after that -// -// Note: no support to https to the proxy yet. -// -type connectMethod struct { - proxyURL *url.URL // nil for no proxy, else full proxy URL - targetScheme string // "http" or "https" - targetAddr string // Not used if proxy + http targetScheme (4th example in table) -} - -func (cm *connectMethod) key() connectMethodKey { - proxyStr := "" - targetAddr := cm.targetAddr - if cm.proxyURL != nil { - proxyStr = cm.proxyURL.String() - if cm.targetScheme == "http" { - targetAddr = "" - } - } - return connectMethodKey{ - proxy: proxyStr, - scheme: cm.targetScheme, - addr: targetAddr, - } -} - -// addr returns the first hop "host:port" to which we need to TCP connect. -func (cm *connectMethod) addr() string { - if cm.proxyURL != nil { - return canonicalAddr(cm.proxyURL) - } - return cm.targetAddr -} - -// tlsHost returns the host name to match against the peer's -// TLS certificate. -func (cm *connectMethod) tlsHost() string { - h := cm.targetAddr - if hasPort(h) { - h = h[:strings.LastIndex(h, ":")] - } - return h -} - -// connectMethodKey is the map key version of connectMethod, with a -// stringified proxy URL (or the empty string) instead of a pointer to -// a URL. -type connectMethodKey struct { - proxy, scheme, addr string -} - -func (k connectMethodKey) String() string { - // Only used by tests. - return fmt.Sprintf("%s|%s|%s", k.proxy, k.scheme, k.addr) -} - -// persistConn wraps a connection, usually a persistent one -// (but may be used for non-keep-alive requests as well) -type persistConn struct { - t *Transport - cacheKey connectMethodKey - conn net.Conn - tlsState *tls.ConnectionState - br *bufio.Reader // from conn - sawEOF bool // whether we've seen EOF from conn; owned by readLoop - bw *bufio.Writer // to conn - reqch chan requestAndChan // written by roundTrip; read by readLoop - writech chan writeRequest // written by roundTrip; read by writeLoop - closech chan struct{} // closed when conn closed - isProxy bool - // writeErrCh passes the request write error (usually nil) - // from the writeLoop goroutine to the readLoop which passes - // it off to the res.Body reader, which then uses it to decide - // whether or not a connection can be reused. Issue 7569. - writeErrCh chan error - - lk sync.Mutex // guards following fields - numExpectedResponses int - closed bool // whether conn has been closed - broken bool // an error has happened on this connection; marked broken so it's not reused. - // mutateHeaderFunc is an optional func to modify extra - // headers on each outbound request before it's written. (the - // original Request given to RoundTrip is not modified) - mutateHeaderFunc func(Header) -} - -// isBroken reports whether this connection is in a known broken state. -func (pc *persistConn) isBroken() bool { - pc.lk.Lock() - b := pc.broken - pc.lk.Unlock() - return b -} - -func (pc *persistConn) cancelRequest() { - pc.conn.Close() -} - -var remoteSideClosedFunc func(error) bool // or nil to use default - -func remoteSideClosed(err error) bool { - if err == io.EOF { - return true - } - if remoteSideClosedFunc != nil { - return remoteSideClosedFunc(err) - } - return false -} - -func (pc *persistConn) readLoop() { - alive := true - - for alive { - pb, err := pc.br.Peek(1) - - pc.lk.Lock() - if pc.numExpectedResponses == 0 { - if !pc.closed { - pc.closeLocked() - if len(pb) > 0 { - log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v", - string(pb), err) - } - } - pc.lk.Unlock() - return - } - pc.lk.Unlock() - - rc := <-pc.reqch - - var resp *Response - if err == nil { - resp, err = ReadResponse(pc.br, rc.req) - if err == nil && resp.StatusCode == 100 { - // Skip any 100-continue for now. - // TODO(bradfitz): if rc.req had "Expect: 100-continue", - // actually block the request body write and signal the - // writeLoop now to begin sending it. (Issue 2184) For now we - // eat it, since we're never expecting one. - resp, err = ReadResponse(pc.br, rc.req) - } - } - - if resp != nil { - resp.TLS = pc.tlsState - } - - hasBody := resp != nil && rc.req.Method != "HEAD" && resp.ContentLength != 0 - - if err != nil { - pc.close() - } else { - if rc.addedGzip && hasBody && resp.Header.Get("Content-Encoding") == "gzip" { - resp.Header.Del("Content-Encoding") - resp.Header.Del("Content-Length") - resp.ContentLength = -1 - resp.Body = &gzipReader{body: resp.Body} - } - resp.Body = &bodyEOFSignal{body: resp.Body} - } - - if err != nil || resp.Close || rc.req.Close || resp.StatusCode <= 199 { - // Don't do keep-alive on error if either party requested a close - // or we get an unexpected informational (1xx) response. - // StatusCode 100 is already handled above. - alive = false - } - - var waitForBodyRead chan bool - if hasBody { - waitForBodyRead = make(chan bool, 2) - resp.Body.(*bodyEOFSignal).earlyCloseFn = func() error { - // Sending false here sets alive to - // false and closes the connection - // below. - waitForBodyRead <- false - return nil - } - resp.Body.(*bodyEOFSignal).fn = func(err error) { - waitForBodyRead <- alive && - err == nil && - !pc.sawEOF && - pc.wroteRequest() && - pc.t.putIdleConn(pc) - } - } - - if alive && !hasBody { - alive = !pc.sawEOF && - pc.wroteRequest() && - pc.t.putIdleConn(pc) - } - - rc.ch <- responseAndError{resp, err} - - // Wait for the just-returned response body to be fully consumed - // before we race and peek on the underlying bufio reader. - if waitForBodyRead != nil { - select { - case alive = <-waitForBodyRead: - case <-pc.closech: - alive = false - } - } - - pc.t.setReqCanceler(rc.req, nil) - - if !alive { - pc.close() - } - } -} - -func (pc *persistConn) writeLoop() { - for { - select { - case wr := <-pc.writech: - if pc.isBroken() { - wr.ch <- errors.New("http: can't write HTTP request on broken connection") - continue - } - err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra) - if err == nil { - err = pc.bw.Flush() - } - if err != nil { - pc.markBroken() - wr.req.Request.closeBody() - } - pc.writeErrCh <- err // to the body reader, which might recycle us - wr.ch <- err // to the roundTrip function - case <-pc.closech: - return - } - } -} - -// wroteRequest is a check before recycling a connection that the previous write -// (from writeLoop above) happened and was successful. -func (pc *persistConn) wroteRequest() bool { - select { - case err := <-pc.writeErrCh: - // Common case: the write happened well before the response, so - // avoid creating a timer. - return err == nil - default: - // Rare case: the request was written in writeLoop above but - // before it could send to pc.writeErrCh, the reader read it - // all, processed it, and called us here. In this case, give the - // write goroutine a bit of time to finish its send. - // - // Less rare case: We also get here in the legitimate case of - // Issue 7569, where the writer is still writing (or stalled), - // but the server has already replied. In this case, we don't - // want to wait too long, and we want to return false so this - // connection isn't re-used. - select { - case err := <-pc.writeErrCh: - return err == nil - case <-time.After(50 * time.Millisecond): - return false - } - } -} - -type responseAndError struct { - res *Response - err error -} - -type requestAndChan struct { - req *Request - ch chan responseAndError - - // did the Transport (as opposed to the client code) add an - // Accept-Encoding gzip header? only if it we set it do - // we transparently decode the gzip. - addedGzip bool -} - -// A writeRequest is sent by the readLoop's goroutine to the -// writeLoop's goroutine to write a request while the read loop -// concurrently waits on both the write response and the server's -// reply. -type writeRequest struct { - req *transportRequest - ch chan<- error -} - -type httpError struct { - err string - timeout bool -} - -func (e *httpError) Error() string { return e.err } -func (e *httpError) Timeout() bool { return e.timeout } -func (e *httpError) Temporary() bool { return true } - -var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true} -var errClosed error = &httpError{err: "net/http: transport closed before response was received"} - -func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) { - pc.t.setReqCanceler(req.Request, pc.cancelRequest) - pc.lk.Lock() - pc.numExpectedResponses++ - headerFn := pc.mutateHeaderFunc - pc.lk.Unlock() - - if headerFn != nil { - headerFn(req.extraHeaders()) - } - - // Ask for a compressed version if the caller didn't set their - // own value for Accept-Encoding. We only attempted to - // uncompress the gzip stream if we were the layer that - // requested it. - requestedGzip := false - if !pc.t.DisableCompression && req.Header.Get("Accept-Encoding") == "" && req.Method != "HEAD" { - // Request gzip only, not deflate. Deflate is ambiguous and - // not as universally supported anyway. - // See: http://www.gzip.org/zlib/zlib_faq.html#faq38 - // - // Note that we don't request this for HEAD requests, - // due to a bug in nginx: - // http://trac.nginx.org/nginx/ticket/358 - // http://golang.org/issue/5522 - requestedGzip = true - req.extraHeaders().Set("Accept-Encoding", "gzip") - } - - // Write the request concurrently with waiting for a response, - // in case the server decides to reply before reading our full - // request body. - writeErrCh := make(chan error, 1) - pc.writech <- writeRequest{req, writeErrCh} - - resc := make(chan responseAndError, 1) - pc.reqch <- requestAndChan{req.Request, resc, requestedGzip} - - var re responseAndError - var pconnDeadCh = pc.closech - var failTicker <-chan time.Time - var respHeaderTimer <-chan time.Time -WaitResponse: - for { - select { - case err := <-writeErrCh: - if err != nil { - re = responseAndError{nil, err} - pc.close() - break WaitResponse - } - if d := pc.t.ResponseHeaderTimeout; d > 0 { - respHeaderTimer = time.After(d) - } - case <-pconnDeadCh: - // The persist connection is dead. This shouldn't - // usually happen (only with Connection: close responses - // with no response bodies), but if it does happen it - // means either a) the remote server hung up on us - // prematurely, or b) the readLoop sent us a response & - // closed its closech at roughly the same time, and we - // selected this case first, in which case a response - // might still be coming soon. - // - // We can't avoid the select race in b) by using a unbuffered - // resc channel instead, because then goroutines can - // leak if we exit due to other errors. - pconnDeadCh = nil // avoid spinning - failTicker = time.After(100 * time.Millisecond) // arbitrary time to wait for resc - case <-failTicker: - re = responseAndError{err: errClosed} - break WaitResponse - case <-respHeaderTimer: - pc.close() - re = responseAndError{err: errTimeout} - break WaitResponse - case re = <-resc: - break WaitResponse - } - } - - pc.lk.Lock() - pc.numExpectedResponses-- - pc.lk.Unlock() - - if re.err != nil { - pc.t.setReqCanceler(req.Request, nil) - } - return re.res, re.err -} - -// markBroken marks a connection as broken (so it's not reused). -// It differs from close in that it doesn't close the underlying -// connection for use when it's still being read. -func (pc *persistConn) markBroken() { - pc.lk.Lock() - defer pc.lk.Unlock() - pc.broken = true -} - -func (pc *persistConn) close() { - pc.lk.Lock() - defer pc.lk.Unlock() - pc.closeLocked() -} - -func (pc *persistConn) closeLocked() { - pc.broken = true - if !pc.closed { - pc.conn.Close() - pc.closed = true - close(pc.closech) - } - pc.mutateHeaderFunc = nil -} - -var portMap = map[string]string{ - "http": "80", - "https": "443", -} - -// canonicalAddr returns url.Host but always with a ":port" suffix -func canonicalAddr(url *url.URL) string { - addr := url.Host - if !hasPort(addr) { - return addr + ":" + portMap[url.Scheme] - } - return addr -} - -// bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most -// once, right before its final (error-producing) Read or Close call -// returns. If earlyCloseFn is non-nil and Close is called before -// io.EOF is seen, earlyCloseFn is called instead of fn, and its -// return value is the return value from Close. -type bodyEOFSignal struct { - body io.ReadCloser - mu sync.Mutex // guards following 4 fields - closed bool // whether Close has been called - rerr error // sticky Read error - fn func(error) // error will be nil on Read io.EOF - earlyCloseFn func() error // optional alt Close func used if io.EOF not seen -} - -func (es *bodyEOFSignal) Read(p []byte) (n int, err error) { - es.mu.Lock() - closed, rerr := es.closed, es.rerr - es.mu.Unlock() - if closed { - return 0, errors.New("http: read on closed response body") - } - if rerr != nil { - return 0, rerr - } - - n, err = es.body.Read(p) - if err != nil { - es.mu.Lock() - defer es.mu.Unlock() - if es.rerr == nil { - es.rerr = err - } - es.condfn(err) - } - return -} - -func (es *bodyEOFSignal) Close() error { - es.mu.Lock() - defer es.mu.Unlock() - if es.closed { - return nil - } - es.closed = true - if es.earlyCloseFn != nil && es.rerr != io.EOF { - return es.earlyCloseFn() - } - err := es.body.Close() - es.condfn(err) - return err -} - -// caller must hold es.mu. -func (es *bodyEOFSignal) condfn(err error) { - if es.fn == nil { - return - } - if err == io.EOF { - err = nil - } - es.fn(err) - es.fn = nil -} - -// gzipReader wraps a response body so it can lazily -// call gzip.NewReader on the first call to Read -type gzipReader struct { - body io.ReadCloser // underlying Response.Body - zr io.Reader // lazily-initialized gzip reader -} - -func (gz *gzipReader) Read(p []byte) (n int, err error) { - if gz.zr == nil { - gz.zr, err = gzip.NewReader(gz.body) - if err != nil { - return 0, err - } - } - return gz.zr.Read(p) -} - -func (gz *gzipReader) Close() error { - return gz.body.Close() -} - -type readerAndCloser struct { - io.Reader - io.Closer -} - -type tlsHandshakeTimeoutError struct{} - -func (tlsHandshakeTimeoutError) Timeout() bool { return true } -func (tlsHandshakeTimeoutError) Temporary() bool { return true } -func (tlsHandshakeTimeoutError) Error() string { return "net/http: TLS handshake timeout" } - -type noteEOFReader struct { - r io.Reader - sawEOF *bool -} - -func (nr noteEOFReader) Read(p []byte) (n int, err error) { - n, err = nr.r.Read(p) - if err == io.EOF { - *nr.sawEOF = true - } - return -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transport_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transport_test.go deleted file mode 100644 index 964ca0fca5..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/transport_test.go +++ /dev/null @@ -1,2173 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests for transport.go - -package http_test - -import ( - "bufio" - "bytes" - "compress/gzip" - "crypto/rand" - "crypto/tls" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net" - "net/http" - . "net/http" - "net/http/httptest" - "net/url" - "os" - "runtime" - "strconv" - "strings" - "sync" - "testing" - "time" -) - -// TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close -// and then verify that the final 2 responses get errors back. - -// hostPortHandler writes back the client's "host:port". -var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) { - if r.FormValue("close") == "true" { - w.Header().Set("Connection", "close") - } - w.Write([]byte(r.RemoteAddr)) -}) - -// testCloseConn is a net.Conn tracked by a testConnSet. -type testCloseConn struct { - net.Conn - set *testConnSet -} - -func (c *testCloseConn) Close() error { - c.set.remove(c) - return c.Conn.Close() -} - -// testConnSet tracks a set of TCP connections and whether they've -// been closed. -type testConnSet struct { - t *testing.T - mu sync.Mutex // guards closed and list - closed map[net.Conn]bool - list []net.Conn // in order created -} - -func (tcs *testConnSet) insert(c net.Conn) { - tcs.mu.Lock() - defer tcs.mu.Unlock() - tcs.closed[c] = false - tcs.list = append(tcs.list, c) -} - -func (tcs *testConnSet) remove(c net.Conn) { - tcs.mu.Lock() - defer tcs.mu.Unlock() - tcs.closed[c] = true -} - -// some tests use this to manage raw tcp connections for later inspection -func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) { - connSet := &testConnSet{ - t: t, - closed: make(map[net.Conn]bool), - } - dial := func(n, addr string) (net.Conn, error) { - c, err := net.Dial(n, addr) - if err != nil { - return nil, err - } - tc := &testCloseConn{c, connSet} - connSet.insert(tc) - return tc, nil - } - return connSet, dial -} - -func (tcs *testConnSet) check(t *testing.T) { - tcs.mu.Lock() - defer tcs.mu.Unlock() - for i := 4; i >= 0; i-- { - for i, c := range tcs.list { - if tcs.closed[c] { - continue - } - if i != 0 { - tcs.mu.Unlock() - time.Sleep(50 * time.Millisecond) - tcs.mu.Lock() - continue - } - t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list)) - } - } -} - -// Two subsequent requests and verify their response is the same. -// The response from the server is our own IP:port -func TestTransportKeepAlives(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(hostPortHandler) - defer ts.Close() - - for _, disableKeepAlive := range []bool{false, true} { - tr := &Transport{DisableKeepAlives: disableKeepAlive} - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - fetch := func(n int) string { - res, err := c.Get(ts.URL) - if err != nil { - t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err) - } - return string(body) - } - - body1 := fetch(1) - body2 := fetch(2) - - bodiesDiffer := body1 != body2 - if bodiesDiffer != disableKeepAlive { - t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", - disableKeepAlive, bodiesDiffer, body1, body2) - } - } -} - -func TestTransportConnectionCloseOnResponse(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(hostPortHandler) - defer ts.Close() - - connSet, testDial := makeTestDial(t) - - for _, connectionClose := range []bool{false, true} { - tr := &Transport{ - Dial: testDial, - } - c := &Client{Transport: tr} - - fetch := func(n int) string { - req := new(Request) - var err error - req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose)) - if err != nil { - t.Fatalf("URL parse error: %v", err) - } - req.Method = "GET" - req.Proto = "HTTP/1.1" - req.ProtoMajor = 1 - req.ProtoMinor = 1 - - res, err := c.Do(req) - if err != nil { - t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err) - } - defer res.Body.Close() - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err) - } - return string(body) - } - - body1 := fetch(1) - body2 := fetch(2) - bodiesDiffer := body1 != body2 - if bodiesDiffer != connectionClose { - t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", - connectionClose, bodiesDiffer, body1, body2) - } - - tr.CloseIdleConnections() - } - - connSet.check(t) -} - -func TestTransportConnectionCloseOnRequest(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(hostPortHandler) - defer ts.Close() - - connSet, testDial := makeTestDial(t) - - for _, connectionClose := range []bool{false, true} { - tr := &Transport{ - Dial: testDial, - } - c := &Client{Transport: tr} - - fetch := func(n int) string { - req := new(Request) - var err error - req.URL, err = url.Parse(ts.URL) - if err != nil { - t.Fatalf("URL parse error: %v", err) - } - req.Method = "GET" - req.Proto = "HTTP/1.1" - req.ProtoMajor = 1 - req.ProtoMinor = 1 - req.Close = connectionClose - - res, err := c.Do(req) - if err != nil { - t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err) - } - return string(body) - } - - body1 := fetch(1) - body2 := fetch(2) - bodiesDiffer := body1 != body2 - if bodiesDiffer != connectionClose { - t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", - connectionClose, bodiesDiffer, body1, body2) - } - - tr.CloseIdleConnections() - } - - connSet.check(t) -} - -func TestTransportIdleCacheKeys(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(hostPortHandler) - defer ts.Close() - - tr := &Transport{DisableKeepAlives: false} - c := &Client{Transport: tr} - - if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { - t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g) - } - - resp, err := c.Get(ts.URL) - if err != nil { - t.Error(err) - } - ioutil.ReadAll(resp.Body) - - keys := tr.IdleConnKeysForTesting() - if e, g := 1, len(keys); e != g { - t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g) - } - - if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e { - t.Errorf("Expected idle cache key %q; got %q", e, keys[0]) - } - - tr.CloseIdleConnections() - if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { - t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g) - } -} - -// Tests that the HTTP transport re-uses connections when a client -// reads to the end of a response Body without closing it. -func TestTransportReadToEndReusesConn(t *testing.T) { - defer afterTest(t) - const msg = "foobar" - - var addrSeen map[string]int - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - addrSeen[r.RemoteAddr]++ - if r.URL.Path == "/chunked/" { - w.WriteHeader(200) - w.(http.Flusher).Flush() - } else { - w.Header().Set("Content-Type", strconv.Itoa(len(msg))) - w.WriteHeader(200) - } - w.Write([]byte(msg)) - })) - defer ts.Close() - - buf := make([]byte, len(msg)) - - for pi, path := range []string{"/content-length/", "/chunked/"} { - wantLen := []int{len(msg), -1}[pi] - addrSeen = make(map[string]int) - for i := 0; i < 3; i++ { - res, err := http.Get(ts.URL + path) - if err != nil { - t.Errorf("Get %s: %v", path, err) - continue - } - // We want to close this body eventually (before the - // defer afterTest at top runs), but not before the - // len(addrSeen) check at the bottom of this test, - // since Closing this early in the loop would risk - // making connections be re-used for the wrong reason. - defer res.Body.Close() - - if res.ContentLength != int64(wantLen) { - t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen) - } - n, err := res.Body.Read(buf) - if n != len(msg) || err != io.EOF { - t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg)) - } - } - if len(addrSeen) != 1 { - t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen)) - } - } -} - -func TestTransportMaxPerHostIdleConns(t *testing.T) { - defer afterTest(t) - resch := make(chan string) - gotReq := make(chan bool) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - gotReq <- true - msg := <-resch - _, err := w.Write([]byte(msg)) - if err != nil { - t.Fatalf("Write: %v", err) - } - })) - defer ts.Close() - maxIdleConns := 2 - tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns} - c := &Client{Transport: tr} - - // Start 3 outstanding requests and wait for the server to get them. - // Their responses will hang until we write to resch, though. - donech := make(chan bool) - doReq := func() { - resp, err := c.Get(ts.URL) - if err != nil { - t.Error(err) - return - } - if _, err := ioutil.ReadAll(resp.Body); err != nil { - t.Errorf("ReadAll: %v", err) - return - } - donech <- true - } - go doReq() - <-gotReq - go doReq() - <-gotReq - go doReq() - <-gotReq - - if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { - t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g) - } - - resch <- "res1" - <-donech - keys := tr.IdleConnKeysForTesting() - if e, g := 1, len(keys); e != g { - t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g) - } - cacheKey := "|http|" + ts.Listener.Addr().String() - if keys[0] != cacheKey { - t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0]) - } - if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g { - t.Errorf("after first response, expected %d idle conns; got %d", e, g) - } - - resch <- "res2" - <-donech - if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g { - t.Errorf("after second response, expected %d idle conns; got %d", e, g) - } - - resch <- "res3" - <-donech - if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g { - t.Errorf("after third response, still expected %d idle conns; got %d", e, g) - } -} - -func TestTransportServerClosingUnexpectedly(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(hostPortHandler) - defer ts.Close() - - tr := &Transport{} - c := &Client{Transport: tr} - - fetch := func(n, retries int) string { - condFatalf := func(format string, arg ...interface{}) { - if retries <= 0 { - t.Fatalf(format, arg...) - } - t.Logf("retrying shortly after expected error: "+format, arg...) - time.Sleep(time.Second / time.Duration(retries)) - } - for retries >= 0 { - retries-- - res, err := c.Get(ts.URL) - if err != nil { - condFatalf("error in req #%d, GET: %v", n, err) - continue - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - condFatalf("error in req #%d, ReadAll: %v", n, err) - continue - } - res.Body.Close() - return string(body) - } - panic("unreachable") - } - - body1 := fetch(1, 0) - body2 := fetch(2, 0) - - ts.CloseClientConnections() // surprise! - - // This test has an expected race. Sleeping for 25 ms prevents - // it on most fast machines, causing the next fetch() call to - // succeed quickly. But if we do get errors, fetch() will retry 5 - // times with some delays between. - time.Sleep(25 * time.Millisecond) - - body3 := fetch(3, 5) - - if body1 != body2 { - t.Errorf("expected body1 and body2 to be equal") - } - if body2 == body3 { - t.Errorf("expected body2 and body3 to be different") - } -} - -// Test for http://golang.org/issue/2616 (appropriate issue number) -// This fails pretty reliably with GOMAXPROCS=100 or something high. -func TestStressSurpriseServerCloses(t *testing.T) { - defer afterTest(t) - if testing.Short() { - t.Skip("skipping test in short mode") - } - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Length", "5") - w.Header().Set("Content-Type", "text/plain") - w.Write([]byte("Hello")) - w.(Flusher).Flush() - conn, buf, _ := w.(Hijacker).Hijack() - buf.Flush() - conn.Close() - })) - defer ts.Close() - - tr := &Transport{DisableKeepAlives: false} - c := &Client{Transport: tr} - - // Do a bunch of traffic from different goroutines. Send to activityc - // after each request completes, regardless of whether it failed. - const ( - numClients = 50 - reqsPerClient = 250 - ) - activityc := make(chan bool) - for i := 0; i < numClients; i++ { - go func() { - for i := 0; i < reqsPerClient; i++ { - res, err := c.Get(ts.URL) - if err == nil { - // We expect errors since the server is - // hanging up on us after telling us to - // send more requests, so we don't - // actually care what the error is. - // But we want to close the body in cases - // where we won the race. - res.Body.Close() - } - activityc <- true - } - }() - } - - // Make sure all the request come back, one way or another. - for i := 0; i < numClients*reqsPerClient; i++ { - select { - case <-activityc: - case <-time.After(5 * time.Second): - t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile") - } - } -} - -// TestTransportHeadResponses verifies that we deal with Content-Lengths -// with no bodies properly -func TestTransportHeadResponses(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.Method != "HEAD" { - panic("expected HEAD; got " + r.Method) - } - w.Header().Set("Content-Length", "123") - w.WriteHeader(200) - })) - defer ts.Close() - - tr := &Transport{DisableKeepAlives: false} - c := &Client{Transport: tr} - for i := 0; i < 2; i++ { - res, err := c.Head(ts.URL) - if err != nil { - t.Errorf("error on loop %d: %v", i, err) - continue - } - if e, g := "123", res.Header.Get("Content-Length"); e != g { - t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g) - } - if e, g := int64(123), res.ContentLength; e != g { - t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g) - } - if all, err := ioutil.ReadAll(res.Body); err != nil { - t.Errorf("loop %d: Body ReadAll: %v", i, err) - } else if len(all) != 0 { - t.Errorf("Bogus body %q", all) - } - } -} - -// TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding -// on responses to HEAD requests. -func TestTransportHeadChunkedResponse(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.Method != "HEAD" { - panic("expected HEAD; got " + r.Method) - } - w.Header().Set("Transfer-Encoding", "chunked") // client should ignore - w.Header().Set("x-client-ipport", r.RemoteAddr) - w.WriteHeader(200) - })) - defer ts.Close() - - tr := &Transport{DisableKeepAlives: false} - c := &Client{Transport: tr} - - res1, err := c.Head(ts.URL) - if err != nil { - t.Fatalf("request 1 error: %v", err) - } - res2, err := c.Head(ts.URL) - if err != nil { - t.Fatalf("request 2 error: %v", err) - } - if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 { - t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2) - } -} - -var roundTripTests = []struct { - accept string - expectAccept string - compressed bool -}{ - // Requests with no accept-encoding header use transparent compression - {"", "gzip", false}, - // Requests with other accept-encoding should pass through unmodified - {"foo", "foo", false}, - // Requests with accept-encoding == gzip should be passed through - {"gzip", "gzip", true}, -} - -// Test that the modification made to the Request by the RoundTripper is cleaned up -func TestRoundTripGzip(t *testing.T) { - defer afterTest(t) - const responseBody = "test response body" - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - accept := req.Header.Get("Accept-Encoding") - if expect := req.FormValue("expect_accept"); accept != expect { - t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q", - req.FormValue("testnum"), accept, expect) - } - if accept == "gzip" { - rw.Header().Set("Content-Encoding", "gzip") - gz := gzip.NewWriter(rw) - gz.Write([]byte(responseBody)) - gz.Close() - } else { - rw.Header().Set("Content-Encoding", accept) - rw.Write([]byte(responseBody)) - } - })) - defer ts.Close() - - for i, test := range roundTripTests { - // Test basic request (no accept-encoding) - req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil) - if test.accept != "" { - req.Header.Set("Accept-Encoding", test.accept) - } - res, err := DefaultTransport.RoundTrip(req) - var body []byte - if test.compressed { - var r *gzip.Reader - r, err = gzip.NewReader(res.Body) - if err != nil { - t.Errorf("%d. gzip NewReader: %v", i, err) - continue - } - body, err = ioutil.ReadAll(r) - res.Body.Close() - } else { - body, err = ioutil.ReadAll(res.Body) - } - if err != nil { - t.Errorf("%d. Error: %q", i, err) - continue - } - if g, e := string(body), responseBody; g != e { - t.Errorf("%d. body = %q; want %q", i, g, e) - } - if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e { - t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e) - } - if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e { - t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e) - } - } - -} - -func TestTransportGzip(t *testing.T) { - defer afterTest(t) - const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - const nRandBytes = 1024 * 1024 - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { - if req.Method == "HEAD" { - if g := req.Header.Get("Accept-Encoding"); g != "" { - t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g) - } - return - } - if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e { - t.Errorf("Accept-Encoding = %q, want %q", g, e) - } - rw.Header().Set("Content-Encoding", "gzip") - - var w io.Writer = rw - var buf bytes.Buffer - if req.FormValue("chunked") == "0" { - w = &buf - defer io.Copy(rw, &buf) - defer func() { - rw.Header().Set("Content-Length", strconv.Itoa(buf.Len())) - }() - } - gz := gzip.NewWriter(w) - gz.Write([]byte(testString)) - if req.FormValue("body") == "large" { - io.CopyN(gz, rand.Reader, nRandBytes) - } - gz.Close() - })) - defer ts.Close() - - for _, chunked := range []string{"1", "0"} { - c := &Client{Transport: &Transport{}} - - // First fetch something large, but only read some of it. - res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked) - if err != nil { - t.Fatalf("large get: %v", err) - } - buf := make([]byte, len(testString)) - n, err := io.ReadFull(res.Body, buf) - if err != nil { - t.Fatalf("partial read of large response: size=%d, %v", n, err) - } - if e, g := testString, string(buf); e != g { - t.Errorf("partial read got %q, expected %q", g, e) - } - res.Body.Close() - // Read on the body, even though it's closed - n, err = res.Body.Read(buf) - if n != 0 || err == nil { - t.Errorf("expected error post-closed large Read; got = %d, %v", n, err) - } - - // Then something small. - res, err = c.Get(ts.URL + "/?chunked=" + chunked) - if err != nil { - t.Fatal(err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if g, e := string(body), testString; g != e { - t.Fatalf("body = %q; want %q", g, e) - } - if g, e := res.Header.Get("Content-Encoding"), ""; g != e { - t.Fatalf("Content-Encoding = %q; want %q", g, e) - } - - // Read on the body after it's been fully read: - n, err = res.Body.Read(buf) - if n != 0 || err == nil { - t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err) - } - res.Body.Close() - n, err = res.Body.Read(buf) - if n != 0 || err == nil { - t.Errorf("expected Read error after Close; got %d, %v", n, err) - } - } - - // And a HEAD request too, because they're always weird. - c := &Client{Transport: &Transport{}} - res, err := c.Head(ts.URL) - if err != nil { - t.Fatalf("Head: %v", err) - } - if res.StatusCode != 200 { - t.Errorf("Head status=%d; want=200", res.StatusCode) - } -} - -func TestTransportProxy(t *testing.T) { - defer afterTest(t) - ch := make(chan string, 1) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - ch <- "real server" - })) - defer ts.Close() - proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - ch <- "proxy for " + r.URL.String() - })) - defer proxy.Close() - - pu, err := url.Parse(proxy.URL) - if err != nil { - t.Fatal(err) - } - c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}} - c.Head(ts.URL) - got := <-ch - want := "proxy for " + ts.URL + "/" - if got != want { - t.Errorf("want %q, got %q", want, got) - } -} - -// TestTransportGzipRecursive sends a gzip quine and checks that the -// client gets the same value back. This is more cute than anything, -// but checks that we don't recurse forever, and checks that -// Content-Encoding is removed. -func TestTransportGzipRecursive(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Encoding", "gzip") - w.Write(rgz) - })) - defer ts.Close() - - c := &Client{Transport: &Transport{}} - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(body, rgz) { - t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x", - body, rgz) - } - if g, e := res.Header.Get("Content-Encoding"), ""; g != e { - t.Fatalf("Content-Encoding = %q; want %q", g, e) - } -} - -// golang.org/issue/7750: request fails when server replies with -// a short gzip body -func TestTransportGzipShort(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Encoding", "gzip") - w.Write([]byte{0x1f, 0x8b}) - })) - defer ts.Close() - - tr := &Transport{} - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - defer res.Body.Close() - _, err = ioutil.ReadAll(res.Body) - if err == nil { - t.Fatal("Expect an error from reading a body.") - } - if err != io.ErrUnexpectedEOF { - t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err) - } -} - -// tests that persistent goroutine connections shut down when no longer desired. -func TestTransportPersistConnLeak(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - gotReqCh := make(chan bool) - unblockCh := make(chan bool) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - gotReqCh <- true - <-unblockCh - w.Header().Set("Content-Length", "0") - w.WriteHeader(204) - })) - defer ts.Close() - - tr := &Transport{} - c := &Client{Transport: tr} - - n0 := runtime.NumGoroutine() - - const numReq = 25 - didReqCh := make(chan bool) - for i := 0; i < numReq; i++ { - go func() { - res, err := c.Get(ts.URL) - didReqCh <- true - if err != nil { - t.Errorf("client fetch error: %v", err) - return - } - res.Body.Close() - }() - } - - // Wait for all goroutines to be stuck in the Handler. - for i := 0; i < numReq; i++ { - <-gotReqCh - } - - nhigh := runtime.NumGoroutine() - - // Tell all handlers to unblock and reply. - for i := 0; i < numReq; i++ { - unblockCh <- true - } - - // Wait for all HTTP clients to be done. - for i := 0; i < numReq; i++ { - <-didReqCh - } - - tr.CloseIdleConnections() - time.Sleep(100 * time.Millisecond) - runtime.GC() - runtime.GC() // even more. - nfinal := runtime.NumGoroutine() - - growth := nfinal - n0 - - // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. - // Previously we were leaking one per numReq. - if int(growth) > 5 { - t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) - t.Error("too many new goroutines") - } -} - -// golang.org/issue/4531: Transport leaks goroutines when -// request.ContentLength is explicitly short -func TestTransportPersistConnLeakShortBody(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - })) - defer ts.Close() - - tr := &Transport{} - c := &Client{Transport: tr} - - n0 := runtime.NumGoroutine() - body := []byte("Hello") - for i := 0; i < 20; i++ { - req, err := NewRequest("POST", ts.URL, bytes.NewReader(body)) - if err != nil { - t.Fatal(err) - } - req.ContentLength = int64(len(body) - 2) // explicitly short - _, err = c.Do(req) - if err == nil { - t.Fatal("Expect an error from writing too long of a body.") - } - } - nhigh := runtime.NumGoroutine() - tr.CloseIdleConnections() - time.Sleep(400 * time.Millisecond) - runtime.GC() - nfinal := runtime.NumGoroutine() - - growth := nfinal - n0 - - // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. - // Previously we were leaking one per numReq. - t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) - if int(growth) > 5 { - t.Error("too many new goroutines") - } -} - -// This used to crash; http://golang.org/issue/3266 -func TestTransportIdleConnCrash(t *testing.T) { - defer afterTest(t) - tr := &Transport{} - c := &Client{Transport: tr} - - unblockCh := make(chan bool, 1) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - <-unblockCh - tr.CloseIdleConnections() - })) - defer ts.Close() - - didreq := make(chan bool) - go func() { - res, err := c.Get(ts.URL) - if err != nil { - t.Error(err) - } else { - res.Body.Close() // returns idle conn - } - didreq <- true - }() - unblockCh <- true - <-didreq -} - -// Test that the transport doesn't close the TCP connection early, -// before the response body has been read. This was a regression -// which sadly lacked a triggering test. The large response body made -// the old race easier to trigger. -func TestIssue3644(t *testing.T) { - defer afterTest(t) - const numFoos = 5000 - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Connection", "close") - for i := 0; i < numFoos; i++ { - w.Write([]byte("foo ")) - } - })) - defer ts.Close() - tr := &Transport{} - c := &Client{Transport: tr} - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - defer res.Body.Close() - bs, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if len(bs) != numFoos*len("foo ") { - t.Errorf("unexpected response length") - } -} - -// Test that a client receives a server's reply, even if the server doesn't read -// the entire request body. -func TestIssue3595(t *testing.T) { - defer afterTest(t) - const deniedMsg = "sorry, denied." - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - Error(w, deniedMsg, StatusUnauthorized) - })) - defer ts.Close() - tr := &Transport{} - c := &Client{Transport: tr} - res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a')) - if err != nil { - t.Errorf("Post: %v", err) - return - } - got, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("Body ReadAll: %v", err) - } - if !strings.Contains(string(got), deniedMsg) { - t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg) - } -} - -// From http://golang.org/issue/4454 , -// "client fails to handle requests with no body and chunked encoding" -func TestChunkedNoContent(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.WriteHeader(StatusNoContent) - })) - defer ts.Close() - - for _, closeBody := range []bool{true, false} { - c := &Client{Transport: &Transport{}} - const n = 4 - for i := 1; i <= n; i++ { - res, err := c.Get(ts.URL) - if err != nil { - t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err) - } else { - if closeBody { - res.Body.Close() - } - } - } - } -} - -func TestTransportConcurrency(t *testing.T) { - defer afterTest(t) - maxProcs, numReqs := 16, 500 - if testing.Short() { - maxProcs, numReqs = 4, 50 - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - fmt.Fprintf(w, "%v", r.FormValue("echo")) - })) - defer ts.Close() - - var wg sync.WaitGroup - wg.Add(numReqs) - - tr := &Transport{ - Dial: func(netw, addr string) (c net.Conn, err error) { - // Due to the Transport's "socket late - // binding" (see idleConnCh in transport.go), - // the numReqs HTTP requests below can finish - // with a dial still outstanding. So count - // our dials as work too so the leak checker - // doesn't complain at us. - wg.Add(1) - defer wg.Done() - return net.Dial(netw, addr) - }, - } - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - reqs := make(chan string) - defer close(reqs) - - for i := 0; i < maxProcs*2; i++ { - go func() { - for req := range reqs { - res, err := c.Get(ts.URL + "/?echo=" + req) - if err != nil { - t.Errorf("error on req %s: %v", req, err) - wg.Done() - continue - } - all, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Errorf("read error on req %s: %v", req, err) - wg.Done() - continue - } - if string(all) != req { - t.Errorf("body of req %s = %q; want %q", req, all, req) - } - res.Body.Close() - wg.Done() - } - }() - } - for i := 0; i < numReqs; i++ { - reqs <- fmt.Sprintf("request-%d", i) - } - wg.Wait() -} - -func TestIssue4191_InfiniteGetTimeout(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - const debug = false - mux := NewServeMux() - mux.HandleFunc("/get", func(w ResponseWriter, r *Request) { - io.Copy(w, neverEnding('a')) - }) - ts := httptest.NewServer(mux) - timeout := 100 * time.Millisecond - - client := &Client{ - Transport: &Transport{ - Dial: func(n, addr string) (net.Conn, error) { - conn, err := net.Dial(n, addr) - if err != nil { - return nil, err - } - conn.SetDeadline(time.Now().Add(timeout)) - if debug { - conn = NewLoggingConn("client", conn) - } - return conn, nil - }, - DisableKeepAlives: true, - }, - } - - getFailed := false - nRuns := 5 - if testing.Short() { - nRuns = 1 - } - for i := 0; i < nRuns; i++ { - if debug { - println("run", i+1, "of", nRuns) - } - sres, err := client.Get(ts.URL + "/get") - if err != nil { - if !getFailed { - // Make the timeout longer, once. - getFailed = true - t.Logf("increasing timeout") - i-- - timeout *= 10 - continue - } - t.Errorf("Error issuing GET: %v", err) - break - } - _, err = io.Copy(ioutil.Discard, sres.Body) - if err == nil { - t.Errorf("Unexpected successful copy") - break - } - } - if debug { - println("tests complete; waiting for handlers to finish") - } - ts.Close() -} - -func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7237") - } - defer afterTest(t) - const debug = false - mux := NewServeMux() - mux.HandleFunc("/get", func(w ResponseWriter, r *Request) { - io.Copy(w, neverEnding('a')) - }) - mux.HandleFunc("/put", func(w ResponseWriter, r *Request) { - defer r.Body.Close() - io.Copy(ioutil.Discard, r.Body) - }) - ts := httptest.NewServer(mux) - timeout := 100 * time.Millisecond - - client := &Client{ - Transport: &Transport{ - Dial: func(n, addr string) (net.Conn, error) { - conn, err := net.Dial(n, addr) - if err != nil { - return nil, err - } - conn.SetDeadline(time.Now().Add(timeout)) - if debug { - conn = NewLoggingConn("client", conn) - } - return conn, nil - }, - DisableKeepAlives: true, - }, - } - - getFailed := false - nRuns := 5 - if testing.Short() { - nRuns = 1 - } - for i := 0; i < nRuns; i++ { - if debug { - println("run", i+1, "of", nRuns) - } - sres, err := client.Get(ts.URL + "/get") - if err != nil { - if !getFailed { - // Make the timeout longer, once. - getFailed = true - t.Logf("increasing timeout") - i-- - timeout *= 10 - continue - } - t.Errorf("Error issuing GET: %v", err) - break - } - req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body) - _, err = client.Do(req) - if err == nil { - sres.Body.Close() - t.Errorf("Unexpected successful PUT") - break - } - sres.Body.Close() - } - if debug { - println("tests complete; waiting for handlers to finish") - } - ts.Close() -} - -func TestTransportResponseHeaderTimeout(t *testing.T) { - defer afterTest(t) - if testing.Short() { - t.Skip("skipping timeout test in -short mode") - } - inHandler := make(chan bool, 1) - mux := NewServeMux() - mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) { - inHandler <- true - }) - mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) { - inHandler <- true - time.Sleep(2 * time.Second) - }) - ts := httptest.NewServer(mux) - defer ts.Close() - - tr := &Transport{ - ResponseHeaderTimeout: 500 * time.Millisecond, - } - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - tests := []struct { - path string - want int - wantErr string - }{ - {path: "/fast", want: 200}, - {path: "/slow", wantErr: "timeout awaiting response headers"}, - {path: "/fast", want: 200}, - } - for i, tt := range tests { - res, err := c.Get(ts.URL + tt.path) - select { - case <-inHandler: - case <-time.After(5 * time.Second): - t.Errorf("never entered handler for test index %d, %s", i, tt.path) - continue - } - if err != nil { - uerr, ok := err.(*url.Error) - if !ok { - t.Errorf("error is not an url.Error; got: %#v", err) - continue - } - nerr, ok := uerr.Err.(net.Error) - if !ok { - t.Errorf("error does not satisfy net.Error interface; got: %#v", err) - continue - } - if !nerr.Timeout() { - t.Errorf("want timeout error; got: %q", nerr) - continue - } - if strings.Contains(err.Error(), tt.wantErr) { - continue - } - t.Errorf("%d. unexpected error: %v", i, err) - continue - } - if tt.wantErr != "" { - t.Errorf("%d. no error. expected error: %v", i, tt.wantErr) - continue - } - if res.StatusCode != tt.want { - t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want) - } - } -} - -func TestTransportCancelRequest(t *testing.T) { - defer afterTest(t) - if testing.Short() { - t.Skip("skipping test in -short mode") - } - unblockc := make(chan bool) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - fmt.Fprintf(w, "Hello") - w.(Flusher).Flush() // send headers and some body - <-unblockc - })) - defer ts.Close() - defer close(unblockc) - - tr := &Transport{} - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - req, _ := NewRequest("GET", ts.URL, nil) - res, err := c.Do(req) - if err != nil { - t.Fatal(err) - } - go func() { - time.Sleep(1 * time.Second) - tr.CancelRequest(req) - }() - t0 := time.Now() - body, err := ioutil.ReadAll(res.Body) - d := time.Since(t0) - - if err == nil { - t.Error("expected an error reading the body") - } - if string(body) != "Hello" { - t.Errorf("Body = %q; want Hello", body) - } - if d < 500*time.Millisecond { - t.Errorf("expected ~1 second delay; got %v", d) - } - // Verify no outstanding requests after readLoop/writeLoop - // goroutines shut down. - for tries := 3; tries > 0; tries-- { - n := tr.NumPendingRequestsForTesting() - if n == 0 { - break - } - time.Sleep(100 * time.Millisecond) - if tries == 1 { - t.Errorf("pending requests = %d; want 0", n) - } - } -} - -func TestTransportCancelRequestInDial(t *testing.T) { - defer afterTest(t) - if testing.Short() { - t.Skip("skipping test in -short mode") - } - var logbuf bytes.Buffer - eventLog := log.New(&logbuf, "", 0) - - unblockDial := make(chan bool) - defer close(unblockDial) - - inDial := make(chan bool) - tr := &Transport{ - Dial: func(network, addr string) (net.Conn, error) { - eventLog.Println("dial: blocking") - inDial <- true - <-unblockDial - return nil, errors.New("nope") - }, - } - cl := &Client{Transport: tr} - gotres := make(chan bool) - req, _ := NewRequest("GET", "http://something.no-network.tld/", nil) - go func() { - _, err := cl.Do(req) - eventLog.Printf("Get = %v", err) - gotres <- true - }() - - select { - case <-inDial: - case <-time.After(5 * time.Second): - t.Fatal("timeout; never saw blocking dial") - } - - eventLog.Printf("canceling") - tr.CancelRequest(req) - - select { - case <-gotres: - case <-time.After(5 * time.Second): - panic("hang. events are: " + logbuf.String()) - } - - got := logbuf.String() - want := `dial: blocking -canceling -Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection -` - if got != want { - t.Errorf("Got events:\n%s\nWant:\n%s", got, want) - } -} - -// golang.org/issue/3672 -- Client can't close HTTP stream -// Calling Close on a Response.Body used to just read until EOF. -// Now it actually closes the TCP connection. -func TestTransportCloseResponseBody(t *testing.T) { - defer afterTest(t) - writeErr := make(chan error, 1) - msg := []byte("young\n") - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - for { - _, err := w.Write(msg) - if err != nil { - writeErr <- err - return - } - w.(Flusher).Flush() - } - })) - defer ts.Close() - - tr := &Transport{} - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - req, _ := NewRequest("GET", ts.URL, nil) - defer tr.CancelRequest(req) - - res, err := c.Do(req) - if err != nil { - t.Fatal(err) - } - - const repeats = 3 - buf := make([]byte, len(msg)*repeats) - want := bytes.Repeat(msg, repeats) - - _, err = io.ReadFull(res.Body, buf) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(buf, want) { - t.Fatalf("read %q; want %q", buf, want) - } - didClose := make(chan error, 1) - go func() { - didClose <- res.Body.Close() - }() - select { - case err := <-didClose: - if err != nil { - t.Errorf("Close = %v", err) - } - case <-time.After(10 * time.Second): - t.Fatal("too long waiting for close") - } - select { - case err := <-writeErr: - if err == nil { - t.Errorf("expected non-nil write error") - } - case <-time.After(10 * time.Second): - t.Fatal("too long waiting for write error") - } -} - -type fooProto struct{} - -func (fooProto) RoundTrip(req *Request) (*Response, error) { - res := &Response{ - Status: "200 OK", - StatusCode: 200, - Header: make(Header), - Body: ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())), - } - return res, nil -} - -func TestTransportAltProto(t *testing.T) { - defer afterTest(t) - tr := &Transport{} - c := &Client{Transport: tr} - tr.RegisterProtocol("foo", fooProto{}) - res, err := c.Get("foo://bar.com/path") - if err != nil { - t.Fatal(err) - } - bodyb, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - body := string(bodyb) - if e := "You wanted foo://bar.com/path"; body != e { - t.Errorf("got response %q, want %q", body, e) - } -} - -func TestTransportNoHost(t *testing.T) { - defer afterTest(t) - tr := &Transport{} - _, err := tr.RoundTrip(&Request{ - Header: make(Header), - URL: &url.URL{ - Scheme: "http", - }, - }) - want := "http: no Host in request URL" - if got := fmt.Sprint(err); got != want { - t.Errorf("error = %v; want %q", err, want) - } -} - -func TestTransportSocketLateBinding(t *testing.T) { - defer afterTest(t) - - mux := NewServeMux() - fooGate := make(chan bool, 1) - mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) { - w.Header().Set("foo-ipport", r.RemoteAddr) - w.(Flusher).Flush() - <-fooGate - }) - mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) { - w.Header().Set("bar-ipport", r.RemoteAddr) - }) - ts := httptest.NewServer(mux) - defer ts.Close() - - dialGate := make(chan bool, 1) - tr := &Transport{ - Dial: func(n, addr string) (net.Conn, error) { - if <-dialGate { - return net.Dial(n, addr) - } - return nil, errors.New("manually closed") - }, - DisableKeepAlives: false, - } - defer tr.CloseIdleConnections() - c := &Client{ - Transport: tr, - } - - dialGate <- true // only allow one dial - fooRes, err := c.Get(ts.URL + "/foo") - if err != nil { - t.Fatal(err) - } - fooAddr := fooRes.Header.Get("foo-ipport") - if fooAddr == "" { - t.Fatal("No addr on /foo request") - } - time.AfterFunc(200*time.Millisecond, func() { - // let the foo response finish so we can use its - // connection for /bar - fooGate <- true - io.Copy(ioutil.Discard, fooRes.Body) - fooRes.Body.Close() - }) - - barRes, err := c.Get(ts.URL + "/bar") - if err != nil { - t.Fatal(err) - } - barAddr := barRes.Header.Get("bar-ipport") - if barAddr != fooAddr { - t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr) - } - barRes.Body.Close() - dialGate <- false -} - -// Issue 2184 -func TestTransportReading100Continue(t *testing.T) { - defer afterTest(t) - - const numReqs = 5 - reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) } - reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) } - - send100Response := func(w *io.PipeWriter, r *io.PipeReader) { - defer w.Close() - defer r.Close() - br := bufio.NewReader(r) - n := 0 - for { - n++ - req, err := ReadRequest(br) - if err == io.EOF { - return - } - if err != nil { - t.Error(err) - return - } - slurp, err := ioutil.ReadAll(req.Body) - if err != nil { - t.Errorf("Server request body slurp: %v", err) - return - } - id := req.Header.Get("Request-Id") - resCode := req.Header.Get("X-Want-Response-Code") - if resCode == "" { - resCode = "100 Continue" - if string(slurp) != reqBody(n) { - t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n)) - } - } - body := fmt.Sprintf("Response number %d", n) - v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s -Date: Thu, 28 Feb 2013 17:55:41 GMT - -HTTP/1.1 200 OK -Content-Type: text/html -Echo-Request-Id: %s -Content-Length: %d - -%s`, resCode, id, len(body), body), "\n", "\r\n", -1)) - w.Write(v) - if id == reqID(numReqs) { - return - } - } - - } - - tr := &Transport{ - Dial: func(n, addr string) (net.Conn, error) { - sr, sw := io.Pipe() // server read/write - cr, cw := io.Pipe() // client read/write - conn := &rwTestConn{ - Reader: cr, - Writer: sw, - closeFunc: func() error { - sw.Close() - cw.Close() - return nil - }, - } - go send100Response(cw, sr) - return conn, nil - }, - DisableKeepAlives: false, - } - defer tr.CloseIdleConnections() - c := &Client{Transport: tr} - - testResponse := func(req *Request, name string, wantCode int) { - res, err := c.Do(req) - if err != nil { - t.Fatalf("%s: Do: %v", name, err) - } - if res.StatusCode != wantCode { - t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode) - } - if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack { - t.Errorf("%s: response id %q != request id %q", name, idBack, id) - } - _, err = ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("%s: Slurp error: %v", name, err) - } - } - - // Few 100 responses, making sure we're not off-by-one. - for i := 1; i <= numReqs; i++ { - req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i))) - req.Header.Set("Request-Id", reqID(i)) - testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200) - } - - // And some other informational 1xx but non-100 responses, to test - // we return them but don't re-use the connection. - for i := 1; i <= numReqs; i++ { - req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i))) - req.Header.Set("X-Want-Response-Code", "123 Sesame Street") - testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123) - } -} - -type proxyFromEnvTest struct { - req string // URL to fetch; blank means "http://example.com" - env string - noenv string - want string - wanterr error -} - -func (t proxyFromEnvTest) String() string { - var buf bytes.Buffer - if t.env != "" { - fmt.Fprintf(&buf, "http_proxy=%q", t.env) - } - if t.noenv != "" { - fmt.Fprintf(&buf, " no_proxy=%q", t.noenv) - } - req := "http://example.com" - if t.req != "" { - req = t.req - } - fmt.Fprintf(&buf, " req=%q", req) - return strings.TrimSpace(buf.String()) -} - -var proxyFromEnvTests = []proxyFromEnvTest{ - {env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"}, - {env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"}, - {env: "cache.corp.example.com", want: "http://cache.corp.example.com"}, - {env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"}, - {env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"}, - {env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"}, - {want: ""}, - {noenv: "example.com", req: "http://example.com/", env: "proxy", want: ""}, - {noenv: ".example.com", req: "http://example.com/", env: "proxy", want: ""}, - {noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"}, - {noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: ""}, - {noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"}, -} - -func TestProxyFromEnvironment(t *testing.T) { - ResetProxyEnv() - for _, tt := range proxyFromEnvTests { - os.Setenv("HTTP_PROXY", tt.env) - os.Setenv("NO_PROXY", tt.noenv) - ResetCachedEnvironment() - reqURL := tt.req - if reqURL == "" { - reqURL = "http://example.com" - } - req, _ := NewRequest("GET", reqURL, nil) - url, err := ProxyFromEnvironment(req) - if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e { - t.Errorf("%v: got error = %q, want %q", tt, g, e) - continue - } - if got := fmt.Sprintf("%s", url); got != tt.want { - t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want) - } - } -} - -func TestIdleConnChannelLeak(t *testing.T) { - var mu sync.Mutex - var n int - - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - mu.Lock() - n++ - mu.Unlock() - })) - defer ts.Close() - - tr := &Transport{ - Dial: func(netw, addr string) (net.Conn, error) { - return net.Dial(netw, ts.Listener.Addr().String()) - }, - } - defer tr.CloseIdleConnections() - - c := &Client{Transport: tr} - - // First, without keep-alives. - for _, disableKeep := range []bool{true, false} { - tr.DisableKeepAlives = disableKeep - for i := 0; i < 5; i++ { - _, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i)) - if err != nil { - t.Fatal(err) - } - } - if got := tr.IdleConnChMapSizeForTesting(); got != 0 { - t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got) - } - } -} - -// Verify the status quo: that the Client.Post function coerces its -// body into a ReadCloser if it's a Closer, and that the Transport -// then closes it. -func TestTransportClosesRequestBody(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(http.HandlerFunc(func(w ResponseWriter, r *Request) { - io.Copy(ioutil.Discard, r.Body) - })) - defer ts.Close() - - tr := &Transport{} - defer tr.CloseIdleConnections() - cl := &Client{Transport: tr} - - closes := 0 - - res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")}) - if err != nil { - t.Fatal(err) - } - res.Body.Close() - if closes != 1 { - t.Errorf("closes = %d; want 1", closes) - } -} - -func TestTransportTLSHandshakeTimeout(t *testing.T) { - defer afterTest(t) - if testing.Short() { - t.Skip("skipping in short mode") - } - ln := newLocalListener(t) - defer ln.Close() - testdonec := make(chan struct{}) - defer close(testdonec) - - go func() { - c, err := ln.Accept() - if err != nil { - t.Error(err) - return - } - <-testdonec - c.Close() - }() - - getdonec := make(chan struct{}) - go func() { - defer close(getdonec) - tr := &Transport{ - Dial: func(_, _ string) (net.Conn, error) { - return net.Dial("tcp", ln.Addr().String()) - }, - TLSHandshakeTimeout: 250 * time.Millisecond, - } - cl := &Client{Transport: tr} - _, err := cl.Get("https://dummy.tld/") - if err == nil { - t.Error("expected error") - return - } - ue, ok := err.(*url.Error) - if !ok { - t.Errorf("expected url.Error; got %#v", err) - return - } - ne, ok := ue.Err.(net.Error) - if !ok { - t.Errorf("expected net.Error; got %#v", err) - return - } - if !ne.Timeout() { - t.Errorf("expected timeout error; got %v", err) - } - if !strings.Contains(err.Error(), "handshake timeout") { - t.Errorf("expected 'handshake timeout' in error; got %v", err) - } - }() - select { - case <-getdonec: - case <-time.After(5 * time.Second): - t.Error("test timeout; TLS handshake hung?") - } -} - -// Trying to repro golang.org/issue/3514 -func TestTLSServerClosesConnection(t *testing.T) { - defer afterTest(t) - if runtime.GOOS == "windows" { - t.Skip("skipping flaky test on Windows; golang.org/issue/7634") - } - closedc := make(chan bool, 1) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if strings.Contains(r.URL.Path, "/keep-alive-then-die") { - conn, _, _ := w.(Hijacker).Hijack() - conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) - conn.Close() - closedc <- true - return - } - fmt.Fprintf(w, "hello") - })) - defer ts.Close() - tr := &Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - } - defer tr.CloseIdleConnections() - client := &Client{Transport: tr} - - var nSuccess = 0 - var errs []error - const trials = 20 - for i := 0; i < trials; i++ { - tr.CloseIdleConnections() - res, err := client.Get(ts.URL + "/keep-alive-then-die") - if err != nil { - t.Fatal(err) - } - <-closedc - slurp, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if string(slurp) != "foo" { - t.Errorf("Got %q, want foo", slurp) - } - - // Now try again and see if we successfully - // pick a new connection. - res, err = client.Get(ts.URL + "/") - if err != nil { - errs = append(errs, err) - continue - } - slurp, err = ioutil.ReadAll(res.Body) - if err != nil { - errs = append(errs, err) - continue - } - nSuccess++ - } - if nSuccess > 0 { - t.Logf("successes = %d of %d", nSuccess, trials) - } else { - t.Errorf("All runs failed:") - } - for _, err := range errs { - t.Logf(" err: %v", err) - } -} - -// byteFromChanReader is an io.Reader that reads a single byte at a -// time from the channel. When the channel is closed, the reader -// returns io.EOF. -type byteFromChanReader chan byte - -func (c byteFromChanReader) Read(p []byte) (n int, err error) { - if len(p) == 0 { - return - } - b, ok := <-c - if !ok { - return 0, io.EOF - } - p[0] = b - return 1, nil -} - -// Verifies that the Transport doesn't reuse a connection in the case -// where the server replies before the request has been fully -// written. We still honor that reply (see TestIssue3595), but don't -// send future requests on the connection because it's then in a -// questionable state. -// golang.org/issue/7569 -func TestTransportNoReuseAfterEarlyResponse(t *testing.T) { - defer afterTest(t) - var sconn struct { - sync.Mutex - c net.Conn - } - var getOkay bool - closeConn := func() { - sconn.Lock() - defer sconn.Unlock() - if sconn.c != nil { - sconn.c.Close() - sconn.c = nil - if !getOkay { - t.Logf("Closed server connection") - } - } - } - defer closeConn() - - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - if r.Method == "GET" { - io.WriteString(w, "bar") - return - } - conn, _, _ := w.(Hijacker).Hijack() - sconn.Lock() - sconn.c = conn - sconn.Unlock() - conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive - go io.Copy(ioutil.Discard, conn) - })) - defer ts.Close() - tr := &Transport{} - defer tr.CloseIdleConnections() - client := &Client{Transport: tr} - - const bodySize = 256 << 10 - finalBit := make(byteFromChanReader, 1) - req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit)) - req.ContentLength = bodySize - res, err := client.Do(req) - if err := wantBody(res, err, "foo"); err != nil { - t.Errorf("POST response: %v", err) - } - donec := make(chan bool) - go func() { - defer close(donec) - res, err = client.Get(ts.URL) - if err := wantBody(res, err, "bar"); err != nil { - t.Errorf("GET response: %v", err) - return - } - getOkay = true // suppress test noise - }() - time.AfterFunc(5*time.Second, closeConn) - select { - case <-donec: - finalBit <- 'x' // unblock the writeloop of the first Post - close(finalBit) - case <-time.After(7 * time.Second): - t.Fatal("timeout waiting for GET request to finish") - } -} - -type errorReader struct { - err error -} - -func (e errorReader) Read(p []byte) (int, error) { return 0, e.err } - -type closerFunc func() error - -func (f closerFunc) Close() error { return f() } - -// Issue 6981 -func TestTransportClosesBodyOnError(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skip("skipping test; see http://golang.org/issue/7782") - } - defer afterTest(t) - readBody := make(chan error, 1) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - _, err := ioutil.ReadAll(r.Body) - readBody <- err - })) - defer ts.Close() - fakeErr := errors.New("fake error") - didClose := make(chan bool, 1) - req, _ := NewRequest("POST", ts.URL, struct { - io.Reader - io.Closer - }{ - io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}), - closerFunc(func() error { - select { - case didClose <- true: - default: - } - return nil - }), - }) - res, err := DefaultClient.Do(req) - if res != nil { - defer res.Body.Close() - } - if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) { - t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error()) - } - select { - case err := <-readBody: - if err == nil { - t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'") - } - case <-time.After(5 * time.Second): - t.Error("timeout waiting for server handler to complete") - } - select { - case <-didClose: - default: - t.Errorf("didn't see Body.Close") - } -} - -func wantBody(res *http.Response, err error, want string) error { - if err != nil { - return err - } - slurp, err := ioutil.ReadAll(res.Body) - if err != nil { - return fmt.Errorf("error reading body: %v", err) - } - if string(slurp) != want { - return fmt.Errorf("body = %q; want %q", slurp, want) - } - if err := res.Body.Close(); err != nil { - return fmt.Errorf("body Close = %v", err) - } - return nil -} - -func newLocalListener(t *testing.T) net.Listener { - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - ln, err = net.Listen("tcp6", "[::1]:0") - } - if err != nil { - t.Fatal(err) - } - return ln -} - -type countCloseReader struct { - n *int - io.Reader -} - -func (cr countCloseReader) Close() error { - (*cr.n)++ - return nil -} - -// rgz is a gzip quine that uncompresses to itself. -var rgz = []byte{ - 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, - 0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0, - 0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, - 0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, - 0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60, - 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2, - 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00, - 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, - 0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16, - 0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05, - 0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff, - 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00, - 0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, - 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, - 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, - 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, - 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, - 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, - 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff, - 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, - 0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, - 0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, - 0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00, - 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, - 0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, - 0x00, 0x00, -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/triv.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/triv.go deleted file mode 100644 index 232d650890..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/triv.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -import ( - "bytes" - "expvar" - "flag" - "fmt" - "io" - "log" - "net/http" - "os" - "os/exec" - "strconv" - "sync" -) - -// hello world, the web server -var helloRequests = expvar.NewInt("hello-requests") - -func HelloServer(w http.ResponseWriter, req *http.Request) { - helloRequests.Add(1) - io.WriteString(w, "hello, world!\n") -} - -// Simple counter server. POSTing to it will set the value. -type Counter struct { - mu sync.Mutex // protects n - n int -} - -// This makes Counter satisfy the expvar.Var interface, so we can export -// it directly. -func (ctr *Counter) String() string { - ctr.mu.Lock() - defer ctr.mu.Unlock() - return fmt.Sprintf("%d", ctr.n) -} - -func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) { - ctr.mu.Lock() - defer ctr.mu.Unlock() - switch req.Method { - case "GET": - ctr.n++ - case "POST": - buf := new(bytes.Buffer) - io.Copy(buf, req.Body) - body := buf.String() - if n, err := strconv.Atoi(body); err != nil { - fmt.Fprintf(w, "bad POST: %v\nbody: [%v]\n", err, body) - } else { - ctr.n = n - fmt.Fprint(w, "counter reset\n") - } - } - fmt.Fprintf(w, "counter = %d\n", ctr.n) -} - -// simple flag server -var booleanflag = flag.Bool("boolean", true, "another flag for testing") - -func FlagServer(w http.ResponseWriter, req *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - fmt.Fprint(w, "Flags:\n") - flag.VisitAll(func(f *flag.Flag) { - if f.Value.String() != f.DefValue { - fmt.Fprintf(w, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue) - } else { - fmt.Fprintf(w, "%s = %s\n", f.Name, f.Value.String()) - } - }) -} - -// simple argument server -func ArgServer(w http.ResponseWriter, req *http.Request) { - for _, s := range os.Args { - fmt.Fprint(w, s, " ") - } -} - -// a channel (just for the fun of it) -type Chan chan int - -func ChanCreate() Chan { - c := make(Chan) - go func(c Chan) { - for x := 0; ; x++ { - c <- x - } - }(c) - return c -} - -func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) { - io.WriteString(w, fmt.Sprintf("channel send #%d\n", <-ch)) -} - -// exec a program, redirecting output -func DateServer(rw http.ResponseWriter, req *http.Request) { - rw.Header().Set("Content-Type", "text/plain; charset=utf-8") - - date, err := exec.Command("/bin/date").Output() - if err != nil { - http.Error(rw, err.Error(), 500) - return - } - rw.Write(date) -} - -func Logger(w http.ResponseWriter, req *http.Request) { - log.Print(req.URL) - http.Error(w, "oops", 404) -} - -var webroot = flag.String("root", os.Getenv("HOME"), "web root directory") - -func main() { - flag.Parse() - - // The counter is published as a variable directly. - ctr := new(Counter) - expvar.Publish("counter", ctr) - http.Handle("/counter", ctr) - http.Handle("/", http.HandlerFunc(Logger)) - http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot)))) - http.Handle("/chan", ChanCreate()) - http.HandleFunc("/flags", FlagServer) - http.HandleFunc("/args", ArgServer) - http.HandleFunc("/go/hello", HelloServer) - http.HandleFunc("/date", DateServer) - err := http.ListenAndServe(":12345", nil) - if err != nil { - log.Panicln("ListenAndServe:", err) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/z_last_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/z_last_test.go deleted file mode 100644 index 5a0cc11984..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/http/z_last_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "net/http" - "runtime" - "sort" - "strings" - "testing" - "time" -) - -func interestingGoroutines() (gs []string) { - buf := make([]byte, 2<<20) - buf = buf[:runtime.Stack(buf, true)] - for _, g := range strings.Split(string(buf), "\n\n") { - sl := strings.SplitN(g, "\n", 2) - if len(sl) != 2 { - continue - } - stack := strings.TrimSpace(sl[1]) - if stack == "" || - strings.Contains(stack, "created by net.startServer") || - strings.Contains(stack, "created by testing.RunTests") || - strings.Contains(stack, "closeWriteAndWait") || - strings.Contains(stack, "testing.Main(") || - // These only show up with GOTRACEBACK=2; Issue 5005 (comment 28) - strings.Contains(stack, "runtime.goexit") || - strings.Contains(stack, "created by runtime.gc") || - strings.Contains(stack, "runtime.MHeap_Scavenger") { - continue - } - gs = append(gs, stack) - } - sort.Strings(gs) - return -} - -// Verify the other tests didn't leave any goroutines running. -// This is in a file named z_last_test.go so it sorts at the end. -func TestGoroutinesRunning(t *testing.T) { - if testing.Short() { - t.Skip("not counting goroutines for leakage in -short mode") - } - gs := interestingGoroutines() - - n := 0 - stackCount := make(map[string]int) - for _, g := range gs { - stackCount[g]++ - n++ - } - - t.Logf("num goroutines = %d", n) - if n > 0 { - t.Error("Too many goroutines.") - for stack, count := range stackCount { - t.Logf("%d instances of:\n%s", count, stack) - } - } -} - -func afterTest(t *testing.T) { - http.DefaultTransport.(*http.Transport).CloseIdleConnections() - if testing.Short() { - return - } - var bad string - badSubstring := map[string]string{ - ").readLoop(": "a Transport", - ").writeLoop(": "a Transport", - "created by net/http/httptest.(*Server).Start": "an httptest.Server", - "timeoutHandler": "a TimeoutHandler", - "net.(*netFD).connect(": "a timing out dial", - ").noteClientGone(": "a closenotifier sender", - } - var stacks string - for i := 0; i < 4; i++ { - bad = "" - stacks = strings.Join(interestingGoroutines(), "\n\n") - for substr, what := range badSubstring { - if strings.Contains(stacks, substr) { - bad = what - } - } - if bad == "" { - return - } - // Bad stuff found, but goroutines might just still be - // shutting down, so give it some time. - time.Sleep(250 * time.Millisecond) - } - t.Errorf("Test appears to have leaked %s:\n%s", bad, stacks) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/alert.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/alert.go deleted file mode 100644 index 0856311e4c..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/alert.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import "strconv" - -type alert uint8 - -const ( - // alert level - alertLevelWarning = 1 - alertLevelError = 2 -) - -const ( - alertCloseNotify alert = 0 - alertUnexpectedMessage alert = 10 - alertBadRecordMAC alert = 20 - alertDecryptionFailed alert = 21 - alertRecordOverflow alert = 22 - alertDecompressionFailure alert = 30 - alertHandshakeFailure alert = 40 - alertBadCertificate alert = 42 - alertUnsupportedCertificate alert = 43 - alertCertificateRevoked alert = 44 - alertCertificateExpired alert = 45 - alertCertificateUnknown alert = 46 - alertIllegalParameter alert = 47 - alertUnknownCA alert = 48 - alertAccessDenied alert = 49 - alertDecodeError alert = 50 - alertDecryptError alert = 51 - alertProtocolVersion alert = 70 - alertInsufficientSecurity alert = 71 - alertInternalError alert = 80 - alertUserCanceled alert = 90 - alertNoRenegotiation alert = 100 -) - -var alertText = map[alert]string{ - alertCloseNotify: "close notify", - alertUnexpectedMessage: "unexpected message", - alertBadRecordMAC: "bad record MAC", - alertDecryptionFailed: "decryption failed", - alertRecordOverflow: "record overflow", - alertDecompressionFailure: "decompression failure", - alertHandshakeFailure: "handshake failure", - alertBadCertificate: "bad certificate", - alertUnsupportedCertificate: "unsupported certificate", - alertCertificateRevoked: "revoked certificate", - alertCertificateExpired: "expired certificate", - alertCertificateUnknown: "unknown certificate", - alertIllegalParameter: "illegal parameter", - alertUnknownCA: "unknown certificate authority", - alertAccessDenied: "access denied", - alertDecodeError: "error decoding message", - alertDecryptError: "error decrypting message", - alertProtocolVersion: "protocol version not supported", - alertInsufficientSecurity: "insufficient security level", - alertInternalError: "internal error", - alertUserCanceled: "user canceled", - alertNoRenegotiation: "no renegotiation", -} - -func (e alert) String() string { - s, ok := alertText[e] - if ok { - return s - } - return "alert(" + strconv.Itoa(int(e)) + ")" -} - -func (e alert) Error() string { - return e.String() -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/cipher_suites.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/cipher_suites.go deleted file mode 100644 index 39a51459d2..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/cipher_suites.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/hmac" - "crypto/rc4" - "crypto/sha1" - "crypto/x509" - "hash" -) - -// a keyAgreement implements the client and server side of a TLS key agreement -// protocol by generating and processing key exchange messages. -type keyAgreement interface { - // On the server side, the first two methods are called in order. - - // In the case that the key agreement protocol doesn't use a - // ServerKeyExchange message, generateServerKeyExchange can return nil, - // nil. - generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) - processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) - - // On the client side, the next two methods are called in order. - - // This method may not be called if the server doesn't send a - // ServerKeyExchange message. - processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error - generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) -} - -const ( - // suiteECDH indicates that the cipher suite involves elliptic curve - // Diffie-Hellman. This means that it should only be selected when the - // client indicates that it supports ECC with a curve and point format - // that we're happy with. - suiteECDHE = 1 << iota - // suiteECDSA indicates that the cipher suite involves an ECDSA - // signature and therefore may only be selected when the server's - // certificate is ECDSA. If this is not set then the cipher suite is - // RSA based. - suiteECDSA - // suiteTLS12 indicates that the cipher suite should only be advertised - // and accepted when using TLS 1.2. - suiteTLS12 -) - -// A cipherSuite is a specific combination of key agreement, cipher and MAC -// function. All cipher suites currently assume RSA key agreement. -type cipherSuite struct { - id uint16 - // the lengths, in bytes, of the key material needed for each component. - keyLen int - macLen int - ivLen int - ka func(version uint16) keyAgreement - // flags is a bitmask of the suite* values, above. - flags int - cipher func(key, iv []byte, isRead bool) interface{} - mac func(version uint16, macKey []byte) macFunction - aead func(key, fixedNonce []byte) cipher.AEAD -} - -var cipherSuites = []*cipherSuite{ - // Ciphersuite order is chosen so that ECDHE comes before plain RSA - // and RC4 comes before AES (because of the Lucky13 attack). - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil}, - {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, -} - -func cipherRC4(key, iv []byte, isRead bool) interface{} { - cipher, _ := rc4.NewCipher(key) - return cipher -} - -func cipher3DES(key, iv []byte, isRead bool) interface{} { - block, _ := des.NewTripleDESCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -func cipherAES(key, iv []byte, isRead bool) interface{} { - block, _ := aes.NewCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -// macSHA1 returns a macFunction for the given protocol version. -func macSHA1(version uint16, key []byte) macFunction { - if version == VersionSSL30 { - mac := ssl30MAC{ - h: sha1.New(), - key: make([]byte, len(key)), - } - copy(mac.key, key) - return mac - } - return tls10MAC{hmac.New(sha1.New, key)} -} - -type macFunction interface { - Size() int - MAC(digestBuf, seq, header, data []byte) []byte -} - -// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to -// each call. -type fixedNonceAEAD struct { - // sealNonce and openNonce are buffers where the larger nonce will be - // constructed. Since a seal and open operation may be running - // concurrently, there is a separate buffer for each. - sealNonce, openNonce []byte - aead cipher.AEAD -} - -func (f *fixedNonceAEAD) NonceSize() int { return 8 } -func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } - -func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { - copy(f.sealNonce[len(f.sealNonce)-8:], nonce) - return f.aead.Seal(out, f.sealNonce, plaintext, additionalData) -} - -func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) { - copy(f.openNonce[len(f.openNonce)-8:], nonce) - return f.aead.Open(out, f.openNonce, plaintext, additionalData) -} - -func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { - aes, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - aead, err := cipher.NewGCM(aes) - if err != nil { - panic(err) - } - - nonce1, nonce2 := make([]byte, 12), make([]byte, 12) - copy(nonce1, fixedNonce) - copy(nonce2, fixedNonce) - - return &fixedNonceAEAD{nonce1, nonce2, aead} -} - -// ssl30MAC implements the SSLv3 MAC function, as defined in -// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 -type ssl30MAC struct { - h hash.Hash - key []byte -} - -func (s ssl30MAC) Size() int { - return s.h.Size() -} - -var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36} - -var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c} - -func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte { - padLength := 48 - if s.h.Size() == 20 { - padLength = 40 - } - - s.h.Reset() - s.h.Write(s.key) - s.h.Write(ssl30Pad1[:padLength]) - s.h.Write(seq) - s.h.Write(header[:1]) - s.h.Write(header[3:5]) - s.h.Write(data) - digestBuf = s.h.Sum(digestBuf[:0]) - - s.h.Reset() - s.h.Write(s.key) - s.h.Write(ssl30Pad2[:padLength]) - s.h.Write(digestBuf) - return s.h.Sum(digestBuf[:0]) -} - -// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. -type tls10MAC struct { - h hash.Hash -} - -func (s tls10MAC) Size() int { - return s.h.Size() -} - -func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte { - s.h.Reset() - s.h.Write(seq) - s.h.Write(header) - s.h.Write(data) - return s.h.Sum(digestBuf[:0]) -} - -func rsaKA(version uint16) keyAgreement { - return rsaKeyAgreement{} -} - -func ecdheECDSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - sigType: signatureECDSA, - version: version, - } -} - -func ecdheRSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - sigType: signatureRSA, - version: version, - } -} - -// mutualCipherSuite returns a cipherSuite given a list of supported -// ciphersuites and the id requested by the peer. -func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { - for _, id := range have { - if id == want { - for _, suite := range cipherSuites { - if suite.id == want { - return suite - } - } - return nil - } - } - return nil -} - -// A list of the possible cipher suite ids. Taken from -// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml -const ( - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b -) diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/common.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/common.go deleted file mode 100644 index 7eb283c5a7..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/common.go +++ /dev/null @@ -1,438 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "crypto" - "crypto/rand" - "crypto/x509" - "io" - "math/big" - "strings" - "sync" - "time" -) - -const ( - VersionSSL30 = 0x0300 - VersionTLS10 = 0x0301 - VersionTLS11 = 0x0302 - VersionTLS12 = 0x0303 -) - -const ( - maxPlaintext = 16384 // maximum plaintext payload length - maxCiphertext = 16384 + 2048 // maximum ciphertext payload length - recordHeaderLen = 5 // record header length - maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) - - minVersion = VersionSSL30 - maxVersion = VersionTLS12 -) - -// TLS record types. -type recordType uint8 - -const ( - recordTypeChangeCipherSpec recordType = 20 - recordTypeAlert recordType = 21 - recordTypeHandshake recordType = 22 - recordTypeApplicationData recordType = 23 -) - -// TLS handshake message types. -const ( - typeHelloRequest uint8 = 0 - typeClientHello uint8 = 1 - typeServerHello uint8 = 2 - typeNewSessionTicket uint8 = 4 - typeCertificate uint8 = 11 - typeServerKeyExchange uint8 = 12 - typeCertificateRequest uint8 = 13 - typeServerHelloDone uint8 = 14 - typeCertificateVerify uint8 = 15 - typeClientKeyExchange uint8 = 16 - typeFinished uint8 = 20 - typeCertificateStatus uint8 = 22 - typeNextProtocol uint8 = 67 // Not IANA assigned -) - -// TLS compression types. -const ( - compressionNone uint8 = 0 -) - -// TLS extension numbers -var ( - extensionServerName uint16 = 0 - extensionStatusRequest uint16 = 5 - extensionSupportedCurves uint16 = 10 - extensionSupportedPoints uint16 = 11 - extensionSignatureAlgorithms uint16 = 13 - extensionSessionTicket uint16 = 35 - extensionNextProtoNeg uint16 = 13172 // not IANA assigned -) - -// TLS Elliptic Curves -// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 -var ( - curveP256 uint16 = 23 - curveP384 uint16 = 24 - curveP521 uint16 = 25 -) - -// TLS Elliptic Curve Point Formats -// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 -var ( - pointFormatUncompressed uint8 = 0 -) - -// TLS CertificateStatusType (RFC 3546) -const ( - statusTypeOCSP uint8 = 1 -) - -// Certificate types (for certificateRequestMsg) -const ( - certTypeRSASign = 1 // A certificate containing an RSA key - certTypeDSSSign = 2 // A certificate containing a DSA key - certTypeRSAFixedDH = 3 // A certificate containing a static DH key - certTypeDSSFixedDH = 4 // A certificate containing a static DH key - - // See RFC4492 sections 3 and 5.5. - certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. - certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. - certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. - - // Rest of these are reserved by the TLS spec -) - -// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1) -const ( - hashSHA1 uint8 = 2 - hashSHA256 uint8 = 4 -) - -// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1) -const ( - signatureRSA uint8 = 1 - signatureECDSA uint8 = 3 -) - -// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See -// RFC 5246, section A.4.1. -type signatureAndHash struct { - hash, signature uint8 -} - -// supportedSKXSignatureAlgorithms contains the signature and hash algorithms -// that the code advertises as supported in a TLS 1.2 ClientHello. -var supportedSKXSignatureAlgorithms = []signatureAndHash{ - {hashSHA256, signatureRSA}, - {hashSHA256, signatureECDSA}, - {hashSHA1, signatureRSA}, - {hashSHA1, signatureECDSA}, -} - -// supportedClientCertSignatureAlgorithms contains the signature and hash -// algorithms that the code advertises as supported in a TLS 1.2 -// CertificateRequest. -var supportedClientCertSignatureAlgorithms = []signatureAndHash{ - {hashSHA256, signatureRSA}, - {hashSHA256, signatureECDSA}, -} - -// ConnectionState records basic TLS details about the connection. -type ConnectionState struct { - HandshakeComplete bool // TLS handshake is complete - DidResume bool // connection resumes a previous TLS connection - CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...) - NegotiatedProtocol string // negotiated next protocol (from Config.NextProtos) - NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server - ServerName string // server name requested by client, if any (server side only) - PeerCertificates []*x509.Certificate // certificate chain presented by remote peer - VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates -} - -// ClientAuthType declares the policy the server will follow for -// TLS Client Authentication. -type ClientAuthType int - -const ( - NoClientCert ClientAuthType = iota - RequestClientCert - RequireAnyClientCert - VerifyClientCertIfGiven - RequireAndVerifyClientCert -) - -// A Config structure is used to configure a TLS client or server. After one -// has been passed to a TLS function it must not be modified. -type Config struct { - // Rand provides the source of entropy for nonces and RSA blinding. - // If Rand is nil, TLS uses the cryptographic random reader in package - // crypto/rand. - Rand io.Reader - - // Time returns the current time as the number of seconds since the epoch. - // If Time is nil, TLS uses time.Now. - Time func() time.Time - - // Certificates contains one or more certificate chains - // to present to the other side of the connection. - // Server configurations must include at least one certificate. - Certificates []Certificate - - // NameToCertificate maps from a certificate name to an element of - // Certificates. Note that a certificate name can be of the form - // '*.example.com' and so doesn't have to be a domain name as such. - // See Config.BuildNameToCertificate - // The nil value causes the first element of Certificates to be used - // for all connections. - NameToCertificate map[string]*Certificate - - // RootCAs defines the set of root certificate authorities - // that clients use when verifying server certificates. - // If RootCAs is nil, TLS uses the host's root CA set. - RootCAs *x509.CertPool - - // NextProtos is a list of supported, application level protocols. - NextProtos []string - - // ServerName is included in the client's handshake to support virtual - // hosting. - ServerName string - - // ClientAuth determines the server's policy for - // TLS Client Authentication. The default is NoClientCert. - ClientAuth ClientAuthType - - // ClientCAs defines the set of root certificate authorities - // that servers use if required to verify a client certificate - // by the policy in ClientAuth. - ClientCAs *x509.CertPool - - // InsecureSkipVerify controls whether a client verifies the - // server's certificate chain and host name. - // If InsecureSkipVerify is true, TLS accepts any certificate - // presented by the server and any host name in that certificate. - // In this mode, TLS is susceptible to man-in-the-middle attacks. - // This should be used only for testing. - InsecureSkipVerify bool - - // CipherSuites is a list of supported cipher suites. If CipherSuites - // is nil, TLS uses a list of suites supported by the implementation. - CipherSuites []uint16 - - // PreferServerCipherSuites controls whether the server selects the - // client's most preferred ciphersuite, or the server's most preferred - // ciphersuite. If true then the server's preference, as expressed in - // the order of elements in CipherSuites, is used. - PreferServerCipherSuites bool - - // SessionTicketsDisabled may be set to true to disable session ticket - // (resumption) support. - SessionTicketsDisabled bool - - // SessionTicketKey is used by TLS servers to provide session - // resumption. See RFC 5077. If zero, it will be filled with - // random data before the first server handshake. - // - // If multiple servers are terminating connections for the same host - // they should all have the same SessionTicketKey. If the - // SessionTicketKey leaks, previously recorded and future TLS - // connections using that key are compromised. - SessionTicketKey [32]byte - - // MinVersion contains the minimum SSL/TLS version that is acceptable. - // If zero, then SSLv3 is taken as the minimum. - MinVersion uint16 - - // MaxVersion contains the maximum SSL/TLS version that is acceptable. - // If zero, then the maximum version supported by this package is used, - // which is currently TLS 1.2. - MaxVersion uint16 - - serverInitOnce sync.Once // guards calling (*Config).serverInit -} - -func (c *Config) serverInit() { - if c.SessionTicketsDisabled { - return - } - - // If the key has already been set then we have nothing to do. - for _, b := range c.SessionTicketKey { - if b != 0 { - return - } - } - - if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { - c.SessionTicketsDisabled = true - } -} - -func (c *Config) rand() io.Reader { - r := c.Rand - if r == nil { - return rand.Reader - } - return r -} - -func (c *Config) time() time.Time { - t := c.Time - if t == nil { - t = time.Now - } - return t() -} - -func (c *Config) cipherSuites() []uint16 { - s := c.CipherSuites - if s == nil { - s = defaultCipherSuites() - } - return s -} - -func (c *Config) minVersion() uint16 { - if c == nil || c.MinVersion == 0 { - return minVersion - } - return c.MinVersion -} - -func (c *Config) maxVersion() uint16 { - if c == nil || c.MaxVersion == 0 { - return maxVersion - } - return c.MaxVersion -} - -// mutualVersion returns the protocol version to use given the advertised -// version of the peer. -func (c *Config) mutualVersion(vers uint16) (uint16, bool) { - minVersion := c.minVersion() - maxVersion := c.maxVersion() - - if vers < minVersion { - return 0, false - } - if vers > maxVersion { - vers = maxVersion - } - return vers, true -} - -// getCertificateForName returns the best certificate for the given name, -// defaulting to the first element of c.Certificates if there are no good -// options. -func (c *Config) getCertificateForName(name string) *Certificate { - if len(c.Certificates) == 1 || c.NameToCertificate == nil { - // There's only one choice, so no point doing any work. - return &c.Certificates[0] - } - - name = strings.ToLower(name) - for len(name) > 0 && name[len(name)-1] == '.' { - name = name[:len(name)-1] - } - - if cert, ok := c.NameToCertificate[name]; ok { - return cert - } - - // try replacing labels in the name with wildcards until we get a - // match. - labels := strings.Split(name, ".") - for i := range labels { - labels[i] = "*" - candidate := strings.Join(labels, ".") - if cert, ok := c.NameToCertificate[candidate]; ok { - return cert - } - } - - // If nothing matches, return the first certificate. - return &c.Certificates[0] -} - -// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate -// from the CommonName and SubjectAlternateName fields of each of the leaf -// certificates. -func (c *Config) BuildNameToCertificate() { - c.NameToCertificate = make(map[string]*Certificate) - for i := range c.Certificates { - cert := &c.Certificates[i] - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - continue - } - if len(x509Cert.Subject.CommonName) > 0 { - c.NameToCertificate[x509Cert.Subject.CommonName] = cert - } - for _, san := range x509Cert.DNSNames { - c.NameToCertificate[san] = cert - } - } -} - -// A Certificate is a chain of one or more certificates, leaf first. -type Certificate struct { - Certificate [][]byte - PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey - // OCSPStaple contains an optional OCSP response which will be served - // to clients that request it. - OCSPStaple []byte - // Leaf is the parsed form of the leaf certificate, which may be - // initialized using x509.ParseCertificate to reduce per-handshake - // processing for TLS clients doing client authentication. If nil, the - // leaf certificate will be parsed as needed. - Leaf *x509.Certificate -} - -// A TLS record. -type record struct { - contentType recordType - major, minor uint8 - payload []byte -} - -type handshakeMessage interface { - marshal() []byte - unmarshal([]byte) bool -} - -// TODO(jsing): Make these available to both crypto/x509 and crypto/tls. -type dsaSignature struct { - R, S *big.Int -} - -type ecdsaSignature dsaSignature - -var emptyConfig Config - -func defaultConfig() *Config { - return &emptyConfig -} - -var ( - once sync.Once - varDefaultCipherSuites []uint16 -) - -func defaultCipherSuites() []uint16 { - once.Do(initDefaultCipherSuites) - return varDefaultCipherSuites -} - -func initDefaultCipherSuites() { - varDefaultCipherSuites = make([]uint16, len(cipherSuites)) - for i, suite := range cipherSuites { - varDefaultCipherSuites[i] = suite.id - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/conn.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/conn.go deleted file mode 100644 index db036f9677..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/conn.go +++ /dev/null @@ -1,1026 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// TLS low level connection and record layer - -package tls - -import ( - "bytes" - "crypto/cipher" - "crypto/subtle" - "crypto/x509" - "errors" - "io" - "net" - "sync" - "time" -) - -// A Conn represents a secured connection. -// It implements the net.Conn interface. -type Conn struct { - // constant - conn net.Conn - isClient bool - - // constant after handshake; protected by handshakeMutex - handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex - vers uint16 // TLS version - haveVers bool // version has been negotiated - config *Config // configuration passed to constructor - handshakeComplete bool - didResume bool // whether this connection was a session resumption - cipherSuite uint16 - ocspResponse []byte // stapled OCSP response - peerCertificates []*x509.Certificate - // verifiedChains contains the certificate chains that we built, as - // opposed to the ones presented by the server. - verifiedChains [][]*x509.Certificate - // serverName contains the server name indicated by the client, if any. - serverName string - - clientProtocol string - clientProtocolFallback bool - - // first permanent error - connErr - - // input/output - in, out halfConn // in.Mutex < out.Mutex - rawInput *block // raw input, right off the wire - input *block // application data waiting to be read - hand bytes.Buffer // handshake data waiting to be read - - tmp [16]byte -} - -type connErr struct { - mu sync.Mutex - value error -} - -func (e *connErr) setError(err error) error { - e.mu.Lock() - defer e.mu.Unlock() - - if e.value == nil { - e.value = err - } - return err -} - -func (e *connErr) error() error { - e.mu.Lock() - defer e.mu.Unlock() - return e.value -} - -// Access to net.Conn methods. -// Cannot just embed net.Conn because that would -// export the struct field too. - -// LocalAddr returns the local network address. -func (c *Conn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -// RemoteAddr returns the remote network address. -func (c *Conn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -// SetDeadline sets the read and write deadlines associated with the connection. -// A zero value for t means Read and Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline on the underlying connection. -// A zero value for t means Read will not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline on the underlying conneciton. -// A zero value for t means Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -// A halfConn represents one direction of the record layer -// connection, either sending or receiving. -type halfConn struct { - sync.Mutex - version uint16 // protocol version - cipher interface{} // cipher algorithm - mac macFunction - seq [8]byte // 64-bit sequence number - bfree *block // list of free blocks - - nextCipher interface{} // next encryption state - nextMac macFunction // next MAC algorithm - - // used to save allocating a new buffer for each MAC. - inDigestBuf, outDigestBuf []byte -} - -// prepareCipherSpec sets the encryption and MAC states -// that a subsequent changeCipherSpec will use. -func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) { - hc.version = version - hc.nextCipher = cipher - hc.nextMac = mac -} - -// changeCipherSpec changes the encryption and MAC states -// to the ones previously passed to prepareCipherSpec. -func (hc *halfConn) changeCipherSpec() error { - if hc.nextCipher == nil { - return alertInternalError - } - hc.cipher = hc.nextCipher - hc.mac = hc.nextMac - hc.nextCipher = nil - hc.nextMac = nil - for i := range hc.seq { - hc.seq[i] = 0 - } - return nil -} - -// incSeq increments the sequence number. -func (hc *halfConn) incSeq() { - for i := 7; i >= 0; i-- { - hc.seq[i]++ - if hc.seq[i] != 0 { - return - } - } - - // Not allowed to let sequence number wrap. - // Instead, must renegotiate before it does. - // Not likely enough to bother. - panic("TLS: sequence number wraparound") -} - -// resetSeq resets the sequence number to zero. -func (hc *halfConn) resetSeq() { - for i := range hc.seq { - hc.seq[i] = 0 - } -} - -// removePadding returns an unpadded slice, in constant time, which is a prefix -// of the input. It also returns a byte which is equal to 255 if the padding -// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2 -func removePadding(payload []byte) ([]byte, byte) { - if len(payload) < 1 { - return payload, 0 - } - - paddingLen := payload[len(payload)-1] - t := uint(len(payload)-1) - uint(paddingLen) - // if len(payload) >= (paddingLen - 1) then the MSB of t is zero - good := byte(int32(^t) >> 31) - - toCheck := 255 // the maximum possible padding length - // The length of the padded data is public, so we can use an if here - if toCheck+1 > len(payload) { - toCheck = len(payload) - 1 - } - - for i := 0; i < toCheck; i++ { - t := uint(paddingLen) - uint(i) - // if i <= paddingLen then the MSB of t is zero - mask := byte(int32(^t) >> 31) - b := payload[len(payload)-1-i] - good &^= mask&paddingLen ^ mask&b - } - - // We AND together the bits of good and replicate the result across - // all the bits. - good &= good << 4 - good &= good << 2 - good &= good << 1 - good = uint8(int8(good) >> 7) - - toRemove := good&paddingLen + 1 - return payload[:len(payload)-int(toRemove)], good -} - -// removePaddingSSL30 is a replacement for removePadding in the case that the -// protocol version is SSLv3. In this version, the contents of the padding -// are random and cannot be checked. -func removePaddingSSL30(payload []byte) ([]byte, byte) { - if len(payload) < 1 { - return payload, 0 - } - - paddingLen := int(payload[len(payload)-1]) + 1 - if paddingLen > len(payload) { - return payload, 0 - } - - return payload[:len(payload)-paddingLen], 255 -} - -func roundUp(a, b int) int { - return a + (b-a%b)%b -} - -// cbcMode is an interface for block ciphers using cipher block chaining. -type cbcMode interface { - cipher.BlockMode - SetIV([]byte) -} - -// decrypt checks and strips the mac and decrypts the data in b. Returns a -// success boolean, the number of bytes to skip from the start of the record in -// order to get the application payload, and an optional alert value. -func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) { - // pull out payload - payload := b.data[recordHeaderLen:] - - macSize := 0 - if hc.mac != nil { - macSize = hc.mac.Size() - } - - paddingGood := byte(255) - explicitIVLen := 0 - - // decrypt - if hc.cipher != nil { - switch c := hc.cipher.(type) { - case cipher.Stream: - c.XORKeyStream(payload, payload) - case cipher.AEAD: - explicitIVLen = 8 - if len(payload) < explicitIVLen { - return false, 0, alertBadRecordMAC - } - nonce := payload[:8] - payload = payload[8:] - - var additionalData [13]byte - copy(additionalData[:], hc.seq[:]) - copy(additionalData[8:], b.data[:3]) - n := len(payload) - c.Overhead() - additionalData[11] = byte(n >> 8) - additionalData[12] = byte(n) - var err error - payload, err = c.Open(payload[:0], nonce, payload, additionalData[:]) - if err != nil { - return false, 0, alertBadRecordMAC - } - b.resize(recordHeaderLen + explicitIVLen + len(payload)) - case cbcMode: - blockSize := c.BlockSize() - if hc.version >= VersionTLS11 { - explicitIVLen = blockSize - } - - if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) { - return false, 0, alertBadRecordMAC - } - - if explicitIVLen > 0 { - c.SetIV(payload[:explicitIVLen]) - payload = payload[explicitIVLen:] - } - c.CryptBlocks(payload, payload) - if hc.version == VersionSSL30 { - payload, paddingGood = removePaddingSSL30(payload) - } else { - payload, paddingGood = removePadding(payload) - } - b.resize(recordHeaderLen + explicitIVLen + len(payload)) - - // note that we still have a timing side-channel in the - // MAC check, below. An attacker can align the record - // so that a correct padding will cause one less hash - // block to be calculated. Then they can iteratively - // decrypt a record by breaking each byte. See - // "Password Interception in a SSL/TLS Channel", Brice - // Canvel et al. - // - // However, our behavior matches OpenSSL, so we leak - // only as much as they do. - default: - panic("unknown cipher type") - } - } - - // check, strip mac - if hc.mac != nil { - if len(payload) < macSize { - return false, 0, alertBadRecordMAC - } - - // strip mac off payload, b.data - n := len(payload) - macSize - b.data[3] = byte(n >> 8) - b.data[4] = byte(n) - b.resize(recordHeaderLen + explicitIVLen + n) - remoteMAC := payload[n:] - localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], payload[:n]) - - if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { - return false, 0, alertBadRecordMAC - } - hc.inDigestBuf = localMAC - } - hc.incSeq() - - return true, recordHeaderLen + explicitIVLen, 0 -} - -// padToBlockSize calculates the needed padding block, if any, for a payload. -// On exit, prefix aliases payload and extends to the end of the last full -// block of payload. finalBlock is a fresh slice which contains the contents of -// any suffix of payload as well as the needed padding to make finalBlock a -// full block. -func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) { - overrun := len(payload) % blockSize - paddingLen := blockSize - overrun - prefix = payload[:len(payload)-overrun] - finalBlock = make([]byte, blockSize) - copy(finalBlock, payload[len(payload)-overrun:]) - for i := overrun; i < blockSize; i++ { - finalBlock[i] = byte(paddingLen - 1) - } - return -} - -// encrypt encrypts and macs the data in b. -func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { - // mac - if hc.mac != nil { - mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:]) - - n := len(b.data) - b.resize(n + len(mac)) - copy(b.data[n:], mac) - hc.outDigestBuf = mac - } - - payload := b.data[recordHeaderLen:] - - // encrypt - if hc.cipher != nil { - switch c := hc.cipher.(type) { - case cipher.Stream: - c.XORKeyStream(payload, payload) - case cipher.AEAD: - payloadLen := len(b.data) - recordHeaderLen - explicitIVLen - b.resize(len(b.data) + c.Overhead()) - nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] - payload := b.data[recordHeaderLen+explicitIVLen:] - payload = payload[:payloadLen] - - var additionalData [13]byte - copy(additionalData[:], hc.seq[:]) - copy(additionalData[8:], b.data[:3]) - additionalData[11] = byte(payloadLen >> 8) - additionalData[12] = byte(payloadLen) - - c.Seal(payload[:0], nonce, payload, additionalData[:]) - case cbcMode: - blockSize := c.BlockSize() - if explicitIVLen > 0 { - c.SetIV(payload[:explicitIVLen]) - payload = payload[explicitIVLen:] - } - prefix, finalBlock := padToBlockSize(payload, blockSize) - b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock)) - c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix) - c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock) - default: - panic("unknown cipher type") - } - } - - // update length to include MAC and any block padding needed. - n := len(b.data) - recordHeaderLen - b.data[3] = byte(n >> 8) - b.data[4] = byte(n) - hc.incSeq() - - return true, 0 -} - -// A block is a simple data buffer. -type block struct { - data []byte - off int // index for Read - link *block -} - -// resize resizes block to be n bytes, growing if necessary. -func (b *block) resize(n int) { - if n > cap(b.data) { - b.reserve(n) - } - b.data = b.data[0:n] -} - -// reserve makes sure that block contains a capacity of at least n bytes. -func (b *block) reserve(n int) { - if cap(b.data) >= n { - return - } - m := cap(b.data) - if m == 0 { - m = 1024 - } - for m < n { - m *= 2 - } - data := make([]byte, len(b.data), m) - copy(data, b.data) - b.data = data -} - -// readFromUntil reads from r into b until b contains at least n bytes -// or else returns an error. -func (b *block) readFromUntil(r io.Reader, n int) error { - // quick case - if len(b.data) >= n { - return nil - } - - // read until have enough. - b.reserve(n) - for { - m, err := r.Read(b.data[len(b.data):cap(b.data)]) - b.data = b.data[0 : len(b.data)+m] - if len(b.data) >= n { - break - } - if err != nil { - return err - } - } - return nil -} - -func (b *block) Read(p []byte) (n int, err error) { - n = copy(p, b.data[b.off:]) - b.off += n - return -} - -// newBlock allocates a new block, from hc's free list if possible. -func (hc *halfConn) newBlock() *block { - b := hc.bfree - if b == nil { - return new(block) - } - hc.bfree = b.link - b.link = nil - b.resize(0) - return b -} - -// freeBlock returns a block to hc's free list. -// The protocol is such that each side only has a block or two on -// its free list at a time, so there's no need to worry about -// trimming the list, etc. -func (hc *halfConn) freeBlock(b *block) { - b.link = hc.bfree - hc.bfree = b -} - -// splitBlock splits a block after the first n bytes, -// returning a block with those n bytes and a -// block with the remainder. the latter may be nil. -func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) { - if len(b.data) <= n { - return b, nil - } - bb := hc.newBlock() - bb.resize(len(b.data) - n) - copy(bb.data, b.data[n:]) - b.data = b.data[0:n] - return b, bb -} - -// readRecord reads the next TLS record from the connection -// and updates the record layer state. -// c.in.Mutex <= L; c.input == nil. -func (c *Conn) readRecord(want recordType) error { - // Caller must be in sync with connection: - // handshake data if handshake not yet completed, - // else application data. (We don't support renegotiation.) - switch want { - default: - return c.sendAlert(alertInternalError) - case recordTypeHandshake, recordTypeChangeCipherSpec: - if c.handshakeComplete { - return c.sendAlert(alertInternalError) - } - case recordTypeApplicationData: - if !c.handshakeComplete { - return c.sendAlert(alertInternalError) - } - } - -Again: - if c.rawInput == nil { - c.rawInput = c.in.newBlock() - } - b := c.rawInput - - // Read header, payload. - if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil { - // RFC suggests that EOF without an alertCloseNotify is - // an error, but popular web sites seem to do this, - // so we can't make it an error. - // if err == io.EOF { - // err = io.ErrUnexpectedEOF - // } - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.setError(err) - } - return err - } - typ := recordType(b.data[0]) - - // No valid TLS record has a type of 0x80, however SSLv2 handshakes - // start with a uint16 length where the MSB is set and the first record - // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests - // an SSLv2 client. - if want == recordTypeHandshake && typ == 0x80 { - c.sendAlert(alertProtocolVersion) - return errors.New("tls: unsupported SSLv2 handshake received") - } - - vers := uint16(b.data[1])<<8 | uint16(b.data[2]) - n := int(b.data[3])<<8 | int(b.data[4]) - if c.haveVers && vers != c.vers { - return c.sendAlert(alertProtocolVersion) - } - if n > maxCiphertext { - return c.sendAlert(alertRecordOverflow) - } - if !c.haveVers { - // First message, be extra suspicious: - // this might not be a TLS client. - // Bail out before reading a full 'body', if possible. - // The current max version is 3.1. - // If the version is >= 16.0, it's probably not real. - // Similarly, a clientHello message encodes in - // well under a kilobyte. If the length is >= 12 kB, - // it's probably not real. - if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 { - return c.sendAlert(alertUnexpectedMessage) - } - } - if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.setError(err) - } - return err - } - - // Process message. - b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n) - ok, off, err := c.in.decrypt(b) - if !ok { - return c.sendAlert(err) - } - b.off = off - data := b.data[b.off:] - if len(data) > maxPlaintext { - c.sendAlert(alertRecordOverflow) - c.in.freeBlock(b) - return c.error() - } - - switch typ { - default: - c.sendAlert(alertUnexpectedMessage) - - case recordTypeAlert: - if len(data) != 2 { - c.sendAlert(alertUnexpectedMessage) - break - } - if alert(data[1]) == alertCloseNotify { - c.setError(io.EOF) - break - } - switch data[0] { - case alertLevelWarning: - // drop on the floor - c.in.freeBlock(b) - goto Again - case alertLevelError: - c.setError(&net.OpError{Op: "remote error", Err: alert(data[1])}) - default: - c.sendAlert(alertUnexpectedMessage) - } - - case recordTypeChangeCipherSpec: - if typ != want || len(data) != 1 || data[0] != 1 { - c.sendAlert(alertUnexpectedMessage) - break - } - err := c.in.changeCipherSpec() - if err != nil { - c.sendAlert(err.(alert)) - } - - case recordTypeApplicationData: - if typ != want { - c.sendAlert(alertUnexpectedMessage) - break - } - c.input = b - b = nil - - case recordTypeHandshake: - // TODO(rsc): Should at least pick off connection close. - if typ != want && !c.isClient { - return c.sendAlert(alertNoRenegotiation) - } - c.hand.Write(data) - } - - if b != nil { - c.in.freeBlock(b) - } - return c.error() -} - -// sendAlert sends a TLS alert message. -// c.out.Mutex <= L. -func (c *Conn) sendAlertLocked(err alert) error { - switch err { - case alertNoRenegotiation, alertCloseNotify: - c.tmp[0] = alertLevelWarning - default: - c.tmp[0] = alertLevelError - } - c.tmp[1] = byte(err) - c.writeRecord(recordTypeAlert, c.tmp[0:2]) - // closeNotify is a special case in that it isn't an error: - if err != alertCloseNotify { - return c.setError(&net.OpError{Op: "local error", Err: err}) - } - return nil -} - -// sendAlert sends a TLS alert message. -// L < c.out.Mutex. -func (c *Conn) sendAlert(err alert) error { - c.out.Lock() - defer c.out.Unlock() - return c.sendAlertLocked(err) -} - -// writeRecord writes a TLS record with the given type and payload -// to the connection and updates the record layer state. -// c.out.Mutex <= L. -func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) { - b := c.out.newBlock() - for len(data) > 0 { - m := len(data) - if m > maxPlaintext { - m = maxPlaintext - } - explicitIVLen := 0 - explicitIVIsSeq := false - - var cbc cbcMode - if c.out.version >= VersionTLS11 { - var ok bool - if cbc, ok = c.out.cipher.(cbcMode); ok { - explicitIVLen = cbc.BlockSize() - } - } - if explicitIVLen == 0 { - if _, ok := c.out.cipher.(cipher.AEAD); ok { - explicitIVLen = 8 - // The AES-GCM construction in TLS has an - // explicit nonce so that the nonce can be - // random. However, the nonce is only 8 bytes - // which is too small for a secure, random - // nonce. Therefore we use the sequence number - // as the nonce. - explicitIVIsSeq = true - } - } - b.resize(recordHeaderLen + explicitIVLen + m) - b.data[0] = byte(typ) - vers := c.vers - if vers == 0 { - // Some TLS servers fail if the record version is - // greater than TLS 1.0 for the initial ClientHello. - vers = VersionTLS10 - } - b.data[1] = byte(vers >> 8) - b.data[2] = byte(vers) - b.data[3] = byte(m >> 8) - b.data[4] = byte(m) - if explicitIVLen > 0 { - explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] - if explicitIVIsSeq { - copy(explicitIV, c.out.seq[:]) - } else { - if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil { - break - } - } - } - copy(b.data[recordHeaderLen+explicitIVLen:], data) - c.out.encrypt(b, explicitIVLen) - _, err = c.conn.Write(b.data) - if err != nil { - break - } - n += m - data = data[m:] - } - c.out.freeBlock(b) - - if typ == recordTypeChangeCipherSpec { - err = c.out.changeCipherSpec() - if err != nil { - // Cannot call sendAlert directly, - // because we already hold c.out.Mutex. - c.tmp[0] = alertLevelError - c.tmp[1] = byte(err.(alert)) - c.writeRecord(recordTypeAlert, c.tmp[0:2]) - return n, c.setError(&net.OpError{Op: "local error", Err: err}) - } - } - return -} - -// readHandshake reads the next handshake message from -// the record layer. -// c.in.Mutex < L; c.out.Mutex < L. -func (c *Conn) readHandshake() (interface{}, error) { - for c.hand.Len() < 4 { - if err := c.error(); err != nil { - return nil, err - } - if err := c.readRecord(recordTypeHandshake); err != nil { - return nil, err - } - } - - data := c.hand.Bytes() - n := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if n > maxHandshake { - c.sendAlert(alertInternalError) - return nil, c.error() - } - for c.hand.Len() < 4+n { - if err := c.error(); err != nil { - return nil, err - } - if err := c.readRecord(recordTypeHandshake); err != nil { - return nil, err - } - } - data = c.hand.Next(4 + n) - var m handshakeMessage - switch data[0] { - case typeHelloRequest: - m = new(helloRequestMsg) - case typeClientHello: - m = new(clientHelloMsg) - case typeServerHello: - m = new(serverHelloMsg) - case typeCertificate: - m = new(certificateMsg) - case typeCertificateRequest: - m = &certificateRequestMsg{ - hasSignatureAndHash: c.vers >= VersionTLS12, - } - case typeCertificateStatus: - m = new(certificateStatusMsg) - case typeServerKeyExchange: - m = new(serverKeyExchangeMsg) - case typeServerHelloDone: - m = new(serverHelloDoneMsg) - case typeClientKeyExchange: - m = new(clientKeyExchangeMsg) - case typeCertificateVerify: - m = &certificateVerifyMsg{ - hasSignatureAndHash: c.vers >= VersionTLS12, - } - case typeNextProtocol: - m = new(nextProtoMsg) - case typeFinished: - m = new(finishedMsg) - default: - c.sendAlert(alertUnexpectedMessage) - return nil, alertUnexpectedMessage - } - - // The handshake message unmarshallers - // expect to be able to keep references to data, - // so pass in a fresh copy that won't be overwritten. - data = append([]byte(nil), data...) - - if !m.unmarshal(data) { - c.sendAlert(alertUnexpectedMessage) - return nil, alertUnexpectedMessage - } - return m, nil -} - -// Write writes data to the connection. -func (c *Conn) Write(b []byte) (int, error) { - if err := c.error(); err != nil { - return 0, err - } - - if err := c.Handshake(); err != nil { - return 0, c.setError(err) - } - - c.out.Lock() - defer c.out.Unlock() - - if !c.handshakeComplete { - return 0, alertInternalError - } - - // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext - // attack when using block mode ciphers due to predictable IVs. - // This can be prevented by splitting each Application Data - // record into two records, effectively randomizing the IV. - // - // http://www.openssl.org/~bodo/tls-cbc.txt - // https://bugzilla.mozilla.org/show_bug.cgi?id=665814 - // http://www.imperialviolet.org/2012/01/15/beastfollowup.html - - var m int - if len(b) > 1 && c.vers <= VersionTLS10 { - if _, ok := c.out.cipher.(cipher.BlockMode); ok { - n, err := c.writeRecord(recordTypeApplicationData, b[:1]) - if err != nil { - return n, c.setError(err) - } - m, b = 1, b[1:] - } - } - - n, err := c.writeRecord(recordTypeApplicationData, b) - return n + m, c.setError(err) -} - -func (c *Conn) handleRenegotiation() error { - c.handshakeComplete = false - if !c.isClient { - panic("renegotiation should only happen for a client") - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - _, ok := msg.(*helloRequestMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return alertUnexpectedMessage - } - - return c.Handshake() -} - -// Read can be made to time out and return a net.Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetReadDeadline. -func (c *Conn) Read(b []byte) (n int, err error) { - if err = c.Handshake(); err != nil { - return - } - - c.in.Lock() - defer c.in.Unlock() - - // Some OpenSSL servers send empty records in order to randomize the - // CBC IV. So this loop ignores a limited number of empty records. - const maxConsecutiveEmptyRecords = 100 - for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ { - for c.input == nil && c.error() == nil { - if err := c.readRecord(recordTypeApplicationData); err != nil { - // Soft error, like EAGAIN - return 0, err - } - if c.hand.Len() > 0 { - // We received handshake bytes, indicating the start of - // a renegotiation. - if err := c.handleRenegotiation(); err != nil { - return 0, err - } - continue - } - } - if err := c.error(); err != nil { - return 0, err - } - - n, err = c.input.Read(b) - if c.input.off >= len(c.input.data) { - c.in.freeBlock(c.input) - c.input = nil - } - - if n != 0 || err != nil { - return n, err - } - } - - return 0, io.ErrNoProgress -} - -// Close closes the connection. -func (c *Conn) Close() error { - var alertErr error - - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if c.handshakeComplete { - alertErr = c.sendAlert(alertCloseNotify) - } - - if err := c.conn.Close(); err != nil { - return err - } - return alertErr -} - -// Handshake runs the client or server handshake -// protocol if it has not yet been run. -// Most uses of this package need not call Handshake -// explicitly: the first Read or Write will call it automatically. -func (c *Conn) Handshake() error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if err := c.error(); err != nil { - return err - } - if c.handshakeComplete { - return nil - } - if c.isClient { - return c.clientHandshake() - } - return c.serverHandshake() -} - -// ConnectionState returns basic TLS details about the connection. -func (c *Conn) ConnectionState() ConnectionState { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - var state ConnectionState - state.HandshakeComplete = c.handshakeComplete - if c.handshakeComplete { - state.NegotiatedProtocol = c.clientProtocol - state.DidResume = c.didResume - state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback - state.CipherSuite = c.cipherSuite - state.PeerCertificates = c.peerCertificates - state.VerifiedChains = c.verifiedChains - state.ServerName = c.serverName - } - - return state -} - -// OCSPResponse returns the stapled OCSP response from the TLS server, if -// any. (Only valid for client connections.) -func (c *Conn) OCSPResponse() []byte { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - return c.ocspResponse -} - -// VerifyHostname checks that the peer certificate chain is valid for -// connecting to host. If so, it returns nil; if not, it returns an error -// describing the problem. -func (c *Conn) VerifyHostname(host string) error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if !c.isClient { - return errors.New("VerifyHostname called on TLS server connection") - } - if !c.handshakeComplete { - return errors.New("TLS handshake has not yet been performed") - } - return c.peerCertificates[0].VerifyHostname(host) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/conn_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/conn_test.go deleted file mode 100644 index 5c555147ca..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/conn_test.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "testing" -) - -func TestRoundUp(t *testing.T) { - if roundUp(0, 16) != 0 || - roundUp(1, 16) != 16 || - roundUp(15, 16) != 16 || - roundUp(16, 16) != 16 || - roundUp(17, 16) != 32 { - t.Error("roundUp broken") - } -} - -var paddingTests = []struct { - in []byte - good bool - expectedLen int -}{ - {[]byte{1, 2, 3, 4, 0}, true, 4}, - {[]byte{1, 2, 3, 4, 0, 1}, false, 0}, - {[]byte{1, 2, 3, 4, 99, 99}, false, 0}, - {[]byte{1, 2, 3, 4, 1, 1}, true, 4}, - {[]byte{1, 2, 3, 2, 2, 2}, true, 3}, - {[]byte{1, 2, 3, 3, 3, 3}, true, 2}, - {[]byte{1, 2, 3, 4, 3, 3}, false, 0}, - {[]byte{1, 4, 4, 4, 4, 4}, true, 1}, - {[]byte{5, 5, 5, 5, 5, 5}, true, 0}, - {[]byte{6, 6, 6, 6, 6, 6}, false, 0}, -} - -func TestRemovePadding(t *testing.T) { - for i, test := range paddingTests { - payload, good := removePadding(test.in) - expectedGood := byte(255) - if !test.good { - expectedGood = 0 - } - if good != expectedGood { - t.Errorf("#%d: wrong validity, want:%d got:%d", i, expectedGood, good) - } - if good == 255 && len(payload) != test.expectedLen { - t.Errorf("#%d: got %d, want %d", i, len(payload), test.expectedLen) - } - } -} - -var certExampleCom = `308201403081eda003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313138353835325a170d3132303933303138353835325a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31a301830160603551d11040f300d820b6578616d706c652e636f6d300b06092a864886f70d0101050341001a0b419d2c74474c6450654e5f10b32bf426ffdf55cad1c52602e7a9151513a3424c70f5960dcd682db0c33769cc1daa3fcdd3db10809d2392ed4a1bf50ced18` - -var certWildcardExampleCom = `308201423081efa003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303034365a170d3132303933303139303034365a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31c301a30180603551d110411300f820d2a2e6578616d706c652e636f6d300b06092a864886f70d0101050341001676f0c9e7c33c1b656ed5a6476c4e2ee9ec8e62df7407accb1875272b2edd0a22096cb2c22598d11604104d604f810eb4b5987ca6bb319c7e6ce48725c54059` - -var certFooExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303131345a170d3132303933303139303131345a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104133011820f666f6f2e6578616d706c652e636f6d300b06092a864886f70d010105034100646a2a51f2aa2477add854b462cf5207ba16d3213ffb5d3d0eed473fbf09935019192d1d5b8ca6a2407b424cf04d97c4cd9197c83ecf81f0eab9464a1109d09f` - -var certDoubleWildcardExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303134315a170d3132303933303139303134315a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104133011820f2a2e2a2e6578616d706c652e636f6d300b06092a864886f70d0101050341001c3de267975f56ef57771c6218ef95ecc65102e57bd1defe6f7efea90d9b26cf40de5bd7ad75e46201c7f2a92aaa3e907451e9409f65e28ddb6db80d726290f6` - -func TestCertificateSelection(t *testing.T) { - config := Config{ - Certificates: []Certificate{ - { - Certificate: [][]byte{fromHex(certExampleCom)}, - }, - { - Certificate: [][]byte{fromHex(certWildcardExampleCom)}, - }, - { - Certificate: [][]byte{fromHex(certFooExampleCom)}, - }, - { - Certificate: [][]byte{fromHex(certDoubleWildcardExampleCom)}, - }, - }, - } - - config.BuildNameToCertificate() - - pointerToIndex := func(c *Certificate) int { - for i := range config.Certificates { - if c == &config.Certificates[i] { - return i - } - } - return -1 - } - - if n := pointerToIndex(config.getCertificateForName("example.com")); n != 0 { - t.Errorf("example.com returned certificate %d, not 0", n) - } - if n := pointerToIndex(config.getCertificateForName("bar.example.com")); n != 1 { - t.Errorf("bar.example.com returned certificate %d, not 1", n) - } - if n := pointerToIndex(config.getCertificateForName("foo.example.com")); n != 2 { - t.Errorf("foo.example.com returned certificate %d, not 2", n) - } - if n := pointerToIndex(config.getCertificateForName("foo.bar.example.com")); n != 3 { - t.Errorf("foo.bar.example.com returned certificate %d, not 3", n) - } - if n := pointerToIndex(config.getCertificateForName("foo.bar.baz.example.com")); n != 0 { - t.Errorf("foo.bar.baz.example.com returned certificate %d, not 0", n) - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/generate_cert.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/generate_cert.go deleted file mode 100644 index b417ea4640..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/generate_cert.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -// Generate a self-signed X.509 certificate for a TLS server. Outputs to -// 'cert.pem' and 'key.pem' and will overwrite existing files. - -package main - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "flag" - "fmt" - "log" - "math/big" - "net" - "os" - "strings" - "time" -) - -var ( - host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") - validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") - validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") - isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") - rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate") -) - -func main() { - flag.Parse() - - if len(*host) == 0 { - log.Fatalf("Missing required --host parameter") - } - - priv, err := rsa.GenerateKey(rand.Reader, *rsaBits) - if err != nil { - log.Fatalf("failed to generate private key: %s", err) - return - } - - var notBefore time.Time - if len(*validFrom) == 0 { - notBefore = time.Now() - } else { - notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) - os.Exit(1) - } - } - - notAfter := notBefore.Add(*validFor) - - // end of ASN.1 time - endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) - if notAfter.After(endOfTime) { - notAfter = endOfTime - } - - template := x509.Certificate{ - SerialNumber: new(big.Int).SetInt64(0), - Subject: pkix.Name{ - Organization: []string{"Acme Co"}, - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - } - - hosts := strings.Split(*host, ",") - for _, h := range hosts { - if ip := net.ParseIP(h); ip != nil { - template.IPAddresses = append(template.IPAddresses, ip) - } else { - template.DNSNames = append(template.DNSNames, h) - } - } - - if *isCA { - template.IsCA = true - template.KeyUsage |= x509.KeyUsageCertSign - } - - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) - if err != nil { - log.Fatalf("Failed to create certificate: %s", err) - return - } - - certOut, err := os.Create("cert.pem") - if err != nil { - log.Fatalf("failed to open cert.pem for writing: %s", err) - return - } - pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) - certOut.Close() - log.Print("written cert.pem\n") - - keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - log.Print("failed to open key.pem for writing:", err) - return - } - pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) - keyOut.Close() - log.Print("written key.pem\n") -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_client.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_client.go deleted file mode 100644 index 85e4adefcb..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_client.go +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "bytes" - "crypto/ecdsa" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "encoding/asn1" - "errors" - "io" - "strconv" -) - -func (c *Conn) clientHandshake() error { - if c.config == nil { - c.config = defaultConfig() - } - - hello := &clientHelloMsg{ - vers: c.config.maxVersion(), - compressionMethods: []uint8{compressionNone}, - random: make([]byte, 32), - ocspStapling: true, - serverName: c.config.ServerName, - supportedCurves: []uint16{curveP256, curveP384, curveP521}, - supportedPoints: []uint8{pointFormatUncompressed}, - nextProtoNeg: len(c.config.NextProtos) > 0, - } - - possibleCipherSuites := c.config.cipherSuites() - hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) - -NextCipherSuite: - for _, suiteId := range possibleCipherSuites { - for _, suite := range cipherSuites { - if suite.id != suiteId { - continue - } - // Don't advertise TLS 1.2-only cipher suites unless - // we're attempting TLS 1.2. - if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { - continue - } - hello.cipherSuites = append(hello.cipherSuites, suiteId) - continue NextCipherSuite - } - } - - t := uint32(c.config.time().Unix()) - hello.random[0] = byte(t >> 24) - hello.random[1] = byte(t >> 16) - hello.random[2] = byte(t >> 8) - hello.random[3] = byte(t) - _, err := io.ReadFull(c.config.rand(), hello.random[4:]) - if err != nil { - c.sendAlert(alertInternalError) - return errors.New("short read from Rand") - } - - if hello.vers >= VersionTLS12 { - hello.signatureAndHashes = supportedSKXSignatureAlgorithms - } - - c.writeRecord(recordTypeHandshake, hello.marshal()) - - msg, err := c.readHandshake() - if err != nil { - return err - } - serverHello, ok := msg.(*serverHelloMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - vers, ok := c.config.mutualVersion(serverHello.vers) - if !ok || vers < VersionTLS10 { - // TLS 1.0 is the minimum version supported as a client. - return c.sendAlert(alertProtocolVersion) - } - c.vers = vers - c.haveVers = true - - finishedHash := newFinishedHash(c.vers) - finishedHash.Write(hello.marshal()) - finishedHash.Write(serverHello.marshal()) - - if serverHello.compressionMethod != compressionNone { - return c.sendAlert(alertUnexpectedMessage) - } - - if !hello.nextProtoNeg && serverHello.nextProtoNeg { - c.sendAlert(alertHandshakeFailure) - return errors.New("server advertised unrequested NPN") - } - - suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite) - if suite == nil { - return c.sendAlert(alertHandshakeFailure) - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - certMsg, ok := msg.(*certificateMsg) - if !ok || len(certMsg.certificates) == 0 { - return c.sendAlert(alertUnexpectedMessage) - } - finishedHash.Write(certMsg.marshal()) - - certs := make([]*x509.Certificate, len(certMsg.certificates)) - for i, asn1Data := range certMsg.certificates { - cert, err := x509.ParseCertificate(asn1Data) - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("failed to parse certificate from server: " + err.Error()) - } - certs[i] = cert - } - - if !c.config.InsecureSkipVerify { - opts := x509.VerifyOptions{ - Roots: c.config.RootCAs, - CurrentTime: c.config.time(), - DNSName: c.config.ServerName, - Intermediates: x509.NewCertPool(), - } - - for i, cert := range certs { - if i == 0 { - continue - } - opts.Intermediates.AddCert(cert) - } - c.verifiedChains, err = certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - switch certs[0].PublicKey.(type) { - case *rsa.PublicKey, *ecdsa.PublicKey: - break - default: - return c.sendAlert(alertUnsupportedCertificate) - } - - c.peerCertificates = certs - - if serverHello.ocspStapling { - msg, err = c.readHandshake() - if err != nil { - return err - } - cs, ok := msg.(*certificateStatusMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - finishedHash.Write(cs.marshal()) - - if cs.statusType == statusTypeOCSP { - c.ocspResponse = cs.response - } - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - - keyAgreement := suite.ka(c.vers) - - skx, ok := msg.(*serverKeyExchangeMsg) - if ok { - finishedHash.Write(skx.marshal()) - err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx) - if err != nil { - c.sendAlert(alertUnexpectedMessage) - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - var chainToSend *Certificate - var certRequested bool - certReq, ok := msg.(*certificateRequestMsg) - if ok { - certRequested = true - - // RFC 4346 on the certificateAuthorities field: - // A list of the distinguished names of acceptable certificate - // authorities. These distinguished names may specify a desired - // distinguished name for a root CA or for a subordinate CA; - // thus, this message can be used to describe both known roots - // and a desired authorization space. If the - // certificate_authorities list is empty then the client MAY - // send any certificate of the appropriate - // ClientCertificateType, unless there is some external - // arrangement to the contrary. - - finishedHash.Write(certReq.marshal()) - - var rsaAvail, ecdsaAvail bool - for _, certType := range certReq.certificateTypes { - switch certType { - case certTypeRSASign: - rsaAvail = true - case certTypeECDSASign: - ecdsaAvail = true - } - } - - // We need to search our list of client certs for one - // where SignatureAlgorithm is RSA and the Issuer is in - // certReq.certificateAuthorities - findCert: - for i, chain := range c.config.Certificates { - if !rsaAvail && !ecdsaAvail { - continue - } - - for j, cert := range chain.Certificate { - x509Cert := chain.Leaf - // parse the certificate if this isn't the leaf - // node, or if chain.Leaf was nil - if j != 0 || x509Cert == nil { - if x509Cert, err = x509.ParseCertificate(cert); err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) - } - } - - switch { - case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA: - case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA: - default: - continue findCert - } - - if len(certReq.certificateAuthorities) == 0 { - // they gave us an empty list, so just take the - // first RSA cert from c.config.Certificates - chainToSend = &chain - break findCert - } - - for _, ca := range certReq.certificateAuthorities { - if bytes.Equal(x509Cert.RawIssuer, ca) { - chainToSend = &chain - break findCert - } - } - } - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - shd, ok := msg.(*serverHelloDoneMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - finishedHash.Write(shd.marshal()) - - // If the server requested a certificate then we have to send a - // Certificate message, even if it's empty because we don't have a - // certificate to send. - if certRequested { - certMsg = new(certificateMsg) - if chainToSend != nil { - certMsg.certificates = chainToSend.Certificate - } - finishedHash.Write(certMsg.marshal()) - c.writeRecord(recordTypeHandshake, certMsg.marshal()) - } - - preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0]) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - if ckx != nil { - finishedHash.Write(ckx.marshal()) - c.writeRecord(recordTypeHandshake, ckx.marshal()) - } - - if chainToSend != nil { - var signed []byte - certVerify := &certificateVerifyMsg{ - hasSignatureAndHash: c.vers >= VersionTLS12, - } - - switch key := c.config.Certificates[0].PrivateKey.(type) { - case *ecdsa.PrivateKey: - digest, _, hashId := finishedHash.hashForClientCertificate(signatureECDSA) - r, s, err := ecdsa.Sign(c.config.rand(), key, digest) - if err == nil { - signed, err = asn1.Marshal(ecdsaSignature{r, s}) - } - certVerify.signatureAndHash.signature = signatureECDSA - certVerify.signatureAndHash.hash = hashId - case *rsa.PrivateKey: - digest, hashFunc, hashId := finishedHash.hashForClientCertificate(signatureRSA) - signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest) - certVerify.signatureAndHash.signature = signatureRSA - certVerify.signatureAndHash.hash = hashId - default: - err = errors.New("unknown private key type") - } - if err != nil { - return c.sendAlert(alertInternalError) - } - certVerify.signature = signed - - finishedHash.Write(certVerify.marshal()) - c.writeRecord(recordTypeHandshake, certVerify.marshal()) - } - - masterSecret := masterFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random) - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen) - - var clientCipher interface{} - var clientHash macFunction - if suite.cipher != nil { - clientCipher = suite.cipher(clientKey, clientIV, false /* not for reading */) - clientHash = suite.mac(c.vers, clientMAC) - } else { - clientCipher = suite.aead(clientKey, clientIV) - } - c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) - c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - - if serverHello.nextProtoNeg { - nextProto := new(nextProtoMsg) - proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos) - nextProto.proto = proto - c.clientProtocol = proto - c.clientProtocolFallback = fallback - - finishedHash.Write(nextProto.marshal()) - c.writeRecord(recordTypeHandshake, nextProto.marshal()) - } - - finished := new(finishedMsg) - finished.verifyData = finishedHash.clientSum(masterSecret) - finishedHash.Write(finished.marshal()) - c.writeRecord(recordTypeHandshake, finished.marshal()) - - var serverCipher interface{} - var serverHash macFunction - if suite.cipher != nil { - serverCipher = suite.cipher(serverKey, serverIV, true /* for reading */) - serverHash = suite.mac(c.vers, serverMAC) - } else { - serverCipher = suite.aead(serverKey, serverIV) - } - c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) - c.readRecord(recordTypeChangeCipherSpec) - if err := c.error(); err != nil { - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - serverFinished, ok := msg.(*finishedMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - verify := finishedHash.serverSum(masterSecret) - if len(verify) != len(serverFinished.verifyData) || - subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { - return c.sendAlert(alertHandshakeFailure) - } - - c.handshakeComplete = true - c.cipherSuite = suite.id - return nil -} - -// mutualProtocol finds the mutual Next Protocol Negotiation protocol given the -// set of client and server supported protocols. The set of client supported -// protocols must not be empty. It returns the resulting protocol and flag -// indicating if the fallback case was reached. -func mutualProtocol(clientProtos, serverProtos []string) (string, bool) { - for _, s := range serverProtos { - for _, c := range clientProtos { - if s == c { - return s, false - } - } - } - - return clientProtos[0], true -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_client_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_client_test.go deleted file mode 100644 index 6c564001b0..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_client_test.go +++ /dev/null @@ -1,3050 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "bytes" - "flag" - "io" - "net" - "os" - "testing" -) - -func testClientScript(t *testing.T, name string, clientScript [][]byte, config *Config) { - c, s := net.Pipe() - cli := Client(c, config) - go func() { - cli.Write([]byte("hello\n")) - cli.Close() - c.Close() - }() - - defer c.Close() - for i, b := range clientScript { - if i%2 == 1 { - s.Write(b) - continue - } - bb := make([]byte, len(b)) - _, err := io.ReadFull(s, bb) - if err != nil { - t.Fatalf("%s #%d: %s", name, i, err) - } - if !bytes.Equal(b, bb) { - t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b) - } - } -} - -func TestHandshakeClientRSARC4(t *testing.T) { - var config = *testConfig - config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA} - testClientScript(t, "RSA-RC4", rsaRC4ClientScript, &config) -} - -func TestHandshakeClientECDHERSAAES(t *testing.T) { - var config = *testConfig - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} - testClientScript(t, "ECDHE-RSA-AES", ecdheRSAAESClientScript, &config) -} - -func TestHandshakeClientECDHECDSAAES(t *testing.T) { - var config = *testConfig - config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA} - config.Certificates = nil - config.BuildNameToCertificate() - testClientScript(t, "ECDHE-ECDSA-AES", ecdheECDSAAESClientScript, &config) -} - -func TestLongClientCerticiateChain(t *testing.T) { - config := *testConfig - cert, _ := X509KeyPair(testClientChainCertificate, testClientChainCertificate) - config.Certificates = []Certificate{cert} - testClientScript(t, "Long client certificate chains", clientChainCertificateScript, &config) -} - -func TestHandshakeClientTLS11(t *testing.T) { - var config = *testConfig - config.MaxVersion = VersionTLS11 - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} - testClientScript(t, "TLS11-ECDHE-AES", tls11ECDHEAESClientScript, &config) -} - -func TestHandshakeClientTLS12(t *testing.T) { - config := *testConfig - config.MaxVersion = VersionTLS12 - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} - cert, _ := X509KeyPair(testClientChainCertificate, testClientChainCertificate) - config.Certificates = []Certificate{cert} - testClientScript(t, "TLS12", clientTLS12Script, &config) -} - -func TestHandshakeClientTLS12ClientCert(t *testing.T) { - config := *testConfig - config.MaxVersion = VersionTLS12 - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256} - cert, _ := X509KeyPair(testClientChainCertificate, testClientChainCertificate) - config.Certificates = []Certificate{cert} - testClientScript(t, "TLS12ClientCert", clientTLS12ClientCertScript, &config) -} - -var connect = flag.Bool("connect", false, "connect to a TLS server on :10443") - -func TestRunClient(t *testing.T) { - if !*connect { - return - } - - tcpConn, err := net.Dial("tcp", "127.0.0.1:10443") - if err != nil { - t.Fatal(err) - } - - record := &recordingConn{ - Conn: tcpConn, - } - - config := GetTestConfig() - conn := Client(record, config) - if err := conn.Handshake(); err != nil { - t.Fatalf("error from TLS handshake: %s", err) - } - - conn.Write([]byte("hello\n")) - conn.Close() - - record.WriteTo(os.Stdout) -} - -func TestEmptyRecords(t *testing.T) { - // emptyRecordScript contains a TLS connection with an empty record as - // the first application data from the server. This test ensures that - // the empty record doesn't cause (0, nil) to be returned from - // Conn.Read. - config := *testConfig - config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA} - - c, s := net.Pipe() - cli := Client(c, &config) - go func() { - buf := make([]byte, 1024) - n, err := cli.Read(buf) - defer c.Close() - defer cli.Close() - - if err != nil { - t.Fatalf("error reading from tls.Client: %s", err) - } - const expectedLength = 197 - if n != expectedLength { - t.Fatalf("incorrect length reading from tls.Client, got %d, want %d", n, expectedLength) - } - }() - - defer c.Close() - for i, b := range emptyRecordScript { - if i%2 == 1 { - s.Write(b) - continue - } - bb := make([]byte, len(b)) - _, err := io.ReadFull(s, bb) - if err != nil { - t.Fatalf("#%d: %s", i, err) - } - if !bytes.Equal(b, bb) { - t.Fatalf("#%d: mismatch on read: got:%x want:%x", i, bb, b) - } - } -} - -// Script of interaction with gnutls implementation. -// The values for this test are obtained by building and running in client mode: -// % go test -test.run "TestRunClient" -connect -// The recorded bytes are written to stdout. -// -// The server private key is: -// -----BEGIN RSA PRIVATE KEY----- -// MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD -// TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu -// OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj -// gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz -// rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b -// PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA -// vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU= -// -----END RSA PRIVATE KEY----- -// -// and certificate is: -// -----BEGIN CERTIFICATE----- -// MIICKzCCAdWgAwIBAgIJALE1E2URIMWSMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -// BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -// aWRnaXRzIFB0eSBMdGQwHhcNMTIwNDA2MTcxMDEzWhcNMTUwNDA2MTcxMDEzWjBF -// MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 -// ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+z -// w4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/ -// 7tdkuD8Ey2//Kv7+ue0CAwEAAaOBpzCBpDAdBgNVHQ4EFgQUeKaXmmO1xaGlM7oi -// fCNuWxt6zCswdQYDVR0jBG4wbIAUeKaXmmO1xaGlM7oifCNuWxt6zCuhSaRHMEUx -// CzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRl -// cm5ldCBXaWRnaXRzIFB0eSBMdGSCCQCxNRNlESDFkjAMBgNVHRMEBTADAQH/MA0G -// CSqGSIb3DQEBBQUAA0EAhTZAc8G7GtrUWZ8tonAxRnTsg26oyDxRrzms7EC86CJG -// HZnWRiok1IsFCEv7NRFukrt3uuQSu/TIXpyBqJdgTA== -// -----END CERTIFICATE----- -var rsaRC4ClientScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - }, - - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x4d, 0x0a, 0x56, 0x16, 0xb5, - 0x91, 0xd1, 0xcb, 0x80, 0x4d, 0xc7, 0x46, 0xf3, - 0x37, 0x0c, 0xef, 0xea, 0x64, 0x11, 0x14, 0x56, - 0x97, 0x9b, 0xc5, 0x67, 0x08, 0xb7, 0x13, 0xea, - 0xf8, 0xc9, 0xb3, 0x20, 0xe2, 0xfc, 0x41, 0xf6, - 0x96, 0x90, 0x9d, 0x43, 0x9b, 0xe9, 0x6e, 0xf8, - 0x41, 0x16, 0xcc, 0xf3, 0xc7, 0xde, 0xda, 0x5a, - 0xa1, 0x33, 0x69, 0xe2, 0xde, 0x5b, 0xaf, 0x2a, - 0x92, 0xe7, 0xd4, 0xa0, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x01, 0x01, 0xf7, 0x0b, 0x00, 0x01, 0xf3, - 0x00, 0x01, 0xf0, 0x00, 0x01, 0xed, 0x30, 0x82, - 0x01, 0xe9, 0x30, 0x82, 0x01, 0x52, 0x02, 0x01, - 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, - 0x30, 0x5b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0a, 0x51, 0x75, 0x65, 0x65, 0x6e, 0x73, - 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x1a, 0x30, 0x18, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, - 0x72, 0x79, 0x70, 0x74, 0x53, 0x6f, 0x66, 0x74, - 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20, - 0x43, 0x41, 0x20, 0x28, 0x31, 0x30, 0x32, 0x34, - 0x20, 0x62, 0x69, 0x74, 0x29, 0x30, 0x1e, 0x17, - 0x0d, 0x30, 0x30, 0x31, 0x30, 0x31, 0x36, 0x32, - 0x32, 0x33, 0x31, 0x30, 0x33, 0x5a, 0x17, 0x0d, - 0x30, 0x33, 0x30, 0x31, 0x31, 0x34, 0x32, 0x32, - 0x33, 0x31, 0x30, 0x33, 0x5a, 0x30, 0x63, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x51, - 0x75, 0x65, 0x65, 0x6e, 0x73, 0x6c, 0x61, 0x6e, - 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x11, 0x43, 0x72, 0x79, 0x70, - 0x74, 0x53, 0x6f, 0x66, 0x74, 0x20, 0x50, 0x74, - 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x23, 0x30, - 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x20, 0x63, 0x65, 0x72, 0x74, - 0x20, 0x28, 0x35, 0x31, 0x32, 0x20, 0x62, 0x69, - 0x74, 0x29, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, - 0x02, 0x41, 0x00, 0x9f, 0xb3, 0xc3, 0x84, 0x27, - 0x95, 0xff, 0x12, 0x31, 0x52, 0x0f, 0x15, 0xef, - 0x46, 0x11, 0xc4, 0xad, 0x80, 0xe6, 0x36, 0x5b, - 0x0f, 0xdd, 0x80, 0xd7, 0x61, 0x8d, 0xe0, 0xfc, - 0x72, 0x45, 0x09, 0x34, 0xfe, 0x55, 0x66, 0x45, - 0x43, 0x4c, 0x68, 0x97, 0x6a, 0xfe, 0xa8, 0xa0, - 0xa5, 0xdf, 0x5f, 0x78, 0xff, 0xee, 0xd7, 0x64, - 0xb8, 0x3f, 0x04, 0xcb, 0x6f, 0xff, 0x2a, 0xfe, - 0xfe, 0xb9, 0xed, 0x02, 0x03, 0x01, 0x00, 0x01, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, - 0x81, 0x81, 0x00, 0x93, 0xd2, 0x0a, 0xc5, 0x41, - 0xe6, 0x5a, 0xa9, 0x86, 0xf9, 0x11, 0x87, 0xe4, - 0xdb, 0x45, 0xe2, 0xc5, 0x95, 0x78, 0x1a, 0x6c, - 0x80, 0x6d, 0x73, 0x1f, 0xb4, 0x6d, 0x44, 0xa3, - 0xba, 0x86, 0x88, 0xc8, 0x58, 0xcd, 0x1c, 0x06, - 0x35, 0x6c, 0x44, 0x62, 0x88, 0xdf, 0xe4, 0xf6, - 0x64, 0x61, 0x95, 0xef, 0x4a, 0xa6, 0x7f, 0x65, - 0x71, 0xd7, 0x6b, 0x88, 0x39, 0xf6, 0x32, 0xbf, - 0xac, 0x93, 0x67, 0x69, 0x51, 0x8c, 0x93, 0xec, - 0x48, 0x5f, 0xc9, 0xb1, 0x42, 0xf9, 0x55, 0xd2, - 0x7e, 0x4e, 0xf4, 0xf2, 0x21, 0x6b, 0x90, 0x57, - 0xe6, 0xd7, 0x99, 0x9e, 0x41, 0xca, 0x80, 0xbf, - 0x1a, 0x28, 0xa2, 0xca, 0x5b, 0x50, 0x4a, 0xed, - 0x84, 0xe7, 0x82, 0xc7, 0xd2, 0xcf, 0x36, 0x9e, - 0x6a, 0x67, 0xb9, 0x88, 0xa7, 0xf3, 0x8a, 0xd0, - 0x04, 0xf8, 0xe8, 0xc6, 0x17, 0xe3, 0xc5, 0x29, - 0xbc, 0x17, 0xf1, 0x16, 0x03, 0x01, 0x00, 0x04, - 0x0e, 0x00, 0x00, 0x00, - }, - - { - 0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00, - 0x42, 0x00, 0x40, 0x87, 0xa1, 0x1f, 0x14, 0xe1, - 0xfb, 0x91, 0xac, 0x58, 0x2e, 0xf3, 0x71, 0xce, - 0x01, 0x85, 0x2c, 0xc7, 0xfe, 0x84, 0x87, 0x82, - 0xb7, 0x57, 0xdb, 0x37, 0x4d, 0x46, 0x83, 0x67, - 0x52, 0x82, 0x51, 0x01, 0x95, 0x23, 0x68, 0x69, - 0x6b, 0xd0, 0xa7, 0xa7, 0xe5, 0x88, 0xd0, 0x47, - 0x71, 0xb8, 0xd2, 0x03, 0x05, 0x25, 0x56, 0x5c, - 0x10, 0x08, 0xc6, 0x9b, 0xd4, 0x67, 0xcd, 0x28, - 0xbe, 0x9c, 0x48, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xc1, 0xb8, - 0xd3, 0x7f, 0xc5, 0xc2, 0x5a, 0x1d, 0x6d, 0x5b, - 0x2d, 0x5c, 0x82, 0x87, 0xc2, 0x6f, 0x0d, 0x63, - 0x7b, 0x72, 0x2b, 0xda, 0x69, 0xc4, 0xfe, 0x3c, - 0x84, 0xa1, 0x5a, 0x62, 0x38, 0x37, 0xc6, 0x54, - 0x25, 0x2a, - }, - - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0xea, 0x88, 0x9c, 0x00, 0xf6, - 0x35, 0xb8, 0x42, 0x7f, 0x15, 0x17, 0x76, 0x5e, - 0x4b, 0x24, 0xcb, 0x7e, 0xa0, 0x7b, 0xc3, 0x70, - 0x52, 0x0a, 0x88, 0x2a, 0x7a, 0x45, 0x59, 0x90, - 0x59, 0xac, 0xc6, 0xb5, 0x56, 0x55, 0x96, - }, -} - -var ecdheRSAAESClientScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13, - 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x52, 0x02, 0x00, 0x00, - 0x4e, 0x03, 0x01, 0x50, 0xad, 0x72, 0xb1, 0x14, - 0x45, 0xce, 0x0a, 0x95, 0xf9, 0x63, 0xef, 0xa8, - 0xe5, 0x07, 0x34, 0x04, 0xe9, 0x08, 0x0f, 0x38, - 0xe4, 0x28, 0x27, 0x91, 0x07, 0x03, 0xe2, 0xfe, - 0xe3, 0x25, 0xf7, 0x20, 0x08, 0x42, 0xa2, 0x01, - 0x69, 0x53, 0xf0, 0xd9, 0x4c, 0xfa, 0x01, 0xa1, - 0xce, 0x4b, 0xf8, 0x28, 0x21, 0xad, 0x06, 0xbe, - 0xe0, 0x1b, 0x3b, 0xf7, 0xec, 0xd2, 0x52, 0xae, - 0x2a, 0x57, 0xb7, 0xa8, 0xc0, 0x13, 0x00, 0x00, - 0x06, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x16, - 0x03, 0x01, 0x02, 0x39, 0x0b, 0x00, 0x02, 0x35, - 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, 0x30, 0x82, - 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xb1, 0x35, - 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, 0x31, 0x37, - 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, 0x0d, 0x31, - 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, 0x37, 0x31, - 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, - 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, - 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, - 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, - 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, 0xc3, 0x84, - 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, 0x0f, 0x15, - 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, 0xe6, 0x36, - 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, 0x8d, 0xe0, - 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, 0x55, 0x66, - 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, 0xfe, 0xa8, - 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, 0xee, 0xd7, - 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, 0xff, 0x2a, - 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, 0xa4, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, - 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, 0x63, 0xb5, - 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, 0x7c, 0x23, - 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, 0x30, 0x75, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x6e, 0x30, - 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, 0x9a, 0x63, - 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, 0x7c, - 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, 0xa1, - 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, 0x35, 0x13, - 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, 0x0c, 0x06, - 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, 0x36, 0x40, - 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, 0x59, 0x9f, - 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, 0xec, 0x83, - 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, 0x39, 0xac, - 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, 0x1d, 0x99, - 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, 0x05, 0x08, - 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, 0xbb, 0x77, - 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, 0x5e, 0x9c, - 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, 0x03, 0x01, - 0x00, 0x8b, 0x0c, 0x00, 0x00, 0x87, 0x03, 0x00, - 0x17, 0x41, 0x04, 0x1c, 0x8f, 0x9c, 0x6d, 0xe7, - 0xab, 0x3e, 0xf8, 0x0a, 0x5d, 0xe1, 0x86, 0xb4, - 0xe2, 0x8e, 0xb2, 0x1c, 0x3b, 0xd9, 0xb6, 0x08, - 0x80, 0x58, 0x21, 0xe9, 0x0e, 0xc6, 0x66, 0x67, - 0x97, 0xcb, 0xb9, 0x92, 0x07, 0x00, 0xc4, 0xe5, - 0xec, 0x5f, 0xb4, 0xe2, 0x20, 0xa9, 0xc9, 0x62, - 0xd0, 0x98, 0xd5, 0xe3, 0x53, 0xff, 0xd0, 0x0a, - 0x6e, 0x29, 0x69, 0x39, 0x2a, 0x4b, 0x5c, 0xd8, - 0x6c, 0xf5, 0xfe, 0x00, 0x40, 0x35, 0xa7, 0x26, - 0x2e, 0xc2, 0x48, 0x93, 0x32, 0xf7, 0x7d, 0x0f, - 0x0d, 0x77, 0x56, 0x9a, 0x85, 0x0c, 0xa6, 0x74, - 0x06, 0xb8, 0x3d, 0x90, 0x56, 0x12, 0x63, 0xff, - 0x00, 0x5e, 0x0f, 0xf7, 0x24, 0xf7, 0xdb, 0x48, - 0x71, 0xe9, 0x2e, 0x03, 0xd3, 0xfa, 0x3a, 0xae, - 0xa0, 0xc1, 0x77, 0x3c, 0x4c, 0x59, 0xce, 0x33, - 0x1a, 0xd2, 0x47, 0x83, 0xfa, 0xea, 0xd8, 0x1e, - 0x06, 0xe7, 0x7d, 0xa0, 0x9b, 0x16, 0x03, 0x01, - 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00, - 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, - 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, - 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, - 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, - 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, - 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, - 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, - 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, - 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xd9, 0xa7, - 0x80, 0x56, 0x3f, 0xa3, 0x8f, 0x96, 0x72, 0x4e, - 0x4e, 0x6e, 0x23, 0x41, 0x8f, 0xda, 0x91, 0xb2, - 0x9e, 0x63, 0x23, 0x82, 0x64, 0xcd, 0x07, 0x24, - 0xd3, 0x40, 0x20, 0x22, 0x4c, 0xe3, 0xff, 0x38, - 0xbb, 0x43, 0x9d, 0x57, 0x11, 0xd5, 0x46, 0xa5, - 0x05, 0x29, 0x92, 0x02, 0xce, 0xdf, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x90, 0xe7, 0xba, 0x0e, 0xb1, 0xda, - 0x92, 0xb5, 0x77, 0x56, 0x38, 0xa6, 0x22, 0xc1, - 0x72, 0xeb, 0x8a, 0x68, 0x09, 0xb6, 0x74, 0xad, - 0xb3, 0x4a, 0xf2, 0xdd, 0x09, 0x9b, 0xc9, 0x4f, - 0x84, 0x73, 0x8b, 0xd6, 0x97, 0x50, 0x23, 0x1c, - 0xa0, 0xc2, 0x0c, 0x25, 0x18, 0xdd, 0x5e, 0x15, - 0x4d, 0xd9, 0xef, 0x4f, 0x6a, 0x43, 0x61, 0x9c, - 0x95, 0xde, 0x3c, 0x66, 0xc4, 0xc1, 0x33, 0x56, - 0xdd, 0x2f, 0x90, 0xaf, 0x68, 0x5c, 0x9c, 0xa4, - 0x90, 0x6d, 0xbf, 0x51, 0x1d, 0x68, 0xcb, 0x81, - 0x77, 0x52, 0xa0, 0x93, 0x2a, 0xf8, 0xc7, 0x61, - 0x87, 0x76, 0xca, 0x93, 0x9e, 0xd6, 0xee, 0x6f, - 0x3f, 0xeb, 0x7d, 0x06, 0xdd, 0x73, 0x4e, 0x27, - 0x16, 0x63, 0x92, 0xe4, 0xb2, 0x3f, 0x91, 0x23, - 0x21, 0x97, 0x90, 0xce, 0x53, 0xb8, 0xb0, 0x9d, - 0xbd, 0xbd, 0x33, 0x84, 0xad, 0x6b, 0x2e, 0x7b, - 0xf5, 0xeb, 0x1d, 0x64, 0x37, 0x2e, 0x29, 0x4e, - 0xb0, 0x93, 0xdb, 0x92, 0xc7, 0xaa, 0x94, 0xa5, - 0x3b, 0x64, 0xd0, - }, - { - 0x17, 0x03, 0x01, 0x00, 0x20, 0x11, 0xd8, 0x6b, - 0x3c, 0xf6, 0xbe, 0xf4, 0x54, 0x87, 0xec, 0x75, - 0x0c, 0x44, 0xdb, 0x92, 0xfc, 0xde, 0x7e, 0x0f, - 0x9f, 0x87, 0x87, 0x9c, 0x03, 0xd5, 0x07, 0x84, - 0xe0, 0x3a, 0xf8, 0xae, 0x14, 0x17, 0x03, 0x01, - 0x00, 0x20, 0xba, 0x54, 0xef, 0x5b, 0xce, 0xfd, - 0x47, 0x76, 0x6d, 0xa1, 0x8b, 0xfd, 0x48, 0xde, - 0x6e, 0x26, 0xc1, 0x0c, 0x9d, 0x54, 0xbf, 0x98, - 0xf6, 0x1c, 0x80, 0xb9, 0xca, 0x93, 0x81, 0x0a, - 0x2e, 0x06, 0x15, 0x03, 0x01, 0x00, 0x20, 0x93, - 0x3e, 0x38, 0x17, 0xc9, 0x0a, 0xc3, 0xea, 0xd3, - 0x92, 0x75, 0xa6, 0x53, 0x37, 0x4d, 0x74, 0x94, - 0xbe, 0x01, 0xdc, 0x5c, 0x5a, 0x0f, 0x09, 0xf6, - 0x57, 0x33, 0xc3, 0xbc, 0x3f, 0x7a, 0x4d, - }, -} - -var emptyRecordScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x35, - 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x51, 0x71, 0x8e, 0x03, 0x02, - 0xef, 0x09, 0xf2, 0x0e, 0xf5, 0x3b, 0x29, 0x9a, - 0xa8, 0x8b, 0x46, 0xa3, 0xd4, 0xb4, 0xc1, 0x14, - 0xc3, 0x19, 0x99, 0xba, 0x3d, 0x78, 0xcf, 0x50, - 0xd1, 0xe7, 0x26, 0x20, 0xa0, 0x37, 0x6d, 0xc9, - 0xae, 0x93, 0x33, 0x81, 0x20, 0xe3, 0xc1, 0x90, - 0x64, 0x6e, 0x67, 0x93, 0xdb, 0xb4, 0x04, 0x16, - 0xc4, 0x25, 0xdd, 0x10, 0x79, 0x3c, 0x18, 0x0a, - 0x7c, 0xfd, 0x28, 0x65, 0x00, 0x35, 0x00, 0x16, - 0x03, 0x01, 0x09, 0x9e, 0x0b, 0x00, 0x09, 0x9a, - 0x00, 0x09, 0x97, 0x00, 0x04, 0xea, 0x30, 0x82, - 0x04, 0xe6, 0x30, 0x82, 0x03, 0xce, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x11, 0x00, 0xff, 0xab, - 0x02, 0x93, 0xe0, 0x72, 0x99, 0x18, 0x6c, 0x9e, - 0x96, 0xb8, 0xb9, 0xf7, 0x47, 0xcb, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x41, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x47, - 0x41, 0x4e, 0x44, 0x49, 0x20, 0x53, 0x41, 0x53, - 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x15, 0x47, 0x61, 0x6e, 0x64, 0x69, - 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, - 0x64, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, - 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, - 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x31, - 0x34, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, - 0x30, 0x62, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x20, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x24, 0x30, - 0x22, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1b, - 0x47, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x53, 0x74, - 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x57, - 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x20, - 0x53, 0x53, 0x4c, 0x31, 0x17, 0x30, 0x15, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x14, 0x0e, 0x2a, 0x2e, - 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, - 0x02, 0x82, 0x01, 0x01, 0x00, 0xdc, 0xe3, 0xfd, - 0xce, 0xc1, 0x66, 0x62, 0x28, 0x8b, 0x99, 0x65, - 0x72, 0x52, 0x88, 0x93, 0x5b, 0x3f, 0x8d, 0xde, - 0x2b, 0xb0, 0xa0, 0xf4, 0xbd, 0xb4, 0x07, 0x5f, - 0x9e, 0x01, 0x47, 0x60, 0x57, 0x5f, 0xdf, 0xdc, - 0x63, 0x28, 0x1c, 0x1e, 0x5b, 0xc8, 0xe6, 0x29, - 0xdd, 0xeb, 0x26, 0x63, 0xd5, 0xbf, 0x83, 0xb2, - 0x2d, 0xcd, 0x2c, 0xa0, 0xb6, 0x91, 0xad, 0xaf, - 0x95, 0x21, 0x1d, 0x1f, 0x39, 0x8d, 0x3e, 0x17, - 0xd6, 0xbd, 0x99, 0xf5, 0x6c, 0xd4, 0xcb, 0x79, - 0x12, 0x3e, 0x11, 0xb9, 0x7e, 0x62, 0xbc, 0x2d, - 0xbf, 0xe0, 0x55, 0x1b, 0x5c, 0x1e, 0xce, 0x31, - 0xd9, 0xf8, 0x56, 0x68, 0x95, 0x2b, 0x15, 0x84, - 0x35, 0xae, 0x98, 0x2c, 0x63, 0x01, 0xb2, 0x0d, - 0xab, 0xa8, 0x61, 0xef, 0x7f, 0x15, 0x2c, 0x6d, - 0xf7, 0x67, 0x1d, 0xb8, 0x8d, 0xf6, 0xa2, 0x1c, - 0x4e, 0x85, 0xf0, 0xea, 0x1a, 0x2b, 0xc8, 0xac, - 0x70, 0x86, 0x9a, 0xbb, 0x9e, 0x9d, 0xbd, 0xc9, - 0x87, 0x2b, 0x9f, 0x5e, 0x40, 0x44, 0x9b, 0xba, - 0x96, 0x45, 0x24, 0xbc, 0x49, 0xb8, 0xfe, 0x26, - 0x3a, 0x1d, 0x1a, 0x0a, 0x3a, 0x90, 0x9c, 0x75, - 0x51, 0x59, 0x89, 0x98, 0x1a, 0x56, 0xe1, 0x3a, - 0x1a, 0xba, 0xff, 0xb4, 0x37, 0x7d, 0xd8, 0x99, - 0xe2, 0xeb, 0x45, 0x27, 0xe2, 0x42, 0x42, 0x46, - 0xbb, 0x00, 0x29, 0x9f, 0x30, 0xc9, 0x1e, 0x6c, - 0xce, 0x59, 0x0e, 0xbe, 0x16, 0x03, 0x31, 0xec, - 0x10, 0xc1, 0x6d, 0xca, 0x9d, 0x5f, 0x6d, 0xf1, - 0x26, 0x11, 0xe5, 0x50, 0xa1, 0xbb, 0x67, 0xb2, - 0xe0, 0x2b, 0xed, 0x76, 0x5b, 0xc7, 0x68, 0xc0, - 0x18, 0xad, 0x91, 0x9e, 0xb5, 0xd4, 0x4d, 0x21, - 0xcd, 0x98, 0xd9, 0xe0, 0x05, 0x0a, 0x4d, 0x24, - 0xa3, 0xe6, 0x12, 0x04, 0xdd, 0x50, 0xe6, 0xc8, - 0x7a, 0x69, 0xb9, 0x32, 0x43, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0xb6, 0x30, 0x82, - 0x01, 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb6, - 0xa8, 0xff, 0xa2, 0xa8, 0x2f, 0xd0, 0xa6, 0xcd, - 0x4b, 0xb1, 0x68, 0xf3, 0xe7, 0x50, 0x10, 0x31, - 0xa7, 0x79, 0x21, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62, 0x37, - 0xd4, 0x3c, 0xbf, 0xd9, 0xc2, 0x99, 0xf3, 0x28, - 0x3e, 0xdb, 0xca, 0xee, 0xf3, 0xb3, 0xc8, 0x73, - 0xb0, 0x3c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, - 0x05, 0xa0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, - 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, - 0x60, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x59, - 0x30, 0x57, 0x30, 0x4b, 0x06, 0x0b, 0x2b, 0x06, - 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x02, - 0x1a, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, - 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x67, 0x61, 0x6e, 0x64, - 0x69, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x2f, - 0x66, 0x72, 0x2f, 0x73, 0x73, 0x6c, 0x2f, 0x63, - 0x70, 0x73, 0x2f, 0x70, 0x64, 0x66, 0x2f, 0x30, - 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, - 0x01, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x35, 0x30, 0x33, 0x30, 0x31, 0xa0, 0x2f, - 0xa0, 0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, - 0x61, 0x6e, 0x64, 0x69, 0x2e, 0x6e, 0x65, 0x74, - 0x2f, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x53, 0x74, - 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x53, 0x53, - 0x4c, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x6a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x5e, 0x30, 0x5c, 0x30, - 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x02, 0x86, 0x2b, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, - 0x67, 0x61, 0x6e, 0x64, 0x69, 0x2e, 0x6e, 0x65, - 0x74, 0x2f, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x53, - 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x53, - 0x53, 0x4c, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, - 0x30, 0x21, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x15, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x67, 0x61, 0x6e, 0x64, 0x69, 0x2e, - 0x6e, 0x65, 0x74, 0x30, 0x27, 0x06, 0x03, 0x55, - 0x1d, 0x11, 0x04, 0x20, 0x30, 0x1e, 0x82, 0x0e, - 0x2a, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x82, 0x0c, - 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0x5b, 0x4a, 0x3a, 0x1d, 0x75, 0xe0, 0xc0, 0x9e, - 0xc9, 0x16, 0x66, 0x7f, 0x73, 0x95, 0x6e, 0x35, - 0xe4, 0x27, 0xfa, 0x8c, 0x9d, 0xee, 0xb1, 0x37, - 0x42, 0x3f, 0x54, 0x6a, 0x9d, 0x41, 0x84, 0x57, - 0xe1, 0x03, 0x3d, 0x69, 0x61, 0x77, 0x3b, 0x91, - 0xa2, 0x70, 0x94, 0xb6, 0x8e, 0x41, 0x63, 0x70, - 0xf2, 0x16, 0x04, 0x50, 0x05, 0x14, 0xfb, 0x59, - 0x7d, 0x89, 0x09, 0x3f, 0xb6, 0xef, 0xca, 0x3c, - 0x89, 0x88, 0x08, 0xe9, 0xa1, 0xf3, 0x33, 0x31, - 0x05, 0x4d, 0x70, 0xff, 0xdd, 0xa7, 0xd2, 0xe2, - 0xa0, 0x94, 0x3a, 0xf7, 0xc2, 0x9f, 0xad, 0x2b, - 0x2e, 0x20, 0xfa, 0x6c, 0xe1, 0xfc, 0xe6, 0x62, - 0x22, 0xa1, 0x38, 0x93, 0xec, 0x3e, 0xce, 0xfd, - 0x1f, 0xdd, 0xd4, 0x7c, 0x39, 0x46, 0x8b, 0xb4, - 0x64, 0xfa, 0xa1, 0x46, 0x87, 0x78, 0x2c, 0xd7, - 0x9c, 0xdd, 0x60, 0xd6, 0xda, 0x8e, 0xd8, 0x29, - 0x6d, 0x61, 0xa7, 0x29, 0x07, 0x76, 0xfc, 0xf9, - 0xbd, 0xfd, 0x14, 0xeb, 0x44, 0x70, 0xff, 0xd0, - 0x23, 0x99, 0x83, 0xc5, 0x5c, 0x56, 0x88, 0xaa, - 0x34, 0xda, 0xa6, 0xb3, 0x9a, 0xbf, 0xda, 0x58, - 0x1e, 0xa4, 0xb8, 0xc0, 0x40, 0x9d, 0xf0, 0xfc, - 0xf1, 0x23, 0xc2, 0xbc, 0x59, 0xe1, 0x82, 0xed, - 0x5d, 0xfb, 0x99, 0xaf, 0xf5, 0xf5, 0x15, 0xb8, - 0x8b, 0x59, 0xce, 0xaa, 0xca, 0xdf, 0xdc, 0x94, - 0x11, 0xe0, 0x96, 0xbf, 0x9f, 0x54, 0xa4, 0x9f, - 0x54, 0x36, 0x4a, 0xe8, 0x93, 0xda, 0xf4, 0x8c, - 0xb0, 0x6b, 0x8d, 0x4a, 0x9e, 0x11, 0xae, 0xcb, - 0xcb, 0x33, 0x8a, 0x4d, 0xcd, 0x4e, 0xa5, 0x9b, - 0xe9, 0x14, 0x46, 0x43, 0x9b, 0x96, 0x5f, 0x6d, - 0xf2, 0xea, 0x40, 0xef, 0x14, 0xc3, 0x99, 0x9f, - 0x23, 0x1e, 0xa5, 0x13, 0xab, 0x08, 0xea, 0x8f, - 0x68, 0x5b, 0x7d, 0x71, 0xdf, 0x18, 0xd1, 0x57, - 0x00, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x30, - 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x10, 0x5a, 0xb6, 0x1d, 0xac, 0x1e, 0x4d, - 0xa2, 0x06, 0x14, 0xc7, 0x55, 0x3d, 0x3d, 0xa9, - 0xb2, 0xdc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, - 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, - 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, - 0x6b, 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, - 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, - 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54, 0x4e, - 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, - 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, - 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d, 0x30, - 0x38, 0x31, 0x30, 0x32, 0x33, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, - 0x33, 0x38, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x09, 0x47, 0x41, 0x4e, - 0x44, 0x49, 0x20, 0x53, 0x41, 0x53, 0x31, 0x1e, - 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x15, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x53, - 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, - 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x82, - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6, - 0x54, 0x3d, 0xa5, 0xdb, 0x0d, 0x22, 0x78, 0x50, - 0x6a, 0x5a, 0x23, 0x89, 0x3f, 0x97, 0xa1, 0xd4, - 0x07, 0x1a, 0xa9, 0x58, 0x08, 0x9b, 0xa0, 0x15, - 0xc3, 0x32, 0xb6, 0xb7, 0xf1, 0xe8, 0xb9, 0xa5, - 0x6f, 0xad, 0x37, 0xf6, 0x6e, 0x71, 0x1b, 0xb4, - 0x75, 0x2d, 0x48, 0x5e, 0x9f, 0xc6, 0x15, 0xaa, - 0x81, 0xef, 0xe5, 0xc4, 0x88, 0x95, 0x8a, 0x3a, - 0x6c, 0x77, 0xcc, 0xb5, 0xcd, 0x65, 0xe4, 0x67, - 0xe5, 0x73, 0xc9, 0x50, 0x52, 0x94, 0xc1, 0x27, - 0x49, 0x3e, 0xa0, 0x6b, 0x41, 0x16, 0x41, 0xb6, - 0x94, 0x99, 0x41, 0xae, 0x3e, 0xcb, 0xe2, 0x06, - 0x46, 0x09, 0xe9, 0x4d, 0xbe, 0xc9, 0x4c, 0x55, - 0xa9, 0x18, 0x7e, 0xa6, 0xdf, 0x6e, 0xfd, 0x4a, - 0xb2, 0xcc, 0x6c, 0x4e, 0xd9, 0xc8, 0x50, 0x15, - 0x93, 0xb3, 0xf2, 0xe9, 0xe3, 0xc2, 0x6a, 0xad, - 0x3a, 0xd5, 0xfb, 0xc3, 0x79, 0x50, 0x9f, 0x25, - 0x79, 0x29, 0xb2, 0x47, 0x64, 0x7c, 0x20, 0x3e, - 0xe2, 0x08, 0x4d, 0x93, 0x29, 0x14, 0xb6, 0x34, - 0x6e, 0xcf, 0x71, 0x46, 0x7e, 0x76, 0x10, 0xf4, - 0xfd, 0x6c, 0xaa, 0x01, 0xd2, 0xc2, 0x06, 0xde, - 0x92, 0x83, 0xcc, 0x58, 0x90, 0x2e, 0x92, 0xde, - 0x1e, 0x65, 0xb7, 0x63, 0x2f, 0x3d, 0xb2, 0xeb, - 0x70, 0x8c, 0x4c, 0xe0, 0xbe, 0x15, 0x9d, 0xde, - 0xc1, 0x4d, 0x56, 0xf8, 0x0b, 0xc6, 0x8e, 0x07, - 0xb9, 0x5d, 0xdf, 0x95, 0xf0, 0x7b, 0x40, 0x1f, - 0x1a, 0x2c, 0xd7, 0x9c, 0x2b, 0x4b, 0x76, 0xf4, - 0x59, 0xf5, 0x43, 0xc1, 0x2c, 0x66, 0x10, 0x9e, - 0x9e, 0x66, 0x96, 0x60, 0x9d, 0x1c, 0x74, 0x1b, - 0x4e, 0x18, 0x5c, 0x08, 0xb0, 0x6e, 0x6c, 0xca, - 0x69, 0x1a, 0x02, 0xe9, 0xbb, 0xca, 0x78, 0xef, - 0x66, 0x2e, 0xe3, 0x32, 0xfd, 0x41, 0x5c, 0x95, - 0x74, 0x81, 0x4d, 0xf4, 0xda, 0xfe, 0x4b, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3e, - 0x30, 0x82, 0x01, 0x3a, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, - 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98, - 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, - 0x9d, 0x4b, 0xd2, 0xc3, 0x45, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0xb6, 0xa8, 0xff, 0xa2, 0xa8, 0x2f, 0xd0, 0xa6, - 0xcd, 0x4b, 0xb1, 0x68, 0xf3, 0xe7, 0x50, 0x10, - 0x31, 0xa7, 0x79, 0x21, 0x30, 0x0e, 0x06, 0x03, - 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, - 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, - 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, - 0x30, 0x18, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, - 0x11, 0x30, 0x0f, 0x30, 0x0d, 0x06, 0x0b, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, - 0x02, 0x1a, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, - 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, - 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, - 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, - 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, - 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, - 0x30, 0x74, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x01, 0x01, 0x04, 0x68, 0x30, 0x66, - 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x02, 0x86, 0x31, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, - 0x54, 0x4e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, - 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, - 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x19, 0x53, 0xbf, 0x03, 0x3d, 0x9b, - 0xe2, 0x6b, 0x5a, 0xfd, 0xba, 0x49, 0x1f, 0x4f, - 0xec, 0xe1, 0xc6, 0x82, 0x39, 0x3c, 0xd2, 0x03, - 0x04, 0x0f, 0xab, 0x7b, 0x3e, 0x82, 0xa9, 0x85, - 0x10, 0x1f, 0xf4, 0xde, 0x32, 0xaf, 0x58, 0x3f, - 0xff, 0x70, 0xf3, 0x30, 0x1d, 0x97, 0x2d, 0x4c, - 0x9a, 0xe2, 0xec, 0x0c, 0x3e, 0x14, 0x2d, 0x2f, - 0x98, 0x48, 0x9d, 0xae, 0x16, 0x6a, 0xac, 0x2d, - 0x42, 0xaa, 0xb5, 0x64, 0xa4, 0x70, 0xbb, 0xeb, - 0x73, 0x94, 0x7b, 0x46, 0x4c, 0xe7, 0x7a, 0x14, - 0x76, 0x5b, 0x4c, 0x1d, 0x84, 0xa1, 0x20, 0x74, - 0x1f, 0x2e, 0x4b, 0x5c, 0x70, 0x88, 0xdc, 0xbd, - 0xf7, 0x19, 0x3d, 0xed, 0x59, 0x0d, 0xe2, 0x3f, - 0x26, 0xe2, 0x9c, 0xac, 0xa4, 0x3c, 0x95, 0x1c, - 0xf8, 0xbe, 0x8c, 0x03, 0xae, 0xf0, 0xe5, 0x9c, - 0x4d, 0xbc, 0xc7, 0x9b, 0x58, 0x00, 0xbf, 0xaf, - 0xad, 0xfa, 0x37, 0x6e, 0x71, 0x6d, 0x18, 0x34, - 0x0e, 0xc1, 0xea, 0x6a, 0xf8, 0x0d, 0xdf, 0x69, - 0x54, 0x56, 0x15, 0xf2, 0x28, 0xb3, 0xfe, 0xa4, - 0x63, 0xec, 0xc5, 0x04, 0x64, 0x60, 0xbb, 0xfe, - 0x2a, 0xf0, 0xf4, 0x87, 0xa1, 0xb0, 0xae, 0xbd, - 0xaa, 0xe4, 0x2f, 0xe3, 0x03, 0x0b, 0x2f, 0x66, - 0x5f, 0x85, 0xa4, 0x32, 0x7b, 0x46, 0xed, 0x25, - 0x0c, 0xe7, 0xf1, 0xb7, 0xe7, 0x19, 0xfd, 0x60, - 0xba, 0x5f, 0x87, 0x77, 0xde, 0x98, 0x07, 0x96, - 0xe4, 0x5e, 0xea, 0x63, 0x7d, 0xa8, 0xde, 0x55, - 0xda, 0x61, 0x5c, 0x3c, 0x90, 0x83, 0x43, 0x04, - 0x07, 0x3c, 0xdd, 0xf3, 0xf8, 0x9f, 0x06, 0x52, - 0x0a, 0xde, 0xc7, 0xb6, 0x7b, 0x8f, 0xe1, 0x11, - 0xf7, 0x04, 0x7a, 0x35, 0xff, 0x6a, 0xbc, 0x5b, - 0xc7, 0x50, 0x49, 0x08, 0x70, 0x6f, 0x94, 0x43, - 0xcd, 0x9e, 0xc7, 0x70, 0xf1, 0xdb, 0xd0, 0x6d, - 0xda, 0x8f, 0x16, 0x03, 0x01, 0x00, 0x0e, 0x0d, - 0x00, 0x00, 0x06, 0x03, 0x01, 0x02, 0x40, 0x00, - 0x00, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, - 0xba, 0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, - 0x82, 0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, - 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, - 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, - 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, - 0x39, 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, - 0x31, 0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, - 0x30, 0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, - 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, - 0x00, 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, - 0xbf, 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, - 0x2b, 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, - 0x7a, 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, - 0x65, 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, - 0xb4, 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, - 0x62, 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, - 0x5c, 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, - 0x58, 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, - 0xd0, 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, - 0x9f, 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, - 0x18, 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, - 0xf1, 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, - 0xc9, 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, - 0x01, 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, - 0x1d, 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, - 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, - 0xa7, 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, - 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, - 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, - 0x18, 0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, - 0x1d, 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, - 0xb1, 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, - 0xdb, 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, - 0x8e, 0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, - 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, - 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, - 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, - 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, - 0xb8, 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x81, 0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, - 0x6b, 0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, - 0xb0, 0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, - 0xb5, 0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, - 0xae, 0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, - 0x6e, 0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, - 0xb5, 0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, - 0x30, 0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, - 0xe7, 0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, - 0x78, 0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, - 0x2d, 0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, - 0x75, 0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, - 0xcd, 0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, - 0x1c, 0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, - 0x57, 0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, - 0x9b, 0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, - 0xa7, 0xbd, 0xd9, 0x16, 0x03, 0x01, 0x01, 0x06, - 0x10, 0x00, 0x01, 0x02, 0x01, 0x00, 0x25, 0x48, - 0x6c, 0x0a, 0xde, 0x9d, 0x3a, 0x57, 0xe4, 0x2e, - 0xb9, 0xfc, 0xb4, 0x46, 0x1f, 0x20, 0x4f, 0x58, - 0x4d, 0x12, 0x08, 0xb4, 0x3e, 0x4c, 0xf5, 0xa8, - 0xa5, 0x16, 0x40, 0x29, 0x19, 0x04, 0x4d, 0xf9, - 0x54, 0x3a, 0x32, 0xd7, 0x79, 0xf2, 0x0e, 0xc1, - 0x7b, 0x0c, 0x62, 0x71, 0xbb, 0xb4, 0x8c, 0xe7, - 0x84, 0xd5, 0xf8, 0x11, 0x77, 0x7f, 0x87, 0x6c, - 0xfc, 0x25, 0xf3, 0x2d, 0x97, 0x3d, 0x1f, 0xf5, - 0xfc, 0x64, 0x94, 0x9f, 0xdd, 0x90, 0x82, 0xdd, - 0x11, 0x74, 0x74, 0x59, 0xa2, 0x1a, 0x71, 0xb2, - 0x55, 0x6d, 0x18, 0xca, 0x85, 0x47, 0x8b, 0x79, - 0x73, 0x06, 0x24, 0x38, 0xc3, 0x34, 0x98, 0x84, - 0x62, 0x81, 0xd8, 0xad, 0x54, 0xad, 0x13, 0xa5, - 0xf4, 0xe4, 0x82, 0x85, 0xd3, 0xe3, 0x9e, 0xeb, - 0xb5, 0xf5, 0x95, 0x83, 0x0e, 0xb9, 0x7d, 0xb6, - 0xda, 0x0c, 0xf6, 0x14, 0x6a, 0x60, 0x8c, 0x75, - 0x56, 0xf0, 0xe9, 0x60, 0xe0, 0x4c, 0xf4, 0x4e, - 0x84, 0x8b, 0x4f, 0xf4, 0x2f, 0xde, 0xb7, 0xec, - 0x61, 0xd3, 0x77, 0x07, 0x6e, 0x41, 0x57, 0xc9, - 0xd9, 0x1d, 0x75, 0xee, 0x42, 0x63, 0xdc, 0x58, - 0xad, 0xfc, 0xc7, 0xe1, 0x77, 0x49, 0xb1, 0x58, - 0x21, 0x96, 0x00, 0x55, 0x90, 0x6b, 0xf6, 0x2a, - 0x5a, 0x19, 0x25, 0x93, 0x59, 0x9d, 0xaf, 0x79, - 0x9b, 0x18, 0x5d, 0xf6, 0x5d, 0x64, 0x4b, 0x9a, - 0xf4, 0xde, 0xf2, 0x7f, 0xbd, 0x93, 0x7e, 0x45, - 0x3e, 0x17, 0xae, 0xbf, 0x52, 0xe1, 0xba, 0x8e, - 0x0b, 0xbc, 0x1e, 0x91, 0x9d, 0xf1, 0x4e, 0x0b, - 0xab, 0x9e, 0x5c, 0x4c, 0x6f, 0xf7, 0xf3, 0x8d, - 0x8c, 0x6d, 0xeb, 0x46, 0x05, 0x36, 0x7e, 0x2f, - 0x9c, 0xa1, 0x86, 0x15, 0xe1, 0xe4, 0xb4, 0x20, - 0x06, 0x44, 0x7b, 0x3c, 0x8b, 0x13, 0x96, 0xf5, - 0x02, 0xb1, 0x4f, 0x3c, 0x2d, 0x4a, 0x16, 0x03, - 0x01, 0x00, 0x86, 0x0f, 0x00, 0x00, 0x82, 0x00, - 0x80, 0x52, 0xb1, 0x0d, 0xfc, 0x85, 0x34, 0x56, - 0xb9, 0xdf, 0xa7, 0x8e, 0xf4, 0xfd, 0x02, 0x46, - 0x8a, 0x23, 0xcc, 0x53, 0x3b, 0x0f, 0xa7, 0x61, - 0xf3, 0xb5, 0xbf, 0xfe, 0x59, 0x77, 0x10, 0xd6, - 0x56, 0x93, 0x19, 0x6b, 0x2c, 0xf1, 0x35, 0x71, - 0xe3, 0x36, 0x2f, 0xa0, 0x90, 0x4e, 0x5a, 0xdf, - 0x8d, 0x06, 0x88, 0xcf, 0xb1, 0x06, 0x56, 0x8b, - 0x74, 0x8f, 0x02, 0x8e, 0x10, 0xd2, 0xab, 0x8d, - 0x3f, 0x3e, 0x02, 0xf1, 0x1a, 0x80, 0x6d, 0x0f, - 0x9e, 0x77, 0xd8, 0xfa, 0x92, 0xb3, 0x16, 0x40, - 0xeb, 0x9e, 0xca, 0xd7, 0xe4, 0x31, 0xcc, 0x63, - 0x5f, 0xe2, 0x4c, 0x85, 0x0e, 0xf2, 0xdd, 0xd3, - 0xfe, 0x7e, 0xa7, 0x60, 0x1c, 0xb4, 0x00, 0xd8, - 0xbe, 0x4b, 0x9b, 0x66, 0x78, 0x0f, 0xfb, 0x3b, - 0x52, 0x30, 0x2b, 0x8b, 0xd9, 0xef, 0x82, 0x0a, - 0xa4, 0x18, 0x1d, 0xb0, 0xb5, 0xbf, 0x54, 0x97, - 0x0c, 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, - 0x03, 0x01, 0x00, 0x30, 0xa1, 0x74, 0x22, 0xd8, - 0x86, 0x6a, 0xbe, 0x53, 0x34, 0x1d, 0xb3, 0x73, - 0xff, 0x51, 0xc0, 0xce, 0x8e, 0x7d, 0x9b, 0xab, - 0xcb, 0x8b, 0x79, 0xae, 0x04, 0x01, 0xa7, 0xf2, - 0x8e, 0x9d, 0xab, 0xa3, 0x73, 0x80, 0x5c, 0xff, - 0x96, 0x20, 0xbb, 0x8d, 0xc0, 0x02, 0x66, 0x6c, - 0x83, 0x4b, 0x78, 0x20, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x30, 0x29, 0xd4, 0xfd, 0x03, 0x8b, - 0x30, 0x20, 0xf7, 0xca, 0xc0, 0x6c, 0x83, 0x5d, - 0x73, 0xcb, 0x81, 0x60, 0xe0, 0x9a, 0x09, 0xcb, - 0x33, 0x03, 0x80, 0x81, 0x4e, 0x84, 0x47, 0xd5, - 0x74, 0x6c, 0x3b, 0xb5, 0xc0, 0x48, 0x0d, 0x52, - 0xdd, 0xbe, 0xc2, 0x06, 0xf5, 0x79, 0x2b, 0x3e, - 0x99, 0x56, 0x94, 0x17, 0x03, 0x01, 0x00, 0x20, - 0x26, 0x46, 0x90, 0x9d, 0xef, 0x59, 0x00, 0xb6, - 0x70, 0xe8, 0x1e, 0x1a, 0x80, 0x8b, 0x04, 0xb2, - 0xfc, 0x51, 0xf8, 0x93, 0xbe, 0x00, 0x28, 0xba, - 0xb8, 0xdc, 0x51, 0x7e, 0x92, 0x80, 0xfa, 0xf2, - 0x17, 0x03, 0x01, 0x00, 0xe0, 0xb8, 0x2e, 0xc4, - 0x6b, 0x3f, 0xda, 0x39, 0x87, 0x7f, 0x03, 0x43, - 0x28, 0xdd, 0xb9, 0xf9, 0x9e, 0x16, 0xf5, 0xce, - 0x3f, 0x7e, 0x6a, 0x7b, 0xb3, 0x60, 0x14, 0xe1, - 0xea, 0x54, 0xc5, 0xe6, 0x05, 0x0a, 0x6c, 0xe0, - 0xef, 0x58, 0x29, 0x8a, 0x77, 0x64, 0x77, 0x5d, - 0x9c, 0xe2, 0xe0, 0x3c, 0x6d, 0x87, 0x82, 0xbe, - 0x47, 0x63, 0xd4, 0xfd, 0x0c, 0x25, 0xc4, 0xb1, - 0xfe, 0x29, 0x6f, 0x84, 0xfb, 0xab, 0x6e, 0xa7, - 0xf9, 0x22, 0x89, 0x97, 0x5b, 0x91, 0x0a, 0x07, - 0xe0, 0xef, 0x3d, 0x67, 0xee, 0x87, 0xa8, 0x33, - 0x02, 0x64, 0x33, 0xca, 0x15, 0x10, 0xb9, 0x57, - 0xd8, 0xe5, 0x1a, 0x4b, 0xe3, 0x45, 0xc1, 0x62, - 0x85, 0x50, 0xf1, 0x79, 0x54, 0xe1, 0x2e, 0x25, - 0x01, 0x3c, 0xdb, 0x2d, 0x39, 0x14, 0x2f, 0x9b, - 0xd0, 0x1d, 0xc1, 0xac, 0x73, 0x7d, 0xa4, 0xed, - 0x89, 0x98, 0xb1, 0xae, 0x8a, 0x9e, 0xc8, 0xa7, - 0xfe, 0x55, 0x27, 0xb5, 0xb5, 0xa2, 0xec, 0x7e, - 0xe3, 0x6b, 0x45, 0x19, 0xfa, 0x20, 0x1c, 0x33, - 0x83, 0x22, 0x33, 0x97, 0xd2, 0x5a, 0xc4, 0xf8, - 0x9a, 0x03, 0x13, 0x85, 0xf2, 0x2b, 0x04, 0x59, - 0x27, 0xd7, 0x0b, 0x42, 0x47, 0x9b, 0x7d, 0x4d, - 0xb2, 0x1a, 0x85, 0x7f, 0x97, 0xc2, 0xf2, 0x10, - 0xf0, 0xfa, 0x4e, 0x4b, 0x62, 0x43, 0x3a, 0x09, - 0x2e, 0xcd, 0x8f, 0xa8, 0xb6, 0x0b, 0x5f, 0x34, - 0xd7, 0x3b, 0xba, 0xd9, 0xe5, 0x01, 0x2d, 0x35, - 0xae, 0xc5, 0x4c, 0xab, 0x40, 0x64, 0xc2, 0xc9, - 0x8c, 0x69, 0x44, 0xf4, 0xb8, 0xb5, 0x3a, 0x05, - 0x3c, 0x29, 0x19, 0xb4, 0x09, 0x17, 0x03, 0x01, - 0x00, 0x20, 0xc8, 0xc5, 0xb7, 0xe3, 0xd2, 0x3e, - 0x27, 0xb5, 0x71, 0x8f, 0x52, 0x0b, 0xce, 0x17, - 0x64, 0x86, 0xa4, 0x34, 0x16, 0x1b, 0x61, 0x64, - 0x7c, 0xb3, 0xf2, 0xe5, 0x3e, 0xfd, 0xdd, 0xfb, - 0x40, 0x78, 0x17, 0x03, 0x01, 0x00, 0x50, 0x8e, - 0x79, 0xf0, 0x8e, 0x76, 0x5d, 0x34, 0x09, 0xdc, - 0xec, 0x6d, 0xc3, 0x43, 0x1d, 0xcb, 0x2d, 0xaa, - 0x08, 0x7a, 0x51, 0x94, 0x4e, 0xc5, 0x26, 0xe4, - 0x0b, 0x8e, 0x8f, 0x51, 0xf2, 0x9f, 0xeb, 0xc3, - 0x18, 0x43, 0x95, 0x15, 0xfc, 0x59, 0x18, 0x25, - 0x47, 0xb6, 0x4a, 0x6e, 0xa3, 0xa4, 0x3b, 0xa3, - 0x47, 0x34, 0x74, 0x6b, 0xc5, 0x3d, 0x41, 0x14, - 0x64, 0xd5, 0x69, 0x5f, 0x77, 0xf3, 0x7c, 0x41, - 0xc6, 0xed, 0x2e, 0xcf, 0xff, 0x40, 0xf2, 0xce, - 0xbb, 0xa7, 0x4e, 0x73, 0x88, 0x98, 0x10, - }, - { - 0x15, 0x03, 0x01, 0x00, 0x20, 0x1a, 0xbc, 0x70, - 0x24, 0xf8, 0xfb, 0xf2, 0x4a, 0xf9, 0x44, 0x1e, - 0x58, 0xf8, 0xaa, 0x41, 0x24, 0xe8, 0x80, 0x33, - 0x45, 0x18, 0xa1, 0x5d, 0xee, 0x16, 0x80, 0xae, - 0x40, 0x41, 0x8e, 0x41, 0x9b, - }, -} - -var tls11ECDHEAESClientScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, - 0x46, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13, - 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - }, - { - 0x16, 0x03, 0x02, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x50, 0x03, 0x02, 0x51, 0x9f, 0xa2, 0x21, 0x1a, - 0xb7, 0x75, 0x42, 0x69, 0xd3, 0x14, 0xdd, 0x05, - 0x1e, 0xda, 0x13, 0x71, 0x8d, 0x6a, 0x45, 0x97, - 0xcb, 0xee, 0x0e, 0x77, 0x01, 0x0d, 0x6e, 0xe5, - 0x22, 0x70, 0x16, 0x20, 0x69, 0xfc, 0xa6, 0x9a, - 0xe8, 0x21, 0xcc, 0x46, 0x65, 0x05, 0xb4, 0x48, - 0x0f, 0x34, 0x63, 0x2c, 0xac, 0xa4, 0xf5, 0x4b, - 0x64, 0xd1, 0x07, 0x13, 0xa7, 0xe4, 0x5b, 0xa3, - 0x4d, 0x31, 0x41, 0x53, 0xc0, 0x13, 0x00, 0x00, - 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, - 0x02, 0x16, 0x03, 0x02, 0x02, 0x39, 0x0b, 0x00, - 0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, - 0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, - 0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, - 0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, - 0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, - 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, - 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, - 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, - 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, - 0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, - 0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, - 0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, - 0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, - 0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, - 0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, - 0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, - 0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, - 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, - 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, - 0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, - 0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, - 0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, - 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, - 0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, - 0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, - 0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, - 0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, - 0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, - 0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, - 0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, - 0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, - 0x03, 0x02, 0x00, 0x8b, 0x0c, 0x00, 0x00, 0x87, - 0x03, 0x00, 0x17, 0x41, 0x04, 0x34, 0xde, 0x50, - 0x32, 0x8f, 0x25, 0x6b, 0x37, 0x2c, 0x36, 0x24, - 0x27, 0x0e, 0xf9, 0x67, 0xb4, 0xf8, 0x29, 0x1c, - 0xa5, 0xa4, 0x59, 0x9a, 0xca, 0x40, 0x26, 0x15, - 0x61, 0x72, 0x34, 0x4a, 0xd3, 0x0c, 0xac, 0x69, - 0xcb, 0x2a, 0x9e, 0xf8, 0x80, 0xfb, 0x7a, 0xc4, - 0xd4, 0x4b, 0x91, 0x1b, 0xbe, 0x24, 0x26, 0xad, - 0x19, 0x24, 0xbe, 0x32, 0x58, 0xfb, 0xc7, 0x77, - 0xce, 0x7e, 0x71, 0x51, 0x1a, 0x00, 0x40, 0x1a, - 0x0b, 0xe8, 0x91, 0x84, 0x64, 0x54, 0xb6, 0x19, - 0xe8, 0xd4, 0x43, 0x7c, 0x09, 0x0c, 0x2e, 0xba, - 0x42, 0xb9, 0x74, 0xc3, 0x6c, 0x06, 0x9b, 0xa6, - 0x7e, 0x92, 0xe9, 0xee, 0x7c, 0x74, 0xa9, 0xd3, - 0x63, 0xf0, 0x16, 0x20, 0x60, 0x71, 0x8e, 0x24, - 0xc7, 0x7f, 0xc5, 0x5b, 0x9c, 0x19, 0x0c, 0x80, - 0x15, 0x61, 0xbf, 0xb6, 0xed, 0x5b, 0x7b, 0x90, - 0xc5, 0x05, 0x13, 0x72, 0x45, 0x79, 0xdf, 0x16, - 0x03, 0x02, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x02, 0x00, 0x46, 0x10, 0x00, 0x00, - 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, - 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, - 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, - 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, - 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, - 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, - 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, - 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, - 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x02, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x02, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x50, - 0x32, 0x26, 0x51, 0xbd, 0xbd, 0x3c, 0x4f, 0x72, - 0xbf, 0xbc, 0x91, 0x70, 0x4b, 0x5d, 0x43, 0x4a, - 0x65, 0x26, 0x0d, 0xaa, 0xed, 0x00, 0x91, 0xaf, - 0x4f, 0x47, 0x09, 0xaa, 0x79, 0xc4, 0x47, 0x21, - 0x71, 0xd8, 0x2b, 0xc1, 0x51, 0xc8, 0xef, 0xed, - 0x67, 0xde, 0x97, 0xef, 0x18, 0x53, - }, - { - 0x14, 0x03, 0x02, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x02, 0x00, 0x40, 0x72, 0x20, 0xbf, 0xd1, 0xbd, - 0x83, 0x53, 0x57, 0xb0, 0x4e, 0xac, 0xba, 0x1a, - 0x2b, 0x2d, 0xeb, 0x8a, 0x48, 0x17, 0xfa, 0x69, - 0xf9, 0xb5, 0x94, 0x8e, 0x6f, 0x9c, 0xda, 0x59, - 0xba, 0x6c, 0x7c, 0x82, 0xe2, 0x53, 0xa9, 0x46, - 0xdc, 0x33, 0xa0, 0x9b, 0xf0, 0x1e, 0xf1, 0x53, - 0x83, 0x48, 0xbf, 0x5e, 0xef, 0x03, 0x2b, 0x50, - 0x7a, 0xa6, 0xf8, 0xc3, 0x9e, 0x24, 0x43, 0x3a, - 0xdf, 0x44, 0x3e, - }, - { - 0x17, 0x03, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0b, 0x8f, - 0x6b, 0xf9, 0xd3, 0x9f, 0x2b, 0x49, 0xe0, 0x62, - 0x9a, 0x0b, 0x3e, 0xa2, 0x72, 0x8b, 0x96, 0x0c, - 0x41, 0x09, 0x95, 0x9e, 0x6b, 0x26, 0xa1, 0x46, - 0xca, 0xb8, 0xb6, 0xd2, 0xd4, 0x15, 0x03, 0x02, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xa0, 0xd4, 0x84, 0xc6, 0x7e, 0x1c, - 0x2f, 0xbd, 0x6b, 0x45, 0x31, 0x1d, 0x7d, 0x8f, - 0x31, 0x39, 0x5a, 0x4e, 0xaa, 0xf1, 0x0a, 0x8a, - 0x6c, 0x33, 0x59, 0x19, 0xd8, 0x75, 0x80, 0xab, - 0x93, 0x81, - }, -} - -var clientChainCertificateScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x51, 0xa2, 0x9b, 0x8b, 0xd4, - 0xe6, 0x33, 0xa2, 0x70, 0x38, 0x37, 0xba, 0x55, - 0x86, 0xcf, 0x87, 0xea, 0x6d, 0x2c, 0x3e, 0x17, - 0xc2, 0x09, 0xf8, 0x4d, 0xb0, 0x5d, 0x93, 0x2b, - 0x15, 0x99, 0x0c, 0x20, 0x5d, 0x61, 0x21, 0x2c, - 0xed, 0x49, 0x32, 0x29, 0x08, 0x6e, 0x21, 0x58, - 0x00, 0xdb, 0x34, 0xb7, 0x37, 0xcd, 0x27, 0x75, - 0x31, 0x1e, 0x6c, 0x74, 0xa6, 0xef, 0xa2, 0xc4, - 0x2b, 0x6c, 0xc3, 0x03, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x01, 0x03, 0xef, 0x0b, 0x00, 0x03, 0xeb, - 0x00, 0x03, 0xe8, 0x00, 0x03, 0xe5, 0x30, 0x82, - 0x03, 0xe1, 0x30, 0x82, 0x02, 0xc9, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xcc, 0x22, - 0x4c, 0x4b, 0x98, 0xa2, 0x88, 0xfc, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x86, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, - 0x4e, 0x59, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, - 0x55, 0x04, 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, - 0x6f, 0x6b, 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, - 0x4d, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, - 0x6f, 0x72, 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, - 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, - 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x33, 0x30, 0x35, 0x32, 0x36, - 0x32, 0x31, 0x30, 0x35, 0x30, 0x31, 0x5a, 0x17, - 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x34, 0x32, - 0x31, 0x30, 0x35, 0x30, 0x31, 0x5a, 0x30, 0x81, - 0x86, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, - 0x02, 0x4e, 0x59, 0x31, 0x11, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x42, 0x72, - 0x6f, 0x6f, 0x6b, 0x6c, 0x79, 0x6e, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, - 0x18, 0x4d, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x0c, 0x08, 0x6d, 0x79, 0x63, 0x61, - 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x21, 0x30, 0x1f, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, - 0x68, 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, - 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, - 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, - 0xf0, 0xfb, 0xad, 0x80, 0x5e, 0x37, 0xd3, 0x6d, - 0xee, 0x2e, 0xcc, 0xbc, 0x0c, 0xd7, 0x56, 0x4b, - 0x56, 0x45, 0xcd, 0x28, 0xb6, 0x22, 0xe9, 0xe2, - 0x0f, 0xd1, 0x87, 0x2a, 0x27, 0xce, 0x77, 0x8d, - 0x6e, 0x0e, 0x0f, 0xfb, 0x66, 0xe1, 0xb5, 0x0e, - 0x9a, 0xb6, 0x05, 0x8e, 0xb3, 0xe1, 0xc5, 0x77, - 0x86, 0x5b, 0x46, 0xd2, 0x0b, 0x92, 0x03, 0x1b, - 0x89, 0x0c, 0x1b, 0x10, 0x0e, 0x99, 0x8f, 0xe2, - 0x17, 0xe8, 0xc2, 0x30, 0x00, 0x47, 0xd6, 0xfc, - 0xf9, 0x0f, 0x3b, 0x75, 0x34, 0x8d, 0x4d, 0xb0, - 0x99, 0xb7, 0xa0, 0x6d, 0xa0, 0xb6, 0xad, 0xda, - 0x07, 0x5e, 0x38, 0x2e, 0x02, 0xe4, 0x30, 0x6d, - 0xae, 0x13, 0x72, 0xd4, 0xc8, 0xce, 0x14, 0x07, - 0xae, 0x23, 0x8c, 0x8f, 0x9e, 0x8c, 0x60, 0xd6, - 0x06, 0xb9, 0xef, 0x00, 0x18, 0xc0, 0x1d, 0x25, - 0x1e, 0xda, 0x3e, 0x2f, 0xcf, 0x2b, 0x56, 0x84, - 0x9e, 0x30, 0x21, 0xc7, 0x29, 0xf6, 0x03, 0x8a, - 0x24, 0xf9, 0x34, 0xac, 0x65, 0x9d, 0x80, 0x36, - 0xc8, 0x3b, 0x15, 0x10, 0xbd, 0x51, 0xe9, 0xbc, - 0x02, 0xe1, 0xe9, 0xb3, 0x5a, 0x9a, 0x99, 0x41, - 0x1b, 0x27, 0xa0, 0x4d, 0x50, 0x9e, 0x27, 0x7f, - 0xa1, 0x7d, 0x09, 0x87, 0xbd, 0x8a, 0xca, 0x5f, - 0xb1, 0xa5, 0x08, 0xb8, 0x04, 0xd4, 0x52, 0x89, - 0xaa, 0xe0, 0x7d, 0x42, 0x2e, 0x2f, 0x15, 0xee, - 0x66, 0x57, 0x0f, 0x13, 0x19, 0x45, 0xa8, 0x4b, - 0x5d, 0x81, 0x66, 0xcc, 0x12, 0x37, 0x94, 0x5e, - 0xfd, 0x3c, 0x10, 0x81, 0x51, 0x3f, 0xfa, 0x0f, - 0xdd, 0xa1, 0x89, 0x03, 0xa9, 0x78, 0x91, 0xf5, - 0x3b, 0xf3, 0xbc, 0xac, 0xbe, 0x93, 0x30, 0x2e, - 0xbe, 0xca, 0x7f, 0x46, 0xd3, 0x28, 0xb4, 0x4e, - 0x91, 0x7b, 0x5b, 0x43, 0x6c, 0xaf, 0x9b, 0x5c, - 0x6a, 0x6d, 0x5a, 0xdb, 0x79, 0x5e, 0x6a, 0x6b, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, - 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x6b, 0x1e, 0x00, 0xa8, - 0x9f, 0xfa, 0x7d, 0x00, 0xf9, 0xe0, 0x9d, 0x0f, - 0x90, 0x8c, 0x90, 0xa8, 0xa1, 0x37, 0x6b, 0xda, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0x6b, 0x1e, 0x00, - 0xa8, 0x9f, 0xfa, 0x7d, 0x00, 0xf9, 0xe0, 0x9d, - 0x0f, 0x90, 0x8c, 0x90, 0xa8, 0xa1, 0x37, 0x6b, - 0xda, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0xcd, 0x6f, 0x73, 0x4d, 0x56, - 0x0b, 0xf3, 0x2e, 0x1c, 0xe2, 0x02, 0x0c, 0x14, - 0xbb, 0x2f, 0xdd, 0x3c, 0x43, 0xfe, 0xdf, 0x94, - 0x2d, 0xa9, 0x89, 0x81, 0x51, 0xf8, 0x5f, 0xa7, - 0xa0, 0x13, 0xaa, 0xcc, 0xb0, 0x18, 0xe2, 0x57, - 0x3e, 0x0d, 0x29, 0x93, 0xe8, 0x95, 0xd5, 0x1b, - 0x53, 0xd2, 0x51, 0xf2, 0xbd, 0xf5, 0x9e, 0x7b, - 0x22, 0x65, 0x62, 0x5c, 0xc4, 0x4c, 0x1d, 0xe8, - 0xe9, 0xc3, 0xd4, 0x2b, 0xe7, 0x78, 0xcb, 0x10, - 0xf3, 0xfe, 0x06, 0x83, 0xdc, 0x3a, 0x1e, 0x62, - 0x10, 0xc0, 0x46, 0x77, 0xc6, 0x9d, 0x9f, 0xab, - 0x96, 0x25, 0x5c, 0xfb, 0x26, 0xc1, 0x15, 0x1f, - 0xa5, 0x33, 0xee, 0x4f, 0x9a, 0x14, 0x6a, 0x14, - 0x97, 0x93, 0x2b, 0x95, 0x0b, 0xdc, 0xa8, 0xd7, - 0x69, 0x2e, 0xf0, 0x01, 0x0e, 0xfd, 0x4e, 0xd0, - 0xd9, 0xa8, 0xe5, 0x65, 0xde, 0xfb, 0xca, 0xca, - 0x1c, 0x5f, 0xf9, 0x53, 0xa0, 0x87, 0xe7, 0x33, - 0x9b, 0x2f, 0xcf, 0xe4, 0x13, 0xfc, 0xec, 0x7a, - 0x6c, 0xb0, 0x90, 0x13, 0x9b, 0xb6, 0xc5, 0x03, - 0xf6, 0x0e, 0x5e, 0xe2, 0xe4, 0x26, 0xc1, 0x7e, - 0x53, 0xfe, 0x69, 0xa3, 0xc7, 0xd8, 0x8e, 0x6e, - 0x94, 0x32, 0xa0, 0xde, 0xca, 0xb6, 0xcc, 0xd6, - 0x01, 0xd5, 0x78, 0x40, 0x28, 0x63, 0x9b, 0xee, - 0xcf, 0x09, 0x3b, 0x35, 0x04, 0xf0, 0x14, 0x02, - 0xf6, 0x80, 0x0e, 0x90, 0xb2, 0x94, 0xd2, 0x25, - 0x16, 0xb8, 0x7a, 0x76, 0x87, 0x84, 0x9f, 0x84, - 0xc5, 0xaf, 0xc2, 0x6d, 0x68, 0x7a, 0x84, 0x9c, - 0xc6, 0x8a, 0x63, 0x60, 0x87, 0x6a, 0x25, 0xc1, - 0xa1, 0x78, 0x0f, 0xba, 0xe8, 0x5f, 0xe1, 0xba, - 0xac, 0xa4, 0x6f, 0xdd, 0x09, 0x3f, 0x12, 0xcb, - 0x1d, 0xf3, 0xcf, 0x48, 0xd7, 0xd3, 0x26, 0xe8, - 0x9c, 0xc3, 0x53, 0xb3, 0xba, 0xdc, 0x32, 0x99, - 0x98, 0x96, 0xd6, 0x16, 0x03, 0x01, 0x00, 0x99, - 0x0d, 0x00, 0x00, 0x91, 0x03, 0x01, 0x02, 0x40, - 0x00, 0x8b, 0x00, 0x89, 0x30, 0x81, 0x86, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, - 0x59, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, - 0x04, 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, - 0x6b, 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, - 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, - 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x0c, 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, - 0x72, 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, - 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, - 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, - 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x0e, 0x00, 0x00, - 0x00, - }, - { - 0x16, 0x03, 0x01, 0x0a, 0xfb, 0x0b, 0x00, 0x0a, - 0xf7, 0x00, 0x0a, 0xf4, 0x00, 0x03, 0x7e, 0x30, - 0x82, 0x03, 0x7a, 0x30, 0x82, 0x02, 0x62, 0x02, - 0x09, 0x00, 0xb4, 0x47, 0x58, 0x57, 0x2b, 0x67, - 0xc8, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, 0x11, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, - 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, 0x20, 0x43, - 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, 0x61, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, - 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, - 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, - 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x34, - 0x34, 0x30, 0x30, 0x5a, 0x30, 0x7d, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x08, 0x4e, 0x65, - 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x31, 0x11, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, - 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x79, 0x20, 0x4c, - 0x65, 0x61, 0x66, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x6d, 0x79, - 0x6c, 0x65, 0x61, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, - 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, - 0x82, 0x01, 0x01, 0x00, 0xa0, 0xa3, 0xef, 0xc1, - 0x44, 0x7d, 0xa2, 0xe3, 0x71, 0x98, 0x27, 0x63, - 0xb3, 0x1d, 0x71, 0x50, 0xa6, 0x34, 0x15, 0xcb, - 0xc9, 0x2a, 0xc3, 0xea, 0xe4, 0x9e, 0x9c, 0x49, - 0xa6, 0x01, 0x9b, 0x7e, 0xa9, 0xb5, 0x7a, 0xff, - 0x15, 0x92, 0x71, 0xc8, 0x97, 0x9c, 0x25, 0xb7, - 0x79, 0x2b, 0xff, 0xab, 0xc6, 0xb1, 0xa7, 0x00, - 0x90, 0xb2, 0x8b, 0xd7, 0x71, 0xd5, 0xc2, 0x3a, - 0xe6, 0x82, 0x42, 0x37, 0x89, 0x41, 0x04, 0xb0, - 0xba, 0xc7, 0x5b, 0x8a, 0x43, 0x9f, 0x97, 0x39, - 0x0c, 0x0f, 0xd5, 0x6d, 0x9e, 0x8d, 0xeb, 0xc0, - 0x26, 0xc5, 0x18, 0xe8, 0x7a, 0x3d, 0x32, 0x2e, - 0x38, 0x90, 0x40, 0x5b, 0x39, 0x2c, 0x07, 0xcb, - 0x24, 0x10, 0xc5, 0xc9, 0x3b, 0xe3, 0x66, 0x47, - 0x57, 0xb9, 0x6a, 0xad, 0x44, 0xf8, 0xd0, 0x70, - 0x62, 0x3b, 0x8e, 0xed, 0x60, 0x5f, 0x22, 0xf8, - 0xb8, 0x0c, 0xc9, 0x41, 0x2b, 0xc9, 0x80, 0x6e, - 0x4e, 0x1b, 0xe1, 0x20, 0xfc, 0x47, 0xa4, 0xac, - 0xc3, 0x3f, 0xe6, 0xc2, 0x81, 0x79, 0x03, 0x37, - 0x25, 0x89, 0xca, 0xd6, 0xa5, 0x46, 0x91, 0x63, - 0x41, 0xc5, 0x3e, 0xd5, 0xed, 0x7f, 0x4f, 0x8d, - 0x06, 0xc0, 0x89, 0x00, 0xbe, 0x37, 0x7b, 0x7e, - 0x73, 0xca, 0x70, 0x00, 0x14, 0x34, 0xbe, 0x47, - 0xbc, 0xb2, 0x6a, 0x28, 0xa5, 0x29, 0x84, 0xa8, - 0x9d, 0xc8, 0x1e, 0x77, 0x66, 0x1f, 0x9f, 0xaa, - 0x2b, 0x47, 0xdb, 0xdd, 0x6b, 0x9c, 0xa8, 0xfc, - 0x82, 0x36, 0x94, 0x62, 0x0d, 0x5c, 0x3f, 0xb2, - 0x01, 0xb4, 0xa5, 0xb8, 0xc6, 0x0e, 0x94, 0x5b, - 0xec, 0x5e, 0xbb, 0x7a, 0x63, 0x24, 0xf1, 0xf9, - 0xd6, 0x50, 0x08, 0xc1, 0xa3, 0xcc, 0x90, 0x07, - 0x5b, 0x04, 0x04, 0x42, 0x74, 0xcf, 0x37, 0xfa, - 0xf0, 0xa5, 0xd9, 0xd3, 0x86, 0x89, 0x89, 0x18, - 0xf3, 0x4c, 0xe2, 0x11, 0x02, 0x03, 0x01, 0x00, - 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x90, 0xbb, 0xf9, - 0x5e, 0xba, 0x17, 0x1f, 0xac, 0x21, 0x9f, 0x6b, - 0x4a, 0x46, 0xd0, 0x6d, 0x3c, 0x8f, 0x3d, 0xf8, - 0x5e, 0x3e, 0x72, 0xaf, 0xa0, 0x1a, 0xf3, 0xff, - 0x89, 0xac, 0x5b, 0x7a, 0xe2, 0x91, 0x2a, 0x23, - 0x85, 0xc6, 0x4d, 0x47, 0x67, 0x01, 0x08, 0xa8, - 0x05, 0x1d, 0x01, 0x60, 0x50, 0x5f, 0x59, 0xad, - 0xfe, 0x7b, 0xc6, 0x0c, 0x54, 0x90, 0x68, 0x70, - 0x67, 0x2e, 0xed, 0x87, 0xf8, 0x69, 0x8a, 0xac, - 0x32, 0xfe, 0x6f, 0x90, 0x19, 0x2a, 0x64, 0x8d, - 0x82, 0x66, 0x05, 0x43, 0x88, 0xee, 0xf2, 0x30, - 0xed, 0xa4, 0x8f, 0xbf, 0xd6, 0x57, 0x20, 0xd4, - 0x43, 0x1d, 0x52, 0x96, 0x6f, 0xae, 0x09, 0x96, - 0x01, 0x52, 0x38, 0xe3, 0xaf, 0x99, 0xd7, 0xdc, - 0x14, 0x99, 0xc4, 0x8b, 0x0e, 0x04, 0x0f, 0xb3, - 0x14, 0x14, 0xd4, 0xa5, 0x93, 0xe1, 0xc9, 0x8a, - 0x81, 0xef, 0x63, 0xfc, 0x36, 0x77, 0x05, 0x06, - 0xf0, 0x2a, 0x04, 0x0a, 0xbe, 0x2e, 0xce, 0x81, - 0x3d, 0x23, 0xa1, 0xda, 0xd8, 0xeb, 0xc6, 0xea, - 0x5e, 0xcf, 0x28, 0x36, 0x51, 0x31, 0x95, 0x5e, - 0x40, 0x04, 0xed, 0xac, 0xc1, 0xc8, 0x56, 0x69, - 0x87, 0xec, 0x3b, 0x03, 0x3e, 0x9d, 0x0f, 0x4c, - 0x4c, 0xeb, 0xd7, 0xba, 0x26, 0xdf, 0xe3, 0xde, - 0x10, 0xee, 0x93, 0x62, 0x8d, 0x73, 0x52, 0x6e, - 0xff, 0x37, 0x36, 0x98, 0x7b, 0x2d, 0x56, 0x4c, - 0xba, 0x09, 0xb8, 0xa7, 0xf0, 0x3b, 0x16, 0x81, - 0xca, 0xdb, 0x43, 0xab, 0xec, 0x4c, 0x6e, 0x7c, - 0xc1, 0x0b, 0x22, 0x22, 0x43, 0x1d, 0xb6, 0x0c, - 0xc1, 0xb9, 0xcf, 0xe4, 0x53, 0xee, 0x1d, 0x3e, - 0x88, 0xa7, 0x13, 0xbe, 0x7f, 0xbd, 0xae, 0x72, - 0xcf, 0xcd, 0x63, 0xd2, 0xc3, 0x18, 0x58, 0x92, - 0xa2, 0xad, 0xb5, 0x09, 0x9d, 0x91, 0x03, 0xdd, - 0x3c, 0xe2, 0x1c, 0xde, 0x78, 0x00, 0x03, 0x88, - 0x30, 0x82, 0x03, 0x84, 0x30, 0x82, 0x02, 0x6c, - 0x02, 0x09, 0x00, 0xab, 0xed, 0xa6, 0xe4, 0x4a, - 0x2b, 0x2b, 0xf8, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, - 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, - 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, - 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, - 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x31, - 0x38, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, - 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x31, 0x38, - 0x34, 0x30, 0x5a, 0x30, 0x81, 0x80, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, - 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, - 0x6c, 0x79, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, - 0x20, 0x43, 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, - 0x61, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, - 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, - 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xce, - 0x13, 0xf0, 0x72, 0xb0, 0x61, 0xc8, 0x18, 0x37, - 0x8a, 0x41, 0x3d, 0x20, 0xa1, 0x1c, 0xcb, 0xbf, - 0xf6, 0x3b, 0x74, 0x26, 0x2a, 0x96, 0x11, 0xec, - 0x53, 0xa1, 0xcc, 0x7d, 0x77, 0x56, 0x45, 0x0f, - 0x36, 0xb7, 0xf2, 0x48, 0x92, 0x1a, 0x62, 0xcc, - 0xb6, 0xc0, 0xa1, 0x2f, 0x44, 0x2b, 0xc1, 0x89, - 0xcb, 0x6e, 0x1e, 0xdb, 0x57, 0x92, 0xd5, 0x97, - 0x60, 0x8c, 0x41, 0x2c, 0xd9, 0x20, 0xfe, 0xe9, - 0x1f, 0x8e, 0xfc, 0x7f, 0x02, 0x44, 0x0f, 0x28, - 0x81, 0xd6, 0x0c, 0xcd, 0xbc, 0xf0, 0x57, 0x6c, - 0xcc, 0xa7, 0xba, 0x06, 0xa0, 0xa6, 0x91, 0xda, - 0xef, 0x46, 0x8a, 0x60, 0x0f, 0x52, 0x6c, 0x90, - 0x6c, 0x8c, 0x44, 0xaf, 0xb0, 0x9d, 0x90, 0xba, - 0x21, 0x58, 0xa0, 0x3c, 0xee, 0x54, 0xb5, 0x29, - 0x26, 0x1f, 0x0a, 0xac, 0xef, 0x48, 0x68, 0x33, - 0xd0, 0x33, 0xd0, 0x8b, 0x1a, 0xec, 0x6e, 0x2f, - 0xb5, 0x4a, 0x53, 0xc2, 0x1a, 0xd2, 0xf1, 0x50, - 0x05, 0x59, 0x5c, 0xd9, 0xda, 0x03, 0x0a, 0x47, - 0xb7, 0xdd, 0xf7, 0x3a, 0x69, 0xf5, 0x4e, 0xea, - 0x4a, 0xc2, 0xca, 0x54, 0xb0, 0x8b, 0x76, 0xe1, - 0x02, 0x2d, 0x52, 0x67, 0xb9, 0xdd, 0x50, 0xc9, - 0x3b, 0x07, 0x24, 0x22, 0x6a, 0x00, 0x1d, 0x58, - 0x83, 0xa8, 0xec, 0x95, 0xf1, 0xda, 0xe2, 0x73, - 0xa0, 0xa1, 0x72, 0x60, 0x9e, 0x86, 0x53, 0xcb, - 0x45, 0xa8, 0xc2, 0xa0, 0x50, 0xa0, 0x53, 0xd6, - 0xfc, 0x18, 0x84, 0xb5, 0x4a, 0x26, 0xd0, 0xa2, - 0xaa, 0xd0, 0xff, 0xb6, 0xfe, 0x3a, 0x9c, 0xb5, - 0x19, 0x3b, 0x3f, 0xe1, 0x48, 0x0d, 0xa4, 0x09, - 0x4f, 0x83, 0xc9, 0xc0, 0xc9, 0xa6, 0x0b, 0x58, - 0x1f, 0x1c, 0x7b, 0xac, 0xa2, 0x42, 0xbc, 0x61, - 0xf4, 0x21, 0x8a, 0x00, 0xda, 0x14, 0xa0, 0x60, - 0x03, 0xfe, 0x93, 0x12, 0x6c, 0x56, 0xcd, 0x02, - 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0x25, 0x29, 0x3b, 0x1e, 0xc3, 0x58, 0x32, 0xe6, - 0x23, 0xc8, 0xee, 0x18, 0xf0, 0x1d, 0x62, 0x6d, - 0x3b, 0x59, 0x99, 0x3a, 0xfe, 0x49, 0x72, 0x07, - 0x3f, 0x58, 0x93, 0xdb, 0xc0, 0xaf, 0xb0, 0xb3, - 0x5c, 0xd1, 0x5c, 0x98, 0xc8, 0xea, 0x4a, 0xe4, - 0x58, 0x73, 0x0d, 0x57, 0xc5, 0x13, 0x7c, 0x5c, - 0x79, 0x66, 0xda, 0x04, 0x1d, 0xe5, 0x98, 0xda, - 0x35, 0x47, 0x44, 0xb0, 0xd2, 0x7a, 0x66, 0x9d, - 0xcd, 0x41, 0xa5, 0x8f, 0xa1, 0x11, 0xb2, 0x1a, - 0x87, 0xc0, 0xcd, 0x55, 0xed, 0xb4, 0x7b, 0x33, - 0x72, 0xeb, 0xf7, 0xe3, 0x7b, 0x8b, 0x02, 0x86, - 0xe9, 0x2b, 0x26, 0x32, 0x9f, 0x99, 0xf1, 0xcb, - 0x93, 0xab, 0xb9, 0x16, 0xb3, 0x9a, 0xb2, 0x22, - 0x13, 0x21, 0x1f, 0x5b, 0xcc, 0xa2, 0x59, 0xbb, - 0x69, 0xf2, 0xb8, 0x07, 0x80, 0xce, 0x0c, 0xf7, - 0x98, 0x4c, 0x85, 0xc2, 0x96, 0x6a, 0x22, 0x05, - 0xe9, 0xbe, 0x48, 0xb0, 0x02, 0x5b, 0x69, 0x28, - 0x18, 0x88, 0x96, 0xe3, 0xd7, 0xc6, 0x7a, 0xd3, - 0xe9, 0x99, 0xff, 0x9d, 0xc3, 0x61, 0x4d, 0x9a, - 0x96, 0xf2, 0xc6, 0x33, 0x4d, 0xe5, 0x5d, 0x5a, - 0x68, 0x64, 0x5a, 0x82, 0x35, 0x65, 0x25, 0xe3, - 0x8c, 0x5b, 0xb0, 0xf6, 0x96, 0x56, 0xbc, 0xbf, - 0x97, 0x76, 0x4b, 0x66, 0x44, 0x81, 0xa4, 0xc4, - 0xa7, 0x31, 0xc5, 0xa1, 0x4f, 0xe8, 0xa4, 0xca, - 0x20, 0xf5, 0x01, 0x5b, 0x99, 0x4f, 0x5a, 0xf4, - 0xf0, 0x78, 0xbf, 0x71, 0x49, 0xd5, 0xf1, 0xc1, - 0xa2, 0x18, 0xfd, 0x72, 0x5b, 0x16, 0xe8, 0x92, - 0xc7, 0x37, 0x48, 0xaf, 0xee, 0x24, 0xfc, 0x35, - 0x0b, 0xc2, 0xdd, 0x05, 0xc7, 0x6e, 0xa3, 0x29, - 0xbb, 0x29, 0x7d, 0xd3, 0x2b, 0x94, 0x80, 0xc3, - 0x40, 0x53, 0x0e, 0x03, 0x54, 0x3d, 0x7b, 0x8b, - 0xce, 0xf9, 0xa4, 0x03, 0x27, 0x63, 0xec, 0x51, - 0x00, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, - 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x09, 0x00, 0xcc, 0x22, 0x4c, 0x4b, 0x98, - 0xa2, 0x88, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, - 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, - 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, - 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, - 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x30, - 0x35, 0x30, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x33, - 0x30, 0x35, 0x32, 0x34, 0x32, 0x31, 0x30, 0x35, - 0x30, 0x31, 0x5a, 0x30, 0x81, 0x86, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, - 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, - 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, - 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, - 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, - 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, - 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, - 0x02, 0x82, 0x01, 0x01, 0x00, 0xf0, 0xfb, 0xad, - 0x80, 0x5e, 0x37, 0xd3, 0x6d, 0xee, 0x2e, 0xcc, - 0xbc, 0x0c, 0xd7, 0x56, 0x4b, 0x56, 0x45, 0xcd, - 0x28, 0xb6, 0x22, 0xe9, 0xe2, 0x0f, 0xd1, 0x87, - 0x2a, 0x27, 0xce, 0x77, 0x8d, 0x6e, 0x0e, 0x0f, - 0xfb, 0x66, 0xe1, 0xb5, 0x0e, 0x9a, 0xb6, 0x05, - 0x8e, 0xb3, 0xe1, 0xc5, 0x77, 0x86, 0x5b, 0x46, - 0xd2, 0x0b, 0x92, 0x03, 0x1b, 0x89, 0x0c, 0x1b, - 0x10, 0x0e, 0x99, 0x8f, 0xe2, 0x17, 0xe8, 0xc2, - 0x30, 0x00, 0x47, 0xd6, 0xfc, 0xf9, 0x0f, 0x3b, - 0x75, 0x34, 0x8d, 0x4d, 0xb0, 0x99, 0xb7, 0xa0, - 0x6d, 0xa0, 0xb6, 0xad, 0xda, 0x07, 0x5e, 0x38, - 0x2e, 0x02, 0xe4, 0x30, 0x6d, 0xae, 0x13, 0x72, - 0xd4, 0xc8, 0xce, 0x14, 0x07, 0xae, 0x23, 0x8c, - 0x8f, 0x9e, 0x8c, 0x60, 0xd6, 0x06, 0xb9, 0xef, - 0x00, 0x18, 0xc0, 0x1d, 0x25, 0x1e, 0xda, 0x3e, - 0x2f, 0xcf, 0x2b, 0x56, 0x84, 0x9e, 0x30, 0x21, - 0xc7, 0x29, 0xf6, 0x03, 0x8a, 0x24, 0xf9, 0x34, - 0xac, 0x65, 0x9d, 0x80, 0x36, 0xc8, 0x3b, 0x15, - 0x10, 0xbd, 0x51, 0xe9, 0xbc, 0x02, 0xe1, 0xe9, - 0xb3, 0x5a, 0x9a, 0x99, 0x41, 0x1b, 0x27, 0xa0, - 0x4d, 0x50, 0x9e, 0x27, 0x7f, 0xa1, 0x7d, 0x09, - 0x87, 0xbd, 0x8a, 0xca, 0x5f, 0xb1, 0xa5, 0x08, - 0xb8, 0x04, 0xd4, 0x52, 0x89, 0xaa, 0xe0, 0x7d, - 0x42, 0x2e, 0x2f, 0x15, 0xee, 0x66, 0x57, 0x0f, - 0x13, 0x19, 0x45, 0xa8, 0x4b, 0x5d, 0x81, 0x66, - 0xcc, 0x12, 0x37, 0x94, 0x5e, 0xfd, 0x3c, 0x10, - 0x81, 0x51, 0x3f, 0xfa, 0x0f, 0xdd, 0xa1, 0x89, - 0x03, 0xa9, 0x78, 0x91, 0xf5, 0x3b, 0xf3, 0xbc, - 0xac, 0xbe, 0x93, 0x30, 0x2e, 0xbe, 0xca, 0x7f, - 0x46, 0xd3, 0x28, 0xb4, 0x4e, 0x91, 0x7b, 0x5b, - 0x43, 0x6c, 0xaf, 0x9b, 0x5c, 0x6a, 0x6d, 0x5a, - 0xdb, 0x79, 0x5e, 0x6a, 0x6b, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, 0x7d, - 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, 0x90, - 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, - 0x7d, 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, - 0x90, 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x0c, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, - 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0xcd, 0x6f, 0x73, 0x4d, 0x56, 0x0b, 0xf3, 0x2e, - 0x1c, 0xe2, 0x02, 0x0c, 0x14, 0xbb, 0x2f, 0xdd, - 0x3c, 0x43, 0xfe, 0xdf, 0x94, 0x2d, 0xa9, 0x89, - 0x81, 0x51, 0xf8, 0x5f, 0xa7, 0xa0, 0x13, 0xaa, - 0xcc, 0xb0, 0x18, 0xe2, 0x57, 0x3e, 0x0d, 0x29, - 0x93, 0xe8, 0x95, 0xd5, 0x1b, 0x53, 0xd2, 0x51, - 0xf2, 0xbd, 0xf5, 0x9e, 0x7b, 0x22, 0x65, 0x62, - 0x5c, 0xc4, 0x4c, 0x1d, 0xe8, 0xe9, 0xc3, 0xd4, - 0x2b, 0xe7, 0x78, 0xcb, 0x10, 0xf3, 0xfe, 0x06, - 0x83, 0xdc, 0x3a, 0x1e, 0x62, 0x10, 0xc0, 0x46, - 0x77, 0xc6, 0x9d, 0x9f, 0xab, 0x96, 0x25, 0x5c, - 0xfb, 0x26, 0xc1, 0x15, 0x1f, 0xa5, 0x33, 0xee, - 0x4f, 0x9a, 0x14, 0x6a, 0x14, 0x97, 0x93, 0x2b, - 0x95, 0x0b, 0xdc, 0xa8, 0xd7, 0x69, 0x2e, 0xf0, - 0x01, 0x0e, 0xfd, 0x4e, 0xd0, 0xd9, 0xa8, 0xe5, - 0x65, 0xde, 0xfb, 0xca, 0xca, 0x1c, 0x5f, 0xf9, - 0x53, 0xa0, 0x87, 0xe7, 0x33, 0x9b, 0x2f, 0xcf, - 0xe4, 0x13, 0xfc, 0xec, 0x7a, 0x6c, 0xb0, 0x90, - 0x13, 0x9b, 0xb6, 0xc5, 0x03, 0xf6, 0x0e, 0x5e, - 0xe2, 0xe4, 0x26, 0xc1, 0x7e, 0x53, 0xfe, 0x69, - 0xa3, 0xc7, 0xd8, 0x8e, 0x6e, 0x94, 0x32, 0xa0, - 0xde, 0xca, 0xb6, 0xcc, 0xd6, 0x01, 0xd5, 0x78, - 0x40, 0x28, 0x63, 0x9b, 0xee, 0xcf, 0x09, 0x3b, - 0x35, 0x04, 0xf0, 0x14, 0x02, 0xf6, 0x80, 0x0e, - 0x90, 0xb2, 0x94, 0xd2, 0x25, 0x16, 0xb8, 0x7a, - 0x76, 0x87, 0x84, 0x9f, 0x84, 0xc5, 0xaf, 0xc2, - 0x6d, 0x68, 0x7a, 0x84, 0x9c, 0xc6, 0x8a, 0x63, - 0x60, 0x87, 0x6a, 0x25, 0xc1, 0xa1, 0x78, 0x0f, - 0xba, 0xe8, 0x5f, 0xe1, 0xba, 0xac, 0xa4, 0x6f, - 0xdd, 0x09, 0x3f, 0x12, 0xcb, 0x1d, 0xf3, 0xcf, - 0x48, 0xd7, 0xd3, 0x26, 0xe8, 0x9c, 0xc3, 0x53, - 0xb3, 0xba, 0xdc, 0x32, 0x99, 0x98, 0x96, 0xd6, - 0x16, 0x03, 0x01, 0x01, 0x06, 0x10, 0x00, 0x01, - 0x02, 0x01, 0x00, 0x6e, 0xea, 0x15, 0x6f, 0x21, - 0xbd, 0x2d, 0x14, 0xde, 0x9d, 0x02, 0xeb, 0xdf, - 0x3b, 0x09, 0x75, 0xaf, 0x32, 0x80, 0x0c, 0xe2, - 0xc2, 0x7b, 0x0d, 0xca, 0x24, 0x96, 0xf6, 0x3e, - 0xa5, 0x97, 0xba, 0x0c, 0x50, 0x7e, 0xb3, 0x68, - 0x58, 0xc6, 0xd8, 0xec, 0xab, 0xa9, 0xd9, 0x3a, - 0xb1, 0x49, 0xea, 0x2f, 0xd7, 0xdb, 0x15, 0x1b, - 0xb5, 0xaf, 0xec, 0xcc, 0x40, 0x5c, 0xe6, 0x0f, - 0xc4, 0x33, 0x71, 0xe7, 0x41, 0xc0, 0x04, 0x89, - 0x60, 0x3e, 0xb7, 0xe6, 0xda, 0x38, 0x62, 0x27, - 0x6a, 0xd9, 0xfb, 0x93, 0x94, 0x9d, 0xc1, 0x63, - 0x92, 0x5c, 0x88, 0x19, 0x38, 0x81, 0x79, 0x9d, - 0x59, 0x48, 0x5e, 0xd3, 0xc8, 0xea, 0xcb, 0x6e, - 0x66, 0x66, 0x03, 0xdc, 0x0c, 0x2d, 0x95, 0xb1, - 0x4d, 0x68, 0xc7, 0xc5, 0x6e, 0xfa, 0x94, 0x14, - 0xdf, 0x2c, 0x70, 0x69, 0x04, 0xf4, 0x69, 0xf1, - 0xf0, 0x07, 0xbd, 0x23, 0x53, 0x63, 0xb3, 0x41, - 0xec, 0xa7, 0x10, 0xa5, 0x04, 0x84, 0x24, 0xb5, - 0xf5, 0x0c, 0x0f, 0x5d, 0x02, 0x47, 0x79, 0x60, - 0x76, 0xbb, 0xdf, 0x60, 0xa6, 0xd7, 0x4d, 0x08, - 0x7d, 0xa6, 0x85, 0x4f, 0x61, 0xac, 0x96, 0x3d, - 0xbc, 0xaf, 0x07, 0xb0, 0x7c, 0xb6, 0x23, 0x3e, - 0x1f, 0x0a, 0x62, 0x77, 0x97, 0x77, 0xae, 0x33, - 0x55, 0x0f, 0x85, 0xdf, 0xdc, 0xbe, 0xc6, 0xe0, - 0xe0, 0x14, 0x83, 0x4c, 0x50, 0xf0, 0xe5, 0x2d, - 0xdc, 0x0b, 0x74, 0x7f, 0xc3, 0x28, 0x98, 0x16, - 0xda, 0x74, 0xe6, 0x40, 0xc2, 0xf0, 0xea, 0xc0, - 0x00, 0xd5, 0xfc, 0x16, 0xe4, 0x43, 0xa1, 0xfc, - 0x31, 0x19, 0x81, 0x62, 0xec, 0x2b, 0xfe, 0xcc, - 0xe8, 0x19, 0xed, 0xa1, 0x1e, 0x6a, 0x49, 0x73, - 0xde, 0xc4, 0xe9, 0x22, 0x0a, 0x21, 0xde, 0x45, - 0x1e, 0x55, 0x12, 0xd9, 0x44, 0xef, 0x4e, 0xaa, - 0x5e, 0x26, 0x57, 0x16, 0x03, 0x01, 0x01, 0x06, - 0x0f, 0x00, 0x01, 0x02, 0x01, 0x00, 0x23, 0xde, - 0xb0, 0x39, 0x60, 0xe9, 0x82, 0xb8, 0xed, 0x17, - 0x78, 0xd2, 0x37, 0x0e, 0x85, 0x69, 0xda, 0xcc, - 0x9f, 0x54, 0x4d, 0xda, 0xce, 0xe8, 0x5a, 0xeb, - 0x3c, 0x61, 0x4c, 0x7a, 0x84, 0x1f, 0x21, 0x03, - 0xb3, 0x8a, 0x74, 0x3b, 0x6a, 0x9e, 0x4f, 0x44, - 0xd9, 0x75, 0x0a, 0xd8, 0x7e, 0x56, 0xa3, 0xef, - 0x5a, 0xfe, 0x8a, 0x35, 0xce, 0x29, 0x18, 0xfe, - 0xa6, 0x61, 0x8e, 0x8f, 0x00, 0x90, 0x2d, 0x85, - 0xe3, 0x6c, 0x0e, 0x8d, 0x8c, 0x27, 0x80, 0x8c, - 0x9f, 0x51, 0xe9, 0xd3, 0xe6, 0x7d, 0x70, 0xe9, - 0xfb, 0xcb, 0xb8, 0x24, 0x94, 0x30, 0x9b, 0xba, - 0x01, 0x14, 0x49, 0x9f, 0xaf, 0x09, 0xd8, 0x26, - 0x1b, 0x23, 0xa4, 0xb8, 0xd9, 0x44, 0x0a, 0xdc, - 0x4e, 0x27, 0xe7, 0x32, 0xf5, 0x9c, 0xf3, 0x8d, - 0xa0, 0xc5, 0xc4, 0xbe, 0x92, 0x02, 0x85, 0x4f, - 0x33, 0x8f, 0xa7, 0xf7, 0x87, 0xa9, 0x44, 0xf3, - 0x64, 0xbd, 0x32, 0x04, 0xeb, 0xc5, 0xc3, 0x62, - 0xe9, 0xda, 0x2f, 0x95, 0x5c, 0xf7, 0x58, 0x3e, - 0xad, 0x35, 0xd7, 0x7e, 0xad, 0xdd, 0x32, 0x8d, - 0xce, 0x81, 0x08, 0xad, 0x49, 0xf7, 0xdb, 0xf7, - 0xaf, 0xe3, 0xc6, 0xb2, 0xdd, 0x76, 0x0c, 0xcf, - 0x0f, 0x87, 0x79, 0x90, 0x10, 0x79, 0xc6, 0xc8, - 0x7b, 0xe6, 0x23, 0xf2, 0xda, 0x33, 0xca, 0xe1, - 0xf0, 0x59, 0x42, 0x43, 0x03, 0x56, 0x19, 0xe3, - 0x8b, 0xe6, 0xa8, 0x70, 0xbc, 0x80, 0xfa, 0x24, - 0xae, 0x03, 0x13, 0x30, 0x0d, 0x1f, 0xab, 0xb7, - 0x82, 0xd9, 0x24, 0x90, 0x80, 0xbf, 0x75, 0xe1, - 0x0d, 0x1c, 0xb2, 0xfe, 0x92, 0x2c, 0x4d, 0x21, - 0xe9, 0x5d, 0xa1, 0x68, 0xf3, 0x16, 0xd8, 0x3f, - 0xb2, 0xc3, 0x00, 0x3e, 0xd8, 0x42, 0x25, 0x5c, - 0x90, 0x11, 0xc0, 0x1b, 0xd4, 0x26, 0x5c, 0x37, - 0x47, 0xbd, 0xf8, 0x1e, 0x34, 0xa9, 0x14, 0x03, - 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, - 0x24, 0x8f, 0x94, 0x7e, 0x01, 0xee, 0xd5, 0x4f, - 0x83, 0x41, 0x31, 0xc0, 0x36, 0x81, 0x46, 0xc3, - 0xc0, 0xcc, 0x9c, 0xea, 0x0f, 0x29, 0x04, 0x10, - 0x43, 0x1e, 0x08, 0x6e, 0x08, 0xce, 0xb2, 0x62, - 0xa6, 0x0f, 0x68, 0x9f, 0x99, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0xd9, 0x46, 0x5b, 0xbf, 0xfd, - 0x8a, 0xa1, 0x08, 0xd5, 0xf3, 0x0c, 0x1c, 0xd8, - 0xa8, 0xb3, 0xe5, 0x89, 0x83, 0x9e, 0x23, 0x47, - 0x81, 0x66, 0x77, 0x11, 0x98, 0xe5, 0xf4, 0xac, - 0x06, 0xe9, 0x4c, 0x05, 0x8b, 0xc4, 0x16, - }, - { - 0x17, 0x03, 0x01, 0x00, 0x1a, 0xc5, 0x28, 0xfd, - 0x71, 0xc0, 0xe6, 0x89, 0xb8, 0x82, 0x92, 0x1b, - 0xdd, 0x39, 0xe5, 0xbf, 0x41, 0x82, 0x1f, 0xc1, - 0xbc, 0x85, 0xe5, 0x32, 0x1b, 0x93, 0x46, 0x15, - 0x03, 0x01, 0x00, 0x16, 0x1a, 0x8b, 0x10, 0x42, - 0x12, 0xb2, 0xbd, 0xd3, 0xf1, 0x74, 0x1f, 0xc2, - 0x10, 0x08, 0xc2, 0x79, 0x99, 0x2c, 0x55, 0xef, - 0x4a, 0xbd, - }, -} - -// $ openssl s_server -tls1_2 -cert server.crt -key server.key \ -// -cipher ECDHE-RSA-AES128-SHA -port 10443 -// $ go test -test.run "TestRunClient" -connect -ciphersuites=0xc013 \ -// -minversion=0x0303 -maxversion=0x0303 -var clientTLS12Script = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, - 0x54, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13, - 0x01, 0x00, 0x00, 0x29, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, - 0x0d, 0x00, 0x0a, 0x00, 0x08, 0x04, 0x01, 0x04, - 0x03, 0x02, 0x01, 0x02, 0x03, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x50, 0x03, 0x03, 0x52, 0x65, 0x67, 0xbd, 0xe8, - 0x72, 0x03, 0x6a, 0x52, 0x8d, 0x28, 0x2c, 0x9a, - 0x53, 0xff, 0xc2, 0xa1, 0x62, 0x5f, 0x54, 0xfb, - 0x73, 0x00, 0xcf, 0x4d, 0x28, 0x36, 0xc2, 0xee, - 0xfd, 0x78, 0xf0, 0x20, 0x6f, 0xbe, 0x49, 0xec, - 0x5b, 0x6f, 0xf9, 0x53, 0x42, 0x69, 0x0d, 0x6d, - 0x8b, 0x68, 0x2e, 0xca, 0x3c, 0x3c, 0x88, 0x9e, - 0x8b, 0xf9, 0x32, 0x65, 0x09, 0xd6, 0xa0, 0x7d, - 0xea, 0xc6, 0xd5, 0xc4, 0xc0, 0x13, 0x00, 0x00, - 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, - 0x02, 0x16, 0x03, 0x03, 0x02, 0x39, 0x0b, 0x00, - 0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, - 0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, - 0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, - 0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, - 0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, - 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, - 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, - 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, - 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, - 0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, - 0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, - 0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, - 0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, - 0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, - 0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, - 0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, - 0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, - 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, - 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, - 0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, - 0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, - 0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, - 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, - 0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, - 0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, - 0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, - 0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, - 0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, - 0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, - 0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, - 0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, - 0x03, 0x03, 0x00, 0x8d, 0x0c, 0x00, 0x00, 0x89, - 0x03, 0x00, 0x17, 0x41, 0x04, 0x48, 0x93, 0x62, - 0x6a, 0xf8, 0x7c, 0x94, 0xcc, 0xcc, 0x0a, 0x9b, - 0x5e, 0x11, 0xad, 0x0b, 0x30, 0xc4, 0x5d, 0xf7, - 0x63, 0x24, 0xc1, 0xb0, 0x40, 0x5f, 0xff, 0x9f, - 0x0d, 0x7e, 0xd5, 0xa5, 0xd0, 0x4f, 0x80, 0x16, - 0xa8, 0x66, 0x18, 0x31, 0x1f, 0x81, 0xb2, 0x9a, - 0x41, 0x62, 0x5b, 0xcf, 0x73, 0xac, 0x4a, 0x64, - 0xb5, 0xc1, 0x46, 0x4d, 0x8a, 0xac, 0x25, 0xba, - 0x81, 0x7f, 0xbe, 0x64, 0x68, 0x04, 0x01, 0x00, - 0x40, 0x4e, 0x3f, 0x1e, 0x04, 0x4c, 0xef, 0xd2, - 0xa6, 0x82, 0xe6, 0x7c, 0x76, 0x23, 0x17, 0xb9, - 0xe7, 0x52, 0x15, 0x6b, 0x3d, 0xb2, 0xb1, 0x17, - 0x7d, 0xe6, 0xde, 0x06, 0x87, 0x30, 0xb0, 0xb5, - 0x57, 0xae, 0xdf, 0xb2, 0xdc, 0x8d, 0xab, 0x76, - 0x9c, 0xaa, 0x45, 0x6d, 0x23, 0x5d, 0xc1, 0xa8, - 0x7b, 0x79, 0x79, 0xb1, 0x3c, 0xdc, 0xf5, 0x33, - 0x2c, 0xa1, 0x62, 0x3e, 0xbd, 0xf5, 0x5d, 0x6c, - 0x87, 0x16, 0x03, 0x03, 0x00, 0x04, 0x0e, 0x00, - 0x00, 0x00, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x46, 0x10, 0x00, 0x00, - 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, - 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, - 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, - 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, - 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, - 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, - 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, - 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, - 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x03, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x03, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x17, - 0x54, 0x51, 0xb6, 0x1d, 0x8e, 0xe4, 0x6b, 0xed, - 0x5b, 0xa1, 0x27, 0x7f, 0xdc, 0xa9, 0xa5, 0xcf, - 0x38, 0xe6, 0x5d, 0x17, 0x34, 0xf9, 0xc0, 0x07, - 0xb8, 0xbe, 0x56, 0xe6, 0xd6, 0x6a, 0xb6, 0x26, - 0x4e, 0x45, 0x8d, 0x48, 0xe9, 0xc6, 0xb1, 0xa1, - 0xea, 0xdc, 0xb1, 0x37, 0xd9, 0xf6, - }, - { - 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x03, 0x00, 0x40, 0x00, 0x68, 0xc5, 0x27, 0xd5, - 0x3d, 0xba, 0x04, 0xde, 0x63, 0xf1, 0x5b, 0xc3, - 0x86, 0xb9, 0x82, 0xc7, 0xb3, 0x90, 0x31, 0xea, - 0x15, 0xe1, 0x42, 0x76, 0x7d, 0x90, 0xcb, 0xc9, - 0xd1, 0x05, 0xe6, 0x8c, 0x76, 0xc7, 0x9a, 0x35, - 0x67, 0xa2, 0x70, 0x9a, 0x8a, 0x6c, 0xb5, 0x6b, - 0xc7, 0x87, 0xf3, 0x65, 0x0a, 0xa0, 0x98, 0xba, - 0x57, 0xbb, 0x31, 0x7b, 0x1f, 0x1a, 0xf7, 0x2a, - 0xf3, 0x12, 0xf6, - }, - { - 0x17, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x80, - 0x54, 0x1e, 0x72, 0xd3, 0x1a, 0x86, 0x1c, 0xc4, - 0x4a, 0x9b, 0xd4, 0x80, 0xd2, 0x03, 0x35, 0x0d, - 0xe4, 0x12, 0xc2, 0x3d, 0x79, 0x4a, 0x2c, 0xba, - 0xc2, 0xad, 0xf3, 0xd2, 0x16, 0x15, 0x03, 0x03, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x9b, 0x68, 0x78, 0x92, 0x28, - 0x62, 0x02, 0x65, 0x87, 0x90, 0xe4, 0x32, 0xd7, - 0x72, 0x08, 0x70, 0xb8, 0x52, 0x32, 0x1f, 0x97, - 0xd4, 0x6a, 0xc6, 0x28, 0x83, 0xb0, 0x1d, 0x6e, - 0x16, 0xd5, - }, -} - -// $ openssl s_server -tls1_2 -cert server.crt -key server.key \ -// -port 10443 -verify 0 -// $ go test -test.run "TestRunClient" -connect -ciphersuites=0xc02f \ -// -maxversion=0x0303 -var clientTLS12ClientCertScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, - 0x54, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x2f, - 0x01, 0x00, 0x00, 0x29, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, - 0x0d, 0x00, 0x0a, 0x00, 0x08, 0x04, 0x01, 0x04, - 0x03, 0x02, 0x01, 0x02, 0x03, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x50, 0x03, 0x03, 0x52, 0x65, 0x67, 0xe0, 0xe8, - 0xf1, 0x13, 0x2a, 0x83, 0x28, 0xa8, 0x2e, 0x76, - 0x69, 0xe6, 0x89, 0x55, 0x6c, 0x48, 0x49, 0x2e, - 0x00, 0xf6, 0x87, 0x6c, 0x13, 0xa1, 0xd4, 0xaa, - 0xd0, 0x76, 0x3b, 0x20, 0xe4, 0xd6, 0x5b, 0x1d, - 0x11, 0xf2, 0x42, 0xf2, 0x82, 0x0c, 0x0d, 0x66, - 0x6d, 0xec, 0x52, 0xf8, 0x4a, 0xd9, 0x45, 0xcf, - 0xe4, 0x4a, 0xba, 0x8b, 0xf1, 0xab, 0x55, 0xe4, - 0x57, 0x18, 0xa9, 0x36, 0xc0, 0x2f, 0x00, 0x00, - 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, - 0x02, 0x16, 0x03, 0x03, 0x02, 0x39, 0x0b, 0x00, - 0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, - 0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, - 0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, - 0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, - 0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, - 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, - 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, - 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, - 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, - 0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, - 0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, - 0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, - 0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, - 0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, - 0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, - 0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, - 0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, - 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, - 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, - 0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, - 0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, - 0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, - 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, - 0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, - 0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, - 0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, - 0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, - 0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, - 0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, - 0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, - 0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, - 0x03, 0x03, 0x00, 0x8d, 0x0c, 0x00, 0x00, 0x89, - 0x03, 0x00, 0x17, 0x41, 0x04, 0xaa, 0xf0, 0x0c, - 0xa3, 0x60, 0xcf, 0x69, 0x1e, 0xad, 0x16, 0x9a, - 0x01, 0x40, 0xc6, 0x22, 0xc4, 0xbb, 0x06, 0x3b, - 0x84, 0x65, 0xea, 0xc7, 0xa2, 0x96, 0x79, 0x17, - 0x2f, 0xc7, 0xbe, 0x56, 0x39, 0xe4, 0x79, 0xf3, - 0xad, 0x17, 0xf3, 0x7e, 0xe2, 0x7b, 0xa2, 0x6f, - 0x3f, 0x96, 0xea, 0xe5, 0x0e, 0xea, 0x39, 0x79, - 0x77, 0xeb, 0x14, 0x18, 0xbb, 0x7c, 0x95, 0xda, - 0xa7, 0x51, 0x09, 0xba, 0xd7, 0x04, 0x01, 0x00, - 0x40, 0x82, 0x3e, 0xce, 0xee, 0x7e, 0xba, 0x3b, - 0x51, 0xb1, 0xba, 0x71, 0x2e, 0x54, 0xa9, 0xb9, - 0xe2, 0xb1, 0x59, 0x17, 0xa1, 0xac, 0x76, 0xb4, - 0x4e, 0xf1, 0xae, 0x65, 0x17, 0x2b, 0x43, 0x06, - 0x31, 0x29, 0x0b, 0xa0, 0x1e, 0xb6, 0xfa, 0x35, - 0xe8, 0x63, 0x06, 0xde, 0x13, 0x89, 0x83, 0x69, - 0x3b, 0xc2, 0x15, 0x73, 0x1c, 0xc5, 0x07, 0xe9, - 0x38, 0x9b, 0x06, 0x81, 0x1b, 0x97, 0x7c, 0xa6, - 0x89, 0x16, 0x03, 0x03, 0x00, 0x30, 0x0d, 0x00, - 0x00, 0x28, 0x03, 0x01, 0x02, 0x40, 0x00, 0x20, - 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, - 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, - 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, - 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x03, 0x0a, 0xfb, 0x0b, 0x00, 0x0a, - 0xf7, 0x00, 0x0a, 0xf4, 0x00, 0x03, 0x7e, 0x30, - 0x82, 0x03, 0x7a, 0x30, 0x82, 0x02, 0x62, 0x02, - 0x09, 0x00, 0xb4, 0x47, 0x58, 0x57, 0x2b, 0x67, - 0xc8, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, 0x11, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, - 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, 0x20, 0x43, - 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, 0x61, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, - 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, - 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, - 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x34, - 0x34, 0x30, 0x30, 0x5a, 0x30, 0x7d, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x08, 0x4e, 0x65, - 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x31, 0x11, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, - 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x79, 0x20, 0x4c, - 0x65, 0x61, 0x66, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x6d, 0x79, - 0x6c, 0x65, 0x61, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, - 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, - 0x82, 0x01, 0x01, 0x00, 0xa0, 0xa3, 0xef, 0xc1, - 0x44, 0x7d, 0xa2, 0xe3, 0x71, 0x98, 0x27, 0x63, - 0xb3, 0x1d, 0x71, 0x50, 0xa6, 0x34, 0x15, 0xcb, - 0xc9, 0x2a, 0xc3, 0xea, 0xe4, 0x9e, 0x9c, 0x49, - 0xa6, 0x01, 0x9b, 0x7e, 0xa9, 0xb5, 0x7a, 0xff, - 0x15, 0x92, 0x71, 0xc8, 0x97, 0x9c, 0x25, 0xb7, - 0x79, 0x2b, 0xff, 0xab, 0xc6, 0xb1, 0xa7, 0x00, - 0x90, 0xb2, 0x8b, 0xd7, 0x71, 0xd5, 0xc2, 0x3a, - 0xe6, 0x82, 0x42, 0x37, 0x89, 0x41, 0x04, 0xb0, - 0xba, 0xc7, 0x5b, 0x8a, 0x43, 0x9f, 0x97, 0x39, - 0x0c, 0x0f, 0xd5, 0x6d, 0x9e, 0x8d, 0xeb, 0xc0, - 0x26, 0xc5, 0x18, 0xe8, 0x7a, 0x3d, 0x32, 0x2e, - 0x38, 0x90, 0x40, 0x5b, 0x39, 0x2c, 0x07, 0xcb, - 0x24, 0x10, 0xc5, 0xc9, 0x3b, 0xe3, 0x66, 0x47, - 0x57, 0xb9, 0x6a, 0xad, 0x44, 0xf8, 0xd0, 0x70, - 0x62, 0x3b, 0x8e, 0xed, 0x60, 0x5f, 0x22, 0xf8, - 0xb8, 0x0c, 0xc9, 0x41, 0x2b, 0xc9, 0x80, 0x6e, - 0x4e, 0x1b, 0xe1, 0x20, 0xfc, 0x47, 0xa4, 0xac, - 0xc3, 0x3f, 0xe6, 0xc2, 0x81, 0x79, 0x03, 0x37, - 0x25, 0x89, 0xca, 0xd6, 0xa5, 0x46, 0x91, 0x63, - 0x41, 0xc5, 0x3e, 0xd5, 0xed, 0x7f, 0x4f, 0x8d, - 0x06, 0xc0, 0x89, 0x00, 0xbe, 0x37, 0x7b, 0x7e, - 0x73, 0xca, 0x70, 0x00, 0x14, 0x34, 0xbe, 0x47, - 0xbc, 0xb2, 0x6a, 0x28, 0xa5, 0x29, 0x84, 0xa8, - 0x9d, 0xc8, 0x1e, 0x77, 0x66, 0x1f, 0x9f, 0xaa, - 0x2b, 0x47, 0xdb, 0xdd, 0x6b, 0x9c, 0xa8, 0xfc, - 0x82, 0x36, 0x94, 0x62, 0x0d, 0x5c, 0x3f, 0xb2, - 0x01, 0xb4, 0xa5, 0xb8, 0xc6, 0x0e, 0x94, 0x5b, - 0xec, 0x5e, 0xbb, 0x7a, 0x63, 0x24, 0xf1, 0xf9, - 0xd6, 0x50, 0x08, 0xc1, 0xa3, 0xcc, 0x90, 0x07, - 0x5b, 0x04, 0x04, 0x42, 0x74, 0xcf, 0x37, 0xfa, - 0xf0, 0xa5, 0xd9, 0xd3, 0x86, 0x89, 0x89, 0x18, - 0xf3, 0x4c, 0xe2, 0x11, 0x02, 0x03, 0x01, 0x00, - 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x90, 0xbb, 0xf9, - 0x5e, 0xba, 0x17, 0x1f, 0xac, 0x21, 0x9f, 0x6b, - 0x4a, 0x46, 0xd0, 0x6d, 0x3c, 0x8f, 0x3d, 0xf8, - 0x5e, 0x3e, 0x72, 0xaf, 0xa0, 0x1a, 0xf3, 0xff, - 0x89, 0xac, 0x5b, 0x7a, 0xe2, 0x91, 0x2a, 0x23, - 0x85, 0xc6, 0x4d, 0x47, 0x67, 0x01, 0x08, 0xa8, - 0x05, 0x1d, 0x01, 0x60, 0x50, 0x5f, 0x59, 0xad, - 0xfe, 0x7b, 0xc6, 0x0c, 0x54, 0x90, 0x68, 0x70, - 0x67, 0x2e, 0xed, 0x87, 0xf8, 0x69, 0x8a, 0xac, - 0x32, 0xfe, 0x6f, 0x90, 0x19, 0x2a, 0x64, 0x8d, - 0x82, 0x66, 0x05, 0x43, 0x88, 0xee, 0xf2, 0x30, - 0xed, 0xa4, 0x8f, 0xbf, 0xd6, 0x57, 0x20, 0xd4, - 0x43, 0x1d, 0x52, 0x96, 0x6f, 0xae, 0x09, 0x96, - 0x01, 0x52, 0x38, 0xe3, 0xaf, 0x99, 0xd7, 0xdc, - 0x14, 0x99, 0xc4, 0x8b, 0x0e, 0x04, 0x0f, 0xb3, - 0x14, 0x14, 0xd4, 0xa5, 0x93, 0xe1, 0xc9, 0x8a, - 0x81, 0xef, 0x63, 0xfc, 0x36, 0x77, 0x05, 0x06, - 0xf0, 0x2a, 0x04, 0x0a, 0xbe, 0x2e, 0xce, 0x81, - 0x3d, 0x23, 0xa1, 0xda, 0xd8, 0xeb, 0xc6, 0xea, - 0x5e, 0xcf, 0x28, 0x36, 0x51, 0x31, 0x95, 0x5e, - 0x40, 0x04, 0xed, 0xac, 0xc1, 0xc8, 0x56, 0x69, - 0x87, 0xec, 0x3b, 0x03, 0x3e, 0x9d, 0x0f, 0x4c, - 0x4c, 0xeb, 0xd7, 0xba, 0x26, 0xdf, 0xe3, 0xde, - 0x10, 0xee, 0x93, 0x62, 0x8d, 0x73, 0x52, 0x6e, - 0xff, 0x37, 0x36, 0x98, 0x7b, 0x2d, 0x56, 0x4c, - 0xba, 0x09, 0xb8, 0xa7, 0xf0, 0x3b, 0x16, 0x81, - 0xca, 0xdb, 0x43, 0xab, 0xec, 0x4c, 0x6e, 0x7c, - 0xc1, 0x0b, 0x22, 0x22, 0x43, 0x1d, 0xb6, 0x0c, - 0xc1, 0xb9, 0xcf, 0xe4, 0x53, 0xee, 0x1d, 0x3e, - 0x88, 0xa7, 0x13, 0xbe, 0x7f, 0xbd, 0xae, 0x72, - 0xcf, 0xcd, 0x63, 0xd2, 0xc3, 0x18, 0x58, 0x92, - 0xa2, 0xad, 0xb5, 0x09, 0x9d, 0x91, 0x03, 0xdd, - 0x3c, 0xe2, 0x1c, 0xde, 0x78, 0x00, 0x03, 0x88, - 0x30, 0x82, 0x03, 0x84, 0x30, 0x82, 0x02, 0x6c, - 0x02, 0x09, 0x00, 0xab, 0xed, 0xa6, 0xe4, 0x4a, - 0x2b, 0x2b, 0xf8, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, - 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, - 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, - 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, - 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x31, - 0x38, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, - 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x31, 0x38, - 0x34, 0x30, 0x5a, 0x30, 0x81, 0x80, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, - 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, - 0x6c, 0x79, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, - 0x20, 0x43, 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, - 0x61, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, - 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, - 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xce, - 0x13, 0xf0, 0x72, 0xb0, 0x61, 0xc8, 0x18, 0x37, - 0x8a, 0x41, 0x3d, 0x20, 0xa1, 0x1c, 0xcb, 0xbf, - 0xf6, 0x3b, 0x74, 0x26, 0x2a, 0x96, 0x11, 0xec, - 0x53, 0xa1, 0xcc, 0x7d, 0x77, 0x56, 0x45, 0x0f, - 0x36, 0xb7, 0xf2, 0x48, 0x92, 0x1a, 0x62, 0xcc, - 0xb6, 0xc0, 0xa1, 0x2f, 0x44, 0x2b, 0xc1, 0x89, - 0xcb, 0x6e, 0x1e, 0xdb, 0x57, 0x92, 0xd5, 0x97, - 0x60, 0x8c, 0x41, 0x2c, 0xd9, 0x20, 0xfe, 0xe9, - 0x1f, 0x8e, 0xfc, 0x7f, 0x02, 0x44, 0x0f, 0x28, - 0x81, 0xd6, 0x0c, 0xcd, 0xbc, 0xf0, 0x57, 0x6c, - 0xcc, 0xa7, 0xba, 0x06, 0xa0, 0xa6, 0x91, 0xda, - 0xef, 0x46, 0x8a, 0x60, 0x0f, 0x52, 0x6c, 0x90, - 0x6c, 0x8c, 0x44, 0xaf, 0xb0, 0x9d, 0x90, 0xba, - 0x21, 0x58, 0xa0, 0x3c, 0xee, 0x54, 0xb5, 0x29, - 0x26, 0x1f, 0x0a, 0xac, 0xef, 0x48, 0x68, 0x33, - 0xd0, 0x33, 0xd0, 0x8b, 0x1a, 0xec, 0x6e, 0x2f, - 0xb5, 0x4a, 0x53, 0xc2, 0x1a, 0xd2, 0xf1, 0x50, - 0x05, 0x59, 0x5c, 0xd9, 0xda, 0x03, 0x0a, 0x47, - 0xb7, 0xdd, 0xf7, 0x3a, 0x69, 0xf5, 0x4e, 0xea, - 0x4a, 0xc2, 0xca, 0x54, 0xb0, 0x8b, 0x76, 0xe1, - 0x02, 0x2d, 0x52, 0x67, 0xb9, 0xdd, 0x50, 0xc9, - 0x3b, 0x07, 0x24, 0x22, 0x6a, 0x00, 0x1d, 0x58, - 0x83, 0xa8, 0xec, 0x95, 0xf1, 0xda, 0xe2, 0x73, - 0xa0, 0xa1, 0x72, 0x60, 0x9e, 0x86, 0x53, 0xcb, - 0x45, 0xa8, 0xc2, 0xa0, 0x50, 0xa0, 0x53, 0xd6, - 0xfc, 0x18, 0x84, 0xb5, 0x4a, 0x26, 0xd0, 0xa2, - 0xaa, 0xd0, 0xff, 0xb6, 0xfe, 0x3a, 0x9c, 0xb5, - 0x19, 0x3b, 0x3f, 0xe1, 0x48, 0x0d, 0xa4, 0x09, - 0x4f, 0x83, 0xc9, 0xc0, 0xc9, 0xa6, 0x0b, 0x58, - 0x1f, 0x1c, 0x7b, 0xac, 0xa2, 0x42, 0xbc, 0x61, - 0xf4, 0x21, 0x8a, 0x00, 0xda, 0x14, 0xa0, 0x60, - 0x03, 0xfe, 0x93, 0x12, 0x6c, 0x56, 0xcd, 0x02, - 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0x25, 0x29, 0x3b, 0x1e, 0xc3, 0x58, 0x32, 0xe6, - 0x23, 0xc8, 0xee, 0x18, 0xf0, 0x1d, 0x62, 0x6d, - 0x3b, 0x59, 0x99, 0x3a, 0xfe, 0x49, 0x72, 0x07, - 0x3f, 0x58, 0x93, 0xdb, 0xc0, 0xaf, 0xb0, 0xb3, - 0x5c, 0xd1, 0x5c, 0x98, 0xc8, 0xea, 0x4a, 0xe4, - 0x58, 0x73, 0x0d, 0x57, 0xc5, 0x13, 0x7c, 0x5c, - 0x79, 0x66, 0xda, 0x04, 0x1d, 0xe5, 0x98, 0xda, - 0x35, 0x47, 0x44, 0xb0, 0xd2, 0x7a, 0x66, 0x9d, - 0xcd, 0x41, 0xa5, 0x8f, 0xa1, 0x11, 0xb2, 0x1a, - 0x87, 0xc0, 0xcd, 0x55, 0xed, 0xb4, 0x7b, 0x33, - 0x72, 0xeb, 0xf7, 0xe3, 0x7b, 0x8b, 0x02, 0x86, - 0xe9, 0x2b, 0x26, 0x32, 0x9f, 0x99, 0xf1, 0xcb, - 0x93, 0xab, 0xb9, 0x16, 0xb3, 0x9a, 0xb2, 0x22, - 0x13, 0x21, 0x1f, 0x5b, 0xcc, 0xa2, 0x59, 0xbb, - 0x69, 0xf2, 0xb8, 0x07, 0x80, 0xce, 0x0c, 0xf7, - 0x98, 0x4c, 0x85, 0xc2, 0x96, 0x6a, 0x22, 0x05, - 0xe9, 0xbe, 0x48, 0xb0, 0x02, 0x5b, 0x69, 0x28, - 0x18, 0x88, 0x96, 0xe3, 0xd7, 0xc6, 0x7a, 0xd3, - 0xe9, 0x99, 0xff, 0x9d, 0xc3, 0x61, 0x4d, 0x9a, - 0x96, 0xf2, 0xc6, 0x33, 0x4d, 0xe5, 0x5d, 0x5a, - 0x68, 0x64, 0x5a, 0x82, 0x35, 0x65, 0x25, 0xe3, - 0x8c, 0x5b, 0xb0, 0xf6, 0x96, 0x56, 0xbc, 0xbf, - 0x97, 0x76, 0x4b, 0x66, 0x44, 0x81, 0xa4, 0xc4, - 0xa7, 0x31, 0xc5, 0xa1, 0x4f, 0xe8, 0xa4, 0xca, - 0x20, 0xf5, 0x01, 0x5b, 0x99, 0x4f, 0x5a, 0xf4, - 0xf0, 0x78, 0xbf, 0x71, 0x49, 0xd5, 0xf1, 0xc1, - 0xa2, 0x18, 0xfd, 0x72, 0x5b, 0x16, 0xe8, 0x92, - 0xc7, 0x37, 0x48, 0xaf, 0xee, 0x24, 0xfc, 0x35, - 0x0b, 0xc2, 0xdd, 0x05, 0xc7, 0x6e, 0xa3, 0x29, - 0xbb, 0x29, 0x7d, 0xd3, 0x2b, 0x94, 0x80, 0xc3, - 0x40, 0x53, 0x0e, 0x03, 0x54, 0x3d, 0x7b, 0x8b, - 0xce, 0xf9, 0xa4, 0x03, 0x27, 0x63, 0xec, 0x51, - 0x00, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, - 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x09, 0x00, 0xcc, 0x22, 0x4c, 0x4b, 0x98, - 0xa2, 0x88, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, - 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, - 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, - 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, - 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x30, - 0x35, 0x30, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x33, - 0x30, 0x35, 0x32, 0x34, 0x32, 0x31, 0x30, 0x35, - 0x30, 0x31, 0x5a, 0x30, 0x81, 0x86, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, - 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, - 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, - 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, - 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, - 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, - 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, - 0x02, 0x82, 0x01, 0x01, 0x00, 0xf0, 0xfb, 0xad, - 0x80, 0x5e, 0x37, 0xd3, 0x6d, 0xee, 0x2e, 0xcc, - 0xbc, 0x0c, 0xd7, 0x56, 0x4b, 0x56, 0x45, 0xcd, - 0x28, 0xb6, 0x22, 0xe9, 0xe2, 0x0f, 0xd1, 0x87, - 0x2a, 0x27, 0xce, 0x77, 0x8d, 0x6e, 0x0e, 0x0f, - 0xfb, 0x66, 0xe1, 0xb5, 0x0e, 0x9a, 0xb6, 0x05, - 0x8e, 0xb3, 0xe1, 0xc5, 0x77, 0x86, 0x5b, 0x46, - 0xd2, 0x0b, 0x92, 0x03, 0x1b, 0x89, 0x0c, 0x1b, - 0x10, 0x0e, 0x99, 0x8f, 0xe2, 0x17, 0xe8, 0xc2, - 0x30, 0x00, 0x47, 0xd6, 0xfc, 0xf9, 0x0f, 0x3b, - 0x75, 0x34, 0x8d, 0x4d, 0xb0, 0x99, 0xb7, 0xa0, - 0x6d, 0xa0, 0xb6, 0xad, 0xda, 0x07, 0x5e, 0x38, - 0x2e, 0x02, 0xe4, 0x30, 0x6d, 0xae, 0x13, 0x72, - 0xd4, 0xc8, 0xce, 0x14, 0x07, 0xae, 0x23, 0x8c, - 0x8f, 0x9e, 0x8c, 0x60, 0xd6, 0x06, 0xb9, 0xef, - 0x00, 0x18, 0xc0, 0x1d, 0x25, 0x1e, 0xda, 0x3e, - 0x2f, 0xcf, 0x2b, 0x56, 0x84, 0x9e, 0x30, 0x21, - 0xc7, 0x29, 0xf6, 0x03, 0x8a, 0x24, 0xf9, 0x34, - 0xac, 0x65, 0x9d, 0x80, 0x36, 0xc8, 0x3b, 0x15, - 0x10, 0xbd, 0x51, 0xe9, 0xbc, 0x02, 0xe1, 0xe9, - 0xb3, 0x5a, 0x9a, 0x99, 0x41, 0x1b, 0x27, 0xa0, - 0x4d, 0x50, 0x9e, 0x27, 0x7f, 0xa1, 0x7d, 0x09, - 0x87, 0xbd, 0x8a, 0xca, 0x5f, 0xb1, 0xa5, 0x08, - 0xb8, 0x04, 0xd4, 0x52, 0x89, 0xaa, 0xe0, 0x7d, - 0x42, 0x2e, 0x2f, 0x15, 0xee, 0x66, 0x57, 0x0f, - 0x13, 0x19, 0x45, 0xa8, 0x4b, 0x5d, 0x81, 0x66, - 0xcc, 0x12, 0x37, 0x94, 0x5e, 0xfd, 0x3c, 0x10, - 0x81, 0x51, 0x3f, 0xfa, 0x0f, 0xdd, 0xa1, 0x89, - 0x03, 0xa9, 0x78, 0x91, 0xf5, 0x3b, 0xf3, 0xbc, - 0xac, 0xbe, 0x93, 0x30, 0x2e, 0xbe, 0xca, 0x7f, - 0x46, 0xd3, 0x28, 0xb4, 0x4e, 0x91, 0x7b, 0x5b, - 0x43, 0x6c, 0xaf, 0x9b, 0x5c, 0x6a, 0x6d, 0x5a, - 0xdb, 0x79, 0x5e, 0x6a, 0x6b, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, 0x7d, - 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, 0x90, - 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, - 0x7d, 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, - 0x90, 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x0c, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, - 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0xcd, 0x6f, 0x73, 0x4d, 0x56, 0x0b, 0xf3, 0x2e, - 0x1c, 0xe2, 0x02, 0x0c, 0x14, 0xbb, 0x2f, 0xdd, - 0x3c, 0x43, 0xfe, 0xdf, 0x94, 0x2d, 0xa9, 0x89, - 0x81, 0x51, 0xf8, 0x5f, 0xa7, 0xa0, 0x13, 0xaa, - 0xcc, 0xb0, 0x18, 0xe2, 0x57, 0x3e, 0x0d, 0x29, - 0x93, 0xe8, 0x95, 0xd5, 0x1b, 0x53, 0xd2, 0x51, - 0xf2, 0xbd, 0xf5, 0x9e, 0x7b, 0x22, 0x65, 0x62, - 0x5c, 0xc4, 0x4c, 0x1d, 0xe8, 0xe9, 0xc3, 0xd4, - 0x2b, 0xe7, 0x78, 0xcb, 0x10, 0xf3, 0xfe, 0x06, - 0x83, 0xdc, 0x3a, 0x1e, 0x62, 0x10, 0xc0, 0x46, - 0x77, 0xc6, 0x9d, 0x9f, 0xab, 0x96, 0x25, 0x5c, - 0xfb, 0x26, 0xc1, 0x15, 0x1f, 0xa5, 0x33, 0xee, - 0x4f, 0x9a, 0x14, 0x6a, 0x14, 0x97, 0x93, 0x2b, - 0x95, 0x0b, 0xdc, 0xa8, 0xd7, 0x69, 0x2e, 0xf0, - 0x01, 0x0e, 0xfd, 0x4e, 0xd0, 0xd9, 0xa8, 0xe5, - 0x65, 0xde, 0xfb, 0xca, 0xca, 0x1c, 0x5f, 0xf9, - 0x53, 0xa0, 0x87, 0xe7, 0x33, 0x9b, 0x2f, 0xcf, - 0xe4, 0x13, 0xfc, 0xec, 0x7a, 0x6c, 0xb0, 0x90, - 0x13, 0x9b, 0xb6, 0xc5, 0x03, 0xf6, 0x0e, 0x5e, - 0xe2, 0xe4, 0x26, 0xc1, 0x7e, 0x53, 0xfe, 0x69, - 0xa3, 0xc7, 0xd8, 0x8e, 0x6e, 0x94, 0x32, 0xa0, - 0xde, 0xca, 0xb6, 0xcc, 0xd6, 0x01, 0xd5, 0x78, - 0x40, 0x28, 0x63, 0x9b, 0xee, 0xcf, 0x09, 0x3b, - 0x35, 0x04, 0xf0, 0x14, 0x02, 0xf6, 0x80, 0x0e, - 0x90, 0xb2, 0x94, 0xd2, 0x25, 0x16, 0xb8, 0x7a, - 0x76, 0x87, 0x84, 0x9f, 0x84, 0xc5, 0xaf, 0xc2, - 0x6d, 0x68, 0x7a, 0x84, 0x9c, 0xc6, 0x8a, 0x63, - 0x60, 0x87, 0x6a, 0x25, 0xc1, 0xa1, 0x78, 0x0f, - 0xba, 0xe8, 0x5f, 0xe1, 0xba, 0xac, 0xa4, 0x6f, - 0xdd, 0x09, 0x3f, 0x12, 0xcb, 0x1d, 0xf3, 0xcf, - 0x48, 0xd7, 0xd3, 0x26, 0xe8, 0x9c, 0xc3, 0x53, - 0xb3, 0xba, 0xdc, 0x32, 0x99, 0x98, 0x96, 0xd6, - 0x16, 0x03, 0x03, 0x00, 0x46, 0x10, 0x00, 0x00, - 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, - 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, - 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, - 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, - 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, - 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, - 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, - 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, - 0xdc, 0x5a, 0x89, 0x16, 0x03, 0x03, 0x01, 0x08, - 0x0f, 0x00, 0x01, 0x04, 0x04, 0x01, 0x01, 0x00, - 0x7e, 0xe4, 0x65, 0x02, 0x8e, 0xb3, 0x34, 0x6a, - 0x47, 0x71, 0xd1, 0xb0, 0x8d, 0x3c, 0x0c, 0xe1, - 0xde, 0x7e, 0x5f, 0xb4, 0x15, 0x2d, 0x32, 0x0a, - 0x2a, 0xdb, 0x9b, 0x40, 0xba, 0xce, 0x8b, 0xf5, - 0x74, 0xc1, 0x68, 0x20, 0x7c, 0x87, 0x23, 0x13, - 0xc3, 0x13, 0xa7, 0xdb, 0xec, 0x59, 0xa0, 0x40, - 0x9e, 0x64, 0x03, 0x60, 0xac, 0x76, 0xff, 0x01, - 0x34, 0x7b, 0x32, 0x26, 0xd9, 0x41, 0x31, 0x93, - 0xaa, 0x30, 0x51, 0x83, 0x85, 0x40, 0xeb, 0x4e, - 0x66, 0x39, 0x83, 0xb1, 0x30, 0x0d, 0x96, 0x01, - 0xee, 0x81, 0x53, 0x5e, 0xec, 0xa9, 0xc9, 0xdf, - 0x7e, 0xc1, 0x09, 0x47, 0x8b, 0x35, 0xdb, 0x10, - 0x15, 0xd4, 0xc7, 0x5a, 0x39, 0xe3, 0xc0, 0xf3, - 0x93, 0x38, 0x11, 0xdc, 0x71, 0xbb, 0xc7, 0x62, - 0x2b, 0x85, 0xad, 0x6b, 0x4f, 0x09, 0xb3, 0x31, - 0xa8, 0xe5, 0xd1, 0xb3, 0xa9, 0x21, 0x37, 0x50, - 0xc8, 0x7d, 0xc3, 0xd2, 0xf7, 0x00, 0xd3, 0xdb, - 0x0f, 0x82, 0xf2, 0x43, 0xcf, 0x36, 0x6c, 0x98, - 0x63, 0xd8, 0x1d, 0xb3, 0xf3, 0xde, 0x63, 0x79, - 0x64, 0xf0, 0xdb, 0x46, 0x04, 0xe1, 0x1c, 0x57, - 0x0f, 0x9e, 0x96, 0xb9, 0x93, 0x45, 0x71, 0x1c, - 0x8b, 0x65, 0x7d, 0x1e, 0xad, 0xbd, 0x03, 0x51, - 0xae, 0x44, 0xef, 0x97, 0x45, 0x0d, 0x8d, 0x41, - 0x5c, 0x80, 0x7b, 0xe6, 0xe0, 0xbc, 0xa6, 0x72, - 0x95, 0xa0, 0x97, 0xe1, 0xbb, 0xc0, 0xcc, 0xe5, - 0x1e, 0xc3, 0xbe, 0xd7, 0x42, 0x2a, 0xf3, 0x75, - 0x8a, 0x44, 0x67, 0x3c, 0xe5, 0x68, 0x78, 0xe5, - 0x40, 0x1f, 0xf0, 0x89, 0x57, 0xda, 0xee, 0x45, - 0xf4, 0x44, 0x81, 0x01, 0x77, 0xf0, 0x4a, 0x14, - 0xb1, 0x3f, 0x60, 0x2b, 0xeb, 0x42, 0x38, 0xa6, - 0xfb, 0xe5, 0x4d, 0x71, 0xdc, 0x7d, 0x0a, 0x72, - 0x56, 0x28, 0x9d, 0xa6, 0x8e, 0x74, 0x2d, 0xbd, - 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x4d, 0x58, 0x94, 0x0b, - 0x0b, 0x06, 0x5f, 0xae, 0x57, 0x17, 0x98, 0x86, - 0xaa, 0x49, 0x17, 0x7f, 0xbd, 0x41, 0x05, 0xa5, - 0x74, 0x1c, 0x58, 0xc8, 0x38, 0x2d, 0x99, 0x5d, - 0xe5, 0x12, 0x43, - }, - { - 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x03, 0x00, 0x28, 0xf2, 0x60, 0xc2, 0x75, 0x27, - 0x64, 0xf4, 0x05, 0x98, 0xc9, 0xd3, 0xa8, 0x00, - 0x4c, 0xa0, 0x49, 0x82, 0x68, 0xf1, 0x21, 0x05, - 0x7b, 0x4b, 0x25, 0x3e, 0xe1, 0x5f, 0x0f, 0x84, - 0x26, 0x2d, 0x16, 0x2e, 0xc0, 0xfd, 0xdf, 0x0a, - 0xf4, 0xba, 0x19, - }, - { - 0x17, 0x03, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x35, 0xef, 0x9d, - 0x6a, 0x86, 0x98, 0xc5, 0xca, 0x55, 0xca, 0x89, - 0x29, 0xb4, 0x55, 0xd4, 0x41, 0x08, 0x96, 0xe0, - 0xf3, 0x39, 0xfc, 0x15, 0x03, 0x03, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x02, 0x63, 0x1b, 0xaa, 0xc6, 0xc9, 0x6d, 0x72, - 0x24, 0x10, 0x55, 0xa9, 0x8c, 0x3b, 0x23, 0xce, - 0xd8, 0x4a, - }, -} - -var testClientChainCertificate = fromHex( - "2d2d2d2d2d424547494e2050524956415445204b" + - "45592d2d2d2d2d0a4d494945766749424144414e" + - "42676b71686b6947397730424151454641415343" + - "424b67776767536b41674541416f494241514367" + - "6f2b2f4252483269343347590a4a324f7a485846" + - "51706a515679386b71772b726b6e70784a706747" + - "6266716d31657638566b6e48496c35776c74336b" + - "722f367647736163416b4c4b4c313348560a776a" + - "726d676b493369554545734c7248573470446e35" + - "633544412f56625a364e3638416d78526a6f656a" + - "30794c6a6951514673354c41664c4a4244467954" + - "766a0a5a6b64587557717452506a51634749376a" + - "75316758794c3475417a4a5153764a6747354f47" + - "2b45672f45656b724d4d2f35734b4265514d334a" + - "596e4b317156470a6b574e427854375637583950" + - "6a5162416951432b4e33742b6338707741425130" + - "766b6538736d6f6f70536d45714a3349486e646d" + - "48352b714b306662335775630a715079434e7052" + - "694456772f7367473070626a4744705262374636" + - "37656d4d6b38666e5755416a426f387951423173" + - "4542454a307a7a6636384b585a3034614a0a6952" + - "6a7a544f495241674d424141454367674542414a" + - "4b613676326b5a3144596146786e586d7369624c" + - "386734426f67514c6a42307362524a6d746b6b4d" + - "54370a685343325873537551522f446c654d7148" + - "664555786731784a717579597643544d44585972" + - "473667354a5051744d4432465a424a7239626c65" + - "467138386c706a0a543766514e793571354c2b4f" + - "682f6b62433835436e623641753641656978776d" + - "2b6e77665a4f3766726b6278306d35516b715975" + - "5739392f452b69502b454e570a76396a68773436" + - "76515065563236494b79717656462b4f7362722f" + - "6152316138707948336361566e3579594a433346" + - "5855756c6f5a77516331714a6b4c434c4c0a375a" + - "49744f525a78514c486d4d4a654d44722f5a4942" + - "34675467645650636145375a4d5141714d6d3066" + - "4c6b6d7671723149526b77642f6831455a645650" + - "79320a742f6b6b43413039566336663749556575" + - "6f67706d705a50303130564e376b6277394a6348" + - "75544561564543675945417a47395679426e6d62" + - "6858496c57764f0a71583747524f2f5231636a2b" + - "6b564e35377876674b54756b35592b7a4d774a48" + - "32626c57435945513251753974446c476854756b" + - "664273385746772b6e6263460a7a6f706d535245" + - "6c6d464d2f6141536d464733574e5a7072696a68" + - "504b77726338376470636b31703131635a415478" + - "5a413168566d43743457616343673634690a4d74" + - "64507a334e2f34416147664956794d2b69624949" + - "35332f515543675945417953693556735a356f6a" + - "644a795077426e6c6142554231686f2b336b7068" + - "70770a7264572b2b4d796b51494a345564534437" + - "3052486e5a315839754359713978616671746c51" + - "664c44395963442f436d665264706461586c5673" + - "5249467a5a556c0a454630557149644e77337046" + - "68634f4a6d6e5a3241434470434342476f763542" + - "6e3068302b3137686a4b376f69315833716e4542" + - "7857326c7462593476556a500a44394c5330666e" + - "4a76703043675942504a527330714c4a4a464333" + - "6669796b712f57574d38727474354b364a584b50" + - "734b674b53644144577a7463316645434d0a7a65" + - "2b394a6a5a376b4d77557063666a644c2b745047" + - "3455563048326c524375635735414131396d7058" + - "50367454494733713737655a6b416e65516f6163" + - "41340a716c3073583051476c6a5763414e30464b" + - "6f4759733975582b6378445a6e7265362f52392f" + - "3930567766443237454c57546373677734633463" + - "514b42675143420a6f5432326e745a5a59396d6e" + - "72455a36752f492f4a332f35664e396737783733" + - "3177746e463745745a5361575453587364597256" + - "466b564f6362505135494a6f0a714a6a7249372b" + - "474a4d69376f6a4c69642f4c45656f31764f3163" + - "454158334f43723236554e38612f6c7434394f5a" + - "69354c337348556b756c475951755671650a6737" + - "6e6e4632437749544c34503645486443575a4461" + - "7a4136626d7375524f2b6462536e335a6c567651" + - "4b42674859524c5a665458536c44755264776977" + - "746b0a513148546b6d6b57694156726c4f577864" + - "5858456d546130303045574c46446145797a7358" + - "7834424863357166776b5a4e746b634a56396e58" + - "63536e647441530a35767a427a676e797a4f7962" + - "68315878484a3966427472414f3847555878446c" + - "6634394457616753393449763072596e616b7656" + - "2f673039786875415763366e0a5365757230576b" + - "5376453847666653734d485149584c456b0a2d2d" + - "2d2d2d454e442050524956415445204b45592d2d" + - "2d2d2d0a2d2d2d2d2d424547494e204345525449" + - "4649434154452d2d2d2d2d0a4d494944656a4343" + - "416d494343514330523168584b326649776a414e" + - "42676b71686b6947397730424151554641444342" + - "6744454c4d416b474131554542684d430a56564d" + - "78437a414a42674e564241674d416b355a4d5245" + - "77447759445651514844416843636d3976613278" + - "35626a45564d424d47413155454367774d54586b" + - "670a51304567513278705a5735304d5263774651" + - "5944565151444441357465574e68593278705a57" + - "35304c6d4e76625445684d423847435371475349" + - "62334451454a0a41525953616e5a7a6147466f61" + - "5752415a32316861577775593239744d42345844" + - "54457a4d4455794e6a49784e4451774d466f5844" + - "54457a4d4459794e5449780a4e4451774d466f77" + - "6654454c4d416b474131554542684d4356564d78" + - "4554415042674e564241674d4345356c6479425a" + - "62334a724d52457744775944565151480a444168" + - "43636d397661327835626a45514d413447413155" + - "454367774854586b67544756685a6a45544d4245" + - "47413155454177774b62586c735a57466d4c6d4e" + - "760a625445684d42384743537147534962334451" + - "454a41525953616e5a7a6147466f615752415a32" + - "316861577775593239744d494942496a414e4267" + - "6b71686b69470a397730424151454641414f4341" + - "5138414d49494243674b43415145416f4b507677" + - "5552396f754e786d43646a73783178554b593046" + - "63764a4b735071354a36630a536159426d333670" + - "7458722f465a4a78794a65634a6264354b2f2b72" + - "7872476e414a43796939647831634936356f4a43" + - "4e346c42424c43367831754b51352b580a4f5177" + - "50315732656a6576414a73555936486f394d6934" + - "346b4542624f5377487979515178636b3734325a" + - "4856376c7172555434304842694f343774594638" + - "690a2b4c674d7955457279594275546876684950" + - "7848704b7a44502b624367586b444e79574a7974" + - "616c5270466a5163552b3165312f543430477749" + - "6b41766a64370a666e504b634141554e4c354876" + - "4c4a714b4b5570684b6964794235335a682b6671" + - "697448323931726e4b6a38676a61555967316350" + - "374942744b5734786736550a572b78657533706a" + - "4a504835316c41497761504d6b41646242415243" + - "644d38332b76436c32644f4769596b5938307a69" + - "45514944415141424d413047435371470a534962" + - "3344514542425155414134494241514351752f6c" + - "65756863667243476661307047304730386a7a33" + - "34586a357972364161382f2b4a72467436347045" + - "710a493458475455646e4151696f425230425946" + - "42665761332b6538594d564a426f634763753759" + - "6634615971734d7635766b426b715a4932435a67" + - "5644694f37790a4d4f326b6a372f575679445551" + - "7831536c6d2b75435a5942556a6a6a72356e5833" + - "42535a7849734f42412b7a46425455705a506879" + - "597142373250384e6e63460a427641714241712b" + - "4c73364250534f6832746a72787570657a796732" + - "55544756586b414537617a4279465a70682b7737" + - "417a36644430784d363965364a742f6a0a336844" + - "756b324b4e63314a752f7a63326d487374566b79" + - "364362696e384473576763726251367673544735" + - "3877517369496b4d6474677a4275632f6b552b34" + - "640a506f696e4537352f766135797a38316a3073" + - "4d59574a4b697262554a6e5a454433547a69484e" + - "35340a2d2d2d2d2d454e44204345525449464943" + - "4154452d2d2d2d2d0a2d2d2d2d2d424547494e20" + - "43455254494649434154452d2d2d2d2d0a4d4949" + - "4468444343416d7743435143723761626b536973" + - "722b44414e42676b71686b694739773042415155" + - "4641444342686a454c4d416b474131554542684d" + - "430a56564d78437a414a42674e564241674d416b" + - "355a4d524577447759445651514844416843636d" + - "397661327835626a45684d423847413155454367" + - "775954586b670a5132567964476c6d61574e6864" + - "4755675158563061473979615852354d52457744" + - "775944565151444441687465574e684c6d39795a" + - "7a45684d423847435371470a534962334451454a" + - "41525953616e5a7a6147466f615752415a323168" + - "61577775593239744d4234584454457a4d445579" + - "4e6a49784d5467304d466f584454457a0a4d4459" + - "794e5449784d5467304d466f7767594178437a41" + - "4a42674e5642415954416c56544d517377435159" + - "445651514944414a4f575445524d413847413155" + - "450a42777749516e4a7662327473655734784654" + - "415442674e5642416f4d4445313549454e424945" + - "4e7361575675644445584d425547413155454177" + - "774f62586c6a0a59574e73615756756443356a62" + - "3230784954416642676b71686b69473977304243" + - "514557456d70326332686861476c6b5147647459" + - "576c734c6d4e76625443430a415349774451594a" + - "4b6f5a496876634e415145424251414467674550" + - "4144434341516f4367674542414d345438484b77" + - "596367594e34704250534368484d752f0a396a74" + - "304a697157456578546f63783964315a46447a61" + - "33386b6953476d4c4d747343684c30517277596e" + - "4c6268376256354c566c32434d51537a5a495037" + - "700a4834373866774a454479694231677a4e7650" + - "4258624d796e75676167707048613730614b5941" + - "3953624a42736a455376734a3251756946596f44" + - "7a75564c55700a4a68384b724f3949614450514d" + - "39434c477578754c37564b553849613076465142" + - "566c6332646f44436b6533336663366166564f36" + - "6b7243796c5377693362680a416931535a376e64" + - "554d6b37427951696167416457494f6f374a5878" + - "32754a7a6f4b4679594a364755387446714d4b67" + - "554b425431767759684c564b4a7443690a717444" + - "2f747634366e4c555a4f7a2f685341326b43552b" + - "447963444a7067745948787837724b4a43764748" + - "3049596f41326853675941502b6b784a73567330" + - "430a417745414154414e42676b71686b69473977" + - "30424151554641414f43415145414a536b374873" + - "4e594d75596a794f3459384231696254745a6d54" + - "722b535849480a5031695432384376734c4e6330" + - "567959794f704b3546687a445666464533786365" + - "5762614242336c6d4e6f3152305377306e706d6e" + - "63314270592b68456249610a6838444e56653230" + - "657a4e79362f666a6534734368756b724a6a4b66" + - "6d66484c6b36753546724f617369495449523962" + - "7a4b4a5a75326e79754165417a677a330a6d4579" + - "4677705a7149675870766b6977416c74704b4269" + - "496c755058786e7254365a6e2f6e634e68545a71" + - "573873597a54655664576d686b576f49315a5358" + - "6a0a6a46757739705a57764c2b58646b746d5249" + - "476b784b637878614650364b544b495055425735" + - "6c5057765477654c397853645878776149592f58" + - "4a62467569530a787a6449722b346b2f44554c77" + - "7430467832366a4b62737066644d726c49444451" + - "464d4f413151396534764f2b6151444a32507355" + - "513d3d0a2d2d2d2d2d454e442043455254494649" + - "434154452d2d2d2d2d0a2d2d2d2d2d424547494e" + - "2043455254494649434154452d2d2d2d2d0a4d49" + - "49443454434341736d67417749424167494a414d" + - "7769544575596f6f6a384d413047435371475349" + - "623344514542425155414d4947474d5173774351" + - "59440a5651514745774a56557a454c4d416b4741" + - "31554543417743546c6b784554415042674e5642" + - "41634d43454a796232397262486c754d53457748" + - "7759445651514b0a4442684e655342445a584a30" + - "61575a70593246305a5342426458526f62334a70" + - "64486b784554415042674e5642414d4d43473135" + - "5932457562334a6e4d5345770a4877594a4b6f5a" + - "496876634e41516b4246684a71646e4e6f595768" + - "705a45426e625746706243356a62323077486863" + - "4e4d544d774e5449324d6a45774e5441780a5768" + - "634e4d6a4d774e5449304d6a45774e544178576a" + - "4342686a454c4d416b474131554542684d435656" + - "4d78437a414a42674e564241674d416b355a4d52" + - "45770a447759445651514844416843636d397661" + - "327835626a45684d423847413155454367775954" + - "586b675132567964476c6d61574e686447556751" + - "585630614739790a615852354d52457744775944" + - "565151444441687465574e684c6d39795a7a4568" + - "4d42384743537147534962334451454a41525953" + - "616e5a7a6147466f615752410a5a323168615777" + - "75593239744d494942496a414e42676b71686b69" + - "47397730424151454641414f43415138414d4949" + - "4243674b434151454138507574674634330a3032" + - "33754c737938444e645753315a467a5369324975" + - "6e69443947484b69664f6434317544672f375a75" + - "4731447071324259367a34635633686c74473067" + - "75530a4178754a4442735144706d503468666f77" + - "6a4141523962382b5138376454534e5462435a74" + - "3642746f4c6174326764654f4334433544427472" + - "684e79314d6a4f0a46416575493479506e6f7867" + - "31676135377741597742306c48746f2b4c383872" + - "566f53654d4348484b665944696954354e4b786c" + - "6e59413279447356454c31520a3662774334656d" + - "7a5770715a5152736e6f4531516e69642f6f5830" + - "4a6837324b796c2b7870516934424e5253696172" + - "67665549754c7858755a6c635045786c460a7145" + - "74646757624d456a65555876303845494652502f" + - "6f503361474a41366c346b665537383779737670" + - "4d774c72374b663062544b4c524f6b5874625132" + - "79760a6d31787162567262655635716177494441" + - "5141426f314177546a416442674e564851344546" + - "67515561783441714a2f3666514435344a30506b" + - "497951714b45330a61396f77487759445652306a" + - "42426777466f415561783441714a2f3666514435" + - "344a30506b497951714b453361396f7744415944" + - "5652305442415577417745420a2f7a414e42676b" + - "71686b6947397730424151554641414f43415145" + - "417a57397a5456594c387934633467494d464c73" + - "76335478442f742b554c616d4a675648340a5836" + - "65674536724d73426a69567a344e4b5a506f6c64" + - "556255394a52387233316e6e73695a574a637845" + - "7764364f6e443143766e654d7351382f34476739" + - "77360a486d495177455a33787032667135596c58" + - "50736d775255667054507554356f55616853586b" + - "7975564339796f31326b753841454f2f55375132" + - "616a6c5a6437370a79736f63582f6c546f49666e" + - "4d3573767a2b51542f4f7836624c435145357532" + - "78515032446c376935436242666c502b61615048" + - "324935756c444b67337371320a7a4e5942315868" + - "414b474f623773384a4f7a554538425143396f41" + - "4f6b4c4b55306955577548703268345366684d57" + - "76776d316f656f5363786f706a594964710a4a63" + - "476865412b3636462f687571796b6239304a5078" + - "4c4c48665050534e66544a75696377314f7a7574" + - "77796d5a695731673d3d0a2d2d2d2d2d454e4420" + - "43455254494649434154452d2d2d2d2d0a", -) - -// Script of interaction with openssl implementation: -// -// openssl s_server -cipher ECDHE-ECDSA-AES128-SHA \ -// -key server.key -cert server.crt -port 10443 -// -// The values for this test are obtained by building and running in client mode: -// % go test -test.run "TestRunClient" -connect -ciphersuites=0xc009 -// The recorded bytes are written to stdout. -// -// The server private key is: -// -// -----BEGIN EC PARAMETERS----- -// BgUrgQQAIw== -// -----END EC PARAMETERS----- -// -----BEGIN EC PRIVATE KEY----- -// MIHcAgEBBEIBmIPpCa0Kyeo9M/nq5mHxeFIGlw+MqakWcvHu3Keo7xK9ZWG7JG3a -// XfS01efjqSZJvF2DoL+Sly4A5iBn0Me9mdegBwYFK4EEACOhgYkDgYYABADEoe2+ -// mPkLSHM2fsMWVhEi8j1TwztNIT3Na3Xm9rDcmt8mwbyyh/ByMnyzZC8ckLzqaCMQ -// fv7jJcBIOmngKG3TNwDvBGLdDaCccGKD2IHTZDGqnpcxvZawaMCbI952ZD8aXH/p -// Eg5YWLZfcN2b2OrV1/XVzLm2nzBmW2aaIOIn5b/+Ow== -// -----END EC PRIVATE KEY----- -// -// and certificate is: -// -// -----BEGIN CERTIFICATE----- -// MIICADCCAWICCQC4vy1HoNLr9DAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw -// EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 -// eSBMdGQwHhcNMTIxMTIyMTUwNjMyWhcNMjIxMTIwMTUwNjMyWjBFMQswCQYDVQQG -// EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk -// Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAxKHtvpj5C0hz -// Nn7DFlYRIvI9U8M7TSE9zWt15vaw3JrfJsG8sofwcjJ8s2QvHJC86mgjEH7+4yXA -// SDpp4Cht0zcA7wRi3Q2gnHBig9iB02Qxqp6XMb2WsGjAmyPedmQ/Glx/6RIOWFi2 -// X3Ddm9jq1df11cy5tp8wZltmmiDiJ+W//jswCQYHKoZIzj0EAQOBjAAwgYgCQgGI -// ok/r4kXFSH0brPXtmJ2uR3DAXhu2L73xtk23YUDTEaLO7gt+kn7/dp3DO36lP876 -// EOJZ7EctfKzaTpcOFaBv0AJCAU38vmcTnC0FDr0/o4wlwTMTgw2UBrvUN3r27HrJ -// hi7d1xFpf4V8Vt77MXgr5Md4Da7Lvp5ONiQxe2oPOZUSB48q -// -----END CERTIFICATE----- -var ecdheECDSAAESClientScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, - 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x09, - 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x50, 0x03, 0x01, 0x50, 0xd7, 0x19, 0xc9, 0x03, - 0xc2, 0x3a, 0xc6, 0x1f, 0x0a, 0x84, 0x9e, 0xd7, - 0xf4, 0x7e, 0x07, 0x6d, 0xa8, 0xe4, 0xa9, 0x4f, - 0x22, 0x50, 0xa2, 0x19, 0x24, 0x44, 0x42, 0x65, - 0xaa, 0xba, 0x3a, 0x20, 0x90, 0x70, 0xb7, 0xe5, - 0x57, 0xed, 0xb1, 0xb1, 0x43, 0x4b, 0xa1, 0x4e, - 0xee, 0x7a, 0x5b, 0x88, 0xf6, 0xa6, 0x73, 0x3b, - 0xcb, 0xa7, 0xbd, 0x57, 0x50, 0xf2, 0x72, 0x8c, - 0xbc, 0x45, 0x73, 0xaa, 0xc0, 0x09, 0x00, 0x00, - 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, - 0x02, 0x16, 0x03, 0x01, 0x02, 0x0e, 0x0b, 0x00, - 0x02, 0x0a, 0x00, 0x02, 0x07, 0x00, 0x02, 0x04, - 0x30, 0x82, 0x02, 0x00, 0x30, 0x82, 0x01, 0x62, - 0x02, 0x09, 0x00, 0xb8, 0xbf, 0x2d, 0x47, 0xa0, - 0xd2, 0xeb, 0xf4, 0x30, 0x09, 0x06, 0x07, 0x2a, - 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30, 0x45, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, - 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, - 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x32, 0x31, 0x31, 0x32, 0x32, 0x31, - 0x35, 0x30, 0x36, 0x33, 0x32, 0x5a, 0x17, 0x0d, - 0x32, 0x32, 0x31, 0x31, 0x32, 0x30, 0x31, 0x35, - 0x30, 0x36, 0x33, 0x32, 0x5a, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9b, 0x30, - 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, - 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, - 0x23, 0x03, 0x81, 0x86, 0x00, 0x04, 0x00, 0xc4, - 0xa1, 0xed, 0xbe, 0x98, 0xf9, 0x0b, 0x48, 0x73, - 0x36, 0x7e, 0xc3, 0x16, 0x56, 0x11, 0x22, 0xf2, - 0x3d, 0x53, 0xc3, 0x3b, 0x4d, 0x21, 0x3d, 0xcd, - 0x6b, 0x75, 0xe6, 0xf6, 0xb0, 0xdc, 0x9a, 0xdf, - 0x26, 0xc1, 0xbc, 0xb2, 0x87, 0xf0, 0x72, 0x32, - 0x7c, 0xb3, 0x64, 0x2f, 0x1c, 0x90, 0xbc, 0xea, - 0x68, 0x23, 0x10, 0x7e, 0xfe, 0xe3, 0x25, 0xc0, - 0x48, 0x3a, 0x69, 0xe0, 0x28, 0x6d, 0xd3, 0x37, - 0x00, 0xef, 0x04, 0x62, 0xdd, 0x0d, 0xa0, 0x9c, - 0x70, 0x62, 0x83, 0xd8, 0x81, 0xd3, 0x64, 0x31, - 0xaa, 0x9e, 0x97, 0x31, 0xbd, 0x96, 0xb0, 0x68, - 0xc0, 0x9b, 0x23, 0xde, 0x76, 0x64, 0x3f, 0x1a, - 0x5c, 0x7f, 0xe9, 0x12, 0x0e, 0x58, 0x58, 0xb6, - 0x5f, 0x70, 0xdd, 0x9b, 0xd8, 0xea, 0xd5, 0xd7, - 0xf5, 0xd5, 0xcc, 0xb9, 0xb6, 0x9f, 0x30, 0x66, - 0x5b, 0x66, 0x9a, 0x20, 0xe2, 0x27, 0xe5, 0xbf, - 0xfe, 0x3b, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, - 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x81, 0x8c, - 0x00, 0x30, 0x81, 0x88, 0x02, 0x42, 0x01, 0x88, - 0xa2, 0x4f, 0xeb, 0xe2, 0x45, 0xc5, 0x48, 0x7d, - 0x1b, 0xac, 0xf5, 0xed, 0x98, 0x9d, 0xae, 0x47, - 0x70, 0xc0, 0x5e, 0x1b, 0xb6, 0x2f, 0xbd, 0xf1, - 0xb6, 0x4d, 0xb7, 0x61, 0x40, 0xd3, 0x11, 0xa2, - 0xce, 0xee, 0x0b, 0x7e, 0x92, 0x7e, 0xff, 0x76, - 0x9d, 0xc3, 0x3b, 0x7e, 0xa5, 0x3f, 0xce, 0xfa, - 0x10, 0xe2, 0x59, 0xec, 0x47, 0x2d, 0x7c, 0xac, - 0xda, 0x4e, 0x97, 0x0e, 0x15, 0xa0, 0x6f, 0xd0, - 0x02, 0x42, 0x01, 0x4d, 0xfc, 0xbe, 0x67, 0x13, - 0x9c, 0x2d, 0x05, 0x0e, 0xbd, 0x3f, 0xa3, 0x8c, - 0x25, 0xc1, 0x33, 0x13, 0x83, 0x0d, 0x94, 0x06, - 0xbb, 0xd4, 0x37, 0x7a, 0xf6, 0xec, 0x7a, 0xc9, - 0x86, 0x2e, 0xdd, 0xd7, 0x11, 0x69, 0x7f, 0x85, - 0x7c, 0x56, 0xde, 0xfb, 0x31, 0x78, 0x2b, 0xe4, - 0xc7, 0x78, 0x0d, 0xae, 0xcb, 0xbe, 0x9e, 0x4e, - 0x36, 0x24, 0x31, 0x7b, 0x6a, 0x0f, 0x39, 0x95, - 0x12, 0x07, 0x8f, 0x2a, 0x16, 0x03, 0x01, 0x00, - 0xd6, 0x0c, 0x00, 0x00, 0xd2, 0x03, 0x00, 0x17, - 0x41, 0x04, 0x33, 0xed, 0xe1, 0x10, 0x3d, 0xe2, - 0xb0, 0x81, 0x5e, 0x01, 0x1b, 0x00, 0x4a, 0x7d, - 0xdc, 0xc5, 0x78, 0x02, 0xb1, 0x9a, 0x78, 0x92, - 0x34, 0xd9, 0x23, 0xcc, 0x01, 0xfb, 0x0c, 0x49, - 0x1c, 0x4a, 0x59, 0x8a, 0x80, 0x1b, 0x34, 0xf0, - 0xe8, 0x87, 0x1b, 0x7c, 0xfb, 0x72, 0xf5, 0xea, - 0xf9, 0xf3, 0xff, 0xa6, 0x3e, 0x4e, 0xac, 0xbc, - 0xee, 0x14, 0x2b, 0x87, 0xd4, 0x0b, 0xda, 0x19, - 0x60, 0x2b, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02, - 0x42, 0x01, 0x75, 0x46, 0x4f, 0x97, 0x9f, 0xc5, - 0xf9, 0x4c, 0x38, 0xcf, 0x3b, 0x37, 0x1a, 0x6b, - 0x53, 0xfc, 0x05, 0x73, 0x7d, 0x98, 0x2c, 0x5b, - 0x76, 0xd4, 0x37, 0x1f, 0x50, 0x6d, 0xad, 0xc6, - 0x0f, 0x8f, 0x7b, 0xcc, 0x60, 0x8e, 0x04, 0x00, - 0x21, 0x80, 0xa8, 0xa5, 0x98, 0xf2, 0x42, 0xf2, - 0xc3, 0xf6, 0x44, 0x50, 0xc4, 0x7a, 0xae, 0x6f, - 0x74, 0xa0, 0x7f, 0x07, 0x7a, 0x0b, 0xbb, 0x41, - 0x9e, 0x3c, 0x0b, 0x02, 0x42, 0x01, 0xbe, 0x64, - 0xaa, 0x12, 0x03, 0xfb, 0xd8, 0x4f, 0x93, 0xf9, - 0x92, 0x54, 0x0d, 0x9c, 0x9d, 0x53, 0x88, 0x19, - 0x69, 0x94, 0xfc, 0xd6, 0xf7, 0x60, 0xcf, 0x70, - 0x64, 0x15, 0x1b, 0x02, 0x22, 0x56, 0xb0, 0x2c, - 0xb1, 0x72, 0x4c, 0x9e, 0x7b, 0xf0, 0x53, 0x97, - 0x43, 0xac, 0x11, 0x62, 0xe5, 0x5a, 0xf1, 0x7e, - 0x87, 0x8f, 0x5c, 0x43, 0x1d, 0xae, 0x56, 0x28, - 0xdb, 0x76, 0x15, 0xd8, 0x1c, 0x73, 0xce, 0x16, - 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00, - 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, - 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, - 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, - 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, - 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, - 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, - 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, - 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, - 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x1a, 0x45, - 0x92, 0x3b, 0xac, 0x8d, 0x91, 0x89, 0xd3, 0x2c, - 0xf4, 0x3c, 0x5f, 0x70, 0xf1, 0x79, 0xa5, 0x6a, - 0xcf, 0x97, 0x8f, 0x3f, 0x73, 0x08, 0xca, 0x3f, - 0x55, 0xb0, 0x28, 0xd1, 0x6f, 0xcd, 0x9b, 0xca, - 0xb6, 0xb7, 0xd0, 0xa5, 0x21, 0x5b, 0x08, 0xf8, - 0x42, 0xe2, 0xdf, 0x25, 0x6a, 0x16, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x30, 0x30, 0x83, 0xb6, 0x51, 0x8a, - 0x85, 0x4a, 0xee, 0xe4, 0xb6, 0xae, 0xf3, 0xc1, - 0xdc, 0xd2, 0x04, 0xb3, 0xd0, 0x25, 0x47, 0x5f, - 0xac, 0x83, 0xa3, 0x7d, 0xcf, 0x47, 0x92, 0xed, - 0x92, 0x6c, 0xd1, 0x6e, 0xfd, 0x63, 0xf5, 0x2d, - 0x89, 0xd8, 0x04, 0x8c, 0x62, 0x71, 0xae, 0x5e, - 0x32, 0x48, 0xf8, - }, - { - 0x17, 0x03, 0x01, 0x00, 0x20, 0xcf, 0x5e, 0xba, - 0xf4, 0x47, 0x32, 0x35, 0x9b, 0x85, 0xdc, 0xb3, - 0xff, 0x77, 0x90, 0xd9, 0x2b, 0xbd, 0x59, 0x2a, - 0x33, 0xe4, 0x6e, 0x9b, 0xfc, 0x1c, 0x73, 0x3f, - 0x5e, 0x1e, 0xe3, 0xa4, 0xc2, 0x17, 0x03, 0x01, - 0x00, 0x20, 0x05, 0xdf, 0x2d, 0x9b, 0x29, 0x7f, - 0x97, 0xcd, 0x49, 0x04, 0x53, 0x22, 0x1a, 0xa1, - 0xa1, 0xe6, 0x38, 0x3a, 0x56, 0x37, 0x1f, 0xd8, - 0x3a, 0x12, 0x2c, 0xf0, 0xeb, 0x61, 0x35, 0x76, - 0xe5, 0xf0, 0x15, 0x03, 0x01, 0x00, 0x20, 0xa5, - 0x56, 0xb5, 0x49, 0x4b, 0xc2, 0xd4, 0x4c, 0xf6, - 0x95, 0x15, 0x7d, 0x41, 0x1d, 0x5c, 0x00, 0x0e, - 0x20, 0xb1, 0x0a, 0xbc, 0xc9, 0x2a, 0x09, 0x17, - 0xb4, 0xaa, 0x1c, 0x79, 0xda, 0x79, 0x27, - }, -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_messages.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_messages.go deleted file mode 100644 index 8197391e35..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_messages.go +++ /dev/null @@ -1,1304 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import "bytes" - -type clientHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuites []uint16 - compressionMethods []uint8 - nextProtoNeg bool - serverName string - ocspStapling bool - supportedCurves []uint16 - supportedPoints []uint8 - ticketSupported bool - sessionTicket []uint8 - signatureAndHashes []signatureAndHash -} - -func (m *clientHelloMsg) equal(i interface{}) bool { - m1, ok := i.(*clientHelloMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.vers == m1.vers && - bytes.Equal(m.random, m1.random) && - bytes.Equal(m.sessionId, m1.sessionId) && - eqUint16s(m.cipherSuites, m1.cipherSuites) && - bytes.Equal(m.compressionMethods, m1.compressionMethods) && - m.nextProtoNeg == m1.nextProtoNeg && - m.serverName == m1.serverName && - m.ocspStapling == m1.ocspStapling && - eqUint16s(m.supportedCurves, m1.supportedCurves) && - bytes.Equal(m.supportedPoints, m1.supportedPoints) && - m.ticketSupported == m1.ticketSupported && - bytes.Equal(m.sessionTicket, m1.sessionTicket) && - eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) -} - -func (m *clientHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods) - numExtensions := 0 - extensionsLength := 0 - if m.nextProtoNeg { - numExtensions++ - } - if m.ocspStapling { - extensionsLength += 1 + 2 + 2 - numExtensions++ - } - if len(m.serverName) > 0 { - extensionsLength += 5 + len(m.serverName) - numExtensions++ - } - if len(m.supportedCurves) > 0 { - extensionsLength += 2 + 2*len(m.supportedCurves) - numExtensions++ - } - if len(m.supportedPoints) > 0 { - extensionsLength += 1 + len(m.supportedPoints) - numExtensions++ - } - if m.ticketSupported { - extensionsLength += len(m.sessionTicket) - numExtensions++ - } - if len(m.signatureAndHashes) > 0 { - extensionsLength += 2 + 2*len(m.signatureAndHashes) - numExtensions++ - } - if numExtensions > 0 { - extensionsLength += 4 * numExtensions - length += 2 + extensionsLength - } - - x := make([]byte, 4+length) - x[0] = typeClientHello - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[4] = uint8(m.vers >> 8) - x[5] = uint8(m.vers) - copy(x[6:38], m.random) - x[38] = uint8(len(m.sessionId)) - copy(x[39:39+len(m.sessionId)], m.sessionId) - y := x[39+len(m.sessionId):] - y[0] = uint8(len(m.cipherSuites) >> 7) - y[1] = uint8(len(m.cipherSuites) << 1) - for i, suite := range m.cipherSuites { - y[2+i*2] = uint8(suite >> 8) - y[3+i*2] = uint8(suite) - } - z := y[2+len(m.cipherSuites)*2:] - z[0] = uint8(len(m.compressionMethods)) - copy(z[1:], m.compressionMethods) - - z = z[1+len(m.compressionMethods):] - if numExtensions > 0 { - z[0] = byte(extensionsLength >> 8) - z[1] = byte(extensionsLength) - z = z[2:] - } - if m.nextProtoNeg { - z[0] = byte(extensionNextProtoNeg >> 8) - z[1] = byte(extensionNextProtoNeg) - // The length is always 0 - z = z[4:] - } - if len(m.serverName) > 0 { - z[0] = byte(extensionServerName >> 8) - z[1] = byte(extensionServerName) - l := len(m.serverName) + 5 - z[2] = byte(l >> 8) - z[3] = byte(l) - z = z[4:] - - // RFC 3546, section 3.1 - // - // struct { - // NameType name_type; - // select (name_type) { - // case host_name: HostName; - // } name; - // } ServerName; - // - // enum { - // host_name(0), (255) - // } NameType; - // - // opaque HostName<1..2^16-1>; - // - // struct { - // ServerName server_name_list<1..2^16-1> - // } ServerNameList; - - z[0] = byte((len(m.serverName) + 3) >> 8) - z[1] = byte(len(m.serverName) + 3) - z[3] = byte(len(m.serverName) >> 8) - z[4] = byte(len(m.serverName)) - copy(z[5:], []byte(m.serverName)) - z = z[l:] - } - if m.ocspStapling { - // RFC 4366, section 3.6 - z[0] = byte(extensionStatusRequest >> 8) - z[1] = byte(extensionStatusRequest) - z[2] = 0 - z[3] = 5 - z[4] = 1 // OCSP type - // Two zero valued uint16s for the two lengths. - z = z[9:] - } - if len(m.supportedCurves) > 0 { - // http://tools.ietf.org/html/rfc4492#section-5.5.1 - z[0] = byte(extensionSupportedCurves >> 8) - z[1] = byte(extensionSupportedCurves) - l := 2 + 2*len(m.supportedCurves) - z[2] = byte(l >> 8) - z[3] = byte(l) - l -= 2 - z[4] = byte(l >> 8) - z[5] = byte(l) - z = z[6:] - for _, curve := range m.supportedCurves { - z[0] = byte(curve >> 8) - z[1] = byte(curve) - z = z[2:] - } - } - if len(m.supportedPoints) > 0 { - // http://tools.ietf.org/html/rfc4492#section-5.5.2 - z[0] = byte(extensionSupportedPoints >> 8) - z[1] = byte(extensionSupportedPoints) - l := 1 + len(m.supportedPoints) - z[2] = byte(l >> 8) - z[3] = byte(l) - l-- - z[4] = byte(l) - z = z[5:] - for _, pointFormat := range m.supportedPoints { - z[0] = byte(pointFormat) - z = z[1:] - } - } - if m.ticketSupported { - // http://tools.ietf.org/html/rfc5077#section-3.2 - z[0] = byte(extensionSessionTicket >> 8) - z[1] = byte(extensionSessionTicket) - l := len(m.sessionTicket) - z[2] = byte(l >> 8) - z[3] = byte(l) - z = z[4:] - copy(z, m.sessionTicket) - z = z[len(m.sessionTicket):] - } - if len(m.signatureAndHashes) > 0 { - // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - z[0] = byte(extensionSignatureAlgorithms >> 8) - z[1] = byte(extensionSignatureAlgorithms) - l := 2 + 2*len(m.signatureAndHashes) - z[2] = byte(l >> 8) - z[3] = byte(l) - z = z[4:] - - l -= 2 - z[0] = byte(l >> 8) - z[1] = byte(l) - z = z[2:] - for _, sigAndHash := range m.signatureAndHashes { - z[0] = sigAndHash.hash - z[1] = sigAndHash.signature - z = z[2:] - } - } - - m.raw = x - - return x -} - -func (m *clientHelloMsg) unmarshal(data []byte) bool { - if len(data) < 42 { - return false - } - m.raw = data - m.vers = uint16(data[4])<<8 | uint16(data[5]) - m.random = data[6:38] - sessionIdLen := int(data[38]) - if sessionIdLen > 32 || len(data) < 39+sessionIdLen { - return false - } - m.sessionId = data[39 : 39+sessionIdLen] - data = data[39+sessionIdLen:] - if len(data) < 2 { - return false - } - // cipherSuiteLen is the number of bytes of cipher suite numbers. Since - // they are uint16s, the number must be even. - cipherSuiteLen := int(data[0])<<8 | int(data[1]) - if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen { - return false - } - numCipherSuites := cipherSuiteLen / 2 - m.cipherSuites = make([]uint16, numCipherSuites) - for i := 0; i < numCipherSuites; i++ { - m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i]) - } - data = data[2+cipherSuiteLen:] - if len(data) < 1 { - return false - } - compressionMethodsLen := int(data[0]) - if len(data) < 1+compressionMethodsLen { - return false - } - m.compressionMethods = data[1 : 1+compressionMethodsLen] - - data = data[1+compressionMethodsLen:] - - m.nextProtoNeg = false - m.serverName = "" - m.ocspStapling = false - m.ticketSupported = false - m.sessionTicket = nil - m.signatureAndHashes = nil - - if len(data) == 0 { - // ClientHello is optionally followed by extension data - return true - } - if len(data) < 2 { - return false - } - - extensionsLength := int(data[0])<<8 | int(data[1]) - data = data[2:] - if extensionsLength != len(data) { - return false - } - - for len(data) != 0 { - if len(data) < 4 { - return false - } - extension := uint16(data[0])<<8 | uint16(data[1]) - length := int(data[2])<<8 | int(data[3]) - data = data[4:] - if len(data) < length { - return false - } - - switch extension { - case extensionServerName: - if length < 2 { - return false - } - numNames := int(data[0])<<8 | int(data[1]) - d := data[2:] - for i := 0; i < numNames; i++ { - if len(d) < 3 { - return false - } - nameType := d[0] - nameLen := int(d[1])<<8 | int(d[2]) - d = d[3:] - if len(d) < nameLen { - return false - } - if nameType == 0 { - m.serverName = string(d[0:nameLen]) - break - } - d = d[nameLen:] - } - case extensionNextProtoNeg: - if length > 0 { - return false - } - m.nextProtoNeg = true - case extensionStatusRequest: - m.ocspStapling = length > 0 && data[0] == statusTypeOCSP - case extensionSupportedCurves: - // http://tools.ietf.org/html/rfc4492#section-5.5.1 - if length < 2 { - return false - } - l := int(data[0])<<8 | int(data[1]) - if l%2 == 1 || length != l+2 { - return false - } - numCurves := l / 2 - m.supportedCurves = make([]uint16, numCurves) - d := data[2:] - for i := 0; i < numCurves; i++ { - m.supportedCurves[i] = uint16(d[0])<<8 | uint16(d[1]) - d = d[2:] - } - case extensionSupportedPoints: - // http://tools.ietf.org/html/rfc4492#section-5.5.2 - if length < 1 { - return false - } - l := int(data[0]) - if length != l+1 { - return false - } - m.supportedPoints = make([]uint8, l) - copy(m.supportedPoints, data[1:]) - case extensionSessionTicket: - // http://tools.ietf.org/html/rfc5077#section-3.2 - m.ticketSupported = true - m.sessionTicket = data[:length] - case extensionSignatureAlgorithms: - // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - if length < 2 || length&1 != 0 { - return false - } - l := int(data[0])<<8 | int(data[1]) - if l != length-2 { - return false - } - n := l / 2 - d := data[2:] - m.signatureAndHashes = make([]signatureAndHash, n) - for i := range m.signatureAndHashes { - m.signatureAndHashes[i].hash = d[0] - m.signatureAndHashes[i].signature = d[1] - d = d[2:] - } - } - data = data[length:] - } - - return true -} - -type serverHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuite uint16 - compressionMethod uint8 - nextProtoNeg bool - nextProtos []string - ocspStapling bool - ticketSupported bool -} - -func (m *serverHelloMsg) equal(i interface{}) bool { - m1, ok := i.(*serverHelloMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.vers == m1.vers && - bytes.Equal(m.random, m1.random) && - bytes.Equal(m.sessionId, m1.sessionId) && - m.cipherSuite == m1.cipherSuite && - m.compressionMethod == m1.compressionMethod && - m.nextProtoNeg == m1.nextProtoNeg && - eqStrings(m.nextProtos, m1.nextProtos) && - m.ocspStapling == m1.ocspStapling && - m.ticketSupported == m1.ticketSupported -} - -func (m *serverHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - length := 38 + len(m.sessionId) - numExtensions := 0 - extensionsLength := 0 - - nextProtoLen := 0 - if m.nextProtoNeg { - numExtensions++ - for _, v := range m.nextProtos { - nextProtoLen += len(v) - } - nextProtoLen += len(m.nextProtos) - extensionsLength += nextProtoLen - } - if m.ocspStapling { - numExtensions++ - } - if m.ticketSupported { - numExtensions++ - } - if numExtensions > 0 { - extensionsLength += 4 * numExtensions - length += 2 + extensionsLength - } - - x := make([]byte, 4+length) - x[0] = typeServerHello - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[4] = uint8(m.vers >> 8) - x[5] = uint8(m.vers) - copy(x[6:38], m.random) - x[38] = uint8(len(m.sessionId)) - copy(x[39:39+len(m.sessionId)], m.sessionId) - z := x[39+len(m.sessionId):] - z[0] = uint8(m.cipherSuite >> 8) - z[1] = uint8(m.cipherSuite) - z[2] = uint8(m.compressionMethod) - - z = z[3:] - if numExtensions > 0 { - z[0] = byte(extensionsLength >> 8) - z[1] = byte(extensionsLength) - z = z[2:] - } - if m.nextProtoNeg { - z[0] = byte(extensionNextProtoNeg >> 8) - z[1] = byte(extensionNextProtoNeg) - z[2] = byte(nextProtoLen >> 8) - z[3] = byte(nextProtoLen) - z = z[4:] - - for _, v := range m.nextProtos { - l := len(v) - if l > 255 { - l = 255 - } - z[0] = byte(l) - copy(z[1:], []byte(v[0:l])) - z = z[1+l:] - } - } - if m.ocspStapling { - z[0] = byte(extensionStatusRequest >> 8) - z[1] = byte(extensionStatusRequest) - z = z[4:] - } - if m.ticketSupported { - z[0] = byte(extensionSessionTicket >> 8) - z[1] = byte(extensionSessionTicket) - z = z[4:] - } - - m.raw = x - - return x -} - -func (m *serverHelloMsg) unmarshal(data []byte) bool { - if len(data) < 42 { - return false - } - m.raw = data - m.vers = uint16(data[4])<<8 | uint16(data[5]) - m.random = data[6:38] - sessionIdLen := int(data[38]) - if sessionIdLen > 32 || len(data) < 39+sessionIdLen { - return false - } - m.sessionId = data[39 : 39+sessionIdLen] - data = data[39+sessionIdLen:] - if len(data) < 3 { - return false - } - m.cipherSuite = uint16(data[0])<<8 | uint16(data[1]) - m.compressionMethod = data[2] - data = data[3:] - - m.nextProtoNeg = false - m.nextProtos = nil - m.ocspStapling = false - m.ticketSupported = false - - if len(data) == 0 { - // ServerHello is optionally followed by extension data - return true - } - if len(data) < 2 { - return false - } - - extensionsLength := int(data[0])<<8 | int(data[1]) - data = data[2:] - if len(data) != extensionsLength { - return false - } - - for len(data) != 0 { - if len(data) < 4 { - return false - } - extension := uint16(data[0])<<8 | uint16(data[1]) - length := int(data[2])<<8 | int(data[3]) - data = data[4:] - if len(data) < length { - return false - } - - switch extension { - case extensionNextProtoNeg: - m.nextProtoNeg = true - d := data[:length] - for len(d) > 0 { - l := int(d[0]) - d = d[1:] - if l == 0 || l > len(d) { - return false - } - m.nextProtos = append(m.nextProtos, string(d[:l])) - d = d[l:] - } - case extensionStatusRequest: - if length > 0 { - return false - } - m.ocspStapling = true - case extensionSessionTicket: - if length > 0 { - return false - } - m.ticketSupported = true - } - data = data[length:] - } - - return true -} - -type certificateMsg struct { - raw []byte - certificates [][]byte -} - -func (m *certificateMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - eqByteSlices(m.certificates, m1.certificates) -} - -func (m *certificateMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - var i int - for _, slice := range m.certificates { - i += len(slice) - } - - length := 3 + 3*len(m.certificates) + i - x = make([]byte, 4+length) - x[0] = typeCertificate - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - certificateOctets := length - 3 - x[4] = uint8(certificateOctets >> 16) - x[5] = uint8(certificateOctets >> 8) - x[6] = uint8(certificateOctets) - - y := x[7:] - for _, slice := range m.certificates { - y[0] = uint8(len(slice) >> 16) - y[1] = uint8(len(slice) >> 8) - y[2] = uint8(len(slice)) - copy(y[3:], slice) - y = y[3+len(slice):] - } - - m.raw = x - return -} - -func (m *certificateMsg) unmarshal(data []byte) bool { - if len(data) < 7 { - return false - } - - m.raw = data - certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]) - if uint32(len(data)) != certsLen+7 { - return false - } - - numCerts := 0 - d := data[7:] - for certsLen > 0 { - if len(d) < 4 { - return false - } - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - if uint32(len(d)) < 3+certLen { - return false - } - d = d[3+certLen:] - certsLen -= 3 + certLen - numCerts++ - } - - m.certificates = make([][]byte, numCerts) - d = data[7:] - for i := 0; i < numCerts; i++ { - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - m.certificates[i] = d[3 : 3+certLen] - d = d[3+certLen:] - } - - return true -} - -type serverKeyExchangeMsg struct { - raw []byte - key []byte -} - -func (m *serverKeyExchangeMsg) equal(i interface{}) bool { - m1, ok := i.(*serverKeyExchangeMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.key, m1.key) -} - -func (m *serverKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.key) - x := make([]byte, length+4) - x[0] = typeServerKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.key) - - m.raw = x - return x -} - -func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - m.key = data[4:] - return true -} - -type certificateStatusMsg struct { - raw []byte - statusType uint8 - response []byte -} - -func (m *certificateStatusMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateStatusMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.statusType == m1.statusType && - bytes.Equal(m.response, m1.response) -} - -func (m *certificateStatusMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var x []byte - if m.statusType == statusTypeOCSP { - x = make([]byte, 4+4+len(m.response)) - x[0] = typeCertificateStatus - l := len(m.response) + 4 - x[1] = byte(l >> 16) - x[2] = byte(l >> 8) - x[3] = byte(l) - x[4] = statusTypeOCSP - - l -= 4 - x[5] = byte(l >> 16) - x[6] = byte(l >> 8) - x[7] = byte(l) - copy(x[8:], m.response) - } else { - x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType} - } - - m.raw = x - return x -} - -func (m *certificateStatusMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 5 { - return false - } - m.statusType = data[4] - - m.response = nil - if m.statusType == statusTypeOCSP { - if len(data) < 8 { - return false - } - respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7]) - if uint32(len(data)) != 4+4+respLen { - return false - } - m.response = data[8:] - } - return true -} - -type serverHelloDoneMsg struct{} - -func (m *serverHelloDoneMsg) equal(i interface{}) bool { - _, ok := i.(*serverHelloDoneMsg) - return ok -} - -func (m *serverHelloDoneMsg) marshal() []byte { - x := make([]byte, 4) - x[0] = typeServerHelloDone - return x -} - -func (m *serverHelloDoneMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -type clientKeyExchangeMsg struct { - raw []byte - ciphertext []byte -} - -func (m *clientKeyExchangeMsg) equal(i interface{}) bool { - m1, ok := i.(*clientKeyExchangeMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.ciphertext, m1.ciphertext) -} - -func (m *clientKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.ciphertext) - x := make([]byte, length+4) - x[0] = typeClientKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.ciphertext) - - m.raw = x - return x -} - -func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - l := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if l != len(data)-4 { - return false - } - m.ciphertext = data[4:] - return true -} - -type finishedMsg struct { - raw []byte - verifyData []byte -} - -func (m *finishedMsg) equal(i interface{}) bool { - m1, ok := i.(*finishedMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.verifyData, m1.verifyData) -} - -func (m *finishedMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - x = make([]byte, 4+len(m.verifyData)) - x[0] = typeFinished - x[3] = byte(len(m.verifyData)) - copy(x[4:], m.verifyData) - m.raw = x - return -} - -func (m *finishedMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - m.verifyData = data[4:] - return true -} - -type nextProtoMsg struct { - raw []byte - proto string -} - -func (m *nextProtoMsg) equal(i interface{}) bool { - m1, ok := i.(*nextProtoMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.proto == m1.proto -} - -func (m *nextProtoMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - l := len(m.proto) - if l > 255 { - l = 255 - } - - padding := 32 - (l+2)%32 - length := l + padding + 2 - x := make([]byte, length+4) - x[0] = typeNextProtocol - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - y := x[4:] - y[0] = byte(l) - copy(y[1:], []byte(m.proto[0:l])) - y = y[1+l:] - y[0] = byte(padding) - - m.raw = x - - return x -} - -func (m *nextProtoMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - data = data[4:] - protoLen := int(data[0]) - data = data[1:] - if len(data) < protoLen { - return false - } - m.proto = string(data[0:protoLen]) - data = data[protoLen:] - - if len(data) < 1 { - return false - } - paddingLen := int(data[0]) - data = data[1:] - if len(data) != paddingLen { - return false - } - - return true -} - -type certificateRequestMsg struct { - raw []byte - // hasSignatureAndHash indicates whether this message includes a list - // of signature and hash functions. This change was introduced with TLS - // 1.2. - hasSignatureAndHash bool - - certificateTypes []byte - signatureAndHashes []signatureAndHash - certificateAuthorities [][]byte -} - -func (m *certificateRequestMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateRequestMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.certificateTypes, m1.certificateTypes) && - eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) && - eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) -} - -func (m *certificateRequestMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See http://tools.ietf.org/html/rfc4346#section-7.4.4 - length := 1 + len(m.certificateTypes) + 2 - casLength := 0 - for _, ca := range m.certificateAuthorities { - casLength += 2 + len(ca) - } - length += casLength - - if m.hasSignatureAndHash { - length += 2 + 2*len(m.signatureAndHashes) - } - - x = make([]byte, 4+length) - x[0] = typeCertificateRequest - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - x[4] = uint8(len(m.certificateTypes)) - - copy(x[5:], m.certificateTypes) - y := x[5+len(m.certificateTypes):] - - if m.hasSignatureAndHash { - n := len(m.signatureAndHashes) * 2 - y[0] = uint8(n >> 8) - y[1] = uint8(n) - y = y[2:] - for _, sigAndHash := range m.signatureAndHashes { - y[0] = sigAndHash.hash - y[1] = sigAndHash.signature - y = y[2:] - } - } - - y[0] = uint8(casLength >> 8) - y[1] = uint8(casLength) - y = y[2:] - for _, ca := range m.certificateAuthorities { - y[0] = uint8(len(ca) >> 8) - y[1] = uint8(len(ca)) - y = y[2:] - copy(y, ca) - y = y[len(ca):] - } - - m.raw = x - return -} - -func (m *certificateRequestMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - numCertTypes := int(data[4]) - data = data[5:] - if numCertTypes == 0 || len(data) <= numCertTypes { - return false - } - - m.certificateTypes = make([]byte, numCertTypes) - if copy(m.certificateTypes, data) != numCertTypes { - return false - } - - data = data[numCertTypes:] - - if m.hasSignatureAndHash { - if len(data) < 2 { - return false - } - sigAndHashLen := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if sigAndHashLen&1 != 0 { - return false - } - if len(data) < int(sigAndHashLen) { - return false - } - numSigAndHash := sigAndHashLen / 2 - m.signatureAndHashes = make([]signatureAndHash, numSigAndHash) - for i := range m.signatureAndHashes { - m.signatureAndHashes[i].hash = data[0] - m.signatureAndHashes[i].signature = data[1] - data = data[2:] - } - } - - if len(data) < 2 { - return false - } - casLength := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if len(data) < int(casLength) { - return false - } - cas := make([]byte, casLength) - copy(cas, data) - data = data[casLength:] - - m.certificateAuthorities = nil - for len(cas) > 0 { - if len(cas) < 2 { - return false - } - caLen := uint16(cas[0])<<8 | uint16(cas[1]) - cas = cas[2:] - - if len(cas) < int(caLen) { - return false - } - - m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen]) - cas = cas[caLen:] - } - if len(data) > 0 { - return false - } - - return true -} - -type certificateVerifyMsg struct { - raw []byte - hasSignatureAndHash bool - signatureAndHash signatureAndHash - signature []byte -} - -func (m *certificateVerifyMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateVerifyMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.hasSignatureAndHash == m1.hasSignatureAndHash && - m.signatureAndHash.hash == m1.signatureAndHash.hash && - m.signatureAndHash.signature == m1.signatureAndHash.signature && - bytes.Equal(m.signature, m1.signature) -} - -func (m *certificateVerifyMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See http://tools.ietf.org/html/rfc4346#section-7.4.8 - siglength := len(m.signature) - length := 2 + siglength - if m.hasSignatureAndHash { - length += 2 - } - x = make([]byte, 4+length) - x[0] = typeCertificateVerify - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - y := x[4:] - if m.hasSignatureAndHash { - y[0] = m.signatureAndHash.hash - y[1] = m.signatureAndHash.signature - y = y[2:] - } - y[0] = uint8(siglength >> 8) - y[1] = uint8(siglength) - copy(y[2:], m.signature) - - m.raw = x - - return -} - -func (m *certificateVerifyMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 6 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - data = data[4:] - if m.hasSignatureAndHash { - m.signatureAndHash.hash = data[0] - m.signatureAndHash.signature = data[1] - data = data[2:] - } - - if len(data) < 2 { - return false - } - siglength := int(data[0])<<8 + int(data[1]) - data = data[2:] - if len(data) != siglength { - return false - } - - m.signature = data - - return true -} - -type newSessionTicketMsg struct { - raw []byte - ticket []byte -} - -func (m *newSessionTicketMsg) equal(i interface{}) bool { - m1, ok := i.(*newSessionTicketMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.ticket, m1.ticket) -} - -func (m *newSessionTicketMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See http://tools.ietf.org/html/rfc5077#section-3.3 - ticketLen := len(m.ticket) - length := 2 + 4 + ticketLen - x = make([]byte, 4+length) - x[0] = typeNewSessionTicket - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[8] = uint8(ticketLen >> 8) - x[9] = uint8(ticketLen) - copy(x[10:], m.ticket) - - m.raw = x - - return -} - -func (m *newSessionTicketMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 10 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - ticketLen := int(data[8])<<8 + int(data[9]) - if len(data)-10 != ticketLen { - return false - } - - m.ticket = data[10:] - - return true -} - -type helloRequestMsg struct { -} - -func (*helloRequestMsg) marshal() []byte { - return []byte{typeHelloRequest, 0, 0, 0} -} - -func (*helloRequestMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -func eqUint16s(x, y []uint16) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - if y[i] != v { - return false - } - } - return true -} - -func eqStrings(x, y []string) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - if y[i] != v { - return false - } - } - return true -} - -func eqByteSlices(x, y [][]byte) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - if !bytes.Equal(v, y[i]) { - return false - } - } - return true -} - -func eqSignatureAndHashes(x, y []signatureAndHash) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - v2 := y[i] - if v.hash != v2.hash || v.signature != v2.signature { - return false - } - } - return true -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_messages_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_messages_test.go deleted file mode 100644 index 4f569eeb13..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_messages_test.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "math/rand" - "reflect" - "testing" - "testing/quick" -) - -var tests = []interface{}{ - &clientHelloMsg{}, - &serverHelloMsg{}, - &finishedMsg{}, - - &certificateMsg{}, - &certificateRequestMsg{}, - &certificateVerifyMsg{}, - &certificateStatusMsg{}, - &clientKeyExchangeMsg{}, - &nextProtoMsg{}, - &newSessionTicketMsg{}, - &sessionState{}, -} - -type testMessage interface { - marshal() []byte - unmarshal([]byte) bool - equal(interface{}) bool -} - -func TestMarshalUnmarshal(t *testing.T) { - rand := rand.New(rand.NewSource(0)) - - for i, iface := range tests { - ty := reflect.ValueOf(iface).Type() - - n := 100 - if testing.Short() { - n = 5 - } - for j := 0; j < n; j++ { - v, ok := quick.Value(ty, rand) - if !ok { - t.Errorf("#%d: failed to create value", i) - break - } - - m1 := v.Interface().(testMessage) - marshaled := m1.marshal() - m2 := iface.(testMessage) - if !m2.unmarshal(marshaled) { - t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled) - break - } - m2.marshal() // to fill any marshal cache in the message - - if !m1.equal(m2) { - t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled) - break - } - - if i >= 3 { - // The first three message types (ClientHello, - // ServerHello and Finished) are allowed to - // have parsable prefixes because the extension - // data is optional and the length of the - // Finished varies across versions. - for j := 0; j < len(marshaled); j++ { - if m2.unmarshal(marshaled[0:j]) { - t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1) - break - } - } - } - } - } -} - -func TestFuzz(t *testing.T) { - rand := rand.New(rand.NewSource(0)) - for _, iface := range tests { - m := iface.(testMessage) - - for j := 0; j < 1000; j++ { - len := rand.Intn(100) - bytes := randomBytes(len, rand) - // This just looks for crashes due to bounds errors etc. - m.unmarshal(bytes) - } - } -} - -func randomBytes(n int, rand *rand.Rand) []byte { - r := make([]byte, n) - for i := 0; i < n; i++ { - r[i] = byte(rand.Int31()) - } - return r -} - -func randomString(n int, rand *rand.Rand) string { - b := randomBytes(n, rand) - return string(b) -} - -func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &clientHelloMsg{} - m.vers = uint16(rand.Intn(65536)) - m.random = randomBytes(32, rand) - m.sessionId = randomBytes(rand.Intn(32), rand) - m.cipherSuites = make([]uint16, rand.Intn(63)+1) - for i := 0; i < len(m.cipherSuites); i++ { - m.cipherSuites[i] = uint16(rand.Int31()) - } - m.compressionMethods = randomBytes(rand.Intn(63)+1, rand) - if rand.Intn(10) > 5 { - m.nextProtoNeg = true - } - if rand.Intn(10) > 5 { - m.serverName = randomString(rand.Intn(255), rand) - } - m.ocspStapling = rand.Intn(10) > 5 - m.supportedPoints = randomBytes(rand.Intn(5)+1, rand) - m.supportedCurves = make([]uint16, rand.Intn(5)+1) - for i := range m.supportedCurves { - m.supportedCurves[i] = uint16(rand.Intn(30000)) - } - if rand.Intn(10) > 5 { - m.ticketSupported = true - if rand.Intn(10) > 5 { - m.sessionTicket = randomBytes(rand.Intn(300), rand) - } - } - if rand.Intn(10) > 5 { - m.signatureAndHashes = supportedSKXSignatureAlgorithms - } - - return reflect.ValueOf(m) -} - -func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &serverHelloMsg{} - m.vers = uint16(rand.Intn(65536)) - m.random = randomBytes(32, rand) - m.sessionId = randomBytes(rand.Intn(32), rand) - m.cipherSuite = uint16(rand.Int31()) - m.compressionMethod = uint8(rand.Intn(256)) - - if rand.Intn(10) > 5 { - m.nextProtoNeg = true - - n := rand.Intn(10) - m.nextProtos = make([]string, n) - for i := 0; i < n; i++ { - m.nextProtos[i] = randomString(20, rand) - } - } - - if rand.Intn(10) > 5 { - m.ocspStapling = true - } - if rand.Intn(10) > 5 { - m.ticketSupported = true - } - - return reflect.ValueOf(m) -} - -func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &certificateMsg{} - numCerts := rand.Intn(20) - m.certificates = make([][]byte, numCerts) - for i := 0; i < numCerts; i++ { - m.certificates[i] = randomBytes(rand.Intn(10)+1, rand) - } - return reflect.ValueOf(m) -} - -func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &certificateRequestMsg{} - m.certificateTypes = randomBytes(rand.Intn(5)+1, rand) - numCAs := rand.Intn(100) - m.certificateAuthorities = make([][]byte, numCAs) - for i := 0; i < numCAs; i++ { - m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand) - } - return reflect.ValueOf(m) -} - -func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &certificateVerifyMsg{} - m.signature = randomBytes(rand.Intn(15)+1, rand) - return reflect.ValueOf(m) -} - -func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &certificateStatusMsg{} - if rand.Intn(10) > 5 { - m.statusType = statusTypeOCSP - m.response = randomBytes(rand.Intn(10)+1, rand) - } else { - m.statusType = 42 - } - return reflect.ValueOf(m) -} - -func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &clientKeyExchangeMsg{} - m.ciphertext = randomBytes(rand.Intn(1000)+1, rand) - return reflect.ValueOf(m) -} - -func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &finishedMsg{} - m.verifyData = randomBytes(12, rand) - return reflect.ValueOf(m) -} - -func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &nextProtoMsg{} - m.proto = randomString(rand.Intn(255), rand) - return reflect.ValueOf(m) -} - -func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &newSessionTicketMsg{} - m.ticket = randomBytes(rand.Intn(4), rand) - return reflect.ValueOf(m) -} - -func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value { - s := &sessionState{} - s.vers = uint16(rand.Intn(10000)) - s.cipherSuite = uint16(rand.Intn(10000)) - s.masterSecret = randomBytes(rand.Intn(100), rand) - numCerts := rand.Intn(20) - s.certificates = make([][]byte, numCerts) - for i := 0; i < numCerts; i++ { - s.certificates[i] = randomBytes(rand.Intn(10)+1, rand) - } - return reflect.ValueOf(s) -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_server.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_server.go deleted file mode 100644 index c9ccf675cd..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_server.go +++ /dev/null @@ -1,638 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "encoding/asn1" - "errors" - "io" -) - -// serverHandshakeState contains details of a server handshake in progress. -// It's discarded once the handshake has completed. -type serverHandshakeState struct { - c *Conn - clientHello *clientHelloMsg - hello *serverHelloMsg - suite *cipherSuite - ellipticOk bool - ecdsaOk bool - sessionState *sessionState - finishedHash finishedHash - masterSecret []byte - certsFromClient [][]byte - cert *Certificate -} - -// serverHandshake performs a TLS handshake as a server. -func (c *Conn) serverHandshake() error { - config := c.config - - // If this is the first server handshake, we generate a random key to - // encrypt the tickets with. - config.serverInitOnce.Do(config.serverInit) - - hs := serverHandshakeState{ - c: c, - } - isResume, err := hs.readClientHello() - if err != nil { - return err - } - - // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3 - if isResume { - // The client has included a session ticket and so we do an abbreviated handshake. - if err := hs.doResumeHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.sendFinished(); err != nil { - return err - } - if err := hs.readFinished(); err != nil { - return err - } - c.didResume = true - } else { - // The client didn't include a session ticket, or it wasn't - // valid so we do a full handshake. - if err := hs.doFullHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.readFinished(); err != nil { - return err - } - if err := hs.sendSessionTicket(); err != nil { - return err - } - if err := hs.sendFinished(); err != nil { - return err - } - } - c.handshakeComplete = true - - return nil -} - -// readClientHello reads a ClientHello message from the client and decides -// whether we will perform session resumption. -func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) { - config := hs.c.config - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return false, err - } - var ok bool - hs.clientHello, ok = msg.(*clientHelloMsg) - if !ok { - return false, c.sendAlert(alertUnexpectedMessage) - } - c.vers, ok = config.mutualVersion(hs.clientHello.vers) - if !ok { - return false, c.sendAlert(alertProtocolVersion) - } - c.haveVers = true - - hs.finishedHash = newFinishedHash(c.vers) - hs.finishedHash.Write(hs.clientHello.marshal()) - - hs.hello = new(serverHelloMsg) - - supportedCurve := false -Curves: - for _, curve := range hs.clientHello.supportedCurves { - switch curve { - case curveP256, curveP384, curveP521: - supportedCurve = true - break Curves - } - } - - supportedPointFormat := false - for _, pointFormat := range hs.clientHello.supportedPoints { - if pointFormat == pointFormatUncompressed { - supportedPointFormat = true - break - } - } - hs.ellipticOk = supportedCurve && supportedPointFormat - - foundCompression := false - // We only support null compression, so check that the client offered it. - for _, compression := range hs.clientHello.compressionMethods { - if compression == compressionNone { - foundCompression = true - break - } - } - - if !foundCompression { - return false, c.sendAlert(alertHandshakeFailure) - } - - hs.hello.vers = c.vers - t := uint32(config.time().Unix()) - hs.hello.random = make([]byte, 32) - hs.hello.random[0] = byte(t >> 24) - hs.hello.random[1] = byte(t >> 16) - hs.hello.random[2] = byte(t >> 8) - hs.hello.random[3] = byte(t) - _, err = io.ReadFull(config.rand(), hs.hello.random[4:]) - if err != nil { - return false, c.sendAlert(alertInternalError) - } - hs.hello.compressionMethod = compressionNone - if len(hs.clientHello.serverName) > 0 { - c.serverName = hs.clientHello.serverName - } - // Although sending an empty NPN extension is reasonable, Firefox has - // had a bug around this. Best to send nothing at all if - // config.NextProtos is empty. See - // https://code.google.com/p/go/issues/detail?id=5445. - if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 { - hs.hello.nextProtoNeg = true - hs.hello.nextProtos = config.NextProtos - } - - if len(config.Certificates) == 0 { - return false, c.sendAlert(alertInternalError) - } - hs.cert = &config.Certificates[0] - if len(hs.clientHello.serverName) > 0 { - hs.cert = config.getCertificateForName(hs.clientHello.serverName) - } - - _, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey) - - if hs.checkForResumption() { - return true, nil - } - - var preferenceList, supportedList []uint16 - if c.config.PreferServerCipherSuites { - preferenceList = c.config.cipherSuites() - supportedList = hs.clientHello.cipherSuites - } else { - preferenceList = hs.clientHello.cipherSuites - supportedList = c.config.cipherSuites() - } - - for _, id := range preferenceList { - if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil { - break - } - } - - if hs.suite == nil { - return false, c.sendAlert(alertHandshakeFailure) - } - - return false, nil -} - -// checkForResumption returns true if we should perform resumption on this connection. -func (hs *serverHandshakeState) checkForResumption() bool { - c := hs.c - - var ok bool - if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok { - return false - } - - if hs.sessionState.vers > hs.clientHello.vers { - return false - } - if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers { - return false - } - - cipherSuiteOk := false - // Check that the client is still offering the ciphersuite in the session. - for _, id := range hs.clientHello.cipherSuites { - if id == hs.sessionState.cipherSuite { - cipherSuiteOk = true - break - } - } - if !cipherSuiteOk { - return false - } - - // Check that we also support the ciphersuite from the session. - hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk) - if hs.suite == nil { - return false - } - - sessionHasClientCerts := len(hs.sessionState.certificates) != 0 - needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert - if needClientCerts && !sessionHasClientCerts { - return false - } - if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { - return false - } - - return true -} - -func (hs *serverHandshakeState) doResumeHandshake() error { - c := hs.c - - hs.hello.cipherSuite = hs.suite.id - // We echo the client's session ID in the ServerHello to let it know - // that we're doing a resumption. - hs.hello.sessionId = hs.clientHello.sessionId - hs.finishedHash.Write(hs.hello.marshal()) - c.writeRecord(recordTypeHandshake, hs.hello.marshal()) - - if len(hs.sessionState.certificates) > 0 { - if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil { - return err - } - } - - hs.masterSecret = hs.sessionState.masterSecret - - return nil -} - -func (hs *serverHandshakeState) doFullHandshake() error { - config := hs.c.config - c := hs.c - - if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { - hs.hello.ocspStapling = true - } - - hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled - hs.hello.cipherSuite = hs.suite.id - hs.finishedHash.Write(hs.hello.marshal()) - c.writeRecord(recordTypeHandshake, hs.hello.marshal()) - - certMsg := new(certificateMsg) - certMsg.certificates = hs.cert.Certificate - hs.finishedHash.Write(certMsg.marshal()) - c.writeRecord(recordTypeHandshake, certMsg.marshal()) - - if hs.hello.ocspStapling { - certStatus := new(certificateStatusMsg) - certStatus.statusType = statusTypeOCSP - certStatus.response = hs.cert.OCSPStaple - hs.finishedHash.Write(certStatus.marshal()) - c.writeRecord(recordTypeHandshake, certStatus.marshal()) - } - - keyAgreement := hs.suite.ka(c.vers) - skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - if skx != nil { - hs.finishedHash.Write(skx.marshal()) - c.writeRecord(recordTypeHandshake, skx.marshal()) - } - - if config.ClientAuth >= RequestClientCert { - // Request a client certificate - certReq := new(certificateRequestMsg) - certReq.certificateTypes = []byte{ - byte(certTypeRSASign), - byte(certTypeECDSASign), - } - if c.vers >= VersionTLS12 { - certReq.hasSignatureAndHash = true - certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms - } - - // An empty list of certificateAuthorities signals to - // the client that it may send any certificate in response - // to our request. When we know the CAs we trust, then - // we can send them down, so that the client can choose - // an appropriate certificate to give to us. - if config.ClientCAs != nil { - certReq.certificateAuthorities = config.ClientCAs.Subjects() - } - hs.finishedHash.Write(certReq.marshal()) - c.writeRecord(recordTypeHandshake, certReq.marshal()) - } - - helloDone := new(serverHelloDoneMsg) - hs.finishedHash.Write(helloDone.marshal()) - c.writeRecord(recordTypeHandshake, helloDone.marshal()) - - var pub crypto.PublicKey // public key for client auth, if any - - msg, err := c.readHandshake() - if err != nil { - return err - } - - var ok bool - // If we requested a client certificate, then the client must send a - // certificate message, even if it's empty. - if config.ClientAuth >= RequestClientCert { - if certMsg, ok = msg.(*certificateMsg); !ok { - return c.sendAlert(alertHandshakeFailure) - } - hs.finishedHash.Write(certMsg.marshal()) - - if len(certMsg.certificates) == 0 { - // The client didn't actually send a certificate - switch config.ClientAuth { - case RequireAnyClientCert, RequireAndVerifyClientCert: - c.sendAlert(alertBadCertificate) - return errors.New("tls: client didn't provide a certificate") - } - } - - pub, err = hs.processCertsFromClient(certMsg.certificates) - if err != nil { - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - // Get client key exchange - ckx, ok := msg.(*clientKeyExchangeMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - hs.finishedHash.Write(ckx.marshal()) - - // If we received a client cert in response to our certificate request message, - // the client will send us a certificateVerifyMsg immediately after the - // clientKeyExchangeMsg. This message is a digest of all preceding - // handshake-layer messages that is signed using the private key corresponding - // to the client's certificate. This allows us to verify that the client is in - // possession of the private key of the certificate. - if len(c.peerCertificates) > 0 { - msg, err = c.readHandshake() - if err != nil { - return err - } - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - switch key := pub.(type) { - case *ecdsa.PublicKey: - ecdsaSig := new(ecdsaSignature) - if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil { - break - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - err = errors.New("ECDSA signature contained zero or negative values") - break - } - digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA) - if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) { - err = errors.New("ECDSA verification failure") - break - } - case *rsa.PublicKey: - digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA) - err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature) - } - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("could not validate signature of connection nonces: " + err.Error()) - } - - hs.finishedHash.Write(certVerify.marshal()) - } - - preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.clientHello.random, hs.hello.random) - - return nil -} - -func (hs *serverHandshakeState) establishKeys() error { - c := hs.c - - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - - var clientCipher, serverCipher interface{} - var clientHash, serverHash macFunction - - if hs.suite.aead == nil { - clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) - clientHash = hs.suite.mac(c.vers, clientMAC) - serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) - serverHash = hs.suite.mac(c.vers, serverMAC) - } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) - } - - c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) - c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) - - return nil -} - -func (hs *serverHandshakeState) readFinished() error { - c := hs.c - - c.readRecord(recordTypeChangeCipherSpec) - if err := c.error(); err != nil { - return err - } - - if hs.hello.nextProtoNeg { - msg, err := c.readHandshake() - if err != nil { - return err - } - nextProto, ok := msg.(*nextProtoMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - hs.finishedHash.Write(nextProto.marshal()) - c.clientProtocol = nextProto.proto - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - clientFinished, ok := msg.(*finishedMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - verify := hs.finishedHash.clientSum(hs.masterSecret) - if len(verify) != len(clientFinished.verifyData) || - subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { - return c.sendAlert(alertHandshakeFailure) - } - - hs.finishedHash.Write(clientFinished.marshal()) - return nil -} - -func (hs *serverHandshakeState) sendSessionTicket() error { - if !hs.hello.ticketSupported { - return nil - } - - c := hs.c - m := new(newSessionTicketMsg) - - var err error - state := sessionState{ - vers: c.vers, - cipherSuite: hs.suite.id, - masterSecret: hs.masterSecret, - certificates: hs.certsFromClient, - } - m.ticket, err = c.encryptTicket(&state) - if err != nil { - return err - } - - hs.finishedHash.Write(m.marshal()) - c.writeRecord(recordTypeHandshake, m.marshal()) - - return nil -} - -func (hs *serverHandshakeState) sendFinished() error { - c := hs.c - - c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - - finished := new(finishedMsg) - finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) - hs.finishedHash.Write(finished.marshal()) - c.writeRecord(recordTypeHandshake, finished.marshal()) - - c.cipherSuite = hs.suite.id - - return nil -} - -// processCertsFromClient takes a chain of client certificates either from a -// Certificates message or from a sessionState and verifies them. It returns -// the public key of the leaf certificate. -func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) { - c := hs.c - - hs.certsFromClient = certificates - certs := make([]*x509.Certificate, len(certificates)) - var err error - for i, asn1Data := range certificates { - if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { - c.sendAlert(alertBadCertificate) - return nil, errors.New("tls: failed to parse client certificate: " + err.Error()) - } - } - - if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { - opts := x509.VerifyOptions{ - Roots: c.config.ClientCAs, - CurrentTime: c.config.time(), - Intermediates: x509.NewCertPool(), - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - } - - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - - chains, err := certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return nil, errors.New("tls: failed to verify client's certificate: " + err.Error()) - } - - ok := false - for _, ku := range certs[0].ExtKeyUsage { - if ku == x509.ExtKeyUsageClientAuth { - ok = true - break - } - } - if !ok { - c.sendAlert(alertHandshakeFailure) - return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication") - } - - c.verifiedChains = chains - } - - if len(certs) > 0 { - var pub crypto.PublicKey - switch key := certs[0].PublicKey.(type) { - case *ecdsa.PublicKey, *rsa.PublicKey: - pub = key - default: - return nil, c.sendAlert(alertUnsupportedCertificate) - } - c.peerCertificates = certs - return pub, nil - } - - return nil, nil -} - -// tryCipherSuite returns a cipherSuite with the given id if that cipher suite -// is acceptable to use. -func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite { - for _, supported := range supportedCipherSuites { - if id == supported { - var candidate *cipherSuite - - for _, s := range cipherSuites { - if s.id == id { - candidate = s - break - } - } - if candidate == nil { - continue - } - // Don't select a ciphersuite which we can't - // support for this client. - if (candidate.flags&suiteECDHE != 0) && !ellipticOk { - continue - } - if (candidate.flags&suiteECDSA != 0) != ecdsaOk { - continue - } - if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { - continue - } - return candidate - } - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_server_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_server_test.go deleted file mode 100644 index c08eba7f17..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/handshake_server_test.go +++ /dev/null @@ -1,3796 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "bytes" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "crypto/x509" - "encoding/hex" - "encoding/pem" - "flag" - "fmt" - "io" - "log" - "math/big" - "net" - "os" - "strconv" - "strings" - "sync" - "testing" - "time" -) - -type zeroSource struct{} - -func (zeroSource) Read(b []byte) (n int, err error) { - for i := range b { - b[i] = 0 - } - - return len(b), nil -} - -var testConfig *Config - -func init() { - testConfig = new(Config) - testConfig.Time = func() time.Time { return time.Unix(0, 0) } - testConfig.Rand = zeroSource{} - testConfig.Certificates = make([]Certificate, 2) - testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate} - testConfig.Certificates[0].PrivateKey = testRSAPrivateKey - testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate} - testConfig.Certificates[1].PrivateKey = testRSAPrivateKey - testConfig.BuildNameToCertificate() - testConfig.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA} - testConfig.InsecureSkipVerify = true - testConfig.MinVersion = VersionSSL30 - testConfig.MaxVersion = VersionTLS10 -} - -func testClientHelloFailure(t *testing.T, m handshakeMessage, expected error) { - // Create in-memory network connection, - // send message to server. Should return - // expected error. - c, s := net.Pipe() - go func() { - cli := Client(c, testConfig) - if ch, ok := m.(*clientHelloMsg); ok { - cli.vers = ch.vers - } - cli.writeRecord(recordTypeHandshake, m.marshal()) - c.Close() - }() - err := Server(s, testConfig).Handshake() - s.Close() - if e, ok := err.(*net.OpError); !ok || e.Err != expected { - t.Errorf("Got error: %s; expected: %s", err, expected) - } -} - -func TestSimpleError(t *testing.T) { - testClientHelloFailure(t, &serverHelloDoneMsg{}, alertUnexpectedMessage) -} - -var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205} - -func TestRejectBadProtocolVersion(t *testing.T) { - for _, v := range badProtocolVersions { - testClientHelloFailure(t, &clientHelloMsg{vers: v}, alertProtocolVersion) - } -} - -func TestNoSuiteOverlap(t *testing.T) { - clientHello := &clientHelloMsg{ - vers: 0x0301, - cipherSuites: []uint16{0xff00}, - compressionMethods: []uint8{0}, - } - testClientHelloFailure(t, clientHello, alertHandshakeFailure) -} - -func TestNoCompressionOverlap(t *testing.T) { - clientHello := &clientHelloMsg{ - vers: 0x0301, - cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, - compressionMethods: []uint8{0xff}, - } - testClientHelloFailure(t, clientHello, alertHandshakeFailure) -} - -func TestTLS12OnlyCipherSuites(t *testing.T) { - // Test that a Server doesn't select a TLS 1.2-only cipher suite when - // the client negotiates TLS 1.1. - var zeros [32]byte - - clientHello := &clientHelloMsg{ - vers: VersionTLS11, - random: zeros[:], - cipherSuites: []uint16{ - // The Server, by default, will use the client's - // preference order. So the GCM cipher suite - // will be selected unless it's excluded because - // of the version in this ClientHello. - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_RSA_WITH_RC4_128_SHA, - }, - compressionMethods: []uint8{compressionNone}, - supportedCurves: []uint16{curveP256, curveP384, curveP521}, - supportedPoints: []uint8{pointFormatUncompressed}, - } - - c, s := net.Pipe() - var reply interface{} - var clientErr error - go func() { - cli := Client(c, testConfig) - cli.vers = clientHello.vers - cli.writeRecord(recordTypeHandshake, clientHello.marshal()) - reply, clientErr = cli.readHandshake() - c.Close() - }() - config := *testConfig - config.CipherSuites = clientHello.cipherSuites - Server(s, &config).Handshake() - s.Close() - if clientErr != nil { - t.Fatal(clientErr) - } - serverHello, ok := reply.(*serverHelloMsg) - if !ok { - t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply) - } - if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA { - t.Fatalf("bad cipher suite from server: %x", s) - } -} - -func TestAlertForwarding(t *testing.T) { - c, s := net.Pipe() - go func() { - Client(c, testConfig).sendAlert(alertUnknownCA) - c.Close() - }() - - err := Server(s, testConfig).Handshake() - s.Close() - if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) { - t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA)) - } -} - -func TestClose(t *testing.T) { - c, s := net.Pipe() - go c.Close() - - err := Server(s, testConfig).Handshake() - s.Close() - if err != io.EOF { - t.Errorf("Got error: %s; expected: %s", err, io.EOF) - } -} - -func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, err error) { - c, s := net.Pipe() - go func() { - cli := Client(c, clientConfig) - cli.Handshake() - c.Close() - }() - server := Server(s, serverConfig) - err = server.Handshake() - if err == nil { - state = server.ConnectionState() - } - s.Close() - return -} - -func TestCipherSuitePreference(t *testing.T) { - serverConfig := &Config{ - CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, - Certificates: testConfig.Certificates, - MaxVersion: VersionTLS11, - } - clientConfig := &Config{ - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA}, - InsecureSkipVerify: true, - } - state, err := testHandshake(clientConfig, serverConfig) - if err != nil { - t.Fatalf("handshake failed: %s", err) - } - if state.CipherSuite != TLS_RSA_WITH_AES_128_CBC_SHA { - // By default the server should use the client's preference. - t.Fatalf("Client's preference was not used, got %x", state.CipherSuite) - } - - serverConfig.PreferServerCipherSuites = true - state, err = testHandshake(clientConfig, serverConfig) - if err != nil { - t.Fatalf("handshake failed: %s", err) - } - if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA { - t.Fatalf("Server's preference was not used, got %x", state.CipherSuite) - } -} - -func testServerScript(t *testing.T, name string, serverScript [][]byte, config *Config, peers []*x509.Certificate) { - c, s := net.Pipe() - srv := Server(s, config) - pchan := make(chan []*x509.Certificate, 1) - go func() { - srv.Write([]byte("hello, world\n")) - srv.Close() - s.Close() - st := srv.ConnectionState() - pchan <- st.PeerCertificates - }() - - for i, b := range serverScript { - if i%2 == 0 { - c.Write(b) - continue - } - bb := make([]byte, len(b)) - n, err := io.ReadFull(c, bb) - if err != nil { - t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", name, i, err, n, len(bb), bb[:n], b) - } - if !bytes.Equal(b, bb) { - t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b) - } - } - c.Close() - - if peers != nil { - gotpeers := <-pchan - if len(peers) == len(gotpeers) { - for i := range peers { - if !peers[i].Equal(gotpeers[i]) { - t.Fatalf("%s: mismatch on peer cert %d", name, i) - } - } - } else { - t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", name, len(peers), len(gotpeers)) - } - } -} - -func TestHandshakeServerRSARC4(t *testing.T) { - testServerScript(t, "RSA-RC4", rsaRC4ServerScript, testConfig, nil) -} - -func TestHandshakeServerRSA3DES(t *testing.T) { - des3Config := new(Config) - *des3Config = *testConfig - des3Config.CipherSuites = []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA} - testServerScript(t, "RSA-3DES", rsaDES3ServerScript, des3Config, nil) -} - -func TestHandshakeServerRSAAES(t *testing.T) { - aesConfig := new(Config) - *aesConfig = *testConfig - aesConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_CBC_SHA} - testServerScript(t, "RSA-AES", rsaAESServerScript, aesConfig, nil) -} - -func TestHandshakeServerECDHEECDSAAES(t *testing.T) { - ecdsaConfig := new(Config) - *ecdsaConfig = *testConfig - ecdsaConfig.Certificates = make([]Certificate, 1) - ecdsaConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate} - ecdsaConfig.Certificates[0].PrivateKey = testECDSAPrivateKey - ecdsaConfig.BuildNameToCertificate() - ecdsaConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} - testServerScript(t, "ECDHE-ECDSA-AES", ecdheECDSAAESServerScript, ecdsaConfig, nil) -} - -func TestHandshakeServerSSLv3(t *testing.T) { - testServerScript(t, "SSLv3", sslv3ServerScript, testConfig, nil) -} - -// TestHandshakeServerSNI involves a client sending an SNI extension of -// "snitest.com", which happens to match the CN of testSNICertificate. The test -// verifies that the server correctly selects that certificate. -func TestHandshakeServerSNI(t *testing.T) { - testServerScript(t, "SNI", selectCertificateBySNIScript, testConfig, nil) -} - -func TestResumption(t *testing.T) { - testServerScript(t, "IssueTicket", issueSessionTicketTest, testConfig, nil) - testServerScript(t, "Resume", serverResumeTest, testConfig, nil) -} - -func TestTLS12ClientCertServer(t *testing.T) { - config := *testConfig - config.MaxVersion = VersionTLS12 - config.ClientAuth = RequireAnyClientCert - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA} - - testServerScript(t, "TLS12", tls12ServerScript, &config, nil) -} - -type clientauthTest struct { - name string - clientauth ClientAuthType - peers []*x509.Certificate - script [][]byte -} - -func TestClientAuthRSA(t *testing.T) { - for _, cat := range clientauthRSATests { - t.Log("running", cat.name) - cfg := new(Config) - *cfg = *testConfig - cfg.ClientAuth = cat.clientauth - testServerScript(t, cat.name, cat.script, cfg, cat.peers) - } -} - -func TestClientAuthECDSA(t *testing.T) { - for _, cat := range clientauthECDSATests { - t.Log("running", cat.name) - cfg := new(Config) - *cfg = *testConfig - cfg.Certificates = make([]Certificate, 1) - cfg.Certificates[0].Certificate = [][]byte{testECDSACertificate} - cfg.Certificates[0].PrivateKey = testECDSAPrivateKey - cfg.BuildNameToCertificate() - cfg.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} - cfg.ClientAuth = cat.clientauth - testServerScript(t, cat.name, cat.script, cfg, cat.peers) - } -} - -// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with -// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate. -func TestCipherSuiteCertPreferance(t *testing.T) { - var config = *testConfig - config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} - config.MaxVersion = VersionTLS11 - config.PreferServerCipherSuites = true - testServerScript(t, "CipherSuiteCertPreference", tls11ECDHEAESServerScript, &config, nil) - - config = *testConfig - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} - config.Certificates = []Certificate{ - Certificate{ - Certificate: [][]byte{testECDSACertificate}, - PrivateKey: testECDSAPrivateKey, - }, - } - config.BuildNameToCertificate() - config.PreferServerCipherSuites = true - testServerScript(t, "CipherSuiteCertPreference2", ecdheECDSAAESServerScript, &config, nil) -} - -func TestTLS11Server(t *testing.T) { - var config = *testConfig - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} - config.MaxVersion = VersionTLS11 - testServerScript(t, "TLS11", tls11ECDHEAESServerScript, &config, nil) -} - -func TestAESGCM(t *testing.T) { - var config = *testConfig - config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256} - config.MaxVersion = VersionTLS12 - testServerScript(t, "AES-GCM", aesGCMServerScript, &config, nil) -} - -// recordingConn is a net.Conn that records the traffic that passes through it. -// WriteTo can be used to produce Go code that contains the recorded traffic. -type recordingConn struct { - net.Conn - lock sync.Mutex - flows [][]byte - currentlyReading bool -} - -func (r *recordingConn) Read(b []byte) (n int, err error) { - if n, err = r.Conn.Read(b); n == 0 { - return - } - b = b[:n] - - r.lock.Lock() - defer r.lock.Unlock() - - if l := len(r.flows); l == 0 || !r.currentlyReading { - buf := make([]byte, len(b)) - copy(buf, b) - r.flows = append(r.flows, buf) - } else { - r.flows[l-1] = append(r.flows[l-1], b[:n]...) - } - r.currentlyReading = true - return -} - -func (r *recordingConn) Write(b []byte) (n int, err error) { - if n, err = r.Conn.Write(b); n == 0 { - return - } - b = b[:n] - - r.lock.Lock() - defer r.lock.Unlock() - - if l := len(r.flows); l == 0 || r.currentlyReading { - buf := make([]byte, len(b)) - copy(buf, b) - r.flows = append(r.flows, buf) - } else { - r.flows[l-1] = append(r.flows[l-1], b[:n]...) - } - r.currentlyReading = false - return -} - -// WriteTo writes Go source code to w that contains the recorded traffic. -func (r *recordingConn) WriteTo(w io.Writer) { - fmt.Fprintf(w, "var changeMe = [][]byte {\n") - for _, buf := range r.flows { - fmt.Fprintf(w, "\t{") - for i, b := range buf { - if i%8 == 0 { - fmt.Fprintf(w, "\n\t\t") - } - fmt.Fprintf(w, "0x%02x, ", b) - } - fmt.Fprintf(w, "\n\t},\n") - } - fmt.Fprintf(w, "}\n") -} - -var serve = flag.Bool("serve", false, "run a TLS server on :10443") -var testCipherSuites = flag.String("ciphersuites", - "0x"+strconv.FormatInt(int64(TLS_RSA_WITH_RC4_128_SHA), 16), - "cipher suites to accept in serving mode") -var testMinVersion = flag.String("minversion", - "0x"+strconv.FormatInt(int64(VersionSSL30), 16), - "minimum version to negotiate") -var testMaxVersion = flag.String("maxversion", - "0x"+strconv.FormatInt(int64(VersionTLS10), 16), - "maximum version to negotiate") -var testClientAuth = flag.Int("clientauth", 0, "value for tls.Config.ClientAuth") - -func GetTestConfig() *Config { - var config = *testConfig - - minVersion, err := strconv.ParseUint(*testMinVersion, 0, 64) - if err != nil { - panic(err) - } - config.MinVersion = uint16(minVersion) - maxVersion, err := strconv.ParseUint(*testMaxVersion, 0, 64) - if err != nil { - panic(err) - } - config.MaxVersion = uint16(maxVersion) - - suites := strings.Split(*testCipherSuites, ",") - config.CipherSuites = make([]uint16, len(suites)) - for i := range suites { - suite, err := strconv.ParseUint(suites[i], 0, 64) - if err != nil { - panic(err) - } - config.CipherSuites[i] = uint16(suite) - } - - ecdsa := false - for _, suite := range config.CipherSuites { - switch suite { - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - ecdsa = true - } - } - if ecdsa { - config.Certificates = nil - if !*connect { - config.Certificates = make([]Certificate, 1) - config.Certificates[0].Certificate = [][]byte{testECDSACertificate} - config.Certificates[0].PrivateKey = testECDSAPrivateKey - } - config.BuildNameToCertificate() - } - - config.ClientAuth = ClientAuthType(*testClientAuth) - return &config -} - -func TestRunServer(t *testing.T) { - if !*serve { - return - } - - config := GetTestConfig() - - const addr = ":10443" - l, err := net.Listen("tcp", addr) - if err != nil { - t.Fatal(err) - } - log.Printf("Now listening for connections on %s", addr) - - for { - tcpConn, err := l.Accept() - if err != nil { - log.Printf("error accepting connection: %s", err) - break - } - - record := &recordingConn{ - Conn: tcpConn, - } - - conn := Server(record, config) - if err := conn.Handshake(); err != nil { - log.Printf("error from TLS handshake: %s", err) - break - } - - _, err = conn.Write([]byte("hello, world\n")) - if err != nil { - log.Printf("error from Write: %s", err) - continue - } - - conn.Close() - - record.WriteTo(os.Stdout) - } -} - -func bigFromString(s string) *big.Int { - ret := new(big.Int) - ret.SetString(s, 10) - return ret -} - -func fromHex(s string) []byte { - b, _ := hex.DecodeString(s) - return b -} - -var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9") - -var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186000400c4a1edbe98f90b4873367ec316561122f23d53c33b4d213dcd6b75e6f6b0dc9adf26c1bcb287f072327cb3642f1c90bcea6823107efee325c0483a69e0286dd33700ef0462dd0da09c706283d881d36431aa9e9731bd96b068c09b23de76643f1a5c7fe9120e5858b65f70dd9bd8ead5d7f5d5ccb9b69f30665b669a20e227e5bffe3b300906072a8648ce3d040103818c0030818802420188a24febe245c5487d1bacf5ed989dae4770c05e1bb62fbdf1b64db76140d311a2ceee0b7e927eff769dc33b7ea53fcefa10e259ec472d7cacda4e970e15a06fd00242014dfcbe67139c2d050ebd3fa38c25c13313830d9406bbd4377af6ec7ac9862eddd711697f857c56defb31782be4c7780daecbbe9e4e3624317b6a0f399512078f2a") - -var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a864886f70d01010530283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d301e170d3132303431313137343033355a170d3133303431313137343533355a30283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d30819d300b06092a864886f70d01010103818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a3323030300e0603551d0f0101ff0404030200a0300d0603551d0e0406040401020304300f0603551d2304083006800401020304300b06092a864886f70d0101050381810089c6455f1c1f5ef8eb1ab174ee2439059f5c4259bb1a8d86cdb1d056f56a717da40e95ab90f59e8deaf627c157995094db0802266eb34fc6842dea8a4b68d9c1389103ab84fb9e1f85d9b5d23ff2312c8670fbb540148245a4ebafe264d90c8a4cf4f85b0fac12ac2fc4a3154bad52462868af96c62c6525d652b6e31845bdcc") - -var testRSAPrivateKey = &rsa.PrivateKey{ - PublicKey: rsa.PublicKey{ - N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"), - E: 65537, - }, - D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"), - Primes: []*big.Int{ - bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"), - bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"), - }, -} - -var testECDSAPrivateKey = &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: &elliptic.CurveParams{ - P: bigFromString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), - N: bigFromString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449"), - B: bigFromString("1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984"), - Gx: bigFromString("2661740802050217063228768716723360960729859168756973147706671368418802944996427808491545080627771902352094241225065558662157113545570916814161637315895999846"), - Gy: bigFromString("3757180025770020463545507224491183603594455134769762486694567779615544477440556316691234405012945539562144444537289428522585666729196580810124344277578376784"), - BitSize: 521, - }, - X: bigFromString("2636411247892461147287360222306590634450676461695221912739908880441342231985950069527906976759812296359387337367668045707086543273113073382714101597903639351"), - Y: bigFromString("3204695818431246682253994090650952614555094516658732116404513121125038617915183037601737180082382202488628239201196033284060130040574800684774115478859677243"), - }, - D: bigFromString("5477294338614160138026852784385529180817726002953041720191098180813046231640184669647735805135001309477695746518160084669446643325196003346204701381388769751"), -} - -func loadPEMCert(in string) *x509.Certificate { - block, _ := pem.Decode([]byte(in)) - if block.Type == "CERTIFICATE" && len(block.Headers) == 0 { - cert, err := x509.ParseCertificate(block.Bytes) - if err == nil { - return cert - } - panic("error parsing cert") - } - panic("error parsing PEM") -} - -// Script of interaction with gnutls implementation. -// The values for this test are obtained by building and running in server mode: -// % go test -test.run "TestRunServer" -serve -// The recorded bytes are written to stdout. -var rsaRC4ServerScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x54, 0x01, 0x00, 0x00, - 0x50, 0x03, 0x01, 0x50, 0x77, 0x3d, 0xbd, 0x32, - 0x13, 0xd7, 0xea, 0x33, 0x65, 0x02, 0xb8, 0x70, - 0xb7, 0x84, 0xc4, 0x05, 0x1f, 0xa4, 0x24, 0xc4, - 0x91, 0x69, 0x04, 0x32, 0x96, 0xfe, 0x5b, 0x49, - 0x71, 0x60, 0x9a, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00, - 0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, - 0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, - 0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, - 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, - 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, - 0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, - 0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, - 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, - 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, - 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, - 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, - 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, - 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, - 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, - 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, - 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, - 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, - 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, - 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, - 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, - 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, - 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, - 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, - 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, - 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, - 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, - 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, - 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, - 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, - 0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, - 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, - 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, - 0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, - 0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, - 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, - 0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, - 0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, - 0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, - 0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, - 0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, - 0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, - 0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, - 0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, - 0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, - 0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, - 0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, - 0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, - 0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, - 0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, - 0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, - 0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, - 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x2d, 0x09, 0x7c, 0x7f, 0xfc, - 0x84, 0xce, 0xb3, 0x30, 0x9b, 0xf9, 0xb7, 0xc8, - 0xc3, 0xff, 0xee, 0x6f, 0x20, 0x8a, 0xf4, 0xfb, - 0x86, 0x55, 0x1f, 0x6a, 0xb4, 0x81, 0x50, 0x3a, - 0x46, 0x1b, 0xd3, 0xca, 0x4b, 0x11, 0xff, 0xef, - 0x02, 0xbc, 0x18, 0xb8, 0x4a, 0x7d, 0x43, 0x23, - 0x96, 0x92, 0x27, 0x7c, 0xca, 0xcf, 0xe6, 0x91, - 0xe8, 0x14, 0x97, 0x68, 0xb4, 0xe5, 0xc0, 0xc9, - 0x23, 0xdd, 0x54, 0x07, 0xa6, 0x2e, 0x8c, 0x98, - 0xfc, 0xc6, 0x8c, 0x04, 0x6b, 0x1b, 0x5f, 0xd5, - 0x3d, 0x8b, 0x6c, 0x55, 0x4f, 0x7a, 0xe6, 0x6c, - 0x74, 0x2c, 0x1e, 0x34, 0xdb, 0xfb, 0x00, 0xb1, - 0x4e, 0x10, 0x21, 0x16, 0xe0, 0x3e, 0xc5, 0x64, - 0x84, 0x28, 0x2b, 0x2b, 0x29, 0x47, 0x51, 0x34, - 0x76, 0x15, 0x20, 0x71, 0x0b, 0x30, 0xa1, 0x85, - 0xd5, 0x15, 0x18, 0x14, 0x64, 0x4b, 0x40, 0x7c, - 0x4f, 0xb3, 0x7b, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xab, 0xee, - 0xf5, 0x97, 0x5f, 0xc6, 0x78, 0xf3, 0xc6, 0x83, - 0x5b, 0x55, 0x4f, 0xcb, 0x45, 0x3f, 0xfa, 0xf7, - 0x05, 0x02, 0xc2, 0x63, 0x87, 0x18, 0xb5, 0x9a, - 0x62, 0xe2, 0x3f, 0x88, 0x5a, 0x60, 0x61, 0x72, - 0xfa, 0x9c, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0x72, 0xa4, 0xe4, 0xaa, 0xd2, - 0xc4, 0x39, 0x7e, 0x2a, 0xc1, 0x6f, 0x34, 0x42, - 0x28, 0xcb, 0x9d, 0x7a, 0x09, 0xca, 0x96, 0xad, - 0x0e, 0x11, 0x51, 0x8a, 0x06, 0xb0, 0xe9, 0xca, - 0xeb, 0xce, 0xe2, 0xd5, 0x2e, 0xc1, 0x8d, 0x17, - 0x03, 0x01, 0x00, 0x21, 0x2e, 0x61, 0x86, 0x17, - 0xdb, 0xa6, 0x30, 0xe2, 0x62, 0x06, 0x2a, 0x8b, - 0x75, 0x2c, 0x2d, 0xcf, 0xf5, 0x01, 0x11, 0x52, - 0x81, 0x38, 0xcf, 0xd5, 0xf7, 0xdc, 0x52, 0x31, - 0x1f, 0x97, 0x43, 0xc2, 0x71, 0x15, 0x03, 0x01, - 0x00, 0x16, 0xe0, 0x21, 0xfe, 0x36, 0x2e, 0x68, - 0x2c, 0xf1, 0xbe, 0x04, 0xec, 0xd4, 0xc6, 0xdd, - 0xac, 0x6f, 0x4c, 0x85, 0x32, 0x3f, 0x87, 0x1b, - }, -} - -var rsaDES3ServerScript = [][]byte{ - { - 0x16, 0x03, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x00, - 0xc1, 0x03, 0x03, 0x50, 0xae, 0x5d, 0x38, 0xec, - 0xaa, 0x2f, 0x41, 0xf9, 0xd2, 0x7b, 0xa1, 0xfd, - 0x0f, 0xff, 0x4e, 0x54, 0x0e, 0x15, 0x57, 0xaf, - 0x2c, 0x91, 0xb5, 0x35, 0x5b, 0x2e, 0xb0, 0xec, - 0x20, 0xe5, 0xd2, 0x00, 0x00, 0x50, 0xc0, 0x09, - 0xc0, 0x23, 0xc0, 0x2b, 0xc0, 0x0a, 0xc0, 0x24, - 0xc0, 0x2c, 0xc0, 0x08, 0xc0, 0x13, 0xc0, 0x27, - 0xc0, 0x2f, 0xc0, 0x14, 0xc0, 0x30, 0xc0, 0x12, - 0x00, 0x33, 0x00, 0x67, 0x00, 0x45, 0x00, 0x9e, - 0x00, 0x39, 0x00, 0x6b, 0x00, 0x88, 0x00, 0x16, - 0x00, 0x32, 0x00, 0x40, 0x00, 0x44, 0x00, 0xa2, - 0x00, 0x38, 0x00, 0x6a, 0x00, 0x87, 0x00, 0x13, - 0x00, 0x66, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x41, - 0x00, 0x9c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x84, - 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, - 0x00, 0x48, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, - 0x00, 0x23, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, - 0x00, 0x0a, 0x00, 0x13, 0x00, 0x15, 0x00, 0x17, - 0x00, 0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1a, - 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x05, 0x01, - 0x05, 0x03, 0x06, 0x01, 0x06, 0x03, 0x03, 0x01, - 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, - 0x02, 0x03, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, - 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x51, 0x04, 0xf1, 0x7a, 0xbf, - 0xe8, 0xa5, 0x86, 0x09, 0xa7, 0xf3, 0xcc, 0x93, - 0x00, 0x10, 0x5b, 0xb8, 0xc1, 0x51, 0x0d, 0x5b, - 0xcd, 0xed, 0x26, 0x01, 0x69, 0x73, 0xf4, 0x05, - 0x8a, 0x6a, 0xc3, 0xb1, 0x9e, 0x84, 0x4e, 0x39, - 0xcf, 0x5e, 0x55, 0xa9, 0x70, 0x19, 0x96, 0x91, - 0xcd, 0x2c, 0x78, 0x3c, 0xa2, 0x6d, 0xb0, 0x49, - 0x86, 0xf6, 0xd1, 0x3a, 0xde, 0x00, 0x4b, 0xa6, - 0x25, 0xbf, 0x85, 0x39, 0xce, 0xb1, 0xcf, 0xbc, - 0x16, 0xc7, 0x66, 0xac, 0xf8, 0xd2, 0x3b, 0xd1, - 0xcc, 0x16, 0xac, 0x63, 0x3c, 0xbe, 0xd9, 0xb6, - 0x6a, 0xe4, 0x13, 0x8a, 0xf4, 0x56, 0x2f, 0x92, - 0x54, 0xd8, 0xf0, 0x84, 0x01, 0x32, 0x1a, 0xa9, - 0x2d, 0xaf, 0x82, 0x0e, 0x00, 0xfa, 0x07, 0x88, - 0xd9, 0x87, 0xe7, 0xdc, 0x9e, 0xe9, 0x72, 0x49, - 0xb8, 0xfa, 0x8c, 0x7b, 0x07, 0x0b, 0x03, 0x7c, - 0x10, 0x8c, 0x8a, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0xa8, 0x61, 0xa4, - 0xf4, 0x5f, 0x8a, 0x1f, 0x5c, 0x92, 0x3f, 0x8c, - 0xdb, 0xd6, 0x10, 0xcd, 0x9e, 0xe7, 0xf0, 0xc4, - 0x3c, 0xb6, 0x1c, 0x9a, 0x56, 0x73, 0x7f, 0xa6, - 0x14, 0x24, 0xcb, 0x96, 0x1f, 0xe0, 0xaf, 0xcd, - 0x3c, 0x66, 0x43, 0xb7, 0x37, 0x65, 0x34, 0x47, - 0xf8, 0x43, 0xf1, 0xcc, 0x15, 0xb8, 0xdc, 0x35, - 0xe0, 0xa4, 0x2d, 0x78, 0x94, 0xe0, 0x02, 0xf3, - 0x76, 0x46, 0xf7, 0x9b, 0x8d, 0x0d, 0x5d, 0x0b, - 0xd3, 0xdd, 0x9a, 0x9e, 0x62, 0x2e, 0xc5, 0x98, - 0x75, 0x63, 0x0c, 0xbf, 0x8e, 0x49, 0x33, 0x23, - 0x7c, 0x00, 0xcf, 0xfb, 0xcf, 0xba, 0x0f, 0x41, - 0x39, 0x89, 0xb9, 0xcc, 0x59, 0xd0, 0x2b, 0xb6, - 0xec, 0x04, 0xe2, 0xc0, 0x52, 0xc7, 0xcf, 0x71, - 0x47, 0xff, 0x70, 0x7e, 0xa9, 0xbd, 0x1c, 0xdd, - 0x17, 0xa5, 0x6c, 0xb7, 0x10, 0x4f, 0x42, 0x18, - 0x37, 0x69, 0xa9, 0xd2, 0xb3, 0x18, 0x84, 0x92, - 0xa7, 0x47, 0x21, 0xf6, 0x95, 0x63, 0x29, 0xd6, - 0xa5, 0xb6, 0xda, 0x65, 0x67, 0x69, 0xc4, 0x26, - 0xac, 0x8b, 0x08, 0x58, 0xdd, 0x3c, 0x31, 0x20, - 0xd5, 0x0c, 0x88, 0x72, 0x18, 0x16, 0x88, 0x1e, - 0x4a, 0x0f, 0xe1, 0xcf, 0x95, 0x24, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x4b, 0xde, 0xef, 0xba, 0x3e, 0x18, 0x1c, - 0x1e, 0x5e, 0xbc, 0x87, 0xf1, 0x87, 0x8d, 0x72, - 0xe3, 0xbe, 0x0f, 0xdf, 0xfd, 0xd0, 0xb2, 0x89, - 0xf8, 0x05, 0x9a, 0x52, 0x47, 0x77, 0x9e, 0xe8, - 0xb1, 0x1d, 0x18, 0xed, 0x6a, 0x4b, 0x63, 0x1d, - 0xf1, 0x62, 0xd2, 0x65, 0x21, 0x26, 0x73, 0xd4, - 0x35, 0x5b, 0x95, 0x89, 0x12, 0x59, 0x23, 0x8c, - 0xc3, 0xfc, 0xf9, 0x4d, 0x21, 0x79, 0xa0, 0xbd, - 0xff, 0x33, 0xa2, 0x3d, 0x0b, 0x6f, 0x89, 0xc9, - 0x23, 0xe4, 0xe7, 0x9f, 0x1d, 0x98, 0xf6, 0xed, - 0x02, 0x8d, 0xac, 0x1a, 0xf9, 0xcb, 0xa5, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x28, 0x91, 0x56, 0x80, 0xe2, 0x6d, 0x51, - 0x88, 0x03, 0xf8, 0x49, 0xe6, 0x6a, 0x5a, 0xfb, - 0x2f, 0x0b, 0xb5, 0xa1, 0x0d, 0x63, 0x83, 0xae, - 0xb9, 0xbc, 0x05, 0xf0, 0x81, 0x00, 0x61, 0x83, - 0x38, 0xda, 0x14, 0xf6, 0xea, 0xd8, 0x78, 0x65, - 0xc7, 0x26, 0x17, 0x03, 0x01, 0x00, 0x18, 0x81, - 0x30, 0x8b, 0x22, 0x5a, 0xd3, 0x7f, 0xc8, 0xf2, - 0x8a, 0x6b, 0xa3, 0xba, 0x4d, 0xe7, 0x6e, 0xd2, - 0xfd, 0xbf, 0xf2, 0xc5, 0x28, 0xa0, 0x62, 0x17, - 0x03, 0x01, 0x00, 0x28, 0x17, 0x83, 0x3c, 0x78, - 0x18, 0xfa, 0x8d, 0x58, 0x5c, 0xaa, 0x05, 0x7d, - 0x67, 0x96, 0x11, 0x60, 0x11, 0xc0, 0x1e, 0x0d, - 0x6a, 0x6e, 0x5f, 0x1d, 0x98, 0x4b, 0xff, 0x82, - 0xee, 0x21, 0x06, 0x29, 0xd3, 0x8b, 0x80, 0x78, - 0x39, 0x05, 0x34, 0x9b, 0x15, 0x03, 0x01, 0x00, - 0x18, 0xa9, 0x38, 0x18, 0x4f, 0x9d, 0x84, 0x75, - 0x88, 0x53, 0xd6, 0x85, 0xc2, 0x15, 0x4b, 0xe3, - 0xe3, 0x35, 0x9a, 0x74, 0xc9, 0x3e, 0x13, 0xc1, - 0x8c, - }, -} - -var rsaAESServerScript = [][]byte{ - { - 0x16, 0x03, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x00, - 0xc1, 0x03, 0x03, 0x50, 0xae, 0x5c, 0xe9, 0x5e, - 0x31, 0x93, 0x82, 0xa5, 0x6f, 0x51, 0x82, 0xc8, - 0x55, 0x4f, 0x1f, 0x2e, 0x90, 0x98, 0x81, 0x13, - 0x27, 0x80, 0x68, 0xb4, 0x2d, 0xba, 0x3a, 0x76, - 0xd8, 0xd7, 0x2c, 0x00, 0x00, 0x50, 0xc0, 0x09, - 0xc0, 0x23, 0xc0, 0x2b, 0xc0, 0x0a, 0xc0, 0x24, - 0xc0, 0x2c, 0xc0, 0x08, 0xc0, 0x13, 0xc0, 0x27, - 0xc0, 0x2f, 0xc0, 0x14, 0xc0, 0x30, 0xc0, 0x12, - 0x00, 0x33, 0x00, 0x67, 0x00, 0x45, 0x00, 0x9e, - 0x00, 0x39, 0x00, 0x6b, 0x00, 0x88, 0x00, 0x16, - 0x00, 0x32, 0x00, 0x40, 0x00, 0x44, 0x00, 0xa2, - 0x00, 0x38, 0x00, 0x6a, 0x00, 0x87, 0x00, 0x13, - 0x00, 0x66, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x41, - 0x00, 0x9c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x84, - 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, - 0x00, 0x48, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, - 0x00, 0x23, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, - 0x00, 0x0a, 0x00, 0x13, 0x00, 0x15, 0x00, 0x17, - 0x00, 0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1a, - 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x05, 0x01, - 0x05, 0x03, 0x06, 0x01, 0x06, 0x03, 0x03, 0x01, - 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, - 0x02, 0x03, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, - 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x51, 0x2e, 0xec, 0x0d, 0x86, - 0xf3, 0x9f, 0xf2, 0x77, 0x04, 0x27, 0x2b, 0x0e, - 0x9c, 0xab, 0x35, 0x84, 0x65, 0xff, 0x36, 0xef, - 0xc0, 0x08, 0xc9, 0x1d, 0x9f, 0x29, 0xae, 0x8d, - 0xc5, 0x66, 0x81, 0x31, 0x92, 0x5e, 0x3d, 0xac, - 0xaa, 0x37, 0x28, 0x2c, 0x06, 0x91, 0xa6, 0xc2, - 0xd0, 0x83, 0x34, 0x24, 0x1c, 0x88, 0xfc, 0x0a, - 0xcf, 0xbf, 0xc2, 0x94, 0xe2, 0xed, 0xa7, 0x6a, - 0xa8, 0x8d, 0x3d, 0xf7, 0x06, 0x7d, 0x69, 0xf8, - 0x0d, 0xb2, 0xf7, 0xe4, 0x45, 0xcb, 0x0a, 0x25, - 0xcb, 0xb2, 0x2e, 0x38, 0x9a, 0x84, 0x75, 0xe8, - 0xe1, 0x42, 0x39, 0xa2, 0x18, 0x0e, 0x48, 0xca, - 0x33, 0x16, 0x4e, 0xf6, 0x2f, 0xec, 0x07, 0xe7, - 0x57, 0xe1, 0x20, 0x40, 0x40, 0x6d, 0x4e, 0x29, - 0x04, 0x1a, 0x8c, 0x99, 0xfb, 0x19, 0x3c, 0xaa, - 0x75, 0x64, 0xd3, 0xa6, 0xe6, 0xed, 0x3f, 0x5a, - 0xd2, 0xc9, 0x80, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x01, 0x10, 0xe9, 0x9e, - 0x06, 0x92, 0x18, 0xbf, 0x5e, 0xaf, 0x33, 0xc1, - 0xbf, 0x0e, 0x12, 0x07, 0x48, 0x4f, 0x6b, 0x6c, - 0xf5, 0x23, 0x5e, 0x87, 0xa7, 0xd3, 0x50, 0x79, - 0x38, 0xdc, 0xe0, 0x49, 0xd3, 0x81, 0x21, 0x12, - 0xd0, 0x3d, 0x9a, 0xfb, 0x83, 0xc1, 0x8b, 0xfc, - 0x14, 0xd5, 0xd5, 0xa7, 0xa3, 0x34, 0x14, 0x71, - 0xbe, 0xea, 0x37, 0x18, 0x12, 0x7f, 0x41, 0xfb, - 0xc5, 0x51, 0x17, 0x9d, 0x96, 0x58, 0x14, 0xfb, - 0x4f, 0xd7, 0xd3, 0x15, 0x0f, 0xec, 0x5a, 0x0d, - 0x35, 0xbb, 0x3c, 0x81, 0x5b, 0x3f, 0xdf, 0x52, - 0xa4, 0x4c, 0xcd, 0x13, 0xe1, 0x10, 0x37, 0x34, - 0xbf, 0xb4, 0x80, 0x1e, 0x8d, 0xe2, 0xc3, 0x7a, - 0x0f, 0x7b, 0x7d, 0x23, 0xeb, 0xd0, 0x99, 0x69, - 0xad, 0x0a, 0x2d, 0xb3, 0x6c, 0xd6, 0x80, 0x11, - 0x7f, 0x6c, 0xed, 0x1b, 0xcd, 0x08, 0x22, 0x56, - 0x90, 0x0e, 0xa4, 0xc3, 0x29, 0x33, 0x96, 0x30, - 0x34, 0x94, 0xa1, 0xeb, 0x9c, 0x1b, 0x5a, 0xd1, - 0x03, 0x61, 0xf9, 0xdd, 0xf3, 0x64, 0x8a, 0xfd, - 0x5f, 0x44, 0xdb, 0x2e, 0xa7, 0xfd, 0xe1, 0x1a, - 0x66, 0xc5, 0x01, 0x9c, 0xc7, 0xd1, 0xc4, 0xd3, - 0xea, 0x14, 0x3c, 0xed, 0x74, 0xbb, 0x1b, 0x97, - 0x8f, 0xf1, 0x29, 0x39, 0x33, 0x92, 0x93, 0x4e, - 0xf5, 0x87, 0x91, 0x61, 0x65, 0x8d, 0x27, 0x8d, - 0x76, 0xc1, 0xfa, 0x6a, 0x99, 0x80, 0xb1, 0x9b, - 0x29, 0x53, 0xce, 0x3e, 0xb6, 0x9a, 0xce, 0x3c, - 0x19, 0x5e, 0x48, 0x83, 0xaa, 0xa7, 0x66, 0x98, - 0x59, 0xf4, 0xbb, 0xf2, 0xbc, 0xd9, 0xc5, 0x9a, - 0xc8, 0x2c, 0x63, 0x58, 0xd5, 0xd4, 0xbc, 0x03, - 0xa9, 0x06, 0xa9, 0x80, 0x0d, 0xb3, 0x46, 0x2d, - 0xe3, 0xc6, 0xaf, 0x1a, 0x39, 0x18, 0x7e, 0x1e, - 0x83, 0x80, 0x46, 0x11, 0xd2, 0x13, 0x9f, 0xda, - 0xfc, 0x2d, 0x42, 0xaa, 0x5a, 0x1d, 0x4c, 0x31, - 0xe5, 0x58, 0x78, 0x5e, 0xe2, 0x04, 0xd6, 0x23, - 0x7f, 0x3f, 0x06, 0xc0, 0x54, 0xf8, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x4b, 0xfb, 0xef, 0xba, 0xed, 0xc5, 0x36, - 0xc8, 0x5a, 0x41, 0x3f, 0x05, 0xfa, 0xfe, 0x48, - 0xc3, 0x91, 0x12, 0x8b, 0xe8, 0x32, 0x6a, 0x9f, - 0xdc, 0x97, 0xe2, 0x77, 0xb9, 0x96, 0x2d, 0xd4, - 0xe5, 0xbd, 0xa1, 0xfd, 0x94, 0xbb, 0x74, 0x63, - 0xb1, 0x0c, 0x38, 0xbc, 0x6f, 0x69, 0xaf, 0xa3, - 0x46, 0x9c, 0x96, 0x41, 0xde, 0x59, 0x23, 0xff, - 0x15, 0x6b, 0x3a, 0xef, 0x91, 0x6d, 0x92, 0x44, - 0xdc, 0x72, 0x1f, 0x40, 0x3d, 0xb5, 0x34, 0x8f, - 0x2a, 0xac, 0x21, 0x69, 0x05, 0x6f, 0xb2, 0x60, - 0x32, 0x5d, 0x3d, 0x97, 0xb4, 0x24, 0x99, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x30, 0x68, 0x27, 0x97, 0xca, 0x63, 0x09, - 0x22, 0xed, 0x0e, 0x61, 0x7c, 0x76, 0x31, 0x9c, - 0xbe, 0x27, 0xc9, 0xe6, 0x09, 0xc3, 0xc3, 0xc2, - 0xf4, 0xa2, 0x32, 0xba, 0x7c, 0xf2, 0x0f, 0xb8, - 0x3d, 0xcb, 0xe2, 0x4c, 0xc0, 0x7d, 0x8e, 0x5b, - 0x5a, 0xed, 0x05, 0x5c, 0x15, 0x96, 0x69, 0xc2, - 0x6f, 0x5f, 0x17, 0x03, 0x01, 0x00, 0x20, 0x5a, - 0xfe, 0x0b, 0xe1, 0x6f, 0xa8, 0x54, 0x19, 0x78, - 0xca, 0xba, 0x2e, 0x1e, 0x2e, 0xe1, 0x5d, 0x17, - 0xe5, 0x97, 0x05, 0x2c, 0x08, 0x0c, 0xff, 0xa8, - 0x59, 0xa9, 0xde, 0x5e, 0x21, 0x34, 0x04, 0x17, - 0x03, 0x01, 0x00, 0x30, 0x86, 0xb1, 0x3f, 0x88, - 0x43, 0xf0, 0x07, 0xee, 0xa8, 0xf4, 0xbc, 0xe7, - 0x5f, 0xc6, 0x8c, 0x86, 0x4c, 0xca, 0x70, 0x88, - 0xcc, 0x6a, 0xb4, 0x3d, 0x40, 0xe8, 0x54, 0x89, - 0x19, 0x43, 0x1f, 0x76, 0xe2, 0xac, 0xb2, 0x5b, - 0x92, 0xf8, 0x57, 0x39, 0x2a, 0xc3, 0x6d, 0x13, - 0x45, 0xfa, 0x36, 0x9e, 0x15, 0x03, 0x01, 0x00, - 0x20, 0x6d, 0xed, 0x7b, 0x59, 0x28, 0x2a, 0x27, - 0x04, 0x15, 0x07, 0x4e, 0xeb, 0x13, 0x00, 0xe3, - 0x3a, 0x3f, 0xf8, 0xaa, 0x2b, 0x3b, 0x1a, 0x8c, - 0x12, 0xd6, 0x4c, 0xec, 0x2a, 0xaf, 0x33, 0x60, - 0xaf, - }, -} - -// Generated using: -// $ go test -test.run TestRunServer -serve -ciphersuites=0xc00a -// $ openssl s_client -host 127.0.0.1 -port 10443 -cipher ECDHE-ECDSA-AES256-SHA -var ecdheECDSAAESServerScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, - 0x9c, 0x03, 0x03, 0x50, 0xd7, 0x18, 0x31, 0x49, - 0xde, 0x19, 0x8d, 0x08, 0x5c, 0x4b, 0x60, 0x67, - 0x0f, 0xfe, 0xd0, 0x62, 0xf9, 0x31, 0x48, 0x17, - 0x9e, 0x50, 0xc1, 0xd8, 0x35, 0x24, 0x0e, 0xa6, - 0x09, 0x06, 0x51, 0x00, 0x00, 0x04, 0xc0, 0x0a, - 0x00, 0xff, 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, - 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, - 0x00, 0x34, 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, - 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, - 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, - 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, - 0x00, 0x15, 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, - 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, - 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, - 0x00, 0x00, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, - 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, - 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, - 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, - 0x00, 0x0f, 0x00, 0x01, 0x01, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0a, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0x0e, 0x0b, 0x00, 0x02, 0x0a, 0x00, 0x02, - 0x07, 0x00, 0x02, 0x04, 0x30, 0x82, 0x02, 0x00, - 0x30, 0x82, 0x01, 0x62, 0x02, 0x09, 0x00, 0xb8, - 0xbf, 0x2d, 0x47, 0xa0, 0xd2, 0xeb, 0xf4, 0x30, - 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, - 0x04, 0x01, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x31, - 0x31, 0x32, 0x32, 0x31, 0x35, 0x30, 0x36, 0x33, - 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x31, 0x31, - 0x32, 0x30, 0x31, 0x35, 0x30, 0x36, 0x33, 0x32, - 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, - 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, - 0x30, 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, - 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, - 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, - 0x00, 0x04, 0x00, 0xc4, 0xa1, 0xed, 0xbe, 0x98, - 0xf9, 0x0b, 0x48, 0x73, 0x36, 0x7e, 0xc3, 0x16, - 0x56, 0x11, 0x22, 0xf2, 0x3d, 0x53, 0xc3, 0x3b, - 0x4d, 0x21, 0x3d, 0xcd, 0x6b, 0x75, 0xe6, 0xf6, - 0xb0, 0xdc, 0x9a, 0xdf, 0x26, 0xc1, 0xbc, 0xb2, - 0x87, 0xf0, 0x72, 0x32, 0x7c, 0xb3, 0x64, 0x2f, - 0x1c, 0x90, 0xbc, 0xea, 0x68, 0x23, 0x10, 0x7e, - 0xfe, 0xe3, 0x25, 0xc0, 0x48, 0x3a, 0x69, 0xe0, - 0x28, 0x6d, 0xd3, 0x37, 0x00, 0xef, 0x04, 0x62, - 0xdd, 0x0d, 0xa0, 0x9c, 0x70, 0x62, 0x83, 0xd8, - 0x81, 0xd3, 0x64, 0x31, 0xaa, 0x9e, 0x97, 0x31, - 0xbd, 0x96, 0xb0, 0x68, 0xc0, 0x9b, 0x23, 0xde, - 0x76, 0x64, 0x3f, 0x1a, 0x5c, 0x7f, 0xe9, 0x12, - 0x0e, 0x58, 0x58, 0xb6, 0x5f, 0x70, 0xdd, 0x9b, - 0xd8, 0xea, 0xd5, 0xd7, 0xf5, 0xd5, 0xcc, 0xb9, - 0xb6, 0x9f, 0x30, 0x66, 0x5b, 0x66, 0x9a, 0x20, - 0xe2, 0x27, 0xe5, 0xbf, 0xfe, 0x3b, 0x30, 0x09, - 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, - 0x01, 0x03, 0x81, 0x8c, 0x00, 0x30, 0x81, 0x88, - 0x02, 0x42, 0x01, 0x88, 0xa2, 0x4f, 0xeb, 0xe2, - 0x45, 0xc5, 0x48, 0x7d, 0x1b, 0xac, 0xf5, 0xed, - 0x98, 0x9d, 0xae, 0x47, 0x70, 0xc0, 0x5e, 0x1b, - 0xb6, 0x2f, 0xbd, 0xf1, 0xb6, 0x4d, 0xb7, 0x61, - 0x40, 0xd3, 0x11, 0xa2, 0xce, 0xee, 0x0b, 0x7e, - 0x92, 0x7e, 0xff, 0x76, 0x9d, 0xc3, 0x3b, 0x7e, - 0xa5, 0x3f, 0xce, 0xfa, 0x10, 0xe2, 0x59, 0xec, - 0x47, 0x2d, 0x7c, 0xac, 0xda, 0x4e, 0x97, 0x0e, - 0x15, 0xa0, 0x6f, 0xd0, 0x02, 0x42, 0x01, 0x4d, - 0xfc, 0xbe, 0x67, 0x13, 0x9c, 0x2d, 0x05, 0x0e, - 0xbd, 0x3f, 0xa3, 0x8c, 0x25, 0xc1, 0x33, 0x13, - 0x83, 0x0d, 0x94, 0x06, 0xbb, 0xd4, 0x37, 0x7a, - 0xf6, 0xec, 0x7a, 0xc9, 0x86, 0x2e, 0xdd, 0xd7, - 0x11, 0x69, 0x7f, 0x85, 0x7c, 0x56, 0xde, 0xfb, - 0x31, 0x78, 0x2b, 0xe4, 0xc7, 0x78, 0x0d, 0xae, - 0xcb, 0xbe, 0x9e, 0x4e, 0x36, 0x24, 0x31, 0x7b, - 0x6a, 0x0f, 0x39, 0x95, 0x12, 0x07, 0x8f, 0x2a, - 0x16, 0x03, 0x01, 0x01, 0x1a, 0x0c, 0x00, 0x01, - 0x16, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, - 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, - 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, - 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, - 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, - 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, - 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, - 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, - 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, - 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, - 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, - 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, - 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, - 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, - 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, - 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, - 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, - 0x90, 0x33, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02, - 0x42, 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, - 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, - 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, - 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, - 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, - 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, - 0xff, 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, - 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, - 0xe5, 0xbd, 0x66, 0x02, 0x42, 0x00, 0xad, 0x7d, - 0x06, 0x35, 0xab, 0xec, 0x8d, 0xac, 0xd4, 0xba, - 0x1b, 0x49, 0x5e, 0x05, 0x5f, 0xf0, 0x97, 0x93, - 0x82, 0xb8, 0x2b, 0x8d, 0x91, 0x98, 0x63, 0x8e, - 0xb4, 0x14, 0x62, 0xdb, 0x1e, 0xc9, 0x2b, 0x30, - 0xf8, 0x41, 0x9b, 0xa6, 0xe6, 0xbc, 0xde, 0x0e, - 0x68, 0x30, 0x22, 0x50, 0xe6, 0x98, 0x97, 0x7b, - 0x69, 0xf7, 0x93, 0xed, 0xcd, 0x19, 0x2f, 0x44, - 0x6c, 0x2e, 0xdf, 0x25, 0xee, 0xcc, 0x46, 0x16, - 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x8a, 0x10, 0x00, 0x00, - 0x86, 0x85, 0x04, 0x00, 0x1c, 0xc5, 0xe8, 0xb3, - 0x42, 0xb4, 0xad, 0xca, 0x45, 0xcd, 0x42, 0x7b, - 0xfb, 0x0c, 0xea, 0x32, 0x26, 0xd4, 0x8a, 0xef, - 0xdf, 0xc9, 0xff, 0xd2, 0xe0, 0x36, 0xea, 0x4e, - 0xbb, 0x3e, 0xf4, 0x9c, 0x76, 0x4f, 0x44, 0xbd, - 0x84, 0x72, 0xdd, 0xcb, 0xe5, 0x28, 0x8d, 0x31, - 0x72, 0x3b, 0xd3, 0xf2, 0x9a, 0x13, 0xfb, 0x8a, - 0xa7, 0x72, 0xca, 0x21, 0x6c, 0xea, 0xbf, 0xe9, - 0x8c, 0x0a, 0xcc, 0x8f, 0xd6, 0x00, 0x20, 0x87, - 0xf3, 0x7d, 0x18, 0xc5, 0xfd, 0x9e, 0xdd, 0x6b, - 0x06, 0xdc, 0x52, 0xeb, 0x14, 0xc0, 0x67, 0x5a, - 0x06, 0xd8, 0x98, 0x19, 0x14, 0xe7, 0xd4, 0x36, - 0x32, 0xee, 0xb7, 0xfa, 0xe2, 0x85, 0x4a, 0x16, - 0x42, 0x0c, 0xa6, 0x21, 0xcf, 0x1f, 0xae, 0x10, - 0x8b, 0x28, 0x32, 0x19, 0xa4, 0x0a, 0xd7, 0xce, - 0xe6, 0xe1, 0x93, 0xfb, 0x5f, 0x08, 0x8b, 0x42, - 0xa2, 0x20, 0xed, 0x0d, 0x62, 0xca, 0xed, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x30, 0x2e, 0x33, 0xc0, 0x57, 0x6c, 0xb4, - 0x1b, 0xd2, 0x63, 0xe8, 0x67, 0x10, 0x2d, 0x87, - 0x71, 0x6e, 0x19, 0x60, 0xf4, 0xa4, 0x10, 0x52, - 0x73, 0x2d, 0x09, 0x5e, 0xdb, 0x6c, 0xdc, 0xcf, - 0x2d, 0xff, 0x03, 0x11, 0x95, 0x76, 0x90, 0xd7, - 0x87, 0x54, 0x43, 0xed, 0xc2, 0x36, 0x69, 0x14, - 0x72, 0x4a, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x8b, 0xde, 0xef, 0xba, 0xc5, 0x7e, 0x04, - 0xab, 0xfd, 0x79, 0x56, 0xf3, 0xe1, 0xa5, 0x3e, - 0x02, 0xdf, 0x69, 0x6d, 0x1f, 0x41, 0x9f, 0xbc, - 0x93, 0xe2, 0x6c, 0xf1, 0xb1, 0x38, 0xf5, 0x2b, - 0x8c, 0x4c, 0xf4, 0x74, 0xe1, 0x79, 0x35, 0x34, - 0x97, 0x9b, 0xd5, 0xba, 0xfd, 0xf7, 0x2f, 0x2d, - 0x9e, 0x84, 0x54, 0xee, 0x77, 0x59, 0x23, 0x8f, - 0xc8, 0x84, 0xb4, 0xd6, 0xea, 0x4c, 0x44, 0x8a, - 0xc6, 0x9c, 0xf9, 0x9b, 0x27, 0xea, 0x4f, 0x28, - 0x72, 0x33, 0x12, 0x20, 0x7c, 0xd7, 0x3f, 0x56, - 0xa6, 0x76, 0xc7, 0x48, 0xe4, 0x2d, 0x6f, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x30, 0x36, 0xe3, 0xd4, 0xf7, 0xb1, 0x69, - 0x18, 0x8d, 0x09, 0xba, 0x52, 0x1e, 0xd5, 0x7d, - 0x2c, 0x15, 0x3a, 0xd6, 0xe3, 0x99, 0x30, 0x2c, - 0x99, 0x97, 0xbc, 0x19, 0x3c, 0x63, 0xa1, 0x25, - 0x68, 0xbc, 0x8a, 0x16, 0x47, 0xec, 0xae, 0x13, - 0xa4, 0x03, 0x96, 0x29, 0x11, 0x92, 0x90, 0x1a, - 0xc8, 0xa4, 0x17, 0x03, 0x01, 0x00, 0x20, 0xc1, - 0x10, 0x1d, 0xa6, 0xf1, 0xe2, 0x8a, 0xcc, 0x37, - 0x7d, 0x8e, 0x05, 0x00, 0xfb, 0xd1, 0x9f, 0xc7, - 0x11, 0xd2, 0x00, 0xb4, 0x27, 0x0a, 0x25, 0x14, - 0xd9, 0x79, 0x1b, 0xcb, 0x4d, 0x81, 0x61, 0x17, - 0x03, 0x01, 0x00, 0x30, 0x5c, 0x7c, 0x2d, 0xc0, - 0x9e, 0xa6, 0xc4, 0x8e, 0xfd, 0xf4, 0xe2, 0xe5, - 0xe4, 0xe6, 0x56, 0x9f, 0x7d, 0x4c, 0x4c, 0x2d, - 0xb7, 0xa9, 0xac, 0xfa, 0x9f, 0x12, 0x7f, 0x2d, - 0x30, 0x57, 0xe4, 0x8e, 0x30, 0x86, 0x65, 0x59, - 0xcd, 0x24, 0xda, 0xe2, 0x8a, 0x7b, 0x0c, 0x5e, - 0x86, 0x05, 0x06, 0x2a, 0x15, 0x03, 0x01, 0x00, - 0x20, 0xd6, 0xb7, 0x70, 0xf8, 0x47, 0xbc, 0x0f, - 0xf4, 0x66, 0x98, 0x1b, 0x1e, 0x8a, 0x8c, 0x0b, - 0xa1, 0x4a, 0x04, 0x29, 0x60, 0x72, 0x8b, 0xc4, - 0x73, 0xc1, 0xd6, 0x41, 0x72, 0xb7, 0x17, 0x39, - 0xda, - }, -} - -var sslv3ServerScript = [][]byte{ - { - 0x16, 0x03, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, - 0x50, 0x03, 0x00, 0x50, 0x77, 0x3d, 0x42, 0xae, - 0x84, 0xbd, 0xc5, 0x07, 0xa5, 0xc4, 0xd6, 0x16, - 0x4e, 0xd5, 0xc5, 0xfa, 0x02, 0x7a, 0x0f, 0x1d, - 0xc1, 0xe1, 0xaa, 0xe3, 0x3b, 0x4b, 0x6f, 0x11, - 0xfa, 0x1a, 0xa4, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, - }, - { - 0x16, 0x03, 0x00, 0x00, 0x2a, 0x02, 0x00, 0x00, - 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x00, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, - 0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, - 0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, - 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, - 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, - 0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, - 0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, - 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, - 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, - 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, - 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, - 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, - 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, - 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, - 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, - 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, - 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, - 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, - 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, - 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, - 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, - 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, - 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, - 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, - 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, - 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, - 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, - 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, - 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, - 0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, - 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, - 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, - 0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, - 0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, - 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, - 0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, - 0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, - 0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, - 0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, - 0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, - 0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, - 0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, - 0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, - 0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, - 0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, - 0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, - 0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, - 0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, - 0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, - 0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, - 0xbd, 0xd9, 0x16, 0x03, 0x00, 0x00, 0x04, 0x0e, - 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, - 0x80, 0x4a, 0x8d, 0xc4, 0x38, 0x7a, 0x9c, 0xd6, - 0xe8, 0x72, 0x9e, 0xa3, 0xdf, 0x37, 0xb4, 0x6c, - 0x58, 0x33, 0x59, 0xd9, 0xc9, 0x4b, 0x50, 0x33, - 0x6c, 0xed, 0x73, 0x38, 0x2a, 0x46, 0x55, 0x31, - 0xa9, 0x8e, 0x8e, 0xfc, 0x0b, 0x5d, 0x5f, 0x3c, - 0x88, 0x28, 0x3f, 0x60, 0x51, 0x13, 0xf1, 0x59, - 0x0c, 0xa3, 0x5e, 0xe0, 0xa3, 0x35, 0x06, 0xb1, - 0x71, 0x59, 0x24, 0x4e, 0xed, 0x07, 0x15, 0x88, - 0x50, 0xef, 0xc2, 0xb2, 0x2a, 0x52, 0x30, 0x6a, - 0x7c, 0xbe, 0x2f, 0xc6, 0x8f, 0xa8, 0x83, 0xc5, - 0x80, 0x14, 0x62, 0x74, 0x7f, 0x96, 0x9f, 0x41, - 0x32, 0x74, 0xdd, 0x76, 0x2d, 0x7b, 0xeb, 0x7b, - 0xea, 0xd0, 0x4f, 0x0c, 0xcf, 0x9a, 0x9c, 0xc5, - 0x7a, 0xe4, 0xbc, 0xf8, 0xa6, 0xe1, 0x09, 0x8e, - 0x7c, 0x53, 0x3a, 0xe3, 0x30, 0x8f, 0x76, 0xee, - 0x58, 0xbb, 0xfd, 0x0b, 0x06, 0xb8, 0xdf, 0xb7, - 0x31, 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, - 0x03, 0x00, 0x00, 0x3c, 0x13, 0x91, 0xc6, 0x4a, - 0x0c, 0x59, 0x25, 0xce, 0x54, 0xc0, 0x1d, 0xb9, - 0x2a, 0xff, 0x4d, 0xca, 0x26, 0x0c, 0x8c, 0x04, - 0x98, 0x7c, 0x7c, 0x38, 0xa3, 0xf5, 0xf9, 0x36, - 0x1c, 0x04, 0x32, 0x47, 0x2d, 0x48, 0x0e, 0x96, - 0xe8, 0x2b, 0x5e, 0x5a, 0xc6, 0x0a, 0x48, 0x41, - 0x34, 0x5e, 0x62, 0xd5, 0x68, 0x4e, 0x44, 0x1d, - 0xb2, 0xa1, 0x11, 0xad, 0x6e, 0x14, 0x85, 0x61, - }, - { - 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x00, 0x00, 0x3c, 0x88, 0xae, 0xa9, 0xd4, 0xa8, - 0x10, 0x8d, 0x65, 0xa6, 0x3e, 0x1e, 0xed, 0xd2, - 0xfc, 0xc4, 0x7c, 0xa8, 0x94, 0x4f, 0x11, 0xaf, - 0xa6, 0x87, 0x09, 0x37, 0x54, 0xf7, 0x69, 0xd1, - 0xb5, 0x25, 0x6b, 0xb5, 0xed, 0xcb, 0x25, 0x39, - 0x73, 0xeb, 0x53, 0x6c, 0xc7, 0xb4, 0x29, 0x8f, - 0xd6, 0x49, 0xd1, 0x95, 0x59, 0x80, 0x9a, 0x67, - 0x5c, 0xb2, 0xe0, 0xbd, 0x1e, 0xff, 0xaa, 0x17, - 0x03, 0x00, 0x00, 0x21, 0x65, 0x7b, 0x99, 0x09, - 0x02, 0xc3, 0x9d, 0x54, 0xd6, 0xe7, 0x32, 0x62, - 0xab, 0xc1, 0x09, 0x91, 0x30, 0x0a, 0xc9, 0xfa, - 0x70, 0xec, 0x06, 0x7b, 0xa3, 0xe1, 0x5f, 0xb4, - 0x63, 0xe6, 0x5c, 0xba, 0x1f, 0x15, 0x03, 0x00, - 0x00, 0x16, 0x40, 0x70, 0xbe, 0xe6, 0xa6, 0xee, - 0x8f, 0xd0, 0x87, 0xa0, 0x43, 0xa1, 0x92, 0xd7, - 0xd0, 0x1a, 0x0c, 0x20, 0x7c, 0xbf, 0xa2, 0xb5, - }, -} - -var selectCertificateBySNIScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x6a, 0x01, 0x00, 0x00, - 0x66, 0x03, 0x01, 0x50, 0x77, 0x3d, 0xfe, 0xfb, - 0x8d, 0xc2, 0x68, 0xeb, 0xf9, 0xfa, 0x54, 0x97, - 0x86, 0x45, 0xa2, 0xa3, 0xed, 0xb1, 0x91, 0xb8, - 0x28, 0xc0, 0x47, 0xaf, 0xfb, 0xcd, 0xdc, 0x0e, - 0xb3, 0xea, 0xa5, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x0b, 0x73, 0x6e, 0x69, 0x74, - 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00, - 0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x01, 0x02, 0x00, 0x0b, 0x00, 0x01, 0xfc, - 0x00, 0x01, 0xf9, 0x00, 0x01, 0xf6, 0x30, 0x82, - 0x01, 0xf2, 0x30, 0x82, 0x01, 0x5d, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, 0x0b, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x30, 0x28, 0x31, 0x10, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, - 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, 0x31, - 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x0b, 0x73, 0x6e, 0x69, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x31, 0x31, - 0x37, 0x34, 0x30, 0x33, 0x35, 0x5a, 0x17, 0x0d, - 0x31, 0x33, 0x30, 0x34, 0x31, 0x31, 0x31, 0x37, - 0x34, 0x35, 0x33, 0x35, 0x5a, 0x30, 0x28, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, - 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0b, 0x73, 0x6e, 0x69, 0x74, - 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x81, 0x9d, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x03, - 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, - 0x81, 0x00, 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, - 0xe5, 0xbf, 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, - 0xe6, 0x2b, 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, - 0x8a, 0x7a, 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, - 0xa5, 0x65, 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, - 0xb5, 0xb4, 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, - 0x7e, 0x62, 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, - 0x12, 0x5c, 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, - 0xfa, 0x58, 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, - 0xd3, 0xd0, 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, - 0x54, 0x9f, 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, - 0xfe, 0x18, 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, - 0x7d, 0xf1, 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, - 0x51, 0xc9, 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, - 0x66, 0x01, 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, - 0x9a, 0x1d, 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, - 0x2d, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x32, 0x30, 0x30, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, - 0x02, 0x00, 0xa0, 0x30, 0x0d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x06, 0x04, 0x04, 0x01, 0x02, - 0x03, 0x04, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x08, 0x30, 0x06, 0x80, 0x04, 0x01, - 0x02, 0x03, 0x04, 0x30, 0x0b, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x03, 0x81, 0x81, 0x00, 0x89, 0xc6, 0x45, 0x5f, - 0x1c, 0x1f, 0x5e, 0xf8, 0xeb, 0x1a, 0xb1, 0x74, - 0xee, 0x24, 0x39, 0x05, 0x9f, 0x5c, 0x42, 0x59, - 0xbb, 0x1a, 0x8d, 0x86, 0xcd, 0xb1, 0xd0, 0x56, - 0xf5, 0x6a, 0x71, 0x7d, 0xa4, 0x0e, 0x95, 0xab, - 0x90, 0xf5, 0x9e, 0x8d, 0xea, 0xf6, 0x27, 0xc1, - 0x57, 0x99, 0x50, 0x94, 0xdb, 0x08, 0x02, 0x26, - 0x6e, 0xb3, 0x4f, 0xc6, 0x84, 0x2d, 0xea, 0x8a, - 0x4b, 0x68, 0xd9, 0xc1, 0x38, 0x91, 0x03, 0xab, - 0x84, 0xfb, 0x9e, 0x1f, 0x85, 0xd9, 0xb5, 0xd2, - 0x3f, 0xf2, 0x31, 0x2c, 0x86, 0x70, 0xfb, 0xb5, - 0x40, 0x14, 0x82, 0x45, 0xa4, 0xeb, 0xaf, 0xe2, - 0x64, 0xd9, 0x0c, 0x8a, 0x4c, 0xf4, 0xf8, 0x5b, - 0x0f, 0xac, 0x12, 0xac, 0x2f, 0xc4, 0xa3, 0x15, - 0x4b, 0xad, 0x52, 0x46, 0x28, 0x68, 0xaf, 0x96, - 0xc6, 0x2c, 0x65, 0x25, 0xd6, 0x52, 0xb6, 0xe3, - 0x18, 0x45, 0xbd, 0xcc, 0x16, 0x03, 0x01, 0x00, - 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x69, 0xc3, 0xd4, 0x0e, 0xcc, - 0xdc, 0xbc, 0x5e, 0xc2, 0x64, 0xa6, 0xde, 0x3c, - 0x0c, 0x7e, 0x0c, 0x6b, 0x80, 0x0f, 0xd4, 0x8f, - 0x02, 0x4b, 0xb2, 0xba, 0x8d, 0x01, 0xeb, 0x6b, - 0xa1, 0x2e, 0x79, 0x37, 0xba, 0xae, 0x24, 0xc2, - 0x26, 0x72, 0x51, 0xe1, 0x82, 0x8e, 0x51, 0x41, - 0x1c, 0x54, 0xa4, 0x26, 0xbe, 0x13, 0xcd, 0x1b, - 0xc6, 0xed, 0x3d, 0x1f, 0xfd, 0x72, 0x80, 0x90, - 0xdb, 0xbf, 0xd6, 0x39, 0x94, 0x5f, 0x48, 0xfb, - 0x25, 0x5a, 0xc9, 0x60, 0x9b, 0xd7, 0xc6, 0x20, - 0xa8, 0x66, 0x64, 0x13, 0xf3, 0x65, 0xc8, 0xb1, - 0xd5, 0x33, 0x21, 0x0e, 0x73, 0x41, 0xc0, 0x18, - 0x1a, 0x37, 0xfe, 0xcf, 0x28, 0x2a, 0xcd, 0xe4, - 0x0b, 0xac, 0xdd, 0x25, 0x5e, 0xcb, 0x17, 0x51, - 0x69, 0xd5, 0x8c, 0xf4, 0xb6, 0x21, 0x98, 0xef, - 0x20, 0xdb, 0x14, 0x67, 0xf3, 0x7c, 0x95, 0x6a, - 0x48, 0x2a, 0x6a, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0x36, 0x1b, - 0x09, 0xe5, 0xb9, 0xb9, 0x4d, 0x7d, 0xae, 0x87, - 0xb6, 0x0f, 0xaf, 0xec, 0x22, 0xba, 0x0d, 0xa5, - 0x96, 0x5e, 0x64, 0x65, 0xe7, 0xfb, 0xe3, 0xf3, - 0x6b, 0x72, 0xa8, 0xdb, 0xed, 0xd8, 0x69, 0x9c, - 0x08, 0xd8, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0x60, 0xf7, 0x09, 0x5f, 0xd1, - 0xcb, 0xc9, 0xe1, 0x22, 0xb5, 0x2a, 0xcc, 0xde, - 0x7c, 0xa7, 0xb8, 0x85, 0x00, 0xbc, 0xfd, 0x85, - 0xe1, 0x91, 0x36, 0xbb, 0x07, 0x42, 0xad, 0x3d, - 0x29, 0x62, 0x69, 0xc1, 0x45, 0x92, 0x6f, 0x17, - 0x03, 0x01, 0x00, 0x21, 0x0d, 0xf9, 0xd5, 0x87, - 0xb9, 0x57, 0x3c, 0x50, 0x19, 0xe4, 0x3a, 0x50, - 0x45, 0xcc, 0x86, 0x89, 0xd4, 0x32, 0x79, 0x45, - 0x7c, 0x9f, 0x96, 0xd4, 0x54, 0x56, 0x0c, 0x63, - 0x72, 0x81, 0xc3, 0xd3, 0xe3, 0x15, 0x03, 0x01, - 0x00, 0x16, 0x84, 0xec, 0x2e, 0xf6, 0xaf, 0x4f, - 0xee, 0x48, 0x0f, 0xbe, 0xcd, 0x82, 0x5c, 0x56, - 0x16, 0xe4, 0xfb, 0x89, 0xc5, 0x57, 0x3e, 0x91, - }, -} - -var issueSessionTicketTest = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, - 0x56, 0x03, 0x01, 0x50, 0x77, 0x3e, 0x49, 0x7a, - 0xb7, 0x86, 0x5c, 0x27, 0xd2, 0x97, 0x61, 0xe3, - 0x49, 0x41, 0x48, 0xe7, 0x0e, 0xaa, 0x7e, 0x4d, - 0xb8, 0xdc, 0x01, 0x97, 0xfb, 0xab, 0x53, 0xb2, - 0x5e, 0x36, 0xf6, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, - 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x68, 0x10, 0xdc, 0x80, 0xbc, - 0xb3, 0x5a, 0x10, 0x75, 0x89, 0xcc, 0xe5, 0x9f, - 0xbf, 0xe2, 0xce, 0xa4, 0x9f, 0x7f, 0x60, 0xc4, - 0xfe, 0x5c, 0xb5, 0x02, 0x2d, 0xa5, 0xa9, 0x1e, - 0x2c, 0x10, 0x79, 0x15, 0x0f, 0xed, 0x96, 0xb3, - 0xa8, 0x5e, 0x21, 0xbc, 0x5b, 0xdc, 0x58, 0x04, - 0x7d, 0x37, 0xdb, 0xa0, 0x31, 0xe8, 0x4f, 0x04, - 0xbc, 0x46, 0x7c, 0xdb, 0x2e, 0x93, 0x07, 0xaf, - 0xa6, 0x36, 0xd3, 0x39, 0x8d, 0x1d, 0x95, 0xa8, - 0x50, 0x4b, 0xc4, 0x2b, 0xde, 0xd7, 0x04, 0x6d, - 0x77, 0x6c, 0x4d, 0x70, 0x51, 0x88, 0x16, 0x31, - 0x40, 0xb5, 0xba, 0x90, 0x47, 0x64, 0x0c, 0x87, - 0xa5, 0x19, 0xf9, 0x89, 0x24, 0x3c, 0x5e, 0x4b, - 0xaa, 0xe0, 0x60, 0x47, 0x0f, 0x2e, 0xcc, 0xc2, - 0xd5, 0x21, 0xed, 0x72, 0xd0, 0xa9, 0xdd, 0x2a, - 0x2b, 0xef, 0x08, 0x3a, 0x65, 0xea, 0x8b, 0x52, - 0x77, 0x2d, 0xcc, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xe2, 0x95, - 0x62, 0x3c, 0x18, 0xe5, 0xc7, 0x2c, 0xda, 0x16, - 0x9b, 0x28, 0x0d, 0xf7, 0x88, 0x7b, 0x5d, 0x33, - 0x55, 0x3b, 0x01, 0x73, 0xf2, 0xc6, 0x4e, 0x96, - 0x01, 0x01, 0x83, 0x65, 0xd4, 0xef, 0x12, 0x13, - 0x1d, 0x42, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x4b, 0xd1, 0xef, 0xba, 0xfb, 0x41, 0x92, - 0x6d, 0x37, 0x5f, 0xf8, 0x7d, 0x90, 0x0f, 0x01, - 0xf8, 0x8c, 0xee, 0xbc, 0xd9, 0x0c, 0x97, 0x7e, - 0x23, 0x46, 0xe2, 0x6b, 0x52, 0xc6, 0xc6, 0x97, - 0x1d, 0xab, 0xde, 0xa0, 0x86, 0x94, 0xc8, 0x2e, - 0x8b, 0x2e, 0x42, 0x5f, 0xc2, 0x70, 0x35, 0xc9, - 0xee, 0x37, 0xeb, 0x70, 0xaa, 0x59, 0x23, 0x6c, - 0xc8, 0xc1, 0x84, 0x89, 0x39, 0x87, 0x73, 0x0a, - 0x7e, 0xba, 0xca, 0xed, 0x63, 0xba, 0x4e, 0x4f, - 0xf3, 0x31, 0x4b, 0xf0, 0xee, 0x91, 0xa5, 0xb4, - 0x62, 0x01, 0x9e, 0xbd, 0xbc, 0xb3, 0x35, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x24, 0x3f, 0x66, 0xe4, 0x98, 0xc1, 0x3f, - 0xc6, 0x2c, 0x81, 0xfb, 0xa9, 0x9f, 0x27, 0xe9, - 0x63, 0x20, 0x1e, 0x0e, 0x4f, 0xfc, 0x5d, 0x12, - 0xee, 0x77, 0x73, 0xc6, 0x96, 0x51, 0xf2, 0x26, - 0x35, 0x3f, 0xce, 0x6a, 0xa9, 0xfd, 0x17, 0x03, - 0x01, 0x00, 0x21, 0x8d, 0xd5, 0x67, 0x60, 0x5d, - 0xa7, 0x93, 0xcc, 0x39, 0x78, 0x59, 0xab, 0xdb, - 0x10, 0x96, 0xf2, 0xad, 0xa2, 0x85, 0xe2, 0x93, - 0x43, 0x43, 0xcf, 0x82, 0xbd, 0x1f, 0xdc, 0x7a, - 0x72, 0xd6, 0x83, 0x3b, 0x15, 0x03, 0x01, 0x00, - 0x16, 0x89, 0x55, 0xf6, 0x42, 0x71, 0xa9, 0xe9, - 0x05, 0x68, 0xe8, 0xce, 0x0d, 0x21, 0xe9, 0xec, - 0xf2, 0x27, 0x67, 0xa7, 0x94, 0xf8, 0x34, - }, -} -var serverResumeTest = [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0xc2, 0x01, 0x00, 0x00, - 0xbe, 0x03, 0x01, 0x50, 0x77, 0x3e, 0x4f, 0x1f, - 0x6f, 0xa5, 0x81, 0xeb, 0xb8, 0x80, 0x55, 0xa4, - 0x76, 0xc2, 0x7f, 0x27, 0xf2, 0xe7, 0xc9, 0x7a, - 0x01, 0x3c, 0xd8, 0xc1, 0xde, 0x99, 0x1f, 0x7c, - 0xab, 0x35, 0x98, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, 0x00, 0x6c, 0x00, 0x23, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x4b, 0xd1, 0xef, 0xba, 0xfb, 0x41, 0x92, - 0x6d, 0x37, 0x5f, 0xf8, 0x7d, 0x90, 0x0f, 0x01, - 0xf8, 0x8c, 0xee, 0xbc, 0xd9, 0x0c, 0x97, 0x7e, - 0x23, 0x46, 0xe2, 0x6b, 0x52, 0xc6, 0xc6, 0x97, - 0x1d, 0xab, 0xde, 0xa0, 0x86, 0x94, 0xc8, 0x2e, - 0x8b, 0x2e, 0x42, 0x5f, 0xc2, 0x70, 0x35, 0xc9, - 0xee, 0x37, 0xeb, 0x70, 0xaa, 0x59, 0x23, 0x6c, - 0xc8, 0xc1, 0x84, 0x89, 0x39, 0x87, 0x73, 0x0a, - 0x7e, 0xba, 0xca, 0xed, 0x63, 0xba, 0x4e, 0x4f, - 0xf3, 0x31, 0x4b, 0xf0, 0xee, 0x91, 0xa5, 0xb4, - 0x62, 0x01, 0x9e, 0xbd, 0xbc, 0xb3, 0x35, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00, - 0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x24, 0xc5, 0x35, 0x74, 0x19, 0x05, 0xc5, - 0x85, 0x68, 0x48, 0xe8, 0xb5, 0xe9, 0xaf, 0x78, - 0xbd, 0x35, 0x6f, 0xe9, 0x79, 0x34, 0x1b, 0xf0, - 0x35, 0xd4, 0x4e, 0x55, 0x2e, 0x3c, 0xd5, 0xaf, - 0xfc, 0xba, 0xf5, 0x1e, 0x83, 0x32, - }, - { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0x27, 0x28, 0x88, 0xe1, 0x7e, - 0x0d, 0x9c, 0x12, 0x50, 0xf6, 0x7a, 0xa7, 0x32, - 0x21, 0x68, 0xba, 0xd8, 0x0a, 0xdc, 0x39, 0xef, - 0x68, 0x95, 0x82, 0xae, 0xbd, 0x12, 0x79, 0xa1, - 0x99, 0xfd, 0xd0, 0x10, 0x8e, 0x4b, 0xd8, - }, - { - 0x17, 0x03, 0x01, 0x00, 0x21, 0xc5, 0x7e, 0x0a, - 0x52, 0x6a, 0xb9, 0xaa, 0x1d, 0xae, 0x9e, 0x24, - 0x9c, 0x34, 0x1e, 0xdb, 0x50, 0x95, 0xee, 0x76, - 0xd7, 0x28, 0x88, 0x08, 0xe3, 0x2e, 0x58, 0xf7, - 0xdb, 0x34, 0x75, 0xa5, 0x7f, 0x9d, 0x15, 0x03, - 0x01, 0x00, 0x16, 0x2c, 0xc1, 0x29, 0x5f, 0x12, - 0x1d, 0x19, 0xab, 0xb3, 0xf4, 0x35, 0x1c, 0x62, - 0x6a, 0x80, 0x29, 0x0d, 0x0e, 0xef, 0x7d, 0x6e, - 0x50, - }, -} - -var clientauthRSATests = []clientauthTest{ - // Server asks for cert with empty CA list, client doesn't give it. - // go test -run "TestRunServer" -serve -clientauth 1 - {"RequestClientCert, none given", RequestClientCert, nil, [][]byte{ - { - 0x16, 0x03, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, - 0x1a, 0x03, 0x03, 0x51, 0xe5, 0x6c, 0xb5, 0x5a, - 0xc2, 0xf5, 0xf0, 0x92, 0x94, 0x8a, 0x64, 0x18, - 0xa4, 0x2b, 0x82, 0x07, 0xbc, 0xd9, 0xd9, 0xf9, - 0x7b, 0xd2, 0xd0, 0xee, 0xa2, 0x70, 0x4e, 0x23, - 0x88, 0x7c, 0x95, 0x00, 0x00, 0x82, 0xc0, 0x30, - 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, - 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, - 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, - 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, - 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, - 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, - 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, - 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, - 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, - 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, - 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, - 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, - 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, - 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, - 0x00, 0x12, 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, - 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, - 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, - 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, - 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, - 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, - 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, - 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, - 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, - 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, - 0x00, 0x01, 0x01, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x01, 0x00, 0x09, 0x0d, 0x00, 0x00, - 0x05, 0x02, 0x01, 0x40, 0x00, 0x00, 0x16, 0x03, - 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x07, 0x0b, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, 0x00, - 0x86, 0x10, 0x00, 0x00, 0x82, 0x00, 0x80, 0x36, - 0xfc, 0xd8, 0xc8, 0xa2, 0x67, 0xc8, 0xc6, 0xf4, - 0x28, 0x70, 0xe1, 0x5a, 0x02, 0x8f, 0xef, 0x42, - 0xe0, 0xd3, 0xb8, 0xd6, 0x6b, 0xe4, 0xee, 0x5c, - 0xcf, 0x42, 0xc4, 0xfa, 0xcd, 0x0f, 0xfe, 0xf4, - 0x76, 0x76, 0x47, 0x73, 0xa8, 0x72, 0x8f, 0xa2, - 0x56, 0x81, 0x83, 0xb8, 0x84, 0x72, 0x67, 0xdd, - 0xbe, 0x05, 0x4b, 0x84, 0xd9, 0xd2, 0xb6, 0xc2, - 0xe7, 0x20, 0xac, 0x1f, 0x46, 0x9d, 0x05, 0x47, - 0x8e, 0x89, 0xc0, 0x42, 0x57, 0x4a, 0xa2, 0x98, - 0xe5, 0x39, 0x4f, 0xc4, 0x27, 0x6d, 0x43, 0xa8, - 0x83, 0x76, 0xe6, 0xad, 0xe3, 0x17, 0x68, 0x31, - 0xcb, 0x7e, 0xfc, 0xe7, 0x4b, 0x76, 0x3d, 0x3c, - 0xfa, 0x77, 0x65, 0xc9, 0x4c, 0x5b, 0xce, 0x5e, - 0xf7, 0x8b, 0xa8, 0xa6, 0xdd, 0xb2, 0xef, 0x0b, - 0x46, 0x83, 0xdf, 0x0a, 0x8c, 0x22, 0x12, 0x6e, - 0xe1, 0x45, 0x54, 0x88, 0xd1, 0xe8, 0xd2, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x24, 0x30, 0x8c, 0x7d, 0x40, 0xfc, 0x5e, - 0x80, 0x9c, 0xc4, 0x7c, 0x62, 0x01, 0xa1, 0x37, - 0xcf, 0x1a, 0x75, 0x28, 0x8d, 0xeb, 0x63, 0xcc, - 0x02, 0xa6, 0x66, 0xdf, 0x36, 0x01, 0xb3, 0x9d, - 0x38, 0x42, 0x16, 0x91, 0xf0, 0x02, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x4b, 0xd1, 0xef, 0xba, 0x96, 0x9a, 0x2a, - 0x6c, 0x8c, 0x7e, 0x38, 0x10, 0x46, 0x86, 0x1d, - 0x19, 0x1d, 0x62, 0x29, 0x3f, 0x58, 0xfb, 0x6d, - 0x89, 0xd2, 0x81, 0x9a, 0x1c, 0xb3, 0x58, 0xb3, - 0x19, 0x39, 0x17, 0x47, 0x49, 0xc9, 0xfe, 0x4a, - 0x7a, 0x32, 0xac, 0x2c, 0x43, 0xf9, 0xa9, 0xea, - 0xec, 0x51, 0x46, 0xf1, 0xb8, 0x59, 0x23, 0x70, - 0xce, 0x7c, 0xb9, 0x47, 0x70, 0xa3, 0xc9, 0xae, - 0x47, 0x7b, 0x7e, 0xc7, 0xcf, 0x76, 0x12, 0x76, - 0x18, 0x90, 0x12, 0xcd, 0xf3, 0xd4, 0x27, 0x81, - 0xfc, 0x46, 0x03, 0x3e, 0x05, 0x87, 0x6f, 0x14, - 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x24, 0xc3, 0xa0, 0x29, 0xb1, 0x52, 0x82, - 0xef, 0x85, 0xa1, 0x64, 0x0f, 0xe4, 0xa3, 0xfb, - 0xa7, 0x1d, 0x22, 0x4c, 0xcb, 0xd6, 0x5b, 0x18, - 0x61, 0xc7, 0x7c, 0xf2, 0x67, 0x4a, 0xc7, 0x11, - 0x9d, 0x8e, 0x0e, 0x15, 0x22, 0xcf, 0x17, 0x03, - 0x01, 0x00, 0x21, 0xfd, 0xbb, 0xf1, 0xa9, 0x7c, - 0xbf, 0x92, 0xb3, 0xfa, 0x2c, 0x08, 0x6f, 0x22, - 0x78, 0x80, 0xf2, 0x2e, 0x86, 0x26, 0x21, 0x36, - 0x3f, 0x32, 0xdf, 0xb6, 0x47, 0xa5, 0xf8, 0x27, - 0xc1, 0xe9, 0x53, 0x90, 0x15, 0x03, 0x01, 0x00, - 0x16, 0xfe, 0xef, 0x2e, 0xa0, 0x5d, 0xe0, 0xce, - 0x94, 0x20, 0x56, 0x61, 0x6e, 0xe5, 0x62, 0xce, - 0x27, 0x57, 0x3e, 0x30, 0x32, 0x77, 0x53, - }, - }}, - - // Server asks for cert with empty CA list, client gives one - // go test -run "TestRunServer" -serve -clientauth 1 - {"RequestClientCert, client gives it", RequestClientCert, []*x509.Certificate{clientCertificate}, [][]byte{ - { - 0x16, 0x03, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, - 0x1a, 0x03, 0x03, 0x51, 0xe5, 0x74, 0x0e, 0x95, - 0x6f, 0x4f, 0x4a, 0xbf, 0xb7, 0xc0, 0x6c, 0xac, - 0xd9, 0xfe, 0x7d, 0xd0, 0x51, 0x19, 0x62, 0x62, - 0x1c, 0x6e, 0x57, 0x77, 0xd2, 0x31, 0xaf, 0x88, - 0xb9, 0xc0, 0x1d, 0x00, 0x00, 0x82, 0xc0, 0x30, - 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, - 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, - 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, - 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, - 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, - 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, - 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, - 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, - 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, - 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, - 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, - 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, - 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, - 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, - 0x00, 0x12, 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, - 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, - 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, - 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, - 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, - 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, - 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, - 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, - 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, - 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, - 0x00, 0x01, 0x01, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x01, 0x00, 0x09, 0x0d, 0x00, 0x00, - 0x05, 0x02, 0x01, 0x40, 0x00, 0x00, 0x16, 0x03, - 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x01, 0xfb, 0x0b, 0x00, 0x01, - 0xf7, 0x00, 0x01, 0xf4, 0x00, 0x01, 0xf1, 0x30, - 0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x58, 0xa0, - 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, - 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x30, 0x26, 0x31, 0x10, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, - 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x31, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37, - 0x35, 0x35, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x31, - 0x32, 0x31, 0x32, 0x30, 0x37, 0x30, 0x38, 0x30, - 0x30, 0x31, 0x32, 0x5a, 0x30, 0x26, 0x31, 0x10, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, - 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9c, 0x30, - 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x03, 0x81, 0x8c, 0x00, - 0x30, 0x81, 0x88, 0x02, 0x81, 0x80, 0x4e, 0xd0, - 0x7b, 0x31, 0xe3, 0x82, 0x64, 0xd9, 0x59, 0xc0, - 0xc2, 0x87, 0xa4, 0x5e, 0x1e, 0x8b, 0x73, 0x33, - 0xc7, 0x63, 0x53, 0xdf, 0x66, 0x92, 0x06, 0x84, - 0xf6, 0x64, 0xd5, 0x8f, 0xe4, 0x36, 0xa7, 0x1d, - 0x2b, 0xe8, 0xb3, 0x20, 0x36, 0x45, 0x23, 0xb5, - 0xe3, 0x95, 0xae, 0xed, 0xe0, 0xf5, 0x20, 0x9c, - 0x8d, 0x95, 0xdf, 0x7f, 0x5a, 0x12, 0xef, 0x87, - 0xe4, 0x5b, 0x68, 0xe4, 0xe9, 0x0e, 0x74, 0xec, - 0x04, 0x8a, 0x7f, 0xde, 0x93, 0x27, 0xc4, 0x01, - 0x19, 0x7a, 0xbd, 0xf2, 0xdc, 0x3d, 0x14, 0xab, - 0xd0, 0x54, 0xca, 0x21, 0x0c, 0xd0, 0x4d, 0x6e, - 0x87, 0x2e, 0x5c, 0xc5, 0xd2, 0xbb, 0x4d, 0x4b, - 0x4f, 0xce, 0xb6, 0x2c, 0xf7, 0x7e, 0x88, 0xec, - 0x7c, 0xd7, 0x02, 0x91, 0x74, 0xa6, 0x1e, 0x0c, - 0x1a, 0xda, 0xe3, 0x4a, 0x5a, 0x2e, 0xde, 0x13, - 0x9c, 0x4c, 0x40, 0x88, 0x59, 0x93, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x32, 0x30, 0x30, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0xa0, 0x30, - 0x0d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x06, - 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x08, 0x30, - 0x06, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, - 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x03, 0x81, 0x81, 0x00, - 0x36, 0x1f, 0xb3, 0x7a, 0x0c, 0x75, 0xc9, 0x6e, - 0x37, 0x46, 0x61, 0x2b, 0xd5, 0xbd, 0xc0, 0xa7, - 0x4b, 0xcc, 0x46, 0x9a, 0x81, 0x58, 0x7c, 0x85, - 0x79, 0x29, 0xc8, 0xc8, 0xc6, 0x67, 0xdd, 0x32, - 0x56, 0x45, 0x2b, 0x75, 0xb6, 0xe9, 0x24, 0xa9, - 0x50, 0x9a, 0xbe, 0x1f, 0x5a, 0xfa, 0x1a, 0x15, - 0xd9, 0xcc, 0x55, 0x95, 0x72, 0x16, 0x83, 0xb9, - 0xc2, 0xb6, 0x8f, 0xfd, 0x88, 0x8c, 0x38, 0x84, - 0x1d, 0xab, 0x5d, 0x92, 0x31, 0x13, 0x4f, 0xfd, - 0x83, 0x3b, 0xc6, 0x9d, 0xf1, 0x11, 0x62, 0xb6, - 0x8b, 0xec, 0xab, 0x67, 0xbe, 0xc8, 0x64, 0xb0, - 0x11, 0x50, 0x46, 0x58, 0x17, 0x6b, 0x99, 0x1c, - 0xd3, 0x1d, 0xfc, 0x06, 0xf1, 0x0e, 0xe5, 0x96, - 0xa8, 0x0c, 0xf9, 0x78, 0x20, 0xb7, 0x44, 0x18, - 0x51, 0x8d, 0x10, 0x7e, 0x4f, 0x94, 0x67, 0xdf, - 0xa3, 0x4e, 0x70, 0x73, 0x8e, 0x90, 0x91, 0x85, - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x0a, 0x4e, 0x89, 0xdf, 0x3a, - 0x3f, 0xf0, 0x4f, 0xef, 0x1a, 0x90, 0xd4, 0x3c, - 0xaf, 0x10, 0x57, 0xb0, 0xa1, 0x5f, 0xcd, 0x62, - 0x01, 0xe9, 0x0c, 0x36, 0x42, 0xfd, 0xaf, 0x23, - 0xf9, 0x14, 0xa6, 0x72, 0x26, 0x4e, 0x01, 0xdb, - 0xac, 0xb7, 0x4c, 0xe6, 0xa9, 0x52, 0xe2, 0xec, - 0x26, 0x8c, 0x7a, 0x64, 0xf8, 0x0b, 0x4c, 0x2f, - 0xa9, 0xcb, 0x75, 0xaf, 0x60, 0xd4, 0xb4, 0xe6, - 0xe8, 0xdb, 0x78, 0x78, 0x85, 0xf6, 0x0c, 0x95, - 0xcc, 0xb6, 0x55, 0xb9, 0xba, 0x9e, 0x91, 0xbc, - 0x66, 0xdb, 0x1e, 0x28, 0xab, 0x73, 0xce, 0x8b, - 0xd0, 0xd3, 0xe8, 0xbc, 0xd0, 0x21, 0x28, 0xbd, - 0xfb, 0x74, 0x64, 0xde, 0x3b, 0x3b, 0xd3, 0x4c, - 0x32, 0x40, 0x82, 0xba, 0x91, 0x1e, 0xe8, 0x47, - 0xc2, 0x09, 0xb7, 0x16, 0xaa, 0x25, 0xa9, 0x3c, - 0x6c, 0xa7, 0xf8, 0xc9, 0x54, 0x84, 0xc6, 0xf7, - 0x56, 0x05, 0xa4, 0x16, 0x03, 0x01, 0x00, 0x86, - 0x0f, 0x00, 0x00, 0x82, 0x00, 0x80, 0x4b, 0xab, - 0xda, 0xac, 0x2a, 0xb3, 0xe6, 0x34, 0x55, 0xcd, - 0xf2, 0x4b, 0x67, 0xe3, 0xd3, 0xff, 0xa3, 0xf4, - 0x79, 0x82, 0x01, 0x47, 0x8a, 0xe3, 0x9f, 0x89, - 0x70, 0xbe, 0x24, 0x24, 0xb7, 0x69, 0x60, 0xed, - 0x55, 0xa0, 0xca, 0x72, 0xb6, 0x4a, 0xbc, 0x1d, - 0xe2, 0x3f, 0xb5, 0x31, 0xda, 0x02, 0xf6, 0x37, - 0x51, 0xf8, 0x4c, 0x88, 0x2e, 0xb3, 0x8a, 0xe8, - 0x7b, 0x4a, 0x90, 0x36, 0xe4, 0xa6, 0x31, 0x95, - 0x8b, 0xa0, 0xc6, 0x91, 0x12, 0xb9, 0x35, 0x4e, - 0x72, 0xeb, 0x5c, 0xa2, 0xe8, 0x4c, 0x68, 0xf9, - 0x69, 0xfa, 0x70, 0x60, 0x6c, 0x7f, 0x32, 0x99, - 0xf1, 0xc3, 0x2d, 0xb4, 0x59, 0x58, 0x87, 0xaf, - 0x67, 0x62, 0x90, 0xe7, 0x8d, 0xd0, 0xa3, 0x77, - 0x33, 0xc2, 0x9b, 0xd5, 0x9c, 0xc7, 0xea, 0x25, - 0x98, 0x76, 0x9c, 0xe0, 0x6a, 0x03, 0x3a, 0x10, - 0xfd, 0x10, 0x3d, 0x55, 0x53, 0xa0, 0x14, 0x03, - 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, - 0x24, 0xd5, 0x12, 0xfc, 0xb9, 0x5a, 0xe3, 0x27, - 0x01, 0xbe, 0xc3, 0x77, 0x17, 0x1a, 0xbb, 0x4f, - 0xae, 0xd5, 0xa7, 0xee, 0x56, 0x61, 0x0d, 0x40, - 0xf4, 0xa4, 0xb5, 0xcc, 0x76, 0xfd, 0xbd, 0x13, - 0x04, 0xe1, 0xb8, 0xc7, 0x36, - }, - { - 0x16, 0x03, 0x01, 0x02, 0x67, 0x04, 0x00, 0x02, - 0x63, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5d, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x4b, 0xd1, 0xef, 0xba, 0x1f, 0xe2, 0x69, - 0x07, 0x7f, 0x85, 0x2d, 0x4e, 0x2a, 0x2e, 0xbd, - 0x05, 0xe9, 0xc1, 0x6c, 0x9e, 0xbf, 0x47, 0x18, - 0x91, 0x77, 0xf7, 0xe8, 0xb6, 0x27, 0x37, 0xa6, - 0x6b, 0x87, 0x29, 0xbb, 0x3b, 0xe5, 0x68, 0x62, - 0x04, 0x3e, 0xad, 0x4d, 0xff, 0xad, 0xf1, 0x22, - 0x87, 0x8d, 0xf6, 0x04, 0x3b, 0x59, 0x22, 0xf7, - 0xfd, 0x88, 0x0e, 0xa4, 0x09, 0xc0, 0x0d, 0x10, - 0x80, 0x10, 0x79, 0xee, 0x70, 0x96, 0xdb, 0x22, - 0x8b, 0xb7, 0xac, 0xe0, 0x98, 0xad, 0xe9, 0xe3, - 0xcb, 0xea, 0x9f, 0xe6, 0x83, 0x28, 0x7c, 0x7e, - 0x4e, 0x9a, 0x8d, 0xd9, 0xf3, 0x86, 0xf4, 0x89, - 0x8b, 0x79, 0x8f, 0xbb, 0xe9, 0x74, 0x02, 0x02, - 0x14, 0x04, 0xea, 0xba, 0x16, 0x10, 0xa1, 0x85, - 0xbe, 0x4e, 0x4e, 0x92, 0xc5, 0x83, 0xf6, 0x1e, - 0x1f, 0xd4, 0x25, 0xc2, 0xc2, 0xb9, 0xce, 0x33, - 0x63, 0x66, 0x79, 0x1f, 0x54, 0x35, 0xc1, 0xe8, - 0x89, 0x34, 0x78, 0x94, 0x36, 0x14, 0xef, 0x01, - 0x1f, 0xf1, 0xbd, 0x77, 0x2c, 0x4d, 0xac, 0x5c, - 0x5c, 0x4a, 0xc6, 0xed, 0xd8, 0x0e, 0x72, 0x84, - 0x83, 0xdc, 0x56, 0x84, 0xc8, 0xf3, 0x89, 0x56, - 0xfd, 0x89, 0xc1, 0xc9, 0x9a, 0x29, 0x91, 0x7e, - 0x19, 0xe9, 0x8b, 0x5b, 0x11, 0x15, 0x4e, 0x6c, - 0xf4, 0x89, 0xe7, 0x6d, 0x68, 0x1e, 0xf9, 0x6c, - 0x23, 0x72, 0x05, 0x68, 0x82, 0x60, 0x84, 0x1f, - 0x83, 0x20, 0x09, 0x86, 0x10, 0x81, 0xec, 0xec, - 0xdc, 0x25, 0x53, 0x20, 0xfa, 0xa9, 0x41, 0x64, - 0xd6, 0x20, 0xf3, 0xf4, 0x52, 0xf2, 0x80, 0x62, - 0x83, 0xc9, 0x23, 0x66, 0x44, 0x95, 0x5a, 0x99, - 0x8a, 0xe1, 0x26, 0x63, 0xc1, 0x8b, 0x31, 0xf9, - 0x21, 0x06, 0x77, 0x04, 0x27, 0xf2, 0x0c, 0x63, - 0x83, 0x45, 0xa0, 0xa9, 0x7b, 0xcf, 0xdf, 0xd7, - 0x56, 0x75, 0xbc, 0xdd, 0x95, 0x36, 0xb1, 0x75, - 0x39, 0x05, 0x00, 0x3c, 0x8a, 0x79, 0xd6, 0xe9, - 0xf0, 0x4b, 0xdc, 0x51, 0x6b, 0x01, 0x94, 0x16, - 0x87, 0x12, 0x92, 0x6c, 0x07, 0xc1, 0xf5, 0x58, - 0xb7, 0x2a, 0x81, 0xf5, 0xa0, 0x37, 0x8b, 0xa6, - 0x22, 0xfe, 0x28, 0x0a, 0x7e, 0x68, 0xe2, 0xda, - 0x6c, 0x53, 0xee, 0x0e, 0x8d, 0x2d, 0x8b, 0x0b, - 0xda, 0xf8, 0x99, 0x3e, 0x0e, 0xed, 0x9f, 0xc1, - 0x2b, 0xf6, 0xfe, 0xe9, 0x52, 0x38, 0x7b, 0x83, - 0x9a, 0x50, 0xa6, 0xd7, 0x49, 0x83, 0x43, 0x7e, - 0x82, 0xec, 0xc7, 0x09, 0x3d, 0x3d, 0xb1, 0xee, - 0xe8, 0xc5, 0x6a, 0xc3, 0x3d, 0x4b, 0x4c, 0x6a, - 0xbb, 0x0b, 0x2c, 0x24, 0x2e, 0xdb, 0x7d, 0x57, - 0x87, 0xb4, 0x80, 0xa5, 0xae, 0xff, 0x54, 0xa8, - 0xa5, 0x27, 0x69, 0x95, 0xc8, 0xe7, 0x79, 0xc7, - 0x89, 0x2a, 0x73, 0x49, 0xcb, 0xf5, 0xc5, 0xbc, - 0x4a, 0xe0, 0x73, 0xa9, 0xbc, 0x88, 0x64, 0x96, - 0x98, 0xa5, 0x1e, 0xe3, 0x43, 0xc1, 0x7d, 0x78, - 0xc7, 0x94, 0x72, 0xd4, 0x2c, 0x6e, 0x85, 0x39, - 0x9a, 0xaf, 0xdb, 0xa1, 0xe9, 0xe2, 0xcb, 0x37, - 0x04, 0xc6, 0x8c, 0x81, 0xd3, 0x2a, 0xb7, 0xbe, - 0x6c, 0x07, 0x1f, 0x5e, 0xd9, 0x00, 0xd2, 0xf7, - 0xe1, 0xa7, 0xbc, 0x0c, 0xb6, 0x6d, 0xfb, 0x3f, - 0x3d, 0x24, 0xaa, 0xfb, 0x7e, 0xe1, 0xb5, 0x1b, - 0xff, 0x38, 0xaa, 0x69, 0x59, 0x38, 0x52, 0x9a, - 0x0e, 0x6d, 0xbc, 0xde, 0x4f, 0x13, 0x09, 0x17, - 0xc4, 0xa9, 0x05, 0x84, 0xbc, 0x50, 0xef, 0x40, - 0xb0, 0x4c, 0x24, 0x32, 0xed, 0x94, 0x2c, 0xdd, - 0xda, 0x20, 0x24, 0x67, 0xe2, 0xea, 0x71, 0x3d, - 0x4a, 0x04, 0x0d, 0x98, 0x29, 0x20, 0x4c, 0xeb, - 0x70, 0xce, 0x45, 0x9e, 0x5a, 0xaf, 0xb6, 0xa3, - 0x92, 0xc8, 0x28, 0xf2, 0xe3, 0xe8, 0x8a, 0x5d, - 0x0a, 0x33, 0x79, 0x9b, 0x6a, 0xf3, 0x30, 0x01, - 0x1d, 0x47, 0xbd, 0x01, 0xcc, 0x4d, 0x71, 0xc0, - 0x56, 0xfa, 0xfd, 0x37, 0xed, 0x0f, 0x27, 0xc0, - 0xbb, 0xa0, 0xee, 0xc3, 0x79, 0x8b, 0xe7, 0x41, - 0x8f, 0xfa, 0x3a, 0xcb, 0x45, 0x3b, 0x85, 0x9f, - 0x06, 0x90, 0xb2, 0x51, 0x7a, 0xc3, 0x11, 0x41, - 0x4b, 0xe3, 0x26, 0x94, 0x3e, 0xa2, 0xfd, 0x0a, - 0xda, 0x50, 0xf6, 0x50, 0x78, 0x19, 0x6c, 0x52, - 0xd1, 0x12, 0x76, 0xc2, 0x50, 0x2f, 0x0b, 0xca, - 0x33, 0xe5, 0x79, 0x93, 0x14, 0x03, 0x01, 0x00, - 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0x2b, - 0x51, 0x42, 0x95, 0x6b, 0xca, 0x9f, 0x42, 0x5d, - 0xd2, 0xd9, 0x67, 0xf9, 0x49, 0x30, 0xfd, 0x2a, - 0x46, 0xd3, 0x04, 0xf4, 0x86, 0xf9, 0x11, 0x34, - 0x82, 0xac, 0xe2, 0xc2, 0x2d, 0xc4, 0xd0, 0xfe, - 0xa9, 0xc9, 0x4b, 0x17, 0x03, 0x01, 0x00, 0x21, - 0x65, 0x1c, 0xe9, 0x5c, 0xb6, 0xe2, 0x7c, 0x8e, - 0x49, 0x12, 0x1b, 0xe6, 0x40, 0xd3, 0x97, 0x21, - 0x76, 0x01, 0xe5, 0x80, 0x5e, 0xf3, 0x11, 0x47, - 0x25, 0x02, 0x78, 0x8e, 0x6b, 0xae, 0xb3, 0xf3, - 0x59, 0x15, 0x03, 0x01, 0x00, 0x16, 0x38, 0xc1, - 0x99, 0x2e, 0xf8, 0x6f, 0x45, 0xa4, 0x10, 0x79, - 0x5b, 0xc1, 0x47, 0x9a, 0xf6, 0x5c, 0x90, 0xeb, - 0xa6, 0xe3, 0x1a, 0x24, - }, - }}, -} - -var tls11ECDHEAESServerScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x01, 0x46, 0x01, 0x00, 0x01, - 0x42, 0x03, 0x03, 0x51, 0x9f, 0xa3, 0xb0, 0xb7, - 0x1d, 0x26, 0x93, 0x36, 0xc0, 0x8d, 0x7e, 0xf8, - 0x4f, 0x6f, 0xc9, 0x3c, 0x31, 0x1e, 0x7f, 0xb1, - 0xf0, 0xc1, 0x0f, 0xf9, 0x0c, 0xa2, 0xd5, 0xca, - 0x48, 0xe5, 0x35, 0x00, 0x00, 0xd0, 0xc0, 0x30, - 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, - 0xc0, 0x0a, 0xc0, 0x22, 0xc0, 0x21, 0x00, 0xa5, - 0x00, 0xa3, 0x00, 0xa1, 0x00, 0x9f, 0x00, 0x6b, - 0x00, 0x6a, 0x00, 0x69, 0x00, 0x68, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x37, 0x00, 0x36, 0x00, 0x88, - 0x00, 0x87, 0x00, 0x86, 0x00, 0x85, 0xc0, 0x32, - 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, - 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, - 0x00, 0x84, 0xc0, 0x12, 0xc0, 0x08, 0xc0, 0x1c, - 0xc0, 0x1b, 0x00, 0x16, 0x00, 0x13, 0x00, 0x10, - 0x00, 0x0d, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, - 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, - 0xc0, 0x13, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x1e, - 0x00, 0xa4, 0x00, 0xa2, 0x00, 0xa0, 0x00, 0x9e, - 0x00, 0x67, 0x00, 0x40, 0x00, 0x3f, 0x00, 0x3e, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x31, 0x00, 0x30, - 0x00, 0x9a, 0x00, 0x99, 0x00, 0x98, 0x00, 0x97, - 0x00, 0x45, 0x00, 0x44, 0x00, 0x43, 0x00, 0x42, - 0xc0, 0x31, 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, - 0xc0, 0x0e, 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, - 0x00, 0x2f, 0x00, 0x96, 0x00, 0x41, 0x00, 0x07, - 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x14, - 0x00, 0x11, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x01, 0x00, - 0x00, 0x49, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, - 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, - 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, - 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, - 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, - 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, - 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x01, 0x01, - }, - { - 0x16, 0x03, 0x02, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x13, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x02, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x02, 0x01, 0x0f, 0x0c, 0x00, 0x01, - 0x0b, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, - 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, - 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, - 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, - 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, - 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, - 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, - 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, - 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, - 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, - 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, - 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, - 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, - 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, - 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, - 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, - 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, - 0x90, 0x33, 0x00, 0x80, 0x16, 0x83, 0x9b, 0xf9, - 0x72, 0xdb, 0x9f, 0x55, 0x02, 0xe1, 0x04, 0xf7, - 0xb5, 0x3f, 0x4c, 0x71, 0x13, 0x5a, 0x91, 0xe9, - 0x1d, 0xeb, 0x9d, 0x9c, 0xfb, 0x88, 0xef, 0xca, - 0xec, 0x7d, 0x9b, 0xdd, 0xd9, 0xee, 0x2b, 0x8e, - 0xef, 0xf8, 0xb6, 0xc7, 0x7d, 0xfe, 0xda, 0x7f, - 0x90, 0x2e, 0x53, 0xf1, 0x64, 0x95, 0xfc, 0x66, - 0xfc, 0x87, 0x27, 0xb6, 0x9f, 0xc8, 0x3a, 0x95, - 0x68, 0x17, 0xe1, 0x7d, 0xf1, 0x88, 0xe8, 0x17, - 0x5f, 0x99, 0x90, 0x3f, 0x47, 0x47, 0x81, 0x06, - 0xe2, 0x8e, 0x22, 0x56, 0x8f, 0xc2, 0x14, 0xe5, - 0x62, 0xa7, 0x0d, 0x41, 0x3c, 0xc7, 0x4a, 0x0a, - 0x74, 0x4b, 0xda, 0x00, 0x8e, 0x4f, 0x90, 0xe6, - 0xd7, 0x68, 0xe5, 0x8b, 0xf2, 0x3f, 0x53, 0x1d, - 0x7a, 0xe6, 0xb3, 0xe9, 0x8a, 0xc9, 0x4d, 0x19, - 0xa6, 0xcf, 0xf9, 0xed, 0x5e, 0x26, 0xdc, 0x90, - 0x1c, 0x41, 0xad, 0x7c, 0x16, 0x03, 0x02, 0x00, - 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x02, 0x00, 0x8a, 0x10, 0x00, 0x00, - 0x86, 0x85, 0x04, 0x01, 0x11, 0xf2, 0xa4, 0x2d, - 0x1a, 0x75, 0x6c, 0xbc, 0x2d, 0x91, 0x95, 0x07, - 0xbe, 0xd6, 0x41, 0x7a, 0xbb, 0xc2, 0x7b, 0xa6, - 0x9b, 0xe3, 0xdc, 0x41, 0x7f, 0x1e, 0x2e, 0xcc, - 0x6d, 0xa3, 0x85, 0x53, 0x98, 0x9f, 0x2d, 0xe6, - 0x3c, 0xb9, 0x82, 0xa6, 0x80, 0x53, 0x9b, 0x71, - 0xfd, 0x27, 0xe5, 0xe5, 0xdf, 0x13, 0xba, 0x56, - 0x62, 0x30, 0x4a, 0x57, 0x27, 0xa7, 0xcc, 0x26, - 0x54, 0xe8, 0x65, 0x6e, 0x4d, 0x00, 0xbf, 0x8a, - 0xcc, 0x89, 0x6a, 0x6c, 0x88, 0xda, 0x79, 0x4f, - 0xc5, 0xad, 0x6d, 0x1d, 0x7c, 0x53, 0x7b, 0x1a, - 0x96, 0xf2, 0xf8, 0x30, 0x01, 0x0b, 0xc2, 0xf0, - 0x78, 0x41, 0xf4, 0x0d, 0xe0, 0xbe, 0xb9, 0x36, - 0xe0, 0xb7, 0xee, 0x16, 0xeb, 0x25, 0x67, 0x04, - 0xc0, 0x2e, 0xd8, 0x34, 0x4a, 0x65, 0xa5, 0xf1, - 0x95, 0x75, 0xc7, 0x39, 0xa9, 0x68, 0xa9, 0x53, - 0x93, 0x5b, 0xca, 0x7b, 0x7f, 0xc0, 0x63, 0x14, - 0x03, 0x02, 0x00, 0x01, 0x01, 0x16, 0x03, 0x02, - 0x00, 0x40, 0x01, 0xb1, 0xae, 0x1b, 0x8a, 0x65, - 0xf8, 0x37, 0x50, 0x39, 0x76, 0xef, 0xaa, 0xda, - 0x84, 0xc9, 0x5f, 0x80, 0xdc, 0xfa, 0xe0, 0x46, - 0x5a, 0xc7, 0x77, 0x9d, 0x76, 0x03, 0xa6, 0xd5, - 0x0e, 0xbf, 0x25, 0x30, 0x5c, 0x99, 0x7d, 0xcd, - 0x2b, 0xaa, 0x2e, 0x8c, 0xdd, 0xda, 0xaa, 0xd7, - 0xf1, 0xf6, 0x33, 0x47, 0x51, 0x1e, 0x83, 0xa1, - 0x83, 0x04, 0xd2, 0xb2, 0xc8, 0xbc, 0x11, 0xc5, - 0x1a, 0x87, - }, - { - 0x16, 0x03, 0x02, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xeb, 0x8b, 0xc7, 0xef, 0xba, 0xe8, 0x0f, 0x69, - 0xfe, 0xfb, 0xc3, 0x3d, 0x90, 0x5d, 0xd7, 0xb2, - 0x51, 0x64, 0xac, 0xc3, 0xae, 0x33, 0x03, 0x42, - 0x45, 0x2d, 0xa7, 0x57, 0xbd, 0xa3, 0x85, 0x64, - 0xa6, 0xfe, 0x5c, 0x33, 0x04, 0x93, 0xf2, 0x7c, - 0x06, 0x6d, 0xd7, 0xd7, 0xcf, 0x4a, 0xaf, 0xb2, - 0xdd, 0x06, 0xdc, 0x28, 0x14, 0x59, 0x23, 0x02, - 0xef, 0x97, 0x6a, 0xe8, 0xec, 0xca, 0x10, 0x44, - 0xcd, 0xb8, 0x50, 0x16, 0x46, 0x5a, 0x05, 0xda, - 0x04, 0xb3, 0x0e, 0xe9, 0xf0, 0x74, 0xc5, 0x23, - 0xc2, 0x0e, 0xa1, 0x54, 0x66, 0x7b, 0xe8, 0x14, - 0x03, 0x02, 0x00, 0x01, 0x01, 0x16, 0x03, 0x02, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6b, 0x43, 0x1c, 0x58, 0xbc, 0x85, - 0xf7, 0xc1, 0x76, 0xbc, 0x72, 0x33, 0x41, 0x6b, - 0xb8, 0xf8, 0xfd, 0x53, 0x21, 0xc2, 0x41, 0x1b, - 0x72, 0x4f, 0xce, 0x97, 0xca, 0x14, 0x23, 0x4d, - 0xbc, 0x44, 0xd6, 0xd7, 0xfc, 0xbc, 0xfd, 0xfd, - 0x5d, 0x33, 0x42, 0x1b, 0x52, 0x40, 0x0a, 0x2b, - 0x6c, 0x98, 0x17, 0x03, 0x02, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, - 0x31, 0xef, 0x03, 0x7d, 0xa5, 0x74, 0x92, 0x24, - 0x34, 0xae, 0x4e, 0xc9, 0xfc, 0x59, 0xcb, 0x64, - 0xf4, 0x45, 0xb1, 0xac, 0x02, 0xf2, 0x87, 0xe7, - 0x2f, 0xfd, 0x01, 0xca, 0x78, 0x02, 0x2e, 0x3a, - 0x38, 0xcd, 0xb1, 0xe0, 0xf2, 0x2e, 0xf6, 0x27, - 0xa0, 0xac, 0x1f, 0x91, 0x43, 0xc2, 0x3d, 0x15, - 0x03, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9f, 0x30, 0x24, 0x56, - 0x2c, 0xde, 0xa0, 0xe6, 0x44, 0x35, 0x30, 0x51, - 0xec, 0xd4, 0x69, 0x2d, 0x46, 0x64, 0x04, 0x21, - 0xfe, 0x7c, 0x4d, 0xc5, 0xd0, 0x8c, 0xf9, 0xd2, - 0x3f, 0x88, 0x69, 0xd5, - }, -} - -// $ go test -run TestRunServer -serve -clientauth 1 \ -// -ciphersuites=0xc011 -minversion=0x0303 -maxversion=0x0303 -var tls12ServerScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, - 0x1a, 0x03, 0x03, 0x51, 0xe5, 0x76, 0x84, 0x0e, - 0xb9, 0x17, 0xca, 0x08, 0x47, 0xd9, 0xbd, 0xd0, - 0x94, 0xd1, 0x97, 0xca, 0x5b, 0xe7, 0x20, 0xac, - 0x8e, 0xbb, 0xc7, 0x29, 0xe9, 0x26, 0xcf, 0x7d, - 0xb3, 0xdc, 0x99, 0x00, 0x00, 0x82, 0xc0, 0x30, - 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, - 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, - 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, - 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, - 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, - 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, - 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, - 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, - 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, - 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, - 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, - 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, - 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, - 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, - 0x00, 0x12, 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, - 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, - 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, - 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, - 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, - 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, - 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, - 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, - 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, - 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, - 0x00, 0x01, 0x01, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x03, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x03, 0x01, 0x11, 0x0c, 0x00, 0x01, - 0x0d, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, - 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, - 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, - 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, - 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, - 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, - 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, - 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, - 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, - 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, - 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, - 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, - 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, - 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, - 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, - 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, - 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, - 0x90, 0x33, 0x04, 0x01, 0x00, 0x80, 0x4a, 0xf9, - 0xf5, 0x0a, 0x61, 0x37, 0x7e, 0x4e, 0x92, 0xb5, - 0x1c, 0x91, 0x21, 0xb2, 0xb5, 0x17, 0x00, 0xbf, - 0x01, 0x5f, 0x30, 0xec, 0x62, 0x08, 0xd6, 0x9d, - 0x1a, 0x08, 0x05, 0x72, 0x8b, 0xf4, 0x49, 0x85, - 0xa7, 0xbf, 0x3f, 0x75, 0x58, 0x3e, 0x26, 0x82, - 0xc3, 0x28, 0x07, 0xf9, 0x41, 0x7d, 0x03, 0x14, - 0x3b, 0xc3, 0x05, 0x64, 0xff, 0x52, 0xf4, 0x75, - 0x6a, 0x87, 0xcd, 0xdf, 0x93, 0x31, 0x0a, 0x71, - 0x60, 0x17, 0xc6, 0x33, 0xf0, 0x79, 0xb6, 0x7b, - 0xd0, 0x9c, 0xa0, 0x5f, 0x74, 0x14, 0x2c, 0x5a, - 0xb4, 0x3f, 0x39, 0xf5, 0xe4, 0x9f, 0xbe, 0x6d, - 0x21, 0xd2, 0xa9, 0x42, 0xf7, 0xdc, 0xa6, 0x65, - 0xb7, 0x6a, 0x7e, 0x2e, 0x14, 0xd3, 0xf6, 0xf3, - 0x4b, 0x4c, 0x5b, 0x1a, 0x70, 0x7a, 0xbc, 0xb0, - 0x12, 0xf3, 0x6e, 0x0c, 0xcf, 0x43, 0x22, 0xae, - 0x5b, 0xba, 0x00, 0xf8, 0xfd, 0xaf, 0x16, 0x03, - 0x03, 0x00, 0x0f, 0x0d, 0x00, 0x00, 0x0b, 0x02, - 0x01, 0x40, 0x00, 0x04, 0x04, 0x01, 0x04, 0x03, - 0x00, 0x00, 0x16, 0x03, 0x03, 0x00, 0x04, 0x0e, - 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x03, 0x01, 0xfb, 0x0b, 0x00, 0x01, - 0xf7, 0x00, 0x01, 0xf4, 0x00, 0x01, 0xf1, 0x30, - 0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x58, 0xa0, - 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, - 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x30, 0x26, 0x31, 0x10, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, - 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x31, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37, - 0x35, 0x35, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x31, - 0x32, 0x31, 0x32, 0x30, 0x37, 0x30, 0x38, 0x30, - 0x30, 0x31, 0x32, 0x5a, 0x30, 0x26, 0x31, 0x10, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, - 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9c, 0x30, - 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x03, 0x81, 0x8c, 0x00, - 0x30, 0x81, 0x88, 0x02, 0x81, 0x80, 0x4e, 0xd0, - 0x7b, 0x31, 0xe3, 0x82, 0x64, 0xd9, 0x59, 0xc0, - 0xc2, 0x87, 0xa4, 0x5e, 0x1e, 0x8b, 0x73, 0x33, - 0xc7, 0x63, 0x53, 0xdf, 0x66, 0x92, 0x06, 0x84, - 0xf6, 0x64, 0xd5, 0x8f, 0xe4, 0x36, 0xa7, 0x1d, - 0x2b, 0xe8, 0xb3, 0x20, 0x36, 0x45, 0x23, 0xb5, - 0xe3, 0x95, 0xae, 0xed, 0xe0, 0xf5, 0x20, 0x9c, - 0x8d, 0x95, 0xdf, 0x7f, 0x5a, 0x12, 0xef, 0x87, - 0xe4, 0x5b, 0x68, 0xe4, 0xe9, 0x0e, 0x74, 0xec, - 0x04, 0x8a, 0x7f, 0xde, 0x93, 0x27, 0xc4, 0x01, - 0x19, 0x7a, 0xbd, 0xf2, 0xdc, 0x3d, 0x14, 0xab, - 0xd0, 0x54, 0xca, 0x21, 0x0c, 0xd0, 0x4d, 0x6e, - 0x87, 0x2e, 0x5c, 0xc5, 0xd2, 0xbb, 0x4d, 0x4b, - 0x4f, 0xce, 0xb6, 0x2c, 0xf7, 0x7e, 0x88, 0xec, - 0x7c, 0xd7, 0x02, 0x91, 0x74, 0xa6, 0x1e, 0x0c, - 0x1a, 0xda, 0xe3, 0x4a, 0x5a, 0x2e, 0xde, 0x13, - 0x9c, 0x4c, 0x40, 0x88, 0x59, 0x93, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x32, 0x30, 0x30, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0xa0, 0x30, - 0x0d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x06, - 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x08, 0x30, - 0x06, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, - 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x03, 0x81, 0x81, 0x00, - 0x36, 0x1f, 0xb3, 0x7a, 0x0c, 0x75, 0xc9, 0x6e, - 0x37, 0x46, 0x61, 0x2b, 0xd5, 0xbd, 0xc0, 0xa7, - 0x4b, 0xcc, 0x46, 0x9a, 0x81, 0x58, 0x7c, 0x85, - 0x79, 0x29, 0xc8, 0xc8, 0xc6, 0x67, 0xdd, 0x32, - 0x56, 0x45, 0x2b, 0x75, 0xb6, 0xe9, 0x24, 0xa9, - 0x50, 0x9a, 0xbe, 0x1f, 0x5a, 0xfa, 0x1a, 0x15, - 0xd9, 0xcc, 0x55, 0x95, 0x72, 0x16, 0x83, 0xb9, - 0xc2, 0xb6, 0x8f, 0xfd, 0x88, 0x8c, 0x38, 0x84, - 0x1d, 0xab, 0x5d, 0x92, 0x31, 0x13, 0x4f, 0xfd, - 0x83, 0x3b, 0xc6, 0x9d, 0xf1, 0x11, 0x62, 0xb6, - 0x8b, 0xec, 0xab, 0x67, 0xbe, 0xc8, 0x64, 0xb0, - 0x11, 0x50, 0x46, 0x58, 0x17, 0x6b, 0x99, 0x1c, - 0xd3, 0x1d, 0xfc, 0x06, 0xf1, 0x0e, 0xe5, 0x96, - 0xa8, 0x0c, 0xf9, 0x78, 0x20, 0xb7, 0x44, 0x18, - 0x51, 0x8d, 0x10, 0x7e, 0x4f, 0x94, 0x67, 0xdf, - 0xa3, 0x4e, 0x70, 0x73, 0x8e, 0x90, 0x91, 0x85, - 0x16, 0x03, 0x03, 0x00, 0x8a, 0x10, 0x00, 0x00, - 0x86, 0x85, 0x04, 0x01, 0x5d, 0x3a, 0x92, 0x59, - 0x7f, 0x9a, 0x22, 0x36, 0x0e, 0x1b, 0x1d, 0x2a, - 0x05, 0xb7, 0xa4, 0xb6, 0x5d, 0xfc, 0x51, 0x6e, - 0x15, 0xe5, 0x89, 0x7c, 0xe2, 0xfa, 0x87, 0x38, - 0x05, 0x79, 0x15, 0x92, 0xb4, 0x8f, 0x88, 0x8f, - 0x9d, 0x5d, 0xa0, 0xaf, 0xf8, 0xce, 0xf9, 0x6f, - 0x83, 0xf4, 0x08, 0x69, 0xe4, 0x91, 0xc5, 0xed, - 0xb9, 0xc5, 0xa8, 0x1f, 0x4b, 0xec, 0xef, 0x91, - 0xc1, 0xa3, 0x34, 0x24, 0x18, 0x00, 0x2d, 0xcd, - 0xe6, 0x44, 0xef, 0x5a, 0x3e, 0x52, 0x63, 0x5b, - 0x36, 0x1f, 0x7e, 0xce, 0x9e, 0xaa, 0xda, 0x8d, - 0xb5, 0xc9, 0xea, 0xd8, 0x1b, 0xd1, 0x1c, 0x7c, - 0x07, 0xfc, 0x3c, 0x2d, 0x70, 0x1f, 0xf9, 0x4d, - 0xcb, 0xaa, 0xad, 0x07, 0xd5, 0x6d, 0xbd, 0xa6, - 0x61, 0xf3, 0x2f, 0xa3, 0x9c, 0x45, 0x02, 0x4a, - 0xac, 0x6c, 0xb6, 0x37, 0x95, 0xb1, 0x4a, 0xb5, - 0x0a, 0x4e, 0x60, 0x67, 0xd7, 0xe0, 0x04, 0x16, - 0x03, 0x03, 0x00, 0x88, 0x0f, 0x00, 0x00, 0x84, - 0x04, 0x01, 0x00, 0x80, 0x08, 0x83, 0x53, 0xf0, - 0xf8, 0x14, 0xf5, 0xc2, 0xd1, 0x8b, 0xf0, 0xa5, - 0xc1, 0xd8, 0x1a, 0x36, 0x4b, 0x75, 0x77, 0x02, - 0x19, 0xd8, 0x11, 0x3f, 0x5a, 0x36, 0xfc, 0xe9, - 0x2b, 0x4b, 0xf9, 0xfe, 0xda, 0x8a, 0x0f, 0x6e, - 0x3d, 0xd3, 0x52, 0x87, 0xf7, 0x9c, 0x78, 0x39, - 0xa8, 0xf1, 0xd7, 0xf7, 0x4e, 0x35, 0x33, 0xf9, - 0xc5, 0x76, 0xa8, 0x12, 0xc4, 0x91, 0x33, 0x1d, - 0x93, 0x8c, 0xbf, 0xb1, 0x83, 0x00, 0x90, 0xc5, - 0x52, 0x3e, 0xe0, 0x0a, 0xe8, 0x92, 0x75, 0xdf, - 0x54, 0x5f, 0x9f, 0x95, 0x76, 0x62, 0xb5, 0x85, - 0x69, 0xa4, 0x86, 0x85, 0x6c, 0xf3, 0x6b, 0x2a, - 0x72, 0x7b, 0x4d, 0x42, 0x33, 0x67, 0x4a, 0xce, - 0xb5, 0xdb, 0x9b, 0xae, 0xc0, 0xb0, 0x10, 0xeb, - 0x3b, 0xf4, 0xc2, 0x9a, 0x64, 0x47, 0x4c, 0x1e, - 0xa5, 0x91, 0x7f, 0x6d, 0xd1, 0x03, 0xf5, 0x4a, - 0x90, 0x69, 0x18, 0xb1, 0x14, 0x03, 0x03, 0x00, - 0x01, 0x01, 0x16, 0x03, 0x03, 0x00, 0x24, 0x59, - 0xfc, 0x7e, 0xae, 0xb3, 0xbf, 0xab, 0x4d, 0xdb, - 0x4e, 0xab, 0xa9, 0x6d, 0x6b, 0x4c, 0x60, 0xb6, - 0x16, 0xe0, 0xab, 0x7f, 0x52, 0x2d, 0xa1, 0xfc, - 0xe1, 0x80, 0xd2, 0x8a, 0xa1, 0xe5, 0x8f, 0xa1, - 0x70, 0x93, 0x23, - }, - { - 0x16, 0x03, 0x03, 0x02, 0x67, 0x04, 0x00, 0x02, - 0x63, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5d, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xea, 0x8b, 0xc5, 0xef, 0xba, 0x64, 0xb7, 0x23, - 0x08, 0x86, 0x4f, 0x37, 0xe0, 0x8f, 0xbd, 0x75, - 0x71, 0x2b, 0xcb, 0x20, 0x75, 0x11, 0x3b, 0xa2, - 0x9e, 0x39, 0x3c, 0x03, 0xef, 0x6e, 0x41, 0xd7, - 0xcf, 0x1a, 0x2c, 0xf2, 0xfe, 0xc2, 0xd3, 0x65, - 0x59, 0x00, 0x9d, 0x03, 0xb4, 0xf2, 0x20, 0xe4, - 0x33, 0x80, 0xcd, 0xf6, 0xe4, 0x59, 0x22, 0xf7, - 0xfd, 0x88, 0x0e, 0xa4, 0x09, 0xc0, 0x0d, 0x10, - 0x80, 0x10, 0x79, 0xee, 0x70, 0x96, 0xdb, 0x22, - 0x8b, 0xb7, 0xac, 0xe0, 0x98, 0xad, 0xe9, 0xe3, - 0xcb, 0xea, 0x9f, 0xe6, 0x83, 0x28, 0x7c, 0x7e, - 0x4e, 0x9a, 0x8d, 0xd9, 0xf3, 0x86, 0xf4, 0x89, - 0x8b, 0x79, 0x8f, 0xbb, 0xe9, 0x74, 0x02, 0x02, - 0x14, 0x04, 0xea, 0xba, 0x16, 0x10, 0xa1, 0x85, - 0xbe, 0x4e, 0x4e, 0x92, 0xc5, 0x83, 0xf6, 0x1e, - 0x1f, 0xd4, 0x25, 0xc2, 0xc2, 0xb9, 0xce, 0x33, - 0x63, 0x66, 0x79, 0x1f, 0x54, 0x35, 0xc1, 0xe8, - 0x89, 0x34, 0x78, 0x94, 0x36, 0x14, 0xef, 0x01, - 0x1f, 0xf1, 0xbd, 0x77, 0x2c, 0x4d, 0xac, 0x5c, - 0x5c, 0x4a, 0xc6, 0xed, 0xd8, 0x0e, 0x72, 0x84, - 0x83, 0xdc, 0x56, 0x84, 0xc8, 0xf3, 0x89, 0x56, - 0xfd, 0x89, 0xc1, 0xc9, 0x9a, 0x29, 0x91, 0x7e, - 0x19, 0xe9, 0x8b, 0x5b, 0x11, 0x15, 0x4e, 0x6c, - 0xf4, 0x89, 0xe7, 0x6d, 0x68, 0x1e, 0xf9, 0x6c, - 0x23, 0x72, 0x05, 0x68, 0x82, 0x60, 0x84, 0x1f, - 0x83, 0x20, 0x09, 0x86, 0x10, 0x81, 0xec, 0xec, - 0xdc, 0x25, 0x53, 0x20, 0xfa, 0xa9, 0x41, 0x64, - 0xd6, 0x20, 0xf3, 0xf4, 0x52, 0xf2, 0x80, 0x62, - 0x83, 0xc9, 0x23, 0x66, 0x44, 0x95, 0x5a, 0x99, - 0x8a, 0xe1, 0x26, 0x63, 0xc1, 0x8b, 0x31, 0xf9, - 0x21, 0x06, 0x77, 0x04, 0x27, 0xf2, 0x0c, 0x63, - 0x83, 0x45, 0xa0, 0xa9, 0x7b, 0xcf, 0xdf, 0xd7, - 0x56, 0x75, 0xbc, 0xdd, 0x95, 0x36, 0xb1, 0x75, - 0x39, 0x05, 0x00, 0x3c, 0x8a, 0x79, 0xd6, 0xe9, - 0xf0, 0x4b, 0xdc, 0x51, 0x6b, 0x01, 0x94, 0x16, - 0x87, 0x12, 0x92, 0x6c, 0x07, 0xc1, 0xf5, 0x58, - 0xb7, 0x2a, 0x81, 0xf5, 0xa0, 0x37, 0x8b, 0xa6, - 0x22, 0xfe, 0x28, 0x0a, 0x7e, 0x68, 0xe2, 0xda, - 0x6c, 0x53, 0xee, 0x0e, 0x8d, 0x2d, 0x8b, 0x0b, - 0xda, 0xf8, 0x99, 0x3e, 0x0e, 0xed, 0x9f, 0xc1, - 0x2b, 0xf6, 0xfe, 0xe9, 0x52, 0x38, 0x7b, 0x83, - 0x9a, 0x50, 0xa6, 0xd7, 0x49, 0x83, 0x43, 0x7e, - 0x82, 0xec, 0xc7, 0x09, 0x3d, 0x3d, 0xb1, 0xee, - 0xe8, 0xc5, 0x6a, 0xc3, 0x3d, 0x4b, 0x4c, 0x6a, - 0xbb, 0x0b, 0x2c, 0x24, 0x2e, 0xdb, 0x7d, 0x57, - 0x87, 0xb4, 0x80, 0xa5, 0xae, 0xff, 0x54, 0xa8, - 0xa5, 0x27, 0x69, 0x95, 0xc8, 0xe7, 0x79, 0xc7, - 0x89, 0x2a, 0x73, 0x49, 0xcb, 0xf5, 0xc5, 0xbc, - 0x4a, 0xe0, 0x73, 0xa9, 0xbc, 0x88, 0x64, 0x96, - 0x98, 0xa5, 0x1e, 0xe3, 0x43, 0xc1, 0x7d, 0x78, - 0xc7, 0x94, 0x72, 0xd4, 0x2c, 0x6e, 0x85, 0x39, - 0x9a, 0xaf, 0xdb, 0xa1, 0xe9, 0xe2, 0xcb, 0x37, - 0x04, 0xc6, 0x8c, 0x81, 0xd3, 0x2a, 0xb7, 0xbe, - 0x6c, 0x07, 0x1f, 0x5e, 0xd9, 0x00, 0xd2, 0xf7, - 0xe1, 0xa7, 0xbc, 0x0c, 0xb6, 0x6d, 0xfb, 0x3f, - 0x3d, 0x24, 0xaa, 0xfb, 0x7e, 0xe1, 0xb5, 0x1b, - 0xff, 0x38, 0xaa, 0x69, 0x59, 0x38, 0x52, 0x9a, - 0x0e, 0x6d, 0xbc, 0xde, 0x4f, 0x13, 0x09, 0x17, - 0xc4, 0xa9, 0x05, 0x84, 0xbc, 0x50, 0xef, 0x40, - 0xb0, 0x4c, 0x24, 0x32, 0xed, 0x94, 0x2c, 0xdd, - 0xda, 0x20, 0x24, 0x67, 0xe2, 0xea, 0x71, 0x3d, - 0x4a, 0x04, 0x0d, 0x98, 0x29, 0x20, 0x4c, 0xeb, - 0x70, 0xce, 0x45, 0x9e, 0x5a, 0xaf, 0xb6, 0xa3, - 0x92, 0xc8, 0x28, 0xf2, 0xe3, 0xe8, 0x8a, 0x5d, - 0x0a, 0x33, 0x79, 0x9b, 0x6a, 0xf3, 0x30, 0x01, - 0x1d, 0x47, 0xbd, 0x01, 0xcc, 0x4d, 0x71, 0xc0, - 0x56, 0xfa, 0xfd, 0x37, 0xed, 0x0f, 0x27, 0xc0, - 0xbb, 0xa0, 0xee, 0xc3, 0x79, 0x8b, 0xe7, 0x41, - 0x8f, 0xfa, 0x3a, 0xcb, 0x45, 0x3b, 0x85, 0x9f, - 0x06, 0x90, 0xb2, 0x51, 0xc0, 0x48, 0x10, 0xac, - 0x2a, 0xec, 0xec, 0x48, 0x7a, 0x19, 0x47, 0xc4, - 0x2a, 0xeb, 0xb3, 0xa2, 0x07, 0x22, 0x32, 0x78, - 0xf4, 0x73, 0x5e, 0x92, 0x42, 0x15, 0xa1, 0x90, - 0x91, 0xd0, 0xeb, 0x12, 0x14, 0x03, 0x03, 0x00, - 0x01, 0x01, 0x16, 0x03, 0x03, 0x00, 0x24, 0x45, - 0x4b, 0x80, 0x42, 0x46, 0xde, 0xbb, 0xe7, 0x76, - 0xd1, 0x33, 0x92, 0xfc, 0x46, 0x17, 0x6d, 0x21, - 0xf6, 0x0e, 0x16, 0xca, 0x9b, 0x9b, 0x04, 0x65, - 0x16, 0x40, 0x44, 0x64, 0xbc, 0x58, 0xfa, 0x2a, - 0x49, 0xe9, 0xed, 0x17, 0x03, 0x03, 0x00, 0x21, - 0x89, 0x71, 0xcd, 0x56, 0x54, 0xbf, 0x73, 0xde, - 0xfb, 0x4b, 0x4e, 0xf1, 0x7f, 0xc6, 0x75, 0xa6, - 0xbd, 0x6b, 0x6c, 0xd9, 0xdc, 0x0c, 0x71, 0xb4, - 0xb9, 0xbb, 0x6e, 0xfa, 0x9e, 0xc7, 0xc7, 0x4c, - 0x24, 0x15, 0x03, 0x03, 0x00, 0x16, 0x62, 0xea, - 0x65, 0x69, 0x68, 0x4a, 0xce, 0xa7, 0x9e, 0xce, - 0xc0, 0xf1, 0x5c, 0x96, 0xd9, 0x1f, 0x49, 0xac, - 0x2d, 0x05, 0x89, 0x94, - }, -} - -// cert.pem and key.pem were generated with generate_cert.go -// Thus, they have no ExtKeyUsage fields and trigger an error -// when verification is turned on. - -var clientCertificate = loadPEMCert(` ------BEGIN CERTIFICATE----- -MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD -bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4 -MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc -MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG -hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE -ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e -E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw -DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A -p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4 -hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE -GFGNEH5PlGffo05wc46QkYU= ------END CERTIFICATE----- -`) - -/* corresponding key.pem for cert.pem is: ------BEGIN RSA PRIVATE KEY----- -MIICWgIBAAKBgE7QezHjgmTZWcDCh6ReHotzM8djU99mkgaE9mTVj+Q2px0r6LMg -NkUjteOVru3g9SCcjZXff1oS74fkW2jk6Q507ASKf96TJ8QBGXq98tw9FKvQVMoh -DNBNbocuXMXSu01LT862LPd+iOx81wKRdKYeDBra40paLt4TnExAiFmTAgMBAAEC -gYBxvXd8yNteFTns8A/2yomEMC4yeosJJSpp1CsN3BJ7g8/qTnrVPxBy+RU+qr63 -t2WquaOu/cr5P8iEsa6lk20tf8pjKLNXeX0b1RTzK8rJLbS7nGzP3tvOhL096VtQ -dAo4ROEaro0TzYpHmpciSvxVIeEIAAdFDObDJPKqcJAxyQJBAJizfYgK8Gzx9fsx -hxp+VteCbVPg2euASH5Yv3K5LukRdKoSzHE2grUVQgN/LafC0eZibRanxHegYSr7 -7qaswKUCQQCEIWor/X4XTMdVj3Oj+vpiw75y/S9gh682+myZL+d/02IEkwnB098P -RkKVpenBHyrGg0oeN5La7URILWKj7CPXAkBKo6F+d+phNjwIFoN1Xb/RA32w/D1I -saG9sF+UEhRt9AxUfW/U/tIQ9V0ZHHcSg1XaCM5Nvp934brdKdvTOKnJAkBD5h/3 -Rybatlvg/fzBEaJFyq09zhngkxlZOUtBVTqzl17RVvY2orgH02U4HbCHy4phxOn7 -qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN -1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvA ------END RSA PRIVATE KEY----- -*/ - -var clientECDSACertificate = loadPEMCert(` ------BEGIN CERTIFICATE----- -MIIB/DCCAV4CCQCaMIRsJjXZFzAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw -EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 -eSBMdGQwHhcNMTIxMTE0MTMyNTUzWhcNMjIxMTEyMTMyNTUzWjBBMQswCQYDVQQG -EwJBVTEMMAoGA1UECBMDTlNXMRAwDgYDVQQHEwdQeXJtb250MRIwEAYDVQQDEwlK -b2VsIFNpbmcwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACVjJF1FMBexFe01MNv -ja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd3kfDdq0Z9kUs -jLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx+U56jb0JuK7q -ixgnTy5w/hOWusPTQBbNZU6sER7m8TAJBgcqhkjOPQQBA4GMADCBiAJCAOAUxGBg -C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa -2RU6+b0DeoeiIzXsAkIBo9SKeDUcSpoj0gq+KxAxnZxfvuiRs9oa9V2jI/Umi0Vw -jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes= ------END CERTIFICATE----- -`) - -/* corresponding key for cert is: ------BEGIN EC PARAMETERS----- -BgUrgQQAIw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8 -k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1 -FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd -3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx -+U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q== ------END EC PRIVATE KEY----- -*/ -var clientauthECDSATests = []clientauthTest{ - // Server asks for cert with empty CA list, client gives one - // go test -run "TestRunServer" -serve \ - // -clientauth 1 -ciphersuites=0xc00a - // openssl s_client -host 127.0.0.1 -port 10443 \ - // -cipher ECDHE-ECDSA-AES256-SHA -key client.key -cert client.crt - {"RequestClientCert, client gives it", RequestClientCert, []*x509.Certificate{clientECDSACertificate}, [][]byte{ - { - 0x16, 0x03, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, - 0x9c, 0x03, 0x03, 0x51, 0xe5, 0x73, 0xc5, 0xae, - 0x51, 0x94, 0xb4, 0xf2, 0xe8, 0xf6, 0x03, 0x0e, - 0x3b, 0x34, 0xaf, 0xf0, 0xdc, 0x1b, 0xcc, 0xd8, - 0x0c, 0x45, 0x82, 0xd4, 0xd6, 0x76, 0x04, 0x6e, - 0x4f, 0x7a, 0x24, 0x00, 0x00, 0x04, 0xc0, 0x0a, - 0x00, 0xff, 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, - 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, - 0x00, 0x34, 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, - 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, - 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, - 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, - 0x00, 0x15, 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, - 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, - 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, - 0x00, 0x00, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, - 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, - 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, - 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, - 0x00, 0x0f, 0x00, 0x01, 0x01, - }, - { - 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0a, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x02, 0x0e, 0x0b, 0x00, 0x02, 0x0a, 0x00, 0x02, - 0x07, 0x00, 0x02, 0x04, 0x30, 0x82, 0x02, 0x00, - 0x30, 0x82, 0x01, 0x62, 0x02, 0x09, 0x00, 0xb8, - 0xbf, 0x2d, 0x47, 0xa0, 0xd2, 0xeb, 0xf4, 0x30, - 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, - 0x04, 0x01, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x31, - 0x31, 0x32, 0x32, 0x31, 0x35, 0x30, 0x36, 0x33, - 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x31, 0x31, - 0x32, 0x30, 0x31, 0x35, 0x30, 0x36, 0x33, 0x32, - 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, - 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, - 0x30, 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, - 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, - 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, - 0x00, 0x04, 0x00, 0xc4, 0xa1, 0xed, 0xbe, 0x98, - 0xf9, 0x0b, 0x48, 0x73, 0x36, 0x7e, 0xc3, 0x16, - 0x56, 0x11, 0x22, 0xf2, 0x3d, 0x53, 0xc3, 0x3b, - 0x4d, 0x21, 0x3d, 0xcd, 0x6b, 0x75, 0xe6, 0xf6, - 0xb0, 0xdc, 0x9a, 0xdf, 0x26, 0xc1, 0xbc, 0xb2, - 0x87, 0xf0, 0x72, 0x32, 0x7c, 0xb3, 0x64, 0x2f, - 0x1c, 0x90, 0xbc, 0xea, 0x68, 0x23, 0x10, 0x7e, - 0xfe, 0xe3, 0x25, 0xc0, 0x48, 0x3a, 0x69, 0xe0, - 0x28, 0x6d, 0xd3, 0x37, 0x00, 0xef, 0x04, 0x62, - 0xdd, 0x0d, 0xa0, 0x9c, 0x70, 0x62, 0x83, 0xd8, - 0x81, 0xd3, 0x64, 0x31, 0xaa, 0x9e, 0x97, 0x31, - 0xbd, 0x96, 0xb0, 0x68, 0xc0, 0x9b, 0x23, 0xde, - 0x76, 0x64, 0x3f, 0x1a, 0x5c, 0x7f, 0xe9, 0x12, - 0x0e, 0x58, 0x58, 0xb6, 0x5f, 0x70, 0xdd, 0x9b, - 0xd8, 0xea, 0xd5, 0xd7, 0xf5, 0xd5, 0xcc, 0xb9, - 0xb6, 0x9f, 0x30, 0x66, 0x5b, 0x66, 0x9a, 0x20, - 0xe2, 0x27, 0xe5, 0xbf, 0xfe, 0x3b, 0x30, 0x09, - 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, - 0x01, 0x03, 0x81, 0x8c, 0x00, 0x30, 0x81, 0x88, - 0x02, 0x42, 0x01, 0x88, 0xa2, 0x4f, 0xeb, 0xe2, - 0x45, 0xc5, 0x48, 0x7d, 0x1b, 0xac, 0xf5, 0xed, - 0x98, 0x9d, 0xae, 0x47, 0x70, 0xc0, 0x5e, 0x1b, - 0xb6, 0x2f, 0xbd, 0xf1, 0xb6, 0x4d, 0xb7, 0x61, - 0x40, 0xd3, 0x11, 0xa2, 0xce, 0xee, 0x0b, 0x7e, - 0x92, 0x7e, 0xff, 0x76, 0x9d, 0xc3, 0x3b, 0x7e, - 0xa5, 0x3f, 0xce, 0xfa, 0x10, 0xe2, 0x59, 0xec, - 0x47, 0x2d, 0x7c, 0xac, 0xda, 0x4e, 0x97, 0x0e, - 0x15, 0xa0, 0x6f, 0xd0, 0x02, 0x42, 0x01, 0x4d, - 0xfc, 0xbe, 0x67, 0x13, 0x9c, 0x2d, 0x05, 0x0e, - 0xbd, 0x3f, 0xa3, 0x8c, 0x25, 0xc1, 0x33, 0x13, - 0x83, 0x0d, 0x94, 0x06, 0xbb, 0xd4, 0x37, 0x7a, - 0xf6, 0xec, 0x7a, 0xc9, 0x86, 0x2e, 0xdd, 0xd7, - 0x11, 0x69, 0x7f, 0x85, 0x7c, 0x56, 0xde, 0xfb, - 0x31, 0x78, 0x2b, 0xe4, 0xc7, 0x78, 0x0d, 0xae, - 0xcb, 0xbe, 0x9e, 0x4e, 0x36, 0x24, 0x31, 0x7b, - 0x6a, 0x0f, 0x39, 0x95, 0x12, 0x07, 0x8f, 0x2a, - 0x16, 0x03, 0x01, 0x01, 0x1a, 0x0c, 0x00, 0x01, - 0x16, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, - 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, - 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, - 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, - 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, - 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, - 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, - 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, - 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, - 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, - 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, - 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, - 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, - 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, - 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, - 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, - 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, - 0x90, 0x33, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02, - 0x42, 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, - 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, - 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, - 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, - 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, - 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, - 0xff, 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, - 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, - 0xe5, 0xbd, 0x66, 0x02, 0x42, 0x00, 0xad, 0x7d, - 0x06, 0x35, 0xab, 0xec, 0x8d, 0xac, 0xd4, 0xba, - 0x1b, 0x49, 0x5e, 0x05, 0x5f, 0xf0, 0x97, 0x93, - 0x82, 0xb8, 0x2b, 0x8d, 0x91, 0x98, 0x63, 0x8e, - 0xb4, 0x14, 0x62, 0xdb, 0x1e, 0xc9, 0x2b, 0x30, - 0xf8, 0x41, 0x9b, 0xa6, 0xe6, 0xbc, 0xde, 0x0e, - 0x68, 0x30, 0x21, 0xf4, 0xa8, 0xa9, 0x1b, 0xec, - 0x44, 0x4f, 0x5d, 0x02, 0x2f, 0x60, 0x45, 0x60, - 0xba, 0xe0, 0x4e, 0xc0, 0xd4, 0x3b, 0x01, 0x16, - 0x03, 0x01, 0x00, 0x09, 0x0d, 0x00, 0x00, 0x05, - 0x02, 0x01, 0x40, 0x00, 0x00, 0x16, 0x03, 0x01, - 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x01, 0x02, 0x0a, 0x0b, 0x00, 0x02, - 0x06, 0x00, 0x02, 0x03, 0x00, 0x02, 0x00, 0x30, - 0x82, 0x01, 0xfc, 0x30, 0x82, 0x01, 0x5e, 0x02, - 0x09, 0x00, 0x9a, 0x30, 0x84, 0x6c, 0x26, 0x35, - 0xd9, 0x17, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, - 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x32, 0x31, 0x31, 0x31, 0x34, 0x31, 0x33, - 0x32, 0x35, 0x35, 0x33, 0x5a, 0x17, 0x0d, 0x32, - 0x32, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x32, - 0x35, 0x35, 0x33, 0x5a, 0x30, 0x41, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x41, 0x55, 0x31, 0x0c, 0x30, 0x0a, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x03, 0x4e, 0x53, - 0x57, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x04, 0x07, 0x13, 0x07, 0x50, 0x79, 0x72, 0x6d, - 0x6f, 0x6e, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x4a, 0x6f, - 0x65, 0x6c, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x30, - 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, - 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, - 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, 0x00, - 0x04, 0x00, 0x95, 0x8c, 0x91, 0x75, 0x14, 0xc0, - 0x5e, 0xc4, 0x57, 0xb4, 0xd4, 0xc3, 0x6f, 0x8d, - 0xae, 0x68, 0x1e, 0xdd, 0x6f, 0xce, 0x86, 0xe1, - 0x7e, 0x6e, 0xb2, 0x48, 0x3e, 0x81, 0xe5, 0x4e, - 0xe2, 0xc6, 0x88, 0x4b, 0x64, 0xdc, 0xf5, 0x30, - 0xbb, 0xd3, 0xff, 0x65, 0xcc, 0x5b, 0xf4, 0xdd, - 0xb5, 0x6a, 0x3e, 0x3e, 0xd0, 0x1d, 0xde, 0x47, - 0xc3, 0x76, 0xad, 0x19, 0xf6, 0x45, 0x2c, 0x8c, - 0xbc, 0xd8, 0x1d, 0x01, 0x4c, 0x1f, 0x70, 0x90, - 0x46, 0x76, 0x48, 0x8b, 0x8f, 0x83, 0xcc, 0x4a, - 0x5c, 0x8f, 0x40, 0x76, 0xda, 0xe0, 0x89, 0xec, - 0x1d, 0x2b, 0xc4, 0x4e, 0x30, 0x76, 0x28, 0x41, - 0xb2, 0x62, 0xa8, 0xfb, 0x5b, 0xf1, 0xf9, 0x4e, - 0x7a, 0x8d, 0xbd, 0x09, 0xb8, 0xae, 0xea, 0x8b, - 0x18, 0x27, 0x4f, 0x2e, 0x70, 0xfe, 0x13, 0x96, - 0xba, 0xc3, 0xd3, 0x40, 0x16, 0xcd, 0x65, 0x4e, - 0xac, 0x11, 0x1e, 0xe6, 0xf1, 0x30, 0x09, 0x06, - 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, - 0x03, 0x81, 0x8c, 0x00, 0x30, 0x81, 0x88, 0x02, - 0x42, 0x00, 0xe0, 0x14, 0xc4, 0x60, 0x60, 0x0b, - 0x72, 0x68, 0xb0, 0x32, 0x5d, 0x61, 0x4a, 0x02, - 0x74, 0x5c, 0xc2, 0x81, 0xb9, 0x16, 0xa8, 0x3f, - 0x29, 0xc8, 0x36, 0xc7, 0x81, 0xff, 0x6c, 0xb6, - 0x5b, 0xd9, 0x70, 0xf1, 0x38, 0x3b, 0x50, 0x48, - 0x28, 0x94, 0xcb, 0x09, 0x1a, 0x52, 0xf1, 0x5d, - 0xee, 0x8d, 0xf2, 0xb9, 0xf0, 0xf0, 0xda, 0xd9, - 0x15, 0x3a, 0xf9, 0xbd, 0x03, 0x7a, 0x87, 0xa2, - 0x23, 0x35, 0xec, 0x02, 0x42, 0x01, 0xa3, 0xd4, - 0x8a, 0x78, 0x35, 0x1c, 0x4a, 0x9a, 0x23, 0xd2, - 0x0a, 0xbe, 0x2b, 0x10, 0x31, 0x9d, 0x9c, 0x5f, - 0xbe, 0xe8, 0x91, 0xb3, 0xda, 0x1a, 0xf5, 0x5d, - 0xa3, 0x23, 0xf5, 0x26, 0x8b, 0x45, 0x70, 0x8d, - 0x65, 0x62, 0x9b, 0x7e, 0x01, 0x99, 0x3d, 0x18, - 0xf6, 0x10, 0x9a, 0x38, 0x61, 0x9b, 0x2e, 0x57, - 0xe4, 0xfa, 0xcc, 0xb1, 0x8a, 0xce, 0xe2, 0x23, - 0xa0, 0x87, 0xf0, 0xe1, 0x67, 0x51, 0xeb, 0x16, - 0x03, 0x01, 0x00, 0x8a, 0x10, 0x00, 0x00, 0x86, - 0x85, 0x04, 0x00, 0xcd, 0x1c, 0xe8, 0x66, 0x5b, - 0xa8, 0x9d, 0x83, 0x2f, 0x7e, 0x1d, 0x0b, 0x59, - 0x23, 0xbc, 0x30, 0xcf, 0xa3, 0xaf, 0x21, 0xdc, - 0xf2, 0x57, 0x49, 0x56, 0x30, 0x25, 0x7c, 0x84, - 0x5d, 0xad, 0xaa, 0x9c, 0x7b, 0x2a, 0x95, 0x58, - 0x3d, 0x30, 0x87, 0x01, 0x3b, 0xb7, 0xea, 0xcb, - 0xc4, 0xa3, 0xeb, 0x22, 0xbf, 0x2d, 0x61, 0x17, - 0x8c, 0x9b, 0xe8, 0x1b, 0xb2, 0x87, 0x16, 0x78, - 0xd5, 0xfd, 0x8b, 0xdd, 0x00, 0x0f, 0xda, 0x8e, - 0xfd, 0x28, 0x36, 0xeb, 0xe4, 0xc5, 0x42, 0x14, - 0xc7, 0xbd, 0x29, 0x5e, 0x9a, 0xed, 0x5e, 0xc1, - 0xf7, 0xf4, 0xbd, 0xbd, 0x15, 0x9c, 0xe8, 0x44, - 0x71, 0xa7, 0xb6, 0xe9, 0xfa, 0x7e, 0x97, 0xcb, - 0x96, 0x3e, 0x53, 0x76, 0xfb, 0x11, 0x1f, 0x36, - 0x8f, 0x30, 0xfb, 0x71, 0x3a, 0x75, 0x3a, 0x25, - 0x7b, 0xa2, 0xc1, 0xf9, 0x3e, 0x58, 0x5f, 0x07, - 0x16, 0xed, 0xe1, 0xf7, 0xc1, 0xb1, 0x16, 0x03, - 0x01, 0x00, 0x90, 0x0f, 0x00, 0x00, 0x8c, 0x00, - 0x8a, 0x30, 0x81, 0x87, 0x02, 0x42, 0x00, 0xb2, - 0xd3, 0x91, 0xe6, 0xd5, 0x9b, 0xb2, 0xb8, 0x03, - 0xf4, 0x85, 0x4d, 0x43, 0x79, 0x1f, 0xb6, 0x6f, - 0x0c, 0xcd, 0x67, 0x5f, 0x5e, 0xca, 0xee, 0xb3, - 0xe4, 0xab, 0x1e, 0x58, 0xc3, 0x04, 0xa9, 0x8a, - 0xa7, 0xcf, 0xaa, 0x33, 0x88, 0xd5, 0x35, 0xd2, - 0x80, 0x8f, 0xfa, 0x1b, 0x3c, 0x3d, 0xf7, 0x80, - 0x50, 0xde, 0x80, 0x30, 0x64, 0xee, 0xc0, 0xb3, - 0x91, 0x6e, 0x5d, 0x1e, 0xc0, 0xdc, 0x3a, 0x93, - 0x02, 0x41, 0x4e, 0xca, 0x98, 0x41, 0x8c, 0x36, - 0xf2, 0x12, 0xbf, 0x8e, 0x0f, 0x69, 0x8e, 0xf8, - 0x7b, 0x9d, 0xba, 0x9c, 0x5c, 0x48, 0x79, 0xf4, - 0xba, 0x3d, 0x06, 0xa5, 0xab, 0x47, 0xe0, 0x1a, - 0x45, 0x28, 0x3a, 0x8f, 0xbf, 0x14, 0x24, 0x36, - 0xd1, 0x1d, 0x29, 0xdc, 0xde, 0x72, 0x5b, 0x76, - 0x41, 0x67, 0xe8, 0xe5, 0x71, 0x4a, 0x77, 0xe9, - 0xed, 0x02, 0x19, 0xdd, 0xe4, 0xaa, 0xe9, 0x2d, - 0xe7, 0x47, 0x32, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xfa, 0xc3, - 0xf2, 0x35, 0xd0, 0x6d, 0x32, 0x78, 0x6a, 0xd6, - 0xe6, 0x70, 0x5e, 0x00, 0x4c, 0x35, 0xf1, 0xe0, - 0x21, 0xcf, 0xc3, 0x78, 0xcd, 0xe0, 0x2b, 0x0b, - 0xf4, 0xeb, 0xf9, 0xc0, 0x38, 0xf2, 0x9a, 0x31, - 0x55, 0x07, 0x2b, 0x8d, 0x68, 0x40, 0x31, 0x08, - 0xaa, 0xe3, 0x16, 0xcf, 0x4b, 0xd4, - }, - { - 0x16, 0x03, 0x01, 0x02, 0x76, 0x04, 0x00, 0x02, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xe8, 0x8b, 0xde, 0xef, 0xba, 0xf9, 0xdb, 0x95, - 0x24, 0xa5, 0x49, 0xb3, 0x23, 0xd8, 0x73, 0x88, - 0x50, 0x42, 0xed, 0xeb, 0xa3, 0xd8, 0xab, 0x31, - 0x9c, 0xd0, 0x00, 0x01, 0xef, 0xc0, 0xbf, 0xab, - 0x59, 0x55, 0xb5, 0xb9, 0xef, 0xa5, 0xa6, 0xec, - 0x69, 0xed, 0x00, 0x2f, 0x47, 0xdb, 0x75, 0x52, - 0x0c, 0xe5, 0x86, 0xb7, 0x02, 0x59, 0x22, 0xf7, - 0xfd, 0x8b, 0xff, 0xa4, 0x09, 0xc0, 0x1c, 0x10, - 0x80, 0x10, 0x7f, 0x4c, 0x7a, 0x94, 0x40, 0x10, - 0x0d, 0xda, 0x8a, 0xe5, 0x4a, 0xbc, 0xd0, 0xc0, - 0x4b, 0xa5, 0x33, 0x97, 0xc6, 0xe7, 0x40, 0x7f, - 0x7f, 0x8c, 0xf9, 0xf8, 0xc8, 0xb8, 0xfb, 0x8c, - 0xdd, 0x28, 0x81, 0xae, 0xfd, 0x37, 0x20, 0x3a, - 0x40, 0x37, 0x99, 0xc4, 0x21, 0x01, 0xc4, 0x91, - 0xb0, 0x5e, 0x11, 0xc5, 0xa9, 0xfd, 0x9a, 0x02, - 0x7e, 0x97, 0x6a, 0x86, 0x89, 0xb8, 0xc1, 0x32, - 0x4c, 0x7e, 0x6d, 0x47, 0x61, 0x0e, 0xe3, 0xc2, - 0xf0, 0x62, 0x3c, 0xc6, 0x71, 0x4f, 0xbb, 0x47, - 0x65, 0xb1, 0xd9, 0x22, 0x79, 0x15, 0xea, 0x1f, - 0x4b, 0x2a, 0x8a, 0xa4, 0xc8, 0x73, 0x34, 0xba, - 0x83, 0xe4, 0x70, 0x99, 0xc9, 0xcf, 0xbe, 0x64, - 0x99, 0xb9, 0xfa, 0xe9, 0xaf, 0x5d, 0xc7, 0x20, - 0x26, 0xde, 0xc5, 0x06, 0x12, 0x36, 0x4f, 0x4d, - 0xc0, 0xbb, 0x81, 0x5b, 0x5e, 0x38, 0xc3, 0x07, - 0x21, 0x04, 0x1a, 0x53, 0x9c, 0x59, 0xac, 0x2d, - 0xe6, 0xa5, 0x93, 0xa5, 0x19, 0xc6, 0xb0, 0xf7, - 0x56, 0x5d, 0xdf, 0xd1, 0xf4, 0xfd, 0x44, 0x6d, - 0xc6, 0xa2, 0x31, 0xa7, 0x35, 0x42, 0x18, 0x50, - 0x0c, 0x4f, 0x6e, 0xe3, 0x3b, 0xa3, 0xaa, 0x1c, - 0xbe, 0x41, 0x0d, 0xce, 0x6c, 0x62, 0xe1, 0x96, - 0x2d, 0xbd, 0x14, 0x31, 0xe3, 0xc4, 0x5b, 0xbf, - 0xf6, 0xde, 0xec, 0x42, 0xe8, 0xc7, 0x2a, 0x0b, - 0xdb, 0x2d, 0x7c, 0xf0, 0x3f, 0x45, 0x32, 0x45, - 0x09, 0x47, 0x09, 0x0f, 0x21, 0x22, 0x45, 0x06, - 0x11, 0xb8, 0xf9, 0xe6, 0x67, 0x90, 0x4b, 0x4a, - 0xde, 0x81, 0xfb, 0xeb, 0xe7, 0x9a, 0x08, 0x30, - 0xcf, 0x51, 0xe1, 0xd9, 0xfa, 0x79, 0xa3, 0xcc, - 0x65, 0x1a, 0x83, 0x86, 0xc9, 0x7a, 0x41, 0xf5, - 0xdf, 0xa0, 0x7c, 0x44, 0x23, 0x17, 0xf3, 0x62, - 0xe8, 0xa9, 0x31, 0x1e, 0x6b, 0x05, 0x4b, 0x4f, - 0x9d, 0x91, 0x46, 0x92, 0xa6, 0x25, 0x32, 0xca, - 0xa1, 0x75, 0xda, 0xe6, 0x80, 0x3e, 0x7f, 0xd1, - 0x26, 0x57, 0x07, 0x42, 0xe4, 0x91, 0xff, 0xbd, - 0x44, 0xae, 0x98, 0x5c, 0x1d, 0xdf, 0x11, 0xe3, - 0xae, 0x87, 0x5e, 0xb7, 0x69, 0xad, 0x34, 0x7f, - 0x3a, 0x07, 0x7c, 0xdf, 0xfc, 0x76, 0x17, 0x8b, - 0x62, 0xc8, 0xe1, 0x78, 0x2a, 0xc8, 0xb9, 0x8a, - 0xbb, 0x5c, 0xfb, 0x38, 0x74, 0x91, 0x6e, 0x12, - 0x0c, 0x1f, 0x8e, 0xe1, 0xc2, 0x01, 0xd8, 0x9d, - 0x23, 0x0f, 0xc4, 0x67, 0x5d, 0xe5, 0x67, 0x4b, - 0x94, 0x6e, 0x69, 0x72, 0x90, 0x2d, 0x52, 0x78, - 0x8e, 0x61, 0xba, 0xdf, 0x4e, 0xf5, 0xdc, 0xfb, - 0x73, 0xbe, 0x03, 0x70, 0xd9, 0x01, 0x30, 0xf3, - 0xa1, 0xbb, 0x9a, 0x5f, 0xec, 0x9e, 0xed, 0x8d, - 0xdd, 0x53, 0xfd, 0x60, 0xc3, 0x2b, 0x7a, 0x00, - 0x2c, 0xf9, 0x0a, 0x57, 0x47, 0x45, 0x43, 0xb3, - 0x23, 0x01, 0x9c, 0xee, 0x54, 0x4d, 0x58, 0xd3, - 0x71, 0x1c, 0xc9, 0xd3, 0x30, 0x9e, 0x14, 0xa5, - 0xf3, 0xbf, 0x4d, 0x9b, 0xb7, 0x13, 0x21, 0xae, - 0xd2, 0x8d, 0x6e, 0x6f, 0x1c, 0xcc, 0xb2, 0x41, - 0xb2, 0x64, 0x56, 0x83, 0xce, 0xd1, 0x0c, 0x79, - 0x32, 0x78, 0xef, 0xc5, 0x21, 0xb1, 0xe8, 0xc4, - 0x42, 0xa7, 0x8d, 0xc1, 0xfa, 0xa1, 0x9c, 0x3c, - 0x21, 0xd8, 0xe9, 0x90, 0xe2, 0x7c, 0x14, 0x26, - 0xfe, 0x61, 0x3e, 0xf9, 0x71, 0x1d, 0x5d, 0x49, - 0x3b, 0xb1, 0xb8, 0x42, 0xa1, 0xb8, 0x1c, 0x75, - 0x7d, 0xee, 0xed, 0xfc, 0xe6, 0x20, 0x2b, 0x9e, - 0x10, 0x52, 0xda, 0x56, 0x4d, 0x64, 0x6c, 0x41, - 0xc1, 0xf7, 0x60, 0x0c, 0x10, 0x65, 0x6f, 0xd4, - 0xe9, 0x9b, 0x0d, 0x83, 0x13, 0xc8, 0x5a, 0xa3, - 0x56, 0x2a, 0x42, 0xc6, 0x1c, 0xfe, 0xdb, 0xba, - 0x3d, 0x04, 0x12, 0xfd, 0x28, 0xeb, 0x78, 0xdd, - 0xbc, 0xc8, 0x0d, 0xa1, 0xce, 0xd4, 0x54, 0xbf, - 0xaf, 0xe1, 0x60, 0x0c, 0xa3, 0xc3, 0xc3, 0x62, - 0x58, 0xc1, 0x79, 0xa7, 0x95, 0x41, 0x09, 0x24, - 0xc6, 0x9a, 0x50, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x4d, 0x7b, - 0x5f, 0x28, 0x5e, 0x68, 0x6c, 0xa3, 0x65, 0xc7, - 0x7e, 0x49, 0x6c, 0xb3, 0x67, 0xbb, 0xd0, 0x75, - 0xa2, 0x9e, 0x8c, 0x92, 0x4f, 0x8c, 0x33, 0x14, - 0x7c, 0x6c, 0xf1, 0x74, 0x97, 0xc3, 0xe0, 0x10, - 0xe9, 0x0d, 0xc2, 0x30, 0x5c, 0x23, 0xee, 0x1d, - 0x16, 0x2e, 0xb9, 0x96, 0x2b, 0x2d, 0x17, 0x03, - 0x01, 0x00, 0x20, 0xf2, 0xc8, 0xa7, 0x1b, 0x60, - 0x46, 0xee, 0xe5, 0x7e, 0xc9, 0x35, 0xb3, 0xf1, - 0x7c, 0x32, 0x0c, 0x85, 0x94, 0x59, 0x57, 0x27, - 0xb0, 0xbd, 0x52, 0x86, 0x90, 0xf1, 0xb7, 0x4d, - 0x1e, 0xc1, 0x16, 0x17, 0x03, 0x01, 0x00, 0x30, - 0xff, 0x85, 0x50, 0xdf, 0x3f, 0xfc, 0xa2, 0x61, - 0x1a, 0x12, 0xc0, 0x1e, 0x10, 0x32, 0x88, 0x50, - 0xa0, 0x2c, 0x80, 0xda, 0x77, 0xea, 0x09, 0x47, - 0xe0, 0x85, 0x07, 0x29, 0x45, 0x65, 0x19, 0xa3, - 0x8d, 0x99, 0xb8, 0xbf, 0xb6, 0xbc, 0x76, 0xe2, - 0x50, 0x24, 0x82, 0x0a, 0xfd, 0xdd, 0x35, 0x09, - 0x15, 0x03, 0x01, 0x00, 0x20, 0xe7, 0x36, 0xf6, - 0x61, 0xd2, 0x95, 0x3c, 0xb6, 0x65, 0x7b, 0xb2, - 0xb8, 0xdf, 0x03, 0x53, 0xeb, 0xf7, 0x16, 0xe0, - 0xe0, 0x15, 0x22, 0x71, 0x70, 0x62, 0x73, 0xad, - 0xb5, 0x1a, 0x77, 0x44, 0x57, - }, - }}, -} - -var aesGCMServerScript = [][]byte{ - { - 0x16, 0x03, 0x01, 0x01, 0x1c, 0x01, 0x00, 0x01, - 0x18, 0x03, 0x03, 0x52, 0x1e, 0x74, 0xf0, 0xb0, - 0xc1, 0x8b, 0x16, 0xf9, 0x74, 0xfc, 0x16, 0xc4, - 0x11, 0x18, 0x96, 0x08, 0x25, 0x38, 0x4f, 0x98, - 0x98, 0xbe, 0xb5, 0x61, 0xdf, 0x94, 0x15, 0xcc, - 0x9b, 0x61, 0xef, 0x00, 0x00, 0x80, 0xc0, 0x30, - 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, - 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, - 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, - 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, - 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, - 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, - 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, - 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, - 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, - 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, - 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, - 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, - 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x01, 0x00, - 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, - 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, - 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, - 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, - 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, - 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, - 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, 0x06, 0x02, - 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, - 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x03, 0x01, - 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, - 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, 0x00, 0x01, - 0x01, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x2c, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x2f, 0x00, 0x00, - 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x03, - 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, - 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, - 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, - 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, - 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, - 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, - 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, - 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, - 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, - 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, - 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, - 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, - 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, - 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, - 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, - 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, - 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, - 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, - 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, - 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, - 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, - 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, - 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, - 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, - 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, - 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, - 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, - 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, - 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, - 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, - 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, - 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, - 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, - 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, - 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, - 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, - 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, - 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, - 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, - 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, - 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, - 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, - 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, - 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, - 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, - 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, - 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, - 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, - 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, - 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, - 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, - 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, - 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, - 0x16, 0x03, 0x03, 0x01, 0x11, 0x0c, 0x00, 0x01, - 0x0d, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, - 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, - 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, - 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, - 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, - 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, - 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, - 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, - 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, - 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, - 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, - 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, - 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, - 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, - 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, - 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, - 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, - 0x90, 0x33, 0x04, 0x01, 0x00, 0x80, 0x0d, 0x8e, - 0x79, 0xe6, 0x86, 0xf6, 0xb6, 0xfb, 0x6b, 0x6a, - 0xcc, 0x55, 0xe4, 0x80, 0x4d, 0xc5, 0x0c, 0xc6, - 0xa3, 0x9f, 0x1d, 0x39, 0xd2, 0x98, 0x57, 0x31, - 0xa2, 0x90, 0x73, 0xe8, 0xd2, 0xcd, 0xb0, 0x93, - 0x1a, 0x60, 0x0f, 0x38, 0x02, 0x3b, 0x1b, 0x25, - 0x56, 0xec, 0x44, 0xab, 0xbe, 0x2e, 0x0c, 0xc0, - 0x6e, 0x54, 0x91, 0x50, 0xd6, 0xb1, 0xa2, 0x98, - 0x14, 0xa8, 0x35, 0x62, 0x9d, 0xca, 0xfb, 0x0f, - 0x64, 0x2b, 0x05, 0xa0, 0xa0, 0x57, 0xef, 0xcd, - 0x95, 0x45, 0x13, 0x5a, 0x9b, 0x3d, 0xdb, 0x42, - 0x54, 0x7f, 0xb9, 0x17, 0x08, 0x7f, 0xb2, 0xf0, - 0xb1, 0xc3, 0xdf, 0x67, 0x95, 0xe2, 0x73, 0xf2, - 0x76, 0xa3, 0x97, 0xfd, 0x9c, 0x92, 0x4a, 0xdb, - 0x95, 0x1e, 0x91, 0x95, 0xae, 0x3d, 0xae, 0x58, - 0xb5, 0x03, 0x6f, 0x5c, 0x3a, 0x19, 0xab, 0x92, - 0xa5, 0x09, 0x6b, 0x40, 0x61, 0xb0, 0x16, 0x03, - 0x03, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x8a, 0x10, 0x00, 0x00, - 0x86, 0x85, 0x04, 0x01, 0xba, 0xb8, 0xad, 0x69, - 0x20, 0x5e, 0xc1, 0x61, 0xc3, 0x0f, 0xb4, 0x30, - 0x64, 0x66, 0x70, 0x96, 0x33, 0x3c, 0x8e, 0x12, - 0x56, 0xbf, 0x6d, 0xb8, 0x6d, 0xc6, 0xba, 0xea, - 0xfc, 0x38, 0xc0, 0x8b, 0x87, 0xa8, 0xf3, 0x87, - 0xa1, 0xd5, 0xb6, 0xb0, 0x72, 0xc7, 0xd4, 0x19, - 0x56, 0xa0, 0x91, 0xe1, 0x45, 0xc7, 0xf1, 0x7d, - 0xb0, 0x1d, 0x78, 0x18, 0xf6, 0x3d, 0xbf, 0x1a, - 0x23, 0x93, 0x0b, 0x19, 0xb1, 0x00, 0x56, 0xc9, - 0x5e, 0x89, 0xd4, 0x9d, 0xd9, 0x5b, 0xe0, 0xb8, - 0xff, 0x2f, 0x7d, 0x93, 0xae, 0x5b, 0xa5, 0x1f, - 0x1f, 0x2b, 0x09, 0xe5, 0xf6, 0x07, 0x26, 0xa3, - 0xed, 0xcb, 0x6a, 0x1a, 0xd6, 0x14, 0x83, 0x9b, - 0xd3, 0x9d, 0x47, 0x1b, 0xf3, 0x72, 0x5f, 0x69, - 0x21, 0x8f, 0xfa, 0x09, 0x38, 0x1a, 0x6b, 0x91, - 0xcf, 0x19, 0x32, 0x54, 0x58, 0x8e, 0xee, 0xaf, - 0xeb, 0x06, 0x9b, 0x3a, 0x34, 0x16, 0x66, 0x14, - 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, 0x03, - 0x00, 0x28, 0xc6, 0x96, 0x67, 0x62, 0xcc, 0x47, - 0x01, 0xb5, 0xbd, 0xb7, 0x24, 0xd3, 0xb6, 0xfd, - 0xb8, 0x46, 0xce, 0x82, 0x6d, 0x31, 0x1f, 0x15, - 0x11, 0x8f, 0xed, 0x62, 0x71, 0x5f, 0xae, 0xb6, - 0xa9, 0x0c, 0x24, 0x1d, 0xe8, 0x26, 0x51, 0xca, - 0x7c, 0x42, - }, - { - 0x16, 0x03, 0x03, 0x00, 0x72, 0x04, 0x00, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xea, 0x8b, 0xfb, 0xef, 0xba, 0xc8, 0x88, 0x94, - 0x44, 0x99, 0x5f, 0x02, 0x68, 0x3a, 0x12, 0x67, - 0x7f, 0xb9, 0x39, 0x71, 0x84, 0xe0, 0x30, 0xe6, - 0x90, 0x6c, 0xcf, 0x32, 0x29, 0x29, 0x5c, 0x5a, - 0x8b, 0x7d, 0xaa, 0x11, 0x28, 0x26, 0xb5, 0xce, - 0xd2, 0x88, 0xd5, 0xb0, 0x5f, 0x94, 0x37, 0xa2, - 0x48, 0xd9, 0x53, 0xb2, 0xab, 0x59, 0x23, 0x3d, - 0x81, 0x6e, 0x64, 0x89, 0xca, 0x1a, 0x84, 0x16, - 0xdf, 0x31, 0x10, 0xde, 0x52, 0x7f, 0x50, 0xf3, - 0xd9, 0x27, 0xa0, 0xe8, 0x34, 0x15, 0x9e, 0x11, - 0xdd, 0xba, 0xce, 0x40, 0x17, 0xf3, 0x67, 0x14, - 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, 0x03, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x35, 0xcb, 0x17, 0x66, 0xee, 0xfd, - 0x27, 0xdb, 0xb8, 0xa8, 0x8a, 0xf1, 0x56, 0x67, - 0x89, 0x0d, 0x13, 0xac, 0xe2, 0x31, 0xb9, 0xa2, - 0x26, 0xbb, 0x1c, 0xcf, 0xd1, 0xb2, 0x48, 0x1d, - 0x0d, 0xb1, 0x17, 0x03, 0x03, 0x00, 0x25, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, - 0x89, 0x7c, 0x58, 0x6a, 0x9b, 0x00, 0x05, 0x8c, - 0x7f, 0x28, 0x54, 0x61, 0x44, 0x10, 0xee, 0x85, - 0x26, 0xa8, 0x04, 0xcd, 0xca, 0x85, 0x60, 0xf2, - 0xeb, 0x22, 0xbd, 0x9e, 0x15, 0x03, 0x03, 0x00, - 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x10, 0xe4, 0xe5, 0xf9, 0x85, 0xe3, 0xb0, - 0xec, 0x84, 0x29, 0x91, 0x05, 0x7d, 0x86, 0xe3, - 0x97, 0xeb, 0xb2, - }, -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/key_agreement.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/key_agreement.go deleted file mode 100644 index 7e820c1e7e..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/key_agreement.go +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/md5" - "crypto/rsa" - "crypto/sha1" - "crypto/sha256" - "crypto/x509" - "encoding/asn1" - "errors" - "io" - "math/big" -) - -// rsaKeyAgreement implements the standard TLS key agreement where the client -// encrypts the pre-master secret to the server's public key. -type rsaKeyAgreement struct{} - -func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - return nil, nil -} - -func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - preMasterSecret := make([]byte, 48) - _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) - if err != nil { - return nil, err - } - - if len(ckx.ciphertext) < 2 { - return nil, errors.New("bad ClientKeyExchange") - } - - ciphertext := ckx.ciphertext - if version != VersionSSL30 { - ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) - if ciphertextLen != len(ckx.ciphertext)-2 { - return nil, errors.New("bad ClientKeyExchange") - } - ciphertext = ckx.ciphertext[2:] - } - - err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret) - if err != nil { - return nil, err - } - // We don't check the version number in the premaster secret. For one, - // by checking it, we would leak information about the validity of the - // encrypted pre-master secret. Secondly, it provides only a small - // benefit against a downgrade attack and some implementations send the - // wrong version anyway. See the discussion at the end of section - // 7.4.7.1 of RFC 4346. - return preMasterSecret, nil -} - -func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - return errors.New("unexpected ServerKeyExchange") -} - -func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - preMasterSecret := make([]byte, 48) - preMasterSecret[0] = byte(clientHello.vers >> 8) - preMasterSecret[1] = byte(clientHello.vers) - _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) - if err != nil { - return nil, nil, err - } - - encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret) - if err != nil { - return nil, nil, err - } - ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, len(encrypted)+2) - ckx.ciphertext[0] = byte(len(encrypted) >> 8) - ckx.ciphertext[1] = byte(len(encrypted)) - copy(ckx.ciphertext[2:], encrypted) - return preMasterSecret, ckx, nil -} - -// sha1Hash calculates a SHA1 hash over the given byte slices. -func sha1Hash(slices [][]byte) []byte { - hsha1 := sha1.New() - for _, slice := range slices { - hsha1.Write(slice) - } - return hsha1.Sum(nil) -} - -// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the -// concatenation of an MD5 and SHA1 hash. -func md5SHA1Hash(slices [][]byte) []byte { - md5sha1 := make([]byte, md5.Size+sha1.Size) - hmd5 := md5.New() - for _, slice := range slices { - hmd5.Write(slice) - } - copy(md5sha1, hmd5.Sum(nil)) - copy(md5sha1[md5.Size:], sha1Hash(slices)) - return md5sha1 -} - -// sha256Hash implements TLS 1.2's hash function. -func sha256Hash(slices [][]byte) []byte { - h := sha256.New() - for _, slice := range slices { - h.Write(slice) - } - return h.Sum(nil) -} - -// hashForServerKeyExchange hashes the given slices and returns their digest -// and the identifier of the hash function used. The hashFunc argument is only -// used for >= TLS 1.2 and precisely identifies the hash function to use. -func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) { - if version >= VersionTLS12 { - switch hashFunc { - case hashSHA256: - return sha256Hash(slices), crypto.SHA256, nil - case hashSHA1: - return sha1Hash(slices), crypto.SHA1, nil - default: - return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer") - } - } - if sigType == signatureECDSA { - return sha1Hash(slices), crypto.SHA1, nil - } - return md5SHA1Hash(slices), crypto.MD5SHA1, nil -} - -// pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a -// ServerKeyExchange given the signature type being used and the client's -// advertized list of supported signature and hash combinations. -func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) { - if len(clientSignatureAndHashes) == 0 { - // If the client didn't specify any signature_algorithms - // extension then we can assume that it supports SHA1. See - // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - return hashSHA1, nil - } - - for _, sigAndHash := range clientSignatureAndHashes { - if sigAndHash.signature != sigType { - continue - } - switch sigAndHash.hash { - case hashSHA1, hashSHA256: - return sigAndHash.hash, nil - } - } - - return 0, errors.New("tls: client doesn't support any common hash functions") -} - -// ecdheRSAKeyAgreement implements a TLS key agreement where the server -// generates a ephemeral EC public/private key pair and signs it. The -// pre-master secret is then calculated using ECDH. The signature may -// either be ECDSA or RSA. -type ecdheKeyAgreement struct { - version uint16 - sigType uint8 - privateKey []byte - curve elliptic.Curve - x, y *big.Int -} - -func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - var curveid uint16 - -Curve: - for _, c := range clientHello.supportedCurves { - switch c { - case curveP256: - ka.curve = elliptic.P256() - curveid = c - break Curve - case curveP384: - ka.curve = elliptic.P384() - curveid = c - break Curve - case curveP521: - ka.curve = elliptic.P521() - curveid = c - break Curve - } - } - - if curveid == 0 { - return nil, errors.New("tls: no supported elliptic curves offered") - } - - var x, y *big.Int - var err error - ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand()) - if err != nil { - return nil, err - } - ecdhePublic := elliptic.Marshal(ka.curve, x, y) - - // http://tools.ietf.org/html/rfc4492#section-5.4 - serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) - serverECDHParams[0] = 3 // named curve - serverECDHParams[1] = byte(curveid >> 8) - serverECDHParams[2] = byte(curveid) - serverECDHParams[3] = byte(len(ecdhePublic)) - copy(serverECDHParams[4:], ecdhePublic) - - var tls12HashId uint8 - if ka.version >= VersionTLS12 { - if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil { - return nil, err - } - } - - digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams) - if err != nil { - return nil, err - } - var sig []byte - switch ka.sigType { - case signatureECDSA: - privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey) - if !ok { - return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key") - } - r, s, err := ecdsa.Sign(config.rand(), privKey, digest) - if err != nil { - return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) - } - sig, err = asn1.Marshal(ecdsaSignature{r, s}) - case signatureRSA: - privKey, ok := cert.PrivateKey.(*rsa.PrivateKey) - if !ok { - return nil, errors.New("ECDHE RSA requires a RSA server private key") - } - sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest) - if err != nil { - return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) - } - default: - return nil, errors.New("unknown ECDHE signature algorithm") - } - - skx := new(serverKeyExchangeMsg) - sigAndHashLen := 0 - if ka.version >= VersionTLS12 { - sigAndHashLen = 2 - } - skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig)) - copy(skx.key, serverECDHParams) - k := skx.key[len(serverECDHParams):] - if ka.version >= VersionTLS12 { - k[0] = tls12HashId - k[1] = ka.sigType - k = k[2:] - } - k[0] = byte(len(sig) >> 8) - k[1] = byte(len(sig)) - copy(k[2:], sig) - - return skx, nil -} - -func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { - return nil, errors.New("bad ClientKeyExchange") - } - x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:]) - if x == nil { - return nil, errors.New("bad ClientKeyExchange") - } - x, _ = ka.curve.ScalarMult(x, y, ka.privateKey) - preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) - xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - return preMasterSecret, nil -} - -var errServerKeyExchange = errors.New("invalid ServerKeyExchange") - -func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - if len(skx.key) < 4 { - return errServerKeyExchange - } - if skx.key[0] != 3 { // named curve - return errors.New("server selected unsupported curve") - } - curveid := uint16(skx.key[1])<<8 | uint16(skx.key[2]) - - switch curveid { - case curveP256: - ka.curve = elliptic.P256() - case curveP384: - ka.curve = elliptic.P384() - case curveP521: - ka.curve = elliptic.P521() - default: - return errors.New("server selected unsupported curve") - } - - publicLen := int(skx.key[3]) - if publicLen+4 > len(skx.key) { - return errServerKeyExchange - } - ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen]) - if ka.x == nil { - return errServerKeyExchange - } - serverECDHParams := skx.key[:4+publicLen] - - sig := skx.key[4+publicLen:] - if len(sig) < 2 { - return errServerKeyExchange - } - - var tls12HashId uint8 - if ka.version >= VersionTLS12 { - // handle SignatureAndHashAlgorithm - var sigAndHash []uint8 - sigAndHash, sig = sig[:2], sig[2:] - if sigAndHash[1] != ka.sigType { - return errServerKeyExchange - } - tls12HashId = sigAndHash[0] - if len(sig) < 2 { - return errServerKeyExchange - } - } - sigLen := int(sig[0])<<8 | int(sig[1]) - if sigLen+2 != len(sig) { - return errServerKeyExchange - } - sig = sig[2:] - - digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams) - if err != nil { - return err - } - switch ka.sigType { - case signatureECDSA: - pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey) - if !ok { - return errors.New("ECDHE ECDSA requires a ECDSA server public key") - } - ecdsaSig := new(ecdsaSignature) - if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { - return err - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("ECDSA signature contained zero or negative values") - } - if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { - return errors.New("ECDSA verification failure") - } - case signatureRSA: - pubKey, ok := cert.PublicKey.(*rsa.PublicKey) - if !ok { - return errors.New("ECDHE RSA requires a RSA server public key") - } - if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { - return err - } - default: - return errors.New("unknown ECDHE signature algorithm") - } - - return nil -} - -func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - if ka.curve == nil { - return nil, nil, errors.New("missing ServerKeyExchange message") - } - priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand()) - if err != nil { - return nil, nil, err - } - x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv) - preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) - xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - serialized := elliptic.Marshal(ka.curve, mx, my) - - ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, 1+len(serialized)) - ckx.ciphertext[0] = byte(len(serialized)) - copy(ckx.ciphertext[1:], serialized) - - return preMasterSecret, ckx, nil -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/prf.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/prf.go deleted file mode 100644 index fb8b3ab4d1..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/prf.go +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "crypto" - "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "hash" -) - -// Split a premaster secret in two as specified in RFC 4346, section 5. -func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { - s1 = secret[0 : (len(secret)+1)/2] - s2 = secret[len(secret)/2:] - return -} - -// pHash implements the P_hash function, as defined in RFC 4346, section 5. -func pHash(result, secret, seed []byte, hash func() hash.Hash) { - h := hmac.New(hash, secret) - h.Write(seed) - a := h.Sum(nil) - - j := 0 - for j < len(result) { - h.Reset() - h.Write(a) - h.Write(seed) - b := h.Sum(nil) - todo := len(b) - if j+todo > len(result) { - todo = len(result) - j - } - copy(result[j:j+todo], b) - j += todo - - h.Reset() - h.Write(a) - a = h.Sum(nil) - } -} - -// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5. -func prf10(result, secret, label, seed []byte) { - hashSHA1 := sha1.New - hashMD5 := md5.New - - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - s1, s2 := splitPreMasterSecret(secret) - pHash(result, s1, labelAndSeed, hashMD5) - result2 := make([]byte, len(result)) - pHash(result2, s2, labelAndSeed, hashSHA1) - - for i, b := range result2 { - result[i] ^= b - } -} - -// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5. -func prf12(result, secret, label, seed []byte) { - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - pHash(result, secret, labelAndSeed, sha256.New) -} - -// prf30 implements the SSL 3.0 pseudo-random function, as defined in -// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6. -func prf30(result, secret, label, seed []byte) { - hashSHA1 := sha1.New() - hashMD5 := md5.New() - - done := 0 - i := 0 - // RFC5246 section 6.3 says that the largest PRF output needed is 128 - // bytes. Since no more ciphersuites will be added to SSLv3, this will - // remain true. Each iteration gives us 16 bytes so 10 iterations will - // be sufficient. - var b [11]byte - for done < len(result) { - for j := 0; j <= i; j++ { - b[j] = 'A' + byte(i) - } - - hashSHA1.Reset() - hashSHA1.Write(b[:i+1]) - hashSHA1.Write(secret) - hashSHA1.Write(seed) - digest := hashSHA1.Sum(nil) - - hashMD5.Reset() - hashMD5.Write(secret) - hashMD5.Write(digest) - - done += copy(result[done:], hashMD5.Sum(nil)) - i++ - } -} - -const ( - tlsRandomLength = 32 // Length of a random nonce in TLS 1.1. - masterSecretLength = 48 // Length of a master secret in TLS 1.1. - finishedVerifyLength = 12 // Length of verify_data in a Finished message. -) - -var masterSecretLabel = []byte("master secret") -var keyExpansionLabel = []byte("key expansion") -var clientFinishedLabel = []byte("client finished") -var serverFinishedLabel = []byte("server finished") - -func prfForVersion(version uint16) func(result, secret, label, seed []byte) { - switch version { - case VersionSSL30: - return prf30 - case VersionTLS10, VersionTLS11: - return prf10 - case VersionTLS12: - return prf12 - default: - panic("unknown version") - } -} - -// masterFromPreMasterSecret generates the master secret from the pre-master -// secret. See http://tools.ietf.org/html/rfc5246#section-8.1 -func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte) []byte { - var seed [tlsRandomLength * 2]byte - copy(seed[0:len(clientRandom)], clientRandom) - copy(seed[len(clientRandom):], serverRandom) - masterSecret := make([]byte, masterSecretLength) - prfForVersion(version)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) - return masterSecret -} - -// keysFromMasterSecret generates the connection keys from the master -// secret, given the lengths of the MAC key, cipher key and IV, as defined in -// RFC 2246, section 6.3. -func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { - var seed [tlsRandomLength * 2]byte - copy(seed[0:len(clientRandom)], serverRandom) - copy(seed[len(serverRandom):], clientRandom) - - n := 2*macLen + 2*keyLen + 2*ivLen - keyMaterial := make([]byte, n) - prfForVersion(version)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) - clientMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - serverMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - clientKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - serverKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - clientIV = keyMaterial[:ivLen] - keyMaterial = keyMaterial[ivLen:] - serverIV = keyMaterial[:ivLen] - return -} - -func newFinishedHash(version uint16) finishedHash { - if version >= VersionTLS12 { - return finishedHash{sha256.New(), sha256.New(), nil, nil, version} - } - return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version} -} - -// A finishedHash calculates the hash of a set of handshake messages suitable -// for including in a Finished message. -type finishedHash struct { - client hash.Hash - server hash.Hash - - // Prior to TLS 1.2, an additional MD5 hash is required. - clientMD5 hash.Hash - serverMD5 hash.Hash - - version uint16 -} - -func (h finishedHash) Write(msg []byte) (n int, err error) { - h.client.Write(msg) - h.server.Write(msg) - - if h.version < VersionTLS12 { - h.clientMD5.Write(msg) - h.serverMD5.Write(msg) - } - return len(msg), nil -} - -// finishedSum30 calculates the contents of the verify_data member of a SSLv3 -// Finished message given the MD5 and SHA1 hashes of a set of handshake -// messages. -func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte { - md5.Write(magic[:]) - md5.Write(masterSecret) - md5.Write(ssl30Pad1[:]) - md5Digest := md5.Sum(nil) - - md5.Reset() - md5.Write(masterSecret) - md5.Write(ssl30Pad2[:]) - md5.Write(md5Digest) - md5Digest = md5.Sum(nil) - - sha1.Write(magic[:]) - sha1.Write(masterSecret) - sha1.Write(ssl30Pad1[:40]) - sha1Digest := sha1.Sum(nil) - - sha1.Reset() - sha1.Write(masterSecret) - sha1.Write(ssl30Pad2[:40]) - sha1.Write(sha1Digest) - sha1Digest = sha1.Sum(nil) - - ret := make([]byte, len(md5Digest)+len(sha1Digest)) - copy(ret, md5Digest) - copy(ret[len(md5Digest):], sha1Digest) - return ret -} - -var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54} -var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52} - -// clientSum returns the contents of the verify_data member of a client's -// Finished message. -func (h finishedHash) clientSum(masterSecret []byte) []byte { - if h.version == VersionSSL30 { - return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic) - } - - out := make([]byte, finishedVerifyLength) - if h.version >= VersionTLS12 { - seed := h.client.Sum(nil) - prf12(out, masterSecret, clientFinishedLabel, seed) - } else { - seed := make([]byte, 0, md5.Size+sha1.Size) - seed = h.clientMD5.Sum(seed) - seed = h.client.Sum(seed) - prf10(out, masterSecret, clientFinishedLabel, seed) - } - return out -} - -// serverSum returns the contents of the verify_data member of a server's -// Finished message. -func (h finishedHash) serverSum(masterSecret []byte) []byte { - if h.version == VersionSSL30 { - return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic) - } - - out := make([]byte, finishedVerifyLength) - if h.version >= VersionTLS12 { - seed := h.server.Sum(nil) - prf12(out, masterSecret, serverFinishedLabel, seed) - } else { - seed := make([]byte, 0, md5.Size+sha1.Size) - seed = h.serverMD5.Sum(seed) - seed = h.server.Sum(seed) - prf10(out, masterSecret, serverFinishedLabel, seed) - } - return out -} - -// hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash -// id suitable for signing by a TLS client certificate. -func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) { - if h.version >= VersionTLS12 { - digest := h.server.Sum(nil) - return digest, crypto.SHA256, hashSHA256 - } - if sigType == signatureECDSA { - digest := h.server.Sum(nil) - return digest, crypto.SHA1, hashSHA1 - } - - digest := make([]byte, 0, 36) - digest = h.serverMD5.Sum(digest) - digest = h.server.Sum(digest) - return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */ -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/prf_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/prf_test.go deleted file mode 100644 index a9b6c9e4c7..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/prf_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "encoding/hex" - "testing" -) - -type testSplitPreMasterSecretTest struct { - in, out1, out2 string -} - -var testSplitPreMasterSecretTests = []testSplitPreMasterSecretTest{ - {"", "", ""}, - {"00", "00", "00"}, - {"0011", "00", "11"}, - {"001122", "0011", "1122"}, - {"00112233", "0011", "2233"}, -} - -func TestSplitPreMasterSecret(t *testing.T) { - for i, test := range testSplitPreMasterSecretTests { - in, _ := hex.DecodeString(test.in) - out1, out2 := splitPreMasterSecret(in) - s1 := hex.EncodeToString(out1) - s2 := hex.EncodeToString(out2) - if s1 != test.out1 || s2 != test.out2 { - t.Errorf("#%d: got: (%s, %s) want: (%s, %s)", i, s1, s2, test.out1, test.out2) - } - } -} - -type testKeysFromTest struct { - version uint16 - preMasterSecret string - clientRandom, serverRandom string - masterSecret string - clientMAC, serverMAC string - clientKey, serverKey string - macLen, keyLen int -} - -func TestKeysFromPreMasterSecret(t *testing.T) { - for i, test := range testKeysFromTests { - in, _ := hex.DecodeString(test.preMasterSecret) - clientRandom, _ := hex.DecodeString(test.clientRandom) - serverRandom, _ := hex.DecodeString(test.serverRandom) - - masterSecret := masterFromPreMasterSecret(test.version, in, clientRandom, serverRandom) - if s := hex.EncodeToString(masterSecret); s != test.masterSecret { - t.Errorf("#%d: bad master secret %s, want %s", i, s, test.masterSecret) - continue - } - - clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromMasterSecret(test.version, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0) - clientMACString := hex.EncodeToString(clientMAC) - serverMACString := hex.EncodeToString(serverMAC) - clientKeyString := hex.EncodeToString(clientKey) - serverKeyString := hex.EncodeToString(serverKey) - if clientMACString != test.clientMAC || - serverMACString != test.serverMAC || - clientKeyString != test.clientKey || - serverKeyString != test.serverKey { - t.Errorf("#%d: got: (%s, %s, %s, %s) want: (%s, %s, %s, %s)", i, clientMACString, serverMACString, clientKeyString, serverKeyString, test.clientMAC, test.serverMAC, test.clientKey, test.serverKey) - } - } -} - -// These test vectors were generated from GnuTLS using `gnutls-cli --insecure -d 9 ` -var testKeysFromTests = []testKeysFromTest{ - { - VersionTLS10, - "0302cac83ad4b1db3b9ab49ad05957de2a504a634a386fc600889321e1a971f57479466830ac3e6f468e87f5385fa0c5", - "4ae66303755184a3917fcb44880605fcc53baa01912b22ed94473fc69cebd558", - "4ae663020ec16e6bb5130be918cfcafd4d765979a3136a5d50c593446e4e44db", - "3d851bab6e5556e959a16bc36d66cfae32f672bfa9ecdef6096cbb1b23472df1da63dbbd9827606413221d149ed08ceb", - "805aaa19b3d2c0a0759a4b6c9959890e08480119", - "2d22f9fe519c075c16448305ceee209fc24ad109", - "d50b5771244f850cd8117a9ccafe2cf1", - "e076e33206b30507a85c32855acd0919", - 20, - 16, - }, - { - VersionTLS10, - "03023f7527316bc12cbcd69e4b9e8275d62c028f27e65c745cfcddc7ce01bd3570a111378b63848127f1c36e5f9e4890", - "4ae66364b5ea56b20ce4e25555aed2d7e67f42788dd03f3fee4adae0459ab106", - "4ae66363ab815cbf6a248b87d6b556184e945e9b97fbdf247858b0bdafacfa1c", - "7d64be7c80c59b740200b4b9c26d0baaa1c5ae56705acbcf2307fe62beb4728c19392c83f20483801cce022c77645460", - "97742ed60a0554ca13f04f97ee193177b971e3b0", - "37068751700400e03a8477a5c7eec0813ab9e0dc", - "207cddbc600d2a200abac6502053ee5c", - "df3f94f6e1eacc753b815fe16055cd43", - 20, - 16, - }, - { - VersionTLS10, - "832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1", - "4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e", - "4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e", - "1aff2e7a2c4279d0126f57a65a77a8d9d0087cf2733366699bec27eb53d5740705a8574bb1acc2abbe90e44f0dd28d6c", - "3c7647c93c1379a31a609542aa44e7f117a70085", - "0d73102994be74a575a3ead8532590ca32a526d4", - "ac7581b0b6c10d85bbd905ffbf36c65e", - "ff07edde49682b45466bd2e39464b306", - 20, - 16, - }, - { - VersionSSL30, - "832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1", - "4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e", - "4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e", - "a614863e56299dcffeea2938f22c2ba023768dbe4b3f6877bc9c346c6ae529b51d9cb87ff9695ea4d01f2205584405b2", - "2c450d5b6f6e2013ac6bea6a0b32200d4e1ffb94", - "7a7a7438769536f2fb1ae49a61f0703b79b2dc53", - "f8f6b26c10f12855c9aafb1e0e839ccf", - "2b9d4b4a60cb7f396780ebff50650419", - 20, - 16, - }, -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/ticket.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/ticket.go deleted file mode 100644 index 4cfc5a53ff..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/ticket.go +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/sha256" - "crypto/subtle" - "errors" - "io" -) - -// sessionState contains the information that is serialized into a session -// ticket in order to later resume a connection. -type sessionState struct { - vers uint16 - cipherSuite uint16 - masterSecret []byte - certificates [][]byte -} - -func (s *sessionState) equal(i interface{}) bool { - s1, ok := i.(*sessionState) - if !ok { - return false - } - - if s.vers != s1.vers || - s.cipherSuite != s1.cipherSuite || - !bytes.Equal(s.masterSecret, s1.masterSecret) { - return false - } - - if len(s.certificates) != len(s1.certificates) { - return false - } - - for i := range s.certificates { - if !bytes.Equal(s.certificates[i], s1.certificates[i]) { - return false - } - } - - return true -} - -func (s *sessionState) marshal() []byte { - length := 2 + 2 + 2 + len(s.masterSecret) + 2 - for _, cert := range s.certificates { - length += 4 + len(cert) - } - - ret := make([]byte, length) - x := ret - x[0] = byte(s.vers >> 8) - x[1] = byte(s.vers) - x[2] = byte(s.cipherSuite >> 8) - x[3] = byte(s.cipherSuite) - x[4] = byte(len(s.masterSecret) >> 8) - x[5] = byte(len(s.masterSecret)) - x = x[6:] - copy(x, s.masterSecret) - x = x[len(s.masterSecret):] - - x[0] = byte(len(s.certificates) >> 8) - x[1] = byte(len(s.certificates)) - x = x[2:] - - for _, cert := range s.certificates { - x[0] = byte(len(cert) >> 24) - x[1] = byte(len(cert) >> 16) - x[2] = byte(len(cert) >> 8) - x[3] = byte(len(cert)) - copy(x[4:], cert) - x = x[4+len(cert):] - } - - return ret -} - -func (s *sessionState) unmarshal(data []byte) bool { - if len(data) < 8 { - return false - } - - s.vers = uint16(data[0])<<8 | uint16(data[1]) - s.cipherSuite = uint16(data[2])<<8 | uint16(data[3]) - masterSecretLen := int(data[4])<<8 | int(data[5]) - data = data[6:] - if len(data) < masterSecretLen { - return false - } - - s.masterSecret = data[:masterSecretLen] - data = data[masterSecretLen:] - - if len(data) < 2 { - return false - } - - numCerts := int(data[0])<<8 | int(data[1]) - data = data[2:] - - s.certificates = make([][]byte, numCerts) - for i := range s.certificates { - if len(data) < 4 { - return false - } - certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - data = data[4:] - if certLen < 0 { - return false - } - if len(data) < certLen { - return false - } - s.certificates[i] = data[:certLen] - data = data[certLen:] - } - - if len(data) > 0 { - return false - } - - return true -} - -func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) { - serialized := state.marshal() - encrypted := make([]byte, aes.BlockSize+len(serialized)+sha256.Size) - iv := encrypted[:aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - - if _, err := io.ReadFull(c.config.rand(), iv); err != nil { - return nil, err - } - block, err := aes.NewCipher(c.config.SessionTicketKey[:16]) - if err != nil { - return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) - } - cipher.NewCTR(block, iv).XORKeyStream(encrypted[aes.BlockSize:], serialized) - - mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - mac.Sum(macBytes[:0]) - - return encrypted, nil -} - -func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) { - if len(encrypted) < aes.BlockSize+sha256.Size { - return nil, false - } - - iv := encrypted[:aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - - mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - expected := mac.Sum(nil) - - if subtle.ConstantTimeCompare(macBytes, expected) != 1 { - return nil, false - } - - block, err := aes.NewCipher(c.config.SessionTicketKey[:16]) - if err != nil { - return nil, false - } - ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size] - plaintext := ciphertext - cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) - - state := new(sessionState) - ok := state.unmarshal(plaintext) - return state, ok -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/tls.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/tls.go deleted file mode 100644 index 6c67506fc3..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/tls.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package tls partially implements TLS 1.2, as specified in RFC 5246. -package tls - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" - "io/ioutil" - "net" - "strings" -) - -// Server returns a new TLS server side connection -// using conn as the underlying transport. -// The configuration config must be non-nil and must have -// at least one certificate. -func Server(conn net.Conn, config *Config) *Conn { - return &Conn{conn: conn, config: config} -} - -// Client returns a new TLS client side connection -// using conn as the underlying transport. -// Client interprets a nil configuration as equivalent to -// the zero configuration; see the documentation of Config -// for the defaults. -func Client(conn net.Conn, config *Config) *Conn { - return &Conn{conn: conn, config: config, isClient: true} -} - -// A listener implements a network listener (net.Listener) for TLS connections. -type listener struct { - net.Listener - config *Config -} - -// Accept waits for and returns the next incoming TLS connection. -// The returned connection c is a *tls.Conn. -func (l *listener) Accept() (c net.Conn, err error) { - c, err = l.Listener.Accept() - if err != nil { - return - } - c = Server(c, l.config) - return -} - -// NewListener creates a Listener which accepts connections from an inner -// Listener and wraps each connection with Server. -// The configuration config must be non-nil and must have -// at least one certificate. -func NewListener(inner net.Listener, config *Config) net.Listener { - l := new(listener) - l.Listener = inner - l.config = config - return l -} - -// Listen creates a TLS listener accepting connections on the -// given network address using net.Listen. -// The configuration config must be non-nil and must have -// at least one certificate. -func Listen(network, laddr string, config *Config) (net.Listener, error) { - if config == nil || len(config.Certificates) == 0 { - return nil, errors.New("tls.Listen: no certificates in configuration") - } - l, err := net.Listen(network, laddr) - if err != nil { - return nil, err - } - return NewListener(l, config), nil -} - -// Dial connects to the given network address using net.Dial -// and then initiates a TLS handshake, returning the resulting -// TLS connection. -// Dial interprets a nil configuration as equivalent to -// the zero configuration; see the documentation of Config -// for the defaults. -func Dial(network, addr string, config *Config) (*Conn, error) { - raddr := addr - c, err := net.Dial(network, raddr) - if err != nil { - return nil, err - } - - colonPos := strings.LastIndex(raddr, ":") - if colonPos == -1 { - colonPos = len(raddr) - } - hostname := raddr[:colonPos] - - if config == nil { - config = defaultConfig() - } - // If no ServerName is set, infer the ServerName - // from the hostname we're connecting to. - if config.ServerName == "" { - // Make a copy to avoid polluting argument or default. - c := *config - c.ServerName = hostname - config = &c - } - conn := Client(c, config) - if err = conn.Handshake(); err != nil { - c.Close() - return nil, err - } - return conn, nil -} - -// LoadX509KeyPair reads and parses a public/private key pair from a pair of -// files. The files must contain PEM encoded data. -func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) { - certPEMBlock, err := ioutil.ReadFile(certFile) - if err != nil { - return - } - keyPEMBlock, err := ioutil.ReadFile(keyFile) - if err != nil { - return - } - return X509KeyPair(certPEMBlock, keyPEMBlock) -} - -// X509KeyPair parses a public/private key pair from a pair of -// PEM encoded data. -func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) { - var certDERBlock *pem.Block - for { - certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) - if certDERBlock == nil { - break - } - if certDERBlock.Type == "CERTIFICATE" { - cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) - } - } - - if len(cert.Certificate) == 0 { - err = errors.New("crypto/tls: failed to parse certificate PEM data") - return - } - - var keyDERBlock *pem.Block - for { - keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) - if keyDERBlock == nil { - err = errors.New("crypto/tls: failed to parse key PEM data") - return - } - if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { - break - } - } - - cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) - if err != nil { - return - } - - // We don't need to parse the public key for TLS, but we so do anyway - // to check that it looks sane and matches the private key. - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - return - } - - switch pub := x509Cert.PublicKey.(type) { - case *rsa.PublicKey: - priv, ok := cert.PrivateKey.(*rsa.PrivateKey) - if !ok { - err = errors.New("crypto/tls: private key type does not match public key type") - return - } - if pub.N.Cmp(priv.N) != 0 { - err = errors.New("crypto/tls: private key does not match public key") - return - } - case *ecdsa.PublicKey: - priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) - if !ok { - err = errors.New("crypto/tls: private key type does not match public key type") - return - - } - if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { - err = errors.New("crypto/tls: private key does not match public key") - return - } - default: - err = errors.New("crypto/tls: unknown public key algorithm") - return - } - - return -} - -// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates -// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. -// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. -func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { - if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { - return key, nil - } - if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { - switch key := key.(type) { - case *rsa.PrivateKey, *ecdsa.PrivateKey: - return key, nil - default: - return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping") - } - } - if key, err := x509.ParseECPrivateKey(der); err == nil { - return key, nil - } - - return nil, errors.New("crypto/tls: failed to parse private key") -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/tls_test.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/tls_test.go deleted file mode 100644 index 38229014cd..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/core/tls/tls_test.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tls - -import ( - "testing" -) - -var rsaCertPEM = `-----BEGIN CERTIFICATE----- -MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ -hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa -rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv -zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW -r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V ------END CERTIFICATE----- -` - -var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo -k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G -6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N -MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW -SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T -xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi -D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== ------END RSA PRIVATE KEY----- -` - -// keyPEM is the same as rsaKeyPEM, but declares itself as just -// "PRIVATE KEY", not "RSA PRIVATE KEY". http://golang.org/issue/4477 -var keyPEM = `-----BEGIN PRIVATE KEY----- -MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo -k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G -6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N -MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW -SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T -xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi -D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== ------END PRIVATE KEY----- -` - -var ecdsaCertPEM = `-----BEGIN CERTIFICATE----- -MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw -EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 -eSBMdGQwHhcNMTIxMTE0MTI0MDQ4WhcNMTUxMTE0MTI0MDQ4WjBFMQswCQYDVQQG -EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk -Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBY9+my9OoeSUR -lDQdV/x8LsOuLilthhiS1Tz4aGDHIPwC1mlvnf7fg5lecYpMCrLLhauAc1UJXcgl -01xoLuzgtAEAgv2P/jgytzRSpUYvgLBt1UA0leLYBy6mQQbrNEuqT3INapKIcUv8 -XxYP0xMEUksLPq6Ca+CRSqTtrd/23uTnapkwCQYHKoZIzj0EAQOBigAwgYYCQXJo -A7Sl2nLVf+4Iu/tAX/IF4MavARKC4PPHK3zfuGfPR3oCCcsAoz3kAzOeijvd0iXb -H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1 -+jwM1FGS4fREIOvlBYr/SzzQRtwrvrzGYxDEDbsC0ZGRnA== ------END CERTIFICATE----- -` - -var ecdsaKeyPEM = `-----BEGIN EC PARAMETERS----- -BgUrgQQAIw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0 -NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL -06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz -VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q -kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ== ------END EC PRIVATE KEY----- -` - -var keyPairTests = []struct { - algo string - cert string - key string -}{ - {"ECDSA", ecdsaCertPEM, ecdsaKeyPEM}, - {"RSA", rsaCertPEM, rsaKeyPEM}, - {"RSA-untyped", rsaCertPEM, keyPEM}, // golang.org/issue/4477 -} - -func TestX509KeyPair(t *testing.T) { - var pem []byte - for _, test := range keyPairTests { - pem = []byte(test.cert + test.key) - if _, err := X509KeyPair(pem, pem); err != nil { - t.Errorf("Failed to load %s cert followed by %s key: %s", test.algo, test.algo, err) - } - pem = []byte(test.key + test.cert) - if _, err := X509KeyPair(pem, pem); err != nil { - t.Errorf("Failed to load %s key followed by %s cert: %s", test.algo, test.algo, err) - } - } -} - -func TestX509MixedKeyPair(t *testing.T) { - if _, err := X509KeyPair([]byte(rsaCertPEM), []byte(ecdsaKeyPEM)); err == nil { - t.Error("Load of RSA certificate succeeded with ECDSA private key") - } - if _, err := X509KeyPair([]byte(ecdsaCertPEM), []byte(rsaKeyPEM)); err == nil { - t.Error("Load of ECDSA certificate succeeded with RSA private key") - } -} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/publishSettings.go b/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/publishSettings.go deleted file mode 100644 index 34d8bf0552..0000000000 --- a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/publishSettings.go +++ /dev/null @@ -1,138 +0,0 @@ -package azureSdkForGo - -import ( - "encoding/base64" - "encoding/xml" - "errors" - "fmt" - "io/ioutil" -) - -var settings publishSettings = publishSettings{} - -func GetPublishSettings() publishSettings { - return settings -} - -func setPublishSettings(id string, cert []byte, key []byte) { - settings.SubscriptionID = id - settings.SubscriptionCert = cert - settings.SubscriptionKey = key -} - -func ImportPublishSettings(id string, certPath string) error { - if len(id) == 0 { - return fmt.Errorf(ParamNotSpecifiedError, "id") - } - if len(certPath) == 0 { - return fmt.Errorf(ParamNotSpecifiedError, "certPath") - } - - cert, err := ioutil.ReadFile(certPath) - if err != nil { - return err - } - - setPublishSettings(id, cert, cert) - return nil -} - -func ImportPublishSettingsFile(filePath string) error { - if len(filePath) == 0 { - return fmt.Errorf(ParamNotSpecifiedError, "filePath") - } - - publishSettingsContent, err := ioutil.ReadFile(filePath) - if err != nil { - return err - } - - activeSubscription, err := getActiveSubscription(publishSettingsContent) - if err != nil { - return err - } - - cert, err := getSubscriptionCert(activeSubscription) - if err != nil { - return err - } - - setPublishSettings(activeSubscription.Id, cert, cert) - return nil -} - -func getSubscriptionCert(subscription subscription) ([]byte, error) { - certPassword := "" - - pfxCert, err := base64.StdEncoding.DecodeString(subscription.ManagementCertificate) - if err != nil { - return nil, err - } - - subscriptionCert, err := ExecuteCommand(fmt.Sprintf("openssl pkcs12 -nodes -passin pass:%s", certPassword), pfxCert) - if err != nil { - return nil, err - } - - return subscriptionCert, nil -} - -func getActiveSubscription(publishSettingsContent []byte) (subscription, error) { - publishData := publishData{} - activeSubscription := subscription{} - - err := xml.Unmarshal(publishSettingsContent, &publishData) - if err != nil { - return activeSubscription, err - } - - if len(publishData.PublishProfiles) == 0 { - err = errors.New("No publish profiles were found") - return activeSubscription, err - } - - publishProfile := publishData.PublishProfiles[0] - subscriptions := publishProfile.Subscriptions - if len(subscriptions) == 0 { - err = errors.New("No subscriptions were found") - return activeSubscription, err - } - - activeSubscription = subscriptions[0] - - if len(activeSubscription.ManagementCertificate) == 0 { - activeSubscription.ManagementCertificate = publishProfile.ManagementCertificate - activeSubscription.ServiceManagementUrl = publishProfile.Url - } - - return activeSubscription, nil -} - -type publishSettings struct { - XMLName xml.Name `xml:"PublishSettings"` - SubscriptionID string - SubscriptionCert []byte - SubscriptionKey []byte -} - -type publishData struct { - XMLName xml.Name `xml:"PublishData"` - PublishProfiles []publishProfile `xml:"PublishProfile"` -} - -type publishProfile struct { - XMLName xml.Name `xml:"PublishProfile"` - SchemaVersion string `xml:",attr"` - PublishMethod string `xml:",attr"` - Url string `xml:",attr"` - ManagementCertificate string `xml:",attr"` - Subscriptions []subscription `xml:"Subscription"` -} - -type subscription struct { - XMLName xml.Name `xml:"Subscription"` - ServiceManagementUrl string `xml:",attr"` - Id string `xml:",attr"` - Name string `xml:",attr"` - ManagementCertificate string `xml:",attr"` -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml b/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml deleted file mode 100644 index d5a559f840..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -go: - - 1.2 - - 1.3 - - tip -install: - - go get github.com/stretchr/testify - - go get github.com/stvp/go-udp-testing - - go get github.com/tobi/airbrake-go diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md b/Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md deleted file mode 100644 index cabd027ae9..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md +++ /dev/null @@ -1,349 +0,0 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) - -Logrus is a structured logger for Go (golang), completely API compatible with -the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not -yet stable (pre 1.0), the core API is unlikely change much but please version -control your Logrus to make sure you aren't fetching latest `master` on every -build.** - -Nicely color-coded in development (when a TTY is attached, otherwise just -plain text): - -![Colored](http://i.imgur.com/PY7qMwd.png) - -With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash -or Splunk: - -```json -{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the -ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} - -{"level":"warning","msg":"The group's number increased tremendously!", -"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"A giant walrus appears!", -"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", -"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} - -{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, -"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} -``` - -With the default `log.Formatter = new(logrus.TextFormatter)` when a TTY is not -attached, the output is compatible with the -[l2met](http://r.32k.io/l2met-introduction) format: - -```text -time="2014-04-20 15:36:23.830442383 -0400 EDT" level="info" msg="A group of walrus emerges from the ocean" animal="walrus" size=10 -time="2014-04-20 15:36:23.830584199 -0400 EDT" level="warning" msg="The group's number increased tremendously!" omg=true number=122 -time="2014-04-20 15:36:23.830596521 -0400 EDT" level="info" msg="A giant walrus appears!" animal="walrus" size=10 -time="2014-04-20 15:36:23.830611837 -0400 EDT" level="info" msg="Tremendously sized cow enters the ocean." animal="walrus" size=9 -time="2014-04-20 15:36:23.830626464 -0400 EDT" level="fatal" msg="The ice breaks!" omg=true number=100 -``` - -#### Example - -The simplest way to use Logrus is simply the package-level exported logger: - -```go -package main - -import ( - log "github.com/Sirupsen/logrus" -) - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - }).Info("A walrus appears") -} -``` - -Note that it's completely api-compatible with the stdlib logger, so you can -replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` -and you'll now have the flexibility of Logrus. You can customize it all you -want: - -```go -package main - -import ( - "os" - log "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" -) - -func init() { - // Log as JSON instead of the default ASCII formatter. - log.SetFormatter(&log.JSONFormatter{}) - - // Use the Airbrake hook to report errors that have Error severity or above to - // an exception tracker. You can create custom hooks, see the Hooks section. - log.AddHook(&logrus_airbrake.AirbrakeHook{}) - - // Output to stderr instead of stdout, could also be a file. - log.SetOutput(os.Stderr) - - // Only log the warning severity or above. - log.SetLevel(log.WarnLevel) -} - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(log.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(log.Fields{ - "omg": true, - "number": 100, - }).Fatal("The ice breaks!") -} -``` - -For more advanced usage such as logging to multiple locations from the same -application, you can also create an instance of the `logrus` Logger: - -```go -package main - -import ( - "github.com/Sirupsen/logrus" -) - -// Create a new instance of the logger. You can have any number of instances. -var log = logrus.New() - -func main() { - // The API for setting attributes is a little different than the package level - // exported logger. See Godoc. - log.Out = os.Stderr - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") -} -``` - -#### Fields - -Logrus encourages careful, structured logging though logging fields instead of -long, unparseable error messages. For example, instead of: `log.Fatalf("Failed -to send event %s to topic %s with key %d")`, you should log the much more -discoverable: - -```go -log.WithFields(log.Fields{ - "event": event, - "topic": topic, - "key": key, -}).Fatal("Failed to send event") -``` - -We've found this API forces you to think about logging in a way that produces -much more useful logging messages. We've been in countless situations where just -a single added field to a log statement that was already there would've saved us -hours. The `WithFields` call is optional. - -In general, with Logrus using any of the `printf`-family functions should be -seen as a hint you should add a field, however, you can still use the -`printf`-family functions with Logrus. - -#### Hooks - -You can add hooks for logging levels. For example to send errors to an exception -tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to -multiple places simultaneously, e.g. syslog. - -```go -// Not the real implementation of the Airbrake hook. Just a simple sample. -import ( - log "github.com/Sirupsen/logrus" -) - -func init() { - log.AddHook(new(AirbrakeHook)) -} - -type AirbrakeHook struct{} - -// `Fire()` takes the entry that the hook is fired for. `entry.Data[]` contains -// the fields for the entry. See the Fields section of the README. -func (hook *AirbrakeHook) Fire(entry *logrus.Entry) error { - err := airbrake.Notify(entry.Data["error"].(error)) - if err != nil { - log.WithFields(log.Fields{ - "source": "airbrake", - "endpoint": airbrake.Endpoint, - }).Info("Failed to send error to Airbrake") - } - - return nil -} - -// `Levels()` returns a slice of `Levels` the hook is fired for. -func (hook *AirbrakeHook) Levels() []log.Level { - return []log.Level{ - log.ErrorLevel, - log.FatalLevel, - log.PanicLevel, - } -} -``` - -Logrus comes with built-in hooks. Add those, or your custom hook, in `init`: - -```go -import ( - log "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" - "github.com/Sirupsen/logrus/hooks/syslog" - "log/syslog" -) - -func init() { - log.AddHook(new(logrus_airbrake.AirbrakeHook)) - - hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - if err != nil { - log.Error("Unable to connect to local syslog daemon") - } else { - log.AddHook(hook) - } -} -``` - -* [`github.com/Sirupsen/logrus/hooks/airbrake`](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) - Send errors to an exception tracking service compatible with the Airbrake API. - Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. - -* [`github.com/Sirupsen/logrus/hooks/papertrail`](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) - Send errors to the Papertrail hosted logging service via UDP. - -* [`github.com/Sirupsen/logrus/hooks/syslog`](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) - Send errors to remote syslog server. - Uses standard library `log/syslog` behind the scenes. - -* [`github.com/nubo/hiprus`](https://github.com/nubo/hiprus) - Send errors to a channel in hipchat. - -#### Level logging - -Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. - -```go -log.Debug("Useful debugging information.") -log.Info("Something noteworthy happened!") -log.Warn("You should probably take a look at this.") -log.Error("Something failed but I'm not quitting.") -// Calls os.Exit(1) after logging -log.Fatal("Bye.") -// Calls panic() after logging -log.Panic("I'm bailing.") -``` - -You can set the logging level on a `Logger`, then it will only log entries with -that severity or anything above it: - -```go -// Will log anything that is info or above (warn, error, fatal, panic). Default. -log.SetLevel(log.InfoLevel) -``` - -It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose -environment if your application has that. - -#### Entries - -Besides the fields added with `WithField` or `WithFields` some fields are -automatically added to all logging events: - -1. `time`. The timestamp when the entry was created. -2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after - the `AddFields` call. E.g. `Failed to send event.` -3. `level`. The logging level. E.g. `info`. - -#### Environments - -Logrus has no notion of environment. - -If you wish for hooks and formatters to only be used in specific environments, -you should handle that yourself. For example, if your application has a global -variable `Environment`, which is a string representation of the environment you -could do: - -```go -import ( - log "github.com/Sirupsen/logrus" -) - -init() { - // do something here to set environment depending on an environment variable - // or command-line flag - if Environment == "production" { - log.SetFormatter(logrus.JSONFormatter) - } else { - // The TextFormatter is default, you don't actually have to do this. - log.SetFormatter(logrus.TextFormatter) - } -} -``` - -This configuration is how `logrus` was intended to be used, but JSON in -production is mostly only useful if you do log aggregation with tools like -Splunk or Logstash. - -#### Formatters - -The built-in logging formatters are: - -* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise - without colors. - * *Note:* to force colored output when there is no TTY, set the `ForceColors` - field to `true`. To force no colored output even if there is a TTY set the - `DisableColors` field to `true` -* `logrus.JSONFormatter`. Logs fields as JSON. - -Third party logging formatters: - -* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. - -You can define your formatter by implementing the `Formatter` interface, -requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a -`Fields` type (`map[string]interface{}`) with all your fields as well as the -default ones (see Entries section above): - -```go -type MyJSONFormatter struct { -} - -log.SetFormatter(new(MyJSONFormatter)) - -func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - // Note this doesn't include Time, Level and Message which are available on - // the Entry. Consult `godoc` on information about those fields or read the - // source of the official loggers. - serialized, err := json.Marshal(entry.Data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} -``` - -#### Rotation - -Log rotation is not provided with Logrus. Log rotation should be done by an -external program (like `logrotated(8)`) that can compress and delete old log -entries. It should not be a feature of the application-level logger. - - -[godoc]: https://godoc.org/github.com/Sirupsen/logrus diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go deleted file mode 100644 index e164eecb5f..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go +++ /dev/null @@ -1,248 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "io" - "os" - "time" -) - -// An entry is the final or intermediate Logrus logging entry. It contains all -// the fields passed with WithField{,s}. It's finally logged when Debug, Info, -// Warn, Error, Fatal or Panic is called on it. These objects can be reused and -// passed around as much as you wish to avoid field duplication. -type Entry struct { - Logger *Logger - - // Contains all the fields set by the user. - Data Fields - - // Time at which the log entry was created - Time time.Time - - // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic - Level Level - - // Message passed to Debug, Info, Warn, Error, Fatal or Panic - Message string -} - -func NewEntry(logger *Logger) *Entry { - return &Entry{ - Logger: logger, - // Default is three fields, give a little extra room - Data: make(Fields, 5), - } -} - -// Returns a reader for the entry, which is a proxy to the formatter. -func (entry *Entry) Reader() (*bytes.Buffer, error) { - serialized, err := entry.Logger.Formatter.Format(entry) - return bytes.NewBuffer(serialized), err -} - -// Returns the string representation from the reader and ultimately the -// formatter. -func (entry *Entry) String() (string, error) { - reader, err := entry.Reader() - if err != nil { - return "", err - } - - return reader.String(), err -} - -// Add a single field to the Entry. -func (entry *Entry) WithField(key string, value interface{}) *Entry { - return entry.WithFields(Fields{key: value}) -} - -// Add a map of fields to the Entry. -func (entry *Entry) WithFields(fields Fields) *Entry { - data := Fields{} - for k, v := range entry.Data { - data[k] = v - } - for k, v := range fields { - data[k] = v - } - return &Entry{Logger: entry.Logger, Data: data} -} - -func (entry *Entry) log(level Level, msg string) { - entry.Time = time.Now() - entry.Level = level - entry.Message = msg - - if err := entry.Logger.Hooks.Fire(level, entry); err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) - entry.Logger.mu.Unlock() - } - - reader, err := entry.Reader() - if err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) - entry.Logger.mu.Unlock() - } - - entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() - - _, err = io.Copy(entry.Logger.Out, reader) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) - } - - // To avoid Entry#log() returning a value that only would make sense for - // panic() to use in Entry#Panic(), we avoid the allocation by checking - // directly here. - if level <= PanicLevel { - panic(entry) - } -} - -func (entry *Entry) Debug(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.log(DebugLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Print(args ...interface{}) { - entry.Info(args...) -} - -func (entry *Entry) Info(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.log(InfoLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Warn(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.log(WarnLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Error(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.log(ErrorLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Fatal(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.log(FatalLevel, fmt.Sprint(args...)) - } - os.Exit(1) -} - -func (entry *Entry) Panic(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.log(PanicLevel, fmt.Sprint(args...)) - } - panic(fmt.Sprint(args...)) -} - -// Entry Printf family functions - -func (entry *Entry) Debugf(format string, args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.Debug(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Infof(format string, args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.Info(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Printf(format string, args ...interface{}) { - entry.Infof(format, args...) -} - -func (entry *Entry) Warnf(format string, args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.Warn(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Warningf(format string, args ...interface{}) { - entry.Warnf(format, args...) -} - -func (entry *Entry) Errorf(format string, args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.Error(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Fatalf(format string, args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.Fatal(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Panicf(format string, args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.Panic(fmt.Sprintf(format, args...)) - } -} - -// Entry Println family functions - -func (entry *Entry) Debugln(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.Debug(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Infoln(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.Info(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Println(args ...interface{}) { - entry.Infoln(args...) -} - -func (entry *Entry) Warnln(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.Warn(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Warningln(args ...interface{}) { - entry.Warnln(args...) -} - -func (entry *Entry) Errorln(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.Error(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Fatalln(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.Fatal(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Panicln(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.Panic(entry.sprintlnn(args...)) - } -} - -// Sprintlnn => Sprint no newline. This is to get the behavior of how -// fmt.Sprintln where spaces are always added between operands, regardless of -// their type. Instead of vendoring the Sprintln implementation to spare a -// string allocation, we do the simplest thing. -func (entry *Entry) sprintlnn(args ...interface{}) string { - msg := fmt.Sprintln(args...) - return msg[:len(msg)-1] -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go deleted file mode 100644 index 98717df490..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestEntryPanicln(t *testing.T) { - errBoom := fmt.Errorf("boom time") - - defer func() { - p := recover() - assert.NotNil(t, p) - - switch pVal := p.(type) { - case *Entry: - assert.Equal(t, "kaboom", pVal.Message) - assert.Equal(t, errBoom, pVal.Data["err"]) - default: - t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) - } - }() - - logger := New() - logger.Out = &bytes.Buffer{} - entry := NewEntry(logger) - entry.WithField("err", errBoom).Panicln("kaboom") -} - -func TestEntryPanicf(t *testing.T) { - errBoom := fmt.Errorf("boom again") - - defer func() { - p := recover() - assert.NotNil(t, p) - - switch pVal := p.(type) { - case *Entry: - assert.Equal(t, "kaboom true", pVal.Message) - assert.Equal(t, errBoom, pVal.Data["err"]) - default: - t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) - } - }() - - logger := New() - logger.Out = &bytes.Buffer{} - entry := NewEntry(logger) - entry.WithField("err", errBoom).Panicf("kaboom %v", true) -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go deleted file mode 100644 index a62ba45de5..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "github.com/Sirupsen/logrus" -) - -var log = logrus.New() - -func init() { - log.Formatter = new(logrus.JSONFormatter) - log.Formatter = new(logrus.TextFormatter) // default -} - -func main() { - defer func() { - err := recover() - if err != nil { - log.WithFields(logrus.Fields{ - "omg": true, - "err": err, - "number": 100, - }).Fatal("The ice breaks!") - } - }() - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(logrus.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(logrus.Fields{ - "animal": "orca", - "size": 9009, - }).Panic("It's over 9000!") -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go deleted file mode 100644 index 42e7a4c982..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" - "github.com/tobi/airbrake-go" -) - -var log = logrus.New() - -func init() { - log.Formatter = new(logrus.TextFormatter) // default - log.Hooks.Add(new(logrus_airbrake.AirbrakeHook)) -} - -func main() { - airbrake.Endpoint = "https://exceptions.whatever.com/notifier_api/v2/notices.xml" - airbrake.ApiKey = "whatever" - airbrake.Environment = "production" - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(logrus.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(logrus.Fields{ - "omg": true, - "number": 100, - }).Fatal("The ice breaks!") -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter_bench_test.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter_bench_test.go deleted file mode 100644 index 77989da629..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter_bench_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package logrus - -import ( - "testing" - "time" -) - -// smallFields is a small size data set for benchmarking -var smallFields = Fields{ - "foo": "bar", - "baz": "qux", - "one": "two", - "three": "four", -} - -// largeFields is a large size data set for benchmarking -var largeFields = Fields{ - "foo": "bar", - "baz": "qux", - "one": "two", - "three": "four", - "five": "six", - "seven": "eight", - "nine": "ten", - "eleven": "twelve", - "thirteen": "fourteen", - "fifteen": "sixteen", - "seventeen": "eighteen", - "nineteen": "twenty", - "a": "b", - "c": "d", - "e": "f", - "g": "h", - "i": "j", - "k": "l", - "m": "n", - "o": "p", - "q": "r", - "s": "t", - "u": "v", - "w": "x", - "y": "z", - "this": "will", - "make": "thirty", - "entries": "yeah", -} - -func BenchmarkSmallTextFormatter(b *testing.B) { - doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields) -} - -func BenchmarkLargeTextFormatter(b *testing.B) { - doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields) -} - -func BenchmarkSmallColoredTextFormatter(b *testing.B) { - doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields) -} - -func BenchmarkLargeColoredTextFormatter(b *testing.B) { - doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields) -} - -func BenchmarkSmallJSONFormatter(b *testing.B) { - doBenchmark(b, &JSONFormatter{}, smallFields) -} - -func BenchmarkLargeJSONFormatter(b *testing.B) { - doBenchmark(b, &JSONFormatter{}, largeFields) -} - -func doBenchmark(b *testing.B, formatter Formatter, fields Fields) { - entry := &Entry{ - Time: time.Time{}, - Level: InfoLevel, - Message: "message", - Data: fields, - } - var d []byte - var err error - for i := 0; i < b.N; i++ { - d, err = formatter.Format(entry) - if err != nil { - b.Fatal(err) - } - b.SetBytes(int64(len(d))) - } -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hook_test.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hook_test.go deleted file mode 100644 index 13f34cb6f8..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hook_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package logrus - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -type TestHook struct { - Fired bool -} - -func (hook *TestHook) Fire(entry *Entry) error { - hook.Fired = true - return nil -} - -func (hook *TestHook) Levels() []Level { - return []Level{ - DebugLevel, - InfoLevel, - WarnLevel, - ErrorLevel, - FatalLevel, - PanicLevel, - } -} - -func TestHookFires(t *testing.T) { - hook := new(TestHook) - - LogAndAssertJSON(t, func(log *Logger) { - log.Hooks.Add(hook) - assert.Equal(t, hook.Fired, false) - - log.Print("test") - }, func(fields Fields) { - assert.Equal(t, hook.Fired, true) - }) -} - -type ModifyHook struct { -} - -func (hook *ModifyHook) Fire(entry *Entry) error { - entry.Data["wow"] = "whale" - return nil -} - -func (hook *ModifyHook) Levels() []Level { - return []Level{ - DebugLevel, - InfoLevel, - WarnLevel, - ErrorLevel, - FatalLevel, - PanicLevel, - } -} - -func TestHookCanModifyEntry(t *testing.T) { - hook := new(ModifyHook) - - LogAndAssertJSON(t, func(log *Logger) { - log.Hooks.Add(hook) - log.WithField("wow", "elephant").Print("test") - }, func(fields Fields) { - assert.Equal(t, fields["wow"], "whale") - }) -} - -func TestCanFireMultipleHooks(t *testing.T) { - hook1 := new(ModifyHook) - hook2 := new(TestHook) - - LogAndAssertJSON(t, func(log *Logger) { - log.Hooks.Add(hook1) - log.Hooks.Add(hook2) - - log.WithField("wow", "elephant").Print("test") - }, func(fields Fields) { - assert.Equal(t, fields["wow"], "whale") - assert.Equal(t, hook2.Fired, true) - }) -} - -type ErrorHook struct { - Fired bool -} - -func (hook *ErrorHook) Fire(entry *Entry) error { - hook.Fired = true - return nil -} - -func (hook *ErrorHook) Levels() []Level { - return []Level{ - ErrorLevel, - } -} - -func TestErrorHookShouldntFireOnInfo(t *testing.T) { - hook := new(ErrorHook) - - LogAndAssertJSON(t, func(log *Logger) { - log.Hooks.Add(hook) - log.Info("test") - }, func(fields Fields) { - assert.Equal(t, hook.Fired, false) - }) -} - -func TestErrorHookShouldFireOnError(t *testing.T) { - hook := new(ErrorHook) - - LogAndAssertJSON(t, func(log *Logger) { - log.Hooks.Add(hook) - log.Error("test") - }, func(fields Fields) { - assert.Equal(t, hook.Fired, true) - }) -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go deleted file mode 100644 index 880d21ecdc..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go +++ /dev/null @@ -1,54 +0,0 @@ -package logrus_airbrake - -import ( - "github.com/Sirupsen/logrus" - "github.com/tobi/airbrake-go" -) - -// AirbrakeHook to send exceptions to an exception-tracking service compatible -// with the Airbrake API. You must set: -// * airbrake.Endpoint -// * airbrake.ApiKey -// * airbrake.Environment (only sends exceptions when set to "production") -// -// Before using this hook, to send an error. Entries that trigger an Error, -// Fatal or Panic should now include an "error" field to send to Airbrake. -type AirbrakeHook struct{} - -func (hook *AirbrakeHook) Fire(entry *logrus.Entry) error { - if entry.Data["error"] == nil { - entry.Logger.WithFields(logrus.Fields{ - "source": "airbrake", - "endpoint": airbrake.Endpoint, - }).Warn("Exceptions sent to Airbrake must have an 'error' key with the error") - return nil - } - - err, ok := entry.Data["error"].(error) - if !ok { - entry.Logger.WithFields(logrus.Fields{ - "source": "airbrake", - "endpoint": airbrake.Endpoint, - }).Warn("Exceptions sent to Airbrake must have an `error` key of type `error`") - return nil - } - - airErr := airbrake.Notify(err) - if airErr != nil { - entry.Logger.WithFields(logrus.Fields{ - "source": "airbrake", - "endpoint": airbrake.Endpoint, - "error": airErr, - }).Warn("Failed to send error to Airbrake") - } - - return nil -} - -func (hook *AirbrakeHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.ErrorLevel, - logrus.FatalLevel, - logrus.PanicLevel, - } -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md deleted file mode 100644 index ae61e9229a..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Papertrail Hook for Logrus :walrus: - -[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts). - -In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible. - -## Usage - -You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`. - -For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs. - -```go -import ( - "log/syslog" - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/papertrail" -) - -func main() { - log := logrus.New() - hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME) - - if err == nil { - log.Hooks.Add(hook) - } -} -``` diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go deleted file mode 100644 index 48e2feaeb5..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go +++ /dev/null @@ -1,54 +0,0 @@ -package logrus_papertrail - -import ( - "fmt" - "net" - "os" - "time" - - "github.com/Sirupsen/logrus" -) - -const ( - format = "Jan 2 15:04:05" -) - -// PapertrailHook to send logs to a logging service compatible with the Papertrail API. -type PapertrailHook struct { - Host string - Port int - AppName string - UDPConn net.Conn -} - -// NewPapertrailHook creates a hook to be added to an instance of logger. -func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) { - conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port)) - return &PapertrailHook{host, port, appName, conn}, err -} - -// Fire is called when a log event is fired. -func (hook *PapertrailHook) Fire(entry *logrus.Entry) error { - date := time.Now().Format(format) - payload := fmt.Sprintf("<22> %s %s: [%s] %s", date, hook.AppName, entry.Data["level"], entry.Message) - - bytesWritten, err := hook.UDPConn.Write([]byte(payload)) - if err != nil { - fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err) - return err - } - - return nil -} - -// Levels returns the available logging levels. -func (hook *PapertrailHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, - logrus.WarnLevel, - logrus.InfoLevel, - logrus.DebugLevel, - } -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go deleted file mode 100644 index 96318d0030..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package logrus_papertrail - -import ( - "fmt" - "testing" - - "github.com/Sirupsen/logrus" - "github.com/stvp/go-udp-testing" -) - -func TestWritingToUDP(t *testing.T) { - port := 16661 - udp.SetAddr(fmt.Sprintf(":%d", port)) - - hook, err := NewPapertrailHook("localhost", port, "test") - if err != nil { - t.Errorf("Unable to connect to local UDP server.") - } - - log := logrus.New() - log.Hooks.Add(hook) - - udp.ShouldReceive(t, "foo", func() { - log.Info("foo") - }) -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md deleted file mode 100644 index cd706bc1b1..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Syslog Hooks for Logrus :walrus: - -## Usage - -```go -import ( - "log/syslog" - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/syslog" -) - -func main() { - log := logrus.New() - hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - - if err == nil { - log.Hooks.Add(hook) - } -} -``` \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go deleted file mode 100644 index b6fa374628..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go +++ /dev/null @@ -1,59 +0,0 @@ -package logrus_syslog - -import ( - "fmt" - "github.com/Sirupsen/logrus" - "log/syslog" - "os" -) - -// SyslogHook to send logs via syslog. -type SyslogHook struct { - Writer *syslog.Writer - SyslogNetwork string - SyslogRaddr string -} - -// Creates a hook to be added to an instance of logger. This is called with -// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")` -// `if err == nil { log.Hooks.Add(hook) }` -func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) { - w, err := syslog.Dial(network, raddr, priority, tag) - return &SyslogHook{w, network, raddr}, err -} - -func (hook *SyslogHook) Fire(entry *logrus.Entry) error { - line, err := entry.String() - if err != nil { - fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err) - return err - } - - switch entry.Level { - case logrus.PanicLevel: - return hook.Writer.Crit(line) - case logrus.FatalLevel: - return hook.Writer.Crit(line) - case logrus.ErrorLevel: - return hook.Writer.Err(line) - case logrus.WarnLevel: - return hook.Writer.Warning(line) - case logrus.InfoLevel: - return hook.Writer.Info(line) - case logrus.DebugLevel: - return hook.Writer.Debug(line) - default: - return nil - } -} - -func (hook *SyslogHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, - logrus.WarnLevel, - logrus.InfoLevel, - logrus.DebugLevel, - } -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go deleted file mode 100644 index 42762dc10d..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package logrus_syslog - -import ( - "github.com/Sirupsen/logrus" - "log/syslog" - "testing" -) - -func TestLocalhostAddAndPrint(t *testing.T) { - log := logrus.New() - hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - - if err != nil { - t.Errorf("Unable to connect to local syslog.") - } - - log.Hooks.Add(hook) - - for _, level := range hook.Levels() { - if len(log.Hooks[level]) != 1 { - t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level])) - } - } - - log.Info("Congratulations!") -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go deleted file mode 100644 index 9d11b642d4..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go +++ /dev/null @@ -1,22 +0,0 @@ -package logrus - -import ( - "encoding/json" - "fmt" - "time" -) - -type JSONFormatter struct{} - -func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - prefixFieldClashes(entry) - entry.Data["time"] = entry.Time.Format(time.RFC3339) - entry.Data["msg"] = entry.Message - entry.Data["level"] = entry.Level.String() - - serialized, err := json.Marshal(entry.Data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go deleted file mode 100644 index 7374fe365d..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go +++ /dev/null @@ -1,161 +0,0 @@ -package logrus - -import ( - "io" - "os" - "sync" -) - -type Logger struct { - // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a - // file, or leave it default which is `os.Stdout`. You can also set this to - // something more adventorous, such as logging to Kafka. - Out io.Writer - // Hooks for the logger instance. These allow firing events based on logging - // levels and log entries. For example, to send errors to an error tracking - // service, log to StatsD or dump the core on fatal errors. - Hooks levelHooks - // All log entries pass through the formatter before logged to Out. The - // included formatters are `TextFormatter` and `JSONFormatter` for which - // TextFormatter is the default. In development (when a TTY is attached) it - // logs with colors, but to a file it wouldn't. You can easily implement your - // own that implements the `Formatter` interface, see the `README` or included - // formatters for examples. - Formatter Formatter - // The logging level the logger should log at. This is typically (and defaults - // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be - // logged. `logrus.Debug` is useful in - Level Level - // Used to sync writing to the log. - mu sync.Mutex -} - -// Creates a new logger. Configuration should be set by changing `Formatter`, -// `Out` and `Hooks` directly on the default logger instance. You can also just -// instantiate your own: -// -// var log = &Logger{ -// Out: os.Stderr, -// Formatter: new(JSONFormatter), -// Hooks: make(levelHooks), -// Level: logrus.Debug, -// } -// -// It's recommended to make this a global instance called `log`. -func New() *Logger { - return &Logger{ - Out: os.Stdout, - Formatter: new(TextFormatter), - Hooks: make(levelHooks), - Level: InfoLevel, - } -} - -// Adds a field to the log entry, note that you it doesn't log until you call -// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. -// Ff you want multiple fields, use `WithFields`. -func (logger *Logger) WithField(key string, value interface{}) *Entry { - return NewEntry(logger).WithField(key, value) -} - -// Adds a struct of fields to the log entry. All it does is call `WithField` for -// each `Field`. -func (logger *Logger) WithFields(fields Fields) *Entry { - return NewEntry(logger).WithFields(fields) -} - -func (logger *Logger) Debugf(format string, args ...interface{}) { - NewEntry(logger).Debugf(format, args...) -} - -func (logger *Logger) Infof(format string, args ...interface{}) { - NewEntry(logger).Infof(format, args...) -} - -func (logger *Logger) Printf(format string, args ...interface{}) { - NewEntry(logger).Printf(format, args...) -} - -func (logger *Logger) Warnf(format string, args ...interface{}) { - NewEntry(logger).Warnf(format, args...) -} - -func (logger *Logger) Warningf(format string, args ...interface{}) { - NewEntry(logger).Warnf(format, args...) -} - -func (logger *Logger) Errorf(format string, args ...interface{}) { - NewEntry(logger).Errorf(format, args...) -} - -func (logger *Logger) Fatalf(format string, args ...interface{}) { - NewEntry(logger).Fatalf(format, args...) -} - -func (logger *Logger) Panicf(format string, args ...interface{}) { - NewEntry(logger).Panicf(format, args...) -} - -func (logger *Logger) Debug(args ...interface{}) { - NewEntry(logger).Debug(args...) -} - -func (logger *Logger) Info(args ...interface{}) { - NewEntry(logger).Info(args...) -} - -func (logger *Logger) Print(args ...interface{}) { - NewEntry(logger).Info(args...) -} - -func (logger *Logger) Warn(args ...interface{}) { - NewEntry(logger).Warn(args...) -} - -func (logger *Logger) Warning(args ...interface{}) { - NewEntry(logger).Warn(args...) -} - -func (logger *Logger) Error(args ...interface{}) { - NewEntry(logger).Error(args...) -} - -func (logger *Logger) Fatal(args ...interface{}) { - NewEntry(logger).Fatal(args...) -} - -func (logger *Logger) Panic(args ...interface{}) { - NewEntry(logger).Panic(args...) -} - -func (logger *Logger) Debugln(args ...interface{}) { - NewEntry(logger).Debugln(args...) -} - -func (logger *Logger) Infoln(args ...interface{}) { - NewEntry(logger).Infoln(args...) -} - -func (logger *Logger) Println(args ...interface{}) { - NewEntry(logger).Println(args...) -} - -func (logger *Logger) Warnln(args ...interface{}) { - NewEntry(logger).Warnln(args...) -} - -func (logger *Logger) Warningln(args ...interface{}) { - NewEntry(logger).Warnln(args...) -} - -func (logger *Logger) Errorln(args ...interface{}) { - NewEntry(logger).Errorln(args...) -} - -func (logger *Logger) Fatalln(args ...interface{}) { - NewEntry(logger).Fatalln(args...) -} - -func (logger *Logger) Panicln(args ...interface{}) { - NewEntry(logger).Panicln(args...) -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go deleted file mode 100644 index 43ee12e90e..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go +++ /dev/null @@ -1,94 +0,0 @@ -package logrus - -import ( - "fmt" - "log" -) - -// Fields type, used to pass to `WithFields`. -type Fields map[string]interface{} - -// Level type -type Level uint8 - -// Convert the Level to a string. E.g. PanicLevel becomes "panic". -func (level Level) String() string { - switch level { - case DebugLevel: - return "debug" - case InfoLevel: - return "info" - case WarnLevel: - return "warning" - case ErrorLevel: - return "error" - case FatalLevel: - return "fatal" - case PanicLevel: - return "panic" - } - - return "unknown" -} - -// ParseLevel takes a string level and returns the Logrus log level constant. -func ParseLevel(lvl string) (Level, error) { - switch lvl { - case "panic": - return PanicLevel, nil - case "fatal": - return FatalLevel, nil - case "error": - return ErrorLevel, nil - case "warn", "warning": - return WarnLevel, nil - case "info": - return InfoLevel, nil - case "debug": - return DebugLevel, nil - } - - var l Level - return l, fmt.Errorf("not a valid logrus Level: %q", lvl) -} - -// These are the different logging levels. You can set the logging level to log -// on your instance of logger, obtained with `logrus.New()`. -const ( - // PanicLevel level, highest level of severity. Logs and then calls panic with the - // message passed to Debug, Info, ... - PanicLevel Level = iota - // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the - // logging level is set to Panic. - FatalLevel - // ErrorLevel level. Logs. Used for errors that should definitely be noted. - // Commonly used for hooks to send errors to an error tracking service. - ErrorLevel - // WarnLevel level. Non-critical entries that deserve eyes. - WarnLevel - // InfoLevel level. General operational entries about what's going on inside the - // application. - InfoLevel - // DebugLevel level. Usually only enabled when debugging. Very verbose logging. - DebugLevel -) - -// Won't compile if StdLogger can't be realized by a log.Logger -var _ StdLogger = &log.Logger{} - -// StdLogger is what your logrus-enabled library should take, that way -// it'll accept a stdlib logger and a logrus logger. There's no standard -// interface, this is the closest we get, unfortunately. -type StdLogger interface { - Print(...interface{}) - Printf(string, ...interface{}) - Println(...interface{}) - - Fatal(...interface{}) - Fatalf(string, ...interface{}) - Fatalln(...interface{}) - - Panic(...interface{}) - Panicf(string, ...interface{}) - Panicln(...interface{}) -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus_test.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus_test.go deleted file mode 100644 index 15157d172d..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus_test.go +++ /dev/null @@ -1,247 +0,0 @@ -package logrus - -import ( - "bytes" - "encoding/json" - "strconv" - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) { - var buffer bytes.Buffer - var fields Fields - - logger := New() - logger.Out = &buffer - logger.Formatter = new(JSONFormatter) - - log(logger) - - err := json.Unmarshal(buffer.Bytes(), &fields) - assert.Nil(t, err) - - assertions(fields) -} - -func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) { - var buffer bytes.Buffer - - logger := New() - logger.Out = &buffer - logger.Formatter = &TextFormatter{ - DisableColors: true, - } - - log(logger) - - fields := make(map[string]string) - for _, kv := range strings.Split(buffer.String(), " ") { - if !strings.Contains(kv, "=") { - continue - } - kvArr := strings.Split(kv, "=") - key := strings.TrimSpace(kvArr[0]) - val, err := strconv.Unquote(kvArr[1]) - assert.NoError(t, err) - fields[key] = val - } - assertions(fields) -} - -func TestPrint(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Print("test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test") - assert.Equal(t, fields["level"], "info") - }) -} - -func TestInfo(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Info("test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test") - assert.Equal(t, fields["level"], "info") - }) -} - -func TestWarn(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Warn("test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test") - assert.Equal(t, fields["level"], "warning") - }) -} - -func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Infoln("test", "test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test test") - }) -} - -func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Infoln("test", 10) - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test 10") - }) -} - -func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Infoln(10, 10) - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "10 10") - }) -} - -func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Infoln(10, 10) - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "10 10") - }) -} - -func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Info("test", 10) - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test10") - }) -} - -func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.Info("test", "test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "testtest") - }) -} - -func TestWithFieldsShouldAllowAssignments(t *testing.T) { - var buffer bytes.Buffer - var fields Fields - - logger := New() - logger.Out = &buffer - logger.Formatter = new(JSONFormatter) - - localLog := logger.WithFields(Fields{ - "key1": "value1", - }) - - localLog.WithField("key2", "value2").Info("test") - err := json.Unmarshal(buffer.Bytes(), &fields) - assert.Nil(t, err) - - assert.Equal(t, "value2", fields["key2"]) - assert.Equal(t, "value1", fields["key1"]) - - buffer = bytes.Buffer{} - fields = Fields{} - localLog.Info("test") - err = json.Unmarshal(buffer.Bytes(), &fields) - assert.Nil(t, err) - - _, ok := fields["key2"] - assert.Equal(t, false, ok) - assert.Equal(t, "value1", fields["key1"]) -} - -func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.WithField("msg", "hello").Info("test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test") - }) -} - -func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.WithField("msg", "hello").Info("test") - }, func(fields Fields) { - assert.Equal(t, fields["msg"], "test") - assert.Equal(t, fields["fields.msg"], "hello") - }) -} - -func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.WithField("time", "hello").Info("test") - }, func(fields Fields) { - assert.Equal(t, fields["fields.time"], "hello") - }) -} - -func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) { - LogAndAssertJSON(t, func(log *Logger) { - log.WithField("level", 1).Info("test") - }, func(fields Fields) { - assert.Equal(t, fields["level"], "info") - assert.Equal(t, fields["fields.level"], 1) - }) -} - -func TestDefaultFieldsAreNotPrefixed(t *testing.T) { - LogAndAssertText(t, func(log *Logger) { - ll := log.WithField("herp", "derp") - ll.Info("hello") - ll.Info("bye") - }, func(fields map[string]string) { - for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} { - if _, ok := fields[fieldName]; ok { - t.Fatalf("should not have prefixed %q: %v", fieldName, fields) - } - } - }) -} - -func TestConvertLevelToString(t *testing.T) { - assert.Equal(t, "debug", DebugLevel.String()) - assert.Equal(t, "info", InfoLevel.String()) - assert.Equal(t, "warning", WarnLevel.String()) - assert.Equal(t, "error", ErrorLevel.String()) - assert.Equal(t, "fatal", FatalLevel.String()) - assert.Equal(t, "panic", PanicLevel.String()) -} - -func TestParseLevel(t *testing.T) { - l, err := ParseLevel("panic") - assert.Nil(t, err) - assert.Equal(t, PanicLevel, l) - - l, err = ParseLevel("fatal") - assert.Nil(t, err) - assert.Equal(t, FatalLevel, l) - - l, err = ParseLevel("error") - assert.Nil(t, err) - assert.Equal(t, ErrorLevel, l) - - l, err = ParseLevel("warn") - assert.Nil(t, err) - assert.Equal(t, WarnLevel, l) - - l, err = ParseLevel("warning") - assert.Nil(t, err) - assert.Equal(t, WarnLevel, l) - - l, err = ParseLevel("info") - assert.Nil(t, err) - assert.Equal(t, InfoLevel, l) - - l, err = ParseLevel("debug") - assert.Nil(t, err) - assert.Equal(t, DebugLevel, l) - - l, err = ParseLevel("invalid") - assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error()) -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go deleted file mode 100644 index 8fe02a4aec..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go +++ /dev/null @@ -1,12 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logrus - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA - -type Termios syscall.Termios diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go deleted file mode 100644 index 0428ee5d52..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go +++ /dev/null @@ -1,20 +0,0 @@ -/* - Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin. -*/ -package logrus - -import ( - "syscall" -) - -const ioctlReadTermios = syscall.TIOCGETA - -type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [20]uint8 - Ispeed uint32 - Ospeed uint32 -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go deleted file mode 100644 index a2c0b40db6..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logrus - -import "syscall" - -const ioctlReadTermios = syscall.TCGETS - -type Termios syscall.Termios diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go deleted file mode 100644 index 276447bd5c..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go +++ /dev/null @@ -1,21 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux,!appengine darwin freebsd - -package logrus - -import ( - "syscall" - "unsafe" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stdout - var termios Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go deleted file mode 100644 index 2e09f6f7e3..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows - -package logrus - -import ( - "syscall" - "unsafe" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stdout - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go b/Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go deleted file mode 100644 index fc0a4082a7..0000000000 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go +++ /dev/null @@ -1,95 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "sort" - "strings" - "time" -) - -const ( - nocolor = 0 - red = 31 - green = 32 - yellow = 33 - blue = 34 -) - -var ( - baseTimestamp time.Time - isTerminal bool -) - -func init() { - baseTimestamp = time.Now() - isTerminal = IsTerminal() -} - -func miniTS() int { - return int(time.Since(baseTimestamp) / time.Second) -} - -type TextFormatter struct { - // Set to true to bypass checking for a TTY before outputting colors. - ForceColors bool - DisableColors bool -} - -func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - - var keys []string - for k := range entry.Data { - keys = append(keys, k) - } - sort.Strings(keys) - - b := &bytes.Buffer{} - - prefixFieldClashes(entry) - - isColored := (f.ForceColors || isTerminal) && !f.DisableColors - - if isColored { - printColored(b, entry, keys) - } else { - f.appendKeyValue(b, "time", entry.Time.Format(time.RFC3339)) - f.appendKeyValue(b, "level", entry.Level.String()) - f.appendKeyValue(b, "msg", entry.Message) - for _, key := range keys { - f.appendKeyValue(b, key, entry.Data[key]) - } - } - - b.WriteByte('\n') - return b.Bytes(), nil -} - -func printColored(b *bytes.Buffer, entry *Entry, keys []string) { - var levelColor int - switch entry.Level { - case WarnLevel: - levelColor = yellow - case ErrorLevel, FatalLevel, PanicLevel: - levelColor = red - default: - levelColor = blue - } - - levelText := strings.ToUpper(entry.Level.String())[0:4] - - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) - for _, k := range keys { - v := entry.Data[k] - fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v) - } -} - -func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key, value interface{}) { - switch value.(type) { - case string, error: - fmt.Fprintf(b, "%v=%q ", key, value) - default: - fmt.Fprintf(b, "%v=%v ", key, value) - } -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml b/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml deleted file mode 100644 index baf46abc6f..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go -go: 1.1 - -script: -- go vet ./... -- go test -v ./... diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/README.md b/Godeps/_workspace/src/github.com/codegangsta/cli/README.md deleted file mode 100644 index 0e8327b8b3..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/README.md +++ /dev/null @@ -1,298 +0,0 @@ -[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli) - -# cli.go -cli.go is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. - -You can view the API docs here: -http://godoc.org/github.com/codegangsta/cli - -## Overview -Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app. - -**This is where cli.go comes into play.** cli.go makes command line programming fun, organized, and expressive! - -## Installation -Make sure you have a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html). - -To install `cli.go`, simply run: -``` -$ go get github.com/codegangsta/cli -``` - -Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used: -``` -export PATH=$PATH:$GOPATH/bin -``` - -## Getting Started -One of the philosophies behind cli.go is that an API should be playful and full of discovery. So a cli.go app can be as little as one line of code in `main()`. - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - cli.NewApp().Run(os.Args) -} -``` - -This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation: - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "boom" - app.Usage = "make an explosive entrance" - app.Action = func(c *cli.Context) { - println("boom! I say!") - } - - app.Run(os.Args) -} -``` - -Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below. - -## Example - -Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness! - -Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it: - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "greet" - app.Usage = "fight the loneliness!" - app.Action = func(c *cli.Context) { - println("Hello friend!") - } - - app.Run(os.Args) -} -``` - -Install our command to the `$GOPATH/bin` directory: - -``` -$ go install -``` - -Finally run our new command: - -``` -$ greet -Hello friend! -``` - -cli.go also generates some bitchass help text: -``` -$ greet help -NAME: - greet - fight the loneliness! - -USAGE: - greet [global options] command [command options] [arguments...] - -VERSION: - 0.0.0 - -COMMANDS: - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS - --version Shows version information -``` - -### Arguments -You can lookup arguments by calling the `Args` function on `cli.Context`. - -``` go -... -app.Action = func(c *cli.Context) { - println("Hello", c.Args()[0]) -} -... -``` - -### Flags -Setting and querying flags is simple. -``` go -... -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - }, -} -app.Action = func(c *cli.Context) { - name := "someone" - if len(c.Args()) > 0 { - name = c.Args()[0] - } - if c.String("lang") == "spanish" { - println("Hola", name) - } else { - println("Hello", name) - } -} -... -``` - -#### Alternate Names - -You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g. - -``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - }, -} -``` - -That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error. - -#### Values from the Environment - -You can also have the default value set from the environment via `EnvVar`. e.g. - -``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "APP_LANG", - }, -} -``` - -The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default. - -``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG", - }, -} -``` - -### Subcommands - -Subcommands can be defined for a more git-like command line app. -```go -... -app.Commands = []cli.Command{ - { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) - }, - }, - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - }, - { - Name: "template", - ShortName: "r", - Usage: "options for task templates", - Subcommands: []cli.Command{ - { - Name: "add", - Usage: "add a new template", - Action: func(c *cli.Context) { - println("new task template: ", c.Args().First()) - }, - }, - { - Name: "remove", - Usage: "remove an existing template", - Action: func(c *cli.Context) { - println("removed task template: ", c.Args().First()) - }, - }, - }, - }, -} -... -``` - -### Bash Completion - -You can enable completion commands by setting the `EnableBashCompletion` -flag on the `App` object. By default, this setting will only auto-complete to -show an app's subcommands, but you can write your own completion methods for -the App or its subcommands. -```go -... -var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"} -app := cli.NewApp() -app.EnableBashCompletion = true -app.Commands = []cli.Command{ - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - BashComplete: func(c *cli.Context) { - // This will complete if no args are passed - if len(c.Args()) > 0 { - return - } - for _, t := range tasks { - fmt.Println(t) - } - }, - } -} -... -``` - -#### To Enable - -Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while -setting the `PROG` variable to the name of your program: - -`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` - - -## Contribution Guidelines -Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch. - -If you are have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together. - -If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out. diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/app.go b/Godeps/_workspace/src/github.com/codegangsta/cli/app.go deleted file mode 100644 index 6422345dc2..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/app.go +++ /dev/null @@ -1,275 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "text/tabwriter" - "text/template" - "time" -) - -// App is the main structure of a cli application. It is recomended that -// and app be created with the cli.NewApp() function -type App struct { - // The name of the program. Defaults to os.Args[0] - Name string - // Description of the program. - Usage string - // Version of the program - Version string - // List of commands to execute - Commands []Command - // List of flags to parse - Flags []Flag - // Boolean to enable bash completion commands - EnableBashCompletion bool - // Boolean to hide built-in help command - HideHelp bool - // Boolean to hide built-in version flag - HideVersion bool - // An action to execute when the bash-completion flag is set - BashComplete func(context *Context) - // An action to execute before any subcommands are run, but after the context is ready - // If a non-nil error is returned, no subcommands are run - Before func(context *Context) error - // The action to execute when no subcommands are specified - Action func(context *Context) - // Execute this function if the proper command cannot be found - CommandNotFound func(context *Context, command string) - // Compilation date - Compiled time.Time - // Author - Author string - // Author e-mail - Email string - // Writer writer to write output to - Writer io.Writer -} - -// Tries to find out when this binary was compiled. -// Returns the current time if it fails to find it. -func compileTime() time.Time { - info, err := os.Stat(os.Args[0]) - if err != nil { - return time.Now() - } - return info.ModTime() -} - -// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action. -func NewApp() *App { - return &App{ - Name: os.Args[0], - Usage: "A new cli application", - Version: "0.0.0", - BashComplete: DefaultAppComplete, - Action: helpCommand.Action, - Compiled: compileTime(), - Author: "Author", - Email: "unknown@email", - Writer: os.Stdout, - } -} - -// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination -func (a *App) Run(arguments []string) error { - if HelpPrinter == nil { - defer func() { - HelpPrinter = nil - }() - - HelpPrinter = func(templ string, data interface{}) { - w := tabwriter.NewWriter(a.Writer, 0, 8, 1, '\t', 0) - t := template.Must(template.New("help").Parse(templ)) - err := t.Execute(w, data) - if err != nil { - panic(err) - } - w.Flush() - } - } - - // append help to commands - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { - a.appendFlag(HelpFlag) - } - } - - //append version/help flags - if a.EnableBashCompletion { - a.appendFlag(BashCompletionFlag) - } - - if !a.HideVersion { - a.appendFlag(VersionFlag) - } - - // parse flags - set := flagSet(a.Name, a.Flags) - set.SetOutput(ioutil.Discard) - err := set.Parse(arguments[1:]) - nerr := normalizeFlags(a.Flags, set) - if nerr != nil { - fmt.Fprintln(a.Writer, nerr) - context := NewContext(a, set, set) - ShowAppHelp(context) - fmt.Fprintln(a.Writer) - return nerr - } - context := NewContext(a, set, set) - - if err != nil { - fmt.Fprintf(a.Writer, "Incorrect Usage.\n\n") - ShowAppHelp(context) - fmt.Fprintln(a.Writer) - return err - } - - if checkCompletions(context) { - return nil - } - - if checkHelp(context) { - return nil - } - - if checkVersion(context) { - return nil - } - - if a.Before != nil { - err := a.Before(context) - if err != nil { - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - a.Action(context) - return nil -} - -// Another entry point to the cli app, takes care of passing arguments and error handling -func (a *App) RunAndExitOnError() { - if err := a.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags -func (a *App) RunAsSubcommand(ctx *Context) error { - // append help to commands - if len(a.Commands) > 0 { - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { - a.appendFlag(HelpFlag) - } - } - } - - // append flags - if a.EnableBashCompletion { - a.appendFlag(BashCompletionFlag) - } - - // parse flags - set := flagSet(a.Name, a.Flags) - set.SetOutput(ioutil.Discard) - err := set.Parse(ctx.Args().Tail()) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, ctx.globalSet) - - if nerr != nil { - fmt.Fprintln(a.Writer, nerr) - if len(a.Commands) > 0 { - ShowSubcommandHelp(context) - } else { - ShowCommandHelp(ctx, context.Args().First()) - } - fmt.Fprintln(a.Writer) - return nerr - } - - if err != nil { - fmt.Fprintf(a.Writer, "Incorrect Usage.\n\n") - ShowSubcommandHelp(context) - return err - } - - if checkCompletions(context) { - return nil - } - - if len(a.Commands) > 0 { - if checkSubcommandHelp(context) { - return nil - } - } else { - if checkCommandHelp(ctx, context.Args().First()) { - return nil - } - } - - if a.Before != nil { - err := a.Before(context) - if err != nil { - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - a.Action(context) - - return nil -} - -// Returns the named command on App. Returns nil if the command does not exist -func (a *App) Command(name string) *Command { - for _, c := range a.Commands { - if c.HasName(name) { - return &c - } - } - - return nil -} - -func (a *App) hasFlag(flag Flag) bool { - for _, f := range a.Flags { - if flag == f { - return true - } - } - - return false -} - -func (a *App) appendFlag(flag Flag) { - if !a.hasFlag(flag) { - a.Flags = append(a.Flags, flag) - } -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go deleted file mode 100644 index 2cbb0e3a17..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go +++ /dev/null @@ -1,554 +0,0 @@ -package cli_test - -import ( - "flag" - "fmt" - "os" - "testing" - - "github.com/codegangsta/cli" -) - -func ExampleApp() { - // set args for examples sake - os.Args = []string{"greet", "--name", "Jeremy"} - - app := cli.NewApp() - app.Name = "greet" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, - } - app.Action = func(c *cli.Context) { - fmt.Printf("Hello %v\n", c.String("name")) - } - app.Run(os.Args) - // Output: - // Hello Jeremy -} - -func ExampleAppSubcommand() { - // set args for examples sake - os.Args = []string{"say", "hi", "english", "--name", "Jeremy"} - app := cli.NewApp() - app.Name = "say" - app.Commands = []cli.Command{ - { - Name: "hello", - ShortName: "hi", - Usage: "use it to see a description", - Description: "This is how we describe hello the function", - Subcommands: []cli.Command{ - { - Name: "english", - ShortName: "en", - Usage: "sends a greeting in english", - Description: "greets someone in english", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "name", - Value: "Bob", - Usage: "Name of the person to greet", - }, - }, - Action: func(c *cli.Context) { - fmt.Println("Hello,", c.String("name")) - }, - }, - }, - }, - } - - app.Run(os.Args) - // Output: - // Hello, Jeremy -} - -func ExampleAppHelp() { - // set args for examples sake - os.Args = []string{"greet", "h", "describeit"} - - app := cli.NewApp() - app.Name = "greet" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, - } - app.Commands = []cli.Command{ - { - Name: "describeit", - ShortName: "d", - Usage: "use it to see a description", - Description: "This is how we describe describeit the function", - Action: func(c *cli.Context) { - fmt.Printf("i like to describe things") - }, - }, - } - app.Run(os.Args) - // Output: - // NAME: - // describeit - use it to see a description - // - // USAGE: - // command describeit [arguments...] - // - // DESCRIPTION: - // This is how we describe describeit the function -} - -func ExampleAppBashComplete() { - // set args for examples sake - os.Args = []string{"greet", "--generate-bash-completion"} - - app := cli.NewApp() - app.Name = "greet" - app.EnableBashCompletion = true - app.Commands = []cli.Command{ - { - Name: "describeit", - ShortName: "d", - Usage: "use it to see a description", - Description: "This is how we describe describeit the function", - Action: func(c *cli.Context) { - fmt.Printf("i like to describe things") - }, - }, { - Name: "next", - Usage: "next example", - Description: "more stuff to see when generating bash completion", - Action: func(c *cli.Context) { - fmt.Printf("the next example") - }, - }, - } - - app.Run(os.Args) - // Output: - // describeit - // d - // next - // help - // h -} - -func TestApp_Run(t *testing.T) { - s := "" - - app := cli.NewApp() - app.Action = func(c *cli.Context) { - s = s + c.Args().First() - } - - err := app.Run([]string{"command", "foo"}) - expect(t, err, nil) - err = app.Run([]string{"command", "bar"}) - expect(t, err, nil) - expect(t, s, "foobar") -} - -var commandAppTests = []struct { - name string - expected bool -}{ - {"foobar", true}, - {"batbaz", true}, - {"b", true}, - {"f", true}, - {"bat", false}, - {"nothing", false}, -} - -func TestApp_Command(t *testing.T) { - app := cli.NewApp() - fooCommand := cli.Command{Name: "foobar", ShortName: "f"} - batCommand := cli.Command{Name: "batbaz", ShortName: "b"} - app.Commands = []cli.Command{ - fooCommand, - batCommand, - } - - for _, test := range commandAppTests { - expect(t, app.Command(test.name) != nil, test.expected) - } -} - -func TestApp_CommandWithArgBeforeFlags(t *testing.T) { - var parsedOption, firstArg string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.StringFlag{Name: "option", Value: "", Usage: "some option"}, - }, - Action: func(c *cli.Context) { - parsedOption = c.String("option") - firstArg = c.Args().First() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"}) - - expect(t, parsedOption, "my-option") - expect(t, firstArg, "my-arg") -} - -func TestApp_RunAsSubcommandParseFlags(t *testing.T) { - var context *cli.Context - - a := cli.NewApp() - a.Commands = []cli.Command{ - { - Name: "foo", - Action: func(c *cli.Context) { - context = c - }, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - }, - }, - Before: func(_ *cli.Context) error { return nil }, - }, - } - a.Run([]string{"", "foo", "--lang", "spanish", "abcd"}) - - expect(t, context.Args().Get(0), "abcd") - expect(t, context.String("lang"), "spanish") -} - -func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) { - var parsedOption string - var args []string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.StringFlag{Name: "option", Value: "", Usage: "some option"}, - }, - Action: func(c *cli.Context) { - parsedOption = c.String("option") - args = c.Args() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"}) - - expect(t, parsedOption, "my-option") - expect(t, args[0], "my-arg") - expect(t, args[1], "--") - expect(t, args[2], "--notARealFlag") -} - -func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) { - var args []string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Action: func(c *cli.Context) { - args = c.Args() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"}) - - expect(t, args[0], "my-arg") - expect(t, args[1], "--") - expect(t, args[2], "notAFlagAtAll") -} - -func TestApp_Float64Flag(t *testing.T) { - var meters float64 - - app := cli.NewApp() - app.Flags = []cli.Flag{ - cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"}, - } - app.Action = func(c *cli.Context) { - meters = c.Float64("height") - } - - app.Run([]string{"", "--height", "1.93"}) - expect(t, meters, 1.93) -} - -func TestApp_ParseSliceFlags(t *testing.T) { - var parsedOption, firstArg string - var parsedIntSlice []int - var parsedStringSlice []string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"}, - cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"}, - }, - Action: func(c *cli.Context) { - parsedIntSlice = c.IntSlice("p") - parsedStringSlice = c.StringSlice("ip") - parsedOption = c.String("option") - firstArg = c.Args().First() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"}) - - IntsEquals := func(a, b []int) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true - } - - StrsEquals := func(a, b []string) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true - } - var expectedIntSlice = []int{22, 80} - var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"} - - if !IntsEquals(parsedIntSlice, expectedIntSlice) { - t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice) - } - - if !StrsEquals(parsedStringSlice, expectedStringSlice) { - t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice) - } -} - -func TestApp_DefaultStdout(t *testing.T) { - app := cli.NewApp() - - if app.Writer != os.Stdout { - t.Error("Default output writer not set.") - } -} - -type mockWriter struct { - written []byte -} - -func (fw *mockWriter) Write(p []byte) (n int, err error) { - if fw.written == nil { - fw.written = p - } else { - fw.written = append(fw.written, p...) - } - - return len(p), nil -} - -func (fw *mockWriter) GetWritten() (b []byte) { - return fw.written -} - -func TestApp_SetStdout(t *testing.T) { - w := &mockWriter{} - - app := cli.NewApp() - app.Name = "test" - app.Writer = w - - err := app.Run([]string{"help"}) - - if err != nil { - t.Fatalf("Run error: %s", err) - } - - if len(w.written) == 0 { - t.Error("App did not write output to desired writer.") - } -} - -func TestApp_BeforeFunc(t *testing.T) { - beforeRun, subcommandRun := false, false - beforeError := fmt.Errorf("fail") - var err error - - app := cli.NewApp() - - app.Before = func(c *cli.Context) error { - beforeRun = true - s := c.String("opt") - if s == "fail" { - return beforeError - } - - return nil - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "sub", - Action: func(c *cli.Context) { - subcommandRun = true - }, - }, - } - - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "opt"}, - } - - // run with the Before() func succeeding - err = app.Run([]string{"command", "--opt", "succeed", "sub"}) - - if err != nil { - t.Fatalf("Run error: %s", err) - } - - if beforeRun == false { - t.Errorf("Before() not executed when expected") - } - - if subcommandRun == false { - t.Errorf("Subcommand not executed when expected") - } - - // reset - beforeRun, subcommandRun = false, false - - // run with the Before() func failing - err = app.Run([]string{"command", "--opt", "fail", "sub"}) - - // should be the same error produced by the Before func - if err != beforeError { - t.Errorf("Run error expected, but not received") - } - - if beforeRun == false { - t.Errorf("Before() not executed when expected") - } - - if subcommandRun == true { - t.Errorf("Subcommand executed when NOT expected") - } - -} - -func TestAppNoHelpFlag(t *testing.T) { - oldFlag := cli.HelpFlag - defer func() { - cli.HelpFlag = oldFlag - }() - - cli.HelpFlag = cli.BoolFlag{} - - app := cli.NewApp() - err := app.Run([]string{"test", "-h"}) - - if err != flag.ErrHelp { - t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err) - } -} - -func TestAppHelpPrinter(t *testing.T) { - oldPrinter := cli.HelpPrinter - defer func() { - cli.HelpPrinter = oldPrinter - }() - - var wasCalled = false - cli.HelpPrinter = func(template string, data interface{}) { - wasCalled = true - } - - app := cli.NewApp() - app.Run([]string{"-h"}) - - if wasCalled == false { - t.Errorf("Help printer expected to be called, but was not") - } -} - -func TestAppVersionPrinter(t *testing.T) { - oldPrinter := cli.VersionPrinter - defer func() { - cli.VersionPrinter = oldPrinter - }() - - var wasCalled = false - cli.VersionPrinter = func(c *cli.Context) { - wasCalled = true - } - - app := cli.NewApp() - ctx := cli.NewContext(app, nil, nil) - cli.ShowVersion(ctx) - - if wasCalled == false { - t.Errorf("Version printer expected to be called, but was not") - } -} - -func TestAppCommandNotFound(t *testing.T) { - beforeRun, subcommandRun := false, false - app := cli.NewApp() - - app.CommandNotFound = func(c *cli.Context, command string) { - beforeRun = true - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "bar", - Action: func(c *cli.Context) { - subcommandRun = true - }, - }, - } - - app.Run([]string{"command", "foo"}) - - expect(t, beforeRun, true) - expect(t, subcommandRun, false) -} - -func TestGlobalFlagsInSubcommands(t *testing.T) { - subcommandRun := false - app := cli.NewApp() - - app.Flags = []cli.Flag{ - cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "foo", - Subcommands: []cli.Command{ - { - Name: "bar", - Action: func(c *cli.Context) { - if c.GlobalBool("debug") { - subcommandRun = true - } - }, - }, - }, - }, - } - - app.Run([]string{"command", "-d", "foo", "bar"}) - - expect(t, subcommandRun, true) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete b/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete deleted file mode 100644 index 9b55dd990c..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/bash - -_cli_bash_autocomplete() { - local cur prev opts base - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - } - - complete -F _cli_bash_autocomplete $PROG \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete b/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete deleted file mode 100644 index 5430a18f95..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete +++ /dev/null @@ -1,5 +0,0 @@ -autoload -U compinit && compinit -autoload -U bashcompinit && bashcompinit - -script_dir=$(dirname $0) -source ${script_dir}/bash_autocomplete diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go b/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go deleted file mode 100644 index b742545812..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go +++ /dev/null @@ -1,19 +0,0 @@ -// Package cli provides a minimal framework for creating and organizing command line -// Go applications. cli is designed to be easy to understand and write, the most simple -// cli application can be written as follows: -// func main() { -// cli.NewApp().Run(os.Args) -// } -// -// Of course this application does not do much, so let's make this an actual application: -// func main() { -// app := cli.NewApp() -// app.Name = "greet" -// app.Usage = "say a greeting" -// app.Action = func(c *cli.Context) { -// println("Greetings") -// } -// -// app.Run(os.Args) -// } -package cli diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go deleted file mode 100644 index 879a793dc2..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package cli_test - -import ( - "os" - - "github.com/codegangsta/cli" -) - -func Example() { - app := cli.NewApp() - app.Name = "todo" - app.Usage = "task list on the command line" - app.Commands = []cli.Command{ - { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) - }, - }, - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - }, - } - - app.Run(os.Args) -} - -func ExampleSubcommand() { - app := cli.NewApp() - app.Name = "say" - app.Commands = []cli.Command{ - { - Name: "hello", - ShortName: "hi", - Usage: "use it to see a description", - Description: "This is how we describe hello the function", - Subcommands: []cli.Command{ - { - Name: "english", - ShortName: "en", - Usage: "sends a greeting in english", - Description: "greets someone in english", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "name", - Value: "Bob", - Usage: "Name of the person to greet", - }, - }, - Action: func(c *cli.Context) { - println("Hello, ", c.String("name")) - }, - }, { - Name: "spanish", - ShortName: "sp", - Usage: "sends a greeting in spanish", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "surname", - Value: "Jones", - Usage: "Surname of the person to greet", - }, - }, - Action: func(c *cli.Context) { - println("Hola, ", c.String("surname")) - }, - }, { - Name: "french", - ShortName: "fr", - Usage: "sends a greeting in french", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "nickname", - Value: "Stevie", - Usage: "Nickname of the person to greet", - }, - }, - Action: func(c *cli.Context) { - println("Bonjour, ", c.String("nickname")) - }, - }, - }, - }, { - Name: "bye", - Usage: "says goodbye", - Action: func(c *cli.Context) { - println("bye") - }, - }, - } - - app.Run(os.Args) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/command.go b/Godeps/_workspace/src/github.com/codegangsta/cli/command.go deleted file mode 100644 index ffd3ef81d3..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/command.go +++ /dev/null @@ -1,156 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "strings" -) - -// Command is a subcommand for a cli.App. -type Command struct { - // The name of the command - Name string - // short name of the command. Typically one character - ShortName string - // A short description of the usage of this command - Usage string - // A longer explanation of how the command works - Description string - // The function to call when checking for bash command completions - BashComplete func(context *Context) - // An action to execute before any sub-subcommands are run, but after the context is ready - // If a non-nil error is returned, no sub-subcommands are run - Before func(context *Context) error - // The function to call when this command is invoked - Action func(context *Context) - // List of child commands - Subcommands []Command - // List of flags to parse - Flags []Flag - // Treat all flags as normal arguments if true - SkipFlagParsing bool - // Boolean to hide built-in help command - HideHelp bool -} - -// Invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c Command) Run(ctx *Context) error { - - if len(c.Subcommands) > 0 || c.Before != nil { - return c.startApp(ctx) - } - - if !c.HideHelp && (HelpFlag != BoolFlag{}) { - // append help to flags - c.Flags = append( - c.Flags, - HelpFlag, - ) - } - - if ctx.App.EnableBashCompletion { - c.Flags = append(c.Flags, BashCompletionFlag) - } - - set := flagSet(c.Name, c.Flags) - set.SetOutput(ioutil.Discard) - - firstFlagIndex := -1 - terminatorIndex := -1 - for index, arg := range ctx.Args() { - if arg == "--" { - terminatorIndex = index - break - } else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 { - firstFlagIndex = index - } - } - - var err error - if firstFlagIndex > -1 && !c.SkipFlagParsing { - args := ctx.Args() - regularArgs := make([]string, len(args[1:firstFlagIndex])) - copy(regularArgs, args[1:firstFlagIndex]) - - var flagArgs []string - if terminatorIndex > -1 { - flagArgs = args[firstFlagIndex:terminatorIndex] - regularArgs = append(regularArgs, args[terminatorIndex:]...) - } else { - flagArgs = args[firstFlagIndex:] - } - - err = set.Parse(append(flagArgs, regularArgs...)) - } else { - err = set.Parse(ctx.Args().Tail()) - } - - if err != nil { - fmt.Fprint(ctx.App.Writer, "Incorrect Usage.\n\n") - ShowCommandHelp(ctx, c.Name) - fmt.Fprintln(ctx.App.Writer) - return err - } - - nerr := normalizeFlags(c.Flags, set) - if nerr != nil { - fmt.Fprintln(ctx.App.Writer, nerr) - fmt.Fprintln(ctx.App.Writer) - ShowCommandHelp(ctx, c.Name) - fmt.Fprintln(ctx.App.Writer) - return nerr - } - context := NewContext(ctx.App, set, ctx.globalSet) - - if checkCommandCompletions(context, c.Name) { - return nil - } - - if checkCommandHelp(context, c.Name) { - return nil - } - context.Command = c - c.Action(context) - return nil -} - -// Returns true if Command.Name or Command.ShortName matches given name -func (c Command) HasName(name string) bool { - return c.Name == name || c.ShortName == name -} - -func (c Command) startApp(ctx *Context) error { - app := NewApp() - - // set the name and usage - app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) - if c.Description != "" { - app.Usage = c.Description - } else { - app.Usage = c.Usage - } - - // set CommandNotFound - app.CommandNotFound = ctx.App.CommandNotFound - - // set the flags and commands - app.Commands = c.Subcommands - app.Flags = c.Flags - app.HideHelp = c.HideHelp - - // bash completion - app.EnableBashCompletion = ctx.App.EnableBashCompletion - if c.BashComplete != nil { - app.BashComplete = c.BashComplete - } - - // set the actions - app.Before = c.Before - if c.Action != nil { - app.Action = c.Action - } else { - app.Action = helpSubcommand.Action - } - - return app.RunAsSubcommand(ctx) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go deleted file mode 100644 index c0f556ad24..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package cli_test - -import ( - "flag" - "testing" - - "github.com/codegangsta/cli" -) - -func TestCommandDoNotIgnoreFlags(t *testing.T) { - app := cli.NewApp() - set := flag.NewFlagSet("test", 0) - test := []string{"blah", "blah", "-break"} - set.Parse(test) - - c := cli.NewContext(app, set, set) - - command := cli.Command{ - Name: "test-cmd", - ShortName: "tc", - Usage: "this is for testing", - Description: "testing", - Action: func(_ *cli.Context) {}, - } - err := command.Run(c) - - expect(t, err.Error(), "flag provided but not defined: -break") -} - -func TestCommandIgnoreFlags(t *testing.T) { - app := cli.NewApp() - set := flag.NewFlagSet("test", 0) - test := []string{"blah", "blah"} - set.Parse(test) - - c := cli.NewContext(app, set, set) - - command := cli.Command{ - Name: "test-cmd", - ShortName: "tc", - Usage: "this is for testing", - Description: "testing", - Action: func(_ *cli.Context) {}, - SkipFlagParsing: true, - } - err := command.Run(c) - - expect(t, err, nil) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/context.go b/Godeps/_workspace/src/github.com/codegangsta/cli/context.go deleted file mode 100644 index c9f645b189..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/context.go +++ /dev/null @@ -1,339 +0,0 @@ -package cli - -import ( - "errors" - "flag" - "strconv" - "strings" - "time" -) - -// Context is a type that is passed through to -// each Handler action in a cli application. Context -// can be used to retrieve context-specific Args and -// parsed command-line options. -type Context struct { - App *App - Command Command - flagSet *flag.FlagSet - globalSet *flag.FlagSet - setFlags map[string]bool - globalSetFlags map[string]bool -} - -// Creates a new context. For use in when invoking an App or Command action. -func NewContext(app *App, set *flag.FlagSet, globalSet *flag.FlagSet) *Context { - return &Context{App: app, flagSet: set, globalSet: globalSet} -} - -// Looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Int(name string) int { - return lookupInt(name, c.flagSet) -} - -// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists -func (c *Context) Duration(name string) time.Duration { - return lookupDuration(name, c.flagSet) -} - -// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists -func (c *Context) Float64(name string) float64 { - return lookupFloat64(name, c.flagSet) -} - -// Looks up the value of a local bool flag, returns false if no bool flag exists -func (c *Context) Bool(name string) bool { - return lookupBool(name, c.flagSet) -} - -// Looks up the value of a local boolT flag, returns false if no bool flag exists -func (c *Context) BoolT(name string) bool { - return lookupBoolT(name, c.flagSet) -} - -// Looks up the value of a local string flag, returns "" if no string flag exists -func (c *Context) String(name string) string { - return lookupString(name, c.flagSet) -} - -// Looks up the value of a local string slice flag, returns nil if no string slice flag exists -func (c *Context) StringSlice(name string) []string { - return lookupStringSlice(name, c.flagSet) -} - -// Looks up the value of a local int slice flag, returns nil if no int slice flag exists -func (c *Context) IntSlice(name string) []int { - return lookupIntSlice(name, c.flagSet) -} - -// Looks up the value of a local generic flag, returns nil if no generic flag exists -func (c *Context) Generic(name string) interface{} { - return lookupGeneric(name, c.flagSet) -} - -// Looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalInt(name string) int { - return lookupInt(name, c.globalSet) -} - -// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists -func (c *Context) GlobalDuration(name string) time.Duration { - return lookupDuration(name, c.globalSet) -} - -// Looks up the value of a global bool flag, returns false if no bool flag exists -func (c *Context) GlobalBool(name string) bool { - return lookupBool(name, c.globalSet) -} - -// Looks up the value of a global string flag, returns "" if no string flag exists -func (c *Context) GlobalString(name string) string { - return lookupString(name, c.globalSet) -} - -// Looks up the value of a global string slice flag, returns nil if no string slice flag exists -func (c *Context) GlobalStringSlice(name string) []string { - return lookupStringSlice(name, c.globalSet) -} - -// Looks up the value of a global int slice flag, returns nil if no int slice flag exists -func (c *Context) GlobalIntSlice(name string) []int { - return lookupIntSlice(name, c.globalSet) -} - -// Looks up the value of a global generic flag, returns nil if no generic flag exists -func (c *Context) GlobalGeneric(name string) interface{} { - return lookupGeneric(name, c.globalSet) -} - -// Determines if the flag was actually set -func (c *Context) IsSet(name string) bool { - if c.setFlags == nil { - c.setFlags = make(map[string]bool) - c.flagSet.Visit(func(f *flag.Flag) { - c.setFlags[f.Name] = true - }) - } - return c.setFlags[name] == true -} - -// Determines if the global flag was actually set -func (c *Context) GlobalIsSet(name string) bool { - if c.globalSetFlags == nil { - c.globalSetFlags = make(map[string]bool) - c.globalSet.Visit(func(f *flag.Flag) { - c.globalSetFlags[f.Name] = true - }) - } - return c.globalSetFlags[name] == true -} - -// Returns a slice of flag names used in this context. -func (c *Context) FlagNames() (names []string) { - for _, flag := range c.Command.Flags { - name := strings.Split(flag.getName(), ",")[0] - if name == "help" { - continue - } - names = append(names, name) - } - return -} - -// Returns a slice of global flag names used by the app. -func (c *Context) GlobalFlagNames() (names []string) { - for _, flag := range c.App.Flags { - name := strings.Split(flag.getName(), ",")[0] - if name == "help" || name == "version" { - continue - } - names = append(names, name) - } - return -} - -type Args []string - -// Returns the command line arguments associated with the context. -func (c *Context) Args() Args { - args := Args(c.flagSet.Args()) - return args -} - -// Returns the nth argument, or else a blank string -func (a Args) Get(n int) string { - if len(a) > n { - return a[n] - } - return "" -} - -// Returns the first argument, or else a blank string -func (a Args) First() string { - return a.Get(0) -} - -// Return the rest of the arguments (not the first one) -// or else an empty string slice -func (a Args) Tail() []string { - if len(a) >= 2 { - return []string(a)[1:] - } - return []string{} -} - -// Checks if there are any arguments present -func (a Args) Present() bool { - return len(a) != 0 -} - -// Swaps arguments at the given indexes -func (a Args) Swap(from, to int) error { - if from >= len(a) || to >= len(a) { - return errors.New("index out of range") - } - a[from], a[to] = a[to], a[from] - return nil -} - -func lookupInt(name string, set *flag.FlagSet) int { - f := set.Lookup(name) - if f != nil { - val, err := strconv.Atoi(f.Value.String()) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupDuration(name string, set *flag.FlagSet) time.Duration { - f := set.Lookup(name) - if f != nil { - val, err := time.ParseDuration(f.Value.String()) - if err == nil { - return val - } - } - - return 0 -} - -func lookupFloat64(name string, set *flag.FlagSet) float64 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseFloat(f.Value.String(), 64) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupString(name string, set *flag.FlagSet) string { - f := set.Lookup(name) - if f != nil { - return f.Value.String() - } - - return "" -} - -func lookupStringSlice(name string, set *flag.FlagSet) []string { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*StringSlice)).Value() - - } - - return nil -} - -func lookupIntSlice(name string, set *flag.FlagSet) []int { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*IntSlice)).Value() - - } - - return nil -} - -func lookupGeneric(name string, set *flag.FlagSet) interface{} { - f := set.Lookup(name) - if f != nil { - return f.Value - } - return nil -} - -func lookupBool(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return false - } - return val - } - - return false -} - -func lookupBoolT(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return true - } - return val - } - - return false -} - -func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { - switch ff.Value.(type) { - case *StringSlice: - default: - set.Set(name, ff.Value.String()) - } -} - -func normalizeFlags(flags []Flag, set *flag.FlagSet) error { - visited := make(map[string]bool) - set.Visit(func(f *flag.Flag) { - visited[f.Name] = true - }) - for _, f := range flags { - parts := strings.Split(f.getName(), ",") - if len(parts) == 1 { - continue - } - var ff *flag.Flag - for _, name := range parts { - name = strings.Trim(name, " ") - if visited[name] { - if ff != nil { - return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name) - } - ff = set.Lookup(name) - } - } - if ff == nil { - continue - } - for _, name := range parts { - name = strings.Trim(name, " ") - if !visited[name] { - copyFlag(name, ff, set) - } - } - } - return nil -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go deleted file mode 100644 index 7c9a4436fc..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package cli_test - -import ( - "flag" - "testing" - "time" - - "github.com/codegangsta/cli" -) - -func TestNewContext(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Int("myflag", 12, "doc") - globalSet := flag.NewFlagSet("test", 0) - globalSet.Int("myflag", 42, "doc") - command := cli.Command{Name: "mycommand"} - c := cli.NewContext(nil, set, globalSet) - c.Command = command - expect(t, c.Int("myflag"), 12) - expect(t, c.GlobalInt("myflag"), 42) - expect(t, c.Command.Name, "mycommand") -} - -func TestContext_Int(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Int("myflag", 12, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Int("myflag"), 12) -} - -func TestContext_Duration(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Duration("myflag", time.Duration(12*time.Second), "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Duration("myflag"), time.Duration(12*time.Second)) -} - -func TestContext_String(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.String("myflag", "hello world", "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.String("myflag"), "hello world") -} - -func TestContext_Bool(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Bool("myflag"), false) -} - -func TestContext_BoolT(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", true, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.BoolT("myflag"), true) -} - -func TestContext_Args(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - c := cli.NewContext(nil, set, set) - set.Parse([]string{"--myflag", "bat", "baz"}) - expect(t, len(c.Args()), 2) - expect(t, c.Bool("myflag"), true) -} - -func TestContext_IsSet(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - set.String("otherflag", "hello world", "doc") - globalSet := flag.NewFlagSet("test", 0) - globalSet.Bool("myflagGlobal", true, "doc") - c := cli.NewContext(nil, set, globalSet) - set.Parse([]string{"--myflag", "bat", "baz"}) - globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"}) - expect(t, c.IsSet("myflag"), true) - expect(t, c.IsSet("otherflag"), false) - expect(t, c.IsSet("bogusflag"), false) - expect(t, c.IsSet("myflagGlobal"), false) -} - -func TestContext_GlobalIsSet(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - set.String("otherflag", "hello world", "doc") - globalSet := flag.NewFlagSet("test", 0) - globalSet.Bool("myflagGlobal", true, "doc") - globalSet.Bool("myflagGlobalUnset", true, "doc") - c := cli.NewContext(nil, set, globalSet) - set.Parse([]string{"--myflag", "bat", "baz"}) - globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"}) - expect(t, c.GlobalIsSet("myflag"), false) - expect(t, c.GlobalIsSet("otherflag"), false) - expect(t, c.GlobalIsSet("bogusflag"), false) - expect(t, c.GlobalIsSet("myflagGlobal"), true) - expect(t, c.GlobalIsSet("myflagGlobalUnset"), false) - expect(t, c.GlobalIsSet("bogusGlobal"), false) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go b/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go deleted file mode 100644 index 251158667b..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go +++ /dev/null @@ -1,454 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "os" - "strconv" - "strings" - "time" -) - -// This flag enables bash-completion for all commands and subcommands -var BashCompletionFlag = BoolFlag{ - Name: "generate-bash-completion", -} - -// This flag prints the version for the application -var VersionFlag = BoolFlag{ - Name: "version, v", - Usage: "print the version", -} - -// This flag prints the help for all commands and subcommands -// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand -// unless HideHelp is set to true) -var HelpFlag = BoolFlag{ - Name: "help, h", - Usage: "show help", -} - -// Flag is a common interface related to parsing flags in cli. -// For more advanced flag parsing techniques, it is recomended that -// this interface be implemented. -type Flag interface { - fmt.Stringer - // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) - getName() string -} - -func flagSet(name string, flags []Flag) *flag.FlagSet { - set := flag.NewFlagSet(name, flag.ContinueOnError) - - for _, f := range flags { - f.Apply(set) - } - return set -} - -func eachName(longName string, fn func(string)) { - parts := strings.Split(longName, ",") - for _, name := range parts { - name = strings.Trim(name, " ") - fn(name) - } -} - -// Generic is a generic parseable type identified by a specific flag -type Generic interface { - Set(value string) error - String() string -} - -// GenericFlag is the flag type for types implementing Generic -type GenericFlag struct { - Name string - Value Generic - Usage string - EnvVar string -} - -// String returns the string representation of the generic flag to display the -// help text to the user (uses the String() method of the generic flag to show -// the value) -func (f GenericFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s \"%v\"\t%v", prefixFor(f.Name), f.Name, f.Value, f.Usage)) -} - -// Apply takes the flagset and calls Set on the generic flag with the value -// provided by the user for parsing by the flag -func (f GenericFlag) Apply(set *flag.FlagSet) { - val := f.Value - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - val.Set(envVal) - break - } - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f GenericFlag) getName() string { - return f.Name -} - -type StringSlice []string - -func (f *StringSlice) Set(value string) error { - *f = append(*f, value) - return nil -} - -func (f *StringSlice) String() string { - return fmt.Sprintf("%s", *f) -} - -func (f *StringSlice) Value() []string { - return *f -} - -type StringSliceFlag struct { - Name string - Value *StringSlice - Usage string - EnvVar string -} - -func (f StringSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)) -} - -func (f StringSliceFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - newVal := &StringSlice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - newVal.Set(s) - } - f.Value = newVal - break - } - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f StringSliceFlag) getName() string { - return f.Name -} - -type IntSlice []int - -func (f *IntSlice) Set(value string) error { - - tmp, err := strconv.Atoi(value) - if err != nil { - return err - } else { - *f = append(*f, tmp) - } - return nil -} - -func (f *IntSlice) String() string { - return fmt.Sprintf("%d", *f) -} - -func (f *IntSlice) Value() []int { - return *f -} - -type IntSliceFlag struct { - Name string - Value *IntSlice - Usage string - EnvVar string -} - -func (f IntSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)) -} - -func (f IntSliceFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - newVal := &IntSlice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - err := newVal.Set(s) - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - } - } - f.Value = newVal - break - } - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f IntSliceFlag) getName() string { - return f.Name -} - -type BoolFlag struct { - Name string - Usage string - EnvVar string -} - -func (f BoolFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)) -} - -func (f BoolFlag) Apply(set *flag.FlagSet) { - val := false - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - envValBool, err := strconv.ParseBool(envVal) - if err == nil { - val = envValBool - } - break - } - } - } - - eachName(f.Name, func(name string) { - set.Bool(name, val, f.Usage) - }) -} - -func (f BoolFlag) getName() string { - return f.Name -} - -type BoolTFlag struct { - Name string - Usage string - EnvVar string -} - -func (f BoolTFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)) -} - -func (f BoolTFlag) Apply(set *flag.FlagSet) { - val := true - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - envValBool, err := strconv.ParseBool(envVal) - if err == nil { - val = envValBool - break - } - } - } - } - - eachName(f.Name, func(name string) { - set.Bool(name, val, f.Usage) - }) -} - -func (f BoolTFlag) getName() string { - return f.Name -} - -type StringFlag struct { - Name string - Value string - Usage string - EnvVar string -} - -func (f StringFlag) String() string { - var fmtString string - fmtString = "%s %v\t%v" - - if len(f.Value) > 0 { - fmtString = "%s \"%v\"\t%v" - } else { - fmtString = "%s %v\t%v" - } - - return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f StringFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - f.Value = envVal - break - } - } - } - - eachName(f.Name, func(name string) { - set.String(name, f.Value, f.Usage) - }) -} - -func (f StringFlag) getName() string { - return f.Name -} - -type IntFlag struct { - Name string - Value int - Usage string - EnvVar string -} - -func (f IntFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f IntFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - envValInt, err := strconv.ParseInt(envVal, 0, 64) - if err == nil { - f.Value = int(envValInt) - break - } - } - } - } - - eachName(f.Name, func(name string) { - set.Int(name, f.Value, f.Usage) - }) -} - -func (f IntFlag) getName() string { - return f.Name -} - -type DurationFlag struct { - Name string - Value time.Duration - Usage string - EnvVar string -} - -func (f DurationFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f DurationFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - envValDuration, err := time.ParseDuration(envVal) - if err == nil { - f.Value = envValDuration - break - } - } - } - } - - eachName(f.Name, func(name string) { - set.Duration(name, f.Value, f.Usage) - }) -} - -func (f DurationFlag) getName() string { - return f.Name -} - -type Float64Flag struct { - Name string - Value float64 - Usage string - EnvVar string -} - -func (f Float64Flag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f Float64Flag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - envValFloat, err := strconv.ParseFloat(envVal, 10) - if err == nil { - f.Value = float64(envValFloat) - } - } - } - } - - eachName(f.Name, func(name string) { - set.Float64(name, f.Value, f.Usage) - }) -} - -func (f Float64Flag) getName() string { - return f.Name -} - -func prefixFor(name string) (prefix string) { - if len(name) == 1 { - prefix = "-" - } else { - prefix = "--" - } - - return -} - -func prefixedNames(fullName string) (prefixed string) { - parts := strings.Split(fullName, ",") - for i, name := range parts { - name = strings.Trim(name, " ") - prefixed += prefixFor(name) + name - if i < len(parts)-1 { - prefixed += ", " - } - } - return -} - -func withEnvHint(envVar, str string) string { - envText := "" - if envVar != "" { - envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $")) - } - return str + envText -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go deleted file mode 100644 index f0f096a2d5..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go +++ /dev/null @@ -1,742 +0,0 @@ -package cli_test - -import ( - "fmt" - "os" - "reflect" - "strings" - "testing" - - "github.com/codegangsta/cli" -) - -var boolFlagTests = []struct { - name string - expected string -}{ - {"help", "--help\t"}, - {"h", "-h\t"}, -} - -func TestBoolFlagHelpOutput(t *testing.T) { - - for _, test := range boolFlagTests { - flag := cli.BoolFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -var stringFlagTests = []struct { - name string - value string - expected string -}{ - {"help", "", "--help \t"}, - {"h", "", "-h \t"}, - {"h", "", "-h \t"}, - {"test", "Something", "--test \"Something\"\t"}, -} - -func TestStringFlagHelpOutput(t *testing.T) { - - for _, test := range stringFlagTests { - flag := cli.StringFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestStringFlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_FOO", "derp") - for _, test := range stringFlagTests { - flag := cli.StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_FOO]") { - t.Errorf("%s does not end with [$APP_FOO]", output) - } - } -} - -var stringSliceFlagTests = []struct { - name string - value *cli.StringSlice - expected string -}{ - {"help", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("") - return s - }(), "--help [--help option --help option]\t"}, - {"h", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("") - return s - }(), "-h [-h option -h option]\t"}, - {"h", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("") - return s - }(), "-h [-h option -h option]\t"}, - {"test", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("Something") - return s - }(), "--test [--test option --test option]\t"}, -} - -func TestStringSliceFlagHelpOutput(t *testing.T) { - - for _, test := range stringSliceFlagTests { - flag := cli.StringSliceFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%q does not match %q", output, test.expected) - } - } -} - -func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_QWWX", "11,4") - for _, test := range stringSliceFlagTests { - flag := cli.StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_QWWX]") { - t.Errorf("%q does not end with [$APP_QWWX]", output) - } - } -} - -var intFlagTests = []struct { - name string - expected string -}{ - {"help", "--help \"0\"\t"}, - {"h", "-h \"0\"\t"}, -} - -func TestIntFlagHelpOutput(t *testing.T) { - - for _, test := range intFlagTests { - flag := cli.IntFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestIntFlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_BAR", "2") - for _, test := range intFlagTests { - flag := cli.IntFlag{Name: test.name, EnvVar: "APP_BAR"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_BAR]") { - t.Errorf("%s does not end with [$APP_BAR]", output) - } - } -} - -var durationFlagTests = []struct { - name string - expected string -}{ - {"help", "--help \"0\"\t"}, - {"h", "-h \"0\"\t"}, -} - -func TestDurationFlagHelpOutput(t *testing.T) { - - for _, test := range durationFlagTests { - flag := cli.DurationFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_BAR", "2h3m6s") - for _, test := range durationFlagTests { - flag := cli.DurationFlag{Name: test.name, EnvVar: "APP_BAR"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_BAR]") { - t.Errorf("%s does not end with [$APP_BAR]", output) - } - } -} - -var intSliceFlagTests = []struct { - name string - value *cli.IntSlice - expected string -}{ - {"help", &cli.IntSlice{}, "--help [--help option --help option]\t"}, - {"h", &cli.IntSlice{}, "-h [-h option -h option]\t"}, - {"h", &cli.IntSlice{}, "-h [-h option -h option]\t"}, - {"test", func() *cli.IntSlice { - i := &cli.IntSlice{} - i.Set("9") - return i - }(), "--test [--test option --test option]\t"}, -} - -func TestIntSliceFlagHelpOutput(t *testing.T) { - - for _, test := range intSliceFlagTests { - flag := cli.IntSliceFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%q does not match %q", output, test.expected) - } - } -} - -func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_SMURF", "42,3") - for _, test := range intSliceFlagTests { - flag := cli.IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_SMURF]") { - t.Errorf("%q does not end with [$APP_SMURF]", output) - } - } -} - -var float64FlagTests = []struct { - name string - expected string -}{ - {"help", "--help \"0\"\t"}, - {"h", "-h \"0\"\t"}, -} - -func TestFloat64FlagHelpOutput(t *testing.T) { - - for _, test := range float64FlagTests { - flag := cli.Float64Flag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_BAZ", "99.4") - for _, test := range float64FlagTests { - flag := cli.Float64Flag{Name: test.name, EnvVar: "APP_BAZ"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_BAZ]") { - t.Errorf("%s does not end with [$APP_BAZ]", output) - } - } -} - -var genericFlagTests = []struct { - name string - value cli.Generic - expected string -}{ - {"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"}, - {"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"}, -} - -func TestGenericFlagHelpOutput(t *testing.T) { - - for _, test := range genericFlagTests { - flag := cli.GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"} - output := flag.String() - - if output != test.expected { - t.Errorf("%q does not match %q", output, test.expected) - } - } -} - -func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) { - os.Clearenv() - os.Setenv("APP_ZAP", "3") - for _, test := range genericFlagTests { - flag := cli.GenericFlag{Name: test.name, EnvVar: "APP_ZAP"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_ZAP]") { - t.Errorf("%s does not end with [$APP_ZAP]", output) - } - } -} - -func TestParseMultiString(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.StringFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.String("serve") != "10" { - t.Errorf("main name not set") - } - if ctx.String("s") != "10" { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10"}) -} - -func TestParseMultiStringFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_COUNT", "20") - (&cli.App{ - Flags: []cli.Flag{ - cli.StringFlag{Name: "count, c", EnvVar: "APP_COUNT"}, - }, - Action: func(ctx *cli.Context) { - if ctx.String("count") != "20" { - t.Errorf("main name not set") - } - if ctx.String("c") != "20" { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiStringFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_COUNT", "20") - (&cli.App{ - Flags: []cli.Flag{ - cli.StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"}, - }, - Action: func(ctx *cli.Context) { - if ctx.String("count") != "20" { - t.Errorf("main name not set") - } - if ctx.String("c") != "20" { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiStringSlice(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10", "-s", "20"}) -} - -func TestParseMultiStringSliceFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_INTERVALS", "20,30,40") - - (&cli.App{ - Flags: []cli.Flag{ - cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "APP_INTERVALS"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) { - t.Errorf("short name not set from env") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiStringSliceFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_INTERVALS", "20,30,40") - - (&cli.App{ - Flags: []cli.Flag{ - cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) { - t.Errorf("short name not set from env") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiInt(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.IntFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Int("serve") != 10 { - t.Errorf("main name not set") - } - if ctx.Int("s") != 10 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10"}) -} - -func TestParseMultiIntFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_TIMEOUT_SECONDS", "10") - a := cli.App{ - Flags: []cli.Flag{ - cli.IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Int("timeout") != 10 { - t.Errorf("main name not set") - } - if ctx.Int("t") != 10 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiIntFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_TIMEOUT_SECONDS", "10") - a := cli.App{ - Flags: []cli.Flag{ - cli.IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Int("timeout") != 10 { - t.Errorf("main name not set") - } - if ctx.Int("t") != 10 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiIntSlice(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "serve, s", Value: &cli.IntSlice{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10", "-s", "20"}) -} - -func TestParseMultiIntSliceFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_INTERVALS", "20,30,40") - - (&cli.App{ - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "APP_INTERVALS"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) { - t.Errorf("short name not set from env") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiIntSliceFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_INTERVALS", "20,30,40") - - (&cli.App{ - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) { - t.Errorf("short name not set from env") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiFloat64(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.Float64Flag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Float64("serve") != 10.2 { - t.Errorf("main name not set") - } - if ctx.Float64("s") != 10.2 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10.2"}) -} - -func TestParseMultiFloat64FromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_TIMEOUT_SECONDS", "15.5") - a := cli.App{ - Flags: []cli.Flag{ - cli.Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Float64("timeout") != 15.5 { - t.Errorf("main name not set") - } - if ctx.Float64("t") != 15.5 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiFloat64FromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_TIMEOUT_SECONDS", "15.5") - a := cli.App{ - Flags: []cli.Flag{ - cli.Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Float64("timeout") != 15.5 { - t.Errorf("main name not set") - } - if ctx.Float64("t") != 15.5 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiBool(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Bool("serve") != true { - t.Errorf("main name not set") - } - if ctx.Bool("s") != true { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "--serve"}) -} - -func TestParseMultiBoolFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_DEBUG", "1") - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Bool("debug") != true { - t.Errorf("main name not set from env") - } - if ctx.Bool("d") != true { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiBoolFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_DEBUG", "1") - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Bool("debug") != true { - t.Errorf("main name not set from env") - } - if ctx.Bool("d") != true { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiBoolT(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolTFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.BoolT("serve") != true { - t.Errorf("main name not set") - } - if ctx.BoolT("s") != true { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "--serve"}) -} - -func TestParseMultiBoolTFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_DEBUG", "0") - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"}, - }, - Action: func(ctx *cli.Context) { - if ctx.BoolT("debug") != false { - t.Errorf("main name not set from env") - } - if ctx.BoolT("d") != false { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiBoolTFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_DEBUG", "0") - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"}, - }, - Action: func(ctx *cli.Context) { - if ctx.BoolT("debug") != false { - t.Errorf("main name not set from env") - } - if ctx.BoolT("d") != false { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -type Parser [2]string - -func (p *Parser) Set(value string) error { - parts := strings.Split(value, ",") - if len(parts) != 2 { - return fmt.Errorf("invalid format") - } - - (*p)[0] = parts[0] - (*p)[1] = parts[1] - - return nil -} - -func (p *Parser) String() string { - return fmt.Sprintf("%s,%s", p[0], p[1]) -} - -func TestParseGeneric(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.GenericFlag{Name: "serve, s", Value: &Parser{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10,20"}) -} - -func TestParseGenericFromEnv(t *testing.T) { - os.Clearenv() - os.Setenv("APP_SERVE", "20,30") - a := cli.App{ - Flags: []cli.Flag{ - cli.GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseGenericFromEnvCascade(t *testing.T) { - os.Clearenv() - os.Setenv("APP_FOO", "99,2000") - a := cli.App{ - Flags: []cli.Flag{ - cli.GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) { - t.Errorf("value not set from env") - } - }, - } - a.Run([]string{"run"}) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/help.go b/Godeps/_workspace/src/github.com/codegangsta/cli/help.go deleted file mode 100644 index bfb2788519..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/help.go +++ /dev/null @@ -1,211 +0,0 @@ -package cli - -import "fmt" - -// The text template for the Default help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var AppHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - {{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...] - -VERSION: - {{.Version}}{{if or .Author .Email}} - -AUTHOR:{{if .Author}} - {{.Author}}{{if .Email}} - <{{.Email}}>{{end}}{{else}} - {{.Email}}{{end}}{{end}} - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{if .Flags}} -GLOBAL OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}} -` - -// The text template for the command help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var CommandHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - command {{.Name}}{{if .Flags}} [command options]{{end}} [arguments...]{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}}{{if .Flags}} - -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{ end }} -` - -// The text template for the subcommand help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var SubcommandHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - {{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...] - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{if .Flags}} -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}} -` - -var helpCommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", - Action: func(c *Context) { - args := c.Args() - if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowAppHelp(c) - } - }, -} - -var helpSubcommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", - Action: func(c *Context) { - args := c.Args() - if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowSubcommandHelp(c) - } - }, -} - -// Prints help for the App -type helpPrinter func(templ string, data interface{}) - -var HelpPrinter helpPrinter = nil - -// Prints version for the App -var VersionPrinter = printVersion - -func ShowAppHelp(c *Context) { - HelpPrinter(AppHelpTemplate, c.App) -} - -// Prints the list of subcommands as the default app completion method -func DefaultAppComplete(c *Context) { - for _, command := range c.App.Commands { - fmt.Fprintln(c.App.Writer, command.Name) - if command.ShortName != "" { - fmt.Fprintln(c.App.Writer, command.ShortName) - } - } -} - -// Prints help for the given command -func ShowCommandHelp(c *Context, command string) { - for _, c := range c.App.Commands { - if c.HasName(command) { - HelpPrinter(CommandHelpTemplate, c) - return - } - } - - if c.App.CommandNotFound != nil { - c.App.CommandNotFound(c, command) - } else { - fmt.Fprintf(c.App.Writer, "No help topic for '%v'\n", command) - } -} - -// Prints help for the given subcommand -func ShowSubcommandHelp(c *Context) { - ShowCommandHelp(c, c.Command.Name) -} - -// Prints the version number of the App -func ShowVersion(c *Context) { - VersionPrinter(c) -} - -func printVersion(c *Context) { - fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) -} - -// Prints the lists of commands within a given context -func ShowCompletions(c *Context) { - a := c.App - if a != nil && a.BashComplete != nil { - a.BashComplete(c) - } -} - -// Prints the custom completions for a given command -func ShowCommandCompletions(ctx *Context, command string) { - c := ctx.App.Command(command) - if c != nil && c.BashComplete != nil { - c.BashComplete(ctx) - } -} - -func checkVersion(c *Context) bool { - if c.GlobalBool("version") { - ShowVersion(c) - return true - } - - return false -} - -func checkHelp(c *Context) bool { - if c.GlobalBool("h") || c.GlobalBool("help") { - ShowAppHelp(c) - return true - } - - return false -} - -func checkCommandHelp(c *Context, name string) bool { - if c.Bool("h") || c.Bool("help") { - ShowCommandHelp(c, name) - return true - } - - return false -} - -func checkSubcommandHelp(c *Context) bool { - if c.GlobalBool("h") || c.GlobalBool("help") { - ShowSubcommandHelp(c) - return true - } - - return false -} - -func checkCompletions(c *Context) bool { - if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion { - ShowCompletions(c) - return true - } - - return false -} - -func checkCommandCompletions(c *Context, name string) bool { - if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion { - ShowCommandCompletions(c, name) - return true - } - - return false -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go deleted file mode 100644 index cdc4feb2fc..0000000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package cli_test - -import ( - "reflect" - "testing" -) - -/* Test Helpers */ -func expect(t *testing.T, a interface{}, b interface{}) { - if a != b { - t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} - -func refute(t *testing.T, a interface{}, b interface{}) { - if a == b { - t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/LICENSE.txt b/Godeps/_workspace/src/github.com/digitalocean/godo/LICENSE.txt deleted file mode 100644 index d9cd60c476..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/LICENSE.txt +++ /dev/null @@ -1,55 +0,0 @@ -Copyright (c) 2014 The godo AUTHORS. All rights reserved. - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -====================== -Portions of the client are based on code at: -https://github.com/google/go-github/ - -Copyright (c) 2013 The go-github AUTHORS. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/Makefile b/Godeps/_workspace/src/github.com/digitalocean/godo/Makefile deleted file mode 100644 index 86a0a0b14c..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OPEN = $(shell which xdg-open || which gnome-open || which open) - -cov: - @@gocov test | gocov-html > /tmp/coverage.html - @@${OPEN} /tmp/coverage.html - -ci: - go get -d -v -t ./... - go build ./... - go test -v ./... diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/README.md b/Godeps/_workspace/src/github.com/digitalocean/godo/README.md deleted file mode 100644 index 4d86333615..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# Godo - -Godo is a Go client library for accessing the DigitalOcean V2 API. - -You can view the client API docs here: [http://godoc.org/github.com/digitalocean/godo](http://godoc.org/github.com/digitalocean/godo) - -You can view Digital Ocean API docs here: [https://developers.digitalocean.com/v2/](https://developers.digitalocean.com/v2/) - - -## Usage - -```go -import "github.com/digitalocean/godo" -``` - -Create a new DigitalOcean client, then use the exposed services to -access different parts of the DigitalOcean API. - -### Authentication - -Currently, Personal Access Token (PAT) is the only method of -authenticating with the API. You can manage your tokens -at the Digital Ocean Control Panel [Applications Page](https://cloud.digitalocean.com/settings/applications). - -You can then use your token to create a new client: - -```go -import "code.google.com/p/goauth2/oauth" - -pat := "mytoken" -t := &oauth.Transport{ - Token: &oauth.Token{AccessToken: pat}, -} - -client := godo.NewClient(t.Client()) -``` - -## Examples - - -To create a new Droplet: - -```go -dropletName := "super-cool-droplet" - -createRequest := &godo.DropletCreateRequest{ - Name: dropletName, - Region: "nyc3", - Size: "512mb", - Image: "ubuntu-14-04-x64", -} - -newDroplet, _, err := client.Droplets.Create(createRequest) - -if err != nil { - fmt.Printf("Something bad happened: %s\n\n", err) - return err -} -``` - -### Pagination - -If a list of items is paginated by the API, you must request pages individually. For example, to fetch all Droplets: - -```go -func DropletList(client *godo.Client) ([]godo.Droplet, error) { - // create a list to hold our droplets - list := []godo.Droplet{} - - // create options. initially, these will be blank - opt := &godo.ListOptions{} - for { - droplets, resp, err := client.Droplets.List(opt) - if err != nil { - return err - } - - // append the current page's droplets to our list - for _, d := range droplets { - list = append(list, d) - } - - // if we are at the last page, break out the for loop - if resp.Links.IsLastPage() { - break - } - - page, err := resp.Links.CurrentPage() - if err != nil { - return err - } - - // set the page we want for the next request - opt.Page = page + 1 - } - - return nil -} - -``` diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/action.go b/Godeps/_workspace/src/github.com/digitalocean/godo/action.go deleted file mode 100644 index ff7298fecb..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/action.go +++ /dev/null @@ -1,92 +0,0 @@ -package godo - -import "fmt" - -const ( - actionsBasePath = "v2/actions" - - // ActionInProgress is an in progress action status - ActionInProgress = "in-progress" - - //ActionCompleted is a completed action status - ActionCompleted = "completed" -) - -// ActionsService handles communction with action related methods of the -// DigitalOcean API: https://developers.digitalocean.com/#actions -type ActionsService interface { - List(*ListOptions) ([]Action, *Response, error) - Get(int) (*Action, *Response, error) -} - -// ActionsServiceOp handles communition with the image action related methods of the -// DigitalOcean API. -type ActionsServiceOp struct { - client *Client -} - -type actionsRoot struct { - Actions []Action `json:"actions"` - Links *Links `json:"links"` -} - -type actionRoot struct { - Event Action `json:"action"` -} - -// Action represents a DigitalOcean Action -type Action struct { - ID int `json:"id"` - Status string `json:"status"` - Type string `json:"type"` - StartedAt *Timestamp `json:"started_at"` - CompletedAt *Timestamp `json:"completed_at"` - ResourceID int `json:"resource_id"` - ResourceType string `json:"resource_type"` -} - -// List all actions -func (s *ActionsServiceOp) List(opt *ListOptions) ([]Action, *Response, error) { - path := actionsBasePath - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(actionsRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.Actions, resp, err -} - -// Get an action by ID -func (s *ActionsServiceOp) Get(id int) (*Action, *Response, error) { - path := fmt.Sprintf("%s/%d", actionsBasePath, id) - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(actionRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.Event, resp, err -} - -func (a Action) String() string { - return Stringify(a) -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/action_request.go b/Godeps/_workspace/src/github.com/digitalocean/godo/action_request.go deleted file mode 100644 index d4411766e7..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/action_request.go +++ /dev/null @@ -1,12 +0,0 @@ -package godo - -// ActionRequest reprents DigitalOcean Action Request -type ActionRequest struct { - Type string `json:"type"` - Params map[string]interface{} `json:"params,omitempty"` -} - -// Converts an ActionRequest to a string. -func (d ActionRequest) String() string { - return Stringify(d) -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/action_request_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/action_request_test.go deleted file mode 100644 index 5b752102e2..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/action_request_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package godo - -import "testing" - -func TestActionRequest_String(t *testing.T) { - action := &ActionRequest{ - Type: "transfer", - Params: map[string]interface{}{"key-1": "value-1"}, - } - - stringified := action.String() - expected := `godo.ActionRequest{Type:"transfer", Params:map[key-1:value-1]}` - if expected != stringified { - t.Errorf("Action.Stringify returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/action_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/action_test.go deleted file mode 100644 index 501236e092..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/action_test.go +++ /dev/null @@ -1,126 +0,0 @@ -package godo - -import ( - "fmt" - "net/http" - "testing" - "time" -) - -func TestAction_ActionsServiceOpImplementsActionsService(t *testing.T) { - if !Implements((*ActionsService)(nil), new(ActionsServiceOp)) { - t.Error("ActionsServiceOp does not implement ActionsService") - } -} - -func TestAction_List(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/actions", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"actions": [{"id":1},{"id":2}]}`) - testMethod(t, r, "GET") - }) - - actions, _, err := client.Actions.List(nil) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - expected := []Action{{ID: 1}, {ID: 2}} - if len(actions) != len(expected) || actions[0].ID != expected[0].ID || actions[1].ID != expected[1].ID { - t.Fatalf("unexpected response") - } -} - -func TestAction_ListActionMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/actions", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"actions": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/droplets/?page=2"}}}`) - testMethod(t, r, "GET") - }) - - _, resp, err := client.Actions.List(nil) - if err != nil { - t.Fatal(nil) - } - - checkCurrentPage(t, resp, 1) -} - -func TestAction_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "actions": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/actions/?page=3", - "prev":"http://example.com/v2/actions/?page=1", - "last":"http://example.com/v2/actions/?page=3", - "first":"http://example.com/v2/actions/?page=1" - } - } - }` - - mux.HandleFunc("/v2/actions", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Actions.List(opt) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 2) -} - -func TestAction_Get(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/actions/12345", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"action": {"id":12345}}`) - testMethod(t, r, "GET") - }) - - action, _, err := client.Actions.Get(12345) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - if action.ID != 12345 { - t.Fatalf("unexpected response") - } -} - -func TestAction_String(t *testing.T) { - pt, err := time.Parse(time.RFC3339, "2014-05-08T20:36:47Z") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - startedAt := &Timestamp{ - Time: pt, - } - action := &Action{ - ID: 1, - Status: "in-progress", - Type: "transfer", - StartedAt: startedAt, - } - - stringified := action.String() - expected := `godo.Action{ID:1, Status:"in-progress", Type:"transfer", ` + - `StartedAt:godo.Timestamp{2014-05-08 20:36:47 +0000 UTC}, ` + - `ResourceID:0, ResourceType:""}` - if expected != stringified { - t.Errorf("Action.Stringify returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/domains.go b/Godeps/_workspace/src/github.com/digitalocean/godo/domains.go deleted file mode 100644 index 4ec2433bbb..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/domains.go +++ /dev/null @@ -1,269 +0,0 @@ -package godo - -import "fmt" - -const domainsBasePath = "v2/domains" - -// DomainsService is an interface for managing DNS with the Digital Ocean API. -// See: https://developers.digitalocean.com/#domains and -// https://developers.digitalocean.com/#domain-records -type DomainsService interface { - List(*ListOptions) ([]Domain, *Response, error) - Get(string) (*DomainRoot, *Response, error) - Create(*DomainCreateRequest) (*DomainRoot, *Response, error) - Delete(string) (*Response, error) - - Records(string, *ListOptions) ([]DomainRecord, *Response, error) - Record(string, int) (*DomainRecord, *Response, error) - DeleteRecord(string, int) (*Response, error) - EditRecord(string, int, *DomainRecordEditRequest) (*DomainRecord, *Response, error) - CreateRecord(string, *DomainRecordEditRequest) (*DomainRecord, *Response, error) -} - -// DomainsServiceOp handles communication with the domain related methods of the -// DigitalOcean API. -type DomainsServiceOp struct { - client *Client -} - -// Domain represents a Digital Ocean domain -type Domain struct { - Name string `json:"name"` - TTL int `json:"ttl"` - ZoneFile string `json:"zone_file"` -} - -// DomainRoot represents a response from the Digital Ocean API -type DomainRoot struct { - Domain *Domain `json:"domain"` -} - -type domainsRoot struct { - Domains []Domain `json:"domains"` - Links *Links `json:"links"` -} - -// DomainCreateRequest respresents a request to create a domain. -type DomainCreateRequest struct { - Name string `json:"name"` - IPAddress string `json:"ip_address"` -} - -// DomainRecordRoot is the root of an individual Domain Record response -type DomainRecordRoot struct { - DomainRecord *DomainRecord `json:"domain_record"` -} - -// DomainRecordsRoot is the root of a group of Domain Record responses -type DomainRecordsRoot struct { - DomainRecords []DomainRecord `json:"domain_records"` - Links *Links `json:"links"` -} - -// DomainRecord represents a DigitalOcean DomainRecord -type DomainRecord struct { - ID int `json:"id,float64,omitempty"` - Type string `json:"type,omitempty"` - Name string `json:"name,omitempty"` - Data string `json:"data,omitempty"` - Priority int `json:"priority,omitempty"` - Port int `json:"port,omitempty"` - Weight int `json:"weight,omitempty"` -} - -// DomainRecordEditRequest represents a request to update a domain record. -type DomainRecordEditRequest struct { - Type string `json:"type,omitempty"` - Name string `json:"name,omitempty"` - Data string `json:"data,omitempty"` - Priority int `json:"priority,omitempty"` - Port int `json:"port,omitempty"` - Weight int `json:"weight,omitempty"` -} - -func (d Domain) String() string { - return Stringify(d) -} - -// List all domains -func (s DomainsServiceOp) List(opt *ListOptions) ([]Domain, *Response, error) { - path := domainsBasePath - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(domainsRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.Domains, resp, err -} - -// Get individual domain -func (s *DomainsServiceOp) Get(name string) (*DomainRoot, *Response, error) { - path := fmt.Sprintf("%s/%s", domainsBasePath, name) - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(DomainRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return root, resp, err -} - -// Create a new domain -func (s *DomainsServiceOp) Create(createRequest *DomainCreateRequest) (*DomainRoot, *Response, error) { - path := domainsBasePath - - req, err := s.client.NewRequest("POST", path, createRequest) - if err != nil { - return nil, nil, err - } - - root := new(DomainRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return root, resp, err -} - -// Delete droplet -func (s *DomainsServiceOp) Delete(name string) (*Response, error) { - path := fmt.Sprintf("%s/%s", domainsBasePath, name) - - req, err := s.client.NewRequest("DELETE", path, nil) - if err != nil { - return nil, err - } - - resp, err := s.client.Do(req, nil) - - return resp, err -} - -// Converts a DomainRecord to a string. -func (d DomainRecord) String() string { - return Stringify(d) -} - -// Converts a DomainRecordEditRequest to a string. -func (d DomainRecordEditRequest) String() string { - return Stringify(d) -} - -// Records returns a slice of DomainRecords for a domain -func (s *DomainsServiceOp) Records(domain string, opt *ListOptions) ([]DomainRecord, *Response, error) { - path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain) - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(DomainRecordsRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.DomainRecords, resp, err -} - -// Record returns the record id from a domain -func (s *DomainsServiceOp) Record(domain string, id int) (*DomainRecord, *Response, error) { - path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - record := new(DomainRecordRoot) - resp, err := s.client.Do(req, record) - if err != nil { - return nil, resp, err - } - - return record.DomainRecord, resp, err -} - -// DeleteRecord deletes a record from a domain identified by id -func (s *DomainsServiceOp) DeleteRecord(domain string, id int) (*Response, error) { - path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) - - req, err := s.client.NewRequest("DELETE", path, nil) - if err != nil { - return nil, err - } - - resp, err := s.client.Do(req, nil) - - return resp, err -} - -// EditRecord edits a record using a DomainRecordEditRequest -func (s *DomainsServiceOp) EditRecord( - domain string, - id int, - editRequest *DomainRecordEditRequest) (*DomainRecord, *Response, error) { - path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) - - req, err := s.client.NewRequest("PUT", path, editRequest) - if err != nil { - return nil, nil, err - } - - d := new(DomainRecord) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateRecord creates a record using a DomainRecordEditRequest -func (s *DomainsServiceOp) CreateRecord( - domain string, - createRequest *DomainRecordEditRequest) (*DomainRecord, *Response, error) { - path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain) - req, err := s.client.NewRequest("POST", path, createRequest) - - if err != nil { - return nil, nil, err - } - - d := new(DomainRecordRoot) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d.DomainRecord, resp, err -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/domains_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/domains_test.go deleted file mode 100644 index ab26df808a..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/domains_test.go +++ /dev/null @@ -1,345 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestAction_DomainsServiceOpImplementsDomainsService(t *testing.T) { - if !Implements((*DomainsService)(nil), new(DomainsServiceOp)) { - t.Error("DomainsServiceOp does not implement DomainsService") - } -} - -func TestDomains_ListDomains(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"domains": [{"name":"foo.com"},{"name":"bar.com"}]}`) - }) - - domains, _, err := client.Domains.List(nil) - if err != nil { - t.Errorf("Domains.List returned error: %v", err) - } - - expected := []Domain{{Name: "foo.com"}, {Name: "bar.com"}} - if !reflect.DeepEqual(domains, expected) { - t.Errorf("Domains.List returned %+v, expected %+v", domains, expected) - } -} - -func TestDomains_ListDomainsMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"domains": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/domains/?page=2"}}}`) - }) - - _, resp, err := client.Domains.List(nil) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 1) -} - -func TestDomains_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "domains": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/domains/?page=3", - "prev":"http://example.com/v2/domains/?page=1", - "last":"http://example.com/v2/domains/?page=3", - "first":"http://example.com/v2/domains/?page=1" - } - } - }` - - mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Domains.List(opt) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 2) -} - -func TestDomains_GetDomain(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains/example.com", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"domain":{"name":"example.com"}}`) - }) - - domains, _, err := client.Domains.Get("example.com") - if err != nil { - t.Errorf("domain.Get returned error: %v", err) - } - - expected := &DomainRoot{Domain: &Domain{Name: "example.com"}} - if !reflect.DeepEqual(domains, expected) { - t.Errorf("domains.Get returned %+v, expected %+v", domains, expected) - } -} - -func TestDomains_Create(t *testing.T) { - setup() - defer teardown() - - createRequest := &DomainCreateRequest{ - Name: "example.com", - IPAddress: "127.0.0.1", - } - - mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) { - v := new(DomainCreateRequest) - err := json.NewDecoder(r.Body).Decode(v) - if err != nil { - t.Fatal(err) - } - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, createRequest) { - t.Errorf("Request body = %+v, expected %+v", v, createRequest) - } - - dr := DomainRoot{&Domain{Name: v.Name}} - b, err := json.Marshal(dr) - if err != nil { - t.Fatal(err) - } - - fmt.Fprint(w, string(b)) - }) - - domain, _, err := client.Domains.Create(createRequest) - if err != nil { - t.Errorf("Domains.Create returned error: %v", err) - } - - expected := &DomainRoot{Domain: &Domain{Name: "example.com"}} - if !reflect.DeepEqual(domain, expected) { - t.Errorf("Domains.Create returned %+v, expected %+v", domain, expected) - } -} - -func TestDomains_Destroy(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains/example.com", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - }) - - _, err := client.Domains.Delete("example.com") - if err != nil { - t.Errorf("Domains.Delete returned error: %v", err) - } -} - -func TestDomains_AllRecordsForDomainName(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains/example.com/records", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"domain_records":[{"id":1},{"id":2}]}`) - }) - - records, _, err := client.Domains.Records("example.com", nil) - if err != nil { - t.Errorf("Domains.List returned error: %v", err) - } - - expected := []DomainRecord{{ID: 1}, {ID: 2}} - if !reflect.DeepEqual(records, expected) { - t.Errorf("Domains.List returned %+v, expected %+v", records, expected) - } -} - -func TestDomains_AllRecordsForDomainName_PerPage(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains/example.com/records", func(w http.ResponseWriter, r *http.Request) { - perPage := r.URL.Query().Get("per_page") - if perPage != "2" { - t.Fatalf("expected '2', got '%s'", perPage) - } - - fmt.Fprint(w, `{"domain_records":[{"id":1},{"id":2}]}`) - }) - - dro := &ListOptions{PerPage: 2} - records, _, err := client.Domains.Records("example.com", dro) - if err != nil { - t.Errorf("Domains.List returned error: %v", err) - } - - expected := []DomainRecord{{ID: 1}, {ID: 2}} - if !reflect.DeepEqual(records, expected) { - t.Errorf("Domains.List returned %+v, expected %+v", records, expected) - } -} - -func TestDomains_GetRecordforDomainName(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains/example.com/records/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"domain_record":{"id":1}}`) - }) - - record, _, err := client.Domains.Record("example.com", 1) - if err != nil { - t.Errorf("Domains.GetRecord returned error: %v", err) - } - - expected := &DomainRecord{ID: 1} - if !reflect.DeepEqual(record, expected) { - t.Errorf("Domains.GetRecord returned %+v, expected %+v", record, expected) - } -} - -func TestDomains_DeleteRecordForDomainName(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/domains/example.com/records/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - }) - - _, err := client.Domains.DeleteRecord("example.com", 1) - if err != nil { - t.Errorf("Domains.RecordDelete returned error: %v", err) - } -} - -func TestDomains_CreateRecordForDomainName(t *testing.T) { - setup() - defer teardown() - - createRequest := &DomainRecordEditRequest{ - Type: "CNAME", - Name: "example", - Data: "@", - Priority: 10, - Port: 10, - Weight: 10, - } - - mux.HandleFunc("/v2/domains/example.com/records", - func(w http.ResponseWriter, r *http.Request) { - v := new(DomainRecordEditRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, createRequest) { - t.Errorf("Request body = %+v, expected %+v", v, createRequest) - } - - fmt.Fprintf(w, `{"domain_record": {"id":1}}`) - }) - - record, _, err := client.Domains.CreateRecord("example.com", createRequest) - if err != nil { - t.Errorf("Domains.CreateRecord returned error: %v", err) - } - - expected := &DomainRecord{ID: 1} - if !reflect.DeepEqual(record, expected) { - t.Errorf("Domains.CreateRecord returned %+v, expected %+v", record, expected) - } -} - -func TestDomains_EditRecordForDomainName(t *testing.T) { - setup() - defer teardown() - - editRequest := &DomainRecordEditRequest{ - Type: "CNAME", - Name: "example", - Data: "@", - Priority: 10, - Port: 10, - Weight: 10, - } - - mux.HandleFunc("/v2/domains/example.com/records/1", func(w http.ResponseWriter, r *http.Request) { - v := new(DomainRecordEditRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "PUT") - if !reflect.DeepEqual(v, editRequest) { - t.Errorf("Request body = %+v, expected %+v", v, editRequest) - } - - fmt.Fprintf(w, `{"id":1}`) - }) - - record, _, err := client.Domains.EditRecord("example.com", 1, editRequest) - if err != nil { - t.Errorf("Domains.EditRecord returned error: %v", err) - } - - expected := &DomainRecord{ID: 1} - if !reflect.DeepEqual(record, expected) { - t.Errorf("Domains.EditRecord returned %+v, expected %+v", record, expected) - } -} - -func TestDomainRecord_String(t *testing.T) { - record := &DomainRecord{ - ID: 1, - Type: "CNAME", - Name: "example", - Data: "@", - Priority: 10, - Port: 10, - Weight: 10, - } - - stringified := record.String() - expected := `godo.DomainRecord{ID:1, Type:"CNAME", Name:"example", Data:"@", Priority:10, Port:10, Weight:10}` - if expected != stringified { - t.Errorf("DomainRecord.String returned %+v, expected %+v", stringified, expected) - } -} - -func TestDomainRecordEditRequest_String(t *testing.T) { - record := &DomainRecordEditRequest{ - Type: "CNAME", - Name: "example", - Data: "@", - Priority: 10, - Port: 10, - Weight: 10, - } - - stringified := record.String() - expected := `godo.DomainRecordEditRequest{Type:"CNAME", Name:"example", Data:"@", Priority:10, Port:10, Weight:10}` - if expected != stringified { - t.Errorf("DomainRecordEditRequest.String returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/droplet_actions.go b/Godeps/_workspace/src/github.com/digitalocean/godo/droplet_actions.go deleted file mode 100644 index c23c477db0..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/droplet_actions.go +++ /dev/null @@ -1,155 +0,0 @@ -package godo - -import ( - "fmt" - "net/url" -) - -// DropletActionsService is an interface for interfacing with the droplet actions -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#droplet-actions -type DropletActionsService interface { - Shutdown(int) (*Action, *Response, error) - PowerOff(int) (*Action, *Response, error) - PowerOn(int) (*Action, *Response, error) - PowerCycle(int) (*Action, *Response, error) - Reboot(int) (*Action, *Response, error) - Restore(int, int) (*Action, *Response, error) - Resize(int, string) (*Action, *Response, error) - Rename(int, string) (*Action, *Response, error) - doAction(int, *ActionRequest) (*Action, *Response, error) - Get(int, int) (*Action, *Response, error) - GetByURI(string) (*Action, *Response, error) -} - -// DropletActionsServiceOp handles communication with the droplet action related -// methods of the DigitalOcean API. -type DropletActionsServiceOp struct { - client *Client -} - -// Shutdown a Droplet -func (s *DropletActionsServiceOp) Shutdown(id int) (*Action, *Response, error) { - request := &ActionRequest{Type: "shutdown"} - return s.doAction(id, request) -} - -// PowerOff a Droplet -func (s *DropletActionsServiceOp) PowerOff(id int) (*Action, *Response, error) { - request := &ActionRequest{Type: "power_off"} - return s.doAction(id, request) -} - -// PowerOn a Droplet -func (s *DropletActionsServiceOp) PowerOn(id int) (*Action, *Response, error) { - request := &ActionRequest{Type: "power_on"} - return s.doAction(id, request) -} - -// PowerCycle a Droplet -func (s *DropletActionsServiceOp) PowerCycle(id int) (*Action, *Response, error) { - request := &ActionRequest{Type: "power_cycle"} - return s.doAction(id, request) -} - -// Reboot a Droplet -func (s *DropletActionsServiceOp) Reboot(id int) (*Action, *Response, error) { - request := &ActionRequest{Type: "reboot"} - return s.doAction(id, request) -} - -// Restore an image to a Droplet -func (s *DropletActionsServiceOp) Restore(id, imageID int) (*Action, *Response, error) { - options := map[string]interface{}{ - "image": float64(imageID), - } - - requestType := "restore" - request := &ActionRequest{ - Type: requestType, - Params: options, - } - return s.doAction(id, request) -} - -// Resize a Droplet -func (s *DropletActionsServiceOp) Resize(id int, sizeSlug string) (*Action, *Response, error) { - options := map[string]interface{}{ - "size": sizeSlug, - } - - requestType := "resize" - request := &ActionRequest{ - Type: requestType, - Params: options, - } - return s.doAction(id, request) -} - -// Rename a Droplet -func (s *DropletActionsServiceOp) Rename(id int, name string) (*Action, *Response, error) { - options := map[string]interface{}{ - "name": name, - } - - requestType := "rename" - request := &ActionRequest{ - Type: requestType, - Params: options, - } - return s.doAction(id, request) -} - -func (s *DropletActionsServiceOp) doAction(id int, request *ActionRequest) (*Action, *Response, error) { - path := dropletActionPath(id) - - req, err := s.client.NewRequest("POST", path, request) - if err != nil { - return nil, nil, err - } - - root := new(actionRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.Event, resp, err -} - -// Get an action for a particular droplet by id. -func (s *DropletActionsServiceOp) Get(dropletID, actionID int) (*Action, *Response, error) { - path := fmt.Sprintf("%s/%d", dropletActionPath(dropletID), actionID) - return s.get(path) -} - -// GetByURI gets an action for a particular droplet by id. -func (s *DropletActionsServiceOp) GetByURI(rawurl string) (*Action, *Response, error) { - u, err := url.Parse(rawurl) - if err != nil { - return nil, nil, err - } - - return s.get(u.Path) - -} - -func (s *DropletActionsServiceOp) get(path string) (*Action, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(actionRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.Event, resp, err - -} - -func dropletActionPath(dropletID int) string { - return fmt.Sprintf("v2/droplets/%d/actions", dropletID) -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/droplet_actions_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/droplet_actions_test.go deleted file mode 100644 index 31efba8f35..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/droplet_actions_test.go +++ /dev/null @@ -1,305 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestDropletActions_DropletActionsServiceOpImplementsDropletActionsService(t *testing.T) { - if !Implements((*DropletActionsService)(nil), new(DropletActionsServiceOp)) { - t.Error("DropletActionsServiceOp does not implement DropletActionsService") - } -} - -func TestDropletActions_Shutdown(t *testing.T) { - setup() - defer teardown() - - request := &ActionRequest{ - Type: "shutdown", - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - }) - - action, _, err := client.DropletActions.Shutdown(1) - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_PowerOff(t *testing.T) { - setup() - defer teardown() - - request := &ActionRequest{ - Type: "power_off", - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - }) - - action, _, err := client.DropletActions.PowerOff(1) - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_PowerOn(t *testing.T) { - setup() - defer teardown() - - request := &ActionRequest{ - Type: "power_on", - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - }) - - action, _, err := client.DropletActions.PowerOn(1) - if err != nil { - t.Errorf("DropletActions.PowerOn returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.PowerOn returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_Reboot(t *testing.T) { - setup() - defer teardown() - - request := &ActionRequest{ - Type: "reboot", - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - - }) - - action, _, err := client.DropletActions.Reboot(1) - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_Restore(t *testing.T) { - setup() - defer teardown() - - options := map[string]interface{}{ - "image": float64(1), - } - - request := &ActionRequest{ - Type: "restore", - Params: options, - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - - }) - - action, _, err := client.DropletActions.Restore(1, 1) - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_Resize(t *testing.T) { - setup() - defer teardown() - - options := map[string]interface{}{ - "size": "1024mb", - } - - request := &ActionRequest{ - Type: "resize", - Params: options, - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - - }) - - action, _, err := client.DropletActions.Resize(1, "1024mb") - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_Rename(t *testing.T) { - setup() - defer teardown() - - options := map[string]interface{}{ - "name": "Droplet-Name", - } - - request := &ActionRequest{ - Type: "rename", - Params: options, - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - }) - - action, _, err := client.DropletActions.Rename(1, "Droplet-Name") - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletAction_PowerCycle(t *testing.T) { - setup() - defer teardown() - - request := &ActionRequest{ - Type: "power_cycle", - } - - mux.HandleFunc("/v2/droplets/1/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, request) { - t.Errorf("Request body = %+v, expected %+v", v, request) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - - }) - - action, _, err := client.DropletActions.PowerCycle(1) - if err != nil { - t.Errorf("DropletActions.Shutdown returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Shutdown returned %+v, expected %+v", action, expected) - } -} - -func TestDropletActions_Get(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/droplets/123/actions/456", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - }) - - action, _, err := client.DropletActions.Get(123, 456) - if err != nil { - t.Errorf("DropletActions.Get returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("DropletActions.Get returned %+v, expected %+v", action, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/droplets.go b/Godeps/_workspace/src/github.com/digitalocean/godo/droplets.go deleted file mode 100644 index 5b73cdc734..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/droplets.go +++ /dev/null @@ -1,179 +0,0 @@ -package godo - -import "fmt" - -const dropletBasePath = "v2/droplets" - -// DropletsService is an interface for interfacing with the droplet -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#droplets -type DropletsService interface { - List(*ListOptions) ([]Droplet, *Response, error) - Get(int) (*DropletRoot, *Response, error) - Create(*DropletCreateRequest) (*DropletRoot, *Response, error) - Delete(int) (*Response, error) - dropletActionStatus(string) (string, error) -} - -// DropletsServiceOp handles communication with the droplet related methods of the -// DigitalOcean API. -type DropletsServiceOp struct { - client *Client -} - -// Droplet represents a DigitalOcean Droplet -type Droplet struct { - ID int `json:"id,float64,omitempty"` - Name string `json:"name,omitempty"` - Memory int `json:"memory,omitempty"` - Vcpus int `json:"vcpus,omitempty"` - Disk int `json:"disk,omitempty"` - Region *Region `json:"region,omitempty"` - Image *Image `json:"image,omitempty"` - Size *Size `json:"size,omitempty"` - BackupIDs []int `json:"backup_ids,omitempty"` - SnapshotIDs []int `json:"snapshot_ids,omitempty"` - Locked bool `json:"locked,bool,omitempty"` - Status string `json:"status,omitempty"` - Networks *Networks `json:"networks,omitempty"` - ActionIDs []int `json:"action_ids,omitempty"` -} - -// Convert Droplet to a string -func (d Droplet) String() string { - return Stringify(d) -} - -// DropletRoot represents a Droplet root -type DropletRoot struct { - Droplet *Droplet `json:"droplet"` - Links *Links `json:"links,omitempty"` -} - -type dropletsRoot struct { - Droplets []Droplet `json:"droplets"` - Links *Links `json:"links"` -} - -// DropletCreateRequest represents a request to create a droplet. -type DropletCreateRequest struct { - Name string `json:"name"` - Region string `json:"region"` - Size string `json:"size"` - Image string `json:"image"` - SSHKeys []interface{} `json:"ssh_keys"` - Backups bool `json:"backups"` - IPv6 bool `json:"ipv6"` - PrivateNetworking bool `json:"private_networking"` - UserData string `json:"user_data"` -} - -func (d DropletCreateRequest) String() string { - return Stringify(d) -} - -// Networks represents the droplet's networks -type Networks struct { - V4 []Network `json:"v4,omitempty"` - V6 []Network `json:"v6,omitempty"` -} - -// Network represents a DigitalOcean Network -type Network struct { - IPAddress string `json:"ip_address,omitempty"` - Netmask string `json:"netmask,omitempty"` - Gateway string `json:"gateway,omitempty"` - Type string `json:"type,omitempty"` -} - -func (n Network) String() string { - return Stringify(n) -} - -// List all droplets -func (s *DropletsServiceOp) List(opt *ListOptions) ([]Droplet, *Response, error) { - path := dropletBasePath - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(dropletsRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.Droplets, resp, err -} - -// Get individual droplet -func (s *DropletsServiceOp) Get(dropletID int) (*DropletRoot, *Response, error) { - path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID) - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(DropletRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return root, resp, err -} - -// Create droplet -func (s *DropletsServiceOp) Create(createRequest *DropletCreateRequest) (*DropletRoot, *Response, error) { - path := dropletBasePath - - req, err := s.client.NewRequest("POST", path, createRequest) - if err != nil { - return nil, nil, err - } - - root := new(DropletRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root, resp, err -} - -// Delete droplet -func (s *DropletsServiceOp) Delete(dropletID int) (*Response, error) { - path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID) - - req, err := s.client.NewRequest("DELETE", path, nil) - if err != nil { - return nil, err - } - - resp, err := s.client.Do(req, nil) - - return resp, err -} - -func (s *DropletsServiceOp) dropletActionStatus(uri string) (string, error) { - action, _, err := s.client.DropletActions.GetByURI(uri) - - if err != nil { - return "", err - } - - return action.Status, nil -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/droplets_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/droplets_test.go deleted file mode 100644 index 97fb442b72..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/droplets_test.go +++ /dev/null @@ -1,242 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestAction_DropletsServiceOpImplementsActionService(t *testing.T) { - if !Implements((*DropletsService)(nil), new(DropletsServiceOp)) { - t.Error("DropletsServiceOp does not implement DropletsService") - } -} - -func TestDroplets_ListDroplets(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"droplets": [{"id":1},{"id":2}]}`) - }) - - droplets, _, err := client.Droplets.List(nil) - if err != nil { - t.Errorf("Droplets.List returned error: %v", err) - } - - expected := []Droplet{{ID: 1}, {ID: 2}} - if !reflect.DeepEqual(droplets, expected) { - t.Errorf("Droplets.List returned %+v, expected %+v", droplets, expected) - } -} - -func TestDroplets_ListDropletsMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - - dr := dropletsRoot{ - Droplets: []Droplet{ - Droplet{ID: 1}, - Droplet{ID: 2}, - }, - Links: &Links{ - Pages: &Pages{Next: "http://example.com/v2/droplets/?page=2"}, - }, - } - - b, err := json.Marshal(dr) - if err != nil { - t.Fatal(err) - } - - fmt.Fprint(w, string(b)) - }) - - _, resp, err := client.Droplets.List(nil) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 1) -} - -func TestDroplets_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "droplets": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/droplets/?page=3", - "prev":"http://example.com/v2/droplets/?page=1", - "last":"http://example.com/v2/droplets/?page=3", - "first":"http://example.com/v2/droplets/?page=1" - } - } - }` - - mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Droplets.List(opt) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 2) -} - -func TestDroplets_GetDroplet(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/droplets/12345", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"droplet":{"id":12345}}`) - }) - - droplets, _, err := client.Droplets.Get(12345) - if err != nil { - t.Errorf("Droplet.Get returned error: %v", err) - } - - expected := &DropletRoot{Droplet: &Droplet{ID: 12345}} - if !reflect.DeepEqual(droplets, expected) { - t.Errorf("Droplets.Get returned %+v, expected %+v", droplets, expected) - } -} - -func TestDroplets_Create(t *testing.T) { - setup() - defer teardown() - - createRequest := &DropletCreateRequest{ - Name: "name", - Region: "region", - Size: "size", - Image: "1", - } - - mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) { - v := new(DropletCreateRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, createRequest) { - t.Errorf("Request body = %+v, expected %+v", v, createRequest) - } - - fmt.Fprintf(w, `{"droplet":{"id":1}, "links":{"actions": [{"id": 1, "href": "http://example.com", "rel": "create"}]}}`) - }) - - root, resp, err := client.Droplets.Create(createRequest) - if err != nil { - t.Errorf("Droplets.Create returned error: %v", err) - } - - if id := root.Droplet.ID; id != 1 { - t.Errorf("expected id '%d', received '%d'", 1, id) - } - - if a := resp.Links.Actions[0]; a.ID != 1 { - t.Errorf("expected action id '%d', received '%d'", 1, a.ID) - } -} - -func TestDroplets_Destroy(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/droplets/12345", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - }) - - _, err := client.Droplets.Delete(12345) - if err != nil { - t.Errorf("Droplet.Delete returned error: %v", err) - } -} - -func TestNetwork_String(t *testing.T) { - network := &Network{ - IPAddress: "192.168.1.2", - Netmask: "255.255.255.0", - Gateway: "192.168.1.1", - } - - stringified := network.String() - expected := `godo.Network{IPAddress:"192.168.1.2", Netmask:"255.255.255.0", Gateway:"192.168.1.1", Type:""}` - if expected != stringified { - t.Errorf("Distribution.String returned %+v, expected %+v", stringified, expected) - } - -} - -func TestDroplet_String(t *testing.T) { - - region := &Region{ - Slug: "region", - Name: "Region", - Sizes: []string{"1", "2"}, - Available: true, - } - - image := &Image{ - ID: 1, - Name: "Image", - Distribution: "Ubuntu", - Slug: "image", - Public: true, - Regions: []string{"one", "two"}, - } - - size := &Size{ - Slug: "size", - PriceMonthly: 123, - PriceHourly: 456, - Regions: []string{"1", "2"}, - } - network := &Network{ - IPAddress: "192.168.1.2", - Netmask: "255.255.255.0", - Gateway: "192.168.1.1", - } - networks := &Networks{ - V4: []Network{*network}, - } - - droplet := &Droplet{ - ID: 1, - Name: "droplet", - Memory: 123, - Vcpus: 456, - Disk: 789, - Region: region, - Image: image, - Size: size, - BackupIDs: []int{1}, - SnapshotIDs: []int{1}, - ActionIDs: []int{1}, - Locked: false, - Status: "active", - Networks: networks, - } - - stringified := droplet.String() - expected := `godo.Droplet{ID:1, Name:"droplet", Memory:123, Vcpus:456, Disk:789, Region:godo.Region{Slug:"region", Name:"Region", Sizes:["1" "2"], Available:true}, Image:godo.Image{ID:1, Name:"Image", Distribution:"Ubuntu", Slug:"image", Public:true, Regions:["one" "two"]}, Size:godo.Size{Slug:"size", Memory:0, Vcpus:0, Disk:0, PriceMonthly:123, PriceHourly:456, Regions:["1" "2"]}, BackupIDs:[1], SnapshotIDs:[1], Locked:false, Status:"active", Networks:godo.Networks{V4:[godo.Network{IPAddress:"192.168.1.2", Netmask:"255.255.255.0", Gateway:"192.168.1.1", Type:""}]}, ActionIDs:[1]}` - if expected != stringified { - t.Errorf("Droplet.String returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/godo.go b/Godeps/_workspace/src/github.com/digitalocean/godo/godo.go deleted file mode 100644 index 34a9854d56..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/godo.go +++ /dev/null @@ -1,302 +0,0 @@ -package godo - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "reflect" - "strconv" - "time" - - "github.com/google/go-querystring/query" - headerLink "github.com/tent/http-link-go" -) - -const ( - libraryVersion = "0.1.0" - defaultBaseURL = "https://api.digitalocean.com/" - userAgent = "godo/" + libraryVersion - mediaType = "application/json" - - headerRateLimit = "X-RateLimit-Limit" - headerRateRemaining = "X-RateLimit-Remaining" - headerRateReset = "X-RateLimit-Reset" -) - -// Client manages communication with DigitalOcean V2 API. -type Client struct { - // HTTP client used to communicate with the DO API. - client *http.Client - - // Base URL for API requests. - BaseURL *url.URL - - // User agent for client - UserAgent string - - // Rate contains the current rate limit for the client as determined by the most recent - // API call. - Rate Rate - - // Services used for communicating with the API - Actions ActionsService - Domains DomainsService - Droplets DropletsService - DropletActions DropletActionsService - Images ImagesService - ImageActions ImageActionsService - Keys KeysService - Regions RegionsService - Sizes SizesService -} - -// ListOptions specifies the optional parameters to various List methods that -// support pagination. -type ListOptions struct { - // For paginated result sets, page of results to retrieve. - Page int `url:"page,omitempty"` - - // For paginated result sets, the number of results to include per page. - PerPage int `url:"per_page,omitempty"` -} - -// Response is a Digital Ocean response. This wraps the standard http.Response returned from DigitalOcean. -type Response struct { - *http.Response - - // Links that were returned with the response. These are parsed from - // request body and not the header. - Links *Links - - // Monitoring URI - Monitor string - - Rate -} - -// An ErrorResponse reports the error caused by an API request -type ErrorResponse struct { - // HTTP response that caused this error - Response *http.Response - - // Error message - Message string -} - -// Rate contains the rate limit for the current client. -type Rate struct { - // The number of request per hour the client is currently limited to. - Limit int `json:"limit"` - - // The number of remaining requests the client can make this hour. - Remaining int `json:"remaining"` - - // The time at w\hic the current rate limit will reset. - Reset Timestamp `json:"reset"` -} - -func addOptions(s string, opt interface{}) (string, error) { - v := reflect.ValueOf(opt) - - if v.Kind() == reflect.Ptr && v.IsNil() { - return s, nil - } - - u, err := url.Parse(s) - if err != nil { - return s, err - } - - qv, err := query.Values(opt) - if err != nil { - return s, err - } - - u.RawQuery = qv.Encode() - return u.String(), nil -} - -// NewClient returns a new Digital Ocean API client. -func NewClient(httpClient *http.Client) *Client { - if httpClient == nil { - httpClient = http.DefaultClient - } - - baseURL, _ := url.Parse(defaultBaseURL) - - c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent} - c.Actions = &ActionsServiceOp{client: c} - c.Domains = &DomainsServiceOp{client: c} - c.Droplets = &DropletsServiceOp{client: c} - c.DropletActions = &DropletActionsServiceOp{client: c} - c.Images = &ImagesServiceOp{client: c} - c.ImageActions = &ImageActionsServiceOp{client: c} - c.Keys = &KeysServiceOp{client: c} - c.Regions = &RegionsServiceOp{client: c} - c.Sizes = &SizesServiceOp{client: c} - - return c -} - -// NewRequest creates an API request. A relative URL can be provided in urlStr, which will be resolved to the -// BaseURL of the Client. Relative URLS should always be specified without a preceding slash. If specified, the -// value pointed to by body is JSON encoded and included in as the request body. -func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) { - rel, err := url.Parse(urlStr) - if err != nil { - return nil, err - } - - u := c.BaseURL.ResolveReference(rel) - - buf := new(bytes.Buffer) - if body != nil { - err := json.NewEncoder(buf).Encode(body) - if err != nil { - return nil, err - } - } - - req, err := http.NewRequest(method, u.String(), buf) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", mediaType) - req.Header.Add("Accept", mediaType) - req.Header.Add("User-Agent", userAgent) - return req, nil -} - -// newResponse creates a new Response for the provided http.Response -func newResponse(r *http.Response) *Response { - response := Response{Response: r} - response.populateRate() - - return &response -} - -func (r *Response) links() (map[string]headerLink.Link, error) { - if linkText, ok := r.Response.Header["Link"]; ok { - links, err := headerLink.Parse(linkText[0]) - - if err != nil { - return nil, err - } - - linkMap := map[string]headerLink.Link{} - for _, link := range links { - linkMap[link.Rel] = link - } - - return linkMap, nil - } - - return map[string]headerLink.Link{}, nil -} - -// populateRate parses the rate related headers and populates the response Rate. -func (r *Response) populateRate() { - if limit := r.Header.Get(headerRateLimit); limit != "" { - r.Rate.Limit, _ = strconv.Atoi(limit) - } - if remaining := r.Header.Get(headerRateRemaining); remaining != "" { - r.Rate.Remaining, _ = strconv.Atoi(remaining) - } - if reset := r.Header.Get(headerRateReset); reset != "" { - if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 { - r.Rate.Reset = Timestamp{time.Unix(v, 0)} - } - } -} - -// Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value -// pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface, -// the raw response will be written to v, without attempting to decode it. -func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { - resp, err := c.client.Do(req) - if err != nil { - return nil, err - } - - defer resp.Body.Close() - - response := newResponse(resp) - c.Rate = response.Rate - - err = CheckResponse(resp) - if err != nil { - return response, err - } - - if v != nil { - if w, ok := v.(io.Writer); ok { - io.Copy(w, resp.Body) - } else { - json.NewDecoder(resp.Body).Decode(v) - } - } - - return response, err -} -func (r *ErrorResponse) Error() string { - return fmt.Sprintf("%v %v: %d %v", - r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message) -} - -// CheckResponse checks the API response for errors, and returns them if present. A response is considered an -// error if it has a status code outside the 200 range. API error responses are expected to have either no response -// body, or a JSON response body that maps to ErrorResponse. Any other response body will be silently ignored. -func CheckResponse(r *http.Response) error { - if c := r.StatusCode; c >= 200 && c <= 299 { - return nil - } - - errorResponse := &ErrorResponse{Response: r} - data, err := ioutil.ReadAll(r.Body) - if err == nil && len(data) > 0 { - json.Unmarshal(data, errorResponse) - } - - return errorResponse -} - -func (r Rate) String() string { - return Stringify(r) -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - p := new(string) - *p = v - return p -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int { - p := new(int) - *p = v - return p -} - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - p := new(bool) - *p = v - return p -} - -// StreamToString converts a reader to a string -func StreamToString(stream io.Reader) string { - buf := new(bytes.Buffer) - buf.ReadFrom(stream) - return buf.String() -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/godo_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/godo_test.go deleted file mode 100644 index 8b71451924..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/godo_test.go +++ /dev/null @@ -1,325 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/http/httptest" - "net/url" - "reflect" - "strings" - "testing" - "time" -) - -var ( - mux *http.ServeMux - - client *Client - - server *httptest.Server -) - -func setup() { - mux = http.NewServeMux() - server = httptest.NewServer(mux) - - client = NewClient(nil) - url, _ := url.Parse(server.URL) - client.BaseURL = url -} - -func teardown() { - server.Close() -} - -func testMethod(t *testing.T, r *http.Request, expected string) { - if expected != r.Method { - t.Errorf("Request method = %v, expected %v", r.Method, expected) - } -} - -type values map[string]string - -func testFormValues(t *testing.T, r *http.Request, values values) { - expected := url.Values{} - for k, v := range values { - expected.Add(k, v) - } - - r.ParseForm() - if !reflect.DeepEqual(expected, r.Form) { - t.Errorf("Request parameters = %v, expected %v", r.Form, expected) - } -} - -func testURLParseError(t *testing.T, err error) { - if err == nil { - t.Errorf("Expected error to be returned") - } - if err, ok := err.(*url.Error); !ok || err.Op != "parse" { - t.Errorf("Expected URL parse error, got %+v", err) - } -} - -func TestNewClient(t *testing.T) { - c := NewClient(nil) - if c.BaseURL.String() != defaultBaseURL { - t.Errorf("NewClient BaseURL = %v, expected %v", c.BaseURL.String(), defaultBaseURL) - } - - if c.UserAgent != userAgent { - t.Errorf("NewClick UserAgent = %v, expected %v", c.UserAgent, userAgent) - } -} - -func TestNewRequest(t *testing.T) { - c := NewClient(nil) - - inURL, outURL := "/foo", defaultBaseURL+"foo" - inBody, outBody := &DropletCreateRequest{Name: "l"}, - `{"name":"l","region":"","size":"","image":"",`+ - `"ssh_keys":null,"backups":false,"ipv6":false,`+ - `"private_networking":false,"user_data":""}`+"\n" - req, _ := c.NewRequest("GET", inURL, inBody) - - // test relative URL was expanded - if req.URL.String() != outURL { - t.Errorf("NewRequest(%v) URL = %v, expected %v", inURL, req.URL, outURL) - } - - // test body was JSON encoded - body, _ := ioutil.ReadAll(req.Body) - if string(body) != outBody { - t.Errorf("NewRequest(%v)Body = %v, expected %v", inBody, string(body), outBody) - } - - // test default user-agent is attached to the request - userAgent := req.Header.Get("User-Agent") - if c.UserAgent != userAgent { - t.Errorf("NewRequest() User-Agent = %v, expected %v", userAgent, c.UserAgent) - } -} - -func TestNewRequest_invalidJSON(t *testing.T) { - c := NewClient(nil) - - type T struct { - A map[int]interface{} - } - _, err := c.NewRequest("GET", "/", &T{}) - - if err == nil { - t.Error("Expected error to be returned.") - } - if err, ok := err.(*json.UnsupportedTypeError); !ok { - t.Errorf("Expected a JSON error; got %#v.", err) - } -} - -func TestNewRequest_badURL(t *testing.T) { - c := NewClient(nil) - _, err := c.NewRequest("GET", ":", nil) - testURLParseError(t, err) -} - -func TestDo(t *testing.T) { - setup() - defer teardown() - - type foo struct { - A string - } - - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - if m := "GET"; m != r.Method { - t.Errorf("Request method = %v, expected %v", r.Method, m) - } - fmt.Fprint(w, `{"A":"a"}`) - }) - - req, _ := client.NewRequest("GET", "/", nil) - body := new(foo) - client.Do(req, body) - - expected := &foo{"a"} - if !reflect.DeepEqual(body, expected) { - t.Errorf("Response body = %v, expected %v", body, expected) - } -} - -func TestDo_httpError(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - http.Error(w, "Bad Request", 400) - }) - - req, _ := client.NewRequest("GET", "/", nil) - _, err := client.Do(req, nil) - - if err == nil { - t.Error("Expected HTTP 400 error.") - } -} - -// Test handling of an error caused by the internal http client's Do() -// function. -func TestDo_redirectLoop(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/", http.StatusFound) - }) - - req, _ := client.NewRequest("GET", "/", nil) - _, err := client.Do(req, nil) - - if err == nil { - t.Error("Expected error to be returned.") - } - if err, ok := err.(*url.Error); !ok { - t.Errorf("Expected a URL error; got %#v.", err) - } -} - -func TestCheckResponse(t *testing.T) { - res := &http.Response{ - Request: &http.Request{}, - StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(strings.NewReader(`{"message":"m", - "errors": [{"resource": "r", "field": "f", "code": "c"}]}`)), - } - err := CheckResponse(res).(*ErrorResponse) - - if err == nil { - t.Fatalf("Expected error response.") - } - - expected := &ErrorResponse{ - Response: res, - Message: "m", - } - if !reflect.DeepEqual(err, expected) { - t.Errorf("Error = %#v, expected %#v", err, expected) - } -} - -// ensure that we properly handle API errors that do not contain a response -// body -func TestCheckResponse_noBody(t *testing.T) { - res := &http.Response{ - Request: &http.Request{}, - StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(strings.NewReader("")), - } - err := CheckResponse(res).(*ErrorResponse) - - if err == nil { - t.Errorf("Expected error response.") - } - - expected := &ErrorResponse{ - Response: res, - } - if !reflect.DeepEqual(err, expected) { - t.Errorf("Error = %#v, expected %#v", err, expected) - } -} - -func TestErrorResponse_Error(t *testing.T) { - res := &http.Response{Request: &http.Request{}} - err := ErrorResponse{Message: "m", Response: res} - if err.Error() == "" { - t.Errorf("Expected non-empty ErrorResponse.Error()") - } -} - -func TestDo_rateLimit(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add(headerRateLimit, "60") - w.Header().Add(headerRateRemaining, "59") - w.Header().Add(headerRateReset, "1372700873") - }) - - var expected int - - if expected = 0; client.Rate.Limit != expected { - t.Errorf("Client rate limit = %v, expected %v", client.Rate.Limit, expected) - } - if expected = 0; client.Rate.Remaining != expected { - t.Errorf("Client rate remaining = %v, got %v", client.Rate.Remaining, expected) - } - if !client.Rate.Reset.IsZero() { - t.Errorf("Client rate reset not initialized to zero value") - } - - req, _ := client.NewRequest("GET", "/", nil) - client.Do(req, nil) - - if expected = 60; client.Rate.Limit != expected { - t.Errorf("Client rate limit = %v, expected %v", client.Rate.Limit, expected) - } - if expected = 59; client.Rate.Remaining != expected { - t.Errorf("Client rate remaining = %v, expected %v", client.Rate.Remaining, expected) - } - reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC) - if client.Rate.Reset.UTC() != reset { - t.Errorf("Client rate reset = %v, expected %v", client.Rate.Reset, reset) - } -} - -func TestDo_rateLimit_errorResponse(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add(headerRateLimit, "60") - w.Header().Add(headerRateRemaining, "59") - w.Header().Add(headerRateReset, "1372700873") - http.Error(w, "Bad Request", 400) - }) - - var expected int - - req, _ := client.NewRequest("GET", "/", nil) - client.Do(req, nil) - - if expected = 60; client.Rate.Limit != expected { - t.Errorf("Client rate limit = %v, expected %v", client.Rate.Limit, expected) - } - if expected = 59; client.Rate.Remaining != expected { - t.Errorf("Client rate remaining = %v, expected %v", client.Rate.Remaining, expected) - } - reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC) - if client.Rate.Reset.UTC() != reset { - t.Errorf("Client rate reset = %v, expected %v", client.Rate.Reset, reset) - } -} - -func Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - interfaceType := reflect.TypeOf(interfaceObject).Elem() - if !reflect.TypeOf(object).Implements(interfaceType) { - return false - } - - return true -} - -func checkCurrentPage(t *testing.T, resp *Response, expectedPage int) { - links := resp.Links - p, err := links.CurrentPage() - if err != nil { - t.Fatal(err) - } - - if p != expectedPage { - t.Fatalf("expected current page to be '%d', was '%d'", expectedPage, p) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/image_actions.go b/Godeps/_workspace/src/github.com/digitalocean/godo/image_actions.go deleted file mode 100644 index c1467d72f6..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/image_actions.go +++ /dev/null @@ -1,53 +0,0 @@ -package godo - -import "fmt" - -// ImageActionsService is an interface for interfacing with the image actions -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#image-actions -type ImageActionsService interface { - Get(int, int) (*Action, *Response, error) - Transfer(int, *ActionRequest) (*Action, *Response, error) -} - -// ImageActionsServiceOp handles communition with the image action related methods of the -// DigitalOcean API. -type ImageActionsServiceOp struct { - client *Client -} - -// Transfer an image -func (i *ImageActionsServiceOp) Transfer(imageID int, transferRequest *ActionRequest) (*Action, *Response, error) { - path := fmt.Sprintf("v2/images/%d/actions", imageID) - - req, err := i.client.NewRequest("POST", path, transferRequest) - if err != nil { - return nil, nil, err - } - - root := new(actionRoot) - resp, err := i.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.Event, resp, err -} - -// Get an action for a particular image by id. -func (i *ImageActionsServiceOp) Get(imageID, actionID int) (*Action, *Response, error) { - path := fmt.Sprintf("v2/images/%d/actions/%d", imageID, actionID) - - req, err := i.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(actionRoot) - resp, err := i.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.Event, resp, err -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/image_actions_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/image_actions_test.go deleted file mode 100644 index 4f7c7e338a..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/image_actions_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestImageActions_ImageActionsServiceOpImplementsImageActionsService(t *testing.T) { - if !Implements((*ImageActionsService)(nil), new(ImageActionsServiceOp)) { - t.Error("ImageActionsServiceOp does not implement ImageActionsService") - } -} - -func TestImageActions_Transfer(t *testing.T) { - setup() - defer teardown() - - transferRequest := &ActionRequest{} - - mux.HandleFunc("/v2/images/12345/actions", func(w http.ResponseWriter, r *http.Request) { - v := new(ActionRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, transferRequest) { - t.Errorf("Request body = %+v, expected %+v", v, transferRequest) - } - - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - - }) - - transfer, _, err := client.ImageActions.Transfer(12345, transferRequest) - if err != nil { - t.Errorf("ImageActions.Transfer returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(transfer, expected) { - t.Errorf("ImageActions.Transfer returned %+v, expected %+v", transfer, expected) - } -} - -func TestImageActions_Get(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/images/123/actions/456", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`) - }) - - action, _, err := client.ImageActions.Get(123, 456) - if err != nil { - t.Errorf("ImageActions.Get returned error: %v", err) - } - - expected := &Action{Status: "in-progress"} - if !reflect.DeepEqual(action, expected) { - t.Errorf("ImageActions.Get returned %+v, expected %+v", action, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/images.go b/Godeps/_workspace/src/github.com/digitalocean/godo/images.go deleted file mode 100644 index 07ec274dc1..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/images.go +++ /dev/null @@ -1,62 +0,0 @@ -package godo - -// ImagesService is an interface for interfacing with the images -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#images -type ImagesService interface { - List(*ListOptions) ([]Image, *Response, error) -} - -// ImagesServiceOp handles communication with the image related methods of the -// DigitalOcean API. -type ImagesServiceOp struct { - client *Client -} - -// Image represents a DigitalOcean Image -type Image struct { - ID int `json:"id,float64,omitempty"` - Name string `json:"name,omitempty"` - Distribution string `json:"distribution,omitempty"` - Slug string `json:"slug,omitempty"` - Public bool `json:"public,omitempty"` - Regions []string `json:"regions,omitempty"` -} - -type imageRoot struct { - Image Image -} - -type imagesRoot struct { - Images []Image - Links *Links `json:"links"` -} - -func (i Image) String() string { - return Stringify(i) -} - -// List all sizes -func (s *ImagesServiceOp) List(opt *ListOptions) ([]Image, *Response, error) { - path := "v2/images" - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(imagesRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.Images, resp, err -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/images_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/images_test.go deleted file mode 100644 index fffbe45302..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/images_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package godo - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestImages_ImagesServiceOpImplementsImagesService(t *testing.T) { - if !Implements((*ImagesService)(nil), new(ImagesServiceOp)) { - t.Error("ImagesServiceOp does not implement ImagesService") - } -} - -func TestImages_List(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"images":[{"id":1},{"id":2}]}`) - }) - - images, _, err := client.Images.List(nil) - if err != nil { - t.Errorf("Images.List returned error: %v", err) - } - - expected := []Image{{ID: 1}, {ID: 2}} - if !reflect.DeepEqual(images, expected) { - t.Errorf("Images.List returned %+v, expected %+v", images, expected) - } -} - -func TestImages_ListImagesMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"images": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/images/?page=2"}}}`) - }) - - _, resp, err := client.Images.List(&ListOptions{Page: 2}) - if err != nil { - t.Fatal(err) - } - checkCurrentPage(t, resp, 1) -} - -func TestImages_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "images": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/images/?page=3", - "prev":"http://example.com/v2/images/?page=1", - "last":"http://example.com/v2/images/?page=3", - "first":"http://example.com/v2/images/?page=1" - } - } - }` - - mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Images.List(opt) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 2) -} - -func TestImage_String(t *testing.T) { - image := &Image{ - ID: 1, - Name: "Image", - Distribution: "Ubuntu", - Slug: "image", - Public: true, - Regions: []string{"one", "two"}, - } - - stringified := image.String() - expected := `godo.Image{ID:1, Name:"Image", Distribution:"Ubuntu", Slug:"image", Public:true, Regions:["one" "two"]}` - if expected != stringified { - t.Errorf("Image.String returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/keys.go b/Godeps/_workspace/src/github.com/digitalocean/godo/keys.go deleted file mode 100644 index 1945aa13e0..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/keys.go +++ /dev/null @@ -1,143 +0,0 @@ -package godo - -import "fmt" - -const keysBasePath = "v2/account/keys" - -// KeysService is an interface for interfacing with the keys -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#keys -type KeysService interface { - List(*ListOptions) ([]Key, *Response, error) - GetByID(int) (*Key, *Response, error) - GetByFingerprint(string) (*Key, *Response, error) - Create(*KeyCreateRequest) (*Key, *Response, error) - DeleteByID(int) (*Response, error) - DeleteByFingerprint(string) (*Response, error) -} - -// KeysServiceOp handles communication with key related method of the -// DigitalOcean API. -type KeysServiceOp struct { - client *Client -} - -// Key represents a DigitalOcean Key. -type Key struct { - ID int `json:"id,float64,omitempty"` - Name string `json:"name,omitempty"` - Fingerprint string `json:"fingerprint,omitempty"` - PublicKey string `json:"public_key,omitempty"` -} - -type keysRoot struct { - SSHKeys []Key `json:"ssh_keys"` - Links *Links `json:"links"` -} - -type keyRoot struct { - SSHKey Key `json:"ssh_key"` -} - -func (s Key) String() string { - return Stringify(s) -} - -// KeyCreateRequest represents a request to create a new key. -type KeyCreateRequest struct { - Name string `json:"name"` - PublicKey string `json:"public_key"` -} - -// List all keys -func (s *KeysServiceOp) List(opt *ListOptions) ([]Key, *Response, error) { - path := keysBasePath - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(keysRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.SSHKeys, resp, err -} - -// Performs a get given a path -func (s *KeysServiceOp) get(path string) (*Key, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(keyRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.SSHKey, resp, err -} - -// GetByID gets a Key by id -func (s *KeysServiceOp) GetByID(keyID int) (*Key, *Response, error) { - path := fmt.Sprintf("%s/%d", keysBasePath, keyID) - return s.get(path) -} - -// GetByFingerprint gets a Key by by fingerprint -func (s *KeysServiceOp) GetByFingerprint(fingerprint string) (*Key, *Response, error) { - path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) - return s.get(path) -} - -// Create a key using a KeyCreateRequest -func (s *KeysServiceOp) Create(createRequest *KeyCreateRequest) (*Key, *Response, error) { - req, err := s.client.NewRequest("POST", keysBasePath, createRequest) - if err != nil { - return nil, nil, err - } - - root := new(keyRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - - return &root.SSHKey, resp, err -} - -// Delete key using a path -func (s *KeysServiceOp) delete(path string) (*Response, error) { - req, err := s.client.NewRequest("DELETE", path, nil) - if err != nil { - return nil, err - } - - resp, err := s.client.Do(req, nil) - - return resp, err -} - -// DeleteByID deletes a key by its id -func (s *KeysServiceOp) DeleteByID(keyID int) (*Response, error) { - path := fmt.Sprintf("%s/%d", keysBasePath, keyID) - return s.delete(path) -} - -// DeleteByFingerprint deletes a key by its fingerprint -func (s *KeysServiceOp) DeleteByFingerprint(fingerprint string) (*Response, error) { - path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) - return s.delete(path) -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/keys_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/keys_test.go deleted file mode 100644 index 6452903835..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/keys_test.go +++ /dev/null @@ -1,196 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestKeys_KeysServiceOpImplementsKeysService(t *testing.T) { - if !Implements((*KeysService)(nil), new(KeysServiceOp)) { - t.Error("KeysServiceOp does not implement KeysService") - } -} - -func TestKeys_List(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"ssh_keys":[{"id":1},{"id":2}]}`) - }) - - keys, _, err := client.Keys.List(nil) - if err != nil { - t.Errorf("Keys.List returned error: %v", err) - } - - expected := []Key{{ID: 1}, {ID: 2}} - if !reflect.DeepEqual(keys, expected) { - t.Errorf("Keys.List returned %+v, expected %+v", keys, expected) - } -} - -func TestKeys_ListKeysMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"droplets": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/account/keys/?page=2"}}}`) - }) - - _, resp, err := client.Keys.List(nil) - if err != nil { - t.Fatal(err) - } - checkCurrentPage(t, resp, 1) -} - -func TestKeys_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "keys": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/account/keys/?page=3", - "prev":"http://example.com/v2/account/keys/?page=1", - "last":"http://example.com/v2/account/keys/?page=3", - "first":"http://example.com/v2/account/keys/?page=1" - } - } - }` - - mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Keys.List(opt) - if err != nil { - t.Fatal(err) - } - checkCurrentPage(t, resp, 2) -} - -func TestKeys_GetByID(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/account/keys/12345", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"ssh_key": {"id":12345}}`) - }) - - keys, _, err := client.Keys.GetByID(12345) - if err != nil { - t.Errorf("Keys.GetByID returned error: %v", err) - } - - expected := &Key{ID: 12345} - if !reflect.DeepEqual(keys, expected) { - t.Errorf("Keys.GetByID returned %+v, expected %+v", keys, expected) - } -} - -func TestKeys_GetByFingerprint(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/account/keys/aa:bb:cc", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"ssh_key": {"fingerprint":"aa:bb:cc"}}`) - }) - - keys, _, err := client.Keys.GetByFingerprint("aa:bb:cc") - if err != nil { - t.Errorf("Keys.GetByFingerprint returned error: %v", err) - } - - expected := &Key{Fingerprint: "aa:bb:cc"} - if !reflect.DeepEqual(keys, expected) { - t.Errorf("Keys.GetByFingerprint returned %+v, expected %+v", keys, expected) - } -} - -func TestKeys_Create(t *testing.T) { - setup() - defer teardown() - - createRequest := &KeyCreateRequest{ - Name: "name", - PublicKey: "ssh-rsa longtextandstuff", - } - - mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) { - v := new(KeyCreateRequest) - json.NewDecoder(r.Body).Decode(v) - - testMethod(t, r, "POST") - if !reflect.DeepEqual(v, createRequest) { - t.Errorf("Request body = %+v, expected %+v", v, createRequest) - } - - fmt.Fprintf(w, `{"ssh_key":{"id":1}}`) - }) - - key, _, err := client.Keys.Create(createRequest) - if err != nil { - t.Errorf("Keys.Create returned error: %v", err) - } - - expected := &Key{ID: 1} - if !reflect.DeepEqual(key, expected) { - t.Errorf("Keys.Create returned %+v, expected %+v", key, expected) - } -} - -func TestKeys_DestroyByID(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/account/keys/12345", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - }) - - _, err := client.Keys.DeleteByID(12345) - if err != nil { - t.Errorf("Keys.Delete returned error: %v", err) - } -} - -func TestKeys_DestroyByFingerprint(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/account/keys/aa:bb:cc", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - }) - - _, err := client.Keys.DeleteByFingerprint("aa:bb:cc") - if err != nil { - t.Errorf("Keys.Delete returned error: %v", err) - } -} - -func TestKey_String(t *testing.T) { - key := &Key{ - ID: 123, - Name: "Key", - Fingerprint: "fingerprint", - PublicKey: "public key", - } - - stringified := key.String() - expected := `godo.Key{ID:123, Name:"Key", Fingerprint:"fingerprint", PublicKey:"public key"}` - if expected != stringified { - t.Errorf("Key.String returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/links_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/links_test.go deleted file mode 100644 index 78f9f4d5a1..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/links_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package godo - -import ( - "encoding/json" - "testing" -) - -var ( - firstPageLinksJSONBlob = []byte(`{ - "links": { - "pages": { - "last": "https://api.digitalocean.com/v2/droplets/?page=3", - "next": "https://api.digitalocean.com/v2/droplets/?page=2" - } - } - }`) - otherPageLinksJSONBlob = []byte(`{ - "links": { - "pages": { - "first": "https://api.digitalocean.com/v2/droplets/?page=1", - "prev": "https://api.digitalocean.com/v2/droplets/?page=1", - "last": "https://api.digitalocean.com/v2/droplets/?page=3", - "next": "https://api.digitalocean.com/v2/droplets/?page=3" - } - } - }`) - lastPageLinksJSONBlob = []byte(`{ - "links": { - "pages": { - "first": "https://api.digitalocean.com/v2/droplets/?page=1", - "prev": "https://api.digitalocean.com/v2/droplets/?page=2" - } - } - }`) - - missingLinksJSONBlob = []byte(`{ }`) -) - -type godoList struct { - Links Links `json:"links"` -} - -func loadLinksJSON(t *testing.T, j []byte) Links { - var list godoList - err := json.Unmarshal(j, &list) - if err != nil { - t.Fatal(err) - } - - return list.Links -} - -func TestLinks_ParseFirst(t *testing.T) { - links := loadLinksJSON(t, firstPageLinksJSONBlob) - _, err := links.CurrentPage() - if err != nil { - t.Fatal(err) - } - - r := &Response{Links: &links} - checkCurrentPage(t, r, 1) - - if links.IsLastPage() { - t.Fatalf("shouldn't be last page") - } -} - -func TestLinks_ParseMiddle(t *testing.T) { - links := loadLinksJSON(t, otherPageLinksJSONBlob) - _, err := links.CurrentPage() - if err != nil { - t.Fatal(err) - } - - r := &Response{Links: &links} - checkCurrentPage(t, r, 2) - - if links.IsLastPage() { - t.Fatalf("shouldn't be last page") - } -} - -func TestLinks_ParseLast(t *testing.T) { - links := loadLinksJSON(t, lastPageLinksJSONBlob) - _, err := links.CurrentPage() - if err != nil { - t.Fatal(err) - } - - r := &Response{Links: &links} - checkCurrentPage(t, r, 3) - if !links.IsLastPage() { - t.Fatalf("expected last page") - } -} - -func TestLinks_ParseMissing(t *testing.T) { - links := loadLinksJSON(t, missingLinksJSONBlob) - _, err := links.CurrentPage() - if err != nil { - t.Fatal(err) - } - - r := &Response{Links: &links} - checkCurrentPage(t, r, 1) -} - -func TestLinks_ParseURL(t *testing.T) { - type linkTest struct { - name, url string - expected int - } - - linkTests := []linkTest{ - { - name: "prev", - url: "https://api.digitalocean.com/v2/droplets/?page=1", - expected: 1, - }, - { - name: "last", - url: "https://api.digitalocean.com/v2/droplets/?page=5", - expected: 5, - }, - { - name: "nexta", - url: "https://api.digitalocean.com/v2/droplets/?page=2", - expected: 2, - }, - } - - for _, lT := range linkTests { - p, err := pageForURL(lT.url) - if err != nil { - t.Fatal(err) - } - - if p != lT.expected { - t.Error("expected page for '%s' to be '%d', was '%d'", - lT.url, lT.expected, p) - } - } - -} - -func TestLinks_ParseEmptyString(t *testing.T) { - type linkTest struct { - name, url string - expected int - } - - linkTests := []linkTest{ - { - name: "none", - url: "http://example.com", - expected: 0, - }, - { - name: "bad", - url: "no url", - expected: 0, - }, - { - name: "empty", - url: "", - expected: 0, - }, - } - - for _, lT := range linkTests { - _, err := pageForURL(lT.url) - if err == nil { - t.Fatalf("expected error for test '%s', but received none", lT.name) - } - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/regions.go b/Godeps/_workspace/src/github.com/digitalocean/godo/regions.go deleted file mode 100644 index 63977fc6d0..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/regions.go +++ /dev/null @@ -1,61 +0,0 @@ -package godo - -// RegionsService is an interface for interfacing with the regions -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#regions -type RegionsService interface { - List(*ListOptions) ([]Region, *Response, error) -} - -// RegionsServiceOp handles communication with the region related methods of the -// DigitalOcean API. -type RegionsServiceOp struct { - client *Client -} - -// Region represents a DigitalOcean Region -type Region struct { - Slug string `json:"slug,omitempty"` - Name string `json:"name,omitempty"` - Sizes []string `json:"sizes,omitempty"` - Available bool `json:"available,omitempty` - Features []string `json:"features,omitempty` -} - -type regionsRoot struct { - Regions []Region - Links *Links `json:"links"` -} - -type regionRoot struct { - Region Region -} - -func (r Region) String() string { - return Stringify(r) -} - -// List all regions -func (s *RegionsServiceOp) List(opt *ListOptions) ([]Region, *Response, error) { - path := "v2/regions" - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(regionsRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.Regions, resp, err -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/regions_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/regions_test.go deleted file mode 100644 index 8c8aa2e0b9..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/regions_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package godo - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestRegions_RegionsServiceOpImplementsRegionsService(t *testing.T) { - if !Implements((*RegionsService)(nil), new(RegionsServiceOp)) { - t.Error("RegionsServiceOp does not implement RegionsService") - } -} - -func TestRegions_List(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/regions", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"regions":[{"slug":"1"},{"slug":"2"}]}`) - }) - - regions, _, err := client.Regions.List(nil) - if err != nil { - t.Errorf("Regions.List returned error: %v", err) - } - - expected := []Region{{Slug: "1"}, {Slug: "2"}} - if !reflect.DeepEqual(regions, expected) { - t.Errorf("Regions.List returned %+v, expected %+v", regions, expected) - } -} - -func TestRegions_ListRegionsMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/regions", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"regions": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/regions/?page=2"}}}`) - }) - - _, resp, err := client.Regions.List(nil) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 1) -} - -func TestRegions_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "regions": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/regions/?page=3", - "prev":"http://example.com/v2/regions/?page=1", - "last":"http://example.com/v2/regions/?page=3", - "first":"http://example.com/v2/regions/?page=1" - } - } - }` - - mux.HandleFunc("/v2/regions", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Regions.List(opt) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 2) -} - -func TestRegion_String(t *testing.T) { - region := &Region{ - Slug: "region", - Name: "Region", - Sizes: []string{"1", "2"}, - Available: true, - } - - stringified := region.String() - expected := `godo.Region{Slug:"region", Name:"Region", Sizes:["1" "2"], Available:true}` - if expected != stringified { - t.Errorf("Region.String returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/sizes.go b/Godeps/_workspace/src/github.com/digitalocean/godo/sizes.go deleted file mode 100644 index 108b962e4a..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/sizes.go +++ /dev/null @@ -1,59 +0,0 @@ -package godo - -// SizesService is an interface for interfacing with the size -// endpoints of the Digital Ocean API -// See: https://developers.digitalocean.com/#sizes -type SizesService interface { - List(*ListOptions) ([]Size, *Response, error) -} - -// SizesServiceOp handles communication with the size related methods of the -// DigitalOcean API. -type SizesServiceOp struct { - client *Client -} - -// Size represents a DigitalOcean Size -type Size struct { - Slug string `json:"slug,omitempty"` - Memory int `json:"memory,omitempty"` - Vcpus int `json:"vcpus,omitempty"` - Disk int `json:"disk,omitempty"` - PriceMonthly float64 `json:"price_monthly,omitempty"` - PriceHourly float64 `json:"price_hourly,omitempty"` - Regions []string `json:"regions,omitempty"` -} - -func (s Size) String() string { - return Stringify(s) -} - -type sizesRoot struct { - Sizes []Size - Links *Links `json:"links"` -} - -// List all images -func (s *SizesServiceOp) List(opt *ListOptions) ([]Size, *Response, error) { - path := "v2/sizes" - path, err := addOptions(path, opt) - if err != nil { - return nil, nil, err - } - - req, err := s.client.NewRequest("GET", path, nil) - if err != nil { - return nil, nil, err - } - - root := new(sizesRoot) - resp, err := s.client.Do(req, root) - if err != nil { - return nil, resp, err - } - if l := root.Links; l != nil { - resp.Links = l - } - - return root.Sizes, resp, err -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/sizes_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/sizes_test.go deleted file mode 100644 index 54f8e9c38f..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/sizes_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package godo - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestSizes_SizesServiceOpImplementsSizesService(t *testing.T) { - if !Implements((*SizesService)(nil), new(SizesServiceOp)) { - t.Error("SizesServiceOp does not implement SizesService") - } -} - -func TestSizes_List(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/sizes", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"sizes":[{"slug":"1"},{"slug":"2"}]}`) - }) - - sizes, _, err := client.Sizes.List(nil) - if err != nil { - t.Errorf("Sizes.List returned error: %v", err) - } - - expected := []Size{{Slug: "1"}, {Slug: "2"}} - if !reflect.DeepEqual(sizes, expected) { - t.Errorf("Sizes.List returned %+v, expected %+v", sizes, expected) - } -} - -func TestSizes_ListSizesMultiplePages(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/v2/sizes", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"sizes": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/sizes/?page=2"}}}`) - }) - - _, resp, err := client.Sizes.List(nil) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 1) -} - -func TestSizes_RetrievePageByNumber(t *testing.T) { - setup() - defer teardown() - - jBlob := ` - { - "sizes": [{"id":1},{"id":2}], - "links":{ - "pages":{ - "next":"http://example.com/v2/sizes/?page=3", - "prev":"http://example.com/v2/sizes/?page=1", - "last":"http://example.com/v2/sizes/?page=3", - "first":"http://example.com/v2/sizes/?page=1" - } - } - }` - - mux.HandleFunc("/v2/sizes", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, jBlob) - }) - - opt := &ListOptions{Page: 2} - _, resp, err := client.Sizes.List(opt) - if err != nil { - t.Fatal(err) - } - - checkCurrentPage(t, resp, 2) -} - -func TestSize_String(t *testing.T) { - size := &Size{ - Slug: "slize", - Memory: 123, - Vcpus: 456, - Disk: 789, - PriceMonthly: 123, - PriceHourly: 456, - Regions: []string{"1", "2"}, - } - - stringified := size.String() - expected := `godo.Size{Slug:"slize", Memory:123, Vcpus:456, Disk:789, PriceMonthly:123, PriceHourly:456, Regions:["1" "2"]}` - if expected != stringified { - t.Errorf("Size.String returned %+v, expected %+v", stringified, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/strings.go b/Godeps/_workspace/src/github.com/digitalocean/godo/strings.go deleted file mode 100644 index f1789e9d79..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/strings.go +++ /dev/null @@ -1,84 +0,0 @@ -package godo - -import ( - "bytes" - "fmt" - "io" - "reflect" -) - -var timestampType = reflect.TypeOf(Timestamp{}) - -// Stringify attempts to create a string representation of Digital Ocean types -func Stringify(message interface{}) string { - var buf bytes.Buffer - v := reflect.ValueOf(message) - stringifyValue(&buf, v) - return buf.String() -} - -// stringifyValue was graciously cargoculted from the goprotubuf library -func stringifyValue(w io.Writer, val reflect.Value) { - if val.Kind() == reflect.Ptr && val.IsNil() { - w.Write([]byte("")) - return - } - - v := reflect.Indirect(val) - - switch v.Kind() { - case reflect.String: - fmt.Fprintf(w, `"%s"`, v) - case reflect.Slice: - w.Write([]byte{'['}) - for i := 0; i < v.Len(); i++ { - if i > 0 { - w.Write([]byte{' '}) - } - - stringifyValue(w, v.Index(i)) - } - - w.Write([]byte{']'}) - return - case reflect.Struct: - if v.Type().Name() != "" { - w.Write([]byte(v.Type().String())) - } - - // special handling of Timestamp values - if v.Type() == timestampType { - fmt.Fprintf(w, "{%s}", v.Interface()) - return - } - - w.Write([]byte{'{'}) - - var sep bool - for i := 0; i < v.NumField(); i++ { - fv := v.Field(i) - if fv.Kind() == reflect.Ptr && fv.IsNil() { - continue - } - if fv.Kind() == reflect.Slice && fv.IsNil() { - continue - } - - if sep { - w.Write([]byte(", ")) - } else { - sep = true - } - - w.Write([]byte(v.Type().Field(i).Name)) - w.Write([]byte{':'}) - stringifyValue(w, fv) - } - - w.Write([]byte{'}'}) - default: - if v.CanInterface() { - fmt.Fprint(w, v.Interface()) - } - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/timestamp_test.go b/Godeps/_workspace/src/github.com/digitalocean/godo/timestamp_test.go deleted file mode 100644 index 087e8aac14..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/timestamp_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "testing" - "time" -) - -const ( - emptyTimeStr = `"0001-01-01T00:00:00Z"` - referenceTimeStr = `"2006-01-02T15:04:05Z"` - referenceUnixTimeStr = `1136214245` -) - -var ( - referenceTime = time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC) - unixOrigin = time.Unix(0, 0).In(time.UTC) -) - -func TestTimestamp_Marshal(t *testing.T) { - testCases := []struct { - desc string - data Timestamp - want string - wantErr bool - equal bool - }{ - {"Reference", Timestamp{referenceTime}, referenceTimeStr, false, true}, - {"Empty", Timestamp{}, emptyTimeStr, false, true}, - {"Mismatch", Timestamp{}, referenceTimeStr, false, false}, - } - for _, tc := range testCases { - out, err := json.Marshal(tc.data) - if gotErr := (err != nil); gotErr != tc.wantErr { - t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) - } - got := string(out) - equal := got == tc.want - if (got == tc.want) != tc.equal { - t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) - } - } -} - -func TestTimestamp_Unmarshal(t *testing.T) { - testCases := []struct { - desc string - data string - want Timestamp - wantErr bool - equal bool - }{ - {"Reference", referenceTimeStr, Timestamp{referenceTime}, false, true}, - {"ReferenceUnix", `1136214245`, Timestamp{referenceTime}, false, true}, - {"Empty", emptyTimeStr, Timestamp{}, false, true}, - {"UnixStart", `0`, Timestamp{unixOrigin}, false, true}, - {"Mismatch", referenceTimeStr, Timestamp{}, false, false}, - {"MismatchUnix", `0`, Timestamp{}, false, false}, - {"Invalid", `"asdf"`, Timestamp{referenceTime}, true, false}, - } - for _, tc := range testCases { - var got Timestamp - err := json.Unmarshal([]byte(tc.data), &got) - if gotErr := err != nil; gotErr != tc.wantErr { - t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) - continue - } - equal := got.Equal(tc.want) - if equal != tc.equal { - t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) - } - } -} - -func TestTimstamp_MarshalReflexivity(t *testing.T) { - testCases := []struct { - desc string - data Timestamp - }{ - {"Reference", Timestamp{referenceTime}}, - {"Empty", Timestamp{}}, - } - for _, tc := range testCases { - data, err := json.Marshal(tc.data) - if err != nil { - t.Errorf("%s: Marshal err=%v", tc.desc, err) - } - var got Timestamp - err = json.Unmarshal(data, &got) - if !got.Equal(tc.data) { - t.Errorf("%s: %+v != %+v", tc.desc, got, data) - } - } -} - -type WrappedTimestamp struct { - A int - Time Timestamp -} - -func TestWrappedTimstamp_Marshal(t *testing.T) { - testCases := []struct { - desc string - data WrappedTimestamp - want string - wantErr bool - equal bool - }{ - {"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, true}, - {"Empty", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, emptyTimeStr), false, true}, - {"Mismatch", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, false}, - } - for _, tc := range testCases { - out, err := json.Marshal(tc.data) - if gotErr := err != nil; gotErr != tc.wantErr { - t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) - } - got := string(out) - equal := got == tc.want - if equal != tc.equal { - t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) - } - } -} - -func TestWrappedTimestamp_Unmarshal(t *testing.T) { - testCases := []struct { - desc string - data string - want WrappedTimestamp - wantErr bool - equal bool - }{ - {"Reference", referenceTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true}, - {"ReferenceUnix", referenceUnixTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true}, - {"Empty", emptyTimeStr, WrappedTimestamp{0, Timestamp{}}, false, true}, - {"UnixStart", `0`, WrappedTimestamp{0, Timestamp{unixOrigin}}, false, true}, - {"Mismatch", referenceTimeStr, WrappedTimestamp{0, Timestamp{}}, false, false}, - {"MismatchUnix", `0`, WrappedTimestamp{0, Timestamp{}}, false, false}, - {"Invalid", `"asdf"`, WrappedTimestamp{0, Timestamp{referenceTime}}, true, false}, - } - for _, tc := range testCases { - var got Timestamp - err := json.Unmarshal([]byte(tc.data), &got) - if gotErr := err != nil; gotErr != tc.wantErr { - t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) - continue - } - equal := got.Time.Equal(tc.want.Time.Time) - if equal != tc.equal { - t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) - } - } -} - -func TestWrappedTimestamp_MarshalReflexivity(t *testing.T) { - testCases := []struct { - desc string - data WrappedTimestamp - }{ - {"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}}, - {"Empty", WrappedTimestamp{0, Timestamp{}}}, - } - for _, tc := range testCases { - bytes, err := json.Marshal(tc.data) - if err != nil { - t.Errorf("%s: Marshal err=%v", tc.desc, err) - } - var got WrappedTimestamp - err = json.Unmarshal(bytes, &got) - if !got.Time.Equal(tc.data.Time) { - t.Errorf("%s: %+v != %+v", tc.desc, got, tc.data) - } - } -} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/util/droplet.go b/Godeps/_workspace/src/github.com/digitalocean/godo/util/droplet.go deleted file mode 100644 index da6cef21f7..0000000000 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/util/droplet.go +++ /dev/null @@ -1,47 +0,0 @@ -package util - -import ( - "fmt" - "time" - - "github.com/digitaloceancloud/godo" -) - -const ( - // activeFailure is the amount of times we can fail before deciding - // the check for active is a total failure. This can help account - // for servers randomly not answering. - activeFailure = 3 -) - -// WaitForActive waits for a droplet to become active -func WaitForActive(client *godo.Client, monitorURI string) error { - if len(monitorURI) == 0 { - return fmt.Errorf("create had no monitor uri") - } - - completed := false - failCount := 0 - for !completed { - action, _, err := client.DropletActions.GetByURI(monitorURI) - - if err != nil { - if failCount <= activeFailure { - failCount++ - continue - } - return err - } - - switch action.Status { - case godo.ActionInProgress: - time.Sleep(5 * time.Second) - case godo.ActionCompleted: - completed = true - default: - return fmt.Errorf("unknown status: [%s]", action.Status) - } - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/api/MAINTAINERS deleted file mode 100644 index 96abeae570..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Victor Vieux (@vieux) -Jessie Frazelle (@jfrazelle) diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/README.md b/Godeps/_workspace/src/github.com/docker/docker/api/README.md deleted file mode 100644 index 453f61a1a1..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/README.md +++ /dev/null @@ -1,5 +0,0 @@ -This directory contains code pertaining to the Docker API: - - - Used by the docker client when communicating with the docker daemon - - - Used by third party tools wishing to interface with the docker daemon diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/api_unit_test.go b/Godeps/_workspace/src/github.com/docker/docker/api/api_unit_test.go deleted file mode 100644 index 678331d369..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/api_unit_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package api - -import ( - "testing" -) - -func TestJsonContentType(t *testing.T) { - if !MatchesContentType("application/json", "application/json") { - t.Fail() - } - - if !MatchesContentType("application/json; charset=utf-8", "application/json") { - t.Fail() - } - - if MatchesContentType("dockerapplication/json", "application/json") { - t.Fail() - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/client/auth.go b/Godeps/_workspace/src/github.com/docker/docker/api/client/auth.go deleted file mode 100644 index a2124048c7..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/client/auth.go +++ /dev/null @@ -1,159 +0,0 @@ -package client - -import ( - "bufio" - "crypto/tls" - "crypto/x509" - "fmt" - "io/ioutil" - "log" - "os" - "strings" - "time" - - "github.com/docker/libtrust" -) - -// NewIdentityAuthTLSConfig creates a tls.Config for the client to use for -// libtrust identity authentication -func NewIdentityAuthTLSConfig(trustKey libtrust.PrivateKey, knownHostsPath, proto, addr string) (*tls.Config, error) { - tlsConfig := createTLSConfig() - - // Load known hosts - knownHosts, err := libtrust.LoadKeySetFile(knownHostsPath) - if err != nil { - return nil, fmt.Errorf("Could not load trusted hosts file: %s", err) - } - - // Generate CA pool from known hosts - allowedHosts, err := libtrust.FilterByHosts(knownHosts, addr, false) - if err != nil { - return nil, fmt.Errorf("Error filtering hosts: %s", err) - } - certPool, err := libtrust.GenerateCACertPool(trustKey, allowedHosts) - if err != nil { - return nil, fmt.Errorf("Could not create CA pool: %s", err) - } - tlsConfig.ServerName = "docker" - tlsConfig.RootCAs = certPool - - // Generate client cert from trust key - x509Cert, err := libtrust.GenerateSelfSignedClientCert(trustKey) - if err != nil { - return nil, fmt.Errorf("Certificate generation error: %s", err) - } - tlsConfig.Certificates = []tls.Certificate{{ - Certificate: [][]byte{x509Cert.Raw}, - PrivateKey: trustKey.CryptoPrivateKey(), - Leaf: x509Cert, - }} - - // Connect to server to see if it is a known host - tlsConfig.InsecureSkipVerify = true - testConn, err := tls.Dial(proto, addr, tlsConfig) - if err != nil { - return nil, fmt.Errorf("TLS Handshake error: %s", err) - } - opts := x509.VerifyOptions{ - Roots: tlsConfig.RootCAs, - CurrentTime: time.Now(), - DNSName: tlsConfig.ServerName, - Intermediates: x509.NewCertPool(), - } - - certs := testConn.ConnectionState().PeerCertificates - for i, cert := range certs { - if i == 0 { - continue - } - opts.Intermediates.AddCert(cert) - } - _, err = certs[0].Verify(opts) - if err != nil { - if _, ok := err.(x509.UnknownAuthorityError); ok { - pubKey, err := libtrust.FromCryptoPublicKey(certs[0].PublicKey) - if err != nil { - return nil, fmt.Errorf("Error extracting public key from certificate: %s", err) - } - - // If server is not a known host, prompt user to ask whether it should - // be trusted and add to the known hosts file - if promptUnknownKey(pubKey, addr) { - pubKey.AddExtendedField("hosts", []string{addr}) - err = libtrust.AddKeySetFile(knownHostsPath, pubKey) - if err != nil { - return nil, fmt.Errorf("Error saving updated host keys file: %s", err) - } - - ca, err := libtrust.GenerateCACert(trustKey, pubKey) - if err != nil { - return nil, fmt.Errorf("Error generating CA: %s", err) - } - tlsConfig.RootCAs.AddCert(ca) - } else { - return nil, fmt.Errorf("Cancelling request due to invalid certificate") - } - } else { - return nil, fmt.Errorf("TLS verification error: %s", err) - } - } - - testConn.Close() - tlsConfig.InsecureSkipVerify = false - - return tlsConfig, nil -} - -// NewCertAuthTLSConfig creates a tls.Config for the client to use for -// certificate authentication -func NewCertAuthTLSConfig(caPath, certPath, keyPath string) (*tls.Config, error) { - tlsConfig := createTLSConfig() - - // Verify the server against a CA certificate? - if caPath != "" { - certPool := x509.NewCertPool() - file, err := ioutil.ReadFile(caPath) - if err != nil { - return nil, fmt.Errorf("Couldn't read ca cert %s: %s", caPath, err) - } - certPool.AppendCertsFromPEM(file) - tlsConfig.RootCAs = certPool - } else { - tlsConfig.InsecureSkipVerify = true - } - - // Try to load and send client certificates - if certPath != "" && keyPath != "" { - _, errCert := os.Stat(certPath) - _, errKey := os.Stat(keyPath) - if errCert == nil && errKey == nil { - cert, err := tls.LoadX509KeyPair(certPath, keyPath) - if err != nil { - return nil, fmt.Errorf("Couldn't load X509 key pair: %s. Key encrypted?", err) - } - tlsConfig.Certificates = []tls.Certificate{cert} - } - } - return tlsConfig, nil -} - -// createTLSConfig creates the base tls.Config used by auth methods with some -// sensible defaults -func createTLSConfig() *tls.Config { - return &tls.Config{ - // Avoid fallback to SSL protocols < TLS1.0 - MinVersion: tls.VersionTLS10, - } -} - -func promptUnknownKey(key libtrust.PublicKey, host string) bool { - fmt.Printf("The authenticity of host %q can't be established.\nRemote key ID %s\n", host, key.KeyID()) - fmt.Printf("Are you sure you want to continue connecting (yes/no)? ") - reader := bufio.NewReader(os.Stdin) - line, _, err := reader.ReadLine() - if err != nil { - log.Fatalf("Error reading input: %s", err) - } - input := strings.TrimSpace(strings.ToLower(string(line))) - return input == "yes" || input == "y" -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/client/cli.go b/Godeps/_workspace/src/github.com/docker/docker/api/client/cli.go deleted file mode 100644 index a477d0b3a9..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/client/cli.go +++ /dev/null @@ -1,170 +0,0 @@ -package client - -import ( - "crypto/tls" - "encoding/json" - "fmt" - "io" - "net" - "net/http" - "os" - "reflect" - "strings" - "text/template" - "time" - - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/term" - "github.com/docker/docker/registry" - "github.com/docker/libtrust" -) - -type DockerCli struct { - proto string - addr string - configFile *registry.ConfigFile - in io.ReadCloser - out io.Writer - err io.Writer - key libtrust.PrivateKey - tlsConfig *tls.Config - scheme string - // inFd holds file descriptor of the client's STDIN, if it's a valid file - inFd uintptr - // outFd holds file descriptor of the client's STDOUT, if it's a valid file - outFd uintptr - // isTerminalIn describes if client's STDIN is a TTY - isTerminalIn bool - // isTerminalOut describes if client's STDOUT is a TTY - isTerminalOut bool - transport *http.Transport -} - -var funcMap = template.FuncMap{ - "json": func(v interface{}) string { - a, _ := json.Marshal(v) - return string(a) - }, -} - -func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) { - camelArgs := make([]string, len(args)) - for i, s := range args { - if len(s) == 0 { - return nil, false - } - camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:]) - } - methodName := "Cmd" + strings.Join(camelArgs, "") - method := reflect.ValueOf(cli).MethodByName(methodName) - if !method.IsValid() { - return nil, false - } - return method.Interface().(func(...string) error), true -} - -// Cmd executes the specified command -func (cli *DockerCli) Cmd(args ...string) error { - if len(args) > 1 { - method, exists := cli.getMethod(args[:2]...) - if exists { - return method(args[2:]...) - } - } - if len(args) > 0 { - method, exists := cli.getMethod(args[0]) - if !exists { - fmt.Println("Error: Command not found:", args[0]) - return cli.CmdHelp() - } - return method(args[1:]...) - } - return cli.CmdHelp() -} - -func (cli *DockerCli) Subcmd(name, signature, description string) *flag.FlagSet { - flags := flag.NewFlagSet(name, flag.ContinueOnError) - flags.Usage = func() { - options := "" - if flags.FlagCountUndeprecated() > 0 { - options = "[OPTIONS] " - } - fmt.Fprintf(cli.err, "\nUsage: docker %s %s%s\n\n%s\n\n", name, options, signature, description) - flags.PrintDefaults() - os.Exit(2) - } - return flags -} - -func (cli *DockerCli) LoadConfigFile() (err error) { - cli.configFile, err = registry.LoadConfig(os.Getenv("HOME")) - if err != nil { - fmt.Fprintf(cli.err, "WARNING: %s\n", err) - } - return err -} - -func NewDockerCli(in io.ReadCloser, out, err io.Writer, key libtrust.PrivateKey, proto, addr string, tlsConfig *tls.Config) *DockerCli { - var ( - inFd uintptr - outFd uintptr - isTerminalIn = false - isTerminalOut = false - scheme = "http" - ) - - if tlsConfig != nil { - scheme = "https" - } - - if in != nil { - if file, ok := in.(*os.File); ok { - inFd = file.Fd() - isTerminalIn = term.IsTerminal(inFd) - } - } - - if out != nil { - if file, ok := out.(*os.File); ok { - outFd = file.Fd() - isTerminalOut = term.IsTerminal(outFd) - } - } - - if err == nil { - err = out - } - - // The transport is created here for reuse during the client session - tr := &http.Transport{ - TLSClientConfig: tlsConfig, - } - - // Why 32? See issue 8035 - timeout := 32 * time.Second - if proto == "unix" { - // no need in compressing for local communications - tr.DisableCompression = true - tr.Dial = func(_, _ string) (net.Conn, error) { - return net.DialTimeout(proto, addr, timeout) - } - } else { - tr.Dial = (&net.Dialer{Timeout: timeout}).Dial - } - - return &DockerCli{ - proto: proto, - addr: addr, - in: in, - out: out, - err: err, - key: key, - inFd: inFd, - outFd: outFd, - isTerminalIn: isTerminalIn, - isTerminalOut: isTerminalOut, - tlsConfig: tlsConfig, - scheme: scheme, - transport: tr, - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/client/commands.go b/Godeps/_workspace/src/github.com/docker/docker/api/client/commands.go deleted file mode 100644 index 4255bdbc50..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/client/commands.go +++ /dev/null @@ -1,2644 +0,0 @@ -package client - -import ( - "bufio" - "bytes" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "os/exec" - "path" - "path/filepath" - "runtime" - "strconv" - "strings" - "text/tabwriter" - "text/template" - "time" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/api" - "github.com/docker/docker/dockerversion" - "github.com/docker/docker/engine" - "github.com/docker/docker/graph" - "github.com/docker/docker/nat" - "github.com/docker/docker/opts" - "github.com/docker/docker/pkg/archive" - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/parsers" - "github.com/docker/docker/pkg/parsers/filters" - "github.com/docker/docker/pkg/promise" - "github.com/docker/docker/pkg/signal" - "github.com/docker/docker/pkg/term" - "github.com/docker/docker/pkg/timeutils" - "github.com/docker/docker/pkg/units" - "github.com/docker/docker/registry" - "github.com/docker/docker/runconfig" - "github.com/docker/docker/utils" -) - -const ( - tarHeaderSize = 512 -) - -var ( - acceptedImageFilterTags = map[string]struct{}{"dangling": {}} -) - -func (cli *DockerCli) CmdHelp(args ...string) error { - if len(args) > 1 { - method, exists := cli.getMethod(args[:2]...) - if exists { - method("--help") - return nil - } - } - if len(args) > 0 { - method, exists := cli.getMethod(args[0]) - if !exists { - fmt.Fprintf(cli.err, "Error: Command not found: %s\n", args[0]) - } else { - method("--help") - return nil - } - } - - flag.Usage() - - return nil -} - -func (cli *DockerCli) CmdBuild(args ...string) error { - cmd := cli.Subcmd("build", "PATH | URL | -", "Build a new image from the source code at PATH") - tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success") - suppressOutput := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the verbose output generated by the containers") - noCache := cmd.Bool([]string{"#no-cache", "-no-cache"}, false, "Do not use cache when building the image") - rm := cmd.Bool([]string{"#rm", "-rm"}, true, "Remove intermediate containers after a successful build") - forceRm := cmd.Bool([]string{"-force-rm"}, false, "Always remove intermediate containers, even after unsuccessful builds") - pull := cmd.Bool([]string{"-pull"}, false, "Always attempt to pull a newer version of the image") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - var ( - context archive.Archive - isRemote bool - err error - ) - - _, err = exec.LookPath("git") - hasGit := err == nil - if cmd.Arg(0) == "-" { - // As a special case, 'docker build -' will build from either an empty context with the - // contents of stdin as a Dockerfile, or a tar-ed context from stdin. - buf := bufio.NewReader(cli.in) - magic, err := buf.Peek(tarHeaderSize) - if err != nil && err != io.EOF { - return fmt.Errorf("failed to peek context header from STDIN: %v", err) - } - if !archive.IsArchive(magic) { - dockerfile, err := ioutil.ReadAll(buf) - if err != nil { - return fmt.Errorf("failed to read Dockerfile from STDIN: %v", err) - } - context, err = archive.Generate("Dockerfile", string(dockerfile)) - } else { - context = ioutil.NopCloser(buf) - } - } else if utils.IsURL(cmd.Arg(0)) && (!utils.IsGIT(cmd.Arg(0)) || !hasGit) { - isRemote = true - } else { - root := cmd.Arg(0) - if utils.IsGIT(root) { - remoteURL := cmd.Arg(0) - if !utils.ValidGitTransport(remoteURL) { - remoteURL = "https://" + remoteURL - } - - root, err = ioutil.TempDir("", "docker-build-git") - if err != nil { - return err - } - defer os.RemoveAll(root) - - if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil { - return fmt.Errorf("Error trying to use git: %s (%s)", err, output) - } - } - if _, err := os.Stat(root); err != nil { - return err - } - filename := path.Join(root, "Dockerfile") - if _, err = os.Stat(filename); os.IsNotExist(err) { - return fmt.Errorf("no Dockerfile found in %s", cmd.Arg(0)) - } - var excludes []string - ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore")) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("Error reading .dockerignore: '%s'", err) - } - for _, pattern := range strings.Split(string(ignore), "\n") { - pattern = strings.TrimSpace(pattern) - if pattern == "" { - continue - } - pattern = filepath.Clean(pattern) - ok, err := filepath.Match(pattern, "Dockerfile") - if err != nil { - return fmt.Errorf("Bad .dockerignore pattern: '%s', error: %s", pattern, err) - } - if ok { - return fmt.Errorf("Dockerfile was excluded by .dockerignore pattern '%s'", pattern) - } - excludes = append(excludes, pattern) - } - if err = utils.ValidateContextDirectory(root, excludes); err != nil { - return fmt.Errorf("Error checking context is accessible: '%s'. Please check permissions and try again.", err) - } - options := &archive.TarOptions{ - Compression: archive.Uncompressed, - Excludes: excludes, - } - context, err = archive.TarWithOptions(root, options) - if err != nil { - return err - } - } - var body io.Reader - // Setup an upload progress bar - // FIXME: ProgressReader shouldn't be this annoying to use - if context != nil { - sf := utils.NewStreamFormatter(false) - body = utils.ProgressReader(context, 0, cli.err, sf, true, "", "Sending build context to Docker daemon") - } - // Send the build context - v := &url.Values{} - - //Check if the given image name can be resolved - if *tag != "" { - repository, tag := parsers.ParseRepositoryTag(*tag) - if _, _, err := registry.ResolveRepositoryName(repository); err != nil { - return err - } - if len(tag) > 0 { - if err := graph.ValidateTagName(tag); err != nil { - return err - } - } - } - - v.Set("t", *tag) - - if *suppressOutput { - v.Set("q", "1") - } - if isRemote { - v.Set("remote", cmd.Arg(0)) - } - if *noCache { - v.Set("nocache", "1") - } - if *rm { - v.Set("rm", "1") - } else { - v.Set("rm", "0") - } - - if *forceRm { - v.Set("forcerm", "1") - } - - if *pull { - v.Set("pull", "1") - } - cli.LoadConfigFile() - - headers := http.Header(make(map[string][]string)) - buf, err := json.Marshal(cli.configFile) - if err != nil { - return err - } - headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) - - if context != nil { - headers.Set("Content-Type", "application/tar") - } - err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), body, cli.out, headers) - if jerr, ok := err.(*utils.JSONError); ok { - // If no error code is set, default to 1 - if jerr.Code == 0 { - jerr.Code = 1 - } - return &utils.StatusError{Status: jerr.Message, StatusCode: jerr.Code} - } - return err -} - -// 'docker login': login / register a user to registry service. -func (cli *DockerCli) CmdLogin(args ...string) error { - cmd := cli.Subcmd("login", "[SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.") - - var username, password, email string - - cmd.StringVar(&username, []string{"u", "-username"}, "", "Username") - cmd.StringVar(&password, []string{"p", "-password"}, "", "Password") - cmd.StringVar(&email, []string{"e", "-email"}, "", "Email") - err := cmd.Parse(args) - if err != nil { - return nil - } - serverAddress := registry.IndexServerAddress() - if len(cmd.Args()) > 0 { - serverAddress = cmd.Arg(0) - } - - promptDefault := func(prompt string, configDefault string) { - if configDefault == "" { - fmt.Fprintf(cli.out, "%s: ", prompt) - } else { - fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault) - } - } - - readInput := func(in io.Reader, out io.Writer) string { - reader := bufio.NewReader(in) - line, _, err := reader.ReadLine() - if err != nil { - fmt.Fprintln(out, err.Error()) - os.Exit(1) - } - return string(line) - } - - cli.LoadConfigFile() - authconfig, ok := cli.configFile.Configs[serverAddress] - if !ok { - authconfig = registry.AuthConfig{} - } - - if username == "" { - promptDefault("Username", authconfig.Username) - username = readInput(cli.in, cli.out) - if username == "" { - username = authconfig.Username - } - } - // Assume that a different username means they may not want to use - // the password or email from the config file, so prompt them - if username != authconfig.Username { - if password == "" { - oldState, err := term.SaveState(cli.inFd) - if err != nil { - return err - } - fmt.Fprintf(cli.out, "Password: ") - term.DisableEcho(cli.inFd, oldState) - - password = readInput(cli.in, cli.out) - fmt.Fprint(cli.out, "\n") - - term.RestoreTerminal(cli.inFd, oldState) - if password == "" { - return fmt.Errorf("Error : Password Required") - } - } - - if email == "" { - promptDefault("Email", authconfig.Email) - email = readInput(cli.in, cli.out) - if email == "" { - email = authconfig.Email - } - } - } else { - // However, if they don't override the username use the - // password or email from the cmd line if specified. IOW, allow - // then to change/overide them. And if not specified, just - // use what's in the config file - if password == "" { - password = authconfig.Password - } - if email == "" { - email = authconfig.Email - } - } - authconfig.Username = username - authconfig.Password = password - authconfig.Email = email - authconfig.ServerAddress = serverAddress - cli.configFile.Configs[serverAddress] = authconfig - - stream, statusCode, err := cli.call("POST", "/auth", cli.configFile.Configs[serverAddress], false) - if statusCode == 401 { - delete(cli.configFile.Configs, serverAddress) - registry.SaveConfig(cli.configFile) - return err - } - if err != nil { - return err - } - var out2 engine.Env - err = out2.Decode(stream) - if err != nil { - cli.configFile, _ = registry.LoadConfig(os.Getenv("HOME")) - return err - } - registry.SaveConfig(cli.configFile) - if out2.Get("Status") != "" { - fmt.Fprintf(cli.out, "%s\n", out2.Get("Status")) - } - return nil -} - -// log out from a Docker registry -func (cli *DockerCli) CmdLogout(args ...string) error { - cmd := cli.Subcmd("logout", "[SERVER]", "Log out from a Docker registry, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.") - - if err := cmd.Parse(args); err != nil { - return nil - } - serverAddress := registry.IndexServerAddress() - if len(cmd.Args()) > 0 { - serverAddress = cmd.Arg(0) - } - - cli.LoadConfigFile() - if _, ok := cli.configFile.Configs[serverAddress]; !ok { - fmt.Fprintf(cli.out, "Not logged in to %s\n", serverAddress) - } else { - fmt.Fprintf(cli.out, "Remove login credentials for %s\n", serverAddress) - delete(cli.configFile.Configs, serverAddress) - - if err := registry.SaveConfig(cli.configFile); err != nil { - return fmt.Errorf("Failed to save docker config: %v", err) - } - } - return nil -} - -// 'docker wait': block until a container stops -func (cli *DockerCli) CmdWait(args ...string) error { - cmd := cli.Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - var encounteredError error - for _, name := range cmd.Args() { - status, err := waitForExit(cli, name) - if err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to wait one or more containers") - } else { - fmt.Fprintf(cli.out, "%d\n", status) - } - } - return encounteredError -} - -// 'docker version': show version information -func (cli *DockerCli) CmdVersion(args ...string) error { - cmd := cli.Subcmd("version", "", "Show the Docker version information.") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() > 0 { - cmd.Usage() - return nil - } - if dockerversion.VERSION != "" { - fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION) - } - fmt.Fprintf(cli.out, "Client API version: %s\n", api.APIVERSION) - fmt.Fprintf(cli.out, "Go version (client): %s\n", runtime.Version()) - if dockerversion.GITCOMMIT != "" { - fmt.Fprintf(cli.out, "Git commit (client): %s\n", dockerversion.GITCOMMIT) - } - fmt.Fprintf(cli.out, "OS/Arch (client): %s/%s\n", runtime.GOOS, runtime.GOARCH) - - body, _, err := readBody(cli.call("GET", "/version", nil, false)) - if err != nil { - return err - } - - out := engine.NewOutput() - remoteVersion, err := out.AddEnv() - if err != nil { - log.Errorf("Error reading remote version: %s", err) - return err - } - if _, err := out.Write(body); err != nil { - log.Errorf("Error reading remote version: %s", err) - return err - } - out.Close() - fmt.Fprintf(cli.out, "Server version: %s\n", remoteVersion.Get("Version")) - if apiVersion := remoteVersion.Get("ApiVersion"); apiVersion != "" { - fmt.Fprintf(cli.out, "Server API version: %s\n", apiVersion) - } - fmt.Fprintf(cli.out, "Go version (server): %s\n", remoteVersion.Get("GoVersion")) - fmt.Fprintf(cli.out, "Git commit (server): %s\n", remoteVersion.Get("GitCommit")) - return nil -} - -// 'docker info': display system-wide information. -func (cli *DockerCli) CmdInfo(args ...string) error { - cmd := cli.Subcmd("info", "", "Display system-wide information") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() > 0 { - cmd.Usage() - return nil - } - - body, _, err := readBody(cli.call("GET", "/info", nil, false)) - if err != nil { - return err - } - - out := engine.NewOutput() - remoteInfo, err := out.AddEnv() - if err != nil { - return err - } - - if _, err := out.Write(body); err != nil { - log.Errorf("Error reading remote info: %s", err) - return err - } - out.Close() - - if remoteInfo.Exists("Containers") { - fmt.Fprintf(cli.out, "Containers: %d\n", remoteInfo.GetInt("Containers")) - } - if remoteInfo.Exists("Images") { - fmt.Fprintf(cli.out, "Images: %d\n", remoteInfo.GetInt("Images")) - } - if remoteInfo.Exists("Driver") { - fmt.Fprintf(cli.out, "Storage Driver: %s\n", remoteInfo.Get("Driver")) - } - if remoteInfo.Exists("DriverStatus") { - var driverStatus [][2]string - if err := remoteInfo.GetJson("DriverStatus", &driverStatus); err != nil { - return err - } - for _, pair := range driverStatus { - fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1]) - } - } - if remoteInfo.Exists("ExecutionDriver") { - fmt.Fprintf(cli.out, "Execution Driver: %s\n", remoteInfo.Get("ExecutionDriver")) - } - if remoteInfo.Exists("KernelVersion") { - fmt.Fprintf(cli.out, "Kernel Version: %s\n", remoteInfo.Get("KernelVersion")) - } - if remoteInfo.Exists("OperatingSystem") { - fmt.Fprintf(cli.out, "Operating System: %s\n", remoteInfo.Get("OperatingSystem")) - } - if remoteInfo.Exists("NCPU") { - fmt.Fprintf(cli.out, "CPUs: %d\n", remoteInfo.GetInt("NCPU")) - } - if remoteInfo.Exists("MemTotal") { - fmt.Fprintf(cli.out, "Total Memory: %s\n", units.BytesSize(float64(remoteInfo.GetInt64("MemTotal")))) - } - if remoteInfo.Exists("Name") { - fmt.Fprintf(cli.out, "Name: %s\n", remoteInfo.Get("Name")) - } - if remoteInfo.Exists("ID") { - fmt.Fprintf(cli.out, "ID: %s\n", remoteInfo.Get("ID")) - } - - if remoteInfo.GetBool("Debug") || os.Getenv("DEBUG") != "" { - if remoteInfo.Exists("Debug") { - fmt.Fprintf(cli.out, "Debug mode (server): %v\n", remoteInfo.GetBool("Debug")) - } - fmt.Fprintf(cli.out, "Debug mode (client): %v\n", os.Getenv("DEBUG") != "") - if remoteInfo.Exists("NFd") { - fmt.Fprintf(cli.out, "Fds: %d\n", remoteInfo.GetInt("NFd")) - } - if remoteInfo.Exists("NGoroutines") { - fmt.Fprintf(cli.out, "Goroutines: %d\n", remoteInfo.GetInt("NGoroutines")) - } - if remoteInfo.Exists("NEventsListener") { - fmt.Fprintf(cli.out, "EventsListeners: %d\n", remoteInfo.GetInt("NEventsListener")) - } - if initSha1 := remoteInfo.Get("InitSha1"); initSha1 != "" { - fmt.Fprintf(cli.out, "Init SHA1: %s\n", initSha1) - } - if initPath := remoteInfo.Get("InitPath"); initPath != "" { - fmt.Fprintf(cli.out, "Init Path: %s\n", initPath) - } - } - - if len(remoteInfo.GetList("IndexServerAddress")) != 0 { - cli.LoadConfigFile() - u := cli.configFile.Configs[remoteInfo.Get("IndexServerAddress")].Username - if len(u) > 0 { - fmt.Fprintf(cli.out, "Username: %v\n", u) - fmt.Fprintf(cli.out, "Registry: %v\n", remoteInfo.GetList("IndexServerAddress")) - } - } - if remoteInfo.Exists("MemoryLimit") && !remoteInfo.GetBool("MemoryLimit") { - fmt.Fprintf(cli.err, "WARNING: No memory limit support\n") - } - if remoteInfo.Exists("SwapLimit") && !remoteInfo.GetBool("SwapLimit") { - fmt.Fprintf(cli.err, "WARNING: No swap limit support\n") - } - if remoteInfo.Exists("IPv4Forwarding") && !remoteInfo.GetBool("IPv4Forwarding") { - fmt.Fprintf(cli.err, "WARNING: IPv4 forwarding is disabled.\n") - } - if remoteInfo.Exists("Labels") { - fmt.Fprintln(cli.out, "Labels:") - for _, attribute := range remoteInfo.GetList("Labels") { - fmt.Fprintf(cli.out, " %s\n", attribute) - } - } - - return nil -} - -func (cli *DockerCli) CmdStop(args ...string) error { - cmd := cli.Subcmd("stop", "CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period") - nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - v := url.Values{} - v.Set("t", strconv.Itoa(*nSeconds)) - - var encounteredError error - for _, name := range cmd.Args() { - _, _, err := readBody(cli.call("POST", "/containers/"+name+"/stop?"+v.Encode(), nil, false)) - if err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to stop one or more containers") - } else { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - return encounteredError -} - -func (cli *DockerCli) CmdRestart(args ...string) error { - cmd := cli.Subcmd("restart", "CONTAINER [CONTAINER...]", "Restart a running container") - nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - v := url.Values{} - v.Set("t", strconv.Itoa(*nSeconds)) - - var encounteredError error - for _, name := range cmd.Args() { - _, _, err := readBody(cli.call("POST", "/containers/"+name+"/restart?"+v.Encode(), nil, false)) - if err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to restart one or more containers") - } else { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - return encounteredError -} - -func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal { - sigc := make(chan os.Signal, 128) - signal.CatchAll(sigc) - go func() { - for s := range sigc { - if s == signal.SIGCHLD { - continue - } - var sig string - for sigStr, sigN := range signal.SignalMap { - if sigN == s { - sig = sigStr - break - } - } - if sig == "" { - log.Errorf("Unsupported signal: %v. Discarding.", s) - } - if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", cid, sig), nil, false)); err != nil { - log.Debugf("Error sending signal: %s", err) - } - } - }() - return sigc -} - -func (cli *DockerCli) CmdStart(args ...string) error { - var ( - cErr chan error - tty bool - - cmd = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container") - attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's STDOUT and STDERR and forward all signals to the process") - openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN") - ) - - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - hijacked := make(chan io.Closer) - - if *attach || *openStdin { - if cmd.NArg() > 1 { - return fmt.Errorf("You cannot start and attach multiple containers at once.") - } - - stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false) - if err != nil { - return err - } - - env := engine.Env{} - if err := env.Decode(stream); err != nil { - return err - } - config := env.GetSubEnv("Config") - tty = config.GetBool("Tty") - - if !tty { - sigc := cli.forwardAllSignals(cmd.Arg(0)) - defer signal.StopCatch(sigc) - } - - var in io.ReadCloser - - v := url.Values{} - v.Set("stream", "1") - - if *openStdin && config.GetBool("OpenStdin") { - v.Set("stdin", "1") - in = cli.in - } - - v.Set("stdout", "1") - v.Set("stderr", "1") - - cErr = promise.Go(func() error { - return cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), tty, in, cli.out, cli.err, hijacked, nil) - }) - } else { - close(hijacked) - } - - // Acknowledge the hijack before starting - select { - case closer := <-hijacked: - // Make sure that the hijack gets closed when returning (results - // in closing the hijack chan and freeing server's goroutines) - if closer != nil { - defer closer.Close() - } - case err := <-cErr: - if err != nil { - return err - } - } - - var encounteredError error - for _, name := range cmd.Args() { - _, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil, false)) - if err != nil { - if !*attach || !*openStdin { - fmt.Fprintf(cli.err, "%s\n", err) - } - encounteredError = fmt.Errorf("Error: failed to start one or more containers") - } else { - if !*attach || !*openStdin { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - } - if encounteredError != nil { - if *openStdin || *attach { - cli.in.Close() - } - return encounteredError - } - - if *openStdin || *attach { - if tty && cli.isTerminalOut { - if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil { - log.Errorf("Error monitoring TTY size: %s", err) - } - } - if attchErr := <-cErr; attchErr != nil { - return attchErr - } - _, status, err := getExitCode(cli, cmd.Arg(0)) - if err != nil { - return err - } - if status != 0 { - return &utils.StatusError{StatusCode: status} - } - } - return nil -} - -func (cli *DockerCli) CmdUnpause(args ...string) error { - cmd := cli.Subcmd("unpause", "CONTAINER", "Unpause all processes within a container") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - var encounteredError error - for _, name := range cmd.Args() { - if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/unpause", name), nil, false)); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to unpause container named %s", name) - } else { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - return encounteredError -} - -func (cli *DockerCli) CmdPause(args ...string) error { - cmd := cli.Subcmd("pause", "CONTAINER", "Pause all processes within a container") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - var encounteredError error - for _, name := range cmd.Args() { - if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/pause", name), nil, false)); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to pause container named %s", name) - } else { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - return encounteredError -} - -func (cli *DockerCli) CmdInspect(args ...string) error { - cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image") - tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - var tmpl *template.Template - if *tmplStr != "" { - var err error - if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil { - fmt.Fprintf(cli.err, "Template parsing error: %v\n", err) - return &utils.StatusError{StatusCode: 64, - Status: "Template parsing error: " + err.Error()} - } - } - - indented := new(bytes.Buffer) - indented.WriteByte('[') - status := 0 - - for _, name := range cmd.Args() { - obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false)) - if err != nil { - obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil, false)) - if err != nil { - if strings.Contains(err.Error(), "No such") { - fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name) - } else { - fmt.Fprintf(cli.err, "%s", err) - } - status = 1 - continue - } - } - - if tmpl == nil { - if err = json.Indent(indented, obj, "", " "); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - status = 1 - continue - } - } else { - // Has template, will render - var value interface{} - if err := json.Unmarshal(obj, &value); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - status = 1 - continue - } - if err := tmpl.Execute(cli.out, value); err != nil { - return err - } - cli.out.Write([]byte{'\n'}) - } - indented.WriteString(",") - } - - if indented.Len() > 1 { - // Remove trailing ',' - indented.Truncate(indented.Len() - 1) - } - indented.WriteByte(']') - - if tmpl == nil { - if _, err := io.Copy(cli.out, indented); err != nil { - return err - } - } - - if status != 0 { - return &utils.StatusError{StatusCode: status} - } - return nil -} - -func (cli *DockerCli) CmdTop(args ...string) error { - cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() == 0 { - cmd.Usage() - return nil - } - val := url.Values{} - if cmd.NArg() > 1 { - val.Set("ps_args", strings.Join(cmd.Args()[1:], " ")) - } - - stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/top?"+val.Encode(), nil, false) - if err != nil { - return err - } - var procs engine.Env - if err := procs.Decode(stream); err != nil { - return err - } - w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) - fmt.Fprintln(w, strings.Join(procs.GetList("Titles"), "\t")) - processes := [][]string{} - if err := procs.GetJson("Processes", &processes); err != nil { - return err - } - for _, proc := range processes { - fmt.Fprintln(w, strings.Join(proc, "\t")) - } - w.Flush() - return nil -} - -func (cli *DockerCli) CmdPort(args ...string) error { - cmd := cli.Subcmd("port", "CONTAINER [PRIVATE_PORT[/PROTO]]", "List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false) - if err != nil { - return err - } - - env := engine.Env{} - if err := env.Decode(stream); err != nil { - return err - } - ports := nat.PortMap{} - if err := env.GetSubEnv("NetworkSettings").GetJson("Ports", &ports); err != nil { - return err - } - - if cmd.NArg() == 2 { - var ( - port = cmd.Arg(1) - proto = "tcp" - parts = strings.SplitN(port, "/", 2) - ) - - if len(parts) == 2 && len(parts[1]) != 0 { - port = parts[0] - proto = parts[1] - } - natPort := port + "/" + proto - if frontends, exists := ports[nat.Port(port+"/"+proto)]; exists && frontends != nil { - for _, frontend := range frontends { - fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort) - } - return nil - } - return fmt.Errorf("Error: No public port '%s' published for %s", natPort, cmd.Arg(0)) - } - - for from, frontends := range ports { - for _, frontend := range frontends { - fmt.Fprintf(cli.out, "%s -> %s:%s\n", from, frontend.HostIp, frontend.HostPort) - } - } - - return nil -} - -// 'docker rmi IMAGE' removes all images with the name IMAGE -func (cli *DockerCli) CmdRmi(args ...string) error { - var ( - cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images") - force = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image") - noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") - ) - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - v := url.Values{} - if *force { - v.Set("force", "1") - } - if *noprune { - v.Set("noprune", "1") - } - - var encounteredError error - for _, name := range cmd.Args() { - body, _, err := readBody(cli.call("DELETE", "/images/"+name+"?"+v.Encode(), nil, false)) - if err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to remove one or more images") - } else { - outs := engine.NewTable("Created", 0) - if _, err := outs.ReadListFrom(body); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to remove one or more images") - continue - } - for _, out := range outs.Data { - if out.Get("Deleted") != "" { - fmt.Fprintf(cli.out, "Deleted: %s\n", out.Get("Deleted")) - } else { - fmt.Fprintf(cli.out, "Untagged: %s\n", out.Get("Untagged")) - } - } - } - } - return encounteredError -} - -func (cli *DockerCli) CmdHistory(args ...string) error { - cmd := cli.Subcmd("history", "IMAGE", "Show the history of an image") - quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs") - noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") - - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - body, _, err := readBody(cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, false)) - if err != nil { - return err - } - - outs := engine.NewTable("Created", 0) - if _, err := outs.ReadListFrom(body); err != nil { - return err - } - - w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) - if !*quiet { - fmt.Fprintln(w, "IMAGE\tCREATED\tCREATED BY\tSIZE") - } - - for _, out := range outs.Data { - outID := out.Get("Id") - if !*quiet { - if *noTrunc { - fmt.Fprintf(w, "%s\t", outID) - } else { - fmt.Fprintf(w, "%s\t", utils.TruncateID(outID)) - } - - fmt.Fprintf(w, "%s ago\t", units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0)))) - - if *noTrunc { - fmt.Fprintf(w, "%s\t", out.Get("CreatedBy")) - } else { - fmt.Fprintf(w, "%s\t", utils.Trunc(out.Get("CreatedBy"), 45)) - } - fmt.Fprintf(w, "%s\n", units.HumanSize(out.GetInt64("Size"))) - } else { - if *noTrunc { - fmt.Fprintln(w, outID) - } else { - fmt.Fprintln(w, utils.TruncateID(outID)) - } - } - } - w.Flush() - return nil -} - -func (cli *DockerCli) CmdRm(args ...string) error { - cmd := cli.Subcmd("rm", "CONTAINER [CONTAINER...]", "Remove one or more containers") - v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container") - link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container") - force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)") - - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - val := url.Values{} - if *v { - val.Set("v", "1") - } - if *link { - val.Set("link", "1") - } - - if *force { - val.Set("force", "1") - } - - var encounteredError error - for _, name := range cmd.Args() { - _, _, err := readBody(cli.call("DELETE", "/containers/"+name+"?"+val.Encode(), nil, false)) - if err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to remove one or more containers") - } else { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - return encounteredError -} - -// 'docker kill NAME' kills a running container -func (cli *DockerCli) CmdKill(args ...string) error { - cmd := cli.Subcmd("kill", "CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal") - signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container") - - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - var encounteredError error - for _, name := range cmd.Args() { - if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", name, *signal), nil, false)); err != nil { - fmt.Fprintf(cli.err, "%s\n", err) - encounteredError = fmt.Errorf("Error: failed to kill one or more containers") - } else { - fmt.Fprintf(cli.out, "%s\n", name) - } - } - return encounteredError -} - -func (cli *DockerCli) CmdImport(args ...string) error { - cmd := cli.Subcmd("import", "URL|- [REPOSITORY[:TAG]]", "Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it.") - - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - var ( - v = url.Values{} - src = cmd.Arg(0) - repository = cmd.Arg(1) - ) - - v.Set("fromSrc", src) - v.Set("repo", repository) - - if cmd.NArg() == 3 { - fmt.Fprintf(cli.err, "[DEPRECATED] The format 'URL|- [REPOSITORY [TAG]]' as been deprecated. Please use URL|- [REPOSITORY[:TAG]]\n") - v.Set("tag", cmd.Arg(2)) - } - - if repository != "" { - //Check if the given image name can be resolved - repo, _ := parsers.ParseRepositoryTag(repository) - if _, _, err := registry.ResolveRepositoryName(repo); err != nil { - return err - } - } - - var in io.Reader - - if src == "-" { - in = cli.in - } - - return cli.stream("POST", "/images/create?"+v.Encode(), in, cli.out, nil) -} - -func (cli *DockerCli) CmdPush(args ...string) error { - cmd := cli.Subcmd("push", "NAME[:TAG]", "Push an image or a repository to the registry") - if err := cmd.Parse(args); err != nil { - return nil - } - name := cmd.Arg(0) - - if name == "" { - cmd.Usage() - return nil - } - - cli.LoadConfigFile() - - remote, tag := parsers.ParseRepositoryTag(name) - - // Resolve the Repository name from fqn to hostname + name - hostname, _, err := registry.ResolveRepositoryName(remote) - if err != nil { - return err - } - // Resolve the Auth config relevant for this server - authConfig := cli.configFile.ResolveAuthConfig(hostname) - // If we're not using a custom registry, we know the restrictions - // applied to repository names and can warn the user in advance. - // Custom repositories can have different rules, and we must also - // allow pushing by image ID. - if len(strings.SplitN(name, "/", 2)) == 1 { - username := cli.configFile.Configs[registry.IndexServerAddress()].Username - if username == "" { - username = "" - } - return fmt.Errorf("You cannot push a \"root\" repository. Please rename your repository in / (ex: %s/%s)", username, name) - } - - v := url.Values{} - v.Set("tag", tag) - push := func(authConfig registry.AuthConfig) error { - buf, err := json.Marshal(authConfig) - if err != nil { - return err - } - registryAuthHeader := []string{ - base64.URLEncoding.EncodeToString(buf), - } - - return cli.stream("POST", "/images/"+remote+"/push?"+v.Encode(), nil, cli.out, map[string][]string{ - "X-Registry-Auth": registryAuthHeader, - }) - } - - if err := push(authConfig); err != nil { - if strings.Contains(err.Error(), "Status 401") { - fmt.Fprintln(cli.out, "\nPlease login prior to push:") - if err := cli.CmdLogin(hostname); err != nil { - return err - } - authConfig := cli.configFile.ResolveAuthConfig(hostname) - return push(authConfig) - } - return err - } - return nil -} - -func (cli *DockerCli) CmdPull(args ...string) error { - cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry") - allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - var ( - v = url.Values{} - remote = cmd.Arg(0) - newRemote = remote - ) - taglessRemote, tag := parsers.ParseRepositoryTag(remote) - if tag == "" && !*allTags { - newRemote = taglessRemote + ":" + graph.DEFAULTTAG - } - if tag != "" && *allTags { - return fmt.Errorf("tag can't be used with --all-tags/-a") - } - - v.Set("fromImage", newRemote) - - // Resolve the Repository name from fqn to hostname + name - hostname, _, err := registry.ResolveRepositoryName(taglessRemote) - if err != nil { - return err - } - - cli.LoadConfigFile() - - // Resolve the Auth config relevant for this server - authConfig := cli.configFile.ResolveAuthConfig(hostname) - - pull := func(authConfig registry.AuthConfig) error { - buf, err := json.Marshal(authConfig) - if err != nil { - return err - } - registryAuthHeader := []string{ - base64.URLEncoding.EncodeToString(buf), - } - - return cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.out, map[string][]string{ - "X-Registry-Auth": registryAuthHeader, - }) - } - - if err := pull(authConfig); err != nil { - if strings.Contains(err.Error(), "Status 401") { - fmt.Fprintln(cli.out, "\nPlease login prior to pull:") - if err := cli.CmdLogin(hostname); err != nil { - return err - } - authConfig := cli.configFile.ResolveAuthConfig(hostname) - return pull(authConfig) - } - return err - } - - return nil -} - -func (cli *DockerCli) CmdImages(args ...string) error { - cmd := cli.Subcmd("images", "[NAME]", "List images") - quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs") - all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (by default filter out the intermediate image layers)") - noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") - // FIXME: --viz and --tree are deprecated. Remove them in a future version. - flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format") - flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format") - - flFilter := opts.NewListOpts(nil) - cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')") - - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() > 1 { - cmd.Usage() - return nil - } - - // Consolidate all filter flags, and sanity check them early. - // They'll get process in the daemon/server. - imageFilterArgs := filters.Args{} - for _, f := range flFilter.GetAll() { - var err error - imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs) - if err != nil { - return err - } - } - - for name := range imageFilterArgs { - if _, ok := acceptedImageFilterTags[name]; !ok { - return fmt.Errorf("Invalid filter '%s'", name) - } - } - - matchName := cmd.Arg(0) - // FIXME: --viz and --tree are deprecated. Remove them in a future version. - if *flViz || *flTree { - v := url.Values{ - "all": []string{"1"}, - } - if len(imageFilterArgs) > 0 { - filterJson, err := filters.ToParam(imageFilterArgs) - if err != nil { - return err - } - v.Set("filters", filterJson) - } - - body, _, err := readBody(cli.call("GET", "/images/json?"+v.Encode(), nil, false)) - if err != nil { - return err - } - - outs := engine.NewTable("Created", 0) - if _, err := outs.ReadListFrom(body); err != nil { - return err - } - - var ( - printNode func(cli *DockerCli, noTrunc bool, image *engine.Env, prefix string) - startImage *engine.Env - - roots = engine.NewTable("Created", outs.Len()) - byParent = make(map[string]*engine.Table) - ) - - for _, image := range outs.Data { - if image.Get("ParentId") == "" { - roots.Add(image) - } else { - if children, exists := byParent[image.Get("ParentId")]; exists { - children.Add(image) - } else { - byParent[image.Get("ParentId")] = engine.NewTable("Created", 1) - byParent[image.Get("ParentId")].Add(image) - } - } - - if matchName != "" { - if matchName == image.Get("Id") || matchName == utils.TruncateID(image.Get("Id")) { - startImage = image - } - - for _, repotag := range image.GetList("RepoTags") { - if repotag == matchName { - startImage = image - } - } - } - } - - if *flViz { - fmt.Fprintf(cli.out, "digraph docker {\n") - printNode = (*DockerCli).printVizNode - } else { - printNode = (*DockerCli).printTreeNode - } - - if startImage != nil { - root := engine.NewTable("Created", 1) - root.Add(startImage) - cli.WalkTree(*noTrunc, root, byParent, "", printNode) - } else if matchName == "" { - cli.WalkTree(*noTrunc, roots, byParent, "", printNode) - } - if *flViz { - fmt.Fprintf(cli.out, " base [style=invisible]\n}\n") - } - } else { - v := url.Values{} - if len(imageFilterArgs) > 0 { - filterJson, err := filters.ToParam(imageFilterArgs) - if err != nil { - return err - } - v.Set("filters", filterJson) - } - - if cmd.NArg() == 1 { - // FIXME rename this parameter, to not be confused with the filters flag - v.Set("filter", matchName) - } - if *all { - v.Set("all", "1") - } - - body, _, err := readBody(cli.call("GET", "/images/json?"+v.Encode(), nil, false)) - - if err != nil { - return err - } - - outs := engine.NewTable("Created", 0) - if _, err := outs.ReadListFrom(body); err != nil { - return err - } - - w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) - if !*quiet { - fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE") - } - - for _, out := range outs.Data { - for _, repotag := range out.GetList("RepoTags") { - - repo, tag := parsers.ParseRepositoryTag(repotag) - outID := out.Get("Id") - if !*noTrunc { - outID = utils.TruncateID(outID) - } - - if !*quiet { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(out.GetInt64("VirtualSize"))) - } else { - fmt.Fprintln(w, outID) - } - } - } - - if !*quiet { - w.Flush() - } - } - return nil -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) WalkTree(noTrunc bool, images *engine.Table, byParent map[string]*engine.Table, prefix string, printNode func(cli *DockerCli, noTrunc bool, image *engine.Env, prefix string)) { - length := images.Len() - if length > 1 { - for index, image := range images.Data { - if index+1 == length { - printNode(cli, noTrunc, image, prefix+"└─") - if subimages, exists := byParent[image.Get("Id")]; exists { - cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode) - } - } else { - printNode(cli, noTrunc, image, prefix+"\u251C─") - if subimages, exists := byParent[image.Get("Id")]; exists { - cli.WalkTree(noTrunc, subimages, byParent, prefix+"\u2502 ", printNode) - } - } - } - } else { - for _, image := range images.Data { - printNode(cli, noTrunc, image, prefix+"└─") - if subimages, exists := byParent[image.Get("Id")]; exists { - cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode) - } - } - } -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) printVizNode(noTrunc bool, image *engine.Env, prefix string) { - var ( - imageID string - parentID string - ) - if noTrunc { - imageID = image.Get("Id") - parentID = image.Get("ParentId") - } else { - imageID = utils.TruncateID(image.Get("Id")) - parentID = utils.TruncateID(image.Get("ParentId")) - } - if parentID == "" { - fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID) - } else { - fmt.Fprintf(cli.out, " \"%s\" -> \"%s\"\n", parentID, imageID) - } - if image.GetList("RepoTags")[0] != ":" { - fmt.Fprintf(cli.out, " \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", - imageID, imageID, strings.Join(image.GetList("RepoTags"), "\\n")) - } -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix string) { - var imageID string - if noTrunc { - imageID = image.Get("Id") - } else { - imageID = utils.TruncateID(image.Get("Id")) - } - - fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(image.GetInt64("VirtualSize"))) - if image.GetList("RepoTags")[0] != ":" { - fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.GetList("RepoTags"), ", ")) - } else { - fmt.Fprint(cli.out, "\n") - } -} - -func (cli *DockerCli) CmdPs(args ...string) error { - var ( - err error - - psFilterArgs = filters.Args{} - v = url.Values{} - - cmd = cli.Subcmd("ps", "", "List containers") - quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs") - size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes") - all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers. Only running containers are shown by default.") - noTrunc = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") - nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show only the latest created container, include non-running ones.") - since = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show only containers created since Id or Name, include non-running ones.") - before = cmd.String([]string{"#beforeId", "#-before-id", "-before"}, "", "Show only container created before Id or Name, include non-running ones.") - last = cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running ones.") - flFilter = opts.NewListOpts(nil) - ) - - cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values. Valid filters:\nexited= - containers with exit code of \nstatus=(restarting|running|paused|exited)") - - if err := cmd.Parse(args); err != nil { - return nil - } - - if *last == -1 && *nLatest { - *last = 1 - } - - if *all { - v.Set("all", "1") - } - - if *last != -1 { - v.Set("limit", strconv.Itoa(*last)) - } - - if *since != "" { - v.Set("since", *since) - } - - if *before != "" { - v.Set("before", *before) - } - - if *size { - v.Set("size", "1") - } - - // Consolidate all filter flags, and sanity check them. - // They'll get processed in the daemon/server. - for _, f := range flFilter.GetAll() { - if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil { - return err - } - } - - if len(psFilterArgs) > 0 { - filterJson, err := filters.ToParam(psFilterArgs) - if err != nil { - return err - } - - v.Set("filters", filterJson) - } - - body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, false)) - if err != nil { - return err - } - - outs := engine.NewTable("Created", 0) - if _, err := outs.ReadListFrom(body); err != nil { - return err - } - - w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) - if !*quiet { - fmt.Fprint(w, "CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES") - - if *size { - fmt.Fprintln(w, "\tSIZE") - } else { - fmt.Fprint(w, "\n") - } - } - - stripNamePrefix := func(ss []string) []string { - for i, s := range ss { - ss[i] = s[1:] - } - - return ss - } - - for _, out := range outs.Data { - outID := out.Get("Id") - - if !*noTrunc { - outID = utils.TruncateID(outID) - } - - if *quiet { - fmt.Fprintln(w, outID) - - continue - } - - var ( - outNames = stripNamePrefix(out.GetList("Names")) - outCommand = strconv.Quote(out.Get("Command")) - ports = engine.NewTable("", 0) - ) - - if !*noTrunc { - outCommand = utils.Trunc(outCommand, 20) - - // only display the default name for the container with notrunc is passed - for _, name := range outNames { - if len(strings.Split(name, "/")) == 1 { - outNames = []string{name} - - break - } - } - } - - ports.ReadListFrom([]byte(out.Get("Ports"))) - - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", outID, out.Get("Image"), outCommand, - units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), - out.Get("Status"), api.DisplayablePorts(ports), strings.Join(outNames, ",")) - - if *size { - if out.GetInt("SizeRootFs") > 0 { - fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(out.GetInt64("SizeRw")), units.HumanSize(out.GetInt64("SizeRootFs"))) - } else { - fmt.Fprintf(w, "%s\n", units.HumanSize(out.GetInt64("SizeRw"))) - } - - continue - } - - fmt.Fprint(w, "\n") - } - - if !*quiet { - w.Flush() - } - - return nil -} - -func (cli *DockerCli) CmdCommit(args ...string) error { - cmd := cli.Subcmd("commit", "CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes") - flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit") - flComment := cmd.String([]string{"m", "-message"}, "", "Commit message") - flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith \")") - // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. - flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") - if err := cmd.Parse(args); err != nil { - return nil - } - - var ( - name = cmd.Arg(0) - repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1)) - ) - - if name == "" || len(cmd.Args()) > 2 { - cmd.Usage() - return nil - } - - //Check if the given image name can be resolved - if repository != "" { - if _, _, err := registry.ResolveRepositoryName(repository); err != nil { - return err - } - } - - v := url.Values{} - v.Set("container", name) - v.Set("repo", repository) - v.Set("tag", tag) - v.Set("comment", *flComment) - v.Set("author", *flAuthor) - - if *flPause != true { - v.Set("pause", "0") - } - - var ( - config *runconfig.Config - env engine.Env - ) - if *flConfig != "" { - config = &runconfig.Config{} - if err := json.Unmarshal([]byte(*flConfig), config); err != nil { - return err - } - } - stream, _, err := cli.call("POST", "/commit?"+v.Encode(), config, false) - if err != nil { - return err - } - if err := env.Decode(stream); err != nil { - return err - } - - fmt.Fprintf(cli.out, "%s\n", env.Get("Id")) - return nil -} - -func (cli *DockerCli) CmdEvents(args ...string) error { - cmd := cli.Subcmd("events", "", "Get real time events from the server") - since := cmd.String([]string{"#since", "-since"}, "", "Show all events created since timestamp") - until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 0 { - cmd.Usage() - return nil - } - var ( - v = url.Values{} - loc = time.FixedZone(time.Now().Zone()) - ) - var setTime = func(key, value string) { - format := timeutils.RFC3339NanoFixed - if len(value) < len(format) { - format = format[:len(value)] - } - if t, err := time.ParseInLocation(format, value, loc); err == nil { - v.Set(key, strconv.FormatInt(t.Unix(), 10)) - } else { - v.Set(key, value) - } - } - if *since != "" { - setTime("since", *since) - } - if *until != "" { - setTime("until", *until) - } - if err := cli.stream("GET", "/events?"+v.Encode(), nil, cli.out, nil); err != nil { - return err - } - return nil -} - -func (cli *DockerCli) CmdExport(args ...string) error { - cmd := cli.Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive to STDOUT") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - if err := cli.stream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, cli.out, nil); err != nil { - return err - } - return nil -} - -func (cli *DockerCli) CmdDiff(args ...string) error { - cmd := cli.Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, false)) - - if err != nil { - return err - } - - outs := engine.NewTable("", 0) - if _, err := outs.ReadListFrom(body); err != nil { - return err - } - for _, change := range outs.Data { - var kind string - switch change.GetInt("Kind") { - case archive.ChangeModify: - kind = "C" - case archive.ChangeAdd: - kind = "A" - case archive.ChangeDelete: - kind = "D" - } - fmt.Fprintf(cli.out, "%s %s\n", kind, change.Get("Path")) - } - return nil -} - -func (cli *DockerCli) CmdLogs(args ...string) error { - var ( - cmd = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container") - follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") - times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") - tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs (defaults to all logs)") - ) - - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - name := cmd.Arg(0) - - stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false) - if err != nil { - return err - } - - env := engine.Env{} - if err := env.Decode(stream); err != nil { - return err - } - - v := url.Values{} - v.Set("stdout", "1") - v.Set("stderr", "1") - - if *times { - v.Set("timestamps", "1") - } - - if *follow { - v.Set("follow", "1") - } - v.Set("tail", *tail) - - return cli.streamHelper("GET", "/containers/"+name+"/logs?"+v.Encode(), env.GetSubEnv("Config").GetBool("Tty"), nil, cli.out, cli.err, nil) -} - -func (cli *DockerCli) CmdAttach(args ...string) error { - var ( - cmd = cli.Subcmd("attach", "CONTAINER", "Attach to a running container") - noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN") - proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process (non-TTY mode only). SIGCHLD, SIGKILL, and SIGSTOP are not proxied.") - ) - - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - name := cmd.Arg(0) - - stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false) - if err != nil { - return err - } - - env := engine.Env{} - if err := env.Decode(stream); err != nil { - return err - } - - if !env.GetSubEnv("State").GetBool("Running") { - return fmt.Errorf("You cannot attach to a stopped container, start it first") - } - - var ( - config = env.GetSubEnv("Config") - tty = config.GetBool("Tty") - ) - - if tty && cli.isTerminalOut { - if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil { - log.Debugf("Error monitoring TTY size: %s", err) - } - } - - var in io.ReadCloser - - v := url.Values{} - v.Set("stream", "1") - if !*noStdin && config.GetBool("OpenStdin") { - v.Set("stdin", "1") - in = cli.in - } - - v.Set("stdout", "1") - v.Set("stderr", "1") - - if *proxy && !tty { - sigc := cli.forwardAllSignals(cmd.Arg(0)) - defer signal.StopCatch(sigc) - } - - if err := cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), tty, in, cli.out, cli.err, nil, nil); err != nil { - return err - } - - _, status, err := getExitCode(cli, cmd.Arg(0)) - if err != nil { - return err - } - if status != 0 { - return &utils.StatusError{StatusCode: status} - } - - return nil -} - -func (cli *DockerCli) CmdSearch(args ...string) error { - cmd := cli.Subcmd("search", "TERM", "Search the Docker Hub for images") - noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") - trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds") - automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds") - stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() != 1 { - cmd.Usage() - return nil - } - - v := url.Values{} - v.Set("term", cmd.Arg(0)) - - body, _, err := readBody(cli.call("GET", "/images/search?"+v.Encode(), nil, true)) - - if err != nil { - return err - } - outs := engine.NewTable("star_count", 0) - if _, err := outs.ReadListFrom(body); err != nil { - return err - } - w := tabwriter.NewWriter(cli.out, 10, 1, 3, ' ', 0) - fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n") - for _, out := range outs.Data { - if ((*automated || *trusted) && (!out.GetBool("is_trusted") && !out.GetBool("is_automated"))) || (*stars > out.GetInt("star_count")) { - continue - } - desc := strings.Replace(out.Get("description"), "\n", " ", -1) - desc = strings.Replace(desc, "\r", " ", -1) - if !*noTrunc && len(desc) > 45 { - desc = utils.Trunc(desc, 42) + "..." - } - fmt.Fprintf(w, "%s\t%s\t%d\t", out.Get("name"), desc, out.GetInt("star_count")) - if out.GetBool("is_official") { - fmt.Fprint(w, "[OK]") - - } - fmt.Fprint(w, "\t") - if out.GetBool("is_automated") || out.GetBool("is_trusted") { - fmt.Fprint(w, "[OK]") - } - fmt.Fprint(w, "\n") - } - w.Flush() - return nil -} - -// Ports type - Used to parse multiple -p flags -type ports []int - -func (cli *DockerCli) CmdTag(args ...string) error { - cmd := cli.Subcmd("tag", "IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository") - force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force") - if err := cmd.Parse(args); err != nil { - return nil - } - if cmd.NArg() != 2 { - cmd.Usage() - return nil - } - - var ( - repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1)) - v = url.Values{} - ) - - //Check if the given image name can be resolved - if _, _, err := registry.ResolveRepositoryName(repository); err != nil { - return err - } - v.Set("repo", repository) - v.Set("tag", tag) - - if *force { - v.Set("force", "1") - } - - if _, _, err := readBody(cli.call("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil, false)); err != nil { - return err - } - return nil -} - -func (cli *DockerCli) pullImage(image string) error { - return cli.pullImageCustomOut(image, cli.out) -} - -func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error { - v := url.Values{} - repos, tag := parsers.ParseRepositoryTag(image) - // pull only the image tagged 'latest' if no tag was specified - if tag == "" { - tag = graph.DEFAULTTAG - } - v.Set("fromImage", repos) - v.Set("tag", tag) - - // Resolve the Repository name from fqn to hostname + name - hostname, _, err := registry.ResolveRepositoryName(repos) - if err != nil { - return err - } - - // Load the auth config file, to be able to pull the image - cli.LoadConfigFile() - - // Resolve the Auth config relevant for this server - authConfig := cli.configFile.ResolveAuthConfig(hostname) - buf, err := json.Marshal(authConfig) - if err != nil { - return err - } - - registryAuthHeader := []string{ - base64.URLEncoding.EncodeToString(buf), - } - if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, out, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil { - return err - } - return nil -} - -type cidFile struct { - path string - file *os.File - written bool -} - -func newCIDFile(path string) (*cidFile, error) { - if _, err := os.Stat(path); err == nil { - return nil, fmt.Errorf("Container ID file found, make sure the other container isn't running or delete %s", path) - } - f, err := os.Create(path) - if err != nil { - return nil, fmt.Errorf("Failed to create the container ID file: %s", err) - } - - return &cidFile{path: path, file: f}, nil -} - -func (cid *cidFile) Close() error { - cid.file.Close() - - if !cid.written { - if err := os.Remove(cid.path); err != nil { - return fmt.Errorf("failed to remove the CID file '%s': %s \n", cid.path, err) - } - } - - return nil -} - -func (cid *cidFile) Write(id string) error { - if _, err := cid.file.Write([]byte(id)); err != nil { - return fmt.Errorf("Failed to write the container ID to the file: %s", err) - } - cid.written = true - return nil -} - -func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runconfig.HostConfig, cidfile, name string) (engine.Env, error) { - containerValues := url.Values{} - if name != "" { - containerValues.Set("name", name) - } - - mergedConfig := runconfig.MergeConfigs(config, hostConfig) - - var containerIDFile *cidFile - if cidfile != "" { - var err error - if containerIDFile, err = newCIDFile(cidfile); err != nil { - return nil, err - } - defer containerIDFile.Close() - } - - //create the container - stream, statusCode, err := cli.call("POST", "/containers/create?"+containerValues.Encode(), mergedConfig, false) - //if image not found try to pull it - if statusCode == 404 { - repo, tag := parsers.ParseRepositoryTag(config.Image) - if tag == "" { - tag = graph.DEFAULTTAG - } - fmt.Fprintf(cli.err, "Unable to find image '%s:%s' locally\n", repo, tag) - - // we don't want to write to stdout anything apart from container.ID - if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil { - return nil, err - } - // Retry - if stream, _, err = cli.call("POST", "/containers/create?"+containerValues.Encode(), mergedConfig, false); err != nil { - return nil, err - } - } else if err != nil { - return nil, err - } - - var result engine.Env - if err := result.Decode(stream); err != nil { - return nil, err - } - - for _, warning := range result.GetList("Warnings") { - fmt.Fprintf(cli.err, "WARNING: %s\n", warning) - } - - if containerIDFile != nil { - if err = containerIDFile.Write(result.Get("Id")); err != nil { - return nil, err - } - } - - return result, nil - -} - -func (cli *DockerCli) CmdCreate(args ...string) error { - cmd := cli.Subcmd("create", "IMAGE [COMMAND] [ARG...]", "Create a new container") - - // These are flags not stored in Config/HostConfig - var ( - flName = cmd.String([]string{"-name"}, "", "Assign a name to the container") - ) - - config, hostConfig, cmd, err := runconfig.Parse(cmd, args) - if err != nil { - return err - } - if config.Image == "" { - cmd.Usage() - return nil - } - - createResult, err := cli.createContainer(config, hostConfig, hostConfig.ContainerIDFile, *flName) - if err != nil { - return err - } - - fmt.Fprintf(cli.out, "%s\n", createResult.Get("Id")) - - return nil -} - -func (cli *DockerCli) CmdRun(args ...string) error { - // FIXME: just use runconfig.Parse already - cmd := cli.Subcmd("run", "IMAGE [COMMAND] [ARG...]", "Run a command in a new container") - - // These are flags not stored in Config/HostConfig - var ( - flAutoRemove = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)") - flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: run the container in the background and print the new container ID") - flSigProxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied.") - flName = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container") - flAttach *opts.ListOpts - - ErrConflictAttachDetach = fmt.Errorf("Conflicting options: -a and -d") - ErrConflictRestartPolicyAndAutoRemove = fmt.Errorf("Conflicting options: --restart and --rm") - ErrConflictDetachAutoRemove = fmt.Errorf("Conflicting options: --rm and -d") - ) - - config, hostConfig, cmd, err := runconfig.Parse(cmd, args) - if err != nil { - return err - } - if config.Image == "" { - cmd.Usage() - return nil - } - - if *flDetach { - if fl := cmd.Lookup("attach"); fl != nil { - flAttach = fl.Value.(*opts.ListOpts) - if flAttach.Len() != 0 { - return ErrConflictAttachDetach - } - } - if *flAutoRemove { - return ErrConflictDetachAutoRemove - } - - config.AttachStdin = false - config.AttachStdout = false - config.AttachStderr = false - config.StdinOnce = false - } - - // Disable flSigProxy when in TTY mode - sigProxy := *flSigProxy - if config.Tty { - sigProxy = false - } - - runResult, err := cli.createContainer(config, hostConfig, hostConfig.ContainerIDFile, *flName) - if err != nil { - return err - } - - if sigProxy { - sigc := cli.forwardAllSignals(runResult.Get("Id")) - defer signal.StopCatch(sigc) - } - - var ( - waitDisplayId chan struct{} - errCh chan error - ) - - if !config.AttachStdout && !config.AttachStderr { - // Make this asynchronous to allow the client to write to stdin before having to read the ID - waitDisplayId = make(chan struct{}) - go func() { - defer close(waitDisplayId) - fmt.Fprintf(cli.out, "%s\n", runResult.Get("Id")) - }() - } - - if *flAutoRemove && (hostConfig.RestartPolicy.Name == "always" || hostConfig.RestartPolicy.Name == "on-failure") { - return ErrConflictRestartPolicyAndAutoRemove - } - - // We need to instantiate the chan because the select needs it. It can - // be closed but can't be uninitialized. - hijacked := make(chan io.Closer) - - // Block the return until the chan gets closed - defer func() { - log.Debugf("End of CmdRun(), Waiting for hijack to finish.") - if _, ok := <-hijacked; ok { - log.Errorf("Hijack did not finish (chan still open)") - } - }() - - if config.AttachStdin || config.AttachStdout || config.AttachStderr { - var ( - out, stderr io.Writer - in io.ReadCloser - v = url.Values{} - ) - v.Set("stream", "1") - - if config.AttachStdin { - v.Set("stdin", "1") - in = cli.in - } - if config.AttachStdout { - v.Set("stdout", "1") - out = cli.out - } - if config.AttachStderr { - v.Set("stderr", "1") - if config.Tty { - stderr = cli.out - } else { - stderr = cli.err - } - } - - errCh = promise.Go(func() error { - return cli.hijack("POST", "/containers/"+runResult.Get("Id")+"/attach?"+v.Encode(), config.Tty, in, out, stderr, hijacked, nil) - }) - } else { - close(hijacked) - } - - // Acknowledge the hijack before starting - select { - case closer := <-hijacked: - // Make sure that the hijack gets closed when returning (results - // in closing the hijack chan and freeing server's goroutines) - if closer != nil { - defer closer.Close() - } - case err := <-errCh: - if err != nil { - log.Debugf("Error hijack: %s", err) - return err - } - } - - //start the container - if _, _, err = readBody(cli.call("POST", "/containers/"+runResult.Get("Id")+"/start", nil, false)); err != nil { - return err - } - - if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && cli.isTerminalOut { - if err := cli.monitorTtySize(runResult.Get("Id"), false); err != nil { - log.Errorf("Error monitoring TTY size: %s", err) - } - } - - if errCh != nil { - if err := <-errCh; err != nil { - log.Debugf("Error hijack: %s", err) - return err - } - } - - // Detached mode: wait for the id to be displayed and return. - if !config.AttachStdout && !config.AttachStderr { - // Detached mode - <-waitDisplayId - return nil - } - - var status int - - // Attached mode - if *flAutoRemove { - // Autoremove: wait for the container to finish, retrieve - // the exit code and remove the container - if _, _, err := readBody(cli.call("POST", "/containers/"+runResult.Get("Id")+"/wait", nil, false)); err != nil { - return err - } - if _, status, err = getExitCode(cli, runResult.Get("Id")); err != nil { - return err - } - if _, _, err := readBody(cli.call("DELETE", "/containers/"+runResult.Get("Id")+"?v=1", nil, false)); err != nil { - return err - } - } else { - // No Autoremove: Simply retrieve the exit code - if !config.Tty { - // In non-TTY mode, we can't detach, so we must wait for container exit - if status, err = waitForExit(cli, runResult.Get("Id")); err != nil { - return err - } - } else { - // In TTY mode, there is a race: if the process dies too slowly, the state could - // be updated after the getExitCode call and result in the wrong exit code being reported - if _, status, err = getExitCode(cli, runResult.Get("Id")); err != nil { - return err - } - } - } - if status != 0 { - return &utils.StatusError{StatusCode: status} - } - return nil -} - -func (cli *DockerCli) CmdCp(args ...string) error { - cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH") - if err := cmd.Parse(args); err != nil { - return nil - } - - if cmd.NArg() != 2 { - cmd.Usage() - return nil - } - - var copyData engine.Env - info := strings.Split(cmd.Arg(0), ":") - - if len(info) != 2 { - return fmt.Errorf("Error: Path not specified") - } - - copyData.Set("Resource", info[1]) - copyData.Set("HostPath", cmd.Arg(1)) - - stream, statusCode, err := cli.call("POST", "/containers/"+info[0]+"/copy", copyData, false) - if stream != nil { - defer stream.Close() - } - if statusCode == 404 { - return fmt.Errorf("No such container: %v", info[0]) - } - if err != nil { - return err - } - - if statusCode == 200 { - if err := archive.Untar(stream, copyData.Get("HostPath"), &archive.TarOptions{NoLchown: true}); err != nil { - return err - } - } - return nil -} - -func (cli *DockerCli) CmdSave(args ...string) error { - cmd := cli.Subcmd("save", "IMAGE [IMAGE...]", "Save an image(s) to a tar archive (streamed to STDOUT by default)") - outfile := cmd.String([]string{"o", "-output"}, "", "Write to a file, instead of STDOUT") - - if err := cmd.Parse(args); err != nil { - return err - } - - if cmd.NArg() < 1 { - cmd.Usage() - return nil - } - - var ( - output io.Writer = cli.out - err error - ) - if *outfile != "" { - output, err = os.Create(*outfile) - if err != nil { - return err - } - } else if cli.isTerminalOut { - return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.") - } - - if len(cmd.Args()) == 1 { - image := cmd.Arg(0) - if err := cli.stream("GET", "/images/"+image+"/get", nil, output, nil); err != nil { - return err - } - } else { - v := url.Values{} - for _, arg := range cmd.Args() { - v.Add("names", arg) - } - if err := cli.stream("GET", "/images/get?"+v.Encode(), nil, output, nil); err != nil { - return err - } - } - return nil -} - -func (cli *DockerCli) CmdLoad(args ...string) error { - cmd := cli.Subcmd("load", "", "Load an image from a tar archive on STDIN") - infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN") - - if err := cmd.Parse(args); err != nil { - return err - } - - if cmd.NArg() != 0 { - cmd.Usage() - return nil - } - - var ( - input io.Reader = cli.in - err error - ) - if *infile != "" { - input, err = os.Open(*infile) - if err != nil { - return err - } - } - if err := cli.stream("POST", "/images/load", input, cli.out, nil); err != nil { - return err - } - return nil -} - -func (cli *DockerCli) CmdExec(args ...string) error { - cmd := cli.Subcmd("exec", "CONTAINER COMMAND [ARG...]", "Run a command in a running container") - - execConfig, err := runconfig.ParseExec(cmd, args) - if err != nil { - return err - } - if execConfig.Container == "" { - cmd.Usage() - return nil - } - - stream, _, err := cli.call("POST", "/containers/"+execConfig.Container+"/exec", execConfig, false) - if err != nil { - return err - } - - var execResult engine.Env - if err := execResult.Decode(stream); err != nil { - return err - } - - execID := execResult.Get("Id") - - if execID == "" { - fmt.Fprintf(cli.out, "exec ID empty") - return nil - } - - if execConfig.Detach { - if _, _, err := readBody(cli.call("POST", "/exec/"+execID+"/start", execConfig, false)); err != nil { - return err - } - return nil - } - - // Interactive exec requested. - var ( - out, stderr io.Writer - in io.ReadCloser - hijacked = make(chan io.Closer) - errCh chan error - ) - - // Block the return until the chan gets closed - defer func() { - log.Debugf("End of CmdExec(), Waiting for hijack to finish.") - if _, ok := <-hijacked; ok { - log.Errorf("Hijack did not finish (chan still open)") - } - }() - - if execConfig.AttachStdin { - in = cli.in - } - if execConfig.AttachStdout { - out = cli.out - } - if execConfig.AttachStderr { - if execConfig.Tty { - stderr = cli.out - } else { - stderr = cli.err - } - } - errCh = promise.Go(func() error { - return cli.hijack("POST", "/exec/"+execID+"/start", execConfig.Tty, in, out, stderr, hijacked, execConfig) - }) - - // Acknowledge the hijack before starting - select { - case closer := <-hijacked: - // Make sure that hijack gets closed when returning. (result - // in closing hijack chan and freeing server's goroutines. - if closer != nil { - defer closer.Close() - } - case err := <-errCh: - if err != nil { - log.Debugf("Error hijack: %s", err) - return err - } - } - - if execConfig.Tty && cli.isTerminalIn { - if err := cli.monitorTtySize(execID, true); err != nil { - log.Errorf("Error monitoring TTY size: %s", err) - } - } - - if err := <-errCh; err != nil { - log.Debugf("Error hijack: %s", err) - return err - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/client/hijack.go b/Godeps/_workspace/src/github.com/docker/docker/api/client/hijack.go deleted file mode 100644 index adc012bace..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/client/hijack.go +++ /dev/null @@ -1,139 +0,0 @@ -package client - -import ( - "crypto/tls" - "fmt" - "io" - "net" - "net/http" - "net/http/httputil" - "os" - "runtime" - "strings" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/api" - "github.com/docker/docker/dockerversion" - "github.com/docker/docker/pkg/promise" - "github.com/docker/docker/pkg/stdcopy" - "github.com/docker/docker/pkg/term" -) - -func (cli *DockerCli) dial() (net.Conn, error) { - if cli.tlsConfig != nil && cli.proto != "unix" { - return tls.Dial(cli.proto, cli.addr, cli.tlsConfig) - } - return net.Dial(cli.proto, cli.addr) -} - -func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.ReadCloser, stdout, stderr io.Writer, started chan io.Closer, data interface{}) error { - defer func() { - if started != nil { - close(started) - } - }() - - params, err := cli.encodeData(data) - if err != nil { - return err - } - req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params) - if err != nil { - return err - } - req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION) - req.Header.Set("Content-Type", "plain/text") - req.Host = cli.addr - - dial, err := cli.dial() - if err != nil { - if strings.Contains(err.Error(), "connection refused") { - return fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?") - } - return err - } - clientconn := httputil.NewClientConn(dial, nil) - defer clientconn.Close() - - // Server hijacks the connection, error 'connection closed' expected - clientconn.Do(req) - - rwc, br := clientconn.Hijack() - defer rwc.Close() - - if started != nil { - started <- rwc - } - - var receiveStdout chan error - - var oldState *term.State - - if in != nil && setRawTerminal && cli.isTerminalIn && os.Getenv("NORAW") == "" { - oldState, err = term.SetRawTerminal(cli.inFd) - if err != nil { - return err - } - defer term.RestoreTerminal(cli.inFd, oldState) - } - - if stdout != nil || stderr != nil { - receiveStdout = promise.Go(func() (err error) { - defer func() { - if in != nil { - if setRawTerminal && cli.isTerminalIn { - term.RestoreTerminal(cli.inFd, oldState) - } - // For some reason this Close call blocks on darwin.. - // As the client exists right after, simply discard the close - // until we find a better solution. - if runtime.GOOS != "darwin" { - in.Close() - } - } - }() - - // When TTY is ON, use regular copy - if setRawTerminal && stdout != nil { - _, err = io.Copy(stdout, br) - } else { - _, err = stdcopy.StdCopy(stdout, stderr, br) - } - log.Debugf("[hijack] End of stdout") - return err - }) - } - - sendStdin := promise.Go(func() error { - if in != nil { - io.Copy(rwc, in) - log.Debugf("[hijack] End of stdin") - } - if tcpc, ok := rwc.(*net.TCPConn); ok { - if err := tcpc.CloseWrite(); err != nil { - log.Debugf("Couldn't send EOF: %s", err) - } - } else if unixc, ok := rwc.(*net.UnixConn); ok { - if err := unixc.CloseWrite(); err != nil { - log.Debugf("Couldn't send EOF: %s", err) - } - } - // Discard errors due to pipe interruption - return nil - }) - - if stdout != nil || stderr != nil { - if err := <-receiveStdout; err != nil { - log.Debugf("Error receiveStdout: %s", err) - return err - } - } - - if !cli.isTerminalIn { - if err := <-sendStdin; err != nil { - log.Debugf("Error sendStdin: %s", err) - return err - } - } - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/client/utils.go b/Godeps/_workspace/src/github.com/docker/docker/api/client/utils.go deleted file mode 100644 index 3799ce6735..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/client/utils.go +++ /dev/null @@ -1,276 +0,0 @@ -package client - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - gosignal "os/signal" - "strconv" - "strings" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/api" - "github.com/docker/docker/dockerversion" - "github.com/docker/docker/engine" - "github.com/docker/docker/pkg/signal" - "github.com/docker/docker/pkg/stdcopy" - "github.com/docker/docker/pkg/term" - "github.com/docker/docker/registry" - "github.com/docker/docker/utils" -) - -var ( - ErrConnectionRefused = errors.New("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?") -) - -func (cli *DockerCli) HTTPClient() *http.Client { - return &http.Client{Transport: cli.transport} -} - -func (cli *DockerCli) encodeData(data interface{}) (*bytes.Buffer, error) { - params := bytes.NewBuffer(nil) - if data != nil { - if env, ok := data.(engine.Env); ok { - if err := env.Encode(params); err != nil { - return nil, err - } - } else { - buf, err := json.Marshal(data) - if err != nil { - return nil, err - } - if _, err := params.Write(buf); err != nil { - return nil, err - } - } - } - return params, nil -} - -func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo bool) (io.ReadCloser, int, error) { - params, err := cli.encodeData(data) - if err != nil { - return nil, -1, err - } - req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params) - if err != nil { - return nil, -1, err - } - if passAuthInfo { - cli.LoadConfigFile() - // Resolve the Auth config relevant for this server - authConfig := cli.configFile.ResolveAuthConfig(registry.IndexServerAddress()) - getHeaders := func(authConfig registry.AuthConfig) (map[string][]string, error) { - buf, err := json.Marshal(authConfig) - if err != nil { - return nil, err - } - registryAuthHeader := []string{ - base64.URLEncoding.EncodeToString(buf), - } - return map[string][]string{"X-Registry-Auth": registryAuthHeader}, nil - } - if headers, err := getHeaders(authConfig); err == nil && headers != nil { - for k, v := range headers { - req.Header[k] = v - } - } - } - req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION) - req.URL.Host = cli.addr - req.URL.Scheme = cli.scheme - if data != nil { - req.Header.Set("Content-Type", "application/json") - } else if method == "POST" { - req.Header.Set("Content-Type", "plain/text") - } - resp, err := cli.HTTPClient().Do(req) - if err != nil { - if strings.Contains(err.Error(), "connection refused") { - return nil, -1, ErrConnectionRefused - } - - if cli.tlsConfig == nil { - return nil, -1, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err) - } - return nil, -1, fmt.Errorf("An error occurred trying to connect: %v", err) - - } - - if resp.StatusCode < 200 || resp.StatusCode >= 400 { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, -1, err - } - if len(body) == 0 { - return nil, resp.StatusCode, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(resp.StatusCode), req.URL) - } - return nil, resp.StatusCode, fmt.Errorf("Error response from daemon: %s", bytes.TrimSpace(body)) - } - - return resp.Body, resp.StatusCode, nil -} - -func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer, headers map[string][]string) error { - return cli.streamHelper(method, path, true, in, out, nil, headers) -} - -func (cli *DockerCli) streamHelper(method, path string, setRawTerminal bool, in io.Reader, stdout, stderr io.Writer, headers map[string][]string) error { - if (method == "POST" || method == "PUT") && in == nil { - in = bytes.NewReader([]byte{}) - } - - req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), in) - if err != nil { - return err - } - req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION) - req.URL.Host = cli.addr - req.URL.Scheme = cli.scheme - if method == "POST" { - req.Header.Set("Content-Type", "plain/text") - } - - if headers != nil { - for k, v := range headers { - req.Header[k] = v - } - } - resp, err := cli.HTTPClient().Do(req) - if err != nil { - if strings.Contains(err.Error(), "connection refused") { - return fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?") - } - return err - } - defer resp.Body.Close() - - if resp.StatusCode < 200 || resp.StatusCode >= 400 { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - if len(body) == 0 { - return fmt.Errorf("Error :%s", http.StatusText(resp.StatusCode)) - } - return fmt.Errorf("Error: %s", bytes.TrimSpace(body)) - } - - if api.MatchesContentType(resp.Header.Get("Content-Type"), "application/json") { - return utils.DisplayJSONMessagesStream(resp.Body, stdout, cli.outFd, cli.isTerminalOut) - } - if stdout != nil || stderr != nil { - // When TTY is ON, use regular copy - if setRawTerminal { - _, err = io.Copy(stdout, resp.Body) - } else { - _, err = stdcopy.StdCopy(stdout, stderr, resp.Body) - } - log.Debugf("[stream] End of stdout") - return err - } - return nil -} - -func (cli *DockerCli) resizeTty(id string, isExec bool) { - height, width := cli.getTtySize() - if height == 0 && width == 0 { - return - } - v := url.Values{} - v.Set("h", strconv.Itoa(height)) - v.Set("w", strconv.Itoa(width)) - - path := "" - if !isExec { - path = "/containers/" + id + "/resize?" - } else { - path = "/exec/" + id + "/resize?" - } - - if _, _, err := readBody(cli.call("POST", path+v.Encode(), nil, false)); err != nil { - log.Debugf("Error resize: %s", err) - } -} - -func waitForExit(cli *DockerCli, containerId string) (int, error) { - stream, _, err := cli.call("POST", "/containers/"+containerId+"/wait", nil, false) - if err != nil { - return -1, err - } - - var out engine.Env - if err := out.Decode(stream); err != nil { - return -1, err - } - return out.GetInt("StatusCode"), nil -} - -// getExitCode perform an inspect on the container. It returns -// the running state and the exit code. -func getExitCode(cli *DockerCli, containerId string) (bool, int, error) { - stream, _, err := cli.call("GET", "/containers/"+containerId+"/json", nil, false) - if err != nil { - // If we can't connect, then the daemon probably died. - if err != ErrConnectionRefused { - return false, -1, err - } - return false, -1, nil - } - - var result engine.Env - if err := result.Decode(stream); err != nil { - return false, -1, err - } - - state := result.GetSubEnv("State") - return state.GetBool("Running"), state.GetInt("ExitCode"), nil -} - -func (cli *DockerCli) monitorTtySize(id string, isExec bool) error { - cli.resizeTty(id, isExec) - - sigchan := make(chan os.Signal, 1) - gosignal.Notify(sigchan, signal.SIGWINCH) - go func() { - for _ = range sigchan { - cli.resizeTty(id, isExec) - } - }() - return nil -} - -func (cli *DockerCli) getTtySize() (int, int) { - if !cli.isTerminalOut { - return 0, 0 - } - ws, err := term.GetWinsize(cli.outFd) - if err != nil { - log.Debugf("Error getting size: %s", err) - if ws == nil { - return 0, 0 - } - } - return int(ws.Height), int(ws.Width) -} - -func readBody(stream io.ReadCloser, statusCode int, err error) ([]byte, int, error) { - if stream != nil { - defer stream.Close() - } - if err != nil { - return nil, statusCode, err - } - body, err := ioutil.ReadAll(stream) - if err != nil { - return nil, -1, err - } - return body, statusCode, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/common.go b/Godeps/_workspace/src/github.com/docker/docker/api/common.go deleted file mode 100644 index 94bcc1b267..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/common.go +++ /dev/null @@ -1,79 +0,0 @@ -package api - -import ( - "fmt" - "mime" - "os" - "path" - "strings" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/engine" - "github.com/docker/docker/pkg/parsers" - "github.com/docker/docker/pkg/version" - "github.com/docker/libtrust" -) - -const ( - APIVERSION version.Version = "1.16" - DEFAULTHTTPHOST = "127.0.0.1" - DEFAULTUNIXSOCKET = "/var/run/docker.sock" -) - -func ValidateHost(val string) (string, error) { - host, err := parsers.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val) - if err != nil { - return val, err - } - return host, nil -} - -//TODO remove, used on < 1.5 in getContainersJSON -func DisplayablePorts(ports *engine.Table) string { - result := []string{} - ports.SetKey("PublicPort") - ports.Sort() - for _, port := range ports.Data { - if port.Get("IP") == "" { - result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PrivatePort"), port.Get("Type"))) - } else { - result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type"))) - } - } - return strings.Join(result, ", ") -} - -func MatchesContentType(contentType, expectedType string) bool { - mimetype, _, err := mime.ParseMediaType(contentType) - if err != nil { - log.Errorf("Error parsing media type: %s error: %s", contentType, err.Error()) - } - return err == nil && mimetype == expectedType -} - -// LoadOrCreateTrustKey attempts to load the libtrust key at the given path, -// otherwise generates a new one -func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) { - err := os.MkdirAll(path.Dir(trustKeyPath), 0700) - if err != nil { - return nil, err - } - trustKey, err := libtrust.LoadKeyFile(trustKeyPath) - if err == libtrust.ErrKeyFileDoesNotExist { - trustKey, err = libtrust.GenerateECP256PrivateKey() - if err != nil { - return nil, fmt.Errorf("Error generating key: %s", err) - } - if err := libtrust.SaveKey(trustKeyPath, trustKey); err != nil { - return nil, fmt.Errorf("Error saving key file: %s", err) - } - dir, file := path.Split(trustKeyPath) - // Save public key - if err := libtrust.SavePublicKey(path.Join(dir, "public-"+file), trustKey.PublicKey()); err != nil { - return nil, fmt.Errorf("Error saving public key file: %s", err) - } - } else if err != nil { - return nil, fmt.Errorf("Error loading key file: %s", err) - } - return trustKey, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/server/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/api/server/MAINTAINERS deleted file mode 100644 index c92a061143..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/server/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Victor Vieux (@vieux) -Johan Euphrosine (@proppy) diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/server/auth.go b/Godeps/_workspace/src/github.com/docker/docker/api/server/auth.go deleted file mode 100644 index 75c292ecf7..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/server/auth.go +++ /dev/null @@ -1,177 +0,0 @@ -package server - -import ( - "crypto/tls" - "crypto/x509" - "fmt" - "io/ioutil" - "net" - "os" - "path" - "sync" - - "github.com/docker/libtrust" -) - -// ClientKeyManager manages client keys on the filesystem -type ClientKeyManager struct { - key libtrust.PrivateKey - clientFile string - clientDir string - - clientLock sync.RWMutex - clients []libtrust.PublicKey - - configLock sync.Mutex - configs []*tls.Config -} - -// NewClientKeyManager loads a new manager from a set of key files -// and managed by the given private key. -func NewClientKeyManager(trustKey libtrust.PrivateKey, clientFile, clientDir string) (*ClientKeyManager, error) { - m := &ClientKeyManager{ - key: trustKey, - clientFile: clientFile, - clientDir: clientDir, - } - if err := m.loadKeys(); err != nil { - return nil, err - } - // TODO Start watching file and directory - - return m, nil -} -func (c *ClientKeyManager) loadKeys() error { - // Load authorized keys file - var clients []libtrust.PublicKey - if c.clientFile != "" { - fileClients, err := libtrust.LoadKeySetFile(c.clientFile) - if err != nil { - return fmt.Errorf("unable to load authorized keys: %s", err) - } - clients = fileClients - } - - // Add clients from authorized keys directory - files, err := ioutil.ReadDir(c.clientDir) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("unable to open authorized keys directory: %s", err) - } - for _, f := range files { - if !f.IsDir() { - publicKey, err := libtrust.LoadPublicKeyFile(path.Join(c.clientDir, f.Name())) - if err != nil { - return fmt.Errorf("unable to load authorized key file: %s", err) - } - clients = append(clients, publicKey) - } - } - - c.clientLock.Lock() - c.clients = clients - c.clientLock.Unlock() - - return nil -} - -// RegisterTLSConfig registers a tls configuration to manager -// such that any changes to the keys may be reflected in -// the tls client CA pool -func (c *ClientKeyManager) RegisterTLSConfig(tlsConfig *tls.Config) error { - c.clientLock.RLock() - certPool, err := libtrust.GenerateCACertPool(c.key, c.clients) - if err != nil { - return fmt.Errorf("CA pool generation error: %s", err) - } - c.clientLock.RUnlock() - - tlsConfig.ClientCAs = certPool - - c.configLock.Lock() - c.configs = append(c.configs, tlsConfig) - c.configLock.Unlock() - - return nil -} - -// NewIdentityAuthTLSConfig creates a tls.Config for the server to use for -// libtrust identity authentication -func NewIdentityAuthTLSConfig(trustKey libtrust.PrivateKey, clients *ClientKeyManager, addr string) (*tls.Config, error) { - tlsConfig := createTLSConfig() - - tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert - if err := clients.RegisterTLSConfig(tlsConfig); err != nil { - return nil, err - } - - // Generate cert - ips, domains, err := parseAddr(addr) - if err != nil { - return nil, err - } - // add default docker domain for docker clients to look for - domains = append(domains, "docker") - x509Cert, err := libtrust.GenerateSelfSignedServerCert(trustKey, domains, ips) - if err != nil { - return nil, fmt.Errorf("certificate generation error: %s", err) - } - tlsConfig.Certificates = []tls.Certificate{{ - Certificate: [][]byte{x509Cert.Raw}, - PrivateKey: trustKey.CryptoPrivateKey(), - Leaf: x509Cert, - }} - - return tlsConfig, nil -} - -// NewCertAuthTLSConfig creates a tls.Config for the server to use for -// certificate authentication -func NewCertAuthTLSConfig(caPath, certPath, keyPath string) (*tls.Config, error) { - tlsConfig := createTLSConfig() - - cert, err := tls.LoadX509KeyPair(certPath, keyPath) - if err != nil { - return nil, fmt.Errorf("Couldn't load X509 key pair (%s, %s): %s. Key encrypted?", certPath, keyPath, err) - } - tlsConfig.Certificates = []tls.Certificate{cert} - - // Verify client certificates against a CA? - if caPath != "" { - certPool := x509.NewCertPool() - file, err := ioutil.ReadFile(caPath) - if err != nil { - return nil, fmt.Errorf("Couldn't read CA certificate: %s", err) - } - certPool.AppendCertsFromPEM(file) - - tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert - tlsConfig.ClientCAs = certPool - } - - return tlsConfig, nil -} - -func createTLSConfig() *tls.Config { - return &tls.Config{ - NextProtos: []string{"http/1.1"}, - // Avoid fallback on insecure SSL protocols - MinVersion: tls.VersionTLS10, - } -} - -// parseAddr parses an address into an array of IPs and domains -func parseAddr(addr string) ([]net.IP, []string, error) { - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, nil, err - } - var domains []string - var ips []net.IP - ip := net.ParseIP(host) - if ip != nil { - ips = []net.IP{ip} - } else { - domains = []string{host} - } - return ips, domains, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/server/server.go b/Godeps/_workspace/src/github.com/docker/docker/api/server/server.go deleted file mode 100644 index 3595b16aa8..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/server/server.go +++ /dev/null @@ -1,1582 +0,0 @@ -package server - -import ( - "bufio" - "bytes" - "crypto/tls" - "encoding/base64" - "encoding/json" - "expvar" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/http/pprof" - "os" - "strconv" - "strings" - "syscall" - - "code.google.com/p/go.net/websocket" - "github.com/docker/libcontainer/user" - "github.com/gorilla/mux" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/api" - "github.com/docker/docker/engine" - "github.com/docker/docker/pkg/listenbuffer" - "github.com/docker/docker/pkg/parsers" - "github.com/docker/docker/pkg/stdcopy" - "github.com/docker/docker/pkg/systemd" - "github.com/docker/docker/pkg/version" - "github.com/docker/docker/registry" - "github.com/docker/docker/utils" -) - -var ( - activationLock chan struct{} -) - -type HttpServer struct { - srv *http.Server - l net.Listener -} - -func (s *HttpServer) Serve() error { - return s.srv.Serve(s.l) -} -func (s *HttpServer) Close() error { - return s.l.Close() -} - -type HttpApiFunc func(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error - -func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) { - conn, _, err := w.(http.Hijacker).Hijack() - if err != nil { - return nil, nil, err - } - // Flush the options to make sure the client sets the raw mode - conn.Write([]byte{}) - return conn, conn, nil -} - -// Check to make sure request's Content-Type is application/json -func checkForJson(r *http.Request) error { - ct := r.Header.Get("Content-Type") - - // No Content-Type header is ok as long as there's no Body - if ct == "" { - if r.Body == nil || r.ContentLength == 0 { - return nil - } - } - - // Otherwise it better be json - if api.MatchesContentType(ct, "application/json") { - return nil - } - return fmt.Errorf("Content-Type specified (%s) must be 'application/json'", ct) -} - -//If we don't do this, POST method without Content-type (even with empty body) will fail -func parseForm(r *http.Request) error { - if r == nil { - return nil - } - if err := r.ParseForm(); err != nil && !strings.HasPrefix(err.Error(), "mime:") { - return err - } - return nil -} - -func parseMultipartForm(r *http.Request) error { - if err := r.ParseMultipartForm(4096); err != nil && !strings.HasPrefix(err.Error(), "mime:") { - return err - } - return nil -} - -func httpError(w http.ResponseWriter, err error) { - statusCode := http.StatusInternalServerError - // FIXME: this is brittle and should not be necessary. - // If we need to differentiate between different possible error types, we should - // create appropriate error types with clearly defined meaning. - errStr := strings.ToLower(err.Error()) - if strings.Contains(errStr, "no such") { - statusCode = http.StatusNotFound - } else if strings.Contains(errStr, "bad parameter") { - statusCode = http.StatusBadRequest - } else if strings.Contains(errStr, "conflict") { - statusCode = http.StatusConflict - } else if strings.Contains(errStr, "impossible") { - statusCode = http.StatusNotAcceptable - } else if strings.Contains(errStr, "wrong login/password") { - statusCode = http.StatusUnauthorized - } else if strings.Contains(errStr, "hasn't been activated") { - statusCode = http.StatusForbidden - } - - if err != nil { - log.Errorf("HTTP Error: statusCode=%d %s", statusCode, err.Error()) - http.Error(w, err.Error(), statusCode) - } -} - -func writeJSON(w http.ResponseWriter, code int, v engine.Env) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(code) - return v.Encode(w) -} - -func streamJSON(job *engine.Job, w http.ResponseWriter, flush bool) { - w.Header().Set("Content-Type", "application/json") - if flush { - job.Stdout.Add(utils.NewWriteFlusher(w)) - } else { - job.Stdout.Add(w) - } -} - -func getBoolParam(value string) (bool, error) { - if value == "" { - return false, nil - } - ret, err := strconv.ParseBool(value) - if err != nil { - return false, fmt.Errorf("Bad parameter") - } - return ret, nil -} - -func postAuth(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - var ( - authConfig, err = ioutil.ReadAll(r.Body) - job = eng.Job("auth") - stdoutBuffer = bytes.NewBuffer(nil) - ) - if err != nil { - return err - } - job.Setenv("authConfig", string(authConfig)) - job.Stdout.Add(stdoutBuffer) - if err = job.Run(); err != nil { - return err - } - if status := engine.Tail(stdoutBuffer, 1); status != "" { - var env engine.Env - env.Set("Status", status) - return writeJSON(w, http.StatusOK, env) - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func getVersion(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - w.Header().Set("Content-Type", "application/json") - eng.ServeHTTP(w, r) - return nil -} - -func postContainersKill(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := parseForm(r); err != nil { - return err - } - job := eng.Job("kill", vars["name"]) - if sig := r.Form.Get("signal"); sig != "" { - job.Args = append(job.Args, sig) - } - if err := job.Run(); err != nil { - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func postContainersPause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := parseForm(r); err != nil { - return err - } - job := eng.Job("pause", vars["name"]) - if err := job.Run(); err != nil { - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func postContainersUnpause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := parseForm(r); err != nil { - return err - } - job := eng.Job("unpause", vars["name"]) - if err := job.Run(); err != nil { - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func getContainersExport(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - job := eng.Job("export", vars["name"]) - job.Stdout.Add(w) - if err := job.Run(); err != nil { - return err - } - return nil -} - -func getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - - var ( - err error - outs *engine.Table - job = eng.Job("images") - ) - - job.Setenv("filters", r.Form.Get("filters")) - // FIXME this parameter could just be a match filter - job.Setenv("filter", r.Form.Get("filter")) - job.Setenv("all", r.Form.Get("all")) - - if version.GreaterThanOrEqualTo("1.7") { - streamJSON(job, w, false) - } else if outs, err = job.Stdout.AddListTable(); err != nil { - return err - } - - if err := job.Run(); err != nil { - return err - } - - if version.LessThan("1.7") && outs != nil { // Convert to legacy format - outsLegacy := engine.NewTable("Created", 0) - for _, out := range outs.Data { - for _, repoTag := range out.GetList("RepoTags") { - repo, tag := parsers.ParseRepositoryTag(repoTag) - outLegacy := &engine.Env{} - outLegacy.Set("Repository", repo) - outLegacy.SetJson("Tag", tag) - outLegacy.Set("Id", out.Get("Id")) - outLegacy.SetInt64("Created", out.GetInt64("Created")) - outLegacy.SetInt64("Size", out.GetInt64("Size")) - outLegacy.SetInt64("VirtualSize", out.GetInt64("VirtualSize")) - outsLegacy.Add(outLegacy) - } - } - w.Header().Set("Content-Type", "application/json") - if _, err := outsLegacy.WriteListTo(w); err != nil { - return err - } - } - return nil -} - -func getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if version.GreaterThan("1.6") { - w.WriteHeader(http.StatusNotFound) - return fmt.Errorf("This is now implemented in the client.") - } - eng.ServeHTTP(w, r) - return nil -} - -func getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - w.Header().Set("Content-Type", "application/json") - eng.ServeHTTP(w, r) - return nil -} - -func getEvents(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - - var job = eng.Job("events") - streamJSON(job, w, true) - job.Setenv("since", r.Form.Get("since")) - job.Setenv("until", r.Form.Get("until")) - return job.Run() -} - -func getImagesHistory(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - var job = eng.Job("history", vars["name"]) - streamJSON(job, w, false) - - if err := job.Run(); err != nil { - return err - } - return nil -} - -func getContainersChanges(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - var job = eng.Job("container_changes", vars["name"]) - streamJSON(job, w, false) - - return job.Run() -} - -func getContainersTop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if version.LessThan("1.4") { - return fmt.Errorf("top was improved a lot since 1.3, Please upgrade your docker client.") - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := parseForm(r); err != nil { - return err - } - - job := eng.Job("top", vars["name"], r.Form.Get("ps_args")) - streamJSON(job, w, false) - return job.Run() -} - -func getContainersJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - var ( - err error - outs *engine.Table - job = eng.Job("containers") - ) - - job.Setenv("all", r.Form.Get("all")) - job.Setenv("size", r.Form.Get("size")) - job.Setenv("since", r.Form.Get("since")) - job.Setenv("before", r.Form.Get("before")) - job.Setenv("limit", r.Form.Get("limit")) - job.Setenv("filters", r.Form.Get("filters")) - - if version.GreaterThanOrEqualTo("1.5") { - streamJSON(job, w, false) - } else if outs, err = job.Stdout.AddTable(); err != nil { - return err - } - if err = job.Run(); err != nil { - return err - } - if version.LessThan("1.5") { // Convert to legacy format - for _, out := range outs.Data { - ports := engine.NewTable("", 0) - ports.ReadListFrom([]byte(out.Get("Ports"))) - out.Set("Ports", api.DisplayablePorts(ports)) - } - w.Header().Set("Content-Type", "application/json") - if _, err = outs.WriteListTo(w); err != nil { - return err - } - } - return nil -} - -func getContainersLogs(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - var ( - inspectJob = eng.Job("container_inspect", vars["name"]) - logsJob = eng.Job("logs", vars["name"]) - c, err = inspectJob.Stdout.AddEnv() - ) - if err != nil { - return err - } - logsJob.Setenv("follow", r.Form.Get("follow")) - logsJob.Setenv("tail", r.Form.Get("tail")) - logsJob.Setenv("stdout", r.Form.Get("stdout")) - logsJob.Setenv("stderr", r.Form.Get("stderr")) - logsJob.Setenv("timestamps", r.Form.Get("timestamps")) - // Validate args here, because we can't return not StatusOK after job.Run() call - stdout, stderr := logsJob.GetenvBool("stdout"), logsJob.GetenvBool("stderr") - if !(stdout || stderr) { - return fmt.Errorf("Bad parameters: you must choose at least one stream") - } - if err = inspectJob.Run(); err != nil { - return err - } - - var outStream, errStream io.Writer - outStream = utils.NewWriteFlusher(w) - - if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && version.GreaterThanOrEqualTo("1.6") { - errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) - outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) - } else { - errStream = outStream - } - - logsJob.Stdout.Add(outStream) - logsJob.Stderr.Set(errStream) - if err := logsJob.Run(); err != nil { - fmt.Fprintf(outStream, "Error running logs job: %s\n", err) - } - return nil -} - -func postImagesTag(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - job := eng.Job("tag", vars["name"], r.Form.Get("repo"), r.Form.Get("tag")) - job.Setenv("force", r.Form.Get("force")) - if err := job.Run(); err != nil { - return err - } - w.WriteHeader(http.StatusCreated) - return nil -} - -func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - var ( - config engine.Env - env engine.Env - job = eng.Job("commit", r.Form.Get("container")) - stdoutBuffer = bytes.NewBuffer(nil) - ) - - if err := checkForJson(r); err != nil { - return err - } - - if err := config.Decode(r.Body); err != nil { - log.Errorf("%s", err) - } - - if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") { - job.Setenv("pause", "1") - } else { - job.Setenv("pause", r.FormValue("pause")) - } - - job.Setenv("repo", r.Form.Get("repo")) - job.Setenv("tag", r.Form.Get("tag")) - job.Setenv("author", r.Form.Get("author")) - job.Setenv("comment", r.Form.Get("comment")) - job.SetenvSubEnv("config", &config) - - job.Stdout.Add(stdoutBuffer) - if err := job.Run(); err != nil { - return err - } - env.Set("Id", engine.Tail(stdoutBuffer, 1)) - return writeJSON(w, http.StatusCreated, env) -} - -// Creates an image from Pull or from Import -func postImagesCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - - var ( - image = r.Form.Get("fromImage") - repo = r.Form.Get("repo") - tag = r.Form.Get("tag") - job *engine.Job - ) - authEncoded := r.Header.Get("X-Registry-Auth") - authConfig := ®istry.AuthConfig{} - if authEncoded != "" { - authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) - if err := json.NewDecoder(authJson).Decode(authConfig); err != nil { - // for a pull it is not an error if no auth was given - // to increase compatibility with the existing api it is defaulting to be empty - authConfig = ®istry.AuthConfig{} - } - } - if image != "" { //pull - if tag == "" { - image, tag = parsers.ParseRepositoryTag(image) - } - metaHeaders := map[string][]string{} - for k, v := range r.Header { - if strings.HasPrefix(k, "X-Meta-") { - metaHeaders[k] = v - } - } - job = eng.Job("pull", image, tag) - job.SetenvBool("parallel", version.GreaterThan("1.3")) - job.SetenvJson("metaHeaders", metaHeaders) - job.SetenvJson("authConfig", authConfig) - } else { //import - if tag == "" { - repo, tag = parsers.ParseRepositoryTag(repo) - } - job = eng.Job("import", r.Form.Get("fromSrc"), repo, tag) - job.Stdin.Add(r.Body) - } - - if version.GreaterThan("1.0") { - job.SetenvBool("json", true) - streamJSON(job, w, true) - } else { - job.Stdout.Add(utils.NewWriteFlusher(w)) - } - if err := job.Run(); err != nil { - if !job.Stdout.Used() { - return err - } - sf := utils.NewStreamFormatter(version.GreaterThan("1.0")) - w.Write(sf.FormatError(err)) - } - - return nil -} - -func getImagesSearch(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - var ( - authEncoded = r.Header.Get("X-Registry-Auth") - authConfig = ®istry.AuthConfig{} - metaHeaders = map[string][]string{} - ) - - if authEncoded != "" { - authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) - if err := json.NewDecoder(authJson).Decode(authConfig); err != nil { - // for a search it is not an error if no auth was given - // to increase compatibility with the existing api it is defaulting to be empty - authConfig = ®istry.AuthConfig{} - } - } - for k, v := range r.Header { - if strings.HasPrefix(k, "X-Meta-") { - metaHeaders[k] = v - } - } - - var job = eng.Job("search", r.Form.Get("term")) - job.SetenvJson("metaHeaders", metaHeaders) - job.SetenvJson("authConfig", authConfig) - streamJSON(job, w, false) - - return job.Run() -} - -func postImagesPush(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - metaHeaders := map[string][]string{} - for k, v := range r.Header { - if strings.HasPrefix(k, "X-Meta-") { - metaHeaders[k] = v - } - } - if err := parseForm(r); err != nil { - return err - } - authConfig := ®istry.AuthConfig{} - - authEncoded := r.Header.Get("X-Registry-Auth") - if authEncoded != "" { - // the new format is to handle the authConfig as a header - authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) - if err := json.NewDecoder(authJson).Decode(authConfig); err != nil { - // to increase compatibility to existing api it is defaulting to be empty - authConfig = ®istry.AuthConfig{} - } - } else { - // the old format is supported for compatibility if there was no authConfig header - if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil { - return err - } - } - - job := eng.Job("push", vars["name"]) - job.SetenvJson("metaHeaders", metaHeaders) - job.SetenvJson("authConfig", authConfig) - job.Setenv("tag", r.Form.Get("tag")) - if version.GreaterThan("1.0") { - job.SetenvBool("json", true) - streamJSON(job, w, true) - } else { - job.Stdout.Add(utils.NewWriteFlusher(w)) - } - - if err := job.Run(); err != nil { - if !job.Stdout.Used() { - return err - } - sf := utils.NewStreamFormatter(version.GreaterThan("1.0")) - w.Write(sf.FormatError(err)) - } - return nil -} - -func getImagesGet(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := parseForm(r); err != nil { - return err - } - if version.GreaterThan("1.0") { - w.Header().Set("Content-Type", "application/x-tar") - } - var job *engine.Job - if name, ok := vars["name"]; ok { - job = eng.Job("image_export", name) - } else { - job = eng.Job("image_export", r.Form["names"]...) - } - job.Stdout.Add(w) - return job.Run() -} - -func postImagesLoad(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - job := eng.Job("load") - job.Stdin.Add(r.Body) - return job.Run() -} - -func postContainersCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return nil - } - var ( - out engine.Env - job = eng.Job("create", r.Form.Get("name")) - outWarnings []string - stdoutBuffer = bytes.NewBuffer(nil) - warnings = bytes.NewBuffer(nil) - ) - - if err := checkForJson(r); err != nil { - return err - } - - if err := job.DecodeEnv(r.Body); err != nil { - return err - } - // Read container ID from the first line of stdout - job.Stdout.Add(stdoutBuffer) - // Read warnings from stderr - job.Stderr.Add(warnings) - if err := job.Run(); err != nil { - return err - } - // Parse warnings from stderr - scanner := bufio.NewScanner(warnings) - for scanner.Scan() { - outWarnings = append(outWarnings, scanner.Text()) - } - out.Set("Id", engine.Tail(stdoutBuffer, 1)) - out.SetList("Warnings", outWarnings) - - return writeJSON(w, http.StatusCreated, out) -} - -func postContainersRestart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - job := eng.Job("restart", vars["name"]) - job.Setenv("t", r.Form.Get("t")) - if err := job.Run(); err != nil { - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func deleteContainers(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - job := eng.Job("rm", vars["name"]) - - job.Setenv("forceRemove", r.Form.Get("force")) - - job.Setenv("removeVolume", r.Form.Get("v")) - job.Setenv("removeLink", r.Form.Get("link")) - if err := job.Run(); err != nil { - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - var job = eng.Job("image_delete", vars["name"]) - streamJSON(job, w, false) - job.Setenv("force", r.Form.Get("force")) - job.Setenv("noprune", r.Form.Get("noprune")) - - return job.Run() -} - -func postContainersStart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - var ( - name = vars["name"] - job = eng.Job("start", name) - ) - - // If contentLength is -1, we can assumed chunked encoding - // or more technically that the length is unknown - // http://golang.org/src/pkg/net/http/request.go#L139 - // net/http otherwise seems to swallow any headers related to chunked encoding - // including r.TransferEncoding - // allow a nil body for backwards compatibility - if r.Body != nil && (r.ContentLength > 0 || r.ContentLength == -1) { - if err := checkForJson(r); err != nil { - return err - } - - if err := job.DecodeEnv(r.Body); err != nil { - return err - } - } - - if err := job.Run(); err != nil { - if err.Error() == "Container already started" { - w.WriteHeader(http.StatusNotModified) - return nil - } - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func postContainersStop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - job := eng.Job("stop", vars["name"]) - job.Setenv("t", r.Form.Get("t")) - if err := job.Run(); err != nil { - if err.Error() == "Container already stopped" { - w.WriteHeader(http.StatusNotModified) - return nil - } - return err - } - w.WriteHeader(http.StatusNoContent) - return nil -} - -func postContainersWait(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - var ( - env engine.Env - stdoutBuffer = bytes.NewBuffer(nil) - job = eng.Job("wait", vars["name"]) - ) - job.Stdout.Add(stdoutBuffer) - if err := job.Run(); err != nil { - return err - } - - env.Set("StatusCode", engine.Tail(stdoutBuffer, 1)) - return writeJSON(w, http.StatusOK, env) -} - -func postContainersResize(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := eng.Job("resize", vars["name"], r.Form.Get("h"), r.Form.Get("w")).Run(); err != nil { - return err - } - return nil -} - -func postContainersAttach(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - var ( - job = eng.Job("container_inspect", vars["name"]) - c, err = job.Stdout.AddEnv() - ) - if err != nil { - return err - } - if err = job.Run(); err != nil { - return err - } - - inStream, outStream, err := hijackServer(w) - if err != nil { - return err - } - defer func() { - if tcpc, ok := inStream.(*net.TCPConn); ok { - tcpc.CloseWrite() - } else { - inStream.Close() - } - }() - defer func() { - if tcpc, ok := outStream.(*net.TCPConn); ok { - tcpc.CloseWrite() - } else if closer, ok := outStream.(io.Closer); ok { - closer.Close() - } - }() - - var errStream io.Writer - - fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") - - if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && version.GreaterThanOrEqualTo("1.6") { - errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) - outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) - } else { - errStream = outStream - } - - job = eng.Job("attach", vars["name"]) - job.Setenv("logs", r.Form.Get("logs")) - job.Setenv("stream", r.Form.Get("stream")) - job.Setenv("stdin", r.Form.Get("stdin")) - job.Setenv("stdout", r.Form.Get("stdout")) - job.Setenv("stderr", r.Form.Get("stderr")) - job.Stdin.Add(inStream) - job.Stdout.Add(outStream) - job.Stderr.Set(errStream) - if err := job.Run(); err != nil { - fmt.Fprintf(outStream, "Error attaching: %s\n", err) - - } - return nil -} - -func wsContainersAttach(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - if err := eng.Job("container_inspect", vars["name"]).Run(); err != nil { - return err - } - - h := websocket.Handler(func(ws *websocket.Conn) { - defer ws.Close() - job := eng.Job("attach", vars["name"]) - job.Setenv("logs", r.Form.Get("logs")) - job.Setenv("stream", r.Form.Get("stream")) - job.Setenv("stdin", r.Form.Get("stdin")) - job.Setenv("stdout", r.Form.Get("stdout")) - job.Setenv("stderr", r.Form.Get("stderr")) - job.Stdin.Add(ws) - job.Stdout.Add(ws) - job.Stderr.Set(ws) - if err := job.Run(); err != nil { - log.Errorf("Error attaching websocket: %s", err) - } - }) - h.ServeHTTP(w, r) - - return nil -} - -func getContainersByName(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - var job = eng.Job("container_inspect", vars["name"]) - if version.LessThan("1.12") { - job.SetenvBool("raw", true) - } - streamJSON(job, w, false) - return job.Run() -} - -func getImagesByName(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - var job = eng.Job("image_inspect", vars["name"]) - if version.LessThan("1.12") { - job.SetenvBool("raw", true) - } - streamJSON(job, w, false) - return job.Run() -} - -func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if version.LessThan("1.3") { - return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.") - } - var ( - authEncoded = r.Header.Get("X-Registry-Auth") - authConfig = ®istry.AuthConfig{} - configFileEncoded = r.Header.Get("X-Registry-Config") - configFile = ®istry.ConfigFile{} - job = eng.Job("build") - ) - - // This block can be removed when API versions prior to 1.9 are deprecated. - // Both headers will be parsed and sent along to the daemon, but if a non-empty - // ConfigFile is present, any value provided as an AuthConfig directly will - // be overridden. See BuildFile::CmdFrom for details. - if version.LessThan("1.9") && authEncoded != "" { - authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) - if err := json.NewDecoder(authJson).Decode(authConfig); err != nil { - // for a pull it is not an error if no auth was given - // to increase compatibility with the existing api it is defaulting to be empty - authConfig = ®istry.AuthConfig{} - } - } - - if configFileEncoded != "" { - configFileJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(configFileEncoded)) - if err := json.NewDecoder(configFileJson).Decode(configFile); err != nil { - // for a pull it is not an error if no auth was given - // to increase compatibility with the existing api it is defaulting to be empty - configFile = ®istry.ConfigFile{} - } - } - - if version.GreaterThanOrEqualTo("1.8") { - job.SetenvBool("json", true) - streamJSON(job, w, true) - } else { - job.Stdout.Add(utils.NewWriteFlusher(w)) - } - - if r.FormValue("forcerm") == "1" && version.GreaterThanOrEqualTo("1.12") { - job.Setenv("rm", "1") - } else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") { - job.Setenv("rm", "1") - } else { - job.Setenv("rm", r.FormValue("rm")) - } - if r.FormValue("pull") == "1" && version.GreaterThanOrEqualTo("1.16") { - job.Setenv("pull", "1") - } - job.Stdin.Add(r.Body) - job.Setenv("remote", r.FormValue("remote")) - job.Setenv("t", r.FormValue("t")) - job.Setenv("q", r.FormValue("q")) - job.Setenv("nocache", r.FormValue("nocache")) - job.Setenv("forcerm", r.FormValue("forcerm")) - job.SetenvJson("authConfig", authConfig) - job.SetenvJson("configFile", configFile) - - if err := job.Run(); err != nil { - if !job.Stdout.Used() { - return err - } - sf := utils.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8")) - w.Write(sf.FormatError(err)) - } - return nil -} - -func postContainersCopy(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if vars == nil { - return fmt.Errorf("Missing parameter") - } - - var copyData engine.Env - - if err := checkForJson(r); err != nil { - return err - } - - if err := copyData.Decode(r.Body); err != nil { - return err - } - - if copyData.Get("Resource") == "" { - return fmt.Errorf("Path cannot be empty") - } - - origResource := copyData.Get("Resource") - - if copyData.Get("Resource")[0] == '/' { - copyData.Set("Resource", copyData.Get("Resource")[1:]) - } - - job := eng.Job("container_copy", vars["name"], copyData.Get("Resource")) - job.Stdout.Add(w) - w.Header().Set("Content-Type", "application/x-tar") - if err := job.Run(); err != nil { - log.Errorf("%s", err.Error()) - if strings.Contains(strings.ToLower(err.Error()), "no such container") { - w.WriteHeader(http.StatusNotFound) - } else if strings.Contains(err.Error(), "no such file or directory") { - return fmt.Errorf("Could not find the file %s in container %s", origResource, vars["name"]) - } - } - return nil -} - -func postContainerExecCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return nil - } - var ( - out engine.Env - name = vars["name"] - job = eng.Job("execCreate", name) - stdoutBuffer = bytes.NewBuffer(nil) - ) - - if err := job.DecodeEnv(r.Body); err != nil { - return err - } - - job.Stdout.Add(stdoutBuffer) - // Register an instance of Exec in container. - if err := job.Run(); err != nil { - fmt.Fprintf(os.Stderr, "Error setting up exec command in container %s: %s\n", name, err) - return err - } - // Return the ID - out.Set("Id", engine.Tail(stdoutBuffer, 1)) - - return writeJSON(w, http.StatusCreated, out) -} - -// TODO(vishh): Refactor the code to avoid having to specify stream config as part of both create and start. -func postContainerExecStart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return nil - } - var ( - name = vars["name"] - job = eng.Job("execStart", name) - errOut io.Writer = os.Stderr - ) - - if err := job.DecodeEnv(r.Body); err != nil { - return err - } - if !job.GetenvBool("Detach") { - // Setting up the streaming http interface. - inStream, outStream, err := hijackServer(w) - if err != nil { - return err - } - - defer func() { - if tcpc, ok := inStream.(*net.TCPConn); ok { - tcpc.CloseWrite() - } else { - inStream.Close() - } - }() - defer func() { - if tcpc, ok := outStream.(*net.TCPConn); ok { - tcpc.CloseWrite() - } else if closer, ok := outStream.(io.Closer); ok { - closer.Close() - } - }() - - var errStream io.Writer - - fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") - if !job.GetenvBool("Tty") && version.GreaterThanOrEqualTo("1.6") { - errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) - outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) - } else { - errStream = outStream - } - job.Stdin.Add(inStream) - job.Stdout.Add(outStream) - job.Stderr.Set(errStream) - errOut = outStream - } - // Now run the user process in container. - job.SetCloseIO(false) - if err := job.Run(); err != nil { - fmt.Fprintf(errOut, "Error starting exec command in container %s: %s\n", name, err) - return err - } - w.WriteHeader(http.StatusNoContent) - - return nil -} - -func postContainerExecResize(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if err := parseForm(r); err != nil { - return err - } - if vars == nil { - return fmt.Errorf("Missing parameter") - } - if err := eng.Job("execResize", vars["name"], r.Form.Get("h"), r.Form.Get("w")).Run(); err != nil { - return err - } - return nil -} - -func optionsHandler(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - w.WriteHeader(http.StatusOK) - return nil -} -func writeCorsHeaders(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Access-Control-Allow-Origin", "*") - w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth") - w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS") -} - -func ping(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - _, err := w.Write([]byte{'O', 'K'}) - return err -} - -func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, enableCors bool, dockerVersion version.Version) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // log the request - log.Debugf("Calling %s %s", localMethod, localRoute) - - if logging { - log.Infof("%s %s", r.Method, r.RequestURI) - } - - if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") { - userAgent := strings.Split(r.Header.Get("User-Agent"), "/") - if len(userAgent) == 2 && !dockerVersion.Equal(version.Version(userAgent[1])) { - log.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], dockerVersion) - } - } - version := version.Version(mux.Vars(r)["version"]) - if version == "" { - version = api.APIVERSION - } - if enableCors { - writeCorsHeaders(w, r) - } - - if version.GreaterThan(api.APIVERSION) { - http.Error(w, fmt.Errorf("client and server don't have same version (client : %s, server: %s)", version, api.APIVERSION).Error(), http.StatusNotFound) - return - } - - if err := handlerFunc(eng, version, w, r, mux.Vars(r)); err != nil { - log.Errorf("Handler for %s %s returned error: %s", localMethod, localRoute, err) - httpError(w, err) - } - } -} - -// Replicated from expvar.go as not public. -func expvarHandler(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=utf-8") - fmt.Fprintf(w, "{\n") - first := true - expvar.Do(func(kv expvar.KeyValue) { - if !first { - fmt.Fprintf(w, ",\n") - } - first = false - fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) - }) - fmt.Fprintf(w, "\n}\n") -} - -func AttachProfiler(router *mux.Router) { - router.HandleFunc("/debug/vars", expvarHandler) - router.HandleFunc("/debug/pprof/", pprof.Index) - router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) - router.HandleFunc("/debug/pprof/profile", pprof.Profile) - router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) - router.HandleFunc("/debug/pprof/heap", pprof.Handler("heap").ServeHTTP) - router.HandleFunc("/debug/pprof/goroutine", pprof.Handler("goroutine").ServeHTTP) - router.HandleFunc("/debug/pprof/threadcreate", pprof.Handler("threadcreate").ServeHTTP) -} - -func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion string) (*mux.Router, error) { - r := mux.NewRouter() - if os.Getenv("DEBUG") != "" { - AttachProfiler(r) - } - m := map[string]map[string]HttpApiFunc{ - "GET": { - "/_ping": ping, - "/events": getEvents, - "/info": getInfo, - "/version": getVersion, - "/images/json": getImagesJSON, - "/images/viz": getImagesViz, - "/images/search": getImagesSearch, - "/images/get": getImagesGet, - "/images/{name:.*}/get": getImagesGet, - "/images/{name:.*}/history": getImagesHistory, - "/images/{name:.*}/json": getImagesByName, - "/containers/ps": getContainersJSON, - "/containers/json": getContainersJSON, - "/containers/{name:.*}/export": getContainersExport, - "/containers/{name:.*}/changes": getContainersChanges, - "/containers/{name:.*}/json": getContainersByName, - "/containers/{name:.*}/top": getContainersTop, - "/containers/{name:.*}/logs": getContainersLogs, - "/containers/{name:.*}/attach/ws": wsContainersAttach, - }, - "POST": { - "/auth": postAuth, - "/commit": postCommit, - "/build": postBuild, - "/images/create": postImagesCreate, - "/images/load": postImagesLoad, - "/images/{name:.*}/push": postImagesPush, - "/images/{name:.*}/tag": postImagesTag, - "/containers/create": postContainersCreate, - "/containers/{name:.*}/kill": postContainersKill, - "/containers/{name:.*}/pause": postContainersPause, - "/containers/{name:.*}/unpause": postContainersUnpause, - "/containers/{name:.*}/restart": postContainersRestart, - "/containers/{name:.*}/start": postContainersStart, - "/containers/{name:.*}/stop": postContainersStop, - "/containers/{name:.*}/wait": postContainersWait, - "/containers/{name:.*}/resize": postContainersResize, - "/containers/{name:.*}/attach": postContainersAttach, - "/containers/{name:.*}/copy": postContainersCopy, - "/containers/{name:.*}/exec": postContainerExecCreate, - "/exec/{name:.*}/start": postContainerExecStart, - "/exec/{name:.*}/resize": postContainerExecResize, - }, - "DELETE": { - "/containers/{name:.*}": deleteContainers, - "/images/{name:.*}": deleteImages, - }, - "OPTIONS": { - "": optionsHandler, - }, - } - - for method, routes := range m { - for route, fct := range routes { - log.Debugf("Registering %s, %s", method, route) - // NOTE: scope issue, make sure the variables are local and won't be changed - localRoute := route - localFct := fct - localMethod := method - - // build the handler function - f := makeHttpHandler(eng, logging, localMethod, localRoute, localFct, enableCors, version.Version(dockerVersion)) - - // add the new route - if localRoute == "" { - r.Methods(localMethod).HandlerFunc(f) - } else { - r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(f) - r.Path(localRoute).Methods(localMethod).HandlerFunc(f) - } - } - } - - return r, nil -} - -// ServeRequest processes a single http request to the docker remote api. -// FIXME: refactor this to be part of Server and not require re-creating a new -// router each time. This requires first moving ListenAndServe into Server. -func ServeRequest(eng *engine.Engine, apiversion version.Version, w http.ResponseWriter, req *http.Request) error { - router, err := createRouter(eng, false, true, "") - if err != nil { - return err - } - // Insert APIVERSION into the request as a convenience - req.URL.Path = fmt.Sprintf("/v%s%s", apiversion, req.URL.Path) - router.ServeHTTP(w, req) - return nil -} - -// serveFd creates an http.Server and sets it up to serve given a socket activated -// argument. -func serveFd(addr string, job *engine.Job) error { - r, err := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version")) - if err != nil { - return err - } - - ls, e := systemd.ListenFD(addr) - if e != nil { - return e - } - - chErrors := make(chan error, len(ls)) - - // We don't want to start serving on these sockets until the - // daemon is initialized and installed. Otherwise required handlers - // won't be ready. - <-activationLock - - // Since ListenFD will return one or more sockets we have - // to create a go func to spawn off multiple serves - for i := range ls { - listener := ls[i] - go func() { - httpSrv := http.Server{Handler: r} - chErrors <- httpSrv.Serve(listener) - }() - } - - for i := 0; i < len(ls); i++ { - err := <-chErrors - if err != nil { - return err - } - } - - return nil -} - -func lookupGidByName(nameOrGid string) (int, error) { - groupFile, err := user.GetGroupFile() - if err != nil { - return -1, err - } - groups, err := user.ParseGroupFileFilter(groupFile, func(g user.Group) bool { - return g.Name == nameOrGid || strconv.Itoa(g.Gid) == nameOrGid - }) - if err != nil { - return -1, err - } - if groups != nil && len(groups) > 0 { - return groups[0].Gid, nil - } - return -1, fmt.Errorf("Group %s not found", nameOrGid) -} - -func newListener(proto, addr string, bufferRequests bool) (net.Listener, error) { - if bufferRequests { - return listenbuffer.NewListenBuffer(proto, addr, activationLock) - } - - return net.Listen(proto, addr) -} - -func changeGroup(addr string, nameOrGid string) error { - gid, err := lookupGidByName(nameOrGid) - if err != nil { - return err - } - - log.Debugf("%s group found. gid: %d", nameOrGid, gid) - return os.Chown(addr, 0, gid) -} - -func setSocketGroup(addr, group string) error { - if group == "" { - return nil - } - - if err := changeGroup(addr, group); err != nil { - if group != "docker" { - return err - } - log.Debugf("Warning: could not chgrp %s to docker: %v", addr, err) - } - - return nil -} - -func setupUnixHttp(addr string, job *engine.Job) (*HttpServer, error) { - r, err := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version")) - if err != nil { - return nil, err - } - - if err := syscall.Unlink(addr); err != nil && !os.IsNotExist(err) { - return nil, err - } - mask := syscall.Umask(0777) - defer syscall.Umask(mask) - - l, err := newListener("unix", addr, job.GetenvBool("BufferRequests")) - if err != nil { - return nil, err - } - - if err := setSocketGroup(addr, job.Getenv("SocketGroup")); err != nil { - return nil, err - } - - if err := os.Chmod(addr, 0660); err != nil { - return nil, err - } - - return &HttpServer{&http.Server{Addr: addr, Handler: r}, l}, nil -} - -func setupTcpHttp(addr string, job *engine.Job) (*HttpServer, error) { - r, err := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version")) - if err != nil { - return nil, err - } - - l, err := newListener("tcp", addr, job.GetenvBool("BufferRequests")) - if err != nil { - return nil, err - } - - var tlsConfig *tls.Config - - switch job.Getenv("Auth") { - case "identity": - trustKey, err := api.LoadOrCreateTrustKey(job.Getenv("TrustKey")) - if err != nil { - return nil, err - } - manager, err := NewClientKeyManager(trustKey, job.Getenv("TrustClients"), job.Getenv("TrustDir")) - if err != nil { - return nil, err - } - if tlsConfig, err = NewIdentityAuthTLSConfig(trustKey, manager, addr); err != nil { - return nil, fmt.Errorf("Error creating TLS config: %s", err) - } - case "cert": - if tlsConfig, err = NewCertAuthTLSConfig(job.Getenv("AuthCa"), job.Getenv("AuthCert"), job.Getenv("AuthKey")); err != nil { - return nil, fmt.Errorf("Error creating TLS config: %s", err) - } - case "none": - tlsConfig = nil - default: - return nil, fmt.Errorf("Unknown auth method: %s", job.Getenv("Auth")) - } - - if tlsConfig == nil { - log.Infof("/!\\ DON'T BIND INSECURELY ON A TCP ADDRESS IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") - } else { - l = tls.NewListener(l, tlsConfig) - } - - return &HttpServer{&http.Server{Addr: addr, Handler: r}, l}, nil -} - -// NewServer sets up the required Server and does protocol specific checking. -func NewServer(proto, addr string, job *engine.Job) (Server, error) { - // Basic error and sanity checking - switch proto { - case "fd": - return nil, serveFd(addr, job) - case "tcp": - return setupTcpHttp(addr, job) - case "unix": - return setupUnixHttp(addr, job) - default: - return nil, fmt.Errorf("Invalid protocol format.") - } -} - -type Server interface { - Serve() error - Close() error -} - -// ServeApi loops through all of the protocols sent in to docker and spawns -// off a go routine to setup a serving http.Server for each. -func ServeApi(job *engine.Job) engine.Status { - if len(job.Args) == 0 { - return job.Errorf("usage: %s PROTO://ADDR [PROTO://ADDR ...]", job.Name) - } - var ( - protoAddrs = job.Args - chErrors = make(chan error, len(protoAddrs)) - ) - activationLock = make(chan struct{}) - - for _, protoAddr := range protoAddrs { - protoAddrParts := strings.SplitN(protoAddr, "://", 2) - if len(protoAddrParts) != 2 { - return job.Errorf("usage: %s PROTO://ADDR [PROTO://ADDR ...]", job.Name) - } - go func() { - log.Infof("Listening for HTTP on %s (%s)", protoAddrParts[0], protoAddrParts[1]) - srv, err := NewServer(protoAddrParts[0], protoAddrParts[1], job) - if err != nil { - chErrors <- err - return - } - chErrors <- srv.Serve() - }() - } - - for i := 0; i < len(protoAddrs); i++ { - err := <-chErrors - if err != nil { - return job.Error(err) - } - } - - return engine.StatusOK -} - -func AcceptConnections(job *engine.Job) engine.Status { - // Tell the init daemon we are accepting requests - go systemd.SdNotify("READY=1") - - // close the lock so the listeners start accepting connections - if activationLock != nil { - close(activationLock) - } - - return engine.StatusOK -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/api/server/server_unit_test.go b/Godeps/_workspace/src/github.com/docker/docker/api/server/server_unit_test.go deleted file mode 100644 index 519652f377..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/api/server/server_unit_test.go +++ /dev/null @@ -1,555 +0,0 @@ -package server - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "net/http/httptest" - "reflect" - "strings" - "testing" - - "github.com/docker/docker/api" - "github.com/docker/docker/engine" - "github.com/docker/docker/pkg/version" -) - -func TestGetBoolParam(t *testing.T) { - if ret, err := getBoolParam("true"); err != nil || !ret { - t.Fatalf("true -> true, nil | got %t %s", ret, err) - } - if ret, err := getBoolParam("True"); err != nil || !ret { - t.Fatalf("True -> true, nil | got %t %s", ret, err) - } - if ret, err := getBoolParam("1"); err != nil || !ret { - t.Fatalf("1 -> true, nil | got %t %s", ret, err) - } - if ret, err := getBoolParam(""); err != nil || ret { - t.Fatalf("\"\" -> false, nil | got %t %s", ret, err) - } - if ret, err := getBoolParam("false"); err != nil || ret { - t.Fatalf("false -> false, nil | got %t %s", ret, err) - } - if ret, err := getBoolParam("0"); err != nil || ret { - t.Fatalf("0 -> false, nil | got %t %s", ret, err) - } - if ret, err := getBoolParam("faux"); err == nil || ret { - t.Fatalf("faux -> false, err | got %t %s", ret, err) - - } -} - -func TesthttpError(t *testing.T) { - r := httptest.NewRecorder() - - httpError(r, fmt.Errorf("No such method")) - if r.Code != http.StatusNotFound { - t.Fatalf("Expected %d, got %d", http.StatusNotFound, r.Code) - } - - httpError(r, fmt.Errorf("This accound hasn't been activated")) - if r.Code != http.StatusForbidden { - t.Fatalf("Expected %d, got %d", http.StatusForbidden, r.Code) - } - - httpError(r, fmt.Errorf("Some error")) - if r.Code != http.StatusInternalServerError { - t.Fatalf("Expected %d, got %d", http.StatusInternalServerError, r.Code) - } -} - -func TestGetVersion(t *testing.T) { - eng := engine.New() - var called bool - eng.Register("version", func(job *engine.Job) engine.Status { - called = true - v := &engine.Env{} - v.SetJson("Version", "42.1") - v.Set("ApiVersion", "1.1.1.1.1") - v.Set("GoVersion", "2.42") - v.Set("Os", "Linux") - v.Set("Arch", "x86_64") - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/version", nil, eng, t) - if !called { - t.Fatalf("handler was not called") - } - v := readEnv(r.Body, t) - if v.Get("Version") != "42.1" { - t.Fatalf("%#v\n", v) - } - if r.HeaderMap.Get("Content-Type") != "application/json" { - t.Fatalf("%#v\n", r) - } -} - -func TestGetInfo(t *testing.T) { - eng := engine.New() - var called bool - eng.Register("info", func(job *engine.Job) engine.Status { - called = true - v := &engine.Env{} - v.SetInt("Containers", 1) - v.SetInt("Images", 42000) - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/info", nil, eng, t) - if !called { - t.Fatalf("handler was not called") - } - v := readEnv(r.Body, t) - if v.GetInt("Images") != 42000 { - t.Fatalf("%#v\n", v) - } - if v.GetInt("Containers") != 1 { - t.Fatalf("%#v\n", v) - } - assertContentType(r, "application/json", t) -} - -func TestGetImagesJSON(t *testing.T) { - eng := engine.New() - var called bool - eng.Register("images", func(job *engine.Job) engine.Status { - called = true - v := createEnvFromGetImagesJSONStruct(sampleImage) - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/images/json", nil, eng, t) - if !called { - t.Fatal("handler was not called") - } - assertHttpNotError(r, t) - assertContentType(r, "application/json", t) - var observed getImagesJSONStruct - if err := json.Unmarshal(r.Body.Bytes(), &observed); err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(observed, sampleImage) { - t.Errorf("Expected %#v but got %#v", sampleImage, observed) - } -} - -func TestGetImagesJSONFilter(t *testing.T) { - eng := engine.New() - filter := "nothing" - eng.Register("images", func(job *engine.Job) engine.Status { - filter = job.Getenv("filter") - return engine.StatusOK - }) - serveRequest("GET", "/images/json?filter=aaaa", nil, eng, t) - if filter != "aaaa" { - t.Errorf("%#v", filter) - } -} - -func TestGetImagesJSONFilters(t *testing.T) { - eng := engine.New() - filter := "nothing" - eng.Register("images", func(job *engine.Job) engine.Status { - filter = job.Getenv("filters") - return engine.StatusOK - }) - serveRequest("GET", "/images/json?filters=nnnn", nil, eng, t) - if filter != "nnnn" { - t.Errorf("%#v", filter) - } -} - -func TestGetImagesJSONAll(t *testing.T) { - eng := engine.New() - allFilter := "-1" - eng.Register("images", func(job *engine.Job) engine.Status { - allFilter = job.Getenv("all") - return engine.StatusOK - }) - serveRequest("GET", "/images/json?all=1", nil, eng, t) - if allFilter != "1" { - t.Errorf("%#v", allFilter) - } -} - -func TestGetImagesJSONLegacyFormat(t *testing.T) { - eng := engine.New() - var called bool - eng.Register("images", func(job *engine.Job) engine.Status { - called = true - outsLegacy := engine.NewTable("Created", 0) - outsLegacy.Add(createEnvFromGetImagesJSONStruct(sampleImage)) - if _, err := outsLegacy.WriteListTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequestUsingVersion("GET", "/images/json", "1.6", nil, eng, t) - if !called { - t.Fatal("handler was not called") - } - assertHttpNotError(r, t) - assertContentType(r, "application/json", t) - images := engine.NewTable("Created", 0) - if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil { - t.Fatal(err) - } - if images.Len() != 1 { - t.Fatalf("Expected 1 image, %d found", images.Len()) - } - image := images.Data[0] - if image.Get("Tag") != "test-tag" { - t.Errorf("Expected tag 'test-tag', found '%s'", image.Get("Tag")) - } - if image.Get("Repository") != "test-name" { - t.Errorf("Expected repository 'test-name', found '%s'", image.Get("Repository")) - } -} - -func TestGetContainersByName(t *testing.T) { - eng := engine.New() - name := "container_name" - var called bool - eng.Register("container_inspect", func(job *engine.Job) engine.Status { - called = true - if job.Args[0] != name { - t.Errorf("name != '%s': %#v", name, job.Args[0]) - } - if api.APIVERSION.LessThan("1.12") && !job.GetenvBool("dirty") { - t.Errorf("dirty env variable not set") - } else if api.APIVERSION.GreaterThanOrEqualTo("1.12") && job.GetenvBool("dirty") { - t.Errorf("dirty env variable set when it shouldn't") - } - v := &engine.Env{} - v.SetBool("dirty", true) - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/containers/"+name+"/json", nil, eng, t) - if !called { - t.Fatal("handler was not called") - } - assertContentType(r, "application/json", t) - var stdoutJson interface{} - if err := json.Unmarshal(r.Body.Bytes(), &stdoutJson); err != nil { - t.Fatalf("%#v", err) - } - if stdoutJson.(map[string]interface{})["dirty"].(float64) != 1 { - t.Fatalf("%#v", stdoutJson) - } -} - -func TestGetEvents(t *testing.T) { - eng := engine.New() - var called bool - eng.Register("events", func(job *engine.Job) engine.Status { - called = true - since := job.Getenv("since") - if since != "1" { - t.Fatalf("'since' should be 1, found %#v instead", since) - } - until := job.Getenv("until") - if until != "0" { - t.Fatalf("'until' should be 0, found %#v instead", until) - } - v := &engine.Env{} - v.Set("since", since) - v.Set("until", until) - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/events?since=1&until=0", nil, eng, t) - if !called { - t.Fatal("handler was not called") - } - assertContentType(r, "application/json", t) - var stdout_json struct { - Since int - Until int - } - if err := json.Unmarshal(r.Body.Bytes(), &stdout_json); err != nil { - t.Fatal(err) - } - if stdout_json.Since != 1 { - t.Errorf("since != 1: %#v", stdout_json.Since) - } - if stdout_json.Until != 0 { - t.Errorf("until != 0: %#v", stdout_json.Until) - } -} - -func TestLogs(t *testing.T) { - eng := engine.New() - var inspect bool - var logs bool - eng.Register("container_inspect", func(job *engine.Job) engine.Status { - inspect = true - if len(job.Args) == 0 { - t.Fatal("Job arguments is empty") - } - if job.Args[0] != "test" { - t.Fatalf("Container name %s, must be test", job.Args[0]) - } - return engine.StatusOK - }) - expected := "logs" - eng.Register("logs", func(job *engine.Job) engine.Status { - logs = true - if len(job.Args) == 0 { - t.Fatal("Job arguments is empty") - } - if job.Args[0] != "test" { - t.Fatalf("Container name %s, must be test", job.Args[0]) - } - follow := job.Getenv("follow") - if follow != "1" { - t.Fatalf("follow: %s, must be 1", follow) - } - stdout := job.Getenv("stdout") - if stdout != "1" { - t.Fatalf("stdout %s, must be 1", stdout) - } - stderr := job.Getenv("stderr") - if stderr != "" { - t.Fatalf("stderr %s, must be empty", stderr) - } - timestamps := job.Getenv("timestamps") - if timestamps != "1" { - t.Fatalf("timestamps %s, must be 1", timestamps) - } - job.Stdout.Write([]byte(expected)) - return engine.StatusOK - }) - r := serveRequest("GET", "/containers/test/logs?follow=1&stdout=1×tamps=1", nil, eng, t) - if r.Code != http.StatusOK { - t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK) - } - if !inspect { - t.Fatal("container_inspect job was not called") - } - if !logs { - t.Fatal("logs job was not called") - } - res := r.Body.String() - if res != expected { - t.Fatalf("Output %s, expected %s", res, expected) - } -} - -func TestLogsNoStreams(t *testing.T) { - eng := engine.New() - var inspect bool - var logs bool - eng.Register("container_inspect", func(job *engine.Job) engine.Status { - inspect = true - if len(job.Args) == 0 { - t.Fatal("Job arguments is empty") - } - if job.Args[0] != "test" { - t.Fatalf("Container name %s, must be test", job.Args[0]) - } - return engine.StatusOK - }) - eng.Register("logs", func(job *engine.Job) engine.Status { - logs = true - return engine.StatusOK - }) - r := serveRequest("GET", "/containers/test/logs", nil, eng, t) - if r.Code != http.StatusBadRequest { - t.Fatalf("Got status %d, expected %d", r.Code, http.StatusBadRequest) - } - if inspect { - t.Fatal("container_inspect job was called, but it shouldn't") - } - if logs { - t.Fatal("logs job was called, but it shouldn't") - } - res := strings.TrimSpace(r.Body.String()) - expected := "Bad parameters: you must choose at least one stream" - if !strings.Contains(res, expected) { - t.Fatalf("Output %s, expected %s in it", res, expected) - } -} - -func TestGetImagesHistory(t *testing.T) { - eng := engine.New() - imageName := "docker-test-image" - var called bool - eng.Register("history", func(job *engine.Job) engine.Status { - called = true - if len(job.Args) == 0 { - t.Fatal("Job arguments is empty") - } - if job.Args[0] != imageName { - t.Fatalf("name != '%s': %#v", imageName, job.Args[0]) - } - v := &engine.Env{} - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/images/"+imageName+"/history", nil, eng, t) - if !called { - t.Fatalf("handler was not called") - } - if r.Code != http.StatusOK { - t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK) - } - if r.HeaderMap.Get("Content-Type") != "application/json" { - t.Fatalf("%#v\n", r) - } -} - -func TestGetImagesByName(t *testing.T) { - eng := engine.New() - name := "image_name" - var called bool - eng.Register("image_inspect", func(job *engine.Job) engine.Status { - called = true - if job.Args[0] != name { - t.Fatalf("name != '%s': %#v", name, job.Args[0]) - } - if api.APIVERSION.LessThan("1.12") && !job.GetenvBool("dirty") { - t.Fatal("dirty env variable not set") - } else if api.APIVERSION.GreaterThanOrEqualTo("1.12") && job.GetenvBool("dirty") { - t.Fatal("dirty env variable set when it shouldn't") - } - v := &engine.Env{} - v.SetBool("dirty", true) - if _, err := v.WriteTo(job.Stdout); err != nil { - return job.Error(err) - } - return engine.StatusOK - }) - r := serveRequest("GET", "/images/"+name+"/json", nil, eng, t) - if !called { - t.Fatal("handler was not called") - } - if r.HeaderMap.Get("Content-Type") != "application/json" { - t.Fatalf("%#v\n", r) - } - var stdoutJson interface{} - if err := json.Unmarshal(r.Body.Bytes(), &stdoutJson); err != nil { - t.Fatalf("%#v", err) - } - if stdoutJson.(map[string]interface{})["dirty"].(float64) != 1 { - t.Fatalf("%#v", stdoutJson) - } -} - -func TestDeleteContainers(t *testing.T) { - eng := engine.New() - name := "foo" - var called bool - eng.Register("rm", func(job *engine.Job) engine.Status { - called = true - if len(job.Args) == 0 { - t.Fatalf("Job arguments is empty") - } - if job.Args[0] != name { - t.Fatalf("name != '%s': %#v", name, job.Args[0]) - } - return engine.StatusOK - }) - r := serveRequest("DELETE", "/containers/"+name, nil, eng, t) - if !called { - t.Fatalf("handler was not called") - } - if r.Code != http.StatusNoContent { - t.Fatalf("Got status %d, expected %d", r.Code, http.StatusNoContent) - } -} - -func serveRequest(method, target string, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder { - return serveRequestUsingVersion(method, target, api.APIVERSION, body, eng, t) -} - -func serveRequestUsingVersion(method, target string, version version.Version, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder { - r := httptest.NewRecorder() - req, err := http.NewRequest(method, target, body) - if err != nil { - t.Fatal(err) - } - if err := ServeRequest(eng, version, r, req); err != nil { - t.Fatal(err) - } - return r -} - -func readEnv(src io.Reader, t *testing.T) *engine.Env { - out := engine.NewOutput() - v, err := out.AddEnv() - if err != nil { - t.Fatal(err) - } - if _, err := io.Copy(out, src); err != nil { - t.Fatal(err) - } - out.Close() - return v -} - -func toJson(data interface{}, t *testing.T) io.Reader { - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(data); err != nil { - t.Fatal(err) - } - return &buf -} - -func assertContentType(recorder *httptest.ResponseRecorder, content_type string, t *testing.T) { - if recorder.HeaderMap.Get("Content-Type") != content_type { - t.Fatalf("%#v\n", recorder) - } -} - -// XXX: Duplicated from integration/utils_test.go, but maybe that's OK as that -// should die as soon as we converted all integration tests? -// assertHttpNotError expect the given response to not have an error. -// Otherwise the it causes the test to fail. -func assertHttpNotError(r *httptest.ResponseRecorder, t *testing.T) { - // Non-error http status are [200, 400) - if r.Code < http.StatusOK || r.Code >= http.StatusBadRequest { - t.Fatal(fmt.Errorf("Unexpected http error: %v", r.Code)) - } -} - -func createEnvFromGetImagesJSONStruct(data getImagesJSONStruct) *engine.Env { - v := &engine.Env{} - v.SetList("RepoTags", data.RepoTags) - v.Set("Id", data.Id) - v.SetInt64("Created", data.Created) - v.SetInt64("Size", data.Size) - v.SetInt64("VirtualSize", data.VirtualSize) - return v -} - -type getImagesJSONStruct struct { - RepoTags []string - Id string - Created int64 - Size int64 - VirtualSize int64 -} - -var sampleImage getImagesJSONStruct = getImagesJSONStruct{ - RepoTags: []string{"test-name:test-tag"}, - Id: "ID", - Created: 999, - Size: 777, - VirtualSize: 666, -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/dockerversion/dockerversion.go b/Godeps/_workspace/src/github.com/docker/docker/dockerversion/dockerversion.go deleted file mode 100644 index c130ac2810..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/dockerversion/dockerversion.go +++ /dev/null @@ -1,15 +0,0 @@ -package dockerversion - -// FIXME: this should be embedded in the docker/docker.go, -// but we can't because distro policy requires us to -// package a separate dockerinit binary, and that binary needs -// to know its version too. - -var ( - GITCOMMIT string - VERSION string - - IAMSTATIC bool // whether or not Docker itself was compiled statically via ./hack/make.sh binary - INITSHA1 string // sha1sum of separate static dockerinit, if Docker itself was compiled dynamically via ./hack/make.sh dynbinary - INITPATH string // custom location to search for a valid dockerinit binary (available for packagers as a last resort escape hatch) -) diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/engine/MAINTAINERS deleted file mode 100644 index aee10c8421..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/MAINTAINERS +++ /dev/null @@ -1 +0,0 @@ -Solomon Hykes (@shykes) diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/engine.go b/Godeps/_workspace/src/github.com/docker/docker/engine/engine.go deleted file mode 100644 index 769f644a17..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/engine.go +++ /dev/null @@ -1,261 +0,0 @@ -package engine - -import ( - "bufio" - "fmt" - "io" - "os" - "sort" - "strings" - "sync" - "time" - - "github.com/docker/docker/pkg/ioutils" - "github.com/docker/docker/pkg/timeutils" - "github.com/docker/docker/utils" -) - -// Installer is a standard interface for objects which can "install" themselves -// on an engine by registering handlers. -// This can be used as an entrypoint for external plugins etc. -type Installer interface { - Install(*Engine) error -} - -type Handler func(*Job) Status - -var globalHandlers map[string]Handler - -func init() { - globalHandlers = make(map[string]Handler) -} - -func Register(name string, handler Handler) error { - _, exists := globalHandlers[name] - if exists { - return fmt.Errorf("Can't overwrite global handler for command %s", name) - } - globalHandlers[name] = handler - return nil -} - -func unregister(name string) { - delete(globalHandlers, name) -} - -// The Engine is the core of Docker. -// It acts as a store for *containers*, and allows manipulation of these -// containers by executing *jobs*. -type Engine struct { - handlers map[string]Handler - catchall Handler - hack Hack // data for temporary hackery (see hack.go) - id string - Stdout io.Writer - Stderr io.Writer - Stdin io.Reader - Logging bool - tasks sync.WaitGroup - l sync.RWMutex // lock for shutdown - shutdown bool - onShutdown []func() // shutdown handlers -} - -func (eng *Engine) Register(name string, handler Handler) error { - _, exists := eng.handlers[name] - if exists { - return fmt.Errorf("Can't overwrite handler for command %s", name) - } - eng.handlers[name] = handler - return nil -} - -func (eng *Engine) RegisterCatchall(catchall Handler) { - eng.catchall = catchall -} - -// New initializes a new engine. -func New() *Engine { - eng := &Engine{ - handlers: make(map[string]Handler), - id: utils.RandomString(), - Stdout: os.Stdout, - Stderr: os.Stderr, - Stdin: os.Stdin, - Logging: true, - } - eng.Register("commands", func(job *Job) Status { - for _, name := range eng.commands() { - job.Printf("%s\n", name) - } - return StatusOK - }) - // Copy existing global handlers - for k, v := range globalHandlers { - eng.handlers[k] = v - } - return eng -} - -func (eng *Engine) String() string { - return fmt.Sprintf("%s", eng.id[:8]) -} - -// Commands returns a list of all currently registered commands, -// sorted alphabetically. -func (eng *Engine) commands() []string { - names := make([]string, 0, len(eng.handlers)) - for name := range eng.handlers { - names = append(names, name) - } - sort.Strings(names) - return names -} - -// Job creates a new job which can later be executed. -// This function mimics `Command` from the standard os/exec package. -func (eng *Engine) Job(name string, args ...string) *Job { - job := &Job{ - Eng: eng, - Name: name, - Args: args, - Stdin: NewInput(), - Stdout: NewOutput(), - Stderr: NewOutput(), - env: &Env{}, - closeIO: true, - } - if eng.Logging { - job.Stderr.Add(ioutils.NopWriteCloser(eng.Stderr)) - } - - // Catchall is shadowed by specific Register. - if handler, exists := eng.handlers[name]; exists { - job.handler = handler - } else if eng.catchall != nil && name != "" { - // empty job names are illegal, catchall or not. - job.handler = eng.catchall - } - return job -} - -// OnShutdown registers a new callback to be called by Shutdown. -// This is typically used by services to perform cleanup. -func (eng *Engine) OnShutdown(h func()) { - eng.l.Lock() - eng.onShutdown = append(eng.onShutdown, h) - eng.l.Unlock() -} - -// Shutdown permanently shuts down eng as follows: -// - It refuses all new jobs, permanently. -// - It waits for all active jobs to complete (with no timeout) -// - It calls all shutdown handlers concurrently (if any) -// - It returns when all handlers complete, or after 15 seconds, -// whichever happens first. -func (eng *Engine) Shutdown() { - eng.l.Lock() - if eng.shutdown { - eng.l.Unlock() - return - } - eng.shutdown = true - eng.l.Unlock() - // We don't need to protect the rest with a lock, to allow - // for other calls to immediately fail with "shutdown" instead - // of hanging for 15 seconds. - // This requires all concurrent calls to check for shutdown, otherwise - // it might cause a race. - - // Wait for all jobs to complete. - // Timeout after 5 seconds. - tasksDone := make(chan struct{}) - go func() { - eng.tasks.Wait() - close(tasksDone) - }() - select { - case <-time.After(time.Second * 5): - case <-tasksDone: - } - - // Call shutdown handlers, if any. - // Timeout after 10 seconds. - var wg sync.WaitGroup - for _, h := range eng.onShutdown { - wg.Add(1) - go func(h func()) { - defer wg.Done() - h() - }(h) - } - done := make(chan struct{}) - go func() { - wg.Wait() - close(done) - }() - select { - case <-time.After(time.Second * 10): - case <-done: - } - return -} - -// IsShutdown returns true if the engine is in the process -// of shutting down, or already shut down. -// Otherwise it returns false. -func (eng *Engine) IsShutdown() bool { - eng.l.RLock() - defer eng.l.RUnlock() - return eng.shutdown -} - -// ParseJob creates a new job from a text description using a shell-like syntax. -// -// The following syntax is used to parse `input`: -// -// * Words are separated using standard whitespaces as separators. -// * Quotes and backslashes are not interpreted. -// * Words of the form 'KEY=[VALUE]' are added to the job environment. -// * All other words are added to the job arguments. -// -// For example: -// -// job, _ := eng.ParseJob("VERBOSE=1 echo hello TEST=true world") -// -// The resulting job will have: -// job.Args={"echo", "hello", "world"} -// job.Env={"VERBOSE":"1", "TEST":"true"} -// -func (eng *Engine) ParseJob(input string) (*Job, error) { - // FIXME: use a full-featured command parser - scanner := bufio.NewScanner(strings.NewReader(input)) - scanner.Split(bufio.ScanWords) - var ( - cmd []string - env Env - ) - for scanner.Scan() { - word := scanner.Text() - kv := strings.SplitN(word, "=", 2) - if len(kv) == 2 { - env.Set(kv[0], kv[1]) - } else { - cmd = append(cmd, word) - } - } - if len(cmd) == 0 { - return nil, fmt.Errorf("empty command: '%s'", input) - } - job := eng.Job(cmd[0], cmd[1:]...) - job.Env().Init(&env) - return job, nil -} - -func (eng *Engine) Logf(format string, args ...interface{}) (n int, err error) { - if !eng.Logging { - return 0, nil - } - prefixedFormat := fmt.Sprintf("[%s] [%s] %s\n", time.Now().Format(timeutils.RFC3339NanoFixed), eng, strings.TrimRight(format, "\n")) - return fmt.Fprintf(eng.Stderr, prefixedFormat, args...) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/engine_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/engine_test.go deleted file mode 100644 index 92f3757251..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/engine_test.go +++ /dev/null @@ -1,162 +0,0 @@ -package engine - -import ( - "bytes" - "strings" - "testing" -) - -func TestRegister(t *testing.T) { - if err := Register("dummy1", nil); err != nil { - t.Fatal(err) - } - - if err := Register("dummy1", nil); err == nil { - t.Fatalf("Expecting error, got none") - } - // Register is global so let's cleanup to avoid conflicts - defer unregister("dummy1") - - eng := New() - - //Should fail because global handlers are copied - //at the engine creation - if err := eng.Register("dummy1", nil); err == nil { - t.Fatalf("Expecting error, got none") - } - - if err := eng.Register("dummy2", nil); err != nil { - t.Fatal(err) - } - - if err := eng.Register("dummy2", nil); err == nil { - t.Fatalf("Expecting error, got none") - } - defer unregister("dummy2") -} - -func TestJob(t *testing.T) { - eng := New() - job1 := eng.Job("dummy1", "--level=awesome") - - if job1.handler != nil { - t.Fatalf("job1.handler should be empty") - } - - h := func(j *Job) Status { - j.Printf("%s\n", j.Name) - return 42 - } - - eng.Register("dummy2", h) - defer unregister("dummy2") - job2 := eng.Job("dummy2", "--level=awesome") - - if job2.handler == nil { - t.Fatalf("job2.handler shouldn't be nil") - } - - if job2.handler(job2) != 42 { - t.Fatalf("handler dummy2 was not found in job2") - } -} - -func TestEngineShutdown(t *testing.T) { - eng := New() - if eng.IsShutdown() { - t.Fatalf("Engine should not show as shutdown") - } - eng.Shutdown() - if !eng.IsShutdown() { - t.Fatalf("Engine should show as shutdown") - } -} - -func TestEngineCommands(t *testing.T) { - eng := New() - handler := func(job *Job) Status { return StatusOK } - eng.Register("foo", handler) - eng.Register("bar", handler) - eng.Register("echo", handler) - eng.Register("die", handler) - var output bytes.Buffer - commands := eng.Job("commands") - commands.Stdout.Add(&output) - commands.Run() - expected := "bar\ncommands\ndie\necho\nfoo\n" - if result := output.String(); result != expected { - t.Fatalf("Unexpected output:\nExpected = %v\nResult = %v\n", expected, result) - } -} - -func TestEngineString(t *testing.T) { - eng1 := New() - eng2 := New() - s1 := eng1.String() - s2 := eng2.String() - if eng1 == eng2 { - t.Fatalf("Different engines should have different names (%v == %v)", s1, s2) - } -} - -func TestEngineLogf(t *testing.T) { - eng := New() - input := "Test log line" - if n, err := eng.Logf("%s\n", input); err != nil { - t.Fatal(err) - } else if n < len(input) { - t.Fatalf("Test: Logf() should print at least as much as the input\ninput=%d\nprinted=%d", len(input), n) - } -} - -func TestParseJob(t *testing.T) { - eng := New() - // Verify that the resulting job calls to the right place - var called bool - eng.Register("echo", func(job *Job) Status { - called = true - return StatusOK - }) - input := "echo DEBUG=1 hello world VERBOSITY=42" - job, err := eng.ParseJob(input) - if err != nil { - t.Fatal(err) - } - if job.Name != "echo" { - t.Fatalf("Invalid job name: %v", job.Name) - } - if strings.Join(job.Args, ":::") != "hello:::world" { - t.Fatalf("Invalid job args: %v", job.Args) - } - if job.Env().Get("DEBUG") != "1" { - t.Fatalf("Invalid job env: %v", job.Env) - } - if job.Env().Get("VERBOSITY") != "42" { - t.Fatalf("Invalid job env: %v", job.Env) - } - if len(job.Env().Map()) != 2 { - t.Fatalf("Invalid job env: %v", job.Env) - } - if err := job.Run(); err != nil { - t.Fatal(err) - } - if !called { - t.Fatalf("Job was not called") - } -} - -func TestCatchallEmptyName(t *testing.T) { - eng := New() - var called bool - eng.RegisterCatchall(func(job *Job) Status { - called = true - return StatusOK - }) - err := eng.Job("").Run() - if err == nil { - t.Fatalf("Engine.Job(\"\").Run() should return an error") - } - if called { - t.Fatalf("Engine.Job(\"\").Run() should return an error") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/env.go b/Godeps/_workspace/src/github.com/docker/docker/engine/env.go deleted file mode 100644 index a16dc35cd9..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/env.go +++ /dev/null @@ -1,297 +0,0 @@ -package engine - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "strconv" - "strings" -) - -type Env []string - -// Get returns the last value associated with the given key. If there are no -// values associated with the key, Get returns the empty string. -func (env *Env) Get(key string) (value string) { - // not using Map() because of the extra allocations https://github.com/docker/docker/pull/7488#issuecomment-51638315 - for _, kv := range *env { - if strings.Index(kv, "=") == -1 { - continue - } - parts := strings.SplitN(kv, "=", 2) - if parts[0] != key { - continue - } - if len(parts) < 2 { - value = "" - } else { - value = parts[1] - } - } - return -} - -func (env *Env) Exists(key string) bool { - _, exists := env.Map()[key] - return exists -} - -// Len returns the number of keys in the environment. -// Note that len(env) might be different from env.Len(), -// because the same key might be set multiple times. -func (env *Env) Len() int { - return len(env.Map()) -} - -func (env *Env) Init(src *Env) { - (*env) = make([]string, 0, len(*src)) - for _, val := range *src { - (*env) = append((*env), val) - } -} - -func (env *Env) GetBool(key string) (value bool) { - s := strings.ToLower(strings.Trim(env.Get(key), " \t")) - if s == "" || s == "0" || s == "no" || s == "false" || s == "none" { - return false - } - return true -} - -func (env *Env) SetBool(key string, value bool) { - if value { - env.Set(key, "1") - } else { - env.Set(key, "0") - } -} - -func (env *Env) GetInt(key string) int { - return int(env.GetInt64(key)) -} - -func (env *Env) GetInt64(key string) int64 { - s := strings.Trim(env.Get(key), " \t") - val, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return 0 - } - return val -} - -func (env *Env) SetInt(key string, value int) { - env.Set(key, fmt.Sprintf("%d", value)) -} - -func (env *Env) SetInt64(key string, value int64) { - env.Set(key, fmt.Sprintf("%d", value)) -} - -// Returns nil if key not found -func (env *Env) GetList(key string) []string { - sval := env.Get(key) - if sval == "" { - return nil - } - l := make([]string, 0, 1) - if err := json.Unmarshal([]byte(sval), &l); err != nil { - l = append(l, sval) - } - return l -} - -func (env *Env) GetSubEnv(key string) *Env { - sval := env.Get(key) - if sval == "" { - return nil - } - buf := bytes.NewBufferString(sval) - var sub Env - if err := sub.Decode(buf); err != nil { - return nil - } - return &sub -} - -func (env *Env) SetSubEnv(key string, sub *Env) error { - var buf bytes.Buffer - if err := sub.Encode(&buf); err != nil { - return err - } - env.Set(key, string(buf.Bytes())) - return nil -} - -func (env *Env) GetJson(key string, iface interface{}) error { - sval := env.Get(key) - if sval == "" { - return nil - } - return json.Unmarshal([]byte(sval), iface) -} - -func (env *Env) SetJson(key string, value interface{}) error { - sval, err := json.Marshal(value) - if err != nil { - return err - } - env.Set(key, string(sval)) - return nil -} - -func (env *Env) SetList(key string, value []string) error { - return env.SetJson(key, value) -} - -func (env *Env) Set(key, value string) { - *env = append(*env, key+"="+value) -} - -func NewDecoder(src io.Reader) *Decoder { - return &Decoder{ - json.NewDecoder(src), - } -} - -type Decoder struct { - *json.Decoder -} - -func (decoder *Decoder) Decode() (*Env, error) { - m := make(map[string]interface{}) - if err := decoder.Decoder.Decode(&m); err != nil { - return nil, err - } - env := &Env{} - for key, value := range m { - env.SetAuto(key, value) - } - return env, nil -} - -// DecodeEnv decodes `src` as a json dictionary, and adds -// each decoded key-value pair to the environment. -// -// If `src` cannot be decoded as a json dictionary, an error -// is returned. -func (env *Env) Decode(src io.Reader) error { - m := make(map[string]interface{}) - if err := json.NewDecoder(src).Decode(&m); err != nil { - return err - } - for k, v := range m { - env.SetAuto(k, v) - } - return nil -} - -func (env *Env) SetAuto(k string, v interface{}) { - // Issue 7941 - if the value in the incoming JSON is null then treat it - // as if they never specified the property at all. - if v == nil { - return - } - - // FIXME: we fix-convert float values to int, because - // encoding/json decodes integers to float64, but cannot encode them back. - // (See http://golang.org/src/pkg/encoding/json/decode.go#L46) - if fval, ok := v.(float64); ok { - env.SetInt64(k, int64(fval)) - } else if sval, ok := v.(string); ok { - env.Set(k, sval) - } else if val, err := json.Marshal(v); err == nil { - env.Set(k, string(val)) - } else { - env.Set(k, fmt.Sprintf("%v", v)) - } -} - -func changeFloats(v interface{}) interface{} { - switch v := v.(type) { - case float64: - return int(v) - case map[string]interface{}: - for key, val := range v { - v[key] = changeFloats(val) - } - case []interface{}: - for idx, val := range v { - v[idx] = changeFloats(val) - } - } - return v -} - -func (env *Env) Encode(dst io.Writer) error { - m := make(map[string]interface{}) - for k, v := range env.Map() { - var val interface{} - if err := json.Unmarshal([]byte(v), &val); err == nil { - // FIXME: we fix-convert float values to int, because - // encoding/json decodes integers to float64, but cannot encode them back. - // (See http://golang.org/src/pkg/encoding/json/decode.go#L46) - m[k] = changeFloats(val) - } else { - m[k] = v - } - } - if err := json.NewEncoder(dst).Encode(&m); err != nil { - return err - } - return nil -} - -func (env *Env) WriteTo(dst io.Writer) (n int64, err error) { - // FIXME: return the number of bytes written to respect io.WriterTo - return 0, env.Encode(dst) -} - -func (env *Env) Import(src interface{}) (err error) { - defer func() { - if err != nil { - err = fmt.Errorf("ImportEnv: %s", err) - } - }() - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(src); err != nil { - return err - } - if err := env.Decode(&buf); err != nil { - return err - } - return nil -} - -func (env *Env) Map() map[string]string { - m := make(map[string]string) - for _, kv := range *env { - parts := strings.SplitN(kv, "=", 2) - m[parts[0]] = parts[1] - } - return m -} - -// MultiMap returns a representation of env as a -// map of string arrays, keyed by string. -// This is the same structure as http headers for example, -// which allow each key to have multiple values. -func (env *Env) MultiMap() map[string][]string { - m := make(map[string][]string) - for _, kv := range *env { - parts := strings.SplitN(kv, "=", 2) - m[parts[0]] = append(m[parts[0]], parts[1]) - } - return m -} - -// InitMultiMap removes all values in env, then initializes -// new values from the contents of m. -func (env *Env) InitMultiMap(m map[string][]string) { - (*env) = make([]string, 0, len(m)) - for k, vals := range m { - for _, v := range vals { - env.Set(k, v) - } - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/env_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/env_test.go deleted file mode 100644 index b0caca9cbd..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/env_test.go +++ /dev/null @@ -1,324 +0,0 @@ -package engine - -import ( - "bytes" - "encoding/json" - "testing" - - "github.com/docker/docker/pkg/testutils" -) - -func TestEnvLenZero(t *testing.T) { - env := &Env{} - if env.Len() != 0 { - t.Fatalf("%d", env.Len()) - } -} - -func TestEnvLenNotZero(t *testing.T) { - env := &Env{} - env.Set("foo", "bar") - env.Set("ga", "bu") - if env.Len() != 2 { - t.Fatalf("%d", env.Len()) - } -} - -func TestEnvLenDup(t *testing.T) { - env := &Env{ - "foo=bar", - "foo=baz", - "a=b", - } - // len(env) != env.Len() - if env.Len() != 2 { - t.Fatalf("%d", env.Len()) - } -} - -func TestEnvGetDup(t *testing.T) { - env := &Env{ - "foo=bar", - "foo=baz", - "foo=bif", - } - expected := "bif" - if v := env.Get("foo"); v != expected { - t.Fatalf("expect %q, got %q", expected, v) - } -} - -func TestNewJob(t *testing.T) { - job := mkJob(t, "dummy", "--level=awesome") - if job.Name != "dummy" { - t.Fatalf("Wrong job name: %s", job.Name) - } - if len(job.Args) != 1 { - t.Fatalf("Wrong number of job arguments: %d", len(job.Args)) - } - if job.Args[0] != "--level=awesome" { - t.Fatalf("Wrong job arguments: %s", job.Args[0]) - } -} - -func TestSetenv(t *testing.T) { - job := mkJob(t, "dummy") - job.Setenv("foo", "bar") - if val := job.Getenv("foo"); val != "bar" { - t.Fatalf("Getenv returns incorrect value: %s", val) - } - - job.Setenv("bar", "") - if val := job.Getenv("bar"); val != "" { - t.Fatalf("Getenv returns incorrect value: %s", val) - } - if val := job.Getenv("nonexistent"); val != "" { - t.Fatalf("Getenv returns incorrect value: %s", val) - } -} - -func TestSetenvBool(t *testing.T) { - job := mkJob(t, "dummy") - job.SetenvBool("foo", true) - if val := job.GetenvBool("foo"); !val { - t.Fatalf("GetenvBool returns incorrect value: %t", val) - } - - job.SetenvBool("bar", false) - if val := job.GetenvBool("bar"); val { - t.Fatalf("GetenvBool returns incorrect value: %t", val) - } - - if val := job.GetenvBool("nonexistent"); val { - t.Fatalf("GetenvBool returns incorrect value: %t", val) - } -} - -func TestSetenvInt(t *testing.T) { - job := mkJob(t, "dummy") - - job.SetenvInt("foo", -42) - if val := job.GetenvInt("foo"); val != -42 { - t.Fatalf("GetenvInt returns incorrect value: %d", val) - } - - job.SetenvInt("bar", 42) - if val := job.GetenvInt("bar"); val != 42 { - t.Fatalf("GetenvInt returns incorrect value: %d", val) - } - if val := job.GetenvInt("nonexistent"); val != 0 { - t.Fatalf("GetenvInt returns incorrect value: %d", val) - } -} - -func TestSetenvList(t *testing.T) { - job := mkJob(t, "dummy") - - job.SetenvList("foo", []string{"bar"}) - if val := job.GetenvList("foo"); len(val) != 1 || val[0] != "bar" { - t.Fatalf("GetenvList returns incorrect value: %v", val) - } - - job.SetenvList("bar", nil) - if val := job.GetenvList("bar"); val != nil { - t.Fatalf("GetenvList returns incorrect value: %v", val) - } - if val := job.GetenvList("nonexistent"); val != nil { - t.Fatalf("GetenvList returns incorrect value: %v", val) - } -} - -func TestEnviron(t *testing.T) { - job := mkJob(t, "dummy") - job.Setenv("foo", "bar") - val, exists := job.Environ()["foo"] - if !exists { - t.Fatalf("foo not found in the environ") - } - if val != "bar" { - t.Fatalf("bar not found in the environ") - } -} - -func TestMultiMap(t *testing.T) { - e := &Env{} - e.Set("foo", "bar") - e.Set("bar", "baz") - e.Set("hello", "world") - m := e.MultiMap() - e2 := &Env{} - e2.Set("old_key", "something something something") - e2.InitMultiMap(m) - if v := e2.Get("old_key"); v != "" { - t.Fatalf("%#v", v) - } - if v := e2.Get("bar"); v != "baz" { - t.Fatalf("%#v", v) - } - if v := e2.Get("hello"); v != "world" { - t.Fatalf("%#v", v) - } -} - -func testMap(l int) [][2]string { - res := make([][2]string, l) - for i := 0; i < l; i++ { - t := [2]string{testutils.RandomString(5), testutils.RandomString(20)} - res[i] = t - } - return res -} - -func BenchmarkSet(b *testing.B) { - fix := testMap(100) - b.ResetTimer() - for i := 0; i < b.N; i++ { - env := &Env{} - for _, kv := range fix { - env.Set(kv[0], kv[1]) - } - } -} - -func BenchmarkSetJson(b *testing.B) { - fix := testMap(100) - type X struct { - f string - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - env := &Env{} - for _, kv := range fix { - if err := env.SetJson(kv[0], X{kv[1]}); err != nil { - b.Fatal(err) - } - } - } -} - -func BenchmarkGet(b *testing.B) { - fix := testMap(100) - env := &Env{} - for _, kv := range fix { - env.Set(kv[0], kv[1]) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - for _, kv := range fix { - env.Get(kv[0]) - } - } -} - -func BenchmarkGetJson(b *testing.B) { - fix := testMap(100) - env := &Env{} - type X struct { - f string - } - for _, kv := range fix { - env.SetJson(kv[0], X{kv[1]}) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - for _, kv := range fix { - if err := env.GetJson(kv[0], &X{}); err != nil { - b.Fatal(err) - } - } - } -} - -func BenchmarkEncode(b *testing.B) { - fix := testMap(100) - env := &Env{} - type X struct { - f string - } - // half a json - for i, kv := range fix { - if i%2 != 0 { - if err := env.SetJson(kv[0], X{kv[1]}); err != nil { - b.Fatal(err) - } - continue - } - env.Set(kv[0], kv[1]) - } - var writer bytes.Buffer - b.ResetTimer() - for i := 0; i < b.N; i++ { - env.Encode(&writer) - writer.Reset() - } -} - -func BenchmarkDecode(b *testing.B) { - fix := testMap(100) - env := &Env{} - type X struct { - f string - } - // half a json - for i, kv := range fix { - if i%2 != 0 { - if err := env.SetJson(kv[0], X{kv[1]}); err != nil { - b.Fatal(err) - } - continue - } - env.Set(kv[0], kv[1]) - } - var writer bytes.Buffer - env.Encode(&writer) - denv := &Env{} - reader := bytes.NewReader(writer.Bytes()) - b.ResetTimer() - for i := 0; i < b.N; i++ { - err := denv.Decode(reader) - if err != nil { - b.Fatal(err) - } - reader.Seek(0, 0) - } -} - -func TestLongNumbers(t *testing.T) { - type T struct { - TestNum int64 - } - v := T{67108864} - var buf bytes.Buffer - e := &Env{} - e.SetJson("Test", v) - if err := e.Encode(&buf); err != nil { - t.Fatal(err) - } - res := make(map[string]T) - if err := json.Unmarshal(buf.Bytes(), &res); err != nil { - t.Fatal(err) - } - if res["Test"].TestNum != v.TestNum { - t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum) - } -} - -func TestLongNumbersArray(t *testing.T) { - type T struct { - TestNum []int64 - } - v := T{[]int64{67108864}} - var buf bytes.Buffer - e := &Env{} - e.SetJson("Test", v) - if err := e.Encode(&buf); err != nil { - t.Fatal(err) - } - res := make(map[string]T) - if err := json.Unmarshal(buf.Bytes(), &res); err != nil { - t.Fatal(err) - } - if res["Test"].TestNum[0] != v.TestNum[0] { - t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/hack.go b/Godeps/_workspace/src/github.com/docker/docker/engine/hack.go deleted file mode 100644 index be4fadbe6e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/hack.go +++ /dev/null @@ -1,21 +0,0 @@ -package engine - -type Hack map[string]interface{} - -func (eng *Engine) Hack_GetGlobalVar(key string) interface{} { - if eng.hack == nil { - return nil - } - val, exists := eng.hack[key] - if !exists { - return nil - } - return val -} - -func (eng *Engine) Hack_SetGlobalVar(key string, val interface{}) { - if eng.hack == nil { - eng.hack = make(Hack) - } - eng.hack[key] = val -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/helpers_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/helpers_test.go deleted file mode 100644 index cfa11da7cd..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/helpers_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package engine - -import ( - "testing" -) - -var globalTestID string - -func mkJob(t *testing.T, name string, args ...string) *Job { - return New().Job(name, args...) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/http.go b/Godeps/_workspace/src/github.com/docker/docker/engine/http.go deleted file mode 100644 index 7e4dcd7bb4..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/http.go +++ /dev/null @@ -1,42 +0,0 @@ -package engine - -import ( - "net/http" - "path" -) - -// ServeHTTP executes a job as specified by the http request `r`, and sends the -// result as an http response. -// This method allows an Engine instance to be passed as a standard http.Handler interface. -// -// Note that the protocol used in this method is a convenience wrapper and is not the canonical -// implementation of remote job execution. This is because HTTP/1 does not handle stream multiplexing, -// and so cannot differentiate stdout from stderr. Additionally, headers cannot be added to a response -// once data has been written to the body, which makes it inconvenient to return metadata such -// as the exit status. -// -func (eng *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) { - var ( - jobName = path.Base(r.URL.Path) - jobArgs, exists = r.URL.Query()["a"] - ) - if !exists { - jobArgs = []string{} - } - w.Header().Set("Job-Name", jobName) - for _, arg := range jobArgs { - w.Header().Add("Job-Args", arg) - } - job := eng.Job(jobName, jobArgs...) - job.Stdout.Add(w) - job.Stderr.Add(w) - // FIXME: distinguish job status from engine error in Run() - // The former should be passed as a special header, the former - // should cause a 500 status - w.WriteHeader(http.StatusOK) - // The exit status cannot be sent reliably with HTTP1, because headers - // can only be sent before the body. - // (we could possibly use http footers via chunked encoding, but I couldn't find - // how to use them in net/http) - job.Run() -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/job.go b/Godeps/_workspace/src/github.com/docker/docker/engine/job.go deleted file mode 100644 index 6c11b13446..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/job.go +++ /dev/null @@ -1,242 +0,0 @@ -package engine - -import ( - "bytes" - "fmt" - "io" - "strings" - "time" - - log "github.com/Sirupsen/logrus" -) - -// A job is the fundamental unit of work in the docker engine. -// Everything docker can do should eventually be exposed as a job. -// For example: execute a process in a container, create a new container, -// download an archive from the internet, serve the http api, etc. -// -// The job API is designed after unix processes: a job has a name, arguments, -// environment variables, standard streams for input, output and error, and -// an exit status which can indicate success (0) or error (anything else). -// -// For status, 0 indicates success, and any other integers indicates an error. -// This allows for richer error reporting. -// -type Job struct { - Eng *Engine - Name string - Args []string - env *Env - Stdout *Output - Stderr *Output - Stdin *Input - handler Handler - status Status - end time.Time - closeIO bool -} - -type Status int - -const ( - StatusOK Status = 0 - StatusErr Status = 1 - StatusNotFound Status = 127 -) - -// Run executes the job and blocks until the job completes. -// If the job returns a failure status, an error is returned -// which includes the status. -func (job *Job) Run() error { - if job.Eng.IsShutdown() && !job.GetenvBool("overrideShutdown") { - return fmt.Errorf("engine is shutdown") - } - // FIXME: this is a temporary workaround to avoid Engine.Shutdown - // waiting 5 seconds for server/api.ServeApi to complete (which it never will) - // everytime the daemon is cleanly restarted. - // The permanent fix is to implement Job.Stop and Job.OnStop so that - // ServeApi can cooperate and terminate cleanly. - if job.Name != "serveapi" { - job.Eng.l.Lock() - job.Eng.tasks.Add(1) - job.Eng.l.Unlock() - defer job.Eng.tasks.Done() - } - // FIXME: make this thread-safe - // FIXME: implement wait - if !job.end.IsZero() { - return fmt.Errorf("%s: job has already completed", job.Name) - } - // Log beginning and end of the job - if job.Eng.Logging { - log.Infof("+job %s", job.CallString()) - defer func() { - log.Infof("-job %s%s", job.CallString(), job.StatusString()) - }() - } - var errorMessage = bytes.NewBuffer(nil) - job.Stderr.Add(errorMessage) - if job.handler == nil { - job.Errorf("%s: command not found", job.Name) - job.status = 127 - } else { - job.status = job.handler(job) - job.end = time.Now() - } - if job.closeIO { - // Wait for all background tasks to complete - if err := job.Stdout.Close(); err != nil { - return err - } - if err := job.Stderr.Close(); err != nil { - return err - } - if err := job.Stdin.Close(); err != nil { - return err - } - } - if job.status != 0 { - return fmt.Errorf("%s", Tail(errorMessage, 1)) - } - - return nil -} - -func (job *Job) CallString() string { - return fmt.Sprintf("%s(%s)", job.Name, strings.Join(job.Args, ", ")) -} - -func (job *Job) StatusString() string { - // If the job hasn't completed, status string is empty - if job.end.IsZero() { - return "" - } - var okerr string - if job.status == StatusOK { - okerr = "OK" - } else { - okerr = "ERR" - } - return fmt.Sprintf(" = %s (%d)", okerr, job.status) -} - -// String returns a human-readable description of `job` -func (job *Job) String() string { - return fmt.Sprintf("%s.%s%s", job.Eng, job.CallString(), job.StatusString()) -} - -func (job *Job) Env() *Env { - return job.env -} - -func (job *Job) EnvExists(key string) (value bool) { - return job.env.Exists(key) -} - -func (job *Job) Getenv(key string) (value string) { - return job.env.Get(key) -} - -func (job *Job) GetenvBool(key string) (value bool) { - return job.env.GetBool(key) -} - -func (job *Job) SetenvBool(key string, value bool) { - job.env.SetBool(key, value) -} - -func (job *Job) GetenvSubEnv(key string) *Env { - return job.env.GetSubEnv(key) -} - -func (job *Job) SetenvSubEnv(key string, value *Env) error { - return job.env.SetSubEnv(key, value) -} - -func (job *Job) GetenvInt64(key string) int64 { - return job.env.GetInt64(key) -} - -func (job *Job) GetenvInt(key string) int { - return job.env.GetInt(key) -} - -func (job *Job) SetenvInt64(key string, value int64) { - job.env.SetInt64(key, value) -} - -func (job *Job) SetenvInt(key string, value int) { - job.env.SetInt(key, value) -} - -// Returns nil if key not found -func (job *Job) GetenvList(key string) []string { - return job.env.GetList(key) -} - -func (job *Job) GetenvJson(key string, iface interface{}) error { - return job.env.GetJson(key, iface) -} - -func (job *Job) SetenvJson(key string, value interface{}) error { - return job.env.SetJson(key, value) -} - -func (job *Job) SetenvList(key string, value []string) error { - return job.env.SetJson(key, value) -} - -func (job *Job) Setenv(key, value string) { - job.env.Set(key, value) -} - -// DecodeEnv decodes `src` as a json dictionary, and adds -// each decoded key-value pair to the environment. -// -// If `src` cannot be decoded as a json dictionary, an error -// is returned. -func (job *Job) DecodeEnv(src io.Reader) error { - return job.env.Decode(src) -} - -func (job *Job) EncodeEnv(dst io.Writer) error { - return job.env.Encode(dst) -} - -func (job *Job) ImportEnv(src interface{}) (err error) { - return job.env.Import(src) -} - -func (job *Job) Environ() map[string]string { - return job.env.Map() -} - -func (job *Job) Logf(format string, args ...interface{}) (n int, err error) { - prefixedFormat := fmt.Sprintf("[%s] %s\n", job, strings.TrimRight(format, "\n")) - return fmt.Fprintf(job.Stderr, prefixedFormat, args...) -} - -func (job *Job) Printf(format string, args ...interface{}) (n int, err error) { - return fmt.Fprintf(job.Stdout, format, args...) -} - -func (job *Job) Errorf(format string, args ...interface{}) Status { - if format[len(format)-1] != '\n' { - format = format + "\n" - } - fmt.Fprintf(job.Stderr, format, args...) - return StatusErr -} - -func (job *Job) Error(err error) Status { - fmt.Fprintf(job.Stderr, "%s\n", err) - return StatusErr -} - -func (job *Job) StatusCode() int { - return int(job.status) -} - -func (job *Job) SetCloseIO(val bool) { - job.closeIO = val -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/job_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/job_test.go deleted file mode 100644 index 67e723988e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/job_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package engine - -import ( - "bytes" - "fmt" - "testing" -) - -func TestJobStatusOK(t *testing.T) { - eng := New() - eng.Register("return_ok", func(job *Job) Status { return StatusOK }) - err := eng.Job("return_ok").Run() - if err != nil { - t.Fatalf("Expected: err=%v\nReceived: err=%v", nil, err) - } -} - -func TestJobStatusErr(t *testing.T) { - eng := New() - eng.Register("return_err", func(job *Job) Status { return StatusErr }) - err := eng.Job("return_err").Run() - if err == nil { - t.Fatalf("When a job returns StatusErr, Run() should return an error") - } -} - -func TestJobStatusNotFound(t *testing.T) { - eng := New() - eng.Register("return_not_found", func(job *Job) Status { return StatusNotFound }) - err := eng.Job("return_not_found").Run() - if err == nil { - t.Fatalf("When a job returns StatusNotFound, Run() should return an error") - } -} - -func TestJobStdoutString(t *testing.T) { - eng := New() - // FIXME: test multiple combinations of output and status - eng.Register("say_something_in_stdout", func(job *Job) Status { - job.Printf("Hello world\n") - return StatusOK - }) - - job := eng.Job("say_something_in_stdout") - var outputBuffer = bytes.NewBuffer(nil) - job.Stdout.Add(outputBuffer) - if err := job.Run(); err != nil { - t.Fatal(err) - } - fmt.Println(outputBuffer) - var output = Tail(outputBuffer, 1) - if expectedOutput := "Hello world"; output != expectedOutput { - t.Fatalf("Stdout last line:\nExpected: %v\nReceived: %v", expectedOutput, output) - } -} - -func TestJobStderrString(t *testing.T) { - eng := New() - // FIXME: test multiple combinations of output and status - eng.Register("say_something_in_stderr", func(job *Job) Status { - job.Errorf("Warning, something might happen\nHere it comes!\nOh no...\nSomething happened\n") - return StatusOK - }) - - job := eng.Job("say_something_in_stderr") - var outputBuffer = bytes.NewBuffer(nil) - job.Stderr.Add(outputBuffer) - if err := job.Run(); err != nil { - t.Fatal(err) - } - var output = Tail(outputBuffer, 1) - if expectedOutput := "Something happened"; output != expectedOutput { - t.Fatalf("Stderr last line:\nExpected: %v\nReceived: %v", expectedOutput, output) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/shutdown_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/shutdown_test.go deleted file mode 100644 index 13d8049267..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/shutdown_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package engine - -import ( - "testing" - "time" -) - -func TestShutdownEmpty(t *testing.T) { - eng := New() - if eng.IsShutdown() { - t.Fatalf("IsShutdown should be false") - } - eng.Shutdown() - if !eng.IsShutdown() { - t.Fatalf("IsShutdown should be true") - } -} - -func TestShutdownAfterRun(t *testing.T) { - eng := New() - var called bool - eng.Register("foo", func(job *Job) Status { - called = true - return StatusOK - }) - if err := eng.Job("foo").Run(); err != nil { - t.Fatal(err) - } - eng.Shutdown() - if err := eng.Job("foo").Run(); err == nil { - t.Fatalf("%#v", *eng) - } -} - -// An approximate and racy, but better-than-nothing test that -// -func TestShutdownDuringRun(t *testing.T) { - var ( - jobDelay time.Duration = 500 * time.Millisecond - jobDelayLow time.Duration = 100 * time.Millisecond - jobDelayHigh time.Duration = 700 * time.Millisecond - ) - eng := New() - var completed bool - eng.Register("foo", func(job *Job) Status { - time.Sleep(jobDelay) - completed = true - return StatusOK - }) - go eng.Job("foo").Run() - time.Sleep(50 * time.Millisecond) - done := make(chan struct{}) - var startShutdown time.Time - go func() { - startShutdown = time.Now() - eng.Shutdown() - close(done) - }() - time.Sleep(50 * time.Millisecond) - if err := eng.Job("foo").Run(); err == nil { - t.Fatalf("run on shutdown should fail: %#v", *eng) - } - <-done - // Verify that Shutdown() blocks for roughly 500ms, instead - // of returning almost instantly. - // - // We use >100ms to leave ample margin for race conditions between - // goroutines. It's possible (but unlikely in reasonable testing - // conditions), that this test will cause a false positive or false - // negative. But it's probably better than not having any test - // for the 99.999% of time where testing conditions are reasonable. - if d := time.Since(startShutdown); d.Nanoseconds() < jobDelayLow.Nanoseconds() { - t.Fatalf("shutdown did not block long enough: %v", d) - } else if d.Nanoseconds() > jobDelayHigh.Nanoseconds() { - t.Fatalf("shutdown blocked too long: %v", d) - } - if !completed { - t.Fatalf("job did not complete") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/streams.go b/Godeps/_workspace/src/github.com/docker/docker/engine/streams.go deleted file mode 100644 index 99e876e17b..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/streams.go +++ /dev/null @@ -1,222 +0,0 @@ -package engine - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "sync" -) - -type Output struct { - sync.Mutex - dests []io.Writer - tasks sync.WaitGroup - used bool -} - -// Tail returns the n last lines of a buffer -// stripped out of the last \n, if any -// if n <= 0, returns an empty string -func Tail(buffer *bytes.Buffer, n int) string { - if n <= 0 { - return "" - } - bytes := buffer.Bytes() - if len(bytes) > 0 && bytes[len(bytes)-1] == '\n' { - bytes = bytes[:len(bytes)-1] - } - for i := buffer.Len() - 2; i >= 0; i-- { - if bytes[i] == '\n' { - n-- - if n == 0 { - return string(bytes[i+1:]) - } - } - } - return string(bytes) -} - -// NewOutput returns a new Output object with no destinations attached. -// Writing to an empty Output will cause the written data to be discarded. -func NewOutput() *Output { - return &Output{} -} - -// Return true if something was written on this output -func (o *Output) Used() bool { - o.Lock() - defer o.Unlock() - return o.used -} - -// Add attaches a new destination to the Output. Any data subsequently written -// to the output will be written to the new destination in addition to all the others. -// This method is thread-safe. -func (o *Output) Add(dst io.Writer) { - o.Lock() - defer o.Unlock() - o.dests = append(o.dests, dst) -} - -// Set closes and remove existing destination and then attaches a new destination to -// the Output. Any data subsequently written to the output will be written to the new -// destination in addition to all the others. This method is thread-safe. -func (o *Output) Set(dst io.Writer) { - o.Close() - o.Lock() - defer o.Unlock() - o.dests = []io.Writer{dst} -} - -// AddPipe creates an in-memory pipe with io.Pipe(), adds its writing end as a destination, -// and returns its reading end for consumption by the caller. -// This is a rough equivalent similar to Cmd.StdoutPipe() in the standard os/exec package. -// This method is thread-safe. -func (o *Output) AddPipe() (io.Reader, error) { - r, w := io.Pipe() - o.Add(w) - return r, nil -} - -// Write writes the same data to all registered destinations. -// This method is thread-safe. -func (o *Output) Write(p []byte) (n int, err error) { - o.Lock() - defer o.Unlock() - o.used = true - var firstErr error - for _, dst := range o.dests { - _, err := dst.Write(p) - if err != nil && firstErr == nil { - firstErr = err - } - } - return len(p), firstErr -} - -// Close unregisters all destinations and waits for all background -// AddTail and AddString tasks to complete. -// The Close method of each destination is called if it exists. -func (o *Output) Close() error { - o.Lock() - defer o.Unlock() - var firstErr error - for _, dst := range o.dests { - if closer, ok := dst.(io.Closer); ok { - err := closer.Close() - if err != nil && firstErr == nil { - firstErr = err - } - } - } - o.tasks.Wait() - return firstErr -} - -type Input struct { - src io.Reader - sync.Mutex -} - -// NewInput returns a new Input object with no source attached. -// Reading to an empty Input will return io.EOF. -func NewInput() *Input { - return &Input{} -} - -// Read reads from the input in a thread-safe way. -func (i *Input) Read(p []byte) (n int, err error) { - i.Mutex.Lock() - defer i.Mutex.Unlock() - if i.src == nil { - return 0, io.EOF - } - return i.src.Read(p) -} - -// Closes the src -// Not thread safe on purpose -func (i *Input) Close() error { - if i.src != nil { - if closer, ok := i.src.(io.Closer); ok { - return closer.Close() - } - } - return nil -} - -// Add attaches a new source to the input. -// Add can only be called once per input. Subsequent calls will -// return an error. -func (i *Input) Add(src io.Reader) error { - i.Mutex.Lock() - defer i.Mutex.Unlock() - if i.src != nil { - return fmt.Errorf("Maximum number of sources reached: 1") - } - i.src = src - return nil -} - -// AddEnv starts a new goroutine which will decode all subsequent data -// as a stream of json-encoded objects, and point `dst` to the last -// decoded object. -// The result `env` can be queried using the type-neutral Env interface. -// It is not safe to query `env` until the Output is closed. -func (o *Output) AddEnv() (dst *Env, err error) { - src, err := o.AddPipe() - if err != nil { - return nil, err - } - dst = &Env{} - o.tasks.Add(1) - go func() { - defer o.tasks.Done() - decoder := NewDecoder(src) - for { - env, err := decoder.Decode() - if err != nil { - return - } - *dst = *env - } - }() - return dst, nil -} - -func (o *Output) AddListTable() (dst *Table, err error) { - src, err := o.AddPipe() - if err != nil { - return nil, err - } - dst = NewTable("", 0) - o.tasks.Add(1) - go func() { - defer o.tasks.Done() - content, err := ioutil.ReadAll(src) - if err != nil { - return - } - if _, err := dst.ReadListFrom(content); err != nil { - return - } - }() - return dst, nil -} - -func (o *Output) AddTable() (dst *Table, err error) { - src, err := o.AddPipe() - if err != nil { - return nil, err - } - dst = NewTable("", 0) - o.tasks.Add(1) - go func() { - defer o.tasks.Done() - if _, err := dst.ReadFrom(src); err != nil { - return - } - }() - return dst, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/streams_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/streams_test.go deleted file mode 100644 index 5cfd5d0e6c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/streams_test.go +++ /dev/null @@ -1,210 +0,0 @@ -package engine - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "strings" - "testing" -) - -type sentinelWriteCloser struct { - calledWrite bool - calledClose bool -} - -func (w *sentinelWriteCloser) Write(p []byte) (int, error) { - w.calledWrite = true - return len(p), nil -} - -func (w *sentinelWriteCloser) Close() error { - w.calledClose = true - return nil -} - -func TestOutputAddEnv(t *testing.T) { - input := "{\"foo\": \"bar\", \"answer_to_life_the_universe_and_everything\": 42}" - o := NewOutput() - result, err := o.AddEnv() - if err != nil { - t.Fatal(err) - } - o.Write([]byte(input)) - o.Close() - if v := result.Get("foo"); v != "bar" { - t.Errorf("Expected %v, got %v", "bar", v) - } - if v := result.GetInt("answer_to_life_the_universe_and_everything"); v != 42 { - t.Errorf("Expected %v, got %v", 42, v) - } - if v := result.Get("this-value-doesnt-exist"); v != "" { - t.Errorf("Expected %v, got %v", "", v) - } -} - -func TestOutputAddClose(t *testing.T) { - o := NewOutput() - var s sentinelWriteCloser - o.Add(&s) - if err := o.Close(); err != nil { - t.Fatal(err) - } - // Write data after the output is closed. - // Write should succeed, but no destination should receive it. - if _, err := o.Write([]byte("foo bar")); err != nil { - t.Fatal(err) - } - if !s.calledClose { - t.Fatal("Output.Close() didn't close the destination") - } -} - -func TestOutputAddPipe(t *testing.T) { - var testInputs = []string{ - "hello, world!", - "One\nTwo\nThree", - "", - "A line\nThen another nl-terminated line\n", - "A line followed by an empty line\n\n", - } - for _, input := range testInputs { - expectedOutput := input - o := NewOutput() - r, err := o.AddPipe() - if err != nil { - t.Fatal(err) - } - go func(o *Output) { - if n, err := o.Write([]byte(input)); err != nil { - t.Error(err) - } else if n != len(input) { - t.Errorf("Expected %d, got %d", len(input), n) - } - if err := o.Close(); err != nil { - t.Error(err) - } - }(o) - output, err := ioutil.ReadAll(r) - if err != nil { - t.Fatal(err) - } - if string(output) != expectedOutput { - t.Errorf("Last line is not stored as return string.\nExpected: '%s'\nGot: '%s'", expectedOutput, output) - } - } -} - -func TestTail(t *testing.T) { - var tests = make(map[string][]string) - tests["hello, world!"] = []string{ - "", - "hello, world!", - "hello, world!", - "hello, world!", - } - tests["One\nTwo\nThree"] = []string{ - "", - "Three", - "Two\nThree", - "One\nTwo\nThree", - } - for input, outputs := range tests { - for n, expectedOutput := range outputs { - output := Tail(bytes.NewBufferString(input), n) - if output != expectedOutput { - t.Errorf("Tail n=%d returned wrong result.\nExpected: '%s'\nGot : '%s'", n, expectedOutput, output) - } - } - } -} - -func lastLine(txt string) string { - scanner := bufio.NewScanner(strings.NewReader(txt)) - var lastLine string - for scanner.Scan() { - lastLine = scanner.Text() - } - return lastLine -} - -func TestOutputAdd(t *testing.T) { - o := NewOutput() - b := &bytes.Buffer{} - o.Add(b) - input := "hello, world!" - if n, err := o.Write([]byte(input)); err != nil { - t.Fatal(err) - } else if n != len(input) { - t.Fatalf("Expected %d, got %d", len(input), n) - } - if output := b.String(); output != input { - t.Fatalf("Received wrong data from Add.\nExpected: '%s'\nGot: '%s'", input, output) - } -} - -func TestOutputWriteError(t *testing.T) { - o := NewOutput() - buf := &bytes.Buffer{} - o.Add(buf) - r, w := io.Pipe() - input := "Hello there" - expectedErr := fmt.Errorf("This is an error") - r.CloseWithError(expectedErr) - o.Add(w) - n, err := o.Write([]byte(input)) - if err != expectedErr { - t.Fatalf("Output.Write() should return the first error encountered, if any") - } - if buf.String() != input { - t.Fatalf("Output.Write() should attempt write on all destinations, even after encountering an error") - } - if n != len(input) { - t.Fatalf("Output.Write() should return the size of the input if it successfully writes to at least one destination") - } -} - -func TestInputAddEmpty(t *testing.T) { - i := NewInput() - var b bytes.Buffer - if err := i.Add(&b); err != nil { - t.Fatal(err) - } - data, err := ioutil.ReadAll(i) - if err != nil { - t.Fatal(err) - } - if len(data) > 0 { - t.Fatalf("Read from empty input shoul yield no data") - } -} - -func TestInputAddTwo(t *testing.T) { - i := NewInput() - var b1 bytes.Buffer - // First add should succeed - if err := i.Add(&b1); err != nil { - t.Fatal(err) - } - var b2 bytes.Buffer - // Second add should fail - if err := i.Add(&b2); err == nil { - t.Fatalf("Adding a second source should return an error") - } -} - -func TestInputAddNotEmpty(t *testing.T) { - i := NewInput() - b := bytes.NewBufferString("hello world\nabc") - expectedResult := b.String() - i.Add(b) - result, err := ioutil.ReadAll(i) - if err != nil { - t.Fatal(err) - } - if string(result) != expectedResult { - t.Fatalf("Expected: %v\nReceived: %v", expectedResult, result) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/table.go b/Godeps/_workspace/src/github.com/docker/docker/engine/table.go deleted file mode 100644 index 4498bdf1ec..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/table.go +++ /dev/null @@ -1,140 +0,0 @@ -package engine - -import ( - "bytes" - "encoding/json" - "io" - "sort" - "strconv" -) - -type Table struct { - Data []*Env - sortKey string - Chan chan *Env -} - -func NewTable(sortKey string, sizeHint int) *Table { - return &Table{ - make([]*Env, 0, sizeHint), - sortKey, - make(chan *Env), - } -} - -func (t *Table) SetKey(sortKey string) { - t.sortKey = sortKey -} - -func (t *Table) Add(env *Env) { - t.Data = append(t.Data, env) -} - -func (t *Table) Len() int { - return len(t.Data) -} - -func (t *Table) Less(a, b int) bool { - return t.lessBy(a, b, t.sortKey) -} - -func (t *Table) lessBy(a, b int, by string) bool { - keyA := t.Data[a].Get(by) - keyB := t.Data[b].Get(by) - intA, errA := strconv.ParseInt(keyA, 10, 64) - intB, errB := strconv.ParseInt(keyB, 10, 64) - if errA == nil && errB == nil { - return intA < intB - } - return keyA < keyB -} - -func (t *Table) Swap(a, b int) { - tmp := t.Data[a] - t.Data[a] = t.Data[b] - t.Data[b] = tmp -} - -func (t *Table) Sort() { - sort.Sort(t) -} - -func (t *Table) ReverseSort() { - sort.Sort(sort.Reverse(t)) -} - -func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) { - if _, err := dst.Write([]byte{'['}); err != nil { - return -1, err - } - n = 1 - for i, env := range t.Data { - bytes, err := env.WriteTo(dst) - if err != nil { - return -1, err - } - n += bytes - if i != len(t.Data)-1 { - if _, err := dst.Write([]byte{','}); err != nil { - return -1, err - } - n++ - } - } - if _, err := dst.Write([]byte{']'}); err != nil { - return -1, err - } - return n + 1, nil -} - -func (t *Table) ToListString() (string, error) { - buffer := bytes.NewBuffer(nil) - if _, err := t.WriteListTo(buffer); err != nil { - return "", err - } - return buffer.String(), nil -} - -func (t *Table) WriteTo(dst io.Writer) (n int64, err error) { - for _, env := range t.Data { - bytes, err := env.WriteTo(dst) - if err != nil { - return -1, err - } - n += bytes - } - return n, nil -} - -func (t *Table) ReadListFrom(src []byte) (n int64, err error) { - var array []interface{} - - if err := json.Unmarshal(src, &array); err != nil { - return -1, err - } - - for _, item := range array { - if m, ok := item.(map[string]interface{}); ok { - env := &Env{} - for key, value := range m { - env.SetAuto(key, value) - } - t.Add(env) - } - } - - return int64(len(src)), nil -} - -func (t *Table) ReadFrom(src io.Reader) (n int64, err error) { - decoder := NewDecoder(src) - for { - env, err := decoder.Decode() - if err == io.EOF { - return 0, nil - } else if err != nil { - return -1, err - } - t.Add(env) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/engine/table_test.go b/Godeps/_workspace/src/github.com/docker/docker/engine/table_test.go deleted file mode 100644 index 9a32ac9cdb..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/engine/table_test.go +++ /dev/null @@ -1,112 +0,0 @@ -package engine - -import ( - "bytes" - "encoding/json" - "testing" -) - -func TestTableWriteTo(t *testing.T) { - table := NewTable("", 0) - e := &Env{} - e.Set("foo", "bar") - table.Add(e) - var buf bytes.Buffer - if _, err := table.WriteTo(&buf); err != nil { - t.Fatal(err) - } - output := make(map[string]string) - if err := json.Unmarshal(buf.Bytes(), &output); err != nil { - t.Fatal(err) - } - if len(output) != 1 { - t.Fatalf("Incorrect output: %v", output) - } - if val, exists := output["foo"]; !exists || val != "bar" { - t.Fatalf("Inccorect output: %v", output) - } -} - -func TestTableSortStringValue(t *testing.T) { - table := NewTable("Key", 0) - - e := &Env{} - e.Set("Key", "A") - table.Add(e) - - e = &Env{} - e.Set("Key", "D") - table.Add(e) - - e = &Env{} - e.Set("Key", "B") - table.Add(e) - - e = &Env{} - e.Set("Key", "C") - table.Add(e) - - table.Sort() - - if len := table.Len(); len != 4 { - t.Fatalf("Expected 4, got %d", len) - } - - if value := table.Data[0].Get("Key"); value != "A" { - t.Fatalf("Expected A, got %s", value) - } - - if value := table.Data[1].Get("Key"); value != "B" { - t.Fatalf("Expected B, got %s", value) - } - - if value := table.Data[2].Get("Key"); value != "C" { - t.Fatalf("Expected C, got %s", value) - } - - if value := table.Data[3].Get("Key"); value != "D" { - t.Fatalf("Expected D, got %s", value) - } -} - -func TestTableReverseSortStringValue(t *testing.T) { - table := NewTable("Key", 0) - - e := &Env{} - e.Set("Key", "A") - table.Add(e) - - e = &Env{} - e.Set("Key", "D") - table.Add(e) - - e = &Env{} - e.Set("Key", "B") - table.Add(e) - - e = &Env{} - e.Set("Key", "C") - table.Add(e) - - table.ReverseSort() - - if len := table.Len(); len != 4 { - t.Fatalf("Expected 4, got %d", len) - } - - if value := table.Data[0].Get("Key"); value != "D" { - t.Fatalf("Expected D, got %s", value) - } - - if value := table.Data[1].Get("Key"); value != "C" { - t.Fatalf("Expected B, got %s", value) - } - - if value := table.Data[2].Get("Key"); value != "B" { - t.Fatalf("Expected C, got %s", value) - } - - if value := table.Data[3].Get("Key"); value != "A" { - t.Fatalf("Expected A, got %s", value) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/MAINTAINERS deleted file mode 100644 index 2aac7265d2..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Cristian Staretu (@unclejack) -Tibor Vass (@tiborvass) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/README.md b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/README.md deleted file mode 100644 index 7307d9694f..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/README.md +++ /dev/null @@ -1 +0,0 @@ -This code provides helper functions for dealing with archive files. diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive.go deleted file mode 100644 index 995668104d..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive.go +++ /dev/null @@ -1,762 +0,0 @@ -package archive - -import ( - "bufio" - "bytes" - "compress/bzip2" - "compress/gzip" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path" - "path/filepath" - "strings" - "syscall" - - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/pkg/fileutils" - "github.com/docker/docker/pkg/pools" - "github.com/docker/docker/pkg/promise" - "github.com/docker/docker/pkg/system" -) - -type ( - Archive io.ReadCloser - ArchiveReader io.Reader - Compression int - TarOptions struct { - Includes []string - Excludes []string - Compression Compression - NoLchown bool - Name string - } - - // Archiver allows the reuse of most utility functions of this package - // with a pluggable Untar function. - Archiver struct { - Untar func(io.Reader, string, *TarOptions) error - } -) - -var ( - ErrNotImplemented = errors.New("Function not implemented") - defaultArchiver = &Archiver{Untar} -) - -const ( - Uncompressed Compression = iota - Bzip2 - Gzip - Xz -) - -func IsArchive(header []byte) bool { - compression := DetectCompression(header) - if compression != Uncompressed { - return true - } - r := tar.NewReader(bytes.NewBuffer(header)) - _, err := r.Next() - return err == nil -} - -func DetectCompression(source []byte) Compression { - for compression, m := range map[Compression][]byte{ - Bzip2: {0x42, 0x5A, 0x68}, - Gzip: {0x1F, 0x8B, 0x08}, - Xz: {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}, - } { - if len(source) < len(m) { - log.Debugf("Len too short") - continue - } - if bytes.Compare(m, source[:len(m)]) == 0 { - return compression - } - } - return Uncompressed -} - -func xzDecompress(archive io.Reader) (io.ReadCloser, error) { - args := []string{"xz", "-d", "-c", "-q"} - - return CmdStream(exec.Command(args[0], args[1:]...), archive) -} - -func DecompressStream(archive io.Reader) (io.ReadCloser, error) { - p := pools.BufioReader32KPool - buf := p.Get(archive) - bs, err := buf.Peek(10) - if err != nil { - return nil, err - } - log.Debugf("[tar autodetect] n: %v", bs) - - compression := DetectCompression(bs) - switch compression { - case Uncompressed: - readBufWrapper := p.NewReadCloserWrapper(buf, buf) - return readBufWrapper, nil - case Gzip: - gzReader, err := gzip.NewReader(buf) - if err != nil { - return nil, err - } - readBufWrapper := p.NewReadCloserWrapper(buf, gzReader) - return readBufWrapper, nil - case Bzip2: - bz2Reader := bzip2.NewReader(buf) - readBufWrapper := p.NewReadCloserWrapper(buf, bz2Reader) - return readBufWrapper, nil - case Xz: - xzReader, err := xzDecompress(buf) - if err != nil { - return nil, err - } - readBufWrapper := p.NewReadCloserWrapper(buf, xzReader) - return readBufWrapper, nil - default: - return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension()) - } -} - -func CompressStream(dest io.WriteCloser, compression Compression) (io.WriteCloser, error) { - p := pools.BufioWriter32KPool - buf := p.Get(dest) - switch compression { - case Uncompressed: - writeBufWrapper := p.NewWriteCloserWrapper(buf, buf) - return writeBufWrapper, nil - case Gzip: - gzWriter := gzip.NewWriter(dest) - writeBufWrapper := p.NewWriteCloserWrapper(buf, gzWriter) - return writeBufWrapper, nil - case Bzip2, Xz: - // archive/bzip2 does not support writing, and there is no xz support at all - // However, this is not a problem as docker only currently generates gzipped tars - return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension()) - default: - return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension()) - } -} - -func (compression *Compression) Extension() string { - switch *compression { - case Uncompressed: - return "tar" - case Bzip2: - return "tar.bz2" - case Gzip: - return "tar.gz" - case Xz: - return "tar.xz" - } - return "" -} - -type tarAppender struct { - TarWriter *tar.Writer - Buffer *bufio.Writer - - // for hardlink mapping - SeenFiles map[uint64]string -} - -func (ta *tarAppender) addTarFile(path, name string) error { - fi, err := os.Lstat(path) - if err != nil { - return err - } - - link := "" - if fi.Mode()&os.ModeSymlink != 0 { - if link, err = os.Readlink(path); err != nil { - return err - } - } - - hdr, err := tar.FileInfoHeader(fi, link) - if err != nil { - return err - } - - if fi.IsDir() && !strings.HasSuffix(name, "/") { - name = name + "/" - } - - hdr.Name = name - - nlink, inode, err := setHeaderForSpecialDevice(hdr, ta, name, fi.Sys()) - if err != nil { - return err - } - - // if it's a regular file and has more than 1 link, - // it's hardlinked, so set the type flag accordingly - if fi.Mode().IsRegular() && nlink > 1 { - // a link should have a name that it links too - // and that linked name should be first in the tar archive - if oldpath, ok := ta.SeenFiles[inode]; ok { - hdr.Typeflag = tar.TypeLink - hdr.Linkname = oldpath - hdr.Size = 0 // This Must be here for the writer math to add up! - } else { - ta.SeenFiles[inode] = name - } - } - - capability, _ := system.Lgetxattr(path, "security.capability") - if capability != nil { - hdr.Xattrs = make(map[string]string) - hdr.Xattrs["security.capability"] = string(capability) - } - - if err := ta.TarWriter.WriteHeader(hdr); err != nil { - return err - } - - if hdr.Typeflag == tar.TypeReg { - file, err := os.Open(path) - if err != nil { - return err - } - - ta.Buffer.Reset(ta.TarWriter) - defer ta.Buffer.Reset(nil) - _, err = io.Copy(ta.Buffer, file) - file.Close() - if err != nil { - return err - } - err = ta.Buffer.Flush() - if err != nil { - return err - } - } - - return nil -} - -func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool) error { - // hdr.Mode is in linux format, which we can use for sycalls, - // but for os.Foo() calls we need the mode converted to os.FileMode, - // so use hdrInfo.Mode() (they differ for e.g. setuid bits) - hdrInfo := hdr.FileInfo() - - switch hdr.Typeflag { - case tar.TypeDir: - // Create directory unless it exists as a directory already. - // In that case we just want to merge the two - if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) { - if err := os.Mkdir(path, hdrInfo.Mode()); err != nil { - return err - } - } - - case tar.TypeReg, tar.TypeRegA: - // Source is regular file - file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, hdrInfo.Mode()) - if err != nil { - return err - } - if _, err := io.Copy(file, reader); err != nil { - file.Close() - return err - } - file.Close() - - case tar.TypeBlock, tar.TypeChar, tar.TypeFifo: - mode := uint32(hdr.Mode & 07777) - switch hdr.Typeflag { - case tar.TypeBlock: - mode |= syscall.S_IFBLK - case tar.TypeChar: - mode |= syscall.S_IFCHR - case tar.TypeFifo: - mode |= syscall.S_IFIFO - } - - if err := system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor))); err != nil { - return err - } - - case tar.TypeLink: - if err := os.Link(filepath.Join(extractDir, hdr.Linkname), path); err != nil { - return err - } - - case tar.TypeSymlink: - if err := os.Symlink(hdr.Linkname, path); err != nil { - return err - } - - case tar.TypeXGlobalHeader: - log.Debugf("PAX Global Extended Headers found and ignored") - return nil - - default: - return fmt.Errorf("Unhandled tar header type %d\n", hdr.Typeflag) - } - - if err := os.Lchown(path, hdr.Uid, hdr.Gid); err != nil && Lchown { - return err - } - - for key, value := range hdr.Xattrs { - if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil { - return err - } - } - - // There is no LChmod, so ignore mode for symlink. Also, this - // must happen after chown, as that can modify the file mode - if hdr.Typeflag != tar.TypeSymlink { - if err := os.Chmod(path, hdrInfo.Mode()); err != nil { - return err - } - } - - ts := []syscall.Timespec{timeToTimespec(hdr.AccessTime), timeToTimespec(hdr.ModTime)} - // syscall.UtimesNano doesn't support a NOFOLLOW flag atm, and - if hdr.Typeflag != tar.TypeSymlink { - if err := system.UtimesNano(path, ts); err != nil && err != system.ErrNotSupportedPlatform { - return err - } - } else { - if err := system.LUtimesNano(path, ts); err != nil && err != system.ErrNotSupportedPlatform { - return err - } - } - return nil -} - -// Tar creates an archive from the directory at `path`, and returns it as a -// stream of bytes. -func Tar(path string, compression Compression) (io.ReadCloser, error) { - return TarWithOptions(path, &TarOptions{Compression: compression}) -} - -func escapeName(name string) string { - escaped := make([]byte, 0) - for i, c := range []byte(name) { - if i == 0 && c == '/' { - continue - } - // all printable chars except "-" which is 0x2d - if (0x20 <= c && c <= 0x7E) && c != 0x2d { - escaped = append(escaped, c) - } else { - escaped = append(escaped, fmt.Sprintf("\\%03o", c)...) - } - } - return string(escaped) -} - -// TarWithOptions creates an archive from the directory at `path`, only including files whose relative -// paths are included in `options.Includes` (if non-nil) or not in `options.Excludes`. -func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { - pipeReader, pipeWriter := io.Pipe() - - compressWriter, err := CompressStream(pipeWriter, options.Compression) - if err != nil { - return nil, err - } - - go func() { - ta := &tarAppender{ - TarWriter: tar.NewWriter(compressWriter), - Buffer: pools.BufioWriter32KPool.Get(nil), - SeenFiles: make(map[uint64]string), - } - // this buffer is needed for the duration of this piped stream - defer pools.BufioWriter32KPool.Put(ta.Buffer) - - // In general we log errors here but ignore them because - // during e.g. a diff operation the container can continue - // mutating the filesystem and we can see transient errors - // from this - - if options.Includes == nil { - options.Includes = []string{"."} - } - - var renamedRelFilePath string // For when tar.Options.Name is set - for _, include := range options.Includes { - filepath.Walk(filepath.Join(srcPath, include), func(filePath string, f os.FileInfo, err error) error { - if err != nil { - log.Debugf("Tar: Can't stat file %s to tar: %s", srcPath, err) - return nil - } - - relFilePath, err := filepath.Rel(srcPath, filePath) - if err != nil || (relFilePath == "." && f.IsDir()) { - // Error getting relative path OR we are looking - // at the root path. Skip in both situations. - return nil - } - - skip, err := fileutils.Matches(relFilePath, options.Excludes) - if err != nil { - log.Debugf("Error matching %s", relFilePath, err) - return err - } - - if skip { - if f.IsDir() { - return filepath.SkipDir - } - return nil - } - - // Rename the base resource - if options.Name != "" && filePath == srcPath+"/"+filepath.Base(relFilePath) { - renamedRelFilePath = relFilePath - } - // Set this to make sure the items underneath also get renamed - if options.Name != "" { - relFilePath = strings.Replace(relFilePath, renamedRelFilePath, options.Name, 1) - } - - if err := ta.addTarFile(filePath, relFilePath); err != nil { - log.Debugf("Can't add file %s to tar: %s", srcPath, err) - } - return nil - }) - } - - // Make sure to check the error on Close. - if err := ta.TarWriter.Close(); err != nil { - log.Debugf("Can't close tar writer: %s", err) - } - if err := compressWriter.Close(); err != nil { - log.Debugf("Can't close compress writer: %s", err) - } - if err := pipeWriter.Close(); err != nil { - log.Debugf("Can't close pipe writer: %s", err) - } - }() - - return pipeReader, nil -} - -// Untar reads a stream of bytes from `archive`, parses it as a tar archive, -// and unpacks it into the directory at `dest`. -// The archive may be compressed with one of the following algorithms: -// identity (uncompressed), gzip, bzip2, xz. -// FIXME: specify behavior when target path exists vs. doesn't exist. -func Untar(archive io.Reader, dest string, options *TarOptions) error { - if options == nil { - options = &TarOptions{} - } - - if archive == nil { - return fmt.Errorf("Empty archive") - } - - if options.Excludes == nil { - options.Excludes = []string{} - } - - decompressedArchive, err := DecompressStream(archive) - if err != nil { - return err - } - defer decompressedArchive.Close() - - tr := tar.NewReader(decompressedArchive) - trBuf := pools.BufioReader32KPool.Get(nil) - defer pools.BufioReader32KPool.Put(trBuf) - - var dirs []*tar.Header - - // Iterate through the files in the archive. -loop: - for { - hdr, err := tr.Next() - if err == io.EOF { - // end of tar archive - break - } - if err != nil { - return err - } - - // Normalize name, for safety and for a simple is-root check - hdr.Name = filepath.Clean(hdr.Name) - - for _, exclude := range options.Excludes { - if strings.HasPrefix(hdr.Name, exclude) { - continue loop - } - } - - if !strings.HasSuffix(hdr.Name, "/") { - // Not the root directory, ensure that the parent directory exists - parent := filepath.Dir(hdr.Name) - parentPath := filepath.Join(dest, parent) - if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) { - err = os.MkdirAll(parentPath, 0777) - if err != nil { - return err - } - } - } - - path := filepath.Join(dest, hdr.Name) - - // If path exits we almost always just want to remove and replace it - // The only exception is when it is a directory *and* the file from - // the layer is also a directory. Then we want to merge them (i.e. - // just apply the metadata from the layer). - if fi, err := os.Lstat(path); err == nil { - if fi.IsDir() && hdr.Name == "." { - continue - } - if !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) { - if err := os.RemoveAll(path); err != nil { - return err - } - } - } - trBuf.Reset(tr) - if err := createTarFile(path, dest, hdr, trBuf, !options.NoLchown); err != nil { - return err - } - - // Directory mtimes must be handled at the end to avoid further - // file creation in them to modify the directory mtime - if hdr.Typeflag == tar.TypeDir { - dirs = append(dirs, hdr) - } - } - - for _, hdr := range dirs { - path := filepath.Join(dest, hdr.Name) - ts := []syscall.Timespec{timeToTimespec(hdr.AccessTime), timeToTimespec(hdr.ModTime)} - if err := syscall.UtimesNano(path, ts); err != nil { - return err - } - } - - return nil -} - -func (archiver *Archiver) TarUntar(src, dst string) error { - log.Debugf("TarUntar(%s %s)", src, dst) - archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed}) - if err != nil { - return err - } - defer archive.Close() - return archiver.Untar(archive, dst, nil) -} - -// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other. -// If either Tar or Untar fails, TarUntar aborts and returns the error. -func TarUntar(src, dst string) error { - return defaultArchiver.TarUntar(src, dst) -} - -func (archiver *Archiver) UntarPath(src, dst string) error { - archive, err := os.Open(src) - if err != nil { - return err - } - defer archive.Close() - if err := archiver.Untar(archive, dst, nil); err != nil { - return err - } - return nil -} - -// UntarPath is a convenience function which looks for an archive -// at filesystem path `src`, and unpacks it at `dst`. -func UntarPath(src, dst string) error { - return defaultArchiver.UntarPath(src, dst) -} - -func (archiver *Archiver) CopyWithTar(src, dst string) error { - srcSt, err := os.Stat(src) - if err != nil { - return err - } - if !srcSt.IsDir() { - return archiver.CopyFileWithTar(src, dst) - } - // Create dst, copy src's content into it - log.Debugf("Creating dest directory: %s", dst) - if err := os.MkdirAll(dst, 0755); err != nil && !os.IsExist(err) { - return err - } - log.Debugf("Calling TarUntar(%s, %s)", src, dst) - return archiver.TarUntar(src, dst) -} - -// CopyWithTar creates a tar archive of filesystem path `src`, and -// unpacks it at filesystem path `dst`. -// The archive is streamed directly with fixed buffering and no -// intermediary disk IO. -func CopyWithTar(src, dst string) error { - return defaultArchiver.CopyWithTar(src, dst) -} - -func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) { - log.Debugf("CopyFileWithTar(%s, %s)", src, dst) - srcSt, err := os.Stat(src) - if err != nil { - return err - } - if srcSt.IsDir() { - return fmt.Errorf("Can't copy a directory") - } - // Clean up the trailing / - if dst[len(dst)-1] == '/' { - dst = path.Join(dst, filepath.Base(src)) - } - // Create the holding directory if necessary - if err := os.MkdirAll(filepath.Dir(dst), 0700); err != nil && !os.IsExist(err) { - return err - } - - r, w := io.Pipe() - errC := promise.Go(func() error { - defer w.Close() - - srcF, err := os.Open(src) - if err != nil { - return err - } - defer srcF.Close() - - hdr, err := tar.FileInfoHeader(srcSt, "") - if err != nil { - return err - } - hdr.Name = filepath.Base(dst) - tw := tar.NewWriter(w) - defer tw.Close() - if err := tw.WriteHeader(hdr); err != nil { - return err - } - if _, err := io.Copy(tw, srcF); err != nil { - return err - } - return nil - }) - defer func() { - if er := <-errC; err != nil { - err = er - } - }() - return archiver.Untar(r, filepath.Dir(dst), nil) -} - -// CopyFileWithTar emulates the behavior of the 'cp' command-line -// for a single file. It copies a regular file from path `src` to -// path `dst`, and preserves all its metadata. -// -// If `dst` ends with a trailing slash '/', the final destination path -// will be `dst/base(src)`. -func CopyFileWithTar(src, dst string) (err error) { - return defaultArchiver.CopyFileWithTar(src, dst) -} - -// CmdStream executes a command, and returns its stdout as a stream. -// If the command fails to run or doesn't complete successfully, an error -// will be returned, including anything written on stderr. -func CmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { - if input != nil { - stdin, err := cmd.StdinPipe() - if err != nil { - return nil, err - } - // Write stdin if any - go func() { - io.Copy(stdin, input) - stdin.Close() - }() - } - stdout, err := cmd.StdoutPipe() - if err != nil { - return nil, err - } - stderr, err := cmd.StderrPipe() - if err != nil { - return nil, err - } - pipeR, pipeW := io.Pipe() - errChan := make(chan []byte) - // Collect stderr, we will use it in case of an error - go func() { - errText, e := ioutil.ReadAll(stderr) - if e != nil { - errText = []byte("(...couldn't fetch stderr: " + e.Error() + ")") - } - errChan <- errText - }() - // Copy stdout to the returned pipe - go func() { - _, err := io.Copy(pipeW, stdout) - if err != nil { - pipeW.CloseWithError(err) - } - errText := <-errChan - if err := cmd.Wait(); err != nil { - pipeW.CloseWithError(fmt.Errorf("%s: %s", err, errText)) - } else { - pipeW.Close() - } - }() - // Run the command and return the pipe - if err := cmd.Start(); err != nil { - return nil, err - } - return pipeR, nil -} - -// NewTempArchive reads the content of src into a temporary file, and returns the contents -// of that file as an archive. The archive can only be read once - as soon as reading completes, -// the file will be deleted. -func NewTempArchive(src Archive, dir string) (*TempArchive, error) { - f, err := ioutil.TempFile(dir, "") - if err != nil { - return nil, err - } - if _, err := io.Copy(f, src); err != nil { - return nil, err - } - if err = f.Sync(); err != nil { - return nil, err - } - if _, err := f.Seek(0, 0); err != nil { - return nil, err - } - st, err := f.Stat() - if err != nil { - return nil, err - } - size := st.Size() - return &TempArchive{f, size, 0}, nil -} - -type TempArchive struct { - *os.File - Size int64 // Pre-computed from Stat().Size() as a convenience - read int64 -} - -func (archive *TempArchive) Read(data []byte) (int, error) { - n, err := archive.File.Read(data) - archive.read += int64(n) - if err != nil || archive.read == archive.Size { - archive.File.Close() - os.Remove(archive.File.Name()) - } - return n, err -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_test.go deleted file mode 100644 index 3516aca8f0..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_test.go +++ /dev/null @@ -1,405 +0,0 @@ -package archive - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path" - "syscall" - "testing" - "time" - - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" -) - -func TestCmdStreamLargeStderr(t *testing.T) { - cmd := exec.Command("/bin/sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello") - out, err := CmdStream(cmd, nil) - if err != nil { - t.Fatalf("Failed to start command: %s", err) - } - errCh := make(chan error) - go func() { - _, err := io.Copy(ioutil.Discard, out) - errCh <- err - }() - select { - case err := <-errCh: - if err != nil { - t.Fatalf("Command should not have failed (err=%.100s...)", err) - } - case <-time.After(5 * time.Second): - t.Fatalf("Command did not complete in 5 seconds; probable deadlock") - } -} - -func TestCmdStreamBad(t *testing.T) { - badCmd := exec.Command("/bin/sh", "-c", "echo hello; echo >&2 error couldn\\'t reverse the phase pulser; exit 1") - out, err := CmdStream(badCmd, nil) - if err != nil { - t.Fatalf("Failed to start command: %s", err) - } - if output, err := ioutil.ReadAll(out); err == nil { - t.Fatalf("Command should have failed") - } else if err.Error() != "exit status 1: error couldn't reverse the phase pulser\n" { - t.Fatalf("Wrong error value (%s)", err) - } else if s := string(output); s != "hello\n" { - t.Fatalf("Command output should be '%s', not '%s'", "hello\\n", output) - } -} - -func TestCmdStreamGood(t *testing.T) { - cmd := exec.Command("/bin/sh", "-c", "echo hello; exit 0") - out, err := CmdStream(cmd, nil) - if err != nil { - t.Fatal(err) - } - if output, err := ioutil.ReadAll(out); err != nil { - t.Fatalf("Command should not have failed (err=%s)", err) - } else if s := string(output); s != "hello\n" { - t.Fatalf("Command output should be '%s', not '%s'", "hello\\n", output) - } -} - -func TestTarFiles(t *testing.T) { - // try without hardlinks - if err := checkNoChanges(1000, false); err != nil { - t.Fatal(err) - } - // try with hardlinks - if err := checkNoChanges(1000, true); err != nil { - t.Fatal(err) - } -} - -func checkNoChanges(fileNum int, hardlinks bool) error { - srcDir, err := ioutil.TempDir("", "docker-test-srcDir") - if err != nil { - return err - } - defer os.RemoveAll(srcDir) - - destDir, err := ioutil.TempDir("", "docker-test-destDir") - if err != nil { - return err - } - defer os.RemoveAll(destDir) - - _, err = prepareUntarSourceDirectory(fileNum, srcDir, hardlinks) - if err != nil { - return err - } - - err = TarUntar(srcDir, destDir) - if err != nil { - return err - } - - changes, err := ChangesDirs(destDir, srcDir) - if err != nil { - return err - } - if len(changes) > 0 { - return fmt.Errorf("with %d files and %v hardlinks: expected 0 changes, got %d", fileNum, hardlinks, len(changes)) - } - return nil -} - -func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error) { - archive, err := TarWithOptions(origin, options) - if err != nil { - t.Fatal(err) - } - defer archive.Close() - - buf := make([]byte, 10) - if _, err := archive.Read(buf); err != nil { - return nil, err - } - wrap := io.MultiReader(bytes.NewReader(buf), archive) - - detectedCompression := DetectCompression(buf) - compression := options.Compression - if detectedCompression.Extension() != compression.Extension() { - return nil, fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) - } - - tmp, err := ioutil.TempDir("", "docker-test-untar") - if err != nil { - return nil, err - } - defer os.RemoveAll(tmp) - if err := Untar(wrap, tmp, nil); err != nil { - return nil, err - } - if _, err := os.Stat(tmp); err != nil { - return nil, err - } - - return ChangesDirs(origin, tmp) -} - -func TestTarUntar(t *testing.T) { - origin, err := ioutil.TempDir("", "docker-test-untar-origin") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(origin) - if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(path.Join(origin, "3"), []byte("will be ignored"), 0700); err != nil { - t.Fatal(err) - } - - for _, c := range []Compression{ - Uncompressed, - Gzip, - } { - changes, err := tarUntar(t, origin, &TarOptions{ - Compression: c, - Excludes: []string{"3"}, - }) - - if err != nil { - t.Fatalf("Error tar/untar for compression %s: %s", c.Extension(), err) - } - - if len(changes) != 1 || changes[0].Path != "/3" { - t.Fatalf("Unexpected differences after tarUntar: %v", changes) - } - } -} - -func TestTarWithOptions(t *testing.T) { - origin, err := ioutil.TempDir("", "docker-test-untar-origin") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(origin) - if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { - t.Fatal(err) - } - - cases := []struct { - opts *TarOptions - numChanges int - }{ - {&TarOptions{Includes: []string{"1"}}, 1}, - {&TarOptions{Excludes: []string{"2"}}, 1}, - } - for _, testCase := range cases { - changes, err := tarUntar(t, origin, testCase.opts) - if err != nil { - t.Fatalf("Error tar/untar when testing inclusion/exclusion: %s", err) - } - if len(changes) != testCase.numChanges { - t.Errorf("Expected %d changes, got %d for %+v:", - testCase.numChanges, len(changes), testCase.opts) - } - } -} - -// Some tar archives such as http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev21.tar.gz -// use PAX Global Extended Headers. -// Failing prevents the archives from being uncompressed during ADD -func TestTypeXGlobalHeaderDoesNotFail(t *testing.T) { - hdr := tar.Header{Typeflag: tar.TypeXGlobalHeader} - err := createTarFile("pax_global_header", "some_dir", &hdr, nil, true) - if err != nil { - t.Fatal(err) - } -} - -// Some tar have both GNU specific (huge uid) and Ustar specific (long name) things. -// Not supposed to happen (should use PAX instead of Ustar for long name) but it does and it should still work. -func TestUntarUstarGnuConflict(t *testing.T) { - f, err := os.Open("testdata/broken.tar") - if err != nil { - t.Fatal(err) - } - found := false - tr := tar.NewReader(f) - // Iterate through the files in the archive. - for { - hdr, err := tr.Next() - if err == io.EOF { - // end of tar archive - break - } - if err != nil { - t.Fatal(err) - } - if hdr.Name == "root/.cpanm/work/1395823785.24209/Plack-1.0030/blib/man3/Plack::Middleware::LighttpdScriptNameFix.3pm" { - found = true - break - } - } - if !found { - t.Fatalf("%s not found in the archive", "root/.cpanm/work/1395823785.24209/Plack-1.0030/blib/man3/Plack::Middleware::LighttpdScriptNameFix.3pm") - } -} - -func TestTarWithHardLink(t *testing.T) { - origin, err := ioutil.TempDir("", "docker-test-tar-hardlink") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(origin) - if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil { - t.Fatal(err) - } - if err := os.Link(path.Join(origin, "1"), path.Join(origin, "2")); err != nil { - t.Fatal(err) - } - - var i1, i2 uint64 - if i1, err = getNlink(path.Join(origin, "1")); err != nil { - t.Fatal(err) - } - // sanity check that we can hardlink - if i1 != 2 { - t.Skipf("skipping since hardlinks don't work here; expected 2 links, got %d", i1) - } - - dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dest) - - // we'll do this in two steps to separate failure - fh, err := Tar(origin, Uncompressed) - if err != nil { - t.Fatal(err) - } - - // ensure we can read the whole thing with no error, before writing back out - buf, err := ioutil.ReadAll(fh) - if err != nil { - t.Fatal(err) - } - - bRdr := bytes.NewReader(buf) - err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed}) - if err != nil { - t.Fatal(err) - } - - if i1, err = getInode(path.Join(dest, "1")); err != nil { - t.Fatal(err) - } - if i2, err = getInode(path.Join(dest, "2")); err != nil { - t.Fatal(err) - } - - if i1 != i2 { - t.Errorf("expected matching inodes, but got %d and %d", i1, i2) - } -} - -func getNlink(path string) (uint64, error) { - stat, err := os.Stat(path) - if err != nil { - return 0, err - } - statT, ok := stat.Sys().(*syscall.Stat_t) - if !ok { - return 0, fmt.Errorf("expected type *syscall.Stat_t, got %t", stat.Sys()) - } - return statT.Nlink, nil -} - -func getInode(path string) (uint64, error) { - stat, err := os.Stat(path) - if err != nil { - return 0, err - } - statT, ok := stat.Sys().(*syscall.Stat_t) - if !ok { - return 0, fmt.Errorf("expected type *syscall.Stat_t, got %t", stat.Sys()) - } - return statT.Ino, nil -} - -func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) { - fileData := []byte("fooo") - for n := 0; n < numberOfFiles; n++ { - fileName := fmt.Sprintf("file-%d", n) - if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { - return 0, err - } - if makeLinks { - if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil { - return 0, err - } - } - } - totalSize := numberOfFiles * len(fileData) - return totalSize, nil -} - -func BenchmarkTarUntar(b *testing.B) { - origin, err := ioutil.TempDir("", "docker-test-untar-origin") - if err != nil { - b.Fatal(err) - } - tempDir, err := ioutil.TempDir("", "docker-test-untar-destination") - if err != nil { - b.Fatal(err) - } - target := path.Join(tempDir, "dest") - n, err := prepareUntarSourceDirectory(100, origin, false) - if err != nil { - b.Fatal(err) - } - defer os.RemoveAll(origin) - defer os.RemoveAll(tempDir) - - b.ResetTimer() - b.SetBytes(int64(n)) - for n := 0; n < b.N; n++ { - err := TarUntar(origin, target) - if err != nil { - b.Fatal(err) - } - os.RemoveAll(target) - } -} - -func BenchmarkTarUntarWithLinks(b *testing.B) { - origin, err := ioutil.TempDir("", "docker-test-untar-origin") - if err != nil { - b.Fatal(err) - } - tempDir, err := ioutil.TempDir("", "docker-test-untar-destination") - if err != nil { - b.Fatal(err) - } - target := path.Join(tempDir, "dest") - n, err := prepareUntarSourceDirectory(100, origin, true) - if err != nil { - b.Fatal(err) - } - defer os.RemoveAll(origin) - defer os.RemoveAll(tempDir) - - b.ResetTimer() - b.SetBytes(int64(n)) - for n := 0; n < b.N; n++ { - err := TarUntar(origin, target) - if err != nil { - b.Fatal(err) - } - os.RemoveAll(target) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_unix.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_unix.go deleted file mode 100644 index c0e8aee93c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_unix.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build !windows - -package archive - -import ( - "errors" - "syscall" - - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" -) - -func setHeaderForSpecialDevice(hdr *tar.Header, ta *tarAppender, name string, stat interface{}) (nlink uint32, inode uint64, err error) { - s, ok := stat.(*syscall.Stat_t) - - if !ok { - err = errors.New("cannot convert stat value to syscall.Stat_t") - return - } - - nlink = uint32(s.Nlink) - inode = uint64(s.Ino) - - // Currently go does not fil in the major/minors - if s.Mode&syscall.S_IFBLK == syscall.S_IFBLK || - s.Mode&syscall.S_IFCHR == syscall.S_IFCHR { - hdr.Devmajor = int64(major(uint64(s.Rdev))) - hdr.Devminor = int64(minor(uint64(s.Rdev))) - } - - return -} - -func major(device uint64) uint64 { - return (device >> 8) & 0xfff -} - -func minor(device uint64) uint64 { - return (device & 0xff) | ((device >> 12) & 0xfff00) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_windows.go deleted file mode 100644 index 3cc2493f6f..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/archive_windows.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build windows - -package archive - -import ( - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" -) - -func setHeaderForSpecialDevice(hdr *tar.Header, ta *tarAppender, name string, stat interface{}) (nlink uint32, inode uint64, err error) { - // do nothing. no notion of Rdev, Inode, Nlink in stat on Windows - return -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/changes.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/changes.go deleted file mode 100644 index 85217f6e08..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/changes.go +++ /dev/null @@ -1,413 +0,0 @@ -package archive - -import ( - "bytes" - "fmt" - "io" - "os" - "path/filepath" - "strings" - "syscall" - "time" - - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/pkg/pools" - "github.com/docker/docker/pkg/system" -) - -type ChangeType int - -const ( - ChangeModify = iota - ChangeAdd - ChangeDelete -) - -type Change struct { - Path string - Kind ChangeType -} - -func (change *Change) String() string { - var kind string - switch change.Kind { - case ChangeModify: - kind = "C" - case ChangeAdd: - kind = "A" - case ChangeDelete: - kind = "D" - } - return fmt.Sprintf("%s %s", kind, change.Path) -} - -// Gnu tar and the go tar writer don't have sub-second mtime -// precision, which is problematic when we apply changes via tar -// files, we handle this by comparing for exact times, *or* same -// second count and either a or b having exactly 0 nanoseconds -func sameFsTime(a, b time.Time) bool { - return a == b || - (a.Unix() == b.Unix() && - (a.Nanosecond() == 0 || b.Nanosecond() == 0)) -} - -func sameFsTimeSpec(a, b syscall.Timespec) bool { - return a.Sec == b.Sec && - (a.Nsec == b.Nsec || a.Nsec == 0 || b.Nsec == 0) -} - -// Changes walks the path rw and determines changes for the files in the path, -// with respect to the parent layers -func Changes(layers []string, rw string) ([]Change, error) { - var changes []Change - err := filepath.Walk(rw, func(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - - // Rebase path - path, err = filepath.Rel(rw, path) - if err != nil { - return err - } - path = filepath.Join("/", path) - - // Skip root - if path == "/" { - return nil - } - - // Skip AUFS metadata - if matched, err := filepath.Match("/.wh..wh.*", path); err != nil || matched { - return err - } - - change := Change{ - Path: path, - } - - // Find out what kind of modification happened - file := filepath.Base(path) - // If there is a whiteout, then the file was removed - if strings.HasPrefix(file, ".wh.") { - originalFile := file[len(".wh."):] - change.Path = filepath.Join(filepath.Dir(path), originalFile) - change.Kind = ChangeDelete - } else { - // Otherwise, the file was added - change.Kind = ChangeAdd - - // ...Unless it already existed in a top layer, in which case, it's a modification - for _, layer := range layers { - stat, err := os.Stat(filepath.Join(layer, path)) - if err != nil && !os.IsNotExist(err) { - return err - } - if err == nil { - // The file existed in the top layer, so that's a modification - - // However, if it's a directory, maybe it wasn't actually modified. - // If you modify /foo/bar/baz, then /foo will be part of the changed files only because it's the parent of bar - if stat.IsDir() && f.IsDir() { - if f.Size() == stat.Size() && f.Mode() == stat.Mode() && sameFsTime(f.ModTime(), stat.ModTime()) { - // Both directories are the same, don't record the change - return nil - } - } - change.Kind = ChangeModify - break - } - } - } - - // Record change - changes = append(changes, change) - return nil - }) - if err != nil && !os.IsNotExist(err) { - return nil, err - } - return changes, nil -} - -type FileInfo struct { - parent *FileInfo - name string - stat *system.Stat - children map[string]*FileInfo - capability []byte - added bool -} - -func (root *FileInfo) LookUp(path string) *FileInfo { - parent := root - if path == "/" { - return root - } - - pathElements := strings.Split(path, "/") - for _, elem := range pathElements { - if elem != "" { - child := parent.children[elem] - if child == nil { - return nil - } - parent = child - } - } - return parent -} - -func (info *FileInfo) path() string { - if info.parent == nil { - return "/" - } - return filepath.Join(info.parent.path(), info.name) -} - -func (info *FileInfo) isDir() bool { - return info.parent == nil || info.stat.Mode()&syscall.S_IFDIR == syscall.S_IFDIR -} - -func (info *FileInfo) addChanges(oldInfo *FileInfo, changes *[]Change) { - - sizeAtEntry := len(*changes) - - if oldInfo == nil { - // add - change := Change{ - Path: info.path(), - Kind: ChangeAdd, - } - *changes = append(*changes, change) - info.added = true - } - - // We make a copy so we can modify it to detect additions - // also, we only recurse on the old dir if the new info is a directory - // otherwise any previous delete/change is considered recursive - oldChildren := make(map[string]*FileInfo) - if oldInfo != nil && info.isDir() { - for k, v := range oldInfo.children { - oldChildren[k] = v - } - } - - for name, newChild := range info.children { - oldChild, _ := oldChildren[name] - if oldChild != nil { - // change? - oldStat := oldChild.stat - newStat := newChild.stat - // Note: We can't compare inode or ctime or blocksize here, because these change - // when copying a file into a container. However, that is not generally a problem - // because any content change will change mtime, and any status change should - // be visible when actually comparing the stat fields. The only time this - // breaks down is if some code intentionally hides a change by setting - // back mtime - if oldStat.Mode() != newStat.Mode() || - oldStat.Uid() != newStat.Uid() || - oldStat.Gid() != newStat.Gid() || - oldStat.Rdev() != newStat.Rdev() || - // Don't look at size for dirs, its not a good measure of change - (oldStat.Size() != newStat.Size() && oldStat.Mode()&syscall.S_IFDIR != syscall.S_IFDIR) || - !sameFsTimeSpec(oldStat.Mtim(), newStat.Mtim()) || - bytes.Compare(oldChild.capability, newChild.capability) != 0 { - change := Change{ - Path: newChild.path(), - Kind: ChangeModify, - } - *changes = append(*changes, change) - newChild.added = true - } - - // Remove from copy so we can detect deletions - delete(oldChildren, name) - } - - newChild.addChanges(oldChild, changes) - } - for _, oldChild := range oldChildren { - // delete - change := Change{ - Path: oldChild.path(), - Kind: ChangeDelete, - } - *changes = append(*changes, change) - } - - // If there were changes inside this directory, we need to add it, even if the directory - // itself wasn't changed. This is needed to properly save and restore filesystem permissions. - if len(*changes) > sizeAtEntry && info.isDir() && !info.added && info.path() != "/" { - change := Change{ - Path: info.path(), - Kind: ChangeModify, - } - // Let's insert the directory entry before the recently added entries located inside this dir - *changes = append(*changes, change) // just to resize the slice, will be overwritten - copy((*changes)[sizeAtEntry+1:], (*changes)[sizeAtEntry:]) - (*changes)[sizeAtEntry] = change - } - -} - -func (info *FileInfo) Changes(oldInfo *FileInfo) []Change { - var changes []Change - - info.addChanges(oldInfo, &changes) - - return changes -} - -func newRootFileInfo() *FileInfo { - root := &FileInfo{ - name: "/", - children: make(map[string]*FileInfo), - } - return root -} - -func collectFileInfo(sourceDir string) (*FileInfo, error) { - root := newRootFileInfo() - - err := filepath.Walk(sourceDir, func(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - - // Rebase path - relPath, err := filepath.Rel(sourceDir, path) - if err != nil { - return err - } - relPath = filepath.Join("/", relPath) - - if relPath == "/" { - return nil - } - - parent := root.LookUp(filepath.Dir(relPath)) - if parent == nil { - return fmt.Errorf("collectFileInfo: Unexpectedly no parent for %s", relPath) - } - - info := &FileInfo{ - name: filepath.Base(relPath), - children: make(map[string]*FileInfo), - parent: parent, - } - - s, err := system.Lstat(path) - if err != nil { - return err - } - info.stat = s - - info.capability, _ = system.Lgetxattr(path, "security.capability") - - parent.children[info.name] = info - - return nil - }) - if err != nil { - return nil, err - } - return root, nil -} - -// ChangesDirs compares two directories and generates an array of Change objects describing the changes. -// If oldDir is "", then all files in newDir will be Add-Changes. -func ChangesDirs(newDir, oldDir string) ([]Change, error) { - var ( - oldRoot, newRoot *FileInfo - err1, err2 error - errs = make(chan error, 2) - ) - go func() { - if oldDir != "" { - oldRoot, err1 = collectFileInfo(oldDir) - } - errs <- err1 - }() - go func() { - newRoot, err2 = collectFileInfo(newDir) - errs <- err2 - }() - - // block until both routines have returned - for i := 0; i < 2; i++ { - if err := <-errs; err != nil { - return nil, err - } - } - - return newRoot.Changes(oldRoot), nil -} - -// ChangesSize calculates the size in bytes of the provided changes, based on newDir. -func ChangesSize(newDir string, changes []Change) int64 { - var size int64 - for _, change := range changes { - if change.Kind == ChangeModify || change.Kind == ChangeAdd { - file := filepath.Join(newDir, change.Path) - fileInfo, _ := os.Lstat(file) - if fileInfo != nil && !fileInfo.IsDir() { - size += fileInfo.Size() - } - } - } - return size -} - -// ExportChanges produces an Archive from the provided changes, relative to dir. -func ExportChanges(dir string, changes []Change) (Archive, error) { - reader, writer := io.Pipe() - go func() { - ta := &tarAppender{ - TarWriter: tar.NewWriter(writer), - Buffer: pools.BufioWriter32KPool.Get(nil), - SeenFiles: make(map[uint64]string), - } - // this buffer is needed for the duration of this piped stream - defer pools.BufioWriter32KPool.Put(ta.Buffer) - - // In general we log errors here but ignore them because - // during e.g. a diff operation the container can continue - // mutating the filesystem and we can see transient errors - // from this - for _, change := range changes { - if change.Kind == ChangeDelete { - whiteOutDir := filepath.Dir(change.Path) - whiteOutBase := filepath.Base(change.Path) - whiteOut := filepath.Join(whiteOutDir, ".wh."+whiteOutBase) - timestamp := time.Now() - hdr := &tar.Header{ - Name: whiteOut[1:], - Size: 0, - ModTime: timestamp, - AccessTime: timestamp, - ChangeTime: timestamp, - } - if err := ta.TarWriter.WriteHeader(hdr); err != nil { - log.Debugf("Can't write whiteout header: %s", err) - } - } else { - path := filepath.Join(dir, change.Path) - if err := ta.addTarFile(path, change.Path[1:]); err != nil { - log.Debugf("Can't add file %s to tar: %s", path, err) - } - } - } - - // Make sure to check the error on Close. - if err := ta.TarWriter.Close(); err != nil { - log.Debugf("Can't close layer: %s", err) - } - if err := writer.Close(); err != nil { - log.Debugf("failed close Changes writer: %s", err) - } - }() - return reader, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/changes_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/changes_test.go deleted file mode 100644 index 34c0f0da64..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/changes_test.go +++ /dev/null @@ -1,301 +0,0 @@ -package archive - -import ( - "io/ioutil" - "os" - "os/exec" - "path" - "sort" - "testing" - "time" -) - -func max(x, y int) int { - if x >= y { - return x - } - return y -} - -func copyDir(src, dst string) error { - cmd := exec.Command("cp", "-a", src, dst) - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -// Helper to sort []Change by path -type byPath struct{ changes []Change } - -func (b byPath) Less(i, j int) bool { return b.changes[i].Path < b.changes[j].Path } -func (b byPath) Len() int { return len(b.changes) } -func (b byPath) Swap(i, j int) { b.changes[i], b.changes[j] = b.changes[j], b.changes[i] } - -type FileType uint32 - -const ( - Regular FileType = iota - Dir - Symlink -) - -type FileData struct { - filetype FileType - path string - contents string - permissions os.FileMode -} - -func createSampleDir(t *testing.T, root string) { - files := []FileData{ - {Regular, "file1", "file1\n", 0600}, - {Regular, "file2", "file2\n", 0666}, - {Regular, "file3", "file3\n", 0404}, - {Regular, "file4", "file4\n", 0600}, - {Regular, "file5", "file5\n", 0600}, - {Regular, "file6", "file6\n", 0600}, - {Regular, "file7", "file7\n", 0600}, - {Dir, "dir1", "", 0740}, - {Regular, "dir1/file1-1", "file1-1\n", 01444}, - {Regular, "dir1/file1-2", "file1-2\n", 0666}, - {Dir, "dir2", "", 0700}, - {Regular, "dir2/file2-1", "file2-1\n", 0666}, - {Regular, "dir2/file2-2", "file2-2\n", 0666}, - {Dir, "dir3", "", 0700}, - {Regular, "dir3/file3-1", "file3-1\n", 0666}, - {Regular, "dir3/file3-2", "file3-2\n", 0666}, - {Dir, "dir4", "", 0700}, - {Regular, "dir4/file3-1", "file4-1\n", 0666}, - {Regular, "dir4/file3-2", "file4-2\n", 0666}, - {Symlink, "symlink1", "target1", 0666}, - {Symlink, "symlink2", "target2", 0666}, - } - - now := time.Now() - for _, info := range files { - p := path.Join(root, info.path) - if info.filetype == Dir { - if err := os.MkdirAll(p, info.permissions); err != nil { - t.Fatal(err) - } - } else if info.filetype == Regular { - if err := ioutil.WriteFile(p, []byte(info.contents), info.permissions); err != nil { - t.Fatal(err) - } - } else if info.filetype == Symlink { - if err := os.Symlink(info.contents, p); err != nil { - t.Fatal(err) - } - } - - if info.filetype != Symlink { - // Set a consistent ctime, atime for all files and dirs - if err := os.Chtimes(p, now, now); err != nil { - t.Fatal(err) - } - } - } -} - -// Create an directory, copy it, make sure we report no changes between the two -func TestChangesDirsEmpty(t *testing.T) { - src, err := ioutil.TempDir("", "docker-changes-test") - if err != nil { - t.Fatal(err) - } - createSampleDir(t, src) - dst := src + "-copy" - if err := copyDir(src, dst); err != nil { - t.Fatal(err) - } - changes, err := ChangesDirs(dst, src) - if err != nil { - t.Fatal(err) - } - - if len(changes) != 0 { - t.Fatalf("Reported changes for identical dirs: %v", changes) - } - os.RemoveAll(src) - os.RemoveAll(dst) -} - -func mutateSampleDir(t *testing.T, root string) { - // Remove a regular file - if err := os.RemoveAll(path.Join(root, "file1")); err != nil { - t.Fatal(err) - } - - // Remove a directory - if err := os.RemoveAll(path.Join(root, "dir1")); err != nil { - t.Fatal(err) - } - - // Remove a symlink - if err := os.RemoveAll(path.Join(root, "symlink1")); err != nil { - t.Fatal(err) - } - - // Rewrite a file - if err := ioutil.WriteFile(path.Join(root, "file2"), []byte("fileNN\n"), 0777); err != nil { - t.Fatal(err) - } - - // Replace a file - if err := os.RemoveAll(path.Join(root, "file3")); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(path.Join(root, "file3"), []byte("fileMM\n"), 0404); err != nil { - t.Fatal(err) - } - - // Touch file - if err := os.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { - t.Fatal(err) - } - - // Replace file with dir - if err := os.RemoveAll(path.Join(root, "file5")); err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(path.Join(root, "file5"), 0666); err != nil { - t.Fatal(err) - } - - // Create new file - if err := ioutil.WriteFile(path.Join(root, "filenew"), []byte("filenew\n"), 0777); err != nil { - t.Fatal(err) - } - - // Create new dir - if err := os.MkdirAll(path.Join(root, "dirnew"), 0766); err != nil { - t.Fatal(err) - } - - // Create a new symlink - if err := os.Symlink("targetnew", path.Join(root, "symlinknew")); err != nil { - t.Fatal(err) - } - - // Change a symlink - if err := os.RemoveAll(path.Join(root, "symlink2")); err != nil { - t.Fatal(err) - } - if err := os.Symlink("target2change", path.Join(root, "symlink2")); err != nil { - t.Fatal(err) - } - - // Replace dir with file - if err := os.RemoveAll(path.Join(root, "dir2")); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(path.Join(root, "dir2"), []byte("dir2\n"), 0777); err != nil { - t.Fatal(err) - } - - // Touch dir - if err := os.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { - t.Fatal(err) - } -} - -func TestChangesDirsMutated(t *testing.T) { - src, err := ioutil.TempDir("", "docker-changes-test") - if err != nil { - t.Fatal(err) - } - createSampleDir(t, src) - dst := src + "-copy" - if err := copyDir(src, dst); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(src) - defer os.RemoveAll(dst) - - mutateSampleDir(t, dst) - - changes, err := ChangesDirs(dst, src) - if err != nil { - t.Fatal(err) - } - - sort.Sort(byPath{changes}) - - expectedChanges := []Change{ - {"/dir1", ChangeDelete}, - {"/dir2", ChangeModify}, - {"/dir3", ChangeModify}, - {"/dirnew", ChangeAdd}, - {"/file1", ChangeDelete}, - {"/file2", ChangeModify}, - {"/file3", ChangeModify}, - {"/file4", ChangeModify}, - {"/file5", ChangeModify}, - {"/filenew", ChangeAdd}, - {"/symlink1", ChangeDelete}, - {"/symlink2", ChangeModify}, - {"/symlinknew", ChangeAdd}, - } - - for i := 0; i < max(len(changes), len(expectedChanges)); i++ { - if i >= len(expectedChanges) { - t.Fatalf("unexpected change %s\n", changes[i].String()) - } - if i >= len(changes) { - t.Fatalf("no change for expected change %s\n", expectedChanges[i].String()) - } - if changes[i].Path == expectedChanges[i].Path { - if changes[i] != expectedChanges[i] { - t.Fatalf("Wrong change for %s, expected %s, got %s\n", changes[i].Path, changes[i].String(), expectedChanges[i].String()) - } - } else if changes[i].Path < expectedChanges[i].Path { - t.Fatalf("unexpected change %s\n", changes[i].String()) - } else { - t.Fatalf("no change for expected change %s != %s\n", expectedChanges[i].String(), changes[i].String()) - } - } -} - -func TestApplyLayer(t *testing.T) { - src, err := ioutil.TempDir("", "docker-changes-test") - if err != nil { - t.Fatal(err) - } - createSampleDir(t, src) - defer os.RemoveAll(src) - dst := src + "-copy" - if err := copyDir(src, dst); err != nil { - t.Fatal(err) - } - mutateSampleDir(t, dst) - defer os.RemoveAll(dst) - - changes, err := ChangesDirs(dst, src) - if err != nil { - t.Fatal(err) - } - - layer, err := ExportChanges(dst, changes) - if err != nil { - t.Fatal(err) - } - - layerCopy, err := NewTempArchive(layer, "") - if err != nil { - t.Fatal(err) - } - - if err := ApplyLayer(src, layerCopy); err != nil { - t.Fatal(err) - } - - changes2, err := ChangesDirs(src, dst) - if err != nil { - t.Fatal(err) - } - - if len(changes2) != 0 { - t.Fatalf("Unexpected differences after reapplying mutation: %v", changes2) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/diff.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/diff.go deleted file mode 100644 index eabb7c48ff..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/diff.go +++ /dev/null @@ -1,154 +0,0 @@ -package archive - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "syscall" - - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" - - "github.com/docker/docker/pkg/pools" - "github.com/docker/docker/pkg/system" -) - -// ApplyLayer parses a diff in the standard layer format from `layer`, and -// applies it to the directory `dest`. -func ApplyLayer(dest string, layer ArchiveReader) error { - // We need to be able to set any perms - oldmask, err := system.Umask(0) - if err != nil { - return err - } - - defer system.Umask(oldmask) // ignore err, ErrNotSupportedPlatform - - layer, err = DecompressStream(layer) - if err != nil { - return err - } - - tr := tar.NewReader(layer) - trBuf := pools.BufioReader32KPool.Get(tr) - defer pools.BufioReader32KPool.Put(trBuf) - - var dirs []*tar.Header - - aufsTempdir := "" - aufsHardlinks := make(map[string]*tar.Header) - - // Iterate through the files in the archive. - for { - hdr, err := tr.Next() - if err == io.EOF { - // end of tar archive - break - } - if err != nil { - return err - } - - // Normalize name, for safety and for a simple is-root check - hdr.Name = filepath.Clean(hdr.Name) - - if !strings.HasSuffix(hdr.Name, "/") { - // Not the root directory, ensure that the parent directory exists. - // This happened in some tests where an image had a tarfile without any - // parent directories. - parent := filepath.Dir(hdr.Name) - parentPath := filepath.Join(dest, parent) - if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) { - err = os.MkdirAll(parentPath, 0600) - if err != nil { - return err - } - } - } - - // Skip AUFS metadata dirs - if strings.HasPrefix(hdr.Name, ".wh..wh.") { - // Regular files inside /.wh..wh.plnk can be used as hardlink targets - // We don't want this directory, but we need the files in them so that - // such hardlinks can be resolved. - if strings.HasPrefix(hdr.Name, ".wh..wh.plnk") && hdr.Typeflag == tar.TypeReg { - basename := filepath.Base(hdr.Name) - aufsHardlinks[basename] = hdr - if aufsTempdir == "" { - if aufsTempdir, err = ioutil.TempDir("", "dockerplnk"); err != nil { - return err - } - defer os.RemoveAll(aufsTempdir) - } - if err := createTarFile(filepath.Join(aufsTempdir, basename), dest, hdr, tr, true); err != nil { - return err - } - } - continue - } - - path := filepath.Join(dest, hdr.Name) - base := filepath.Base(path) - if strings.HasPrefix(base, ".wh.") { - originalBase := base[len(".wh."):] - originalPath := filepath.Join(filepath.Dir(path), originalBase) - if err := os.RemoveAll(originalPath); err != nil { - return err - } - } else { - // If path exits we almost always just want to remove and replace it. - // The only exception is when it is a directory *and* the file from - // the layer is also a directory. Then we want to merge them (i.e. - // just apply the metadata from the layer). - if fi, err := os.Lstat(path); err == nil { - if !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) { - if err := os.RemoveAll(path); err != nil { - return err - } - } - } - - trBuf.Reset(tr) - srcData := io.Reader(trBuf) - srcHdr := hdr - - // Hard links into /.wh..wh.plnk don't work, as we don't extract that directory, so - // we manually retarget these into the temporary files we extracted them into - if hdr.Typeflag == tar.TypeLink && strings.HasPrefix(filepath.Clean(hdr.Linkname), ".wh..wh.plnk") { - linkBasename := filepath.Base(hdr.Linkname) - srcHdr = aufsHardlinks[linkBasename] - if srcHdr == nil { - return fmt.Errorf("Invalid aufs hardlink") - } - tmpFile, err := os.Open(filepath.Join(aufsTempdir, linkBasename)) - if err != nil { - return err - } - defer tmpFile.Close() - srcData = tmpFile - } - - if err := createTarFile(path, dest, srcHdr, srcData, true); err != nil { - return err - } - - // Directory mtimes must be handled at the end to avoid further - // file creation in them to modify the directory mtime - if hdr.Typeflag == tar.TypeDir { - dirs = append(dirs, hdr) - } - } - } - - for _, hdr := range dirs { - path := filepath.Join(dest, hdr.Name) - ts := []syscall.Timespec{timeToTimespec(hdr.AccessTime), timeToTimespec(hdr.ModTime)} - if err := syscall.UtimesNano(path, ts); err != nil { - return err - } - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/example_changes.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/example_changes.go deleted file mode 100644 index cedd46a408..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/example_changes.go +++ /dev/null @@ -1,97 +0,0 @@ -// +build ignore - -// Simple tool to create an archive stream from an old and new directory -// -// By default it will stream the comparison of two temporary directories with junk files -package main - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "path" - - "github.com/Sirupsen/logrus" - "github.com/docker/docker/pkg/archive" -) - -var ( - flDebug = flag.Bool("D", false, "debugging output") - flNewDir = flag.String("newdir", "", "") - flOldDir = flag.String("olddir", "", "") - log = logrus.New() -) - -func main() { - flag.Usage = func() { - fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)") - fmt.Printf("%s [OPTIONS]\n", os.Args[0]) - flag.PrintDefaults() - } - flag.Parse() - log.Out = os.Stderr - if (len(os.Getenv("DEBUG")) > 0) || *flDebug { - logrus.SetLevel(logrus.DebugLevel) - } - var newDir, oldDir string - - if len(*flNewDir) == 0 { - var err error - newDir, err = ioutil.TempDir("", "docker-test-newDir") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(newDir) - if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil { - log.Fatal(err) - } - } else { - newDir = *flNewDir - } - - if len(*flOldDir) == 0 { - oldDir, err := ioutil.TempDir("", "docker-test-oldDir") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(oldDir) - } else { - oldDir = *flOldDir - } - - changes, err := archive.ChangesDirs(newDir, oldDir) - if err != nil { - log.Fatal(err) - } - - a, err := archive.ExportChanges(newDir, changes) - if err != nil { - log.Fatal(err) - } - defer a.Close() - - i, err := io.Copy(os.Stdout, a) - if err != nil && err != io.EOF { - log.Fatal(err) - } - fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i) -} - -func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) { - fileData := []byte("fooo") - for n := 0; n < numberOfFiles; n++ { - fileName := fmt.Sprintf("file-%d", n) - if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { - return 0, err - } - if makeLinks { - if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil { - return 0, err - } - } - } - totalSize := numberOfFiles * len(fileData) - return totalSize, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/testdata/broken.tar b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/testdata/broken.tar deleted file mode 100644 index 8f10ea6b87..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/testdata/broken.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/time_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/time_linux.go deleted file mode 100644 index 3448569b1e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/time_linux.go +++ /dev/null @@ -1,16 +0,0 @@ -package archive - -import ( - "syscall" - "time" -) - -func timeToTimespec(time time.Time) (ts syscall.Timespec) { - if time.IsZero() { - // Return UTIME_OMIT special value - ts.Sec = 0 - ts.Nsec = ((1 << 30) - 2) - return - } - return syscall.NsecToTimespec(time.UnixNano()) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/time_unsupported.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/time_unsupported.go deleted file mode 100644 index e85aac0540..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/time_unsupported.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build !linux - -package archive - -import ( - "syscall" - "time" -) - -func timeToTimespec(time time.Time) (ts syscall.Timespec) { - nsec := int64(0) - if !time.IsZero() { - nsec = time.UnixNano() - } - return syscall.NsecToTimespec(nsec) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/wrap.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/wrap.go deleted file mode 100644 index b8b60197a3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/archive/wrap.go +++ /dev/null @@ -1,59 +0,0 @@ -package archive - -import ( - "bytes" - "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" - "io/ioutil" -) - -// Generate generates a new archive from the content provided -// as input. -// -// `files` is a sequence of path/content pairs. A new file is -// added to the archive for each pair. -// If the last pair is incomplete, the file is created with an -// empty content. For example: -// -// Generate("foo.txt", "hello world", "emptyfile") -// -// The above call will return an archive with 2 files: -// * ./foo.txt with content "hello world" -// * ./empty with empty content -// -// FIXME: stream content instead of buffering -// FIXME: specify permissions and other archive metadata -func Generate(input ...string) (Archive, error) { - files := parseStringPairs(input...) - buf := new(bytes.Buffer) - tw := tar.NewWriter(buf) - for _, file := range files { - name, content := file[0], file[1] - hdr := &tar.Header{ - Name: name, - Size: int64(len(content)), - } - if err := tw.WriteHeader(hdr); err != nil { - return nil, err - } - if _, err := tw.Write([]byte(content)); err != nil { - return nil, err - } - } - if err := tw.Close(); err != nil { - return nil, err - } - return ioutil.NopCloser(buf), nil -} - -func parseStringPairs(input ...string) (output [][2]string) { - output = make([][2]string, 0, len(input)/2+1) - for i := 0; i < len(input); i += 2 { - var pair [2]string - pair[0] = input[i] - if i+1 < len(input) { - pair[1] = input[i+1] - } - output = append(output, pair) - } - return -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/fileutils/fileutils.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/fileutils/fileutils.go deleted file mode 100644 index 4e4a91b91a..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/fileutils/fileutils.go +++ /dev/null @@ -1,26 +0,0 @@ -package fileutils - -import ( - log "github.com/Sirupsen/logrus" - "path/filepath" -) - -// Matches returns true if relFilePath matches any of the patterns -func Matches(relFilePath string, patterns []string) (bool, error) { - for _, exclude := range patterns { - matched, err := filepath.Match(exclude, relFilePath) - if err != nil { - log.Errorf("Error matching: %s (pattern: %s)", relFilePath, exclude) - return false, err - } - if matched { - if filepath.Clean(relFilePath) == "." { - log.Errorf("Can't exclude whole path, excluding pattern: %s", exclude) - continue - } - log.Debugf("Skipping excluded path: %s", relFilePath) - return true, nil - } - } - return false, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go deleted file mode 100644 index 22f46fbd92..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go +++ /dev/null @@ -1,114 +0,0 @@ -package ioutils - -import ( - "bytes" - "io" - "sync" -) - -type readCloserWrapper struct { - io.Reader - closer func() error -} - -func (r *readCloserWrapper) Close() error { - return r.closer() -} - -func NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser { - return &readCloserWrapper{ - Reader: r, - closer: closer, - } -} - -type readerErrWrapper struct { - reader io.Reader - closer func() -} - -func (r *readerErrWrapper) Read(p []byte) (int, error) { - n, err := r.reader.Read(p) - if err != nil { - r.closer() - } - return n, err -} - -func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader { - return &readerErrWrapper{ - reader: r, - closer: closer, - } -} - -type bufReader struct { - sync.Mutex - buf *bytes.Buffer - reader io.Reader - err error - wait sync.Cond - drainBuf []byte -} - -func NewBufReader(r io.Reader) *bufReader { - reader := &bufReader{ - buf: &bytes.Buffer{}, - drainBuf: make([]byte, 1024), - reader: r, - } - reader.wait.L = &reader.Mutex - go reader.drain() - return reader -} - -func NewBufReaderWithDrainbufAndBuffer(r io.Reader, drainBuffer []byte, buffer *bytes.Buffer) *bufReader { - reader := &bufReader{ - buf: buffer, - drainBuf: drainBuffer, - reader: r, - } - reader.wait.L = &reader.Mutex - go reader.drain() - return reader -} - -func (r *bufReader) drain() { - for { - n, err := r.reader.Read(r.drainBuf) - r.Lock() - if err != nil { - r.err = err - } else { - r.buf.Write(r.drainBuf[0:n]) - } - r.wait.Signal() - r.Unlock() - if err != nil { - break - } - } -} - -func (r *bufReader) Read(p []byte) (n int, err error) { - r.Lock() - defer r.Unlock() - for { - n, err = r.buf.Read(p) - if n > 0 { - return n, err - } - if r.err != nil { - return 0, r.err - } - r.wait.Wait() - } -} - -func (r *bufReader) Close() error { - closer, ok := r.reader.(io.ReadCloser) - if !ok { - return nil - } - return closer.Close() -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go deleted file mode 100644 index a7a2dad176..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package ioutils - -import ( - "bytes" - "io" - "io/ioutil" - "testing" -) - -func TestBufReader(t *testing.T) { - reader, writer := io.Pipe() - bufreader := NewBufReader(reader) - - // Write everything down to a Pipe - // Usually, a pipe should block but because of the buffered reader, - // the writes will go through - done := make(chan bool) - go func() { - writer.Write([]byte("hello world")) - writer.Close() - done <- true - }() - - // Drain the reader *after* everything has been written, just to verify - // it is indeed buffering - <-done - output, err := ioutil.ReadAll(bufreader) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(output, []byte("hello world")) { - t.Error(string(output)) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go deleted file mode 100644 index c0b3608fe6..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go +++ /dev/null @@ -1,39 +0,0 @@ -package ioutils - -import "io" - -type NopWriter struct{} - -func (*NopWriter) Write(buf []byte) (int, error) { - return len(buf), nil -} - -type nopWriteCloser struct { - io.Writer -} - -func (w *nopWriteCloser) Close() error { return nil } - -func NopWriteCloser(w io.Writer) io.WriteCloser { - return &nopWriteCloser{w} -} - -type NopFlusher struct{} - -func (f *NopFlusher) Flush() {} - -type writeCloserWrapper struct { - io.Writer - closer func() error -} - -func (r *writeCloserWrapper) Close() error { - return r.closer() -} - -func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser { - return &writeCloserWrapper{ - Writer: r, - closer: closer, - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/MAINTAINERS deleted file mode 100644 index 8c8902530a..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/MAINTAINERS +++ /dev/null @@ -1 +0,0 @@ -Erik Hollensbe (@erikh) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse.go deleted file mode 100644 index 8b045a3098..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse.go +++ /dev/null @@ -1,85 +0,0 @@ -package filters - -import ( - "encoding/json" - "errors" - "regexp" - "strings" -) - -type Args map[string][]string - -// Parse the argument to the filter flag. Like -// -// `docker ps -f 'created=today' -f 'image.name=ubuntu*'` -// -// If prev map is provided, then it is appended to, and returned. By default a new -// map is created. -func ParseFlag(arg string, prev Args) (Args, error) { - var filters Args = prev - if prev == nil { - filters = Args{} - } - if len(arg) == 0 { - return filters, nil - } - - if !strings.Contains(arg, "=") { - return filters, ErrorBadFormat - } - - f := strings.SplitN(arg, "=", 2) - name := strings.ToLower(strings.TrimSpace(f[0])) - value := strings.TrimSpace(f[1]) - filters[name] = append(filters[name], value) - - return filters, nil -} - -var ErrorBadFormat = errors.New("bad format of filter (expected name=value)") - -// packs the Args into an string for easy transport from client to server -func ToParam(a Args) (string, error) { - // this way we don't URL encode {}, just empty space - if len(a) == 0 { - return "", nil - } - - buf, err := json.Marshal(a) - if err != nil { - return "", err - } - return string(buf), nil -} - -// unpacks the filter Args -func FromParam(p string) (Args, error) { - args := Args{} - if len(p) == 0 { - return args, nil - } - err := json.Unmarshal([]byte(p), &args) - if err != nil { - return nil, err - } - return args, nil -} - -func (filters Args) Match(field, source string) bool { - fieldValues := filters[field] - - //do not filter if there is no filter set or cannot determine filter - if len(fieldValues) == 0 { - return true - } - for _, name2match := range fieldValues { - match, err := regexp.MatchString(name2match, source) - if err != nil { - continue - } - if match { - return true - } - } - return false -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse_test.go deleted file mode 100644 index a248350223..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package filters - -import ( - "sort" - "testing" -) - -func TestParseArgs(t *testing.T) { - // equivalent of `docker ps -f 'created=today' -f 'image.name=ubuntu*' -f 'image.name=*untu'` - flagArgs := []string{ - "created=today", - "image.name=ubuntu*", - "image.name=*untu", - } - var ( - args = Args{} - err error - ) - for i := range flagArgs { - args, err = ParseFlag(flagArgs[i], args) - if err != nil { - t.Errorf("failed to parse %s: %s", flagArgs[i], err) - } - } - if len(args["created"]) != 1 { - t.Errorf("failed to set this arg") - } - if len(args["image.name"]) != 2 { - t.Errorf("the args should have collapsed") - } -} - -func TestParam(t *testing.T) { - a := Args{ - "created": []string{"today"}, - "image.name": []string{"ubuntu*", "*untu"}, - } - - v, err := ToParam(a) - if err != nil { - t.Errorf("failed to marshal the filters: %s", err) - } - v1, err := FromParam(v) - if err != nil { - t.Errorf("%s", err) - } - for key, vals := range v1 { - if _, ok := a[key]; !ok { - t.Errorf("could not find key %s in original set", key) - } - sort.Strings(vals) - sort.Strings(a[key]) - if len(vals) != len(a[key]) { - t.Errorf("value lengths ought to match") - continue - } - for i := range vals { - if vals[i] != a[key][i] { - t.Errorf("expected %s, but got %s", a[key][i], vals[i]) - } - } - } -} - -func TestEmpty(t *testing.T) { - a := Args{} - v, err := ToParam(a) - if err != nil { - t.Errorf("failed to marshal the filters: %s", err) - } - v1, err := FromParam(v) - if err != nil { - t.Errorf("%s", err) - } - if len(a) != len(v1) { - t.Errorf("these should both be empty sets") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go deleted file mode 100644 index 70d09003a3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go +++ /dev/null @@ -1,93 +0,0 @@ -package kernel - -import ( - "bytes" - "errors" - "fmt" -) - -type KernelVersionInfo struct { - Kernel int - Major int - Minor int - Flavor string -} - -func (k *KernelVersionInfo) String() string { - return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor) -} - -// Compare two KernelVersionInfo struct. -// Returns -1 if a < b, 0 if a == b, 1 it a > b -func CompareKernelVersion(a, b *KernelVersionInfo) int { - if a.Kernel < b.Kernel { - return -1 - } else if a.Kernel > b.Kernel { - return 1 - } - - if a.Major < b.Major { - return -1 - } else if a.Major > b.Major { - return 1 - } - - if a.Minor < b.Minor { - return -1 - } else if a.Minor > b.Minor { - return 1 - } - - return 0 -} - -func GetKernelVersion() (*KernelVersionInfo, error) { - var ( - err error - ) - - uts, err := uname() - if err != nil { - return nil, err - } - - release := make([]byte, len(uts.Release)) - - i := 0 - for _, c := range uts.Release { - release[i] = byte(c) - i++ - } - - // Remove the \x00 from the release for Atoi to parse correctly - release = release[:bytes.IndexByte(release, 0)] - - return ParseRelease(string(release)) -} - -func ParseRelease(release string) (*KernelVersionInfo, error) { - var ( - kernel, major, minor, parsed int - flavor, partial string - ) - - // Ignore error from Sscanf to allow an empty flavor. Instead, just - // make sure we got all the version numbers. - parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial) - if parsed < 2 { - return nil, errors.New("Can't parse kernel version " + release) - } - - // sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64 - parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor) - if parsed < 1 { - flavor = partial - } - - return &KernelVersionInfo{ - Kernel: kernel, - Major: major, - Minor: minor, - Flavor: flavor, - }, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_test.go deleted file mode 100644 index e211a63b7d..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package kernel - -import ( - "testing" -) - -func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) { - var ( - a *KernelVersionInfo - ) - a, _ = ParseRelease(release) - - if r := CompareKernelVersion(a, b); r != result { - t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result) - } - if a.Flavor != b.Flavor { - t.Fatalf("Unexpected parsed kernel flavor. Found %s, expected %s", a.Flavor, b.Flavor) - } -} - -func TestParseRelease(t *testing.T) { - assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0) - assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0) - assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0) - assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0) - assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0) - assertParseRelease(t, "3.12-1-amd64", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0) -} - -func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) { - if r := CompareKernelVersion(a, b); r != result { - t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result) - } -} - -func TestCompareKernelVersion(t *testing.T) { - assertKernelVersion(t, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - 0) - assertKernelVersion(t, - &KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0}, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - -1) - assertKernelVersion(t, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - &KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0}, - 1) - assertKernelVersion(t, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - 0) - assertKernelVersion(t, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5}, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - 1) - assertKernelVersion(t, - &KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20}, - &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, - -1) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go deleted file mode 100644 index 8ca814c1fb..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go +++ /dev/null @@ -1,16 +0,0 @@ -package kernel - -import ( - "syscall" -) - -type Utsname syscall.Utsname - -func uname() (*syscall.Utsname, error) { - uts := &syscall.Utsname{} - - if err := syscall.Uname(uts); err != nil { - return nil, err - } - return uts, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go deleted file mode 100644 index 00c5422589..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !linux - -package kernel - -import ( - "errors" -) - -type Utsname struct { - Release [65]byte -} - -func uname() (*Utsname, error) { - return nil, errors.New("Kernel version detection is available only on linux") -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem.go deleted file mode 100644 index af185f9f6b..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem.go +++ /dev/null @@ -1,40 +0,0 @@ -package operatingsystem - -import ( - "bytes" - "errors" - "io/ioutil" -) - -var ( - // file to use to detect if the daemon is running in a container - proc1Cgroup = "/proc/1/cgroup" - - // file to check to determine Operating System - etcOsRelease = "/etc/os-release" -) - -func GetOperatingSystem() (string, error) { - b, err := ioutil.ReadFile(etcOsRelease) - if err != nil { - return "", err - } - if i := bytes.Index(b, []byte("PRETTY_NAME")); i >= 0 { - b = b[i+13:] - return string(b[:bytes.IndexByte(b, '"')]), nil - } - return "", errors.New("PRETTY_NAME not found") -} - -func IsContainerized() (bool, error) { - b, err := ioutil.ReadFile(proc1Cgroup) - if err != nil { - return false, err - } - for _, line := range bytes.Split(b, []byte{'\n'}) { - if len(line) > 0 && !bytes.HasSuffix(line, []byte{'/'}) { - return true, nil - } - } - return false, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_test.go deleted file mode 100644 index b7d54cbb1c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_test.go +++ /dev/null @@ -1,124 +0,0 @@ -package operatingsystem - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -func TestGetOperatingSystem(t *testing.T) { - var ( - backup = etcOsRelease - ubuntuTrusty = []byte(`NAME="Ubuntu" -VERSION="14.04, Trusty Tahr" -ID=ubuntu -ID_LIKE=debian -PRETTY_NAME="Ubuntu 14.04 LTS" -VERSION_ID="14.04" -HOME_URL="http://www.ubuntu.com/" -SUPPORT_URL="http://help.ubuntu.com/" -BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`) - gentoo = []byte(`NAME=Gentoo -ID=gentoo -PRETTY_NAME="Gentoo/Linux" -ANSI_COLOR="1;32" -HOME_URL="http://www.gentoo.org/" -SUPPORT_URL="http://www.gentoo.org/main/en/support.xml" -BUG_REPORT_URL="https://bugs.gentoo.org/" -`) - noPrettyName = []byte(`NAME="Ubuntu" -VERSION="14.04, Trusty Tahr" -ID=ubuntu -ID_LIKE=debian -VERSION_ID="14.04" -HOME_URL="http://www.ubuntu.com/" -SUPPORT_URL="http://help.ubuntu.com/" -BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`) - ) - - dir := os.TempDir() - etcOsRelease = filepath.Join(dir, "etcOsRelease") - - defer func() { - os.Remove(etcOsRelease) - etcOsRelease = backup - }() - - for expect, osRelease := range map[string][]byte{ - "Ubuntu 14.04 LTS": ubuntuTrusty, - "Gentoo/Linux": gentoo, - "": noPrettyName, - } { - if err := ioutil.WriteFile(etcOsRelease, osRelease, 0600); err != nil { - t.Fatalf("failed to write to %s: %v", etcOsRelease, err) - } - s, err := GetOperatingSystem() - if s != expect { - if expect == "" { - t.Fatalf("Expected error 'PRETTY_NAME not found', but got %v", err) - } else { - t.Fatalf("Expected '%s', but got '%s'. Err=%v", expect, s, err) - } - } - } -} - -func TestIsContainerized(t *testing.T) { - var ( - backup = proc1Cgroup - nonContainerizedProc1Cgroup = []byte(`14:name=systemd:/ -13:hugetlb:/ -12:net_prio:/ -11:perf_event:/ -10:bfqio:/ -9:blkio:/ -8:net_cls:/ -7:freezer:/ -6:devices:/ -5:memory:/ -4:cpuacct:/ -3:cpu:/ -2:cpuset:/ -`) - containerizedProc1Cgroup = []byte(`9:perf_event:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -8:blkio:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -7:net_cls:/ -6:freezer:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -5:devices:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -4:memory:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -3:cpuacct:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -2:cpu:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d -1:cpuset:/`) - ) - - dir := os.TempDir() - proc1Cgroup = filepath.Join(dir, "proc1Cgroup") - - defer func() { - os.Remove(proc1Cgroup) - proc1Cgroup = backup - }() - - if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil { - t.Fatalf("failed to write to %s: %v", proc1Cgroup, err) - } - inContainer, err := IsContainerized() - if err != nil { - t.Fatal(err) - } - if inContainer { - t.Fatal("Wrongly assuming containerized") - } - - if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil { - t.Fatalf("failed to write to %s: %v", proc1Cgroup, err) - } - inContainer, err = IsContainerized() - if err != nil { - t.Fatal(err) - } - if !inContainer { - t.Fatal("Wrongly assuming non-containerized") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers.go deleted file mode 100644 index e6e3718b40..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers.go +++ /dev/null @@ -1,110 +0,0 @@ -package parsers - -import ( - "fmt" - "strconv" - "strings" -) - -// FIXME: Change this not to receive default value as parameter -func ParseHost(defaultHost string, defaultUnix, addr string) (string, error) { - var ( - proto string - host string - port int - ) - addr = strings.TrimSpace(addr) - switch { - case addr == "tcp://": - return "", fmt.Errorf("Invalid bind address format: %s", addr) - case strings.HasPrefix(addr, "unix://"): - proto = "unix" - addr = strings.TrimPrefix(addr, "unix://") - if addr == "" { - addr = defaultUnix - } - case strings.HasPrefix(addr, "tcp://"): - proto = "tcp" - addr = strings.TrimPrefix(addr, "tcp://") - case strings.HasPrefix(addr, "fd://"): - return addr, nil - case addr == "": - proto = "unix" - addr = defaultUnix - default: - if strings.Contains(addr, "://") { - return "", fmt.Errorf("Invalid bind address protocol: %s", addr) - } - proto = "tcp" - } - - if proto != "unix" && strings.Contains(addr, ":") { - hostParts := strings.Split(addr, ":") - if len(hostParts) != 2 { - return "", fmt.Errorf("Invalid bind address format: %s", addr) - } - if hostParts[0] != "" { - host = hostParts[0] - } else { - host = defaultHost - } - - if p, err := strconv.Atoi(hostParts[1]); err == nil && p != 0 { - port = p - } else { - return "", fmt.Errorf("Invalid bind address format: %s", addr) - } - - } else if proto == "tcp" && !strings.Contains(addr, ":") { - return "", fmt.Errorf("Invalid bind address format: %s", addr) - } else { - host = addr - } - if proto == "unix" { - return fmt.Sprintf("%s://%s", proto, host), nil - } - return fmt.Sprintf("%s://%s:%d", proto, host, port), nil -} - -// Get a repos name and returns the right reposName + tag -// The tag can be confusing because of a port in a repository name. -// Ex: localhost.localdomain:5000/samalba/hipache:latest -func ParseRepositoryTag(repos string) (string, string) { - n := strings.LastIndex(repos, ":") - if n < 0 { - return repos, "" - } - if tag := repos[n+1:]; !strings.Contains(tag, "/") { - return repos[:n], tag - } - return repos, "" -} - -func PartParser(template, data string) (map[string]string, error) { - // ip:public:private - var ( - templateParts = strings.Split(template, ":") - parts = strings.Split(data, ":") - out = make(map[string]string, len(templateParts)) - ) - if len(parts) != len(templateParts) { - return nil, fmt.Errorf("Invalid format to parse. %s should match template %s", data, template) - } - - for i, t := range templateParts { - value := "" - if len(parts) > i { - value = parts[i] - } - out[t] = value - } - return out, nil -} - -func ParseKeyValueOpt(opt string) (string, string, error) { - parts := strings.SplitN(opt, "=", 2) - if len(parts) != 2 { - return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt) - } - return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers_test.go deleted file mode 100644 index 12b8df5708..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package parsers - -import ( - "testing" -) - -func TestParseHost(t *testing.T) { - var ( - defaultHttpHost = "127.0.0.1" - defaultUnix = "/var/run/docker.sock" - ) - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.0"); err == nil { - t.Errorf("tcp 0.0.0.0 address expected error return, but err == nil, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://"); err == nil { - t.Errorf("default tcp:// address expected error return, but err == nil, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.1:5555"); err != nil || addr != "tcp://0.0.0.1:5555" { - t.Errorf("0.0.0.1:5555 -> expected tcp://0.0.0.1:5555, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, ":6666"); err != nil || addr != "tcp://127.0.0.1:6666" { - t.Errorf(":6666 -> expected tcp://127.0.0.1:6666, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://:7777"); err != nil || addr != "tcp://127.0.0.1:7777" { - t.Errorf("tcp://:7777 -> expected tcp://127.0.0.1:7777, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, ""); err != nil || addr != "unix:///var/run/docker.sock" { - t.Errorf("empty argument -> expected unix:///var/run/docker.sock, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix:///var/run/docker.sock"); err != nil || addr != "unix:///var/run/docker.sock" { - t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix://"); err != nil || addr != "unix:///var/run/docker.sock" { - t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1"); err == nil { - t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr) - } - if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1:2375"); err == nil { - t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr) - } -} - -func TestParseRepositoryTag(t *testing.T) { - if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" { - t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag) - } - if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" { - t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag) - } - if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" { - t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag) - } - if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" { - t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag) - } - if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" { - t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag) - } - if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" { - t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag) - } -} - -func TestParsePortMapping(t *testing.T) { - data, err := PartParser("ip:public:private", "192.168.1.1:80:8080") - if err != nil { - t.Fatal(err) - } - - if len(data) != 3 { - t.FailNow() - } - if data["ip"] != "192.168.1.1" { - t.Fail() - } - if data["public"] != "80" { - t.Fail() - } - if data["private"] != "8080" { - t.Fail() - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools.go deleted file mode 100644 index 5338a0cfb2..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools.go +++ /dev/null @@ -1,111 +0,0 @@ -// +build go1.3 - -// Package pools provides a collection of pools which provide various -// data types with buffers. These can be used to lower the number of -// memory allocations and reuse buffers. -// -// New pools should be added to this package to allow them to be -// shared across packages. -// -// Utility functions which operate on pools should be added to this -// package to allow them to be reused. -package pools - -import ( - "bufio" - "io" - "sync" - - "github.com/docker/docker/pkg/ioutils" -) - -var ( - // Pool which returns bufio.Reader with a 32K buffer - BufioReader32KPool *BufioReaderPool - // Pool which returns bufio.Writer with a 32K buffer - BufioWriter32KPool *BufioWriterPool -) - -const buffer32K = 32 * 1024 - -type BufioReaderPool struct { - pool sync.Pool -} - -func init() { - BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K) - BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K) -} - -// newBufioReaderPoolWithSize is unexported because new pools should be -// added here to be shared where required. -func newBufioReaderPoolWithSize(size int) *BufioReaderPool { - pool := sync.Pool{ - New: func() interface{} { return bufio.NewReaderSize(nil, size) }, - } - return &BufioReaderPool{pool: pool} -} - -// Get returns a bufio.Reader which reads from r. The buffer size is that of the pool. -func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader { - buf := bufPool.pool.Get().(*bufio.Reader) - buf.Reset(r) - return buf -} - -// Put puts the bufio.Reader back into the pool. -func (bufPool *BufioReaderPool) Put(b *bufio.Reader) { - b.Reset(nil) - bufPool.pool.Put(b) -} - -// NewReadCloserWrapper returns a wrapper which puts the bufio.Reader back -// into the pool and closes the reader if it's an io.ReadCloser. -func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser { - return ioutils.NewReadCloserWrapper(r, func() error { - if readCloser, ok := r.(io.ReadCloser); ok { - readCloser.Close() - } - bufPool.Put(buf) - return nil - }) -} - -type BufioWriterPool struct { - pool sync.Pool -} - -// newBufioWriterPoolWithSize is unexported because new pools should be -// added here to be shared where required. -func newBufioWriterPoolWithSize(size int) *BufioWriterPool { - pool := sync.Pool{ - New: func() interface{} { return bufio.NewWriterSize(nil, size) }, - } - return &BufioWriterPool{pool: pool} -} - -// Get returns a bufio.Writer which writes to w. The buffer size is that of the pool. -func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer { - buf := bufPool.pool.Get().(*bufio.Writer) - buf.Reset(w) - return buf -} - -// Put puts the bufio.Writer back into the pool. -func (bufPool *BufioWriterPool) Put(b *bufio.Writer) { - b.Reset(nil) - bufPool.pool.Put(b) -} - -// NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back -// into the pool and closes the writer if it's an io.Writecloser. -func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser { - return ioutils.NewWriteCloserWrapper(w, func() error { - buf.Flush() - if writeCloser, ok := w.(io.WriteCloser); ok { - writeCloser.Close() - } - bufPool.Put(buf) - return nil - }) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools_nopool.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools_nopool.go deleted file mode 100644 index 48903c2396..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools_nopool.go +++ /dev/null @@ -1,73 +0,0 @@ -// +build !go1.3 - -package pools - -import ( - "bufio" - "io" - - "github.com/docker/docker/pkg/ioutils" -) - -var ( - BufioReader32KPool *BufioReaderPool - BufioWriter32KPool *BufioWriterPool -) - -const buffer32K = 32 * 1024 - -type BufioReaderPool struct { - size int -} - -func init() { - BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K) - BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K) -} - -func newBufioReaderPoolWithSize(size int) *BufioReaderPool { - return &BufioReaderPool{size: size} -} - -func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader { - return bufio.NewReaderSize(r, bufPool.size) -} - -func (bufPool *BufioReaderPool) Put(b *bufio.Reader) { - b.Reset(nil) -} - -func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser { - return ioutils.NewReadCloserWrapper(r, func() error { - if readCloser, ok := r.(io.ReadCloser); ok { - return readCloser.Close() - } - return nil - }) -} - -type BufioWriterPool struct { - size int -} - -func newBufioWriterPoolWithSize(size int) *BufioWriterPool { - return &BufioWriterPool{size: size} -} - -func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer { - return bufio.NewWriterSize(w, bufPool.size) -} - -func (bufPool *BufioWriterPool) Put(b *bufio.Writer) { - b.Reset(nil) -} - -func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser { - return ioutils.NewWriteCloserWrapper(w, func() error { - buf.Flush() - if writeCloser, ok := w.(io.WriteCloser); ok { - return writeCloser.Close() - } - return nil - }) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/promise/promise.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/promise/promise.go deleted file mode 100644 index dd52b9082f..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/promise/promise.go +++ /dev/null @@ -1,11 +0,0 @@ -package promise - -// Go is a basic promise implementation: it wraps calls a function in a goroutine, -// and returns a channel which will later return the function's return value. -func Go(f func() error) chan error { - ch := make(chan error, 1) - go func() { - ch <- f() - }() - return ch -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/MAINTAINERS deleted file mode 100644 index 68a97d2fc2..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Michael Crosby (@crosbymichael) -Victor Vieux (@vieux) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/errors.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/errors.go deleted file mode 100644 index 63045186fe..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/errors.go +++ /dev/null @@ -1,9 +0,0 @@ -package system - -import ( - "errors" -) - -var ( - ErrNotSupportedPlatform = errors.New("platform and architecture is not supported") -) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat.go deleted file mode 100644 index 9ef82d5523..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build !windows - -package system - -import ( - "syscall" -) - -func Lstat(path string) (*Stat, error) { - s := &syscall.Stat_t{} - err := syscall.Lstat(path, s) - if err != nil { - return nil, err - } - return fromStatT(s) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat_test.go deleted file mode 100644 index 9bab4d7b0c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package system - -import ( - "os" - "testing" -) - -func TestLstat(t *testing.T) { - file, invalid, _, dir := prepareFiles(t) - defer os.RemoveAll(dir) - - statFile, err := Lstat(file) - if err != nil { - t.Fatal(err) - } - if statFile == nil { - t.Fatal("returned empty stat for existing file") - } - - statInvalid, err := Lstat(invalid) - if err == nil { - t.Fatal("did not return error for non-existing file") - } - if statInvalid != nil { - t.Fatal("returned non-nil stat for non-existing file") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat_windows.go deleted file mode 100644 index 213a7c7ade..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/lstat_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build windows - -package system - -func Lstat(path string) (*Stat, error) { - // should not be called on cli code path - return nil, ErrNotSupportedPlatform -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo.go deleted file mode 100644 index 3b6e947e67..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo.go +++ /dev/null @@ -1,17 +0,0 @@ -package system - -// MemInfo contains memory statistics of the host system. -type MemInfo struct { - // Total usable RAM (i.e. physical RAM minus a few reserved bits and the - // kernel binary code). - MemTotal int64 - - // Amount of free memory. - MemFree int64 - - // Total amount of swap space available. - SwapTotal int64 - - // Amount of swap space that is currently unused. - SwapFree int64 -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_linux.go deleted file mode 100644 index b7de3ff776..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_linux.go +++ /dev/null @@ -1,67 +0,0 @@ -package system - -import ( - "bufio" - "errors" - "io" - "os" - "strconv" - "strings" - - "github.com/docker/docker/pkg/units" -) - -var ( - ErrMalformed = errors.New("malformed file") -) - -// Retrieve memory statistics of the host system and parse them into a MemInfo -// type. -func ReadMemInfo() (*MemInfo, error) { - file, err := os.Open("/proc/meminfo") - if err != nil { - return nil, err - } - defer file.Close() - return parseMemInfo(file) -} - -func parseMemInfo(reader io.Reader) (*MemInfo, error) { - meminfo := &MemInfo{} - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - // Expected format: ["MemTotal:", "1234", "kB"] - parts := strings.Fields(scanner.Text()) - - // Sanity checks: Skip malformed entries. - if len(parts) < 3 || parts[2] != "kB" { - continue - } - - // Convert to bytes. - size, err := strconv.Atoi(parts[1]) - if err != nil { - continue - } - bytes := int64(size) * units.KiB - - switch parts[0] { - case "MemTotal:": - meminfo.MemTotal = bytes - case "MemFree:": - meminfo.MemFree = bytes - case "SwapTotal:": - meminfo.SwapTotal = bytes - case "SwapFree:": - meminfo.SwapFree = bytes - } - - } - - // Handle errors that may have occurred during the reading of the file. - if err := scanner.Err(); err != nil { - return nil, err - } - - return meminfo, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_linux_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_linux_test.go deleted file mode 100644 index 377405ea69..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_linux_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package system - -import ( - "strings" - "testing" - - "github.com/docker/docker/pkg/units" -) - -func TestMemInfo(t *testing.T) { - const input = ` - MemTotal: 1 kB - MemFree: 2 kB - SwapTotal: 3 kB - SwapFree: 4 kB - Malformed1: - Malformed2: 1 - Malformed3: 2 MB - Malformed4: X kB - ` - meminfo, err := parseMemInfo(strings.NewReader(input)) - if err != nil { - t.Fatal(err) - } - if meminfo.MemTotal != 1*units.KiB { - t.Fatalf("Unexpected MemTotal: %d", meminfo.MemTotal) - } - if meminfo.MemFree != 2*units.KiB { - t.Fatalf("Unexpected MemFree: %d", meminfo.MemFree) - } - if meminfo.SwapTotal != 3*units.KiB { - t.Fatalf("Unexpected SwapTotal: %d", meminfo.SwapTotal) - } - if meminfo.SwapFree != 4*units.KiB { - t.Fatalf("Unexpected SwapFree: %d", meminfo.SwapFree) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_unsupported.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_unsupported.go deleted file mode 100644 index 63b8b16e05..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/meminfo_unsupported.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !linux - -package system - -func ReadMemInfo() (*MemInfo, error) { - return nil, ErrNotSupportedPlatform -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/mknod.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/mknod.go deleted file mode 100644 index 06f9c6afbb..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/mknod.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build !windows - -package system - -import ( - "syscall" -) - -func Mknod(path string, mode uint32, dev int) error { - return syscall.Mknod(path, mode, dev) -} - -// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes. -// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major, -// then the top 12 bits of the minor -func Mkdev(major int64, minor int64) uint32 { - return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff)) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/mknod_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/mknod_windows.go deleted file mode 100644 index b4020c11b6..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/mknod_windows.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build windows - -package system - -func Mknod(path string, mode uint32, dev int) error { - // should not be called on cli code path - return ErrNotSupportedPlatform -} - -func Mkdev(major int64, minor int64) uint32 { - panic("Mkdev not implemented on windows, should not be called on cli code") -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat.go deleted file mode 100644 index 5d47494d21..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat.go +++ /dev/null @@ -1,42 +0,0 @@ -package system - -import ( - "syscall" -) - -type Stat struct { - mode uint32 - uid uint32 - gid uint32 - rdev uint64 - size int64 - mtim syscall.Timespec -} - -func (s Stat) Mode() uint32 { - return s.mode -} - -func (s Stat) Uid() uint32 { - return s.uid -} - -func (s Stat) Gid() uint32 { - return s.gid -} - -func (s Stat) Rdev() uint64 { - return s.rdev -} - -func (s Stat) Size() int64 { - return s.size -} - -func (s Stat) Mtim() syscall.Timespec { - return s.mtim -} - -func (s Stat) GetLastModification() syscall.Timespec { - return s.Mtim() -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_linux.go deleted file mode 100644 index 47cebef5cf..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_linux.go +++ /dev/null @@ -1,14 +0,0 @@ -package system - -import ( - "syscall" -) - -func fromStatT(s *syscall.Stat_t) (*Stat, error) { - return &Stat{size: s.Size, - mode: s.Mode, - uid: s.Uid, - gid: s.Gid, - rdev: s.Rdev, - mtim: s.Mtim}, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_test.go deleted file mode 100644 index abcc8ea7a6..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package system - -import ( - "os" - "syscall" - "testing" -) - -func TestFromStatT(t *testing.T) { - file, _, _, dir := prepareFiles(t) - defer os.RemoveAll(dir) - - stat := &syscall.Stat_t{} - err := syscall.Lstat(file, stat) - - s, err := fromStatT(stat) - if err != nil { - t.Fatal(err) - } - - if stat.Mode != s.Mode() { - t.Fatal("got invalid mode") - } - if stat.Uid != s.Uid() { - t.Fatal("got invalid uid") - } - if stat.Gid != s.Gid() { - t.Fatal("got invalid gid") - } - if stat.Rdev != s.Rdev() { - t.Fatal("got invalid rdev") - } - if stat.Mtim != s.Mtim() { - t.Fatal("got invalid mtim") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_unsupported.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_unsupported.go deleted file mode 100644 index c4d53e6cd6..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_unsupported.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build !linux,!windows - -package system - -import ( - "syscall" -) - -func fromStatT(s *syscall.Stat_t) (*Stat, error) { - return &Stat{size: s.Size, - mode: uint32(s.Mode), - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtimespec}, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_windows.go deleted file mode 100644 index 584e8940cc..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_windows.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build windows - -package system - -import ( - "errors" - "syscall" -) - -func fromStatT(s *syscall.Win32FileAttributeData) (*Stat, error) { - return nil, errors.New("fromStatT should not be called on windows path") -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/umask.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/umask.go deleted file mode 100644 index fddbecd390..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/umask.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !windows - -package system - -import ( - "syscall" -) - -func Umask(newmask int) (oldmask int, err error) { - return syscall.Umask(newmask), nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/umask_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/umask_windows.go deleted file mode 100644 index 3be563f89e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/umask_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build windows - -package system - -func Umask(newmask int) (oldmask int, err error) { - // should not be called on cli code path - return 0, ErrNotSupportedPlatform -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go deleted file mode 100644 index 4c6002fe8e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go +++ /dev/null @@ -1,11 +0,0 @@ -package system - -import "syscall" - -func LUtimesNano(path string, ts []syscall.Timespec) error { - return ErrNotSupportedPlatform -} - -func UtimesNano(path string, ts []syscall.Timespec) error { - return syscall.UtimesNano(path, ts) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_freebsd.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_freebsd.go deleted file mode 100644 index ceaa044c1c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_freebsd.go +++ /dev/null @@ -1,24 +0,0 @@ -package system - -import ( - "syscall" - "unsafe" -) - -func LUtimesNano(path string, ts []syscall.Timespec) error { - var _path *byte - _path, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - - if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS { - return err - } - - return nil -} - -func UtimesNano(path string, ts []syscall.Timespec) error { - return syscall.UtimesNano(path, ts) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_linux.go deleted file mode 100644 index 8f90298271..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_linux.go +++ /dev/null @@ -1,28 +0,0 @@ -package system - -import ( - "syscall" - "unsafe" -) - -func LUtimesNano(path string, ts []syscall.Timespec) error { - // These are not currently available in syscall - AT_FDCWD := -100 - AT_SYMLINK_NOFOLLOW := 0x100 - - var _path *byte - _path, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - - if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(AT_FDCWD), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(AT_SYMLINK_NOFOLLOW), 0, 0); err != 0 && err != syscall.ENOSYS { - return err - } - - return nil -} - -func UtimesNano(path string, ts []syscall.Timespec) error { - return syscall.UtimesNano(path, ts) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_test.go deleted file mode 100644 index 1dea47cc15..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package system - -import ( - "io/ioutil" - "os" - "path/filepath" - "syscall" - "testing" -) - -func prepareFiles(t *testing.T) (string, string, string, string) { - dir, err := ioutil.TempDir("", "docker-system-test") - if err != nil { - t.Fatal(err) - } - - file := filepath.Join(dir, "exist") - if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil { - t.Fatal(err) - } - - invalid := filepath.Join(dir, "doesnt-exist") - - symlink := filepath.Join(dir, "symlink") - if err := os.Symlink(file, symlink); err != nil { - t.Fatal(err) - } - - return file, invalid, symlink, dir -} - -func TestLUtimesNano(t *testing.T) { - file, invalid, symlink, dir := prepareFiles(t) - defer os.RemoveAll(dir) - - before, err := os.Stat(file) - if err != nil { - t.Fatal(err) - } - - ts := []syscall.Timespec{{0, 0}, {0, 0}} - if err := LUtimesNano(symlink, ts); err != nil { - t.Fatal(err) - } - - symlinkInfo, err := os.Lstat(symlink) - if err != nil { - t.Fatal(err) - } - if before.ModTime().Unix() == symlinkInfo.ModTime().Unix() { - t.Fatal("The modification time of the symlink should be different") - } - - fileInfo, err := os.Stat(file) - if err != nil { - t.Fatal(err) - } - if before.ModTime().Unix() != fileInfo.ModTime().Unix() { - t.Fatal("The modification time of the file should be same") - } - - if err := LUtimesNano(invalid, ts); err == nil { - t.Fatal("Doesn't return an error on a non-existing file") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_unsupported.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_unsupported.go deleted file mode 100644 index adf2734f27..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_unsupported.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !linux,!freebsd,!darwin - -package system - -import "syscall" - -func LUtimesNano(path string, ts []syscall.Timespec) error { - return ErrNotSupportedPlatform -} - -func UtimesNano(path string, ts []syscall.Timespec) error { - return ErrNotSupportedPlatform -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/xattrs_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/xattrs_linux.go deleted file mode 100644 index 00edb201b5..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/xattrs_linux.go +++ /dev/null @@ -1,59 +0,0 @@ -package system - -import ( - "syscall" - "unsafe" -) - -// Returns a nil slice and nil error if the xattr is not set -func Lgetxattr(path string, attr string) ([]byte, error) { - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return nil, err - } - attrBytes, err := syscall.BytePtrFromString(attr) - if err != nil { - return nil, err - } - - dest := make([]byte, 128) - destBytes := unsafe.Pointer(&dest[0]) - sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) - if errno == syscall.ENODATA { - return nil, nil - } - if errno == syscall.ERANGE { - dest = make([]byte, sz) - destBytes := unsafe.Pointer(&dest[0]) - sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) - } - if errno != 0 { - return nil, errno - } - - return dest[:sz], nil -} - -var _zero uintptr - -func Lsetxattr(path string, attr string, data []byte, flags int) error { - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - attrBytes, err := syscall.BytePtrFromString(attr) - if err != nil { - return err - } - var dataBytes unsafe.Pointer - if len(data) > 0 { - dataBytes = unsafe.Pointer(&data[0]) - } else { - dataBytes = unsafe.Pointer(&_zero) - } - _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) - if errno != 0 { - return errno - } - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/xattrs_unsupported.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/system/xattrs_unsupported.go deleted file mode 100644 index 0060c167dc..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/system/xattrs_unsupported.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !linux - -package system - -func Lgetxattr(path string, attr string) ([]byte, error) { - return nil, ErrNotSupportedPlatform -} - -func Lsetxattr(path string, attr string, data []byte, flags int) error { - return ErrNotSupportedPlatform -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/MAINTAINERS deleted file mode 100644 index aee10c8421..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/MAINTAINERS +++ /dev/null @@ -1 +0,0 @@ -Solomon Hykes (@shykes) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/console_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/console_windows.go deleted file mode 100644 index 6335b2b837..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/console_windows.go +++ /dev/null @@ -1,87 +0,0 @@ -// +build windows - -package term - -import ( - "syscall" - "unsafe" -) - -const ( - // Consts for Get/SetConsoleMode function - // see http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx - ENABLE_ECHO_INPUT = 0x0004 - ENABLE_INSERT_MODE = 0x0020 - ENABLE_LINE_INPUT = 0x0002 - ENABLE_MOUSE_INPUT = 0x0010 - ENABLE_PROCESSED_INPUT = 0x0001 - ENABLE_QUICK_EDIT_MODE = 0x0040 - ENABLE_WINDOW_INPUT = 0x0008 - // If parameter is a screen buffer handle, additional values - ENABLE_PROCESSED_OUTPUT = 0x0001 - ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 -) - -var kernel32DLL = syscall.NewLazyDLL("kernel32.dll") - -var ( - setConsoleModeProc = kernel32DLL.NewProc("SetConsoleMode") - getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") -) - -func GetConsoleMode(fileDesc uintptr) (uint32, error) { - var mode uint32 - err := syscall.GetConsoleMode(syscall.Handle(fileDesc), &mode) - return mode, err -} - -func SetConsoleMode(fileDesc uintptr, mode uint32) error { - r, _, err := setConsoleModeProc.Call(fileDesc, uintptr(mode), 0) - if r == 0 { - if err != nil { - return err - } - return syscall.EINVAL - } - return nil -} - -// types for calling GetConsoleScreenBufferInfo -// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx -type ( - SHORT int16 - - SMALL_RECT struct { - Left SHORT - Top SHORT - Right SHORT - Bottom SHORT - } - - COORD struct { - X SHORT - Y SHORT - } - - WORD uint16 - - CONSOLE_SCREEN_BUFFER_INFO struct { - dwSize COORD - dwCursorPosition COORD - wAttributes WORD - srWindow SMALL_RECT - dwMaximumWindowSize COORD - } -) - -func GetConsoleScreenBufferInfo(fileDesc uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) { - var info CONSOLE_SCREEN_BUFFER_INFO - r, _, err := getConsoleScreenBufferInfoProc.Call(uintptr(fileDesc), uintptr(unsafe.Pointer(&info)), 0) - if r == 0 { - if err != nil { - return nil, err - } - return nil, syscall.EINVAL - } - return &info, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go deleted file mode 100644 index 553747a7a0..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go +++ /dev/null @@ -1,105 +0,0 @@ -// +build !windows - -package term - -import ( - "errors" - "os" - "os/signal" - "syscall" - "unsafe" -) - -var ( - ErrInvalidState = errors.New("Invalid terminal state") -) - -type State struct { - termios Termios -} - -type Winsize struct { - Height uint16 - Width uint16 - x uint16 - y uint16 -} - -func GetWinsize(fd uintptr) (*Winsize, error) { - ws := &Winsize{} - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws))) - // Skipp errno = 0 - if err == 0 { - return ws, nil - } - return ws, err -} - -func SetWinsize(fd uintptr, ws *Winsize) error { - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) - // Skipp errno = 0 - if err == 0 { - return nil - } - return err -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd uintptr) bool { - var termios Termios - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&termios))) - return err == 0 -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func RestoreTerminal(fd uintptr, state *State) error { - if state == nil { - return ErrInvalidState - } - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios))) - if err != 0 { - return err - } - return nil -} - -func SaveState(fd uintptr) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { - return nil, err - } - - return &oldState, nil -} - -func DisableEcho(fd uintptr, state *State) error { - newState := state.termios - newState.Lflag &^= syscall.ECHO - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { - return err - } - handleInterrupt(fd, state) - return nil -} - -func SetRawTerminal(fd uintptr) (*State, error) { - oldState, err := MakeRaw(fd) - if err != nil { - return nil, err - } - handleInterrupt(fd, oldState) - return oldState, err -} - -func handleInterrupt(fd uintptr, state *State) { - sigchan := make(chan os.Signal, 1) - signal.Notify(sigchan, os.Interrupt) - - go func() { - _ = <-sigchan - RestoreTerminal(fd, state) - os.Exit(0) - }() -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go deleted file mode 100644 index d372e86a88..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go +++ /dev/null @@ -1,89 +0,0 @@ -// +build windows - -package term - -type State struct { - mode uint32 -} - -type Winsize struct { - Height uint16 - Width uint16 - x uint16 - y uint16 -} - -func GetWinsize(fd uintptr) (*Winsize, error) { - ws := &Winsize{} - var info *CONSOLE_SCREEN_BUFFER_INFO - info, err := GetConsoleScreenBufferInfo(fd) - if err != nil { - return nil, err - } - ws.Height = uint16(info.srWindow.Right - info.srWindow.Left + 1) - ws.Width = uint16(info.srWindow.Bottom - info.srWindow.Top + 1) - - ws.x = 0 // todo azlinux -- this is the pixel size of the Window, and not currently used by any caller - ws.y = 0 - - return ws, nil -} - -func SetWinsize(fd uintptr, ws *Winsize) error { - return nil -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd uintptr) bool { - _, e := GetConsoleMode(fd) - return e == nil -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func RestoreTerminal(fd uintptr, state *State) error { - return SetConsoleMode(fd, state.mode) -} - -func SaveState(fd uintptr) (*State, error) { - mode, e := GetConsoleMode(fd) - if e != nil { - return nil, e - } - return &State{mode}, nil -} - -// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx for these flag settings -func DisableEcho(fd uintptr, state *State) error { - state.mode &^= (ENABLE_ECHO_INPUT) - state.mode |= (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT) - return SetConsoleMode(fd, state.mode) -} - -func SetRawTerminal(fd uintptr) (*State, error) { - oldState, err := MakeRaw(fd) - if err != nil { - return nil, err - } - // TODO (azlinux): implement handling interrupt and restore state of terminal - return oldState, err -} - -// MakeRaw puts the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - var state *State - state, err := SaveState(fd) - if err != nil { - return nil, err - } - - // see http://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx for these flag settings - state.mode &^= (ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT) - err = SetConsoleMode(fd, state.mode) - if err != nil { - return nil, err - } - return state, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go deleted file mode 100644 index 11cd70d10b..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go +++ /dev/null @@ -1,65 +0,0 @@ -package term - -import ( - "syscall" - "unsafe" -) - -const ( - getTermios = syscall.TIOCGETA - setTermios = syscall.TIOCSETA - - IGNBRK = syscall.IGNBRK - PARMRK = syscall.PARMRK - INLCR = syscall.INLCR - IGNCR = syscall.IGNCR - ECHONL = syscall.ECHONL - CSIZE = syscall.CSIZE - ICRNL = syscall.ICRNL - ISTRIP = syscall.ISTRIP - PARENB = syscall.PARENB - ECHO = syscall.ECHO - ICANON = syscall.ICANON - ISIG = syscall.ISIG - IXON = syscall.IXON - BRKINT = syscall.BRKINT - INPCK = syscall.INPCK - OPOST = syscall.OPOST - CS8 = syscall.CS8 - IEXTEN = syscall.IEXTEN -) - -type Termios struct { - Iflag uint64 - Oflag uint64 - Cflag uint64 - Lflag uint64 - Cc [20]byte - Ispeed uint64 - Ospeed uint64 -} - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) - newState.Oflag &^= OPOST - newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN) - newState.Cflag &^= (CSIZE | PARENB) - newState.Cflag |= CS8 - newState.Cc[syscall.VMIN] = 1 - newState.Cc[syscall.VTIME] = 0 - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 { - return nil, err - } - - return &oldState, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go deleted file mode 100644 index ed3659572c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go +++ /dev/null @@ -1,65 +0,0 @@ -package term - -import ( - "syscall" - "unsafe" -) - -const ( - getTermios = syscall.TIOCGETA - setTermios = syscall.TIOCSETA - - IGNBRK = syscall.IGNBRK - PARMRK = syscall.PARMRK - INLCR = syscall.INLCR - IGNCR = syscall.IGNCR - ECHONL = syscall.ECHONL - CSIZE = syscall.CSIZE - ICRNL = syscall.ICRNL - ISTRIP = syscall.ISTRIP - PARENB = syscall.PARENB - ECHO = syscall.ECHO - ICANON = syscall.ICANON - ISIG = syscall.ISIG - IXON = syscall.IXON - BRKINT = syscall.BRKINT - INPCK = syscall.INPCK - OPOST = syscall.OPOST - CS8 = syscall.CS8 - IEXTEN = syscall.IEXTEN -) - -type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [20]byte - Ispeed uint32 - Ospeed uint32 -} - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) - newState.Oflag &^= OPOST - newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN) - newState.Cflag &^= (CSIZE | PARENB) - newState.Cflag |= CS8 - newState.Cc[syscall.VMIN] = 1 - newState.Cc[syscall.VTIME] = 0 - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 { - return nil, err - } - - return &oldState, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go deleted file mode 100644 index 4a717c84a7..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go +++ /dev/null @@ -1,44 +0,0 @@ -package term - -import ( - "syscall" - "unsafe" -) - -const ( - getTermios = syscall.TCGETS - setTermios = syscall.TCSETS -) - -type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [20]byte - Ispeed uint32 - Ospeed uint32 -} - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { - return nil, err - } - - newState := oldState.termios - - newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON) - newState.Oflag &^= syscall.OPOST - newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN) - newState.Cflag &^= (syscall.CSIZE | syscall.PARENB) - newState.Cflag |= syscall.CS8 - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { - return nil, err - } - return &oldState, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/MAINTAINERS deleted file mode 100644 index 6dde4769d7..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/MAINTAINERS +++ /dev/null @@ -1 +0,0 @@ -Cristian Staretu (@unclejack) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/json.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/json.go deleted file mode 100644 index 8043d69d18..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/json.go +++ /dev/null @@ -1,26 +0,0 @@ -package timeutils - -import ( - "errors" - "time" -) - -const ( - // RFC3339NanoFixed is our own version of RFC339Nano because we want one - // that pads the nano seconds part with zeros to ensure - // the timestamps are aligned in the logs. - RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" - // JSONFormat is the format used by FastMarshalJSON - JSONFormat = `"` + time.RFC3339Nano + `"` -) - -// FastMarshalJSON avoids one of the extra allocations that -// time.MarshalJSON is making. -func FastMarshalJSON(t time.Time) (string, error) { - if y := t.Year(); y < 0 || y >= 10000 { - // RFC 3339 is clear that years are 4 digits exactly. - // See golang.org/issue/4556#c15 for more discussion. - return "", errors.New("time.MarshalJSON: year outside of range [0,9999]") - } - return t.Format(JSONFormat), nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/docker/pkg/units/MAINTAINERS deleted file mode 100644 index 96abeae570..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Victor Vieux (@vieux) -Jessie Frazelle (@jfrazelle) diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go deleted file mode 100644 index a22947402b..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package units - -import ( - "testing" - "time" -) - -func TestHumanDuration(t *testing.T) { - // Useful duration abstractions - day := 24 * time.Hour - week := 7 * day - month := 30 * day - year := 365 * day - - assertEquals(t, "Less than a second", HumanDuration(450*time.Millisecond)) - assertEquals(t, "47 seconds", HumanDuration(47*time.Second)) - assertEquals(t, "About a minute", HumanDuration(1*time.Minute)) - assertEquals(t, "3 minutes", HumanDuration(3*time.Minute)) - assertEquals(t, "35 minutes", HumanDuration(35*time.Minute)) - assertEquals(t, "35 minutes", HumanDuration(35*time.Minute+40*time.Second)) - assertEquals(t, "About an hour", HumanDuration(1*time.Hour)) - assertEquals(t, "About an hour", HumanDuration(1*time.Hour+45*time.Minute)) - assertEquals(t, "3 hours", HumanDuration(3*time.Hour)) - assertEquals(t, "3 hours", HumanDuration(3*time.Hour+59*time.Minute)) - assertEquals(t, "4 hours", HumanDuration(3*time.Hour+60*time.Minute)) - assertEquals(t, "24 hours", HumanDuration(24*time.Hour)) - assertEquals(t, "36 hours", HumanDuration(1*day+12*time.Hour)) - assertEquals(t, "2 days", HumanDuration(2*day)) - assertEquals(t, "7 days", HumanDuration(7*day)) - assertEquals(t, "13 days", HumanDuration(13*day+5*time.Hour)) - assertEquals(t, "2 weeks", HumanDuration(2*week)) - assertEquals(t, "2 weeks", HumanDuration(2*week+4*day)) - assertEquals(t, "3 weeks", HumanDuration(3*week)) - assertEquals(t, "4 weeks", HumanDuration(4*week)) - assertEquals(t, "4 weeks", HumanDuration(4*week+3*day)) - assertEquals(t, "4 weeks", HumanDuration(1*month)) - assertEquals(t, "6 weeks", HumanDuration(1*month+2*week)) - assertEquals(t, "8 weeks", HumanDuration(2*month)) - assertEquals(t, "3 months", HumanDuration(3*month+1*week)) - assertEquals(t, "5 months", HumanDuration(5*month+2*week)) - assertEquals(t, "13 months", HumanDuration(13*month)) - assertEquals(t, "23 months", HumanDuration(23*month)) - assertEquals(t, "24 months", HumanDuration(24*month)) - assertEquals(t, "2.010959 years", HumanDuration(24*month+2*week)) - assertEquals(t, "3.164384 years", HumanDuration(3*year+2*month)) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go deleted file mode 100644 index 264f388225..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go +++ /dev/null @@ -1,91 +0,0 @@ -package units - -import ( - "fmt" - "regexp" - "strconv" - "strings" -) - -// See: http://en.wikipedia.org/wiki/Binary_prefix -const ( - // Decimal - - KB = 1000 - MB = 1000 * KB - GB = 1000 * MB - TB = 1000 * GB - PB = 1000 * TB - - // Binary - - KiB = 1024 - MiB = 1024 * KiB - GiB = 1024 * MiB - TiB = 1024 * GiB - PiB = 1024 * TiB -) - -type unitMap map[string]int64 - -var ( - decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} - binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} - sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`) -) - -var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} -var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} - -// HumanSize returns a human-readable approximation of a size -// using SI standard (eg. "44kB", "17MB") -func HumanSize(size int64) string { - return intToString(float64(size), 1000.0, decimapAbbrs) -} - -func BytesSize(size float64) string { - return intToString(size, 1024.0, binaryAbbrs) -} - -func intToString(size, unit float64, _map []string) string { - i := 0 - for size >= unit { - size = size / unit - i++ - } - return fmt.Sprintf("%.4g %s", size, _map[i]) -} - -// FromHumanSize returns an integer from a human-readable specification of a -// size using SI standard (eg. "44kB", "17MB") -func FromHumanSize(size string) (int64, error) { - return parseSize(size, decimalMap) -} - -// RAMInBytes parses a human-readable string representing an amount of RAM -// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and -// returns the number of bytes, or -1 if the string is unparseable. -// Units are case-insensitive, and the 'b' suffix is optional. -func RAMInBytes(size string) (int64, error) { - return parseSize(size, binaryMap) -} - -// Parses the human-readable size string into the amount it represents -func parseSize(sizeStr string, uMap unitMap) (int64, error) { - matches := sizeRegex.FindStringSubmatch(sizeStr) - if len(matches) != 3 { - return -1, fmt.Errorf("invalid size: '%s'", sizeStr) - } - - size, err := strconv.ParseInt(matches[1], 10, 0) - if err != nil { - return -1, err - } - - unitPrefix := strings.ToLower(matches[2]) - if mul, ok := uMap[unitPrefix]; ok { - size *= mul - } - - return size, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/size_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/units/size_test.go deleted file mode 100644 index 5b329fcf68..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/size_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package units - -import ( - "reflect" - "runtime" - "strings" - "testing" -) - -func TestBytesSize(t *testing.T) { - assertEquals(t, "1 KiB", BytesSize(1024)) - assertEquals(t, "1 MiB", BytesSize(1024*1024)) - assertEquals(t, "1 MiB", BytesSize(1048576)) - assertEquals(t, "2 MiB", BytesSize(2*MiB)) - assertEquals(t, "3.42 GiB", BytesSize(3.42*GiB)) - assertEquals(t, "5.372 TiB", BytesSize(5.372*TiB)) - assertEquals(t, "2.22 PiB", BytesSize(2.22*PiB)) -} - -func TestHumanSize(t *testing.T) { - assertEquals(t, "1 kB", HumanSize(1000)) - assertEquals(t, "1.024 kB", HumanSize(1024)) - assertEquals(t, "1 MB", HumanSize(1000000)) - assertEquals(t, "1.049 MB", HumanSize(1048576)) - assertEquals(t, "2 MB", HumanSize(2*MB)) - assertEquals(t, "3.42 GB", HumanSize(3.42*GB)) - assertEquals(t, "5.372 TB", HumanSize(5.372*TB)) - assertEquals(t, "2.22 PB", HumanSize(2.22*PB)) -} - -func TestFromHumanSize(t *testing.T) { - assertSuccessEquals(t, 32, FromHumanSize, "32") - assertSuccessEquals(t, 32, FromHumanSize, "32b") - assertSuccessEquals(t, 32, FromHumanSize, "32B") - assertSuccessEquals(t, 32*KB, FromHumanSize, "32k") - assertSuccessEquals(t, 32*KB, FromHumanSize, "32K") - assertSuccessEquals(t, 32*KB, FromHumanSize, "32kb") - assertSuccessEquals(t, 32*KB, FromHumanSize, "32Kb") - assertSuccessEquals(t, 32*MB, FromHumanSize, "32Mb") - assertSuccessEquals(t, 32*GB, FromHumanSize, "32Gb") - assertSuccessEquals(t, 32*TB, FromHumanSize, "32Tb") - assertSuccessEquals(t, 32*PB, FromHumanSize, "32Pb") - - assertError(t, FromHumanSize, "") - assertError(t, FromHumanSize, "hello") - assertError(t, FromHumanSize, "-32") - assertError(t, FromHumanSize, "32.3") - assertError(t, FromHumanSize, " 32 ") - assertError(t, FromHumanSize, "32.3Kb") - assertError(t, FromHumanSize, "32 mb") - assertError(t, FromHumanSize, "32m b") - assertError(t, FromHumanSize, "32bm") -} - -func TestRAMInBytes(t *testing.T) { - assertSuccessEquals(t, 32, RAMInBytes, "32") - assertSuccessEquals(t, 32, RAMInBytes, "32b") - assertSuccessEquals(t, 32, RAMInBytes, "32B") - assertSuccessEquals(t, 32*KiB, RAMInBytes, "32k") - assertSuccessEquals(t, 32*KiB, RAMInBytes, "32K") - assertSuccessEquals(t, 32*KiB, RAMInBytes, "32kb") - assertSuccessEquals(t, 32*KiB, RAMInBytes, "32Kb") - assertSuccessEquals(t, 32*MiB, RAMInBytes, "32Mb") - assertSuccessEquals(t, 32*GiB, RAMInBytes, "32Gb") - assertSuccessEquals(t, 32*TiB, RAMInBytes, "32Tb") - assertSuccessEquals(t, 32*PiB, RAMInBytes, "32Pb") - assertSuccessEquals(t, 32*PiB, RAMInBytes, "32PB") - assertSuccessEquals(t, 32*PiB, RAMInBytes, "32P") - - assertError(t, RAMInBytes, "") - assertError(t, RAMInBytes, "hello") - assertError(t, RAMInBytes, "-32") - assertError(t, RAMInBytes, "32.3") - assertError(t, RAMInBytes, " 32 ") - assertError(t, RAMInBytes, "32.3Kb") - assertError(t, RAMInBytes, "32 mb") - assertError(t, RAMInBytes, "32m b") - assertError(t, RAMInBytes, "32bm") -} - -func assertEquals(t *testing.T, expected, actual interface{}) { - if expected != actual { - t.Errorf("Expected '%v' but got '%v'", expected, actual) - } -} - -// func that maps to the parse function signatures as testing abstraction -type parseFn func(string) (int64, error) - -// Define 'String()' for pretty-print -func (fn parseFn) String() string { - fnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name() - return fnName[strings.LastIndex(fnName, ".")+1:] -} - -func assertSuccessEquals(t *testing.T, expected int64, fn parseFn, arg string) { - res, err := fn(arg) - if err != nil || res != expected { - t.Errorf("%s(\"%s\") -> expected '%d' but got '%d' with error '%v'", fn, arg, expected, res, err) - } -} - -func assertError(t *testing.T, fn parseFn, arg string) { - res, err := fn(arg) - if err == nil && res != -1 { - t.Errorf("%s(\"%s\") -> expected error but got '%d'", fn, arg, res) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/version/version.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/version/version.go deleted file mode 100644 index cc802a654c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/version/version.go +++ /dev/null @@ -1,63 +0,0 @@ -package version - -import ( - "strconv" - "strings" -) - -// Version provides utility methods for comparing versions. -type Version string - -func (v Version) compareTo(other Version) int { - var ( - currTab = strings.Split(string(v), ".") - otherTab = strings.Split(string(other), ".") - ) - - max := len(currTab) - if len(otherTab) > max { - max = len(otherTab) - } - for i := 0; i < max; i++ { - var currInt, otherInt int - - if len(currTab) > i { - currInt, _ = strconv.Atoi(currTab[i]) - } - if len(otherTab) > i { - otherInt, _ = strconv.Atoi(otherTab[i]) - } - if currInt > otherInt { - return 1 - } - if otherInt > currInt { - return -1 - } - } - return 0 -} - -// LessThan checks if a version is less than another version -func (v Version) LessThan(other Version) bool { - return v.compareTo(other) == -1 -} - -// LessThanOrEqualTo checks if a version is less than or equal to another -func (v Version) LessThanOrEqualTo(other Version) bool { - return v.compareTo(other) <= 0 -} - -// GreaterThan checks if a version is greater than another one -func (v Version) GreaterThan(other Version) bool { - return v.compareTo(other) == 1 -} - -// GreaterThanOrEqualTo checks ia version is greater than or equal to another -func (v Version) GreaterThanOrEqualTo(other Version) bool { - return v.compareTo(other) >= 0 -} - -// Equal checks if a version is equal to another -func (v Version) Equal(other Version) bool { - return v.compareTo(other) == 0 -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/version/version_test.go b/Godeps/_workspace/src/github.com/docker/docker/pkg/version/version_test.go deleted file mode 100644 index c02ec40fcb..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/version/version_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package version - -import ( - "testing" -) - -func assertVersion(t *testing.T, a, b string, result int) { - if r := Version(a).compareTo(Version(b)); r != result { - t.Fatalf("Unexpected version comparison result. Found %d, expected %d", r, result) - } -} - -func TestCompareVersion(t *testing.T) { - assertVersion(t, "1.12", "1.12", 0) - assertVersion(t, "1.0.0", "1", 0) - assertVersion(t, "1", "1.0.0", 0) - assertVersion(t, "1.05.00.0156", "1.0.221.9289", 1) - assertVersion(t, "1", "1.0.1", -1) - assertVersion(t, "1.0.1", "1", 1) - assertVersion(t, "1.0.1", "1.0.2", -1) - assertVersion(t, "1.0.2", "1.0.3", -1) - assertVersion(t, "1.0.3", "1.1", -1) - assertVersion(t, "1.1", "1.1.1", -1) - assertVersion(t, "1.1.1", "1.1.2", -1) - assertVersion(t, "1.1.2", "1.2", -1) - -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/daemon.go b/Godeps/_workspace/src/github.com/docker/docker/utils/daemon.go deleted file mode 100644 index 871122ed59..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/daemon.go +++ /dev/null @@ -1,36 +0,0 @@ -package utils - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "strconv" -) - -func CreatePidFile(pidfile string) error { - if pidString, err := ioutil.ReadFile(pidfile); err == nil { - pid, err := strconv.Atoi(string(pidString)) - if err == nil { - if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil { - return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile) - } - } - } - - file, err := os.Create(pidfile) - if err != nil { - return err - } - - defer file.Close() - - _, err = fmt.Fprintf(file, "%d", os.Getpid()) - return err -} - -func RemovePidFile(pidfile string) { - if err := os.Remove(pidfile); err != nil { - log.Printf("Error removing %s: %s", pidfile, err) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/http.go b/Godeps/_workspace/src/github.com/docker/docker/utils/http.go deleted file mode 100644 index bcf1865e2e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/http.go +++ /dev/null @@ -1,164 +0,0 @@ -package utils - -import ( - "io" - "net/http" - "strings" - - log "github.com/Sirupsen/logrus" -) - -// VersionInfo is used to model entities which has a version. -// It is basically a tupple with name and version. -type VersionInfo interface { - Name() string - Version() string -} - -func validVersion(version VersionInfo) bool { - const stopChars = " \t\r\n/" - name := version.Name() - vers := version.Version() - if len(name) == 0 || strings.ContainsAny(name, stopChars) { - return false - } - if len(vers) == 0 || strings.ContainsAny(vers, stopChars) { - return false - } - return true -} - -// Convert versions to a string and append the string to the string base. -// -// Each VersionInfo will be converted to a string in the format of -// "product/version", where the "product" is get from the Name() method, while -// version is get from the Version() method. Several pieces of verson information -// will be concatinated and separated by space. -func appendVersions(base string, versions ...VersionInfo) string { - if len(versions) == 0 { - return base - } - - verstrs := make([]string, 0, 1+len(versions)) - if len(base) > 0 { - verstrs = append(verstrs, base) - } - - for _, v := range versions { - if !validVersion(v) { - continue - } - verstrs = append(verstrs, v.Name()+"/"+v.Version()) - } - return strings.Join(verstrs, " ") -} - -// HTTPRequestDecorator is used to change an instance of -// http.Request. It could be used to add more header fields, -// change body, etc. -type HTTPRequestDecorator interface { - // ChangeRequest() changes the request accordingly. - // The changed request will be returned or err will be non-nil - // if an error occur. - ChangeRequest(req *http.Request) (newReq *http.Request, err error) -} - -// HTTPUserAgentDecorator appends the product/version to the user agent field -// of a request. -type HTTPUserAgentDecorator struct { - versions []VersionInfo -} - -func NewHTTPUserAgentDecorator(versions ...VersionInfo) HTTPRequestDecorator { - return &HTTPUserAgentDecorator{ - versions: versions, - } -} - -func (h *HTTPUserAgentDecorator) ChangeRequest(req *http.Request) (newReq *http.Request, err error) { - if req == nil { - return req, nil - } - - userAgent := appendVersions(req.UserAgent(), h.versions...) - if len(userAgent) > 0 { - req.Header.Set("User-Agent", userAgent) - } - return req, nil -} - -type HTTPMetaHeadersDecorator struct { - Headers map[string][]string -} - -func (h *HTTPMetaHeadersDecorator) ChangeRequest(req *http.Request) (newReq *http.Request, err error) { - if h.Headers == nil { - return req, nil - } - for k, v := range h.Headers { - req.Header[k] = v - } - return req, nil -} - -type HTTPAuthDecorator struct { - login string - password string -} - -func NewHTTPAuthDecorator(login, password string) HTTPRequestDecorator { - return &HTTPAuthDecorator{ - login: login, - password: password, - } -} - -func (self *HTTPAuthDecorator) ChangeRequest(req *http.Request) (*http.Request, error) { - req.SetBasicAuth(self.login, self.password) - return req, nil -} - -// HTTPRequestFactory creates an HTTP request -// and applies a list of decorators on the request. -type HTTPRequestFactory struct { - decorators []HTTPRequestDecorator -} - -func NewHTTPRequestFactory(d ...HTTPRequestDecorator) *HTTPRequestFactory { - return &HTTPRequestFactory{ - decorators: d, - } -} - -func (self *HTTPRequestFactory) AddDecorator(d ...HTTPRequestDecorator) { - self.decorators = append(self.decorators, d...) -} - -// NewRequest() creates a new *http.Request, -// applies all decorators in the HTTPRequestFactory on the request, -// then applies decorators provided by d on the request. -func (h *HTTPRequestFactory) NewRequest(method, urlStr string, body io.Reader, d ...HTTPRequestDecorator) (*http.Request, error) { - req, err := http.NewRequest(method, urlStr, body) - if err != nil { - return nil, err - } - - // By default, a nil factory should work. - if h == nil { - return req, nil - } - for _, dec := range h.decorators { - req, err = dec.ChangeRequest(req) - if err != nil { - return nil, err - } - } - for _, dec := range d { - req, err = dec.ChangeRequest(req) - if err != nil { - return nil, err - } - } - log.Debugf("%v -- HEADERS: %v", req.URL, req.Header) - return req, err -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/jsonmessage.go b/Godeps/_workspace/src/github.com/docker/docker/utils/jsonmessage.go deleted file mode 100644 index bdc47f0e1d..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/jsonmessage.go +++ /dev/null @@ -1,169 +0,0 @@ -package utils - -import ( - "encoding/json" - "fmt" - "io" - "strings" - "time" - - "github.com/docker/docker/pkg/term" - "github.com/docker/docker/pkg/timeutils" - "github.com/docker/docker/pkg/units" -) - -type JSONError struct { - Code int `json:"code,omitempty"` - Message string `json:"message,omitempty"` -} - -func (e *JSONError) Error() string { - return e.Message -} - -type JSONProgress struct { - terminalFd uintptr - Current int `json:"current,omitempty"` - Total int `json:"total,omitempty"` - Start int64 `json:"start,omitempty"` -} - -func (p *JSONProgress) String() string { - var ( - width = 200 - pbBox string - numbersBox string - timeLeftBox string - ) - - ws, err := term.GetWinsize(p.terminalFd) - if err == nil { - width = int(ws.Width) - } - - if p.Current <= 0 && p.Total <= 0 { - return "" - } - current := units.HumanSize(int64(p.Current)) - if p.Total <= 0 { - return fmt.Sprintf("%8v", current) - } - total := units.HumanSize(int64(p.Total)) - percentage := int(float64(p.Current)/float64(p.Total)*100) / 2 - if width > 110 { - // this number can't be negetive gh#7136 - numSpaces := 0 - if 50-percentage > 0 { - numSpaces = 50 - percentage - } - pbBox = fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", numSpaces)) - } - numbersBox = fmt.Sprintf("%8v/%v", current, total) - - if p.Current > 0 && p.Start > 0 && percentage < 50 { - fromStart := time.Now().UTC().Sub(time.Unix(int64(p.Start), 0)) - perEntry := fromStart / time.Duration(p.Current) - left := time.Duration(p.Total-p.Current) * perEntry - left = (left / time.Second) * time.Second - - if width > 50 { - timeLeftBox = " " + left.String() - } - } - return pbBox + numbersBox + timeLeftBox -} - -type JSONMessage struct { - Stream string `json:"stream,omitempty"` - Status string `json:"status,omitempty"` - Progress *JSONProgress `json:"progressDetail,omitempty"` - ProgressMessage string `json:"progress,omitempty"` //deprecated - ID string `json:"id,omitempty"` - From string `json:"from,omitempty"` - Time int64 `json:"time,omitempty"` - Error *JSONError `json:"errorDetail,omitempty"` - ErrorMessage string `json:"error,omitempty"` //deprecated -} - -func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { - if jm.Error != nil { - if jm.Error.Code == 401 { - return fmt.Errorf("Authentication is required.") - } - return jm.Error - } - var endl string - if isTerminal && jm.Stream == "" && jm.Progress != nil { - // [2K = erase entire current line - fmt.Fprintf(out, "%c[2K\r", 27) - endl = "\r" - } else if jm.Progress != nil && jm.Progress.String() != "" { //disable progressbar in non-terminal - return nil - } - if jm.Time != 0 { - fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(timeutils.RFC3339NanoFixed)) - } - if jm.ID != "" { - fmt.Fprintf(out, "%s: ", jm.ID) - } - if jm.From != "" { - fmt.Fprintf(out, "(from %s) ", jm.From) - } - if jm.Progress != nil && isTerminal { - fmt.Fprintf(out, "%s %s%s", jm.Status, jm.Progress.String(), endl) - } else if jm.ProgressMessage != "" { //deprecated - fmt.Fprintf(out, "%s %s%s", jm.Status, jm.ProgressMessage, endl) - } else if jm.Stream != "" { - fmt.Fprintf(out, "%s%s", jm.Stream, endl) - } else { - fmt.Fprintf(out, "%s%s\n", jm.Status, endl) - } - return nil -} - -func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool) error { - var ( - dec = json.NewDecoder(in) - ids = make(map[string]int) - diff = 0 - ) - for { - var jm JSONMessage - if err := dec.Decode(&jm); err != nil { - if err == io.EOF { - break - } - return err - } - - if jm.Progress != nil { - jm.Progress.terminalFd = terminalFd - } - if jm.ID != "" && (jm.Progress != nil || jm.ProgressMessage != "") { - line, ok := ids[jm.ID] - if !ok { - line = len(ids) - ids[jm.ID] = line - if isTerminal { - fmt.Fprintf(out, "\n") - } - diff = 0 - } else { - diff = len(ids) - line - } - if jm.ID != "" && isTerminal { - // [{diff}A = move cursor up diff rows - fmt.Fprintf(out, "%c[%dA", 27, diff) - } - } - err := jm.Display(out, isTerminal) - if jm.ID != "" && isTerminal { - // [{diff}B = move cursor down diff rows - fmt.Fprintf(out, "%c[%dB", 27, diff) - } - if err != nil { - return err - } - } - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/jsonmessage_test.go b/Godeps/_workspace/src/github.com/docker/docker/utils/jsonmessage_test.go deleted file mode 100644 index 0ce9492c98..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/jsonmessage_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package utils - -import ( - "testing" -) - -func TestError(t *testing.T) { - je := JSONError{404, "Not found"} - if je.Error() != "Not found" { - t.Fatalf("Expected 'Not found' got '%s'", je.Error()) - } -} - -func TestProgress(t *testing.T) { - jp := JSONProgress{} - if jp.String() != "" { - t.Fatalf("Expected empty string, got '%s'", jp.String()) - } - - expected := " 1 B" - jp2 := JSONProgress{Current: 1} - if jp2.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp2.String()) - } - - expected = "[=========================> ] 50 B/100 B" - jp3 := JSONProgress{Current: 50, Total: 100} - if jp3.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp3.String()) - } - - // this number can't be negetive gh#7136 - expected = "[==============================================================>] 50 B/40 B" - jp4 := JSONProgress{Current: 50, Total: 40} - if jp4.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp4.String()) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/progressreader.go b/Godeps/_workspace/src/github.com/docker/docker/utils/progressreader.go deleted file mode 100644 index 87eae8ba73..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/progressreader.go +++ /dev/null @@ -1,55 +0,0 @@ -package utils - -import ( - "io" - "time" -) - -// Reader with progress bar -type progressReader struct { - reader io.ReadCloser // Stream to read from - output io.Writer // Where to send progress bar to - progress JSONProgress - lastUpdate int // How many bytes read at least update - ID string - action string - sf *StreamFormatter - newLine bool -} - -func (r *progressReader) Read(p []byte) (n int, err error) { - read, err := r.reader.Read(p) - r.progress.Current += read - updateEvery := 1024 * 512 //512kB - if r.progress.Total > 0 { - // Update progress for every 1% read if 1% < 512kB - if increment := int(0.01 * float64(r.progress.Total)); increment < updateEvery { - updateEvery = increment - } - } - if r.progress.Current-r.lastUpdate > updateEvery || err != nil { - r.output.Write(r.sf.FormatProgress(r.ID, r.action, &r.progress)) - r.lastUpdate = r.progress.Current - } - // Send newline when complete - if r.newLine && err != nil && read == 0 { - r.output.Write(r.sf.FormatStatus("", "")) - } - return read, err -} -func (r *progressReader) Close() error { - r.progress.Current = r.progress.Total - r.output.Write(r.sf.FormatProgress(r.ID, r.action, &r.progress)) - return r.reader.Close() -} -func ProgressReader(r io.ReadCloser, size int, output io.Writer, sf *StreamFormatter, newline bool, ID, action string) *progressReader { - return &progressReader{ - reader: r, - output: NewWriteFlusher(output), - ID: ID, - action: action, - progress: JSONProgress{Total: size, Start: time.Now().UTC().Unix()}, - sf: sf, - newLine: newline, - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/random.go b/Godeps/_workspace/src/github.com/docker/docker/utils/random.go deleted file mode 100644 index 907f28eec3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/random.go +++ /dev/null @@ -1,16 +0,0 @@ -package utils - -import ( - "crypto/rand" - "encoding/hex" - "io" -) - -func RandomString() string { - id := make([]byte, 32) - - if _, err := io.ReadFull(rand.Reader, id); err != nil { - panic(err) // This shouldn't happen - } - return hex.EncodeToString(id) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/streamformatter.go b/Godeps/_workspace/src/github.com/docker/docker/utils/streamformatter.go deleted file mode 100644 index d0bc295bb3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/streamformatter.go +++ /dev/null @@ -1,112 +0,0 @@ -package utils - -import ( - "encoding/json" - "fmt" - "io" -) - -type StreamFormatter struct { - json bool -} - -func NewStreamFormatter(json bool) *StreamFormatter { - return &StreamFormatter{json} -} - -const streamNewline = "\r\n" - -var streamNewlineBytes = []byte(streamNewline) - -func (sf *StreamFormatter) FormatStream(str string) []byte { - if sf.json { - b, err := json.Marshal(&JSONMessage{Stream: str}) - if err != nil { - return sf.FormatError(err) - } - return append(b, streamNewlineBytes...) - } - return []byte(str + "\r") -} - -func (sf *StreamFormatter) FormatStatus(id, format string, a ...interface{}) []byte { - str := fmt.Sprintf(format, a...) - if sf.json { - b, err := json.Marshal(&JSONMessage{ID: id, Status: str}) - if err != nil { - return sf.FormatError(err) - } - return append(b, streamNewlineBytes...) - } - return []byte(str + streamNewline) -} - -func (sf *StreamFormatter) FormatError(err error) []byte { - if sf.json { - jsonError, ok := err.(*JSONError) - if !ok { - jsonError = &JSONError{Message: err.Error()} - } - if b, err := json.Marshal(&JSONMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil { - return append(b, streamNewlineBytes...) - } - return []byte("{\"error\":\"format error\"}" + streamNewline) - } - return []byte("Error: " + err.Error() + streamNewline) -} - -func (sf *StreamFormatter) FormatProgress(id, action string, progress *JSONProgress) []byte { - if progress == nil { - progress = &JSONProgress{} - } - if sf.json { - - b, err := json.Marshal(&JSONMessage{ - Status: action, - ProgressMessage: progress.String(), - Progress: progress, - ID: id, - }) - if err != nil { - return nil - } - return b - } - endl := "\r" - if progress.String() == "" { - endl += "\n" - } - return []byte(action + " " + progress.String() + endl) -} - -func (sf *StreamFormatter) Json() bool { - return sf.json -} - -type StdoutFormater struct { - io.Writer - *StreamFormatter -} - -func (sf *StdoutFormater) Write(buf []byte) (int, error) { - formattedBuf := sf.StreamFormatter.FormatStream(string(buf)) - n, err := sf.Writer.Write(formattedBuf) - if n != len(formattedBuf) { - return n, io.ErrShortWrite - } - return len(buf), err -} - -type StderrFormater struct { - io.Writer - *StreamFormatter -} - -func (sf *StderrFormater) Write(buf []byte) (int, error) { - formattedBuf := sf.StreamFormatter.FormatStream("\033[91m" + string(buf) + "\033[0m") - n, err := sf.Writer.Write(formattedBuf) - if n != len(formattedBuf) { - return n, io.ErrShortWrite - } - return len(buf), err -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/streamformatter_test.go b/Godeps/_workspace/src/github.com/docker/docker/utils/streamformatter_test.go deleted file mode 100644 index 20610f6c01..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/streamformatter_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package utils - -import ( - "encoding/json" - "errors" - "reflect" - "testing" -) - -func TestFormatStream(t *testing.T) { - sf := NewStreamFormatter(true) - res := sf.FormatStream("stream") - if string(res) != `{"stream":"stream"}`+"\r\n" { - t.Fatalf("%q", res) - } -} - -func TestFormatStatus(t *testing.T) { - sf := NewStreamFormatter(true) - res := sf.FormatStatus("ID", "%s%d", "a", 1) - if string(res) != `{"status":"a1","id":"ID"}`+"\r\n" { - t.Fatalf("%q", res) - } -} - -func TestFormatSimpleError(t *testing.T) { - sf := NewStreamFormatter(true) - res := sf.FormatError(errors.New("Error for formatter")) - if string(res) != `{"errorDetail":{"message":"Error for formatter"},"error":"Error for formatter"}`+"\r\n" { - t.Fatalf("%q", res) - } -} - -func TestFormatJSONError(t *testing.T) { - sf := NewStreamFormatter(true) - err := &JSONError{Code: 50, Message: "Json error"} - res := sf.FormatError(err) - if string(res) != `{"errorDetail":{"code":50,"message":"Json error"},"error":"Json error"}`+"\r\n" { - t.Fatalf("%q", res) - } -} - -func TestFormatProgress(t *testing.T) { - sf := NewStreamFormatter(true) - progress := &JSONProgress{ - Current: 15, - Total: 30, - Start: 1, - } - res := sf.FormatProgress("id", "action", progress) - msg := &JSONMessage{} - if err := json.Unmarshal(res, msg); err != nil { - t.Fatal(err) - } - if msg.ID != "id" { - t.Fatalf("ID must be 'id', got: %s", msg.ID) - } - if msg.Status != "action" { - t.Fatalf("Status must be 'action', got: %s", msg.Status) - } - if msg.ProgressMessage != progress.String() { - t.Fatalf("ProgressMessage must be %s, got: %s", progress.String(), msg.ProgressMessage) - } - if !reflect.DeepEqual(msg.Progress, progress) { - t.Fatal("Original progress not equals progress from FormatProgress") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/timeoutconn.go b/Godeps/_workspace/src/github.com/docker/docker/utils/timeoutconn.go deleted file mode 100644 index a3231c7ee3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/timeoutconn.go +++ /dev/null @@ -1,26 +0,0 @@ -package utils - -import ( - "net" - "time" -) - -func NewTimeoutConn(conn net.Conn, timeout time.Duration) net.Conn { - return &TimeoutConn{conn, timeout} -} - -// A net.Conn that sets a deadline for every Read or Write operation -type TimeoutConn struct { - net.Conn - timeout time.Duration -} - -func (c *TimeoutConn) Read(b []byte) (int, error) { - if c.timeout > 0 { - err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)) - if err != nil { - return 0, err - } - } - return c.Conn.Read(b) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/timeoutconn_test.go b/Godeps/_workspace/src/github.com/docker/docker/utils/timeoutconn_test.go deleted file mode 100644 index d07b96cc06..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/timeoutconn_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package utils - -import ( - "bufio" - "fmt" - "net" - "net/http" - "net/http/httptest" - "testing" - "time" -) - -func TestTimeoutConnRead(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "hello") - })) - defer ts.Close() - conn, err := net.Dial("tcp", ts.URL[7:]) - if err != nil { - t.Fatalf("failed to create connection to %q: %v", ts.URL, err) - } - tconn := NewTimeoutConn(conn, 1*time.Second) - - if _, err = bufio.NewReader(tconn).ReadString('\n'); err == nil { - t.Fatalf("expected timeout error, got none") - } - if _, err := fmt.Fprintf(tconn, "GET / HTTP/1.0\r\n\r\n"); err != nil { - t.Errorf("unexpected error: %v", err) - } - if _, err = bufio.NewReader(tconn).ReadString('\n'); err != nil { - t.Errorf("unexpected error: %v", err) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/tmpdir.go b/Godeps/_workspace/src/github.com/docker/docker/utils/tmpdir.go deleted file mode 100644 index e200f340db..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/tmpdir.go +++ /dev/null @@ -1,16 +0,0 @@ -package utils - -import ( - "os" - "path/filepath" -) - -// TempDir returns the default directory to use for temporary files. -func TempDir(rootDir string) (string, error) { - var tmpDir string - if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" { - tmpDir = filepath.Join(rootDir, "tmp") - } - err := os.MkdirAll(tmpDir, 0700) - return tmpDir, err -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/utils.go b/Godeps/_workspace/src/github.com/docker/docker/utils/utils.go deleted file mode 100644 index 84d01f6c9d..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/utils.go +++ /dev/null @@ -1,506 +0,0 @@ -package utils - -import ( - "bytes" - "crypto/rand" - "crypto/sha1" - "crypto/sha256" - "encoding/hex" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" - "sync" - - log "github.com/Sirupsen/logrus" - "github.com/docker/docker/dockerversion" - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/fileutils" - "github.com/docker/docker/pkg/ioutils" -) - -type KeyValuePair struct { - Key string - Value string -} - -// Request a given URL and return an io.Reader -func Download(url string) (resp *http.Response, err error) { - if resp, err = http.Get(url); err != nil { - return nil, err - } - if resp.StatusCode >= 400 { - return nil, fmt.Errorf("Got HTTP status code >= 400: %s", resp.Status) - } - return resp, nil -} - -func Trunc(s string, maxlen int) string { - if len(s) <= maxlen { - return s - } - return s[:maxlen] -} - -// Figure out the absolute path of our own binary (if it's still around). -func SelfPath() string { - path, err := exec.LookPath(os.Args[0]) - if err != nil { - if os.IsNotExist(err) { - return "" - } - if execErr, ok := err.(*exec.Error); ok && os.IsNotExist(execErr.Err) { - return "" - } - panic(err) - } - path, err = filepath.Abs(path) - if err != nil { - if os.IsNotExist(err) { - return "" - } - panic(err) - } - return path -} - -func dockerInitSha1(target string) string { - f, err := os.Open(target) - if err != nil { - return "" - } - defer f.Close() - h := sha1.New() - _, err = io.Copy(h, f) - if err != nil { - return "" - } - return hex.EncodeToString(h.Sum(nil)) -} - -func isValidDockerInitPath(target string, selfPath string) bool { // target and selfPath should be absolute (InitPath and SelfPath already do this) - if target == "" { - return false - } - if dockerversion.IAMSTATIC { - if selfPath == "" { - return false - } - if target == selfPath { - return true - } - targetFileInfo, err := os.Lstat(target) - if err != nil { - return false - } - selfPathFileInfo, err := os.Lstat(selfPath) - if err != nil { - return false - } - return os.SameFile(targetFileInfo, selfPathFileInfo) - } - return dockerversion.INITSHA1 != "" && dockerInitSha1(target) == dockerversion.INITSHA1 -} - -// Figure out the path of our dockerinit (which may be SelfPath()) -func DockerInitPath(localCopy string) string { - selfPath := SelfPath() - if isValidDockerInitPath(selfPath, selfPath) { - // if we're valid, don't bother checking anything else - return selfPath - } - var possibleInits = []string{ - localCopy, - dockerversion.INITPATH, - filepath.Join(filepath.Dir(selfPath), "dockerinit"), - - // FHS 3.0 Draft: "/usr/libexec includes internal binaries that are not intended to be executed directly by users or shell scripts. Applications may use a single subdirectory under /usr/libexec." - // http://www.linuxbase.org/betaspecs/fhs/fhs.html#usrlibexec - "/usr/libexec/docker/dockerinit", - "/usr/local/libexec/docker/dockerinit", - - // FHS 2.3: "/usr/lib includes object files, libraries, and internal binaries that are not intended to be executed directly by users or shell scripts." - // http://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA - "/usr/lib/docker/dockerinit", - "/usr/local/lib/docker/dockerinit", - } - for _, dockerInit := range possibleInits { - if dockerInit == "" { - continue - } - path, err := exec.LookPath(dockerInit) - if err == nil { - path, err = filepath.Abs(path) - if err != nil { - // LookPath already validated that this file exists and is executable (following symlinks), so how could Abs fail? - panic(err) - } - if isValidDockerInitPath(path, selfPath) { - return path - } - } - } - return "" -} - -func GetTotalUsedFds() int { - if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { - log.Errorf("Error opening /proc/%d/fd: %s", os.Getpid(), err) - } else { - return len(fds) - } - return -1 -} - -// TruncateID returns a shorthand version of a string identifier for convenience. -// A collision with other shorthands is very unlikely, but possible. -// In case of a collision a lookup with TruncIndex.Get() will fail, and the caller -// will need to use a langer prefix, or the full-length Id. -func TruncateID(id string) string { - shortLen := 12 - if len(id) < shortLen { - shortLen = len(id) - } - return id[:shortLen] -} - -// GenerateRandomID returns an unique id -func GenerateRandomID() string { - for { - id := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, id); err != nil { - panic(err) // This shouldn't happen - } - value := hex.EncodeToString(id) - // if we try to parse the truncated for as an int and we don't have - // an error then the value is all numberic and causes issues when - // used as a hostname. ref #3869 - if _, err := strconv.ParseInt(TruncateID(value), 10, 64); err == nil { - continue - } - return value - } -} - -func ValidateID(id string) error { - if id == "" { - return fmt.Errorf("Id can't be empty") - } - if strings.Contains(id, ":") { - return fmt.Errorf("Invalid character in id: ':'") - } - return nil -} - -// Code c/c from io.Copy() modified to handle escape sequence -func CopyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error) { - buf := make([]byte, 32*1024) - for { - nr, er := src.Read(buf) - if nr > 0 { - // ---- Docker addition - // char 16 is C-p - if nr == 1 && buf[0] == 16 { - nr, er = src.Read(buf) - // char 17 is C-q - if nr == 1 && buf[0] == 17 { - if err := src.Close(); err != nil { - return 0, err - } - return 0, nil - } - } - // ---- End of docker - nw, ew := dst.Write(buf[0:nr]) - if nw > 0 { - written += int64(nw) - } - if ew != nil { - err = ew - break - } - if nr != nw { - err = io.ErrShortWrite - break - } - } - if er == io.EOF { - break - } - if er != nil { - err = er - break - } - } - return written, err -} - -func HashData(src io.Reader) (string, error) { - h := sha256.New() - if _, err := io.Copy(h, src); err != nil { - return "", err - } - return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil -} - -type WriteFlusher struct { - sync.Mutex - w io.Writer - flusher http.Flusher -} - -func (wf *WriteFlusher) Write(b []byte) (n int, err error) { - wf.Lock() - defer wf.Unlock() - n, err = wf.w.Write(b) - wf.flusher.Flush() - return n, err -} - -// Flush the stream immediately. -func (wf *WriteFlusher) Flush() { - wf.Lock() - defer wf.Unlock() - wf.flusher.Flush() -} - -func NewWriteFlusher(w io.Writer) *WriteFlusher { - var flusher http.Flusher - if f, ok := w.(http.Flusher); ok { - flusher = f - } else { - flusher = &ioutils.NopFlusher{} - } - return &WriteFlusher{w: w, flusher: flusher} -} - -func NewHTTPRequestError(msg string, res *http.Response) error { - return &JSONError{ - Message: msg, - Code: res.StatusCode, - } -} - -func IsURL(str string) bool { - return strings.HasPrefix(str, "http://") || strings.HasPrefix(str, "https://") -} - -func IsGIT(str string) bool { - return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "github.com/") || strings.HasPrefix(str, "git@github.com:") || (strings.HasSuffix(str, ".git") && IsURL(str)) -} - -func ValidGitTransport(str string) bool { - return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "git@") || IsURL(str) -} - -var ( - localHostRx = regexp.MustCompile(`(?m)^nameserver 127[^\n]+\n*`) -) - -// RemoveLocalDns looks into the /etc/resolv.conf, -// and removes any local nameserver entries. -func RemoveLocalDns(resolvConf []byte) []byte { - return localHostRx.ReplaceAll(resolvConf, []byte{}) -} - -// An StatusError reports an unsuccessful exit by a command. -type StatusError struct { - Status string - StatusCode int -} - -func (e *StatusError) Error() string { - return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode) -} - -func quote(word string, buf *bytes.Buffer) { - // Bail out early for "simple" strings - if word != "" && !strings.ContainsAny(word, "\\'\"`${[|&;<>()~*?! \t\n") { - buf.WriteString(word) - return - } - - buf.WriteString("'") - - for i := 0; i < len(word); i++ { - b := word[i] - if b == '\'' { - // Replace literal ' with a close ', a \', and a open ' - buf.WriteString("'\\''") - } else { - buf.WriteByte(b) - } - } - - buf.WriteString("'") -} - -// Take a list of strings and escape them so they will be handled right -// when passed as arguments to an program via a shell -func ShellQuoteArguments(args []string) string { - var buf bytes.Buffer - for i, arg := range args { - if i != 0 { - buf.WriteByte(' ') - } - quote(arg, &buf) - } - return buf.String() -} - -var globalTestID string - -// TestDirectory creates a new temporary directory and returns its path. -// The contents of directory at path `templateDir` is copied into the -// new directory. -func TestDirectory(templateDir string) (dir string, err error) { - if globalTestID == "" { - globalTestID = RandomString()[:4] - } - prefix := fmt.Sprintf("docker-test%s-%s-", globalTestID, GetCallerName(2)) - if prefix == "" { - prefix = "docker-test-" - } - dir, err = ioutil.TempDir("", prefix) - if err = os.Remove(dir); err != nil { - return - } - if templateDir != "" { - if err = archive.CopyWithTar(templateDir, dir); err != nil { - return - } - } - return -} - -// GetCallerName introspects the call stack and returns the name of the -// function `depth` levels down in the stack. -func GetCallerName(depth int) string { - // Use the caller function name as a prefix. - // This helps trace temp directories back to their test. - pc, _, _, _ := runtime.Caller(depth + 1) - callerLongName := runtime.FuncForPC(pc).Name() - parts := strings.Split(callerLongName, ".") - callerShortName := parts[len(parts)-1] - return callerShortName -} - -func CopyFile(src, dst string) (int64, error) { - if src == dst { - return 0, nil - } - sf, err := os.Open(src) - if err != nil { - return 0, err - } - defer sf.Close() - if err := os.Remove(dst); err != nil && !os.IsNotExist(err) { - return 0, err - } - df, err := os.Create(dst) - if err != nil { - return 0, err - } - defer df.Close() - return io.Copy(df, sf) -} - -// ReplaceOrAppendValues returns the defaults with the overrides either -// replaced by env key or appended to the list -func ReplaceOrAppendEnvValues(defaults, overrides []string) []string { - cache := make(map[string]int, len(defaults)) - for i, e := range defaults { - parts := strings.SplitN(e, "=", 2) - cache[parts[0]] = i - } - for _, value := range overrides { - parts := strings.SplitN(value, "=", 2) - if i, exists := cache[parts[0]]; exists { - defaults[i] = value - } else { - defaults = append(defaults, value) - } - } - return defaults -} - -// ReadSymlinkedDirectory returns the target directory of a symlink. -// The target of the symbolic link may not be a file. -func ReadSymlinkedDirectory(path string) (string, error) { - var realPath string - var err error - if realPath, err = filepath.Abs(path); err != nil { - return "", fmt.Errorf("unable to get absolute path for %s: %s", path, err) - } - if realPath, err = filepath.EvalSymlinks(realPath); err != nil { - return "", fmt.Errorf("failed to canonicalise path for %s: %s", path, err) - } - realPathInfo, err := os.Stat(realPath) - if err != nil { - return "", fmt.Errorf("failed to stat target '%s' of '%s': %s", realPath, path, err) - } - if !realPathInfo.Mode().IsDir() { - return "", fmt.Errorf("canonical path points to a file '%s'", realPath) - } - return realPath, nil -} - -// ValidateContextDirectory checks if all the contents of the directory -// can be read and returns an error if some files can't be read -// symlinks which point to non-existing files don't trigger an error -func ValidateContextDirectory(srcPath string, excludes []string) error { - return filepath.Walk(filepath.Join(srcPath, "."), func(filePath string, f os.FileInfo, err error) error { - // skip this directory/file if it's not in the path, it won't get added to the context - if relFilePath, err := filepath.Rel(srcPath, filePath); err != nil { - return err - } else if skip, err := fileutils.Matches(relFilePath, excludes); err != nil { - return err - } else if skip { - if f.IsDir() { - return filepath.SkipDir - } - return nil - } - - if err != nil { - if os.IsPermission(err) { - return fmt.Errorf("can't stat '%s'", filePath) - } - if os.IsNotExist(err) { - return nil - } - return err - } - - // skip checking if symlinks point to non-existing files, such symlinks can be useful - // also skip named pipes, because they hanging on open - if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 { - return nil - } - - if !f.IsDir() { - currentFile, err := os.Open(filePath) - if err != nil && os.IsPermission(err) { - return fmt.Errorf("no permission to read from '%s'", filePath) - } - currentFile.Close() - } - return nil - }) -} - -func StringsContainsNoCase(slice []string, s string) bool { - for _, ss := range slice { - if strings.ToLower(s) == strings.ToLower(ss) { - return true - } - } - return false -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/utils_daemon.go b/Godeps/_workspace/src/github.com/docker/docker/utils/utils_daemon.go deleted file mode 100644 index 098e227367..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/utils_daemon.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build daemon - -package utils - -import ( - "os" - "path/filepath" - "syscall" -) - -// TreeSize walks a directory tree and returns its total size in bytes. -func TreeSize(dir string) (size int64, err error) { - data := make(map[uint64]struct{}) - err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, e error) error { - // Ignore directory sizes - if fileInfo == nil { - return nil - } - - s := fileInfo.Size() - if fileInfo.IsDir() || s == 0 { - return nil - } - - // Check inode to handle hard links correctly - inode := fileInfo.Sys().(*syscall.Stat_t).Ino - // inode is not a uint64 on all platforms. Cast it to avoid issues. - if _, exists := data[uint64(inode)]; exists { - return nil - } - // inode is not a uint64 on all platforms. Cast it to avoid issues. - data[uint64(inode)] = struct{}{} - - size += s - - return nil - }) - return -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/utils/utils_test.go b/Godeps/_workspace/src/github.com/docker/docker/utils/utils_test.go deleted file mode 100644 index 6e2de7e041..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/utils/utils_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package utils - -import ( - "os" - "testing" -) - -func TestReplaceAndAppendEnvVars(t *testing.T) { - var ( - d = []string{"HOME=/"} - o = []string{"HOME=/root", "TERM=xterm"} - ) - - env := ReplaceOrAppendEnvValues(d, o) - if len(env) != 2 { - t.Fatalf("expected len of 2 got %d", len(env)) - } - if env[0] != "HOME=/root" { - t.Fatalf("expected HOME=/root got '%s'", env[0]) - } - if env[1] != "TERM=xterm" { - t.Fatalf("expected TERM=xterm got '%s'", env[1]) - } -} - -// Reading a symlink to a directory must return the directory -func TestReadSymlinkedDirectoryExistingDirectory(t *testing.T) { - var err error - if err = os.Mkdir("/tmp/testReadSymlinkToExistingDirectory", 0777); err != nil { - t.Errorf("failed to create directory: %s", err) - } - - if err = os.Symlink("/tmp/testReadSymlinkToExistingDirectory", "/tmp/dirLinkTest"); err != nil { - t.Errorf("failed to create symlink: %s", err) - } - - var path string - if path, err = ReadSymlinkedDirectory("/tmp/dirLinkTest"); err != nil { - t.Fatalf("failed to read symlink to directory: %s", err) - } - - if path != "/tmp/testReadSymlinkToExistingDirectory" { - t.Fatalf("symlink returned unexpected directory: %s", path) - } - - if err = os.Remove("/tmp/testReadSymlinkToExistingDirectory"); err != nil { - t.Errorf("failed to remove temporary directory: %s", err) - } - - if err = os.Remove("/tmp/dirLinkTest"); err != nil { - t.Errorf("failed to remove symlink: %s", err) - } -} - -// Reading a non-existing symlink must fail -func TestReadSymlinkedDirectoryNonExistingSymlink(t *testing.T) { - var path string - var err error - if path, err = ReadSymlinkedDirectory("/tmp/test/foo/Non/ExistingPath"); err == nil { - t.Fatalf("error expected for non-existing symlink") - } - - if path != "" { - t.Fatalf("expected empty path, but '%s' was returned", path) - } -} - -// Reading a symlink to a file must fail -func TestReadSymlinkedDirectoryToFile(t *testing.T) { - var err error - var file *os.File - - if file, err = os.Create("/tmp/testReadSymlinkToFile"); err != nil { - t.Fatalf("failed to create file: %s", err) - } - - file.Close() - - if err = os.Symlink("/tmp/testReadSymlinkToFile", "/tmp/fileLinkTest"); err != nil { - t.Errorf("failed to create symlink: %s", err) - } - - var path string - if path, err = ReadSymlinkedDirectory("/tmp/fileLinkTest"); err == nil { - t.Fatalf("ReadSymlinkedDirectory on a symlink to a file should've failed") - } - - if path != "" { - t.Fatalf("path should've been empty: %s", path) - } - - if err = os.Remove("/tmp/testReadSymlinkToFile"); err != nil { - t.Errorf("failed to remove file: %s", err) - } - - if err = os.Remove("/tmp/fileLinkTest"); err != nil { - t.Errorf("failed to remove symlink: %s", err) - } -} - -func TestValidGitTransport(t *testing.T) { - for _, url := range []string{ - "git://github.com/docker/docker", - "git@github.com:docker/docker.git", - "https://github.com/docker/docker.git", - "http://github.com/docker/docker.git", - } { - if ValidGitTransport(url) == false { - t.Fatalf("%q should be detected as valid Git prefix", url) - } - } - - for _, url := range []string{ - "github.com/docker/docker", - } { - if ValidGitTransport(url) == true { - t.Fatalf("%q should not be detected as valid Git prefix", url) - } - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/common.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/common.go deleted file mode 100644 index e363aa793e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/common.go +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package tar implements access to tar archives. -// It aims to cover most of the variations, including those produced -// by GNU and BSD tars. -// -// References: -// http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5 -// http://www.gnu.org/software/tar/manual/html_node/Standard.html -// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html -package tar - -import ( - "bytes" - "errors" - "fmt" - "os" - "path" - "time" -) - -const ( - blockSize = 512 - - // Types - TypeReg = '0' // regular file - TypeRegA = '\x00' // regular file - TypeLink = '1' // hard link - TypeSymlink = '2' // symbolic link - TypeChar = '3' // character device node - TypeBlock = '4' // block device node - TypeDir = '5' // directory - TypeFifo = '6' // fifo node - TypeCont = '7' // reserved - TypeXHeader = 'x' // extended header - TypeXGlobalHeader = 'g' // global extended header - TypeGNULongName = 'L' // Next file has a long name - TypeGNULongLink = 'K' // Next file symlinks to a file w/ a long name - TypeGNUSparse = 'S' // sparse file -) - -// A Header represents a single header in a tar archive. -// Some fields may not be populated. -type Header struct { - Name string // name of header file entry - Mode int64 // permission and mode bits - Uid int // user id of owner - Gid int // group id of owner - Size int64 // length in bytes - ModTime time.Time // modified time - Typeflag byte // type of header entry - Linkname string // target name of link - Uname string // user name of owner - Gname string // group name of owner - Devmajor int64 // major number of character or block device - Devminor int64 // minor number of character or block device - AccessTime time.Time // access time - ChangeTime time.Time // status change time - Xattrs map[string]string -} - -// File name constants from the tar spec. -const ( - fileNameSize = 100 // Maximum number of bytes in a standard tar name. - fileNamePrefixSize = 155 // Maximum number of ustar extension bytes. -) - -// FileInfo returns an os.FileInfo for the Header. -func (h *Header) FileInfo() os.FileInfo { - return headerFileInfo{h} -} - -// headerFileInfo implements os.FileInfo. -type headerFileInfo struct { - h *Header -} - -func (fi headerFileInfo) Size() int64 { return fi.h.Size } -func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() } -func (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime } -func (fi headerFileInfo) Sys() interface{} { return fi.h } - -// Name returns the base name of the file. -func (fi headerFileInfo) Name() string { - if fi.IsDir() { - return path.Base(path.Clean(fi.h.Name)) - } - return path.Base(fi.h.Name) -} - -// Mode returns the permission and mode bits for the headerFileInfo. -func (fi headerFileInfo) Mode() (mode os.FileMode) { - // Set file permission bits. - mode = os.FileMode(fi.h.Mode).Perm() - - // Set setuid, setgid and sticky bits. - if fi.h.Mode&c_ISUID != 0 { - // setuid - mode |= os.ModeSetuid - } - if fi.h.Mode&c_ISGID != 0 { - // setgid - mode |= os.ModeSetgid - } - if fi.h.Mode&c_ISVTX != 0 { - // sticky - mode |= os.ModeSticky - } - - // Set file mode bits. - // clear perm, setuid, setgid and sticky bits. - m := os.FileMode(fi.h.Mode) &^ 07777 - if m == c_ISDIR { - // directory - mode |= os.ModeDir - } - if m == c_ISFIFO { - // named pipe (FIFO) - mode |= os.ModeNamedPipe - } - if m == c_ISLNK { - // symbolic link - mode |= os.ModeSymlink - } - if m == c_ISBLK { - // device file - mode |= os.ModeDevice - } - if m == c_ISCHR { - // Unix character device - mode |= os.ModeDevice - mode |= os.ModeCharDevice - } - if m == c_ISSOCK { - // Unix domain socket - mode |= os.ModeSocket - } - - switch fi.h.Typeflag { - case TypeLink, TypeSymlink: - // hard link, symbolic link - mode |= os.ModeSymlink - case TypeChar: - // character device node - mode |= os.ModeDevice - mode |= os.ModeCharDevice - case TypeBlock: - // block device node - mode |= os.ModeDevice - case TypeDir: - // directory - mode |= os.ModeDir - case TypeFifo: - // fifo node - mode |= os.ModeNamedPipe - } - - return mode -} - -// sysStat, if non-nil, populates h from system-dependent fields of fi. -var sysStat func(fi os.FileInfo, h *Header) error - -// Mode constants from the tar spec. -const ( - c_ISUID = 04000 // Set uid - c_ISGID = 02000 // Set gid - c_ISVTX = 01000 // Save text (sticky bit) - c_ISDIR = 040000 // Directory - c_ISFIFO = 010000 // FIFO - c_ISREG = 0100000 // Regular file - c_ISLNK = 0120000 // Symbolic link - c_ISBLK = 060000 // Block special file - c_ISCHR = 020000 // Character special file - c_ISSOCK = 0140000 // Socket -) - -// Keywords for the PAX Extended Header -const ( - paxAtime = "atime" - paxCharset = "charset" - paxComment = "comment" - paxCtime = "ctime" // please note that ctime is not a valid pax header. - paxGid = "gid" - paxGname = "gname" - paxLinkpath = "linkpath" - paxMtime = "mtime" - paxPath = "path" - paxSize = "size" - paxUid = "uid" - paxUname = "uname" - paxXattr = "SCHILY.xattr." - paxNone = "" -) - -// FileInfoHeader creates a partially-populated Header from fi. -// If fi describes a symlink, FileInfoHeader records link as the link target. -// If fi describes a directory, a slash is appended to the name. -// Because os.FileInfo's Name method returns only the base name of -// the file it describes, it may be necessary to modify the Name field -// of the returned header to provide the full path name of the file. -func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { - if fi == nil { - return nil, errors.New("tar: FileInfo is nil") - } - fm := fi.Mode() - h := &Header{ - Name: fi.Name(), - ModTime: fi.ModTime(), - Mode: int64(fm.Perm()), // or'd with c_IS* constants later - } - switch { - case fm.IsRegular(): - h.Mode |= c_ISREG - h.Typeflag = TypeReg - h.Size = fi.Size() - case fi.IsDir(): - h.Typeflag = TypeDir - h.Mode |= c_ISDIR - h.Name += "/" - case fm&os.ModeSymlink != 0: - h.Typeflag = TypeSymlink - h.Mode |= c_ISLNK - h.Linkname = link - case fm&os.ModeDevice != 0: - if fm&os.ModeCharDevice != 0 { - h.Mode |= c_ISCHR - h.Typeflag = TypeChar - } else { - h.Mode |= c_ISBLK - h.Typeflag = TypeBlock - } - case fm&os.ModeNamedPipe != 0: - h.Typeflag = TypeFifo - h.Mode |= c_ISFIFO - case fm&os.ModeSocket != 0: - h.Mode |= c_ISSOCK - default: - return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm) - } - if fm&os.ModeSetuid != 0 { - h.Mode |= c_ISUID - } - if fm&os.ModeSetgid != 0 { - h.Mode |= c_ISGID - } - if fm&os.ModeSticky != 0 { - h.Mode |= c_ISVTX - } - if sysStat != nil { - return h, sysStat(fi, h) - } - return h, nil -} - -var zeroBlock = make([]byte, blockSize) - -// POSIX specifies a sum of the unsigned byte values, but the Sun tar uses signed byte values. -// We compute and return both. -func checksum(header []byte) (unsigned int64, signed int64) { - for i := 0; i < len(header); i++ { - if i == 148 { - // The chksum field (header[148:156]) is special: it should be treated as space bytes. - unsigned += ' ' * 8 - signed += ' ' * 8 - i += 7 - continue - } - unsigned += int64(header[i]) - signed += int64(int8(header[i])) - } - return -} - -type slicer []byte - -func (sp *slicer) next(n int) (b []byte) { - s := *sp - b, *sp = s[0:n], s[n:] - return -} - -func isASCII(s string) bool { - for _, c := range s { - if c >= 0x80 { - return false - } - } - return true -} - -func toASCII(s string) string { - if isASCII(s) { - return s - } - var buf bytes.Buffer - for _, c := range s { - if c < 0x80 { - buf.WriteByte(byte(c)) - } - } - return buf.String() -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/example_test.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/example_test.go deleted file mode 100644 index 351eaa0e6c..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/example_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tar_test - -import ( - "archive/tar" - "bytes" - "fmt" - "io" - "log" - "os" -) - -func Example() { - // Create a buffer to write our archive to. - buf := new(bytes.Buffer) - - // Create a new tar archive. - tw := tar.NewWriter(buf) - - // Add some files to the archive. - var files = []struct { - Name, Body string - }{ - {"readme.txt", "This archive contains some text files."}, - {"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"}, - {"todo.txt", "Get animal handling licence."}, - } - for _, file := range files { - hdr := &tar.Header{ - Name: file.Name, - Size: int64(len(file.Body)), - } - if err := tw.WriteHeader(hdr); err != nil { - log.Fatalln(err) - } - if _, err := tw.Write([]byte(file.Body)); err != nil { - log.Fatalln(err) - } - } - // Make sure to check the error on Close. - if err := tw.Close(); err != nil { - log.Fatalln(err) - } - - // Open the tar archive for reading. - r := bytes.NewReader(buf.Bytes()) - tr := tar.NewReader(r) - - // Iterate through the files in the archive. - for { - hdr, err := tr.Next() - if err == io.EOF { - // end of tar archive - break - } - if err != nil { - log.Fatalln(err) - } - fmt.Printf("Contents of %s:\n", hdr.Name) - if _, err := io.Copy(os.Stdout, tr); err != nil { - log.Fatalln(err) - } - fmt.Println() - } - - // Output: - // Contents of readme.txt: - // This archive contains some text files. - // Contents of gopher.txt: - // Gopher names: - // George - // Geoffrey - // Gonzo - // Contents of todo.txt: - // Get animal handling licence. -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/reader.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/reader.go deleted file mode 100644 index a27559d0f0..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/reader.go +++ /dev/null @@ -1,820 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tar - -// TODO(dsymonds): -// - pax extensions - -import ( - "bytes" - "errors" - "io" - "io/ioutil" - "os" - "strconv" - "strings" - "time" -) - -var ( - ErrHeader = errors.New("archive/tar: invalid tar header") -) - -const maxNanoSecondIntSize = 9 - -// A Reader provides sequential access to the contents of a tar archive. -// A tar archive consists of a sequence of files. -// The Next method advances to the next file in the archive (including the first), -// and then it can be treated as an io.Reader to access the file's data. -type Reader struct { - r io.Reader - err error - pad int64 // amount of padding (ignored) after current file entry - curr numBytesReader // reader for current file entry - hdrBuff [blockSize]byte // buffer to use in readHeader -} - -// A numBytesReader is an io.Reader with a numBytes method, returning the number -// of bytes remaining in the underlying encoded data. -type numBytesReader interface { - io.Reader - numBytes() int64 -} - -// A regFileReader is a numBytesReader for reading file data from a tar archive. -type regFileReader struct { - r io.Reader // underlying reader - nb int64 // number of unread bytes for current file entry -} - -// A sparseFileReader is a numBytesReader for reading sparse file data from a tar archive. -type sparseFileReader struct { - rfr *regFileReader // reads the sparse-encoded file data - sp []sparseEntry // the sparse map for the file - pos int64 // keeps track of file position - tot int64 // total size of the file -} - -// Keywords for GNU sparse files in a PAX extended header -const ( - paxGNUSparseNumBlocks = "GNU.sparse.numblocks" - paxGNUSparseOffset = "GNU.sparse.offset" - paxGNUSparseNumBytes = "GNU.sparse.numbytes" - paxGNUSparseMap = "GNU.sparse.map" - paxGNUSparseName = "GNU.sparse.name" - paxGNUSparseMajor = "GNU.sparse.major" - paxGNUSparseMinor = "GNU.sparse.minor" - paxGNUSparseSize = "GNU.sparse.size" - paxGNUSparseRealSize = "GNU.sparse.realsize" -) - -// Keywords for old GNU sparse headers -const ( - oldGNUSparseMainHeaderOffset = 386 - oldGNUSparseMainHeaderIsExtendedOffset = 482 - oldGNUSparseMainHeaderNumEntries = 4 - oldGNUSparseExtendedHeaderIsExtendedOffset = 504 - oldGNUSparseExtendedHeaderNumEntries = 21 - oldGNUSparseOffsetSize = 12 - oldGNUSparseNumBytesSize = 12 -) - -// NewReader creates a new Reader reading from r. -func NewReader(r io.Reader) *Reader { return &Reader{r: r} } - -// Next advances to the next entry in the tar archive. -func (tr *Reader) Next() (*Header, error) { - var hdr *Header - if tr.err == nil { - tr.skipUnread() - } - if tr.err != nil { - return hdr, tr.err - } - hdr = tr.readHeader() - if hdr == nil { - return hdr, tr.err - } - // Check for PAX/GNU header. - switch hdr.Typeflag { - case TypeXHeader: - // PAX extended header - headers, err := parsePAX(tr) - if err != nil { - return nil, err - } - // We actually read the whole file, - // but this skips alignment padding - tr.skipUnread() - hdr = tr.readHeader() - mergePAX(hdr, headers) - - // Check for a PAX format sparse file - sp, err := tr.checkForGNUSparsePAXHeaders(hdr, headers) - if err != nil { - tr.err = err - return nil, err - } - if sp != nil { - // Current file is a PAX format GNU sparse file. - // Set the current file reader to a sparse file reader. - tr.curr = &sparseFileReader{rfr: tr.curr.(*regFileReader), sp: sp, tot: hdr.Size} - } - return hdr, nil - case TypeGNULongName: - // We have a GNU long name header. Its contents are the real file name. - realname, err := ioutil.ReadAll(tr) - if err != nil { - return nil, err - } - hdr, err := tr.Next() - hdr.Name = cString(realname) - return hdr, err - case TypeGNULongLink: - // We have a GNU long link header. - realname, err := ioutil.ReadAll(tr) - if err != nil { - return nil, err - } - hdr, err := tr.Next() - hdr.Linkname = cString(realname) - return hdr, err - } - return hdr, tr.err -} - -// checkForGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers. If they are found, then -// this function reads the sparse map and returns it. Unknown sparse formats are ignored, causing the file to -// be treated as a regular file. -func (tr *Reader) checkForGNUSparsePAXHeaders(hdr *Header, headers map[string]string) ([]sparseEntry, error) { - var sparseFormat string - - // Check for sparse format indicators - major, majorOk := headers[paxGNUSparseMajor] - minor, minorOk := headers[paxGNUSparseMinor] - sparseName, sparseNameOk := headers[paxGNUSparseName] - _, sparseMapOk := headers[paxGNUSparseMap] - sparseSize, sparseSizeOk := headers[paxGNUSparseSize] - sparseRealSize, sparseRealSizeOk := headers[paxGNUSparseRealSize] - - // Identify which, if any, sparse format applies from which PAX headers are set - if majorOk && minorOk { - sparseFormat = major + "." + minor - } else if sparseNameOk && sparseMapOk { - sparseFormat = "0.1" - } else if sparseSizeOk { - sparseFormat = "0.0" - } else { - // Not a PAX format GNU sparse file. - return nil, nil - } - - // Check for unknown sparse format - if sparseFormat != "0.0" && sparseFormat != "0.1" && sparseFormat != "1.0" { - return nil, nil - } - - // Update hdr from GNU sparse PAX headers - if sparseNameOk { - hdr.Name = sparseName - } - if sparseSizeOk { - realSize, err := strconv.ParseInt(sparseSize, 10, 0) - if err != nil { - return nil, ErrHeader - } - hdr.Size = realSize - } else if sparseRealSizeOk { - realSize, err := strconv.ParseInt(sparseRealSize, 10, 0) - if err != nil { - return nil, ErrHeader - } - hdr.Size = realSize - } - - // Set up the sparse map, according to the particular sparse format in use - var sp []sparseEntry - var err error - switch sparseFormat { - case "0.0", "0.1": - sp, err = readGNUSparseMap0x1(headers) - case "1.0": - sp, err = readGNUSparseMap1x0(tr.curr) - } - return sp, err -} - -// mergePAX merges well known headers according to PAX standard. -// In general headers with the same name as those found -// in the header struct overwrite those found in the header -// struct with higher precision or longer values. Esp. useful -// for name and linkname fields. -func mergePAX(hdr *Header, headers map[string]string) error { - for k, v := range headers { - switch k { - case paxPath: - hdr.Name = v - case paxLinkpath: - hdr.Linkname = v - case paxGname: - hdr.Gname = v - case paxUname: - hdr.Uname = v - case paxUid: - uid, err := strconv.ParseInt(v, 10, 0) - if err != nil { - return err - } - hdr.Uid = int(uid) - case paxGid: - gid, err := strconv.ParseInt(v, 10, 0) - if err != nil { - return err - } - hdr.Gid = int(gid) - case paxAtime: - t, err := parsePAXTime(v) - if err != nil { - return err - } - hdr.AccessTime = t - case paxMtime: - t, err := parsePAXTime(v) - if err != nil { - return err - } - hdr.ModTime = t - case paxCtime: - t, err := parsePAXTime(v) - if err != nil { - return err - } - hdr.ChangeTime = t - case paxSize: - size, err := strconv.ParseInt(v, 10, 0) - if err != nil { - return err - } - hdr.Size = int64(size) - default: - if strings.HasPrefix(k, paxXattr) { - if hdr.Xattrs == nil { - hdr.Xattrs = make(map[string]string) - } - hdr.Xattrs[k[len(paxXattr):]] = v - } - } - } - return nil -} - -// parsePAXTime takes a string of the form %d.%d as described in -// the PAX specification. -func parsePAXTime(t string) (time.Time, error) { - buf := []byte(t) - pos := bytes.IndexByte(buf, '.') - var seconds, nanoseconds int64 - var err error - if pos == -1 { - seconds, err = strconv.ParseInt(t, 10, 0) - if err != nil { - return time.Time{}, err - } - } else { - seconds, err = strconv.ParseInt(string(buf[:pos]), 10, 0) - if err != nil { - return time.Time{}, err - } - nano_buf := string(buf[pos+1:]) - // Pad as needed before converting to a decimal. - // For example .030 -> .030000000 -> 30000000 nanoseconds - if len(nano_buf) < maxNanoSecondIntSize { - // Right pad - nano_buf += strings.Repeat("0", maxNanoSecondIntSize-len(nano_buf)) - } else if len(nano_buf) > maxNanoSecondIntSize { - // Right truncate - nano_buf = nano_buf[:maxNanoSecondIntSize] - } - nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0) - if err != nil { - return time.Time{}, err - } - } - ts := time.Unix(seconds, nanoseconds) - return ts, nil -} - -// parsePAX parses PAX headers. -// If an extended header (type 'x') is invalid, ErrHeader is returned -func parsePAX(r io.Reader) (map[string]string, error) { - buf, err := ioutil.ReadAll(r) - if err != nil { - return nil, err - } - - // For GNU PAX sparse format 0.0 support. - // This function transforms the sparse format 0.0 headers into sparse format 0.1 headers. - var sparseMap bytes.Buffer - - headers := make(map[string]string) - // Each record is constructed as - // "%d %s=%s\n", length, keyword, value - for len(buf) > 0 { - // or the header was empty to start with. - var sp int - // The size field ends at the first space. - sp = bytes.IndexByte(buf, ' ') - if sp == -1 { - return nil, ErrHeader - } - // Parse the first token as a decimal integer. - n, err := strconv.ParseInt(string(buf[:sp]), 10, 0) - if err != nil { - return nil, ErrHeader - } - // Extract everything between the decimal and the n -1 on the - // beginning to eat the ' ', -1 on the end to skip the newline. - var record []byte - record, buf = buf[sp+1:n-1], buf[n:] - // The first equals is guaranteed to mark the end of the key. - // Everything else is value. - eq := bytes.IndexByte(record, '=') - if eq == -1 { - return nil, ErrHeader - } - key, value := record[:eq], record[eq+1:] - - keyStr := string(key) - if keyStr == paxGNUSparseOffset || keyStr == paxGNUSparseNumBytes { - // GNU sparse format 0.0 special key. Write to sparseMap instead of using the headers map. - sparseMap.Write(value) - sparseMap.Write([]byte{','}) - } else { - // Normal key. Set the value in the headers map. - headers[keyStr] = string(value) - } - } - if sparseMap.Len() != 0 { - // Add sparse info to headers, chopping off the extra comma - sparseMap.Truncate(sparseMap.Len() - 1) - headers[paxGNUSparseMap] = sparseMap.String() - } - return headers, nil -} - -// cString parses bytes as a NUL-terminated C-style string. -// If a NUL byte is not found then the whole slice is returned as a string. -func cString(b []byte) string { - n := 0 - for n < len(b) && b[n] != 0 { - n++ - } - return string(b[0:n]) -} - -func (tr *Reader) octal(b []byte) int64 { - // Check for binary format first. - if len(b) > 0 && b[0]&0x80 != 0 { - var x int64 - for i, c := range b { - if i == 0 { - c &= 0x7f // ignore signal bit in first byte - } - x = x<<8 | int64(c) - } - return x - } - - // Because unused fields are filled with NULs, we need - // to skip leading NULs. Fields may also be padded with - // spaces or NULs. - // So we remove leading and trailing NULs and spaces to - // be sure. - b = bytes.Trim(b, " \x00") - - if len(b) == 0 { - return 0 - } - x, err := strconv.ParseUint(cString(b), 8, 64) - if err != nil { - tr.err = err - } - return int64(x) -} - -// skipUnread skips any unread bytes in the existing file entry, as well as any alignment padding. -func (tr *Reader) skipUnread() { - nr := tr.numBytes() + tr.pad // number of bytes to skip - tr.curr, tr.pad = nil, 0 - if sr, ok := tr.r.(io.Seeker); ok { - if _, err := sr.Seek(nr, os.SEEK_CUR); err == nil { - return - } - } - _, tr.err = io.CopyN(ioutil.Discard, tr.r, nr) -} - -func (tr *Reader) verifyChecksum(header []byte) bool { - if tr.err != nil { - return false - } - - given := tr.octal(header[148:156]) - unsigned, signed := checksum(header) - return given == unsigned || given == signed -} - -func (tr *Reader) readHeader() *Header { - header := tr.hdrBuff[:] - copy(header, zeroBlock) - - if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil { - return nil - } - - // Two blocks of zero bytes marks the end of the archive. - if bytes.Equal(header, zeroBlock[0:blockSize]) { - if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil { - return nil - } - if bytes.Equal(header, zeroBlock[0:blockSize]) { - tr.err = io.EOF - } else { - tr.err = ErrHeader // zero block and then non-zero block - } - return nil - } - - if !tr.verifyChecksum(header) { - tr.err = ErrHeader - return nil - } - - // Unpack - hdr := new(Header) - s := slicer(header) - - hdr.Name = cString(s.next(100)) - hdr.Mode = tr.octal(s.next(8)) - hdr.Uid = int(tr.octal(s.next(8))) - hdr.Gid = int(tr.octal(s.next(8))) - hdr.Size = tr.octal(s.next(12)) - hdr.ModTime = time.Unix(tr.octal(s.next(12)), 0) - s.next(8) // chksum - hdr.Typeflag = s.next(1)[0] - hdr.Linkname = cString(s.next(100)) - - // The remainder of the header depends on the value of magic. - // The original (v7) version of tar had no explicit magic field, - // so its magic bytes, like the rest of the block, are NULs. - magic := string(s.next(8)) // contains version field as well. - var format string - switch { - case magic[:6] == "ustar\x00": // POSIX tar (1003.1-1988) - if string(header[508:512]) == "tar\x00" { - format = "star" - } else { - format = "posix" - } - case magic == "ustar \x00": // old GNU tar - format = "gnu" - } - - switch format { - case "posix", "gnu", "star": - hdr.Uname = cString(s.next(32)) - hdr.Gname = cString(s.next(32)) - devmajor := s.next(8) - devminor := s.next(8) - if hdr.Typeflag == TypeChar || hdr.Typeflag == TypeBlock { - hdr.Devmajor = tr.octal(devmajor) - hdr.Devminor = tr.octal(devminor) - } - var prefix string - switch format { - case "posix", "gnu": - prefix = cString(s.next(155)) - case "star": - prefix = cString(s.next(131)) - hdr.AccessTime = time.Unix(tr.octal(s.next(12)), 0) - hdr.ChangeTime = time.Unix(tr.octal(s.next(12)), 0) - } - if len(prefix) > 0 { - hdr.Name = prefix + "/" + hdr.Name - } - } - - if tr.err != nil { - tr.err = ErrHeader - return nil - } - - // Maximum value of hdr.Size is 64 GB (12 octal digits), - // so there's no risk of int64 overflowing. - nb := int64(hdr.Size) - tr.pad = -nb & (blockSize - 1) // blockSize is a power of two - - // Set the current file reader. - tr.curr = ®FileReader{r: tr.r, nb: nb} - - // Check for old GNU sparse format entry. - if hdr.Typeflag == TypeGNUSparse { - // Get the real size of the file. - hdr.Size = tr.octal(header[483:495]) - - // Read the sparse map. - sp := tr.readOldGNUSparseMap(header) - if tr.err != nil { - return nil - } - // Current file is a GNU sparse file. Update the current file reader. - tr.curr = &sparseFileReader{rfr: tr.curr.(*regFileReader), sp: sp, tot: hdr.Size} - } - - return hdr -} - -// A sparseEntry holds a single entry in a sparse file's sparse map. -// A sparse entry indicates the offset and size in a sparse file of a -// block of data. -type sparseEntry struct { - offset int64 - numBytes int64 -} - -// readOldGNUSparseMap reads the sparse map as stored in the old GNU sparse format. -// The sparse map is stored in the tar header if it's small enough. If it's larger than four entries, -// then one or more extension headers are used to store the rest of the sparse map. -func (tr *Reader) readOldGNUSparseMap(header []byte) []sparseEntry { - isExtended := header[oldGNUSparseMainHeaderIsExtendedOffset] != 0 - spCap := oldGNUSparseMainHeaderNumEntries - if isExtended { - spCap += oldGNUSparseExtendedHeaderNumEntries - } - sp := make([]sparseEntry, 0, spCap) - s := slicer(header[oldGNUSparseMainHeaderOffset:]) - - // Read the four entries from the main tar header - for i := 0; i < oldGNUSparseMainHeaderNumEntries; i++ { - offset := tr.octal(s.next(oldGNUSparseOffsetSize)) - numBytes := tr.octal(s.next(oldGNUSparseNumBytesSize)) - if tr.err != nil { - tr.err = ErrHeader - return nil - } - if offset == 0 && numBytes == 0 { - break - } - sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes}) - } - - for isExtended { - // There are more entries. Read an extension header and parse its entries. - sparseHeader := make([]byte, blockSize) - if _, tr.err = io.ReadFull(tr.r, sparseHeader); tr.err != nil { - return nil - } - isExtended = sparseHeader[oldGNUSparseExtendedHeaderIsExtendedOffset] != 0 - s = slicer(sparseHeader) - for i := 0; i < oldGNUSparseExtendedHeaderNumEntries; i++ { - offset := tr.octal(s.next(oldGNUSparseOffsetSize)) - numBytes := tr.octal(s.next(oldGNUSparseNumBytesSize)) - if tr.err != nil { - tr.err = ErrHeader - return nil - } - if offset == 0 && numBytes == 0 { - break - } - sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes}) - } - } - return sp -} - -// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0. -// The sparse map is stored just before the file data and padded out to the nearest block boundary. -func readGNUSparseMap1x0(r io.Reader) ([]sparseEntry, error) { - buf := make([]byte, 2*blockSize) - sparseHeader := buf[:blockSize] - - // readDecimal is a helper function to read a decimal integer from the sparse map - // while making sure to read from the file in blocks of size blockSize - readDecimal := func() (int64, error) { - // Look for newline - nl := bytes.IndexByte(sparseHeader, '\n') - if nl == -1 { - if len(sparseHeader) >= blockSize { - // This is an error - return 0, ErrHeader - } - oldLen := len(sparseHeader) - newLen := oldLen + blockSize - if cap(sparseHeader) < newLen { - // There's more header, but we need to make room for the next block - copy(buf, sparseHeader) - sparseHeader = buf[:newLen] - } else { - // There's more header, and we can just reslice - sparseHeader = sparseHeader[:newLen] - } - - // Now that sparseHeader is large enough, read next block - if _, err := io.ReadFull(r, sparseHeader[oldLen:newLen]); err != nil { - return 0, err - } - - // Look for a newline in the new data - nl = bytes.IndexByte(sparseHeader[oldLen:newLen], '\n') - if nl == -1 { - // This is an error - return 0, ErrHeader - } - nl += oldLen // We want the position from the beginning - } - // Now that we've found a newline, read a number - n, err := strconv.ParseInt(string(sparseHeader[:nl]), 10, 0) - if err != nil { - return 0, ErrHeader - } - - // Update sparseHeader to consume this number - sparseHeader = sparseHeader[nl+1:] - return n, nil - } - - // Read the first block - if _, err := io.ReadFull(r, sparseHeader); err != nil { - return nil, err - } - - // The first line contains the number of entries - numEntries, err := readDecimal() - if err != nil { - return nil, err - } - - // Read all the entries - sp := make([]sparseEntry, 0, numEntries) - for i := int64(0); i < numEntries; i++ { - // Read the offset - offset, err := readDecimal() - if err != nil { - return nil, err - } - // Read numBytes - numBytes, err := readDecimal() - if err != nil { - return nil, err - } - - sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes}) - } - - return sp, nil -} - -// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format version 0.1. -// The sparse map is stored in the PAX headers. -func readGNUSparseMap0x1(headers map[string]string) ([]sparseEntry, error) { - // Get number of entries - numEntriesStr, ok := headers[paxGNUSparseNumBlocks] - if !ok { - return nil, ErrHeader - } - numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) - if err != nil { - return nil, ErrHeader - } - - sparseMap := strings.Split(headers[paxGNUSparseMap], ",") - - // There should be two numbers in sparseMap for each entry - if int64(len(sparseMap)) != 2*numEntries { - return nil, ErrHeader - } - - // Loop through the entries in the sparse map - sp := make([]sparseEntry, 0, numEntries) - for i := int64(0); i < numEntries; i++ { - offset, err := strconv.ParseInt(sparseMap[2*i], 10, 0) - if err != nil { - return nil, ErrHeader - } - numBytes, err := strconv.ParseInt(sparseMap[2*i+1], 10, 0) - if err != nil { - return nil, ErrHeader - } - sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes}) - } - - return sp, nil -} - -// numBytes returns the number of bytes left to read in the current file's entry -// in the tar archive, or 0 if there is no current file. -func (tr *Reader) numBytes() int64 { - if tr.curr == nil { - // No current file, so no bytes - return 0 - } - return tr.curr.numBytes() -} - -// Read reads from the current entry in the tar archive. -// It returns 0, io.EOF when it reaches the end of that entry, -// until Next is called to advance to the next entry. -func (tr *Reader) Read(b []byte) (n int, err error) { - if tr.curr == nil { - return 0, io.EOF - } - n, err = tr.curr.Read(b) - if err != nil && err != io.EOF { - tr.err = err - } - return -} - -func (rfr *regFileReader) Read(b []byte) (n int, err error) { - if rfr.nb == 0 { - // file consumed - return 0, io.EOF - } - if int64(len(b)) > rfr.nb { - b = b[0:rfr.nb] - } - n, err = rfr.r.Read(b) - rfr.nb -= int64(n) - - if err == io.EOF && rfr.nb > 0 { - err = io.ErrUnexpectedEOF - } - return -} - -// numBytes returns the number of bytes left to read in the file's data in the tar archive. -func (rfr *regFileReader) numBytes() int64 { - return rfr.nb -} - -// readHole reads a sparse file hole ending at offset toOffset -func (sfr *sparseFileReader) readHole(b []byte, toOffset int64) int { - n64 := toOffset - sfr.pos - if n64 > int64(len(b)) { - n64 = int64(len(b)) - } - n := int(n64) - for i := 0; i < n; i++ { - b[i] = 0 - } - sfr.pos += n64 - return n -} - -// Read reads the sparse file data in expanded form. -func (sfr *sparseFileReader) Read(b []byte) (n int, err error) { - if len(sfr.sp) == 0 { - // No more data fragments to read from. - if sfr.pos < sfr.tot { - // We're in the last hole - n = sfr.readHole(b, sfr.tot) - return - } - // Otherwise, we're at the end of the file - return 0, io.EOF - } - if sfr.pos < sfr.sp[0].offset { - // We're in a hole - n = sfr.readHole(b, sfr.sp[0].offset) - return - } - - // We're not in a hole, so we'll read from the next data fragment - posInFragment := sfr.pos - sfr.sp[0].offset - bytesLeft := sfr.sp[0].numBytes - posInFragment - if int64(len(b)) > bytesLeft { - b = b[0:bytesLeft] - } - - n, err = sfr.rfr.Read(b) - sfr.pos += int64(n) - - if int64(n) == bytesLeft { - // We're done with this fragment - sfr.sp = sfr.sp[1:] - } - - if err == io.EOF && sfr.pos < sfr.tot { - // We reached the end of the last fragment's data, but there's a final hole - err = nil - } - return -} - -// numBytes returns the number of bytes left to read in the sparse file's -// sparse-encoded data in the tar archive. -func (sfr *sparseFileReader) numBytes() int64 { - return sfr.rfr.nb -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/reader_test.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/reader_test.go deleted file mode 100644 index 9601ffe459..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/reader_test.go +++ /dev/null @@ -1,743 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tar - -import ( - "bytes" - "crypto/md5" - "fmt" - "io" - "io/ioutil" - "os" - "reflect" - "strings" - "testing" - "time" -) - -type untarTest struct { - file string - headers []*Header - cksums []string -} - -var gnuTarTest = &untarTest{ - file: "testdata/gnu.tar", - headers: []*Header{ - { - Name: "small.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 5, - ModTime: time.Unix(1244428340, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - }, - { - Name: "small2.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 11, - ModTime: time.Unix(1244436044, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - }, - }, - cksums: []string{ - "e38b27eaccb4391bdec553a7f3ae6b2f", - "c65bd2e50a56a2138bf1716f2fd56fe9", - }, -} - -var sparseTarTest = &untarTest{ - file: "testdata/sparse-formats.tar", - headers: []*Header{ - { - Name: "sparse-gnu", - Mode: 420, - Uid: 1000, - Gid: 1000, - Size: 200, - ModTime: time.Unix(1392395740, 0), - Typeflag: 0x53, - Linkname: "", - Uname: "david", - Gname: "david", - Devmajor: 0, - Devminor: 0, - }, - { - Name: "sparse-posix-0.0", - Mode: 420, - Uid: 1000, - Gid: 1000, - Size: 200, - ModTime: time.Unix(1392342187, 0), - Typeflag: 0x30, - Linkname: "", - Uname: "david", - Gname: "david", - Devmajor: 0, - Devminor: 0, - }, - { - Name: "sparse-posix-0.1", - Mode: 420, - Uid: 1000, - Gid: 1000, - Size: 200, - ModTime: time.Unix(1392340456, 0), - Typeflag: 0x30, - Linkname: "", - Uname: "david", - Gname: "david", - Devmajor: 0, - Devminor: 0, - }, - { - Name: "sparse-posix-1.0", - Mode: 420, - Uid: 1000, - Gid: 1000, - Size: 200, - ModTime: time.Unix(1392337404, 0), - Typeflag: 0x30, - Linkname: "", - Uname: "david", - Gname: "david", - Devmajor: 0, - Devminor: 0, - }, - { - Name: "end", - Mode: 420, - Uid: 1000, - Gid: 1000, - Size: 4, - ModTime: time.Unix(1392398319, 0), - Typeflag: 0x30, - Linkname: "", - Uname: "david", - Gname: "david", - Devmajor: 0, - Devminor: 0, - }, - }, - cksums: []string{ - "6f53234398c2449fe67c1812d993012f", - "6f53234398c2449fe67c1812d993012f", - "6f53234398c2449fe67c1812d993012f", - "6f53234398c2449fe67c1812d993012f", - "b0061974914468de549a2af8ced10316", - }, -} - -var untarTests = []*untarTest{ - gnuTarTest, - sparseTarTest, - { - file: "testdata/star.tar", - headers: []*Header{ - { - Name: "small.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 5, - ModTime: time.Unix(1244592783, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - AccessTime: time.Unix(1244592783, 0), - ChangeTime: time.Unix(1244592783, 0), - }, - { - Name: "small2.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 11, - ModTime: time.Unix(1244592783, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - AccessTime: time.Unix(1244592783, 0), - ChangeTime: time.Unix(1244592783, 0), - }, - }, - }, - { - file: "testdata/v7.tar", - headers: []*Header{ - { - Name: "small.txt", - Mode: 0444, - Uid: 73025, - Gid: 5000, - Size: 5, - ModTime: time.Unix(1244593104, 0), - Typeflag: '\x00', - }, - { - Name: "small2.txt", - Mode: 0444, - Uid: 73025, - Gid: 5000, - Size: 11, - ModTime: time.Unix(1244593104, 0), - Typeflag: '\x00', - }, - }, - }, - { - file: "testdata/pax.tar", - headers: []*Header{ - { - Name: "a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", - Mode: 0664, - Uid: 1000, - Gid: 1000, - Uname: "shane", - Gname: "shane", - Size: 7, - ModTime: time.Unix(1350244992, 23960108), - ChangeTime: time.Unix(1350244992, 23960108), - AccessTime: time.Unix(1350244992, 23960108), - Typeflag: TypeReg, - }, - { - Name: "a/b", - Mode: 0777, - Uid: 1000, - Gid: 1000, - Uname: "shane", - Gname: "shane", - Size: 0, - ModTime: time.Unix(1350266320, 910238425), - ChangeTime: time.Unix(1350266320, 910238425), - AccessTime: time.Unix(1350266320, 910238425), - Typeflag: TypeSymlink, - Linkname: "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", - }, - }, - }, - { - file: "testdata/nil-uid.tar", // golang.org/issue/5290 - headers: []*Header{ - { - Name: "P1050238.JPG.log", - Mode: 0664, - Uid: 0, - Gid: 0, - Size: 14, - ModTime: time.Unix(1365454838, 0), - Typeflag: TypeReg, - Linkname: "", - Uname: "eyefi", - Gname: "eyefi", - Devmajor: 0, - Devminor: 0, - }, - }, - }, - { - file: "testdata/xattrs.tar", - headers: []*Header{ - { - Name: "small.txt", - Mode: 0644, - Uid: 1000, - Gid: 10, - Size: 5, - ModTime: time.Unix(1386065770, 448252320), - Typeflag: '0', - Uname: "alex", - Gname: "wheel", - AccessTime: time.Unix(1389782991, 419875220), - ChangeTime: time.Unix(1389782956, 794414986), - Xattrs: map[string]string{ - "user.key": "value", - "user.key2": "value2", - // Interestingly, selinux encodes the terminating null inside the xattr - "security.selinux": "unconfined_u:object_r:default_t:s0\x00", - }, - }, - { - Name: "small2.txt", - Mode: 0644, - Uid: 1000, - Gid: 10, - Size: 11, - ModTime: time.Unix(1386065770, 449252304), - Typeflag: '0', - Uname: "alex", - Gname: "wheel", - AccessTime: time.Unix(1389782991, 419875220), - ChangeTime: time.Unix(1386065770, 449252304), - Xattrs: map[string]string{ - "security.selinux": "unconfined_u:object_r:default_t:s0\x00", - }, - }, - }, - }, -} - -func TestReader(t *testing.T) { -testLoop: - for i, test := range untarTests { - f, err := os.Open(test.file) - if err != nil { - t.Errorf("test %d: Unexpected error: %v", i, err) - continue - } - defer f.Close() - tr := NewReader(f) - for j, header := range test.headers { - hdr, err := tr.Next() - if err != nil || hdr == nil { - t.Errorf("test %d, entry %d: Didn't get entry: %v", i, j, err) - f.Close() - continue testLoop - } - if !reflect.DeepEqual(*hdr, *header) { - t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v", - i, j, *hdr, *header) - } - } - hdr, err := tr.Next() - if err == io.EOF { - continue testLoop - } - if hdr != nil || err != nil { - t.Errorf("test %d: Unexpected entry or error: hdr=%v err=%v", i, hdr, err) - } - } -} - -func TestPartialRead(t *testing.T) { - f, err := os.Open("testdata/gnu.tar") - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - defer f.Close() - - tr := NewReader(f) - - // Read the first four bytes; Next() should skip the last byte. - hdr, err := tr.Next() - if err != nil || hdr == nil { - t.Fatalf("Didn't get first file: %v", err) - } - buf := make([]byte, 4) - if _, err := io.ReadFull(tr, buf); err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if expected := []byte("Kilt"); !bytes.Equal(buf, expected) { - t.Errorf("Contents = %v, want %v", buf, expected) - } - - // Second file - hdr, err = tr.Next() - if err != nil || hdr == nil { - t.Fatalf("Didn't get second file: %v", err) - } - buf = make([]byte, 6) - if _, err := io.ReadFull(tr, buf); err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if expected := []byte("Google"); !bytes.Equal(buf, expected) { - t.Errorf("Contents = %v, want %v", buf, expected) - } -} - -func TestIncrementalRead(t *testing.T) { - test := gnuTarTest - f, err := os.Open(test.file) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - defer f.Close() - - tr := NewReader(f) - - headers := test.headers - cksums := test.cksums - nread := 0 - - // loop over all files - for ; ; nread++ { - hdr, err := tr.Next() - if hdr == nil || err == io.EOF { - break - } - - // check the header - if !reflect.DeepEqual(*hdr, *headers[nread]) { - t.Errorf("Incorrect header:\nhave %+v\nwant %+v", - *hdr, headers[nread]) - } - - // read file contents in little chunks EOF, - // checksumming all the way - h := md5.New() - rdbuf := make([]uint8, 8) - for { - nr, err := tr.Read(rdbuf) - if err == io.EOF { - break - } - if err != nil { - t.Errorf("Read: unexpected error %v\n", err) - break - } - h.Write(rdbuf[0:nr]) - } - // verify checksum - have := fmt.Sprintf("%x", h.Sum(nil)) - want := cksums[nread] - if want != have { - t.Errorf("Bad checksum on file %s:\nhave %+v\nwant %+v", hdr.Name, have, want) - } - } - if nread != len(headers) { - t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(headers), nread) - } -} - -func TestNonSeekable(t *testing.T) { - test := gnuTarTest - f, err := os.Open(test.file) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - defer f.Close() - - type readerOnly struct { - io.Reader - } - tr := NewReader(readerOnly{f}) - nread := 0 - - for ; ; nread++ { - _, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - } - - if nread != len(test.headers) { - t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(test.headers), nread) - } -} - -func TestParsePAXHeader(t *testing.T) { - paxTests := [][3]string{ - {"a", "a=name", "10 a=name\n"}, // Test case involving multiple acceptable lengths - {"a", "a=name", "9 a=name\n"}, // Test case involving multiple acceptable length - {"mtime", "mtime=1350244992.023960108", "30 mtime=1350244992.023960108\n"}} - for _, test := range paxTests { - key, expected, raw := test[0], test[1], test[2] - reader := bytes.NewReader([]byte(raw)) - headers, err := parsePAX(reader) - if err != nil { - t.Errorf("Couldn't parse correctly formatted headers: %v", err) - continue - } - if strings.EqualFold(headers[key], expected) { - t.Errorf("mtime header incorrectly parsed: got %s, wanted %s", headers[key], expected) - continue - } - trailer := make([]byte, 100) - n, err := reader.Read(trailer) - if err != io.EOF || n != 0 { - t.Error("Buffer wasn't consumed") - } - } - badHeader := bytes.NewReader([]byte("3 somelongkey=")) - if _, err := parsePAX(badHeader); err != ErrHeader { - t.Fatal("Unexpected success when parsing bad header") - } -} - -func TestParsePAXTime(t *testing.T) { - // Some valid PAX time values - timestamps := map[string]time.Time{ - "1350244992.023960108": time.Unix(1350244992, 23960108), // The common case - "1350244992.02396010": time.Unix(1350244992, 23960100), // Lower precision value - "1350244992.0239601089": time.Unix(1350244992, 23960108), // Higher precision value - "1350244992": time.Unix(1350244992, 0), // Low precision value - } - for input, expected := range timestamps { - ts, err := parsePAXTime(input) - if err != nil { - t.Fatal(err) - } - if !ts.Equal(expected) { - t.Fatalf("Time parsing failure %s %s", ts, expected) - } - } -} - -func TestMergePAX(t *testing.T) { - hdr := new(Header) - // Test a string, integer, and time based value. - headers := map[string]string{ - "path": "a/b/c", - "uid": "1000", - "mtime": "1350244992.023960108", - } - err := mergePAX(hdr, headers) - if err != nil { - t.Fatal(err) - } - want := &Header{ - Name: "a/b/c", - Uid: 1000, - ModTime: time.Unix(1350244992, 23960108), - } - if !reflect.DeepEqual(hdr, want) { - t.Errorf("incorrect merge: got %+v, want %+v", hdr, want) - } -} - -func TestSparseEndToEnd(t *testing.T) { - test := sparseTarTest - f, err := os.Open(test.file) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - defer f.Close() - - tr := NewReader(f) - - headers := test.headers - cksums := test.cksums - nread := 0 - - // loop over all files - for ; ; nread++ { - hdr, err := tr.Next() - if hdr == nil || err == io.EOF { - break - } - - // check the header - if !reflect.DeepEqual(*hdr, *headers[nread]) { - t.Errorf("Incorrect header:\nhave %+v\nwant %+v", - *hdr, headers[nread]) - } - - // read and checksum the file data - h := md5.New() - _, err = io.Copy(h, tr) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - // verify checksum - have := fmt.Sprintf("%x", h.Sum(nil)) - want := cksums[nread] - if want != have { - t.Errorf("Bad checksum on file %s:\nhave %+v\nwant %+v", hdr.Name, have, want) - } - } - if nread != len(headers) { - t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(headers), nread) - } -} - -type sparseFileReadTest struct { - sparseData []byte - sparseMap []sparseEntry - realSize int64 - expected []byte -} - -var sparseFileReadTests = []sparseFileReadTest{ - { - sparseData: []byte("abcde"), - sparseMap: []sparseEntry{ - {offset: 0, numBytes: 2}, - {offset: 5, numBytes: 3}, - }, - realSize: 8, - expected: []byte("ab\x00\x00\x00cde"), - }, - { - sparseData: []byte("abcde"), - sparseMap: []sparseEntry{ - {offset: 0, numBytes: 2}, - {offset: 5, numBytes: 3}, - }, - realSize: 10, - expected: []byte("ab\x00\x00\x00cde\x00\x00"), - }, - { - sparseData: []byte("abcde"), - sparseMap: []sparseEntry{ - {offset: 1, numBytes: 3}, - {offset: 6, numBytes: 2}, - }, - realSize: 8, - expected: []byte("\x00abc\x00\x00de"), - }, - { - sparseData: []byte("abcde"), - sparseMap: []sparseEntry{ - {offset: 1, numBytes: 3}, - {offset: 6, numBytes: 2}, - }, - realSize: 10, - expected: []byte("\x00abc\x00\x00de\x00\x00"), - }, - { - sparseData: []byte(""), - sparseMap: nil, - realSize: 2, - expected: []byte("\x00\x00"), - }, -} - -func TestSparseFileReader(t *testing.T) { - for i, test := range sparseFileReadTests { - r := bytes.NewReader(test.sparseData) - nb := int64(r.Len()) - sfr := &sparseFileReader{ - rfr: ®FileReader{r: r, nb: nb}, - sp: test.sparseMap, - pos: 0, - tot: test.realSize, - } - if sfr.numBytes() != nb { - t.Errorf("test %d: Before reading, sfr.numBytes() = %d, want %d", i, sfr.numBytes(), nb) - } - buf, err := ioutil.ReadAll(sfr) - if err != nil { - t.Errorf("test %d: Unexpected error: %v", i, err) - } - if e := test.expected; !bytes.Equal(buf, e) { - t.Errorf("test %d: Contents = %v, want %v", i, buf, e) - } - if sfr.numBytes() != 0 { - t.Errorf("test %d: After draining the reader, numBytes() was nonzero", i) - } - } -} - -func TestSparseIncrementalRead(t *testing.T) { - sparseMap := []sparseEntry{{10, 2}} - sparseData := []byte("Go") - expected := "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Go\x00\x00\x00\x00\x00\x00\x00\x00" - - r := bytes.NewReader(sparseData) - nb := int64(r.Len()) - sfr := &sparseFileReader{ - rfr: ®FileReader{r: r, nb: nb}, - sp: sparseMap, - pos: 0, - tot: int64(len(expected)), - } - - // We'll read the data 6 bytes at a time, with a hole of size 10 at - // the beginning and one of size 8 at the end. - var outputBuf bytes.Buffer - buf := make([]byte, 6) - for { - n, err := sfr.Read(buf) - if err == io.EOF { - break - } - if err != nil { - t.Errorf("Read: unexpected error %v\n", err) - } - if n > 0 { - _, err := outputBuf.Write(buf[:n]) - if err != nil { - t.Errorf("Write: unexpected error %v\n", err) - } - } - } - got := outputBuf.String() - if got != expected { - t.Errorf("Contents = %v, want %v", got, expected) - } -} - -func TestReadGNUSparseMap0x1(t *testing.T) { - headers := map[string]string{ - paxGNUSparseNumBlocks: "4", - paxGNUSparseMap: "0,5,10,5,20,5,30,5", - } - expected := []sparseEntry{ - {offset: 0, numBytes: 5}, - {offset: 10, numBytes: 5}, - {offset: 20, numBytes: 5}, - {offset: 30, numBytes: 5}, - } - - sp, err := readGNUSparseMap0x1(headers) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if !reflect.DeepEqual(sp, expected) { - t.Errorf("Incorrect sparse map: got %v, wanted %v", sp, expected) - } -} - -func TestReadGNUSparseMap1x0(t *testing.T) { - // This test uses lots of holes so the sparse header takes up more than two blocks - numEntries := 100 - expected := make([]sparseEntry, 0, numEntries) - sparseMap := new(bytes.Buffer) - - fmt.Fprintf(sparseMap, "%d\n", numEntries) - for i := 0; i < numEntries; i++ { - offset := int64(2048 * i) - numBytes := int64(1024) - expected = append(expected, sparseEntry{offset: offset, numBytes: numBytes}) - fmt.Fprintf(sparseMap, "%d\n%d\n", offset, numBytes) - } - - // Make the header the smallest multiple of blockSize that fits the sparseMap - headerBlocks := (sparseMap.Len() + blockSize - 1) / blockSize - bufLen := blockSize * headerBlocks - buf := make([]byte, bufLen) - copy(buf, sparseMap.Bytes()) - - // Get an reader to read the sparse map - r := bytes.NewReader(buf) - - // Read the sparse map - sp, err := readGNUSparseMap1x0(r) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if !reflect.DeepEqual(sp, expected) { - t.Errorf("Incorrect sparse map: got %v, wanted %v", sp, expected) - } -} - -func TestUninitializedRead(t *testing.T) { - test := gnuTarTest - f, err := os.Open(test.file) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - defer f.Close() - - tr := NewReader(f) - _, err = tr.Read([]byte{}) - if err == nil || err != io.EOF { - t.Errorf("Unexpected error: %v, wanted %v", err, io.EOF) - } - -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_atim.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_atim.go deleted file mode 100644 index cf9cc79c59..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_atim.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux dragonfly openbsd solaris - -package tar - -import ( - "syscall" - "time" -) - -func statAtime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Atim.Unix()) -} - -func statCtime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Ctim.Unix()) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_atimespec.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_atimespec.go deleted file mode 100644 index 6f17dbe307..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_atimespec.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin freebsd netbsd - -package tar - -import ( - "syscall" - "time" -) - -func statAtime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Atimespec.Unix()) -} - -func statCtime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Ctimespec.Unix()) -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_unix.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_unix.go deleted file mode 100644 index cb843db4cf..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/stat_unix.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux darwin dragonfly freebsd openbsd netbsd solaris - -package tar - -import ( - "os" - "syscall" -) - -func init() { - sysStat = statUnix -} - -func statUnix(fi os.FileInfo, h *Header) error { - sys, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return nil - } - h.Uid = int(sys.Uid) - h.Gid = int(sys.Gid) - // TODO(bradfitz): populate username & group. os/user - // doesn't cache LookupId lookups, and lacks group - // lookup functions. - h.AccessTime = statAtime(sys) - h.ChangeTime = statCtime(sys) - // TODO(bradfitz): major/minor device numbers? - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/tar_test.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/tar_test.go deleted file mode 100644 index ed333f3ea4..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/tar_test.go +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tar - -import ( - "bytes" - "io/ioutil" - "os" - "path" - "reflect" - "strings" - "testing" - "time" -) - -func TestFileInfoHeader(t *testing.T) { - fi, err := os.Stat("testdata/small.txt") - if err != nil { - t.Fatal(err) - } - h, err := FileInfoHeader(fi, "") - if err != nil { - t.Fatalf("FileInfoHeader: %v", err) - } - if g, e := h.Name, "small.txt"; g != e { - t.Errorf("Name = %q; want %q", g, e) - } - if g, e := h.Mode, int64(fi.Mode().Perm())|c_ISREG; g != e { - t.Errorf("Mode = %#o; want %#o", g, e) - } - if g, e := h.Size, int64(5); g != e { - t.Errorf("Size = %v; want %v", g, e) - } - if g, e := h.ModTime, fi.ModTime(); !g.Equal(e) { - t.Errorf("ModTime = %v; want %v", g, e) - } - // FileInfoHeader should error when passing nil FileInfo - if _, err := FileInfoHeader(nil, ""); err == nil { - t.Fatalf("Expected error when passing nil to FileInfoHeader") - } -} - -func TestFileInfoHeaderDir(t *testing.T) { - fi, err := os.Stat("testdata") - if err != nil { - t.Fatal(err) - } - h, err := FileInfoHeader(fi, "") - if err != nil { - t.Fatalf("FileInfoHeader: %v", err) - } - if g, e := h.Name, "testdata/"; g != e { - t.Errorf("Name = %q; want %q", g, e) - } - // Ignoring c_ISGID for golang.org/issue/4867 - if g, e := h.Mode&^c_ISGID, int64(fi.Mode().Perm())|c_ISDIR; g != e { - t.Errorf("Mode = %#o; want %#o", g, e) - } - if g, e := h.Size, int64(0); g != e { - t.Errorf("Size = %v; want %v", g, e) - } - if g, e := h.ModTime, fi.ModTime(); !g.Equal(e) { - t.Errorf("ModTime = %v; want %v", g, e) - } -} - -func TestFileInfoHeaderSymlink(t *testing.T) { - h, err := FileInfoHeader(symlink{}, "some-target") - if err != nil { - t.Fatal(err) - } - if g, e := h.Name, "some-symlink"; g != e { - t.Errorf("Name = %q; want %q", g, e) - } - if g, e := h.Linkname, "some-target"; g != e { - t.Errorf("Linkname = %q; want %q", g, e) - } -} - -type symlink struct{} - -func (symlink) Name() string { return "some-symlink" } -func (symlink) Size() int64 { return 0 } -func (symlink) Mode() os.FileMode { return os.ModeSymlink } -func (symlink) ModTime() time.Time { return time.Time{} } -func (symlink) IsDir() bool { return false } -func (symlink) Sys() interface{} { return nil } - -func TestRoundTrip(t *testing.T) { - data := []byte("some file contents") - - var b bytes.Buffer - tw := NewWriter(&b) - hdr := &Header{ - Name: "file.txt", - Uid: 1 << 21, // too big for 8 octal digits - Size: int64(len(data)), - ModTime: time.Now(), - } - // tar only supports second precision. - hdr.ModTime = hdr.ModTime.Add(-time.Duration(hdr.ModTime.Nanosecond()) * time.Nanosecond) - if err := tw.WriteHeader(hdr); err != nil { - t.Fatalf("tw.WriteHeader: %v", err) - } - if _, err := tw.Write(data); err != nil { - t.Fatalf("tw.Write: %v", err) - } - if err := tw.Close(); err != nil { - t.Fatalf("tw.Close: %v", err) - } - - // Read it back. - tr := NewReader(&b) - rHdr, err := tr.Next() - if err != nil { - t.Fatalf("tr.Next: %v", err) - } - if !reflect.DeepEqual(rHdr, hdr) { - t.Errorf("Header mismatch.\n got %+v\nwant %+v", rHdr, hdr) - } - rData, err := ioutil.ReadAll(tr) - if err != nil { - t.Fatalf("Read: %v", err) - } - if !bytes.Equal(rData, data) { - t.Errorf("Data mismatch.\n got %q\nwant %q", rData, data) - } -} - -type headerRoundTripTest struct { - h *Header - fm os.FileMode -} - -func TestHeaderRoundTrip(t *testing.T) { - golden := []headerRoundTripTest{ - // regular file. - { - h: &Header{ - Name: "test.txt", - Mode: 0644 | c_ISREG, - Size: 12, - ModTime: time.Unix(1360600916, 0), - Typeflag: TypeReg, - }, - fm: 0644, - }, - // hard link. - { - h: &Header{ - Name: "hard.txt", - Mode: 0644 | c_ISLNK, - Size: 0, - ModTime: time.Unix(1360600916, 0), - Typeflag: TypeLink, - }, - fm: 0644 | os.ModeSymlink, - }, - // symbolic link. - { - h: &Header{ - Name: "link.txt", - Mode: 0777 | c_ISLNK, - Size: 0, - ModTime: time.Unix(1360600852, 0), - Typeflag: TypeSymlink, - }, - fm: 0777 | os.ModeSymlink, - }, - // character device node. - { - h: &Header{ - Name: "dev/null", - Mode: 0666 | c_ISCHR, - Size: 0, - ModTime: time.Unix(1360578951, 0), - Typeflag: TypeChar, - }, - fm: 0666 | os.ModeDevice | os.ModeCharDevice, - }, - // block device node. - { - h: &Header{ - Name: "dev/sda", - Mode: 0660 | c_ISBLK, - Size: 0, - ModTime: time.Unix(1360578954, 0), - Typeflag: TypeBlock, - }, - fm: 0660 | os.ModeDevice, - }, - // directory. - { - h: &Header{ - Name: "dir/", - Mode: 0755 | c_ISDIR, - Size: 0, - ModTime: time.Unix(1360601116, 0), - Typeflag: TypeDir, - }, - fm: 0755 | os.ModeDir, - }, - // fifo node. - { - h: &Header{ - Name: "dev/initctl", - Mode: 0600 | c_ISFIFO, - Size: 0, - ModTime: time.Unix(1360578949, 0), - Typeflag: TypeFifo, - }, - fm: 0600 | os.ModeNamedPipe, - }, - // setuid. - { - h: &Header{ - Name: "bin/su", - Mode: 0755 | c_ISREG | c_ISUID, - Size: 23232, - ModTime: time.Unix(1355405093, 0), - Typeflag: TypeReg, - }, - fm: 0755 | os.ModeSetuid, - }, - // setguid. - { - h: &Header{ - Name: "group.txt", - Mode: 0750 | c_ISREG | c_ISGID, - Size: 0, - ModTime: time.Unix(1360602346, 0), - Typeflag: TypeReg, - }, - fm: 0750 | os.ModeSetgid, - }, - // sticky. - { - h: &Header{ - Name: "sticky.txt", - Mode: 0600 | c_ISREG | c_ISVTX, - Size: 7, - ModTime: time.Unix(1360602540, 0), - Typeflag: TypeReg, - }, - fm: 0600 | os.ModeSticky, - }, - } - - for i, g := range golden { - fi := g.h.FileInfo() - h2, err := FileInfoHeader(fi, "") - if err != nil { - t.Error(err) - continue - } - if strings.Contains(fi.Name(), "/") { - t.Errorf("FileInfo of %q contains slash: %q", g.h.Name, fi.Name()) - } - name := path.Base(g.h.Name) - if fi.IsDir() { - name += "/" - } - if got, want := h2.Name, name; got != want { - t.Errorf("i=%d: Name: got %v, want %v", i, got, want) - } - if got, want := h2.Size, g.h.Size; got != want { - t.Errorf("i=%d: Size: got %v, want %v", i, got, want) - } - if got, want := h2.Mode, g.h.Mode; got != want { - t.Errorf("i=%d: Mode: got %o, want %o", i, got, want) - } - if got, want := fi.Mode(), g.fm; got != want { - t.Errorf("i=%d: fi.Mode: got %o, want %o", i, got, want) - } - if got, want := h2.ModTime, g.h.ModTime; got != want { - t.Errorf("i=%d: ModTime: got %v, want %v", i, got, want) - } - if sysh, ok := fi.Sys().(*Header); !ok || sysh != g.h { - t.Errorf("i=%d: Sys didn't return original *Header", i) - } - } -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/gnu.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/gnu.tar deleted file mode 100644 index fc899dc8dc..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/gnu.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/nil-uid.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/nil-uid.tar deleted file mode 100644 index cc9cfaa33c..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/nil-uid.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/pax.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/pax.tar deleted file mode 100644 index 9bc24b6587..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/pax.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/small.txt b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/small.txt deleted file mode 100644 index b249bfc518..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/small.txt +++ /dev/null @@ -1 +0,0 @@ -Kilts \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/small2.txt b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/small2.txt deleted file mode 100644 index 394ee3ecd0..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/small2.txt +++ /dev/null @@ -1 +0,0 @@ -Google.com diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/sparse-formats.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/sparse-formats.tar deleted file mode 100644 index 8bd4e74d50..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/sparse-formats.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/star.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/star.tar deleted file mode 100644 index 59e2d4e604..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/star.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/ustar.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/ustar.tar deleted file mode 100644 index 29679d9a30..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/ustar.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/v7.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/v7.tar deleted file mode 100644 index eb65fc9410..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/v7.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer-big-long.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer-big-long.tar deleted file mode 100644 index 5960ee8247..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer-big-long.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer-big.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer-big.tar deleted file mode 100644 index 753e883ceb..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer-big.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer.tar deleted file mode 100644 index e6d816ad07..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/writer.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/xattrs.tar b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/xattrs.tar deleted file mode 100644 index 9701950edd..0000000000 Binary files a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/testdata/xattrs.tar and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go deleted file mode 100644 index dafb2cabf3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go +++ /dev/null @@ -1,396 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tar - -// TODO(dsymonds): -// - catch more errors (no first header, etc.) - -import ( - "bytes" - "errors" - "fmt" - "io" - "os" - "path" - "strconv" - "strings" - "time" -) - -var ( - ErrWriteTooLong = errors.New("archive/tar: write too long") - ErrFieldTooLong = errors.New("archive/tar: header field too long") - ErrWriteAfterClose = errors.New("archive/tar: write after close") - errNameTooLong = errors.New("archive/tar: name too long") - errInvalidHeader = errors.New("archive/tar: header field too long or contains invalid values") -) - -// A Writer provides sequential writing of a tar archive in POSIX.1 format. -// A tar archive consists of a sequence of files. -// Call WriteHeader to begin a new file, and then call Write to supply that file's data, -// writing at most hdr.Size bytes in total. -type Writer struct { - w io.Writer - err error - nb int64 // number of unwritten bytes for current file entry - pad int64 // amount of padding to write after current file entry - closed bool - usedBinary bool // whether the binary numeric field extension was used - preferPax bool // use pax header instead of binary numeric header - hdrBuff [blockSize]byte // buffer to use in writeHeader when writing a regular header - paxHdrBuff [blockSize]byte // buffer to use in writeHeader when writing a pax header -} - -// NewWriter creates a new Writer writing to w. -func NewWriter(w io.Writer) *Writer { return &Writer{w: w} } - -// Flush finishes writing the current file (optional). -func (tw *Writer) Flush() error { - if tw.nb > 0 { - tw.err = fmt.Errorf("archive/tar: missed writing %d bytes", tw.nb) - return tw.err - } - - n := tw.nb + tw.pad - for n > 0 && tw.err == nil { - nr := n - if nr > blockSize { - nr = blockSize - } - var nw int - nw, tw.err = tw.w.Write(zeroBlock[0:nr]) - n -= int64(nw) - } - tw.nb = 0 - tw.pad = 0 - return tw.err -} - -// Write s into b, terminating it with a NUL if there is room. -// If the value is too long for the field and allowPax is true add a paxheader record instead -func (tw *Writer) cString(b []byte, s string, allowPax bool, paxKeyword string, paxHeaders map[string]string) { - needsPaxHeader := allowPax && len(s) > len(b) || !isASCII(s) - if needsPaxHeader { - paxHeaders[paxKeyword] = s - return - } - if len(s) > len(b) { - if tw.err == nil { - tw.err = ErrFieldTooLong - } - return - } - ascii := toASCII(s) - copy(b, ascii) - if len(ascii) < len(b) { - b[len(ascii)] = 0 - } -} - -// Encode x as an octal ASCII string and write it into b with leading zeros. -func (tw *Writer) octal(b []byte, x int64) { - s := strconv.FormatInt(x, 8) - // leading zeros, but leave room for a NUL. - for len(s)+1 < len(b) { - s = "0" + s - } - tw.cString(b, s, false, paxNone, nil) -} - -// Write x into b, either as octal or as binary (GNUtar/star extension). -// If the value is too long for the field and writingPax is enabled both for the field and the add a paxheader record instead -func (tw *Writer) numeric(b []byte, x int64, allowPax bool, paxKeyword string, paxHeaders map[string]string) { - // Try octal first. - s := strconv.FormatInt(x, 8) - if len(s) < len(b) { - tw.octal(b, x) - return - } - - // If it is too long for octal, and pax is preferred, use a pax header - if allowPax && tw.preferPax { - tw.octal(b, 0) - s := strconv.FormatInt(x, 10) - paxHeaders[paxKeyword] = s - return - } - - // Too big: use binary (big-endian). - tw.usedBinary = true - for i := len(b) - 1; x > 0 && i >= 0; i-- { - b[i] = byte(x) - x >>= 8 - } - b[0] |= 0x80 // highest bit indicates binary format -} - -var ( - minTime = time.Unix(0, 0) - // There is room for 11 octal digits (33 bits) of mtime. - maxTime = minTime.Add((1<<33 - 1) * time.Second) -) - -// WriteHeader writes hdr and prepares to accept the file's contents. -// WriteHeader calls Flush if it is not the first header. -// Calling after a Close will return ErrWriteAfterClose. -func (tw *Writer) WriteHeader(hdr *Header) error { - return tw.writeHeader(hdr, true) -} - -// WriteHeader writes hdr and prepares to accept the file's contents. -// WriteHeader calls Flush if it is not the first header. -// Calling after a Close will return ErrWriteAfterClose. -// As this method is called internally by writePax header to allow it to -// suppress writing the pax header. -func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error { - if tw.closed { - return ErrWriteAfterClose - } - if tw.err == nil { - tw.Flush() - } - if tw.err != nil { - return tw.err - } - - // a map to hold pax header records, if any are needed - paxHeaders := make(map[string]string) - - // TODO(shanemhansen): we might want to use PAX headers for - // subsecond time resolution, but for now let's just capture - // too long fields or non ascii characters - - var header []byte - - // We need to select which scratch buffer to use carefully, - // since this method is called recursively to write PAX headers. - // If allowPax is true, this is the non-recursive call, and we will use hdrBuff. - // If allowPax is false, we are being called by writePAXHeader, and hdrBuff is - // already being used by the non-recursive call, so we must use paxHdrBuff. - header = tw.hdrBuff[:] - if !allowPax { - header = tw.paxHdrBuff[:] - } - copy(header, zeroBlock) - s := slicer(header) - - // keep a reference to the filename to allow to overwrite it later if we detect that we can use ustar longnames instead of pax - pathHeaderBytes := s.next(fileNameSize) - - tw.cString(pathHeaderBytes, hdr.Name, true, paxPath, paxHeaders) - - // Handle out of range ModTime carefully. - var modTime int64 - if !hdr.ModTime.Before(minTime) && !hdr.ModTime.After(maxTime) { - modTime = hdr.ModTime.Unix() - } - - tw.octal(s.next(8), hdr.Mode) // 100:108 - tw.numeric(s.next(8), int64(hdr.Uid), true, paxUid, paxHeaders) // 108:116 - tw.numeric(s.next(8), int64(hdr.Gid), true, paxGid, paxHeaders) // 116:124 - tw.numeric(s.next(12), hdr.Size, true, paxSize, paxHeaders) // 124:136 - tw.numeric(s.next(12), modTime, false, paxNone, nil) // 136:148 --- consider using pax for finer granularity - s.next(8) // chksum (148:156) - s.next(1)[0] = hdr.Typeflag // 156:157 - - tw.cString(s.next(100), hdr.Linkname, true, paxLinkpath, paxHeaders) - - copy(s.next(8), []byte("ustar\x0000")) // 257:265 - tw.cString(s.next(32), hdr.Uname, true, paxUname, paxHeaders) // 265:297 - tw.cString(s.next(32), hdr.Gname, true, paxGname, paxHeaders) // 297:329 - tw.numeric(s.next(8), hdr.Devmajor, false, paxNone, nil) // 329:337 - tw.numeric(s.next(8), hdr.Devminor, false, paxNone, nil) // 337:345 - - // keep a reference to the prefix to allow to overwrite it later if we detect that we can use ustar longnames instead of pax - prefixHeaderBytes := s.next(155) - tw.cString(prefixHeaderBytes, "", false, paxNone, nil) // 345:500 prefix - - // Use the GNU magic instead of POSIX magic if we used any GNU extensions. - if tw.usedBinary { - copy(header[257:265], []byte("ustar \x00")) - } - - _, paxPathUsed := paxHeaders[paxPath] - // try to use a ustar header when only the name is too long - if !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed { - suffix := hdr.Name - prefix := "" - if len(hdr.Name) > fileNameSize && isASCII(hdr.Name) { - var err error - prefix, suffix, err = tw.splitUSTARLongName(hdr.Name) - if err == nil { - // ok we can use a ustar long name instead of pax, now correct the fields - - // remove the path field from the pax header. this will suppress the pax header - delete(paxHeaders, paxPath) - - // update the path fields - tw.cString(pathHeaderBytes, suffix, false, paxNone, nil) - tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil) - - // Use the ustar magic if we used ustar long names. - if len(prefix) > 0 && !tw.usedBinary { - copy(header[257:265], []byte("ustar\x00")) - } - } - } - } - - // The chksum field is terminated by a NUL and a space. - // This is different from the other octal fields. - chksum, _ := checksum(header) - tw.octal(header[148:155], chksum) - header[155] = ' ' - - if tw.err != nil { - // problem with header; probably integer too big for a field. - return tw.err - } - - if allowPax { - for k, v := range hdr.Xattrs { - paxHeaders[paxXattr+k] = v - } - } - - if len(paxHeaders) > 0 { - if !allowPax { - return errInvalidHeader - } - if err := tw.writePAXHeader(hdr, paxHeaders); err != nil { - return err - } - } - tw.nb = int64(hdr.Size) - tw.pad = (blockSize - (tw.nb % blockSize)) % blockSize - - _, tw.err = tw.w.Write(header) - return tw.err -} - -// writeUSTARLongName splits a USTAR long name hdr.Name. -// name must be < 256 characters. errNameTooLong is returned -// if hdr.Name can't be split. The splitting heuristic -// is compatible with gnu tar. -func (tw *Writer) splitUSTARLongName(name string) (prefix, suffix string, err error) { - length := len(name) - if length > fileNamePrefixSize+1 { - length = fileNamePrefixSize + 1 - } else if name[length-1] == '/' { - length-- - } - i := strings.LastIndex(name[:length], "/") - // nlen contains the resulting length in the name field. - // plen contains the resulting length in the prefix field. - nlen := len(name) - i - 1 - plen := i - if i <= 0 || nlen > fileNameSize || nlen == 0 || plen > fileNamePrefixSize { - err = errNameTooLong - return - } - prefix, suffix = name[:i], name[i+1:] - return -} - -// writePaxHeader writes an extended pax header to the -// archive. -func (tw *Writer) writePAXHeader(hdr *Header, paxHeaders map[string]string) error { - // Prepare extended header - ext := new(Header) - ext.Typeflag = TypeXHeader - // Setting ModTime is required for reader parsing to - // succeed, and seems harmless enough. - ext.ModTime = hdr.ModTime - // The spec asks that we namespace our pseudo files - // with the current pid. - pid := os.Getpid() - dir, file := path.Split(hdr.Name) - fullName := path.Join(dir, - fmt.Sprintf("PaxHeaders.%d", pid), file) - - ascii := toASCII(fullName) - if len(ascii) > 100 { - ascii = ascii[:100] - } - ext.Name = ascii - // Construct the body - var buf bytes.Buffer - - for k, v := range paxHeaders { - fmt.Fprint(&buf, paxHeader(k+"="+v)) - } - - ext.Size = int64(len(buf.Bytes())) - if err := tw.writeHeader(ext, false); err != nil { - return err - } - if _, err := tw.Write(buf.Bytes()); err != nil { - return err - } - if err := tw.Flush(); err != nil { - return err - } - return nil -} - -// paxHeader formats a single pax record, prefixing it with the appropriate length -func paxHeader(msg string) string { - const padding = 2 // Extra padding for space and newline - size := len(msg) + padding - size += len(strconv.Itoa(size)) - record := fmt.Sprintf("%d %s\n", size, msg) - if len(record) != size { - // Final adjustment if adding size increased - // the number of digits in size - size = len(record) - record = fmt.Sprintf("%d %s\n", size, msg) - } - return record -} - -// Write writes to the current entry in the tar archive. -// Write returns the error ErrWriteTooLong if more than -// hdr.Size bytes are written after WriteHeader. -func (tw *Writer) Write(b []byte) (n int, err error) { - if tw.closed { - err = ErrWriteTooLong - return - } - overwrite := false - if int64(len(b)) > tw.nb { - b = b[0:tw.nb] - overwrite = true - } - n, err = tw.w.Write(b) - tw.nb -= int64(n) - if err == nil && overwrite { - err = ErrWriteTooLong - return - } - tw.err = err - return -} - -// Close closes the tar archive, flushing any unwritten -// data to the underlying writer. -func (tw *Writer) Close() error { - if tw.err != nil || tw.closed { - return tw.err - } - tw.Flush() - tw.closed = true - if tw.err != nil { - return tw.err - } - - // trailer: two zero blocks - for i := 0; i < 2; i++ { - _, tw.err = tw.w.Write(zeroBlock) - if tw.err != nil { - break - } - } - return tw.err -} diff --git a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go b/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go deleted file mode 100644 index 5e42e322f9..0000000000 --- a/Godeps/_workspace/src/github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go +++ /dev/null @@ -1,491 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tar - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "reflect" - "strings" - "testing" - "testing/iotest" - "time" -) - -type writerTestEntry struct { - header *Header - contents string -} - -type writerTest struct { - file string // filename of expected output - entries []*writerTestEntry -} - -var writerTests = []*writerTest{ - // The writer test file was produced with this command: - // tar (GNU tar) 1.26 - // ln -s small.txt link.txt - // tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt - { - file: "testdata/writer.tar", - entries: []*writerTestEntry{ - { - header: &Header{ - Name: "small.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 5, - ModTime: time.Unix(1246508266, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - }, - contents: "Kilts", - }, - { - header: &Header{ - Name: "small2.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 11, - ModTime: time.Unix(1245217492, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - }, - contents: "Google.com\n", - }, - { - header: &Header{ - Name: "link.txt", - Mode: 0777, - Uid: 1000, - Gid: 1000, - Size: 0, - ModTime: time.Unix(1314603082, 0), - Typeflag: '2', - Linkname: "small.txt", - Uname: "strings", - Gname: "strings", - }, - // no contents - }, - }, - }, - // The truncated test file was produced using these commands: - // dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt - // tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar - { - file: "testdata/writer-big.tar", - entries: []*writerTestEntry{ - { - header: &Header{ - Name: "tmp/16gig.txt", - Mode: 0640, - Uid: 73025, - Gid: 5000, - Size: 16 << 30, - ModTime: time.Unix(1254699560, 0), - Typeflag: '0', - Uname: "dsymonds", - Gname: "eng", - }, - // fake contents - contents: strings.Repeat("\x00", 4<<10), - }, - }, - }, - // The truncated test file was produced using these commands: - // dd if=/dev/zero bs=1048576 count=16384 > (longname/)*15 /16gig.txt - // tar -b 1 -c -f- (longname/)*15 /16gig.txt | dd bs=512 count=8 > writer-big-long.tar - { - file: "testdata/writer-big-long.tar", - entries: []*writerTestEntry{ - { - header: &Header{ - Name: strings.Repeat("longname/", 15) + "16gig.txt", - Mode: 0644, - Uid: 1000, - Gid: 1000, - Size: 16 << 30, - ModTime: time.Unix(1399583047, 0), - Typeflag: '0', - Uname: "guillaume", - Gname: "guillaume", - }, - // fake contents - contents: strings.Repeat("\x00", 4<<10), - }, - }, - }, - // This file was produced using gnu tar 1.17 - // gnutar -b 4 --format=ustar (longname/)*15 + file.txt - { - file: "testdata/ustar.tar", - entries: []*writerTestEntry{ - { - header: &Header{ - Name: strings.Repeat("longname/", 15) + "file.txt", - Mode: 0644, - Uid: 0765, - Gid: 024, - Size: 06, - ModTime: time.Unix(1360135598, 0), - Typeflag: '0', - Uname: "shane", - Gname: "staff", - }, - contents: "hello\n", - }, - }, - }, -} - -// Render byte array in a two-character hexadecimal string, spaced for easy visual inspection. -func bytestr(offset int, b []byte) string { - const rowLen = 32 - s := fmt.Sprintf("%04x ", offset) - for _, ch := range b { - switch { - case '0' <= ch && ch <= '9', 'A' <= ch && ch <= 'Z', 'a' <= ch && ch <= 'z': - s += fmt.Sprintf(" %c", ch) - default: - s += fmt.Sprintf(" %02x", ch) - } - } - return s -} - -// Render a pseudo-diff between two blocks of bytes. -func bytediff(a []byte, b []byte) string { - const rowLen = 32 - s := fmt.Sprintf("(%d bytes vs. %d bytes)\n", len(a), len(b)) - for offset := 0; len(a)+len(b) > 0; offset += rowLen { - na, nb := rowLen, rowLen - if na > len(a) { - na = len(a) - } - if nb > len(b) { - nb = len(b) - } - sa := bytestr(offset, a[0:na]) - sb := bytestr(offset, b[0:nb]) - if sa != sb { - s += fmt.Sprintf("-%v\n+%v\n", sa, sb) - } - a = a[na:] - b = b[nb:] - } - return s -} - -func TestWriter(t *testing.T) { -testLoop: - for i, test := range writerTests { - expected, err := ioutil.ReadFile(test.file) - if err != nil { - t.Errorf("test %d: Unexpected error: %v", i, err) - continue - } - - buf := new(bytes.Buffer) - tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB - big := false - for j, entry := range test.entries { - big = big || entry.header.Size > 1<<10 - if err := tw.WriteHeader(entry.header); err != nil { - t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err) - continue testLoop - } - if _, err := io.WriteString(tw, entry.contents); err != nil { - t.Errorf("test %d, entry %d: Failed writing contents: %v", i, j, err) - continue testLoop - } - } - // Only interested in Close failures for the small tests. - if err := tw.Close(); err != nil && !big { - t.Errorf("test %d: Failed closing archive: %v", i, err) - continue testLoop - } - - actual := buf.Bytes() - if !bytes.Equal(expected, actual) { - t.Errorf("test %d: Incorrect result: (-=expected, +=actual)\n%v", - i, bytediff(expected, actual)) - } - if testing.Short() { // The second test is expensive. - break - } - } -} - -func TestPax(t *testing.T) { - // Create an archive with a large name - fileinfo, err := os.Stat("testdata/small.txt") - if err != nil { - t.Fatal(err) - } - hdr, err := FileInfoHeader(fileinfo, "") - if err != nil { - t.Fatalf("os.Stat: %v", err) - } - // Force a PAX long name to be written - longName := strings.Repeat("ab", 100) - contents := strings.Repeat(" ", int(hdr.Size)) - hdr.Name = longName - var buf bytes.Buffer - writer := NewWriter(&buf) - if err := writer.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if _, err = writer.Write([]byte(contents)); err != nil { - t.Fatal(err) - } - if err := writer.Close(); err != nil { - t.Fatal(err) - } - // Simple test to make sure PAX extensions are in effect - if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) { - t.Fatal("Expected at least one PAX header to be written.") - } - // Test that we can get a long name back out of the archive. - reader := NewReader(&buf) - hdr, err = reader.Next() - if err != nil { - t.Fatal(err) - } - if hdr.Name != longName { - t.Fatal("Couldn't recover long file name") - } -} - -func TestPaxSymlink(t *testing.T) { - // Create an archive with a large linkname - fileinfo, err := os.Stat("testdata/small.txt") - if err != nil { - t.Fatal(err) - } - hdr, err := FileInfoHeader(fileinfo, "") - hdr.Typeflag = TypeSymlink - if err != nil { - t.Fatalf("os.Stat:1 %v", err) - } - // Force a PAX long linkname to be written - longLinkname := strings.Repeat("1234567890/1234567890", 10) - hdr.Linkname = longLinkname - - hdr.Size = 0 - var buf bytes.Buffer - writer := NewWriter(&buf) - if err := writer.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if err := writer.Close(); err != nil { - t.Fatal(err) - } - // Simple test to make sure PAX extensions are in effect - if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) { - t.Fatal("Expected at least one PAX header to be written.") - } - // Test that we can get a long name back out of the archive. - reader := NewReader(&buf) - hdr, err = reader.Next() - if err != nil { - t.Fatal(err) - } - if hdr.Linkname != longLinkname { - t.Fatal("Couldn't recover long link name") - } -} - -func TestPaxNonAscii(t *testing.T) { - // Create an archive with non ascii. These should trigger a pax header - // because pax headers have a defined utf-8 encoding. - fileinfo, err := os.Stat("testdata/small.txt") - if err != nil { - t.Fatal(err) - } - - hdr, err := FileInfoHeader(fileinfo, "") - if err != nil { - t.Fatalf("os.Stat:1 %v", err) - } - - // some sample data - chineseFilename := "文件名" - chineseGroupname := "組" - chineseUsername := "用戶名" - - hdr.Name = chineseFilename - hdr.Gname = chineseGroupname - hdr.Uname = chineseUsername - - contents := strings.Repeat(" ", int(hdr.Size)) - - var buf bytes.Buffer - writer := NewWriter(&buf) - if err := writer.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if _, err = writer.Write([]byte(contents)); err != nil { - t.Fatal(err) - } - if err := writer.Close(); err != nil { - t.Fatal(err) - } - // Simple test to make sure PAX extensions are in effect - if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) { - t.Fatal("Expected at least one PAX header to be written.") - } - // Test that we can get a long name back out of the archive. - reader := NewReader(&buf) - hdr, err = reader.Next() - if err != nil { - t.Fatal(err) - } - if hdr.Name != chineseFilename { - t.Fatal("Couldn't recover unicode name") - } - if hdr.Gname != chineseGroupname { - t.Fatal("Couldn't recover unicode group") - } - if hdr.Uname != chineseUsername { - t.Fatal("Couldn't recover unicode user") - } -} - -func TestPaxXattrs(t *testing.T) { - xattrs := map[string]string{ - "user.key": "value", - } - - // Create an archive with an xattr - fileinfo, err := os.Stat("testdata/small.txt") - if err != nil { - t.Fatal(err) - } - hdr, err := FileInfoHeader(fileinfo, "") - if err != nil { - t.Fatalf("os.Stat: %v", err) - } - contents := "Kilts" - hdr.Xattrs = xattrs - var buf bytes.Buffer - writer := NewWriter(&buf) - if err := writer.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if _, err = writer.Write([]byte(contents)); err != nil { - t.Fatal(err) - } - if err := writer.Close(); err != nil { - t.Fatal(err) - } - // Test that we can get the xattrs back out of the archive. - reader := NewReader(&buf) - hdr, err = reader.Next() - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(hdr.Xattrs, xattrs) { - t.Fatalf("xattrs did not survive round trip: got %+v, want %+v", - hdr.Xattrs, xattrs) - } -} - -func TestPAXHeader(t *testing.T) { - medName := strings.Repeat("CD", 50) - longName := strings.Repeat("AB", 100) - paxTests := [][2]string{ - {paxPath + "=/etc/hosts", "19 path=/etc/hosts\n"}, - {"a=b", "6 a=b\n"}, // Single digit length - {"a=names", "11 a=names\n"}, // Test case involving carries - {paxPath + "=" + longName, fmt.Sprintf("210 path=%s\n", longName)}, - {paxPath + "=" + medName, fmt.Sprintf("110 path=%s\n", medName)}} - - for _, test := range paxTests { - key, expected := test[0], test[1] - if result := paxHeader(key); result != expected { - t.Fatalf("paxHeader: got %s, expected %s", result, expected) - } - } -} - -func TestUSTARLongName(t *testing.T) { - // Create an archive with a path that failed to split with USTAR extension in previous versions. - fileinfo, err := os.Stat("testdata/small.txt") - if err != nil { - t.Fatal(err) - } - hdr, err := FileInfoHeader(fileinfo, "") - hdr.Typeflag = TypeDir - if err != nil { - t.Fatalf("os.Stat:1 %v", err) - } - // Force a PAX long name to be written. The name was taken from a practical example - // that fails and replaced ever char through numbers to anonymize the sample. - longName := "/0000_0000000/00000-000000000/0000_0000000/00000-0000000000000/0000_0000000/00000-0000000-00000000/0000_0000000/00000000/0000_0000000/000/0000_0000000/00000000v00/0000_0000000/000000/0000_0000000/0000000/0000_0000000/00000y-00/0000/0000/00000000/0x000000/" - hdr.Name = longName - - hdr.Size = 0 - var buf bytes.Buffer - writer := NewWriter(&buf) - if err := writer.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if err := writer.Close(); err != nil { - t.Fatal(err) - } - // Test that we can get a long name back out of the archive. - reader := NewReader(&buf) - hdr, err = reader.Next() - if err != nil { - t.Fatal(err) - } - if hdr.Name != longName { - t.Fatal("Couldn't recover long name") - } -} - -func TestValidTypeflagWithPAXHeader(t *testing.T) { - var buffer bytes.Buffer - tw := NewWriter(&buffer) - - fileName := strings.Repeat("ab", 100) - - hdr := &Header{ - Name: fileName, - Size: 4, - Typeflag: 0, - } - if err := tw.WriteHeader(hdr); err != nil { - t.Fatalf("Failed to write header: %s", err) - } - if _, err := tw.Write([]byte("fooo")); err != nil { - t.Fatalf("Failed to write the file's data: %s", err) - } - tw.Close() - - tr := NewReader(&buffer) - - for { - header, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - t.Fatalf("Failed to read header: %s", err) - } - if header.Typeflag != 0 { - t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag) - } - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/docker/libtrust/CONTRIBUTING.md deleted file mode 100644 index 05be0f8ab3..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/CONTRIBUTING.md +++ /dev/null @@ -1,13 +0,0 @@ -# Contributing to libtrust - -Want to hack on libtrust? Awesome! Here are instructions to get you -started. - -libtrust is a part of the [Docker](https://www.docker.com) project, and follows -the same rules and principles. If you're already familiar with the way -Docker does things, you'll feel right at home. - -Otherwise, go read -[Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md). - -Happy hacking! diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/LICENSE b/Godeps/_workspace/src/github.com/docker/libtrust/LICENSE deleted file mode 100644 index 27448585ad..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2014 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/libtrust/MAINTAINERS deleted file mode 100644 index 9768175feb..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/MAINTAINERS +++ /dev/null @@ -1,3 +0,0 @@ -Solomon Hykes -Josh Hawn (github: jlhawn) -Derek McGowan (github: dmcgowan) diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/README.md b/Godeps/_workspace/src/github.com/docker/libtrust/README.md deleted file mode 100644 index 8e7db38186..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# libtrust - -Libtrust is library for managing authentication and authorization using public key cryptography. - -Authentication is handled using the identity attached to the public key. -Libtrust provides multiple methods to prove possession of the private key associated with an identity. - - TLS x509 certificates - - Signature verification - - Key Challenge - -Authorization and access control is managed through a distributed trust graph. -Trust servers are used as the authorities of the trust graph and allow caching portions of the graph for faster access. - -## Copyright and license - -Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license. -Docs released under Creative commons. - diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/certificates.go b/Godeps/_workspace/src/github.com/docker/libtrust/certificates.go deleted file mode 100644 index 3dcca33cb1..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/certificates.go +++ /dev/null @@ -1,175 +0,0 @@ -package libtrust - -import ( - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "fmt" - "io/ioutil" - "math/big" - "net" - "time" -) - -type certTemplateInfo struct { - commonName string - domains []string - ipAddresses []net.IP - isCA bool - clientAuth bool - serverAuth bool -} - -func generateCertTemplate(info *certTemplateInfo) *x509.Certificate { - // Generate a certificate template which is valid from the past week to - // 10 years from now. The usage of the certificate depends on the - // specified fields in the given certTempInfo object. - var ( - keyUsage x509.KeyUsage - extKeyUsage []x509.ExtKeyUsage - ) - - if info.isCA { - keyUsage = x509.KeyUsageCertSign - } - - if info.clientAuth { - extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageClientAuth) - } - - if info.serverAuth { - extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageServerAuth) - } - - return &x509.Certificate{ - SerialNumber: big.NewInt(0), - Subject: pkix.Name{ - CommonName: info.commonName, - }, - NotBefore: time.Now().Add(-time.Hour * 24 * 7), - NotAfter: time.Now().Add(time.Hour * 24 * 365 * 10), - DNSNames: info.domains, - IPAddresses: info.ipAddresses, - IsCA: info.isCA, - KeyUsage: keyUsage, - ExtKeyUsage: extKeyUsage, - BasicConstraintsValid: info.isCA, - } -} - -func generateCert(pub PublicKey, priv PrivateKey, subInfo, issInfo *certTemplateInfo) (cert *x509.Certificate, err error) { - pubCertTemplate := generateCertTemplate(subInfo) - privCertTemplate := generateCertTemplate(issInfo) - - certDER, err := x509.CreateCertificate( - rand.Reader, pubCertTemplate, privCertTemplate, - pub.CryptoPublicKey(), priv.CryptoPrivateKey(), - ) - if err != nil { - return nil, fmt.Errorf("failed to create certificate: %s", err) - } - - cert, err = x509.ParseCertificate(certDER) - if err != nil { - return nil, fmt.Errorf("failed to parse certificate: %s", err) - } - - return -} - -// GenerateSelfSignedServerCert creates a self-signed certificate for the -// given key which is to be used for TLS servers with the given domains and -// IP addresses. -func GenerateSelfSignedServerCert(key PrivateKey, domains []string, ipAddresses []net.IP) (*x509.Certificate, error) { - info := &certTemplateInfo{ - commonName: key.KeyID(), - domains: domains, - ipAddresses: ipAddresses, - serverAuth: true, - } - - return generateCert(key.PublicKey(), key, info, info) -} - -// GenerateSelfSignedClientCert creates a self-signed certificate for the -// given key which is to be used for TLS clients. -func GenerateSelfSignedClientCert(key PrivateKey) (*x509.Certificate, error) { - info := &certTemplateInfo{ - commonName: key.KeyID(), - clientAuth: true, - } - - return generateCert(key.PublicKey(), key, info, info) -} - -// GenerateCACert creates a certificate which can be used as a trusted -// certificate authority. -func GenerateCACert(signer PrivateKey, trustedKey PublicKey) (*x509.Certificate, error) { - subjectInfo := &certTemplateInfo{ - commonName: trustedKey.KeyID(), - isCA: true, - } - issuerInfo := &certTemplateInfo{ - commonName: signer.KeyID(), - } - - return generateCert(trustedKey, signer, subjectInfo, issuerInfo) -} - -// GenerateCACertPool creates a certificate authority pool to be used for a -// TLS configuration. Any self-signed certificates issued by the specified -// trusted keys will be verified during a TLS handshake -func GenerateCACertPool(signer PrivateKey, trustedKeys []PublicKey) (*x509.CertPool, error) { - certPool := x509.NewCertPool() - - for _, trustedKey := range trustedKeys { - cert, err := GenerateCACert(signer, trustedKey) - if err != nil { - return nil, fmt.Errorf("failed to generate CA certificate: %s", err) - } - - certPool.AddCert(cert) - } - - return certPool, nil -} - -// LoadCertificateBundle loads certificates from the given file. The file should be pem encoded -// containing one or more certificates. The expected pem type is "CERTIFICATE". -func LoadCertificateBundle(filename string) ([]*x509.Certificate, error) { - b, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - certificates := []*x509.Certificate{} - var block *pem.Block - block, b = pem.Decode(b) - for ; block != nil; block, b = pem.Decode(b) { - if block.Type == "CERTIFICATE" { - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return nil, err - } - certificates = append(certificates, cert) - } else { - return nil, fmt.Errorf("invalid pem block type: %s", block.Type) - } - } - - return certificates, nil -} - -// LoadCertificatePool loads a CA pool from the given file. The file should be pem encoded -// containing one or more certificates. The expected pem type is "CERTIFICATE". -func LoadCertificatePool(filename string) (*x509.CertPool, error) { - certs, err := LoadCertificateBundle(filename) - if err != nil { - return nil, err - } - pool := x509.NewCertPool() - for _, cert := range certs { - pool.AddCert(cert) - } - return pool, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/certificates_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/certificates_test.go deleted file mode 100644 index c111f3531a..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/certificates_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package libtrust - -import ( - "encoding/pem" - "io/ioutil" - "net" - "os" - "path" - "testing" -) - -func TestGenerateCertificates(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - _, err = GenerateSelfSignedServerCert(key, []string{"localhost"}, []net.IP{net.ParseIP("127.0.0.1")}) - if err != nil { - t.Fatal(err) - } - - _, err = GenerateSelfSignedClientCert(key) - if err != nil { - t.Fatal(err) - } -} - -func TestGenerateCACertPool(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - caKey1, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - caKey2, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - _, err = GenerateCACertPool(key, []PublicKey{caKey1.PublicKey(), caKey2.PublicKey()}) - if err != nil { - t.Fatal(err) - } -} - -func TestLoadCertificates(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - caKey1, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - caKey2, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - cert1, err := GenerateCACert(caKey1, key) - if err != nil { - t.Fatal(err) - } - cert2, err := GenerateCACert(caKey2, key) - if err != nil { - t.Fatal(err) - } - - d, err := ioutil.TempDir("/tmp", "cert-test") - if err != nil { - t.Fatal(err) - } - caFile := path.Join(d, "ca.pem") - f, err := os.OpenFile(caFile, os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - t.Fatal(err) - } - - err = pem.Encode(f, &pem.Block{Type: "CERTIFICATE", Bytes: cert1.Raw}) - if err != nil { - t.Fatal(err) - } - err = pem.Encode(f, &pem.Block{Type: "CERTIFICATE", Bytes: cert2.Raw}) - if err != nil { - t.Fatal(err) - } - f.Close() - - certs, err := LoadCertificateBundle(caFile) - if err != nil { - t.Fatal(err) - } - if len(certs) != 2 { - t.Fatalf("Wrong number of certs received, expected: %d, received %d", 2, len(certs)) - } - - pool, err := LoadCertificatePool(caFile) - if err != nil { - t.Fatal(err) - } - - if len(pool.Subjects()) != 2 { - t.Fatalf("Invalid certificate pool") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/doc.go b/Godeps/_workspace/src/github.com/docker/libtrust/doc.go deleted file mode 100644 index ec5d2159c1..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -/* -Package libtrust provides an interface for managing authentication and -authorization using public key cryptography. Authentication is handled -using the identity attached to the public key and verified through TLS -x509 certificates, a key challenge, or signature. Authorization and -access control is managed through a trust graph distributed between -both remote trust servers and locally cached and managed data. -*/ -package libtrust diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/ec_key.go b/Godeps/_workspace/src/github.com/docker/libtrust/ec_key.go deleted file mode 100644 index 00bbe4b3ca..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/ec_key.go +++ /dev/null @@ -1,428 +0,0 @@ -package libtrust - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "io" - "math/big" -) - -/* - * EC DSA PUBLIC KEY - */ - -// ecPublicKey implements a libtrust.PublicKey using elliptic curve digital -// signature algorithms. -type ecPublicKey struct { - *ecdsa.PublicKey - curveName string - signatureAlgorithm *signatureAlgorithm - extended map[string]interface{} -} - -func fromECPublicKey(cryptoPublicKey *ecdsa.PublicKey) (*ecPublicKey, error) { - curve := cryptoPublicKey.Curve - - switch { - case curve == elliptic.P256(): - return &ecPublicKey{cryptoPublicKey, "P-256", es256, map[string]interface{}{}}, nil - case curve == elliptic.P384(): - return &ecPublicKey{cryptoPublicKey, "P-384", es384, map[string]interface{}{}}, nil - case curve == elliptic.P521(): - return &ecPublicKey{cryptoPublicKey, "P-521", es512, map[string]interface{}{}}, nil - default: - return nil, errors.New("unsupported elliptic curve") - } -} - -// KeyType returns the key type for elliptic curve keys, i.e., "EC". -func (k *ecPublicKey) KeyType() string { - return "EC" -} - -// CurveName returns the elliptic curve identifier. -// Possible values are "P-256", "P-384", and "P-521". -func (k *ecPublicKey) CurveName() string { - return k.curveName -} - -// KeyID returns a distinct identifier which is unique to this Public Key. -func (k *ecPublicKey) KeyID() string { - return keyIDFromCryptoKey(k) -} - -func (k *ecPublicKey) String() string { - return fmt.Sprintf("EC Public Key <%s>", k.KeyID()) -} - -// Verify verifyies the signature of the data in the io.Reader using this -// PublicKey. The alg parameter should identify the digital signature -// algorithm which was used to produce the signature and should be supported -// by this public key. Returns a nil error if the signature is valid. -func (k *ecPublicKey) Verify(data io.Reader, alg string, signature []byte) error { - // For EC keys there is only one supported signature algorithm depending - // on the curve parameters. - if k.signatureAlgorithm.HeaderParam() != alg { - return fmt.Errorf("unable to verify signature: EC Public Key with curve %q does not support signature algorithm %q", k.curveName, alg) - } - - // signature is the concatenation of (r, s), base64Url encoded. - sigLength := len(signature) - expectedOctetLength := 2 * ((k.Params().BitSize + 7) >> 3) - if sigLength != expectedOctetLength { - return fmt.Errorf("signature length is %d octets long, should be %d", sigLength, expectedOctetLength) - } - - rBytes, sBytes := signature[:sigLength/2], signature[sigLength/2:] - r := new(big.Int).SetBytes(rBytes) - s := new(big.Int).SetBytes(sBytes) - - hasher := k.signatureAlgorithm.HashID().New() - _, err := io.Copy(hasher, data) - if err != nil { - return fmt.Errorf("error reading data to sign: %s", err) - } - hash := hasher.Sum(nil) - - if !ecdsa.Verify(k.PublicKey, hash, r, s) { - return errors.New("invalid signature") - } - - return nil -} - -// CryptoPublicKey returns the internal object which can be used as a -// crypto.PublicKey for use with other standard library operations. The type -// is either *rsa.PublicKey or *ecdsa.PublicKey -func (k *ecPublicKey) CryptoPublicKey() crypto.PublicKey { - return k.PublicKey -} - -func (k *ecPublicKey) toMap() map[string]interface{} { - jwk := make(map[string]interface{}) - for k, v := range k.extended { - jwk[k] = v - } - jwk["kty"] = k.KeyType() - jwk["kid"] = k.KeyID() - jwk["crv"] = k.CurveName() - - xBytes := k.X.Bytes() - yBytes := k.Y.Bytes() - octetLength := (k.Params().BitSize + 7) >> 3 - // MUST include leading zeros in the output so that x, y are each - // *octetLength* bytes long. - xBuf := make([]byte, octetLength-len(xBytes), octetLength) - yBuf := make([]byte, octetLength-len(yBytes), octetLength) - xBuf = append(xBuf, xBytes...) - yBuf = append(yBuf, yBytes...) - - jwk["x"] = joseBase64UrlEncode(xBuf) - jwk["y"] = joseBase64UrlEncode(yBuf) - - return jwk -} - -// MarshalJSON serializes this Public Key using the JWK JSON serialization format for -// elliptic curve keys. -func (k *ecPublicKey) MarshalJSON() (data []byte, err error) { - return json.Marshal(k.toMap()) -} - -// PEMBlock serializes this Public Key to DER-encoded PKIX format. -func (k *ecPublicKey) PEMBlock() (*pem.Block, error) { - derBytes, err := x509.MarshalPKIXPublicKey(k.PublicKey) - if err != nil { - return nil, fmt.Errorf("unable to serialize EC PublicKey to DER-encoded PKIX format: %s", err) - } - k.extended["kid"] = k.KeyID() // For display purposes. - return createPemBlock("PUBLIC KEY", derBytes, k.extended) -} - -func (k *ecPublicKey) AddExtendedField(field string, value interface{}) { - k.extended[field] = value -} - -func (k *ecPublicKey) GetExtendedField(field string) interface{} { - v, ok := k.extended[field] - if !ok { - return nil - } - return v -} - -func ecPublicKeyFromMap(jwk map[string]interface{}) (*ecPublicKey, error) { - // JWK key type (kty) has already been determined to be "EC". - // Need to extract 'crv', 'x', 'y', and 'kid' and check for - // consistency. - - // Get the curve identifier value. - crv, err := stringFromMap(jwk, "crv") - if err != nil { - return nil, fmt.Errorf("JWK EC Public Key curve identifier: %s", err) - } - - var ( - curve elliptic.Curve - sigAlg *signatureAlgorithm - ) - - switch { - case crv == "P-256": - curve = elliptic.P256() - sigAlg = es256 - case crv == "P-384": - curve = elliptic.P384() - sigAlg = es384 - case crv == "P-521": - curve = elliptic.P521() - sigAlg = es512 - default: - return nil, fmt.Errorf("JWK EC Public Key curve identifier not supported: %q\n", crv) - } - - // Get the X and Y coordinates for the public key point. - xB64Url, err := stringFromMap(jwk, "x") - if err != nil { - return nil, fmt.Errorf("JWK EC Public Key x-coordinate: %s", err) - } - x, err := parseECCoordinate(xB64Url, curve) - if err != nil { - return nil, fmt.Errorf("JWK EC Public Key x-coordinate: %s", err) - } - - yB64Url, err := stringFromMap(jwk, "y") - if err != nil { - return nil, fmt.Errorf("JWK EC Public Key y-coordinate: %s", err) - } - y, err := parseECCoordinate(yB64Url, curve) - if err != nil { - return nil, fmt.Errorf("JWK EC Public Key y-coordinate: %s", err) - } - - key := &ecPublicKey{ - PublicKey: &ecdsa.PublicKey{Curve: curve, X: x, Y: y}, - curveName: crv, signatureAlgorithm: sigAlg, - } - - // Key ID is optional too, but if it exists, it should match the key. - _, ok := jwk["kid"] - if ok { - kid, err := stringFromMap(jwk, "kid") - if err != nil { - return nil, fmt.Errorf("JWK EC Public Key ID: %s", err) - } - if kid != key.KeyID() { - return nil, fmt.Errorf("JWK EC Public Key ID does not match: %s", kid) - } - } - - key.extended = jwk - - return key, nil -} - -/* - * EC DSA PRIVATE KEY - */ - -// ecPrivateKey implements a JWK Private Key using elliptic curve digital signature -// algorithms. -type ecPrivateKey struct { - ecPublicKey - *ecdsa.PrivateKey -} - -func fromECPrivateKey(cryptoPrivateKey *ecdsa.PrivateKey) (*ecPrivateKey, error) { - publicKey, err := fromECPublicKey(&cryptoPrivateKey.PublicKey) - if err != nil { - return nil, err - } - - return &ecPrivateKey{*publicKey, cryptoPrivateKey}, nil -} - -// PublicKey returns the Public Key data associated with this Private Key. -func (k *ecPrivateKey) PublicKey() PublicKey { - return &k.ecPublicKey -} - -func (k *ecPrivateKey) String() string { - return fmt.Sprintf("EC Private Key <%s>", k.KeyID()) -} - -// Sign signs the data read from the io.Reader using a signature algorithm supported -// by the elliptic curve private key. If the specified hashing algorithm is -// supported by this key, that hash function is used to generate the signature -// otherwise the the default hashing algorithm for this key is used. Returns -// the signature and the name of the JWK signature algorithm used, e.g., -// "ES256", "ES384", "ES512". -func (k *ecPrivateKey) Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error) { - // Generate a signature of the data using the internal alg. - // The given hashId is only a suggestion, and since EC keys only support - // on signature/hash algorithm given the curve name, we disregard it for - // the elliptic curve JWK signature implementation. - hasher := k.signatureAlgorithm.HashID().New() - _, err = io.Copy(hasher, data) - if err != nil { - return nil, "", fmt.Errorf("error reading data to sign: %s", err) - } - hash := hasher.Sum(nil) - - r, s, err := ecdsa.Sign(rand.Reader, k.PrivateKey, hash) - if err != nil { - return nil, "", fmt.Errorf("error producing signature: %s", err) - } - rBytes, sBytes := r.Bytes(), s.Bytes() - octetLength := (k.ecPublicKey.Params().BitSize + 7) >> 3 - // MUST include leading zeros in the output - rBuf := make([]byte, octetLength-len(rBytes), octetLength) - sBuf := make([]byte, octetLength-len(sBytes), octetLength) - - rBuf = append(rBuf, rBytes...) - sBuf = append(sBuf, sBytes...) - - signature = append(rBuf, sBuf...) - alg = k.signatureAlgorithm.HeaderParam() - - return -} - -// CryptoPrivateKey returns the internal object which can be used as a -// crypto.PublicKey for use with other standard library operations. The type -// is either *rsa.PublicKey or *ecdsa.PublicKey -func (k *ecPrivateKey) CryptoPrivateKey() crypto.PrivateKey { - return k.PrivateKey -} - -func (k *ecPrivateKey) toMap() map[string]interface{} { - jwk := k.ecPublicKey.toMap() - - dBytes := k.D.Bytes() - // The length of this octet string MUST be ceiling(log-base-2(n)/8) - // octets (where n is the order of the curve). This is because the private - // key d must be in the interval [1, n-1] so the bitlength of d should be - // no larger than the bitlength of n-1. The easiest way to find the octet - // length is to take bitlength(n-1), add 7 to force a carry, and shift this - // bit sequence right by 3, which is essentially dividing by 8 and adding - // 1 if there is any remainder. Thus, the private key value d should be - // output to (bitlength(n-1)+7)>>3 octets. - n := k.ecPublicKey.Params().N - octetLength := (new(big.Int).Sub(n, big.NewInt(1)).BitLen() + 7) >> 3 - // Create a buffer with the necessary zero-padding. - dBuf := make([]byte, octetLength-len(dBytes), octetLength) - dBuf = append(dBuf, dBytes...) - - jwk["d"] = joseBase64UrlEncode(dBuf) - - return jwk -} - -// MarshalJSON serializes this Private Key using the JWK JSON serialization format for -// elliptic curve keys. -func (k *ecPrivateKey) MarshalJSON() (data []byte, err error) { - return json.Marshal(k.toMap()) -} - -// PEMBlock serializes this Private Key to DER-encoded PKIX format. -func (k *ecPrivateKey) PEMBlock() (*pem.Block, error) { - derBytes, err := x509.MarshalECPrivateKey(k.PrivateKey) - if err != nil { - return nil, fmt.Errorf("unable to serialize EC PrivateKey to DER-encoded PKIX format: %s", err) - } - k.extended["keyID"] = k.KeyID() // For display purposes. - return createPemBlock("EC PRIVATE KEY", derBytes, k.extended) -} - -func ecPrivateKeyFromMap(jwk map[string]interface{}) (*ecPrivateKey, error) { - dB64Url, err := stringFromMap(jwk, "d") - if err != nil { - return nil, fmt.Errorf("JWK EC Private Key: %s", err) - } - - // JWK key type (kty) has already been determined to be "EC". - // Need to extract the public key information, then extract the private - // key value 'd'. - publicKey, err := ecPublicKeyFromMap(jwk) - if err != nil { - return nil, err - } - - d, err := parseECPrivateParam(dB64Url, publicKey.Curve) - if err != nil { - return nil, fmt.Errorf("JWK EC Private Key d-param: %s", err) - } - - key := &ecPrivateKey{ - ecPublicKey: *publicKey, - PrivateKey: &ecdsa.PrivateKey{ - PublicKey: *publicKey.PublicKey, - D: d, - }, - } - - return key, nil -} - -/* - * Key Generation Functions. - */ - -func generateECPrivateKey(curve elliptic.Curve) (k *ecPrivateKey, err error) { - k = new(ecPrivateKey) - k.PrivateKey, err = ecdsa.GenerateKey(curve, rand.Reader) - if err != nil { - return nil, err - } - - k.ecPublicKey.PublicKey = &k.PrivateKey.PublicKey - k.extended = make(map[string]interface{}) - - return -} - -// GenerateECP256PrivateKey generates a key pair using elliptic curve P-256. -func GenerateECP256PrivateKey() (PrivateKey, error) { - k, err := generateECPrivateKey(elliptic.P256()) - if err != nil { - return nil, fmt.Errorf("error generating EC P-256 key: %s", err) - } - - k.curveName = "P-256" - k.signatureAlgorithm = es256 - - return k, nil -} - -// GenerateECP384PrivateKey generates a key pair using elliptic curve P-384. -func GenerateECP384PrivateKey() (PrivateKey, error) { - k, err := generateECPrivateKey(elliptic.P384()) - if err != nil { - return nil, fmt.Errorf("error generating EC P-384 key: %s", err) - } - - k.curveName = "P-384" - k.signatureAlgorithm = es384 - - return k, nil -} - -// GenerateECP521PrivateKey generates aß key pair using elliptic curve P-521. -func GenerateECP521PrivateKey() (PrivateKey, error) { - k, err := generateECPrivateKey(elliptic.P521()) - if err != nil { - return nil, fmt.Errorf("error generating EC P-521 key: %s", err) - } - - k.curveName = "P-521" - k.signatureAlgorithm = es512 - - return k, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/ec_key_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/ec_key_test.go deleted file mode 100644 index 26ac381497..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/ec_key_test.go +++ /dev/null @@ -1,157 +0,0 @@ -package libtrust - -import ( - "bytes" - "encoding/json" - "testing" -) - -func generateECTestKeys(t *testing.T) []PrivateKey { - p256Key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - p384Key, err := GenerateECP384PrivateKey() - if err != nil { - t.Fatal(err) - } - - p521Key, err := GenerateECP521PrivateKey() - if err != nil { - t.Fatal(err) - } - - return []PrivateKey{p256Key, p384Key, p521Key} -} - -func TestECKeys(t *testing.T) { - ecKeys := generateECTestKeys(t) - - for _, ecKey := range ecKeys { - if ecKey.KeyType() != "EC" { - t.Fatalf("key type must be %q, instead got %q", "EC", ecKey.KeyType()) - } - } -} - -func TestECSignVerify(t *testing.T) { - ecKeys := generateECTestKeys(t) - - message := "Hello, World!" - data := bytes.NewReader([]byte(message)) - - sigAlgs := []*signatureAlgorithm{es256, es384, es512} - - for i, ecKey := range ecKeys { - sigAlg := sigAlgs[i] - - t.Logf("%s signature of %q with kid: %s\n", sigAlg.HeaderParam(), message, ecKey.KeyID()) - - data.Seek(0, 0) // Reset the byte reader - - // Sign - sig, alg, err := ecKey.Sign(data, sigAlg.HashID()) - if err != nil { - t.Fatal(err) - } - - data.Seek(0, 0) // Reset the byte reader - - // Verify - err = ecKey.Verify(data, alg, sig) - if err != nil { - t.Fatal(err) - } - } -} - -func TestMarshalUnmarshalECKeys(t *testing.T) { - ecKeys := generateECTestKeys(t) - data := bytes.NewReader([]byte("This is a test. I repeat: this is only a test.")) - sigAlgs := []*signatureAlgorithm{es256, es384, es512} - - for i, ecKey := range ecKeys { - sigAlg := sigAlgs[i] - privateJWKJSON, err := json.MarshalIndent(ecKey, "", " ") - if err != nil { - t.Fatal(err) - } - - publicJWKJSON, err := json.MarshalIndent(ecKey.PublicKey(), "", " ") - if err != nil { - t.Fatal(err) - } - - t.Logf("JWK Private Key: %s", string(privateJWKJSON)) - t.Logf("JWK Public Key: %s", string(publicJWKJSON)) - - privKey2, err := UnmarshalPrivateKeyJWK(privateJWKJSON) - if err != nil { - t.Fatal(err) - } - - pubKey2, err := UnmarshalPublicKeyJWK(publicJWKJSON) - if err != nil { - t.Fatal(err) - } - - // Ensure we can sign/verify a message with the unmarshalled keys. - data.Seek(0, 0) // Reset the byte reader - signature, alg, err := privKey2.Sign(data, sigAlg.HashID()) - if err != nil { - t.Fatal(err) - } - - data.Seek(0, 0) // Reset the byte reader - err = pubKey2.Verify(data, alg, signature) - if err != nil { - t.Fatal(err) - } - } -} - -func TestFromCryptoECKeys(t *testing.T) { - ecKeys := generateECTestKeys(t) - - for _, ecKey := range ecKeys { - cryptoPrivateKey := ecKey.CryptoPrivateKey() - cryptoPublicKey := ecKey.CryptoPublicKey() - - pubKey, err := FromCryptoPublicKey(cryptoPublicKey) - if err != nil { - t.Fatal(err) - } - - if pubKey.KeyID() != ecKey.KeyID() { - t.Fatal("public key key ID mismatch") - } - - privKey, err := FromCryptoPrivateKey(cryptoPrivateKey) - if err != nil { - t.Fatal(err) - } - - if privKey.KeyID() != ecKey.KeyID() { - t.Fatal("public key key ID mismatch") - } - } -} - -func TestExtendedFields(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - key.AddExtendedField("test", "foobar") - val := key.GetExtendedField("test") - - gotVal, ok := val.(string) - if !ok { - t.Fatalf("value is not a string") - } else if gotVal != val { - t.Fatalf("value %q is not equal to %q", gotVal, val) - } - -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/filter.go b/Godeps/_workspace/src/github.com/docker/libtrust/filter.go deleted file mode 100644 index 5b2b4fca6f..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/filter.go +++ /dev/null @@ -1,50 +0,0 @@ -package libtrust - -import ( - "path/filepath" -) - -// FilterByHosts filters the list of PublicKeys to only those which contain a -// 'hosts' pattern which matches the given host. If *includeEmpty* is true, -// then keys which do not specify any hosts are also returned. -func FilterByHosts(keys []PublicKey, host string, includeEmpty bool) ([]PublicKey, error) { - filtered := make([]PublicKey, 0, len(keys)) - - for _, pubKey := range keys { - var hosts []string - switch v := pubKey.GetExtendedField("hosts").(type) { - case []string: - hosts = v - case []interface{}: - for _, value := range v { - h, ok := value.(string) - if !ok { - continue - } - hosts = append(hosts, h) - } - } - - if len(hosts) == 0 { - if includeEmpty { - filtered = append(filtered, pubKey) - } - continue - } - - // Check if any hosts match pattern - for _, hostPattern := range hosts { - match, err := filepath.Match(hostPattern, host) - if err != nil { - return nil, err - } - - if match { - filtered = append(filtered, pubKey) - continue - } - } - } - - return filtered, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/filter_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/filter_test.go deleted file mode 100644 index 997e554c04..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/filter_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package libtrust - -import ( - "testing" -) - -func compareKeySlices(t *testing.T, sliceA, sliceB []PublicKey) { - if len(sliceA) != len(sliceB) { - t.Fatalf("slice size %d, expected %d", len(sliceA), len(sliceB)) - } - - for i, itemA := range sliceA { - itemB := sliceB[i] - if itemA != itemB { - t.Fatalf("slice index %d not equal: %#v != %#v", i, itemA, itemB) - } - } -} - -func TestFilter(t *testing.T) { - keys := make([]PublicKey, 0, 8) - - // Create 8 keys and add host entries. - for i := 0; i < cap(keys); i++ { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - // we use both []interface{} and []string here because jwt uses - // []interface{} format, while PEM uses []string - switch { - case i == 0: - // Don't add entries for this key, key 0. - break - case i%2 == 0: - // Should catch keys 2, 4, and 6. - key.AddExtendedField("hosts", []interface{}{"*.even.example.com"}) - case i == 7: - // Should catch only the last key, and make it match any hostname. - key.AddExtendedField("hosts", []string{"*"}) - default: - // should catch keys 1, 3, 5. - key.AddExtendedField("hosts", []string{"*.example.com"}) - } - - keys = append(keys, key) - } - - // Should match 2 keys, the empty one, and the one that matches all hosts. - matchedKeys, err := FilterByHosts(keys, "foo.bar.com", true) - if err != nil { - t.Fatal(err) - } - expectedMatch := []PublicKey{keys[0], keys[7]} - compareKeySlices(t, expectedMatch, matchedKeys) - - // Should match 1 key, the one that matches any host. - matchedKeys, err = FilterByHosts(keys, "foo.bar.com", false) - if err != nil { - t.Fatal(err) - } - expectedMatch = []PublicKey{keys[7]} - compareKeySlices(t, expectedMatch, matchedKeys) - - // Should match keys that end in "example.com", and the key that matches anything. - matchedKeys, err = FilterByHosts(keys, "foo.example.com", false) - if err != nil { - t.Fatal(err) - } - expectedMatch = []PublicKey{keys[1], keys[3], keys[5], keys[7]} - compareKeySlices(t, expectedMatch, matchedKeys) - - // Should match all of the keys except the empty key. - matchedKeys, err = FilterByHosts(keys, "foo.even.example.com", false) - if err != nil { - t.Fatal(err) - } - expectedMatch = keys[1:] - compareKeySlices(t, expectedMatch, matchedKeys) -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/hash.go b/Godeps/_workspace/src/github.com/docker/libtrust/hash.go deleted file mode 100644 index a2df787dd9..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/hash.go +++ /dev/null @@ -1,56 +0,0 @@ -package libtrust - -import ( - "crypto" - _ "crypto/sha256" // Registrer SHA224 and SHA256 - _ "crypto/sha512" // Registrer SHA384 and SHA512 - "fmt" -) - -type signatureAlgorithm struct { - algHeaderParam string - hashID crypto.Hash -} - -func (h *signatureAlgorithm) HeaderParam() string { - return h.algHeaderParam -} - -func (h *signatureAlgorithm) HashID() crypto.Hash { - return h.hashID -} - -var ( - rs256 = &signatureAlgorithm{"RS256", crypto.SHA256} - rs384 = &signatureAlgorithm{"RS384", crypto.SHA384} - rs512 = &signatureAlgorithm{"RS512", crypto.SHA512} - es256 = &signatureAlgorithm{"ES256", crypto.SHA256} - es384 = &signatureAlgorithm{"ES384", crypto.SHA384} - es512 = &signatureAlgorithm{"ES512", crypto.SHA512} -) - -func rsaSignatureAlgorithmByName(alg string) (*signatureAlgorithm, error) { - switch { - case alg == "RS256": - return rs256, nil - case alg == "RS384": - return rs384, nil - case alg == "RS512": - return rs512, nil - default: - return nil, fmt.Errorf("RSA Digital Signature Algorithm %q not supported", alg) - } -} - -func rsaPKCS1v15SignatureAlgorithmForHashID(hashID crypto.Hash) *signatureAlgorithm { - switch { - case hashID == crypto.SHA512: - return rs512 - case hashID == crypto.SHA384: - return rs384 - case hashID == crypto.SHA256: - fallthrough - default: - return rs256 - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/jsonsign.go b/Godeps/_workspace/src/github.com/docker/libtrust/jsonsign.go deleted file mode 100644 index c63530410d..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/jsonsign.go +++ /dev/null @@ -1,566 +0,0 @@ -package libtrust - -import ( - "bytes" - "crypto" - "crypto/x509" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "time" - "unicode" -) - -var ( - // ErrInvalidSignContent is used when the content to be signed is invalid. - ErrInvalidSignContent = errors.New("invalid sign content") - - // ErrInvalidJSONContent is used when invalid json is encountered. - ErrInvalidJSONContent = errors.New("invalid json content") - - // ErrMissingSignatureKey is used when the specified signature key - // does not exist in the JSON content. - ErrMissingSignatureKey = errors.New("missing signature key") -) - -type jsHeader struct { - JWK PublicKey `json:"jwk,omitempty"` - Algorithm string `json:"alg"` - Chain []string `json:"x5c,omitempty"` -} - -type jsSignature struct { - Header *jsHeader `json:"header"` - Signature string `json:"signature"` - Protected string `json:"protected,omitempty"` -} - -type signKey struct { - PrivateKey - Chain []*x509.Certificate -} - -// JSONSignature represents a signature of a json object. -type JSONSignature struct { - payload string - signatures []*jsSignature - indent string - formatLength int - formatTail []byte -} - -func newJSONSignature() *JSONSignature { - return &JSONSignature{ - signatures: make([]*jsSignature, 0, 1), - } -} - -// Payload returns the encoded payload of the signature. This -// payload should not be signed directly -func (js *JSONSignature) Payload() ([]byte, error) { - return joseBase64UrlDecode(js.payload) -} - -func (js *JSONSignature) protectedHeader() (string, error) { - protected := map[string]interface{}{ - "formatLength": js.formatLength, - "formatTail": joseBase64UrlEncode(js.formatTail), - "time": time.Now().UTC().Format(time.RFC3339), - } - protectedBytes, err := json.Marshal(protected) - if err != nil { - return "", err - } - - return joseBase64UrlEncode(protectedBytes), nil -} - -func (js *JSONSignature) signBytes(protectedHeader string) ([]byte, error) { - buf := make([]byte, len(js.payload)+len(protectedHeader)+1) - copy(buf, protectedHeader) - buf[len(protectedHeader)] = '.' - copy(buf[len(protectedHeader)+1:], js.payload) - return buf, nil -} - -// Sign adds a signature using the given private key. -func (js *JSONSignature) Sign(key PrivateKey) error { - protected, err := js.protectedHeader() - if err != nil { - return err - } - signBytes, err := js.signBytes(protected) - if err != nil { - return err - } - sigBytes, algorithm, err := key.Sign(bytes.NewReader(signBytes), crypto.SHA256) - if err != nil { - return err - } - - header := &jsHeader{ - JWK: key.PublicKey(), - Algorithm: algorithm, - } - sig := &jsSignature{ - Header: header, - Signature: joseBase64UrlEncode(sigBytes), - Protected: protected, - } - - js.signatures = append(js.signatures, sig) - - return nil -} - -// SignWithChain adds a signature using the given private key -// and setting the x509 chain. The public key of the first element -// in the chain must be the public key corresponding with the sign key. -func (js *JSONSignature) SignWithChain(key PrivateKey, chain []*x509.Certificate) error { - // Ensure key.Chain[0] is public key for key - //key.Chain.PublicKey - //key.PublicKey().CryptoPublicKey() - - // Verify chain - protected, err := js.protectedHeader() - if err != nil { - return err - } - signBytes, err := js.signBytes(protected) - if err != nil { - return err - } - sigBytes, algorithm, err := key.Sign(bytes.NewReader(signBytes), crypto.SHA256) - if err != nil { - return err - } - - header := &jsHeader{ - Chain: make([]string, len(chain)), - Algorithm: algorithm, - } - - for i, cert := range chain { - header.Chain[i] = base64.StdEncoding.EncodeToString(cert.Raw) - } - - sig := &jsSignature{ - Header: header, - Signature: joseBase64UrlEncode(sigBytes), - Protected: protected, - } - - js.signatures = append(js.signatures, sig) - - return nil -} - -// Verify verifies all the signatures and returns the list of -// public keys used to sign. Any x509 chains are not checked. -func (js *JSONSignature) Verify() ([]PublicKey, error) { - keys := make([]PublicKey, len(js.signatures)) - for i, signature := range js.signatures { - signBytes, err := js.signBytes(signature.Protected) - if err != nil { - return nil, err - } - var publicKey PublicKey - if len(signature.Header.Chain) > 0 { - certBytes, err := base64.StdEncoding.DecodeString(signature.Header.Chain[0]) - if err != nil { - return nil, err - } - cert, err := x509.ParseCertificate(certBytes) - if err != nil { - return nil, err - } - publicKey, err = FromCryptoPublicKey(cert.PublicKey) - if err != nil { - return nil, err - } - } else if signature.Header.JWK != nil { - publicKey = signature.Header.JWK - } else { - return nil, errors.New("missing public key") - } - - sigBytes, err := joseBase64UrlDecode(signature.Signature) - if err != nil { - return nil, err - } - - err = publicKey.Verify(bytes.NewReader(signBytes), signature.Header.Algorithm, sigBytes) - if err != nil { - return nil, err - } - - keys[i] = publicKey - } - return keys, nil -} - -// VerifyChains verifies all the signatures and the chains associated -// with each signature and returns the list of verified chains. -// Signatures without an x509 chain are not checked. -func (js *JSONSignature) VerifyChains(ca *x509.CertPool) ([][]*x509.Certificate, error) { - chains := make([][]*x509.Certificate, 0, len(js.signatures)) - for _, signature := range js.signatures { - signBytes, err := js.signBytes(signature.Protected) - if err != nil { - return nil, err - } - var publicKey PublicKey - if len(signature.Header.Chain) > 0 { - certBytes, err := base64.StdEncoding.DecodeString(signature.Header.Chain[0]) - if err != nil { - return nil, err - } - cert, err := x509.ParseCertificate(certBytes) - if err != nil { - return nil, err - } - publicKey, err = FromCryptoPublicKey(cert.PublicKey) - if err != nil { - return nil, err - } - intermediates := x509.NewCertPool() - if len(signature.Header.Chain) > 1 { - intermediateChain := signature.Header.Chain[1:] - for i := range intermediateChain { - certBytes, err := base64.StdEncoding.DecodeString(intermediateChain[i]) - if err != nil { - return nil, err - } - intermediate, err := x509.ParseCertificate(certBytes) - if err != nil { - return nil, err - } - intermediates.AddCert(intermediate) - } - } - - verifyOptions := x509.VerifyOptions{ - Intermediates: intermediates, - Roots: ca, - } - - verifiedChains, err := cert.Verify(verifyOptions) - if err != nil { - return nil, err - } - chains = append(chains, verifiedChains...) - - sigBytes, err := joseBase64UrlDecode(signature.Signature) - if err != nil { - return nil, err - } - - err = publicKey.Verify(bytes.NewReader(signBytes), signature.Header.Algorithm, sigBytes) - if err != nil { - return nil, err - } - } - - } - return chains, nil -} - -// JWS returns JSON serialized JWS according to -// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-7.2 -func (js *JSONSignature) JWS() ([]byte, error) { - if len(js.signatures) == 0 { - return nil, errors.New("missing signature") - } - jsonMap := map[string]interface{}{ - "payload": js.payload, - "signatures": js.signatures, - } - - return json.MarshalIndent(jsonMap, "", " ") -} - -func notSpace(r rune) bool { - return !unicode.IsSpace(r) -} - -func detectJSONIndent(jsonContent []byte) (indent string) { - if len(jsonContent) > 2 && jsonContent[0] == '{' && jsonContent[1] == '\n' { - quoteIndex := bytes.IndexRune(jsonContent[1:], '"') - if quoteIndex > 0 { - indent = string(jsonContent[2 : quoteIndex+1]) - } - } - return -} - -type jsParsedHeader struct { - JWK json.RawMessage `json:"jwk"` - Algorithm string `json:"alg"` - Chain []string `json:"x5c"` -} - -type jsParsedSignature struct { - Header *jsParsedHeader `json:"header"` - Signature string `json:"signature"` - Protected string `json:"protected"` -} - -// ParseJWS parses a JWS serialized JSON object into a Json Signature. -func ParseJWS(content []byte) (*JSONSignature, error) { - type jsParsed struct { - Payload string `json:"payload"` - Signatures []*jsParsedSignature `json:"signatures"` - } - parsed := &jsParsed{} - err := json.Unmarshal(content, parsed) - if err != nil { - return nil, err - } - if len(parsed.Signatures) == 0 { - return nil, errors.New("missing signatures") - } - payload, err := joseBase64UrlDecode(parsed.Payload) - if err != nil { - return nil, err - } - - js, err := NewJSONSignature(payload) - if err != nil { - return nil, err - } - js.signatures = make([]*jsSignature, len(parsed.Signatures)) - for i, signature := range parsed.Signatures { - header := &jsHeader{ - Algorithm: signature.Header.Algorithm, - } - if signature.Header.Chain != nil { - header.Chain = signature.Header.Chain - } - if signature.Header.JWK != nil { - publicKey, err := UnmarshalPublicKeyJWK([]byte(signature.Header.JWK)) - if err != nil { - return nil, err - } - header.JWK = publicKey - } - js.signatures[i] = &jsSignature{ - Header: header, - Signature: signature.Signature, - Protected: signature.Protected, - } - } - - return js, nil -} - -// NewJSONSignature returns a new unsigned JWS from a json byte array. -// JSONSignature will need to be signed before serializing or storing. -func NewJSONSignature(content []byte) (*JSONSignature, error) { - var dataMap map[string]interface{} - err := json.Unmarshal(content, &dataMap) - if err != nil { - return nil, err - } - - js := newJSONSignature() - js.indent = detectJSONIndent(content) - - js.payload = joseBase64UrlEncode(content) - - // Find trailing } and whitespace, put in protected header - closeIndex := bytes.LastIndexFunc(content, notSpace) - if content[closeIndex] != '}' { - return nil, ErrInvalidJSONContent - } - lastRuneIndex := bytes.LastIndexFunc(content[:closeIndex], notSpace) - if content[lastRuneIndex] == ',' { - return nil, ErrInvalidJSONContent - } - js.formatLength = lastRuneIndex + 1 - js.formatTail = content[js.formatLength:] - - return js, nil -} - -// NewJSONSignatureFromMap returns a new unsigned JSONSignature from a map or -// struct. JWS will need to be signed before serializing or storing. -func NewJSONSignatureFromMap(content interface{}) (*JSONSignature, error) { - switch content.(type) { - case map[string]interface{}: - case struct{}: - default: - return nil, errors.New("invalid data type") - } - - js := newJSONSignature() - js.indent = " " - - payload, err := json.MarshalIndent(content, "", js.indent) - if err != nil { - return nil, err - } - js.payload = joseBase64UrlEncode(payload) - - // Remove '\n}' from formatted section, put in protected header - js.formatLength = len(payload) - 2 - js.formatTail = payload[js.formatLength:] - - return js, nil -} - -func readIntFromMap(key string, m map[string]interface{}) (int, bool) { - value, ok := m[key] - if !ok { - return 0, false - } - switch v := value.(type) { - case int: - return v, true - case float64: - return int(v), true - default: - return 0, false - } -} - -func readStringFromMap(key string, m map[string]interface{}) (v string, ok bool) { - value, ok := m[key] - if !ok { - return "", false - } - v, ok = value.(string) - return -} - -// ParsePrettySignature parses a formatted signature into a -// JSON signature. If the signatures are missing the format information -// an error is thrown. The formatted signature must be created by -// the same method as format signature. -func ParsePrettySignature(content []byte, signatureKey string) (*JSONSignature, error) { - var contentMap map[string]json.RawMessage - err := json.Unmarshal(content, &contentMap) - if err != nil { - return nil, fmt.Errorf("error unmarshalling content: %s", err) - } - sigMessage, ok := contentMap[signatureKey] - if !ok { - return nil, ErrMissingSignatureKey - } - - var signatureBlocks []jsParsedSignature - err = json.Unmarshal([]byte(sigMessage), &signatureBlocks) - if err != nil { - return nil, fmt.Errorf("error unmarshalling signatures: %s", err) - } - - js := newJSONSignature() - js.signatures = make([]*jsSignature, len(signatureBlocks)) - - for i, signatureBlock := range signatureBlocks { - protectedBytes, err := joseBase64UrlDecode(signatureBlock.Protected) - if err != nil { - return nil, fmt.Errorf("base64 decode error: %s", err) - } - var protectedHeader map[string]interface{} - err = json.Unmarshal(protectedBytes, &protectedHeader) - if err != nil { - return nil, fmt.Errorf("error unmarshalling protected header: %s", err) - } - - formatLength, ok := readIntFromMap("formatLength", protectedHeader) - if !ok { - return nil, errors.New("missing formatted length") - } - encodedTail, ok := readStringFromMap("formatTail", protectedHeader) - if !ok { - return nil, errors.New("missing formatted tail") - } - formatTail, err := joseBase64UrlDecode(encodedTail) - if err != nil { - return nil, fmt.Errorf("base64 decode error on tail: %s", err) - } - if js.formatLength == 0 { - js.formatLength = formatLength - } else if js.formatLength != formatLength { - return nil, errors.New("conflicting format length") - } - if len(js.formatTail) == 0 { - js.formatTail = formatTail - } else if bytes.Compare(js.formatTail, formatTail) != 0 { - return nil, errors.New("conflicting format tail") - } - - header := &jsHeader{ - Algorithm: signatureBlock.Header.Algorithm, - Chain: signatureBlock.Header.Chain, - } - if signatureBlock.Header.JWK != nil { - publicKey, err := UnmarshalPublicKeyJWK([]byte(signatureBlock.Header.JWK)) - if err != nil { - return nil, fmt.Errorf("error unmarshalling public key: %s", err) - } - header.JWK = publicKey - } - js.signatures[i] = &jsSignature{ - Header: header, - Signature: signatureBlock.Signature, - Protected: signatureBlock.Protected, - } - } - if js.formatLength > len(content) { - return nil, errors.New("invalid format length") - } - formatted := make([]byte, js.formatLength+len(js.formatTail)) - copy(formatted, content[:js.formatLength]) - copy(formatted[js.formatLength:], js.formatTail) - js.indent = detectJSONIndent(formatted) - js.payload = joseBase64UrlEncode(formatted) - - return js, nil -} - -// PrettySignature formats a json signature into an easy to read -// single json serialized object. -func (js *JSONSignature) PrettySignature(signatureKey string) ([]byte, error) { - if len(js.signatures) == 0 { - return nil, errors.New("no signatures") - } - payload, err := joseBase64UrlDecode(js.payload) - if err != nil { - return nil, err - } - payload = payload[:js.formatLength] - - var marshalled []byte - var marshallErr error - if js.indent != "" { - marshalled, marshallErr = json.MarshalIndent(js.signatures, js.indent, js.indent) - } else { - marshalled, marshallErr = json.Marshal(js.signatures) - } - if marshallErr != nil { - return nil, marshallErr - } - - buf := bytes.NewBuffer(make([]byte, 0, len(payload)+len(marshalled)+34)) - buf.Write(payload) - buf.WriteByte(',') - if js.indent != "" { - buf.WriteByte('\n') - buf.WriteString(js.indent) - buf.WriteByte('"') - buf.WriteString(signatureKey) - buf.WriteString("\": ") - buf.Write(marshalled) - buf.WriteByte('\n') - } else { - buf.WriteByte('"') - buf.WriteString(signatureKey) - buf.WriteString("\":") - buf.Write(marshalled) - } - buf.WriteByte('}') - - return buf.Bytes(), nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/jsonsign_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/jsonsign_test.go deleted file mode 100644 index 59616b9f4e..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/jsonsign_test.go +++ /dev/null @@ -1,297 +0,0 @@ -package libtrust - -import ( - "bytes" - "crypto/x509" - "encoding/json" - "fmt" - "testing" - - "github.com/docker/libtrust/testutil" -) - -func createTestJSON(sigKey string, indent string) (map[string]interface{}, []byte) { - testMap := map[string]interface{}{ - "name": "dmcgowan/mycontainer", - "config": map[string]interface{}{ - "ports": []int{9101, 9102}, - "run": "/bin/echo \"Hello\"", - }, - "layers": []string{ - "2893c080-27f5-11e4-8c21-0800200c9a66", - "c54bc25b-fbb2-497b-a899-a8bc1b5b9d55", - "4d5d7e03-f908-49f3-a7f6-9ba28dfe0fb4", - "0b6da891-7f7f-4abf-9c97-7887549e696c", - "1d960389-ae4f-4011-85fd-18d0f96a67ad", - }, - } - formattedSection := `{"config":{"ports":[9101,9102],"run":"/bin/echo \"Hello\""},"layers":["2893c080-27f5-11e4-8c21-0800200c9a66","c54bc25b-fbb2-497b-a899-a8bc1b5b9d55","4d5d7e03-f908-49f3-a7f6-9ba28dfe0fb4","0b6da891-7f7f-4abf-9c97-7887549e696c","1d960389-ae4f-4011-85fd-18d0f96a67ad"],"name":"dmcgowan/mycontainer","%s":[{"header":{` - formattedSection = fmt.Sprintf(formattedSection, sigKey) - if indent != "" { - buf := bytes.NewBuffer(nil) - json.Indent(buf, []byte(formattedSection), "", indent) - return testMap, buf.Bytes() - } - return testMap, []byte(formattedSection) - -} - -func TestSignJSON(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating EC key: %s", err) - } - - testMap, _ := createTestJSON("buildSignatures", " ") - indented, err := json.MarshalIndent(testMap, "", " ") - if err != nil { - t.Fatalf("Marshall error: %s", err) - } - - js, err := NewJSONSignature(indented) - if err != nil { - t.Fatalf("Error creating JSON signature: %s", err) - } - err = js.Sign(key) - if err != nil { - t.Fatalf("Error signing content: %s", err) - } - - keys, err := js.Verify() - if err != nil { - t.Fatalf("Error verifying signature: %s", err) - } - if len(keys) != 1 { - t.Fatalf("Error wrong number of keys returned") - } - if keys[0].KeyID() != key.KeyID() { - t.Fatalf("Unexpected public key returned") - } - -} - -func TestSignMap(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating EC key: %s", err) - } - - testMap, _ := createTestJSON("buildSignatures", " ") - js, err := NewJSONSignatureFromMap(testMap) - if err != nil { - t.Fatalf("Error creating JSON signature: %s", err) - } - err = js.Sign(key) - if err != nil { - t.Fatalf("Error signing JSON signature: %s", err) - } - - keys, err := js.Verify() - if err != nil { - t.Fatalf("Error verifying signature: %s", err) - } - if len(keys) != 1 { - t.Fatalf("Error wrong number of keys returned") - } - if keys[0].KeyID() != key.KeyID() { - t.Fatalf("Unexpected public key returned") - } -} - -func TestFormattedJson(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating EC key: %s", err) - } - - testMap, firstSection := createTestJSON("buildSignatures", " ") - indented, err := json.MarshalIndent(testMap, "", " ") - if err != nil { - t.Fatalf("Marshall error: %s", err) - } - - js, err := NewJSONSignature(indented) - if err != nil { - t.Fatalf("Error creating JSON signature: %s", err) - } - err = js.Sign(key) - if err != nil { - t.Fatalf("Error signing content: %s", err) - } - - b, err := js.PrettySignature("buildSignatures") - if err != nil { - t.Fatalf("Error signing map: %s", err) - } - - if bytes.Compare(b[:len(firstSection)], firstSection) != 0 { - t.Fatalf("Wrong signed value\nExpected:\n%s\nActual:\n%s", firstSection, b[:len(firstSection)]) - } - - parsed, err := ParsePrettySignature(b, "buildSignatures") - if err != nil { - t.Fatalf("Error parsing formatted signature: %s", err) - } - - keys, err := parsed.Verify() - if err != nil { - t.Fatalf("Error verifying signature: %s", err) - } - if len(keys) != 1 { - t.Fatalf("Error wrong number of keys returned") - } - if keys[0].KeyID() != key.KeyID() { - t.Fatalf("Unexpected public key returned") - } - - var unmarshalled map[string]interface{} - err = json.Unmarshal(b, &unmarshalled) - if err != nil { - t.Fatalf("Could not unmarshall after parse: %s", err) - } - -} - -func TestFormattedFlatJson(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating EC key: %s", err) - } - - testMap, firstSection := createTestJSON("buildSignatures", "") - unindented, err := json.Marshal(testMap) - if err != nil { - t.Fatalf("Marshall error: %s", err) - } - - js, err := NewJSONSignature(unindented) - if err != nil { - t.Fatalf("Error creating JSON signature: %s", err) - } - err = js.Sign(key) - if err != nil { - t.Fatalf("Error signing JSON signature: %s", err) - } - - b, err := js.PrettySignature("buildSignatures") - if err != nil { - t.Fatalf("Error signing map: %s", err) - } - - if bytes.Compare(b[:len(firstSection)], firstSection) != 0 { - t.Fatalf("Wrong signed value\nExpected:\n%s\nActual:\n%s", firstSection, b[:len(firstSection)]) - } - - parsed, err := ParsePrettySignature(b, "buildSignatures") - if err != nil { - t.Fatalf("Error parsing formatted signature: %s", err) - } - - keys, err := parsed.Verify() - if err != nil { - t.Fatalf("Error verifying signature: %s", err) - } - if len(keys) != 1 { - t.Fatalf("Error wrong number of keys returned") - } - if keys[0].KeyID() != key.KeyID() { - t.Fatalf("Unexpected public key returned") - } -} - -func generateTrustChain(t *testing.T, key PrivateKey, ca *x509.Certificate) (PrivateKey, []*x509.Certificate) { - parent := ca - parentKey := key - chain := make([]*x509.Certificate, 6) - for i := 5; i > 0; i-- { - intermediatekey, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generate key: %s", err) - } - chain[i], err = testutil.GenerateIntermediate(intermediatekey.CryptoPublicKey(), parentKey.CryptoPrivateKey(), parent) - if err != nil { - t.Fatalf("Error generating intermdiate certificate: %s", err) - } - parent = chain[i] - parentKey = intermediatekey - } - trustKey, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generate key: %s", err) - } - chain[0], err = testutil.GenerateTrustCert(trustKey.CryptoPublicKey(), parentKey.CryptoPrivateKey(), parent) - if err != nil { - t.Fatalf("Error generate trust cert: %s", err) - } - - return trustKey, chain -} - -func TestChainVerify(t *testing.T) { - caKey, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating key: %s", err) - } - ca, err := testutil.GenerateTrustCA(caKey.CryptoPublicKey(), caKey.CryptoPrivateKey()) - if err != nil { - t.Fatalf("Error generating ca: %s", err) - } - trustKey, chain := generateTrustChain(t, caKey, ca) - - testMap, _ := createTestJSON("verifySignatures", " ") - js, err := NewJSONSignatureFromMap(testMap) - if err != nil { - t.Fatalf("Error creating JSONSignature from map: %s", err) - } - - err = js.SignWithChain(trustKey, chain) - if err != nil { - t.Fatalf("Error signing with chain: %s", err) - } - - pool := x509.NewCertPool() - pool.AddCert(ca) - chains, err := js.VerifyChains(pool) - if err != nil { - t.Fatalf("Error verifying content: %s", err) - } - if len(chains) != 1 { - t.Fatalf("Unexpected chains length: %d", len(chains)) - } - if len(chains[0]) != 7 { - t.Fatalf("Unexpected chain length: %d", len(chains[0])) - } -} - -func TestInvalidChain(t *testing.T) { - caKey, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating key: %s", err) - } - ca, err := testutil.GenerateTrustCA(caKey.CryptoPublicKey(), caKey.CryptoPrivateKey()) - if err != nil { - t.Fatalf("Error generating ca: %s", err) - } - trustKey, chain := generateTrustChain(t, caKey, ca) - - testMap, _ := createTestJSON("verifySignatures", " ") - js, err := NewJSONSignatureFromMap(testMap) - if err != nil { - t.Fatalf("Error creating JSONSignature from map: %s", err) - } - - err = js.SignWithChain(trustKey, chain[:5]) - if err != nil { - t.Fatalf("Error signing with chain: %s", err) - } - - pool := x509.NewCertPool() - pool.AddCert(ca) - chains, err := js.VerifyChains(pool) - if err == nil { - t.Fatalf("Expected error verifying with bad chain") - } - if len(chains) != 0 { - t.Fatalf("Unexpected chains returned from invalid verify") - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/key.go b/Godeps/_workspace/src/github.com/docker/libtrust/key.go deleted file mode 100644 index 73642db2a8..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/key.go +++ /dev/null @@ -1,253 +0,0 @@ -package libtrust - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/x509" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "io" -) - -// PublicKey is a generic interface for a Public Key. -type PublicKey interface { - // KeyType returns the key type for this key. For elliptic curve keys, - // this value should be "EC". For RSA keys, this value should be "RSA". - KeyType() string - // KeyID returns a distinct identifier which is unique to this Public Key. - // The format generated by this library is a base32 encoding of a 240 bit - // hash of the public key data divided into 12 groups like so: - // ABCD:EFGH:IJKL:MNOP:QRST:UVWX:YZ23:4567:ABCD:EFGH:IJKL:MNOP - KeyID() string - // Verify verifyies the signature of the data in the io.Reader using this - // Public Key. The alg parameter should identify the digital signature - // algorithm which was used to produce the signature and should be - // supported by this public key. Returns a nil error if the signature - // is valid. - Verify(data io.Reader, alg string, signature []byte) error - // CryptoPublicKey returns the internal object which can be used as a - // crypto.PublicKey for use with other standard library operations. The type - // is either *rsa.PublicKey or *ecdsa.PublicKey - CryptoPublicKey() crypto.PublicKey - // These public keys can be serialized to the standard JSON encoding for - // JSON Web Keys. See section 6 of the IETF draft RFC for JOSE JSON Web - // Algorithms. - MarshalJSON() ([]byte, error) - // These keys can also be serialized to the standard PEM encoding. - PEMBlock() (*pem.Block, error) - // The string representation of a key is its key type and ID. - String() string - AddExtendedField(string, interface{}) - GetExtendedField(string) interface{} -} - -// PrivateKey is a generic interface for a Private Key. -type PrivateKey interface { - // A PrivateKey contains all fields and methods of a PublicKey of the - // same type. The MarshalJSON method also outputs the private key as a - // JSON Web Key, and the PEMBlock method outputs the private key as a - // PEM block. - PublicKey - // PublicKey returns the PublicKey associated with this PrivateKey. - PublicKey() PublicKey - // Sign signs the data read from the io.Reader using a signature algorithm - // supported by the private key. If the specified hashing algorithm is - // supported by this key, that hash function is used to generate the - // signature otherwise the the default hashing algorithm for this key is - // used. Returns the signature and identifier of the algorithm used. - Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error) - // CryptoPrivateKey returns the internal object which can be used as a - // crypto.PublicKey for use with other standard library operations. The - // type is either *rsa.PublicKey or *ecdsa.PublicKey - CryptoPrivateKey() crypto.PrivateKey -} - -// FromCryptoPublicKey returns a libtrust PublicKey representation of the given -// *ecdsa.PublicKey or *rsa.PublicKey. Returns a non-nil error when the given -// key is of an unsupported type. -func FromCryptoPublicKey(cryptoPublicKey crypto.PublicKey) (PublicKey, error) { - switch cryptoPublicKey := cryptoPublicKey.(type) { - case *ecdsa.PublicKey: - return fromECPublicKey(cryptoPublicKey) - case *rsa.PublicKey: - return fromRSAPublicKey(cryptoPublicKey), nil - default: - return nil, fmt.Errorf("public key type %T is not supported", cryptoPublicKey) - } -} - -// FromCryptoPrivateKey returns a libtrust PrivateKey representation of the given -// *ecdsa.PrivateKey or *rsa.PrivateKey. Returns a non-nil error when the given -// key is of an unsupported type. -func FromCryptoPrivateKey(cryptoPrivateKey crypto.PrivateKey) (PrivateKey, error) { - switch cryptoPrivateKey := cryptoPrivateKey.(type) { - case *ecdsa.PrivateKey: - return fromECPrivateKey(cryptoPrivateKey) - case *rsa.PrivateKey: - return fromRSAPrivateKey(cryptoPrivateKey), nil - default: - return nil, fmt.Errorf("private key type %T is not supported", cryptoPrivateKey) - } -} - -// UnmarshalPublicKeyPEM parses the PEM encoded data and returns a libtrust -// PublicKey or an error if there is a problem with the encoding. -func UnmarshalPublicKeyPEM(data []byte) (PublicKey, error) { - pemBlock, _ := pem.Decode(data) - if pemBlock == nil { - return nil, errors.New("unable to find PEM encoded data") - } else if pemBlock.Type != "PUBLIC KEY" { - return nil, fmt.Errorf("unable to get PublicKey from PEM type: %s", pemBlock.Type) - } - - return pubKeyFromPEMBlock(pemBlock) -} - -// UnmarshalPublicKeyPEMBundle parses the PEM encoded data as a bundle of -// PEM blocks appended one after the other and returns a slice of PublicKey -// objects that it finds. -func UnmarshalPublicKeyPEMBundle(data []byte) ([]PublicKey, error) { - pubKeys := []PublicKey{} - - for { - var pemBlock *pem.Block - pemBlock, data = pem.Decode(data) - if pemBlock == nil { - break - } else if pemBlock.Type != "PUBLIC KEY" { - return nil, fmt.Errorf("unable to get PublicKey from PEM type: %s", pemBlock.Type) - } - - pubKey, err := pubKeyFromPEMBlock(pemBlock) - if err != nil { - return nil, err - } - - pubKeys = append(pubKeys, pubKey) - } - - return pubKeys, nil -} - -// UnmarshalPrivateKeyPEM parses the PEM encoded data and returns a libtrust -// PrivateKey or an error if there is a problem with the encoding. -func UnmarshalPrivateKeyPEM(data []byte) (PrivateKey, error) { - pemBlock, _ := pem.Decode(data) - if pemBlock == nil { - return nil, errors.New("unable to find PEM encoded data") - } - - var key PrivateKey - - switch { - case pemBlock.Type == "RSA PRIVATE KEY": - rsaPrivateKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes) - if err != nil { - return nil, fmt.Errorf("unable to decode RSA Private Key PEM data: %s", err) - } - key = fromRSAPrivateKey(rsaPrivateKey) - case pemBlock.Type == "EC PRIVATE KEY": - ecPrivateKey, err := x509.ParseECPrivateKey(pemBlock.Bytes) - if err != nil { - return nil, fmt.Errorf("unable to decode EC Private Key PEM data: %s", err) - } - key, err = fromECPrivateKey(ecPrivateKey) - if err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("unable to get PrivateKey from PEM type: %s", pemBlock.Type) - } - - addPEMHeadersToKey(pemBlock, key.PublicKey()) - - return key, nil -} - -// UnmarshalPublicKeyJWK unmarshals the given JSON Web Key into a generic -// Public Key to be used with libtrust. -func UnmarshalPublicKeyJWK(data []byte) (PublicKey, error) { - jwk := make(map[string]interface{}) - - err := json.Unmarshal(data, &jwk) - if err != nil { - return nil, fmt.Errorf( - "decoding JWK Public Key JSON data: %s\n", err, - ) - } - - // Get the Key Type value. - kty, err := stringFromMap(jwk, "kty") - if err != nil { - return nil, fmt.Errorf("JWK Public Key type: %s", err) - } - - switch { - case kty == "EC": - // Call out to unmarshal EC public key. - return ecPublicKeyFromMap(jwk) - case kty == "RSA": - // Call out to unmarshal RSA public key. - return rsaPublicKeyFromMap(jwk) - default: - return nil, fmt.Errorf( - "JWK Public Key type not supported: %q\n", kty, - ) - } -} - -// UnmarshalPublicKeyJWKSet parses the JSON encoded data as a JSON Web Key Set -// and returns a slice of Public Key objects. -func UnmarshalPublicKeyJWKSet(data []byte) ([]PublicKey, error) { - rawKeys, err := loadJSONKeySetRaw(data) - if err != nil { - return nil, err - } - - pubKeys := make([]PublicKey, 0, len(rawKeys)) - - for _, rawKey := range rawKeys { - pubKey, err := UnmarshalPublicKeyJWK(rawKey) - if err != nil { - return nil, err - } - pubKeys = append(pubKeys, pubKey) - } - - return pubKeys, nil -} - -// UnmarshalPrivateKeyJWK unmarshals the given JSON Web Key into a generic -// Private Key to be used with libtrust. -func UnmarshalPrivateKeyJWK(data []byte) (PrivateKey, error) { - jwk := make(map[string]interface{}) - - err := json.Unmarshal(data, &jwk) - if err != nil { - return nil, fmt.Errorf( - "decoding JWK Private Key JSON data: %s\n", err, - ) - } - - // Get the Key Type value. - kty, err := stringFromMap(jwk, "kty") - if err != nil { - return nil, fmt.Errorf("JWK Private Key type: %s", err) - } - - switch { - case kty == "EC": - // Call out to unmarshal EC private key. - return ecPrivateKeyFromMap(jwk) - case kty == "RSA": - // Call out to unmarshal RSA private key. - return rsaPrivateKeyFromMap(jwk) - default: - return nil, fmt.Errorf( - "JWK Private Key type not supported: %q\n", kty, - ) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/key_files.go b/Godeps/_workspace/src/github.com/docker/libtrust/key_files.go deleted file mode 100644 index c526de5455..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/key_files.go +++ /dev/null @@ -1,255 +0,0 @@ -package libtrust - -import ( - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "io/ioutil" - "os" - "strings" -) - -var ( - // ErrKeyFileDoesNotExist indicates that the private key file does not exist. - ErrKeyFileDoesNotExist = errors.New("key file does not exist") -) - -func readKeyFileBytes(filename string) ([]byte, error) { - data, err := ioutil.ReadFile(filename) - if err != nil { - if os.IsNotExist(err) { - err = ErrKeyFileDoesNotExist - } else { - err = fmt.Errorf("unable to read key file %s: %s", filename, err) - } - - return nil, err - } - - return data, nil -} - -/* - Loading and Saving of Public and Private Keys in either PEM or JWK format. -*/ - -// LoadKeyFile opens the given filename and attempts to read a Private Key -// encoded in either PEM or JWK format (if .json or .jwk file extension). -func LoadKeyFile(filename string) (PrivateKey, error) { - contents, err := readKeyFileBytes(filename) - if err != nil { - return nil, err - } - - var key PrivateKey - - if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") { - key, err = UnmarshalPrivateKeyJWK(contents) - if err != nil { - return nil, fmt.Errorf("unable to decode private key JWK: %s", err) - } - } else { - key, err = UnmarshalPrivateKeyPEM(contents) - if err != nil { - return nil, fmt.Errorf("unable to decode private key PEM: %s", err) - } - } - - return key, nil -} - -// LoadPublicKeyFile opens the given filename and attempts to read a Public Key -// encoded in either PEM or JWK format (if .json or .jwk file extension). -func LoadPublicKeyFile(filename string) (PublicKey, error) { - contents, err := readKeyFileBytes(filename) - if err != nil { - return nil, err - } - - var key PublicKey - - if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") { - key, err = UnmarshalPublicKeyJWK(contents) - if err != nil { - return nil, fmt.Errorf("unable to decode public key JWK: %s", err) - } - } else { - key, err = UnmarshalPublicKeyPEM(contents) - if err != nil { - return nil, fmt.Errorf("unable to decode public key PEM: %s", err) - } - } - - return key, nil -} - -// SaveKey saves the given key to a file using the provided filename. -// This process will overwrite any existing file at the provided location. -func SaveKey(filename string, key PrivateKey) error { - var encodedKey []byte - var err error - - if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") { - // Encode in JSON Web Key format. - encodedKey, err = json.MarshalIndent(key, "", " ") - if err != nil { - return fmt.Errorf("unable to encode private key JWK: %s", err) - } - } else { - // Encode in PEM format. - pemBlock, err := key.PEMBlock() - if err != nil { - return fmt.Errorf("unable to encode private key PEM: %s", err) - } - encodedKey = pem.EncodeToMemory(pemBlock) - } - - err = ioutil.WriteFile(filename, encodedKey, os.FileMode(0600)) - if err != nil { - return fmt.Errorf("unable to write private key file %s: %s", filename, err) - } - - return nil -} - -// SavePublicKey saves the given public key to the file. -func SavePublicKey(filename string, key PublicKey) error { - var encodedKey []byte - var err error - - if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") { - // Encode in JSON Web Key format. - encodedKey, err = json.MarshalIndent(key, "", " ") - if err != nil { - return fmt.Errorf("unable to encode public key JWK: %s", err) - } - } else { - // Encode in PEM format. - pemBlock, err := key.PEMBlock() - if err != nil { - return fmt.Errorf("unable to encode public key PEM: %s", err) - } - encodedKey = pem.EncodeToMemory(pemBlock) - } - - err = ioutil.WriteFile(filename, encodedKey, os.FileMode(0644)) - if err != nil { - return fmt.Errorf("unable to write public key file %s: %s", filename, err) - } - - return nil -} - -// Public Key Set files - -type jwkSet struct { - Keys []json.RawMessage `json:"keys"` -} - -// LoadKeySetFile loads a key set -func LoadKeySetFile(filename string) ([]PublicKey, error) { - if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") { - return loadJSONKeySetFile(filename) - } - - // Must be a PEM format file - return loadPEMKeySetFile(filename) -} - -func loadJSONKeySetRaw(data []byte) ([]json.RawMessage, error) { - if len(data) == 0 { - // This is okay, just return an empty slice. - return []json.RawMessage{}, nil - } - - keySet := jwkSet{} - - err := json.Unmarshal(data, &keySet) - if err != nil { - return nil, fmt.Errorf("unable to decode JSON Web Key Set: %s", err) - } - - return keySet.Keys, nil -} - -func loadJSONKeySetFile(filename string) ([]PublicKey, error) { - contents, err := readKeyFileBytes(filename) - if err != nil && err != ErrKeyFileDoesNotExist { - return nil, err - } - - return UnmarshalPublicKeyJWKSet(contents) -} - -func loadPEMKeySetFile(filename string) ([]PublicKey, error) { - data, err := readKeyFileBytes(filename) - if err != nil && err != ErrKeyFileDoesNotExist { - return nil, err - } - - return UnmarshalPublicKeyPEMBundle(data) -} - -// AddKeySetFile adds a key to a key set -func AddKeySetFile(filename string, key PublicKey) error { - if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") { - return addKeySetJSONFile(filename, key) - } - - // Must be a PEM format file - return addKeySetPEMFile(filename, key) -} - -func addKeySetJSONFile(filename string, key PublicKey) error { - encodedKey, err := json.Marshal(key) - if err != nil { - return fmt.Errorf("unable to encode trusted client key: %s", err) - } - - contents, err := readKeyFileBytes(filename) - if err != nil && err != ErrKeyFileDoesNotExist { - return err - } - - rawEntries, err := loadJSONKeySetRaw(contents) - if err != nil { - return err - } - - rawEntries = append(rawEntries, json.RawMessage(encodedKey)) - entriesWrapper := jwkSet{Keys: rawEntries} - - encodedEntries, err := json.MarshalIndent(entriesWrapper, "", " ") - if err != nil { - return fmt.Errorf("unable to encode trusted client keys: %s", err) - } - - err = ioutil.WriteFile(filename, encodedEntries, os.FileMode(0644)) - if err != nil { - return fmt.Errorf("unable to write trusted client keys file %s: %s", filename, err) - } - - return nil -} - -func addKeySetPEMFile(filename string, key PublicKey) error { - // Encode to PEM, open file for appending, write PEM. - file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, os.FileMode(0644)) - if err != nil { - return fmt.Errorf("unable to open trusted client keys file %s: %s", filename, err) - } - defer file.Close() - - pemBlock, err := key.PEMBlock() - if err != nil { - return fmt.Errorf("unable to encoded trusted key: %s", err) - } - - _, err = file.Write(pem.EncodeToMemory(pemBlock)) - if err != nil { - return fmt.Errorf("unable to write trusted keys file: %s", err) - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/key_files_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/key_files_test.go deleted file mode 100644 index 57e691f2ed..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/key_files_test.go +++ /dev/null @@ -1,220 +0,0 @@ -package libtrust - -import ( - "errors" - "io/ioutil" - "os" - "testing" -) - -func makeTempFile(t *testing.T, prefix string) (filename string) { - file, err := ioutil.TempFile("", prefix) - if err != nil { - t.Fatal(err) - } - - filename = file.Name() - file.Close() - - return -} - -func TestKeyFiles(t *testing.T) { - key, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - testKeyFiles(t, key) - - key, err = GenerateRSA2048PrivateKey() - if err != nil { - t.Fatal(err) - } - - testKeyFiles(t, key) -} - -func testKeyFiles(t *testing.T, key PrivateKey) { - var err error - - privateKeyFilename := makeTempFile(t, "private_key") - privateKeyFilenamePEM := privateKeyFilename + ".pem" - privateKeyFilenameJWK := privateKeyFilename + ".jwk" - - publicKeyFilename := makeTempFile(t, "public_key") - publicKeyFilenamePEM := publicKeyFilename + ".pem" - publicKeyFilenameJWK := publicKeyFilename + ".jwk" - - if err = SaveKey(privateKeyFilenamePEM, key); err != nil { - t.Fatal(err) - } - - if err = SaveKey(privateKeyFilenameJWK, key); err != nil { - t.Fatal(err) - } - - if err = SavePublicKey(publicKeyFilenamePEM, key.PublicKey()); err != nil { - t.Fatal(err) - } - - if err = SavePublicKey(publicKeyFilenameJWK, key.PublicKey()); err != nil { - t.Fatal(err) - } - - loadedPEMKey, err := LoadKeyFile(privateKeyFilenamePEM) - if err != nil { - t.Fatal(err) - } - - loadedJWKKey, err := LoadKeyFile(privateKeyFilenameJWK) - if err != nil { - t.Fatal(err) - } - - loadedPEMPublicKey, err := LoadPublicKeyFile(publicKeyFilenamePEM) - if err != nil { - t.Fatal(err) - } - - loadedJWKPublicKey, err := LoadPublicKeyFile(publicKeyFilenameJWK) - if err != nil { - t.Fatal(err) - } - - if key.KeyID() != loadedPEMKey.KeyID() { - t.Fatal(errors.New("key IDs do not match")) - } - - if key.KeyID() != loadedJWKKey.KeyID() { - t.Fatal(errors.New("key IDs do not match")) - } - - if key.KeyID() != loadedPEMPublicKey.KeyID() { - t.Fatal(errors.New("key IDs do not match")) - } - - if key.KeyID() != loadedJWKPublicKey.KeyID() { - t.Fatal(errors.New("key IDs do not match")) - } - - os.Remove(privateKeyFilename) - os.Remove(privateKeyFilenamePEM) - os.Remove(privateKeyFilenameJWK) - os.Remove(publicKeyFilename) - os.Remove(publicKeyFilenamePEM) - os.Remove(publicKeyFilenameJWK) -} - -func TestTrustedHostKeysFile(t *testing.T) { - trustedHostKeysFilename := makeTempFile(t, "trusted_host_keys") - trustedHostKeysFilenamePEM := trustedHostKeysFilename + ".pem" - trustedHostKeysFilenameJWK := trustedHostKeysFilename + ".json" - - testTrustedHostKeysFile(t, trustedHostKeysFilenamePEM) - testTrustedHostKeysFile(t, trustedHostKeysFilenameJWK) - - os.Remove(trustedHostKeysFilename) - os.Remove(trustedHostKeysFilenamePEM) - os.Remove(trustedHostKeysFilenameJWK) -} - -func testTrustedHostKeysFile(t *testing.T, trustedHostKeysFilename string) { - hostAddress1 := "docker.example.com:2376" - hostKey1, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - hostKey1.AddExtendedField("hosts", []string{hostAddress1}) - err = AddKeySetFile(trustedHostKeysFilename, hostKey1.PublicKey()) - if err != nil { - t.Fatal(err) - } - - trustedHostKeysMapping, err := LoadKeySetFile(trustedHostKeysFilename) - if err != nil { - t.Fatal(err) - } - - for addr, hostKey := range trustedHostKeysMapping { - t.Logf("Host Address: %d\n", addr) - t.Logf("Host Key: %s\n\n", hostKey) - } - - hostAddress2 := "192.168.59.103:2376" - hostKey2, err := GenerateRSA2048PrivateKey() - if err != nil { - t.Fatal(err) - } - - hostKey2.AddExtendedField("hosts", hostAddress2) - err = AddKeySetFile(trustedHostKeysFilename, hostKey2.PublicKey()) - if err != nil { - t.Fatal(err) - } - - trustedHostKeysMapping, err = LoadKeySetFile(trustedHostKeysFilename) - if err != nil { - t.Fatal(err) - } - - for addr, hostKey := range trustedHostKeysMapping { - t.Logf("Host Address: %d\n", addr) - t.Logf("Host Key: %s\n\n", hostKey) - } - -} - -func TestTrustedClientKeysFile(t *testing.T) { - trustedClientKeysFilename := makeTempFile(t, "trusted_client_keys") - trustedClientKeysFilenamePEM := trustedClientKeysFilename + ".pem" - trustedClientKeysFilenameJWK := trustedClientKeysFilename + ".json" - - testTrustedClientKeysFile(t, trustedClientKeysFilenamePEM) - testTrustedClientKeysFile(t, trustedClientKeysFilenameJWK) - - os.Remove(trustedClientKeysFilename) - os.Remove(trustedClientKeysFilenamePEM) - os.Remove(trustedClientKeysFilenameJWK) -} - -func testTrustedClientKeysFile(t *testing.T, trustedClientKeysFilename string) { - clientKey1, err := GenerateECP256PrivateKey() - if err != nil { - t.Fatal(err) - } - - err = AddKeySetFile(trustedClientKeysFilename, clientKey1.PublicKey()) - if err != nil { - t.Fatal(err) - } - - trustedClientKeys, err := LoadKeySetFile(trustedClientKeysFilename) - if err != nil { - t.Fatal(err) - } - - for _, clientKey := range trustedClientKeys { - t.Logf("Client Key: %s\n", clientKey) - } - - clientKey2, err := GenerateRSA2048PrivateKey() - if err != nil { - t.Fatal(err) - } - - err = AddKeySetFile(trustedClientKeysFilename, clientKey2.PublicKey()) - if err != nil { - t.Fatal(err) - } - - trustedClientKeys, err = LoadKeySetFile(trustedClientKeysFilename) - if err != nil { - t.Fatal(err) - } - - for _, clientKey := range trustedClientKeys { - t.Logf("Client Key: %s\n", clientKey) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/key_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/key_test.go deleted file mode 100644 index f6c59cc42b..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/key_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package libtrust - -import ( - "testing" -) - -type generateFunc func() (PrivateKey, error) - -func runGenerateBench(b *testing.B, f generateFunc, name string) { - for i := 0; i < b.N; i++ { - _, err := f() - if err != nil { - b.Fatalf("Error generating %s: %s", name, err) - } - } -} - -func runFingerprintBench(b *testing.B, f generateFunc, name string) { - b.StopTimer() - // Don't count this relatively slow generation call. - key, err := f() - if err != nil { - b.Fatalf("Error generating %s: %s", name, err) - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - if key.KeyID() == "" { - b.Fatalf("Error generating key ID for %s", name) - } - } -} - -func BenchmarkECP256Generate(b *testing.B) { - runGenerateBench(b, GenerateECP256PrivateKey, "P256") -} - -func BenchmarkECP384Generate(b *testing.B) { - runGenerateBench(b, GenerateECP384PrivateKey, "P384") -} - -func BenchmarkECP521Generate(b *testing.B) { - runGenerateBench(b, GenerateECP521PrivateKey, "P521") -} - -func BenchmarkRSA2048Generate(b *testing.B) { - runGenerateBench(b, GenerateRSA2048PrivateKey, "RSA2048") -} - -func BenchmarkRSA3072Generate(b *testing.B) { - runGenerateBench(b, GenerateRSA3072PrivateKey, "RSA3072") -} - -func BenchmarkRSA4096Generate(b *testing.B) { - runGenerateBench(b, GenerateRSA4096PrivateKey, "RSA4096") -} - -func BenchmarkECP256Fingerprint(b *testing.B) { - runFingerprintBench(b, GenerateECP256PrivateKey, "P256") -} - -func BenchmarkECP384Fingerprint(b *testing.B) { - runFingerprintBench(b, GenerateECP384PrivateKey, "P384") -} - -func BenchmarkECP521Fingerprint(b *testing.B) { - runFingerprintBench(b, GenerateECP521PrivateKey, "P521") -} - -func BenchmarkRSA2048Fingerprint(b *testing.B) { - runFingerprintBench(b, GenerateRSA2048PrivateKey, "RSA2048") -} - -func BenchmarkRSA3072Fingerprint(b *testing.B) { - runFingerprintBench(b, GenerateRSA3072PrivateKey, "RSA3072") -} - -func BenchmarkRSA4096Fingerprint(b *testing.B) { - runFingerprintBench(b, GenerateRSA4096PrivateKey, "RSA4096") -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/rsa_key.go b/Godeps/_workspace/src/github.com/docker/libtrust/rsa_key.go deleted file mode 100644 index dac4cacf20..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/rsa_key.go +++ /dev/null @@ -1,427 +0,0 @@ -package libtrust - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "io" - "math/big" -) - -/* - * RSA DSA PUBLIC KEY - */ - -// rsaPublicKey implements a JWK Public Key using RSA digital signature algorithms. -type rsaPublicKey struct { - *rsa.PublicKey - extended map[string]interface{} -} - -func fromRSAPublicKey(cryptoPublicKey *rsa.PublicKey) *rsaPublicKey { - return &rsaPublicKey{cryptoPublicKey, map[string]interface{}{}} -} - -// KeyType returns the JWK key type for RSA keys, i.e., "RSA". -func (k *rsaPublicKey) KeyType() string { - return "RSA" -} - -// KeyID returns a distinct identifier which is unique to this Public Key. -func (k *rsaPublicKey) KeyID() string { - return keyIDFromCryptoKey(k) -} - -func (k *rsaPublicKey) String() string { - return fmt.Sprintf("RSA Public Key <%s>", k.KeyID()) -} - -// Verify verifyies the signature of the data in the io.Reader using this Public Key. -// The alg parameter should be the name of the JWA digital signature algorithm -// which was used to produce the signature and should be supported by this -// public key. Returns a nil error if the signature is valid. -func (k *rsaPublicKey) Verify(data io.Reader, alg string, signature []byte) error { - // Verify the signature of the given date, return non-nil error if valid. - sigAlg, err := rsaSignatureAlgorithmByName(alg) - if err != nil { - return fmt.Errorf("unable to verify Signature: %s", err) - } - - hasher := sigAlg.HashID().New() - _, err = io.Copy(hasher, data) - if err != nil { - return fmt.Errorf("error reading data to sign: %s", err) - } - hash := hasher.Sum(nil) - - err = rsa.VerifyPKCS1v15(k.PublicKey, sigAlg.HashID(), hash, signature) - if err != nil { - return fmt.Errorf("invalid %s signature: %s", sigAlg.HeaderParam(), err) - } - - return nil -} - -// CryptoPublicKey returns the internal object which can be used as a -// crypto.PublicKey for use with other standard library operations. The type -// is either *rsa.PublicKey or *ecdsa.PublicKey -func (k *rsaPublicKey) CryptoPublicKey() crypto.PublicKey { - return k.PublicKey -} - -func (k *rsaPublicKey) toMap() map[string]interface{} { - jwk := make(map[string]interface{}) - for k, v := range k.extended { - jwk[k] = v - } - jwk["kty"] = k.KeyType() - jwk["kid"] = k.KeyID() - jwk["n"] = joseBase64UrlEncode(k.N.Bytes()) - jwk["e"] = joseBase64UrlEncode(serializeRSAPublicExponentParam(k.E)) - - return jwk -} - -// MarshalJSON serializes this Public Key using the JWK JSON serialization format for -// RSA keys. -func (k *rsaPublicKey) MarshalJSON() (data []byte, err error) { - return json.Marshal(k.toMap()) -} - -// PEMBlock serializes this Public Key to DER-encoded PKIX format. -func (k *rsaPublicKey) PEMBlock() (*pem.Block, error) { - derBytes, err := x509.MarshalPKIXPublicKey(k.PublicKey) - if err != nil { - return nil, fmt.Errorf("unable to serialize RSA PublicKey to DER-encoded PKIX format: %s", err) - } - k.extended["kid"] = k.KeyID() // For display purposes. - return createPemBlock("PUBLIC KEY", derBytes, k.extended) -} - -func (k *rsaPublicKey) AddExtendedField(field string, value interface{}) { - k.extended[field] = value -} - -func (k *rsaPublicKey) GetExtendedField(field string) interface{} { - v, ok := k.extended[field] - if !ok { - return nil - } - return v -} - -func rsaPublicKeyFromMap(jwk map[string]interface{}) (*rsaPublicKey, error) { - // JWK key type (kty) has already been determined to be "RSA". - // Need to extract 'n', 'e', and 'kid' and check for - // consistency. - - // Get the modulus parameter N. - nB64Url, err := stringFromMap(jwk, "n") - if err != nil { - return nil, fmt.Errorf("JWK RSA Public Key modulus: %s", err) - } - - n, err := parseRSAModulusParam(nB64Url) - if err != nil { - return nil, fmt.Errorf("JWK RSA Public Key modulus: %s", err) - } - - // Get the public exponent E. - eB64Url, err := stringFromMap(jwk, "e") - if err != nil { - return nil, fmt.Errorf("JWK RSA Public Key exponent: %s", err) - } - - e, err := parseRSAPublicExponentParam(eB64Url) - if err != nil { - return nil, fmt.Errorf("JWK RSA Public Key exponent: %s", err) - } - - key := &rsaPublicKey{ - PublicKey: &rsa.PublicKey{N: n, E: e}, - } - - // Key ID is optional, but if it exists, it should match the key. - _, ok := jwk["kid"] - if ok { - kid, err := stringFromMap(jwk, "kid") - if err != nil { - return nil, fmt.Errorf("JWK RSA Public Key ID: %s", err) - } - if kid != key.KeyID() { - return nil, fmt.Errorf("JWK RSA Public Key ID does not match: %s", kid) - } - } - - if _, ok := jwk["d"]; ok { - return nil, fmt.Errorf("JWK RSA Public Key cannot contain private exponent") - } - - key.extended = jwk - - return key, nil -} - -/* - * RSA DSA PRIVATE KEY - */ - -// rsaPrivateKey implements a JWK Private Key using RSA digital signature algorithms. -type rsaPrivateKey struct { - rsaPublicKey - *rsa.PrivateKey -} - -func fromRSAPrivateKey(cryptoPrivateKey *rsa.PrivateKey) *rsaPrivateKey { - return &rsaPrivateKey{ - *fromRSAPublicKey(&cryptoPrivateKey.PublicKey), - cryptoPrivateKey, - } -} - -// PublicKey returns the Public Key data associated with this Private Key. -func (k *rsaPrivateKey) PublicKey() PublicKey { - return &k.rsaPublicKey -} - -func (k *rsaPrivateKey) String() string { - return fmt.Sprintf("RSA Private Key <%s>", k.KeyID()) -} - -// Sign signs the data read from the io.Reader using a signature algorithm supported -// by the RSA private key. If the specified hashing algorithm is supported by -// this key, that hash function is used to generate the signature otherwise the -// the default hashing algorithm for this key is used. Returns the signature -// and the name of the JWK signature algorithm used, e.g., "RS256", "RS384", -// "RS512". -func (k *rsaPrivateKey) Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error) { - // Generate a signature of the data using the internal alg. - sigAlg := rsaPKCS1v15SignatureAlgorithmForHashID(hashID) - hasher := sigAlg.HashID().New() - - _, err = io.Copy(hasher, data) - if err != nil { - return nil, "", fmt.Errorf("error reading data to sign: %s", err) - } - hash := hasher.Sum(nil) - - signature, err = rsa.SignPKCS1v15(rand.Reader, k.PrivateKey, sigAlg.HashID(), hash) - if err != nil { - return nil, "", fmt.Errorf("error producing signature: %s", err) - } - - alg = sigAlg.HeaderParam() - - return -} - -// CryptoPrivateKey returns the internal object which can be used as a -// crypto.PublicKey for use with other standard library operations. The type -// is either *rsa.PublicKey or *ecdsa.PublicKey -func (k *rsaPrivateKey) CryptoPrivateKey() crypto.PrivateKey { - return k.PrivateKey -} - -func (k *rsaPrivateKey) toMap() map[string]interface{} { - k.Precompute() // Make sure the precomputed values are stored. - jwk := k.rsaPublicKey.toMap() - - jwk["d"] = joseBase64UrlEncode(k.D.Bytes()) - jwk["p"] = joseBase64UrlEncode(k.Primes[0].Bytes()) - jwk["q"] = joseBase64UrlEncode(k.Primes[1].Bytes()) - jwk["dp"] = joseBase64UrlEncode(k.Precomputed.Dp.Bytes()) - jwk["dq"] = joseBase64UrlEncode(k.Precomputed.Dq.Bytes()) - jwk["qi"] = joseBase64UrlEncode(k.Precomputed.Qinv.Bytes()) - - otherPrimes := k.Primes[2:] - - if len(otherPrimes) > 0 { - otherPrimesInfo := make([]interface{}, len(otherPrimes)) - for i, r := range otherPrimes { - otherPrimeInfo := make(map[string]string, 3) - otherPrimeInfo["r"] = joseBase64UrlEncode(r.Bytes()) - crtVal := k.Precomputed.CRTValues[i] - otherPrimeInfo["d"] = joseBase64UrlEncode(crtVal.Exp.Bytes()) - otherPrimeInfo["t"] = joseBase64UrlEncode(crtVal.Coeff.Bytes()) - otherPrimesInfo[i] = otherPrimeInfo - } - jwk["oth"] = otherPrimesInfo - } - - return jwk -} - -// MarshalJSON serializes this Private Key using the JWK JSON serialization format for -// RSA keys. -func (k *rsaPrivateKey) MarshalJSON() (data []byte, err error) { - return json.Marshal(k.toMap()) -} - -// PEMBlock serializes this Private Key to DER-encoded PKIX format. -func (k *rsaPrivateKey) PEMBlock() (*pem.Block, error) { - derBytes := x509.MarshalPKCS1PrivateKey(k.PrivateKey) - k.extended["keyID"] = k.KeyID() // For display purposes. - return createPemBlock("RSA PRIVATE KEY", derBytes, k.extended) -} - -func rsaPrivateKeyFromMap(jwk map[string]interface{}) (*rsaPrivateKey, error) { - // The JWA spec for RSA Private Keys (draft rfc section 5.3.2) states that - // only the private key exponent 'd' is REQUIRED, the others are just for - // signature/decryption optimizations and SHOULD be included when the JWK - // is produced. We MAY choose to accept a JWK which only includes 'd', but - // we're going to go ahead and not choose to accept it without the extra - // fields. Only the 'oth' field will be optional (for multi-prime keys). - privateExponent, err := parseRSAPrivateKeyParamFromMap(jwk, "d") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key exponent: %s", err) - } - firstPrimeFactor, err := parseRSAPrivateKeyParamFromMap(jwk, "p") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err) - } - secondPrimeFactor, err := parseRSAPrivateKeyParamFromMap(jwk, "q") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err) - } - firstFactorCRT, err := parseRSAPrivateKeyParamFromMap(jwk, "dp") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err) - } - secondFactorCRT, err := parseRSAPrivateKeyParamFromMap(jwk, "dq") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err) - } - crtCoeff, err := parseRSAPrivateKeyParamFromMap(jwk, "qi") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key CRT coefficient: %s", err) - } - - var oth interface{} - if _, ok := jwk["oth"]; ok { - oth = jwk["oth"] - delete(jwk, "oth") - } - - // JWK key type (kty) has already been determined to be "RSA". - // Need to extract the public key information, then extract the private - // key values. - publicKey, err := rsaPublicKeyFromMap(jwk) - if err != nil { - return nil, err - } - - privateKey := &rsa.PrivateKey{ - PublicKey: *publicKey.PublicKey, - D: privateExponent, - Primes: []*big.Int{firstPrimeFactor, secondPrimeFactor}, - Precomputed: rsa.PrecomputedValues{ - Dp: firstFactorCRT, - Dq: secondFactorCRT, - Qinv: crtCoeff, - }, - } - - if oth != nil { - // Should be an array of more JSON objects. - otherPrimesInfo, ok := oth.([]interface{}) - if !ok { - return nil, errors.New("JWK RSA Private Key: Invalid other primes info: must be an array") - } - numOtherPrimeFactors := len(otherPrimesInfo) - if numOtherPrimeFactors == 0 { - return nil, errors.New("JWK RSA Privake Key: Invalid other primes info: must be absent or non-empty") - } - otherPrimeFactors := make([]*big.Int, numOtherPrimeFactors) - productOfPrimes := new(big.Int).Mul(firstPrimeFactor, secondPrimeFactor) - crtValues := make([]rsa.CRTValue, numOtherPrimeFactors) - - for i, val := range otherPrimesInfo { - otherPrimeinfo, ok := val.(map[string]interface{}) - if !ok { - return nil, errors.New("JWK RSA Private Key: Invalid other prime info: must be a JSON object") - } - - otherPrimeFactor, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "r") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err) - } - otherFactorCRT, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "d") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err) - } - otherCrtCoeff, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "t") - if err != nil { - return nil, fmt.Errorf("JWK RSA Private Key CRT coefficient: %s", err) - } - - crtValue := crtValues[i] - crtValue.Exp = otherFactorCRT - crtValue.Coeff = otherCrtCoeff - crtValue.R = productOfPrimes - otherPrimeFactors[i] = otherPrimeFactor - productOfPrimes = new(big.Int).Mul(productOfPrimes, otherPrimeFactor) - } - - privateKey.Primes = append(privateKey.Primes, otherPrimeFactors...) - privateKey.Precomputed.CRTValues = crtValues - } - - key := &rsaPrivateKey{ - rsaPublicKey: *publicKey, - PrivateKey: privateKey, - } - - return key, nil -} - -/* - * Key Generation Functions. - */ - -func generateRSAPrivateKey(bits int) (k *rsaPrivateKey, err error) { - k = new(rsaPrivateKey) - k.PrivateKey, err = rsa.GenerateKey(rand.Reader, bits) - if err != nil { - return nil, err - } - - k.rsaPublicKey.PublicKey = &k.PrivateKey.PublicKey - k.extended = make(map[string]interface{}) - - return -} - -// GenerateRSA2048PrivateKey generates a key pair using 2048-bit RSA. -func GenerateRSA2048PrivateKey() (PrivateKey, error) { - k, err := generateRSAPrivateKey(2048) - if err != nil { - return nil, fmt.Errorf("error generating RSA 2048-bit key: %s", err) - } - - return k, nil -} - -// GenerateRSA3072PrivateKey generates a key pair using 3072-bit RSA. -func GenerateRSA3072PrivateKey() (PrivateKey, error) { - k, err := generateRSAPrivateKey(3072) - if err != nil { - return nil, fmt.Errorf("error generating RSA 3072-bit key: %s", err) - } - - return k, nil -} - -// GenerateRSA4096PrivateKey generates a key pair using 4096-bit RSA. -func GenerateRSA4096PrivateKey() (PrivateKey, error) { - k, err := generateRSAPrivateKey(4096) - if err != nil { - return nil, fmt.Errorf("error generating RSA 4096-bit key: %s", err) - } - - return k, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/rsa_key_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/rsa_key_test.go deleted file mode 100644 index 5ec7707aa6..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/rsa_key_test.go +++ /dev/null @@ -1,157 +0,0 @@ -package libtrust - -import ( - "bytes" - "encoding/json" - "log" - "testing" -) - -var rsaKeys []PrivateKey - -func init() { - var err error - rsaKeys, err = generateRSATestKeys() - if err != nil { - log.Fatal(err) - } -} - -func generateRSATestKeys() (keys []PrivateKey, err error) { - log.Println("Generating RSA 2048-bit Test Key") - rsa2048Key, err := GenerateRSA2048PrivateKey() - if err != nil { - return - } - - log.Println("Generating RSA 3072-bit Test Key") - rsa3072Key, err := GenerateRSA3072PrivateKey() - if err != nil { - return - } - - log.Println("Generating RSA 4096-bit Test Key") - rsa4096Key, err := GenerateRSA4096PrivateKey() - if err != nil { - return - } - - log.Println("Done generating RSA Test Keys!") - keys = []PrivateKey{rsa2048Key, rsa3072Key, rsa4096Key} - - return -} - -func TestRSAKeys(t *testing.T) { - for _, rsaKey := range rsaKeys { - if rsaKey.KeyType() != "RSA" { - t.Fatalf("key type must be %q, instead got %q", "RSA", rsaKey.KeyType()) - } - } -} - -func TestRSASignVerify(t *testing.T) { - message := "Hello, World!" - data := bytes.NewReader([]byte(message)) - - sigAlgs := []*signatureAlgorithm{rs256, rs384, rs512} - - for i, rsaKey := range rsaKeys { - sigAlg := sigAlgs[i] - - t.Logf("%s signature of %q with kid: %s\n", sigAlg.HeaderParam(), message, rsaKey.KeyID()) - - data.Seek(0, 0) // Reset the byte reader - - // Sign - sig, alg, err := rsaKey.Sign(data, sigAlg.HashID()) - if err != nil { - t.Fatal(err) - } - - data.Seek(0, 0) // Reset the byte reader - - // Verify - err = rsaKey.Verify(data, alg, sig) - if err != nil { - t.Fatal(err) - } - } -} - -func TestMarshalUnmarshalRSAKeys(t *testing.T) { - data := bytes.NewReader([]byte("This is a test. I repeat: this is only a test.")) - sigAlgs := []*signatureAlgorithm{rs256, rs384, rs512} - - for i, rsaKey := range rsaKeys { - sigAlg := sigAlgs[i] - privateJWKJSON, err := json.MarshalIndent(rsaKey, "", " ") - if err != nil { - t.Fatal(err) - } - - publicJWKJSON, err := json.MarshalIndent(rsaKey.PublicKey(), "", " ") - if err != nil { - t.Fatal(err) - } - - t.Logf("JWK Private Key: %s", string(privateJWKJSON)) - t.Logf("JWK Public Key: %s", string(publicJWKJSON)) - - privKey2, err := UnmarshalPrivateKeyJWK(privateJWKJSON) - if err != nil { - t.Fatal(err) - } - - pubKey2, err := UnmarshalPublicKeyJWK(publicJWKJSON) - if err != nil { - t.Fatal(err) - } - - // Ensure we can sign/verify a message with the unmarshalled keys. - data.Seek(0, 0) // Reset the byte reader - signature, alg, err := privKey2.Sign(data, sigAlg.HashID()) - if err != nil { - t.Fatal(err) - } - - data.Seek(0, 0) // Reset the byte reader - err = pubKey2.Verify(data, alg, signature) - if err != nil { - t.Fatal(err) - } - - // It's a good idea to validate the Private Key to make sure our - // (un)marshal process didn't corrupt the extra parameters. - k := privKey2.(*rsaPrivateKey) - err = k.PrivateKey.Validate() - if err != nil { - t.Fatal(err) - } - } -} - -func TestFromCryptoRSAKeys(t *testing.T) { - for _, rsaKey := range rsaKeys { - cryptoPrivateKey := rsaKey.CryptoPrivateKey() - cryptoPublicKey := rsaKey.CryptoPublicKey() - - pubKey, err := FromCryptoPublicKey(cryptoPublicKey) - if err != nil { - t.Fatal(err) - } - - if pubKey.KeyID() != rsaKey.KeyID() { - t.Fatal("public key key ID mismatch") - } - - privKey, err := FromCryptoPrivateKey(cryptoPrivateKey) - if err != nil { - t.Fatal(err) - } - - if privKey.KeyID() != rsaKey.KeyID() { - t.Fatal("public key key ID mismatch") - } - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/testutil/certificates.go b/Godeps/_workspace/src/github.com/docker/libtrust/testutil/certificates.go deleted file mode 100644 index 89debf6b64..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/testutil/certificates.go +++ /dev/null @@ -1,94 +0,0 @@ -package testutil - -import ( - "crypto" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "math/big" - "time" -) - -// GenerateTrustCA generates a new certificate authority for testing. -func GenerateTrustCA(pub crypto.PublicKey, priv crypto.PrivateKey) (*x509.Certificate, error) { - cert := &x509.Certificate{ - SerialNumber: big.NewInt(0), - Subject: pkix.Name{ - CommonName: "CA Root", - }, - NotBefore: time.Now().Add(-time.Second), - NotAfter: time.Now().Add(time.Hour), - IsCA: true, - KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, - BasicConstraintsValid: true, - } - - certDER, err := x509.CreateCertificate(rand.Reader, cert, cert, pub, priv) - if err != nil { - return nil, err - } - - cert, err = x509.ParseCertificate(certDER) - if err != nil { - return nil, err - } - - return cert, nil -} - -// GenerateIntermediate generates an intermediate certificate for testing using -// the parent certificate (likely a CA) and the provided keys. -func GenerateIntermediate(key crypto.PublicKey, parentKey crypto.PrivateKey, parent *x509.Certificate) (*x509.Certificate, error) { - cert := &x509.Certificate{ - SerialNumber: big.NewInt(0), - Subject: pkix.Name{ - CommonName: "Intermediate", - }, - NotBefore: time.Now().Add(-time.Second), - NotAfter: time.Now().Add(time.Hour), - IsCA: true, - KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, - BasicConstraintsValid: true, - } - - certDER, err := x509.CreateCertificate(rand.Reader, cert, parent, key, parentKey) - if err != nil { - return nil, err - } - - cert, err = x509.ParseCertificate(certDER) - if err != nil { - return nil, err - } - - return cert, nil -} - -// GenerateTrustCert generates a new trust certificate for testing. Unlike the -// intermediate certificates, this certificate should be used for signature -// only, not creating certificates. -func GenerateTrustCert(key crypto.PublicKey, parentKey crypto.PrivateKey, parent *x509.Certificate) (*x509.Certificate, error) { - cert := &x509.Certificate{ - SerialNumber: big.NewInt(0), - Subject: pkix.Name{ - CommonName: "Trust Cert", - }, - NotBefore: time.Now().Add(-time.Second), - NotAfter: time.Now().Add(time.Hour), - IsCA: true, - KeyUsage: x509.KeyUsageDigitalSignature, - BasicConstraintsValid: true, - } - - certDER, err := x509.CreateCertificate(rand.Reader, cert, parent, key, parentKey) - if err != nil { - return nil, err - } - - cert, err = x509.ParseCertificate(certDER) - if err != nil { - return nil, err - } - - return cert, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/README.md b/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/README.md deleted file mode 100644 index 24124db216..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/README.md +++ /dev/null @@ -1,50 +0,0 @@ -## Libtrust TLS Config Demo - -This program generates key pairs and trust files for a TLS client and server. - -To generate the keys, run: - -``` -$ go run genkeys.go -``` - -The generated files are: - -``` -$ ls -l client_data/ server_data/ -client_data/: -total 24 --rw------- 1 jlhawn staff 281 Aug 8 16:21 private_key.json --rw-r--r-- 1 jlhawn staff 225 Aug 8 16:21 public_key.json --rw-r--r-- 1 jlhawn staff 275 Aug 8 16:21 trusted_hosts.json - -server_data/: -total 24 --rw-r--r-- 1 jlhawn staff 348 Aug 8 16:21 trusted_clients.json --rw------- 1 jlhawn staff 281 Aug 8 16:21 private_key.json --rw-r--r-- 1 jlhawn staff 225 Aug 8 16:21 public_key.json -``` - -The private key and public key for the client and server are stored in `private_key.json` and `public_key.json`, respectively, and in their respective directories. They are represented as JSON Web Keys: JSON objects which represent either an ECDSA or RSA private key. The host keys trusted by the client are stored in `trusted_hosts.json` and contain a mapping of an internet address, `:`, to a JSON Web Key which is a JSON object representing either an ECDSA or RSA public key of the trusted server. The client keys trusted by the server are stored in `trusted_clients.json` and contain an array of JSON objects which contain a comment field which can be used describe the key and a JSON Web Key which is a JSON object representing either an ECDSA or RSA public key of the trusted client. - -To start the server, run: - -``` -$ go run server.go -``` - -This starts an HTTPS server which listens on `localhost:8888`. The server configures itself with a certificate which is valid for both `localhost` and `127.0.0.1` and uses the key from `server_data/private_key.json`. It accepts connections from clients which present a certificate for a key that it is configured to trust from the `trusted_clients.json` file and returns a simple 'hello' message. - -To make a request using the client, run: - -``` -$ go run client.go -``` - -This command creates an HTTPS client which makes a GET request to `https://localhost:8888`. The client configures itself with a certificate using the key from `client_data/private_key.json`. It only connects to a server which presents a certificate signed by the key specified for the `localhost:8888` address from `client_data/trusted_hosts.json` and made to be used for the `localhost` hostname. If the connection succeeds, it prints the response from the server. - -The file `gencert.go` can be used to generate PEM encoded version of the client key and certificate. If you save them to `key.pem` and `cert.pem` respectively, you can use them with `curl` to test out the server (if it is still running). - -``` -curl --cert cert.pem --key key.pem -k https://localhost:8888 -``` diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client.go b/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client.go deleted file mode 100644 index 0a699a0ee2..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client.go +++ /dev/null @@ -1,89 +0,0 @@ -package main - -import ( - "crypto/tls" - "fmt" - "io/ioutil" - "log" - "net" - "net/http" - - "github.com/docker/libtrust" -) - -var ( - serverAddress = "localhost:8888" - privateKeyFilename = "client_data/private_key.pem" - trustedHostsFilename = "client_data/trusted_hosts.pem" -) - -func main() { - // Load Client Key. - clientKey, err := libtrust.LoadKeyFile(privateKeyFilename) - if err != nil { - log.Fatal(err) - } - - // Generate Client Certificate. - selfSignedClientCert, err := libtrust.GenerateSelfSignedClientCert(clientKey) - if err != nil { - log.Fatal(err) - } - - // Load trusted host keys. - hostKeys, err := libtrust.LoadKeySetFile(trustedHostsFilename) - if err != nil { - log.Fatal(err) - } - - // Ensure the host we want to connect to is trusted! - host, _, err := net.SplitHostPort(serverAddress) - if err != nil { - log.Fatal(err) - } - serverKeys, err := libtrust.FilterByHosts(hostKeys, host, false) - if err != nil { - log.Fatalf("%q is not a known and trusted host", host) - } - - // Generate a CA pool with the trusted host's key. - caPool, err := libtrust.GenerateCACertPool(clientKey, serverKeys) - if err != nil { - log.Fatal(err) - } - - // Create HTTP Client. - client := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - Certificates: []tls.Certificate{ - tls.Certificate{ - Certificate: [][]byte{selfSignedClientCert.Raw}, - PrivateKey: clientKey.CryptoPrivateKey(), - Leaf: selfSignedClientCert, - }, - }, - RootCAs: caPool, - }, - }, - } - - var makeRequest = func(url string) { - resp, err := client.Get(url) - if err != nil { - log.Fatal(err) - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Fatal(err) - } - - log.Println(resp.Status) - log.Println(string(body)) - } - - // Make the request to the trusted server! - makeRequest(fmt.Sprintf("https://%s", serverAddress)) -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/gencert.go b/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/gencert.go deleted file mode 100644 index c65f3b6b44..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/gencert.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "encoding/pem" - "fmt" - "log" - "net" - - "github.com/docker/libtrust" -) - -var ( - serverAddress = "localhost:8888" - clientPrivateKeyFilename = "client_data/private_key.pem" - trustedHostsFilename = "client_data/trusted_hosts.pem" -) - -func main() { - key, err := libtrust.LoadKeyFile(clientPrivateKeyFilename) - if err != nil { - log.Fatal(err) - } - - keyPEMBlock, err := key.PEMBlock() - if err != nil { - log.Fatal(err) - } - - encodedPrivKey := pem.EncodeToMemory(keyPEMBlock) - fmt.Printf("Client Key:\n\n%s\n", string(encodedPrivKey)) - - cert, err := libtrust.GenerateSelfSignedClientCert(key) - if err != nil { - log.Fatal(err) - } - - encodedCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}) - fmt.Printf("Client Cert:\n\n%s\n", string(encodedCert)) - - trustedServerKeys, err := libtrust.LoadKeySetFile(trustedHostsFilename) - if err != nil { - log.Fatal(err) - } - - hostname, _, err := net.SplitHostPort(serverAddress) - if err != nil { - log.Fatal(err) - } - - trustedServerKeys, err = libtrust.FilterByHosts(trustedServerKeys, hostname, false) - if err != nil { - log.Fatal(err) - } - - caCert, err := libtrust.GenerateCACert(key, trustedServerKeys[0]) - if err != nil { - log.Fatal(err) - } - - encodedCert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caCert.Raw}) - fmt.Printf("CA Cert:\n\n%s\n", string(encodedCert)) -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/genkeys.go b/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/genkeys.go deleted file mode 100644 index 9dc8842ad9..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/genkeys.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "log" - - "github.com/docker/libtrust" -) - -func main() { - // Generate client key. - clientKey, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - log.Fatal(err) - } - - // Add a comment for the client key. - clientKey.AddExtendedField("comment", "TLS Demo Client") - - // Save the client key, public and private versions. - err = libtrust.SaveKey("client_data/private_key.pem", clientKey) - if err != nil { - log.Fatal(err) - } - - err = libtrust.SavePublicKey("client_data/public_key.pem", clientKey.PublicKey()) - if err != nil { - log.Fatal(err) - } - - // Generate server key. - serverKey, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - log.Fatal(err) - } - - // Set the list of addresses to use for the server. - serverKey.AddExtendedField("hosts", []string{"localhost", "docker.example.com"}) - - // Save the server key, public and private versions. - err = libtrust.SaveKey("server_data/private_key.pem", serverKey) - if err != nil { - log.Fatal(err) - } - - err = libtrust.SavePublicKey("server_data/public_key.pem", serverKey.PublicKey()) - if err != nil { - log.Fatal(err) - } - - // Generate Authorized Keys file for server. - err = libtrust.AddKeySetFile("server_data/trusted_clients.pem", clientKey.PublicKey()) - if err != nil { - log.Fatal(err) - } - - // Generate Known Host Keys file for client. - err = libtrust.AddKeySetFile("client_data/trusted_hosts.pem", serverKey.PublicKey()) - if err != nil { - log.Fatal(err) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server.go b/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server.go deleted file mode 100644 index d3cb2ea91f..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server.go +++ /dev/null @@ -1,80 +0,0 @@ -package main - -import ( - "crypto/tls" - "fmt" - "html" - "log" - "net" - "net/http" - - "github.com/docker/libtrust" -) - -var ( - serverAddress = "localhost:8888" - privateKeyFilename = "server_data/private_key.pem" - authorizedClientsFilename = "server_data/trusted_clients.pem" -) - -func requestHandler(w http.ResponseWriter, r *http.Request) { - clientCert := r.TLS.PeerCertificates[0] - keyID := clientCert.Subject.CommonName - log.Printf("Request from keyID: %s\n", keyID) - fmt.Fprintf(w, "Hello, client! I'm a server! And you are %T: %s.\n", clientCert.PublicKey, html.EscapeString(keyID)) -} - -func main() { - // Load server key. - serverKey, err := libtrust.LoadKeyFile(privateKeyFilename) - if err != nil { - log.Fatal(err) - } - - // Generate server certificate. - selfSignedServerCert, err := libtrust.GenerateSelfSignedServerCert( - serverKey, []string{"localhost"}, []net.IP{net.ParseIP("127.0.0.1")}, - ) - if err != nil { - log.Fatal(err) - } - - // Load authorized client keys. - authorizedClients, err := libtrust.LoadKeySetFile(authorizedClientsFilename) - if err != nil { - log.Fatal(err) - } - - // Create CA pool using trusted client keys. - caPool, err := libtrust.GenerateCACertPool(serverKey, authorizedClients) - if err != nil { - log.Fatal(err) - } - - // Create TLS config, requiring client certificates. - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{ - tls.Certificate{ - Certificate: [][]byte{selfSignedServerCert.Raw}, - PrivateKey: serverKey.CryptoPrivateKey(), - Leaf: selfSignedServerCert, - }, - }, - ClientAuth: tls.RequireAndVerifyClientCert, - ClientCAs: caPool, - } - - // Create HTTP server with simple request handler. - server := &http.Server{ - Addr: serverAddress, - Handler: http.HandlerFunc(requestHandler), - } - - // Listen and server HTTPS using the libtrust TLS config. - listener, err := net.Listen("tcp", server.Addr) - if err != nil { - log.Fatal(err) - } - tlsListener := tls.NewListener(listener, tlsConfig) - server.Serve(tlsListener) -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graph.go b/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graph.go deleted file mode 100644 index 72b0fc3664..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graph.go +++ /dev/null @@ -1,50 +0,0 @@ -package trustgraph - -import "github.com/docker/libtrust" - -// TrustGraph represents a graph of authorization mapping -// public keys to nodes and grants between nodes. -type TrustGraph interface { - // Verifies that the given public key is allowed to perform - // the given action on the given node according to the trust - // graph. - Verify(libtrust.PublicKey, string, uint16) (bool, error) - - // GetGrants returns an array of all grant chains which are used to - // allow the requested permission. - GetGrants(libtrust.PublicKey, string, uint16) ([][]*Grant, error) -} - -// Grant represents a transfer of permission from one part of the -// trust graph to another. This is the only way to delegate -// permission between two different sub trees in the graph. -type Grant struct { - // Subject is the namespace being granted - Subject string - - // Permissions is a bit map of permissions - Permission uint16 - - // Grantee represents the node being granted - // a permission scope. The grantee can be - // either a namespace item or a key id where namespace - // items will always start with a '/'. - Grantee string - - // statement represents the statement used to create - // this object. - statement *Statement -} - -// Permissions -// Read node 0x01 (can read node, no sub nodes) -// Write node 0x02 (can write to node object, cannot create subnodes) -// Read subtree 0x04 (delegates read to each sub node) -// Write subtree 0x08 (delegates write to each sub node, included create on the subject) -// -// Permission shortcuts -// ReadItem = 0x01 -// WriteItem = 0x03 -// ReadAccess = 0x07 -// WriteAccess = 0x0F -// Delegate = 0x0F diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/memory_graph.go b/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/memory_graph.go deleted file mode 100644 index 247bfa7aa6..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/memory_graph.go +++ /dev/null @@ -1,133 +0,0 @@ -package trustgraph - -import ( - "strings" - - "github.com/docker/libtrust" -) - -type grantNode struct { - grants []*Grant - children map[string]*grantNode -} - -type memoryGraph struct { - roots map[string]*grantNode -} - -func newGrantNode() *grantNode { - return &grantNode{ - grants: []*Grant{}, - children: map[string]*grantNode{}, - } -} - -// NewMemoryGraph returns a new in memory trust graph created from -// a static list of grants. This graph is immutable after creation -// and any alterations should create a new instance. -func NewMemoryGraph(grants []*Grant) TrustGraph { - roots := map[string]*grantNode{} - for _, grant := range grants { - parts := strings.Split(grant.Grantee, "/") - nodes := roots - var node *grantNode - var nodeOk bool - for _, part := range parts { - node, nodeOk = nodes[part] - if !nodeOk { - node = newGrantNode() - nodes[part] = node - } - if part != "" { - node.grants = append(node.grants, grant) - } - nodes = node.children - } - } - return &memoryGraph{roots} -} - -func (g *memoryGraph) getGrants(name string) []*Grant { - nameParts := strings.Split(name, "/") - nodes := g.roots - var node *grantNode - var nodeOk bool - for _, part := range nameParts { - node, nodeOk = nodes[part] - if !nodeOk { - return nil - } - nodes = node.children - } - return node.grants -} - -func isSubName(name, sub string) bool { - if strings.HasPrefix(name, sub) { - if len(name) == len(sub) || name[len(sub)] == '/' { - return true - } - } - return false -} - -type walkFunc func(*Grant, []*Grant) bool - -func foundWalkFunc(*Grant, []*Grant) bool { - return true -} - -func (g *memoryGraph) walkGrants(start, target string, permission uint16, f walkFunc, chain []*Grant, visited map[*Grant]bool, collect bool) bool { - if visited == nil { - visited = map[*Grant]bool{} - } - grants := g.getGrants(start) - subGrants := make([]*Grant, 0, len(grants)) - for _, grant := range grants { - if visited[grant] { - continue - } - visited[grant] = true - if grant.Permission&permission == permission { - if isSubName(target, grant.Subject) { - if f(grant, chain) { - return true - } - } else { - subGrants = append(subGrants, grant) - } - } - } - for _, grant := range subGrants { - var chainCopy []*Grant - if collect { - chainCopy = make([]*Grant, len(chain)+1) - copy(chainCopy, chain) - chainCopy[len(chainCopy)-1] = grant - } else { - chainCopy = nil - } - - if g.walkGrants(grant.Subject, target, permission, f, chainCopy, visited, collect) { - return true - } - } - return false -} - -func (g *memoryGraph) Verify(key libtrust.PublicKey, node string, permission uint16) (bool, error) { - return g.walkGrants(key.KeyID(), node, permission, foundWalkFunc, nil, nil, false), nil -} - -func (g *memoryGraph) GetGrants(key libtrust.PublicKey, node string, permission uint16) ([][]*Grant, error) { - grants := [][]*Grant{} - collect := func(grant *Grant, chain []*Grant) bool { - grantChain := make([]*Grant, len(chain)+1) - copy(grantChain, chain) - grantChain[len(grantChain)-1] = grant - grants = append(grants, grantChain) - return false - } - g.walkGrants(key.KeyID(), node, permission, collect, nil, nil, true) - return grants, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/memory_graph_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/memory_graph_test.go deleted file mode 100644 index 49fd0f3b54..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/memory_graph_test.go +++ /dev/null @@ -1,174 +0,0 @@ -package trustgraph - -import ( - "fmt" - "testing" - - "github.com/docker/libtrust" -) - -func createTestKeysAndGrants(count int) ([]*Grant, []libtrust.PrivateKey) { - grants := make([]*Grant, count) - keys := make([]libtrust.PrivateKey, count) - for i := 0; i < count; i++ { - pk, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - panic(err) - } - grant := &Grant{ - Subject: fmt.Sprintf("/user-%d", i+1), - Permission: 0x0f, - Grantee: pk.KeyID(), - } - keys[i] = pk - grants[i] = grant - } - return grants, keys -} - -func testVerified(t *testing.T, g TrustGraph, k libtrust.PublicKey, keyName, target string, permission uint16) { - if ok, err := g.Verify(k, target, permission); err != nil { - t.Fatalf("Unexpected error during verification: %s", err) - } else if !ok { - t.Errorf("key failed verification\n\tKey: %s(%s)\n\tNamespace: %s", keyName, k.KeyID(), target) - } -} - -func testNotVerified(t *testing.T, g TrustGraph, k libtrust.PublicKey, keyName, target string, permission uint16) { - if ok, err := g.Verify(k, target, permission); err != nil { - t.Fatalf("Unexpected error during verification: %s", err) - } else if ok { - t.Errorf("key should have failed verification\n\tKey: %s(%s)\n\tNamespace: %s", keyName, k.KeyID(), target) - } -} - -func TestVerify(t *testing.T) { - grants, keys := createTestKeysAndGrants(4) - extraGrants := make([]*Grant, 3) - extraGrants[0] = &Grant{ - Subject: "/user-3", - Permission: 0x0f, - Grantee: "/user-2", - } - extraGrants[1] = &Grant{ - Subject: "/user-3/sub-project", - Permission: 0x0f, - Grantee: "/user-4", - } - extraGrants[2] = &Grant{ - Subject: "/user-4", - Permission: 0x07, - Grantee: "/user-1", - } - grants = append(grants, extraGrants...) - - g := NewMemoryGraph(grants) - - testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f) - testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1/some-project/sub-value", 0x0f) - testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-4", 0x07) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2/", 0x0f) - testVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-3/sub-value", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3/sub-value", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3/", 0x0f) - testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3/sub-project", 0x0f) - testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3/sub-project/app", 0x0f) - testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-4", 0x0f) - - testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-2", 0x0f) - testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-3/sub-value", 0x0f) - testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-4", 0x0f) - testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-1/", 0x0f) - testNotVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-2", 0x0f) - testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-4", 0x0f) - testNotVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3", 0x0f) -} - -func TestCircularWalk(t *testing.T) { - grants, keys := createTestKeysAndGrants(3) - user1Grant := &Grant{ - Subject: "/user-2", - Permission: 0x0f, - Grantee: "/user-1", - } - user2Grant := &Grant{ - Subject: "/user-1", - Permission: 0x0f, - Grantee: "/user-2", - } - grants = append(grants, user1Grant, user2Grant) - - g := NewMemoryGraph(grants) - - testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f) - testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-2", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-1", 0x0f) - testVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-3", 0x0f) - - testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-3", 0x0f) - testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3", 0x0f) -} - -func assertGrantSame(t *testing.T, actual, expected *Grant) { - if actual != expected { - t.Fatalf("Unexpected grant retrieved\n\tExpected: %v\n\tActual: %v", expected, actual) - } -} - -func TestGetGrants(t *testing.T) { - grants, keys := createTestKeysAndGrants(5) - extraGrants := make([]*Grant, 4) - extraGrants[0] = &Grant{ - Subject: "/user-3/friend-project", - Permission: 0x0f, - Grantee: "/user-2/friends", - } - extraGrants[1] = &Grant{ - Subject: "/user-3/sub-project", - Permission: 0x0f, - Grantee: "/user-4", - } - extraGrants[2] = &Grant{ - Subject: "/user-2/friends", - Permission: 0x0f, - Grantee: "/user-5/fun-project", - } - extraGrants[3] = &Grant{ - Subject: "/user-5/fun-project", - Permission: 0x0f, - Grantee: "/user-1", - } - grants = append(grants, extraGrants...) - - g := NewMemoryGraph(grants) - - grantChains, err := g.GetGrants(keys[3], "/user-3/sub-project/specific-app", 0x0f) - if err != nil { - t.Fatalf("Error getting grants: %s", err) - } - if len(grantChains) != 1 { - t.Fatalf("Expected number of grant chains returned, expected %d, received %d", 1, len(grantChains)) - } - if len(grantChains[0]) != 2 { - t.Fatalf("Unexpected number of grants retrieved\n\tExpected: %d\n\tActual: %d", 2, len(grantChains[0])) - } - assertGrantSame(t, grantChains[0][0], grants[3]) - assertGrantSame(t, grantChains[0][1], extraGrants[1]) - - grantChains, err = g.GetGrants(keys[0], "/user-3/friend-project/fun-app", 0x0f) - if err != nil { - t.Fatalf("Error getting grants: %s", err) - } - if len(grantChains) != 1 { - t.Fatalf("Expected number of grant chains returned, expected %d, received %d", 1, len(grantChains)) - } - if len(grantChains[0]) != 4 { - t.Fatalf("Unexpected number of grants retrieved\n\tExpected: %d\n\tActual: %d", 2, len(grantChains[0])) - } - assertGrantSame(t, grantChains[0][0], grants[0]) - assertGrantSame(t, grantChains[0][1], extraGrants[3]) - assertGrantSame(t, grantChains[0][2], extraGrants[2]) - assertGrantSame(t, grantChains[0][3], extraGrants[0]) -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/statement.go b/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/statement.go deleted file mode 100644 index 7a74b553cd..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/statement.go +++ /dev/null @@ -1,227 +0,0 @@ -package trustgraph - -import ( - "crypto/x509" - "encoding/json" - "io" - "io/ioutil" - "sort" - "strings" - "time" - - "github.com/docker/libtrust" -) - -type jsonGrant struct { - Subject string `json:"subject"` - Permission uint16 `json:"permission"` - Grantee string `json:"grantee"` -} - -type jsonRevocation struct { - Subject string `json:"subject"` - Revocation uint16 `json:"revocation"` - Grantee string `json:"grantee"` -} - -type jsonStatement struct { - Revocations []*jsonRevocation `json:"revocations"` - Grants []*jsonGrant `json:"grants"` - Expiration time.Time `json:"expiration"` - IssuedAt time.Time `json:"issuedAt"` -} - -func (g *jsonGrant) Grant(statement *Statement) *Grant { - return &Grant{ - Subject: g.Subject, - Permission: g.Permission, - Grantee: g.Grantee, - statement: statement, - } -} - -// Statement represents a set of grants made from a verifiable -// authority. A statement has an expiration associated with it -// set by the authority. -type Statement struct { - jsonStatement - - signature *libtrust.JSONSignature -} - -// IsExpired returns whether the statement has expired -func (s *Statement) IsExpired() bool { - return s.Expiration.Before(time.Now().Add(-10 * time.Second)) -} - -// Bytes returns an indented json representation of the statement -// in a byte array. This value can be written to a file or stream -// without alteration. -func (s *Statement) Bytes() ([]byte, error) { - return s.signature.PrettySignature("signatures") -} - -// LoadStatement loads and verifies a statement from an input stream. -func LoadStatement(r io.Reader, authority *x509.CertPool) (*Statement, error) { - b, err := ioutil.ReadAll(r) - if err != nil { - return nil, err - } - js, err := libtrust.ParsePrettySignature(b, "signatures") - if err != nil { - return nil, err - } - payload, err := js.Payload() - if err != nil { - return nil, err - } - var statement Statement - err = json.Unmarshal(payload, &statement.jsonStatement) - if err != nil { - return nil, err - } - - if authority == nil { - _, err = js.Verify() - if err != nil { - return nil, err - } - } else { - _, err = js.VerifyChains(authority) - if err != nil { - return nil, err - } - } - statement.signature = js - - return &statement, nil -} - -// CreateStatements creates and signs a statement from a stream of grants -// and revocations in a JSON array. -func CreateStatement(grants, revocations io.Reader, expiration time.Duration, key libtrust.PrivateKey, chain []*x509.Certificate) (*Statement, error) { - var statement Statement - err := json.NewDecoder(grants).Decode(&statement.jsonStatement.Grants) - if err != nil { - return nil, err - } - err = json.NewDecoder(revocations).Decode(&statement.jsonStatement.Revocations) - if err != nil { - return nil, err - } - statement.jsonStatement.Expiration = time.Now().UTC().Add(expiration) - statement.jsonStatement.IssuedAt = time.Now().UTC() - - b, err := json.MarshalIndent(&statement.jsonStatement, "", " ") - if err != nil { - return nil, err - } - - statement.signature, err = libtrust.NewJSONSignature(b) - if err != nil { - return nil, err - } - err = statement.signature.SignWithChain(key, chain) - if err != nil { - return nil, err - } - - return &statement, nil -} - -type statementList []*Statement - -func (s statementList) Len() int { - return len(s) -} - -func (s statementList) Less(i, j int) bool { - return s[i].IssuedAt.Before(s[j].IssuedAt) -} - -func (s statementList) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// CollapseStatements returns a single list of the valid statements as well as the -// time when the next grant will expire. -func CollapseStatements(statements []*Statement, useExpired bool) ([]*Grant, time.Time, error) { - sorted := make(statementList, 0, len(statements)) - for _, statement := range statements { - if useExpired || !statement.IsExpired() { - sorted = append(sorted, statement) - } - } - sort.Sort(sorted) - - var minExpired time.Time - var grantCount int - roots := map[string]*grantNode{} - for i, statement := range sorted { - if statement.Expiration.Before(minExpired) || i == 0 { - minExpired = statement.Expiration - } - for _, grant := range statement.Grants { - parts := strings.Split(grant.Grantee, "/") - nodes := roots - g := grant.Grant(statement) - grantCount = grantCount + 1 - - for _, part := range parts { - node, nodeOk := nodes[part] - if !nodeOk { - node = newGrantNode() - nodes[part] = node - } - node.grants = append(node.grants, g) - nodes = node.children - } - } - - for _, revocation := range statement.Revocations { - parts := strings.Split(revocation.Grantee, "/") - nodes := roots - - var node *grantNode - var nodeOk bool - for _, part := range parts { - node, nodeOk = nodes[part] - if !nodeOk { - break - } - nodes = node.children - } - if node != nil { - for _, grant := range node.grants { - if isSubName(grant.Subject, revocation.Subject) { - grant.Permission = grant.Permission &^ revocation.Revocation - } - } - } - } - } - - retGrants := make([]*Grant, 0, grantCount) - for _, rootNodes := range roots { - retGrants = append(retGrants, rootNodes.grants...) - } - - return retGrants, minExpired, nil -} - -// FilterStatements filters the statements to statements including the given grants. -func FilterStatements(grants []*Grant) ([]*Statement, error) { - statements := map[*Statement]bool{} - for _, grant := range grants { - if grant.statement != nil { - statements[grant.statement] = true - } - } - retStatements := make([]*Statement, len(statements)) - var i int - for statement := range statements { - retStatements[i] = statement - i++ - } - return retStatements, nil -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/statement_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/statement_test.go deleted file mode 100644 index e509468659..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/statement_test.go +++ /dev/null @@ -1,417 +0,0 @@ -package trustgraph - -import ( - "bytes" - "crypto/x509" - "encoding/json" - "testing" - "time" - - "github.com/docker/libtrust" - "github.com/docker/libtrust/testutil" -) - -const testStatementExpiration = time.Hour * 5 - -func generateStatement(grants []*Grant, key libtrust.PrivateKey, chain []*x509.Certificate) (*Statement, error) { - var statement Statement - - statement.Grants = make([]*jsonGrant, len(grants)) - for i, grant := range grants { - statement.Grants[i] = &jsonGrant{ - Subject: grant.Subject, - Permission: grant.Permission, - Grantee: grant.Grantee, - } - } - statement.IssuedAt = time.Now() - statement.Expiration = time.Now().Add(testStatementExpiration) - statement.Revocations = make([]*jsonRevocation, 0) - - marshalled, err := json.MarshalIndent(statement.jsonStatement, "", " ") - if err != nil { - return nil, err - } - - sig, err := libtrust.NewJSONSignature(marshalled) - if err != nil { - return nil, err - } - err = sig.SignWithChain(key, chain) - if err != nil { - return nil, err - } - statement.signature = sig - - return &statement, nil -} - -func generateTrustChain(t *testing.T, chainLen int) (libtrust.PrivateKey, *x509.CertPool, []*x509.Certificate) { - caKey, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generating key: %s", err) - } - ca, err := testutil.GenerateTrustCA(caKey.CryptoPublicKey(), caKey.CryptoPrivateKey()) - if err != nil { - t.Fatalf("Error generating ca: %s", err) - } - - parent := ca - parentKey := caKey - chain := make([]*x509.Certificate, chainLen) - for i := chainLen - 1; i > 0; i-- { - intermediatekey, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generate key: %s", err) - } - chain[i], err = testutil.GenerateIntermediate(intermediatekey.CryptoPublicKey(), parentKey.CryptoPrivateKey(), parent) - if err != nil { - t.Fatalf("Error generating intermdiate certificate: %s", err) - } - parent = chain[i] - parentKey = intermediatekey - } - trustKey, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - t.Fatalf("Error generate key: %s", err) - } - chain[0], err = testutil.GenerateTrustCert(trustKey.CryptoPublicKey(), parentKey.CryptoPrivateKey(), parent) - if err != nil { - t.Fatalf("Error generate trust cert: %s", err) - } - - caPool := x509.NewCertPool() - caPool.AddCert(ca) - - return trustKey, caPool, chain -} - -func TestLoadStatement(t *testing.T) { - grantCount := 4 - grants, _ := createTestKeysAndGrants(grantCount) - - trustKey, caPool, chain := generateTrustChain(t, 6) - - statement, err := generateStatement(grants, trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - - statementBytes, err := statement.Bytes() - if err != nil { - t.Fatalf("Error getting statement bytes: %s", err) - } - - s2, err := LoadStatement(bytes.NewReader(statementBytes), caPool) - if err != nil { - t.Fatalf("Error loading statement: %s", err) - } - if len(s2.Grants) != grantCount { - t.Fatalf("Unexpected grant length\n\tExpected: %d\n\tActual: %d", grantCount, len(s2.Grants)) - } - - pool := x509.NewCertPool() - _, err = LoadStatement(bytes.NewReader(statementBytes), pool) - if err == nil { - t.Fatalf("No error thrown verifying without an authority") - } else if _, ok := err.(x509.UnknownAuthorityError); !ok { - t.Fatalf("Unexpected error verifying without authority: %s", err) - } - - s2, err = LoadStatement(bytes.NewReader(statementBytes), nil) - if err != nil { - t.Fatalf("Error loading statement: %s", err) - } - if len(s2.Grants) != grantCount { - t.Fatalf("Unexpected grant length\n\tExpected: %d\n\tActual: %d", grantCount, len(s2.Grants)) - } - - badData := make([]byte, len(statementBytes)) - copy(badData, statementBytes) - badData[0] = '[' - _, err = LoadStatement(bytes.NewReader(badData), nil) - if err == nil { - t.Fatalf("No error thrown parsing bad json") - } - - alteredData := make([]byte, len(statementBytes)) - copy(alteredData, statementBytes) - alteredData[30] = '0' - _, err = LoadStatement(bytes.NewReader(alteredData), nil) - if err == nil { - t.Fatalf("No error thrown from bad data") - } -} - -func TestCollapseGrants(t *testing.T) { - grantCount := 8 - grants, keys := createTestKeysAndGrants(grantCount) - linkGrants := make([]*Grant, 4) - linkGrants[0] = &Grant{ - Subject: "/user-3", - Permission: 0x0f, - Grantee: "/user-2", - } - linkGrants[1] = &Grant{ - Subject: "/user-3/sub-project", - Permission: 0x0f, - Grantee: "/user-4", - } - linkGrants[2] = &Grant{ - Subject: "/user-6", - Permission: 0x0f, - Grantee: "/user-7", - } - linkGrants[3] = &Grant{ - Subject: "/user-6/sub-project/specific-app", - Permission: 0x0f, - Grantee: "/user-5", - } - trustKey, pool, chain := generateTrustChain(t, 3) - - statements := make([]*Statement, 3) - var err error - statements[0], err = generateStatement(grants[0:4], trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - statements[1], err = generateStatement(grants[4:], trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - statements[2], err = generateStatement(linkGrants, trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - - statementsCopy := make([]*Statement, len(statements)) - for i, statement := range statements { - b, err := statement.Bytes() - if err != nil { - t.Fatalf("Error getting statement bytes: %s", err) - } - verifiedStatement, err := LoadStatement(bytes.NewReader(b), pool) - if err != nil { - t.Fatalf("Error loading statement: %s", err) - } - // Force sort by reversing order - statementsCopy[len(statementsCopy)-i-1] = verifiedStatement - } - statements = statementsCopy - - collapsedGrants, expiration, err := CollapseStatements(statements, false) - if len(collapsedGrants) != 12 { - t.Fatalf("Unexpected number of grants\n\tExpected: %d\n\tActual: %d", 12, len(collapsedGrants)) - } - if expiration.After(time.Now().Add(time.Hour*5)) || expiration.Before(time.Now()) { - t.Fatalf("Unexpected expiration time: %s", expiration.String()) - } - g := NewMemoryGraph(collapsedGrants) - - testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x0f) - testVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-3", 0x0f) - testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-4", 0x0f) - testVerified(t, g, keys[4].PublicKey(), "user-key-5", "/user-5", 0x0f) - testVerified(t, g, keys[5].PublicKey(), "user-key-6", "/user-6", 0x0f) - testVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-7", 0x0f) - testVerified(t, g, keys[7].PublicKey(), "user-key-8", "/user-8", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3", 0x0f) - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3/sub-project/specific-app", 0x0f) - testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3/sub-project", 0x0f) - testVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-6", 0x0f) - testVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-6/sub-project/specific-app", 0x0f) - testVerified(t, g, keys[4].PublicKey(), "user-key-5", "/user-6/sub-project/specific-app", 0x0f) - - testNotVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3", 0x0f) - testNotVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-6/sub-project", 0x0f) - testNotVerified(t, g, keys[4].PublicKey(), "user-key-5", "/user-6/sub-project", 0x0f) - - // Add revocation grant - statements = append(statements, &Statement{ - jsonStatement{ - IssuedAt: time.Now(), - Expiration: time.Now().Add(testStatementExpiration), - Grants: []*jsonGrant{}, - Revocations: []*jsonRevocation{ - &jsonRevocation{ - Subject: "/user-1", - Revocation: 0x0f, - Grantee: keys[0].KeyID(), - }, - &jsonRevocation{ - Subject: "/user-2", - Revocation: 0x08, - Grantee: keys[1].KeyID(), - }, - &jsonRevocation{ - Subject: "/user-6", - Revocation: 0x0f, - Grantee: "/user-7", - }, - &jsonRevocation{ - Subject: "/user-9", - Revocation: 0x0f, - Grantee: "/user-10", - }, - }, - }, - nil, - }) - - collapsedGrants, expiration, err = CollapseStatements(statements, false) - if len(collapsedGrants) != 12 { - t.Fatalf("Unexpected number of grants\n\tExpected: %d\n\tActual: %d", 12, len(collapsedGrants)) - } - if expiration.After(time.Now().Add(time.Hour*5)) || expiration.Before(time.Now()) { - t.Fatalf("Unexpected expiration time: %s", expiration.String()) - } - g = NewMemoryGraph(collapsedGrants) - - testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f) - testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x0f) - testNotVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-6/sub-project/specific-app", 0x0f) - - testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x07) -} - -func TestFilterStatements(t *testing.T) { - grantCount := 8 - grants, keys := createTestKeysAndGrants(grantCount) - linkGrants := make([]*Grant, 3) - linkGrants[0] = &Grant{ - Subject: "/user-3", - Permission: 0x0f, - Grantee: "/user-2", - } - linkGrants[1] = &Grant{ - Subject: "/user-5", - Permission: 0x0f, - Grantee: "/user-4", - } - linkGrants[2] = &Grant{ - Subject: "/user-7", - Permission: 0x0f, - Grantee: "/user-6", - } - - trustKey, _, chain := generateTrustChain(t, 3) - - statements := make([]*Statement, 5) - var err error - statements[0], err = generateStatement(grants[0:2], trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - statements[1], err = generateStatement(grants[2:4], trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - statements[2], err = generateStatement(grants[4:6], trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - statements[3], err = generateStatement(grants[6:], trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - statements[4], err = generateStatement(linkGrants, trustKey, chain) - if err != nil { - t.Fatalf("Error generating statement: %s", err) - } - collapsed, _, err := CollapseStatements(statements, false) - if err != nil { - t.Fatalf("Error collapsing grants: %s", err) - } - - // Filter 1, all 5 statements - filter1, err := FilterStatements(collapsed) - if err != nil { - t.Fatalf("Error filtering statements: %s", err) - } - if len(filter1) != 5 { - t.Fatalf("Wrong number of statements, expected %d, received %d", 5, len(filter1)) - } - - // Filter 2, one statement - filter2, err := FilterStatements([]*Grant{collapsed[0]}) - if err != nil { - t.Fatalf("Error filtering statements: %s", err) - } - if len(filter2) != 1 { - t.Fatalf("Wrong number of statements, expected %d, received %d", 1, len(filter2)) - } - - // Filter 3, 2 statements, from graph lookup - g := NewMemoryGraph(collapsed) - lookupGrants, err := g.GetGrants(keys[1], "/user-3", 0x0f) - if err != nil { - t.Fatalf("Error looking up grants: %s", err) - } - if len(lookupGrants) != 1 { - t.Fatalf("Wrong numberof grant chains returned from lookup, expected %d, received %d", 1, len(lookupGrants)) - } - if len(lookupGrants[0]) != 2 { - t.Fatalf("Wrong number of grants looked up, expected %d, received %d", 2, len(lookupGrants)) - } - filter3, err := FilterStatements(lookupGrants[0]) - if err != nil { - t.Fatalf("Error filtering statements: %s", err) - } - if len(filter3) != 2 { - t.Fatalf("Wrong number of statements, expected %d, received %d", 2, len(filter3)) - } - -} - -func TestCreateStatement(t *testing.T) { - grantJSON := bytes.NewReader([]byte(`[ - { - "subject": "/user-2", - "permission": 15, - "grantee": "/user-1" - }, - { - "subject": "/user-7", - "permission": 1, - "grantee": "/user-9" - }, - { - "subject": "/user-3", - "permission": 15, - "grantee": "/user-2" - } -]`)) - revocationJSON := bytes.NewReader([]byte(`[ - { - "subject": "user-8", - "revocation": 12, - "grantee": "user-9" - } -]`)) - - trustKey, pool, chain := generateTrustChain(t, 3) - - statement, err := CreateStatement(grantJSON, revocationJSON, testStatementExpiration, trustKey, chain) - if err != nil { - t.Fatalf("Error creating statement: %s", err) - } - - b, err := statement.Bytes() - if err != nil { - t.Fatalf("Error retrieving bytes: %s", err) - } - - verified, err := LoadStatement(bytes.NewReader(b), pool) - if err != nil { - t.Fatalf("Error loading statement: %s", err) - } - - if len(verified.Grants) != 3 { - t.Errorf("Unexpected number of grants, expected %d, received %d", 3, len(verified.Grants)) - } - - if len(verified.Revocations) != 1 { - t.Errorf("Unexpected number of revocations, expected %d, received %d", 1, len(verified.Revocations)) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/util.go b/Godeps/_workspace/src/github.com/docker/libtrust/util.go deleted file mode 100644 index 4d5a6200a8..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/util.go +++ /dev/null @@ -1,225 +0,0 @@ -package libtrust - -import ( - "bytes" - "crypto" - "crypto/elliptic" - "crypto/x509" - "encoding/base32" - "encoding/base64" - "encoding/binary" - "encoding/pem" - "errors" - "fmt" - "math/big" - "strings" -) - -// joseBase64UrlEncode encodes the given data using the standard base64 url -// encoding format but with all trailing '=' characters ommitted in accordance -// with the jose specification. -// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2 -func joseBase64UrlEncode(b []byte) string { - return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") -} - -// joseBase64UrlDecode decodes the given string using the standard base64 url -// decoder but first adds the appropriate number of trailing '=' characters in -// accordance with the jose specification. -// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2 -func joseBase64UrlDecode(s string) ([]byte, error) { - switch len(s) % 4 { - case 0: - case 2: - s += "==" - case 3: - s += "=" - default: - return nil, errors.New("illegal base64url string") - } - return base64.URLEncoding.DecodeString(s) -} - -func keyIDEncode(b []byte) string { - s := strings.TrimRight(base32.StdEncoding.EncodeToString(b), "=") - var buf bytes.Buffer - var i int - for i = 0; i < len(s)/4-1; i++ { - start := i * 4 - end := start + 4 - buf.WriteString(s[start:end] + ":") - } - buf.WriteString(s[i*4:]) - return buf.String() -} - -func keyIDFromCryptoKey(pubKey PublicKey) string { - // Generate and return a 'libtrust' fingerprint of the public key. - // For an RSA key this should be: - // SHA256(DER encoded ASN1) - // Then truncated to 240 bits and encoded into 12 base32 groups like so: - // ABCD:EFGH:IJKL:MNOP:QRST:UVWX:YZ23:4567:ABCD:EFGH:IJKL:MNOP - derBytes, err := x509.MarshalPKIXPublicKey(pubKey.CryptoPublicKey()) - if err != nil { - return "" - } - hasher := crypto.SHA256.New() - hasher.Write(derBytes) - return keyIDEncode(hasher.Sum(nil)[:30]) -} - -func stringFromMap(m map[string]interface{}, key string) (string, error) { - val, ok := m[key] - if !ok { - return "", fmt.Errorf("%q value not specified", key) - } - - str, ok := val.(string) - if !ok { - return "", fmt.Errorf("%q value must be a string", key) - } - delete(m, key) - - return str, nil -} - -func parseECCoordinate(cB64Url string, curve elliptic.Curve) (*big.Int, error) { - curveByteLen := (curve.Params().BitSize + 7) >> 3 - - cBytes, err := joseBase64UrlDecode(cB64Url) - if err != nil { - return nil, fmt.Errorf("invalid base64 URL encoding: %s", err) - } - cByteLength := len(cBytes) - if cByteLength != curveByteLen { - return nil, fmt.Errorf("invalid number of octets: got %d, should be %d", cByteLength, curveByteLen) - } - return new(big.Int).SetBytes(cBytes), nil -} - -func parseECPrivateParam(dB64Url string, curve elliptic.Curve) (*big.Int, error) { - dBytes, err := joseBase64UrlDecode(dB64Url) - if err != nil { - return nil, fmt.Errorf("invalid base64 URL encoding: %s", err) - } - - // The length of this octet string MUST be ceiling(log-base-2(n)/8) - // octets (where n is the order of the curve). This is because the private - // key d must be in the interval [1, n-1] so the bitlength of d should be - // no larger than the bitlength of n-1. The easiest way to find the octet - // length is to take bitlength(n-1), add 7 to force a carry, and shift this - // bit sequence right by 3, which is essentially dividing by 8 and adding - // 1 if there is any remainder. Thus, the private key value d should be - // output to (bitlength(n-1)+7)>>3 octets. - n := curve.Params().N - octetLength := (new(big.Int).Sub(n, big.NewInt(1)).BitLen() + 7) >> 3 - dByteLength := len(dBytes) - - if dByteLength != octetLength { - return nil, fmt.Errorf("invalid number of octets: got %d, should be %d", dByteLength, octetLength) - } - - return new(big.Int).SetBytes(dBytes), nil -} - -func parseRSAModulusParam(nB64Url string) (*big.Int, error) { - nBytes, err := joseBase64UrlDecode(nB64Url) - if err != nil { - return nil, fmt.Errorf("invalid base64 URL encoding: %s", err) - } - - return new(big.Int).SetBytes(nBytes), nil -} - -func serializeRSAPublicExponentParam(e int) []byte { - // We MUST use the minimum number of octets to represent E. - // E is supposed to be 65537 for performance and security reasons - // and is what golang's rsa package generates, but it might be - // different if imported from some other generator. - buf := make([]byte, 4) - binary.BigEndian.PutUint32(buf, uint32(e)) - var i int - for i = 0; i < 8; i++ { - if buf[i] != 0 { - break - } - } - return buf[i:] -} - -func parseRSAPublicExponentParam(eB64Url string) (int, error) { - eBytes, err := joseBase64UrlDecode(eB64Url) - if err != nil { - return 0, fmt.Errorf("invalid base64 URL encoding: %s", err) - } - // Only the minimum number of bytes were used to represent E, but - // binary.BigEndian.Uint32 expects at least 4 bytes, so we need - // to add zero padding if necassary. - byteLen := len(eBytes) - buf := make([]byte, 4-byteLen, 4) - eBytes = append(buf, eBytes...) - - return int(binary.BigEndian.Uint32(eBytes)), nil -} - -func parseRSAPrivateKeyParamFromMap(m map[string]interface{}, key string) (*big.Int, error) { - b64Url, err := stringFromMap(m, key) - if err != nil { - return nil, err - } - - paramBytes, err := joseBase64UrlDecode(b64Url) - if err != nil { - return nil, fmt.Errorf("invaled base64 URL encoding: %s", err) - } - - return new(big.Int).SetBytes(paramBytes), nil -} - -func createPemBlock(name string, derBytes []byte, headers map[string]interface{}) (*pem.Block, error) { - pemBlock := &pem.Block{Type: name, Bytes: derBytes, Headers: map[string]string{}} - for k, v := range headers { - switch val := v.(type) { - case string: - pemBlock.Headers[k] = val - case []string: - if k == "hosts" { - pemBlock.Headers[k] = strings.Join(val, ",") - } else { - // Return error, non-encodable type - } - default: - // Return error, non-encodable type - } - } - - return pemBlock, nil -} - -func pubKeyFromPEMBlock(pemBlock *pem.Block) (PublicKey, error) { - cryptoPublicKey, err := x509.ParsePKIXPublicKey(pemBlock.Bytes) - if err != nil { - return nil, fmt.Errorf("unable to decode Public Key PEM data: %s", err) - } - - pubKey, err := FromCryptoPublicKey(cryptoPublicKey) - if err != nil { - return nil, err - } - - addPEMHeadersToKey(pemBlock, pubKey) - - return pubKey, nil -} - -func addPEMHeadersToKey(pemBlock *pem.Block, pubKey PublicKey) { - for key, value := range pemBlock.Headers { - var safeVal interface{} - if key == "hosts" { - safeVal = strings.Split(value, ",") - } else { - safeVal = value - } - pubKey.AddExtendedField(key, safeVal) - } -} diff --git a/Godeps/_workspace/src/github.com/docker/libtrust/util_test.go b/Godeps/_workspace/src/github.com/docker/libtrust/util_test.go deleted file mode 100644 index ee54f5b8cc..0000000000 --- a/Godeps/_workspace/src/github.com/docker/libtrust/util_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package libtrust - -import ( - "encoding/pem" - "reflect" - "testing" -) - -func TestAddPEMHeadersToKey(t *testing.T) { - pk := &rsaPublicKey{nil, map[string]interface{}{}} - blk := &pem.Block{Headers: map[string]string{"hosts": "localhost,127.0.0.1"}} - addPEMHeadersToKey(blk, pk) - - val := pk.GetExtendedField("hosts") - hosts, ok := val.([]string) - if !ok { - t.Fatalf("hosts type(%v), expected []string", reflect.TypeOf(val)) - } - expected := []string{"localhost", "127.0.0.1"} - if !reflect.DeepEqual(hosts, expected) { - t.Errorf("hosts(%v), expected %v", hosts, expected) - } -} diff --git a/Godeps/_workspace/src/github.com/google/go-querystring/query/encode_test.go b/Godeps/_workspace/src/github.com/google/go-querystring/query/encode_test.go deleted file mode 100644 index 6cf26d6204..0000000000 --- a/Godeps/_workspace/src/github.com/google/go-querystring/query/encode_test.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package query - -import ( - "fmt" - "net/url" - "reflect" - "testing" - "time" -) - -func TestValues_types(t *testing.T) { - str := "string" - strPtr := &str - - tests := []struct { - in interface{} - want url.Values - }{ - { - // basic primitives - struct { - A string - B int - C uint - D float32 - E bool - }{}, - url.Values{ - "A": {""}, - "B": {"0"}, - "C": {"0"}, - "D": {"0"}, - "E": {"false"}, - }, - }, - { - // pointers - struct { - A *string - B *int - C **string - }{A: strPtr, C: &strPtr}, - url.Values{ - "A": {str}, - "B": {""}, - "C": {str}, - }, - }, - { - // slices and arrays - struct { - A []string - B []string `url:",comma"` - C []string `url:",space"` - D [2]string - E [2]string `url:",comma"` - F [2]string `url:",space"` - G []*string `url:",space"` - H []bool `url:",int,space"` - }{ - A: []string{"a", "b"}, - B: []string{"a", "b"}, - C: []string{"a", "b"}, - D: [2]string{"a", "b"}, - E: [2]string{"a", "b"}, - F: [2]string{"a", "b"}, - G: []*string{&str, &str}, - H: []bool{true, false}, - }, - url.Values{ - "A": {"a", "b"}, - "B": {"a,b"}, - "C": {"a b"}, - "D": {"a", "b"}, - "E": {"a,b"}, - "F": {"a b"}, - "G": {"string string"}, - "H": {"1 0"}, - }, - }, - { - // other types - struct { - A time.Time - B time.Time `url:",unix"` - C bool `url:",int"` - D bool `url:",int"` - }{ - A: time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC), - B: time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC), - C: true, - D: false, - }, - url.Values{ - "A": {"2000-01-01T12:34:56Z"}, - "B": {"946730096"}, - "C": {"1"}, - "D": {"0"}, - }, - }, - } - - for i, tt := range tests { - v, err := Values(tt.in) - if err != nil { - t.Errorf("%d. Values(%q) returned error: %v", i, tt.in, err) - } - - if !reflect.DeepEqual(tt.want, v) { - t.Errorf("%d. Values(%q) returned %v, want %v", i, tt.in, v, tt.want) - } - } -} - -func TestValues_omitEmpty(t *testing.T) { - str := "" - s := struct { - a string - A string - B string `url:",omitempty"` - C string `url:"-"` - D string `url:"omitempty"` // actually named omitempty, not an option - E *string `url:",omitempty"` - }{E: &str} - - v, err := Values(s) - if err != nil { - t.Errorf("Values(%q) returned error: %v", s, err) - } - - want := url.Values{ - "A": {""}, - "omitempty": {""}, - "E": {""}, // E is included because the pointer is not empty, even though the string being pointed to is - } - if !reflect.DeepEqual(want, v) { - t.Errorf("Values(%q) returned %v, want %v", s, v, want) - } -} - -type A struct { - B -} - -type B struct { - C string -} - -type D struct { - B - C string -} - -func TestValues_embeddedStructs(t *testing.T) { - tests := []struct { - in interface{} - want url.Values - }{ - { - A{B{C: "foo"}}, - url.Values{"C": {"foo"}}, - }, - { - D{B: B{C: "bar"}, C: "foo"}, - url.Values{"C": {"foo", "bar"}}, - }, - } - - for i, tt := range tests { - v, err := Values(tt.in) - if err != nil { - t.Errorf("%d. Values(%q) returned error: %v", i, tt.in, err) - } - - if !reflect.DeepEqual(tt.want, v) { - t.Errorf("%d. Values(%q) returned %v, want %v", i, tt.in, v, tt.want) - } - } -} - -func TestValues_invalidInput(t *testing.T) { - _, err := Values("") - if err == nil { - t.Errorf("expected Values() to return an error on invalid input") - } -} - -type EncodedArgs []string - -func (m EncodedArgs) EncodeValues(v *url.Values) error { - for i, arg := range m { - v.Set(fmt.Sprintf("arg.%d", i), arg) - } - return nil -} - -func TestValues_Marshaler(t *testing.T) { - s := struct { - Args EncodedArgs `url:"args"` - }{[]string{"a", "b", "c"}} - v, err := Values(s) - if err != nil { - t.Errorf("Values(%q) returned error: %v", s, err) - } - - want := url.Values{ - "arg.0": {"a"}, - "arg.1": {"b"}, - "arg.2": {"c"}, - } - if !reflect.DeepEqual(want, v) { - t.Errorf("Values(%q) returned %v, want %v", s, v, want) - } -} - -func TestTagParsing(t *testing.T) { - name, opts := parseTag("field,foobar,foo") - if name != "field" { - t.Fatalf("name = %q, want field", name) - } - for _, tt := range []struct { - opt string - want bool - }{ - {"foobar", true}, - {"foo", true}, - {"bar", false}, - {"field", false}, - } { - if opts.Contains(tt.opt) != tt.want { - t.Errorf("Contains(%q) = %v", tt.opt, !tt.want) - } - } -} diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/decode_hooks_test.go b/Godeps/_workspace/src/github.com/mitchellh/mapstructure/decode_hooks_test.go deleted file mode 100644 index b417deeb64..0000000000 --- a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/decode_hooks_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package mapstructure - -import ( - "errors" - "reflect" - "testing" -) - -func TestComposeDecodeHookFunc(t *testing.T) { - f1 := func( - f reflect.Kind, - t reflect.Kind, - data interface{}) (interface{}, error) { - return data.(string) + "foo", nil - } - - f2 := func( - f reflect.Kind, - t reflect.Kind, - data interface{}) (interface{}, error) { - return data.(string) + "bar", nil - } - - f := ComposeDecodeHookFunc(f1, f2) - - result, err := f(reflect.String, reflect.Slice, "") - if err != nil { - t.Fatalf("bad: %s", err) - } - if result.(string) != "foobar" { - t.Fatalf("bad: %#v", result) - } -} - -func TestComposeDecodeHookFunc_err(t *testing.T) { - f1 := func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) { - return nil, errors.New("foo") - } - - f2 := func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) { - panic("NOPE") - } - - f := ComposeDecodeHookFunc(f1, f2) - - _, err := f(reflect.String, reflect.Slice, 42) - if err.Error() != "foo" { - t.Fatalf("bad: %s", err) - } -} - -func TestComposeDecodeHookFunc_kinds(t *testing.T) { - var f2From reflect.Kind - - f1 := func( - f reflect.Kind, - t reflect.Kind, - data interface{}) (interface{}, error) { - return int(42), nil - } - - f2 := func( - f reflect.Kind, - t reflect.Kind, - data interface{}) (interface{}, error) { - f2From = f - return data, nil - } - - f := ComposeDecodeHookFunc(f1, f2) - - _, err := f(reflect.String, reflect.Slice, "") - if err != nil { - t.Fatalf("bad: %s", err) - } - if f2From != reflect.Int { - t.Fatalf("bad: %#v", f2From) - } -} - -func TestStringToSliceHookFunc(t *testing.T) { - f := StringToSliceHookFunc(",") - - cases := []struct { - f, t reflect.Kind - data interface{} - result interface{} - err bool - }{ - {reflect.Slice, reflect.Slice, 42, 42, false}, - {reflect.String, reflect.String, 42, 42, false}, - { - reflect.String, - reflect.Slice, - "foo,bar,baz", - []string{"foo", "bar", "baz"}, - false, - }, - { - reflect.String, - reflect.Slice, - "", - []string{}, - false, - }, - } - - for i, tc := range cases { - actual, err := f(tc.f, tc.t, tc.data) - if tc.err != (err != nil) { - t.Fatalf("case %d: expected err %#v", i, tc.err) - } - if !reflect.DeepEqual(actual, tc.result) { - t.Fatalf( - "case %d: expected %#v, got %#v", - i, tc.result, actual) - } - } -} - -func TestWeaklyTypedHook(t *testing.T) { - var f DecodeHookFunc = WeaklyTypedHook - - cases := []struct { - f, t reflect.Kind - data interface{} - result interface{} - err bool - }{ - // TO STRING - { - reflect.Bool, - reflect.String, - false, - "0", - false, - }, - - { - reflect.Bool, - reflect.String, - true, - "1", - false, - }, - - { - reflect.Float32, - reflect.String, - float32(7), - "7", - false, - }, - - { - reflect.Int, - reflect.String, - int(7), - "7", - false, - }, - - { - reflect.Slice, - reflect.String, - []uint8("foo"), - "foo", - false, - }, - - { - reflect.Uint, - reflect.String, - uint(7), - "7", - false, - }, - } - - for i, tc := range cases { - actual, err := f(tc.f, tc.t, tc.data) - if tc.err != (err != nil) { - t.Fatalf("case %d: expected err %#v", i, tc.err) - } - if !reflect.DeepEqual(actual, tc.result) { - t.Fatalf( - "case %d: expected %#v, got %#v", - i, tc.result, actual) - } - } -} diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_benchmark_test.go b/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_benchmark_test.go deleted file mode 100644 index b50ac36e5d..0000000000 --- a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_benchmark_test.go +++ /dev/null @@ -1,243 +0,0 @@ -package mapstructure - -import ( - "testing" -) - -func Benchmark_Decode(b *testing.B) { - type Person struct { - Name string - Age int - Emails []string - Extra map[string]string - } - - input := map[string]interface{}{ - "name": "Mitchell", - "age": 91, - "emails": []string{"one", "two", "three"}, - "extra": map[string]string{ - "twitter": "mitchellh", - }, - } - - var result Person - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeBasic(b *testing.B) { - input := map[string]interface{}{ - "vstring": "foo", - "vint": 42, - "Vuint": 42, - "vbool": true, - "Vfloat": 42.42, - "vsilent": true, - "vdata": 42, - } - - var result Basic - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeEmbedded(b *testing.B) { - input := map[string]interface{}{ - "vstring": "foo", - "Basic": map[string]interface{}{ - "vstring": "innerfoo", - }, - "vunique": "bar", - } - - var result Embedded - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeTypeConversion(b *testing.B) { - input := map[string]interface{}{ - "IntToFloat": 42, - "IntToUint": 42, - "IntToBool": 1, - "IntToString": 42, - "UintToInt": 42, - "UintToFloat": 42, - "UintToBool": 42, - "UintToString": 42, - "BoolToInt": true, - "BoolToUint": true, - "BoolToFloat": true, - "BoolToString": true, - "FloatToInt": 42.42, - "FloatToUint": 42.42, - "FloatToBool": 42.42, - "FloatToString": 42.42, - "StringToInt": "42", - "StringToUint": "42", - "StringToBool": "1", - "StringToFloat": "42.42", - "SliceToMap": []interface{}{}, - "MapToSlice": map[string]interface{}{}, - } - - var resultStrict TypeConversionResult - for i := 0; i < b.N; i++ { - Decode(input, &resultStrict) - } -} - -func Benchmark_DecodeMap(b *testing.B) { - input := map[string]interface{}{ - "vfoo": "foo", - "vother": map[interface{}]interface{}{ - "foo": "foo", - "bar": "bar", - }, - } - - var result Map - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeMapOfStruct(b *testing.B) { - input := map[string]interface{}{ - "value": map[string]interface{}{ - "foo": map[string]string{"vstring": "one"}, - "bar": map[string]string{"vstring": "two"}, - }, - } - - var result MapOfStruct - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeSlice(b *testing.B) { - input := map[string]interface{}{ - "vfoo": "foo", - "vbar": []string{"foo", "bar", "baz"}, - } - - var result Slice - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeSliceOfStruct(b *testing.B) { - input := map[string]interface{}{ - "value": []map[string]interface{}{ - {"vstring": "one"}, - {"vstring": "two"}, - }, - } - - var result SliceOfStruct - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} - -func Benchmark_DecodeWeaklyTypedInput(b *testing.B) { - type Person struct { - Name string - Age int - Emails []string - } - - // This input can come from anywhere, but typically comes from - // something like decoding JSON, generated by a weakly typed language - // such as PHP. - input := map[string]interface{}{ - "name": 123, // number => string - "age": "42", // string => number - "emails": map[string]interface{}{}, // empty map => empty array - } - - var result Person - config := &DecoderConfig{ - WeaklyTypedInput: true, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - panic(err) - } - - for i := 0; i < b.N; i++ { - decoder.Decode(input) - } -} - -func Benchmark_DecodeMetadata(b *testing.B) { - type Person struct { - Name string - Age int - } - - input := map[string]interface{}{ - "name": "Mitchell", - "age": 91, - "email": "foo@bar.com", - } - - var md Metadata - var result Person - config := &DecoderConfig{ - Metadata: &md, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - panic(err) - } - - for i := 0; i < b.N; i++ { - decoder.Decode(input) - } -} - -func Benchmark_DecodeMetadataEmbedded(b *testing.B) { - input := map[string]interface{}{ - "vstring": "foo", - "vunique": "bar", - } - - var md Metadata - var result EmbeddedSquash - config := &DecoderConfig{ - Metadata: &md, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - b.Fatalf("err: %s", err) - } - - for i := 0; i < b.N; i++ { - decoder.Decode(input) - } -} - -func Benchmark_DecodeTagged(b *testing.B) { - input := map[string]interface{}{ - "foo": "bar", - "bar": "value", - } - - var result Tagged - for i := 0; i < b.N; i++ { - Decode(input, &result) - } -} diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go b/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go deleted file mode 100644 index 7054f1ac9a..0000000000 --- a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package mapstructure - -import "testing" - -// GH-1 -func TestDecode_NilValue(t *testing.T) { - input := map[string]interface{}{ - "vfoo": nil, - "vother": nil, - } - - var result Map - err := Decode(input, &result) - if err != nil { - t.Fatalf("should not error: %s", err) - } - - if result.Vfoo != "" { - t.Fatalf("value should be default: %s", result.Vfoo) - } - - if result.Vother != nil { - t.Fatalf("Vother should be nil: %s", result.Vother) - } -} - -// GH-10 -func TestDecode_mapInterfaceInterface(t *testing.T) { - input := map[interface{}]interface{}{ - "vfoo": nil, - "vother": nil, - } - - var result Map - err := Decode(input, &result) - if err != nil { - t.Fatalf("should not error: %s", err) - } - - if result.Vfoo != "" { - t.Fatalf("value should be default: %s", result.Vfoo) - } - - if result.Vother != nil { - t.Fatalf("Vother should be nil: %s", result.Vother) - } -} diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_examples_test.go b/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_examples_test.go deleted file mode 100644 index aa393cc572..0000000000 --- a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_examples_test.go +++ /dev/null @@ -1,169 +0,0 @@ -package mapstructure - -import ( - "fmt" -) - -func ExampleDecode() { - type Person struct { - Name string - Age int - Emails []string - Extra map[string]string - } - - // This input can come from anywhere, but typically comes from - // something like decoding JSON where we're not quite sure of the - // struct initially. - input := map[string]interface{}{ - "name": "Mitchell", - "age": 91, - "emails": []string{"one", "two", "three"}, - "extra": map[string]string{ - "twitter": "mitchellh", - }, - } - - var result Person - err := Decode(input, &result) - if err != nil { - panic(err) - } - - fmt.Printf("%#v", result) - // Output: - // mapstructure.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}} -} - -func ExampleDecode_errors() { - type Person struct { - Name string - Age int - Emails []string - Extra map[string]string - } - - // This input can come from anywhere, but typically comes from - // something like decoding JSON where we're not quite sure of the - // struct initially. - input := map[string]interface{}{ - "name": 123, - "age": "bad value", - "emails": []int{1, 2, 3}, - } - - var result Person - err := Decode(input, &result) - if err == nil { - panic("should have an error") - } - - fmt.Println(err.Error()) - // Output: - // 5 error(s) decoding: - // - // * 'Name' expected type 'string', got unconvertible type 'int' - // * 'Age' expected type 'int', got unconvertible type 'string' - // * 'Emails[0]' expected type 'string', got unconvertible type 'int' - // * 'Emails[1]' expected type 'string', got unconvertible type 'int' - // * 'Emails[2]' expected type 'string', got unconvertible type 'int' -} - -func ExampleDecode_metadata() { - type Person struct { - Name string - Age int - } - - // This input can come from anywhere, but typically comes from - // something like decoding JSON where we're not quite sure of the - // struct initially. - input := map[string]interface{}{ - "name": "Mitchell", - "age": 91, - "email": "foo@bar.com", - } - - // For metadata, we make a more advanced DecoderConfig so we can - // more finely configure the decoder that is used. In this case, we - // just tell the decoder we want to track metadata. - var md Metadata - var result Person - config := &DecoderConfig{ - Metadata: &md, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - panic(err) - } - - if err := decoder.Decode(input); err != nil { - panic(err) - } - - fmt.Printf("Unused keys: %#v", md.Unused) - // Output: - // Unused keys: []string{"email"} -} - -func ExampleDecode_weaklyTypedInput() { - type Person struct { - Name string - Age int - Emails []string - } - - // This input can come from anywhere, but typically comes from - // something like decoding JSON, generated by a weakly typed language - // such as PHP. - input := map[string]interface{}{ - "name": 123, // number => string - "age": "42", // string => number - "emails": map[string]interface{}{}, // empty map => empty array - } - - var result Person - config := &DecoderConfig{ - WeaklyTypedInput: true, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - panic(err) - } - - err = decoder.Decode(input) - if err != nil { - panic(err) - } - - fmt.Printf("%#v", result) - // Output: mapstructure.Person{Name:"123", Age:42, Emails:[]string{}} -} - -func ExampleDecode_tags() { - // Note that the mapstructure tags defined in the struct type - // can indicate which fields the values are mapped to. - type Person struct { - Name string `mapstructure:"person_name"` - Age int `mapstructure:"person_age"` - } - - input := map[string]interface{}{ - "person_name": "Mitchell", - "person_age": 91, - } - - var result Person - err := Decode(input, &result) - if err != nil { - panic(err) - } - - fmt.Printf("%#v", result) - // Output: - // mapstructure.Person{Name:"Mitchell", Age:91} -} diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_test.go b/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_test.go deleted file mode 100644 index 23029c7c4a..0000000000 --- a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure_test.go +++ /dev/null @@ -1,828 +0,0 @@ -package mapstructure - -import ( - "reflect" - "sort" - "testing" -) - -type Basic struct { - Vstring string - Vint int - Vuint uint - Vbool bool - Vfloat float64 - Vextra string - vsilent bool - Vdata interface{} -} - -type Embedded struct { - Basic - Vunique string -} - -type EmbeddedPointer struct { - *Basic - Vunique string -} - -type EmbeddedSquash struct { - Basic `mapstructure:",squash"` - Vunique string -} - -type Map struct { - Vfoo string - Vother map[string]string -} - -type MapOfStruct struct { - Value map[string]Basic -} - -type Nested struct { - Vfoo string - Vbar Basic -} - -type NestedPointer struct { - Vfoo string - Vbar *Basic -} - -type Slice struct { - Vfoo string - Vbar []string -} - -type SliceOfStruct struct { - Value []Basic -} - -type Tagged struct { - Extra string `mapstructure:"bar,what,what"` - Value string `mapstructure:"foo"` -} - -type TypeConversionResult struct { - IntToFloat float32 - IntToUint uint - IntToBool bool - IntToString string - UintToInt int - UintToFloat float32 - UintToBool bool - UintToString string - BoolToInt int - BoolToUint uint - BoolToFloat float32 - BoolToString string - FloatToInt int - FloatToUint uint - FloatToBool bool - FloatToString string - SliceUint8ToString string - StringToInt int - StringToUint uint - StringToBool bool - StringToFloat float32 - SliceToMap map[string]interface{} - MapToSlice []interface{} -} - -func TestBasicTypes(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": "foo", - "vint": 42, - "Vuint": 42, - "vbool": true, - "Vfloat": 42.42, - "vsilent": true, - "vdata": 42, - } - - var result Basic - err := Decode(input, &result) - if err != nil { - t.Errorf("got an err: %s", err.Error()) - t.FailNow() - } - - if result.Vstring != "foo" { - t.Errorf("vstring value should be 'foo': %#v", result.Vstring) - } - - if result.Vint != 42 { - t.Errorf("vint value should be 42: %#v", result.Vint) - } - - if result.Vuint != 42 { - t.Errorf("vuint value should be 42: %#v", result.Vuint) - } - - if result.Vbool != true { - t.Errorf("vbool value should be true: %#v", result.Vbool) - } - - if result.Vfloat != 42.42 { - t.Errorf("vfloat value should be 42.42: %#v", result.Vfloat) - } - - if result.Vextra != "" { - t.Errorf("vextra value should be empty: %#v", result.Vextra) - } - - if result.vsilent != false { - t.Error("vsilent should not be set, it is unexported") - } - - if result.Vdata != 42 { - t.Error("vdata should be valid") - } -} - -func TestBasic_IntWithFloat(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vint": float64(42), - } - - var result Basic - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an err: %s", err) - } -} - -func TestDecode_Embedded(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": "foo", - "Basic": map[string]interface{}{ - "vstring": "innerfoo", - }, - "vunique": "bar", - } - - var result Embedded - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an err: %s", err.Error()) - } - - if result.Vstring != "innerfoo" { - t.Errorf("vstring value should be 'innerfoo': %#v", result.Vstring) - } - - if result.Vunique != "bar" { - t.Errorf("vunique value should be 'bar': %#v", result.Vunique) - } -} - -func TestDecode_EmbeddedPointer(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": "foo", - "Basic": map[string]interface{}{ - "vstring": "innerfoo", - }, - "vunique": "bar", - } - - var result EmbeddedPointer - err := Decode(input, &result) - if err == nil { - t.Fatal("should get error") - } -} - -func TestDecode_EmbeddedSquash(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": "foo", - "vunique": "bar", - } - - var result EmbeddedSquash - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an err: %s", err.Error()) - } - - if result.Vstring != "foo" { - t.Errorf("vstring value should be 'foo': %#v", result.Vstring) - } - - if result.Vunique != "bar" { - t.Errorf("vunique value should be 'bar': %#v", result.Vunique) - } -} - -func TestDecode_DecodeHook(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vint": "WHAT", - } - - decodeHook := func(from reflect.Kind, to reflect.Kind, v interface{}) (interface{}, error) { - if from == reflect.String && to != reflect.String { - return 5, nil - } - - return v, nil - } - - var result Basic - config := &DecoderConfig{ - DecodeHook: decodeHook, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - t.Fatalf("err: %s", err) - } - - err = decoder.Decode(input) - if err != nil { - t.Fatalf("got an err: %s", err) - } - - if result.Vint != 5 { - t.Errorf("vint should be 5: %#v", result.Vint) - } -} - -func TestDecode_Nil(t *testing.T) { - t.Parallel() - - var input interface{} = nil - result := Basic{ - Vstring: "foo", - } - - err := Decode(input, &result) - if err != nil { - t.Fatalf("err: %s", err) - } - - if result.Vstring != "foo" { - t.Fatalf("bad: %#v", result.Vstring) - } -} - -func TestDecode_NonStruct(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "foo": "bar", - "bar": "baz", - } - - var result map[string]string - err := Decode(input, &result) - if err != nil { - t.Fatalf("err: %s", err) - } - - if result["foo"] != "bar" { - t.Fatal("foo is not bar") - } -} - -func TestDecode_TypeConversion(t *testing.T) { - input := map[string]interface{}{ - "IntToFloat": 42, - "IntToUint": 42, - "IntToBool": 1, - "IntToString": 42, - "UintToInt": 42, - "UintToFloat": 42, - "UintToBool": 42, - "UintToString": 42, - "BoolToInt": true, - "BoolToUint": true, - "BoolToFloat": true, - "BoolToString": true, - "FloatToInt": 42.42, - "FloatToUint": 42.42, - "FloatToBool": 42.42, - "FloatToString": 42.42, - "SliceUint8ToString": []uint8("foo"), - "StringToInt": "42", - "StringToUint": "42", - "StringToBool": "1", - "StringToFloat": "42.42", - "SliceToMap": []interface{}{}, - "MapToSlice": map[string]interface{}{}, - } - - expectedResultStrict := TypeConversionResult{ - IntToFloat: 42.0, - IntToUint: 42, - UintToInt: 42, - UintToFloat: 42, - BoolToInt: 0, - BoolToUint: 0, - BoolToFloat: 0, - FloatToInt: 42, - FloatToUint: 42, - } - - expectedResultWeak := TypeConversionResult{ - IntToFloat: 42.0, - IntToUint: 42, - IntToBool: true, - IntToString: "42", - UintToInt: 42, - UintToFloat: 42, - UintToBool: true, - UintToString: "42", - BoolToInt: 1, - BoolToUint: 1, - BoolToFloat: 1, - BoolToString: "1", - FloatToInt: 42, - FloatToUint: 42, - FloatToBool: true, - FloatToString: "42.42", - SliceUint8ToString: "foo", - StringToInt: 42, - StringToUint: 42, - StringToBool: true, - StringToFloat: 42.42, - SliceToMap: map[string]interface{}{}, - MapToSlice: []interface{}{}, - } - - // Test strict type conversion - var resultStrict TypeConversionResult - err := Decode(input, &resultStrict) - if err == nil { - t.Errorf("should return an error") - } - if !reflect.DeepEqual(resultStrict, expectedResultStrict) { - t.Errorf("expected %v, got: %v", expectedResultStrict, resultStrict) - } - - // Test weak type conversion - var decoder *Decoder - var resultWeak TypeConversionResult - - config := &DecoderConfig{ - WeaklyTypedInput: true, - Result: &resultWeak, - } - - decoder, err = NewDecoder(config) - if err != nil { - t.Fatalf("err: %s", err) - } - - err = decoder.Decode(input) - if err != nil { - t.Fatalf("got an err: %s", err) - } - - if !reflect.DeepEqual(resultWeak, expectedResultWeak) { - t.Errorf("expected \n%#v, got: \n%#v", expectedResultWeak, resultWeak) - } -} - -func TestDecoder_ErrorUnused(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": "hello", - "foo": "bar", - } - - var result Basic - config := &DecoderConfig{ - ErrorUnused: true, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - t.Fatalf("err: %s", err) - } - - err = decoder.Decode(input) - if err == nil { - t.Fatal("expected error") - } -} - -func TestMap(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vfoo": "foo", - "vother": map[interface{}]interface{}{ - "foo": "foo", - "bar": "bar", - }, - } - - var result Map - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an error: %s", err) - } - - if result.Vfoo != "foo" { - t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo) - } - - if result.Vother == nil { - t.Fatal("vother should not be nil") - } - - if len(result.Vother) != 2 { - t.Error("vother should have two items") - } - - if result.Vother["foo"] != "foo" { - t.Errorf("'foo' key should be foo, got: %#v", result.Vother["foo"]) - } - - if result.Vother["bar"] != "bar" { - t.Errorf("'bar' key should be bar, got: %#v", result.Vother["bar"]) - } -} - -func TestMapOfStruct(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "value": map[string]interface{}{ - "foo": map[string]string{"vstring": "one"}, - "bar": map[string]string{"vstring": "two"}, - }, - } - - var result MapOfStruct - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an err: %s", err) - } - - if result.Value == nil { - t.Fatal("value should not be nil") - } - - if len(result.Value) != 2 { - t.Error("value should have two items") - } - - if result.Value["foo"].Vstring != "one" { - t.Errorf("foo value should be 'one', got: %s", result.Value["foo"].Vstring) - } - - if result.Value["bar"].Vstring != "two" { - t.Errorf("bar value should be 'two', got: %s", result.Value["bar"].Vstring) - } -} - -func TestNestedType(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vfoo": "foo", - "vbar": map[string]interface{}{ - "vstring": "foo", - "vint": 42, - "vbool": true, - }, - } - - var result Nested - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an err: %s", err.Error()) - } - - if result.Vfoo != "foo" { - t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo) - } - - if result.Vbar.Vstring != "foo" { - t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring) - } - - if result.Vbar.Vint != 42 { - t.Errorf("vint value should be 42: %#v", result.Vbar.Vint) - } - - if result.Vbar.Vbool != true { - t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool) - } - - if result.Vbar.Vextra != "" { - t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra) - } -} - -func TestNestedTypePointer(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vfoo": "foo", - "vbar": &map[string]interface{}{ - "vstring": "foo", - "vint": 42, - "vbool": true, - }, - } - - var result NestedPointer - err := Decode(input, &result) - if err != nil { - t.Fatalf("got an err: %s", err.Error()) - } - - if result.Vfoo != "foo" { - t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo) - } - - if result.Vbar.Vstring != "foo" { - t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring) - } - - if result.Vbar.Vint != 42 { - t.Errorf("vint value should be 42: %#v", result.Vbar.Vint) - } - - if result.Vbar.Vbool != true { - t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool) - } - - if result.Vbar.Vextra != "" { - t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra) - } -} - -func TestSlice(t *testing.T) { - t.Parallel() - - inputStringSlice := map[string]interface{}{ - "vfoo": "foo", - "vbar": []string{"foo", "bar", "baz"}, - } - - inputStringSlicePointer := map[string]interface{}{ - "vfoo": "foo", - "vbar": &[]string{"foo", "bar", "baz"}, - } - - outputStringSlice := &Slice{ - "foo", - []string{"foo", "bar", "baz"}, - } - - testSliceInput(t, inputStringSlice, outputStringSlice) - testSliceInput(t, inputStringSlicePointer, outputStringSlice) -} - -func TestInvalidSlice(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vfoo": "foo", - "vbar": 42, - } - - result := Slice{} - err := Decode(input, &result) - if err == nil { - t.Errorf("expected failure") - } -} - -func TestSliceOfStruct(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "value": []map[string]interface{}{ - {"vstring": "one"}, - {"vstring": "two"}, - }, - } - - var result SliceOfStruct - err := Decode(input, &result) - if err != nil { - t.Fatalf("got unexpected error: %s", err) - } - - if len(result.Value) != 2 { - t.Fatalf("expected two values, got %d", len(result.Value)) - } - - if result.Value[0].Vstring != "one" { - t.Errorf("first value should be 'one', got: %s", result.Value[0].Vstring) - } - - if result.Value[1].Vstring != "two" { - t.Errorf("second value should be 'two', got: %s", result.Value[1].Vstring) - } -} - -func TestInvalidType(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": 42, - } - - var result Basic - err := Decode(input, &result) - if err == nil { - t.Fatal("error should exist") - } - - derr, ok := err.(*Error) - if !ok { - t.Fatalf("error should be kind of Error, instead: %#v", err) - } - - if derr.Errors[0] != "'Vstring' expected type 'string', got unconvertible type 'int'" { - t.Errorf("got unexpected error: %s", err) - } -} - -func TestMetadata(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vfoo": "foo", - "vbar": map[string]interface{}{ - "vstring": "foo", - "Vuint": 42, - "foo": "bar", - }, - "bar": "nil", - } - - var md Metadata - var result Nested - config := &DecoderConfig{ - Metadata: &md, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - t.Fatalf("err: %s", err) - } - - err = decoder.Decode(input) - if err != nil { - t.Fatalf("err: %s", err.Error()) - } - - expectedKeys := []string{"Vfoo", "Vbar.Vstring", "Vbar.Vuint", "Vbar"} - if !reflect.DeepEqual(md.Keys, expectedKeys) { - t.Fatalf("bad keys: %#v", md.Keys) - } - - expectedUnused := []string{"Vbar.foo", "bar"} - if !reflect.DeepEqual(md.Unused, expectedUnused) { - t.Fatalf("bad unused: %#v", md.Unused) - } -} - -func TestMetadata_Embedded(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "vstring": "foo", - "vunique": "bar", - } - - var md Metadata - var result EmbeddedSquash - config := &DecoderConfig{ - Metadata: &md, - Result: &result, - } - - decoder, err := NewDecoder(config) - if err != nil { - t.Fatalf("err: %s", err) - } - - err = decoder.Decode(input) - if err != nil { - t.Fatalf("err: %s", err.Error()) - } - - expectedKeys := []string{"Vstring", "Vunique"} - - sort.Strings(md.Keys) - if !reflect.DeepEqual(md.Keys, expectedKeys) { - t.Fatalf("bad keys: %#v", md.Keys) - } - - expectedUnused := []string{} - if !reflect.DeepEqual(md.Unused, expectedUnused) { - t.Fatalf("bad unused: %#v", md.Unused) - } -} - -func TestNonPtrValue(t *testing.T) { - t.Parallel() - - err := Decode(map[string]interface{}{}, Basic{}) - if err == nil { - t.Fatal("error should exist") - } - - if err.Error() != "result must be a pointer" { - t.Errorf("got unexpected error: %s", err) - } -} - -func TestTagged(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "foo": "bar", - "bar": "value", - } - - var result Tagged - err := Decode(input, &result) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - if result.Value != "bar" { - t.Errorf("value should be 'bar', got: %#v", result.Value) - } - - if result.Extra != "value" { - t.Errorf("extra should be 'value', got: %#v", result.Extra) - } -} - -func TestWeakDecode(t *testing.T) { - t.Parallel() - - input := map[string]interface{}{ - "foo": "4", - "bar": "value", - } - - var result struct { - Foo int - Bar string - } - - if err := WeakDecode(input, &result); err != nil { - t.Fatalf("err: %s", err) - } - if result.Foo != 4 { - t.Fatalf("bad: %#v", result) - } - if result.Bar != "value" { - t.Fatalf("bad: %#v", result) - } -} - -func testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice) { - var result Slice - err := Decode(input, &result) - if err != nil { - t.Fatalf("got error: %s", err) - } - - if result.Vfoo != expected.Vfoo { - t.Errorf("Vfoo expected '%s', got '%s'", expected.Vfoo, result.Vfoo) - } - - if result.Vbar == nil { - t.Fatalf("Vbar a slice, got '%#v'", result.Vbar) - } - - if len(result.Vbar) != len(expected.Vbar) { - t.Errorf("Vbar length should be %d, got %d", len(expected.Vbar), len(result.Vbar)) - } - - for i, v := range result.Vbar { - if v != expected.Vbar[i] { - t.Errorf( - "Vbar[%d] should be '%#v', got '%#v'", - i, expected.Vbar[i], v) - } - } -} diff --git a/Godeps/_workspace/src/github.com/racker/perigee/.gitignore b/Godeps/_workspace/src/github.com/racker/perigee/.gitignore deleted file mode 100644 index 49ca32aa20..0000000000 --- a/Godeps/_workspace/src/github.com/racker/perigee/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin/* -pkg/* diff --git a/Godeps/_workspace/src/github.com/racker/perigee/README.md b/Godeps/_workspace/src/github.com/racker/perigee/README.md deleted file mode 100644 index 81cbf4a95f..0000000000 --- a/Godeps/_workspace/src/github.com/racker/perigee/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# perigee - -Perigee provides a REST client that, while it should be generic enough to use with most any RESTful API, is nonetheless optimized to the needs of the OpenStack APIs. -Perigee grew out of the need to refactor out common API access code from the [gorax](http://github.com/racker/gorax) project. - -Several things influenced the name of the project. -Numerous elements of the OpenStack ecosystem are named after astronomical artifacts. -Additionally, perigee occurs when two orbiting bodies are closest to each other. -Perigee seemed appropriate for something aiming to bring OpenStack and other RESTful services closer to the end-user. - -**This library is still in the very early stages of development. Unless you want to contribute, it probably isn't what you want** - -## Installation and Testing - -To install: - -```bash -go get github.com/racker/perigee -``` - -To run unit tests: - -```bash -go test github.com/racker/perigee -``` - -## Contributing - -The following guidelines are preliminary, as this project is just starting out. -However, this should serve as a working first-draft. - -### Branching - -The master branch must always be a valid build. -The `go get` command will not work otherwise. -Therefore, development must occur on a different branch. - -When creating a feature branch, do so off the master branch: - -```bash -git checkout master -git pull -git checkout -b featureBranch -git checkout -b featureBranch-wip # optional -``` - -Perform all your editing and testing in the WIP-branch. -Feel free to make as many commits as you see fit. -You may even open "WIP" pull requests from your feature branch to seek feedback. -WIP pull requests will **never** be merged, however. - -To get code merged, you'll need to "squash" your changes into one or more clean commits in the feature branch. -These steps should be followed: - -```bash -git checkout featureBranch -git merge --squash featureBranch-wip -git commit -a -git push origin featureBranch -``` - -You may now open a nice, clean, self-contained pull request from featureBranch to master. - -The `git commit -a` command above will open a text editor so that -you may provide a comprehensive description of the changes. - -In general, when submitting a pull request against master, -be sure to answer the following questions: - -- What is the problem? -- Why is it a problem? -- What is your solution? -- How does your solution work? (Recommended for non-trivial changes.) -- Why should we use your solution over someone elses? (Recommended especially if multiple solutions being discussed.) - -Remember that monster-sized pull requests are a bear to code-review, -so having helpful commit logs are an absolute must to review changes as quickly as possible. - -Finally, (s)he who breaks master is ultimately responsible for fixing master. - -### Source Representation - -The Go community firmly believes in a consistent representation for all Go source code. -We do too. -Make sure all source code is passed through "go fmt" *before* you create your pull request. - -Please note, however, that we fully acknowledge and recognize that we no longer rely upon punch-cards for representing source files. -Therefore, no 80-column limit exists. -However, if a line exceeds 132 columns, you may want to consider splitting the line. - -### Unit and Integration Tests - -Pull requests that include non-trivial code changes without accompanying unit tests will be flatly rejected. -While we have no way of enforcing this practice, -you can ensure your code is thoroughly tested by always [writing tests first by intention.](http://en.wikipedia.org/wiki/Test-driven_development) - -When creating a pull request, if even one test fails, the PR will be rejected. -Make sure all unit tests pass. -Make sure all integration tests pass. - -### Documentation - -Private functions and methods which are obvious to anyone unfamiliar with gorax needn't be accompanied by documentation. -However, this is a code-smell; if submitting a PR, expect to justify your decision. - -Public functions, regardless of how obvious, **must** have accompanying godoc-style documentation. -This is not to suggest you should provide a tome for each function, however. -Sometimes a link to more information is more appropriate, provided the link is stable, reliable, and pertinent. - -Changing documentation often results in bizarre diffs in pull requests, due to text often spanning multiple lines. -To work around this, put [one logical thought or sentence on a single line.](http://rhodesmill.org/brandon/2012/one-sentence-per-line/) -While this looks weird in a plain-text editor, -remember that both godoc and HTML viewers will reflow text. -The source code and its comments should be easy to edit with minimal diff pollution. -Let software dedicated to presenting the documentation to human readers deal with its presentation. - -## Examples - -t.b.d. - diff --git a/Godeps/_workspace/src/github.com/racker/perigee/api.go b/Godeps/_workspace/src/github.com/racker/perigee/api.go deleted file mode 100644 index 0fcbadbee5..0000000000 --- a/Godeps/_workspace/src/github.com/racker/perigee/api.go +++ /dev/null @@ -1,269 +0,0 @@ -// vim: ts=8 sw=8 noet ai - -package perigee - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "strings" -) - -// The UnexpectedResponseCodeError structure represents a mismatch in understanding between server and client in terms of response codes. -// Most often, this is due to an actual error condition (e.g., getting a 404 for a resource when you expect a 200). -// However, it needn't always be the case (e.g., getting a 204 (No Content) response back when a 200 is expected). -type UnexpectedResponseCodeError struct { - Url string - Expected []int - Actual int - Body []byte -} - -func (err *UnexpectedResponseCodeError) Error() string { - return fmt.Sprintf("Expected HTTP response code %d when accessing URL(%s); got %d instead with the following body:\n%s", err.Expected, err.Url, err.Actual, string(err.Body)) -} - -// Request issues an HTTP request, marshaling parameters, and unmarshaling results, as configured in the provided Options parameter. -// The Response structure returned, if any, will include accumulated results recovered from the HTTP server. -// See the Response structure for more details. -func Request(method string, url string, opts Options) (*Response, error) { - var body io.Reader - var response Response - - client := opts.CustomClient - if client == nil { - client = new(http.Client) - } - - contentType := opts.ContentType - - body = nil - if opts.ReqBody != nil { - if contentType == "" { - contentType = "application/json" - } - - if contentType == "application/json" { - bodyText, err := json.Marshal(opts.ReqBody) - if err != nil { - return nil, err - } - body = strings.NewReader(string(bodyText)) - if opts.DumpReqJson { - log.Printf("Making request:\n%#v\n", string(bodyText)) - } - } else { - // assume opts.ReqBody implements the correct interface - body = opts.ReqBody.(io.Reader) - } - } - - req, err := http.NewRequest(method, url, body) - if err != nil { - return nil, err - } - - if contentType != "" { - req.Header.Add("Content-Type", contentType) - } - - if opts.ContentLength > 0 { - req.ContentLength = opts.ContentLength - req.Header.Add("Content-Length", string(opts.ContentLength)) - } - - if opts.MoreHeaders != nil { - for k, v := range opts.MoreHeaders { - req.Header.Add(k, v) - } - } - - if accept := req.Header.Get("Accept"); accept == "" { - accept = opts.Accept - if accept == "" { - accept = "application/json" - } - req.Header.Add("Accept", accept) - } - - if opts.SetHeaders != nil { - err = opts.SetHeaders(req) - if err != nil { - return &response, err - } - } - - httpResponse, err := client.Do(req) - if httpResponse != nil { - response.HttpResponse = *httpResponse - response.StatusCode = httpResponse.StatusCode - } - - if err != nil { - return &response, err - } - // This if-statement is legacy code, preserved for backward compatibility. - if opts.StatusCode != nil { - *opts.StatusCode = httpResponse.StatusCode - } - - acceptableResponseCodes := opts.OkCodes - if len(acceptableResponseCodes) != 0 { - if not_in(httpResponse.StatusCode, acceptableResponseCodes) { - b, _ := ioutil.ReadAll(httpResponse.Body) - httpResponse.Body.Close() - return &response, &UnexpectedResponseCodeError{ - Url: url, - Expected: acceptableResponseCodes, - Actual: httpResponse.StatusCode, - Body: b, - } - } - } - if opts.Results != nil { - defer httpResponse.Body.Close() - jsonResult, err := ioutil.ReadAll(httpResponse.Body) - response.JsonResult = jsonResult - if err != nil { - return &response, err - } - - err = json.Unmarshal(jsonResult, opts.Results) - // This if-statement is legacy code, preserved for backward compatibility. - if opts.ResponseJson != nil { - *opts.ResponseJson = jsonResult - } - } - return &response, err -} - -// not_in returns false if, and only if, the provided needle is _not_ -// in the given set of integers. -func not_in(needle int, haystack []int) bool { - for _, straw := range haystack { - if needle == straw { - return false - } - } - return true -} - -// Post makes a POST request against a server using the provided HTTP client. -// The url must be a fully-formed URL string. -// DEPRECATED. Use Request() instead. -func Post(url string, opts Options) error { - r, err := Request("POST", url, opts) - if opts.Response != nil { - *opts.Response = r - } - return err -} - -// Get makes a GET request against a server using the provided HTTP client. -// The url must be a fully-formed URL string. -// DEPRECATED. Use Request() instead. -func Get(url string, opts Options) error { - r, err := Request("GET", url, opts) - if opts.Response != nil { - *opts.Response = r - } - return err -} - -// Delete makes a DELETE request against a server using the provided HTTP client. -// The url must be a fully-formed URL string. -// DEPRECATED. Use Request() instead. -func Delete(url string, opts Options) error { - r, err := Request("DELETE", url, opts) - if opts.Response != nil { - *opts.Response = r - } - return err -} - -// Put makes a PUT request against a server using the provided HTTP client. -// The url must be a fully-formed URL string. -// DEPRECATED. Use Request() instead. -func Put(url string, opts Options) error { - r, err := Request("PUT", url, opts) - if opts.Response != nil { - *opts.Response = r - } - return err -} - -// Options describes a set of optional parameters to the various request calls. -// -// The custom client can be used for a variety of purposes beyond selecting encrypted versus unencrypted channels. -// Transports can be defined to provide augmented logging, header manipulation, et. al. -// -// If the ReqBody field is provided, it will be embedded as a JSON object. -// Otherwise, provide nil. -// -// If JSON output is to be expected from the response, -// provide either a pointer to the container structure in Results, -// or a pointer to a nil-initialized pointer variable. -// The latter method will cause the unmarshaller to allocate the container type for you. -// If no response is expected, provide a nil Results value. -// -// The MoreHeaders map, if non-nil or empty, provides a set of headers to add to those -// already present in the request. At present, only Accepted and Content-Type are set -// by default. -// -// OkCodes provides a set of acceptable, positive responses. -// -// If provided, StatusCode specifies a pointer to an integer, which will receive the -// returned HTTP status code, successful or not. DEPRECATED; use the Response.StatusCode field instead for new software. -// -// ResponseJson, if specified, provides a means for returning the raw JSON. This is -// most useful for diagnostics. DEPRECATED; use the Response.JsonResult field instead for new software. -// -// DumpReqJson, if set to true, will cause the request to appear to stdout for debugging purposes. -// This attribute may be removed at any time in the future; DO NOT use this attribute in production software. -// -// Response, if set, provides a way to communicate the complete set of HTTP response, raw JSON, status code, and -// other useful attributes back to the caller. Note that the Request() method returns a Response structure as part -// of its public interface; you don't need to set the Response field here to use this structure. The Response field -// exists primarily for legacy or deprecated functions. -// -// SetHeaders allows the caller to provide code to set any custom headers programmatically. Typically, this -// facility can invoke, e.g., SetBasicAuth() on the request to easily set up authentication. -// Any error generated will terminate the request and will propegate back to the caller. -type Options struct { - CustomClient *http.Client - ReqBody interface{} - Results interface{} - MoreHeaders map[string]string - OkCodes []int - StatusCode *int `DEPRECATED` - DumpReqJson bool `UNSUPPORTED` - ResponseJson *[]byte `DEPRECATED` - Response **Response - ContentType string `json:"Content-Type,omitempty"` - ContentLength int64 `json:"Content-Length,omitempty"` - Accept string `json:"Accept,omitempty"` - SetHeaders func(r *http.Request) error -} - -// Response contains return values from the various request calls. -// -// HttpResponse will return the http response from the request call. -// Note: HttpResponse.Body is always closed and will not be available from this return value. -// -// StatusCode specifies the returned HTTP status code, successful or not. -// -// If Results is specified in the Options: -// - JsonResult will contain the raw return from the request call -// This is most useful for diagnostics. -// - Result will contain the unmarshalled json either in the Result passed in -// or the unmarshaller will allocate the container type for you. - -type Response struct { - HttpResponse http.Response - JsonResult []byte - Results interface{} - StatusCode int -} diff --git a/Godeps/_workspace/src/github.com/racker/perigee/api_test.go b/Godeps/_workspace/src/github.com/racker/perigee/api_test.go deleted file mode 100644 index da943b247b..0000000000 --- a/Godeps/_workspace/src/github.com/racker/perigee/api_test.go +++ /dev/null @@ -1,226 +0,0 @@ -package perigee - -import ( - "bytes" - "fmt" - "net/http" - "net/http/httptest" - "strings" - "testing" -) - -func TestNormal(t *testing.T) { - handler := http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("testing")) - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - response, err := Request("GET", ts.URL, Options{}) - if err != nil { - t.Fatalf("should not have error: %s", err) - } - if response.StatusCode != 200 { - t.Fatalf("response code %d is not 200", response.StatusCode) - } -} - -func TestOKCodes(t *testing.T) { - expectCode := 201 - handler := http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(expectCode) - w.Write([]byte("testing")) - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - options := Options{ - OkCodes: []int{expectCode}, - } - results, err := Request("GET", ts.URL, options) - if err != nil { - t.Fatalf("should not have error: %s", err) - } - if results.StatusCode != expectCode { - t.Fatalf("response code %d is not %d", results.StatusCode, expectCode) - } -} - -func TestLocation(t *testing.T) { - newLocation := "http://www.example.com" - handler := http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Location", newLocation) - w.Write([]byte("testing")) - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - response, err := Request("GET", ts.URL, Options{}) - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - location, err := response.HttpResponse.Location() - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - if location.String() != newLocation { - t.Fatalf("location returned \"%s\" is not \"%s\"", location.String(), newLocation) - } -} - -func TestHeaders(t *testing.T) { - newLocation := "http://www.example.com" - handler := http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Location", newLocation) - w.Write([]byte("testing")) - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - response, err := Request("GET", ts.URL, Options{}) - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - location := response.HttpResponse.Header.Get("Location") - if location == "" { - t.Fatalf("Location should not empty") - } - - if location != newLocation { - t.Fatalf("location returned \"%s\" is not \"%s\"", location, newLocation) - } -} - -func TestCustomHeaders(t *testing.T) { - var contentType, accept, contentLength string - - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - m := map[string][]string(r.Header) - contentType = m["Content-Type"][0] - accept = m["Accept"][0] - contentLength = m["Content-Length"][0] - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - _, err := Request("GET", ts.URL, Options{ - ContentLength: 5, - ContentType: "x-application/vb", - Accept: "x-application/c", - ReqBody: strings.NewReader("Hello"), - }) - if err != nil { - t.Fatalf(err.Error()) - } - - if contentType != "x-application/vb" { - t.Fatalf("I expected x-application/vb; got ", contentType) - } - - if contentLength != "5" { - t.Fatalf("I expected 5 byte content length; got ", contentLength) - } - - if accept != "x-application/c" { - t.Fatalf("I expected x-application/c; got ", accept) - } -} - -func TestJson(t *testing.T) { - newLocation := "http://www.example.com" - jsonBytes := []byte(`{"foo": {"bar": "baz"}}`) - handler := http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Location", newLocation) - w.Write(jsonBytes) - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - type Data struct { - Foo struct { - Bar string `json:"bar"` - } `json:"foo"` - } - var data Data - - response, err := Request("GET", ts.URL, Options{Results: &data}) - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - if bytes.Compare(jsonBytes, response.JsonResult) != 0 { - t.Fatalf("json returned \"%s\" is not \"%s\"", response.JsonResult, jsonBytes) - } - - if data.Foo.Bar != "baz" { - t.Fatalf("Results returned %v", data) - } -} - -func TestSetHeaders(t *testing.T) { - var wasCalled bool - handler := http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("Hi")) - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - _, err := Request("GET", ts.URL, Options{ - SetHeaders: func(r *http.Request) error { - wasCalled = true - return nil - }, - }) - - if err != nil { - t.Fatal(err) - } - - if !wasCalled { - t.Fatal("I expected header setter callback to be called, but it wasn't") - } - - myError := fmt.Errorf("boo") - - _, err = Request("GET", ts.URL, Options{ - SetHeaders: func(r *http.Request) error { - return myError - }, - }) - - if err != myError { - t.Fatal("I expected errors to propegate back to the caller.") - } -} - -func TestBodilessMethodsAreSentWithoutContentHeaders(t *testing.T) { - var h map[string][]string - - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - h = r.Header - }) - ts := httptest.NewServer(handler) - defer ts.Close() - - _, err := Request("GET", ts.URL, Options{}) - if err != nil { - t.Fatalf(err.Error()) - } - - if len(h["Content-Type"]) != 0 { - t.Fatalf("I expected nothing for Content-Type but got ", h["Content-Type"]) - } - - if len(h["Content-Length"]) != 0 { - t.Fatalf("I expected nothing for Content-Length but got ", h["Content-Length"]) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/.travis.yml b/Godeps/_workspace/src/github.com/rackspace/gophercloud/.travis.yml deleted file mode 100644 index cf4f8cafcc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -install: - - go get -v -tags 'fixtures acceptance' ./... -go: - - 1.1 - - 1.2 - - tip -script: script/cibuild -after_success: - - go get code.google.com/p/go.tools/cmd/cover - - go get github.com/axw/gocov/gocov - - go get github.com/mattn/goveralls - - export PATH=$PATH:$HOME/gopath/bin/ - - goveralls 2k7PTU3xa474Hymwgdj6XjqenNfGTNkO8 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md deleted file mode 100644 index 93b798e5a2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md +++ /dev/null @@ -1,275 +0,0 @@ -# Contributing to gophercloud - -- [Getting started](#getting-started) -- [Tests](#tests) -- [Style guide](#basic-style-guide) -- [5 ways to get involved](#5-ways-to-get-involved) - -## Setting up your git workspace - -As a contributor you will need to setup your workspace in a slightly different -way than just downloading it. Here are the basic installation instructions: - -1. Configure your `$GOPATH` and run `go get` as described in the main -[README](/README.md#how-to-install). - -2. Move into the directory that houses your local repository: - - ```bash - cd ${GOPATH}/src/github.com/rackspace/gophercloud - ``` - -3. Fork the `rackspace/gophercloud` repository and update your remote refs. You -will need to rename the `origin` remote branch to `upstream`, and add your -fork as `origin` instead: - - ```bash - git remote rename origin upstream - git remote add origin git@github.com//gophercloud - ``` - -4. Checkout the latest development branch ([click here](/branches) to see all -the branches): - - ```bash - git checkout release/v1.0.1 - ``` - -5. If you're working on something (discussed more in detail below), you will -need to checkout a new feature branch: - - ```bash - git checkout -b my-new-feature - ``` - -Another thing to bear in mind is that you will need to add a few extra -environment variables for acceptance tests - this is documented in our -[acceptance tests readme](/acceptance). - -## Tests - -When working on a new or existing feature, testing will be the backbone of your -work since it helps uncover and prevent regressions in the codebase. There are -two types of test we use in gophercloud: unit tests and acceptance tests, which -are both described below. - -### Unit tests - -Unit tests are the fine-grained tests that establish and ensure the behaviour -of individual units of functionality. We usually test on an -operation-by-operation basis (an operation typically being an API action) with -the use of mocking to set up explicit expectations. Each operation will set up -its HTTP response expectation, and then test how the system responds when fed -this controlled, pre-determined input. - -To make life easier, we've introduced a bunch of test helpers to simplify the -process of testing expectations with assertions: - -```go -import ( - "testing" - - "github.com/rackspace/gophercloud/testhelper" -) - -func TestSomething(t *testing.T) { - result, err := Operation() - - testhelper.AssertEquals(t, "foo", result.Bar) - testhelper.AssertNoErr(t, err) -} - -func TestSomethingElse(t *testing.T) { - testhelper.CheckEquals(t, "expected", "actual") -} -``` - -`AssertEquals` and `AssertNoErr` will throw a fatal error if a value does not -match an expected value or if an error has been declared, respectively. You can -also use `CheckEquals` and `CheckNoErr` for the same purpose; the only difference -being that `t.Errorf` is raised rather than `t.Fatalf`. - -Here is a truncated example of mocked HTTP responses: - -```go -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestGet(t *testing.T) { - // Setup the HTTP request multiplexer and server - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - // Test we're using the correct HTTP method - th.TestMethod(t, r, "GET") - - // Test we're setting the auth token - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - // Set the appropriate headers for our mocked response - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - // Set the HTTP body - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "name": "private-network", - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) - - // Call our API operation - network, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - - // Assert no errors and equality - th.AssertNoErr(t, err) - th.AssertEquals(t, n.Status, "ACTIVE") -} -``` - -### Acceptance tests - -As we've already mentioned, unit tests have a very narrow and confined focus - -they test small units of behaviour. Acceptance tests on the other hand have a -far larger scope: they are fully functional tests that test the entire API of a -service in one fell swoop. They don't care about unit isolation or mocking -expectations, they instead do a full run-through and consequently test how the -entire system _integrates_ together. When an API satisfies expectations, it -proves by default that the requirements for a contract have been met. - -Please be aware that acceptance tests will hit a live API - and may incur -service charges from your provider. Although most tests handle their own -teardown procedures, it is always worth manually checking that resources are -deleted after the test suite finishes. - -### Running tests - -To run all tests: - -```bash -go test ./... -``` - -To run all tests with verbose output: - -```bash -go test -v ./... -``` - -To run tests that match certain [build tags](): - -```bash -go test -tags "foo bar" ./... -``` - -To run tests for a particular sub-package: - -```bash -cd ./path/to/package && go test . -``` - -## Basic style guide - -We follow the standard formatting recommendations and language idioms set out -in the [Effective Go](https://golang.org/doc/effective_go.html) guide. It's -definitely worth reading - but the relevant sections are -[formatting](https://golang.org/doc/effective_go.html#formatting) -and [names](https://golang.org/doc/effective_go.html#names). - -## 5 ways to get involved - -There are five main ways you can get involved in our open-source project, and -each is described briefly below. Once you've made up your mind and decided on -your fix, you will need to follow the same basic steps that all submissions are -required to adhere to: - -1. [fork](https://help.github.com/articles/fork-a-repo/) the `rackspace/gophercloud` repository -2. checkout a [new branch](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches) -3. submit your branch as a [pull request](https://help.github.com/articles/creating-a-pull-request/) - -### 1. Providing feedback - -On of the easiest ways to get readily involved in our project is to let us know -about your experiences using our SDK. Feedback like this is incredibly useful -to us, because it allows us to refine and change features based on what our -users want and expect of us. There are a bunch of ways to get in contact! You -can [ping us](mailto:sdk-support@rackspace.com) via e-mail, talk to us on irc -(#rackspace-dev on freenode), [tweet us](https://twitter.com/rackspace), or -submit an issue on our [bug tracker](/issues). Things you might like to tell us -are: - -* how easy was it to start using our SDK? -* did it meet your expectations? If not, why not? -* did our documentation help or hinder you? -* what could we improve in general? - -### 2. Fixing bugs - -If you want to start fixing open bugs, we'd really appreciate that! Bug fixing -is central to any project. The best way to get started is by heading to our -[bug tracker](https://github.com/rackspace/gophercloud/issues) and finding open -bugs that you think nobody is working on. It might be useful to comment on the -thread to see the current state of the issue and if anybody has made any -breakthroughs on it so far. - -### 3. Improving documentation - -We have three forms of documentation: - -* short README documents that briefly introduce a topic -* reference documentation on [godoc.org](http://godoc.org) that is automatically -generated from source code comments -* user documentation on our [homepage](http://gophercloud.io) that includes -getting started guides, installation guides and code samples - -If you feel that a certain section could be improved - whether it's to clarify -ambiguity, correct a technical mistake, or to fix a grammatical error - please -feel entitled to do so! We welcome doc pull requests with the same childlike -enthusiasm as any other contribution! - -### 4. Optimizing existing features - -If you would like to improve or optimize an existing feature, please be aware -that we adhere to [semantic versioning](http://semver.org) - which means that -we cannot introduce breaking changes to the API without a major version change -(v1.x -> v2.x). Making that leap is a big step, so we encourage contributors to -refactor rather than rewrite. Running tests will prevent regression and avoid -the possibility of breaking somebody's current implementation. - -Another tip is to keep the focus of your work as small as possible - try not to -introduce a change that affects lots and lots of files because it introduces -added risk and increases the cognitive load on the reviewers checking your -work. Change-sets which are easily understood and will not negatively impact -users are more likely to be integrated quickly. - -Lastly, if you're seeking to optimize a particular operation, you should try to -demonstrate a negative performance impact - perhaps using go's inbuilt -[benchmark capabilities](http://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go). - -### 5. Working on a new feature - -If you've found something we've left out, definitely feel free to start work on -introducing that feature. It's always useful to open an issue or submit a pull -request early on to indicate your intent to a core contributor - this enables -quick/early feedback and can help steer you in the right direction by avoiding -known issues. It might also help you avoid losing time implementing something -that might not ever work. One tip is to prefix your Pull Request issue title -with [wip] - then people know it's a work in progress. - -You must ensure that all of your work is well tested - both in terms of unit -and acceptance tests. Untested code will not be merged because it introduces -too much of a risk to end-users. - -Happy hacking! diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/Godeps/Godeps.json b/Godeps/_workspace/src/github.com/rackspace/gophercloud/Godeps/Godeps.json deleted file mode 100644 index dbe26bbf76..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/Godeps/Godeps.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ImportPath": "github.com/rackspace/gophercloud", - "GoVersion": "go1.3.3", - "Deps": [] -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/Godeps/Readme b/Godeps/_workspace/src/github.com/rackspace/gophercloud/Godeps/Readme deleted file mode 100644 index 4cdaa53d56..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/Godeps/Readme +++ /dev/null @@ -1,5 +0,0 @@ -This directory tree is generated automatically by godep. - -Please do not edit. - -See https://github.com/tools/godep for more information. diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/README.md b/Godeps/_workspace/src/github.com/rackspace/gophercloud/README.md deleted file mode 100644 index 9f7552b0d2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/README.md +++ /dev/null @@ -1,161 +0,0 @@ -# Gophercloud: the OpenStack SDK for Go -[![Build Status](https://travis-ci.org/rackspace/gophercloud.svg?branch=master)](https://travis-ci.org/rackspace/gophercloud) - -Gophercloud is a flexible SDK that allows you to consume and work with OpenStack -clouds in a simple and idiomatic way using golang. Many services are supported, -including Compute, Block Storage, Object Storage, Networking, and Identity. -Each service API is backed with getting started guides, code samples, reference -documentation, unit tests and acceptance tests. - -## Useful links - -* [Gophercloud homepage](http://gophercloud.io) -* [Reference documentation](http://godoc.org/github.com/rackspace/gophercloud) -* [Getting started guides](http://gophercloud.io/docs) -* [Effective Go](https://golang.org/doc/effective_go.html) - -## How to install - -Before installing, you need to ensure that your [GOPATH environment variable](https://golang.org/doc/code.html#GOPATH) -is pointing to an appropriate directory where you want to install Gophercloud: - -```bash -mkdir $HOME/go -export GOPATH=$HOME/go -``` - -To protect yourself against changes in your dependencies, we highly recommend choosing a -[dependency management solution](https://code.google.com/p/go-wiki/wiki/PackageManagementTools) for -your projects, such as [godep](https://github.com/tools/godep). Once this is set up, you can install -Gophercloud as a dependency like so: - -```bash -go get github.com/rackspace/gophercloud - -# Edit your code to import relevant packages from "github.com/rackspace/gophercloud" - -godep save ./... -``` - -This will install all the source files you need into a `Godeps/_workspace` directory, which is -referenceable from your own source files when you use the `godep go` command. - -## Getting started - -### Credentials - -Because you'll be hitting an API, you will need to retrieve your OpenStack -credentials and either store them as environment variables or in your local Go -files. The first method is recommended because it decouples credential -information from source code, allowing you to push the latter to your version -control system without any security risk. - -You will need to retrieve the following: - -* username -* password -* tenant name or tenant ID -* a valid Keystone identity URL - -For users that have the OpenStack dashboard installed, there's a shortcut. If -you visit the `project/access_and_security` path in Horizon and click on the -"Download OpenStack RC File" button at the top right hand corner, you will -download a bash file that exports all of your access details to environment -variables. To execute the file, run `source admin-openrc.sh` and you will be -prompted for your password. - -### Authentication - -Once you have access to your credentials, you can begin plugging them into -Gophercloud. The next step is authentication, and this is handled by a base -"Provider" struct. To get one, you can either pass in your credentials -explicitly, or tell Gophercloud to use environment variables: - -```go -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - "github.com/rackspace/gophercloud/openstack/utils" -) - -// Option 1: Pass in the values yourself -opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://my-openstack.com:5000/v2.0", - Username: "{username}", - Password: "{password}", - TenantID: "{tenant_id}", -} - -// Option 2: Use a utility function to retrieve all your environment variables -opts, err := openstack.AuthOptionsFromEnv() -``` - -Once you have the `opts` variable, you can pass it in and get back a -`ProviderClient` struct: - -```go -provider, err := openstack.AuthenticatedClient(opts) -``` - -The `ProviderClient` is the top-level client that all of your OpenStack services -derive from. The provider contains all of the authentication details that allow -your Go code to access the API - such as the base URL and token ID. - -### Provision a server - -Once we have a base Provider, we inject it as a dependency into each OpenStack -service. In order to work with the Compute API, we need a Compute service -client; which can be created like so: - -```go -client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), -}) -``` - -We then use this `client` for any Compute API operation we want. In our case, -we want to provision a new server - so we invoke the `Create` method and pass -in the flavor ID (hardware specification) and image ID (operating system) we're -interested in: - -```go -import "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - -server, err := servers.Create(client, servers.CreateOpts{ - Name: "My new server!", - FlavorRef: "flavor_id", - ImageRef: "image_id", -}).Extract() -``` - -If you are unsure about what images and flavors are, you can read our [Compute -Getting Started guide](http://gophercloud.io/docs/compute). The above code -sample creates a new server with the parameters, and embodies the new resource -in the `server` variable (a -[`servers.Server`](http://godoc.org/github.com/rackspace/gophercloud) struct). - -### Next steps - -Cool! You've handled authentication, got your `ProviderClient` and provisioned -a new server. You're now ready to use more OpenStack services. - -* [Getting started with Compute](http://gophercloud.io/docs/compute) -* [Getting started with Object Storage](http://gophercloud.io/docs/object-storage) -* [Getting started with Networking](http://gophercloud.io/docs/networking) -* [Getting started with Block Storage](http://gophercloud.io/docs/block-storage) -* [Getting started with Identity](http://gophercloud.io/docs/identity) - -## Contributing - -Engaging the community and lowering barriers for contributors is something we -care a lot about. For this reason, we've taken the time to write a [contributing -guide](./CONTRIBUTING.md) for folks interested in getting involved in our project. -If you're not sure how you can get involved, feel free to submit an issue or -[e-mail us](mailto:sdk-support@rackspace.com) privately. You don't need to be a -Go expert - all members of the community are welcome! - -## Help and feedback - -If you're struggling with something or have spotted a potential bug, feel free -to submit an issue to our [bug tracker](/issues) or e-mail us directly at -[sdk-support@rackspace.com](mailto:sdk-support@rackspace.com). diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/README.md b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/README.md deleted file mode 100644 index 3199837c20..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Gophercloud Acceptance tests - -The purpose of these acceptance tests is to validate that SDK features meet -the requirements of a contract - to consumers, other parts of the library, and -to a remote API. - -> **Note:** Because every test will be run against a real API endpoint, you -> may incur bandwidth and service charges for all the resource usage. These -> tests *should* remove their remote products automatically. However, there may -> be certain cases where this does not happen; always double-check to make sure -> you have no stragglers left behind. - -### Step 1. Set environment variables - -A lot of tests rely on environment variables for configuration - so you will need -to set them before running the suite. If you're testing against pure OpenStack APIs, -you can download a file that contains all of these variables for you: just visit -the `project/access_and_security` page in your control panel and click the "Download -OpenStack RC File" button at the top right. For all other providers, you will need -to set them manually. - -#### Authentication - -|Name|Description| -|---|---| -|`OS_USERNAME`|Your API username| -|`OS_PASSWORD`|Your API password| -|`OS_AUTH_URL`|The identity URL you need to authenticate| -|`OS_TENANT_NAME`|Your API tenant name| -|`OS_TENANT_ID`|Your API tenant ID| -|`RS_USERNAME`|Your Rackspace username| -|`RS_API_KEY`|Your Rackspace API key| - -#### General - -|Name|Description| -|---|---| -|`OS_REGION_NAME`|The region you want your resources to reside in| -|`RS_REGION`|Rackspace region you want your resource to reside in| - -#### Compute - -|Name|Description| -|---|---| -|`OS_IMAGE_ID`|The ID of the image your want your server to be based on| -|`OS_FLAVOR_ID`|The ID of the flavor you want your server to be based on| -|`OS_FLAVOR_ID_RESIZE`|The ID of the flavor you want your server to be resized to| -|`RS_IMAGE_ID`|The ID of the image you want servers to be created with| -|`RS_FLAVOR_ID`|The ID of the flavor you want your server to be created with| - -### 2. Run the test suite - -From the root directory, run: - -``` -./script/acceptancetest -``` diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/snapshots_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/snapshots_test.go deleted file mode 100644 index 7741aa9841..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/snapshots_test.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots" - "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestSnapshots(t *testing.T) { - - client, err := newClient(t) - th.AssertNoErr(t, err) - - v, err := volumes.Create(client, &volumes.CreateOpts{ - Name: "gophercloud-test-volume", - Size: 1, - }).Extract() - th.AssertNoErr(t, err) - - err = volumes.WaitForStatus(client, v.ID, "available", 120) - th.AssertNoErr(t, err) - - t.Logf("Created volume: %v\n", v) - - ss, err := snapshots.Create(client, &snapshots.CreateOpts{ - Name: "gophercloud-test-snapshot", - VolumeID: v.ID, - }).Extract() - th.AssertNoErr(t, err) - - err = snapshots.WaitForStatus(client, ss.ID, "available", 120) - th.AssertNoErr(t, err) - - t.Logf("Created snapshot: %+v\n", ss) - - err = snapshots.Delete(client, ss.ID).ExtractErr() - th.AssertNoErr(t, err) - - err = gophercloud.WaitFor(120, func() (bool, error) { - _, err := snapshots.Get(client, ss.ID).Extract() - if err != nil { - return true, nil - } - - return false, nil - }) - th.AssertNoErr(t, err) - - t.Log("Deleted snapshot\n") - - err = volumes.Delete(client, v.ID).ExtractErr() - th.AssertNoErr(t, err) - - err = gophercloud.WaitFor(120, func() (bool, error) { - _, err := volumes.Get(client, v.ID).Extract() - if err != nil { - return true, nil - } - - return false, nil - }) - th.AssertNoErr(t, err) - - t.Log("Deleted volume\n") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/volumes_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/volumes_test.go deleted file mode 100644 index 7760427f08..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/volumes_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// +build acceptance blockstorage - -package v1 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func newClient(t *testing.T) (*gophercloud.ServiceClient, error) { - ao, err := openstack.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - - client, err := openstack.AuthenticatedClient(ao) - th.AssertNoErr(t, err) - - return openstack.NewBlockStorageV1(client, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) -} - -func TestVolumes(t *testing.T) { - client, err := newClient(t) - th.AssertNoErr(t, err) - - cv, err := volumes.Create(client, &volumes.CreateOpts{ - Size: 1, - Name: "gophercloud-test-volume", - }).Extract() - th.AssertNoErr(t, err) - defer func() { - err = volumes.WaitForStatus(client, cv.ID, "available", 60) - th.AssertNoErr(t, err) - err = volumes.Delete(client, cv.ID).ExtractErr() - th.AssertNoErr(t, err) - }() - - _, err = volumes.Update(client, cv.ID, &volumes.UpdateOpts{ - Name: "gophercloud-updated-volume", - }).Extract() - th.AssertNoErr(t, err) - - v, err := volumes.Get(client, cv.ID).Extract() - th.AssertNoErr(t, err) - t.Logf("Got volume: %+v\n", v) - - if v.Name != "gophercloud-updated-volume" { - t.Errorf("Unable to update volume: Expected name: gophercloud-updated-volume\nActual name: %s", v.Name) - } - - err = volumes.List(client, &volumes.ListOpts{Name: "gophercloud-updated-volume"}).EachPage(func(page pagination.Page) (bool, error) { - vols, err := volumes.ExtractVolumes(page) - th.CheckEquals(t, 1, len(vols)) - return true, err - }) - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/volumetypes_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/volumetypes_test.go deleted file mode 100644 index 000bc01d57..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/blockstorage/v1/volumetypes_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "testing" - "time" - - "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestVolumeTypes(t *testing.T) { - client, err := newClient(t) - th.AssertNoErr(t, err) - - vt, err := volumetypes.Create(client, &volumetypes.CreateOpts{ - ExtraSpecs: map[string]interface{}{ - "capabilities": "gpu", - "priority": 3, - }, - Name: "gophercloud-test-volumeType", - }).Extract() - th.AssertNoErr(t, err) - defer func() { - time.Sleep(10000 * time.Millisecond) - err = volumetypes.Delete(client, vt.ID).ExtractErr() - if err != nil { - t.Error(err) - return - } - }() - t.Logf("Created volume type: %+v\n", vt) - - vt, err = volumetypes.Get(client, vt.ID).Extract() - th.AssertNoErr(t, err) - t.Logf("Got volume type: %+v\n", vt) - - err = volumetypes.List(client).EachPage(func(page pagination.Page) (bool, error) { - volTypes, err := volumetypes.ExtractVolumeTypes(page) - if len(volTypes) != 1 { - t.Errorf("Expected 1 volume type, got %d", len(volTypes)) - } - t.Logf("Listing volume types: %+v\n", volTypes) - return true, err - }) - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/client_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/client_test.go deleted file mode 100644 index 6e88819d80..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/client_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build acceptance - -package openstack - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" -) - -func TestAuthenticatedClient(t *testing.T) { - // Obtain credentials from the environment. - ao, err := openstack.AuthOptionsFromEnv() - if err != nil { - t.Fatalf("Unable to acquire credentials: %v", err) - } - - client, err := openstack.AuthenticatedClient(ao) - if err != nil { - t.Fatalf("Unable to authenticate: %v", err) - } - - if client.TokenID == "" { - t.Errorf("No token ID assigned to the client") - } - - t.Logf("Client successfully acquired a token: %v", client.TokenID) - - // Find the storage service in the service catalog. - storage, err := openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) - if err != nil { - t.Errorf("Unable to locate a storage service: %v", err) - } else { - t.Logf("Located a storage service at endpoint: [%s]", storage.Endpoint) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/bootfromvolume_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/bootfromvolume_test.go deleted file mode 100644 index add0e5fc11..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/bootfromvolume_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestBootFromVolume(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - if testing.Short() { - t.Skip("Skipping test that requires server creation in short mode.") - } - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - name := tools.RandomString("Gophercloud-", 8) - t.Logf("Creating server [%s].", name) - - bd := []bootfromvolume.BlockDevice{ - bootfromvolume.BlockDevice{ - UUID: choices.ImageID, - SourceType: bootfromvolume.Image, - VolumeSize: 10, - }, - } - - serverCreateOpts := servers.CreateOpts{ - Name: name, - FlavorRef: choices.FlavorID, - ImageRef: choices.ImageID, - } - server, err := bootfromvolume.Create(client, bootfromvolume.CreateOptsExt{ - serverCreateOpts, - bd, - }).Extract() - th.AssertNoErr(t, err) - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - t.Logf("Created server: %+v\n", server) - defer servers.Delete(client, server.ID) - t.Logf("Deleting server [%s]...", name) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/compute_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/compute_test.go deleted file mode 100644 index 33e49fea9b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/compute_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// +build acceptance common - -package v2 - -import ( - "fmt" - "os" - "strings" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" -) - -func newClient() (*gophercloud.ServiceClient, error) { - ao, err := openstack.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - - client, err := openstack.AuthenticatedClient(ao) - if err != nil { - return nil, err - } - - return openstack.NewComputeV2(client, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) -} - -func waitForStatus(client *gophercloud.ServiceClient, server *servers.Server, status string) error { - return tools.WaitFor(func() (bool, error) { - latest, err := servers.Get(client, server.ID).Extract() - if err != nil { - return false, err - } - - if latest.Status == status { - // Success! - return true, nil - } - - return false, nil - }) -} - -// ComputeChoices contains image and flavor selections for use by the acceptance tests. -type ComputeChoices struct { - // ImageID contains the ID of a valid image. - ImageID string - - // FlavorID contains the ID of a valid flavor. - FlavorID string - - // FlavorIDResize contains the ID of a different flavor available on the same OpenStack installation, that is distinct - // from FlavorID. - FlavorIDResize string -} - -// ComputeChoicesFromEnv populates a ComputeChoices struct from environment variables. -// If any required state is missing, an `error` will be returned that enumerates the missing properties. -func ComputeChoicesFromEnv() (*ComputeChoices, error) { - imageID := os.Getenv("OS_IMAGE_ID") - flavorID := os.Getenv("OS_FLAVOR_ID") - flavorIDResize := os.Getenv("OS_FLAVOR_ID_RESIZE") - - missing := make([]string, 0, 3) - if imageID == "" { - missing = append(missing, "OS_IMAGE_ID") - } - if flavorID == "" { - missing = append(missing, "OS_FLAVOR_ID") - } - if flavorIDResize == "" { - missing = append(missing, "OS_FLAVOR_ID_RESIZE") - } - - notDistinct := "" - if flavorID == flavorIDResize { - notDistinct = "OS_FLAVOR_ID and OS_FLAVOR_ID_RESIZE must be distinct." - } - - if len(missing) > 0 || notDistinct != "" { - text := "You're missing some important setup:\n" - if len(missing) > 0 { - text += " * These environment variables must be provided: " + strings.Join(missing, ", ") + "\n" - } - if notDistinct != "" { - text += " * " + notDistinct + "\n" - } - - return nil, fmt.Errorf(text) - } - - return &ComputeChoices{ImageID: imageID, FlavorID: flavorID, FlavorIDResize: flavorIDResize}, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/extension_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/extension_test.go deleted file mode 100644 index 1356ffa899..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/extension_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build acceptance compute extensionss - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListExtensions(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - err = extensions.List(client).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - exts, err := extensions.ExtractExtensions(page) - th.AssertNoErr(t, err) - - for i, ext := range exts { - t.Logf("[%02d] name=[%s]\n", i, ext.Name) - t.Logf(" alias=[%s]\n", ext.Alias) - t.Logf(" description=[%s]\n", ext.Description) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func TestGetExtension(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - ext, err := extensions.Get(client, "os-admin-actions").Extract() - th.AssertNoErr(t, err) - - t.Logf("Extension details:") - t.Logf(" name=[%s]\n", ext.Name) - t.Logf(" namespace=[%s]\n", ext.Namespace) - t.Logf(" alias=[%s]\n", ext.Alias) - t.Logf(" description=[%s]\n", ext.Description) - t.Logf(" updated=[%s]\n", ext.Updated) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/flavors_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/flavors_test.go deleted file mode 100644 index 9f51b12280..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/flavors_test.go +++ /dev/null @@ -1,57 +0,0 @@ -// +build acceptance compute flavors - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" - "github.com/rackspace/gophercloud/pagination" -) - -func TestListFlavors(t *testing.T) { - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - t.Logf("ID\tRegion\tName\tStatus\tCreated") - - pager := flavors.ListDetail(client, nil) - count, pages := 0, 0 - pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("---") - pages++ - flavors, err := flavors.ExtractFlavors(page) - if err != nil { - return false, err - } - - for _, f := range flavors { - t.Logf("%s\t%s\t%d\t%d\t%d", f.ID, f.Name, f.RAM, f.Disk, f.VCPUs) - } - - return true, nil - }) - - t.Logf("--------\n%d flavors listed on %d pages.", count, pages) -} - -func TestGetFlavor(t *testing.T) { - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - flavor, err := flavors.Get(client, choices.FlavorID).Extract() - if err != nil { - t.Fatalf("Unable to get flavor information: %v", err) - } - - t.Logf("Flavor: %#v", flavor) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/images_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/images_test.go deleted file mode 100644 index ceab22fa76..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/images_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build acceptance compute images - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/images" - "github.com/rackspace/gophercloud/pagination" -) - -func TestListImages(t *testing.T) { - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute: client: %v", err) - } - - t.Logf("ID\tRegion\tName\tStatus\tCreated") - - pager := images.ListDetail(client, nil) - count, pages := 0, 0 - pager.EachPage(func(page pagination.Page) (bool, error) { - pages++ - images, err := images.ExtractImages(page) - if err != nil { - return false, err - } - - for _, i := range images { - t.Logf("%s\t%s\t%s\t%s", i.ID, i.Name, i.Status, i.Created) - } - - return true, nil - }) - - t.Logf("--------\n%d images listed on %d pages.", count, pages) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/keypairs_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/keypairs_test.go deleted file mode 100644 index 3e12d6b3cd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/keypairs_test.go +++ /dev/null @@ -1,74 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "crypto/rand" - "crypto/rsa" - "testing" - - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" - - "code.google.com/p/go.crypto/ssh" -) - -const keyName = "gophercloud_test_key_pair" - -func TestCreateServerWithKeyPair(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - if testing.Short() { - t.Skip("Skipping test that requires server creation in short mode.") - } - - privateKey, err := rsa.GenerateKey(rand.Reader, 2048) - publicKey := privateKey.PublicKey - pub, err := ssh.NewPublicKey(&publicKey) - th.AssertNoErr(t, err) - pubBytes := ssh.MarshalAuthorizedKey(pub) - pk := string(pubBytes) - - kp, err := keypairs.Create(client, keypairs.CreateOpts{ - Name: keyName, - PublicKey: pk, - }).Extract() - th.AssertNoErr(t, err) - t.Logf("Created key pair: %s\n", kp) - - choices, err := ComputeChoicesFromEnv() - th.AssertNoErr(t, err) - - name := tools.RandomString("Gophercloud-", 8) - t.Logf("Creating server [%s] with key pair.", name) - - serverCreateOpts := servers.CreateOpts{ - Name: name, - FlavorRef: choices.FlavorID, - ImageRef: choices.ImageID, - } - - server, err := servers.Create(client, keypairs.CreateOptsExt{ - serverCreateOpts, - keyName, - }).Extract() - th.AssertNoErr(t, err) - defer servers.Delete(client, server.ID) - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatalf("Unable to wait for server: %v", err) - } - - server, err = servers.Get(client, server.ID).Extract() - t.Logf("Created server: %+v\n", server) - th.AssertNoErr(t, err) - th.AssertEquals(t, server.KeyName, keyName) - - t.Logf("Deleting key pair [%s]...", kp.Name) - err = keypairs.Delete(client, keyName).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Deleting server [%s]...", name) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/pkg.go deleted file mode 100644 index bb158c3eec..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/pkg.go +++ /dev/null @@ -1,3 +0,0 @@ -// The v2 package contains acceptance tests for the Openstack Compute V2 service. - -package v2 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/secdefrules_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/secdefrules_test.go deleted file mode 100644 index 78b07986bd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/secdefrules_test.go +++ /dev/null @@ -1,72 +0,0 @@ -// +build acceptance compute defsecrules - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - dsr "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestSecDefRules(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - id := createDefRule(t, client) - - listDefRules(t, client) - - getDefRule(t, client, id) - - deleteDefRule(t, client, id) -} - -func createDefRule(t *testing.T, client *gophercloud.ServiceClient) string { - opts := dsr.CreateOpts{ - FromPort: tools.RandomInt(80, 89), - ToPort: tools.RandomInt(90, 99), - IPProtocol: "TCP", - CIDR: "0.0.0.0/0", - } - - rule, err := dsr.Create(client, opts).Extract() - th.AssertNoErr(t, err) - - t.Logf("Created default rule %s", rule.ID) - - return rule.ID -} - -func listDefRules(t *testing.T, client *gophercloud.ServiceClient) { - err := dsr.List(client).EachPage(func(page pagination.Page) (bool, error) { - drList, err := dsr.ExtractDefaultRules(page) - th.AssertNoErr(t, err) - - for _, dr := range drList { - t.Logf("Listing default rule %s: Name [%s] From Port [%s] To Port [%s] Protocol [%s]", - dr.ID, dr.FromPort, dr.ToPort, dr.IPProtocol) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func getDefRule(t *testing.T, client *gophercloud.ServiceClient, id string) { - rule, err := dsr.Get(client, id).Extract() - th.AssertNoErr(t, err) - - t.Logf("Getting rule %s: %#v", id, rule) -} - -func deleteDefRule(t *testing.T, client *gophercloud.ServiceClient, id string) { - err := dsr.Delete(client, id).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Deleted rule %s", id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/secgroup_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/secgroup_test.go deleted file mode 100644 index 4f50739109..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/secgroup_test.go +++ /dev/null @@ -1,177 +0,0 @@ -// +build acceptance compute secgroups - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestSecGroups(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - serverID, needsDeletion := findServer(t, client) - - groupID := createSecGroup(t, client) - - listSecGroups(t, client) - - newName := tools.RandomString("secgroup_", 5) - updateSecGroup(t, client, groupID, newName) - - getSecGroup(t, client, groupID) - - addRemoveRules(t, client, groupID) - - addServerToSecGroup(t, client, serverID, newName) - - removeServerFromSecGroup(t, client, serverID, newName) - - if needsDeletion { - servers.Delete(client, serverID) - } - - deleteSecGroup(t, client, groupID) -} - -func createSecGroup(t *testing.T, client *gophercloud.ServiceClient) string { - opts := secgroups.CreateOpts{ - Name: tools.RandomString("secgroup_", 5), - Description: "something", - } - - group, err := secgroups.Create(client, opts).Extract() - th.AssertNoErr(t, err) - - t.Logf("Created secgroup %s %s", group.ID, group.Name) - - return group.ID -} - -func listSecGroups(t *testing.T, client *gophercloud.ServiceClient) { - err := secgroups.List(client).EachPage(func(page pagination.Page) (bool, error) { - secGrpList, err := secgroups.ExtractSecurityGroups(page) - th.AssertNoErr(t, err) - - for _, sg := range secGrpList { - t.Logf("Listing secgroup %s: Name [%s] Desc [%s] TenantID [%s]", sg.ID, - sg.Name, sg.Description, sg.TenantID) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func updateSecGroup(t *testing.T, client *gophercloud.ServiceClient, id, newName string) { - opts := secgroups.UpdateOpts{ - Name: newName, - Description: tools.RandomString("dec_", 10), - } - group, err := secgroups.Update(client, id, opts).Extract() - th.AssertNoErr(t, err) - - t.Logf("Updated %s's name to %s", group.ID, group.Name) -} - -func getSecGroup(t *testing.T, client *gophercloud.ServiceClient, id string) { - group, err := secgroups.Get(client, id).Extract() - th.AssertNoErr(t, err) - - t.Logf("Getting %s: %#v", id, group) -} - -func addRemoveRules(t *testing.T, client *gophercloud.ServiceClient, id string) { - opts := secgroups.CreateRuleOpts{ - ParentGroupID: id, - FromPort: 22, - ToPort: 22, - IPProtocol: "TCP", - CIDR: "0.0.0.0/0", - } - - rule, err := secgroups.CreateRule(client, opts).Extract() - th.AssertNoErr(t, err) - - t.Logf("Adding rule %s to group %s", rule.ID, id) - - err = secgroups.DeleteRule(client, rule.ID).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Deleted rule %s from group %s", rule.ID, id) -} - -func findServer(t *testing.T, client *gophercloud.ServiceClient) (string, bool) { - var serverID string - var needsDeletion bool - - err := servers.List(client, nil).EachPage(func(page pagination.Page) (bool, error) { - sList, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - - for _, s := range sList { - serverID = s.ID - needsDeletion = false - - t.Logf("Found an existing server: ID [%s]", serverID) - break - } - - return true, nil - }) - th.AssertNoErr(t, err) - - if serverID == "" { - t.Log("No server found, creating one") - - choices, err := ComputeChoicesFromEnv() - th.AssertNoErr(t, err) - - opts := &servers.CreateOpts{ - Name: tools.RandomString("secgroup_test_", 5), - ImageRef: choices.ImageID, - FlavorRef: choices.FlavorID, - } - - s, err := servers.Create(client, opts).Extract() - th.AssertNoErr(t, err) - serverID = s.ID - - t.Logf("Created server %s, waiting for it to build", s.ID) - err = servers.WaitForStatus(client, serverID, "ACTIVE", 300) - th.AssertNoErr(t, err) - - needsDeletion = true - } - - return serverID, needsDeletion -} - -func addServerToSecGroup(t *testing.T, client *gophercloud.ServiceClient, serverID, groupName string) { - err := secgroups.AddServerToGroup(client, serverID, groupName).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Adding group %s to server %s", groupName, serverID) -} - -func removeServerFromSecGroup(t *testing.T, client *gophercloud.ServiceClient, serverID, groupName string) { - err := secgroups.RemoveServerFromGroup(client, serverID, groupName).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Removing group %s from server %s", groupName, serverID) -} - -func deleteSecGroup(t *testing.T, client *gophercloud.ServiceClient, id string) { - err := secgroups.Delete(client, id).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Deleted group %s", id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go deleted file mode 100644 index d52a9d3537..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go +++ /dev/null @@ -1,450 +0,0 @@ -// +build acceptance compute servers - -package v2 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListServers(t *testing.T) { - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - t.Logf("ID\tRegion\tName\tStatus\tIPv4\tIPv6") - - pager := servers.List(client, servers.ListOpts{}) - count, pages := 0, 0 - pager.EachPage(func(page pagination.Page) (bool, error) { - pages++ - t.Logf("---") - - servers, err := servers.ExtractServers(page) - if err != nil { - return false, err - } - - for _, s := range servers { - t.Logf("%s\t%s\t%s\t%s\t%s\t\n", s.ID, s.Name, s.Status, s.AccessIPv4, s.AccessIPv6) - count++ - } - - return true, nil - }) - - t.Logf("--------\n%d servers listed on %d pages.\n", count, pages) -} - -func networkingClient() (*gophercloud.ServiceClient, error) { - opts, err := openstack.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - - provider, err := openstack.AuthenticatedClient(opts) - if err != nil { - return nil, err - } - - return openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ - Name: "neutron", - Region: os.Getenv("OS_REGION_NAME"), - }) -} - -func createServer(t *testing.T, client *gophercloud.ServiceClient, choices *ComputeChoices) (*servers.Server, error) { - if testing.Short() { - t.Skip("Skipping test that requires server creation in short mode.") - } - - var network networks.Network - - networkingClient, err := networkingClient() - if err != nil { - t.Fatalf("Unable to create a networking client: %v", err) - } - - pager := networks.List(networkingClient, networks.ListOpts{Name: "public", Limit: 1}) - pager.EachPage(func(page pagination.Page) (bool, error) { - networks, err := networks.ExtractNetworks(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - if len(networks) == 0 { - t.Fatalf("No networks to attach to server") - return false, err - } - - network = networks[0] - - return false, nil - }) - - name := tools.RandomString("ACPTTEST", 16) - t.Logf("Attempting to create server: %s\n", name) - - pwd := tools.MakeNewPassword("") - - server, err := servers.Create(client, servers.CreateOpts{ - Name: name, - FlavorRef: choices.FlavorID, - ImageRef: choices.ImageID, - Networks: []servers.Network{ - servers.Network{UUID: network.ID}, - }, - AdminPass: pwd, - }).Extract() - if err != nil { - t.Fatalf("Unable to create server: %v", err) - } - - th.AssertEquals(t, pwd, server.AdminPass) - - return server, err -} - -func TestCreateDestroyServer(t *testing.T) { - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatalf("Unable to create server: %v", err) - } - defer func() { - servers.Delete(client, server.ID) - t.Logf("Server deleted.") - }() - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatalf("Unable to wait for server: %v", err) - } -} - -func TestUpdateServer(t *testing.T) { - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - alternateName := tools.RandomString("ACPTTEST", 16) - for alternateName == server.Name { - alternateName = tools.RandomString("ACPTTEST", 16) - } - - t.Logf("Attempting to rename the server to %s.", alternateName) - - updated, err := servers.Update(client, server.ID, servers.UpdateOpts{Name: alternateName}).Extract() - if err != nil { - t.Fatalf("Unable to rename server: %v", err) - } - - if updated.ID != server.ID { - t.Errorf("Updated server ID [%s] didn't match original server ID [%s]!", updated.ID, server.ID) - } - - err = tools.WaitFor(func() (bool, error) { - latest, err := servers.Get(client, updated.ID).Extract() - if err != nil { - return false, err - } - - return latest.Name == alternateName, nil - }) -} - -func TestActionChangeAdminPassword(t *testing.T) { - t.Parallel() - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - randomPassword := tools.MakeNewPassword(server.AdminPass) - res := servers.ChangeAdminPassword(client, server.ID, randomPassword) - if res.Err != nil { - t.Fatal(err) - } - - if err = waitForStatus(client, server, "PASSWORD"); err != nil { - t.Fatal(err) - } - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } -} - -func TestActionReboot(t *testing.T) { - t.Parallel() - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - res := servers.Reboot(client, server.ID, "aldhjflaskhjf") - if res.Err == nil { - t.Fatal("Expected the SDK to provide an ArgumentError here") - } - - t.Logf("Attempting reboot of server %s", server.ID) - res = servers.Reboot(client, server.ID, servers.OSReboot) - if res.Err != nil { - t.Fatalf("Unable to reboot server: %v", err) - } - - if err = waitForStatus(client, server, "REBOOT"); err != nil { - t.Fatal(err) - } - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } -} - -func TestActionRebuild(t *testing.T) { - t.Parallel() - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - t.Logf("Attempting to rebuild server %s", server.ID) - - rebuildOpts := servers.RebuildOpts{ - Name: tools.RandomString("ACPTTEST", 16), - AdminPass: tools.MakeNewPassword(server.AdminPass), - ImageID: choices.ImageID, - } - - rebuilt, err := servers.Rebuild(client, server.ID, rebuildOpts).Extract() - if err != nil { - t.Fatal(err) - } - - if rebuilt.ID != server.ID { - t.Errorf("Expected rebuilt server ID of [%s]; got [%s]", server.ID, rebuilt.ID) - } - - if err = waitForStatus(client, rebuilt, "REBUILD"); err != nil { - t.Fatal(err) - } - - if err = waitForStatus(client, rebuilt, "ACTIVE"); err != nil { - t.Fatal(err) - } -} - -func resizeServer(t *testing.T, client *gophercloud.ServiceClient, server *servers.Server, choices *ComputeChoices) { - if err := waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - t.Logf("Attempting to resize server [%s]", server.ID) - - opts := &servers.ResizeOpts{ - FlavorRef: choices.FlavorIDResize, - } - if res := servers.Resize(client, server.ID, opts); res.Err != nil { - t.Fatal(res.Err) - } - - if err := waitForStatus(client, server, "VERIFY_RESIZE"); err != nil { - t.Fatal(err) - } -} - -func TestActionResizeConfirm(t *testing.T) { - t.Parallel() - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - resizeServer(t, client, server, choices) - - t.Logf("Attempting to confirm resize for server %s", server.ID) - - if res := servers.ConfirmResize(client, server.ID); res.Err != nil { - t.Fatal(err) - } - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } -} - -func TestActionResizeRevert(t *testing.T) { - t.Parallel() - - choices, err := ComputeChoicesFromEnv() - if err != nil { - t.Fatal(err) - } - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - resizeServer(t, client, server, choices) - - t.Logf("Attempting to revert resize for server %s", server.ID) - - if res := servers.RevertResize(client, server.ID); res.Err != nil { - t.Fatal(err) - } - - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } -} - -func TestServerMetadata(t *testing.T) { - t.Parallel() - - choices, err := ComputeChoicesFromEnv() - th.AssertNoErr(t, err) - - client, err := newClient() - if err != nil { - t.Fatalf("Unable to create a compute client: %v", err) - } - - server, err := createServer(t, client, choices) - if err != nil { - t.Fatal(err) - } - defer servers.Delete(client, server.ID) - if err = waitForStatus(client, server, "ACTIVE"); err != nil { - t.Fatal(err) - } - - metadata, err := servers.UpdateMetadata(client, server.ID, servers.MetadataOpts{ - "foo": "bar", - "this": "that", - }).Extract() - th.AssertNoErr(t, err) - t.Logf("UpdateMetadata result: %+v\n", metadata) - - err = servers.DeleteMetadatum(client, server.ID, "foo").ExtractErr() - th.AssertNoErr(t, err) - - metadata, err = servers.CreateMetadatum(client, server.ID, servers.MetadatumOpts{ - "foo": "baz", - }).Extract() - th.AssertNoErr(t, err) - t.Logf("CreateMetadatum result: %+v\n", metadata) - - metadata, err = servers.Metadatum(client, server.ID, "foo").Extract() - th.AssertNoErr(t, err) - t.Logf("Metadatum result: %+v\n", metadata) - th.AssertEquals(t, "baz", metadata["foo"]) - - metadata, err = servers.Metadata(client, server.ID).Extract() - th.AssertNoErr(t, err) - t.Logf("Metadata result: %+v\n", metadata) - - metadata, err = servers.ResetMetadata(client, server.ID, servers.MetadataOpts{}).Extract() - th.AssertNoErr(t, err) - t.Logf("ResetMetadata result: %+v\n", metadata) - th.AssertDeepEquals(t, map[string]string{}, metadata) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/extension_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/extension_test.go deleted file mode 100644 index d1fa1e3dce..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/extension_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build acceptance identity - -package v2 - -import ( - "testing" - - extensions2 "github.com/rackspace/gophercloud/openstack/identity/v2/extensions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestEnumerateExtensions(t *testing.T) { - service := authenticatedClient(t) - - t.Logf("Extensions available on this identity endpoint:") - count := 0 - err := extensions2.List(service).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - extensions, err := extensions2.ExtractExtensions(page) - th.AssertNoErr(t, err) - - for i, ext := range extensions { - t.Logf("[%02d] name=[%s] namespace=[%s]", i, ext.Name, ext.Namespace) - t.Logf(" alias=[%s] updated=[%s]", ext.Alias, ext.Updated) - t.Logf(" description=[%s]", ext.Description) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) -} - -func TestGetExtension(t *testing.T) { - service := authenticatedClient(t) - - ext, err := extensions2.Get(service, "OS-KSCRUD").Extract() - th.AssertNoErr(t, err) - - th.CheckEquals(t, "OpenStack Keystone User CRUD", ext.Name) - th.CheckEquals(t, "http://docs.openstack.org/identity/api/ext/OS-KSCRUD/v1.0", ext.Namespace) - th.CheckEquals(t, "OS-KSCRUD", ext.Alias) - th.CheckEquals(t, "OpenStack extensions to Keystone v2.0 API enabling User Operations.", ext.Description) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/identity_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/identity_test.go deleted file mode 100644 index 96bf1fdade..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/identity_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build acceptance identity - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - th "github.com/rackspace/gophercloud/testhelper" -) - -func v2AuthOptions(t *testing.T) gophercloud.AuthOptions { - // Obtain credentials from the environment. - ao, err := openstack.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - - // Trim out unused fields. Prefer authentication by API key to password. - ao.UserID, ao.DomainID, ao.DomainName = "", "", "" - if ao.APIKey != "" { - ao.Password = "" - } - - return ao -} - -func createClient(t *testing.T, auth bool) *gophercloud.ServiceClient { - ao := v2AuthOptions(t) - - provider, err := openstack.NewClient(ao.IdentityEndpoint) - th.AssertNoErr(t, err) - - if auth { - err = openstack.AuthenticateV2(provider, ao) - th.AssertNoErr(t, err) - } - - return openstack.NewIdentityV2(provider) -} - -func unauthenticatedClient(t *testing.T) *gophercloud.ServiceClient { - return createClient(t, false) -} - -func authenticatedClient(t *testing.T) *gophercloud.ServiceClient { - return createClient(t, true) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/pkg.go deleted file mode 100644 index 5ec3cc8e83..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package v2 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/role_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/role_test.go deleted file mode 100644 index ba243fe02b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/role_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// +build acceptance identity roles - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestRoles(t *testing.T) { - client := authenticatedClient(t) - - tenantID := findTenant(t, client) - userID := createUser(t, client, tenantID) - roleID := listRoles(t, client) - - addUserRole(t, client, tenantID, userID, roleID) - - deleteUserRole(t, client, tenantID, userID, roleID) - - deleteUser(t, client, userID) -} - -func listRoles(t *testing.T, client *gophercloud.ServiceClient) string { - var roleID string - - err := roles.List(client).EachPage(func(page pagination.Page) (bool, error) { - roleList, err := roles.ExtractRoles(page) - th.AssertNoErr(t, err) - - for _, role := range roleList { - t.Logf("Listing role: ID [%s] Name [%s]", role.ID, role.Name) - roleID = role.ID - } - - return true, nil - }) - - th.AssertNoErr(t, err) - - return roleID -} - -func addUserRole(t *testing.T, client *gophercloud.ServiceClient, tenantID, userID, roleID string) { - err := roles.AddUserRole(client, tenantID, userID, roleID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Added role %s to user %s", roleID, userID) -} - -func deleteUserRole(t *testing.T, client *gophercloud.ServiceClient, tenantID, userID, roleID string) { - err := roles.DeleteUserRole(client, tenantID, userID, roleID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Removed role %s from user %s", roleID, userID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/tenant_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/tenant_test.go deleted file mode 100644 index 578fc483b8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/tenant_test.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build acceptance identity - -package v2 - -import ( - "testing" - - tenants2 "github.com/rackspace/gophercloud/openstack/identity/v2/tenants" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestEnumerateTenants(t *testing.T) { - service := authenticatedClient(t) - - t.Logf("Tenants to which your current token grants access:") - count := 0 - err := tenants2.List(service, nil).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - tenants, err := tenants2.ExtractTenants(page) - th.AssertNoErr(t, err) - for i, tenant := range tenants { - t.Logf("[%02d] name=[%s] id=[%s] description=[%s] enabled=[%v]", - i, tenant.Name, tenant.ID, tenant.Description, tenant.Enabled) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/token_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/token_test.go deleted file mode 100644 index d903140855..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/token_test.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build acceptance identity - -package v2 - -import ( - "testing" - - tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAuthenticate(t *testing.T) { - ao := v2AuthOptions(t) - service := unauthenticatedClient(t) - - // Authenticated! - result := tokens2.Create(service, tokens2.WrapOptions(ao)) - - // Extract and print the token. - token, err := result.ExtractToken() - th.AssertNoErr(t, err) - - t.Logf("Acquired token: [%s]", token.ID) - t.Logf("The token will expire at: [%s]", token.ExpiresAt.String()) - t.Logf("The token is valid for tenant: [%#v]", token.Tenant) - - // Extract and print the service catalog. - catalog, err := result.ExtractServiceCatalog() - th.AssertNoErr(t, err) - - t.Logf("Acquired service catalog listing [%d] services", len(catalog.Entries)) - for i, entry := range catalog.Entries { - t.Logf("[%02d]: name=[%s], type=[%s]", i, entry.Name, entry.Type) - for _, endpoint := range entry.Endpoints { - t.Logf(" - region=[%s] publicURL=[%s]", endpoint.Region, endpoint.PublicURL) - } - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/user_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/user_test.go deleted file mode 100644 index fe73d19898..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v2/user_test.go +++ /dev/null @@ -1,127 +0,0 @@ -// +build acceptance identity - -package v2 - -import ( - "strconv" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/identity/v2/tenants" - "github.com/rackspace/gophercloud/openstack/identity/v2/users" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestUsers(t *testing.T) { - client := authenticatedClient(t) - - tenantID := findTenant(t, client) - - userID := createUser(t, client, tenantID) - - listUsers(t, client) - - getUser(t, client, userID) - - updateUser(t, client, userID) - - listUserRoles(t, client, tenantID, userID) - - deleteUser(t, client, userID) -} - -func findTenant(t *testing.T, client *gophercloud.ServiceClient) string { - var tenantID string - err := tenants.List(client, nil).EachPage(func(page pagination.Page) (bool, error) { - tenantList, err := tenants.ExtractTenants(page) - th.AssertNoErr(t, err) - - for _, t := range tenantList { - tenantID = t.ID - break - } - - return true, nil - }) - th.AssertNoErr(t, err) - - return tenantID -} - -func createUser(t *testing.T, client *gophercloud.ServiceClient, tenantID string) string { - t.Log("Creating user") - - opts := users.CreateOpts{ - Name: tools.RandomString("user_", 5), - Enabled: users.Disabled, - TenantID: tenantID, - Email: "new_user@foo.com", - } - - user, err := users.Create(client, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Created user %s on tenant %s", user.ID, tenantID) - - return user.ID -} - -func listUsers(t *testing.T, client *gophercloud.ServiceClient) { - err := users.List(client).EachPage(func(page pagination.Page) (bool, error) { - userList, err := users.ExtractUsers(page) - th.AssertNoErr(t, err) - - for _, user := range userList { - t.Logf("Listing user: ID [%s] Name [%s] Email [%s] Enabled? [%s]", - user.ID, user.Name, user.Email, strconv.FormatBool(user.Enabled)) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func getUser(t *testing.T, client *gophercloud.ServiceClient, userID string) { - _, err := users.Get(client, userID).Extract() - th.AssertNoErr(t, err) - t.Logf("Getting user %s", userID) -} - -func updateUser(t *testing.T, client *gophercloud.ServiceClient, userID string) { - opts := users.UpdateOpts{Name: tools.RandomString("new_name", 5), Email: "new@foo.com"} - user, err := users.Update(client, userID, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Updated user %s: Name [%s] Email [%s]", userID, user.Name, user.Email) -} - -func listUserRoles(t *testing.T, client *gophercloud.ServiceClient, tenantID, userID string) { - count := 0 - err := users.ListRoles(client, tenantID, userID).EachPage(func(page pagination.Page) (bool, error) { - count++ - - roleList, err := users.ExtractRoles(page) - th.AssertNoErr(t, err) - - t.Logf("Listing roles for user %s", userID) - - for _, r := range roleList { - t.Logf("- %s (%s)", r.Name, r.ID) - } - - return true, nil - }) - - if count == 0 { - t.Logf("No roles for user %s", userID) - } - - th.AssertNoErr(t, err) -} - -func deleteUser(t *testing.T, client *gophercloud.ServiceClient, userID string) { - res := users.Delete(client, userID) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted user %s", userID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/endpoint_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/endpoint_test.go deleted file mode 100644 index ea893c2dea..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/endpoint_test.go +++ /dev/null @@ -1,111 +0,0 @@ -// +build acceptance - -package v3 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - endpoints3 "github.com/rackspace/gophercloud/openstack/identity/v3/endpoints" - services3 "github.com/rackspace/gophercloud/openstack/identity/v3/services" - "github.com/rackspace/gophercloud/pagination" -) - -func TestListEndpoints(t *testing.T) { - // Create a service client. - serviceClient := createAuthenticatedClient(t) - if serviceClient == nil { - return - } - - // Use the service to list all available endpoints. - pager := endpoints3.List(serviceClient, endpoints3.ListOpts{}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - endpoints, err := endpoints3.ExtractEndpoints(page) - if err != nil { - t.Fatalf("Error extracting endpoings: %v", err) - } - - for _, endpoint := range endpoints { - t.Logf("Endpoint: %8s %10s %9s %s", - endpoint.ID, - endpoint.Availability, - endpoint.Name, - endpoint.URL) - } - - return true, nil - }) - if err != nil { - t.Errorf("Unexpected error while iterating endpoint pages: %v", err) - } -} - -func TestNavigateCatalog(t *testing.T) { - // Create a service client. - client := createAuthenticatedClient(t) - if client == nil { - return - } - - var compute *services3.Service - var endpoint *endpoints3.Endpoint - - // Discover the service we're interested in. - servicePager := services3.List(client, services3.ListOpts{ServiceType: "compute"}) - err := servicePager.EachPage(func(page pagination.Page) (bool, error) { - part, err := services3.ExtractServices(page) - if err != nil { - return false, err - } - if compute != nil { - t.Fatalf("Expected one service, got more than one page") - return false, nil - } - if len(part) != 1 { - t.Fatalf("Expected one service, got %d", len(part)) - return false, nil - } - - compute = &part[0] - return true, nil - }) - if err != nil { - t.Fatalf("Unexpected error iterating pages: %v", err) - } - - if compute == nil { - t.Fatalf("No compute service found.") - } - - // Enumerate the endpoints available for this service. - computePager := endpoints3.List(client, endpoints3.ListOpts{ - Availability: gophercloud.AvailabilityPublic, - ServiceID: compute.ID, - }) - err = computePager.EachPage(func(page pagination.Page) (bool, error) { - part, err := endpoints3.ExtractEndpoints(page) - if err != nil { - return false, err - } - if endpoint != nil { - t.Fatalf("Expected one endpoint, got more than one page") - return false, nil - } - if len(part) != 1 { - t.Fatalf("Expected one endpoint, got %d", len(part)) - return false, nil - } - - endpoint = &part[0] - return true, nil - }) - - if endpoint == nil { - t.Fatalf("No endpoint found.") - } - - t.Logf("Success. The compute endpoint is at %s.", endpoint.URL) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/identity_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/identity_test.go deleted file mode 100644 index ce64345886..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/identity_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build acceptance - -package v3 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - th "github.com/rackspace/gophercloud/testhelper" -) - -func createAuthenticatedClient(t *testing.T) *gophercloud.ServiceClient { - // Obtain credentials from the environment. - ao, err := openstack.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - - // Trim out unused fields. - ao.Username, ao.TenantID, ao.TenantName = "", "", "" - - if ao.UserID == "" { - t.Logf("Skipping identity v3 tests because no OS_USERID is present.") - return nil - } - - // Create a client and manually authenticate against v3. - providerClient, err := openstack.NewClient(ao.IdentityEndpoint) - if err != nil { - t.Fatalf("Unable to instantiate client: %v", err) - } - - err = openstack.AuthenticateV3(providerClient, ao) - if err != nil { - t.Fatalf("Unable to authenticate against identity v3: %v", err) - } - - // Create a service client. - return openstack.NewIdentityV3(providerClient) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/pkg.go deleted file mode 100644 index eac3ae96a1..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package v3 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/service_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/service_test.go deleted file mode 100644 index 082bd11e74..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/service_test.go +++ /dev/null @@ -1,36 +0,0 @@ -// +build acceptance - -package v3 - -import ( - "testing" - - services3 "github.com/rackspace/gophercloud/openstack/identity/v3/services" - "github.com/rackspace/gophercloud/pagination" -) - -func TestListServices(t *testing.T) { - // Create a service client. - serviceClient := createAuthenticatedClient(t) - if serviceClient == nil { - return - } - - // Use the client to list all available services. - pager := services3.List(serviceClient, services3.ListOpts{}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - parts, err := services3.ExtractServices(page) - if err != nil { - return false, err - } - - t.Logf("--- Page ---") - for _, service := range parts { - t.Logf("Service: %32s %15s %10s %s", service.ID, service.Type, service.Name, *service.Description) - } - return true, nil - }) - if err != nil { - t.Errorf("Unexpected error traversing pages: %v", err) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/token_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/token_test.go deleted file mode 100644 index 4342ade03c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/identity/v3/token_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// +build acceptance - -package v3 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack" - tokens3 "github.com/rackspace/gophercloud/openstack/identity/v3/tokens" -) - -func TestGetToken(t *testing.T) { - // Obtain credentials from the environment. - ao, err := openstack.AuthOptionsFromEnv() - if err != nil { - t.Fatalf("Unable to acquire credentials: %v", err) - } - - // Trim out unused fields. Skip if we don't have a UserID. - ao.Username, ao.TenantID, ao.TenantName = "", "", "" - if ao.UserID == "" { - t.Logf("Skipping identity v3 tests because no OS_USERID is present.") - return - } - - // Create an unauthenticated client. - provider, err := openstack.NewClient(ao.IdentityEndpoint) - if err != nil { - t.Fatalf("Unable to instantiate client: %v", err) - } - - // Create a service client. - service := openstack.NewIdentityV3(provider) - - // Use the service to create a token. - token, err := tokens3.Create(service, ao, nil).Extract() - if err != nil { - t.Fatalf("Unable to get token: %v", err) - } - - t.Logf("Acquired token: %s", token.ID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/apiversion_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/apiversion_test.go deleted file mode 100644 index 99e1d01187..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/apiversion_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/networking/v2/apiversions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListAPIVersions(t *testing.T) { - Setup(t) - defer Teardown() - - pager := apiversions.ListVersions(Client) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - versions, err := apiversions.ExtractAPIVersions(page) - th.AssertNoErr(t, err) - - for _, v := range versions { - t.Logf("API Version: ID [%s] Status [%s]", v.ID, v.Status) - } - - return true, nil - }) - th.CheckNoErr(t, err) -} - -func TestListAPIResources(t *testing.T) { - Setup(t) - defer Teardown() - - pager := apiversions.ListVersionResources(Client, "v2.0") - err := pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - vrs, err := apiversions.ExtractVersionResources(page) - th.AssertNoErr(t, err) - - for _, vr := range vrs { - t.Logf("Network: Name [%s] Collection [%s]", vr.Name, vr.Collection) - } - - return true, nil - }) - th.CheckNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/common.go deleted file mode 100644 index 1efac2c081..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/common.go +++ /dev/null @@ -1,39 +0,0 @@ -package v2 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - th "github.com/rackspace/gophercloud/testhelper" -) - -var Client *gophercloud.ServiceClient - -func NewClient() (*gophercloud.ServiceClient, error) { - opts, err := openstack.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - - provider, err := openstack.AuthenticatedClient(opts) - if err != nil { - return nil, err - } - - return openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ - Name: "neutron", - Region: os.Getenv("OS_REGION_NAME"), - }) -} - -func Setup(t *testing.T) { - client, err := NewClient() - th.AssertNoErr(t, err) - Client = client -} - -func Teardown() { - Client = nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extension_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extension_test.go deleted file mode 100644 index edcbba4fd1..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extension_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListExts(t *testing.T) { - Setup(t) - defer Teardown() - - pager := extensions.List(Client) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - exts, err := extensions.ExtractExtensions(page) - th.AssertNoErr(t, err) - - for _, ext := range exts { - t.Logf("Extension: Name [%s] Description [%s]", ext.Name, ext.Description) - } - - return true, nil - }) - th.CheckNoErr(t, err) -} - -func TestGetExt(t *testing.T) { - Setup(t) - defer Teardown() - - ext, err := extensions.Get(Client, "service-type").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ext.Updated, "2013-01-20T00:00:00-00:00") - th.AssertEquals(t, ext.Name, "Neutron Service Type Management") - th.AssertEquals(t, ext.Namespace, "http://docs.openstack.org/ext/neutron/service-type/api/v1.0") - th.AssertEquals(t, ext.Alias, "service-type") - th.AssertEquals(t, ext.Description, "API for retrieving service providers for Neutron advanced services") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/layer3_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/layer3_test.go deleted file mode 100644 index 63e0be39d7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/layer3_test.go +++ /dev/null @@ -1,300 +0,0 @@ -// +build acceptance networking layer3ext - -package extensions - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/openstack/networking/v2/ports" - "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -const ( - cidr1 = "10.0.0.1/24" - cidr2 = "20.0.0.1/24" -) - -func TestAll(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - testRouter(t) - testFloatingIP(t) -} - -func testRouter(t *testing.T) { - // Setup: Create network - networkID := createNetwork(t) - - // Create router - routerID := createRouter(t, networkID) - - // Lists routers - listRouters(t) - - // Update router - updateRouter(t, routerID) - - // Get router - getRouter(t, routerID) - - // Create new subnet. Note: this subnet will be deleted when networkID is deleted - subnetID := createSubnet(t, networkID, cidr2) - - // Add interface - addInterface(t, routerID, subnetID) - - // Remove interface - removeInterface(t, routerID, subnetID) - - // Delete router - deleteRouter(t, routerID) - - // Cleanup - deleteNetwork(t, networkID) -} - -func testFloatingIP(t *testing.T) { - // Setup external network - extNetworkID := createNetwork(t) - - // Setup internal network, subnet and port - intNetworkID, subnetID, portID := createInternalTopology(t) - - // Now the important part: we need to allow the external network to talk to - // the internal subnet. For this we need a router that has an interface to - // the internal subnet. - routerID := bridgeIntSubnetWithExtNetwork(t, extNetworkID, subnetID) - - // Create floating IP - ipID := createFloatingIP(t, extNetworkID, portID) - - // Get floating IP - getFloatingIP(t, ipID) - - // Update floating IP - updateFloatingIP(t, ipID, portID) - - // Delete floating IP - deleteFloatingIP(t, ipID) - - // Remove the internal subnet interface - removeInterface(t, routerID, subnetID) - - // Delete router and external network - deleteRouter(t, routerID) - deleteNetwork(t, extNetworkID) - - // Delete internal port and network - deletePort(t, portID) - deleteNetwork(t, intNetworkID) -} - -func createNetwork(t *testing.T) string { - t.Logf("Creating a network") - - asu := true - opts := external.CreateOpts{ - Parent: networks.CreateOpts{Name: "sample_network", AdminStateUp: &asu}, - External: true, - } - n, err := networks.Create(base.Client, opts).Extract() - - th.AssertNoErr(t, err) - - if n.ID == "" { - t.Fatalf("No ID returned when creating a network") - } - - createSubnet(t, n.ID, cidr1) - - t.Logf("Network created: ID [%s]", n.ID) - - return n.ID -} - -func deleteNetwork(t *testing.T, networkID string) { - t.Logf("Deleting network %s", networkID) - networks.Delete(base.Client, networkID) -} - -func deletePort(t *testing.T, portID string) { - t.Logf("Deleting port %s", portID) - ports.Delete(base.Client, portID) -} - -func createInternalTopology(t *testing.T) (string, string, string) { - t.Logf("Creating an internal network (for port)") - opts := networks.CreateOpts{Name: "internal_network"} - n, err := networks.Create(base.Client, opts).Extract() - th.AssertNoErr(t, err) - - // A subnet is also needed - subnetID := createSubnet(t, n.ID, cidr2) - - t.Logf("Creating an internal port on network %s", n.ID) - p, err := ports.Create(base.Client, ports.CreateOpts{ - NetworkID: n.ID, - Name: "fixed_internal_port", - }).Extract() - th.AssertNoErr(t, err) - - return n.ID, subnetID, p.ID -} - -func bridgeIntSubnetWithExtNetwork(t *testing.T, networkID, subnetID string) string { - // Create router with external gateway info - routerID := createRouter(t, networkID) - - // Add interface for internal subnet - addInterface(t, routerID, subnetID) - - return routerID -} - -func createSubnet(t *testing.T, networkID, cidr string) string { - t.Logf("Creating a subnet for network %s", networkID) - - iFalse := false - s, err := subnets.Create(base.Client, subnets.CreateOpts{ - NetworkID: networkID, - CIDR: cidr, - IPVersion: subnets.IPv4, - Name: "my_subnet", - EnableDHCP: &iFalse, - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Subnet created: ID [%s]", s.ID) - - return s.ID -} - -func createRouter(t *testing.T, networkID string) string { - t.Logf("Creating a router for network %s", networkID) - - asu := false - gwi := routers.GatewayInfo{NetworkID: networkID} - r, err := routers.Create(base.Client, routers.CreateOpts{ - Name: "foo_router", - AdminStateUp: &asu, - GatewayInfo: &gwi, - }).Extract() - - th.AssertNoErr(t, err) - - if r.ID == "" { - t.Fatalf("No ID returned when creating a router") - } - - t.Logf("Router created: ID [%s]", r.ID) - - return r.ID -} - -func listRouters(t *testing.T) { - pager := routers.List(base.Client, routers.ListOpts{}) - - err := pager.EachPage(func(page pagination.Page) (bool, error) { - routerList, err := routers.ExtractRouters(page) - th.AssertNoErr(t, err) - - for _, r := range routerList { - t.Logf("Listing router: ID [%s] Name [%s] Status [%s] GatewayInfo [%#v]", - r.ID, r.Name, r.Status, r.GatewayInfo) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func updateRouter(t *testing.T, routerID string) { - _, err := routers.Update(base.Client, routerID, routers.UpdateOpts{ - Name: "another_name", - }).Extract() - - th.AssertNoErr(t, err) -} - -func getRouter(t *testing.T, routerID string) { - r, err := routers.Get(base.Client, routerID).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Getting router: ID [%s] Name [%s] Status [%s]", r.ID, r.Name, r.Status) -} - -func addInterface(t *testing.T, routerID, subnetID string) { - ir, err := routers.AddInterface(base.Client, routerID, routers.InterfaceOpts{SubnetID: subnetID}).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Interface added to router %s: SubnetID [%s] PortID [%s]", routerID, ir.SubnetID, ir.PortID) -} - -func removeInterface(t *testing.T, routerID, subnetID string) { - ir, err := routers.RemoveInterface(base.Client, routerID, routers.InterfaceOpts{SubnetID: subnetID}).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Interface %s removed from %s", ir.ID, routerID) -} - -func deleteRouter(t *testing.T, routerID string) { - t.Logf("Deleting router %s", routerID) - - res := routers.Delete(base.Client, routerID) - - th.AssertNoErr(t, res.Err) -} - -func createFloatingIP(t *testing.T, networkID, portID string) string { - t.Logf("Creating floating IP on network [%s] with port [%s]", networkID, portID) - - opts := floatingips.CreateOpts{ - FloatingNetworkID: networkID, - PortID: portID, - } - - ip, err := floatingips.Create(base.Client, opts).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Floating IP created: ID [%s] Status [%s] Fixed (internal) IP: [%s] Floating (external) IP: [%s]", - ip.ID, ip.Status, ip.FixedIP, ip.FloatingIP) - - return ip.ID -} - -func getFloatingIP(t *testing.T, ipID string) { - ip, err := floatingips.Get(base.Client, ipID).Extract() - th.AssertNoErr(t, err) - - t.Logf("Getting floating IP: ID [%s] Status [%s]", ip.ID, ip.Status) -} - -func updateFloatingIP(t *testing.T, ipID, portID string) { - t.Logf("Disassociate all ports from IP %s", ipID) - _, err := floatingips.Update(base.Client, ipID, floatingips.UpdateOpts{PortID: ""}).Extract() - th.AssertNoErr(t, err) - - t.Logf("Re-associate the port %s", portID) - _, err = floatingips.Update(base.Client, ipID, floatingips.UpdateOpts{PortID: portID}).Extract() - th.AssertNoErr(t, err) -} - -func deleteFloatingIP(t *testing.T, ipID string) { - t.Logf("Deleting IP %s", ipID) - res := floatingips.Delete(base.Client, ipID) - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/common.go deleted file mode 100644 index 27dfe5f8b7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/common.go +++ /dev/null @@ -1,78 +0,0 @@ -package lbaas - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - th "github.com/rackspace/gophercloud/testhelper" -) - -func SetupTopology(t *testing.T) (string, string) { - // create network - n, err := networks.Create(base.Client, networks.CreateOpts{Name: "tmp_network"}).Extract() - th.AssertNoErr(t, err) - - t.Logf("Created network %s", n.ID) - - // create subnet - s, err := subnets.Create(base.Client, subnets.CreateOpts{ - NetworkID: n.ID, - CIDR: "192.168.199.0/24", - IPVersion: subnets.IPv4, - Name: "tmp_subnet", - }).Extract() - th.AssertNoErr(t, err) - - t.Logf("Created subnet %s", s.ID) - - return n.ID, s.ID -} - -func DeleteTopology(t *testing.T, networkID string) { - res := networks.Delete(base.Client, networkID) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted network %s", networkID) -} - -func CreatePool(t *testing.T, subnetID string) string { - p, err := pools.Create(base.Client, pools.CreateOpts{ - LBMethod: pools.LBMethodRoundRobin, - Protocol: "HTTP", - Name: "tmp_pool", - SubnetID: subnetID, - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Created pool %s", p.ID) - - return p.ID -} - -func DeletePool(t *testing.T, poolID string) { - res := pools.Delete(base.Client, poolID) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted pool %s", poolID) -} - -func CreateMonitor(t *testing.T) string { - m, err := monitors.Create(base.Client, monitors.CreateOpts{ - Delay: 10, - Timeout: 10, - MaxRetries: 3, - Type: monitors.TypeHTTP, - ExpectedCodes: "200", - URLPath: "/login", - HTTPMethod: "GET", - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Created monitor ID [%s]", m.ID) - - return m.ID -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/member_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/member_test.go deleted file mode 100644 index 9b60582d14..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/member_test.go +++ /dev/null @@ -1,95 +0,0 @@ -// +build acceptance networking lbaas lbaasmember - -package lbaas - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestMembers(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // setup - networkID, subnetID := SetupTopology(t) - poolID := CreatePool(t, subnetID) - - // create member - memberID := createMember(t, poolID) - - // list members - listMembers(t) - - // update member - updateMember(t, memberID) - - // get member - getMember(t, memberID) - - // delete member - deleteMember(t, memberID) - - // teardown - DeletePool(t, poolID) - DeleteTopology(t, networkID) -} - -func createMember(t *testing.T, poolID string) string { - m, err := members.Create(base.Client, members.CreateOpts{ - Address: "192.168.199.1", - ProtocolPort: 8080, - PoolID: poolID, - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Created member: ID [%s] Status [%s] Weight [%d] Address [%s] Port [%d]", - m.ID, m.Status, m.Weight, m.Address, m.ProtocolPort) - - return m.ID -} - -func listMembers(t *testing.T) { - err := members.List(base.Client, members.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - memberList, err := members.ExtractMembers(page) - if err != nil { - t.Errorf("Failed to extract members: %v", err) - return false, err - } - - for _, m := range memberList { - t.Logf("Listing member: ID [%s] Status [%s]", m.ID, m.Status) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func updateMember(t *testing.T, memberID string) { - m, err := members.Update(base.Client, memberID, members.UpdateOpts{AdminStateUp: true}).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Updated member ID [%s]", m.ID) -} - -func getMember(t *testing.T, memberID string) { - m, err := members.Get(base.Client, memberID).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Getting member ID [%s]", m.ID) -} - -func deleteMember(t *testing.T, memberID string) { - res := members.Delete(base.Client, memberID) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted member %s", memberID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go deleted file mode 100644 index 9056fff671..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build acceptance networking lbaas lbaasmonitor - -package lbaas - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestMonitors(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // create monitor - monitorID := CreateMonitor(t) - - // list monitors - listMonitors(t) - - // update monitor - updateMonitor(t, monitorID) - - // get monitor - getMonitor(t, monitorID) - - // delete monitor - deleteMonitor(t, monitorID) -} - -func listMonitors(t *testing.T) { - err := monitors.List(base.Client, monitors.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - monitorList, err := monitors.ExtractMonitors(page) - if err != nil { - t.Errorf("Failed to extract monitors: %v", err) - return false, err - } - - for _, m := range monitorList { - t.Logf("Listing monitor: ID [%s] Type [%s] Delay [%ds] Timeout [%d] Retries [%d] Status [%s]", - m.ID, m.Type, m.Delay, m.Timeout, m.MaxRetries, m.Status) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func updateMonitor(t *testing.T, monitorID string) { - opts := monitors.UpdateOpts{Delay: 10, Timeout: 10, MaxRetries: 3} - m, err := monitors.Update(base.Client, monitorID, opts).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Updated monitor ID [%s]", m.ID) -} - -func getMonitor(t *testing.T, monitorID string) { - m, err := monitors.Get(base.Client, monitorID).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Getting monitor ID [%s]: URL path [%s] HTTP Method [%s] Accepted codes [%s]", - m.ID, m.URLPath, m.HTTPMethod, m.ExpectedCodes) -} - -func deleteMonitor(t *testing.T, monitorID string) { - res := monitors.Delete(base.Client, monitorID) - - th.AssertNoErr(t, res.Err) - - t.Logf("Deleted monitor %s", monitorID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/pkg.go deleted file mode 100644 index f5a7df7b75..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package lbaas diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/pool_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/pool_test.go deleted file mode 100644 index 81940649c5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/pool_test.go +++ /dev/null @@ -1,98 +0,0 @@ -// +build acceptance networking lbaas lbaaspool - -package lbaas - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestPools(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // setup - networkID, subnetID := SetupTopology(t) - - // create pool - poolID := CreatePool(t, subnetID) - - // list pools - listPools(t) - - // update pool - updatePool(t, poolID) - - // get pool - getPool(t, poolID) - - // create monitor - monitorID := CreateMonitor(t) - - // associate health monitor - associateMonitor(t, poolID, monitorID) - - // disassociate health monitor - disassociateMonitor(t, poolID, monitorID) - - // delete pool - DeletePool(t, poolID) - - // teardown - DeleteTopology(t, networkID) -} - -func listPools(t *testing.T) { - err := pools.List(base.Client, pools.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - poolList, err := pools.ExtractPools(page) - if err != nil { - t.Errorf("Failed to extract pools: %v", err) - return false, err - } - - for _, p := range poolList { - t.Logf("Listing pool: ID [%s] Name [%s] Status [%s] LB algorithm [%s]", p.ID, p.Name, p.Status, p.LBMethod) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func updatePool(t *testing.T, poolID string) { - opts := pools.UpdateOpts{Name: "SuperPool", LBMethod: pools.LBMethodLeastConnections} - p, err := pools.Update(base.Client, poolID, opts).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Updated pool ID [%s]", p.ID) -} - -func getPool(t *testing.T, poolID string) { - p, err := pools.Get(base.Client, poolID).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Getting pool ID [%s]", p.ID) -} - -func associateMonitor(t *testing.T, poolID, monitorID string) { - res := pools.AssociateMonitor(base.Client, poolID, monitorID) - - th.AssertNoErr(t, res.Err) - - t.Logf("Associated pool %s with monitor %s", poolID, monitorID) -} - -func disassociateMonitor(t *testing.T, poolID, monitorID string) { - res := pools.DisassociateMonitor(base.Client, poolID, monitorID) - - th.AssertNoErr(t, res.Err) - - t.Logf("Disassociated pool %s with monitor %s", poolID, monitorID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/vip_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/vip_test.go deleted file mode 100644 index c8dff2d93f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/lbaas/vip_test.go +++ /dev/null @@ -1,101 +0,0 @@ -// +build acceptance networking lbaas lbaasvip - -package lbaas - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestVIPs(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // setup - networkID, subnetID := SetupTopology(t) - poolID := CreatePool(t, subnetID) - - // create VIP - VIPID := createVIP(t, subnetID, poolID) - - // list VIPs - listVIPs(t) - - // update VIP - updateVIP(t, VIPID) - - // get VIP - getVIP(t, VIPID) - - // delete VIP - deleteVIP(t, VIPID) - - // teardown - DeletePool(t, poolID) - DeleteTopology(t, networkID) -} - -func createVIP(t *testing.T, subnetID, poolID string) string { - p, err := vips.Create(base.Client, vips.CreateOpts{ - Protocol: "HTTP", - Name: "New_VIP", - AdminStateUp: vips.Up, - SubnetID: subnetID, - PoolID: poolID, - ProtocolPort: 80, - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Created pool %s", p.ID) - - return p.ID -} - -func listVIPs(t *testing.T) { - err := vips.List(base.Client, vips.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - vipList, err := vips.ExtractVIPs(page) - if err != nil { - t.Errorf("Failed to extract VIPs: %v", err) - return false, err - } - - for _, vip := range vipList { - t.Logf("Listing VIP: ID [%s] Name [%s] Address [%s] Port [%s] Connection Limit [%d]", - vip.ID, vip.Name, vip.Address, vip.ProtocolPort, vip.ConnLimit) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func updateVIP(t *testing.T, VIPID string) { - i1000 := 1000 - _, err := vips.Update(base.Client, VIPID, vips.UpdateOpts{ConnLimit: &i1000}).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Updated VIP ID [%s]", VIPID) -} - -func getVIP(t *testing.T, VIPID string) { - vip, err := vips.Get(base.Client, VIPID).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Getting VIP ID [%s]: Status [%s]", vip.ID, vip.Status) -} - -func deleteVIP(t *testing.T, VIPID string) { - res := vips.Delete(base.Client, VIPID) - - th.AssertNoErr(t, res.Err) - - t.Logf("Deleted VIP %s", VIPID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/pkg.go deleted file mode 100644 index aeec0fa756..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package extensions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/provider_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/provider_test.go deleted file mode 100644 index f10c9d9bd1..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/provider_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// +build acceptance networking - -package extensions - -import ( - "strconv" - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestNetworkCRUDOperations(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // Create a network - n, err := networks.Create(base.Client, networks.CreateOpts{Name: "sample_network", AdminStateUp: networks.Up}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, n.Name, "sample_network") - th.AssertEquals(t, n.AdminStateUp, true) - networkID := n.ID - - // List networks - pager := networks.List(base.Client, networks.ListOpts{Limit: 2}) - err = pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - networkList, err := networks.ExtractNetworks(page) - th.AssertNoErr(t, err) - - for _, n := range networkList { - t.Logf("Network: ID [%s] Name [%s] Status [%s] Is shared? [%s]", - n.ID, n.Name, n.Status, strconv.FormatBool(n.Shared)) - } - - return true, nil - }) - th.CheckNoErr(t, err) - - // Get a network - if networkID == "" { - t.Fatalf("In order to retrieve a network, the NetworkID must be set") - } - n, err = networks.Get(base.Client, networkID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.Subnets, []string{}) - th.AssertEquals(t, n.Name, "sample_network") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.Shared, false) - th.AssertEquals(t, n.ID, networkID) - - // Update network - n, err = networks.Update(base.Client, networkID, networks.UpdateOpts{Name: "new_network_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, n.Name, "new_network_name") - - // Delete network - res := networks.Delete(base.Client, networkID) - th.AssertNoErr(t, res.Err) -} - -func TestCreateMultipleNetworks(t *testing.T) { - //networks.CreateMany() -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/security_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/security_test.go deleted file mode 100644 index 7d75292f0d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/extensions/security_test.go +++ /dev/null @@ -1,171 +0,0 @@ -// +build acceptance networking security - -package extensions - -import ( - "testing" - - base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/openstack/networking/v2/ports" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestSecurityGroups(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // create security group - groupID := createSecGroup(t) - - // delete security group - defer deleteSecGroup(t, groupID) - - // list security group - listSecGroups(t) - - // get security group - getSecGroup(t, groupID) - - // create port with security group - networkID, portID := createPort(t, groupID) - - // teardown - defer deleteNetwork(t, networkID) - - // delete port - defer deletePort(t, portID) -} - -func TestSecurityGroupRules(t *testing.T) { - base.Setup(t) - defer base.Teardown() - - // create security group - groupID := createSecGroup(t) - - defer deleteSecGroup(t, groupID) - - // create security group rule - ruleID := createSecRule(t, groupID) - - // delete security group rule - defer deleteSecRule(t, ruleID) - - // list security group rule - listSecRules(t) - - // get security group rule - getSecRule(t, ruleID) -} - -func createSecGroup(t *testing.T) string { - sg, err := groups.Create(base.Client, groups.CreateOpts{ - Name: "new-webservers", - Description: "security group for webservers", - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Created security group %s", sg.ID) - - return sg.ID -} - -func listSecGroups(t *testing.T) { - err := groups.List(base.Client, groups.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - list, err := groups.ExtractGroups(page) - if err != nil { - t.Errorf("Failed to extract secgroups: %v", err) - return false, err - } - - for _, sg := range list { - t.Logf("Listing security group: ID [%s] Name [%s]", sg.ID, sg.Name) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func getSecGroup(t *testing.T, id string) { - sg, err := groups.Get(base.Client, id).Extract() - th.AssertNoErr(t, err) - t.Logf("Getting security group: ID [%s] Name [%s] Description [%s]", sg.ID, sg.Name, sg.Description) -} - -func createPort(t *testing.T, groupID string) (string, string) { - n, err := networks.Create(base.Client, networks.CreateOpts{Name: "tmp_network"}).Extract() - th.AssertNoErr(t, err) - t.Logf("Created network %s", n.ID) - - opts := ports.CreateOpts{ - NetworkID: n.ID, - Name: "my_port", - SecurityGroups: []string{groupID}, - } - p, err := ports.Create(base.Client, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Created port %s with security group %s", p.ID, groupID) - - return n.ID, p.ID -} - -func deleteSecGroup(t *testing.T, groupID string) { - res := groups.Delete(base.Client, groupID) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted security group %s", groupID) -} - -func createSecRule(t *testing.T, groupID string) string { - r, err := rules.Create(base.Client, rules.CreateOpts{ - Direction: "ingress", - PortRangeMin: 80, - EtherType: "IPv4", - PortRangeMax: 80, - Protocol: "tcp", - SecGroupID: groupID, - }).Extract() - - th.AssertNoErr(t, err) - - t.Logf("Created security group rule %s", r.ID) - - return r.ID -} - -func listSecRules(t *testing.T) { - err := rules.List(base.Client, rules.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - list, err := rules.ExtractRules(page) - if err != nil { - t.Errorf("Failed to extract sec rules: %v", err) - return false, err - } - - for _, r := range list { - t.Logf("Listing security rule: ID [%s]", r.ID) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func getSecRule(t *testing.T, id string) { - r, err := rules.Get(base.Client, id).Extract() - th.AssertNoErr(t, err) - t.Logf("Getting security rule: ID [%s] Direction [%s] EtherType [%s] Protocol [%s]", - r.ID, r.Direction, r.EtherType, r.Protocol) -} - -func deleteSecRule(t *testing.T, id string) { - res := rules.Delete(base.Client, id) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted security rule %s", id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/network_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/network_test.go deleted file mode 100644 index be8a3a195a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/network_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "strconv" - "testing" - - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestNetworkCRUDOperations(t *testing.T) { - Setup(t) - defer Teardown() - - // Create a network - n, err := networks.Create(Client, networks.CreateOpts{Name: "sample_network", AdminStateUp: networks.Up}).Extract() - th.AssertNoErr(t, err) - defer networks.Delete(Client, n.ID) - th.AssertEquals(t, n.Name, "sample_network") - th.AssertEquals(t, n.AdminStateUp, true) - networkID := n.ID - - // List networks - pager := networks.List(Client, networks.ListOpts{Limit: 2}) - err = pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - networkList, err := networks.ExtractNetworks(page) - th.AssertNoErr(t, err) - - for _, n := range networkList { - t.Logf("Network: ID [%s] Name [%s] Status [%s] Is shared? [%s]", - n.ID, n.Name, n.Status, strconv.FormatBool(n.Shared)) - } - - return true, nil - }) - th.CheckNoErr(t, err) - - // Get a network - if networkID == "" { - t.Fatalf("In order to retrieve a network, the NetworkID must be set") - } - n, err = networks.Get(Client, networkID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.Subnets, []string{}) - th.AssertEquals(t, n.Name, "sample_network") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.Shared, false) - th.AssertEquals(t, n.ID, networkID) - - // Update network - n, err = networks.Update(Client, networkID, networks.UpdateOpts{Name: "new_network_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, n.Name, "new_network_name") - - // Delete network - res := networks.Delete(Client, networkID) - th.AssertNoErr(t, res.Err) -} - -func TestCreateMultipleNetworks(t *testing.T) { - //networks.CreateMany() -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/pkg.go deleted file mode 100644 index 5ec3cc8e83..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package v2 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/port_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/port_test.go deleted file mode 100644 index 03e8e27842..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/port_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/openstack/networking/v2/ports" - "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestPortCRUD(t *testing.T) { - Setup(t) - defer Teardown() - - // Setup network - t.Log("Setting up network") - networkID, err := createNetwork() - th.AssertNoErr(t, err) - defer networks.Delete(Client, networkID) - - // Setup subnet - t.Logf("Setting up subnet on network %s", networkID) - subnetID, err := createSubnet(networkID) - th.AssertNoErr(t, err) - defer subnets.Delete(Client, subnetID) - - // Create port - t.Logf("Create port based on subnet %s", subnetID) - portID := createPort(t, networkID, subnetID) - - // List ports - t.Logf("Listing all ports") - listPorts(t) - - // Get port - if portID == "" { - t.Fatalf("In order to retrieve a port, the portID must be set") - } - p, err := ports.Get(Client, portID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, p.ID, portID) - - // Update port - p, err = ports.Update(Client, portID, ports.UpdateOpts{Name: "new_port_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, p.Name, "new_port_name") - - // Delete port - res := ports.Delete(Client, portID) - th.AssertNoErr(t, res.Err) -} - -func createPort(t *testing.T, networkID, subnetID string) string { - enable := false - opts := ports.CreateOpts{ - NetworkID: networkID, - Name: "my_port", - AdminStateUp: &enable, - FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}}, - } - p, err := ports.Create(Client, opts).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, p.NetworkID, networkID) - th.AssertEquals(t, p.Name, "my_port") - th.AssertEquals(t, p.AdminStateUp, false) - - return p.ID -} - -func listPorts(t *testing.T) { - count := 0 - pager := ports.List(Client, ports.ListOpts{}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - count++ - t.Logf("--- Page ---") - - portList, err := ports.ExtractPorts(page) - th.AssertNoErr(t, err) - - for _, p := range portList { - t.Logf("Port: ID [%s] Name [%s] Status [%s] MAC addr [%s] Fixed IPs [%#v] Security groups [%#v]", - p.ID, p.Name, p.Status, p.MACAddress, p.FixedIPs, p.SecurityGroups) - } - - return true, nil - }) - - th.CheckNoErr(t, err) - - if count == 0 { - t.Logf("No pages were iterated over when listing ports") - } -} - -func createNetwork() (string, error) { - res, err := networks.Create(Client, networks.CreateOpts{Name: "tmp_network", AdminStateUp: networks.Up}).Extract() - return res.ID, err -} - -func createSubnet(networkID string) (string, error) { - s, err := subnets.Create(Client, subnets.CreateOpts{ - NetworkID: networkID, - CIDR: "192.168.199.0/24", - IPVersion: subnets.IPv4, - Name: "my_subnet", - EnableDHCP: subnets.Down, - }).Extract() - return s.ID, err -} - -func TestPortBatchCreate(t *testing.T) { - // todo -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/subnet_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/subnet_test.go deleted file mode 100644 index 097a303ede..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/networking/v2/subnet_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - Setup(t) - defer Teardown() - - pager := subnets.List(Client, subnets.ListOpts{Limit: 2}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - subnetList, err := subnets.ExtractSubnets(page) - th.AssertNoErr(t, err) - - for _, s := range subnetList { - t.Logf("Subnet: ID [%s] Name [%s] IP Version [%d] CIDR [%s] GatewayIP [%s]", - s.ID, s.Name, s.IPVersion, s.CIDR, s.GatewayIP) - } - - return true, nil - }) - th.CheckNoErr(t, err) -} - -func TestCRUD(t *testing.T) { - Setup(t) - defer Teardown() - - // Setup network - t.Log("Setting up network") - n, err := networks.Create(Client, networks.CreateOpts{Name: "tmp_network", AdminStateUp: networks.Up}).Extract() - th.AssertNoErr(t, err) - networkID := n.ID - defer networks.Delete(Client, networkID) - - // Create subnet - t.Log("Create subnet") - enable := false - opts := subnets.CreateOpts{ - NetworkID: networkID, - CIDR: "192.168.199.0/24", - IPVersion: subnets.IPv4, - Name: "my_subnet", - EnableDHCP: &enable, - } - s, err := subnets.Create(Client, opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.NetworkID, networkID) - th.AssertEquals(t, s.CIDR, "192.168.199.0/24") - th.AssertEquals(t, s.IPVersion, 4) - th.AssertEquals(t, s.Name, "my_subnet") - th.AssertEquals(t, s.EnableDHCP, false) - subnetID := s.ID - - // Get subnet - t.Log("Getting subnet") - s, err = subnets.Get(Client, subnetID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, s.ID, subnetID) - - // Update subnet - t.Log("Update subnet") - s, err = subnets.Update(Client, subnetID, subnets.UpdateOpts{Name: "new_subnet_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, s.Name, "new_subnet_name") - - // Delete subnet - t.Log("Delete subnet") - res := subnets.Delete(Client, subnetID) - th.AssertNoErr(t, res.Err) -} - -func TestBatchCreate(t *testing.T) { - // todo -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/accounts_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/accounts_test.go deleted file mode 100644 index f7c01a7c11..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/accounts_test.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "strings" - "testing" - - "github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAccounts(t *testing.T) { - // Create a provider client for making the HTTP requests. - // See common.go in this directory for more information. - client := newClient(t) - - // Update an account's metadata. - updateres := accounts.Update(client, accounts.UpdateOpts{Metadata: metadata}) - th.AssertNoErr(t, updateres.Err) - - // Defer the deletion of the metadata set above. - defer func() { - tempMap := make(map[string]string) - for k := range metadata { - tempMap[k] = "" - } - updateres = accounts.Update(client, accounts.UpdateOpts{Metadata: tempMap}) - th.AssertNoErr(t, updateres.Err) - }() - - // Retrieve account metadata. - getres := accounts.Get(client, nil) - th.AssertNoErr(t, getres.Err) - // Extract the custom metadata from the 'Get' response. - am, err := getres.ExtractMetadata() - th.AssertNoErr(t, err) - for k := range metadata { - if am[k] != metadata[strings.Title(k)] { - t.Errorf("Expected custom metadata with key: %s", k) - return - } - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/common.go deleted file mode 100644 index 1eac681b57..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/common.go +++ /dev/null @@ -1,28 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - th "github.com/rackspace/gophercloud/testhelper" -) - -var metadata = map[string]string{"gopher": "cloud"} - -func newClient(t *testing.T) *gophercloud.ServiceClient { - ao, err := openstack.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - - client, err := openstack.AuthenticatedClient(ao) - th.AssertNoErr(t, err) - - c, err := openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) - th.AssertNoErr(t, err) - return c -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/containers_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/containers_test.go deleted file mode 100644 index d6832f1914..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/containers_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "strings" - "testing" - - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -// numContainers is the number of containers to create for testing. -var numContainers = 2 - -func TestContainers(t *testing.T) { - // Create a new client to execute the HTTP requests. See common.go for newClient body. - client := newClient(t) - - // Create a slice of random container names. - cNames := make([]string, numContainers) - for i := 0; i < numContainers; i++ { - cNames[i] = tools.RandomString("gophercloud-test-container-", 8) - } - - // Create numContainers containers. - for i := 0; i < len(cNames); i++ { - res := containers.Create(client, cNames[i], nil) - th.AssertNoErr(t, res.Err) - } - // Delete the numContainers containers after function completion. - defer func() { - for i := 0; i < len(cNames); i++ { - res := containers.Delete(client, cNames[i]) - th.AssertNoErr(t, res.Err) - } - }() - - // List the numContainer names that were just created. To just list those, - // the 'prefix' parameter is used. - err := containers.List(client, &containers.ListOpts{Full: true, Prefix: "gophercloud-test-container-"}).EachPage(func(page pagination.Page) (bool, error) { - containerList, err := containers.ExtractInfo(page) - th.AssertNoErr(t, err) - - for _, n := range containerList { - t.Logf("Container: Name [%s] Count [%d] Bytes [%d]", - n.Name, n.Count, n.Bytes) - } - - return true, nil - }) - th.AssertNoErr(t, err) - - // List the info for the numContainer containers that were created. - err = containers.List(client, &containers.ListOpts{Full: false, Prefix: "gophercloud-test-container-"}).EachPage(func(page pagination.Page) (bool, error) { - containerList, err := containers.ExtractNames(page) - th.AssertNoErr(t, err) - for _, n := range containerList { - t.Logf("Container: Name [%s]", n) - } - - return true, nil - }) - th.AssertNoErr(t, err) - - // Update one of the numContainer container metadata. - updateres := containers.Update(client, cNames[0], &containers.UpdateOpts{Metadata: metadata}) - th.AssertNoErr(t, updateres.Err) - // After the tests are done, delete the metadata that was set. - defer func() { - tempMap := make(map[string]string) - for k := range metadata { - tempMap[k] = "" - } - res := containers.Update(client, cNames[0], &containers.UpdateOpts{Metadata: tempMap}) - th.AssertNoErr(t, res.Err) - }() - - // Retrieve a container's metadata. - cm, err := containers.Get(client, cNames[0]).ExtractMetadata() - th.AssertNoErr(t, err) - for k := range metadata { - if cm[k] != metadata[strings.Title(k)] { - t.Errorf("Expected custom metadata with key: %s", k) - } - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/objects_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/objects_test.go deleted file mode 100644 index a8de338c3d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/objectstorage/v1/objects_test.go +++ /dev/null @@ -1,119 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "bytes" - "strings" - "testing" - - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -// numObjects is the number of objects to create for testing. -var numObjects = 2 - -func TestObjects(t *testing.T) { - // Create a provider client for executing the HTTP request. - // See common.go for more information. - client := newClient(t) - - // Make a slice of length numObjects to hold the random object names. - oNames := make([]string, numObjects) - for i := 0; i < len(oNames); i++ { - oNames[i] = tools.RandomString("test-object-", 8) - } - - // Create a container to hold the test objects. - cName := tools.RandomString("test-container-", 8) - header, err := containers.Create(client, cName, nil).ExtractHeader() - th.AssertNoErr(t, err) - t.Logf("Create object headers: %+v\n", header) - - // Defer deletion of the container until after testing. - defer func() { - res := containers.Delete(client, cName) - th.AssertNoErr(t, res.Err) - }() - - // Create a slice of buffers to hold the test object content. - oContents := make([]*bytes.Buffer, numObjects) - for i := 0; i < numObjects; i++ { - oContents[i] = bytes.NewBuffer([]byte(tools.RandomString("", 10))) - res := objects.Create(client, cName, oNames[i], oContents[i], nil) - th.AssertNoErr(t, res.Err) - } - // Delete the objects after testing. - defer func() { - for i := 0; i < numObjects; i++ { - res := objects.Delete(client, cName, oNames[i], nil) - th.AssertNoErr(t, res.Err) - } - }() - - ons := make([]string, 0, len(oNames)) - err = objects.List(client, cName, &objects.ListOpts{Full: false, Prefix: "test-object-"}).EachPage(func(page pagination.Page) (bool, error) { - names, err := objects.ExtractNames(page) - th.AssertNoErr(t, err) - ons = append(ons, names...) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, len(ons), len(oNames)) - - ois := make([]objects.Object, 0, len(oNames)) - err = objects.List(client, cName, &objects.ListOpts{Full: true, Prefix: "test-object-"}).EachPage(func(page pagination.Page) (bool, error) { - info, err := objects.ExtractInfo(page) - th.AssertNoErr(t, err) - - ois = append(ois, info...) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, len(ois), len(oNames)) - - // Copy the contents of one object to another. - copyres := objects.Copy(client, cName, oNames[0], &objects.CopyOpts{Destination: cName + "/" + oNames[1]}) - th.AssertNoErr(t, copyres.Err) - - // Download one of the objects that was created above. - o1Content, err := objects.Download(client, cName, oNames[0], nil).ExtractContent() - th.AssertNoErr(t, err) - - // Download the another object that was create above. - o2Content, err := objects.Download(client, cName, oNames[1], nil).ExtractContent() - th.AssertNoErr(t, err) - - // Compare the two object's contents to test that the copy worked. - th.AssertEquals(t, string(o2Content), string(o1Content)) - - // Update an object's metadata. - updateres := objects.Update(client, cName, oNames[0], &objects.UpdateOpts{Metadata: metadata}) - th.AssertNoErr(t, updateres.Err) - - // Delete the object's metadata after testing. - defer func() { - tempMap := make(map[string]string) - for k := range metadata { - tempMap[k] = "" - } - res := objects.Update(client, cName, oNames[0], &objects.UpdateOpts{Metadata: tempMap}) - th.AssertNoErr(t, res.Err) - }() - - // Retrieve an object's metadata. - om, err := objects.Get(client, cName, oNames[0], nil).ExtractMetadata() - th.AssertNoErr(t, err) - for k := range metadata { - if om[k] != metadata[strings.Title(k)] { - t.Errorf("Expected custom metadata with key: %s", k) - return - } - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/pkg.go deleted file mode 100644 index 3a8ecdb100..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/pkg.go +++ /dev/null @@ -1,4 +0,0 @@ -// +build acceptance - -package openstack - diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/common.go deleted file mode 100644 index e9fdd99205..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/common.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build acceptance - -package v1 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/rackspace" - th "github.com/rackspace/gophercloud/testhelper" -) - -func newClient() (*gophercloud.ServiceClient, error) { - opts, err := rackspace.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - opts = tools.OnlyRS(opts) - region := os.Getenv("RS_REGION") - - provider, err := rackspace.AuthenticatedClient(opts) - if err != nil { - return nil, err - } - - return rackspace.NewBlockStorageV1(provider, gophercloud.EndpointOpts{ - Region: region, - }) -} - -func setup(t *testing.T) *gophercloud.ServiceClient { - client, err := newClient() - th.AssertNoErr(t, err) - - return client -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/snapshot_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/snapshot_test.go deleted file mode 100644 index 25b2cfeeeb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/snapshot_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// +build acceptance blockstorage snapshots - -package v1 - -import ( - "testing" - "time" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestSnapshots(t *testing.T) { - client := setup(t) - volID := testVolumeCreate(t, client) - - t.Log("Creating snapshots") - s := testSnapshotCreate(t, client, volID) - id := s.ID - - t.Log("Listing snapshots") - testSnapshotList(t, client) - - t.Logf("Getting snapshot %s", id) - testSnapshotGet(t, client, id) - - t.Logf("Updating snapshot %s", id) - testSnapshotUpdate(t, client, id) - - t.Logf("Deleting snapshot %s", id) - testSnapshotDelete(t, client, id) - s.WaitUntilDeleted(client, -1) - - t.Logf("Deleting volume %s", volID) - testVolumeDelete(t, client, volID) -} - -func testSnapshotCreate(t *testing.T, client *gophercloud.ServiceClient, volID string) *snapshots.Snapshot { - opts := snapshots.CreateOpts{VolumeID: volID, Name: "snapshot-001"} - s, err := snapshots.Create(client, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Created snapshot %s", s.ID) - - t.Logf("Waiting for new snapshot to become available...") - start := time.Now().Second() - s.WaitUntilComplete(client, -1) - t.Logf("Snapshot completed after %ds", time.Now().Second()-start) - - return s -} - -func testSnapshotList(t *testing.T, client *gophercloud.ServiceClient) { - snapshots.List(client).EachPage(func(page pagination.Page) (bool, error) { - sList, err := snapshots.ExtractSnapshots(page) - th.AssertNoErr(t, err) - - for _, s := range sList { - t.Logf("Snapshot: ID [%s] Name [%s] Volume ID [%s] Progress [%s] Created [%s]", - s.ID, s.Name, s.VolumeID, s.Progress, s.CreatedAt) - } - - return true, nil - }) -} - -func testSnapshotGet(t *testing.T, client *gophercloud.ServiceClient, id string) { - _, err := snapshots.Get(client, id).Extract() - th.AssertNoErr(t, err) -} - -func testSnapshotUpdate(t *testing.T, client *gophercloud.ServiceClient, id string) { - _, err := snapshots.Update(client, id, snapshots.UpdateOpts{Name: "new_name"}).Extract() - th.AssertNoErr(t, err) -} - -func testSnapshotDelete(t *testing.T, client *gophercloud.ServiceClient, id string) { - res := snapshots.Delete(client, id) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted snapshot %s", id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/volume_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/volume_test.go deleted file mode 100644 index f86f9adedd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/volume_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// +build acceptance blockstorage volumes - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestVolumes(t *testing.T) { - client := setup(t) - - t.Logf("Listing volumes") - testVolumeList(t, client) - - t.Logf("Creating volume") - volumeID := testVolumeCreate(t, client) - - t.Logf("Getting volume %s", volumeID) - testVolumeGet(t, client, volumeID) - - t.Logf("Updating volume %s", volumeID) - testVolumeUpdate(t, client, volumeID) - - t.Logf("Deleting volume %s", volumeID) - testVolumeDelete(t, client, volumeID) -} - -func testVolumeList(t *testing.T, client *gophercloud.ServiceClient) { - volumes.List(client).EachPage(func(page pagination.Page) (bool, error) { - vList, err := volumes.ExtractVolumes(page) - th.AssertNoErr(t, err) - - for _, v := range vList { - t.Logf("Volume: ID [%s] Name [%s] Type [%s] Created [%s]", v.ID, v.Name, - v.VolumeType, v.CreatedAt) - } - - return true, nil - }) -} - -func testVolumeCreate(t *testing.T, client *gophercloud.ServiceClient) string { - vol, err := volumes.Create(client, os.CreateOpts{Size: 75}).Extract() - th.AssertNoErr(t, err) - t.Logf("Created volume: ID [%s] Size [%s]", vol.ID, vol.Size) - return vol.ID -} - -func testVolumeGet(t *testing.T, client *gophercloud.ServiceClient, id string) { - vol, err := volumes.Get(client, id).Extract() - th.AssertNoErr(t, err) - t.Logf("Created volume: ID [%s] Size [%s]", vol.ID, vol.Size) -} - -func testVolumeUpdate(t *testing.T, client *gophercloud.ServiceClient, id string) { - vol, err := volumes.Update(client, id, volumes.UpdateOpts{Name: "new_name"}).Extract() - th.AssertNoErr(t, err) - t.Logf("Created volume: ID [%s] Name [%s]", vol.ID, vol.Name) -} - -func testVolumeDelete(t *testing.T, client *gophercloud.ServiceClient, id string) { - res := volumes.Delete(client, id) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted volume %s", id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/volume_type_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/volume_type_test.go deleted file mode 100644 index 716f2b9fd5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/blockstorage/v1/volume_type_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build acceptance blockstorage volumetypes - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAll(t *testing.T) { - client := setup(t) - - t.Logf("Listing volume types") - id := testList(t, client) - - t.Logf("Getting volume type %s", id) - testGet(t, client, id) -} - -func testList(t *testing.T, client *gophercloud.ServiceClient) string { - var lastID string - - volumetypes.List(client).EachPage(func(page pagination.Page) (bool, error) { - typeList, err := volumetypes.ExtractVolumeTypes(page) - th.AssertNoErr(t, err) - - for _, vt := range typeList { - t.Logf("Volume type: ID [%s] Name [%s]", vt.ID, vt.Name) - lastID = vt.ID - } - - return true, nil - }) - - return lastID -} - -func testGet(t *testing.T, client *gophercloud.ServiceClient, id string) { - vt, err := volumetypes.Get(client, id).Extract() - th.AssertNoErr(t, err) - t.Logf("Volume: ID [%s] Name [%s]", vt.ID, vt.Name) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/client_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/client_test.go deleted file mode 100644 index 61214c047a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/client_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// +build acceptance - -package rackspace - -import ( - "testing" - - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/rackspace" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAuthenticatedClient(t *testing.T) { - // Obtain credentials from the environment. - ao, err := rackspace.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - - client, err := rackspace.AuthenticatedClient(tools.OnlyRS(ao)) - if err != nil { - t.Fatalf("Unable to authenticate: %v", err) - } - - if client.TokenID == "" { - t.Errorf("No token ID assigned to the client") - } - - t.Logf("Client successfully acquired a token: %v", client.TokenID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/bootfromvolume_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/bootfromvolume_test.go deleted file mode 100644 index c8c8e21058..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/bootfromvolume_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/acceptance/tools" - osBFV "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume" - "github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume" - "github.com/rackspace/gophercloud/rackspace/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestBootFromVolume(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - if testing.Short() { - t.Skip("Skipping test that requires server creation in short mode.") - } - - options, err := optionsFromEnv() - th.AssertNoErr(t, err) - - name := tools.RandomString("Gophercloud-", 8) - t.Logf("Creating server [%s].", name) - - bd := []osBFV.BlockDevice{ - osBFV.BlockDevice{ - UUID: options.imageID, - SourceType: osBFV.Image, - VolumeSize: 10, - }, - } - - server, err := bootfromvolume.Create(client, servers.CreateOpts{ - Name: name, - FlavorRef: "performance1-1", - BlockDevice: bd, - }).Extract() - th.AssertNoErr(t, err) - t.Logf("Created server: %+v\n", server) - //defer deleteServer(t, client, server) - t.Logf("Deleting server [%s]...", name) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/compute_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/compute_test.go deleted file mode 100644 index 3ca6dc9b6c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/compute_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "errors" - "os" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/rackspace" -) - -func newClient() (*gophercloud.ServiceClient, error) { - // Obtain credentials from the environment. - options, err := rackspace.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - options = tools.OnlyRS(options) - region := os.Getenv("RS_REGION") - - if options.Username == "" { - return nil, errors.New("Please provide a Rackspace username as RS_USERNAME.") - } - if options.APIKey == "" { - return nil, errors.New("Please provide a Rackspace API key as RS_API_KEY.") - } - if region == "" { - return nil, errors.New("Please provide a Rackspace region as RS_REGION.") - } - - client, err := rackspace.AuthenticatedClient(options) - if err != nil { - return nil, err - } - - return rackspace.NewComputeV2(client, gophercloud.EndpointOpts{ - Region: region, - }) -} - -type serverOpts struct { - imageID string - flavorID string -} - -func optionsFromEnv() (*serverOpts, error) { - options := &serverOpts{ - imageID: os.Getenv("RS_IMAGE_ID"), - flavorID: os.Getenv("RS_FLAVOR_ID"), - } - if options.imageID == "" { - return nil, errors.New("Please provide a valid Rackspace image ID as RS_IMAGE_ID") - } - if options.flavorID == "" { - return nil, errors.New("Please provide a valid Rackspace flavor ID as RS_FLAVOR_ID") - } - return options, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/flavors_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/flavors_test.go deleted file mode 100644 index 4618ecc8a9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/flavors_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/flavors" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListFlavors(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - count := 0 - err = flavors.ListDetail(client, nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - t.Logf("-- Page %0d --", count) - - fs, err := flavors.ExtractFlavors(page) - th.AssertNoErr(t, err) - - for i, flavor := range fs { - t.Logf("[%02d] id=[%s]", i, flavor.ID) - t.Logf(" name=[%s]", flavor.Name) - t.Logf(" disk=[%d]", flavor.Disk) - t.Logf(" RAM=[%d]", flavor.RAM) - t.Logf(" rxtx_factor=[%f]", flavor.RxTxFactor) - t.Logf(" swap=[%d]", flavor.Swap) - t.Logf(" VCPUs=[%d]", flavor.VCPUs) - } - - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No flavors listed!") - } -} - -func TestGetFlavor(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - options, err := optionsFromEnv() - th.AssertNoErr(t, err) - - flavor, err := flavors.Get(client, options.flavorID).Extract() - th.AssertNoErr(t, err) - - t.Logf("Requested flavor:") - t.Logf(" id=[%s]", flavor.ID) - t.Logf(" name=[%s]", flavor.Name) - t.Logf(" disk=[%d]", flavor.Disk) - t.Logf(" RAM=[%d]", flavor.RAM) - t.Logf(" rxtx_factor=[%f]", flavor.RxTxFactor) - t.Logf(" swap=[%d]", flavor.Swap) - t.Logf(" VCPUs=[%d]", flavor.VCPUs) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/images_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/images_test.go deleted file mode 100644 index 5e36c2e454..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/images_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/images" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListImages(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - count := 0 - err = images.ListDetail(client, nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - t.Logf("-- Page %02d --", count) - - is, err := images.ExtractImages(page) - th.AssertNoErr(t, err) - - for i, image := range is { - t.Logf("[%02d] id=[%s]", i, image.ID) - t.Logf(" name=[%s]", image.Name) - t.Logf(" created=[%s]", image.Created) - t.Logf(" updated=[%s]", image.Updated) - t.Logf(" min disk=[%d]", image.MinDisk) - t.Logf(" min RAM=[%d]", image.MinRAM) - t.Logf(" progress=[%d]", image.Progress) - t.Logf(" status=[%s]", image.Status) - } - - return true, nil - }) - th.AssertNoErr(t, err) - if count < 1 { - t.Errorf("Expected at least one page of images.") - } -} - -func TestGetImage(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - options, err := optionsFromEnv() - th.AssertNoErr(t, err) - - image, err := images.Get(client, options.imageID).Extract() - th.AssertNoErr(t, err) - - t.Logf("Requested image:") - t.Logf(" id=[%s]", image.ID) - t.Logf(" name=[%s]", image.Name) - t.Logf(" created=[%s]", image.Created) - t.Logf(" updated=[%s]", image.Updated) - t.Logf(" min disk=[%d]", image.MinDisk) - t.Logf(" min RAM=[%d]", image.MinRAM) - t.Logf(" progress=[%d]", image.Progress) - t.Logf(" status=[%s]", image.Status) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/keypairs_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/keypairs_test.go deleted file mode 100644 index 9bd6eb4284..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/keypairs_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// +build acceptance rackspace - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - os "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs" - th "github.com/rackspace/gophercloud/testhelper" -) - -func deleteKeyPair(t *testing.T, client *gophercloud.ServiceClient, name string) { - err := keypairs.Delete(client, name).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Successfully deleted key [%s].", name) -} - -func TestCreateKeyPair(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - name := tools.RandomString("createdkey-", 8) - k, err := keypairs.Create(client, os.CreateOpts{Name: name}).Extract() - th.AssertNoErr(t, err) - defer deleteKeyPair(t, client, name) - - t.Logf("Created a new keypair:") - t.Logf(" name=[%s]", k.Name) - t.Logf(" fingerprint=[%s]", k.Fingerprint) - t.Logf(" publickey=[%s]", tools.Elide(k.PublicKey)) - t.Logf(" privatekey=[%s]", tools.Elide(k.PrivateKey)) - t.Logf(" userid=[%s]", k.UserID) -} - -func TestImportKeyPair(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - name := tools.RandomString("importedkey-", 8) - pubkey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDlIQ3r+zd97kb9Hzmujd3V6pbO53eb3Go4q2E8iqVGWQfZTrFdL9KACJnqJIm9HmncfRkUTxE37hqeGCCv8uD+ZPmPiZG2E60OX1mGDjbbzAyReRwYWXgXHopggZTLak5k4mwZYaxwaufbVBDRn847e01lZnaXaszEToLM37NLw+uz29sl3TwYy2R0RGHPwPc160aWmdLjSyd1Nd4c9pvvOP/EoEuBjIC6NJJwg2Rvg9sjjx9jYj0QUgc8CqKLN25oMZ69kNJzlFylKRUoeeVr89txlR59yehJWk6Uw6lYFTdJmcmQOFVAJ12RMmS1hLWCM8UzAgtw+EDa0eqBxBDl smash@winter" - - k, err := keypairs.Create(client, os.CreateOpts{ - Name: name, - PublicKey: pubkey, - }).Extract() - th.AssertNoErr(t, err) - defer deleteKeyPair(t, client, name) - - th.CheckEquals(t, pubkey, k.PublicKey) - th.CheckEquals(t, "", k.PrivateKey) - - t.Logf("Imported an existing keypair:") - t.Logf(" name=[%s]", k.Name) - t.Logf(" fingerprint=[%s]", k.Fingerprint) - t.Logf(" publickey=[%s]", tools.Elide(k.PublicKey)) - t.Logf(" privatekey=[%s]", tools.Elide(k.PrivateKey)) - t.Logf(" userid=[%s]", k.UserID) -} - -func TestListKeyPairs(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - count := 0 - err = keypairs.List(client).EachPage(func(page pagination.Page) (bool, error) { - count++ - t.Logf("--- %02d ---", count) - - ks, err := keypairs.ExtractKeyPairs(page) - th.AssertNoErr(t, err) - - for i, keypair := range ks { - t.Logf("[%02d] name=[%s]", i, keypair.Name) - t.Logf(" fingerprint=[%s]", keypair.Fingerprint) - t.Logf(" publickey=[%s]", tools.Elide(keypair.PublicKey)) - t.Logf(" privatekey=[%s]", tools.Elide(keypair.PrivateKey)) - t.Logf(" userid=[%s]", keypair.UserID) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/networks_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/networks_test.go deleted file mode 100644 index e8fc4d37df..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/networks_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// +build acceptance rackspace - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/networks" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestNetworks(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - // Create a network - n, err := networks.Create(client, networks.CreateOpts{Label: "sample_network", CIDR: "172.20.0.0/24"}).Extract() - th.AssertNoErr(t, err) - t.Logf("Created network: %+v\n", n) - defer networks.Delete(client, n.ID) - th.AssertEquals(t, n.Label, "sample_network") - th.AssertEquals(t, n.CIDR, "172.20.0.0/24") - networkID := n.ID - - // List networks - pager := networks.List(client) - err = pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - networkList, err := networks.ExtractNetworks(page) - th.AssertNoErr(t, err) - - for _, n := range networkList { - t.Logf("Network: ID [%s] Label [%s] CIDR [%s]", - n.ID, n.Label, n.CIDR) - } - - return true, nil - }) - th.CheckNoErr(t, err) - - // Get a network - if networkID == "" { - t.Fatalf("In order to retrieve a network, the NetworkID must be set") - } - n, err = networks.Get(client, networkID).Extract() - t.Logf("Retrieved Network: %+v\n", n) - th.AssertNoErr(t, err) - th.AssertEquals(t, n.CIDR, "172.20.0.0/24") - th.AssertEquals(t, n.Label, "sample_network") - th.AssertEquals(t, n.ID, networkID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/pkg.go deleted file mode 100644 index 5ec3cc8e83..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package v2 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/servers_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/servers_test.go deleted file mode 100644 index 81c8599f3d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/servers_test.go +++ /dev/null @@ -1,204 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig" - oskey "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" - os "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs" - "github.com/rackspace/gophercloud/rackspace/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func createServerKeyPair(t *testing.T, client *gophercloud.ServiceClient) *oskey.KeyPair { - name := tools.RandomString("importedkey-", 8) - pubkey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDlIQ3r+zd97kb9Hzmujd3V6pbO53eb3Go4q2E8iqVGWQfZTrFdL9KACJnqJIm9HmncfRkUTxE37hqeGCCv8uD+ZPmPiZG2E60OX1mGDjbbzAyReRwYWXgXHopggZTLak5k4mwZYaxwaufbVBDRn847e01lZnaXaszEToLM37NLw+uz29sl3TwYy2R0RGHPwPc160aWmdLjSyd1Nd4c9pvvOP/EoEuBjIC6NJJwg2Rvg9sjjx9jYj0QUgc8CqKLN25oMZ69kNJzlFylKRUoeeVr89txlR59yehJWk6Uw6lYFTdJmcmQOFVAJ12RMmS1hLWCM8UzAgtw+EDa0eqBxBDl smash@winter" - - k, err := keypairs.Create(client, oskey.CreateOpts{ - Name: name, - PublicKey: pubkey, - }).Extract() - th.AssertNoErr(t, err) - - return k -} - -func createServer(t *testing.T, client *gophercloud.ServiceClient, keyName string) *os.Server { - if testing.Short() { - t.Skip("Skipping test that requires server creation in short mode.") - } - - options, err := optionsFromEnv() - th.AssertNoErr(t, err) - - name := tools.RandomString("Gophercloud-", 8) - - pwd := tools.MakeNewPassword("") - - opts := &servers.CreateOpts{ - Name: name, - ImageRef: options.imageID, - FlavorRef: options.flavorID, - DiskConfig: diskconfig.Manual, - AdminPass: pwd, - } - - if keyName != "" { - opts.KeyPair = keyName - } - - t.Logf("Creating server [%s].", name) - s, err := servers.Create(client, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Creating server.") - - err = servers.WaitForStatus(client, s.ID, "ACTIVE", 300) - th.AssertNoErr(t, err) - t.Logf("Server created successfully.") - - th.CheckEquals(t, pwd, s.AdminPass) - - return s -} - -func logServer(t *testing.T, server *os.Server, index int) { - if index == -1 { - t.Logf(" id=[%s]", server.ID) - } else { - t.Logf("[%02d] id=[%s]", index, server.ID) - } - t.Logf(" name=[%s]", server.Name) - t.Logf(" tenant ID=[%s]", server.TenantID) - t.Logf(" user ID=[%s]", server.UserID) - t.Logf(" updated=[%s]", server.Updated) - t.Logf(" created=[%s]", server.Created) - t.Logf(" host ID=[%s]", server.HostID) - t.Logf(" access IPv4=[%s]", server.AccessIPv4) - t.Logf(" access IPv6=[%s]", server.AccessIPv6) - t.Logf(" image=[%v]", server.Image) - t.Logf(" flavor=[%v]", server.Flavor) - t.Logf(" addresses=[%v]", server.Addresses) - t.Logf(" metadata=[%v]", server.Metadata) - t.Logf(" links=[%v]", server.Links) - t.Logf(" keyname=[%s]", server.KeyName) - t.Logf(" admin password=[%s]", server.AdminPass) - t.Logf(" status=[%s]", server.Status) - t.Logf(" progress=[%d]", server.Progress) -} - -func getServer(t *testing.T, client *gophercloud.ServiceClient, server *os.Server) { - t.Logf("> servers.Get") - - details, err := servers.Get(client, server.ID).Extract() - th.AssertNoErr(t, err) - logServer(t, details, -1) -} - -func listServers(t *testing.T, client *gophercloud.ServiceClient) { - t.Logf("> servers.List") - - count := 0 - err := servers.List(client, nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - t.Logf("--- Page %02d ---", count) - - s, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - for index, server := range s { - logServer(t, &server, index) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func changeAdminPassword(t *testing.T, client *gophercloud.ServiceClient, server *os.Server) { - t.Logf("> servers.ChangeAdminPassword") - - original := server.AdminPass - - t.Logf("Changing server password.") - err := servers.ChangeAdminPassword(client, server.ID, tools.MakeNewPassword(original)).ExtractErr() - th.AssertNoErr(t, err) - - err = servers.WaitForStatus(client, server.ID, "ACTIVE", 300) - th.AssertNoErr(t, err) - t.Logf("Password changed successfully.") -} - -func rebootServer(t *testing.T, client *gophercloud.ServiceClient, server *os.Server) { - t.Logf("> servers.Reboot") - - err := servers.Reboot(client, server.ID, os.HardReboot).ExtractErr() - th.AssertNoErr(t, err) - - err = servers.WaitForStatus(client, server.ID, "ACTIVE", 300) - th.AssertNoErr(t, err) - - t.Logf("Server successfully rebooted.") -} - -func rebuildServer(t *testing.T, client *gophercloud.ServiceClient, server *os.Server) { - t.Logf("> servers.Rebuild") - - options, err := optionsFromEnv() - th.AssertNoErr(t, err) - - opts := servers.RebuildOpts{ - Name: tools.RandomString("RenamedGopher", 16), - AdminPass: tools.MakeNewPassword(server.AdminPass), - ImageID: options.imageID, - DiskConfig: diskconfig.Manual, - } - after, err := servers.Rebuild(client, server.ID, opts).Extract() - th.AssertNoErr(t, err) - th.CheckEquals(t, after.ID, server.ID) - - err = servers.WaitForStatus(client, after.ID, "ACTIVE", 300) - th.AssertNoErr(t, err) - - t.Logf("Server successfully rebuilt.") - logServer(t, after, -1) -} - -func deleteServer(t *testing.T, client *gophercloud.ServiceClient, server *os.Server) { - t.Logf("> servers.Delete") - - res := servers.Delete(client, server.ID) - th.AssertNoErr(t, res.Err) - - t.Logf("Server deleted successfully.") -} - -func deleteServerKeyPair(t *testing.T, client *gophercloud.ServiceClient, k *oskey.KeyPair) { - t.Logf("> keypairs.Delete") - - err := keypairs.Delete(client, k.Name).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Keypair deleted successfully.") -} - -func TestServerOperations(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - kp := createServerKeyPair(t, client) - defer deleteServerKeyPair(t, client, kp) - - server := createServer(t, client, kp.Name) - defer deleteServer(t, client, server) - - getServer(t, client, server) - listServers(t, client) - changeAdminPassword(t, client, server) - rebootServer(t, client, server) - rebuildServer(t, client, server) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/virtualinterfaces_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/virtualinterfaces_test.go deleted file mode 100644 index 39475e176e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/compute/v2/virtualinterfaces_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// +build acceptance rackspace - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/networks" - "github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestVirtualInterfaces(t *testing.T) { - client, err := newClient() - th.AssertNoErr(t, err) - - // Create a server - server := createServer(t, client, "") - t.Logf("Created Server: %v\n", server) - defer deleteServer(t, client, server) - serverID := server.ID - - // Create a network - n, err := networks.Create(client, networks.CreateOpts{Label: "sample_network", CIDR: "172.20.0.0/24"}).Extract() - th.AssertNoErr(t, err) - t.Logf("Created Network: %v\n", n) - defer networks.Delete(client, n.ID) - networkID := n.ID - - // Create a virtual interface - vi, err := virtualinterfaces.Create(client, serverID, networkID).Extract() - th.AssertNoErr(t, err) - t.Logf("Created virtual interface: %+v\n", vi) - defer virtualinterfaces.Delete(client, serverID, vi.ID) - - // List virtual interfaces - pager := virtualinterfaces.List(client, serverID) - err = pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - virtualinterfacesList, err := virtualinterfaces.ExtractVirtualInterfaces(page) - th.AssertNoErr(t, err) - - for _, vi := range virtualinterfacesList { - t.Logf("Virtual Interface: ID [%s] MAC Address [%s] IP Addresses [%v]", - vi.ID, vi.MACAddress, vi.IPAddresses) - } - - return true, nil - }) - th.CheckNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/extension_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/extension_test.go deleted file mode 100644 index a50e015522..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/extension_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - extensions2 "github.com/rackspace/gophercloud/rackspace/identity/v2/extensions" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestExtensions(t *testing.T) { - service := authenticatedClient(t) - - t.Logf("Extensions available on this identity endpoint:") - count := 0 - var chosen string - err := extensions2.List(service).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - extensions, err := extensions2.ExtractExtensions(page) - th.AssertNoErr(t, err) - - for i, ext := range extensions { - if chosen == "" { - chosen = ext.Alias - } - - t.Logf("[%02d] name=[%s] namespace=[%s]", i, ext.Name, ext.Namespace) - t.Logf(" alias=[%s] updated=[%s]", ext.Alias, ext.Updated) - t.Logf(" description=[%s]", ext.Description) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - - if chosen == "" { - t.Logf("No extensions found.") - return - } - - ext, err := extensions2.Get(service, chosen).Extract() - th.AssertNoErr(t, err) - - t.Logf("Detail for extension [%s]:", chosen) - t.Logf(" name=[%s]", ext.Name) - t.Logf(" namespace=[%s]", ext.Namespace) - t.Logf(" alias=[%s]", ext.Alias) - t.Logf(" updated=[%s]", ext.Updated) - t.Logf(" description=[%s]", ext.Description) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/identity_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/identity_test.go deleted file mode 100644 index 1182982f44..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/identity_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/rackspace" - th "github.com/rackspace/gophercloud/testhelper" -) - -func rackspaceAuthOptions(t *testing.T) gophercloud.AuthOptions { - // Obtain credentials from the environment. - options, err := rackspace.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - options = tools.OnlyRS(options) - - if options.Username == "" { - t.Fatal("Please provide a Rackspace username as RS_USERNAME.") - } - if options.APIKey == "" { - t.Fatal("Please provide a Rackspace API key as RS_API_KEY.") - } - - return options -} - -func createClient(t *testing.T, auth bool) *gophercloud.ServiceClient { - ao := rackspaceAuthOptions(t) - - provider, err := rackspace.NewClient(ao.IdentityEndpoint) - th.AssertNoErr(t, err) - - if auth { - err = rackspace.Authenticate(provider, ao) - th.AssertNoErr(t, err) - } - - return rackspace.NewIdentityV2(provider) -} - -func unauthenticatedClient(t *testing.T) *gophercloud.ServiceClient { - return createClient(t, false) -} - -func authenticatedClient(t *testing.T) *gophercloud.ServiceClient { - return createClient(t, true) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/pkg.go deleted file mode 100644 index 5ec3cc8e83..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package v2 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/role_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/role_test.go deleted file mode 100644 index efaeb75cde..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/role_test.go +++ /dev/null @@ -1,59 +0,0 @@ -// +build acceptance identity roles - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles" - - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/identity/v2/roles" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestRoles(t *testing.T) { - client := authenticatedClient(t) - - userID := createUser(t, client) - roleID := listRoles(t, client) - - addUserRole(t, client, userID, roleID) - - deleteUserRole(t, client, userID, roleID) - - deleteUser(t, client, userID) -} - -func listRoles(t *testing.T, client *gophercloud.ServiceClient) string { - var roleID string - - err := roles.List(client).EachPage(func(page pagination.Page) (bool, error) { - roleList, err := os.ExtractRoles(page) - th.AssertNoErr(t, err) - - for _, role := range roleList { - t.Logf("Listing role: ID [%s] Name [%s]", role.ID, role.Name) - roleID = role.ID - } - - return true, nil - }) - - th.AssertNoErr(t, err) - - return roleID -} - -func addUserRole(t *testing.T, client *gophercloud.ServiceClient, userID, roleID string) { - err := roles.AddUserRole(client, userID, roleID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Added role %s to user %s", roleID, userID) -} - -func deleteUserRole(t *testing.T, client *gophercloud.ServiceClient, userID, roleID string) { - err := roles.DeleteUserRole(client, userID, roleID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Removed role %s from user %s", roleID, userID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tenant_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tenant_test.go deleted file mode 100644 index 6081a498e3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tenant_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build acceptance - -package v2 - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - rstenants "github.com/rackspace/gophercloud/rackspace/identity/v2/tenants" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestTenants(t *testing.T) { - service := authenticatedClient(t) - - t.Logf("Tenants available to the currently issued token:") - count := 0 - err := rstenants.List(service, nil).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - tenants, err := rstenants.ExtractTenants(page) - th.AssertNoErr(t, err) - - for i, tenant := range tenants { - t.Logf("[%02d] id=[%s]", i, tenant.ID) - t.Logf(" name=[%s] enabled=[%v]", i, tenant.Name, tenant.Enabled) - t.Logf(" description=[%s]", tenant.Description) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No tenants listed for your current token.") - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/user_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/user_test.go deleted file mode 100644 index 28c0c832be..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/user_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// +build acceptance identity - -package v2 - -import ( - "strconv" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - os "github.com/rackspace/gophercloud/openstack/identity/v2/users" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/identity/v2/users" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestUsers(t *testing.T) { - client := authenticatedClient(t) - - userID := createUser(t, client) - - listUsers(t, client) - - getUser(t, client, userID) - - updateUser(t, client, userID) - - resetApiKey(t, client, userID) - - deleteUser(t, client, userID) -} - -func createUser(t *testing.T, client *gophercloud.ServiceClient) string { - t.Log("Creating user") - - opts := users.CreateOpts{ - Username: tools.RandomString("user_", 5), - Enabled: os.Disabled, - Email: "new_user@foo.com", - } - - user, err := users.Create(client, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Created user %s", user.ID) - - return user.ID -} - -func listUsers(t *testing.T, client *gophercloud.ServiceClient) { - err := users.List(client).EachPage(func(page pagination.Page) (bool, error) { - userList, err := os.ExtractUsers(page) - th.AssertNoErr(t, err) - - for _, user := range userList { - t.Logf("Listing user: ID [%s] Username [%s] Email [%s] Enabled? [%s]", - user.ID, user.Username, user.Email, strconv.FormatBool(user.Enabled)) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func getUser(t *testing.T, client *gophercloud.ServiceClient, userID string) { - _, err := users.Get(client, userID).Extract() - th.AssertNoErr(t, err) - t.Logf("Getting user %s", userID) -} - -func updateUser(t *testing.T, client *gophercloud.ServiceClient, userID string) { - opts := users.UpdateOpts{Username: tools.RandomString("new_name", 5), Email: "new@foo.com"} - user, err := users.Update(client, userID, opts).Extract() - th.AssertNoErr(t, err) - t.Logf("Updated user %s: Username [%s] Email [%s]", userID, user.Username, user.Email) -} - -func deleteUser(t *testing.T, client *gophercloud.ServiceClient, userID string) { - res := users.Delete(client, userID) - th.AssertNoErr(t, res.Err) - t.Logf("Deleted user %s", userID) -} - -func resetApiKey(t *testing.T, client *gophercloud.ServiceClient, userID string) { - key, err := users.ResetAPIKey(client, userID).Extract() - th.AssertNoErr(t, err) - - if key.APIKey == "" { - t.Fatal("failed to reset API key for user") - } - - t.Logf("Reset API key for user %s to %s", key.Username, key.APIKey) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/acl_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/acl_test.go deleted file mode 100644 index 7a380273c6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/acl_test.go +++ /dev/null @@ -1,94 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/lb/v1/acl" - "github.com/rackspace/gophercloud/rackspace/lb/v1/lbs" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestACL(t *testing.T) { - client := setup(t) - - ids := createLB(t, client, 1) - lbID := ids[0] - - createACL(t, client, lbID) - - waitForLB(client, lbID, lbs.ACTIVE) - - networkIDs := showACL(t, client, lbID) - - deleteNetworkItem(t, client, lbID, networkIDs[0]) - waitForLB(client, lbID, lbs.ACTIVE) - - bulkDeleteACL(t, client, lbID, networkIDs[1:2]) - waitForLB(client, lbID, lbs.ACTIVE) - - deleteACL(t, client, lbID) - waitForLB(client, lbID, lbs.ACTIVE) - - deleteLB(t, client, lbID) -} - -func createACL(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - opts := acl.CreateOpts{ - acl.CreateOpt{Address: "206.160.163.21", Type: acl.DENY}, - acl.CreateOpt{Address: "206.160.165.11", Type: acl.DENY}, - acl.CreateOpt{Address: "206.160.165.12", Type: acl.DENY}, - acl.CreateOpt{Address: "206.160.165.13", Type: acl.ALLOW}, - } - - err := acl.Create(client, lbID, opts).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Created ACL items for LB %d", lbID) -} - -func showACL(t *testing.T, client *gophercloud.ServiceClient, lbID int) []int { - ids := []int{} - - err := acl.List(client, lbID).EachPage(func(page pagination.Page) (bool, error) { - accessList, err := acl.ExtractAccessList(page) - th.AssertNoErr(t, err) - - for _, i := range accessList { - t.Logf("Listing network item: ID [%s] Address [%s] Type [%s]", i.ID, i.Address, i.Type) - ids = append(ids, i.ID) - } - - return true, nil - }) - th.AssertNoErr(t, err) - - return ids -} - -func deleteNetworkItem(t *testing.T, client *gophercloud.ServiceClient, lbID, itemID int) { - err := acl.Delete(client, lbID, itemID).ExtractErr() - - th.AssertNoErr(t, err) - - t.Logf("Deleted network item %d", itemID) -} - -func bulkDeleteACL(t *testing.T, client *gophercloud.ServiceClient, lbID int, items []int) { - err := acl.BulkDelete(client, lbID, items).ExtractErr() - - th.AssertNoErr(t, err) - - t.Logf("Deleted network items %s", intsToStr(items)) -} - -func deleteACL(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - err := acl.DeleteAll(client, lbID).ExtractErr() - - th.AssertNoErr(t, err) - - t.Logf("Deleted ACL from LB %d", lbID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/common.go deleted file mode 100644 index 4ce05e69ca..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/common.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "os" - "strconv" - "strings" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/rackspace" - th "github.com/rackspace/gophercloud/testhelper" -) - -func newProvider() (*gophercloud.ProviderClient, error) { - opts, err := rackspace.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - opts = tools.OnlyRS(opts) - - return rackspace.AuthenticatedClient(opts) -} - -func newClient() (*gophercloud.ServiceClient, error) { - provider, err := newProvider() - if err != nil { - return nil, err - } - - return rackspace.NewLBV1(provider, gophercloud.EndpointOpts{ - Region: os.Getenv("RS_REGION"), - }) -} - -func newComputeClient() (*gophercloud.ServiceClient, error) { - provider, err := newProvider() - if err != nil { - return nil, err - } - - return rackspace.NewComputeV2(provider, gophercloud.EndpointOpts{ - Region: os.Getenv("RS_REGION"), - }) -} - -func setup(t *testing.T) *gophercloud.ServiceClient { - client, err := newClient() - th.AssertNoErr(t, err) - - return client -} - -func intsToStr(ids []int) string { - strIDs := []string{} - for _, id := range ids { - strIDs = append(strIDs, strconv.Itoa(id)) - } - return strings.Join(strIDs, ", ") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/lb_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/lb_test.go deleted file mode 100644 index c67ddecad9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/lb_test.go +++ /dev/null @@ -1,214 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "strconv" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/lb/v1/lbs" - "github.com/rackspace/gophercloud/rackspace/lb/v1/vips" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestLBs(t *testing.T) { - client := setup(t) - - ids := createLB(t, client, 3) - id := ids[0] - - listLBProtocols(t, client) - - listLBAlgorithms(t, client) - - listLBs(t, client) - - getLB(t, client, id) - - checkLBLogging(t, client, id) - - checkErrorPage(t, client, id) - - getStats(t, client, id) - - updateLB(t, client, id) - - deleteLB(t, client, id) - - batchDeleteLBs(t, client, ids[1:]) -} - -func createLB(t *testing.T, client *gophercloud.ServiceClient, count int) []int { - ids := []int{} - - for i := 0; i < count; i++ { - opts := lbs.CreateOpts{ - Name: tools.RandomString("test_", 5), - Port: 80, - Protocol: "HTTP", - VIPs: []vips.VIP{ - vips.VIP{Type: vips.PUBLIC}, - }, - } - - lb, err := lbs.Create(client, opts).Extract() - th.AssertNoErr(t, err) - - t.Logf("Created LB %d - waiting for it to build...", lb.ID) - waitForLB(client, lb.ID, lbs.ACTIVE) - t.Logf("LB %d has reached ACTIVE state", lb.ID) - - ids = append(ids, lb.ID) - } - - return ids -} - -func waitForLB(client *gophercloud.ServiceClient, id int, state lbs.Status) { - gophercloud.WaitFor(60, func() (bool, error) { - lb, err := lbs.Get(client, id).Extract() - if err != nil { - return false, err - } - if lb.Status != state { - return false, nil - } - return true, nil - }) -} - -func listLBProtocols(t *testing.T, client *gophercloud.ServiceClient) { - err := lbs.ListProtocols(client).EachPage(func(page pagination.Page) (bool, error) { - pList, err := lbs.ExtractProtocols(page) - th.AssertNoErr(t, err) - - for _, p := range pList { - t.Logf("Listing protocol: Name [%s]", p.Name) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func listLBAlgorithms(t *testing.T, client *gophercloud.ServiceClient) { - err := lbs.ListAlgorithms(client).EachPage(func(page pagination.Page) (bool, error) { - aList, err := lbs.ExtractAlgorithms(page) - th.AssertNoErr(t, err) - - for _, a := range aList { - t.Logf("Listing algorithm: Name [%s]", a.Name) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func listLBs(t *testing.T, client *gophercloud.ServiceClient) { - err := lbs.List(client, lbs.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - lbList, err := lbs.ExtractLBs(page) - th.AssertNoErr(t, err) - - for _, lb := range lbList { - t.Logf("Listing LB: ID [%d] Name [%s] Protocol [%s] Status [%s] Node count [%d] Port [%d]", - lb.ID, lb.Name, lb.Protocol, lb.Status, lb.NodeCount, lb.Port) - } - - return true, nil - }) - - th.AssertNoErr(t, err) -} - -func getLB(t *testing.T, client *gophercloud.ServiceClient, id int) { - lb, err := lbs.Get(client, id).Extract() - th.AssertNoErr(t, err) - t.Logf("Getting LB %d: Created [%s] VIPs [%#v] Logging [%#v] Persistence [%#v] SourceAddrs [%#v]", - lb.ID, lb.Created, lb.VIPs, lb.ConnectionLogging, lb.SessionPersistence, lb.SourceAddrs) -} - -func updateLB(t *testing.T, client *gophercloud.ServiceClient, id int) { - opts := lbs.UpdateOpts{ - Name: tools.RandomString("new_", 5), - Protocol: "TCP", - HalfClosed: gophercloud.Enabled, - Algorithm: "RANDOM", - Port: 8080, - Timeout: 100, - HTTPSRedirect: gophercloud.Disabled, - } - - err := lbs.Update(client, id, opts).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Updating LB %d - waiting for it to finish", id) - waitForLB(client, id, lbs.ACTIVE) - t.Logf("LB %d has reached ACTIVE state", id) -} - -func deleteLB(t *testing.T, client *gophercloud.ServiceClient, id int) { - err := lbs.Delete(client, id).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Deleted LB %d", id) -} - -func batchDeleteLBs(t *testing.T, client *gophercloud.ServiceClient, ids []int) { - err := lbs.BulkDelete(client, ids).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Deleted LB %s", intsToStr(ids)) -} - -func checkLBLogging(t *testing.T, client *gophercloud.ServiceClient, id int) { - err := lbs.EnableLogging(client, id).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Enabled logging for LB %d", id) - - res, err := lbs.IsLoggingEnabled(client, id) - th.AssertNoErr(t, err) - t.Logf("LB %d log enabled? %s", id, strconv.FormatBool(res)) - - waitForLB(client, id, lbs.ACTIVE) - - err = lbs.DisableLogging(client, id).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Disabled logging for LB %d", id) -} - -func checkErrorPage(t *testing.T, client *gophercloud.ServiceClient, id int) { - content, err := lbs.SetErrorPage(client, id, "New content!").Extract() - t.Logf("Set error page for LB %d", id) - - content, err = lbs.GetErrorPage(client, id).Extract() - th.AssertNoErr(t, err) - t.Logf("Error page for LB %d: %s", id, content) - - err = lbs.DeleteErrorPage(client, id).ExtractErr() - t.Logf("Deleted error page for LB %d", id) -} - -func getStats(t *testing.T, client *gophercloud.ServiceClient, id int) { - waitForLB(client, id, lbs.ACTIVE) - - stats, err := lbs.GetStats(client, id).Extract() - th.AssertNoErr(t, err) - - t.Logf("Stats for LB %d: %#v", id, stats) -} - -func checkCaching(t *testing.T, client *gophercloud.ServiceClient, id int) { - err := lbs.EnableCaching(client, id).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Enabled caching for LB %d", id) - - res, err := lbs.IsContentCached(client, id) - th.AssertNoErr(t, err) - t.Logf("Is caching enabled for LB? %s", strconv.FormatBool(res)) - - err = lbs.DisableCaching(client, id).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Disabled caching for LB %d", id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/monitor_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/monitor_test.go deleted file mode 100644 index c1a8e24dd9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/monitor_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/rackspace/lb/v1/lbs" - "github.com/rackspace/gophercloud/rackspace/lb/v1/monitors" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestMonitors(t *testing.T) { - client := setup(t) - - ids := createLB(t, client, 1) - lbID := ids[0] - - getMonitor(t, client, lbID) - - updateMonitor(t, client, lbID) - - deleteMonitor(t, client, lbID) - - deleteLB(t, client, lbID) -} - -func getMonitor(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - hm, err := monitors.Get(client, lbID).Extract() - th.AssertNoErr(t, err) - t.Logf("Health monitor for LB %d: Type [%s] Delay [%d] Timeout [%d] AttemptLimit [%d]", - lbID, hm.Type, hm.Delay, hm.Timeout, hm.AttemptLimit) -} - -func updateMonitor(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - opts := monitors.UpdateHTTPMonitorOpts{ - AttemptLimit: 3, - Delay: 10, - Timeout: 10, - BodyRegex: "hello is it me you're looking for", - Path: "/foo", - StatusRegex: "200", - Type: monitors.HTTP, - } - - err := monitors.Update(client, lbID, opts).ExtractErr() - th.AssertNoErr(t, err) - - waitForLB(client, lbID, lbs.ACTIVE) - t.Logf("Updated monitor for LB %d", lbID) -} - -func deleteMonitor(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - err := monitors.Delete(client, lbID).ExtractErr() - th.AssertNoErr(t, err) - - waitForLB(client, lbID, lbs.ACTIVE) - t.Logf("Deleted monitor for LB %d", lbID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/node_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/node_test.go deleted file mode 100644 index 18b9fe71ce..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/node_test.go +++ /dev/null @@ -1,175 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/compute/v2/servers" - "github.com/rackspace/gophercloud/rackspace/lb/v1/lbs" - "github.com/rackspace/gophercloud/rackspace/lb/v1/nodes" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestNodes(t *testing.T) { - client := setup(t) - - serverIP := findServer(t) - ids := createLB(t, client, 1) - lbID := ids[0] - - nodeID := addNodes(t, client, lbID, serverIP) - - listNodes(t, client, lbID) - - getNode(t, client, lbID, nodeID) - - updateNode(t, client, lbID, nodeID) - - listEvents(t, client, lbID) - - deleteNode(t, client, lbID, nodeID) - - waitForLB(client, lbID, lbs.ACTIVE) - deleteLB(t, client, lbID) -} - -func findServer(t *testing.T) string { - var serverIP string - - client, err := newComputeClient() - th.AssertNoErr(t, err) - - err = servers.List(client, nil).EachPage(func(page pagination.Page) (bool, error) { - sList, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - - for _, s := range sList { - serverIP = s.AccessIPv4 - t.Logf("Found an existing server: ID [%s] Public IP [%s]", s.ID, serverIP) - break - } - - return true, nil - }) - th.AssertNoErr(t, err) - - if serverIP == "" { - t.Log("No server found, creating one") - - imageRef := os.Getenv("RS_IMAGE_ID") - if imageRef == "" { - t.Fatalf("OS var RS_IMAGE_ID undefined") - } - flavorRef := os.Getenv("RS_FLAVOR_ID") - if flavorRef == "" { - t.Fatalf("OS var RS_FLAVOR_ID undefined") - } - - opts := &servers.CreateOpts{ - Name: tools.RandomString("lb_test_", 5), - ImageRef: imageRef, - FlavorRef: flavorRef, - DiskConfig: diskconfig.Manual, - } - - s, err := servers.Create(client, opts).Extract() - th.AssertNoErr(t, err) - serverIP = s.AccessIPv4 - - t.Logf("Created server %s, waiting for it to build", s.ID) - err = servers.WaitForStatus(client, s.ID, "ACTIVE", 300) - th.AssertNoErr(t, err) - t.Logf("Server created successfully.") - } - - return serverIP -} - -func addNodes(t *testing.T, client *gophercloud.ServiceClient, lbID int, serverIP string) int { - opts := nodes.CreateOpts{ - nodes.CreateOpt{ - Address: serverIP, - Port: 80, - Condition: nodes.ENABLED, - Type: nodes.PRIMARY, - }, - } - - page := nodes.Create(client, lbID, opts) - - nodeList, err := page.ExtractNodes() - th.AssertNoErr(t, err) - - var nodeID int - for _, n := range nodeList { - nodeID = n.ID - } - if nodeID == 0 { - t.Fatalf("nodeID could not be extracted from create response") - } - - t.Logf("Added node %d to LB %d", nodeID, lbID) - waitForLB(client, lbID, lbs.ACTIVE) - - return nodeID -} - -func listNodes(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - err := nodes.List(client, lbID, nil).EachPage(func(page pagination.Page) (bool, error) { - nodeList, err := nodes.ExtractNodes(page) - th.AssertNoErr(t, err) - - for _, n := range nodeList { - t.Logf("Listing node: ID [%d] Address [%s:%d] Status [%s]", n.ID, n.Address, n.Port, n.Status) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func getNode(t *testing.T, client *gophercloud.ServiceClient, lbID int, nodeID int) { - node, err := nodes.Get(client, lbID, nodeID).Extract() - th.AssertNoErr(t, err) - t.Logf("Getting node %d: Type [%s] Weight [%d]", nodeID, node.Type, node.Weight) -} - -func updateNode(t *testing.T, client *gophercloud.ServiceClient, lbID int, nodeID int) { - opts := nodes.UpdateOpts{ - Weight: gophercloud.IntToPointer(10), - Condition: nodes.DRAINING, - Type: nodes.SECONDARY, - } - err := nodes.Update(client, lbID, nodeID, opts).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Updated node %d", nodeID) - waitForLB(client, lbID, lbs.ACTIVE) -} - -func listEvents(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - pager := nodes.ListEvents(client, lbID, nodes.ListEventsOpts{}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - eventList, err := nodes.ExtractNodeEvents(page) - th.AssertNoErr(t, err) - - for _, e := range eventList { - t.Logf("Listing events for node %d: Type [%s] Msg [%s] Severity [%s] Date [%s]", - e.NodeID, e.Type, e.DetailedMessage, e.Severity, e.Created) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func deleteNode(t *testing.T, client *gophercloud.ServiceClient, lbID int, nodeID int) { - err := nodes.Delete(client, lbID, nodeID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Deleted node %d", nodeID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/session_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/session_test.go deleted file mode 100644 index 8d85655f6b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/session_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/rackspace/lb/v1/sessions" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestSession(t *testing.T) { - client := setup(t) - - ids := createLB(t, client, 1) - lbID := ids[0] - - getSession(t, client, lbID) - - enableSession(t, client, lbID) - waitForLB(client, lbID, "ACTIVE") - - disableSession(t, client, lbID) - waitForLB(client, lbID, "ACTIVE") - - deleteLB(t, client, lbID) -} - -func getSession(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - sp, err := sessions.Get(client, lbID).Extract() - th.AssertNoErr(t, err) - t.Logf("Session config: Type [%s]", sp.Type) -} - -func enableSession(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - opts := sessions.CreateOpts{Type: sessions.HTTPCOOKIE} - err := sessions.Enable(client, lbID, opts).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Enable %s sessions for %d", opts.Type, lbID) -} - -func disableSession(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - err := sessions.Disable(client, lbID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Disable sessions for %d", lbID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/throttle_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/throttle_test.go deleted file mode 100644 index 1cc12356ca..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/throttle_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/rackspace/lb/v1/throttle" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestThrottle(t *testing.T) { - client := setup(t) - - ids := createLB(t, client, 1) - lbID := ids[0] - - getThrottleConfig(t, client, lbID) - - createThrottleConfig(t, client, lbID) - waitForLB(client, lbID, "ACTIVE") - - deleteThrottleConfig(t, client, lbID) - waitForLB(client, lbID, "ACTIVE") - - deleteLB(t, client, lbID) -} - -func getThrottleConfig(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - sp, err := throttle.Get(client, lbID).Extract() - th.AssertNoErr(t, err) - t.Logf("Throttle config: MaxConns [%s]", sp.MaxConnections) -} - -func createThrottleConfig(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - opts := throttle.CreateOpts{ - MaxConnections: 200, - MaxConnectionRate: 100, - MinConnections: 0, - RateInterval: 10, - } - - err := throttle.Create(client, lbID, opts).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Enable throttling for %d", lbID) -} - -func deleteThrottleConfig(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - err := throttle.Delete(client, lbID).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Disable throttling for %d", lbID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/vip_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/vip_test.go deleted file mode 100644 index bc0c2a89f2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/lb/v1/vip_test.go +++ /dev/null @@ -1,83 +0,0 @@ -// +build acceptance lbs - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/lb/v1/lbs" - "github.com/rackspace/gophercloud/rackspace/lb/v1/vips" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestVIPs(t *testing.T) { - client := setup(t) - - ids := createLB(t, client, 1) - lbID := ids[0] - - listVIPs(t, client, lbID) - - vipIDs := addVIPs(t, client, lbID, 3) - - deleteVIP(t, client, lbID, vipIDs[0]) - - bulkDeleteVIPs(t, client, lbID, vipIDs[1:]) - - waitForLB(client, lbID, lbs.ACTIVE) - deleteLB(t, client, lbID) -} - -func listVIPs(t *testing.T, client *gophercloud.ServiceClient, lbID int) { - err := vips.List(client, lbID).EachPage(func(page pagination.Page) (bool, error) { - vipList, err := vips.ExtractVIPs(page) - th.AssertNoErr(t, err) - - for _, vip := range vipList { - t.Logf("Listing VIP: ID [%s] Address [%s] Type [%s] Version [%s]", - vip.ID, vip.Address, vip.Type, vip.Version) - } - - return true, nil - }) - th.AssertNoErr(t, err) -} - -func addVIPs(t *testing.T, client *gophercloud.ServiceClient, lbID, count int) []int { - ids := []int{} - - for i := 0; i < count; i++ { - opts := vips.CreateOpts{ - Type: vips.PUBLIC, - Version: vips.IPV6, - } - - vip, err := vips.Create(client, lbID, opts).Extract() - th.AssertNoErr(t, err) - - t.Logf("Created VIP %d", vip.ID) - - waitForLB(client, lbID, lbs.ACTIVE) - - ids = append(ids, vip.ID) - } - - return ids -} - -func deleteVIP(t *testing.T, client *gophercloud.ServiceClient, lbID, vipID int) { - err := vips.Delete(client, lbID, vipID).ExtractErr() - th.AssertNoErr(t, err) - - t.Logf("Deleted VIP %d", vipID) - - waitForLB(client, lbID, lbs.ACTIVE) -} - -func bulkDeleteVIPs(t *testing.T, client *gophercloud.ServiceClient, lbID int, ids []int) { - err := vips.BulkDelete(client, lbID, ids).ExtractErr() - th.AssertNoErr(t, err) - t.Logf("Deleted VIPs %s", intsToStr(ids)) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/common.go deleted file mode 100644 index 81704187fe..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/common.go +++ /dev/null @@ -1,39 +0,0 @@ -package v2 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/rackspace" - th "github.com/rackspace/gophercloud/testhelper" -) - -var Client *gophercloud.ServiceClient - -func NewClient() (*gophercloud.ServiceClient, error) { - opts, err := rackspace.AuthOptionsFromEnv() - if err != nil { - return nil, err - } - - provider, err := rackspace.AuthenticatedClient(opts) - if err != nil { - return nil, err - } - - return rackspace.NewNetworkV2(provider, gophercloud.EndpointOpts{ - Name: "cloudNetworks", - Region: os.Getenv("RS_REGION"), - }) -} - -func Setup(t *testing.T) { - client, err := NewClient() - th.AssertNoErr(t, err) - Client = client -} - -func Teardown() { - Client = nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/network_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/network_test.go deleted file mode 100644 index 3862123bfd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/network_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "strconv" - "testing" - - os "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/networking/v2/networks" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestNetworkCRUDOperations(t *testing.T) { - Setup(t) - defer Teardown() - - // Create a network - n, err := networks.Create(Client, os.CreateOpts{Name: "sample_network", AdminStateUp: os.Up}).Extract() - th.AssertNoErr(t, err) - defer networks.Delete(Client, n.ID) - th.AssertEquals(t, "sample_network", n.Name) - th.AssertEquals(t, true, n.AdminStateUp) - networkID := n.ID - - // List networks - pager := networks.List(Client, os.ListOpts{Limit: 2}) - err = pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - networkList, err := os.ExtractNetworks(page) - th.AssertNoErr(t, err) - - for _, n := range networkList { - t.Logf("Network: ID [%s] Name [%s] Status [%s] Is shared? [%s]", - n.ID, n.Name, n.Status, strconv.FormatBool(n.Shared)) - } - - return true, nil - }) - th.CheckNoErr(t, err) - - // Get a network - if networkID == "" { - t.Fatalf("In order to retrieve a network, the NetworkID must be set") - } - n, err = networks.Get(Client, networkID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, "ACTIVE", n.Status) - th.AssertDeepEquals(t, []string{}, n.Subnets) - th.AssertEquals(t, "sample_network", n.Name) - th.AssertEquals(t, true, n.AdminStateUp) - th.AssertEquals(t, false, n.Shared) - th.AssertEquals(t, networkID, n.ID) - - // Update network - n, err = networks.Update(Client, networkID, os.UpdateOpts{Name: "new_network_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, "new_network_name", n.Name) - - // Delete network - res := networks.Delete(Client, networkID) - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/port_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/port_test.go deleted file mode 100644 index 3c42bb20cd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/port_test.go +++ /dev/null @@ -1,116 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "testing" - - osNetworks "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - osPorts "github.com/rackspace/gophercloud/openstack/networking/v2/ports" - osSubnets "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/networking/v2/networks" - "github.com/rackspace/gophercloud/rackspace/networking/v2/ports" - "github.com/rackspace/gophercloud/rackspace/networking/v2/subnets" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestPortCRUD(t *testing.T) { - Setup(t) - defer Teardown() - - // Setup network - t.Log("Setting up network") - networkID, err := createNetwork() - th.AssertNoErr(t, err) - defer networks.Delete(Client, networkID) - - // Setup subnet - t.Logf("Setting up subnet on network %s", networkID) - subnetID, err := createSubnet(networkID) - th.AssertNoErr(t, err) - defer subnets.Delete(Client, subnetID) - - // Create port - t.Logf("Create port based on subnet %s", subnetID) - portID := createPort(t, networkID, subnetID) - - // List ports - t.Logf("Listing all ports") - listPorts(t) - - // Get port - if portID == "" { - t.Fatalf("In order to retrieve a port, the portID must be set") - } - p, err := ports.Get(Client, portID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, portID, p.ID) - - // Update port - p, err = ports.Update(Client, portID, osPorts.UpdateOpts{Name: "new_port_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, "new_port_name", p.Name) - - // Delete port - res := ports.Delete(Client, portID) - th.AssertNoErr(t, res.Err) -} - -func createPort(t *testing.T, networkID, subnetID string) string { - enable := true - opts := osPorts.CreateOpts{ - NetworkID: networkID, - Name: "my_port", - AdminStateUp: &enable, - FixedIPs: []osPorts.IP{osPorts.IP{SubnetID: subnetID}}, - } - p, err := ports.Create(Client, opts).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, networkID, p.NetworkID) - th.AssertEquals(t, "my_port", p.Name) - th.AssertEquals(t, true, p.AdminStateUp) - - return p.ID -} - -func listPorts(t *testing.T) { - count := 0 - pager := ports.List(Client, osPorts.ListOpts{}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - count++ - t.Logf("--- Page ---") - - portList, err := osPorts.ExtractPorts(page) - th.AssertNoErr(t, err) - - for _, p := range portList { - t.Logf("Port: ID [%s] Name [%s] Status [%s] MAC addr [%s] Fixed IPs [%#v] Security groups [%#v]", - p.ID, p.Name, p.Status, p.MACAddress, p.FixedIPs, p.SecurityGroups) - } - - return true, nil - }) - - th.CheckNoErr(t, err) - - if count == 0 { - t.Logf("No pages were iterated over when listing ports") - } -} - -func createNetwork() (string, error) { - res, err := networks.Create(Client, osNetworks.CreateOpts{Name: "tmp_network", AdminStateUp: osNetworks.Up}).Extract() - return res.ID, err -} - -func createSubnet(networkID string) (string, error) { - s, err := subnets.Create(Client, osSubnets.CreateOpts{ - NetworkID: networkID, - CIDR: "192.168.199.0/24", - IPVersion: osSubnets.IPv4, - Name: "my_subnet", - EnableDHCP: osSubnets.Down, - }).Extract() - return s.ID, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/subnet_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/subnet_test.go deleted file mode 100644 index c4014320a4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/networking/v2/subnet_test.go +++ /dev/null @@ -1,84 +0,0 @@ -// +build acceptance networking - -package v2 - -import ( - "testing" - - osNetworks "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - osSubnets "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/networking/v2/networks" - "github.com/rackspace/gophercloud/rackspace/networking/v2/subnets" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestListSubnets(t *testing.T) { - Setup(t) - defer Teardown() - - pager := subnets.List(Client, osSubnets.ListOpts{Limit: 2}) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page ---") - - subnetList, err := osSubnets.ExtractSubnets(page) - th.AssertNoErr(t, err) - - for _, s := range subnetList { - t.Logf("Subnet: ID [%s] Name [%s] IP Version [%d] CIDR [%s] GatewayIP [%s]", - s.ID, s.Name, s.IPVersion, s.CIDR, s.GatewayIP) - } - - return true, nil - }) - th.CheckNoErr(t, err) -} - -func TestSubnetCRUD(t *testing.T) { - Setup(t) - defer Teardown() - - // Setup network - t.Log("Setting up network") - n, err := networks.Create(Client, osNetworks.CreateOpts{Name: "tmp_network", AdminStateUp: osNetworks.Up}).Extract() - th.AssertNoErr(t, err) - networkID := n.ID - defer networks.Delete(Client, networkID) - - // Create subnet - t.Log("Create subnet") - enable := false - opts := osSubnets.CreateOpts{ - NetworkID: networkID, - CIDR: "192.168.199.0/24", - IPVersion: osSubnets.IPv4, - Name: "my_subnet", - EnableDHCP: &enable, - } - s, err := subnets.Create(Client, opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, networkID, s.NetworkID) - th.AssertEquals(t, "192.168.199.0/24", s.CIDR) - th.AssertEquals(t, 4, s.IPVersion) - th.AssertEquals(t, "my_subnet", s.Name) - th.AssertEquals(t, false, s.EnableDHCP) - subnetID := s.ID - - // Get subnet - t.Log("Getting subnet") - s, err = subnets.Get(Client, subnetID).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, subnetID, s.ID) - - // Update subnet - t.Log("Update subnet") - s, err = subnets.Update(Client, subnetID, osSubnets.UpdateOpts{Name: "new_subnet_name"}).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, "new_subnet_name", s.Name) - - // Delete subnet - t.Log("Delete subnet") - res := subnets.Delete(Client, subnetID) - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/accounts_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/accounts_test.go deleted file mode 100644 index 145e4e0482..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/accounts_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build acceptance rackspace - -package v1 - -import ( - "testing" - - raxAccounts "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAccounts(t *testing.T) { - c, err := createClient(t, false) - th.AssertNoErr(t, err) - - updateres := raxAccounts.Update(c, raxAccounts.UpdateOpts{Metadata: map[string]string{"white": "mountains"}}) - th.AssertNoErr(t, updateres.Err) - t.Logf("Headers from Update Account request: %+v\n", updateres.Header) - defer func() { - updateres = raxAccounts.Update(c, raxAccounts.UpdateOpts{Metadata: map[string]string{"white": ""}}) - th.AssertNoErr(t, updateres.Err) - metadata, err := raxAccounts.Get(c).ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Metadata from Get Account request (after update reverted): %+v\n", metadata) - th.CheckEquals(t, metadata["White"], "") - }() - - metadata, err := raxAccounts.Get(c).ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Metadata from Get Account request (after update): %+v\n", metadata) - - th.CheckEquals(t, metadata["White"], "mountains") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/bulk_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/bulk_test.go deleted file mode 100644 index 79013a564a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/bulk_test.go +++ /dev/null @@ -1,23 +0,0 @@ -// +build acceptance rackspace objectstorage v1 - -package v1 - -import ( - "testing" - - "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestBulk(t *testing.T) { - c, err := createClient(t, false) - th.AssertNoErr(t, err) - - var options bulk.DeleteOpts - options = append(options, "container/object1") - res := bulk.Delete(c, options) - th.AssertNoErr(t, res.Err) - body, err := res.ExtractBody() - th.AssertNoErr(t, err) - t.Logf("Response body from Bulk Delete Request: %+v\n", body) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/cdncontainers_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/cdncontainers_test.go deleted file mode 100644 index e1bf38b16f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/cdncontainers_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build acceptance rackspace objectstorage v1 - -package v1 - -import ( - "testing" - - osContainers "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" - raxCDNContainers "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers" - raxContainers "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestCDNContainers(t *testing.T) { - raxClient, err := createClient(t, false) - th.AssertNoErr(t, err) - - createres := raxContainers.Create(raxClient, "gophercloud-test", nil) - th.AssertNoErr(t, createres.Err) - t.Logf("Headers from Create Container request: %+v\n", createres.Header) - defer func() { - res := raxContainers.Delete(raxClient, "gophercloud-test") - th.AssertNoErr(t, res.Err) - }() - - raxCDNClient, err := createClient(t, true) - th.AssertNoErr(t, err) - - r := raxCDNContainers.Enable(raxCDNClient, "gophercloud-test", raxCDNContainers.EnableOpts{CDNEnabled: true, TTL: 900}) - th.AssertNoErr(t, r.Err) - t.Logf("Headers from Enable CDN Container request: %+v\n", r.Header) - - t.Logf("Container Names available to the currently issued token:") - count := 0 - err = raxCDNContainers.List(raxCDNClient, &osContainers.ListOpts{Full: false}).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - names, err := raxCDNContainers.ExtractNames(page) - th.AssertNoErr(t, err) - - for i, name := range names { - t.Logf("[%02d] %s", i, name) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No CDN containers listed for your current token.") - } - - updateres := raxCDNContainers.Update(raxCDNClient, "gophercloud-test", raxCDNContainers.UpdateOpts{CDNEnabled: false}) - th.AssertNoErr(t, updateres.Err) - t.Logf("Headers from Update CDN Container request: %+v\n", updateres.Header) - - metadata, err := raxCDNContainers.Get(raxCDNClient, "gophercloud-test").ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Headers from Get CDN Container request (after update): %+v\n", metadata) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go deleted file mode 100644 index 6e477ae704..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build acceptance rackspace objectstorage v1 - -package v1 - -import ( - "bytes" - "testing" - - raxCDNContainers "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers" - raxCDNObjects "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects" - raxContainers "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers" - raxObjects "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestCDNObjects(t *testing.T) { - raxClient, err := createClient(t, false) - th.AssertNoErr(t, err) - - createContResult := raxContainers.Create(raxClient, "gophercloud-test", nil) - th.AssertNoErr(t, createContResult.Err) - t.Logf("Headers from Create Container request: %+v\n", createContResult.Header) - defer func() { - deleteResult := raxContainers.Delete(raxClient, "gophercloud-test") - th.AssertNoErr(t, deleteResult.Err) - }() - - header, err := raxObjects.Create(raxClient, "gophercloud-test", "test-object", bytes.NewBufferString("gophercloud cdn test"), nil).ExtractHeader() - th.AssertNoErr(t, err) - t.Logf("Headers from Create Object request: %+v\n", header) - defer func() { - deleteResult := raxObjects.Delete(raxClient, "gophercloud-test", "test-object", nil) - th.AssertNoErr(t, deleteResult.Err) - }() - - raxCDNClient, err := createClient(t, true) - th.AssertNoErr(t, err) - - enableResult := raxCDNContainers.Enable(raxCDNClient, "gophercloud-test", raxCDNContainers.EnableOpts{CDNEnabled: true, TTL: 900}) - th.AssertNoErr(t, enableResult.Err) - t.Logf("Headers from Enable CDN Container request: %+v\n", enableResult.Header) - - deleteResult := raxCDNObjects.Delete(raxCDNClient, "gophercloud-test", "test-object", nil) - th.AssertNoErr(t, deleteResult.Err) - t.Logf("Headers from Delete CDN Object request: %+v\n", deleteResult.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/common.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/common.go deleted file mode 100644 index 1ae07278cc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/common.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build acceptance rackspace objectstorage v1 - -package v1 - -import ( - "os" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/acceptance/tools" - "github.com/rackspace/gophercloud/rackspace" - th "github.com/rackspace/gophercloud/testhelper" -) - -func rackspaceAuthOptions(t *testing.T) gophercloud.AuthOptions { - // Obtain credentials from the environment. - options, err := rackspace.AuthOptionsFromEnv() - th.AssertNoErr(t, err) - options = tools.OnlyRS(options) - - if options.Username == "" { - t.Fatal("Please provide a Rackspace username as RS_USERNAME.") - } - if options.APIKey == "" { - t.Fatal("Please provide a Rackspace API key as RS_API_KEY.") - } - - return options -} - -func createClient(t *testing.T, cdn bool) (*gophercloud.ServiceClient, error) { - region := os.Getenv("RS_REGION") - if region == "" { - t.Fatal("Please provide a Rackspace region as RS_REGION") - } - - ao := rackspaceAuthOptions(t) - - provider, err := rackspace.NewClient(ao.IdentityEndpoint) - th.AssertNoErr(t, err) - - err = rackspace.Authenticate(provider, ao) - th.AssertNoErr(t, err) - - if cdn { - return rackspace.NewObjectCDNV1(provider, gophercloud.EndpointOpts{ - Region: region, - }) - } - - return rackspace.NewObjectStorageV1(provider, gophercloud.EndpointOpts{ - Region: region, - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/containers_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/containers_test.go deleted file mode 100644 index a7339cf388..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/containers_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// +build acceptance rackspace objectstorage v1 - -package v1 - -import ( - "testing" - - osContainers "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" - raxContainers "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestContainers(t *testing.T) { - c, err := createClient(t, false) - th.AssertNoErr(t, err) - - t.Logf("Containers Info available to the currently issued token:") - count := 0 - err = raxContainers.List(c, &osContainers.ListOpts{Full: true}).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - containers, err := raxContainers.ExtractInfo(page) - th.AssertNoErr(t, err) - - for i, container := range containers { - t.Logf("[%02d] name=[%s]", i, container.Name) - t.Logf(" count=[%d]", container.Count) - t.Logf(" bytes=[%d]", container.Bytes) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No containers listed for your current token.") - } - - t.Logf("Container Names available to the currently issued token:") - count = 0 - err = raxContainers.List(c, &osContainers.ListOpts{Full: false}).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - names, err := raxContainers.ExtractNames(page) - th.AssertNoErr(t, err) - - for i, name := range names { - t.Logf("[%02d] %s", i, name) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No containers listed for your current token.") - } - - createres := raxContainers.Create(c, "gophercloud-test", nil) - th.AssertNoErr(t, createres.Err) - defer func() { - res := raxContainers.Delete(c, "gophercloud-test") - th.AssertNoErr(t, res.Err) - }() - - updateres := raxContainers.Update(c, "gophercloud-test", raxContainers.UpdateOpts{Metadata: map[string]string{"white": "mountains"}}) - th.AssertNoErr(t, updateres.Err) - t.Logf("Headers from Update Account request: %+v\n", updateres.Header) - defer func() { - res := raxContainers.Update(c, "gophercloud-test", raxContainers.UpdateOpts{Metadata: map[string]string{"white": ""}}) - th.AssertNoErr(t, res.Err) - metadata, err := raxContainers.Get(c, "gophercloud-test").ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Metadata from Get Account request (after update reverted): %+v\n", metadata) - th.CheckEquals(t, metadata["White"], "") - }() - - getres := raxContainers.Get(c, "gophercloud-test") - t.Logf("Headers from Get Account request (after update): %+v\n", getres.Header) - metadata, err := getres.ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Metadata from Get Account request (after update): %+v\n", metadata) - th.CheckEquals(t, metadata["White"], "mountains") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/objects_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/objects_test.go deleted file mode 100644 index 462f2847db..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/objectstorage/v1/objects_test.go +++ /dev/null @@ -1,112 +0,0 @@ -// +build acceptance rackspace objectstorage v1 - -package v1 - -import ( - "bytes" - "testing" - - osObjects "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" - "github.com/rackspace/gophercloud/pagination" - raxContainers "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers" - raxObjects "github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestObjects(t *testing.T) { - c, err := createClient(t, false) - th.AssertNoErr(t, err) - - res := raxContainers.Create(c, "gophercloud-test", nil) - th.AssertNoErr(t, res.Err) - - defer func() { - res := raxContainers.Delete(c, "gophercloud-test") - th.AssertNoErr(t, res.Err) - }() - - content := bytes.NewBufferString("Lewis Carroll") - options := &osObjects.CreateOpts{ContentType: "text/plain"} - createres := raxObjects.Create(c, "gophercloud-test", "o1", content, options) - th.AssertNoErr(t, createres.Err) - defer func() { - res := raxObjects.Delete(c, "gophercloud-test", "o1", nil) - th.AssertNoErr(t, res.Err) - }() - - t.Logf("Objects Info available to the currently issued token:") - count := 0 - err = raxObjects.List(c, "gophercloud-test", &osObjects.ListOpts{Full: true}).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - objects, err := raxObjects.ExtractInfo(page) - th.AssertNoErr(t, err) - - for i, object := range objects { - t.Logf("[%02d] name=[%s]", i, object.Name) - t.Logf(" content-type=[%s]", object.ContentType) - t.Logf(" bytes=[%d]", object.Bytes) - t.Logf(" last-modified=[%s]", object.LastModified) - t.Logf(" hash=[%s]", object.Hash) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No objects listed for your current token.") - } - t.Logf("Container Names available to the currently issued token:") - count = 0 - err = raxObjects.List(c, "gophercloud-test", &osObjects.ListOpts{Full: false}).EachPage(func(page pagination.Page) (bool, error) { - t.Logf("--- Page %02d ---", count) - - names, err := raxObjects.ExtractNames(page) - th.AssertNoErr(t, err) - - for i, name := range names { - t.Logf("[%02d] %s", i, name) - } - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - if count == 0 { - t.Errorf("No objects listed for your current token.") - } - - copyres := raxObjects.Copy(c, "gophercloud-test", "o1", &raxObjects.CopyOpts{Destination: "gophercloud-test/o2"}) - th.AssertNoErr(t, copyres.Err) - defer func() { - res := raxObjects.Delete(c, "gophercloud-test", "o2", nil) - th.AssertNoErr(t, res.Err) - }() - - o1Content, err := raxObjects.Download(c, "gophercloud-test", "o1", nil).ExtractContent() - th.AssertNoErr(t, err) - o2Content, err := raxObjects.Download(c, "gophercloud-test", "o2", nil).ExtractContent() - th.AssertNoErr(t, err) - th.AssertEquals(t, string(o2Content), string(o1Content)) - - updateres := raxObjects.Update(c, "gophercloud-test", "o2", osObjects.UpdateOpts{Metadata: map[string]string{"white": "mountains"}}) - th.AssertNoErr(t, updateres.Err) - t.Logf("Headers from Update Account request: %+v\n", updateres.Header) - defer func() { - res := raxObjects.Update(c, "gophercloud-test", "o2", osObjects.UpdateOpts{Metadata: map[string]string{"white": ""}}) - th.AssertNoErr(t, res.Err) - metadata, err := raxObjects.Get(c, "gophercloud-test", "o2", nil).ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Metadata from Get Account request (after update reverted): %+v\n", metadata) - th.CheckEquals(t, metadata["White"], "") - }() - - getres := raxObjects.Get(c, "gophercloud-test", "o2", nil) - th.AssertNoErr(t, getres.Err) - t.Logf("Headers from Get Account request (after update): %+v\n", getres.Header) - metadata, err := getres.ExtractMetadata() - th.AssertNoErr(t, err) - t.Logf("Metadata from Get Account request (after update): %+v\n", metadata) - th.CheckEquals(t, metadata["White"], "mountains") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/pkg.go deleted file mode 100644 index 5d17b32caa..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package rackspace diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/tools/pkg.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/tools/pkg.go deleted file mode 100644 index f7eca1298a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/tools/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package tools diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/tools/tools.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/tools/tools.go deleted file mode 100644 index 35679b728c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/tools/tools.go +++ /dev/null @@ -1,89 +0,0 @@ -// +build acceptance common - -package tools - -import ( - "crypto/rand" - "errors" - mrand "math/rand" - "os" - "time" - - "github.com/rackspace/gophercloud" -) - -// ErrTimeout is returned if WaitFor takes longer than 300 second to happen. -var ErrTimeout = errors.New("Timed out") - -// OnlyRS overrides the default Gophercloud behavior of using OS_-prefixed environment variables -// if RS_ variables aren't present. Otherwise, they'll stomp over each other here in the acceptance -// tests, where you need to have both defined. -func OnlyRS(original gophercloud.AuthOptions) gophercloud.AuthOptions { - if os.Getenv("RS_AUTH_URL") == "" { - original.IdentityEndpoint = "" - } - if os.Getenv("RS_USERNAME") == "" { - original.Username = "" - } - if os.Getenv("RS_PASSWORD") == "" { - original.Password = "" - } - if os.Getenv("RS_API_KEY") == "" { - original.APIKey = "" - } - return original -} - -// WaitFor polls a predicate function once per second to wait for a certain state to arrive. -func WaitFor(predicate func() (bool, error)) error { - for i := 0; i < 300; i++ { - time.Sleep(1 * time.Second) - - satisfied, err := predicate() - if err != nil { - return err - } - if satisfied { - return nil - } - } - return ErrTimeout -} - -// MakeNewPassword generates a new string that's guaranteed to be different than the given one. -func MakeNewPassword(oldPass string) string { - randomPassword := RandomString("", 16) - for randomPassword == oldPass { - randomPassword = RandomString("", 16) - } - return randomPassword -} - -// RandomString generates a string of given length, but random content. -// All content will be within the ASCII graphic character set. -// (Implementation from Even Shaw's contribution on -// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go). -func RandomString(prefix string, n int) string { - const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - var bytes = make([]byte, n) - rand.Read(bytes) - for i, b := range bytes { - bytes[i] = alphanum[b%byte(len(alphanum))] - } - return prefix + string(bytes) -} - -// RandomInt will return a random integer between a specified range. -func RandomInt(min, max int) int { - mrand.Seed(time.Now().Unix()) - return mrand.Intn(max-min) + min -} - -// Elide returns the first bit of its input string with a suffix of "..." if it's longer than -// a comfortable 40 characters. -func Elide(value string) string { - if len(value) > 40 { - return value[0:37] + "..." - } - return value -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/endpoint_search_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/endpoint_search_test.go deleted file mode 100644 index 3457453427..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/endpoint_search_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package gophercloud - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestApplyDefaultsToEndpointOpts(t *testing.T) { - eo := EndpointOpts{Availability: AvailabilityPublic} - eo.ApplyDefaults("compute") - expected := EndpointOpts{Availability: AvailabilityPublic, Type: "compute"} - th.CheckDeepEquals(t, expected, eo) - - eo = EndpointOpts{Type: "compute"} - eo.ApplyDefaults("object-store") - expected = EndpointOpts{Availability: AvailabilityPublic, Type: "compute"} - th.CheckDeepEquals(t, expected, eo) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/doc.go deleted file mode 100644 index e3af39f513..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package apiversions provides information and interaction with the different -// API versions for the OpenStack Block Storage service, code-named Cinder. -package apiversions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/requests.go deleted file mode 100644 index 016bf374e3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/requests.go +++ /dev/null @@ -1,28 +0,0 @@ -package apiversions - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// List lists all the Cinder API versions available to end-users. -func List(c *gophercloud.ServiceClient) pagination.Pager { - return pagination.NewPager(c, listURL(c), func(r pagination.PageResult) pagination.Page { - return APIVersionPage{pagination.SinglePageBase(r)} - }) -} - -// Get will retrieve the volume type with the provided ID. To extract the volume -// type from the result, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, v string) GetResult { - var res GetResult - _, err := perigee.Request("GET", getURL(client, v), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - Results: &res.Body, - }) - res.Err = err - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/requests_test.go deleted file mode 100644 index 56b5e4fc72..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/requests_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package apiversions - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, `{ - "versions": [ - { - "status": "CURRENT", - "updated": "2012-01-04T11:33:21Z", - "id": "v1.0", - "links": [ - { - "href": "http://23.253.228.211:8776/v1/", - "rel": "self" - } - ] - }, - { - "status": "CURRENT", - "updated": "2012-11-21T11:33:21Z", - "id": "v2.0", - "links": [ - { - "href": "http://23.253.228.211:8776/v2/", - "rel": "self" - } - ] - } - ] - }`) - }) - - count := 0 - - List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractAPIVersions(page) - if err != nil { - t.Errorf("Failed to extract API versions: %v", err) - return false, err - } - - expected := []APIVersion{ - APIVersion{ - ID: "v1.0", - Status: "CURRENT", - Updated: "2012-01-04T11:33:21Z", - }, - APIVersion{ - ID: "v2.0", - Status: "CURRENT", - Updated: "2012-11-21T11:33:21Z", - }, - } - - th.AssertDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestAPIInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, `{ - "version": { - "status": "CURRENT", - "updated": "2012-01-04T11:33:21Z", - "media-types": [ - { - "base": "application/xml", - "type": "application/vnd.openstack.volume+xml;version=1" - }, - { - "base": "application/json", - "type": "application/vnd.openstack.volume+json;version=1" - } - ], - "id": "v1.0", - "links": [ - { - "href": "http://23.253.228.211:8776/v1/", - "rel": "self" - }, - { - "href": "http://jorgew.github.com/block-storage-api/content/os-block-storage-1.0.pdf", - "type": "application/pdf", - "rel": "describedby" - }, - { - "href": "http://docs.rackspacecloud.com/servers/api/v1.1/application.wadl", - "type": "application/vnd.sun.wadl+xml", - "rel": "describedby" - } - ] - } - }`) - }) - - actual, err := Get(client.ServiceClient(), "v1").Extract() - if err != nil { - t.Errorf("Failed to extract version: %v", err) - } - - expected := APIVersion{ - ID: "v1.0", - Status: "CURRENT", - Updated: "2012-01-04T11:33:21Z", - } - - th.AssertEquals(t, actual.ID, expected.ID) - th.AssertEquals(t, actual.Status, expected.Status) - th.AssertEquals(t, actual.Updated, expected.Updated) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/results.go deleted file mode 100644 index 7b0df115b5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/results.go +++ /dev/null @@ -1,58 +0,0 @@ -package apiversions - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// APIVersion represents an API version for Cinder. -type APIVersion struct { - ID string `json:"id" mapstructure:"id"` // unique identifier - Status string `json:"status" mapstructure:"status"` // current status - Updated string `json:"updated" mapstructure:"updated"` // date last updated -} - -// APIVersionPage is the page returned by a pager when traversing over a -// collection of API versions. -type APIVersionPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether an APIVersionPage struct is empty. -func (r APIVersionPage) IsEmpty() (bool, error) { - is, err := ExtractAPIVersions(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -// ExtractAPIVersions takes a collection page, extracts all of the elements, -// and returns them a slice of APIVersion structs. It is effectively a cast. -func ExtractAPIVersions(page pagination.Page) ([]APIVersion, error) { - var resp struct { - Versions []APIVersion `mapstructure:"versions"` - } - - err := mapstructure.Decode(page.(APIVersionPage).Body, &resp) - - return resp.Versions, err -} - -// GetResult represents the result of a get operation. -type GetResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts an API version resource. -func (r GetResult) Extract() (*APIVersion, error) { - var resp struct { - Version *APIVersion `mapstructure:"version"` - } - - err := mapstructure.Decode(r.Body, &resp) - - return resp.Version, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/urls.go deleted file mode 100644 index 56f8260a25..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package apiversions - -import ( - "strings" - - "github.com/rackspace/gophercloud" -) - -func getURL(c *gophercloud.ServiceClient, version string) string { - return c.ServiceURL(strings.TrimRight(version, "/") + "/") -} - -func listURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/urls_test.go deleted file mode 100644 index 37e91425b5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/apiversions/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package apiversions - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "v1") - expected := endpoint + "v1/" - th.AssertEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/doc.go deleted file mode 100644 index 198f83077c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package snapshots provides information and interaction with snapshots in the -// OpenStack Block Storage service. A snapshot is a point in time copy of the -// data contained in an external storage volume, and can be controlled -// programmatically. -package snapshots diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/fixtures.go deleted file mode 100644 index d1461fb69d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/fixtures.go +++ /dev/null @@ -1,114 +0,0 @@ -package snapshots - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` - { - "snapshots": [ - { - "id": "289da7f8-6440-407c-9fb4-7db01ec49164", - "display_name": "snapshot-001" - }, - { - "id": "96c3bda7-c82a-4f50-be73-ca7621794835", - "display_name": "snapshot-002" - } - ] - } - `) - }) -} - -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` -{ - "snapshot": { - "display_name": "snapshot-001", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) -} - -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "snapshot": { - "volume_id": "1234", - "display_name": "snapshot-001" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "snapshot": { - "volume_id": "1234", - "display_name": "snapshot-001", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) -} - -func MockUpdateMetadataResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestJSONRequest(t, r, ` - { - "metadata": { - "key": "v1" - } - } - `) - - fmt.Fprintf(w, ` - { - "metadata": { - "key": "v1" - } - } - `) - }) -} - -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go deleted file mode 100644 index 443f696057..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go +++ /dev/null @@ -1,188 +0,0 @@ -package snapshots - -import ( - "fmt" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToSnapshotCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains options for creating a Snapshot. This object is passed to -// the snapshots.Create function. For more information about these parameters, -// see the Snapshot object. -type CreateOpts struct { - // OPTIONAL - Description string - // OPTIONAL - Force bool - // OPTIONAL - Metadata map[string]interface{} - // OPTIONAL - Name string - // REQUIRED - VolumeID string -} - -// ToSnapshotCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) { - s := make(map[string]interface{}) - - if opts.VolumeID == "" { - return nil, fmt.Errorf("Required CreateOpts field 'VolumeID' not set.") - } - s["volume_id"] = opts.VolumeID - - if opts.Description != "" { - s["display_description"] = opts.Description - } - if opts.Force == true { - s["force"] = opts.Force - } - if opts.Metadata != nil { - s["metadata"] = opts.Metadata - } - if opts.Name != "" { - s["display_name"] = opts.Name - } - - return map[string]interface{}{"snapshot": s}, nil -} - -// Create will create a new Snapshot based on the values in CreateOpts. To -// extract the Snapshot object from the response, call the Extract method on the -// CreateResult. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToSnapshotCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200, 201}, - ReqBody: &reqBody, - Results: &res.Body, - }) - return res -} - -// Delete will delete the existing Snapshot with the provided ID. -func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202, 204}, - }) - return res -} - -// Get retrieves the Snapshot with the provided ID. To extract the Snapshot -// object from the response, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{ - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - return res -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToSnapshotListQuery() (string, error) -} - -// ListOpts hold options for listing Snapshots. It is passed to the -// snapshots.List function. -type ListOpts struct { - Name string `q:"display_name"` - Status string `q:"status"` - VolumeID string `q:"volume_id"` -} - -// ToSnapshotListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToSnapshotListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List returns Snapshots optionally limited by the conditions provided in -// ListOpts. -func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToSnapshotListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - createPage := func(r pagination.PageResult) pagination.Page { - return ListResult{pagination.SinglePageBase(r)} - } - return pagination.NewPager(client, url, createPage) -} - -// UpdateMetadataOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateMetadataOptsBuilder interface { - ToSnapshotUpdateMetadataMap() (map[string]interface{}, error) -} - -// UpdateMetadataOpts contain options for updating an existing Snapshot. This -// object is passed to the snapshots.Update function. For more information -// about the parameters, see the Snapshot object. -type UpdateMetadataOpts struct { - Metadata map[string]interface{} -} - -// ToSnapshotUpdateMetadataMap assembles a request body based on the contents of -// an UpdateMetadataOpts. -func (opts UpdateMetadataOpts) ToSnapshotUpdateMetadataMap() (map[string]interface{}, error) { - v := make(map[string]interface{}) - - if opts.Metadata != nil { - v["metadata"] = opts.Metadata - } - - return v, nil -} - -// UpdateMetadata will update the Snapshot with provided information. To -// extract the updated Snapshot from the response, call the ExtractMetadata -// method on the UpdateMetadataResult. -func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) UpdateMetadataResult { - var res UpdateMetadataResult - - reqBody, err := opts.ToSnapshotUpdateMetadataMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", updateMetadataURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - ReqBody: &reqBody, - Results: &res.Body, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests_test.go deleted file mode 100644 index d0f9e887e8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package snapshots - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockListResponse(t) - - count := 0 - - List(client.ServiceClient(), &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractSnapshots(page) - if err != nil { - t.Errorf("Failed to extract snapshots: %v", err) - return false, err - } - - expected := []Snapshot{ - Snapshot{ - ID: "289da7f8-6440-407c-9fb4-7db01ec49164", - Name: "snapshot-001", - }, - Snapshot{ - ID: "96c3bda7-c82a-4f50-be73-ca7621794835", - Name: "snapshot-002", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockGetResponse(t) - - v, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, v.Name, "snapshot-001") - th.AssertEquals(t, v.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockCreateResponse(t) - - options := CreateOpts{VolumeID: "1234", Name: "snapshot-001"} - n, err := Create(client.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.VolumeID, "1234") - th.AssertEquals(t, n.Name, "snapshot-001") - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestUpdateMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockUpdateMetadataResponse(t) - - expected := map[string]interface{}{"key": "v1"} - - options := &UpdateMetadataOpts{ - Metadata: map[string]interface{}{ - "key": "v1", - }, - } - - actual, err := UpdateMetadata(client.ServiceClient(), "123", options).ExtractMetadata() - - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, actual, expected) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockDeleteResponse(t) - - res := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/results.go deleted file mode 100644 index e595798e4a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/results.go +++ /dev/null @@ -1,123 +0,0 @@ -package snapshots - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// Snapshot contains all the information associated with an OpenStack Snapshot. -type Snapshot struct { - // Currect status of the Snapshot. - Status string `mapstructure:"status"` - - // Display name. - Name string `mapstructure:"display_name"` - - // Instances onto which the Snapshot is attached. - Attachments []string `mapstructure:"attachments"` - - // Logical group. - AvailabilityZone string `mapstructure:"availability_zone"` - - // Is the Snapshot bootable? - Bootable string `mapstructure:"bootable"` - - // Date created. - CreatedAt string `mapstructure:"created_at"` - - // Display description. - Description string `mapstructure:"display_discription"` - - // See VolumeType object for more information. - VolumeType string `mapstructure:"volume_type"` - - // ID of the Snapshot from which this Snapshot was created. - SnapshotID string `mapstructure:"snapshot_id"` - - // ID of the Volume from which this Snapshot was created. - VolumeID string `mapstructure:"volume_id"` - - // User-defined key-value pairs. - Metadata map[string]string `mapstructure:"metadata"` - - // Unique identifier. - ID string `mapstructure:"id"` - - // Size of the Snapshot, in GB. - Size int `mapstructure:"size"` -} - -// CreateResult contains the response body and error from a Create request. -type CreateResult struct { - commonResult -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} - -// DeleteResult contains the response body and error from a Delete request. -type DeleteResult struct { - gophercloud.ErrResult -} - -// ListResult is a pagination.Pager that is returned from a call to the List function. -type ListResult struct { - pagination.SinglePageBase -} - -// IsEmpty returns true if a ListResult contains no Snapshots. -func (r ListResult) IsEmpty() (bool, error) { - volumes, err := ExtractSnapshots(r) - if err != nil { - return true, err - } - return len(volumes) == 0, nil -} - -// ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call. -func ExtractSnapshots(page pagination.Page) ([]Snapshot, error) { - var response struct { - Snapshots []Snapshot `json:"snapshots"` - } - - err := mapstructure.Decode(page.(ListResult).Body, &response) - return response.Snapshots, err -} - -// UpdateMetadataResult contains the response body and error from an UpdateMetadata request. -type UpdateMetadataResult struct { - commonResult -} - -// ExtractMetadata returns the metadata from a response from snapshots.UpdateMetadata. -func (r UpdateMetadataResult) ExtractMetadata() (map[string]interface{}, error) { - if r.Err != nil { - return nil, r.Err - } - - m := r.Body.(map[string]interface{})["metadata"] - return m.(map[string]interface{}), nil -} - -type commonResult struct { - gophercloud.Result -} - -// Extract will get the Snapshot object out of the commonResult object. -func (r commonResult) Extract() (*Snapshot, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Snapshot *Snapshot `json:"snapshot"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Snapshot, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/urls.go deleted file mode 100644 index 4d635e8dd4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/urls.go +++ /dev/null @@ -1,27 +0,0 @@ -package snapshots - -import "github.com/rackspace/gophercloud" - -func createURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("snapshots") -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("snapshots", id) -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return deleteURL(c, id) -} - -func listURL(c *gophercloud.ServiceClient) string { - return createURL(c) -} - -func metadataURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("snapshots", id, "metadata") -} - -func updateMetadataURL(c *gophercloud.ServiceClient, id string) string { - return metadataURL(c, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/urls_test.go deleted file mode 100644 index feacf7f69b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/urls_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package snapshots - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "snapshots" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "snapshots/foo" - th.AssertEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "snapshots/foo" - th.AssertEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "snapshots" - th.AssertEquals(t, expected, actual) -} - -func TestMetadataURL(t *testing.T) { - actual := metadataURL(endpointClient(), "foo") - expected := endpoint + "snapshots/foo/metadata" - th.AssertEquals(t, expected, actual) -} - -func TestUpdateMetadataURL(t *testing.T) { - actual := updateMetadataURL(endpointClient(), "foo") - expected := endpoint + "snapshots/foo/metadata" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/util.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/util.go deleted file mode 100644 index 64cdc607ec..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/util.go +++ /dev/null @@ -1,22 +0,0 @@ -package snapshots - -import ( - "github.com/rackspace/gophercloud" -) - -// WaitForStatus will continually poll the resource, checking for a particular -// status. It will do this for the amount of seconds defined. -func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error { - return gophercloud.WaitFor(secs, func() (bool, error) { - current, err := Get(c, id).Extract() - if err != nil { - return false, err - } - - if current.Status == status { - return true, nil - } - - return false, nil - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/doc.go deleted file mode 100644 index 307b8b12d2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package volumes provides information and interaction with volumes in the -// OpenStack Block Storage service. A volume is a detachable block storage -// device, akin to a USB hard drive. It can only be attached to one instance at -// a time. -package volumes diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures.go deleted file mode 100644 index a01ad05a38..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures.go +++ /dev/null @@ -1,105 +0,0 @@ -package volumes - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` - { - "volumes": [ - { - "id": "289da7f8-6440-407c-9fb4-7db01ec49164", - "display_name": "vol-001" - }, - { - "id": "96c3bda7-c82a-4f50-be73-ca7621794835", - "display_name": "vol-002" - } - ] - } - `) - }) -} - -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` -{ - "volume": { - "display_name": "vol-001", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) -} - -func MockCreateResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "volume": { - "size": 75 - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "volume": { - "size": 4, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) -} - -func MockDeleteResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) -} - -func MockUpdateResponse(t *testing.T) { - th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` - { - "volume": { - "display_name": "vol-002", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } - } - `) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go deleted file mode 100644 index f4332de657..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go +++ /dev/null @@ -1,217 +0,0 @@ -package volumes - -import ( - "fmt" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToVolumeCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains options for creating a Volume. This object is passed to -// the volumes.Create function. For more information about these parameters, -// see the Volume object. -type CreateOpts struct { - // OPTIONAL - Availability string - // OPTIONAL - Description string - // OPTIONAL - Metadata map[string]string - // OPTIONAL - Name string - // REQUIRED - Size int - // OPTIONAL - SnapshotID, SourceVolID, ImageID string - // OPTIONAL - VolumeType string -} - -// ToVolumeCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) { - v := make(map[string]interface{}) - - if opts.Size == 0 { - return nil, fmt.Errorf("Required CreateOpts field 'Size' not set.") - } - v["size"] = opts.Size - - if opts.Availability != "" { - v["availability_zone"] = opts.Availability - } - if opts.Description != "" { - v["display_description"] = opts.Description - } - if opts.ImageID != "" { - v["imageRef"] = opts.ImageID - } - if opts.Metadata != nil { - v["metadata"] = opts.Metadata - } - if opts.Name != "" { - v["display_name"] = opts.Name - } - if opts.SourceVolID != "" { - v["source_volid"] = opts.SourceVolID - } - if opts.SnapshotID != "" { - v["snapshot_id"] = opts.SnapshotID - } - if opts.VolumeType != "" { - v["volume_type"] = opts.VolumeType - } - - return map[string]interface{}{"volume": v}, nil -} - -// Create will create a new Volume based on the values in CreateOpts. To extract -// the Volume object from the response, call the Extract method on the -// CreateResult. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToVolumeCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201}, - }) - return res -} - -// Delete will delete the existing Volume with the provided ID. -func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202, 204}, - }) - return res -} - -// Get retrieves the Volume with the provided ID. To extract the Volume object -// from the response, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{ - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - return res -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToVolumeListQuery() (string, error) -} - -// ListOpts holds options for listing Volumes. It is passed to the volumes.List -// function. -type ListOpts struct { - // admin-only option. Set it to true to see all tenant volumes. - AllTenants bool `q:"all_tenants"` - // List only volumes that contain Metadata. - Metadata map[string]string `q:"metadata"` - // List only volumes that have Name as the display name. - Name string `q:"name"` - // List only volumes that have a status of Status. - Status string `q:"status"` -} - -// ToVolumeListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVolumeListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List returns Volumes optionally limited by the conditions provided in ListOpts. -func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToVolumeListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - createPage := func(r pagination.PageResult) pagination.Page { - return ListResult{pagination.SinglePageBase(r)} - } - return pagination.NewPager(client, url, createPage) -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToVolumeUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contain options for updating an existing Volume. This object is passed -// to the volumes.Update function. For more information about the parameters, see -// the Volume object. -type UpdateOpts struct { - // OPTIONAL - Name string - // OPTIONAL - Description string - // OPTIONAL - Metadata map[string]string -} - -// ToVolumeUpdateMap assembles a request body based on the contents of an -// UpdateOpts. -func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) { - v := make(map[string]interface{}) - - if opts.Description != "" { - v["display_description"] = opts.Description - } - if opts.Metadata != nil { - v["metadata"] = opts.Metadata - } - if opts.Name != "" { - v["display_name"] = opts.Name - } - - return map[string]interface{}{"volume": v}, nil -} - -// Update will update the Volume with provided information. To extract the updated -// Volume from the response, call the Extract method on the UpdateResult. -func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToVolumeUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - ReqBody: &reqBody, - Results: &res.Body, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go deleted file mode 100644 index 067f89bdd9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package volumes - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockListResponse(t) - - count := 0 - - List(client.ServiceClient(), &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVolumes(page) - if err != nil { - t.Errorf("Failed to extract volumes: %v", err) - return false, err - } - - expected := []Volume{ - Volume{ - ID: "289da7f8-6440-407c-9fb4-7db01ec49164", - Name: "vol-001", - }, - Volume{ - ID: "96c3bda7-c82a-4f50-be73-ca7621794835", - Name: "vol-002", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockGetResponse(t) - - v, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, v.Name, "vol-001") - th.AssertEquals(t, v.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockCreateResponse(t) - - options := &CreateOpts{Size: 75} - n, err := Create(client.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Size, 4) - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockDeleteResponse(t) - - res := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertNoErr(t, res.Err) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockUpdateResponse(t) - - options := UpdateOpts{Name: "vol-002"} - v, err := Update(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() - th.AssertNoErr(t, err) - th.CheckEquals(t, "vol-002", v.Name) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/results.go deleted file mode 100644 index c6ddbb5167..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/results.go +++ /dev/null @@ -1,113 +0,0 @@ -package volumes - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// Volume contains all the information associated with an OpenStack Volume. -type Volume struct { - // Current status of the volume. - Status string `mapstructure:"status"` - - // Human-readable display name for the volume. - Name string `mapstructure:"display_name"` - - // Instances onto which the volume is attached. - Attachments []string `mapstructure:"attachments"` - - // This parameter is no longer used. - AvailabilityZone string `mapstructure:"availability_zone"` - - // Indicates whether this is a bootable volume. - Bootable string `mapstructure:"bootable"` - - // The date when this volume was created. - CreatedAt string `mapstructure:"created_at"` - - // Human-readable description for the volume. - Description string `mapstructure:"display_discription"` - - // The type of volume to create, either SATA or SSD. - VolumeType string `mapstructure:"volume_type"` - - // The ID of the snapshot from which the volume was created - SnapshotID string `mapstructure:"snapshot_id"` - - // The ID of another block storage volume from which the current volume was created - SourceVolID string `mapstructure:"source_volid"` - - // Arbitrary key-value pairs defined by the user. - Metadata map[string]string `mapstructure:"metadata"` - - // Unique identifier for the volume. - ID string `mapstructure:"id"` - - // Size of the volume in GB. - Size int `mapstructure:"size"` -} - -// CreateResult contains the response body and error from a Create request. -type CreateResult struct { - commonResult -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} - -// DeleteResult contains the response body and error from a Delete request. -type DeleteResult struct { - gophercloud.ErrResult -} - -// ListResult is a pagination.pager that is returned from a call to the List function. -type ListResult struct { - pagination.SinglePageBase -} - -// IsEmpty returns true if a ListResult contains no Volumes. -func (r ListResult) IsEmpty() (bool, error) { - volumes, err := ExtractVolumes(r) - if err != nil { - return true, err - } - return len(volumes) == 0, nil -} - -// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call. -func ExtractVolumes(page pagination.Page) ([]Volume, error) { - var response struct { - Volumes []Volume `json:"volumes"` - } - - err := mapstructure.Decode(page.(ListResult).Body, &response) - return response.Volumes, err -} - -// UpdateResult contains the response body and error from an Update request. -type UpdateResult struct { - commonResult -} - -type commonResult struct { - gophercloud.Result -} - -// Extract will get the Volume object out of the commonResult object. -func (r commonResult) Extract() (*Volume, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Volume *Volume `json:"volume"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Volume, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/urls.go deleted file mode 100644 index 29629a1af8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package volumes - -import "github.com/rackspace/gophercloud" - -func createURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("volumes") -} - -func listURL(c *gophercloud.ServiceClient) string { - return createURL(c) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("volumes", id) -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return deleteURL(c, id) -} - -func updateURL(c *gophercloud.ServiceClient, id string) string { - return deleteURL(c, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/urls_test.go deleted file mode 100644 index a95270e14c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/urls_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package volumes - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "volumes" - th.AssertEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "volumes" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "volumes/foo" - th.AssertEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "volumes/foo" - th.AssertEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo") - expected := endpoint + "volumes/foo" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/util.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/util.go deleted file mode 100644 index 1dda695ea0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/util.go +++ /dev/null @@ -1,22 +0,0 @@ -package volumes - -import ( - "github.com/rackspace/gophercloud" -) - -// WaitForStatus will continually poll the resource, checking for a particular -// status. It will do this for the amount of seconds defined. -func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error { - return gophercloud.WaitFor(secs, func() (bool, error) { - current, err := Get(c, id).Extract() - if err != nil { - return false, err - } - - if current.Status == status { - return true, nil - } - - return false, nil - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/doc.go deleted file mode 100644 index 793084f89b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package volumetypes provides information and interaction with volume types -// in the OpenStack Block Storage service. A volume type indicates the type of -// a block storage volume, such as SATA, SCSCI, SSD, etc. These can be -// customized or defined by the OpenStack admin. -// -// You can also define extra_specs associated with your volume types. For -// instance, you could have a VolumeType=SATA, with extra_specs (RPM=10000, -// RAID-Level=5) . Extra_specs are defined and customized by the admin. -package volumetypes diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/fixtures.go deleted file mode 100644 index e3326eae14..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/fixtures.go +++ /dev/null @@ -1,60 +0,0 @@ -package volumetypes - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func MockListResponse(t *testing.T) { - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` - { - "volume_types": [ - { - "id": "289da7f8-6440-407c-9fb4-7db01ec49164", - "name": "vol-type-001", - "extra_specs": { - "capabilities": "gpu" - } - }, - { - "id": "96c3bda7-c82a-4f50-be73-ca7621794835", - "name": "vol-type-002", - "extra_specs": {} - } - ] - } - `) - }) -} - -func MockGetResponse(t *testing.T) { - th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` -{ - "volume_type": { - "name": "vol-type-001", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "extra_specs": { - "serverNumber": "2" - } - } -} - `) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/requests.go deleted file mode 100644 index 87e20f6003..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/requests.go +++ /dev/null @@ -1,87 +0,0 @@ -package volumetypes - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToVolumeTypeCreateMap() (map[string]interface{}, error) -} - -// CreateOpts are options for creating a volume type. -type CreateOpts struct { - // OPTIONAL. See VolumeType. - ExtraSpecs map[string]interface{} - // OPTIONAL. See VolumeType. - Name string -} - -// ToVolumeTypeCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToVolumeTypeCreateMap() (map[string]interface{}, error) { - vt := make(map[string]interface{}) - - if opts.ExtraSpecs != nil { - vt["extra_specs"] = opts.ExtraSpecs - } - if opts.Name != "" { - vt["name"] = opts.Name - } - - return map[string]interface{}{"volume_type": vt}, nil -} - -// Create will create a new volume. To extract the created volume type object, -// call the Extract method on the CreateResult. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToVolumeTypeCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200, 201}, - ReqBody: &reqBody, - Results: &res.Body, - }) - return res -} - -// Delete will delete the volume type with the provided ID. -func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} - -// Get will retrieve the volume type with the provided ID. To extract the volume -// type from the result, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, err := perigee.Request("GET", getURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - Results: &res.Body, - }) - res.Err = err - return res -} - -// List returns all volume types. -func List(client *gophercloud.ServiceClient) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return ListResult{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(client, listURL(client), createPage) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/requests_test.go deleted file mode 100644 index 8d40bfe1d4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/requests_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package volumetypes - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockListResponse(t) - - count := 0 - - List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVolumeTypes(page) - if err != nil { - t.Errorf("Failed to extract volume types: %v", err) - return false, err - } - - expected := []VolumeType{ - VolumeType{ - ID: "289da7f8-6440-407c-9fb4-7db01ec49164", - Name: "vol-type-001", - ExtraSpecs: map[string]interface{}{ - "capabilities": "gpu", - }, - }, - VolumeType{ - ID: "96c3bda7-c82a-4f50-be73-ca7621794835", - Name: "vol-type-002", - ExtraSpecs: map[string]interface{}{}, - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockGetResponse(t) - - vt, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, vt.ExtraSpecs, map[string]interface{}{"serverNumber": "2"}) - th.AssertEquals(t, vt.Name, "vol-type-001") - th.AssertEquals(t, vt.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "volume_type": { - "name": "vol-type-001" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "volume_type": { - "name": "vol-type-001", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) - - options := &CreateOpts{Name: "vol-type-001"} - n, err := Create(client.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Name, "vol-type-001") - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - w.WriteHeader(http.StatusAccepted) - }) - - err := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/results.go deleted file mode 100644 index c049a045d8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/results.go +++ /dev/null @@ -1,72 +0,0 @@ -package volumetypes - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// VolumeType contains all information associated with an OpenStack Volume Type. -type VolumeType struct { - ExtraSpecs map[string]interface{} `json:"extra_specs" mapstructure:"extra_specs"` // user-defined metadata - ID string `json:"id" mapstructure:"id"` // unique identifier - Name string `json:"name" mapstructure:"name"` // display name -} - -// CreateResult contains the response body and error from a Create request. -type CreateResult struct { - commonResult -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} - -// DeleteResult contains the response error from a Delete request. -type DeleteResult struct { - gophercloud.ErrResult -} - -// ListResult is a pagination.Pager that is returned from a call to the List function. -type ListResult struct { - pagination.SinglePageBase -} - -// IsEmpty returns true if a ListResult contains no Volume Types. -func (r ListResult) IsEmpty() (bool, error) { - volumeTypes, err := ExtractVolumeTypes(r) - if err != nil { - return true, err - } - return len(volumeTypes) == 0, nil -} - -// ExtractVolumeTypes extracts and returns Volume Types. -func ExtractVolumeTypes(page pagination.Page) ([]VolumeType, error) { - var response struct { - VolumeTypes []VolumeType `mapstructure:"volume_types"` - } - - err := mapstructure.Decode(page.(ListResult).Body, &response) - return response.VolumeTypes, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract will get the Volume Type object out of the commonResult object. -func (r commonResult) Extract() (*VolumeType, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - VolumeType *VolumeType `json:"volume_type" mapstructure:"volume_type"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.VolumeType, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/urls.go deleted file mode 100644 index cf8367bfab..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/urls.go +++ /dev/null @@ -1,19 +0,0 @@ -package volumetypes - -import "github.com/rackspace/gophercloud" - -func listURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("types") -} - -func createURL(c *gophercloud.ServiceClient) string { - return listURL(c) -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("types", id) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return getURL(c, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/urls_test.go deleted file mode 100644 index 44016e2954..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes/urls_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package volumetypes - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "types" - th.AssertEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "types" - th.AssertEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "types/foo" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "types/foo" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/client.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/client.go deleted file mode 100644 index 99b3d466d3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/client.go +++ /dev/null @@ -1,205 +0,0 @@ -package openstack - -import ( - "fmt" - "net/url" - - "github.com/rackspace/gophercloud" - tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" - tokens3 "github.com/rackspace/gophercloud/openstack/identity/v3/tokens" - "github.com/rackspace/gophercloud/openstack/utils" -) - -const ( - v20 = "v2.0" - v30 = "v3.0" -) - -// NewClient prepares an unauthenticated ProviderClient instance. -// Most users will probably prefer using the AuthenticatedClient function instead. -// This is useful if you wish to explicitly control the version of the identity service that's used for authentication explicitly, -// for example. -func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { - u, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - hadPath := u.Path != "" - u.Path, u.RawQuery, u.Fragment = "", "", "" - base := u.String() - - endpoint = gophercloud.NormalizeURL(endpoint) - base = gophercloud.NormalizeURL(base) - - if hadPath { - return &gophercloud.ProviderClient{ - IdentityBase: base, - IdentityEndpoint: endpoint, - }, nil - } - - return &gophercloud.ProviderClient{ - IdentityBase: base, - IdentityEndpoint: "", - }, nil -} - -// AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint specified by options, acquires a token, and -// returns a Client instance that's ready to operate. -// It first queries the root identity endpoint to determine which versions of the identity service are supported, then chooses -// the most recent identity service available to proceed. -func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) { - client, err := NewClient(options.IdentityEndpoint) - if err != nil { - return nil, err - } - - err = Authenticate(client, options) - if err != nil { - return nil, err - } - return client, nil -} - -// Authenticate or re-authenticate against the most recent identity service supported at the provided endpoint. -func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { - versions := []*utils.Version{ - &utils.Version{ID: v20, Priority: 20, Suffix: "/v2.0/"}, - &utils.Version{ID: v30, Priority: 30, Suffix: "/v3/"}, - } - - chosen, endpoint, err := utils.ChooseVersion(client.IdentityBase, client.IdentityEndpoint, versions) - if err != nil { - return err - } - - switch chosen.ID { - case v20: - return v2auth(client, endpoint, options) - case v30: - return v3auth(client, endpoint, options) - default: - // The switch statement must be out of date from the versions list. - return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) - } -} - -// AuthenticateV2 explicitly authenticates against the identity v2 endpoint. -func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { - return v2auth(client, "", options) -} - -func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error { - v2Client := NewIdentityV2(client) - if endpoint != "" { - v2Client.Endpoint = endpoint - } - - result := tokens2.Create(v2Client, tokens2.AuthOptions{AuthOptions: options}) - - token, err := result.ExtractToken() - if err != nil { - return err - } - - catalog, err := result.ExtractServiceCatalog() - if err != nil { - return err - } - - client.TokenID = token.ID - client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return V2EndpointURL(catalog, opts) - } - - return nil -} - -// AuthenticateV3 explicitly authenticates against the identity v3 service. -func AuthenticateV3(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { - return v3auth(client, "", options) -} - -func v3auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error { - // Override the generated service endpoint with the one returned by the version endpoint. - v3Client := NewIdentityV3(client) - if endpoint != "" { - v3Client.Endpoint = endpoint - } - - token, err := tokens3.Create(v3Client, options, nil).Extract() - if err != nil { - return err - } - client.TokenID = token.ID - - client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return V3EndpointURL(v3Client, opts) - } - - return nil -} - -// NewIdentityV2 creates a ServiceClient that may be used to interact with the v2 identity service. -func NewIdentityV2(client *gophercloud.ProviderClient) *gophercloud.ServiceClient { - v2Endpoint := client.IdentityBase + "v2.0/" - - return &gophercloud.ServiceClient{ - ProviderClient: client, - Endpoint: v2Endpoint, - } -} - -// NewIdentityV3 creates a ServiceClient that may be used to access the v3 identity service. -func NewIdentityV3(client *gophercloud.ProviderClient) *gophercloud.ServiceClient { - v3Endpoint := client.IdentityBase + "v3/" - - return &gophercloud.ServiceClient{ - ProviderClient: client, - Endpoint: v3Endpoint, - } -} - -// NewObjectStorageV1 creates a ServiceClient that may be used with the v1 object storage package. -func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("object-store") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} - -// NewComputeV2 creates a ServiceClient that may be used with the v2 compute package. -func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("compute") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} - -// NewNetworkV2 creates a ServiceClient that may be used with the v2 network package. -func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("network") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ - ProviderClient: client, - Endpoint: url, - ResourceBase: url + "v2.0/", - }, nil -} - -// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 block storage service. -func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("volume") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/client_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/client_test.go deleted file mode 100644 index 257260c4e1..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/client_test.go +++ /dev/null @@ -1,161 +0,0 @@ -package openstack - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAuthenticatedClientV3(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - const ID = "0123456789" - - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "versions": { - "values": [ - { - "status": "stable", - "id": "v3.0", - "links": [ - { "href": "%s", "rel": "self" } - ] - }, - { - "status": "stable", - "id": "v2.0", - "links": [ - { "href": "%s", "rel": "self" } - ] - } - ] - } - } - `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") - }) - - th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("X-Subject-Token", ID) - - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ "token": { "expires_at": "2013-02-02T18:30:59.000000Z" } }`) - }) - - options := gophercloud.AuthOptions{ - UserID: "me", - Password: "secret", - IdentityEndpoint: th.Endpoint(), - } - client, err := AuthenticatedClient(options) - th.AssertNoErr(t, err) - th.CheckEquals(t, ID, client.TokenID) -} - -func TestAuthenticatedClientV2(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "versions": { - "values": [ - { - "status": "experimental", - "id": "v3.0", - "links": [ - { "href": "%s", "rel": "self" } - ] - }, - { - "status": "stable", - "id": "v2.0", - "links": [ - { "href": "%s", "rel": "self" } - ] - } - ] - } - } - `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") - }) - - th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "access": { - "token": { - "id": "01234567890", - "expires": "2014-10-01T10:00:00.000000Z" - }, - "serviceCatalog": [ - { - "name": "Cloud Servers", - "type": "compute", - "endpoints": [ - { - "tenantId": "t1000", - "publicURL": "https://compute.north.host.com/v1/t1000", - "internalURL": "https://compute.north.internal/v1/t1000", - "region": "North", - "versionId": "1", - "versionInfo": "https://compute.north.host.com/v1/", - "versionList": "https://compute.north.host.com/" - }, - { - "tenantId": "t1000", - "publicURL": "https://compute.north.host.com/v1.1/t1000", - "internalURL": "https://compute.north.internal/v1.1/t1000", - "region": "North", - "versionId": "1.1", - "versionInfo": "https://compute.north.host.com/v1.1/", - "versionList": "https://compute.north.host.com/" - } - ], - "endpoints_links": [] - }, - { - "name": "Cloud Files", - "type": "object-store", - "endpoints": [ - { - "tenantId": "t1000", - "publicURL": "https://storage.north.host.com/v1/t1000", - "internalURL": "https://storage.north.internal/v1/t1000", - "region": "North", - "versionId": "1", - "versionInfo": "https://storage.north.host.com/v1/", - "versionList": "https://storage.north.host.com/" - }, - { - "tenantId": "t1000", - "publicURL": "https://storage.south.host.com/v1/t1000", - "internalURL": "https://storage.south.internal/v1/t1000", - "region": "South", - "versionId": "1", - "versionInfo": "https://storage.south.host.com/v1/", - "versionList": "https://storage.south.host.com/" - } - ] - } - ] - } - } - `) - }) - - options := gophercloud.AuthOptions{ - Username: "me", - Password: "secret", - IdentityEndpoint: th.Endpoint(), - } - client, err := AuthenticatedClient(options) - th.AssertNoErr(t, err) - th.CheckEquals(t, "01234567890", client.TokenID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/README.md b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/README.md deleted file mode 100644 index 7b55795d08..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Common Resources - -This directory is for resources that are shared by multiple services. diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/doc.go deleted file mode 100644 index 4a168f4b2c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// Package extensions provides information and interaction with the different extensions available -// for an OpenStack service. -// -// The purpose of OpenStack API extensions is to: -// -// - Introduce new features in the API without requiring a version change. -// - Introduce vendor-specific niche functionality. -// - Act as a proving ground for experimental functionalities that might be included in a future -// version of the API. -// -// Extensions usually have tags that prevent conflicts with other extensions that define attributes -// or resources with the same names, and with core resources and attributes. -// Because an extension might not be supported by all plug-ins, its availability varies with deployments -// and the specific plug-in. -package extensions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/errors.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/errors.go deleted file mode 100644 index aeec0fa756..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/errors.go +++ /dev/null @@ -1 +0,0 @@ -package extensions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/fixtures.go deleted file mode 100644 index 0ed7de9f1d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/fixtures.go +++ /dev/null @@ -1,91 +0,0 @@ -// +build fixtures - -package extensions - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -// ListOutput provides a single page of Extension results. -const ListOutput = ` -{ - "extensions": [ - { - "updated": "2013-01-20T00:00:00-00:00", - "name": "Neutron Service Type Management", - "links": [], - "namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - "alias": "service-type", - "description": "API for retrieving service providers for Neutron advanced services" - } - ] -}` - -// GetOutput provides a single Extension result. -const GetOutput = ` -{ - "extension": { - "updated": "2013-02-03T10:00:00-00:00", - "name": "agent", - "links": [], - "namespace": "http://docs.openstack.org/ext/agent/api/v2.0", - "alias": "agent", - "description": "The agent management extension." - } -} -` - -// ListedExtension is the Extension that should be parsed from ListOutput. -var ListedExtension = Extension{ - Updated: "2013-01-20T00:00:00-00:00", - Name: "Neutron Service Type Management", - Links: []interface{}{}, - Namespace: "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - Alias: "service-type", - Description: "API for retrieving service providers for Neutron advanced services", -} - -// ExpectedExtensions is a slice containing the Extension that should be parsed from ListOutput. -var ExpectedExtensions = []Extension{ListedExtension} - -// SingleExtension is the Extension that should be parsed from GetOutput. -var SingleExtension = &Extension{ - Updated: "2013-02-03T10:00:00-00:00", - Name: "agent", - Links: []interface{}{}, - Namespace: "http://docs.openstack.org/ext/agent/api/v2.0", - Alias: "agent", - Description: "The agent management extension.", -} - -// HandleListExtensionsSuccessfully creates an HTTP handler at `/extensions` on the test handler -// mux that response with a list containing a single tenant. -func HandleListExtensionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - - fmt.Fprintf(w, ListOutput) - }) -} - -// HandleGetExtensionSuccessfully creates an HTTP handler at `/extensions/agent` that responds with -// a JSON payload corresponding to SingleExtension. -func HandleGetExtensionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions/agent", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetOutput) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/requests.go deleted file mode 100644 index 3ca6e12f19..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/requests.go +++ /dev/null @@ -1,26 +0,0 @@ -package extensions - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// Get retrieves information for a specific extension using its alias. -func Get(c *gophercloud.ServiceClient, alias string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", ExtensionURL(c, alias), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// List returns a Pager which allows you to iterate over the full collection of extensions. -// It does not accept query parameters. -func List(c *gophercloud.ServiceClient) pagination.Pager { - return pagination.NewPager(c, ListExtensionURL(c), func(r pagination.PageResult) pagination.Page { - return ExtensionPage{pagination.SinglePageBase(r)} - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/requests_test.go deleted file mode 100644 index 6550283df7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/requests_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package extensions - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListExtensionsSuccessfully(t) - - count := 0 - - List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractExtensions(page) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedExtensions, actual) - - return true, nil - }) - - th.CheckEquals(t, 1, count) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetExtensionSuccessfully(t) - - actual, err := Get(client.ServiceClient(), "agent").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, SingleExtension, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/results.go deleted file mode 100644 index 777d083fa0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/results.go +++ /dev/null @@ -1,65 +0,0 @@ -package extensions - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// GetResult temporarily stores the result of a Get call. -// Use its Extract() method to interpret it as an Extension. -type GetResult struct { - gophercloud.Result -} - -// Extract interprets a GetResult as an Extension. -func (r GetResult) Extract() (*Extension, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Extension *Extension `json:"extension"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Extension, err -} - -// Extension is a struct that represents an OpenStack extension. -type Extension struct { - Updated string `json:"updated" mapstructure:"updated"` - Name string `json:"name" mapstructure:"name"` - Links []interface{} `json:"links" mapstructure:"links"` - Namespace string `json:"namespace" mapstructure:"namespace"` - Alias string `json:"alias" mapstructure:"alias"` - Description string `json:"description" mapstructure:"description"` -} - -// ExtensionPage is the page returned by a pager when traversing over a collection of extensions. -type ExtensionPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether an ExtensionPage struct is empty. -func (r ExtensionPage) IsEmpty() (bool, error) { - is, err := ExtractExtensions(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the -// elements into a slice of Extension structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractExtensions(page pagination.Page) ([]Extension, error) { - var resp struct { - Extensions []Extension `mapstructure:"extensions"` - } - - err := mapstructure.Decode(page.(ExtensionPage).Body, &resp) - - return resp.Extensions, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/urls.go deleted file mode 100644 index 6460c66bc0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package extensions - -import "github.com/rackspace/gophercloud" - -// ExtensionURL generates the URL for an extension resource by name. -func ExtensionURL(c *gophercloud.ServiceClient, name string) string { - return c.ServiceURL("extensions", name) -} - -// ListExtensionURL generates the URL for the extensions resource collection. -func ListExtensionURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("extensions") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/urls_test.go deleted file mode 100644 index 3223b1ca8b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/common/extensions/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package extensions - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestExtensionURL(t *testing.T) { - actual := ExtensionURL(endpointClient(), "agent") - expected := endpoint + "extensions/agent" - th.AssertEquals(t, expected, actual) -} - -func TestListExtensionURL(t *testing.T) { - actual := ListExtensionURL(endpointClient()) - expected := endpoint + "extensions" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go deleted file mode 100644 index 5a976d1146..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go +++ /dev/null @@ -1,111 +0,0 @@ -package bootfromvolume - -import ( - "errors" - "strconv" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - - "github.com/racker/perigee" -) - -// SourceType represents the type of medium being used to create the volume. -type SourceType string - -const ( - Volume SourceType = "volume" - Snapshot SourceType = "snapshot" - Image SourceType = "image" -) - -// BlockDevice is a structure with options for booting a server instance -// from a volume. The volume may be created from an image, snapshot, or another -// volume. -type BlockDevice struct { - // BootIndex [optional] is the boot index. It defaults to 0. - BootIndex int `json:"boot_index"` - - // DeleteOnTermination [optional] specifies whether or not to delete the attached volume - // when the server is deleted. Defaults to `false`. - DeleteOnTermination bool `json:"delete_on_termination"` - - // DestinationType [optional] is the type that gets created. Possible values are "volume" - // and "local". - DestinationType string `json:"destination_type"` - - // SourceType [required] must be one of: "volume", "snapshot", "image". - SourceType SourceType `json:"source_type"` - - // UUID [required] is the unique identifier for the volume, snapshot, or image (see above) - UUID string `json:"uuid"` - - // VolumeSize [optional] is the size of the volume to create (in gigabytes). - VolumeSize int `json:"volume_size"` -} - -// CreateOptsExt is a structure that extends the server `CreateOpts` structure -// by allowing for a block device mapping. -type CreateOptsExt struct { - servers.CreateOptsBuilder - BlockDevice []BlockDevice `json:"block_device_mapping_v2,omitempty"` -} - -// ToServerCreateMap adds the block device mapping option to the base server -// creation options. -func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { - base, err := opts.CreateOptsBuilder.ToServerCreateMap() - if err != nil { - return nil, err - } - - if len(opts.BlockDevice) == 0 { - return nil, errors.New("Required fields UUID and SourceType not set.") - } - - serverMap := base["server"].(map[string]interface{}) - - blockDevice := make([]map[string]interface{}, len(opts.BlockDevice)) - - for i, bd := range opts.BlockDevice { - if string(bd.SourceType) == "" { - return nil, errors.New("SourceType must be one of: volume, image, snapshot.") - } - - blockDevice[i] = make(map[string]interface{}) - - blockDevice[i]["source_type"] = bd.SourceType - blockDevice[i]["boot_index"] = strconv.Itoa(bd.BootIndex) - blockDevice[i]["delete_on_termination"] = strconv.FormatBool(bd.DeleteOnTermination) - blockDevice[i]["volume_size"] = strconv.Itoa(bd.VolumeSize) - if bd.UUID != "" { - blockDevice[i]["uuid"] = bd.UUID - } - if bd.DestinationType != "" { - blockDevice[i]["destination_type"] = bd.DestinationType - } - - } - serverMap["block_device_mapping_v2"] = blockDevice - - return base, nil -} - -// Create requests the creation of a server from the given block device mapping. -func Create(client *gophercloud.ServiceClient, opts servers.CreateOptsBuilder) servers.CreateResult { - var res servers.CreateResult - - reqBody, err := opts.ToServerCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: reqBody, - Results: &res.Body, - OkCodes: []int{200, 202}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go deleted file mode 100644 index 5bf9137906..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package bootfromvolume - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestCreateOpts(t *testing.T) { - base := servers.CreateOpts{ - Name: "createdserver", - ImageRef: "asdfasdfasdf", - FlavorRef: "performance1-1", - } - - ext := CreateOptsExt{ - CreateOptsBuilder: base, - BlockDevice: []BlockDevice{ - BlockDevice{ - UUID: "123456", - SourceType: Image, - DestinationType: "volume", - VolumeSize: 10, - }, - }, - } - - expected := ` - { - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "block_device_mapping_v2":[ - { - "uuid":"123456", - "source_type":"image", - "destination_type":"volume", - "boot_index": "0", - "delete_on_termination": "false", - "volume_size": "10" - } - ] - } - } - ` - actual, err := ext.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go deleted file mode 100644 index f60329f0f3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go +++ /dev/null @@ -1,10 +0,0 @@ -package bootfromvolume - -import ( - os "github.com/rackspace/gophercloud/openstack/compute/v2/servers" -) - -// CreateResult temporarily contains the response from a Create call. -type CreateResult struct { - os.CreateResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go deleted file mode 100644 index 0cffe25ffd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package bootfromvolume - -import "github.com/rackspace/gophercloud" - -func createURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("os-volumes_boot") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls_test.go deleted file mode 100644 index 6ee647732d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package bootfromvolume - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestCreateURL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - c := client.ServiceClient() - - th.CheckEquals(t, c.Endpoint+"os-volumes_boot", createURL(c)) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/doc.go deleted file mode 100644 index 2571a1a5a7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/doc.go +++ /dev/null @@ -1 +0,0 @@ -package defsecrules diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/fixtures.go deleted file mode 100644 index c28e492d35..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/fixtures.go +++ /dev/null @@ -1,108 +0,0 @@ -package defsecrules - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -const rootPath = "/os-security-group-default-rules" - -func mockListRulesResponse(t *testing.T) { - th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group_default_rules": [ - { - "from_port": 80, - "id": "{ruleID}", - "ip_protocol": "TCP", - "ip_range": { - "cidr": "10.10.10.0/24" - }, - "to_port": 80 - } - ] -} - `) - }) -} - -func mockCreateRuleResponse(t *testing.T) { - th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "security_group_default_rule": { - "ip_protocol": "TCP", - "from_port": 80, - "to_port": 80, - "cidr": "10.10.12.0/24" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group_default_rule": { - "from_port": 80, - "id": "{ruleID}", - "ip_protocol": "TCP", - "ip_range": { - "cidr": "10.10.12.0/24" - }, - "to_port": 80 - } -} -`) - }) -} - -func mockGetRuleResponse(t *testing.T, ruleID string) { - url := rootPath + "/" + ruleID - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group_default_rule": { - "id": "{ruleID}", - "from_port": 80, - "to_port": 80, - "ip_protocol": "TCP", - "ip_range": { - "cidr": "10.10.12.0/24" - } - } -} - `) - }) -} - -func mockDeleteRuleResponse(t *testing.T, ruleID string) { - url := rootPath + "/" + ruleID - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/requests.go deleted file mode 100644 index 7d19741e10..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/requests.go +++ /dev/null @@ -1,111 +0,0 @@ -package defsecrules - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// List will return a collection of default rules. -func List(client *gophercloud.ServiceClient) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return DefaultRulePage{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(client, rootURL(client), createPage) -} - -// CreateOpts represents the configuration for adding a new default rule. -type CreateOpts struct { - // Required - the lower bound of the port range that will be opened. - FromPort int `json:"from_port"` - - // Required - the upper bound of the port range that will be opened. - ToPort int `json:"to_port"` - - // Required - the protocol type that will be allowed, e.g. TCP. - IPProtocol string `json:"ip_protocol"` - - // ONLY required if FromGroupID is blank. This represents the IP range that - // will be the source of network traffic to your security group. Use - // 0.0.0.0/0 to allow all IP addresses. - CIDR string `json:"cidr,omitempty"` -} - -// CreateOptsBuilder builds the create rule options into a serializable format. -type CreateOptsBuilder interface { - ToRuleCreateMap() (map[string]interface{}, error) -} - -// ToRuleCreateMap builds the create rule options into a serializable format. -func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) { - rule := make(map[string]interface{}) - - if opts.FromPort == 0 { - return rule, errors.New("A FromPort must be set") - } - if opts.ToPort == 0 { - return rule, errors.New("A ToPort must be set") - } - if opts.IPProtocol == "" { - return rule, errors.New("A IPProtocol must be set") - } - if opts.CIDR == "" { - return rule, errors.New("A CIDR must be set") - } - - rule["from_port"] = opts.FromPort - rule["to_port"] = opts.ToPort - rule["ip_protocol"] = opts.IPProtocol - rule["cidr"] = opts.CIDR - - return map[string]interface{}{"security_group_default_rule": rule}, nil -} - -// Create is the operation responsible for creating a new default rule. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var result CreateResult - - reqBody, err := opts.ToRuleCreateMap() - if err != nil { - result.Err = err - return result - } - - _, result.Err = perigee.Request("POST", rootURL(client), perigee.Options{ - Results: &result.Body, - ReqBody: &reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// Get will return details for a particular default rule. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var result GetResult - - _, result.Err = perigee.Request("GET", resourceURL(client, id), perigee.Options{ - Results: &result.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// Delete will permanently delete a default rule from the project. -func Delete(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { - var result gophercloud.ErrResult - - _, result.Err = perigee.Request("DELETE", resourceURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - - return result -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/requests_test.go deleted file mode 100644 index d4ebe87c56..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/requests_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package defsecrules - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ruleID = "{ruleID}" - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListRulesResponse(t) - - count := 0 - - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractDefaultRules(page) - th.AssertNoErr(t, err) - - expected := []DefaultRule{ - DefaultRule{ - FromPort: 80, - ID: ruleID, - IPProtocol: "TCP", - IPRange: secgroups.IPRange{CIDR: "10.10.10.0/24"}, - ToPort: 80, - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateRuleResponse(t) - - opts := CreateOpts{ - IPProtocol: "TCP", - FromPort: 80, - ToPort: 80, - CIDR: "10.10.12.0/24", - } - - group, err := Create(client.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - expected := &DefaultRule{ - ID: ruleID, - FromPort: 80, - ToPort: 80, - IPProtocol: "TCP", - IPRange: secgroups.IPRange{CIDR: "10.10.12.0/24"}, - } - th.AssertDeepEquals(t, expected, group) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetRuleResponse(t, ruleID) - - group, err := Get(client.ServiceClient(), ruleID).Extract() - th.AssertNoErr(t, err) - - expected := &DefaultRule{ - ID: ruleID, - FromPort: 80, - ToPort: 80, - IPProtocol: "TCP", - IPRange: secgroups.IPRange{CIDR: "10.10.12.0/24"}, - } - - th.AssertDeepEquals(t, expected, group) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteRuleResponse(t, ruleID) - - err := Delete(client.ServiceClient(), ruleID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/results.go deleted file mode 100644 index e588d3e327..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/results.go +++ /dev/null @@ -1,69 +0,0 @@ -package defsecrules - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups" - "github.com/rackspace/gophercloud/pagination" -) - -// DefaultRule represents a default rule - which is identical to a -// normal security rule. -type DefaultRule secgroups.Rule - -// DefaultRulePage is a single page of a DefaultRule collection. -type DefaultRulePage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a page of default rules contains any results. -func (page DefaultRulePage) IsEmpty() (bool, error) { - users, err := ExtractDefaultRules(page) - if err != nil { - return false, err - } - return len(users) == 0, nil -} - -// ExtractDefaultRules returns a slice of DefaultRules contained in a single -// page of results. -func ExtractDefaultRules(page pagination.Page) ([]DefaultRule, error) { - casted := page.(DefaultRulePage).Body - var response struct { - Rules []DefaultRule `mapstructure:"security_group_default_rules"` - } - - err := mapstructure.WeakDecode(casted, &response) - - return response.Rules, err -} - -type commonResult struct { - gophercloud.Result -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// Extract will extract a DefaultRule struct from most responses. -func (r commonResult) Extract() (*DefaultRule, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Rule DefaultRule `mapstructure:"security_group_default_rule"` - } - - err := mapstructure.WeakDecode(r.Body, &response) - - return &response.Rule, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/urls.go deleted file mode 100644 index cc928ab895..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/defsecrules/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package defsecrules - -import "github.com/rackspace/gophercloud" - -const rulepath = "os-security-group-default-rules" - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rulepath, id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rulepath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/delegate.go deleted file mode 100644 index 10079097b6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/delegate.go +++ /dev/null @@ -1,23 +0,0 @@ -package extensions - -import ( - "github.com/rackspace/gophercloud" - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtractExtensions interprets a Page as a slice of Extensions. -func ExtractExtensions(page pagination.Page) ([]common.Extension, error) { - return common.ExtractExtensions(page) -} - -// Get retrieves information for a specific extension using its alias. -func Get(c *gophercloud.ServiceClient, alias string) common.GetResult { - return common.Get(c, alias) -} - -// List returns a Pager which allows you to iterate over the full collection of extensions. -// It does not accept query parameters. -func List(c *gophercloud.ServiceClient) pagination.Pager { - return common.List(c) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/delegate_test.go deleted file mode 100644 index c3c525fa20..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/delegate_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package extensions - -import ( - "fmt" - "net/http" - "testing" - - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - - fmt.Fprintf(w, ` -{ - "extensions": [ - { - "updated": "2013-01-20T00:00:00-00:00", - "name": "Neutron Service Type Management", - "links": [], - "namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - "alias": "service-type", - "description": "API for retrieving service providers for Neutron advanced services" - } - ] -} - `) - }) - - count := 0 - List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractExtensions(page) - th.AssertNoErr(t, err) - - expected := []common.Extension{ - common.Extension{ - Updated: "2013-01-20T00:00:00-00:00", - Name: "Neutron Service Type Management", - Links: []interface{}{}, - Namespace: "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - Alias: "service-type", - Description: "API for retrieving service providers for Neutron advanced services", - }, - } - th.AssertDeepEquals(t, expected, actual) - - return true, nil - }) - th.CheckEquals(t, 1, count) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/extensions/agent", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "extension": { - "updated": "2013-02-03T10:00:00-00:00", - "name": "agent", - "links": [], - "namespace": "http://docs.openstack.org/ext/agent/api/v2.0", - "alias": "agent", - "description": "The agent management extension." - } -} - `) - }) - - ext, err := Get(client.ServiceClient(), "agent").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ext.Updated, "2013-02-03T10:00:00-00:00") - th.AssertEquals(t, ext.Name, "agent") - th.AssertEquals(t, ext.Namespace, "http://docs.openstack.org/ext/agent/api/v2.0") - th.AssertEquals(t, ext.Alias, "agent") - th.AssertEquals(t, ext.Description, "The agent management extension.") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/doc.go deleted file mode 100644 index 80785faca9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package diskconfig provides information and interaction with the Disk -// Config extension that works with the OpenStack Compute service. -package diskconfig diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests.go deleted file mode 100644 index 7407e0d175..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests.go +++ /dev/null @@ -1,114 +0,0 @@ -package diskconfig - -import ( - "errors" - - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" -) - -// DiskConfig represents one of the two possible settings for the DiskConfig option when creating, -// rebuilding, or resizing servers: Auto or Manual. -type DiskConfig string - -const ( - // Auto builds a server with a single partition the size of the target flavor disk and - // automatically adjusts the filesystem to fit the entire partition. Auto may only be used with - // images and servers that use a single EXT3 partition. - Auto DiskConfig = "AUTO" - - // Manual builds a server using whatever partition scheme and filesystem are present in the source - // image. If the target flavor disk is larger, the remaining space is left unpartitioned. This - // enables images to have non-EXT3 filesystems, multiple partitions, and so on, and enables you - // to manage the disk configuration. It also results in slightly shorter boot times. - Manual DiskConfig = "MANUAL" -) - -// ErrInvalidDiskConfig is returned if an invalid string is specified for a DiskConfig option. -var ErrInvalidDiskConfig = errors.New("DiskConfig must be either diskconfig.Auto or diskconfig.Manual.") - -// Validate ensures that a DiskConfig contains an appropriate value. -func (config DiskConfig) validate() error { - switch config { - case Auto, Manual: - return nil - default: - return ErrInvalidDiskConfig - } -} - -// CreateOptsExt adds a DiskConfig option to the base CreateOpts. -type CreateOptsExt struct { - servers.CreateOptsBuilder - - // DiskConfig [optional] controls how the created server's disk is partitioned. - DiskConfig DiskConfig `json:"OS-DCF:diskConfig,omitempty"` -} - -// ToServerCreateMap adds the diskconfig option to the base server creation options. -func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { - base, err := opts.CreateOptsBuilder.ToServerCreateMap() - if err != nil { - return nil, err - } - - if string(opts.DiskConfig) == "" { - return base, nil - } - - serverMap := base["server"].(map[string]interface{}) - serverMap["OS-DCF:diskConfig"] = string(opts.DiskConfig) - - return base, nil -} - -// RebuildOptsExt adds a DiskConfig option to the base RebuildOpts. -type RebuildOptsExt struct { - servers.RebuildOptsBuilder - - // DiskConfig [optional] controls how the rebuilt server's disk is partitioned. - DiskConfig DiskConfig -} - -// ToServerRebuildMap adds the diskconfig option to the base server rebuild options. -func (opts RebuildOptsExt) ToServerRebuildMap() (map[string]interface{}, error) { - err := opts.DiskConfig.validate() - if err != nil { - return nil, err - } - - base, err := opts.RebuildOptsBuilder.ToServerRebuildMap() - if err != nil { - return nil, err - } - - serverMap := base["rebuild"].(map[string]interface{}) - serverMap["OS-DCF:diskConfig"] = string(opts.DiskConfig) - - return base, nil -} - -// ResizeOptsExt adds a DiskConfig option to the base server resize options. -type ResizeOptsExt struct { - servers.ResizeOptsBuilder - - // DiskConfig [optional] controls how the resized server's disk is partitioned. - DiskConfig DiskConfig -} - -// ToServerResizeMap adds the diskconfig option to the base server creation options. -func (opts ResizeOptsExt) ToServerResizeMap() (map[string]interface{}, error) { - err := opts.DiskConfig.validate() - if err != nil { - return nil, err - } - - base, err := opts.ResizeOptsBuilder.ToServerResizeMap() - if err != nil { - return nil, err - } - - serverMap := base["resize"].(map[string]interface{}) - serverMap["OS-DCF:diskConfig"] = string(opts.DiskConfig) - - return base, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go deleted file mode 100644 index e3c26d49a5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package diskconfig - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestCreateOpts(t *testing.T) { - base := servers.CreateOpts{ - Name: "createdserver", - ImageRef: "asdfasdfasdf", - FlavorRef: "performance1-1", - } - - ext := CreateOptsExt{ - CreateOptsBuilder: base, - DiskConfig: Manual, - } - - expected := ` - { - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "OS-DCF:diskConfig": "MANUAL" - } - } - ` - actual, err := ext.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expected, actual) -} - -func TestRebuildOpts(t *testing.T) { - base := servers.RebuildOpts{ - Name: "rebuiltserver", - AdminPass: "swordfish", - ImageID: "asdfasdfasdf", - } - - ext := RebuildOptsExt{ - RebuildOptsBuilder: base, - DiskConfig: Auto, - } - - actual, err := ext.ToServerRebuildMap() - th.AssertNoErr(t, err) - - expected := ` - { - "rebuild": { - "name": "rebuiltserver", - "imageRef": "asdfasdfasdf", - "adminPass": "swordfish", - "OS-DCF:diskConfig": "AUTO" - } - } - ` - th.CheckJSONEquals(t, expected, actual) -} - -func TestResizeOpts(t *testing.T) { - base := servers.ResizeOpts{ - FlavorRef: "performance1-8", - } - - ext := ResizeOptsExt{ - ResizeOptsBuilder: base, - DiskConfig: Auto, - } - - actual, err := ext.ToServerResizeMap() - th.AssertNoErr(t, err) - - expected := ` - { - "resize": { - "flavorRef": "performance1-8", - "OS-DCF:diskConfig": "AUTO" - } - } - ` - th.CheckJSONEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/results.go deleted file mode 100644 index 10ec2dafcb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/results.go +++ /dev/null @@ -1,60 +0,0 @@ -package diskconfig - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" -) - -func commonExtract(result gophercloud.Result) (*DiskConfig, error) { - var resp struct { - Server struct { - DiskConfig string `mapstructure:"OS-DCF:diskConfig"` - } `mapstructure:"server"` - } - - err := mapstructure.Decode(result.Body, &resp) - if err != nil { - return nil, err - } - - config := DiskConfig(resp.Server.DiskConfig) - return &config, nil -} - -// ExtractGet returns the disk configuration from a servers.Get call. -func ExtractGet(result servers.GetResult) (*DiskConfig, error) { - return commonExtract(result.Result) -} - -// ExtractUpdate returns the disk configuration from a servers.Update call. -func ExtractUpdate(result servers.UpdateResult) (*DiskConfig, error) { - return commonExtract(result.Result) -} - -// ExtractRebuild returns the disk configuration from a servers.Rebuild call. -func ExtractRebuild(result servers.RebuildResult) (*DiskConfig, error) { - return commonExtract(result.Result) -} - -// ExtractDiskConfig returns the DiskConfig setting for a specific server acquired from an -// servers.ExtractServers call, while iterating through a Pager. -func ExtractDiskConfig(page pagination.Page, index int) (*DiskConfig, error) { - casted := page.(servers.ServerPage).Body - - type server struct { - DiskConfig string `mapstructure:"OS-DCF:diskConfig"` - } - var response struct { - Servers []server `mapstructure:"servers"` - } - - err := mapstructure.Decode(casted, &response) - if err != nil { - return nil, err - } - - config := DiskConfig(response.Servers[index].DiskConfig) - return &config, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/results_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/results_test.go deleted file mode 100644 index dd8d2b7dfa..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/results_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package diskconfig - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestExtractGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - servers.HandleServerGetSuccessfully(t) - - config, err := ExtractGet(servers.Get(client.ServiceClient(), "1234asdf")) - th.AssertNoErr(t, err) - th.CheckEquals(t, Manual, *config) -} - -func TestExtractUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - servers.HandleServerUpdateSuccessfully(t) - - r := servers.Update(client.ServiceClient(), "1234asdf", servers.UpdateOpts{ - Name: "new-name", - }) - config, err := ExtractUpdate(r) - th.AssertNoErr(t, err) - th.CheckEquals(t, Manual, *config) -} - -func TestExtractRebuild(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - servers.HandleRebuildSuccessfully(t, servers.SingleServerBody) - - r := servers.Rebuild(client.ServiceClient(), "1234asdf", servers.RebuildOpts{ - Name: "new-name", - AdminPass: "swordfish", - ImageID: "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - AccessIPv4: "1.2.3.4", - }) - config, err := ExtractRebuild(r) - th.AssertNoErr(t, err) - th.CheckEquals(t, Manual, *config) -} - -func TestExtractList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - servers.HandleServerListSuccessfully(t) - - pages := 0 - err := servers.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - pages++ - - config, err := ExtractDiskConfig(page, 0) - th.AssertNoErr(t, err) - th.CheckEquals(t, Manual, *config) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, pages, 1) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/doc.go deleted file mode 100644 index 2b447da1d6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package extensions provides information and interaction with the -// different extensions available for the OpenStack Compute service. -package extensions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go deleted file mode 100644 index 7b372a355f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go +++ /dev/null @@ -1,113 +0,0 @@ -package keypairs - -import ( - "errors" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" -) - -// CreateOptsExt adds a KeyPair option to the base CreateOpts. -type CreateOptsExt struct { - servers.CreateOptsBuilder - KeyName string `json:"key_name,omitempty"` -} - -// ToServerCreateMap adds the key_name and, optionally, key_data options to -// the base server creation options. -func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { - base, err := opts.CreateOptsBuilder.ToServerCreateMap() - if err != nil { - return nil, err - } - - if opts.KeyName == "" { - return base, nil - } - - serverMap := base["server"].(map[string]interface{}) - serverMap["key_name"] = opts.KeyName - - return base, nil -} - -// List returns a Pager that allows you to iterate over a collection of KeyPairs. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { - return KeyPairPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the -// CreateOpts struct in this package does. -type CreateOptsBuilder interface { - ToKeyPairCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies keypair creation or import parameters. -type CreateOpts struct { - // Name [required] is a friendly name to refer to this KeyPair in other services. - Name string - - // PublicKey [optional] is a pregenerated OpenSSH-formatted public key. If provided, this key - // will be imported and no new key will be created. - PublicKey string -} - -// ToKeyPairCreateMap constructs a request body from CreateOpts. -func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) { - if opts.Name == "" { - return nil, errors.New("Missing field required for keypair creation: Name") - } - - keypair := make(map[string]interface{}) - keypair["name"] = opts.Name - if opts.PublicKey != "" { - keypair["public_key"] = opts.PublicKey - } - - return map[string]interface{}{"keypair": keypair}, nil -} - -// Create requests the creation of a new keypair on the server, or to import a pre-existing -// keypair. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToKeyPairCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Get returns public data about a previously uploaded KeyPair. -func Get(client *gophercloud.ServiceClient, name string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(client, name), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Delete requests the deletion of a previous stored KeyPair from the server. -func Delete(client *gophercloud.ServiceClient, name string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(client, name), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests_test.go deleted file mode 100644 index 67d1833f57..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package keypairs - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListSuccessfully(t) - - count := 0 - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractKeyPairs(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedKeyPairSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateSuccessfully(t) - - actual, err := Create(client.ServiceClient(), CreateOpts{ - Name: "createdkey", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &CreatedKeyPair, actual) -} - -func TestImport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleImportSuccessfully(t) - - actual, err := Create(client.ServiceClient(), CreateOpts{ - Name: "importedkey", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &ImportedKeyPair, actual) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetSuccessfully(t) - - actual, err := Get(client.ServiceClient(), "firstkey").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &FirstKeyPair, actual) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) - - err := Delete(client.ServiceClient(), "deletedkey").ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls_test.go deleted file mode 100644 index 60efd2a5d3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package keypairs - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListURL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - c := client.ServiceClient() - - th.CheckEquals(t, c.Endpoint+"os-keypairs", listURL(c)) -} - -func TestCreateURL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - c := client.ServiceClient() - - th.CheckEquals(t, c.Endpoint+"os-keypairs", createURL(c)) -} - -func TestGetURL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - c := client.ServiceClient() - - th.CheckEquals(t, c.Endpoint+"os-keypairs/wat", getURL(c, "wat")) -} - -func TestDeleteURL(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - c := client.ServiceClient() - - th.CheckEquals(t, c.Endpoint+"os-keypairs/wat", deleteURL(c, "wat")) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go deleted file mode 100644 index 702f32c985..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go +++ /dev/null @@ -1 +0,0 @@ -package secgroups diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go deleted file mode 100644 index ca76f686b8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go +++ /dev/null @@ -1,265 +0,0 @@ -package secgroups - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -const rootPath = "/os-security-groups" - -const listGroupsJSON = ` -{ - "security_groups": [ - { - "description": "default", - "id": "{groupID}", - "name": "default", - "rules": [], - "tenant_id": "openstack" - } - ] -} -` - -func mockListGroupsResponse(t *testing.T) { - th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, listGroupsJSON) - }) -} - -func mockListGroupsByServerResponse(t *testing.T, serverID string) { - url := fmt.Sprintf("%s/servers/%s%s", rootPath, serverID, rootPath) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, listGroupsJSON) - }) -} - -func mockCreateGroupResponse(t *testing.T) { - th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "security_group": { - "name": "test", - "description": "something" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group": { - "description": "something", - "id": "{groupID}", - "name": "test", - "rules": [], - "tenant_id": "openstack" - } -} -`) - }) -} - -func mockUpdateGroupResponse(t *testing.T, groupID string) { - url := fmt.Sprintf("%s/%s", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "security_group": { - "name": "new_name", - "description": "new_desc" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group": { - "description": "something", - "id": "{groupID}", - "name": "new_name", - "rules": [], - "tenant_id": "openstack" - } -} -`) - }) -} - -func mockGetGroupsResponse(t *testing.T, groupID string) { - url := fmt.Sprintf("%s/%s", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group": { - "description": "default", - "id": "{groupID}", - "name": "default", - "rules": [ - { - "from_port": 80, - "group": { - "tenant_id": "openstack", - "name": "default" - }, - "ip_protocol": "TCP", - "to_port": 85, - "parent_group_id": "{groupID}", - "ip_range": { - "cidr": "0.0.0.0" - }, - "id": "{ruleID}" - } - ], - "tenant_id": "openstack" - } -} - `) - }) -} - -func mockGetNumericIDGroupResponse(t *testing.T, groupID int) { - url := fmt.Sprintf("%s/%d", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group": { - "id": 12345 - } -} - `) - }) -} - -func mockDeleteGroupResponse(t *testing.T, groupID string) { - url := fmt.Sprintf("%s/%s", rootPath, groupID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockAddRuleResponse(t *testing.T) { - th.Mux.HandleFunc("/os-security-group-rules", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "security_group_rule": { - "from_port": 22, - "ip_protocol": "TCP", - "to_port": 22, - "parent_group_id": "{groupID}", - "cidr": "0.0.0.0/0" - } -} `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group_rule": { - "from_port": 22, - "group": {}, - "ip_protocol": "TCP", - "to_port": 22, - "parent_group_id": "{groupID}", - "ip_range": { - "cidr": "0.0.0.0/0" - }, - "id": "{ruleID}" - } -}`) - }) -} - -func mockDeleteRuleResponse(t *testing.T, ruleID string) { - url := fmt.Sprintf("/os-security-group-rules/%s", ruleID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockAddServerToGroupResponse(t *testing.T, serverID string) { - url := fmt.Sprintf("/servers/%s/action", serverID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "addSecurityGroup": { - "name": "test" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockRemoveServerFromGroupResponse(t *testing.T, serverID string) { - url := fmt.Sprintf("/servers/%s/action", serverID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "removeSecurityGroup": { - "name": "test" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/requests.go deleted file mode 100644 index 09503d715e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/requests.go +++ /dev/null @@ -1,298 +0,0 @@ -package secgroups - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -func commonList(client *gophercloud.ServiceClient, url string) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return SecurityGroupPage{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(client, url, createPage) -} - -// List will return a collection of all the security groups for a particular -// tenant. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return commonList(client, rootURL(client)) -} - -// ListByServer will return a collection of all the security groups which are -// associated with a particular server. -func ListByServer(client *gophercloud.ServiceClient, serverID string) pagination.Pager { - return commonList(client, listByServerURL(client, serverID)) -} - -// GroupOpts is the underlying struct responsible for creating or updating -// security groups. It therefore represents the mutable attributes of a -// security group. -type GroupOpts struct { - // Required - the name of your security group. - Name string `json:"name"` - - // Required - the description of your security group. - Description string `json:"description"` -} - -// CreateOpts is the struct responsible for creating a security group. -type CreateOpts GroupOpts - -// CreateOptsBuilder builds the create options into a serializable format. -type CreateOptsBuilder interface { - ToSecGroupCreateMap() (map[string]interface{}, error) -} - -var ( - errName = errors.New("Name is a required field") - errDesc = errors.New("Description is a required field") -) - -// ToSecGroupCreateMap builds the create options into a serializable format. -func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) { - sg := make(map[string]interface{}) - - if opts.Name == "" { - return sg, errName - } - if opts.Description == "" { - return sg, errDesc - } - - sg["name"] = opts.Name - sg["description"] = opts.Description - - return map[string]interface{}{"security_group": sg}, nil -} - -// Create will create a new security group. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var result CreateResult - - reqBody, err := opts.ToSecGroupCreateMap() - if err != nil { - result.Err = err - return result - } - - _, result.Err = perigee.Request("POST", rootURL(client), perigee.Options{ - Results: &result.Body, - ReqBody: &reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// UpdateOpts is the struct responsible for updating an existing security group. -type UpdateOpts GroupOpts - -// UpdateOptsBuilder builds the update options into a serializable format. -type UpdateOptsBuilder interface { - ToSecGroupUpdateMap() (map[string]interface{}, error) -} - -// ToSecGroupUpdateMap builds the update options into a serializable format. -func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) { - sg := make(map[string]interface{}) - - if opts.Name == "" { - return sg, errName - } - if opts.Description == "" { - return sg, errDesc - } - - sg["name"] = opts.Name - sg["description"] = opts.Description - - return map[string]interface{}{"security_group": sg}, nil -} - -// Update will modify the mutable properties of a security group, notably its -// name and description. -func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var result UpdateResult - - reqBody, err := opts.ToSecGroupUpdateMap() - if err != nil { - result.Err = err - return result - } - - _, result.Err = perigee.Request("PUT", resourceURL(client, id), perigee.Options{ - Results: &result.Body, - ReqBody: &reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// Get will return details for a particular security group. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var result GetResult - - _, result.Err = perigee.Request("GET", resourceURL(client, id), perigee.Options{ - Results: &result.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// Delete will permanently delete a security group from the project. -func Delete(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { - var result gophercloud.ErrResult - - _, result.Err = perigee.Request("DELETE", resourceURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return result -} - -// CreateRuleOpts represents the configuration for adding a new rule to an -// existing security group. -type CreateRuleOpts struct { - // Required - the ID of the group that this rule will be added to. - ParentGroupID string `json:"parent_group_id"` - - // Required - the lower bound of the port range that will be opened. - FromPort int `json:"from_port"` - - // Required - the upper bound of the port range that will be opened. - ToPort int `json:"to_port"` - - // Required - the protocol type that will be allowed, e.g. TCP. - IPProtocol string `json:"ip_protocol"` - - // ONLY required if FromGroupID is blank. This represents the IP range that - // will be the source of network traffic to your security group. Use - // 0.0.0.0/0 to allow all IP addresses. - CIDR string `json:"cidr,omitempty"` - - // ONLY required if CIDR is blank. This value represents the ID of a group - // that forwards traffic to the parent group. So, instead of accepting - // network traffic from an entire IP range, you can instead refine the - // inbound source by an existing security group. - FromGroupID string `json:"group_id,omitempty"` -} - -// CreateRuleOptsBuilder builds the create rule options into a serializable format. -type CreateRuleOptsBuilder interface { - ToRuleCreateMap() (map[string]interface{}, error) -} - -// ToRuleCreateMap builds the create rule options into a serializable format. -func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) { - rule := make(map[string]interface{}) - - if opts.ParentGroupID == "" { - return rule, errors.New("A ParentGroupID must be set") - } - if opts.FromPort == 0 { - return rule, errors.New("A FromPort must be set") - } - if opts.ToPort == 0 { - return rule, errors.New("A ToPort must be set") - } - if opts.IPProtocol == "" { - return rule, errors.New("A IPProtocol must be set") - } - if opts.CIDR == "" && opts.FromGroupID == "" { - return rule, errors.New("A CIDR or FromGroupID must be set") - } - - rule["parent_group_id"] = opts.ParentGroupID - rule["from_port"] = opts.FromPort - rule["to_port"] = opts.ToPort - rule["ip_protocol"] = opts.IPProtocol - - if opts.CIDR != "" { - rule["cidr"] = opts.CIDR - } - if opts.FromGroupID != "" { - rule["from_group_id"] = opts.FromGroupID - } - - return map[string]interface{}{"security_group_rule": rule}, nil -} - -// CreateRule will add a new rule to an existing security group (whose ID is -// specified in CreateRuleOpts). You have the option of controlling inbound -// traffic from either an IP range (CIDR) or from another security group. -func CreateRule(client *gophercloud.ServiceClient, opts CreateRuleOptsBuilder) CreateRuleResult { - var result CreateRuleResult - - reqBody, err := opts.ToRuleCreateMap() - if err != nil { - result.Err = err - return result - } - - _, result.Err = perigee.Request("POST", rootRuleURL(client), perigee.Options{ - Results: &result.Body, - ReqBody: &reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// DeleteRule will permanently delete a rule from a security group. -func DeleteRule(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { - var result gophercloud.ErrResult - - _, result.Err = perigee.Request("DELETE", resourceRuleURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return result -} - -func actionMap(prefix, groupName string) map[string]map[string]string { - return map[string]map[string]string{ - prefix + "SecurityGroup": map[string]string{"name": groupName}, - } -} - -// AddServerToGroup will associate a server and a security group, enforcing the -// rules of the group on the server. -func AddServerToGroup(client *gophercloud.ServiceClient, serverID, groupName string) gophercloud.ErrResult { - var result gophercloud.ErrResult - - _, result.Err = perigee.Request("POST", serverActionURL(client, serverID), perigee.Options{ - Results: &result.Body, - ReqBody: actionMap("add", groupName), - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return result -} - -// RemoveServerFromGroup will disassociate a server from a security group. -func RemoveServerFromGroup(client *gophercloud.ServiceClient, serverID, groupName string) gophercloud.ErrResult { - var result gophercloud.ErrResult - - _, result.Err = perigee.Request("POST", serverActionURL(client, serverID), perigee.Options{ - Results: &result.Body, - ReqBody: actionMap("remove", groupName), - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return result -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/requests_test.go deleted file mode 100644 index 4e21d5deaa..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/requests_test.go +++ /dev/null @@ -1,248 +0,0 @@ -package secgroups - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ( - serverID = "{serverID}" - groupID = "{groupID}" - ruleID = "{ruleID}" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListGroupsResponse(t) - - count := 0 - - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractSecurityGroups(page) - if err != nil { - t.Errorf("Failed to extract users: %v", err) - return false, err - } - - expected := []SecurityGroup{ - SecurityGroup{ - ID: groupID, - Description: "default", - Name: "default", - Rules: []Rule{}, - TenantID: "openstack", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestListByServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListGroupsByServerResponse(t, serverID) - - count := 0 - - err := ListByServer(client.ServiceClient(), serverID).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractSecurityGroups(page) - if err != nil { - t.Errorf("Failed to extract users: %v", err) - return false, err - } - - expected := []SecurityGroup{ - SecurityGroup{ - ID: groupID, - Description: "default", - Name: "default", - Rules: []Rule{}, - TenantID: "openstack", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateGroupResponse(t) - - opts := CreateOpts{ - Name: "test", - Description: "something", - } - - group, err := Create(client.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - expected := &SecurityGroup{ - ID: groupID, - Name: "test", - Description: "something", - TenantID: "openstack", - Rules: []Rule{}, - } - th.AssertDeepEquals(t, expected, group) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateGroupResponse(t, groupID) - - opts := UpdateOpts{ - Name: "new_name", - Description: "new_desc", - } - - group, err := Update(client.ServiceClient(), groupID, opts).Extract() - th.AssertNoErr(t, err) - - expected := &SecurityGroup{ - ID: groupID, - Name: "new_name", - Description: "something", - TenantID: "openstack", - Rules: []Rule{}, - } - th.AssertDeepEquals(t, expected, group) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetGroupsResponse(t, groupID) - - group, err := Get(client.ServiceClient(), groupID).Extract() - th.AssertNoErr(t, err) - - expected := &SecurityGroup{ - ID: groupID, - Description: "default", - Name: "default", - TenantID: "openstack", - Rules: []Rule{ - Rule{ - FromPort: 80, - ToPort: 85, - IPProtocol: "TCP", - IPRange: IPRange{CIDR: "0.0.0.0"}, - Group: Group{TenantID: "openstack", Name: "default"}, - ParentGroupID: groupID, - ID: ruleID, - }, - }, - } - - th.AssertDeepEquals(t, expected, group) -} - -func TestGetNumericID(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - numericGroupID := 12345 - - mockGetNumericIDGroupResponse(t, numericGroupID) - - group, err := Get(client.ServiceClient(), "12345").Extract() - th.AssertNoErr(t, err) - - expected := &SecurityGroup{ID: "12345"} - th.AssertDeepEquals(t, expected, group) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteGroupResponse(t, groupID) - - err := Delete(client.ServiceClient(), groupID).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestAddRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockAddRuleResponse(t) - - opts := CreateRuleOpts{ - ParentGroupID: groupID, - FromPort: 22, - ToPort: 22, - IPProtocol: "TCP", - CIDR: "0.0.0.0/0", - } - - rule, err := CreateRule(client.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - expected := &Rule{ - FromPort: 22, - ToPort: 22, - Group: Group{}, - IPProtocol: "TCP", - ParentGroupID: groupID, - IPRange: IPRange{CIDR: "0.0.0.0/0"}, - ID: ruleID, - } - - th.AssertDeepEquals(t, expected, rule) -} - -func TestDeleteRule(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteRuleResponse(t, ruleID) - - err := DeleteRule(client.ServiceClient(), ruleID).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestAddServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockAddServerToGroupResponse(t, serverID) - - err := AddServerToGroup(client.ServiceClient(), serverID, "test").ExtractErr() - th.AssertNoErr(t, err) -} - -func TestRemoveServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockRemoveServerFromGroupResponse(t, serverID) - - err := RemoveServerFromGroup(client.ServiceClient(), serverID, "test").ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/results.go deleted file mode 100644 index 478c5dc097..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/results.go +++ /dev/null @@ -1,147 +0,0 @@ -package secgroups - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// SecurityGroup represents a security group. -type SecurityGroup struct { - // The unique ID of the group. If Neutron is installed, this ID will be - // represented as a string UUID; if Neutron is not installed, it will be a - // numeric ID. For the sake of consistency, we always cast it to a string. - ID string - - // The human-readable name of the group, which needs to be unique. - Name string - - // The human-readable description of the group. - Description string - - // The rules which determine how this security group operates. - Rules []Rule - - // The ID of the tenant to which this security group belongs. - TenantID string `mapstructure:"tenant_id"` -} - -// Rule represents a security group rule, a policy which determines how a -// security group operates and what inbound traffic it allows in. -type Rule struct { - // The unique ID. If Neutron is installed, this ID will be - // represented as a string UUID; if Neutron is not installed, it will be a - // numeric ID. For the sake of consistency, we always cast it to a string. - ID string - - // The lower bound of the port range which this security group should open up - FromPort int `mapstructure:"from_port"` - - // The upper bound of the port range which this security group should open up - ToPort int `mapstructure:"to_port"` - - // The IP protocol (e.g. TCP) which the security group accepts - IPProtocol string `mapstructure:"ip_protocol"` - - // The CIDR IP range whose traffic can be received - IPRange IPRange `mapstructure:"ip_range"` - - // The security group ID to which this rule belongs - ParentGroupID string `mapstructure:"parent_group_id"` - - // Not documented. - Group Group -} - -// IPRange represents the IP range whose traffic will be accepted by the -// security group. -type IPRange struct { - CIDR string -} - -// Group represents a group. -type Group struct { - TenantID string `mapstructure:"tenant_id"` - Name string -} - -// SecurityGroupPage is a single page of a SecurityGroup collection. -type SecurityGroupPage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a page of Security Groups contains any results. -func (page SecurityGroupPage) IsEmpty() (bool, error) { - users, err := ExtractSecurityGroups(page) - if err != nil { - return false, err - } - return len(users) == 0, nil -} - -// ExtractSecurityGroups returns a slice of SecurityGroups contained in a single page of results. -func ExtractSecurityGroups(page pagination.Page) ([]SecurityGroup, error) { - casted := page.(SecurityGroupPage).Body - var response struct { - SecurityGroups []SecurityGroup `mapstructure:"security_groups"` - } - - err := mapstructure.WeakDecode(casted, &response) - - return response.SecurityGroups, err -} - -type commonResult struct { - gophercloud.Result -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// Extract will extract a SecurityGroup struct from most responses. -func (r commonResult) Extract() (*SecurityGroup, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - SecurityGroup SecurityGroup `mapstructure:"security_group"` - } - - err := mapstructure.WeakDecode(r.Body, &response) - - return &response.SecurityGroup, err -} - -// CreateRuleResult represents the result when adding rules to a security group. -type CreateRuleResult struct { - gophercloud.Result -} - -// Extract will extract a Rule struct from a CreateRuleResult. -func (r CreateRuleResult) Extract() (*Rule, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Rule Rule `mapstructure:"security_group_rule"` - } - - err := mapstructure.WeakDecode(r.Body, &response) - - return &response.Rule, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/urls.go deleted file mode 100644 index f4760b6f2e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/urls.go +++ /dev/null @@ -1,32 +0,0 @@ -package secgroups - -import "github.com/rackspace/gophercloud" - -const ( - secgrouppath = "os-security-groups" - rulepath = "os-security-group-rules" -) - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(secgrouppath, id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(secgrouppath) -} - -func listByServerURL(c *gophercloud.ServiceClient, serverID string) string { - return c.ServiceURL(secgrouppath, "servers", serverID, secgrouppath) -} - -func rootRuleURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rulepath) -} - -func resourceRuleURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rulepath, id) -} - -func serverActionURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("servers", id, "action") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests.go deleted file mode 100644 index 99c91b054a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests.go +++ /dev/null @@ -1,40 +0,0 @@ -package startstop - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -func actionURL(client *gophercloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "action") -} - -// Start is the operation responsible for starting a Compute server. -func Start(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { - var res gophercloud.ErrResult - - reqBody := map[string]interface{}{"os-start": nil} - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// Stop is the operation responsible for stopping a Compute server. -func Stop(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { - var res gophercloud.ErrResult - - reqBody := map[string]interface{}{"os-stop": nil} - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: reqBody, - OkCodes: []int{202}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests_test.go deleted file mode 100644 index 97a121b19a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package startstop - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const serverID = "{serverId}" - -func TestStart(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockStartServerResponse(t, serverID) - - err := Start(client.ServiceClient(), serverID).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestStop(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockStopServerResponse(t, serverID) - - err := Stop(client.ServiceClient(), serverID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go deleted file mode 100644 index 065a2ec472..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go +++ /dev/null @@ -1,72 +0,0 @@ -package flavors - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToFlavorListQuery() (string, error) -} - -// ListOpts helps control the results returned by the List() function. -// For example, a flavor with a minDisk field of 10 will not be returned if you specify MinDisk set to 20. -// Typically, software will use the last ID of the previous call to List to set the Marker for the current call. -type ListOpts struct { - - // ChangesSince, if provided, instructs List to return only those things which have changed since the timestamp provided. - ChangesSince string `q:"changes-since"` - - // MinDisk and MinRAM, if provided, elides flavors which do not meet your criteria. - MinDisk int `q:"minDisk"` - MinRAM int `q:"minRam"` - - // Marker and Limit control paging. - // Marker instructs List where to start listing from. - Marker string `q:"marker"` - - // Limit instructs List to refrain from sending excessively large lists of flavors. - Limit int `q:"limit"` -} - -// ToFlavorListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToFlavorListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// ListDetail instructs OpenStack to provide a list of flavors. -// You may provide criteria by which List curtails its results for easier processing. -// See ListOpts for more details. -func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToFlavorListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - createPage := func(r pagination.PageResult) pagination.Page { - return FlavorPage{pagination.LinkedPageBase{PageResult: r}} - } - - return pagination.NewPager(client, url, createPage) -} - -// Get instructs OpenStack to provide details on a single flavor, identified by its ID. -// Use ExtractFlavor to convert its result into a Flavor. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var gr GetResult - gr.Err = perigee.Get(getURL(client, id), perigee.Options{ - Results: &gr.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return gr -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests_test.go deleted file mode 100644 index fbd7c33140..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package flavors - -import ( - "fmt" - "net/http" - "reflect" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -const tokenID = "blerb" - -func TestListFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, ` - { - "flavors": [ - { - "id": "1", - "name": "m1.tiny", - "disk": 1, - "ram": 512, - "vcpus": 1 - }, - { - "id": "2", - "name": "m2.small", - "disk": 10, - "ram": 1024, - "vcpus": 2 - } - ], - "flavors_links": [ - { - "href": "%s/flavors/detail?marker=2", - "rel": "next" - } - ] - } - `, th.Server.URL) - case "2": - fmt.Fprintf(w, `{ "flavors": [] }`) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) - - pages := 0 - err := ListDetail(fake.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - pages++ - - actual, err := ExtractFlavors(page) - if err != nil { - return false, err - } - - expected := []Flavor{ - Flavor{ID: "1", Name: "m1.tiny", Disk: 1, RAM: 512, VCPUs: 1}, - Flavor{ID: "2", Name: "m2.small", Disk: 10, RAM: 1024, VCPUs: 2}, - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %#v, but was %#v", expected, actual) - } - - return true, nil - }) - if err != nil { - t.Fatal(err) - } - if pages != 1 { - t.Errorf("Expected one page, got %d", pages) - } -} - -func TestGetFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/flavors/12345", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "flavor": { - "id": "1", - "name": "m1.tiny", - "disk": 1, - "ram": 512, - "vcpus": 1, - "rxtx_factor": 1 - } - } - `) - }) - - actual, err := Get(fake.ServiceClient(), "12345").Extract() - if err != nil { - t.Fatalf("Unable to get flavor: %v", err) - } - - expected := &Flavor{ - ID: "1", - Name: "m1.tiny", - Disk: 1, - RAM: 512, - VCPUs: 1, - RxTxFactor: 1, - } - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %#v, but was %#v", expected, actual) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls_test.go deleted file mode 100644 index 069da2496e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package flavors - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "flavors/foo" - th.CheckEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "flavors/detail" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go deleted file mode 100644 index bc61ddb9df..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go +++ /dev/null @@ -1,71 +0,0 @@ -package images - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToImageListQuery() (string, error) -} - -// ListOpts contain options for limiting the number of Images returned from a call to ListDetail. -type ListOpts struct { - // When the image last changed status (in date-time format). - ChangesSince string `q:"changes-since"` - // The number of Images to return. - Limit int `q:"limit"` - // UUID of the Image at which to set a marker. - Marker string `q:"marker"` - // The name of the Image. - Name string `q:"name:"` - // The name of the Server (in URL format). - Server string `q:"server"` - // The current status of the Image. - Status string `q:"status"` - // The value of the type of image (e.g. BASE, SERVER, ALL) - Type string `q:"type"` -} - -// ToImageListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToImageListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// ListDetail enumerates the available images. -func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listDetailURL(client) - if opts != nil { - query, err := opts.ToImageListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - createPage := func(r pagination.PageResult) pagination.Page { - return ImagePage{pagination.LinkedPageBase{PageResult: r}} - } - - return pagination.NewPager(client, url, createPage) -} - -// Get acquires additional detail about a specific image by ID. -// Use ExtractImage() to interpret the result as an openstack Image. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var result GetResult - _, result.Err = perigee.Request("GET", getURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &result.Body, - OkCodes: []int{200}, - }) - return result -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests_test.go deleted file mode 100644 index 9a05f97ec0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package images - -import ( - "encoding/json" - "fmt" - "net/http" - "reflect" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListImages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/images/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, ` - { - "images": [ - { - "status": "ACTIVE", - "updated": "2014-09-23T12:54:56Z", - "id": "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7", - "OS-EXT-IMG-SIZE:size": 476704768, - "name": "F17-x86_64-cfntools", - "created": "2014-09-23T12:54:52Z", - "minDisk": 0, - "progress": 100, - "minRam": 0, - "metadata": {} - }, - { - "status": "ACTIVE", - "updated": "2014-09-23T12:51:43Z", - "id": "f90f6034-2570-4974-8351-6b49732ef2eb", - "OS-EXT-IMG-SIZE:size": 13167616, - "name": "cirros-0.3.2-x86_64-disk", - "created": "2014-09-23T12:51:42Z", - "minDisk": 0, - "progress": 100, - "minRam": 0, - "metadata": {} - } - ] - } - `) - case "2": - fmt.Fprintf(w, `{ "images": [] }`) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) - - pages := 0 - options := &ListOpts{Limit: 2} - err := ListDetail(fake.ServiceClient(), options).EachPage(func(page pagination.Page) (bool, error) { - pages++ - - actual, err := ExtractImages(page) - if err != nil { - return false, err - } - - expected := []Image{ - Image{ - ID: "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7", - Name: "F17-x86_64-cfntools", - Created: "2014-09-23T12:54:52Z", - Updated: "2014-09-23T12:54:56Z", - MinDisk: 0, - MinRAM: 0, - Progress: 100, - Status: "ACTIVE", - }, - Image{ - ID: "f90f6034-2570-4974-8351-6b49732ef2eb", - Name: "cirros-0.3.2-x86_64-disk", - Created: "2014-09-23T12:51:42Z", - Updated: "2014-09-23T12:51:43Z", - MinDisk: 0, - MinRAM: 0, - Progress: 100, - Status: "ACTIVE", - }, - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Unexpected page contents: expected %#v, got %#v", expected, actual) - } - - return false, nil - }) - - if err != nil { - t.Fatalf("EachPage error: %v", err) - } - if pages != 1 { - t.Errorf("Expected one page, got %d", pages) - } -} - -func TestGetImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/images/12345678", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "image": { - "status": "ACTIVE", - "updated": "2014-09-23T12:54:56Z", - "id": "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7", - "OS-EXT-IMG-SIZE:size": 476704768, - "name": "F17-x86_64-cfntools", - "created": "2014-09-23T12:54:52Z", - "minDisk": 0, - "progress": 100, - "minRam": 0, - "metadata": {} - } - } - `) - }) - - actual, err := Get(fake.ServiceClient(), "12345678").Extract() - if err != nil { - t.Fatalf("Unexpected error from Get: %v", err) - } - - expected := &Image{ - Status: "ACTIVE", - Updated: "2014-09-23T12:54:56Z", - ID: "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7", - Name: "F17-x86_64-cfntools", - Created: "2014-09-23T12:54:52Z", - MinDisk: 0, - Progress: 100, - MinRAM: 0, - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %#v, but got %#v", expected, actual) - } -} - -func TestNextPageURL(t *testing.T) { - var page ImagePage - var body map[string]interface{} - bodyString := []byte(`{"images":{"links":[{"href":"http://192.154.23.87/12345/images/image3","rel":"bookmark"}]}, "images_links":[{"href":"http://192.154.23.87/12345/images/image4","rel":"next"}]}`) - err := json.Unmarshal(bodyString, &body) - if err != nil { - t.Fatalf("Error unmarshaling data into page body: %v", err) - } - page.Body = body - - expected := "http://192.154.23.87/12345/images/image4" - actual, err := page.NextPageURL() - th.AssertNoErr(t, err) - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls_test.go deleted file mode 100644 index b1ab3d6790..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package images - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "images/foo" - th.CheckEquals(t, expected, actual) -} - -func TestListDetailURL(t *testing.T) { - actual := listDetailURL(endpointClient()) - expected := endpoint + "images/detail" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/fixtures.go deleted file mode 100644 index 01646058e6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/fixtures.go +++ /dev/null @@ -1,559 +0,0 @@ -// +build fixtures - -package servers - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -// ServerListBody contains the canned body of a servers.List response. -const ServerListBody = ` -{ - "servers": [ - { - "status": "ACTIVE", - "updated": "2014-09-25T13:10:10Z", - "hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", - "OS-EXT-SRV-ATTR:host": "devstack", - "addresses": { - "private": [ - { - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b", - "version": 4, - "addr": "10.0.0.32", - "OS-EXT-IPS:type": "fixed" - } - ] - }, - "links": [ - { - "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", - "rel": "self" - }, - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", - "rel": "bookmark" - } - ], - "key_name": null, - "image": { - "id": "f90f6034-2570-4974-8351-6b49732ef2eb", - "links": [ - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - "rel": "bookmark" - } - ] - }, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "OS-EXT-SRV-ATTR:instance_name": "instance-0000001e", - "OS-SRV-USG:launched_at": "2014-09-25T13:10:10.000000", - "OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack", - "flavor": { - "id": "1", - "links": [ - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", - "rel": "bookmark" - } - ] - }, - "id": "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", - "security_groups": [ - { - "name": "default" - } - ], - "OS-SRV-USG:terminated_at": null, - "OS-EXT-AZ:availability_zone": "nova", - "user_id": "9349aff8be7545ac9d2f1d00999a23cd", - "name": "herp", - "created": "2014-09-25T13:10:02Z", - "tenant_id": "fcad67a6189847c4aecfa3c81a05783b", - "OS-DCF:diskConfig": "MANUAL", - "os-extended-volumes:volumes_attached": [], - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "OS-EXT-STS:power_state": 1, - "config_drive": "", - "metadata": {} - }, - { - "status": "ACTIVE", - "updated": "2014-09-25T13:04:49Z", - "hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", - "OS-EXT-SRV-ATTR:host": "devstack", - "addresses": { - "private": [ - { - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be", - "version": 4, - "addr": "10.0.0.31", - "OS-EXT-IPS:type": "fixed" - } - ] - }, - "links": [ - { - "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "rel": "self" - }, - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "rel": "bookmark" - } - ], - "key_name": null, - "image": { - "id": "f90f6034-2570-4974-8351-6b49732ef2eb", - "links": [ - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - "rel": "bookmark" - } - ] - }, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "OS-EXT-SRV-ATTR:instance_name": "instance-0000001d", - "OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000", - "OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack", - "flavor": { - "id": "1", - "links": [ - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", - "rel": "bookmark" - } - ] - }, - "id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "security_groups": [ - { - "name": "default" - } - ], - "OS-SRV-USG:terminated_at": null, - "OS-EXT-AZ:availability_zone": "nova", - "user_id": "9349aff8be7545ac9d2f1d00999a23cd", - "name": "derp", - "created": "2014-09-25T13:04:41Z", - "tenant_id": "fcad67a6189847c4aecfa3c81a05783b", - "OS-DCF:diskConfig": "MANUAL", - "os-extended-volumes:volumes_attached": [], - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "OS-EXT-STS:power_state": 1, - "config_drive": "", - "metadata": {} - } - ] -} -` - -// SingleServerBody is the canned body of a Get request on an existing server. -const SingleServerBody = ` -{ - "server": { - "status": "ACTIVE", - "updated": "2014-09-25T13:04:49Z", - "hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", - "OS-EXT-SRV-ATTR:host": "devstack", - "addresses": { - "private": [ - { - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be", - "version": 4, - "addr": "10.0.0.31", - "OS-EXT-IPS:type": "fixed" - } - ] - }, - "links": [ - { - "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "rel": "self" - }, - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "rel": "bookmark" - } - ], - "key_name": null, - "image": { - "id": "f90f6034-2570-4974-8351-6b49732ef2eb", - "links": [ - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - "rel": "bookmark" - } - ] - }, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "OS-EXT-SRV-ATTR:instance_name": "instance-0000001d", - "OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000", - "OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack", - "flavor": { - "id": "1", - "links": [ - { - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", - "rel": "bookmark" - } - ] - }, - "id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "security_groups": [ - { - "name": "default" - } - ], - "OS-SRV-USG:terminated_at": null, - "OS-EXT-AZ:availability_zone": "nova", - "user_id": "9349aff8be7545ac9d2f1d00999a23cd", - "name": "derp", - "created": "2014-09-25T13:04:41Z", - "tenant_id": "fcad67a6189847c4aecfa3c81a05783b", - "OS-DCF:diskConfig": "MANUAL", - "os-extended-volumes:volumes_attached": [], - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "OS-EXT-STS:power_state": 1, - "config_drive": "", - "metadata": {} - } -} -` - -var ( - // ServerHerp is a Server struct that should correspond to the first result in ServerListBody. - ServerHerp = Server{ - Status: "ACTIVE", - Updated: "2014-09-25T13:10:10Z", - HostID: "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", - Addresses: map[string]interface{}{ - "private": []interface{}{ - map[string]interface{}{ - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b", - "version": float64(4), - "addr": "10.0.0.32", - "OS-EXT-IPS:type": "fixed", - }, - }, - }, - Links: []interface{}{ - map[string]interface{}{ - "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", - "rel": "self", - }, - map[string]interface{}{ - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", - "rel": "bookmark", - }, - }, - Image: map[string]interface{}{ - "id": "f90f6034-2570-4974-8351-6b49732ef2eb", - "links": []interface{}{ - map[string]interface{}{ - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "1", - "links": []interface{}{ - map[string]interface{}{ - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", - "rel": "bookmark", - }, - }, - }, - ID: "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", - UserID: "9349aff8be7545ac9d2f1d00999a23cd", - Name: "herp", - Created: "2014-09-25T13:10:02Z", - TenantID: "fcad67a6189847c4aecfa3c81a05783b", - Metadata: map[string]interface{}{}, - } - - // ServerDerp is a Server struct that should correspond to the second server in ServerListBody. - ServerDerp = Server{ - Status: "ACTIVE", - Updated: "2014-09-25T13:04:49Z", - HostID: "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", - Addresses: map[string]interface{}{ - "private": []interface{}{ - map[string]interface{}{ - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be", - "version": float64(4), - "addr": "10.0.0.31", - "OS-EXT-IPS:type": "fixed", - }, - }, - }, - Links: []interface{}{ - map[string]interface{}{ - "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "rel": "self", - }, - map[string]interface{}{ - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", - "rel": "bookmark", - }, - }, - Image: map[string]interface{}{ - "id": "f90f6034-2570-4974-8351-6b49732ef2eb", - "links": []interface{}{ - map[string]interface{}{ - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "1", - "links": []interface{}{ - map[string]interface{}{ - "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", - "rel": "bookmark", - }, - }, - }, - ID: "9e5476bd-a4ec-4653-93d6-72c93aa682ba", - UserID: "9349aff8be7545ac9d2f1d00999a23cd", - Name: "derp", - Created: "2014-09-25T13:04:41Z", - TenantID: "fcad67a6189847c4aecfa3c81a05783b", - Metadata: map[string]interface{}{}, - } -) - -// HandleServerCreationSuccessfully sets up the test server to respond to a server creation request -// with a given response. -func HandleServerCreationSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ - "server": { - "name": "derp", - "imageRef": "f90f6034-2570-4974-8351-6b49732ef2eb", - "flavorRef": "1" - } - }`) - - w.WriteHeader(http.StatusAccepted) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) - }) -} - -// HandleServerListSuccessfully sets up the test server to respond to a server List request. -func HandleServerListSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, ServerListBody) - case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": - fmt.Fprintf(w, `{ "servers": [] }`) - default: - t.Fatalf("/servers/detail invoked with unexpected marker=[%s]", marker) - } - }) -} - -// HandleServerDeletionSuccessfully sets up the test server to respond to a server deletion request. -func HandleServerDeletionSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleServerGetSuccessfully sets up the test server to respond to a server Get request. -func HandleServerGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - fmt.Fprintf(w, SingleServerBody) - }) -} - -// HandleServerUpdateSuccessfully sets up the test server to respond to a server Update request. -func HandleServerUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestJSONRequest(t, r, `{ "server": { "name": "new-name" } }`) - - fmt.Fprintf(w, SingleServerBody) - }) -} - -// HandleAdminPasswordChangeSuccessfully sets up the test server to respond to a server password -// change request. -func HandleAdminPasswordChangeSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ "changePassword": { "adminPass": "new-password" } }`) - - w.WriteHeader(http.StatusAccepted) - }) -} - -// HandleRebootSuccessfully sets up the test server to respond to a reboot request with success. -func HandleRebootSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ "reboot": { "type": "SOFT" } }`) - - w.WriteHeader(http.StatusAccepted) - }) -} - -// HandleRebuildSuccessfully sets up the test server to respond to a rebuild request with success. -func HandleRebuildSuccessfully(t *testing.T, response string) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, ` - { - "rebuild": { - "name": "new-name", - "adminPass": "swordfish", - "imageRef": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - "accessIPv4": "1.2.3.4" - } - } - `) - - w.WriteHeader(http.StatusAccepted) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, response) - }) -} - -// HandleServerRescueSuccessfully sets up the test server to respond to a server Rescue request. -func HandleServerRescueSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ "rescue": { "adminPass": "1234567890" } }`) - - w.WriteHeader(http.StatusOK) - w.Write([]byte(`{ "adminPass": "1234567890" }`)) - }) -} - -// HandleMetadatumGetSuccessfully sets up the test server to respond to a metadatum Get request. -func HandleMetadatumGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - w.Write([]byte(`{ "meta": {"foo":"bar"}}`)) - }) -} - -// HandleMetadatumCreateSuccessfully sets up the test server to respond to a metadatum Create request. -func HandleMetadatumCreateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ - "meta": { - "foo": "bar" - } - }`) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - w.Write([]byte(`{ "meta": {"foo":"bar"}}`)) - }) -} - -// HandleMetadatumDeleteSuccessfully sets up the test server to respond to a metadatum Delete request. -func HandleMetadatumDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleMetadataGetSuccessfully sets up the test server to respond to a metadata Get request. -func HandleMetadataGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - w.WriteHeader(http.StatusOK) - w.Write([]byte(`{ "metadata": {"foo":"bar", "this":"that"}}`)) - }) -} - -// HandleMetadataResetSuccessfully sets up the test server to respond to a metadata Create request. -func HandleMetadataResetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ - "metadata": { - "foo": "bar", - "this": "that" - } - }`) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - w.Write([]byte(`{ "metadata": {"foo":"bar", "this":"that"}}`)) - }) -} - -// HandleMetadataUpdateSuccessfully sets up the test server to respond to a metadata Update request. -func HandleMetadataUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ - "metadata": { - "foo": "baz", - "this": "those" - } - }`) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - w.Write([]byte(`{ "metadata": {"foo":"baz", "this":"those"}}`)) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go deleted file mode 100644 index 79d7998937..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go +++ /dev/null @@ -1,726 +0,0 @@ -package servers - -import ( - "encoding/base64" - "errors" - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToServerListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the server attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - // A time/date stamp for when the server last changed status. - ChangesSince string `q:"changes-since"` - - // Name of the image in URL format. - Image string `q:"image"` - - // Name of the flavor in URL format. - Flavor string `q:"flavor"` - - // Name of the server as a string; can be queried with regular expressions. - // Realize that ?name=bob returns both bob and bobb. If you need to match bob - // only, you can use a regular expression matching the syntax of the - // underlying database server implemented for Compute. - Name string `q:"name"` - - // Value of the status of the server so that you can filter on "ACTIVE" for example. - Status string `q:"status"` - - // Name of the host as a string. - Host string `q:"host"` - - // UUID of the server at which you want to set a marker. - Marker string `q:"marker"` - - // Integer value for the limit of values to return. - Limit int `q:"limit"` -} - -// ToServerListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToServerListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List makes a request against the API to list servers accessible to you. -func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listDetailURL(client) - - if opts != nil { - query, err := opts.ToServerListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - createPageFn := func(r pagination.PageResult) pagination.Page { - return ServerPage{pagination.LinkedPageBase{PageResult: r}} - } - - return pagination.NewPager(client, url, createPageFn) -} - -// CreateOptsBuilder describes struct types that can be accepted by the Create call. -// The CreateOpts struct in this package does. -type CreateOptsBuilder interface { - ToServerCreateMap() (map[string]interface{}, error) -} - -// Network is used within CreateOpts to control a new server's network attachments. -type Network struct { - // UUID of a nova-network to attach to the newly provisioned server. - // Required unless Port is provided. - UUID string - - // Port of a neutron network to attach to the newly provisioned server. - // Required unless UUID is provided. - Port string - - // FixedIP [optional] specifies a fixed IPv4 address to be used on this network. - FixedIP string -} - -// CreateOpts specifies server creation parameters. -type CreateOpts struct { - // Name [required] is the name to assign to the newly launched server. - Name string - - // ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state. - // Optional if using the boot-from-volume extension. - ImageRef string - - // FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs. - FlavorRef string - - // SecurityGroups [optional] lists the names of the security groups to which this server should belong. - SecurityGroups []string - - // UserData [optional] contains configuration information or scripts to use upon launch. - // Create will base64-encode it for you. - UserData []byte - - // AvailabilityZone [optional] in which to launch the server. - AvailabilityZone string - - // Networks [optional] dictates how this server will be attached to available networks. - // By default, the server will be attached to all isolated networks for the tenant. - Networks []Network - - // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. - Metadata map[string]string - - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte - - // ConfigDrive [optional] enables metadata injection through a configuration drive. - ConfigDrive bool - - // AdminPass [optional] sets the root user password. If not set, a randomly-generated - // password will be created and returned in the response. - AdminPass string -} - -// ToServerCreateMap assembles a request body based on the contents of a CreateOpts. -func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { - server := make(map[string]interface{}) - - server["name"] = opts.Name - server["imageRef"] = opts.ImageRef - server["flavorRef"] = opts.FlavorRef - - if opts.UserData != nil { - encoded := base64.StdEncoding.EncodeToString(opts.UserData) - server["user_data"] = &encoded - } - if opts.Personality != nil { - encoded := base64.StdEncoding.EncodeToString(opts.Personality) - server["personality"] = &encoded - } - if opts.ConfigDrive { - server["config_drive"] = "true" - } - if opts.AvailabilityZone != "" { - server["availability_zone"] = opts.AvailabilityZone - } - if opts.Metadata != nil { - server["metadata"] = opts.Metadata - } - if opts.AdminPass != "" { - server["adminPass"] = opts.AdminPass - } - - if len(opts.SecurityGroups) > 0 { - securityGroups := make([]map[string]interface{}, len(opts.SecurityGroups)) - for i, groupName := range opts.SecurityGroups { - securityGroups[i] = map[string]interface{}{"name": groupName} - } - server["security_groups"] = securityGroups - } - - if len(opts.Networks) > 0 { - networks := make([]map[string]interface{}, len(opts.Networks)) - for i, net := range opts.Networks { - networks[i] = make(map[string]interface{}) - if net.UUID != "" { - networks[i]["uuid"] = net.UUID - } - if net.Port != "" { - networks[i]["port"] = net.Port - } - if net.FixedIP != "" { - networks[i]["fixed_ip"] = net.FixedIP - } - } - server["networks"] = networks - } - - return map[string]interface{}{"server": server}, nil -} - -// Create requests a server to be provisioned to the user in the current tenant. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToServerCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", listURL(client), perigee.Options{ - Results: &res.Body, - ReqBody: reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} - -// Delete requests that a server previously provisioned be removed from your account. -func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} - -// Get requests details on a single server, by ID. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var result GetResult - _, result.Err = perigee.Request("GET", getURL(client, id), perigee.Options{ - Results: &result.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return result -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the Update request. -type UpdateOptsBuilder interface { - ToServerUpdateMap() map[string]interface{} -} - -// UpdateOpts specifies the base attributes that may be updated on an existing server. -type UpdateOpts struct { - // Name [optional] changes the displayed name of the server. - // The server host name will *not* change. - // Server names are not constrained to be unique, even within the same tenant. - Name string - - // AccessIPv4 [optional] provides a new IPv4 address for the instance. - AccessIPv4 string - - // AccessIPv6 [optional] provides a new IPv6 address for the instance. - AccessIPv6 string -} - -// ToServerUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToServerUpdateMap() map[string]interface{} { - server := make(map[string]string) - if opts.Name != "" { - server["name"] = opts.Name - } - if opts.AccessIPv4 != "" { - server["accessIPv4"] = opts.AccessIPv4 - } - if opts.AccessIPv6 != "" { - server["accessIPv6"] = opts.AccessIPv6 - } - return map[string]interface{}{"server": server} -} - -// Update requests that various attributes of the indicated server be changed. -func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var result UpdateResult - _, result.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{ - Results: &result.Body, - ReqBody: opts.ToServerUpdateMap(), - MoreHeaders: client.AuthenticatedHeaders(), - }) - return result -} - -// ChangeAdminPassword alters the administrator or root password for a specified server. -func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) ActionResult { - var req struct { - ChangePassword struct { - AdminPass string `json:"adminPass"` - } `json:"changePassword"` - } - - req.ChangePassword.AdminPass = newPassword - - var res ActionResult - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - ReqBody: req, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// ErrArgument errors occur when an argument supplied to a package function -// fails to fall within acceptable values. For example, the Reboot() function -// expects the "how" parameter to be one of HardReboot or SoftReboot. These -// constants are (currently) strings, leading someone to wonder if they can pass -// other string values instead, perhaps in an effort to break the API of their -// provider. Reboot() returns this error in this situation. -// -// Function identifies which function was called/which function is generating -// the error. -// Argument identifies which formal argument was responsible for producing the -// error. -// Value provides the value as it was passed into the function. -type ErrArgument struct { - Function, Argument string - Value interface{} -} - -// Error yields a useful diagnostic for debugging purposes. -func (e *ErrArgument) Error() string { - return fmt.Sprintf("Bad argument in call to %s, formal parameter %s, value %#v", e.Function, e.Argument, e.Value) -} - -func (e *ErrArgument) String() string { - return e.Error() -} - -// RebootMethod describes the mechanisms by which a server reboot can be requested. -type RebootMethod string - -// These constants determine how a server should be rebooted. -// See the Reboot() function for further details. -const ( - SoftReboot RebootMethod = "SOFT" - HardReboot RebootMethod = "HARD" - OSReboot = SoftReboot - PowerCycle = HardReboot -) - -// Reboot requests that a given server reboot. -// Two methods exist for rebooting a server: -// -// HardReboot (aka PowerCycle) restarts the server instance by physically cutting power to the machine, or if a VM, -// terminating it at the hypervisor level. -// It's done. Caput. Full stop. -// Then, after a brief while, power is restored or the VM instance restarted. -// -// SoftReboot (aka OSReboot) simply tells the OS to restart under its own procedures. -// E.g., in Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to restart the machine. -func Reboot(client *gophercloud.ServiceClient, id string, how RebootMethod) ActionResult { - var res ActionResult - - if (how != SoftReboot) && (how != HardReboot) { - res.Err = &ErrArgument{ - Function: "Reboot", - Argument: "how", - Value: how, - } - return res - } - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - ReqBody: struct { - C map[string]string `json:"reboot"` - }{ - map[string]string{"type": string(how)}, - }, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// RebuildOptsBuilder is an interface that allows extensions to override the -// default behaviour of rebuild options -type RebuildOptsBuilder interface { - ToServerRebuildMap() (map[string]interface{}, error) -} - -// RebuildOpts represents the configuration options used in a server rebuild -// operation -type RebuildOpts struct { - // Required. The ID of the image you want your server to be provisioned on - ImageID string - - // Name to set the server to - Name string - - // Required. The server's admin password - AdminPass string - - // AccessIPv4 [optional] provides a new IPv4 address for the instance. - AccessIPv4 string - - // AccessIPv6 [optional] provides a new IPv6 address for the instance. - AccessIPv6 string - - // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. - Metadata map[string]string - - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte -} - -// ToServerRebuildMap formats a RebuildOpts struct into a map for use in JSON -func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) { - var err error - server := make(map[string]interface{}) - - if opts.AdminPass == "" { - err = fmt.Errorf("AdminPass is required") - } - - if opts.ImageID == "" { - err = fmt.Errorf("ImageID is required") - } - - if err != nil { - return server, err - } - - server["name"] = opts.Name - server["adminPass"] = opts.AdminPass - server["imageRef"] = opts.ImageID - - if opts.AccessIPv4 != "" { - server["accessIPv4"] = opts.AccessIPv4 - } - - if opts.AccessIPv6 != "" { - server["accessIPv6"] = opts.AccessIPv6 - } - - if opts.Metadata != nil { - server["metadata"] = opts.Metadata - } - - if opts.Personality != nil { - encoded := base64.StdEncoding.EncodeToString(opts.Personality) - server["personality"] = &encoded - } - - return map[string]interface{}{"rebuild": server}, nil -} - -// Rebuild will reprovision the server according to the configuration options -// provided in the RebuildOpts struct. -func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuilder) RebuildResult { - var result RebuildResult - - if id == "" { - result.Err = fmt.Errorf("ID is required") - return result - } - - reqBody, err := opts.ToServerRebuildMap() - if err != nil { - result.Err = err - return result - } - - _, result.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - ReqBody: &reqBody, - Results: &result.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return result -} - -// ResizeOptsBuilder is an interface that allows extensions to override the default structure of -// a Resize request. -type ResizeOptsBuilder interface { - ToServerResizeMap() (map[string]interface{}, error) -} - -// ResizeOpts represents the configuration options used to control a Resize operation. -type ResizeOpts struct { - // FlavorRef is the ID of the flavor you wish your server to become. - FlavorRef string -} - -// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON request body for the -// Resize request. -func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) { - resize := map[string]interface{}{ - "flavorRef": opts.FlavorRef, - } - - return map[string]interface{}{"resize": resize}, nil -} - -// Resize instructs the provider to change the flavor of the server. -// Note that this implies rebuilding it. -// Unfortunately, one cannot pass rebuild parameters to the resize function. -// When the resize completes, the server will be in RESIZE_VERIFY state. -// While in this state, you can explore the use of the new server's configuration. -// If you like it, call ConfirmResize() to commit the resize permanently. -// Otherwise, call RevertResize() to restore the old configuration. -func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) ActionResult { - var res ActionResult - reqBody, err := opts.ToServerResizeMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - ReqBody: reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// ConfirmResize confirms a previous resize operation on a server. -// See Resize() for more details. -func ConfirmResize(client *gophercloud.ServiceClient, id string) ActionResult { - var res ActionResult - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - ReqBody: map[string]interface{}{"confirmResize": nil}, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - - return res -} - -// RevertResize cancels a previous resize operation on a server. -// See Resize() for more details. -func RevertResize(client *gophercloud.ServiceClient, id string) ActionResult { - var res ActionResult - - _, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - ReqBody: map[string]interface{}{"revertResize": nil}, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// RescueOptsBuilder is an interface that allows extensions to override the -// default structure of a Rescue request. -type RescueOptsBuilder interface { - ToServerRescueMap() (map[string]interface{}, error) -} - -// RescueOpts represents the configuration options used to control a Rescue -// option. -type RescueOpts struct { - // AdminPass is the desired administrative password for the instance in - // RESCUE mode. If it's left blank, the server will generate a password. - AdminPass string -} - -// ToServerRescueMap formats a RescueOpts as a map that can be used as a JSON -// request body for the Rescue request. -func (opts RescueOpts) ToServerRescueMap() (map[string]interface{}, error) { - server := make(map[string]interface{}) - if opts.AdminPass != "" { - server["adminPass"] = opts.AdminPass - } - return map[string]interface{}{"rescue": server}, nil -} - -// Rescue instructs the provider to place the server into RESCUE mode. -func Rescue(client *gophercloud.ServiceClient, id string, opts RescueOptsBuilder) RescueResult { - var result RescueResult - - if id == "" { - result.Err = fmt.Errorf("ID is required") - return result - } - reqBody, err := opts.ToServerRescueMap() - if err != nil { - result.Err = err - return result - } - - _, result.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{ - Results: &result.Body, - ReqBody: &reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// ResetMetadataOptsBuilder allows extensions to add additional parameters to the -// Reset request. -type ResetMetadataOptsBuilder interface { - ToMetadataResetMap() (map[string]interface{}, error) -} - -// MetadataOpts is a map that contains key-value pairs. -type MetadataOpts map[string]string - -// ToMetadataResetMap assembles a body for a Reset request based on the contents of a MetadataOpts. -func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) { - return map[string]interface{}{"metadata": opts}, nil -} - -// ToMetadataUpdateMap assembles a body for an Update request based on the contents of a MetadataOpts. -func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) { - return map[string]interface{}{"metadata": opts}, nil -} - -// ResetMetadata will create multiple new key-value pairs for the given server ID. -// Note: Using this operation will erase any already-existing metadata and create -// the new metadata provided. To keep any already-existing metadata, use the -// UpdateMetadatas or UpdateMetadata function. -func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) ResetMetadataResult { - var res ResetMetadataResult - metadata, err := opts.ToMetadataResetMap() - if err != nil { - res.Err = err - return res - } - _, res.Err = perigee.Request("PUT", metadataURL(client, id), perigee.Options{ - ReqBody: metadata, - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return res -} - -// Metadata requests all the metadata for the given server ID. -func Metadata(client *gophercloud.ServiceClient, id string) GetMetadataResult { - var res GetMetadataResult - _, res.Err = perigee.Request("GET", metadataURL(client, id), perigee.Options{ - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return res -} - -// UpdateMetadataOptsBuilder allows extensions to add additional parameters to the -// Create request. -type UpdateMetadataOptsBuilder interface { - ToMetadataUpdateMap() (map[string]interface{}, error) -} - -// UpdateMetadata updates (or creates) all the metadata specified by opts for the given server ID. -// This operation does not affect already-existing metadata that is not specified -// by opts. -func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) UpdateMetadataResult { - var res UpdateMetadataResult - metadata, err := opts.ToMetadataUpdateMap() - if err != nil { - res.Err = err - return res - } - _, res.Err = perigee.Request("POST", metadataURL(client, id), perigee.Options{ - ReqBody: metadata, - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return res -} - -// MetadatumOptsBuilder allows extensions to add additional parameters to the -// Create request. -type MetadatumOptsBuilder interface { - ToMetadatumCreateMap() (map[string]interface{}, string, error) -} - -// MetadatumOpts is a map of length one that contains a key-value pair. -type MetadatumOpts map[string]string - -// ToMetadatumCreateMap assembles a body for a Create request based on the contents of a MetadataumOpts. -func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) { - if len(opts) != 1 { - return nil, "", errors.New("CreateMetadatum operation must have 1 and only 1 key-value pair.") - } - metadatum := map[string]interface{}{"meta": opts} - var key string - for k := range metadatum["meta"].(MetadatumOpts) { - key = k - } - return metadatum, key, nil -} - -// CreateMetadatum will create or update the key-value pair with the given key for the given server ID. -func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts MetadatumOptsBuilder) CreateMetadatumResult { - var res CreateMetadatumResult - metadatum, key, err := opts.ToMetadatumCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", metadatumURL(client, id, key), perigee.Options{ - ReqBody: metadatum, - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return res -} - -// Metadatum requests the key-value pair with the given key for the given server ID. -func Metadatum(client *gophercloud.ServiceClient, id, key string) GetMetadatumResult { - var res GetMetadatumResult - _, res.Err = perigee.Request("GET", metadatumURL(client, id, key), perigee.Options{ - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return res -} - -// DeleteMetadatum will delete the key-value pair with the given key for the given server ID. -func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) DeleteMetadatumResult { - var res DeleteMetadatumResult - _, res.Err = perigee.Request("DELETE", metadatumURL(client, id, key), perigee.Options{ - Results: &res.Body, - MoreHeaders: client.AuthenticatedHeaders(), - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go deleted file mode 100644 index 017e793ccd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go +++ /dev/null @@ -1,266 +0,0 @@ -package servers - -import ( - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerListSuccessfully(t) - - pages := 0 - err := List(client.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - pages++ - - actual, err := ExtractServers(page) - if err != nil { - return false, err - } - - if len(actual) != 2 { - t.Fatalf("Expected 2 servers, got %d", len(actual)) - } - th.CheckDeepEquals(t, ServerHerp, actual[0]) - th.CheckDeepEquals(t, ServerDerp, actual[1]) - - return true, nil - }) - - th.AssertNoErr(t, err) - - if pages != 1 { - t.Errorf("Expected 1 page, saw %d", pages) - } -} - -func TestCreateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerCreationSuccessfully(t, SingleServerBody) - - actual, err := Create(client.ServiceClient(), CreateOpts{ - Name: "derp", - ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", - FlavorRef: "1", - }).Extract() - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, ServerDerp, *actual) -} - -func TestDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerDeletionSuccessfully(t) - - res := Delete(client.ServiceClient(), "asdfasdfasdf") - th.AssertNoErr(t, res.Err) -} - -func TestGetServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerGetSuccessfully(t) - - client := client.ServiceClient() - actual, err := Get(client, "1234asdf").Extract() - if err != nil { - t.Fatalf("Unexpected Get error: %v", err) - } - - th.CheckDeepEquals(t, ServerDerp, *actual) -} - -func TestUpdateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleServerUpdateSuccessfully(t) - - client := client.ServiceClient() - actual, err := Update(client, "1234asdf", UpdateOpts{Name: "new-name"}).Extract() - if err != nil { - t.Fatalf("Unexpected Update error: %v", err) - } - - th.CheckDeepEquals(t, ServerDerp, *actual) -} - -func TestChangeServerAdminPassword(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAdminPasswordChangeSuccessfully(t) - - res := ChangeAdminPassword(client.ServiceClient(), "1234asdf", "new-password") - th.AssertNoErr(t, res.Err) -} - -func TestRebootServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRebootSuccessfully(t) - - res := Reboot(client.ServiceClient(), "1234asdf", SoftReboot) - th.AssertNoErr(t, res.Err) -} - -func TestRebuildServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleRebuildSuccessfully(t, SingleServerBody) - - opts := RebuildOpts{ - Name: "new-name", - AdminPass: "swordfish", - ImageID: "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - AccessIPv4: "1.2.3.4", - } - - actual, err := Rebuild(client.ServiceClient(), "1234asdf", opts).Extract() - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, ServerDerp, *actual) -} - -func TestResizeServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ "resize": { "flavorRef": "2" } }`) - - w.WriteHeader(http.StatusAccepted) - }) - - res := Resize(client.ServiceClient(), "1234asdf", ResizeOpts{FlavorRef: "2"}) - th.AssertNoErr(t, res.Err) -} - -func TestConfirmResize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ "confirmResize": null }`) - - w.WriteHeader(http.StatusNoContent) - }) - - res := ConfirmResize(client.ServiceClient(), "1234asdf") - th.AssertNoErr(t, res.Err) -} - -func TestRevertResize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{ "revertResize": null }`) - - w.WriteHeader(http.StatusAccepted) - }) - - res := RevertResize(client.ServiceClient(), "1234asdf") - th.AssertNoErr(t, res.Err) -} - -func TestRescue(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleServerRescueSuccessfully(t) - - res := Rescue(client.ServiceClient(), "1234asdf", RescueOpts{ - AdminPass: "1234567890", - }) - th.AssertNoErr(t, res.Err) - adminPass, _ := res.Extract() - th.AssertEquals(t, "1234567890", adminPass) -} - -func TestGetMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleMetadatumGetSuccessfully(t) - - expected := map[string]string{"foo": "bar"} - actual, err := Metadatum(client.ServiceClient(), "1234asdf", "foo").Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expected, actual) -} - -func TestCreateMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleMetadatumCreateSuccessfully(t) - - expected := map[string]string{"foo": "bar"} - actual, err := CreateMetadatum(client.ServiceClient(), "1234asdf", MetadatumOpts{"foo": "bar"}).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expected, actual) -} - -func TestDeleteMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleMetadatumDeleteSuccessfully(t) - - err := DeleteMetadatum(client.ServiceClient(), "1234asdf", "foo").ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGetMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleMetadataGetSuccessfully(t) - - expected := map[string]string{"foo": "bar", "this": "that"} - actual, err := Metadata(client.ServiceClient(), "1234asdf").Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expected, actual) -} - -func TestResetMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleMetadataResetSuccessfully(t) - - expected := map[string]string{"foo": "bar", "this": "that"} - actual, err := ResetMetadata(client.ServiceClient(), "1234asdf", MetadataOpts{ - "foo": "bar", - "this": "that", - }).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expected, actual) -} - -func TestUpdateMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleMetadataUpdateSuccessfully(t) - - expected := map[string]string{"foo": "baz", "this": "those"} - actual, err := UpdateMetadata(client.ServiceClient(), "1234asdf", MetadataOpts{ - "foo": "baz", - "this": "those", - }).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/results.go deleted file mode 100644 index 3a145f8007..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/results.go +++ /dev/null @@ -1,237 +0,0 @@ -package servers - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -type serverResult struct { - gophercloud.Result -} - -// Extract interprets any serverResult as a Server, if possible. -func (r serverResult) Extract() (*Server, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Server Server `mapstructure:"server"` - } - - err := mapstructure.Decode(r.Body, &response) - return &response.Server, err -} - -// CreateResult temporarily contains the response from a Create call. -type CreateResult struct { - serverResult -} - -// GetResult temporarily contains the response from a Get call. -type GetResult struct { - serverResult -} - -// UpdateResult temporarily contains the response from an Update call. -type UpdateResult struct { - serverResult -} - -// DeleteResult temporarily contains the response from a Delete call. -type DeleteResult struct { - gophercloud.ErrResult -} - -// RebuildResult temporarily contains the response from a Rebuild call. -type RebuildResult struct { - serverResult -} - -// ActionResult represents the result of server action operations, like reboot -type ActionResult struct { - gophercloud.ErrResult -} - -// RescueResult represents the result of a server rescue operation -type RescueResult struct { - ActionResult -} - -// Extract interprets any RescueResult as an AdminPass, if possible. -func (r RescueResult) Extract() (string, error) { - if r.Err != nil { - return "", r.Err - } - - var response struct { - AdminPass string `mapstructure:"adminPass"` - } - - err := mapstructure.Decode(r.Body, &response) - return response.AdminPass, err -} - -// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account. -type Server struct { - // ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant. - ID string - - // TenantID identifies the tenant owning this server resource. - TenantID string `mapstructure:"tenant_id"` - - // UserID uniquely identifies the user account owning the tenant. - UserID string `mapstructure:"user_id"` - - // Name contains the human-readable name for the server. - Name string - - // Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created. - Updated string - Created string - - HostID string - - // Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE. - Status string - - // Progress ranges from 0..100. - // A request made against the server completes only once Progress reaches 100. - Progress int - - // AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration. - AccessIPv4, AccessIPv6 string - - // Image refers to a JSON object, which itself indicates the OS image used to deploy the server. - Image map[string]interface{} - - // Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server. - Flavor map[string]interface{} - - // Addresses includes a list of all IP addresses assigned to the server, keyed by pool. - Addresses map[string]interface{} - - // Metadata includes a list of all user-specified key-value pairs attached to the server. - Metadata map[string]interface{} - - // Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference. - Links []interface{} - - // KeyName indicates which public key was injected into the server on launch. - KeyName string `json:"key_name" mapstructure:"key_name"` - - // AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place. - // Note that this is the ONLY time this field will be valid. - AdminPass string `json:"adminPass" mapstructure:"adminPass"` -} - -// ServerPage abstracts the raw results of making a List() request against the API. -// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the -// data provided through the ExtractServers call. -type ServerPage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if a page contains no Server results. -func (page ServerPage) IsEmpty() (bool, error) { - servers, err := ExtractServers(page) - if err != nil { - return true, err - } - return len(servers) == 0, nil -} - -// NextPageURL uses the response's embedded link reference to navigate to the next page of results. -func (page ServerPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"servers_links"` - } - - var r resp - err := mapstructure.Decode(page.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities. -func ExtractServers(page pagination.Page) ([]Server, error) { - casted := page.(ServerPage).Body - - var response struct { - Servers []Server `mapstructure:"servers"` - } - err := mapstructure.Decode(casted, &response) - return response.Servers, err -} - -// MetadataResult contains the result of a call for (potentially) multiple key-value pairs. -type MetadataResult struct { - gophercloud.Result -} - -// GetMetadataResult temporarily contains the response from a metadata Get call. -type GetMetadataResult struct { - MetadataResult -} - -// ResetMetadataResult temporarily contains the response from a metadata Reset call. -type ResetMetadataResult struct { - MetadataResult -} - -// UpdateMetadataResult temporarily contains the response from a metadata Update call. -type UpdateMetadataResult struct { - MetadataResult -} - -// MetadatumResult contains the result of a call for individual a single key-value pair. -type MetadatumResult struct { - gophercloud.Result -} - -// GetMetadatumResult temporarily contains the response from a metadatum Get call. -type GetMetadatumResult struct { - MetadatumResult -} - -// CreateMetadatumResult temporarily contains the response from a metadatum Create call. -type CreateMetadatumResult struct { - MetadatumResult -} - -// DeleteMetadatumResult temporarily contains the response from a metadatum Delete call. -type DeleteMetadatumResult struct { - gophercloud.ErrResult -} - -// Extract interprets any MetadataResult as a Metadata, if possible. -func (r MetadataResult) Extract() (map[string]string, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Metadata map[string]string `mapstructure:"metadata"` - } - - err := mapstructure.Decode(r.Body, &response) - return response.Metadata, err -} - -// Extract interprets any MetadatumResult as a Metadatum, if possible. -func (r MetadatumResult) Extract() (map[string]string, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Metadatum map[string]string `mapstructure:"meta"` - } - - err := mapstructure.Decode(r.Body, &response) - return response.Metadatum, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls.go deleted file mode 100644 index 4bc6586a50..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls.go +++ /dev/null @@ -1,39 +0,0 @@ -package servers - -import "github.com/rackspace/gophercloud" - -func createURL(client *gophercloud.ServiceClient) string { - return client.ServiceURL("servers") -} - -func listURL(client *gophercloud.ServiceClient) string { - return createURL(client) -} - -func listDetailURL(client *gophercloud.ServiceClient) string { - return client.ServiceURL("servers", "detail") -} - -func deleteURL(client *gophercloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id) -} - -func getURL(client *gophercloud.ServiceClient, id string) string { - return deleteURL(client, id) -} - -func updateURL(client *gophercloud.ServiceClient, id string) string { - return deleteURL(client, id) -} - -func actionURL(client *gophercloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "action") -} - -func metadatumURL(client *gophercloud.ServiceClient, id, key string) string { - return client.ServiceURL("servers", id, "metadata", key) -} - -func metadataURL(client *gophercloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "metadata") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls_test.go deleted file mode 100644 index 17a1d287f2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package servers - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "servers" - th.CheckEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "servers" - th.CheckEquals(t, expected, actual) -} - -func TestListDetailURL(t *testing.T) { - actual := listDetailURL(endpointClient()) - expected := endpoint + "servers/detail" - th.CheckEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "servers/foo" - th.CheckEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "servers/foo" - th.CheckEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo") - expected := endpoint + "servers/foo" - th.CheckEquals(t, expected, actual) -} - -func TestActionURL(t *testing.T) { - actual := actionURL(endpointClient(), "foo") - expected := endpoint + "servers/foo/action" - th.CheckEquals(t, expected, actual) -} - -func TestMetadatumURL(t *testing.T) { - actual := metadatumURL(endpointClient(), "foo", "bar") - expected := endpoint + "servers/foo/metadata/bar" - th.CheckEquals(t, expected, actual) -} - -func TestMetadataURL(t *testing.T) { - actual := metadataURL(endpointClient(), "foo") - expected := endpoint + "servers/foo/metadata" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/endpoint_location.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/endpoint_location.go deleted file mode 100644 index 5a311e4085..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/endpoint_location.go +++ /dev/null @@ -1,124 +0,0 @@ -package openstack - -import ( - "fmt" - - "github.com/rackspace/gophercloud" - tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" - endpoints3 "github.com/rackspace/gophercloud/openstack/identity/v3/endpoints" - services3 "github.com/rackspace/gophercloud/openstack/identity/v3/services" - "github.com/rackspace/gophercloud/pagination" -) - -// V2EndpointURL discovers the endpoint URL for a specific service from a ServiceCatalog acquired -// during the v2 identity service. The specified EndpointOpts are used to identify a unique, -// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided -// criteria and when none do. The minimum that can be specified is a Type, but you will also often -// need to specify a Name and/or a Region depending on what's available on your OpenStack -// deployment. -func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { - // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. - var endpoints = make([]tokens2.Endpoint, 0, 1) - for _, entry := range catalog.Entries { - if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { - for _, endpoint := range entry.Endpoints { - if opts.Region == "" || endpoint.Region == opts.Region { - endpoints = append(endpoints, endpoint) - } - } - } - } - - // Report an error if the options were ambiguous. - if len(endpoints) > 1 { - return "", fmt.Errorf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints) - } - - // Extract the appropriate URL from the matching Endpoint. - for _, endpoint := range endpoints { - switch opts.Availability { - case gophercloud.AvailabilityPublic: - return gophercloud.NormalizeURL(endpoint.PublicURL), nil - case gophercloud.AvailabilityInternal: - return gophercloud.NormalizeURL(endpoint.InternalURL), nil - case gophercloud.AvailabilityAdmin: - return gophercloud.NormalizeURL(endpoint.AdminURL), nil - default: - return "", fmt.Errorf("Unexpected availability in endpoint query: %s", opts.Availability) - } - } - - // Report an error if there were no matching endpoints. - return "", gophercloud.ErrEndpointNotFound -} - -// V3EndpointURL discovers the endpoint URL for a specific service using multiple calls against -// an identity v3 service endpoint. The specified EndpointOpts are used to identify a unique, -// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided -// criteria and when none do. The minimum that can be specified is a Type, but you will also often -// need to specify a Name and/or a Region depending on what's available on your OpenStack -// deployment. -func V3EndpointURL(v3Client *gophercloud.ServiceClient, opts gophercloud.EndpointOpts) (string, error) { - // Discover the service we're interested in. - var services = make([]services3.Service, 0, 1) - servicePager := services3.List(v3Client, services3.ListOpts{ServiceType: opts.Type}) - err := servicePager.EachPage(func(page pagination.Page) (bool, error) { - part, err := services3.ExtractServices(page) - if err != nil { - return false, err - } - - for _, service := range part { - if service.Name == opts.Name { - services = append(services, service) - } - } - - return true, nil - }) - if err != nil { - return "", err - } - - if len(services) == 0 { - return "", gophercloud.ErrServiceNotFound - } - if len(services) > 1 { - return "", fmt.Errorf("Discovered %d matching services: %#v", len(services), services) - } - service := services[0] - - // Enumerate the endpoints available for this service. - var endpoints []endpoints3.Endpoint - endpointPager := endpoints3.List(v3Client, endpoints3.ListOpts{ - Availability: opts.Availability, - ServiceID: service.ID, - }) - err = endpointPager.EachPage(func(page pagination.Page) (bool, error) { - part, err := endpoints3.ExtractEndpoints(page) - if err != nil { - return false, err - } - - for _, endpoint := range part { - if opts.Region == "" || endpoint.Region == opts.Region { - endpoints = append(endpoints, endpoint) - } - } - - return true, nil - }) - if err != nil { - return "", err - } - - if len(endpoints) == 0 { - return "", gophercloud.ErrEndpointNotFound - } - if len(endpoints) > 1 { - return "", fmt.Errorf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints) - } - endpoint := endpoints[0] - - return gophercloud.NormalizeURL(endpoint.URL), nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/endpoint_location_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/endpoint_location_test.go deleted file mode 100644 index 4e0569ac1f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/endpoint_location_test.go +++ /dev/null @@ -1,225 +0,0 @@ -package openstack - -import ( - "fmt" - "net/http" - "strings" - "testing" - - "github.com/rackspace/gophercloud" - tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -// Service catalog fixtures take too much vertical space! -var catalog2 = tokens2.ServiceCatalog{ - Entries: []tokens2.CatalogEntry{ - tokens2.CatalogEntry{ - Type: "same", - Name: "same", - Endpoints: []tokens2.Endpoint{ - tokens2.Endpoint{ - Region: "same", - PublicURL: "https://public.correct.com/", - InternalURL: "https://internal.correct.com/", - AdminURL: "https://admin.correct.com/", - }, - tokens2.Endpoint{ - Region: "different", - PublicURL: "https://badregion.com/", - }, - }, - }, - tokens2.CatalogEntry{ - Type: "same", - Name: "different", - Endpoints: []tokens2.Endpoint{ - tokens2.Endpoint{ - Region: "same", - PublicURL: "https://badname.com/", - }, - tokens2.Endpoint{ - Region: "different", - PublicURL: "https://badname.com/+badregion", - }, - }, - }, - tokens2.CatalogEntry{ - Type: "different", - Name: "different", - Endpoints: []tokens2.Endpoint{ - tokens2.Endpoint{ - Region: "same", - PublicURL: "https://badtype.com/+badname", - }, - tokens2.Endpoint{ - Region: "different", - PublicURL: "https://badtype.com/+badregion+badname", - }, - }, - }, - }, -} - -func TestV2EndpointExact(t *testing.T) { - expectedURLs := map[gophercloud.Availability]string{ - gophercloud.AvailabilityPublic: "https://public.correct.com/", - gophercloud.AvailabilityAdmin: "https://admin.correct.com/", - gophercloud.AvailabilityInternal: "https://internal.correct.com/", - } - - for availability, expected := range expectedURLs { - actual, err := V2EndpointURL(&catalog2, gophercloud.EndpointOpts{ - Type: "same", - Name: "same", - Region: "same", - Availability: availability, - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, expected, actual) - } -} - -func TestV2EndpointNone(t *testing.T) { - _, err := V2EndpointURL(&catalog2, gophercloud.EndpointOpts{ - Type: "nope", - Availability: gophercloud.AvailabilityPublic, - }) - th.CheckEquals(t, gophercloud.ErrEndpointNotFound, err) -} - -func TestV2EndpointMultiple(t *testing.T) { - _, err := V2EndpointURL(&catalog2, gophercloud.EndpointOpts{ - Type: "same", - Region: "same", - Availability: gophercloud.AvailabilityPublic, - }) - if !strings.HasPrefix(err.Error(), "Discovered 2 matching endpoints:") { - t.Errorf("Received unexpected error: %v", err) - } -} - -func TestV2EndpointBadAvailability(t *testing.T) { - _, err := V2EndpointURL(&catalog2, gophercloud.EndpointOpts{ - Type: "same", - Name: "same", - Region: "same", - Availability: "wat", - }) - th.CheckEquals(t, err.Error(), "Unexpected availability in endpoint query: wat") -} - -func setupV3Responses(t *testing.T) { - // Mock the service query. - th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "links": { - "next": null, - "previous": null - }, - "services": [ - { - "description": "Correct", - "id": "1234", - "name": "same", - "type": "same" - }, - { - "description": "Bad Name", - "id": "9876", - "name": "different", - "type": "same" - } - ] - } - `) - }) - - // Mock the endpoint query. - th.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestFormValues(t, r, map[string]string{ - "service_id": "1234", - "interface": "public", - }) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "endpoints": [ - { - "id": "12", - "interface": "public", - "name": "the-right-one", - "region": "same", - "service_id": "1234", - "url": "https://correct:9000/" - }, - { - "id": "14", - "interface": "public", - "name": "bad-region", - "region": "different", - "service_id": "1234", - "url": "https://bad-region:9001/" - } - ], - "links": { - "next": null, - "previous": null - } - } - `) - }) -} - -func TestV3EndpointExact(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - setupV3Responses(t) - - actual, err := V3EndpointURL(fake.ServiceClient(), gophercloud.EndpointOpts{ - Type: "same", - Name: "same", - Region: "same", - Availability: gophercloud.AvailabilityPublic, - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, actual, "https://correct:9000/") -} - -func TestV3EndpointNoService(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "links": { - "next": null, - "previous": null - }, - "services": [] - } - `) - }) - - _, err := V3EndpointURL(fake.ServiceClient(), gophercloud.EndpointOpts{ - Type: "nope", - Name: "same", - Region: "same", - Availability: gophercloud.AvailabilityPublic, - }) - th.CheckEquals(t, gophercloud.ErrServiceNotFound, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/docs.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/docs.go deleted file mode 100644 index 8954178716..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/docs.go +++ /dev/null @@ -1,16 +0,0 @@ -// Package roles provides functionality to interact with and control roles on -// the API. -// -// A role represents a personality that a user can assume when performing a -// specific set of operations. If a role includes a set of rights and -// privileges, a user assuming that role inherits those rights and privileges. -// -// When a token is generated, the list of roles that user can assume is returned -// back to them. Services that are being called by that user determine how they -// interpret the set of roles a user has and to which operations or resources -// each role grants access. -// -// It is up to individual services such as Compute or Image to assign meaning -// to these roles. As far as the Identity service is concerned, a role is an -// arbitrary name assigned by the user. -package roles diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/fixtures.go deleted file mode 100644 index 8256f0fe8e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/fixtures.go +++ /dev/null @@ -1,48 +0,0 @@ -package roles - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func MockListRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/OS-KSADM/roles", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "roles": [ - { - "id": "123", - "name": "compute:admin", - "description": "Nova Administrator" - } - ] -} - `) - }) -} - -func MockAddUserRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusCreated) - }) -} - -func MockDeleteUserRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests.go deleted file mode 100644 index 152031ac35..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests.go +++ /dev/null @@ -1,44 +0,0 @@ -package roles - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// List is the operation responsible for listing all available global roles -// that a user can adopt. -func List(client *gophercloud.ServiceClient) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return RolePage{pagination.SinglePageBase(r)} - } - return pagination.NewPager(client, rootURL(client), createPage) -} - -// AddUserRole is the operation responsible for assigning a particular role to -// a user. This is confined to the scope of the user's tenant - so the tenant -// ID is a required argument. -func AddUserRole(client *gophercloud.ServiceClient, tenantID, userID, roleID string) UserRoleResult { - var result UserRoleResult - - _, result.Err = perigee.Request("PUT", userRoleURL(client, tenantID, userID, roleID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200, 201}, - }) - - return result -} - -// DeleteUserRole is the operation responsible for deleting a particular role -// from a user. This is confined to the scope of the user's tenant - so the -// tenant ID is a required argument. -func DeleteUserRole(client *gophercloud.ServiceClient, tenantID, userID, roleID string) UserRoleResult { - var result UserRoleResult - - _, result.Err = perigee.Request("DELETE", userRoleURL(client, tenantID, userID, roleID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - - return result -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests_test.go deleted file mode 100644 index 7bfeea44a8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package roles - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockListRoleResponse(t) - - count := 0 - - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractRoles(page) - if err != nil { - t.Errorf("Failed to extract users: %v", err) - return false, err - } - - expected := []Role{ - Role{ - ID: "123", - Name: "compute:admin", - Description: "Nova Administrator", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestAddUserRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockAddUserRoleResponse(t) - - err := AddUserRole(client.ServiceClient(), "{tenant_id}", "{user_id}", "{role_id}").ExtractErr() - - th.AssertNoErr(t, err) -} - -func TestDeleteUserRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockDeleteUserRoleResponse(t) - - err := DeleteUserRole(client.ServiceClient(), "{tenant_id}", "{user_id}", "{role_id}").ExtractErr() - - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/results.go deleted file mode 100644 index ebb3aa530b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/results.go +++ /dev/null @@ -1,53 +0,0 @@ -package roles - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// Role represents an API role resource. -type Role struct { - // The unique ID for the role. - ID string - - // The human-readable name of the role. - Name string - - // The description of the role. - Description string - - // The associated service for this role. - ServiceID string -} - -// RolePage is a single page of a user Role collection. -type RolePage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a page of Tenants contains any results. -func (page RolePage) IsEmpty() (bool, error) { - users, err := ExtractRoles(page) - if err != nil { - return false, err - } - return len(users) == 0, nil -} - -// ExtractRoles returns a slice of roles contained in a single page of results. -func ExtractRoles(page pagination.Page) ([]Role, error) { - casted := page.(RolePage).Body - var response struct { - Roles []Role `mapstructure:"roles"` - } - - err := mapstructure.Decode(casted, &response) - return response.Roles, err -} - -// UserRoleResult represents the result of either an AddUserRole or -// a DeleteUserRole operation. -type UserRoleResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/urls.go deleted file mode 100644 index 61b31551dd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package roles - -import "github.com/rackspace/gophercloud" - -const ( - ExtPath = "OS-KSADM" - RolePath = "roles" - UserPath = "users" -) - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(ExtPath, RolePath, id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(ExtPath, RolePath) -} - -func userRoleURL(c *gophercloud.ServiceClient, tenantID, userID, roleID string) string { - return c.ServiceURL("tenants", tenantID, UserPath, userID, RolePath, ExtPath, roleID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate.go deleted file mode 100644 index fd6e80ea6f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate.go +++ /dev/null @@ -1,52 +0,0 @@ -package extensions - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtensionPage is a single page of Extension results. -type ExtensionPage struct { - common.ExtensionPage -} - -// IsEmpty returns true if the current page contains at least one Extension. -func (page ExtensionPage) IsEmpty() (bool, error) { - is, err := ExtractExtensions(page) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the -// elements into a slice of Extension structs. -func ExtractExtensions(page pagination.Page) ([]common.Extension, error) { - // Identity v2 adds an intermediate "values" object. - - var resp struct { - Extensions struct { - Values []common.Extension `mapstructure:"values"` - } `mapstructure:"extensions"` - } - - err := mapstructure.Decode(page.(ExtensionPage).Body, &resp) - return resp.Extensions.Values, err -} - -// Get retrieves information for a specific extension using its alias. -func Get(c *gophercloud.ServiceClient, alias string) common.GetResult { - return common.Get(c, alias) -} - -// List returns a Pager which allows you to iterate over the full collection of extensions. -// It does not accept query parameters. -func List(c *gophercloud.ServiceClient) pagination.Pager { - return common.List(c).WithPageCreator(func(r pagination.PageResult) pagination.Page { - return ExtensionPage{ - ExtensionPage: common.ExtensionPage{SinglePageBase: pagination.SinglePageBase(r)}, - } - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate_test.go deleted file mode 100644 index 504118a825..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package extensions - -import ( - "testing" - - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListExtensionsSuccessfully(t) - - count := 0 - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractExtensions(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, common.ExpectedExtensions, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - common.HandleGetExtensionSuccessfully(t) - - actual, err := Get(client.ServiceClient(), "agent").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, common.SingleExtension, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/doc.go deleted file mode 100644 index 791e4e391d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package extensions provides information and interaction with the -// different extensions available for the OpenStack Identity service. -package extensions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/fixtures.go deleted file mode 100644 index 96cb7d24a1..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/fixtures.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build fixtures - -package extensions - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -// ListOutput provides a single Extension result. It differs from the delegated implementation -// by the introduction of an intermediate "values" member. -const ListOutput = ` -{ - "extensions": { - "values": [ - { - "updated": "2013-01-20T00:00:00-00:00", - "name": "Neutron Service Type Management", - "links": [], - "namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - "alias": "service-type", - "description": "API for retrieving service providers for Neutron advanced services" - } - ] - } -} -` - -// HandleListExtensionsSuccessfully creates an HTTP handler that returns ListOutput for a List -// call. -func HandleListExtensionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - - fmt.Fprintf(w, ` -{ - "extensions": { - "values": [ - { - "updated": "2013-01-20T00:00:00-00:00", - "name": "Neutron Service Type Management", - "links": [], - "namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - "alias": "service-type", - "description": "API for retrieving service providers for Neutron advanced services" - } - ] - } -} - `) - }) - -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests_test.go deleted file mode 100644 index e8f172dd18..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package tenants - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListTenants(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTenantsSuccessfully(t) - - count := 0 - err := List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := ExtractTenants(page) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, ExpectedTenantSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go deleted file mode 100644 index 87c923a2b4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go +++ /dev/null @@ -1,87 +0,0 @@ -package tokens - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -// AuthOptionsBuilder describes any argument that may be passed to the Create call. -type AuthOptionsBuilder interface { - - // ToTokenCreateMap assembles the Create request body, returning an error if parameters are - // missing or inconsistent. - ToTokenCreateMap() (map[string]interface{}, error) -} - -// AuthOptions wraps a gophercloud AuthOptions in order to adhere to the AuthOptionsBuilder -// interface. -type AuthOptions struct { - gophercloud.AuthOptions -} - -// WrapOptions embeds a root AuthOptions struct in a package-specific one. -func WrapOptions(original gophercloud.AuthOptions) AuthOptions { - return AuthOptions{AuthOptions: original} -} - -// ToTokenCreateMap converts AuthOptions into nested maps that can be serialized into a JSON -// request. -func (auth AuthOptions) ToTokenCreateMap() (map[string]interface{}, error) { - // Error out if an unsupported auth option is present. - if auth.UserID != "" { - return nil, ErrUserIDProvided - } - if auth.APIKey != "" { - return nil, ErrAPIKeyProvided - } - if auth.DomainID != "" { - return nil, ErrDomainIDProvided - } - if auth.DomainName != "" { - return nil, ErrDomainNameProvided - } - - // Username and Password are always required. - if auth.Username == "" { - return nil, ErrUsernameRequired - } - if auth.Password == "" { - return nil, ErrPasswordRequired - } - - // Populate the request map. - authMap := make(map[string]interface{}) - - authMap["passwordCredentials"] = map[string]interface{}{ - "username": auth.Username, - "password": auth.Password, - } - - if auth.TenantID != "" { - authMap["tenantId"] = auth.TenantID - } - if auth.TenantName != "" { - authMap["tenantName"] = auth.TenantName - } - - return map[string]interface{}{"auth": authMap}, nil -} - -// Create authenticates to the identity service and attempts to acquire a Token. -// If successful, the CreateResult -// Generally, rather than interact with this call directly, end users should call openstack.AuthenticatedClient(), -// which abstracts all of the gory details about navigating service catalogs and such. -func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) CreateResult { - request, err := auth.ToTokenCreateMap() - if err != nil { - return CreateResult{gophercloud.Result{Err: err}} - } - - var result CreateResult - _, result.Err = perigee.Request("POST", CreateURL(client), perigee.Options{ - ReqBody: &request, - Results: &result.Body, - OkCodes: []int{200, 203}, - }) - return result -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go deleted file mode 100644 index 2f02825a47..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go +++ /dev/null @@ -1,140 +0,0 @@ -package tokens - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func tokenPost(t *testing.T, options gophercloud.AuthOptions, requestJSON string) CreateResult { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleTokenPost(t, requestJSON) - - return Create(client.ServiceClient(), AuthOptions{options}) -} - -func tokenPostErr(t *testing.T, options gophercloud.AuthOptions, expectedErr error) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleTokenPost(t, "") - - actualErr := Create(client.ServiceClient(), AuthOptions{options}).Err - th.CheckEquals(t, expectedErr, actualErr) -} - -func TestCreateWithPassword(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - Password: "swordfish", - } - - IsSuccessful(t, tokenPost(t, options, ` - { - "auth": { - "passwordCredentials": { - "username": "me", - "password": "swordfish" - } - } - } - `)) -} - -func TestCreateTokenWithTenantID(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - Password: "opensesame", - TenantID: "fc394f2ab2df4114bde39905f800dc57", - } - - IsSuccessful(t, tokenPost(t, options, ` - { - "auth": { - "tenantId": "fc394f2ab2df4114bde39905f800dc57", - "passwordCredentials": { - "username": "me", - "password": "opensesame" - } - } - } - `)) -} - -func TestCreateTokenWithTenantName(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - Password: "opensesame", - TenantName: "demo", - } - - IsSuccessful(t, tokenPost(t, options, ` - { - "auth": { - "tenantName": "demo", - "passwordCredentials": { - "username": "me", - "password": "opensesame" - } - } - } - `)) -} - -func TestProhibitUserID(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - UserID: "1234", - Password: "thing", - } - - tokenPostErr(t, options, ErrUserIDProvided) -} - -func TestProhibitAPIKey(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - Password: "thing", - APIKey: "123412341234", - } - - tokenPostErr(t, options, ErrAPIKeyProvided) -} - -func TestProhibitDomainID(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - Password: "thing", - DomainID: "1234", - } - - tokenPostErr(t, options, ErrDomainIDProvided) -} - -func TestProhibitDomainName(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - Password: "thing", - DomainName: "wat", - } - - tokenPostErr(t, options, ErrDomainNameProvided) -} - -func TestRequireUsername(t *testing.T) { - options := gophercloud.AuthOptions{ - Password: "thing", - } - - tokenPostErr(t, options, ErrUsernameRequired) -} - -func TestRequirePassword(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - } - - tokenPostErr(t, options, ErrPasswordRequired) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/doc.go deleted file mode 100644 index 82abcb9fcc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/doc.go +++ /dev/null @@ -1 +0,0 @@ -package users diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/fixtures.go deleted file mode 100644 index 8941868dd2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/fixtures.go +++ /dev/null @@ -1,163 +0,0 @@ -package users - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func MockListUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "users":[ - { - "id": "u1000", - "name": "John Smith", - "username": "jqsmith", - "email": "john.smith@example.org", - "enabled": true, - "tenant_id": "12345" - }, - { - "id": "u1001", - "name": "Jane Smith", - "username": "jqsmith", - "email": "jane.smith@example.org", - "enabled": true, - "tenant_id": "12345" - } - ] -} - `) - }) -} - -func mockCreateUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "user": { - "name": "new_user", - "tenant_id": "12345", - "enabled": false, - "email": "new_user@foo.com" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "user": { - "name": "new_user", - "tenant_id": "12345", - "enabled": false, - "email": "new_user@foo.com", - "id": "c39e3de9be2d4c779f1dfd6abacc176d" - } -} -`) - }) -} - -func mockGetUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users/new_user", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "user": { - "name": "new_user", - "tenant_id": "12345", - "enabled": false, - "email": "new_user@foo.com", - "id": "c39e3de9be2d4c779f1dfd6abacc176d" - } -} -`) - }) -} - -func mockUpdateUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "user": { - "name": "new_name", - "enabled": true, - "email": "new_email@foo.com" - } -} -`) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "user": { - "name": "new_name", - "tenant_id": "12345", - "enabled": true, - "email": "new_email@foo.com", - "id": "c39e3de9be2d4c779f1dfd6abacc176d" - } -} -`) - }) -} - -func mockDeleteUserResponse(t *testing.T) { - th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) -} - -func mockListRolesResponse(t *testing.T) { - th.Mux.HandleFunc("/tenants/1d8b6120dcc640fda4fc9194ffc80273/users/c39e3de9be2d4c779f1dfd6abacc176d/roles", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "roles": [ - { - "id": "9fe2ff9ee4384b1894a90878d3e92bab", - "name": "foo_role" - }, - { - "id": "1ea3d56793574b668e85960fbf651e13", - "name": "admin" - } - ] -} - `) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests.go deleted file mode 100644 index 4ce395f2dd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests.go +++ /dev/null @@ -1,180 +0,0 @@ -package users - -import ( - "errors" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -func List(client *gophercloud.ServiceClient) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return UserPage{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(client, rootURL(client), createPage) -} - -// EnabledState represents whether the user is enabled or not. -type EnabledState *bool - -// Useful variables to use when creating or updating users. -var ( - iTrue = true - iFalse = false - - Enabled EnabledState = &iTrue - Disabled EnabledState = &iFalse -) - -// CommonOpts are the parameters that are shared between CreateOpts and -// UpdateOpts -type CommonOpts struct { - // Either a name or username is required. When provided, the value must be - // unique or a 409 conflict error will be returned. If you provide a name but - // omit a username, the latter will be set to the former; and vice versa. - Name, Username string - - // The ID of the tenant to which you want to assign this user. - TenantID string - - // Indicates whether this user is enabled or not. - Enabled EnabledState - - // The email address of this user. - Email string -} - -// CreateOpts represents the options needed when creating new users. -type CreateOpts CommonOpts - -// CreateOptsBuilder describes struct types that can be accepted by the Create call. -type CreateOptsBuilder interface { - ToUserCreateMap() (map[string]interface{}, error) -} - -// ToUserCreateMap assembles a request body based on the contents of a CreateOpts. -func (opts CreateOpts) ToUserCreateMap() (map[string]interface{}, error) { - m := make(map[string]interface{}) - - if opts.Name == "" && opts.Username == "" { - return m, errors.New("Either a Name or Username must be provided") - } - - if opts.Name != "" { - m["name"] = opts.Name - } - if opts.Username != "" { - m["username"] = opts.Username - } - if opts.Enabled != nil { - m["enabled"] = &opts.Enabled - } - if opts.Email != "" { - m["email"] = opts.Email - } - if opts.TenantID != "" { - m["tenant_id"] = opts.TenantID - } - - return map[string]interface{}{"user": m}, nil -} - -// Create is the operation responsible for creating new users. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToUserCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", rootURL(client), perigee.Options{ - Results: &res.Body, - ReqBody: reqBody, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200, 201}, - }) - - return res -} - -// Get requests details on a single user, either by ID. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - var result GetResult - - _, result.Err = perigee.Request("GET", ResourceURL(client, id), perigee.Options{ - Results: &result.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the Update request. -type UpdateOptsBuilder interface { - ToUserUpdateMap() map[string]interface{} -} - -// UpdateOpts specifies the base attributes that may be updated on an existing server. -type UpdateOpts CommonOpts - -// ToUserUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToUserUpdateMap() map[string]interface{} { - m := make(map[string]interface{}) - - if opts.Name != "" { - m["name"] = opts.Name - } - if opts.Username != "" { - m["username"] = opts.Username - } - if opts.Enabled != nil { - m["enabled"] = &opts.Enabled - } - if opts.Email != "" { - m["email"] = opts.Email - } - if opts.TenantID != "" { - m["tenant_id"] = opts.TenantID - } - - return map[string]interface{}{"user": m} -} - -// Update is the operation responsible for updating exist users by their UUID. -func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var result UpdateResult - - _, result.Err = perigee.Request("PUT", ResourceURL(client, id), perigee.Options{ - Results: &result.Body, - ReqBody: opts.ToUserUpdateMap(), - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// Delete is the operation responsible for permanently deleting an API user. -func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { - var result DeleteResult - - _, result.Err = perigee.Request("DELETE", ResourceURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - - return result -} - -func ListRoles(client *gophercloud.ServiceClient, tenantID, userID string) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return RolePage{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(client, listRolesURL(client, tenantID, userID), createPage) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests_test.go deleted file mode 100644 index 04f837163a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package users - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockListUserResponse(t) - - count := 0 - - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractUsers(page) - if err != nil { - t.Errorf("Failed to extract users: %v", err) - return false, err - } - - expected := []User{ - User{ - ID: "u1000", - Name: "John Smith", - Username: "jqsmith", - Email: "john.smith@example.org", - Enabled: true, - TenantID: "12345", - }, - User{ - ID: "u1001", - Name: "Jane Smith", - Username: "jqsmith", - Email: "jane.smith@example.org", - Enabled: true, - TenantID: "12345", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateUserResponse(t) - - opts := CreateOpts{ - Name: "new_user", - TenantID: "12345", - Enabled: Disabled, - Email: "new_user@foo.com", - } - - user, err := Create(client.ServiceClient(), opts).Extract() - - th.AssertNoErr(t, err) - - expected := &User{ - Name: "new_user", - ID: "c39e3de9be2d4c779f1dfd6abacc176d", - Email: "new_user@foo.com", - Enabled: false, - TenantID: "12345", - } - - th.AssertDeepEquals(t, expected, user) -} - -func TestGetUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetUserResponse(t) - - user, err := Get(client.ServiceClient(), "new_user").Extract() - th.AssertNoErr(t, err) - - expected := &User{ - Name: "new_user", - ID: "c39e3de9be2d4c779f1dfd6abacc176d", - Email: "new_user@foo.com", - Enabled: false, - TenantID: "12345", - } - - th.AssertDeepEquals(t, expected, user) -} - -func TestUpdateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateUserResponse(t) - - id := "c39e3de9be2d4c779f1dfd6abacc176d" - opts := UpdateOpts{ - Name: "new_name", - Enabled: Enabled, - Email: "new_email@foo.com", - } - - user, err := Update(client.ServiceClient(), id, opts).Extract() - - th.AssertNoErr(t, err) - - expected := &User{ - Name: "new_name", - ID: id, - Email: "new_email@foo.com", - Enabled: true, - TenantID: "12345", - } - - th.AssertDeepEquals(t, expected, user) -} - -func TestDeleteUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteUserResponse(t) - - res := Delete(client.ServiceClient(), "c39e3de9be2d4c779f1dfd6abacc176d") - th.AssertNoErr(t, res.Err) -} - -func TestListingUserRoles(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListRolesResponse(t) - - tenantID := "1d8b6120dcc640fda4fc9194ffc80273" - userID := "c39e3de9be2d4c779f1dfd6abacc176d" - - err := ListRoles(client.ServiceClient(), tenantID, userID).EachPage(func(page pagination.Page) (bool, error) { - actual, err := ExtractRoles(page) - th.AssertNoErr(t, err) - - expected := []Role{ - Role{ID: "9fe2ff9ee4384b1894a90878d3e92bab", Name: "foo_role"}, - Role{ID: "1ea3d56793574b668e85960fbf651e13", Name: "admin"}, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/results.go deleted file mode 100644 index f531d5d023..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/results.go +++ /dev/null @@ -1,128 +0,0 @@ -package users - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// User represents a user resource that exists on the API. -type User struct { - // The UUID for this user. - ID string - - // The human name for this user. - Name string - - // The username for this user. - Username string - - // Indicates whether the user is enabled (true) or disabled (false). - Enabled bool - - // The email address for this user. - Email string - - // The ID of the tenant to which this user belongs. - TenantID string `mapstructure:"tenant_id"` -} - -// Role assigns specific responsibilities to users, allowing them to accomplish -// certain API operations whilst scoped to a service. -type Role struct { - // UUID of the role - ID string - - // Name of the role - Name string -} - -// UserPage is a single page of a User collection. -type UserPage struct { - pagination.SinglePageBase -} - -// RolePage is a single page of a user Role collection. -type RolePage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a page of Tenants contains any results. -func (page UserPage) IsEmpty() (bool, error) { - users, err := ExtractUsers(page) - if err != nil { - return false, err - } - return len(users) == 0, nil -} - -// ExtractUsers returns a slice of Tenants contained in a single page of results. -func ExtractUsers(page pagination.Page) ([]User, error) { - casted := page.(UserPage).Body - var response struct { - Users []User `mapstructure:"users"` - } - - err := mapstructure.Decode(casted, &response) - return response.Users, err -} - -// IsEmpty determines whether or not a page of Tenants contains any results. -func (page RolePage) IsEmpty() (bool, error) { - users, err := ExtractRoles(page) - if err != nil { - return false, err - } - return len(users) == 0, nil -} - -// ExtractRoles returns a slice of Roles contained in a single page of results. -func ExtractRoles(page pagination.Page) ([]Role, error) { - casted := page.(RolePage).Body - var response struct { - Roles []Role `mapstructure:"roles"` - } - - err := mapstructure.Decode(casted, &response) - return response.Roles, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract interprets any commonResult as a User, if possible. -func (r commonResult) Extract() (*User, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - User User `mapstructure:"user"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.User, err -} - -// CreateResult represents the result of a Create operation -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a Get operation -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an Update operation -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a Delete operation -type DeleteResult struct { - commonResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/urls.go deleted file mode 100644 index 7ec4385d74..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/users/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package users - -import "github.com/rackspace/gophercloud" - -const ( - tenantPath = "tenants" - userPath = "users" - rolePath = "roles" -) - -func ResourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(userPath, id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(userPath) -} - -func listRolesURL(c *gophercloud.ServiceClient, tenantID, userID string) string { - return c.ServiceURL(tenantPath, tenantID, userPath, userID, rolePath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/doc.go deleted file mode 100644 index 85163949a8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package endpoints provides information and interaction with the service -// endpoints API resource in the OpenStack Identity service. -// -// For more information, see: -// http://developer.openstack.org/api-ref-identity-v3.html#endpoints-v3 -package endpoints diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/errors.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/errors.go deleted file mode 100644 index 854957ff98..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/errors.go +++ /dev/null @@ -1,21 +0,0 @@ -package endpoints - -import "fmt" - -func requiredAttribute(attribute string) error { - return fmt.Errorf("You must specify %s for this endpoint.", attribute) -} - -var ( - // ErrAvailabilityRequired is reported if an Endpoint is created without an Availability. - ErrAvailabilityRequired = requiredAttribute("an availability") - - // ErrNameRequired is reported if an Endpoint is created without a Name. - ErrNameRequired = requiredAttribute("a name") - - // ErrURLRequired is reported if an Endpoint is created without a URL. - ErrURLRequired = requiredAttribute("a URL") - - // ErrServiceIDRequired is reported if an Endpoint is created without a ServiceID. - ErrServiceIDRequired = requiredAttribute("a serviceID") -) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests.go deleted file mode 100644 index 7bdb7cef2e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests.go +++ /dev/null @@ -1,133 +0,0 @@ -package endpoints - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// EndpointOpts contains the subset of Endpoint attributes that should be used to create or update an Endpoint. -type EndpointOpts struct { - Availability gophercloud.Availability - Name string - Region string - URL string - ServiceID string -} - -// Create inserts a new Endpoint into the service catalog. -// Within EndpointOpts, Region may be omitted by being left as "", but all other fields are required. -func Create(client *gophercloud.ServiceClient, opts EndpointOpts) CreateResult { - // Redefined so that Region can be re-typed as a *string, which can be omitted from the JSON output. - type endpoint struct { - Interface string `json:"interface"` - Name string `json:"name"` - Region *string `json:"region,omitempty"` - URL string `json:"url"` - ServiceID string `json:"service_id"` - } - - type request struct { - Endpoint endpoint `json:"endpoint"` - } - - // Ensure that EndpointOpts is fully populated. - if opts.Availability == "" { - return createErr(ErrAvailabilityRequired) - } - if opts.Name == "" { - return createErr(ErrNameRequired) - } - if opts.URL == "" { - return createErr(ErrURLRequired) - } - if opts.ServiceID == "" { - return createErr(ErrServiceIDRequired) - } - - // Populate the request body. - reqBody := request{ - Endpoint: endpoint{ - Interface: string(opts.Availability), - Name: opts.Name, - URL: opts.URL, - ServiceID: opts.ServiceID, - }, - } - reqBody.Endpoint.Region = gophercloud.MaybeString(opts.Region) - - var result CreateResult - _, result.Err = perigee.Request("POST", listURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &result.Body, - OkCodes: []int{201}, - }) - return result -} - -// ListOpts allows finer control over the endpoints returned by a List call. -// All fields are optional. -type ListOpts struct { - Availability gophercloud.Availability `q:"interface"` - ServiceID string `q:"service_id"` - Page int `q:"page"` - PerPage int `q:"per_page"` -} - -// List enumerates endpoints in a paginated collection, optionally filtered by ListOpts criteria. -func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - u := listURL(client) - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return pagination.Pager{Err: err} - } - u += q.String() - createPage := func(r pagination.PageResult) pagination.Page { - return EndpointPage{pagination.LinkedPageBase{PageResult: r}} - } - - return pagination.NewPager(client, u, createPage) -} - -// Update changes an existing endpoint with new data. -// All fields are optional in the provided EndpointOpts. -func Update(client *gophercloud.ServiceClient, endpointID string, opts EndpointOpts) UpdateResult { - type endpoint struct { - Interface *string `json:"interface,omitempty"` - Name *string `json:"name,omitempty"` - Region *string `json:"region,omitempty"` - URL *string `json:"url,omitempty"` - ServiceID *string `json:"service_id,omitempty"` - } - - type request struct { - Endpoint endpoint `json:"endpoint"` - } - - reqBody := request{Endpoint: endpoint{}} - reqBody.Endpoint.Interface = gophercloud.MaybeString(string(opts.Availability)) - reqBody.Endpoint.Name = gophercloud.MaybeString(opts.Name) - reqBody.Endpoint.Region = gophercloud.MaybeString(opts.Region) - reqBody.Endpoint.URL = gophercloud.MaybeString(opts.URL) - reqBody.Endpoint.ServiceID = gophercloud.MaybeString(opts.ServiceID) - - var result UpdateResult - _, result.Err = perigee.Request("PATCH", endpointURL(client, endpointID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &result.Body, - OkCodes: []int{200}, - }) - return result -} - -// Delete removes an endpoint from the service catalog. -func Delete(client *gophercloud.ServiceClient, endpointID string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", endpointURL(client, endpointID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests_test.go deleted file mode 100644 index 80687c4cb7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests_test.go +++ /dev/null @@ -1,226 +0,0 @@ -package endpoints - -import ( - "fmt" - "net/http" - "reflect" - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestCreateSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestJSONRequest(t, r, ` - { - "endpoint": { - "interface": "public", - "name": "the-endiest-of-points", - "region": "underground", - "url": "https://1.2.3.4:9000/", - "service_id": "asdfasdfasdfasdf" - } - } - `) - - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, ` - { - "endpoint": { - "id": "12", - "interface": "public", - "links": { - "self": "https://localhost:5000/v3/endpoints/12" - }, - "name": "the-endiest-of-points", - "region": "underground", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" - } - } - `) - }) - - actual, err := Create(client.ServiceClient(), EndpointOpts{ - Availability: gophercloud.AvailabilityPublic, - Name: "the-endiest-of-points", - Region: "underground", - URL: "https://1.2.3.4:9000/", - ServiceID: "asdfasdfasdfasdf", - }).Extract() - if err != nil { - t.Fatalf("Unable to create an endpoint: %v", err) - } - - expected := &Endpoint{ - ID: "12", - Availability: gophercloud.AvailabilityPublic, - Name: "the-endiest-of-points", - Region: "underground", - ServiceID: "asdfasdfasdfasdf", - URL: "https://1.2.3.4:9000/", - } - - if !reflect.DeepEqual(actual, expected) { - t.Errorf("Expected %#v, was %#v", expected, actual) - } -} - -func TestListEndpoints(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "endpoints": [ - { - "id": "12", - "interface": "public", - "links": { - "self": "https://localhost:5000/v3/endpoints/12" - }, - "name": "the-endiest-of-points", - "region": "underground", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" - }, - { - "id": "13", - "interface": "internal", - "links": { - "self": "https://localhost:5000/v3/endpoints/13" - }, - "name": "shhhh", - "region": "underground", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9001/" - } - ], - "links": { - "next": null, - "previous": null - } - } - `) - }) - - count := 0 - List(client.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractEndpoints(page) - if err != nil { - t.Errorf("Failed to extract endpoints: %v", err) - return false, err - } - - expected := []Endpoint{ - Endpoint{ - ID: "12", - Availability: gophercloud.AvailabilityPublic, - Name: "the-endiest-of-points", - Region: "underground", - ServiceID: "asdfasdfasdfasdf", - URL: "https://1.2.3.4:9000/", - }, - Endpoint{ - ID: "13", - Availability: gophercloud.AvailabilityInternal, - Name: "shhhh", - Region: "underground", - ServiceID: "asdfasdfasdfasdf", - URL: "https://1.2.3.4:9001/", - }, - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %#v, got %#v", expected, actual) - } - - return true, nil - }) - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestUpdateEndpoint(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "PATCH") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestJSONRequest(t, r, ` - { - "endpoint": { - "name": "renamed", - "region": "somewhere-else" - } - } - `) - - fmt.Fprintf(w, ` - { - "endpoint": { - "id": "12", - "interface": "public", - "links": { - "self": "https://localhost:5000/v3/endpoints/12" - }, - "name": "renamed", - "region": "somewhere-else", - "service_id": "asdfasdfasdfasdf", - "url": "https://1.2.3.4:9000/" - } - } - `) - }) - - actual, err := Update(client.ServiceClient(), "12", EndpointOpts{ - Name: "renamed", - Region: "somewhere-else", - }).Extract() - if err != nil { - t.Fatalf("Unexpected error from Update: %v", err) - } - - expected := &Endpoint{ - ID: "12", - Availability: gophercloud.AvailabilityPublic, - Name: "renamed", - Region: "somewhere-else", - ServiceID: "asdfasdfasdfasdf", - URL: "https://1.2.3.4:9000/", - } - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %#v, was %#v", expected, actual) - } -} - -func TestDeleteEndpoint(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/endpoints/34", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "DELETE") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(client.ServiceClient(), "34") - testhelper.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/results.go deleted file mode 100644 index 128112295a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/results.go +++ /dev/null @@ -1,82 +0,0 @@ -package endpoints - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Endpoint. -// An error is returned if the original call or the extraction failed. -func (r commonResult) Extract() (*Endpoint, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Endpoint `json:"endpoint"` - } - - err := mapstructure.Decode(r.Body, &res) - - return &res.Endpoint, err -} - -// CreateResult is the deferred result of a Create call. -type CreateResult struct { - commonResult -} - -// createErr quickly wraps an error in a CreateResult. -func createErr(err error) CreateResult { - return CreateResult{commonResult{gophercloud.Result{Err: err}}} -} - -// UpdateResult is the deferred result of an Update call. -type UpdateResult struct { - commonResult -} - -// DeleteResult is the deferred result of an Delete call. -type DeleteResult struct { - gophercloud.ErrResult -} - -// Endpoint describes the entry point for another service's API. -type Endpoint struct { - ID string `mapstructure:"id" json:"id"` - Availability gophercloud.Availability `mapstructure:"interface" json:"interface"` - Name string `mapstructure:"name" json:"name"` - Region string `mapstructure:"region" json:"region"` - ServiceID string `mapstructure:"service_id" json:"service_id"` - URL string `mapstructure:"url" json:"url"` -} - -// EndpointPage is a single page of Endpoint results. -type EndpointPage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if no Endpoints were returned. -func (p EndpointPage) IsEmpty() (bool, error) { - es, err := ExtractEndpoints(p) - if err != nil { - return true, err - } - return len(es) == 0, nil -} - -// ExtractEndpoints extracts an Endpoint slice from a Page. -func ExtractEndpoints(page pagination.Page) ([]Endpoint, error) { - var response struct { - Endpoints []Endpoint `mapstructure:"endpoints"` - } - - err := mapstructure.Decode(page.(EndpointPage).Body, &response) - - return response.Endpoints, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls.go deleted file mode 100644 index 547d7b102a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package endpoints - -import "github.com/rackspace/gophercloud" - -func listURL(client *gophercloud.ServiceClient) string { - return client.ServiceURL("endpoints") -} - -func endpointURL(client *gophercloud.ServiceClient, endpointID string) string { - return client.ServiceURL("endpoints", endpointID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls_test.go deleted file mode 100644 index 0b183b7434..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package endpoints - -import ( - "testing" - - "github.com/rackspace/gophercloud" -) - -func TestGetListURL(t *testing.T) { - client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"} - url := listURL(&client) - if url != "http://localhost:5000/v3/endpoints" { - t.Errorf("Unexpected list URL generated: [%s]", url) - } -} - -func TestGetEndpointURL(t *testing.T) { - client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"} - url := endpointURL(&client, "1234") - if url != "http://localhost:5000/v3/endpoints/1234" { - t.Errorf("Unexpected service URL generated: [%s]", url) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/doc.go deleted file mode 100644 index fa56411856..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package services provides information and interaction with the services API -// resource for the OpenStack Identity service. -package services diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests.go deleted file mode 100644 index 1d9aaa873a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests.go +++ /dev/null @@ -1,91 +0,0 @@ -package services - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -type response struct { - Service Service `json:"service"` -} - -// Create adds a new service of the requested type to the catalog. -func Create(client *gophercloud.ServiceClient, serviceType string) CreateResult { - type request struct { - Type string `json:"type"` - } - - req := request{Type: serviceType} - - var result CreateResult - _, result.Err = perigee.Request("POST", listURL(client), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &req, - Results: &result.Body, - OkCodes: []int{201}, - }) - return result -} - -// ListOpts allows you to query the List method. -type ListOpts struct { - ServiceType string `q:"type"` - PerPage int `q:"perPage"` - Page int `q:"page"` -} - -// List enumerates the services available to a specific user. -func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - u := listURL(client) - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return pagination.Pager{Err: err} - } - u += q.String() - createPage := func(r pagination.PageResult) pagination.Page { - return ServicePage{pagination.LinkedPageBase{PageResult: r}} - } - - return pagination.NewPager(client, u, createPage) -} - -// Get returns additional information about a service, given its ID. -func Get(client *gophercloud.ServiceClient, serviceID string) GetResult { - var result GetResult - _, result.Err = perigee.Request("GET", serviceURL(client, serviceID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &result.Body, - OkCodes: []int{200}, - }) - return result -} - -// Update changes the service type of an existing service. -func Update(client *gophercloud.ServiceClient, serviceID string, serviceType string) UpdateResult { - type request struct { - Type string `json:"type"` - } - - req := request{Type: serviceType} - - var result UpdateResult - _, result.Err = perigee.Request("PATCH", serviceURL(client, serviceID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &req, - Results: &result.Body, - OkCodes: []int{200}, - }) - return result -} - -// Delete removes an existing service. -// It either deletes all associated endpoints, or fails until all endpoints are deleted. -func Delete(client *gophercloud.ServiceClient, serviceID string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", serviceURL(client, serviceID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests_test.go deleted file mode 100644 index 42f05d365a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package services - -import ( - "fmt" - "net/http" - "reflect" - "testing" - - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestCreateSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestJSONRequest(t, r, `{ "type": "compute" }`) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ - "service": { - "description": "Here's your service", - "id": "1234", - "name": "InscrutableOpenStackProjectName", - "type": "compute" - } - }`) - }) - - result, err := Create(client.ServiceClient(), "compute").Extract() - if err != nil { - t.Fatalf("Unexpected error from Create: %v", err) - } - - if result.Description == nil || *result.Description != "Here's your service" { - t.Errorf("Service description was unexpected [%s]", *result.Description) - } - if result.ID != "1234" { - t.Errorf("Service ID was unexpected [%s]", result.ID) - } - if result.Name != "InscrutableOpenStackProjectName" { - t.Errorf("Service name was unexpected [%s]", result.Name) - } - if result.Type != "compute" { - t.Errorf("Service type was unexpected [%s]", result.Type) - } -} - -func TestListSinglePage(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "links": { - "next": null, - "previous": null - }, - "services": [ - { - "description": "Service One", - "id": "1234", - "name": "service-one", - "type": "identity" - }, - { - "description": "Service Two", - "id": "9876", - "name": "service-two", - "type": "compute" - } - ] - } - `) - }) - - count := 0 - err := List(client.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractServices(page) - if err != nil { - return false, err - } - - desc0 := "Service One" - desc1 := "Service Two" - expected := []Service{ - Service{ - Description: &desc0, - ID: "1234", - Name: "service-one", - Type: "identity", - }, - Service{ - Description: &desc1, - ID: "9876", - Name: "service-two", - Type: "compute", - }, - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Expected %#v, got %#v", expected, actual) - } - - return true, nil - }) - if err != nil { - t.Errorf("Unexpected error while paging: %v", err) - } - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "service": { - "description": "Service One", - "id": "12345", - "name": "service-one", - "type": "identity" - } - } - `) - }) - - result, err := Get(client.ServiceClient(), "12345").Extract() - if err != nil { - t.Fatalf("Error fetching service information: %v", err) - } - - if result.ID != "12345" { - t.Errorf("Unexpected service ID: %s", result.ID) - } - if *result.Description != "Service One" { - t.Errorf("Unexpected service description: [%s]", *result.Description) - } - if result.Name != "service-one" { - t.Errorf("Unexpected service name: [%s]", result.Name) - } - if result.Type != "identity" { - t.Errorf("Unexpected service type: [%s]", result.Type) - } -} - -func TestUpdateSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "PATCH") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - testhelper.TestJSONRequest(t, r, `{ "type": "lasermagic" }`) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ` - { - "service": { - "id": "12345", - "type": "lasermagic" - } - } - `) - }) - - result, err := Update(client.ServiceClient(), "12345", "lasermagic").Extract() - if err != nil { - t.Fatalf("Unable to update service: %v", err) - } - - if result.ID != "12345" { - t.Fatalf("Expected ID 12345, was %s", result.ID) - } -} - -func TestDeleteSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - testhelper.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "DELETE") - testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(client.ServiceClient(), "12345") - testhelper.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/results.go deleted file mode 100644 index 1d0d141280..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/results.go +++ /dev/null @@ -1,80 +0,0 @@ -package services - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Service. -// An error is returned if the original call or the extraction failed. -func (r commonResult) Extract() (*Service, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Service `json:"service"` - } - - err := mapstructure.Decode(r.Body, &res) - - return &res.Service, err -} - -// CreateResult is the deferred result of a Create call. -type CreateResult struct { - commonResult -} - -// GetResult is the deferred result of a Get call. -type GetResult struct { - commonResult -} - -// UpdateResult is the deferred result of an Update call. -type UpdateResult struct { - commonResult -} - -// DeleteResult is the deferred result of an Delete call. -type DeleteResult struct { - gophercloud.ErrResult -} - -// Service is the result of a list or information query. -type Service struct { - Description *string `json:"description,omitempty"` - ID string `json:"id"` - Name string `json:"name"` - Type string `json:"type"` -} - -// ServicePage is a single page of Service results. -type ServicePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if the page contains no results. -func (p ServicePage) IsEmpty() (bool, error) { - services, err := ExtractServices(p) - if err != nil { - return true, err - } - return len(services) == 0, nil -} - -// ExtractServices extracts a slice of Services from a Collection acquired from List. -func ExtractServices(page pagination.Page) ([]Service, error) { - var response struct { - Services []Service `mapstructure:"services"` - } - - err := mapstructure.Decode(page.(ServicePage).Body, &response) - return response.Services, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls.go deleted file mode 100644 index 85443a48a0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package services - -import "github.com/rackspace/gophercloud" - -func listURL(client *gophercloud.ServiceClient) string { - return client.ServiceURL("services") -} - -func serviceURL(client *gophercloud.ServiceClient, serviceID string) string { - return client.ServiceURL("services", serviceID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls_test.go deleted file mode 100644 index 5a31b32316..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package services - -import ( - "testing" - - "github.com/rackspace/gophercloud" -) - -func TestListURL(t *testing.T) { - client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"} - url := listURL(&client) - if url != "http://localhost:5000/v3/services" { - t.Errorf("Unexpected list URL generated: [%s]", url) - } -} - -func TestServiceURL(t *testing.T) { - client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"} - url := serviceURL(&client, "1234") - if url != "http://localhost:5000/v3/services/1234" { - t.Errorf("Unexpected service URL generated: [%s]", url) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go deleted file mode 100644 index 5ca1031c41..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go +++ /dev/null @@ -1,286 +0,0 @@ -package tokens - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -// Scope allows a created token to be limited to a specific domain or project. -type Scope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string -} - -func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string { - h := c.AuthenticatedHeaders() - h["X-Subject-Token"] = subjectToken - return h -} - -// Create authenticates and either generates a new token, or changes the Scope of an existing token. -func Create(c *gophercloud.ServiceClient, options gophercloud.AuthOptions, scope *Scope) CreateResult { - type domainReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - } - - type projectReq struct { - Domain *domainReq `json:"domain,omitempty"` - Name *string `json:"name,omitempty"` - ID *string `json:"id,omitempty"` - } - - type userReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Password string `json:"password"` - Domain *domainReq `json:"domain,omitempty"` - } - - type passwordReq struct { - User userReq `json:"user"` - } - - type tokenReq struct { - ID string `json:"id"` - } - - type identityReq struct { - Methods []string `json:"methods"` - Password *passwordReq `json:"password,omitempty"` - Token *tokenReq `json:"token,omitempty"` - } - - type scopeReq struct { - Domain *domainReq `json:"domain,omitempty"` - Project *projectReq `json:"project,omitempty"` - } - - type authReq struct { - Identity identityReq `json:"identity"` - Scope *scopeReq `json:"scope,omitempty"` - } - - type request struct { - Auth authReq `json:"auth"` - } - - // Populate the request structure based on the provided arguments. Create and return an error - // if insufficient or incompatible information is present. - var req request - - // Test first for unrecognized arguments. - if options.APIKey != "" { - return createErr(ErrAPIKeyProvided) - } - if options.TenantID != "" { - return createErr(ErrTenantIDProvided) - } - if options.TenantName != "" { - return createErr(ErrTenantNameProvided) - } - - if options.Password == "" { - if c.TokenID != "" { - // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication - // parameters. - if options.Username != "" { - return createErr(ErrUsernameWithToken) - } - if options.UserID != "" { - return createErr(ErrUserIDWithToken) - } - if options.DomainID != "" { - return createErr(ErrDomainIDWithToken) - } - if options.DomainName != "" { - return createErr(ErrDomainNameWithToken) - } - - // Configure the request for Token authentication. - req.Auth.Identity.Methods = []string{"token"} - req.Auth.Identity.Token = &tokenReq{ - ID: c.TokenID, - } - } else { - // If no password or token ID are available, authentication can't continue. - return createErr(ErrMissingPassword) - } - } else { - // Password authentication. - req.Auth.Identity.Methods = []string{"password"} - - // At least one of Username and UserID must be specified. - if options.Username == "" && options.UserID == "" { - return createErr(ErrUsernameOrUserID) - } - - if options.Username != "" { - // If Username is provided, UserID may not be provided. - if options.UserID != "" { - return createErr(ErrUsernameOrUserID) - } - - // Either DomainID or DomainName must also be specified. - if options.DomainID == "" && options.DomainName == "" { - return createErr(ErrDomainIDOrDomainName) - } - - if options.DomainID != "" { - if options.DomainName != "" { - return createErr(ErrDomainIDOrDomainName) - } - - // Configure the request for Username and Password authentication with a DomainID. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &options.Username, - Password: options.Password, - Domain: &domainReq{ID: &options.DomainID}, - }, - } - } - - if options.DomainName != "" { - // Configure the request for Username and Password authentication with a DomainName. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &options.Username, - Password: options.Password, - Domain: &domainReq{Name: &options.DomainName}, - }, - } - } - } - - if options.UserID != "" { - // If UserID is specified, neither DomainID nor DomainName may be. - if options.DomainID != "" { - return createErr(ErrDomainIDWithUserID) - } - if options.DomainName != "" { - return createErr(ErrDomainNameWithUserID) - } - - // Configure the request for UserID and Password authentication. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ID: &options.UserID, Password: options.Password}, - } - } - } - - // Add a "scope" element if a Scope has been provided. - if scope != nil { - if scope.ProjectName != "" { - // ProjectName provided: either DomainID or DomainName must also be supplied. - // ProjectID may not be supplied. - if scope.DomainID == "" && scope.DomainName == "" { - return createErr(ErrScopeDomainIDOrDomainName) - } - if scope.ProjectID != "" { - return createErr(ErrScopeProjectIDOrProjectName) - } - - if scope.DomainID != "" { - // ProjectName + DomainID - req.Auth.Scope = &scopeReq{ - Project: &projectReq{ - Name: &scope.ProjectName, - Domain: &domainReq{ID: &scope.DomainID}, - }, - } - } - - if scope.DomainName != "" { - // ProjectName + DomainName - req.Auth.Scope = &scopeReq{ - Project: &projectReq{ - Name: &scope.ProjectName, - Domain: &domainReq{Name: &scope.DomainName}, - }, - } - } - } else if scope.ProjectID != "" { - // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. - if scope.DomainID != "" { - return createErr(ErrScopeProjectIDAlone) - } - if scope.DomainName != "" { - return createErr(ErrScopeProjectIDAlone) - } - - // ProjectID - req.Auth.Scope = &scopeReq{ - Project: &projectReq{ID: &scope.ProjectID}, - } - } else if scope.DomainID != "" { - // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. - if scope.DomainName != "" { - return createErr(ErrScopeDomainIDOrDomainName) - } - - // DomainID - req.Auth.Scope = &scopeReq{ - Domain: &domainReq{ID: &scope.DomainID}, - } - } else if scope.DomainName != "" { - return createErr(ErrScopeDomainName) - } else { - return createErr(ErrScopeEmpty) - } - } - - var result CreateResult - var response *perigee.Response - response, result.Err = perigee.Request("POST", tokenURL(c), perigee.Options{ - ReqBody: &req, - Results: &result.Body, - OkCodes: []int{201}, - }) - if result.Err != nil { - return result - } - result.Header = response.HttpResponse.Header - return result -} - -// Get validates and retrieves information about another token. -func Get(c *gophercloud.ServiceClient, token string) GetResult { - var result GetResult - var response *perigee.Response - response, result.Err = perigee.Request("GET", tokenURL(c), perigee.Options{ - MoreHeaders: subjectTokenHeaders(c, token), - Results: &result.Body, - OkCodes: []int{200, 203}, - }) - if result.Err != nil { - return result - } - result.Header = response.HttpResponse.Header - return result -} - -// Validate determines if a specified token is valid or not. -func Validate(c *gophercloud.ServiceClient, token string) (bool, error) { - response, err := perigee.Request("HEAD", tokenURL(c), perigee.Options{ - MoreHeaders: subjectTokenHeaders(c, token), - OkCodes: []int{204, 404}, - }) - if err != nil { - return false, err - } - - return response.StatusCode == 204, nil -} - -// Revoke immediately makes specified token invalid. -func Revoke(c *gophercloud.ServiceClient, token string) RevokeResult { - var res RevokeResult - _, res.Err = perigee.Request("DELETE", tokenURL(c), perigee.Options{ - MoreHeaders: subjectTokenHeaders(c, token), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests_test.go deleted file mode 100644 index 2b26e4ad36..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests_test.go +++ /dev/null @@ -1,514 +0,0 @@ -package tokens - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/testhelper" -) - -// authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. -func authTokenPost(t *testing.T, options gophercloud.AuthOptions, scope *Scope, requestJSON string) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - client := gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{ - TokenID: "12345abcdef", - }, - Endpoint: testhelper.Endpoint(), - } - - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "POST") - testhelper.TestHeader(t, r, "Content-Type", "application/json") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestJSONRequest(t, r, requestJSON) - - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ - "token": { - "expires_at": "2014-10-02T13:45:00.000000Z" - } - }`) - }) - - _, err := Create(&client, options, scope).Extract() - if err != nil { - t.Errorf("Create returned an error: %v", err) - } -} - -func authTokenPostErr(t *testing.T, options gophercloud.AuthOptions, scope *Scope, includeToken bool, expectedErr error) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - client := gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), - } - if includeToken { - client.TokenID = "abcdef123456" - } - - _, err := Create(&client, options, scope).Extract() - if err == nil { - t.Errorf("Create did NOT return an error") - } - if err != expectedErr { - t.Errorf("Create returned an unexpected error: wanted %v, got %v", expectedErr, err) - } -} - -func TestCreateUserIDAndPassword(t *testing.T) { - authTokenPost(t, gophercloud.AuthOptions{UserID: "me", Password: "squirrel!"}, nil, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { "id": "me", "password": "squirrel!" } - } - } - } - } - `) -} - -func TestCreateUsernameDomainIDPassword(t *testing.T) { - authTokenPost(t, gophercloud.AuthOptions{Username: "fakey", Password: "notpassword", DomainID: "abc123"}, nil, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "domain": { - "id": "abc123" - }, - "name": "fakey", - "password": "notpassword" - } - } - } - } - } - `) -} - -func TestCreateUsernameDomainNamePassword(t *testing.T) { - authTokenPost(t, gophercloud.AuthOptions{Username: "frank", Password: "swordfish", DomainName: "spork.net"}, nil, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "domain": { - "name": "spork.net" - }, - "name": "frank", - "password": "swordfish" - } - } - } - } - } - `) -} - -func TestCreateTokenID(t *testing.T) { - authTokenPost(t, gophercloud.AuthOptions{}, nil, ` - { - "auth": { - "identity": { - "methods": ["token"], - "token": { - "id": "12345abcdef" - } - } - } - } - `) -} - -func TestCreateProjectIDScope(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"} - scope := &Scope{ProjectID: "123456"} - authTokenPost(t, options, scope, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "id": "fenris", - "password": "g0t0h311" - } - } - }, - "scope": { - "project": { - "id": "123456" - } - } - } - } - `) -} - -func TestCreateDomainIDScope(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"} - scope := &Scope{DomainID: "1000"} - authTokenPost(t, options, scope, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "id": "fenris", - "password": "g0t0h311" - } - } - }, - "scope": { - "domain": { - "id": "1000" - } - } - } - } - `) -} - -func TestCreateProjectNameAndDomainIDScope(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"} - scope := &Scope{ProjectName: "world-domination", DomainID: "1000"} - authTokenPost(t, options, scope, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "id": "fenris", - "password": "g0t0h311" - } - } - }, - "scope": { - "project": { - "domain": { - "id": "1000" - }, - "name": "world-domination" - } - } - } - } - `) -} - -func TestCreateProjectNameAndDomainNameScope(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"} - scope := &Scope{ProjectName: "world-domination", DomainName: "evil-plans"} - authTokenPost(t, options, scope, ` - { - "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "id": "fenris", - "password": "g0t0h311" - } - } - }, - "scope": { - "project": { - "domain": { - "name": "evil-plans" - }, - "name": "world-domination" - } - } - } - } - `) -} - -func TestCreateExtractsTokenFromResponse(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - client := gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{}, - Endpoint: testhelper.Endpoint(), - } - - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("X-Subject-Token", "aaa111") - - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ - "token": { - "expires_at": "2014-10-02T13:45:00.000000Z" - } - }`) - }) - - options := gophercloud.AuthOptions{UserID: "me", Password: "shhh"} - token, err := Create(&client, options, nil).Extract() - if err != nil { - t.Fatalf("Create returned an error: %v", err) - } - - if token.ID != "aaa111" { - t.Errorf("Expected token to be aaa111, but was %s", token.ID) - } -} - -func TestCreateFailureEmptyAuth(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{}, nil, false, ErrMissingPassword) -} - -func TestCreateFailureAPIKey(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{APIKey: "something"}, nil, false, ErrAPIKeyProvided) -} - -func TestCreateFailureTenantID(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{TenantID: "something"}, nil, false, ErrTenantIDProvided) -} - -func TestCreateFailureTenantName(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{TenantName: "something"}, nil, false, ErrTenantNameProvided) -} - -func TestCreateFailureTokenIDUsername(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{Username: "something"}, nil, true, ErrUsernameWithToken) -} - -func TestCreateFailureTokenIDUserID(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{UserID: "something"}, nil, true, ErrUserIDWithToken) -} - -func TestCreateFailureTokenIDDomainID(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{DomainID: "something"}, nil, true, ErrDomainIDWithToken) -} - -func TestCreateFailureTokenIDDomainName(t *testing.T) { - authTokenPostErr(t, gophercloud.AuthOptions{DomainName: "something"}, nil, true, ErrDomainNameWithToken) -} - -func TestCreateFailureMissingUser(t *testing.T) { - options := gophercloud.AuthOptions{Password: "supersecure"} - authTokenPostErr(t, options, nil, false, ErrUsernameOrUserID) -} - -func TestCreateFailureBothUser(t *testing.T) { - options := gophercloud.AuthOptions{ - Password: "supersecure", - Username: "oops", - UserID: "redundancy", - } - authTokenPostErr(t, options, nil, false, ErrUsernameOrUserID) -} - -func TestCreateFailureMissingDomain(t *testing.T) { - options := gophercloud.AuthOptions{ - Password: "supersecure", - Username: "notuniqueenough", - } - authTokenPostErr(t, options, nil, false, ErrDomainIDOrDomainName) -} - -func TestCreateFailureBothDomain(t *testing.T) { - options := gophercloud.AuthOptions{ - Password: "supersecure", - Username: "someone", - DomainID: "hurf", - DomainName: "durf", - } - authTokenPostErr(t, options, nil, false, ErrDomainIDOrDomainName) -} - -func TestCreateFailureUserIDDomainID(t *testing.T) { - options := gophercloud.AuthOptions{ - UserID: "100", - Password: "stuff", - DomainID: "oops", - } - authTokenPostErr(t, options, nil, false, ErrDomainIDWithUserID) -} - -func TestCreateFailureUserIDDomainName(t *testing.T) { - options := gophercloud.AuthOptions{ - UserID: "100", - Password: "sssh", - DomainName: "oops", - } - authTokenPostErr(t, options, nil, false, ErrDomainNameWithUserID) -} - -func TestCreateFailureScopeProjectNameAlone(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{ProjectName: "notenough"} - authTokenPostErr(t, options, scope, false, ErrScopeDomainIDOrDomainName) -} - -func TestCreateFailureScopeProjectNameAndID(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"} - authTokenPostErr(t, options, scope, false, ErrScopeProjectIDOrProjectName) -} - -func TestCreateFailureScopeProjectIDAndDomainID(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{ProjectID: "toomuch", DomainID: "notneeded"} - authTokenPostErr(t, options, scope, false, ErrScopeProjectIDAlone) -} - -func TestCreateFailureScopeProjectIDAndDomainNAme(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{ProjectID: "toomuch", DomainName: "notneeded"} - authTokenPostErr(t, options, scope, false, ErrScopeProjectIDAlone) -} - -func TestCreateFailureScopeDomainIDAndDomainName(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{DomainID: "toomuch", DomainName: "notneeded"} - authTokenPostErr(t, options, scope, false, ErrScopeDomainIDOrDomainName) -} - -func TestCreateFailureScopeDomainNameAlone(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{DomainName: "notenough"} - authTokenPostErr(t, options, scope, false, ErrScopeDomainName) -} - -func TestCreateFailureEmptyScope(t *testing.T) { - options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"} - scope := &Scope{} - authTokenPostErr(t, options, scope, false, ErrScopeEmpty) -} - -func TestGetRequest(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - client := gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{ - TokenID: "12345abcdef", - }, - Endpoint: testhelper.Endpoint(), - } - - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, "GET") - testhelper.TestHeader(t, r, "Content-Type", "") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef") - testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345") - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` - { "token": { "expires_at": "2014-08-29T13:10:01.000000Z" } } - `) - }) - - token, err := Get(&client, "abcdef12345").Extract() - if err != nil { - t.Errorf("Info returned an error: %v", err) - } - - expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014") - if token.ExpiresAt != expected { - t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), token.ExpiresAt.Format(time.UnixDate)) - } -} - -func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) gophercloud.ServiceClient { - client := gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{ - TokenID: "12345abcdef", - }, - Endpoint: testhelper.Endpoint(), - } - - testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { - testhelper.TestMethod(t, r, expectedMethod) - testhelper.TestHeader(t, r, "Content-Type", "") - testhelper.TestHeader(t, r, "Accept", "application/json") - testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef") - testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345") - - w.WriteHeader(status) - }) - - return client -} - -func TestValidateRequestSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent) - - ok, err := Validate(&client, "abcdef12345") - if err != nil { - t.Errorf("Unexpected error from Validate: %v", err) - } - - if !ok { - t.Errorf("Validate returned false for a valid token") - } -} - -func TestValidateRequestFailure(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound) - - ok, err := Validate(&client, "abcdef12345") - if err != nil { - t.Errorf("Unexpected error from Validate: %v", err) - } - - if ok { - t.Errorf("Validate returned true for an invalid token") - } -} - -func TestValidateRequestError(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - client := prepareAuthTokenHandler(t, "HEAD", http.StatusUnauthorized) - - _, err := Validate(&client, "abcdef12345") - if err == nil { - t.Errorf("Missing expected error from Validate") - } -} - -func TestRevokeRequestSuccessful(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent) - - res := Revoke(&client, "abcdef12345") - testhelper.AssertNoErr(t, res.Err) -} - -func TestRevokeRequestError(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound) - - res := Revoke(&client, "abcdef12345") - if res.Err == nil { - t.Errorf("Missing expected error from Revoke") - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go deleted file mode 100644 index d1fff4c2a5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go +++ /dev/null @@ -1,73 +0,0 @@ -package tokens - -import ( - "time" - - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" -) - -// commonResult is the deferred result of a Create or a Get call. -type commonResult struct { - gophercloud.Result -} - -// Extract interprets a commonResult as a Token. -func (r commonResult) Extract() (*Token, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Token struct { - ExpiresAt string `mapstructure:"expires_at"` - } `mapstructure:"token"` - } - - var token Token - - // Parse the token itself from the stored headers. - token.ID = r.Header.Get("X-Subject-Token") - - err := mapstructure.Decode(r.Body, &response) - if err != nil { - return nil, err - } - - // Attempt to parse the timestamp. - token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt) - - return &token, err -} - -// CreateResult is the deferred response from a Create call. -type CreateResult struct { - commonResult -} - -// createErr quickly creates a CreateResult that reports an error. -func createErr(err error) CreateResult { - return CreateResult{ - commonResult: commonResult{Result: gophercloud.Result{Err: err}}, - } -} - -// GetResult is the deferred response from a Get call. -type GetResult struct { - commonResult -} - -// RevokeResult is the deferred response from a Revoke call. -type RevokeResult struct { - commonResult -} - -// Token is a string that grants a user access to a controlled set of services in an OpenStack provider. -// Each Token is valid for a set length of time. -type Token struct { - // ID is the issued token. - ID string - - // ExpiresAt is the timestamp at which this token will no longer be accepted. - ExpiresAt time.Time -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls_test.go deleted file mode 100644 index 549c398620..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package tokens - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/testhelper" -) - -func TestTokenURL(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - client := gophercloud.ServiceClient{Endpoint: testhelper.Endpoint()} - - expected := testhelper.Endpoint() + "auth/tokens" - actual := tokenURL(&client) - if actual != expected { - t.Errorf("Expected URL %s, but was %s", expected, actual) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/doc.go deleted file mode 100644 index 0208ee20ec..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package apiversions provides information and interaction with the different -// API versions for the OpenStack Neutron service. This functionality is not -// restricted to this particular version. -package apiversions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/errors.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/errors.go deleted file mode 100644 index 76bdb14f75..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/errors.go +++ /dev/null @@ -1 +0,0 @@ -package apiversions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/requests.go deleted file mode 100644 index 9fb6de1411..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/requests.go +++ /dev/null @@ -1,21 +0,0 @@ -package apiversions - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListVersions lists all the Neutron API versions available to end-users -func ListVersions(c *gophercloud.ServiceClient) pagination.Pager { - return pagination.NewPager(c, apiVersionsURL(c), func(r pagination.PageResult) pagination.Page { - return APIVersionPage{pagination.SinglePageBase(r)} - }) -} - -// ListVersionResources lists all of the different API resources for a particular -// API versions. Typical resources for Neutron might be: networks, subnets, etc. -func ListVersionResources(c *gophercloud.ServiceClient, v string) pagination.Pager { - return pagination.NewPager(c, apiInfoURL(c, v), func(r pagination.PageResult) pagination.Page { - return APIVersionResourcePage{pagination.SinglePageBase(r)} - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/requests_test.go deleted file mode 100644 index d35af9f0c6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/requests_test.go +++ /dev/null @@ -1,182 +0,0 @@ -package apiversions - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "versions": [ - { - "status": "CURRENT", - "id": "v2.0", - "links": [ - { - "href": "http://23.253.228.211:9696/v2.0", - "rel": "self" - } - ] - } - ] -}`) - }) - - count := 0 - - ListVersions(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractAPIVersions(page) - if err != nil { - t.Errorf("Failed to extract API versions: %v", err) - return false, err - } - - expected := []APIVersion{ - APIVersion{ - Status: "CURRENT", - ID: "v2.0", - }, - } - - th.AssertDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestNonJSONCannotBeExtractedIntoAPIVersions(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - }) - - ListVersions(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - if _, err := ExtractAPIVersions(page); err == nil { - t.Fatalf("Expected error, got nil") - } - return true, nil - }) -} - -func TestAPIInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "resources": [ - { - "links": [ - { - "href": "http://23.253.228.211:9696/v2.0/subnets", - "rel": "self" - } - ], - "name": "subnet", - "collection": "subnets" - }, - { - "links": [ - { - "href": "http://23.253.228.211:9696/v2.0/networks", - "rel": "self" - } - ], - "name": "network", - "collection": "networks" - }, - { - "links": [ - { - "href": "http://23.253.228.211:9696/v2.0/ports", - "rel": "self" - } - ], - "name": "port", - "collection": "ports" - } - ] -} - `) - }) - - count := 0 - - ListVersionResources(fake.ServiceClient(), "v2.0").EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVersionResources(page) - if err != nil { - t.Errorf("Failed to extract version resources: %v", err) - return false, err - } - - expected := []APIVersionResource{ - APIVersionResource{ - Name: "subnet", - Collection: "subnets", - }, - APIVersionResource{ - Name: "network", - Collection: "networks", - }, - APIVersionResource{ - Name: "port", - Collection: "ports", - }, - } - - th.AssertDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestNonJSONCannotBeExtractedIntoAPIVersionResources(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - }) - - ListVersionResources(fake.ServiceClient(), "v2.0").EachPage(func(page pagination.Page) (bool, error) { - if _, err := ExtractVersionResources(page); err == nil { - t.Fatalf("Expected error, got nil") - } - return true, nil - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/results.go deleted file mode 100644 index 97159341ff..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/results.go +++ /dev/null @@ -1,77 +0,0 @@ -package apiversions - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud/pagination" -) - -// APIVersion represents an API version for Neutron. It contains the status of -// the API, and its unique ID. -type APIVersion struct { - Status string `mapstructure:"status" json:"status"` - ID string `mapstructure:"id" json:"id"` -} - -// APIVersionPage is the page returned by a pager when traversing over a -// collection of API versions. -type APIVersionPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether an APIVersionPage struct is empty. -func (r APIVersionPage) IsEmpty() (bool, error) { - is, err := ExtractAPIVersions(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -// ExtractAPIVersions takes a collection page, extracts all of the elements, -// and returns them a slice of APIVersion structs. It is effectively a cast. -func ExtractAPIVersions(page pagination.Page) ([]APIVersion, error) { - var resp struct { - Versions []APIVersion `mapstructure:"versions"` - } - - err := mapstructure.Decode(page.(APIVersionPage).Body, &resp) - - return resp.Versions, err -} - -// APIVersionResource represents a generic API resource. It contains the name -// of the resource and its plural collection name. -type APIVersionResource struct { - Name string `mapstructure:"name" json:"name"` - Collection string `mapstructure:"collection" json:"collection"` -} - -// APIVersionResourcePage is a concrete type which embeds the common -// SinglePageBase struct, and is used when traversing API versions collections. -type APIVersionResourcePage struct { - pagination.SinglePageBase -} - -// IsEmpty is a concrete function which indicates whether an -// APIVersionResourcePage is empty or not. -func (r APIVersionResourcePage) IsEmpty() (bool, error) { - is, err := ExtractVersionResources(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -// ExtractVersionResources accepts a Page struct, specifically a -// APIVersionResourcePage struct, and extracts the elements into a slice of -// APIVersionResource structs. In other words, the collection is mapped into -// a relevant slice. -func ExtractVersionResources(page pagination.Page) ([]APIVersionResource, error) { - var resp struct { - APIVersionResources []APIVersionResource `mapstructure:"resources"` - } - - err := mapstructure.Decode(page.(APIVersionResourcePage).Body, &resp) - - return resp.APIVersionResources, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/urls.go deleted file mode 100644 index 58aa2b61f8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package apiversions - -import ( - "strings" - - "github.com/rackspace/gophercloud" -) - -func apiVersionsURL(c *gophercloud.ServiceClient) string { - return c.Endpoint -} - -func apiInfoURL(c *gophercloud.ServiceClient, version string) string { - return c.Endpoint + strings.TrimRight(version, "/") + "/" -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/urls_test.go deleted file mode 100644 index 7dd069c94f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/apiversions/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package apiversions - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestAPIVersionsURL(t *testing.T) { - actual := apiVersionsURL(endpointClient()) - expected := endpoint - th.AssertEquals(t, expected, actual) -} - -func TestAPIInfoURL(t *testing.T) { - actual := apiInfoURL(endpointClient(), "v2.0") - expected := endpoint + "v2.0/" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/common/common_tests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/common/common_tests.go deleted file mode 100644 index 41603510d6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/common/common_tests.go +++ /dev/null @@ -1,14 +0,0 @@ -package common - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const TokenID = client.TokenID - -func ServiceClient() *gophercloud.ServiceClient { - sc := client.ServiceClient() - sc.ResourceBase = sc.Endpoint + "v2.0/" - return sc -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/delegate.go deleted file mode 100644 index d08e1fda97..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/delegate.go +++ /dev/null @@ -1,41 +0,0 @@ -package extensions - -import ( - "github.com/rackspace/gophercloud" - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" -) - -// Extension is a single OpenStack extension. -type Extension struct { - common.Extension -} - -// GetResult wraps a GetResult from common. -type GetResult struct { - common.GetResult -} - -// ExtractExtensions interprets a Page as a slice of Extensions. -func ExtractExtensions(page pagination.Page) ([]Extension, error) { - inner, err := common.ExtractExtensions(page) - if err != nil { - return nil, err - } - outer := make([]Extension, len(inner)) - for index, ext := range inner { - outer[index] = Extension{ext} - } - return outer, nil -} - -// Get retrieves information for a specific extension using its alias. -func Get(c *gophercloud.ServiceClient, alias string) GetResult { - return GetResult{common.Get(c, alias)} -} - -// List returns a Pager which allows you to iterate over the full collection of extensions. -// It does not accept query parameters. -func List(c *gophercloud.ServiceClient) pagination.Pager { - return common.List(c) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/delegate_test.go deleted file mode 100644 index 3d2ac78d48..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/delegate_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package extensions - -import ( - "fmt" - "net/http" - "testing" - - common "github.com/rackspace/gophercloud/openstack/common/extensions" - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/extensions", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - - fmt.Fprintf(w, ` -{ - "extensions": [ - { - "updated": "2013-01-20T00:00:00-00:00", - "name": "Neutron Service Type Management", - "links": [], - "namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - "alias": "service-type", - "description": "API for retrieving service providers for Neutron advanced services" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractExtensions(page) - if err != nil { - t.Errorf("Failed to extract extensions: %v", err) - } - - expected := []Extension{ - Extension{ - common.Extension{ - Updated: "2013-01-20T00:00:00-00:00", - Name: "Neutron Service Type Management", - Links: []interface{}{}, - Namespace: "http://docs.openstack.org/ext/neutron/service-type/api/v1.0", - Alias: "service-type", - Description: "API for retrieving service providers for Neutron advanced services", - }, - }, - } - - th.AssertDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/extensions/agent", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "extension": { - "updated": "2013-02-03T10:00:00-00:00", - "name": "agent", - "links": [], - "namespace": "http://docs.openstack.org/ext/agent/api/v2.0", - "alias": "agent", - "description": "The agent management extension." - } -} - `) - }) - - ext, err := Get(fake.ServiceClient(), "agent").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ext.Updated, "2013-02-03T10:00:00-00:00") - th.AssertEquals(t, ext.Name, "agent") - th.AssertEquals(t, ext.Namespace, "http://docs.openstack.org/ext/agent/api/v2.0") - th.AssertEquals(t, ext.Alias, "agent") - th.AssertEquals(t, ext.Description, "The agent management extension.") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/doc.go deleted file mode 100644 index dad3a844f7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package external provides information and interaction with the external -// extension for the OpenStack Networking service. -package external diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/requests.go deleted file mode 100644 index 2f04593db9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/requests.go +++ /dev/null @@ -1,56 +0,0 @@ -package external - -import "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - -// AdminState gives users a solid type to work with for create and update -// operations. It is recommended that users use the `Up` and `Down` enums. -type AdminState *bool - -// Convenience vars for AdminStateUp values. -var ( - iTrue = true - iFalse = false - - Up AdminState = &iTrue - Down AdminState = &iFalse -) - -// CreateOpts is the structure used when creating new external network -// resources. It embeds networks.CreateOpts and so inherits all of its required -// and optional fields, with the addition of the External field. -type CreateOpts struct { - Parent networks.CreateOpts - External bool -} - -// ToNetworkCreateMap casts a CreateOpts struct to a map. -func (o CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { - outer, err := o.Parent.ToNetworkCreateMap() - if err != nil { - return nil, err - } - - outer["network"].(map[string]interface{})["router:external"] = o.External - - return outer, nil -} - -// UpdateOpts is the structure used when updating existing external network -// resources. It embeds networks.UpdateOpts and so inherits all of its required -// and optional fields, with the addition of the External field. -type UpdateOpts struct { - Parent networks.UpdateOpts - External bool -} - -// ToNetworkUpdateMap casts an UpdateOpts struct to a map. -func (o UpdateOpts) ToNetworkUpdateMap() (map[string]interface{}, error) { - outer, err := o.Parent.ToNetworkUpdateMap() - if err != nil { - return nil, err - } - - outer["network"].(map[string]interface{})["router:external"] = o.External - - return outer, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/results.go deleted file mode 100644 index 1c173c07a3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/results.go +++ /dev/null @@ -1,81 +0,0 @@ -package external - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" -) - -// NetworkExternal represents a decorated form of a Network with based on the -// "external-net" extension. -type NetworkExternal struct { - // UUID for the network - ID string `mapstructure:"id" json:"id"` - - // Human-readable name for the network. Might not be unique. - Name string `mapstructure:"name" json:"name"` - - // The administrative state of network. If false (down), the network does not forward packets. - AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"` - - // Indicates whether network is currently operational. Possible values include - // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values. - Status string `mapstructure:"status" json:"status"` - - // Subnets associated with this network. - Subnets []string `mapstructure:"subnets" json:"subnets"` - - // Owner of network. Only admin users can specify a tenant_id other than its own. - TenantID string `mapstructure:"tenant_id" json:"tenant_id"` - - // Specifies whether the network resource can be accessed by any tenant or not. - Shared bool `mapstructure:"shared" json:"shared"` - - // Specifies whether the network is an external network or not. - External bool `mapstructure:"router:external" json:"router:external"` -} - -func commonExtract(e error, response interface{}) (*NetworkExternal, error) { - if e != nil { - return nil, e - } - - var res struct { - Network *NetworkExternal `json:"network"` - } - - err := mapstructure.Decode(response, &res) - - return res.Network, err -} - -// ExtractGet decorates a GetResult struct returned from a networks.Get() -// function with extended attributes. -func ExtractGet(r networks.GetResult) (*NetworkExternal, error) { - return commonExtract(r.Err, r.Body) -} - -// ExtractCreate decorates a CreateResult struct returned from a networks.Create() -// function with extended attributes. -func ExtractCreate(r networks.CreateResult) (*NetworkExternal, error) { - return commonExtract(r.Err, r.Body) -} - -// ExtractUpdate decorates a UpdateResult struct returned from a -// networks.Update() function with extended attributes. -func ExtractUpdate(r networks.UpdateResult) (*NetworkExternal, error) { - return commonExtract(r.Err, r.Body) -} - -// ExtractList accepts a Page struct, specifically a NetworkPage struct, and -// extracts the elements into a slice of NetworkExtAttrs structs. In other -// words, a generic collection is mapped into a relevant slice. -func ExtractList(page pagination.Page) ([]NetworkExternal, error) { - var resp struct { - Networks []NetworkExternal `mapstructure:"networks" json:"networks"` - } - - err := mapstructure.Decode(page.(networks.NetworkPage).Body, &resp) - - return resp.Networks, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/results_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/results_test.go deleted file mode 100644 index 916cd2cfd0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external/results_test.go +++ /dev/null @@ -1,254 +0,0 @@ -package external - -import ( - "errors" - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "networks": [ - { - "admin_state_up": true, - "id": "0f38d5ad-10a6-428f-a5fc-825cfe0f1970", - "name": "net1", - "router:external": false, - "shared": false, - "status": "ACTIVE", - "subnets": [ - "25778974-48a8-46e7-8998-9dc8c70d2f06" - ], - "tenant_id": "b575417a6c444a6eb5cc3a58eb4f714a" - }, - { - "admin_state_up": true, - "id": "8d05a1b1-297a-46ca-8974-17debf51ca3c", - "name": "ext_net", - "router:external": true, - "shared": false, - "status": "ACTIVE", - "subnets": [ - "2f1fb918-9b0e-4bf9-9a50-6cebbb4db2c5" - ], - "tenant_id": "5eb8995cf717462c9df8d1edfa498010" - } - ] -} - `) - }) - - count := 0 - - networks.List(fake.ServiceClient(), networks.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractList(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - expected := []NetworkExternal{ - NetworkExternal{ - Status: "ACTIVE", - Subnets: []string{"25778974-48a8-46e7-8998-9dc8c70d2f06"}, - Name: "net1", - AdminStateUp: true, - TenantID: "b575417a6c444a6eb5cc3a58eb4f714a", - Shared: false, - ID: "0f38d5ad-10a6-428f-a5fc-825cfe0f1970", - External: false, - }, - NetworkExternal{ - Status: "ACTIVE", - Subnets: []string{"2f1fb918-9b0e-4bf9-9a50-6cebbb4db2c5"}, - Name: "ext_net", - AdminStateUp: true, - TenantID: "5eb8995cf717462c9df8d1edfa498010", - Shared: false, - ID: "8d05a1b1-297a-46ca-8974-17debf51ca3c", - External: true, - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "admin_state_up": true, - "id": "8d05a1b1-297a-46ca-8974-17debf51ca3c", - "name": "ext_net", - "router:external": true, - "shared": false, - "status": "ACTIVE", - "subnets": [ - "2f1fb918-9b0e-4bf9-9a50-6cebbb4db2c5" - ], - "tenant_id": "5eb8995cf717462c9df8d1edfa498010" - } -} - `) - }) - - res := networks.Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - n, err := ExtractGet(res) - - th.AssertNoErr(t, err) - th.AssertEquals(t, true, n.External) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "admin_state_up": true, - "name": "ext_net", - "router:external": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "network": { - "admin_state_up": true, - "id": "8d05a1b1-297a-46ca-8974-17debf51ca3c", - "name": "ext_net", - "router:external": true, - "shared": false, - "status": "ACTIVE", - "subnets": [ - "2f1fb918-9b0e-4bf9-9a50-6cebbb4db2c5" - ], - "tenant_id": "5eb8995cf717462c9df8d1edfa498010" - } -} - `) - }) - - options := CreateOpts{networks.CreateOpts{Name: "ext_net", AdminStateUp: Up}, true} - res := networks.Create(fake.ServiceClient(), options) - - n, err := ExtractCreate(res) - - th.AssertNoErr(t, err) - th.AssertEquals(t, true, n.External) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "router:external": true, - "name": "new_name" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "admin_state_up": true, - "id": "8d05a1b1-297a-46ca-8974-17debf51ca3c", - "name": "new_name", - "router:external": true, - "shared": false, - "status": "ACTIVE", - "subnets": [ - "2f1fb918-9b0e-4bf9-9a50-6cebbb4db2c5" - ], - "tenant_id": "5eb8995cf717462c9df8d1edfa498010" - } -} - `) - }) - - options := UpdateOpts{networks.UpdateOpts{Name: "new_name"}, true} - res := networks.Update(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options) - n, err := ExtractUpdate(res) - - th.AssertNoErr(t, err) - th.AssertEquals(t, true, n.External) -} - -func TestExtractFnsReturnsErrWhenResultContainsErr(t *testing.T) { - gr := networks.GetResult{} - gr.Err = errors.New("") - - if _, err := ExtractGet(gr); err == nil { - t.Fatalf("Expected error, got one") - } - - ur := networks.UpdateResult{} - ur.Err = errors.New("") - - if _, err := ExtractUpdate(ur); err == nil { - t.Fatalf("Expected error, got one") - } - - cr := networks.CreateResult{} - cr.Err = errors.New("") - - if _, err := ExtractCreate(cr); err == nil { - t.Fatalf("Expected error, got one") - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/doc.go deleted file mode 100644 index d533458267..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package layer3 provides access to the Layer-3 networking extension for the -// OpenStack Neutron service. This extension allows API users to route packets -// between subnets, forward packets from internal networks to external ones, -// and access instances from external networks through floating IPs. -package layer3 diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go deleted file mode 100644 index d23f9e2b5a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go +++ /dev/null @@ -1,190 +0,0 @@ -package floatingips - -import ( - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - FloatingNetworkID string `q:"floating_network_id"` - PortID string `q:"port_id"` - FixedIP string `q:"fixed_ip_address"` - FloatingIP string `q:"floating_ip_address"` - TenantID string `q:"tenant_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// floating IP resources. It accepts a ListOpts struct, which allows you to -// filter and sort the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return FloatingIPPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOpts contains all the values needed to create a new floating IP -// resource. The only required fields are FloatingNetworkID and PortID which -// refer to the external network and internal port respectively. -type CreateOpts struct { - FloatingNetworkID string - FloatingIP string - PortID string - FixedIP string - TenantID string -} - -var ( - errFloatingNetworkIDRequired = fmt.Errorf("A NetworkID is required") - errPortIDRequired = fmt.Errorf("A PortID is required") -) - -// Create accepts a CreateOpts struct and uses the values provided to create a -// new floating IP resource. You can create floating IPs on external networks -// only. If you provide a FloatingNetworkID which refers to a network that is -// not external (i.e. its `router:external' attribute is False), the operation -// will fail and return a 400 error. -// -// If you do not specify a FloatingIP address value, the operation will -// automatically allocate an available address for the new resource. If you do -// choose to specify one, it must fall within the subnet range for the external -// network - otherwise the operation returns a 400 error. If the FloatingIP -// address is already in use, the operation returns a 409 error code. -// -// You can associate the new resource with an internal port by using the PortID -// field. If you specify a PortID that is not valid, the operation will fail and -// return 404 error code. -// -// You must also configure an IP address for the port associated with the PortID -// you have provided - this is what the FixedIP refers to: an IP fixed to a port. -// Because a port might be associated with multiple IP addresses, you can use -// the FixedIP field to associate a particular IP address rather than have the -// API assume for you. If you specify an IP address that is not valid, the -// operation will fail and return a 400 error code. If the PortID and FixedIP -// are already associated with another resource, the operation will fail and -// returns a 409 error code. -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - var res CreateResult - - // Validate - if opts.FloatingNetworkID == "" { - res.Err = errFloatingNetworkIDRequired - return res - } - if opts.PortID == "" { - res.Err = errPortIDRequired - return res - } - - // Define structures - type floatingIP struct { - FloatingNetworkID string `json:"floating_network_id"` - FloatingIP string `json:"floating_ip_address,omitempty"` - PortID string `json:"port_id"` - FixedIP string `json:"fixed_ip_address,omitempty"` - TenantID string `json:"tenant_id,omitempty"` - } - type request struct { - FloatingIP floatingIP `json:"floatingip"` - } - - // Populate request body - reqBody := request{FloatingIP: floatingIP{ - FloatingNetworkID: opts.FloatingNetworkID, - PortID: opts.PortID, - FixedIP: opts.FixedIP, - TenantID: opts.TenantID, - }} - - // Send request to API - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// Get retrieves a particular floating IP resource based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// UpdateOpts contains the values used when updating a floating IP resource. The -// only value that can be updated is which internal port the floating IP is -// linked to. To associate the floating IP with a new internal port, provide its -// ID. To disassociate the floating IP from all ports, provide an empty string. -type UpdateOpts struct { - PortID string -} - -// Update allows floating IP resources to be updated. Currently, the only way to -// "update" a floating IP is to associate it with a new internal port, or -// disassociated it from all ports. See UpdateOpts for instructions of how to -// do this. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { - type floatingIP struct { - PortID *string `json:"port_id"` - } - - type request struct { - FloatingIP floatingIP `json:"floatingip"` - } - - var portID *string - if opts.PortID == "" { - portID = nil - } else { - portID = &opts.PortID - } - - reqBody := request{FloatingIP: floatingIP{PortID: portID}} - - // Send request to API - var res UpdateResult - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Delete will permanently delete a particular floating IP resource. Please -// ensure this is what you want - you can also disassociate the IP from existing -// internal ports. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests_test.go deleted file mode 100644 index 19614be2ef..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests_test.go +++ /dev/null @@ -1,306 +0,0 @@ -package floatingips - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "floatingips": [ - { - "floating_network_id": "6d67c30a-ddb4-49a1-bec3-a65b286b4170", - "router_id": null, - "fixed_ip_address": null, - "floating_ip_address": "192.0.0.4", - "tenant_id": "017d8de156df4177889f31a9bd6edc00", - "status": "DOWN", - "port_id": null, - "id": "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e" - }, - { - "floating_network_id": "90f742b1-6d17-487b-ba95-71881dbc0b64", - "router_id": "0a24cb83-faf5-4d7f-b723-3144ed8a2167", - "fixed_ip_address": "192.0.0.2", - "floating_ip_address": "10.0.0.3", - "tenant_id": "017d8de156df4177889f31a9bd6edc00", - "status": "DOWN", - "port_id": "74a342ce-8e07-4e91-880c-9f834b68fa25", - "id": "ada25a95-f321-4f59-b0e0-f3a970dd3d63" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractFloatingIPs(page) - if err != nil { - t.Errorf("Failed to extract floating IPs: %v", err) - return false, err - } - - expected := []FloatingIP{ - FloatingIP{ - FloatingNetworkID: "6d67c30a-ddb4-49a1-bec3-a65b286b4170", - FixedIP: "", - FloatingIP: "192.0.0.4", - TenantID: "017d8de156df4177889f31a9bd6edc00", - Status: "DOWN", - PortID: "", - ID: "2f95fd2b-9f6a-4e8e-9e9a-2cbe286cbf9e", - }, - FloatingIP{ - FloatingNetworkID: "90f742b1-6d17-487b-ba95-71881dbc0b64", - FixedIP: "192.0.0.2", - FloatingIP: "10.0.0.3", - TenantID: "017d8de156df4177889f31a9bd6edc00", - Status: "DOWN", - PortID: "74a342ce-8e07-4e91-880c-9f834b68fa25", - ID: "ada25a95-f321-4f59-b0e0-f3a970dd3d63", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestInvalidNextPageURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{"floatingips": [{}], "floatingips_links": {}}`) - }) - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - ExtractFloatingIPs(page) - return true, nil - }) -} - -func TestRequiredFieldsForCreate(t *testing.T) { - res1 := Create(fake.ServiceClient(), CreateOpts{FloatingNetworkID: ""}) - if res1.Err == nil { - t.Fatalf("Expected error, got none") - } - - res2 := Create(fake.ServiceClient(), CreateOpts{FloatingNetworkID: "foo", PortID: ""}) - if res2.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "floatingip": { - "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57", - "port_id": "ce705c24-c1ef-408a-bda3-7bbd946164ab" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "floatingip": { - "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", - "tenant_id": "4969c491a3c74ee4af974e6d800c62de", - "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57", - "fixed_ip_address": "10.0.0.3", - "floating_ip_address": "", - "port_id": "ce705c24-c1ef-408a-bda3-7bbd946164ab", - "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7" - } -} - `) - }) - - options := CreateOpts{ - FloatingNetworkID: "376da547-b977-4cfe-9cba-275c80debf57", - PortID: "ce705c24-c1ef-408a-bda3-7bbd946164ab", - } - - ip, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "2f245a7b-796b-4f26-9cf9-9e82d248fda7", ip.ID) - th.AssertEquals(t, "4969c491a3c74ee4af974e6d800c62de", ip.TenantID) - th.AssertEquals(t, "376da547-b977-4cfe-9cba-275c80debf57", ip.FloatingNetworkID) - th.AssertEquals(t, "", ip.FloatingIP) - th.AssertEquals(t, "ce705c24-c1ef-408a-bda3-7bbd946164ab", ip.PortID) - th.AssertEquals(t, "10.0.0.3", ip.FixedIP) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "floatingip": { - "floating_network_id": "90f742b1-6d17-487b-ba95-71881dbc0b64", - "fixed_ip_address": "192.0.0.2", - "floating_ip_address": "10.0.0.3", - "tenant_id": "017d8de156df4177889f31a9bd6edc00", - "status": "DOWN", - "port_id": "74a342ce-8e07-4e91-880c-9f834b68fa25", - "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7" - } -} - `) - }) - - ip, err := Get(fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "90f742b1-6d17-487b-ba95-71881dbc0b64", ip.FloatingNetworkID) - th.AssertEquals(t, "10.0.0.3", ip.FloatingIP) - th.AssertEquals(t, "74a342ce-8e07-4e91-880c-9f834b68fa25", ip.PortID) - th.AssertEquals(t, "192.0.0.2", ip.FixedIP) - th.AssertEquals(t, "017d8de156df4177889f31a9bd6edc00", ip.TenantID) - th.AssertEquals(t, "DOWN", ip.Status) - th.AssertEquals(t, "2f245a7b-796b-4f26-9cf9-9e82d248fda7", ip.ID) -} - -func TestAssociate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "floatingip": { - "port_id": "423abc8d-2991-4a55-ba98-2aaea84cc72e" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "floatingip": { - "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", - "tenant_id": "4969c491a3c74ee4af974e6d800c62de", - "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57", - "fixed_ip_address": null, - "floating_ip_address": "172.24.4.228", - "port_id": "423abc8d-2991-4a55-ba98-2aaea84cc72e", - "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7" - } -} - `) - }) - - ip, err := Update(fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", UpdateOpts{PortID: "423abc8d-2991-4a55-ba98-2aaea84cc72e"}).Extract() - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, "423abc8d-2991-4a55-ba98-2aaea84cc72e", ip.PortID) -} - -func TestDisassociate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "floatingip": { - "port_id": null - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "floatingip": { - "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f", - "tenant_id": "4969c491a3c74ee4af974e6d800c62de", - "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57", - "fixed_ip_address": null, - "floating_ip_address": "172.24.4.228", - "port_id": null, - "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7" - } -} - `) - }) - - ip, err := Update(fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7", UpdateOpts{}).Extract() - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, "", ip.FixedIP) - th.AssertDeepEquals(t, "", ip.PortID) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/floatingips/2f245a7b-796b-4f26-9cf9-9e82d248fda7", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "2f245a7b-796b-4f26-9cf9-9e82d248fda7") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go deleted file mode 100644 index e3a144171b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go +++ /dev/null @@ -1,246 +0,0 @@ -package routers - -import ( - "errors" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - AdminStateUp *bool `q:"admin_state_up"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// routers. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those routers that are owned by the -// tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return RouterPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOpts contains all the values needed to create a new router. There are -// no required values. -type CreateOpts struct { - Name string - AdminStateUp *bool - TenantID string - GatewayInfo *GatewayInfo -} - -// Create accepts a CreateOpts struct and uses the values to create a new -// logical router. When it is created, the router does not have an internal -// interface - it is not associated to any subnet. -// -// You can optionally specify an external gateway for a router using the -// GatewayInfo struct. The external gateway for the router must be plugged into -// an external network (it is external if its `router:external' field is set to -// true). -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - type router struct { - Name *string `json:"name,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - TenantID *string `json:"tenant_id,omitempty"` - GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` - } - - type request struct { - Router router `json:"router"` - } - - reqBody := request{Router: router{ - Name: gophercloud.MaybeString(opts.Name), - AdminStateUp: opts.AdminStateUp, - TenantID: gophercloud.MaybeString(opts.TenantID), - }} - - if opts.GatewayInfo != nil { - reqBody.Router.GatewayInfo = opts.GatewayInfo - } - - var res CreateResult - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - return res -} - -// Get retrieves a particular router based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// UpdateOpts contains the values used when updating a router. -type UpdateOpts struct { - Name string - AdminStateUp *bool - GatewayInfo *GatewayInfo -} - -// Update allows routers to be updated. You can update the name, administrative -// state, and the external gateway. For more information about how to set the -// external gateway for a router, see Create. This operation does not enable -// the update of router interfaces. To do this, use the AddInterface and -// RemoveInterface functions. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { - type router struct { - Name *string `json:"name,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` - } - - type request struct { - Router router `json:"router"` - } - - reqBody := request{Router: router{ - Name: gophercloud.MaybeString(opts.Name), - AdminStateUp: opts.AdminStateUp, - }} - - if opts.GatewayInfo != nil { - reqBody.Router.GatewayInfo = opts.GatewayInfo - } - - // Send request to API - var res UpdateResult - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Delete will permanently delete a particular router based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} - -var errInvalidInterfaceOpts = errors.New("When adding a router interface you must provide either a subnet ID or a port ID") - -// InterfaceOpts allow you to work with operations that either add or remote -// an internal interface from a router. -type InterfaceOpts struct { - SubnetID string - PortID string -} - -// AddInterface attaches a subnet to an internal router interface. You must -// specify either a SubnetID or PortID in the request body. If you specify both, -// the operation will fail and an error will be returned. -// -// If you specify a SubnetID, the gateway IP address for that particular subnet -// is used to create the router interface. Alternatively, if you specify a -// PortID, the IP address associated with the port is used to create the router -// interface. -// -// If you reference a port that is associated with multiple IP addresses, or -// if the port is associated with zero IP addresses, the operation will fail and -// a 400 Bad Request error will be returned. -// -// If you reference a port already in use, the operation will fail and a 409 -// Conflict error will be returned. -// -// The PortID that is returned after using Extract() on the result of this -// operation can either be the same PortID passed in or, on the other hand, the -// identifier of a new port created by this operation. After the operation -// completes, the device ID of the port is set to the router ID, and the -// device owner attribute is set to `network:router_interface'. -func AddInterface(c *gophercloud.ServiceClient, id string, opts InterfaceOpts) InterfaceResult { - var res InterfaceResult - - // Validate - if (opts.SubnetID == "" && opts.PortID == "") || (opts.SubnetID != "" && opts.PortID != "") { - res.Err = errInvalidInterfaceOpts - return res - } - - type request struct { - SubnetID string `json:"subnet_id,omitempty"` - PortID string `json:"port_id,omitempty"` - } - - body := request{SubnetID: opts.SubnetID, PortID: opts.PortID} - - _, res.Err = perigee.Request("PUT", addInterfaceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &body, - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// RemoveInterface removes an internal router interface, which detaches a -// subnet from the router. You must specify either a SubnetID or PortID, since -// these values are used to identify the router interface to remove. -// -// Unlike AddInterface, you can also specify both a SubnetID and PortID. If you -// choose to specify both, the subnet ID must correspond to the subnet ID of -// the first IP address on the port specified by the port ID. Otherwise, the -// operation will fail and return a 409 Conflict error. -// -// If the router, subnet or port which are referenced do not exist or are not -// visible to you, the operation will fail and a 404 Not Found error will be -// returned. After this operation completes, the port connecting the router -// with the subnet is removed from the subnet for the network. -func RemoveInterface(c *gophercloud.ServiceClient, id string, opts InterfaceOpts) InterfaceResult { - var res InterfaceResult - - type request struct { - SubnetID string `json:"subnet_id,omitempty"` - PortID string `json:"port_id,omitempty"` - } - - body := request{SubnetID: opts.SubnetID, PortID: opts.PortID} - - _, res.Err = perigee.Request("PUT", removeInterfaceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &body, - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests_test.go deleted file mode 100644 index c34264daee..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests_test.go +++ /dev/null @@ -1,338 +0,0 @@ -package routers - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.AssertEquals(t, th.Endpoint()+"v2.0/routers", rootURL(fake.ServiceClient())) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "routers": [ - { - "status": "ACTIVE", - "external_gateway_info": null, - "name": "second_routers", - "admin_state_up": true, - "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", - "id": "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b" - }, - { - "status": "ACTIVE", - "external_gateway_info": { - "network_id": "3c5bcddd-6af9-4e6b-9c3e-c153e521cab8" - }, - "name": "router1", - "admin_state_up": true, - "tenant_id": "33a40233088643acb66ff6eb0ebea679", - "id": "a9254bdb-2613-4a13-ac4c-adc581fba50d" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractRouters(page) - if err != nil { - t.Errorf("Failed to extract routers: %v", err) - return false, err - } - - expected := []Router{ - Router{ - Status: "ACTIVE", - GatewayInfo: GatewayInfo{NetworkID: ""}, - AdminStateUp: true, - Name: "second_routers", - ID: "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b", - TenantID: "6b96ff0cb17a4b859e1e575d221683d3", - }, - Router{ - Status: "ACTIVE", - GatewayInfo: GatewayInfo{NetworkID: "3c5bcddd-6af9-4e6b-9c3e-c153e521cab8"}, - AdminStateUp: true, - Name: "router1", - ID: "a9254bdb-2613-4a13-ac4c-adc581fba50d", - TenantID: "33a40233088643acb66ff6eb0ebea679", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "router":{ - "name": "foo_router", - "admin_state_up": false, - "external_gateway_info":{ - "network_id":"8ca37218-28ff-41cb-9b10-039601ea7e6b" - } - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "router": { - "status": "ACTIVE", - "external_gateway_info": { - "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b" - }, - "name": "foo_router", - "admin_state_up": false, - "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", - "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e" - } -} - `) - }) - - asu := false - gwi := GatewayInfo{NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b"} - - options := CreateOpts{ - Name: "foo_router", - AdminStateUp: &asu, - GatewayInfo: &gwi, - } - r, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "foo_router", r.Name) - th.AssertEquals(t, false, r.AdminStateUp) - th.AssertDeepEquals(t, GatewayInfo{NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b"}, r.GatewayInfo) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers/a07eea83-7710-4860-931b-5fe220fae533", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "router": { - "status": "ACTIVE", - "external_gateway_info": { - "network_id": "85d76829-6415-48ff-9c63-5c5ca8c61ac6" - }, - "name": "router1", - "admin_state_up": true, - "tenant_id": "d6554fe62e2f41efbb6e026fad5c1542", - "id": "a07eea83-7710-4860-931b-5fe220fae533" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "a07eea83-7710-4860-931b-5fe220fae533").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.GatewayInfo, GatewayInfo{NetworkID: "85d76829-6415-48ff-9c63-5c5ca8c61ac6"}) - th.AssertEquals(t, n.Name, "router1") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.TenantID, "d6554fe62e2f41efbb6e026fad5c1542") - th.AssertEquals(t, n.ID, "a07eea83-7710-4860-931b-5fe220fae533") -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "router": { - "name": "new_name", - "external_gateway_info": { - "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b" - } - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "router": { - "status": "ACTIVE", - "external_gateway_info": { - "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b" - }, - "name": "new_name", - "admin_state_up": true, - "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", - "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e" - } -} - `) - }) - - gwi := GatewayInfo{NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b"} - options := UpdateOpts{Name: "new_name", GatewayInfo: &gwi} - - n, err := Update(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Name, "new_name") - th.AssertDeepEquals(t, n.GatewayInfo, GatewayInfo{NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b"}) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") - th.AssertNoErr(t, res.Err) -} - -func TestAddInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_router_interface", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "subnet_id": "a2f1f29d-571b-4533-907f-5803ab96ead1" -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "subnet_id": "0d32a837-8069-4ec3-84c4-3eef3e10b188", - "tenant_id": "017d8de156df4177889f31a9bd6edc00", - "port_id": "3f990102-4485-4df1-97a0-2c35bdb85b31", - "id": "9a83fa11-8da5-436e-9afe-3d3ac5ce7770" -} -`) - }) - - opts := InterfaceOpts{SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1"} - res, err := AddInterface(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "0d32a837-8069-4ec3-84c4-3eef3e10b188", res.SubnetID) - th.AssertEquals(t, "017d8de156df4177889f31a9bd6edc00", res.TenantID) - th.AssertEquals(t, "3f990102-4485-4df1-97a0-2c35bdb85b31", res.PortID) - th.AssertEquals(t, "9a83fa11-8da5-436e-9afe-3d3ac5ce7770", res.ID) -} - -func TestAddInterfaceRequiredOpts(t *testing.T) { - _, err := AddInterface(fake.ServiceClient(), "foo", InterfaceOpts{}).Extract() - if err == nil { - t.Fatalf("Expected error, got none") - } - _, err = AddInterface(fake.ServiceClient(), "foo", InterfaceOpts{SubnetID: "bar", PortID: "baz"}).Extract() - if err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestRemoveInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_router_interface", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "subnet_id": "a2f1f29d-571b-4533-907f-5803ab96ead1" -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "subnet_id": "0d32a837-8069-4ec3-84c4-3eef3e10b188", - "tenant_id": "017d8de156df4177889f31a9bd6edc00", - "port_id": "3f990102-4485-4df1-97a0-2c35bdb85b31", - "id": "9a83fa11-8da5-436e-9afe-3d3ac5ce7770" -} -`) - }) - - opts := InterfaceOpts{SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1"} - res, err := RemoveInterface(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "0d32a837-8069-4ec3-84c4-3eef3e10b188", res.SubnetID) - th.AssertEquals(t, "017d8de156df4177889f31a9bd6edc00", res.TenantID) - th.AssertEquals(t, "3f990102-4485-4df1-97a0-2c35bdb85b31", res.PortID) - th.AssertEquals(t, "9a83fa11-8da5-436e-9afe-3d3ac5ce7770", res.ID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go deleted file mode 100644 index bdad4cb2fd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go +++ /dev/null @@ -1,161 +0,0 @@ -package routers - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// GatewayInfo represents the information of an external gateway for any -// particular network router. -type GatewayInfo struct { - NetworkID string `json:"network_id" mapstructure:"network_id"` -} - -// Router represents a Neutron router. A router is a logical entity that -// forwards packets across internal subnets and NATs (network address -// translation) them on external networks through an appropriate gateway. -// -// A router has an interface for each subnet with which it is associated. By -// default, the IP address of such interface is the subnet's gateway IP. Also, -// whenever a router is associated with a subnet, a port for that router -// interface is added to the subnet's network. -type Router struct { - // Indicates whether or not a router is currently operational. - Status string `json:"status" mapstructure:"status"` - - // Information on external gateway for the router. - GatewayInfo GatewayInfo `json:"external_gateway_info" mapstructure:"external_gateway_info"` - - // Administrative state of the router. - AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` - - // Human readable name for the router. Does not have to be unique. - Name string `json:"name" mapstructure:"name"` - - // Unique identifier for the router. - ID string `json:"id" mapstructure:"id"` - - // Owner of the router. Only admin users can specify a tenant identifier - // other than its own. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` -} - -// RouterPage is the page returned by a pager when traversing over a -// collection of routers. -type RouterPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of routers has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (p RouterPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"routers_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a RouterPage struct is empty. -func (p RouterPage) IsEmpty() (bool, error) { - is, err := ExtractRouters(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractRouters accepts a Page struct, specifically a RouterPage struct, -// and extracts the elements into a slice of Router structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractRouters(page pagination.Page) ([]Router, error) { - var resp struct { - Routers []Router `mapstructure:"routers" json:"routers"` - } - - err := mapstructure.Decode(page.(RouterPage).Body, &resp) - - return resp.Routers, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a router. -func (r commonResult) Extract() (*Router, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Router *Router `json:"router"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Router, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// InterfaceInfo represents information about a particular router interface. As -// mentioned above, in order for a router to forward to a subnet, it needs an -// interface. -type InterfaceInfo struct { - // The ID of the subnet which this interface is associated with. - SubnetID string `json:"subnet_id" mapstructure:"subnet_id"` - - // The ID of the port that is a part of the subnet. - PortID string `json:"port_id" mapstructure:"port_id"` - - // The UUID of the interface. - ID string `json:"id" mapstructure:"id"` - - // Owner of the interface. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` -} - -// InterfaceResult represents the result of interface operations, such as -// AddInterface() and RemoveInterface(). -type InterfaceResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts an information struct. -func (r InterfaceResult) Extract() (*InterfaceInfo, error) { - if r.Err != nil { - return nil, r.Err - } - - var res *InterfaceInfo - err := mapstructure.Decode(r.Body, &res) - - return res, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/urls.go deleted file mode 100644 index bc22c2a8a8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package routers - -import "github.com/rackspace/gophercloud" - -const resourcePath = "routers" - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(resourcePath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id) -} - -func addInterfaceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id, "add_router_interface") -} - -func removeInterfaceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id, "remove_router_interface") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/doc.go deleted file mode 100644 index bc1fc282f4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package lbaas provides information and interaction with the Load Balancer -// as a Service extension for the OpenStack Networking service. -package lbaas diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/requests.go deleted file mode 100644 index 58ec580dbc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/requests.go +++ /dev/null @@ -1,139 +0,0 @@ -package members - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Status string `q:"status"` - Weight int `q:"weight"` - AdminStateUp *bool `q:"admin_state_up"` - TenantID string `q:"tenant_id"` - PoolID string `q:"pool_id"` - Address string `q:"address"` - ProtocolPort int `q:"protocol_port"` - ID string `q:"id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// pools. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those pools that are owned by the -// tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return MemberPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOpts contains all the values needed to create a new pool member. -type CreateOpts struct { - // Only required if the caller has an admin role and wants to create a pool - // for another tenant. - TenantID string - - // Required. The IP address of the member. - Address string - - // Required. The port on which the application is hosted. - ProtocolPort int - - // Required. The pool to which this member will belong. - PoolID string -} - -// Create accepts a CreateOpts struct and uses the values to create a new -// load balancer pool member. -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - type member struct { - TenantID string `json:"tenant_id"` - ProtocolPort int `json:"protocol_port"` - Address string `json:"address"` - PoolID string `json:"pool_id"` - } - type request struct { - Member member `json:"member"` - } - - reqBody := request{Member: member{ - Address: opts.Address, - TenantID: opts.TenantID, - ProtocolPort: opts.ProtocolPort, - PoolID: opts.PoolID, - }} - - var res CreateResult - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - return res -} - -// Get retrieves a particular pool member based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// UpdateOpts contains the values used when updating a pool member. -type UpdateOpts struct { - // The administrative state of the member, which is up (true) or down (false). - AdminStateUp bool -} - -// Update allows members to be updated. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { - type member struct { - AdminStateUp bool `json:"admin_state_up"` - } - type request struct { - Member member `json:"member"` - } - - reqBody := request{Member: member{AdminStateUp: opts.AdminStateUp}} - - // Send request to API - var res UpdateResult - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Delete will permanently delete a particular member based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/requests_test.go deleted file mode 100644 index dc1ece321f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/requests_test.go +++ /dev/null @@ -1,243 +0,0 @@ -package members - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.AssertEquals(t, th.Endpoint()+"v2.0/lb/members", rootURL(fake.ServiceClient())) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/members", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "members":[ - { - "status":"ACTIVE", - "weight":1, - "admin_state_up":true, - "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", - "pool_id":"72741b06-df4d-4715-b142-276b6bce75ab", - "address":"10.0.0.4", - "protocol_port":80, - "id":"701b531b-111a-4f21-ad85-4795b7b12af6" - }, - { - "status":"ACTIVE", - "weight":1, - "admin_state_up":true, - "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", - "pool_id":"72741b06-df4d-4715-b142-276b6bce75ab", - "address":"10.0.0.3", - "protocol_port":80, - "id":"beb53b4d-230b-4abd-8118-575b8fa006ef" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractMembers(page) - if err != nil { - t.Errorf("Failed to extract members: %v", err) - return false, err - } - - expected := []Member{ - Member{ - Status: "ACTIVE", - Weight: 1, - AdminStateUp: true, - TenantID: "83657cfcdfe44cd5920adaf26c48ceea", - PoolID: "72741b06-df4d-4715-b142-276b6bce75ab", - Address: "10.0.0.4", - ProtocolPort: 80, - ID: "701b531b-111a-4f21-ad85-4795b7b12af6", - }, - Member{ - Status: "ACTIVE", - Weight: 1, - AdminStateUp: true, - TenantID: "83657cfcdfe44cd5920adaf26c48ceea", - PoolID: "72741b06-df4d-4715-b142-276b6bce75ab", - Address: "10.0.0.3", - ProtocolPort: 80, - ID: "beb53b4d-230b-4abd-8118-575b8fa006ef", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/members", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "member": { - "tenant_id": "453105b9-1754-413f-aab1-55f1af620750", - "pool_id": "foo", - "address": "192.0.2.14", - "protocol_port":8080 - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "member": { - "id": "975592ca-e308-48ad-8298-731935ee9f45", - "address": "192.0.2.14", - "protocol_port": 8080, - "tenant_id": "453105b9-1754-413f-aab1-55f1af620750", - "admin_state_up":true, - "weight": 1, - "status": "DOWN" - } -} - `) - }) - - options := CreateOpts{ - TenantID: "453105b9-1754-413f-aab1-55f1af620750", - Address: "192.0.2.14", - ProtocolPort: 8080, - PoolID: "foo", - } - _, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/members/975592ca-e308-48ad-8298-731935ee9f45", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "member":{ - "id":"975592ca-e308-48ad-8298-731935ee9f45", - "address":"192.0.2.14", - "protocol_port":8080, - "tenant_id":"453105b9-1754-413f-aab1-55f1af620750", - "admin_state_up":true, - "weight":1, - "status":"DOWN" - } -} - `) - }) - - m, err := Get(fake.ServiceClient(), "975592ca-e308-48ad-8298-731935ee9f45").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "975592ca-e308-48ad-8298-731935ee9f45", m.ID) - th.AssertEquals(t, "192.0.2.14", m.Address) - th.AssertEquals(t, 8080, m.ProtocolPort) - th.AssertEquals(t, "453105b9-1754-413f-aab1-55f1af620750", m.TenantID) - th.AssertEquals(t, true, m.AdminStateUp) - th.AssertEquals(t, 1, m.Weight) - th.AssertEquals(t, "DOWN", m.Status) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/members/332abe93-f488-41ba-870b-2ac66be7f853", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "member":{ - "admin_state_up":false - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "member":{ - "status":"PENDING_UPDATE", - "protocol_port":8080, - "weight":1, - "admin_state_up":false, - "tenant_id":"4fd44f30292945e481c7b8a0c8908869", - "pool_id":"7803631d-f181-4500-b3a2-1b68ba2a75fd", - "address":"10.0.0.5", - "status_description":null, - "id":"48a471ea-64f1-4eb6-9be7-dae6bbe40a0f" - } -} - `) - }) - - options := UpdateOpts{AdminStateUp: false} - - _, err := Update(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", options).Extract() - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/members/332abe93-f488-41ba-870b-2ac66be7f853", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/results.go deleted file mode 100644 index 3cad339b77..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/results.go +++ /dev/null @@ -1,122 +0,0 @@ -package members - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// Member represents the application running on a backend server. -type Member struct { - // The status of the member. Indicates whether the member is operational. - Status string - - // Weight of member. - Weight int - - // The administrative state of the member, which is up (true) or down (false). - AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` - - // Owner of the member. Only an administrative user can specify a tenant ID - // other than its own. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` - - // The pool to which the member belongs. - PoolID string `json:"pool_id" mapstructure:"pool_id"` - - // The IP address of the member. - Address string - - // The port on which the application is hosted. - ProtocolPort int `json:"protocol_port" mapstructure:"protocol_port"` - - // The unique ID for the member. - ID string -} - -// MemberPage is the page returned by a pager when traversing over a -// collection of pool members. -type MemberPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of members has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (p MemberPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"members_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a MemberPage struct is empty. -func (p MemberPage) IsEmpty() (bool, error) { - is, err := ExtractMembers(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractMembers accepts a Page struct, specifically a MemberPage struct, -// and extracts the elements into a slice of Member structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractMembers(page pagination.Page) ([]Member, error) { - var resp struct { - Members []Member `mapstructure:"members" json:"members"` - } - - err := mapstructure.Decode(page.(MemberPage).Body, &resp) - if err != nil { - return nil, err - } - - return resp.Members, nil -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a router. -func (r commonResult) Extract() (*Member, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Member *Member `json:"member"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Member, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/urls.go deleted file mode 100644 index 94b57e4c58..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/members/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package members - -import "github.com/rackspace/gophercloud" - -const ( - rootPath = "lb" - resourcePath = "members" -) - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath, resourcePath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, resourcePath, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/requests.go deleted file mode 100644 index e2b590ecb5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/requests.go +++ /dev/null @@ -1,282 +0,0 @@ -package monitors - -import ( - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - TenantID string `q:"tenant_id"` - Type string `q:"type"` - Delay int `q:"delay"` - Timeout int `q:"timeout"` - MaxRetries int `q:"max_retries"` - HTTPMethod string `q:"http_method"` - URLPath string `q:"url_path"` - ExpectedCodes string `q:"expected_codes"` - AdminStateUp *bool `q:"admin_state_up"` - Status string `q:"status"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// routers. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those routers that are owned by the -// tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return MonitorPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Constants that represent approved monitoring types. -const ( - TypePING = "PING" - TypeTCP = "TCP" - TypeHTTP = "HTTP" - TypeHTTPS = "HTTPS" -) - -var ( - errValidTypeRequired = fmt.Errorf("A valid Type is required. Supported values are PING, TCP, HTTP and HTTPS") - errDelayRequired = fmt.Errorf("Delay is required") - errTimeoutRequired = fmt.Errorf("Timeout is required") - errMaxRetriesRequired = fmt.Errorf("MaxRetries is required") - errURLPathRequired = fmt.Errorf("URL path is required") - errExpectedCodesRequired = fmt.Errorf("ExpectedCodes is required") - errDelayMustGETimeout = fmt.Errorf("Delay must be greater than or equal to timeout") -) - -// CreateOpts contains all the values needed to create a new health monitor. -type CreateOpts struct { - // Required for admins. Indicates the owner of the VIP. - TenantID string - - // Required. The type of probe, which is PING, TCP, HTTP, or HTTPS, that is - // sent by the load balancer to verify the member state. - Type string - - // Required. The time, in seconds, between sending probes to members. - Delay int - - // Required. Maximum number of seconds for a monitor to wait for a ping reply - // before it times out. The value must be less than the delay value. - Timeout int - - // Required. Number of permissible ping failures before changing the member's - // status to INACTIVE. Must be a number between 1 and 10. - MaxRetries int - - // Required for HTTP(S) types. URI path that will be accessed if monitor type - // is HTTP or HTTPS. - URLPath string - - // Required for HTTP(S) types. The HTTP method used for requests by the - // monitor. If this attribute is not specified, it defaults to "GET". - HTTPMethod string - - // Required for HTTP(S) types. Expected HTTP codes for a passing HTTP(S) - // monitor. You can either specify a single status like "200", or a range - // like "200-202". - ExpectedCodes string - - AdminStateUp *bool -} - -// Create is an operation which provisions a new health monitor. There are -// different types of monitor you can provision: PING, TCP or HTTP(S). Below -// are examples of how to create each one. -// -// Here is an example config struct to use when creating a PING or TCP monitor: -// -// CreateOpts{Type: TypePING, Delay: 20, Timeout: 10, MaxRetries: 3} -// CreateOpts{Type: TypeTCP, Delay: 20, Timeout: 10, MaxRetries: 3} -// -// Here is an example config struct to use when creating a HTTP(S) monitor: -// -// CreateOpts{Type: TypeHTTP, Delay: 20, Timeout: 10, MaxRetries: 3, -// HttpMethod: "HEAD", ExpectedCodes: "200"} -// -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - var res CreateResult - - // Validate inputs - allowed := map[string]bool{TypeHTTP: true, TypeHTTPS: true, TypeTCP: true, TypePING: true} - if opts.Type == "" || allowed[opts.Type] == false { - res.Err = errValidTypeRequired - } - if opts.Delay == 0 { - res.Err = errDelayRequired - } - if opts.Timeout == 0 { - res.Err = errTimeoutRequired - } - if opts.MaxRetries == 0 { - res.Err = errMaxRetriesRequired - } - if opts.Type == TypeHTTP || opts.Type == TypeHTTPS { - if opts.URLPath == "" { - res.Err = errURLPathRequired - } - if opts.ExpectedCodes == "" { - res.Err = errExpectedCodesRequired - } - } - if opts.Delay < opts.Timeout { - res.Err = errDelayMustGETimeout - } - if res.Err != nil { - return res - } - - type monitor struct { - Type string `json:"type"` - Delay int `json:"delay"` - Timeout int `json:"timeout"` - MaxRetries int `json:"max_retries"` - TenantID *string `json:"tenant_id,omitempty"` - URLPath *string `json:"url_path,omitempty"` - ExpectedCodes *string `json:"expected_codes,omitempty"` - HTTPMethod *string `json:"http_method,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - } - - type request struct { - Monitor monitor `json:"health_monitor"` - } - - reqBody := request{Monitor: monitor{ - Type: opts.Type, - Delay: opts.Delay, - Timeout: opts.Timeout, - MaxRetries: opts.MaxRetries, - TenantID: gophercloud.MaybeString(opts.TenantID), - URLPath: gophercloud.MaybeString(opts.URLPath), - ExpectedCodes: gophercloud.MaybeString(opts.ExpectedCodes), - HTTPMethod: gophercloud.MaybeString(opts.HTTPMethod), - AdminStateUp: opts.AdminStateUp, - }} - - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// Get retrieves a particular health monitor based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// UpdateOpts contains all the values needed to update an existing virtual IP. -// Attributes not listed here but appear in CreateOpts are immutable and cannot -// be updated. -type UpdateOpts struct { - // Required. The time, in seconds, between sending probes to members. - Delay int - - // Required. Maximum number of seconds for a monitor to wait for a ping reply - // before it times out. The value must be less than the delay value. - Timeout int - - // Required. Number of permissible ping failures before changing the member's - // status to INACTIVE. Must be a number between 1 and 10. - MaxRetries int - - // Required for HTTP(S) types. URI path that will be accessed if monitor type - // is HTTP or HTTPS. - URLPath string - - // Required for HTTP(S) types. The HTTP method used for requests by the - // monitor. If this attribute is not specified, it defaults to "GET". - HTTPMethod string - - // Required for HTTP(S) types. Expected HTTP codes for a passing HTTP(S) - // monitor. You can either specify a single status like "200", or a range - // like "200-202". - ExpectedCodes string - - AdminStateUp *bool -} - -// Update is an operation which modifies the attributes of the specified monitor. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { - var res UpdateResult - - if opts.Delay > 0 && opts.Timeout > 0 && opts.Delay < opts.Timeout { - res.Err = errDelayMustGETimeout - } - - type monitor struct { - Delay int `json:"delay"` - Timeout int `json:"timeout"` - MaxRetries int `json:"max_retries"` - URLPath *string `json:"url_path,omitempty"` - ExpectedCodes *string `json:"expected_codes,omitempty"` - HTTPMethod *string `json:"http_method,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - } - - type request struct { - Monitor monitor `json:"health_monitor"` - } - - reqBody := request{Monitor: monitor{ - Delay: opts.Delay, - Timeout: opts.Timeout, - MaxRetries: opts.MaxRetries, - URLPath: gophercloud.MaybeString(opts.URLPath), - ExpectedCodes: gophercloud.MaybeString(opts.ExpectedCodes), - HTTPMethod: gophercloud.MaybeString(opts.HTTPMethod), - AdminStateUp: opts.AdminStateUp, - }} - - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 202}, - }) - - return res -} - -// Delete will permanently delete a particular monitor based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go deleted file mode 100644 index 79a99bf8a2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go +++ /dev/null @@ -1,312 +0,0 @@ -package monitors - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.AssertEquals(t, th.Endpoint()+"v2.0/lb/health_monitors", rootURL(fake.ServiceClient())) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/health_monitors", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "health_monitors":[ - { - "admin_state_up":true, - "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", - "delay":10, - "max_retries":1, - "timeout":1, - "type":"PING", - "id":"466c8345-28d8-4f84-a246-e04380b0461d" - }, - { - "admin_state_up":true, - "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", - "delay":5, - "expected_codes":"200", - "max_retries":2, - "http_method":"GET", - "timeout":2, - "url_path":"/", - "type":"HTTP", - "id":"5d4b5228-33b0-4e60-b225-9b727c1a20e7" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractMonitors(page) - if err != nil { - t.Errorf("Failed to extract monitors: %v", err) - return false, err - } - - expected := []Monitor{ - Monitor{ - AdminStateUp: true, - TenantID: "83657cfcdfe44cd5920adaf26c48ceea", - Delay: 10, - MaxRetries: 1, - Timeout: 1, - Type: "PING", - ID: "466c8345-28d8-4f84-a246-e04380b0461d", - }, - Monitor{ - AdminStateUp: true, - TenantID: "83657cfcdfe44cd5920adaf26c48ceea", - Delay: 5, - ExpectedCodes: "200", - MaxRetries: 2, - Timeout: 2, - URLPath: "/", - Type: "HTTP", - HTTPMethod: "GET", - ID: "5d4b5228-33b0-4e60-b225-9b727c1a20e7", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestDelayMustBeGreaterOrEqualThanTimeout(t *testing.T) { - _, err := Create(fake.ServiceClient(), CreateOpts{ - Type: "HTTP", - Delay: 1, - Timeout: 10, - MaxRetries: 5, - URLPath: "/check", - ExpectedCodes: "200-299", - }).Extract() - - if err == nil { - t.Fatalf("Expected error, got none") - } - - _, err = Update(fake.ServiceClient(), "453105b9-1754-413f-aab1-55f1af620750", UpdateOpts{ - Delay: 1, - Timeout: 10, - }).Extract() - - if err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/health_monitors", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "health_monitor":{ - "type":"HTTP", - "tenant_id":"453105b9-1754-413f-aab1-55f1af620750", - "delay":20, - "timeout":10, - "max_retries":5, - "url_path":"/check", - "expected_codes":"200-299" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "health_monitor":{ - "id":"f3eeab00-8367-4524-b662-55e64d4cacb5", - "tenant_id":"453105b9-1754-413f-aab1-55f1af620750", - "type":"HTTP", - "delay":20, - "timeout":10, - "max_retries":5, - "http_method":"GET", - "url_path":"/check", - "expected_codes":"200-299", - "admin_state_up":true, - "status":"ACTIVE" - } -} - `) - }) - - _, err := Create(fake.ServiceClient(), CreateOpts{ - Type: "HTTP", - TenantID: "453105b9-1754-413f-aab1-55f1af620750", - Delay: 20, - Timeout: 10, - MaxRetries: 5, - URLPath: "/check", - ExpectedCodes: "200-299", - }).Extract() - - th.AssertNoErr(t, err) -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Type: TypeHTTP}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/health_monitors/f3eeab00-8367-4524-b662-55e64d4cacb5", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "health_monitor":{ - "id":"f3eeab00-8367-4524-b662-55e64d4cacb5", - "tenant_id":"453105b9-1754-413f-aab1-55f1af620750", - "type":"HTTP", - "delay":20, - "timeout":10, - "max_retries":5, - "http_method":"GET", - "url_path":"/check", - "expected_codes":"200-299", - "admin_state_up":true, - "status":"ACTIVE" - } -} - `) - }) - - hm, err := Get(fake.ServiceClient(), "f3eeab00-8367-4524-b662-55e64d4cacb5").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "f3eeab00-8367-4524-b662-55e64d4cacb5", hm.ID) - th.AssertEquals(t, "453105b9-1754-413f-aab1-55f1af620750", hm.TenantID) - th.AssertEquals(t, "HTTP", hm.Type) - th.AssertEquals(t, 20, hm.Delay) - th.AssertEquals(t, 10, hm.Timeout) - th.AssertEquals(t, 5, hm.MaxRetries) - th.AssertEquals(t, "GET", hm.HTTPMethod) - th.AssertEquals(t, "/check", hm.URLPath) - th.AssertEquals(t, "200-299", hm.ExpectedCodes) - th.AssertEquals(t, true, hm.AdminStateUp) - th.AssertEquals(t, "ACTIVE", hm.Status) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/health_monitors/b05e44b5-81f9-4551-b474-711a722698f7", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "health_monitor":{ - "delay": 3, - "timeout": 20, - "max_retries": 10, - "url_path": "/another_check", - "expected_codes": "301" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, ` -{ - "health_monitor": { - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "delay": 3, - "max_retries": 10, - "http_method": "GET", - "timeout": 20, - "pools": [ - { - "status": "PENDING_CREATE", - "status_description": null, - "pool_id": "6e55751f-6ad4-4e53-b8d4-02e442cd21df" - } - ], - "type": "PING", - "id": "b05e44b5-81f9-4551-b474-711a722698f7" - } -} - `) - }) - - _, err := Update(fake.ServiceClient(), "b05e44b5-81f9-4551-b474-711a722698f7", UpdateOpts{ - Delay: 3, - Timeout: 20, - MaxRetries: 10, - URLPath: "/another_check", - ExpectedCodes: "301", - }).Extract() - - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/health_monitors/b05e44b5-81f9-4551-b474-711a722698f7", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "b05e44b5-81f9-4551-b474-711a722698f7") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/results.go deleted file mode 100644 index d595abd540..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/results.go +++ /dev/null @@ -1,147 +0,0 @@ -package monitors - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// Monitor represents a load balancer health monitor. A health monitor is used -// to determine whether or not back-end members of the VIP's pool are usable -// for processing a request. A pool can have several health monitors associated -// with it. There are different types of health monitors supported: -// -// PING: used to ping the members using ICMP. -// TCP: used to connect to the members using TCP. -// HTTP: used to send an HTTP request to the member. -// HTTPS: used to send a secure HTTP request to the member. -// -// When a pool has several monitors associated with it, each member of the pool -// is monitored by all these monitors. If any monitor declares the member as -// unhealthy, then the member status is changed to INACTIVE and the member -// won't participate in its pool's load balancing. In other words, ALL monitors -// must declare the member to be healthy for it to stay ACTIVE. -type Monitor struct { - // The unique ID for the VIP. - ID string - - // Owner of the VIP. Only an administrative user can specify a tenant ID - // other than its own. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` - - // The type of probe sent by the load balancer to verify the member state, - // which is PING, TCP, HTTP, or HTTPS. - Type string - - // The time, in seconds, between sending probes to members. - Delay int - - // The maximum number of seconds for a monitor to wait for a connection to be - // established before it times out. This value must be less than the delay value. - Timeout int - - // Number of allowed connection failures before changing the status of the - // member to INACTIVE. A valid value is from 1 to 10. - MaxRetries int `json:"max_retries" mapstructure:"max_retries"` - - // The HTTP method that the monitor uses for requests. - HTTPMethod string `json:"http_method" mapstructure:"http_method"` - - // The HTTP path of the request sent by the monitor to test the health of a - // member. Must be a string beginning with a forward slash (/). - URLPath string `json:"url_path" mapstructure:"url_path"` - - // Expected HTTP codes for a passing HTTP(S) monitor. - ExpectedCodes string `json:"expected_codes" mapstructure:"expected_codes"` - - // The administrative state of the health monitor, which is up (true) or down (false). - AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` - - // The status of the health monitor. Indicates whether the health monitor is - // operational. - Status string -} - -// MonitorPage is the page returned by a pager when traversing over a -// collection of health monitors. -type MonitorPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of monitors has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (p MonitorPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"health_monitors_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a PoolPage struct is empty. -func (p MonitorPage) IsEmpty() (bool, error) { - is, err := ExtractMonitors(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractMonitors accepts a Page struct, specifically a MonitorPage struct, -// and extracts the elements into a slice of Monitor structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractMonitors(page pagination.Page) ([]Monitor, error) { - var resp struct { - Monitors []Monitor `mapstructure:"health_monitors" json:"health_monitors"` - } - - err := mapstructure.Decode(page.(MonitorPage).Body, &resp) - - return resp.Monitors, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a monitor. -func (r commonResult) Extract() (*Monitor, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Monitor *Monitor `json:"health_monitor" mapstructure:"health_monitor"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Monitor, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/urls.go deleted file mode 100644 index 46e84bbf52..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package monitors - -import "github.com/rackspace/gophercloud" - -const ( - rootPath = "lb" - resourcePath = "health_monitors" -) - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath, resourcePath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, resourcePath, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests.go deleted file mode 100644 index ca8d33b8d5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests.go +++ /dev/null @@ -1,205 +0,0 @@ -package pools - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Status string `q:"status"` - LBMethod string `q:"lb_method"` - Protocol string `q:"protocol"` - SubnetID string `q:"subnet_id"` - TenantID string `q:"tenant_id"` - AdminStateUp *bool `q:"admin_state_up"` - Name string `q:"name"` - ID string `q:"id"` - VIPID string `q:"vip_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// pools. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those pools that are owned by the -// tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return PoolPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Supported attributes for create/update operations. -const ( - LBMethodRoundRobin = "ROUND_ROBIN" - LBMethodLeastConnections = "LEAST_CONNECTIONS" - - ProtocolTCP = "TCP" - ProtocolHTTP = "HTTP" - ProtocolHTTPS = "HTTPS" -) - -// CreateOpts contains all the values needed to create a new pool. -type CreateOpts struct { - // Only required if the caller has an admin role and wants to create a pool - // for another tenant. - TenantID string - - // Required. Name of the pool. - Name string - - // Required. The protocol used by the pool members, you can use either - // ProtocolTCP, ProtocolHTTP, or ProtocolHTTPS. - Protocol string - - // The network on which the members of the pool will be located. Only members - // that are on this network can be added to the pool. - SubnetID string - - // The algorithm used to distribute load between the members of the pool. The - // current specification supports LBMethodRoundRobin and - // LBMethodLeastConnections as valid values for this attribute. - LBMethod string -} - -// Create accepts a CreateOpts struct and uses the values to create a new -// load balancer pool. -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - type pool struct { - Name string `json:"name"` - TenantID string `json:"tenant_id,omitempty"` - Protocol string `json:"protocol"` - SubnetID string `json:"subnet_id"` - LBMethod string `json:"lb_method"` - } - type request struct { - Pool pool `json:"pool"` - } - - reqBody := request{Pool: pool{ - Name: opts.Name, - TenantID: opts.TenantID, - Protocol: opts.Protocol, - SubnetID: opts.SubnetID, - LBMethod: opts.LBMethod, - }} - - var res CreateResult - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - return res -} - -// Get retrieves a particular pool based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// UpdateOpts contains the values used when updating a pool. -type UpdateOpts struct { - // Required. Name of the pool. - Name string - - // The algorithm used to distribute load between the members of the pool. The - // current specification supports LBMethodRoundRobin and - // LBMethodLeastConnections as valid values for this attribute. - LBMethod string -} - -// Update allows pools to be updated. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { - type pool struct { - Name string `json:"name,"` - LBMethod string `json:"lb_method"` - } - type request struct { - Pool pool `json:"pool"` - } - - reqBody := request{Pool: pool{ - Name: opts.Name, - LBMethod: opts.LBMethod, - }} - - // Send request to API - var res UpdateResult - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Delete will permanently delete a particular pool based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} - -// AssociateMonitor will associate a health monitor with a particular pool. -// Once associated, the health monitor will start monitoring the members of the -// pool and will deactivate these members if they are deemed unhealthy. A -// member can be deactivated (status set to INACTIVE) if any of health monitors -// finds it unhealthy. -func AssociateMonitor(c *gophercloud.ServiceClient, poolID, monitorID string) AssociateResult { - type hm struct { - ID string `json:"id"` - } - type request struct { - Monitor hm `json:"health_monitor"` - } - - reqBody := request{hm{ID: monitorID}} - - var res AssociateResult - _, res.Err = perigee.Request("POST", associateURL(c, poolID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - return res -} - -// DisassociateMonitor will disassociate a health monitor with a particular -// pool. When dissociation is successful, the health monitor will no longer -// check for the health of the members of the pool. -func DisassociateMonitor(c *gophercloud.ServiceClient, poolID, monitorID string) AssociateResult { - var res AssociateResult - _, res.Err = perigee.Request("DELETE", disassociateURL(c, poolID, monitorID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go deleted file mode 100644 index 6da29a6b8e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go +++ /dev/null @@ -1,317 +0,0 @@ -package pools - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.AssertEquals(t, th.Endpoint()+"v2.0/lb/pools", rootURL(fake.ServiceClient())) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "pools":[ - { - "status":"ACTIVE", - "lb_method":"ROUND_ROBIN", - "protocol":"HTTP", - "description":"", - "health_monitors":[ - "466c8345-28d8-4f84-a246-e04380b0461d", - "5d4b5228-33b0-4e60-b225-9b727c1a20e7" - ], - "members":[ - "701b531b-111a-4f21-ad85-4795b7b12af6", - "beb53b4d-230b-4abd-8118-575b8fa006ef" - ], - "status_description": null, - "id":"72741b06-df4d-4715-b142-276b6bce75ab", - "vip_id":"4ec89087-d057-4e2c-911f-60a3b47ee304", - "name":"app_pool", - "admin_state_up":true, - "subnet_id":"8032909d-47a1-4715-90af-5153ffe39861", - "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", - "health_monitors_status": [], - "provider": "haproxy" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractPools(page) - if err != nil { - t.Errorf("Failed to extract pools: %v", err) - return false, err - } - - expected := []Pool{ - Pool{ - Status: "ACTIVE", - LBMethod: "ROUND_ROBIN", - Protocol: "HTTP", - Description: "", - MonitorIDs: []string{ - "466c8345-28d8-4f84-a246-e04380b0461d", - "5d4b5228-33b0-4e60-b225-9b727c1a20e7", - }, - SubnetID: "8032909d-47a1-4715-90af-5153ffe39861", - TenantID: "83657cfcdfe44cd5920adaf26c48ceea", - AdminStateUp: true, - Name: "app_pool", - MemberIDs: []string{ - "701b531b-111a-4f21-ad85-4795b7b12af6", - "beb53b4d-230b-4abd-8118-575b8fa006ef", - }, - ID: "72741b06-df4d-4715-b142-276b6bce75ab", - VIPID: "4ec89087-d057-4e2c-911f-60a3b47ee304", - Provider: "haproxy", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "pool": { - "lb_method": "ROUND_ROBIN", - "protocol": "HTTP", - "name": "Example pool", - "subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", - "tenant_id": "2ffc6e22aae24e4795f87155d24c896f" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "pool": { - "status": "PENDING_CREATE", - "lb_method": "ROUND_ROBIN", - "protocol": "HTTP", - "description": "", - "health_monitors": [], - "members": [], - "status_description": null, - "id": "69055154-f603-4a28-8951-7cc2d9e54a9a", - "vip_id": null, - "name": "Example pool", - "admin_state_up": true, - "subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", - "tenant_id": "2ffc6e22aae24e4795f87155d24c896f", - "health_monitors_status": [] - } -} - `) - }) - - options := CreateOpts{ - LBMethod: LBMethodRoundRobin, - Protocol: "HTTP", - Name: "Example pool", - SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9", - TenantID: "2ffc6e22aae24e4795f87155d24c896f", - } - p, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "PENDING_CREATE", p.Status) - th.AssertEquals(t, "ROUND_ROBIN", p.LBMethod) - th.AssertEquals(t, "HTTP", p.Protocol) - th.AssertEquals(t, "", p.Description) - th.AssertDeepEquals(t, []string{}, p.MonitorIDs) - th.AssertDeepEquals(t, []string{}, p.MemberIDs) - th.AssertEquals(t, "69055154-f603-4a28-8951-7cc2d9e54a9a", p.ID) - th.AssertEquals(t, "Example pool", p.Name) - th.AssertEquals(t, "1981f108-3c48-48d2-b908-30f7d28532c9", p.SubnetID) - th.AssertEquals(t, "2ffc6e22aae24e4795f87155d24c896f", p.TenantID) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools/332abe93-f488-41ba-870b-2ac66be7f853", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "pool":{ - "id":"332abe93-f488-41ba-870b-2ac66be7f853", - "tenant_id":"19eaa775-cf5d-49bc-902e-2f85f668d995", - "name":"Example pool", - "description":"", - "protocol":"tcp", - "lb_algorithm":"ROUND_ROBIN", - "session_persistence":{ - }, - "healthmonitor_id":null, - "members":[ - ], - "admin_state_up":true, - "status":"ACTIVE" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.ID, "332abe93-f488-41ba-870b-2ac66be7f853") -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools/332abe93-f488-41ba-870b-2ac66be7f853", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "pool":{ - "name":"SuperPool", - "lb_method": "LEAST_CONNECTIONS" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "pool":{ - "status":"PENDING_UPDATE", - "lb_method":"LEAST_CONNECTIONS", - "protocol":"TCP", - "description":"", - "health_monitors":[ - - ], - "subnet_id":"8032909d-47a1-4715-90af-5153ffe39861", - "tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", - "admin_state_up":true, - "name":"SuperPool", - "members":[ - - ], - "id":"61b1f87a-7a21-4ad3-9dda-7f81d249944f", - "vip_id":null - } -} - `) - }) - - options := UpdateOpts{Name: "SuperPool", LBMethod: LBMethodLeastConnections} - - n, err := Update(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "SuperPool", n.Name) - th.AssertDeepEquals(t, "LEAST_CONNECTIONS", n.LBMethod) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools/332abe93-f488-41ba-870b-2ac66be7f853", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853") - th.AssertNoErr(t, res.Err) -} - -func TestAssociateHealthMonitor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools/332abe93-f488-41ba-870b-2ac66be7f853/health_monitors", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "health_monitor":{ - "id":"b624decf-d5d3-4c66-9a3d-f047e7786181" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - }) - - _, err := AssociateMonitor(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", "b624decf-d5d3-4c66-9a3d-f047e7786181").Extract() - th.AssertNoErr(t, err) -} - -func TestDisassociateHealthMonitor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/pools/332abe93-f488-41ba-870b-2ac66be7f853/health_monitors/b624decf-d5d3-4c66-9a3d-f047e7786181", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := DisassociateMonitor(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", "b624decf-d5d3-4c66-9a3d-f047e7786181") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/results.go deleted file mode 100644 index 07ec85eda4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/results.go +++ /dev/null @@ -1,146 +0,0 @@ -package pools - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// Pool represents a logical set of devices, such as web servers, that you -// group together to receive and process traffic. The load balancing function -// chooses a member of the pool according to the configured load balancing -// method to handle the new requests or connections received on the VIP address. -// There is only one pool per virtual IP. -type Pool struct { - // The status of the pool. Indicates whether the pool is operational. - Status string - - // The load-balancer algorithm, which is round-robin, least-connections, and - // so on. This value, which must be supported, is dependent on the provider. - // Round-robin must be supported. - LBMethod string `json:"lb_method" mapstructure:"lb_method"` - - // The protocol of the pool, which is TCP, HTTP, or HTTPS. - Protocol string - - // Description for the pool. - Description string - - // The IDs of associated monitors which check the health of the pool members. - MonitorIDs []string `json:"health_monitors" mapstructure:"health_monitors"` - - // The network on which the members of the pool will be located. Only members - // that are on this network can be added to the pool. - SubnetID string `json:"subnet_id" mapstructure:"subnet_id"` - - // Owner of the pool. Only an administrative user can specify a tenant ID - // other than its own. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` - - // The administrative state of the pool, which is up (true) or down (false). - AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` - - // Pool name. Does not have to be unique. - Name string - - // List of member IDs that belong to the pool. - MemberIDs []string `json:"members" mapstructure:"members"` - - // The unique ID for the pool. - ID string - - // The ID of the virtual IP associated with this pool - VIPID string `json:"vip_id" mapstructure:"vip_id"` - - // The provider - Provider string -} - -// PoolPage is the page returned by a pager when traversing over a -// collection of pools. -type PoolPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of pools has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (p PoolPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"pools_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a PoolPage struct is empty. -func (p PoolPage) IsEmpty() (bool, error) { - is, err := ExtractPools(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractPools accepts a Page struct, specifically a RouterPage struct, -// and extracts the elements into a slice of Router structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractPools(page pagination.Page) ([]Pool, error) { - var resp struct { - Pools []Pool `mapstructure:"pools" json:"pools"` - } - - err := mapstructure.Decode(page.(PoolPage).Body, &resp) - - return resp.Pools, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a router. -func (r commonResult) Extract() (*Pool, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Pool *Pool `json:"pool"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Pool, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// AssociateResult represents the result of an association operation. -type AssociateResult struct { - commonResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/urls.go deleted file mode 100644 index 6cd15b0026..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package pools - -import "github.com/rackspace/gophercloud" - -const ( - rootPath = "lb" - resourcePath = "pools" - monitorPath = "health_monitors" -) - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath, resourcePath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, resourcePath, id) -} - -func associateURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, resourcePath, id, monitorPath) -} - -func disassociateURL(c *gophercloud.ServiceClient, poolID, monitorID string) string { - return c.ServiceURL(rootPath, resourcePath, poolID, monitorPath, monitorID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/requests.go deleted file mode 100644 index ec929d6397..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/requests.go +++ /dev/null @@ -1,273 +0,0 @@ -package vips - -import ( - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// AdminState gives users a solid type to work with for create and update -// operations. It is recommended that users use the `Up` and `Down` enums. -type AdminState *bool - -// Convenience vars for AdminStateUp values. -var ( - iTrue = true - iFalse = false - - Up AdminState = &iTrue - Down AdminState = &iFalse -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - AdminStateUp *bool `q:"admin_state_up"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - SubnetID string `q:"subnet_id"` - Address string `q:"address"` - PortID string `q:"port_id"` - Protocol string `q:"protocol"` - ProtocolPort int `q:"protocol_port"` - ConnectionLimit int `q:"connection_limit"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// routers. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those routers that are owned by the -// tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return VIPPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -var ( - errNameRequired = fmt.Errorf("Name is required") - errSubnetIDRequried = fmt.Errorf("SubnetID is required") - errProtocolRequired = fmt.Errorf("Protocol is required") - errProtocolPortRequired = fmt.Errorf("Protocol port is required") - errPoolIDRequired = fmt.Errorf("PoolID is required") -) - -// CreateOpts contains all the values needed to create a new virtual IP. -type CreateOpts struct { - // Required. Human-readable name for the VIP. Does not have to be unique. - Name string - - // Required. The network on which to allocate the VIP's address. A tenant can - // only create VIPs on networks authorized by policy (e.g. networks that - // belong to them or networks that are shared). - SubnetID string - - // Required. The protocol - can either be TCP, HTTP or HTTPS. - Protocol string - - // Required. The port on which to listen for client traffic. - ProtocolPort int - - // Required. The ID of the pool with which the VIP is associated. - PoolID string - - // Required for admins. Indicates the owner of the VIP. - TenantID string - - // Optional. The IP address of the VIP. - Address string - - // Optional. Human-readable description for the VIP. - Description string - - // Optional. Omit this field to prevent session persistence. - Persistence *SessionPersistence - - // Optional. The maximum number of connections allowed for the VIP. - ConnLimit *int - - // Optional. The administrative state of the VIP. A valid value is true (UP) - // or false (DOWN). - AdminStateUp *bool -} - -// Create is an operation which provisions a new virtual IP based on the -// configuration defined in the CreateOpts struct. Once the request is -// validated and progress has started on the provisioning process, a -// CreateResult will be returned. -// -// Please note that the PoolID should refer to a pool that is not already -// associated with another vip. If the pool is already used by another vip, -// then the operation will fail with a 409 Conflict error will be returned. -// -// Users with an admin role can create VIPs on behalf of other tenants by -// specifying a TenantID attribute different than their own. -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - var res CreateResult - - // Validate required opts - if opts.Name == "" { - res.Err = errNameRequired - return res - } - if opts.SubnetID == "" { - res.Err = errSubnetIDRequried - return res - } - if opts.Protocol == "" { - res.Err = errProtocolRequired - return res - } - if opts.ProtocolPort == 0 { - res.Err = errProtocolPortRequired - return res - } - if opts.PoolID == "" { - res.Err = errPoolIDRequired - return res - } - - type vip struct { - Name string `json:"name"` - SubnetID string `json:"subnet_id"` - Protocol string `json:"protocol"` - ProtocolPort int `json:"protocol_port"` - PoolID string `json:"pool_id"` - Description *string `json:"description,omitempty"` - TenantID *string `json:"tenant_id,omitempty"` - Address *string `json:"address,omitempty"` - Persistence *SessionPersistence `json:"session_persistence,omitempty"` - ConnLimit *int `json:"connection_limit,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - } - - type request struct { - VirtualIP vip `json:"vip"` - } - - reqBody := request{VirtualIP: vip{ - Name: opts.Name, - SubnetID: opts.SubnetID, - Protocol: opts.Protocol, - ProtocolPort: opts.ProtocolPort, - PoolID: opts.PoolID, - Description: gophercloud.MaybeString(opts.Description), - TenantID: gophercloud.MaybeString(opts.TenantID), - Address: gophercloud.MaybeString(opts.Address), - ConnLimit: opts.ConnLimit, - AdminStateUp: opts.AdminStateUp, - }} - - if opts.Persistence != nil { - reqBody.VirtualIP.Persistence = opts.Persistence - } - - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// Get retrieves a particular virtual IP based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// UpdateOpts contains all the values needed to update an existing virtual IP. -// Attributes not listed here but appear in CreateOpts are immutable and cannot -// be updated. -type UpdateOpts struct { - // Human-readable name for the VIP. Does not have to be unique. - Name string - - // Required. The ID of the pool with which the VIP is associated. - PoolID string - - // Optional. Human-readable description for the VIP. - Description string - - // Optional. Omit this field to prevent session persistence. - Persistence *SessionPersistence - - // Optional. The maximum number of connections allowed for the VIP. - ConnLimit *int - - // Optional. The administrative state of the VIP. A valid value is true (UP) - // or false (DOWN). - AdminStateUp *bool -} - -// Update is an operation which modifies the attributes of the specified VIP. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { - type vip struct { - Name string `json:"name,omitempty"` - PoolID string `json:"pool_id,omitempty"` - Description *string `json:"description,omitempty"` - Persistence *SessionPersistence `json:"session_persistence,omitempty"` - ConnLimit *int `json:"connection_limit,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - } - - type request struct { - VirtualIP vip `json:"vip"` - } - - reqBody := request{VirtualIP: vip{ - Name: opts.Name, - PoolID: opts.PoolID, - Description: gophercloud.MaybeString(opts.Description), - ConnLimit: opts.ConnLimit, - AdminStateUp: opts.AdminStateUp, - }} - - if opts.Persistence != nil { - reqBody.VirtualIP.Persistence = opts.Persistence - } - - var res UpdateResult - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 202}, - }) - - return res -} - -// Delete will permanently delete a particular virtual IP based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/requests_test.go deleted file mode 100644 index 430f1a1eeb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/requests_test.go +++ /dev/null @@ -1,336 +0,0 @@ -package vips - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.AssertEquals(t, th.Endpoint()+"v2.0/lb/vips", rootURL(fake.ServiceClient())) - th.AssertEquals(t, th.Endpoint()+"v2.0/lb/vips/foo", resourceURL(fake.ServiceClient(), "foo")) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/vips", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "vips":[ - { - "id": "db902c0c-d5ff-4753-b465-668ad9656918", - "tenant_id": "310df60f-2a10-4ee5-9554-98393092194c", - "name": "web_vip", - "description": "lb config for the web tier", - "subnet_id": "96a4386a-f8c3-42ed-afce-d7954eee77b3", - "address" : "10.30.176.47", - "port_id" : "cd1f7a47-4fa6-449c-9ee7-632838aedfea", - "protocol": "HTTP", - "protocol_port": 80, - "pool_id" : "cfc6589d-f949-4c66-99d2-c2da56ef3764", - "admin_state_up": true, - "status": "ACTIVE" - }, - { - "id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", - "tenant_id": "310df60f-2a10-4ee5-9554-98393092194c", - "name": "db_vip", - "description": "lb config for the db tier", - "subnet_id": "9cedb85d-0759-4898-8a4b-fa5a5ea10086", - "address" : "10.30.176.48", - "port_id" : "cd1f7a47-4fa6-449c-9ee7-632838aedfea", - "protocol": "TCP", - "protocol_port": 3306, - "pool_id" : "41efe233-7591-43c5-9cf7-923964759f9e", - "session_persistence" : {"type" : "SOURCE_IP"}, - "connection_limit" : 2000, - "admin_state_up": true, - "status": "INACTIVE" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVIPs(page) - if err != nil { - t.Errorf("Failed to extract LBs: %v", err) - return false, err - } - - expected := []VirtualIP{ - VirtualIP{ - ID: "db902c0c-d5ff-4753-b465-668ad9656918", - TenantID: "310df60f-2a10-4ee5-9554-98393092194c", - Name: "web_vip", - Description: "lb config for the web tier", - SubnetID: "96a4386a-f8c3-42ed-afce-d7954eee77b3", - Address: "10.30.176.47", - PortID: "cd1f7a47-4fa6-449c-9ee7-632838aedfea", - Protocol: "HTTP", - ProtocolPort: 80, - PoolID: "cfc6589d-f949-4c66-99d2-c2da56ef3764", - Persistence: SessionPersistence{}, - ConnLimit: 0, - AdminStateUp: true, - Status: "ACTIVE", - }, - VirtualIP{ - ID: "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", - TenantID: "310df60f-2a10-4ee5-9554-98393092194c", - Name: "db_vip", - Description: "lb config for the db tier", - SubnetID: "9cedb85d-0759-4898-8a4b-fa5a5ea10086", - Address: "10.30.176.48", - PortID: "cd1f7a47-4fa6-449c-9ee7-632838aedfea", - Protocol: "TCP", - ProtocolPort: 3306, - PoolID: "41efe233-7591-43c5-9cf7-923964759f9e", - Persistence: SessionPersistence{Type: "SOURCE_IP"}, - ConnLimit: 2000, - AdminStateUp: true, - Status: "INACTIVE", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/vips", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "vip": { - "protocol": "HTTP", - "name": "NewVip", - "admin_state_up": true, - "subnet_id": "8032909d-47a1-4715-90af-5153ffe39861", - "pool_id": "61b1f87a-7a21-4ad3-9dda-7f81d249944f", - "protocol_port": 80, - "session_persistence": {"type": "SOURCE_IP"} - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "vip": { - "status": "PENDING_CREATE", - "protocol": "HTTP", - "description": "", - "admin_state_up": true, - "subnet_id": "8032909d-47a1-4715-90af-5153ffe39861", - "tenant_id": "83657cfcdfe44cd5920adaf26c48ceea", - "connection_limit": -1, - "pool_id": "61b1f87a-7a21-4ad3-9dda-7f81d249944f", - "address": "10.0.0.11", - "protocol_port": 80, - "port_id": "f7e6fe6a-b8b5-43a8-8215-73456b32e0f5", - "id": "c987d2be-9a3c-4ac9-a046-e8716b1350e2", - "name": "NewVip" - } -} - `) - }) - - opts := CreateOpts{ - Protocol: "HTTP", - Name: "NewVip", - AdminStateUp: Up, - SubnetID: "8032909d-47a1-4715-90af-5153ffe39861", - PoolID: "61b1f87a-7a21-4ad3-9dda-7f81d249944f", - ProtocolPort: 80, - Persistence: &SessionPersistence{Type: "SOURCE_IP"}, - } - - r, err := Create(fake.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "PENDING_CREATE", r.Status) - th.AssertEquals(t, "HTTP", r.Protocol) - th.AssertEquals(t, "", r.Description) - th.AssertEquals(t, true, r.AdminStateUp) - th.AssertEquals(t, "8032909d-47a1-4715-90af-5153ffe39861", r.SubnetID) - th.AssertEquals(t, "83657cfcdfe44cd5920adaf26c48ceea", r.TenantID) - th.AssertEquals(t, -1, r.ConnLimit) - th.AssertEquals(t, "61b1f87a-7a21-4ad3-9dda-7f81d249944f", r.PoolID) - th.AssertEquals(t, "10.0.0.11", r.Address) - th.AssertEquals(t, 80, r.ProtocolPort) - th.AssertEquals(t, "f7e6fe6a-b8b5-43a8-8215-73456b32e0f5", r.PortID) - th.AssertEquals(t, "c987d2be-9a3c-4ac9-a046-e8716b1350e2", r.ID) - th.AssertEquals(t, "NewVip", r.Name) -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Name: "foo"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Name: "foo", SubnetID: "bar"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Name: "foo", SubnetID: "bar", Protocol: "bar"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Name: "foo", SubnetID: "bar", Protocol: "bar", ProtocolPort: 80}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/vips/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "vip": { - "status": "ACTIVE", - "protocol": "HTTP", - "description": "", - "admin_state_up": true, - "subnet_id": "8032909d-47a1-4715-90af-5153ffe39861", - "tenant_id": "83657cfcdfe44cd5920adaf26c48ceea", - "connection_limit": 1000, - "pool_id": "72741b06-df4d-4715-b142-276b6bce75ab", - "session_persistence": { - "cookie_name": "MyAppCookie", - "type": "APP_COOKIE" - }, - "address": "10.0.0.10", - "protocol_port": 80, - "port_id": "b5a743d6-056b-468b-862d-fb13a9aa694e", - "id": "4ec89087-d057-4e2c-911f-60a3b47ee304", - "name": "my-vip" - } -} - `) - }) - - vip, err := Get(fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "ACTIVE", vip.Status) - th.AssertEquals(t, "HTTP", vip.Protocol) - th.AssertEquals(t, "", vip.Description) - th.AssertEquals(t, true, vip.AdminStateUp) - th.AssertEquals(t, 1000, vip.ConnLimit) - th.AssertEquals(t, SessionPersistence{Type: "APP_COOKIE", CookieName: "MyAppCookie"}, vip.Persistence) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/vips/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "vip": { - "connection_limit": 1000, - "session_persistence": {"type": "SOURCE_IP"} - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, ` -{ - "vip": { - "status": "PENDING_UPDATE", - "protocol": "HTTP", - "description": "", - "admin_state_up": true, - "subnet_id": "8032909d-47a1-4715-90af-5153ffe39861", - "tenant_id": "83657cfcdfe44cd5920adaf26c48ceea", - "connection_limit": 1000, - "pool_id": "61b1f87a-7a21-4ad3-9dda-7f81d249944f", - "address": "10.0.0.11", - "protocol_port": 80, - "port_id": "f7e6fe6a-b8b5-43a8-8215-73456b32e0f5", - "id": "c987d2be-9a3c-4ac9-a046-e8716b1350e2", - "name": "NewVip" - } -} - `) - }) - - i1000 := 1000 - options := UpdateOpts{ - ConnLimit: &i1000, - Persistence: &SessionPersistence{Type: "SOURCE_IP"}, - } - vip, err := Update(fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "PENDING_UPDATE", vip.Status) - th.AssertEquals(t, 1000, vip.ConnLimit) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/lb/vips/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/results.go deleted file mode 100644 index e1092e780e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/results.go +++ /dev/null @@ -1,166 +0,0 @@ -package vips - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// SessionPersistence represents the session persistence feature of the load -// balancing service. It attempts to force connections or requests in the same -// session to be processed by the same member as long as it is ative. Three -// types of persistence are supported: -// -// SOURCE_IP: With this mode, all connections originating from the same source -// IP address, will be handled by the same member of the pool. -// HTTP_COOKIE: With this persistence mode, the load balancing function will -// create a cookie on the first request from a client. Subsequent -// requests containing the same cookie value will be handled by -// the same member of the pool. -// APP_COOKIE: With this persistence mode, the load balancing function will -// rely on a cookie established by the backend application. All -// requests carrying the same cookie value will be handled by the -// same member of the pool. -type SessionPersistence struct { - // The type of persistence mode - Type string `mapstructure:"type" json:"type"` - - // Name of cookie if persistence mode is set appropriately - CookieName string `mapstructure:"cookie_name" json:"cookie_name,omitempty"` -} - -// VirtualIP is the primary load balancing configuration object that specifies -// the virtual IP address and port on which client traffic is received, as well -// as other details such as the load balancing method to be use, protocol, etc. -// This entity is sometimes known in LB products under the name of a "virtual -// server", a "vserver" or a "listener". -type VirtualIP struct { - // The unique ID for the VIP. - ID string `mapstructure:"id" json:"id"` - - // Owner of the VIP. Only an admin user can specify a tenant ID other than its own. - TenantID string `mapstructure:"tenant_id" json:"tenant_id"` - - // Human-readable name for the VIP. Does not have to be unique. - Name string `mapstructure:"name" json:"name"` - - // Human-readable description for the VIP. - Description string `mapstructure:"description" json:"description"` - - // The ID of the subnet on which to allocate the VIP address. - SubnetID string `mapstructure:"subnet_id" json:"subnet_id"` - - // The IP address of the VIP. - Address string `mapstructure:"address" json:"address"` - - // The protocol of the VIP address. A valid value is TCP, HTTP, or HTTPS. - Protocol string `mapstructure:"protocol" json:"protocol"` - - // The port on which to listen to client traffic that is associated with the - // VIP address. A valid value is from 0 to 65535. - ProtocolPort int `mapstructure:"protocol_port" json:"protocol_port"` - - // The ID of the pool with which the VIP is associated. - PoolID string `mapstructure:"pool_id" json:"pool_id"` - - // The ID of the port which belongs to the load balancer - PortID string `mapstructure:"port_id" json:"port_id"` - - // Indicates whether connections in the same session will be processed by the - // same pool member or not. - Persistence SessionPersistence `mapstructure:"session_persistence" json:"session_persistence"` - - // The maximum number of connections allowed for the VIP. Default is -1, - // meaning no limit. - ConnLimit int `mapstructure:"connection_limit" json:"connection_limit"` - - // The administrative state of the VIP. A valid value is true (UP) or false (DOWN). - AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"` - - // The status of the VIP. Indicates whether the VIP is operational. - Status string `mapstructure:"status" json:"status"` -} - -// VIPPage is the page returned by a pager when traversing over a -// collection of routers. -type VIPPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of routers has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (p VIPPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"vips_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a RouterPage struct is empty. -func (p VIPPage) IsEmpty() (bool, error) { - is, err := ExtractVIPs(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractVIPs accepts a Page struct, specifically a VIPPage struct, -// and extracts the elements into a slice of VirtualIP structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractVIPs(page pagination.Page) ([]VirtualIP, error) { - var resp struct { - VIPs []VirtualIP `mapstructure:"vips" json:"vips"` - } - - err := mapstructure.Decode(page.(VIPPage).Body, &resp) - - return resp.VIPs, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a router. -func (r commonResult) Extract() (*VirtualIP, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - VirtualIP *VirtualIP `mapstructure:"vip" json:"vip"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.VirtualIP, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/urls.go deleted file mode 100644 index 2b6f67e71d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/vips/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package vips - -import "github.com/rackspace/gophercloud" - -const ( - rootPath = "lb" - resourcePath = "vips" -) - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath, resourcePath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, resourcePath, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/doc.go deleted file mode 100644 index 373da44f84..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package provider gives access to the provider Neutron plugin, allowing -// network extended attributes. The provider extended attributes for networks -// enable administrative users to specify how network objects map to the -// underlying networking infrastructure. These extended attributes also appear -// when administrative users query networks. -// -// For more information about extended attributes, see the NetworkExtAttrs -// struct. The actual semantics of these attributes depend on the technology -// back end of the particular plug-in. See the plug-in documentation and the -// OpenStack Cloud Administrator Guide to understand which values should be -// specific for each of these attributes when OpenStack Networking is deployed -// with a particular plug-in. The examples shown in this chapter refer to the -// Open vSwitch plug-in. -// -// The default policy settings enable only users with administrative rights to -// specify these parameters in requests and to see their values in responses. By -// default, the provider network extension attributes are completely hidden from -// regular tenants. As a rule of thumb, if these attributes are not visible in a -// GET /networks/ operation, this implies the user submitting the -// request is not authorized to view or manipulate provider network attributes. -package provider diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/results.go deleted file mode 100644 index 3453584587..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/results.go +++ /dev/null @@ -1,124 +0,0 @@ -package provider - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" -) - -// AdminState gives users a solid type to work with for create and update -// operations. It is recommended that users use the `Up` and `Down` enums. -type AdminState *bool - -// Convenience vars for AdminStateUp values. -var ( - iTrue = true - iFalse = false - - Up AdminState = &iTrue - Down AdminState = &iFalse -) - -// NetworkExtAttrs represents an extended form of a Network with additional fields. -type NetworkExtAttrs struct { - // UUID for the network - ID string `mapstructure:"id" json:"id"` - - // Human-readable name for the network. Might not be unique. - Name string `mapstructure:"name" json:"name"` - - // The administrative state of network. If false (down), the network does not forward packets. - AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"` - - // Indicates whether network is currently operational. Possible values include - // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values. - Status string `mapstructure:"status" json:"status"` - - // Subnets associated with this network. - Subnets []string `mapstructure:"subnets" json:"subnets"` - - // Owner of network. Only admin users can specify a tenant_id other than its own. - TenantID string `mapstructure:"tenant_id" json:"tenant_id"` - - // Specifies whether the network resource can be accessed by any tenant or not. - Shared bool `mapstructure:"shared" json:"shared"` - - // Specifies the nature of the physical network mapped to this network - // resource. Examples are flat, vlan, or gre. - NetworkType string `json:"provider:network_type" mapstructure:"provider:network_type"` - - // Identifies the physical network on top of which this network object is - // being implemented. The OpenStack Networking API does not expose any facility - // for retrieving the list of available physical networks. As an example, in - // the Open vSwitch plug-in this is a symbolic name which is then mapped to - // specific bridges on each compute host through the Open vSwitch plug-in - // configuration file. - PhysicalNetwork string `json:"provider:physical_network" mapstructure:"provider:physical_network"` - - // Identifies an isolated segment on the physical network; the nature of the - // segment depends on the segmentation model defined by network_type. For - // instance, if network_type is vlan, then this is a vlan identifier; - // otherwise, if network_type is gre, then this will be a gre key. - SegmentationID string `json:"provider:segmentation_id" mapstructure:"provider:segmentation_id"` -} - -// ExtractGet decorates a GetResult struct returned from a networks.Get() -// function with extended attributes. -func ExtractGet(r networks.GetResult) (*NetworkExtAttrs, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Network *NetworkExtAttrs `json:"network"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Network, err -} - -// ExtractCreate decorates a CreateResult struct returned from a networks.Create() -// function with extended attributes. -func ExtractCreate(r networks.CreateResult) (*NetworkExtAttrs, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Network *NetworkExtAttrs `json:"network"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Network, err -} - -// ExtractUpdate decorates a UpdateResult struct returned from a -// networks.Update() function with extended attributes. -func ExtractUpdate(r networks.UpdateResult) (*NetworkExtAttrs, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Network *NetworkExtAttrs `json:"network"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Network, err -} - -// ExtractList accepts a Page struct, specifically a NetworkPage struct, and -// extracts the elements into a slice of NetworkExtAttrs structs. In other -// words, a generic collection is mapped into a relevant slice. -func ExtractList(page pagination.Page) ([]NetworkExtAttrs, error) { - var resp struct { - Networks []NetworkExtAttrs `mapstructure:"networks" json:"networks"` - } - - err := mapstructure.Decode(page.(networks.NetworkPage).Body, &resp) - - return resp.Networks, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/results_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/results_test.go deleted file mode 100644 index 9801b2e5e3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/provider/results_test.go +++ /dev/null @@ -1,253 +0,0 @@ -package provider - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "networks": [ - { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "provider:segmentation_id": null, - "provider:physical_network": null, - "provider:network_type": "local" - }, - { - "status": "ACTIVE", - "subnets": [ - "08eae331-0402-425a-923c-34f7cfe39c1b" - ], - "name": "private", - "admin_state_up": true, - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "shared": true, - "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "provider:segmentation_id": null, - "provider:physical_network": null, - "provider:network_type": "local" - } - ] -} - `) - }) - - count := 0 - - networks.List(fake.ServiceClient(), networks.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractList(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - expected := []NetworkExtAttrs{ - NetworkExtAttrs{ - Status: "ACTIVE", - Subnets: []string{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"}, - Name: "private-network", - AdminStateUp: true, - TenantID: "4fd44f30292945e481c7b8a0c8908869", - Shared: true, - ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - NetworkType: "local", - PhysicalNetwork: "", - SegmentationID: "", - }, - NetworkExtAttrs{ - Status: "ACTIVE", - Subnets: []string{"08eae331-0402-425a-923c-34f7cfe39c1b"}, - Name: "private", - AdminStateUp: true, - TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", - Shared: true, - ID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - NetworkType: "local", - PhysicalNetwork: "", - SegmentationID: "", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "provider:physical_network": null, - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "provider:network_type": "local", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "provider:segmentation_id": null - } -} - `) - }) - - res := networks.Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - n, err := ExtractGet(res) - - th.AssertNoErr(t, err) - - th.AssertEquals(t, "", n.PhysicalNetwork) - th.AssertEquals(t, "local", n.NetworkType) - th.AssertEquals(t, "", n.SegmentationID) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "sample_network", - "admin_state_up": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "provider:physical_network": null, - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "provider:network_type": "local", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "provider:segmentation_id": null - } -} - `) - }) - - options := networks.CreateOpts{Name: "sample_network", AdminStateUp: Up} - res := networks.Create(fake.ServiceClient(), options) - n, err := ExtractCreate(res) - - th.AssertNoErr(t, err) - - th.AssertEquals(t, "", n.PhysicalNetwork) - th.AssertEquals(t, "local", n.NetworkType) - th.AssertEquals(t, "", n.SegmentationID) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "new_network_name", - "admin_state_up": false, - "shared": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "provider:physical_network": null, - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "provider:network_type": "local", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "provider:segmentation_id": null - } -} - `) - }) - - iTrue := true - options := networks.UpdateOpts{Name: "new_network_name", AdminStateUp: Down, Shared: &iTrue} - res := networks.Update(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options) - n, err := ExtractUpdate(res) - - th.AssertNoErr(t, err) - - th.AssertEquals(t, "", n.PhysicalNetwork) - th.AssertEquals(t, "local", n.NetworkType) - th.AssertEquals(t, "", n.SegmentationID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/doc.go deleted file mode 100644 index 8ef455ffb3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Package security contains functionality to work with security group and -// security group rules Neutron resources. -// -// Security groups and security group rules allows administrators and tenants -// the ability to specify the type of traffic and direction (ingress/egress) -// that is allowed to pass through a port. A security group is a container for -// security group rules. -// -// When a port is created in Networking it is associated with a security group. -// If a security group is not specified the port is associated with a 'default' -// security group. By default, this group drops all ingress traffic and allows -// all egress. Rules can be added to this group in order to change the behaviour. -// -// The basic characteristics of Neutron Security Groups are: -// -// For ingress traffic (to an instance) -// - Only traffic matched with security group rules are allowed. -// - When there is no rule defined, all traffic are dropped. -// -// For egress traffic (from an instance) -// - Only traffic matched with security group rules are allowed. -// - When there is no rule defined, all egress traffic are dropped. -// - When a new security group is created, rules to allow all egress traffic -// are automatically added. -// -// "default security group" is defined for each tenant. -// - For the default security group a rule which allows intercommunication -// among hosts associated with the default security group is defined by default. -// - As a result, all egress traffic and intercommunication in the default -// group are allowed and all ingress from outside of the default group is -// dropped by default (in the default security group). -package security diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go deleted file mode 100644 index 0c970ae6f2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go +++ /dev/null @@ -1,107 +0,0 @@ -package groups - -import ( - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - TenantID string `q:"tenant_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// security groups. It accepts a ListOpts struct, which allows you to filter -// and sort the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return SecGroupPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -var ( - errNameRequired = fmt.Errorf("Name is required") -) - -// CreateOpts contains all the values needed to create a new security group. -type CreateOpts struct { - // Required. Human-readable name for the VIP. Does not have to be unique. - Name string - - // Optional. Describes the security group. - Description string -} - -// Create is an operation which provisions a new security group with default -// security group rules for the IPv4 and IPv6 ether types. -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - var res CreateResult - - // Validate required opts - if opts.Name == "" { - res.Err = errNameRequired - return res - } - - type secgroup struct { - Name string `json:"name"` - Description string `json:"description,omitempty"` - } - - type request struct { - SecGroup secgroup `json:"security_group"` - } - - reqBody := request{SecGroup: secgroup{ - Name: opts.Name, - Description: opts.Description, - }} - - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// Get retrieves a particular security group based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Delete will permanently delete a particular security group based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests_test.go deleted file mode 100644 index 5f074c72f3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests_test.go +++ /dev/null @@ -1,213 +0,0 @@ -package groups - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.AssertEquals(t, th.Endpoint()+"v2.0/security-groups", rootURL(fake.ServiceClient())) - th.AssertEquals(t, th.Endpoint()+"v2.0/security-groups/foo", resourceURL(fake.ServiceClient(), "foo")) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-groups", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_groups": [ - { - "description": "default", - "id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "name": "default", - "security_group_rules": [], - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractGroups(page) - if err != nil { - t.Errorf("Failed to extract secgroups: %v", err) - return false, err - } - - expected := []SecGroup{ - SecGroup{ - Description: "default", - ID: "85cc3048-abc3-43cc-89b3-377341426ac5", - Name: "default", - Rules: []rules.SecGroupRule{}, - TenantID: "e4f50856753b4dc6afee5fa6b9b6c550", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-groups", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "security_group": { - "name": "new-webservers", - "description": "security group for webservers" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "security_group": { - "description": "security group for webservers", - "id": "2076db17-a522-4506-91de-c6dd8e837028", - "name": "new-webservers", - "security_group_rules": [ - { - "direction": "egress", - "ethertype": "IPv4", - "id": "38ce2d8e-e8f1-48bd-83c2-d33cb9f50c3d", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "2076db17-a522-4506-91de-c6dd8e837028", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - }, - { - "direction": "egress", - "ethertype": "IPv6", - "id": "565b9502-12de-4ffd-91e9-68885cff6ae1", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "2076db17-a522-4506-91de-c6dd8e837028", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } - ], - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } -} - `) - }) - - opts := CreateOpts{Name: "new-webservers", Description: "security group for webservers"} - _, err := Create(fake.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-groups/85cc3048-abc3-43cc-89b3-377341426ac5", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group": { - "description": "default", - "id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "name": "default", - "security_group_rules": [ - { - "direction": "egress", - "ethertype": "IPv6", - "id": "3c0e45ff-adaf-4124-b083-bf390e5482ff", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - }, - { - "direction": "egress", - "ethertype": "IPv4", - "id": "93aa42e5-80db-4581-9391-3a608bd0e448", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } - ], - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } -} - `) - }) - - sg, err := Get(fake.ServiceClient(), "85cc3048-abc3-43cc-89b3-377341426ac5").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "default", sg.Description) - th.AssertEquals(t, "85cc3048-abc3-43cc-89b3-377341426ac5", sg.ID) - th.AssertEquals(t, "default", sg.Name) - th.AssertEquals(t, 2, len(sg.Rules)) - th.AssertEquals(t, "e4f50856753b4dc6afee5fa6b9b6c550", sg.TenantID) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-groups/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/results.go deleted file mode 100644 index 49db261c22..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/results.go +++ /dev/null @@ -1,108 +0,0 @@ -package groups - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules" - "github.com/rackspace/gophercloud/pagination" -) - -// SecGroup represents a container for security group rules. -type SecGroup struct { - // The UUID for the security group. - ID string - - // Human-readable name for the security group. Might not be unique. Cannot be - // named "default" as that is automatically created for a tenant. - Name string - - // The security group description. - Description string - - // A slice of security group rules that dictate the permitted behaviour for - // traffic entering and leaving the group. - Rules []rules.SecGroupRule `json:"security_group_rules" mapstructure:"security_group_rules"` - - // Owner of the security group. Only admin users can specify a TenantID - // other than their own. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` -} - -// SecGroupPage is the page returned by a pager when traversing over a -// collection of security groups. -type SecGroupPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of security groups has -// reached the end of a page and the pager seeks to traverse over a new one. In -// order to do this, it needs to construct the next page's URL. -func (p SecGroupPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"security_groups_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a SecGroupPage struct is empty. -func (p SecGroupPage) IsEmpty() (bool, error) { - is, err := ExtractGroups(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractGroups accepts a Page struct, specifically a SecGroupPage struct, -// and extracts the elements into a slice of SecGroup structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractGroups(page pagination.Page) ([]SecGroup, error) { - var resp struct { - SecGroups []SecGroup `mapstructure:"security_groups" json:"security_groups"` - } - - err := mapstructure.Decode(page.(SecGroupPage).Body, &resp) - - return resp.SecGroups, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a security group. -func (r commonResult) Extract() (*SecGroup, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - SecGroup *SecGroup `mapstructure:"security_group" json:"security_group"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.SecGroup, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/urls.go deleted file mode 100644 index 84f7324f09..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package groups - -import "github.com/rackspace/gophercloud" - -const rootPath = "security-groups" - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go deleted file mode 100644 index edaebe82cd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go +++ /dev/null @@ -1,183 +0,0 @@ -package rules - -import ( - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the security group attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Direction string `q:"direction"` - EtherType string `q:"ethertype"` - ID string `q:"id"` - PortRangeMax int `q:"port_range_max"` - PortRangeMin int `q:"port_range_min"` - Protocol string `q:"protocol"` - RemoteGroupID string `q:"remote_group_id"` - RemoteIPPrefix string `q:"remote_ip_prefix"` - SecGroupID string `q:"security_group_id"` - TenantID string `q:"tenant_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// security group rules. It accepts a ListOpts struct, which allows you to filter -// and sort the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return SecGroupRulePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Errors -var ( - errValidDirectionRequired = fmt.Errorf("A valid Direction is required") - errValidEtherTypeRequired = fmt.Errorf("A valid EtherType is required") - errSecGroupIDRequired = fmt.Errorf("A valid SecGroupID is required") - errValidProtocolRequired = fmt.Errorf("A valid Protocol is required") -) - -// Constants useful for CreateOpts -const ( - DirIngress = "ingress" - DirEgress = "egress" - Ether4 = "IPv4" - Ether6 = "IPv6" - ProtocolTCP = "tcp" - ProtocolUDP = "udp" - ProtocolICMP = "icmp" -) - -// CreateOpts contains all the values needed to create a new security group rule. -type CreateOpts struct { - // Required. Must be either "ingress" or "egress": the direction in which the - // security group rule is applied. - Direction string - - // Required. Must be "IPv4" or "IPv6", and addresses represented in CIDR must - // match the ingress or egress rules. - EtherType string - - // Required. The security group ID to associate with this security group rule. - SecGroupID string - - // Optional. The maximum port number in the range that is matched by the - // security group rule. The PortRangeMin attribute constrains the PortRangeMax - // attribute. If the protocol is ICMP, this value must be an ICMP type. - PortRangeMax int - - // Optional. The minimum port number in the range that is matched by the - // security group rule. If the protocol is TCP or UDP, this value must be - // less than or equal to the value of the PortRangeMax attribute. If the - // protocol is ICMP, this value must be an ICMP type. - PortRangeMin int - - // Optional. The protocol that is matched by the security group rule. Valid - // values are "tcp", "udp", "icmp" or an empty string. - Protocol string - - // Optional. The remote group ID to be associated with this security group - // rule. You can specify either RemoteGroupID or RemoteIPPrefix. - RemoteGroupID string - - // Optional. The remote IP prefix to be associated with this security group - // rule. You can specify either RemoteGroupID or RemoteIPPrefix. This - // attribute matches the specified IP prefix as the source IP address of the - // IP packet. - RemoteIPPrefix string -} - -// Create is an operation which provisions a new security group with default -// security group rules for the IPv4 and IPv6 ether types. -func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { - var res CreateResult - - // Validate required opts - if opts.Direction != DirIngress && opts.Direction != DirEgress { - res.Err = errValidDirectionRequired - return res - } - if opts.EtherType != Ether4 && opts.EtherType != Ether6 { - res.Err = errValidEtherTypeRequired - return res - } - if opts.SecGroupID == "" { - res.Err = errSecGroupIDRequired - return res - } - if opts.Protocol != "" && opts.Protocol != ProtocolTCP && opts.Protocol != ProtocolUDP && opts.Protocol != ProtocolICMP { - res.Err = errValidProtocolRequired - return res - } - - type secrule struct { - Direction string `json:"direction"` - EtherType string `json:"ethertype"` - SecGroupID string `json:"security_group_id"` - PortRangeMax int `json:"port_range_max,omitempty"` - PortRangeMin int `json:"port_range_min,omitempty"` - Protocol string `json:"protocol,omitempty"` - RemoteGroupID string `json:"remote_group_id,omitempty"` - RemoteIPPrefix string `json:"remote_ip_prefix,omitempty"` - } - - type request struct { - SecRule secrule `json:"security_group_rule"` - } - - reqBody := request{SecRule: secrule{ - Direction: opts.Direction, - EtherType: opts.EtherType, - SecGroupID: opts.SecGroupID, - PortRangeMax: opts.PortRangeMax, - PortRangeMin: opts.PortRangeMin, - Protocol: opts.Protocol, - RemoteGroupID: opts.RemoteGroupID, - RemoteIPPrefix: opts.RemoteIPPrefix, - }} - - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// Get retrieves a particular security group based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Delete will permanently delete a particular security group based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests_test.go deleted file mode 100644 index b5afef31ed..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests_test.go +++ /dev/null @@ -1,243 +0,0 @@ -package rules - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestURLs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.AssertEquals(t, th.Endpoint()+"v2.0/security-group-rules", rootURL(fake.ServiceClient())) - th.AssertEquals(t, th.Endpoint()+"v2.0/security-group-rules/foo", resourceURL(fake.ServiceClient(), "foo")) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group_rules": [ - { - "direction": "egress", - "ethertype": "IPv6", - "id": "3c0e45ff-adaf-4124-b083-bf390e5482ff", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - }, - { - "direction": "egress", - "ethertype": "IPv4", - "id": "93aa42e5-80db-4581-9391-3a608bd0e448", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractRules(page) - if err != nil { - t.Errorf("Failed to extract secrules: %v", err) - return false, err - } - - expected := []SecGroupRule{ - SecGroupRule{ - Direction: "egress", - EtherType: "IPv6", - ID: "3c0e45ff-adaf-4124-b083-bf390e5482ff", - PortRangeMax: 0, - PortRangeMin: 0, - Protocol: "", - RemoteGroupID: "", - RemoteIPPrefix: "", - SecGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", - TenantID: "e4f50856753b4dc6afee5fa6b9b6c550", - }, - SecGroupRule{ - Direction: "egress", - EtherType: "IPv4", - ID: "93aa42e5-80db-4581-9391-3a608bd0e448", - PortRangeMax: 0, - PortRangeMin: 0, - Protocol: "", - RemoteGroupID: "", - RemoteIPPrefix: "", - SecGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", - TenantID: "e4f50856753b4dc6afee5fa6b9b6c550", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "security_group_rule": { - "direction": "ingress", - "port_range_min": 80, - "ethertype": "IPv4", - "port_range_max": 80, - "protocol": "tcp", - "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "security_group_rule": { - "direction": "ingress", - "ethertype": "IPv4", - "id": "2bc0accf-312e-429a-956e-e4407625eb62", - "port_range_max": 80, - "port_range_min": 80, - "protocol": "tcp", - "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "remote_ip_prefix": null, - "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } -} - `) - }) - - opts := CreateOpts{ - Direction: "ingress", - PortRangeMin: 80, - EtherType: "IPv4", - PortRangeMax: 80, - Protocol: "tcp", - RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", - SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", - } - _, err := Create(fake.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), CreateOpts{Direction: "something"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Direction: DirIngress, EtherType: "something"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Direction: DirIngress, EtherType: Ether4}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - res = Create(fake.ServiceClient(), CreateOpts{Direction: DirIngress, EtherType: Ether4, SecGroupID: "something", Protocol: "foo"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-group-rules/3c0e45ff-adaf-4124-b083-bf390e5482ff", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "security_group_rule": { - "direction": "egress", - "ethertype": "IPv6", - "id": "3c0e45ff-adaf-4124-b083-bf390e5482ff", - "port_range_max": null, - "port_range_min": null, - "protocol": null, - "remote_group_id": null, - "remote_ip_prefix": null, - "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", - "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" - } -} - `) - }) - - sr, err := Get(fake.ServiceClient(), "3c0e45ff-adaf-4124-b083-bf390e5482ff").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, "egress", sr.Direction) - th.AssertEquals(t, "IPv6", sr.EtherType) - th.AssertEquals(t, "3c0e45ff-adaf-4124-b083-bf390e5482ff", sr.ID) - th.AssertEquals(t, 0, sr.PortRangeMax) - th.AssertEquals(t, 0, sr.PortRangeMin) - th.AssertEquals(t, "", sr.Protocol) - th.AssertEquals(t, "", sr.RemoteGroupID) - th.AssertEquals(t, "", sr.RemoteIPPrefix) - th.AssertEquals(t, "85cc3048-abc3-43cc-89b3-377341426ac5", sr.SecGroupID) - th.AssertEquals(t, "e4f50856753b4dc6afee5fa6b9b6c550", sr.TenantID) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/security-group-rules/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/results.go deleted file mode 100644 index 6e13857689..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/results.go +++ /dev/null @@ -1,133 +0,0 @@ -package rules - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// SecGroupRule represents a rule to dictate the behaviour of incoming or -// outgoing traffic for a particular security group. -type SecGroupRule struct { - // The UUID for this security group rule. - ID string - - // The direction in which the security group rule is applied. The only values - // allowed are "ingress" or "egress". For a compute instance, an ingress - // security group rule is applied to incoming (ingress) traffic for that - // instance. An egress rule is applied to traffic leaving the instance. - Direction string - - // Must be IPv4 or IPv6, and addresses represented in CIDR must match the - // ingress or egress rules. - EtherType string `json:"ethertype" mapstructure:"ethertype"` - - // The security group ID to associate with this security group rule. - SecGroupID string `json:"security_group_id" mapstructure:"security_group_id"` - - // The minimum port number in the range that is matched by the security group - // rule. If the protocol is TCP or UDP, this value must be less than or equal - // to the value of the PortRangeMax attribute. If the protocol is ICMP, this - // value must be an ICMP type. - PortRangeMin int `json:"port_range_min" mapstructure:"port_range_min"` - - // The maximum port number in the range that is matched by the security group - // rule. The PortRangeMin attribute constrains the PortRangeMax attribute. If - // the protocol is ICMP, this value must be an ICMP type. - PortRangeMax int `json:"port_range_max" mapstructure:"port_range_max"` - - // The protocol that is matched by the security group rule. Valid values are - // "tcp", "udp", "icmp" or an empty string. - Protocol string - - // The remote group ID to be associated with this security group rule. You - // can specify either RemoteGroupID or RemoteIPPrefix. - RemoteGroupID string `json:"remote_group_id" mapstructure:"remote_group_id"` - - // The remote IP prefix to be associated with this security group rule. You - // can specify either RemoteGroupID or RemoteIPPrefix . This attribute - // matches the specified IP prefix as the source IP address of the IP packet. - RemoteIPPrefix string `json:"remote_ip_prefix" mapstructure:"remote_ip_prefix"` - - // The owner of this security group rule. - TenantID string `json:"tenant_id" mapstructure:"tenant_id"` -} - -// SecGroupRulePage is the page returned by a pager when traversing over a -// collection of security group rules. -type SecGroupRulePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of security group rules has -// reached the end of a page and the pager seeks to traverse over a new one. In -// order to do this, it needs to construct the next page's URL. -func (p SecGroupRulePage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"security_group_rules_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a SecGroupRulePage struct is empty. -func (p SecGroupRulePage) IsEmpty() (bool, error) { - is, err := ExtractRules(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractRules accepts a Page struct, specifically a SecGroupRulePage struct, -// and extracts the elements into a slice of SecGroupRule structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractRules(page pagination.Page) ([]SecGroupRule, error) { - var resp struct { - SecGroupRules []SecGroupRule `mapstructure:"security_group_rules" json:"security_group_rules"` - } - - err := mapstructure.Decode(page.(SecGroupRulePage).Body, &resp) - - return resp.SecGroupRules, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a security rule. -func (r commonResult) Extract() (*SecGroupRule, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - SecGroupRule *SecGroupRule `mapstructure:"security_group_rule" json:"security_group_rule"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.SecGroupRule, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/urls.go deleted file mode 100644 index 8e2b2bb28d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package rules - -import "github.com/rackspace/gophercloud" - -const rootPath = "security-group-rules" - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go deleted file mode 100644 index dedbb252de..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go +++ /dev/null @@ -1,209 +0,0 @@ -package networks - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// AdminState gives users a solid type to work with for create and update -// operations. It is recommended that users use the `Up` and `Down` enums. -type AdminState *bool - -// Convenience vars for AdminStateUp values. -var ( - iTrue = true - iFalse = false - - Up AdminState = &iTrue - Down AdminState = &iFalse -) - -type networkOpts struct { - AdminStateUp *bool - Name string - Shared *bool - TenantID string -} - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToNetworkListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the network attributes you want to see returned. SortKey allows you to sort -// by a particular network attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Status string `q:"status"` - Name string `q:"name"` - AdminStateUp *bool `q:"admin_state_up"` - TenantID string `q:"tenant_id"` - Shared *bool `q:"shared"` - ID string `q:"id"` - Marker string `q:"marker"` - Limit int `q:"limit"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// ToNetworkListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToNetworkListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List returns a Pager which allows you to iterate over a collection of -// networks. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToNetworkListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return NetworkPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific network based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type CreateOptsBuilder interface { - ToNetworkCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is the common options struct used in this package's Create -// operation. -type CreateOpts networkOpts - -// ToNetworkCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { - n := make(map[string]interface{}) - - if opts.AdminStateUp != nil { - n["admin_state_up"] = &opts.AdminStateUp - } - if opts.Name != "" { - n["name"] = opts.Name - } - if opts.Shared != nil { - n["shared"] = &opts.Shared - } - if opts.TenantID != "" { - n["tenant_id"] = opts.TenantID - } - - return map[string]interface{}{"network": n}, nil -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -// -// The tenant ID that is contained in the URI is the tenant that creates the -// network. An admin user, however, has the option of specifying another tenant -// ID in the CreateOpts struct. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToNetworkCreateMap() - if err != nil { - res.Err = err - return res - } - - // Send request to API - _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - return res -} - -// UpdateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Update operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type UpdateOptsBuilder interface { - ToNetworkUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts is the common options struct used in this package's Update -// operation. -type UpdateOpts networkOpts - -// ToNetworkUpdateMap casts a UpdateOpts struct to a map. -func (opts UpdateOpts) ToNetworkUpdateMap() (map[string]interface{}, error) { - n := make(map[string]interface{}) - - if opts.AdminStateUp != nil { - n["admin_state_up"] = &opts.AdminStateUp - } - if opts.Name != "" { - n["name"] = opts.Name - } - if opts.Shared != nil { - n["shared"] = &opts.Shared - } - - return map[string]interface{}{"network": n}, nil -} - -// Update accepts a UpdateOpts struct and updates an existing network using the -// values provided. For more information, see the Create function. -func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToNetworkUpdateMap() - if err != nil { - res.Err = err - return res - } - - // Send request to API - _, res.Err = perigee.Request("PUT", updateURL(c, networkID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201}, - }) - - return res -} - -// Delete accepts a unique ID and deletes the network associated with it. -func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(c, networkID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go deleted file mode 100644 index a263b7b16b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go +++ /dev/null @@ -1,275 +0,0 @@ -package networks - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "networks": [ - { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - }, - { - "status": "ACTIVE", - "subnets": [ - "08eae331-0402-425a-923c-34f7cfe39c1b" - ], - "name": "private", - "admin_state_up": true, - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "shared": true, - "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324" - } - ] -} - `) - }) - - client := fake.ServiceClient() - count := 0 - - List(client, ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNetworks(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - expected := []Network{ - Network{ - Status: "ACTIVE", - Subnets: []string{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"}, - Name: "private-network", - AdminStateUp: true, - TenantID: "4fd44f30292945e481c7b8a0c8908869", - Shared: true, - ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - }, - Network{ - Status: "ACTIVE", - Subnets: []string{"08eae331-0402-425a-923c-34f7cfe39c1b"}, - Name: "private", - AdminStateUp: true, - TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", - Shared: true, - ID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.Subnets, []string{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"}) - th.AssertEquals(t, n.Name, "private-network") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.TenantID, "4fd44f30292945e481c7b8a0c8908869") - th.AssertEquals(t, n.Shared, true) - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "sample_network", - "admin_state_up": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [], - "name": "net1", - "admin_state_up": true, - "tenant_id": "9bacb3c5d39d41a79512987f338cf177", - "shared": false, - "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - } -} - `) - }) - - iTrue := true - options := CreateOpts{Name: "sample_network", AdminStateUp: &iTrue} - n, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.Subnets, []string{}) - th.AssertEquals(t, n.Name, "net1") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.TenantID, "9bacb3c5d39d41a79512987f338cf177") - th.AssertEquals(t, n.Shared, false) - th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") -} - -func TestCreateWithOptionalFields(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "sample_network", - "admin_state_up": true, - "shared": true, - "tenant_id": "12345" - } -} - `) - - w.WriteHeader(http.StatusCreated) - }) - - iTrue := true - options := CreateOpts{Name: "sample_network", AdminStateUp: &iTrue, Shared: &iTrue, TenantID: "12345"} - _, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "new_network_name", - "admin_state_up": false, - "shared": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [], - "name": "new_network_name", - "admin_state_up": false, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - } -} - `) - }) - - iTrue, iFalse := true, false - options := UpdateOpts{Name: "new_network_name", AdminStateUp: &iFalse, Shared: &iTrue} - n, err := Update(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Name, "new_network_name") - th.AssertEquals(t, n.AdminStateUp, false) - th.AssertEquals(t, n.Shared, true) - th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls_test.go deleted file mode 100644 index caf77dbe04..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package networks - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint, ResourceBase: endpoint + "v2.0/"} -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "v2.0/networks/foo" - th.AssertEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "v2.0/networks" - th.AssertEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "v2.0/networks" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "v2.0/networks/foo" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go deleted file mode 100644 index 06d273ef19..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go +++ /dev/null @@ -1,244 +0,0 @@ -package ports - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// AdminState gives users a solid type to work with for create and update -// operations. It is recommended that users use the `Up` and `Down` enums. -type AdminState *bool - -// Convenience vars for AdminStateUp values. -var ( - iTrue = true - iFalse = false - - Up AdminState = &iTrue - Down AdminState = &iFalse -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToPortListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the port attributes you want to see returned. SortKey allows you to sort -// by a particular port attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Status string `q:"status"` - Name string `q:"name"` - AdminStateUp *bool `q:"admin_state_up"` - NetworkID string `q:"network_id"` - TenantID string `q:"tenant_id"` - DeviceOwner string `q:"device_owner"` - MACAddress string `q:"mac_address"` - ID string `q:"id"` - DeviceID string `q:"device_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// ToPortListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToPortListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List returns a Pager which allows you to iterate over a collection of -// ports. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those ports that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToPortListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return PortPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific port based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type CreateOptsBuilder interface { - ToPortCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents the attributes used when creating a new port. -type CreateOpts struct { - NetworkID string - Name string - AdminStateUp *bool - MACAddress string - FixedIPs interface{} - DeviceID string - DeviceOwner string - TenantID string - SecurityGroups []string -} - -// ToPortCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) { - p := make(map[string]interface{}) - - if opts.NetworkID == "" { - return nil, errNetworkIDRequired - } - p["network_id"] = opts.NetworkID - - if opts.DeviceID != "" { - p["device_id"] = opts.DeviceID - } - if opts.DeviceOwner != "" { - p["device_owner"] = opts.DeviceOwner - } - if opts.FixedIPs != nil { - p["fixed_ips"] = opts.FixedIPs - } - if opts.SecurityGroups != nil { - p["security_groups"] = opts.SecurityGroups - } - if opts.TenantID != "" { - p["tenant_id"] = opts.TenantID - } - if opts.AdminStateUp != nil { - p["admin_state_up"] = &opts.AdminStateUp - } - if opts.Name != "" { - p["name"] = opts.Name - } - if opts.MACAddress != "" { - p["mac_address"] = opts.MACAddress - } - - return map[string]interface{}{"port": p}, nil -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. You must remember to provide a NetworkID value. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToPortCreateMap() - if err != nil { - res.Err = err - return res - } - - // Response - _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// UpdateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Update operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type UpdateOptsBuilder interface { - ToPortUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents the attributes used when updating an existing port. -type UpdateOpts struct { - Name string - AdminStateUp *bool - FixedIPs interface{} - DeviceID string - DeviceOwner string - SecurityGroups []string -} - -// ToPortUpdateMap casts an UpdateOpts struct to a map. -func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { - p := make(map[string]interface{}) - - if opts.DeviceID != "" { - p["device_id"] = opts.DeviceID - } - if opts.DeviceOwner != "" { - p["device_owner"] = opts.DeviceOwner - } - if opts.FixedIPs != nil { - p["fixed_ips"] = opts.FixedIPs - } - if opts.SecurityGroups != nil { - p["security_groups"] = opts.SecurityGroups - } - if opts.AdminStateUp != nil { - p["admin_state_up"] = &opts.AdminStateUp - } - if opts.Name != "" { - p["name"] = opts.Name - } - - return map[string]interface{}{"port": p}, nil -} - -// Update accepts a UpdateOpts struct and updates an existing port using the -// values provided. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToPortUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201}, - }) - return res -} - -// Delete accepts a unique ID and deletes the port associated with it. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests_test.go deleted file mode 100644 index 9e323efa3a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests_test.go +++ /dev/null @@ -1,321 +0,0 @@ -package ports - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "ports": [ - { - "status": "ACTIVE", - "binding:host_id": "devstack", - "name": "", - "admin_state_up": true, - "network_id": "70c1db1f-b701-45bd-96e0-a313ee3430b3", - "tenant_id": "", - "device_owner": "network:router_gateway", - "mac_address": "fa:16:3e:58:42:ed", - "fixed_ips": [ - { - "subnet_id": "008ba151-0b8c-4a67-98b5-0d2b87666062", - "ip_address": "172.24.4.2" - } - ], - "id": "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b", - "security_groups": [], - "device_id": "9ae135f4-b6e0-4dad-9e91-3c223e385824" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractPorts(page) - if err != nil { - t.Errorf("Failed to extract subnets: %v", err) - return false, nil - } - - expected := []Port{ - Port{ - Status: "ACTIVE", - Name: "", - AdminStateUp: true, - NetworkID: "70c1db1f-b701-45bd-96e0-a313ee3430b3", - TenantID: "", - DeviceOwner: "network:router_gateway", - MACAddress: "fa:16:3e:58:42:ed", - FixedIPs: []IP{ - IP{ - SubnetID: "008ba151-0b8c-4a67-98b5-0d2b87666062", - IPAddress: "172.24.4.2", - }, - }, - ID: "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b", - SecurityGroups: []string{}, - DeviceID: "9ae135f4-b6e0-4dad-9e91-3c223e385824", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "port": { - "status": "ACTIVE", - "name": "", - "admin_state_up": true, - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "tenant_id": "7e02058126cc4950b75f9970368ba177", - "device_owner": "network:router_interface", - "mac_address": "fa:16:3e:23:fd:d7", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.1" - } - ], - "id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", - "security_groups": [], - "device_id": "5e3898d7-11be-483e-9732-b2f5eccd2b2e" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertEquals(t, n.Name, "") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") - th.AssertEquals(t, n.TenantID, "7e02058126cc4950b75f9970368ba177") - th.AssertEquals(t, n.DeviceOwner, "network:router_interface") - th.AssertEquals(t, n.MACAddress, "fa:16:3e:23:fd:d7") - th.AssertDeepEquals(t, n.FixedIPs, []IP{ - IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.1"}, - }) - th.AssertEquals(t, n.ID, "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2") - th.AssertDeepEquals(t, n.SecurityGroups, []string{}) - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertEquals(t, n.DeviceID, "5e3898d7-11be-483e-9732-b2f5eccd2b2e") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "port": { - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "name": "private-port", - "admin_state_up": true, - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.2" - } - ], - "security_groups": ["foo"] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "port": { - "status": "DOWN", - "name": "private-port", - "allowed_address_pairs": [], - "admin_state_up": true, - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", - "device_owner": "", - "mac_address": "fa:16:3e:c9:cb:f0", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.2" - } - ], - "id": "65c0ee9f-d634-4522-8954-51021b570b0d", - "security_groups": [ - "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ], - "device_id": "" - } -} - `) - }) - - asu := true - options := CreateOpts{ - Name: "private-port", - AdminStateUp: &asu, - NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7", - FixedIPs: []IP{ - IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, - }, - SecurityGroups: []string{"foo"}, - } - n, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "DOWN") - th.AssertEquals(t, n.Name, "private-port") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") - th.AssertEquals(t, n.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa") - th.AssertEquals(t, n.DeviceOwner, "") - th.AssertEquals(t, n.MACAddress, "fa:16:3e:c9:cb:f0") - th.AssertDeepEquals(t, n.FixedIPs, []IP{ - IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, - }) - th.AssertEquals(t, n.ID, "65c0ee9f-d634-4522-8954-51021b570b0d") - th.AssertDeepEquals(t, n.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}) -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "port": { - "name": "new_port_name", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.3" - } - ], - "security_groups": [ - "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "port": { - "status": "DOWN", - "name": "new_port_name", - "admin_state_up": true, - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", - "device_owner": "", - "mac_address": "fa:16:3e:c9:cb:f0", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.3" - } - ], - "id": "65c0ee9f-d634-4522-8954-51021b570b0d", - "security_groups": [ - "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ], - "device_id": "" - } -} - `) - }) - - options := UpdateOpts{ - Name: "new_port_name", - FixedIPs: []IP{ - IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"}, - }, - SecurityGroups: []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}, - } - - s, err := Update(fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "new_port_name") - th.AssertDeepEquals(t, s.FixedIPs, []IP{ - IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"}, - }) - th.AssertDeepEquals(t, s.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls_test.go deleted file mode 100644 index 7fadd4dcb7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package ports - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint, ResourceBase: endpoint + "v2.0/"} -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "v2.0/ports" - th.AssertEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "v2.0/ports/foo" - th.AssertEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "v2.0/ports" - th.AssertEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo") - expected := endpoint + "v2.0/ports/foo" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "v2.0/ports/foo" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/doc.go deleted file mode 100644 index 43e8296c7f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package subnets contains functionality for working with Neutron subnet -// resources. A subnet represents an IP address block that can be used to -// assign IP addresses to virtual instances. Each subnet must have a CIDR and -// must be associated with a network. IPs can either be selected from the whole -// subnet CIDR or from allocation pools specified by the user. -// -// A subnet can also have a gateway, a list of DNS name servers, and host routes. -// This information is pushed to instances whose interfaces are associated with -// the subnet. -package subnets diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/errors.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/errors.go deleted file mode 100644 index 0db0a6e604..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/errors.go +++ /dev/null @@ -1,13 +0,0 @@ -package subnets - -import "fmt" - -func err(str string) error { - return fmt.Errorf("%s", str) -} - -var ( - errNetworkIDRequired = err("A network ID is required") - errCIDRRequired = err("A valid CIDR is required") - errInvalidIPType = err("An IP type must either be 4 or 6") -) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go deleted file mode 100644 index cd7c663c2d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go +++ /dev/null @@ -1,254 +0,0 @@ -package subnets - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// AdminState gives users a solid type to work with for create and update -// operations. It is recommended that users use the `Up` and `Down` enums. -type AdminState *bool - -// Convenience vars for AdminStateUp values. -var ( - iTrue = true - iFalse = false - - Up AdminState = &iTrue - Down AdminState = &iFalse -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToSubnetListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the subnet attributes you want to see returned. SortKey allows you to sort -// by a particular subnet attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Name string `q:"name"` - EnableDHCP *bool `q:"enable_dhcp"` - NetworkID string `q:"network_id"` - TenantID string `q:"tenant_id"` - IPVersion int `q:"ip_version"` - GatewayIP string `q:"gateway_ip"` - CIDR string `q:"cidr"` - ID string `q:"id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// ToSubnetListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToSubnetListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List returns a Pager which allows you to iterate over a collection of -// subnets. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those subnets that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToSubnetListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return SubnetPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific subnet based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// Valid IP types -const ( - IPv4 = 4 - IPv6 = 6 -) - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type CreateOptsBuilder interface { - ToSubnetCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents the attributes used when creating a new subnet. -type CreateOpts struct { - // Required - NetworkID string - CIDR string - // Optional - Name string - TenantID string - AllocationPools []AllocationPool - GatewayIP string - IPVersion int - EnableDHCP *bool - DNSNameservers []string - HostRoutes []HostRoute -} - -// ToSubnetCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) { - s := make(map[string]interface{}) - - if opts.NetworkID == "" { - return nil, errNetworkIDRequired - } - if opts.CIDR == "" { - return nil, errCIDRRequired - } - if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 { - return nil, errInvalidIPType - } - - s["network_id"] = opts.NetworkID - s["cidr"] = opts.CIDR - - if opts.EnableDHCP != nil { - s["enable_dhcp"] = &opts.EnableDHCP - } - if opts.Name != "" { - s["name"] = opts.Name - } - if opts.GatewayIP != "" { - s["gateway_ip"] = opts.GatewayIP - } - if opts.TenantID != "" { - s["tenant_id"] = opts.TenantID - } - if opts.IPVersion != 0 { - s["ip_version"] = opts.IPVersion - } - if len(opts.AllocationPools) != 0 { - s["allocation_pools"] = opts.AllocationPools - } - if len(opts.DNSNameservers) != 0 { - s["dns_nameservers"] = opts.DNSNameservers - } - if len(opts.HostRoutes) != 0 { - s["host_routes"] = opts.HostRoutes - } - - return map[string]interface{}{"subnet": s}, nil -} - -// Create accepts a CreateOpts struct and creates a new subnet using the values -// provided. You must remember to provide a valid NetworkID, CIDR and IP version. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToSubnetCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{201}, - }) - - return res -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToSubnetUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents the attributes used when updating an existing subnet. -type UpdateOpts struct { - Name string - GatewayIP string - DNSNameservers []string - HostRoutes []HostRoute - EnableDHCP *bool -} - -// ToSubnetUpdateMap casts an UpdateOpts struct to a map. -func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { - s := make(map[string]interface{}) - - if opts.EnableDHCP != nil { - s["enable_dhcp"] = &opts.EnableDHCP - } - if opts.Name != "" { - s["name"] = opts.Name - } - if opts.GatewayIP != "" { - s["gateway_ip"] = opts.GatewayIP - } - if len(opts.DNSNameservers) != 0 { - s["dns_nameservers"] = opts.DNSNameservers - } - if len(opts.HostRoutes) != 0 { - s["host_routes"] = opts.HostRoutes - } - - return map[string]interface{}{"subnet": s}, nil -} - -// Update accepts a UpdateOpts struct and updates an existing subnet using the -// values provided. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToSubnetUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201}, - }) - - return res -} - -// Delete accepts a unique ID and deletes the subnet associated with it. -func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests_test.go deleted file mode 100644 index 987064ada6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests_test.go +++ /dev/null @@ -1,362 +0,0 @@ -package subnets - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/rackspace/gophercloud/openstack/networking/v2/common" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "subnets": [ - { - "name": "private-subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - }, - { - "name": "my_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.0.0.2", - "end": "192.255.255.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.0.0.1", - "cidr": "192.0.0.0/8", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractSubnets(page) - if err != nil { - t.Errorf("Failed to extract subnets: %v", err) - return false, nil - } - - expected := []Subnet{ - Subnet{ - Name: "private-subnet", - EnableDHCP: true, - NetworkID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", - DNSNameservers: []string{}, - AllocationPools: []AllocationPool{ - AllocationPool{ - Start: "10.0.0.2", - End: "10.0.0.254", - }, - }, - HostRoutes: []HostRoute{}, - IPVersion: 4, - GatewayIP: "10.0.0.1", - CIDR: "10.0.0.0/24", - ID: "08eae331-0402-425a-923c-34f7cfe39c1b", - }, - Subnet{ - Name: "my_subnet", - EnableDHCP: true, - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - TenantID: "4fd44f30292945e481c7b8a0c8908869", - DNSNameservers: []string{}, - AllocationPools: []AllocationPool{ - AllocationPool{ - Start: "192.0.0.2", - End: "192.255.255.254", - }, - }, - HostRoutes: []HostRoute{}, - IPVersion: 4, - GatewayIP: "192.0.0.1", - CIDR: "192.0.0.0/8", - ID: "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets/54d6f61d-db07-451c-9ab3-b9609b6b6f0b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "subnet": { - "name": "my_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.0.0.2", - "end": "192.255.255.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.0.0.1", - "cidr": "192.0.0.0/8", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - } -} - `) - }) - - s, err := Get(fake.ServiceClient(), "54d6f61d-db07-451c-9ab3-b9609b6b6f0b").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "my_subnet") - th.AssertEquals(t, s.EnableDHCP, true) - th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") - th.AssertDeepEquals(t, s.DNSNameservers, []string{}) - th.AssertDeepEquals(t, s.AllocationPools, []AllocationPool{ - AllocationPool{ - Start: "192.0.0.2", - End: "192.255.255.254", - }, - }) - th.AssertDeepEquals(t, s.HostRoutes, []HostRoute{}) - th.AssertEquals(t, s.IPVersion, 4) - th.AssertEquals(t, s.GatewayIP, "192.0.0.1") - th.AssertEquals(t, s.CIDR, "192.0.0.0/8") - th.AssertEquals(t, s.ID, "54d6f61d-db07-451c-9ab3-b9609b6b6f0b") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "ip_version": 4, - "cidr": "192.168.199.0/24", - "dns_nameservers": ["foo"], - "allocation_pools": [ - { - "start": "192.168.199.2", - "end": "192.168.199.254" - } - ], - "host_routes": [{"destination":"","nexthop": "bar"}] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "subnet": { - "name": "", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.168.199.2", - "end": "192.168.199.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.168.199.1", - "cidr": "192.168.199.0/24", - "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126" - } -} - `) - }) - - opts := CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - IPVersion: 4, - CIDR: "192.168.199.0/24", - AllocationPools: []AllocationPool{ - AllocationPool{ - Start: "192.168.199.2", - End: "192.168.199.254", - }, - }, - DNSNameservers: []string{"foo"}, - HostRoutes: []HostRoute{ - HostRoute{NextHop: "bar"}, - }, - } - s, err := Create(fake.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "") - th.AssertEquals(t, s.EnableDHCP, true) - th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") - th.AssertDeepEquals(t, s.DNSNameservers, []string{}) - th.AssertDeepEquals(t, s.AllocationPools, []AllocationPool{ - AllocationPool{ - Start: "192.168.199.2", - End: "192.168.199.254", - }, - }) - th.AssertDeepEquals(t, s.HostRoutes, []HostRoute{}) - th.AssertEquals(t, s.IPVersion, 4) - th.AssertEquals(t, s.GatewayIP, "192.168.199.1") - th.AssertEquals(t, s.CIDR, "192.168.199.0/24") - th.AssertEquals(t, s.ID, "3b80198d-4f7b-4f77-9ef5-774d54e17126") -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - - res = Create(fake.ServiceClient(), CreateOpts{NetworkID: "foo"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - - res = Create(fake.ServiceClient(), CreateOpts{NetworkID: "foo", CIDR: "bar", IPVersion: 40}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "subnet": { - "name": "my_new_subnet", - "dns_nameservers": ["foo"], - "host_routes": [{"destination":"","nexthop": "bar"}] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } -} - `) - }) - - opts := UpdateOpts{ - Name: "my_new_subnet", - DNSNameservers: []string{"foo"}, - HostRoutes: []HostRoute{ - HostRoute{NextHop: "bar"}, - }, - } - s, err := Update(fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "my_new_subnet") - th.AssertEquals(t, s.ID, "08eae331-0402-425a-923c-34f7cfe39c1b") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go deleted file mode 100644 index 1910f17dd9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go +++ /dev/null @@ -1,132 +0,0 @@ -package subnets - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a subnet resource. -func (r commonResult) Extract() (*Subnet, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Subnet *Subnet `json:"subnet"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Subnet, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// AllocationPool represents a sub-range of cidr available for dynamic -// allocation to ports, e.g. {Start: "10.0.0.2", End: "10.0.0.254"} -type AllocationPool struct { - Start string `json:"start"` - End string `json:"end"` -} - -// HostRoute represents a route that should be used by devices with IPs from -// a subnet (not including local subnet route). -type HostRoute struct { - DestinationCIDR string `json:"destination"` - NextHop string `json:"nexthop"` -} - -// Subnet represents a subnet. See package documentation for a top-level -// description of what this is. -type Subnet struct { - // UUID representing the subnet - ID string `mapstructure:"id" json:"id"` - // UUID of the parent network - NetworkID string `mapstructure:"network_id" json:"network_id"` - // Human-readable name for the subnet. Might not be unique. - Name string `mapstructure:"name" json:"name"` - // IP version, either `4' or `6' - IPVersion int `mapstructure:"ip_version" json:"ip_version"` - // CIDR representing IP range for this subnet, based on IP version - CIDR string `mapstructure:"cidr" json:"cidr"` - // Default gateway used by devices in this subnet - GatewayIP string `mapstructure:"gateway_ip" json:"gateway_ip"` - // DNS name servers used by hosts in this subnet. - DNSNameservers []string `mapstructure:"dns_nameservers" json:"dns_nameservers"` - // Sub-ranges of CIDR available for dynamic allocation to ports. See AllocationPool. - AllocationPools []AllocationPool `mapstructure:"allocation_pools" json:"allocation_pools"` - // Routes that should be used by devices with IPs from this subnet (not including local subnet route). - HostRoutes []HostRoute `mapstructure:"host_routes" json:"host_routes"` - // Specifies whether DHCP is enabled for this subnet or not. - EnableDHCP bool `mapstructure:"enable_dhcp" json:"enable_dhcp"` - // Owner of network. Only admin users can specify a tenant_id other than its own. - TenantID string `mapstructure:"tenant_id" json:"tenant_id"` -} - -// SubnetPage is the page returned by a pager when traversing over a collection -// of subnets. -type SubnetPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of subnets has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (p SubnetPage) NextPageURL() (string, error) { - type resp struct { - Links []gophercloud.Link `mapstructure:"subnets_links"` - } - - var r resp - err := mapstructure.Decode(p.Body, &r) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(r.Links) -} - -// IsEmpty checks whether a SubnetPage struct is empty. -func (p SubnetPage) IsEmpty() (bool, error) { - is, err := ExtractSubnets(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct, -// and extracts the elements into a slice of Subnet structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractSubnets(page pagination.Page) ([]Subnet, error) { - var resp struct { - Subnets []Subnet `mapstructure:"subnets" json:"subnets"` - } - - err := mapstructure.Decode(page.(SubnetPage).Body, &resp) - - return resp.Subnets, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/urls.go deleted file mode 100644 index 0d02368941..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package subnets - -import "github.com/rackspace/gophercloud" - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("subnets", id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("subnets") -} - -func listURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func createURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/urls_test.go deleted file mode 100644 index aeeddf3549..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/urls_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package subnets - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint, ResourceBase: endpoint + "v2.0/"} -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint + "v2.0/subnets" - th.AssertEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "v2.0/subnets/foo" - th.AssertEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "v2.0/subnets" - th.AssertEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo") - expected := endpoint + "v2.0/subnets/foo" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "v2.0/subnets/foo" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/doc.go deleted file mode 100644 index f5f894a9e5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package accounts contains functionality for working with Object Storage -// account resources. An account is the top-level resource the object storage -// hierarchy: containers belong to accounts, objects belong to containers. -// -// Another way of thinking of an account is like a namespace for all your -// resources. It is synonymous with a project or tenant in other OpenStack -// services. -package accounts diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/fixtures.go deleted file mode 100644 index 3dad0c5a9b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/fixtures.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build fixtures - -package accounts - -import ( - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -// HandleGetAccountSuccessfully creates an HTTP handler at `/` on the test handler mux that -// responds with a `Get` response. -func HandleGetAccountSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "X-Account-Meta-Gophercloud-Test", "accounts") - - w.Header().Set("X-Account-Container-Count", "2") - w.Header().Set("X-Account-Bytes-Used", "14") - w.Header().Set("X-Account-Meta-Subject", "books") - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateAccountSuccessfully creates an HTTP handler at `/` on the test handler mux that -// responds with a `Update` response. -func HandleUpdateAccountSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.Header().Set("X-Account-Meta-Foo", "bar") - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go deleted file mode 100644 index e6f5f9594c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go +++ /dev/null @@ -1,106 +0,0 @@ -package accounts - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -// GetOptsBuilder allows extensions to add additional headers to the Get -// request. -type GetOptsBuilder interface { - ToAccountGetMap() (map[string]string, error) -} - -// GetOpts is a structure that contains parameters for getting an account's -// metadata. -type GetOpts struct { - Newest bool `h:"X-Newest"` -} - -// ToAccountGetMap formats a GetOpts into a map[string]string of headers. -func (opts GetOpts) ToAccountGetMap() (map[string]string, error) { - return gophercloud.BuildHeaders(opts) -} - -// Get is a function that retrieves an account's metadata. To extract just the -// custom metadata, call the ExtractMetadata method on the GetResult. To extract -// all the headers that are returned (including the metadata), call the -// ExtractHeader method on the GetResult. -func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult { - var res GetResult - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, err := opts.ToAccountGetMap() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - } - - resp, err := perigee.Request("HEAD", getURL(c), perigee.Options{ - MoreHeaders: h, - OkCodes: []int{204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// UpdateOptsBuilder allows extensions to add additional headers to the Update -// request. -type UpdateOptsBuilder interface { - ToAccountUpdateMap() (map[string]string, error) -} - -// UpdateOpts is a structure that contains parameters for updating, creating, or -// deleting an account's metadata. -type UpdateOpts struct { - Metadata map[string]string - ContentType string `h:"Content-Type"` - DetectContentType bool `h:"X-Detect-Content-Type"` - TempURLKey string `h:"X-Account-Meta-Temp-URL-Key"` - TempURLKey2 string `h:"X-Account-Meta-Temp-URL-Key-2"` -} - -// ToAccountUpdateMap formats an UpdateOpts into a map[string]string of headers. -func (opts UpdateOpts) ToAccountUpdateMap() (map[string]string, error) { - headers, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - headers["X-Account-Meta-"+k] = v - } - return headers, err -} - -// Update is a function that creates, updates, or deletes an account's metadata. -// To extract the headers returned, call the Extract method on the UpdateResult. -func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, err := opts.ToAccountUpdateMap() - if err != nil { - res.Err = err - return res - } - for k, v := range headers { - h[k] = v - } - } - - resp, err := perigee.Request("POST", updateURL(c), perigee.Options{ - MoreHeaders: h, - OkCodes: []int{204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests_test.go deleted file mode 100644 index d6dc26b650..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package accounts - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -var metadata = map[string]string{"gophercloud-test": "accounts"} - -func TestUpdateAccount(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAccountSuccessfully(t) - - options := &UpdateOpts{Metadata: map[string]string{"gophercloud-test": "accounts"}} - res := Update(fake.ServiceClient(), options) - th.AssertNoErr(t, res.Err) -} - -func TestGetAccount(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateAccountSuccessfully(t) - - expected := map[string]string{"Foo": "bar"} - actual, err := Get(fake.ServiceClient(), &GetOpts{}).ExtractMetadata() - if err != nil { - t.Fatalf("Unable to get account metadata: %v", err) - } - th.CheckDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/results.go deleted file mode 100644 index abae02659c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/results.go +++ /dev/null @@ -1,34 +0,0 @@ -package accounts - -import ( - "strings" - - "github.com/rackspace/gophercloud" -) - -// GetResult is returned from a call to the Get function. -type GetResult struct { - gophercloud.HeaderResult -} - -// ExtractMetadata is a function that takes a GetResult (of type *http.Response) -// and returns the custom metatdata associated with the account. -func (gr GetResult) ExtractMetadata() (map[string]string, error) { - if gr.Err != nil { - return nil, gr.Err - } - - metadata := make(map[string]string) - for k, v := range gr.Header { - if strings.HasPrefix(k, "X-Account-Meta-") { - key := strings.TrimPrefix(k, "X-Account-Meta-") - metadata[key] = v[0] - } - } - return metadata, nil -} - -// UpdateResult is returned from a call to the Update function. -type UpdateResult struct { - gophercloud.HeaderResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/urls.go deleted file mode 100644 index 9952fe4345..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package accounts - -import "github.com/rackspace/gophercloud" - -func getURL(c *gophercloud.ServiceClient) string { - return c.Endpoint -} - -func updateURL(c *gophercloud.ServiceClient) string { - return getURL(c) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/urls_test.go deleted file mode 100644 index 074d52dfd5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package accounts - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient()) - expected := endpoint - th.CheckEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient()) - expected := endpoint - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/doc.go deleted file mode 100644 index 5fed5537f1..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package containers contains functionality for working with Object Storage -// container resources. A container serves as a logical namespace for objects -// that are placed inside it - an object with the same name in two different -// containers represents two different objects. -// -// In addition to containing objects, you can also use the container to control -// access to objects by using an access control list (ACL). -package containers diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/fixtures.go deleted file mode 100644 index 1c0a915cb7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/fixtures.go +++ /dev/null @@ -1,132 +0,0 @@ -// +build fixtures - -package containers - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -// ExpectedListInfo is the result expected from a call to `List` when full -// info is requested. -var ExpectedListInfo = []Container{ - Container{ - Count: 0, - Bytes: 0, - Name: "janeausten", - }, - Container{ - Count: 1, - Bytes: 14, - Name: "marktwain", - }, -} - -// ExpectedListNames is the result expected from a call to `List` when just -// container names are requested. -var ExpectedListNames = []string{"janeausten", "marktwain"} - -// HandleListContainerInfoSuccessfully creates an HTTP handler at `/` on the test handler mux that -// responds with a `List` response when full info is requested. -func HandleListContainerInfoSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - w.Header().Set("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, `[ - { - "count": 0, - "bytes": 0, - "name": "janeausten" - }, - { - "count": 1, - "bytes": 14, - "name": "marktwain" - } - ]`) - case "marktwain": - fmt.Fprintf(w, `[]`) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) -} - -// HandleListContainerNamesSuccessfully creates an HTTP handler at `/` on the test handler mux that -// responds with a `ListNames` response when only container names are requested. -func HandleListContainerNamesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "text/plain") - - w.Header().Set("Content-Type", "text/plain") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, "janeausten\nmarktwain\n") - case "marktwain": - fmt.Fprintf(w, ``) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) -} - -// HandleCreateContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that -// responds with a `Create` response. -func HandleCreateContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - w.Header().Add("X-Container-Meta-Foo", "bar") - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleDeleteContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that -// responds with a `Delete` response. -func HandleDeleteContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that -// responds with a `Update` response. -func HandleUpdateContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleGetContainerSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that -// responds with a `Get` response. -func HandleGetContainerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go deleted file mode 100644 index 9f3b2af0a6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go +++ /dev/null @@ -1,204 +0,0 @@ -package containers - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToContainerListParams() (bool, string, error) -} - -// ListOpts is a structure that holds options for listing containers. -type ListOpts struct { - Full bool - Limit int `q:"limit"` - Marker string `q:"marker"` - EndMarker string `q:"end_marker"` - Format string `q:"format"` - Prefix string `q:"prefix"` - Delimiter string `q:"delimiter"` -} - -// ToContainerListParams formats a ListOpts into a query string and boolean -// representing whether to list complete information for each container. -func (opts ListOpts) ToContainerListParams() (bool, string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return false, "", err - } - return opts.Full, q.String(), nil -} - -// List is a function that retrieves containers associated with the account as -// well as account metadata. It returns a pager which can be iterated with the -// EachPage function. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - headers := map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"} - - url := listURL(c) - if opts != nil { - full, query, err := opts.ToContainerListParams() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - - if full { - headers = map[string]string{"Accept": "application/json", "Content-Type": "application/json"} - } - } - - createPage := func(r pagination.PageResult) pagination.Page { - p := ContainerPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p - return p - } - - pager := pagination.NewPager(c, url, createPage) - pager.Headers = headers - return pager -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToContainerCreateMap() (map[string]string, error) -} - -// CreateOpts is a structure that holds parameters for creating a container. -type CreateOpts struct { - Metadata map[string]string - ContainerRead string `h:"X-Container-Read"` - ContainerSyncTo string `h:"X-Container-Sync-To"` - ContainerSyncKey string `h:"X-Container-Sync-Key"` - ContainerWrite string `h:"X-Container-Write"` - ContentType string `h:"Content-Type"` - DetectContentType bool `h:"X-Detect-Content-Type"` - IfNoneMatch string `h:"If-None-Match"` - VersionsLocation string `h:"X-Versions-Location"` -} - -// ToContainerCreateMap formats a CreateOpts into a map of headers. -func (opts CreateOpts) ToContainerCreateMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Container-Meta-"+k] = v - } - return h, nil -} - -// Create is a function that creates a new container. -func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsBuilder) CreateResult { - var res CreateResult - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, err := opts.ToContainerCreateMap() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - } - - resp, err := perigee.Request("PUT", createURL(c, containerName), perigee.Options{ - MoreHeaders: h, - OkCodes: []int{201, 202, 204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// Delete is a function that deletes a container. -func Delete(c *gophercloud.ServiceClient, containerName string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(c, containerName), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202, 204}, - }) - return res -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToContainerUpdateMap() (map[string]string, error) -} - -// UpdateOpts is a structure that holds parameters for updating, creating, or -// deleting a container's metadata. -type UpdateOpts struct { - Metadata map[string]string - ContainerRead string `h:"X-Container-Read"` - ContainerSyncTo string `h:"X-Container-Sync-To"` - ContainerSyncKey string `h:"X-Container-Sync-Key"` - ContainerWrite string `h:"X-Container-Write"` - ContentType string `h:"Content-Type"` - DetectContentType bool `h:"X-Detect-Content-Type"` - RemoveVersionsLocation string `h:"X-Remove-Versions-Location"` - VersionsLocation string `h:"X-Versions-Location"` -} - -// ToContainerUpdateMap formats a CreateOpts into a map of headers. -func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Container-Meta-"+k] = v - } - return h, nil -} - -// Update is a function that creates, updates, or deletes a container's -// metadata. -func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, err := opts.ToContainerUpdateMap() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - } - - resp, err := perigee.Request("POST", updateURL(c, containerName), perigee.Options{ - MoreHeaders: h, - OkCodes: []int{202, 204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// Get is a function that retrieves the metadata of a container. To extract just -// the custom metadata, pass the GetResult response to the ExtractMetadata -// function. -func Get(c *gophercloud.ServiceClient, containerName string) GetResult { - var res GetResult - resp, err := perigee.Request("HEAD", getURL(c, containerName), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{200, 204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests_test.go deleted file mode 100644 index d0ce7f1e58..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package containers - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -var metadata = map[string]string{"gophercloud-test": "containers"} - -func TestListContainerInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainerInfoSuccessfully(t) - - count := 0 - err := List(fake.ServiceClient(), &ListOpts{Full: true}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractInfo(page) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, ExpectedListInfo, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestListContainerNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListContainerNamesSuccessfully(t) - - count := 0 - err := List(fake.ServiceClient(), &ListOpts{Full: false}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNames(page) - if err != nil { - t.Errorf("Failed to extract container names: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedListNames, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestCreateContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateContainerSuccessfully(t) - - options := CreateOpts{ContentType: "application/json", Metadata: map[string]string{"foo": "bar"}} - res := Create(fake.ServiceClient(), "testContainer", options) - th.CheckNoErr(t, res.Err) - th.CheckEquals(t, "bar", res.Header["X-Container-Meta-Foo"][0]) -} - -func TestDeleteContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteContainerSuccessfully(t) - - res := Delete(fake.ServiceClient(), "testContainer") - th.CheckNoErr(t, res.Err) -} - -func TestUpateContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateContainerSuccessfully(t) - - options := &UpdateOpts{Metadata: map[string]string{"foo": "bar"}} - res := Update(fake.ServiceClient(), "testContainer", options) - th.CheckNoErr(t, res.Err) -} - -func TestGetContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetContainerSuccessfully(t) - - _, err := Get(fake.ServiceClient(), "testContainer").ExtractMetadata() - th.CheckNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/results.go deleted file mode 100644 index 74f3286046..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/results.go +++ /dev/null @@ -1,139 +0,0 @@ -package containers - -import ( - "fmt" - "strings" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// Container represents a container resource. -type Container struct { - // The total number of bytes stored in the container. - Bytes int `json:"bytes" mapstructure:"bytes"` - - // The total number of objects stored in the container. - Count int `json:"count" mapstructure:"count"` - - // The name of the container. - Name string `json:"name" mapstructure:"name"` -} - -// ContainerPage is the page returned by a pager when traversing over a -// collection of containers. -type ContainerPage struct { - pagination.MarkerPageBase -} - -// IsEmpty returns true if a ListResult contains no container names. -func (r ContainerPage) IsEmpty() (bool, error) { - names, err := ExtractNames(r) - if err != nil { - return true, err - } - return len(names) == 0, nil -} - -// LastMarker returns the last container name in a ListResult. -func (r ContainerPage) LastMarker() (string, error) { - names, err := ExtractNames(r) - if err != nil { - return "", err - } - if len(names) == 0 { - return "", nil - } - return names[len(names)-1], nil -} - -// ExtractInfo is a function that takes a ListResult and returns the containers' information. -func ExtractInfo(page pagination.Page) ([]Container, error) { - untyped := page.(ContainerPage).Body.([]interface{}) - results := make([]Container, len(untyped)) - for index, each := range untyped { - container := each.(map[string]interface{}) - err := mapstructure.Decode(container, &results[index]) - if err != nil { - return results, err - } - } - return results, nil -} - -// ExtractNames is a function that takes a ListResult and returns the containers' names. -func ExtractNames(page pagination.Page) ([]string, error) { - casted := page.(ContainerPage) - ct := casted.Header.Get("Content-Type") - - switch { - case strings.HasPrefix(ct, "application/json"): - parsed, err := ExtractInfo(page) - if err != nil { - return nil, err - } - - names := make([]string, 0, len(parsed)) - for _, container := range parsed { - names = append(names, container.Name) - } - return names, nil - case strings.HasPrefix(ct, "text/plain"): - names := make([]string, 0, 50) - - body := string(page.(ContainerPage).Body.([]uint8)) - for _, name := range strings.Split(body, "\n") { - if len(name) > 0 { - names = append(names, name) - } - } - - return names, nil - default: - return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct) - } -} - -// GetResult represents the result of a get operation. -type GetResult struct { - gophercloud.HeaderResult -} - -// ExtractMetadata is a function that takes a GetResult (of type *http.Response) -// and returns the custom metadata associated with the container. -func (gr GetResult) ExtractMetadata() (map[string]string, error) { - if gr.Err != nil { - return nil, gr.Err - } - metadata := make(map[string]string) - for k, v := range gr.Header { - if strings.HasPrefix(k, "X-Container-Meta-") { - key := strings.TrimPrefix(k, "X-Container-Meta-") - metadata[key] = v[0] - } - } - return metadata, nil -} - -// CreateResult represents the result of a create operation. To extract the -// the headers from the HTTP response, you can invoke the 'ExtractHeader' -// method on the result struct. -type CreateResult struct { - gophercloud.HeaderResult -} - -// UpdateResult represents the result of an update operation. To extract the -// the headers from the HTTP response, you can invoke the 'ExtractHeader' -// method on the result struct. -type UpdateResult struct { - gophercloud.HeaderResult -} - -// DeleteResult represents the result of a delete operation. To extract the -// the headers from the HTTP response, you can invoke the 'ExtractHeader' -// method on the result struct. -type DeleteResult struct { - gophercloud.HeaderResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/urls.go deleted file mode 100644 index f864f846eb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package containers - -import "github.com/rackspace/gophercloud" - -func listURL(c *gophercloud.ServiceClient) string { - return c.Endpoint -} - -func createURL(c *gophercloud.ServiceClient, container string) string { - return c.ServiceURL(container) -} - -func getURL(c *gophercloud.ServiceClient, container string) string { - return createURL(c, container) -} - -func deleteURL(c *gophercloud.ServiceClient, container string) string { - return createURL(c, container) -} - -func updateURL(c *gophercloud.ServiceClient, container string) string { - return createURL(c, container) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/urls_test.go deleted file mode 100644 index d043a2aae5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/urls_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package containers - -import ( - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" - "testing" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient()) - expected := endpoint - th.CheckEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient(), "foo") - expected := endpoint + "foo" - th.CheckEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "foo" - th.CheckEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "foo" - th.CheckEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo") - expected := endpoint + "foo" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/doc.go deleted file mode 100644 index 30a9adde1c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package objects contains functionality for working with Object Storage -// object resources. An object is a resource that represents and contains data -// - such as documents, images, and so on. You can also store custom metadata -// with an object. -package objects diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go deleted file mode 100644 index d951160e3a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go +++ /dev/null @@ -1,164 +0,0 @@ -// +build fixtures - -package objects - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -// HandleDownloadObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that -// responds with a `Download` response. -func HandleDownloadObjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "Successful download with Gophercloud") - }) -} - -// ExpectedListInfo is the result expected from a call to `List` when full -// info is requested. -var ExpectedListInfo = []Object{ - Object{ - Hash: "451e372e48e0f6b1114fa0724aa79fa1", - LastModified: "2009-11-10 23:00:00 +0000 UTC", - Bytes: 14, - Name: "goodbye", - ContentType: "application/octet-stream", - }, - Object{ - Hash: "451e372e48e0f6b1114fa0724aa79fa1", - LastModified: "2009-11-10 23:00:00 +0000 UTC", - Bytes: 14, - Name: "hello", - ContentType: "application/octet-stream", - }, -} - -// ExpectedListNames is the result expected from a call to `List` when just -// object names are requested. -var ExpectedListNames = []string{"hello", "goodbye"} - -// HandleListObjectsInfoSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that -// responds with a `List` response when full info is requested. -func HandleListObjectsInfoSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - w.Header().Set("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, `[ - { - "hash": "451e372e48e0f6b1114fa0724aa79fa1", - "last_modified": "2009-11-10 23:00:00 +0000 UTC", - "bytes": 14, - "name": "goodbye", - "content_type": "application/octet-stream" - }, - { - "hash": "451e372e48e0f6b1114fa0724aa79fa1", - "last_modified": "2009-11-10 23:00:00 +0000 UTC", - "bytes": 14, - "name": "hello", - "content_type": "application/octet-stream" - } - ]`) - case "hello": - fmt.Fprintf(w, `[]`) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) -} - -// HandleListObjectNamesSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that -// responds with a `List` response when only object names are requested. -func HandleListObjectNamesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "text/plain") - - w.Header().Set("Content-Type", "text/plain") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, "hello\ngoodbye\n") - case "goodbye": - fmt.Fprintf(w, "") - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) -} - -// HandleCreateObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that -// responds with a `Create` response. -func HandleCreateObjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.WriteHeader(http.StatusCreated) - }) -} - -// HandleCopyObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that -// responds with a `Copy` response. -func HandleCopyObjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "COPY") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Destination", "/newTestContainer/newTestObject") - w.WriteHeader(http.StatusCreated) - }) -} - -// HandleDeleteObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that -// responds with a `Delete` response. -func HandleDeleteObjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that -// responds with a `Update` response. -func HandleUpdateObjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Object-Meta-Gophercloud-Test", "objects") - w.WriteHeader(http.StatusAccepted) - }) -} - -// HandleGetObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that -// responds with a `Get` response. -func HandleGetObjectSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "HEAD") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - w.Header().Add("X-Object-Meta-Gophercloud-Test", "objects") - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go deleted file mode 100644 index 7b96fa2fe5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go +++ /dev/null @@ -1,420 +0,0 @@ -package objects - -import ( - "fmt" - "io" - "time" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToObjectListParams() (bool, string, error) -} - -// ListOpts is a structure that holds parameters for listing objects. -type ListOpts struct { - // Full is a true/false value that represents the amount of object information - // returned. If Full is set to true, then the content-type, number of bytes, hash - // date last modified, and name are returned. If set to false or not set, then - // only the object names are returned. - Full bool - Limit int `q:"limit"` - Marker string `q:"marker"` - EndMarker string `q:"end_marker"` - Format string `q:"format"` - Prefix string `q:"prefix"` - Delimiter string `q:"delimiter"` - Path string `q:"path"` -} - -// ToObjectListParams formats a ListOpts into a query string and boolean -// representing whether to list complete information for each object. -func (opts ListOpts) ToObjectListParams() (bool, string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return false, "", err - } - return opts.Full, q.String(), nil -} - -// List is a function that retrieves all objects in a container. It also returns the details -// for the container. To extract only the object information or names, pass the ListResult -// response to the ExtractInfo or ExtractNames function, respectively. -func List(c *gophercloud.ServiceClient, containerName string, opts ListOptsBuilder) pagination.Pager { - headers := map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"} - - url := listURL(c, containerName) - if opts != nil { - full, query, err := opts.ToObjectListParams() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - - if full { - headers = map[string]string{"Accept": "application/json", "Content-Type": "application/json"} - } - } - - createPage := func(r pagination.PageResult) pagination.Page { - p := ObjectPage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p - return p - } - - pager := pagination.NewPager(c, url, createPage) - pager.Headers = headers - return pager -} - -// DownloadOptsBuilder allows extensions to add additional parameters to the -// Download request. -type DownloadOptsBuilder interface { - ToObjectDownloadParams() (map[string]string, string, error) -} - -// DownloadOpts is a structure that holds parameters for downloading an object. -type DownloadOpts struct { - IfMatch string `h:"If-Match"` - IfModifiedSince time.Time `h:"If-Modified-Since"` - IfNoneMatch string `h:"If-None-Match"` - IfUnmodifiedSince time.Time `h:"If-Unmodified-Since"` - Range string `h:"Range"` - Expires string `q:"expires"` - MultipartManifest string `q:"multipart-manifest"` - Signature string `q:"signature"` -} - -// ToObjectDownloadParams formats a DownloadOpts into a query string and map of -// headers. -func (opts DownloadOpts) ToObjectDownloadParams() (map[string]string, string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return nil, "", err - } - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, q.String(), err - } - return h, q.String(), nil -} - -// Download is a function that retrieves the content and metadata for an object. -// To extract just the content, pass the DownloadResult response to the -// ExtractContent function. -func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts DownloadOptsBuilder) DownloadResult { - var res DownloadResult - - url := downloadURL(c, containerName, objectName) - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, query, err := opts.ToObjectDownloadParams() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - - url += query - } - - resp, err := perigee.Request("GET", url, perigee.Options{ - MoreHeaders: h, - OkCodes: []int{200, 304}, - }) - - res.Body = resp.HttpResponse.Body - res.Err = err - res.Header = resp.HttpResponse.Header - - return res -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToObjectCreateParams() (map[string]string, string, error) -} - -// CreateOpts is a structure that holds parameters for creating an object. -type CreateOpts struct { - Metadata map[string]string - ContentDisposition string `h:"Content-Disposition"` - ContentEncoding string `h:"Content-Encoding"` - ContentLength int64 `h:"Content-Length"` - ContentType string `h:"Content-Type"` - CopyFrom string `h:"X-Copy-From"` - DeleteAfter int `h:"X-Delete-After"` - DeleteAt int `h:"X-Delete-At"` - DetectContentType string `h:"X-Detect-Content-Type"` - ETag string `h:"ETag"` - IfNoneMatch string `h:"If-None-Match"` - ObjectManifest string `h:"X-Object-Manifest"` - TransferEncoding string `h:"Transfer-Encoding"` - Expires string `q:"expires"` - MultipartManifest string `q:"multiple-manifest"` - Signature string `q:"signature"` -} - -// ToObjectCreateParams formats a CreateOpts into a query string and map of -// headers. -func (opts CreateOpts) ToObjectCreateParams() (map[string]string, string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return nil, "", err - } - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, q.String(), err - } - - for k, v := range opts.Metadata { - h["X-Object-Meta-"+k] = v - } - - return h, q.String(), nil -} - -// Create is a function that creates a new object or replaces an existing object. -func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - url := createURL(c, containerName, objectName) - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, query, err := opts.ToObjectCreateParams() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - - url += query - } - - contentType := h["Content-Type"] - - resp, err := perigee.Request("PUT", url, perigee.Options{ - ContentType: contentType, - ReqBody: content, - MoreHeaders: h, - OkCodes: []int{201, 202}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// CopyOptsBuilder allows extensions to add additional parameters to the -// Copy request. -type CopyOptsBuilder interface { - ToObjectCopyMap() (map[string]string, error) -} - -// CopyOpts is a structure that holds parameters for copying one object to -// another. -type CopyOpts struct { - Metadata map[string]string - ContentDisposition string `h:"Content-Disposition"` - ContentEncoding string `h:"Content-Encoding"` - ContentType string `h:"Content-Type"` - Destination string `h:"Destination,required"` -} - -// ToObjectCopyMap formats a CopyOpts into a map of headers. -func (opts CopyOpts) ToObjectCopyMap() (map[string]string, error) { - if opts.Destination == "" { - return nil, fmt.Errorf("Required CopyOpts field 'Destination' not set.") - } - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Object-Meta-"+k] = v - } - return h, nil -} - -// Copy is a function that copies one object to another. -func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts CopyOptsBuilder) CopyResult { - var res CopyResult - h := c.AuthenticatedHeaders() - - headers, err := opts.ToObjectCopyMap() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - - url := copyURL(c, containerName, objectName) - resp, err := perigee.Request("COPY", url, perigee.Options{ - MoreHeaders: h, - OkCodes: []int{201}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// DeleteOptsBuilder allows extensions to add additional parameters to the -// Delete request. -type DeleteOptsBuilder interface { - ToObjectDeleteQuery() (string, error) -} - -// DeleteOpts is a structure that holds parameters for deleting an object. -type DeleteOpts struct { - MultipartManifest string `q:"multipart-manifest"` -} - -// ToObjectDeleteQuery formats a DeleteOpts into a query string. -func (opts DeleteOpts) ToObjectDeleteQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// Delete is a function that deletes an object. -func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts DeleteOptsBuilder) DeleteResult { - var res DeleteResult - url := deleteURL(c, containerName, objectName) - - if opts != nil { - query, err := opts.ToObjectDeleteQuery() - if err != nil { - res.Err = err - return res - } - url += query - } - - resp, err := perigee.Request("DELETE", url, perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// GetOptsBuilder allows extensions to add additional parameters to the -// Get request. -type GetOptsBuilder interface { - ToObjectGetQuery() (string, error) -} - -// GetOpts is a structure that holds parameters for getting an object's metadata. -type GetOpts struct { - Expires string `q:"expires"` - Signature string `q:"signature"` -} - -// ToObjectGetQuery formats a GetOpts into a query string. -func (opts GetOpts) ToObjectGetQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// Get is a function that retrieves the metadata of an object. To extract just the custom -// metadata, pass the GetResult response to the ExtractMetadata function. -func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts GetOptsBuilder) GetResult { - var res GetResult - url := getURL(c, containerName, objectName) - - if opts != nil { - query, err := opts.ToObjectGetQuery() - if err != nil { - res.Err = err - return res - } - url += query - } - - resp, err := perigee.Request("HEAD", url, perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{200, 204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToObjectUpdateMap() (map[string]string, error) -} - -// UpdateOpts is a structure that holds parameters for updating, creating, or deleting an -// object's metadata. -type UpdateOpts struct { - Metadata map[string]string - ContentDisposition string `h:"Content-Disposition"` - ContentEncoding string `h:"Content-Encoding"` - ContentType string `h:"Content-Type"` - DeleteAfter int `h:"X-Delete-After"` - DeleteAt int `h:"X-Delete-At"` - DetectContentType bool `h:"X-Detect-Content-Type"` -} - -// ToObjectUpdateMap formats a UpdateOpts into a map of headers. -func (opts UpdateOpts) ToObjectUpdateMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Object-Meta-"+k] = v - } - return h, nil -} - -// Update is a function that creates, updates, or deletes an object's metadata. -func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, err := opts.ToObjectUpdateMap() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - } - - url := updateURL(c, containerName, objectName) - resp, err := perigee.Request("POST", url, perigee.Options{ - MoreHeaders: h, - OkCodes: []int{202}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go deleted file mode 100644 index c3c28a789b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package objects - -import ( - "bytes" - "io" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestDownloadReader(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDownloadObjectSuccessfully(t) - - response := Download(fake.ServiceClient(), "testContainer", "testObject", nil) - defer response.Body.Close() - - // Check reader - buf := bytes.NewBuffer(make([]byte, 0)) - io.CopyN(buf, response.Body, 10) - th.CheckEquals(t, "Successful", string(buf.Bytes())) -} - -func TestDownloadExtraction(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDownloadObjectSuccessfully(t) - - response := Download(fake.ServiceClient(), "testContainer", "testObject", nil) - - // Check []byte extraction - bytes, err := response.ExtractContent() - th.AssertNoErr(t, err) - th.CheckEquals(t, "Successful download with Gophercloud", string(bytes)) -} - -func TestListObjectInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListObjectsInfoSuccessfully(t) - - count := 0 - options := &ListOpts{Full: true} - err := List(fake.ServiceClient(), "testContainer", options).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractInfo(page) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, ExpectedListInfo, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestListObjectNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListObjectNamesSuccessfully(t) - - count := 0 - options := &ListOpts{Full: false} - err := List(fake.ServiceClient(), "testContainer", options).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNames(page) - if err != nil { - t.Errorf("Failed to extract container names: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedListNames, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestCreateObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateObjectSuccessfully(t) - - content := bytes.NewBufferString("Did gyre and gimble in the wabe") - options := &CreateOpts{ContentType: "application/json"} - res := Create(fake.ServiceClient(), "testContainer", "testObject", content, options) - th.AssertNoErr(t, res.Err) -} - -func TestCopyObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCopyObjectSuccessfully(t) - - options := &CopyOpts{Destination: "/newTestContainer/newTestObject"} - res := Copy(fake.ServiceClient(), "testContainer", "testObject", options) - th.AssertNoErr(t, res.Err) -} - -func TestDeleteObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteObjectSuccessfully(t) - - res := Delete(fake.ServiceClient(), "testContainer", "testObject", nil) - th.AssertNoErr(t, res.Err) -} - -func TestUpateObjectMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateObjectSuccessfully(t) - - options := &UpdateOpts{Metadata: map[string]string{"Gophercloud-Test": "objects"}} - res := Update(fake.ServiceClient(), "testContainer", "testObject", options) - th.AssertNoErr(t, res.Err) -} - -func TestGetObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetObjectSuccessfully(t) - - expected := map[string]string{"Gophercloud-Test": "objects"} - actual, err := Get(fake.ServiceClient(), "testContainer", "testObject", nil).ExtractMetadata() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/results.go deleted file mode 100644 index b51b840c99..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/results.go +++ /dev/null @@ -1,173 +0,0 @@ -package objects - -import ( - "fmt" - "io" - "io/ioutil" - "strings" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// Object is a structure that holds information related to a storage object. -type Object struct { - // Bytes is the total number of bytes that comprise the object. - Bytes int64 `json:"bytes" mapstructure:"bytes"` - - // ContentType is the content type of the object. - ContentType string `json:"content_type" mapstructure:"content_type"` - - // Hash represents the MD5 checksum value of the object's content. - Hash string `json:"hash" mapstructure:"hash"` - - // LastModified is the RFC3339Milli time the object was last modified, represented - // as a string. For any given object (obj), this value may be parsed to a time.Time: - // lastModified, err := time.Parse(gophercloud.RFC3339Milli, obj.LastModified) - LastModified string `json:"last_modified" mapstructure:"last_modified"` - - // Name is the unique name for the object. - Name string `json:"name" mapstructure:"name"` -} - -// ObjectPage is a single page of objects that is returned from a call to the -// List function. -type ObjectPage struct { - pagination.MarkerPageBase -} - -// IsEmpty returns true if a ListResult contains no object names. -func (r ObjectPage) IsEmpty() (bool, error) { - names, err := ExtractNames(r) - if err != nil { - return true, err - } - return len(names) == 0, nil -} - -// LastMarker returns the last object name in a ListResult. -func (r ObjectPage) LastMarker() (string, error) { - names, err := ExtractNames(r) - if err != nil { - return "", err - } - if len(names) == 0 { - return "", nil - } - return names[len(names)-1], nil -} - -// ExtractInfo is a function that takes a page of objects and returns their full information. -func ExtractInfo(page pagination.Page) ([]Object, error) { - untyped := page.(ObjectPage).Body.([]interface{}) - results := make([]Object, len(untyped)) - for index, each := range untyped { - object := each.(map[string]interface{}) - err := mapstructure.Decode(object, &results[index]) - if err != nil { - return results, err - } - } - return results, nil -} - -// ExtractNames is a function that takes a page of objects and returns only their names. -func ExtractNames(page pagination.Page) ([]string, error) { - casted := page.(ObjectPage) - ct := casted.Header.Get("Content-Type") - switch { - case strings.HasPrefix(ct, "application/json"): - parsed, err := ExtractInfo(page) - if err != nil { - return nil, err - } - - names := make([]string, 0, len(parsed)) - for _, object := range parsed { - names = append(names, object.Name) - } - - return names, nil - case strings.HasPrefix(ct, "text/plain"): - names := make([]string, 0, 50) - - body := string(page.(ObjectPage).Body.([]uint8)) - for _, name := range strings.Split(body, "\n") { - if len(name) > 0 { - names = append(names, name) - } - } - - return names, nil - case strings.HasPrefix(ct, "text/html"): - return []string{}, nil - default: - return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct) - } -} - -// DownloadResult is a *http.Response that is returned from a call to the Download function. -type DownloadResult struct { - gophercloud.HeaderResult - Body io.ReadCloser -} - -// ExtractContent is a function that takes a DownloadResult's io.Reader body -// and reads all available data into a slice of bytes. Please be aware that due -// the nature of io.Reader is forward-only - meaning that it can only be read -// once and not rewound. You can recreate a reader from the output of this -// function by using bytes.NewReader(downloadBytes) -func (dr DownloadResult) ExtractContent() ([]byte, error) { - if dr.Err != nil { - return nil, dr.Err - } - body, err := ioutil.ReadAll(dr.Body) - if err != nil { - return nil, err - } - dr.Body.Close() - return body, nil -} - -// GetResult is a *http.Response that is returned from a call to the Get function. -type GetResult struct { - gophercloud.HeaderResult -} - -// ExtractMetadata is a function that takes a GetResult (of type *http.Response) -// and returns the custom metadata associated with the object. -func (gr GetResult) ExtractMetadata() (map[string]string, error) { - if gr.Err != nil { - return nil, gr.Err - } - metadata := make(map[string]string) - for k, v := range gr.Header { - if strings.HasPrefix(k, "X-Object-Meta-") { - key := strings.TrimPrefix(k, "X-Object-Meta-") - metadata[key] = v[0] - } - } - return metadata, nil -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - gophercloud.HeaderResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - gophercloud.HeaderResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.HeaderResult -} - -// CopyResult represents the result of a copy operation. -type CopyResult struct { - gophercloud.HeaderResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/urls.go deleted file mode 100644 index d2ec62cff2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/urls.go +++ /dev/null @@ -1,33 +0,0 @@ -package objects - -import ( - "github.com/rackspace/gophercloud" -) - -func listURL(c *gophercloud.ServiceClient, container string) string { - return c.ServiceURL(container) -} - -func copyURL(c *gophercloud.ServiceClient, container, object string) string { - return c.ServiceURL(container, object) -} - -func createURL(c *gophercloud.ServiceClient, container, object string) string { - return copyURL(c, container, object) -} - -func getURL(c *gophercloud.ServiceClient, container, object string) string { - return copyURL(c, container, object) -} - -func deleteURL(c *gophercloud.ServiceClient, container, object string) string { - return copyURL(c, container, object) -} - -func downloadURL(c *gophercloud.ServiceClient, container, object string) string { - return copyURL(c, container, object) -} - -func updateURL(c *gophercloud.ServiceClient, container, object string) string { - return copyURL(c, container, object) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/urls_test.go deleted file mode 100644 index 1dcfe3543c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/urls_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package objects - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestListURL(t *testing.T) { - actual := listURL(endpointClient(), "foo") - expected := endpoint + "foo" - th.CheckEquals(t, expected, actual) -} - -func TestCopyURL(t *testing.T) { - actual := copyURL(endpointClient(), "foo", "bar") - expected := endpoint + "foo/bar" - th.CheckEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient(), "foo", "bar") - expected := endpoint + "foo/bar" - th.CheckEquals(t, expected, actual) -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo", "bar") - expected := endpoint + "foo/bar" - th.CheckEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo", "bar") - expected := endpoint + "foo/bar" - th.CheckEquals(t, expected, actual) -} - -func TestDownloadURL(t *testing.T) { - actual := downloadURL(endpointClient(), "foo", "bar") - expected := endpoint + "foo/bar" - th.CheckEquals(t, expected, actual) -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo", "bar") - expected := endpoint + "foo/bar" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/utils/choose_version_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/utils/choose_version_test.go deleted file mode 100644 index 9552696232..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/utils/choose_version_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package utils - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/testhelper" -) - -func setupVersionHandler() { - testhelper.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "versions": { - "values": [ - { - "status": "stable", - "id": "v3.0", - "links": [ - { "href": "%s/v3.0", "rel": "self" } - ] - }, - { - "status": "stable", - "id": "v2.0", - "links": [ - { "href": "%s/v2.0", "rel": "self" } - ] - } - ] - } - } - `, testhelper.Server.URL, testhelper.Server.URL) - }) -} - -func TestChooseVersion(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - setupVersionHandler() - - v2 := &Version{ID: "v2.0", Priority: 2, Suffix: "blarg"} - v3 := &Version{ID: "v3.0", Priority: 3, Suffix: "hargl"} - - v, endpoint, err := ChooseVersion(testhelper.Endpoint(), "", []*Version{v2, v3}) - - if err != nil { - t.Fatalf("Unexpected error from ChooseVersion: %v", err) - } - - if v != v3 { - t.Errorf("Expected %#v to win, but %#v did instead", v3, v) - } - - expected := testhelper.Endpoint() + "v3.0/" - if endpoint != expected { - t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) - } -} - -func TestChooseVersionOpinionatedLink(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - setupVersionHandler() - - v2 := &Version{ID: "v2.0", Priority: 2, Suffix: "nope"} - v3 := &Version{ID: "v3.0", Priority: 3, Suffix: "northis"} - - v, endpoint, err := ChooseVersion(testhelper.Endpoint(), testhelper.Endpoint()+"v2.0/", []*Version{v2, v3}) - if err != nil { - t.Fatalf("Unexpected error from ChooseVersion: %v", err) - } - - if v != v2 { - t.Errorf("Expected %#v to win, but %#v did instead", v2, v) - } - - expected := testhelper.Endpoint() + "v2.0/" - if endpoint != expected { - t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) - } -} - -func TestChooseVersionFromSuffix(t *testing.T) { - testhelper.SetupHTTP() - defer testhelper.TeardownHTTP() - - v2 := &Version{ID: "v2.0", Priority: 2, Suffix: "/v2.0/"} - v3 := &Version{ID: "v3.0", Priority: 3, Suffix: "/v3.0/"} - - v, endpoint, err := ChooseVersion(testhelper.Endpoint(), testhelper.Endpoint()+"v2.0/", []*Version{v2, v3}) - if err != nil { - t.Fatalf("Unexpected error from ChooseVersion: %v", err) - } - - if v != v2 { - t.Errorf("Expected %#v to win, but %#v did instead", v2, v) - } - - expected := testhelper.Endpoint() + "v2.0/" - if endpoint != expected { - t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go deleted file mode 100644 index 1e108c8039..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go +++ /dev/null @@ -1,64 +0,0 @@ -package pagination - -import ( - "encoding/json" - "io/ioutil" - "net/http" - "net/url" - "strings" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -// PageResult stores the HTTP response that returned the current page of results. -type PageResult struct { - gophercloud.Result - url.URL -} - -// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the -// results, interpreting it as JSON if the content type indicates. -func PageResultFrom(resp http.Response) (PageResult, error) { - var parsedBody interface{} - - defer resp.Body.Close() - rawBody, err := ioutil.ReadAll(resp.Body) - if err != nil { - return PageResult{}, err - } - - if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { - err = json.Unmarshal(rawBody, &parsedBody) - if err != nil { - return PageResult{}, err - } - } else { - parsedBody = rawBody - } - - return PageResult{ - Result: gophercloud.Result{ - Body: parsedBody, - Header: resp.Header, - }, - URL: *resp.Request.URL, - }, err -} - -// Request performs a Perigee request and extracts the http.Response from the result. -func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (http.Response, error) { - h := client.AuthenticatedHeaders() - for key, value := range headers { - h[key] = value - } - - resp, err := perigee.Request("GET", url, perigee.Options{ - MoreHeaders: h, - OkCodes: []int{200, 204}, - }) - if err != nil { - return http.Response{}, err - } - return resp.HttpResponse, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/linked_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/linked_test.go deleted file mode 100644 index 4d3248e6ac..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/linked_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package pagination - -import ( - "fmt" - "net/http" - "reflect" - "testing" - - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud/testhelper" -) - -// LinkedPager sample and test cases. - -type LinkedPageResult struct { - LinkedPageBase -} - -func (r LinkedPageResult) IsEmpty() (bool, error) { - is, err := ExtractLinkedInts(r) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -func ExtractLinkedInts(page Page) ([]int, error) { - var response struct { - Ints []int `mapstructure:"ints"` - } - - err := mapstructure.Decode(page.(LinkedPageResult).Body, &response) - if err != nil { - return nil, err - } - - return response.Ints, nil -} - -func createLinked(t *testing.T) Pager { - testhelper.SetupHTTP() - - testhelper.Mux.HandleFunc("/page1", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3], "links": { "next": "%s/page2" } }`, testhelper.Server.URL) - }) - - testhelper.Mux.HandleFunc("/page2", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [4, 5, 6], "links": { "next": "%s/page3" } }`, testhelper.Server.URL) - }) - - testhelper.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) - }) - - client := createClient() - - createPage := func(r PageResult) Page { - return LinkedPageResult{LinkedPageBase{PageResult: r}} - } - - return NewPager(client, testhelper.Server.URL+"/page1", createPage) -} - -func TestEnumerateLinked(t *testing.T) { - pager := createLinked(t) - defer testhelper.TeardownHTTP() - - callCount := 0 - err := pager.EachPage(func(page Page) (bool, error) { - actual, err := ExtractLinkedInts(page) - if err != nil { - return false, err - } - - t.Logf("Handler invoked with %v", actual) - - var expected []int - switch callCount { - case 0: - expected = []int{1, 2, 3} - case 1: - expected = []int{4, 5, 6} - case 2: - expected = []int{7, 8, 9} - default: - t.Fatalf("Unexpected call count: %d", callCount) - return false, nil - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Call %d: Expected %#v, but was %#v", callCount, expected, actual) - } - - callCount++ - return true, nil - }) - if err != nil { - t.Errorf("Unexpected error for page iteration: %v", err) - } - - if callCount != 3 { - t.Errorf("Expected 3 calls, but was %d", callCount) - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/marker_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/marker_test.go deleted file mode 100644 index 3b1df1d68b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/marker_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package pagination - -import ( - "fmt" - "net/http" - "strings" - "testing" - - "github.com/rackspace/gophercloud/testhelper" -) - -// MarkerPager sample and test cases. - -type MarkerPageResult struct { - MarkerPageBase -} - -func (r MarkerPageResult) IsEmpty() (bool, error) { - results, err := ExtractMarkerStrings(r) - if err != nil { - return true, err - } - return len(results) == 0, err -} - -func (r MarkerPageResult) LastMarker() (string, error) { - results, err := ExtractMarkerStrings(r) - if err != nil { - return "", err - } - if len(results) == 0 { - return "", nil - } - return results[len(results)-1], nil -} - -func createMarkerPaged(t *testing.T) Pager { - testhelper.SetupHTTP() - - testhelper.Mux.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) { - r.ParseForm() - ms := r.Form["marker"] - switch { - case len(ms) == 0: - fmt.Fprintf(w, "aaa\nbbb\nccc") - case len(ms) == 1 && ms[0] == "ccc": - fmt.Fprintf(w, "ddd\neee\nfff") - case len(ms) == 1 && ms[0] == "fff": - fmt.Fprintf(w, "ggg\nhhh\niii") - case len(ms) == 1 && ms[0] == "iii": - w.WriteHeader(http.StatusNoContent) - default: - t.Errorf("Request with unexpected marker: [%v]", ms) - } - }) - - client := createClient() - - createPage := func(r PageResult) Page { - p := MarkerPageResult{MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p - return p - } - - return NewPager(client, testhelper.Server.URL+"/page", createPage) -} - -func ExtractMarkerStrings(page Page) ([]string, error) { - content := page.(MarkerPageResult).Body.([]uint8) - parts := strings.Split(string(content), "\n") - results := make([]string, 0, len(parts)) - for _, part := range parts { - if len(part) > 0 { - results = append(results, part) - } - } - return results, nil -} - -func TestEnumerateMarker(t *testing.T) { - pager := createMarkerPaged(t) - defer testhelper.TeardownHTTP() - - callCount := 0 - err := pager.EachPage(func(page Page) (bool, error) { - actual, err := ExtractMarkerStrings(page) - if err != nil { - return false, err - } - - t.Logf("Handler invoked with %v", actual) - - var expected []string - switch callCount { - case 0: - expected = []string{"aaa", "bbb", "ccc"} - case 1: - expected = []string{"ddd", "eee", "fff"} - case 2: - expected = []string{"ggg", "hhh", "iii"} - default: - t.Fatalf("Unexpected call count: %d", callCount) - return false, nil - } - - testhelper.CheckDeepEquals(t, expected, actual) - - callCount++ - return true, nil - }) - testhelper.AssertNoErr(t, err) - testhelper.AssertEquals(t, callCount, 3) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go deleted file mode 100644 index 5c20e16c6c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go +++ /dev/null @@ -1,115 +0,0 @@ -package pagination - -import ( - "errors" - - "github.com/rackspace/gophercloud" -) - -var ( - // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. - ErrPageNotAvailable = errors.New("The requested page does not exist.") -) - -// Page must be satisfied by the result type of any resource collection. -// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated. -// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs, -// instead. -// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type -// will need to implement. -type Page interface { - - // NextPageURL generates the URL for the page of data that follows this collection. - // Return "" if no such page exists. - NextPageURL() (string, error) - - // IsEmpty returns true if this Page has no items in it. - IsEmpty() (bool, error) -} - -// Pager knows how to advance through a specific resource collection, one page at a time. -type Pager struct { - client *gophercloud.ServiceClient - - initialURL string - - createPage func(r PageResult) Page - - Err error - - // Headers supplies additional HTTP headers to populate on each paged request. - Headers map[string]string -} - -// NewPager constructs a manually-configured pager. -// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page. -func NewPager(client *gophercloud.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager { - return Pager{ - client: client, - initialURL: initialURL, - createPage: createPage, - } -} - -// WithPageCreator returns a new Pager that substitutes a different page creation function. This is -// useful for overriding List functions in delegation. -func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager { - return Pager{ - client: p.client, - initialURL: p.initialURL, - createPage: createPage, - } -} - -func (p Pager) fetchNextPage(url string) (Page, error) { - resp, err := Request(p.client, p.Headers, url) - if err != nil { - return nil, err - } - - remembered, err := PageResultFrom(resp) - if err != nil { - return nil, err - } - - return p.createPage(remembered), nil -} - -// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function. -// Return "false" from the handler to prematurely stop iterating. -func (p Pager) EachPage(handler func(Page) (bool, error)) error { - if p.Err != nil { - return p.Err - } - currentURL := p.initialURL - for { - currentPage, err := p.fetchNextPage(currentURL) - if err != nil { - return err - } - - empty, err := currentPage.IsEmpty() - if err != nil { - return err - } - if empty { - return nil - } - - ok, err := handler(currentPage) - if err != nil { - return err - } - if !ok { - return nil - } - - currentURL, err = currentPage.NextPageURL() - if err != nil { - return err - } - if currentURL == "" { - return nil - } - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pagination_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pagination_test.go deleted file mode 100644 index f3e4de1b04..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pagination_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package pagination - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/testhelper" -) - -func createClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{ - ProviderClient: &gophercloud.ProviderClient{TokenID: "abc123"}, - Endpoint: testhelper.Endpoint(), - } -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/single.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/single.go deleted file mode 100644 index 4dd3c5c425..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/single.go +++ /dev/null @@ -1,9 +0,0 @@ -package pagination - -// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once. -type SinglePageBase PageResult - -// NextPageURL always returns "" to indicate that there are no more pages to return. -func (current SinglePageBase) NextPageURL() (string, error) { - return "", nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/single_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/single_test.go deleted file mode 100644 index 8817d570f2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/single_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package pagination - -import ( - "fmt" - "net/http" - "testing" - - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud/testhelper" -) - -// SinglePage sample and test cases. - -type SinglePageResult struct { - SinglePageBase -} - -func (r SinglePageResult) IsEmpty() (bool, error) { - is, err := ExtractSingleInts(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -func ExtractSingleInts(page Page) ([]int, error) { - var response struct { - Ints []int `mapstructure:"ints"` - } - - err := mapstructure.Decode(page.(SinglePageResult).Body, &response) - if err != nil { - return nil, err - } - - return response.Ints, nil -} - -func setupSinglePaged() Pager { - testhelper.SetupHTTP() - client := createClient() - - testhelper.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3] }`) - }) - - createPage := func(r PageResult) Page { - return SinglePageResult{SinglePageBase(r)} - } - - return NewPager(client, testhelper.Server.URL+"/only", createPage) -} - -func TestEnumerateSinglePaged(t *testing.T) { - callCount := 0 - pager := setupSinglePaged() - defer testhelper.TeardownHTTP() - - err := pager.EachPage(func(page Page) (bool, error) { - callCount++ - - expected := []int{1, 2, 3} - actual, err := ExtractSingleInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) - return true, nil - }) - testhelper.CheckNoErr(t, err) - testhelper.CheckEquals(t, 1, callCount) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/params.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/params.go deleted file mode 100644 index 948783b073..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/params.go +++ /dev/null @@ -1,260 +0,0 @@ -package gophercloud - -import ( - "fmt" - "net/url" - "reflect" - "strconv" - "strings" - "time" -) - -// EnabledState is a convenience type, mostly used in Create and Update -// operations. Because the zero value of a bool is FALSE, we need to use a -// pointer instead to indicate zero-ness. -type EnabledState *bool - -// Convenience vars for EnabledState values. -var ( - iTrue = true - iFalse = false - - Enabled EnabledState = &iTrue - Disabled EnabledState = &iFalse -) - -// IntToPointer is a function for converting integers into integer pointers. -// This is useful when passing in options to operations. -func IntToPointer(i int) *int { - return &i -} - -/* -MaybeString is an internal function to be used by request methods in individual -resource packages. - -It takes a string that might be a zero value and returns either a pointer to its -address or nil. This is useful for allowing users to conveniently omit values -from an options struct by leaving them zeroed, but still pass nil to the JSON -serializer so they'll be omitted from the request body. -*/ -func MaybeString(original string) *string { - if original != "" { - return &original - } - return nil -} - -/* -MaybeInt is an internal function to be used by request methods in individual -resource packages. - -Like MaybeString, it accepts an int that may or may not be a zero value, and -returns either a pointer to its address or nil. It's intended to hint that the -JSON serializer should omit its field. -*/ -func MaybeInt(original int) *int { - if original != 0 { - return &original - } - return nil -} - -var t time.Time - -func isZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Func, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - z := true - for i := 0; i < v.Len(); i++ { - z = z && isZero(v.Index(i)) - } - return z - case reflect.Struct: - if v.Type() == reflect.TypeOf(t) { - if v.Interface().(time.Time).IsZero() { - return true - } - return false - } - z := true - for i := 0; i < v.NumField(); i++ { - z = z && isZero(v.Field(i)) - } - return z - } - // Compare other types directly: - z := reflect.Zero(v.Type()) - return v.Interface() == z.Interface() -} - -/* -BuildQueryString is an internal function to be used by request methods in -individual resource packages. - -It accepts a tagged structure and expands it into a URL struct. Field names are -converted into query parameters based on a "q" tag. For example: - - type struct Something { - Bar string `q:"x_bar"` - Baz int `q:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into "?x_bar=AAA&lorem_ipsum=BBB". - -The struct's fields may be strings, integers, or boolean values. Fields left at -their type's zero value will be omitted from the query. -*/ -func BuildQueryString(opts interface{}) (*url.URL, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - params := url.Values{} - - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - qTag := f.Tag.Get("q") - - // if the field has a 'q' tag, it goes in the query string - if qTag != "" { - tags := strings.Split(qTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - switch v.Kind() { - case reflect.String: - params.Add(tags[0], v.String()) - case reflect.Int: - params.Add(tags[0], strconv.FormatInt(v.Int(), 10)) - case reflect.Bool: - params.Add(tags[0], strconv.FormatBool(v.Bool())) - } - } else { - // Otherwise, the field is not set. - if len(tags) == 2 && tags[1] == "required" { - // And the field is required. Return an error. - return nil, fmt.Errorf("Required query parameter [%s] not set.", f.Name) - } - } - } - } - - return &url.URL{RawQuery: params.Encode()}, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("Options type is not a struct.") -} - -/* -BuildHeaders is an internal function to be used by request methods in -individual resource packages. - -It accepts an arbitrary tagged structure and produces a string map that's -suitable for use as the HTTP headers of an outgoing request. Field names are -mapped to header names based in "h" tags. - - type struct Something { - Bar string `h:"x_bar"` - Baz int `h:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into: - - map[string]string{ - "x_bar": "AAA", - "lorem_ipsum": "BBB", - } - -Untagged fields and fields left at their zero values are skipped. Integers, -booleans and string values are supported. -*/ -func BuildHeaders(opts interface{}) (map[string]string, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]string) - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - hTag := f.Tag.Get("h") - - // if the field has a 'h' tag, it goes in the header - if hTag != "" { - tags := strings.Split(hTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - switch v.Kind() { - case reflect.String: - optsMap[tags[0]] = v.String() - case reflect.Int: - optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) - case reflect.Bool: - optsMap[tags[0]] = strconv.FormatBool(v.Bool()) - } - } else { - // Otherwise, the field is not set. - if len(tags) == 2 && tags[1] == "required" { - // And the field is required. Return an error. - return optsMap, fmt.Errorf("Required header not set.") - } - } - } - - } - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return optsMap, fmt.Errorf("Options type is not a struct.") -} - -// IDSliceToQueryString takes a slice of elements and converts them into a query -// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the -// result would be `?name=20&name=40&name=60' -func IDSliceToQueryString(name string, ids []int) string { - str := "" - for k, v := range ids { - if k == 0 { - str += "?" - } else { - str += "&" - } - str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v)) - } - return str -} - -// IntWithinRange returns TRUE if an integer falls within a defined range, and -// FALSE if not. -func IntWithinRange(val, min, max int) bool { - return val > min && val < max -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/params_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/params_test.go deleted file mode 100644 index 4a2c9fe341..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/params_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package gophercloud - -import ( - "net/url" - "reflect" - "testing" - "time" - - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestMaybeString(t *testing.T) { - testString := "" - var expected *string - actual := MaybeString(testString) - th.CheckDeepEquals(t, expected, actual) - - testString = "carol" - expected = &testString - actual = MaybeString(testString) - th.CheckDeepEquals(t, expected, actual) -} - -func TestMaybeInt(t *testing.T) { - testInt := 0 - var expected *int - actual := MaybeInt(testInt) - th.CheckDeepEquals(t, expected, actual) - - testInt = 4 - expected = &testInt - actual = MaybeInt(testInt) - th.CheckDeepEquals(t, expected, actual) -} - -func TestBuildQueryString(t *testing.T) { - opts := struct { - J int `q:"j"` - R string `q:"r,required"` - C bool `q:"c"` - }{ - J: 2, - R: "red", - C: true, - } - expected := &url.URL{RawQuery: "c=true&j=2&r=red"} - actual, err := BuildQueryString(&opts) - if err != nil { - t.Errorf("Error building query string: %v", err) - } - th.CheckDeepEquals(t, expected, actual) - - opts = struct { - J int `q:"j"` - R string `q:"r,required"` - C bool `q:"c"` - }{ - J: 2, - C: true, - } - _, err = BuildQueryString(&opts) - if err == nil { - t.Errorf("Expected error: 'Required field not set'") - } - th.CheckDeepEquals(t, expected, actual) - - _, err = BuildQueryString(map[string]interface{}{"Number": 4}) - if err == nil { - t.Errorf("Expected error: 'Options type is not a struct'") - } -} - -func TestBuildHeaders(t *testing.T) { - testStruct := struct { - Accept string `h:"Accept"` - Num int `h:"Number,required"` - Style bool `h:"Style"` - }{ - Accept: "application/json", - Num: 4, - Style: true, - } - expected := map[string]string{"Accept": "application/json", "Number": "4", "Style": "true"} - actual, err := BuildHeaders(&testStruct) - th.CheckNoErr(t, err) - th.CheckDeepEquals(t, expected, actual) - - testStruct.Num = 0 - _, err = BuildHeaders(&testStruct) - if err == nil { - t.Errorf("Expected error: 'Required header not set'") - } - - _, err = BuildHeaders(map[string]interface{}{"Number": 4}) - if err == nil { - t.Errorf("Expected error: 'Options type is not a struct'") - } -} - -func TestIsZero(t *testing.T) { - var testMap map[string]interface{} - testMapValue := reflect.ValueOf(testMap) - expected := true - actual := isZero(testMapValue) - th.CheckEquals(t, expected, actual) - testMap = map[string]interface{}{"empty": false} - testMapValue = reflect.ValueOf(testMap) - expected = false - actual = isZero(testMapValue) - th.CheckEquals(t, expected, actual) - - var testArray [2]string - testArrayValue := reflect.ValueOf(testArray) - expected = true - actual = isZero(testArrayValue) - th.CheckEquals(t, expected, actual) - testArray = [2]string{"one", "two"} - testArrayValue = reflect.ValueOf(testArray) - expected = false - actual = isZero(testArrayValue) - th.CheckEquals(t, expected, actual) - - var testStruct struct { - A string - B time.Time - } - testStructValue := reflect.ValueOf(testStruct) - expected = true - actual = isZero(testStructValue) - th.CheckEquals(t, expected, actual) - testStruct = struct { - A string - B time.Time - }{ - B: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), - } - testStructValue = reflect.ValueOf(testStruct) - expected = false - actual = isZero(testStructValue) - th.CheckEquals(t, expected, actual) -} - -func TestQueriesAreEscaped(t *testing.T) { - type foo struct { - Name string `q:"something"` - Shape string `q:"else"` - } - - expected := &url.URL{RawQuery: "else=Triangl+e&something=blah%2B%3F%21%21foo"} - - actual, err := BuildQueryString(foo{Name: "blah+?!!foo", Shape: "Triangl e"}) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go deleted file mode 100644 index 7754c20812..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go +++ /dev/null @@ -1,33 +0,0 @@ -package gophercloud - -// ProviderClient stores details that are required to interact with any -// services within a specific provider's API. -// -// Generally, you acquire a ProviderClient by calling the NewClient method in -// the appropriate provider's child package, providing whatever authentication -// credentials are required. -type ProviderClient struct { - // IdentityBase is the base URL used for a particular provider's identity - // service - it will be used when issuing authenticatation requests. It - // should point to the root resource of the identity service, not a specific - // identity version. - IdentityBase string - - // IdentityEndpoint is the identity endpoint. This may be a specific version - // of the identity service. If this is the case, this endpoint is used rather - // than querying versions first. - IdentityEndpoint string - - // TokenID is the ID of the most recently issued valid token. - TokenID string - - // EndpointLocator describes how this provider discovers the endpoints for - // its constituent services. - EndpointLocator EndpointLocator -} - -// AuthenticatedHeaders returns a map of HTTP headers that are common for all -// authenticated service requests. -func (client *ProviderClient) AuthenticatedHeaders() map[string]string { - return map[string]string{"X-Auth-Token": client.TokenID} -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client_test.go deleted file mode 100644 index b260246c5a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package gophercloud - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAuthenticatedHeaders(t *testing.T) { - p := &ProviderClient{ - TokenID: "1234", - } - expected := map[string]string{"X-Auth-Token": "1234"} - actual := p.AuthenticatedHeaders() - th.CheckDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/delegate.go deleted file mode 100644 index b338c36b71..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/delegate.go +++ /dev/null @@ -1,134 +0,0 @@ -package snapshots - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots" -) - -func updateURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("snapshots", id) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToSnapshotCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains options for creating a Snapshot. This object is passed to -// the snapshots.Create function. For more information about these parameters, -// see the Snapshot object. -type CreateOpts struct { - // REQUIRED - VolumeID string - // OPTIONAL - Description string - // OPTIONAL - Force bool - // OPTIONAL - Name string -} - -// ToSnapshotCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) { - s := make(map[string]interface{}) - - if opts.VolumeID == "" { - return nil, errors.New("Required CreateOpts field 'VolumeID' not set.") - } - - s["volume_id"] = opts.VolumeID - - if opts.Description != "" { - s["display_description"] = opts.Description - } - if opts.Name != "" { - s["display_name"] = opts.Name - } - if opts.Force { - s["force"] = opts.Force - } - - return map[string]interface{}{"snapshot": s}, nil -} - -// Create will create a new Snapshot based on the values in CreateOpts. To -// extract the Snapshot object from the response, call the Extract method on the -// CreateResult. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - return CreateResult{os.Create(client, opts)} -} - -// Delete will delete the existing Snapshot with the provided ID. -func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult { - return os.Delete(client, id) -} - -// Get retrieves the Snapshot with the provided ID. To extract the Snapshot -// object from the response, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - return GetResult{os.Get(client, id)} -} - -// List returns Snapshots. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return os.List(client, os.ListOpts{}) -} - -// UpdateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Update operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type UpdateOptsBuilder interface { - ToSnapshotUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts is the common options struct used in this package's Update -// operation. -type UpdateOpts struct { - Name string - Description string -} - -// ToSnapshotUpdateMap casts a UpdateOpts struct to a map. -func (opts UpdateOpts) ToSnapshotUpdateMap() (map[string]interface{}, error) { - s := make(map[string]interface{}) - - if opts.Name != "" { - s["display_name"] = opts.Name - } - if opts.Description != "" { - s["display_description"] = opts.Description - } - - return map[string]interface{}{"snapshot": s}, nil -} - -// Update accepts a UpdateOpts struct and updates an existing snapshot using the -// values provided. -func Update(c *gophercloud.ServiceClient, snapshotID string, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToSnapshotUpdateMap() - if err != nil { - res.Err = err - return res - } - - // Send request to API - _, res.Err = perigee.Request("PUT", updateURL(c, snapshotID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/delegate_test.go deleted file mode 100644 index 1a02b46527..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/delegate_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package snapshots - -import ( - "testing" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -const endpoint = "http://localhost:57909/v1/12345" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestUpdateURL(t *testing.T) { - actual := updateURL(endpointClient(), "foo") - expected := endpoint + "snapshots/foo" - th.AssertEquals(t, expected, actual) -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockListResponse(t) - - count := 0 - - err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractSnapshots(page) - if err != nil { - t.Errorf("Failed to extract snapshots: %v", err) - return false, err - } - - expected := []Snapshot{ - Snapshot{ - ID: "289da7f8-6440-407c-9fb4-7db01ec49164", - Name: "snapshot-001", - }, - Snapshot{ - ID: "96c3bda7-c82a-4f50-be73-ca7621794835", - Name: "snapshot-002", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertEquals(t, 1, count) - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockGetResponse(t) - - v, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, v.Name, "snapshot-001") - th.AssertEquals(t, v.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockCreateResponse(t) - - options := &CreateOpts{VolumeID: "1234", Name: "snapshot-001"} - n, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.VolumeID, "1234") - th.AssertEquals(t, n.Name, "snapshot-001") - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockDeleteResponse(t) - - res := Delete(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/doc.go deleted file mode 100644 index ad6064f2af..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package snapshots provides information and interaction with the snapshot -// API resource for the Rackspace Block Storage service. -package snapshots diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/results.go deleted file mode 100644 index 0fab2828bc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/snapshots/results.go +++ /dev/null @@ -1,149 +0,0 @@ -package snapshots - -import ( - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// Status is the type used to represent a snapshot's status -type Status string - -// Constants to use for supported statuses -const ( - Creating Status = "CREATING" - Available Status = "AVAILABLE" - Deleting Status = "DELETING" - Error Status = "ERROR" - DeleteError Status = "ERROR_DELETING" -) - -// Snapshot is the Rackspace representation of an external block storage device. -type Snapshot struct { - // The timestamp when this snapshot was created. - CreatedAt string `mapstructure:"created_at"` - - // The human-readable description for this snapshot. - Description string `mapstructure:"display_description"` - - // The human-readable name for this snapshot. - Name string `mapstructure:"display_name"` - - // The UUID for this snapshot. - ID string `mapstructure:"id"` - - // The random metadata associated with this snapshot. Note: unlike standard - // OpenStack snapshots, this cannot actually be set. - Metadata map[string]string `mapstructure:"metadata"` - - // Indicates the current progress of the snapshot's backup procedure. - Progress string `mapstructure:"os-extended-snapshot-attributes:progress"` - - // The project ID. - ProjectID string `mapstructure:"os-extended-snapshot-attributes:project_id"` - - // The size of the volume which this snapshot backs up. - Size int `mapstructure:"size"` - - // The status of the snapshot. - Status Status `mapstructure:"status"` - - // The ID of the volume which this snapshot seeks to back up. - VolumeID string `mapstructure:"volume_id"` -} - -// CreateResult represents the result of a create operation -type CreateResult struct { - os.CreateResult -} - -// GetResult represents the result of a get operation -type GetResult struct { - os.GetResult -} - -// UpdateResult represents the result of an update operation -type UpdateResult struct { - gophercloud.Result -} - -func commonExtract(resp interface{}, err error) (*Snapshot, error) { - if err != nil { - return nil, err - } - - var respStruct struct { - Snapshot *Snapshot `json:"snapshot"` - } - - err = mapstructure.Decode(resp, &respStruct) - - return respStruct.Snapshot, err -} - -// Extract will get the Snapshot object out of the GetResult object. -func (r GetResult) Extract() (*Snapshot, error) { - return commonExtract(r.Body, r.Err) -} - -// Extract will get the Snapshot object out of the CreateResult object. -func (r CreateResult) Extract() (*Snapshot, error) { - return commonExtract(r.Body, r.Err) -} - -// Extract will get the Snapshot object out of the UpdateResult object. -func (r UpdateResult) Extract() (*Snapshot, error) { - return commonExtract(r.Body, r.Err) -} - -// ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call. -func ExtractSnapshots(page pagination.Page) ([]Snapshot, error) { - var response struct { - Snapshots []Snapshot `json:"snapshots"` - } - - err := mapstructure.Decode(page.(os.ListResult).Body, &response) - return response.Snapshots, err -} - -// WaitUntilComplete will continually poll a snapshot until it successfully -// transitions to a specified state. It will do this for at most the number of -// seconds specified. -func (snapshot Snapshot) WaitUntilComplete(c *gophercloud.ServiceClient, timeout int) error { - return gophercloud.WaitFor(timeout, func() (bool, error) { - // Poll resource - current, err := Get(c, snapshot.ID).Extract() - if err != nil { - return false, err - } - - // Has it been built yet? - if current.Progress == "100%" { - return true, nil - } - - return false, nil - }) -} - -// WaitUntilDeleted will continually poll a snapshot until it has been -// successfully deleted, i.e. returns a 404 status. -func (snapshot Snapshot) WaitUntilDeleted(c *gophercloud.ServiceClient, timeout int) error { - return gophercloud.WaitFor(timeout, func() (bool, error) { - // Poll resource - _, err := Get(c, snapshot.ID).Extract() - - // Check for a 404 - if casted, ok := err.(*perigee.UnexpectedResponseCodeError); ok && casted.Actual == 404 { - return true, nil - } else if err != nil { - return false, err - } - - return false, nil - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate.go deleted file mode 100644 index 438349410a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate.go +++ /dev/null @@ -1,75 +0,0 @@ -package volumes - -import ( - "fmt" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - "github.com/rackspace/gophercloud/pagination" -) - -type CreateOpts struct { - os.CreateOpts -} - -func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) { - if opts.Size < 75 || opts.Size > 1024 { - return nil, fmt.Errorf("Size field must be between 75 and 1024") - } - - return opts.CreateOpts.ToVolumeCreateMap() -} - -// Create will create a new Volume based on the values in CreateOpts. To extract -// the Volume object from the response, call the Extract method on the -// CreateResult. -func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) CreateResult { - return CreateResult{os.Create(client, opts)} -} - -// Delete will delete the existing Volume with the provided ID. -func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult { - return os.Delete(client, id) -} - -// Get retrieves the Volume with the provided ID. To extract the Volume object -// from the response, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - return GetResult{os.Get(client, id)} -} - -// List returns volumes optionally limited by the conditions provided in ListOpts. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return os.List(client, os.ListOpts{}) -} - -// UpdateOpts contain options for updating an existing Volume. This object is passed -// to the volumes.Update function. For more information about the parameters, see -// the Volume object. -type UpdateOpts struct { - // OPTIONAL - Name string - // OPTIONAL - Description string -} - -// ToVolumeUpdateMap assembles a request body based on the contents of an -// UpdateOpts. -func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) { - v := make(map[string]interface{}) - - if opts.Description != "" { - v["display_description"] = opts.Description - } - if opts.Name != "" { - v["display_name"] = opts.Name - } - - return map[string]interface{}{"volume": v}, nil -} - -// Update will update the Volume with provided information. To extract the updated -// Volume from the response, call the Extract method on the UpdateResult. -func Update(client *gophercloud.ServiceClient, id string, opts os.UpdateOptsBuilder) UpdateResult { - return UpdateResult{os.Update(client, id, opts)} -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go deleted file mode 100644 index b44564cc1f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package volumes - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockListResponse(t) - - count := 0 - - err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVolumes(page) - if err != nil { - t.Errorf("Failed to extract volumes: %v", err) - return false, err - } - - expected := []Volume{ - Volume{ - ID: "289da7f8-6440-407c-9fb4-7db01ec49164", - Name: "vol-001", - }, - Volume{ - ID: "96c3bda7-c82a-4f50-be73-ca7621794835", - Name: "vol-002", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertEquals(t, 1, count) - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockGetResponse(t) - - v, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, v.Name, "vol-001") - th.AssertEquals(t, v.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockCreateResponse(t) - - n, err := Create(fake.ServiceClient(), CreateOpts{os.CreateOpts{Size: 75}}).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Size, 4) - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestSizeRange(t *testing.T) { - _, err := Create(fake.ServiceClient(), CreateOpts{os.CreateOpts{Size: 1}}).Extract() - if err == nil { - t.Fatalf("Expected error, got none") - } - - _, err = Create(fake.ServiceClient(), CreateOpts{os.CreateOpts{Size: 2000}}).Extract() - if err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockDeleteResponse(t) - - res := Delete(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertNoErr(t, res.Err) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockUpdateResponse(t) - - options := &UpdateOpts{Name: "vol-002"} - v, err := Update(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() - th.AssertNoErr(t, err) - th.CheckEquals(t, "vol-002", v.Name) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/doc.go deleted file mode 100644 index b2be25c538..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package volumes provides information and interaction with the volume -// API resource for the Rackspace Block Storage service. -package volumes diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/results.go deleted file mode 100644 index c7c2cc4984..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/results.go +++ /dev/null @@ -1,66 +0,0 @@ -package volumes - -import ( - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - "github.com/rackspace/gophercloud/pagination" - - "github.com/mitchellh/mapstructure" -) - -// Volume wraps an Openstack volume -type Volume os.Volume - -// CreateResult represents the result of a create operation -type CreateResult struct { - os.CreateResult -} - -// GetResult represents the result of a get operation -type GetResult struct { - os.GetResult -} - -// UpdateResult represents the result of an update operation -type UpdateResult struct { - os.UpdateResult -} - -func commonExtract(resp interface{}, err error) (*Volume, error) { - if err != nil { - return nil, err - } - - var respStruct struct { - Volume *Volume `json:"volume"` - } - - err = mapstructure.Decode(resp, &respStruct) - - return respStruct.Volume, err -} - -// Extract will get the Volume object out of the GetResult object. -func (r GetResult) Extract() (*Volume, error) { - return commonExtract(r.Body, r.Err) -} - -// Extract will get the Volume object out of the CreateResult object. -func (r CreateResult) Extract() (*Volume, error) { - return commonExtract(r.Body, r.Err) -} - -// Extract will get the Volume object out of the UpdateResult object. -func (r UpdateResult) Extract() (*Volume, error) { - return commonExtract(r.Body, r.Err) -} - -// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call. -func ExtractVolumes(page pagination.Page) ([]Volume, error) { - var response struct { - Volumes []Volume `json:"volumes"` - } - - err := mapstructure.Decode(page.(os.ListResult).Body, &response) - - return response.Volumes, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/delegate.go deleted file mode 100644 index c96b3e4a35..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/delegate.go +++ /dev/null @@ -1,18 +0,0 @@ -package volumetypes - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes" - "github.com/rackspace/gophercloud/pagination" -) - -// List returns all volume types. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return os.List(client) -} - -// Get will retrieve the volume type with the provided ID. To extract the volume -// type from the result, call the Extract method on the GetResult. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - return GetResult{os.Get(client, id)} -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/delegate_test.go deleted file mode 100644 index 6e65c904b5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/delegate_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package volumetypes - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockListResponse(t) - - count := 0 - - err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVolumeTypes(page) - if err != nil { - t.Errorf("Failed to extract volume types: %v", err) - return false, err - } - - expected := []VolumeType{ - VolumeType{ - ID: "289da7f8-6440-407c-9fb4-7db01ec49164", - Name: "vol-type-001", - ExtraSpecs: map[string]interface{}{ - "capabilities": "gpu", - }, - }, - VolumeType{ - ID: "96c3bda7-c82a-4f50-be73-ca7621794835", - Name: "vol-type-002", - ExtraSpecs: map[string]interface{}{}, - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertEquals(t, 1, count) - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - os.MockGetResponse(t) - - vt, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, vt.ExtraSpecs, map[string]interface{}{"serverNumber": "2"}) - th.AssertEquals(t, vt.Name, "vol-type-001") - th.AssertEquals(t, vt.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/doc.go deleted file mode 100644 index 70122b77c4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package volumetypes provides information and interaction with the volume type -// API resource for the Rackspace Block Storage service. -package volumetypes diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/results.go deleted file mode 100644 index 39c8d6f7fa..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumetypes/results.go +++ /dev/null @@ -1,37 +0,0 @@ -package volumetypes - -import ( - "github.com/mitchellh/mapstructure" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes" - "github.com/rackspace/gophercloud/pagination" -) - -type VolumeType os.VolumeType - -type GetResult struct { - os.GetResult -} - -// Extract will get the Volume Type struct out of the response. -func (r GetResult) Extract() (*VolumeType, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - VolumeType *VolumeType `json:"volume_type" mapstructure:"volume_type"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.VolumeType, err -} - -func ExtractVolumeTypes(page pagination.Page) ([]VolumeType, error) { - var response struct { - VolumeTypes []VolumeType `mapstructure:"volume_types"` - } - - err := mapstructure.Decode(page.(os.ListResult).Body, &response) - return response.VolumeTypes, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/client.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/client.go deleted file mode 100644 index 7421ff01ad..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/client.go +++ /dev/null @@ -1,178 +0,0 @@ -package rackspace - -import ( - "fmt" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack" - "github.com/rackspace/gophercloud/openstack/utils" - tokens2 "github.com/rackspace/gophercloud/rackspace/identity/v2/tokens" -) - -const ( - // RackspaceUSIdentity is an identity endpoint located in the United States. - RackspaceUSIdentity = "https://identity.api.rackspacecloud.com/v2.0/" - - // RackspaceUKIdentity is an identity endpoint located in the UK. - RackspaceUKIdentity = "https://lon.identity.api.rackspacecloud.com/v2.0/" -) - -const ( - v20 = "v2.0" -) - -// NewClient creates a client that's prepared to communicate with the Rackspace API, but is not -// yet authenticated. Most users will probably prefer using the AuthenticatedClient function -// instead. -// -// Provide the base URL of the identity endpoint you wish to authenticate against as "endpoint". -// Often, this will be either RackspaceUSIdentity or RackspaceUKIdentity. -func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { - if endpoint == "" { - return os.NewClient(RackspaceUSIdentity) - } - return os.NewClient(endpoint) -} - -// AuthenticatedClient logs in to Rackspace with the provided credentials and constructs a -// ProviderClient that's ready to operate. -// -// If the provided AuthOptions does not specify an explicit IdentityEndpoint, it will default to -// the canonical, production Rackspace US identity endpoint. -func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) { - client, err := NewClient(options.IdentityEndpoint) - if err != nil { - return nil, err - } - - err = Authenticate(client, options) - if err != nil { - return nil, err - } - return client, nil -} - -// Authenticate or re-authenticate against the most recent identity service supported at the -// provided endpoint. -func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { - versions := []*utils.Version{ - &utils.Version{ID: v20, Priority: 20, Suffix: "/v2.0/"}, - } - - chosen, endpoint, err := utils.ChooseVersion(client.IdentityBase, client.IdentityEndpoint, versions) - if err != nil { - return err - } - - switch chosen.ID { - case v20: - return v2auth(client, endpoint, options) - default: - // The switch statement must be out of date from the versions list. - return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) - } -} - -// AuthenticateV2 explicitly authenticates with v2 of the identity service. -func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { - return v2auth(client, "", options) -} - -func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error { - v2Client := NewIdentityV2(client) - if endpoint != "" { - v2Client.Endpoint = endpoint - } - - result := tokens2.Create(v2Client, tokens2.WrapOptions(options)) - - token, err := result.ExtractToken() - if err != nil { - return err - } - - catalog, err := result.ExtractServiceCatalog() - if err != nil { - return err - } - - client.TokenID = token.ID - client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { - return os.V2EndpointURL(catalog, opts) - } - - return nil -} - -// NewIdentityV2 creates a ServiceClient that may be used to access the v2 identity service. -func NewIdentityV2(client *gophercloud.ProviderClient) *gophercloud.ServiceClient { - v2Endpoint := client.IdentityBase + "v2.0/" - - return &gophercloud.ServiceClient{ - ProviderClient: client, - Endpoint: v2Endpoint, - } -} - -// NewComputeV2 creates a ServiceClient that may be used to access the v2 compute service. -func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("compute") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - - return &gophercloud.ServiceClient{ - ProviderClient: client, - Endpoint: url, - }, nil -} - -// NewObjectCDNV1 creates a ServiceClient that may be used with the Rackspace v1 CDN. -func NewObjectCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("rax:object-cdn") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} - -// NewObjectStorageV1 creates a ServiceClient that may be used with the Rackspace v1 object storage package. -func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - return os.NewObjectStorageV1(client, eo) -} - -// NewBlockStorageV1 creates a ServiceClient that can be used to access the -// Rackspace Cloud Block Storage v1 API. -func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("volume") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} - -// NewLBV1 creates a ServiceClient that can be used to access the Rackspace -// Cloud Load Balancer v1 API. -func NewLBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("rax:load-balancer") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} - -// NewNetworkV2 creates a ServiceClient that can be used to access the Rackspace -// Networking v2 API. -func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { - eo.ApplyDefaults("network") - url, err := client.EndpointLocator(eo) - if err != nil { - return nil, err - } - return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/client_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/client_test.go deleted file mode 100644 index 73b1c886ff..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/client_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package rackspace - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestAuthenticatedClientV2(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, ` - { - "access": { - "token": { - "id": "01234567890", - "expires": "2014-10-01T10:00:00.000000Z" - }, - "serviceCatalog": [] - } - } - `) - }) - - options := gophercloud.AuthOptions{ - Username: "me", - APIKey: "09876543210", - IdentityEndpoint: th.Endpoint() + "v2.0/", - } - client, err := AuthenticatedClient(options) - th.AssertNoErr(t, err) - th.CheckEquals(t, "01234567890", client.TokenID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate.go deleted file mode 100644 index 2580459f07..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate.go +++ /dev/null @@ -1,12 +0,0 @@ -package bootfromvolume - -import ( - "github.com/rackspace/gophercloud" - osBFV "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume" - osServers "github.com/rackspace/gophercloud/openstack/compute/v2/servers" -) - -// Create requests the creation of a server from the given block device mapping. -func Create(client *gophercloud.ServiceClient, opts osServers.CreateOptsBuilder) osServers.CreateResult { - return osBFV.Create(client, opts) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go deleted file mode 100644 index 0b5352751b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package bootfromvolume - -import ( - "testing" - - osBFV "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume" - "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestCreateOpts(t *testing.T) { - base := servers.CreateOpts{ - Name: "createdserver", - ImageRef: "asdfasdfasdf", - FlavorRef: "performance1-1", - } - - ext := osBFV.CreateOptsExt{ - CreateOptsBuilder: base, - BlockDevice: []osBFV.BlockDevice{ - osBFV.BlockDevice{ - UUID: "123456", - SourceType: osBFV.Image, - DestinationType: "volume", - VolumeSize: 10, - }, - }, - } - - expected := ` - { - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "block_device_mapping_v2":[ - { - "uuid":"123456", - "source_type":"image", - "destination_type":"volume", - "boot_index": "0", - "delete_on_termination": "false", - "volume_size": "10" - } - ] - } - } - ` - actual, err := ext.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go deleted file mode 100644 index 6bfc20c564..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go +++ /dev/null @@ -1,46 +0,0 @@ -package flavors - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" - "github.com/rackspace/gophercloud/pagination" -) - -// ListOpts helps control the results returned by the List() function. For example, a flavor with a -// minDisk field of 10 will not be returned if you specify MinDisk set to 20. -type ListOpts struct { - - // MinDisk and MinRAM, if provided, elide flavors that do not meet your criteria. - MinDisk int `q:"minDisk"` - MinRAM int `q:"minRam"` - - // Marker specifies the ID of the last flavor in the previous page. - Marker string `q:"marker"` - - // Limit instructs List to refrain from sending excessively large lists of flavors. - Limit int `q:"limit"` -} - -// ToFlavorListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToFlavorListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// ListDetail enumerates the server images available to your account. -func ListDetail(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.ListDetail(client, opts) -} - -// Get returns details about a single flavor, identity by ID. -func Get(client *gophercloud.ServiceClient, id string) os.GetResult { - return os.Get(client, id) -} - -// ExtractFlavors interprets a page of List results as Flavors. -func ExtractFlavors(page pagination.Page) ([]os.Flavor, error) { - return os.ExtractFlavors(page) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate_test.go deleted file mode 100644 index 204081dd17..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package flavors - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, ListOutput) - case "performance1-2": - fmt.Fprintf(w, `{ "flavors": [] }`) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) - - count := 0 - err := ListDetail(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - actual, err := ExtractFlavors(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedFlavorSlice, actual) - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestGetFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/flavors/performance1-1", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) - }) - - actual, err := Get(client.ServiceClient(), "performance1-1").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &Performance1Flavor, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/doc.go deleted file mode 100644 index 278229ab97..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package flavors provides information and interaction with the flavor -// API resource for the Rackspace Cloud Servers service. -package flavors diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go deleted file mode 100644 index 894f916f67..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go +++ /dev/null @@ -1,129 +0,0 @@ -// +build fixtures - -package flavors - -import ( - os "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" -) - -// ListOutput is a sample response of a flavor List request. -const ListOutput = ` -{ - "flavors": [ - { - "OS-FLV-EXT-DATA:ephemeral": 0, - "OS-FLV-WITH-EXT-SPECS:extra_specs": { - "class": "performance1", - "disk_io_index": "40", - "number_of_data_disks": "0", - "policy_class": "performance_flavor", - "resize_policy_class": "performance_flavor" - }, - "disk": 20, - "id": "performance1-1", - "links": [ - { - "href": "https://iad.servers.api.rackspacecloud.com/v2/864477/flavors/performance1-1", - "rel": "self" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/864477/flavors/performance1-1", - "rel": "bookmark" - } - ], - "name": "1 GB Performance", - "ram": 1024, - "rxtx_factor": 200, - "swap": "", - "vcpus": 1 - }, - { - "OS-FLV-EXT-DATA:ephemeral": 20, - "OS-FLV-WITH-EXT-SPECS:extra_specs": { - "class": "performance1", - "disk_io_index": "40", - "number_of_data_disks": "1", - "policy_class": "performance_flavor", - "resize_policy_class": "performance_flavor" - }, - "disk": 40, - "id": "performance1-2", - "links": [ - { - "href": "https://iad.servers.api.rackspacecloud.com/v2/864477/flavors/performance1-2", - "rel": "self" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/864477/flavors/performance1-2", - "rel": "bookmark" - } - ], - "name": "2 GB Performance", - "ram": 2048, - "rxtx_factor": 400, - "swap": "", - "vcpus": 2 - } - ] -}` - -// GetOutput is a sample response from a flavor Get request. Its contents correspond to the -// Performance1Flavor struct. -const GetOutput = ` -{ - "flavor": { - "OS-FLV-EXT-DATA:ephemeral": 0, - "OS-FLV-WITH-EXT-SPECS:extra_specs": { - "class": "performance1", - "disk_io_index": "40", - "number_of_data_disks": "0", - "policy_class": "performance_flavor", - "resize_policy_class": "performance_flavor" - }, - "disk": 20, - "id": "performance1-1", - "links": [ - { - "href": "https://iad.servers.api.rackspacecloud.com/v2/864477/flavors/performance1-1", - "rel": "self" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/864477/flavors/performance1-1", - "rel": "bookmark" - } - ], - "name": "1 GB Performance", - "ram": 1024, - "rxtx_factor": 200, - "swap": "", - "vcpus": 1 - } -} -` - -// Performance1Flavor is the expected result of parsing GetOutput, or the first element of -// ListOutput. -var Performance1Flavor = os.Flavor{ - ID: "performance1-1", - Disk: 20, - RAM: 1024, - Name: "1 GB Performance", - RxTxFactor: 200.0, - Swap: 0, - VCPUs: 1, -} - -// Performance2Flavor is the second result expected from parsing ListOutput. -var Performance2Flavor = os.Flavor{ - ID: "performance1-2", - Disk: 40, - RAM: 2048, - Name: "2 GB Performance", - RxTxFactor: 400.0, - Swap: 0, - VCPUs: 2, -} - -// ExpectedFlavorSlice is the slice of Flavor structs that are expected to be parsed from -// ListOutput. -var ExpectedFlavorSlice = []os.Flavor{Performance1Flavor, Performance2Flavor} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/delegate.go deleted file mode 100644 index 18e1f315af..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/delegate.go +++ /dev/null @@ -1,22 +0,0 @@ -package images - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/compute/v2/images" - "github.com/rackspace/gophercloud/pagination" -) - -// ListDetail enumerates the available server images. -func ListDetail(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.ListDetail(client, opts) -} - -// Get acquires additional detail about a specific image by ID. -func Get(client *gophercloud.ServiceClient, id string) os.GetResult { - return os.Get(client, id) -} - -// ExtractImages interprets a page as a collection of server images. -func ExtractImages(page pagination.Page) ([]os.Image, error) { - return os.ExtractImages(page) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/delegate_test.go deleted file mode 100644 index db0a6e3414..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/delegate_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package images - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListImageDetails(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/images/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - r.ParseForm() - marker := r.Form.Get("marker") - switch marker { - case "": - fmt.Fprintf(w, ListOutput) - case "e19a734c-c7e6-443a-830c-242209c4d65d": - fmt.Fprintf(w, `{ "images": [] }`) - default: - t.Fatalf("Unexpected marker: [%s]", marker) - } - }) - - count := 0 - err := ListDetail(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractImages(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedImageSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestGetImageDetails(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/images/e19a734c-c7e6-443a-830c-242209c4d65d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) - }) - - actual, err := Get(client.ServiceClient(), "e19a734c-c7e6-443a-830c-242209c4d65d").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &UbuntuImage, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/doc.go deleted file mode 100644 index cfae806712..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package images provides information and interaction with the image -// API resource for the Rackspace Cloud Servers service. -package images diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/fixtures.go deleted file mode 100644 index ccfbdc6a1e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/images/fixtures.go +++ /dev/null @@ -1,200 +0,0 @@ -// +build fixtures - -package images - -import ( - os "github.com/rackspace/gophercloud/openstack/compute/v2/images" -) - -// ListOutput is an example response from an /images/detail request. -const ListOutput = ` -{ - "images": [ - { - "OS-DCF:diskConfig": "MANUAL", - "OS-EXT-IMG-SIZE:size": 1.017415075e+09, - "created": "2014-10-01T15:49:02Z", - "id": "30aa010e-080e-4d4b-a7f9-09fc55b07d69", - "links": [ - { - "href": "https://iad.servers.api.rackspacecloud.com/v2/111222/images/30aa010e-080e-4d4b-a7f9-09fc55b07d69", - "rel": "self" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/111222/images/30aa010e-080e-4d4b-a7f9-09fc55b07d69", - "rel": "bookmark" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/111222/images/30aa010e-080e-4d4b-a7f9-09fc55b07d69", - "rel": "alternate", - "type": "application/vnd.openstack.image" - } - ], - "metadata": { - "auto_disk_config": "disabled", - "cache_in_nova": "True", - "com.rackspace__1__build_core": "1", - "com.rackspace__1__build_managed": "1", - "com.rackspace__1__build_rackconnect": "1", - "com.rackspace__1__options": "0", - "com.rackspace__1__platform_target": "PublicCloud", - "com.rackspace__1__release_build_date": "2014-10-01_15-46-08", - "com.rackspace__1__release_id": "100", - "com.rackspace__1__release_version": "10", - "com.rackspace__1__source": "kickstart", - "com.rackspace__1__visible_core": "1", - "com.rackspace__1__visible_managed": "0", - "com.rackspace__1__visible_rackconnect": "0", - "image_type": "base", - "org.openstack__1__architecture": "x64", - "org.openstack__1__os_distro": "org.archlinux", - "org.openstack__1__os_version": "2014.8", - "os_distro": "arch", - "os_type": "linux", - "vm_mode": "hvm" - }, - "minDisk": 20, - "minRam": 512, - "name": "Arch 2014.10 (PVHVM)", - "progress": 100, - "status": "ACTIVE", - "updated": "2014-10-01T19:37:58Z" - }, - { - "OS-DCF:diskConfig": "AUTO", - "OS-EXT-IMG-SIZE:size": 1.060306463e+09, - "created": "2014-10-01T12:58:11Z", - "id": "e19a734c-c7e6-443a-830c-242209c4d65d", - "links": [ - { - "href": "https://iad.servers.api.rackspacecloud.com/v2/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "self" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "bookmark" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "alternate", - "type": "application/vnd.openstack.image" - } - ], - "metadata": { - "auto_disk_config": "True", - "cache_in_nova": "True", - "com.rackspace__1__build_core": "1", - "com.rackspace__1__build_managed": "1", - "com.rackspace__1__build_rackconnect": "1", - "com.rackspace__1__options": "0", - "com.rackspace__1__platform_target": "PublicCloud", - "com.rackspace__1__release_build_date": "2014-10-01_12-31-03", - "com.rackspace__1__release_id": "1007", - "com.rackspace__1__release_version": "6", - "com.rackspace__1__source": "kickstart", - "com.rackspace__1__visible_core": "1", - "com.rackspace__1__visible_managed": "1", - "com.rackspace__1__visible_rackconnect": "1", - "image_type": "base", - "org.openstack__1__architecture": "x64", - "org.openstack__1__os_distro": "com.ubuntu", - "org.openstack__1__os_version": "14.04", - "os_distro": "ubuntu", - "os_type": "linux", - "vm_mode": "xen" - }, - "minDisk": 20, - "minRam": 512, - "name": "Ubuntu 14.04 LTS (Trusty Tahr)", - "progress": 100, - "status": "ACTIVE", - "updated": "2014-10-01T15:51:44Z" - } - ] -} -` - -// GetOutput is an example response from an /images request. -const GetOutput = ` -{ - "image": { - "OS-DCF:diskConfig": "AUTO", - "OS-EXT-IMG-SIZE:size": 1060306463, - "created": "2014-10-01T12:58:11Z", - "id": "e19a734c-c7e6-443a-830c-242209c4d65d", - "links": [ - { - "href": "https://iad.servers.api.rackspacecloud.com/v2/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "self" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "bookmark" - }, - { - "href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "alternate", - "type": "application/vnd.openstack.image" - } - ], - "metadata": { - "auto_disk_config": "True", - "cache_in_nova": "True", - "com.rackspace__1__build_core": "1", - "com.rackspace__1__build_managed": "1", - "com.rackspace__1__build_rackconnect": "1", - "com.rackspace__1__options": "0", - "com.rackspace__1__platform_target": "PublicCloud", - "com.rackspace__1__release_build_date": "2014-10-01_12-31-03", - "com.rackspace__1__release_id": "1007", - "com.rackspace__1__release_version": "6", - "com.rackspace__1__source": "kickstart", - "com.rackspace__1__visible_core": "1", - "com.rackspace__1__visible_managed": "1", - "com.rackspace__1__visible_rackconnect": "1", - "image_type": "base", - "org.openstack__1__architecture": "x64", - "org.openstack__1__os_distro": "com.ubuntu", - "org.openstack__1__os_version": "14.04", - "os_distro": "ubuntu", - "os_type": "linux", - "vm_mode": "xen" - }, - "minDisk": 20, - "minRam": 512, - "name": "Ubuntu 14.04 LTS (Trusty Tahr)", - "progress": 100, - "status": "ACTIVE", - "updated": "2014-10-01T15:51:44Z" - } -} -` - -// ArchImage is the first Image structure that should be parsed from ListOutput. -var ArchImage = os.Image{ - ID: "30aa010e-080e-4d4b-a7f9-09fc55b07d69", - Name: "Arch 2014.10 (PVHVM)", - Created: "2014-10-01T15:49:02Z", - Updated: "2014-10-01T19:37:58Z", - MinDisk: 20, - MinRAM: 512, - Progress: 100, - Status: "ACTIVE", -} - -// UbuntuImage is the second Image structure that should be parsed from ListOutput and -// the only image that should be extracted from GetOutput. -var UbuntuImage = os.Image{ - ID: "e19a734c-c7e6-443a-830c-242209c4d65d", - Name: "Ubuntu 14.04 LTS (Trusty Tahr)", - Created: "2014-10-01T12:58:11Z", - Updated: "2014-10-01T15:51:44Z", - MinDisk: 20, - MinRAM: 512, - Progress: 100, - Status: "ACTIVE", -} - -// ExpectedImageSlice is the collection of images that should be parsed from ListOutput, -// in order. -var ExpectedImageSlice = []os.Image{ArchImage, UbuntuImage} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/delegate.go deleted file mode 100644 index 3e53525dc7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/delegate.go +++ /dev/null @@ -1,33 +0,0 @@ -package keypairs - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" - "github.com/rackspace/gophercloud/pagination" -) - -// List returns a Pager that allows you to iterate over a collection of KeyPairs. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return os.List(client) -} - -// Create requests the creation of a new keypair on the server, or to import a pre-existing -// keypair. -func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(client, opts) -} - -// Get returns public data about a previously uploaded KeyPair. -func Get(client *gophercloud.ServiceClient, name string) os.GetResult { - return os.Get(client, name) -} - -// Delete requests the deletion of a previous stored KeyPair from the server. -func Delete(client *gophercloud.ServiceClient, name string) os.DeleteResult { - return os.Delete(client, name) -} - -// ExtractKeyPairs interprets a page of results as a slice of KeyPairs. -func ExtractKeyPairs(page pagination.Page) ([]os.KeyPair, error) { - return os.ExtractKeyPairs(page) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/delegate_test.go deleted file mode 100644 index 62e5df950c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/delegate_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package keypairs - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListSuccessfully(t) - - count := 0 - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractKeyPairs(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, os.ExpectedKeyPairSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleCreateSuccessfully(t) - - actual, err := Create(client.ServiceClient(), os.CreateOpts{ - Name: "createdkey", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &os.CreatedKeyPair, actual) -} - -func TestImport(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleImportSuccessfully(t) - - actual, err := Create(client.ServiceClient(), os.CreateOpts{ - Name: "importedkey", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &os.ImportedKeyPair, actual) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleGetSuccessfully(t) - - actual, err := Get(client.ServiceClient(), "firstkey").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &os.FirstKeyPair, actual) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleDeleteSuccessfully(t) - - err := Delete(client.ServiceClient(), "deletedkey").ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/doc.go deleted file mode 100644 index 31713752ea..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/keypairs/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package keypairs provides information and interaction with the keypair -// API resource for the Rackspace Cloud Servers service. -package keypairs diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/doc.go deleted file mode 100644 index 8e5c77382d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package networks provides information and interaction with the network -// API resource for the Rackspace Cloud Servers service. -package networks diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/requests.go deleted file mode 100644 index d3c973ecb2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/requests.go +++ /dev/null @@ -1,101 +0,0 @@ -package networks - -import ( - "errors" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// List returns a Pager which allows you to iterate over a collection of -// networks. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return NetworkPage{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(c, listURL(c), createPage) -} - -// Get retrieves a specific network based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) GetResult { - var res GetResult - _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - return res -} - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type CreateOptsBuilder interface { - ToNetworkCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is the common options struct used in this package's Create -// operation. -type CreateOpts struct { - // REQUIRED. See Network object for more info. - CIDR string - // REQUIRED. See Network object for more info. - Label string -} - -// ToNetworkCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { - n := make(map[string]interface{}) - - if opts.CIDR == "" { - return nil, errors.New("Required field CIDR not set.") - } - if opts.Label == "" { - return nil, errors.New("Required field Label not set.") - } - - n["label"] = opts.Label - n["cidr"] = opts.CIDR - return map[string]interface{}{"network": n}, nil -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -// -// The tenant ID that is contained in the URI is the tenant that creates the -// network. An admin user, however, has the option of specifying another tenant -// ID in the CreateOpts struct. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToNetworkCreateMap() - if err != nil { - res.Err = err - return res - } - - // Send request to API - _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201, 202}, - }) - return res -} - -// Delete accepts a unique ID and deletes the network associated with it. -func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(c, networkID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/requests_test.go deleted file mode 100644 index 6f44c1caba..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/requests_test.go +++ /dev/null @@ -1,156 +0,0 @@ -package networks - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-networksv2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "networks": [ - { - "label": "test-network-1", - "cidr": "192.168.100.0/24", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - }, - { - "label": "test-network-2", - "cidr": "192.30.250.00/18", - "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324" - } - ] -} - `) - }) - - client := fake.ServiceClient() - count := 0 - - err := List(client).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNetworks(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - expected := []Network{ - Network{ - Label: "test-network-1", - CIDR: "192.168.100.0/24", - ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - }, - Network{ - Label: "test-network-2", - CIDR: "192.30.250.00/18", - ID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-networksv2/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "label": "test-network-1", - "cidr": "192.168.100.0/24", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.CIDR, "192.168.100.0/24") - th.AssertEquals(t, n.Label, "test-network-1") - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-networksv2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "label": "test-network-1", - "cidr": "192.168.100.0/24" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "network": { - "label": "test-network-1", - "cidr": "192.168.100.0/24", - "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - } -} - `) - }) - - options := CreateOpts{Label: "test-network-1", CIDR: "192.168.100.0/24"} - n, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Label, "test-network-1") - th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-networksv2/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/results.go deleted file mode 100644 index eb6a76c008..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/results.go +++ /dev/null @@ -1,81 +0,0 @@ -package networks - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a network resource. -func (r commonResult) Extract() (*Network, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - Network *Network `json:"network"` - } - - err := mapstructure.Decode(r.Body, &res) - - return res.Network, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// Network represents, well, a network. -type Network struct { - // UUID for the network - ID string `mapstructure:"id" json:"id"` - - // Human-readable name for the network. Might not be unique. - Label string `mapstructure:"label" json:"label"` - - // Classless Inter-Domain Routing - CIDR string `mapstructure:"cidr" json:"cidr"` -} - -// NetworkPage is the page returned by a pager when traversing over a -// collection of networks. -type NetworkPage struct { - pagination.SinglePageBase -} - -// IsEmpty returns true if the NetworkPage contains no Networks. -func (r NetworkPage) IsEmpty() (bool, error) { - networks, err := ExtractNetworks(r) - if err != nil { - return true, err - } - return len(networks) == 0, nil -} - -// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct, -// and extracts the elements into a slice of Network structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractNetworks(page pagination.Page) ([]Network, error) { - var resp struct { - Networks []Network `mapstructure:"networks" json:"networks"` - } - - err := mapstructure.Decode(page.(NetworkPage).Body, &resp) - - return resp.Networks, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/urls.go deleted file mode 100644 index 19a21aa90d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/urls.go +++ /dev/null @@ -1,27 +0,0 @@ -package networks - -import "github.com/rackspace/gophercloud" - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("os-networksv2", id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("os-networksv2") -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/urls_test.go deleted file mode 100644 index 983992e2b9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/networks/urls_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package networks - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestGetURL(t *testing.T) { - actual := getURL(endpointClient(), "foo") - expected := endpoint + "os-networksv2/foo" - th.AssertEquals(t, expected, actual) -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "os-networksv2" - th.AssertEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := createURL(endpointClient()) - expected := endpoint + "os-networksv2" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "foo") - expected := endpoint + "os-networksv2/foo" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/delegate.go deleted file mode 100644 index 4c7b24909a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/delegate.go +++ /dev/null @@ -1,61 +0,0 @@ -package servers - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" -) - -// List makes a request against the API to list servers accessible to you. -func List(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.List(client, opts) -} - -// Create requests a server to be provisioned to the user in the current tenant. -func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(client, opts) -} - -// Delete requests that a server previously provisioned be removed from your account. -func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult { - return os.Delete(client, id) -} - -// Get requests details on a single server, by ID. -func Get(client *gophercloud.ServiceClient, id string) os.GetResult { - return os.Get(client, id) -} - -// ChangeAdminPassword alters the administrator or root password for a specified server. -func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) os.ActionResult { - return os.ChangeAdminPassword(client, id, newPassword) -} - -// Reboot requests that a given server reboot. Two methods exist for rebooting a server: -// -// os.HardReboot (aka PowerCycle) restarts the server instance by physically cutting power to the -// machine, or if a VM, terminating it at the hypervisor level. It's done. Caput. Full stop. Then, -// after a brief wait, power is restored or the VM instance restarted. -// -// os.SoftReboot (aka OSReboot) simply tells the OS to restart under its own procedures. E.g., in -// Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to restart the machine. -func Reboot(client *gophercloud.ServiceClient, id string, how os.RebootMethod) os.ActionResult { - return os.Reboot(client, id, how) -} - -// Rebuild will reprovision the server according to the configuration options provided in the -// RebuildOpts struct. -func Rebuild(client *gophercloud.ServiceClient, id string, opts os.RebuildOptsBuilder) os.RebuildResult { - return os.Rebuild(client, id, opts) -} - -// WaitForStatus will continually poll a server until it successfully transitions to a specified -// status. It will do this for at most the number of seconds specified. -func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error { - return os.WaitForStatus(c, id, status, secs) -} - -// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities. -func ExtractServers(page pagination.Page) ([]os.Server, error) { - return os.ExtractServers(page) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/delegate_test.go deleted file mode 100644 index 7f414040f7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/delegate_test.go +++ /dev/null @@ -1,112 +0,0 @@ -package servers - -import ( - "fmt" - "net/http" - "testing" - - os "github.com/rackspace/gophercloud/openstack/compute/v2/servers" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListOutput) - }) - - count := 0 - err := List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractServers(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedServerSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleServerCreationSuccessfully(t, CreateOutput) - - actual, err := Create(client.ServiceClient(), os.CreateOpts{ - Name: "derp", - ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", - FlavorRef: "1", - }).Extract() - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, &CreatedServer, actual) -} - -func TestDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleServerDeletionSuccessfully(t) - - res := Delete(client.ServiceClient(), "asdfasdfasdf") - th.AssertNoErr(t, res.Err) -} - -func TestGetServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetOutput) - }) - - actual, err := Get(client.ServiceClient(), "8c65cb68-0681-4c30-bc88-6b83a8a26aee").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &GophercloudServer, actual) -} - -func TestChangeAdminPassword(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleAdminPasswordChangeSuccessfully(t) - - res := ChangeAdminPassword(client.ServiceClient(), "1234asdf", "new-password") - th.AssertNoErr(t, res.Err) -} - -func TestReboot(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleRebootSuccessfully(t) - - res := Reboot(client.ServiceClient(), "1234asdf", os.SoftReboot) - th.AssertNoErr(t, res.Err) -} - -func TestRebuildServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleRebuildSuccessfully(t, GetOutput) - - opts := os.RebuildOpts{ - Name: "new-name", - AdminPass: "swordfish", - ImageID: "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", - AccessIPv4: "1.2.3.4", - } - actual, err := Rebuild(client.ServiceClient(), "1234asdf", opts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &GophercloudServer, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/doc.go deleted file mode 100644 index c9f77f6945..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package servers provides information and interaction with the server -// API resource for the Rackspace Cloud Servers service. -package servers diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/fixtures.go deleted file mode 100644 index b22a28998d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/fixtures.go +++ /dev/null @@ -1,439 +0,0 @@ -// +build fixtures - -package servers - -import ( - os "github.com/rackspace/gophercloud/openstack/compute/v2/servers" -) - -// ListOutput is the recorded output of a Rackspace servers.List request. -const ListOutput = ` -{ - "servers": [ - { - "OS-DCF:diskConfig": "MANUAL", - "OS-EXT-STS:power_state": 1, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "accessIPv4": "1.2.3.4", - "accessIPv6": "1111:4822:7818:121:2000:9b5e:7438:a2d0", - "addresses": { - "private": [ - { - "addr": "10.208.230.113", - "version": 4 - } - ], - "public": [ - { - "addr": "2001:4800:7818:101:2000:9b5e:7428:a2d0", - "version": 6 - }, - { - "addr": "104.130.131.164", - "version": 4 - } - ] - }, - "created": "2014-09-23T12:34:58Z", - "flavor": { - "id": "performance1-8", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-8", - "rel": "bookmark" - } - ] - }, - "hostId": "e8951a524bc465b0898aeac7674da6fe1495e253ae1ea17ddb2c2475", - "id": "59818cee-bc8c-44eb-8073-673ee65105f7", - "image": { - "id": "255df5fb-e3d4-45a3-9a07-c976debf7c14", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/images/255df5fb-e3d4-45a3-9a07-c976debf7c14", - "rel": "bookmark" - } - ] - }, - "key_name": "mykey", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/59818cee-bc8c-44eb-8073-673ee65105f7", - "rel": "self" - }, - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/59818cee-bc8c-44eb-8073-673ee65105f7", - "rel": "bookmark" - } - ], - "metadata": {}, - "name": "devstack", - "progress": 100, - "status": "ACTIVE", - "tenant_id": "111111", - "updated": "2014-09-23T12:38:19Z", - "user_id": "14ae7bb21d81422694655f3cc30f2930" - }, - { - "OS-DCF:diskConfig": "MANUAL", - "OS-EXT-STS:power_state": 1, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "accessIPv4": "1.1.2.3", - "accessIPv6": "2222:4444:7817:101:be76:4eff:f0e5:9e02", - "addresses": { - "private": [ - { - "addr": "10.10.20.30", - "version": 4 - } - ], - "public": [ - { - "addr": "1.1.2.3", - "version": 4 - }, - { - "addr": "2222:4444:7817:101:be76:4eff:f0e5:9e02", - "version": 6 - } - ] - }, - "created": "2014-07-21T19:32:55Z", - "flavor": { - "id": "performance1-2", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-2", - "rel": "bookmark" - } - ] - }, - "hostId": "f859679906d6b1a38c1bd516b78f4dcc7d5fcf012578fa3ce460716c", - "id": "25f1c7f5-e00a-4715-b354-16e24b2f4630", - "image": { - "id": "bb02b1a3-bc77-4d17-ab5b-421d89850fca", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/images/bb02b1a3-bc77-4d17-ab5b-421d89850fca", - "rel": "bookmark" - } - ] - }, - "key_name": "otherkey", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630", - "rel": "self" - }, - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630", - "rel": "bookmark" - } - ], - "metadata": {}, - "name": "peril-dfw", - "progress": 100, - "status": "ACTIVE", - "tenant_id": "111111", - "updated": "2014-07-21T19:34:24Z", - "user_id": "14ae7bb21d81422694655f3cc30f2930" - } - ] -} -` - -// GetOutput is the recorded output of a Rackspace servers.Get request. -const GetOutput = ` -{ - "server": { - "OS-DCF:diskConfig": "AUTO", - "OS-EXT-STS:power_state": 1, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "accessIPv4": "1.2.4.8", - "accessIPv6": "2001:4800:6666:105:2a0f:c056:f594:7777", - "addresses": { - "private": [ - { - "addr": "10.20.40.80", - "version": 4 - } - ], - "public": [ - { - "addr": "1.2.4.8", - "version": 4 - }, - { - "addr": "2001:4800:6666:105:2a0f:c056:f594:7777", - "version": 6 - } - ] - }, - "created": "2014-10-21T14:42:16Z", - "flavor": { - "id": "performance1-1", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-1", - "rel": "bookmark" - } - ] - }, - "hostId": "430d2ae02de0a7af77012c94778145eccf67e75b1fac0528aa10d4a7", - "id": "8c65cb68-0681-4c30-bc88-6b83a8a26aee", - "image": { - "id": "e19a734c-c7e6-443a-830c-242209c4d65d", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "bookmark" - } - ] - }, - "key_name": null, - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee", - "rel": "self" - }, - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee", - "rel": "bookmark" - } - ], - "metadata": {}, - "name": "Gophercloud-pxpGGuey", - "progress": 100, - "status": "ACTIVE", - "tenant_id": "111111", - "updated": "2014-10-21T14:42:57Z", - "user_id": "14ae7bb21d81423694655f4dd30f2930" - } -} -` - -// CreateOutput contains a sample of Rackspace's response to a Create call. -const CreateOutput = ` -{ - "server": { - "OS-DCF:diskConfig": "AUTO", - "adminPass": "v7tADqbE5pr9", - "id": "bb63327b-6a2f-34bc-b0ef-4b6d97ea637e", - "links": [ - { - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/bb63327b-6a2f-34bc-b0ef-4b6d97ea637e", - "rel": "self" - }, - { - "href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/bb63327b-6a2f-34bc-b0ef-4b6d97ea637e", - "rel": "bookmark" - } - ] - } -} -` - -// DevstackServer is the expected first result from parsing ListOutput. -var DevstackServer = os.Server{ - ID: "59818cee-bc8c-44eb-8073-673ee65105f7", - Name: "devstack", - TenantID: "111111", - UserID: "14ae7bb21d81422694655f3cc30f2930", - HostID: "e8951a524bc465b0898aeac7674da6fe1495e253ae1ea17ddb2c2475", - Updated: "2014-09-23T12:38:19Z", - Created: "2014-09-23T12:34:58Z", - AccessIPv4: "1.2.3.4", - AccessIPv6: "1111:4822:7818:121:2000:9b5e:7438:a2d0", - Progress: 100, - Status: "ACTIVE", - Image: map[string]interface{}{ - "id": "255df5fb-e3d4-45a3-9a07-c976debf7c14", - "links": []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/images/255df5fb-e3d4-45a3-9a07-c976debf7c14", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "performance1-8", - "links": []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-8", - "rel": "bookmark", - }, - }, - }, - Addresses: map[string]interface{}{ - "private": []interface{}{ - map[string]interface{}{ - "addr": "10.20.30.40", - "version": float64(4.0), - }, - }, - "public": []interface{}{ - map[string]interface{}{ - "addr": "1111:4822:7818:121:2000:9b5e:7438:a2d0", - "version": float64(6.0), - }, - map[string]interface{}{ - "addr": "1.2.3.4", - "version": float64(4.0), - }, - }, - }, - Metadata: map[string]interface{}{}, - Links: []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/59918cee-bd9d-44eb-8173-673ee75105f7", - "rel": "self", - }, - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/59818cee-bc8c-44eb-8073-673ee65105f7", - "rel": "bookmark", - }, - }, - KeyName: "mykey", - AdminPass: "", -} - -// PerilServer is the expected second result from parsing ListOutput. -var PerilServer = os.Server{ - ID: "25f1c7f5-e00a-4715-b354-16e24b2f4630", - Name: "peril-dfw", - TenantID: "111111", - UserID: "14ae7bb21d81422694655f3cc30f2930", - HostID: "f859679906d6b1a38c1bd516b78f4dcc7d5fcf012578fa3ce460716c", - Updated: "2014-07-21T19:34:24Z", - Created: "2014-07-21T19:32:55Z", - AccessIPv4: "1.1.2.3", - AccessIPv6: "2222:4444:7817:101:be76:4eff:f0e5:9e02", - Progress: 100, - Status: "ACTIVE", - Image: map[string]interface{}{ - "id": "bb02b1a3-bc77-4d17-ab5b-421d89850fca", - "links": []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/images/bb02b1a3-bc77-4d17-ab5b-421d89850fca", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "performance1-2", - "links": []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-2", - "rel": "bookmark", - }, - }, - }, - Addresses: map[string]interface{}{ - "private": []interface{}{ - map[string]interface{}{ - "addr": "10.10.20.30", - "version": float64(4.0), - }, - }, - "public": []interface{}{ - map[string]interface{}{ - "addr": "2222:4444:7817:101:be76:4eff:f0e5:9e02", - "version": float64(6.0), - }, - map[string]interface{}{ - "addr": "1.1.2.3", - "version": float64(4.0), - }, - }, - }, - Metadata: map[string]interface{}{}, - Links: []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630", - "rel": "self", - }, - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630", - "rel": "bookmark", - }, - }, - KeyName: "otherkey", - AdminPass: "", -} - -// GophercloudServer is the expected result from parsing GetOutput. -var GophercloudServer = os.Server{ - ID: "8c65cb68-0681-4c30-bc88-6b83a8a26aee", - Name: "Gophercloud-pxpGGuey", - TenantID: "111111", - UserID: "14ae7bb21d81423694655f4dd30f2930", - HostID: "430d2ae02de0a7af77012c94778145eccf67e75b1fac0528aa10d4a7", - Updated: "2014-10-21T14:42:57Z", - Created: "2014-10-21T14:42:16Z", - AccessIPv4: "1.2.4.8", - AccessIPv6: "2001:4800:6666:105:2a0f:c056:f594:7777", - Progress: 100, - Status: "ACTIVE", - Image: map[string]interface{}{ - "id": "e19a734c-c7e6-443a-830c-242209c4d65d", - "links": []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/images/e19a734c-c7e6-443a-830c-242209c4d65d", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "performance1-1", - "links": []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-1", - "rel": "bookmark", - }, - }, - }, - Addresses: map[string]interface{}{ - "private": []interface{}{ - map[string]interface{}{ - "addr": "10.20.40.80", - "version": float64(4.0), - }, - }, - "public": []interface{}{ - map[string]interface{}{ - "addr": "2001:4800:6666:105:2a0f:c056:f594:7777", - "version": float64(6.0), - }, - map[string]interface{}{ - "addr": "1.2.4.8", - "version": float64(4.0), - }, - }, - }, - Metadata: map[string]interface{}{}, - Links: []interface{}{ - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee", - "rel": "self", - }, - map[string]interface{}{ - "href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee", - "rel": "bookmark", - }, - }, - KeyName: "", - AdminPass: "", -} - -// CreatedServer is the partial Server struct that can be parsed from CreateOutput. -var CreatedServer = os.Server{ - ID: "bb63327b-6a2f-34bc-b0ef-4b6d97ea637e", - AdminPass: "v7tADqbE5pr9", - Links: []interface{}{}, -} - -// ExpectedServerSlice is the collection of servers, in order, that should be parsed from ListOutput. -var ExpectedServerSlice = []os.Server{DevstackServer, PerilServer} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go deleted file mode 100644 index 809183ec7c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go +++ /dev/null @@ -1,163 +0,0 @@ -package servers - -import ( - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig" - os "github.com/rackspace/gophercloud/openstack/compute/v2/servers" -) - -// CreateOpts specifies all of the options that Rackspace accepts in its Create request, including -// the union of all extensions that Rackspace supports. -type CreateOpts struct { - // Name [required] is the name to assign to the newly launched server. - Name string - - // ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state. - // Optional if using the boot-from-volume extension. - ImageRef string - - // FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs. - FlavorRef string - - // SecurityGroups [optional] lists the names of the security groups to which this server should belong. - SecurityGroups []string - - // UserData [optional] contains configuration information or scripts to use upon launch. - // Create will base64-encode it for you. - UserData []byte - - // AvailabilityZone [optional] in which to launch the server. - AvailabilityZone string - - // Networks [optional] dictates how this server will be attached to available networks. - // By default, the server will be attached to all isolated networks for the tenant. - Networks []os.Network - - // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. - Metadata map[string]string - - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte - - // ConfigDrive [optional] enables metadata injection through a configuration drive. - ConfigDrive bool - - // AdminPass [optional] sets the root user password. If not set, a randomly-generated - // password will be created and returned in the response. - AdminPass string - - // Rackspace-specific extensions begin here. - - // KeyPair [optional] specifies the name of the SSH KeyPair to be injected into the newly launched - // server. See the "keypairs" extension in OpenStack compute v2. - KeyPair string - - // DiskConfig [optional] controls how the created server's disk is partitioned. See the "diskconfig" - // extension in OpenStack compute v2. - DiskConfig diskconfig.DiskConfig - - // BlockDevice [optional] will create the server from a volume, which is created from an image, - // a snapshot, or an another volume. - BlockDevice []bootfromvolume.BlockDevice -} - -// ToServerCreateMap constructs a request body using all of the OpenStack extensions that are -// active on Rackspace. -func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { - base := os.CreateOpts{ - Name: opts.Name, - ImageRef: opts.ImageRef, - FlavorRef: opts.FlavorRef, - SecurityGroups: opts.SecurityGroups, - UserData: opts.UserData, - AvailabilityZone: opts.AvailabilityZone, - Networks: opts.Networks, - Metadata: opts.Metadata, - Personality: opts.Personality, - ConfigDrive: opts.ConfigDrive, - AdminPass: opts.AdminPass, - } - - drive := diskconfig.CreateOptsExt{ - CreateOptsBuilder: base, - DiskConfig: opts.DiskConfig, - } - - res, err := drive.ToServerCreateMap() - if err != nil { - return nil, err - } - - if len(opts.BlockDevice) != 0 { - bfv := bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: drive, - BlockDevice: opts.BlockDevice, - } - - res, err = bfv.ToServerCreateMap() - if err != nil { - return nil, err - } - } - - // key_name doesn't actually come from the extension (or at least isn't documented there) so - // we need to add it manually. - serverMap := res["server"].(map[string]interface{}) - serverMap["key_name"] = opts.KeyPair - - return res, nil -} - -// RebuildOpts represents all of the configuration options used in a server rebuild operation that -// are supported by Rackspace. -type RebuildOpts struct { - // Required. The ID of the image you want your server to be provisioned on - ImageID string - - // Name to set the server to - Name string - - // Required. The server's admin password - AdminPass string - - // AccessIPv4 [optional] provides a new IPv4 address for the instance. - AccessIPv4 string - - // AccessIPv6 [optional] provides a new IPv6 address for the instance. - AccessIPv6 string - - // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. - Metadata map[string]string - - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte - - // Rackspace-specific stuff begins here. - - // DiskConfig [optional] controls how the created server's disk is partitioned. See the "diskconfig" - // extension in OpenStack compute v2. - DiskConfig diskconfig.DiskConfig -} - -// ToServerRebuildMap constructs a request body using all of the OpenStack extensions that are -// active on Rackspace. -func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) { - base := os.RebuildOpts{ - ImageID: opts.ImageID, - Name: opts.Name, - AdminPass: opts.AdminPass, - AccessIPv4: opts.AccessIPv4, - AccessIPv6: opts.AccessIPv6, - Metadata: opts.Metadata, - Personality: opts.Personality, - } - - drive := diskconfig.RebuildOptsExt{ - RebuildOptsBuilder: base, - DiskConfig: opts.DiskConfig, - } - - return drive.ToServerRebuildMap() -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go deleted file mode 100644 index 3c0f806936..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package servers - -import ( - "testing" - - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestCreateOpts(t *testing.T) { - opts := CreateOpts{ - Name: "createdserver", - ImageRef: "image-id", - FlavorRef: "flavor-id", - KeyPair: "mykey", - DiskConfig: diskconfig.Manual, - } - - expected := ` - { - "server": { - "name": "createdserver", - "imageRef": "image-id", - "flavorRef": "flavor-id", - "key_name": "mykey", - "OS-DCF:diskConfig": "MANUAL" - } - } - ` - actual, err := opts.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expected, actual) -} - -func TestRebuildOpts(t *testing.T) { - opts := RebuildOpts{ - Name: "rebuiltserver", - AdminPass: "swordfish", - ImageID: "asdfasdfasdf", - DiskConfig: diskconfig.Auto, - } - - actual, err := opts.ToServerRebuildMap() - th.AssertNoErr(t, err) - - expected := ` - { - "rebuild": { - "name": "rebuiltserver", - "imageRef": "asdfasdfasdf", - "adminPass": "swordfish", - "OS-DCF:diskConfig": "AUTO" - } - } - ` - th.CheckJSONEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/requests.go deleted file mode 100644 index bfe3487861..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/requests.go +++ /dev/null @@ -1,51 +0,0 @@ -package virtualinterfaces - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - "github.com/racker/perigee" -) - -// List returns a Pager which allows you to iterate over a collection of -// networks. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, instanceID string) pagination.Pager { - createPage := func(r pagination.PageResult) pagination.Page { - return VirtualInterfacePage{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(c, listURL(c, instanceID), createPage) -} - -// Create creates a new virtual interface for a network and attaches the network -// to the server instance. -func Create(c *gophercloud.ServiceClient, instanceID, networkID string) CreateResult { - var res CreateResult - - reqBody := map[string]map[string]string{ - "virtual_interface": { - "network_id": networkID, - }, - } - - // Send request to API - _, res.Err = perigee.Request("POST", createURL(c, instanceID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200, 201, 202}, - }) - return res -} - -// Delete deletes the interface with interfaceID attached to the instance with -// instanceID. -func Delete(c *gophercloud.ServiceClient, instanceID, interfaceID string) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", deleteURL(c, instanceID, interfaceID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{200, 204}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/requests_test.go deleted file mode 100644 index d40af9c462..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/requests_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package virtualinterfaces - -import ( - "fmt" - "net/http" - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/12345/os-virtual-interfacesv2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "virtual_interfaces": [ - { - "id": "de7c6d53-b895-4b4a-963c-517ccb0f0775", - "ip_addresses": [ - { - "address": "192.168.0.2", - "network_id": "f212726e-6321-4210-9bae-a13f5a33f83f", - "network_label": "superprivate_xml" - } - ], - "mac_address": "BC:76:4E:04:85:20" - }, - { - "id": "e14e789d-3b98-44a6-9c2d-c23eb1d1465c", - "ip_addresses": [ - { - "address": "10.181.1.30", - "network_id": "3b324a1b-31b8-4db5-9fe5-4a2067f60297", - "network_label": "private" - } - ], - "mac_address": "BC:76:4E:04:81:55" - } - ] -} - `) - }) - - client := fake.ServiceClient() - count := 0 - - err := List(client, "12345").EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVirtualInterfaces(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - expected := []VirtualInterface{ - VirtualInterface{ - MACAddress: "BC:76:4E:04:85:20", - IPAddresses: []IPAddress{ - IPAddress{ - Address: "192.168.0.2", - NetworkID: "f212726e-6321-4210-9bae-a13f5a33f83f", - NetworkLabel: "superprivate_xml", - }, - }, - ID: "de7c6d53-b895-4b4a-963c-517ccb0f0775", - }, - VirtualInterface{ - MACAddress: "BC:76:4E:04:81:55", - IPAddresses: []IPAddress{ - IPAddress{ - Address: "10.181.1.30", - NetworkID: "3b324a1b-31b8-4db5-9fe5-4a2067f60297", - NetworkLabel: "private", - }, - }, - ID: "e14e789d-3b98-44a6-9c2d-c23eb1d1465c", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/12345/os-virtual-interfacesv2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "virtual_interface": { - "network_id": "6789" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, `{ - "virtual_interfaces": [ - { - "id": "de7c6d53-b895-4b4a-963c-517ccb0f0775", - "ip_addresses": [ - { - "address": "192.168.0.2", - "network_id": "f212726e-6321-4210-9bae-a13f5a33f83f", - "network_label": "superprivate_xml" - } - ], - "mac_address": "BC:76:4E:04:85:20" - } - ] - }`) - }) - - expected := &VirtualInterface{ - MACAddress: "BC:76:4E:04:85:20", - IPAddresses: []IPAddress{ - IPAddress{ - Address: "192.168.0.2", - NetworkID: "f212726e-6321-4210-9bae-a13f5a33f83f", - NetworkLabel: "superprivate_xml", - }, - }, - ID: "de7c6d53-b895-4b4a-963c-517ccb0f0775", - } - - actual, err := Create(fake.ServiceClient(), "12345", "6789").Extract() - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, expected, actual) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/12345/os-virtual-interfacesv2/6789", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "12345", "6789") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/results.go deleted file mode 100644 index 26fa7f31ce..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/results.go +++ /dev/null @@ -1,81 +0,0 @@ -package virtualinterfaces - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a network resource. -func (r commonResult) Extract() (*VirtualInterface, error) { - if r.Err != nil { - return nil, r.Err - } - - var res struct { - VirtualInterfaces []VirtualInterface `mapstructure:"virtual_interfaces" json:"virtual_interfaces"` - } - - err := mapstructure.Decode(r.Body, &res) - - return &res.VirtualInterfaces[0], err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// IPAddress represents a vitual address attached to a VirtualInterface. -type IPAddress struct { - Address string `mapstructure:"address" json:"address"` - NetworkID string `mapstructure:"network_id" json:"network_id"` - NetworkLabel string `mapstructure:"network_label" json:"network_label"` -} - -// VirtualInterface represents a virtual interface. -type VirtualInterface struct { - // UUID for the virtual interface - ID string `mapstructure:"id" json:"id"` - - MACAddress string `mapstructure:"mac_address" json:"mac_address"` - - IPAddresses []IPAddress `mapstructure:"ip_addresses" json:"ip_addresses"` -} - -// VirtualInterfacePage is the page returned by a pager when traversing over a -// collection of virtual interfaces. -type VirtualInterfacePage struct { - pagination.SinglePageBase -} - -// IsEmpty returns true if the NetworkPage contains no Networks. -func (r VirtualInterfacePage) IsEmpty() (bool, error) { - networks, err := ExtractVirtualInterfaces(r) - if err != nil { - return true, err - } - return len(networks) == 0, nil -} - -// ExtractVirtualInterfaces accepts a Page struct, specifically a VirtualInterfacePage struct, -// and extracts the elements into a slice of VirtualInterface structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractVirtualInterfaces(page pagination.Page) ([]VirtualInterface, error) { - var resp struct { - VirtualInterfaces []VirtualInterface `mapstructure:"virtual_interfaces" json:"virtual_interfaces"` - } - - err := mapstructure.Decode(page.(VirtualInterfacePage).Body, &resp) - - return resp.VirtualInterfaces, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/urls.go deleted file mode 100644 index 9e5693e849..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package virtualinterfaces - -import "github.com/rackspace/gophercloud" - -func listURL(c *gophercloud.ServiceClient, instanceID string) string { - return c.ServiceURL("servers", instanceID, "os-virtual-interfacesv2") -} - -func createURL(c *gophercloud.ServiceClient, instanceID string) string { - return c.ServiceURL("servers", instanceID, "os-virtual-interfacesv2") -} - -func deleteURL(c *gophercloud.ServiceClient, instanceID, interfaceID string) string { - return c.ServiceURL("servers", instanceID, "os-virtual-interfacesv2", interfaceID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/urls_test.go deleted file mode 100644 index 6732e4ed9f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/virtualinterfaces/urls_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package virtualinterfaces - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestCreateURL(t *testing.T) { - actual := createURL(endpointClient(), "12345") - expected := endpoint + "servers/12345/os-virtual-interfacesv2" - th.AssertEquals(t, expected, actual) -} - -func TestListURL(t *testing.T) { - actual := createURL(endpointClient(), "12345") - expected := endpoint + "servers/12345/os-virtual-interfacesv2" - th.AssertEquals(t, expected, actual) -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient(), "12345", "6789") - expected := endpoint + "servers/12345/os-virtual-interfacesv2/6789" - th.AssertEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/delegate.go deleted file mode 100644 index fc547cde5f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/delegate.go +++ /dev/null @@ -1,24 +0,0 @@ -package extensions - -import ( - "github.com/rackspace/gophercloud" - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the -// elements into a slice of os.Extension structs. -func ExtractExtensions(page pagination.Page) ([]common.Extension, error) { - return common.ExtractExtensions(page) -} - -// Get retrieves information for a specific extension using its alias. -func Get(c *gophercloud.ServiceClient, alias string) common.GetResult { - return common.Get(c, alias) -} - -// List returns a Pager which allows you to iterate over the full collection of extensions. -// It does not accept query parameters. -func List(c *gophercloud.ServiceClient) pagination.Pager { - return common.List(c) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/delegate_test.go deleted file mode 100644 index e30f79404d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/delegate_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package extensions - -import ( - "testing" - - common "github.com/rackspace/gophercloud/openstack/common/extensions" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - common.HandleListExtensionsSuccessfully(t) - - count := 0 - - err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractExtensions(page) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, common.ExpectedExtensions, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - common.HandleGetExtensionSuccessfully(t) - - actual, err := Get(fake.ServiceClient(), "agent").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, common.SingleExtension, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/doc.go deleted file mode 100644 index b02a95b534..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/extensions/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package extensions provides information and interaction with the all the -// extensions available for the Rackspace Identity service. -package extensions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/delegate.go deleted file mode 100644 index a6c01e4f2d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/delegate.go +++ /dev/null @@ -1,53 +0,0 @@ -package roles - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - - os "github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles" -) - -// List is the operation responsible for listing all available global roles -// that a user can adopt. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return os.List(client) -} - -// AddUserRole is the operation responsible for assigning a particular role to -// a user. This is confined to the scope of the user's tenant - so the tenant -// ID is a required argument. -func AddUserRole(client *gophercloud.ServiceClient, userID, roleID string) UserRoleResult { - var result UserRoleResult - - _, result.Err = perigee.Request("PUT", userRoleURL(client, userID, roleID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200, 201}, - }) - - return result -} - -// DeleteUserRole is the operation responsible for deleting a particular role -// from a user. This is confined to the scope of the user's tenant - so the -// tenant ID is a required argument. -func DeleteUserRole(client *gophercloud.ServiceClient, userID, roleID string) UserRoleResult { - var result UserRoleResult - - _, result.Err = perigee.Request("DELETE", userRoleURL(client, userID, roleID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{204}, - }) - - return result -} - -// UserRoleResult represents the result of either an AddUserRole or -// a DeleteUserRole operation. -type UserRoleResult struct { - gophercloud.ErrResult -} - -func userRoleURL(c *gophercloud.ServiceClient, userID, roleID string) string { - return c.ServiceURL(os.UserPath, userID, os.RolePath, os.ExtPath, roleID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/delegate_test.go deleted file mode 100644 index fcee97d0bc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/delegate_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package roles - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockListRoleResponse(t) - - count := 0 - - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := os.ExtractRoles(page) - if err != nil { - t.Errorf("Failed to extract users: %v", err) - return false, err - } - - expected := []os.Role{ - os.Role{ - ID: "123", - Name: "compute:admin", - Description: "Nova Administrator", - ServiceID: "cke5372ebabeeabb70a0e702a4626977x4406e5", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestAddUserRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockAddUserRoleResponse(t) - - err := AddUserRole(client.ServiceClient(), "{user_id}", "{role_id}").ExtractErr() - - th.AssertNoErr(t, err) -} - -func TestDeleteUserRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - MockDeleteUserRoleResponse(t) - - err := DeleteUserRole(client.ServiceClient(), "{user_id}", "{role_id}").ExtractErr() - - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/fixtures.go deleted file mode 100644 index 5f22d0f642..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/roles/fixtures.go +++ /dev/null @@ -1,49 +0,0 @@ -package roles - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func MockListRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/OS-KSADM/roles", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "roles": [ - { - "id": "123", - "name": "compute:admin", - "description": "Nova Administrator", - "serviceId": "cke5372ebabeeabb70a0e702a4626977x4406e5" - } - ] -} - `) - }) -} - -func MockAddUserRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusCreated) - }) -} - -func MockDeleteUserRoleResponse(t *testing.T) { - th.Mux.HandleFunc("/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/delegate.go deleted file mode 100644 index 6cdd0cfbdc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/delegate.go +++ /dev/null @@ -1,17 +0,0 @@ -package tenants - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/identity/v2/tenants" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtractTenants interprets a page of List results as a more usable slice of Tenant structs. -func ExtractTenants(page pagination.Page) ([]os.Tenant, error) { - return os.ExtractTenants(page) -} - -// List enumerates the tenants to which the current token grants access. -func List(client *gophercloud.ServiceClient, opts *os.ListOpts) pagination.Pager { - return os.List(client, opts) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/delegate_test.go deleted file mode 100644 index eccbfe23eb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/delegate_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package tenants - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/identity/v2/tenants" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListTenants(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListTenantsSuccessfully(t) - - count := 0 - err := List(fake.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - actual, err := ExtractTenants(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, os.ExpectedTenantSlice, actual) - - count++ - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/doc.go deleted file mode 100644 index c1825c21dc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tenants/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package tenants provides information and interaction with the tenant -// API resource for the Rackspace Identity service. -package tenants diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate_test.go deleted file mode 100644 index 6678ff4a7c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package tokens - -import ( - "testing" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func tokenPost(t *testing.T, options gophercloud.AuthOptions, requestJSON string) os.CreateResult { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleTokenPost(t, requestJSON) - - return Create(client.ServiceClient(), WrapOptions(options)) -} - -func TestCreateTokenWithAPIKey(t *testing.T) { - options := gophercloud.AuthOptions{ - Username: "me", - APIKey: "1234567890abcdef", - } - - os.IsSuccessful(t, tokenPost(t, options, ` - { - "auth": { - "RAX-KSKEY:apiKeyCredentials": { - "username": "me", - "apiKey": "1234567890abcdef" - } - } - } - `)) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/delegate.go deleted file mode 100644 index ae2acde643..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/delegate.go +++ /dev/null @@ -1,145 +0,0 @@ -package users - -import ( - "errors" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/identity/v2/users" - "github.com/rackspace/gophercloud/pagination" -) - -// List returns a pager that allows traversal over a collection of users. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return os.List(client) -} - -// CommonOpts are the options which are shared between CreateOpts and -// UpdateOpts -type CommonOpts struct { - // Required. The username to assign to the user. When provided, the username - // must: - // - start with an alphabetical (A-Za-z) character - // - have a minimum length of 1 character - // - // The username may contain upper and lowercase characters, as well as any of - // the following special character: . - @ _ - Username string - - // Required. Email address for the user account. - Email string - - // Required. Indicates whether the user can authenticate after the user - // account is created. If no value is specified, the default value is true. - Enabled os.EnabledState - - // Optional. The password to assign to the user. If provided, the password - // must: - // - start with an alphabetical (A-Za-z) character - // - have a minimum length of 8 characters - // - contain at least one uppercase character, one lowercase character, and - // one numeric character. - // - // The password may contain any of the following special characters: . - @ _ - Password string -} - -// CreateOpts represents the options needed when creating new users. -type CreateOpts CommonOpts - -// ToUserCreateMap assembles a request body based on the contents of a CreateOpts. -func (opts CreateOpts) ToUserCreateMap() (map[string]interface{}, error) { - m := make(map[string]interface{}) - - if opts.Username == "" { - return m, errors.New("Username is a required field") - } - if opts.Enabled == nil { - return m, errors.New("Enabled is a required field") - } - if opts.Email == "" { - return m, errors.New("Email is a required field") - } - - if opts.Username != "" { - m["username"] = opts.Username - } - if opts.Email != "" { - m["email"] = opts.Email - } - if opts.Enabled != nil { - m["enabled"] = opts.Enabled - } - if opts.Password != "" { - m["OS-KSADM:password"] = opts.Password - } - - return map[string]interface{}{"user": m}, nil -} - -// Create is the operation responsible for creating new users. -func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) CreateResult { - return CreateResult{os.Create(client, opts)} -} - -// Get requests details on a single user, either by ID. -func Get(client *gophercloud.ServiceClient, id string) GetResult { - return GetResult{os.Get(client, id)} -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the Update request. -type UpdateOptsBuilder interface { - ToUserUpdateMap() map[string]interface{} -} - -// UpdateOpts specifies the base attributes that may be updated on an existing server. -type UpdateOpts CommonOpts - -// ToUserUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToUserUpdateMap() map[string]interface{} { - m := make(map[string]interface{}) - - if opts.Username != "" { - m["username"] = opts.Username - } - if opts.Enabled != nil { - m["enabled"] = &opts.Enabled - } - if opts.Email != "" { - m["email"] = opts.Email - } - - return map[string]interface{}{"user": m} -} - -// Update is the operation responsible for updating exist users by their UUID. -func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { - var result UpdateResult - - _, result.Err = perigee.Request("POST", os.ResourceURL(client, id), perigee.Options{ - Results: &result.Body, - ReqBody: opts.ToUserUpdateMap(), - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} - -// Delete is the operation responsible for permanently deleting an API user. -func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult { - return os.Delete(client, id) -} - -// ResetAPIKey resets the User's API key. -func ResetAPIKey(client *gophercloud.ServiceClient, id string) ResetAPIKeyResult { - var result ResetAPIKeyResult - - _, result.Err = perigee.Request("POST", resetAPIKeyURL(client, id), perigee.Options{ - Results: &result.Body, - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return result -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/delegate_test.go deleted file mode 100644 index 62faf0c5be..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/delegate_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package users - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/identity/v2/users" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListResponse(t) - - count := 0 - - err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - users, err := os.ExtractUsers(page) - - th.AssertNoErr(t, err) - th.AssertEquals(t, "u1000", users[0].ID) - th.AssertEquals(t, "u1001", users[1].ID) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateUser(t) - - opts := CreateOpts{ - Username: "new_user", - Enabled: os.Disabled, - Email: "new_user@foo.com", - Password: "foo", - } - - user, err := Create(client.ServiceClient(), opts).Extract() - - th.AssertNoErr(t, err) - - th.AssertEquals(t, "123456", user.ID) - th.AssertEquals(t, "5830280", user.DomainID) - th.AssertEquals(t, "DFW", user.DefaultRegion) -} - -func TestGetUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetUser(t) - - user, err := Get(client.ServiceClient(), "new_user").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, true, user.Enabled) - th.AssertEquals(t, true, user.MultiFactorEnabled) -} - -func TestUpdateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateUser(t) - - id := "c39e3de9be2d4c779f1dfd6abacc176d" - - opts := UpdateOpts{ - Enabled: os.Enabled, - Email: "new_email@foo.com", - } - - user, err := Update(client.ServiceClient(), id, opts).Extract() - - th.AssertNoErr(t, err) - - th.AssertEquals(t, true, user.Enabled) - th.AssertEquals(t, "new_email@foo.com", user.Email) -} - -func TestDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteUser(t) - - res := Delete(client.ServiceClient(), "c39e3de9be2d4c779f1dfd6abacc176d") - th.AssertNoErr(t, res.Err) -} - -func TestResetAPIKey(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockResetAPIKey(t) - - apiKey, err := ResetAPIKey(client.ServiceClient(), "99").Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, "joesmith", apiKey.Username) - th.AssertEquals(t, "mooH1eiLahd5ahYood7r", apiKey.APIKey) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/fixtures.go deleted file mode 100644 index 973f39ea8c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/fixtures.go +++ /dev/null @@ -1,154 +0,0 @@ -package users - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func mockListResponse(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "users":[ - { - "id": "u1000", - "username": "jqsmith", - "email": "john.smith@example.org", - "enabled": true - }, - { - "id": "u1001", - "username": "jqsmith", - "email": "jane.smith@example.org", - "enabled": true - } - ] -} - `) - }) -} - -func mockCreateUser(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "user": { - "username": "new_user", - "enabled": false, - "email": "new_user@foo.com", - "OS-KSADM:password": "foo" - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "user": { - "RAX-AUTH:defaultRegion": "DFW", - "RAX-AUTH:domainId": "5830280", - "id": "123456", - "username": "new_user", - "email": "new_user@foo.com", - "enabled": false - } -} -`) - }) -} - -func mockGetUser(t *testing.T) { - th.Mux.HandleFunc("/users/new_user", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "user": { - "RAX-AUTH:defaultRegion": "DFW", - "RAX-AUTH:domainId": "5830280", - "RAX-AUTH:multiFactorEnabled": "true", - "id": "c39e3de9be2d4c779f1dfd6abacc176d", - "username": "jqsmith", - "email": "john.smith@example.org", - "enabled": true - } -} -`) - }) -} - -func mockUpdateUser(t *testing.T) { - th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "user": { - "email": "new_email@foo.com", - "enabled": true - } -} -`) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "user": { - "RAX-AUTH:defaultRegion": "DFW", - "RAX-AUTH:domainId": "5830280", - "RAX-AUTH:multiFactorEnabled": "true", - "id": "123456", - "username": "jqsmith", - "email": "new_email@foo.com", - "enabled": true - } -} -`) - }) -} - -func mockDeleteUser(t *testing.T) { - th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) -} - -func mockResetAPIKey(t *testing.T) { - th.Mux.HandleFunc("/users/99/OS-KSADM/credentials/RAX-KSKEY:apiKeyCredentials/RAX-AUTH/reset", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` -{ - "RAX-KSKEY:apiKeyCredentials": { - "username": "joesmith", - "apiKey": "mooH1eiLahd5ahYood7r" - } -}`) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/results.go deleted file mode 100644 index 6936ecba84..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/results.go +++ /dev/null @@ -1,129 +0,0 @@ -package users - -import ( - "strconv" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/identity/v2/users" - - "github.com/mitchellh/mapstructure" -) - -// User represents a user resource that exists on the API. -type User struct { - // The UUID for this user. - ID string - - // The human name for this user. - Name string - - // The username for this user. - Username string - - // Indicates whether the user is enabled (true) or disabled (false). - Enabled bool - - // The email address for this user. - Email string - - // The ID of the tenant to which this user belongs. - TenantID string `mapstructure:"tenant_id"` - - // Specifies the default region for the user account. This value is inherited - // from the user administrator when the account is created. - DefaultRegion string `mapstructure:"RAX-AUTH:defaultRegion"` - - // Identifies the domain that contains the user account. This value is - // inherited from the user administrator when the account is created. - DomainID string `mapstructure:"RAX-AUTH:domainId"` - - // The password value that the user needs for authentication. If the Add user - // request included a password value, this attribute is not included in the - // response. - Password string `mapstructure:"OS-KSADM:password"` - - // Indicates whether the user has enabled multi-factor authentication. - MultiFactorEnabled bool `mapstructure:"RAX-AUTH:multiFactorEnabled"` -} - -// CreateResult represents the result of a Create operation -type CreateResult struct { - os.CreateResult -} - -// GetResult represents the result of a Get operation -type GetResult struct { - os.GetResult -} - -// UpdateResult represents the result of an Update operation -type UpdateResult struct { - os.UpdateResult -} - -func commonExtract(resp interface{}, err error) (*User, error) { - if err != nil { - return nil, err - } - - var respStruct struct { - User *User `json:"user"` - } - - // Since the API returns a string instead of a bool, we need to hack the JSON - json := resp.(map[string]interface{}) - user := json["user"].(map[string]interface{}) - if s, ok := user["RAX-AUTH:multiFactorEnabled"].(string); ok && s != "" { - if b, err := strconv.ParseBool(s); err == nil { - user["RAX-AUTH:multiFactorEnabled"] = b - } - } - - err = mapstructure.Decode(json, &respStruct) - - return respStruct.User, err -} - -// Extract will get the Snapshot object out of the GetResult object. -func (r GetResult) Extract() (*User, error) { - return commonExtract(r.Body, r.Err) -} - -// Extract will get the Snapshot object out of the CreateResult object. -func (r CreateResult) Extract() (*User, error) { - return commonExtract(r.Body, r.Err) -} - -// Extract will get the Snapshot object out of the UpdateResult object. -func (r UpdateResult) Extract() (*User, error) { - return commonExtract(r.Body, r.Err) -} - -// ResetAPIKeyResult represents the server response to the ResetAPIKey method. -type ResetAPIKeyResult struct { - gophercloud.Result -} - -// ResetAPIKeyValue represents an API Key that has been reset. -type ResetAPIKeyValue struct { - // The Username for this API Key reset. - Username string `mapstructure:"username"` - - // The new API Key for this user. - APIKey string `mapstructure:"apiKey"` -} - -// Extract will get the Error or ResetAPIKeyValue object out of the ResetAPIKeyResult object. -func (r ResetAPIKeyResult) Extract() (*ResetAPIKeyValue, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - ResetAPIKeyValue ResetAPIKeyValue `mapstructure:"RAX-KSKEY:apiKeyCredentials"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.ResetAPIKeyValue, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/urls.go deleted file mode 100644 index bc1aaefb02..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/users/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package users - -import "github.com/rackspace/gophercloud" - -func resetAPIKeyURL(client *gophercloud.ServiceClient, id string) string { - return client.ServiceURL("users", id, "OS-KSADM", "credentials", "RAX-KSKEY:apiKeyCredentials", "RAX-AUTH", "reset") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/doc.go deleted file mode 100644 index 42325fe83d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -/* -Package acl provides information and interaction with the access lists feature -of the Rackspace Cloud Load Balancer service. - -The access list management feature allows fine-grained network access controls -to be applied to the load balancer's virtual IP address. A single IP address, -multiple IP addresses, or entire network subnets can be added. Items that are -configured with the ALLOW type always takes precedence over items with the DENY -type. To reject traffic from all items except for those with the ALLOW type, -add a networkItem with an address of "0.0.0.0/0" and a DENY type. -*/ -package acl diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/fixtures.go deleted file mode 100644 index e3c941c81b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/fixtures.go +++ /dev/null @@ -1,109 +0,0 @@ -package acl - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(lbID int) string { - return "/loadbalancers/" + strconv.Itoa(lbID) + "/accesslist" -} - -func mockListResponse(t *testing.T, id int) { - th.Mux.HandleFunc(_rootURL(id), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "accessList": [ - { - "address": "206.160.163.21", - "id": 21, - "type": "DENY" - }, - { - "address": "206.160.163.22", - "id": 22, - "type": "DENY" - }, - { - "address": "206.160.163.23", - "id": 23, - "type": "DENY" - }, - { - "address": "206.160.163.24", - "id": 24, - "type": "DENY" - } - ] -} - `) - }) -} - -func mockCreateResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "accessList": [ - { - "address": "206.160.163.21", - "type": "DENY" - }, - { - "address": "206.160.165.11", - "type": "DENY" - } - ] -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteAllResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockBatchDeleteResponse(t *testing.T, lbID int, ids []int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - r.ParseForm() - - for k, v := range ids { - fids := r.Form["id"] - th.AssertEquals(t, strconv.Itoa(v), fids[k]) - } - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteResponse(t *testing.T, lbID, networkID int) { - th.Mux.HandleFunc(_rootURL(lbID)+"/"+strconv.Itoa(networkID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/requests.go deleted file mode 100644 index e1e92ac631..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/requests.go +++ /dev/null @@ -1,127 +0,0 @@ -package acl - -import ( - "errors" - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// List is the operation responsible for returning a paginated collection of -// network items that define a load balancer's access list. -func List(client *gophercloud.ServiceClient, lbID int) pagination.Pager { - url := rootURL(client, lbID) - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return AccessListPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder is the interface responsible for generating the JSON -// for a Create operation. -type CreateOptsBuilder interface { - ToAccessListCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is a slice of CreateOpt structs, that allow the user to create -// multiple nodes in a single operation (one node per CreateOpt). -type CreateOpts []CreateOpt - -// CreateOpt represents the options to create a single node. -type CreateOpt struct { - // Required - the IP address or CIDR for item to add to access list. - Address string - - // Required - the type of the node. Either ALLOW or DENY. - Type Type -} - -// ToAccessListCreateMap converts a slice of options into a map that can be -// used for the JSON. -func (opts CreateOpts) ToAccessListCreateMap() (map[string]interface{}, error) { - type itemMap map[string]interface{} - items := []itemMap{} - - for k, v := range opts { - if v.Address == "" { - return itemMap{}, fmt.Errorf("Address is a required attribute, none provided for %d CreateOpt element", k) - } - if v.Type != ALLOW && v.Type != DENY { - return itemMap{}, fmt.Errorf("Type must be ALLOW or DENY") - } - - item := make(itemMap) - item["address"] = v.Address - item["type"] = v.Type - - items = append(items, item) - } - - return itemMap{"accessList": items}, nil -} - -// Create is the operation responsible for adding network items to the access -// rules for a particular load balancer. If network items already exist, the -// new item will be appended. A single IP address or subnet range is considered -// unique and cannot be duplicated. -func Create(client *gophercloud.ServiceClient, loadBalancerID int, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToAccessListCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", rootURL(client, loadBalancerID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// BulkDelete will delete multiple network items from a load balancer's access -// list in a single operation. -func BulkDelete(c *gophercloud.ServiceClient, loadBalancerID int, itemIDs []int) DeleteResult { - var res DeleteResult - - if len(itemIDs) > 10 || len(itemIDs) == 0 { - res.Err = errors.New("You must provide a minimum of 1 and a maximum of 10 item IDs") - return res - } - - url := rootURL(c, loadBalancerID) - url += gophercloud.IDSliceToQueryString("id", itemIDs) - - _, res.Err = perigee.Request("DELETE", url, perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// Delete will remove a single network item from a load balancer's access list. -func Delete(c *gophercloud.ServiceClient, lbID, itemID int) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, lbID, itemID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} - -// DeleteAll will delete the entire contents of a load balancer's access list, -// effectively resetting it and allowing all traffic. -func DeleteAll(c *gophercloud.ServiceClient, lbID int) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/requests_test.go deleted file mode 100644 index c4961a3dd8..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/requests_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package acl - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ( - lbID = 12345 - itemID1 = 67890 - itemID2 = 67891 -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListResponse(t, lbID) - - count := 0 - - err := List(client.ServiceClient(), lbID).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractAccessList(page) - th.AssertNoErr(t, err) - - expected := AccessList{ - NetworkItem{Address: "206.160.163.21", ID: 21, Type: DENY}, - NetworkItem{Address: "206.160.163.22", ID: 22, Type: DENY}, - NetworkItem{Address: "206.160.163.23", ID: 23, Type: DENY}, - NetworkItem{Address: "206.160.163.24", ID: 24, Type: DENY}, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateResponse(t, lbID) - - opts := CreateOpts{ - CreateOpt{Address: "206.160.163.21", Type: DENY}, - CreateOpt{Address: "206.160.165.11", Type: DENY}, - } - - err := Create(client.ServiceClient(), lbID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - ids := []int{itemID1, itemID2} - - mockBatchDeleteResponse(t, lbID, ids) - - err := BulkDelete(client.ServiceClient(), lbID, ids).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteResponse(t, lbID, itemID1) - - err := Delete(client.ServiceClient(), lbID, itemID1).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDeleteAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteAllResponse(t, lbID) - - err := DeleteAll(client.ServiceClient(), lbID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/results.go deleted file mode 100644 index 9ea5ea2f4b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/results.go +++ /dev/null @@ -1,72 +0,0 @@ -package acl - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// AccessList represents the rules of network access to a particular load -// balancer. -type AccessList []NetworkItem - -// NetworkItem describes how an IP address or entire subnet may interact with a -// load balancer. -type NetworkItem struct { - // The IP address or subnet (CIDR) that defines the network item. - Address string - - // The numeric unique ID for this item. - ID int - - // Either ALLOW or DENY. - Type Type -} - -// Type defines how an item may connect to the load balancer. -type Type string - -// Convenience consts. -const ( - ALLOW Type = "ALLOW" - DENY Type = "DENY" -) - -// AccessListPage is the page returned by a pager for traversing over a -// collection of network items in an access list. -type AccessListPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether an AccessListPage struct is empty. -func (p AccessListPage) IsEmpty() (bool, error) { - is, err := ExtractAccessList(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractAccessList accepts a Page struct, specifically an AccessListPage -// struct, and extracts the elements into a slice of NetworkItem structs. In -// other words, a generic collection is mapped into a relevant slice. -func ExtractAccessList(page pagination.Page) (AccessList, error) { - var resp struct { - List AccessList `mapstructure:"accessList" json:"accessList"` - } - - err := mapstructure.Decode(page.(AccessListPage).Body, &resp) - - return resp.List, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - gophercloud.ErrResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/urls.go deleted file mode 100644 index e373fa1d80..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/acl/urls.go +++ /dev/null @@ -1,20 +0,0 @@ -package acl - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - path = "loadbalancers" - aclPath = "accesslist" -) - -func resourceURL(c *gophercloud.ServiceClient, lbID, networkID int) string { - return c.ServiceURL(path, strconv.Itoa(lbID), aclPath, strconv.Itoa(networkID)) -} - -func rootURL(c *gophercloud.ServiceClient, lbID int) string { - return c.ServiceURL(path, strconv.Itoa(lbID), aclPath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/doc.go deleted file mode 100644 index 05f0032859..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/doc.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Package lbs provides information and interaction with the Load Balancer API -resource for the Rackspace Cloud Load Balancer service. - -A load balancer is a logical device which belongs to a cloud account. It is -used to distribute workloads between multiple back-end systems or services, -based on the criteria defined as part of its configuration. This configuration -is defined using the Create operation, and can be updated with Update. - -To conserve IPv4 address space, it is highly recommended that you share Virtual -IPs between load balancers. If you have at least one load balancer, you may -create subsequent ones that share a single virtual IPv4 and/or a single IPv6 by -passing in a virtual IP ID to the Update operation (instead of a type). This -feature is also highly desirable if you wish to load balance both an insecure -and secure protocol using one IP or DNS name. In order to share a virtual IP, -each Load Balancer must utilize a unique port. - -All load balancers have a Status attribute that shows the current configuration -status of the device. This status is immutable by the caller and is updated -automatically based on state changes within the service. When a load balancer -is first created, it is placed into a BUILD state while the configuration is -being generated and applied based on the request. Once the configuration is -applied and finalized, it is in an ACTIVE status. In the event of a -configuration change or update, the status of the load balancer changes to -PENDING_UPDATE to signify configuration changes are in progress but have not yet -been finalized. Load balancers in a SUSPENDED status are configured to reject -traffic and do not forward requests to back-end nodes. - -An HTTP load balancer has the X-Forwarded-For (XFF) HTTP header set by default. -This header contains the originating IP address of a client connecting to a web -server through an HTTP proxy or load balancer, which many web applications are -already designed to use when determining the source address for a request. - -It also includes the X-Forwarded-Proto (XFP) HTTP header, which has been added -for identifying the originating protocol of an HTTP request as "http" or -"https" depending on which protocol the client requested. This is useful when -using SSL termination. - -Finally, it also includes the X-Forwarded-Port HTTP header, which has been -added for being able to generate secure URLs containing the specified port. -This header, along with the X-Forwarded-For header, provides the needed -information to the underlying application servers. -*/ -package lbs diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/fixtures.go deleted file mode 100644 index 6325310dbb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/fixtures.go +++ /dev/null @@ -1,584 +0,0 @@ -package lbs - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func mockListLBResponse(t *testing.T) { - th.Mux.HandleFunc("/loadbalancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "loadBalancers":[ - { - "name":"lb-site1", - "id":71, - "protocol":"HTTP", - "port":80, - "algorithm":"RANDOM", - "status":"ACTIVE", - "nodeCount":3, - "virtualIps":[ - { - "id":403, - "address":"206.55.130.1", - "type":"PUBLIC", - "ipVersion":"IPV4" - } - ], - "created":{ - "time":"2010-11-30T03:23:42Z" - }, - "updated":{ - "time":"2010-11-30T03:23:44Z" - } - }, - { - "name":"lb-site2", - "id":72, - "created":{ - "time":"2011-11-30T03:23:42Z" - }, - "updated":{ - "time":"2011-11-30T03:23:44Z" - } - }, - { - "name":"lb-site3", - "id":73, - "created":{ - "time":"2012-11-30T03:23:42Z" - }, - "updated":{ - "time":"2012-11-30T03:23:44Z" - } - } - ] -} - `) - }) -} - -func mockCreateLBResponse(t *testing.T) { - th.Mux.HandleFunc("/loadbalancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "loadBalancer": { - "name": "a-new-loadbalancer", - "port": 80, - "protocol": "HTTP", - "virtualIps": [ - { - "id": 2341 - }, - { - "id": 900001 - } - ], - "nodes": [ - { - "address": "10.1.1.1", - "port": 80, - "condition": "ENABLED" - } - ] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, ` -{ - "loadBalancer": { - "name": "a-new-loadbalancer", - "id": 144, - "protocol": "HTTP", - "halfClosed": false, - "port": 83, - "algorithm": "RANDOM", - "status": "BUILD", - "timeout": 30, - "cluster": { - "name": "ztm-n01.staging1.lbaas.rackspace.net" - }, - "nodes": [ - { - "address": "10.1.1.1", - "id": 653, - "port": 80, - "status": "ONLINE", - "condition": "ENABLED", - "weight": 1 - } - ], - "virtualIps": [ - { - "address": "206.10.10.210", - "id": 39, - "type": "PUBLIC", - "ipVersion": "IPV4" - }, - { - "address": "2001:4801:79f1:0002:711b:be4c:0000:0021", - "id": 900001, - "type": "PUBLIC", - "ipVersion": "IPV6" - } - ], - "created": { - "time": "2010-11-30T03:23:42Z" - }, - "updated": { - "time": "2010-11-30T03:23:44Z" - }, - "connectionLogging": { - "enabled": false - } - } -} - `) - }) -} - -func mockBatchDeleteLBResponse(t *testing.T, ids []int) { - th.Mux.HandleFunc("/loadbalancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - r.ParseForm() - - for k, v := range ids { - fids := r.Form["id"] - th.AssertEquals(t, strconv.Itoa(v), fids[k]) - } - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteLBResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockGetLBResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "loadBalancer": { - "id": 2000, - "name": "sample-loadbalancer", - "protocol": "HTTP", - "port": 80, - "algorithm": "RANDOM", - "status": "ACTIVE", - "timeout": 30, - "connectionLogging": { - "enabled": true - }, - "virtualIps": [ - { - "id": 1000, - "address": "206.10.10.210", - "type": "PUBLIC", - "ipVersion": "IPV4" - } - ], - "nodes": [ - { - "id": 1041, - "address": "10.1.1.1", - "port": 80, - "condition": "ENABLED", - "status": "ONLINE" - }, - { - "id": 1411, - "address": "10.1.1.2", - "port": 80, - "condition": "ENABLED", - "status": "ONLINE" - } - ], - "sessionPersistence": { - "persistenceType": "HTTP_COOKIE" - }, - "connectionThrottle": { - "maxConnections": 100 - }, - "cluster": { - "name": "c1.dfw1" - }, - "created": { - "time": "2010-11-30T03:23:42Z" - }, - "updated": { - "time": "2010-11-30T03:23:44Z" - }, - "sourceAddresses": { - "ipv6Public": "2001:4801:79f1:1::1/64", - "ipv4Servicenet": "10.0.0.0", - "ipv4Public": "10.12.99.28" - } - } -} - `) - }) -} - -func mockUpdateLBResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "loadBalancer": { - "name": "a-new-loadbalancer", - "protocol": "TCP", - "halfClosed": true, - "algorithm": "RANDOM", - "port": 8080, - "timeout": 100, - "httpsRedirect": false - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockListProtocolsResponse(t *testing.T) { - th.Mux.HandleFunc("/loadbalancers/protocols", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "protocols": [ - { - "name": "DNS_TCP", - "port": 53 - }, - { - "name": "DNS_UDP", - "port": 53 - }, - { - "name": "FTP", - "port": 21 - }, - { - "name": "HTTP", - "port": 80 - }, - { - "name": "HTTPS", - "port": 443 - }, - { - "name": "IMAPS", - "port": 993 - }, - { - "name": "IMAPv4", - "port": 143 - }, - { - "name": "LDAP", - "port": 389 - }, - { - "name": "LDAPS", - "port": 636 - }, - { - "name": "MYSQL", - "port": 3306 - }, - { - "name": "POP3", - "port": 110 - }, - { - "name": "POP3S", - "port": 995 - }, - { - "name": "SMTP", - "port": 25 - }, - { - "name": "TCP", - "port": 0 - }, - { - "name": "TCP_CLIENT_FIRST", - "port": 0 - }, - { - "name": "UDP", - "port": 0 - }, - { - "name": "UDP_STREAM", - "port": 0 - }, - { - "name": "SFTP", - "port": 22 - }, - { - "name": "TCP_STREAM", - "port": 0 - } - ] -} - `) - }) -} - -func mockListAlgorithmsResponse(t *testing.T) { - th.Mux.HandleFunc("/loadbalancers/algorithms", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "algorithms": [ - { - "name": "LEAST_CONNECTIONS" - }, - { - "name": "RANDOM" - }, - { - "name": "ROUND_ROBIN" - }, - { - "name": "WEIGHTED_LEAST_CONNECTIONS" - }, - { - "name": "WEIGHTED_ROUND_ROBIN" - } - ] -} - `) - }) -} - -func mockGetLoggingResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/connectionlogging", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "connectionLogging": { - "enabled": true - } -} - `) - }) -} - -func mockEnableLoggingResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/connectionlogging", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "connectionLogging":{ - "enabled":true - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDisableLoggingResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/connectionlogging", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "connectionLogging":{ - "enabled":false - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockGetErrorPageResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/errorpage", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "errorpage": { - "content": "DEFAULT ERROR PAGE" - } -} - `) - }) -} - -func mockSetErrorPageResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/errorpage", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "errorpage": { - "content": "New error page" - } -} - `) - - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "errorpage": { - "content": "New error page" - } -} - `) - }) -} - -func mockDeleteErrorPageResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/errorpage", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusOK) - }) -} - -func mockGetStatsResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/stats", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "connectTimeOut": 10, - "connectError": 20, - "connectFailure": 30, - "dataTimedOut": 40, - "keepAliveTimedOut": 50, - "maxConn": 60, - "currentConn": 40, - "connectTimeOutSsl": 10, - "connectErrorSsl": 20, - "connectFailureSsl": 30, - "dataTimedOutSsl": 40, - "keepAliveTimedOutSsl": 50, - "maxConnSsl": 60, - "currentConnSsl": 40 -} - `) - }) -} - -func mockGetCachingResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/contentcaching", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "contentCaching": { - "enabled": true - } -} - `) - }) -} - -func mockEnableCachingResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/contentcaching", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "contentCaching":{ - "enabled":true - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDisableCachingResponse(t *testing.T, id int) { - th.Mux.HandleFunc("/loadbalancers/"+strconv.Itoa(id)+"/contentcaching", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "contentCaching":{ - "enabled":false - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/requests.go deleted file mode 100644 index 342f10790e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/requests.go +++ /dev/null @@ -1,574 +0,0 @@ -package lbs - -import ( - "errors" - - "github.com/mitchellh/mapstructure" - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/lb/v1/acl" - "github.com/rackspace/gophercloud/rackspace/lb/v1/monitors" - "github.com/rackspace/gophercloud/rackspace/lb/v1/nodes" - "github.com/rackspace/gophercloud/rackspace/lb/v1/sessions" - "github.com/rackspace/gophercloud/rackspace/lb/v1/throttle" - "github.com/rackspace/gophercloud/rackspace/lb/v1/vips" -) - -var ( - errNameRequired = errors.New("Name is a required attribute") - errTimeoutExceeded = errors.New("Timeout must be less than 120") -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToLBListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. -type ListOpts struct { - ChangesSince string `q:"changes-since"` - Status Status `q:"status"` - NodeAddr string `q:"nodeaddress"` - Marker string `q:"marker"` - Limit int `q:"limit"` -} - -// ToLBListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToLBListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List is the operation responsible for returning a paginated collection of -// load balancers. You may pass in a ListOpts struct to filter results. -func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := rootURL(client) - if opts != nil { - query, err := opts.ToLBListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return LBPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type CreateOptsBuilder interface { - ToLBCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is the common options struct used in this package's Create -// operation. -type CreateOpts struct { - // Required - name of the load balancer to create. The name must be 128 - // characters or fewer in length, and all UTF-8 characters are valid. - Name string - - // Optional - nodes to be added. - Nodes []nodes.Node - - // Required - protocol of the service that is being load balanced. - // See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html - // for a full list of supported protocols. - Protocol string - - // Optional - enables or disables Half-Closed support for the load balancer. - // Half-Closed support provides the ability for one end of the connection to - // terminate its output, while still receiving data from the other end. Only - // available for TCP/TCP_CLIENT_FIRST protocols. - HalfClosed gophercloud.EnabledState - - // Optional - the type of virtual IPs you want associated with the load - // balancer. - VIPs []vips.VIP - - // Optional - the access list management feature allows fine-grained network - // access controls to be applied to the load balancer virtual IP address. - AccessList *acl.AccessList - - // Optional - algorithm that defines how traffic should be directed between - // back-end nodes. - Algorithm string - - // Optional - current connection logging configuration. - ConnectionLogging *ConnectionLogging - - // Optional - specifies a limit on the number of connections per IP address - // to help mitigate malicious or abusive traffic to your applications. - ConnThrottle *throttle.ConnectionThrottle - - // Optional - the type of health monitor check to perform to ensure that the - // service is performing properly. - HealthMonitor *monitors.Monitor - - // Optional - arbitrary information that can be associated with each LB. - Metadata map[string]interface{} - - // Optional - port number for the service you are load balancing. - Port int - - // Optional - the timeout value for the load balancer and communications with - // its nodes. Defaults to 30 seconds with a maximum of 120 seconds. - Timeout int - - // Optional - specifies whether multiple requests from clients are directed - // to the same node. - SessionPersistence *sessions.SessionPersistence - - // Optional - enables or disables HTTP to HTTPS redirection for the load - // balancer. When enabled, any HTTP request returns status code 301 (Moved - // Permanently), and the requester is redirected to the requested URL via the - // HTTPS protocol on port 443. For example, http://example.com/page.html - // would be redirected to https://example.com/page.html. Only available for - // HTTPS protocol (port=443), or HTTP protocol with a properly configured SSL - // termination (secureTrafficOnly=true, securePort=443). - HTTPSRedirect gophercloud.EnabledState -} - -// ToLBCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToLBCreateMap() (map[string]interface{}, error) { - lb := make(map[string]interface{}) - - if opts.Name == "" { - return lb, errNameRequired - } - if opts.Timeout > 120 { - return lb, errTimeoutExceeded - } - - lb["name"] = opts.Name - - if len(opts.Nodes) > 0 { - nodes := []map[string]interface{}{} - for _, n := range opts.Nodes { - nodes = append(nodes, map[string]interface{}{ - "address": n.Address, - "port": n.Port, - "condition": n.Condition, - }) - } - lb["nodes"] = nodes - } - - if opts.Protocol != "" { - lb["protocol"] = opts.Protocol - } - if opts.HalfClosed != nil { - lb["halfClosed"] = opts.HalfClosed - } - if len(opts.VIPs) > 0 { - lb["virtualIps"] = opts.VIPs - } - if opts.AccessList != nil { - lb["accessList"] = &opts.AccessList - } - if opts.Algorithm != "" { - lb["algorithm"] = opts.Algorithm - } - if opts.ConnectionLogging != nil { - lb["connectionLogging"] = &opts.ConnectionLogging - } - if opts.ConnThrottle != nil { - lb["connectionThrottle"] = &opts.ConnThrottle - } - if opts.HealthMonitor != nil { - lb["healthMonitor"] = &opts.HealthMonitor - } - if len(opts.Metadata) != 0 { - lb["metadata"] = opts.Metadata - } - if opts.Port > 0 { - lb["port"] = opts.Port - } - if opts.Timeout > 0 { - lb["timeout"] = opts.Timeout - } - if opts.SessionPersistence != nil { - lb["sessionPersistence"] = &opts.SessionPersistence - } - if opts.HTTPSRedirect != nil { - lb["httpsRedirect"] = &opts.HTTPSRedirect - } - - return map[string]interface{}{"loadBalancer": lb}, nil -} - -// Create is the operation responsible for asynchronously provisioning a new -// load balancer based on the configuration defined in CreateOpts. Once the -// request is validated and progress has started on the provisioning process, a -// response struct is returned. When extracted (with Extract()), you have -// to the load balancer's unique ID and status. -// -// Once an ID is attained, you can check on the progress of the operation by -// calling Get and passing in the ID. If the corresponding request cannot be -// fulfilled due to insufficient or invalid data, an HTTP 400 (Bad Request) -// error response is returned with information regarding the nature of the -// failure in the body of the response. Failures in the validation process are -// non-recoverable and require the caller to correct the cause of the failure. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToLBCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{202}, - }) - - return res -} - -// Get is the operation responsible for providing detailed information -// regarding a specific load balancer which is configured and associated with -// your account. This operation is not capable of returning details for a load -// balancer which has been deleted. -func Get(c *gophercloud.ServiceClient, id int) GetResult { - var res GetResult - - _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// BulkDelete removes all the load balancers referenced in the slice of IDs. -// Any and all configuration data associated with these load balancers is -// immediately purged and is not recoverable. -// -// If one of the items in the list cannot be removed due to its current status, -// a 400 Bad Request error is returned along with the IDs of the ones the -// system identified as potential failures for this request. -func BulkDelete(c *gophercloud.ServiceClient, ids []int) DeleteResult { - var res DeleteResult - - if len(ids) > 10 || len(ids) == 0 { - res.Err = errors.New("You must provide a minimum of 1 and a maximum of 10 LB IDs") - return res - } - - url := rootURL(c) - url += gophercloud.IDSliceToQueryString("id", ids) - - _, res.Err = perigee.Request("DELETE", url, perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// Delete removes a single load balancer. -func Delete(c *gophercloud.ServiceClient, id int) DeleteResult { - var res DeleteResult - - _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// UpdateOptsBuilder represents a type that can be converted into a JSON-like -// map structure. -type UpdateOptsBuilder interface { - ToLBUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents the options for updating an existing load balancer. -type UpdateOpts struct { - // Optional - new name of the load balancer. - Name string - - // Optional - the new protocol you want your load balancer to have. - // See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html - // for a full list of supported protocols. - Protocol string - - // Optional - see the HalfClosed field in CreateOpts for more information. - HalfClosed gophercloud.EnabledState - - // Optional - see the Algorithm field in CreateOpts for more information. - Algorithm string - - // Optional - see the Port field in CreateOpts for more information. - Port int - - // Optional - see the Timeout field in CreateOpts for more information. - Timeout int - - // Optional - see the HTTPSRedirect field in CreateOpts for more information. - HTTPSRedirect gophercloud.EnabledState -} - -// ToLBUpdateMap casts an UpdateOpts struct to a map. -func (opts UpdateOpts) ToLBUpdateMap() (map[string]interface{}, error) { - lb := make(map[string]interface{}) - - if opts.Name != "" { - lb["name"] = opts.Name - } - if opts.Protocol != "" { - lb["protocol"] = opts.Protocol - } - if opts.HalfClosed != nil { - lb["halfClosed"] = opts.HalfClosed - } - if opts.Algorithm != "" { - lb["algorithm"] = opts.Algorithm - } - if opts.Port > 0 { - lb["port"] = opts.Port - } - if opts.Timeout > 0 { - lb["timeout"] = opts.Timeout - } - if opts.HTTPSRedirect != nil { - lb["httpsRedirect"] = &opts.HTTPSRedirect - } - - return map[string]interface{}{"loadBalancer": lb}, nil -} - -// Update is the operation responsible for asynchronously updating the -// attributes of a specific load balancer. Upon successful validation of the -// request, the service returns a 202 Accepted response, and the load balancer -// enters a PENDING_UPDATE state. A user can poll the load balancer with Get to -// wait for the changes to be applied. When this happens, the load balancer will -// return to an ACTIVE state. -func Update(c *gophercloud.ServiceClient, id int, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToLBUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// ListProtocols is the operation responsible for returning a paginated -// collection of load balancer protocols. -func ListProtocols(client *gophercloud.ServiceClient) pagination.Pager { - url := protocolsURL(client) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ProtocolPage{pagination.SinglePageBase(r)} - }) -} - -// ListAlgorithms is the operation responsible for returning a paginated -// collection of load balancer algorithms. -func ListAlgorithms(client *gophercloud.ServiceClient) pagination.Pager { - url := algorithmsURL(client) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return AlgorithmPage{pagination.SinglePageBase(r)} - }) -} - -// IsLoggingEnabled returns true if the load balancer has connection logging -// enabled and false if not. -func IsLoggingEnabled(client *gophercloud.ServiceClient, id int) (bool, error) { - var body interface{} - - _, err := perigee.Request("GET", loggingURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &body, - OkCodes: []int{200}, - }) - if err != nil { - return false, err - } - - var resp struct { - CL struct { - Enabled bool `mapstructure:"enabled"` - } `mapstructure:"connectionLogging"` - } - - err = mapstructure.Decode(body, &resp) - return resp.CL.Enabled, err -} - -func toConnLoggingMap(state bool) map[string]map[string]bool { - return map[string]map[string]bool{ - "connectionLogging": map[string]bool{"enabled": state}, - } -} - -// EnableLogging will enable connection logging for a specified load balancer. -func EnableLogging(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult { - reqBody := toConnLoggingMap(true) - var res gophercloud.ErrResult - - _, res.Err = perigee.Request("PUT", loggingURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// DisableLogging will disable connection logging for a specified load balancer. -func DisableLogging(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult { - reqBody := toConnLoggingMap(false) - var res gophercloud.ErrResult - - _, res.Err = perigee.Request("PUT", loggingURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// GetErrorPage will retrieve the current error page for the load balancer. -func GetErrorPage(client *gophercloud.ServiceClient, id int) ErrorPageResult { - var res ErrorPageResult - - _, res.Err = perigee.Request("GET", errorPageURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// SetErrorPage will set the HTML of the load balancer's error page to a -// specific value. -func SetErrorPage(client *gophercloud.ServiceClient, id int, html string) ErrorPageResult { - var res ErrorPageResult - - type stringMap map[string]string - reqBody := map[string]stringMap{"errorpage": stringMap{"content": html}} - - _, res.Err = perigee.Request("PUT", errorPageURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &res.Body, - ReqBody: &reqBody, - OkCodes: []int{200}, - }) - - return res -} - -// DeleteErrorPage will delete the current error page for the load balancer. -func DeleteErrorPage(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult { - var res gophercloud.ErrResult - - _, res.Err = perigee.Request("DELETE", errorPageURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return res -} - -// GetStats will retrieve detailed stats related to the load balancer's usage. -func GetStats(client *gophercloud.ServiceClient, id int) StatsResult { - var res StatsResult - - _, res.Err = perigee.Request("GET", statsURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// IsContentCached will check to see whether the specified load balancer caches -// content. When content caching is enabled, recently-accessed files are stored -// on the load balancer for easy retrieval by web clients. Content caching -// improves the performance of high traffic web sites by temporarily storing -// data that was recently accessed. While it's cached, requests for that data -// are served by the load balancer, which in turn reduces load off the back-end -// nodes. The result is improved response times for those requests and less -// load on the web server. -func IsContentCached(client *gophercloud.ServiceClient, id int) (bool, error) { - var body interface{} - - _, err := perigee.Request("GET", cacheURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - Results: &body, - OkCodes: []int{200}, - }) - if err != nil { - return false, err - } - - var resp struct { - CC struct { - Enabled bool `mapstructure:"enabled"` - } `mapstructure:"contentCaching"` - } - - err = mapstructure.Decode(body, &resp) - return resp.CC.Enabled, err -} - -func toCachingMap(state bool) map[string]map[string]bool { - return map[string]map[string]bool{ - "contentCaching": map[string]bool{"enabled": state}, - } -} - -// EnableCaching will enable content-caching for the specified load balancer. -func EnableCaching(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult { - reqBody := toCachingMap(true) - var res gophercloud.ErrResult - - _, res.Err = perigee.Request("PUT", cacheURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// DisableCaching will disable content-caching for the specified load balancer. -func DisableCaching(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult { - reqBody := toCachingMap(false) - var res gophercloud.ErrResult - - _, res.Err = perigee.Request("PUT", cacheURL(client, id), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/requests_test.go deleted file mode 100644 index a8ec19e07c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/requests_test.go +++ /dev/null @@ -1,438 +0,0 @@ -package lbs - -import ( - "testing" - "time" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/lb/v1/nodes" - "github.com/rackspace/gophercloud/rackspace/lb/v1/sessions" - "github.com/rackspace/gophercloud/rackspace/lb/v1/throttle" - "github.com/rackspace/gophercloud/rackspace/lb/v1/vips" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ( - id1 = 12345 - id2 = 67890 - ts1 = "2010-11-30T03:23:42Z" - ts2 = "2010-11-30T03:23:44Z" -) - -func toTime(t *testing.T, str string) time.Time { - ts, err := time.Parse(time.RFC3339, str) - if err != nil { - t.Fatalf("Could not parse time: %s", err.Error()) - } - return ts -} - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListLBResponse(t) - - count := 0 - - err := List(client.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractLBs(page) - th.AssertNoErr(t, err) - - expected := []LoadBalancer{ - LoadBalancer{ - Name: "lb-site1", - ID: 71, - Protocol: "HTTP", - Port: 80, - Algorithm: "RANDOM", - Status: ACTIVE, - NodeCount: 3, - VIPs: []vips.VIP{ - vips.VIP{ - ID: 403, - Address: "206.55.130.1", - Type: "PUBLIC", - Version: "IPV4", - }, - }, - Created: Datetime{Time: toTime(t, ts1)}, - Updated: Datetime{Time: toTime(t, ts2)}, - }, - LoadBalancer{ - ID: 72, - Name: "lb-site2", - Created: Datetime{Time: toTime(t, "2011-11-30T03:23:42Z")}, - Updated: Datetime{Time: toTime(t, "2011-11-30T03:23:44Z")}, - }, - LoadBalancer{ - ID: 73, - Name: "lb-site3", - Created: Datetime{Time: toTime(t, "2012-11-30T03:23:42Z")}, - Updated: Datetime{Time: toTime(t, "2012-11-30T03:23:44Z")}, - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateLBResponse(t) - - opts := CreateOpts{ - Name: "a-new-loadbalancer", - Port: 80, - Protocol: "HTTP", - VIPs: []vips.VIP{ - vips.VIP{ID: 2341}, - vips.VIP{ID: 900001}, - }, - Nodes: []nodes.Node{ - nodes.Node{Address: "10.1.1.1", Port: 80, Condition: "ENABLED"}, - }, - } - - lb, err := Create(client.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - expected := &LoadBalancer{ - Name: "a-new-loadbalancer", - ID: 144, - Protocol: "HTTP", - HalfClosed: false, - Port: 83, - Algorithm: "RANDOM", - Status: BUILD, - Timeout: 30, - Cluster: Cluster{Name: "ztm-n01.staging1.lbaas.rackspace.net"}, - Nodes: []nodes.Node{ - nodes.Node{ - Address: "10.1.1.1", - ID: 653, - Port: 80, - Status: "ONLINE", - Condition: "ENABLED", - Weight: 1, - }, - }, - VIPs: []vips.VIP{ - vips.VIP{ - ID: 39, - Address: "206.10.10.210", - Type: vips.PUBLIC, - Version: vips.IPV4, - }, - vips.VIP{ - ID: 900001, - Address: "2001:4801:79f1:0002:711b:be4c:0000:0021", - Type: vips.PUBLIC, - Version: vips.IPV6, - }, - }, - Created: Datetime{Time: toTime(t, ts1)}, - Updated: Datetime{Time: toTime(t, ts2)}, - ConnectionLogging: ConnectionLogging{Enabled: false}, - } - - th.AssertDeepEquals(t, expected, lb) -} - -func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - ids := []int{id1, id2} - - mockBatchDeleteLBResponse(t, ids) - - err := BulkDelete(client.ServiceClient(), ids).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteLBResponse(t, id1) - - err := Delete(client.ServiceClient(), id1).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetLBResponse(t, id1) - - lb, err := Get(client.ServiceClient(), id1).Extract() - - expected := &LoadBalancer{ - Name: "sample-loadbalancer", - ID: 2000, - Protocol: "HTTP", - Port: 80, - Algorithm: "RANDOM", - Status: ACTIVE, - Timeout: 30, - ConnectionLogging: ConnectionLogging{Enabled: true}, - VIPs: []vips.VIP{ - vips.VIP{ - ID: 1000, - Address: "206.10.10.210", - Type: "PUBLIC", - Version: "IPV4", - }, - }, - Nodes: []nodes.Node{ - nodes.Node{ - Address: "10.1.1.1", - ID: 1041, - Port: 80, - Status: "ONLINE", - Condition: "ENABLED", - }, - nodes.Node{ - Address: "10.1.1.2", - ID: 1411, - Port: 80, - Status: "ONLINE", - Condition: "ENABLED", - }, - }, - SessionPersistence: sessions.SessionPersistence{Type: "HTTP_COOKIE"}, - ConnectionThrottle: throttle.ConnectionThrottle{MaxConnections: 100}, - Cluster: Cluster{Name: "c1.dfw1"}, - Created: Datetime{Time: toTime(t, ts1)}, - Updated: Datetime{Time: toTime(t, ts2)}, - SourceAddrs: SourceAddrs{ - IPv4Public: "10.12.99.28", - IPv4Private: "10.0.0.0", - IPv6Public: "2001:4801:79f1:1::1/64", - }, - } - - th.AssertDeepEquals(t, expected, lb) - th.AssertNoErr(t, err) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateLBResponse(t, id1) - - opts := UpdateOpts{ - Name: "a-new-loadbalancer", - Protocol: "TCP", - HalfClosed: gophercloud.Enabled, - Algorithm: "RANDOM", - Port: 8080, - Timeout: 100, - HTTPSRedirect: gophercloud.Disabled, - } - - err := Update(client.ServiceClient(), id1, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestListProtocols(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListProtocolsResponse(t) - - count := 0 - - err := ListProtocols(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractProtocols(page) - th.AssertNoErr(t, err) - - expected := []Protocol{ - Protocol{Name: "DNS_TCP", Port: 53}, - Protocol{Name: "DNS_UDP", Port: 53}, - Protocol{Name: "FTP", Port: 21}, - Protocol{Name: "HTTP", Port: 80}, - Protocol{Name: "HTTPS", Port: 443}, - Protocol{Name: "IMAPS", Port: 993}, - Protocol{Name: "IMAPv4", Port: 143}, - } - - th.CheckDeepEquals(t, expected[0:7], actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestListAlgorithms(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListAlgorithmsResponse(t) - - count := 0 - - err := ListAlgorithms(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractAlgorithms(page) - th.AssertNoErr(t, err) - - expected := []Algorithm{ - Algorithm{Name: "LEAST_CONNECTIONS"}, - Algorithm{Name: "RANDOM"}, - Algorithm{Name: "ROUND_ROBIN"}, - Algorithm{Name: "WEIGHTED_LEAST_CONNECTIONS"}, - Algorithm{Name: "WEIGHTED_ROUND_ROBIN"}, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestIsLoggingEnabled(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetLoggingResponse(t, id1) - - res, err := IsLoggingEnabled(client.ServiceClient(), id1) - th.AssertNoErr(t, err) - th.AssertEquals(t, true, res) -} - -func TestEnablingLogging(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockEnableLoggingResponse(t, id1) - - err := EnableLogging(client.ServiceClient(), id1).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDisablingLogging(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDisableLoggingResponse(t, id1) - - err := DisableLogging(client.ServiceClient(), id1).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGetErrorPage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetErrorPageResponse(t, id1) - - content, err := GetErrorPage(client.ServiceClient(), id1).Extract() - th.AssertNoErr(t, err) - - expected := &ErrorPage{Content: "DEFAULT ERROR PAGE"} - th.AssertDeepEquals(t, expected, content) -} - -func TestSetErrorPage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockSetErrorPageResponse(t, id1) - - html := "New error page" - content, err := SetErrorPage(client.ServiceClient(), id1, html).Extract() - th.AssertNoErr(t, err) - - expected := &ErrorPage{Content: html} - th.AssertDeepEquals(t, expected, content) -} - -func TestDeleteErrorPage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteErrorPageResponse(t, id1) - - err := DeleteErrorPage(client.ServiceClient(), id1).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGetStats(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetStatsResponse(t, id1) - - content, err := GetStats(client.ServiceClient(), id1).Extract() - th.AssertNoErr(t, err) - - expected := &Stats{ - ConnectTimeout: 10, - ConnectError: 20, - ConnectFailure: 30, - DataTimedOut: 40, - KeepAliveTimedOut: 50, - MaxConnections: 60, - CurrentConnections: 40, - SSLConnectTimeout: 10, - SSLConnectError: 20, - SSLConnectFailure: 30, - SSLDataTimedOut: 40, - SSLKeepAliveTimedOut: 50, - SSLMaxConnections: 60, - SSLCurrentConnections: 40, - } - th.AssertDeepEquals(t, expected, content) -} - -func TestIsCached(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetCachingResponse(t, id1) - - res, err := IsContentCached(client.ServiceClient(), id1) - th.AssertNoErr(t, err) - th.AssertEquals(t, true, res) -} - -func TestEnablingCaching(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockEnableCachingResponse(t, id1) - - err := EnableCaching(client.ServiceClient(), id1).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDisablingCaching(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDisableCachingResponse(t, id1) - - err := DisableCaching(client.ServiceClient(), id1).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/results.go deleted file mode 100644 index 98f3962d77..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/results.go +++ /dev/null @@ -1,420 +0,0 @@ -package lbs - -import ( - "reflect" - "time" - - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - "github.com/rackspace/gophercloud/rackspace/lb/v1/acl" - "github.com/rackspace/gophercloud/rackspace/lb/v1/nodes" - "github.com/rackspace/gophercloud/rackspace/lb/v1/sessions" - "github.com/rackspace/gophercloud/rackspace/lb/v1/throttle" - "github.com/rackspace/gophercloud/rackspace/lb/v1/vips" -) - -// Protocol represents the network protocol which the load balancer accepts. -type Protocol struct { - // The name of the protocol, e.g. HTTP, LDAP, FTP, etc. - Name string - - // The port number for the protocol. - Port int -} - -// Algorithm defines how traffic should be directed between back-end nodes. -type Algorithm struct { - // The name of the algorithm, e.g RANDOM, ROUND_ROBIN, etc. - Name string -} - -// Status represents the potential state of a load balancer resource. -type Status string - -const ( - // ACTIVE indicates that the LB is configured properly and ready to serve - // traffic to incoming requests via the configured virtual IPs. - ACTIVE Status = "ACTIVE" - - // BUILD indicates that the LB is being provisioned for the first time and - // configuration is being applied to bring the service online. The service - // cannot yet serve incoming requests. - BUILD Status = "BUILD" - - // PENDINGUPDATE indicates that the LB is online but configuration changes - // are being applied to update the service based on a previous request. - PENDINGUPDATE Status = "PENDING_UPDATE" - - // PENDINGDELETE indicates that the LB is online but configuration changes - // are being applied to begin deletion of the service based on a previous - // request. - PENDINGDELETE Status = "PENDING_DELETE" - - // SUSPENDED indicates that the LB has been taken offline and disabled. - SUSPENDED Status = "SUSPENDED" - - // ERROR indicates that the system encountered an error when attempting to - // configure the load balancer. - ERROR Status = "ERROR" - - // DELETED indicates that the LB has been deleted. - DELETED Status = "DELETED" -) - -// Datetime represents the structure of a Created or Updated field. -type Datetime struct { - Time time.Time `mapstructure:"-"` -} - -// LoadBalancer represents a load balancer API resource. -type LoadBalancer struct { - // Human-readable name for the load balancer. - Name string - - // The unique ID for the load balancer. - ID int - - // Represents the service protocol being load balanced. See Protocol type for - // a list of accepted values. - // See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html - // for a full list of supported protocols. - Protocol string - - // Defines how traffic should be directed between back-end nodes. The default - // algorithm is RANDOM. See Algorithm type for a list of accepted values. - Algorithm string - - // The current status of the load balancer. - Status Status - - // The number of load balancer nodes. - NodeCount int `mapstructure:"nodeCount"` - - // Slice of virtual IPs associated with this load balancer. - VIPs []vips.VIP `mapstructure:"virtualIps"` - - // Datetime when the LB was created. - Created Datetime - - // Datetime when the LB was created. - Updated Datetime - - // Port number for the service you are load balancing. - Port int - - // HalfClosed provides the ability for one end of the connection to - // terminate its output while still receiving data from the other end. This - // is only available on TCP/TCP_CLIENT_FIRST protocols. - HalfClosed bool - - // Timeout represents the timeout value between a load balancer and its - // nodes. Defaults to 30 seconds with a maximum of 120 seconds. - Timeout int - - // The cluster name. - Cluster Cluster - - // Nodes shows all the back-end nodes which are associated with the load - // balancer. These are the devices which are delivered traffic. - Nodes []nodes.Node - - // Current connection logging configuration. - ConnectionLogging ConnectionLogging - - // SessionPersistence specifies whether multiple requests from clients are - // directed to the same node. - SessionPersistence sessions.SessionPersistence - - // ConnectionThrottle specifies a limit on the number of connections per IP - // address to help mitigate malicious or abusive traffic to your applications. - ConnectionThrottle throttle.ConnectionThrottle - - // The source public and private IP addresses. - SourceAddrs SourceAddrs `mapstructure:"sourceAddresses"` - - // Represents the access rules for this particular load balancer. IP addresses - // or subnet ranges, depending on their type (ALLOW or DENY), can be permitted - // or blocked. - AccessList acl.AccessList -} - -// SourceAddrs represents the source public and private IP addresses. -type SourceAddrs struct { - IPv4Public string `json:"ipv4Public" mapstructure:"ipv4Public"` - IPv4Private string `json:"ipv4Servicenet" mapstructure:"ipv4Servicenet"` - IPv6Public string `json:"ipv6Public" mapstructure:"ipv6Public"` - IPv6Private string `json:"ipv6Servicenet" mapstructure:"ipv6Servicenet"` -} - -// ConnectionLogging - temp -type ConnectionLogging struct { - Enabled bool -} - -// Cluster - temp -type Cluster struct { - Name string -} - -// LBPage is the page returned by a pager when traversing over a collection of -// LBs. -type LBPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a NetworkPage struct is empty. -func (p LBPage) IsEmpty() (bool, error) { - is, err := ExtractLBs(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractLBs accepts a Page struct, specifically a LBPage struct, and extracts -// the elements into a slice of LoadBalancer structs. In other words, a generic -// collection is mapped into a relevant slice. -func ExtractLBs(page pagination.Page) ([]LoadBalancer, error) { - var resp struct { - LBs []LoadBalancer `mapstructure:"loadBalancers" json:"loadBalancers"` - } - - coll := page.(LBPage).Body - err := mapstructure.Decode(coll, &resp) - - s := reflect.ValueOf(coll.(map[string]interface{})["loadBalancers"]) - - for i := 0; i < s.Len(); i++ { - val := (s.Index(i).Interface()).(map[string]interface{}) - - ts, err := extractTS(val, "created") - if err != nil { - return resp.LBs, err - } - resp.LBs[i].Created.Time = ts - - ts, err = extractTS(val, "updated") - if err != nil { - return resp.LBs, err - } - resp.LBs[i].Updated.Time = ts - } - - return resp.LBs, err -} - -func extractTS(body map[string]interface{}, key string) (time.Time, error) { - val := body[key].(map[string]interface{}) - return time.Parse(time.RFC3339, val["time"].(string)) -} - -type commonResult struct { - gophercloud.Result -} - -// Extract interprets any commonResult as a LB, if possible. -func (r commonResult) Extract() (*LoadBalancer, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - LB LoadBalancer `mapstructure:"loadBalancer"` - } - - err := mapstructure.Decode(r.Body, &response) - - json := r.Body.(map[string]interface{}) - lb := json["loadBalancer"].(map[string]interface{}) - - ts, err := extractTS(lb, "created") - if err != nil { - return nil, err - } - response.LB.Created.Time = ts - - ts, err = extractTS(lb, "updated") - if err != nil { - return nil, err - } - response.LB.Updated.Time = ts - - return &response.LB, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - gophercloud.ErrResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// ProtocolPage is the page returned by a pager when traversing over a -// collection of LB protocols. -type ProtocolPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether a ProtocolPage struct is empty. -func (p ProtocolPage) IsEmpty() (bool, error) { - is, err := ExtractProtocols(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractProtocols accepts a Page struct, specifically a ProtocolPage struct, -// and extracts the elements into a slice of Protocol structs. In other -// words, a generic collection is mapped into a relevant slice. -func ExtractProtocols(page pagination.Page) ([]Protocol, error) { - var resp struct { - Protocols []Protocol `mapstructure:"protocols" json:"protocols"` - } - err := mapstructure.Decode(page.(ProtocolPage).Body, &resp) - return resp.Protocols, err -} - -// AlgorithmPage is the page returned by a pager when traversing over a -// collection of LB algorithms. -type AlgorithmPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether an AlgorithmPage struct is empty. -func (p AlgorithmPage) IsEmpty() (bool, error) { - is, err := ExtractAlgorithms(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractAlgorithms accepts a Page struct, specifically an AlgorithmPage struct, -// and extracts the elements into a slice of Algorithm structs. In other -// words, a generic collection is mapped into a relevant slice. -func ExtractAlgorithms(page pagination.Page) ([]Algorithm, error) { - var resp struct { - Algorithms []Algorithm `mapstructure:"algorithms" json:"algorithms"` - } - err := mapstructure.Decode(page.(AlgorithmPage).Body, &resp) - return resp.Algorithms, err -} - -// ErrorPage represents the HTML file that is shown to an end user who is -// attempting to access a load balancer node that is offline/unavailable. -// -// During provisioning, every load balancer is configured with a default error -// page that gets displayed when traffic is requested for an offline node. -// -// You can add a single custom error page with an HTTP-based protocol to a load -// balancer. Page updates override existing content. If a custom error page is -// deleted, or the load balancer is changed to a non-HTTP protocol, the default -// error page is restored. -type ErrorPage struct { - Content string -} - -// ErrorPageResult represents the result of an error page operation - -// specifically getting or creating one. -type ErrorPageResult struct { - gophercloud.Result -} - -// Extract interprets any commonResult as an ErrorPage, if possible. -func (r ErrorPageResult) Extract() (*ErrorPage, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - ErrorPage ErrorPage `mapstructure:"errorpage"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.ErrorPage, err -} - -// Stats represents all the key information about a load balancer's usage. -type Stats struct { - // The number of connections closed by this load balancer because its - // ConnectTimeout interval was exceeded. - ConnectTimeout int `mapstructure:"connectTimeOut"` - - // The number of transaction or protocol errors for this load balancer. - ConnectError int - - // Number of connection failures for this load balancer. - ConnectFailure int - - // Number of connections closed by this load balancer because its Timeout - // interval was exceeded. - DataTimedOut int - - // Number of connections closed by this load balancer because the - // 'keepalive_timeout' interval was exceeded. - KeepAliveTimedOut int - - // The maximum number of simultaneous TCP connections this load balancer has - // processed at any one time. - MaxConnections int `mapstructure:"maxConn"` - - // Number of simultaneous connections active at the time of the request. - CurrentConnections int `mapstructure:"currentConn"` - - // Number of SSL connections closed by this load balancer because the - // ConnectTimeout interval was exceeded. - SSLConnectTimeout int `mapstructure:"connectTimeOutSsl"` - - // Number of SSL transaction or protocol erros in this load balancer. - SSLConnectError int `mapstructure:"connectErrorSsl"` - - // Number of SSL connection failures in this load balancer. - SSLConnectFailure int `mapstructure:"connectFailureSsl"` - - // Number of SSL connections closed by this load balancer because the - // Timeout interval was exceeded. - SSLDataTimedOut int `mapstructure:"dataTimedOutSsl"` - - // Number of SSL connections closed by this load balancer because the - // 'keepalive_timeout' interval was exceeded. - SSLKeepAliveTimedOut int `mapstructure:"keepAliveTimedOutSsl"` - - // Maximum number of simultaneous SSL connections this load balancer has - // processed at any one time. - SSLMaxConnections int `mapstructure:"maxConnSsl"` - - // Number of simultaneous SSL connections active at the time of the request. - SSLCurrentConnections int `mapstructure:"currentConnSsl"` -} - -// StatsResult represents the result of a Stats operation. -type StatsResult struct { - gophercloud.Result -} - -// Extract interprets any commonResult as a Stats struct, if possible. -func (r StatsResult) Extract() (*Stats, error) { - if r.Err != nil { - return nil, r.Err - } - res := &Stats{} - err := mapstructure.Decode(r.Body, res) - return res, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/urls.go deleted file mode 100644 index 471a86b0a7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/lbs/urls.go +++ /dev/null @@ -1,49 +0,0 @@ -package lbs - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - path = "loadbalancers" - protocolsPath = "protocols" - algorithmsPath = "algorithms" - logPath = "connectionlogging" - epPath = "errorpage" - stPath = "stats" - cachePath = "contentcaching" -) - -func resourceURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id)) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(path) -} - -func protocolsURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(path, protocolsPath) -} - -func algorithmsURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(path, algorithmsPath) -} - -func loggingURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), logPath) -} - -func errorPageURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), epPath) -} - -func statsURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), stPath) -} - -func cacheURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), cachePath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/doc.go deleted file mode 100644 index 2c5be75ae4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -Package monitors provides information and interaction with the Health Monitor -API resource for the Rackspace Cloud Load Balancer service. - -The load balancing service includes a health monitoring resource that -periodically checks your back-end nodes to ensure they are responding correctly. -If a node does not respond, it is removed from rotation until the health monitor -determines that the node is functional. In addition to being performed -periodically, a health check also executes against every new node that is -added, to ensure that the node is operating properly before allowing it to -service traffic. Only one health monitor is allowed to be enabled on a load -balancer at a time. - -As part of a good strategy for monitoring connections, secondary nodes should -also be created which provide failover for effectively routing traffic in case -the primary node fails. This is an additional feature that ensures that you -remain up in case your primary node fails. - -There are three types of health monitor: CONNECT, HTTP and HTTPS. -*/ -package monitors diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/fixtures.go deleted file mode 100644 index a565abced5..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/fixtures.go +++ /dev/null @@ -1,87 +0,0 @@ -package monitors - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(lbID int) string { - return "/loadbalancers/" + strconv.Itoa(lbID) + "/healthmonitor" -} - -func mockGetResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "healthMonitor": { - "type": "CONNECT", - "delay": 10, - "timeout": 10, - "attemptsBeforeDeactivation": 3 - } -} - `) - }) -} - -func mockUpdateConnectResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "healthMonitor": { - "type": "CONNECT", - "delay": 10, - "timeout": 10, - "attemptsBeforeDeactivation": 3 - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockUpdateHTTPResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "healthMonitor": { - "attemptsBeforeDeactivation": 3, - "bodyRegex": "{regex}", - "delay": 10, - "path": "/foo", - "statusRegex": "200", - "timeout": 10, - "type": "HTTPS" - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/requests.go deleted file mode 100644 index cfc35d2ef7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/requests.go +++ /dev/null @@ -1,178 +0,0 @@ -package monitors - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" -) - -var ( - errAttemptLimit = errors.New("AttemptLimit field must be an int greater than 1 and less than 10") - errDelay = errors.New("Delay field must be an int greater than 1 and less than 10") - errTimeout = errors.New("Timeout field must be an int greater than 1 and less than 10") -) - -// UpdateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Update operation in this package. -type UpdateOptsBuilder interface { - ToMonitorUpdateMap() (map[string]interface{}, error) -} - -// UpdateConnectMonitorOpts represents the options needed to update a CONNECT -// monitor. -type UpdateConnectMonitorOpts struct { - // Required - number of permissible monitor failures before removing a node - // from rotation. Must be a number between 1 and 10. - AttemptLimit int - - // Required - the minimum number of seconds to wait before executing the - // health monitor. Must be a number between 1 and 3600. - Delay int - - // Required - maximum number of seconds to wait for a connection to be - // established before timing out. Must be a number between 1 and 300. - Timeout int -} - -// ToMonitorUpdateMap produces a map for updating CONNECT monitors. -func (opts UpdateConnectMonitorOpts) ToMonitorUpdateMap() (map[string]interface{}, error) { - type m map[string]interface{} - - if !gophercloud.IntWithinRange(opts.AttemptLimit, 1, 10) { - return m{}, errAttemptLimit - } - if !gophercloud.IntWithinRange(opts.Delay, 1, 3600) { - return m{}, errDelay - } - if !gophercloud.IntWithinRange(opts.Timeout, 1, 300) { - return m{}, errTimeout - } - - return m{"healthMonitor": m{ - "attemptsBeforeDeactivation": opts.AttemptLimit, - "delay": opts.Delay, - "timeout": opts.Timeout, - "type": CONNECT, - }}, nil -} - -// UpdateHTTPMonitorOpts represents the options needed to update a HTTP monitor. -type UpdateHTTPMonitorOpts struct { - // Required - number of permissible monitor failures before removing a node - // from rotation. Must be a number between 1 and 10. - AttemptLimit int `mapstructure:"attemptsBeforeDeactivation"` - - // Required - the minimum number of seconds to wait before executing the - // health monitor. Must be a number between 1 and 3600. - Delay int - - // Required - maximum number of seconds to wait for a connection to be - // established before timing out. Must be a number between 1 and 300. - Timeout int - - // Required - a regular expression that will be used to evaluate the contents - // of the body of the response. - BodyRegex string - - // Required - the HTTP path that will be used in the sample request. - Path string - - // Required - a regular expression that will be used to evaluate the HTTP - // status code returned in the response. - StatusRegex string - - // Optional - the name of a host for which the health monitors will check. - HostHeader string - - // Required - either HTTP or HTTPS - Type Type -} - -// ToMonitorUpdateMap produces a map for updating HTTP(S) monitors. -func (opts UpdateHTTPMonitorOpts) ToMonitorUpdateMap() (map[string]interface{}, error) { - type m map[string]interface{} - - if !gophercloud.IntWithinRange(opts.AttemptLimit, 1, 10) { - return m{}, errAttemptLimit - } - if !gophercloud.IntWithinRange(opts.Delay, 1, 3600) { - return m{}, errDelay - } - if !gophercloud.IntWithinRange(opts.Timeout, 1, 300) { - return m{}, errTimeout - } - if opts.Type != HTTP && opts.Type != HTTPS { - return m{}, errors.New("Type must either by HTTP or HTTPS") - } - if opts.BodyRegex == "" { - return m{}, errors.New("BodyRegex is a required field") - } - if opts.Path == "" { - return m{}, errors.New("Path is a required field") - } - if opts.StatusRegex == "" { - return m{}, errors.New("StatusRegex is a required field") - } - - json := m{ - "attemptsBeforeDeactivation": opts.AttemptLimit, - "delay": opts.Delay, - "timeout": opts.Timeout, - "type": opts.Type, - "bodyRegex": opts.BodyRegex, - "path": opts.Path, - "statusRegex": opts.StatusRegex, - } - - if opts.HostHeader != "" { - json["hostHeader"] = opts.HostHeader - } - - return m{"healthMonitor": json}, nil -} - -// Update is the operation responsible for updating a health monitor. -func Update(c *gophercloud.ServiceClient, id int, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToMonitorUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", rootURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// Get is the operation responsible for showing details of a health monitor. -func Get(c *gophercloud.ServiceClient, id int) GetResult { - var res GetResult - - _, res.Err = perigee.Request("GET", rootURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Delete is the operation responsible for deleting a health monitor. -func Delete(c *gophercloud.ServiceClient, id int) DeleteResult { - var res DeleteResult - - _, res.Err = perigee.Request("DELETE", rootURL(c, id), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/requests_test.go deleted file mode 100644 index 76a60db7f4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/requests_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package monitors - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const lbID = 12345 - -func TestUpdateCONNECT(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateConnectResponse(t, lbID) - - opts := UpdateConnectMonitorOpts{ - AttemptLimit: 3, - Delay: 10, - Timeout: 10, - } - - err := Update(client.ServiceClient(), lbID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestUpdateHTTP(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateHTTPResponse(t, lbID) - - opts := UpdateHTTPMonitorOpts{ - AttemptLimit: 3, - Delay: 10, - Timeout: 10, - BodyRegex: "{regex}", - Path: "/foo", - StatusRegex: "200", - Type: HTTPS, - } - - err := Update(client.ServiceClient(), lbID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetResponse(t, lbID) - - m, err := Get(client.ServiceClient(), lbID).Extract() - th.AssertNoErr(t, err) - - expected := &Monitor{ - Type: CONNECT, - Delay: 10, - Timeout: 10, - AttemptLimit: 3, - } - - th.AssertDeepEquals(t, expected, m) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteResponse(t, lbID) - - err := Delete(client.ServiceClient(), lbID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/results.go deleted file mode 100644 index eec556f343..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/results.go +++ /dev/null @@ -1,90 +0,0 @@ -package monitors - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" -) - -// Type represents the type of Monitor. -type Type string - -// Useful constants. -const ( - CONNECT Type = "CONNECT" - HTTP Type = "HTTP" - HTTPS Type = "HTTPS" -) - -// Monitor represents a health monitor API resource. A monitor comes in three -// forms: CONNECT, HTTP or HTTPS. -// -// A CONNECT monitor establishes a basic connection to each node on its defined -// port to ensure that the service is listening properly. The connect monitor -// is the most basic type of health check and does no post-processing or -// protocol-specific health checks. -// -// HTTP and HTTPS health monitors are generally considered more intelligent and -// powerful than CONNECT. It is capable of processing an HTTP or HTTPS response -// to determine the condition of a node. It supports the same basic properties -// as CONNECT and includes additional attributes that are used to evaluate the -// HTTP response. -type Monitor struct { - // Number of permissible monitor failures before removing a node from - // rotation. - AttemptLimit int `mapstructure:"attemptsBeforeDeactivation"` - - // The minimum number of seconds to wait before executing the health monitor. - Delay int - - // Maximum number of seconds to wait for a connection to be established - // before timing out. - Timeout int - - // Type of the health monitor. - Type Type - - // A regular expression that will be used to evaluate the contents of the - // body of the response. - BodyRegex string - - // The name of a host for which the health monitors will check. - HostHeader string - - // The HTTP path that will be used in the sample request. - Path string - - // A regular expression that will be used to evaluate the HTTP status code - // returned in the response. - StatusRegex string -} - -// UpdateResult represents the result of an Update operation. -type UpdateResult struct { - gophercloud.ErrResult -} - -// GetResult represents the result of a Get operation. -type GetResult struct { - gophercloud.Result -} - -// DeleteResult represents the result of an Delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// Extract interprets any GetResult as a Monitor. -func (r GetResult) Extract() (*Monitor, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - M Monitor `mapstructure:"healthMonitor"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.M, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/urls.go deleted file mode 100644 index 0a1e6df5f4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/monitors/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package monitors - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - path = "loadbalancers" - monitorPath = "healthmonitor" -) - -func rootURL(c *gophercloud.ServiceClient, lbID int) string { - return c.ServiceURL(path, strconv.Itoa(lbID), monitorPath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/doc.go deleted file mode 100644 index 49c431894a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/doc.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Package nodes provides information and interaction with the Node API resource -for the Rackspace Cloud Load Balancer service. - -Nodes are responsible for servicing the requests received through the load -balancer's virtual IP. A node is usually a virtual machine. By default, the -load balancer employs a basic health check that ensures the node is listening -on its defined port. The node is checked at the time of addition and at regular -intervals as defined by the load balancer's health check configuration. If a -back-end node is not listening on its port, or does not meet the conditions of -the defined check, then connections will not be forwarded to the node, and its -status is changed to OFFLINE. Only nodes that are in an ONLINE status receive -and can service traffic from the load balancer. - -All nodes have an associated status that indicates whether the node is -ONLINE, OFFLINE, or DRAINING. Only nodes that are in ONLINE status can receive -and service traffic from the load balancer. The OFFLINE status represents a -node that cannot accept or service traffic. A node in DRAINING status -represents a node that stops the traffic manager from sending any additional -new connections to the node, but honors established sessions. If the traffic -manager receives a request and session persistence requires that the node is -used, the traffic manager uses it. The status is determined by the passive or -active health monitors. - -If the WEIGHTED_ROUND_ROBIN load balancer algorithm mode is selected, then the -caller should assign the relevant weights to the node as part of the weight -attribute of the node element. When the algorithm of the load balancer is -changed to WEIGHTED_ROUND_ROBIN and the nodes do not already have an assigned -weight, the service automatically sets the weight to 1 for all nodes. - -One or more secondary nodes can be added to a specified load balancer so that -if all the primary nodes fail, traffic can be redirected to secondary nodes. -The type attribute allows configuring the node as either PRIMARY or SECONDARY. -*/ -package nodes diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go deleted file mode 100644 index 0aea541036..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go +++ /dev/null @@ -1,208 +0,0 @@ -package nodes - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(lbID int) string { - return "/loadbalancers/" + strconv.Itoa(lbID) + "/nodes" -} - -func _nodeURL(lbID, nodeID int) string { - return _rootURL(lbID) + "/" + strconv.Itoa(nodeID) -} - -func mockListResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "nodes": [ - { - "id": 410, - "address": "10.1.1.1", - "port": 80, - "condition": "ENABLED", - "status": "ONLINE", - "weight": 3, - "type": "PRIMARY" - }, - { - "id": 411, - "address": "10.1.1.2", - "port": 80, - "condition": "ENABLED", - "status": "ONLINE", - "weight": 8, - "type": "SECONDARY" - } - ] -} - `) - }) -} - -func mockCreateResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "nodes": [ - { - "address": "10.2.2.3", - "port": 80, - "condition": "ENABLED", - "type": "PRIMARY" - }, - { - "address": "10.2.2.4", - "port": 81, - "condition": "ENABLED", - "type": "SECONDARY" - } - ] -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, ` -{ - "nodes": [ - { - "address": "10.2.2.3", - "id": 185, - "port": 80, - "status": "ONLINE", - "condition": "ENABLED", - "weight": 1, - "type": "PRIMARY" - }, - { - "address": "10.2.2.4", - "id": 186, - "port": 81, - "status": "ONLINE", - "condition": "ENABLED", - "weight": 1, - "type": "SECONDARY" - } - ] -} - `) - }) -} - -func mockBatchDeleteResponse(t *testing.T, lbID int, ids []int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - r.ParseForm() - - for k, v := range ids { - fids := r.Form["id"] - th.AssertEquals(t, strconv.Itoa(v), fids[k]) - } - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteResponse(t *testing.T, lbID, nodeID int) { - th.Mux.HandleFunc(_nodeURL(lbID, nodeID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockGetResponse(t *testing.T, lbID, nodeID int) { - th.Mux.HandleFunc(_nodeURL(lbID, nodeID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "node": { - "id": 410, - "address": "10.1.1.1", - "port": 80, - "condition": "ENABLED", - "status": "ONLINE", - "weight": 12, - "type": "PRIMARY" - } -} - `) - }) -} - -func mockUpdateResponse(t *testing.T, lbID, nodeID int) { - th.Mux.HandleFunc(_nodeURL(lbID, nodeID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "node": { - "address": "1.2.3.4", - "condition": "DRAINING", - "weight": 10, - "type": "SECONDARY" - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockListEventsResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID)+"/events", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "nodeServiceEvents": [ - { - "detailedMessage": "Node is ok", - "nodeId": 373, - "id": 7, - "type": "UPDATE_NODE", - "description": "Node '373' status changed to 'ONLINE' for load balancer '323'", - "category": "UPDATE", - "severity": "INFO", - "relativeUri": "/406271/loadbalancers/323/nodes/373/events", - "accountId": 406271, - "loadbalancerId": 323, - "title": "Node Status Updated", - "author": "Rackspace Cloud", - "created": "10-30-2012 10:18:23" - } - ] -} -`) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go deleted file mode 100644 index bfd0aed79f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go +++ /dev/null @@ -1,286 +0,0 @@ -package nodes - -import ( - "errors" - "fmt" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// List is the operation responsible for returning a paginated collection of -// load balancer nodes. It requires the node ID, its parent load balancer ID, -// and optional limit integer (passed in either as a pointer or a nil poitner). -func List(client *gophercloud.ServiceClient, loadBalancerID int, limit *int) pagination.Pager { - url := rootURL(client, loadBalancerID) - if limit != nil { - url += fmt.Sprintf("?limit=%d", limit) - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return NodePage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder is the interface responsible for generating the JSON -// for a Create operation. -type CreateOptsBuilder interface { - ToNodeCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is a slice of CreateOpt structs, that allow the user to create -// multiple nodes in a single operation (one node per CreateOpt). -type CreateOpts []CreateOpt - -// CreateOpt represents the options to create a single node. -type CreateOpt struct { - // Required - the IP address or CIDR for this back-end node. It can either be - // a private IP (ServiceNet) or a public IP. - Address string - - // Optional - the port on which traffic is sent and received. - Port int - - // Optional - the condition of the node. See the consts in Results.go. - Condition Condition - - // Optional - the type of the node. See the consts in Results.go. - Type Type - - // Optional - a pointer to an integer between 0 and 100. - Weight *int -} - -func validateWeight(weight *int) error { - if weight != nil && (*weight > 100 || *weight < 0) { - return errors.New("Weight must be a valid int between 0 and 100") - } - return nil -} - -// ToNodeCreateMap converts a slice of options into a map that can be used for -// the JSON. -func (opts CreateOpts) ToNodeCreateMap() (map[string]interface{}, error) { - type nodeMap map[string]interface{} - nodes := []nodeMap{} - - for k, v := range opts { - if v.Address == "" { - return nodeMap{}, fmt.Errorf("ID is a required attribute, none provided for %d CreateOpt element", k) - } - if weightErr := validateWeight(v.Weight); weightErr != nil { - return nodeMap{}, weightErr - } - - node := make(map[string]interface{}) - node["address"] = v.Address - - if v.Port > 0 { - node["port"] = v.Port - } - if v.Condition != "" { - node["condition"] = v.Condition - } - if v.Type != "" { - node["type"] = v.Type - } - if v.Weight != nil { - node["weight"] = &v.Weight - } - - nodes = append(nodes, node) - } - - return nodeMap{"nodes": nodes}, nil -} - -// Create is the operation responsible for creating a new node on a load -// balancer. Since every load balancer exists in both ServiceNet and the public -// Internet, both private and public IP addresses can be used for nodes. -// -// If nodes need time to boot up services before they become operational, you -// can temporarily prevent traffic from being sent to that node by setting the -// Condition field to DRAINING. Health checks will still be performed; but once -// your node is ready, you can update its condition to ENABLED and have it -// handle traffic. -func Create(client *gophercloud.ServiceClient, loadBalancerID int, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToNodeCreateMap() - if err != nil { - res.Err = err - return res - } - - resp, err := perigee.Request("POST", rootURL(client, loadBalancerID), perigee.Options{ - MoreHeaders: client.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{202}, - }) - if err != nil { - res.Err = err - return res - } - - pr, err := pagination.PageResultFrom(resp.HttpResponse) - if err != nil { - res.Err = err - return res - } - - return CreateResult{pagination.SinglePageBase(pr)} -} - -// BulkDelete is the operation responsible for batch deleting multiple nodes in -// a single operation. It accepts a slice of integer IDs and will remove them -// from the load balancer. The maximum limit is 10 node removals at once. -func BulkDelete(c *gophercloud.ServiceClient, loadBalancerID int, nodeIDs []int) DeleteResult { - var res DeleteResult - - if len(nodeIDs) > 10 || len(nodeIDs) == 0 { - res.Err = errors.New("You must provide a minimum of 1 and a maximum of 10 node IDs") - return res - } - - url := rootURL(c, loadBalancerID) - url += gophercloud.IDSliceToQueryString("id", nodeIDs) - - _, res.Err = perigee.Request("DELETE", url, perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// Get is the operation responsible for showing details for a single node. -func Get(c *gophercloud.ServiceClient, lbID, nodeID int) GetResult { - var res GetResult - - _, res.Err = perigee.Request("GET", resourceURL(c, lbID, nodeID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// UpdateOptsBuilder represents a type that can be converted into a JSON-like -// map structure. -type UpdateOptsBuilder interface { - ToNodeUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represent the options for updating an existing node. -type UpdateOpts struct { - // Optional - the IP address or CIDR for this back-end node. It can either be - // a private IP (ServiceNet) or a public IP. - Address string - - // Optional - the condition of the node. See the consts in Results.go. - Condition Condition - - // Optional - the type of the node. See the consts in Results.go. - Type Type - - // Optional - a pointer to an integer between 0 and 100. - Weight *int -} - -// ToNodeUpdateMap converts an options struct into a JSON-like map. -func (opts UpdateOpts) ToNodeUpdateMap() (map[string]interface{}, error) { - node := make(map[string]interface{}) - - if opts.Address != "" { - node["address"] = opts.Address - } - if opts.Condition != "" { - node["condition"] = opts.Condition - } - if opts.Weight != nil { - if weightErr := validateWeight(opts.Weight); weightErr != nil { - return node, weightErr - } - node["weight"] = &opts.Weight - } - if opts.Type != "" { - node["type"] = opts.Type - } - - return map[string]interface{}{"node": node}, nil -} - -// Update is the operation responsible for updating an existing node. A node's -// IP, port, and status are immutable attributes and cannot be modified. -func Update(c *gophercloud.ServiceClient, lbID, nodeID int, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToNodeUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", resourceURL(c, lbID, nodeID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - OkCodes: []int{202}, - }) - - return res -} - -// Delete is the operation responsible for permanently deleting a node. -func Delete(c *gophercloud.ServiceClient, lbID, nodeID int) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, lbID, nodeID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} - -// ListEventsOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListEventsOptsBuilder interface { - ToEventsListQuery() (string, error) -} - -// ListEventsOpts allows the filtering and sorting of paginated collections through -// the API. -type ListEventsOpts struct { - Marker string `q:"marker"` - Limit int `q:"limit"` -} - -// ToEventsListQuery formats a ListOpts into a query string. -func (opts ListEventsOpts) ToEventsListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// ListEvents is the operation responsible for listing all the events -// associated with the activity between the node and the load balancer. The -// events report errors found with the node. The detailedMessage provides the -// detailed reason for the error. -func ListEvents(client *gophercloud.ServiceClient, loadBalancerID int, opts ListEventsOptsBuilder) pagination.Pager { - url := eventsURL(client, loadBalancerID) - - if opts != nil { - query, err := opts.ToEventsListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return NodeEventPage{pagination.SinglePageBase(r)} - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go deleted file mode 100644 index f888a14586..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go +++ /dev/null @@ -1,212 +0,0 @@ -package nodes - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ( - lbID = 12345 - nodeID = 67890 - nodeID2 = 67891 -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListResponse(t, lbID) - - count := 0 - - err := List(client.ServiceClient(), lbID, nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNodes(page) - th.AssertNoErr(t, err) - - expected := []Node{ - Node{ - ID: 410, - Address: "10.1.1.1", - Port: 80, - Condition: ENABLED, - Status: ONLINE, - Weight: 3, - Type: PRIMARY, - }, - Node{ - ID: 411, - Address: "10.1.1.2", - Port: 80, - Condition: ENABLED, - Status: ONLINE, - Weight: 8, - Type: SECONDARY, - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateResponse(t, lbID) - - opts := CreateOpts{ - CreateOpt{ - Address: "10.2.2.3", - Port: 80, - Condition: ENABLED, - Type: PRIMARY, - }, - CreateOpt{ - Address: "10.2.2.4", - Port: 81, - Condition: ENABLED, - Type: SECONDARY, - }, - } - - page := Create(client.ServiceClient(), lbID, opts) - - actual, err := page.ExtractNodes() - th.AssertNoErr(t, err) - - expected := []Node{ - Node{ - ID: 185, - Address: "10.2.2.3", - Port: 80, - Condition: ENABLED, - Status: ONLINE, - Weight: 1, - Type: PRIMARY, - }, - Node{ - ID: 186, - Address: "10.2.2.4", - Port: 81, - Condition: ENABLED, - Status: ONLINE, - Weight: 1, - Type: SECONDARY, - }, - } - - th.CheckDeepEquals(t, expected, actual) -} - -func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - ids := []int{nodeID, nodeID2} - - mockBatchDeleteResponse(t, lbID, ids) - - err := BulkDelete(client.ServiceClient(), lbID, ids).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetResponse(t, lbID, nodeID) - - node, err := Get(client.ServiceClient(), lbID, nodeID).Extract() - th.AssertNoErr(t, err) - - expected := &Node{ - ID: 410, - Address: "10.1.1.1", - Port: 80, - Condition: ENABLED, - Status: ONLINE, - Weight: 12, - Type: PRIMARY, - } - - th.AssertDeepEquals(t, expected, node) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateResponse(t, lbID, nodeID) - - opts := UpdateOpts{ - Address: "1.2.3.4", - Weight: gophercloud.IntToPointer(10), - Condition: DRAINING, - Type: SECONDARY, - } - - err := Update(client.ServiceClient(), lbID, nodeID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteResponse(t, lbID, nodeID) - - err := Delete(client.ServiceClient(), lbID, nodeID).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestListEvents(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListEventsResponse(t, lbID) - - count := 0 - - pager := ListEvents(client.ServiceClient(), lbID, ListEventsOpts{}) - - err := pager.EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNodeEvents(page) - th.AssertNoErr(t, err) - - expected := []NodeEvent{ - NodeEvent{ - DetailedMessage: "Node is ok", - NodeID: 373, - ID: 7, - Type: "UPDATE_NODE", - Description: "Node '373' status changed to 'ONLINE' for load balancer '323'", - Category: "UPDATE", - Severity: "INFO", - RelativeURI: "/406271/loadbalancers/323/nodes/373/events", - AccountID: 406271, - LoadBalancerID: 323, - Title: "Node Status Updated", - Author: "Rackspace Cloud", - Created: "10-30-2012 10:18:23", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go deleted file mode 100644 index 916485f2fc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go +++ /dev/null @@ -1,210 +0,0 @@ -package nodes - -import ( - "github.com/mitchellh/mapstructure" - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// Node represents a back-end device, usually a virtual machine, that can -// handle traffic. It is assigned traffic based on its parent load balancer. -type Node struct { - // The IP address or CIDR for this back-end node. - Address string - - // The unique ID for this node. - ID int - - // The port on which traffic is sent and received. - Port int - - // The node's status. - Status Status - - // The node's condition. - Condition Condition - - // The priority at which this node will receive traffic if a weighted - // algorithm is used by its parent load balancer. Ranges from 1 to 100. - Weight int - - // Type of node. - Type Type -} - -// Type indicates whether the node is of a PRIMARY or SECONDARY nature. -type Type string - -const ( - // PRIMARY nodes are in the normal rotation to receive traffic from the load - // balancer. - PRIMARY Type = "PRIMARY" - - // SECONDARY nodes are only in the rotation to receive traffic from the load - // balancer when all the primary nodes fail. This provides a failover feature - // that automatically routes traffic to the secondary node in the event that - // the primary node is disabled or in a failing state. Note that active - // health monitoring must be enabled on the load balancer to enable the - // failover feature to the secondary node. - SECONDARY Type = "SECONDARY" -) - -// Condition represents the condition of a node. -type Condition string - -const ( - // ENABLED indicates that the node is permitted to accept new connections. - ENABLED Condition = "ENABLED" - - // DISABLED indicates that the node is not permitted to accept any new - // connections regardless of session persistence configuration. Existing - // connections are forcibly terminated. - DISABLED Condition = "DISABLED" - - // DRAINING indicates that the node is allowed to service existing - // established connections and connections that are being directed to it as a - // result of the session persistence configuration. - DRAINING Condition = "DRAINING" -) - -// Status indicates whether the node can accept service traffic. If a node is -// not listening on its port or does not meet the conditions of the defined -// active health check for the load balancer, then the load balancer does not -// forward connections, and its status is listed as OFFLINE. -type Status string - -const ( - // ONLINE indicates that the node is healthy and capable of receiving traffic - // from the load balancer. - ONLINE Status = "ONLINE" - - // OFFLINE indicates that the node is not in a position to receive service - // traffic. It is usually switched into this state when a health check is not - // satisfied with the node's response time. - OFFLINE Status = "OFFLINE" -) - -// NodePage is the page returned by a pager when traversing over a collection -// of nodes. -type NodePage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether a NodePage struct is empty. -func (p NodePage) IsEmpty() (bool, error) { - is, err := ExtractNodes(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -func commonExtractNodes(body interface{}) ([]Node, error) { - var resp struct { - Nodes []Node `mapstructure:"nodes" json:"nodes"` - } - - err := mapstructure.Decode(body, &resp) - - return resp.Nodes, err -} - -// ExtractNodes accepts a Page struct, specifically a NodePage struct, and -// extracts the elements into a slice of Node structs. In other words, a -// generic collection is mapped into a relevant slice. -func ExtractNodes(page pagination.Page) ([]Node, error) { - return commonExtractNodes(page.(NodePage).Body) -} - -// CreateResult represents the result of a create operation. Since multiple -// nodes can be added in one operation, this result represents multiple nodes -// and should be treated as a typical pagination Page. Use its ExtractNodes -// method to get out a slice of Node structs. -type CreateResult struct { - pagination.SinglePageBase -} - -// ExtractNodes extracts a slice of Node structs from a CreateResult. -func (res CreateResult) ExtractNodes() ([]Node, error) { - return commonExtractNodes(res.Body) -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -type commonResult struct { - gophercloud.Result -} - -// GetResult represents the result of a get operation. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - gophercloud.ErrResult -} - -func (r commonResult) Extract() (*Node, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Node Node `mapstructure:"node"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.Node, err -} - -// NodeEvent represents a service event that occurred between a node and a -// load balancer. -type NodeEvent struct { - ID int - DetailedMessage string - NodeID int - Type string - Description string - Category string - Severity string - RelativeURI string - AccountID int - LoadBalancerID int - Title string - Author string - Created string -} - -// NodeEventPage is a concrete type which embeds the common SinglePageBase -// struct, and is used when traversing node event collections. -type NodeEventPage struct { - pagination.SinglePageBase -} - -// IsEmpty is a concrete function which indicates whether an NodeEventPage is -// empty or not. -func (r NodeEventPage) IsEmpty() (bool, error) { - is, err := ExtractNodeEvents(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -// ExtractNodeEvents accepts a Page struct, specifically a NodeEventPage -// struct, and extracts the elements into a slice of NodeEvent structs. In -// other words, the collection is mapped into a relevant slice. -func ExtractNodeEvents(page pagination.Page) ([]NodeEvent, error) { - var resp struct { - Events []NodeEvent `mapstructure:"nodeServiceEvents" json:"nodeServiceEvents"` - } - - err := mapstructure.Decode(page.(NodeEventPage).Body, &resp) - - return resp.Events, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/urls.go deleted file mode 100644 index 2cefee2644..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package nodes - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - lbPath = "loadbalancers" - nodePath = "nodes" - eventPath = "events" -) - -func resourceURL(c *gophercloud.ServiceClient, lbID, nodeID int) string { - return c.ServiceURL(lbPath, strconv.Itoa(lbID), nodePath, strconv.Itoa(nodeID)) -} - -func rootURL(c *gophercloud.ServiceClient, lbID int) string { - return c.ServiceURL(lbPath, strconv.Itoa(lbID), nodePath) -} - -func eventsURL(c *gophercloud.ServiceClient, lbID int) string { - return c.ServiceURL(lbPath, strconv.Itoa(lbID), nodePath, eventPath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/doc.go deleted file mode 100644 index dcec0a87e2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/doc.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Package sessions provides information and interaction with the Session -Persistence feature of the Rackspace Cloud Load Balancer service. - -Session persistence is a feature of the load balancing service that forces -multiple requests from clients (of the same protocol) to be directed to the -same node. This is common with many web applications that do not inherently -share application state between back-end servers. - -There are two modes to choose from: HTTP_COOKIE and SOURCE_IP. You can only set -one of the session persistence modes on a load balancer, and it can only -support one protocol. If you set HTTP_COOKIE mode for an HTTP load balancer, it -supports session persistence for HTTP requests only. Likewise, if you set -SOURCE_IP mode for an HTTPS load balancer, it supports session persistence for -only HTTPS requests. - -To support session persistence for both HTTP and HTTPS requests concurrently, -choose one of the following options: - -- Use two load balancers, one configured for session persistence for HTTP -requests and the other configured for session persistence for HTTPS requests. -That way, the load balancers support session persistence for both HTTP and -HTTPS requests concurrently, with each load balancer supporting one of the -protocols. - -- Use one load balancer, configure it for session persistence for HTTP requests, -and then enable SSL termination for that load balancer. The load balancer -supports session persistence for both HTTP and HTTPS requests concurrently. -*/ -package sessions diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go deleted file mode 100644 index 9596819d16..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go +++ /dev/null @@ -1,58 +0,0 @@ -package sessions - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(id int) string { - return "/loadbalancers/" + strconv.Itoa(id) + "/sessionpersistence" -} - -func mockGetResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "sessionPersistence": { - "persistenceType": "HTTP_COOKIE" - } -} -`) - }) -} - -func mockEnableResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "sessionPersistence": { - "persistenceType": "HTTP_COOKIE" - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDisableResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/requests.go deleted file mode 100644 index 9853ad1320..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/requests.go +++ /dev/null @@ -1,82 +0,0 @@ -package sessions - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" -) - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. -type CreateOptsBuilder interface { - ToSPCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is the common options struct used in this package's Create -// operation. -type CreateOpts struct { - // Required - can either be HTTPCOOKIE or SOURCEIP - Type Type -} - -// ToSPCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToSPCreateMap() (map[string]interface{}, error) { - sp := make(map[string]interface{}) - - if opts.Type == "" { - return sp, errors.New("Type is a required field") - } - - sp["persistenceType"] = opts.Type - return map[string]interface{}{"sessionPersistence": sp}, nil -} - -// Enable is the operation responsible for enabling session persistence for a -// particular load balancer. -func Enable(c *gophercloud.ServiceClient, lbID int, opts CreateOptsBuilder) EnableResult { - var res EnableResult - - reqBody, err := opts.ToSPCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{202}, - }) - - return res -} - -// Get is the operation responsible for showing details of the session -// persistence configuration for a particular load balancer. -func Get(c *gophercloud.ServiceClient, lbID int) GetResult { - var res GetResult - - _, res.Err = perigee.Request("GET", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Disable is the operation responsible for disabling session persistence for a -// particular load balancer. -func Disable(c *gophercloud.ServiceClient, lbID int) DisableResult { - var res DisableResult - - _, res.Err = perigee.Request("DELETE", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/requests_test.go deleted file mode 100644 index f319e540bb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/requests_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package sessions - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const lbID = 12345 - -func TestEnable(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockEnableResponse(t, lbID) - - opts := CreateOpts{Type: HTTPCOOKIE} - err := Enable(client.ServiceClient(), lbID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetResponse(t, lbID) - - sp, err := Get(client.ServiceClient(), lbID).Extract() - th.AssertNoErr(t, err) - - expected := &SessionPersistence{Type: HTTPCOOKIE} - th.AssertDeepEquals(t, expected, sp) -} - -func TestDisable(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDisableResponse(t, lbID) - - err := Disable(client.ServiceClient(), lbID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/results.go deleted file mode 100644 index fe90e722cb..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/results.go +++ /dev/null @@ -1,58 +0,0 @@ -package sessions - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" -) - -// Type represents the type of session persistence being used. -type Type string - -const ( - // HTTPCOOKIE is a session persistence mechanism that inserts an HTTP cookie - // and is used to determine the destination back-end node. This is supported - // for HTTP load balancing only. - HTTPCOOKIE Type = "HTTP_COOKIE" - - // SOURCEIP is a session persistence mechanism that keeps track of the source - // IP address that is mapped and is able to determine the destination - // back-end node. This is supported for HTTPS pass-through and non-HTTP load - // balancing only. - SOURCEIP Type = "SOURCE_IP" -) - -// SessionPersistence indicates how a load balancer is using session persistence -type SessionPersistence struct { - Type Type `mapstructure:"persistenceType"` -} - -// EnableResult represents the result of an enable operation. -type EnableResult struct { - gophercloud.ErrResult -} - -// DisableResult represents the result of a disable operation. -type DisableResult struct { - gophercloud.ErrResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - gophercloud.Result -} - -// Extract interprets a GetResult as an SP, if possible. -func (r GetResult) Extract() (*SessionPersistence, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - SP SessionPersistence `mapstructure:"sessionPersistence"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.SP, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/urls.go deleted file mode 100644 index c4a896d905..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package sessions - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - path = "loadbalancers" - spPath = "sessionpersistence" -) - -func rootURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), spPath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/doc.go deleted file mode 100644 index 6a2c174ae9..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -/* -Package ssl provides information and interaction with the SSL Termination -feature of the Rackspace Cloud Load Balancer service. - -You may only enable and configure SSL termination on load balancers with -non-secure protocols, such as HTTP, but not HTTPS. - -SSL-terminated load balancers decrypt the traffic at the traffic manager and -pass unencrypted traffic to the back-end node. Because of this, the customer's -back-end nodes don't know what protocol the client requested. For this reason, -the X-Forwarded-Proto (XFP) header has been added for identifying the -originating protocol of an HTTP request as "http" or "https" depending on what -protocol the client requested. - -Not every service returns certificates in the proper order. Please verify that -your chain of certificates matches that of walking up the chain from the domain -to the CA root. - -If used for HTTP to HTTPS redirection, the LoadBalancer's securePort attribute -must be set to 443, and its secureTrafficOnly attribute must be true. -*/ -package ssl diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go deleted file mode 100644 index 1d40100125..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go +++ /dev/null @@ -1,195 +0,0 @@ -package ssl - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(id int) string { - return "/loadbalancers/" + strconv.Itoa(id) + "/ssltermination" -} - -func _certURL(id, certID int) string { - url := _rootURL(id) + "/certificatemappings" - if certID > 0 { - url += "/" + strconv.Itoa(certID) - } - return url -} - -func mockGetResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "sslTermination": { - "certificate": "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "enabled": true, - "secureTrafficOnly": false, - "intermediateCertificate": "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - "securePort": 443 - } -} -`) - }) -} - -func mockUpdateResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "sslTermination": { - "enabled": true, - "securePort": 443, - "secureTrafficOnly": false, - "privateKey": "foo", - "certificate": "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "intermediateCertificate": "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n" - } -} - `) - - w.WriteHeader(http.StatusOK) - }) -} - -func mockDeleteResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusOK) - }) -} - -func mockListCertsResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_certURL(lbID, 0), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "certificateMappings": [ - { - "certificateMapping": { - "id": 123, - "hostName": "rackspace.com" - } - }, - { - "certificateMapping": { - "id": 124, - "hostName": "*.rackspace.com" - } - } - ] -} -`) - }) -} - -func mockAddCertResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_certURL(lbID, 0), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "certificateMapping": { - "hostName": "rackspace.com", - "privateKey":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwIudSMpRZx7TS0/AtDVX3DgXwLD9g+XrNaoazlhwhpYALgzJ\nLAbAnOxT6OT0gTpkPus/B7QhW6y6Auf2cdBeW31XoIwPsSoyNhxgErGBxzNARRB9\nlI1HCa1ojFrcULluj4W6rpaOycI5soDBJiJHin/hbZBPZq6vhPCuNP7Ya48Zd/2X\nCQ9ft3XKfmbs1SdrdROIhigse/SGRbMrCorn/vhNIuohr7yOlHG3GcVcUI9k6ZSZ\nBbqF+ZA4ApSF/Q6/cumieEgofhkYbx5fg02s9Jwr4IWnIR2bSHs7UQ6sVgKYzjs7\nPd3Unpa74jFw6/H6shABoO2CIYLotGmQbFgnpwIDAQABAoIBAQCBCQ+PCIclJHNV\ntUzfeCA5ZR4F9JbxHdRTUnxEbOB8UWotckQfTScoAvj4yvdQ42DrCZxj/UOdvFOs\nPufZvlp91bIz1alugWjE+p8n5+2hIaegoTyHoWZKBfxak0myj5KYfHZvKlbmv1ML\nXV4TwEVRfAIG+v87QTY/UUxuF5vR+BpKIbgUJLfPUFFvJUdl84qsJ44pToxaYUd/\nh5YAGC00U4ay1KVSAUnTkkPNZ0lPG/rWU6w6WcTvNRLMd8DzFLTKLOgQfHhbExAF\n+sXPWjWSzbBRP1O7fHqq96QQh4VFiY/7w9W+sDKQyV6Ul17OSXs6aZ4f+lq4rJTI\n1FG96YiBAoGBAO1tiH0h1oWDBYfJB3KJJ6CQQsDGwtHo/DEgznFVP4XwEVbZ98Ha\nBfBCn3sAybbaikyCV1Hwj7kfHMZPDHbrcUSFX7quu/2zPK+wO3lZKXSyu4YsguSa\nRedInN33PpdnlPhLyQdWSuD5sVHJDF6xn22vlyxeILH3ooLg2WOFMPmVAoGBAM+b\nUG/a7iyfpAQKYyuFAsXz6SeFaDY+ZYeX45L112H8Pu+Ie/qzon+bzLB9FIH8GP6+\nQpQgmm/p37U2gD1zChUv7iW6OfQBKk9rWvMpfRF6d7YHquElejhizfTZ+ntBV/VY\ndOYEczxhrdW7keLpatYaaWUy/VboRZmlz/9JGqVLAoGAHfqNmFc0cgk4IowEj7a3\ntTNh6ltub/i+FynwRykfazcDyXaeLPDtfQe8gVh5H8h6W+y9P9BjJVnDVVrX1RAn\nbiJ1EupLPF5sVDapW8ohTOXgfbGTGXBNUUW+4Nv+IDno+mz/RhjkPYHpnM0I7c/5\ntGzOZsC/2hjNgT8I0+MWav0CgYEAuULdJeQVlKalI6HtW2Gn1uRRVJ49H+LQkY6e\nW3+cw2jo9LI0CMWSphNvNrN3wIMp/vHj0fHCP0pSApDvIWbuQXfzKaGko7UCf7rK\nf6GvZRCHkV4IREBAb97j8bMvThxClMNqFfU0rFZyXP+0MOyhFQyertswrgQ6T+Fi\n2mnvKD8CgYAmJHP3NTDRMoMRyAzonJ6nEaGUbAgNmivTaUWMe0+leCvAdwD89gzC\nTKbm3eDUg/6Va3X6ANh3wsfIOe4RXXxcbcFDk9R4zO2M5gfLSjYm5Q87EBZ2hrdj\nM2gLI7dt6thx0J8lR8xRHBEMrVBdgwp0g1gQzo5dAV88/kpkZVps8Q==\n-----END RSA PRIVATE KEY-----\n", - "certificate":"-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "intermediateCertificate":"-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n" - } -} - `) - - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "certificateMapping": { - "id": 123, - "hostName": "rackspace.com", - "certificate":"-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "intermediateCertificate":"-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n" - } -} - `) - }) -} - -func mockGetCertResponse(t *testing.T, lbID, certID int) { - th.Mux.HandleFunc(_certURL(lbID, certID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "certificateMapping": { - "id": 123, - "hostName": "rackspace.com", - "certificate":"-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "intermediateCertificate":"-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n" - } -} -`) - }) -} - -func mockUpdateCertResponse(t *testing.T, lbID, certID int) { - th.Mux.HandleFunc(_certURL(lbID, certID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "certificateMapping": { - "hostName": "rackspace.com", - "privateKey":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwIudSMpRZx7TS0/AtDVX3DgXwLD9g+XrNaoazlhwhpYALgzJ\nLAbAnOxT6OT0gTpkPus/B7QhW6y6Auf2cdBeW31XoIwPsSoyNhxgErGBxzNARRB9\nlI1HCa1ojFrcULluj4W6rpaOycI5soDBJiJHin/hbZBPZq6vhPCuNP7Ya48Zd/2X\nCQ9ft3XKfmbs1SdrdROIhigse/SGRbMrCorn/vhNIuohr7yOlHG3GcVcUI9k6ZSZ\nBbqF+ZA4ApSF/Q6/cumieEgofhkYbx5fg02s9Jwr4IWnIR2bSHs7UQ6sVgKYzjs7\nPd3Unpa74jFw6/H6shABoO2CIYLotGmQbFgnpwIDAQABAoIBAQCBCQ+PCIclJHNV\ntUzfeCA5ZR4F9JbxHdRTUnxEbOB8UWotckQfTScoAvj4yvdQ42DrCZxj/UOdvFOs\nPufZvlp91bIz1alugWjE+p8n5+2hIaegoTyHoWZKBfxak0myj5KYfHZvKlbmv1ML\nXV4TwEVRfAIG+v87QTY/UUxuF5vR+BpKIbgUJLfPUFFvJUdl84qsJ44pToxaYUd/\nh5YAGC00U4ay1KVSAUnTkkPNZ0lPG/rWU6w6WcTvNRLMd8DzFLTKLOgQfHhbExAF\n+sXPWjWSzbBRP1O7fHqq96QQh4VFiY/7w9W+sDKQyV6Ul17OSXs6aZ4f+lq4rJTI\n1FG96YiBAoGBAO1tiH0h1oWDBYfJB3KJJ6CQQsDGwtHo/DEgznFVP4XwEVbZ98Ha\nBfBCn3sAybbaikyCV1Hwj7kfHMZPDHbrcUSFX7quu/2zPK+wO3lZKXSyu4YsguSa\nRedInN33PpdnlPhLyQdWSuD5sVHJDF6xn22vlyxeILH3ooLg2WOFMPmVAoGBAM+b\nUG/a7iyfpAQKYyuFAsXz6SeFaDY+ZYeX45L112H8Pu+Ie/qzon+bzLB9FIH8GP6+\nQpQgmm/p37U2gD1zChUv7iW6OfQBKk9rWvMpfRF6d7YHquElejhizfTZ+ntBV/VY\ndOYEczxhrdW7keLpatYaaWUy/VboRZmlz/9JGqVLAoGAHfqNmFc0cgk4IowEj7a3\ntTNh6ltub/i+FynwRykfazcDyXaeLPDtfQe8gVh5H8h6W+y9P9BjJVnDVVrX1RAn\nbiJ1EupLPF5sVDapW8ohTOXgfbGTGXBNUUW+4Nv+IDno+mz/RhjkPYHpnM0I7c/5\ntGzOZsC/2hjNgT8I0+MWav0CgYEAuULdJeQVlKalI6HtW2Gn1uRRVJ49H+LQkY6e\nW3+cw2jo9LI0CMWSphNvNrN3wIMp/vHj0fHCP0pSApDvIWbuQXfzKaGko7UCf7rK\nf6GvZRCHkV4IREBAb97j8bMvThxClMNqFfU0rFZyXP+0MOyhFQyertswrgQ6T+Fi\n2mnvKD8CgYAmJHP3NTDRMoMRyAzonJ6nEaGUbAgNmivTaUWMe0+leCvAdwD89gzC\nTKbm3eDUg/6Va3X6ANh3wsfIOe4RXXxcbcFDk9R4zO2M5gfLSjYm5Q87EBZ2hrdj\nM2gLI7dt6thx0J8lR8xRHBEMrVBdgwp0g1gQzo5dAV88/kpkZVps8Q==\n-----END RSA PRIVATE KEY-----\n", - "certificate":"-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "intermediateCertificate":"-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n" - } -} - `) - - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, ` -{ - "certificateMapping": { - "id": 123, - "hostName": "rackspace.com", - "certificate":"-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - "intermediateCertificate":"-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n" - } -} - `) - }) -} - -func mockDeleteCertResponse(t *testing.T, lbID, certID int) { - th.Mux.HandleFunc(_certURL(lbID, certID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusOK) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/requests.go deleted file mode 100644 index 84b2712172..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/requests.go +++ /dev/null @@ -1,278 +0,0 @@ -package ssl - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -var ( - errPrivateKey = errors.New("PrivateKey is a required field") - errCertificate = errors.New("Certificate is a required field") - errIntCertificate = errors.New("IntCertificate is a required field") -) - -// UpdateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Update operation in this package. -type UpdateOptsBuilder interface { - ToSSLUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts is the common options struct used in this package's Update -// operation. -type UpdateOpts struct { - // Required - consult the SSLTermConfig struct for more info. - SecurePort int - - // Required - consult the SSLTermConfig struct for more info. - PrivateKey string - - // Required - consult the SSLTermConfig struct for more info. - Certificate string - - // Required - consult the SSLTermConfig struct for more info. - IntCertificate string - - // Optional - consult the SSLTermConfig struct for more info. - Enabled *bool - - // Optional - consult the SSLTermConfig struct for more info. - SecureTrafficOnly *bool -} - -// ToSSLUpdateMap casts a CreateOpts struct to a map. -func (opts UpdateOpts) ToSSLUpdateMap() (map[string]interface{}, error) { - ssl := make(map[string]interface{}) - - if opts.SecurePort == 0 { - return ssl, errors.New("SecurePort needs to be an integer greater than 0") - } - if opts.PrivateKey == "" { - return ssl, errPrivateKey - } - if opts.Certificate == "" { - return ssl, errCertificate - } - if opts.IntCertificate == "" { - return ssl, errIntCertificate - } - - ssl["securePort"] = opts.SecurePort - ssl["privateKey"] = opts.PrivateKey - ssl["certificate"] = opts.Certificate - ssl["intermediateCertificate"] = opts.IntCertificate - - if opts.Enabled != nil { - ssl["enabled"] = &opts.Enabled - } - - if opts.SecureTrafficOnly != nil { - ssl["secureTrafficOnly"] = &opts.SecureTrafficOnly - } - - return map[string]interface{}{"sslTermination": ssl}, nil -} - -// Update is the operation responsible for updating the SSL Termination -// configuration for a load balancer. -func Update(c *gophercloud.ServiceClient, lbID int, opts UpdateOptsBuilder) UpdateResult { - var res UpdateResult - - reqBody, err := opts.ToSSLUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Get is the operation responsible for showing the details of the SSL -// Termination configuration for a load balancer. -func Get(c *gophercloud.ServiceClient, lbID int) GetResult { - var res GetResult - - _, res.Err = perigee.Request("GET", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Delete is the operation responsible for deleting the SSL Termination -// configuration for a load balancer. -func Delete(c *gophercloud.ServiceClient, lbID int) DeleteResult { - var res DeleteResult - - _, res.Err = perigee.Request("DELETE", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return res -} - -// ListCerts will list all of the certificate mappings associated with a -// SSL-terminated HTTP load balancer. -func ListCerts(c *gophercloud.ServiceClient, lbID int) pagination.Pager { - url := certURL(c, lbID) - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return CertPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateCertOptsBuilder is the interface options structs have to satisfy in -// order to be used in the AddCert operation in this package. -type CreateCertOptsBuilder interface { - ToCertCreateMap() (map[string]interface{}, error) -} - -// CreateCertOpts represents the options used when adding a new certificate mapping. -type CreateCertOpts struct { - HostName string - PrivateKey string - Certificate string - IntCertificate string -} - -// ToCertCreateMap will cast an CreateCertOpts struct to a map for JSON serialization. -func (opts CreateCertOpts) ToCertCreateMap() (map[string]interface{}, error) { - cm := make(map[string]interface{}) - - if opts.HostName == "" { - return cm, errors.New("HostName is a required option") - } - if opts.PrivateKey == "" { - return cm, errPrivateKey - } - if opts.Certificate == "" { - return cm, errCertificate - } - - cm["hostName"] = opts.HostName - cm["privateKey"] = opts.PrivateKey - cm["certificate"] = opts.Certificate - - if opts.IntCertificate != "" { - cm["intermediateCertificate"] = opts.IntCertificate - } - - return map[string]interface{}{"certificateMapping": cm}, nil -} - -// CreateCert will add a new SSL certificate and allow an SSL-terminated HTTP -// load balancer to use it. This feature is useful because it allows multiple -// certificates to be used. The maximum number of certificates that can be -// stored per LB is 20. -func CreateCert(c *gophercloud.ServiceClient, lbID int, opts CreateCertOptsBuilder) CreateCertResult { - var res CreateCertResult - - reqBody, err := opts.ToCertCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", certURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// GetCert will show the details of an existing SSL certificate. -func GetCert(c *gophercloud.ServiceClient, lbID, certID int) GetCertResult { - var res GetCertResult - - _, res.Err = perigee.Request("GET", certResourceURL(c, lbID, certID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// UpdateCertOptsBuilder is the interface options structs have to satisfy in -// order to be used in the UpdateCert operation in this package. -type UpdateCertOptsBuilder interface { - ToCertUpdateMap() (map[string]interface{}, error) -} - -// UpdateCertOpts represents the options needed to update a SSL certificate. -type UpdateCertOpts struct { - HostName string - PrivateKey string - Certificate string - IntCertificate string -} - -// ToCertUpdateMap will cast an UpdateCertOpts struct into a map for JSON -// seralization. -func (opts UpdateCertOpts) ToCertUpdateMap() (map[string]interface{}, error) { - cm := make(map[string]interface{}) - - if opts.HostName != "" { - cm["hostName"] = opts.HostName - } - if opts.PrivateKey != "" { - cm["privateKey"] = opts.PrivateKey - } - if opts.Certificate != "" { - cm["certificate"] = opts.Certificate - } - if opts.IntCertificate != "" { - cm["intermediateCertificate"] = opts.IntCertificate - } - - return map[string]interface{}{"certificateMapping": cm}, nil -} - -// UpdateCert is the operation responsible for updating the details of an -// existing SSL certificate. -func UpdateCert(c *gophercloud.ServiceClient, lbID, certID int, opts UpdateCertOptsBuilder) UpdateCertResult { - var res UpdateCertResult - - reqBody, err := opts.ToCertUpdateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", certResourceURL(c, lbID, certID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{202}, - }) - - return res -} - -// DeleteCert is the operation responsible for permanently removing a SSL -// certificate. -func DeleteCert(c *gophercloud.ServiceClient, lbID, certID int) DeleteResult { - var res DeleteResult - - _, res.Err = perigee.Request("DELETE", certResourceURL(c, lbID, certID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{200}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/requests_test.go deleted file mode 100644 index fb14c4a28d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/requests_test.go +++ /dev/null @@ -1,167 +0,0 @@ -package ssl - -import ( - "testing" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ( - lbID = 12345 - certID = 67890 -) - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetResponse(t, lbID) - - sp, err := Get(client.ServiceClient(), lbID).Extract() - th.AssertNoErr(t, err) - - expected := &SSLTermConfig{ - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - Enabled: true, - SecureTrafficOnly: false, - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - SecurePort: 443, - } - th.AssertDeepEquals(t, expected, sp) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateResponse(t, lbID) - - opts := UpdateOpts{ - Enabled: gophercloud.Enabled, - SecurePort: 443, - SecureTrafficOnly: gophercloud.Disabled, - PrivateKey: "foo", - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - } - err := Update(client.ServiceClient(), lbID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteResponse(t, lbID) - - err := Delete(client.ServiceClient(), lbID).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestListCerts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListCertsResponse(t, lbID) - - count := 0 - - err := ListCerts(client.ServiceClient(), lbID).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractCerts(page) - th.AssertNoErr(t, err) - - expected := []Certificate{ - Certificate{ID: 123, HostName: "rackspace.com"}, - Certificate{ID: 124, HostName: "*.rackspace.com"}, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreateCert(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockAddCertResponse(t, lbID) - - opts := CreateCertOpts{ - HostName: "rackspace.com", - PrivateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwIudSMpRZx7TS0/AtDVX3DgXwLD9g+XrNaoazlhwhpYALgzJ\nLAbAnOxT6OT0gTpkPus/B7QhW6y6Auf2cdBeW31XoIwPsSoyNhxgErGBxzNARRB9\nlI1HCa1ojFrcULluj4W6rpaOycI5soDBJiJHin/hbZBPZq6vhPCuNP7Ya48Zd/2X\nCQ9ft3XKfmbs1SdrdROIhigse/SGRbMrCorn/vhNIuohr7yOlHG3GcVcUI9k6ZSZ\nBbqF+ZA4ApSF/Q6/cumieEgofhkYbx5fg02s9Jwr4IWnIR2bSHs7UQ6sVgKYzjs7\nPd3Unpa74jFw6/H6shABoO2CIYLotGmQbFgnpwIDAQABAoIBAQCBCQ+PCIclJHNV\ntUzfeCA5ZR4F9JbxHdRTUnxEbOB8UWotckQfTScoAvj4yvdQ42DrCZxj/UOdvFOs\nPufZvlp91bIz1alugWjE+p8n5+2hIaegoTyHoWZKBfxak0myj5KYfHZvKlbmv1ML\nXV4TwEVRfAIG+v87QTY/UUxuF5vR+BpKIbgUJLfPUFFvJUdl84qsJ44pToxaYUd/\nh5YAGC00U4ay1KVSAUnTkkPNZ0lPG/rWU6w6WcTvNRLMd8DzFLTKLOgQfHhbExAF\n+sXPWjWSzbBRP1O7fHqq96QQh4VFiY/7w9W+sDKQyV6Ul17OSXs6aZ4f+lq4rJTI\n1FG96YiBAoGBAO1tiH0h1oWDBYfJB3KJJ6CQQsDGwtHo/DEgznFVP4XwEVbZ98Ha\nBfBCn3sAybbaikyCV1Hwj7kfHMZPDHbrcUSFX7quu/2zPK+wO3lZKXSyu4YsguSa\nRedInN33PpdnlPhLyQdWSuD5sVHJDF6xn22vlyxeILH3ooLg2WOFMPmVAoGBAM+b\nUG/a7iyfpAQKYyuFAsXz6SeFaDY+ZYeX45L112H8Pu+Ie/qzon+bzLB9FIH8GP6+\nQpQgmm/p37U2gD1zChUv7iW6OfQBKk9rWvMpfRF6d7YHquElejhizfTZ+ntBV/VY\ndOYEczxhrdW7keLpatYaaWUy/VboRZmlz/9JGqVLAoGAHfqNmFc0cgk4IowEj7a3\ntTNh6ltub/i+FynwRykfazcDyXaeLPDtfQe8gVh5H8h6W+y9P9BjJVnDVVrX1RAn\nbiJ1EupLPF5sVDapW8ohTOXgfbGTGXBNUUW+4Nv+IDno+mz/RhjkPYHpnM0I7c/5\ntGzOZsC/2hjNgT8I0+MWav0CgYEAuULdJeQVlKalI6HtW2Gn1uRRVJ49H+LQkY6e\nW3+cw2jo9LI0CMWSphNvNrN3wIMp/vHj0fHCP0pSApDvIWbuQXfzKaGko7UCf7rK\nf6GvZRCHkV4IREBAb97j8bMvThxClMNqFfU0rFZyXP+0MOyhFQyertswrgQ6T+Fi\n2mnvKD8CgYAmJHP3NTDRMoMRyAzonJ6nEaGUbAgNmivTaUWMe0+leCvAdwD89gzC\nTKbm3eDUg/6Va3X6ANh3wsfIOe4RXXxcbcFDk9R4zO2M5gfLSjYm5Q87EBZ2hrdj\nM2gLI7dt6thx0J8lR8xRHBEMrVBdgwp0g1gQzo5dAV88/kpkZVps8Q==\n-----END RSA PRIVATE KEY-----\n", - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - } - - cm, err := CreateCert(client.ServiceClient(), lbID, opts).Extract() - th.AssertNoErr(t, err) - - expected := &Certificate{ - ID: 123, - HostName: "rackspace.com", - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - } - th.AssertDeepEquals(t, expected, cm) -} - -func TestGetCertMapping(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetCertResponse(t, lbID, certID) - - sp, err := GetCert(client.ServiceClient(), lbID, certID).Extract() - th.AssertNoErr(t, err) - - expected := &Certificate{ - ID: 123, - HostName: "rackspace.com", - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - } - th.AssertDeepEquals(t, expected, sp) -} - -func TestUpdateCert(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockUpdateCertResponse(t, lbID, certID) - - opts := UpdateCertOpts{ - HostName: "rackspace.com", - PrivateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwIudSMpRZx7TS0/AtDVX3DgXwLD9g+XrNaoazlhwhpYALgzJ\nLAbAnOxT6OT0gTpkPus/B7QhW6y6Auf2cdBeW31XoIwPsSoyNhxgErGBxzNARRB9\nlI1HCa1ojFrcULluj4W6rpaOycI5soDBJiJHin/hbZBPZq6vhPCuNP7Ya48Zd/2X\nCQ9ft3XKfmbs1SdrdROIhigse/SGRbMrCorn/vhNIuohr7yOlHG3GcVcUI9k6ZSZ\nBbqF+ZA4ApSF/Q6/cumieEgofhkYbx5fg02s9Jwr4IWnIR2bSHs7UQ6sVgKYzjs7\nPd3Unpa74jFw6/H6shABoO2CIYLotGmQbFgnpwIDAQABAoIBAQCBCQ+PCIclJHNV\ntUzfeCA5ZR4F9JbxHdRTUnxEbOB8UWotckQfTScoAvj4yvdQ42DrCZxj/UOdvFOs\nPufZvlp91bIz1alugWjE+p8n5+2hIaegoTyHoWZKBfxak0myj5KYfHZvKlbmv1ML\nXV4TwEVRfAIG+v87QTY/UUxuF5vR+BpKIbgUJLfPUFFvJUdl84qsJ44pToxaYUd/\nh5YAGC00U4ay1KVSAUnTkkPNZ0lPG/rWU6w6WcTvNRLMd8DzFLTKLOgQfHhbExAF\n+sXPWjWSzbBRP1O7fHqq96QQh4VFiY/7w9W+sDKQyV6Ul17OSXs6aZ4f+lq4rJTI\n1FG96YiBAoGBAO1tiH0h1oWDBYfJB3KJJ6CQQsDGwtHo/DEgznFVP4XwEVbZ98Ha\nBfBCn3sAybbaikyCV1Hwj7kfHMZPDHbrcUSFX7quu/2zPK+wO3lZKXSyu4YsguSa\nRedInN33PpdnlPhLyQdWSuD5sVHJDF6xn22vlyxeILH3ooLg2WOFMPmVAoGBAM+b\nUG/a7iyfpAQKYyuFAsXz6SeFaDY+ZYeX45L112H8Pu+Ie/qzon+bzLB9FIH8GP6+\nQpQgmm/p37U2gD1zChUv7iW6OfQBKk9rWvMpfRF6d7YHquElejhizfTZ+ntBV/VY\ndOYEczxhrdW7keLpatYaaWUy/VboRZmlz/9JGqVLAoGAHfqNmFc0cgk4IowEj7a3\ntTNh6ltub/i+FynwRykfazcDyXaeLPDtfQe8gVh5H8h6W+y9P9BjJVnDVVrX1RAn\nbiJ1EupLPF5sVDapW8ohTOXgfbGTGXBNUUW+4Nv+IDno+mz/RhjkPYHpnM0I7c/5\ntGzOZsC/2hjNgT8I0+MWav0CgYEAuULdJeQVlKalI6HtW2Gn1uRRVJ49H+LQkY6e\nW3+cw2jo9LI0CMWSphNvNrN3wIMp/vHj0fHCP0pSApDvIWbuQXfzKaGko7UCf7rK\nf6GvZRCHkV4IREBAb97j8bMvThxClMNqFfU0rFZyXP+0MOyhFQyertswrgQ6T+Fi\n2mnvKD8CgYAmJHP3NTDRMoMRyAzonJ6nEaGUbAgNmivTaUWMe0+leCvAdwD89gzC\nTKbm3eDUg/6Va3X6ANh3wsfIOe4RXXxcbcFDk9R4zO2M5gfLSjYm5Q87EBZ2hrdj\nM2gLI7dt6thx0J8lR8xRHBEMrVBdgwp0g1gQzo5dAV88/kpkZVps8Q==\n-----END RSA PRIVATE KEY-----\n", - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - } - - cm, err := UpdateCert(client.ServiceClient(), lbID, certID, opts).Extract() - th.AssertNoErr(t, err) - - expected := &Certificate{ - ID: 123, - HostName: "rackspace.com", - Certificate: "-----BEGIN CERTIFICATE-----\nMIIEXTCCA0WgAwIBAgIGATTEAjK3MA0GCSqGSIb3DQEBBQUAMIGDMRkwFwYDVQQD\nExBUZXN0IENBIFNUdWIgS2V5MRcwFQYDVQQLEw5QbGF0Zm9ybSBMYmFhczEaMBgG\nA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFDASBgNVBAcTC1NhbiBBbnRvbmlvMQ4w\nDAYDVQQIEwVUZXhhczELMAkGA1UEBhMCVVMwHhcNMTIwMTA5MTk0NjQ1WhcNMTQw\nMTA4MTk0NjQ1WjCBgjELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRQwEgYD\nVQQHEwtTYW4gQW50b25pbzEaMBgGA1UEChMRUmFja3NwYWNlIEhvc3RpbmcxFzAV\nBgNVBAsTDlBsYXRmb3JtIExiYWFzMRgwFgYDVQQDEw9UZXN0IENsaWVudCBLZXkw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAi51IylFnHtNLT8C0NVfc\nOBfAsP2D5es1qhrOWHCGlgAuDMksBsCc7FPo5PSBOmQ+6z8HtCFbrLoC5/Zx0F5b\nfVegjA+xKjI2HGASsYHHM0BFEH2UjUcJrWiMWtxQuW6Phbqulo7JwjmygMEmIkeK\nf+FtkE9mrq+E8K40/thrjxl3/ZcJD1+3dcp+ZuzVJ2t1E4iGKCx79IZFsysKiuf+\n+E0i6iGvvI6UcbcZxVxQj2TplJkFuoX5kDgClIX9Dr9y6aJ4SCh+GRhvHl+DTaz0\nnCvghachHZtIeztRDqxWApjOOzs93dSelrviMXDr8fqyEAGg7YIhgui0aZBsWCen\nAgMBAAGjgdUwgdIwgbAGA1UdIwSBqDCBpYAUNpx1Pc6cGA7KqEwHMmHBTZMA7lSh\ngYmkgYYwgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVU4IBATAd\nBgNVHQ4EFgQULueOfsjZZOHwJHZwBy6u0swnpccwDQYJKoZIhvcNAQEFBQADggEB\nAFNuqSVUaotUJoWDv4z7Kbi6JFpTjDht5ORw4BdVYlRD4h9DACAFzPrPV2ym/Osp\nhNMdZq6msZku7MdOSQVhdeGWrSNk3M8O9Hg7cVzPNXOF3iNoo3irQ5tURut44xs4\nWw5YWQqS9WyUY5snD8tm7Y1rQTPfhg+678xIq/zWCv/u+FSnfVv1nlhLVQkEeG/Y\ngh1uMaTIpUKTGEjIAGtpGP7wwIcXptR/HyfzhTUSTaWc1Ef7zoKT9LL5z3IV1hC2\njVWz+RwYs98LjMuksJFoHqRfWyYhCIym0jb6GTwaEmpxAjc+d7OLNQdnoEGoUYGP\nYjtfkRYg265ESMA+Kww4Xy8=\n-----END CERTIFICATE-----\n", - IntCertificate: "-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzEZMBcGA1UEAxMQVGVz\ndCBDQSBTVHViIEtleTEXMBUGA1UECxMOUGxhdGZvcm0gTGJhYXMxGjAYBgNVBAoT\nEVJhY2tzcGFjZSBIb3N0aW5nMRQwEgYDVQQHEwtTYW4gQW50b25pbzEOMAwGA1UE\nCBMFVGV4YXMxCzAJBgNVBAYTAlVTMB4XDTEyMDEwOTE5NDU0OVoXDTE0MDEwODE5\nNDU0OVowgYMxGTAXBgNVBAMTEFRlc3QgQ0EgU1R1YiBLZXkxFzAVBgNVBAsTDlBs\nYXRmb3JtIExiYWFzMRowGAYDVQQKExFSYWNrc3BhY2UgSG9zdGluZzEUMBIGA1UE\nBxMLU2FuIEFudG9uaW8xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNh55lwTVwQvNoEZjq1zGdYz9jA\nXXdjizn8AJhjHLOAallfPtvCfTEgKanhdoyz5FnhQE8HbDAop/KNS1lN2UMvdl5f\nZNLTSjJrNtedqxQwxN/i3bpyBxNVejUH2NjV1mmyj+5CJYwCzWalvI/gLPq/A3as\nO2EQqtf3U8unRgn0zXLRdYxV9MrUzNAmdipPNvNrsVdrCgA42rgF/8KsyRVQfJCX\nfN7PGCfrsC3YaUvhymraWxNnXIzMYTNa9wEeBZLUw8SlEtpa1Zsvui+TPXu3USNZ\nVnWH8Lb6ENlnoX0VBwo62fjOG3JzhNKoJawi3bRqyDdINOvafr7iPrrs/T8CAwEA\nAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNpx1Pc6cGA7KqEwHMmHB\nTZMA7lQwDQYJKoZIhvcNAQEFBQADggEBAMoRgH3iTG3t317viLKoY+lNMHUgHuR7\nb3mn9MidJKyYVewe6hCDIN6WY4fUojmMW9wFJWJIo0hRMNHL3n3tq8HP2j20Mxy8\nacPdfGZJa+jiBw72CrIGdobKaFduIlIEDBA1pNdZIJ+EulrtqrMesnIt92WaypIS\n8JycbIgDMCiyC0ENHEk8UWlC6429c7OZAsplMTbHME/1R4btxjkdfrYZJjdJ2yL2\n8cjZDUDMCPTdW/ycP07Gkq30RB5tACB5aZdaCn2YaKC8FsEdhff4X7xEOfOEHWEq\nSRxADDj8Lx1MT6QpR07hCiDyHfTCtbqzI0iGjX63Oh7xXSa0f+JVTa8=\n-----END CERTIFICATE-----\n", - } - th.AssertDeepEquals(t, expected, cm) -} - -func TestDeleteCert(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteCertResponse(t, lbID, certID) - - err := DeleteCert(client.ServiceClient(), lbID, certID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/results.go deleted file mode 100644 index ead9fcd37e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/results.go +++ /dev/null @@ -1,148 +0,0 @@ -package ssl - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// SSLTermConfig represents the SSL configuration for a particular load balancer. -type SSLTermConfig struct { - // The port on which the SSL termination load balancer listens for secure - // traffic. The value must be unique to the existing LB protocol/port - // combination - SecurePort int `mapstructure:"securePort"` - - // The private key for the SSL certificate which is validated and verified - // against the provided certificates. - PrivateKey string `mapstructure:"privatekey"` - - // The certificate used for SSL termination, which is validated and verified - // against the key and intermediate certificate if provided. - Certificate string - - // The intermediate certificate (for the user). The intermediate certificate - // is validated and verified against the key and certificate credentials - // provided. A user may only provide this value when accompanied by a - // Certificate, PrivateKey, and SecurePort. It may not be added or updated as - // a single attribute in a future operation. - IntCertificate string `mapstructure:"intermediatecertificate"` - - // Determines if the load balancer is enabled to terminate SSL traffic or not. - // If this is set to false, the load balancer retains its specified SSL - // attributes but does not terminate SSL traffic. - Enabled bool - - // Determines if the load balancer can only accept secure traffic. If set to - // true, the load balancer will not accept non-secure traffic. - SecureTrafficOnly bool -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// UpdateResult represents the result of an update operation. -type UpdateResult struct { - gophercloud.ErrResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - gophercloud.Result -} - -// Extract interprets a GetResult as a SSLTermConfig struct, if possible. -func (r GetResult) Extract() (*SSLTermConfig, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - SSL SSLTermConfig `mapstructure:"sslTermination"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.SSL, err -} - -// Certificate represents an SSL certificate associated with an SSL-terminated -// HTTP load balancer. -type Certificate struct { - ID int - HostName string - Certificate string - IntCertificate string `mapstructure:"intermediateCertificate"` -} - -// CertPage represents a page of certificates. -type CertPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a CertMappingPage struct is empty. -func (p CertPage) IsEmpty() (bool, error) { - is, err := ExtractCerts(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractCerts accepts a Page struct, specifically a CertPage struct, and -// extracts the elements into a slice of Cert structs. In other words, a generic -// collection is mapped into a relevant slice. -func ExtractCerts(page pagination.Page) ([]Certificate, error) { - type NestedMap struct { - Cert Certificate `mapstructure:"certificateMapping" json:"certificateMapping"` - } - var resp struct { - Certs []NestedMap `mapstructure:"certificateMappings" json:"certificateMappings"` - } - - err := mapstructure.Decode(page.(CertPage).Body, &resp) - - slice := []Certificate{} - for _, cert := range resp.Certs { - slice = append(slice, cert.Cert) - } - - return slice, err -} - -type certResult struct { - gophercloud.Result -} - -// Extract interprets a result as a CertMapping struct, if possible. -func (r certResult) Extract() (*Certificate, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - Cert Certificate `mapstructure:"certificateMapping"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.Cert, err -} - -// CreateCertResult represents the result of an CreateCert operation. -type CreateCertResult struct { - certResult -} - -// GetCertResult represents the result of a GetCert operation. -type GetCertResult struct { - certResult -} - -// UpdateCertResult represents the result of an UpdateCert operation. -type UpdateCertResult struct { - certResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/urls.go deleted file mode 100644 index aa814b3583..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package ssl - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - path = "loadbalancers" - sslPath = "ssltermination" - certPath = "certificatemappings" -) - -func rootURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), sslPath) -} - -func certURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), sslPath, certPath) -} - -func certResourceURL(c *gophercloud.ServiceClient, id, certID int) string { - return c.ServiceURL(path, strconv.Itoa(id), sslPath, certPath, strconv.Itoa(certID)) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/doc.go deleted file mode 100644 index 1ed605d362..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -/* -Package throttle provides information and interaction with the Connection -Throttling feature of the Rackspace Cloud Load Balancer service. -*/ -package throttle diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go deleted file mode 100644 index 40223f60a6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go +++ /dev/null @@ -1,61 +0,0 @@ -package throttle - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(id int) string { - return "/loadbalancers/" + strconv.Itoa(id) + "/connectionthrottle" -} - -func mockGetResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "connectionThrottle": { - "maxConnections": 100 - } -} -`) - }) -} - -func mockCreateResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "connectionThrottle": { - "maxConnectionRate": 0, - "maxConnections": 200, - "minConnections": 0, - "rateInterval": 0 - } -} - `) - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/requests.go deleted file mode 100644 index 8c2e4be415..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/requests.go +++ /dev/null @@ -1,95 +0,0 @@ -package throttle - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" -) - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. -type CreateOptsBuilder interface { - ToCTCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is the common options struct used in this package's Create -// operation. -type CreateOpts struct { - // Required - the maximum amount of connections per IP address to allow per LB. - MaxConnections int - - // Deprecated as of v1.22. - MaxConnectionRate int - - // Deprecated as of v1.22. - MinConnections int - - // Deprecated as of v1.22. - RateInterval int -} - -// ToCTCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToCTCreateMap() (map[string]interface{}, error) { - ct := make(map[string]interface{}) - - if opts.MaxConnections < 0 || opts.MaxConnections > 100000 { - return ct, errors.New("MaxConnections must be an int between 0 and 100000") - } - - ct["maxConnections"] = opts.MaxConnections - ct["maxConnectionRate"] = opts.MaxConnectionRate - ct["minConnections"] = opts.MinConnections - ct["rateInterval"] = opts.RateInterval - - return map[string]interface{}{"connectionThrottle": ct}, nil -} - -// Create is the operation responsible for creating or updating the connection -// throttling configuration for a load balancer. -func Create(c *gophercloud.ServiceClient, lbID int, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToCTCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("PUT", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{202}, - }) - - return res -} - -// Get is the operation responsible for showing the details of the connection -// throttling configuration for a load balancer. -func Get(c *gophercloud.ServiceClient, lbID int) GetResult { - var res GetResult - - _, res.Err = perigee.Request("GET", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - Results: &res.Body, - OkCodes: []int{200}, - }) - - return res -} - -// Delete is the operation responsible for deleting the connection throttling -// configuration for a load balancer. -func Delete(c *gophercloud.ServiceClient, lbID int) DeleteResult { - var res DeleteResult - - _, res.Err = perigee.Request("DELETE", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/requests_test.go deleted file mode 100644 index 6e9703ffce..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/requests_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package throttle - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const lbID = 12345 - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateResponse(t, lbID) - - opts := CreateOpts{MaxConnections: 200} - err := Create(client.ServiceClient(), lbID, opts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockGetResponse(t, lbID) - - sp, err := Get(client.ServiceClient(), lbID).Extract() - th.AssertNoErr(t, err) - - expected := &ConnectionThrottle{MaxConnections: 100} - th.AssertDeepEquals(t, expected, sp) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteResponse(t, lbID) - - err := Delete(client.ServiceClient(), lbID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/results.go deleted file mode 100644 index db93c6f3f4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/results.go +++ /dev/null @@ -1,43 +0,0 @@ -package throttle - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" -) - -// ConnectionThrottle represents the connection throttle configuration for a -// particular load balancer. -type ConnectionThrottle struct { - MaxConnections int -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - gophercloud.ErrResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} - -// GetResult represents the result of a get operation. -type GetResult struct { - gophercloud.Result -} - -// Extract interprets a GetResult as a SP, if possible. -func (r GetResult) Extract() (*ConnectionThrottle, error) { - if r.Err != nil { - return nil, r.Err - } - - var response struct { - CT ConnectionThrottle `mapstructure:"connectionThrottle"` - } - - err := mapstructure.Decode(r.Body, &response) - - return &response.CT, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/urls.go deleted file mode 100644 index b77f0ac1c7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package throttle - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - path = "loadbalancers" - ctPath = "connectionthrottle" -) - -func rootURL(c *gophercloud.ServiceClient, id int) string { - return c.ServiceURL(path, strconv.Itoa(id), ctPath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/doc.go deleted file mode 100644 index 5c3846d44d..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/doc.go +++ /dev/null @@ -1,13 +0,0 @@ -/* -Package vips provides information and interaction with the Virtual IP API -resource for the Rackspace Cloud Load Balancer service. - -A virtual IP (VIP) makes a load balancer accessible by clients. The load -balancing service supports either a public VIP, routable on the public Internet, -or a ServiceNet address, routable only within the region in which the load -balancer resides. - -All load balancers must have at least one virtual IP associated with them at -all times. -*/ -package vips diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/fixtures.go deleted file mode 100644 index 158759f7fa..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/fixtures.go +++ /dev/null @@ -1,88 +0,0 @@ -package vips - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func _rootURL(lbID int) string { - return "/loadbalancers/" + strconv.Itoa(lbID) + "/virtualips" -} - -func mockListResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "virtualIps": [ - { - "id": 1000, - "address": "206.10.10.210", - "type": "PUBLIC" - } - ] -} - `) - }) -} - -func mockCreateResponse(t *testing.T, lbID int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - th.TestJSONRequest(t, r, ` -{ - "type":"PUBLIC", - "ipVersion":"IPV6" -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, ` -{ - "address":"fd24:f480:ce44:91bc:1af2:15ff:0000:0002", - "id":9000134, - "type":"PUBLIC", - "ipVersion":"IPV6" -} - `) - }) -} - -func mockBatchDeleteResponse(t *testing.T, lbID int, ids []int) { - th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - r.ParseForm() - - for k, v := range ids { - fids := r.Form["id"] - th.AssertEquals(t, strconv.Itoa(v), fids[k]) - } - - w.WriteHeader(http.StatusAccepted) - }) -} - -func mockDeleteResponse(t *testing.T, lbID, vipID int) { - url := _rootURL(lbID) + "/" + strconv.Itoa(vipID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/requests.go deleted file mode 100644 index 42f0c1d071..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/requests.go +++ /dev/null @@ -1,112 +0,0 @@ -package vips - -import ( - "errors" - - "github.com/racker/perigee" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// List is the operation responsible for returning a paginated collection of -// load balancer virtual IP addresses. -func List(client *gophercloud.ServiceClient, loadBalancerID int) pagination.Pager { - url := rootURL(client, loadBalancerID) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return VIPPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder is the interface options structs have to satisfy in order -// to be used in the main Create operation in this package. Since many -// extensions decorate or modify the common logic, it is useful for them to -// satisfy a basic interface in order for them to be used. -type CreateOptsBuilder interface { - ToVIPCreateMap() (map[string]interface{}, error) -} - -// CreateOpts is the common options struct used in this package's Create -// operation. -type CreateOpts struct { - // Optional - the ID of an existing virtual IP. By doing this, you are - // allowing load balancers to share IPV6 addresses. - ID string - - // Optional - the type of address. - Type Type - - // Optional - the version of address. - Version Version -} - -// ToVIPCreateMap casts a CreateOpts struct to a map. -func (opts CreateOpts) ToVIPCreateMap() (map[string]interface{}, error) { - lb := make(map[string]interface{}) - - if opts.ID != "" { - lb["id"] = opts.ID - } - if opts.Type != "" { - lb["type"] = opts.Type - } - if opts.Version != "" { - lb["ipVersion"] = opts.Version - } - - return lb, nil -} - -// Create is the operation responsible for assigning a new Virtual IP to an -// existing load balancer resource. Currently, only version 6 IP addresses may -// be added. -func Create(c *gophercloud.ServiceClient, lbID int, opts CreateOptsBuilder) CreateResult { - var res CreateResult - - reqBody, err := opts.ToVIPCreateMap() - if err != nil { - res.Err = err - return res - } - - _, res.Err = perigee.Request("POST", rootURL(c, lbID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - ReqBody: &reqBody, - Results: &res.Body, - OkCodes: []int{202}, - }) - - return res -} - -// BulkDelete is the operation responsible for batch deleting multiple VIPs in -// a single operation. It accepts a slice of integer IDs and will remove them -// from the load balancer. The maximum limit is 10 VIP removals at once. -func BulkDelete(c *gophercloud.ServiceClient, loadBalancerID int, vipIDs []int) DeleteResult { - var res DeleteResult - - if len(vipIDs) > 10 || len(vipIDs) == 0 { - res.Err = errors.New("You must provide a minimum of 1 and a maximum of 10 VIP IDs") - return res - } - - url := rootURL(c, loadBalancerID) - url += gophercloud.IDSliceToQueryString("id", vipIDs) - - _, res.Err = perigee.Request("DELETE", url, perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - - return res -} - -// Delete is the operation responsible for permanently deleting a VIP. -func Delete(c *gophercloud.ServiceClient, lbID, vipID int) DeleteResult { - var res DeleteResult - _, res.Err = perigee.Request("DELETE", resourceURL(c, lbID, vipID), perigee.Options{ - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{202}, - }) - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/requests_test.go deleted file mode 100644 index 74ac461738..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/requests_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package vips - -import ( - "testing" - - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const ( - lbID = 12345 - vipID = 67890 - vipID2 = 67891 -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockListResponse(t, lbID) - - count := 0 - - err := List(client.ServiceClient(), lbID).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractVIPs(page) - th.AssertNoErr(t, err) - - expected := []VIP{ - VIP{ID: 1000, Address: "206.10.10.210", Type: "PUBLIC"}, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, count) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockCreateResponse(t, lbID) - - opts := CreateOpts{ - Type: "PUBLIC", - Version: "IPV6", - } - - vip, err := Create(client.ServiceClient(), lbID, opts).Extract() - th.AssertNoErr(t, err) - - expected := &VIP{ - Address: "fd24:f480:ce44:91bc:1af2:15ff:0000:0002", - ID: 9000134, - Type: "PUBLIC", - Version: "IPV6", - } - - th.CheckDeepEquals(t, expected, vip) -} - -func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - ids := []int{vipID, vipID2} - - mockBatchDeleteResponse(t, lbID, ids) - - err := BulkDelete(client.ServiceClient(), lbID, ids).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - mockDeleteResponse(t, lbID, vipID) - - err := Delete(client.ServiceClient(), lbID, vipID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/results.go deleted file mode 100644 index 678b2aff79..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/results.go +++ /dev/null @@ -1,89 +0,0 @@ -package vips - -import ( - "github.com/mitchellh/mapstructure" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/pagination" -) - -// VIP represents a Virtual IP API resource. -type VIP struct { - Address string `json:"address,omitempty"` - ID int `json:"id,omitempty"` - Type Type `json:"type,omitempty"` - Version Version `json:"ipVersion,omitempty" mapstructure:"ipVersion"` -} - -// Version represents the version of a VIP. -type Version string - -// Convenient constants to use for type -const ( - IPV4 Version = "IPV4" - IPV6 Version = "IPV6" -) - -// Type represents the type of a VIP. -type Type string - -const ( - // PUBLIC indicates a VIP type that is routable on the public Internet. - PUBLIC Type = "PUBLIC" - - // PRIVATE indicates a VIP type that is routable only on ServiceNet. - PRIVATE Type = "SERVICENET" -) - -// VIPPage is the page returned by a pager when traversing over a collection -// of VIPs. -type VIPPage struct { - pagination.SinglePageBase -} - -// IsEmpty checks whether a VIPPage struct is empty. -func (p VIPPage) IsEmpty() (bool, error) { - is, err := ExtractVIPs(p) - if err != nil { - return true, nil - } - return len(is) == 0, nil -} - -// ExtractVIPs accepts a Page struct, specifically a VIPPage struct, and -// extracts the elements into a slice of VIP structs. In other words, a -// generic collection is mapped into a relevant slice. -func ExtractVIPs(page pagination.Page) ([]VIP, error) { - var resp struct { - VIPs []VIP `mapstructure:"virtualIps" json:"virtualIps"` - } - - err := mapstructure.Decode(page.(VIPPage).Body, &resp) - - return resp.VIPs, err -} - -type commonResult struct { - gophercloud.Result -} - -func (r commonResult) Extract() (*VIP, error) { - if r.Err != nil { - return nil, r.Err - } - - resp := &VIP{} - err := mapstructure.Decode(r.Body, resp) - - return resp, err -} - -// CreateResult represents the result of a create operation. -type CreateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/urls.go deleted file mode 100644 index 28f063a0f7..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/vips/urls.go +++ /dev/null @@ -1,20 +0,0 @@ -package vips - -import ( - "strconv" - - "github.com/rackspace/gophercloud" -) - -const ( - lbPath = "loadbalancers" - vipPath = "virtualips" -) - -func resourceURL(c *gophercloud.ServiceClient, lbID, nodeID int) string { - return c.ServiceURL(lbPath, strconv.Itoa(lbID), vipPath, strconv.Itoa(nodeID)) -} - -func rootURL(c *gophercloud.ServiceClient, lbID int) string { - return c.ServiceURL(lbPath, strconv.Itoa(lbID), vipPath) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/common/common_tests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/common/common_tests.go deleted file mode 100644 index 129cd63aee..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/common/common_tests.go +++ /dev/null @@ -1,12 +0,0 @@ -package common - -import ( - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/testhelper/client" -) - -const TokenID = client.TokenID - -func ServiceClient() *gophercloud.ServiceClient { - return client.ServiceClient() -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate.go deleted file mode 100644 index dcb0855dba..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate.go +++ /dev/null @@ -1,41 +0,0 @@ -package networks - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" -) - -// List returns a Pager which allows you to iterate over a collection of -// networks. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.List(c, opts) -} - -// Get retrieves a specific network based on its unique ID. -func Get(c *gophercloud.ServiceClient, networkID string) os.GetResult { - return os.Get(c, networkID) -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -// -// The tenant ID that is contained in the URI is the tenant that creates the -// network. An admin user, however, has the option of specifying another tenant -// ID in the CreateOpts struct. -func Create(c *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(c, opts) -} - -// Update accepts a UpdateOpts struct and updates an existing network using the -// values provided. For more information, see the Create function. -func Update(c *gophercloud.ServiceClient, networkID string, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, networkID, opts) -} - -// Delete accepts a unique ID and deletes the network associated with it. -func Delete(c *gophercloud.ServiceClient, networkID string) os.DeleteResult { - return os.Delete(c, networkID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go deleted file mode 100644 index f51c732d43..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go +++ /dev/null @@ -1,276 +0,0 @@ -package networks - -import ( - "fmt" - "net/http" - "testing" - - os "github.com/rackspace/gophercloud/openstack/networking/v2/networks" - "github.com/rackspace/gophercloud/pagination" - fake "github.com/rackspace/gophercloud/rackspace/networking/v2/common" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "networks": [ - { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - }, - { - "status": "ACTIVE", - "subnets": [ - "08eae331-0402-425a-923c-34f7cfe39c1b" - ], - "name": "private", - "admin_state_up": true, - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "shared": true, - "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324" - } - ] -} - `) - }) - - client := fake.ServiceClient() - count := 0 - - List(client, os.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := os.ExtractNetworks(page) - if err != nil { - t.Errorf("Failed to extract networks: %v", err) - return false, err - } - - expected := []os.Network{ - os.Network{ - Status: "ACTIVE", - Subnets: []string{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"}, - Name: "private-network", - AdminStateUp: true, - TenantID: "4fd44f30292945e481c7b8a0c8908869", - Shared: true, - ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - }, - os.Network{ - Status: "ACTIVE", - Subnets: []string{"08eae331-0402-425a-923c-34f7cfe39c1b"}, - Name: "private", - AdminStateUp: true, - TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", - Shared: true, - ID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [ - "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - ], - "name": "private-network", - "admin_state_up": true, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.Subnets, []string{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"}) - th.AssertEquals(t, n.Name, "private-network") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.TenantID, "4fd44f30292945e481c7b8a0c8908869") - th.AssertEquals(t, n.Shared, true) - th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "sample_network", - "admin_state_up": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [], - "name": "net1", - "admin_state_up": true, - "tenant_id": "9bacb3c5d39d41a79512987f338cf177", - "shared": false, - "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - } -} - `) - }) - - iTrue := true - options := os.CreateOpts{Name: "sample_network", AdminStateUp: &iTrue} - n, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertDeepEquals(t, n.Subnets, []string{}) - th.AssertEquals(t, n.Name, "net1") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.TenantID, "9bacb3c5d39d41a79512987f338cf177") - th.AssertEquals(t, n.Shared, false) - th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") -} - -func TestCreateWithOptionalFields(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "sample_network", - "admin_state_up": true, - "shared": true, - "tenant_id": "12345" - } -} - `) - - w.WriteHeader(http.StatusCreated) - }) - - iTrue := true - options := os.CreateOpts{Name: "sample_network", AdminStateUp: &iTrue, Shared: &iTrue, TenantID: "12345"} - _, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "network": { - "name": "new_network_name", - "admin_state_up": false, - "shared": true - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "network": { - "status": "ACTIVE", - "subnets": [], - "name": "new_network_name", - "admin_state_up": false, - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "shared": true, - "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - } -} - `) - }) - - iTrue := true - options := os.UpdateOpts{Name: "new_network_name", AdminStateUp: os.Down, Shared: &iTrue} - n, err := Update(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Name, "new_network_name") - th.AssertEquals(t, n.AdminStateUp, false) - th.AssertEquals(t, n.Shared, true) - th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/ports/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/ports/delegate.go deleted file mode 100644 index 091b99e0f4..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/ports/delegate.go +++ /dev/null @@ -1,40 +0,0 @@ -package ports - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/networking/v2/ports" - "github.com/rackspace/gophercloud/pagination" -) - -// List returns a Pager which allows you to iterate over a collection of -// ports. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those ports that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.List(c, opts) -} - -// Get retrieves a specific port based on its unique ID. -func Get(c *gophercloud.ServiceClient, networkID string) os.GetResult { - return os.Get(c, networkID) -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. You must remember to provide a NetworkID value. -func Create(c *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(c, opts) -} - -// Update accepts a UpdateOpts struct and updates an existing port using the -// values provided. -func Update(c *gophercloud.ServiceClient, networkID string, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, networkID, opts) -} - -// Delete accepts a unique ID and deletes the port associated with it. -func Delete(c *gophercloud.ServiceClient, networkID string) os.DeleteResult { - return os.Delete(c, networkID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/ports/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/ports/delegate_test.go deleted file mode 100644 index f53ff595a0..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/ports/delegate_test.go +++ /dev/null @@ -1,322 +0,0 @@ -package ports - -import ( - "fmt" - "net/http" - "testing" - - os "github.com/rackspace/gophercloud/openstack/networking/v2/ports" - "github.com/rackspace/gophercloud/pagination" - fake "github.com/rackspace/gophercloud/rackspace/networking/v2/common" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ports", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "ports": [ - { - "status": "ACTIVE", - "binding:host_id": "devstack", - "name": "", - "admin_state_up": true, - "network_id": "70c1db1f-b701-45bd-96e0-a313ee3430b3", - "tenant_id": "", - "device_owner": "network:router_gateway", - "mac_address": "fa:16:3e:58:42:ed", - "fixed_ips": [ - { - "subnet_id": "008ba151-0b8c-4a67-98b5-0d2b87666062", - "ip_address": "172.24.4.2" - } - ], - "id": "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b", - "security_groups": [], - "device_id": "9ae135f4-b6e0-4dad-9e91-3c223e385824" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), os.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := os.ExtractPorts(page) - if err != nil { - t.Errorf("Failed to extract subnets: %v", err) - return false, nil - } - - expected := []os.Port{ - os.Port{ - Status: "ACTIVE", - Name: "", - AdminStateUp: true, - NetworkID: "70c1db1f-b701-45bd-96e0-a313ee3430b3", - TenantID: "", - DeviceOwner: "network:router_gateway", - MACAddress: "fa:16:3e:58:42:ed", - FixedIPs: []os.IP{ - os.IP{ - SubnetID: "008ba151-0b8c-4a67-98b5-0d2b87666062", - IPAddress: "172.24.4.2", - }, - }, - ID: "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b", - SecurityGroups: []string{}, - DeviceID: "9ae135f4-b6e0-4dad-9e91-3c223e385824", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "port": { - "status": "ACTIVE", - "name": "", - "admin_state_up": true, - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "tenant_id": "7e02058126cc4950b75f9970368ba177", - "device_owner": "network:router_interface", - "mac_address": "fa:16:3e:23:fd:d7", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.1" - } - ], - "id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", - "security_groups": [], - "device_id": "5e3898d7-11be-483e-9732-b2f5eccd2b2e" - } -} - `) - }) - - n, err := Get(fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertEquals(t, n.Name, "") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") - th.AssertEquals(t, n.TenantID, "7e02058126cc4950b75f9970368ba177") - th.AssertEquals(t, n.DeviceOwner, "network:router_interface") - th.AssertEquals(t, n.MACAddress, "fa:16:3e:23:fd:d7") - th.AssertDeepEquals(t, n.FixedIPs, []os.IP{ - os.IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.1"}, - }) - th.AssertEquals(t, n.ID, "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2") - th.AssertDeepEquals(t, n.SecurityGroups, []string{}) - th.AssertEquals(t, n.Status, "ACTIVE") - th.AssertEquals(t, n.DeviceID, "5e3898d7-11be-483e-9732-b2f5eccd2b2e") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ports", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "port": { - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "name": "private-port", - "admin_state_up": true, - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.2" - } - ], - "security_groups": ["foo"] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "port": { - "status": "DOWN", - "name": "private-port", - "allowed_address_pairs": [], - "admin_state_up": true, - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", - "device_owner": "", - "mac_address": "fa:16:3e:c9:cb:f0", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.2" - } - ], - "id": "65c0ee9f-d634-4522-8954-51021b570b0d", - "security_groups": [ - "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ], - "device_id": "" - } -} - `) - }) - - asu := true - options := os.CreateOpts{ - Name: "private-port", - AdminStateUp: &asu, - NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7", - FixedIPs: []os.IP{ - os.IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, - }, - SecurityGroups: []string{"foo"}, - } - n, err := Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, n.Status, "DOWN") - th.AssertEquals(t, n.Name, "private-port") - th.AssertEquals(t, n.AdminStateUp, true) - th.AssertEquals(t, n.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7") - th.AssertEquals(t, n.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa") - th.AssertEquals(t, n.DeviceOwner, "") - th.AssertEquals(t, n.MACAddress, "fa:16:3e:c9:cb:f0") - th.AssertDeepEquals(t, n.FixedIPs, []os.IP{ - os.IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, - }) - th.AssertEquals(t, n.ID, "65c0ee9f-d634-4522-8954-51021b570b0d") - th.AssertDeepEquals(t, n.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}) -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), os.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "port": { - "name": "new_port_name", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.3" - } - ], - "security_groups": [ - "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "port": { - "status": "DOWN", - "name": "new_port_name", - "admin_state_up": true, - "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7", - "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", - "device_owner": "", - "mac_address": "fa:16:3e:c9:cb:f0", - "fixed_ips": [ - { - "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2", - "ip_address": "10.0.0.3" - } - ], - "id": "65c0ee9f-d634-4522-8954-51021b570b0d", - "security_groups": [ - "f0ac4394-7e4a-4409-9701-ba8be283dbc3" - ], - "device_id": "" - } -} - `) - }) - - options := os.UpdateOpts{ - Name: "new_port_name", - FixedIPs: []os.IP{ - os.IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"}, - }, - SecurityGroups: []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}, - } - - s, err := Update(fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "new_port_name") - th.AssertDeepEquals(t, s.FixedIPs, []os.IP{ - os.IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"}, - }) - th.AssertDeepEquals(t, s.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"}) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/subnets/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/subnets/delegate.go deleted file mode 100644 index a7fb7bb15f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/subnets/delegate.go +++ /dev/null @@ -1,40 +0,0 @@ -package subnets - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" -) - -// List returns a Pager which allows you to iterate over a collection of -// subnets. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those subnets that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.List(c, opts) -} - -// Get retrieves a specific subnet based on its unique ID. -func Get(c *gophercloud.ServiceClient, networkID string) os.GetResult { - return os.Get(c, networkID) -} - -// Create accepts a CreateOpts struct and creates a new subnet using the values -// provided. You must remember to provide a valid NetworkID, CIDR and IP version. -func Create(c *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(c, opts) -} - -// Update accepts a UpdateOpts struct and updates an existing subnet using the -// values provided. -func Update(c *gophercloud.ServiceClient, networkID string, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, networkID, opts) -} - -// Delete accepts a unique ID and deletes the subnet associated with it. -func Delete(c *gophercloud.ServiceClient, networkID string) os.DeleteResult { - return os.Delete(c, networkID) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/subnets/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/subnets/delegate_test.go deleted file mode 100644 index fafc6fb302..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/subnets/delegate_test.go +++ /dev/null @@ -1,363 +0,0 @@ -package subnets - -import ( - "fmt" - "net/http" - "testing" - - os "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" - "github.com/rackspace/gophercloud/pagination" - fake "github.com/rackspace/gophercloud/rackspace/networking/v2/common" - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/subnets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "subnets": [ - { - "name": "private-subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - }, - { - "name": "my_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.0.0.2", - "end": "192.255.255.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.0.0.1", - "cidr": "192.0.0.0/8", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - } - ] -} - `) - }) - - count := 0 - - List(fake.ServiceClient(), os.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := os.ExtractSubnets(page) - if err != nil { - t.Errorf("Failed to extract subnets: %v", err) - return false, nil - } - - expected := []os.Subnet{ - os.Subnet{ - Name: "private-subnet", - EnableDHCP: true, - NetworkID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e", - DNSNameservers: []string{}, - AllocationPools: []os.AllocationPool{ - os.AllocationPool{ - Start: "10.0.0.2", - End: "10.0.0.254", - }, - }, - HostRoutes: []os.HostRoute{}, - IPVersion: 4, - GatewayIP: "10.0.0.1", - CIDR: "10.0.0.0/24", - ID: "08eae331-0402-425a-923c-34f7cfe39c1b", - }, - os.Subnet{ - Name: "my_subnet", - EnableDHCP: true, - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - TenantID: "4fd44f30292945e481c7b8a0c8908869", - DNSNameservers: []string{}, - AllocationPools: []os.AllocationPool{ - os.AllocationPool{ - Start: "192.0.0.2", - End: "192.255.255.254", - }, - }, - HostRoutes: []os.HostRoute{}, - IPVersion: 4, - GatewayIP: "192.0.0.1", - CIDR: "192.0.0.0/8", - ID: "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", - }, - } - - th.CheckDeepEquals(t, expected, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/subnets/54d6f61d-db07-451c-9ab3-b9609b6b6f0b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ` -{ - "subnet": { - "name": "my_subnet", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.0.0.2", - "end": "192.255.255.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.0.0.1", - "cidr": "192.0.0.0/8", - "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b" - } -} - `) - }) - - s, err := Get(fake.ServiceClient(), "54d6f61d-db07-451c-9ab3-b9609b6b6f0b").Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "my_subnet") - th.AssertEquals(t, s.EnableDHCP, true) - th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") - th.AssertDeepEquals(t, s.DNSNameservers, []string{}) - th.AssertDeepEquals(t, s.AllocationPools, []os.AllocationPool{ - os.AllocationPool{ - Start: "192.0.0.2", - End: "192.255.255.254", - }, - }) - th.AssertDeepEquals(t, s.HostRoutes, []os.HostRoute{}) - th.AssertEquals(t, s.IPVersion, 4) - th.AssertEquals(t, s.GatewayIP, "192.0.0.1") - th.AssertEquals(t, s.CIDR, "192.0.0.0/8") - th.AssertEquals(t, s.ID, "54d6f61d-db07-451c-9ab3-b9609b6b6f0b") -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/subnets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "subnet": { - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "ip_version": 4, - "cidr": "192.168.199.0/24", - "dns_nameservers": ["foo"], - "allocation_pools": [ - { - "start": "192.168.199.2", - "end": "192.168.199.254" - } - ], - "host_routes": [{"destination":"","nexthop": "bar"}] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "subnet": { - "name": "", - "enable_dhcp": true, - "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "tenant_id": "4fd44f30292945e481c7b8a0c8908869", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "192.168.199.2", - "end": "192.168.199.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "192.168.199.1", - "cidr": "192.168.199.0/24", - "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126" - } -} - `) - }) - - opts := os.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - IPVersion: 4, - CIDR: "192.168.199.0/24", - AllocationPools: []os.AllocationPool{ - os.AllocationPool{ - Start: "192.168.199.2", - End: "192.168.199.254", - }, - }, - DNSNameservers: []string{"foo"}, - HostRoutes: []os.HostRoute{ - os.HostRoute{NextHop: "bar"}, - }, - } - s, err := Create(fake.ServiceClient(), opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "") - th.AssertEquals(t, s.EnableDHCP, true) - th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869") - th.AssertDeepEquals(t, s.DNSNameservers, []string{}) - th.AssertDeepEquals(t, s.AllocationPools, []os.AllocationPool{ - os.AllocationPool{ - Start: "192.168.199.2", - End: "192.168.199.254", - }, - }) - th.AssertDeepEquals(t, s.HostRoutes, []os.HostRoute{}) - th.AssertEquals(t, s.IPVersion, 4) - th.AssertEquals(t, s.GatewayIP, "192.168.199.1") - th.AssertEquals(t, s.CIDR, "192.168.199.0/24") - th.AssertEquals(t, s.ID, "3b80198d-4f7b-4f77-9ef5-774d54e17126") -} - -func TestRequiredCreateOpts(t *testing.T) { - res := Create(fake.ServiceClient(), os.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - - res = Create(fake.ServiceClient(), os.CreateOpts{NetworkID: "foo"}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } - - res = Create(fake.ServiceClient(), os.CreateOpts{NetworkID: "foo", CIDR: "bar", IPVersion: 40}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ` -{ - "subnet": { - "name": "my_new_subnet", - "dns_nameservers": ["foo"], - "host_routes": [{"destination":"","nexthop": "bar"}] - } -} - `) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, ` -{ - "subnet": { - "name": "my_new_subnet", - "enable_dhcp": true, - "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324", - "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e", - "dns_nameservers": [], - "allocation_pools": [ - { - "start": "10.0.0.2", - "end": "10.0.0.254" - } - ], - "host_routes": [], - "ip_version": 4, - "gateway_ip": "10.0.0.1", - "cidr": "10.0.0.0/24", - "id": "08eae331-0402-425a-923c-34f7cfe39c1b" - } -} - `) - }) - - opts := os.UpdateOpts{ - Name: "my_new_subnet", - DNSNameservers: []string{"foo"}, - HostRoutes: []os.HostRoute{ - os.HostRoute{NextHop: "bar"}, - }, - } - s, err := Update(fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b", opts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "my_new_subnet") - th.AssertEquals(t, s.ID, "08eae331-0402-425a-923c-34f7cfe39c1b") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/subnets/08eae331-0402-425a-923c-34f7cfe39c1b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := Delete(fake.ServiceClient(), "08eae331-0402-425a-923c-34f7cfe39c1b") - th.AssertNoErr(t, res.Err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/delegate.go deleted file mode 100644 index 94739308fa..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/delegate.go +++ /dev/null @@ -1,39 +0,0 @@ -package accounts - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts" -) - -// Get is a function that retrieves an account's metadata. To extract just the -// custom metadata, call the ExtractMetadata method on the GetResult. To extract -// all the headers that are returned (including the metadata), call the -// ExtractHeader method on the GetResult. -func Get(c *gophercloud.ServiceClient) os.GetResult { - return os.Get(c, nil) -} - -// UpdateOpts is a structure that contains parameters for updating, creating, or -// deleting an account's metadata. -type UpdateOpts struct { - Metadata map[string]string - TempURLKey string `h:"X-Account-Meta-Temp-URL-Key"` - TempURLKey2 string `h:"X-Account-Meta-Temp-URL-Key-2"` -} - -// ToAccountUpdateMap formats an UpdateOpts into a map[string]string of headers. -func (opts UpdateOpts) ToAccountUpdateMap() (map[string]string, error) { - headers, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - headers["X-Account-Meta-"+k] = v - } - return headers, err -} - -// Update will update an account's metadata with the Metadata in the UpdateOptsBuilder. -func Update(c *gophercloud.ServiceClient, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, opts) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/delegate_test.go deleted file mode 100644 index c568bd6e3b..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/delegate_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package accounts - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestGetAccounts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleGetAccountSuccessfully(t) - - options := &UpdateOpts{Metadata: map[string]string{"gophercloud-test": "accounts"}} - res := Update(fake.ServiceClient(), options) - th.CheckNoErr(t, res.Err) -} - -func TestUpdateAccounts(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleUpdateAccountSuccessfully(t) - - expected := map[string]string{"Foo": "bar"} - actual, err := Get(fake.ServiceClient()).ExtractMetadata() - th.CheckNoErr(t, err) - th.CheckDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/doc.go deleted file mode 100644 index 293a93088a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/accounts/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package accounts provides information and interaction with the account -// API resource for the Rackspace Cloud Files service. -package accounts diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/doc.go deleted file mode 100644 index 9c89e22b21..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package bulk provides functionality for working with bulk operations in the -// Rackspace Cloud Files service. -package bulk diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go deleted file mode 100644 index d252609d41..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go +++ /dev/null @@ -1,51 +0,0 @@ -package bulk - -import ( - "net/url" - "strings" - - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -// DeleteOptsBuilder allows extensions to add additional parameters to the -// Delete request. -type DeleteOptsBuilder interface { - ToBulkDeleteBody() (string, error) -} - -// DeleteOpts is a structure that holds parameters for deleting an object. -type DeleteOpts []string - -// ToBulkDeleteBody formats a DeleteOpts into a request body. -func (opts DeleteOpts) ToBulkDeleteBody() (string, error) { - return url.QueryEscape(strings.Join(opts, "\n")), nil -} - -// Delete will delete objects or containers in bulk. -func Delete(c *gophercloud.ServiceClient, opts DeleteOptsBuilder) DeleteResult { - var res DeleteResult - - if opts == nil { - return res - } - - reqString, err := opts.ToBulkDeleteBody() - if err != nil { - res.Err = err - return res - } - - reqBody := strings.NewReader(reqString) - - resp, err := perigee.Request("DELETE", deleteURL(c), perigee.Options{ - ContentType: "text/plain", - MoreHeaders: c.AuthenticatedHeaders(), - OkCodes: []int{200}, - ReqBody: reqBody, - Results: &res.Body, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests_test.go deleted file mode 100644 index 8b5578e91e..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package bulk - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestBulkDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.AssertEquals(t, r.URL.RawQuery, "bulk-delete") - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ` - { - "Number Not Found": 1, - "Response Status": "200 OK", - "Errors": [], - "Number Deleted": 1, - "Response Body": "" - } - `) - }) - - options := DeleteOpts{"gophercloud-testcontainer1", "gophercloud-testcontainer2"} - actual, err := Delete(fake.ServiceClient(), options).ExtractBody() - th.AssertNoErr(t, err) - th.AssertEquals(t, actual.NumberDeleted, 1) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/results.go deleted file mode 100644 index fddc125ac6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/results.go +++ /dev/null @@ -1,28 +0,0 @@ -package bulk - -import ( - "github.com/rackspace/gophercloud" - - "github.com/mitchellh/mapstructure" -) - -// DeleteResult represents the result of a bulk delete operation. -type DeleteResult struct { - gophercloud.Result -} - -// DeleteRespBody is the form of the response body returned by a bulk delete request. -type DeleteRespBody struct { - NumberNotFound int `mapstructure:"Number Not Found"` - ResponseStatus string `mapstructure:"Response Status"` - Errors []string `mapstructure:"Errors"` - NumberDeleted int `mapstructure:"Number Deleted"` - ResponseBody string `mapstructure:"Response Body"` -} - -// ExtractBody will extract the body returned by the bulk extract request. -func (dr DeleteResult) ExtractBody() (DeleteRespBody, error) { - var resp DeleteRespBody - err := mapstructure.Decode(dr.Body, &resp) - return resp, err -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/urls.go deleted file mode 100644 index 2e112033be..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package bulk - -import "github.com/rackspace/gophercloud" - -func deleteURL(c *gophercloud.ServiceClient) string { - return c.Endpoint + "?bulk-delete" -} - -func extractURL(c *gophercloud.ServiceClient, ext string) string { - return c.Endpoint + "?extract-archive=" + ext -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/urls_test.go deleted file mode 100644 index 9169e52f16..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/urls_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package bulk - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestDeleteURL(t *testing.T) { - actual := deleteURL(endpointClient()) - expected := endpoint + "?bulk-delete" - th.CheckEquals(t, expected, actual) -} - -func TestExtractURL(t *testing.T) { - actual := extractURL(endpointClient(), "tar") - expected := endpoint + "?extract-archive=tar" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/delegate.go deleted file mode 100644 index d7eef20255..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/delegate.go +++ /dev/null @@ -1,71 +0,0 @@ -package cdncontainers - -import ( - "strconv" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtractNames interprets a page of List results when just the container -// names are requested. -func ExtractNames(page pagination.Page) ([]string, error) { - return os.ExtractNames(page) -} - -// ListOpts are options for listing Rackspace CDN containers. -type ListOpts struct { - EndMarker string `q:"end_marker"` - Format string `q:"format"` - Limit int `q:"limit"` - Marker string `q:"marker"` -} - -// ToContainerListParams formats a ListOpts into a query string and boolean -// representing whether to list complete information for each container. -func (opts ListOpts) ToContainerListParams() (bool, string, error) { - q, err := gophercloud.BuildQueryString(opts) - if err != nil { - return false, "", err - } - return false, q.String(), nil -} - -// List is a function that retrieves containers associated with the account as -// well as account metadata. It returns a pager which can be iterated with the -// EachPage function. -func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.List(c, opts) -} - -// Get is a function that retrieves the metadata of a container. To extract just -// the custom metadata, pass the GetResult response to the ExtractMetadata -// function. -func Get(c *gophercloud.ServiceClient, containerName string) os.GetResult { - return os.Get(c, containerName) -} - -// UpdateOpts is a structure that holds parameters for updating, creating, or -// deleting a container's metadata. -type UpdateOpts struct { - CDNEnabled bool `h:"X-Cdn-Enabled"` - LogRetention bool `h:"X-Log-Retention"` - TTL int `h:"X-Ttl"` -} - -// ToContainerUpdateMap formats a CreateOpts into a map of headers. -func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - h["X-Cdn-Enabled"] = strconv.FormatBool(opts.CDNEnabled) - return h, nil -} - -// Update is a function that creates, updates, or deletes a container's -// metadata. -func Update(c *gophercloud.ServiceClient, containerName string, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, containerName, opts) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/delegate_test.go deleted file mode 100644 index 02c3c5e150..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/delegate_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package cdncontainers - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListCDNContainers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListContainerNamesSuccessfully(t) - - count := 0 - err := List(fake.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNames(page) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, os.ExpectedListNames, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestGetCDNContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleGetContainerSuccessfully(t) - - _, err := Get(fake.ServiceClient(), "testContainer").ExtractMetadata() - th.CheckNoErr(t, err) - -} - -func TestUpdateCDNContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleUpdateContainerSuccessfully(t) - - options := &UpdateOpts{TTL: 3600} - res := Update(fake.ServiceClient(), "testContainer", options) - th.CheckNoErr(t, res.Err) - -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/doc.go deleted file mode 100644 index 7b0930eeea..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package cdncontainers provides information and interaction with the CDN -// Container API resource for the Rackspace Cloud Files service. -package cdncontainers diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go deleted file mode 100644 index 0567833204..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go +++ /dev/null @@ -1,58 +0,0 @@ -package cdncontainers - -import ( - "github.com/racker/perigee" - "github.com/rackspace/gophercloud" -) - -// EnableOptsBuilder allows extensions to add additional parameters to the Enable -// request. -type EnableOptsBuilder interface { - ToCDNContainerEnableMap() (map[string]string, error) -} - -// EnableOpts is a structure that holds options for enabling a CDN container. -type EnableOpts struct { - // CDNEnabled indicates whether or not the container is CDN enabled. Set to - // `true` to enable the container. Note that changing this setting from true - // to false will disable the container in the CDN but only after the TTL has - // expired. - CDNEnabled bool `h:"X-Cdn-Enabled"` - // TTL is the time-to-live for the container (in seconds). - TTL int `h:"X-Ttl"` -} - -// ToCDNContainerEnableMap formats an EnableOpts into a map of headers. -func (opts EnableOpts) ToCDNContainerEnableMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - return h, nil -} - -// Enable is a function that enables/disables a CDN container. -func Enable(c *gophercloud.ServiceClient, containerName string, opts EnableOptsBuilder) EnableResult { - var res EnableResult - h := c.AuthenticatedHeaders() - - if opts != nil { - headers, err := opts.ToCDNContainerEnableMap() - if err != nil { - res.Err = err - return res - } - - for k, v := range headers { - h[k] = v - } - } - - resp, err := perigee.Request("PUT", enableURL(c, containerName), perigee.Options{ - MoreHeaders: h, - OkCodes: []int{201, 202, 204}, - }) - res.Header = resp.HttpResponse.Header - res.Err = err - return res -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests_test.go deleted file mode 100644 index 28b963dace..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package cdncontainers - -import ( - "net/http" - "testing" - - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestEnableCDNContainer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Accept", "application/json") - - w.Header().Add("X-Ttl", "259200") - w.Header().Add("X-Cdn-Enabled", "True") - w.WriteHeader(http.StatusNoContent) - }) - - options := &EnableOpts{CDNEnabled: true, TTL: 259200} - actual := Enable(fake.ServiceClient(), "testContainer", options) - th.AssertNoErr(t, actual.Err) - th.CheckEquals(t, actual.Header["X-Ttl"][0], "259200") - th.CheckEquals(t, actual.Header["X-Cdn-Enabled"][0], "True") -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/results.go deleted file mode 100644 index a5097ca7f6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/results.go +++ /dev/null @@ -1,8 +0,0 @@ -package cdncontainers - -import "github.com/rackspace/gophercloud" - -// EnableResult represents the result of a get operation. -type EnableResult struct { - gophercloud.HeaderResult -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/urls.go deleted file mode 100644 index 80653f2762..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package cdncontainers - -import "github.com/rackspace/gophercloud" - -func enableURL(c *gophercloud.ServiceClient, containerName string) string { - return c.ServiceURL(containerName) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/urls_test.go deleted file mode 100644 index aa5bfe68b2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/urls_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package cdncontainers - -import ( - "testing" - - "github.com/rackspace/gophercloud" - th "github.com/rackspace/gophercloud/testhelper" -) - -const endpoint = "http://localhost:57909/" - -func endpointClient() *gophercloud.ServiceClient { - return &gophercloud.ServiceClient{Endpoint: endpoint} -} - -func TestEnableURL(t *testing.T) { - actual := enableURL(endpointClient(), "foo") - expected := endpoint + "foo" - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/delegate.go deleted file mode 100644 index e9d2ff1d6f..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/delegate.go +++ /dev/null @@ -1,11 +0,0 @@ -package cdnobjects - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" -) - -// Delete is a function that deletes an object from the CDN. -func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts os.DeleteOptsBuilder) os.DeleteResult { - return os.Delete(c, containerName, objectName, nil) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/delegate_test.go deleted file mode 100644 index b5e04a98c3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/delegate_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package cdnobjects - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestDeleteCDNObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleDeleteObjectSuccessfully(t) - - res := Delete(fake.ServiceClient(), "testContainer", "testObject", nil) - th.AssertNoErr(t, res.Err) - -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/doc.go deleted file mode 100644 index 90cd5c97ff..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdnobjects/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package cdnobjects provides information and interaction with the CDN -// Object API resource for the Rackspace Cloud Files service. -package cdnobjects diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/delegate.go deleted file mode 100644 index 77ed002574..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/delegate.go +++ /dev/null @@ -1,93 +0,0 @@ -package containers - -import ( - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtractInfo interprets a page of List results when full container info -// is requested. -func ExtractInfo(page pagination.Page) ([]os.Container, error) { - return os.ExtractInfo(page) -} - -// ExtractNames interprets a page of List results when just the container -// names are requested. -func ExtractNames(page pagination.Page) ([]string, error) { - return os.ExtractNames(page) -} - -// List is a function that retrieves containers associated with the account as -// well as account metadata. It returns a pager which can be iterated with the -// EachPage function. -func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager { - return os.List(c, opts) -} - -// CreateOpts is a structure that holds parameters for creating a container. -type CreateOpts struct { - Metadata map[string]string - ContainerRead string `h:"X-Container-Read"` - ContainerWrite string `h:"X-Container-Write"` - VersionsLocation string `h:"X-Versions-Location"` -} - -// ToContainerCreateMap formats a CreateOpts into a map of headers. -func (opts CreateOpts) ToContainerCreateMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Container-Meta-"+k] = v - } - return h, nil -} - -// Create is a function that creates a new container. -func Create(c *gophercloud.ServiceClient, containerName string, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(c, containerName, opts) -} - -// Delete is a function that deletes a container. -func Delete(c *gophercloud.ServiceClient, containerName string) os.DeleteResult { - return os.Delete(c, containerName) -} - -// UpdateOpts is a structure that holds parameters for updating or creating a -// container's metadata. -type UpdateOpts struct { - Metadata map[string]string - ContainerRead string `h:"X-Container-Read"` - ContainerWrite string `h:"X-Container-Write"` - ContentType string `h:"Content-Type"` - DetectContentType bool `h:"X-Detect-Content-Type"` - RemoveVersionsLocation string `h:"X-Remove-Versions-Location"` - VersionsLocation string `h:"X-Versions-Location"` -} - -// ToContainerUpdateMap formats a CreateOpts into a map of headers. -func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Container-Meta-"+k] = v - } - return h, nil -} - -// Update is a function that creates, updates, or deletes a container's -// metadata. -func Update(c *gophercloud.ServiceClient, containerName string, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, containerName, opts) -} - -// Get is a function that retrieves the metadata of a container. To extract just -// the custom metadata, pass the GetResult response to the ExtractMetadata -// function. -func Get(c *gophercloud.ServiceClient, containerName string) os.GetResult { - return os.Get(c, containerName) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/delegate_test.go deleted file mode 100644 index 7ba4eb21c6..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/delegate_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package containers - -import ( - "testing" - - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestListContainerInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListContainerInfoSuccessfully(t) - - count := 0 - err := List(fake.ServiceClient(), &os.ListOpts{Full: true}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractInfo(page) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, os.ExpectedListInfo, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestListContainerNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListContainerNamesSuccessfully(t) - - count := 0 - err := List(fake.ServiceClient(), &os.ListOpts{Full: false}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNames(page) - if err != nil { - t.Errorf("Failed to extract container names: %v", err) - return false, err - } - - th.CheckDeepEquals(t, os.ExpectedListNames, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestCreateContainers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleCreateContainerSuccessfully(t) - - options := os.CreateOpts{ContentType: "application/json", Metadata: map[string]string{"foo": "bar"}} - res := Create(fake.ServiceClient(), "testContainer", options) - th.CheckNoErr(t, res.Err) - th.CheckEquals(t, "bar", res.Header["X-Container-Meta-Foo"][0]) - -} - -func TestDeleteContainers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleDeleteContainerSuccessfully(t) - - res := Delete(fake.ServiceClient(), "testContainer") - th.CheckNoErr(t, res.Err) -} - -func TestUpdateContainers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleUpdateContainerSuccessfully(t) - - options := &os.UpdateOpts{Metadata: map[string]string{"foo": "bar"}} - res := Update(fake.ServiceClient(), "testContainer", options) - th.CheckNoErr(t, res.Err) -} - -func TestGetContainers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleGetContainerSuccessfully(t) - - _, err := Get(fake.ServiceClient(), "testContainer").ExtractMetadata() - th.CheckNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/doc.go deleted file mode 100644 index d132a07382..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/containers/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package containers provides information and interaction with the Container -// API resource for the Rackspace Cloud Files service. -package containers diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go deleted file mode 100644 index bd4a4f0835..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go +++ /dev/null @@ -1,90 +0,0 @@ -package objects - -import ( - "io" - - "github.com/rackspace/gophercloud" - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" - "github.com/rackspace/gophercloud/pagination" -) - -// ExtractInfo is a function that takes a page of objects and returns their full information. -func ExtractInfo(page pagination.Page) ([]os.Object, error) { - return os.ExtractInfo(page) -} - -// ExtractNames is a function that takes a page of objects and returns only their names. -func ExtractNames(page pagination.Page) ([]string, error) { - return os.ExtractNames(page) -} - -// List is a function that retrieves objects in the container as -// well as container metadata. It returns a pager which can be iterated with the -// EachPage function. -func List(c *gophercloud.ServiceClient, containerName string, opts os.ListOptsBuilder) pagination.Pager { - return os.List(c, containerName, opts) -} - -// Download is a function that retrieves the content and metadata for an object. -// To extract just the content, pass the DownloadResult response to the -// ExtractContent function. -func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts os.DownloadOptsBuilder) os.DownloadResult { - return os.Download(c, containerName, objectName, opts) -} - -// Create is a function that creates a new object or replaces an existing object. -func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts os.CreateOptsBuilder) os.CreateResult { - return os.Create(c, containerName, objectName, content, opts) -} - -// CopyOpts is a structure that holds parameters for copying one object to -// another. -type CopyOpts struct { - Metadata map[string]string - ContentDisposition string `h:"Content-Disposition"` - ContentEncoding string `h:"Content-Encoding"` - ContentLength int `h:"Content-Length"` - ContentType string `h:"Content-Type"` - CopyFrom string `h:"X-Copy_From"` - Destination string `h:"Destination"` - DetectContentType bool `h:"X-Detect-Content-Type"` -} - -// ToObjectCopyMap formats a CopyOpts into a map of headers. -func (opts CopyOpts) ToObjectCopyMap() (map[string]string, error) { - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - return nil, err - } - for k, v := range opts.Metadata { - h["X-Object-Meta-"+k] = v - } - // `Content-Length` is required and a value of "0" is acceptable, but calling `gophercloud.BuildHeaders` - // will remove the `Content-Length` header if it's set to 0 (or equivalently not set). This will add - // the header if it's not already set. - if _, ok := h["Content-Length"]; !ok { - h["Content-Length"] = "0" - } - return h, nil -} - -// Copy is a function that copies one object to another. -func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts os.CopyOptsBuilder) os.CopyResult { - return os.Copy(c, containerName, objectName, opts) -} - -// Delete is a function that deletes an object. -func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts os.DeleteOptsBuilder) os.DeleteResult { - return os.Delete(c, containerName, objectName, opts) -} - -// Get is a function that retrieves the metadata of an object. To extract just the custom -// metadata, pass the GetResult response to the ExtractMetadata function. -func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts os.GetOptsBuilder) os.GetResult { - return os.Get(c, containerName, objectName, opts) -} - -// Update is a function that creates, updates, or deletes an object's metadata. -func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts os.UpdateOptsBuilder) os.UpdateResult { - return os.Update(c, containerName, objectName, opts) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go deleted file mode 100644 index 08831ec56a..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package objects - -import ( - "bytes" - "testing" - - os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" - "github.com/rackspace/gophercloud/pagination" - th "github.com/rackspace/gophercloud/testhelper" - fake "github.com/rackspace/gophercloud/testhelper/client" -) - -func TestDownloadObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleDownloadObjectSuccessfully(t) - - content, err := Download(fake.ServiceClient(), "testContainer", "testObject", nil).ExtractContent() - th.AssertNoErr(t, err) - th.CheckEquals(t, string(content), "Successful download with Gophercloud") -} - -func TestListObjectsInfo(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListObjectsInfoSuccessfully(t) - - count := 0 - options := &os.ListOpts{Full: true} - err := List(fake.ServiceClient(), "testContainer", options).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractInfo(page) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, os.ExpectedListInfo, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestListObjectNames(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleListObjectNamesSuccessfully(t) - - count := 0 - options := &os.ListOpts{Full: false} - err := List(fake.ServiceClient(), "testContainer", options).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ExtractNames(page) - if err != nil { - t.Errorf("Failed to extract container names: %v", err) - return false, err - } - - th.CheckDeepEquals(t, os.ExpectedListNames, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, count, 1) -} - -func TestCreateObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleCreateObjectSuccessfully(t) - - content := bytes.NewBufferString("Did gyre and gimble in the wabe") - options := &os.CreateOpts{ContentType: "application/json"} - res := Create(fake.ServiceClient(), "testContainer", "testObject", content, options) - th.AssertNoErr(t, res.Err) -} - -func TestCopyObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleCopyObjectSuccessfully(t) - - options := &CopyOpts{Destination: "/newTestContainer/newTestObject"} - res := Copy(fake.ServiceClient(), "testContainer", "testObject", options) - th.AssertNoErr(t, res.Err) -} - -func TestDeleteObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleDeleteObjectSuccessfully(t) - - res := Delete(fake.ServiceClient(), "testContainer", "testObject", nil) - th.AssertNoErr(t, res.Err) -} - -func TestUpdateObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleUpdateObjectSuccessfully(t) - - options := &os.UpdateOpts{Metadata: map[string]string{"Gophercloud-Test": "objects"}} - res := Update(fake.ServiceClient(), "testContainer", "testObject", options) - th.AssertNoErr(t, res.Err) -} - -func TestGetObject(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - os.HandleGetObjectSuccessfully(t) - - expected := map[string]string{"Gophercloud-Test": "objects"} - actual, err := Get(fake.ServiceClient(), "testContainer", "testObject", nil).ExtractMetadata() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/doc.go deleted file mode 100644 index 781984bee2..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package objects provides information and interaction with the Object -// API resource for the Rackspace Cloud Files service. -package objects diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go deleted file mode 100644 index 3fd50296f3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go +++ /dev/null @@ -1,122 +0,0 @@ -package gophercloud - -import ( - "encoding/json" - "net/http" -) - -/* -Result is an internal type to be used by individual resource packages, but its -methods will be available on a wide variety of user-facing embedding types. - -It acts as a base struct that other Result types, returned from request -functions, can embed for convenience. All Results capture basic information -from the HTTP transaction that was performed, including the response body, -HTTP headers, and any errors that happened. - -Generally, each Result type will have an Extract method that can be used to -further interpret the result's payload in a specific context. Extensions or -providers can then provide additional extraction functions to pull out -provider- or extension-specific information as well. -*/ -type Result struct { - // Body is the payload of the HTTP response from the server. In most cases, - // this will be the deserialized JSON structure. - Body interface{} - - // Header contains the HTTP header structure from the original response. - Header http.Header - - // Err is an error that occurred during the operation. It's deferred until - // extraction to make it easier to chain the Extract call. - Err error -} - -// PrettyPrintJSON creates a string containing the full response body as -// pretty-printed JSON. It's useful for capturing test fixtures and for -// debugging extraction bugs. If you include its output in an issue related to -// a buggy extraction function, we will all love you forever. -func (r Result) PrettyPrintJSON() string { - pretty, err := json.MarshalIndent(r.Body, "", " ") - if err != nil { - panic(err.Error()) - } - return string(pretty) -} - -// ErrResult is an internal type to be used by individual resource packages, but -// its methods will be available on a wide variety of user-facing embedding -// types. -// -// It represents results that only contain a potential error and -// nothing else. Usually, if the operation executed successfully, the Err field -// will be nil; otherwise it will be stocked with a relevant error. Use the -// ExtractErr method -// to cleanly pull it out. -type ErrResult struct { - Result -} - -// ExtractErr is a function that extracts error information, or nil, from a result. -func (r ErrResult) ExtractErr() error { - return r.Err -} - -/* -HeaderResult is an internal type to be used by individual resource packages, but -its methods will be available on a wide variety of user-facing embedding types. - -It represents a result that only contains an error (possibly nil) and an -http.Header. This is used, for example, by the objectstorage packages in -openstack, because most of the operations don't return response bodies, but do -have relevant information in headers. -*/ -type HeaderResult struct { - Result -} - -// ExtractHeader will return the http.Header and error from the HeaderResult. -// -// header, err := objects.Create(client, "my_container", objects.CreateOpts{}).ExtractHeader() -func (hr HeaderResult) ExtractHeader() (http.Header, error) { - return hr.Header, hr.Err -} - -// RFC3339Milli describes a common time format used by some API responses. -const RFC3339Milli = "2006-01-02T15:04:05.999999Z" - -/* -Link is an internal type to be used in packages of collection resources that are -paginated in a certain way. - -It's a response substructure common to many paginated collection results that is -used to point to related pages. Usually, the one we care about is the one with -Rel field set to "next". -*/ -type Link struct { - Href string `mapstructure:"href"` - Rel string `mapstructure:"rel"` -} - -/* -ExtractNextURL is an internal function useful for packages of collection -resources that are paginated in a certain way. - -It attempts attempts to extract the "next" URL from slice of Link structs, or -"" if no such URL is present. -*/ -func ExtractNextURL(links []Link) (string, error) { - var url string - - for _, l := range links { - if l.Rel == "next" { - url = l.Href - } - } - - if url == "" { - return "", nil - } - - return url, nil -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/acceptancetest b/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/acceptancetest deleted file mode 100644 index f9c89f4dfd..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/acceptancetest +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# -# Run the acceptance tests. - -exec go test -p=1 -tags 'acceptance fixtures' github.com/rackspace/gophercloud/acceptance/... $@ diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/bootstrap b/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/bootstrap deleted file mode 100644 index 6bae6e8f14..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/bootstrap +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# -# This script helps new contributors set up their local workstation for -# gophercloud development and contributions. - -# Create the environment -export GOPATH=$HOME/go/gophercloud -mkdir -p $GOPATH - -# Download gophercloud into that environment -go get github.com/rackspace/gophercloud -cd $GOPATH/src/github.com/rackspace/gophercloud -git checkout master - -# Write out the env.sh convenience file. -cd $GOPATH -cat <env.sh -#!/bin/bash -export GOPATH=$(pwd) -export GOPHERCLOUD=$GOPATH/src/github.com/rackspace/gophercloud -EOF -chmod a+x env.sh - -# Make changes immediately available as a convenience. -. ./env.sh - diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/cibuild b/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/cibuild deleted file mode 100644 index 1cb389e7dc..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/cibuild +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# -# Test script to be invoked by Travis. - -exec script/unittest -v diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/test b/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/test deleted file mode 100644 index 1e03dff8ab..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/test +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# -# Run all the tests. - -exec go test -tags 'acceptance fixtures' ./... $@ diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/unittest b/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/unittest deleted file mode 100644 index d3440a902c..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/script/unittest +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# -# Run the unit tests. - -exec go test -tags fixtures ./... $@ diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/service_client_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/service_client_test.go deleted file mode 100644 index 84beb3f768..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/service_client_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package gophercloud - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestServiceURL(t *testing.T) { - c := &ServiceClient{Endpoint: "http://123.45.67.8/"} - expected := "http://123.45.67.8/more/parts/here" - actual := c.ServiceURL("more", "parts", "here") - th.CheckEquals(t, expected, actual) -} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/util_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/util_test.go deleted file mode 100644 index 5a15a005d3..0000000000 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/util_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package gophercloud - -import ( - "testing" - - th "github.com/rackspace/gophercloud/testhelper" -) - -func TestWaitFor(t *testing.T) { - err := WaitFor(5, func() (bool, error) { - return true, nil - }) - th.CheckNoErr(t, err) -} diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/LICENSE b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/LICENSE deleted file mode 100644 index 0071511a96..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 SmartyStreets - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/README.md b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/README.md deleted file mode 100644 index e2f6e405e6..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/README.md +++ /dev/null @@ -1,86 +0,0 @@ -go-aws-auth -=========== - -[![GoDoc](https://godoc.org/github.com/smartystreets/go-aws-auth?status.svg)](http://godoc.org/github.com/smartystreets/go-aws-auth) - -Go-AWS-Auth is a comprehensive, lightweight library for signing requests to Amazon Web Services. - -It's easy to use: simply build your HTTP request and call `awsauth.Sign(req)` before sending your request over the wire. - - - -### Supported signing mechanisms - -- [Signed Signature Version 2](http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html) -- [Signed Signature Version 3](http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) -- [Signed Signature Version 4](http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) -- [Custom S3 Authentication Scheme](http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) -- [Security Token Service](http://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html) -- [S3 Query String Authentication](http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth) -- [IAM Role](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials) - -For more info about AWS authentication, see the [comprehensive docs](http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) at AWS. - - -### Install - -Go get it: - - $ go get github.com/smartystreets/go-aws-auth - -Then import it: - - import "github.com/smartystreets/go-aws-auth" - - -### Using your AWS Credentials - -The library looks for credentials in this order: - -1. **Hard-code:** You can manually pass in an instance of `awsauth.Credentials` to any call to a signing function as a second argument: - - ```go - awsauth.Sign(req, awsauth.Credentials{ - AccessKeyID: "Access Key ID", - SecretAccessKey: "Secret Access Key", - SecurityToken: "Security Token", // STS (optional) - }) - ``` - - -2. **Environment variables:** Set the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables with your credentials. The library will automatically detect and use them. Optionally, you may also set the `AWS_SECURITY_TOKEN` environment variable if you are using temporary credentials from [STS](http://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html). - -3. **IAM Role:** If running on EC2 and the credentials are neither hard-coded nor in the environment, go-aws-auth will detect the first IAM role assigned to the current EC2 instance and use those credentials. - -(Be especially careful hard-coding credentials into your application if the code is committed to source control.) - - - -### Signing requests - -Just make the request, have it signed, and perform the request as you normally would. - -```go -url := "https://iam.amazonaws.com/?Action=ListRoles&Version=2010-05-08" -client := new(http.Client) - -req, err := http.NewRequest("GET", url, nil) - -awsauth.Sign(req) // Automatically chooses the best signing mechanism for the service - -resp, err := client.Do(req) -``` - -You can use `Sign` to have the library choose the best signing algorithm depending on the service, or you can specify it manually if you know what you need: - -- `Sign2` -- `Sign3` -- `Sign4` -- `SignS3` (deprecated for Sign4) -- `SignS3Url` (for pre-signed S3 URLs; GETs only) - - - -### Contributing - -Please feel free to contribute! Bug fixes are more than welcome any time, as long as tests assert correct behavior. If you'd like to change an existing implementation or see a new feature, open an issue first so we can discuss it. Thanks to all contributors! diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/awsauth.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/awsauth.go deleted file mode 100644 index 7bc9228535..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/awsauth.go +++ /dev/null @@ -1,231 +0,0 @@ -// Package awsauth implements AWS request signing using Signed Signature Version 2, -// Signed Signature Version 3, and Signed Signature Version 4. Supports S3 and STS. -package awsauth - -import ( - "net/http" - "net/url" - "sync" - "time" -) - -// Credentials stores the information necessary to authorize with AWS and it -// is from this information that requests are signed. -type Credentials struct { - AccessKeyID string - SecretAccessKey string - SecurityToken string `json:"Token"` - Expiration time.Time -} - -// Sign signs a request bound for AWS. It automatically chooses the best -// authentication scheme based on the service the request is going to. -func Sign(req *http.Request, cred ...Credentials) *http.Request { - service, _ := serviceAndRegion(req.URL.Host) - sigVersion := awsSignVersion[service] - - switch sigVersion { - case 2: - return Sign2(req, cred...) - case 3: - return Sign3(req, cred...) - case 4: - return Sign4(req, cred...) - case -1: - return SignS3(req, cred...) - } - - return nil -} - -// Sign4 signs a request with Signed Signature Version 4. -func Sign4(req *http.Request, cred ...Credentials) *http.Request { - signMutex.Lock() - defer signMutex.Unlock() - keys := chooseKeys(cred) - - // Add the X-Amz-Security-Token header when using STS - if keys.SecurityToken != "" { - req.Header.Set("X-Amz-Security-Token", keys.SecurityToken) - } - - prepareRequestV4(req) - meta := new(metadata) - - // Task 1 - hashedCanonReq := hashedCanonicalRequestV4(req, meta) - - // Task 2 - stringToSign := stringToSignV4(req, hashedCanonReq, meta) - - // Task 3 - signingKey := signingKeyV4(keys.SecretAccessKey, meta.date, meta.region, meta.service) - signature := signatureV4(signingKey, stringToSign) - - req.Header.Set("Authorization", buildAuthHeaderV4(signature, meta, keys)) - - return req -} - -// Sign3 signs a request with Signed Signature Version 3. -// If the service you're accessing supports Version 4, use that instead. -func Sign3(req *http.Request, cred ...Credentials) *http.Request { - signMutex.Lock() - defer signMutex.Unlock() - keys := chooseKeys(cred) - - // Add the X-Amz-Security-Token header when using STS - if keys.SecurityToken != "" { - req.Header.Set("X-Amz-Security-Token", keys.SecurityToken) - } - - prepareRequestV3(req) - - // Task 1 - stringToSign := stringToSignV3(req) - - // Task 2 - signature := signatureV3(stringToSign, keys) - - // Task 3 - req.Header.Set("X-Amzn-Authorization", buildAuthHeaderV3(signature, keys)) - - return req -} - -// Sign2 signs a request with Signed Signature Version 2. -// If the service you're accessing supports Version 4, use that instead. -func Sign2(req *http.Request, cred ...Credentials) *http.Request { - signMutex.Lock() - defer signMutex.Unlock() - keys := chooseKeys(cred) - - // Add the SecurityToken parameter when using STS - // This must be added before the signature is calculated - if keys.SecurityToken != "" { - v := url.Values{} - v.Set("SecurityToken", keys.SecurityToken) - augmentRequestQuery(req, v) - - } - - prepareRequestV2(req, keys) - - stringToSign := stringToSignV2(req) - signature := signatureV2(stringToSign, keys) - - values := url.Values{} - values.Set("Signature", signature) - - augmentRequestQuery(req, values) - - return req -} - -// SignS3 signs a request bound for Amazon S3 using their custom -// HTTP authentication scheme. -func SignS3(req *http.Request, cred ...Credentials) *http.Request { - signMutex.Lock() - defer signMutex.Unlock() - keys := chooseKeys(cred) - - // Add the X-Amz-Security-Token header when using STS - if keys.SecurityToken != "" { - req.Header.Set("X-Amz-Security-Token", keys.SecurityToken) - } - - prepareRequestS3(req) - - stringToSign := stringToSignS3(req) - signature := signatureS3(stringToSign, keys) - - authHeader := "AWS " + keys.AccessKeyID + ":" + signature - req.Header.Set("Authorization", authHeader) - - return req -} - -// SignS3Url signs a GET request for a resource on Amazon S3 by appending -// query string parameters containing credentials and signature. You must -// specify an expiration date for these signed requests. After that date, -// a request signed with this method will be rejected by S3. -func SignS3Url(req *http.Request, expire time.Time, cred ...Credentials) *http.Request { - signMutex.Lock() - defer signMutex.Unlock() - keys := chooseKeys(cred) - - stringToSign := stringToSignS3Url("GET", expire, req.URL.Path) - signature := signatureS3(stringToSign, keys) - - qs := req.URL.Query() - qs.Set("AWSAccessKeyId", keys.AccessKeyID) - qs.Set("Signature", signature) - qs.Set("Expires", timeToUnixEpochString(expire)) - req.URL.RawQuery = qs.Encode() - - return req -} - -// expired checks to see if the temporary credentials from an IAM role are -// within 4 minutes of expiration (The IAM documentation says that new keys -// will be provisioned 5 minutes before the old keys expire). Credentials -// that do not have an Expiration cannot expire. -func (k *Credentials) expired() bool { - if k.Expiration.IsZero() { - // Credentials with no expiration can't expire - return false - } - expireTime := k.Expiration.Add(-4 * time.Minute) - // if t - 4 mins is before now, true - if expireTime.Before(time.Now()) { - return true - } else { - return false - } -} - -type metadata struct { - algorithm string - credentialScope string - signedHeaders string - date string - region string - service string -} - -const ( - envAccessKeyID = "AWS_ACCESS_KEY_ID" - envSecretAccessKey = "AWS_SECRET_ACCESS_KEY" - envSecurityToken = "AWS_SECURITY_TOKEN" -) - -var ( - awsSignVersion = map[string]int{ - "autoscaling": 4, - "cloudfront": 4, - "cloudformation": 4, - "cloudsearch": 4, - "monitoring": 4, - "dynamodb": 4, - "ec2": 2, - "elasticmapreduce": 4, - "elastictranscoder": 4, - "elasticache": 2, - "glacier": 4, - "kinesis": 4, - "redshift": 4, - "rds": 4, - "sdb": 2, - "sns": 4, - "sqs": 4, - "s3": 4, - "elasticbeanstalk": 4, - "importexport": 2, - "iam": 4, - "route53": 3, - "elasticloadbalancing": 4, - "email": 3, - } - - signMutex sync.Mutex -) diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/awsauth_test.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/awsauth_test.go deleted file mode 100644 index 4ff5dbe38f..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/awsauth_test.go +++ /dev/null @@ -1,284 +0,0 @@ -package awsauth - -import ( - "io/ioutil" - "net/http" - "net/url" - "os" - "strings" - "testing" - "time" - . "github.com/smartystreets/goconvey/convey" -) - -func TestIntegration(t *testing.T) { - Convey("Given real credentials from environment variables", t, func() { - Convey("A request (with out-of-order query string) with to IAM should succeed (assuming Administrator Access policy)", func() { - req := newRequest("GET", "https://iam.amazonaws.com/?Version=2010-05-08&Action=ListRoles", nil) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign4AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("A request to S3 should succeed", func() { - req, _ := http.NewRequest("GET", "https://s3.amazonaws.com", nil) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign4AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("A request to EC2 should succeed", func() { - req := newRequest("GET", "https://ec2.amazonaws.com/?Version=2013-10-15&Action=DescribeInstances", nil) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign2AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("A request to SQS should succeed", func() { - req := newRequest("POST", "https://sqs.us-west-2.amazonaws.com", url.Values{ - "Action": []string{"ListQueues"}, - }) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign4AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("A request to SES should succeed", func() { - req := newRequest("GET", "https://email.us-east-1.amazonaws.com/?Action=GetSendStatistics", nil) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign3AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("A request to Route 53 should succeed", func() { - req := newRequest("GET", "https://route53.amazonaws.com/2013-04-01/hostedzone?maxitems=1", nil) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign3AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("A request to SimpleDB should succeed", func() { - req := newRequest("GET", "https://sdb.amazonaws.com/?Action=ListDomains&Version=2009-04-15", nil) - - if !credentialsSet() { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := sign2AndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - - Convey("If S3Resource env variable is set", func() { - s3res := os.Getenv("S3Resource") - - Convey("A URL-signed request to that S3 resource should succeed", func() { - req, _ := http.NewRequest("GET", s3res, nil) - - if !credentialsSet() || s3res == "" { - SkipSo(http.StatusOK, ShouldEqual, http.StatusOK) - } else { - resp := signS3UrlAndDo(req) - if resp.StatusCode != http.StatusOK { - msg, _ := ioutil.ReadAll(resp.Body) - t.Error(string(msg)) - } - So(resp.StatusCode, ShouldEqual, http.StatusOK) - } - }) - }) - }) -} - -func TestSign(t *testing.T) { - Convey("Requests to services using Version 2 should be signed accordingly", t, func() { - reqs := []*http.Request{ - newRequest("GET", "https://ec2.amazonaws.com", url.Values{}), - newRequest("GET", "https://elasticache.amazonaws.com/", url.Values{}), - } - for _, req := range reqs { - signedReq := Sign(req) - So(signedReq.URL.Query().Get("SignatureVersion"), ShouldEqual, "2") - } - }) - - Convey("Requests to services using Version 3 should be signed accordingly", t, func() { - reqs := []*http.Request{ - newRequest("GET", "https://route53.amazonaws.com", url.Values{}), - newRequest("GET", "https://email.us-east-1.amazonaws.com/", url.Values{}), - } - for _, req := range reqs { - signedReq := Sign(req) - So(signedReq.Header.Get("X-Amzn-Authorization"), ShouldNotBeBlank) - } - }) - - Convey("Requests to services using Version 4 should be signed accordingly", t, func() { - reqs := []*http.Request{ - newRequest("POST", "https://sqs.amazonaws.com/", url.Values{}), - newRequest("GET", "https://iam.amazonaws.com", url.Values{}), - newRequest("GET", "https://s3.amazonaws.com", url.Values{}), - } - for _, req := range reqs { - signedReq := Sign(req) - So(signedReq.Header.Get("Authorization"), ShouldContainSubstring, ", Signature=") - } - }) - - var keys Credentials - keys = newKeys() - Convey("Requests to services using existing credentials Version 2 should be signed accordingly", t, func() { - reqs := []*http.Request{ - newRequest("GET", "https://ec2.amazonaws.com", url.Values{}), - newRequest("GET", "https://elasticache.amazonaws.com/", url.Values{}), - } - for _, req := range reqs { - signedReq := Sign(req, keys) - So(signedReq.URL.Query().Get("SignatureVersion"), ShouldEqual, "2") - } - }) - - Convey("Requests to services using existing credentials Version 3 should be signed accordingly", t, func() { - reqs := []*http.Request{ - newRequest("GET", "https://route53.amazonaws.com", url.Values{}), - newRequest("GET", "https://email.us-east-1.amazonaws.com/", url.Values{}), - } - for _, req := range reqs { - signedReq := Sign(req, keys) - So(signedReq.Header.Get("X-Amzn-Authorization"), ShouldNotBeBlank) - } - }) - - Convey("Requests to services using existing credentials Version 4 should be signed accordingly", t, func() { - reqs := []*http.Request{ - newRequest("POST", "https://sqs.amazonaws.com/", url.Values{}), - newRequest("GET", "https://iam.amazonaws.com", url.Values{}), - newRequest("GET", "https://s3.amazonaws.com", url.Values{}), - } - for _, req := range reqs { - signedReq := Sign(req, keys) - So(signedReq.Header.Get("Authorization"), ShouldContainSubstring, ", Signature=") - } - }) -} - -func TestExpiration(t *testing.T) { - var c = &Credentials{} - - Convey("Credentials without an expiration can't expire", t, func() { - So(c.expired(), ShouldBeFalse) - }) - - Convey("Credentials that expire in 5 minutes aren't expired", t, func() { - c.Expiration = time.Now().Add(5 * time.Minute) - So(c.expired(), ShouldBeFalse) - }) - - Convey("Credentials that expire in 1 minute are expired", t, func() { - c.Expiration = time.Now().Add(1 * time.Minute) - So(c.expired(), ShouldBeTrue) - }) - - Convey("Credentials that expired 2 hours ago are expired", t, func() { - c.Expiration = time.Now().Add(-2 * time.Hour) - So(c.expired(), ShouldBeTrue) - }) -} - -func credentialsSet() bool { - var keys Credentials - keys = newKeys() - if keys.AccessKeyID == "" { - return false - } else { - return true - } -} - -func newRequest(method string, url string, v url.Values) *http.Request { - req, _ := http.NewRequest(method, url, strings.NewReader(v.Encode())) - return req -} - -func sign2AndDo(req *http.Request) *http.Response { - Sign2(req) - resp, _ := client.Do(req) - return resp -} - -func sign3AndDo(req *http.Request) *http.Response { - Sign3(req) - resp, _ := client.Do(req) - return resp -} - -func sign4AndDo(req *http.Request) *http.Response { - Sign4(req) - resp, _ := client.Do(req) - return resp -} - -func signS3AndDo(req *http.Request) *http.Response { - SignS3(req) - resp, _ := client.Do(req) - return resp -} - -func signS3UrlAndDo(req *http.Request) *http.Response { - SignS3Url(req, time.Now().AddDate(0, 0, 1)) - resp, _ := client.Do(req) - return resp -} - -var client = &http.Client{} diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/common.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/common.go deleted file mode 100644 index f39c899175..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/common.go +++ /dev/null @@ -1,300 +0,0 @@ -package awsauth - -import ( - "bufio" - "bytes" - "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "strings" - "time" -) - -type location struct { - ec2 bool - checked bool -} - -var loc *location - -// serviceAndRegion parsers a hostname to find out which ones it is. -// http://docs.aws.amazon.com/general/latest/gr/rande.html -func serviceAndRegion(host string) (service string, region string) { - // These are the defaults if the hostname doesn't suggest something else - region = "us-east-1" - service = "s3" - - parts := strings.Split(host, ".") - if len(parts) == 4 { - // Either service.region.amazonaws.com or virtual-host.region.amazonaws.com - if parts[1] == "s3" { - service = "s3" - } else if strings.HasPrefix(parts[1], "s3-") { - region = parts[1][3:] - service = "s3" - } else { - service = parts[0] - region = parts[1] - } - } else { - // Either service.amazonaws.com or s3-region.amazonaws.com - if strings.HasPrefix(parts[0], "s3-") { - region = parts[0][3:] - } else { - service = parts[0] - } - } - - if region == "external-1" { - region = "us-east-1" - } - - return -} - -// newKeys produces a set of credentials based on the environment -func newKeys() (newCredentials Credentials) { - // First use credentials from environment variables - newCredentials.AccessKeyID = os.Getenv(envAccessKeyID) - newCredentials.SecretAccessKey = os.Getenv(envSecretAccessKey) - newCredentials.SecurityToken = os.Getenv(envSecurityToken) - - // If there is no Access Key and you are on EC2, get the key from the role - if newCredentials.AccessKeyID == "" && onEC2() { - newCredentials = *getIAMRoleCredentials() - } - - // If the key is expiring, get a new key - if newCredentials.expired() && onEC2() { - newCredentials = *getIAMRoleCredentials() - } - - return newCredentials -} - -// checkKeys gets credentials depending on if any were passed in as an argument -// or it makes new ones based on the environment. -func chooseKeys(cred []Credentials) Credentials { - if len(cred) == 0 { - return newKeys() - } else { - return cred[0] - } -} - -// onEC2 checks to see if the program is running on an EC2 instance. -// It does this by looking for the EC2 metadata service. -// This caches that information in a struct so that it doesn't waste time. -func onEC2() bool { - if loc == nil { - loc = &location{} - } - if !(loc.checked) { - c, err := net.DialTimeout("tcp", "169.254.169.254:80", time.Second) - - if err != nil { - loc.ec2 = false - } else { - c.Close() - loc.ec2 = true - } - loc.checked = true - } - - return loc.ec2 -} - -// getIAMRoleList gets a list of the roles that are available to this instance -func getIAMRoleList() []string { - - var roles []string - url := "http://169.254.169.254/latest/meta-data/iam/security-credentials/" - - client := &http.Client{} - - req, err := http.NewRequest("GET", url, nil) - - if err != nil { - return roles - } - - resp, err := client.Do(req) - - if err != nil { - return roles - } - defer resp.Body.Close() - - scanner := bufio.NewScanner(resp.Body) - for scanner.Scan() { - roles = append(roles, scanner.Text()) - } - return roles -} - -func getIAMRoleCredentials() *Credentials { - - roles := getIAMRoleList() - - if len(roles) < 1 { - return &Credentials{} - } - - // Use the first role in the list - role := roles[0] - - url := "http://169.254.169.254/latest/meta-data/iam/security-credentials/" - - // Create the full URL of the role - var buffer bytes.Buffer - buffer.WriteString(url) - buffer.WriteString(role) - roleurl := buffer.String() - - // Get the role - rolereq, err := http.NewRequest("GET", roleurl, nil) - - if err != nil { - return &Credentials{} - } - - client := &http.Client{} - roleresp, err := client.Do(rolereq) - - if err != nil { - return &Credentials{} - } - defer roleresp.Body.Close() - - rolebuf := new(bytes.Buffer) - rolebuf.ReadFrom(roleresp.Body) - - creds := Credentials{} - - err = json.Unmarshal(rolebuf.Bytes(), &creds) - - if err != nil { - return &Credentials{} - } - - return &creds - -} - -func augmentRequestQuery(req *http.Request, values url.Values) *http.Request { - for key, arr := range req.URL.Query() { - for _, val := range arr { - values.Set(key, val) - } - } - - req.URL.RawQuery = values.Encode() - - return req -} - -func hmacSHA256(key []byte, content string) []byte { - mac := hmac.New(sha256.New, key) - mac.Write([]byte(content)) - return mac.Sum(nil) -} - -func hmacSHA1(key []byte, content string) []byte { - mac := hmac.New(sha1.New, key) - mac.Write([]byte(content)) - return mac.Sum(nil) -} - -func hashSHA256(content []byte) string { - h := sha256.New() - h.Write(content) - return fmt.Sprintf("%x", h.Sum(nil)) -} - -func hashMD5(content []byte) string { - h := md5.New() - h.Write(content) - return base64.StdEncoding.EncodeToString(h.Sum(nil)) -} - -func readAndReplaceBody(req *http.Request) []byte { - if req.Body == nil { - return []byte{} - } - payload, _ := ioutil.ReadAll(req.Body) - req.Body = ioutil.NopCloser(bytes.NewReader(payload)) - return payload -} - -func concat(delim string, str ...string) string { - return strings.Join(str, delim) -} - -var now = func() time.Time { - return time.Now().UTC() -} - -func normuri(uri string) string { - parts := strings.Split(uri, "/") - for i := range parts { - parts[i] = encodePathFrag(parts[i]) - } - return strings.Join(parts, "/") -} - -func encodePathFrag(s string) string { - hexCount := 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEscape(c) { - hexCount++ - } - } - t := make([]byte, len(s)+2*hexCount) - j := 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEscape(c) { - t[j] = '%' - t[j+1] = "0123456789ABCDEF"[c>>4] - t[j+2] = "0123456789ABCDEF"[c&15] - j += 3 - } else { - t[j] = c - j++ - } - } - return string(t) -} - -func shouldEscape(c byte) bool { - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' { - return false - } - if '0' <= c && c <= '9' { - return false - } - if c == '-' || c == '_' || c == '.' || c == '~' { - return false - } - return true -} - -func normquery(v url.Values) string { - qs := v.Encode() - - // Go encodes a space as '+' but Amazon require '%20'. Luckily any '+' in the - // original query string has been percent escaped so all '+' chars that are left - // were originally spaces. - - return strings.Replace(qs, "+", "%20", -1) -} diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/common_test.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/common_test.go deleted file mode 100644 index 0ae891c3b8..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/common_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package awsauth - -import ( - "testing" - "net/url" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestCommonFunctions(t *testing.T) { - Convey("Service and region should be properly extracted from host strings", t, func() { - service, region := serviceAndRegion("sqs.us-west-2.amazonaws.com") - So(service, ShouldEqual, "sqs") - So(region, ShouldEqual, "us-west-2") - - service, region = serviceAndRegion("iam.amazonaws.com") - So(service, ShouldEqual, "iam") - So(region, ShouldEqual, "us-east-1") - - service, region = serviceAndRegion("sns.us-west-2.amazonaws.com") - So(service, ShouldEqual, "sns") - So(region, ShouldEqual, "us-west-2") - - service, region = serviceAndRegion("bucketname.s3.amazonaws.com") - So(service, ShouldEqual, "s3") - So(region, ShouldEqual, "us-east-1") - - service, region = serviceAndRegion("s3.amazonaws.com") - So(service, ShouldEqual, "s3") - So(region, ShouldEqual, "us-east-1") - - service, region = serviceAndRegion("s3-us-west-1.amazonaws.com") - So(service, ShouldEqual, "s3") - So(region, ShouldEqual, "us-west-1") - - service, region = serviceAndRegion("s3-external-1.amazonaws.com") - So(service, ShouldEqual, "s3") - So(region, ShouldEqual, "us-east-1") - }) - - Convey("MD5 hashes should be properly computed and base-64 encoded", t, func() { - input := []byte("Pretend this is a REALLY long byte array...") - actual := hashMD5(input) - - So(actual, ShouldEqual, "KbVTY8Vl6VccnzQf1AGOFw==") - }) - - Convey("SHA-256 hashes should be properly hex-encoded (base 16)", t, func() { - input := []byte("This is... Sparta!!") - actual := hashSHA256(input) - - So(actual, ShouldEqual, "5c81a4ef1172e89b1a9d575f4cd82f4ed20ea9137e61aa7f1ab936291d24e79a") - }) - - Convey("Given a key and contents", t, func() { - key := []byte("asdf1234") - contents := "SmartyStreets was here" - - Convey("HMAC-SHA256 should be properly computed", func() { - expected := []byte{65, 46, 186, 78, 2, 155, 71, 104, 49, 37, 5, 66, 195, 129, 159, 227, 239, 53, 240, 107, 83, 21, 235, 198, 238, 216, 108, 149, 143, 222, 144, 94} - actual := hmacSHA256(key, contents) - - So(actual, ShouldResemble, expected) - }) - - Convey("HMAC-SHA1 should be properly computed", func() { - expected := []byte{164, 77, 252, 0, 87, 109, 207, 110, 163, 75, 228, 122, 83, 255, 233, 237, 125, 206, 85, 70} - actual := hmacSHA1(key, contents) - - So(actual, ShouldResemble, expected) - }) - }) - - Convey("Strings should be properly concatenated with a delimiter", t, func() { - So(concat("\n", "Test1", "Test2"), ShouldEqual, "Test1\nTest2") - So(concat(".", "Test1"), ShouldEqual, "Test1") - So(concat("\t", "1", "2", "3", "4"), ShouldEqual, "1\t2\t3\t4") - }) - - Convey("URI components should be properly encoded", t, func() { - So(normuri("/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), ShouldEqual, "/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") - So(normuri("/ /foo"), ShouldEqual, "/%20/foo") - So(normuri("/(foo)"), ShouldEqual, "/%28foo%29") - }) - - Convey("URI query strings should be properly encoded", t, func() { - So(normquery(url.Values{"p": []string{" +&;-=._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}}), ShouldEqual, "p=%20%2B%26%3B-%3D._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") - }) -} diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/s3.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/s3.go deleted file mode 100644 index bca79a2c98..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/s3.go +++ /dev/null @@ -1,121 +0,0 @@ -package awsauth - -import ( - "encoding/base64" - "net/http" - "sort" - "strconv" - "strings" - "time" -) - -func signatureS3(stringToSign string, keys Credentials) string { - hashed := hmacSHA1([]byte(keys.SecretAccessKey), stringToSign) - return base64.StdEncoding.EncodeToString(hashed) -} - -func stringToSignS3(req *http.Request) string { - str := req.Method + "\n" - - if req.Header.Get("Content-Md5") != "" { - str += req.Header.Get("Content-Md5") - } else { - body := readAndReplaceBody(req) - if len(body) > 0 { - str += hashMD5(body) - } - } - str += "\n" - - str += req.Header.Get("Content-Type") + "\n" - - if req.Header.Get("Date") != "" { - str += req.Header.Get("Date") - } else { - str += timestampS3() - } - - str += "\n" - - canonicalHeaders := canonicalAmzHeadersS3(req) - if canonicalHeaders != "" { - str += canonicalHeaders - } - - str += canonicalResourceS3(req) - - return str -} - -func stringToSignS3Url(method string, expire time.Time, path string) string { - return method + "\n\n\n" + timeToUnixEpochString(expire) + "\n" + path -} - -func timeToUnixEpochString(t time.Time) string { - return strconv.FormatInt(t.Unix(), 10) -} - -func canonicalAmzHeadersS3(req *http.Request) string { - var headers []string - - for header := range req.Header { - standardized := strings.ToLower(strings.TrimSpace(header)) - if strings.HasPrefix(standardized, "x-amz") { - headers = append(headers, standardized) - } - } - - sort.Strings(headers) - - for i, header := range headers { - headers[i] = header + ":" + strings.Replace(req.Header.Get(header), "\n", " ", -1) - } - - if len(headers) > 0 { - return strings.Join(headers, "\n") + "\n" - } else { - return "" - } -} - -func canonicalResourceS3(req *http.Request) string { - res := "" - - if isS3VirtualHostedStyle(req) { - bucketname := strings.Split(req.Host, ".")[0] - res += "/" + bucketname - } - - res += req.URL.Path - - for _, subres := range strings.Split(subresourcesS3, ",") { - if strings.HasPrefix(req.URL.RawQuery, subres) { - res += "?" + subres - } - } - - return res -} - -func prepareRequestS3(req *http.Request) *http.Request { - req.Header.Set("Date", timestampS3()) - if req.URL.Path == "" { - req.URL.Path += "/" - } - return req -} - -// Info: http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html -func isS3VirtualHostedStyle(req *http.Request) bool { - service, _ := serviceAndRegion(req.Host) - return service == "s3" && strings.Count(req.Host, ".") == 3 -} - -func timestampS3() string { - return now().Format(timeFormatS3) -} - -const ( - timeFormatS3 = time.RFC1123Z - subresourcesS3 = "acl,lifecycle,location,logging,notification,partNumber,policy,requestPayment,torrent,uploadId,uploads,versionId,versioning,versions,website" -) diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/s3_test.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/s3_test.go deleted file mode 100644 index 39c4e179a9..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/s3_test.go +++ /dev/null @@ -1,152 +0,0 @@ -package awsauth - -import ( - "fmt" - "net/http" - "net/url" - "testing" - "time" - . "github.com/smartystreets/goconvey/convey" -) - -func TestSignatureS3(t *testing.T) { - // http://docs.aws.amazon.com/AmazonS3/2006-03-01/dev/RESTAuthentication.html - // Note: S3 now supports signed signature version 4 - // (but signed URL requests still utilize a lot of the same functionality) - - Convey("Given a GET request to Amazon S3", t, func() { - keys := *testCredS3 - req := test_plainRequestS3() - - // Mock time - now = func() time.Time { - parsed, _ := time.Parse(timeFormatS3, exampleReqTsS3) - return parsed - } - - Convey("The request should be prepared with a Date header", func() { - prepareRequestS3(req) - So(req.Header.Get("Date"), ShouldEqual, exampleReqTsS3) - }) - - Convey("The CanonicalizedAmzHeaders should be built properly", func() { - req2 := test_headerRequestS3() - actual := canonicalAmzHeadersS3(req2) - So(actual, ShouldEqual, expectedCanonAmzHeadersS3) - }) - - Convey("The CanonicalizedResource should be built properly", func() { - actual := canonicalResourceS3(req) - So(actual, ShouldEqual, expectedCanonResourceS3) - }) - - Convey("The string to sign should be correct", func() { - actual := stringToSignS3(req) - So(actual, ShouldEqual, expectedStringToSignS3) - }) - - Convey("The final signature string should be exactly correct", func() { - actual := signatureS3(stringToSignS3(req), keys) - So(actual, ShouldEqual, "bWq2s1WEIj+Ydj0vQ697zp+IXMU=") - }) - }) - - Convey("Given a GET request for a resource on S3 for query string authentication", t, func() { - keys := *testCredS3 - req, _ := http.NewRequest("GET", "https://johnsmith.s3.amazonaws.com/johnsmith/photos/puppy.jpg", nil) - - now = func() time.Time { - parsed, _ := time.Parse(timeFormatS3, exampleReqTsS3) - return parsed - } - - Convey("The string to sign should be correct", func() { - actual := stringToSignS3Url("GET", now(), req.URL.Path) - So(actual, ShouldEqual, expectedStringToSignS3Url) - }) - - Convey("The signature of string to sign should be correct", func() { - actual := signatureS3(expectedStringToSignS3Url, keys) - So(actual, ShouldEqual, "R2K/+9bbnBIbVDCs7dqlz3XFtBQ=") - }) - - Convey("The finished signed URL should be correct", func() { - expiry := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) - So(SignS3Url(req, expiry, keys).URL.String(), ShouldEqual, expectedSignedS3Url) - }) - }) -} - -func TestS3STSRequestPreparer(t *testing.T) { - Convey("Given a plain request with no custom headers", t, func() { - req := test_plainRequestS3() - - Convey("And a set of credentials with an STS token", func() { - keys := *testCredS3WithSTS - - Convey("It should include an X-Amz-Security-Token when the request is signed", func() { - actualSigned := SignS3(req, keys) - actual := actualSigned.Header.Get("X-Amz-Security-Token") - - So(actual, ShouldNotBeBlank) - So(actual, ShouldEqual, testCredS3WithSTS.SecurityToken) - - }) - }) - }) -} - -func test_plainRequestS3() *http.Request { - req, _ := http.NewRequest("GET", "https://johnsmith.s3.amazonaws.com/photos/puppy.jpg", nil) - return req -} - -func test_headerRequestS3() *http.Request { - req := test_plainRequestS3() - req.Header.Set("X-Amz-Meta-Something", "more foobar") - req.Header.Set("X-Amz-Date", "foobar") - req.Header.Set("X-Foobar", "nanoo-nanoo") - return req -} - -func TestCanonical(t *testing.T) { - expectedCanonicalString := "PUT\nc8fdb181845a4ca6b8fec737b3581d76\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-amz-magic:abracadabra\nx-amz-meta-author:foo@bar.com\n/quotes/nelson" - - origUrl := "https://s3.amazonaws.com/" - resource := "/quotes/nelson" - - u, _ := url.ParseRequestURI(origUrl) - u.Path = resource - urlStr := fmt.Sprintf("%v", u) - - req, _ := http.NewRequest("PUT", urlStr, nil) - req.Header.Add("Content-Md5", "c8fdb181845a4ca6b8fec737b3581d76") - req.Header.Add("Content-Type", "text/html") - req.Header.Add("Date", "Thu, 17 Nov 2005 18:49:58 GMT") - req.Header.Add("X-Amz-Meta-Author", "foo@bar.com") - req.Header.Add("X-Amz-Magic", "abracadabra") - - if stringToSignS3(req) != expectedCanonicalString { - t.Errorf("----Got\n***%s***\n----Expected\n***%s***", stringToSignS3(req), expectedCanonicalString) - } -} - -var ( - testCredS3 = &Credentials{ - AccessKeyID: "AKIAIOSFODNN7EXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - } - - testCredS3WithSTS = &Credentials{ - AccessKeyID: "AKIDEXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", - SecurityToken: "AQoDYXdzEHcaoAJ1Aqwx1Sum0iW2NQjXJcWlKR7vuB6lnAeGBaQnjDRZPVyniwc48ml5hx+0qiXenVJdfusMMl9XLhSncfhx9Rb1UF8IAOaQ+CkpWXvoH67YYN+93dgckSVgVEBRByTl/BvLOZhe0ii/pOWkuQtBm5T7lBHRe4Dfmxy9X6hd8L3FrWxgnGV3fWZ3j0gASdYXaa+VBJlU0E2/GmCzn3T+t2mjYaeoInAnYVKVpmVMOrh6lNAeETTOHElLopblSa7TAmROq5xHIyu4a9i2qwjERTwa3Yk4Jk6q7JYVA5Cu7kS8wKVml8LdzzCTsy+elJgvH+Jf6ivpaHt/En0AJ5PZUJDev2+Y5+9j4AYfrmXfm4L73DC1ZJFJrv+Yh+EXAMPLE=", - } - - expectedCanonAmzHeadersS3 = "x-amz-date:foobar\nx-amz-meta-something:more foobar\n" - expectedCanonResourceS3 = "/johnsmith/photos/puppy.jpg" - expectedStringToSignS3 = "GET\n\n\nTue, 27 Mar 2007 19:36:42 +0000\n/johnsmith/photos/puppy.jpg" - expectedStringToSignS3Url = "GET\n\n\n1175024202\n/johnsmith/photos/puppy.jpg" - expectedSignedS3Url = "https://johnsmith.s3.amazonaws.com/johnsmith/photos/puppy.jpg?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Expires=1257894000&Signature=X%2FarTLAJP08uP1Bsap52rwmsVok%3D" - exampleReqTsS3 = "Tue, 27 Mar 2007 19:36:42 +0000" -) diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign2.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign2.go deleted file mode 100644 index c10f132f11..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign2.go +++ /dev/null @@ -1,50 +0,0 @@ -package awsauth - -import ( - "encoding/base64" - "net/http" - "net/url" - "strings" -) - -func prepareRequestV2(req *http.Request, keys Credentials) *http.Request { - - keyID := keys.AccessKeyID - - values := url.Values{} - values.Set("AWSAccessKeyId", keyID) - values.Set("SignatureVersion", "2") - values.Set("SignatureMethod", "HmacSHA256") - values.Set("Timestamp", timestampV2()) - - augmentRequestQuery(req, values) - - if req.URL.Path == "" { - req.URL.Path += "/" - } - - return req -} - -func stringToSignV2(req *http.Request) string { - str := req.Method + "\n" - str += strings.ToLower(req.URL.Host) + "\n" - str += req.URL.Path + "\n" - str += canonicalQueryStringV2(req) - return str -} - -func signatureV2(strToSign string, keys Credentials) string { - hashed := hmacSHA256([]byte(keys.SecretAccessKey), strToSign) - return base64.StdEncoding.EncodeToString(hashed) -} - -func canonicalQueryStringV2(req *http.Request) string { - return req.URL.RawQuery -} - -func timestampV2() string { - return now().Format(timeFormatV2) -} - -const timeFormatV2 = "2006-01-02T15:04:05" diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign2_test.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign2_test.go deleted file mode 100644 index c69557d03b..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign2_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package awsauth - -import ( - "net/http" - "net/url" - "testing" - "time" - . "github.com/smartystreets/goconvey/convey" -) - -func TestSignature2(t *testing.T) { - // http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html - - Convey("Given bogus credentials", t, func() { - keys := *testCredV2 - - // Mock time - now = func() time.Time { - parsed, _ := time.Parse(timeFormatV2, exampleReqTsV2) - return parsed - } - - Convey("Given a plain request that is unprepared", func() { - req := test_plainRequestV2() - - Convey("The request should be prepared to be signed", func() { - expectedUnsigned := test_unsignedRequestV2() - prepareRequestV2(req, keys) - So(req, ShouldResemble, expectedUnsigned) - }) - }) - - Convey("Given a prepared, but unsigned, request", func() { - req := test_unsignedRequestV2() - - Convey("The canonical query string should be correct", func() { - actual := canonicalQueryStringV2(req) - expected := canonicalQsV2 - So(actual, ShouldEqual, expected) - }) - - Convey("The absolute path should be extracted correctly", func() { - So(req.URL.Path, ShouldEqual, "/") - }) - - Convey("The string to sign should be well-formed", func() { - actual := stringToSignV2(req) - So(actual, ShouldEqual, expectedStringToSignV2) - }) - - Convey("The resulting signature should be correct", func() { - actual := signatureV2(stringToSignV2(req), keys) - So(actual, ShouldEqual, "i91nKc4PWAt0JJIdXwz9HxZCJDdiy6cf/Mj6vPxyYIs=") - }) - - Convey("The final signed request should be correctly formed", func() { - Sign2(req, keys) - actual := req.URL.String() - So(actual, ShouldResemble, expectedFinalUrlV2) - }) - }) - }) -} - -func TestVersion2STSRequestPreparer(t *testing.T) { - Convey("Given a plain request ", t, func() { - req := test_plainRequestV2() - - Convey("And a set of credentials with an STS token", func() { - var keys Credentials - keys = *testCredV2WithSTS - - Convey("It should include the SecurityToken parameter when the request is signed", func() { - actualSigned := Sign2(req, keys) - actual := actualSigned.URL.Query()["SecurityToken"][0] - - So(actual, ShouldNotBeBlank) - So(actual, ShouldEqual, testCredV2WithSTS.SecurityToken) - - }) - }) - }) - -} - -func test_plainRequestV2() *http.Request { - values := url.Values{} - values.Set("Action", "DescribeJobFlows") - values.Set("Version", "2009-03-31") - - url := baseUrlV2 + "?" + values.Encode() - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - panic(err) - } - - return req -} - -func test_unsignedRequestV2() *http.Request { - req := test_plainRequestV2() - newUrl, _ := url.Parse(baseUrlV2 + "/?" + canonicalQsV2) - req.URL = newUrl - return req -} - -var ( - testCredV2 = &Credentials{ - AccessKeyID: "AKIAIOSFODNN7EXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - } - - testCredV2WithSTS = &Credentials{ - AccessKeyID: "AKIDEXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", - SecurityToken: "AQoDYXdzEHcaoAJ1Aqwx1Sum0iW2NQjXJcWlKR7vuB6lnAeGBaQnjDRZPVyniwc48ml5hx+0qiXenVJdfusMMl9XLhSncfhx9Rb1UF8IAOaQ+CkpWXvoH67YYN+93dgckSVgVEBRByTl/BvLOZhe0ii/pOWkuQtBm5T7lBHRe4Dfmxy9X6hd8L3FrWxgnGV3fWZ3j0gASdYXaa+VBJlU0E2/GmCzn3T+t2mjYaeoInAnYVKVpmVMOrh6lNAeETTOHElLopblSa7TAmROq5xHIyu4a9i2qwjERTwa3Yk4Jk6q7JYVA5Cu7kS8wKVml8LdzzCTsy+elJgvH+Jf6ivpaHt/En0AJ5PZUJDev2+Y5+9j4AYfrmXfm4L73DC1ZJFJrv+Yh+EXAMPLE=", - } - - exampleReqTsV2 = "2011-10-03T15:19:30" - baseUrlV2 = "https://elasticmapreduce.amazonaws.com" - canonicalQsV2 = "AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Action=DescribeJobFlows&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2011-10-03T15%3A19%3A30&Version=2009-03-31" - expectedStringToSignV2 = "GET\nelasticmapreduce.amazonaws.com\n/\n" + canonicalQsV2 - expectedFinalUrlV2 = baseUrlV2 + "/?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Action=DescribeJobFlows&Signature=i91nKc4PWAt0JJIdXwz9HxZCJDdiy6cf%2FMj6vPxyYIs%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2011-10-03T15%3A19%3A30&Version=2009-03-31" -) diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign3.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign3.go deleted file mode 100644 index 5a1260d9cc..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign3.go +++ /dev/null @@ -1,58 +0,0 @@ -// Thanks to Michael Vierling for contributing sign3.go - -package awsauth - -import ( - "encoding/base64" - "net/http" - "time" -) - -func stringToSignV3(req *http.Request) string { - // TASK 1. http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RESTAuthentication.html#StringToSign - - return req.Header.Get("Date") + req.Header.Get("x-amz-nonce") -} - -func signatureV3(stringToSign string, keys Credentials) string { - // TASK 2. http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RESTAuthentication.html#Signature - - hash := hmacSHA256([]byte(keys.SecretAccessKey), stringToSign) - return base64.StdEncoding.EncodeToString(hash) -} - -func buildAuthHeaderV3(signature string, keys Credentials) string { - // TASK 3. http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RESTAuthentication.html#AuthorizationHeader - - return "AWS3-HTTPS AWSAccessKeyId=" + keys.AccessKeyID + - ", Algorithm=HmacSHA256" + - ", Signature=" + signature -} - -func prepareRequestV3(req *http.Request) *http.Request { - ts := timestampV3() - necessaryDefaults := map[string]string{ - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", - "x-amz-date": ts, - "Date": ts, - "x-amz-nonce": "", - } - - for header, value := range necessaryDefaults { - if req.Header.Get(header) == "" { - req.Header.Set(header, value) - } - } - - if req.URL.Path == "" { - req.URL.Path += "/" - } - - return req -} - -func timestampV3() string { - return now().Format(timeFormatV3) -} - -const timeFormatV3 = time.RFC1123 diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign3_test.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign3_test.go deleted file mode 100644 index f4e87fd28c..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign3_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package awsauth - -import ( - "net/http" - "net/url" - "testing" - "time" - . "github.com/smartystreets/goconvey/convey" -) - -func TestSignature3(t *testing.T) { - // http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RESTAuthentication.html - // http://docs.aws.amazon.com/ses/latest/DeveloperGuide/query-interface-authentication.html - - Convey("Given bogus credentials", t, func() { - keys := *testCredV3 - - // Mock time - now = func() time.Time { - parsed, _ := time.Parse(timeFormatV3, exampleReqTsV3) - return parsed - } - - Convey("Given a plain request that is unprepared", func() { - req := test_plainRequestV3() - - Convey("The request should be prepared to be signed", func() { - expectedUnsigned := test_unsignedRequestV3() - prepareRequestV3(req) - So(req, ShouldResemble, expectedUnsigned) - }) - }) - - Convey("Given a prepared, but unsigned, request", func() { - req := test_unsignedRequestV3() - - Convey("The absolute path should be extracted correctly", func() { - So(req.URL.Path, ShouldEqual, "/") - }) - - Convey("The string to sign should be well-formed", func() { - actual := stringToSignV3(req) - So(actual, ShouldEqual, expectedStringToSignV3) - }) - - Convey("The resulting signature should be correct", func() { - actual := signatureV3(stringToSignV3(req), keys) - So(actual, ShouldEqual, "PjAJ6buiV6l4WyzmmuwtKE59NJXVg5Dr3Sn4PCMZ0Yk=") - }) - - Convey("The final signed request should be correctly formed", func() { - Sign3(req, keys) - actual := req.Header.Get("X-Amzn-Authorization") - So(actual, ShouldResemble, expectedAuthHeaderV3) - }) - }) - }) -} - -func test_plainRequestV3() *http.Request { - values := url.Values{} - values.Set("Action", "GetSendStatistics") - values.Set("Version", "2010-12-01") - - url := baseUrlV3 + "/?" + values.Encode() - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - panic(err) - } - - return req -} - -func test_unsignedRequestV3() *http.Request { - req := test_plainRequestV3() - req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") - req.Header.Set("x-amz-date", exampleReqTsV3) - req.Header.Set("Date", exampleReqTsV3) - req.Header.Set("x-amz-nonce", "") - return req -} - -func TestVersion3STSRequestPreparer(t *testing.T) { - Convey("Given a plain request with no custom headers", t, func() { - req := test_plainRequestV3() - - Convey("And a set of credentials with an STS token", func() { - var keys Credentials - keys = *testCredV3WithSTS - - Convey("It should include an X-Amz-Security-Token when the request is signed", func() { - actualSigned := Sign3(req, keys) - actual := actualSigned.Header.Get("X-Amz-Security-Token") - - So(actual, ShouldNotBeBlank) - So(actual, ShouldEqual, testCredV4WithSTS.SecurityToken) - - }) - }) - }) - -} - -var ( - testCredV3 = &Credentials{ - AccessKeyID: "AKIAIOSFODNN7EXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - } - - testCredV3WithSTS = &Credentials{ - AccessKeyID: "AKIDEXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", - SecurityToken: "AQoDYXdzEHcaoAJ1Aqwx1Sum0iW2NQjXJcWlKR7vuB6lnAeGBaQnjDRZPVyniwc48ml5hx+0qiXenVJdfusMMl9XLhSncfhx9Rb1UF8IAOaQ+CkpWXvoH67YYN+93dgckSVgVEBRByTl/BvLOZhe0ii/pOWkuQtBm5T7lBHRe4Dfmxy9X6hd8L3FrWxgnGV3fWZ3j0gASdYXaa+VBJlU0E2/GmCzn3T+t2mjYaeoInAnYVKVpmVMOrh6lNAeETTOHElLopblSa7TAmROq5xHIyu4a9i2qwjERTwa3Yk4Jk6q7JYVA5Cu7kS8wKVml8LdzzCTsy+elJgvH+Jf6ivpaHt/En0AJ5PZUJDev2+Y5+9j4AYfrmXfm4L73DC1ZJFJrv+Yh+EXAMPLE=", - } - - exampleReqTsV3 = "Thu, 14 Aug 2008 17:08:48 GMT" - baseUrlV3 = "https://email.us-east-1.amazonaws.com" - expectedStringToSignV3 = exampleReqTsV3 - expectedAuthHeaderV3 = "AWS3-HTTPS AWSAccessKeyId=" + testCredV3.AccessKeyID + ", Algorithm=HmacSHA256, Signature=PjAJ6buiV6l4WyzmmuwtKE59NJXVg5Dr3Sn4PCMZ0Yk=" -) diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign4.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign4.go deleted file mode 100644 index 3ae9da6831..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign4.go +++ /dev/null @@ -1,107 +0,0 @@ -package awsauth - -import ( - "encoding/hex" - "net/http" - "sort" - "strings" -) - -func hashedCanonicalRequestV4(req *http.Request, meta *metadata) string { - // TASK 1. http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - - payload := readAndReplaceBody(req) - payloadHash := hashSHA256(payload) - req.Header.Set("X-Amz-Content-Sha256", payloadHash) - - // Set this in header values to make it appear in the range of headers to sign - req.Header.Set("Host", req.Host) - - var sortedHeaderKeys []string - for key, _ := range req.Header { - switch key { - case "Content-Type", "Content-Md5", "Host": - default: - if !strings.HasPrefix(key, "X-Amz-") { - continue - } - } - sortedHeaderKeys = append(sortedHeaderKeys, strings.ToLower(key)) - } - sort.Strings(sortedHeaderKeys) - - var headersToSign string - for _, key := range sortedHeaderKeys { - value := strings.TrimSpace(req.Header.Get(key)) - headersToSign += key + ":" + value + "\n" - } - meta.signedHeaders = concat(";", sortedHeaderKeys...) - canonicalRequest := concat("\n", req.Method, normuri(req.URL.Path), normquery(req.URL.Query()), headersToSign, meta.signedHeaders, payloadHash) - - return hashSHA256([]byte(canonicalRequest)) -} - -func stringToSignV4(req *http.Request, hashedCanonReq string, meta *metadata) string { - // TASK 2. http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html - - requestTs := req.Header.Get("X-Amz-Date") - - meta.algorithm = "AWS4-HMAC-SHA256" - meta.service, meta.region = serviceAndRegion(req.Host) - meta.date = tsDateV4(requestTs) - meta.credentialScope = concat("/", meta.date, meta.region, meta.service, "aws4_request") - - return concat("\n", meta.algorithm, requestTs, meta.credentialScope, hashedCanonReq) -} - -func signatureV4(signingKey []byte, stringToSign string) string { - // TASK 3. http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html - - return hex.EncodeToString(hmacSHA256(signingKey, stringToSign)) -} - -func prepareRequestV4(req *http.Request) *http.Request { - necessaryDefaults := map[string]string{ - "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", - "X-Amz-Date": timestampV4(), - } - - for header, value := range necessaryDefaults { - if req.Header.Get(header) == "" { - req.Header.Set(header, value) - } - } - - if req.URL.Path == "" { - req.URL.Path += "/" - } - - return req -} - -func signingKeyV4(secretKey, date, region, service string) []byte { - kDate := hmacSHA256([]byte("AWS4"+secretKey), date) - kRegion := hmacSHA256(kDate, region) - kService := hmacSHA256(kRegion, service) - kSigning := hmacSHA256(kService, "aws4_request") - return kSigning -} - -func buildAuthHeaderV4(signature string, meta *metadata, keys Credentials) string { - credential := keys.AccessKeyID + "/" + meta.credentialScope - - return meta.algorithm + - " Credential=" + credential + - ", SignedHeaders=" + meta.signedHeaders + - ", Signature=" + signature -} - -func timestampV4() string { - return now().Format(timeFormatV4) -} - -func tsDateV4(timestamp string) string { - return timestamp[:8] -} - -const timeFormatV4 = "20060102T150405Z" diff --git a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign4_test.go b/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign4_test.go deleted file mode 100644 index d0924d3e84..0000000000 --- a/Godeps/_workspace/src/github.com/smartystreets/go-aws-auth/sign4_test.go +++ /dev/null @@ -1,216 +0,0 @@ -package awsauth - -import ( - "net/http" - "net/url" - "strings" - "testing" - . "github.com/smartystreets/goconvey/convey" -) - -func TestVersion4RequestPreparer(t *testing.T) { - Convey("Given a plain request with no custom headers", t, func() { - req := test_plainRequestV4(false) - - expectedUnsigned := test_unsignedRequestV4(true, false) - expectedUnsigned.Header.Set("X-Amz-Date", timestampV4()) - - Convey("The necessary, default headers should be appended", func() { - prepareRequestV4(req) - So(req, ShouldResemble, expectedUnsigned) - }) - - Convey("Forward-slash should be appended to URI if not present", func() { - prepareRequestV4(req) - So(req.URL.Path, ShouldEqual, "/") - }) - - Convey("And a set of credentials", func() { - var keys Credentials - keys = *testCredV4 - - Convey("It should be signed with an Authorization header", func() { - actualSigned := Sign4(req, keys) - actual := actualSigned.Header.Get("Authorization") - - So(actual, ShouldNotBeBlank) - So(actual, ShouldContainSubstring, "Credential="+testCredV4.AccessKeyID) - So(actual, ShouldContainSubstring, "SignedHeaders=") - So(actual, ShouldContainSubstring, "Signature=") - So(actual, ShouldContainSubstring, "AWS4") - }) - }) - }) - - Convey("Given a request with custom, necessary headers", t, func() { - Convey("The custom, necessary headers must not be changed", func() { - req := test_unsignedRequestV4(true, false) - prepareRequestV4(req) - So(req, ShouldResemble, test_unsignedRequestV4(true, false)) - }) - }) -} - -func TestVersion4STSRequestPreparer(t *testing.T) { - Convey("Given a plain request with no custom headers", t, func() { - req := test_plainRequestV4(false) - - Convey("And a set of credentials with an STS token", func() { - var keys Credentials - keys = *testCredV4WithSTS - - Convey("It should include an X-Amz-Security-Token when the request is signed", func() { - actualSigned := Sign4(req, keys) - actual := actualSigned.Header.Get("X-Amz-Security-Token") - - So(actual, ShouldNotBeBlank) - So(actual, ShouldEqual, testCredV4WithSTS.SecurityToken) - - }) - }) - }) - -} - -func TestVersion4SigningTasks(t *testing.T) { - // http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html - - Convey("Given a bogus request and credentials from AWS documentation with an additional meta tag", t, func() { - req := test_unsignedRequestV4(true, true) - meta := new(metadata) - - Convey("(Task 1) The canonical request should be built correctly", func() { - hashedCanonReq := hashedCanonicalRequestV4(req, meta) - - So(hashedCanonReq, ShouldEqual, expectingV4["CanonicalHash"]) - }) - - Convey("(Task 2) The string to sign should be built correctly", func() { - hashedCanonReq := hashedCanonicalRequestV4(req, meta) - stringToSign := stringToSignV4(req, hashedCanonReq, meta) - - So(stringToSign, ShouldEqual, expectingV4["StringToSign"]) - }) - - Convey("(Task 3) The version 4 signed signature should be correct", func() { - hashedCanonReq := hashedCanonicalRequestV4(req, meta) - stringToSign := stringToSignV4(req, hashedCanonReq, meta) - signature := signatureV4(test_signingKeyV4(), stringToSign) - - So(signature, ShouldEqual, expectingV4["SignatureV4"]) - }) - }) -} - -func TestSignature4Helpers(t *testing.T) { - - keys := *testCredV4 - - Convey("The signing key should be properly generated", t, func() { - expected := []byte{152, 241, 216, 137, 254, 196, 244, 66, 26, 220, 82, 43, 171, 12, 225, 248, 46, 105, 41, 194, 98, 237, 21, 229, 169, 76, 144, 239, 209, 227, 176, 231} - actual := test_signingKeyV4() - - So(actual, ShouldResemble, expected) - }) - - Convey("Authorization headers should be built properly", t, func() { - meta := &metadata{ - algorithm: "AWS4-HMAC-SHA256", - credentialScope: "20110909/us-east-1/iam/aws4_request", - signedHeaders: "content-type;host;x-amz-date", - } - expected := expectingV4["AuthHeader"] + expectingV4["SignatureV4"] - actual := buildAuthHeaderV4(expectingV4["SignatureV4"], meta, keys) - - So(actual, ShouldEqual, expected) - }) - - Convey("Timestamps should be in the correct format, in UTC time", t, func() { - actual := timestampV4() - - So(len(actual), ShouldEqual, 16) - So(actual, ShouldNotContainSubstring, ":") - So(actual, ShouldNotContainSubstring, "-") - So(actual, ShouldNotContainSubstring, " ") - So(actual, ShouldEndWith, "Z") - So(actual, ShouldContainSubstring, "T") - }) - - Convey("Given an Version 4 AWS-formatted timestamp", t, func() { - ts := "20110909T233600Z" - - Convey("The date string should be extracted properly", func() { - So(tsDateV4(ts), ShouldEqual, "20110909") - }) - }) - - Convey("Given any request with a body", t, func() { - req := test_plainRequestV4(false) - - Convey("Its body should be read and replaced without differences", func() { - expected := []byte(requestValuesV4.Encode()) - - actual1 := readAndReplaceBody(req) - So(actual1, ShouldResemble, expected) - - actual2 := readAndReplaceBody(req) - So(actual2, ShouldResemble, expected) - }) - }) -} - -func test_plainRequestV4(trailingSlash bool) *http.Request { - url := "http://iam.amazonaws.com" - body := strings.NewReader(requestValuesV4.Encode()) - - if trailingSlash { - url += "/" - } - - req, err := http.NewRequest("POST", url, body) - - if err != nil { - panic(err) - } - - return req -} - -func test_unsignedRequestV4(trailingSlash, tag bool) *http.Request { - req := test_plainRequestV4(trailingSlash) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") - req.Header.Set("X-Amz-Date", "20110909T233600Z") - if tag { - req.Header.Set("X-Amz-Meta-Foo", "Bar!") - } - return req -} - -func test_signingKeyV4() []byte { - return signingKeyV4(testCredV4.SecretAccessKey, "20110909", "us-east-1", "iam") -} - -var ( - testCredV4 = &Credentials{ - AccessKeyID: "AKIDEXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", - } - - testCredV4WithSTS = &Credentials{ - AccessKeyID: "AKIDEXAMPLE", - SecretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", - SecurityToken: "AQoDYXdzEHcaoAJ1Aqwx1Sum0iW2NQjXJcWlKR7vuB6lnAeGBaQnjDRZPVyniwc48ml5hx+0qiXenVJdfusMMl9XLhSncfhx9Rb1UF8IAOaQ+CkpWXvoH67YYN+93dgckSVgVEBRByTl/BvLOZhe0ii/pOWkuQtBm5T7lBHRe4Dfmxy9X6hd8L3FrWxgnGV3fWZ3j0gASdYXaa+VBJlU0E2/GmCzn3T+t2mjYaeoInAnYVKVpmVMOrh6lNAeETTOHElLopblSa7TAmROq5xHIyu4a9i2qwjERTwa3Yk4Jk6q7JYVA5Cu7kS8wKVml8LdzzCTsy+elJgvH+Jf6ivpaHt/En0AJ5PZUJDev2+Y5+9j4AYfrmXfm4L73DC1ZJFJrv+Yh+EXAMPLE=", - } - - expectingV4 = map[string]string{ - "CanonicalHash": "41c56ed0df12052f7c10407a809e64cd61a4b0471956cdea28d6d1bb904f5d92", - "StringToSign": "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/iam/aws4_request\n41c56ed0df12052f7c10407a809e64cd61a4b0471956cdea28d6d1bb904f5d92", - "SignatureV4": "08292a4b86aae1a6f80f1988182a33cbf73ccc70c5da505303e355a67cc64cb4", - "AuthHeader": "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=", - } - - requestValuesV4 = &url.Values{ - "Action": []string{"ListUsers"}, - "Version": []string{"2010-05-08"}, - } -) diff --git a/Godeps/_workspace/src/github.com/tent/http-link-go/link_test.go b/Godeps/_workspace/src/github.com/tent/http-link-go/link_test.go deleted file mode 100644 index 8a78eeabb8..0000000000 --- a/Godeps/_workspace/src/github.com/tent/http-link-go/link_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package link - -import ( - "testing" - - . "launchpad.net/gocheck" -) - -// Hook up gocheck into the "go test" runner. -func Test(t *testing.T) { TestingT(t) } - -type LinkSuite struct{} - -var _ = Suite(&LinkSuite{}) - -// TODO: add more tests -var linkParseTests = []struct { - in string - out []Link -}{ - { - "; rel=\"previous\";\n title=\"previous chapter\"", - []Link{{URI: "http://example.com/TheBook/chapter2", Rel: "previous", Params: map[string]string{"title": "previous chapter"}}}, - }, - { - ";\n rel=\"previous\"; title*=UTF-8'de'letztes%20Kapitel,\n ;\n rel=\"next\"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel", - []Link{ - {URI: "/TheBook/chapter2", Rel: "previous", Params: map[string]string{"title*": "UTF-8'de'letztes%20Kapitel"}}, - {URI: "/TheBook/chapter4", Rel: "next", Params: map[string]string{"title*": "UTF-8'de'n%c3%a4chstes%20Kapitel"}}, - }, - }, -} - -func (s *LinkSuite) TestLinkParsing(c *C) { - for i, t := range linkParseTests { - res, err := Parse(t.in) - c.Assert(err, IsNil, Commentf("test %d", i)) - c.Assert(res, DeepEquals, t.out, Commentf("test %d", i)) - } -} - -var linkFormatTests = []struct { - in []Link - out string -}{ - { - []Link{{URI: "/a", Rel: "foo", Params: map[string]string{"a": "b", "c": "d"}}}, - `; rel="foo"; a="b"; c="d"`, - }, - { - []Link{ - {URI: "/b", Rel: "foo", Params: map[string]string{"a": "b", "c": "d"}}, - {URI: "/a", Rel: "foo", Params: map[string]string{"a": "b", "c": "d"}}}, - `; rel="foo"; a="b"; c="d", ; rel="foo"; a="b"; c="d"`, - }, -} - -func (s *LinkSuite) TestLinkGeneration(c *C) { - for i, t := range linkFormatTests { - res := Format(t.in) - cm := Commentf("test %d", i) - c.Assert(res, Equals, t.out, cm) - parsed, err := Parse(res) - c.Assert(err, IsNil, cm) - c.Assert(parsed, DeepEquals, t.in, cm) - } -} diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/.travis.yml b/Godeps/_workspace/src/github.com/vmware/govcloudair/.travis.yml deleted file mode 100644 index ff7ba7a7c1..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go - -install: - - go get -t ./... - - go get code.google.com/p/go.tools/cmd/cover - - go get github.com/mattn/goveralls - -script: - - PATH="$HOME/gopath/bin:$PATH" - - script/coverage --coveralls \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/Readme.md b/Godeps/_workspace/src/github.com/vmware/govcloudair/Readme.md deleted file mode 100644 index 64a51c7f4c..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/Readme.md +++ /dev/null @@ -1,7 +0,0 @@ -## govcloudair - -This package provides the `govcloudair` package which offers an interface to the vCloud Air 5.6 API. - -It serves as a foundation for a project currently in development, there are plans to make it a general purpose API in the future. - -The API is currently under heavy development, its coverage is extremely limited at the moment. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/api.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/api.go deleted file mode 100644 index 3e778b219e..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/api.go +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -// Package govcloudair provides a simple binding for vCloud Air REST APIs. -package govcloudair - -import ( - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "time" - - types "github.com/vmware/govcloudair/types/v56" -) - -// Client provides a client to vCloud Air, values can be populated automatically using the Authenticate method. -type Client struct { - VAToken string // vCloud Air authorization token - VAEndpoint url.URL // vCloud Air API endpoint - Region string // Region where the compute resource lives. - VCDToken string // Access Token (authorization header) - VCDAuthHeader string // Authorization header - VCDVDCHREF url.URL // HREF of the backend VDC you're using - Http http.Client // HttpClient is the client to use. Default will be used if not provided. -} - -// VCHS API - -type services struct { - Service []struct { - Region string `xml:"region,attr"` - ServiceID string `xml:"serviceId,attr"` - ServiceType string `xml:"serviceType,attr"` - Type string `xml:"type,attr"` - HREF string `xml:"href,attr"` - } `xml:"Service"` -} - -type session struct { - Link []*types.Link `xml:"Link"` -} - -type computeResources struct { - VdcRef []struct { - Status string `xml:"status,attr"` - Name string `xml:"name,attr"` - Type string `xml:"type,attr"` - HREF string `xml:"href,attr"` - Link []*types.Link `xml:"Link"` - } `xml:"VdcRef"` -} - -type vCloudSession struct { - VdcLink []struct { - AuthorizationToken string `xml:"authorizationToken,attr"` - AuthorizationHeader string `xml:"authorizationHeader,attr"` - Name string `xml:"name,attr"` - HREF string `xml:"href,attr"` - } `xml:"VdcLink"` -} - -// - -func (c *Client) vaauthorize(user, pass string) (u url.URL, err error) { - - if user == "" { - user = os.Getenv("VCLOUDAIR_USERNAME") - } - - if pass == "" { - pass = os.Getenv("VCLOUDAIR_PASSWORD") - } - - s := c.VAEndpoint - s.Path += "/vchs/sessions" - - // No point in checking for errors here - req := c.NewRequest(map[string]string{}, "POST", s, nil) - - // Set Basic Authentication Header - req.SetBasicAuth(user, pass) - - // Add the Accept header for vCA - req.Header.Add("Accept", "application/xml;version=5.6") - - resp, err := checkResp(c.Http.Do(req)) - if err != nil { - return url.URL{}, err - } - defer resp.Body.Close() - - // Store the authentication header - c.VAToken = resp.Header.Get("X-Vchs-Authorization") - - session := new(session) - - if err = decodeBody(resp, session); err != nil { - return url.URL{}, fmt.Errorf("error decoding session response: %s", err) - } - - // Loop in the session struct to find right service and compute resource. - for _, s := range session.Link { - if s.Type == "application/xml;class=vnd.vmware.vchs.servicelist" && s.Rel == "down" { - u, err := url.ParseRequestURI(s.HREF) - return *u, err - } - } - return url.URL{}, fmt.Errorf("couldn't find a Service List in current session") -} - -func (c *Client) vaacquireservice(s url.URL, cid string) (u url.URL, err error) { - - if cid == "" { - cid = os.Getenv("VCLOUDAIR_COMPUTEID") - } - - req := c.NewRequest(map[string]string{}, "GET", s, nil) - - // Add the Accept header for vCA - req.Header.Add("Accept", "application/xml;version=5.6") - - // Set Authorization Header for vCA - req.Header.Add("x-vchs-authorization", c.VAToken) - - resp, err := checkResp(c.Http.Do(req)) - if err != nil { - return url.URL{}, fmt.Errorf("error processing compute action: %s", err) - } - - services := new(services) - - if err = decodeBody(resp, services); err != nil { - return url.URL{}, fmt.Errorf("error decoding services response: %s", err) - } - - // Loop in the Services struct to find right service and compute resource. - for _, s := range services.Service { - if s.ServiceID == cid { - c.Region = s.Region - u, err := url.ParseRequestURI(s.HREF) - return *u, err - } - } - return url.URL{}, fmt.Errorf("couldn't find a Compute Resource in current service list") -} - -func (c *Client) vaacquirecompute(s url.URL, vid string) (u url.URL, err error) { - - if vid == "" { - vid = os.Getenv("VCLOUDAIR_VDCID") - } - - req := c.NewRequest(map[string]string{}, "GET", s, nil) - - // Add the Accept header for vCA - req.Header.Add("Accept", "application/xml;version=5.6") - - // Set Authorization Header - req.Header.Add("x-vchs-authorization", c.VAToken) - - // TODO: wrap into checkresp to parse error - resp, err := checkResp(c.Http.Do(req)) - if err != nil { - return url.URL{}, fmt.Errorf("error processing compute action: %s", err) - } - - computeresources := new(computeResources) - - if err = decodeBody(resp, computeresources); err != nil { - return url.URL{}, fmt.Errorf("error decoding computeresources response: %s", err) - } - - // Iterate through the ComputeResources struct searching for the right - // backend server - for _, s := range computeresources.VdcRef { - if s.Name == vid { - for _, t := range s.Link { - if t.Name == vid { - u, err := url.ParseRequestURI(t.HREF) - return *u, err - } - } - } - } - return url.URL{}, fmt.Errorf("couldn't find a VDC Resource in current Compute list") -} - -func (c *Client) vagetbackendauth(s url.URL, cid string) error { - - if cid == "" { - cid = os.Getenv("VCLOUDAIR_COMPUTEID") - } - - req := c.NewRequest(map[string]string{}, "POST", s, nil) - - // Add the Accept header for vCA - req.Header.Add("Accept", "application/xml;version=5.6") - - // Set Authorization Header - req.Header.Add("x-vchs-authorization", c.VAToken) - - // TODO: wrap into checkresp to parse error - resp, err := checkResp(c.Http.Do(req)) - if err != nil { - return fmt.Errorf("error processing backend url action: %s", err) - } - defer resp.Body.Close() - - vcloudsession := new(vCloudSession) - - if err = decodeBody(resp, vcloudsession); err != nil { - return fmt.Errorf("error decoding vcloudsession response: %s", err) - } - - // Get the backend session information - for _, s := range vcloudsession.VdcLink { - if s.Name == cid { - // Fetch the authorization token - c.VCDToken = s.AuthorizationToken - - // Fetch the authorization header - c.VCDAuthHeader = s.AuthorizationHeader - - u, err := url.ParseRequestURI(s.HREF) - if err != nil { - return fmt.Errorf("error decoding href: %s", err) - } - c.VCDVDCHREF = *u - return nil - } - } - return fmt.Errorf("error finding the right backend resource") -} - -// NewClient returns a new empty client to authenticate against the vCloud Air -// service, the vCloud Air endpoint can be overridden by setting the -// VCLOUDAIR_ENDPOINT environment variable. -func NewClient() (*Client, error) { - - var u *url.URL - var err error - - if os.Getenv("VCLOUDAIR_ENDPOINT") != "" { - u, err = url.ParseRequestURI(os.Getenv("VCLOUDAIR_ENDPOINT")) - if err != nil { - return &Client{}, fmt.Errorf("cannot parse endpoint coming from VCLOUDAIR_ENDPOINT") - } - } else { - // Implicitly trust this URL parse. - u, _ = url.ParseRequestURI("https://vchs.vmware.com/api") - } - - Client := Client{ - VAEndpoint: *u, - // Patching things up as we're hitting several TLS timeouts. - Http: http.Client{Transport: &http.Transport{TLSHandshakeTimeout: 120 * time.Second}}, - } - return &Client, nil -} - -// Authenticate is an helper function that performs a complete login in vCloud -// Air and in the backend vCloud Director instance. -func (c *Client) Authenticate(username, password, computeid, vdcid string) (Vdc, error) { - // Authorize - vaservicehref, err := c.vaauthorize(username, password) - if err != nil { - return Vdc{}, fmt.Errorf("error Authorizing: %s", err) - } - - // Get Service - vacomputehref, err := c.vaacquireservice(vaservicehref, computeid) - if err != nil { - return Vdc{}, fmt.Errorf("error Acquiring Service: %s", err) - } - - // Get Compute - vavdchref, err := c.vaacquirecompute(vacomputehref, vdcid) - if err != nil { - return Vdc{}, fmt.Errorf("error Acquiring Compute: %s", err) - } - - // Get Backend Authorization - if err = c.vagetbackendauth(vavdchref, computeid); err != nil { - return Vdc{}, fmt.Errorf("error Acquiring Backend Authorization: %s", err) - } - - v, err := c.retrieveVDC() - if err != nil { - return Vdc{}, fmt.Errorf("error Acquiring VDC: %s", err) - } - - return v, nil - -} - -// NewRequest creates a new HTTP request and applies necessary auth headers if -// set. -func (c *Client) NewRequest(params map[string]string, method string, u url.URL, body io.Reader) *http.Request { - - p := url.Values{} - - // Build up our request parameters - for k, v := range params { - p.Add(k, v) - } - - // Add the params to our URL - u.RawQuery = p.Encode() - - // Build the request, no point in checking for errors here as we're just - // passing a string version of an url.URL struct and http.NewRequest returns - // error only if can't process an url.ParseRequestURI(). - req, _ := http.NewRequest(method, u.String(), body) - - if c.VCDAuthHeader != "" && c.VCDToken != "" { - // Add the authorization header - req.Header.Add(c.VCDAuthHeader, c.VCDToken) - // Add the Accept header for VCD - req.Header.Add("Accept", "application/*+xml;version=5.6") - } - - return req - -} - -// Disconnect performs a disconnection from the vCloud Air API endpoint. -func (c *Client) Disconnect() error { - if c.VCDToken == "" && c.VCDAuthHeader == "" && c.VAToken == "" { - return fmt.Errorf("cannot disconnect, client is not authenticated") - } - - s := c.VAEndpoint - s.Path += "/vchs/session" - - req := c.NewRequest(map[string]string{}, "DELETE", s, nil) - - // Add the Accept header for vCA - req.Header.Add("Accept", "application/xml;version=5.6") - - // Set Authorization Header - req.Header.Add("x-vchs-authorization", c.VAToken) - - if _, err := checkResp(c.Http.Do(req)); err != nil { - return fmt.Errorf("error processing session delete for vchs: %s", err) - } - - return nil -} - -// parseErr takes an error XML resp and returns a single string for use in error messages. -func parseErr(resp *http.Response) error { - - errBody := new(types.Error) - - // if there was an error decoding the body, just return that - if err := decodeBody(resp, errBody); err != nil { - return fmt.Errorf("error parsing error body for non-200 request: %s", err) - } - - return fmt.Errorf("API Error: %d: %s", errBody.MajorErrorCode, errBody.Message) -} - -// decodeBody is used to XML decode a response body -func decodeBody(resp *http.Response, out interface{}) error { - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - - // Unmarshal the XML. - if err = xml.Unmarshal(body, &out); err != nil { - return err - } - - return nil -} - -// checkResp wraps http.Client.Do() and verifies the request, if status code -// is 2XX it passes back the response, if it's a known invalid status code it -// parses the resultant XML error and returns a descriptive error, if the -// status code is not handled it returns a generic error with the status code. -func checkResp(resp *http.Response, err error) (*http.Response, error) { - if err != nil { - return resp, err - } - - switch i := resp.StatusCode; { - // Valid request, return the response. - case i == 200 || i == 201 || i == 202 || i == 204: - return resp, nil - // Invalid request, parse the XML error returned and return it. - case i == 400 || i == 401 || i == 403 || i == 404 || i == 405 || i == 406 || i == 409 || i == 415 || i == 500 || i == 503 || i == 504: - return nil, parseErr(resp) - // Unhandled response. - default: - return nil, fmt.Errorf("unhandled API response, please report this issue, status code: %s", resp.Status) - } -} diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/api_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/api_test.go deleted file mode 100644 index e033a09868..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/api_test.go +++ /dev/null @@ -1,749 +0,0 @@ -/* - * @Author: frapposelli - * @Project: govcloudair - * @Filename: api_test.go - * @Last Modified by: frapposelli - */ - -package govcloudair - -import ( - "net/url" - "os" - "testing" - - "github.com/vmware/govcloudair/testutil" - . "gopkg.in/check.v1" -) - -var au, _ = url.ParseRequestURI("http://localhost:4444/api") -var aus, _ = url.ParseRequestURI("http://localhost:4444/api/vchs/services") -var auc, _ = url.ParseRequestURI("http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000") -var aucs, _ = url.ParseRequestURI("http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession") - -func Test(t *testing.T) { TestingT(t) } - -type S struct { - client *Client - vdc Vdc - vapp *VApp -} - -var _ = Suite(&S{}) - -var testServer = testutil.NewHTTPServer() - -var authheader = map[string]string{"x-vchs-authorization": "012345678901234567890123456789"} - -func (s *S) SetUpSuite(c *C) { - testServer.Start() - var err error - - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - - s.client, err = NewClient() - if err != nil { - panic(err) - } - - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - s.vdc, err = s.client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - s.vapp = NewVApp(s.client) - _ = testServer.WaitRequests(5) - testServer.Flush() - if err != nil { - panic(err) - } -} - -func (s *S) TearDownTest(c *C) { - testServer.Flush() -} - -func TestClient_vaauthorize(t *testing.T) { - testServer.Start() - var err error - - // Set up a working client - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - - // Set up a correct conversation - testServer.Response(201, authheader, vaauthorization) - _, err = client.vaauthorize("username", "password") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - // Test if token is correctly set on client. - if client.VAToken != "012345678901234567890123456789" { - t.Fatalf("VAtoken not set on client: %s", client.VAToken) - } - - // Test client errors - - // Test a correct response with a wrong status code - testServer.Response(404, authheader, notfoundErr) - _, err = client.vaauthorize("username", "password") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an API error - testServer.Response(500, authheader, vcdError) - _, err = client.vaauthorize("username", "password") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an API response that doesn't contain the param we're looking for. - testServer.Response(200, authheader, vaauthorizationErr) - _, err = client.vaauthorize("username", "password") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an un-parsable response. - testServer.Response(200, authheader, notfoundErr) - _, err = client.vaauthorize("username", "password") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - -} - -func TestClient_vaacquireservice(t *testing.T) { - testServer.Start() - var err error - - // Set up a working client - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - client.VAToken = "012345678901234567890123456789" - - // Test a correct conversation - testServer.Response(200, nil, vaservices) - vacomputehref, err := client.vaacquireservice(*aus, "CI123456-789") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if vacomputehref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000" { - t.Fatalf("VAComputeHREF not set on client: %s", vacomputehref) - } - - if client.Region != "US - Anywhere" { - t.Fatalf("Region not set on client: %s", client.Region) - } - - // Test client errors - - // Test a 404 - testServer.Response(404, nil, notfoundErr) - _, err = client.vaacquireservice(*aus, "CI123456-789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an API error - testServer.Response(500, nil, vcdError) - _, err = client.vaacquireservice(*aus, "CI123456-789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an unknown Compute ID - testServer.Response(200, nil, vaservices) - _, err = client.vaacquireservice(*aus, "NOTVALID-789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an un-parsable response - testServer.Response(200, nil, notfoundErr) - _, err = client.vaacquireservice(*aus, "CI123456-789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - -} - -func TestClient_vaacquirecompute(t *testing.T) { - testServer.Start() - var err error - - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - client.VAToken = "012345678901234567890123456789" - client.Region = "US - Anywhere" - - testServer.Response(200, nil, vacompute) - vavdchref, err := client.vaacquirecompute(*auc, "VDC12345-6789") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if vavdchref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" { - t.Fatalf("VAVDCHREF not set on client: %s", vavdchref) - } - - // Test client errors - - // Test a 404 - testServer.Response(404, nil, notfoundErr) - _, err = client.vaacquirecompute(*auc, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - // Test an API error - testServer.Response(500, nil, vcdError) - _, err = client.vaacquirecompute(*auc, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an unknown VDC ID - testServer.Response(200, nil, vacompute) - _, err = client.vaacquirecompute(*auc, "INVALID-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - - // Test an un-parsable response - testServer.Response(200, nil, notfoundErr) - _, err = client.vaacquirecompute(*auc, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - -} - -func TestClient_vagetbackendauth(t *testing.T) { - testServer.Start() - var err error - - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - client.VAToken = "012345678901234567890123456789" - client.Region = "US - Anywhere" - - testServer.Response(201, nil, vabackend) - err = client.vagetbackendauth(*aucs, "CI123456-789") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if client.VCDToken != "01234567890123456789012345678901" { - t.Fatalf("VCDToken not set on client: %s", client.VCDToken) - } - if client.VCDAuthHeader != "x-vcloud-authorization" { - t.Fatalf("VCDAuthHeader not set on client: %s", client.VCDAuthHeader) - } - if client.VCDVDCHREF.String() != "http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" { - t.Fatalf("VDC not set on client: %s", client.VCDVDCHREF) - } - - // Test client errors - - // Test a 404 - testServer.Response(404, nil, notfoundErr) - err = client.vagetbackendauth(*aucs, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - // Test an API error - testServer.Response(500, nil, vcdError) - err = client.vagetbackendauth(*aucs, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - // Test an unknown backend VDC IC - testServer.Response(201, nil, vabackend) - err = client.vagetbackendauth(*aucs, "INVALID-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - // Test an un-parsable response - testServer.Response(201, nil, notfoundErr) - err = client.vagetbackendauth(*aucs, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - // Test a botched backend VDC IC - testServer.Response(201, nil, vabackendErr) - err = client.vagetbackendauth(*aucs, "VDC12345-6789") - _ = testServer.WaitRequest() - if err == nil { - t.Fatalf("Request error not caught: %v", err) - } - -} - -// Env variable tests - -func TestClient_vaauthorize_env(t *testing.T) { - - os.Setenv("VCLOUDAIR_USERNAME", "username") - os.Setenv("VCLOUDAIR_PASSWORD", "password") - - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - - testServer.Response(201, authheader, vaauthorization) - _, err = client.vaauthorize("", "") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if client.VAToken != "012345678901234567890123456789" { - t.Fatalf("VAtoken not set on client: %s", client.VAToken) - } - -} - -func TestClient_vaacquireservice_env(t *testing.T) { - - os.Setenv("VCLOUDAIR_COMPUTEID", "CI123456-789") - - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - client.VAToken = "012345678901234567890123456789" - - testServer.Response(200, nil, vaservices) - vacomputehref, err := client.vaacquireservice(*aus, "") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if vacomputehref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000" { - t.Fatalf("VAComputeHREF not set on client: %s", vacomputehref) - } - - if client.Region != "US - Anywhere" { - t.Fatalf("Region not set on client: %s", client.Region) - } - -} - -func TestClient_vaacquirecompute_env(t *testing.T) { - - os.Setenv("VCLOUDAIR_VDCID", "VDC12345-6789") - - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - client.VAToken = "012345678901234567890123456789" - client.Region = "US - Anywhere" - - testServer.Response(200, nil, vacompute) - vavdchref, err := client.vaacquirecompute(*auc, "") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if vavdchref.String() != "http://localhost:4444/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession" { - t.Fatalf("VAVDCHREF not set on client: %s", vavdchref) - } - -} - -func TestClient_vagetbackendauth_env(t *testing.T) { - - os.Setenv("VCLOUDAIR_VDCID", "VDC12345-6789") - - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - client.VAToken = "012345678901234567890123456789" - client.Region = "US - Anywhere" - - testServer.Response(201, nil, vabackend) - err = client.vagetbackendauth(*aucs, "") - _ = testServer.WaitRequest() - if err != nil { - t.Fatalf("err: %v", err) - } - - if client.VCDToken != "01234567890123456789012345678901" { - t.Fatalf("VCDToken not set on client: %s", client.VCDToken) - } - if client.VCDAuthHeader != "x-vcloud-authorization" { - t.Fatalf("VCDAuthHeader not set on client: %s", client.VCDAuthHeader) - } - if client.VCDVDCHREF.String() != "http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" { - t.Fatalf("VDC not set on client: %s", client.VCDVDCHREF) - } - -} - -func TestClient_NewClient(t *testing.T) { - - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "") - if _, err = NewClient(); err != nil { - t.Fatalf("err: %v", err) - } - - os.Setenv("VCLOUDAIR_ENDPOINT", "💩") - if _, err = NewClient(); err == nil { - t.Fatalf("err: %v", err) - } - -} - -func TestClient_Disconnect(t *testing.T) { - - testServer.Start() - var err error - - // Test an authenticated client - c := makeClient(t) - testServer.Response(201, nil, "") - err = c.Disconnect() - if err != nil { - t.Fatalf("err: %v", err) - } - - // Test an empty client - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - err = client.Disconnect() - if err == nil { - t.Fatalf("err: %v", err) - } - -} - -func TestClient_Authenticate(t *testing.T) { - - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - - // Botched auth - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{401, nil, vcdError}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - _ = testServer.WaitRequests(1) - testServer.Flush() - if err == nil { - t.Fatalf("Uncatched error: %v", err) - } - - // Botched services - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{500, nil, vcdError}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - _ = testServer.WaitRequests(2) - testServer.Flush() - if err == nil { - t.Fatalf("Uncatched error: %v", err) - } - - // Botched compute - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{500, nil, vcdError}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - _ = testServer.WaitRequests(3) - testServer.Flush() - if err == nil { - t.Fatalf("Uncatched error: %v", err) - } - - // Botched backend - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{500, nil, vcdError}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - _ = testServer.WaitRequests(4) - testServer.Flush() - if err == nil { - t.Fatalf("Uncatched error: %v", err) - } - - // Botched vdc - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{500, nil, vcdError}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - _ = testServer.WaitRequests(5) - testServer.Flush() - if err == nil { - t.Fatalf("Uncatched error: %v", err) - } - -} - -func makeClient(t *testing.T) Client { - - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{201, nil, vabackend}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - - _ = testServer.WaitRequests(5) - testServer.Flush() - - if err != nil { - t.Fatalf("err: %v", err) - } - - if client.VAToken != "012345678901234567890123456789" { - t.Fatalf("VAtoken not set on client: %s", client.VAToken) - } - - if client.Region != "US - Anywhere" { - t.Fatalf("Region not set on client: %s", client.Region) - } - - if client.VCDToken != "01234567890123456789012345678901" { - t.Fatalf("VCDToken not set on client: %s", client.VCDToken) - } - if client.VCDAuthHeader != "x-vcloud-authorization" { - t.Fatalf("VCDAuthHeader not set on client: %s", client.VCDAuthHeader) - } - if client.VCDVDCHREF.String() != "http://localhost:4444/api/vdc/00000000-0000-0000-0000-000000000000" { - t.Fatalf("VDC not set on client: %s", client.VCDVDCHREF) - } - - return *client -} - -func TestClient_parseErr(t *testing.T) { - testServer.Start() - var err error - os.Setenv("VCLOUDAIR_ENDPOINT", "http://localhost:4444/api") - client, err := NewClient() - if err != nil { - t.Fatalf("err: %v", err) - } - - // I'M A TEAPOT! - testServer.ResponseMap(5, testutil.ResponseMap{ - "/api/vchs/sessions": testutil.Response{201, authheader, vaauthorization}, - "/api/vchs/services": testutil.Response{200, nil, vaservices}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vacompute}, - "/api/vchs/compute/00000000-0000-0000-0000-000000000000/vdc/00000000-0000-0000-0000-000000000000/vcloudsession": testutil.Response{418, nil, notfoundErr}, - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - }) - - _, err = client.Authenticate("username", "password", "CI123456-789", "VDC12345-6789") - - _ = testServer.WaitRequests(4) - testServer.Flush() - - if err == nil { - t.Fatalf("Uncatched error: %v", err) - } - -} - -func TestClient_NewRequest(t *testing.T) { - c := makeClient(t) - - params := map[string]string{ - "foo": "bar", - "baz": "bar", - } - - uri, _ := url.ParseRequestURI("http://localhost:4444/api/bar") - - req := c.NewRequest(params, "POST", *uri, nil) - - encoded := req.URL.Query() - if encoded.Get("foo") != "bar" { - t.Fatalf("bad: %v", encoded) - } - - if encoded.Get("baz") != "bar" { - t.Fatalf("bad: %v", encoded) - } - - if req.URL.String() != "http://localhost:4444/api/bar?baz=bar&foo=bar" { - t.Fatalf("bad base url: %v", req.URL.String()) - } - - if req.Header.Get("x-vcloud-authorization") != "01234567890123456789012345678901" { - t.Fatalf("bad auth header: %v", req.Header) - } - - if req.Method != "POST" { - t.Fatalf("bad method: %v", req.Method) - } - -} - -// status: 404 -var notfoundErr = ` - - 404 Not Found - -

404 Not Found

-
nginx/1.4.6 (Ubuntu)
- - - ` - -// status: 201 -var vaauthorization = ` - - - - - - ` -var vaauthorizationErr = ` - - - - - ` - -// status: 200 -var vaservices = ` - - - - - ` - -// status: 200 -var vacompute = ` - - - - - - - - ` - -// status: 201 -var vabackend = ` - - - - - - ` - -// status: 201 -var vabackendErr = ` - - - - - - ` - -var vcdError = ` - - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/catalog_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/catalog_test.go deleted file mode 100644 index 8c8cd74ce2..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/catalog_test.go +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - . "gopkg.in/check.v1" -) - -func (s *S) Test_FindCatalogItem(c *C) { - - // Get the Org populated - testServer.Response(200, nil, orgExample) - org, err := s.vdc.GetVDCOrg() - _ = testServer.WaitRequest() - testServer.Flush() - c.Assert(err, IsNil) - - // Populate Catalog - testServer.Response(200, nil, catalogExample) - cat, err := org.FindCatalog("Public Catalog") - _ = testServer.WaitRequest() - testServer.Flush() - - // Find Catalog Item - testServer.Response(200, nil, catalogitemExample) - catitem, err := cat.FindCatalogItem("CentOS64-32bit") - _ = testServer.WaitRequest() - testServer.Flush() - - c.Assert(err, IsNil) - c.Assert(catitem.CatalogItem.HREF, Equals, "http://localhost:4444/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae") - c.Assert(catitem.CatalogItem.Description, Equals, "id: cts-6.4-32bit") - - // Test non-existant catalog item - catitem, err = cat.FindCatalogItem("INVALID") - c.Assert(err, NotNil) - -} - -var catalogExample = ` - - - - vCHS service catalog - - - - - - - - - - - - - - - - - - true - 2013-10-15T01:14:22.370Z - 60 - -` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem_test.go deleted file mode 100644 index 4b526c9213..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - . "gopkg.in/check.v1" -) - -func (s *S) Test_GetVAppTemplate(c *C) { - - // Get the Org populated - testServer.Response(200, nil, orgExample) - org, err := s.vdc.GetVDCOrg() - _ = testServer.WaitRequest() - testServer.Flush() - c.Assert(err, IsNil) - - // Populate Catalog - testServer.Response(200, nil, catalogExample) - cat, err := org.FindCatalog("Public Catalog") - _ = testServer.WaitRequest() - testServer.Flush() - - // Populate Catalog Item - testServer.Response(200, nil, catalogitemExample) - catitem, err := cat.FindCatalogItem("CentOS64-32bit") - _ = testServer.WaitRequest() - testServer.Flush() - - // Get VAppTemplate - testServer.Response(200, nil, vapptemplateExample) - vapptemplate, err := catitem.GetVAppTemplate() - _ = testServer.WaitRequest() - testServer.Flush() - - c.Assert(err, IsNil) - c.Assert(vapptemplate.VAppTemplate.HREF, Equals, "http://localhost:4444/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5") - c.Assert(vapptemplate.VAppTemplate.Name, Equals, "CentOS64-32bit") - c.Assert(vapptemplate.VAppTemplate.Description, Equals, "id: cts-6.4-32bit") - -} - -var catalogitemExample = ` - - - - - id: cts-6.4-32bit - - 2014-06-04T21:06:43.750Z - 4 - -` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway_test.go deleted file mode 100644 index 70217e2503..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway_test.go +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - "github.com/vmware/govcloudair/testutil" - - . "gopkg.in/check.v1" -) - -func (s *S) Test_Refresh(c *C) { - - // Get the Org populated - testServer.ResponseMap(2, testutil.ResponseMap{ - "/api/vdc/00000000-0000-0000-0000-000000000000/edgeGateways": testutil.Response{200, nil, edgegatewayqueryresultsExample}, - "/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample}, - }) - - edge, err := s.vdc.FindEdgeGateway("M916272752-5793") - _ = testServer.WaitRequests(2) - testServer.Flush() - - c.Assert(err, IsNil) - c.Assert(edge.EdgeGateway.Name, Equals, "M916272752-5793") - - testServer.Response(200, nil, edgegatewayExample) - err = edge.Refresh() - _ = testServer.WaitRequest() - testServer.Flush() - - c.Assert(err, IsNil) - c.Assert(edge.EdgeGateway.Name, Equals, "M916272752-5793") - -} - -func (s *S) Test_1to1Mappings(c *C) { - - testServer.ResponseMap(2, testutil.ResponseMap{ - "/api/vdc/00000000-0000-0000-0000-000000000000/edgeGateways": testutil.Response{200, nil, edgegatewayqueryresultsExample}, - "/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample}, - }) - - edge, err := s.vdc.FindEdgeGateway("M916272752-5793") - _ = testServer.WaitRequests(2) - testServer.Flush() - - c.Assert(err, IsNil) - c.Assert(edge.EdgeGateway.Name, Equals, "M916272752-5793") - - testServer.ResponseMap(2, testutil.ResponseMap{ - "/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample}, - "/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/configureServices": testutil.Response{200, nil, taskExample}, - }) - - _, err = edge.Create1to1Mapping("10.0.0.1", "20.0.0.2", "description") - _ = testServer.WaitRequests(2) - - c.Assert(err, IsNil) - - testServer.ResponseMap(2, testutil.ResponseMap{ - "/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, edgegatewayExample}, - "/api/admin/edgeGateway/00000000-0000-0000-0000-000000000000/action/configureServices": testutil.Response{200, nil, taskExample}, - }) - - _, err = edge.Remove1to1Mapping("10.0.0.1", "20.0.0.2") - _ = testServer.WaitRequests(2) - - c.Assert(err, IsNil) - -} - -var edgegatewayqueryresultsExample = ` - - - - - -` - -var edgegatewayExample = ` - - - - - - - - compact - - - JGray Network - JGray Network - - internal - - 192.168.108.1 - 255.255.255.0 - 192.168.108.1 - - false - false - - - M916272752-5793-default-routed - M916272752-5793-default-routed - - internal - - 192.168.109.1 - 255.255.255.0 - 192.168.109.1 - - false - false - - - d2p3-ext - d2p3-ext - - uplink - - 23.92.224.1 - 255.255.254.0 - 23.92.225.51 - - - 23.92.225.73 - 23.92.225.75 - - - 23.92.225.27 - 23.92.225.27 - - - 23.92.225.11 - 23.92.225.11 - - - 23.92.225.54 - 23.92.225.54 - - - 23.92.224.34 - 23.92.224.34 - - - 23.92.225.5 - 23.92.225.5 - - - 23.92.225.34 - 23.92.225.34 - - - 23.92.224.255 - 23.92.224.255 - - - 23.92.225.49 - 23.92.225.51 - - - 23.92.225.62 - 23.92.225.62 - - - 23.92.225.43 - 23.92.225.43 - - - 23.92.225.30 - 23.92.225.30 - - - - true - 1024.0 - 1024.0 - true - - - - - true - drop - false - - 1 - true - false - ssh prd-001 - allow - - true - - 999 - 999 - 23.92.225.51 - -1 - Any - 60.241.110.111 - false - - - 2 - true - false - inet prd-001 - allow - - true - - -1 - Any - Any - -1 - Any - 192.168.109.8 - false - - - 3 - true - false - suppah megah rulez creati0nz - allow - - true - - -1 - Any - 23.92.224.255 - -1 - Any - Any - false - - - 4 - true - false - suppah megah rulez creati0nz - allow - - true - - -1 - Any - Any - -1 - Any - 192.168.109.3 - false - - - - false - - DNAT - true - 65537 - - - 23.92.225.51 - 999 - 192.168.109.8 - 22 - Tcp - - - - SNAT - true - 65538 - - - 192.168.109.8 - 23.92.225.51 - - - - SNAT - true - 65539 - - - 192.168.109.3 - 23.92.224.255 - - - - DNAT - true - 65540 - - - 23.92.224.255 - any - 192.168.109.3 - any - any - - - - - true - - Test VPN Alpha - For OC Pod Testing - - 192.168.110.99 - - 64.184.133.62 - 192.168.110.99 - 23.92.225.51 - 23.92.225.51 - - M916272752-5793-default-routed - 192.168.109.1 - 255.255.255.0 - - - 192.168.120.0/24 - 192.168.120.0 - 255.255.255.0 - - Blah1Blah2Blah3Blah1Blah2Blah3Blah1Blah2Blah3 - false - AES256 - 1500 - true - false - - - JGray VPN - - 67.172.148.74 - - 67.172.148.74 - 67.172.148.74 - 23.92.225.51 - 23.92.225.51 - - JGray Network - 192.168.108.1 - 255.255.255.0 - - - 192.168.1.0/24 - 192.168.1.0 - 255.255.255.0 - - fM7puHkGbg6tqpd4jKNhBo45mbs8fw3yapgt3H7f97a2jrkLyYjP9eSH4oGwps7u - false - AES256 - 1500 - false - false - - - - false - - - false - - - true - true - - - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/org_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/org_test.go deleted file mode 100644 index 401d430804..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/org_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - . "gopkg.in/check.v1" -) - -func (s *S) Test_FindCatalog(c *C) { - - // Get the Org populated - testServer.Response(200, nil, orgExample) - org, err := s.vdc.GetVDCOrg() - _ = testServer.WaitRequest() - testServer.Flush() - c.Assert(err, IsNil) - - // Find Catalog - testServer.Response(200, nil, catalogExample) - cat, err := org.FindCatalog("Public Catalog") - _ = testServer.WaitRequest() - testServer.Flush() - c.Assert(err, IsNil) - c.Assert(cat.Catalog.Description, Equals, "vCHS service catalog") - -} - -var orgExample = ` - - - - - - - - - - - - - - - - - - - - - - - OrganizationName - - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork_test.go deleted file mode 100644 index a230d5ef0c..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork_test.go +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -var orgvdcnetExample = ` - - - - - - This routed network was created with Create VDC. - - - - false - 192.168.109.1 - 255.255.255.0 - true - - - 192.168.109.2 - 192.168.109.100 - - - - - natRouted - false - - false - - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/script/coverage b/Godeps/_workspace/src/github.com/vmware/govcloudair/script/coverage deleted file mode 100755 index 5ffa996a35..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/script/coverage +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# Generate test coverage statistics for Go packages. -# -# Works around the fact that `go test -coverprofile` currently does not work -# with multiple packages, see https://code.google.com/p/go/issues/detail?id=6909 -# -# Usage: script/coverage [--html|--coveralls] -# -# --html Additionally create HTML report and open it in browser -# --coveralls Push coverage statistics to coveralls.io -# - -set -e - -workdir=.cover -profile="$workdir/cover.out" -mode=count - -generate_cover_data() { - rm -rf "$workdir" - mkdir "$workdir" - - for pkg in "$@"; do - f="$workdir/$(echo $pkg | tr / -).cover" - go test -covermode="$mode" -coverprofile="$f" "$pkg" - done - - echo "mode: $mode" >"$profile" - grep -h -v "^mode:" "$workdir"/*.cover >>"$profile" -} - -show_cover_report() { - go tool cover -${1}="$profile" -} - -push_to_coveralls() { - echo "Pushing coverage statistics to coveralls.io" - goveralls -coverprofile="$profile" -} - -generate_cover_data $(go list ./...) -show_cover_report func -case "$1" in -"") - ;; ---html) - show_cover_report html ;; ---coveralls) - push_to_coveralls ;; -*) - echo >&2 "error: invalid option: $1"; exit 1 ;; -esac \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/task_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/task_test.go deleted file mode 100644 index f743772463..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/task_test.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - . "gopkg.in/check.v1" -) - -func (s *S) Test_WaitTaskCompletion(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Deploy() - _ = testServer.WaitRequest() - testServer.Flush() - c.Assert(err, IsNil) - - testServer.Response(200, nil, taskExample) - err = task.WaitTaskCompletion() - _ = testServer.WaitRequest() - testServer.Flush() - c.Assert(err, IsNil) - -} - -var taskExample = ` - - - - - 100 -
- - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/testutil/http.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/testutil/http.go deleted file mode 100644 index 5ce9e66c59..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/testutil/http.go +++ /dev/null @@ -1,186 +0,0 @@ -// -// The software in this package is published under the terms of the Mozilla -// Public License, version 2.0 a copy of which has been included with this -// distribution in the LICENSE file. -// - -package testutil - -import ( - "bytes" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "time" -) - -type HTTPServer struct { - URL string - Timeout time.Duration - started bool - request chan *http.Request - response chan ResponseFunc -} - -type Response struct { - Status int - Headers map[string]string - Body string -} - -var DefaultClient = &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - }, -} - -func NewHTTPServer() *HTTPServer { - return &HTTPServer{URL: "http://localhost:4444", Timeout: 5 * time.Second} -} - -type ResponseFunc func(path string) Response - -func (s *HTTPServer) Start() { - if s.started { - return - } - s.started = true - s.request = make(chan *http.Request, 1024) - s.response = make(chan ResponseFunc, 1024) - u, err := url.Parse(s.URL) - if err != nil { - panic(err) - } - l, err := net.Listen("tcp", u.Host) - if err != nil { - panic(err) - } - go http.Serve(l, s) - - s.Response(203, nil, "") - for { - // Wait for it to be up. - resp, err := http.Get(s.URL) - if err == nil && resp.StatusCode == 203 { - break - } - time.Sleep(1e8) - } - s.WaitRequest() // Consume dummy request. -} - -// Flush discards all pending requests and responses. -func (s *HTTPServer) Flush() { - for { - select { - case <-s.request: - case <-s.response: - default: - return - } - } -} - -func body(req *http.Request) string { - data, err := ioutil.ReadAll(req.Body) - if err != nil { - panic(err) - } - return string(data) -} - -func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { - req.ParseMultipartForm(1e6) - data, err := ioutil.ReadAll(req.Body) - if err != nil { - panic(err) - } - req.Body = ioutil.NopCloser(bytes.NewBuffer(data)) - s.request <- req - var resp Response - select { - case respFunc := <-s.response: - resp = respFunc(req.URL.Path) - case <-time.After(s.Timeout): - const msg = "ERROR: Timeout waiting for test to prepare a response\n" - fmt.Fprintf(os.Stderr, msg) - resp = Response{500, nil, msg} - } - if resp.Headers != nil { - h := w.Header() - for k, v := range resp.Headers { - h.Set(k, v) - } - } - if resp.Status != 0 { - w.WriteHeader(resp.Status) - } - w.Write([]byte(resp.Body)) -} - -// WaitRequests returns the next n requests made to the http server from -// the queue. If not enough requests were previously made, it waits until -// the timeout value for them to be made. -func (s *HTTPServer) WaitRequests(n int) []*http.Request { - reqs := make([]*http.Request, 0, n) - for i := 0; i < n; i++ { - select { - case req := <-s.request: - reqs = append(reqs, req) - case <-time.After(s.Timeout): - panic("Timeout waiting for request") - } - } - return reqs -} - -// WaitRequest returns the next request made to the http server from -// the queue. If no requests were previously made, it waits until the -// timeout value for one to be made. -func (s *HTTPServer) WaitRequest() *http.Request { - return s.WaitRequests(1)[0] -} - -// ResponseFunc prepares the test server to respond the following n -// requests using f to build each response. -func (s *HTTPServer) ResponseFunc(n int, f ResponseFunc) { - for i := 0; i < n; i++ { - s.response <- f - } -} - -// ResponseMap maps request paths to responses. -type ResponseMap map[string]Response - -// ResponseMap prepares the test server to respond the following n -// requests using the m to obtain the responses. -func (s *HTTPServer) ResponseMap(n int, m ResponseMap) { - f := func(path string) Response { - for rpath, resp := range m { - if rpath == path { - return resp - } - } - body := "Path not found in response map: " + path - return Response{Status: 500, Body: body} - } - s.ResponseFunc(n, f) -} - -// Responses prepares the test server to respond the following n requests -// using the provided response parameters. -func (s *HTTPServer) Responses(n int, status int, headers map[string]string, body string) { - f := func(path string) Response { - return Response{status, headers, body} - } - s.ResponseFunc(n, f) -} - -// Response prepares the test server to respond the following request -// using the provided response parameters. -func (s *HTTPServer) Response(status int, headers map[string]string, body string) { - s.Responses(1, status, headers, body) -} diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/vapp_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/vapp_test.go deleted file mode 100644 index a218d1d70a..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/vapp_test.go +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - "github.com/vmware/govcloudair/testutil" - - . "gopkg.in/check.v1" -) - -func (s *S) Test_ComposeVApp(c *C) { - - testServer.ResponseMap(7, testutil.ResponseMap{ - "/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample}, - "/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample}, - "/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample}, - "/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample}, - "/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample}, - "/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample}, - "/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample}, - }) - - // Get the Org populated - org, err := s.vdc.GetVDCOrg() - c.Assert(err, IsNil) - - // Populate OrgVDCNetwork - net, err := s.vdc.FindVDCNetwork("networkName") - c.Assert(err, IsNil) - - // Populate Catalog - cat, err := org.FindCatalog("Public Catalog") - c.Assert(err, IsNil) - - // Populate Catalog Item - catitem, err := cat.FindCatalogItem("CentOS64-32bit") - c.Assert(err, IsNil) - - // Get VAppTemplate - vapptemplate, err := catitem.GetVAppTemplate() - c.Assert(err, IsNil) - - // Compose VApp - task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description") - c.Assert(err, IsNil) - c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp") - c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000") - - status, err := s.vapp.GetStatus() - - c.Assert(err, IsNil) - c.Assert(status, Equals, "POWERED_OFF") - - _ = testServer.WaitRequests(7) - -} - -func (s *S) Test_PowerOn(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.PowerOn() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_PowerOff(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.PowerOff() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Reboot(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Reboot() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Reset(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Reset() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Suspend(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Suspend() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Shutdown(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Shutdown() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Undeploy(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Undeploy() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Deploy(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Deploy() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_Delete(c *C) { - - testServer.Response(200, nil, taskExample) - task, err := s.vapp.Delete() - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - -} - -func (s *S) Test_RunCustomizationScript(c *C) { - - testServer.ResponseMap(8, testutil.ResponseMap{ - "/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample}, - "/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample}, - "/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample}, - "/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample}, - "/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample}, - "/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample}, - "/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample}, - "/api/vApp/vm-00000000-0000-0000-0000-000000000000/guestCustomizationSection/": testutil.Response{200, nil, taskExample}, - }) - - // Get the Org populated - org, err := s.vdc.GetVDCOrg() - c.Assert(err, IsNil) - - // Populate OrgVDCNetwork - net, err := s.vdc.FindVDCNetwork("networkName") - c.Assert(err, IsNil) - - // Populate Catalog - cat, err := org.FindCatalog("Public Catalog") - c.Assert(err, IsNil) - - // Populate Catalog Item - catitem, err := cat.FindCatalogItem("CentOS64-32bit") - c.Assert(err, IsNil) - - // Get VAppTemplate - vapptemplate, err := catitem.GetVAppTemplate() - c.Assert(err, IsNil) - - // Compose VApp - task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description") - c.Assert(err, IsNil) - c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp") - c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000") - - task, err = s.vapp.RunCustomizationScript("computername", "this is my script") - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - - _ = testServer.WaitRequests(8) - -} - -func (s *S) Test_ChangeCPUcount(c *C) { - - testServer.ResponseMap(8, testutil.ResponseMap{ - "/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample}, - "/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample}, - "/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample}, - "/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample}, - "/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample}, - "/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample}, - "/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample}, - "/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/cpu": testutil.Response{200, nil, taskExample}, - }) - - // Get the Org populated - org, err := s.vdc.GetVDCOrg() - c.Assert(err, IsNil) - - // Populate OrgVDCNetwork - net, err := s.vdc.FindVDCNetwork("networkName") - c.Assert(err, IsNil) - - // Populate Catalog - cat, err := org.FindCatalog("Public Catalog") - c.Assert(err, IsNil) - - // Populate Catalog Item - catitem, err := cat.FindCatalogItem("CentOS64-32bit") - c.Assert(err, IsNil) - - // Get VAppTemplate - vapptemplate, err := catitem.GetVAppTemplate() - c.Assert(err, IsNil) - - // Compose VApp - task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description") - c.Assert(err, IsNil) - c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp") - c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000") - - task, err = s.vapp.ChangeCPUcount(2) - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - - _ = testServer.WaitRequests(8) - -} - -func (s *S) Test_ChangeMemorySize(c *C) { - - testServer.ResponseMap(8, testutil.ResponseMap{ - "/api/org/11111111-1111-1111-1111-111111111111": testutil.Response{200, nil, orgExample}, - "/api/network/44444444-4444-4444-4444-4444444444444": testutil.Response{200, nil, orgvdcnetExample}, - "/api/catalog/e8a20fdf-8a78-440c-ac71-0420db59f854": testutil.Response{200, nil, catalogExample}, - "/api/catalogItem/1176e485-8858-4e15-94e5-ae4face605ae": testutil.Response{200, nil, catalogitemExample}, - "/api/vAppTemplate/vappTemplate-40cb9721-5f1a-44f9-b5c3-98c5f518c4f5": testutil.Response{200, nil, vapptemplateExample}, - "/api/vdc/00000000-0000-0000-0000-000000000000/action/composeVApp": testutil.Response{200, nil, instantiatedvappExample}, - "/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample}, - "/api/vApp/vm-00000000-0000-0000-0000-000000000000/virtualHardwareSection/memory": testutil.Response{200, nil, taskExample}, - }) - - // Get the Org populated - org, err := s.vdc.GetVDCOrg() - c.Assert(err, IsNil) - - // Populate OrgVDCNetwork - net, err := s.vdc.FindVDCNetwork("networkName") - c.Assert(err, IsNil) - - // Populate Catalog - cat, err := org.FindCatalog("Public Catalog") - c.Assert(err, IsNil) - - // Populate Catalog Item - catitem, err := cat.FindCatalogItem("CentOS64-32bit") - c.Assert(err, IsNil) - - // Get VAppTemplate - vapptemplate, err := catitem.GetVAppTemplate() - c.Assert(err, IsNil) - - // Compose VApp - task, err := s.vapp.ComposeVApp(net, vapptemplate, "name", "description") - c.Assert(err, IsNil) - c.Assert(task.Task.OperationName, Equals, "vdcInstantiateVapp") - c.Assert(s.vapp.VApp.HREF, Equals, "http://localhost:4444/api/vApp/vapp-00000000-0000-0000-0000-000000000000") - - task, err = s.vapp.ChangeMemorySize(4096) - - c.Assert(err, IsNil) - c.Assert(task.Task.Status, Equals, "success") - - _ = testServer.WaitRequests(8) - -} - -var instantiatedvappExample = ` - - - - - - - - - - - - - My vApp to be deployed - - - - - - - 1 -
- - - 2014-10-24T15:26:59.067Z - - - - false - - ` - -var vappExample = ` - - - - - - - - - - - - - - - - - - - - - - Test API GO4444! - - Lease settings section - - 0 - 0 - - - VApp startup section - - - - - The list of logical networks - - This isolated network was created with Create VDC. - - - This is a special place-holder used for disconnected network interfaces. - - - - The configuration parameters for logical networks - - - - This isolated network was created with Create VDC. - - - - true - 192.168.99.1 - 255.255.255.0 - true - - - 192.168.99.2 - 192.168.99.100 - - - - - - bridged - false - - false - - - This is a special place-holder used for disconnected network interfaces. - - - - false - 196.254.254.254 - 255.255.0.0 - 196.254.254.254 - - - isolated - - false - - - - Snapshot information section - - 2014-11-06T22:24:43.913Z - - - - false - - - - - - - - - - - - - - - - - - - - - - id: cts-6.4-32bit - - Virtual hardware requirements - - Virtual Hardware Family - 0 - CentOS64-32bit - vmx-09 - - - 00:50:56:02:0b:36 - 0 - false - none - E1000 ethernet adapter on "none" - Network adapter 0 - 1 - E1000 - 10 - - - 0 - SCSI Controller - SCSI Controller 0 - 2 - lsilogic - 6 - - - 0 - Hard disk - Hard disk 1 - - 2000 - 2 - 17 - - - 1 - IDE Controller - IDE Controller 1 - 3 - 5 - - - 0 - false - CD/DVD Drive - CD/DVD Drive 1 - - 3002 - 3 - 15 - - - 0 - false - Floppy Drive - Floppy Drive 1 - - 8000 - 14 - - - hertz * 10^6 - Number of Virtual CPUs - 1 virtual CPU(s) - 4 - 0 - 3 - 1 - 0 - 1 - - - - byte * 2^20 - Memory Size - 1024 MB of memory - 5 - 0 - 4 - 1024 - 0 - - - - - - - - - - - - - - - - - Specifies the operating system installed - CentOS 4/5/6 (32-bit) - - - - Specifies the available VM network connections - 0 - - 0 - false - 00:50:56:02:0b:36 - NONE - - - - - Specifies Guest OS Customization Settings - true - false - 00000000-0000-0000-0000-000000000000 - false - false - true - true - false - 0 - true - cts-6.4-32bit - - - - Specifies Runtime info - - - - Snapshot information section - - CentOS64-32bit - - - false - false - - - - - - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate_test.go deleted file mode 100644 index cddb143ef0..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate_test.go +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -var vapptemplateExample = ` - - - - - - - - - - - id: cts-6.4-32bit - - - - - - - - - - id: cts-6.4-32bit - - Specifies the available VM network connections - 0 - - 0 - false - 00:50:56:02:00:39 - NONE - - - - Specifies Guest OS Customization Settings - true - false - 3a3934d2-1f3f-4782-a911-f143da27e88c - false - false - true - true - false - 0 - true - cts-6.4-32bit - - - Virtual hardware requirements - - Virtual Hardware Family - 0 - CentOS64-32bit - vmx-09 - - - 00:50:56:02:00:39 - 0 - false - none - E1000 ethernet adapter on "none" - Network adapter 0 - 1 - E1000 - 10 - - - 0 - SCSI Controller - SCSI Controller 0 - 2 - lsilogic - 6 - - - 0 - Hard disk - Hard disk 1 - - 2000 - 2 - 17 - - - 1 - IDE Controller - IDE Controller 1 - 3 - 5 - - - 0 - false - CD/DVD Drive - CD/DVD Drive 1 - - 3002 - 3 - 15 - - - 0 - false - Floppy Drive - Floppy Drive 1 - - 8000 - 14 - - - hertz * 10^6 - Number of Virtual CPUs - 1 virtual CPU(s) - 4 - 0 - 3 - 1 - 0 - 1 - - - byte * 2^20 - Memory Size - 1024 MB of memory - 5 - 0 - 4 - 1024 - 0 - - - - - - - - - CentOS64-32bit - 2014-06-04T21:06:43.547Z - - - - The list of logical networks - - This is a special place-holder used for disconnected network interfaces. - - - - The configuration parameters for logical networks - - This is a special place-holder used for disconnected network interfaces. - - - - false - 196.254.254.254 - 255.255.0.0 - 196.254.254.254 - - - isolated - - false - - - - Lease settings section - - 0 - - - VApp template customization section - true - - 2014-06-04T21:06:43.547Z - - - ` diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/vdc_test.go b/Godeps/_workspace/src/github.com/vmware/govcloudair/vdc_test.go deleted file mode 100644 index 5fb44a7c82..0000000000 --- a/Godeps/_workspace/src/github.com/vmware/govcloudair/vdc_test.go +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package govcloudair - -import ( - "github.com/vmware/govcloudair/testutil" - - . "gopkg.in/check.v1" -) - -func (s *S) Test_FindVDCNetwork(c *C) { - - testServer.Response(200, nil, orgvdcnetExample) - - net, err := s.vdc.FindVDCNetwork("networkName") - - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(net, NotNil) - c.Assert(net.OrgVDCNetwork.HREF, Equals, "http://localhost:4444/api/network/cb0f4c9e-1a46-49d4-9fcb-d228000a6bc1") - - // find Invalid Network - net, err = s.vdc.FindVDCNetwork("INVALID") - c.Assert(err, NotNil) -} - -func (s *S) Test_GetVDCOrg(c *C) { - - testServer.Response(200, nil, orgExample) - - org, err := s.vdc.GetVDCOrg() - - _ = testServer.WaitRequest() - - c.Assert(err, IsNil) - c.Assert(org, NotNil) - c.Assert(org.Org.HREF, Equals, "http://localhost:4444/api/org/23bd2339-c55f-403c-baf3-13109e8c8d57") -} - -func (s *S) Test_NewVdc(c *C) { - - testServer.Response(200, nil, vdcExample) - err := s.vdc.Refresh() - _ = testServer.WaitRequest() - c.Assert(err, IsNil) - - c.Assert(s.vdc.Vdc.Link[0].Rel, Equals, "up") - c.Assert(s.vdc.Vdc.Link[0].Type, Equals, "application/vnd.vmware.vcloud.org+xml") - c.Assert(s.vdc.Vdc.Link[0].HREF, Equals, "http://localhost:4444/api/org/11111111-1111-1111-1111-111111111111") - - c.Assert(s.vdc.Vdc.AllocationModel, Equals, "AllocationPool") - - for _, v := range s.vdc.Vdc.ComputeCapacity { - c.Assert(v.CPU.Units, Equals, "MHz") - c.Assert(v.CPU.Allocated, Equals, int64(30000)) - c.Assert(v.CPU.Limit, Equals, int64(30000)) - c.Assert(v.CPU.Reserved, Equals, int64(15000)) - c.Assert(v.CPU.Used, Equals, int64(0)) - c.Assert(v.CPU.Overhead, Equals, int64(0)) - c.Assert(v.Memory.Units, Equals, "MB") - c.Assert(v.Memory.Allocated, Equals, int64(61440)) - c.Assert(v.Memory.Limit, Equals, int64(61440)) - c.Assert(v.Memory.Reserved, Equals, int64(61440)) - c.Assert(v.Memory.Used, Equals, int64(6144)) - c.Assert(v.Memory.Overhead, Equals, int64(95)) - } - - c.Assert(s.vdc.Vdc.ResourceEntities[0].ResourceEntity[0].Name, Equals, "vAppTemplate") - c.Assert(s.vdc.Vdc.ResourceEntities[0].ResourceEntity[0].Type, Equals, "application/vnd.vmware.vcloud.vAppTemplate+xml") - c.Assert(s.vdc.Vdc.ResourceEntities[0].ResourceEntity[0].HREF, Equals, "http://localhost:4444/api/vAppTemplate/vappTemplate-22222222-2222-2222-2222-222222222222") - - for _, v := range s.vdc.Vdc.AvailableNetworks { - for _, v2 := range v.Network { - c.Assert(v2.Name, Equals, "networkName") - c.Assert(v2.Type, Equals, "application/vnd.vmware.vcloud.network+xml") - c.Assert(v2.HREF, Equals, "http://localhost:4444/api/network/44444444-4444-4444-4444-4444444444444") - } - } - - c.Assert(s.vdc.Vdc.NicQuota, Equals, 0) - c.Assert(s.vdc.Vdc.NetworkQuota, Equals, 20) - c.Assert(s.vdc.Vdc.UsedNetworkCount, Equals, 0) - c.Assert(s.vdc.Vdc.VMQuota, Equals, 0) - c.Assert(s.vdc.Vdc.IsEnabled, Equals, true) - - for _, v := range s.vdc.Vdc.VdcStorageProfiles { - for _, v2 := range v.VdcStorageProfile { - c.Assert(v2.Name, Equals, "storageProfile") - c.Assert(v2.Type, Equals, "application/vnd.vmware.vcloud.vdcStorageProfile+xml") - c.Assert(v2.HREF, Equals, "http://localhost:4444/api/vdcStorageProfile/88888888-8888-8888-8888-888888888888") - } - } - -} - -func (s *S) Test_FindVApp(c *C) { - - // testServer.Response(200, nil, vappExample) - - // vapp, err := s.vdc.FindVAppByID("") - - // _ = testServer.WaitRequest() - // testServer.Flush() - // c.Assert(err, IsNil) - - testServer.ResponseMap(2, testutil.ResponseMap{ - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - "/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample}, - }) - - _, err := s.vdc.FindVAppByName("myVApp") - - _ = testServer.WaitRequests(2) - - c.Assert(err, IsNil) - - testServer.ResponseMap(2, testutil.ResponseMap{ - "/api/vdc/00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vdcExample}, - "/api/vApp/vapp-00000000-0000-0000-0000-000000000000": testutil.Response{200, nil, vappExample}, - }) - - _, err = s.vdc.FindVAppByID("urn:vcloud:vapp:00000000-0000-0000-0000-000000000000") - - _ = testServer.WaitRequests(2) - - c.Assert(err, IsNil) - -} - -var vdcExample = ` - - - - - AllocationPool - - - MHz - 30000 - 30000 - 15000 - 0 - 0 - - - MB - 61440 - 61440 - 61440 - 6144 - 95 - - - - - - - - - - - - vmx-10 - - - 0 - 20 - 0 - 0 - true - - - - - ` diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/client.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/client.go deleted file mode 100644 index 7f2ae50274..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/client.go +++ /dev/null @@ -1,563 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - Package agent implements a client to an ssh-agent daemon. - -References: - [PROTOCOL.agent]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent -*/ -package agent - -import ( - "bytes" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "encoding/base64" - "encoding/binary" - "errors" - "fmt" - "io" - "math/big" - "sync" - - "golang.org/x/crypto/ssh" -) - -// Agent represents the capabilities of an ssh-agent. -type Agent interface { - // List returns the identities known to the agent. - List() ([]*Key, error) - - // Sign has the agent sign the data using a protocol 2 key as defined - // in [PROTOCOL.agent] section 2.6.2. - Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) - - // Insert adds a private key to the agent. If a certificate - // is given, that certificate is added as public key. - Add(s interface{}, cert *ssh.Certificate, comment string) error - - // Remove removes all identities with the given public key. - Remove(key ssh.PublicKey) error - - // RemoveAll removes all identities. - RemoveAll() error - - // Lock locks the agent. Sign and Remove will fail, and List will empty an empty list. - Lock(passphrase []byte) error - - // Unlock undoes the effect of Lock - Unlock(passphrase []byte) error - - // Signers returns signers for all the known keys. - Signers() ([]ssh.Signer, error) -} - -// See [PROTOCOL.agent], section 3. -const ( - agentRequestV1Identities = 1 - - // 3.2 Requests from client to agent for protocol 2 key operations - agentAddIdentity = 17 - agentRemoveIdentity = 18 - agentRemoveAllIdentities = 19 - agentAddIdConstrained = 25 - - // 3.3 Key-type independent requests from client to agent - agentAddSmartcardKey = 20 - agentRemoveSmartcardKey = 21 - agentLock = 22 - agentUnlock = 23 - agentAddSmartcardKeyConstrained = 26 - - // 3.7 Key constraint identifiers - agentConstrainLifetime = 1 - agentConstrainConfirm = 2 -) - -// maxAgentResponseBytes is the maximum agent reply size that is accepted. This -// is a sanity check, not a limit in the spec. -const maxAgentResponseBytes = 16 << 20 - -// Agent messages: -// These structures mirror the wire format of the corresponding ssh agent -// messages found in [PROTOCOL.agent]. - -// 3.4 Generic replies from agent to client -const agentFailure = 5 - -type failureAgentMsg struct{} - -const agentSuccess = 6 - -type successAgentMsg struct{} - -// See [PROTOCOL.agent], section 2.5.2. -const agentRequestIdentities = 11 - -type requestIdentitiesAgentMsg struct{} - -// See [PROTOCOL.agent], section 2.5.2. -const agentIdentitiesAnswer = 12 - -type identitiesAnswerAgentMsg struct { - NumKeys uint32 `sshtype:"12"` - Keys []byte `ssh:"rest"` -} - -// See [PROTOCOL.agent], section 2.6.2. -const agentSignRequest = 13 - -type signRequestAgentMsg struct { - KeyBlob []byte `sshtype:"13"` - Data []byte - Flags uint32 -} - -// See [PROTOCOL.agent], section 2.6.2. - -// 3.6 Replies from agent to client for protocol 2 key operations -const agentSignResponse = 14 - -type signResponseAgentMsg struct { - SigBlob []byte `sshtype:"14"` -} - -type publicKey struct { - Format string - Rest []byte `ssh:"rest"` -} - -// Key represents a protocol 2 public key as defined in -// [PROTOCOL.agent], section 2.5.2. -type Key struct { - Format string - Blob []byte - Comment string -} - -func clientErr(err error) error { - return fmt.Errorf("agent: client error: %v", err) -} - -// String returns the storage form of an agent key with the format, base64 -// encoded serialized key, and the comment if it is not empty. -func (k *Key) String() string { - s := string(k.Format) + " " + base64.StdEncoding.EncodeToString(k.Blob) - - if k.Comment != "" { - s += " " + k.Comment - } - - return s -} - -// Type returns the public key type. -func (k *Key) Type() string { - return k.Format -} - -// Marshal returns key blob to satisfy the ssh.PublicKey interface. -func (k *Key) Marshal() []byte { - return k.Blob -} - -// Verify satisfies the ssh.PublicKey interface, but is not -// implemented for agent keys. -func (k *Key) Verify(data []byte, sig *ssh.Signature) error { - return errors.New("agent: agent key does not know how to verify") -} - -type wireKey struct { - Format string - Rest []byte `ssh:"rest"` -} - -func parseKey(in []byte) (out *Key, rest []byte, err error) { - var record struct { - Blob []byte - Comment string - Rest []byte `ssh:"rest"` - } - - if err := ssh.Unmarshal(in, &record); err != nil { - return nil, nil, err - } - - var wk wireKey - if err := ssh.Unmarshal(record.Blob, &wk); err != nil { - return nil, nil, err - } - - return &Key{ - Format: wk.Format, - Blob: record.Blob, - Comment: record.Comment, - }, record.Rest, nil -} - -// client is a client for an ssh-agent process. -type client struct { - // conn is typically a *net.UnixConn - conn io.ReadWriter - // mu is used to prevent concurrent access to the agent - mu sync.Mutex -} - -// NewClient returns an Agent that talks to an ssh-agent process over -// the given connection. -func NewClient(rw io.ReadWriter) Agent { - return &client{conn: rw} -} - -// call sends an RPC to the agent. On success, the reply is -// unmarshaled into reply and replyType is set to the first byte of -// the reply, which contains the type of the message. -func (c *client) call(req []byte) (reply interface{}, err error) { - c.mu.Lock() - defer c.mu.Unlock() - - msg := make([]byte, 4+len(req)) - binary.BigEndian.PutUint32(msg, uint32(len(req))) - copy(msg[4:], req) - if _, err = c.conn.Write(msg); err != nil { - return nil, clientErr(err) - } - - var respSizeBuf [4]byte - if _, err = io.ReadFull(c.conn, respSizeBuf[:]); err != nil { - return nil, clientErr(err) - } - respSize := binary.BigEndian.Uint32(respSizeBuf[:]) - if respSize > maxAgentResponseBytes { - return nil, clientErr(err) - } - - buf := make([]byte, respSize) - if _, err = io.ReadFull(c.conn, buf); err != nil { - return nil, clientErr(err) - } - reply, err = unmarshal(buf) - if err != nil { - return nil, clientErr(err) - } - return reply, err -} - -func (c *client) simpleCall(req []byte) error { - resp, err := c.call(req) - if err != nil { - return err - } - if _, ok := resp.(*successAgentMsg); ok { - return nil - } - return errors.New("agent: failure") -} - -func (c *client) RemoveAll() error { - return c.simpleCall([]byte{agentRemoveAllIdentities}) -} - -func (c *client) Remove(key ssh.PublicKey) error { - req := ssh.Marshal(&agentRemoveIdentityMsg{ - KeyBlob: key.Marshal(), - }) - return c.simpleCall(req) -} - -func (c *client) Lock(passphrase []byte) error { - req := ssh.Marshal(&agentLockMsg{ - Passphrase: passphrase, - }) - return c.simpleCall(req) -} - -func (c *client) Unlock(passphrase []byte) error { - req := ssh.Marshal(&agentUnlockMsg{ - Passphrase: passphrase, - }) - return c.simpleCall(req) -} - -// List returns the identities known to the agent. -func (c *client) List() ([]*Key, error) { - // see [PROTOCOL.agent] section 2.5.2. - req := []byte{agentRequestIdentities} - - msg, err := c.call(req) - if err != nil { - return nil, err - } - - switch msg := msg.(type) { - case *identitiesAnswerAgentMsg: - if msg.NumKeys > maxAgentResponseBytes/8 { - return nil, errors.New("agent: too many keys in agent reply") - } - keys := make([]*Key, msg.NumKeys) - data := msg.Keys - for i := uint32(0); i < msg.NumKeys; i++ { - var key *Key - var err error - if key, data, err = parseKey(data); err != nil { - return nil, err - } - keys[i] = key - } - return keys, nil - case *failureAgentMsg: - return nil, errors.New("agent: failed to list keys") - } - panic("unreachable") -} - -// Sign has the agent sign the data using a protocol 2 key as defined -// in [PROTOCOL.agent] section 2.6.2. -func (c *client) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { - req := ssh.Marshal(signRequestAgentMsg{ - KeyBlob: key.Marshal(), - Data: data, - }) - - msg, err := c.call(req) - if err != nil { - return nil, err - } - - switch msg := msg.(type) { - case *signResponseAgentMsg: - var sig ssh.Signature - if err := ssh.Unmarshal(msg.SigBlob, &sig); err != nil { - return nil, err - } - - return &sig, nil - case *failureAgentMsg: - return nil, errors.New("agent: failed to sign challenge") - } - panic("unreachable") -} - -// unmarshal parses an agent message in packet, returning the parsed -// form and the message type of packet. -func unmarshal(packet []byte) (interface{}, error) { - if len(packet) < 1 { - return nil, errors.New("agent: empty packet") - } - var msg interface{} - switch packet[0] { - case agentFailure: - return new(failureAgentMsg), nil - case agentSuccess: - return new(successAgentMsg), nil - case agentIdentitiesAnswer: - msg = new(identitiesAnswerAgentMsg) - case agentSignResponse: - msg = new(signResponseAgentMsg) - default: - return nil, fmt.Errorf("agent: unknown type tag %d", packet[0]) - } - if err := ssh.Unmarshal(packet, msg); err != nil { - return nil, err - } - return msg, nil -} - -type rsaKeyMsg struct { - Type string `sshtype:"17"` - N *big.Int - E *big.Int - D *big.Int - Iqmp *big.Int // IQMP = Inverse Q Mod P - P *big.Int - Q *big.Int - Comments string -} - -type dsaKeyMsg struct { - Type string `sshtype:"17"` - P *big.Int - Q *big.Int - G *big.Int - Y *big.Int - X *big.Int - Comments string -} - -type ecdsaKeyMsg struct { - Type string `sshtype:"17"` - Curve string - KeyBytes []byte - D *big.Int - Comments string -} - -// Insert adds a private key to the agent. -func (c *client) insertKey(s interface{}, comment string) error { - var req []byte - switch k := s.(type) { - case *rsa.PrivateKey: - if len(k.Primes) != 2 { - return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes)) - } - k.Precompute() - req = ssh.Marshal(rsaKeyMsg{ - Type: ssh.KeyAlgoRSA, - N: k.N, - E: big.NewInt(int64(k.E)), - D: k.D, - Iqmp: k.Precomputed.Qinv, - P: k.Primes[0], - Q: k.Primes[1], - Comments: comment, - }) - case *dsa.PrivateKey: - req = ssh.Marshal(dsaKeyMsg{ - Type: ssh.KeyAlgoDSA, - P: k.P, - Q: k.Q, - G: k.G, - Y: k.Y, - X: k.X, - Comments: comment, - }) - case *ecdsa.PrivateKey: - nistID := fmt.Sprintf("nistp%d", k.Params().BitSize) - req = ssh.Marshal(ecdsaKeyMsg{ - Type: "ecdsa-sha2-" + nistID, - Curve: nistID, - KeyBytes: elliptic.Marshal(k.Curve, k.X, k.Y), - D: k.D, - Comments: comment, - }) - default: - return fmt.Errorf("agent: unsupported key type %T", s) - } - resp, err := c.call(req) - if err != nil { - return err - } - if _, ok := resp.(*successAgentMsg); ok { - return nil - } - return errors.New("agent: failure") -} - -type rsaCertMsg struct { - Type string `sshtype:"17"` - CertBytes []byte - D *big.Int - Iqmp *big.Int // IQMP = Inverse Q Mod P - P *big.Int - Q *big.Int - Comments string -} - -type dsaCertMsg struct { - Type string `sshtype:"17"` - CertBytes []byte - X *big.Int - Comments string -} - -type ecdsaCertMsg struct { - Type string `sshtype:"17"` - CertBytes []byte - D *big.Int - Comments string -} - -// Insert adds a private key to the agent. If a certificate is given, -// that certificate is added instead as public key. -func (c *client) Add(s interface{}, cert *ssh.Certificate, comment string) error { - if cert == nil { - return c.insertKey(s, comment) - } else { - return c.insertCert(s, cert, comment) - } -} - -func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string) error { - var req []byte - switch k := s.(type) { - case *rsa.PrivateKey: - if len(k.Primes) != 2 { - return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes)) - } - k.Precompute() - req = ssh.Marshal(rsaCertMsg{ - Type: cert.Type(), - CertBytes: cert.Marshal(), - D: k.D, - Iqmp: k.Precomputed.Qinv, - P: k.Primes[0], - Q: k.Primes[1], - Comments: comment, - }) - case *dsa.PrivateKey: - req = ssh.Marshal(dsaCertMsg{ - Type: cert.Type(), - CertBytes: cert.Marshal(), - X: k.X, - Comments: comment, - }) - case *ecdsa.PrivateKey: - req = ssh.Marshal(ecdsaCertMsg{ - Type: cert.Type(), - CertBytes: cert.Marshal(), - D: k.D, - Comments: comment, - }) - default: - return fmt.Errorf("agent: unsupported key type %T", s) - } - - signer, err := ssh.NewSignerFromKey(s) - if err != nil { - return err - } - if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 { - return errors.New("agent: signer and cert have different public key") - } - - resp, err := c.call(req) - if err != nil { - return err - } - if _, ok := resp.(*successAgentMsg); ok { - return nil - } - return errors.New("agent: failure") -} - -// Signers provides a callback for client authentication. -func (c *client) Signers() ([]ssh.Signer, error) { - keys, err := c.List() - if err != nil { - return nil, err - } - - var result []ssh.Signer - for _, k := range keys { - result = append(result, &agentKeyringSigner{c, k}) - } - return result, nil -} - -type agentKeyringSigner struct { - agent *client - pub ssh.PublicKey -} - -func (s *agentKeyringSigner) PublicKey() ssh.PublicKey { - return s.pub -} - -func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) { - // The agent has its own entropy source, so the rand argument is ignored. - return s.agent.Sign(s.pub, data) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/client_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/client_test.go deleted file mode 100644 index 80e2c2c382..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/client_test.go +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package agent - -import ( - "bytes" - "crypto/rand" - "errors" - "net" - "os" - "os/exec" - "path/filepath" - "strconv" - "testing" - - "golang.org/x/crypto/ssh" -) - -// startAgent executes ssh-agent, and returns a Agent interface to it. -func startAgent(t *testing.T) (client Agent, socket string, cleanup func()) { - if testing.Short() { - // ssh-agent is not always available, and the key - // types supported vary by platform. - t.Skip("skipping test due to -short") - } - - bin, err := exec.LookPath("ssh-agent") - if err != nil { - t.Skip("could not find ssh-agent") - } - - cmd := exec.Command(bin, "-s") - out, err := cmd.Output() - if err != nil { - t.Fatalf("cmd.Output: %v", err) - } - - /* Output looks like: - - SSH_AUTH_SOCK=/tmp/ssh-P65gpcqArqvH/agent.15541; export SSH_AUTH_SOCK; - SSH_AGENT_PID=15542; export SSH_AGENT_PID; - echo Agent pid 15542; - */ - fields := bytes.Split(out, []byte(";")) - line := bytes.SplitN(fields[0], []byte("="), 2) - line[0] = bytes.TrimLeft(line[0], "\n") - if string(line[0]) != "SSH_AUTH_SOCK" { - t.Fatalf("could not find key SSH_AUTH_SOCK in %q", fields[0]) - } - socket = string(line[1]) - - line = bytes.SplitN(fields[2], []byte("="), 2) - line[0] = bytes.TrimLeft(line[0], "\n") - if string(line[0]) != "SSH_AGENT_PID" { - t.Fatalf("could not find key SSH_AGENT_PID in %q", fields[2]) - } - pidStr := line[1] - pid, err := strconv.Atoi(string(pidStr)) - if err != nil { - t.Fatalf("Atoi(%q): %v", pidStr, err) - } - - conn, err := net.Dial("unix", string(socket)) - if err != nil { - t.Fatalf("net.Dial: %v", err) - } - - ac := NewClient(conn) - return ac, socket, func() { - proc, _ := os.FindProcess(pid) - if proc != nil { - proc.Kill() - } - conn.Close() - os.RemoveAll(filepath.Dir(socket)) - } -} - -func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate) { - agent, _, cleanup := startAgent(t) - defer cleanup() - - testAgentInterface(t, agent, key, cert) -} - -func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate) { - signer, err := ssh.NewSignerFromKey(key) - if err != nil { - t.Fatalf("NewSignerFromKey(%T): %v", key, err) - } - // The agent should start up empty. - if keys, err := agent.List(); err != nil { - t.Fatalf("RequestIdentities: %v", err) - } else if len(keys) > 0 { - t.Fatalf("got %d keys, want 0: %v", len(keys), keys) - } - - // Attempt to insert the key, with certificate if specified. - var pubKey ssh.PublicKey - if cert != nil { - err = agent.Add(key, cert, "comment") - pubKey = cert - } else { - err = agent.Add(key, nil, "comment") - pubKey = signer.PublicKey() - } - if err != nil { - t.Fatalf("insert(%T): %v", key, err) - } - - // Did the key get inserted successfully? - if keys, err := agent.List(); err != nil { - t.Fatalf("List: %v", err) - } else if len(keys) != 1 { - t.Fatalf("got %v, want 1 key", keys) - } else if keys[0].Comment != "comment" { - t.Fatalf("key comment: got %v, want %v", keys[0].Comment, "comment") - } else if !bytes.Equal(keys[0].Blob, pubKey.Marshal()) { - t.Fatalf("key mismatch") - } - - // Can the agent make a valid signature? - data := []byte("hello") - sig, err := agent.Sign(pubKey, data) - if err != nil { - t.Fatalf("Sign(%s): %v", pubKey.Type(), err) - } - - if err := pubKey.Verify(data, sig); err != nil { - t.Fatalf("Verify(%s): %v", pubKey.Type(), err) - } -} - -func TestAgent(t *testing.T) { - for _, keyType := range []string{"rsa", "dsa", "ecdsa"} { - testAgent(t, testPrivateKeys[keyType], nil) - } -} - -func TestCert(t *testing.T) { - cert := &ssh.Certificate{ - Key: testPublicKeys["rsa"], - ValidBefore: ssh.CertTimeInfinity, - CertType: ssh.UserCert, - } - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - - testAgent(t, testPrivateKeys["rsa"], cert) -} - -// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and -// therefore is buffered (net.Pipe deadlocks if both sides start with -// a write.) -func netPipe() (net.Conn, net.Conn, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, nil, err - } - defer listener.Close() - c1, err := net.Dial("tcp", listener.Addr().String()) - if err != nil { - return nil, nil, err - } - - c2, err := listener.Accept() - if err != nil { - c1.Close() - return nil, nil, err - } - - return c1, c2, nil -} - -func TestAuth(t *testing.T) { - a, b, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - - defer a.Close() - defer b.Close() - - agent, _, cleanup := startAgent(t) - defer cleanup() - - if err := agent.Add(testPrivateKeys["rsa"], nil, "comment"); err != nil { - t.Errorf("Add: %v", err) - } - - serverConf := ssh.ServerConfig{} - serverConf.AddHostKey(testSigners["rsa"]) - serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) { - return nil, nil - } - - return nil, errors.New("pubkey rejected") - } - - go func() { - conn, _, _, err := ssh.NewServerConn(a, &serverConf) - if err != nil { - t.Fatalf("Server: %v", err) - } - conn.Close() - }() - - conf := ssh.ClientConfig{} - conf.Auth = append(conf.Auth, ssh.PublicKeysCallback(agent.Signers)) - conn, _, _, err := ssh.NewClientConn(b, "", &conf) - if err != nil { - t.Fatalf("NewClientConn: %v", err) - } - conn.Close() -} - -func TestLockClient(t *testing.T) { - agent, _, cleanup := startAgent(t) - defer cleanup() - testLockAgent(agent, t) -} - -func testLockAgent(agent Agent, t *testing.T) { - if err := agent.Add(testPrivateKeys["rsa"], nil, "comment 1"); err != nil { - t.Errorf("Add: %v", err) - } - if err := agent.Add(testPrivateKeys["dsa"], nil, "comment dsa"); err != nil { - t.Errorf("Add: %v", err) - } - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 2 { - t.Errorf("Want 2 keys, got %v", keys) - } - - passphrase := []byte("secret") - if err := agent.Lock(passphrase); err != nil { - t.Errorf("Lock: %v", err) - } - - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 0 { - t.Errorf("Want 0 keys, got %v", keys) - } - - signer, _ := ssh.NewSignerFromKey(testPrivateKeys["rsa"]) - if _, err := agent.Sign(signer.PublicKey(), []byte("hello")); err == nil { - t.Fatalf("Sign did not fail") - } - - if err := agent.Remove(signer.PublicKey()); err == nil { - t.Fatalf("Remove did not fail") - } - - if err := agent.RemoveAll(); err == nil { - t.Fatalf("RemoveAll did not fail") - } - - if err := agent.Unlock(nil); err == nil { - t.Errorf("Unlock with wrong passphrase succeeded") - } - if err := agent.Unlock(passphrase); err != nil { - t.Errorf("Unlock: %v", err) - } - - if err := agent.Remove(signer.PublicKey()); err != nil { - t.Fatalf("Remove: %v", err) - } - - if keys, err := agent.List(); err != nil { - t.Errorf("List: %v", err) - } else if len(keys) != 1 { - t.Errorf("Want 1 keys, got %v", keys) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/forward.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/forward.go deleted file mode 100644 index fd24ba900d..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/forward.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package agent - -import ( - "errors" - "io" - "net" - "sync" - - "golang.org/x/crypto/ssh" -) - -// RequestAgentForwarding sets up agent forwarding for the session. -// ForwardToAgent or ForwardToRemote should be called to route -// the authentication requests. -func RequestAgentForwarding(session *ssh.Session) error { - ok, err := session.SendRequest("auth-agent-req@openssh.com", true, nil) - if err != nil { - return err - } - if !ok { - return errors.New("forwarding request denied") - } - return nil -} - -// ForwardToAgent routes authentication requests to the given keyring. -func ForwardToAgent(client *ssh.Client, keyring Agent) error { - channels := client.HandleChannelOpen(channelType) - if channels == nil { - return errors.New("agent: already have handler for " + channelType) - } - - go func() { - for ch := range channels { - channel, reqs, err := ch.Accept() - if err != nil { - continue - } - go ssh.DiscardRequests(reqs) - go func() { - ServeAgent(keyring, channel) - channel.Close() - }() - } - }() - return nil -} - -const channelType = "auth-agent@openssh.com" - -// ForwardToRemote routes authentication requests to the ssh-agent -// process serving on the given unix socket. -func ForwardToRemote(client *ssh.Client, addr string) error { - channels := client.HandleChannelOpen(channelType) - if channels == nil { - return errors.New("agent: already have handler for " + channelType) - } - conn, err := net.Dial("unix", addr) - if err != nil { - return err - } - conn.Close() - - go func() { - for ch := range channels { - channel, reqs, err := ch.Accept() - if err != nil { - continue - } - go ssh.DiscardRequests(reqs) - go forwardUnixSocket(channel, addr) - } - }() - return nil -} - -func forwardUnixSocket(channel ssh.Channel, addr string) { - conn, err := net.Dial("unix", addr) - if err != nil { - return - } - - var wg sync.WaitGroup - wg.Add(2) - go func() { - io.Copy(conn, channel) - conn.(*net.UnixConn).CloseWrite() - wg.Done() - }() - go func() { - io.Copy(channel, conn) - channel.CloseWrite() - wg.Done() - }() - - wg.Wait() - conn.Close() - channel.Close() -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/keyring.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/keyring.go deleted file mode 100644 index 831a5b9ae5..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/keyring.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package agent - -import ( - "bytes" - "crypto/rand" - "crypto/subtle" - "errors" - "fmt" - "sync" - - "golang.org/x/crypto/ssh" -) - -type privKey struct { - signer ssh.Signer - comment string -} - -type keyring struct { - mu sync.Mutex - keys []privKey - - locked bool - passphrase []byte -} - -var errLocked = errors.New("agent: locked") - -// NewKeyring returns an Agent that holds keys in memory. It is safe -// for concurrent use by multiple goroutines. -func NewKeyring() Agent { - return &keyring{} -} - -// RemoveAll removes all identities. -func (r *keyring) RemoveAll() error { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return errLocked - } - - r.keys = nil - return nil -} - -// Remove removes all identities with the given public key. -func (r *keyring) Remove(key ssh.PublicKey) error { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return errLocked - } - - want := key.Marshal() - found := false - for i := 0; i < len(r.keys); { - if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) { - found = true - r.keys[i] = r.keys[len(r.keys)-1] - r.keys = r.keys[len(r.keys)-1:] - continue - } else { - i++ - } - } - - if !found { - return errors.New("agent: key not found") - } - return nil -} - -// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list. -func (r *keyring) Lock(passphrase []byte) error { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return errLocked - } - - r.locked = true - r.passphrase = passphrase - return nil -} - -// Unlock undoes the effect of Lock -func (r *keyring) Unlock(passphrase []byte) error { - r.mu.Lock() - defer r.mu.Unlock() - if !r.locked { - return errors.New("agent: not locked") - } - if len(passphrase) != len(r.passphrase) || 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) { - return fmt.Errorf("agent: incorrect passphrase") - } - - r.locked = false - r.passphrase = nil - return nil -} - -// List returns the identities known to the agent. -func (r *keyring) List() ([]*Key, error) { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - // section 2.7: locked agents return empty. - return nil, nil - } - - var ids []*Key - for _, k := range r.keys { - pub := k.signer.PublicKey() - ids = append(ids, &Key{ - Format: pub.Type(), - Blob: pub.Marshal(), - Comment: k.comment}) - } - return ids, nil -} - -// Insert adds a private key to the keyring. If a certificate -// is given, that certificate is added as public key. -func (r *keyring) Add(priv interface{}, cert *ssh.Certificate, comment string) error { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return errLocked - } - signer, err := ssh.NewSignerFromKey(priv) - - if err != nil { - return err - } - - if cert != nil { - signer, err = ssh.NewCertSigner(cert, signer) - if err != nil { - return err - } - } - - r.keys = append(r.keys, privKey{signer, comment}) - - return nil -} - -// Sign returns a signature for the data. -func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return nil, errLocked - } - - wanted := key.Marshal() - for _, k := range r.keys { - if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) { - return k.signer.Sign(rand.Reader, data) - } - } - return nil, errors.New("not found") -} - -// Signers returns signers for all the known keys. -func (r *keyring) Signers() ([]ssh.Signer, error) { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return nil, errLocked - } - - s := make([]ssh.Signer, len(r.keys)) - for _, k := range r.keys { - s = append(s, k.signer) - } - return s, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/server.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/server.go deleted file mode 100644 index be9df0eb02..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/server.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package agent - -import ( - "crypto/rsa" - "encoding/binary" - "fmt" - "io" - "log" - "math/big" - - "golang.org/x/crypto/ssh" -) - -// Server wraps an Agent and uses it to implement the agent side of -// the SSH-agent, wire protocol. -type server struct { - agent Agent -} - -func (s *server) processRequestBytes(reqData []byte) []byte { - rep, err := s.processRequest(reqData) - if err != nil { - if err != errLocked { - // TODO(hanwen): provide better logging interface? - log.Printf("agent %d: %v", reqData[0], err) - } - return []byte{agentFailure} - } - - if err == nil && rep == nil { - return []byte{agentSuccess} - } - - return ssh.Marshal(rep) -} - -func marshalKey(k *Key) []byte { - var record struct { - Blob []byte - Comment string - } - record.Blob = k.Marshal() - record.Comment = k.Comment - - return ssh.Marshal(&record) -} - -type agentV1IdentityMsg struct { - Numkeys uint32 `sshtype:"2"` -} - -type agentRemoveIdentityMsg struct { - KeyBlob []byte `sshtype:"18"` -} - -type agentLockMsg struct { - Passphrase []byte `sshtype:"22"` -} - -type agentUnlockMsg struct { - Passphrase []byte `sshtype:"23"` -} - -func (s *server) processRequest(data []byte) (interface{}, error) { - switch data[0] { - case agentRequestV1Identities: - return &agentV1IdentityMsg{0}, nil - case agentRemoveIdentity: - var req agentRemoveIdentityMsg - if err := ssh.Unmarshal(data, &req); err != nil { - return nil, err - } - - var wk wireKey - if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil { - return nil, err - } - - return nil, s.agent.Remove(&Key{Format: wk.Format, Blob: req.KeyBlob}) - - case agentRemoveAllIdentities: - return nil, s.agent.RemoveAll() - - case agentLock: - var req agentLockMsg - if err := ssh.Unmarshal(data, &req); err != nil { - return nil, err - } - - return nil, s.agent.Lock(req.Passphrase) - - case agentUnlock: - var req agentLockMsg - if err := ssh.Unmarshal(data, &req); err != nil { - return nil, err - } - return nil, s.agent.Unlock(req.Passphrase) - - case agentSignRequest: - var req signRequestAgentMsg - if err := ssh.Unmarshal(data, &req); err != nil { - return nil, err - } - - var wk wireKey - if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil { - return nil, err - } - - k := &Key{ - Format: wk.Format, - Blob: req.KeyBlob, - } - - sig, err := s.agent.Sign(k, req.Data) // TODO(hanwen): flags. - if err != nil { - return nil, err - } - return &signResponseAgentMsg{SigBlob: ssh.Marshal(sig)}, nil - case agentRequestIdentities: - keys, err := s.agent.List() - if err != nil { - return nil, err - } - - rep := identitiesAnswerAgentMsg{ - NumKeys: uint32(len(keys)), - } - for _, k := range keys { - rep.Keys = append(rep.Keys, marshalKey(k)...) - } - return rep, nil - case agentAddIdentity: - return nil, s.insertIdentity(data) - } - - return nil, fmt.Errorf("unknown opcode %d", data[0]) -} - -func (s *server) insertIdentity(req []byte) error { - var record struct { - Type string `sshtype:"17"` - Rest []byte `ssh:"rest"` - } - if err := ssh.Unmarshal(req, &record); err != nil { - return err - } - - switch record.Type { - case ssh.KeyAlgoRSA: - var k rsaKeyMsg - if err := ssh.Unmarshal(req, &k); err != nil { - return err - } - - priv := rsa.PrivateKey{ - PublicKey: rsa.PublicKey{ - E: int(k.E.Int64()), - N: k.N, - }, - D: k.D, - Primes: []*big.Int{k.P, k.Q}, - } - priv.Precompute() - - return s.agent.Add(&priv, nil, k.Comments) - } - return fmt.Errorf("not implemented: %s", record.Type) -} - -// ServeAgent serves the agent protocol on the given connection. It -// returns when an I/O error occurs. -func ServeAgent(agent Agent, c io.ReadWriter) error { - s := &server{agent} - - var length [4]byte - for { - if _, err := io.ReadFull(c, length[:]); err != nil { - return err - } - l := binary.BigEndian.Uint32(length[:]) - if l > maxAgentResponseBytes { - // We also cap requests. - return fmt.Errorf("agent: request too large: %d", l) - } - - req := make([]byte, l) - if _, err := io.ReadFull(c, req); err != nil { - return err - } - - repData := s.processRequestBytes(req) - if len(repData) > maxAgentResponseBytes { - return fmt.Errorf("agent: reply too large: %d bytes", len(repData)) - } - - binary.BigEndian.PutUint32(length[:], uint32(len(repData))) - if _, err := c.Write(length[:]); err != nil { - return err - } - if _, err := c.Write(repData); err != nil { - return err - } - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/server_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/server_test.go deleted file mode 100644 index def5f8ccc3..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/server_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package agent - -import ( - "testing" - - "golang.org/x/crypto/ssh" -) - -func TestServer(t *testing.T) { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - client := NewClient(c1) - - go ServeAgent(NewKeyring(), c2) - - testAgentInterface(t, client, testPrivateKeys["rsa"], nil) -} - -func TestLockServer(t *testing.T) { - testLockAgent(NewKeyring(), t) -} - -func TestSetupForwardAgent(t *testing.T) { - a, b, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - - defer a.Close() - defer b.Close() - - _, socket, cleanup := startAgent(t) - defer cleanup() - - serverConf := ssh.ServerConfig{ - NoClientAuth: true, - } - serverConf.AddHostKey(testSigners["rsa"]) - incoming := make(chan *ssh.ServerConn, 1) - go func() { - conn, _, _, err := ssh.NewServerConn(a, &serverConf) - if err != nil { - t.Fatalf("Server: %v", err) - } - incoming <- conn - }() - - conf := ssh.ClientConfig{} - conn, chans, reqs, err := ssh.NewClientConn(b, "", &conf) - if err != nil { - t.Fatalf("NewClientConn: %v", err) - } - client := ssh.NewClient(conn, chans, reqs) - - if err := ForwardToRemote(client, socket); err != nil { - t.Fatalf("SetupForwardAgent: %v", err) - } - - server := <-incoming - ch, reqs, err := server.OpenChannel(channelType, nil) - if err != nil { - t.Fatalf("OpenChannel(%q): %v", channelType, err) - } - go ssh.DiscardRequests(reqs) - - agentClient := NewClient(ch) - testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil) - conn.Close() -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/testdata_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/testdata_test.go deleted file mode 100644 index b7a8781e1a..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/agent/testdata_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: -// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three -// instances. - -package agent - -import ( - "crypto/rand" - "fmt" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/testdata" -) - -var ( - testPrivateKeys map[string]interface{} - testSigners map[string]ssh.Signer - testPublicKeys map[string]ssh.PublicKey -) - -func init() { - var err error - - n := len(testdata.PEMBytes) - testPrivateKeys = make(map[string]interface{}, n) - testSigners = make(map[string]ssh.Signer, n) - testPublicKeys = make(map[string]ssh.PublicKey, n) - for t, k := range testdata.PEMBytes { - testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) - if err != nil { - panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) - } - testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) - if err != nil { - panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) - } - testPublicKeys[t] = testSigners[t].PublicKey() - } - - // Create a cert and sign it for use in tests. - testCert := &ssh.Certificate{ - Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage - ValidAfter: 0, // unix epoch - ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. - Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - Key: testPublicKeys["ecdsa"], - SignatureKey: testPublicKeys["rsa"], - Permissions: ssh.Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - testCert.SignCert(rand.Reader, testSigners["rsa"]) - testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] - testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) - if err != nil { - panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/benchmark_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/benchmark_test.go deleted file mode 100644 index d9f7eb9b60..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/benchmark_test.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "errors" - "io" - "net" - "testing" -) - -type server struct { - *ServerConn - chans <-chan NewChannel -} - -func newServer(c net.Conn, conf *ServerConfig) (*server, error) { - sconn, chans, reqs, err := NewServerConn(c, conf) - if err != nil { - return nil, err - } - go DiscardRequests(reqs) - return &server{sconn, chans}, nil -} - -func (s *server) Accept() (NewChannel, error) { - n, ok := <-s.chans - if !ok { - return nil, io.EOF - } - return n, nil -} - -func sshPipe() (Conn, *server, error) { - c1, c2, err := netPipe() - if err != nil { - return nil, nil, err - } - - clientConf := ClientConfig{ - User: "user", - } - serverConf := ServerConfig{ - NoClientAuth: true, - } - serverConf.AddHostKey(testSigners["ecdsa"]) - done := make(chan *server, 1) - go func() { - server, err := newServer(c2, &serverConf) - if err != nil { - done <- nil - } - done <- server - }() - - client, _, reqs, err := NewClientConn(c1, "", &clientConf) - if err != nil { - return nil, nil, err - } - - server := <-done - if server == nil { - return nil, nil, errors.New("server handshake failed.") - } - go DiscardRequests(reqs) - - return client, server, nil -} - -func BenchmarkEndToEnd(b *testing.B) { - b.StopTimer() - - client, server, err := sshPipe() - if err != nil { - b.Fatalf("sshPipe: %v", err) - } - - defer client.Close() - defer server.Close() - - size := (1 << 20) - input := make([]byte, size) - output := make([]byte, size) - b.SetBytes(int64(size)) - done := make(chan int, 1) - - go func() { - newCh, err := server.Accept() - if err != nil { - b.Fatalf("Client: %v", err) - } - ch, incoming, err := newCh.Accept() - go DiscardRequests(incoming) - for i := 0; i < b.N; i++ { - if _, err := io.ReadFull(ch, output); err != nil { - b.Fatalf("ReadFull: %v", err) - } - } - ch.Close() - done <- 1 - }() - - ch, in, err := client.OpenChannel("speed", nil) - if err != nil { - b.Fatalf("OpenChannel: %v", err) - } - go DiscardRequests(in) - - b.ResetTimer() - b.StartTimer() - for i := 0; i < b.N; i++ { - if _, err := ch.Write(input); err != nil { - b.Fatalf("WriteFull: %v", err) - } - } - ch.Close() - b.StopTimer() - - <-done -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/buffer_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/buffer_test.go deleted file mode 100644 index d5781cb3da..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/buffer_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "io" - "testing" -) - -var alphabet = []byte("abcdefghijklmnopqrstuvwxyz") - -func TestBufferReadwrite(t *testing.T) { - b := newBuffer() - b.write(alphabet[:10]) - r, _ := b.Read(make([]byte, 10)) - if r != 10 { - t.Fatalf("Expected written == read == 10, written: 10, read %d", r) - } - - b = newBuffer() - b.write(alphabet[:5]) - r, _ = b.Read(make([]byte, 10)) - if r != 5 { - t.Fatalf("Expected written == read == 5, written: 5, read %d", r) - } - - b = newBuffer() - b.write(alphabet[:10]) - r, _ = b.Read(make([]byte, 5)) - if r != 5 { - t.Fatalf("Expected written == 10, read == 5, written: 10, read %d", r) - } - - b = newBuffer() - b.write(alphabet[:5]) - b.write(alphabet[5:15]) - r, _ = b.Read(make([]byte, 10)) - r2, _ := b.Read(make([]byte, 10)) - if r != 10 || r2 != 5 || 15 != r+r2 { - t.Fatal("Expected written == read == 15") - } -} - -func TestBufferClose(t *testing.T) { - b := newBuffer() - b.write(alphabet[:10]) - b.eof() - _, err := b.Read(make([]byte, 5)) - if err != nil { - t.Fatal("expected read of 5 to not return EOF") - } - b = newBuffer() - b.write(alphabet[:10]) - b.eof() - r, err := b.Read(make([]byte, 5)) - r2, err2 := b.Read(make([]byte, 10)) - if r != 5 || r2 != 5 || err != nil || err2 != nil { - t.Fatal("expected reads of 5 and 5") - } - - b = newBuffer() - b.write(alphabet[:10]) - b.eof() - r, err = b.Read(make([]byte, 5)) - r2, err2 = b.Read(make([]byte, 10)) - r3, err3 := b.Read(make([]byte, 10)) - if r != 5 || r2 != 5 || r3 != 0 || err != nil || err2 != nil || err3 != io.EOF { - t.Fatal("expected reads of 5 and 5 and 0, with EOF") - } - - b = newBuffer() - b.write(make([]byte, 5)) - b.write(make([]byte, 10)) - b.eof() - r, err = b.Read(make([]byte, 9)) - r2, err2 = b.Read(make([]byte, 3)) - r3, err3 = b.Read(make([]byte, 3)) - r4, err4 := b.Read(make([]byte, 10)) - if err != nil || err2 != nil || err3 != nil || err4 != io.EOF { - t.Fatalf("Expected EOF on forth read only, err=%v, err2=%v, err3=%v, err4=%v", err, err2, err3, err4) - } - if r != 9 || r2 != 3 || r3 != 3 || r4 != 0 { - t.Fatal("Expected written == read == 15", r, r2, r3, r4) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/certs.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/certs.go deleted file mode 100644 index 9962ff0f3d..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/certs.go +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "errors" - "fmt" - "io" - "net" - "sort" - "time" -) - -// These constants from [PROTOCOL.certkeys] represent the algorithm names -// for certificate types supported by this package. -const ( - CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" - CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" - CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" - CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" -) - -// Certificate types distinguish between host and user -// certificates. The values can be set in the CertType field of -// Certificate. -const ( - UserCert = 1 - HostCert = 2 -) - -// Signature represents a cryptographic signature. -type Signature struct { - Format string - Blob []byte -} - -// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that -// a certificate does not expire. -const CertTimeInfinity = 1<<64 - 1 - -// An Certificate represents an OpenSSH certificate as defined in -// [PROTOCOL.certkeys]?rev=1.8. -type Certificate struct { - Nonce []byte - Key PublicKey - Serial uint64 - CertType uint32 - KeyId string - ValidPrincipals []string - ValidAfter uint64 - ValidBefore uint64 - Permissions - Reserved []byte - SignatureKey PublicKey - Signature *Signature -} - -// genericCertData holds the key-independent part of the certificate data. -// Overall, certificates contain an nonce, public key fields and -// key-independent fields. -type genericCertData struct { - Serial uint64 - CertType uint32 - KeyId string - ValidPrincipals []byte - ValidAfter uint64 - ValidBefore uint64 - CriticalOptions []byte - Extensions []byte - Reserved []byte - SignatureKey []byte - Signature []byte -} - -func marshalStringList(namelist []string) []byte { - var to []byte - for _, name := range namelist { - s := struct{ N string }{name} - to = append(to, Marshal(&s)...) - } - return to -} - -func marshalTuples(tups map[string]string) []byte { - keys := make([]string, 0, len(tups)) - for k := range tups { - keys = append(keys, k) - } - sort.Strings(keys) - - var r []byte - for _, k := range keys { - s := struct{ K, V string }{k, tups[k]} - r = append(r, Marshal(&s)...) - } - return r -} - -func parseTuples(in []byte) (map[string]string, error) { - tups := map[string]string{} - var lastKey string - var haveLastKey bool - - for len(in) > 0 { - nameBytes, rest, ok := parseString(in) - if !ok { - return nil, errShortRead - } - data, rest, ok := parseString(rest) - if !ok { - return nil, errShortRead - } - name := string(nameBytes) - - // according to [PROTOCOL.certkeys], the names must be in - // lexical order. - if haveLastKey && name <= lastKey { - return nil, fmt.Errorf("ssh: certificate options are not in lexical order") - } - lastKey, haveLastKey = name, true - - tups[name] = string(data) - in = rest - } - return tups, nil -} - -func parseCert(in []byte, privAlgo string) (*Certificate, error) { - nonce, rest, ok := parseString(in) - if !ok { - return nil, errShortRead - } - - key, rest, err := parsePubKey(rest, privAlgo) - if err != nil { - return nil, err - } - - var g genericCertData - if err := Unmarshal(rest, &g); err != nil { - return nil, err - } - - c := &Certificate{ - Nonce: nonce, - Key: key, - Serial: g.Serial, - CertType: g.CertType, - KeyId: g.KeyId, - ValidAfter: g.ValidAfter, - ValidBefore: g.ValidBefore, - } - - for principals := g.ValidPrincipals; len(principals) > 0; { - principal, rest, ok := parseString(principals) - if !ok { - return nil, errShortRead - } - c.ValidPrincipals = append(c.ValidPrincipals, string(principal)) - principals = rest - } - - c.CriticalOptions, err = parseTuples(g.CriticalOptions) - if err != nil { - return nil, err - } - c.Extensions, err = parseTuples(g.Extensions) - if err != nil { - return nil, err - } - c.Reserved = g.Reserved - k, err := ParsePublicKey(g.SignatureKey) - if err != nil { - return nil, err - } - - c.SignatureKey = k - c.Signature, rest, ok = parseSignatureBody(g.Signature) - if !ok || len(rest) > 0 { - return nil, errors.New("ssh: signature parse error") - } - - return c, nil -} - -type openSSHCertSigner struct { - pub *Certificate - signer Signer -} - -// NewCertSigner returns a Signer that signs with the given Certificate, whose -// private key is held by signer. It returns an error if the public key in cert -// doesn't match the key used by signer. -func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) { - if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 { - return nil, errors.New("ssh: signer and cert have different public key") - } - - return &openSSHCertSigner{cert, signer}, nil -} - -func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) { - return s.signer.Sign(rand, data) -} - -func (s *openSSHCertSigner) PublicKey() PublicKey { - return s.pub -} - -const sourceAddressCriticalOption = "source-address" - -// CertChecker does the work of verifying a certificate. Its methods -// can be plugged into ClientConfig.HostKeyCallback and -// ServerConfig.PublicKeyCallback. For the CertChecker to work, -// minimally, the IsAuthority callback should be set. -type CertChecker struct { - // SupportedCriticalOptions lists the CriticalOptions that the - // server application layer understands. These are only used - // for user certificates. - SupportedCriticalOptions []string - - // IsAuthority should return true if the key is recognized as - // an authority. This allows for certificates to be signed by other - // certificates. - IsAuthority func(auth PublicKey) bool - - // Clock is used for verifying time stamps. If nil, time.Now - // is used. - Clock func() time.Time - - // UserKeyFallback is called when CertChecker.Authenticate encounters a - // public key that is not a certificate. It must implement validation - // of user keys or else, if nil, all such keys are rejected. - UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) - - // HostKeyFallback is called when CertChecker.CheckHostKey encounters a - // public key that is not a certificate. It must implement host key - // validation or else, if nil, all such keys are rejected. - HostKeyFallback func(addr string, remote net.Addr, key PublicKey) error - - // IsRevoked is called for each certificate so that revocation checking - // can be implemented. It should return true if the given certificate - // is revoked and false otherwise. If nil, no certificates are - // considered to have been revoked. - IsRevoked func(cert *Certificate) bool -} - -// CheckHostKey checks a host key certificate. This method can be -// plugged into ClientConfig.HostKeyCallback. -func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error { - cert, ok := key.(*Certificate) - if !ok { - if c.HostKeyFallback != nil { - return c.HostKeyFallback(addr, remote, key) - } - return errors.New("ssh: non-certificate host key") - } - if cert.CertType != HostCert { - return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType) - } - - return c.CheckCert(addr, cert) -} - -// Authenticate checks a user certificate. Authenticate can be used as -// a value for ServerConfig.PublicKeyCallback. -func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) { - cert, ok := pubKey.(*Certificate) - if !ok { - if c.UserKeyFallback != nil { - return c.UserKeyFallback(conn, pubKey) - } - return nil, errors.New("ssh: normal key pairs not accepted") - } - - if cert.CertType != UserCert { - return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType) - } - - if err := c.CheckCert(conn.User(), cert); err != nil { - return nil, err - } - - return &cert.Permissions, nil -} - -// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and -// the signature of the certificate. -func (c *CertChecker) CheckCert(principal string, cert *Certificate) error { - if c.IsRevoked != nil && c.IsRevoked(cert) { - return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial) - } - - for opt, _ := range cert.CriticalOptions { - // sourceAddressCriticalOption will be enforced by - // serverAuthenticate - if opt == sourceAddressCriticalOption { - continue - } - - found := false - for _, supp := range c.SupportedCriticalOptions { - if supp == opt { - found = true - break - } - } - if !found { - return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt) - } - } - - if len(cert.ValidPrincipals) > 0 { - // By default, certs are valid for all users/hosts. - found := false - for _, p := range cert.ValidPrincipals { - if p == principal { - found = true - break - } - } - if !found { - return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals) - } - } - - if !c.IsAuthority(cert.SignatureKey) { - return fmt.Errorf("ssh: certificate signed by unrecognized authority") - } - - clock := c.Clock - if clock == nil { - clock = time.Now - } - - unixNow := clock().Unix() - if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) { - return fmt.Errorf("ssh: cert is not yet valid") - } - if before := int64(cert.ValidBefore); cert.ValidBefore != CertTimeInfinity && (unixNow >= before || before < 0) { - return fmt.Errorf("ssh: cert has expired") - } - if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil { - return fmt.Errorf("ssh: certificate signature does not verify") - } - - return nil -} - -// SignCert sets c.SignatureKey to the authority's public key and stores a -// Signature, by authority, in the certificate. -func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { - c.Nonce = make([]byte, 32) - if _, err := io.ReadFull(rand, c.Nonce); err != nil { - return err - } - c.SignatureKey = authority.PublicKey() - - sig, err := authority.Sign(rand, c.bytesForSigning()) - if err != nil { - return err - } - c.Signature = sig - return nil -} - -var certAlgoNames = map[string]string{ - KeyAlgoRSA: CertAlgoRSAv01, - KeyAlgoDSA: CertAlgoDSAv01, - KeyAlgoECDSA256: CertAlgoECDSA256v01, - KeyAlgoECDSA384: CertAlgoECDSA384v01, - KeyAlgoECDSA521: CertAlgoECDSA521v01, -} - -// certToPrivAlgo returns the underlying algorithm for a certificate algorithm. -// Panics if a non-certificate algorithm is passed. -func certToPrivAlgo(algo string) string { - for privAlgo, pubAlgo := range certAlgoNames { - if pubAlgo == algo { - return privAlgo - } - } - panic("unknown cert algorithm") -} - -func (cert *Certificate) bytesForSigning() []byte { - c2 := *cert - c2.Signature = nil - out := c2.Marshal() - // Drop trailing signature length. - return out[:len(out)-4] -} - -// Marshal serializes c into OpenSSH's wire format. It is part of the -// PublicKey interface. -func (c *Certificate) Marshal() []byte { - generic := genericCertData{ - Serial: c.Serial, - CertType: c.CertType, - KeyId: c.KeyId, - ValidPrincipals: marshalStringList(c.ValidPrincipals), - ValidAfter: uint64(c.ValidAfter), - ValidBefore: uint64(c.ValidBefore), - CriticalOptions: marshalTuples(c.CriticalOptions), - Extensions: marshalTuples(c.Extensions), - Reserved: c.Reserved, - SignatureKey: c.SignatureKey.Marshal(), - } - if c.Signature != nil { - generic.Signature = Marshal(c.Signature) - } - genericBytes := Marshal(&generic) - keyBytes := c.Key.Marshal() - _, keyBytes, _ = parseString(keyBytes) - prefix := Marshal(&struct { - Name string - Nonce []byte - Key []byte `ssh:"rest"` - }{c.Type(), c.Nonce, keyBytes}) - - result := make([]byte, 0, len(prefix)+len(genericBytes)) - result = append(result, prefix...) - result = append(result, genericBytes...) - return result -} - -// Type returns the key name. It is part of the PublicKey interface. -func (c *Certificate) Type() string { - algo, ok := certAlgoNames[c.Key.Type()] - if !ok { - panic("unknown cert key type") - } - return algo -} - -// Verify verifies a signature against the certificate's public -// key. It is part of the PublicKey interface. -func (c *Certificate) Verify(data []byte, sig *Signature) error { - return c.Key.Verify(data, sig) -} - -func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) { - format, in, ok := parseString(in) - if !ok { - return - } - - out = &Signature{ - Format: string(format), - } - - if out.Blob, in, ok = parseString(in); !ok { - return - } - - return out, in, ok -} - -func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) { - sigBytes, rest, ok := parseString(in) - if !ok { - return - } - - out, trailing, ok := parseSignatureBody(sigBytes) - if !ok || len(trailing) > 0 { - return nil, nil, false - } - return -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/certs_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/certs_test.go deleted file mode 100644 index 7d1b00f6d1..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/certs_test.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto/rand" - "testing" - "time" -) - -// Cert generated by ssh-keygen 6.0p1 Debian-4. -// % ssh-keygen -s ca-key -I test user-key -var exampleSSHCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=` - -func TestParseCert(t *testing.T) { - authKeyBytes := []byte(exampleSSHCert) - - key, _, _, rest, err := ParseAuthorizedKey(authKeyBytes) - if err != nil { - t.Fatalf("ParseAuthorizedKey: %v", err) - } - if len(rest) > 0 { - t.Errorf("rest: got %q, want empty", rest) - } - - if _, ok := key.(*Certificate); !ok { - t.Fatalf("got %#v, want *Certificate", key) - } - - marshaled := MarshalAuthorizedKey(key) - // Before comparison, remove the trailing newline that - // MarshalAuthorizedKey adds. - marshaled = marshaled[:len(marshaled)-1] - if !bytes.Equal(authKeyBytes, marshaled) { - t.Errorf("marshaled certificate does not match original: got %q, want %q", marshaled, authKeyBytes) - } -} - -func TestValidateCert(t *testing.T) { - key, _, _, _, err := ParseAuthorizedKey([]byte(exampleSSHCert)) - if err != nil { - t.Fatalf("ParseAuthorizedKey: %v", err) - } - validCert, ok := key.(*Certificate) - if !ok { - t.Fatalf("got %v (%T), want *Certificate", key, key) - } - checker := CertChecker{} - checker.IsAuthority = func(k PublicKey) bool { - return bytes.Equal(k.Marshal(), validCert.SignatureKey.Marshal()) - } - - if err := checker.CheckCert("user", validCert); err != nil { - t.Errorf("Unable to validate certificate: %v", err) - } - invalidCert := &Certificate{ - Key: testPublicKeys["rsa"], - SignatureKey: testPublicKeys["ecdsa"], - ValidBefore: CertTimeInfinity, - Signature: &Signature{}, - } - if err := checker.CheckCert("user", invalidCert); err == nil { - t.Error("Invalid cert signature passed validation") - } -} - -func TestValidateCertTime(t *testing.T) { - cert := Certificate{ - ValidPrincipals: []string{"user"}, - Key: testPublicKeys["rsa"], - ValidAfter: 50, - ValidBefore: 100, - } - - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - - for ts, ok := range map[int64]bool{ - 25: false, - 50: true, - 99: true, - 100: false, - 125: false, - } { - checker := CertChecker{ - Clock: func() time.Time { return time.Unix(ts, 0) }, - } - checker.IsAuthority = func(k PublicKey) bool { - return bytes.Equal(k.Marshal(), - testPublicKeys["ecdsa"].Marshal()) - } - - if v := checker.CheckCert("user", &cert); (v == nil) != ok { - t.Errorf("Authenticate(%d): %v", ts, v) - } - } -} - -// TODO(hanwen): tests for -// -// host keys: -// * fallbacks - -func TestHostKeyCert(t *testing.T) { - cert := &Certificate{ - ValidPrincipals: []string{"hostname", "hostname.domain"}, - Key: testPublicKeys["rsa"], - ValidBefore: CertTimeInfinity, - CertType: HostCert, - } - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - - checker := &CertChecker{ - IsAuthority: func(p PublicKey) bool { - return bytes.Equal(testPublicKeys["ecdsa"].Marshal(), p.Marshal()) - }, - } - - certSigner, err := NewCertSigner(cert, testSigners["rsa"]) - if err != nil { - t.Errorf("NewCertSigner: %v", err) - } - - for _, name := range []string{"hostname", "otherhost"} { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - go func() { - conf := ServerConfig{ - NoClientAuth: true, - } - conf.AddHostKey(certSigner) - _, _, _, err := NewServerConn(c1, &conf) - if err != nil { - t.Fatalf("NewServerConn: %v", err) - } - }() - - config := &ClientConfig{ - User: "user", - HostKeyCallback: checker.CheckHostKey, - } - _, _, _, err = NewClientConn(c2, name, config) - - succeed := name == "hostname" - if (err == nil) != succeed { - t.Fatalf("NewClientConn(%q): %v", name, err) - } - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/cipher.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/cipher.go deleted file mode 100644 index 642696bbbb..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/cipher.go +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rc4" - "crypto/subtle" - "encoding/binary" - "errors" - "fmt" - "hash" - "io" -) - -const ( - packetSizeMultiple = 16 // TODO(huin) this should be determined by the cipher. - - // RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations - // MUST be able to process (plus a few more kilobytes for padding and mac). The RFC - // indicates implementations SHOULD be able to handle larger packet sizes, but then - // waffles on about reasonable limits. - // - // OpenSSH caps their maxPacket at 256kB so we choose to do - // the same. maxPacket is also used to ensure that uint32 - // length fields do not overflow, so it should remain well - // below 4G. - maxPacket = 256 * 1024 -) - -// noneCipher implements cipher.Stream and provides no encryption. It is used -// by the transport before the first key-exchange. -type noneCipher struct{} - -func (c noneCipher) XORKeyStream(dst, src []byte) { - copy(dst, src) -} - -func newAESCTR(key, iv []byte) (cipher.Stream, error) { - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - return cipher.NewCTR(c, iv), nil -} - -func newRC4(key, iv []byte) (cipher.Stream, error) { - return rc4.NewCipher(key) -} - -type streamCipherMode struct { - keySize int - ivSize int - skip int - createFunc func(key, iv []byte) (cipher.Stream, error) -} - -func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) { - if len(key) < c.keySize { - panic("ssh: key length too small for cipher") - } - if len(iv) < c.ivSize { - panic("ssh: iv too small for cipher") - } - - stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize]) - if err != nil { - return nil, err - } - - var streamDump []byte - if c.skip > 0 { - streamDump = make([]byte, 512) - } - - for remainingToDump := c.skip; remainingToDump > 0; { - dumpThisTime := remainingToDump - if dumpThisTime > len(streamDump) { - dumpThisTime = len(streamDump) - } - stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime]) - remainingToDump -= dumpThisTime - } - - return stream, nil -} - -// cipherModes documents properties of supported ciphers. Ciphers not included -// are not supported and will not be negotiated, even if explicitly requested in -// ClientConfig.Crypto.Ciphers. -var cipherModes = map[string]*streamCipherMode{ - // Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms - // are defined in the order specified in the RFC. - "aes128-ctr": {16, aes.BlockSize, 0, newAESCTR}, - "aes192-ctr": {24, aes.BlockSize, 0, newAESCTR}, - "aes256-ctr": {32, aes.BlockSize, 0, newAESCTR}, - - // Ciphers from RFC4345, which introduces security-improved arcfour ciphers. - // They are defined in the order specified in the RFC. - "arcfour128": {16, 0, 1536, newRC4}, - "arcfour256": {32, 0, 1536, newRC4}, - - // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. - // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and - // RC4) has problems with weak keys, and should be used with caution." - // RFC4345 introduces improved versions of Arcfour. - "arcfour": {16, 0, 0, newRC4}, - - // AES-GCM is not a stream cipher, so it is constructed with a - // special case. If we add any more non-stream ciphers, we - // should invest a cleaner way to do this. - gcmCipherID: {16, 12, 0, nil}, -} - -// prefixLen is the length of the packet prefix that contains the packet length -// and number of padding bytes. -const prefixLen = 5 - -// streamPacketCipher is a packetCipher using a stream cipher. -type streamPacketCipher struct { - mac hash.Hash - cipher cipher.Stream - - // The following members are to avoid per-packet allocations. - prefix [prefixLen]byte - seqNumBytes [4]byte - padding [2 * packetSizeMultiple]byte - packetData []byte - macResult []byte -} - -// readPacket reads and decrypt a single packet from the reader argument. -func (s *streamPacketCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) { - if _, err := io.ReadFull(r, s.prefix[:]); err != nil { - return nil, err - } - - s.cipher.XORKeyStream(s.prefix[:], s.prefix[:]) - length := binary.BigEndian.Uint32(s.prefix[0:4]) - paddingLength := uint32(s.prefix[4]) - - var macSize uint32 - if s.mac != nil { - s.mac.Reset() - binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum) - s.mac.Write(s.seqNumBytes[:]) - s.mac.Write(s.prefix[:]) - macSize = uint32(s.mac.Size()) - } - - if length <= paddingLength+1 { - return nil, errors.New("ssh: invalid packet length, packet too small") - } - - if length > maxPacket { - return nil, errors.New("ssh: invalid packet length, packet too large") - } - - // the maxPacket check above ensures that length-1+macSize - // does not overflow. - if uint32(cap(s.packetData)) < length-1+macSize { - s.packetData = make([]byte, length-1+macSize) - } else { - s.packetData = s.packetData[:length-1+macSize] - } - - if _, err := io.ReadFull(r, s.packetData); err != nil { - return nil, err - } - mac := s.packetData[length-1:] - data := s.packetData[:length-1] - s.cipher.XORKeyStream(data, data) - - if s.mac != nil { - s.mac.Write(data) - s.macResult = s.mac.Sum(s.macResult[:0]) - if subtle.ConstantTimeCompare(s.macResult, mac) != 1 { - return nil, errors.New("ssh: MAC failure") - } - } - - return s.packetData[:length-paddingLength-1], nil -} - -// writePacket encrypts and sends a packet of data to the writer argument -func (s *streamPacketCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error { - if len(packet) > maxPacket { - return errors.New("ssh: packet too large") - } - - paddingLength := packetSizeMultiple - (prefixLen+len(packet))%packetSizeMultiple - if paddingLength < 4 { - paddingLength += packetSizeMultiple - } - - length := len(packet) + 1 + paddingLength - binary.BigEndian.PutUint32(s.prefix[:], uint32(length)) - s.prefix[4] = byte(paddingLength) - padding := s.padding[:paddingLength] - if _, err := io.ReadFull(rand, padding); err != nil { - return err - } - - if s.mac != nil { - s.mac.Reset() - binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum) - s.mac.Write(s.seqNumBytes[:]) - s.mac.Write(s.prefix[:]) - s.mac.Write(packet) - s.mac.Write(padding) - } - - s.cipher.XORKeyStream(s.prefix[:], s.prefix[:]) - s.cipher.XORKeyStream(packet, packet) - s.cipher.XORKeyStream(padding, padding) - - if _, err := w.Write(s.prefix[:]); err != nil { - return err - } - if _, err := w.Write(packet); err != nil { - return err - } - if _, err := w.Write(padding); err != nil { - return err - } - - if s.mac != nil { - s.macResult = s.mac.Sum(s.macResult[:0]) - if _, err := w.Write(s.macResult); err != nil { - return err - } - } - - return nil -} - -type gcmCipher struct { - aead cipher.AEAD - prefix [4]byte - iv []byte - buf []byte -} - -func newGCMCipher(iv, key, macKey []byte) (packetCipher, error) { - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - aead, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - return &gcmCipher{ - aead: aead, - iv: iv, - }, nil -} - -const gcmTagSize = 16 - -func (c *gcmCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error { - // Pad out to multiple of 16 bytes. This is different from the - // stream cipher because that encrypts the length too. - padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple) - if padding < 4 { - padding += packetSizeMultiple - } - - length := uint32(len(packet) + int(padding) + 1) - binary.BigEndian.PutUint32(c.prefix[:], length) - if _, err := w.Write(c.prefix[:]); err != nil { - return err - } - - if cap(c.buf) < int(length) { - c.buf = make([]byte, length) - } else { - c.buf = c.buf[:length] - } - - c.buf[0] = padding - copy(c.buf[1:], packet) - if _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil { - return err - } - c.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:]) - if _, err := w.Write(c.buf); err != nil { - return err - } - c.incIV() - - return nil -} - -func (c *gcmCipher) incIV() { - for i := 4 + 7; i >= 4; i-- { - c.iv[i]++ - if c.iv[i] != 0 { - break - } - } -} - -func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) { - if _, err := io.ReadFull(r, c.prefix[:]); err != nil { - return nil, err - } - length := binary.BigEndian.Uint32(c.prefix[:]) - if length > maxPacket { - return nil, errors.New("ssh: max packet length exceeded.") - } - - if cap(c.buf) < int(length+gcmTagSize) { - c.buf = make([]byte, length+gcmTagSize) - } else { - c.buf = c.buf[:length+gcmTagSize] - } - - if _, err := io.ReadFull(r, c.buf); err != nil { - return nil, err - } - - plain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:]) - if err != nil { - return nil, err - } - c.incIV() - - padding := plain[0] - if padding < 4 || padding >= 20 { - return nil, fmt.Errorf("ssh: illegal padding %d", padding) - } - - if int(padding+1) >= len(plain) { - return nil, fmt.Errorf("ssh: padding %d too large", padding) - } - plain = plain[1 : length-uint32(padding)] - return plain, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/cipher_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/cipher_test.go deleted file mode 100644 index e279af04bd..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/cipher_test.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto" - "crypto/rand" - "testing" -) - -func TestDefaultCiphersExist(t *testing.T) { - for _, cipherAlgo := range supportedCiphers { - if _, ok := cipherModes[cipherAlgo]; !ok { - t.Errorf("default cipher %q is unknown", cipherAlgo) - } - } -} - -func TestPacketCiphers(t *testing.T) { - for cipher := range cipherModes { - kr := &kexResult{Hash: crypto.SHA1} - algs := directionAlgorithms{ - Cipher: cipher, - MAC: "hmac-sha1", - Compression: "none", - } - client, err := newPacketCipher(clientKeys, algs, kr) - if err != nil { - t.Errorf("newPacketCipher(client, %q): %v", cipher, err) - continue - } - server, err := newPacketCipher(clientKeys, algs, kr) - if err != nil { - t.Errorf("newPacketCipher(client, %q): %v", cipher, err) - continue - } - - want := "bla bla" - input := []byte(want) - buf := &bytes.Buffer{} - if err := client.writePacket(0, buf, rand.Reader, input); err != nil { - t.Errorf("writePacket(%q): %v", cipher, err) - continue - } - - packet, err := server.readPacket(0, buf) - if err != nil { - t.Errorf("readPacket(%q): %v", cipher, err) - continue - } - - if string(packet) != want { - t.Errorf("roundtrip(%q): got %q, want %q", cipher, packet, want) - } - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/client.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/client.go deleted file mode 100644 index 03c4e77d4d..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/client.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "errors" - "fmt" - "net" - "sync" -) - -// Client implements a traditional SSH client that supports shells, -// subprocesses, port forwarding and tunneled dialing. -type Client struct { - Conn - - forwards forwardList // forwarded tcpip connections from the remote side - mu sync.Mutex - channelHandlers map[string]chan NewChannel -} - -// HandleChannelOpen returns a channel on which NewChannel requests -// for the given type are sent. If the type already is being handled, -// nil is returned. The channel is closed when the connection is closed. -func (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel { - c.mu.Lock() - defer c.mu.Unlock() - if c.channelHandlers == nil { - // The SSH channel has been closed. - c := make(chan NewChannel) - close(c) - return c - } - - ch := c.channelHandlers[channelType] - if ch != nil { - return nil - } - - ch = make(chan NewChannel, 16) - c.channelHandlers[channelType] = ch - return ch -} - -// NewClient creates a Client on top of the given connection. -func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client { - conn := &Client{ - Conn: c, - channelHandlers: make(map[string]chan NewChannel, 1), - } - - go conn.handleGlobalRequests(reqs) - go conn.handleChannelOpens(chans) - go func() { - conn.Wait() - conn.forwards.closeAll() - }() - go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip")) - return conn -} - -// NewClientConn establishes an authenticated SSH connection using c -// as the underlying transport. The Request and NewChannel channels -// must be serviced or the connection will hang. -func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) { - fullConf := *config - fullConf.SetDefaults() - conn := &connection{ - sshConn: sshConn{conn: c}, - } - - if err := conn.clientHandshake(addr, &fullConf); err != nil { - c.Close() - return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err) - } - conn.mux = newMux(conn.transport) - return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil -} - -// clientHandshake performs the client side key exchange. See RFC 4253 Section -// 7. -func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error { - c.clientVersion = []byte(packageVersion) - if config.ClientVersion != "" { - c.clientVersion = []byte(config.ClientVersion) - } - - var err error - c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion) - if err != nil { - return err - } - - c.transport = newClientTransport( - newTransport(c.sshConn.conn, config.Rand, true /* is client */), - c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr()) - if err := c.transport.requestKeyChange(); err != nil { - return err - } - - if packet, err := c.transport.readPacket(); err != nil { - return err - } else if packet[0] != msgNewKeys { - return unexpectedMessageError(msgNewKeys, packet[0]) - } - return c.clientAuthenticate(config) -} - -// verifyHostKeySignature verifies the host key obtained in the key -// exchange. -func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error { - sig, rest, ok := parseSignatureBody(result.Signature) - if len(rest) > 0 || !ok { - return errors.New("ssh: signature parse error") - } - - return hostKey.Verify(result.H, sig) -} - -// NewSession opens a new Session for this client. (A session is a remote -// execution of a program.) -func (c *Client) NewSession() (*Session, error) { - ch, in, err := c.OpenChannel("session", nil) - if err != nil { - return nil, err - } - return newSession(ch, in) -} - -func (c *Client) handleGlobalRequests(incoming <-chan *Request) { - for r := range incoming { - // This handles keepalive messages and matches - // the behaviour of OpenSSH. - r.Reply(false, nil) - } -} - -// handleChannelOpens channel open messages from the remote side. -func (c *Client) handleChannelOpens(in <-chan NewChannel) { - for ch := range in { - c.mu.Lock() - handler := c.channelHandlers[ch.ChannelType()] - c.mu.Unlock() - - if handler != nil { - handler <- ch - } else { - ch.Reject(UnknownChannelType, fmt.Sprintf("unknown channel type: %v", ch.ChannelType())) - } - } - - c.mu.Lock() - for _, ch := range c.channelHandlers { - close(ch) - } - c.channelHandlers = nil - c.mu.Unlock() -} - -// Dial starts a client connection to the given SSH server. It is a -// convenience function that connects to the given network address, -// initiates the SSH handshake, and then sets up a Client. For access -// to incoming channels and requests, use net.Dial with NewClientConn -// instead. -func Dial(network, addr string, config *ClientConfig) (*Client, error) { - conn, err := net.Dial(network, addr) - if err != nil { - return nil, err - } - c, chans, reqs, err := NewClientConn(conn, addr, config) - if err != nil { - return nil, err - } - return NewClient(c, chans, reqs), nil -} - -// A ClientConfig structure is used to configure a Client. It must not be -// modified after having been passed to an SSH function. -type ClientConfig struct { - // Config contains configuration that is shared between clients and - // servers. - Config - - // User contains the username to authenticate as. - User string - - // Auth contains possible authentication methods to use with the - // server. Only the first instance of a particular RFC 4252 method will - // be used during authentication. - Auth []AuthMethod - - // HostKeyCallback, if not nil, is called during the cryptographic - // handshake to validate the server's host key. A nil HostKeyCallback - // implies that all host keys are accepted. - HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error - - // ClientVersion contains the version identification string that will - // be used for the connection. If empty, a reasonable default is used. - ClientVersion string -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/client_auth_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/client_auth_test.go deleted file mode 100644 index c92b58786b..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/client_auth_test.go +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto/rand" - "errors" - "fmt" - "strings" - "testing" -) - -type keyboardInteractive map[string]string - -func (cr keyboardInteractive) Challenge(user string, instruction string, questions []string, echos []bool) ([]string, error) { - var answers []string - for _, q := range questions { - answers = append(answers, cr[q]) - } - return answers, nil -} - -// reused internally by tests -var clientPassword = "tiger" - -// tryAuth runs a handshake with a given config against an SSH server -// with config serverConfig -func tryAuth(t *testing.T, config *ClientConfig) error { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - certChecker := CertChecker{ - IsAuthority: func(k PublicKey) bool { - return bytes.Equal(k.Marshal(), testPublicKeys["ecdsa"].Marshal()) - }, - UserKeyFallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) { - if conn.User() == "testuser" && bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) { - return nil, nil - } - - return nil, fmt.Errorf("pubkey for %q not acceptable", conn.User()) - }, - IsRevoked: func(c *Certificate) bool { - return c.Serial == 666 - }, - } - - serverConfig := &ServerConfig{ - PasswordCallback: func(conn ConnMetadata, pass []byte) (*Permissions, error) { - if conn.User() == "testuser" && string(pass) == clientPassword { - return nil, nil - } - return nil, errors.New("password auth failed") - }, - PublicKeyCallback: certChecker.Authenticate, - KeyboardInteractiveCallback: func(conn ConnMetadata, challenge KeyboardInteractiveChallenge) (*Permissions, error) { - ans, err := challenge("user", - "instruction", - []string{"question1", "question2"}, - []bool{true, true}) - if err != nil { - return nil, err - } - ok := conn.User() == "testuser" && ans[0] == "answer1" && ans[1] == "answer2" - if ok { - challenge("user", "motd", nil, nil) - return nil, nil - } - return nil, errors.New("keyboard-interactive failed") - }, - AuthLogCallback: func(conn ConnMetadata, method string, err error) { - t.Logf("user %q, method %q: %v", conn.User(), method, err) - }, - } - serverConfig.AddHostKey(testSigners["rsa"]) - - go newServer(c1, serverConfig) - _, _, _, err = NewClientConn(c2, "", config) - return err -} - -func TestClientAuthPublicKey(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - }, - } - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodPassword(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - Password(clientPassword), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodFallback(t *testing.T) { - var passwordCalled bool - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - PasswordCallback( - func() (string, error) { - passwordCalled = true - return "WRONG", nil - }), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } - - if passwordCalled { - t.Errorf("password auth tried before public-key auth.") - } -} - -func TestAuthMethodWrongPassword(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - Password("wrong"), - PublicKeys(testSigners["rsa"]), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodKeyboardInteractive(t *testing.T) { - answers := keyboardInteractive(map[string]string{ - "question1": "answer1", - "question2": "answer2", - }) - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - KeyboardInteractive(answers.Challenge), - }, - } - - if err := tryAuth(t, config); err != nil { - t.Fatalf("unable to dial remote side: %s", err) - } -} - -func TestAuthMethodWrongKeyboardInteractive(t *testing.T) { - answers := keyboardInteractive(map[string]string{ - "question1": "answer1", - "question2": "WRONG", - }) - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - KeyboardInteractive(answers.Challenge), - }, - } - - if err := tryAuth(t, config); err == nil { - t.Fatalf("wrong answers should not have authenticated with KeyboardInteractive") - } -} - -// the mock server will only authenticate ssh-rsa keys -func TestAuthMethodInvalidPublicKey(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["dsa"]), - }, - } - - if err := tryAuth(t, config); err == nil { - t.Fatalf("dsa private key should not have authenticated with rsa public key") - } -} - -// the client should authenticate with the second key -func TestAuthMethodRSAandDSA(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["dsa"], testSigners["rsa"]), - }, - } - if err := tryAuth(t, config); err != nil { - t.Fatalf("client could not authenticate with rsa key: %v", err) - } -} - -func TestClientHMAC(t *testing.T) { - for _, mac := range supportedMACs { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - }, - Config: Config{ - MACs: []string{mac}, - }, - } - if err := tryAuth(t, config); err != nil { - t.Fatalf("client could not authenticate with mac algo %s: %v", mac, err) - } - } -} - -// issue 4285. -func TestClientUnsupportedCipher(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(), - }, - Config: Config{ - Ciphers: []string{"aes128-cbc"}, // not currently supported - }, - } - if err := tryAuth(t, config); err == nil { - t.Errorf("expected no ciphers in common") - } -} - -func TestClientUnsupportedKex(t *testing.T) { - config := &ClientConfig{ - User: "testuser", - Auth: []AuthMethod{ - PublicKeys(), - }, - Config: Config{ - KeyExchanges: []string{"diffie-hellman-group-exchange-sha256"}, // not currently supported - }, - } - if err := tryAuth(t, config); err == nil || !strings.Contains(err.Error(), "no common algorithms") { - t.Errorf("got %v, expected 'no common algorithms'", err) - } -} - -func TestClientLoginCert(t *testing.T) { - cert := &Certificate{ - Key: testPublicKeys["rsa"], - ValidBefore: CertTimeInfinity, - CertType: UserCert, - } - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - certSigner, err := NewCertSigner(cert, testSigners["rsa"]) - if err != nil { - t.Fatalf("NewCertSigner: %v", err) - } - - clientConfig := &ClientConfig{ - User: "user", - } - clientConfig.Auth = append(clientConfig.Auth, PublicKeys(certSigner)) - - t.Log("should succeed") - if err := tryAuth(t, clientConfig); err != nil { - t.Errorf("cert login failed: %v", err) - } - - t.Log("corrupted signature") - cert.Signature.Blob[0]++ - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with corrupted sig") - } - - t.Log("revoked") - cert.Serial = 666 - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("revoked cert login succeeded") - } - cert.Serial = 1 - - t.Log("sign with wrong key") - cert.SignCert(rand.Reader, testSigners["dsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with non-authoritive key") - } - - t.Log("host cert") - cert.CertType = HostCert - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with wrong type") - } - cert.CertType = UserCert - - t.Log("principal specified") - cert.ValidPrincipals = []string{"user"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err != nil { - t.Errorf("cert login failed: %v", err) - } - - t.Log("wrong principal specified") - cert.ValidPrincipals = []string{"fred"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with wrong principal") - } - cert.ValidPrincipals = nil - - t.Log("added critical option") - cert.CriticalOptions = map[string]string{"root-access": "yes"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login passed with unrecognized critical option") - } - - t.Log("allowed source address") - cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42/24"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err != nil { - t.Errorf("cert login with source-address failed: %v", err) - } - - t.Log("disallowed source address") - cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42"} - cert.SignCert(rand.Reader, testSigners["ecdsa"]) - if err := tryAuth(t, clientConfig); err == nil { - t.Errorf("cert login with source-address succeeded") - } -} - -func testPermissionsPassing(withPermissions bool, t *testing.T) { - serverConfig := &ServerConfig{ - PublicKeyCallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) { - if conn.User() == "nopermissions" { - return nil, nil - } else { - return &Permissions{}, nil - } - }, - } - serverConfig.AddHostKey(testSigners["rsa"]) - - clientConfig := &ClientConfig{ - Auth: []AuthMethod{ - PublicKeys(testSigners["rsa"]), - }, - } - if withPermissions { - clientConfig.User = "permissions" - } else { - clientConfig.User = "nopermissions" - } - - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - defer c1.Close() - defer c2.Close() - - go NewClientConn(c2, "", clientConfig) - serverConn, err := newServer(c1, serverConfig) - if err != nil { - t.Fatal(err) - } - if p := serverConn.Permissions; (p != nil) != withPermissions { - t.Fatalf("withPermissions is %t, but Permissions object is %#v", withPermissions, p) - } -} - -func TestPermissionsPassing(t *testing.T) { - testPermissionsPassing(true, t) -} - -func TestNoPermissionsPassing(t *testing.T) { - testPermissionsPassing(false, t) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/client_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/client_test.go deleted file mode 100644 index 1fe790cb49..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/client_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "net" - "testing" -) - -func testClientVersion(t *testing.T, config *ClientConfig, expected string) { - clientConn, serverConn := net.Pipe() - defer clientConn.Close() - receivedVersion := make(chan string, 1) - go func() { - version, err := readVersion(serverConn) - if err != nil { - receivedVersion <- "" - } else { - receivedVersion <- string(version) - } - serverConn.Close() - }() - NewClientConn(clientConn, "", config) - actual := <-receivedVersion - if actual != expected { - t.Fatalf("got %s; want %s", actual, expected) - } -} - -func TestCustomClientVersion(t *testing.T) { - version := "Test-Client-Version-0.0" - testClientVersion(t, &ClientConfig{ClientVersion: version}, version) -} - -func TestDefaultClientVersion(t *testing.T) { - testClientVersion(t, &ClientConfig{}, packageVersion) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/common.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/common.go deleted file mode 100644 index 2fd7fd9270..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/common.go +++ /dev/null @@ -1,357 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "crypto" - "crypto/rand" - "fmt" - "io" - "sync" - - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" -) - -// These are string constants in the SSH protocol. -const ( - compressionNone = "none" - serviceUserAuth = "ssh-userauth" - serviceSSH = "ssh-connection" -) - -// supportedCiphers specifies the supported ciphers in preference order. -var supportedCiphers = []string{ - "aes128-ctr", "aes192-ctr", "aes256-ctr", - "aes128-gcm@openssh.com", - "arcfour256", "arcfour128", -} - -// supportedKexAlgos specifies the supported key-exchange algorithms in -// preference order. -var supportedKexAlgos = []string{ - // P384 and P521 are not constant-time yet, but since we don't - // reuse ephemeral keys, using them for ECDH should be OK. - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA1, kexAlgoDH1SHA1, -} - -// supportedKexAlgos specifies the supported host-key algorithms (i.e. methods -// of authenticating servers) in preference order. -var supportedHostKeyAlgos = []string{ - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, - CertAlgoECDSA384v01, CertAlgoECDSA521v01, - - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSA, KeyAlgoDSA, -} - -// supportedMACs specifies a default set of MAC algorithms in preference order. -// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed -// because they have reached the end of their useful life. -var supportedMACs = []string{ - "hmac-sha1", "hmac-sha1-96", -} - -var supportedCompressions = []string{compressionNone} - -// hashFuncs keeps the mapping of supported algorithms to their respective -// hashes needed for signature verification. -var hashFuncs = map[string]crypto.Hash{ - KeyAlgoRSA: crypto.SHA1, - KeyAlgoDSA: crypto.SHA1, - KeyAlgoECDSA256: crypto.SHA256, - KeyAlgoECDSA384: crypto.SHA384, - KeyAlgoECDSA521: crypto.SHA512, - CertAlgoRSAv01: crypto.SHA1, - CertAlgoDSAv01: crypto.SHA1, - CertAlgoECDSA256v01: crypto.SHA256, - CertAlgoECDSA384v01: crypto.SHA384, - CertAlgoECDSA521v01: crypto.SHA512, -} - -// unexpectedMessageError results when the SSH message that we received didn't -// match what we wanted. -func unexpectedMessageError(expected, got uint8) error { - return fmt.Errorf("ssh: unexpected message type %d (expected %d)", got, expected) -} - -// parseError results from a malformed SSH message. -func parseError(tag uint8) error { - return fmt.Errorf("ssh: parse error in message type %d", tag) -} - -func findCommonAlgorithm(clientAlgos []string, serverAlgos []string) (commonAlgo string, ok bool) { - for _, clientAlgo := range clientAlgos { - for _, serverAlgo := range serverAlgos { - if clientAlgo == serverAlgo { - return clientAlgo, true - } - } - } - return -} - -func findCommonCipher(clientCiphers []string, serverCiphers []string) (commonCipher string, ok bool) { - for _, clientCipher := range clientCiphers { - for _, serverCipher := range serverCiphers { - // reject the cipher if we have no cipherModes definition - if clientCipher == serverCipher && cipherModes[clientCipher] != nil { - return clientCipher, true - } - } - } - return -} - -type directionAlgorithms struct { - Cipher string - MAC string - Compression string -} - -type algorithms struct { - kex string - hostKey string - w directionAlgorithms - r directionAlgorithms -} - -func findAgreedAlgorithms(clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms) { - var ok bool - result := &algorithms{} - result.kex, ok = findCommonAlgorithm(clientKexInit.KexAlgos, serverKexInit.KexAlgos) - if !ok { - return - } - - result.hostKey, ok = findCommonAlgorithm(clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) - if !ok { - return - } - - result.w.Cipher, ok = findCommonCipher(clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer) - if !ok { - return - } - - result.r.Cipher, ok = findCommonCipher(clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient) - if !ok { - return - } - - result.w.MAC, ok = findCommonAlgorithm(clientKexInit.MACsClientServer, serverKexInit.MACsClientServer) - if !ok { - return - } - - result.r.MAC, ok = findCommonAlgorithm(clientKexInit.MACsServerClient, serverKexInit.MACsServerClient) - if !ok { - return - } - - result.w.Compression, ok = findCommonAlgorithm(clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) - if !ok { - return - } - - result.r.Compression, ok = findCommonAlgorithm(clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) - if !ok { - return - } - - return result -} - -// If rekeythreshold is too small, we can't make any progress sending -// stuff. -const minRekeyThreshold uint64 = 256 - -// Config contains configuration data common to both ServerConfig and -// ClientConfig. -type Config struct { - // Rand provides the source of entropy for cryptographic - // primitives. If Rand is nil, the cryptographic random reader - // in package crypto/rand will be used. - Rand io.Reader - - // The maximum number of bytes sent or received after which a - // new key is negotiated. It must be at least 256. If - // unspecified, 1 gigabyte is used. - RekeyThreshold uint64 - - // The allowed key exchanges algorithms. If unspecified then a - // default set of algorithms is used. - KeyExchanges []string - - // The allowed cipher algorithms. If unspecified then a sensible - // default is used. - Ciphers []string - - // The allowed MAC algorithms. If unspecified then a sensible default - // is used. - MACs []string -} - -// SetDefaults sets sensible values for unset fields in config. This is -// exported for testing: Configs passed to SSH functions are copied and have -// default values set automatically. -func (c *Config) SetDefaults() { - if c.Rand == nil { - c.Rand = rand.Reader - } - if c.Ciphers == nil { - c.Ciphers = supportedCiphers - } - - if c.KeyExchanges == nil { - c.KeyExchanges = supportedKexAlgos - } - - if c.MACs == nil { - c.MACs = supportedMACs - } - - if c.RekeyThreshold == 0 { - // RFC 4253, section 9 suggests rekeying after 1G. - c.RekeyThreshold = 1 << 30 - } - if c.RekeyThreshold < minRekeyThreshold { - c.RekeyThreshold = minRekeyThreshold - } -} - -// buildDataSignedForAuth returns the data that is signed in order to prove -// possession of a private key. See RFC 4252, section 7. -func buildDataSignedForAuth(sessionId []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte { - data := struct { - Session []byte - Type byte - User string - Service string - Method string - Sign bool - Algo []byte - PubKey []byte - }{ - sessionId, - msgUserAuthRequest, - req.User, - req.Service, - req.Method, - true, - algo, - pubKey, - } - return Marshal(data) -} - -func appendU16(buf []byte, n uint16) []byte { - return append(buf, byte(n>>8), byte(n)) -} - -func appendU32(buf []byte, n uint32) []byte { - return append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) -} - -func appendU64(buf []byte, n uint64) []byte { - return append(buf, - byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), - byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) -} - -func appendInt(buf []byte, n int) []byte { - return appendU32(buf, uint32(n)) -} - -func appendString(buf []byte, s string) []byte { - buf = appendU32(buf, uint32(len(s))) - buf = append(buf, s...) - return buf -} - -func appendBool(buf []byte, b bool) []byte { - if b { - return append(buf, 1) - } - return append(buf, 0) -} - -// newCond is a helper to hide the fact that there is no usable zero -// value for sync.Cond. -func newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) } - -// window represents the buffer available to clients -// wishing to write to a channel. -type window struct { - *sync.Cond - win uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1 - writeWaiters int - closed bool -} - -// add adds win to the amount of window available -// for consumers. -func (w *window) add(win uint32) bool { - // a zero sized window adjust is a noop. - if win == 0 { - return true - } - w.L.Lock() - if w.win+win < win { - w.L.Unlock() - return false - } - w.win += win - // It is unusual that multiple goroutines would be attempting to reserve - // window space, but not guaranteed. Use broadcast to notify all waiters - // that additional window is available. - w.Broadcast() - w.L.Unlock() - return true -} - -// close sets the window to closed, so all reservations fail -// immediately. -func (w *window) close() { - w.L.Lock() - w.closed = true - w.Broadcast() - w.L.Unlock() -} - -// reserve reserves win from the available window capacity. -// If no capacity remains, reserve will block. reserve may -// return less than requested. -func (w *window) reserve(win uint32) (uint32, error) { - var err error - w.L.Lock() - w.writeWaiters++ - w.Broadcast() - for w.win == 0 && !w.closed { - w.Wait() - } - w.writeWaiters-- - if w.win < win { - win = w.win - } - w.win -= win - if w.closed { - err = io.EOF - } - w.L.Unlock() - return win, err -} - -// waitWriterBlocked waits until some goroutine is blocked for further -// writes. It is used in tests only. -func (w *window) waitWriterBlocked() { - w.Cond.L.Lock() - for w.writeWaiters == 0 { - w.Cond.Wait() - } - w.Cond.L.Unlock() -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/doc.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/doc.go deleted file mode 100644 index d4d16f08de..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package ssh implements an SSH client and server. - -SSH is a transport security protocol, an authentication protocol and a -family of application protocols. The most typical application level -protocol is a remote shell and this is specifically implemented. However, -the multiplexed nature of SSH is exposed to users that wish to support -others. - -References: - [PROTOCOL.certkeys]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys - [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 -*/ -package ssh diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/example_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/example_test.go deleted file mode 100644 index 22f42ecc50..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/example_test.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "net" - "net/http" - - "golang.org/x/crypto/ssh/terminal" -) - -func ExampleNewServerConn() { - // An SSH server is represented by a ServerConfig, which holds - // certificate details and handles authentication of ServerConns. - config := &ServerConfig{ - PasswordCallback: func(c ConnMetadata, pass []byte) (*Permissions, error) { - // Should use constant-time compare (or better, salt+hash) in - // a production setting. - if c.User() == "testuser" && string(pass) == "tiger" { - return nil, nil - } - return nil, fmt.Errorf("password rejected for %q", c.User()) - }, - } - - privateBytes, err := ioutil.ReadFile("id_rsa") - if err != nil { - panic("Failed to load private key") - } - - private, err := ParsePrivateKey(privateBytes) - if err != nil { - panic("Failed to parse private key") - } - - config.AddHostKey(private) - - // Once a ServerConfig has been configured, connections can be - // accepted. - listener, err := net.Listen("tcp", "0.0.0.0:2022") - if err != nil { - panic("failed to listen for connection") - } - nConn, err := listener.Accept() - if err != nil { - panic("failed to accept incoming connection") - } - - // Before use, a handshake must be performed on the incoming - // net.Conn. - _, chans, reqs, err := NewServerConn(nConn, config) - if err != nil { - panic("failed to handshake") - } - // The incoming Request channel must be serviced. - go DiscardRequests(reqs) - - // Service the incoming Channel channel. - for newChannel := range chans { - // Channels have a type, depending on the application level - // protocol intended. In the case of a shell, the type is - // "session" and ServerShell may be used to present a simple - // terminal interface. - if newChannel.ChannelType() != "session" { - newChannel.Reject(UnknownChannelType, "unknown channel type") - continue - } - channel, requests, err := newChannel.Accept() - if err != nil { - panic("could not accept channel.") - } - - // Sessions have out-of-band requests such as "shell", - // "pty-req" and "env". Here we handle only the - // "shell" request. - go func(in <-chan *Request) { - for req := range in { - ok := false - switch req.Type { - case "shell": - ok = true - if len(req.Payload) > 0 { - // We don't accept any - // commands, only the - // default shell. - ok = false - } - } - req.Reply(ok, nil) - } - }(requests) - - term := terminal.NewTerminal(channel, "> ") - - go func() { - defer channel.Close() - for { - line, err := term.ReadLine() - if err != nil { - break - } - fmt.Println(line) - } - }() - } -} - -func ExampleDial() { - // An SSH client is represented with a ClientConn. Currently only - // the "password" authentication method is supported. - // - // To authenticate with the remote server you must pass at least one - // implementation of AuthMethod via the Auth field in ClientConfig. - config := &ClientConfig{ - User: "username", - Auth: []AuthMethod{ - Password("yourpassword"), - }, - } - client, err := Dial("tcp", "yourserver.com:22", config) - if err != nil { - panic("Failed to dial: " + err.Error()) - } - - // Each ClientConn can support multiple interactive sessions, - // represented by a Session. - session, err := client.NewSession() - if err != nil { - panic("Failed to create session: " + err.Error()) - } - defer session.Close() - - // Once a Session is created, you can execute a single command on - // the remote side using the Run method. - var b bytes.Buffer - session.Stdout = &b - if err := session.Run("/usr/bin/whoami"); err != nil { - panic("Failed to run: " + err.Error()) - } - fmt.Println(b.String()) -} - -func ExampleClient_Listen() { - config := &ClientConfig{ - User: "username", - Auth: []AuthMethod{ - Password("password"), - }, - } - // Dial your ssh server. - conn, err := Dial("tcp", "localhost:22", config) - if err != nil { - log.Fatalf("unable to connect: %s", err) - } - defer conn.Close() - - // Request the remote side to open port 8080 on all interfaces. - l, err := conn.Listen("tcp", "0.0.0.0:8080") - if err != nil { - log.Fatalf("unable to register tcp forward: %v", err) - } - defer l.Close() - - // Serve HTTP with your SSH server acting as a reverse proxy. - http.Serve(l, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - fmt.Fprintf(resp, "Hello world!\n") - })) -} - -func ExampleSession_RequestPty() { - // Create client config - config := &ClientConfig{ - User: "username", - Auth: []AuthMethod{ - Password("password"), - }, - } - // Connect to ssh server - conn, err := Dial("tcp", "localhost:22", config) - if err != nil { - log.Fatalf("unable to connect: %s", err) - } - defer conn.Close() - // Create a session - session, err := conn.NewSession() - if err != nil { - log.Fatalf("unable to create session: %s", err) - } - defer session.Close() - // Set up terminal modes - modes := TerminalModes{ - ECHO: 0, // disable echoing - TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud - TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud - } - // Request pseudo terminal - if err := session.RequestPty("xterm", 80, 40, modes); err != nil { - log.Fatalf("request for pseudo terminal failed: %s", err) - } - // Start remote shell - if err := session.Shell(); err != nil { - log.Fatalf("failed to start shell: %s", err) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/handshake.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/handshake.go deleted file mode 100644 index a1e2c23dad..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/handshake.go +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "crypto/rand" - "errors" - "fmt" - "io" - "log" - "net" - "sync" -) - -// debugHandshake, if set, prints messages sent and received. Key -// exchange messages are printed as if DH were used, so the debug -// messages are wrong when using ECDH. -const debugHandshake = false - -// keyingTransport is a packet based transport that supports key -// changes. It need not be thread-safe. It should pass through -// msgNewKeys in both directions. -type keyingTransport interface { - packetConn - - // prepareKeyChange sets up a key change. The key change for a - // direction will be effected if a msgNewKeys message is sent - // or received. - prepareKeyChange(*algorithms, *kexResult) error - - // getSessionID returns the session ID. prepareKeyChange must - // have been called once. - getSessionID() []byte -} - -// rekeyingTransport is the interface of handshakeTransport that we -// (internally) expose to ClientConn and ServerConn. -type rekeyingTransport interface { - packetConn - - // requestKeyChange asks the remote side to change keys. All - // writes are blocked until the key change succeeds, which is - // signaled by reading a msgNewKeys. - requestKeyChange() error - - // getSessionID returns the session ID. This is only valid - // after the first key change has completed. - getSessionID() []byte -} - -// handshakeTransport implements rekeying on top of a keyingTransport -// and offers a thread-safe writePacket() interface. -type handshakeTransport struct { - conn keyingTransport - config *Config - - serverVersion []byte - clientVersion []byte - - hostKeys []Signer // If hostKeys are given, we are the server. - - // On read error, incoming is closed, and readError is set. - incoming chan []byte - readError error - - // data for host key checking - hostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error - dialAddress string - remoteAddr net.Addr - - readSinceKex uint64 - - // Protects the writing side of the connection - mu sync.Mutex - cond *sync.Cond - sentInitPacket []byte - sentInitMsg *kexInitMsg - writtenSinceKex uint64 - writeError error -} - -func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport { - t := &handshakeTransport{ - conn: conn, - serverVersion: serverVersion, - clientVersion: clientVersion, - incoming: make(chan []byte, 16), - config: config, - } - t.cond = sync.NewCond(&t.mu) - return t -} - -func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport { - t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion) - t.dialAddress = dialAddr - t.remoteAddr = addr - t.hostKeyCallback = config.HostKeyCallback - go t.readLoop() - return t -} - -func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport { - t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion) - t.hostKeys = config.hostKeys - go t.readLoop() - return t -} - -func (t *handshakeTransport) getSessionID() []byte { - return t.conn.getSessionID() -} - -func (t *handshakeTransport) id() string { - if len(t.hostKeys) > 0 { - return "server" - } - return "client" -} - -func (t *handshakeTransport) readPacket() ([]byte, error) { - p, ok := <-t.incoming - if !ok { - return nil, t.readError - } - return p, nil -} - -func (t *handshakeTransport) readLoop() { - for { - p, err := t.readOnePacket() - if err != nil { - t.readError = err - close(t.incoming) - break - } - if p[0] == msgIgnore || p[0] == msgDebug { - continue - } - t.incoming <- p - } -} - -func (t *handshakeTransport) readOnePacket() ([]byte, error) { - if t.readSinceKex > t.config.RekeyThreshold { - if err := t.requestKeyChange(); err != nil { - return nil, err - } - } - - p, err := t.conn.readPacket() - if err != nil { - return nil, err - } - - t.readSinceKex += uint64(len(p)) - if debugHandshake { - msg, err := decode(p) - log.Printf("%s got %T %v (%v)", t.id(), msg, msg, err) - } - if p[0] != msgKexInit { - return p, nil - } - err = t.enterKeyExchange(p) - - t.mu.Lock() - if err != nil { - // drop connection - t.conn.Close() - t.writeError = err - } - - if debugHandshake { - log.Printf("%s exited key exchange, err %v", t.id(), err) - } - - // Unblock writers. - t.sentInitMsg = nil - t.sentInitPacket = nil - t.cond.Broadcast() - t.writtenSinceKex = 0 - t.mu.Unlock() - - if err != nil { - return nil, err - } - - t.readSinceKex = 0 - return []byte{msgNewKeys}, nil -} - -// sendKexInit sends a key change message, and returns the message -// that was sent. After initiating the key change, all writes will be -// blocked until the change is done, and a failed key change will -// close the underlying transport. This function is safe for -// concurrent use by multiple goroutines. -func (t *handshakeTransport) sendKexInit() (*kexInitMsg, []byte, error) { - t.mu.Lock() - defer t.mu.Unlock() - return t.sendKexInitLocked() -} - -func (t *handshakeTransport) requestKeyChange() error { - _, _, err := t.sendKexInit() - return err -} - -// sendKexInitLocked sends a key change message. t.mu must be locked -// while this happens. -func (t *handshakeTransport) sendKexInitLocked() (*kexInitMsg, []byte, error) { - // kexInits may be sent either in response to the other side, - // or because our side wants to initiate a key change, so we - // may have already sent a kexInit. In that case, don't send a - // second kexInit. - if t.sentInitMsg != nil { - return t.sentInitMsg, t.sentInitPacket, nil - } - msg := &kexInitMsg{ - KexAlgos: t.config.KeyExchanges, - CiphersClientServer: t.config.Ciphers, - CiphersServerClient: t.config.Ciphers, - MACsClientServer: t.config.MACs, - MACsServerClient: t.config.MACs, - CompressionClientServer: supportedCompressions, - CompressionServerClient: supportedCompressions, - } - io.ReadFull(rand.Reader, msg.Cookie[:]) - - if len(t.hostKeys) > 0 { - for _, k := range t.hostKeys { - msg.ServerHostKeyAlgos = append( - msg.ServerHostKeyAlgos, k.PublicKey().Type()) - } - } else { - msg.ServerHostKeyAlgos = supportedHostKeyAlgos - } - packet := Marshal(msg) - - // writePacket destroys the contents, so save a copy. - packetCopy := make([]byte, len(packet)) - copy(packetCopy, packet) - - if err := t.conn.writePacket(packetCopy); err != nil { - return nil, nil, err - } - - t.sentInitMsg = msg - t.sentInitPacket = packet - return msg, packet, nil -} - -func (t *handshakeTransport) writePacket(p []byte) error { - t.mu.Lock() - if t.writtenSinceKex > t.config.RekeyThreshold { - t.sendKexInitLocked() - } - for t.sentInitMsg != nil { - t.cond.Wait() - } - if t.writeError != nil { - return t.writeError - } - t.writtenSinceKex += uint64(len(p)) - - var err error - switch p[0] { - case msgKexInit: - err = errors.New("ssh: only handshakeTransport can send kexInit") - case msgNewKeys: - err = errors.New("ssh: only handshakeTransport can send newKeys") - default: - err = t.conn.writePacket(p) - } - t.mu.Unlock() - return err -} - -func (t *handshakeTransport) Close() error { - return t.conn.Close() -} - -// enterKeyExchange runs the key exchange. -func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { - if debugHandshake { - log.Printf("%s entered key exchange", t.id()) - } - myInit, myInitPacket, err := t.sendKexInit() - if err != nil { - return err - } - - otherInit := &kexInitMsg{} - if err := Unmarshal(otherInitPacket, otherInit); err != nil { - return err - } - - magics := handshakeMagics{ - clientVersion: t.clientVersion, - serverVersion: t.serverVersion, - clientKexInit: otherInitPacket, - serverKexInit: myInitPacket, - } - - clientInit := otherInit - serverInit := myInit - if len(t.hostKeys) == 0 { - clientInit = myInit - serverInit = otherInit - - magics.clientKexInit = myInitPacket - magics.serverKexInit = otherInitPacket - } - - algs := findAgreedAlgorithms(clientInit, serverInit) - if algs == nil { - return errors.New("ssh: no common algorithms") - } - - // We don't send FirstKexFollows, but we handle receiving it. - if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] { - // other side sent a kex message for the wrong algorithm, - // which we have to ignore. - if _, err := t.conn.readPacket(); err != nil { - return err - } - } - - kex, ok := kexAlgoMap[algs.kex] - if !ok { - return fmt.Errorf("ssh: unexpected key exchange algorithm %v", algs.kex) - } - - var result *kexResult - if len(t.hostKeys) > 0 { - result, err = t.server(kex, algs, &magics) - } else { - result, err = t.client(kex, algs, &magics) - } - - if err != nil { - return err - } - - t.conn.prepareKeyChange(algs, result) - if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil { - return err - } - if packet, err := t.conn.readPacket(); err != nil { - return err - } else if packet[0] != msgNewKeys { - return unexpectedMessageError(msgNewKeys, packet[0]) - } - return nil -} - -func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) { - var hostKey Signer - for _, k := range t.hostKeys { - if algs.hostKey == k.PublicKey().Type() { - hostKey = k - } - } - - r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey) - return r, err -} - -func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) { - result, err := kex.Client(t.conn, t.config.Rand, magics) - if err != nil { - return nil, err - } - - hostKey, err := ParsePublicKey(result.HostKey) - if err != nil { - return nil, err - } - - if err := verifyHostKeySignature(hostKey, result); err != nil { - return nil, err - } - - if t.hostKeyCallback != nil { - err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey) - if err != nil { - return nil, err - } - } - - return result, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/handshake_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/handshake_test.go deleted file mode 100644 index 613c498224..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/handshake_test.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto/rand" - "fmt" - "net" - "testing" -) - -type testChecker struct { - calls []string -} - -func (t *testChecker) Check(dialAddr string, addr net.Addr, key PublicKey) error { - if dialAddr == "bad" { - return fmt.Errorf("dialAddr is bad") - } - - if tcpAddr, ok := addr.(*net.TCPAddr); !ok || tcpAddr == nil { - return fmt.Errorf("testChecker: got %T want *net.TCPAddr", addr) - } - - t.calls = append(t.calls, fmt.Sprintf("%s %v %s %x", dialAddr, addr, key.Type(), key.Marshal())) - - return nil -} - -// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and -// therefore is buffered (net.Pipe deadlocks if both sides start with -// a write.) -func netPipe() (net.Conn, net.Conn, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, nil, err - } - defer listener.Close() - c1, err := net.Dial("tcp", listener.Addr().String()) - if err != nil { - return nil, nil, err - } - - c2, err := listener.Accept() - if err != nil { - c1.Close() - return nil, nil, err - } - - return c1, c2, nil -} - -func handshakePair(clientConf *ClientConfig, addr string) (client *handshakeTransport, server *handshakeTransport, err error) { - a, b, err := netPipe() - if err != nil { - return nil, nil, err - } - - trC := newTransport(a, rand.Reader, true) - trS := newTransport(b, rand.Reader, false) - clientConf.SetDefaults() - - v := []byte("version") - client = newClientTransport(trC, v, v, clientConf, addr, a.RemoteAddr()) - - serverConf := &ServerConfig{} - serverConf.AddHostKey(testSigners["ecdsa"]) - serverConf.SetDefaults() - server = newServerTransport(trS, v, v, serverConf) - - return client, server, nil -} - -func TestHandshakeBasic(t *testing.T) { - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - - defer trC.Close() - defer trS.Close() - - go func() { - // Client writes a bunch of stuff, and does a key - // change in the middle. This should not confuse the - // handshake in progress - for i := 0; i < 10; i++ { - p := []byte{msgRequestSuccess, byte(i)} - if err := trC.writePacket(p); err != nil { - t.Fatalf("sendPacket: %v", err) - } - if i == 5 { - // halfway through, we request a key change. - _, _, err := trC.sendKexInit() - if err != nil { - t.Fatalf("sendKexInit: %v", err) - } - } - } - trC.Close() - }() - - // Server checks that client messages come in cleanly - i := 0 - for { - p, err := trS.readPacket() - if err != nil { - break - } - if p[0] == msgNewKeys { - continue - } - want := []byte{msgRequestSuccess, byte(i)} - if bytes.Compare(p, want) != 0 { - t.Errorf("message %d: got %q, want %q", i, p, want) - } - i++ - } - if i != 10 { - t.Errorf("received %d messages, want 10.", i) - } - - // If all went well, we registered exactly 1 key change. - if len(checker.calls) != 1 { - t.Fatalf("got %d host key checks, want 1", len(checker.calls)) - } - - pub := testSigners["ecdsa"].PublicKey() - want := fmt.Sprintf("%s %v %s %x", "addr", trC.remoteAddr, pub.Type(), pub.Marshal()) - if want != checker.calls[0] { - t.Errorf("got %q want %q for host key check", checker.calls[0], want) - } -} - -func TestHandshakeError(t *testing.T) { - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "bad") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - defer trC.Close() - defer trS.Close() - - // send a packet - packet := []byte{msgRequestSuccess, 42} - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - - // Now request a key change. - _, _, err = trC.sendKexInit() - if err != nil { - t.Errorf("sendKexInit: %v", err) - } - - // the key change will fail, and afterwards we can't write. - if err := trC.writePacket([]byte{msgRequestSuccess, 43}); err == nil { - t.Errorf("writePacket after botched rekey succeeded.") - } - - readback, err := trS.readPacket() - if err != nil { - t.Fatalf("server closed too soon: %v", err) - } - if bytes.Compare(readback, packet) != 0 { - t.Errorf("got %q want %q", readback, packet) - } - readback, err = trS.readPacket() - if err == nil { - t.Errorf("got a message %q after failed key change", readback) - } -} - -func TestHandshakeTwice(t *testing.T) { - checker := &testChecker{} - trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - - defer trC.Close() - defer trS.Close() - - // send a packet - packet := make([]byte, 5) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - - // Now request a key change. - _, _, err = trC.sendKexInit() - if err != nil { - t.Errorf("sendKexInit: %v", err) - } - - // Send another packet. Use a fresh one, since writePacket destroys. - packet = make([]byte, 5) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - - // 2nd key change. - _, _, err = trC.sendKexInit() - if err != nil { - t.Errorf("sendKexInit: %v", err) - } - - packet = make([]byte, 5) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - - packet = make([]byte, 5) - packet[0] = msgRequestSuccess - for i := 0; i < 5; i++ { - msg, err := trS.readPacket() - if err != nil { - t.Fatalf("server closed too soon: %v", err) - } - if msg[0] == msgNewKeys { - continue - } - - if bytes.Compare(msg, packet) != 0 { - t.Errorf("packet %d: got %q want %q", i, msg, packet) - } - } - if len(checker.calls) != 2 { - t.Errorf("got %d key changes, want 2", len(checker.calls)) - } -} - -func TestHandshakeAutoRekeyWrite(t *testing.T) { - checker := &testChecker{} - clientConf := &ClientConfig{HostKeyCallback: checker.Check} - clientConf.RekeyThreshold = 500 - trC, trS, err := handshakePair(clientConf, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - defer trC.Close() - defer trS.Close() - - for i := 0; i < 5; i++ { - packet := make([]byte, 251) - packet[0] = msgRequestSuccess - if err := trC.writePacket(packet); err != nil { - t.Errorf("writePacket: %v", err) - } - } - - j := 0 - for ; j < 5; j++ { - _, err := trS.readPacket() - if err != nil { - break - } - } - - if j != 5 { - t.Errorf("got %d, want 5 messages", j) - } - - if len(checker.calls) != 2 { - t.Errorf("got %d key changes, wanted 2", len(checker.calls)) - } -} - -type syncChecker struct { - called chan int -} - -func (t *syncChecker) Check(dialAddr string, addr net.Addr, key PublicKey) error { - t.called <- 1 - return nil -} - -func TestHandshakeAutoRekeyRead(t *testing.T) { - sync := &syncChecker{make(chan int, 2)} - clientConf := &ClientConfig{ - HostKeyCallback: sync.Check, - } - clientConf.RekeyThreshold = 500 - - trC, trS, err := handshakePair(clientConf, "addr") - if err != nil { - t.Fatalf("handshakePair: %v", err) - } - defer trC.Close() - defer trS.Close() - - packet := make([]byte, 501) - packet[0] = msgRequestSuccess - if err := trS.writePacket(packet); err != nil { - t.Fatalf("writePacket: %v", err) - } - // While we read out the packet, a key change will be - // initiated. - if _, err := trC.readPacket(); err != nil { - t.Fatalf("readPacket(client): %v", err) - } - - <-sync.called -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/kex.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/kex.go deleted file mode 100644 index 6a835c7630..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/kex.go +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "errors" - "io" - "math/big" -) - -const ( - kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1" - kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1" - kexAlgoECDH256 = "ecdh-sha2-nistp256" - kexAlgoECDH384 = "ecdh-sha2-nistp384" - kexAlgoECDH521 = "ecdh-sha2-nistp521" -) - -// kexResult captures the outcome of a key exchange. -type kexResult struct { - // Session hash. See also RFC 4253, section 8. - H []byte - - // Shared secret. See also RFC 4253, section 8. - K []byte - - // Host key as hashed into H. - HostKey []byte - - // Signature of H. - Signature []byte - - // A cryptographic hash function that matches the security - // level of the key exchange algorithm. It is used for - // calculating H, and for deriving keys from H and K. - Hash crypto.Hash - - // The session ID, which is the first H computed. This is used - // to signal data inside transport. - SessionID []byte -} - -// handshakeMagics contains data that is always included in the -// session hash. -type handshakeMagics struct { - clientVersion, serverVersion []byte - clientKexInit, serverKexInit []byte -} - -func (m *handshakeMagics) write(w io.Writer) { - writeString(w, m.clientVersion) - writeString(w, m.serverVersion) - writeString(w, m.clientKexInit) - writeString(w, m.serverKexInit) -} - -// kexAlgorithm abstracts different key exchange algorithms. -type kexAlgorithm interface { - // Server runs server-side key agreement, signing the result - // with a hostkey. - Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error) - - // Client runs the client-side key agreement. Caller is - // responsible for verifying the host key signature. - Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) -} - -// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement. -type dhGroup struct { - g, p *big.Int -} - -func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) { - if theirPublic.Sign() <= 0 || theirPublic.Cmp(group.p) >= 0 { - return nil, errors.New("ssh: DH parameter out of bounds") - } - return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil -} - -func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) { - hashFunc := crypto.SHA1 - - x, err := rand.Int(randSource, group.p) - if err != nil { - return nil, err - } - X := new(big.Int).Exp(group.g, x, group.p) - kexDHInit := kexDHInitMsg{ - X: X, - } - if err := c.writePacket(Marshal(&kexDHInit)); err != nil { - return nil, err - } - - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var kexDHReply kexDHReplyMsg - if err = Unmarshal(packet, &kexDHReply); err != nil { - return nil, err - } - - kInt, err := group.diffieHellman(kexDHReply.Y, x) - if err != nil { - return nil, err - } - - h := hashFunc.New() - magics.write(h) - writeString(h, kexDHReply.HostKey) - writeInt(h, X) - writeInt(h, kexDHReply.Y) - K := make([]byte, intLength(kInt)) - marshalInt(K, kInt) - h.Write(K) - - return &kexResult{ - H: h.Sum(nil), - K: K, - HostKey: kexDHReply.HostKey, - Signature: kexDHReply.Signature, - Hash: crypto.SHA1, - }, nil -} - -func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { - hashFunc := crypto.SHA1 - packet, err := c.readPacket() - if err != nil { - return - } - var kexDHInit kexDHInitMsg - if err = Unmarshal(packet, &kexDHInit); err != nil { - return - } - - y, err := rand.Int(randSource, group.p) - if err != nil { - return - } - - Y := new(big.Int).Exp(group.g, y, group.p) - kInt, err := group.diffieHellman(kexDHInit.X, y) - if err != nil { - return nil, err - } - - hostKeyBytes := priv.PublicKey().Marshal() - - h := hashFunc.New() - magics.write(h) - writeString(h, hostKeyBytes) - writeInt(h, kexDHInit.X) - writeInt(h, Y) - - K := make([]byte, intLength(kInt)) - marshalInt(K, kInt) - h.Write(K) - - H := h.Sum(nil) - - // H is already a hash, but the hostkey signing will apply its - // own key-specific hash algorithm. - sig, err := signAndMarshal(priv, randSource, H) - if err != nil { - return nil, err - } - - kexDHReply := kexDHReplyMsg{ - HostKey: hostKeyBytes, - Y: Y, - Signature: sig, - } - packet = Marshal(&kexDHReply) - - err = c.writePacket(packet) - return &kexResult{ - H: H, - K: K, - HostKey: hostKeyBytes, - Signature: sig, - Hash: crypto.SHA1, - }, nil -} - -// ecdh performs Elliptic Curve Diffie-Hellman key exchange as -// described in RFC 5656, section 4. -type ecdh struct { - curve elliptic.Curve -} - -func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { - ephKey, err := ecdsa.GenerateKey(kex.curve, rand) - if err != nil { - return nil, err - } - - kexInit := kexECDHInitMsg{ - ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y), - } - - serialized := Marshal(&kexInit) - if err := c.writePacket(serialized); err != nil { - return nil, err - } - - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var reply kexECDHReplyMsg - if err = Unmarshal(packet, &reply); err != nil { - return nil, err - } - - x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey) - if err != nil { - return nil, err - } - - // generate shared secret - secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes()) - - h := ecHash(kex.curve).New() - magics.write(h) - writeString(h, reply.HostKey) - writeString(h, kexInit.ClientPubKey) - writeString(h, reply.EphemeralPubKey) - K := make([]byte, intLength(secret)) - marshalInt(K, secret) - h.Write(K) - - return &kexResult{ - H: h.Sum(nil), - K: K, - HostKey: reply.HostKey, - Signature: reply.Signature, - Hash: ecHash(kex.curve), - }, nil -} - -// unmarshalECKey parses and checks an EC key. -func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) { - x, y = elliptic.Unmarshal(curve, pubkey) - if x == nil { - return nil, nil, errors.New("ssh: elliptic.Unmarshal failure") - } - if !validateECPublicKey(curve, x, y) { - return nil, nil, errors.New("ssh: public key not on curve") - } - return x, y, nil -} - -// validateECPublicKey checks that the point is a valid public key for -// the given curve. See [SEC1], 3.2.2 -func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool { - if x.Sign() == 0 && y.Sign() == 0 { - return false - } - - if x.Cmp(curve.Params().P) >= 0 { - return false - } - - if y.Cmp(curve.Params().P) >= 0 { - return false - } - - if !curve.IsOnCurve(x, y) { - return false - } - - // We don't check if N * PubKey == 0, since - // - // - the NIST curves have cofactor = 1, so this is implicit. - // (We don't foresee an implementation that supports non NIST - // curves) - // - // - for ephemeral keys, we don't need to worry about small - // subgroup attacks. - return true -} - -func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { - packet, err := c.readPacket() - if err != nil { - return nil, err - } - - var kexECDHInit kexECDHInitMsg - if err = Unmarshal(packet, &kexECDHInit); err != nil { - return nil, err - } - - clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey) - if err != nil { - return nil, err - } - - // We could cache this key across multiple users/multiple - // connection attempts, but the benefit is small. OpenSSH - // generates a new key for each incoming connection. - ephKey, err := ecdsa.GenerateKey(kex.curve, rand) - if err != nil { - return nil, err - } - - hostKeyBytes := priv.PublicKey().Marshal() - - serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y) - - // generate shared secret - secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes()) - - h := ecHash(kex.curve).New() - magics.write(h) - writeString(h, hostKeyBytes) - writeString(h, kexECDHInit.ClientPubKey) - writeString(h, serializedEphKey) - - K := make([]byte, intLength(secret)) - marshalInt(K, secret) - h.Write(K) - - H := h.Sum(nil) - - // H is already a hash, but the hostkey signing will apply its - // own key-specific hash algorithm. - sig, err := signAndMarshal(priv, rand, H) - if err != nil { - return nil, err - } - - reply := kexECDHReplyMsg{ - EphemeralPubKey: serializedEphKey, - HostKey: hostKeyBytes, - Signature: sig, - } - - serialized := Marshal(&reply) - if err := c.writePacket(serialized); err != nil { - return nil, err - } - - return &kexResult{ - H: H, - K: K, - HostKey: reply.HostKey, - Signature: sig, - Hash: ecHash(kex.curve), - }, nil -} - -var kexAlgoMap = map[string]kexAlgorithm{} - -func init() { - // This is the group called diffie-hellman-group1-sha1 in RFC - // 4253 and Oakley Group 2 in RFC 2409. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) - kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ - g: new(big.Int).SetInt64(2), - p: p, - } - - // This is the group called diffie-hellman-group14-sha1 in RFC - // 4253 and Oakley Group 14 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) - - kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{ - g: new(big.Int).SetInt64(2), - p: p, - } - - kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()} - kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()} - kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()} -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/kex_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/kex_test.go deleted file mode 100644 index 0db5f9be1c..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/kex_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -// Key exchange tests. - -import ( - "crypto/rand" - "reflect" - "testing" -) - -func TestKexes(t *testing.T) { - type kexResultErr struct { - result *kexResult - err error - } - - for name, kex := range kexAlgoMap { - a, b := memPipe() - - s := make(chan kexResultErr, 1) - c := make(chan kexResultErr, 1) - var magics handshakeMagics - go func() { - r, e := kex.Client(a, rand.Reader, &magics) - c <- kexResultErr{r, e} - }() - go func() { - r, e := kex.Server(b, rand.Reader, &magics, testSigners["ecdsa"]) - s <- kexResultErr{r, e} - }() - - clientRes := <-c - serverRes := <-s - if clientRes.err != nil { - t.Errorf("client: %v", clientRes.err) - } - if serverRes.err != nil { - t.Errorf("server: %v", serverRes.err) - } - if !reflect.DeepEqual(clientRes.result, serverRes.result) { - t.Errorf("kex %q: mismatch %#v, %#v", name, clientRes.result, serverRes.result) - } - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/keys.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/keys.go deleted file mode 100644 index e8af511eeb..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/keys.go +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "crypto/x509" - "encoding/asn1" - "encoding/base64" - "encoding/pem" - "errors" - "fmt" - "io" - "math/big" -) - -// These constants represent the algorithm names for key types supported by this -// package. -const ( - KeyAlgoRSA = "ssh-rsa" - KeyAlgoDSA = "ssh-dss" - KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" - KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" - KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" -) - -// parsePubKey parses a public key of the given algorithm. -// Use ParsePublicKey for keys with prepended algorithm. -func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) { - switch algo { - case KeyAlgoRSA: - return parseRSA(in) - case KeyAlgoDSA: - return parseDSA(in) - case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: - return parseECDSA(in) - case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01: - cert, err := parseCert(in, certToPrivAlgo(algo)) - if err != nil { - return nil, nil, err - } - return cert, nil, nil - } - return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", err) -} - -// parseAuthorizedKey parses a public key in OpenSSH authorized_keys format -// (see sshd(8) manual page) once the options and key type fields have been -// removed. -func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) { - in = bytes.TrimSpace(in) - - i := bytes.IndexAny(in, " \t") - if i == -1 { - i = len(in) - } - base64Key := in[:i] - - key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key))) - n, err := base64.StdEncoding.Decode(key, base64Key) - if err != nil { - return nil, "", err - } - key = key[:n] - out, err = ParsePublicKey(key) - if err != nil { - return nil, "", err - } - comment = string(bytes.TrimSpace(in[i:])) - return out, comment, nil -} - -// ParseAuthorizedKeys parses a public key from an authorized_keys -// file used in OpenSSH according to the sshd(8) manual page. -func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { - for len(in) > 0 { - end := bytes.IndexByte(in, '\n') - if end != -1 { - rest = in[end+1:] - in = in[:end] - } else { - rest = nil - } - - end = bytes.IndexByte(in, '\r') - if end != -1 { - in = in[:end] - } - - in = bytes.TrimSpace(in) - if len(in) == 0 || in[0] == '#' { - in = rest - continue - } - - i := bytes.IndexAny(in, " \t") - if i == -1 { - in = rest - continue - } - - if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { - return out, comment, options, rest, nil - } - - // No key type recognised. Maybe there's an options field at - // the beginning. - var b byte - inQuote := false - var candidateOptions []string - optionStart := 0 - for i, b = range in { - isEnd := !inQuote && (b == ' ' || b == '\t') - if (b == ',' && !inQuote) || isEnd { - if i-optionStart > 0 { - candidateOptions = append(candidateOptions, string(in[optionStart:i])) - } - optionStart = i + 1 - } - if isEnd { - break - } - if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) { - inQuote = !inQuote - } - } - for i < len(in) && (in[i] == ' ' || in[i] == '\t') { - i++ - } - if i == len(in) { - // Invalid line: unmatched quote - in = rest - continue - } - - in = in[i:] - i = bytes.IndexAny(in, " \t") - if i == -1 { - in = rest - continue - } - - if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { - options = candidateOptions - return out, comment, options, rest, nil - } - - in = rest - continue - } - - return nil, "", nil, nil, errors.New("ssh: no key found") -} - -// ParsePublicKey parses an SSH public key formatted for use in -// the SSH wire protocol according to RFC 4253, section 6.6. -func ParsePublicKey(in []byte) (out PublicKey, err error) { - algo, in, ok := parseString(in) - if !ok { - return nil, errShortRead - } - var rest []byte - out, rest, err = parsePubKey(in, string(algo)) - if len(rest) > 0 { - return nil, errors.New("ssh: trailing junk in public key") - } - - return out, err -} - -// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH -// authorized_keys file. The return value ends with newline. -func MarshalAuthorizedKey(key PublicKey) []byte { - b := &bytes.Buffer{} - b.WriteString(key.Type()) - b.WriteByte(' ') - e := base64.NewEncoder(base64.StdEncoding, b) - e.Write(key.Marshal()) - e.Close() - b.WriteByte('\n') - return b.Bytes() -} - -// PublicKey is an abstraction of different types of public keys. -type PublicKey interface { - // Type returns the key's type, e.g. "ssh-rsa". - Type() string - - // Marshal returns the serialized key data in SSH wire format, - // with the name prefix. - Marshal() []byte - - // Verify that sig is a signature on the given data using this - // key. This function will hash the data appropriately first. - Verify(data []byte, sig *Signature) error -} - -// A Signer can create signatures that verify against a public key. -type Signer interface { - // PublicKey returns an associated PublicKey instance. - PublicKey() PublicKey - - // Sign returns raw signature for the given data. This method - // will apply the hash specified for the keytype to the data. - Sign(rand io.Reader, data []byte) (*Signature, error) -} - -type rsaPublicKey rsa.PublicKey - -func (r *rsaPublicKey) Type() string { - return "ssh-rsa" -} - -// parseRSA parses an RSA key according to RFC 4253, section 6.6. -func parseRSA(in []byte) (out PublicKey, rest []byte, err error) { - var w struct { - E *big.Int - N *big.Int - Rest []byte `ssh:"rest"` - } - if err := Unmarshal(in, &w); err != nil { - return nil, nil, err - } - - if w.E.BitLen() > 24 { - return nil, nil, errors.New("ssh: exponent too large") - } - e := w.E.Int64() - if e < 3 || e&1 == 0 { - return nil, nil, errors.New("ssh: incorrect exponent") - } - - var key rsa.PublicKey - key.E = int(e) - key.N = w.N - return (*rsaPublicKey)(&key), w.Rest, nil -} - -func (r *rsaPublicKey) Marshal() []byte { - e := new(big.Int).SetInt64(int64(r.E)) - wirekey := struct { - Name string - E *big.Int - N *big.Int - }{ - KeyAlgoRSA, - e, - r.N, - } - return Marshal(&wirekey) -} - -func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { - if sig.Format != r.Type() { - return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type()) - } - h := crypto.SHA1.New() - h.Write(data) - digest := h.Sum(nil) - return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob) -} - -type rsaPrivateKey struct { - *rsa.PrivateKey -} - -func (r *rsaPrivateKey) PublicKey() PublicKey { - return (*rsaPublicKey)(&r.PrivateKey.PublicKey) -} - -func (r *rsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) { - h := crypto.SHA1.New() - h.Write(data) - digest := h.Sum(nil) - blob, err := rsa.SignPKCS1v15(rand, r.PrivateKey, crypto.SHA1, digest) - if err != nil { - return nil, err - } - return &Signature{ - Format: r.PublicKey().Type(), - Blob: blob, - }, nil -} - -type dsaPublicKey dsa.PublicKey - -func (r *dsaPublicKey) Type() string { - return "ssh-dss" -} - -// parseDSA parses an DSA key according to RFC 4253, section 6.6. -func parseDSA(in []byte) (out PublicKey, rest []byte, err error) { - var w struct { - P, Q, G, Y *big.Int - Rest []byte `ssh:"rest"` - } - if err := Unmarshal(in, &w); err != nil { - return nil, nil, err - } - - key := &dsaPublicKey{ - Parameters: dsa.Parameters{ - P: w.P, - Q: w.Q, - G: w.G, - }, - Y: w.Y, - } - return key, w.Rest, nil -} - -func (k *dsaPublicKey) Marshal() []byte { - w := struct { - Name string - P, Q, G, Y *big.Int - }{ - k.Type(), - k.P, - k.Q, - k.G, - k.Y, - } - - return Marshal(&w) -} - -func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error { - if sig.Format != k.Type() { - return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) - } - h := crypto.SHA1.New() - h.Write(data) - digest := h.Sum(nil) - - // Per RFC 4253, section 6.6, - // The value for 'dss_signature_blob' is encoded as a string containing - // r, followed by s (which are 160-bit integers, without lengths or - // padding, unsigned, and in network byte order). - // For DSS purposes, sig.Blob should be exactly 40 bytes in length. - if len(sig.Blob) != 40 { - return errors.New("ssh: DSA signature parse error") - } - r := new(big.Int).SetBytes(sig.Blob[:20]) - s := new(big.Int).SetBytes(sig.Blob[20:]) - if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) { - return nil - } - return errors.New("ssh: signature did not verify") -} - -type dsaPrivateKey struct { - *dsa.PrivateKey -} - -func (k *dsaPrivateKey) PublicKey() PublicKey { - return (*dsaPublicKey)(&k.PrivateKey.PublicKey) -} - -func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) { - h := crypto.SHA1.New() - h.Write(data) - digest := h.Sum(nil) - r, s, err := dsa.Sign(rand, k.PrivateKey, digest) - if err != nil { - return nil, err - } - - sig := make([]byte, 40) - rb := r.Bytes() - sb := s.Bytes() - - copy(sig[20-len(rb):20], rb) - copy(sig[40-len(sb):], sb) - - return &Signature{ - Format: k.PublicKey().Type(), - Blob: sig, - }, nil -} - -type ecdsaPublicKey ecdsa.PublicKey - -func (key *ecdsaPublicKey) Type() string { - return "ecdsa-sha2-" + key.nistID() -} - -func (key *ecdsaPublicKey) nistID() string { - switch key.Params().BitSize { - case 256: - return "nistp256" - case 384: - return "nistp384" - case 521: - return "nistp521" - } - panic("ssh: unsupported ecdsa key size") -} - -func supportedEllipticCurve(curve elliptic.Curve) bool { - return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521() -} - -// ecHash returns the hash to match the given elliptic curve, see RFC -// 5656, section 6.2.1 -func ecHash(curve elliptic.Curve) crypto.Hash { - bitSize := curve.Params().BitSize - switch { - case bitSize <= 256: - return crypto.SHA256 - case bitSize <= 384: - return crypto.SHA384 - } - return crypto.SHA512 -} - -// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. -func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) { - identifier, in, ok := parseString(in) - if !ok { - return nil, nil, errShortRead - } - - key := new(ecdsa.PublicKey) - - switch string(identifier) { - case "nistp256": - key.Curve = elliptic.P256() - case "nistp384": - key.Curve = elliptic.P384() - case "nistp521": - key.Curve = elliptic.P521() - default: - return nil, nil, errors.New("ssh: unsupported curve") - } - - var keyBytes []byte - if keyBytes, in, ok = parseString(in); !ok { - return nil, nil, errShortRead - } - - key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes) - if key.X == nil || key.Y == nil { - return nil, nil, errors.New("ssh: invalid curve point") - } - return (*ecdsaPublicKey)(key), in, nil -} - -func (key *ecdsaPublicKey) Marshal() []byte { - // See RFC 5656, section 3.1. - keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y) - w := struct { - Name string - ID string - Key []byte - }{ - key.Type(), - key.nistID(), - keyBytes, - } - - return Marshal(&w) -} - -func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error { - if sig.Format != key.Type() { - return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type()) - } - - h := ecHash(key.Curve).New() - h.Write(data) - digest := h.Sum(nil) - - // Per RFC 5656, section 3.1.2, - // The ecdsa_signature_blob value has the following specific encoding: - // mpint r - // mpint s - var ecSig struct { - R *big.Int - S *big.Int - } - - if err := Unmarshal(sig.Blob, &ecSig); err != nil { - return err - } - - if ecdsa.Verify((*ecdsa.PublicKey)(key), digest, ecSig.R, ecSig.S) { - return nil - } - return errors.New("ssh: signature did not verify") -} - -type ecdsaPrivateKey struct { - *ecdsa.PrivateKey -} - -func (k *ecdsaPrivateKey) PublicKey() PublicKey { - return (*ecdsaPublicKey)(&k.PrivateKey.PublicKey) -} - -func (k *ecdsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) { - h := ecHash(k.PrivateKey.PublicKey.Curve).New() - h.Write(data) - digest := h.Sum(nil) - r, s, err := ecdsa.Sign(rand, k.PrivateKey, digest) - if err != nil { - return nil, err - } - - sig := make([]byte, intLength(r)+intLength(s)) - rest := marshalInt(sig, r) - marshalInt(rest, s) - return &Signature{ - Format: k.PublicKey().Type(), - Blob: sig, - }, nil -} - -// NewSignerFromKey takes a pointer to rsa, dsa or ecdsa PrivateKey -// returns a corresponding Signer instance. EC keys should use P256, -// P384 or P521. -func NewSignerFromKey(k interface{}) (Signer, error) { - var sshKey Signer - switch t := k.(type) { - case *rsa.PrivateKey: - sshKey = &rsaPrivateKey{t} - case *dsa.PrivateKey: - sshKey = &dsaPrivateKey{t} - case *ecdsa.PrivateKey: - if !supportedEllipticCurve(t.Curve) { - return nil, errors.New("ssh: only P256, P384 and P521 EC keys are supported.") - } - - sshKey = &ecdsaPrivateKey{t} - default: - return nil, fmt.Errorf("ssh: unsupported key type %T", k) - } - return sshKey, nil -} - -// NewPublicKey takes a pointer to rsa, dsa or ecdsa PublicKey -// and returns a corresponding ssh PublicKey instance. EC keys should use P256, P384 or P521. -func NewPublicKey(k interface{}) (PublicKey, error) { - var sshKey PublicKey - switch t := k.(type) { - case *rsa.PublicKey: - sshKey = (*rsaPublicKey)(t) - case *ecdsa.PublicKey: - if !supportedEllipticCurve(t.Curve) { - return nil, errors.New("ssh: only P256, P384 and P521 EC keys are supported.") - } - sshKey = (*ecdsaPublicKey)(t) - case *dsa.PublicKey: - sshKey = (*dsaPublicKey)(t) - default: - return nil, fmt.Errorf("ssh: unsupported key type %T", k) - } - return sshKey, nil -} - -// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports -// the same keys as ParseRawPrivateKey. -func ParsePrivateKey(pemBytes []byte) (Signer, error) { - key, err := ParseRawPrivateKey(pemBytes) - if err != nil { - return nil, err - } - - return NewSignerFromKey(key) -} - -// ParseRawPrivateKey returns a private key from a PEM encoded private key. It -// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys. -func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { - block, _ := pem.Decode(pemBytes) - if block == nil { - return nil, errors.New("ssh: no key found") - } - - switch block.Type { - case "RSA PRIVATE KEY": - return x509.ParsePKCS1PrivateKey(block.Bytes) - case "EC PRIVATE KEY": - return x509.ParseECPrivateKey(block.Bytes) - case "DSA PRIVATE KEY": - return ParseDSAPrivateKey(block.Bytes) - default: - return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type) - } -} - -// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as -// specified by the OpenSSL DSA man page. -func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) { - var k struct { - Version int - P *big.Int - Q *big.Int - G *big.Int - Priv *big.Int - Pub *big.Int - } - rest, err := asn1.Unmarshal(der, &k) - if err != nil { - return nil, errors.New("ssh: failed to parse DSA key: " + err.Error()) - } - if len(rest) > 0 { - return nil, errors.New("ssh: garbage after DSA key") - } - - return &dsa.PrivateKey{ - PublicKey: dsa.PublicKey{ - Parameters: dsa.Parameters{ - P: k.P, - Q: k.Q, - G: k.G, - }, - Y: k.Priv, - }, - X: k.Pub, - }, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/keys_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/keys_test.go deleted file mode 100644 index 36b97ad225..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/keys_test.go +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "encoding/base64" - "fmt" - "reflect" - "strings" - "testing" - - "golang.org/x/crypto/ssh/testdata" -) - -func rawKey(pub PublicKey) interface{} { - switch k := pub.(type) { - case *rsaPublicKey: - return (*rsa.PublicKey)(k) - case *dsaPublicKey: - return (*dsa.PublicKey)(k) - case *ecdsaPublicKey: - return (*ecdsa.PublicKey)(k) - case *Certificate: - return k - } - panic("unknown key type") -} - -func TestKeyMarshalParse(t *testing.T) { - for _, priv := range testSigners { - pub := priv.PublicKey() - roundtrip, err := ParsePublicKey(pub.Marshal()) - if err != nil { - t.Errorf("ParsePublicKey(%T): %v", pub, err) - } - - k1 := rawKey(pub) - k2 := rawKey(roundtrip) - - if !reflect.DeepEqual(k1, k2) { - t.Errorf("got %#v in roundtrip, want %#v", k2, k1) - } - } -} - -func TestUnsupportedCurves(t *testing.T) { - raw, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) - if err != nil { - t.Fatalf("GenerateKey: %v", err) - } - - if _, err = NewSignerFromKey(raw); err == nil || !strings.Contains(err.Error(), "only P256") { - t.Fatalf("NewPrivateKey should not succeed with P224, got: %v", err) - } - - if _, err = NewPublicKey(&raw.PublicKey); err == nil || !strings.Contains(err.Error(), "only P256") { - t.Fatalf("NewPublicKey should not succeed with P224, got: %v", err) - } -} - -func TestNewPublicKey(t *testing.T) { - for _, k := range testSigners { - raw := rawKey(k.PublicKey()) - // Skip certificates, as NewPublicKey does not support them. - if _, ok := raw.(*Certificate); ok { - continue - } - pub, err := NewPublicKey(raw) - if err != nil { - t.Errorf("NewPublicKey(%#v): %v", raw, err) - } - if !reflect.DeepEqual(k.PublicKey(), pub) { - t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub, k.PublicKey()) - } - } -} - -func TestKeySignVerify(t *testing.T) { - for _, priv := range testSigners { - pub := priv.PublicKey() - - data := []byte("sign me") - sig, err := priv.Sign(rand.Reader, data) - if err != nil { - t.Fatalf("Sign(%T): %v", priv, err) - } - - if err := pub.Verify(data, sig); err != nil { - t.Errorf("publicKey.Verify(%T): %v", priv, err) - } - sig.Blob[5]++ - if err := pub.Verify(data, sig); err == nil { - t.Errorf("publicKey.Verify on broken sig did not fail") - } - } -} - -func TestParseRSAPrivateKey(t *testing.T) { - key := testPrivateKeys["rsa"] - - rsa, ok := key.(*rsa.PrivateKey) - if !ok { - t.Fatalf("got %T, want *rsa.PrivateKey", rsa) - } - - if err := rsa.Validate(); err != nil { - t.Errorf("Validate: %v", err) - } -} - -func TestParseECPrivateKey(t *testing.T) { - key := testPrivateKeys["ecdsa"] - - ecKey, ok := key.(*ecdsa.PrivateKey) - if !ok { - t.Fatalf("got %T, want *ecdsa.PrivateKey", ecKey) - } - - if !validateECPublicKey(ecKey.Curve, ecKey.X, ecKey.Y) { - t.Fatalf("public key does not validate.") - } -} - -func TestParseDSA(t *testing.T) { - // We actually exercise the ParsePrivateKey codepath here, as opposed to - // using the ParseRawPrivateKey+NewSignerFromKey path that testdata_test.go - // uses. - s, err := ParsePrivateKey(testdata.PEMBytes["dsa"]) - if err != nil { - t.Fatalf("ParsePrivateKey returned error: %s", err) - } - - data := []byte("sign me") - sig, err := s.Sign(rand.Reader, data) - if err != nil { - t.Fatalf("dsa.Sign: %v", err) - } - - if err := s.PublicKey().Verify(data, sig); err != nil { - t.Errorf("Verify failed: %v", err) - } -} - -// Tests for authorized_keys parsing. - -// getTestKey returns a public key, and its base64 encoding. -func getTestKey() (PublicKey, string) { - k := testPublicKeys["rsa"] - - b := &bytes.Buffer{} - e := base64.NewEncoder(base64.StdEncoding, b) - e.Write(k.Marshal()) - e.Close() - - return k, b.String() -} - -func TestMarshalParsePublicKey(t *testing.T) { - pub, pubSerialized := getTestKey() - line := fmt.Sprintf("%s %s user@host", pub.Type(), pubSerialized) - - authKeys := MarshalAuthorizedKey(pub) - actualFields := strings.Fields(string(authKeys)) - if len(actualFields) == 0 { - t.Fatalf("failed authKeys: %v", authKeys) - } - - // drop the comment - expectedFields := strings.Fields(line)[0:2] - - if !reflect.DeepEqual(actualFields, expectedFields) { - t.Errorf("got %v, expected %v", actualFields, expectedFields) - } - - actPub, _, _, _, err := ParseAuthorizedKey([]byte(line)) - if err != nil { - t.Fatalf("cannot parse %v: %v", line, err) - } - if !reflect.DeepEqual(actPub, pub) { - t.Errorf("got %v, expected %v", actPub, pub) - } -} - -type authResult struct { - pubKey PublicKey - options []string - comments string - rest string - ok bool -} - -func testAuthorizedKeys(t *testing.T, authKeys []byte, expected []authResult) { - rest := authKeys - var values []authResult - for len(rest) > 0 { - var r authResult - var err error - r.pubKey, r.comments, r.options, rest, err = ParseAuthorizedKey(rest) - r.ok = (err == nil) - t.Log(err) - r.rest = string(rest) - values = append(values, r) - } - - if !reflect.DeepEqual(values, expected) { - t.Errorf("got %#v, expected %#v", values, expected) - } -} - -func TestAuthorizedKeyBasic(t *testing.T) { - pub, pubSerialized := getTestKey() - line := "ssh-rsa " + pubSerialized + " user@host" - testAuthorizedKeys(t, []byte(line), - []authResult{ - {pub, nil, "user@host", "", true}, - }) -} - -func TestAuth(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithOptions := []string{ - `# comments to ignore before any keys...`, - ``, - `env="HOME=/home/root",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`, - `# comments to ignore, along with a blank line`, - ``, - `env="HOME=/home/root2" ssh-rsa ` + pubSerialized + ` user2@host2`, - ``, - `# more comments, plus a invalid entry`, - `ssh-rsa data-that-will-not-parse user@host3`, - } - for _, eol := range []string{"\n", "\r\n"} { - authOptions := strings.Join(authWithOptions, eol) - rest2 := strings.Join(authWithOptions[3:], eol) - rest3 := strings.Join(authWithOptions[6:], eol) - testAuthorizedKeys(t, []byte(authOptions), []authResult{ - {pub, []string{`env="HOME=/home/root"`, "no-port-forwarding"}, "user@host", rest2, true}, - {pub, []string{`env="HOME=/home/root2"`}, "user2@host2", rest3, true}, - {nil, nil, "", "", false}, - }) - } -} - -func TestAuthWithQuotedSpaceInEnv(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithQuotedSpaceInEnv := []byte(`env="HOME=/home/root dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`) - testAuthorizedKeys(t, []byte(authWithQuotedSpaceInEnv), []authResult{ - {pub, []string{`env="HOME=/home/root dir"`, "no-port-forwarding"}, "user@host", "", true}, - }) -} - -func TestAuthWithQuotedCommaInEnv(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithQuotedCommaInEnv := []byte(`env="HOME=/home/root,dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`) - testAuthorizedKeys(t, []byte(authWithQuotedCommaInEnv), []authResult{ - {pub, []string{`env="HOME=/home/root,dir"`, "no-port-forwarding"}, "user@host", "", true}, - }) -} - -func TestAuthWithQuotedQuoteInEnv(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithQuotedQuoteInEnv := []byte(`env="HOME=/home/\"root dir",no-port-forwarding` + "\t" + `ssh-rsa` + "\t" + pubSerialized + ` user@host`) - authWithDoubleQuotedQuote := []byte(`no-port-forwarding,env="HOME=/home/ \"root dir\"" ssh-rsa ` + pubSerialized + "\t" + `user@host`) - testAuthorizedKeys(t, []byte(authWithQuotedQuoteInEnv), []authResult{ - {pub, []string{`env="HOME=/home/\"root dir"`, "no-port-forwarding"}, "user@host", "", true}, - }) - - testAuthorizedKeys(t, []byte(authWithDoubleQuotedQuote), []authResult{ - {pub, []string{"no-port-forwarding", `env="HOME=/home/ \"root dir\""`}, "user@host", "", true}, - }) -} - -func TestAuthWithInvalidSpace(t *testing.T) { - _, pubSerialized := getTestKey() - authWithInvalidSpace := []byte(`env="HOME=/home/root dir", no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host -#more to follow but still no valid keys`) - testAuthorizedKeys(t, []byte(authWithInvalidSpace), []authResult{ - {nil, nil, "", "", false}, - }) -} - -func TestAuthWithMissingQuote(t *testing.T) { - pub, pubSerialized := getTestKey() - authWithMissingQuote := []byte(`env="HOME=/home/root,no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host -env="HOME=/home/root",shared-control ssh-rsa ` + pubSerialized + ` user@host`) - - testAuthorizedKeys(t, []byte(authWithMissingQuote), []authResult{ - {pub, []string{`env="HOME=/home/root"`, `shared-control`}, "user@host", "", true}, - }) -} - -func TestInvalidEntry(t *testing.T) { - authInvalid := []byte(`ssh-rsa`) - _, _, _, _, err := ParseAuthorizedKey(authInvalid) - if err == nil { - t.Errorf("got valid entry for %q", authInvalid) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/mac.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/mac.go deleted file mode 100644 index aff4042913..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/mac.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -// Message authentication support - -import ( - "crypto/hmac" - "crypto/sha1" - "hash" -) - -type macMode struct { - keySize int - new func(key []byte) hash.Hash -} - -// truncatingMAC wraps around a hash.Hash and truncates the output digest to -// a given size. -type truncatingMAC struct { - length int - hmac hash.Hash -} - -func (t truncatingMAC) Write(data []byte) (int, error) { - return t.hmac.Write(data) -} - -func (t truncatingMAC) Sum(in []byte) []byte { - out := t.hmac.Sum(in) - return out[:len(in)+t.length] -} - -func (t truncatingMAC) Reset() { - t.hmac.Reset() -} - -func (t truncatingMAC) Size() int { - return t.length -} - -func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } - -var macModes = map[string]*macMode{ - "hmac-sha1": {20, func(key []byte) hash.Hash { - return hmac.New(sha1.New, key) - }}, - "hmac-sha1-96": {20, func(key []byte) hash.Hash { - return truncatingMAC{12, hmac.New(sha1.New, key)} - }}, -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/mempipe_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/mempipe_test.go deleted file mode 100644 index 92519dd6bd..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/mempipe_test.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "io" - "sync" - "testing" -) - -// An in-memory packetConn. It is safe to call Close and writePacket -// from different goroutines. -type memTransport struct { - eof bool - pending [][]byte - write *memTransport - sync.Mutex - *sync.Cond -} - -func (t *memTransport) readPacket() ([]byte, error) { - t.Lock() - defer t.Unlock() - for { - if len(t.pending) > 0 { - r := t.pending[0] - t.pending = t.pending[1:] - return r, nil - } - if t.eof { - return nil, io.EOF - } - t.Cond.Wait() - } -} - -func (t *memTransport) closeSelf() error { - t.Lock() - defer t.Unlock() - if t.eof { - return io.EOF - } - t.eof = true - t.Cond.Broadcast() - return nil -} - -func (t *memTransport) Close() error { - err := t.write.closeSelf() - t.closeSelf() - return err -} - -func (t *memTransport) writePacket(p []byte) error { - t.write.Lock() - defer t.write.Unlock() - if t.write.eof { - return io.EOF - } - c := make([]byte, len(p)) - copy(c, p) - t.write.pending = append(t.write.pending, c) - t.write.Cond.Signal() - return nil -} - -func memPipe() (a, b packetConn) { - t1 := memTransport{} - t2 := memTransport{} - t1.write = &t2 - t2.write = &t1 - t1.Cond = sync.NewCond(&t1.Mutex) - t2.Cond = sync.NewCond(&t2.Mutex) - return &t1, &t2 -} - -func TestmemPipe(t *testing.T) { - a, b := memPipe() - if err := a.writePacket([]byte{42}); err != nil { - t.Fatalf("writePacket: %v", err) - } - if err := a.Close(); err != nil { - t.Fatal("Close: ", err) - } - p, err := b.readPacket() - if err != nil { - t.Fatal("readPacket: ", err) - } - if len(p) != 1 || p[0] != 42 { - t.Fatalf("got %v, want {42}", p) - } - p, err = b.readPacket() - if err != io.EOF { - t.Fatalf("got %v, %v, want EOF", p, err) - } -} - -func TestDoubleClose(t *testing.T) { - a, _ := memPipe() - err := a.Close() - if err != nil { - t.Errorf("Close: %v", err) - } - err = a.Close() - if err != io.EOF { - t.Errorf("expect EOF on double close.") - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/messages_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/messages_test.go deleted file mode 100644 index 21d52daf26..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/messages_test.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "math/big" - "math/rand" - "reflect" - "testing" - "testing/quick" -) - -var intLengthTests = []struct { - val, length int -}{ - {0, 4 + 0}, - {1, 4 + 1}, - {127, 4 + 1}, - {128, 4 + 2}, - {-1, 4 + 1}, -} - -func TestIntLength(t *testing.T) { - for _, test := range intLengthTests { - v := new(big.Int).SetInt64(int64(test.val)) - length := intLength(v) - if length != test.length { - t.Errorf("For %d, got length %d but expected %d", test.val, length, test.length) - } - } -} - -type msgAllTypes struct { - Bool bool `sshtype:"21"` - Array [16]byte - Uint64 uint64 - Uint32 uint32 - Uint8 uint8 - String string - Strings []string - Bytes []byte - Int *big.Int - Rest []byte `ssh:"rest"` -} - -func (t *msgAllTypes) Generate(rand *rand.Rand, size int) reflect.Value { - m := &msgAllTypes{} - m.Bool = rand.Intn(2) == 1 - randomBytes(m.Array[:], rand) - m.Uint64 = uint64(rand.Int63n(1<<63 - 1)) - m.Uint32 = uint32(rand.Intn((1 << 31) - 1)) - m.Uint8 = uint8(rand.Intn(1 << 8)) - m.String = string(m.Array[:]) - m.Strings = randomNameList(rand) - m.Bytes = m.Array[:] - m.Int = randomInt(rand) - m.Rest = m.Array[:] - return reflect.ValueOf(m) -} - -func TestMarshalUnmarshal(t *testing.T) { - rand := rand.New(rand.NewSource(0)) - iface := &msgAllTypes{} - ty := reflect.ValueOf(iface).Type() - - n := 100 - if testing.Short() { - n = 5 - } - for j := 0; j < n; j++ { - v, ok := quick.Value(ty, rand) - if !ok { - t.Errorf("failed to create value") - break - } - - m1 := v.Elem().Interface() - m2 := iface - - marshaled := Marshal(m1) - if err := Unmarshal(marshaled, m2); err != nil { - t.Errorf("Unmarshal %#v: %s", m1, err) - break - } - - if !reflect.DeepEqual(v.Interface(), m2) { - t.Errorf("got: %#v\nwant:%#v\n%x", m2, m1, marshaled) - break - } - } -} - -func TestUnmarshalEmptyPacket(t *testing.T) { - var b []byte - var m channelRequestSuccessMsg - if err := Unmarshal(b, &m); err == nil { - t.Fatalf("unmarshal of empty slice succeeded") - } -} - -func TestUnmarshalUnexpectedPacket(t *testing.T) { - type S struct { - I uint32 `sshtype:"43"` - S string - B bool - } - - s := S{11, "hello", true} - packet := Marshal(s) - packet[0] = 42 - roundtrip := S{} - err := Unmarshal(packet, &roundtrip) - if err == nil { - t.Fatal("expected error, not nil") - } -} - -func TestMarshalPtr(t *testing.T) { - s := struct { - S string - }{"hello"} - - m1 := Marshal(s) - m2 := Marshal(&s) - if !bytes.Equal(m1, m2) { - t.Errorf("got %q, want %q for marshaled pointer", m2, m1) - } -} - -func TestBareMarshalUnmarshal(t *testing.T) { - type S struct { - I uint32 - S string - B bool - } - - s := S{42, "hello", true} - packet := Marshal(s) - roundtrip := S{} - Unmarshal(packet, &roundtrip) - - if !reflect.DeepEqual(s, roundtrip) { - t.Errorf("got %#v, want %#v", roundtrip, s) - } -} - -func TestBareMarshal(t *testing.T) { - type S2 struct { - I uint32 - } - s := S2{42} - packet := Marshal(s) - i, rest, ok := parseUint32(packet) - if len(rest) > 0 || !ok { - t.Errorf("parseInt(%q): parse error", packet) - } - if i != s.I { - t.Errorf("got %d, want %d", i, s.I) - } -} - -func randomBytes(out []byte, rand *rand.Rand) { - for i := 0; i < len(out); i++ { - out[i] = byte(rand.Int31()) - } -} - -func randomNameList(rand *rand.Rand) []string { - ret := make([]string, rand.Int31()&15) - for i := range ret { - s := make([]byte, 1+(rand.Int31()&15)) - for j := range s { - s[j] = 'a' + uint8(rand.Int31()&15) - } - ret[i] = string(s) - } - return ret -} - -func randomInt(rand *rand.Rand) *big.Int { - return new(big.Int).SetInt64(int64(int32(rand.Uint32()))) -} - -func (*kexInitMsg) Generate(rand *rand.Rand, size int) reflect.Value { - ki := &kexInitMsg{} - randomBytes(ki.Cookie[:], rand) - ki.KexAlgos = randomNameList(rand) - ki.ServerHostKeyAlgos = randomNameList(rand) - ki.CiphersClientServer = randomNameList(rand) - ki.CiphersServerClient = randomNameList(rand) - ki.MACsClientServer = randomNameList(rand) - ki.MACsServerClient = randomNameList(rand) - ki.CompressionClientServer = randomNameList(rand) - ki.CompressionServerClient = randomNameList(rand) - ki.LanguagesClientServer = randomNameList(rand) - ki.LanguagesServerClient = randomNameList(rand) - if rand.Int31()&1 == 1 { - ki.FirstKexFollows = true - } - return reflect.ValueOf(ki) -} - -func (*kexDHInitMsg) Generate(rand *rand.Rand, size int) reflect.Value { - dhi := &kexDHInitMsg{} - dhi.X = randomInt(rand) - return reflect.ValueOf(dhi) -} - -var ( - _kexInitMsg = new(kexInitMsg).Generate(rand.New(rand.NewSource(0)), 10).Elem().Interface() - _kexDHInitMsg = new(kexDHInitMsg).Generate(rand.New(rand.NewSource(0)), 10).Elem().Interface() - - _kexInit = Marshal(_kexInitMsg) - _kexDHInit = Marshal(_kexDHInitMsg) -) - -func BenchmarkMarshalKexInitMsg(b *testing.B) { - for i := 0; i < b.N; i++ { - Marshal(_kexInitMsg) - } -} - -func BenchmarkUnmarshalKexInitMsg(b *testing.B) { - m := new(kexInitMsg) - for i := 0; i < b.N; i++ { - Unmarshal(_kexInit, m) - } -} - -func BenchmarkMarshalKexDHInitMsg(b *testing.B) { - for i := 0; i < b.N; i++ { - Marshal(_kexDHInitMsg) - } -} - -func BenchmarkUnmarshalKexDHInitMsg(b *testing.B) { - m := new(kexDHInitMsg) - for i := 0; i < b.N; i++ { - Unmarshal(_kexDHInit, m) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/mux_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/mux_test.go deleted file mode 100644 index 523038960f..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/mux_test.go +++ /dev/null @@ -1,525 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "io" - "io/ioutil" - "sync" - "testing" -) - -func muxPair() (*mux, *mux) { - a, b := memPipe() - - s := newMux(a) - c := newMux(b) - - return s, c -} - -// Returns both ends of a channel, and the mux for the the 2nd -// channel. -func channelPair(t *testing.T) (*channel, *channel, *mux) { - c, s := muxPair() - - res := make(chan *channel, 1) - go func() { - newCh, ok := <-s.incomingChannels - if !ok { - t.Fatalf("No incoming channel") - } - if newCh.ChannelType() != "chan" { - t.Fatalf("got type %q want chan", newCh.ChannelType()) - } - ch, _, err := newCh.Accept() - if err != nil { - t.Fatalf("Accept %v", err) - } - res <- ch.(*channel) - }() - - ch, err := c.openChannel("chan", nil) - if err != nil { - t.Fatalf("OpenChannel: %v", err) - } - - return <-res, ch, c -} - -// Test that stderr and stdout can be addressed from different -// goroutines. This is intended for use with the race detector. -func TestMuxChannelExtendedThreadSafety(t *testing.T) { - writer, reader, mux := channelPair(t) - defer writer.Close() - defer reader.Close() - defer mux.Close() - - var wr, rd sync.WaitGroup - magic := "hello world" - - wr.Add(2) - go func() { - io.WriteString(writer, magic) - wr.Done() - }() - go func() { - io.WriteString(writer.Stderr(), magic) - wr.Done() - }() - - rd.Add(2) - go func() { - c, err := ioutil.ReadAll(reader) - if string(c) != magic { - t.Fatalf("stdout read got %q, want %q (error %s)", c, magic, err) - } - rd.Done() - }() - go func() { - c, err := ioutil.ReadAll(reader.Stderr()) - if string(c) != magic { - t.Fatalf("stderr read got %q, want %q (error %s)", c, magic, err) - } - rd.Done() - }() - - wr.Wait() - writer.CloseWrite() - rd.Wait() -} - -func TestMuxReadWrite(t *testing.T) { - s, c, mux := channelPair(t) - defer s.Close() - defer c.Close() - defer mux.Close() - - magic := "hello world" - magicExt := "hello stderr" - go func() { - _, err := s.Write([]byte(magic)) - if err != nil { - t.Fatalf("Write: %v", err) - } - _, err = s.Extended(1).Write([]byte(magicExt)) - if err != nil { - t.Fatalf("Write: %v", err) - } - err = s.Close() - if err != nil { - t.Fatalf("Close: %v", err) - } - }() - - var buf [1024]byte - n, err := c.Read(buf[:]) - if err != nil { - t.Fatalf("server Read: %v", err) - } - got := string(buf[:n]) - if got != magic { - t.Fatalf("server: got %q want %q", got, magic) - } - - n, err = c.Extended(1).Read(buf[:]) - if err != nil { - t.Fatalf("server Read: %v", err) - } - - got = string(buf[:n]) - if got != magicExt { - t.Fatalf("server: got %q want %q", got, magic) - } -} - -func TestMuxChannelOverflow(t *testing.T) { - reader, writer, mux := channelPair(t) - defer reader.Close() - defer writer.Close() - defer mux.Close() - - wDone := make(chan int, 1) - go func() { - if _, err := writer.Write(make([]byte, channelWindowSize)); err != nil { - t.Errorf("could not fill window: %v", err) - } - writer.Write(make([]byte, 1)) - wDone <- 1 - }() - writer.remoteWin.waitWriterBlocked() - - // Send 1 byte. - packet := make([]byte, 1+4+4+1) - packet[0] = msgChannelData - marshalUint32(packet[1:], writer.remoteId) - marshalUint32(packet[5:], uint32(1)) - packet[9] = 42 - - if err := writer.mux.conn.writePacket(packet); err != nil { - t.Errorf("could not send packet") - } - if _, err := reader.SendRequest("hello", true, nil); err == nil { - t.Errorf("SendRequest succeeded.") - } - <-wDone -} - -func TestMuxChannelCloseWriteUnblock(t *testing.T) { - reader, writer, mux := channelPair(t) - defer reader.Close() - defer writer.Close() - defer mux.Close() - - wDone := make(chan int, 1) - go func() { - if _, err := writer.Write(make([]byte, channelWindowSize)); err != nil { - t.Errorf("could not fill window: %v", err) - } - if _, err := writer.Write(make([]byte, 1)); err != io.EOF { - t.Errorf("got %v, want EOF for unblock write", err) - } - wDone <- 1 - }() - - writer.remoteWin.waitWriterBlocked() - reader.Close() - <-wDone -} - -func TestMuxConnectionCloseWriteUnblock(t *testing.T) { - reader, writer, mux := channelPair(t) - defer reader.Close() - defer writer.Close() - defer mux.Close() - - wDone := make(chan int, 1) - go func() { - if _, err := writer.Write(make([]byte, channelWindowSize)); err != nil { - t.Errorf("could not fill window: %v", err) - } - if _, err := writer.Write(make([]byte, 1)); err != io.EOF { - t.Errorf("got %v, want EOF for unblock write", err) - } - wDone <- 1 - }() - - writer.remoteWin.waitWriterBlocked() - mux.Close() - <-wDone -} - -func TestMuxReject(t *testing.T) { - client, server := muxPair() - defer server.Close() - defer client.Close() - - go func() { - ch, ok := <-server.incomingChannels - if !ok { - t.Fatalf("Accept") - } - if ch.ChannelType() != "ch" || string(ch.ExtraData()) != "extra" { - t.Fatalf("unexpected channel: %q, %q", ch.ChannelType(), ch.ExtraData()) - } - ch.Reject(RejectionReason(42), "message") - }() - - ch, err := client.openChannel("ch", []byte("extra")) - if ch != nil { - t.Fatal("openChannel not rejected") - } - - ocf, ok := err.(*OpenChannelError) - if !ok { - t.Errorf("got %#v want *OpenChannelError", err) - } else if ocf.Reason != 42 || ocf.Message != "message" { - t.Errorf("got %#v, want {Reason: 42, Message: %q}", ocf, "message") - } - - want := "ssh: rejected: unknown reason 42 (message)" - if err.Error() != want { - t.Errorf("got %q, want %q", err.Error(), want) - } -} - -func TestMuxChannelRequest(t *testing.T) { - client, server, mux := channelPair(t) - defer server.Close() - defer client.Close() - defer mux.Close() - - var received int - var wg sync.WaitGroup - wg.Add(1) - go func() { - for r := range server.incomingRequests { - received++ - r.Reply(r.Type == "yes", nil) - } - wg.Done() - }() - _, err := client.SendRequest("yes", false, nil) - if err != nil { - t.Fatalf("SendRequest: %v", err) - } - ok, err := client.SendRequest("yes", true, nil) - if err != nil { - t.Fatalf("SendRequest: %v", err) - } - - if !ok { - t.Errorf("SendRequest(yes): %v", ok) - - } - - ok, err = client.SendRequest("no", true, nil) - if err != nil { - t.Fatalf("SendRequest: %v", err) - } - if ok { - t.Errorf("SendRequest(no): %v", ok) - - } - - client.Close() - wg.Wait() - - if received != 3 { - t.Errorf("got %d requests, want %d", received, 3) - } -} - -func TestMuxGlobalRequest(t *testing.T) { - clientMux, serverMux := muxPair() - defer serverMux.Close() - defer clientMux.Close() - - var seen bool - go func() { - for r := range serverMux.incomingRequests { - seen = seen || r.Type == "peek" - if r.WantReply { - err := r.Reply(r.Type == "yes", - append([]byte(r.Type), r.Payload...)) - if err != nil { - t.Errorf("AckRequest: %v", err) - } - } - } - }() - - _, _, err := clientMux.SendRequest("peek", false, nil) - if err != nil { - t.Errorf("SendRequest: %v", err) - } - - ok, data, err := clientMux.SendRequest("yes", true, []byte("a")) - if !ok || string(data) != "yesa" || err != nil { - t.Errorf("SendRequest(\"yes\", true, \"a\"): %v %v %v", - ok, data, err) - } - if ok, data, err := clientMux.SendRequest("yes", true, []byte("a")); !ok || string(data) != "yesa" || err != nil { - t.Errorf("SendRequest(\"yes\", true, \"a\"): %v %v %v", - ok, data, err) - } - - if ok, data, err := clientMux.SendRequest("no", true, []byte("a")); ok || string(data) != "noa" || err != nil { - t.Errorf("SendRequest(\"no\", true, \"a\"): %v %v %v", - ok, data, err) - } - - clientMux.Disconnect(0, "") - if !seen { - t.Errorf("never saw 'peek' request") - } -} - -func TestMuxGlobalRequestUnblock(t *testing.T) { - clientMux, serverMux := muxPair() - defer serverMux.Close() - defer clientMux.Close() - - result := make(chan error, 1) - go func() { - _, _, err := clientMux.SendRequest("hello", true, nil) - result <- err - }() - - <-serverMux.incomingRequests - serverMux.conn.Close() - err := <-result - - if err != io.EOF { - t.Errorf("want EOF, got %v", io.EOF) - } -} - -func TestMuxChannelRequestUnblock(t *testing.T) { - a, b, connB := channelPair(t) - defer a.Close() - defer b.Close() - defer connB.Close() - - result := make(chan error, 1) - go func() { - _, err := a.SendRequest("hello", true, nil) - result <- err - }() - - <-b.incomingRequests - connB.conn.Close() - err := <-result - - if err != io.EOF { - t.Errorf("want EOF, got %v", err) - } -} - -func TestMuxDisconnect(t *testing.T) { - a, b := muxPair() - defer a.Close() - defer b.Close() - - go func() { - for r := range b.incomingRequests { - r.Reply(true, nil) - } - }() - - a.Disconnect(42, "whatever") - ok, _, err := a.SendRequest("hello", true, nil) - if ok || err == nil { - t.Errorf("got reply after disconnecting") - } - err = b.Wait() - if d, ok := err.(*disconnectMsg); !ok || d.Reason != 42 { - t.Errorf("got %#v, want disconnectMsg{Reason:42}", err) - } -} - -func TestMuxCloseChannel(t *testing.T) { - r, w, mux := channelPair(t) - defer mux.Close() - defer r.Close() - defer w.Close() - - result := make(chan error, 1) - go func() { - var b [1024]byte - _, err := r.Read(b[:]) - result <- err - }() - if err := w.Close(); err != nil { - t.Errorf("w.Close: %v", err) - } - - if _, err := w.Write([]byte("hello")); err != io.EOF { - t.Errorf("got err %v, want io.EOF after Close", err) - } - - if err := <-result; err != io.EOF { - t.Errorf("got %v (%T), want io.EOF", err, err) - } -} - -func TestMuxCloseWriteChannel(t *testing.T) { - r, w, mux := channelPair(t) - defer mux.Close() - - result := make(chan error, 1) - go func() { - var b [1024]byte - _, err := r.Read(b[:]) - result <- err - }() - if err := w.CloseWrite(); err != nil { - t.Errorf("w.CloseWrite: %v", err) - } - - if _, err := w.Write([]byte("hello")); err != io.EOF { - t.Errorf("got err %v, want io.EOF after CloseWrite", err) - } - - if err := <-result; err != io.EOF { - t.Errorf("got %v (%T), want io.EOF", err, err) - } -} - -func TestMuxInvalidRecord(t *testing.T) { - a, b := muxPair() - defer a.Close() - defer b.Close() - - packet := make([]byte, 1+4+4+1) - packet[0] = msgChannelData - marshalUint32(packet[1:], 29348723 /* invalid channel id */) - marshalUint32(packet[5:], 1) - packet[9] = 42 - - a.conn.writePacket(packet) - go a.SendRequest("hello", false, nil) - // 'a' wrote an invalid packet, so 'b' has exited. - req, ok := <-b.incomingRequests - if ok { - t.Errorf("got request %#v after receiving invalid packet", req) - } -} - -func TestZeroWindowAdjust(t *testing.T) { - a, b, mux := channelPair(t) - defer a.Close() - defer b.Close() - defer mux.Close() - - go func() { - io.WriteString(a, "hello") - // bogus adjust. - a.sendMessage(windowAdjustMsg{}) - io.WriteString(a, "world") - a.Close() - }() - - want := "helloworld" - c, _ := ioutil.ReadAll(b) - if string(c) != want { - t.Errorf("got %q want %q", c, want) - } -} - -func TestMuxMaxPacketSize(t *testing.T) { - a, b, mux := channelPair(t) - defer a.Close() - defer b.Close() - defer mux.Close() - - large := make([]byte, a.maxRemotePayload+1) - packet := make([]byte, 1+4+4+1+len(large)) - packet[0] = msgChannelData - marshalUint32(packet[1:], a.remoteId) - marshalUint32(packet[5:], uint32(len(large))) - packet[9] = 42 - - if err := a.mux.conn.writePacket(packet); err != nil { - t.Errorf("could not send packet") - } - - go a.SendRequest("hello", false, nil) - - _, ok := <-b.incomingRequests - if ok { - t.Errorf("connection still alive after receiving large packet.") - } -} - -// Don't ship code with debug=true. -func TestDebug(t *testing.T) { - if debugMux { - t.Error("mux debug switched on") - } - if debugHandshake { - t.Error("handshake debug switched on") - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/server.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/server.go deleted file mode 100644 index 8c4f1429ee..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/server.go +++ /dev/null @@ -1,477 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "errors" - "fmt" - "io" - "net" -) - -// The Permissions type holds fine-grained permissions that are -// specific to a user or a specific authentication method for a -// user. Permissions, except for "source-address", must be enforced in -// the server application layer, after successful authentication. The -// Permissions are passed on in ServerConn so a server implementation -// can honor them. -type Permissions struct { - // Critical options restrict default permissions. Common - // restrictions are "source-address" and "force-command". If - // the server cannot enforce the restriction, or does not - // recognize it, the user should not authenticate. - CriticalOptions map[string]string - - // Extensions are extra functionality that the server may - // offer on authenticated connections. Common extensions are - // "permit-agent-forwarding", "permit-X11-forwarding". Lack of - // support for an extension does not preclude authenticating a - // user. - Extensions map[string]string -} - -// ServerConfig holds server specific configuration data. -type ServerConfig struct { - // Config contains configuration shared between client and server. - Config - - hostKeys []Signer - - // NoClientAuth is true if clients are allowed to connect without - // authenticating. - NoClientAuth bool - - // PasswordCallback, if non-nil, is called when a user - // attempts to authenticate using a password. - PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error) - - // PublicKeyCallback, if non-nil, is called when a client attempts public - // key authentication. It must return true if the given public key is - // valid for the given user. For example, see CertChecker.Authenticate. - PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) - - // KeyboardInteractiveCallback, if non-nil, is called when - // keyboard-interactive authentication is selected (RFC - // 4256). The client object's Challenge function should be - // used to query the user. The callback may offer multiple - // Challenge rounds. To avoid information leaks, the client - // should be presented a challenge even if the user is - // unknown. - KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error) - - // AuthLogCallback, if non-nil, is called to log all authentication - // attempts. - AuthLogCallback func(conn ConnMetadata, method string, err error) -} - -// AddHostKey adds a private key as a host key. If an existing host -// key exists with the same algorithm, it is overwritten. Each server -// config must have at least one host key. -func (s *ServerConfig) AddHostKey(key Signer) { - for i, k := range s.hostKeys { - if k.PublicKey().Type() == key.PublicKey().Type() { - s.hostKeys[i] = key - return - } - } - - s.hostKeys = append(s.hostKeys, key) -} - -// cachedPubKey contains the results of querying whether a public key is -// acceptable for a user. -type cachedPubKey struct { - user string - pubKeyData []byte - result error - perms *Permissions -} - -const maxCachedPubKeys = 16 - -// pubKeyCache caches tests for public keys. Since SSH clients -// will query whether a public key is acceptable before attempting to -// authenticate with it, we end up with duplicate queries for public -// key validity. The cache only applies to a single ServerConn. -type pubKeyCache struct { - keys []cachedPubKey -} - -// get returns the result for a given user/algo/key tuple. -func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) { - for _, k := range c.keys { - if k.user == user && bytes.Equal(k.pubKeyData, pubKeyData) { - return k, true - } - } - return cachedPubKey{}, false -} - -// add adds the given tuple to the cache. -func (c *pubKeyCache) add(candidate cachedPubKey) { - if len(c.keys) < maxCachedPubKeys { - c.keys = append(c.keys, candidate) - } -} - -// ServerConn is an authenticated SSH connection, as seen from the -// server -type ServerConn struct { - Conn - - // If the succeeding authentication callback returned a - // non-nil Permissions pointer, it is stored here. - Permissions *Permissions -} - -// NewServerConn starts a new SSH server with c as the underlying -// transport. It starts with a handshake and, if the handshake is -// unsuccessful, it closes the connection and returns an error. The -// Request and NewChannel channels must be serviced, or the connection -// will hang. -func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) { - fullConf := *config - fullConf.SetDefaults() - s := &connection{ - sshConn: sshConn{conn: c}, - } - perms, err := s.serverHandshake(&fullConf) - if err != nil { - c.Close() - return nil, nil, nil, err - } - return &ServerConn{s, perms}, s.mux.incomingChannels, s.mux.incomingRequests, nil -} - -// signAndMarshal signs the data with the appropriate algorithm, -// and serializes the result in SSH wire format. -func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) { - sig, err := k.Sign(rand, data) - if err != nil { - return nil, err - } - - return Marshal(sig), nil -} - -// handshake performs key exchange and user authentication. -func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) { - if len(config.hostKeys) == 0 { - return nil, errors.New("ssh: server has no host keys") - } - - var err error - s.serverVersion = []byte(packageVersion) - s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion) - if err != nil { - return nil, err - } - - tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */) - s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config) - - if err := s.transport.requestKeyChange(); err != nil { - return nil, err - } - - if packet, err := s.transport.readPacket(); err != nil { - return nil, err - } else if packet[0] != msgNewKeys { - return nil, unexpectedMessageError(msgNewKeys, packet[0]) - } - - var packet []byte - if packet, err = s.transport.readPacket(); err != nil { - return nil, err - } - - var serviceRequest serviceRequestMsg - if err = Unmarshal(packet, &serviceRequest); err != nil { - return nil, err - } - if serviceRequest.Service != serviceUserAuth { - return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating") - } - serviceAccept := serviceAcceptMsg{ - Service: serviceUserAuth, - } - if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil { - return nil, err - } - - perms, err := s.serverAuthenticate(config) - if err != nil { - return nil, err - } - s.mux = newMux(s.transport) - return perms, err -} - -func isAcceptableAlgo(algo string) bool { - switch algo { - case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01: - return true - } - return false -} - -func checkSourceAddress(addr net.Addr, sourceAddr string) error { - if addr == nil { - return errors.New("ssh: no address known for client, but source-address match required") - } - - tcpAddr, ok := addr.(*net.TCPAddr) - if !ok { - return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr) - } - - if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil { - if bytes.Equal(allowedIP, tcpAddr.IP) { - return nil - } - } else { - _, ipNet, err := net.ParseCIDR(sourceAddr) - if err != nil { - return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err) - } - - if ipNet.Contains(tcpAddr.IP) { - return nil - } - } - - return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr) -} - -func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) { - var err error - var cache pubKeyCache - var perms *Permissions - -userAuthLoop: - for { - var userAuthReq userAuthRequestMsg - if packet, err := s.transport.readPacket(); err != nil { - return nil, err - } else if err = Unmarshal(packet, &userAuthReq); err != nil { - return nil, err - } - - if userAuthReq.Service != serviceSSH { - return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service) - } - - s.user = userAuthReq.User - perms = nil - authErr := errors.New("no auth passed yet") - - switch userAuthReq.Method { - case "none": - if config.NoClientAuth { - s.user = "" - authErr = nil - } - case "password": - if config.PasswordCallback == nil { - authErr = errors.New("ssh: password auth not configured") - break - } - payload := userAuthReq.Payload - if len(payload) < 1 || payload[0] != 0 { - return nil, parseError(msgUserAuthRequest) - } - payload = payload[1:] - password, payload, ok := parseString(payload) - if !ok || len(payload) > 0 { - return nil, parseError(msgUserAuthRequest) - } - - perms, authErr = config.PasswordCallback(s, password) - case "keyboard-interactive": - if config.KeyboardInteractiveCallback == nil { - authErr = errors.New("ssh: keyboard-interactive auth not configubred") - break - } - - prompter := &sshClientKeyboardInteractive{s} - perms, authErr = config.KeyboardInteractiveCallback(s, prompter.Challenge) - case "publickey": - if config.PublicKeyCallback == nil { - authErr = errors.New("ssh: publickey auth not configured") - break - } - payload := userAuthReq.Payload - if len(payload) < 1 { - return nil, parseError(msgUserAuthRequest) - } - isQuery := payload[0] == 0 - payload = payload[1:] - algoBytes, payload, ok := parseString(payload) - if !ok { - return nil, parseError(msgUserAuthRequest) - } - algo := string(algoBytes) - if !isAcceptableAlgo(algo) { - authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo) - break - } - - pubKeyData, payload, ok := parseString(payload) - if !ok { - return nil, parseError(msgUserAuthRequest) - } - - pubKey, err := ParsePublicKey(pubKeyData) - if err != nil { - return nil, err - } - - candidate, ok := cache.get(s.user, pubKeyData) - if !ok { - candidate.user = s.user - candidate.pubKeyData = pubKeyData - candidate.perms, candidate.result = config.PublicKeyCallback(s, pubKey) - if candidate.result == nil && candidate.perms != nil && candidate.perms.CriticalOptions != nil && candidate.perms.CriticalOptions[sourceAddressCriticalOption] != "" { - candidate.result = checkSourceAddress( - s.RemoteAddr(), - candidate.perms.CriticalOptions[sourceAddressCriticalOption]) - } - cache.add(candidate) - } - - if isQuery { - // The client can query if the given public key - // would be okay. - if len(payload) > 0 { - return nil, parseError(msgUserAuthRequest) - } - - if candidate.result == nil { - okMsg := userAuthPubKeyOkMsg{ - Algo: algo, - PubKey: pubKeyData, - } - if err = s.transport.writePacket(Marshal(&okMsg)); err != nil { - return nil, err - } - continue userAuthLoop - } - authErr = candidate.result - } else { - sig, payload, ok := parseSignature(payload) - if !ok || len(payload) > 0 { - return nil, parseError(msgUserAuthRequest) - } - // Ensure the public key algo and signature algo - // are supported. Compare the private key - // algorithm name that corresponds to algo with - // sig.Format. This is usually the same, but - // for certs, the names differ. - if !isAcceptableAlgo(sig.Format) { - break - } - signedData := buildDataSignedForAuth(s.transport.getSessionID(), userAuthReq, algoBytes, pubKeyData) - - if err := pubKey.Verify(signedData, sig); err != nil { - return nil, err - } - - authErr = candidate.result - perms = candidate.perms - } - default: - authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method) - } - - if config.AuthLogCallback != nil { - config.AuthLogCallback(s, userAuthReq.Method, authErr) - } - - if authErr == nil { - break userAuthLoop - } - - var failureMsg userAuthFailureMsg - if config.PasswordCallback != nil { - failureMsg.Methods = append(failureMsg.Methods, "password") - } - if config.PublicKeyCallback != nil { - failureMsg.Methods = append(failureMsg.Methods, "publickey") - } - if config.KeyboardInteractiveCallback != nil { - failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive") - } - - if len(failureMsg.Methods) == 0 { - return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false") - } - - if err = s.transport.writePacket(Marshal(&failureMsg)); err != nil { - return nil, err - } - } - - if err = s.transport.writePacket([]byte{msgUserAuthSuccess}); err != nil { - return nil, err - } - return perms, nil -} - -// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by -// asking the client on the other side of a ServerConn. -type sshClientKeyboardInteractive struct { - *connection -} - -func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) { - if len(questions) != len(echos) { - return nil, errors.New("ssh: echos and questions must have equal length") - } - - var prompts []byte - for i := range questions { - prompts = appendString(prompts, questions[i]) - prompts = appendBool(prompts, echos[i]) - } - - if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{ - Instruction: instruction, - NumPrompts: uint32(len(questions)), - Prompts: prompts, - })); err != nil { - return nil, err - } - - packet, err := c.transport.readPacket() - if err != nil { - return nil, err - } - if packet[0] != msgUserAuthInfoResponse { - return nil, unexpectedMessageError(msgUserAuthInfoResponse, packet[0]) - } - packet = packet[1:] - - n, packet, ok := parseUint32(packet) - if !ok || int(n) != len(questions) { - return nil, parseError(msgUserAuthInfoResponse) - } - - for i := uint32(0); i < n; i++ { - ans, rest, ok := parseString(packet) - if !ok { - return nil, parseError(msgUserAuthInfoResponse) - } - - answers = append(answers, string(ans)) - packet = rest - } - if len(packet) != 0 { - return nil, errors.New("ssh: junk at end of message") - } - - return answers, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/session.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/session.go deleted file mode 100644 index 3b42b508a8..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/session.go +++ /dev/null @@ -1,605 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -// Session implements an interactive session described in -// "RFC 4254, section 6". - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "sync" -) - -type Signal string - -// POSIX signals as listed in RFC 4254 Section 6.10. -const ( - SIGABRT Signal = "ABRT" - SIGALRM Signal = "ALRM" - SIGFPE Signal = "FPE" - SIGHUP Signal = "HUP" - SIGILL Signal = "ILL" - SIGINT Signal = "INT" - SIGKILL Signal = "KILL" - SIGPIPE Signal = "PIPE" - SIGQUIT Signal = "QUIT" - SIGSEGV Signal = "SEGV" - SIGTERM Signal = "TERM" - SIGUSR1 Signal = "USR1" - SIGUSR2 Signal = "USR2" -) - -var signals = map[Signal]int{ - SIGABRT: 6, - SIGALRM: 14, - SIGFPE: 8, - SIGHUP: 1, - SIGILL: 4, - SIGINT: 2, - SIGKILL: 9, - SIGPIPE: 13, - SIGQUIT: 3, - SIGSEGV: 11, - SIGTERM: 15, -} - -type TerminalModes map[uint8]uint32 - -// POSIX terminal mode flags as listed in RFC 4254 Section 8. -const ( - tty_OP_END = 0 - VINTR = 1 - VQUIT = 2 - VERASE = 3 - VKILL = 4 - VEOF = 5 - VEOL = 6 - VEOL2 = 7 - VSTART = 8 - VSTOP = 9 - VSUSP = 10 - VDSUSP = 11 - VREPRINT = 12 - VWERASE = 13 - VLNEXT = 14 - VFLUSH = 15 - VSWTCH = 16 - VSTATUS = 17 - VDISCARD = 18 - IGNPAR = 30 - PARMRK = 31 - INPCK = 32 - ISTRIP = 33 - INLCR = 34 - IGNCR = 35 - ICRNL = 36 - IUCLC = 37 - IXON = 38 - IXANY = 39 - IXOFF = 40 - IMAXBEL = 41 - ISIG = 50 - ICANON = 51 - XCASE = 52 - ECHO = 53 - ECHOE = 54 - ECHOK = 55 - ECHONL = 56 - NOFLSH = 57 - TOSTOP = 58 - IEXTEN = 59 - ECHOCTL = 60 - ECHOKE = 61 - PENDIN = 62 - OPOST = 70 - OLCUC = 71 - ONLCR = 72 - OCRNL = 73 - ONOCR = 74 - ONLRET = 75 - CS7 = 90 - CS8 = 91 - PARENB = 92 - PARODD = 93 - TTY_OP_ISPEED = 128 - TTY_OP_OSPEED = 129 -) - -// A Session represents a connection to a remote command or shell. -type Session struct { - // Stdin specifies the remote process's standard input. - // If Stdin is nil, the remote process reads from an empty - // bytes.Buffer. - Stdin io.Reader - - // Stdout and Stderr specify the remote process's standard - // output and error. - // - // If either is nil, Run connects the corresponding file - // descriptor to an instance of ioutil.Discard. There is a - // fixed amount of buffering that is shared for the two streams. - // If either blocks it may eventually cause the remote - // command to block. - Stdout io.Writer - Stderr io.Writer - - ch Channel // the channel backing this session - started bool // true once Start, Run or Shell is invoked. - copyFuncs []func() error - errors chan error // one send per copyFunc - - // true if pipe method is active - stdinpipe, stdoutpipe, stderrpipe bool - - // stdinPipeWriter is non-nil if StdinPipe has not been called - // and Stdin was specified by the user; it is the write end of - // a pipe connecting Session.Stdin to the stdin channel. - stdinPipeWriter io.WriteCloser - - exitStatus chan error -} - -// SendRequest sends an out-of-band channel request on the SSH channel -// underlying the session. -func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { - return s.ch.SendRequest(name, wantReply, payload) -} - -func (s *Session) Close() error { - return s.ch.Close() -} - -// RFC 4254 Section 6.4. -type setenvRequest struct { - Name string - Value string -} - -// Setenv sets an environment variable that will be applied to any -// command executed by Shell or Run. -func (s *Session) Setenv(name, value string) error { - msg := setenvRequest{ - Name: name, - Value: value, - } - ok, err := s.ch.SendRequest("env", true, Marshal(&msg)) - if err == nil && !ok { - err = errors.New("ssh: setenv failed") - } - return err -} - -// RFC 4254 Section 6.2. -type ptyRequestMsg struct { - Term string - Columns uint32 - Rows uint32 - Width uint32 - Height uint32 - Modelist string -} - -// RequestPty requests the association of a pty with the session on the remote host. -func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error { - var tm []byte - for k, v := range termmodes { - kv := struct { - Key byte - Val uint32 - }{k, v} - - tm = append(tm, Marshal(&kv)...) - } - tm = append(tm, tty_OP_END) - req := ptyRequestMsg{ - Term: term, - Columns: uint32(w), - Rows: uint32(h), - Width: uint32(w * 8), - Height: uint32(h * 8), - Modelist: string(tm), - } - ok, err := s.ch.SendRequest("pty-req", true, Marshal(&req)) - if err == nil && !ok { - err = errors.New("ssh: pty-req failed") - } - return err -} - -// RFC 4254 Section 6.5. -type subsystemRequestMsg struct { - Subsystem string -} - -// RequestSubsystem requests the association of a subsystem with the session on the remote host. -// A subsystem is a predefined command that runs in the background when the ssh session is initiated -func (s *Session) RequestSubsystem(subsystem string) error { - msg := subsystemRequestMsg{ - Subsystem: subsystem, - } - ok, err := s.ch.SendRequest("subsystem", true, Marshal(&msg)) - if err == nil && !ok { - err = errors.New("ssh: subsystem request failed") - } - return err -} - -// RFC 4254 Section 6.9. -type signalMsg struct { - Signal string -} - -// Signal sends the given signal to the remote process. -// sig is one of the SIG* constants. -func (s *Session) Signal(sig Signal) error { - msg := signalMsg{ - Signal: string(sig), - } - - _, err := s.ch.SendRequest("signal", false, Marshal(&msg)) - return err -} - -// RFC 4254 Section 6.5. -type execMsg struct { - Command string -} - -// Start runs cmd on the remote host. Typically, the remote -// server passes cmd to the shell for interpretation. -// A Session only accepts one call to Run, Start or Shell. -func (s *Session) Start(cmd string) error { - if s.started { - return errors.New("ssh: session already started") - } - req := execMsg{ - Command: cmd, - } - - ok, err := s.ch.SendRequest("exec", true, Marshal(&req)) - if err == nil && !ok { - err = fmt.Errorf("ssh: command %v failed", cmd) - } - if err != nil { - return err - } - return s.start() -} - -// Run runs cmd on the remote host. Typically, the remote -// server passes cmd to the shell for interpretation. -// A Session only accepts one call to Run, Start, Shell, Output, -// or CombinedOutput. -// -// The returned error is nil if the command runs, has no problems -// copying stdin, stdout, and stderr, and exits with a zero exit -// status. -// -// If the command fails to run or doesn't complete successfully, the -// error is of type *ExitError. Other error types may be -// returned for I/O problems. -func (s *Session) Run(cmd string) error { - err := s.Start(cmd) - if err != nil { - return err - } - return s.Wait() -} - -// Output runs cmd on the remote host and returns its standard output. -func (s *Session) Output(cmd string) ([]byte, error) { - if s.Stdout != nil { - return nil, errors.New("ssh: Stdout already set") - } - var b bytes.Buffer - s.Stdout = &b - err := s.Run(cmd) - return b.Bytes(), err -} - -type singleWriter struct { - b bytes.Buffer - mu sync.Mutex -} - -func (w *singleWriter) Write(p []byte) (int, error) { - w.mu.Lock() - defer w.mu.Unlock() - return w.b.Write(p) -} - -// CombinedOutput runs cmd on the remote host and returns its combined -// standard output and standard error. -func (s *Session) CombinedOutput(cmd string) ([]byte, error) { - if s.Stdout != nil { - return nil, errors.New("ssh: Stdout already set") - } - if s.Stderr != nil { - return nil, errors.New("ssh: Stderr already set") - } - var b singleWriter - s.Stdout = &b - s.Stderr = &b - err := s.Run(cmd) - return b.b.Bytes(), err -} - -// Shell starts a login shell on the remote host. A Session only -// accepts one call to Run, Start, Shell, Output, or CombinedOutput. -func (s *Session) Shell() error { - if s.started { - return errors.New("ssh: session already started") - } - - ok, err := s.ch.SendRequest("shell", true, nil) - if err == nil && !ok { - return fmt.Errorf("ssh: cound not start shell") - } - if err != nil { - return err - } - return s.start() -} - -func (s *Session) start() error { - s.started = true - - type F func(*Session) - for _, setupFd := range []F{(*Session).stdin, (*Session).stdout, (*Session).stderr} { - setupFd(s) - } - - s.errors = make(chan error, len(s.copyFuncs)) - for _, fn := range s.copyFuncs { - go func(fn func() error) { - s.errors <- fn() - }(fn) - } - return nil -} - -// Wait waits for the remote command to exit. -// -// The returned error is nil if the command runs, has no problems -// copying stdin, stdout, and stderr, and exits with a zero exit -// status. -// -// If the command fails to run or doesn't complete successfully, the -// error is of type *ExitError. Other error types may be -// returned for I/O problems. -func (s *Session) Wait() error { - if !s.started { - return errors.New("ssh: session not started") - } - waitErr := <-s.exitStatus - - if s.stdinPipeWriter != nil { - s.stdinPipeWriter.Close() - } - var copyError error - for _ = range s.copyFuncs { - if err := <-s.errors; err != nil && copyError == nil { - copyError = err - } - } - if waitErr != nil { - return waitErr - } - return copyError -} - -func (s *Session) wait(reqs <-chan *Request) error { - wm := Waitmsg{status: -1} - // Wait for msg channel to be closed before returning. - for msg := range reqs { - switch msg.Type { - case "exit-status": - d := msg.Payload - wm.status = int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3]) - case "exit-signal": - var sigval struct { - Signal string - CoreDumped bool - Error string - Lang string - } - if err := Unmarshal(msg.Payload, &sigval); err != nil { - return err - } - - // Must sanitize strings? - wm.signal = sigval.Signal - wm.msg = sigval.Error - wm.lang = sigval.Lang - default: - // This handles keepalives and matches - // OpenSSH's behaviour. - if msg.WantReply { - msg.Reply(false, nil) - } - } - } - if wm.status == 0 { - return nil - } - if wm.status == -1 { - // exit-status was never sent from server - if wm.signal == "" { - return errors.New("wait: remote command exited without exit status or exit signal") - } - wm.status = 128 - if _, ok := signals[Signal(wm.signal)]; ok { - wm.status += signals[Signal(wm.signal)] - } - } - return &ExitError{wm} -} - -func (s *Session) stdin() { - if s.stdinpipe { - return - } - var stdin io.Reader - if s.Stdin == nil { - stdin = new(bytes.Buffer) - } else { - r, w := io.Pipe() - go func() { - _, err := io.Copy(w, s.Stdin) - w.CloseWithError(err) - }() - stdin, s.stdinPipeWriter = r, w - } - s.copyFuncs = append(s.copyFuncs, func() error { - _, err := io.Copy(s.ch, stdin) - if err1 := s.ch.CloseWrite(); err == nil && err1 != io.EOF { - err = err1 - } - return err - }) -} - -func (s *Session) stdout() { - if s.stdoutpipe { - return - } - if s.Stdout == nil { - s.Stdout = ioutil.Discard - } - s.copyFuncs = append(s.copyFuncs, func() error { - _, err := io.Copy(s.Stdout, s.ch) - return err - }) -} - -func (s *Session) stderr() { - if s.stderrpipe { - return - } - if s.Stderr == nil { - s.Stderr = ioutil.Discard - } - s.copyFuncs = append(s.copyFuncs, func() error { - _, err := io.Copy(s.Stderr, s.ch.Stderr()) - return err - }) -} - -// sessionStdin reroutes Close to CloseWrite. -type sessionStdin struct { - io.Writer - ch Channel -} - -func (s *sessionStdin) Close() error { - return s.ch.CloseWrite() -} - -// StdinPipe returns a pipe that will be connected to the -// remote command's standard input when the command starts. -func (s *Session) StdinPipe() (io.WriteCloser, error) { - if s.Stdin != nil { - return nil, errors.New("ssh: Stdin already set") - } - if s.started { - return nil, errors.New("ssh: StdinPipe after process started") - } - s.stdinpipe = true - return &sessionStdin{s.ch, s.ch}, nil -} - -// StdoutPipe returns a pipe that will be connected to the -// remote command's standard output when the command starts. -// There is a fixed amount of buffering that is shared between -// stdout and stderr streams. If the StdoutPipe reader is -// not serviced fast enough it may eventually cause the -// remote command to block. -func (s *Session) StdoutPipe() (io.Reader, error) { - if s.Stdout != nil { - return nil, errors.New("ssh: Stdout already set") - } - if s.started { - return nil, errors.New("ssh: StdoutPipe after process started") - } - s.stdoutpipe = true - return s.ch, nil -} - -// StderrPipe returns a pipe that will be connected to the -// remote command's standard error when the command starts. -// There is a fixed amount of buffering that is shared between -// stdout and stderr streams. If the StderrPipe reader is -// not serviced fast enough it may eventually cause the -// remote command to block. -func (s *Session) StderrPipe() (io.Reader, error) { - if s.Stderr != nil { - return nil, errors.New("ssh: Stderr already set") - } - if s.started { - return nil, errors.New("ssh: StderrPipe after process started") - } - s.stderrpipe = true - return s.ch.Stderr(), nil -} - -// newSession returns a new interactive session on the remote host. -func newSession(ch Channel, reqs <-chan *Request) (*Session, error) { - s := &Session{ - ch: ch, - } - s.exitStatus = make(chan error, 1) - go func() { - s.exitStatus <- s.wait(reqs) - }() - - return s, nil -} - -// An ExitError reports unsuccessful completion of a remote command. -type ExitError struct { - Waitmsg -} - -func (e *ExitError) Error() string { - return e.Waitmsg.String() -} - -// Waitmsg stores the information about an exited remote command -// as reported by Wait. -type Waitmsg struct { - status int - signal string - msg string - lang string -} - -// ExitStatus returns the exit status of the remote command. -func (w Waitmsg) ExitStatus() int { - return w.status -} - -// Signal returns the exit signal of the remote command if -// it was terminated violently. -func (w Waitmsg) Signal() string { - return w.signal -} - -// Msg returns the exit message given by the remote command -func (w Waitmsg) Msg() string { - return w.msg -} - -// Lang returns the language tag. See RFC 3066 -func (w Waitmsg) Lang() string { - return w.lang -} - -func (w Waitmsg) String() string { - return fmt.Sprintf("Process exited with: %v. Reason was: %v (%v)", w.status, w.msg, w.signal) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/session_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/session_test.go deleted file mode 100644 index fce9868222..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/session_test.go +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -// Session tests. - -import ( - "bytes" - crypto_rand "crypto/rand" - "io" - "io/ioutil" - "math/rand" - "testing" - - "golang.org/x/crypto/ssh/terminal" -) - -type serverType func(Channel, <-chan *Request, *testing.T) - -// dial constructs a new test server and returns a *ClientConn. -func dial(handler serverType, t *testing.T) *Client { - c1, c2, err := netPipe() - if err != nil { - t.Fatalf("netPipe: %v", err) - } - - go func() { - defer c1.Close() - conf := ServerConfig{ - NoClientAuth: true, - } - conf.AddHostKey(testSigners["rsa"]) - - _, chans, reqs, err := NewServerConn(c1, &conf) - if err != nil { - t.Fatalf("Unable to handshake: %v", err) - } - go DiscardRequests(reqs) - - for newCh := range chans { - if newCh.ChannelType() != "session" { - newCh.Reject(UnknownChannelType, "unknown channel type") - continue - } - - ch, inReqs, err := newCh.Accept() - if err != nil { - t.Errorf("Accept: %v", err) - continue - } - go func() { - handler(ch, inReqs, t) - }() - } - }() - - config := &ClientConfig{ - User: "testuser", - } - - conn, chans, reqs, err := NewClientConn(c2, "", config) - if err != nil { - t.Fatalf("unable to dial remote side: %v", err) - } - - return NewClient(conn, chans, reqs) -} - -// Test a simple string is returned to session.Stdout. -func TestSessionShell(t *testing.T) { - conn := dial(shellHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - stdout := new(bytes.Buffer) - session.Stdout = stdout - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %s", err) - } - if err := session.Wait(); err != nil { - t.Fatalf("Remote command did not exit cleanly: %v", err) - } - actual := stdout.String() - if actual != "golang" { - t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual) - } -} - -// TODO(dfc) add support for Std{in,err}Pipe when the Server supports it. - -// Test a simple string is returned via StdoutPipe. -func TestSessionStdoutPipe(t *testing.T) { - conn := dial(shellHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("Unable to request StdoutPipe(): %v", err) - } - var buf bytes.Buffer - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - done := make(chan bool, 1) - go func() { - if _, err := io.Copy(&buf, stdout); err != nil { - t.Errorf("Copy of stdout failed: %v", err) - } - done <- true - }() - if err := session.Wait(); err != nil { - t.Fatalf("Remote command did not exit cleanly: %v", err) - } - <-done - actual := buf.String() - if actual != "golang" { - t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual) - } -} - -// Test that a simple string is returned via the Output helper, -// and that stderr is discarded. -func TestSessionOutput(t *testing.T) { - conn := dial(fixedOutputHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - - buf, err := session.Output("") // cmd is ignored by fixedOutputHandler - if err != nil { - t.Error("Remote command did not exit cleanly:", err) - } - w := "this-is-stdout." - g := string(buf) - if g != w { - t.Error("Remote command did not return expected string:") - t.Logf("want %q", w) - t.Logf("got %q", g) - } -} - -// Test that both stdout and stderr are returned -// via the CombinedOutput helper. -func TestSessionCombinedOutput(t *testing.T) { - conn := dial(fixedOutputHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - - buf, err := session.CombinedOutput("") // cmd is ignored by fixedOutputHandler - if err != nil { - t.Error("Remote command did not exit cleanly:", err) - } - const stdout = "this-is-stdout." - const stderr = "this-is-stderr." - g := string(buf) - if g != stdout+stderr && g != stderr+stdout { - t.Error("Remote command did not return expected string:") - t.Logf("want %q, or %q", stdout+stderr, stderr+stdout) - t.Logf("got %q", g) - } -} - -// Test non-0 exit status is returned correctly. -func TestExitStatusNonZero(t *testing.T) { - conn := dial(exitStatusNonZeroHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.ExitStatus() != 15 { - t.Fatalf("expected command to exit with 15 but got %v", e.ExitStatus()) - } -} - -// Test 0 exit status is returned correctly. -func TestExitStatusZero(t *testing.T) { - conn := dial(exitStatusZeroHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err != nil { - t.Fatalf("expected nil but got %v", err) - } -} - -// Test exit signal and status are both returned correctly. -func TestExitSignalAndStatus(t *testing.T) { - conn := dial(exitSignalAndStatusHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.Signal() != "TERM" || e.ExitStatus() != 15 { - t.Fatalf("expected command to exit with signal TERM and status 15 but got signal %s and status %v", e.Signal(), e.ExitStatus()) - } -} - -// Test exit signal and status are both returned correctly. -func TestKnownExitSignalOnly(t *testing.T) { - conn := dial(exitSignalHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.Signal() != "TERM" || e.ExitStatus() != 143 { - t.Fatalf("expected command to exit with signal TERM and status 143 but got signal %s and status %v", e.Signal(), e.ExitStatus()) - } -} - -// Test exit signal and status are both returned correctly. -func TestUnknownExitSignal(t *testing.T) { - conn := dial(exitSignalUnknownHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - e, ok := err.(*ExitError) - if !ok { - t.Fatalf("expected *ExitError but got %T", err) - } - if e.Signal() != "SYS" || e.ExitStatus() != 128 { - t.Fatalf("expected command to exit with signal SYS and status 128 but got signal %s and status %v", e.Signal(), e.ExitStatus()) - } -} - -// Test WaitMsg is not returned if the channel closes abruptly. -func TestExitWithoutStatusOrSignal(t *testing.T) { - conn := dial(exitWithoutSignalOrStatus, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatalf("Unable to request new session: %v", err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err == nil { - t.Fatalf("expected command to fail but it didn't") - } - _, ok := err.(*ExitError) - if ok { - // you can't actually test for errors.errorString - // because it's not exported. - t.Fatalf("expected *errorString but got %T", err) - } -} - -// windowTestBytes is the number of bytes that we'll send to the SSH server. -const windowTestBytes = 16000 * 200 - -// TestServerWindow writes random data to the server. The server is expected to echo -// the same data back, which is compared against the original. -func TestServerWindow(t *testing.T) { - origBuf := bytes.NewBuffer(make([]byte, 0, windowTestBytes)) - io.CopyN(origBuf, crypto_rand.Reader, windowTestBytes) - origBytes := origBuf.Bytes() - - conn := dial(echoHandler, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatal(err) - } - defer session.Close() - result := make(chan []byte) - - go func() { - defer close(result) - echoedBuf := bytes.NewBuffer(make([]byte, 0, windowTestBytes)) - serverStdout, err := session.StdoutPipe() - if err != nil { - t.Errorf("StdoutPipe failed: %v", err) - return - } - n, err := copyNRandomly("stdout", echoedBuf, serverStdout, windowTestBytes) - if err != nil && err != io.EOF { - t.Errorf("Read only %d bytes from server, expected %d: %v", n, windowTestBytes, err) - } - result <- echoedBuf.Bytes() - }() - - serverStdin, err := session.StdinPipe() - if err != nil { - t.Fatalf("StdinPipe failed: %v", err) - } - written, err := copyNRandomly("stdin", serverStdin, origBuf, windowTestBytes) - if err != nil { - t.Fatalf("failed to copy origBuf to serverStdin: %v", err) - } - if written != windowTestBytes { - t.Fatalf("Wrote only %d of %d bytes to server", written, windowTestBytes) - } - - echoedBytes := <-result - - if !bytes.Equal(origBytes, echoedBytes) { - t.Fatalf("Echoed buffer differed from original, orig %d, echoed %d", len(origBytes), len(echoedBytes)) - } -} - -// Verify the client can handle a keepalive packet from the server. -func TestClientHandlesKeepalives(t *testing.T) { - conn := dial(channelKeepaliveSender, t) - defer conn.Close() - session, err := conn.NewSession() - if err != nil { - t.Fatal(err) - } - defer session.Close() - if err := session.Shell(); err != nil { - t.Fatalf("Unable to execute command: %v", err) - } - err = session.Wait() - if err != nil { - t.Fatalf("expected nil but got: %v", err) - } -} - -type exitStatusMsg struct { - Status uint32 -} - -type exitSignalMsg struct { - Signal string - CoreDumped bool - Errmsg string - Lang string -} - -func handleTerminalRequests(in <-chan *Request) { - for req := range in { - ok := false - switch req.Type { - case "shell": - ok = true - if len(req.Payload) > 0 { - // We don't accept any commands, only the default shell. - ok = false - } - case "env": - ok = true - } - req.Reply(ok, nil) - } -} - -func newServerShell(ch Channel, in <-chan *Request, prompt string) *terminal.Terminal { - term := terminal.NewTerminal(ch, prompt) - go handleTerminalRequests(in) - return term -} - -func exitStatusZeroHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - // this string is returned to stdout - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendStatus(0, ch, t) -} - -func exitStatusNonZeroHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendStatus(15, ch, t) -} - -func exitSignalAndStatusHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendStatus(15, ch, t) - sendSignal("TERM", ch, t) -} - -func exitSignalHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendSignal("TERM", ch, t) -} - -func exitSignalUnknownHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - sendSignal("SYS", ch, t) -} - -func exitWithoutSignalOrStatus(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) -} - -func shellHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - // this string is returned to stdout - shell := newServerShell(ch, in, "golang") - readLine(shell, t) - sendStatus(0, ch, t) -} - -// Ignores the command, writes fixed strings to stderr and stdout. -// Strings are "this-is-stdout." and "this-is-stderr.". -func fixedOutputHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - _, err := ch.Read(nil) - - req, ok := <-in - if !ok { - t.Fatalf("error: expected channel request, got: %#v", err) - return - } - - // ignore request, always send some text - req.Reply(true, nil) - - _, err = io.WriteString(ch, "this-is-stdout.") - if err != nil { - t.Fatalf("error writing on server: %v", err) - } - _, err = io.WriteString(ch.Stderr(), "this-is-stderr.") - if err != nil { - t.Fatalf("error writing on server: %v", err) - } - sendStatus(0, ch, t) -} - -func readLine(shell *terminal.Terminal, t *testing.T) { - if _, err := shell.ReadLine(); err != nil && err != io.EOF { - t.Errorf("unable to read line: %v", err) - } -} - -func sendStatus(status uint32, ch Channel, t *testing.T) { - msg := exitStatusMsg{ - Status: status, - } - if _, err := ch.SendRequest("exit-status", false, Marshal(&msg)); err != nil { - t.Errorf("unable to send status: %v", err) - } -} - -func sendSignal(signal string, ch Channel, t *testing.T) { - sig := exitSignalMsg{ - Signal: signal, - CoreDumped: false, - Errmsg: "Process terminated", - Lang: "en-GB-oed", - } - if _, err := ch.SendRequest("exit-signal", false, Marshal(&sig)); err != nil { - t.Errorf("unable to send signal: %v", err) - } -} - -func discardHandler(ch Channel, t *testing.T) { - defer ch.Close() - io.Copy(ioutil.Discard, ch) -} - -func echoHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - if n, err := copyNRandomly("echohandler", ch, ch, windowTestBytes); err != nil { - t.Errorf("short write, wrote %d, expected %d: %v ", n, windowTestBytes, err) - } -} - -// copyNRandomly copies n bytes from src to dst. It uses a variable, and random, -// buffer size to exercise more code paths. -func copyNRandomly(title string, dst io.Writer, src io.Reader, n int) (int, error) { - var ( - buf = make([]byte, 32*1024) - written int - remaining = n - ) - for remaining > 0 { - l := rand.Intn(1 << 15) - if remaining < l { - l = remaining - } - nr, er := src.Read(buf[:l]) - nw, ew := dst.Write(buf[:nr]) - remaining -= nw - written += nw - if ew != nil { - return written, ew - } - if nr != nw { - return written, io.ErrShortWrite - } - if er != nil && er != io.EOF { - return written, er - } - } - return written, nil -} - -func channelKeepaliveSender(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - shell := newServerShell(ch, in, "> ") - readLine(shell, t) - if _, err := ch.SendRequest("keepalive@openssh.com", true, nil); err != nil { - t.Errorf("unable to send channel keepalive request: %v", err) - } - sendStatus(0, ch, t) -} - -func TestClientWriteEOF(t *testing.T) { - conn := dial(simpleEchoHandler, t) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatal(err) - } - defer session.Close() - stdin, err := session.StdinPipe() - if err != nil { - t.Fatalf("StdinPipe failed: %v", err) - } - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("StdoutPipe failed: %v", err) - } - - data := []byte(`0000`) - _, err = stdin.Write(data) - if err != nil { - t.Fatalf("Write failed: %v", err) - } - stdin.Close() - - res, err := ioutil.ReadAll(stdout) - if err != nil { - t.Fatalf("Read failed: %v", err) - } - - if !bytes.Equal(data, res) { - t.Fatalf("Read differed from write, wrote: %v, read: %v", data, res) - } -} - -func simpleEchoHandler(ch Channel, in <-chan *Request, t *testing.T) { - defer ch.Close() - data, err := ioutil.ReadAll(ch) - if err != nil { - t.Errorf("handler read error: %v", err) - } - _, err = ch.Write(data) - if err != nil { - t.Errorf("handler write error: %v", err) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/tcpip.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/tcpip.go deleted file mode 100644 index 4ecad0b3ff..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/tcpip.go +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "errors" - "fmt" - "io" - "math/rand" - "net" - "strconv" - "strings" - "sync" - "time" -) - -// Listen requests the remote peer open a listening socket on -// addr. Incoming connections will be available by calling Accept on -// the returned net.Listener. The listener must be serviced, or the -// SSH connection may hang. -func (c *Client) Listen(n, addr string) (net.Listener, error) { - laddr, err := net.ResolveTCPAddr(n, addr) - if err != nil { - return nil, err - } - return c.ListenTCP(laddr) -} - -// Automatic port allocation is broken with OpenSSH before 6.0. See -// also https://bugzilla.mindrot.org/show_bug.cgi?id=2017. In -// particular, OpenSSH 5.9 sends a channelOpenMsg with port number 0, -// rather than the actual port number. This means you can never open -// two different listeners with auto allocated ports. We work around -// this by trying explicit ports until we succeed. - -const openSSHPrefix = "OpenSSH_" - -var portRandomizer = rand.New(rand.NewSource(time.Now().UnixNano())) - -// isBrokenOpenSSHVersion returns true if the given version string -// specifies a version of OpenSSH that is known to have a bug in port -// forwarding. -func isBrokenOpenSSHVersion(versionStr string) bool { - i := strings.Index(versionStr, openSSHPrefix) - if i < 0 { - return false - } - i += len(openSSHPrefix) - j := i - for ; j < len(versionStr); j++ { - if versionStr[j] < '0' || versionStr[j] > '9' { - break - } - } - version, _ := strconv.Atoi(versionStr[i:j]) - return version < 6 -} - -// autoPortListenWorkaround simulates automatic port allocation by -// trying random ports repeatedly. -func (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) { - var sshListener net.Listener - var err error - const tries = 10 - for i := 0; i < tries; i++ { - addr := *laddr - addr.Port = 1024 + portRandomizer.Intn(60000) - sshListener, err = c.ListenTCP(&addr) - if err == nil { - laddr.Port = addr.Port - return sshListener, err - } - } - return nil, fmt.Errorf("ssh: listen on random port failed after %d tries: %v", tries, err) -} - -// RFC 4254 7.1 -type channelForwardMsg struct { - addr string - rport uint32 -} - -// ListenTCP requests the remote peer open a listening socket -// on laddr. Incoming connections will be available by calling -// Accept on the returned net.Listener. -func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) { - if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) { - return c.autoPortListenWorkaround(laddr) - } - - m := channelForwardMsg{ - laddr.IP.String(), - uint32(laddr.Port), - } - // send message - ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m)) - if err != nil { - return nil, err - } - if !ok { - return nil, errors.New("ssh: tcpip-forward request denied by peer") - } - - // If the original port was 0, then the remote side will - // supply a real port number in the response. - if laddr.Port == 0 { - var p struct { - Port uint32 - } - if err := Unmarshal(resp, &p); err != nil { - return nil, err - } - laddr.Port = int(p.Port) - } - - // Register this forward, using the port number we obtained. - ch := c.forwards.add(*laddr) - - return &tcpListener{laddr, c, ch}, nil -} - -// forwardList stores a mapping between remote -// forward requests and the tcpListeners. -type forwardList struct { - sync.Mutex - entries []forwardEntry -} - -// forwardEntry represents an established mapping of a laddr on a -// remote ssh server to a channel connected to a tcpListener. -type forwardEntry struct { - laddr net.TCPAddr - c chan forward -} - -// forward represents an incoming forwarded tcpip connection. The -// arguments to add/remove/lookup should be address as specified in -// the original forward-request. -type forward struct { - newCh NewChannel // the ssh client channel underlying this forward - raddr *net.TCPAddr // the raddr of the incoming connection -} - -func (l *forwardList) add(addr net.TCPAddr) chan forward { - l.Lock() - defer l.Unlock() - f := forwardEntry{ - addr, - make(chan forward, 1), - } - l.entries = append(l.entries, f) - return f.c -} - -// See RFC 4254, section 7.2 -type forwardedTCPPayload struct { - Addr string - Port uint32 - OriginAddr string - OriginPort uint32 -} - -// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr. -func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) { - if port == 0 || port > 65535 { - return nil, fmt.Errorf("ssh: port number out of range: %d", port) - } - ip := net.ParseIP(string(addr)) - if ip == nil { - return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr) - } - return &net.TCPAddr{IP: ip, Port: int(port)}, nil -} - -func (l *forwardList) handleChannels(in <-chan NewChannel) { - for ch := range in { - var payload forwardedTCPPayload - if err := Unmarshal(ch.ExtraData(), &payload); err != nil { - ch.Reject(ConnectionFailed, "could not parse forwarded-tcpip payload: "+err.Error()) - continue - } - - // RFC 4254 section 7.2 specifies that incoming - // addresses should list the address, in string - // format. It is implied that this should be an IP - // address, as it would be impossible to connect to it - // otherwise. - laddr, err := parseTCPAddr(payload.Addr, payload.Port) - if err != nil { - ch.Reject(ConnectionFailed, err.Error()) - continue - } - raddr, err := parseTCPAddr(payload.OriginAddr, payload.OriginPort) - if err != nil { - ch.Reject(ConnectionFailed, err.Error()) - continue - } - - if ok := l.forward(*laddr, *raddr, ch); !ok { - // Section 7.2, implementations MUST reject spurious incoming - // connections. - ch.Reject(Prohibited, "no forward for address") - continue - } - } -} - -// remove removes the forward entry, and the channel feeding its -// listener. -func (l *forwardList) remove(addr net.TCPAddr) { - l.Lock() - defer l.Unlock() - for i, f := range l.entries { - if addr.IP.Equal(f.laddr.IP) && addr.Port == f.laddr.Port { - l.entries = append(l.entries[:i], l.entries[i+1:]...) - close(f.c) - return - } - } -} - -// closeAll closes and clears all forwards. -func (l *forwardList) closeAll() { - l.Lock() - defer l.Unlock() - for _, f := range l.entries { - close(f.c) - } - l.entries = nil -} - -func (l *forwardList) forward(laddr, raddr net.TCPAddr, ch NewChannel) bool { - l.Lock() - defer l.Unlock() - for _, f := range l.entries { - if laddr.IP.Equal(f.laddr.IP) && laddr.Port == f.laddr.Port { - f.c <- forward{ch, &raddr} - return true - } - } - return false -} - -type tcpListener struct { - laddr *net.TCPAddr - - conn *Client - in <-chan forward -} - -// Accept waits for and returns the next connection to the listener. -func (l *tcpListener) Accept() (net.Conn, error) { - s, ok := <-l.in - if !ok { - return nil, io.EOF - } - ch, incoming, err := s.newCh.Accept() - if err != nil { - return nil, err - } - go DiscardRequests(incoming) - - return &tcpChanConn{ - Channel: ch, - laddr: l.laddr, - raddr: s.raddr, - }, nil -} - -// Close closes the listener. -func (l *tcpListener) Close() error { - m := channelForwardMsg{ - l.laddr.IP.String(), - uint32(l.laddr.Port), - } - - // this also closes the listener. - l.conn.forwards.remove(*l.laddr) - ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m)) - if err == nil && !ok { - err = errors.New("ssh: cancel-tcpip-forward failed") - } - return err -} - -// Addr returns the listener's network address. -func (l *tcpListener) Addr() net.Addr { - return l.laddr -} - -// Dial initiates a connection to the addr from the remote host. -// The resulting connection has a zero LocalAddr() and RemoteAddr(). -func (c *Client) Dial(n, addr string) (net.Conn, error) { - // Parse the address into host and numeric port. - host, portString, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - port, err := strconv.ParseUint(portString, 10, 16) - if err != nil { - return nil, err - } - // Use a zero address for local and remote address. - zeroAddr := &net.TCPAddr{ - IP: net.IPv4zero, - Port: 0, - } - ch, err := c.dial(net.IPv4zero.String(), 0, host, int(port)) - if err != nil { - return nil, err - } - return &tcpChanConn{ - Channel: ch, - laddr: zeroAddr, - raddr: zeroAddr, - }, nil -} - -// DialTCP connects to the remote address raddr on the network net, -// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used -// as the local address for the connection. -func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) { - if laddr == nil { - laddr = &net.TCPAddr{ - IP: net.IPv4zero, - Port: 0, - } - } - ch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port) - if err != nil { - return nil, err - } - return &tcpChanConn{ - Channel: ch, - laddr: laddr, - raddr: raddr, - }, nil -} - -// RFC 4254 7.2 -type channelOpenDirectMsg struct { - raddr string - rport uint32 - laddr string - lport uint32 -} - -func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel, error) { - msg := channelOpenDirectMsg{ - raddr: raddr, - rport: uint32(rport), - laddr: laddr, - lport: uint32(lport), - } - ch, in, err := c.OpenChannel("direct-tcpip", Marshal(&msg)) - go DiscardRequests(in) - return ch, err -} - -type tcpChan struct { - Channel // the backing channel -} - -// tcpChanConn fulfills the net.Conn interface without -// the tcpChan having to hold laddr or raddr directly. -type tcpChanConn struct { - Channel - laddr, raddr net.Addr -} - -// LocalAddr returns the local network address. -func (t *tcpChanConn) LocalAddr() net.Addr { - return t.laddr -} - -// RemoteAddr returns the remote network address. -func (t *tcpChanConn) RemoteAddr() net.Addr { - return t.raddr -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. -func (t *tcpChanConn) SetDeadline(deadline time.Time) error { - if err := t.SetReadDeadline(deadline); err != nil { - return err - } - return t.SetWriteDeadline(deadline) -} - -// SetReadDeadline sets the read deadline. -// A zero value for t means Read will not time out. -// After the deadline, the error from Read will implement net.Error -// with Timeout() == true. -func (t *tcpChanConn) SetReadDeadline(deadline time.Time) error { - return errors.New("ssh: tcpChan: deadline not supported") -} - -// SetWriteDeadline exists to satisfy the net.Conn interface -// but is not implemented by this type. It always returns an error. -func (t *tcpChanConn) SetWriteDeadline(deadline time.Time) error { - return errors.New("ssh: tcpChan: deadline not supported") -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/tcpip_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/tcpip_test.go deleted file mode 100644 index f1265cb496..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/tcpip_test.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "testing" -) - -func TestAutoPortListenBroken(t *testing.T) { - broken := "SSH-2.0-OpenSSH_5.9hh11" - works := "SSH-2.0-OpenSSH_6.1" - if !isBrokenOpenSSHVersion(broken) { - t.Errorf("version %q not marked as broken", broken) - } - if isBrokenOpenSSHVersion(works) { - t.Errorf("version %q marked as broken", works) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal_test.go deleted file mode 100644 index 6579801204..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal_test.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package terminal - -import ( - "io" - "testing" -) - -type MockTerminal struct { - toSend []byte - bytesPerRead int - received []byte -} - -func (c *MockTerminal) Read(data []byte) (n int, err error) { - n = len(data) - if n == 0 { - return - } - if n > len(c.toSend) { - n = len(c.toSend) - } - if n == 0 { - return 0, io.EOF - } - if c.bytesPerRead > 0 && n > c.bytesPerRead { - n = c.bytesPerRead - } - copy(data, c.toSend[:n]) - c.toSend = c.toSend[n:] - return -} - -func (c *MockTerminal) Write(data []byte) (n int, err error) { - c.received = append(c.received, data...) - return len(data), nil -} - -func TestClose(t *testing.T) { - c := &MockTerminal{} - ss := NewTerminal(c, "> ") - line, err := ss.ReadLine() - if line != "" { - t.Errorf("Expected empty line but got: %s", line) - } - if err != io.EOF { - t.Errorf("Error should have been EOF but got: %s", err) - } -} - -var keyPressTests = []struct { - in string - line string - err error - throwAwayLines int -}{ - { - err: io.EOF, - }, - { - in: "\r", - line: "", - }, - { - in: "foo\r", - line: "foo", - }, - { - in: "a\x1b[Cb\r", // right - line: "ab", - }, - { - in: "a\x1b[Db\r", // left - line: "ba", - }, - { - in: "a\177b\r", // backspace - line: "b", - }, - { - in: "\x1b[A\r", // up - }, - { - in: "\x1b[B\r", // down - }, - { - in: "line\x1b[A\x1b[B\r", // up then down - line: "line", - }, - { - in: "line1\rline2\x1b[A\r", // recall previous line. - line: "line1", - throwAwayLines: 1, - }, - { - // recall two previous lines and append. - in: "line1\rline2\rline3\x1b[A\x1b[Axxx\r", - line: "line1xxx", - throwAwayLines: 2, - }, - { - // Ctrl-A to move to beginning of line followed by ^K to kill - // line. - in: "a b \001\013\r", - line: "", - }, - { - // Ctrl-A to move to beginning of line, Ctrl-E to move to end, - // finally ^K to kill nothing. - in: "a b \001\005\013\r", - line: "a b ", - }, - { - in: "\027\r", - line: "", - }, - { - in: "a\027\r", - line: "", - }, - { - in: "a \027\r", - line: "", - }, - { - in: "a b\027\r", - line: "a ", - }, - { - in: "a b \027\r", - line: "a ", - }, - { - in: "one two thr\x1b[D\027\r", - line: "one two r", - }, - { - in: "\013\r", - line: "", - }, - { - in: "a\013\r", - line: "a", - }, - { - in: "ab\x1b[D\013\r", - line: "a", - }, - { - in: "Ξεσκεπάζω\r", - line: "Ξεσκεπάζω", - }, - { - in: "£\r\x1b[A\177\r", // non-ASCII char, enter, up, backspace. - line: "", - throwAwayLines: 1, - }, - { - in: "£\r££\x1b[A\x1b[B\177\r", // non-ASCII char, enter, 2x non-ASCII, up, down, backspace, enter. - line: "£", - throwAwayLines: 1, - }, - { - // Ctrl-D at the end of the line should be ignored. - in: "a\004\r", - line: "a", - }, - { - // a, b, left, Ctrl-D should erase the b. - in: "ab\x1b[D\004\r", - line: "a", - }, - { - // a, b, c, d, left, left, ^U should erase to the beginning of - // the line. - in: "abcd\x1b[D\x1b[D\025\r", - line: "cd", - }, - { - // Bracketed paste mode: control sequences should be returned - // verbatim in paste mode. - in: "abc\x1b[200~de\177f\x1b[201~\177\r", - line: "abcde\177", - }, - { - // Enter in bracketed paste mode should still work. - in: "abc\x1b[200~d\refg\x1b[201~h\r", - line: "efgh", - throwAwayLines: 1, - }, - { - // Lines consisting entirely of pasted data should be indicated as such. - in: "\x1b[200~a\r", - line: "a", - err: ErrPasteIndicator, - }, -} - -func TestKeyPresses(t *testing.T) { - for i, test := range keyPressTests { - for j := 1; j < len(test.in); j++ { - c := &MockTerminal{ - toSend: []byte(test.in), - bytesPerRead: j, - } - ss := NewTerminal(c, "> ") - for k := 0; k < test.throwAwayLines; k++ { - _, err := ss.ReadLine() - if err != nil { - t.Errorf("Throwaway line %d from test %d resulted in error: %s", k, i, err) - } - } - line, err := ss.ReadLine() - if line != test.line { - t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line) - break - } - if err != test.err { - t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err) - break - } - } - } -} - -func TestPasswordNotSaved(t *testing.T) { - c := &MockTerminal{ - toSend: []byte("password\r\x1b[A\r"), - bytesPerRead: 1, - } - ss := NewTerminal(c, "> ") - pw, _ := ss.ReadPassword("> ") - if pw != "password" { - t.Fatalf("failed to read password, got %s", pw) - } - line, _ := ss.ReadLine() - if len(line) > 0 { - t.Fatalf("password was saved in history") - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go deleted file mode 100644 index 0763c9a978..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd - -// Package terminal provides support functions for dealing with terminals, as -// commonly found on UNIX systems. -// -// Putting a terminal into raw mode is the most common requirement: -// -// oldState, err := terminal.MakeRaw(0) -// if err != nil { -// panic(err) -// } -// defer terminal.Restore(0, oldState) -package terminal - -import ( - "io" - "syscall" - "unsafe" -) - -// State contains the state of a terminal. -type State struct { - termios syscall.Termios -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd int) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd int) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF - newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { - return nil, err - } - - return &oldState, nil -} - -// GetState returns the current state of a terminal which may be useful to -// restore the terminal after a signal. -func GetState(fd int) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { - return nil, err - } - - return &oldState, nil -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) - return err -} - -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { - var dimensions [4]uint16 - - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { - return -1, -1, err - } - return int(dimensions[1]), int(dimensions[0]), nil -} - -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd int) ([]byte, error) { - var oldState syscall.Termios - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { - return nil, err - } - - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { - return nil, err - } - - defer func() { - syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) - }() - - var buf [16]byte - var ret []byte - for { - n, err := syscall.Read(fd, buf[:]) - if err != nil { - return nil, err - } - if n == 0 { - if len(ret) == 0 { - return nil, io.EOF - } - break - } - if buf[n-1] == '\n' { - n-- - } - ret = append(ret, buf[:n]...) - if n < len(buf) { - break - } - } - - return ret, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/agent_unix_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/agent_unix_test.go deleted file mode 100644 index 502e24febb..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/agent_unix_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux netbsd openbsd - -package test - -import ( - "bytes" - "testing" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/agent" -) - -func TestAgentForward(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - keyring := agent.NewKeyring() - keyring.Add(testPrivateKeys["dsa"], nil, "") - pub := testPublicKeys["dsa"] - - sess, err := conn.NewSession() - if err != nil { - t.Fatalf("NewSession: %v", err) - } - if err := agent.RequestAgentForwarding(sess); err != nil { - t.Fatalf("RequestAgentForwarding: %v", err) - } - - if err := agent.ForwardToAgent(conn, keyring); err != nil { - t.Fatalf("SetupForwardKeyring: %v", err) - } - out, err := sess.CombinedOutput("ssh-add -L") - if err != nil { - t.Fatalf("running ssh-add: %v, out %s", err, out) - } - key, _, _, _, err := ssh.ParseAuthorizedKey(out) - if err != nil { - t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) - } - - if !bytes.Equal(key.Marshal(), pub.Marshal()) { - t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/cert_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/cert_test.go deleted file mode 100644 index 364790f17d..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/cert_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux netbsd openbsd - -package test - -import ( - "crypto/rand" - "testing" - - "golang.org/x/crypto/ssh" -) - -func TestCertLogin(t *testing.T) { - s := newServer(t) - defer s.Shutdown() - - // Use a key different from the default. - clientKey := testSigners["dsa"] - caAuthKey := testSigners["ecdsa"] - cert := &ssh.Certificate{ - Key: clientKey.PublicKey(), - ValidPrincipals: []string{username()}, - CertType: ssh.UserCert, - ValidBefore: ssh.CertTimeInfinity, - } - if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { - t.Fatalf("SetSignature: %v", err) - } - - certSigner, err := ssh.NewCertSigner(cert, clientKey) - if err != nil { - t.Fatalf("NewCertSigner: %v", err) - } - - conf := &ssh.ClientConfig{ - User: username(), - } - conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) - client, err := s.TryDial(conf) - if err != nil { - t.Fatalf("TryDial: %v", err) - } - client.Close() -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/doc.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/doc.go deleted file mode 100644 index 787b8fa207..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This package contains integration tests for the -// code.google.com/p/go.crypto/ssh package. -package test diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/forward_unix_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/forward_unix_test.go deleted file mode 100644 index 877a88cde3..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/forward_unix_test.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux netbsd openbsd - -package test - -import ( - "bytes" - "io" - "io/ioutil" - "math/rand" - "net" - "testing" - "time" -) - -func TestPortForward(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - sshListener, err := conn.Listen("tcp", "localhost:0") - if err != nil { - t.Fatal(err) - } - - go func() { - sshConn, err := sshListener.Accept() - if err != nil { - t.Fatalf("listen.Accept failed: %v", err) - } - - _, err = io.Copy(sshConn, sshConn) - if err != nil && err != io.EOF { - t.Fatalf("ssh client copy: %v", err) - } - sshConn.Close() - }() - - forwardedAddr := sshListener.Addr().String() - tcpConn, err := net.Dial("tcp", forwardedAddr) - if err != nil { - t.Fatalf("TCP dial failed: %v", err) - } - - readChan := make(chan []byte) - go func() { - data, _ := ioutil.ReadAll(tcpConn) - readChan <- data - }() - - // Invent some data. - data := make([]byte, 100*1000) - for i := range data { - data[i] = byte(i % 255) - } - - var sent []byte - for len(sent) < 1000*1000 { - // Send random sized chunks - m := rand.Intn(len(data)) - n, err := tcpConn.Write(data[:m]) - if err != nil { - break - } - sent = append(sent, data[:n]...) - } - if err := tcpConn.(*net.TCPConn).CloseWrite(); err != nil { - t.Errorf("tcpConn.CloseWrite: %v", err) - } - - read := <-readChan - - if len(sent) != len(read) { - t.Fatalf("got %d bytes, want %d", len(read), len(sent)) - } - if bytes.Compare(sent, read) != 0 { - t.Fatalf("read back data does not match") - } - - if err := sshListener.Close(); err != nil { - t.Fatalf("sshListener.Close: %v", err) - } - - // Check that the forward disappeared. - tcpConn, err = net.Dial("tcp", forwardedAddr) - if err == nil { - tcpConn.Close() - t.Errorf("still listening to %s after closing", forwardedAddr) - } -} - -func TestAcceptClose(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - - sshListener, err := conn.Listen("tcp", "localhost:0") - if err != nil { - t.Fatal(err) - } - - quit := make(chan error, 1) - go func() { - for { - c, err := sshListener.Accept() - if err != nil { - quit <- err - break - } - c.Close() - } - }() - sshListener.Close() - - select { - case <-time.After(1 * time.Second): - t.Errorf("timeout: listener did not close.") - case err := <-quit: - t.Logf("quit as expected (error %v)", err) - } -} - -// Check that listeners exit if the underlying client transport dies. -func TestPortForwardConnectionClose(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - - sshListener, err := conn.Listen("tcp", "localhost:0") - if err != nil { - t.Fatal(err) - } - - quit := make(chan error, 1) - go func() { - for { - c, err := sshListener.Accept() - if err != nil { - quit <- err - break - } - c.Close() - } - }() - - // It would be even nicer if we closed the server side, but it - // is more involved as the fd for that side is dup()ed. - server.clientConn.Close() - - select { - case <-time.After(1 * time.Second): - t.Errorf("timeout: listener did not close.") - case err := <-quit: - t.Logf("quit as expected (error %v)", err) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/session_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/session_test.go deleted file mode 100644 index 0b7892ba7a..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/session_test.go +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !windows - -package test - -// Session functional tests. - -import ( - "bytes" - "errors" - "golang.org/x/crypto/ssh" - "io" - "strings" - "testing" -) - -func TestRunCommandSuccess(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - err = session.Run("true") - if err != nil { - t.Fatalf("session failed: %v", err) - } -} - -func TestHostKeyCheck(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - - conf := clientConfig() - hostDB := hostKeyDB() - conf.HostKeyCallback = hostDB.Check - - // change the keys. - hostDB.keys[ssh.KeyAlgoRSA][25]++ - hostDB.keys[ssh.KeyAlgoDSA][25]++ - hostDB.keys[ssh.KeyAlgoECDSA256][25]++ - - conn, err := server.TryDial(conf) - if err == nil { - conn.Close() - t.Fatalf("dial should have failed.") - } else if !strings.Contains(err.Error(), "host key mismatch") { - t.Fatalf("'host key mismatch' not found in %v", err) - } -} - -func TestRunCommandStdin(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - r, w := io.Pipe() - defer r.Close() - defer w.Close() - session.Stdin = r - - err = session.Run("true") - if err != nil { - t.Fatalf("session failed: %v", err) - } -} - -func TestRunCommandStdinError(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - r, w := io.Pipe() - defer r.Close() - session.Stdin = r - pipeErr := errors.New("closing write end of pipe") - w.CloseWithError(pipeErr) - - err = session.Run("true") - if err != pipeErr { - t.Fatalf("expected %v, found %v", pipeErr, err) - } -} - -func TestRunCommandFailed(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - err = session.Run(`bash -c "kill -9 $$"`) - if err == nil { - t.Fatalf("session succeeded: %v", err) - } -} - -func TestRunCommandWeClosed(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - err = session.Shell() - if err != nil { - t.Fatalf("shell failed: %v", err) - } - err = session.Close() - if err != nil { - t.Fatalf("shell failed: %v", err) - } -} - -func TestFuncLargeRead(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("unable to create new session: %s", err) - } - - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("unable to acquire stdout pipe: %s", err) - } - - err = session.Start("dd if=/dev/urandom bs=2048 count=1024") - if err != nil { - t.Fatalf("unable to execute remote command: %s", err) - } - - buf := new(bytes.Buffer) - n, err := io.Copy(buf, stdout) - if err != nil { - t.Fatalf("error reading from remote stdout: %s", err) - } - - if n != 2048*1024 { - t.Fatalf("Expected %d bytes but read only %d from remote command", 2048, n) - } -} - -func TestKeyChange(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - hostDB := hostKeyDB() - conf.HostKeyCallback = hostDB.Check - conf.RekeyThreshold = 1024 - conn := server.Dial(conf) - defer conn.Close() - - for i := 0; i < 4; i++ { - session, err := conn.NewSession() - if err != nil { - t.Fatalf("unable to create new session: %s", err) - } - - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("unable to acquire stdout pipe: %s", err) - } - - err = session.Start("dd if=/dev/urandom bs=1024 count=1") - if err != nil { - t.Fatalf("unable to execute remote command: %s", err) - } - buf := new(bytes.Buffer) - n, err := io.Copy(buf, stdout) - if err != nil { - t.Fatalf("error reading from remote stdout: %s", err) - } - - want := int64(1024) - if n != want { - t.Fatalf("Expected %d bytes but read only %d from remote command", want, n) - } - } - - if changes := hostDB.checkCount; changes < 4 { - t.Errorf("got %d key changes, want 4", changes) - } -} - -func TestInvalidTerminalMode(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - if err = session.RequestPty("vt100", 80, 40, ssh.TerminalModes{255: 1984}); err == nil { - t.Fatalf("req-pty failed: successful request with invalid mode") - } -} - -func TestValidTerminalMode(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - conn := server.Dial(clientConfig()) - defer conn.Close() - - session, err := conn.NewSession() - if err != nil { - t.Fatalf("session failed: %v", err) - } - defer session.Close() - - stdout, err := session.StdoutPipe() - if err != nil { - t.Fatalf("unable to acquire stdout pipe: %s", err) - } - - stdin, err := session.StdinPipe() - if err != nil { - t.Fatalf("unable to acquire stdin pipe: %s", err) - } - - tm := ssh.TerminalModes{ssh.ECHO: 0} - if err = session.RequestPty("xterm", 80, 40, tm); err != nil { - t.Fatalf("req-pty failed: %s", err) - } - - err = session.Shell() - if err != nil { - t.Fatalf("session failed: %s", err) - } - - stdin.Write([]byte("stty -a && exit\n")) - - var buf bytes.Buffer - if _, err := io.Copy(&buf, stdout); err != nil { - t.Fatalf("reading failed: %s", err) - } - - if sttyOutput := buf.String(); !strings.Contains(sttyOutput, "-echo ") { - t.Fatalf("terminal mode failure: expected -echo in stty output, got %s", sttyOutput) - } -} - -func TestCiphers(t *testing.T) { - var config ssh.Config - config.SetDefaults() - cipherOrder := config.Ciphers - - for _, ciph := range cipherOrder { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - conf.Ciphers = []string{ciph} - // Don't fail if sshd doesnt have the cipher. - conf.Ciphers = append(conf.Ciphers, cipherOrder...) - conn, err := server.TryDial(conf) - if err == nil { - conn.Close() - } else { - t.Fatalf("failed for cipher %q", ciph) - } - } -} - -func TestMACs(t *testing.T) { - var config ssh.Config - config.SetDefaults() - macOrder := config.MACs - - for _, mac := range macOrder { - server := newServer(t) - defer server.Shutdown() - conf := clientConfig() - conf.MACs = []string{mac} - // Don't fail if sshd doesnt have the MAC. - conf.MACs = append(conf.MACs, macOrder...) - if conn, err := server.TryDial(conf); err == nil { - conn.Close() - } else { - t.Fatalf("failed for MAC %q", mac) - } - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/tcpip_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/tcpip_test.go deleted file mode 100644 index a2eb9358d0..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/tcpip_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !windows - -package test - -// direct-tcpip functional tests - -import ( - "io" - "net" - "testing" -) - -func TestDial(t *testing.T) { - server := newServer(t) - defer server.Shutdown() - sshConn := server.Dial(clientConfig()) - defer sshConn.Close() - - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatalf("Listen: %v", err) - } - defer l.Close() - - go func() { - for { - c, err := l.Accept() - if err != nil { - break - } - - io.WriteString(c, c.RemoteAddr().String()) - c.Close() - } - }() - - conn, err := sshConn.Dial("tcp", l.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer conn.Close() -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/test_unix_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/test_unix_test.go deleted file mode 100644 index f1fc50b2e4..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/test_unix_test.go +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux netbsd openbsd plan9 - -package test - -// functional test harness for unix. - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "net" - "os" - "os/exec" - "os/user" - "path/filepath" - "testing" - "text/template" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/testdata" -) - -const sshd_config = ` -Protocol 2 -HostKey {{.Dir}}/id_rsa -HostKey {{.Dir}}/id_dsa -HostKey {{.Dir}}/id_ecdsa -Pidfile {{.Dir}}/sshd.pid -#UsePrivilegeSeparation no -KeyRegenerationInterval 3600 -ServerKeyBits 768 -SyslogFacility AUTH -LogLevel DEBUG2 -LoginGraceTime 120 -PermitRootLogin no -StrictModes no -RSAAuthentication yes -PubkeyAuthentication yes -AuthorizedKeysFile {{.Dir}}/id_user.pub -TrustedUserCAKeys {{.Dir}}/id_ecdsa.pub -IgnoreRhosts yes -RhostsRSAAuthentication no -HostbasedAuthentication no -` - -var configTmpl = template.Must(template.New("").Parse(sshd_config)) - -type server struct { - t *testing.T - cleanup func() // executed during Shutdown - configfile string - cmd *exec.Cmd - output bytes.Buffer // holds stderr from sshd process - - // Client half of the network connection. - clientConn net.Conn -} - -func username() string { - var username string - if user, err := user.Current(); err == nil { - username = user.Username - } else { - // user.Current() currently requires cgo. If an error is - // returned attempt to get the username from the environment. - log.Printf("user.Current: %v; falling back on $USER", err) - username = os.Getenv("USER") - } - if username == "" { - panic("Unable to get username") - } - return username -} - -type storedHostKey struct { - // keys map from an algorithm string to binary key data. - keys map[string][]byte - - // checkCount counts the Check calls. Used for testing - // rekeying. - checkCount int -} - -func (k *storedHostKey) Add(key ssh.PublicKey) { - if k.keys == nil { - k.keys = map[string][]byte{} - } - k.keys[key.Type()] = key.Marshal() -} - -func (k *storedHostKey) Check(addr string, remote net.Addr, key ssh.PublicKey) error { - k.checkCount++ - algo := key.Type() - - if k.keys == nil || bytes.Compare(key.Marshal(), k.keys[algo]) != 0 { - return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo]) - } - return nil -} - -func hostKeyDB() *storedHostKey { - keyChecker := &storedHostKey{} - keyChecker.Add(testPublicKeys["ecdsa"]) - keyChecker.Add(testPublicKeys["rsa"]) - keyChecker.Add(testPublicKeys["dsa"]) - return keyChecker -} - -func clientConfig() *ssh.ClientConfig { - config := &ssh.ClientConfig{ - User: username(), - Auth: []ssh.AuthMethod{ - ssh.PublicKeys(testSigners["user"]), - }, - HostKeyCallback: hostKeyDB().Check, - } - return config -} - -// unixConnection creates two halves of a connected net.UnixConn. It -// is used for connecting the Go SSH client with sshd without opening -// ports. -func unixConnection() (*net.UnixConn, *net.UnixConn, error) { - dir, err := ioutil.TempDir("", "unixConnection") - if err != nil { - return nil, nil, err - } - defer os.Remove(dir) - - addr := filepath.Join(dir, "ssh") - listener, err := net.Listen("unix", addr) - if err != nil { - return nil, nil, err - } - defer listener.Close() - c1, err := net.Dial("unix", addr) - if err != nil { - return nil, nil, err - } - - c2, err := listener.Accept() - if err != nil { - c1.Close() - return nil, nil, err - } - - return c1.(*net.UnixConn), c2.(*net.UnixConn), nil -} - -func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) { - sshd, err := exec.LookPath("sshd") - if err != nil { - s.t.Skipf("skipping test: %v", err) - } - - c1, c2, err := unixConnection() - if err != nil { - s.t.Fatalf("unixConnection: %v", err) - } - - s.cmd = exec.Command(sshd, "-f", s.configfile, "-i", "-e") - f, err := c2.File() - if err != nil { - s.t.Fatalf("UnixConn.File: %v", err) - } - defer f.Close() - s.cmd.Stdin = f - s.cmd.Stdout = f - s.cmd.Stderr = &s.output - if err := s.cmd.Start(); err != nil { - s.t.Fail() - s.Shutdown() - s.t.Fatalf("s.cmd.Start: %v", err) - } - s.clientConn = c1 - conn, chans, reqs, err := ssh.NewClientConn(c1, "", config) - if err != nil { - return nil, err - } - return ssh.NewClient(conn, chans, reqs), nil -} - -func (s *server) Dial(config *ssh.ClientConfig) *ssh.Client { - conn, err := s.TryDial(config) - if err != nil { - s.t.Fail() - s.Shutdown() - s.t.Fatalf("ssh.Client: %v", err) - } - return conn -} - -func (s *server) Shutdown() { - if s.cmd != nil && s.cmd.Process != nil { - // Don't check for errors; if it fails it's most - // likely "os: process already finished", and we don't - // care about that. Use os.Interrupt, so child - // processes are killed too. - s.cmd.Process.Signal(os.Interrupt) - s.cmd.Wait() - } - if s.t.Failed() { - // log any output from sshd process - s.t.Logf("sshd: %s", s.output.String()) - } - s.cleanup() -} - -func writeFile(path string, contents []byte) { - f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600) - if err != nil { - panic(err) - } - defer f.Close() - if _, err := f.Write(contents); err != nil { - panic(err) - } -} - -// newServer returns a new mock ssh server. -func newServer(t *testing.T) *server { - if testing.Short() { - t.Skip("skipping test due to -short") - } - dir, err := ioutil.TempDir("", "sshtest") - if err != nil { - t.Fatal(err) - } - f, err := os.Create(filepath.Join(dir, "sshd_config")) - if err != nil { - t.Fatal(err) - } - err = configTmpl.Execute(f, map[string]string{ - "Dir": dir, - }) - if err != nil { - t.Fatal(err) - } - f.Close() - - for k, v := range testdata.PEMBytes { - filename := "id_" + k - writeFile(filepath.Join(dir, filename), v) - writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k])) - } - - return &server{ - t: t, - configfile: f.Name(), - cleanup: func() { - if err := os.RemoveAll(dir); err != nil { - t.Error(err) - } - }, - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/testdata_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/testdata_test.go deleted file mode 100644 index ae48c7516c..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/testdata_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: -// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three -// instances. - -package test - -import ( - "crypto/rand" - "fmt" - - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/testdata" -) - -var ( - testPrivateKeys map[string]interface{} - testSigners map[string]ssh.Signer - testPublicKeys map[string]ssh.PublicKey -) - -func init() { - var err error - - n := len(testdata.PEMBytes) - testPrivateKeys = make(map[string]interface{}, n) - testSigners = make(map[string]ssh.Signer, n) - testPublicKeys = make(map[string]ssh.PublicKey, n) - for t, k := range testdata.PEMBytes { - testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) - if err != nil { - panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) - } - testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) - if err != nil { - panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) - } - testPublicKeys[t] = testSigners[t].PublicKey() - } - - // Create a cert and sign it for use in tests. - testCert := &ssh.Certificate{ - Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage - ValidAfter: 0, // unix epoch - ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. - Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - Key: testPublicKeys["ecdsa"], - SignatureKey: testPublicKeys["rsa"], - Permissions: ssh.Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - testCert.SignCert(rand.Reader, testSigners["rsa"]) - testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] - testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) - if err != nil { - panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go deleted file mode 100644 index 430248698b..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This package contains test data shared between the various subpackages of -// the code.google.com/p/go.crypto/ssh package. Under no circumstance should -// this data be used for production code. -package testdata diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go deleted file mode 100644 index 5ff1c0e035..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package testdata - -var PEMBytes = map[string][]byte{ - "dsa": []byte(`-----BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQD6PDSEyXiI9jfNs97WuM46MSDCYlOqWw80ajN16AohtBncs1YB -lHk//dQOvCYOsYaE+gNix2jtoRjwXhDsc25/IqQbU1ahb7mB8/rsaILRGIbA5WH3 -EgFtJmXFovDz3if6F6TzvhFpHgJRmLYVR8cqsezL3hEZOvvs2iH7MorkxwIVAJHD -nD82+lxh2fb4PMsIiaXudAsBAoGAQRf7Q/iaPRn43ZquUhd6WwvirqUj+tkIu6eV -2nZWYmXLlqFQKEy4Tejl7Wkyzr2OSYvbXLzo7TNxLKoWor6ips0phYPPMyXld14r -juhT24CrhOzuLMhDduMDi032wDIZG4Y+K7ElU8Oufn8Sj5Wge8r6ANmmVgmFfynr -FhdYCngCgYEA3ucGJ93/Mx4q4eKRDxcWD3QzWyqpbRVRRV1Vmih9Ha/qC994nJFz -DQIdjxDIT2Rk2AGzMqFEB68Zc3O+Wcsmz5eWWzEwFxaTwOGWTyDqsDRLm3fD+QYj -nOwuxb0Kce+gWI8voWcqC9cyRm09jGzu2Ab3Bhtpg8JJ8L7gS3MRZK4CFEx4UAfY -Fmsr0W6fHB9nhS4/UXM8 ------END DSA PRIVATE KEY----- -`), - "ecdsa": []byte(`-----BEGIN EC PRIVATE KEY----- -MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 -AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ -6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== ------END EC PRIVATE KEY----- -`), - "rsa": []byte(`-----BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld -r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ -tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC -nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW -2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB -y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr -rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg== ------END RSA PRIVATE KEY----- -`), - "user": []byte(`-----BEGIN EC PRIVATE KEY----- -MHcCAQEEILYCAeq8f7V4vSSypRw7pxy8yz3V5W4qg8kSC3zJhqpQoAoGCCqGSM49 -AwEHoUQDQgAEYcO2xNKiRUYOLEHM7VYAp57HNyKbOdYtHD83Z4hzNPVC4tM5mdGD -PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w== ------END EC PRIVATE KEY----- -`), -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata_test.go deleted file mode 100644 index f2828c1b5f..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: -// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three -// instances. - -package ssh - -import ( - "crypto/rand" - "fmt" - - "golang.org/x/crypto/ssh/testdata" -) - -var ( - testPrivateKeys map[string]interface{} - testSigners map[string]Signer - testPublicKeys map[string]PublicKey -) - -func init() { - var err error - - n := len(testdata.PEMBytes) - testPrivateKeys = make(map[string]interface{}, n) - testSigners = make(map[string]Signer, n) - testPublicKeys = make(map[string]PublicKey, n) - for t, k := range testdata.PEMBytes { - testPrivateKeys[t], err = ParseRawPrivateKey(k) - if err != nil { - panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) - } - testSigners[t], err = NewSignerFromKey(testPrivateKeys[t]) - if err != nil { - panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) - } - testPublicKeys[t] = testSigners[t].PublicKey() - } - - // Create a cert and sign it for use in tests. - testCert := &Certificate{ - Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage - ValidAfter: 0, // unix epoch - ValidBefore: CertTimeInfinity, // The end of currently representable time. - Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil - Key: testPublicKeys["ecdsa"], - SignatureKey: testPublicKeys["rsa"], - Permissions: Permissions{ - CriticalOptions: map[string]string{}, - Extensions: map[string]string{}, - }, - } - testCert.SignCert(rand.Reader, testSigners["rsa"]) - testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] - testSigners["cert"], err = NewCertSigner(testCert, testSigners["ecdsa"]) - if err != nil { - panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/transport.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/transport.go deleted file mode 100644 index 4f68b0473f..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/transport.go +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bufio" - "errors" - "io" -) - -const ( - gcmCipherID = "aes128-gcm@openssh.com" -) - -// packetConn represents a transport that implements packet based -// operations. -type packetConn interface { - // Encrypt and send a packet of data to the remote peer. - writePacket(packet []byte) error - - // Read a packet from the connection - readPacket() ([]byte, error) - - // Close closes the write-side of the connection. - Close() error -} - -// transport is the keyingTransport that implements the SSH packet -// protocol. -type transport struct { - reader connectionState - writer connectionState - - bufReader *bufio.Reader - bufWriter *bufio.Writer - rand io.Reader - - io.Closer - - // Initial H used for the session ID. Once assigned this does - // not change, even during subsequent key exchanges. - sessionID []byte -} - -func (t *transport) getSessionID() []byte { - if t.sessionID == nil { - panic("session ID not set yet") - } - s := make([]byte, len(t.sessionID)) - copy(s, t.sessionID) - return s -} - -// packetCipher represents a combination of SSH encryption/MAC -// protocol. A single instance should be used for one direction only. -type packetCipher interface { - // writePacket encrypts the packet and writes it to w. The - // contents of the packet are generally scrambled. - writePacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error - - // readPacket reads and decrypts a packet of data. The - // returned packet may be overwritten by future calls of - // readPacket. - readPacket(seqnum uint32, r io.Reader) ([]byte, error) -} - -// connectionState represents one side (read or write) of the -// connection. This is necessary because each direction has its own -// keys, and can even have its own algorithms -type connectionState struct { - packetCipher - seqNum uint32 - dir direction - pendingKeyChange chan packetCipher -} - -// prepareKeyChange sets up key material for a keychange. The key changes in -// both directions are triggered by reading and writing a msgNewKey packet -// respectively. -func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error { - if t.sessionID == nil { - t.sessionID = kexResult.H - } - - kexResult.SessionID = t.sessionID - - if ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult); err != nil { - return err - } else { - t.reader.pendingKeyChange <- ciph - } - - if ciph, err := newPacketCipher(t.writer.dir, algs.w, kexResult); err != nil { - return err - } else { - t.writer.pendingKeyChange <- ciph - } - - return nil -} - -// Read and decrypt next packet. -func (t *transport) readPacket() ([]byte, error) { - return t.reader.readPacket(t.bufReader) -} - -func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) { - packet, err := s.packetCipher.readPacket(s.seqNum, r) - s.seqNum++ - if err == nil && len(packet) == 0 { - err = errors.New("ssh: zero length packet") - } - - if len(packet) > 0 && packet[0] == msgNewKeys { - select { - case cipher := <-s.pendingKeyChange: - s.packetCipher = cipher - default: - return nil, errors.New("ssh: got bogus newkeys message.") - } - } - - // The packet may point to an internal buffer, so copy the - // packet out here. - fresh := make([]byte, len(packet)) - copy(fresh, packet) - - return fresh, err -} - -func (t *transport) writePacket(packet []byte) error { - return t.writer.writePacket(t.bufWriter, t.rand, packet) -} - -func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error { - changeKeys := len(packet) > 0 && packet[0] == msgNewKeys - - err := s.packetCipher.writePacket(s.seqNum, w, rand, packet) - if err != nil { - return err - } - if err = w.Flush(); err != nil { - return err - } - s.seqNum++ - if changeKeys { - select { - case cipher := <-s.pendingKeyChange: - s.packetCipher = cipher - default: - panic("ssh: no key material for msgNewKeys") - } - } - return err -} - -func newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport { - t := &transport{ - bufReader: bufio.NewReader(rwc), - bufWriter: bufio.NewWriter(rwc), - rand: rand, - reader: connectionState{ - packetCipher: &streamPacketCipher{cipher: noneCipher{}}, - pendingKeyChange: make(chan packetCipher, 1), - }, - writer: connectionState{ - packetCipher: &streamPacketCipher{cipher: noneCipher{}}, - pendingKeyChange: make(chan packetCipher, 1), - }, - Closer: rwc, - } - if isClient { - t.reader.dir = serverKeys - t.writer.dir = clientKeys - } else { - t.reader.dir = clientKeys - t.writer.dir = serverKeys - } - - return t -} - -type direction struct { - ivTag []byte - keyTag []byte - macKeyTag []byte -} - -var ( - serverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}} - clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}} -) - -// generateKeys generates key material for IV, MAC and encryption. -func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) { - cipherMode := cipherModes[algs.Cipher] - macMode := macModes[algs.MAC] - - iv = make([]byte, cipherMode.ivSize) - key = make([]byte, cipherMode.keySize) - macKey = make([]byte, macMode.keySize) - - generateKeyMaterial(iv, d.ivTag, kex) - generateKeyMaterial(key, d.keyTag, kex) - generateKeyMaterial(macKey, d.macKeyTag, kex) - return -} - -// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as -// described in RFC 4253, section 6.4. direction should either be serverKeys -// (to setup server->client keys) or clientKeys (for client->server keys). -func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) { - iv, key, macKey := generateKeys(d, algs, kex) - - if algs.Cipher == gcmCipherID { - return newGCMCipher(iv, key, macKey) - } - - c := &streamPacketCipher{ - mac: macModes[algs.MAC].new(macKey), - } - c.macResult = make([]byte, c.mac.Size()) - - var err error - c.cipher, err = cipherModes[algs.Cipher].createStream(key, iv) - if err != nil { - return nil, err - } - - return c, nil -} - -// generateKeyMaterial fills out with key material generated from tag, K, H -// and sessionId, as specified in RFC 4253, section 7.2. -func generateKeyMaterial(out, tag []byte, r *kexResult) { - var digestsSoFar []byte - - h := r.Hash.New() - for len(out) > 0 { - h.Reset() - h.Write(r.K) - h.Write(r.H) - - if len(digestsSoFar) == 0 { - h.Write(tag) - h.Write(r.SessionID) - } else { - h.Write(digestsSoFar) - } - - digest := h.Sum(nil) - n := copy(out, digest) - out = out[n:] - if len(out) > 0 { - digestsSoFar = append(digestsSoFar, digest...) - } - } -} - -const packageVersion = "SSH-2.0-Go" - -// Sends and receives a version line. The versionLine string should -// be US ASCII, start with "SSH-2.0-", and should not include a -// newline. exchangeVersions returns the other side's version line. -func exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) { - // Contrary to the RFC, we do not ignore lines that don't - // start with "SSH-2.0-" to make the library usable with - // nonconforming servers. - for _, c := range versionLine { - // The spec disallows non US-ASCII chars, and - // specifically forbids null chars. - if c < 32 { - return nil, errors.New("ssh: junk character in version line") - } - } - if _, err = rw.Write(append(versionLine, '\r', '\n')); err != nil { - return - } - - them, err = readVersion(rw) - return them, err -} - -// maxVersionStringBytes is the maximum number of bytes that we'll -// accept as a version string. RFC 4253 section 4.2 limits this at 255 -// chars -const maxVersionStringBytes = 255 - -// Read version string as specified by RFC 4253, section 4.2. -func readVersion(r io.Reader) ([]byte, error) { - versionString := make([]byte, 0, 64) - var ok bool - var buf [1]byte - - for len(versionString) < maxVersionStringBytes { - _, err := io.ReadFull(r, buf[:]) - if err != nil { - return nil, err - } - // The RFC says that the version should be terminated with \r\n - // but several SSH servers actually only send a \n. - if buf[0] == '\n' { - ok = true - break - } - - // non ASCII chars are disallowed, but we are lenient, - // since Go doesn't use null-terminated strings. - - // The RFC allows a comment after a space, however, - // all of it (version and comments) goes into the - // session hash. - versionString = append(versionString, buf[0]) - } - - if !ok { - return nil, errors.New("ssh: overflow reading version string") - } - - // There might be a '\r' on the end which we should remove. - if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' { - versionString = versionString[:len(versionString)-1] - } - return versionString, nil -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/transport_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/transport_test.go deleted file mode 100644 index 92d83abf93..0000000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/ssh/transport_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssh - -import ( - "bytes" - "crypto/rand" - "encoding/binary" - "strings" - "testing" -) - -func TestReadVersion(t *testing.T) { - longversion := strings.Repeat("SSH-2.0-bla", 50)[:253] - cases := map[string]string{ - "SSH-2.0-bla\r\n": "SSH-2.0-bla", - "SSH-2.0-bla\n": "SSH-2.0-bla", - longversion + "\r\n": longversion, - } - - for in, want := range cases { - result, err := readVersion(bytes.NewBufferString(in)) - if err != nil { - t.Errorf("readVersion(%q): %s", in, err) - } - got := string(result) - if got != want { - t.Errorf("got %q, want %q", got, want) - } - } -} - -func TestReadVersionError(t *testing.T) { - longversion := strings.Repeat("SSH-2.0-bla", 50)[:253] - cases := []string{ - longversion + "too-long\r\n", - } - for _, in := range cases { - if _, err := readVersion(bytes.NewBufferString(in)); err == nil { - t.Errorf("readVersion(%q) should have failed", in) - } - } -} - -func TestExchangeVersionsBasic(t *testing.T) { - v := "SSH-2.0-bla" - buf := bytes.NewBufferString(v + "\r\n") - them, err := exchangeVersions(buf, []byte("xyz")) - if err != nil { - t.Errorf("exchangeVersions: %v", err) - } - - if want := "SSH-2.0-bla"; string(them) != want { - t.Errorf("got %q want %q for our version", them, want) - } -} - -func TestExchangeVersions(t *testing.T) { - cases := []string{ - "not\x000allowed", - "not allowed\n", - } - for _, c := range cases { - buf := bytes.NewBufferString("SSH-2.0-bla\r\n") - if _, err := exchangeVersions(buf, []byte(c)); err == nil { - t.Errorf("exchangeVersions(%q): should have failed", c) - } - } -} - -type closerBuffer struct { - bytes.Buffer -} - -func (b *closerBuffer) Close() error { - return nil -} - -func TestTransportMaxPacketWrite(t *testing.T) { - buf := &closerBuffer{} - tr := newTransport(buf, rand.Reader, true) - huge := make([]byte, maxPacket+1) - err := tr.writePacket(huge) - if err == nil { - t.Errorf("transport accepted write for a huge packet.") - } -} - -func TestTransportMaxPacketReader(t *testing.T) { - var header [5]byte - huge := make([]byte, maxPacket+128) - binary.BigEndian.PutUint32(header[0:], uint32(len(huge))) - // padding. - header[4] = 0 - - buf := &closerBuffer{} - buf.Write(header[:]) - buf.Write(huge) - - tr := newTransport(buf, rand.Reader, true) - _, err := tr.readPacket() - if err == nil { - t.Errorf("transport succeeded reading huge packet.") - } else if !strings.Contains(err.Error(), "large") { - t.Errorf("got %q, should mention %q", err.Error(), "large") - } -} diff --git a/Godeps/_workspace/src/google.golang.org/api/compute/v1/compute-api.json b/Godeps/_workspace/src/google.golang.org/api/compute/v1/compute-api.json deleted file mode 100644 index 726a0ac363..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/compute/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/google.golang.org/api/compute/v1/compute-gen.go b/Godeps/_workspace/src/google.golang.org/api/compute/v1/compute-gen.go deleted file mode 100644 index 5e9da0dffd..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/compute/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 "google.golang.org/api/compute/v1" -// ... -// computeService, err := compute.New(oauthHttpClient) -package compute - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "google.golang.org/api/googleapi" - "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/google.golang.org/api/googleapi/googleapi.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/googleapi.go deleted file mode 100644 index af3442eb8a..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/googleapi.go +++ /dev/null @@ -1,401 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package googleapi contains the common code shared by all Google API -// libraries. -package googleapi - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "net/textproto" - "net/url" - "os" - "strings" - - "google.golang.org/api/googleapi/internal/uritemplates" -) - -// ContentTyper is an interface for Readers which know (or would like -// to override) their Content-Type. If a media body doesn't implement -// ContentTyper, the type is sniffed from the content using -// http.DetectContentType. -type ContentTyper interface { - ContentType() string -} - -const Version = "0.5" - -// Error contains an error response from the server. -type Error struct { - // Code is the HTTP response status code and will always be populated. - Code int `json:"code"` - // Message is the server response message and is only populated when - // explicitly referenced by the JSON server response. - Message string `json:"message"` - // Body is the raw response returned by the server. - // It is often but not always JSON, depending on how the request fails. - Body string - - Errors []ErrorItem -} - -// ErrorItem is a detailed error code & message from the Google API frontend. -type ErrorItem struct { - // Reason is the typed error code. For example: "some_example". - Reason string `json:"reason"` - // Message is the human-readable description of the error. - Message string `json:"message"` -} - -func (e *Error) Error() string { - if len(e.Errors) == 0 && e.Message == "" { - return fmt.Sprintf("googleapi: got HTTP response code %d with body: %v", e.Code, e.Body) - } - var buf bytes.Buffer - fmt.Fprintf(&buf, "googleapi: Error %d: ", e.Code) - if e.Message != "" { - fmt.Fprintf(&buf, "%s", e.Message) - } - if len(e.Errors) == 0 { - return strings.TrimSpace(buf.String()) - } - if len(e.Errors) == 1 && e.Errors[0].Message == e.Message { - fmt.Fprintf(&buf, ", %s", e.Errors[0].Reason) - return buf.String() - } - fmt.Fprintln(&buf, "\nMore details:") - for _, v := range e.Errors { - fmt.Fprintf(&buf, "Reason: %s, Message: %s\n", v.Reason, v.Message) - } - return buf.String() -} - -type errorReply struct { - Error *Error `json:"error"` -} - -// CheckResponse returns an error (of type *Error) if the response -// status code is not 2xx. -func CheckResponse(res *http.Response) error { - if res.StatusCode >= 200 && res.StatusCode <= 299 { - return nil - } - slurp, err := ioutil.ReadAll(res.Body) - if err == nil { - jerr := new(errorReply) - err = json.Unmarshal(slurp, jerr) - if err == nil && jerr.Error != nil { - if jerr.Error.Code == 0 { - jerr.Error.Code = res.StatusCode - } - jerr.Error.Body = string(slurp) - return jerr.Error - } - } - return &Error{ - Code: res.StatusCode, - Body: string(slurp), - } -} - -type MarshalStyle bool - -var WithDataWrapper = MarshalStyle(true) -var WithoutDataWrapper = MarshalStyle(false) - -func (wrap MarshalStyle) JSONReader(v interface{}) (io.Reader, error) { - buf := new(bytes.Buffer) - if wrap { - buf.Write([]byte(`{"data": `)) - } - err := json.NewEncoder(buf).Encode(v) - if err != nil { - return nil, err - } - if wrap { - buf.Write([]byte(`}`)) - } - return buf, nil -} - -func getMediaType(media io.Reader) (io.Reader, string) { - if typer, ok := media.(ContentTyper); ok { - return media, typer.ContentType() - } - - typ := "application/octet-stream" - buf := make([]byte, 1024) - n, err := media.Read(buf) - buf = buf[:n] - if err == nil { - typ = http.DetectContentType(buf) - } - return io.MultiReader(bytes.NewBuffer(buf), media), typ -} - -type Lengther interface { - Len() int -} - -// endingWithErrorReader from r until it returns an error. If the -// final error from r is os.EOF and e is non-nil, e is used instead. -type endingWithErrorReader struct { - r io.Reader - e error -} - -func (er endingWithErrorReader) Read(p []byte) (n int, err error) { - n, err = er.r.Read(p) - if err == io.EOF && er.e != nil { - err = er.e - } - return -} - -func getReaderSize(r io.Reader) (io.Reader, int64) { - // Ideal case, the reader knows its own size. - if lr, ok := r.(Lengther); ok { - return r, int64(lr.Len()) - } - - // But maybe it's a seeker and we can seek to the end to find its size. - if s, ok := r.(io.Seeker); ok { - pos0, err := s.Seek(0, os.SEEK_CUR) - if err == nil { - posend, err := s.Seek(0, os.SEEK_END) - if err == nil { - _, err = s.Seek(pos0, os.SEEK_SET) - if err == nil { - return r, posend - pos0 - } else { - // We moved it forward but can't restore it. - // Seems unlikely, but can't really restore now. - return endingWithErrorReader{strings.NewReader(""), err}, posend - pos0 - } - } - } - } - - // Otherwise we have to make a copy to calculate how big the reader is. - buf := new(bytes.Buffer) - // TODO(bradfitz): put a cap on this copy? spill to disk after - // a certain point? - _, err := io.Copy(buf, r) - return endingWithErrorReader{buf, err}, int64(buf.Len()) -} - -func typeHeader(contentType string) textproto.MIMEHeader { - h := make(textproto.MIMEHeader) - h.Set("Content-Type", contentType) - return h -} - -// countingWriter counts the number of bytes it receives to write, but -// discards them. -type countingWriter struct { - n *int64 -} - -func (w countingWriter) Write(p []byte) (int, error) { - *w.n += int64(len(p)) - return len(p), nil -} - -// ConditionallyIncludeMedia does nothing if media is nil. -// -// bodyp is an in/out parameter. It should initially point to the -// reader of the application/json (or whatever) payload to send in the -// API request. It's updated to point to the multipart body reader. -// -// ctypep is an in/out parameter. It should initially point to the -// content type of the bodyp, usually "application/json". It's updated -// to the "multipart/related" content type, with random boundary. -// -// The return value is the content-length of the entire multpart body. -func ConditionallyIncludeMedia(media io.Reader, bodyp *io.Reader, ctypep *string) (totalContentLength int64, ok bool) { - if media == nil { - return - } - // Get the media type and size. The type check might return a - // different reader instance, so do the size check first, - // which looks at the specific type of the io.Reader. - var mediaType string - if typer, ok := media.(ContentTyper); ok { - mediaType = typer.ContentType() - } - media, mediaSize := getReaderSize(media) - if mediaType == "" { - media, mediaType = getMediaType(media) - } - body, bodyType := *bodyp, *ctypep - body, bodySize := getReaderSize(body) - - // Calculate how big the the multipart will be. - { - totalContentLength = bodySize + mediaSize - mpw := multipart.NewWriter(countingWriter{&totalContentLength}) - mpw.CreatePart(typeHeader(bodyType)) - mpw.CreatePart(typeHeader(mediaType)) - mpw.Close() - } - - pr, pw := io.Pipe() - mpw := multipart.NewWriter(pw) - *bodyp = pr - *ctypep = "multipart/related; boundary=" + mpw.Boundary() - go func() { - defer pw.Close() - defer mpw.Close() - - w, err := mpw.CreatePart(typeHeader(bodyType)) - if err != nil { - return - } - _, err = io.Copy(w, body) - if err != nil { - return - } - - w, err = mpw.CreatePart(typeHeader(mediaType)) - if err != nil { - return - } - _, err = io.Copy(w, media) - if err != nil { - return - } - }() - return totalContentLength, true -} - -func ResolveRelative(basestr, relstr string) string { - u, _ := url.Parse(basestr) - rel, _ := url.Parse(relstr) - u = u.ResolveReference(rel) - us := u.String() - us = strings.Replace(us, "%7B", "{", -1) - us = strings.Replace(us, "%7D", "}", -1) - return us -} - -// has4860Fix is whether this Go environment contains the fix for -// http://golang.org/issue/4860 -var has4860Fix bool - -// init initializes has4860Fix by checking the behavior of the net/http package. -func init() { - r := http.Request{ - URL: &url.URL{ - Scheme: "http", - Opaque: "//opaque", - }, - } - b := &bytes.Buffer{} - r.Write(b) - has4860Fix = bytes.HasPrefix(b.Bytes(), []byte("GET http")) -} - -// SetOpaque sets u.Opaque from u.Path such that HTTP requests to it -// don't alter any hex-escaped characters in u.Path. -func SetOpaque(u *url.URL) { - u.Opaque = "//" + u.Host + u.Path - if !has4860Fix { - u.Opaque = u.Scheme + ":" + u.Opaque - } -} - -// Expand subsitutes any {encoded} strings in the URL passed in using -// the map supplied. -// -// This calls SetOpaque to avoid encoding of the parameters in the URL path. -func Expand(u *url.URL, expansions map[string]string) { - expanded, err := uritemplates.Expand(u.Path, expansions) - if err == nil { - u.Path = expanded - SetOpaque(u) - } -} - -// CloseBody is used to close res.Body. -// Prior to calling Close, it also tries to Read a small amount to see an EOF. -// Not seeing an EOF can prevent HTTP Transports from reusing connections. -func CloseBody(res *http.Response) { - if res == nil || res.Body == nil { - return - } - // Justification for 3 byte reads: two for up to "\r\n" after - // a JSON/XML document, and then 1 to see EOF if we haven't yet. - // TODO(bradfitz): detect Go 1.3+ and skip these reads. - // See https://codereview.appspot.com/58240043 - // and https://codereview.appspot.com/49570044 - buf := make([]byte, 1) - for i := 0; i < 3; i++ { - _, err := res.Body.Read(buf) - if err != nil { - break - } - } - res.Body.Close() - -} - -// VariantType returns the type name of the given variant. -// If the map doesn't contain the named key or the value is not a []interface{}, "" is returned. -// This is used to support "variant" APIs that can return one of a number of different types. -func VariantType(t map[string]interface{}) string { - s, _ := t["type"].(string) - return s -} - -// ConvertVariant uses the JSON encoder/decoder to fill in the struct 'dst' with the fields found in variant 'v'. -// This is used to support "variant" APIs that can return one of a number of different types. -// It reports whether the conversion was successful. -func ConvertVariant(v map[string]interface{}, dst interface{}) bool { - var buf bytes.Buffer - err := json.NewEncoder(&buf).Encode(v) - if err != nil { - return false - } - return json.Unmarshal(buf.Bytes(), dst) == nil -} - -// A Field names a field to be retrieved with a partial response. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// -// Partial responses can dramatically reduce the amount of data that must be sent to your application. -// In order to request partial responses, you can specify the full list of fields -// that your application needs by adding the Fields option to your request. -// -// Field strings use camelCase with leading lower-case characters to identify fields within the response. -// -// For example, if your response has a "NextPageToken" and a slice of "Items" with "Id" fields, -// you could request just those fields like this: -// -// svc.Events.List().Fields("nextPageToken", "items/id").Do() -// -// or if you were also interested in each Item's "Updated" field, you can combine them like this: -// -// svc.Events.List().Fields("nextPageToken", "items(id,updated)").Do() -// -// More information about field formatting can be found here: -// https://developers.google.com/+/api/#fields-syntax -// -// Another way to find field names is through the Google API explorer: -// https://developers.google.com/apis-explorer/#p/ -type Field string - -// CombineFields combines fields into a single string. -func CombineFields(s []Field) string { - r := make([]string, len(s)) - for i, v := range s { - r[i] = string(v) - } - return strings.Join(r, ",") -} diff --git a/Godeps/_workspace/src/google.golang.org/api/googleapi/googleapi_test.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/googleapi_test.go deleted file mode 100644 index abc5185061..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/googleapi_test.go +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package googleapi - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "reflect" - "strings" - "testing" -) - -type SetOpaqueTest struct { - in *url.URL - wantRequestURI string -} - -var setOpaqueTests = []SetOpaqueTest{ - // no path - { - &url.URL{ - Scheme: "http", - Host: "www.golang.org", - }, - "http://www.golang.org", - }, - // path - { - &url.URL{ - Scheme: "http", - Host: "www.golang.org", - Path: "/", - }, - "http://www.golang.org/", - }, - // file with hex escaping - { - &url.URL{ - Scheme: "https", - Host: "www.golang.org", - Path: "/file%20one&two", - }, - "https://www.golang.org/file%20one&two", - }, - // query - { - &url.URL{ - Scheme: "http", - Host: "www.golang.org", - Path: "/", - RawQuery: "q=go+language", - }, - "http://www.golang.org/?q=go+language", - }, - // file with hex escaping in path plus query - { - &url.URL{ - Scheme: "https", - Host: "www.golang.org", - Path: "/file%20one&two", - RawQuery: "q=go+language", - }, - "https://www.golang.org/file%20one&two?q=go+language", - }, - // query with hex escaping - { - &url.URL{ - Scheme: "http", - Host: "www.golang.org", - Path: "/", - RawQuery: "q=go%20language", - }, - "http://www.golang.org/?q=go%20language", - }, -} - -// prefixTmpl is a template for the expected prefix of the output of writing -// an HTTP request. -const prefixTmpl = "GET %v HTTP/1.1\r\nHost: %v\r\n" - -func TestSetOpaque(t *testing.T) { - for _, test := range setOpaqueTests { - u := *test.in - SetOpaque(&u) - - w := &bytes.Buffer{} - r := &http.Request{URL: &u} - if err := r.Write(w); err != nil { - t.Errorf("write request: %v", err) - continue - } - - prefix := fmt.Sprintf(prefixTmpl, test.wantRequestURI, test.in.Host) - if got := string(w.Bytes()); !strings.HasPrefix(got, prefix) { - t.Errorf("got %q expected prefix %q", got, prefix) - } - } -} - -type ExpandTest struct { - in string - expansions map[string]string - want string -} - -var expandTests = []ExpandTest{ - // no expansions - { - "http://www.golang.org/", - map[string]string{}, - "http://www.golang.org/", - }, - // one expansion, no escaping - { - "http://www.golang.org/{bucket}/delete", - map[string]string{ - "bucket": "red", - }, - "http://www.golang.org/red/delete", - }, - // one expansion, with hex escapes - { - "http://www.golang.org/{bucket}/delete", - map[string]string{ - "bucket": "red/blue", - }, - "http://www.golang.org/red%2Fblue/delete", - }, - // one expansion, with space - { - "http://www.golang.org/{bucket}/delete", - map[string]string{ - "bucket": "red or blue", - }, - "http://www.golang.org/red%20or%20blue/delete", - }, - // expansion not found - { - "http://www.golang.org/{object}/delete", - map[string]string{ - "bucket": "red or blue", - }, - "http://www.golang.org//delete", - }, - // multiple expansions - { - "http://www.golang.org/{one}/{two}/{three}/get", - map[string]string{ - "one": "ONE", - "two": "TWO", - "three": "THREE", - }, - "http://www.golang.org/ONE/TWO/THREE/get", - }, - // utf-8 characters - { - "http://www.golang.org/{bucket}/get", - map[string]string{ - "bucket": "£100", - }, - "http://www.golang.org/%C2%A3100/get", - }, - // punctuations - { - "http://www.golang.org/{bucket}/get", - map[string]string{ - "bucket": `/\@:,.`, - }, - "http://www.golang.org/%2F%5C%40%3A%2C./get", - }, - // mis-matched brackets - { - "http://www.golang.org/{bucket/get", - map[string]string{ - "bucket": "red", - }, - "http://www.golang.org/{bucket/get", - }, - // "+" prefix for suppressing escape - // See also: http://tools.ietf.org/html/rfc6570#section-3.2.3 - { - "http://www.golang.org/{+topic}", - map[string]string{ - "topic": "/topics/myproject/mytopic", - }, - // The double slashes here look weird, but it's intentional - "http://www.golang.org//topics/myproject/mytopic", - }, -} - -func TestExpand(t *testing.T) { - for i, test := range expandTests { - u := url.URL{ - Path: test.in, - } - Expand(&u, test.expansions) - got := u.Path - if got != test.want { - t.Errorf("got %q expected %q in test %d", got, test.want, i+1) - } - } -} - -type CheckResponseTest struct { - in *http.Response - bodyText string - want error - errText string -} - -var checkResponseTests = []CheckResponseTest{ - { - &http.Response{ - StatusCode: http.StatusOK, - }, - "", - nil, - "", - }, - { - &http.Response{ - StatusCode: http.StatusInternalServerError, - }, - `{"error":{}}`, - &Error{ - Code: http.StatusInternalServerError, - Body: `{"error":{}}`, - }, - `googleapi: got HTTP response code 500 with body: {"error":{}}`, - }, - { - &http.Response{ - StatusCode: http.StatusNotFound, - }, - `{"error":{"message":"Error message for StatusNotFound."}}`, - &Error{ - Code: http.StatusNotFound, - Message: "Error message for StatusNotFound.", - Body: `{"error":{"message":"Error message for StatusNotFound."}}`, - }, - "googleapi: Error 404: Error message for StatusNotFound.", - }, - { - &http.Response{ - StatusCode: http.StatusBadRequest, - }, - `{"error":"invalid_token","error_description":"Invalid Value"}`, - &Error{ - Code: http.StatusBadRequest, - Body: `{"error":"invalid_token","error_description":"Invalid Value"}`, - }, - `googleapi: got HTTP response code 400 with body: {"error":"invalid_token","error_description":"Invalid Value"}`, - }, - { - &http.Response{ - StatusCode: http.StatusBadRequest, - }, - `{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}`, - &Error{ - Code: http.StatusBadRequest, - Errors: []ErrorItem{ - { - Reason: "keyInvalid", - Message: "Bad Request", - }, - }, - Body: `{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}`, - Message: "Bad Request", - }, - "googleapi: Error 400: Bad Request, keyInvalid", - }, -} - -func TestCheckResponse(t *testing.T) { - for _, test := range checkResponseTests { - res := test.in - if test.bodyText != "" { - res.Body = ioutil.NopCloser(strings.NewReader(test.bodyText)) - } - g := CheckResponse(res) - if !reflect.DeepEqual(g, test.want) { - t.Errorf("CheckResponse: got %v, want %v", g, test.want) - gotJson, err := json.Marshal(g) - if err != nil { - t.Error(err) - } - wantJson, err := json.Marshal(test.want) - if err != nil { - t.Error(err) - } - t.Errorf("json(got): %q\njson(want): %q", string(gotJson), string(wantJson)) - } - if g != nil && g.Error() != test.errText { - t.Errorf("CheckResponse: unexpected error message.\nGot: %q\nwant: %q", g, test.errText) - } - } -} - -type VariantPoint struct { - Type string - Coordinates []float64 -} - -type VariantTest struct { - in map[string]interface{} - result bool - want VariantPoint -} - -var coords = []interface{}{1.0, 2.0} - -var variantTests = []VariantTest{ - { - in: map[string]interface{}{ - "type": "Point", - "coordinates": coords, - }, - result: true, - want: VariantPoint{ - Type: "Point", - Coordinates: []float64{1.0, 2.0}, - }, - }, - { - in: map[string]interface{}{ - "type": "Point", - "bogus": coords, - }, - result: true, - want: VariantPoint{ - Type: "Point", - }, - }, -} - -func TestVariantType(t *testing.T) { - for _, test := range variantTests { - if g := VariantType(test.in); g != test.want.Type { - t.Errorf("VariantType(%v): got %v, want %v", test.in, g, test.want.Type) - } - } -} - -func TestConvertVariant(t *testing.T) { - for _, test := range variantTests { - g := VariantPoint{} - r := ConvertVariant(test.in, &g) - if r != test.result { - t.Errorf("ConvertVariant(%v): got %v, want %v", test.in, r, test.result) - } - if !reflect.DeepEqual(g, test.want) { - t.Errorf("ConvertVariant(%v): got %v, want %v", test.in, g, test.want) - } - } -} diff --git a/Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go deleted file mode 100644 index 8a84813fe5..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2013 Joshua Tacoma. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package uritemplates is a level 4 implementation of RFC 6570 (URI -// Template, http://tools.ietf.org/html/rfc6570). -// -// To use uritemplates, parse a template string and expand it with a value -// map: -// -// template, _ := uritemplates.Parse("https://api.github.com/repos{/user,repo}") -// values := make(map[string]interface{}) -// values["user"] = "jtacoma" -// values["repo"] = "uritemplates" -// expanded, _ := template.ExpandString(values) -// fmt.Printf(expanded) -// -package uritemplates - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "regexp" - "strconv" - "strings" -) - -var ( - unreserved = regexp.MustCompile("[^A-Za-z0-9\\-._~]") - reserved = regexp.MustCompile("[^A-Za-z0-9\\-._~:/?#[\\]@!$&'()*+,;=]") - validname = regexp.MustCompile("^([A-Za-z0-9_\\.]|%[0-9A-Fa-f][0-9A-Fa-f])+$") - hex = []byte("0123456789ABCDEF") -) - -func pctEncode(src []byte) []byte { - dst := make([]byte, len(src)*3) - for i, b := range src { - buf := dst[i*3 : i*3+3] - buf[0] = 0x25 - buf[1] = hex[b/16] - buf[2] = hex[b%16] - } - return dst -} - -func escape(s string, allowReserved bool) (escaped string) { - if allowReserved { - escaped = string(reserved.ReplaceAllFunc([]byte(s), pctEncode)) - } else { - escaped = string(unreserved.ReplaceAllFunc([]byte(s), pctEncode)) - } - return escaped -} - -// A UriTemplate is a parsed representation of a URI template. -type UriTemplate struct { - raw string - parts []templatePart -} - -// Parse parses a URI template string into a UriTemplate object. -func Parse(rawtemplate string) (template *UriTemplate, err error) { - template = new(UriTemplate) - template.raw = rawtemplate - split := strings.Split(rawtemplate, "{") - template.parts = make([]templatePart, len(split)*2-1) - for i, s := range split { - if i == 0 { - if strings.Contains(s, "}") { - err = errors.New("unexpected }") - break - } - template.parts[i].raw = s - } else { - subsplit := strings.Split(s, "}") - if len(subsplit) != 2 { - err = errors.New("malformed template") - break - } - expression := subsplit[0] - template.parts[i*2-1], err = parseExpression(expression) - if err != nil { - break - } - template.parts[i*2].raw = subsplit[1] - } - } - if err != nil { - template = nil - } - return template, err -} - -type templatePart struct { - raw string - terms []templateTerm - first string - sep string - named bool - ifemp string - allowReserved bool -} - -type templateTerm struct { - name string - explode bool - truncate int -} - -func parseExpression(expression string) (result templatePart, err error) { - switch expression[0] { - case '+': - result.sep = "," - result.allowReserved = true - expression = expression[1:] - case '.': - result.first = "." - result.sep = "." - expression = expression[1:] - case '/': - result.first = "/" - result.sep = "/" - expression = expression[1:] - case ';': - result.first = ";" - result.sep = ";" - result.named = true - expression = expression[1:] - case '?': - result.first = "?" - result.sep = "&" - result.named = true - result.ifemp = "=" - expression = expression[1:] - case '&': - result.first = "&" - result.sep = "&" - result.named = true - result.ifemp = "=" - expression = expression[1:] - case '#': - result.first = "#" - result.sep = "," - result.allowReserved = true - expression = expression[1:] - default: - result.sep = "," - } - rawterms := strings.Split(expression, ",") - result.terms = make([]templateTerm, len(rawterms)) - for i, raw := range rawterms { - result.terms[i], err = parseTerm(raw) - if err != nil { - break - } - } - return result, err -} - -func parseTerm(term string) (result templateTerm, err error) { - if strings.HasSuffix(term, "*") { - result.explode = true - term = term[:len(term)-1] - } - split := strings.Split(term, ":") - if len(split) == 1 { - result.name = term - } else if len(split) == 2 { - result.name = split[0] - var parsed int64 - parsed, err = strconv.ParseInt(split[1], 10, 0) - result.truncate = int(parsed) - } else { - err = errors.New("multiple colons in same term") - } - if !validname.MatchString(result.name) { - err = errors.New("not a valid name: " + result.name) - } - if result.explode && result.truncate > 0 { - err = errors.New("both explode and prefix modifers on same term") - } - return result, err -} - -// Expand expands a URI template with a set of values to produce a string. -func (self *UriTemplate) Expand(value interface{}) (string, error) { - values, ismap := value.(map[string]interface{}) - if !ismap { - if m, ismap := struct2map(value); !ismap { - return "", errors.New("expected map[string]interface{}, struct, or pointer to struct.") - } else { - return self.Expand(m) - } - } - var buf bytes.Buffer - for _, p := range self.parts { - err := p.expand(&buf, values) - if err != nil { - return "", err - } - } - return buf.String(), nil -} - -func (self *templatePart) expand(buf *bytes.Buffer, values map[string]interface{}) error { - if len(self.raw) > 0 { - buf.WriteString(self.raw) - return nil - } - var zeroLen = buf.Len() - buf.WriteString(self.first) - var firstLen = buf.Len() - for _, term := range self.terms { - value, exists := values[term.name] - if !exists { - continue - } - if buf.Len() != firstLen { - buf.WriteString(self.sep) - } - switch v := value.(type) { - case string: - self.expandString(buf, term, v) - case []interface{}: - self.expandArray(buf, term, v) - case map[string]interface{}: - if term.truncate > 0 { - return errors.New("cannot truncate a map expansion") - } - self.expandMap(buf, term, v) - default: - if m, ismap := struct2map(value); ismap { - if term.truncate > 0 { - return errors.New("cannot truncate a map expansion") - } - self.expandMap(buf, term, m) - } else { - str := fmt.Sprintf("%v", value) - self.expandString(buf, term, str) - } - } - } - if buf.Len() == firstLen { - original := buf.Bytes()[:zeroLen] - buf.Reset() - buf.Write(original) - } - return nil -} - -func (self *templatePart) expandName(buf *bytes.Buffer, name string, empty bool) { - if self.named { - buf.WriteString(name) - if empty { - buf.WriteString(self.ifemp) - } else { - buf.WriteString("=") - } - } -} - -func (self *templatePart) expandString(buf *bytes.Buffer, t templateTerm, s string) { - if len(s) > t.truncate && t.truncate > 0 { - s = s[:t.truncate] - } - self.expandName(buf, t.name, len(s) == 0) - buf.WriteString(escape(s, self.allowReserved)) -} - -func (self *templatePart) expandArray(buf *bytes.Buffer, t templateTerm, a []interface{}) { - if len(a) == 0 { - return - } else if !t.explode { - self.expandName(buf, t.name, false) - } - for i, value := range a { - if t.explode && i > 0 { - buf.WriteString(self.sep) - } else if i > 0 { - buf.WriteString(",") - } - var s string - switch v := value.(type) { - case string: - s = v - default: - s = fmt.Sprintf("%v", v) - } - if len(s) > t.truncate && t.truncate > 0 { - s = s[:t.truncate] - } - if self.named && t.explode { - self.expandName(buf, t.name, len(s) == 0) - } - buf.WriteString(escape(s, self.allowReserved)) - } -} - -func (self *templatePart) expandMap(buf *bytes.Buffer, t templateTerm, m map[string]interface{}) { - if len(m) == 0 { - return - } - if !t.explode { - self.expandName(buf, t.name, len(m) == 0) - } - var firstLen = buf.Len() - for k, value := range m { - if firstLen != buf.Len() { - if t.explode { - buf.WriteString(self.sep) - } else { - buf.WriteString(",") - } - } - var s string - switch v := value.(type) { - case string: - s = v - default: - s = fmt.Sprintf("%v", v) - } - if t.explode { - buf.WriteString(escape(k, self.allowReserved)) - buf.WriteRune('=') - buf.WriteString(escape(s, self.allowReserved)) - } else { - buf.WriteString(escape(k, self.allowReserved)) - buf.WriteRune(',') - buf.WriteString(escape(s, self.allowReserved)) - } - } -} - -func struct2map(v interface{}) (map[string]interface{}, bool) { - value := reflect.ValueOf(v) - switch value.Type().Kind() { - case reflect.Ptr: - return struct2map(value.Elem().Interface()) - case reflect.Struct: - m := make(map[string]interface{}) - for i := 0; i < value.NumField(); i++ { - tag := value.Type().Field(i).Tag - var name string - if strings.Contains(string(tag), ":") { - name = tag.Get("uri") - } else { - name = strings.TrimSpace(string(tag)) - } - if len(name) == 0 { - name = value.Type().Field(i).Name - } - m[name] = value.Field(i).Interface() - } - return m, true - } - return nil, false -} diff --git a/Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/utils.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/utils.go deleted file mode 100644 index 399ef46236..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/utils.go +++ /dev/null @@ -1,13 +0,0 @@ -package uritemplates - -func Expand(path string, expansions map[string]string) (string, error) { - template, err := Parse(path) - if err != nil { - return "", err - } - values := make(map[string]interface{}) - for k, v := range expansions { - values[k] = v - } - return template.Expand(values) -} diff --git a/Godeps/_workspace/src/google.golang.org/api/googleapi/transport/apikey.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/transport/apikey.go deleted file mode 100644 index eca1ea2507..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/transport/apikey.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2012 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package transport contains HTTP transports used to make -// authenticated API requests. -package transport - -import ( - "errors" - "net/http" -) - -// APIKey is an HTTP Transport which wraps an underlying transport and -// appends an API Key "key" parameter to the URL of outgoing requests. -type APIKey struct { - // Key is the API Key to set on requests. - Key string - - // Transport is the underlying HTTP transport. - // If nil, http.DefaultTransport is used. - Transport http.RoundTripper -} - -func (t *APIKey) RoundTrip(req *http.Request) (*http.Response, error) { - rt := t.Transport - if rt == nil { - rt = http.DefaultTransport - if rt == nil { - return nil, errors.New("googleapi/transport: no Transport specified or available") - } - } - newReq := *req - args := newReq.URL.Query() - args.Set("key", t.Key) - newReq.URL.RawQuery = args.Encode() - return rt.RoundTrip(&newReq) -} diff --git a/Godeps/_workspace/src/google.golang.org/api/googleapi/types.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/types.go deleted file mode 100644 index 7ed7dd9823..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/types.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package googleapi - -import ( - "encoding/json" - "strconv" -) - -// Int64s is a slice of int64s that marshal as quoted strings in JSON. -type Int64s []int64 - -func (q *Int64s) UnmarshalJSON(raw []byte) error { - *q = (*q)[:0] - var ss []string - if err := json.Unmarshal(raw, &ss); err != nil { - return err - } - for _, s := range ss { - v, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return err - } - *q = append(*q, int64(v)) - } - return nil -} - -// Int32s is a slice of int32s that marshal as quoted strings in JSON. -type Int32s []int32 - -func (q *Int32s) UnmarshalJSON(raw []byte) error { - *q = (*q)[:0] - var ss []string - if err := json.Unmarshal(raw, &ss); err != nil { - return err - } - for _, s := range ss { - v, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return err - } - *q = append(*q, int32(v)) - } - return nil -} - -// Uint64s is a slice of uint64s that marshal as quoted strings in JSON. -type Uint64s []uint64 - -func (q *Uint64s) UnmarshalJSON(raw []byte) error { - *q = (*q)[:0] - var ss []string - if err := json.Unmarshal(raw, &ss); err != nil { - return err - } - for _, s := range ss { - v, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return err - } - *q = append(*q, uint64(v)) - } - return nil -} - -// Uint32s is a slice of uint32s that marshal as quoted strings in JSON. -type Uint32s []uint32 - -func (q *Uint32s) UnmarshalJSON(raw []byte) error { - *q = (*q)[:0] - var ss []string - if err := json.Unmarshal(raw, &ss); err != nil { - return err - } - for _, s := range ss { - v, err := strconv.ParseUint(s, 10, 32) - if err != nil { - return err - } - *q = append(*q, uint32(v)) - } - return nil -} - -// Float64s is a slice of float64s that marshal as quoted strings in JSON. -type Float64s []float64 - -func (q *Float64s) UnmarshalJSON(raw []byte) error { - *q = (*q)[:0] - var ss []string - if err := json.Unmarshal(raw, &ss); err != nil { - return err - } - for _, s := range ss { - v, err := strconv.ParseFloat(s, 64) - if err != nil { - return err - } - *q = append(*q, float64(v)) - } - return nil -} - -func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) { - dst := make([]byte, 0, 2+n*10) // somewhat arbitrary - dst = append(dst, '[') - for i := 0; i < n; i++ { - if i > 0 { - dst = append(dst, ',') - } - dst = append(dst, '"') - dst = fn(dst, i) - dst = append(dst, '"') - } - dst = append(dst, ']') - return dst, nil -} - -func (s Int64s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendInt(dst, s[i], 10) - }) -} - -func (s Int32s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendInt(dst, int64(s[i]), 10) - }) -} - -func (s Uint64s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendUint(dst, s[i], 10) - }) -} - -func (s Uint32s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendUint(dst, uint64(s[i]), 10) - }) -} - -func (s Float64s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendFloat(dst, s[i], 'g', -1, 64) - }) -} diff --git a/Godeps/_workspace/src/google.golang.org/api/googleapi/types_test.go b/Godeps/_workspace/src/google.golang.org/api/googleapi/types_test.go deleted file mode 100644 index a6b2045156..0000000000 --- a/Godeps/_workspace/src/google.golang.org/api/googleapi/types_test.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package googleapi - -import ( - "encoding/json" - "reflect" - "testing" -) - -func TestTypes(t *testing.T) { - type T struct { - I32 Int32s - I64 Int64s - U32 Uint32s - U64 Uint64s - F64 Float64s - } - v := &T{ - I32: Int32s{-1, 2, 3}, - I64: Int64s{-1, 2, 1 << 33}, - U32: Uint32s{1, 2}, - U64: Uint64s{1, 2, 1 << 33}, - F64: Float64s{1.5, 3.33}, - } - got, err := json.Marshal(v) - if err != nil { - t.Fatal(err) - } - want := `{"I32":["-1","2","3"],"I64":["-1","2","8589934592"],"U32":["1","2"],"U64":["1","2","8589934592"],"F64":["1.5","3.33"]}` - if string(got) != want { - t.Fatalf("Marshal mismatch.\n got: %s\nwant: %s\n", got, want) - } - - v2 := new(T) - if err := json.Unmarshal(got, v2); err != nil { - t.Fatalf("Unmarshal: %v", err) - } - if !reflect.DeepEqual(v, v2) { - t.Fatalf("Unmarshal didn't produce same results.\n got: %#v\nwant: %#v\n", v, v2) - } -} diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000000..de834ffaa6 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,486 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:1c1c2c5c3cd554a489b36c951d1267e1be7f1deb16b63908f35fdbc3b926af59" + name = "github.com/Azure/azure-sdk-for-go" + packages = [ + "arm/compute", + "arm/network", + "arm/resources/resources", + "arm/resources/subscriptions", + "arm/storage", + "storage", + ] + pruneopts = "UT" + revision = "91f3d4a4d024e3c0d4d9412916d05cf84504a616" + version = "v5.0.0-beta" + +[[projects]] + branch = "master" + digest = "1:6da51e5ec493ad2b44cb04129e2d0a068c8fb9bd6cb5739d199573558696bb94" + name = "github.com/Azure/go-ansiterm" + packages = [ + ".", + "winterm", + ] + pruneopts = "UT" + revision = "d6e3b3328b783f23731bc4d058875b0371ff8109" + +[[projects]] + digest = "1:7119b0c081a1995d08827e697a94447a922dd57ec4b55962c91cc64c81f363a3" + name = "github.com/Azure/go-autorest" + packages = [ + "autorest", + "autorest/azure", + "autorest/date", + "autorest/to", + "autorest/validation", + ] + pruneopts = "UT" + revision = "0781901f19f1e7db3034d97ec57af753db0bf808" + version = "v7.2.1" + +[[projects]] + digest = "1:3e3787c889e4c6600e320ae16abfde18cac2c1f96948180be584665a35ee3ec2" + name = "github.com/aws/aws-sdk-go" + packages = [ + "aws", + "aws/awserr", + "aws/awsutil", + "aws/client", + "aws/client/metadata", + "aws/corehandlers", + "aws/credentials", + "aws/credentials/ec2rolecreds", + "aws/credentials/endpointcreds", + "aws/credentials/stscreds", + "aws/defaults", + "aws/ec2metadata", + "aws/request", + "aws/session", + "aws/signer/v4", + "private/endpoints", + "private/protocol", + "private/protocol/ec2query", + "private/protocol/query", + "private/protocol/query/queryutil", + "private/protocol/rest", + "private/protocol/xml/xmlutil", + "private/waiter", + "service/ec2", + "service/sts", + ] + pruneopts = "UT" + revision = "ddfd17ec06eee10c24c5c474633273fd034afdda" + version = "v1.4.10" + +[[projects]] + digest = "1:676da826460e2bef9b36b2b1fe93fc73c781937d2c70ca459e41c9f3277d2c55" + name = "github.com/bugsnag/bugsnag-go" + packages = [ + ".", + "errors", + ] + pruneopts = "UT" + revision = "02e952891c52fbcb15f113d90633897355783b6e" + +[[projects]] + branch = "master" + digest = "1:3c8a443f16dd3c3639c7650c19af5b1a0686402f1949dafd18352d15239d9b05" + name = "github.com/bugsnag/osext" + packages = ["."] + pruneopts = "UT" + revision = "0dd3f918b21bec95ace9dc86c7e70266cfc5c702" + +[[projects]] + digest = "1:a99e9f7f0ef9aecfcfafc43152d4c928471ad16335b7141aa1347be6d76db1c2" + name = "github.com/bugsnag/panicwrap" + packages = ["."] + pruneopts = "UT" + revision = "aceac81c6e2f55f23844821679a0553b545e91df" + version = "1.1.0" + +[[projects]] + digest = "1:f50c858ba1549c39fedde09546274f73991a1525870bd2ab575d35b956d2d246" + name = "github.com/cenkalti/backoff" + packages = ["."] + pruneopts = "UT" + revision = "9831e1e25c874e0a0601b6dc43641071414eec7a" + +[[projects]] + digest = "1:af8559c18ec5d3a1a388dedaa0e790437bb99917845e37a2e4533767b02c3961" + name = "github.com/codegangsta/cli" + packages = ["."] + pruneopts = "UT" + revision = "0302d3914d2a6ad61404584cdae6e6dbc9c03599" + +[[projects]] + digest = "1:620bade21ddf8256869717861431d52650c7e40bc56bdcd3d5ec3da63e7573b0" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d" + +[[projects]] + digest = "1:02630c70b55ecda2dcb85805170923d8389c632487568ccffadc5482e8a191ed" + name = "github.com/dgrijalva/jwt-go" + packages = ["."] + pruneopts = "UT" + revision = "24c63f56522a87ec5339cc3567883f1039378fdb" + +[[projects]] + digest = "1:b41bcd468fe0882b4cd1591274dc6d007dc3c947758f34807c83200899637e4f" + name = "github.com/digitalocean/godo" + packages = ["."] + pruneopts = "UT" + revision = "d59ed2fe842bbb3cbee91c9df8bb7659dc9ee86f" + +[[projects]] + branch = "master" + digest = "1:5c709df1e94c6dbee6fdd9699b11e3cdfa06870b1e828e9311e4e879b2ae6a4a" + name = "github.com/docker/docker" + packages = [ + "pkg/term", + "pkg/term/windows", + ] + pruneopts = "UT" + revision = "093424bec097cdf51154255226cf999d6824633b" + +[[projects]] + digest = "1:fe12e1ba38626f7f147bd12a8f1f2e9e24d259b4258fb81a2c27e2a705c04b25" + name = "github.com/docker/go-units" + packages = ["."] + pruneopts = "UT" + revision = "0bbddae09c5a5419a8c6dcdd7ff90da3d450393b" + +[[projects]] + digest = "1:7515ee368d2554cccaecdb552cf602e7a555139ffe45aad7500294fc14bcf2e1" + name = "github.com/exoscale/egoscale" + packages = ["."] + pruneopts = "UT" + revision = "432a702ab7d709538572f9a2a42eaf0ca0691698" + version = "v0.9.23" + +[[projects]] + digest = "1:ad48c8fd2fb8c747d8798f19890f70b18091196274a773550a9e5dffa9e165d1" + name = "github.com/go-ini/ini" + packages = ["."] + pruneopts = "UT" + revision = "03e0e7d51a13a91c765d8d0161246bc14a38001a" + +[[projects]] + digest = "1:922ab7a624d8398c8e986beefc25052b26e02a8ac6bba5dc507bda11adbd878b" + name = "github.com/golang/protobuf" + packages = ["proto"] + pruneopts = "UT" + revision = "3c84672111d91bb5ac31719e112f9f7126a0e26e" + +[[projects]] + digest = "1:5235d8c3e7894393db3e5b1947818966b41e5ae8a5fa5d9c42f6586975894d01" + name = "github.com/google/go-querystring" + packages = ["query"] + pruneopts = "UT" + revision = "30f7a39f4a218feb5325f3aebc60c32a572a8274" + +[[projects]] + branch = "master" + digest = "1:67214f4b22f886c6bc60830382255e3b345d3e1c5aef07d64fe6931aee8baedd" + name = "github.com/intel-go/cpuid" + packages = ["."] + pruneopts = "UT" + revision = "1a4a6f06a1c643c8fbd339bd61d980960627d09e" + +[[projects]] + branch = "master" + digest = "1:5c3444689562053b027ef3b96372e306adbe0d7d109b6cdd48d01eb80f8bab14" + name = "github.com/jinzhu/copier" + packages = ["."] + pruneopts = "UT" + revision = "7e38e58719c33e0d44d585c4ab477a30f8cb82dd" + +[[projects]] + digest = "1:b87714e57a511d88f307aba7d5b63522da12bed0a050889c81272fc50f71100e" + name = "github.com/jmespath/go-jmespath" + packages = ["."] + pruneopts = "UT" + revision = "3433f3ea46d9f8019119e7dd41274e112a2359a9" + version = "0.2.2" + +[[projects]] + digest = "1:481d1ca274189bb298947b76bb522b7e2ee494b7ca3206c705c008a02b5124cf" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + pruneopts = "UT" + revision = "740c764bc6149d3f1806231418adb9f52c11bcbf" + +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "UT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + digest = "1:89249eaf359dc2b64431f1d37a8da136ee3714852f9f5bf4bad4a41f160fcac4" + name = "github.com/rackspace/gophercloud" + packages = [ + ".", + "openstack", + "openstack/compute/v2/extensions/floatingip", + "openstack/compute/v2/extensions/keypairs", + "openstack/compute/v2/extensions/startstop", + "openstack/compute/v2/flavors", + "openstack/compute/v2/images", + "openstack/compute/v2/servers", + "openstack/identity/v2/tenants", + "openstack/identity/v2/tokens", + "openstack/identity/v3/tokens", + "openstack/networking/v2/extensions/layer3/floatingips", + "openstack/networking/v2/networks", + "openstack/networking/v2/ports", + "openstack/utils", + "pagination", + "rackspace", + "rackspace/identity/v2/tokens", + "testhelper", + "testhelper/client", + ] + pruneopts = "UT" + revision = "ce0f487f6747ab43c4e4404722df25349385bebd" + +[[projects]] + digest = "1:26409dfc790d25c654c75f396bd0329a10fc487c389ff7837733aea23bfc7880" + name = "github.com/samalba/dockerclient" + packages = ["."] + pruneopts = "UT" + revision = "f661dd4754aa5c52da85d04b5871ee0e11f4b59c" + +[[projects]] + digest = "1:5622116f2c79239f2d25d47b881e14f96a8b8c17b63b8a8326a38ee1a332b007" + name = "github.com/sirupsen/logrus" + packages = ["."] + pruneopts = "UT" + revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba" + version = "v1.0.4" + +[[projects]] + branch = "master" + digest = "1:d72aa3b5f0cf546d1ee54079b31a17f6d3495157a2aaf0d2d7c00954370915df" + name = "github.com/skarademir/naturalsort" + packages = ["."] + pruneopts = "UT" + revision = "69a5d87bef620f77ee8508db30c846b3b84b111e" + +[[projects]] + digest = "1:9bf0f8c6684cd6cb34d838c6f8a07043d6c48be79ffe271cae99633990f8d786" + name = "github.com/stretchr/objx" + packages = ["."] + pruneopts = "UT" + revision = "1a9d0bb9f541897e62256577b352fdbc1fb4fd94" + +[[projects]] + digest = "1:ce346aa04e3c6989aa128ec6778fb4dff403e3077d48e5204c96704f35efe2e0" + name = "github.com/stretchr/testify" + packages = [ + "assert", + "mock", + ] + pruneopts = "UT" + revision = "1f4a1643a57e798696635ea4c126e9127adb7d3c" + +[[projects]] + branch = "master" + digest = "1:595e123593925253dd02152777ddb8cd42300c4f61e783e163b053802547c47c" + name = "github.com/tent/http-link-go" + packages = ["."] + pruneopts = "UT" + revision = "ac974c61c2f990f4115b119354b5e0b47550e888" + +[[projects]] + digest = "1:0f79aac7325bae1fd3c5b3013d886a212a3a81471a8381058d1f6a455bc158a6" + name = "github.com/vmware/govcloudair" + packages = [ + ".", + "types/v56", + ] + pruneopts = "UT" + revision = "66a23eaabc61518f91769939ff541886fe1dceef" + version = "v0.0.2" + +[[projects]] + digest = "1:46a5783efbdb552f34f2fcac90f3b0bbe790a169153706be69bf22dabdcbf337" + name = "github.com/vmware/govmomi" + packages = [ + ".", + "find", + "guest", + "list", + "object", + "property", + "session", + "task", + "vim25", + "vim25/debug", + "vim25/methods", + "vim25/mo", + "vim25/progress", + "vim25/soap", + "vim25/types", + "vim25/xml", + ] + pruneopts = "UT" + revision = "9051bd6b44125d9472e0c148b5965692ab283d4a" + version = "v0.6.2" + +[[projects]] + digest = "1:c520e4d4fc9976e4da44ee0a3bdd5a45e8a206a72c1ccd2089f3d184f5eb942a" + name = "golang.org/x/crypto" + packages = [ + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "ssh", + "ssh/terminal", + ] + pruneopts = "UT" + revision = "51714a8c4ac1764f07ab4127d7f739351ced4759" + +[[projects]] + digest = "1:8e965c5396cf5304c8a3473adfd4a70c0a2a15df6a1448492f3472b50414779e" + name = "golang.org/x/net" + packages = [ + "context", + "context/ctxhttp", + ] + pruneopts = "UT" + revision = "4f2fc6c1e69d41baf187332ee08fbd2b296f21ed" + +[[projects]] + digest = "1:5b9c174f7602d8927abd72ed7095e16249fd87da044a7f9d9f8f6cb9f737719a" + name = "golang.org/x/oauth2" + packages = [ + ".", + "google", + "internal", + "jws", + "jwt", + ] + pruneopts = "UT" + revision = "442624c9ec9243441e83b374a9e22ac549b5c51d" + +[[projects]] + branch = "master" + digest = "1:524ca168039a413c2a3aded9989f201e869d9d888cbc8e274268f30f66a984cc" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows", + "windows/registry", + ] + pruneopts = "UT" + revision = "37707fdb30a5b38865cfb95e5aab41707daec7fd" + +[[projects]] + branch = "master" + digest = "1:ee95e00dab6de32d68fa8743b99f11edbac3bc9e65e0261cafb8750b313a14bb" + name = "google.golang.org/api" + packages = [ + "compute/v1", + "gensupport", + "googleapi", + "googleapi/internal/uritemplates", + ] + pruneopts = "UT" + revision = "87a2f5c77b3602f3ae7c8dca6d76f9c2b9bc0957" + +[[projects]] + digest = "1:08250caf23d0b98c5aec610449d7a8b5c8f7809a55f1ecaa612a0f1b790ecb5d" + name = "google.golang.org/appengine" + packages = [ + ".", + "internal", + "internal/app_identity", + "internal/base", + "internal/datastore", + "internal/log", + "internal/modules", + "internal/remote_api", + "internal/urlfetch", + "urlfetch", + ] + pruneopts = "UT" + revision = "6a436539be38c296a8075a871cc536686b458371" + +[[projects]] + digest = "1:0b8b0eb3466e09a0aa705b86fa1bd25e8562395cc4034a2dceb297f3ef65e8d3" + name = "google.golang.org/cloud" + packages = [ + "compute/metadata", + "internal", + ] + pruneopts = "UT" + revision = "975617b05ea8a58727e6c1a06b6161ff4185a9f2" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/Azure/azure-sdk-for-go/arm/compute", + "github.com/Azure/azure-sdk-for-go/arm/network", + "github.com/Azure/azure-sdk-for-go/arm/resources/resources", + "github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions", + "github.com/Azure/azure-sdk-for-go/arm/storage", + "github.com/Azure/azure-sdk-for-go/storage", + "github.com/Azure/go-autorest/autorest", + "github.com/Azure/go-autorest/autorest/azure", + "github.com/Azure/go-autorest/autorest/to", + "github.com/aws/aws-sdk-go/aws", + "github.com/aws/aws-sdk-go/aws/awserr", + "github.com/aws/aws-sdk-go/aws/credentials", + "github.com/aws/aws-sdk-go/aws/session", + "github.com/aws/aws-sdk-go/service/ec2", + "github.com/bugsnag/bugsnag-go", + "github.com/codegangsta/cli", + "github.com/digitalocean/godo", + "github.com/docker/docker/pkg/term", + "github.com/exoscale/egoscale", + "github.com/intel-go/cpuid", + "github.com/rackspace/gophercloud", + "github.com/rackspace/gophercloud/openstack", + "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip", + "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs", + "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop", + "github.com/rackspace/gophercloud/openstack/compute/v2/flavors", + "github.com/rackspace/gophercloud/openstack/compute/v2/images", + "github.com/rackspace/gophercloud/openstack/compute/v2/servers", + "github.com/rackspace/gophercloud/openstack/identity/v2/tenants", + "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", + "github.com/rackspace/gophercloud/openstack/networking/v2/networks", + "github.com/rackspace/gophercloud/openstack/networking/v2/ports", + "github.com/rackspace/gophercloud/pagination", + "github.com/rackspace/gophercloud/rackspace", + "github.com/samalba/dockerclient", + "github.com/skarademir/naturalsort", + "github.com/stretchr/testify/assert", + "github.com/stretchr/testify/mock", + "github.com/vmware/govcloudair", + "github.com/vmware/govmomi", + "github.com/vmware/govmomi/find", + "github.com/vmware/govmomi/guest", + "github.com/vmware/govmomi/object", + "github.com/vmware/govmomi/vim25/mo", + "github.com/vmware/govmomi/vim25/soap", + "github.com/vmware/govmomi/vim25/types", + "golang.org/x/crypto/ssh", + "golang.org/x/crypto/ssh/terminal", + "golang.org/x/net/context", + "golang.org/x/oauth2", + "golang.org/x/oauth2/google", + "golang.org/x/sys/windows/registry", + "google.golang.org/api/compute/v1", + "google.golang.org/api/googleapi", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000000..f083c85ae5 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,39 @@ +[[constraint]] + name = "github.com/Azure/azure-sdk-for-go" + version = "5.0.0-beta" + +[[constraint]] + name = "github.com/Azure/go-autorest" + version = "7.2.1" + +[[constraint]] + name = "github.com/aws/aws-sdk-go" + version = "1.4.10" + +[[constraint]] + branch = "master" + name = "github.com/docker/docker" + +[[constraint]] + name = "github.com/exoscale/egoscale" + version = "0.9.23" + +[[constraint]] + branch = "master" + name = "github.com/skarademir/naturalsort" + +[[constraint]] + name = "github.com/vmware/govcloudair" + version = "0.0.2" + +[[constraint]] + name = "github.com/vmware/govmomi" + version = "0.6.2" + +[[constraint]] + name = "github.com/intel-go/cpuid" + branch = "master" + +[prune] + go-tests = true + unused-packages = true diff --git a/MAINTAINERS b/MAINTAINERS index f15d314015..bc91f51300 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1,2 +1,37 @@ -Ben Firshman (@bfirsh) -Evan Hazlett (@ehazlett) +# Machine maintainers file +# +# This file describes who runs the docker/machine project and how. +# This is a living document - if you see something out of date or missing, speak up! +# +# It is structured to be consumable by both humans and programs. +# To extract its contents programmatically, use any TOML-compliant parser. +# +# This file is compiled into the MAINTAINERS file in docker/opensource. +# +[Org] + [Org."Core maintainers"] + people = [ + "jeanlaurent", + ] + + [Org.Alumni] + people = [ + "shin-", + ] +[people] + +# A reference list of all people associated with the project. +# All other sections should refer to people by their canonical key +# in the people section. + + # ADD YOURSELF HERE IN ALPHABETICAL ORDER + + [people.jeanlaurent] + Name = "Jean-Laurent de Morlhon" + Email = "jeanlaurent@docker.com" + GitHub = "jeanlaurent" + + [people.shin-] + Name = "Joffrey F" + Email = "f.joffrey@gmail.com" + GitHub = "shin-" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..5bbe5b00c1 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +# Plain make targets if not requested inside a container +ifneq (,$(findstring test-integration,$(MAKECMDGOALS))) + include Makefile.inc + include mk/main.mk +else ifneq ($(USE_CONTAINER), true) + include Makefile.inc + include mk/main.mk +else +# Otherwise, with docker, swallow all targets and forward into a container +DOCKER_BUILD_DONE := "" + +test: .DEFAULT + +.DEFAULT: + @test ! -z "$(DOCKER_BUILD_DONE)" || ./script/build_in_container.sh $(MAKECMDGOALS) + $(eval DOCKER_BUILD_DONE := "done") + +endif diff --git a/Makefile.inc b/Makefile.inc new file mode 100644 index 0000000000..f09616bd1b --- /dev/null +++ b/Makefile.inc @@ -0,0 +1,31 @@ +# Project name, used to name the binaries +PKG_NAME := docker-machine + +# If true, disable optimizations and does NOT strip the binary +DEBUG ?= +# If true, "build" will produce a static binary (cross compile always produce static build regardless) +STATIC ?= +# If true, turn on verbose output for build +VERBOSE ?= +# Build tags +BUILDTAGS ?= +# Adjust number of parallel builds (XXX not used) +PARALLEL ?= -1 +# Coverage default directory +COVERAGE_DIR ?= cover +# Whether to perform targets inside a docker container, or natively on the host +USE_CONTAINER ?= + +# List of cross compilation targets +ifeq ($(TARGET_OS),) + TARGET_OS := darwin linux windows +endif + +ifeq ($(TARGET_ARCH),) + TARGET_ARCH := amd64 arm arm64 386 +endif + +# Output prefix, defaults to local directory if not specified +ifeq ($(PREFIX),) + PREFIX := $(shell pwd) +endif diff --git a/README.md b/README.md index 1a89258ac7..ef64b66a52 100644 --- a/README.md +++ b/README.md @@ -1,326 +1,143 @@ # Docker Machine -Machine makes it really easy to create Docker hosts on local hypervisors and cloud providers. It creates servers, installs Docker on them, then configures the Docker client to talk to them. +![](https://docs.docker.com/machine/img/logo.png) + +Machine lets you create Docker hosts on your computer, on cloud providers, and +inside your own data center. It creates servers, installs Docker on them, then +configures the Docker client to talk to them. It works a bit like this: ```console -$ docker-machine create -d virtualbox dev -[info] Downloading boot2docker... -[info] Creating SSH key... -[info] Creating VirtualBox VM... -[info] Starting VirtualBox VM... -[info] Waiting for VM to start... -[info] "dev" has been created and is now the active host. Docker commands will now run against that host. +$ docker-machine create -d virtualbox default +Running pre-create checks... +Creating machine... +(default) Creating VirtualBox VM... +(default) Creating SSH key... +(default) Starting VM... +Waiting for machine to be running, this may take a few minutes... +Machine is running, waiting for SSH to be available... +Detecting operating system of created instance... +Detecting the provisioner... +Provisioning with boot2docker... +Copying certs to the local machine directory... +Copying certs to the remote machine... +Setting Docker configuration on the remote daemon... +Checking connection to Docker... +Docker is up and running! +To see how to connect Docker to this machine, run: docker-machine env default $ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Running tcp://192.168.99.100:2375 - -$ docker $(docker-machine config dev) run busybox echo hello world -Unable to find image 'busybox' locally -Pulling repository busybox -e72ac664f4f0: Download complete -511136ea3c5a: Download complete -df7546f9f060: Download complete -e433a6c5b276: Download complete -hello world +NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS +default - virtualbox Running tcp://192.168.99.188:2376 v1.9.1 -$ docker-machine create -d digitalocean --digitalocean-access-token=... staging -[info] Creating SSH key... -[info] Creating Digital Ocean droplet... -[info] Waiting for SSH... -[info] "staging" has been created and is now the active host. Docker commands will now run against that host. +$ eval "$(docker-machine env default)" -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev virtualbox Running tcp://192.168.99.108:2376 -staging * digitalocean Running tcp://104.236.37.134:2376 +$ docker run busybox echo hello world +Unable to find image 'busybox:latest' locally +511136ea3c5a: Pull complete +df7546f9f060: Pull complete +ea13149945cb: Pull complete +4986bf8c1536: Pull complete +hello world ``` -Machine creates Docker hosts that are secure by default. The connection between the client and daemon is encrypted and authenticated using TLS security. To get the Docker arguments for a machine use the command: `docker-machine config ` i.e. `docker-machine config dev`. - -You can also get the commands to export environment variables to use with the Docker CLI: `docker-machine env ` i.e. `docker-machine env dev` to show or `$(docker-machine env dev)` to load in your environment. - -## Try it out - -Machine is still in its early stages. If you'd like to try out a preview build, [download it here](https://github.com/docker/machine/releases/latest). - -## Drivers - -### VirtualBox - -Creates machines locally on [VirtualBox](https://www.virtualbox.org/). Requires VirtualBox to be installed. - -Options: - - - `--virtualbox-boot2docker-url`: The URL of the boot2docker image. Defaults to the latest available version. - - `--virtualbox-disk-size`: Size of disk for the host in MB. Default: `20000` - - `--virtualbox-memory`: Size of memory for the host in MB. Default: `1024` - -### Digital Ocean - -Creates machines on [Digital Ocean](https://www.digitalocean.com/). You need to create a personal access token under "Apps & API" in the Digital Ocean Control Panel and pass that to `docker-machine create` with the `--digitalocean-access-token` option. - -Options: - - - `--digitalocean-access-token`: Your personal access token for the Digital Ocean API. - - `--digitalocean-image`: The name of the Digital Ocean image to use. Default: `docker` - - `--digitalocean-region`: The region to create the droplet in. Default: `nyc3` - - `--digitalocean-size`: The size of the Digital Ocean driver. Default: `512mb` - -### Microsoft Azure - -Create machines on [Microsoft Azure](http://azure.microsoft.com/). - -You need to create a subscription with a cert. Run these commands: - - $ openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem - $ openssl pkcs12 -export -out mycert.pfx -in mycert.pem -name "My Certificate" - $ openssl x509 -inform pem -in mycert.pem -outform der -out mycert.cer - -Go to the Azure portal, go to the "Settings" page, then "Manage Certificates" and upload `mycert.cer`. - -Grab your subscription ID from the portal, then run `docker-machine create` with these details: - - $ docker-machine create -d azure --azure-subscription-id="SUB_ID" --azure-subscription-cert="mycert.pem" - -Options: - - - `--azure-subscription-id`: **required** Your Azure subscription ID. - - `--azure-subscription-cert`: **required** Your Azure subscription cert. - - `--azure-docker-port`: Azure Docker port. Default '2376' - - `--azure-image`: Azure image name. Default is Ubuntu 14.04 LTS x64 [$AZURE_IMAGE] - - `--azure-location`: Azure location. Default is 'West US' [$AZURE_LOCATION] - - `--azure-name`: Azure cloud service name - - `--azure-password`: Azure user password - - `--azure-publish-settings-file`: Azure publish settings file [$AZURE_PUBLISH_SETTINGS_FILE] - - `--azure-size`: Azure size. Default 'Small' [$AZURE_SIZE] - - `--azure-ssh-port`: Azure SSH port. Default '22' - - `--azure-username`: Azure username. Default 'ubuntu' - -Note: the machine name will be used as DNS name for the Cloud Service (e.g. machinename.cloudapp.net) and needs to be unique within Azure. - -### Amazon EC2 - -Create machines on [Amazon Web Services](http://aws.amazon.com). You will need an Access Key ID, Secret Access Key and a VPC ID. To find the VPC ID, login to the AWS console and go to Services -> VPC -> Your VPCs. Select the one where you would like to launch the instance. - -Options: - - - `--amazonec2-access-key`: **required** Your access key id for the Amazon Web Services API. - - `--amazonec2-ami`: The AMI ID of the instance to use Default: `ami-4ae27e22` - - `--amazonec2-instance-type`: The instance type to run. Default: `t2.micro` - - `--amazonec2-region`: The region to use when launching the instance. Default: `us-east-1` - - `--amazonec2-root-size`: The root disk size of the instance (in GB). Default: `16` - - `--amazonec2-secret-key`: **required** Your secret access key for the Amazon Web Services API. - - `--amazonec2-security-group-name`: AWS VPC security group name. Default: `docker-machine` - - `--amazonec2-session-token`: Your session token for the Amazon Web Services API. - - `--amazonec2-subnet-id`: AWS VPC subnet id - - `--amazonec2-vpc-id`: **required** Your VPC ID to launch the instance in. - - `--amazonec2-zone`: The AWS zone launch the instance in (i.e. one of a,b,c,d,e). Default: `a` - -### Google Compute Engine - -Create machines on [Google Compute Engine](https://cloud.google.com/compute/). You will need a Google account and project name. See https://cloud.google.com/compute/docs/projects for details on projects. - -The Google driver uses oAuth. When creating the machine, you will have your browser opened to authorize. Once authorized, paste the code given in the prompt to launch the instance. - -Options: - - - `--google-zone`: The zone to launch the instance. Default: `us-central1-a` - - `--google-machine-type`: The type of instance. Default: `f1-micro` - - `--google-username`: The username to use for the instance. Default: `docker-user` - - `--google-instance-name`: The name of the instance. Default: `docker-machine` - - `--google-project`: The name of your project to use when launching the instance. - -### VMware Fusion - -Creates machines locally on [VMware Fusion](http://www.vmware.com/products/fusion). Requires VMware Fusion to be installed. - -Options: - - - `--vmwarefusion-boot2docker-url`: URL for boot2docker image. - - `--vmwarefusion-disk-size`: Size of disk for host VM (in MB). Default: `20000` - - `--vmwarefusion-memory-size`: Size of memory for host VM (in MB). Default: `1024` +In addition to local VMs, you can create and manage cloud servers: -### VMware vCloud Air - -Creates machines on [vCloud Air](http://vcloud.vmware.com) subscription service. You need an account within an existing subscription of vCloud Air VPC or Dedicated Cloud. - -Options: - - - `--vmwarevcloudair-username`: vCloud Air Username. - - `--vmwarevcloudair-password`: vCloud Air Password. - - `--vmwarevcloudair-catalog`: Catalog. Default: `Public Catalog` - - `--vmwarevcloudair-catalogitem`: Catalog Item. Default: `Ubuntu Server 12.04 LTS (amd64 20140927)` - - `--vmwarevcloudair-computeid`: Compute ID (if using Dedicated Cloud). - - `--vmwarevcloudair-cpu-count`: VM Cpu Count. Default: `1` - - `--vmwarevcloudair-docker-port`: Docker port. Default: `2376` - - `--vmwarevcloudair-edgegateway`: Organization Edge Gateway. Default: `` - - `--vmwarevcloudair-memory-size`: VM Memory Size in MB. Default: `2048` - - `--vmwarevcloudair-name`: vApp Name. Default: `` - - `--vmwarevcloudair-orgvdcnetwork`: Organization VDC Network to attach. Default: `-default-routed` - - `--vmwarevcloudair-provision`: Install Docker binaries. Default: `true` - - `--vmwarevcloudair-publicip`: Org Public IP to use. - - `--vmwarevcloudair-ssh-port`: SSH port. Default: `22` - - `--vmwarevcloudair-vdcid`: Virtual Data Center ID. - -### VMware vSphere - -Creates machines on a [VMware vSphere](http://www.vmware.com/products/vsphere) Virtual Infrastructure. Requires a working vSphere (ESXi and optionally vCenter) installation. The vSphere driver depends on [`govc`](https://github.com/vmware/govmomi/tree/master/govc) (must be in path) and has been tested with [vmware/govmomi@`c848630`](https://github.com/vmware/govmomi/commit/c8486300bfe19427e4f3226e3b3eac067717ef17). - -Options: - - - `--vmwarevsphere-username`: vSphere Username. - - `--vmwarevsphere-password`: vSphere Password. - - `--vmwarevsphere-boot2docker-url`: URL for boot2docker image. - - `--vmwarevsphere-compute-ip`: Compute host IP where the Docker VM will be instantiated. - - `--vmwarevsphere-cpu-count`: CPU number for Docker VM. Default: `2` - - `--vmwarevsphere-datacenter`: Datacenter for Docker VM (must be set to `ha-datacenter` when connecting to a single host). - - `--vmwarevsphere-datastore`: Datastore for Docker VM. - - `--vmwarevsphere-disk-size`: Size of disk for Docker VM (in MB). Default: `20000` - - `--vmwarevsphere-memory-size`: Size of memory for Docker VM (in MB). Default: `2048` - - `--vmwarevsphere-network`: Network where the Docker VM will be attached. - - `--vmwarevsphere-pool`: Resource pool for Docker VM. - - `--vmwarevsphere-vcenter`: IP/hostname for vCenter (or ESXi if connecting directly to a single host). - -### OpenStack - -Create machines on [Openstack](http://www.openstack.org/software/) - -Mandatory: - - - `--openstack-flavor-id`: The flavor ID to use when creating the machine - - `--openstack-image-id`: The image ID to use when creating the machine. - -Options: - - - `--openstack-auth-url`: Keystone service base URL. - - `--openstack-username`: User identifer to authenticate with. - - `--openstack-password`: User password. It can be omitted if the standard environment variable `OS_PASSWORD` is set. - - `--openstack-tenant-name` or `--openstack-tenant-id`: Identify the tenant in which the machine will be created. - - `--openstack-region`: The region to work on. Can be omitted if there is ony one region on the OpenStack. - - `--openstack-endpoint-type`: Endpoint type can be `internalURL`, `adminURL` or `publicURL`. It is a helper for the driver - to choose the right URL in the OpenStack service catalog. If not provided the default is `publicURL`. - - `--openstack-net-id`: The private network id the machine will be connected on. If your OpenStack project - contains only one private network it will be use automatically. - - `--openstack-sec-groups`: If security groups are available on your OpenStack you can specify a comma separated list - to use for the machine (e.g. `secgrp001,secgrp002`). - - `--openstack-floatingip-pool`: The IP pool that will be used to get a public IP and assign it to the machine. If there is an - IP address already allocated but not assigned to any machine, this IP will be chosen and assigned to the machine. If - there is no IP address already allocated a new IP will be allocated and assigned to the machine. - - `--openstack-ssh-user`: The username to use for SSH into the machine. If not provided `root` will be used. - - `--openstack-ssh-port`: Customize the SSH port if the SSH server on the machine does not listen on the default port. - - `--openstack-docker-install`: Boolean flag to indicate if docker has to be installed on the machine. Useful when - docker is already installed and configured in the OpenStack image. Default set to `true` - -Environment variables: - -Here comes the list of the supported variables with the corresponding options. If both environment variable -and CLI option are provided the CLI option takes the precedence. - -| Environment variable | CLI option | -|----------------------|-----------------------------| -| `OS_AUTH_URL` | `--openstack-auth-url` | -| `OS_USERNAME` | `--openstack-username` | -| `OS_PASSWORD` | `--openstack-password` | -| `OS_TENANT_NAME` | `--openstack-tenant-name` | -| `OS_TENANT_ID` | `--openstack-tenant-id` | -| `OS_REGION_NAME` | `--openstack-region` | -| `OS_ENDPOINT_TYPE` | `--openstack-endpoint-type` | - -### Rackspace - -Create machines on [Rackspace cloud](http://www.rackspace.com/cloud) - -Options: - - - `--rackspace-username`: Rackspace account username - - `--rackspace-api-key`: Rackspace API key - - `--rackspace-region`: Rackspace region name - - `--rackspace-endpoint-type`: Rackspace endpoint type (adminURL, internalURL or the default publicURL) - - `--rackspace-image-id`: Rackspace image ID. Default: Ubuntu 14.10 (Utopic Unicorn) (PVHVM) - - `--rackspace-flavor-id`: Rackspace flavor ID. Default: General Purpose 1GB - - `--rackspace-ssh-user`: SSH user for the newly booted machine. Set to root by default - - `--rackspace-ssh-port`: SSH port for the newly booted machine. Set to 22 by default - -Environment variables: - -Here comes the list of the supported variables with the corresponding options. If both environment -variable and CLI option are provided the CLI option takes the precedence. - -| Environment variable | CLI option | -|----------------------|-----------------------------| -| `OS_USERNAME` | `--rackspace-username` | -| `OS_API_KEY` | `--rackspace-ap-key` | -| `OS_REGION_NAME` | `--rackspace-region` | -| `OS_ENDPOINT_TYPE` | `--rackspace-endpoint-type` | - -### Softlayer +```console +$ docker-machine create -d digitalocean --digitalocean-access-token=secret staging +Creating SSH key... +Creating Digital Ocean droplet... +To see how to connect Docker to this machine, run: docker-machine env staging -Create machines on [Softlayer](http://softlayer.com). +$ docker-machine ls +NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS +default - virtualbox Running tcp://192.168.99.188:2376 v1.9.1 +staging - digitalocean Running tcp://203.0.113.81:2376 v1.9.1 +``` -You need to generate an API key in the softlayer control panel. -[Retrieve your API key](http://knowledgelayer.softlayer.com/procedure/retrieve-your-api-key) +## Installation and documentation -Options: - - `--softlayer-api-endpoint=`: Change softlayer API endpoint - - `--softlayer-user`: **required** username for your softlayer account, api key needs to match this user. - - `--softlayer-api-key`: **required** API key for your user account - - `--softlayer-cpu`: Number of CPU's for the machine. - - `--softlayer-disk-size: Size of the disk in MB. `0` sets the softlayer default. - - `--softlayer-domain`: **required** domain name for the machine - - `--softlayer-hostname`: hostname for the machine - - `--softlayer-hourly-billing`: Sets the hourly billing flag (default), otherwise uses monthly billing - - `--softlayer-image`: OS Image to use - - `--softlayer-install-script`: custom install script to use for installing Docker, other setup actions - - `--softlayer-local-disk`: Use local machine disk instead of softlayer SAN. - - `--softlayer-memory`: Memory for host in MB - - `--softlayer-private-net-only`: Disable public networking - - `--softlayer-region`: softlayer region +Full documentation [is available here](https://docs.docker.com/machine/). ## Contributing -[![GoDoc](https://godoc.org/github.com/docker/machine?status.png)](https://godoc.org/github.com/docker/machine) -[![Build Status](https://travis-ci.org/docker/machine.svg?branch=master)](https://travis-ci.org/docker/machine) - -Want to hack on Machine? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply. - -The requirements to build Machine are: - -1. A running instance of Docker -2. The `bash` shell +Want to hack on Machine? Please start with the [Contributing Guide](https://github.com/docker/machine/blob/master/CONTRIBUTING.md). + +## Driver Plugins + +In addition to the core driver plugins bundled alongside Docker Machine, users +can make and distribute their own plugin for any virtualization technology or +cloud provider. To browse the list of known Docker Machine plugins, please [see +this document in our +docs repo](https://github.com/docker/docker.github.io/blob/master/machine/AVAILABLE_DRIVER_PLUGINS.md). + +## Troubleshooting + +Docker Machine tries to do the right thing in a variety of scenarios but +sometimes things do not go according to plan. Here is a quick troubleshooting +guide which may help you to resolve of the issues you may be seeing. + +Note that some of the suggested solutions are only available on the Docker +Machine master branch. If you need them, consider compiling Docker Machine from +source. +#### `docker-machine` hangs + +A common issue with Docker Machine is that it will hang when attempting to start +up the virtual machine. Since starting the machine is part of the `create` +process, `create` is often where these types of errors show up. + +A hang could be due to a variety of factors, but the most common suspect is +networking. Consider the following: + +- Are you using a VPN? If so, try disconnecting and see if creation will + succeed without the VPN. Some VPN software aggressively controls routes and + you may need to [manually add the route](https://github.com/docker/machine/issues/1500#issuecomment-121134958). +- Are you connected to a proxy server, corporate or otherwise? If so, take a + look at the `--no-proxy` flag for `env` and at [setting environment variables + for the created Docker Engine](https://docs.docker.com/machine/reference/create/#specifying-configuration-options-for-the-created-docker-engine). +- Are there a lot of host-only interfaces listed by the command `VBoxManage list + hostonlyifs`? If so, this has sometimes been known to cause bugs. Consider + removing the ones you are not using (`VBoxManage hostonlyif remove name`) and + trying machine creation again. + +We are keenly aware of this as an issue and working towards a set of solutions +which is robust for all users, so please give us feedback and/or report issues, +workarounds, and desired workflows as you discover them. + +#### Machine creation errors out before finishing + +If you see messages such as "exit status 1" creating machines with VirtualBox, +this frequently indicates that there is an issue with VirtualBox itself. Please +[file an issue](https://github.com/docker/machine/issues/new) and include a link +to a [Github Gist](https://gist.github.com/) with the output of the VirtualBox +log (usually located at +`$HOME/.docker/machine/machines/machinename/machinename/Logs/VBox.log`), as well +as the output of running the Docker Machine command which is failing with the +global `--debug` flag enabled. This will help us to track down which versions +of VirtualBox are failing where, and under which conditions. + +If you see messages such as "exit status 255", this frequently indicates there +has been an issue with SSH. Please investigate your SSH configuration if you +have one, and/or [file an issue](https://github.com/docker/machine/issues). + +#### "You may be getting rate limited by Github" error message + +In order to `create` or `upgrade` virtual machines running Docker, Docker +Machine will check the Github API for the latest release of the [boot2docker +operating system](https://github.com/boot2docker/boot2docker). The Github API +allows for a small number of unauthenticated requests from a given client, but +if you share an IP address with many other users (e.g. in an office), you may +get rate limited by their API, and Docker Machine will error out with messages +indicating this. + +In order to work around this issue, you can [generate a +token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/) +and pass it to Docker Machine using the global `--github-api-token` flag like +so: -To build, run: - - $ script/build - -From the Machine repository's root. Machine will run the build inside of a -Docker container and the compiled binaries will appear in the project directory -on the host. - -By default, Machine will run a build which cross-compiles binaries for a variety -of architectures and operating systems. If you know that you are only compiling -for a particular architecture and/or operating system, you can speed up -compilation by overriding the default argument that the build script passes -to [gox](https://github.com/mitchellh/gox). This is very useful if you want -to iterate quickly on a new feature, bug fix, etc. - -For instance, if you only want to compile for use on OSX with the x86_64 arch, -run: - - $ script/build -osarch="darwin/amd64" - -If you have any questions we're in #docker-machine on Freenode. - -## Integration Tests -There is a suite of integration tests that will run for the drivers. In order -to use these you must export the corresponding environment variables for each -driver as these perform the actual actions (start, stop, restart, kill, etc). - -By default, the suite will run tests against all drivers in master. You can -override this by setting the environment variable `MACHINE_TESTS`. For example, -`MACHINE_TESTS="virtualbox" ./script/run-integration-tests` will only run the -virtualbox driver integration tests. +```console +$ docker-machine --github-api-token=token create -d virtualbox newbox +``` -To run, use the helper script `./script/run-integration-tests`. +This should eliminate any issues you've been experiencing with rate limiting. diff --git a/ROADMAP.md b/ROADMAP.md index b620b2b815..7f9d4a99e1 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,22 +1,34 @@ -# Roadmap +# Machine Roadmap +Machine currently works really well for development and test environments. The +goal is to make it work better for provisioning and managing production +environments. -## Machine 1.0 +This is not a simple task -- production is inherently far more complex than +development -- but there are three things which are big steps towards that goal: +**client/server architecture**, **swarm integration** and **flexible +provisioning**. -This will be a stable version of the current design with additional drivers and complete documentation. +(Note: this document is a high-level overview of where we are taking Machine. +For what is coming in specific releases, see our [upcoming +milestones](https://github.com/docker/machine/milestones).) -You can follow progress towards this release with the [GitHub milestone](https://github.com/docker/machine/milestones/1.0). +### Docker Engine / Swarm Configuration -## Future +Currently there are only a few things that can be configured in the Docker Engine and Swarm. This will enable more operations such as Engine labels and Swarm strategies. -There are two main areas for future development: +### Boot2Docker Migration Support - - **Machine server:** Machine currently relies on storing configuration locally on the computer that the command-line client is run which makes it difficult to use in teams and for large deployments. - - Machines should instead be managed by a central server with a REST API. The command-line client would be a client for this server. To keep the current behaviour, and to manage local VMs, the server could run in an embedded mode inside the client. +Currently both Machine and Boot2Docker provider similar functionality. This will enable users to migrate from boot2docker to machine. - - **Swarm integration:** Machine should be able to create and manage [Swarm](https://github.com/docker/swarm) clusters. Perhaps it's even the default. Imagine this: +### Expand Provisioner - $ docker-machine create -d digitalocean production - $ docker-machine scale production=100 +Machine currently supports running Boot2Docker for "local" providers and Ubuntu for "remote" providers. This will expand the provisioning capabilities to include other base operating systems such as Red Hat-like distributions and possibly other "just enough" operating systems. +### Windows Experience + +Currently, the Machine on Windows experience is not as good as the Mac / Linux. There is no "recommended" path to use Machine and there are several inconsistencies on Windows such as logging and output formatting. + +# Project Planning + +An [Open-Source Planning Process](https://github.com/docker/machine/wiki/Open-Source-Planning-Process) is used to define the Roadmap. [Project Pages](https://github.com/docker/machine/wiki) define the goals for each Milestone and identify current progress. diff --git a/_integration-test/machine_test.go b/_integration-test/machine_test.go deleted file mode 100644 index c09fa0267a..0000000000 --- a/_integration-test/machine_test.go +++ /dev/null @@ -1,157 +0,0 @@ -package main - -import ( - "fmt" - "os/exec" - "sync" - "testing" - "time" -) - -var ( - machineName = fmt.Sprintf("machine-test-%d", time.Now().UnixNano()) + "-%s" -) - -func machineCreate(name string, t *testing.T, wg *sync.WaitGroup) { - mName := fmt.Sprintf(machineName, name) - fmt.Printf(" - testing create for %s (%s)\n", name, mName) - runCmd := exec.Command(machineBinary, "create", "-d", name, mName) - out, exitCode, err := runCommandWithOutput(runCmd) - if err != nil { - t.Error(out, err) - } - if exitCode != 0 { - t.Errorf("error creating machine: driver: %s; exit code: %d; output: %s", name, exitCode, out) - } - wg.Done() -} - -func machineStop(name string, t *testing.T, wg *sync.WaitGroup) { - mName := fmt.Sprintf(machineName, name) - fmt.Printf(" - testing stop for %s (%s)\n", name, mName) - runCmd := exec.Command(machineBinary, "stop", mName) - out, exitCode, err := runCommandWithOutput(runCmd) - if err != nil { - t.Error(out, err) - } - if exitCode != 0 { - t.Errorf("error stopping machine: driver: %s; exit code: %d; output: %s", name, exitCode, out) - } - wg.Done() -} - -func machineStart(name string, t *testing.T, wg *sync.WaitGroup) { - mName := fmt.Sprintf(machineName, name) - fmt.Printf(" - testing start for %s (%s)\n", name, mName) - runCmd := exec.Command(machineBinary, "start", mName) - out, exitCode, err := runCommandWithOutput(runCmd) - if err != nil { - t.Error(out, err) - } - if exitCode != 0 { - t.Errorf("error starting machine: driver: %s; exit code: %d; output: %s", name, exitCode, out) - } - wg.Done() -} - -func machineKill(name string, t *testing.T, wg *sync.WaitGroup) { - mName := fmt.Sprintf(machineName, name) - fmt.Printf(" - testing kill for %s (%s)\n", name, mName) - runCmd := exec.Command(machineBinary, "kill", mName) - out, exitCode, err := runCommandWithOutput(runCmd) - if err != nil { - t.Error(out, err) - } - if exitCode != 0 { - t.Errorf("error killing machine: driver: %s; exit code: %d; output: %s", name, exitCode, out) - } - wg.Done() -} - -func machineRm(name string, t *testing.T, wg *sync.WaitGroup) { - mName := fmt.Sprintf(machineName, name) - fmt.Printf(" - testing rm for %s (%s)\n", name, mName) - runCmd := exec.Command(machineBinary, "rm", "-f", mName) - out, exitCode, err := runCommandWithOutput(runCmd) - if err != nil { - t.Error(out, err) - } - if exitCode != 0 { - t.Errorf("error removing machine: driver: %s; exit code: %d; output: %s", name, exitCode, out) - } - wg.Done() -} - -// TestMachineCreate will test that the driver creates the machine -func TestMachineCreate(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - - var wg sync.WaitGroup - for _, d := range machineTestDrivers { - wg.Add(1) - go machineCreate(d.name, t, &wg) - } - wg.Wait() -} - -// TestMachineCreate will test that the driver stops the machine -func TestMachineStop(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - - var wg sync.WaitGroup - for _, d := range machineTestDrivers { - wg.Add(1) - go machineStop(d.name, t, &wg) - } - wg.Wait() - time.Sleep(waitDuration) -} - -// TestMachineCreate will test that the driver starts the machine -func TestMachineStart(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - - var wg sync.WaitGroup - for _, d := range machineTestDrivers { - wg.Add(1) - go machineStart(d.name, t, &wg) - } - wg.Wait() - time.Sleep(waitDuration) -} - -// TestMachineCreate will test that the driver kills the machine -func TestMachineKill(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - - var wg sync.WaitGroup - for _, d := range machineTestDrivers { - wg.Add(1) - go machineKill(d.name, t, &wg) - } - wg.Wait() - time.Sleep(waitDuration) -} - -// TestMachineCreate will test that the driver removes the machine -func TestMachineRemove(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - - var wg sync.WaitGroup - for _, d := range machineTestDrivers { - wg.Add(1) - go machineRm(d.name, t, &wg) - } - wg.Wait() - time.Sleep(waitDuration) -} diff --git a/_integration-test/test_vars.go b/_integration-test/test_vars.go deleted file mode 100644 index 6e86184c54..0000000000 --- a/_integration-test/test_vars.go +++ /dev/null @@ -1,72 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - "strconv" - "strings" - "time" -) - -type ( - MachineDriver struct { - name string - } -) - -var ( - machineBinary = "machine" - machineTestDrivers []MachineDriver - waitInterval int - waitDuration time.Duration -) - -func init() { - // allow filtering driver tests - if machineTests := os.Getenv("MACHINE_TESTS"); machineTests != "" { - tests := strings.Split(machineTests, " ") - for _, test := range tests { - mcn := MachineDriver{ - name: test, - } - machineTestDrivers = append(machineTestDrivers, mcn) - } - } else { - machineTestDrivers = []MachineDriver{ - { - name: "virtualbox", - }, - { - name: "digitalocean", - }, - } - } - - interval := os.Getenv("MACHINE_TEST_DURATION") - if interval == "" { - interval = "30" - } - wait, err := strconv.Atoi(interval) - if err != nil { - fmt.Printf("invalid interval: %s\n", err) - os.Exit(1) - } - - waitInterval = wait - waitDuration = time.Duration(time.Duration(waitInterval) * time.Second) - - // find machine binary - if machineBin := os.Getenv("MACHINE_BINARY"); machineBin != "" { - machineBinary = machineBin - } else { - whichCmd := exec.Command("which", "machine") - out, _, err := runCommandWithOutput(whichCmd) - if err == nil { - machineBinary = stripTrailingCharacters(out) - } else { - fmt.Printf("ERROR: couldn't resolve full path to the Machine binary") - os.Exit(1) - } - } -} diff --git a/_integration-test/utils.go b/_integration-test/utils.go deleted file mode 100644 index d4004e9ad3..0000000000 --- a/_integration-test/utils.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "fmt" - "os/exec" - "strings" - "syscall" -) - -func getExitCode(err error) (int, error) { - exitCode := 0 - if exiterr, ok := err.(*exec.ExitError); ok { - if procExit := exiterr.Sys().(syscall.WaitStatus); ok { - return procExit.ExitStatus(), nil - } - } - return exitCode, fmt.Errorf("failed to get exit code") -} - -func processExitCode(err error) (exitCode int) { - if err != nil { - var exiterr error - if exitCode, exiterr = getExitCode(err); exiterr != nil { - // TODO: Fix this so we check the error's text. - // we've failed to retrieve exit code, so we set it to 127 - exitCode = 127 - } - } - return -} - -func runCommandWithOutput(cmd *exec.Cmd) (output string, exitCode int, err error) { - exitCode = 0 - out, err := cmd.CombinedOutput() - exitCode = processExitCode(err) - output = string(out) - return - -} - -func stripTrailingCharacters(target string) string { - target = strings.Trim(target, "\n") - target = strings.Trim(target, " ") - return target -} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..a32b5620fc --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,18 @@ +version: "{build}" + +skip_tags: true + +os: Windows Server 2012 R2 + +environment: + GOPATH: c:\gopath + +clone_folder: c:\gopath\src\github.com\docker\machine + +build_script: + - go build -i -o ./bin/docker-machine.exe ./cmd/docker-machine + +test_script: + - powershell -Command go test -v ./libmachine/shell + +deploy: off diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000000..f8ce81172c --- /dev/null +++ b/circle.yml @@ -0,0 +1,30 @@ +machine: + pre: + - bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/1.0.22/binscripts/gvm-installer) + + post: + - gvm install go1.7 -B --name=stable + + environment: + CHECKOUT: /home/ubuntu/$CIRCLE_PROJECT_REPONAME + BASE_DIR: src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME + BASE_STABLE: ../../../$HOME/.gvm/pkgsets/stable/global/$BASE_DIR + GO15VENDOREXPERIMENT: 1 + +dependencies: + override: + - > + gvm use stable && + mkdir -p "$(dirname $BASE_STABLE)" && + cp -R "$CHECKOUT" "$BASE_STABLE" + +test: + pre: + - gvm use stable && make build: + pwd: $BASE_STABLE + - gvm use stable && go get github.com/docker/docker-machine-driver-ci-test + + override: + - gvm use stable && PATH=../../../../bin:$PATH DRIVER=ci-test go test -v github.com/docker/machine/its/...: + pwd: $BASE_STABLE + timeout: 600 diff --git a/cmd/docker-machine/machine.go b/cmd/docker-machine/machine.go new file mode 100644 index 0000000000..a80cc334d6 --- /dev/null +++ b/cmd/docker-machine/machine.go @@ -0,0 +1,215 @@ +package main + +import ( + "fmt" + "os" + "strconv" + + "path/filepath" + + "github.com/codegangsta/cli" + "github.com/docker/machine/commands" + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/drivers/amazonec2" + "github.com/docker/machine/drivers/azure" + "github.com/docker/machine/drivers/digitalocean" + "github.com/docker/machine/drivers/exoscale" + "github.com/docker/machine/drivers/generic" + "github.com/docker/machine/drivers/google" + "github.com/docker/machine/drivers/hyperv" + "github.com/docker/machine/drivers/none" + "github.com/docker/machine/drivers/openstack" + "github.com/docker/machine/drivers/rackspace" + "github.com/docker/machine/drivers/softlayer" + "github.com/docker/machine/drivers/virtualbox" + "github.com/docker/machine/drivers/vmwarefusion" + "github.com/docker/machine/drivers/vmwarevcloudair" + "github.com/docker/machine/drivers/vmwarevsphere" + "github.com/docker/machine/libmachine/drivers/plugin" + "github.com/docker/machine/libmachine/drivers/plugin/localbinary" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/version" +) + +var AppHelpTemplate = `Usage: {{.Name}} {{if .Flags}}[OPTIONS] {{end}}COMMAND [arg...] + +{{.Usage}} + +Version: {{.Version}}{{if or .Author .Email}} + +Author:{{if .Author}} + {{.Author}}{{if .Email}} - <{{.Email}}>{{end}}{{else}} + {{.Email}}{{end}}{{end}} +{{if .Flags}} +Options: + {{range .Flags}}{{.}} + {{end}}{{end}} +Commands: + {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} + {{end}} +Run '{{.Name}} COMMAND --help' for more information on a command. +` + +var CommandHelpTemplate = `Usage: docker-machine {{.Name}}{{if .Flags}} [OPTIONS]{{end}} [arg...] + +{{.Usage}}{{if .Description}} + +Description: + {{.Description}}{{end}}{{if .Flags}} + +Options: + {{range .Flags}} + {{.}}{{end}}{{ end }} +` + +func setDebugOutputLevel() { + // TODO: I'm not really a fan of this method and really would rather + // use -v / --verbose TBQH + for _, f := range os.Args { + if f == "-D" || f == "--debug" || f == "-debug" { + log.SetDebug(true) + } + } + + debugEnv := os.Getenv("MACHINE_DEBUG") + if debugEnv != "" { + showDebug, err := strconv.ParseBool(debugEnv) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing boolean value from MACHINE_DEBUG: %s\n", err) + os.Exit(1) + } + log.SetDebug(showDebug) + } +} + +func main() { + if os.Getenv(localbinary.PluginEnvKey) == localbinary.PluginEnvVal { + driverName := os.Getenv(localbinary.PluginEnvDriverName) + runDriver(driverName) + return + } + + localbinary.CurrentBinaryIsDockerMachine = true + + setDebugOutputLevel() + cli.AppHelpTemplate = AppHelpTemplate + cli.CommandHelpTemplate = CommandHelpTemplate + app := cli.NewApp() + app.Name = filepath.Base(os.Args[0]) + app.Author = "Docker Machine Contributors" + app.Email = "https://github.com/docker/machine" + + app.Commands = commands.Commands + app.CommandNotFound = cmdNotFound + app.Usage = "Create and manage machines running Docker." + app.Version = version.FullVersion() + + log.Debug("Docker Machine Version: ", app.Version) + + app.Flags = []cli.Flag{ + cli.BoolFlag{ + Name: "debug, D", + Usage: "Enable debug mode", + }, + cli.StringFlag{ + EnvVar: "MACHINE_STORAGE_PATH", + Name: "storage-path, s", + Value: mcndirs.GetBaseDir(), + Usage: "Configures storage path", + }, + cli.StringFlag{ + EnvVar: "MACHINE_TLS_CA_CERT", + Name: "tls-ca-cert", + Usage: "CA to verify remotes against", + Value: "", + }, + cli.StringFlag{ + EnvVar: "MACHINE_TLS_CA_KEY", + Name: "tls-ca-key", + Usage: "Private key to generate certificates", + Value: "", + }, + cli.StringFlag{ + EnvVar: "MACHINE_TLS_CLIENT_CERT", + Name: "tls-client-cert", + Usage: "Client cert to use for TLS", + Value: "", + }, + cli.StringFlag{ + EnvVar: "MACHINE_TLS_CLIENT_KEY", + Name: "tls-client-key", + Usage: "Private key used in client TLS auth", + Value: "", + }, + cli.StringFlag{ + EnvVar: "MACHINE_GITHUB_API_TOKEN", + Name: "github-api-token", + Usage: "Token to use for requests to the Github API", + Value: "", + }, + cli.BoolFlag{ + EnvVar: "MACHINE_NATIVE_SSH", + Name: "native-ssh", + Usage: "Use the native (Go-based) SSH implementation.", + }, + cli.StringFlag{ + EnvVar: "MACHINE_BUGSNAG_API_TOKEN", + Name: "bugsnag-api-token", + Usage: "BugSnag API token for crash reporting", + Value: "", + }, + } + + if err := app.Run(os.Args); err != nil { + log.Error(err) + } +} + +func runDriver(driverName string) { + switch driverName { + case "amazonec2": + plugin.RegisterDriver(amazonec2.NewDriver("", "")) + case "azure": + plugin.RegisterDriver(azure.NewDriver("", "")) + case "digitalocean": + plugin.RegisterDriver(digitalocean.NewDriver("", "")) + case "exoscale": + plugin.RegisterDriver(exoscale.NewDriver("", "")) + case "generic": + plugin.RegisterDriver(generic.NewDriver("", "")) + case "google": + plugin.RegisterDriver(google.NewDriver("", "")) + case "hyperv": + plugin.RegisterDriver(hyperv.NewDriver("", "")) + case "none": + plugin.RegisterDriver(none.NewDriver("", "")) + case "openstack": + plugin.RegisterDriver(openstack.NewDriver("", "")) + case "rackspace": + plugin.RegisterDriver(rackspace.NewDriver("", "")) + case "softlayer": + plugin.RegisterDriver(softlayer.NewDriver("", "")) + case "virtualbox": + plugin.RegisterDriver(virtualbox.NewDriver("", "")) + case "vmwarefusion": + plugin.RegisterDriver(vmwarefusion.NewDriver("", "")) + case "vmwarevcloudair": + plugin.RegisterDriver(vmwarevcloudair.NewDriver("", "")) + case "vmwarevsphere": + plugin.RegisterDriver(vmwarevsphere.NewDriver("", "")) + default: + fmt.Fprintf(os.Stderr, "Unsupported driver: %s\n", driverName) + os.Exit(1) + } +} + +func cmdNotFound(c *cli.Context, command string) { + log.Errorf( + "%s: '%s' is not a %s command. See '%s --help'.", + c.App.Name, + command, + c.App.Name, + os.Args[0], + ) + os.Exit(1) +} diff --git a/cmd/docker-machine/machine_test.go b/cmd/docker-machine/machine_test.go new file mode 100644 index 0000000000..0287158a94 --- /dev/null +++ b/cmd/docker-machine/machine_test.go @@ -0,0 +1,17 @@ +package main + +import ( + "os" + "testing" + + "github.com/docker/machine/commands/mcndirs" +) + +func TestStorePathSetCorrectly(t *testing.T) { + mcndirs.BaseDir = "" + os.Args = []string{"docker-machine", "--storage-path", "/tmp/foo"} + main() + if mcndirs.BaseDir != "/tmp/foo" { + t.Fatal("Expected MACHINE_STORAGE_PATH environment variable to be /tmp/foo but was ", os.Getenv("MACHINE_STORAGE_PATH")) + } +} diff --git a/commands.go b/commands.go deleted file mode 100644 index 14ca71e5b7..0000000000 --- a/commands.go +++ /dev/null @@ -1,511 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "sort" - "strings" - "text/tabwriter" - - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - - "github.com/docker/machine/drivers" - _ "github.com/docker/machine/drivers/amazonec2" - _ "github.com/docker/machine/drivers/azure" - _ "github.com/docker/machine/drivers/digitalocean" - _ "github.com/docker/machine/drivers/google" - _ "github.com/docker/machine/drivers/none" - _ "github.com/docker/machine/drivers/openstack" - _ "github.com/docker/machine/drivers/rackspace" - _ "github.com/docker/machine/drivers/softlayer" - _ "github.com/docker/machine/drivers/virtualbox" - _ "github.com/docker/machine/drivers/vmwarefusion" - _ "github.com/docker/machine/drivers/vmwarevcloudair" - _ "github.com/docker/machine/drivers/vmwarevsphere" - "github.com/docker/machine/state" - "github.com/docker/machine/utils" -) - -type machineConfig struct { - caCertPath string - clientCertPath string - clientKeyPath string - machineUrl string -} - -type hostListItem struct { - Name string - Active bool - DriverName string - State state.State - URL string -} - -type hostListItemByName []hostListItem - -func (h hostListItemByName) Len() int { - return len(h) -} - -func (h hostListItemByName) Swap(i, j int) { - h[i], h[j] = h[j], h[i] -} - -func (h hostListItemByName) Less(i, j int) bool { - return strings.ToLower(h[i].Name) < strings.ToLower(h[j].Name) -} - -var Commands = []cli.Command{ - { - Name: "active", - Usage: "Get or set the active machine", - Action: cmdActive, - }, - { - Flags: append( - drivers.GetCreateFlags(), - cli.StringFlag{ - Name: "driver, d", - Usage: fmt.Sprintf( - "Driver to create machine with. Available drivers: %s", - strings.Join(drivers.GetDriverNames(), ", "), - ), - Value: "none", - }, - ), - Name: "create", - Usage: "Create a machine", - Action: cmdCreate, - }, - { - Name: "config", - Usage: "Print the connection config for machine", - Action: cmdConfig, - }, - { - Name: "inspect", - Usage: "Inspect information about a machine", - Action: cmdInspect, - }, - { - Name: "ip", - Usage: "Get the IP address of a machine", - Action: cmdIp, - }, - { - Name: "kill", - Usage: "Kill a machine", - Action: cmdKill, - }, - { - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "quiet, q", - Usage: "Enable quiet mode", - }, - }, - Name: "ls", - Usage: "List machines", - Action: cmdLs, - }, - { - Name: "restart", - Usage: "Restart a machine", - Action: cmdRestart, - }, - { - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "force, f", - Usage: "Remove local configuration even if machine cannot be removed", - }, - }, - Name: "rm", - Usage: "Remove a machine", - Action: cmdRm, - }, - { - Name: "env", - Usage: "Display the commands to set up the environment for the Docker client", - Action: cmdEnv, - }, - { - Name: "ssh", - Usage: "Log into or run a command on a machine with SSH", - Action: cmdSsh, - }, - { - Name: "start", - Usage: "Start a machine", - Action: cmdStart, - }, - { - Name: "stop", - Usage: "Stop a machine", - Action: cmdStop, - }, - { - Name: "upgrade", - Usage: "Upgrade a machine to the latest version of Docker", - Action: cmdUpgrade, - }, - { - Name: "url", - Usage: "Get the URL of a machine", - Action: cmdUrl, - }, -} - -func cmdActive(c *cli.Context) { - name := c.Args().First() - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - - if name == "" { - host, err := store.GetActive() - if err != nil { - log.Fatalf("error getting active host: %v", err) - } - if host != nil { - fmt.Println(host.Name) - } - } else if name != "" { - host, err := store.Load(name) - if err != nil { - log.Fatalf("error loading host: %v", err) - } - - if err := store.SetActive(host); err != nil { - log.Fatalf("error setting active host: %v", err) - } - } else { - cli.ShowCommandHelp(c, "active") - } -} - -func cmdCreate(c *cli.Context) { - driver := c.String("driver") - name := c.Args().First() - - if name == "" { - cli.ShowCommandHelp(c, "create") - log.Fatal("You must specify a machine name") - } - - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - - host, err := store.Create(name, driver, c) - if err != nil { - log.Errorf("Error creating machine: %s", err) - log.Warn("You will want to check the provider to make sure the machine and associated resources were properly removed.") - log.Fatal("Error creating machine") - } - if err := store.SetActive(host); err != nil { - log.Fatalf("error setting active host: %v", err) - } - - log.Infof("%q has been created and is now the active machine", name) - log.Infof("Configure docker client with: $(%s env %s)", c.App.Name, name) -} - -func cmdConfig(c *cli.Context) { - cfg, err := getMachineConfig(c) - if err != nil { - log.Fatal(err) - } - fmt.Printf("--tls --tlscacert=%s --tlscert=%s --tlskey=%s -H %s", - cfg.caCertPath, cfg.clientCertPath, cfg.clientKeyPath, cfg.machineUrl) -} - -func cmdInspect(c *cli.Context) { - prettyJSON, err := json.MarshalIndent(getHost(c), "", " ") - if err != nil { - log.Fatal(err) - } - - fmt.Println(string(prettyJSON)) -} - -func cmdIp(c *cli.Context) { - ip, err := getHost(c).Driver.GetIP() - if err != nil { - log.Fatal(err) - } - - fmt.Println(ip) -} - -func cmdKill(c *cli.Context) { - if err := getHost(c).Driver.Kill(); err != nil { - log.Fatal(err) - } -} - -func cmdLs(c *cli.Context) { - quiet := c.Bool("quiet") - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - - hostList, err := store.List() - if err != nil { - log.Fatal(err) - } - - w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) - - if !quiet { - fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL") - } - - items := []hostListItem{} - hostListItems := make(chan hostListItem) - - for _, host := range hostList { - if !quiet { - tmpHost, err := store.GetActive() - if err != nil { - log.Errorf("There's a problem with the active host: %s", err) - } - - if tmpHost == nil { - log.Errorf("There's a problem finding the active host") - } - - go getHostState(host, *store, hostListItems) - } else { - fmt.Fprintf(w, "%s\n", host.Name) - } - } - - if !quiet { - for i := 0; i < len(hostList); i++ { - items = append(items, <-hostListItems) - } - } - - close(hostListItems) - - sort.Sort(hostListItemByName(items)) - - for _, item := range items { - activeString := "" - if item.Active { - activeString = "*" - } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", - item.Name, activeString, item.DriverName, item.State, item.URL) - } - - w.Flush() -} - -func cmdRestart(c *cli.Context) { - if err := getHost(c).Driver.Restart(); err != nil { - log.Fatal(err) - } -} - -func cmdRm(c *cli.Context) { - if len(c.Args()) == 0 { - cli.ShowCommandHelp(c, "rm") - log.Fatal("You must specify a machine name") - } - - force := c.Bool("force") - - isError := false - - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - for _, host := range c.Args() { - if err := store.Remove(host, force); err != nil { - log.Errorf("Error removing machine %s: %s", host, err) - isError = true - } - } - if isError { - log.Fatal("There was an error removing a machine. To force remove it, pass the -f option. Warning: this might leave it running on the provider.") - } -} - -func cmdEnv(c *cli.Context) { - cfg, err := getMachineConfig(c) - if err != nil { - log.Fatal(err) - } - fmt.Printf("export DOCKER_TLS_VERIFY=yes\nexport DOCKER_CERT_PATH=%s\nexport DOCKER_HOST=%s\n", - utils.GetMachineClientCertDir(), cfg.machineUrl) -} - -func cmdSsh(c *cli.Context) { - name := c.Args().First() - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - - if name == "" { - host, err := store.GetActive() - if err != nil { - log.Fatalf("unable to get active host: %v", err) - } - - name = host.Name - } - - var cmd string - - var args []string = c.Args() - - for i, arg := range args { - if arg == "--" { - i++ - cmd = strings.Join(args[i:], " ") - break - } - } - - host, err := store.Load(name) - if err != nil { - log.Fatal(err) - } - - var sshCmd *exec.Cmd - if len(cmd) == 0 { - sshCmd, err = host.Driver.GetSSHCommand() - } else { - sshCmd, err = host.Driver.GetSSHCommand(cmd) - } - if err != nil { - log.Fatal(err) - } - - sshCmd.Stdin = os.Stdin - sshCmd.Stdout = os.Stdout - sshCmd.Stderr = os.Stderr - if err := sshCmd.Run(); err != nil { - log.Fatal(err) - } -} - -func cmdStart(c *cli.Context) { - if err := getHost(c).Start(); err != nil { - log.Fatal(err) - } -} - -func cmdStop(c *cli.Context) { - if err := getHost(c).Stop(); err != nil { - log.Fatal(err) - } -} - -func cmdUpgrade(c *cli.Context) { - if err := getHost(c).Upgrade(); err != nil { - log.Fatal(err) - } -} - -func cmdUrl(c *cli.Context) { - url, err := getHost(c).GetURL() - if err != nil { - log.Fatal(err) - } - - fmt.Println(url) -} - -func cmdNotFound(c *cli.Context, command string) { - log.Fatalf( - "%s: '%s' is not a %s command. See '%s --help'.", - c.App.Name, - command, - c.App.Name, - c.App.Name, - ) -} - -func getHost(c *cli.Context) *Host { - name := c.Args().First() - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - - if name == "" { - host, err := store.GetActive() - if err != nil { - log.Fatalf("unable to get active host: %v", err) - } - - if host == nil { - log.Fatal("unable to get active host, active file not found") - } - return host - } - - host, err := store.Load(name) - if err != nil { - log.Fatalf("unable to load host: %v", err) - } - return host -} - -func getHostState(host Host, store Store, hostListItems chan<- hostListItem) { - currentState, err := host.Driver.GetState() - if err != nil { - log.Errorf("error getting state for host %s: %s", host.Name, err) - } - - url, err := host.GetURL() - if err != nil { - if err == drivers.ErrHostIsNotRunning { - url = "" - } else { - log.Errorf("error getting URL for host %s: %s", host.Name, err) - } - } - - isActive, err := store.IsActive(&host) - if err != nil { - log.Debugf("error determining whether host %q is active: %s", - host.Name, err) - } - - hostListItems <- hostListItem{ - Name: host.Name, - Active: isActive, - DriverName: host.Driver.DriverName(), - State: currentState, - URL: url, - } -} - -func getMachineConfig(c *cli.Context) (*machineConfig, error) { - name := c.Args().First() - store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key")) - var machine *Host - - if name == "" { - m, err := store.GetActive() - if err != nil { - log.Fatalf("error getting active host: %v", err) - } - machine = m - } else { - m, err := store.Load(name) - if err != nil { - return nil, fmt.Errorf("Error loading machine config: %s", err) - } - machine = m - } - - caCert := filepath.Join(utils.GetMachineClientCertDir(), "ca.pem") - clientCert := filepath.Join(utils.GetMachineClientCertDir(), "cert.pem") - clientKey := filepath.Join(utils.GetMachineClientCertDir(), "key.pem") - machineUrl, err := machine.GetURL() - if err != nil { - return nil, fmt.Errorf("Error getting machine url: %s", err) - } - return &machineConfig{ - caCertPath: caCert, - clientCertPath: clientCert, - clientKeyPath: clientKey, - machineUrl: machineUrl, - }, nil -} diff --git a/commands/active.go b/commands/active.go new file mode 100644 index 0000000000..5941f83999 --- /dev/null +++ b/commands/active.go @@ -0,0 +1,60 @@ +package commands + +import ( + "errors" + "fmt" + + "time" + + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/persist" + "github.com/docker/machine/libmachine/state" +) + +const ( + activeDefaultTimeout = 10 +) + +var ( + errNoActiveHost = errors.New("No active host found") + errActiveTimeout = errors.New("Error getting active host: timeout") +) + +func cmdActive(c CommandLine, api libmachine.API) error { + if len(c.Args()) > 0 { + return ErrTooManyArguments + } + + hosts, hostsInError, err := persist.LoadAllHosts(api) + if err != nil { + return fmt.Errorf("Error getting active host: %s", err) + } + + timeout := time.Duration(c.Int("timeout")) * time.Second + items := getHostListItems(hosts, hostsInError, timeout) + + active, err := activeHost(items) + + if err != nil { + return err + } + + fmt.Println(active.Name) + return nil +} + +func activeHost(items []HostListItem) (HostListItem, error) { + timeout := false + for _, item := range items { + if item.ActiveHost || item.ActiveSwarm { + return item, nil + } + if item.State == state.Timeout { + timeout = true + } + } + if timeout { + return HostListItem{}, errActiveTimeout + } + return HostListItem{}, errNoActiveHost +} diff --git a/commands/active_test.go b/commands/active_test.go new file mode 100644 index 0000000000..08a18e698e --- /dev/null +++ b/commands/active_test.go @@ -0,0 +1,110 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +func TestCmdActiveNone(t *testing.T) { + hostListItems := []HostListItem{ + { + Name: "host1", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host2", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host3", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + } + _, err := activeHost(hostListItems) + assert.Equal(t, err, errNoActiveHost) +} + +func TestCmdActiveHost(t *testing.T) { + hostListItems := []HostListItem{ + { + Name: "host1", + ActiveHost: false, + ActiveSwarm: false, + State: state.Timeout, + }, + { + Name: "host2", + ActiveHost: true, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host3", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + } + active, err := activeHost(hostListItems) + assert.Equal(t, err, nil) + assert.Equal(t, active.Name, "host2") +} + +func TestCmdActiveSwarm(t *testing.T) { + hostListItems := []HostListItem{ + { + Name: "host1", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host2", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host3", + ActiveHost: false, + ActiveSwarm: true, + State: state.Running, + }, + } + active, err := activeHost(hostListItems) + assert.Equal(t, err, nil) + assert.Equal(t, active.Name, "host3") +} + +func TestCmdActiveTimeout(t *testing.T) { + hostListItems := []HostListItem{ + { + Name: "host1", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host2", + ActiveHost: false, + ActiveSwarm: false, + State: state.Running, + }, + { + Name: "host3", + ActiveHost: false, + ActiveSwarm: false, + State: state.Timeout, + }, + } + _, err := activeHost(hostListItems) + assert.Equal(t, err, errActiveTimeout) +} diff --git a/commands/commands.go b/commands/commands.go new file mode 100644 index 0000000000..a72fd83bbd --- /dev/null +++ b/commands/commands.go @@ -0,0 +1,489 @@ +package commands + +import ( + "errors" + "fmt" + "os" + "strings" + + "github.com/codegangsta/cli" + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/crashreport" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnerror" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/persist" + "github.com/docker/machine/libmachine/ssh" +) + +const ( + defaultMachineName = "default" +) + +var ( + ErrHostLoad = errors.New("All specified hosts had errors loading their configuration") + ErrNoDefault = fmt.Errorf("Error: No machine name(s) specified and no %q machine exists", defaultMachineName) + ErrNoMachineSpecified = errors.New("Error: Expected to get one or more machine names as arguments") + ErrExpectedOneMachine = errors.New("Error: Expected one machine name as an argument") + ErrTooManyArguments = errors.New("Error: Too many arguments given") + + osExit = func(code int) { os.Exit(code) } +) + +// CommandLine contains all the information passed to the commands on the command line. +type CommandLine interface { + ShowHelp() + + ShowVersion() + + Application() *cli.App + + Args() cli.Args + + IsSet(name string) bool + + Bool(name string) bool + + Int(name string) int + + String(name string) string + + StringSlice(name string) []string + + GlobalString(name string) string + + FlagNames() (names []string) + + Generic(name string) interface{} +} + +type contextCommandLine struct { + *cli.Context +} + +func (c *contextCommandLine) ShowHelp() { + cli.ShowCommandHelp(c.Context, c.Command.Name) +} + +func (c *contextCommandLine) ShowVersion() { + cli.ShowVersion(c.Context) +} + +func (c *contextCommandLine) Application() *cli.App { + return c.App +} + +// targetHost returns a specific host name if one is indicated by the first CLI +// arg, or the default host name if no host is specified. +func targetHost(c CommandLine, api libmachine.API) (string, error) { + if len(c.Args()) == 0 { + defaultExists, err := api.Exists(defaultMachineName) + if err != nil { + return "", fmt.Errorf("Error checking if host %q exists: %s", defaultMachineName, err) + } + + if defaultExists { + return defaultMachineName, nil + } + + return "", ErrNoDefault + } + + return c.Args()[0], nil +} + +func runAction(actionName string, c CommandLine, api libmachine.API) error { + var ( + hostsToLoad []string + ) + + // If user did not specify a machine name explicitly, use the 'default' + // machine if it exists. This allows short form commands such as + // 'docker-machine stop' for convenience. + if len(c.Args()) == 0 { + target, err := targetHost(c, api) + if err != nil { + return err + } + + hostsToLoad = []string{target} + } else { + hostsToLoad = c.Args() + } + + hosts, hostsInError := persist.LoadHosts(api, hostsToLoad) + + if len(hostsInError) > 0 { + errs := []error{} + for _, err := range hostsInError { + errs = append(errs, err) + } + return consolidateErrs(errs) + } + + if len(hosts) == 0 { + return ErrHostLoad + } + + if errs := runActionForeachMachine(actionName, hosts); len(errs) > 0 { + return consolidateErrs(errs) + } + + for _, h := range hosts { + if err := api.Save(h); err != nil { + return fmt.Errorf("Error saving host to store: %s", err) + } + } + + return nil +} + +func runCommand(command func(commandLine CommandLine, api libmachine.API) error) func(context *cli.Context) { + return func(context *cli.Context) { + api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir()) + defer api.Close() + + if context.GlobalBool("native-ssh") { + api.SSHClientType = ssh.Native + } + api.GithubAPIToken = context.GlobalString("github-api-token") + api.Filestore.Path = context.GlobalString("storage-path") + + // TODO (nathanleclaire): These should ultimately be accessed + // through the libmachine client by the rest of the code and + // not through their respective modules. For now, however, + // they are also being set the way that they originally were + // set to preserve backwards compatibility. + mcndirs.BaseDir = api.Filestore.Path + mcnutils.GithubAPIToken = api.GithubAPIToken + ssh.SetDefaultClient(api.SSHClientType) + + if err := command(&contextCommandLine{context}, api); err != nil { + log.Error(err) + + if crashErr, ok := err.(crashreport.CrashError); ok { + crashReporter := crashreport.NewCrashReporter(mcndirs.GetBaseDir(), context.GlobalString("bugsnag-api-token")) + crashReporter.Send(crashErr) + + if _, ok := crashErr.Cause.(mcnerror.ErrDuringPreCreate); ok { + osExit(3) + return + } + } + + osExit(1) + return + } + } +} + +func confirmInput(msg string) (bool, error) { + fmt.Printf("%s (y/n): ", msg) + + var resp string + _, err := fmt.Scanln(&resp) + if err != nil { + return false, err + } + + confirmed := strings.Index(strings.ToLower(resp), "y") == 0 + return confirmed, nil +} + +var Commands = []cli.Command{ + { + Name: "active", + Usage: "Print which machine is active", + Action: runCommand(cmdActive), + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "timeout, t", + Usage: fmt.Sprintf("Timeout in seconds, default to %ds", activeDefaultTimeout), + Value: activeDefaultTimeout, + }, + }, + }, + { + Name: "config", + Usage: "Print the connection config for machine", + Description: "Argument is a machine name.", + Action: runCommand(cmdConfig), + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "swarm", + Usage: "Display the Swarm config instead of the Docker daemon", + }, + }, + }, + { + Flags: SharedCreateFlags, + Name: "create", + Usage: "Create a machine", + Description: fmt.Sprintf("Run '%s create --driver name --help' to include the create flags for that driver in the help text.", os.Args[0]), + Action: runCommand(cmdCreateOuter), + SkipFlagParsing: true, + }, + { + Name: "env", + Usage: "Display the commands to set up the environment for the Docker client", + Description: "Argument is a machine name.", + Action: runCommand(cmdEnv), + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "swarm", + Usage: "Display the Swarm config instead of the Docker daemon", + }, + cli.StringFlag{ + Name: "shell", + Usage: "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, emacs], default is auto-detect", + }, + cli.BoolFlag{ + Name: "unset, u", + Usage: "Unset variables instead of setting them", + }, + cli.BoolFlag{ + Name: "no-proxy", + Usage: "Add machine IP to NO_PROXY environment variable", + }, + }, + }, + { + Name: "inspect", + Usage: "Inspect information about a machine", + Description: "Argument is a machine name.", + Action: runCommand(cmdInspect), + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "format, f", + Usage: "Format the output using the given go template.", + Value: "", + }, + }, + }, + { + Name: "ip", + Usage: "Get the IP address of a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdIP), + }, + { + Name: "kill", + Usage: "Kill a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdKill), + }, + { + Name: "ls", + Usage: "List machines", + Action: runCommand(cmdLs), + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "quiet, q", + Usage: "Enable quiet mode", + }, + cli.StringSliceFlag{ + Name: "filter", + Usage: "Filter output based on conditions provided", + Value: &cli.StringSlice{}, + }, + cli.IntFlag{ + Name: "timeout, t", + Usage: fmt.Sprintf("Timeout in seconds, default to %ds", lsDefaultTimeout), + Value: lsDefaultTimeout, + }, + cli.StringFlag{ + Name: "format, f", + Usage: "Pretty-print machines using a Go template", + }, + }, + }, + { + Name: "provision", + Usage: "Re-provision existing machines", + Action: runCommand(cmdProvision), + }, + { + Name: "regenerate-certs", + Usage: "Regenerate TLS Certificates for a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdRegenerateCerts), + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "force, f", + Usage: "Force rebuild and do not prompt", + }, + cli.BoolFlag{ + Name: "client-certs", + Usage: "Also regenerate client certificates and CA.", + }, + }, + }, + { + Name: "restart", + Usage: "Restart a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdRestart), + }, + { + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "force, f", + Usage: "Remove local configuration even if machine cannot be removed, also implies an automatic yes (`-y`)", + }, + cli.BoolFlag{ + Name: "y", + Usage: "Assumes automatic yes to proceed with remove, without prompting further user confirmation", + }, + }, + Name: "rm", + Usage: "Remove a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdRm), + }, + { + Name: "ssh", + Usage: "Log into or run a command on a machine with SSH.", + Description: "Arguments are [machine-name] [command]", + Action: runCommand(cmdSSH), + SkipFlagParsing: true, + }, + { + Name: "scp", + Usage: "Copy files between machines", + Description: "Arguments are [[user@]machine:][path] [[user@]machine:][path].", + Action: runCommand(cmdScp), + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "recursive, r", + Usage: "Copy files recursively (required to copy directories)", + }, + cli.BoolFlag{ + Name: "delta, d", + Usage: "Reduce amount of data sent over network by sending only the differences (uses rsync)", + }, + cli.BoolFlag{ + Name: "quiet, q", + Usage: "Disables the progress meter as well as warning and diagnostic messages from ssh", + }, + }, + }, + { + Name: "mount", + Usage: "Mount or unmount a directory from a machine with SSHFS.", + Description: "Arguments are [machine:][path] [mountpoint]", + Action: runCommand(cmdMount), + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "unmount, u", + Usage: "Unmount instead of mount", + }, + }, + }, + { + Name: "start", + Usage: "Start a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdStart), + }, + { + Name: "status", + Usage: "Get the status of a machine", + Description: "Argument is a machine name.", + Action: runCommand(cmdStatus), + }, + { + Name: "stop", + Usage: "Stop a machine", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdStop), + }, + { + Name: "upgrade", + Usage: "Upgrade a machine to the latest version of Docker", + Description: "Argument(s) are one or more machine names.", + Action: runCommand(cmdUpgrade), + }, + { + Name: "url", + Usage: "Get the URL of a machine", + Description: "Argument is a machine name.", + Action: runCommand(cmdURL), + }, + { + Name: "version", + Usage: "Show the Docker Machine version or a machine docker version", + Action: runCommand(cmdVersion), + }, +} + +func printIP(h *host.Host) func() error { + return func() error { + ip, err := h.Driver.GetIP() + if err != nil { + return fmt.Errorf("Error getting IP address: %s", err) + } + + fmt.Println(ip) + + return nil + } +} + +// machineCommand maps the command name to the corresponding machine command. +// We run commands concurrently and communicate back an error if there was one. +func machineCommand(actionName string, host *host.Host, errorChan chan<- error) { + // TODO: These actions should have their own type. + commands := map[string](func() error){ + "configureAuth": host.ConfigureAuth, + "configureAllAuth": host.ConfigureAllAuth, + "start": host.Start, + "stop": host.Stop, + "restart": host.Restart, + "kill": host.Kill, + "upgrade": host.Upgrade, + "ip": printIP(host), + "provision": host.Provision, + } + + log.Debugf("command=%s machine=%s", actionName, host.Name) + + errorChan <- commands[actionName]() +} + +// runActionForeachMachine will run the command across multiple machines +func runActionForeachMachine(actionName string, machines []*host.Host) []error { + var ( + numConcurrentActions = 0 + errorChan = make(chan error) + errs = []error{} + ) + + for _, machine := range machines { + numConcurrentActions++ + go machineCommand(actionName, machine, errorChan) + } + + // TODO: We should probably only do 5-10 of these + // at a time, since otherwise cloud providers might + // rate limit us. + for i := 0; i < numConcurrentActions; i++ { + if err := <-errorChan; err != nil { + errs = append(errs, err) + } + } + + close(errorChan) + + return errs +} + +func consolidateErrs(errs []error) error { + finalErr := "" + for _, err := range errs { + finalErr = fmt.Sprintf("%s\n%s", finalErr, err) + } + + return errors.New(strings.TrimSpace(finalErr)) +} diff --git a/commands/commands_test.go b/commands/commands_test.go new file mode 100644 index 0000000000..4b87101939 --- /dev/null +++ b/commands/commands_test.go @@ -0,0 +1,243 @@ +package commands + +import ( + "errors" + "flag" + "testing" + + "github.com/codegangsta/cli" + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/crashreport" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/hosttest" + "github.com/docker/machine/libmachine/mcnerror" + "github.com/docker/machine/libmachine/provision" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +func TestRunActionForeachMachine(t *testing.T) { + defer provision.SetDetector(&provision.StandardDetector{}) + provision.SetDetector(&provision.FakeDetector{ + Provisioner: provision.NewNetstatProvisioner(), + }) + + // Assume a bunch of machines in randomly started or + // stopped states. + machines := []*host.Host{ + { + Name: "foo", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + { + Name: "bar", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + }, + { + Name: "baz", + // Ssh, don't tell anyone but this + // driver only _thinks_ it's named + // virtualbox... (to test serial actions) + // It's actually FakeDriver! + DriverName: "virtualbox", + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + }, + { + Name: "spam", + DriverName: "virtualbox", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + { + Name: "eggs", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + }, + { + Name: "ham", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + } + + runActionForeachMachine("start", machines) + + for _, machine := range machines { + machineState, _ := machine.Driver.GetState() + + assert.Equal(t, state.Running, machineState) + } + + runActionForeachMachine("stop", machines) + + for _, machine := range machines { + machineState, _ := machine.Driver.GetState() + + assert.Equal(t, state.Stopped, machineState) + } +} + +func TestPrintIPEmptyGivenLocalEngine(t *testing.T) { + stdoutGetter := commandstest.NewStdoutGetter() + defer stdoutGetter.Stop() + + host, _ := hosttest.GetDefaultTestHost() + err := printIP(host)() + + assert.NoError(t, err) + assert.Equal(t, "\n", stdoutGetter.Output()) +} + +func TestPrintIPPrintsGivenRemoteEngine(t *testing.T) { + stdoutGetter := commandstest.NewStdoutGetter() + defer stdoutGetter.Stop() + + host, _ := hosttest.GetDefaultTestHost() + host.Driver = &fakedriver.Driver{ + MockState: state.Running, + MockIP: "1.2.3.4", + } + err := printIP(host)() + + assert.NoError(t, err) + assert.Equal(t, "1.2.3.4\n", stdoutGetter.Output()) +} + +func TestConsolidateError(t *testing.T) { + cases := []struct { + inputErrs []error + expectedErr error + }{ + { + inputErrs: []error{ + errors.New("Couldn't remove host 'bar'"), + }, + expectedErr: errors.New("Couldn't remove host 'bar'"), + }, + { + inputErrs: []error{ + errors.New("Couldn't remove host 'bar'"), + errors.New("Couldn't remove host 'foo'"), + }, + expectedErr: errors.New("Couldn't remove host 'bar'\nCouldn't remove host 'foo'"), + }, + } + + for _, c := range cases { + assert.Equal(t, c.expectedErr, consolidateErrs(c.inputErrs)) + } +} + +type MockCrashReporter struct { + sent bool +} + +func (m *MockCrashReporter) Send(err crashreport.CrashError) error { + m.sent = true + return nil +} + +func TestSendCrashReport(t *testing.T) { + defer func(fnOsExit func(code int)) { osExit = fnOsExit }(osExit) + osExit = func(code int) {} + + defer func(factory func(baseDir string, apiKey string) crashreport.CrashReporter) { + crashreport.NewCrashReporter = factory + }(crashreport.NewCrashReporter) + + tests := []struct { + description string + err error + sent bool + }{ + { + description: "Should send crash error", + err: crashreport.CrashError{ + Cause: errors.New("BUG"), + Command: "command", + Context: "context", + DriverName: "virtualbox", + }, + sent: true, + }, + { + description: "Should not send standard error", + err: errors.New("BUG"), + sent: false, + }, + } + + for _, test := range tests { + mockCrashReporter := &MockCrashReporter{} + crashreport.NewCrashReporter = func(baseDir string, apiKey string) crashreport.CrashReporter { + return mockCrashReporter + } + + command := func(commandLine CommandLine, api libmachine.API) error { + return test.err + } + + context := cli.NewContext(cli.NewApp(), &flag.FlagSet{}, nil) + runCommand(command)(context) + + assert.Equal(t, test.sent, mockCrashReporter.sent, test.description) + } +} + +func TestReturnExitCode1onError(t *testing.T) { + command := func(commandLine CommandLine, api libmachine.API) error { + return errors.New("foo is not bar") + } + + exitCode := checkErrorCodeForCommand(command) + + assert.Equal(t, 1, exitCode) +} + +func TestReturnExitCode3onErrorDuringPreCreate(t *testing.T) { + command := func(commandLine CommandLine, api libmachine.API) error { + return crashreport.CrashError{ + Cause: mcnerror.ErrDuringPreCreate{ + Cause: errors.New("foo is not bar"), + }, + } + } + + exitCode := checkErrorCodeForCommand(command) + + assert.Equal(t, 3, exitCode) +} + +func checkErrorCodeForCommand(command func(commandLine CommandLine, api libmachine.API) error) int { + var setExitCode int + + originalOSExit := osExit + + defer func() { + osExit = originalOSExit + }() + + osExit = func(code int) { + setExitCode = code + } + + context := cli.NewContext(cli.NewApp(), &flag.FlagSet{}, nil) + runCommand(command)(context) + + return setExitCode +} diff --git a/commands/commandstest/fake_command_line.go b/commands/commandstest/fake_command_line.go new file mode 100644 index 0000000000..be9368e38e --- /dev/null +++ b/commands/commandstest/fake_command_line.go @@ -0,0 +1,100 @@ +package commandstest + +import ( + "github.com/codegangsta/cli" +) + +type FakeFlagger struct { + Data map[string]interface{} +} + +type FakeCommandLine struct { + LocalFlags, GlobalFlags *FakeFlagger + HelpShown, VersionShown bool + CliArgs []string +} + +func (ff FakeFlagger) String(key string) string { + if value, ok := ff.Data[key]; ok { + return value.(string) + } + return "" +} + +func (ff FakeFlagger) StringSlice(key string) []string { + if value, ok := ff.Data[key]; ok { + return value.([]string) + } + return []string{} +} + +func (ff FakeFlagger) Int(key string) int { + if value, ok := ff.Data[key]; ok { + return value.(int) + } + return 0 +} + +func (ff FakeFlagger) Bool(key string) bool { + if value, ok := ff.Data[key]; ok { + return value.(bool) + } + return false +} + +func (fcli *FakeCommandLine) IsSet(key string) bool { + _, ok := fcli.LocalFlags.Data[key] + return ok +} + +func (fcli *FakeCommandLine) String(key string) string { + return fcli.LocalFlags.String(key) +} + +func (fcli *FakeCommandLine) StringSlice(key string) []string { + return fcli.LocalFlags.StringSlice(key) +} + +func (fcli *FakeCommandLine) Int(key string) int { + return fcli.LocalFlags.Int(key) +} + +func (fcli *FakeCommandLine) Bool(key string) bool { + if fcli.LocalFlags == nil { + return false + } + return fcli.LocalFlags.Bool(key) +} + +func (fcli *FakeCommandLine) GlobalString(key string) string { + return fcli.GlobalFlags.String(key) +} + +func (fcli *FakeCommandLine) Generic(name string) interface{} { + return fcli.LocalFlags.Data[name] +} + +func (fcli *FakeCommandLine) FlagNames() []string { + flagNames := []string{} + for key := range fcli.LocalFlags.Data { + flagNames = append(flagNames, key) + } + + return flagNames +} + +func (fcli *FakeCommandLine) ShowHelp() { + fcli.HelpShown = true +} + +func (fcli *FakeCommandLine) Application() *cli.App { + return cli.NewApp() +} + +func (fcli *FakeCommandLine) Args() cli.Args { + return fcli.CliArgs +} + +func (fcli *FakeCommandLine) ShowVersion() { + fcli.VersionShown = true +} diff --git a/commands/commandstest/stdout_capture.go b/commands/commandstest/stdout_capture.go new file mode 100644 index 0000000000..926aed3d8a --- /dev/null +++ b/commands/commandstest/stdout_capture.go @@ -0,0 +1,54 @@ +package commandstest + +import ( + "bytes" + "io" + + "os" +) + +var ( + stdout *os.File +) + +func init() { + stdout = os.Stdout +} + +type StdoutGetter interface { + Output() string + Stop() +} + +type stdoutCapturer struct { + stdout *os.File + output chan string +} + +func NewStdoutGetter() StdoutGetter { + r, w, _ := os.Pipe() + os.Stdout = w + + output := make(chan string) + go func() { + var testOutput bytes.Buffer + io.Copy(&testOutput, r) + output <- testOutput.String() + }() + + return &stdoutCapturer{ + stdout: w, + output: output, + } +} + +func (c *stdoutCapturer) Output() string { + c.stdout.Close() + text := <-c.output + close(c.output) + return text +} + +func (c *stdoutCapturer) Stop() { + os.Stdout = stdout +} diff --git a/commands/config.go b/commands/config.go new file mode 100644 index 0000000000..0f81217d1f --- /dev/null +++ b/commands/config.go @@ -0,0 +1,46 @@ +package commands + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/check" + "github.com/docker/machine/libmachine/log" +) + +func cmdConfig(c CommandLine, api libmachine.API) error { + // Ensure that log messages always go to stderr when this command is + // being run (it is intended to be run in a subshell) + log.SetOutWriter(os.Stderr) + + target, err := targetHost(c, api) + if err != nil { + return err + } + + host, err := api.Load(target) + if err != nil { + return err + } + + dockerHost, _, err := check.DefaultConnChecker.Check(host, c.Bool("swarm")) + if err != nil { + return fmt.Errorf("Error running connection boilerplate: %s", err) + } + + log.Debug(dockerHost) + + tlsCACert := filepath.Join(mcndirs.GetMachineDir(), host.Name, "ca.pem") + tlsCert := filepath.Join(mcndirs.GetMachineDir(), host.Name, "cert.pem") + tlsKey := filepath.Join(mcndirs.GetMachineDir(), host.Name, "key.pem") + + // TODO(nathanleclaire): These magic strings for the certificate file + // names should be cross-package constants. + fmt.Printf("--tlsverify\n--tlscacert=%q\n--tlscert=%q\n--tlskey=%q\n-H=%s\n", + tlsCACert, tlsCert, tlsKey, dockerHost) + + return nil +} diff --git a/commands/create.go b/commands/create.go new file mode 100644 index 0000000000..1e17dee01b --- /dev/null +++ b/commands/create.go @@ -0,0 +1,462 @@ +package commands + +import ( + "encoding/json" + "flag" + "fmt" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + + "errors" + + "time" + + "github.com/codegangsta/cli" + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/crashreport" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/drivers/rpc" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnerror" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/swarm" +) + +var ( + errNoMachineName = errors.New("Error: No machine name specified") +) + +var ( + SharedCreateFlags = []cli.Flag{ + cli.StringFlag{ + Name: "driver, d", + Usage: "Driver to create machine with.", + Value: "virtualbox", + EnvVar: "MACHINE_DRIVER", + }, + cli.StringFlag{ + Name: "engine-install-url", + Usage: "Custom URL to use for engine installation", + Value: drivers.DefaultEngineInstallURL, + EnvVar: "MACHINE_DOCKER_INSTALL_URL", + }, + cli.StringSliceFlag{ + Name: "engine-opt", + Usage: "Specify arbitrary flags to include with the created engine in the form flag=value", + Value: &cli.StringSlice{}, + }, + cli.StringSliceFlag{ + Name: "engine-insecure-registry", + Usage: "Specify insecure registries to allow with the created engine", + Value: &cli.StringSlice{}, + }, + cli.StringSliceFlag{ + Name: "engine-registry-mirror", + Usage: "Specify registry mirrors to use", + Value: &cli.StringSlice{}, + EnvVar: "ENGINE_REGISTRY_MIRROR", + }, + cli.StringSliceFlag{ + Name: "engine-label", + Usage: "Specify labels for the created engine", + Value: &cli.StringSlice{}, + }, + cli.StringFlag{ + Name: "engine-storage-driver", + Usage: "Specify a storage driver to use with the engine", + }, + cli.StringSliceFlag{ + Name: "engine-env", + Usage: "Specify environment variables to set in the engine", + Value: &cli.StringSlice{}, + }, + cli.BoolFlag{ + Name: "swarm", + Usage: "Configure Machine to join a Swarm cluster", + }, + cli.StringFlag{ + Name: "swarm-image", + Usage: "Specify Docker image to use for Swarm", + Value: "swarm:latest", + EnvVar: "MACHINE_SWARM_IMAGE", + }, + cli.BoolFlag{ + Name: "swarm-master", + Usage: "Configure Machine to be a Swarm master", + }, + cli.StringFlag{ + Name: "swarm-discovery", + Usage: "Discovery service to use with Swarm", + Value: "", + }, + cli.StringFlag{ + Name: "swarm-strategy", + Usage: "Define a default scheduling strategy for Swarm", + Value: "spread", + }, + cli.StringSliceFlag{ + Name: "swarm-opt", + Usage: "Define arbitrary flags for Swarm master", + Value: &cli.StringSlice{}, + }, + cli.StringSliceFlag{ + Name: "swarm-join-opt", + Usage: "Define arbitrary flags for Swarm join", + Value: &cli.StringSlice{}, + }, + cli.StringFlag{ + Name: "swarm-host", + Usage: "ip/socket to listen on for Swarm master", + Value: "tcp://0.0.0.0:3376", + }, + cli.StringFlag{ + Name: "swarm-addr", + Usage: "addr to advertise for Swarm (default: detect and use the machine IP)", + Value: "", + }, + cli.BoolFlag{ + Name: "swarm-experimental", + Usage: "Enable Swarm experimental features", + }, + cli.StringSliceFlag{ + Name: "tls-san", + Usage: "Support extra SANs for TLS certs", + Value: &cli.StringSlice{}, + }, + } +) + +func cmdCreateInner(c CommandLine, api libmachine.API) error { + if len(c.Args()) > 1 { + return fmt.Errorf("Invalid command line. Found extra arguments %v", c.Args()[1:]) + } + + name := c.Args().First() + if name == "" { + c.ShowHelp() + return errNoMachineName + } + + validName := host.ValidateHostName(name) + if !validName { + return fmt.Errorf("Error creating machine: %s", mcnerror.ErrInvalidHostname) + } + + if err := validateSwarmDiscovery(c.String("swarm-discovery")); err != nil { + return fmt.Errorf("Error parsing swarm discovery: %s", err) + } + + // TODO: Fix hacky JSON solution + rawDriver, err := json.Marshal(&drivers.BaseDriver{ + MachineName: name, + StorePath: c.GlobalString("storage-path"), + }) + if err != nil { + return fmt.Errorf("Error attempting to marshal bare driver data: %s", err) + } + + driverName := c.String("driver") + h, err := api.NewHost(driverName, rawDriver) + if err != nil { + return fmt.Errorf("Error getting new host: %s", err) + } + + h.HostOptions = &host.Options{ + AuthOptions: &auth.Options{ + CertDir: mcndirs.GetMachineCertDir(), + CaCertPath: tlsPath(c, "tls-ca-cert", "ca.pem"), + CaPrivateKeyPath: tlsPath(c, "tls-ca-key", "ca-key.pem"), + ClientCertPath: tlsPath(c, "tls-client-cert", "cert.pem"), + ClientKeyPath: tlsPath(c, "tls-client-key", "key.pem"), + ServerCertPath: filepath.Join(mcndirs.GetMachineDir(), name, "server.pem"), + ServerKeyPath: filepath.Join(mcndirs.GetMachineDir(), name, "server-key.pem"), + StorePath: filepath.Join(mcndirs.GetMachineDir(), name), + ServerCertSANs: c.StringSlice("tls-san"), + }, + EngineOptions: &engine.Options{ + ArbitraryFlags: c.StringSlice("engine-opt"), + Env: c.StringSlice("engine-env"), + InsecureRegistry: c.StringSlice("engine-insecure-registry"), + Labels: c.StringSlice("engine-label"), + RegistryMirror: c.StringSlice("engine-registry-mirror"), + StorageDriver: c.String("engine-storage-driver"), + TLSVerify: true, + InstallURL: c.String("engine-install-url"), + }, + SwarmOptions: &swarm.Options{ + IsSwarm: c.Bool("swarm") || c.Bool("swarm-master"), + Image: c.String("swarm-image"), + Agent: c.Bool("swarm"), + Master: c.Bool("swarm-master"), + Discovery: c.String("swarm-discovery"), + Address: c.String("swarm-addr"), + Host: c.String("swarm-host"), + Strategy: c.String("swarm-strategy"), + ArbitraryFlags: c.StringSlice("swarm-opt"), + ArbitraryJoinFlags: c.StringSlice("swarm-join-opt"), + IsExperimental: c.Bool("swarm-experimental"), + }, + } + + exists, err := api.Exists(h.Name) + if err != nil { + return fmt.Errorf("Error checking if host exists: %s", err) + } + if exists { + return mcnerror.ErrHostAlreadyExists{ + Name: h.Name, + } + } + + // driverOpts is the actual data we send over the wire to set the + // driver parameters (an interface fulfilling drivers.DriverOptions, + // concrete type rpcdriver.RpcFlags). + mcnFlags := h.Driver.GetCreateFlags() + driverOpts := getDriverOpts(c, mcnFlags) + + if err := h.Driver.SetConfigFromFlags(driverOpts); err != nil { + return fmt.Errorf("Error setting machine configuration from flags provided: %s", err) + } + + if err := api.Create(h); err != nil { + // Wait for all the logs to reach the client + time.Sleep(2 * time.Second) + + vBoxLog := "" + if h.DriverName == "virtualbox" { + vBoxLog = filepath.Join(api.GetMachinesDir(), h.Name, h.Name, "Logs", "VBox.log") + } + + return crashreport.CrashError{ + Cause: err, + Command: "Create", + Context: "api.performCreate", + DriverName: h.DriverName, + LogFilePath: vBoxLog, + } + } + + if err := api.Save(h); err != nil { + return fmt.Errorf("Error attempting to save store: %s", err) + } + + log.Infof("To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: %s env %s", os.Args[0], name) + + return nil +} + +// The following function is needed because the CLI acrobatics that we're doing +// (with having an "outer" and "inner" function each with their own custom +// settings and flag parsing needs) are not well supported by codegangsta/cli. +// +// Instead of trying to make a convoluted series of flag parsing and relying on +// codegangsta/cli internals work well, we simply read the flags we're +// interested in from the outer function into module-level variables, and then +// use them from the "inner" function. +// +// I'm not very pleased about this, but it seems to be the only decent +// compromise without drastically modifying codegangsta/cli internals or our +// own CLI. +func flagHackLookup(flagName string) string { + // e.g. "-d" for "--driver" + flagPrefix := flagName[1:3] + + // TODO: Should we support -flag-name (single hyphen) syntax as well? + for i, arg := range os.Args { + if strings.Contains(arg, flagPrefix) { + // format '--driver foo' or '-d foo' + if arg == flagPrefix || arg == flagName { + if i+1 < len(os.Args) { + return os.Args[i+1] + } + } + + // format '--driver=foo' or '-d=foo' + if strings.HasPrefix(arg, flagPrefix+"=") || strings.HasPrefix(arg, flagName+"=") { + return strings.Split(arg, "=")[1] + } + } + } + + return "" +} + +func cmdCreateOuter(c CommandLine, api libmachine.API) error { + const ( + flagLookupMachineName = "flag-lookup" + ) + + // We didn't recognize the driver name. + driverName := flagHackLookup("--driver") + if driverName == "" { + //TODO: Check Environment have to include flagHackLookup function. + driverName = os.Getenv("MACHINE_DRIVER") + if driverName == "" { + driverName = "virtualbox" + } + } + + // TODO: Fix hacky JSON solution + rawDriver, err := json.Marshal(&drivers.BaseDriver{ + MachineName: flagLookupMachineName, + }) + if err != nil { + return fmt.Errorf("Error attempting to marshal bare driver data: %s", err) + } + + h, err := api.NewHost(driverName, rawDriver) + if err != nil { + return err + } + + // TODO: So much flag manipulation and voodoo here, it seems to be + // asking for trouble. + // + // mcnFlags is the data we get back over the wire (type mcnflag.Flag) + // to indicate which parameters are available. + mcnFlags := h.Driver.GetCreateFlags() + + // This bit will actually make "create" display the correct flags based + // on the requested driver. + cliFlags, err := convertMcnFlagsToCliFlags(mcnFlags) + if err != nil { + return fmt.Errorf("Error trying to convert provided driver flags to cli flags: %s", err) + } + + for i := range c.Application().Commands { + cmd := &c.Application().Commands[i] + if cmd.HasName("create") { + cmd = addDriverFlagsToCommand(cliFlags, cmd) + } + } + + return c.Application().Run(os.Args) +} + +func getDriverOpts(c CommandLine, mcnflags []mcnflag.Flag) drivers.DriverOptions { + // TODO: This function is pretty damn YOLO and would benefit from some + // sanity checking around types and assertions. + // + // But, we need it so that we can actually send the flags for creating + // a machine over the wire (cli.Context is a no go since there is so + // much stuff in it). + driverOpts := rpcdriver.RPCFlags{ + Values: make(map[string]interface{}), + } + + for _, f := range mcnflags { + driverOpts.Values[f.String()] = f.Default() + + // Hardcoded logic for boolean... :( + if f.Default() == nil { + driverOpts.Values[f.String()] = false + } + } + + for _, name := range c.FlagNames() { + getter, ok := c.Generic(name).(flag.Getter) + if ok { + driverOpts.Values[name] = getter.Get() + } else { + // TODO: This is pretty hacky. StringSlice is the only + // type so far we have to worry about which is not a + // Getter, though. + if c.IsSet(name) { + driverOpts.Values[name] = c.StringSlice(name) + } + } + } + + return driverOpts +} + +func convertMcnFlagsToCliFlags(mcnFlags []mcnflag.Flag) ([]cli.Flag, error) { + cliFlags := []cli.Flag{} + for _, f := range mcnFlags { + switch t := f.(type) { + // TODO: It seems pretty wrong to just default "nil" to this, + // but cli.BoolFlag doesn't have a "Value" field (false is + // always the default) + case *mcnflag.BoolFlag: + f := f.(*mcnflag.BoolFlag) + cliFlags = append(cliFlags, cli.BoolFlag{ + Name: f.Name, + EnvVar: f.EnvVar, + Usage: f.Usage, + }) + case *mcnflag.IntFlag: + f := f.(*mcnflag.IntFlag) + cliFlags = append(cliFlags, cli.IntFlag{ + Name: f.Name, + EnvVar: f.EnvVar, + Usage: f.Usage, + Value: f.Value, + }) + case *mcnflag.StringFlag: + f := f.(*mcnflag.StringFlag) + cliFlags = append(cliFlags, cli.StringFlag{ + Name: f.Name, + EnvVar: f.EnvVar, + Usage: f.Usage, + Value: f.Value, + }) + case *mcnflag.StringSliceFlag: + f := f.(*mcnflag.StringSliceFlag) + cliFlags = append(cliFlags, cli.StringSliceFlag{ + Name: f.Name, + EnvVar: f.EnvVar, + Usage: f.Usage, + + //TODO: Is this used with defaults? Can we convert the literal []string to cli.StringSlice properly? + Value: &cli.StringSlice{}, + }) + default: + log.Warn("Flag is ", f) + return nil, fmt.Errorf("Flag is unrecognized flag type: %T", t) + } + } + + return cliFlags, nil +} + +func addDriverFlagsToCommand(cliFlags []cli.Flag, cmd *cli.Command) *cli.Command { + cmd.Flags = append(SharedCreateFlags, cliFlags...) + cmd.SkipFlagParsing = false + cmd.Action = runCommand(cmdCreateInner) + sort.Sort(ByFlagName(cmd.Flags)) + + return cmd +} + +func validateSwarmDiscovery(discovery string) error { + if discovery == "" { + return nil + } + + matched, err := regexp.MatchString(`[^:]*://.*`, discovery) + if err != nil { + return err + } + + if matched { + return nil + } + + return fmt.Errorf("Swarm Discovery URL was in the wrong format: %s", discovery) +} + +func tlsPath(c CommandLine, flag string, defaultName string) string { + path := c.GlobalString(flag) + if path != "" { + return path + } + + return filepath.Join(mcndirs.GetMachineCertDir(), defaultName) +} diff --git a/commands/create_test.go b/commands/create_test.go new file mode 100644 index 0000000000..ae8fa43ce6 --- /dev/null +++ b/commands/create_test.go @@ -0,0 +1,119 @@ +package commands + +import ( + "testing" + + "flag" + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/stretchr/testify/assert" +) + +func TestValidateSwarmDiscoveryErrorsGivenInvalidURL(t *testing.T) { + err := validateSwarmDiscovery("foo") + assert.Error(t, err) +} + +func TestValidateSwarmDiscoveryAcceptsEmptyString(t *testing.T) { + err := validateSwarmDiscovery("") + assert.NoError(t, err) +} + +func TestValidateSwarmDiscoveryAcceptsValidFormat(t *testing.T) { + err := validateSwarmDiscovery("token://deadbeefcafe") + assert.NoError(t, err) +} + +type fakeFlagGetter struct { + flag.Value + value interface{} +} + +func (ff fakeFlagGetter) Get() interface{} { + return ff.value +} + +var nilStringSlice []string + +var getDriverOptsFlags = []mcnflag.Flag{ + mcnflag.BoolFlag{ + Name: "bool", + }, + mcnflag.IntFlag{ + Name: "int", + }, + mcnflag.IntFlag{ + Name: "int_defaulted", + Value: 42, + }, + mcnflag.StringFlag{ + Name: "string", + }, + mcnflag.StringFlag{ + Name: "string_defaulted", + Value: "bob", + }, + mcnflag.StringSliceFlag{ + Name: "stringslice", + }, + mcnflag.StringSliceFlag{ + Name: "stringslice_defaulted", + Value: []string{"joe"}, + }, +} + +var getDriverOptsTests = []struct { + data map[string]interface{} + expected map[string]interface{} +}{ + { + expected: map[string]interface{}{ + "bool": false, + "int": 0, + "int_defaulted": 42, + "string": "", + "string_defaulted": "bob", + "stringslice": nilStringSlice, + "stringslice_defaulted": []string{"joe"}, + }, + }, + { + data: map[string]interface{}{ + "bool": fakeFlagGetter{value: true}, + "int": fakeFlagGetter{value: 42}, + "int_defaulted": fakeFlagGetter{value: 37}, + "string": fakeFlagGetter{value: "jake"}, + "string_defaulted": fakeFlagGetter{value: "george"}, + // NB: StringSlices are not flag.Getters. + "stringslice": []string{"ford"}, + "stringslice_defaulted": []string{"zaphod", "arthur"}, + }, + expected: map[string]interface{}{ + "bool": true, + "int": 42, + "int_defaulted": 37, + "string": "jake", + "string_defaulted": "george", + "stringslice": []string{"ford"}, + "stringslice_defaulted": []string{"zaphod", "arthur"}, + }, + }, +} + +func TestGetDriverOpts(t *testing.T) { + for _, tt := range getDriverOptsTests { + commandLine := &commandstest.FakeCommandLine{ + LocalFlags: &commandstest.FakeFlagger{ + Data: tt.data, + }, + } + driverOpts := getDriverOpts(commandLine, getDriverOptsFlags) + assert.Equal(t, tt.expected["bool"], driverOpts.Bool("bool")) + assert.Equal(t, tt.expected["int"], driverOpts.Int("int")) + assert.Equal(t, tt.expected["int_defaulted"], driverOpts.Int("int_defaulted")) + assert.Equal(t, tt.expected["string"], driverOpts.String("string")) + assert.Equal(t, tt.expected["string_defaulted"], driverOpts.String("string_defaulted")) + assert.Equal(t, tt.expected["stringslice"], driverOpts.StringSlice("stringslice")) + assert.Equal(t, tt.expected["stringslice_defaulted"], driverOpts.StringSlice("stringslice_defaulted")) + } +} diff --git a/commands/env.go b/commands/env.go new file mode 100644 index 0000000000..d0c9d16892 --- /dev/null +++ b/commands/env.go @@ -0,0 +1,275 @@ +package commands + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + "text/template" + + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/check" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/shell" +) + +const ( + envTmpl = `{{ .Prefix }}DOCKER_TLS_VERIFY{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}DOCKER_HOST{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}DOCKER_CERT_PATH{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}DOCKER_MACHINE_NAME{{ .Delimiter }}{{ .MachineName }}{{ .Suffix }}{{ if .ComposePathsVar }}{{ .Prefix }}COMPOSE_CONVERT_WINDOWS_PATHS{{ .Delimiter }}true{{ .Suffix }}{{end}}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}` +) + +var ( + errImproperUnsetEnvArgs = errors.New("Error: Expected no machine name when the -u flag is present") + defaultUsageHinter UsageHintGenerator + runtimeOS = func() string { return runtime.GOOS } +) + +func init() { + defaultUsageHinter = &EnvUsageHintGenerator{} +} + +type ShellConfig struct { + Prefix string + Delimiter string + Suffix string + DockerCertPath string + DockerHost string + DockerTLSVerify string + UsageHint string + MachineName string + NoProxyVar string + NoProxyValue string + ComposePathsVar bool +} + +func cmdEnv(c CommandLine, api libmachine.API) error { + var ( + err error + shellCfg *ShellConfig + ) + + // Ensure that log messages always go to stderr when this command is + // being run (it is intended to be run in a subshell) + log.SetOutWriter(os.Stderr) + + if c.Bool("unset") { + shellCfg, err = shellCfgUnset(c, api) + if err != nil { + return err + } + } else { + shellCfg, err = shellCfgSet(c, api) + if err != nil { + return err + } + } + + return executeTemplateStdout(shellCfg) +} + +func shellCfgSet(c CommandLine, api libmachine.API) (*ShellConfig, error) { + if len(c.Args()) > 1 { + return nil, ErrExpectedOneMachine + } + + target, err := targetHost(c, api) + if err != nil { + return nil, err + } + + host, err := api.Load(target) + if err != nil { + return nil, err + } + + dockerHost, _, err := check.DefaultConnChecker.Check(host, c.Bool("swarm")) + if err != nil { + return nil, fmt.Errorf("Error checking TLS connection: %s", err) + } + + userShell, err := getShell(c.String("shell")) + if err != nil { + return nil, err + } + + shellCfg := &ShellConfig{ + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), host.Name), + DockerHost: dockerHost, + DockerTLSVerify: "1", + UsageHint: defaultUsageHinter.GenerateUsageHint(userShell, os.Args), + MachineName: host.Name, + } + + if c.Bool("no-proxy") { + ip, err := host.Driver.GetIP() + if err != nil { + return nil, fmt.Errorf("Error getting host IP: %s", err) + } + + noProxyVar, noProxyValue := findNoProxyFromEnv() + + // add the docker host to the no_proxy list idempotently + switch { + case noProxyValue == "": + noProxyValue = ip + case strings.Contains(noProxyValue, ip): + //ip already in no_proxy list, nothing to do + default: + noProxyValue = fmt.Sprintf("%s,%s", noProxyValue, ip) + } + + shellCfg.NoProxyVar = noProxyVar + shellCfg.NoProxyValue = noProxyValue + } + + if runtimeOS() == "windows" { + shellCfg.ComposePathsVar = true + } + + switch userShell { + case "fish": + shellCfg.Prefix = "set -gx " + shellCfg.Suffix = "\";\n" + shellCfg.Delimiter = " \"" + case "powershell": + shellCfg.Prefix = "$Env:" + shellCfg.Suffix = "\"\n" + shellCfg.Delimiter = " = \"" + case "cmd": + shellCfg.Prefix = "SET " + shellCfg.Suffix = "\n" + shellCfg.Delimiter = "=" + case "tcsh": + shellCfg.Prefix = "setenv " + shellCfg.Suffix = "\";\n" + shellCfg.Delimiter = " \"" + case "emacs": + shellCfg.Prefix = "(setenv \"" + shellCfg.Suffix = "\")\n" + shellCfg.Delimiter = "\" \"" + default: + shellCfg.Prefix = "export " + shellCfg.Suffix = "\"\n" + shellCfg.Delimiter = "=\"" + } + + return shellCfg, nil +} + +func shellCfgUnset(c CommandLine, api libmachine.API) (*ShellConfig, error) { + if len(c.Args()) != 0 { + return nil, errImproperUnsetEnvArgs + } + + userShell, err := getShell(c.String("shell")) + if err != nil { + return nil, err + } + + shellCfg := &ShellConfig{ + UsageHint: defaultUsageHinter.GenerateUsageHint(userShell, os.Args), + } + + if c.Bool("no-proxy") { + shellCfg.NoProxyVar, shellCfg.NoProxyValue = findNoProxyFromEnv() + } + + switch userShell { + case "fish": + shellCfg.Prefix = "set -e " + shellCfg.Suffix = ";\n" + shellCfg.Delimiter = "" + case "powershell": + shellCfg.Prefix = `Remove-Item Env:\\` + shellCfg.Suffix = "\n" + shellCfg.Delimiter = "" + case "cmd": + shellCfg.Prefix = "SET " + shellCfg.Suffix = "\n" + shellCfg.Delimiter = "=" + case "emacs": + shellCfg.Prefix = "(setenv \"" + shellCfg.Suffix = ")\n" + shellCfg.Delimiter = "\" nil" + case "tcsh": + shellCfg.Prefix = "unsetenv " + shellCfg.Suffix = ";\n" + shellCfg.Delimiter = "" + default: + shellCfg.Prefix = "unset " + shellCfg.Suffix = "\n" + shellCfg.Delimiter = "" + } + + return shellCfg, nil +} + +func executeTemplateStdout(shellCfg *ShellConfig) error { + t := template.New("envConfig") + tmpl, err := t.Parse(envTmpl) + if err != nil { + return err + } + + return tmpl.Execute(os.Stdout, shellCfg) +} + +func getShell(userShell string) (string, error) { + if userShell != "" { + return userShell, nil + } + return shell.Detect() +} + +func findNoProxyFromEnv() (string, string) { + // first check for an existing lower case no_proxy var + noProxyVar := "no_proxy" + noProxyValue := os.Getenv("no_proxy") + + // otherwise default to allcaps HTTP_PROXY + if noProxyValue == "" { + noProxyVar = "NO_PROXY" + noProxyValue = os.Getenv("NO_PROXY") + } + return noProxyVar, noProxyValue +} + +type UsageHintGenerator interface { + GenerateUsageHint(string, []string) string +} + +type EnvUsageHintGenerator struct{} + +func (g *EnvUsageHintGenerator) GenerateUsageHint(userShell string, args []string) string { + cmd := "" + comment := "#" + + dockerMachinePath := args[0] + if strings.Contains(dockerMachinePath, " ") || strings.Contains(dockerMachinePath, `\`) { + args[0] = fmt.Sprintf("\"%s\"", dockerMachinePath) + } + + commandLine := strings.Join(args, " ") + + switch userShell { + case "fish": + cmd = fmt.Sprintf("eval (%s)", commandLine) + case "powershell": + cmd = fmt.Sprintf("& %s | Invoke-Expression", commandLine) + case "cmd": + cmd = fmt.Sprintf("\t@FOR /f \"tokens=*\" %%i IN ('%s') DO @%%i", commandLine) + comment = "REM" + case "emacs": + cmd = fmt.Sprintf("(with-temp-buffer (shell-command \"%s\" (current-buffer)) (eval-buffer))", commandLine) + comment = ";;" + case "tcsh": + cmd = fmt.Sprintf("eval `%s`", commandLine) + comment = ":" + default: + cmd = fmt.Sprintf("eval $(%s)", commandLine) + } + + return fmt.Sprintf("%s Run this command to configure your shell: \n%s %s\n", comment, comment, cmd) +} diff --git a/commands/env_test.go b/commands/env_test.go new file mode 100644 index 0000000000..545849f0c2 --- /dev/null +++ b/commands/env_test.go @@ -0,0 +1,688 @@ +package commands + +import ( + "os" + "path/filepath" + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/check" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +type FakeConnChecker struct { + DockerHost string + AuthOptions *auth.Options + Err error +} + +func (fcc *FakeConnChecker) Check(_ *host.Host, _ bool) (string, *auth.Options, error) { + return fcc.DockerHost, fcc.AuthOptions, fcc.Err +} + +type SimpleUsageHintGenerator struct { + Hint string +} + +func (suhg *SimpleUsageHintGenerator) GenerateUsageHint(_ string, _ []string) string { + return suhg.Hint +} + +func TestHints(t *testing.T) { + var tests = []struct { + userShell string + commandLine []string + expectedHints string + }{ + {"", []string{"machine", "env", "default"}, "# Run this command to configure your shell: \n# eval $(machine env default)\n"}, + {"", []string{"machine", "env", "--no-proxy", "default"}, "# Run this command to configure your shell: \n# eval $(machine env --no-proxy default)\n"}, + {"", []string{"machine", "env", "--swarm", "default"}, "# Run this command to configure your shell: \n# eval $(machine env --swarm default)\n"}, + {"", []string{"machine", "env", "--no-proxy", "--swarm", "default"}, "# Run this command to configure your shell: \n# eval $(machine env --no-proxy --swarm default)\n"}, + {"", []string{"machine", "env", "--unset"}, "# Run this command to configure your shell: \n# eval $(machine env --unset)\n"}, + {"", []string{`C:\\Program Files\docker-machine.exe`, "env", "default"}, "# Run this command to configure your shell: \n# eval $(\"C:\\\\Program Files\\docker-machine.exe\" env default)\n"}, + {"", []string{`C:\\Me\docker-machine.exe`, "env", "default"}, "# Run this command to configure your shell: \n# eval $(\"C:\\\\Me\\docker-machine.exe\" env default)\n"}, + + {"fish", []string{"./machine", "env", "--shell=fish", "default"}, "# Run this command to configure your shell: \n# eval (./machine env --shell=fish default)\n"}, + {"fish", []string{"./machine", "env", "--shell=fish", "--no-proxy", "default"}, "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --no-proxy default)\n"}, + {"fish", []string{"./machine", "env", "--shell=fish", "--swarm", "default"}, "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --swarm default)\n"}, + {"fish", []string{"./machine", "env", "--shell=fish", "--no-proxy", "--swarm", "default"}, "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --no-proxy --swarm default)\n"}, + {"fish", []string{"./machine", "env", "--shell=fish", "--unset"}, "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --unset)\n"}, + + {"powershell", []string{"./machine", "env", "--shell=powershell", "default"}, "# Run this command to configure your shell: \n# & ./machine env --shell=powershell default | Invoke-Expression\n"}, + {"powershell", []string{"./machine", "env", "--shell=powershell", "--no-proxy", "default"}, "# Run this command to configure your shell: \n# & ./machine env --shell=powershell --no-proxy default | Invoke-Expression\n"}, + {"powershell", []string{"./machine", "env", "--shell=powershell", "--swarm", "default"}, "# Run this command to configure your shell: \n# & ./machine env --shell=powershell --swarm default | Invoke-Expression\n"}, + {"powershell", []string{"./machine", "env", "--shell=powershell", "--no-proxy", "--swarm", "default"}, "# Run this command to configure your shell: \n# & ./machine env --shell=powershell --no-proxy --swarm default | Invoke-Expression\n"}, + {"powershell", []string{"./machine", "env", "--shell=powershell", "--unset"}, "# Run this command to configure your shell: \n# & ./machine env --shell=powershell --unset | Invoke-Expression\n"}, + {"powershell", []string{"./machine", "env", "--shell=powershell", "--unset"}, "# Run this command to configure your shell: \n# & ./machine env --shell=powershell --unset | Invoke-Expression\n"}, + {"powershell", []string{`C:\\Program Files\docker-machine.exe`, "env", "--shell=powershell", "default"}, "# Run this command to configure your shell: \n# & \"C:\\\\Program Files\\docker-machine.exe\" env --shell=powershell default | Invoke-Expression\n"}, + {"powershell", []string{`C:\\Me\docker-machine.exe`, "env", "--shell=powershell", "default"}, "# Run this command to configure your shell: \n# & \"C:\\\\Me\\docker-machine.exe\" env --shell=powershell default | Invoke-Expression\n"}, + + {"cmd", []string{"./machine", "env", "--shell=cmd", "default"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd default') DO @%i\n"}, + {"cmd", []string{"./machine", "env", "--shell=cmd", "--no-proxy", "default"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --no-proxy default') DO @%i\n"}, + {"cmd", []string{"./machine", "env", "--shell=cmd", "--swarm", "default"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --swarm default') DO @%i\n"}, + {"cmd", []string{"./machine", "env", "--shell=cmd", "--no-proxy", "--swarm", "default"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --no-proxy --swarm default') DO @%i\n"}, + {"cmd", []string{"./machine", "env", "--shell=cmd", "--unset"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --unset') DO @%i\n"}, + {"cmd", []string{`C:\\Program Files\docker-machine.exe`, "env", "--shell=cmd", "default"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('\"C:\\\\Program Files\\docker-machine.exe\" env --shell=cmd default') DO @%i\n"}, + {"cmd", []string{`C:\\Me\docker-machine.exe`, "env", "--shell=cmd", "default"}, "REM Run this command to configure your shell: \nREM \t@FOR /f \"tokens=*\" %i IN ('\"C:\\\\Me\\docker-machine.exe\" env --shell=cmd default') DO @%i\n"}, + + {"emacs", []string{"./machine", "env", "--shell=emacs", "default"}, ";; Run this command to configure your shell: \n;; (with-temp-buffer (shell-command \"./machine env --shell=emacs default\" (current-buffer)) (eval-buffer))\n"}, + {"emacs", []string{"./machine", "env", "--shell=emacs", "--no-proxy", "default"}, ";; Run this command to configure your shell: \n;; (with-temp-buffer (shell-command \"./machine env --shell=emacs --no-proxy default\" (current-buffer)) (eval-buffer))\n"}, + {"emacs", []string{"./machine", "env", "--shell=emacs", "--swarm", "default"}, ";; Run this command to configure your shell: \n;; (with-temp-buffer (shell-command \"./machine env --shell=emacs --swarm default\" (current-buffer)) (eval-buffer))\n"}, + {"emacs", []string{"./machine", "env", "--shell=emacs", "--no-proxy", "--swarm", "default"}, ";; Run this command to configure your shell: \n;; (with-temp-buffer (shell-command \"./machine env --shell=emacs --no-proxy --swarm default\" (current-buffer)) (eval-buffer))\n"}, + {"emacs", []string{"./machine", "env", "--shell=emacs", "--unset"}, ";; Run this command to configure your shell: \n;; (with-temp-buffer (shell-command \"./machine env --shell=emacs --unset\" (current-buffer)) (eval-buffer))\n"}, + + {"tcsh", []string{"./machine", "env", "--shell=tcsh", "default"}, ": Run this command to configure your shell: \n: eval `./machine env --shell=tcsh default`\n"}, + {"tcsh", []string{"./machine", "env", "--shell=tcsh", "--no-proxy", "default"}, ": Run this command to configure your shell: \n: eval `./machine env --shell=tcsh --no-proxy default`\n"}, + {"tcsh", []string{"./machine", "env", "--shell=tcsh", "--swarm", "default"}, ": Run this command to configure your shell: \n: eval `./machine env --shell=tcsh --swarm default`\n"}, + {"tcsh", []string{"./machine", "env", "--shell=tcsh", "--no-proxy", "--swarm", "default"}, ": Run this command to configure your shell: \n: eval `./machine env --shell=tcsh --no-proxy --swarm default`\n"}, + {"tcsh", []string{"./machine", "env", "--shell=tcsh", "--unset"}, ": Run this command to configure your shell: \n: eval `./machine env --shell=tcsh --unset`\n"}, + } + + for _, test := range tests { + hints := defaultUsageHinter.GenerateUsageHint(test.userShell, test.commandLine) + assert.Equal(t, test.expectedHints, hints) + } +} + +func revertUsageHinter(uhg UsageHintGenerator) { + defaultUsageHinter = uhg +} + +func TestShellCfgSet(t *testing.T) { + const ( + usageHint = "This is a usage hint" + ) + + // TODO: This should be embedded in some kind of wrapper struct for all + // these `env` operations. + defer revertUsageHinter(defaultUsageHinter) + defaultUsageHinter = &SimpleUsageHintGenerator{usageHint} + isRuntimeWindows := runtimeOS() == "windows" + + var tests = []struct { + description string + commandLine CommandLine + api libmachine.API + connChecker check.ConnChecker + noProxyVar string + noProxyValue string + expectedShellCfg *ShellConfig + expectedErr error + }{ + { + description: "no host name specified", + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{}, + }, + commandLine: &commandstest.FakeCommandLine{ + CliArgs: nil, + }, + expectedShellCfg: nil, + expectedErr: ErrNoDefault, + }, + { + description: "bash shell set happy path without any flags set", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "bash", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "export ", + Delimiter: "=\"", + Suffix: "\"\n", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + expectedErr: nil, + }, + { + description: "bash shell set happy path with 'default' vm", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "bash", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: defaultMachineName, + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "export ", + Delimiter: "=\"", + Suffix: "\"\n", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), defaultMachineName), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: defaultMachineName, + ComposePathsVar: isRuntimeWindows, + }, + expectedErr: nil, + }, + { + description: "fish shell set happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "fish", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "set -gx ", + Suffix: "\";\n", + Delimiter: " \"", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + expectedErr: nil, + }, + { + description: "powershell set happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "powershell", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "$Env:", + Suffix: "\"\n", + Delimiter: " = \"", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + expectedErr: nil, + }, + { + description: "emacs set happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "emacs", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "(setenv \"", + Suffix: "\")\n", + Delimiter: "\" \"", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + expectedErr: nil, + }, + { + description: "cmd.exe happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "cmd", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "SET ", + Suffix: "\n", + Delimiter: "=", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + expectedErr: nil, + }, + { + description: "bash shell set happy path with --no-proxy flag; no existing environment variable set", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "bash", + "swarm": false, + "no-proxy": true, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "1.2.3.4", + }, + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "export ", + Delimiter: "=\"", + Suffix: "\"\n", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + NoProxyVar: "NO_PROXY", + NoProxyValue: "1.2.3.4", // From FakeDriver + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + noProxyVar: "NO_PROXY", + noProxyValue: "", + expectedErr: nil, + }, + { + description: "bash shell set happy path with --no-proxy flag; existing environment variable _is_ set", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "bash", + "swarm": false, + "no-proxy": true, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "1.2.3.4", + }, + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "export ", + Delimiter: "=\"", + Suffix: "\"\n", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + NoProxyVar: "no_proxy", + NoProxyValue: "192.168.59.1,1.2.3.4", // From FakeDriver + MachineName: "quux", + ComposePathsVar: isRuntimeWindows, + }, + noProxyVar: "no_proxy", + noProxyValue: "192.168.59.1", + expectedErr: nil, + }, + } + + for _, test := range tests { + // TODO: Ideally this should not hit the environment at all but + // rather should go through an interface. + os.Setenv(test.noProxyVar, test.noProxyValue) + + t.Log(test.description) + + check.DefaultConnChecker = test.connChecker + shellCfg, err := shellCfgSet(test.commandLine, test.api) + assert.Equal(t, test.expectedShellCfg, shellCfg) + assert.Equal(t, test.expectedErr, err) + + os.Unsetenv(test.noProxyVar) + } +} + +func TestShellCfgSetWindowsRuntime(t *testing.T) { + const ( + usageHint = "This is a usage hint" + ) + + // TODO: This should be embedded in some kind of wrapper struct for all + // these `env` operations. + defer revertUsageHinter(defaultUsageHinter) + defaultUsageHinter = &SimpleUsageHintGenerator{usageHint} + + var tests = []struct { + description string + commandLine CommandLine + api libmachine.API + connChecker check.ConnChecker + noProxyVar string + noProxyValue string + expectedShellCfg *ShellConfig + expectedErr error + }{ + { + description: "powershell set happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"quux"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "powershell", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "quux", + }, + }, + }, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "$Env:", + Suffix: "\"\n", + Delimiter: " = \"", + DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"), + DockerHost: "tcp://1.2.3.4:2376", + DockerTLSVerify: "1", + UsageHint: usageHint, + MachineName: "quux", + ComposePathsVar: true, + }, + expectedErr: nil, + }, + } + + actualRuntimeOS := runtimeOS + runtimeOS = func() string { return "windows" } + defer func() { runtimeOS = actualRuntimeOS }() + + for _, test := range tests { + // TODO: Ideally this should not hit the environment at all but + // rather should go through an interface. + os.Setenv(test.noProxyVar, test.noProxyValue) + + t.Log(test.description) + + check.DefaultConnChecker = test.connChecker + shellCfg, err := shellCfgSet(test.commandLine, test.api) + assert.Equal(t, test.expectedShellCfg, shellCfg) + assert.Equal(t, test.expectedErr, err) + + os.Unsetenv(test.noProxyVar) + } +} + +func TestShellCfgUnset(t *testing.T) { + const ( + usageHint = "This is the unset usage hint" + ) + + defer revertUsageHinter(defaultUsageHinter) + defaultUsageHinter = &SimpleUsageHintGenerator{usageHint} + + var tests = []struct { + description string + commandLine CommandLine + api libmachine.API + connChecker check.ConnChecker + noProxyVar string + noProxyValue string + expectedShellCfg *ShellConfig + expectedErr error + }{ + { + description: "more than expected args passed in", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"foo", "bar"}, + }, + expectedShellCfg: nil, + expectedErr: errImproperUnsetEnvArgs, + }, + { + description: "bash shell unset happy path without any flags set", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: nil, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "bash", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{}, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "unset ", + Suffix: "\n", + Delimiter: "", + UsageHint: usageHint, + }, + expectedErr: nil, + }, + { + description: "fish shell unset happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: nil, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "fish", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{}, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "set -e ", + Suffix: ";\n", + Delimiter: "", + UsageHint: usageHint, + }, + expectedErr: nil, + }, + { + description: "powershell unset happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: nil, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "powershell", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{}, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: `Remove-Item Env:\\`, + Suffix: "\n", + Delimiter: "", + UsageHint: usageHint, + }, + expectedErr: nil, + }, + { + description: "cmd.exe unset happy path", + commandLine: &commandstest.FakeCommandLine{ + CliArgs: nil, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "shell": "cmd", + "swarm": false, + "no-proxy": false, + }, + }, + }, + api: &libmachinetest.FakeAPI{}, + connChecker: &FakeConnChecker{ + DockerHost: "tcp://1.2.3.4:2376", + AuthOptions: nil, + Err: nil, + }, + expectedShellCfg: &ShellConfig{ + Prefix: "SET ", + Suffix: "\n", + Delimiter: "=", + UsageHint: usageHint, + }, + expectedErr: nil, + }, + // TODO: There is kind of a funny bug (feature?) I discovered + // reasoning about unset() where if there was a NO_PROXY value + // set _before_ the original docker-machine env, it won't be + // restored (NO_PROXY won't be unset at all, it will stay the + // same). We should define expected behavior in this case. + } + + for _, test := range tests { + os.Setenv(test.noProxyVar, test.noProxyValue) + + t.Log(test.description) + + check.DefaultConnChecker = test.connChecker + shellCfg, err := shellCfgUnset(test.commandLine, test.api) + assert.Equal(t, test.expectedShellCfg, shellCfg) + assert.Equal(t, test.expectedErr, err) + + os.Setenv(test.noProxyVar, "") + } +} diff --git a/drivers/flag_sort.go b/commands/flag_sort.go similarity index 94% rename from drivers/flag_sort.go rename to commands/flag_sort.go index b71840a0dc..746043b563 100644 --- a/drivers/flag_sort.go +++ b/commands/flag_sort.go @@ -1,4 +1,4 @@ -package drivers +package commands import "github.com/codegangsta/cli" diff --git a/commands/inspect.go b/commands/inspect.go new file mode 100644 index 0000000000..c521501c02 --- /dev/null +++ b/commands/inspect.go @@ -0,0 +1,72 @@ +package commands + +import ( + "encoding/json" + "fmt" + "os" + "text/template" + + "github.com/docker/machine/libmachine" +) + +var funcMap = template.FuncMap{ + "json": func(v interface{}) string { + a, _ := json.Marshal(v) + return string(a) + }, + "prettyjson": func(v interface{}) string { + a, _ := json.MarshalIndent(v, "", " ") + return string(a) + }, +} + +func cmdInspect(c CommandLine, api libmachine.API) error { + if len(c.Args()) > 1 { + c.ShowHelp() + return ErrExpectedOneMachine + } + + target, err := targetHost(c, api) + if err != nil { + return err + } + + host, err := api.Load(target) + if err != nil { + return err + } + + tmplString := c.String("format") + if tmplString != "" { + var tmpl *template.Template + var err error + if tmpl, err = template.New("").Funcs(funcMap).Parse(tmplString); err != nil { + return fmt.Errorf("template parsing error: %v", err) + } + + jsonHost, err := json.Marshal(host) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + if err := json.Unmarshal(jsonHost, &obj); err != nil { + return err + } + + if err := tmpl.Execute(os.Stdout, obj); err != nil { + return err + } + + os.Stdout.Write([]byte{'\n'}) + } else { + prettyJSON, err := json.MarshalIndent(host, "", " ") + if err != nil { + return err + } + + fmt.Println(string(prettyJSON)) + } + + return nil +} diff --git a/commands/inspect_test.go b/commands/inspect_test.go new file mode 100644 index 0000000000..779ce35d38 --- /dev/null +++ b/commands/inspect_test.go @@ -0,0 +1,31 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/stretchr/testify/assert" +) + +func TestCmdInspect(t *testing.T) { + testCases := []struct { + commandLine CommandLine + api libmachine.API + expectedErr error + }{ + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"foo", "bar"}, + }, + api: &libmachinetest.FakeAPI{}, + expectedErr: ErrExpectedOneMachine, + }, + } + + for _, tc := range testCases { + err := cmdInspect(tc.commandLine, tc.api) + assert.Equal(t, tc.expectedErr, err) + } +} diff --git a/commands/ip.go b/commands/ip.go new file mode 100644 index 0000000000..13e45f6896 --- /dev/null +++ b/commands/ip.go @@ -0,0 +1,7 @@ +package commands + +import "github.com/docker/machine/libmachine" + +func cmdIP(c CommandLine, api libmachine.API) error { + return runAction("ip", c, api) +} diff --git a/commands/ip_test.go b/commands/ip_test.go new file mode 100644 index 0000000000..108b33b57d --- /dev/null +++ b/commands/ip_test.go @@ -0,0 +1,79 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +func TestCmdIPMissingMachineName(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{} + api := &libmachinetest.FakeAPI{} + + err := cmdURL(commandLine, api) + + assert.Equal(t, err, ErrNoDefault) +} + +func TestCmdIP(t *testing.T) { + testCases := []struct { + commandLine CommandLine + api libmachine.API + expectedErr error + expectedOut string + }{ + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"machine"}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machine", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "1.2.3.4", + }, + }, + }, + }, + expectedErr: nil, + expectedOut: "1.2.3.4\n", + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "default", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "1.2.3.4", + }, + }, + }, + }, + expectedErr: nil, + expectedOut: "1.2.3.4\n", + }, + } + + for _, tc := range testCases { + stdoutGetter := commandstest.NewStdoutGetter() + + err := cmdIP(tc.commandLine, tc.api) + + assert.Equal(t, tc.expectedErr, err) + assert.Equal(t, tc.expectedOut, stdoutGetter.Output()) + + stdoutGetter.Stop() + } +} diff --git a/commands/kill.go b/commands/kill.go new file mode 100644 index 0000000000..f8c2aac3d1 --- /dev/null +++ b/commands/kill.go @@ -0,0 +1,7 @@ +package commands + +import "github.com/docker/machine/libmachine" + +func cmdKill(c CommandLine, api libmachine.API) error { + return runAction("kill", c, api) +} diff --git a/commands/kill_test.go b/commands/kill_test.go new file mode 100644 index 0000000000..23c1ef5a09 --- /dev/null +++ b/commands/kill_test.go @@ -0,0 +1,56 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +func TestCmdKillMissingMachineName(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{} + api := &libmachinetest.FakeAPI{} + + err := cmdKill(commandLine, api) + + assert.Equal(t, ErrNoDefault, err) +} + +func TestCmdKill(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToKill1", "machineToKill2"}, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToKill1", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + { + Name: "machineToKill2", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + { + Name: "machine", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + }, + } + + err := cmdKill(commandLine, api) + assert.NoError(t, err) + + assert.Equal(t, state.Stopped, libmachinetest.State(api, "machineToKill1")) + assert.Equal(t, state.Stopped, libmachinetest.State(api, "machineToKill2")) + assert.Equal(t, state.Running, libmachinetest.State(api, "machine")) +} diff --git a/commands/ls.go b/commands/ls.go new file mode 100644 index 0000000000..15535950c8 --- /dev/null +++ b/commands/ls.go @@ -0,0 +1,506 @@ +package commands + +import ( + "errors" + "fmt" + "os" + "regexp" + "sort" + "strings" + "text/tabwriter" + "text/template" + "time" + + "io" + + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcndockerclient" + "github.com/docker/machine/libmachine/persist" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/swarm" + "github.com/skarademir/naturalsort" +) + +const ( + lsDefaultTimeout = 10 + tableFormatKey = "table" + lsDefaultFormat = "table {{ .Name }}\t{{ .Active }}\t{{ .DriverName}}\t{{ .State }}\t{{ .URL }}\t{{ .Swarm }}\t{{ .DockerVersion }}\t{{ .Error}}" +) + +var ( + headers = map[string]string{ + "Name": "NAME", + "Active": "ACTIVE", + "ActiveHost": "ACTIVE_HOST", + "ActiveSwarm": "ACTIVE_SWARM", + "DriverName": "DRIVER", + "State": "STATE", + "URL": "URL", + "SwarmOptions": "SWARM_OPTIONS", + "Swarm": "SWARM", + "EngineOptions": "ENGINE_OPTIONS", + "Error": "ERRORS", + "DockerVersion": "DOCKER", + "ResponseTime": "RESPONSE", + } +) + +type HostListItem struct { + Name string + Active string + ActiveHost bool + ActiveSwarm bool + DriverName string + State state.State + URL string + SwarmOptions *swarm.Options + Swarm string + EngineOptions *engine.Options + Error string + DockerVersion string + ResponseTime time.Duration +} + +// FilterOptions - +type FilterOptions struct { + SwarmName []string + DriverName []string + State []string + Name []string + Labels []string +} + +func cmdLs(c CommandLine, api libmachine.API) error { + filters, err := parseFilters(c.StringSlice("filter")) + if err != nil { + return err + } + + hostList, hostInError, err := persist.LoadAllHosts(api) + if err != nil { + return err + } + + hostList = filterHosts(hostList, filters) + + // Just print out the names if we're being quiet + if c.Bool("quiet") { + for _, host := range hostList { + fmt.Println(host.Name) + } + return nil + } + + template, table, err := parseFormat(c.String("format")) + if err != nil { + return err + } + + var w io.Writer + if table { + tabWriter := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) + defer tabWriter.Flush() + + w = tabWriter + + if err := template.Execute(w, headers); err != nil { + return err + } + } else { + w = os.Stdout + } + + timeout := time.Duration(c.Int("timeout")) * time.Second + items := getHostListItems(hostList, hostInError, timeout) + + swarmMasters := make(map[string]string) + swarmInfo := make(map[string]string) + + for _, host := range hostList { + if host.HostOptions != nil { + swarmOptions := host.HostOptions.SwarmOptions + if swarmOptions.Master { + swarmMasters[swarmOptions.Discovery] = host.Name + } + + if swarmOptions.Discovery != "" { + swarmInfo[host.Name] = swarmOptions.Discovery + } + } + } + + for _, item := range items { + swarmColumn := "" + if item.SwarmOptions != nil && item.SwarmOptions.Discovery != "" { + swarmColumn = swarmMasters[item.SwarmOptions.Discovery] + if item.SwarmOptions.Master { + swarmColumn = fmt.Sprintf("%s (master)", swarmColumn) + } + } + item.Swarm = swarmColumn + + if err := template.Execute(w, item); err != nil { + return err + } + } + + return nil +} + +func parseFormat(format string) (*template.Template, bool, error) { + table := false + finalFormat := format + + if finalFormat == "" { + finalFormat = lsDefaultFormat + } + + if strings.HasPrefix(finalFormat, tableFormatKey) { + table = true + finalFormat = finalFormat[len(tableFormatKey):] + } + + finalFormat = strings.Trim(finalFormat, " ") + r := strings.NewReplacer(`\t`, "\t", `\n`, "\n") + finalFormat = r.Replace(finalFormat) + + template, err := template.New("").Parse(finalFormat + "\n") + if err != nil { + return nil, false, err + } + + return template, table, nil +} + +func parseFilters(filters []string) (FilterOptions, error) { + options := FilterOptions{} + for _, f := range filters { + kv := strings.SplitN(f, "=", 2) + if len(kv) != 2 { + return options, errors.New("Unsupported filter syntax") + } + key, value := strings.ToLower(kv[0]), kv[1] + + switch key { + case "swarm": + options.SwarmName = append(options.SwarmName, value) + case "driver": + options.DriverName = append(options.DriverName, value) + case "state": + options.State = append(options.State, value) + case "name": + options.Name = append(options.Name, value) + case "label": + options.Labels = append(options.Labels, value) + default: + return options, fmt.Errorf("Unsupported filter key '%s'", key) + } + } + return options, nil +} + +func filterHosts(hosts []*host.Host, filters FilterOptions) []*host.Host { + if len(filters.SwarmName) == 0 && + len(filters.DriverName) == 0 && + len(filters.State) == 0 && + len(filters.Name) == 0 && + len(filters.Labels) == 0 { + return hosts + } + + filteredHosts := []*host.Host{} + swarmMasters := getSwarmMasters(hosts) + + for _, h := range hosts { + if filterHost(h, filters, swarmMasters) { + filteredHosts = append(filteredHosts, h) + } + } + return filteredHosts +} + +func getSwarmMasters(hosts []*host.Host) map[string]string { + swarmMasters := make(map[string]string) + for _, h := range hosts { + if h.HostOptions != nil { + swarmOptions := h.HostOptions.SwarmOptions + if swarmOptions != nil && swarmOptions.Master { + swarmMasters[swarmOptions.Discovery] = h.Name + } + } + } + return swarmMasters +} + +func filterHost(host *host.Host, filters FilterOptions, swarmMasters map[string]string) bool { + swarmMatches := matchesSwarmName(host, filters.SwarmName, swarmMasters) + driverMatches := matchesDriverName(host, filters.DriverName) + stateMatches := matchesState(host, filters.State) + nameMatches := matchesName(host, filters.Name) + labelMatches := matchesLabel(host, filters.Labels) + + return swarmMatches && driverMatches && stateMatches && nameMatches && labelMatches +} + +func matchesSwarmName(host *host.Host, swarmNames []string, swarmMasters map[string]string) bool { + if len(swarmNames) == 0 { + return true + } + for _, n := range swarmNames { + if host.HostOptions != nil && host.HostOptions.SwarmOptions != nil { + if strings.EqualFold(n, swarmMasters[host.HostOptions.SwarmOptions.Discovery]) { + return true + } + } + } + return false +} + +func matchesDriverName(host *host.Host, driverNames []string) bool { + if len(driverNames) == 0 { + return true + } + for _, n := range driverNames { + if strings.EqualFold(host.DriverName, n) { + return true + } + } + return false +} + +func matchesState(host *host.Host, states []string) bool { + if len(states) == 0 { + return true + } + for _, n := range states { + s, err := host.Driver.GetState() + if err != nil { + log.Warn(err) + } + if strings.EqualFold(n, s.String()) { + return true + } + } + return false +} + +func matchesName(host *host.Host, names []string) bool { + if len(names) == 0 { + return true + } + for _, n := range names { + r, err := regexp.Compile(n) + if err != nil { + log.Error(err) + os.Exit(1) // TODO: Can we get rid of this call, and exit 'properly' ? + } + if r.MatchString(host.Driver.GetMachineName()) { + return true + } + } + return false +} + +func matchesLabel(host *host.Host, labels []string) bool { + if len(labels) == 0 { + return true + } + + var englabels = make(map[string]string, len(host.HostOptions.EngineOptions.Labels)) + + if host.HostOptions != nil && host.HostOptions.EngineOptions.Labels != nil { + for _, s := range host.HostOptions.EngineOptions.Labels { + kv := strings.SplitN(s, "=", 2) + englabels[kv[0]] = kv[1] + } + } + + for _, l := range labels { + kv := strings.SplitN(l, "=", 2) + if val, exists := englabels[kv[0]]; exists && strings.EqualFold(val, kv[1]) { + return true + } + } + return false +} + +// PERFORMANCE: The code of this function is complicated because we try +// to call the underlying drivers as less as possible to get the information +// we need. +func attemptGetHostState(h *host.Host, stateQueryChan chan<- HostListItem) { + requestBeginning := time.Now() + url := "" + currentState := state.None + dockerVersion := "Unknown" + hostError := "" + + url, err := h.URL() + + // PERFORMANCE: if we have the url, it's ok to assume the host is running + // This reduces the number of calls to the drivers + if err == nil { + if url != "" { + currentState = state.Running + } else { + currentState, err = h.Driver.GetState() + } + } else { + currentState, _ = h.Driver.GetState() + } + + if err == nil && url != "" { + // PERFORMANCE: Reuse the url instead of asking the host again. + // This reduces the number of calls to the drivers + dockerHost := &mcndockerclient.RemoteDocker{ + HostURL: url, + AuthOption: h.AuthOptions(), + } + dockerVersion, err = mcndockerclient.DockerVersion(dockerHost) + + if err != nil { + dockerVersion = "Unknown" + } else { + dockerVersion = fmt.Sprintf("v%s", dockerVersion) + } + } + + if err != nil { + hostError = err.Error() + } + if hostError == drivers.ErrHostIsNotRunning.Error() { + hostError = "" + } + + var swarmOptions *swarm.Options + var engineOptions *engine.Options + if h.HostOptions != nil { + swarmOptions = h.HostOptions.SwarmOptions + engineOptions = h.HostOptions.EngineOptions + } + + isMaster := false + swarmHost := "" + if swarmOptions != nil { + isMaster = swarmOptions.Master + swarmHost = swarmOptions.Host + } + + activeHost := isActive(currentState, url) + activeSwarm := isSwarmActive(currentState, url, isMaster, swarmHost) + active := "-" + if activeHost { + active = "*" + } + if activeSwarm { + active = "* (swarm)" + } + + stateQueryChan <- HostListItem{ + Name: h.Name, + Active: active, + ActiveHost: activeHost, + ActiveSwarm: activeSwarm, + DriverName: h.Driver.DriverName(), + State: currentState, + URL: url, + SwarmOptions: swarmOptions, + EngineOptions: engineOptions, + DockerVersion: dockerVersion, + Error: hostError, + ResponseTime: time.Now().Round(time.Millisecond).Sub(requestBeginning.Round(time.Millisecond)), + } +} + +func getHostState(h *host.Host, hostListItemsChan chan<- HostListItem, timeout time.Duration) { + // This channel is used to communicate the properties we are querying + // about the host in the case of a successful read. + stateQueryChan := make(chan HostListItem) + + go attemptGetHostState(h, stateQueryChan) + + select { + // If we get back useful information, great. Forward it straight to + // the original parent channel. + case hli := <-stateQueryChan: + hostListItemsChan <- hli + + // Otherwise, give up after a predetermined duration. + case <-time.After(timeout): + hostListItemsChan <- HostListItem{ + Name: h.Name, + DriverName: h.Driver.DriverName(), + State: state.Timeout, + ResponseTime: timeout, + } + } +} + +func getHostListItems(hostList []*host.Host, hostsInError map[string]error, timeout time.Duration) []HostListItem { + log.Debugf("timeout set to %s", timeout) + + hostListItems := []HostListItem{} + hostListItemsChan := make(chan HostListItem) + + for _, h := range hostList { + go getHostState(h, hostListItemsChan, timeout) + } + + for range hostList { + hostListItems = append(hostListItems, <-hostListItemsChan) + } + + close(hostListItemsChan) + + for name, err := range hostsInError { + hostListItems = append(hostListItems, newHostListItemInError(name, err)) + } + + sortHostListItemsByName(hostListItems) + return hostListItems +} + +func newHostListItemInError(name string, err error) HostListItem { + return HostListItem{ + Name: name, + DriverName: "not found", + State: state.Error, + Error: strings.Replace(err.Error(), "\n", "", -1), + } +} + +func sortHostListItemsByName(items []HostListItem) { + m := make(map[string]HostListItem, len(items)) + s := make([]string, len(items)) + for i, v := range items { + name := strings.ToLower(v.Name) + m[name] = v + s[i] = name + } + sort.Sort(naturalsort.NaturalSort(s)) + for i, v := range s { + items[i] = m[v] + } +} + +func isActive(currentState state.State, hostURL string) bool { + return currentState == state.Running && hostURL == os.Getenv("DOCKER_HOST") +} + +func isSwarmActive(currentState state.State, hostURL string, isMaster bool, swarmHost string) bool { + return isMaster && currentState == state.Running && toSwarmURL(hostURL, swarmHost) == os.Getenv("DOCKER_HOST") +} + +func urlPort(urlWithPort string) string { + parts := strings.Split(urlWithPort, ":") + return parts[len(parts)-1] +} + +func toSwarmURL(hostURL string, swarmHost string) string { + hostPort := urlPort(hostURL) + swarmPort := urlPort(swarmHost) + return strings.Replace(hostURL, ":"+hostPort, ":"+swarmPort, 1) +} diff --git a/commands/ls_test.go b/commands/ls_test.go new file mode 100644 index 0000000000..3e8bf3112b --- /dev/null +++ b/commands/ls_test.go @@ -0,0 +1,535 @@ +package commands + +import ( + "os" + "testing" + + "time" + + "errors" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/mcndockerclient" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/swarm" + "github.com/stretchr/testify/assert" +) + +func TestParseFiltersErrorsGivenInvalidFilter(t *testing.T) { + _, err := parseFilters([]string{"foo=bar"}) + assert.EqualError(t, err, "Unsupported filter key 'foo'") +} + +func TestParseFiltersSwarm(t *testing.T) { + actual, _ := parseFilters([]string{"swarm=foo"}) + assert.Equal(t, actual, FilterOptions{SwarmName: []string{"foo"}}) +} + +func TestParseFiltersDriver(t *testing.T) { + actual, _ := parseFilters([]string{"driver=bar"}) + assert.Equal(t, actual, FilterOptions{DriverName: []string{"bar"}}) +} + +func TestParseFiltersState(t *testing.T) { + actual, _ := parseFilters([]string{"state=Running"}) + assert.Equal(t, actual, FilterOptions{State: []string{"Running"}}) +} + +func TestParseFiltersName(t *testing.T) { + actual, _ := parseFilters([]string{"name=dev"}) + assert.Equal(t, actual, FilterOptions{Name: []string{"dev"}}) +} + +func TestParseFiltersLabel(t *testing.T) { + actual, err := parseFilters([]string{"label=com.example.foo=bar"}) + assert.EqualValues(t, actual, FilterOptions{Labels: []string{"com.example.foo=bar"}}) + assert.Nil(t, err, "returned err value must be Nil") +} + +func TestParseFiltersAll(t *testing.T) { + actual, _ := parseFilters([]string{"swarm=foo", "driver=bar", "state=Stopped", "name=dev"}) + assert.Equal(t, actual, FilterOptions{SwarmName: []string{"foo"}, DriverName: []string{"bar"}, State: []string{"Stopped"}, Name: []string{"dev"}}) +} + +func TestParseFiltersAllCase(t *testing.T) { + actual, err := parseFilters([]string{"sWarM=foo", "DrIver=bar", "StaTe=Stopped", "NAMe=dev", "LABEL=com=foo"}) + assert.Equal(t, actual, FilterOptions{SwarmName: []string{"foo"}, DriverName: []string{"bar"}, State: []string{"Stopped"}, Name: []string{"dev"}, Labels: []string{"com=foo"}}) + assert.Nil(t, err, "err should be nil") +} + +func TestParseFiltersDuplicates(t *testing.T) { + actual, _ := parseFilters([]string{"swarm=foo", "driver=bar", "name=mark", "swarm=baz", "driver=qux", "state=Running", "state=Starting", "name=time"}) + assert.Equal(t, actual, FilterOptions{SwarmName: []string{"foo", "baz"}, DriverName: []string{"bar", "qux"}, State: []string{"Running", "Starting"}, Name: []string{"mark", "time"}}) +} + +func TestParseFiltersValueWithEqual(t *testing.T) { + actual, _ := parseFilters([]string{"driver=bar=baz"}) + assert.Equal(t, actual, FilterOptions{DriverName: []string{"bar=baz"}}) +} + +func TestFilterHostsReturnsFiltersValuesCaseInsensitive(t *testing.T) { + opts := FilterOptions{ + SwarmName: []string{"fOo"}, + DriverName: []string{"ViRtUaLboX"}, + State: []string{"StOPpeD"}, + Labels: []string{"com.EXAMPLE.app=FOO"}, + } + hosts := []*host.Host{} + actual := filterHosts(hosts, opts) + assert.EqualValues(t, actual, hosts) +} +func TestFilterHostsReturnsSameGivenNoFilters(t *testing.T) { + opts := FilterOptions{} + hosts := []*host.Host{ + { + Name: "testhost", + DriverName: "fakedriver", + }, + } + actual := filterHosts(hosts, opts) + assert.EqualValues(t, actual, hosts) +} + +func TestFilterHostsReturnSetLabel(t *testing.T) { + opts := FilterOptions{ + Labels: []string{"com.class.foo=bar"}, + } + hosts := []*host.Host{ + { + Name: "testhost", + DriverName: "fakedriver", + HostOptions: &host.Options{ + EngineOptions: &engine.Options{ + Labels: []string{"com.class.foo=bar"}, + }, + }, + }, + } + actual := filterHosts(hosts, opts) + assert.EqualValues(t, actual, hosts) +} + +func TestFilterHostsReturnsEmptyGivenEmptyHosts(t *testing.T) { + opts := FilterOptions{ + SwarmName: []string{"foo"}, + } + hosts := []*host.Host{} + assert.Empty(t, filterHosts(hosts, opts)) +} + +func TestFilterHostsReturnsEmptyGivenNonMatchingFilters(t *testing.T) { + opts := FilterOptions{ + SwarmName: []string{"foo"}, + } + hosts := []*host.Host{ + { + Name: "testhost", + DriverName: "fakedriver", + }, + } + assert.Empty(t, filterHosts(hosts, opts)) +} + +func TestFilterHostsBySwarmName(t *testing.T) { + opts := FilterOptions{ + SwarmName: []string{"master"}, + } + master := + &host.Host{ + Name: "master", + HostOptions: &host.Options{ + SwarmOptions: &swarm.Options{Master: true, Discovery: "foo"}, + }, + } + node1 := + &host.Host{ + Name: "node1", + HostOptions: &host.Options{ + SwarmOptions: &swarm.Options{Master: false, Discovery: "foo"}, + }, + } + othermaster := + &host.Host{ + Name: "othermaster", + HostOptions: &host.Options{ + SwarmOptions: &swarm.Options{Master: true, Discovery: "bar"}, + }, + } + hosts := []*host.Host{master, node1, othermaster} + expected := []*host.Host{master, node1} + + assert.EqualValues(t, filterHosts(hosts, opts), expected) +} + +func TestFilterHostsByDriverName(t *testing.T) { + opts := FilterOptions{ + DriverName: []string{"fakedriver"}, + } + node1 := + &host.Host{ + Name: "node1", + DriverName: "fakedriver", + } + node2 := + &host.Host{ + Name: "node2", + DriverName: "virtualbox", + } + node3 := + &host.Host{ + Name: "node3", + DriverName: "fakedriver", + } + hosts := []*host.Host{node1, node2, node3} + expected := []*host.Host{node1, node3} + + assert.EqualValues(t, filterHosts(hosts, opts), expected) +} + +func TestFilterHostsByState(t *testing.T) { + opts := FilterOptions{ + State: []string{"Paused", "Saved", "Stopped"}, + } + node1 := + &host.Host{ + Name: "node1", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{MockState: state.Paused}, + } + node2 := + &host.Host{ + Name: "node2", + DriverName: "virtualbox", + Driver: &fakedriver.Driver{MockState: state.Stopped}, + } + node3 := + &host.Host{ + Name: "node3", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{MockState: state.Running}, + } + hosts := []*host.Host{node1, node2, node3} + expected := []*host.Host{node1, node2} + + assert.EqualValues(t, filterHosts(hosts, opts), expected) +} + +func TestFilterHostsByName(t *testing.T) { + opts := FilterOptions{ + Name: []string{"fire", "ice", "earth", "a.?r"}, + } + node1 := + &host.Host{ + Name: "fire", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{MockState: state.Paused, MockName: "fire"}, + } + node2 := + &host.Host{ + Name: "ice", + DriverName: "adriver", + Driver: &fakedriver.Driver{MockState: state.Paused, MockName: "ice"}, + } + node3 := + &host.Host{ + Name: "air", + DriverName: "nodriver", + Driver: &fakedriver.Driver{MockState: state.Paused, MockName: "air"}, + } + node4 := + &host.Host{ + Name: "water", + DriverName: "falsedriver", + Driver: &fakedriver.Driver{MockState: state.Paused, MockName: "water"}, + } + hosts := []*host.Host{node1, node2, node3, node4} + expected := []*host.Host{node1, node2, node3} + + assert.EqualValues(t, filterHosts(hosts, opts), expected) +} + +func TestFilterHostsMultiFlags(t *testing.T) { + opts := FilterOptions{ + SwarmName: []string{}, + DriverName: []string{"fakedriver", "virtualbox"}, + } + node1 := + &host.Host{ + Name: "node1", + DriverName: "fakedriver", + } + node2 := + &host.Host{ + Name: "node2", + DriverName: "virtualbox", + } + node3 := + &host.Host{ + Name: "node3", + DriverName: "softlayer", + } + hosts := []*host.Host{node1, node2, node3} + expected := []*host.Host{node1, node2} + + assert.EqualValues(t, filterHosts(hosts, opts), expected) +} + +func TestFilterHostsDifferentFlagsProduceAND(t *testing.T) { + opts := FilterOptions{ + DriverName: []string{"virtualbox"}, + State: []string{"Running"}, + } + + hosts := []*host.Host{ + { + Name: "node1", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{MockState: state.Paused}, + }, + { + Name: "node2", + DriverName: "virtualbox", + Driver: &fakedriver.Driver{MockState: state.Stopped}, + }, + { + Name: "node3", + DriverName: "fakedriver", + Driver: &fakedriver.Driver{MockState: state.Running}, + }, + } + + assert.Empty(t, filterHosts(hosts, opts)) +} + +func TestGetHostListItems(t *testing.T) { + defer func(versioner mcndockerclient.DockerVersioner) { mcndockerclient.CurrentDockerVersioner = versioner }(mcndockerclient.CurrentDockerVersioner) + mcndockerclient.CurrentDockerVersioner = &mcndockerclient.FakeDockerVersioner{Version: "1.9"} + + // TODO: Ideally this would mockable via interface instead. + defer func(host string) { os.Setenv("DOCKER_HOST", host) }(os.Getenv("DOCKER_HOST")) + os.Setenv("DOCKER_HOST", "tcp://active.host.com:2376") + + hosts := []*host.Host{ + { + Name: "foo", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "active.host.com", + }, + }, + { + Name: "bar100", + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + }, + { + Name: "bar10", + Driver: &fakedriver.Driver{ + MockState: state.Error, + }, + }, + } + + expected := []struct { + name string + state state.State + active bool + version string + error string + }{ + {"bar10", state.Error, false, "Unknown", "Unable to get ip"}, + {"bar100", state.Stopped, false, "Unknown", ""}, + {"foo", state.Running, true, "v1.9", ""}, + } + + items := getHostListItems(hosts, map[string]error{}, 10*time.Second) + + for i := range expected { + assert.Equal(t, expected[i].name, items[i].Name) + assert.Equal(t, expected[i].state, items[i].State) + assert.Equal(t, expected[i].active, items[i].ActiveHost) + assert.Equal(t, expected[i].version, items[i].DockerVersion) + assert.Equal(t, expected[i].error, items[i].Error) + } +} + +func TestGetHostListItemsEnvDockerHostUnset(t *testing.T) { + defer func(versioner mcndockerclient.DockerVersioner) { mcndockerclient.CurrentDockerVersioner = versioner }(mcndockerclient.CurrentDockerVersioner) + mcndockerclient.CurrentDockerVersioner = &mcndockerclient.FakeDockerVersioner{Version: "1.9"} + + defer func(host string) { os.Setenv("DOCKER_HOST", host) }(os.Getenv("DOCKER_HOST")) + os.Unsetenv("DOCKER_HOST") + + hosts := []*host.Host{ + { + Name: "foo", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "120.0.0.1", + }, + }, + { + Name: "bar", + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + }, + { + Name: "baz", + Driver: &fakedriver.Driver{ + MockState: state.Saved, + }, + }, + } + + expected := map[string]struct { + state state.State + active bool + }{ + "foo": {state.Running, false}, + "bar": {state.Stopped, false}, + "baz": {state.Saved, false}, + } + + items := getHostListItems(hosts, map[string]error{}, 10*time.Second) + + for _, item := range items { + expected := expected[item.Name] + + assert.Equal(t, expected.state, item.State) + assert.Equal(t, expected.active, item.ActiveHost) + } +} + +func TestIsActive(t *testing.T) { + cases := []struct { + dockerHost string + state state.State + expected bool + }{ + {"", state.Running, false}, + {"tcp://5.6.7.8:2376", state.Running, false}, + {"tcp://1.2.3.4:2376", state.Stopped, false}, + {"tcp://1.2.3.4:2376", state.Running, true}, + {"tcp://1.2.3.4:3376", state.Running, false}, + } + + for _, c := range cases { + os.Unsetenv("DOCKER_HOST") + if c.dockerHost != "" { + os.Setenv("DOCKER_HOST", c.dockerHost) + } + + actual := isActive(c.state, "tcp://1.2.3.4:2376") + + assert.Equal(t, c.expected, actual) + } +} + +func TestIsSwarmActive(t *testing.T) { + cases := []struct { + dockerHost string + state state.State + isMaster bool + expected bool + }{ + {"", state.Running, false, false}, + {"tcp://5.6.7.8:3376", state.Running, true, false}, + {"tcp://1.2.3.4:3376", state.Stopped, true, false}, + {"tcp://1.2.3.4:3376", state.Running, true, true}, + {"tcp://1.2.3.4:3376", state.Running, false, false}, + {"tcp://1.2.3.4:2376", state.Running, true, false}, + } + + for _, c := range cases { + os.Unsetenv("DOCKER_HOST") + if c.dockerHost != "" { + os.Setenv("DOCKER_HOST", c.dockerHost) + } + + actual := isSwarmActive(c.state, "tcp://1.2.3.4:2376", c.isMaster, "tcp://0.0.0.0:3376") + + assert.Equal(t, c.expected, actual) + } +} + +func TestGetHostStateTimeout(t *testing.T) { + hosts := []*host.Host{ + { + Name: "foo", + Driver: &fakedriver.Driver{ + MockState: state.Timeout, + }, + }, + } + + hostItem := getHostListItems(hosts, nil, time.Millisecond)[0] + + assert.Equal(t, "foo", hostItem.Name) + assert.Equal(t, state.Timeout, hostItem.State) + assert.Equal(t, "Driver", hostItem.DriverName) + assert.Equal(t, time.Millisecond, hostItem.ResponseTime) +} + +func TestGetHostStateError(t *testing.T) { + hosts := []*host.Host{ + { + Name: "foo", + Driver: &fakedriver.Driver{ + MockState: state.Error, + }, + }, + } + + hostItem := getHostListItems(hosts, nil, 10*time.Second)[0] + + assert.Equal(t, "foo", hostItem.Name) + assert.Equal(t, state.Error, hostItem.State) + assert.Equal(t, "Driver", hostItem.DriverName) + assert.Empty(t, hostItem.URL) + assert.Equal(t, "Unable to get ip", hostItem.Error) + assert.Nil(t, hostItem.SwarmOptions) +} + +func TestGetSomeHostInError(t *testing.T) { + defer func(versioner mcndockerclient.DockerVersioner) { mcndockerclient.CurrentDockerVersioner = versioner }(mcndockerclient.CurrentDockerVersioner) + mcndockerclient.CurrentDockerVersioner = &mcndockerclient.FakeDockerVersioner{Version: "1.9"} + + hosts := []*host.Host{ + { + Name: "foo", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + } + hostsInError := map[string]error{ + "bar": errors.New("invalid memory address or nil pointer dereference"), + } + + hostItems := getHostListItems(hosts, hostsInError, 10*time.Second) + assert.Equal(t, 2, len(hostItems)) + + hostItem := hostItems[0] + assert.Equal(t, "bar", hostItem.Name) + assert.Equal(t, state.Error, hostItem.State) + assert.Equal(t, "not found", hostItem.DriverName) + assert.Empty(t, hostItem.URL) + assert.Equal(t, "invalid memory address or nil pointer dereference", hostItem.Error) + assert.Nil(t, hostItem.SwarmOptions) + + hostItem = hostItems[1] + assert.Equal(t, "foo", hostItem.Name) + assert.Equal(t, state.Running, hostItem.State) +} + +func TestOnErrorWithMultilineComment(t *testing.T) { + err := errors.New("missing parameter: the request must contain the parameter InstanceId\n status code: 400") + + itemInError := newHostListItemInError("foo", err) + + assert.Equal(t, itemInError.Error, "missing parameter: the request must contain the parameter InstanceId status code: 400") +} diff --git a/commands/mcndirs/utils.go b/commands/mcndirs/utils.go new file mode 100644 index 0000000000..3181e7c86c --- /dev/null +++ b/commands/mcndirs/utils.go @@ -0,0 +1,27 @@ +package mcndirs + +import ( + "os" + "path/filepath" + + "github.com/docker/machine/libmachine/mcnutils" +) + +var ( + BaseDir = os.Getenv("MACHINE_STORAGE_PATH") +) + +func GetBaseDir() string { + if BaseDir == "" { + BaseDir = filepath.Join(mcnutils.GetHomeDir(), ".docker", "machine") + } + return BaseDir +} + +func GetMachineDir() string { + return filepath.Join(GetBaseDir(), "machines") +} + +func GetMachineCertDir() string { + return filepath.Join(GetBaseDir(), "certs") +} diff --git a/commands/mcndirs/utils_test.go b/commands/mcndirs/utils_test.go new file mode 100644 index 0000000000..9fca65f7ca --- /dev/null +++ b/commands/mcndirs/utils_test.go @@ -0,0 +1,70 @@ +package mcndirs + +import ( + "path" + "strings" + "testing" + + "github.com/docker/machine/libmachine/mcnutils" +) + +func TestGetBaseDir(t *testing.T) { + // reset any override env var + BaseDir = "" + + homeDir := mcnutils.GetHomeDir() + baseDir := GetBaseDir() + + if strings.Index(baseDir, homeDir) != 0 { + t.Fatalf("expected base dir with prefix %s; received %s", homeDir, baseDir) + } +} + +func TestGetCustomBaseDir(t *testing.T) { + root := "/tmp" + BaseDir = root + baseDir := GetBaseDir() + + if strings.Index(baseDir, root) != 0 { + t.Fatalf("expected base dir with prefix %s; received %s", root, baseDir) + } + BaseDir = "" +} + +func TestGetMachineDir(t *testing.T) { + root := "/tmp" + BaseDir = root + machineDir := GetMachineDir() + + if strings.Index(machineDir, root) != 0 { + t.Fatalf("expected machine dir with prefix %s; received %s", root, machineDir) + } + + path, filename := path.Split(machineDir) + if strings.Index(path, root) != 0 { + t.Fatalf("expected base path of %s; received %s", root, path) + } + if filename != "machines" { + t.Fatalf("expected machine dir \"machines\"; received %s", filename) + } + BaseDir = "" +} + +func TestGetMachineCertDir(t *testing.T) { + root := "/tmp" + BaseDir = root + clientDir := GetMachineCertDir() + + if strings.Index(clientDir, root) != 0 { + t.Fatalf("expected machine client cert dir with prefix %s; received %s", root, clientDir) + } + + path, filename := path.Split(clientDir) + if strings.Index(path, root) != 0 { + t.Fatalf("expected base path of %s; received %s", root, path) + } + if filename != "certs" { + t.Fatalf("expected machine client dir \"certs\"; received %s", filename) + } + BaseDir = "" +} diff --git a/commands/mount.go b/commands/mount.go new file mode 100644 index 0000000000..947195ad3e --- /dev/null +++ b/commands/mount.go @@ -0,0 +1,136 @@ +package commands + +import ( + "errors" + "fmt" + "os" + "os/exec" + "strings" + + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +var ( + // TODO: possibly move this to ssh package + baseSSHFSArgs = []string{ + "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null", + "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." + } +) + +func cmdMount(c CommandLine, api libmachine.API) error { + args := c.Args() + if len(args) < 1 || len(args) > 2 { + c.ShowHelp() + return errWrongNumberArguments + } + + src := args[0] + dest := "" + if len(args) > 1 { + dest = args[1] + } + + hostInfoLoader := &storeHostInfoLoader{api} + + cmd, err := getMountCmd(src, dest, c.Bool("unmount"), hostInfoLoader) + if err != nil { + return err + } + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + return cmd.Run() +} + +func getMountCmd(src, dest string, unmount bool, hostInfoLoader HostInfoLoader) (*exec.Cmd, error) { + var cmdPath string + var err error + if !unmount { + cmdPath, err = exec.LookPath("sshfs") + if err != nil { + return nil, errors.New("You must have a copy of the sshfs binary locally to use the mount feature") + } + } else { + cmdPath, err = exec.LookPath("fusermount") + if err != nil { + return nil, errors.New("You must have a copy of the fusermount binary locally to use the unmount option") + } + } + + srcHost, srcUser, srcPath, srcOpts, err := getInfoForSshfsArg(src, hostInfoLoader) + if err != nil { + return nil, err + } + + if dest == "" { + dest = srcPath + } + + sshArgs := baseSSHFSArgs + if srcHost.GetSSHKeyPath() != "" { + sshArgs = append(sshArgs, "-o", "IdentitiesOnly=yes") + } + + // Append needed -i / private key flags to command. + sshArgs = append(sshArgs, srcOpts...) + + // Append actual arguments for the sshfs command (i.e. docker@:/path) + locationArg, err := generateLocationArg(srcHost, srcUser, srcPath) + if err != nil { + return nil, err + } + + if !unmount { + sshArgs = append(sshArgs, locationArg) + sshArgs = append(sshArgs, dest) + } else { + sshArgs = []string{"-u"} + sshArgs = append(sshArgs, dest) + } + + cmd := exec.Command(cmdPath, sshArgs...) + log.Debug(*cmd) + return cmd, nil +} + +func getInfoForSshfsArg(hostAndPath string, hostInfoLoader HostInfoLoader) (h HostInfo, user string, path string, args []string, err error) { + // Path with hostname. e.g. "hostname:/usr/bin/cmatrix" + var hostName string + if parts := strings.SplitN(hostAndPath, ":", 2); len(parts) < 2 { + hostName = defaultMachineName + path = parts[0] + } else { + hostName = parts[0] + path = parts[1] + } + if hParts := strings.SplitN(hostName, "@", 2); len(hParts) == 2 { + user, hostName = hParts[0], hParts[1] + } + + // Remote path + h, err = hostInfoLoader.load(hostName) + if err != nil { + return nil, "", "", nil, fmt.Errorf("Error loading host: %s", err) + } + + args = []string{} + port, err := h.GetSSHPort() + if err == nil && port > 0 { + args = append(args, "-o", fmt.Sprintf("Port=%v", port)) + } + + if h.GetSSHKeyPath() != "" { + args = append(args, "-o", fmt.Sprintf("IdentityFile=%s", h.GetSSHKeyPath())) + } + + if user == "" { + user = h.GetSSHUsername() + } + + return +} diff --git a/commands/mount_test.go b/commands/mount_test.go new file mode 100644 index 0000000000..8f27c3d53c --- /dev/null +++ b/commands/mount_test.go @@ -0,0 +1,84 @@ +package commands + +import ( + "os/exec" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetMountCmd(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + ip: "12.34.56.78", + sshPort: 234, + sshUsername: "root", + sshKeyPath: "/fake/keypath/id_rsa", + }} + + path, err := exec.LookPath("sshfs") + if err != nil { + t.Skip("sshfs not found (install sshfs ?)") + } + cmd, err := getMountCmd("myfunhost:/home/docker/foo", "/tmp/foo", false, &hostInfoLoader) + + expectedArgs := append( + baseSSHFSArgs, + "-o", + "IdentitiesOnly=yes", + "-o", + "Port=234", + "-o", + "IdentityFile=/fake/keypath/id_rsa", + "root@12.34.56.78:/home/docker/foo", + "/tmp/foo", + ) + expectedCmd := exec.Command(path, expectedArgs...) + + assert.Equal(t, expectedCmd, cmd) + assert.NoError(t, err) +} + +func TestGetMountCmdWithoutSshKey(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + ip: "1.2.3.4", + sshUsername: "user", + }} + + path, err := exec.LookPath("sshfs") + if err != nil { + t.Skip("sshfs not found (install sshfs ?)") + } + cmd, err := getMountCmd("myfunhost:/home/docker/foo", "", false, &hostInfoLoader) + + expectedArgs := append( + baseSSHFSArgs, + "user@1.2.3.4:/home/docker/foo", + "/home/docker/foo", + ) + expectedCmd := exec.Command(path, expectedArgs...) + + assert.Equal(t, expectedCmd, cmd) + assert.NoError(t, err) +} + +func TestGetMountCmdUnmount(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + ip: "1.2.3.4", + sshUsername: "user", + }} + + path, err := exec.LookPath("fusermount") + if err != nil { + t.Skip("fusermount not found (install fuse ?)") + } + cmd, err := getMountCmd("myfunhost:/home/docker/foo", "/tmp/foo", true, &hostInfoLoader) + + expectedArgs := []string{ + "-u", + "/tmp/foo", + } + expectedCmd := exec.Command(path, expectedArgs...) + + assert.Equal(t, expectedCmd, cmd) + assert.NoError(t, err) +} diff --git a/commands/provision.go b/commands/provision.go new file mode 100644 index 0000000000..d7070413b9 --- /dev/null +++ b/commands/provision.go @@ -0,0 +1,7 @@ +package commands + +import "github.com/docker/machine/libmachine" + +func cmdProvision(c CommandLine, api libmachine.API) error { + return runAction("provision", c, api) +} diff --git a/commands/provision_test.go b/commands/provision_test.go new file mode 100644 index 0000000000..53f1bb1527 --- /dev/null +++ b/commands/provision_test.go @@ -0,0 +1,67 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/provision" + "github.com/docker/machine/libmachine/swarm" + "github.com/stretchr/testify/assert" +) + +func TestCmdProvision(t *testing.T) { + testCases := []struct { + commandLine CommandLine + api libmachine.API + expectedErr error + }{ + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"foo", "bar"}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "foo", + Driver: &fakedriver.Driver{}, + HostOptions: &host.Options{ + EngineOptions: &engine.Options{}, + AuthOptions: &auth.Options{}, + SwarmOptions: &swarm.Options{}, + }, + }, + { + Name: "bar", + Driver: &fakedriver.Driver{}, + HostOptions: &host.Options{ + EngineOptions: &engine.Options{}, + AuthOptions: &auth.Options{}, + SwarmOptions: &swarm.Options{}, + }, + }, + }, + }, + expectedErr: nil, + }, + } + + provision.SetDetector(&provision.FakeDetector{ + Provisioner: provision.NewFakeProvisioner(nil), + }) + + // fakeprovisioner always returns "true" for compatible host, so we + // just need to register it. + provision.Register("fakeprovisioner", &provision.RegisteredProvisioner{ + New: provision.NewFakeProvisioner, + }) + + for _, tc := range testCases { + assert.Equal(t, tc.expectedErr, cmdProvision(tc.commandLine, tc.api)) + } +} diff --git a/commands/regeneratecerts.go b/commands/regeneratecerts.go new file mode 100644 index 0000000000..70cbd7de62 --- /dev/null +++ b/commands/regeneratecerts.go @@ -0,0 +1,26 @@ +package commands + +import ( + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +func cmdRegenerateCerts(c CommandLine, api libmachine.API) error { + if !c.Bool("force") { + ok, err := confirmInput("Regenerate TLS machine certs? Warning: this is irreversible.") + if err != nil { + return err + } + + if !ok { + return nil + } + } + + log.Infof("Regenerating TLS certificates") + + if c.Bool("client-certs") { + return runAction("configureAllAuth", c, api) + } + return runAction("configureAuth", c, api) +} diff --git a/commands/restart.go b/commands/restart.go new file mode 100644 index 0000000000..1b197f9e47 --- /dev/null +++ b/commands/restart.go @@ -0,0 +1,16 @@ +package commands + +import ( + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +func cmdRestart(c CommandLine, api libmachine.API) error { + if err := runAction("restart", c, api); err != nil { + return err + } + + log.Info("Restarted machines may have new IP addresses. You may need to re-run the `docker-machine env` command.") + + return nil +} diff --git a/commands/rm.go b/commands/rm.go new file mode 100644 index 0000000000..2e282b530d --- /dev/null +++ b/commands/rm.go @@ -0,0 +1,89 @@ +package commands + +import ( + "fmt" + + "strings" + + "errors" + + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +func cmdRm(c CommandLine, api libmachine.API) error { + if len(c.Args()) == 0 { + c.ShowHelp() + return ErrNoMachineSpecified + } + + log.Info(fmt.Sprintf("About to remove %s", strings.Join(c.Args(), ", "))) + log.Warn("WARNING: This action will delete both local reference and remote instance.") + + force := c.Bool("force") + confirm := c.Bool("y") + var errorOccurred []string + + if !userConfirm(confirm, force) { + return nil + } + + for _, hostName := range c.Args() { + err := removeRemoteMachine(hostName, api) + if err != nil { + errorOccurred = collectError(fmt.Sprintf("Error removing host %q: %s", hostName, err), force, errorOccurred) + } + + if err == nil || force { + removeErr := removeLocalMachine(hostName, api) + if removeErr != nil { + errorOccurred = collectError(fmt.Sprintf("Can't remove \"%s\"", hostName), force, errorOccurred) + } else { + log.Infof("Successfully removed %s", hostName) + } + } + } + + if len(errorOccurred) > 0 && !force { + return errors.New(strings.Join(errorOccurred, "\n")) + } + + return nil +} + +func userConfirm(confirm bool, force bool) bool { + if confirm || force { + return true + } + + sure, err := confirmInput(fmt.Sprintf("Are you sure?")) + if err != nil { + return false + } + + return sure +} + +func removeRemoteMachine(hostName string, api libmachine.API) error { + currentHost, loaderr := api.Load(hostName) + if loaderr != nil { + return loaderr + } + + return currentHost.Driver.Remove() +} + +func removeLocalMachine(hostName string, api libmachine.API) error { + exist, _ := api.Exists(hostName) + if !exist { + return errors.New(hostName + " does not exist.") + } + return api.Remove(hostName) +} + +func collectError(message string, force bool, errorOccurred []string) []string { + if force { + log.Error(message) + } + return append(errorOccurred, message) +} diff --git a/commands/rm_test.go b/commands/rm_test.go new file mode 100644 index 0000000000..adfe6a29ae --- /dev/null +++ b/commands/rm_test.go @@ -0,0 +1,233 @@ +package commands + +import ( + "testing" + + "errors" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/stretchr/testify/assert" +) + +func TestCmdRmMissingMachineName(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{} + api := &libmachinetest.FakeAPI{} + + err := cmdRm(commandLine, api) + + assert.Equal(t, ErrNoMachineSpecified, err) + assert.True(t, commandLine.HelpShown) +} + +func TestCmdRm(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1", "machineToRemove2"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "y": true, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &fakedriver.Driver{}, + }, + { + Name: "machineToRemove2", + Driver: &fakedriver.Driver{}, + }, + { + Name: "machine", + Driver: &fakedriver.Driver{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.NoError(t, err) + + assert.False(t, libmachinetest.Exists(api, "machineToRemove1")) + assert.False(t, libmachinetest.Exists(api, "machineToRemove2")) + assert.True(t, libmachinetest.Exists(api, "machine")) +} + +func TestCmdRmforcefully(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1", "machineToRemove2"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "force": true, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &fakedriver.Driver{}, + }, + { + Name: "machineToRemove2", + Driver: &fakedriver.Driver{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.NoError(t, err) + + assert.False(t, libmachinetest.Exists(api, "machineToRemove1")) + assert.False(t, libmachinetest.Exists(api, "machineToRemove2")) +} + +func TestCmdRmforceDoesAutoConfirm(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1", "machineToRemove2"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "y": false, + "force": true, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &fakedriver.Driver{}, + }, + { + Name: "machineToRemove2", + Driver: &fakedriver.Driver{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.NoError(t, err) + + assert.False(t, libmachinetest.Exists(api, "machineToRemove1")) + assert.False(t, libmachinetest.Exists(api, "machineToRemove2")) +} + +func TestCmdRmforceConfirmUnset(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "y": false, + "force": false, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &fakedriver.Driver{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.NoError(t, err) + + assert.True(t, libmachinetest.Exists(api, "machineToRemove1")) +} + +type DriverWithRemoveWhichFail struct { + fakedriver.Driver +} + +func (d *DriverWithRemoveWhichFail) Remove() error { + return errors.New("unknown error") +} + +func TestDontStopWhenADriverRemovalFails(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1", "machineToRemove2", "machineToRemove3"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "y": true, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &fakedriver.Driver{}, + }, + { + Name: "machineToRemove2", + Driver: &DriverWithRemoveWhichFail{}, + }, + { + Name: "machineToRemove3", + Driver: &fakedriver.Driver{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.EqualError(t, err, "Error removing host \"machineToRemove2\": unknown error") + + assert.False(t, libmachinetest.Exists(api, "machineToRemove1")) + assert.True(t, libmachinetest.Exists(api, "machineToRemove2")) + assert.False(t, libmachinetest.Exists(api, "machineToRemove3")) +} + +func TestForceRemoveEvenWhenItFails(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "y": true, + "force": true, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &DriverWithRemoveWhichFail{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.NoError(t, err) + + assert.False(t, libmachinetest.Exists(api, "machineToRemove1")) +} + +func TestDontRemoveMachineIsRemovalFailsAndNotForced(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1"}, + LocalFlags: &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "y": true, + "force": false, + }, + }, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToRemove1", + Driver: &DriverWithRemoveWhichFail{}, + }, + }, + } + + err := cmdRm(commandLine, api) + assert.EqualError(t, err, "Error removing host \"machineToRemove1\": unknown error") + + assert.True(t, libmachinetest.Exists(api, "machineToRemove1")) +} diff --git a/commands/scp.go b/commands/scp.go new file mode 100644 index 0000000000..eb635ee792 --- /dev/null +++ b/commands/scp.go @@ -0,0 +1,196 @@ +package commands + +import ( + "errors" + "fmt" + "os" + "os/exec" + "strings" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/persist" +) + +var ( + errWrongNumberArguments = errors.New("Improper number of arguments") + + // TODO: possibly move this to ssh package + baseSSHArgs = []string{ + "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null", + "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." + } +) + +// HostInfo gives the mandatory information to connect to a host. +type HostInfo interface { + GetMachineName() string + + GetSSHHostname() (string, error) + + GetSSHPort() (int, error) + + GetSSHUsername() string + + GetSSHKeyPath() string +} + +// HostInfoLoader loads host information. +type HostInfoLoader interface { + load(name string) (HostInfo, error) +} + +type storeHostInfoLoader struct { + store persist.Store +} + +func (s *storeHostInfoLoader) load(name string) (HostInfo, error) { + host, err := s.store.Load(name) + if err != nil { + return nil, fmt.Errorf("Error loading host: %s", err) + } + + return host.Driver, nil +} + +func getScpCmd(src, dest string, recursive bool, delta bool, quiet bool, hostInfoLoader HostInfoLoader) (*exec.Cmd, error) { + var cmdPath string + var err error + if !delta { + cmdPath, err = exec.LookPath("scp") + if err != nil { + return nil, errors.New("You must have a copy of the scp binary locally to use the scp feature") + } + } else { + cmdPath, err = exec.LookPath("rsync") + if err != nil { + return nil, errors.New("You must have a copy of the rsync binary locally to use the --delta option") + } + } + + srcHost, srcUser, srcPath, srcOpts, err := getInfoForScpArg(src, hostInfoLoader) + if err != nil { + return nil, err + } + + destHost, destUser, destPath, destOpts, err := getInfoForScpArg(dest, hostInfoLoader) + if err != nil { + return nil, err + } + + // TODO: Check that "-3" flag is available in user's version of scp. + // It is on every system I've checked, but the manual mentioned it's "newer" + sshArgs := baseSSHArgs + if !delta { + sshArgs = append(sshArgs, "-3") + if recursive { + sshArgs = append(sshArgs, "-r") + } + if quiet { + sshArgs = append(sshArgs, "-q") + } + } + + // Don't use ssh-agent if both hosts have explicit ssh keys + if !missesExplicitSSHKey(srcHost) && !missesExplicitSSHKey(destHost) { + sshArgs = append(sshArgs, "-o", "IdentitiesOnly=yes") + } + + // Append needed -i / private key flags to command. + sshArgs = append(sshArgs, srcOpts...) + sshArgs = append(sshArgs, destOpts...) + + // Append actual arguments for the scp command (i.e. docker@:/path) + locationArg, err := generateLocationArg(srcHost, srcUser, srcPath) + if err != nil { + return nil, err + } + + // TODO: Check that "--progress" flag is available in user's version of rsync. + // Use quiet mode as a workaround, if it should happen to not be supported... + if delta { + sshArgs = append([]string{"-e"}, "ssh "+strings.Join(sshArgs, " ")) + if !quiet { + sshArgs = append([]string{"--progress"}, sshArgs...) + } + if recursive { + sshArgs = append(sshArgs, "-r") + } + } + + sshArgs = append(sshArgs, locationArg) + locationArg, err = generateLocationArg(destHost, destUser, destPath) + if err != nil { + return nil, err + } + sshArgs = append(sshArgs, locationArg) + + cmd := exec.Command(cmdPath, sshArgs...) + log.Debug(*cmd) + return cmd, nil +} + +func missesExplicitSSHKey(hostInfo HostInfo) bool { + return hostInfo != nil && hostInfo.GetSSHKeyPath() == "" +} + +func getInfoForScpArg(hostAndPath string, hostInfoLoader HostInfoLoader) (h HostInfo, user string, path string, args []string, err error) { + // Local path. e.g. "/tmp/foo" + if !strings.Contains(hostAndPath, ":") { + return nil, "", hostAndPath, nil, nil + } + + // Path with hostname. e.g. "hostname:/usr/bin/cmatrix" + parts := strings.SplitN(hostAndPath, ":", 2) + hostName := parts[0] + if hParts := strings.SplitN(hostName, "@", 2); len(hParts) == 2 { + user, hostName = hParts[0], hParts[1] + } + path = parts[1] + if hostName == "localhost" { + return nil, "", path, nil, nil + } + + // Remote path + h, err = hostInfoLoader.load(hostName) + if err != nil { + return nil, "", "", nil, fmt.Errorf("Error loading host: %s", err) + } + + args = []string{} + port, err := h.GetSSHPort() + if err == nil && port > 0 { + args = append(args, "-o", fmt.Sprintf("Port=%v", port)) + } + + if h.GetSSHKeyPath() != "" { + args = append(args, "-o", fmt.Sprintf("IdentityFile=%q", h.GetSSHKeyPath())) + } + + return +} + +func generateLocationArg(hostInfo HostInfo, user, path string) (string, error) { + if hostInfo == nil { + return path, nil + } + + hostname, err := hostInfo.GetSSHHostname() + if err != nil { + return "", err + } + + if user == "" { + user = hostInfo.GetSSHUsername() + } + location := fmt.Sprintf("%s@%s:%s", user, hostname, path) + return location, nil +} + +func runCmdWithStdIo(cmd exec.Cmd) error { + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + return cmd.Run() +} diff --git a/commands/scp_test.go b/commands/scp_test.go new file mode 100644 index 0000000000..9e89432072 --- /dev/null +++ b/commands/scp_test.go @@ -0,0 +1,179 @@ +package commands + +import ( + "os/exec" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +type MockHostInfo struct { + name string + ip string + sshPort int + sshUsername string + sshKeyPath string +} + +func (h *MockHostInfo) GetMachineName() string { + return h.name +} + +func (h *MockHostInfo) GetSSHHostname() (string, error) { + return h.ip, nil +} + +func (h *MockHostInfo) GetSSHPort() (int, error) { + return h.sshPort, nil +} + +func (h *MockHostInfo) GetSSHUsername() string { + return h.sshUsername +} + +func (h *MockHostInfo) GetSSHKeyPath() string { + return h.sshKeyPath +} + +type MockHostInfoLoader struct { + hostInfo MockHostInfo +} + +func (l *MockHostInfoLoader) load(name string) (HostInfo, error) { + info := l.hostInfo + info.name = name + return &info, nil +} + +func TestGetInfoForLocalScpArg(t *testing.T) { + host, user, path, opts, err := getInfoForScpArg("/tmp/foo", nil) + assert.Nil(t, host) + assert.Empty(t, user) + assert.Equal(t, "/tmp/foo", path) + assert.Nil(t, opts) + assert.NoError(t, err) + + host, user, path, opts, err = getInfoForScpArg("localhost:C:\\path", nil) + assert.Nil(t, host) + assert.Empty(t, user) + assert.Equal(t, "C:\\path", path) + assert.Nil(t, opts) + assert.NoError(t, err) +} + +func TestGetInfoForRemoteScpArg(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + sshKeyPath: "/fake/keypath/id_rsa", + }} + + host, user, path, opts, err := getInfoForScpArg("myuser@myfunhost:/home/docker/foo", &hostInfoLoader) + assert.Equal(t, "myfunhost", host.GetMachineName()) + assert.Equal(t, "myuser", user) + assert.Equal(t, "/home/docker/foo", path) + assert.Equal(t, []string{"-o", `IdentityFile="/fake/keypath/id_rsa"`}, opts) + assert.NoError(t, err) + + host, user, path, opts, err = getInfoForScpArg("myfunhost:C:\\path", &hostInfoLoader) + assert.Equal(t, "myfunhost", host.GetMachineName()) + assert.Empty(t, user) + assert.Equal(t, "C:\\path", path) + assert.Equal(t, []string{"-o", `IdentityFile="/fake/keypath/id_rsa"`}, opts) + assert.NoError(t, err) +} + +func TestHostLocation(t *testing.T) { + arg, err := generateLocationArg(nil, "user1", "/home/docker/foo") + + assert.Equal(t, "/home/docker/foo", arg) + assert.NoError(t, err) +} + +func TestRemoteLocation(t *testing.T) { + hostInfo := MockHostInfo{ + ip: "12.34.56.78", + sshUsername: "root", + } + + arg, err := generateLocationArg(&hostInfo, "", "/home/docker/foo") + + assert.Equal(t, "root@12.34.56.78:/home/docker/foo", arg) + assert.NoError(t, err) + + argWithUser, err := generateLocationArg(&hostInfo, "user1", "/home/docker/foo") + + assert.Equal(t, "user1@12.34.56.78:/home/docker/foo", argWithUser) + assert.NoError(t, err) +} + +func TestGetScpCmd(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + ip: "12.34.56.78", + sshPort: 234, + sshUsername: "root", + sshKeyPath: "/fake/keypath/id_rsa", + }} + + cmd, err := getScpCmd("/tmp/foo", "myfunhost:/home/docker/foo", true, false, false, &hostInfoLoader) + + expectedArgs := append( + baseSSHArgs, + "-3", + "-r", + "-o", + "IdentitiesOnly=yes", + "-o", + "Port=234", + "-o", + `IdentityFile="/fake/keypath/id_rsa"`, + "/tmp/foo", + "root@12.34.56.78:/home/docker/foo", + ) + expectedCmd := exec.Command("/usr/bin/scp", expectedArgs...) + + assert.Equal(t, expectedCmd, cmd) + assert.NoError(t, err) +} + +func TestGetScpCmdWithoutSshKey(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + ip: "1.2.3.4", + sshUsername: "user", + }} + + cmd, err := getScpCmd("/tmp/foo", "myfunhost:/home/docker/foo", true, false, false, &hostInfoLoader) + + expectedArgs := append( + baseSSHArgs, + "-3", + "-r", + "/tmp/foo", + "user@1.2.3.4:/home/docker/foo", + ) + expectedCmd := exec.Command("/usr/bin/scp", expectedArgs...) + + assert.Equal(t, expectedCmd, cmd) + assert.NoError(t, err) +} + +func TestGetScpCmdWithDelta(t *testing.T) { + hostInfoLoader := MockHostInfoLoader{MockHostInfo{ + ip: "1.2.3.4", + sshUsername: "user", + }} + + cmd, err := getScpCmd("/tmp/foo", "myfunhost:/home/docker/foo", true, true, false, &hostInfoLoader) + + expectedArgs := append( + []string{"--progress"}, + "-e", + "ssh "+strings.Join(baseSSHArgs, " "), + "-r", + "/tmp/foo", + "user@1.2.3.4:/home/docker/foo", + ) + expectedCmd := exec.Command("/usr/bin/rsync", expectedArgs...) + + assert.Equal(t, expectedCmd, cmd) + assert.NoError(t, err) +} diff --git a/commands/scp_unix.go b/commands/scp_unix.go new file mode 100644 index 0000000000..d26cf384e2 --- /dev/null +++ b/commands/scp_unix.go @@ -0,0 +1,27 @@ +// +build !windows + +package commands + +import ( + "github.com/docker/machine/libmachine" +) + +func cmdScp(c CommandLine, api libmachine.API) error { + args := c.Args() + if len(args) != 2 { + c.ShowHelp() + return errWrongNumberArguments + } + + src := args[0] + dest := args[1] + + hostInfoLoader := &storeHostInfoLoader{api} + + cmd, err := getScpCmd(src, dest, c.Bool("recursive"), c.Bool("delta"), c.Bool("quiet"), hostInfoLoader) + if err != nil { + return err + } + + return runCmdWithStdIo(*cmd) +} diff --git a/commands/scp_windows.go b/commands/scp_windows.go new file mode 100644 index 0000000000..5a3b124b4f --- /dev/null +++ b/commands/scp_windows.go @@ -0,0 +1,34 @@ +package commands + +import ( + "fmt" + "strings" + "syscall" + + "github.com/docker/machine/libmachine" +) + +func cmdScp(c CommandLine, api libmachine.API) error { + args := c.Args() + if len(args) != 2 { + c.ShowHelp() + return errWrongNumberArguments + } + + src := args[0] + dest := args[1] + + hostInfoLoader := &storeHostInfoLoader{api} + + cmd, err := getScpCmd(src, dest, c.Bool("recursive"), c.Bool("delta"), c.Bool("quiet"), hostInfoLoader) + if err != nil { + return err + } + + // Default argument escaping is not valid for scp.exe with quoted arguments, so we do it ourselves + // see golang/go#15566 + cmd.SysProcAttr = &syscall.SysProcAttr{} + cmd.SysProcAttr.CmdLine = fmt.Sprintf("%s %s", cmd.Path, strings.Join(cmd.Args, " ")) + + return runCmdWithStdIo(*cmd) +} diff --git a/commands/ssh.go b/commands/ssh.go new file mode 100644 index 0000000000..3c34174c09 --- /dev/null +++ b/commands/ssh.go @@ -0,0 +1,51 @@ +package commands + +import ( + "fmt" + + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/state" +) + +type errStateInvalidForSSH struct { + HostName string +} + +func (e errStateInvalidForSSH) Error() string { + return fmt.Sprintf("Error: Cannot run SSH command: Host %q is not running", e.HostName) +} + +func cmdSSH(c CommandLine, api libmachine.API) error { + // Check for help flag -- Needed due to SkipFlagParsing + firstArg := c.Args().First() + if firstArg == "-help" || firstArg == "--help" || firstArg == "-h" { + c.ShowHelp() + return nil + } + + target, err := targetHost(c, api) + if err != nil { + return err + } + + host, err := api.Load(target) + if err != nil { + return err + } + + currentState, err := host.Driver.GetState() + if err != nil { + return err + } + + if currentState != state.Running { + return errStateInvalidForSSH{host.Name} + } + + client, err := host.CreateSSHClient() + if err != nil { + return err + } + + return client.Shell(c.Args().Tail()...) +} diff --git a/commands/ssh_test.go b/commands/ssh_test.go new file mode 100644 index 0000000000..ebfa10fdf7 --- /dev/null +++ b/commands/ssh_test.go @@ -0,0 +1,111 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/ssh/sshtest" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +type FakeSSHClientCreator struct { + client ssh.Client +} + +func (fsc *FakeSSHClientCreator) CreateSSHClient(d drivers.Driver) (ssh.Client, error) { + if fsc.client == nil { + fsc.client = &sshtest.FakeClient{} + } + return fsc.client, nil +} + +func TestCmdSSH(t *testing.T) { + testCases := []struct { + commandLine CommandLine + api libmachine.API + expectedErr error + helpShown bool + clientCreator host.SSHClientCreator + expectedShell []string + }{ + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"-h"}, + }, + api: &libmachinetest.FakeAPI{}, + expectedErr: nil, + helpShown: true, + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"--help"}, + }, + api: &libmachinetest.FakeAPI{}, + expectedErr: nil, + helpShown: true, + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{}, + }, + api: &libmachinetest.FakeAPI{}, + expectedErr: ErrNoDefault, + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"default", "df", "-h"}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "default", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + }, + }, + expectedErr: nil, + clientCreator: &FakeSSHClientCreator{}, + expectedShell: []string{"df", "-h"}, + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"default"}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "default", + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + }, + }, + }, + expectedErr: errStateInvalidForSSH{"default"}, + }, + } + + for _, tc := range testCases { + host.SetSSHClientCreator(tc.clientCreator) + + err := cmdSSH(tc.commandLine, tc.api) + assert.Equal(t, err, tc.expectedErr) + + if fcl, ok := tc.commandLine.(*commandstest.FakeCommandLine); ok { + assert.Equal(t, tc.helpShown, fcl.HelpShown) + } + + if fcc, ok := tc.clientCreator.(*FakeSSHClientCreator); ok { + assert.Equal(t, tc.expectedShell, fcc.client.(*sshtest.FakeClient).ActivatedShell) + } + } +} diff --git a/commands/start.go b/commands/start.go new file mode 100644 index 0000000000..09322f1d90 --- /dev/null +++ b/commands/start.go @@ -0,0 +1,16 @@ +package commands + +import ( + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +func cmdStart(c CommandLine, api libmachine.API) error { + if err := runAction("start", c, api); err != nil { + return err + } + + log.Info("Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.") + + return nil +} diff --git a/commands/status.go b/commands/status.go new file mode 100644 index 0000000000..672b8dab0c --- /dev/null +++ b/commands/status.go @@ -0,0 +1,32 @@ +package commands + +import ( + "fmt" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +func cmdStatus(c CommandLine, api libmachine.API) error { + if len(c.Args()) > 1 { + return ErrExpectedOneMachine + } + + target, err := targetHost(c, api) + if err != nil { + return err + } + + host, err := api.Load(target) + if err != nil { + return err + } + + currentState, err := host.Driver.GetState() + if err != nil { + return fmt.Errorf("error getting state for host %s: %s", host.Name, err) + } + + log.Info(currentState) + + return nil +} diff --git a/commands/stop.go b/commands/stop.go new file mode 100644 index 0000000000..bd0cd38658 --- /dev/null +++ b/commands/stop.go @@ -0,0 +1,7 @@ +package commands + +import "github.com/docker/machine/libmachine" + +func cmdStop(c CommandLine, api libmachine.API) error { + return runAction("stop", c, api) +} diff --git a/commands/stop_test.go b/commands/stop_test.go new file mode 100644 index 0000000000..76af0955bc --- /dev/null +++ b/commands/stop_test.go @@ -0,0 +1,103 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +func TestCmdStop(t *testing.T) { + testCases := []struct { + commandLine CommandLine + api libmachine.API + expectedErr error + expectedStates map[string]state.State + }{ + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "default", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + }, + }, + expectedErr: nil, + expectedStates: map[string]state.State{ + "default": state.Stopped, + }, + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "foobar", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + }, + }, + expectedErr: ErrNoDefault, + expectedStates: map[string]state.State{ + "foobar": state.Running, + }, + }, + { + commandLine: &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToStop1", "machineToStop2"}, + }, + api: &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machineToStop1", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + { + Name: "machineToStop2", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + { + Name: "machine", + Driver: &fakedriver.Driver{ + MockState: state.Running, + }, + }, + }, + }, + expectedErr: nil, + expectedStates: map[string]state.State{ + "machineToStop1": state.Stopped, + "machineToStop2": state.Stopped, + "machine": state.Running, + }, + }, + } + + for _, tc := range testCases { + err := cmdStop(tc.commandLine, tc.api) + assert.Equal(t, tc.expectedErr, err) + + for hostName, expectedState := range tc.expectedStates { + assert.Equal(t, expectedState, libmachinetest.State(tc.api, hostName)) + } + } +} diff --git a/commands/upgrade.go b/commands/upgrade.go new file mode 100644 index 0000000000..84282f1651 --- /dev/null +++ b/commands/upgrade.go @@ -0,0 +1,7 @@ +package commands + +import "github.com/docker/machine/libmachine" + +func cmdUpgrade(c CommandLine, api libmachine.API) error { + return runAction("upgrade", c, api) +} diff --git a/commands/url.go b/commands/url.go new file mode 100644 index 0000000000..8552e14bf0 --- /dev/null +++ b/commands/url.go @@ -0,0 +1,32 @@ +package commands + +import ( + "fmt" + + "github.com/docker/machine/libmachine" +) + +func cmdURL(c CommandLine, api libmachine.API) error { + if len(c.Args()) > 1 { + return ErrExpectedOneMachine + } + + target, err := targetHost(c, api) + if err != nil { + return err + } + + host, err := api.Load(target) + if err != nil { + return err + } + + url, err := host.URL() + if err != nil { + return err + } + + fmt.Println(url) + + return nil +} diff --git a/commands/url_test.go b/commands/url_test.go new file mode 100644 index 0000000000..02f72689f6 --- /dev/null +++ b/commands/url_test.go @@ -0,0 +1,57 @@ +package commands + +import ( + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +func TestCmdURLMissingMachineName(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{} + api := &libmachinetest.FakeAPI{} + + err := cmdURL(commandLine, api) + + assert.Equal(t, ErrNoDefault, err) +} + +func TestCmdURLTooManyNames(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machineToRemove1", "machineToRemove2"}, + } + api := &libmachinetest.FakeAPI{} + + err := cmdURL(commandLine, api) + + assert.EqualError(t, err, "Error: Expected one machine name as an argument") +} + +func TestCmdURL(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machine"}, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machine", + Driver: &fakedriver.Driver{ + MockState: state.Running, + MockIP: "120.0.0.1", + }, + }, + }, + } + + stdoutGetter := commandstest.NewStdoutGetter() + defer stdoutGetter.Stop() + + err := cmdURL(commandLine, api) + + assert.NoError(t, err) + assert.Equal(t, "tcp://120.0.0.1:2376\n", stdoutGetter.Output()) +} diff --git a/commands/version.go b/commands/version.go new file mode 100644 index 0000000000..a1a539040f --- /dev/null +++ b/commands/version.go @@ -0,0 +1,40 @@ +package commands + +import ( + "fmt" + + "io" + "os" + + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/mcndockerclient" +) + +func cmdVersion(c CommandLine, api libmachine.API) error { + return printVersion(c, api, os.Stdout) +} + +func printVersion(c CommandLine, api libmachine.API, out io.Writer) error { + if len(c.Args()) == 0 { + c.ShowVersion() + return nil + } + + if len(c.Args()) != 1 { + return ErrExpectedOneMachine + } + + host, err := api.Load(c.Args().First()) + if err != nil { + return err + } + + version, err := mcndockerclient.DockerVersion(host) + if err != nil { + return err + } + + fmt.Fprintln(out, version) + + return nil +} diff --git a/commands/version_test.go b/commands/version_test.go new file mode 100644 index 0000000000..4978f8e135 --- /dev/null +++ b/commands/version_test.go @@ -0,0 +1,89 @@ +package commands + +import ( + "errors" + "testing" + + "bytes" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/libmachinetest" + "github.com/docker/machine/libmachine/mcndockerclient" + "github.com/stretchr/testify/assert" +) + +func TestCmdVersion(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{} + api := &libmachinetest.FakeAPI{} + + err := cmdVersion(commandLine, api) + + assert.True(t, commandLine.VersionShown) + assert.NoError(t, err) +} + +func TestCmdVersionTooManyNames(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machine1", "machine2"}, + } + api := &libmachinetest.FakeAPI{} + + err := cmdVersion(commandLine, api) + + assert.EqualError(t, err, "Error: Expected one machine name as an argument") +} + +func TestCmdVersionNotFound(t *testing.T) { + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"unknown"}, + } + api := &libmachinetest.FakeAPI{} + + err := cmdVersion(commandLine, api) + + assert.EqualError(t, err, `Docker machine "unknown" does not exist. Use "docker-machine ls" to list machines. Use "docker-machine create" to add a new one.`) +} + +func TestCmdVersionOnHost(t *testing.T) { + defer func(versioner mcndockerclient.DockerVersioner) { mcndockerclient.CurrentDockerVersioner = versioner }(mcndockerclient.CurrentDockerVersioner) + mcndockerclient.CurrentDockerVersioner = &mcndockerclient.FakeDockerVersioner{Version: "1.9.1"} + + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machine"}, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machine", + }, + }, + } + + out := &bytes.Buffer{} + err := printVersion(commandLine, api, out) + + assert.NoError(t, err) + assert.Equal(t, "1.9.1\n", out.String()) +} + +func TestCmdVersionFailure(t *testing.T) { + defer func(versioner mcndockerclient.DockerVersioner) { mcndockerclient.CurrentDockerVersioner = versioner }(mcndockerclient.CurrentDockerVersioner) + mcndockerclient.CurrentDockerVersioner = &mcndockerclient.FakeDockerVersioner{Err: errors.New("connection failure")} + + commandLine := &commandstest.FakeCommandLine{ + CliArgs: []string{"machine"}, + } + api := &libmachinetest.FakeAPI{ + Hosts: []*host.Host{ + { + Name: "machine", + }, + }, + } + + out := &bytes.Buffer{} + err := printVersion(commandLine, api, out) + + assert.EqualError(t, err, "connection failure") +} diff --git a/commands_test.go b/commands_test.go deleted file mode 100644 index 0438847997..0000000000 --- a/commands_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package main - -import ( - "io/ioutil" - "os/exec" - "testing" - - drivers "github.com/docker/machine/drivers" - "github.com/docker/machine/state" -) - -type FakeDriver struct { - MockState state.State -} - -func (d *FakeDriver) DriverName() string { - return "fakedriver" -} - -func (d *FakeDriver) SetConfigFromFlags(flags drivers.DriverOptions) error { - return nil -} - -func (d *FakeDriver) GetURL() (string, error) { - return "", nil -} - -func (d *FakeDriver) GetIP() (string, error) { - return "", nil -} - -func (d *FakeDriver) GetState() (state.State, error) { - return d.MockState, nil -} - -func (d *FakeDriver) PreCreateCheck() error { - return nil -} - -func (d *FakeDriver) Create() error { - return nil -} - -func (d *FakeDriver) Remove() error { - return nil -} - -func (d *FakeDriver) Start() error { - return nil -} - -func (d *FakeDriver) Stop() error { - return nil -} - -func (d *FakeDriver) Restart() error { - return nil -} - -func (d *FakeDriver) Kill() error { - return nil -} - -func (d *FakeDriver) Upgrade() error { - return nil -} - -func (d *FakeDriver) StartDocker() error { - return nil -} - -func (d *FakeDriver) StopDocker() error { - return nil -} - -func (d *FakeDriver) GetDockerConfigDir() string { - return "" -} - -func (d *FakeDriver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return &exec.Cmd{}, nil -} - -func TestGetHostState(t *testing.T) { - storePath, err := ioutil.TempDir("", ".docker") - if err != nil { - t.Fatal("Error creating tmp dir:", err) - } - hostListItems := make(chan hostListItem) - store := NewStore(storePath, "", "") - hosts := []Host{ - { - Name: "foo", - DriverName: "fakedriver", - Driver: &FakeDriver{ - MockState: state.Running, - }, - storePath: storePath, - }, - { - Name: "bar", - DriverName: "fakedriver", - Driver: &FakeDriver{ - MockState: state.Stopped, - }, - storePath: storePath, - }, - { - Name: "baz", - DriverName: "fakedriver", - Driver: &FakeDriver{ - MockState: state.Running, - }, - storePath: storePath, - }, - } - expected := map[string]state.State{ - "foo": state.Running, - "bar": state.Stopped, - "baz": state.Running, - } - items := []hostListItem{} - for _, host := range hosts { - go getHostState(host, *store, hostListItems) - } - for i := 0; i < len(hosts); i++ { - items = append(items, <-hostListItems) - } - for _, item := range items { - if expected[item.Name] != item.State { - t.Fatal("Expected state did not match for item", item) - } - } -} diff --git a/contrib/completion/.gitignore b/contrib/completion/.gitignore new file mode 100644 index 0000000000..b9d4dad074 --- /dev/null +++ b/contrib/completion/.gitignore @@ -0,0 +1 @@ +!docker-machine* diff --git a/contrib/completion/bash/docker-machine-prompt.bash b/contrib/completion/bash/docker-machine-prompt.bash new file mode 100644 index 0000000000..0a6e43a85a --- /dev/null +++ b/contrib/completion/bash/docker-machine-prompt.bash @@ -0,0 +1,47 @@ +# +# bash prompt support for docker-machine +# +# This script allows you to see the active machine in your bash prompt. +# +# To enable: +# 1a. Copy this file somewhere and source it in your .bashrc +# source /some/where/docker-machine-prompt.bash +# 1b. Alternatively, just copy this file into into /etc/bash_completion.d +# 2. Change your PS1 to call __docker-machine-ps1 as command-substitution +# PS1='[\u@\h \W$(__docker_machine_ps1 " [%s]")]\$ ' +# +# Configuration: +# +# DOCKER_MACHINE_PS1_SHOWSTATUS +# When set, the machine status is indicated in the prompt. This can be slow, +# so use with care. +# + +__docker_machine_ps1 () { + local format=${1:- [%s]} + if test ${DOCKER_MACHINE_NAME}; then + local status + if test ${DOCKER_MACHINE_PS1_SHOWSTATUS:-false} = true; then + status=$(docker-machine status ${DOCKER_MACHINE_NAME}) + case ${status} in + Running) + status=' R' + ;; + Stopping) + status=' R->S' + ;; + Starting) + status=' S->R' + ;; + Error|Timeout) + status=' E' + ;; + *) + # Just consider everything elase as 'stopped' + status=' S' + ;; + esac + fi + printf -- "${format}" "${DOCKER_MACHINE_NAME}${status}" + fi +} diff --git a/contrib/completion/bash/docker-machine-wrapper.bash b/contrib/completion/bash/docker-machine-wrapper.bash new file mode 100644 index 0000000000..89aabfa3b5 --- /dev/null +++ b/contrib/completion/bash/docker-machine-wrapper.bash @@ -0,0 +1,56 @@ +# +# Function wrapper to docker-machine that adds a use subcommand. +# +# The use subcommand runs `eval "$(docker-machine env [args])"`, which is a lot +# less typing. +# +# To enable: +# 1a. Copy this file somewhere and source it in your .bashrc +# source /some/where/docker-machine-wrapper.bash +# 1b. Alternatively, just copy this file into into /etc/bash_completion.d +# +# Configuration: +# +# DOCKER_MACHINE_WRAPPED +# When set to a value other than true, this will disable the alias wrapper +# alias for docker-machine. This is useful if you don't want the wrapper, +# but it is installed by default by your installation. +# + +: ${DOCKER_MACHINE_WRAPPED:=true} + +__docker_machine_wrapper () { + if [[ "$1" == use ]]; then + # Special use wrapper + shift 1 + case "$1" in + -h|--help|"") + cat </dev/null "$@" +} + +# suppresses trailing whitespace +_docker_machine_nospace() { + # compopt is not available in ancient bash versions (OSX) + # so only call it if it's available + type compopt &>/dev/null && compopt -o nospace +} + +_docker_machine_machines() { + _docker_machine_q ls --format '{{.Name}}' "$@" +} + +_docker_machine_drivers() { + local drivers=( + amazonec2 + azure + digitalocean + exoscale + generic + google + hyperv + openstack + rackspace + softlayer + virtualbox + vmwarefusion + vmwarevcloudair + vmwarevsphere + ) + echo "${drivers[@]}" +} + +_docker_machine_value_of_option() { + local pattern="$1" + for (( i=2; i < ${cword}; ++i)); do + if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then + echo ${words[$i + 1]} + break + fi + done +} + +# Returns `key` if we are currently completing the value of a map option +# (`key=value`) which matches the glob passed in as an argument. +# This function is needed for key-specific argument completions. +_docker_machine_map_key_of_current_option() { + local glob="$1" + + local key glob_pos + if [ "$cur" = "=" ] ; then # key= case + key="$prev" + glob_pos=$((cword - 2)) + elif [[ $cur == *=* ]] ; then # key=value case (OSX) + key=${cur%=*} + glob_pos=$((cword - 1)) + elif [ "$prev" = "=" ] ; then + key=${words[$cword - 2]} # key=value case + glob_pos=$((cword - 3)) + else + return + fi + + [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax + + [[ ${words[$glob_pos]} == $glob ]] && echo "$key" +} + +# Finds the position of the first word that is neither option nor an option's argument. +# If there are options that require arguments, you need to pass a glob describing +# those options, e.g. "--option1|-o|--option2". +# Use this function to restrict completions to exact positions after the options. +_docker_machine_pos_first_nonflag() { + local argument_flags=$1 + + local counter=$((${subcommand_pos:-${command_pos}} + 1)) + while [ "$counter" -le "$cword" ]; do + if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then + (( counter++ )) + # eat "=" in case of --option=arg syntax + [ "${words[$counter]}" = "=" ] && (( counter++ )) + else + case "${words[$counter]}" in + -*) + ;; + *) + break + ;; + esac + fi + + # Bash splits words at "=", retaining "=" as a word, examples: + # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words + while [ "${words[$counter + 1]}" = "=" ] ; do + counter=$(( counter + 2)) + done + + (( counter++ )) + done + + echo $counter +} +# --- completion functions --------------------------------------------------- + +_docker_machine_active() { + case "${prev}" in + --timeout|-t) + return + ;; + esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --timeout -t" -- "${cur}")) + fi +} + +_docker_machine_config() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --swarm" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_create() { + case "${prev}" in + --driver|-d) + COMPREPLY=($(compgen -W "$(_docker_machine_drivers)" -- "${cur}")) + return + ;; + esac + + # driver specific options are only included in help output if --driver is given, + # so we have to pass that option when calling docker-machine to harvest options. + local driver="$(_docker_machine_value_of_option '--driver|-d')" + local parsed_options="$(_docker_machine_q create ${driver:+--driver $driver} --help | grep '^ -' | sed 's/^ //; s/[^a-z0-9-].*$//')" + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "${parsed_options} -d --help" -- "${cur}")) + fi +} + +_docker_machine_env() { + case "${prev}" in + --shell) + COMPREPLY=($(compgen -W "cmd emacs fish powershell tcsh" -- "${cur}")) + return + ;; + esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --no-proxy --shell --swarm --unset -u" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +# See docker-machine-wrapper.bash for the use command +_docker_machine_use() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --swarm --unset" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_inspect() { + case "${prev}" in + --format|-f) + return + ;; + esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--format -f --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_ip() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_kill() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_ls() { + local key=$(_docker_machine_map_key_of_current_option '--filter') + case "$key" in + driver) + COMPREPLY=($(compgen -W "$(_docker_machine_drivers)" -- "${cur##*=}")) + return + ;; + state) + COMPREPLY=($(compgen -W "Error Paused Running Saved Starting Stopped Stopping" -- "${cur##*=}")) + return + ;; + esac + + case "${prev}" in + --filter) + COMPREPLY=($(compgen -W "driver label name state swarm" -S= -- "${cur}")) + _docker_machine_nospace + return + ;; + --format|-f|--timeout|-t) + return + ;; + esac + + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--filter --format -f --help --quiet -q --timeout -t" -- "${cur}")) + fi +} + +_docker_machine_mount() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help --unmount -u" -- "${cur}")) + else + local pos=$(_docker_machine_pos_first_nonflag) + if [ "$cword" -eq "$pos" ]; then + # We can't complete remote filesystems. All we can do here is to complete the machine. + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -S: -- "${cur}")) + _docker_machine_nospace + elif [ "$cword" -eq "$((pos + 1))" ]; then + _filedir -d + fi + fi +} + +_docker_machine_provision() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) + fi +} + +_docker_machine_regenerate_certs() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--client-certs --force -f --help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) + fi +} + +_docker_machine_restart() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_rm() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--force -f --help -y" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_ssh() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_scp() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--delta -d --help --quiet -q --recursive -r" -- "${cur}")) + else + _filedir + # It would be really nice to ssh to the machine and ls to complete + # remote files. + COMPREPLY=($(compgen -W "$(_docker_machine_machines | sed 's/$/:/')" -- "${cur}") "${COMPREPLY[@]}") + fi +} + +_docker_machine_start() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Stopped)" -- "${cur}")) + fi +} + +_docker_machine_status() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_stop() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) + fi +} + +_docker_machine_upgrade() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_url() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_version() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) + fi +} + +_docker_machine_help() { + if [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "--help" -- "${cur}")) + else + COMPREPLY=($(compgen -W "${commands[*]}" -- "${cur}")) + fi +} + +_docker_machine_docker_machine() { + if [[ " ${wants_file[*]} " =~ " ${prev} " ]]; then + _filedir + elif [[ " ${wants_dir[*]} " =~ " ${prev} " ]]; then + _filedir -d + elif [[ "${cur}" == -* ]]; then + COMPREPLY=($(compgen -W "${flags[*]} ${wants_dir[*]} ${wants_file[*]}" -- "${cur}")) + else + COMPREPLY=($(compgen -W "${commands[*]}" -- "${cur}")) + fi +} + +_docker_machine() { + COMPREPLY=() + local commands=(active config create env inspect ip kill ls mount provision regenerate-certs restart rm ssh scp start status stop upgrade url version help) + + local flags=(--debug --native-ssh --github-api-token --bugsnag-api-token --help --version) + local wants_dir=(--storage-path) + local wants_file=(--tls-ca-cert --tls-ca-key --tls-client-cert --tls-client-key) + + # Add the use subcommand, if we have an alias loaded + if [[ ${DOCKER_MACHINE_WRAPPED} = true ]]; then + commands=("${commands[@]}" use) + fi + + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + local i + local command=docker-machine command_pos=0 + + for (( i=1; i < ${cword}; ++i)); do + local word=${words[i]} + if [[ " ${wants_file[*]} ${wants_dir[*]} " =~ " ${word} " ]]; then + # skip the next option + (( ++i )) + elif [[ " ${commands[*]} " =~ " ${word} " ]]; then + command=${word} + command_pos=$i + fi + done + + local completion_func=_docker_machine_"${command//-/_}" + if declare -F "${completion_func}" > /dev/null; then + ${completion_func} + fi + + return 0 +} + +complete -F _docker_machine docker-machine docker-machine.exe diff --git a/contrib/completion/zsh/_docker-machine b/contrib/completion/zsh/_docker-machine new file mode 100644 index 0000000000..7c19ba8e79 --- /dev/null +++ b/contrib/completion/zsh/_docker-machine @@ -0,0 +1,359 @@ +#compdef docker-machine +# Description +# ----------- +# zsh completion for docker-machine +# https://github.com/leonhartX/docker-machine-zsh-completion +# ------------------------------------------------------------------------- +# Version +# ------- +# 0.1.1 +# ------------------------------------------------------------------------- +# Authors +# ------- +# * Ke Xu +# ------------------------------------------------------------------------- +# Inspiration +# ----------- +# * @sdurrheimer docker-compose-zsh-completion https://github.com/sdurrheimer/docker-compose-zsh-completion +# * @ilkka _docker-machine + + +__docker-machine_get_hosts() { + [[ $PREFIX = -* ]] && return 1 + local state + declare -a hosts + state=$1; shift + if [[ $state != all ]]; then + hosts=(${(f)"$(_call_program commands docker-machine ls -q --filter state=$state)"}) + else + hosts=(${(f)"$(_call_program commands docker-machine ls -q)"}) + fi + _describe 'host' hosts "$@" && ret=0 + return ret +} + +__docker-machine_hosts_with_state() { + declare -a hosts + hosts=(${(f)"$(_call_program commands docker-machine ls -f '{{.Name}}\:{{.DriverName}}\({{.State}}\)\ {{.URL}}')"}) + _describe 'host' hosts +} + +__docker-machine_hosts_all() { + __docker-machine_get_hosts all "$@" +} + +__docker-machine_hosts_running() { + __docker-machine_get_hosts Running "$@" +} + +__docker-machine_get_swarm() { + declare -a swarms + swarms=(${(f)"$(_call_program commands docker-machine ls -f {{.Swarm}} | awk '{print $1}')"}) + _describe 'swarm' swarms +} + +__docker-machine_hosts_and_files() { + _alternative "hosts:host:__docker-machine_hosts_all -qS ':'" 'files:files:_path_files' +} + +__docker-machine_filters() { + [[ $PREFIX = -* ]] && return 1 + integer ret=1 + + if compset -P '*='; then + case "${${words[-1]%=*}#*=}" in + (driver) + _describe -t driver-filter-opts "driver filter" opts_driver && ret=0 + ;; + (swarm) + __docker-machine_get_swarm && ret=0 + ;; + (state) + opts_state=('Running' 'Paused' 'Saved' 'Stopped' 'Stopping' 'Starting' 'Error') + _describe -t state-filter-opts "state filter" opts_state && ret=0 + ;; + (name) + __docker-machine_hosts_all && ret=0 + ;; + (label) + _message 'label' && ret=0 + ;; + *) + _message 'value' && ret=0 + ;; + esac + else + opts=('driver' 'swarm' 'state' 'name' 'label') + _describe -t filter-opts "filter" opts -qS "=" && ret=0 + fi + return ret +} + +__get_swarm_discovery() { + declare -a masters serivces + local service + services=() + masters=($(docker-machine ls -f {{.Swarm}} |grep '(master)' |awk '{print $1}')) + for master in $masters; do + service=${${${(f)"$(_call_program commands docker-machine inspect -f '{{.HostOptions.SwarmOptions.Discovery}}:{{.Name}}' $master)"}/:/\\:}} + services=($services $service) + done + _describe -t services "swarm service" services && ret=0 + return ret +} + +__get_create_argument() { + typeset -g docker_machine_driver + if [[ CURRENT -le 2 ]]; then + docker_machine_driver="none" + elif [[ CURRENT > 2 && $words[CURRENT-2] = '-d' || $words[CURRENT-2] = '--driver' ]]; then + docker_machine_driver=$words[CURRENT-1] + elif [[ $words[CURRENT-1] =~ '^(-d|--driver)=' ]]; then + docker_machine_driver=${${words[CURRENT-1]}/*=/} + fi + local driver_opt_cmd + local -a opts_provider opts_common opts_read_argument + opts_read_argument=( + ": :->argument" + ) + opts_common=( + $opts_help \ + '(--driver -d)'{--driver=,-d=}'[Driver to create machine with]:dirver:->driver-option' \ + '--engine-install-url=[Custom URL to use for engine installation]:url' \ + '*--engine-opt=[Specify arbitrary flags to include with the created engine in the form flag=value]:flag' \ + '*--engine-insecure-registry=[Specify insecure registries to allow with the created engine]:registry' \ + '*--engine-registry-mirror=[Specify registry mirrors to use]:mirror' \ + '*--engine-label=[Specify labels for the created engine]:label' \ + '--engine-storage-driver=[Specify a storage driver to use with the engine]:storage-driver:->storage-driver-option' \ + '*--engine-env=[Specify environment variables to set in the engine]:environment' \ + '--swarm[Configure Machine with Swarm]' \ + '--swarm-image=[Specify Docker image to use for Swarm]:image' \ + '--swarm-master[Configure Machine to be a Swarm master]' \ + '--swarm-discovery=[Discovery service to use with Swarm]:service:->swarm-service' \ + '--swarm-strategy=[Define a default scheduling strategy for Swarm]:strategy:(spread binpack random)' \ + '*--swarm-opt=[Define arbitrary flags for swarm]:flag' \ + '*--swarm-join-opt=[Define arbitrary flags for Swarm join]:flag' \ + '--swarm-host=[ip/socket to listen on for Swarm master]:host' \ + '--swarm-addr=[addr to advertise for Swarm (default: detect and use the machine IP)]:address' \ + '--swarm-experimental[Enable Swarm experimental features]' \ + '*--tls-san=[Support extra SANs for TLS certs]:option' + ) + driver_opt_cmd="docker-machine create -d $docker_machine_driver | grep $docker_machine_driver | sed -e 's/\(--.*\)\ *\[\1[^]]*\]/*\1/g' -e 's/\(\[[^]]*\)/\\\\\\1\\\\/g' -e 's/\".*\"\(.*\)/\1/g' | awk '{printf \"%s[\", \$1; for(i=2;i<=NF;i++) {printf \"%s \", \$i}; print \"]\"}'" + if [[ $docker_machine_driver != "none" ]]; then + opts_provider=(${(f)"$(_call_program commands $driver_opt_cmd)"}) + _arguments \ + $opts_provider \ + $opts_read_argument \ + $opts_common && ret=0 + else + _arguments $opts_common && ret=0 + fi + case $state in + (driver-option) + _describe -t driver-option "driver" opts_driver && ret=0 + ;; + (storage-driver-option) + _describe -t storage-driver-option "storage driver" opts_storage_driver && ret=0 + ;; + (swarm-service) + __get_swarm_discovery && ret=0 + ;; + (argument) + ret=0 + ;; + esac + return ret +} + + +__docker-machine_subcommand() { + local -a opts_help + opts_help=("(- :)--help[Print usage]") + local -a opts_only_host opts_driver opts_storage_driver opts_stragery + opts_only_host=( + "$opts_help" + "*:host:__docker-machine_hosts_all" + ) + opts_driver=('amazonec2' 'azure' 'digitalocean' 'exoscale' 'generic' 'google' 'hyperv' 'none' 'openstack' 'rackspace' 'softlayer' 'virtualbox' 'vmwarefusion' 'vmwarevcloudair' 'vmwarevsphere') + opts_storage_driver=('overlay' 'aufs' 'btrfs' 'devicemapper' 'vfs' 'zfs') + integer ret=1 + + case "$words[1]" in + (active) + _arguments \ + $opts_help \ + '(--timeout -t)'{--timeout=,-t=}'[Timeout in seconds, default to 10s]:seconds' && ret=0 + ;; + (config) + _arguments \ + $opts_help \ + '--swarm[Display the Swarm config instead of the Docker daemon]' \ + "*:host:__docker-machine_hosts_all" && ret=0 + ;; + (create) + __get_create_argument + ;; + (env) + _arguments \ + $opts_help \ + '--swarm[Display the Swarm config instead of the Docker daemon]' \ + '--shell=[Force environment to be configured for a specified shell: \[fish, cmd, powershell\], default is auto-detect]:shell' \ + '(--unset -u)'{--unset,-u}'[Unset variables instead of setting them]' \ + '--no-proxy[Add machine IP to NO_PROXY environment variable]' \ + '*:host:__docker-machine_hosts_running' && ret=0 + ;; + (help) + _arguments ':subcommand:__docker-machine_commands' && ret=0 + ;; + (inspect) + _arguments \ + $opts_help \ + '(--format -f)'{--format=,-f=}'[Format the output using the given go template]:template' \ + '*:host:__docker-machine_hosts_all' && ret=0 + ;; + (ip) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_running' && ret=0 + ;; + (kill) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_with_state' && ret=0 + ;; + (ls) + _arguments \ + $opts_help \ + '(--quiet -q)'{--quiet,-q}'[Enable quiet mode]' \ + '*--filter=[Filter output based on conditions provided]:filter:->filter-options' \ + '(--timeout -t)'{--timeout=,-t=}'[Timeout in seconds, default to 10s]:seconds' \ + '(--format -f)'{--format=,-f=}'[Pretty-print machines using a Go template]:template' && ret=0 + case $state in + (filter-options) + __docker-machine_filters && ret=0 + ;; + esac + ;; + (provision) + _arguments $opts_only_host && ret=0 + ;; + (regenerate-certs) + _arguments \ + $opts_help \ + '(--force -f)'{--force,-f}'[Force rebuild and do not prompt]' \ + '*:host:__docker-machine_hosts_all' && ret=0 + ;; + (restart) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_with_state' && ret=0 + ;; + (rm) + _arguments \ + $opts_help \ + '(--force -f)'{--force,-f}'[Remove local configuration even if machine cannot be removed, also implies an automatic yes (`-y`)]' \ + '-y[Assumes automatic yes to proceed with remove, without prompting further user confirmation]' \ + '*:host:__docker-machine_hosts_with_state' && ret=0 + ;; + (scp) + _arguments \ + $opts_help \ + '(--recursive -r)'{--recursive,-r}'[Copy files recursively (required to copy directories))]' \ + '*:files:__docker-machine_hosts_and_files' && ret=0 + ;; + (ssh) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_running' && ret=0 + ;; + (start) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_with_state' && ret=0 + ;; + (status) + _arguments $opts_only_host && ret=0 + ;; + (stop) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_with_state' && ret=0 + ;; + (upgrade) + _arguments $opts_only_host && ret=0 + ;; + (url) + _arguments \ + $opts_help \ + '*:host:__docker-machine_hosts_running' && ret=0 + ;; + esac + + return ret +} + + +__docker-machine_commands() { + local cache_policy + + zstyle -s ":completion:${curcontext}:" cache-policy cache_policy + if [[ -z "$cache_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy __docker-machine_caching_policy + fi + + if ( [[ ${+_docker_machine_subcommands} -eq 0 ]] || _cache_invalid docker_machine_subcommands) \ + && ! _retrieve_cache docker_machine_subcommands; + then + local -a lines + lines=(${(f)"$(_call_program commands docker-machine 2>&1)"}) + _docker_machine_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I) *]}]}## #}/$'\t'##/:}) + (( $#_docker_machine_subcommands > 0 )) && _store_cache docker_machine_subcommands _docker_machine_subcommands + fi + _describe -t docker-machine-commands "docker-machine command" _docker_machine_subcommands +} + +__docker-machine_caching_policy() { + oldp=( "$1"(Nmh+1) ) + (( $#oldp )) +} + +_docker-machine() { + if [[ $service != docker-machine ]]; then + _call_function - _$service + return + fi + + local curcontext="$curcontext" state line + integer ret=1 + typeset -A opt_args + + _arguments -C \ + "(- :)"{-h,--help}"[Show help]" \ + "(-D --debug)"{-D,--debug}"[Enable debug mode]" \ + '(-s --stroage-path)'{-s,--storage-path}'[Configures storage path]:file:_files' \ + '--tls-ca-cert[CA to verify remotes against]:file:_files' \ + '--tls-ca-key[Private key to generate certificates]:file:_files' \ + '--tls-client-cert[Client cert to use for TLS]:file:_files' \ + '--tls-client-key[Private key used in client TLS auth]:file:_files' \ + '--github-api-token[Token to use for requests to the Github API]' \ + '--native-ssh[Use the native (Go-based) SSH implementation.]' \ + '--bugsnag-api-token[BugSnag API token for crash reporting]' \ + '(- :)'{-v,--version}'[Print the version]' \ + "(-): :->command" \ + "(-)*:: :->option-or-argument" && ret=0 + + case $state in + (command) + __docker-machine_commands && ret=0 + ;; + (option-or-argument) + curcontext=${curcontext%:*:*}:docker-machine-$words[1]: + __docker-machine_subcommand && ret=0 + ret=0 + ;; + esac + + return ret +} + +_docker-machine "$@" diff --git a/doc.go b/doc.go new file mode 100644 index 0000000000..6ae3312203 --- /dev/null +++ b/doc.go @@ -0,0 +1,4 @@ +// Package machine defines interfaces to manage a variety of docker instances +// deployed on different backends (VMs, baremetal). +// The goal is to allow users get from zero to docker as fast as possible. +package machine diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..f743e5b84d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,16 @@ +# The docs have been moved! + +The documentation for Docker Machine has been merged into +[the general documentation repo](https://github.com/docker/docker.github.io). + +The docs for Docker Machine are now here: +https://github.com/docker/docker.github.io/tree/master/machine + +Please submit pull requests for unpublished features on the `vnext-machine` branch (https://github.com/docker/docker.github.io/tree/vnext-machine). + +If you submit a PR to this codebase that has a docs impact, create a second docs PR on `docker.github.io`. Use the docs PR template provided (coming soon - watch this space). + +PRs for typos, additional information, etc. for already-published features should be labeled as `okay-to-publish` (we are still settling on a naming convention, will provide a label soon). You can submit these PRs either to `vnext-machine` or directly to `master` on `docker.github.io` + +As always, the docs in the general repo remain open-source and we appreciate +your feedback and pull requests! diff --git a/docs/dockermachine.md b/docs/dockermachine.md deleted file mode 100644 index feeb530cef..0000000000 --- a/docs/dockermachine.md +++ /dev/null @@ -1,706 +0,0 @@ -page_title: Working with Docker Machine -page_description: Working with Docker Machine -page_keywords: docker, machine, virtualbox, digitalocean, amazonec2 - -# Working with Docker Machine - -## Overview - -In order to run Docker containers, you must have a -[Docker daemon](https://docs.docker.com/arch) running somewhere. If you’re on a -Linux system and you want to run a container on your local machine, this is -straightforward: you run the daemon on your local machine and communicate with -it over the Unix socket located at `/var/run/docker.sock` (this all happens -behind the scenes when you run `docker` on the command line). However, if you -want to control containers from Mac OSX / Windows or manage them on a remote -server, you’ll need to create a new machine (probably a virtual machine) with -Docker installed and execute Docker commands for that host remotely. -Traditionally, the way to do this was either: - -- manual (open the web interface or virtualization application, make the machine -yourself, manually install Docker, etc.) and therefore tedious and error-prone -- with existing automation technologies, which usually entail a quite high skill -threshold - -Docker's [`docker-machine`](https://github.com/docker/machine) is a tool for making the -process of creating and managing those machines (and running Docker commands -against them) much faster and easier for users. `docker-machine` allows users to -quickly create running instances of the Docker daemon on local virtualization -platforms (e.g. Virtualbox) or on cloud providers (e.g. AWS EC2) that they can -connect to and control from their local Docker client binary. - -## Installation - -Docker Machine is supported on Windows, OSX, and Linux. To install Docker -Machine, download the appropriate binary for your OS and architecture to the -correct place in your `PATH`: - -- [Windows - x86_64]() -- [OSX - x86_64]() -- [Linux - x86_64]() -- [Windows - i386]() -- [OSX - i386]() -- [Linux - i386]() - -Now you should be able to check the version with `docker-machine -v`: - -``` -$ docker-machine -v -machine version 0.1.0 -``` - -## Getting started with Docker Machine using a local VM - -Let's take a look at using `docker-machine` to creating, using, and managing a Docker -host inside of [VirtualBox](ihttps://www.virtualbox.org/). - -First, ensure that -[VirtualBox 4.3.20](https://www.virtualbox.org/wiki/Downloads) is correctly -installed on your system. - -If you run the `docker-machine ls` command to show all available machines, you will see -that none have been created so far. - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -``` - -To create one, we run the `docker-machine create` command, passing the string -`virtualbox` to the `--driver` flag. The final argument we pass is the name of -the machine - in this case, we will name our machine "dev". - -This will download a lightweight Linux distribution -([boot2docker](https://github.com/boot2docker/boot2docker)) with the Docker -daemon installed, and will create and start a VirtualBox VM with Docker running. - - -``` -$ docker-machine create --driver virtualbox dev -INFO[0000] Creating SSH key... -INFO[0000] Creating VirtualBox VM... -INFO[0007] Starting VirtualBox VM... -INFO[0007] Waiting for VM to start... -INFO[0038] "dev" has been created and is now the active machine -INFO[0038] To connect: docker $(docker-machine config dev) ps -``` - -To use the Docker CLI, you can use the `env` command to list the commands -needed to connect to the instance. - -``` -$ docker-machine env dev -export DOCKER_TLS_VERIFY=yes -export DOCKER_CERT_PATH=/home/ehazlett/.docker/machines/.client -export DOCKER_HOST=tcp://192.168.99.100:2376 - -``` - -You can see the machine you have created by running the `docker-machine ls` command -again: - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Running tcp://192.168.99.100:2376 -``` - -The `*` next to `dev` indicates that it is the active host. - -Next, as noted in the output of the `docker-machine create` command, we have to tell -Docker to talk to that machine. You can do this with the `docker-machine config` -command. For example, - -``` -$ docker $(docker-machine config dev) ps -``` - -This will pass arguments to the Docker client that specify the TLS settings. -To see what will be passed, run `docker-machine config dev`. - -You can now run Docker commands on this host: - -``` -$ docker $(docker-machine config dev) run busybox echo hello world -Unable to find image 'busybox' locally -Pulling repository busybox -e72ac664f4f0: Download complete -511136ea3c5a: Download complete -df7546f9f060: Download complete -e433a6c5b276: Download complete -hello world -``` - -Any exposed ports are available on the Docker host’s IP address, which you can -get using the `docker-machine ip` command: - -``` -$ docker-machine ip -192.168.99.100 -``` - -Now you can manage as many local VMs running Docker as you please- just run -`docker-machine create` again. - -If you are finished using a host, you can stop it with `docker stop` and start -it again with `docker start`: - -``` -$ docker-machine stop -$ docker-machine start -``` - -If they aren't passed any arguments, commands such as `docker-machine stop` will run -against the active host (in this case, the VirtualBox VM). You can also specify -a host to run a command against as an argument. For instance, you could also -have written: - -``` -$ docker-machine stop dev -$ docker-machine start dev -``` - -## Using Docker Machine with a cloud provider - -One of the nice things about `docker-machine` is that it provides several “drivers” -which let you use the same interface to create hosts on many different cloud -platforms. This is accomplished by using the `docker-machine create` command with the - `--driver` flag. Here we will be demonstrating the -[Digital Ocean](https://digitalocean.com) driver (called `digitalocean`), but -there are drivers included for several providers including Amazon Web Services, -Google Compute Engine, and Microsoft Azure. - -Usually it is required that you pass account verification credentials for these -providers as flags to `docker-machine create`. These flags are unique for each driver. -For instance, to pass a Digital Ocean access token you use the -`--digitalocean-access-token` flag. - -Let's take a look at how to do this. - -To generate your access token: - -1. Go to the Digital Ocean administrator panel and click on "Apps and API" in -the side panel. -2. Click on "Generate New Token". -3. Give the token a clever name (e.g. "machine"), make sure the "Write" checkbox -is checked, and click on "Generate Token". -4. Grab the big long hex string that is generated (this is your token) and store it somehwere safe. - -Now, run `docker-machine create` with the `digitalocean` driver and pass your key to -the `--digitalocean-access-token` flag. - -Example: - -``` -$ docker-machine create \ - --driver digitalocean \ - --digitalocean-access-token 0ab77166d407f479c6701652cee3a46830fef88b8199722b87821621736ab2d4 \ - staging -INFO[0000] Creating SSH key... -INFO[0000] Creating Digital Ocean droplet... -INFO[0002] Waiting for SSH... -INFO[0085] "staging" has been created and is now the active machine -INFO[0085] To connect: docker $(docker-machine config dev) staging -``` - -For convenience, `docker-machine` will use sensible defaults for choosing settings such - as the image that the VPS is based on, but they can also be overridden using -their respective flags (e.g. `--digitalocean-image`). This is useful if, for -instance, you want to create a nice large instance with a lot of memory and CPUs -(by default `docker-machine` creates a small VPS). For a full list of the -flags/settings available and their defaults, see the output of -`docker-machine create -h`. - -When the creation of a host is initiated, a unique SSH key for accessing the -host (initially for provisioning, then directly later if the user runs the -`docker-machine ssh` command) will be created automatically and stored in the client's -directory in `~/.docker/machines`. After the creation of the SSH key, Docker -will be installed on the remote machine and the daemon will be configured to -accept remote connections over TCP using TLS for authentication. Once this -is finished, the host is ready for connection. - -And then from this point, the remote host behaves much like the local host we -created in the last section. If we look at `docker-machine`, we’ll see it is now the -active host: - -``` -$ docker-machine active dev -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev virtualbox Running tcp://192.168.99.103:2376 -staging * digitalocean Running tcp://104.236.50.118:2376 -``` - -To select an active host, you can use the `docker-machine active` command. - -``` -$ docker-machine active dev -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Running tcp://192.168.99.103:2376 -staging digitalocean Running tcp://104.236.50.118:2376 -``` - -To remove a host and all of its containers and images, use `docker-machine rm`: - -``` -$ docker-machine rm dev staging -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -``` - -## Adding a host without a driver - -You can add a host to Docker which only has a URL and no driver. Therefore it -can be used an alias for an existing host so you don’t have to type out the URL -every time you run a Docker command. - -``` -$ docker-machine create --url=tcp://50.134.234.20:2376 custombox -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -custombox * none Running tcp://50.134.234.20:2376 -``` - -## Subcommands - -#### active - -Get or set the active machine. - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev virtualbox Running tcp://192.168.99.103:2376 -staging * digitalocean Running tcp://104.236.50.118:2376 -$ docker-machine active dev -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Running tcp://192.168.99.103:2376 -staging digitalocean Running tcp://104.236.50.118:2376 -``` - -#### create - -Create a machine. - -``` -$ docker-machine create --driver virtualbox dev -INFO[0000] Creating SSH key... -INFO[0000] Creating VirtualBox VM... -INFO[0007] Starting VirtualBox VM... -INFO[0007] Waiting for VM to start... -INFO[0038] "dev" has been created and is now the active machine. To point Docker at this machine, run: export DOCKER_HOST=$(docker-machine url) DOCKER_AUTH=identity -``` - -#### config - -Show the Docker client configuration for a machine. - -``` -$ docker-machine config dev ---tls --tlscacert=/Users/ehazlett/.docker/machines/dev/ca.pem --tlscert=/Users/ehazlett/.docker/machines/dev/cert.pem --tlskey=/Users/ehazlett/.docker/machines/dev/key.pem -H tcp://192.168.99.103:2376 -``` - -#### inspect - -Inspect information about a machine. - -``` -$ docker-machine inspect dev -{ - "DriverName": "virtualbox", - "Driver": { - "MachineName": "docker-host-128be8d287b2028316c0ad5714b90bcfc11f998056f2f790f7c1f43f3d1e6eda", - "SSHPort": 55834, - "Memory": 1024, - "DiskSize": 20000, - "Boot2DockerURL": "" - } -} -``` - -#### help - -Show help text. - -#### ip - -Get the IP address of a machine. - -``` -$ docker-machine ip -192.168.99.104 -``` - -#### kill - -Kill (abruptly force stop) a machine. - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Running tcp://192.168.99.104:2376 -$ docker-machine kill dev -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Stopped -``` - -#### ls - -List machines. - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev virtualbox Stopped -foo0 virtualbox Running tcp://192.168.99.105:2376 -foo1 virtualbox Running tcp://192.168.99.106:2376 -foo2 virtualbox Running tcp://192.168.99.107:2376 -foo3 virtualbox Running tcp://192.168.99.108:2376 -foo4 * virtualbox Running tcp://192.168.99.109:2376 -``` - -#### restart - -Restart a machine. Oftentimes this is equivalent to -`docker-machine stop; machine start`. - -``` -$ docker-machine restart -INFO[0005] Waiting for VM to start... -``` - -#### rm - -Remove a machine. This will remove the local reference as well as delete it -on the cloud provider or virtualization management platform. - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -foo0 virtualbox Running tcp://192.168.99.105:2376 -foo1 virtualbox Running tcp://192.168.99.106:2376 -$ docker-machine rm foo1 -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -foo0 virtualbox Running tcp://192.168.99.105:2376 -``` - -#### ssh - -Log into or run a command on a machine using SSH. - -``` -$ docker-machine ssh -c "echo this process ran on a remote machine" -this process ran on a remote machine -$ docker-machine ssh - ## . - ## ## ## == - ## ## ## ## === - /""""""""""""""""\___/ === - ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ - \______ o __/ - \ \ __/ - \____\______/ - _ _ ____ _ _ -| |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ -| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| -| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | -|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| -Boot2Docker version 1.4.0, build master : 69cf398 - Fri Dec 12 01:39:42 UTC 2014 -docker@boot2docker:~$ ls / -Users/ dev/ home/ lib/ mnt/ proc/ run/ sys/ usr/ -bin/ etc/ init linuxrc opt/ root/ sbin/ tmp var/ -``` - -#### start - -Gracefully start a machine. - -``` -$ docker-machine restart -INFO[0005] Waiting for VM to start... -``` - -#### stop - -Gracefully stop a machine. - -``` -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Running tcp://192.168.99.104:2376 -$ docker-machine stop dev -$ docker-machine ls -NAME ACTIVE DRIVER STATE URL -dev * virtualbox Stopped -``` - -#### upgrade - -Upgrade a machine to the latest version of Docker. - -``` -$ docker-machine upgrade dev -``` - -#### url - -Get the URL of a host - -``` -$ docker-machine url -tcp://192.168.99.109:2376 -``` - -## Drivers - -TODO: List all possible values (where applicable) for all flags for every -driver. - -#### Amazon Web Services -Create machines on [Amazon Web Services](http://aws.amazon.com). You will need an Access Key ID, Secret Access Key and a VPC ID. To find the VPC ID, login to the AWS console and go to Services -> VPC -> Your VPCs. Select the one where you would like to launch the instance. - -Options: - - - `--amazonec2-access-key`: **required** Your access key id for the Amazon Web Services API. - - `--amazonec2-ami`: The AMI ID of the instance to use Default: `ami-4ae27e22` - - `--amazonec2-instance-type`: The instance type to run. Default: `t2.micro` - - `--amazonec2-region`: The region to use when launching the instance. Default: `us-east-1` - - `--amazonec2-root-size`: The root disk size of the instance (in GB). Default: `16` - - `--amazonec2-secret-key`: **required** Your secret access key for the Amazon Web Services API. - - `--amazonec2-security-group`: AWS VPC security group name. Default: `docker-machine` - - `--amazonec2-session-token`: Your session token for the Amazon Web Services API. - - `--amazonec2-subnet-id`: AWS VPC subnet id - - `--amazonec2-vpc-id`: **required** Your VPC ID to launch the instance in. - - `--amazonec2-zone`: The AWS zone launch the instance in (i.e. one of a,b,c,d,e). Default: `a` - -By default, the Amazon EC2 driver will use a daily image of Ubuntu 14.04 LTS. - - | Region | AMI ID | - |:--------------|:-----------| - |ap-northeast-1 |ami-44f1e245| - |ap-southeast-1 |ami-f95875ab| - |ap-southeast-2 |ami-890b62b3| - |cn-north-1 |ami-fe7ae8c7| - |eu-west-1 |ami-823686f5| - |eu-central-1 |ami-ac1524b1| - |sa-east-1 |ami-c770c1da| - |us-east-1 |ami-4ae27e22| - |us-west-1 |ami-d1180894| - |us-west-2 |ami-898dd9b9| - |us-gov-west-1 |ami-cf5630ec| - -#### Digital Ocean -Creates machines on [Digital Ocean](https://www.digitalocean.com/). You need to create a personal access token under "Apps & API" in the Digital Ocean Control Panel and pass that to `docker-machine create` with the `--digitalocean-access-token` option. - -Options: - - - `--digitalocean-access-token`: Your personal access token for the Digital Ocean API. - - `--digitalocean-image`: The name of the Digital Ocean image to use. Default: `docker` - - `--digitalocean-region`: The region to create the droplet in. Default: `nyc3` - - `--digitalocean-size`: The size of the Digital Ocean driver. Default: `512mb` - -The DigitalOcean driver will use `ubuntu-14-04-x64` as the default image. - -#### Google Compute Engine -Create machines on [Google Compute Engine](https://cloud.google.com/compute/). You will need a Google account and project name. See https://cloud.google.com/compute/docs/projects for details on projects. - -The Google driver uses oAuth. When creating the machine, you will have your browser opened to authorize. Once authorized, paste the code given in the prompt to launch the instance. - -Options: - - - `--google-zone`: The zone to launch the instance. Default: `us-central1-a` - - `--google-machine-type`: The type of instance. Default: `f1-micro` - - `--google-username`: The username to use for the instance. Default: `docker-user` - - `--google-instance-name`: The name of the instance. Default: `docker-machine` - - `--google-project`: The name of your project to use when launching the instance. - -The GCE driver will use the `ubuntu-1404-trusty-v20141212` instance type unless otherwise specified. - -#### IBM Softlayer - -Create machines on [Softlayer](http://softlayer.com). - -You need to generate an API key in the softlayer control panel. -[Retrieve your API key](http://knowledgelayer.softlayer.com/procedure/retrieve-your-api-key) - -Options: - - `--softlayer-api-endpoint=`: Change softlayer API endpoint - - `--softlayer-user`: **required** username for your softlayer account, api key needs to match this user. - - `--softlayer-api-key`: **required** API key for your user account - - `--softlayer-cpu`: Number of CPU's for the machine. - - `--softlayer-disk-size: Size of the disk in MB. `0` sets the softlayer default. - - `--softlayer-domain`: **required** domain name for the machine - - `--softlayer-hostname`: hostname for the machine - - `--softlayer-hourly-billing`: Sets the hourly billing flag (default), otherwise uses monthly billing - - `--softlayer-image`: OS Image to use - - `--softlayer-install-script`: custom install script to use for installing Docker, other setup actions - - `--softlayer-local-disk`: Use local machine disk instead of softlayer SAN. - - `--softlayer-memory`: Memory for host in MB - - `--softlayer-private-net-only`: Disable public networking - - `--softlayer-region`: softlayer region - -The SoftLayer driver will use `UBUNTU_LATEST` as the image type by default. - - -#### Microsoft Azure -Create machines on [Microsoft Azure](http://azure.microsoft.com/). - -You need to create a subscription with a cert. Run these commands: - - $ openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem - $ openssl pkcs12 -export -out mycert.pfx -in mycert.pem -name "My Certificate" - $ openssl x509 -inform pem -in mycert.pem -outform der -out mycert.cer - -Go to the Azure portal, go to the "Settings" page, then "Manage Certificates" and upload `mycert.cer`. - -Grab your subscription ID from the portal, then run `docker-machine create` with these details: - - $ docker-machine create -d azure --azure-subscription-id="SUB_ID" --azure-subscription-cert="mycert.pem" - -Options: - - - `--azure-subscription-id`: Your Azure subscription ID. - - `--azure-subscription-cert`: Your Azure subscription cert. - -The Azure driver uses the `b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB` image by default. Note, this image is not available in the Chinese regions. In China you should specify `b549f4301d0b4295b8e76ceb65df47d4__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB` - -#### Openstack -Create machines on [Openstack](http://www.openstack.org/software/) - -Mandatory: - - - `--openstack-flavor-id`: The flavor ID to use when creating the machine - - `--openstack-image-id`: The image ID to use when creating the machine. - -Options: - - - `--openstack-auth-url`: Keystone service base URL. - - `--openstack-username`: User identifer to authenticate with. - - `--openstack-password`: User password. It can be omitted if the standard environment variable `OS_PASSWORD` is set. - - `--openstack-tenant-name` or `--openstack-tenant-id`: Identify the tenant in which the machine will be created. - - `--openstack-region`: The region to work on. Can be omitted if there is ony one region on the OpenStack. - - `--openstack-endpoint-type`: Endpoint type can be `internalURL`, `adminURL` on `publicURL`. If is a helper for the driver - to choose the right URL in the OpenStack service catalog. If not provided the default id `publicURL` - - `--openstack-net-id`: The private network id the machine will be connected on. If your OpenStack project project - contains only one private network it will be use automatically. - - `--openstack-sec-groups`: If security groups are available on your OpenStack you can specify a comma separated list - to use for the machine (e.g. `secgrp001,secgrp002`). - - `--openstack-floatingip-pool`: The IP pool that will be used to get a public IP an assign it to the machine. If there is an - IP address already allocated but not assigned to any machine, this IP will be chosen and assigned to the machine. If - there is no IP address already allocated a new IP will be allocated and assigned to the machine. - - `--openstack-ssh-user`: The username to use for SSH into the machine. If not provided `root` will be used. - - `--openstack-ssh-port`: Customize the SSH port if the SSH server on the machine does not listen on the default port. - - `--openstack-docker-install`: Boolean flag to indicate if docker have to be installed on the machine. Useful when - docker is already installed and configured in the OpenStack image. Default set to `true` - -Environment variables: - -Here comes the list of the supported variables with the corresponding options. If both environment variable -and CLI option are provided the CLI option takes the precedence. - -| Environment variable | CLI option | -|----------------------|-----------------------------| -| `OS_AUTH_URL` | `--openstack-auth-url` | -| `OS_USERNAME` | `--openstack-username` | -| `OS_PASSWORD` | `--openstack-password` | -| `OS_TENANT_NAME` | `--openstack-tenant-name` | -| `OS_TENANT_ID` | `--openstack-tenant-id` | -| `OS_REGION_NAME` | `--openstack-region` | -| `OS_ENDPOINT_TYPE` | `--openstack-endpoint-type` | - -#### Rackspace -Create machines on [Rackspace cloud](http://www.rackspace.com/cloud) - -Options: - - - `--rackspace-username`: Rackspace account username - - `--rackspace-api-key`: Rackspace API key - - `--rackspace-region`: Rackspace region name - - `--rackspace-endpoint-type`: Rackspace endpoint type (adminURL, internalURL or the default publicURL) - - `--rackspace-image-id`: Rackspace image ID. Default: Ubuntu 14.10 (Utopic Unicorn) (PVHVM) - - `--rackspace-flavor-id`: Rackspace flavor ID. Default: General Purpose 1GB - - `--rackspace-ssh-user`: SSH user for the newly booted machine. Set to root by default - - `--rackspace-ssh-port`: SSH port for the newly booted machine. Set to 22 by default - -Environment variables: - -Here comes the list of the supported variables with the corresponding options. If both environment -variable and CLI option are provided the CLI option takes the precedence. - -| Environment variable | CLI option | -|----------------------|-----------------------------| -| `OS_USERNAME` | `--rackspace-username` | -| `OS_API_KEY` | `--rackspace-ap-key` | -| `OS_REGION_NAME` | `--rackspace-region` | -| `OS_ENDPOINT_TYPE` | `--rackspace-endpoint-type` | - -The Rackspace driver will use `598a4282-f14b-4e50-af4c-b3e52749d9f9` (Ubuntu 14.04 LTS) by default. - -#### VirtualBox -Creates machines locally on [VirtualBox](https://www.virtualbox.org/). Requires VirtualBox to be installed. - -Options: - - - `--virtualbox-boot2docker-url`: The URL of the boot2docker image. Defaults to the latest available version. - - `--virtualbox-disk-size`: Size of disk for the host in MB. Default: `20000` - - `--virtualbox-memory`: Size of memory for the host in MB. Default: `1024` - -The VirtualBox driver uses the latest boot2docker image. - -#### VMware Fusion -Creates machines locally on [VMware Fusion](http://www.vmware.com/products/fusion). Requires VMware Fusion to be installed. - -Options: - - - `--vmwarefusion-boot2docker-url`: URL for boot2docker image. - - `--vmwarefusion-disk-size`: Size of disk for host VM (in MB). Default: `20000` - - `--vmwarefusion-memory-size`: Size of memory for host VM (in MB). Default: `1024` - -The VMware Fusion driver uses the latest boot2docker image. - -#### VMware vCloud Air -Creates machines on [vCloud Air](http://vcloud.vmware.com) subscription service. You need an account within an existing subscription of vCloud Air VPC or Dedicated Cloud. - -Options: - - - `--vmwarevcloudair-username`: vCloud Air Username. - - `--vmwarevcloudair-password`: vCloud Air Password. - - `--vmwarevcloudair-catalog`: Catalog. Default: `Public Catalog` - - `--vmwarevcloudair-catalogitem`: Catalog Item. Default: `Ubuntu Server 12.04 LTS (amd64 20140927)` - - `--vmwarevcloudair-computeid`: Compute ID (if using Dedicated Cloud). - - `--vmwarevcloudair-cpu-count`: VM Cpu Count. Default: `1` - - `--vmwarevcloudair-docker-port`: Docker port. Default: `2376` - - `--vmwarevcloudair-edgegateway`: Organization Edge Gateway. Default: `` - - `--vmwarevcloudair-memory-size`: VM Memory Size in MB. Default: `2048` - - `--vmwarevcloudair-name`: vApp Name. Default: `` - - `--vmwarevcloudair-orgvdcnetwork`: Organization VDC Network to attach. Default: `-default-routed` - - `--vmwarevcloudair-provision`: Install Docker binaries. Default: `true` - - `--vmwarevcloudair-publicip`: Org Public IP to use. - - `--vmwarevcloudair-ssh-port`: SSH port. Default: `22` - - `--vmwarevcloudair-vdcid`: Virtual Data Center ID. - -The VMware vCloud Air driver will use the `Ubuntu Server 12.04 LTS (amd64 20140927)` image by default. - -#### VMware vSphere -Creates machines on a [VMware vSphere](http://www.vmware.com/products/vsphere) Virtual Infrastructure. Requires a working vSphere (ESXi and optionally vCenter) installation. The vSphere driver depends on [`govc`](https://github.com/vmware/govmomi/tree/master/govc) (must be in path) and has been tested with [vmware/govmomi@`c848630`](https://github.com/vmware/govmomi/commit/c8486300bfe19427e4f3226e3b3eac067717ef17). - -Options: - - - `--vmwarevsphere-username`: vSphere Username. - - `--vmwarevsphere-password`: vSphere Password. - - `--vmwarevsphere-boot2docker-url`: URL for boot2docker image. - - `--vmwarevsphere-compute-ip`: Compute host IP where the Docker VM will be instantiated. - - `--vmwarevsphere-cpu-count`: CPU number for Docker VM. Default: `2` - - `--vmwarevsphere-datacenter`: Datacenter for Docker VM (must be set to `ha-datacenter` when connecting to a single host). - - `--vmwarevsphere-datastore`: Datastore for Docker VM. - - `--vmwarevsphere-disk-size`: Size of disk for Docker VM (in MB). Default: `20000` - - `--vmwarevsphere-memory-size`: Size of memory for Docker VM (in MB). Default: `2048` - - `--vmwarevsphere-network`: Network where the Docker VM will be attached. - - `--vmwarevsphere-pool`: Resource pool for Docker VM. - - `--vmwarevsphere-vcenter`: IP/hostname for vCenter (or ESXi if connecting directly to a single host). - -The VMware vSphere driver uses the latest boot2docker image. diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index dc2b477ac7..b7704ad9d8 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -3,154 +3,346 @@ package amazonec2 import ( "crypto/md5" "crypto/rand" + "encoding/base64" + "errors" "fmt" "io" "io/ioutil" - "os/exec" - "path" + "net" + "net/url" + "strconv" + "strings" "time" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" - "github.com/docker/machine/drivers/amazonec2/amz" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/docker/machine/drivers/driverutil" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" ) const ( - driverName = "amazonec2" - defaultRegion = "us-east-1" - defaultInstanceType = "t2.micro" - defaultRootSize = 16 - ipRange = "0.0.0.0/0" - dockerConfigDir = "/etc/docker" - machineSecurityGroupName = "docker-machine" - dockerPort = 2376 + driverName = "amazonec2" + ipRange = "0.0.0.0/0" + machineSecurityGroupName = "docker-machine" + defaultAmiId = "ami-c60b90d1" + defaultRegion = "us-east-1" + defaultInstanceType = "t2.micro" + defaultDeviceName = "/dev/sda1" + defaultRootSize = 16 + defaultVolumeType = "gp2" + defaultZone = "a" + defaultSecurityGroup = machineSecurityGroupName + defaultSSHPort = 22 + defaultSSHUser = "ubuntu" + defaultSpotPrice = "0.50" + defaultBlockDurationMinutes = 0 +) + +const ( + keypairNotFoundCode = "InvalidKeyPair.NotFound" + spotInstanceRequestNotFoundCode = "InvalidSpotInstanceRequestID.NotFound" +) + +var ( + dockerPort = 2376 + swarmPort = 3376 + errorNoPrivateSSHKey = errors.New("using --amazonec2-keypair-name also requires --amazonec2-ssh-keypath") + errorMissingCredentials = errors.New("amazonec2 driver requires AWS credentials configured with the --amazonec2-access-key and --amazonec2-secret-key options, environment variables, ~/.aws/credentials, or an instance role") + errorNoVPCIdFound = errors.New("amazonec2 driver requires either the --amazonec2-subnet-id or --amazonec2-vpc-id option or an AWS Account with a default vpc-id") + errorNoSubnetsFound = errors.New("The desired subnet could not be located in this region. Is '--amazonec2-subnet-id' or AWS_SUBNET_ID configured correctly?") + errorDisableSSLWithoutCustomEndpoint = errors.New("using --amazonec2-insecure-transport also requires --amazonec2-endpoint") + errorReadingUserData = errors.New("unable to read --amazonec2-userdata file") ) type Driver struct { - Id string - AccessKey string - SecretKey string - SessionToken string - Region string - AMI string - SSHKeyID int - KeyName string - InstanceId string - InstanceType string - IPAddress string - MachineName string - SecurityGroupName string - SecurityGroupId string - ReservationId string - RootSize int64 - VpcId string - SubnetId string - Zone string - CaCertPath string - PrivateKeyPath string - storePath string - keyPath string -} - -type CreateFlags struct { - AccessKey *string - SecretKey *string - Region *string - AMI *string - InstanceType *string - SubnetId *string - RootSize *int64 -} - -func init() { - drivers.Register(driverName, &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) + *drivers.BaseDriver + clientFactory func() Ec2Client + awsCredentialsFactory func() awsCredentials + Id string + AccessKey string + SecretKey string + SessionToken string + Region string + AMI string + SSHKeyID int + // ExistingKey keeps track of whether the key was created by us or we used an existing one. If an existing one was used, we shouldn't delete it when the machine is deleted. + ExistingKey bool + KeyName string + InstanceId string + InstanceType string + PrivateIPAddress string + + // NB: SecurityGroupId expanded from single value to slice on 26 Feb 2016 - we maintain both for host storage backwards compatibility. + SecurityGroupId string + SecurityGroupIds []string + + // NB: SecurityGroupName expanded from single value to slice on 26 Feb 2016 - we maintain both for host storage backwards compatibility. + SecurityGroupName string + SecurityGroupNames []string + + SecurityGroupReadOnly bool + OpenPorts []string + Tags string + ReservationId string + DeviceName string + RootSize int64 + VolumeType string + IamInstanceProfile string + VpcId string + SubnetId string + Zone string + keyPath string + RequestSpotInstance bool + SpotPrice string + BlockDurationMinutes int64 + PrivateIPOnly bool + UsePrivateIP bool + UseEbsOptimizedInstance bool + Monitoring bool + SSHPrivateKeyPath string + RetryCount int + Endpoint string + DisableSSL bool + UserDataFile string + + spotInstanceRequestId string } -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ +type clientFactory interface { + build(d *Driver) Ec2Client +} + +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ Name: "amazonec2-access-key", Usage: "AWS Access Key", - Value: "", EnvVar: "AWS_ACCESS_KEY_ID", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-secret-key", Usage: "AWS Secret Key", - Value: "", EnvVar: "AWS_SECRET_ACCESS_KEY", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-session-token", Usage: "AWS Session Token", - Value: "", EnvVar: "AWS_SESSION_TOKEN", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-ami", Usage: "AWS machine image", EnvVar: "AWS_AMI", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-region", Usage: "AWS region", Value: defaultRegion, EnvVar: "AWS_DEFAULT_REGION", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-vpc-id", Usage: "AWS VPC id", - Value: "", EnvVar: "AWS_VPC_ID", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-zone", Usage: "AWS zone for instance (i.e. a,b,c,d,e)", - Value: "a", + Value: defaultZone, EnvVar: "AWS_ZONE", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "amazonec2-subnet-id", Usage: "AWS VPC subnet id", - Value: "", EnvVar: "AWS_SUBNET_ID", }, - cli.StringFlag{ + mcnflag.BoolFlag{ + Name: "amazonec2-security-group-readonly", + Usage: "Skip adding default rules to security groups", + EnvVar: "AWS_SECURITY_GROUP_READONLY", + }, + mcnflag.StringSliceFlag{ Name: "amazonec2-security-group", Usage: "AWS VPC security group", - Value: "docker-machine", + Value: []string{defaultSecurityGroup}, EnvVar: "AWS_SECURITY_GROUP", }, - cli.StringFlag{ + mcnflag.StringSliceFlag{ + Name: "amazonec2-open-port", + Usage: "Make the specified port number accessible from the Internet", + }, + mcnflag.StringFlag{ + Name: "amazonec2-tags", + Usage: "AWS Tags (e.g. key1,value1,key2,value2)", + EnvVar: "AWS_TAGS", + }, + mcnflag.StringFlag{ Name: "amazonec2-instance-type", Usage: "AWS instance type", Value: defaultInstanceType, EnvVar: "AWS_INSTANCE_TYPE", }, - cli.IntFlag{ + mcnflag.StringFlag{ + Name: "amazonec2-device-name", + Usage: "AWS root device name", + Value: defaultDeviceName, + EnvVar: "AWS_DEVICE_NAME", + }, + mcnflag.IntFlag{ Name: "amazonec2-root-size", Usage: "AWS root disk size (in GB)", Value: defaultRootSize, EnvVar: "AWS_ROOT_SIZE", }, + mcnflag.StringFlag{ + Name: "amazonec2-volume-type", + Usage: "Amazon EBS volume type", + Value: defaultVolumeType, + EnvVar: "AWS_VOLUME_TYPE", + }, + mcnflag.StringFlag{ + Name: "amazonec2-iam-instance-profile", + Usage: "AWS IAM Instance Profile", + EnvVar: "AWS_INSTANCE_PROFILE", + }, + mcnflag.IntFlag{ + Name: "amazonec2-ssh-port", + Usage: "SSH port", + Value: defaultSSHPort, + EnvVar: "AWS_SSH_PORT", + }, + mcnflag.StringFlag{ + Name: "amazonec2-ssh-user", + Usage: "SSH username", + Value: defaultSSHUser, + EnvVar: "AWS_SSH_USER", + }, + mcnflag.BoolFlag{ + Name: "amazonec2-request-spot-instance", + Usage: "Set this flag to request spot instance", + }, + mcnflag.StringFlag{ + Name: "amazonec2-spot-price", + Usage: "AWS spot instance bid price (in dollar)", + Value: defaultSpotPrice, + }, + mcnflag.IntFlag{ + Name: "amazonec2-block-duration-minutes", + Usage: "AWS spot instance duration in minutes (60, 120, 180, 240, 300, or 360)", + Value: defaultBlockDurationMinutes, + }, + mcnflag.BoolFlag{ + Name: "amazonec2-private-address-only", + Usage: "Only use a private IP address", + }, + mcnflag.BoolFlag{ + Name: "amazonec2-use-private-address", + Usage: "Force the usage of private IP address", + }, + mcnflag.BoolFlag{ + Name: "amazonec2-monitoring", + Usage: "Set this flag to enable CloudWatch monitoring", + }, + mcnflag.BoolFlag{ + Name: "amazonec2-use-ebs-optimized-instance", + Usage: "Create an EBS optimized instance", + }, + mcnflag.StringFlag{ + Name: "amazonec2-ssh-keypath", + Usage: "SSH Key for Instance", + EnvVar: "AWS_SSH_KEYPATH", + }, + mcnflag.StringFlag{ + Name: "amazonec2-keypair-name", + Usage: "AWS keypair to use; requires --amazonec2-ssh-keypath", + EnvVar: "AWS_KEYPAIR_NAME", + }, + mcnflag.IntFlag{ + Name: "amazonec2-retries", + Usage: "Set retry count for recoverable failures (use -1 to disable)", + Value: 5, + }, + mcnflag.StringFlag{ + Name: "amazonec2-endpoint", + Usage: "Optional endpoint URL (hostname only or fully qualified URI)", + Value: "", + EnvVar: "AWS_ENDPOINT", + }, + mcnflag.BoolFlag{ + Name: "amazonec2-insecure-transport", + Usage: "Disable SSL when sending requests", + EnvVar: "AWS_INSECURE_TRANSPORT", + }, + mcnflag.StringFlag{ + Name: "amazonec2-userdata", + Usage: "path to file with cloud-init user data", + EnvVar: "AWS_USERDATA", + }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { +func NewDriver(hostName, storePath string) *Driver { id := generateId() - return &Driver{Id: id, MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil + driver := &Driver{ + Id: id, + AMI: defaultAmiId, + Region: defaultRegion, + InstanceType: defaultInstanceType, + RootSize: defaultRootSize, + Zone: defaultZone, + SecurityGroupNames: []string{defaultSecurityGroup}, + SpotPrice: defaultSpotPrice, + BlockDurationMinutes: defaultBlockDurationMinutes, + BaseDriver: &drivers.BaseDriver{ + SSHPort: defaultSSHPort, + SSHUser: defaultSSHUser, + MachineName: hostName, + StorePath: storePath, + }, + } + + driver.clientFactory = driver.buildClient + driver.awsCredentialsFactory = driver.buildCredentials + + return driver +} + +func (d *Driver) buildClient() Ec2Client { + config := aws.NewConfig() + alogger := AwsLogger() + config = config.WithRegion(d.Region) + config = config.WithCredentials(d.awsCredentialsFactory().Credentials()) + config = config.WithLogger(alogger) + config = config.WithLogLevel(aws.LogDebugWithHTTPBody) + config = config.WithMaxRetries(d.RetryCount) + if d.Endpoint != "" { + config = config.WithEndpoint(d.Endpoint) + config = config.WithDisableSSL(d.DisableSSL) + } + return ec2.New(session.New(config)) +} + +func (d *Driver) buildCredentials() awsCredentials { + return NewAWSCredentials(d.AccessKey, d.SecretKey, d.SessionToken) +} + +func (d *Driver) getClient() Ec2Client { + return d.clientFactory() } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.Endpoint = flags.String("amazonec2-endpoint") + region, err := validateAwsRegion(flags.String("amazonec2-region")) - if err != nil { - return nil + if err != nil && d.Endpoint == "" { + return err } image := flags.String("amazonec2-ami") @@ -163,43 +355,178 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SessionToken = flags.String("amazonec2-session-token") d.Region = region d.AMI = image + d.RequestSpotInstance = flags.Bool("amazonec2-request-spot-instance") + d.SpotPrice = flags.String("amazonec2-spot-price") + d.BlockDurationMinutes = int64(flags.Int("amazonec2-block-duration-minutes")) d.InstanceType = flags.String("amazonec2-instance-type") d.VpcId = flags.String("amazonec2-vpc-id") d.SubnetId = flags.String("amazonec2-subnet-id") - d.SecurityGroupName = flags.String("amazonec2-security-group") + d.SecurityGroupNames = flags.StringSlice("amazonec2-security-group") + d.SecurityGroupReadOnly = flags.Bool("amazonec2-security-group-readonly") + d.Tags = flags.String("amazonec2-tags") zone := flags.String("amazonec2-zone") d.Zone = zone[:] + d.DeviceName = flags.String("amazonec2-device-name") d.RootSize = int64(flags.Int("amazonec2-root-size")) + d.VolumeType = flags.String("amazonec2-volume-type") + d.IamInstanceProfile = flags.String("amazonec2-iam-instance-profile") + d.SSHUser = flags.String("amazonec2-ssh-user") + d.SSHPort = flags.Int("amazonec2-ssh-port") + d.PrivateIPOnly = flags.Bool("amazonec2-private-address-only") + d.UsePrivateIP = flags.Bool("amazonec2-use-private-address") + d.Monitoring = flags.Bool("amazonec2-monitoring") + d.UseEbsOptimizedInstance = flags.Bool("amazonec2-use-ebs-optimized-instance") + d.SSHPrivateKeyPath = flags.String("amazonec2-ssh-keypath") + d.KeyName = flags.String("amazonec2-keypair-name") + d.ExistingKey = flags.String("amazonec2-keypair-name") != "" + d.SetSwarmConfigFromFlags(flags) + d.RetryCount = flags.Int("amazonec2-retries") + d.OpenPorts = flags.StringSlice("amazonec2-open-port") + d.UserDataFile = flags.String("amazonec2-userdata") + + d.DisableSSL = flags.Bool("amazonec2-insecure-transport") + + if d.DisableSSL && d.Endpoint == "" { + return errorDisableSSLWithoutCustomEndpoint + } - if d.AccessKey == "" { - return fmt.Errorf("amazonec2 driver requires the --amazonec2-access-key option") + if d.KeyName != "" && d.SSHPrivateKeyPath == "" { + return errorNoPrivateSSHKey } - if d.SecretKey == "" { - return fmt.Errorf("amazonec2 driver requires the --amazonec2-secret-key option") + _, err = d.awsCredentialsFactory().Credentials().Get() + if err != nil { + return errorMissingCredentials + } + + if d.VpcId == "" { + d.VpcId, err = d.getDefaultVPCId() + if err != nil { + log.Warnf("Couldn't determine your account Default VPC ID : %q", err) + } } if d.SubnetId == "" && d.VpcId == "" { - return fmt.Errorf("amazonec2 driver requires either the --amazonec2-subnet-id or --amazonec2-vpc-id option") + return errorNoVPCIdFound + } + + if d.SubnetId != "" && d.VpcId != "" { + subnetFilter := []*ec2.Filter{ + { + Name: aws.String("subnet-id"), + Values: []*string{&d.SubnetId}, + }, + } + + subnets, err := d.getClient().DescribeSubnets(&ec2.DescribeSubnetsInput{ + Filters: subnetFilter, + }) + if err != nil { + return err + } + + if subnets == nil || len(subnets.Subnets) == 0 { + return errorNoSubnetsFound + } + + if *subnets.Subnets[0].VpcId != d.VpcId { + return fmt.Errorf("SubnetId: %s does not belong to VpcId: %s", d.SubnetId, d.VpcId) + } + } + + if d.isSwarmMaster() { + u, err := url.Parse(d.SwarmHost) + if err != nil { + return fmt.Errorf("error parsing swarm host: %s", err) + } + + parts := strings.Split(u.Host, ":") + port, err := strconv.Atoi(parts[1]) + if err != nil { + return err + } + + swarmPort = port } return nil } +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return driverName } func (d *Driver) checkPrereqs() error { // check for existing keypair - key, err := d.getClient().GetKeyPair(d.MachineName) + keyName := d.KeyName + keyShouldExist := true + if keyName == "" { + keyName = d.MachineName + keyShouldExist = false + } + + key, err := d.getClient().DescribeKeyPairs(&ec2.DescribeKeyPairsInput{ + KeyNames: []*string{&keyName}, + }) if err != nil { - return err + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == keypairNotFoundCode && keyShouldExist { + return fmt.Errorf("There is no keypair with the name %s. Please verify the key name provided.", keyName) + } + if awsErr.Code() == keypairNotFoundCode && !keyShouldExist { + // Not a real error for 'NotFound' since we're checking existence + } + } else { + return err + } } - if key != nil { - return fmt.Errorf("There is already a keypair with the name %s. Please either remove that keypair or use a different machine name.", d.MachineName) + // In case we got a result with an empty set of keys + if err == nil && len(key.KeyPairs) != 0 { + if !keyShouldExist { + return fmt.Errorf("There is already a keypair with the name %s. Please either remove that keypair or use a different machine name.", d.MachineName) + } + // otherwise we found the key: success } + + regionZone := d.getRegionZone() + if d.SubnetId == "" { + filters := []*ec2.Filter{ + { + Name: aws.String("availability-zone"), + Values: []*string{®ionZone}, + }, + { + Name: aws.String("vpc-id"), + Values: []*string{&d.VpcId}, + }, + } + + subnets, err := d.getClient().DescribeSubnets(&ec2.DescribeSubnetsInput{ + Filters: filters, + }) + if err != nil { + return err + } + + if len(subnets.Subnets) == 0 { + return fmt.Errorf("unable to find a subnet that is both in the zone %s and belonging to VPC ID %s", regionZone, d.VpcId) + } + + d.SubnetId = *subnets.Subnets[0].SubnetId + + // try to find default + if len(subnets.Subnets) > 1 { + for _, subnet := range subnets.Subnets { + if subnet.DefaultForAz != nil && *subnet.DefaultForAz { + d.SubnetId = *subnet.SubnetId + break + } + } + } + } + return nil } @@ -207,112 +534,251 @@ func (d *Driver) PreCreateCheck() error { return d.checkPrereqs() } +func (d *Driver) instanceIpAvailable() bool { + ip, err := d.GetIP() + if err != nil { + log.Debug(err) + } + if ip != "" { + d.IPAddress = ip + log.Debugf("Got the IP Address, it's %q", d.IPAddress) + return true + } + return false +} + +func makePointerSlice(stackSlice []string) []*string { + pointerSlice := []*string{} + for i := range stackSlice { + pointerSlice = append(pointerSlice, &stackSlice[i]) + } + return pointerSlice +} + +// Support migrating single string Driver fields to slices. +func migrateStringToSlice(value string, values []string) (result []string) { + if value != "" { + result = append(result, value) + } + result = append(result, values...) + return +} + +func (d *Driver) securityGroupNames() (ids []string) { + return migrateStringToSlice(d.SecurityGroupName, d.SecurityGroupNames) +} + +func (d *Driver) securityGroupIds() (ids []string) { + return migrateStringToSlice(d.SecurityGroupId, d.SecurityGroupIds) +} + +func (d *Driver) Base64UserData() (userdata string, err error) { + if d.UserDataFile != "" { + buf, ioerr := ioutil.ReadFile(d.UserDataFile) + if ioerr != nil { + log.Warnf("failed to read user data file %q: %s", d.UserDataFile, ioerr) + err = errorReadingUserData + return + } + userdata = base64.StdEncoding.EncodeToString(buf) + } + return +} + func (d *Driver) Create() error { if err := d.checkPrereqs(); err != nil { return err } + if err := d.innerCreate(); err != nil { + // cleanup partially created resources + d.Remove() + return err + } + + return nil +} + +func (d *Driver) innerCreate() error { log.Infof("Launching instance...") if err := d.createKeyPair(); err != nil { return fmt.Errorf("unable to create key pair: %s", err) } - if err := d.configureSecurityGroup(d.SecurityGroupName); err != nil { + if err := d.configureSecurityGroups(d.securityGroupNames()); err != nil { return err } - bdm := &amz.BlockDeviceMapping{ - DeviceName: "/dev/sda1", - VolumeSize: d.RootSize, - DeleteOnTermination: true, - VolumeType: "gp2", + var userdata string + if b64, err := d.Base64UserData(); err != nil { + return err + } else { + userdata = b64 } - // get the subnet id - regionZone := d.Region + d.Zone - subnetId := d.SubnetId + bdm := &ec2.BlockDeviceMapping{ + DeviceName: aws.String(d.DeviceName), + Ebs: &ec2.EbsBlockDevice{ + VolumeSize: aws.Int64(d.RootSize), + VolumeType: aws.String(d.VolumeType), + DeleteOnTermination: aws.Bool(true), + }, + } + netSpecs := []*ec2.InstanceNetworkInterfaceSpecification{{ + DeviceIndex: aws.Int64(0), // eth0 + Groups: makePointerSlice(d.securityGroupIds()), + SubnetId: &d.SubnetId, + AssociatePublicIpAddress: aws.Bool(!d.PrivateIPOnly), + }} + + regionZone := d.getRegionZone() + log.Debugf("launching instance in subnet %s", d.SubnetId) + + var instance *ec2.Instance + + if d.RequestSpotInstance { + req := ec2.RequestSpotInstancesInput{ + LaunchSpecification: &ec2.RequestSpotLaunchSpecification{ + ImageId: &d.AMI, + Placement: &ec2.SpotPlacement{ + AvailabilityZone: ®ionZone, + }, + KeyName: &d.KeyName, + InstanceType: &d.InstanceType, + NetworkInterfaces: netSpecs, + Monitoring: &ec2.RunInstancesMonitoringEnabled{Enabled: aws.Bool(d.Monitoring)}, + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Name: &d.IamInstanceProfile, + }, + EbsOptimized: &d.UseEbsOptimizedInstance, + BlockDeviceMappings: []*ec2.BlockDeviceMapping{bdm}, + UserData: &userdata, + }, + InstanceCount: aws.Int64(1), + SpotPrice: &d.SpotPrice, + } + if d.BlockDurationMinutes != 0 { + req.BlockDurationMinutes = &d.BlockDurationMinutes + } - if d.SubnetId == "" { - subnets, err := d.getClient().GetSubnets() + spotInstanceRequest, err := d.getClient().RequestSpotInstances(&req) if err != nil { - return err + return fmt.Errorf("Error request spot instance: %s", err) } - - for _, s := range subnets { - if s.AvailabilityZone == regionZone { - subnetId = s.SubnetId + d.spotInstanceRequestId = *spotInstanceRequest.SpotInstanceRequests[0].SpotInstanceRequestId + + log.Info("Waiting for spot instance...") + for i := 0; i < 3; i++ { + // AWS eventual consistency means we could not have SpotInstanceRequest ready yet + err = d.getClient().WaitUntilSpotInstanceRequestFulfilled(&ec2.DescribeSpotInstanceRequestsInput{ + SpotInstanceRequestIds: []*string{&d.spotInstanceRequestId}, + }) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == spotInstanceRequestNotFoundCode { + time.Sleep(5 * time.Second) + continue + } + } + return fmt.Errorf("Error fulfilling spot request: %v", err) + } + break + } + log.Infof("Created spot instance request %v", d.spotInstanceRequestId) + // resolve instance id + for i := 0; i < 3; i++ { + // Even though the waiter succeeded, eventual consistency means we could + // get a describe output that does not include this information. Try a + // few times just in case + var resolvedSpotInstance *ec2.DescribeSpotInstanceRequestsOutput + resolvedSpotInstance, err = d.getClient().DescribeSpotInstanceRequests(&ec2.DescribeSpotInstanceRequestsInput{ + SpotInstanceRequestIds: []*string{&d.spotInstanceRequestId}, + }) + if err != nil { + // Unexpected; no need to retry + return fmt.Errorf("Error describing previously made spot instance request: %v", err) + } + maybeInstanceId := resolvedSpotInstance.SpotInstanceRequests[0].InstanceId + if maybeInstanceId != nil { + var instances *ec2.DescribeInstancesOutput + instances, err = d.getClient().DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIds: []*string{maybeInstanceId}, + }) + if err != nil { + // Retry if we get an id from spot instance but EC2 doesn't recognize it yet; see above, eventual consistency possible + continue + } + instance = instances.Reservations[0].Instances[0] + err = nil break } + time.Sleep(5 * time.Second) } - } + if err != nil { + return fmt.Errorf("Error resolving spot instance to real instance: %v", err) + } + } else { + inst, err := d.getClient().RunInstances(&ec2.RunInstancesInput{ + ImageId: &d.AMI, + MinCount: aws.Int64(1), + MaxCount: aws.Int64(1), + Placement: &ec2.Placement{ + AvailabilityZone: ®ionZone, + }, + KeyName: &d.KeyName, + InstanceType: &d.InstanceType, + NetworkInterfaces: netSpecs, + Monitoring: &ec2.RunInstancesMonitoringEnabled{Enabled: aws.Bool(d.Monitoring)}, + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Name: &d.IamInstanceProfile, + }, + EbsOptimized: &d.UseEbsOptimizedInstance, + BlockDeviceMappings: []*ec2.BlockDeviceMapping{bdm}, + UserData: &userdata, + }) - if subnetId == "" { - return fmt.Errorf("unable to find a subnet in the zone: %s", regionZone) + if err != nil { + return fmt.Errorf("Error launching instance: %s", err) + } + instance = inst.Instances[0] } - log.Debugf("launching instance in subnet %s", subnetId) - instance, err := d.getClient().RunInstance(d.AMI, d.InstanceType, d.Zone, 1, 1, d.SecurityGroupId, d.KeyName, subnetId, bdm) + d.InstanceId = *instance.InstanceId - if err != nil { - return fmt.Errorf("Error launching instance: %s", err) + log.Debug("waiting for ip address to become available") + if err := mcnutils.WaitFor(d.instanceIpAvailable); err != nil { + return err } - d.InstanceId = instance.InstanceId + if instance.PrivateIpAddress != nil { + d.PrivateIPAddress = *instance.PrivateIpAddress + } d.waitForInstance() - log.Debugf("created instance ID %s, IP address %s", + log.Debugf("created instance ID %s, IP address %s, Private IP address %s", d.InstanceId, - d.IPAddress) - - log.Infof("Waiting for SSH on %s:%d", d.IPAddress, 22) - - if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.IPAddress, 22)); err != nil { - return err - } + d.IPAddress, + d.PrivateIPAddress, + ) log.Debug("Settings tags for instance") - tags := map[string]string{ - "Name": d.MachineName, - } - - if err = d.getClient().CreateTags(d.InstanceId, tags); err != nil { - return err - } - - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - log.Debugf("Installing Docker") + err := d.configureTags(d.Tags) - cmd, err = d.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl -sL https://get.docker.com | sh -; fi") if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - + return fmt.Errorf("Unable to tag instance %s: %s", d.InstanceId, err) } return nil } func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } + ip, err := d.GetIP() if err != nil { return "", err @@ -320,7 +786,8 @@ func (d *Driver) GetURL() (string, error) { if ip == "" { return "", nil } - return fmt.Sprintf("tcp://%s:%d", ip, dockerPort), nil + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, strconv.Itoa(dockerPort))), nil } func (d *Driver) GetIP() (string, error) { @@ -328,8 +795,25 @@ func (d *Driver) GetIP() (string, error) { if err != nil { return "", err } - d.IPAddress = inst.IpAddress - return d.IPAddress, nil + + if d.PrivateIPOnly { + if inst.PrivateIpAddress == nil { + return "", fmt.Errorf("No private IP for instance %v", *inst.InstanceId) + } + return *inst.PrivateIpAddress, nil + } + + if d.UsePrivateIP { + if inst.PrivateIpAddress == nil { + return "", fmt.Errorf("No private IP for instance %v", *inst.InstanceId) + } + return *inst.PrivateIpAddress, nil + } + + if inst.PublicIpAddress == nil { + return "", fmt.Errorf("No IP for instance %v", *inst.InstanceId) + } + return *inst.PublicIpAddress, nil } func (d *Driver) GetState() (state.State, error) { @@ -337,181 +821,142 @@ func (d *Driver) GetState() (state.State, error) { if err != nil { return state.Error, err } - switch inst.InstanceState.Name { - case "pending": + switch *inst.State.Name { + case ec2.InstanceStateNamePending: return state.Starting, nil - case "running": + case ec2.InstanceStateNameRunning: return state.Running, nil - case "stopping": + case ec2.InstanceStateNameStopping: return state.Stopping, nil - case "shutting-down": + case ec2.InstanceStateNameShuttingDown: return state.Stopping, nil - case "stopped": + case ec2.InstanceStateNameStopped: return state.Stopped, nil + case ec2.InstanceStateNameTerminated: + return state.Error, nil + default: + log.Warnf("unrecognized instance state: %v", *inst.State.Name) + return state.Error, nil } - return state.None, nil } -func (d *Driver) Start() error { - if err := d.getClient().StartInstance(d.InstanceId); err != nil { - return err - } - - if err := d.waitForInstance(); err != nil { - return err - } - - if err := d.updateDriver(); err != nil { - return err - } - return nil +func (d *Driver) GetSSHHostname() (string, error) { + // TODO: use @nathanleclaire retry func here (ehazlett) + return d.GetIP() } -func (d *Driver) Stop() error { - if err := d.getClient().StopInstance(d.InstanceId, false); err != nil { - return err +func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = defaultSSHPort } - return nil -} - -func (d *Driver) Remove() error { - if err := d.terminate(); err != nil { - return fmt.Errorf("unable to terminate instance: %s", err) - } - - // remove keypair - if err := d.deleteKeyPair(); err != nil { - return fmt.Errorf("unable to remove key pair: %s", err) - } - - return nil + return d.SSHPort, nil } -func (d *Driver) Restart() error { - if err := d.getClient().RestartInstance(d.InstanceId); err != nil { - return fmt.Errorf("unable to restart instance: %s", err) +func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = defaultSSHUser } - return nil -} -func (d *Driver) Kill() error { - if err := d.getClient().StopInstance(d.InstanceId, true); err != nil { - return err - } - return nil + return d.SSHUser } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") +func (d *Driver) Start() error { + _, err := d.getClient().StartInstances(&ec2.StartInstancesInput{ + InstanceIds: []*string{&d.InstanceId}, + }) if err != nil { return err } - if err := cmd.Run(); err != nil { - return err - } - return nil + return d.waitForInstance() } -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } +func (d *Driver) Stop() error { + _, err := d.getClient().StopInstances(&ec2.StopInstancesInput{ + InstanceIds: []*string{&d.InstanceId}, + Force: aws.Bool(false), + }) + return err +} - return nil +func (d *Driver) Restart() error { + _, err := d.getClient().RebootInstances(&ec2.RebootInstancesInput{ + InstanceIds: []*string{&d.InstanceId}, + }) + return err } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir +func (d *Driver) Kill() error { + _, err := d.getClient().StopInstances(&ec2.StopInstancesInput{ + InstanceIds: []*string{&d.InstanceId}, + Force: aws.Bool(true), + }) + return err } -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") +func (d *Driver) Remove() error { + multierr := mcnutils.MultiError{ + Errs: []error{}, + } - cmd, err := d.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") - if err != nil { - return err + if err := d.terminate(); err != nil { + multierr.Errs = append(multierr.Errs, err) + } + // In case of failure waiting for a SpotInstance, we must cancel the unfulfilled request, otherwise an instance may be created later. + // If the instance was created, terminating it will be enough for canceling the SpotInstanceRequest + if d.RequestSpotInstance && d.spotInstanceRequestId != "" { + if err := d.cancelSpotInstanceRequest(); err != nil { + multierr.Errs = append(multierr.Errs, err) + } } - if err := cmd.Run(); err != nil { - return err + if !d.ExistingKey { + if err := d.deleteKeyPair(); err != nil { + multierr.Errs = append(multierr.Errs, err) + } } - return cmd.Run() -} + if len(multierr.Errs) == 0 { + return nil + } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.IPAddress, 22, "ubuntu", d.sshKeyPath(), args...), nil + return multierr } -func (d *Driver) getClient() *amz.EC2 { - auth := amz.GetAuth(d.AccessKey, d.SecretKey, d.SessionToken) - return amz.NewEC2(auth, d.Region) -} +func (d *Driver) cancelSpotInstanceRequest() error { + // NB: Canceling a Spot instance request does not terminate running Spot instances associated with the request + _, err := d.getClient().CancelSpotInstanceRequests(&ec2.CancelSpotInstanceRequestsInput{ + SpotInstanceRequestIds: []*string{&d.spotInstanceRequestId}, + }) -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") + return err } -func (d *Driver) updateDriver() error { - inst, err := d.getInstance() +func (d *Driver) getInstance() (*ec2.Instance, error) { + instances, err := d.getClient().DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIds: []*string{&d.InstanceId}, + }) if err != nil { - return err - } - // wait for ipaddress - for { - i, err := d.getInstance() - if err != nil { - return err - } - if i.IpAddress == "" { - time.Sleep(1 * time.Second) - continue - } - - d.InstanceId = inst.InstanceId - d.IPAddress = inst.IpAddress - break + return nil, err } - return nil -} - -func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return instances.Reservations[0].Instances[0], nil } -func (d *Driver) getInstance() (*amz.EC2Instance, error) { - instance, err := d.getClient().GetInstance(d.InstanceId) +func (d *Driver) instanceIsRunning() bool { + st, err := d.GetState() if err != nil { - return nil, err + log.Debug(err) } - - return &instance, nil + if st == state.Running { + return true + } + return false } func (d *Driver) waitForInstance() error { - for { - st, err := d.GetState() - if err != nil { - return err - } - if st == state.Running { - break - } - time.Sleep(1 * time.Second) - } - - if err := d.updateDriver(); err != nil { + if err := mcnutils.WaitFor(d.instanceIsRunning); err != nil { return err } @@ -519,12 +964,30 @@ func (d *Driver) waitForInstance() error { } func (d *Driver) createKeyPair() error { + keyPath := "" - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { - return err + if d.SSHPrivateKeyPath == "" { + log.Debugf("Creating New SSH Key") + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { + return err + } + keyPath = d.GetSSHKeyPath() + } else { + log.Debugf("Using SSHPrivateKeyPath: %s", d.SSHPrivateKeyPath) + if err := mcnutils.CopyFile(d.SSHPrivateKeyPath, d.GetSSHKeyPath()); err != nil { + return err + } + if err := mcnutils.CopyFile(d.SSHPrivateKeyPath+".pub", d.GetSSHKeyPath()+".pub"); err != nil { + return err + } + if d.KeyName != "" { + log.Debugf("Using existing EC2 key pair: %s", d.KeyName) + return nil + } + keyPath = d.SSHPrivateKeyPath } - publicKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) + publicKey, err := ioutil.ReadFile(keyPath + ".pub") if err != nil { return err } @@ -532,147 +995,285 @@ func (d *Driver) createKeyPair() error { keyName := d.MachineName log.Debugf("creating key pair: %s", keyName) - - if err := d.getClient().ImportKeyPair(keyName, string(publicKey)); err != nil { + _, err = d.getClient().ImportKeyPair(&ec2.ImportKeyPairInput{ + KeyName: &keyName, + PublicKeyMaterial: publicKey, + }) + if err != nil { return err } - d.KeyName = keyName return nil } func (d *Driver) terminate() error { if d.InstanceId == "" { - return fmt.Errorf("unknown instance") + log.Warn("Missing instance ID, this is likely due to a failure during machine creation") + return nil } log.Debugf("terminating instance: %s", d.InstanceId) - if err := d.getClient().TerminateInstance(d.InstanceId); err != nil { + _, err := d.getClient().TerminateInstances(&ec2.TerminateInstancesInput{ + InstanceIds: []*string{&d.InstanceId}, + }) + + if err != nil { + if strings.HasPrefix(err.Error(), "unknown instance") || + strings.HasPrefix(err.Error(), "InvalidInstanceID.NotFound") { + log.Warn("Remote instance does not exist, proceeding with removing local reference") + return nil + } + return fmt.Errorf("unable to terminate instance: %s", err) } - return nil } -func (d *Driver) configureSecurityGroup(groupName string) error { - log.Debugf("configuring security group in %s", d.VpcId) +func (d *Driver) isSwarmMaster() bool { + return d.SwarmMaster +} - var securityGroup *amz.SecurityGroup +func (d *Driver) securityGroupAvailableFunc(id string) func() bool { + return func() bool { + + securityGroup, err := d.getClient().DescribeSecurityGroups(&ec2.DescribeSecurityGroupsInput{ + GroupIds: []*string{&id}, + }) + if err == nil && len(securityGroup.SecurityGroups) > 0 { + return true + } else if err == nil { + log.Debugf("No security group with id %v found", id) + return false + } + log.Debug(err) + return false + } +} + +func (d *Driver) configureTags(tagGroups string) error { + + tags := []*ec2.Tag{} + tags = append(tags, &ec2.Tag{ + Key: aws.String("Name"), + Value: &d.MachineName, + }) + + if tagGroups != "" { + t := strings.Split(tagGroups, ",") + if len(t) > 0 && len(t)%2 != 0 { + log.Warnf("Tags are not key value in pairs. %d elements found", len(t)) + } + for i := 0; i < len(t)-1; i += 2 { + tags = append(tags, &ec2.Tag{ + Key: &t[i], + Value: &t[i+1], + }) + } + } + + _, err := d.getClient().CreateTags(&ec2.CreateTagsInput{ + Resources: []*string{&d.InstanceId}, + Tags: tags, + }) - groups, err := d.getClient().GetSecurityGroups() if err != nil { return err } - for _, grp := range groups { - if grp.GroupName == groupName { - log.Debugf("found existing security group (%s) in %s", groupName, d.VpcId) - securityGroup = &grp - break - } - } + return nil +} - // if not found, create - if securityGroup == nil { - log.Debugf("creating security group (%s) in %s", groupName, d.VpcId) - group, err := d.getClient().CreateSecurityGroup(groupName, "Docker Machine", d.VpcId) - if err != nil { - return err - } - securityGroup = group - // wait until created (dat eventual consistency) - log.Debugf("waiting for group (%s) to become available", group.GroupId) - for { - _, err := d.getClient().GetSecurityGroupById(group.GroupId) - if err == nil { - break - } - log.Debug(err) - time.Sleep(1 * time.Second) - } +func (d *Driver) configureSecurityGroups(groupNames []string) error { + if len(groupNames) == 0 { + log.Debugf("no security groups to configure in %s", d.VpcId) + return nil } - d.SecurityGroupId = securityGroup.GroupId + log.Debugf("configuring security groups in %s", d.VpcId) - log.Debugf("configuring security group authorization for %s", ipRange) + filters := []*ec2.Filter{ + { + Name: aws.String("group-name"), + Values: makePointerSlice(groupNames), + }, + { + Name: aws.String("vpc-id"), + Values: []*string{&d.VpcId}, + }, + } + groups, err := d.getClient().DescribeSecurityGroups(&ec2.DescribeSecurityGroupsInput{ + Filters: filters, + }) + if err != nil { + return err + } - perms := configureSecurityGroupPermissions(securityGroup) + var groupsByName = make(map[string]*ec2.SecurityGroup) + for _, securityGroup := range groups.SecurityGroups { + groupsByName[*securityGroup.GroupName] = securityGroup + } + + for _, groupName := range groupNames { + var group *ec2.SecurityGroup + securityGroup, ok := groupsByName[groupName] + if ok { + log.Debugf("found existing security group (%s) in %s", groupName, d.VpcId) + group = securityGroup + } else { + log.Debugf("creating security group (%s) in %s", groupName, d.VpcId) + groupResp, err := d.getClient().CreateSecurityGroup(&ec2.CreateSecurityGroupInput{ + GroupName: aws.String(groupName), + Description: aws.String("Docker Machine"), + VpcId: aws.String(d.VpcId), + }) + if err != nil { + return err + } + // Manually translate into the security group construct + group = &ec2.SecurityGroup{ + GroupId: groupResp.GroupId, + VpcId: aws.String(d.VpcId), + GroupName: aws.String(groupName), + } + // wait until created (dat eventual consistency) + log.Debugf("waiting for group (%s) to become available", *group.GroupId) + if err := mcnutils.WaitFor(d.securityGroupAvailableFunc(*group.GroupId)); err != nil { + return err + } + } + d.SecurityGroupIds = append(d.SecurityGroupIds, *group.GroupId) - if len(perms) != 0 { - log.Debugf("authorizing group %s with permissions: %v", securityGroup.GroupName, perms) - if err := d.getClient().AuthorizeSecurityGroup(d.SecurityGroupId, perms); err != nil { + perms, err := d.configureSecurityGroupPermissions(group) + if err != nil { return err } + if len(perms) != 0 { + log.Debugf("authorizing group %s with permissions: %v", groupNames, perms) + _, err := d.getClient().AuthorizeSecurityGroupIngress(&ec2.AuthorizeSecurityGroupIngressInput{ + GroupId: group.GroupId, + IpPermissions: perms, + }) + if err != nil { + return err + } + } } return nil } -func configureSecurityGroupPermissions(group *amz.SecurityGroup) []amz.IpPermission { - hasSshPort := false - hasDockerPort := false +func (d *Driver) configureSecurityGroupPermissions(group *ec2.SecurityGroup) ([]*ec2.IpPermission, error) { + if d.SecurityGroupReadOnly { + log.Debug("Skipping permission configuration on security groups") + return nil, nil + } + hasPorts := make(map[string]bool) for _, p := range group.IpPermissions { - switch p.FromPort { - case 22: - hasSshPort = true - case dockerPort: - hasDockerPort = true + if p.FromPort != nil { + hasPorts[fmt.Sprintf("%d/%s", *p.FromPort, *p.IpProtocol)] = true } } - perms := []amz.IpPermission{} + perms := []*ec2.IpPermission{} - if !hasSshPort { - perm := amz.IpPermission{ - IpProtocol: "tcp", - FromPort: 22, - ToPort: 22, - IpRange: ipRange, - } + if !hasPorts[fmt.Sprintf("%d/tcp", d.BaseDriver.SSHPort)] { + perms = append(perms, &ec2.IpPermission{ + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(int64(d.BaseDriver.SSHPort)), + ToPort: aws.Int64(int64(d.BaseDriver.SSHPort)), + IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}}, + }) + } - perms = append(perms, perm) + if !hasPorts[fmt.Sprintf("%d/tcp", dockerPort)] { + perms = append(perms, &ec2.IpPermission{ + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(int64(dockerPort)), + ToPort: aws.Int64(int64(dockerPort)), + IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}}, + }) } - if !hasDockerPort { - perm := amz.IpPermission{ - IpProtocol: "tcp", - FromPort: dockerPort, - ToPort: dockerPort, - IpRange: ipRange, - } + if !hasPorts[fmt.Sprintf("%d/tcp", swarmPort)] && d.SwarmMaster { + perms = append(perms, &ec2.IpPermission{ + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(int64(swarmPort)), + ToPort: aws.Int64(int64(swarmPort)), + IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}}, + }) + } - perms = append(perms, perm) + for _, p := range d.OpenPorts { + port, protocol := driverutil.SplitPortProto(p) + portNum, err := strconv.ParseInt(port, 10, 0) + if err != nil { + return nil, fmt.Errorf("invalid port number %s: %s", port, err) + } + if !hasPorts[fmt.Sprintf("%s/%s", port, protocol)] { + perms = append(perms, &ec2.IpPermission{ + IpProtocol: aws.String(protocol), + FromPort: aws.Int64(portNum), + ToPort: aws.Int64(portNum), + IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}}, + }) + } } - return perms + log.Debugf("configuring security group authorization for %s", ipRange) + + return perms, nil } -func (d *Driver) deleteSecurityGroup() error { - log.Debugf("deleting security group %s", d.SecurityGroupId) +func (d *Driver) deleteKeyPair() error { + if d.KeyName == "" { + log.Warn("Missing key pair name, this is likely due to a failure during machine creation") + return nil + } - if err := d.getClient().DeleteSecurityGroup(d.SecurityGroupId); err != nil { + log.Debugf("deleting key pair: %s", d.KeyName) + + _, err := d.getClient().DeleteKeyPair(&ec2.DeleteKeyPairInput{ + KeyName: &d.KeyName, + }) + if err != nil { return err } return nil } -func (d *Driver) deleteKeyPair() error { - log.Debugf("deleting key pair: %s", d.KeyName) +func (d *Driver) getDefaultVPCId() (string, error) { + output, err := d.getClient().DescribeAccountAttributes(&ec2.DescribeAccountAttributesInput{}) + if err != nil { + return "", err + } - if err := d.getClient().DeleteKeyPair(d.KeyName); err != nil { - return err + for _, attribute := range output.AccountAttributes { + if *attribute.AttributeName == "default-vpc" { + value := *attribute.AttributeValues[0].AttributeValue + if value == "none" { + return "", errors.New("default-vpc is 'none'") + } + return value, nil + } } - return nil + return "", errors.New("No default-vpc attribute") +} + +func (d *Driver) getRegionZone() string { + if d.Endpoint == "" { + return d.Region + d.Zone + } + return d.Zone } func generateId() string { rb := make([]byte, 10) _, err := rand.Read(rb) if err != nil { - log.Fatalf("unable to generate id: %s", err) + log.Warnf("Unable to generate id: %s", err) } h := md5.New() diff --git a/drivers/amazonec2/amazonec2_test.go b/drivers/amazonec2/amazonec2_test.go index f26d2bbb13..a74ce3709a 100644 --- a/drivers/amazonec2/amazonec2_test.go +++ b/drivers/amazonec2/amazonec2_test.go @@ -3,125 +3,558 @@ package amazonec2 import ( "testing" - "github.com/docker/machine/drivers/amazonec2/amz" -) + "errors" + "reflect" -var ( - securityGroup = amz.SecurityGroup{ - GroupName: "test-group", - GroupId: "12345", - VpcId: "12345", - } + "io/ioutil" + "os" + "path/filepath" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/docker/machine/commands/commandstest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) const ( - testSshPort = 22 - testDockerPort = 2376 + testSSHPort = int64(22) + testDockerPort = int64(2376) + testSwarmPort = int64(3376) ) -func TestConfigureSecurityGroupPermissionsEmpty(t *testing.T) { - group := securityGroup - perms := configureSecurityGroupPermissions(&group) - if len(perms) != 2 { - t.Fatalf("expected 2 permissions; received %d", len(perms)) +var ( + securityGroup = &ec2.SecurityGroup{ + GroupName: aws.String("test-group"), + GroupId: aws.String("12345"), + VpcId: aws.String("12345"), } +) + +func TestConfigureSecurityGroupPermissionsEmpty(t *testing.T) { + driver := NewTestDriver() + + perms, err := driver.configureSecurityGroupPermissions(securityGroup) + + assert.Nil(t, err) + assert.Len(t, perms, 2) } func TestConfigureSecurityGroupPermissionsSshOnly(t *testing.T) { + driver := NewTestDriver() group := securityGroup - - group.IpPermissions = []amz.IpPermission{ + group.IpPermissions = []*ec2.IpPermission{ { - IpProtocol: "tcp", - FromPort: testSshPort, - ToPort: testSshPort, + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(int64(testSSHPort)), + ToPort: aws.Int64(int64(testSSHPort)), }, } - perms := configureSecurityGroupPermissions(&group) - if len(perms) != 1 { - t.Fatalf("expected 1 permission; received %d", len(perms)) - } + perms, err := driver.configureSecurityGroupPermissions(group) - receivedPort := perms[0].FromPort - if receivedPort != testDockerPort { - t.Fatalf("expected permission on port %d; received port %d", testDockerPort, receivedPort) - } + assert.Nil(t, err) + assert.Len(t, perms, 1) + assert.Equal(t, testDockerPort, *perms[0].FromPort) } func TestConfigureSecurityGroupPermissionsDockerOnly(t *testing.T) { + driver := NewTestDriver() group := securityGroup - - group.IpPermissions = []amz.IpPermission{ + group.IpPermissions = []*ec2.IpPermission{ { - IpProtocol: "tcp", - FromPort: testDockerPort, - ToPort: testDockerPort, + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64((testDockerPort)), + ToPort: aws.Int64((testDockerPort)), }, } - perms := configureSecurityGroupPermissions(&group) - if len(perms) != 1 { - t.Fatalf("expected 1 permission; received %d", len(perms)) - } + perms, err := driver.configureSecurityGroupPermissions(group) - receivedPort := perms[0].FromPort - if receivedPort != testSshPort { - t.Fatalf("expected permission on port %d; received port %d", testSshPort, receivedPort) - } + assert.Nil(t, err) + assert.Len(t, perms, 1) + assert.Equal(t, testSSHPort, *perms[0].FromPort) } func TestConfigureSecurityGroupPermissionsDockerAndSsh(t *testing.T) { + driver := NewTestDriver() group := securityGroup - - group.IpPermissions = []amz.IpPermission{ + group.IpPermissions = []*ec2.IpPermission{ { - IpProtocol: "tcp", - FromPort: testSshPort, - ToPort: testSshPort, + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(testSSHPort), + ToPort: aws.Int64(testSSHPort), }, { - IpProtocol: "tcp", - FromPort: testDockerPort, - ToPort: testDockerPort, + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(testDockerPort), + ToPort: aws.Int64(testDockerPort), }, } - perms := configureSecurityGroupPermissions(&group) - if len(perms) != 0 { - t.Fatalf("expected 0 permissions; received %d", len(perms)) + perms, err := driver.configureSecurityGroupPermissions(group) + + assert.Nil(t, err) + assert.Empty(t, perms) +} + +func TestConfigureSecurityGroupPermissionsSkipReadOnly(t *testing.T) { + driver := NewTestDriver() + driver.SecurityGroupReadOnly = true + perms, err := driver.configureSecurityGroupPermissions(securityGroup) + + assert.Nil(t, err) + assert.Len(t, perms, 0) +} + +func TestConfigureSecurityGroupPermissionsOpenPorts(t *testing.T) { + driver := NewTestDriver() + driver.OpenPorts = []string{"8888/tcp", "8080/udp", "9090"} + perms, err := driver.configureSecurityGroupPermissions(&ec2.SecurityGroup{}) + + assert.NoError(t, err) + assert.Len(t, perms, 5) + assert.Equal(t, aws.Int64(int64(8888)), perms[2].ToPort) + assert.Equal(t, aws.String("tcp"), perms[2].IpProtocol) + assert.Equal(t, aws.Int64(int64(8080)), perms[3].ToPort) + assert.Equal(t, aws.String("udp"), perms[3].IpProtocol) + assert.Equal(t, aws.Int64(int64(9090)), perms[4].ToPort) + assert.Equal(t, aws.String("tcp"), perms[4].IpProtocol) +} + +func TestConfigureSecurityGroupPermissionsOpenPortsSkipExisting(t *testing.T) { + driver := NewTestDriver() + group := securityGroup + group.IpPermissions = []*ec2.IpPermission{ + { + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(8888), + ToPort: aws.Int64(testSSHPort), + }, + { + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(8080), + ToPort: aws.Int64(testSSHPort), + }, } + driver.OpenPorts = []string{"8888/tcp", "8080/udp", "8080"} + perms, err := driver.configureSecurityGroupPermissions(group) + assert.NoError(t, err) + assert.Len(t, perms, 3) + assert.Equal(t, aws.Int64(int64(8080)), perms[2].ToPort) + assert.Equal(t, aws.String("udp"), perms[2].IpProtocol) +} + +func TestConfigureSecurityGroupPermissionsInvalidOpenPorts(t *testing.T) { + driver := NewTestDriver() + driver.OpenPorts = []string{"2222/tcp", "abc1"} + perms, err := driver.configureSecurityGroupPermissions(&ec2.SecurityGroup{}) + + assert.Error(t, err) + assert.Nil(t, perms) } -func TestAwsRegionList(t *testing.T) { +func TestConfigureSecurityGroupPermissionsWithSwarm(t *testing.T) { + driver := NewTestDriver() + driver.SwarmMaster = true + group := securityGroup + group.IpPermissions = []*ec2.IpPermission{ + { + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(testSSHPort), + ToPort: aws.Int64(testSSHPort), + }, + { + IpProtocol: aws.String("tcp"), + FromPort: aws.Int64(testDockerPort), + ToPort: aws.Int64(testDockerPort), + }, + } + + perms, err := driver.configureSecurityGroupPermissions(group) + + assert.Nil(t, err) + assert.Len(t, perms, 1) + assert.Equal(t, testSwarmPort, *perms[0].FromPort) } func TestValidateAwsRegionValid(t *testing.T) { regions := []string{"eu-west-1", "eu-central-1"} - for _, v := range regions { - r, err := validateAwsRegion(v) - if err != nil { - t.Fatal(err) + for _, region := range regions { + validatedRegion, err := validateAwsRegion(region) + + assert.NoError(t, err) + assert.Equal(t, region, validatedRegion) + } +} + +func TestValidateAwsRegionInvalid(t *testing.T) { + regions := []string{"eu-central-2"} + + for _, region := range regions { + _, err := validateAwsRegion(region) + + assert.EqualError(t, err, "Invalid region specified") + } +} + +func TestFindDefaultVPC(t *testing.T) { + driver := NewDriver("machineFoo", "path") + driver.clientFactory = func() Ec2Client { + return &fakeEC2WithLogin{} + } + + vpc, err := driver.getDefaultVPCId() + + assert.Equal(t, "vpc-9999", vpc) + assert.NoError(t, err) +} + +func TestDefaultVPCIsMissing(t *testing.T) { + driver := NewDriver("machineFoo", "path") + driver.clientFactory = func() Ec2Client { + return &fakeEC2WithDescribe{ + output: &ec2.DescribeAccountAttributesOutput{ + AccountAttributes: []*ec2.AccountAttribute{}, + }, } + } - if v != r { - t.Fatal("Wrong region returned") + vpc, err := driver.getDefaultVPCId() + + assert.EqualError(t, err, "No default-vpc attribute") + assert.Empty(t, vpc) +} + +func TestDefaultVPCIsNone(t *testing.T) { + driver := NewDriver("machineFoo", "path") + attributeName := "default-vpc" + vpcName := "none" + driver.clientFactory = func() Ec2Client { + return &fakeEC2WithDescribe{ + output: &ec2.DescribeAccountAttributesOutput{ + AccountAttributes: []*ec2.AccountAttribute{ + { + AttributeName: &attributeName, + AttributeValues: []*ec2.AccountAttributeValue{ + {AttributeValue: &vpcName}, + }, + }, + }, + }, } } + + vpc, err := driver.getDefaultVPCId() + + assert.EqualError(t, err, "default-vpc is 'none'") + assert.Empty(t, vpc) } -func TestValidateAwsRegionInvalid(t *testing.T) { - regions := []string{"eu-west-2", "eu-central-2"} +func TestGetRegionZoneForDefaultEndpoint(t *testing.T) { + driver := NewCustomTestDriver(&fakeEC2WithLogin{}) + driver.awsCredentialsFactory = NewValidAwsCredentials + options := &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "name": "test", + "amazonec2-region": "us-east-1", + "amazonec2-zone": "e", + }, + } + + err := driver.SetConfigFromFlags(options) + + regionZone := driver.getRegionZone() - for _, v := range regions { - r, err := validateAwsRegion(v) - if err == nil { - t.Fatal("No error returned") + assert.Equal(t, "us-east-1e", regionZone) + assert.NoError(t, err) +} + +func TestGetRegionZoneForCustomEndpoint(t *testing.T) { + driver := NewCustomTestDriver(&fakeEC2WithLogin{}) + driver.awsCredentialsFactory = NewValidAwsCredentials + options := &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "name": "test", + "amazonec2-endpoint": "https://someurl", + "amazonec2-region": "custom-endpoint", + "amazonec2-zone": "custom-zone", + }, + } + + err := driver.SetConfigFromFlags(options) + + regionZone := driver.getRegionZone() + + assert.Equal(t, "custom-zone", regionZone) + assert.NoError(t, err) +} + +func TestDescribeAccountAttributeFails(t *testing.T) { + driver := NewDriver("machineFoo", "path") + driver.clientFactory = func() Ec2Client { + return &fakeEC2WithDescribe{ + err: errors.New("Not Found"), } + } - if v == r { - t.Fatal("Wrong region returned") + vpc, err := driver.getDefaultVPCId() + + assert.EqualError(t, err, "Not Found") + assert.Empty(t, vpc) +} + +func TestAwsCredentialsAreRequired(t *testing.T) { + driver := NewTestDriver() + driver.awsCredentialsFactory = NewErrorAwsCredentials + + options := &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "name": "test", + "amazonec2-region": "us-east-1", + "amazonec2-zone": "e", + }, + } + + err := driver.SetConfigFromFlags(options) + assert.Equal(t, err, errorMissingCredentials) +} + +func TestValidAwsCredentialsAreAccepted(t *testing.T) { + driver := NewCustomTestDriver(&fakeEC2WithLogin{}) + driver.awsCredentialsFactory = NewValidAwsCredentials + options := &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "name": "test", + "amazonec2-region": "us-east-1", + "amazonec2-zone": "e", + }, + } + + err := driver.SetConfigFromFlags(options) + assert.NoError(t, err) +} + +func TestEndpointIsMandatoryWhenSSLDisabled(t *testing.T) { + driver := NewTestDriver() + driver.awsCredentialsFactory = NewValidAwsCredentials + options := &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "name": "test", + "amazonec2-access-key": "foobar", + "amazonec2-region": "us-east-1", + "amazonec2-zone": "e", + "amazonec2-insecure-transport": true, + }, + } + + err := driver.SetConfigFromFlags(options) + + assert.Equal(t, err, errorDisableSSLWithoutCustomEndpoint) +} + +var values = []string{ + "bob", + "jake", + "jill", +} + +var pointerSliceTests = []struct { + input []string + expected []*string +}{ + {[]string{}, []*string{}}, + {[]string{values[1]}, []*string{&values[1]}}, + {[]string{values[0], values[2], values[2]}, []*string{&values[0], &values[2], &values[2]}}, +} + +func TestMakePointerSlice(t *testing.T) { + for _, tt := range pointerSliceTests { + actual := makePointerSlice(tt.input) + assert.Equal(t, tt.expected, actual) + } +} + +var securityGroupNameTests = []struct { + groupName string + groupNames []string + expected []string +}{ + {groupName: "bob", expected: []string{"bob"}}, + {groupNames: []string{"bill"}, expected: []string{"bill"}}, + {groupName: "bob", groupNames: []string{"bill"}, expected: []string{"bob", "bill"}}, +} + +func TestMergeSecurityGroupName(t *testing.T) { + for _, tt := range securityGroupNameTests { + d := Driver{SecurityGroupName: tt.groupName, SecurityGroupNames: tt.groupNames} + assert.Equal(t, tt.expected, d.securityGroupNames()) + } +} + +var securityGroupIdTests = []struct { + groupId string + groupIds []string + expected []string +}{ + {groupId: "id", expected: []string{"id"}}, + {groupIds: []string{"id"}, expected: []string{"id"}}, + {groupId: "id1", groupIds: []string{"id2"}, expected: []string{"id1", "id2"}}, +} + +func TestMergeSecurityGroupId(t *testing.T) { + for _, tt := range securityGroupIdTests { + d := Driver{SecurityGroupId: tt.groupId, SecurityGroupIds: tt.groupIds} + assert.Equal(t, tt.expected, d.securityGroupIds()) + } +} + +func matchGroupLookup(expected []string) interface{} { + return func(input *ec2.DescribeSecurityGroupsInput) bool { + actual := []string{} + for _, filter := range input.Filters { + if *filter.Name == "group-name" { + for _, groupName := range filter.Values { + actual = append(actual, *groupName) + } + } } + return reflect.DeepEqual(expected, actual) + } +} + +func ipPermission(port int64) *ec2.IpPermission { + return &ec2.IpPermission{ + FromPort: aws.Int64(port), + ToPort: aws.Int64(port), + IpProtocol: aws.String("tcp"), + IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}}, } } + +func TestConfigureSecurityGroupsEmpty(t *testing.T) { + recorder := fakeEC2SecurityGroupTestRecorder{} + + driver := NewCustomTestDriver(&recorder) + err := driver.configureSecurityGroups([]string{}) + + assert.Nil(t, err) + recorder.AssertExpectations(t) +} + +func TestConfigureSecurityGroupsMixed(t *testing.T) { + groups := []string{"existingGroup", "newGroup"} + recorder := fakeEC2SecurityGroupTestRecorder{} + + // First, a check is made for which groups already exist. + initialLookupResult := ec2.DescribeSecurityGroupsOutput{SecurityGroups: []*ec2.SecurityGroup{ + { + GroupName: aws.String("existingGroup"), + GroupId: aws.String("existingGroupId"), + IpPermissions: []*ec2.IpPermission{ipPermission(testSSHPort)}, + }, + }} + recorder.On("DescribeSecurityGroups", mock.MatchedBy(matchGroupLookup(groups))).Return( + &initialLookupResult, nil) + + // An ingress permission is added to the existing group. + recorder.On("AuthorizeSecurityGroupIngress", &ec2.AuthorizeSecurityGroupIngressInput{ + GroupId: aws.String("existingGroupId"), + IpPermissions: []*ec2.IpPermission{ipPermission(testDockerPort)}, + }).Return( + &ec2.AuthorizeSecurityGroupIngressOutput{}, nil) + + // The new security group is created. + recorder.On("CreateSecurityGroup", &ec2.CreateSecurityGroupInput{ + GroupName: aws.String("newGroup"), + Description: aws.String("Docker Machine"), + VpcId: aws.String(""), + }).Return( + &ec2.CreateSecurityGroupOutput{GroupId: aws.String("newGroupId")}, nil) + + // Ensuring the new security group exists. + postCreateLookupResult := ec2.DescribeSecurityGroupsOutput{SecurityGroups: []*ec2.SecurityGroup{ + { + GroupName: aws.String("newGroup"), + GroupId: aws.String("newGroupId"), + }, + }} + recorder.On("DescribeSecurityGroups", + &ec2.DescribeSecurityGroupsInput{GroupIds: []*string{aws.String("newGroupId")}}).Return( + &postCreateLookupResult, nil) + + // Permissions are added to the new security group. + recorder.On("AuthorizeSecurityGroupIngress", &ec2.AuthorizeSecurityGroupIngressInput{ + GroupId: aws.String("newGroupId"), + IpPermissions: []*ec2.IpPermission{ipPermission(testSSHPort), ipPermission(testDockerPort)}, + }).Return( + &ec2.AuthorizeSecurityGroupIngressOutput{}, nil) + + driver := NewCustomTestDriver(&recorder) + err := driver.configureSecurityGroups(groups) + + assert.Nil(t, err) + recorder.AssertExpectations(t) +} + +func TestConfigureSecurityGroupsErrLookupExist(t *testing.T) { + groups := []string{"group"} + recorder := fakeEC2SecurityGroupTestRecorder{} + + lookupExistErr := errors.New("lookup failed") + recorder.On("DescribeSecurityGroups", mock.MatchedBy(matchGroupLookup(groups))).Return( + nil, lookupExistErr) + + driver := NewCustomTestDriver(&recorder) + err := driver.configureSecurityGroups(groups) + + assert.Exactly(t, lookupExistErr, err) + recorder.AssertExpectations(t) +} + +func TestBase64UserDataIsEmptyIfNoFileProvided(t *testing.T) { + driver := NewTestDriver() + + userdata, err := driver.Base64UserData() + + assert.NoError(t, err) + assert.Empty(t, userdata) +} + +func TestBase64UserDataGeneratesErrorIfFileNotFound(t *testing.T) { + dir, err := ioutil.TempDir("", "awsuserdata") + assert.NoError(t, err, "Unable to create temporary directory.") + + defer os.RemoveAll(dir) + userdata_path := filepath.Join(dir, "does-not-exist.yml") + + driver := NewTestDriver() + driver.UserDataFile = userdata_path + + _, ud_err := driver.Base64UserData() + assert.Equal(t, ud_err, errorReadingUserData) +} + +func TestBase64UserDataIsCorrectWhenFileProvided(t *testing.T) { + dir, err := ioutil.TempDir("", "awsuserdata") + assert.NoError(t, err, "Unable to create temporary directory.") + + defer os.RemoveAll(dir) + + userdata_path := filepath.Join(dir, "test-userdata.yml") + + content := []byte("#cloud-config\nhostname: userdata-test\nfqdn: userdata-test.amazonec2.driver\n") + contentBase64 := "I2Nsb3VkLWNvbmZpZwpob3N0bmFtZTogdXNlcmRhdGEtdGVzdApmcWRuOiB1c2VyZGF0YS10ZXN0LmFtYXpvbmVjMi5kcml2ZXIK" + + err = ioutil.WriteFile(userdata_path, content, 0666) + assert.NoError(t, err, "Unable to create temporary userdata file.") + + driver := NewTestDriver() + driver.UserDataFile = userdata_path + + userdata, ud_err := driver.Base64UserData() + + assert.NoError(t, ud_err) + assert.Equal(t, contentBase64, userdata) +} diff --git a/drivers/amazonec2/amz/auth.go b/drivers/amazonec2/amz/auth.go deleted file mode 100644 index 22291b5306..0000000000 --- a/drivers/amazonec2/amz/auth.go +++ /dev/null @@ -1,9 +0,0 @@ -package amz - -type Auth struct { - AccessKey, SecretKey, SessionToken string -} - -func GetAuth(accessKey, secretKey, sessionToken string) Auth { - return Auth{accessKey, secretKey, sessionToken} -} diff --git a/drivers/amazonec2/amz/block_device_mapping.go b/drivers/amazonec2/amz/block_device_mapping.go deleted file mode 100644 index 27c6cecf3d..0000000000 --- a/drivers/amazonec2/amz/block_device_mapping.go +++ /dev/null @@ -1,9 +0,0 @@ -package amz - -type BlockDeviceMapping struct { - DeviceName string - VirtualName string - VolumeSize int64 - DeleteOnTermination bool - VolumeType string -} diff --git a/drivers/amazonec2/amz/describe_instances.go b/drivers/amazonec2/amz/describe_instances.go deleted file mode 100644 index 34faa78bce..0000000000 --- a/drivers/amazonec2/amz/describe_instances.go +++ /dev/null @@ -1,8 +0,0 @@ -package amz - -type DescribeInstancesResponse struct { - RequestId string `xml:"requestId"` - ReservationSet []struct { - InstancesSet []EC2Instance `xml:"instancesSet>item"` - } `xml:"reservationSet>item"` -} diff --git a/drivers/amazonec2/amz/describe_keypairs.go b/drivers/amazonec2/amz/describe_keypairs.go deleted file mode 100644 index 802c8828e2..0000000000 --- a/drivers/amazonec2/amz/describe_keypairs.go +++ /dev/null @@ -1,6 +0,0 @@ -package amz - -type DescribeKeyPairsResponse struct { - RequestId string `xml:"requestId"` - KeySet []KeyPair `xml:"keySet>item"` -} diff --git a/drivers/amazonec2/amz/describe_security_groups.go b/drivers/amazonec2/amz/describe_security_groups.go deleted file mode 100644 index f03a9dd4b0..0000000000 --- a/drivers/amazonec2/amz/describe_security_groups.go +++ /dev/null @@ -1,6 +0,0 @@ -package amz - -type DescribeSecurityGroupsResponse struct { - RequestId string `xml:"requestId"` - SecurityGroupInfo []SecurityGroup `xml:"securityGroupInfo>item"` -} diff --git a/drivers/amazonec2/amz/describe_subnets.go b/drivers/amazonec2/amz/describe_subnets.go deleted file mode 100644 index 1fabdc5c05..0000000000 --- a/drivers/amazonec2/amz/describe_subnets.go +++ /dev/null @@ -1,14 +0,0 @@ -package amz - -type DescribeSubnetsResponse struct { - RequestId string `xml:"requestId"` - SubnetSet []Subnet `xml:"subnetSet>item"` -} - -type Subnet struct { - SubnetId string `xml:"subnetId"` - State string `xml:"state"` - VpcId string `xml:"vpcId"` - CidrBlock string `xml:"cidrBlock"` - AvailabilityZone string `xml:"availabilityZone"` -} diff --git a/drivers/amazonec2/amz/ec2.go b/drivers/amazonec2/amz/ec2.go deleted file mode 100644 index a79c76ad2f..0000000000 --- a/drivers/amazonec2/amz/ec2.go +++ /dev/null @@ -1,590 +0,0 @@ -package amz - -import ( - "encoding/base64" - "encoding/xml" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "strconv" - "strings" - - "github.com/docker/machine/state" - awsauth "github.com/smartystreets/go-aws-auth" -) - -type ( - EC2 struct { - Endpoint string - Auth Auth - Region string - } - - Instance struct { - info EC2Instance - } - - EC2Instance struct { - InstanceId string `xml:"instanceId"` - ImageId string `xml:"imageId"` - InstanceState struct { - Code int `xml:"code"` - Name string `xml:"name"` - } `xml:"instanceState"` - PrivateDnsName string `xml:"privateDnsName"` - DnsName string `xml:"dnsName"` - Reason string `xml:"reason"` - AmiLaunchIndex string `xml:"amiLaunchIndex"` - ProductCodes string `xml:"productCodes"` - InstanceType string `xml:"instanceType"` - LaunchTime string `xml:"launchTime"` - Placement struct { - AvailabilityZone string `xml:"availabilityZone"` - GroupName string `xml:"groupName"` - Tenancy string `xml:"tenancy"` - } `xml:"placement"` - KernelId string `xml:"kernelId"` - Monitoring struct { - State string `xml:"state"` - } `xml:"monitoring"` - SubnetId string `xml:"subnetId"` - VpcId string `xml:"vpcId"` - IpAddress string `xml:"ipAddress"` - PrivateIpAddress string `xml:"privateIpAddress"` - SourceDestCheck bool `xml:"sourceDestCheck"` - GroupSet []struct { - GroupId string `xml:"groupId"` - GroupName string `xml:"groupName"` - } `xml:"groupSet"` - StateReason struct { - Code string `xml:"code"` - Message string `xml:"message"` - } `xml:"stateReason"` - Architecture string `xml:"architecture"` - RootDeviceType string `xml:"rootDeviceType"` - RootDeviceName string `xml:"rootDeviceName"` - BlockDeviceMapping string `xml:"blockDeviceMapping"` - VirtualizationType string `xml:"virtualizationType"` - ClientToken string `xml:"clientToken"` - Hypervisor string `xml:"hypervisor"` - NetworkInterfaceSet []struct { - NetworkInterfaceId string `xml:"networkInterfaceId"` - SubnetId string `xml:"subnetId"` - VpcId string `xml:"vpcId"` - Description string `xml:"description"` - OwnerId string `xml:"ownerId"` - Status string `xml:"status"` - MacAddress string `xml:"macAddress"` - PrivateIpAddress string `xml:"privateIpAddress"` - PrivateDnsName string `xml:"privateDnsName"` - SourceDestCheck string `xml:"sourceDestCheck"` - GroupSet []struct { - GroupId string `xml:"groupId"` - GroupName string `xml:"groupName"` - } `xml:"groupSet>item"` - Attachment struct { - AttachmentId string `xml:"attachmentId"` - DeviceIndex string `xml:"deviceIndex"` - Status string `xml:"status"` - AttachTime string `xml:"attachTime"` - DeleteOnTermination bool `xml:"deleteOnTermination"` - } `xml:"attachment"` - PrivateIpAddressesSet []struct { - PrivateIpAddress string `xml:"privateIpAddress"` - PrivateDnsName string `xml:"privateDnsName"` - Primary bool `xml:"primary"` - } `xml:"privateIpAddressesSet>item"` - } `xml:"networkInterfaceSet>item"` - EbsOptimized bool `xml:"ebsOptimized"` - } - - RunInstancesResponse struct { - RequestId string `xml:"requestId"` - ReservationId string `xml:"reservationId"` - OwnerId string `xml:"ownerId"` - Instances []EC2Instance `xml:"instancesSet>item"` - } -) - -func newAwsApiResponseError(r http.Response) error { - var errorResponse ErrorResponse - if err := getDecodedResponse(r, &errorResponse); err != nil { - return fmt.Errorf("Error decoding error response: %s", err) - } - msg := "" - for _, e := range errorResponse.Errors { - msg += fmt.Sprintf("%s\n", e.Message) - } - return fmt.Errorf("Non-200 API response: code=%d message=%s", r.StatusCode, msg) -} - -func newAwsApiCallError(err error) error { - return fmt.Errorf("Problem with AWS API call: %s", err) -} - -func getDecodedResponse(r http.Response, into interface{}) error { - defer r.Body.Close() - if err := xml.NewDecoder(r.Body).Decode(into); err != nil { - return fmt.Errorf("Error decoding error response: %s", err) - } - return nil -} - -func NewEC2(auth Auth, region string) *EC2 { - endpoint := fmt.Sprintf("https://ec2.%s.amazonaws.com", region) - return &EC2{ - Endpoint: endpoint, - Auth: auth, - Region: region, - } -} - -func (e *EC2) awsApiCall(v url.Values) (http.Response, error) { - v.Set("Version", "2014-06-15") - client := &http.Client{} - finalEndpoint := fmt.Sprintf("%s?%s", e.Endpoint, v.Encode()) - req, err := http.NewRequest("GET", finalEndpoint, nil) - if err != nil { - return http.Response{}, fmt.Errorf("error creating request from client") - } - req.Header.Add("Content-type", "application/json") - - awsauth.Sign4(req, awsauth.Credentials{ - AccessKeyID: e.Auth.AccessKey, - SecretAccessKey: e.Auth.SecretKey, - SecurityToken: e.Auth.SessionToken, - }) - resp, err := client.Do(req) - if err != nil { - return *resp, fmt.Errorf("client encountered error while doing the request: %s", err) - } - if resp.StatusCode != http.StatusOK { - return *resp, newAwsApiResponseError(*resp) - } - return *resp, nil -} - -func (e *EC2) RunInstance(amiId string, instanceType string, zone string, minCount int, maxCount int, securityGroup string, keyName string, subnetId string, bdm *BlockDeviceMapping) (EC2Instance, error) { - instance := Instance{} - v := url.Values{} - v.Set("Action", "RunInstances") - v.Set("ImageId", amiId) - v.Set("Placement.AvailabilityZone", e.Region+zone) - v.Set("MinCount", strconv.Itoa(minCount)) - v.Set("MaxCount", strconv.Itoa(maxCount)) - v.Set("KeyName", keyName) - v.Set("InstanceType", instanceType) - v.Set("NetworkInterface.0.DeviceIndex", "0") - v.Set("NetworkInterface.0.SecurityGroupId.0", securityGroup) - v.Set("NetworkInterface.0.SubnetId", subnetId) - v.Set("NetworkInterface.0.AssociatePublicIpAddress", "1") - - if bdm != nil { - v.Set("BlockDeviceMapping.0.DeviceName", bdm.DeviceName) - v.Set("BlockDeviceMapping.0.VirtualName", bdm.VirtualName) - v.Set("BlockDeviceMapping.0.Ebs.VolumeSize", strconv.FormatInt(bdm.VolumeSize, 10)) - v.Set("BlockDeviceMapping.0.Ebs.VolumeType", bdm.VolumeType) - deleteOnTerm := 0 - if bdm.DeleteOnTermination { - deleteOnTerm = 1 - } - v.Set("BlockDeviceMapping.0.Ebs.DeleteOnTermination", strconv.Itoa(deleteOnTerm)) - } - - resp, err := e.awsApiCall(v) - - if err != nil { - return instance.info, newAwsApiCallError(err) - } - defer resp.Body.Close() - - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return instance.info, fmt.Errorf("Error reading AWS response body") - } - unmarshalledResponse := RunInstancesResponse{} - err = xml.Unmarshal(contents, &unmarshalledResponse) - if err != nil { - return instance.info, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - instance.info = unmarshalledResponse.Instances[0] - return instance.info, nil -} - -func (e *EC2) DeleteKeyPair(name string) error { - v := url.Values{} - v.Set("Action", "DeleteKeyPair") - v.Set("KeyName", name) - - _, err := e.awsApiCall(v) - if err != nil { - return fmt.Errorf("Error making API call to delete keypair :%s", err) - } - return nil -} - -func (e *EC2) CreateKeyPair(name string) ([]byte, error) { - v := url.Values{} - v.Set("Action", "CreateKeyPair") - v.Set("KeyName", name) - resp, err := e.awsApiCall(v) - if err != nil { - return nil, fmt.Errorf("Error trying API call to create keypair: %s", err) - } - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("Error reading AWS response body") - } - - unmarshalledResponse := CreateKeyPairResponse{} - if xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return nil, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - key := unmarshalledResponse.KeyMaterial - - return key, nil -} - -func (e *EC2) ImportKeyPair(name, publicKey string) error { - keyMaterial := base64.StdEncoding.EncodeToString([]byte(publicKey)) - - v := url.Values{} - v.Set("Action", "ImportKeyPair") - v.Set("KeyName", name) - v.Set("PublicKeyMaterial", keyMaterial) - - resp, err := e.awsApiCall(v) - if err != nil { - return fmt.Errorf("Error trying API call to create keypair: %s", err) - } - - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("Error reading AWS response body") - } - - unmarshalledResponse := ImportKeyPairResponse{} - if xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - return nil -} - -func (e *EC2) CreateTags(id string, tags map[string]string) error { - v := url.Values{} - v.Set("Action", "CreateTags") - v.Set("ResourceId.1", id) - - counter := 1 - for k, val := range tags { - v.Set(fmt.Sprintf("Tag.%d.Key", counter), k) - v.Set(fmt.Sprintf("Tag.%d.Value", counter), val) - - counter += 1 - } - - resp, err := e.awsApiCall(v) - defer resp.Body.Close() - if err != nil { - return err - } - - createTagsResponse := &CreateTagsResponse{} - - if err := getDecodedResponse(resp, &createTagsResponse); err != nil { - return fmt.Errorf("Error decoding create tags response: %s", err) - } - - return nil -} - -func (e *EC2) CreateSecurityGroup(name string, description string, vpcId string) (*SecurityGroup, error) { - v := url.Values{} - v.Set("Action", "CreateSecurityGroup") - v.Set("GroupName", name) - v.Set("GroupDescription", url.QueryEscape(description)) - v.Set("VpcId", vpcId) - - resp, err := e.awsApiCall(v) - defer resp.Body.Close() - if err != nil { - // ugly hack since API has no way to check if SG already exists - if resp.StatusCode == http.StatusBadRequest { - var errorResponse ErrorResponse - if err := getDecodedResponse(resp, &errorResponse); err != nil { - return nil, fmt.Errorf("Error decoding error response: %s", err) - } - if errorResponse.Errors[0].Code == ErrorDuplicateGroup { - return nil, nil - } - } - return nil, fmt.Errorf("Error making API call to create security group: %s", err) - } - - createSecurityGroupResponse := CreateSecurityGroupResponse{} - - if err := getDecodedResponse(resp, &createSecurityGroupResponse); err != nil { - return nil, fmt.Errorf("Error decoding create security groups response: %s", err) - } - - group := &SecurityGroup{ - GroupId: createSecurityGroupResponse.GroupId, - VpcId: vpcId, - } - return group, nil -} - -func (e *EC2) AuthorizeSecurityGroup(groupId string, permissions []IpPermission) error { - v := url.Values{} - v.Set("Action", "AuthorizeSecurityGroupIngress") - v.Set("GroupId", groupId) - - for index, perm := range permissions { - n := index + 1 // amazon starts counting from 1 not 0 - v.Set(fmt.Sprintf("IpPermissions.%d.IpProtocol", n), perm.IpProtocol) - v.Set(fmt.Sprintf("IpPermissions.%d.FromPort", n), strconv.Itoa(perm.FromPort)) - v.Set(fmt.Sprintf("IpPermissions.%d.ToPort", n), strconv.Itoa(perm.ToPort)) - v.Set(fmt.Sprintf("IpPermissions.%d.IpRanges.1.CidrIp", n), perm.IpRange) - } - resp, err := e.awsApiCall(v) - defer resp.Body.Close() - if err != nil { - return fmt.Errorf("Error making API call to authorize security group ingress: %s", err) - } - return nil -} - -func (e *EC2) DeleteSecurityGroup(groupId string) error { - v := url.Values{} - v.Set("Action", "DeleteSecurityGroup") - v.Set("GroupId", groupId) - - resp, err := e.awsApiCall(v) - defer resp.Body.Close() - if err != nil { - return fmt.Errorf("Error making API call to delete security group: %s", err) - } - - deleteSecurityGroupResponse := DeleteSecurityGroupResponse{} - - if err := getDecodedResponse(resp, &deleteSecurityGroupResponse); err != nil { - return fmt.Errorf("Error decoding delete security groups response: %s", err) - } - - return nil -} - -func (e *EC2) GetSecurityGroups() ([]SecurityGroup, error) { - sgs := []SecurityGroup{} - resp, err := e.performStandardAction("DescribeSecurityGroups") - if err != nil { - return sgs, err - } - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return sgs, fmt.Errorf("Error reading AWS response body: %s", err) - } - - unmarshalledResponse := DescribeSecurityGroupsResponse{} - if err = xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return sgs, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - sgs = unmarshalledResponse.SecurityGroupInfo - - return sgs, nil -} - -func (e *EC2) GetSecurityGroupById(id string) (*SecurityGroup, error) { - groups, err := e.GetSecurityGroups() - if err != nil { - return nil, err - } - - for _, g := range groups { - if g.GroupId == id { - return &g, nil - } - } - return nil, nil -} - -func (e *EC2) GetSubnets() ([]Subnet, error) { - subnets := []Subnet{} - resp, err := e.performStandardAction("DescribeSubnets") - if err != nil { - return subnets, err - } - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return subnets, fmt.Errorf("Error reading AWS response body: %s", err) - } - - unmarshalledResponse := DescribeSubnetsResponse{} - if err = xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return subnets, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - subnets = unmarshalledResponse.SubnetSet - - return subnets, nil -} - -func (e *EC2) GetKeyPairs() ([]KeyPair, error) { - keyPairs := []KeyPair{} - resp, err := e.performStandardAction("DescribeKeyPairs") - if err != nil { - return keyPairs, err - } - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return keyPairs, fmt.Errorf("Error reading AWS response body: %s", err) - } - - unmarshalledResponse := DescribeKeyPairsResponse{} - if err = xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return keyPairs, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - keyPairs = unmarshalledResponse.KeySet - - return keyPairs, nil -} - -func (e *EC2) GetKeyPair(name string) (*KeyPair, error) { - keyPairs, err := e.GetKeyPairs() - if err != nil { - return nil, err - } - - for _, key := range keyPairs { - if key.KeyName == name { - return &key, nil - } - } - return nil, nil -} - -func (e *EC2) GetInstanceState(instanceId string) (state.State, error) { - resp, err := e.performInstanceAction(instanceId, "DescribeInstances", nil) - if err != nil { - return state.Error, err - } - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return state.Error, fmt.Errorf("Error reading AWS response body: %s", err) - } - - unmarshalledResponse := DescribeInstancesResponse{} - if err = xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return state.Error, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - reservationSet := unmarshalledResponse.ReservationSet[0] - instanceState := reservationSet.InstancesSet[0].InstanceState - - shortState := strings.TrimSpace(instanceState.Name) - switch shortState { - case "pending": - return state.Starting, nil - case "running": - return state.Running, nil - case "stopped": - return state.Stopped, nil - case "stopping": - return state.Stopped, nil - } - - return state.Error, nil -} - -func (e *EC2) GetInstance(instanceId string) (EC2Instance, error) { - ec2Instance := EC2Instance{} - resp, err := e.performInstanceAction(instanceId, "DescribeInstances", nil) - if err != nil { - return ec2Instance, err - } - defer resp.Body.Close() - contents, err := ioutil.ReadAll(resp.Body) - if err != nil { - return ec2Instance, fmt.Errorf("Error reading AWS response body: %s", err) - } - - unmarshalledResponse := DescribeInstancesResponse{} - if err = xml.Unmarshal(contents, &unmarshalledResponse); err != nil { - return ec2Instance, fmt.Errorf("Error unmarshalling AWS response XML: %s", err) - } - - reservationSet := unmarshalledResponse.ReservationSet[0] - instance := reservationSet.InstancesSet[0] - return instance, nil -} - -func (e *EC2) StartInstance(instanceId string) error { - if _, err := e.performInstanceAction(instanceId, "StartInstances", nil); err != nil { - return err - } - return nil -} - -func (e *EC2) RestartInstance(instanceId string) error { - if _, err := e.performInstanceAction(instanceId, "RebootInstances", nil); err != nil { - return err - } - return nil -} - -func (e *EC2) StopInstance(instanceId string, force bool) error { - vars := make(map[string]string) - if force { - vars["Force"] = "1" - } - - if _, err := e.performInstanceAction(instanceId, "StopInstances", &vars); err != nil { - return err - } - return nil -} - -func (e *EC2) TerminateInstance(instanceId string) error { - if _, err := e.performInstanceAction(instanceId, "TerminateInstances", nil); err != nil { - return err - } - return nil -} - -func (e *EC2) performStandardAction(action string) (http.Response, error) { - v := url.Values{} - v.Set("Action", action) - resp, err := e.awsApiCall(v) - if err != nil { - return resp, newAwsApiCallError(err) - } - return resp, nil -} - -func (e *EC2) performInstanceAction(instanceId, action string, extraVars *map[string]string) (http.Response, error) { - v := url.Values{} - v.Set("Action", action) - v.Set("InstanceId.1", instanceId) - if extraVars != nil { - for k, val := range *extraVars { - v.Set(k, val) - } - } - resp, err := e.awsApiCall(v) - if err != nil { - return resp, newAwsApiCallError(err) - } - return resp, nil -} diff --git a/drivers/amazonec2/amz/error.go b/drivers/amazonec2/amz/error.go deleted file mode 100644 index b8cd98b828..0000000000 --- a/drivers/amazonec2/amz/error.go +++ /dev/null @@ -1,9 +0,0 @@ -package amz - -type ErrorResponse struct { - Errors []struct { - Code string - Message string - } `xml:"Errors>Error"` - RequestID string -} diff --git a/drivers/amazonec2/amz/error_codes.go b/drivers/amazonec2/amz/error_codes.go deleted file mode 100644 index a4de953b4e..0000000000 --- a/drivers/amazonec2/amz/error_codes.go +++ /dev/null @@ -1,5 +0,0 @@ -package amz - -const ( - ErrorDuplicateGroup = "InvalidGroup.Duplicate" -) diff --git a/drivers/amazonec2/amz/ip_permission.go b/drivers/amazonec2/amz/ip_permission.go deleted file mode 100644 index fe3a9df346..0000000000 --- a/drivers/amazonec2/amz/ip_permission.go +++ /dev/null @@ -1,8 +0,0 @@ -package amz - -type IpPermission struct { - IpProtocol string `xml:"ipProtocol"` - FromPort int `xml:"fromPort"` - ToPort int `xml:"toPort"` - IpRange string `xml:"ipRanges"` -} diff --git a/drivers/amazonec2/amz/keypair.go b/drivers/amazonec2/amz/keypair.go deleted file mode 100644 index b14d5977ed..0000000000 --- a/drivers/amazonec2/amz/keypair.go +++ /dev/null @@ -1,18 +0,0 @@ -package amz - -type CreateKeyPairResponse struct { - KeyName string `xml:"keyName"` - KeyFingerprint string `xml:"keyFingerprint"` - KeyMaterial []byte `xml:"keyMaterial"` -} - -type ImportKeyPairResponse struct { - KeyName string `xml:"keyName"` - KeyFingerprint string `xml:"keyFingerprint"` - KeyMaterial []byte `xml:"keyMaterial"` -} - -type KeyPair struct { - KeyFingerprint string `xml:"keyFingerprint"` - KeyName string `xml:"keyName"` -} diff --git a/drivers/amazonec2/amz/security_group.go b/drivers/amazonec2/amz/security_group.go deleted file mode 100644 index 2893206b98..0000000000 --- a/drivers/amazonec2/amz/security_group.go +++ /dev/null @@ -1,21 +0,0 @@ -package amz - -type CreateSecurityGroupResponse struct { - RequestId string `xml:"requestId"` - Return bool `xml:"return"` - GroupId string `xml:"groupId"` -} - -type DeleteSecurityGroupResponse struct { - RequestId string `xml:"requestId"` - Return bool `xml:"return"` -} - -type SecurityGroup struct { - GroupName string `xml:"groupName"` - GroupId string `xml:"groupId"` - VpcId string `xml:"vpcId"` - OwnerId string `xml:"ownerId"` - IpPermissions []IpPermission `xml:"ipPermissions>item,omitempty"` - IpPermissionsEgress []IpPermission `xml:"ipPermissionsEgress>item,omitempty"` -} diff --git a/drivers/amazonec2/amz/tags.go b/drivers/amazonec2/amz/tags.go deleted file mode 100644 index 0d25e90474..0000000000 --- a/drivers/amazonec2/amz/tags.go +++ /dev/null @@ -1,6 +0,0 @@ -package amz - -type CreateTagsResponse struct { - RequestId string `xml:"requestId"` - Return bool `xml:"return"` -} diff --git a/drivers/amazonec2/awscredentials.go b/drivers/amazonec2/awscredentials.go new file mode 100644 index 0000000000..ef04c6c21a --- /dev/null +++ b/drivers/amazonec2/awscredentials.go @@ -0,0 +1,63 @@ +package amazonec2 + +import ( + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" +) + +type awsCredentials interface { + Credentials() *credentials.Credentials +} + +type ProviderFactory interface { + NewStaticProvider(id, secret, token string) credentials.Provider +} + +type defaultAWSCredentials struct { + AccessKey string + SecretKey string + SessionToken string + providerFactory ProviderFactory + fallbackProvider awsCredentials +} + +func NewAWSCredentials(id, secret, token string) *defaultAWSCredentials { + creds := defaultAWSCredentials{ + AccessKey: id, + SecretKey: secret, + SessionToken: token, + fallbackProvider: &AwsDefaultCredentialsProvider{}, + providerFactory: &defaultProviderFactory{}, + } + return &creds +} + +func (c *defaultAWSCredentials) Credentials() *credentials.Credentials { + providers := []credentials.Provider{} + if c.AccessKey != "" && c.SecretKey != "" { + providers = append(providers, c.providerFactory.NewStaticProvider(c.AccessKey, c.SecretKey, c.SessionToken)) + } + if c.fallbackProvider != nil { + fallbackCreds, err := c.fallbackProvider.Credentials().Get() + if err == nil { + providers = append(providers, &credentials.StaticProvider{Value: fallbackCreds}) + } + } + return credentials.NewChainCredentials(providers) +} + +type AwsDefaultCredentialsProvider struct{} + +func (c *AwsDefaultCredentialsProvider) Credentials() *credentials.Credentials { + return session.New().Config.Credentials +} + +type defaultProviderFactory struct{} + +func (c *defaultProviderFactory) NewStaticProvider(id, secret, token string) credentials.Provider { + return &credentials.StaticProvider{Value: credentials.Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: token, + }} +} diff --git a/drivers/amazonec2/awscredentials_test.go b/drivers/amazonec2/awscredentials_test.go new file mode 100644 index 0000000000..7a64e46b75 --- /dev/null +++ b/drivers/amazonec2/awscredentials_test.go @@ -0,0 +1,100 @@ +package amazonec2 + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccessKeyIsMandatoryWhenSystemCredentialsAreNotPresent(t *testing.T) { + awsCreds := NewAWSCredentials("", "", "") + awsCreds.fallbackProvider = nil + + _, err := awsCreds.Credentials().Get() + assert.Error(t, err) +} + +func TestAccessKeyIsMandatoryEvenIfSecretKeyIsPassedWhenSystemCredentialsAreNotPresent(t *testing.T) { + awsCreds := NewAWSCredentials("", "secret", "") + awsCreds.fallbackProvider = nil + + _, err := awsCreds.Credentials().Get() + assert.Error(t, err) +} + +func TestSecretKeyIsMandatoryWhenSystemCredentialsAreNotPresent(t *testing.T) { + awsCreds := NewAWSCredentials("access", "", "") + awsCreds.fallbackProvider = nil + + _, err := awsCreds.Credentials().Get() + assert.Error(t, err) +} + +func TestFallbackCredentialsAreLoadedWhenAccessKeyAndSecretKeyAreMissing(t *testing.T) { + awsCreds := NewAWSCredentials("", "", "") + awsCreds.fallbackProvider = &fallbackCredentials{} + + creds, err := awsCreds.Credentials().Get() + + assert.NoError(t, err) + assert.Equal(t, "fallback_access", creds.AccessKeyID) + assert.Equal(t, "fallback_secret", creds.SecretAccessKey) + assert.Equal(t, "fallback_token", creds.SessionToken) +} + +func TestFallbackCredentialsAreLoadedWhenAccessKeyIsMissing(t *testing.T) { + awsCreds := NewAWSCredentials("", "secret", "") + awsCreds.fallbackProvider = &fallbackCredentials{} + + creds, err := awsCreds.Credentials().Get() + + assert.NoError(t, err) + assert.Equal(t, "fallback_access", creds.AccessKeyID) + assert.Equal(t, "fallback_secret", creds.SecretAccessKey) + assert.Equal(t, "fallback_token", creds.SessionToken) +} + +func TestFallbackCredentialsAreLoadedWhenSecretKeyIsMissing(t *testing.T) { + awsCreds := NewAWSCredentials("access", "", "") + awsCreds.fallbackProvider = &fallbackCredentials{} + + creds, err := awsCreds.Credentials().Get() + + assert.NoError(t, err) + assert.Equal(t, "fallback_access", creds.AccessKeyID) + assert.Equal(t, "fallback_secret", creds.SecretAccessKey) + assert.Equal(t, "fallback_token", creds.SessionToken) +} + +func TestOptionCredentialsAreLoadedWhenAccessKeyAndSecretKeyAreProvided(t *testing.T) { + awsCreds := NewAWSCredentials("access", "secret", "") + awsCreds.fallbackProvider = &fallbackCredentials{} + + creds, err := awsCreds.Credentials().Get() + + assert.NoError(t, err) + assert.Equal(t, "access", creds.AccessKeyID) + assert.Equal(t, "secret", creds.SecretAccessKey) + assert.Equal(t, "", creds.SessionToken) +} + +func TestFallbackCredentialsAreLoadedIfStaticCredentialsGenerateError(t *testing.T) { + awsCreds := NewAWSCredentials("access", "secret", "token") + awsCreds.fallbackProvider = &fallbackCredentials{} + awsCreds.providerFactory = &errorCredentialsProvider{} + + creds, err := awsCreds.Credentials().Get() + + assert.NoError(t, err) + assert.Equal(t, "fallback_access", creds.AccessKeyID) + assert.Equal(t, "fallback_secret", creds.SecretAccessKey) + assert.Equal(t, "fallback_token", creds.SessionToken) +} + +func TestErrorGeneratedWhenAllProvidersGenerateErrors(t *testing.T) { + awsCreds := NewAWSCredentials("access", "secret", "token") + awsCreds.fallbackProvider = &errorFallbackCredentials{} + awsCreds.providerFactory = &errorCredentialsProvider{} + + _, err := awsCreds.Credentials().Get() + assert.Error(t, err) +} diff --git a/drivers/amazonec2/ec2client.go b/drivers/amazonec2/ec2client.go new file mode 100644 index 0000000000..4a1550f3d0 --- /dev/null +++ b/drivers/amazonec2/ec2client.go @@ -0,0 +1,52 @@ +package amazonec2 + +import "github.com/aws/aws-sdk-go/service/ec2" + +type Ec2Client interface { + DescribeAccountAttributes(input *ec2.DescribeAccountAttributesInput) (*ec2.DescribeAccountAttributesOutput, error) + + DescribeSubnets(input *ec2.DescribeSubnetsInput) (*ec2.DescribeSubnetsOutput, error) + + CreateTags(input *ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) + + //SecurityGroup + + CreateSecurityGroup(input *ec2.CreateSecurityGroupInput) (*ec2.CreateSecurityGroupOutput, error) + + AuthorizeSecurityGroupIngress(input *ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) + + DescribeSecurityGroups(input *ec2.DescribeSecurityGroupsInput) (*ec2.DescribeSecurityGroupsOutput, error) + + DeleteSecurityGroup(input *ec2.DeleteSecurityGroupInput) (*ec2.DeleteSecurityGroupOutput, error) + + //KeyPair + + DeleteKeyPair(input *ec2.DeleteKeyPairInput) (*ec2.DeleteKeyPairOutput, error) + + ImportKeyPair(input *ec2.ImportKeyPairInput) (*ec2.ImportKeyPairOutput, error) + + DescribeKeyPairs(input *ec2.DescribeKeyPairsInput) (*ec2.DescribeKeyPairsOutput, error) + + //Instances + + DescribeInstances(input *ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) + + StartInstances(input *ec2.StartInstancesInput) (*ec2.StartInstancesOutput, error) + + RebootInstances(input *ec2.RebootInstancesInput) (*ec2.RebootInstancesOutput, error) + + StopInstances(input *ec2.StopInstancesInput) (*ec2.StopInstancesOutput, error) + + RunInstances(input *ec2.RunInstancesInput) (*ec2.Reservation, error) + + TerminateInstances(input *ec2.TerminateInstancesInput) (*ec2.TerminateInstancesOutput, error) + + //SpotInstances + + RequestSpotInstances(input *ec2.RequestSpotInstancesInput) (*ec2.RequestSpotInstancesOutput, error) + + DescribeSpotInstanceRequests(input *ec2.DescribeSpotInstanceRequestsInput) (*ec2.DescribeSpotInstanceRequestsOutput, error) + + WaitUntilSpotInstanceRequestFulfilled(input *ec2.DescribeSpotInstanceRequestsInput) error + CancelSpotInstanceRequests(input *ec2.CancelSpotInstanceRequestsInput) (*ec2.CancelSpotInstanceRequestsOutput, error) +} diff --git a/drivers/amazonec2/logger.go b/drivers/amazonec2/logger.go new file mode 100644 index 0000000000..a0dd929cdf --- /dev/null +++ b/drivers/amazonec2/logger.go @@ -0,0 +1,21 @@ +package amazonec2 + +import ( + "github.com/aws/aws-sdk-go/aws" + "log" + "os" +) + +type awslogger struct { + logger *log.Logger +} + +func AwsLogger() aws.Logger { + return &awslogger{ + logger: log.New(os.Stderr, "", log.LstdFlags), + } +} + +func (l awslogger) Log(args ...interface{}) { + l.logger.Println(args...) +} diff --git a/drivers/amazonec2/region.go b/drivers/amazonec2/region.go new file mode 100644 index 0000000000..ae990d67ea --- /dev/null +++ b/drivers/amazonec2/region.go @@ -0,0 +1,54 @@ +package amazonec2 + +import ( + "errors" +) + +type region struct { + AmiId string +} + +// Ubuntu 16.04 LTS 20180228.1 hvm:ebs-ssd (amd64) +// See https://cloud-images.ubuntu.com/locator/ec2/ +var regionDetails map[string]*region = map[string]*region{ + "ap-northeast-1": {"ami-bcb7f6da"}, + "ap-northeast-2": {"ami-5073de3e"}, + "ap-southeast-1": {"ami-41e4af3d"}, + "ap-southeast-2": {"ami-c1498fa3"}, + "ap-south-1": {"ami-1083dc7f"}, + "ca-central-1": {"ami-8d9e19e9"}, + "cn-north-1": {"ami-cc4499a1"}, // Note: this is 20180126 + "cn-northwest-1": {"ami-fd0e1a9f"}, // Note: this is 20180126 + "eu-north-1": {"ami-017ff17f"}, + "eu-central-1": {"ami-bc4925d3"}, + "eu-west-1": {"ami-0b541372"}, + "eu-west-2": {"ami-ff46a298"}, + "eu-west-3": {"ami-9465d3e9"}, + "sa-east-1": {"ami-b5501bd9"}, + "us-east-1": {"ami-927185ef"}, + "us-east-2": {"ami-b9daeddc"}, + "us-west-1": {"ami-264c4646"}, + "us-west-2": {"ami-78a22900"}, + "us-gov-west-1": {"ami-2561ea44"}, + "custom-endpoint": {""}, +} + +func awsRegionsList() []string { + var list []string + + for k := range regionDetails { + list = append(list, k) + } + + return list +} + +func validateAwsRegion(region string) (string, error) { + for _, v := range awsRegionsList() { + if v == region { + return region, nil + } + } + + return "", errors.New("Invalid region specified") +} diff --git a/drivers/amazonec2/stub_test.go b/drivers/amazonec2/stub_test.go new file mode 100644 index 0000000000..6dd638604a --- /dev/null +++ b/drivers/amazonec2/stub_test.go @@ -0,0 +1,149 @@ +package amazonec2 + +import ( + "errors" + + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/service/ec2" + + "github.com/stretchr/testify/mock" +) + +type fakeEC2 struct { + *ec2.EC2 +} + +type errorProvider struct{} + +func (p *errorProvider) Retrieve() (credentials.Value, error) { + return credentials.Value{}, errors.New("bad credentials") +} + +func (p *errorProvider) IsExpired() bool { + return true +} + +type okProvider struct { + accessKeyID string + secretAccessKey string + sessionToken string +} + +func (p *okProvider) Retrieve() (credentials.Value, error) { + return credentials.Value{ + AccessKeyID: p.accessKeyID, + SecretAccessKey: p.secretAccessKey, + SessionToken: p.sessionToken, + }, nil +} + +func (p *okProvider) IsExpired() bool { + return true +} + +type fallbackCredentials struct{} + +func (c *fallbackCredentials) Credentials() *credentials.Credentials { + return credentials.NewStaticCredentials("fallback_access", "fallback_secret", "fallback_token") +} + +func NewValidAwsCredentials() awsCredentials { + return &fallbackCredentials{} +} + +type errorFallbackCredentials struct{} + +func (c *errorFallbackCredentials) Credentials() *credentials.Credentials { + return credentials.NewCredentials(&errorProvider{}) +} + +func NewErrorAwsCredentials() awsCredentials { + return &errorFallbackCredentials{} +} + +type errorCredentialsProvider struct{} + +func (c *errorCredentialsProvider) NewStaticProvider(id, secret, token string) credentials.Provider { + return &errorProvider{} +} + +type fakeEC2WithDescribe struct { + *fakeEC2 + output *ec2.DescribeAccountAttributesOutput + err error +} + +func (f *fakeEC2WithDescribe) DescribeAccountAttributes(input *ec2.DescribeAccountAttributesInput) (*ec2.DescribeAccountAttributesOutput, error) { + return f.output, f.err +} + +type fakeEC2WithLogin struct { + *fakeEC2 +} + +func (f *fakeEC2WithLogin) DescribeAccountAttributes(input *ec2.DescribeAccountAttributesInput) (*ec2.DescribeAccountAttributesOutput, error) { + defaultVpc := "default-vpc" + vpcName := "vpc-9999" + + return &ec2.DescribeAccountAttributesOutput{ + AccountAttributes: []*ec2.AccountAttribute{ + { + AttributeName: &defaultVpc, + AttributeValues: []*ec2.AccountAttributeValue{ + {AttributeValue: &vpcName}, + }, + }, + }, + }, nil +} + +type fakeEC2SecurityGroupTestRecorder struct { + *fakeEC2 + mock.Mock +} + +func (f *fakeEC2SecurityGroupTestRecorder) DescribeSecurityGroups(input *ec2.DescribeSecurityGroupsInput) (*ec2.DescribeSecurityGroupsOutput, error) { + result := f.Called(input) + err := result.Error(1) + value, ok := result.Get(0).(*ec2.DescribeSecurityGroupsOutput) + if !ok && err == nil { + return nil, errors.New("Type assertion to DescribeSecurityGroupsOutput failed") + } + return value, err +} + +func (f *fakeEC2SecurityGroupTestRecorder) CreateSecurityGroup(input *ec2.CreateSecurityGroupInput) (*ec2.CreateSecurityGroupOutput, error) { + result := f.Called(input) + err := result.Error(1) + value, ok := result.Get(0).(*ec2.CreateSecurityGroupOutput) + if !ok && err == nil { + return nil, errors.New("Type assertion to CreateSecurityGroupOutput failed") + } + return value, err +} + +func (f *fakeEC2SecurityGroupTestRecorder) AuthorizeSecurityGroupIngress(input *ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) { + result := f.Called(input) + err := result.Error(1) + value, ok := result.Get(0).(*ec2.AuthorizeSecurityGroupIngressOutput) + if !ok && err == nil { + return nil, errors.New("Type assertion to AuthorizeSecurityGroupIngressInput failed") + } + return value, err +} + +func NewTestDriver() *Driver { + driver := NewDriver("machineFoo", "path") + driver.clientFactory = func() Ec2Client { + return &fakeEC2{} + } + return driver +} + +func NewCustomTestDriver(ec2Client Ec2Client) *Driver { + driver := NewDriver("machineFoo", "path") + driver.clientFactory = func() Ec2Client { + return ec2Client + } + return driver +} diff --git a/drivers/amazonec2/utils.go b/drivers/amazonec2/utils.go deleted file mode 100644 index 153f64e773..0000000000 --- a/drivers/amazonec2/utils.go +++ /dev/null @@ -1,51 +0,0 @@ -package amazonec2 - -import ( - "errors" -) - -var ( - errInvalidRegion = errors.New("invalid region specified") - errNoVpcs = errors.New("No VPCs found in region") - errMachineFailure = errors.New("Machine failed to start") - errNoIP = errors.New("No IP Address associated with the instance") - errComplete = errors.New("Complete") -) - -type region struct { - AmiId string -} - -var regionDetails map[string]*region = map[string]*region{ - "ap-northeast-1": {"ami-44f1e245"}, - "ap-southeast-1": {"ami-f95875ab"}, - "ap-southeast-2": {"ami-890b62b3"}, - "cn-north-1": {"ami-fe7ae8c7"}, - "eu-west-1": {"ami-823686f5"}, - "eu-central-1": {"ami-ac1524b1"}, - "sa-east-1": {"ami-c770c1da"}, - "us-east-1": {"ami-4ae27e22"}, - "us-west-1": {"ami-d1180894"}, - "us-west-2": {"ami-898dd9b9"}, - "us-gov-west-1": {"ami-cf5630ec"}, -} - -func awsRegionsList() []string { - var list []string - - for k := range regionDetails { - list = append(list, k) - } - - return list -} - -func validateAwsRegion(region string) (string, error) { - for _, v := range awsRegionsList() { - if v == region { - return region, nil - } - } - - return "", errInvalidRegion -} diff --git a/drivers/azure/azure.go b/drivers/azure/azure.go index 0ca84839d1..f37a8fcafc 100644 --- a/drivers/azure/azure.go +++ b/drivers/azure/azure.go @@ -1,593 +1,566 @@ package azure import ( + "encoding/base64" + "errors" "fmt" + "io/ioutil" "net" + "net/url" "os" - "os/exec" - "path/filepath" - "strings" - "time" - - azure "github.com/MSOpenTech/azure-sdk-for-go" - "github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient" - - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/docker/utils" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" + + "github.com/docker/machine/drivers/azure/azureutil" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" + + "github.com/Azure/azure-sdk-for-go/arm/storage" ) const ( - dockerConfigDir = "/etc/docker" + defaultAzureEnvironment = "AzurePublicCloud" + defaultAzureResourceGroup = "docker-machine" + defaultAzureSize = "Standard_A2" + defaultAzureLocation = "westus" + defaultSSHUser = "docker-user" // 'root' not allowed on Azure + defaultDockerPort = 2376 + defaultAzureImage = "canonical:UbuntuServer:16.04.0-LTS:latest" + defaultAzureVNet = "docker-machine-vnet" + defaultAzureSubnet = "docker-machine" + defaultAzureSubnetPrefix = "192.168.0.0/16" + defaultStorageType = string(storage.StandardLRS) + defaultAzureAvailabilitySet = "docker-machine" ) -type Driver struct { - MachineName string - SubscriptionID string - SubscriptionCert string - PublishSettingsFilePath string - Location string - Size string - UserName string - UserPassword string - Image string - SSHPort int - DockerPort int - CaCertPath string - PrivateKeyPath string - storePath string -} +const ( + flAzureEnvironment = "azure-environment" + flAzureSubscriptionID = "azure-subscription-id" + flAzureResourceGroup = "azure-resource-group" + flAzureSSHUser = "azure-ssh-user" + flAzureDockerPort = "azure-docker-port" + flAzureLocation = "azure-location" + flAzureSize = "azure-size" + flAzureImage = "azure-image" + flAzureVNet = "azure-vnet" + flAzureSubnet = "azure-subnet" + flAzureSubnetPrefix = "azure-subnet-prefix" + flAzureAvailabilitySet = "azure-availability-set" + flAzurePorts = "azure-open-port" + flAzurePrivateIPAddr = "azure-private-ip-address" + flAzureUsePrivateIP = "azure-use-private-ip" + flAzureStaticPublicIP = "azure-static-public-ip" + flAzureNoPublicIP = "azure-no-public-ip" + flAzureDNSLabel = "azure-dns" + flAzureStorageType = "azure-storage-type" + flAzureCustomData = "azure-custom-data" + flAzureClientID = "azure-client-id" + flAzureClientSecret = "azure-client-secret" +) + +const ( + driverName = "azure" + sshPort = 22 +) -func init() { - drivers.Register("azure", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) +// Driver represents Azure Docker Machine Driver. +type Driver struct { + *drivers.BaseDriver + + ClientID string // service principal account name + ClientSecret string // service principal account password + + Environment string + SubscriptionID string + ResourceGroup string + + DockerPort int + Location string + Size string + Image string + VirtualNetwork string + SubnetName string + SubnetPrefix string + AvailabilitySet string + StorageType string + + OpenPorts []string + PrivateIPAddr string + UsePrivateIP bool + NoPublicIP bool + DNSLabel string + StaticPublicIP bool + CustomDataFile string + + // Ephemeral fields + ctx *azureutil.DeploymentContext + resolvedIP string // cache +} + +// NewDriver returns a new driver instance. +func NewDriver(hostName, storePath string) drivers.Driver { + // NOTE(ahmetalpbalkan): any driver initialization I do here gets lost + // afterwards, especially for non-Create RPC calls. Therefore I am mostly + // making rest of the driver stateless by just relying on the following + // piece of info. + d := &Driver{ + BaseDriver: &drivers.BaseDriver{ + SSHUser: defaultSSHUser, + MachineName: hostName, + StorePath: storePath, + }, + } + return d } -// GetCreateFlags registers the flags this driver adds to -// "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.IntFlag{ - Name: "azure-docker-port", - Usage: "Azure Docker port", - Value: 2376, +// GetCreateFlags returns list of create flags driver accepts. +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ + Name: flAzureEnvironment, + Usage: "Azure environment (e.g. AzurePublicCloud, AzureChinaCloud)", + EnvVar: "AZURE_ENVIRONMENT", + Value: defaultAzureEnvironment, }, - cli.StringFlag{ - EnvVar: "AZURE_IMAGE", - Name: "azure-image", - Usage: "Azure image name. Default is Ubuntu 14.04 LTS x64", + mcnflag.StringFlag{ + Name: flAzureSubscriptionID, + Usage: "Azure Subscription ID", + EnvVar: "AZURE_SUBSCRIPTION_ID", }, - cli.StringFlag{ - EnvVar: "AZURE_LOCATION", - Name: "azure-location", - Usage: "Azure location", - Value: "West US", + mcnflag.StringFlag{ + Name: flAzureResourceGroup, + Usage: "Azure Resource Group name (will be created if missing)", + EnvVar: "AZURE_RESOURCE_GROUP", + Value: defaultAzureResourceGroup, + }, + mcnflag.StringFlag{ + Name: flAzureSSHUser, + Usage: "Username for SSH login", + EnvVar: "AZURE_SSH_USER", + Value: defaultSSHUser, }, - cli.StringFlag{ - Name: "azure-password", - Usage: "Azure user password", + mcnflag.IntFlag{ + Name: flAzureDockerPort, + Usage: "Port number for Docker engine", + EnvVar: "AZURE_DOCKER_PORT", + Value: defaultDockerPort, }, - cli.StringFlag{ - EnvVar: "AZURE_PUBLISH_SETTINGS_FILE", - Name: "azure-publish-settings-file", - Usage: "Azure publish settings file", + mcnflag.StringFlag{ + Name: flAzureLocation, + Usage: "Azure region to create the virtual machine", + EnvVar: "AZURE_LOCATION", + Value: defaultAzureLocation, }, - cli.StringFlag{ + mcnflag.StringFlag{ + Name: flAzureSize, + Usage: "Size for Azure Virtual Machine", EnvVar: "AZURE_SIZE", - Name: "azure-size", - Usage: "Azure size", - Value: "Small", + Value: defaultAzureSize, }, - cli.IntFlag{ - Name: "azure-ssh-port", - Usage: "Azure SSH port", - Value: 22, + mcnflag.StringFlag{ + Name: flAzureImage, + Usage: "Azure virtual machine OS image", + EnvVar: "AZURE_IMAGE", + Value: defaultAzureImage, }, - - cli.StringFlag{ - EnvVar: "AZURE_SUBSCRIPTION_CERT", - Name: "azure-subscription-cert", - Usage: "Azure subscription cert", + mcnflag.StringFlag{ + Name: flAzureVNet, + Usage: "Azure Virtual Network name to connect the virtual machine (in [resourcegroup:]name format)", + EnvVar: "AZURE_VNET", + Value: defaultAzureVNet, }, - cli.StringFlag{ - EnvVar: "AZURE_SUBSCRIPTION_ID", - Name: "azure-subscription-id", - Usage: "Azure subscription ID", + mcnflag.StringFlag{ + Name: flAzureSubnet, + Usage: "Azure Subnet Name to be used within the Virtual Network", + EnvVar: "AZURE_SUBNET", + Value: defaultAzureSubnet, + }, + mcnflag.StringFlag{ + Name: flAzureSubnetPrefix, + Usage: "Private CIDR block to be used for the new subnet, should comply RFC 1918", + EnvVar: "AZURE_SUBNET_PREFIX", + Value: defaultAzureSubnetPrefix, + }, + mcnflag.StringFlag{ + Name: flAzureAvailabilitySet, + Usage: "Azure Availability Set to place the virtual machine into", + EnvVar: "AZURE_AVAILABILITY_SET", + Value: defaultAzureAvailabilitySet, + }, + mcnflag.StringFlag{ + Name: flAzureCustomData, + EnvVar: "AZURE_CUSTOM_DATA_FILE", + Usage: "Path to file with custom-data", + }, + mcnflag.StringFlag{ + Name: flAzurePrivateIPAddr, + Usage: "Specify a static private IP address for the machine", + }, + mcnflag.StringFlag{ + Name: flAzureStorageType, + Usage: "Type of Storage Account to host the OS Disk for the machine", + EnvVar: "AZURE_STORAGE_TYPE", + Value: defaultStorageType, + }, + mcnflag.BoolFlag{ + Name: flAzureUsePrivateIP, + Usage: "Use private IP address of the machine to connect", + }, + mcnflag.BoolFlag{ + Name: flAzureNoPublicIP, + Usage: "Do not create a public IP address for the machine", }, - cli.StringFlag{ - Name: "azure-username", - Usage: "Azure username", - Value: "ubuntu", + mcnflag.BoolFlag{ + Name: flAzureStaticPublicIP, + Usage: "Assign a static public IP address to the machine", + }, + mcnflag.StringFlag{ + Name: flAzureDNSLabel, + Usage: "A unique DNS label for the public IP adddress", + EnvVar: "AZURE_DNS_LABEL", + }, + mcnflag.StringSliceFlag{ + Name: flAzurePorts, + Usage: "Make the specified port number accessible from the Internet", + }, + mcnflag.StringFlag{ + Name: flAzureClientID, + Usage: "Azure Service Principal Account ID (optional, browser auth is used if not specified)", + EnvVar: "AZURE_CLIENT_ID", + }, + mcnflag.StringFlag{ + Name: flAzureClientSecret, + Usage: "Azure Service Principal Account password (optional, browser auth is used if not specified)", + EnvVar: "AZURE_CLIENT_SECRET", }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - driver := &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey} - return driver, nil -} - -func (driver *Driver) DriverName() string { - return "azure" -} - -func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.SubscriptionID = flags.String("azure-subscription-id") - - cert := flags.String("azure-subscription-cert") - publishSettings := flags.String("azure-publish-settings-file") - image := flags.String("azure-image") - username := flags.String("azure-username") - - if cert != "" { - if _, err := os.Stat(cert); os.IsNotExist(err) { - return err - } - driver.SubscriptionCert = cert - } - - if publishSettings != "" { - if _, err := os.Stat(publishSettings); os.IsNotExist(err) { - return err +// SetConfigFromFlags initializes driver values from the command line values +// and checks if the arguments have values. +func (d *Driver) SetConfigFromFlags(fl drivers.DriverOptions) error { + // Initialize driver context for machine + d.ctx = &azureutil.DeploymentContext{} + + // Required string flags + flags := []struct { + target *string + flag string + }{ + {&d.BaseDriver.SSHUser, flAzureSSHUser}, + {&d.SubscriptionID, flAzureSubscriptionID}, + {&d.ResourceGroup, flAzureResourceGroup}, + {&d.Location, flAzureLocation}, + {&d.Size, flAzureSize}, + {&d.Image, flAzureImage}, + {&d.VirtualNetwork, flAzureVNet}, + {&d.SubnetName, flAzureSubnet}, + {&d.SubnetPrefix, flAzureSubnetPrefix}, + {&d.AvailabilitySet, flAzureAvailabilitySet}, + {&d.StorageType, flAzureStorageType}, + } + for _, f := range flags { + *f.target = fl.String(f.flag) + if *f.target == "" { + return requiredOptionError(f.flag) } - driver.PublishSettingsFilePath = publishSettings } - if (driver.SubscriptionID == "" || driver.SubscriptionCert == "") && driver.PublishSettingsFilePath == "" { - return fmt.Errorf("Please specify azure subscription params using options: --azure-subscription-id and --azure-subscription-cert or --azure-publish-settings-file") - } + // Optional flags or Flags of other types + d.Environment = fl.String(flAzureEnvironment) + d.OpenPorts = fl.StringSlice(flAzurePorts) + d.PrivateIPAddr = fl.String(flAzurePrivateIPAddr) + d.UsePrivateIP = fl.Bool(flAzureUsePrivateIP) + d.NoPublicIP = fl.Bool(flAzureNoPublicIP) + d.StaticPublicIP = fl.Bool(flAzureStaticPublicIP) + d.DockerPort = fl.Int(flAzureDockerPort) + d.DNSLabel = fl.String(flAzureDNSLabel) + d.CustomDataFile = fl.String(flAzureCustomData) - if image == "" { - driver.Image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB" - } else { - driver.Image = image - } - - driver.Location = flags.String("azure-location") - driver.Size = flags.String("azure-size") + d.ClientID = fl.String(flAzureClientID) + d.ClientSecret = fl.String(flAzureClientSecret) - if strings.ToLower(username) == "docker" { - return fmt.Errorf("'docker' is not valid user name for docker host. Please specify another user name") - } - - driver.UserName = username - driver.UserPassword = flags.String("azure-password") - driver.DockerPort = flags.Int("azure-docker-port") - driver.SSHPort = flags.Int("azure-ssh-port") + // Set flags on the BaseDriver + d.BaseDriver.SSHPort = sshPort + d.SetSwarmConfigFromFlags(fl) + log.Debug("Set configuration from flags.") return nil } -func (driver *Driver) PreCreateCheck() error { - if err := driver.setUserSubscription(); err != nil { - return err - } +// DriverName returns the name of the driver. +func (d *Driver) DriverName() string { return driverName } - // check azure DNS to make sure name is available - available, response, err := vmClient.CheckHostedServiceNameAvailability(driver.MachineName) - if err != nil { - return err - } - - if !available { - return fmt.Errorf(response) - } - - return nil -} - -func (driver *Driver) Create() error { - if err := driver.setUserSubscription(); err != nil { - return err +// PreCreateCheck validates if driver values are valid to create the machine. +func (d *Driver) PreCreateCheck() (err error) { + if d.CustomDataFile != "" { + if _, err := os.Stat(d.CustomDataFile); os.IsNotExist(err) { + return fmt.Errorf("custom-data file %s could not be found", d.CustomDataFile) + } } - log.Info("Creating Azure machine...") - vmConfig, err := vmClient.CreateAzureVMConfiguration(driver.MachineName, driver.Size, driver.Image, driver.Location) + c, err := d.newAzureClient() if err != nil { return err } - log.Debug("Generating certificate for Azure...") - if err := driver.generateCertForAzure(); err != nil { + // Register used resource providers with current Azure subscription. + if err := c.RegisterResourceProviders( + "Microsoft.Compute", + "Microsoft.Network", + "Microsoft.Storage"); err != nil { return err } - log.Debug("Adding Linux provisioning...") - vmConfig, err = vmClient.AddAzureLinuxProvisioningConfig(vmConfig, driver.UserName, driver.UserPassword, driver.azureCertPath(), driver.SSHPort) + // Validate if firewall rules can be read correctly + d.ctx.FirewallRules, err = d.getSecurityRules(d.OpenPorts) if err != nil { return err } - log.Debug("Authorizing ports...") - if err := driver.addDockerEndpoint(vmConfig); err != nil { - return err - } - - log.Debug("Creating VM...") - if err := vmClient.CreateAzureVM(vmConfig, driver.MachineName, driver.Location); err != nil { - return err - } - - log.Info("Waiting for SSH...") - log.Debugf("Host: %s SSH Port: %d", driver.getHostname(), driver.SSHPort) - - if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", driver.getHostname(), driver.SSHPort)); err != nil { - return err - } - - cmd, err := driver.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl -sL https://get.docker.com | sh -; fi") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { + // Check if virtual machine exists. An existing virtual machine cannot be updated. + log.Debug("Checking if Virtual Machine already exists.") + if exists, err := c.VirtualMachineExists(d.ResourceGroup, d.naming().VM()); err != nil { return err + } else if exists { + return fmt.Errorf("Virtual Machine with name %s already exists in resource group %q", d.naming().VM(), d.ResourceGroup) } + // NOTE(ahmetalpbalkan) we could have done more checks here but Azure often + // returns meaningful error messages and it would be repeating the backend + // logic on the client side. Some examples: + // - Deployment of a machine to an existing Virtual Network fails if + // virtual network is in a different region. + // - Changing IP Address space of a subnet would fail if there are machines + // running in the Virtual Network. + log.Info("Completed machine pre-create checks.") return nil } -func (driver *Driver) runSSHCommand(command string, retries int) error { - cmd, err := driver.GetSSHCommand(command) +// Create creates the virtual machine. +func (d *Driver) Create() error { + // NOTE(ahmetalpbalkan): We can probably parallelize the sh*t out of this. + // However that would lead to a concurrency logic and while creation of a + // resource fails, other ones would be kicked off, which could lead to a + // resource leak. This is slower but safer. + c, err := d.newAzureClient() if err != nil { return err } - if err := cmd.Run(); err != nil { - if err.Error() == "exit status 255" { - if retries == 0 { - return err - } - return driver.runSSHCommand(command, retries-1) - } - - return err - } - - return nil -} - -func (driver *Driver) GetURL() (string, error) { - url := fmt.Sprintf("tcp://%s:%v", driver.getHostname(), driver.DockerPort) - return url, nil -} - -func (driver *Driver) GetIP() (string, error) { - return driver.getHostname(), nil -} - -func (driver *Driver) GetState() (state.State, error) { - err := driver.setUserSubscription() - if err != nil { - return state.Error, err - } - dockerVM, err := vmClient.GetVMDeployment(driver.MachineName, driver.MachineName) - if err != nil { - if strings.Contains(err.Error(), "Code: ResourceNotFound") { - return state.Error, fmt.Errorf("Azure host was not found. Please check your Azure subscription.") + var customData string + if d.CustomDataFile != "" { + buf, err := ioutil.ReadFile(d.CustomDataFile) + if err != nil { + return err } - - return state.Error, err + customData = base64.StdEncoding.EncodeToString(buf) } - vmState := dockerVM.RoleInstanceList.RoleInstance[0].PowerState - switch vmState { - case "Started": - return state.Running, nil - case "Starting": - return state.Starting, nil - case "Stopped": - return state.Stopped, nil - } - - return state.None, nil -} - -func (driver *Driver) Start() error { - err := driver.setUserSubscription() - if err != nil { + if err := c.CreateResourceGroup(d.ResourceGroup, d.Location); err != nil { return err } - - vmState, err := driver.GetState() - if err != nil { + if err := c.CreateAvailabilitySetIfNotExists(d.ctx, d.ResourceGroup, d.AvailabilitySet, d.Location); err != nil { return err } - if vmState == state.Running || vmState == state.Starting { - log.Infof("Host is already running or starting") - return nil - } - - log.Debugf("starting %s", driver.MachineName) - - err = vmClient.StartRole(driver.MachineName, driver.MachineName, driver.MachineName) - if err != nil { + if err := c.CreateNetworkSecurityGroup(d.ctx, d.ResourceGroup, d.naming().NSG(), d.Location, d.ctx.FirewallRules); err != nil { return err } - err = driver.waitForSSH() - if err != nil { + vnetResourceGroup, vNetName := parseVirtualNetwork(d.VirtualNetwork, d.ResourceGroup) + if err := c.CreateVirtualNetworkIfNotExists(vnetResourceGroup, vNetName, d.Location); err != nil { return err } - err = driver.waitForDocker() - if err != nil { + if err := c.CreateSubnet(d.ctx, vnetResourceGroup, vNetName, d.SubnetName, d.SubnetPrefix); err != nil { return err } - return nil -} - -func (driver *Driver) Stop() error { - err := driver.setUserSubscription() - if err != nil { - return err + if d.NoPublicIP { + log.Info("Not creating a public IP address.") + } else { + if err := c.CreatePublicIPAddress(d.ctx, d.ResourceGroup, d.naming().IP(), d.Location, d.StaticPublicIP, d.DNSLabel); err != nil { + return err + } } - vmState, err := driver.GetState() - if err != nil { + if err := c.CreateNetworkInterface(d.ctx, d.ResourceGroup, d.naming().NIC(), d.Location, + d.ctx.PublicIPAddressID, d.ctx.SubnetID, d.ctx.NetworkSecurityGroupID, d.PrivateIPAddr); err != nil { return err } - if vmState == state.Stopped { - log.Infof("Host is already stopped") - return nil + if err := c.CreateStorageAccount(d.ctx, d.ResourceGroup, d.Location, storage.SkuName(d.StorageType)); err != nil { + return err } - - log.Debugf("stopping %s", driver.MachineName) - - err = vmClient.ShutdownRole(driver.MachineName, driver.MachineName, driver.MachineName) - if err != nil { + if err := d.generateSSHKey(d.ctx); err != nil { return err } - return nil + err = c.CreateVirtualMachine(d.ResourceGroup, d.naming().VM(), d.Location, d.Size, d.ctx.AvailabilitySetID, + d.ctx.NetworkInterfaceID, d.BaseDriver.SSHUser, d.ctx.SSHPublicKey, d.Image, customData, d.ctx.StorageAccount) + return err } -func (driver *Driver) Remove() error { - err := driver.setUserSubscription() - if err != nil { +// Remove deletes the virtual machine and resources associated to it. +func (d *Driver) Remove() error { + if err := d.checkLegacyDriver(false); err != nil { return err } - available, _, err := vmClient.CheckHostedServiceNameAvailability(driver.MachineName) - if err != nil { - return err - } - if available { - return nil - } - log.Debugf("removing %s", driver.MachineName) + // NOTE(ahmetalpbalkan): + // - remove attempts are best effort and if a resource is already gone, we + // continue removing other resources instead of failing. + // - we can probably do a lot of parallelization here but a sequential + // logic works fine too. If we were to detach the NIC from the VM and + // then delete the VM, this could enable some parallelization. - err = vmClient.DeleteHostedService(driver.MachineName) + log.Info("NOTICE: Please check Azure portal/CLI to make sure you have no leftover resources to avoid unexpected charges.") + c, err := d.newAzureClient() if err != nil { return err } - - return nil -} - -func (driver *Driver) Restart() error { - err := driver.setUserSubscription() - if err != nil { + if err := c.DeleteVirtualMachineIfExists(d.ResourceGroup, d.naming().VM()); err != nil { return err } - vmState, err := driver.GetState() - if err != nil { + if err := c.DeleteNetworkInterfaceIfExists(d.ResourceGroup, d.naming().NIC()); err != nil { return err } - if vmState == state.Stopped { - return fmt.Errorf("Host is already stopped, use start command to run it") + if err := c.DeletePublicIPAddressIfExists(d.ResourceGroup, d.naming().IP()); err != nil { + return err } - - log.Debugf("restarting %s", driver.MachineName) - - err = vmClient.RestartRole(driver.MachineName, driver.MachineName, driver.MachineName) - if err != nil { + if err := c.DeleteNetworkSecurityGroupIfExists(d.ResourceGroup, d.naming().NSG()); err != nil { return err } - err = driver.waitForSSH() - if err != nil { + if err := c.CleanupAvailabilitySetIfExists(d.ResourceGroup, d.AvailabilitySet); err != nil { return err } - err = driver.waitForDocker() - if err != nil { + if err := c.CleanupSubnetIfExists(d.ResourceGroup, d.VirtualNetwork, d.SubnetName); err != nil { return err } - return nil + err = c.CleanupVirtualNetworkIfExists(d.ResourceGroup, d.VirtualNetwork) + return err } -func (driver *Driver) Kill() error { - err := driver.setUserSubscription() - if err != nil { - return err - } - vmState, err := driver.GetState() - if err != nil { - return err - } - if vmState == state.Stopped { - log.Infof("Host is already stopped") - return nil +// GetIP returns public IP address or hostname of the machine instance. +func (d *Driver) GetIP() (string, error) { + if err := d.checkLegacyDriver(true); err != nil { + return "", err } - log.Debugf("killing %s", driver.MachineName) - - err = vmClient.ShutdownRole(driver.MachineName, driver.MachineName, driver.MachineName) - if err != nil { - return err + if d.resolvedIP == "" { + ip, err := d.ipAddress() + if err != nil { + return "", err + } + d.resolvedIP = ip } - return nil + log.Debugf("Machine IP address resolved to: %s", d.resolvedIP) + return d.resolvedIP, nil } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil +// GetSSHHostname returns an IP address or hostname for the machine instance. +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") +// GetURL returns a socket address to connect to Docker engine of the machine +// instance. +func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } - cmd, err := d.GetSSHCommand("sudo service docker stop") + // NOTE (ahmetalpbalkan) I noticed that this is not used until machine is + // actually created and provisioned. By then GetIP() should be returning + // a non-empty IP address as the VM is already allocated and connected to. + ip, err := d.GetIP() if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err + return "", err } - - return nil + u := (&url.URL{ + Scheme: "tcp", + Host: net.JoinHostPort(ip, fmt.Sprintf("%d", d.DockerPort)), + }).String() + log.Debugf("Machine URL is resolved to: %s", u) + return u, nil } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (driver *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - err := driver.setUserSubscription() - if err != nil { - return nil, err +// GetState returns the state of the virtual machine role instance. +func (d *Driver) GetState() (state.State, error) { + if err := d.checkLegacyDriver(true); err != nil { + return state.None, err } - vmState, err := driver.GetState() + c, err := d.newAzureClient() if err != nil { - return nil, err + return state.None, err } - - if vmState == state.Stopped { - return nil, fmt.Errorf("Azure host is stopped. Please start it before using ssh command.") + powerState, err := c.GetVirtualMachinePowerState( + d.ResourceGroup, d.naming().VM()) + if err != nil { + return state.None, err } - return ssh.GetSSHCommand(driver.getHostname(), driver.SSHPort, driver.UserName, driver.sshKeyPath(), args...), nil + machineState := machineStateForVMPowerState(powerState) + log.Debugf("Determined Azure PowerState=%q, docker-machine state=%q", + powerState, machineState) + return machineState, nil } -func (driver *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := driver.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { +// Start issues a power on for the virtual machine instance. +func (d *Driver) Start() error { + if err := d.checkLegacyDriver(true); err != nil { return err - } - return cmd.Run() -} - -func generateVMName() string { - randomID := utils.TruncateID(utils.GenerateRandomID()) - return fmt.Sprintf("docker-host-%s", randomID) -} - -func (driver *Driver) setUserSubscription() error { - if len(driver.PublishSettingsFilePath) != 0 { - err := azure.ImportPublishSettingsFile(driver.PublishSettingsFilePath) - if err != nil { - return err - } - return nil - } - err := azure.ImportPublishSettings(driver.SubscriptionID, driver.SubscriptionCert) + c, err := d.newAzureClient() if err != nil { return err } - return nil + return c.StartVirtualMachine(d.ResourceGroup, d.naming().VM()) } -func (driver *Driver) addDockerEndpoint(vmConfig *vmClient.Role) error { - configSets := vmConfig.ConfigurationSets.ConfigurationSet - if len(configSets) == 0 { - return fmt.Errorf("no configuration set") - } - for i := 0; i < len(configSets); i++ { - if configSets[i].ConfigurationSetType != "NetworkConfiguration" { - continue - } - ep := vmClient.InputEndpoint{} - ep.Name = "docker" - ep.Protocol = "tcp" - ep.Port = driver.DockerPort - ep.LocalPort = driver.DockerPort - configSets[i].InputEndpoints.InputEndpoint = append(configSets[i].InputEndpoints.InputEndpoint, ep) - log.Debugf("added Docker endpoint (port %d) to configuration", driver.DockerPort) +// Stop issues a power off for the virtual machine instance. +func (d *Driver) Stop() error { + if err := d.checkLegacyDriver(true); err != nil { + return err } - return nil -} -func (driver *Driver) waitForSSH() error { - log.Infof("Waiting for SSH...") - err := ssh.WaitForTCP(fmt.Sprintf("%s:%v", driver.getHostname(), driver.SSHPort)) + c, err := d.newAzureClient() if err != nil { return err } - - return nil -} - -func (driver *Driver) waitForDocker() error { - log.Infof("Waiting for docker daemon on host to be available...") - maxRepeats := 48 - url := fmt.Sprintf("%s:%v", driver.getHostname(), driver.DockerPort) - success := waitForDockerEndpoint(url, maxRepeats) - if !success { - return fmt.Errorf("Can not run docker daemon on remote machine. Please try again.") - } - return nil -} - -func waitForDockerEndpoint(url string, maxRepeats int) bool { - counter := 0 - for { - conn, err := net.Dial("tcp", url) - if err != nil { - time.Sleep(10 * time.Second) - counter++ - if counter == maxRepeats { - return false - } - continue - } - defer conn.Close() - break - } - return true + log.Info("NOTICE: Stopping an Azure Virtual Machine is just going to power it off, not deallocate.") + log.Info("NOTICE: You should remove the machine if you would like to avoid unexpected costs.") + return c.StopVirtualMachine(d.ResourceGroup, d.naming().VM()) } -func (driver *Driver) generateCertForAzure() error { - if err := ssh.GenerateSSHKey(driver.sshKeyPath()); err != nil { +// Restart reboots the virtual machine instance. +func (d *Driver) Restart() error { + if err := d.checkLegacyDriver(true); err != nil { return err } - cmd := exec.Command("openssl", "req", "-x509", "-key", driver.sshKeyPath(), "-nodes", "-days", "365", "-newkey", "rsa:2048", "-out", driver.azureCertPath(), "-subj", "/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=\\*") - if err := cmd.Run(); err != nil { + // NOTE(ahmetalpbalkan) Azure will always keep the VM in Running state + // during the restart operation. Hence we rely on returned async operation + // polling to make sure the reboot is waited upon. + c, err := d.newAzureClient() + if err != nil { return err } - - return nil + return c.RestartVirtualMachine(d.ResourceGroup, d.naming().VM()) } -func (driver *Driver) sshKeyPath() string { - return filepath.Join(driver.storePath, "id_rsa") +// Kill stops the virtual machine role instance. +func (d *Driver) Kill() error { + // NOTE(ahmetalpbalkan) In Azure, there is no kill option for virtual + // machines, Stop() is the closest option. + log.Debug("Azure does not implement kill. Calling Stop instead.") + return d.Stop() } -func (driver *Driver) publicSSHKeyPath() string { - return driver.sshKeyPath() + ".pub" -} - -func (driver *Driver) azureCertPath() string { - return filepath.Join(driver.storePath, "azure_cert.pem") -} - -func (driver *Driver) getHostname() string { - return driver.MachineName + ".cloudapp.net" +// checkLegacyDriver errors out if it encounters an Azure VM created with the +// legacy (<=0.6.0) docker-machine Azure driver. +func (d *Driver) checkLegacyDriver(short bool) error { + if d.ResourceGroup == "" { + if short { + return errors.New("new azure driver cannot manage old VMs, downgrade to v0.6.0") + } + return errors.New("new azure driver uses the new Azure Resource Manager APIs and therefore cannot manage this existing machine created with old azure driver. Please downgrade to docker-machine 0.6.0 to continue using these machines or to remove them") + } + return nil } diff --git a/drivers/azure/azureutil/auth.go b/drivers/azure/azureutil/auth.go new file mode 100644 index 0000000000..2e0abb8f37 --- /dev/null +++ b/drivers/azure/azureutil/auth.go @@ -0,0 +1,246 @@ +package azureutil + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/to" + "github.com/docker/machine/drivers/azure/logutil" +) + +// Azure driver allows two authentication methods: +// +// 1. OAuth Device Flow +// +// Azure Active Directory implements OAuth 2.0 Device Flow described here: +// https://tools.ietf.org/html/draft-denniss-oauth-device-flow-00. It is simple +// for users to authenticate through a browser and requires re-authenticating +// every 2 weeks. +// +// Device auth prints a message to the screen telling the user to click on URL +// and approve the app on the browser, meanwhile the client polls the auth API +// for a token. Once we have token, we save it locally to a file with proper +// permissions and when the token expires (in Azure case typically 1 hour) SDK +// will automatically refresh the specified token and will call the refresh +// callback function we implement here. This way we will always be storing a +// token with a refresh_token saved on the machine. +// +// 2. Azure Service Principal Account +// +// This is designed for headless authentication to Azure APIs but requires more +// steps from user to create a Service Principal Account and provide its +// credentials to the machine driver. + +var ( + // AD app id for docker-machine driver in various Azure realms + appIDs = map[string]string{ + azure.PublicCloud.Name: "637ddaba-219b-43b8-bf19-8cea500cf273", + azure.ChinaCloud.Name: "bb5eed6f-120b-4365-8fd9-ab1a3fba5698", + azure.GermanCloud.Name: "aabac5f7-dd47-47ef-824c-e0d57598cada", + } +) + +// AuthenticateDeviceFlow fetches a token from the local file cache or initiates a consent +// flow and waits for token to be obtained. Obtained token is stored in a file cache for +// future use and refreshing. +func AuthenticateDeviceFlow(env azure.Environment, subscriptionID string) (*azure.ServicePrincipalToken, error) { + // First we locate the tenant ID of the subscription as we store tokens per + // tenant (which could have multiple subscriptions) + tenantID, err := loadOrFindTenantID(env, subscriptionID) + if err != nil { + return nil, err + } + oauthCfg, err := env.OAuthConfigForTenant(tenantID) + if err != nil { + return nil, fmt.Errorf("Failed to obtain oauth config for azure environment: %v", err) + } + + tokenPath := tokenCachePath(tenantID) + saveToken := mkTokenCallback(tokenPath) + saveTokenCallback := func(t azure.Token) error { + log.Debug("Azure token expired. Saving the refreshed token...") + return saveToken(t) + } + f := logutil.Fields{"path": tokenPath} + + appID, ok := appIDs[env.Name] + if !ok { + return nil, fmt.Errorf("docker-machine application not set up for Azure environment %q", env.Name) + } + scope := getScope(env) + + // Lookup the token cache file for an existing token. + spt, err := tokenFromFile(*oauthCfg, tokenPath, appID, scope, saveTokenCallback) + if err != nil { + return nil, err + } + if spt != nil { + log.Debug("Auth token found in file.", f) + + // NOTE(ahmetalpbalkan): The token file we found might be containing an + // expired access_token. In that case, the first call to Azure SDK will + // attempt to refresh the token using refresh_token –which might have + // expired[1], in that case we will get an error and we shall remove the + // token file and initiate token flow again so that the user would not + // need removing the token cache file manually. + // + // [1]: for device flow auth, the expiration date of refresh_token is + // not returned in AAD /token response, we just know it is 14 + // days. Therefore user’s token will go stale every 14 days and we + // will delete the token file, re-initiate the device flow. Service + // Principal Account tokens are not subject to this limitation. + log.Debug("Validating the token.") + if err := validateToken(env, spt); err != nil { + log.Debug(fmt.Sprintf("Error: %v", err)) + log.Debug(fmt.Sprintf("Deleting %s", tokenPath)) + if err := os.RemoveAll(tokenPath); err != nil { + return nil, fmt.Errorf("Error deleting stale token file: %v", err) + } + } else { + log.Debug("Token works.") + return spt, nil + } + } + + log.Debug("Obtaining a token.", f) + spt, err = deviceFlowAuth(*oauthCfg, appID, scope) + if err != nil { + return nil, err + } + log.Debug("Obtained a token.") + if err := saveToken(spt.Token); err != nil { + log.Error("Error occurred saving token to cache file.") + return nil, err + } + return spt, nil +} + +// AuthenticateServicePrincipal uses given service principal credentials to return a +// service principal token. Generated token is not stored in a cache file or refreshed. +func AuthenticateServicePrincipal(env azure.Environment, subscriptionID, spID, spPassword string) (*azure.ServicePrincipalToken, error) { + tenantID, err := loadOrFindTenantID(env, subscriptionID) + if err != nil { + return nil, err + } + oauthCfg, err := env.OAuthConfigForTenant(tenantID) + if err != nil { + return nil, fmt.Errorf("Failed to obtain oauth config for azure environment: %v", err) + } + + spt, err := azure.NewServicePrincipalToken(*oauthCfg, spID, spPassword, getScope(env)) + if err != nil { + return nil, fmt.Errorf("Failed to create service principal token: %+v", err) + } + return spt, nil +} + +// tokenFromFile returns a token from the specified file if it is found, otherwise +// returns nil. Any error retrieving or creating the token is returned as an error. +func tokenFromFile(oauthCfg azure.OAuthConfig, tokenPath, clientID, resource string, + callback azure.TokenRefreshCallback) (*azure.ServicePrincipalToken, error) { + log.Debug("Loading auth token from file", logutil.Fields{"path": tokenPath}) + if _, err := os.Stat(tokenPath); err != nil { + if os.IsNotExist(err) { // file not found + return nil, nil + } + return nil, err + } + + token, err := azure.LoadToken(tokenPath) + if err != nil { + return nil, fmt.Errorf("Failed to load token from file: %v", err) + } + + spt, err := azure.NewServicePrincipalTokenFromManualToken(oauthCfg, clientID, resource, *token, callback) + if err != nil { + return nil, fmt.Errorf("Error constructing service principal token: %v", err) + } + return spt, nil +} + +// deviceFlowAuth prints a message to the screen for user to take action to +// consent application on a browser and in the meanwhile the authentication +// endpoint is polled until user gives consent, denies or the flow times out. +// Returned token must be saved. +func deviceFlowAuth(oauthCfg azure.OAuthConfig, clientID, resource string) (*azure.ServicePrincipalToken, error) { + cl := oauthClient() + deviceCode, err := azure.InitiateDeviceAuth(&cl, oauthCfg, clientID, resource) + if err != nil { + return nil, fmt.Errorf("Failed to start device auth: %v", err) + } + log.Debug("Retrieved device code.", logutil.Fields{ + "expires_in": to.Int64(deviceCode.ExpiresIn), + "interval": to.Int64(deviceCode.Interval), + }) + + // Example message: “To sign in, open https://aka.ms/devicelogin and enter + // the code 0000000 to authenticate.” + log.Infof("Microsoft Azure: %s", to.String(deviceCode.Message)) + + token, err := azure.WaitForUserCompletion(&cl, deviceCode) + if err != nil { + return nil, fmt.Errorf("Failed to complete device auth: %v", err) + } + + spt, err := azure.NewServicePrincipalTokenFromManualToken(oauthCfg, clientID, resource, *token) + if err != nil { + return nil, fmt.Errorf("Error constructing service principal token: %v", err) + } + return spt, nil +} + +// azureCredsPath returns the directory the azure credentials are stored in. +func azureCredsPath() string { + return filepath.Join(mcnutils.GetHomeDir(), ".docker", "machine", "credentials", "azure") +} + +// tokenCachePath returns the full path the OAuth 2.0 token should be saved at +// for given tenant ID. +func tokenCachePath(tenantID string) string { + return filepath.Join(azureCredsPath(), fmt.Sprintf("%s.json", tenantID)) +} + +// tenantIDPath returns the full path the tenant ID for the given subscription +// should be saved at.f +func tenantIDPath(subscriptionID string) string { + return filepath.Join(azureCredsPath(), fmt.Sprintf("%s.tenantid", subscriptionID)) +} + +// mkTokenCallback returns a callback function that can be used to save the +// token initially or register to the Azure SDK to be called when the token is +// refreshed. +func mkTokenCallback(path string) azure.TokenRefreshCallback { + return func(t azure.Token) error { + if err := azure.SaveToken(path, 0600, t); err != nil { + return err + } + log.Debug("Saved token to file.") + return nil + } +} + +// validateToken makes a call to Azure SDK with given token, essentially making +// sure if the access_token valid, if not it uses SDK’s functionality to +// automatically refresh the token using refresh_token (which might have +// expired). This check is essentially to make sure refresh_token is good. +func validateToken(env azure.Environment, token *azure.ServicePrincipalToken) error { + c := subscriptionsClient(env.ResourceManagerEndpoint) + c.Authorizer = token + _, err := c.List() + if err != nil { + return fmt.Errorf("Token validity check failed: %v", err) + } + return nil +} + +// getScope returns the API scope for authentication tokens. +func getScope(env azure.Environment) string { + // for AzurePublicCloud (https://management.core.windows.net/), this old + // Service Management scope covers both ASM and ARM. + return env.ServiceManagementEndpoint +} diff --git a/drivers/azure/azureutil/authorizer.go b/drivers/azure/azureutil/authorizer.go new file mode 100644 index 0000000000..8ea1a354eb --- /dev/null +++ b/drivers/azure/azureutil/authorizer.go @@ -0,0 +1,15 @@ +package azureutil + +import ( + "fmt" + + "github.com/Azure/go-autorest/autorest" +) + +// accessToken is interim autorest.Authorizer until we figure out oauth token +// handling. It holds the access token. +type accessToken string + +func (a accessToken) WithAuthorization() autorest.PrepareDecorator { + return autorest.WithHeader("Authorization", fmt.Sprintf("Bearer %s", string(a))) +} diff --git a/drivers/azure/azureutil/azureutil.go b/drivers/azure/azureutil/azureutil.go new file mode 100644 index 0000000000..84d84919a0 --- /dev/null +++ b/drivers/azure/azureutil/azureutil.go @@ -0,0 +1,807 @@ +package azureutil + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/docker/machine/drivers/azure/logutil" + "github.com/docker/machine/libmachine/log" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/Azure/azure-sdk-for-go/arm/resources/resources" + "github.com/Azure/azure-sdk-for-go/arm/storage" + blobstorage "github.com/Azure/azure-sdk-for-go/storage" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/to" +) + +const ( + storageAccountPrefix = "vhds" // do not contaminate to user's existing storage accounts + fmtOSDiskContainer = "vhd-%s" // place vhds of VMs in separate containers for ease of cleanup + fmtOSDiskBlobName = "%s-os-disk.vhd" + fmtOSDiskResourceName = "%s-os-disk" + defaultStorageAPIVersion = blobstorage.DefaultAPIVersion +) + +var ( + // Private IPv4 address space per RFC 1918. + defaultVnetAddressPrefixes = []string{ + "192.168.0.0/16", + "10.0.0.0/8", + "172.16.0.0/12"} + + // Polling interval for VM power state check. + powerStatePollingInterval = time.Second * 5 + waitStartTimeout = time.Minute * 10 + waitPowerOffTimeout = time.Minute * 5 +) + +type AzureClient struct { + env azure.Environment + subscriptionID string + auth autorest.Authorizer +} + +func New(env azure.Environment, subsID string, auth autorest.Authorizer) *AzureClient { + return &AzureClient{env, subsID, auth} +} + +// RegisterResourceProviders registers current subscription to the specified +// resource provider namespaces if they are not already registered. Namespaces +// are case-insensitive. +func (a AzureClient) RegisterResourceProviders(namespaces ...string) error { + l, err := a.providersClient().List(nil, "") + if err != nil { + return err + } + if l.Value == nil { + return errors.New("resource providers list is returned as nil") + } + + m := make(map[string]bool) + for _, p := range *l.Value { + m[strings.ToLower(to.String(p.Namespace))] = to.String(p.RegistrationState) == "Registered" + } + + for _, ns := range namespaces { + registered, ok := m[strings.ToLower(ns)] + if !ok { + return fmt.Errorf("unknown resource provider %q", ns) + } + if registered { + log.Debugf("Already registered for %q", ns) + } else { + log.Info("Registering subscription to resource provider.", logutil.Fields{ + "ns": ns, + "subs": a.subscriptionID, + }) + if _, err := a.providersClient().Register(ns); err != nil { + return err + } + } + } + return nil +} + +// CreateResourceGroup creates a Resource Group if not exists +func (a AzureClient) CreateResourceGroup(name, location string) error { + if ok, err := a.resourceGroupExists(name); err != nil { + return err + } else if ok { + log.Infof("Resource group %q already exists.", name) + return nil + } + + log.Info("Creating resource group.", logutil.Fields{ + "name": name, + "location": location}) + _, err := a.resourceGroupsClient().CreateOrUpdate(name, + resources.ResourceGroup{ + Location: to.StringPtr(location), + }) + return err +} + +func (a AzureClient) resourceGroupExists(name string) (bool, error) { + log.Info("Querying existing resource group.", logutil.Fields{"name": name}) + _, err := a.resourceGroupsClient().Get(name) + return checkResourceExistsFromError(err) +} + +func (a AzureClient) CreateNetworkSecurityGroup(ctx *DeploymentContext, resourceGroup, name, location string, rules *[]network.SecurityRule) error { + log.Info("Configuring network security group.", logutil.Fields{ + "name": name, + "location": location}) + _, err := a.securityGroupsClient().CreateOrUpdate(resourceGroup, name, + network.SecurityGroup{ + Location: to.StringPtr(location), + Properties: &network.SecurityGroupPropertiesFormat{ + SecurityRules: rules, + }, + }, nil) + if err != nil { + return err + } + nsg, err := a.securityGroupsClient().Get(resourceGroup, name, "") + ctx.NetworkSecurityGroupID = to.String(nsg.ID) + return err +} + +func (a AzureClient) DeleteNetworkSecurityGroupIfExists(resourceGroup, name string) error { + return deleteResourceIfExists("Network Security Group", name, + func() error { + _, err := a.securityGroupsClient().Get(resourceGroup, name, "") + return err + }, + func() (autorest.Response, error) { return a.securityGroupsClient().Delete(resourceGroup, name, nil) }) +} + +func (a AzureClient) CreatePublicIPAddress(ctx *DeploymentContext, resourceGroup, name, location string, isStatic bool, dnsLabel string) error { + log.Info("Creating public IP address.", logutil.Fields{ + "name": name, + "static": isStatic}) + + var ipType network.IPAllocationMethod + if isStatic { + ipType = network.Static + } else { + ipType = network.Dynamic + } + + var dns *network.PublicIPAddressDNSSettings + if dnsLabel != "" { + dns = &network.PublicIPAddressDNSSettings{ + DomainNameLabel: to.StringPtr(dnsLabel), + } + } + + _, err := a.publicIPAddressClient().CreateOrUpdate(resourceGroup, name, + network.PublicIPAddress{ + Location: to.StringPtr(location), + Properties: &network.PublicIPAddressPropertiesFormat{ + PublicIPAllocationMethod: ipType, + DNSSettings: dns, + }, + }, nil) + if err != nil { + return err + } + ip, err := a.publicIPAddressClient().Get(resourceGroup, name, "") + ctx.PublicIPAddressID = to.String(ip.ID) + return err +} + +func (a AzureClient) DeletePublicIPAddressIfExists(resourceGroup, name string) error { + return deleteResourceIfExists("Public IP", name, + func() error { + _, err := a.publicIPAddressClient().Get(resourceGroup, name, "") + return err + }, + func() (autorest.Response, error) { return a.publicIPAddressClient().Delete(resourceGroup, name, nil) }) +} + +func (a AzureClient) CreateVirtualNetworkIfNotExists(resourceGroup, name, location string) error { + f := logutil.Fields{ + "name": name, + "rg": resourceGroup, + "location": location, + } + + log.Info("Querying if virtual network already exists.", f) + + if exists, err := a.virtualNetworkExists(resourceGroup, name); err != nil { + return err + } else if exists { + log.Info("Virtual network already exists.", f) + return nil + } + + log.Info("Creating virtual network.", f) + _, err := a.virtualNetworksClient().CreateOrUpdate(resourceGroup, name, + network.VirtualNetwork{ + Location: to.StringPtr(location), + Properties: &network.VirtualNetworkPropertiesFormat{ + AddressSpace: &network.AddressSpace{ + AddressPrefixes: to.StringSlicePtr(defaultVnetAddressPrefixes), + }, + }, + }, nil) + return err +} + +func (a AzureClient) virtualNetworkExists(resourceGroup, name string) (bool, error) { + _, err := a.virtualNetworksClient().Get(resourceGroup, name, "") + return checkResourceExistsFromError(err) +} + +// CleanupVirtualNetworkIfExists removes a subnet if there are no subnets +// attached to it. Note that this method is not safe for multiple concurrent +// writers, in case of races, deployment of a machine could fail or resource +// might not be cleaned up. +func (a AzureClient) CleanupVirtualNetworkIfExists(resourceGroup, name string) error { + return a.cleanupResourceIfExists(&vnetCleanup{rg: resourceGroup, name: name}) +} + +func (a AzureClient) GetSubnet(resourceGroup, virtualNetwork, name string) (network.Subnet, error) { + return a.subnetsClient().Get(resourceGroup, virtualNetwork, name, "") +} + +// CreateSubnet creates or updates a subnet if it does not already exist. +func (a AzureClient) CreateSubnet(ctx *DeploymentContext, resourceGroup, virtualNetwork, name, subnetPrefix string) error { + subnet, err := a.GetSubnet(resourceGroup, virtualNetwork, name) + if err == nil { + log.Info("Subnet already exists.") + ctx.SubnetID = to.String(subnet.ID) + return err + } + + // If the subnet is not found, create it + if err.(autorest.DetailedError).StatusCode == 404 { + log.Info("Configuring subnet.", logutil.Fields{ + "name": name, + "vnet": virtualNetwork, + "cidr": subnetPrefix}) + _, err = a.subnetsClient().CreateOrUpdate(resourceGroup, virtualNetwork, name, + network.Subnet{ + Properties: &network.SubnetPropertiesFormat{ + AddressPrefix: to.StringPtr(subnetPrefix), + }, + }, nil) + + if err != nil { + return err + } + + subnet, err = a.subnetsClient().Get(resourceGroup, virtualNetwork, name, "") + ctx.SubnetID = to.String(subnet.ID) + return err + } + + log.Warn("Create subnet operation error %v: ", err) + return err + +} + +// CleanupSubnetIfExists removes a subnet if there are no IP configurations +// (through NICs) are attached to it. Note that this method is not safe for +// multiple concurrent writers, in case of races, deployment of a machine could +// fail or resource might not be cleaned up. +func (a AzureClient) CleanupSubnetIfExists(resourceGroup, virtualNetwork, name string) error { + return a.cleanupResourceIfExists(&subnetCleanup{ + rg: resourceGroup, vnet: virtualNetwork, name: name, + }) +} + +func (a AzureClient) CreateNetworkInterface(ctx *DeploymentContext, resourceGroup, name, location, publicIPAddressID, subnetID, nsgID, privateIPAddress string) error { + // NOTE(ahmetalpbalkan) This method is expected to fail if the user + // specified Azure location is different than location of the virtual + // network as Azure does not support cross-region virtual networks. In this + // situation, user will get an explanatory API error from Azure. + log.Info("Creating network interface.", logutil.Fields{"name": name}) + + var publicIP *network.PublicIPAddress + if publicIPAddressID != "" { + publicIP = &network.PublicIPAddress{ID: to.StringPtr(publicIPAddressID)} + } + + var privateIPAllocMethod = network.Dynamic + if privateIPAddress != "" { + privateIPAllocMethod = network.Static + } + _, err := a.networkInterfacesClient().CreateOrUpdate(resourceGroup, name, network.Interface{ + Location: to.StringPtr(location), + Properties: &network.InterfacePropertiesFormat{ + NetworkSecurityGroup: &network.SecurityGroup{ + ID: to.StringPtr(nsgID), + }, + IPConfigurations: &[]network.InterfaceIPConfiguration{ + { + Name: to.StringPtr("ip"), + Properties: &network.InterfaceIPConfigurationPropertiesFormat{ + PrivateIPAddress: to.StringPtr(privateIPAddress), + PrivateIPAllocationMethod: privateIPAllocMethod, + PublicIPAddress: publicIP, + Subnet: &network.Subnet{ + ID: to.StringPtr(subnetID), + }, + }, + }, + }, + }, + }, nil) + if err != nil { + return err + } + nic, err := a.networkInterfacesClient().Get(resourceGroup, name, "") + ctx.NetworkInterfaceID = to.String(nic.ID) + return err +} + +func (a AzureClient) DeleteNetworkInterfaceIfExists(resourceGroup, name string) error { + return deleteResourceIfExists("Network Interface", name, + func() error { + _, err := a.networkInterfacesClient().Get(resourceGroup, name, "") + return err + }, + func() (autorest.Response, error) { return a.networkInterfacesClient().Delete(resourceGroup, name, nil) }) +} + +func (a AzureClient) CreateStorageAccount(ctx *DeploymentContext, resourceGroup, location string, storageType storage.SkuName) error { + s, err := a.findOrCreateStorageAccount(resourceGroup, location, storageType) + ctx.StorageAccount = s + return err +} + +func (a AzureClient) findOrCreateStorageAccount(resourceGroup, location string, storageType storage.SkuName) (*storage.AccountProperties, error) { + prefix := storageAccountPrefix + if s, err := a.findStorageAccount(resourceGroup, location, prefix, storageType); err != nil { + return nil, err + } else if s != nil { + return s, nil + } + + log.Debug("No eligible storage account found.", logutil.Fields{ + "location": location, + "sku": storageType}) + return a.createStorageAccount(resourceGroup, location, storageType) +} + +func (a AzureClient) findStorageAccount(resourceGroup, location, prefix string, storageType storage.SkuName) (*storage.AccountProperties, error) { + f := logutil.Fields{ + "sku": storageType, + "prefix": prefix, + "location": location} + log.Debug("Querying existing storage accounts.", f) + l, err := a.storageAccountsClient().ListByResourceGroup(resourceGroup) + if err != nil { + return nil, err + } + + if l.Value != nil { + for _, v := range *l.Value { + log.Debug("Iterating...", logutil.Fields{ + "name": to.String(v.Name), + "sku": storageType, + "location": to.String(v.Location), + }) + if to.String(v.Location) == location && v.Sku.Name == storageType && strings.HasPrefix(to.String(v.Name), prefix) { + log.Debug("Found eligible storage account.", logutil.Fields{"name": to.String(v.Name)}) + log.Info("Using existing storage account.", logutil.Fields{ + "name": to.String(v.Name), + "sku": storageType, + }) + return v.Properties, nil + } + } + } + log.Debug("No account matching the pattern is found.", f) + return nil, err +} + +func (a AzureClient) createStorageAccount(resourceGroup, location string, storageType storage.SkuName) (*storage.AccountProperties, error) { + name := randomAzureStorageAccountName() // if it's not random enough, then you're unlucky + + f := logutil.Fields{ + "name": name, + "location": location, + "sku": storageType, + } + + log.Info("Creating storage account.", f) + _, err := a.storageAccountsClient().Create(resourceGroup, name, + storage.AccountCreateParameters{ + Location: to.StringPtr(location), + Sku: &storage.Sku{Name: storageType}, + }, nil) + if err != nil { + return nil, err + } + + s, err := a.storageAccountsClient().GetProperties(resourceGroup, name) + if err != nil { + return nil, err + } + return s.Properties, nil +} + +func (a AzureClient) VirtualMachineExists(resourceGroup, name string) (bool, error) { + _, err := a.virtualMachinesClient().Get(resourceGroup, name, "") + return checkResourceExistsFromError(err) +} + +func (a AzureClient) DeleteVirtualMachineIfExists(resourceGroup, name string) error { + var vmRef compute.VirtualMachine + err := deleteResourceIfExists("Virtual Machine", name, + func() error { + vm, err := a.virtualMachinesClient().Get(resourceGroup, name, "") + vmRef = vm + return err + }, + func() (autorest.Response, error) { return a.virtualMachinesClient().Delete(resourceGroup, name, nil) }) + if err != nil { + return err + } + + // Remove disk + if vmRef.Properties != nil { + vhdURL := to.String(vmRef.Properties.StorageProfile.OsDisk.Vhd.URI) + return a.removeOSDiskBlob(resourceGroup, name, vhdURL) + } + return nil +} + +func (a AzureClient) removeOSDiskBlob(resourceGroup, vmName, vhdURL string) error { + // NOTE(ahmetalpbalkan) Currently Azure APIs do not offer a Delete Virtual + // Machine functionality which deletes the attached disks along with the VM + // as well. Therefore we find out the storage account from OS disk URL and + // fetch storage account keys to delete the container containing the disk. + log.Debug("Attempting to remove OS disk.", logutil.Fields{"vm": vmName}) + log.Debugf("OS Disk vhd URL: %q", vhdURL) + + vhdContainer := osDiskStorageContainerName(vmName) + + storageAccount, blobServiceBaseURL := extractStorageAccountFromVHDURL(vhdURL) + if storageAccount == "" { + log.Warn("Could not extract the storage account name from URL. Please clean up the disk yourself.") + return nil + } + log.Debug("Fetching storage account keys.", logutil.Fields{ + "account": storageAccount, + "storageBase": blobServiceBaseURL, + }) + resp, err := a.storageAccountsClient().ListKeys(resourceGroup, storageAccount) + if err != nil { + return err + } + + if resp.Keys == nil || len(*resp.Keys) < 1 { + return errors.New("Returned storage keys list response does not contain any keys") + } + storageAccountKey := to.String(((*resp.Keys)[0]).Value) + bs, err := blobstorage.NewClient(storageAccount, storageAccountKey, blobServiceBaseURL, defaultStorageAPIVersion, true) + if err != nil { + return fmt.Errorf("Error constructing blob storage client :%v", err) + } + + f := logutil.Fields{ + "account": storageAccount, + "container": vhdContainer} + log.Debug("Removing container of disk blobs.", f) + ok, err := bs.GetBlobService().DeleteContainerIfExists(vhdContainer) // HTTP round-trip will not be inspected + if err != nil { + log.Debugf("Container remove happened: %v", ok) + } + + cts, err := bs.GetBlobService().ListContainers(blobstorage.ListContainersParameters{}) + if err != nil { + return err + } + + if len(cts.Containers) == 0 { + log.Debugf("No storage containers left. Deleting virtual machine storage account.") + resp, err := a.storageAccountsClient().Delete(resourceGroup, storageAccount) + if err != nil { + return err + } + + log.Debugf("Storage account deletion happened: %v", resp.Response.Status) + } + + return err +} + +func (a AzureClient) CreateVirtualMachine(resourceGroup, name, location, size, availabilitySetID, networkInterfaceID, + username, sshPublicKey, imageName, customData string, storageAccount *storage.AccountProperties) error { + log.Info("Creating virtual machine.", logutil.Fields{ + "name": name, + "location": location, + "size": size, + "username": username, + "osImage": imageName, + }) + + img, err := parseImageName(imageName) + if err != nil { + return err + } + + var ( + osDiskBlobURL = osDiskStorageBlobURL(storageAccount, name) + sshKeyPath = fmt.Sprintf("/home/%s/.ssh/authorized_keys", username) + ) + log.Debugf("OS disk blob will be placed at: %s", osDiskBlobURL) + log.Debugf("SSH key will be placed at: %s", sshKeyPath) + + var osProfile = &compute.OSProfile{ + ComputerName: to.StringPtr(name), + AdminUsername: to.StringPtr(username), + LinuxConfiguration: &compute.LinuxConfiguration{ + DisablePasswordAuthentication: to.BoolPtr(true), + SSH: &compute.SSHConfiguration{ + PublicKeys: &[]compute.SSHPublicKey{ + { + Path: to.StringPtr(sshKeyPath), + KeyData: to.StringPtr(sshPublicKey), + }, + }, + }, + }, + } + + if customData != "" { + osProfile.CustomData = to.StringPtr(customData) + } + + _, err = a.virtualMachinesClient().CreateOrUpdate(resourceGroup, name, + compute.VirtualMachine{ + Location: to.StringPtr(location), + Properties: &compute.VirtualMachineProperties{ + AvailabilitySet: &compute.SubResource{ + ID: to.StringPtr(availabilitySetID), + }, + HardwareProfile: &compute.HardwareProfile{ + VMSize: compute.VirtualMachineSizeTypes(size), + }, + NetworkProfile: &compute.NetworkProfile{ + NetworkInterfaces: &[]compute.NetworkInterfaceReference{ + { + ID: to.StringPtr(networkInterfaceID), + }, + }, + }, + OsProfile: osProfile, + StorageProfile: &compute.StorageProfile{ + ImageReference: &compute.ImageReference{ + Publisher: to.StringPtr(img.publisher), + Offer: to.StringPtr(img.offer), + Sku: to.StringPtr(img.sku), + Version: to.StringPtr(img.version), + }, + OsDisk: &compute.OSDisk{ + Name: to.StringPtr(fmt.Sprintf(fmtOSDiskResourceName, name)), + Caching: compute.ReadWrite, + CreateOption: compute.FromImage, + Vhd: &compute.VirtualHardDisk{ + URI: to.StringPtr(osDiskBlobURL), + }, + }, + }, + }, + }, nil) + return err +} + +func (a AzureClient) GetVirtualMachinePowerState(resourceGroup, name string) (VMPowerState, error) { + log.Debug("Querying instance view for power state.") + vm, err := a.virtualMachinesClient().Get(resourceGroup, name, "instanceView") + if err != nil { + log.Errorf("Error querying instance view: %v", err) + return Unknown, err + } + return powerStateFromInstanceView(vm.Properties.InstanceView), nil +} + +func (a AzureClient) GetAvailabilitySet(resourceGroup, name string) (compute.AvailabilitySet, error) { + return a.availabilitySetsClient().Get(resourceGroup, name) +} + +func (a AzureClient) CreateAvailabilitySetIfNotExists(ctx *DeploymentContext, resourceGroup, name, location string) error { + f := logutil.Fields{"name": name} + log.Info("Configuring availability set.", f) + as, err := a.availabilitySetsClient().CreateOrUpdate(resourceGroup, name, + compute.AvailabilitySet{ + Location: to.StringPtr(location), + }) + ctx.AvailabilitySetID = to.String(as.ID) + return err +} + +// CleanupAvailabilitySetIfExists removes an availability set if there are no +// virtual machines attached to it. Note that this method is not safe for +// multiple concurrent writers, in case of races, deployment of a machine could +// fail or resource might not be cleaned up. +func (a AzureClient) CleanupAvailabilitySetIfExists(resourceGroup, name string) error { + return a.cleanupResourceIfExists(&avSetCleanup{rg: resourceGroup, name: name}) +} + +// GetPublicIPAddress attempts to get public IP address from the Public IP +// resource. If IP address is not allocated yet, returns empty string. If +// useFqdn is set to true, the a FQDN hostname will be returned. +func (a AzureClient) GetPublicIPAddress(resourceGroup, name string, useFqdn bool) (string, error) { + f := logutil.Fields{"name": name} + log.Debug("Querying public IP address.", f) + ip, err := a.publicIPAddressClient().Get(resourceGroup, name, "") + if err != nil { + return "", err + } + if ip.Properties == nil { + log.Debug("publicIP.Properties is nil. Could not determine IP address", f) + return "", nil + } + + if useFqdn { // return FQDN value on public IP + log.Debug("Will attempt to return FQDN.", f) + if ip.Properties.DNSSettings == nil || ip.Properties.DNSSettings.Fqdn == nil { + return "", errors.New("FQDN not found on public IP address") + } + return to.String(ip.Properties.DNSSettings.Fqdn), nil + } + return to.String(ip.Properties.IPAddress), nil +} + +// GetPrivateIPAddress attempts to retrieve private IP address of the specified +// network interface name. If IP address is not allocated yet, returns empty +// string. +func (a AzureClient) GetPrivateIPAddress(resourceGroup, name string) (string, error) { + f := logutil.Fields{"name": name} + log.Debug("Querying network interface.", f) + nic, err := a.networkInterfacesClient().Get(resourceGroup, name, "") + if err != nil { + return "", err + } + if nic.Properties == nil || nic.Properties.IPConfigurations == nil || + len(*nic.Properties.IPConfigurations) == 0 { + log.Debug("No IPConfigurations found on NIC", f) + return "", nil + } + return to.String((*nic.Properties.IPConfigurations)[0].Properties.PrivateIPAddress), nil +} + +// StartVirtualMachine starts the virtual machine and waits until it reaches +// the goal state (running) or times out. +func (a AzureClient) StartVirtualMachine(resourceGroup, name string) error { + log.Info("Starting virtual machine.", logutil.Fields{"vm": name}) + if _, err := a.virtualMachinesClient().Start(resourceGroup, name, nil); err != nil { + return err + } + return a.waitVMPowerState(resourceGroup, name, Running, waitStartTimeout) +} + +// StopVirtualMachine power offs the virtual machine and waits until it reaches +// the goal state (stopped) or times out. +func (a AzureClient) StopVirtualMachine(resourceGroup, name string) error { + log.Info("Stopping virtual machine.", logutil.Fields{"vm": name}) + if _, err := a.virtualMachinesClient().PowerOff(resourceGroup, name, nil); err != nil { + return err + } + return a.waitVMPowerState(resourceGroup, name, Stopped, waitPowerOffTimeout) +} + +// RestartVirtualMachine restarts the virtual machine and waits until it reaches +// the goal state (stopped) or times out. +func (a AzureClient) RestartVirtualMachine(resourceGroup, name string) error { + log.Info("Restarting virtual machine.", logutil.Fields{"vm": name}) + if _, err := a.virtualMachinesClient().Restart(resourceGroup, name, nil); err != nil { + return err + } + return a.waitVMPowerState(resourceGroup, name, Running, waitStartTimeout) +} + +// deleteResourceIfExists is an utility method to determine if a resource exists +// from the error returned from its Get response. If so, deletes it. name is +// used only for logging purposes. +func deleteResourceIfExists(resourceType, name string, getFunc func() error, deleteFunc func() (autorest.Response, error)) error { + f := logutil.Fields{"name": name} + log.Debug(fmt.Sprintf("Querying if %s exists.", resourceType), f) + if exists, err := checkResourceExistsFromError(getFunc()); err != nil { + return err + } else if !exists { + log.Info(fmt.Sprintf("%s does not exist. Skipping.", resourceType), f) + return nil + } + log.Info(fmt.Sprintf("Removing %s resource.", resourceType), f) + _, err := deleteFunc() + return err +} + +// waitVMPowerState polls the Virtual Machine instance view until it reaches the +// specified goal power state or times out. If checking for virtual machine +// state fails or waiting times out, an error is returned. +func (a AzureClient) waitVMPowerState(resourceGroup, name string, goalState VMPowerState, timeout time.Duration) error { + // NOTE(ahmetalpbalkan): Azure APIs for Start and Stop are actually async + // operations on which our SDK blocks and does polling until the operation + // is complete. + // + // By the time the issued power cycle operation is complete, the VM will be + // already in the goal PowerState. Hence, this method will return in the + // first check, however there is no harm in being defensive. + log.Debug("Waiting until VM reaches goal power state.", logutil.Fields{ + "vm": name, + "goalState": goalState, + "timeout": timeout, + }) + + chErr := make(chan error) + go func(ch chan error) { + for { + select { + case <-ch: + // channel closed + return + default: + state, err := a.GetVirtualMachinePowerState(resourceGroup, name) + if err != nil { + ch <- err + return + } + if state != goalState { + log.Debug(fmt.Sprintf("Waiting %v...", powerStatePollingInterval), + logutil.Fields{ + "goalState": goalState, + "state": state, + }) + time.Sleep(powerStatePollingInterval) + } else { + log.Debug("Reached goal power state.", + logutil.Fields{"state": state}) + ch <- nil + return + } + } + } + }(chErr) + + select { + case <-time.After(timeout): + close(chErr) + return fmt.Errorf("Waiting for goal state %q timed out after %v", goalState, timeout) + case err := <-chErr: + return err + } +} + +// checkExistsFromError inspects an error and returns a true if err is nil, +// false if error is an autorest.Error with StatusCode=404 and will return the +// error back if error is another status code or another type of error. +func checkResourceExistsFromError(err error) (bool, error) { + if err == nil { + return true, nil + } + v, ok := err.(autorest.DetailedError) + if ok && v.StatusCode == http.StatusNotFound { + return false, nil + } + return false, v +} + +// osDiskStorageBlobURL gives the full url of the VHD blob where the OS disk for +// the given VM should be stored. +func osDiskStorageBlobURL(account *storage.AccountProperties, vmName string) string { + containerURL := osDiskStorageContainerURL(account, vmName) // has trailing slash + blobName := fmt.Sprintf(fmtOSDiskBlobName, vmName) + return containerURL + blobName +} + +// osDiskStorageContainerName returns the container name the OS disk for the VM +// should be saved. +func osDiskStorageContainerName(vm string) string { return fmt.Sprintf(fmtOSDiskContainer, vm) } + +// osDiskStorageContainerURL crafts a URL with a trailing slash pointing +// to the full Azure Blob Container URL for given VM name. +func osDiskStorageContainerURL(account *storage.AccountProperties, vmName string) string { + return fmt.Sprintf("%s%s/", to.String(account.PrimaryEndpoints.Blob), osDiskStorageContainerName(vmName)) +} + +// extractStorageAccountFromVHDURL parses a blob URL and extracts the Azure +// Storage account name from the URL, namely first subdomain of the hostname and +// the Azure Storage service base URL (e.g. core.windows.net). If it could not +// be parsed, returns empty string. +func extractStorageAccountFromVHDURL(vhdURL string) (string, string) { + u, err := url.Parse(vhdURL) + if err != nil { + log.Warn(fmt.Sprintf("URL parse error: %v", err), logutil.Fields{"url": vhdURL}) + return "", "" + } + parts := strings.SplitN(u.Host, ".", 2) + if len(parts) != 2 { + log.Warnf("Could not split account name and storage base URL: %s", vhdURL) + return "", "" + } + return parts[0], strings.TrimPrefix(parts[1], "blob.") // "blob." prefix will added by azure storage sdk +} diff --git a/drivers/azure/azureutil/cleanup.go b/drivers/azure/azureutil/cleanup.go new file mode 100644 index 0000000000..431ec53026 --- /dev/null +++ b/drivers/azure/azureutil/cleanup.go @@ -0,0 +1,126 @@ +package azureutil + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/docker/machine/drivers/azure/logutil" + "github.com/docker/machine/libmachine/log" +) + +type cleanupResource interface { + // Get retrieves if the resource and saves its reference to the instance + // for further using, returned error is used to determine if the resource + // exists + Get(a AzureClient) error + + // Delete deletes the resource + Delete(a AzureClient) error + + // HasAttachedResources checks the resource reference if it has dependent + // resources attached to it preventing it from being deleted. + HasAttachedResources() bool + + // ResourceType returns human-readable name of the type of the resource. + ResourceType() string + + // LogFields returns the logging fields used during cleanup logging. + LogFields() logutil.Fields +} + +// cleanupResourceIfExists checks if the resource exists, if it does and it +// does not have any attached resources, then deletes the resource. If the +// resource does not exist or is not eligible for cleanup, returns nil. If an +// error is encountered, returns the error. +func (a AzureClient) cleanupResourceIfExists(r cleanupResource) error { + f := r.LogFields() + log.Info(fmt.Sprintf("Attempting to clean up %s resource...", r.ResourceType()), f) + err := r.Get(a) + if exists, err := checkResourceExistsFromError(err); err != nil { + return err + } else if !exists { + log.Debug(fmt.Sprintf("%s resource does not exist. Skipping.", r.ResourceType()), f) + return nil + } + + if !r.HasAttachedResources() { + log.Debug(fmt.Sprintf("%s does not have any attached dependent resource.", r.ResourceType()), f) + log.Info(fmt.Sprintf("Removing %s resource...", r.ResourceType()), f) + return r.Delete(a) + } + log.Info(fmt.Sprintf("%s is still in use by other resources, skipping removal.", r.ResourceType()), f) + return nil +} + +// subnetCleanup manages cleanup of Subnet resources +type subnetCleanup struct { + rg, vnet, name string + ref network.Subnet +} + +func (c *subnetCleanup) Get(a AzureClient) (err error) { + c.ref, err = a.subnetsClient().Get(c.rg, c.vnet, c.name, "") + return err +} + +func (c *subnetCleanup) Delete(a AzureClient) error { + _, err := a.subnetsClient().Delete(c.rg, c.vnet, c.name, nil) + return err +} + +func (c *subnetCleanup) ResourceType() string { return "Subnet" } + +func (c *subnetCleanup) LogFields() logutil.Fields { return logutil.Fields{"name": c.name} } + +func (c *subnetCleanup) HasAttachedResources() bool { + return c.ref.Properties.IPConfigurations != nil && len(*c.ref.Properties.IPConfigurations) > 0 +} + +// vnetCleanup manages cleanup of Virtual Network resources. +type vnetCleanup struct { + rg, name string + ref network.VirtualNetwork +} + +func (c *vnetCleanup) Get(a AzureClient) (err error) { + c.ref, err = a.virtualNetworksClient().Get(c.rg, c.name, "") + return err +} + +func (c *vnetCleanup) Delete(a AzureClient) error { + _, err := a.virtualNetworksClient().Delete(c.rg, c.name, nil) + return err +} + +func (c *vnetCleanup) ResourceType() string { return "Virtual Network" } + +func (c *vnetCleanup) LogFields() logutil.Fields { return logutil.Fields{"name": c.name} } + +func (c *vnetCleanup) HasAttachedResources() bool { + return c.ref.Properties.Subnets != nil && len(*c.ref.Properties.Subnets) > 0 +} + +// avSetCleanup manages cleanup of Availability Set resources. +type avSetCleanup struct { + rg, name string + ref compute.AvailabilitySet +} + +func (c *avSetCleanup) Get(a AzureClient) (err error) { + c.ref, err = a.availabilitySetsClient().Get(c.rg, c.name) + return err +} + +func (c *avSetCleanup) Delete(a AzureClient) error { + _, err := a.availabilitySetsClient().Delete(c.rg, c.name) + return err +} + +func (c *avSetCleanup) ResourceType() string { return "Availability Set" } + +func (c *avSetCleanup) LogFields() logutil.Fields { return logutil.Fields{"name": c.name} } + +func (c *avSetCleanup) HasAttachedResources() bool { + return c.ref.Properties.VirtualMachines != nil && len(*c.ref.Properties.VirtualMachines) > 0 +} diff --git a/drivers/azure/azureutil/clients.go b/drivers/azure/azureutil/clients.go new file mode 100644 index 0000000000..2da99071db --- /dev/null +++ b/drivers/azure/azureutil/clients.go @@ -0,0 +1,137 @@ +package azureutil + +import ( + "fmt" + "time" + + "github.com/docker/machine/version" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/Azure/azure-sdk-for-go/arm/resources/resources" + "github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions" + "github.com/Azure/azure-sdk-for-go/arm/storage" + "github.com/Azure/go-autorest/autorest" +) + +// TODO(ahmetalpbalkan) Remove duplication around client creation. This is +// happening because we auto-generate our SDK and we don't have generics in Go. +// We are hoping to come up with a factory or some defaults instance to set +// these client configuration in a central place in azure-sdk-for-go. + +func oauthClient() autorest.Client { + c := autorest.NewClientWithUserAgent(fmt.Sprintf("docker-machine/%s", version.Version)) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + // TODO set user agent + return c +} + +func subscriptionsClient(baseURI string) subscriptions.Client { + c := subscriptions.NewClientWithBaseURI(baseURI) // used only for unauthenticated requests for generic subs IDs + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) providersClient() resources.ProvidersClient { + c := resources.NewProvidersClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) resourceGroupsClient() resources.GroupsClient { + c := resources.NewGroupsClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) securityGroupsClient() network.SecurityGroupsClient { + c := network.NewSecurityGroupsClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) virtualNetworksClient() network.VirtualNetworksClient { + c := network.NewVirtualNetworksClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) subnetsClient() network.SubnetsClient { + c := network.NewSubnetsClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) networkInterfacesClient() network.InterfacesClient { + c := network.NewInterfacesClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) publicIPAddressClient() network.PublicIPAddressesClient { + c := network.NewPublicIPAddressesClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) storageAccountsClient() storage.AccountsClient { + c := storage.NewAccountsClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) virtualMachinesClient() compute.VirtualMachinesClient { + c := compute.NewVirtualMachinesClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} + +func (a AzureClient) availabilitySetsClient() compute.AvailabilitySetsClient { + c := compute.NewAvailabilitySetsClientWithBaseURI(a.env.ResourceManagerEndpoint, a.subscriptionID) + c.Authorizer = a.auth + c.Client.UserAgent += fmt.Sprintf(";docker-machine/%s", version.Version) + c.RequestInspector = withInspection() + c.ResponseInspector = byInspecting() + c.PollingDelay = time.Second * 5 + return c +} diff --git a/drivers/azure/azureutil/context.go b/drivers/azure/azureutil/context.go new file mode 100644 index 0000000000..63d54af541 --- /dev/null +++ b/drivers/azure/azureutil/context.go @@ -0,0 +1,20 @@ +package azureutil + +import ( + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/Azure/azure-sdk-for-go/arm/storage" +) + +// DeploymentContext contains references to various sources created and then +// used in creating other resources. +type DeploymentContext struct { + VirtualNetworkExists bool + StorageAccount *storage.AccountProperties + PublicIPAddressID string + NetworkSecurityGroupID string + SubnetID string + NetworkInterfaceID string + SSHPublicKey string + AvailabilitySetID string + FirewallRules *[]network.SecurityRule +} diff --git a/drivers/azure/azureutil/inspector.go b/drivers/azure/azureutil/inspector.go new file mode 100644 index 0000000000..d992b69629 --- /dev/null +++ b/drivers/azure/azureutil/inspector.go @@ -0,0 +1,36 @@ +package azureutil + +import ( + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/docker/machine/drivers/azure/logutil" + "github.com/docker/machine/libmachine/log" +) + +func withInspection() autorest.PrepareDecorator { + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + log.Debug("Azure request", logutil.Fields{ + "method": r.Method, + "request": r.URL.String(), + }) + return p.Prepare(r) + }) + } +} + +func byInspecting() autorest.RespondDecorator { + return func(r autorest.Responder) autorest.Responder { + return autorest.ResponderFunc(func(resp *http.Response) error { + log.Debug("Azure response", logutil.Fields{ + "status": resp.Status, + "method": resp.Request.Method, + "request": resp.Request.URL.String(), + "x-ms-request-id": azure.ExtractRequestID(resp), + }) + return r.Respond(resp) + }) + } +} diff --git a/drivers/azure/azureutil/naming.go b/drivers/azure/azureutil/naming.go new file mode 100644 index 0000000000..9967fcf87e --- /dev/null +++ b/drivers/azure/azureutil/naming.go @@ -0,0 +1,21 @@ +package azureutil + +import ( + "fmt" +) + +const ( + fmtNIC = "%s-nic" + fmtIP = "%s-ip" + fmtNSG = "%s-firewall" + fmtVM = "%s" +) + +// ResourceNaming provides methods to construct Azure resource names for a given +// machine name. +type ResourceNaming string + +func (r ResourceNaming) IP() string { return fmt.Sprintf(fmtIP, r) } +func (r ResourceNaming) NIC() string { return fmt.Sprintf(fmtNIC, r) } +func (r ResourceNaming) NSG() string { return fmt.Sprintf(fmtNSG, r) } +func (r ResourceNaming) VM() string { return fmt.Sprintf(fmtVM, r) } diff --git a/drivers/azure/azureutil/powerstate.go b/drivers/azure/azureutil/powerstate.go new file mode 100644 index 0000000000..02e5499ad0 --- /dev/null +++ b/drivers/azure/azureutil/powerstate.go @@ -0,0 +1,93 @@ +package azureutil + +import ( + "strings" + + "github.com/docker/machine/libmachine/log" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/go-autorest/autorest/to" +) + +type VMPowerState string + +const ( + // Unknown is returned when Azure does not provide a PowerState (happens + // when VM is just deployed or started transitioning to another state) or + // obtained PowerState is not one of the following. + Unknown VMPowerState = "" + + // Stopped indicates that VM is allocated and in powered off state or the VM + // has been just deployed for the first time. In this state, VM can be powered + // on or + Stopped VMPowerState = "stopped" + + // Stopping indicates that VM is about to go into powered off state. + Stopping VMPowerState = "stopping" + + // Starting indicates that VM is being created or powered on. + Starting VMPowerState = "starting" + + // Running indicates that VM is either powered on or being rebooted. VM + // stays in this state during the reboot operation. In this state VM can be + // stopped, restarted or deallocated. + Running VMPowerState = "running" + + // Deallocating indicates that the VM is being terminated. + Deallocating VMPowerState = "deallocating" + + // Deallocated indicates that the VM is being terminated. In this state, VM + // can be powered on or powered off. + Deallocated VMPowerState = "deallocated" +) + +const ( + powerStateCodePrefix = "PowerState/" +) + +// powerStateFromInstanceView reads the instance view response and extracts the +// power state status (if exists) from there. If no status is found or an +// unknown status has occurred, returns Unknown. +func powerStateFromInstanceView(instanceView *compute.VirtualMachineInstanceView) VMPowerState { + if instanceView == nil { + log.Debug("Retrieved nil instance view.") + return Unknown + } else if instanceView.Statuses == nil || len(*instanceView.Statuses) == 0 { + log.Debug("Retrieved nil or empty instanceView.statuses.") + return Unknown + } + statuses := *instanceView.Statuses + + // Filter statuses whose "code" starts with "PowerState/" + var s *compute.InstanceViewStatus + for _, v := range statuses { + log.Debugf("Matching pattern for code=%q", to.String(v.Code)) + if strings.HasPrefix(to.String(v.Code), powerStateCodePrefix) { + log.Debug("Power state found.") + s = &v + break + } + } + if s == nil { + log.Debug("No PowerState found in the instance view statuses.") + return Unknown + } + code := strings.TrimPrefix(to.String(s.Code), powerStateCodePrefix) + switch code { + case "stopped": + return Stopped + case "stopping": + return Stopping + case "starting": + return Starting + case "running": + return Running + case "deallocated": + return Deallocated + case "deallocating": + return Deallocating + default: + log.Warn("Encountered unknown PowerState for virtual machine: %q", code) + return Unknown + } +} diff --git a/drivers/azure/azureutil/tenantid.go b/drivers/azure/azureutil/tenantid.go new file mode 100644 index 0000000000..0280152e33 --- /dev/null +++ b/drivers/azure/azureutil/tenantid.go @@ -0,0 +1,123 @@ +package azureutil + +import ( + "fmt" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/docker/machine/drivers/azure/logutil" + "github.com/docker/machine/libmachine/log" + + "github.com/Azure/go-autorest/autorest/azure" +) + +// loadOrFindTenantID figures out the AAD tenant ID of the subscription by first +// looking at the cache file, if not exists, makes a network call to load it and +// cache it for future use. +func loadOrFindTenantID(env azure.Environment, subscriptionID string) (string, error) { + var tenantID string + + log.Debug("Looking up AAD Tenant ID.", logutil.Fields{ + "subs": subscriptionID}) + + // Load from cache + fp := tenantIDPath(subscriptionID) + b, err := ioutil.ReadFile(fp) + if err == nil { + tenantID = strings.TrimSpace(string(b)) + log.Debugf("Tenant ID loaded from file: %s", fp) + } else if os.IsNotExist(err) { + log.Debugf("Tenant ID file not found: %s", fp) + } else { + return "", fmt.Errorf("Failed to load tenant ID file: %v", err) + } + + // Handle cache miss + if tenantID == "" { + log.Debug("Making API call to find tenant ID") + t, err := findTenantID(env, subscriptionID) + if err != nil { + return "", err + } + tenantID = t + + // Cache the result + if err := saveTenantID(fp, tenantID); err != nil { + return "", fmt.Errorf("Failed to save tenant ID: %v", err) + } + log.Debugf("Cached tenant ID to file: %s", fp) + } + log.Debug("Found AAD Tenant ID.", logutil.Fields{ + "tenant": tenantID, + "subs": subscriptionID}) + return tenantID, nil +} + +// findTenantID figures out the AAD tenant ID of the subscription by making an +// unauthenticated request to the Get Subscription Details endpoint and parses +// the value from WWW-Authenticate header. +func findTenantID(env azure.Environment, subscriptionID string) (string, error) { + const hdrKey = "WWW-Authenticate" + c := subscriptionsClient(env.ResourceManagerEndpoint) + + // we expect this request to fail (err != nil), but we are only interested + // in headers, so surface the error if the Response is not present (i.e. + // network error etc) + subs, err := c.Get(subscriptionID) + if subs.Response.Response == nil { + return "", fmt.Errorf("Request failed: %v", err) + } + + // Expecting 401 StatusUnauthorized here, just read the header + if subs.StatusCode != http.StatusUnauthorized { + return "", fmt.Errorf("Unexpected response from Get Subscription: %v", err) + } + hdr := subs.Header.Get(hdrKey) + if hdr == "" { + return "", fmt.Errorf("Header %v not found in Get Subscription response", hdrKey) + } + + // Example value for hdr: + // Bearer authorization_uri="https://login.windows.net/996fe9d1-6171-40aa-945b-4c64b63bf655", error="invalid_token", error_description="The authentication failed because of missing 'Authorization' header." + r := regexp.MustCompile(`authorization_uri=".*/([0-9a-f\-]+)"`) + m := r.FindStringSubmatch(hdr) + if m == nil { + return "", fmt.Errorf("Could not find the tenant ID in header: %s %q", hdrKey, hdr) + } + return m[1], nil +} + +// saveTenantID performs an atomic write to the path with given tenantID contents. +func saveTenantID(path string, tenantID string) error { + var perm os.FileMode = 0600 + + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + return fmt.Errorf("Failed to create directory %s: %v", dir, err) + } + + f, err := ioutil.TempFile(dir, "tenantid") + if err != nil { + return fmt.Errorf("Failed to create temp file: %v", err) + } + defer f.Close() + + fp := f.Name() + if _, err := f.Write([]byte(tenantID)); err != nil { + return fmt.Errorf("Failed to write tenant ID to file: %v", err) + } + f.Close() + + // atomic move by rename + if err := os.Rename(fp, path); err != nil { + return fmt.Errorf("Failed to rename file. src=%s dst=%s error=%v", fp, path, err) + } + if err := os.Chmod(path, perm); err != nil { + return fmt.Errorf("Failed to chmod the file %s: %v", path, err) + } + return nil +} diff --git a/drivers/azure/azureutil/util.go b/drivers/azure/azureutil/util.go new file mode 100644 index 0000000000..55acc464ba --- /dev/null +++ b/drivers/azure/azureutil/util.go @@ -0,0 +1,45 @@ +package azureutil + +import ( + "fmt" + "math/rand" + "strings" + "time" +) + +/* Utilities */ + +// randomAzureStorageAccountName generates a valid storage account name prefixed +// with a predefined string. Availability of the name is not checked. Uses maximum +// length to maximise randomness. +func randomAzureStorageAccountName() string { + const ( + maxLen = 24 + chars = "0123456789abcdefghijklmnopqrstuvwxyz" + ) + return storageAccountPrefix + randomString(maxLen-len(storageAccountPrefix), chars) +} + +// randomString generates a random string of given length using specified alphabet. +func randomString(n int, alphabet string) string { + r := timeSeed() + b := make([]byte, n) + for i := range b { + b[i] = alphabet[r.Intn(len(alphabet))] + } + return string(b) +} + +// imageName holds various components of an OS image name identifier +type imageName struct{ publisher, offer, sku, version string } + +// parseImageName parses a publisher:offer:sku:version into those parts. +func parseImageName(image string) (imageName, error) { + l := strings.Split(image, ":") + if len(l) != 4 { + return imageName{}, fmt.Errorf("image name %q not a valid format", image) + } + return imageName{l[0], l[1], l[2], l[3]}, nil +} + +func timeSeed() *rand.Rand { return rand.New(rand.NewSource(time.Now().UTC().UnixNano())) } diff --git a/drivers/azure/logutil/logfields.go b/drivers/azure/logutil/logfields.go new file mode 100644 index 0000000000..b450594de8 --- /dev/null +++ b/drivers/azure/logutil/logfields.go @@ -0,0 +1,16 @@ +package logutil + +import "fmt" + +type Fields map[string]interface{} + +func (f Fields) String() string { + var s string + for k, v := range f { + if sv, ok := v.(string); ok { + v = fmt.Sprintf("%q", sv) + } + s += fmt.Sprintf(" %s=%v", k, v) + } + return s +} diff --git a/drivers/azure/util.go b/drivers/azure/util.go new file mode 100644 index 0000000000..2f1f64e6d8 --- /dev/null +++ b/drivers/azure/util.go @@ -0,0 +1,230 @@ +package azure + +import ( + "fmt" + "io/ioutil" + "net" + "net/url" + "strings" + + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/to" + "github.com/docker/machine/drivers/azure/azureutil" + "github.com/docker/machine/drivers/azure/logutil" + "github.com/docker/machine/drivers/driverutil" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" +) + +var ( + environments = map[string]azure.Environment{ + azure.PublicCloud.Name: azure.PublicCloud, + azure.USGovernmentCloud.Name: azure.USGovernmentCloud, + azure.ChinaCloud.Name: azure.ChinaCloud, + azure.GermanCloud.Name: azure.GermanCloud, + } +) + +// requiredOptionError forms an error from the error indicating the option has +// to be provided with a value for this driver. +type requiredOptionError string + +func (r requiredOptionError) Error() string { + return fmt.Sprintf("%s driver requires the %q option.", driverName, string(r)) +} + +// newAzureClient creates an AzureClient helper from the Driver context and +// initiates authentication if required. +func (d *Driver) newAzureClient() (*azureutil.AzureClient, error) { + env, ok := environments[d.Environment] + if !ok { + valid := make([]string, 0, len(environments)) + for k := range environments { + valid = append(valid, k) + } + + return nil, fmt.Errorf("Invalid Azure environment: %q, supported values: %s", d.Environment, strings.Join(valid, ", ")) + } + + var ( + token *azure.ServicePrincipalToken + err error + ) + if d.ClientID != "" && d.ClientSecret != "" { // use Service Principal auth + log.Debug("Using Azure service principal authentication.") + token, err = azureutil.AuthenticateServicePrincipal(env, d.SubscriptionID, d.ClientID, d.ClientSecret) + if err != nil { + return nil, fmt.Errorf("Failed to authenticate using service principal credentials: %+v", err) + } + } else { // use browser-based device auth + log.Debug("Using Azure device flow authentication.") + token, err = azureutil.AuthenticateDeviceFlow(env, d.SubscriptionID) + if err != nil { + return nil, fmt.Errorf("Error creating Azure client: %v", err) + } + } + return azureutil.New(env, d.SubscriptionID, token), nil +} + +// generateSSHKey creates a ssh key pair locally and saves the public key file +// contents in OpenSSH format to the DeploymentContext. +func (d *Driver) generateSSHKey(ctx *azureutil.DeploymentContext) error { + privPath := d.GetSSHKeyPath() + pubPath := privPath + ".pub" + + log.Debug("Creating SSH key...", logutil.Fields{ + "pub": pubPath, + "priv": privPath, + }) + + if err := ssh.GenerateSSHKey(privPath); err != nil { + return err + } + log.Debug("SSH key pair generated.") + + publicKey, err := ioutil.ReadFile(pubPath) + ctx.SSHPublicKey = string(publicKey) + return err +} + +// getSecurityRules creates network security group rules based on driver +// configuration such as SSH port, docker port and swarm port. +func (d *Driver) getSecurityRules(extraPorts []string) (*[]network.SecurityRule, error) { + mkRule := func(priority int, name, description, srcPort, dstPort string, proto network.SecurityRuleProtocol) network.SecurityRule { + return network.SecurityRule{ + Name: to.StringPtr(name), + Properties: &network.SecurityRulePropertiesFormat{ + Description: to.StringPtr(description), + SourceAddressPrefix: to.StringPtr("*"), + DestinationAddressPrefix: to.StringPtr("*"), + SourcePortRange: to.StringPtr(srcPort), + DestinationPortRange: to.StringPtr(dstPort), + Access: network.Allow, + Direction: network.Inbound, + Protocol: proto, + Priority: to.Int32Ptr(int32(priority)), + }, + } + } + + log.Debugf("Docker port is configured as %d", d.DockerPort) + + // Base ports to be opened for any machine + rl := []network.SecurityRule{ + mkRule(100, "SSHAllowAny", "Allow ssh from public Internet", "*", fmt.Sprintf("%d", d.BaseDriver.SSHPort), network.TCP), + mkRule(300, "DockerAllowAny", "Allow docker engine access (TLS-protected)", "*", fmt.Sprintf("%d", d.DockerPort), network.TCP), + } + + // Open swarm port if configured + if d.BaseDriver.SwarmMaster { + swarmHost := d.BaseDriver.SwarmHost + log.Debugf("Swarm host is configured as %q", swarmHost) + u, err := url.Parse(swarmHost) + if err != nil { + return nil, fmt.Errorf("Cannot parse URL %q: %v", swarmHost, err) + } + _, swarmPort, err := net.SplitHostPort(u.Host) + if err != nil { + return nil, fmt.Errorf("Could not parse swarm port in %q: %v", u.Host, err) + } + rl = append(rl, mkRule(500, "DockerSwarmAllowAny", "Allow swarm manager access (TLS-protected)", "*", swarmPort, network.TCP)) + } else { + log.Debug("Swarm host is not configured.") + } + + // extra port numbers requested by user + basePri := 1000 + for i, p := range extraPorts { + port, protocol := driverutil.SplitPortProto(p) + proto, err := parseSecurityRuleProtocol(protocol) + if err != nil { + return nil, fmt.Errorf("cannot parse security rule protocol: %v", err) + } + log.Debugf("User-requested port to be opened on NSG: %v/%s", port, proto) + name := fmt.Sprintf("Port%s-%sAllowAny", port, proto) + name = strings.Replace(name, "*", "Asterisk", -1) + r := mkRule(basePri+i, name, "User requested port to be accessible from Internet via docker-machine", "*", port, proto) + rl = append(rl, r) + } + log.Debugf("Total NSG rules: %d", len(rl)) + + return &rl, nil +} + +func (d *Driver) naming() azureutil.ResourceNaming { + return azureutil.ResourceNaming(d.BaseDriver.MachineName) +} + +// ipAddress returns machine’s private or public IP address according to the +// configuration. If no IP address is found it returns empty string. +func (d *Driver) ipAddress() (ip string, err error) { + c, err := d.newAzureClient() + if err != nil { + return "", err + } + + var ipType string + if d.UsePrivateIP || d.NoPublicIP { + ipType = "Private" + ip, err = c.GetPrivateIPAddress(d.ResourceGroup, d.naming().NIC()) + } else { + ipType = "Public" + ip, err = c.GetPublicIPAddress(d.ResourceGroup, + d.naming().IP(), + d.DNSLabel != "") + } + + log.Debugf("Retrieving %s IP address...", ipType) + if err != nil { + return "", fmt.Errorf("Error querying %s IP: %v", ipType, err) + } + if ip == "" { + log.Debugf("%s IP address is not yet allocated.", ipType) + } + return ip, nil +} + +func machineStateForVMPowerState(ps azureutil.VMPowerState) state.State { + m := map[azureutil.VMPowerState]state.State{ + azureutil.Running: state.Running, + azureutil.Starting: state.Starting, + azureutil.Stopping: state.Stopping, + azureutil.Stopped: state.Stopped, + azureutil.Deallocating: state.Stopping, + azureutil.Deallocated: state.Stopped, + azureutil.Unknown: state.None, + } + + if v, ok := m[ps]; ok { + return v + } + log.Warnf("Azure PowerState %q does not map to a docker-machine state.", ps) + return state.None +} + +// parseVirtualNetwork parses Virtual Network input format "[resourcegroup:]name" +// into Resource Group (uses provided one if omitted) and Virtual Network Name +func parseVirtualNetwork(name string, defaultRG string) (string, string) { + l := strings.SplitN(name, ":", 2) + if len(l) == 2 { + return l[0], l[1] + } + return defaultRG, name +} + +// parseSecurityRuleProtocol parses a protocol string into a network.SecurityRuleProtocol +// and returns error if the protocol is not supported +func parseSecurityRuleProtocol(proto string) (network.SecurityRuleProtocol, error) { + switch strings.ToLower(proto) { + case "tcp": + return network.TCP, nil + case "udp": + return network.UDP, nil + case "*": + return network.Asterisk, nil + default: + return "", fmt.Errorf("invalid protocol %s", proto) + } +} diff --git a/drivers/azure/util_test.go b/drivers/azure/util_test.go new file mode 100644 index 0000000000..58da224ab9 --- /dev/null +++ b/drivers/azure/util_test.go @@ -0,0 +1,31 @@ +package azure + +import ( + "testing" + + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/stretchr/testify/assert" +) + +func TestParseSecurityRuleProtocol(t *testing.T) { + tests := []struct { + raw string + expectedProto network.SecurityRuleProtocol + expectedErr bool + }{ + {"tcp", network.TCP, false}, + {"udp", network.UDP, false}, + {"*", network.Asterisk, false}, + {"Invalid", "", true}, + } + + for _, tc := range tests { + proto, err := parseSecurityRuleProtocol(tc.raw) + assert.Equal(t, tc.expectedProto, proto) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + } +} diff --git a/drivers/digitalocean/digitalocean.go b/drivers/digitalocean/digitalocean.go index f0640dcdf0..8b8d89d2c2 100644 --- a/drivers/digitalocean/digitalocean.go +++ b/drivers/digitalocean/digitalocean.go @@ -1,83 +1,151 @@ package digitalocean import ( + "context" "fmt" "io/ioutil" - "os/exec" - "path/filepath" + "net" + "os" + "path" + "strings" "time" - "code.google.com/p/goauth2/oauth" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" "github.com/digitalocean/godo" - // "github.com/docker/docker/utils" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" -) - -const ( - dockerConfigDir = "/etc/docker" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" + "golang.org/x/oauth2" ) type Driver struct { - AccessToken string - DropletID int - DropletName string - Image string - MachineName string - IPAddress string - Region string - SSHKeyID int - Size string - CaCertPath string - PrivateKeyPath string - DriverKeyPath string - storePath string + *drivers.BaseDriver + AccessToken string + DropletID int + DropletName string + Image string + Region string + SSHKeyID int + SSHKeyFingerprint string + SSHKey string + Size string + IPv6 bool + Backups bool + PrivateNetworking bool + UserDataFile string + Monitoring bool + Tags string } -func init() { - drivers.Register("digitalocean", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} +const ( + defaultSSHPort = 22 + defaultSSHUser = "root" + defaultImage = "ubuntu-16-04-x64" + defaultRegion = "nyc3" + defaultSize = "s-1vcpu-1gb" +) // GetCreateFlags registers the flags this driver adds to // "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ EnvVar: "DIGITALOCEAN_ACCESS_TOKEN", Name: "digitalocean-access-token", Usage: "Digital Ocean access token", }, - cli.StringFlag{ + mcnflag.StringFlag{ + EnvVar: "DIGITALOCEAN_SSH_USER", + Name: "digitalocean-ssh-user", + Usage: "SSH username", + Value: defaultSSHUser, + }, + mcnflag.StringFlag{ + EnvVar: "DIGITALOCEAN_SSH_KEY_FINGERPRINT", + Name: "digitalocean-ssh-key-fingerprint", + Usage: "SSH key fingerprint", + }, + mcnflag.StringFlag{ + EnvVar: "DIGITALOCEAN_SSH_KEY_PATH", + Name: "digitalocean-ssh-key-path", + Usage: "SSH private key path ", + }, + mcnflag.IntFlag{ + EnvVar: "DIGITALOCEAN_SSH_PORT", + Name: "digitalocean-ssh-port", + Usage: "SSH port", + Value: defaultSSHPort, + }, + mcnflag.StringFlag{ EnvVar: "DIGITALOCEAN_IMAGE", Name: "digitalocean-image", Usage: "Digital Ocean Image", - Value: "ubuntu-14-04-x64", + Value: defaultImage, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "DIGITALOCEAN_REGION", Name: "digitalocean-region", Usage: "Digital Ocean region", - Value: "nyc3", + Value: defaultRegion, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "DIGITALOCEAN_SIZE", Name: "digitalocean-size", Usage: "Digital Ocean size", - Value: "512mb", + Value: defaultSize, + }, + mcnflag.BoolFlag{ + EnvVar: "DIGITALOCEAN_IPV6", + Name: "digitalocean-ipv6", + Usage: "enable ipv6 for droplet", + }, + mcnflag.BoolFlag{ + EnvVar: "DIGITALOCEAN_PRIVATE_NETWORKING", + Name: "digitalocean-private-networking", + Usage: "enable private networking for droplet", + }, + mcnflag.BoolFlag{ + EnvVar: "DIGITALOCEAN_BACKUPS", + Name: "digitalocean-backups", + Usage: "enable backups for droplet", + }, + mcnflag.StringFlag{ + EnvVar: "DIGITALOCEAN_USERDATA", + Name: "digitalocean-userdata", + Usage: "path to file with cloud-init user-data", + }, + mcnflag.BoolFlag{ + EnvVar: "DIGITALOCEAN_MONITORING", + Name: "digitalocean-monitoring", + Usage: "enable monitoring for droplet", + }, + mcnflag.StringFlag{ + EnvVar: "DIGITALOCEAN_TAGS", + Name: "digitalocean-tags", + Usage: "comma-separated list of tags to apply to the Droplet", + }, + } +} + +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + Image: defaultImage, + Size: defaultSize, + Region: defaultRegion, + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return "digitalocean" } @@ -87,6 +155,18 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.Image = flags.String("digitalocean-image") d.Region = flags.String("digitalocean-region") d.Size = flags.String("digitalocean-size") + d.IPv6 = flags.Bool("digitalocean-ipv6") + d.PrivateNetworking = flags.Bool("digitalocean-private-networking") + d.Backups = flags.Bool("digitalocean-backups") + d.UserDataFile = flags.String("digitalocean-userdata") + d.SSHUser = flags.String("digitalocean-ssh-user") + d.SSHPort = flags.Int("digitalocean-ssh-port") + d.SSHKeyFingerprint = flags.String("digitalocean-ssh-key-fingerprint") + d.SSHKey = flags.String("digitalocean-ssh-key-path") + d.Monitoring = flags.Bool("digitalocean-monitoring") + d.Tags = flags.String("digitalocean-tags") + + d.SetSwarmConfigFromFlags(flags) if d.AccessToken == "" { return fmt.Errorf("digitalocean driver requires the --digitalocean-access-token option") @@ -96,10 +176,46 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { } func (d *Driver) PreCreateCheck() error { - return nil + if d.UserDataFile != "" { + if _, err := os.Stat(d.UserDataFile); os.IsNotExist(err) { + return fmt.Errorf("user-data file %s could not be found", d.UserDataFile) + } + } + + if d.SSHKey != "" { + if d.SSHKeyFingerprint == "" { + return fmt.Errorf("ssh-key-fingerprint needs to be provided for %q", d.SSHKey) + } + + if _, err := os.Stat(d.SSHKey); os.IsNotExist(err) { + return fmt.Errorf("SSH key does not exist: %q", d.SSHKey) + } + } + + client := d.getClient() + regions, _, err := client.Regions.List(context.TODO(), nil) + if err != nil { + return err + } + for _, region := range regions { + if region.Slug == d.Region { + return nil + } + } + + return fmt.Errorf("digitalocean requires a valid region") } func (d *Driver) Create() error { + var userdata string + if d.UserDataFile != "" { + buf, err := ioutil.ReadFile(d.UserDataFile) + if err != nil { + return err + } + userdata = string(buf) + } + log.Infof("Creating SSH key...") key, err := d.createSSHKey() @@ -114,26 +230,33 @@ func (d *Driver) Create() error { client := d.getClient() createRequest := &godo.DropletCreateRequest{ - Image: d.Image, - Name: d.MachineName, - Region: d.Region, - Size: d.Size, - SSHKeys: []interface{}{d.SSHKeyID}, + Image: godo.DropletCreateImage{Slug: d.Image}, + Name: d.MachineName, + Region: d.Region, + Size: d.Size, + IPv6: d.IPv6, + PrivateNetworking: d.PrivateNetworking, + Backups: d.Backups, + UserData: userdata, + SSHKeys: []godo.DropletCreateSSHKey{{ID: d.SSHKeyID}}, + Monitoring: d.Monitoring, + Tags: d.getTags(), } - newDroplet, _, err := client.Droplets.Create(createRequest) + newDroplet, _, err := client.Droplets.Create(context.TODO(), createRequest) if err != nil { return err } - d.DropletID = newDroplet.Droplet.ID + d.DropletID = newDroplet.ID + log.Info("Waiting for IP address to be assigned to the Droplet...") for { - newDroplet, _, err = client.Droplets.Get(d.DropletID) + newDroplet, _, err = client.Droplets.Get(context.TODO(), d.DropletID) if err != nil { return err } - for _, network := range newDroplet.Droplet.Networks.V4 { + for _, network := range newDroplet.Networks.V4 { if network.Type == "public" { d.IPAddress = network.IPAddress } @@ -147,47 +270,33 @@ func (d *Driver) Create() error { } log.Debugf("Created droplet ID %d, IP address %s", - newDroplet.Droplet.ID, + newDroplet.ID, d.IPAddress) - log.Infof("Waiting for SSH...") - - if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.IPAddress, 22)); err != nil { - return err - } - - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } + return nil +} - log.Debugf("Installing Docker") +func (d *Driver) createSSHKey() (*godo.Key, error) { + d.SSHKeyPath = d.GetSSHKeyPath() - cmd, err = d.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl -sL https://get.docker.com | sh -; fi") - if err != nil { - return err + if d.SSHKeyFingerprint != "" { + key, resp, err := d.getClient().Keys.GetByFingerprint(context.TODO(), d.SSHKeyFingerprint) + if err != nil && resp.StatusCode == 404 { + return nil, fmt.Errorf("Digital Ocean SSH key with fingerprint %s doesn't exist", d.SSHKeyFingerprint) + } - } - if err := cmd.Run(); err != nil { - return err + if d.SSHKey == "" { + log.Infof("Assuming Digital Ocean private SSH is located at ~/.ssh/id_rsa") + return key, nil + } + if err := copySSHKey(d.SSHKey, d.SSHKeyPath); err != nil { + return nil, err + } + return key, nil } - return nil -} - -func (d *Driver) createSSHKey() (*godo.Key, error) { - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.SSHKeyPath); err != nil { return nil, err } @@ -201,7 +310,7 @@ func (d *Driver) createSSHKey() (*godo.Key, error) { PublicKey: string(publicKey), } - key, _, err := d.getClient().Keys.Create(createRequest) + key, _, err := d.getClient().Keys.Create(context.TODO(), createRequest) if err != nil { return key, err } @@ -210,26 +319,24 @@ func (d *Driver) createSSHKey() (*godo.Key, error) { } func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } + ip, err := d.GetIP() if err != nil { return "", err } - return fmt.Sprintf("tcp://%s:2376", ip), nil -} -func (d *Driver) GetIP() (string, error) { - if d.IPAddress == "" { - return "", fmt.Errorf("IP address is not set") - } - return d.IPAddress, nil + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil } func (d *Driver) GetState() (state.State, error) { - droplet, _, err := d.getClient().Droplets.Get(d.DropletID) + droplet, _, err := d.getClient().Droplets.Get(context.TODO(), d.DropletID) if err != nil { return state.Error, err } - switch droplet.Droplet.Status { + switch droplet.Status { case "new": return state.Starting, nil case "active": @@ -241,25 +348,37 @@ func (d *Driver) GetState() (state.State, error) { } func (d *Driver) Start() error { - _, _, err := d.getClient().DropletActions.PowerOn(d.DropletID) + _, _, err := d.getClient().DropletActions.PowerOn(context.TODO(), d.DropletID) return err } func (d *Driver) Stop() error { - _, _, err := d.getClient().DropletActions.Shutdown(d.DropletID) + _, _, err := d.getClient().DropletActions.Shutdown(context.TODO(), d.DropletID) + return err +} + +func (d *Driver) Restart() error { + _, _, err := d.getClient().DropletActions.Reboot(context.TODO(), d.DropletID) + return err +} + +func (d *Driver) Kill() error { + _, _, err := d.getClient().DropletActions.PowerOff(context.TODO(), d.DropletID) return err } func (d *Driver) Remove() error { client := d.getClient() - if resp, err := client.Keys.DeleteByID(d.SSHKeyID); err != nil { - if resp.StatusCode == 404 { - log.Infof("Digital Ocean SSH key doesn't exist, assuming it is already deleted") - } else { - return err + if d.SSHKeyFingerprint == "" { + if resp, err := client.Keys.DeleteByID(context.TODO(), d.SSHKeyID); err != nil { + if resp.StatusCode == 404 { + log.Infof("Digital Ocean SSH key doesn't exist, assuming it is already deleted") + } else { + return err + } } } - if resp, err := client.Droplets.Delete(d.DropletID); err != nil { + if resp, err := client.Droplets.Delete(context.TODO(), d.DropletID); err != nil { if resp.StatusCode == 404 { log.Infof("Digital Ocean droplet doesn't exist, assuming it is already deleted") } else { @@ -269,80 +388,48 @@ func (d *Driver) Remove() error { return nil } -func (d *Driver) Restart() error { - _, _, err := d.getClient().DropletActions.Reboot(d.DropletID) - return err -} +func (d *Driver) getClient() *godo.Client { + token := &oauth2.Token{AccessToken: d.AccessToken} + tokenSource := oauth2.StaticTokenSource(token) + client := oauth2.NewClient(oauth2.NoContext, tokenSource) -func (d *Driver) Kill() error { - _, _, err := d.getClient().DropletActions.PowerOff(d.DropletID) - return err + return godo.NewClient(client) } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") +func (d *Driver) getTags() []string { + var tagList []string - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err + for _, t := range strings.Split(d.Tags, ",") { + t = strings.TrimSpace(t) + if t != "" { + tagList = append(tagList, t) + } } - return nil + return tagList } -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err +func (d *Driver) GetSSHKeyPath() string { + if d.SSHKey != "" { + d.SSHKeyPath = d.ResolveStorePath(path.Base(d.SSHKey)) + } else if d.SSHKeyPath == "" && d.SSHKeyFingerprint == "" { + d.SSHKeyPath = d.ResolveStorePath("id_rsa") } - if err := cmd.Run(); err != nil { - return err - } - - return nil + return d.SSHKeyPath } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" } -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") - if err != nil { - return err - +func copySSHKey(src, dst string) error { + if err := mcnutils.CopyFile(src, dst); err != nil { + return fmt.Errorf("unable to copy ssh key: %s", err) } - if err := cmd.Run(); err != nil { - return err + if err := os.Chmod(dst, 0600); err != nil { + return fmt.Errorf("unable to set permissions on the ssh key: %s", err) } - return cmd.Run() -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.IPAddress, 22, "root", d.sshKeyPath(), args...), nil -} - -func (d *Driver) getClient() *godo.Client { - t := &oauth.Transport{ - Token: &oauth.Token{AccessToken: d.AccessToken}, - } - - return godo.NewClient(t.Client()) -} - -func (d *Driver) sshKeyPath() string { - return filepath.Join(d.storePath, "id_rsa") -} - -func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return nil } diff --git a/drivers/digitalocean/digitalocean_test.go b/drivers/digitalocean/digitalocean_test.go new file mode 100644 index 0000000000..4cb13378ff --- /dev/null +++ b/drivers/digitalocean/digitalocean_test.go @@ -0,0 +1,115 @@ +package digitalocean + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "digitalocean-access-token": "TOKEN", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) + + assert.Equal(t, driver.ResolveStorePath("id_rsa"), driver.GetSSHKeyPath()) +} + +func TestDefaultSSHUserAndPort(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "digitalocean-access-token": "TOKEN", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + + sshPort, err := driver.GetSSHPort() + assert.Equal(t, "root", driver.GetSSHUsername()) + assert.Equal(t, 22, sshPort) + assert.NoError(t, err) +} + +func TestCustomSSHUserAndPort(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "digitalocean-access-token": "TOKEN", + "digitalocean-ssh-user": "user", + "digitalocean-ssh-port": 2222, + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + + sshPort, err := driver.GetSSHPort() + assert.Equal(t, "user", driver.GetSSHUsername()) + assert.Equal(t, 2222, sshPort) + assert.NoError(t, err) +} + +func TestSSHKeyFingerprint(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "digitalocean-access-token": "TOKEN", + "digitalocean-ssh-key-fingerprint": "64:51:2b:9b:8b:f0:95:3c:f9:36:4d:8b:80:a8:8f:1e", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + + assert.Equal(t, "64:51:2b:9b:8b:f0:95:3c:f9:36:4d:8b:80:a8:8f:1e", driver.SSHKeyFingerprint) + assert.Equal(t, "", driver.GetSSHKeyPath()) +} + +func TestTags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "digitalocean-access-token": "TOKEN", + "digitalocean-tags": "docker,swarm, no-leading-space,,", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + assert.Equal(t, []string{"docker", "swarm", "no-leading-space"}, driver.getTags()) +} + +func TestTagsEmpty(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "digitalocean-access-token": "TOKEN", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + assert.Nil(t, driver.getTags()) +} diff --git a/drivers/drivers.go b/drivers/drivers.go deleted file mode 100644 index b9e71f83ec..0000000000 --- a/drivers/drivers.go +++ /dev/null @@ -1,146 +0,0 @@ -package drivers - -import ( - "errors" - "fmt" - "os/exec" - "sort" - - "github.com/codegangsta/cli" - "github.com/docker/machine/state" -) - -// Driver defines how a host is created and controlled. Different types of -// driver represent different ways hosts can be created (e.g. different -// hypervisors, different cloud providers) -type Driver interface { - // DriverName returns the name of the driver as it is registered - DriverName() string - - // SetConfigFromFlags configures the driver with the object that was returned - // by RegisterCreateFlags - SetConfigFromFlags(flags DriverOptions) error - - // GetURL returns a Docker compatible host URL for connecting to this host - // e.g. tcp://1.2.3.4:2376 - GetURL() (string, error) - - // GetIP returns an IP or hostname that this host is available at - // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net - GetIP() (string, error) - - // GetState returns the state that the host is in (running, stopped, etc) - GetState() (state.State, error) - - // PreCreate allows for pre-create operations to make sure a driver is ready for creation - PreCreateCheck() error - - // Create a host using the driver's config - Create() error - - // Remove a host - Remove() error - - // Start a host - Start() error - - // Stop a host gracefully - Stop() error - - // Restart a host. This may just call Stop(); Start() if the provider does not - // have any special restart behaviour. - Restart() error - - // Kill stops a host forcefully - Kill() error - - // RestartDocker restarts a Docker daemon on the machine - StartDocker() error - - // RestartDocker restarts a Docker daemon on the machine - StopDocker() error - - // Upgrade the version of Docker on the host to the latest version - Upgrade() error - - // GetDockerConfigDir returns the config directory for storing daemon configs - GetDockerConfigDir() string - - // GetSSHCommand returns a command for SSH pointing at the correct user, host - // and keys for the host with args appended. If no args are passed, it will - // initiate an interactive SSH session as if SSH were passed no args. - GetSSHCommand(args ...string) (*exec.Cmd, error) -} - -// RegisteredDriver is used to register a driver with the Register function. -// It has two attributes: -// - New: a function that returns a new driver given a path to store host -// configuration in -// - RegisterCreateFlags: a function that takes the FlagSet for -// "docker hosts create" and returns an object to pass to SetConfigFromFlags -type RegisteredDriver struct { - New func(machineName string, storePath string, caCert string, privateKey string) (Driver, error) - GetCreateFlags func() []cli.Flag -} - -var ErrHostIsNotRunning = errors.New("host is not running") - -var ( - drivers map[string]*RegisteredDriver -) - -func init() { - drivers = make(map[string]*RegisteredDriver) -} - -// Register a driver -func Register(name string, registeredDriver *RegisteredDriver) error { - if _, exists := drivers[name]; exists { - return fmt.Errorf("Name already registered %s", name) - } - - drivers[name] = registeredDriver - return nil -} - -// NewDriver creates a new driver of type "name" -func NewDriver(name string, machineName string, storePath string, caCert string, privateKey string) (Driver, error) { - driver, exists := drivers[name] - if !exists { - return nil, fmt.Errorf("hosts: Unknown driver %q", name) - } - return driver.New(machineName, storePath, caCert, privateKey) -} - -// GetCreateFlags runs GetCreateFlags for all of the drivers and -// returns their return values indexed by the driver name -func GetCreateFlags() []cli.Flag { - flags := []cli.Flag{} - - for driverName := range drivers { - driver := drivers[driverName] - for _, f := range driver.GetCreateFlags() { - flags = append(flags, f) - } - } - - sort.Sort(ByFlagName(flags)) - - return flags -} - -// GetDriverNames returns a slice of all registered driver names -func GetDriverNames() []string { - names := make([]string, 0, len(drivers)) - for k := range drivers { - names = append(names, k) - } - sort.Strings(names) - return names -} - -type DriverOptions interface { - String(key string) string - Int(key string) int - Bool(key string) bool -} diff --git a/drivers/drivers_test.go b/drivers/drivers_test.go deleted file mode 100644 index 031eb3d189..0000000000 --- a/drivers/drivers_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package drivers - -import ( - "testing" - - "github.com/codegangsta/cli" -) - -func TestGetCreateFlags(t *testing.T) { - Register("foo", &RegisteredDriver{ - New: func(machineName string, storePath string, caCert string, privateKey string) (Driver, error) { - return nil, nil - }, - GetCreateFlags: func() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ - Name: "a", - Value: "", - Usage: "", - EnvVar: "", - }, - cli.StringFlag{ - Name: "b", - Value: "", - Usage: "", - EnvVar: "", - }, - cli.StringFlag{ - Name: "c", - Value: "", - Usage: "", - EnvVar: "", - }, - } - }, - }) - Register("bar", &RegisteredDriver{ - New: func(machineName string, storePath string, caCert string, privateKey string) (Driver, error) { - return nil, nil - }, - GetCreateFlags: func() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ - Name: "d", - Value: "", - Usage: "", - EnvVar: "", - }, - cli.StringFlag{ - Name: "e", - Value: "", - Usage: "", - EnvVar: "", - }, - cli.StringFlag{ - Name: "f", - Value: "", - Usage: "", - EnvVar: "", - }, - } - }, - }) - - expected := []string{"-a \t", "-b \t", "-c \t", "-d \t", "-e \t", "-f \t"} - - // test a few times to catch offset issue - // if it crops up again - for i := 0; i < 5; i++ { - flags := GetCreateFlags() - for j, e := range expected { - if flags[j].String() != e { - t.Fatal("Flags are out of order") - } - } - } -} diff --git a/drivers/driverutil/util.go b/drivers/driverutil/util.go new file mode 100644 index 0000000000..a75bc85115 --- /dev/null +++ b/drivers/driverutil/util.go @@ -0,0 +1,13 @@ +package driverutil + +import "strings" + +// SplitPortProto splits a string in the format port/protocol, defaulting +// protocol to "tcp" if not provided. +func SplitPortProto(raw string) (port string, protocol string) { + parts := strings.SplitN(raw, "/", 2) + if len(parts) == 1 { + return parts[0], "tcp" + } + return parts[0], parts[1] +} diff --git a/drivers/driverutil/util_test.go b/drivers/driverutil/util_test.go new file mode 100644 index 0000000000..f442cc4a6b --- /dev/null +++ b/drivers/driverutil/util_test.go @@ -0,0 +1,25 @@ +package driverutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSplitPortProtocol(t *testing.T) { + tests := []struct { + raw string + expectedPort string + expectedProto string + }{ + {"8080/tcp", "8080", "tcp"}, + {"90/udp", "90", "udp"}, + {"80", "80", "tcp"}, + } + + for _, tc := range tests { + port, proto := SplitPortProto(tc.raw) + assert.Equal(t, tc.expectedPort, port) + assert.Equal(t, tc.expectedProto, proto) + } +} diff --git a/drivers/errdriver/error.go b/drivers/errdriver/error.go new file mode 100644 index 0000000000..532203771b --- /dev/null +++ b/drivers/errdriver/error.go @@ -0,0 +1,104 @@ +package errdriver + +import ( + "fmt" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" +) + +type Driver struct { + Name string +} + +type NotLoadable struct { + Name string +} + +func (e NotLoadable) Error() string { + return fmt.Sprintf("Driver %q not found. Do you have the plugin binary accessible in your PATH?", e.Name) +} + +func NewDriver(Name string) drivers.Driver { + return &Driver{ + Name: Name, + } +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "not-found" +} + +func (d *Driver) PreCreateCheck() error { + return NotLoadable{d.Name} +} + +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return nil +} + +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + return NotLoadable{d.Name} +} + +func (d *Driver) GetURL() (string, error) { + return "", NotLoadable{d.Name} +} + +func (d *Driver) GetMachineName() string { + return d.Name +} + +func (d *Driver) GetIP() (string, error) { + return "1.2.3.4", NotLoadable{d.Name} +} + +func (d *Driver) GetSSHHostname() (string, error) { + return "", NotLoadable{d.Name} +} + +func (d *Driver) GetSSHKeyPath() string { + return "" +} + +func (d *Driver) GetSSHPort() (int, error) { + return 0, NotLoadable{d.Name} +} + +func (d *Driver) GetSSHUsername() string { + return "" +} + +func (d *Driver) GetState() (state.State, error) { + return state.Error, NotLoadable{d.Name} +} + +func (d *Driver) Create() error { + return NotLoadable{d.Name} +} + +func (d *Driver) Remove() error { + return NotLoadable{d.Name} +} + +func (d *Driver) Start() error { + return NotLoadable{d.Name} +} + +func (d *Driver) Stop() error { + return NotLoadable{d.Name} +} + +func (d *Driver) Restart() error { + return NotLoadable{d.Name} +} + +func (d *Driver) Kill() error { + return NotLoadable{d.Name} +} + +func (d *Driver) Upgrade() error { + return NotLoadable{d.Name} +} diff --git a/drivers/exoscale/exoscale.go b/drivers/exoscale/exoscale.go new file mode 100644 index 0000000000..29d0747cf2 --- /dev/null +++ b/drivers/exoscale/exoscale.go @@ -0,0 +1,711 @@ +package exoscale + +import ( + "bytes" + "context" + "encoding/base64" + "errors" + "fmt" + "io/ioutil" + "net" + "os" + "os/user" + "path/filepath" + "regexp" + "strings" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/state" + "github.com/exoscale/egoscale" +) + +// Driver is the struct compatible with github.com/docker/machine/libmachine/drivers.Driver interface +type Driver struct { + *drivers.BaseDriver + URL string + APIKey string `json:"ApiKey"` + APISecretKey string `json:"ApiSecretKey"` + InstanceProfile string + DiskSize int64 + Image string + SecurityGroups []string + AffinityGroups []string + AvailabilityZone string + SSHKey string + KeyPair string + Password string + PublicKey string + UserDataFile string + UserData []byte + ID string `json:"Id"` +} + +const ( + defaultAPIEndpoint = "https://api.exoscale.ch/compute" + defaultInstanceProfile = "Small" + defaultDiskSize = 50 + defaultImage = "Linux Ubuntu 16.04 LTS 64-bit" + defaultAvailabilityZone = "CH-DK-2" + defaultSSHUser = "root" + defaultSecurityGroup = "docker-machine" + defaultAffinityGroupType = "host anti-affinity" + defaultCloudInit = `#cloud-config +manage_etc_hosts: localhost +` +) + +// GetCreateFlags registers the flags this driver adds to +// "docker hosts create" +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_ENDPOINT", + Name: "exoscale-url", + Usage: "exoscale API endpoint", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_API_KEY", + Name: "exoscale-api-key", + Usage: "exoscale API key", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_API_SECRET", + Name: "exoscale-api-secret-key", + Usage: "exoscale API secret key", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_INSTANCE_PROFILE", + Name: "exoscale-instance-profile", + Value: defaultInstanceProfile, + Usage: "exoscale instance profile (Small, Medium, Large, ...)", + }, + mcnflag.IntFlag{ + EnvVar: "EXOSCALE_DISK_SIZE", + Name: "exoscale-disk-size", + Value: defaultDiskSize, + Usage: "exoscale disk size (10, 50, 100, 200, 400)", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_IMAGE", + Name: "exoscale-image", + Value: defaultImage, + Usage: "exoscale image template", + }, + mcnflag.StringSliceFlag{ + EnvVar: "EXOSCALE_SECURITY_GROUP", + Name: "exoscale-security-group", + Value: []string{defaultSecurityGroup}, + Usage: "exoscale security group", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_AVAILABILITY_ZONE", + Name: "exoscale-availability-zone", + Value: defaultAvailabilityZone, + Usage: "exoscale availability zone", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_SSH_USER", + Name: "exoscale-ssh-user", + Value: "", + Usage: "name of the ssh user", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_SSH_KEY", + Name: "exoscale-ssh-key", + Value: "", + Usage: "path to the SSH user private key", + }, + mcnflag.StringFlag{ + EnvVar: "EXOSCALE_USERDATA", + Name: "exoscale-userdata", + Usage: "path to file with cloud-init user-data", + }, + mcnflag.StringSliceFlag{ + EnvVar: "EXOSCALE_AFFINITY_GROUP", + Name: "exoscale-affinity-group", + Value: []string{}, + Usage: "exoscale affinity group", + }, + } +} + +// NewDriver creates a Driver with the specified machineName and storePath. +func NewDriver(machineName, storePath string) drivers.Driver { + return &Driver{ + InstanceProfile: defaultInstanceProfile, + DiskSize: defaultDiskSize, + Image: defaultImage, + AvailabilityZone: defaultAvailabilityZone, + BaseDriver: &drivers.BaseDriver{ + MachineName: machineName, + StorePath: storePath, + }, + } +} + +// GetSSHHostname returns the hostname to use with SSH +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +// GetSSHUsername returns the username to use with SSH +func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + name := strings.ToLower(d.Image) + + if strings.Contains(name, "ubuntu") { + return "ubuntu" + } + if strings.Contains(name, "centos") { + return "centos" + } + if strings.Contains(name, "redhat") { + return "cloud-user" + } + if strings.Contains(name, "fedora") { + return "fedora" + } + if strings.Contains(name, "coreos") { + return "core" + } + if strings.Contains(name, "debian") { + return "debian" + } + return defaultSSHUser + } + + return d.SSHUser +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "exoscale" +} + +// SetConfigFromFlags configures the driver with the object that was returned +// by RegisterCreateFlags +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.URL = flags.String("exoscale-url") + d.APIKey = flags.String("exoscale-api-key") + d.APISecretKey = flags.String("exoscale-api-secret-key") + d.InstanceProfile = flags.String("exoscale-instance-profile") + d.DiskSize = int64(flags.Int("exoscale-disk-size")) + d.Image = flags.String("exoscale-image") + d.SecurityGroups = flags.StringSlice("exoscale-security-group") + d.AffinityGroups = flags.StringSlice("exoscale-affinity-group") + d.AvailabilityZone = flags.String("exoscale-availability-zone") + d.SSHUser = flags.String("exoscale-ssh-user") + d.SSHKey = flags.String("exoscale-ssh-key") + d.UserDataFile = flags.String("exoscale-userdata") + d.UserData = []byte(defaultCloudInit) + d.SetSwarmConfigFromFlags(flags) + + if d.URL == "" { + d.URL = defaultAPIEndpoint + } + if d.APIKey == "" || d.APISecretKey == "" { + return errors.New("missing an API key (--exoscale-api-key) or API secret key (--exoscale-api-secret-key)") + } + + return nil +} + +// PreCreateCheck allows for pre-create operations to make sure a driver is +// ready for creation +func (d *Driver) PreCreateCheck() error { + if d.UserDataFile != "" { + if _, err := os.Stat(d.UserDataFile); os.IsNotExist(err) { + return fmt.Errorf("user-data file %s could not be found", d.UserDataFile) + } + } + + return nil +} + +// GetURL returns a Docker compatible host URL for connecting to this host +// e.g tcp://10.1.2.3:2376 +func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } + + ip, err := d.GetIP() + if err != nil { + return "", err + } + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil +} + +func (d *Driver) client() *egoscale.Client { + return egoscale.NewClient(d.URL, d.APIKey, d.APISecretKey) +} + +func (d *Driver) virtualMachine() (*egoscale.VirtualMachine, error) { + cs := d.client() + virtualMachine := &egoscale.VirtualMachine{ + ID: d.ID, + } + + if err := cs.GetWithContext(context.TODO(), virtualMachine); err != nil { + return nil, err + } + + return virtualMachine, nil +} + +// GetState returns a github.com/machine/libmachine/state.State representing the state of the host (running, stopped, etc.) +func (d *Driver) GetState() (state.State, error) { + vm, err := d.virtualMachine() + if err != nil { + return state.Error, err + } + switch vm.State { + case "Starting": + return state.Starting, nil + case "Running": + return state.Running, nil + case "Stopping": + return state.Running, nil + case "Stopped": + return state.Stopped, nil + case "Destroyed": + return state.Stopped, nil + case "Expunging": + return state.Stopped, nil + case "Migrating": + return state.Paused, nil + case "Error": + return state.Error, nil + case "Unknown": + return state.Error, nil + case "Shutdowned": + return state.Stopped, nil + } + return state.None, nil +} + +func (d *Driver) createDefaultSecurityGroup(group string) (*egoscale.SecurityGroup, error) { + cs := d.client() + resp, err := cs.RequestWithContext(context.TODO(), &egoscale.CreateSecurityGroup{ + Name: group, + Description: "created by docker-machine", + }) + if err != nil { + return nil, err + } + sg := resp.(*egoscale.CreateSecurityGroupResponse).SecurityGroup + + requests := []egoscale.AuthorizeSecurityGroupIngress{ + { + SecurityGroupID: sg.ID, + Description: "SSH", + CidrList: []string{"0.0.0.0/0"}, + Protocol: "TCP", + StartPort: 22, + EndPort: 22, + }, + { + SecurityGroupID: sg.ID, + Description: "Ping", + CidrList: []string{"0.0.0.0/0"}, + Protocol: "ICMP", + IcmpType: 8, + IcmpCode: 0, + }, + { + SecurityGroupID: sg.ID, + Description: "Docker", + CidrList: []string{"0.0.0.0/0"}, + Protocol: "TCP", + StartPort: 2376, + EndPort: 2377, + }, + { + SecurityGroupID: sg.ID, + Description: "Legacy Standalone Swarm", + CidrList: []string{"0.0.0.0/0"}, + Protocol: "TCP", + StartPort: 3376, + EndPort: 3377, + }, + { + SecurityGroupID: sg.ID, + Description: "Communication among nodes", + Protocol: "TCP", + StartPort: 7946, + EndPort: 7946, + UserSecurityGroupList: []egoscale.UserSecurityGroup{{ + Group: sg.Name, + Account: sg.Account, + }}, + }, + { + SecurityGroupID: sg.ID, + Description: "Communication among nodes", + Protocol: "UDP", + StartPort: 7946, + EndPort: 7946, + UserSecurityGroupList: []egoscale.UserSecurityGroup{{ + Group: sg.Name, + Account: sg.Account, + }}, + }, + { + SecurityGroupID: sg.ID, + Description: "Overlay network traffic", + Protocol: "UDP", + StartPort: 4789, + EndPort: 4789, + UserSecurityGroupList: []egoscale.UserSecurityGroup{{ + Group: sg.Name, + Account: sg.Account, + }}, + }, + } + + for _, req := range requests { + _, err := cs.RequestWithContext(context.TODO(), &req) + if err != nil { + return nil, err + } + } + + return &sg, nil +} + +func (d *Driver) createDefaultAffinityGroup(group string) (*egoscale.AffinityGroup, error) { + cs := d.client() + resp, err := cs.RequestWithContext(context.TODO(), &egoscale.CreateAffinityGroup{ + Name: group, + Type: defaultAffinityGroupType, + Description: "created by docker-machine", + }) + + if err != nil { + return nil, err + } + + affinityGroup := resp.(*egoscale.CreateAffinityGroupResponse).AffinityGroup + return &affinityGroup, nil +} + +// Create creates the VM instance acting as the docker host +func (d *Driver) Create() error { + cloudInit, err := d.getCloudInit() + if err != nil { + return err + } + + log.Infof("Querying exoscale for the requested parameters...") + client := egoscale.NewClient(d.URL, d.APIKey, d.APISecretKey) + + resp, err := client.RequestWithContext(context.TODO(), &egoscale.ListZones{ + Name: d.AvailabilityZone, + }) + if err != nil { + return err + } + + zones := resp.(*egoscale.ListZonesResponse) + if len(zones.Zone) != 1 { + return fmt.Errorf("Availability zone %v doesn't exist", + d.AvailabilityZone) + } + zone := zones.Zone[0].ID + log.Debugf("Availability zone %v = %s", d.AvailabilityZone, zone) + + // Image + template := egoscale.Template{ + IsFeatured: true, + ZoneID: "1", // GVA2 + } + + templates, err := client.ListWithContext(context.TODO(), &template) + if err != nil { + return err + } + + image := strings.ToLower(d.Image) + re := regexp.MustCompile(`^Linux (?P.+?) (?P[0-9.]+)\b`) + + for _, t := range templates { + tpl := t.(*egoscale.Template) + + // Keep only 10GiB images + if tpl.Size>>30 != 10 { + continue + } + + fullname := strings.ToLower(tpl.Name) + if image == fullname { + template = *tpl + break + } + + submatch := re.FindStringSubmatch(tpl.Name) + if len(submatch) > 0 { + name := strings.Replace(strings.ToLower(submatch[1]), " ", "-", -1) + version := submatch[2] + shortname := fmt.Sprintf("%s-%s", name, version) + + if image == shortname { + template = *tpl + break + } + } + } + if template.ID == "" { + return fmt.Errorf("Unable to find image %v", d.Image) + } + + // Reading the username from the template + if name, ok := template.Details["username"]; ok { + d.SSHUser = name + } + log.Debugf("Image %v(10) = %s (%s)", d.Image, template.ID, d.SSHUser) + + // Profile UUID + resp, err = client.RequestWithContext(context.TODO(), &egoscale.ListServiceOfferings{ + Name: d.InstanceProfile, + }) + if err != nil { + return err + } + profiles := resp.(*egoscale.ListServiceOfferingsResponse) + if len(profiles.ServiceOffering) != 1 { + return fmt.Errorf("Unable to find the %s profile", + d.InstanceProfile) + } + profile := profiles.ServiceOffering[0].ID + log.Debugf("Profile %v = %s", d.InstanceProfile, profile) + + // Security groups + sgs := make([]string, 0, len(d.SecurityGroups)) + for _, group := range d.SecurityGroups { + if group == "" { + continue + } + + sg := &egoscale.SecurityGroup{Name: group} + if err := client.Get(sg); err != nil { + if _, ok := err.(*egoscale.ErrorResponse); !ok { + return err + } + log.Infof("Security group %v does not exist. Creating it...", group) + securityGroup, err := d.createDefaultSecurityGroup(group) + if err != nil { + return err + } + sg.ID = securityGroup.ID + } + + log.Debugf("Security group %v = %s", group, sg.ID) + sgs = append(sgs, sg.ID) + } + + // Affinity Groups + ags := make([]string, 0, len(d.AffinityGroups)) + for _, group := range d.AffinityGroups { + if group == "" { + continue + } + ag := &egoscale.AffinityGroup{Name: group} + if err := client.Get(ag); err != nil { + if _, ok := err.(*egoscale.ErrorResponse); !ok { + return err + } + log.Infof("Affinity Group %v does not exist, create it", group) + affinityGroup, err := d.createDefaultAffinityGroup(group) + if err != nil { + return err + } + ag.ID = affinityGroup.ID + } + log.Debugf("Affinity group %v = %s", group, ag.ID) + ags = append(ags, ag.ID) + } + + // SSH key pair + if d.SSHKey == "" { + var keyPairName string + keyPairName = fmt.Sprintf("docker-machine-%s", d.MachineName) + log.Infof("Generate an SSH keypair...") + resp, err := client.RequestWithContext(context.TODO(), &egoscale.CreateSSHKeyPair{ + Name: keyPairName, + }) + if err != nil { + return fmt.Errorf("SSH Key pair creation failed %s", err) + } + keyPair := resp.(*egoscale.CreateSSHKeyPairResponse).KeyPair + if err = os.MkdirAll(filepath.Dir(d.GetSSHKeyPath()), 0750); err != nil { + return fmt.Errorf("Cannot create the folder to store the SSH private key. %s", err) + } + if err = ioutil.WriteFile(d.GetSSHKeyPath(), []byte(keyPair.PrivateKey), 0600); err != nil { + return fmt.Errorf("SSH private key could not be written. %s", err) + } + d.KeyPair = keyPairName + } else { + log.Infof("Importing SSH key from %s", d.SSHKey) + + sshKey := d.SSHKey + if strings.HasPrefix(sshKey, "~/") { + usr, _ := user.Current() + sshKey = filepath.Join(usr.HomeDir, sshKey[2:]) + } else { + var err error + if sshKey, err = filepath.Abs(sshKey); err != nil { + return err + } + } + + // Sending the SSH public key through the cloud-init config + pubKey, err := ioutil.ReadFile(sshKey + ".pub") + if err != nil { + return fmt.Errorf("Cannot read SSH public key %s", err) + } + + sshAuthorizedKeys := ` +ssh_authorized_keys: +- ` + cloudInit = bytes.Join([][]byte{cloudInit, []byte(sshAuthorizedKeys), pubKey}, []byte("")) + + // Copying the private key into docker-machine + if err := mcnutils.CopyFile(sshKey, d.GetSSHKeyPath()); err != nil { + return fmt.Errorf("Unable to copy SSH file: %s", err) + } + if err := os.Chmod(d.GetSSHKeyPath(), 0600); err != nil { + return fmt.Errorf("Unable to set permissions on the SSH file: %s", err) + } + } + + log.Infof("Spawn exoscale host...") + log.Debugf("Using the following cloud-init file:") + log.Debugf("%s", string(cloudInit)) + + // Base64 encode the userdata + d.UserData = cloudInit + encodedUserData := base64.StdEncoding.EncodeToString(d.UserData) + + req := &egoscale.DeployVirtualMachine{ + TemplateID: template.ID, + ServiceOfferingID: profile, + UserData: encodedUserData, + ZoneID: zone, + Name: d.MachineName, + KeyPair: d.KeyPair, + DisplayName: d.MachineName, + RootDiskSize: d.DiskSize, + SecurityGroupIDs: sgs, + AffinityGroupIDs: ags, + } + log.Infof("Deploy %#v", req) + resp, err = client.RequestWithContext(context.TODO(), req) + if err != nil { + return err + } + + vm := resp.(*egoscale.DeployVirtualMachineResponse).VirtualMachine + + IPAddress := vm.Nic[0].IPAddress + if IPAddress != nil { + d.IPAddress = IPAddress.String() + } + d.ID = vm.ID + log.Infof("IP Address: %v, SSH User: %v", d.IPAddress, d.GetSSHUsername()) + + if vm.PasswordEnabled { + d.Password = vm.Password + } + + // Destroy the SSH key from CloudStack + if d.KeyPair != "" { + if err := drivers.WaitForSSH(d); err != nil { + return err + } + + key := &egoscale.SSHKeyPair{ + Name: d.KeyPair, + } + if err := client.DeleteWithContext(context.TODO(), key); err != nil { + return err + } + d.KeyPair = "" + } + + return nil +} + +// Start starts the existing VM instance. +func (d *Driver) Start() error { + cs := d.client() + _, err := cs.RequestWithContext(context.TODO(), &egoscale.StartVirtualMachine{ + ID: d.ID, + }) + + return err +} + +// Stop stops the existing VM instance. +func (d *Driver) Stop() error { + cs := d.client() + _, err := cs.RequestWithContext(context.TODO(), &egoscale.StopVirtualMachine{ + ID: d.ID, + }) + + return err +} + +// Restart reboots the existing VM instance. +func (d *Driver) Restart() error { + cs := d.client() + _, err := cs.RequestWithContext(context.TODO(), &egoscale.RebootVirtualMachine{ + ID: d.ID, + }) + + return err +} + +// Kill stops a host forcefully (same as Stop) +func (d *Driver) Kill() error { + return d.Stop() +} + +// Remove destroys the VM instance and the associated SSH key. +func (d *Driver) Remove() error { + client := d.client() + + // Destroy the SSH key from CloudStack + if d.KeyPair != "" { + key := &egoscale.SSHKeyPair{Name: d.KeyPair} + if err := client.DeleteWithContext(context.TODO(), key); err != nil { + return err + } + } + + // Destroy the virtual machine + if d.ID != "" { + vm := &egoscale.VirtualMachine{ID: d.ID} + if err := client.DeleteWithContext(context.TODO(), vm); err != nil { + return err + } + } + + log.Infof("The Anti-Affinity group and Security group were not removed") + + return nil +} + +// Build a cloud-init user data string that will install and run +// docker. +func (d *Driver) getCloudInit() ([]byte, error) { + var err error + if d.UserDataFile != "" { + d.UserData, err = ioutil.ReadFile(d.UserDataFile) + } + + return d.UserData, err +} diff --git a/drivers/exoscale/exoscale_test.go b/drivers/exoscale/exoscale_test.go new file mode 100644 index 0000000000..0638f3cc0c --- /dev/null +++ b/drivers/exoscale/exoscale_test.go @@ -0,0 +1,25 @@ +package exoscale + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "exoscale-api-key": "API_KEY", + "exoscale-api-secret-key": "API_SECRET_KEY", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/fakedriver/fakedriver.go b/drivers/fakedriver/fakedriver.go new file mode 100644 index 0000000000..953db88df2 --- /dev/null +++ b/drivers/fakedriver/fakedriver.go @@ -0,0 +1,109 @@ +package fakedriver + +import ( + "fmt" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" +) + +type Driver struct { + *drivers.BaseDriver + MockState state.State + MockIP string + MockName string +} + +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{} +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "Driver" +} + +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + return nil +} + +func (d *Driver) GetURL() (string, error) { + ip, err := d.GetIP() + if err != nil { + return "", err + } + if ip == "" { + return "", nil + } + return fmt.Sprintf("tcp://%s:2376", ip), nil +} + +func (d *Driver) GetMachineName() string { + return d.MockName +} + +func (d *Driver) GetIP() (string, error) { + if d.MockState == state.Error { + return "", fmt.Errorf("Unable to get ip") + } + if d.MockState == state.Timeout { + select {} // Loop forever + } + if d.MockState != state.Running { + return "", drivers.ErrHostIsNotRunning + } + return d.MockIP, nil +} + +func (d *Driver) GetSSHHostname() (string, error) { + return "", nil +} + +func (d *Driver) GetSSHKeyPath() string { + return "" +} + +func (d *Driver) GetSSHPort() (int, error) { + return 0, nil +} + +func (d *Driver) GetSSHUsername() string { + return "" +} + +func (d *Driver) GetState() (state.State, error) { + return d.MockState, nil +} + +func (d *Driver) Create() error { + return nil +} + +func (d *Driver) Start() error { + d.MockState = state.Running + return nil +} + +func (d *Driver) Stop() error { + d.MockState = state.Stopped + return nil +} + +func (d *Driver) Restart() error { + d.MockState = state.Running + return nil +} + +func (d *Driver) Kill() error { + d.MockState = state.Stopped + return nil +} + +func (d *Driver) Remove() error { + return nil +} + +func (d *Driver) Upgrade() error { + return nil +} diff --git a/drivers/generic/generic.go b/drivers/generic/generic.go new file mode 100644 index 0000000000..f51f3bf384 --- /dev/null +++ b/drivers/generic/generic.go @@ -0,0 +1,196 @@ +package generic + +import ( + "errors" + "fmt" + "net" + "os" + "path" + "strconv" + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/state" +) + +type Driver struct { + *drivers.BaseDriver + EnginePort int + SSHKey string +} + +const ( + defaultTimeout = 15 * time.Second +) + +// GetCreateFlags registers the flags this driver adds to +// "docker hosts create" +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.IntFlag{ + Name: "generic-engine-port", + Usage: "Docker engine port", + Value: engine.DefaultPort, + EnvVar: "GENERIC_ENGINE_PORT", + }, + mcnflag.StringFlag{ + Name: "generic-ip-address", + Usage: "IP Address of machine", + EnvVar: "GENERIC_IP_ADDRESS", + }, + mcnflag.StringFlag{ + Name: "generic-ssh-user", + Usage: "SSH user", + Value: drivers.DefaultSSHUser, + EnvVar: "GENERIC_SSH_USER", + }, + mcnflag.StringFlag{ + Name: "generic-ssh-key", + Usage: "SSH private key path (if not provided, default SSH key will be used)", + Value: "", + EnvVar: "GENERIC_SSH_KEY", + }, + mcnflag.IntFlag{ + Name: "generic-ssh-port", + Usage: "SSH port", + Value: drivers.DefaultSSHPort, + EnvVar: "GENERIC_SSH_PORT", + }, + } +} + +// NewDriver creates and returns a new instance of the driver +func NewDriver(hostName, storePath string) drivers.Driver { + return &Driver{ + EnginePort: engine.DefaultPort, + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + } +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "generic" +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetSSHKeyPath() string { + return d.SSHKeyPath +} + +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.EnginePort = flags.Int("generic-engine-port") + d.IPAddress = flags.String("generic-ip-address") + d.SSHUser = flags.String("generic-ssh-user") + d.SSHKey = flags.String("generic-ssh-key") + d.SSHPort = flags.Int("generic-ssh-port") + + if d.IPAddress == "" { + return errors.New("generic driver requires the --generic-ip-address option") + } + + return nil +} + +func (d *Driver) PreCreateCheck() error { + if d.SSHKey != "" { + if _, err := os.Stat(d.SSHKey); os.IsNotExist(err) { + return fmt.Errorf("SSH key does not exist: %q", d.SSHKey) + } + + // TODO: validate the key is a valid key + } + + return nil +} + +func (d *Driver) Create() error { + if d.SSHKey == "" { + log.Info("No SSH key specified. Assuming an existing key at the default location.") + } else { + log.Info("Importing SSH key...") + + d.SSHKeyPath = d.ResolveStorePath(path.Base(d.SSHKey)) + if err := copySSHKey(d.SSHKey, d.SSHKeyPath); err != nil { + return err + } + + if err := copySSHKey(d.SSHKey+".pub", d.SSHKeyPath+".pub"); err != nil { + log.Infof("Couldn't copy SSH public key : %s", err) + } + } + + log.Debugf("IP: %s", d.IPAddress) + + return nil +} + +func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } + + ip, err := d.GetIP() + if err != nil { + return "", err + } + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, strconv.Itoa(d.EnginePort))), nil +} + +func (d *Driver) GetState() (state.State, error) { + address := net.JoinHostPort(d.IPAddress, strconv.Itoa(d.SSHPort)) + + _, err := net.DialTimeout("tcp", address, defaultTimeout) + if err != nil { + return state.Stopped, nil + } + + return state.Running, nil +} + +func (d *Driver) Start() error { + return errors.New("generic driver does not support start") +} + +func (d *Driver) Stop() error { + return errors.New("generic driver does not support stop") +} + +func (d *Driver) Restart() error { + _, err := drivers.RunSSHCommandFromDriver(d, "sudo shutdown -r now") + return err +} + +func (d *Driver) Kill() error { + return errors.New("generic driver does not support kill") +} + +func (d *Driver) Remove() error { + return nil +} + +func copySSHKey(src, dst string) error { + if err := mcnutils.CopyFile(src, dst); err != nil { + return fmt.Errorf("unable to copy ssh key: %s", err) + } + + if err := os.Chmod(dst, 0600); err != nil { + return fmt.Errorf("unable to set permissions on the ssh key: %s", err) + } + + return nil +} diff --git a/drivers/generic/generic_test.go b/drivers/generic/generic_test.go new file mode 100644 index 0000000000..93caa797c1 --- /dev/null +++ b/drivers/generic/generic_test.go @@ -0,0 +1,26 @@ +package generic + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "generic-engine-port": "3000", + "generic-ip-address": "localhost", + "generic-ssh-key": "path", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/google/auth_util.go b/drivers/google/auth_util.go deleted file mode 100644 index 2bbb633437..0000000000 --- a/drivers/google/auth_util.go +++ /dev/null @@ -1,121 +0,0 @@ -package google - -import ( - "encoding/gob" - "fmt" - "net/http" - "os" - "os/exec" - "path" - "strings" - "time" - - "code.google.com/p/goauth2/oauth" - log "github.com/Sirupsen/logrus" - raw "google.golang.org/api/compute/v1" -) - -const ( - AuthURL = "https://accounts.google.com/o/oauth2/auth" - TokenURL = "https://accounts.google.com/o/oauth2/token" - ClientId = "22738965389-8arp8bah3uln9eoenproamovfjj1ac33.apps.googleusercontent.com" - ClientSecret = "qApc3amTyr5wI74vVrRWAfC_" - RedirectURI = "urn:ietf:wg:oauth:2.0:oob" -) - -func newGCEService(storePath string) (*raw.Service, error) { - client := newOauthClient(storePath) - service, err := raw.New(client) - return service, err -} - -func newOauthClient(storePath string) *http.Client { - config := &oauth.Config{ - ClientId: ClientId, - ClientSecret: ClientSecret, - Scope: raw.ComputeScope, - AuthURL: AuthURL, - TokenURL: TokenURL, - } - token := token(storePath, config) - t := oauth.Transport{ - Token: token, - Config: config, - Transport: http.DefaultTransport, - } - return t.Client() -} - -func token(storePath string, config *oauth.Config) *oauth.Token { - token, err := tokenFromCache(storePath) - if err != nil { - token = tokenFromWeb(config) - saveToken(storePath, token) - } - return token -} - -func tokenFromCache(storePath string) (*oauth.Token, error) { - tokenPath := path.Join(storePath, "gce_token") - f, err := os.Open(tokenPath) - if err != nil { - return nil, err - } - token := new(oauth.Token) - err = gob.NewDecoder(f).Decode(token) - return token, err -} - -func tokenFromWeb(config *oauth.Config) *oauth.Token { - randState := fmt.Sprintf("st%d", time.Now().UnixNano()) - - config.RedirectURL = RedirectURI - authURL := config.AuthCodeURL(randState) - - log.Info("Opening auth URL in browser.") - log.Info(authURL) - log.Info("If the URL doesn't open please open it manually and copy the code here.") - openURL(authURL) - code := getCodeFromStdin() - - log.Infof("Got code: %s", code) - - t := &oauth.Transport{ - Config: config, - Transport: http.DefaultTransport, - } - _, err := t.Exchange(code) - if err != nil { - log.Fatalf("Token exchange error: %v", err) - } - return t.Token -} - -func getCodeFromStdin() string { - fmt.Print("Enter code: ") - var code string - fmt.Scanln(&code) - return strings.Trim(code, "\n") -} - -func openURL(url string) { - try := []string{"xdg-open", "google-chrome", "open"} - for _, bin := range try { - err := exec.Command(bin, url).Run() - if err == nil { - return - } - } -} - -func saveToken(storePath string, token *oauth.Token) { - tokenPath := path.Join(storePath, "gce_token") - log.Infof("Saving token in %v", tokenPath) - f, err := os.Create(tokenPath) - if err != nil { - log.Infof("Warning: failed to cache oauth token: %v", err) - return - } - defer f.Close() - gob.NewEncoder(f).Encode(token) -} diff --git a/drivers/google/compute_util.go b/drivers/google/compute_util.go index 6612737eb9..e095bab0c0 100644 --- a/drivers/google/compute_util.go +++ b/drivers/google/compute_util.go @@ -3,103 +3,227 @@ package google import ( "fmt" "io/ioutil" + "net/http" + "net/url" + "regexp" + "strings" "time" - log "github.com/Sirupsen/logrus" - "github.com/docker/machine/ssh" + "github.com/docker/machine/drivers/driverutil" + "github.com/docker/machine/libmachine/log" raw "google.golang.org/api/compute/v1" + + "errors" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/api/googleapi" ) // ComputeUtil is used to wrap the raw GCE API code and store common parameters. type ComputeUtil struct { - zone string - instanceName string - userName string - project string - service *raw.Service - zoneURL string - globalURL string - ipAddress string + zone string + instanceName string + userName string + project string + diskTypeURL string + address string + network string + subnetwork string + preemptible bool + useInternalIP bool + useInternalIPOnly bool + service *raw.Service + zoneURL string + globalURL string + SwarmMaster bool + SwarmHost string + openPorts []string } const ( - apiURL = "https://www.googleapis.com/compute/v1/projects/" - //imageName = "https://www.googleapis.com/compute/v1/projects/google-containers/global/images/container-vm-v20141016" - imageName = "https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/ubuntu-1404-trusty-v20141212" - firewallRule = "docker-machines" - port = "2376" - firewallTargetTag = "docker-machine" - dockerStartCommand = "sudo service docker start" - dockerStopCommand = "sudo service docker stop" + apiURL = "https://www.googleapis.com/compute/v1/projects/" + firewallRule = "docker-machines" + dockerPort = "2376" + firewallTargetTag = "docker-machine" ) -const () - // NewComputeUtil creates and initializes a ComputeUtil. func newComputeUtil(driver *Driver) (*ComputeUtil, error) { - service, err := newGCEService(driver.storePath) + client, err := google.DefaultClient(oauth2.NoContext, raw.ComputeScope) if err != nil { return nil, err } - c := ComputeUtil{ - zone: driver.Zone, - instanceName: driver.MachineName, - userName: driver.UserName, - project: driver.Project, - service: service, - zoneURL: apiURL + driver.Project + "/zones/" + driver.Zone, - globalURL: apiURL + driver.Project + "/global", + + service, err := raw.New(client) + if err != nil { + return nil, err } - return &c, nil + + return &ComputeUtil{ + zone: driver.Zone, + instanceName: driver.MachineName, + userName: driver.SSHUser, + project: driver.Project, + diskTypeURL: driver.DiskType, + address: driver.Address, + network: driver.Network, + subnetwork: driver.Subnetwork, + preemptible: driver.Preemptible, + useInternalIP: driver.UseInternalIP, + useInternalIPOnly: driver.UseInternalIPOnly, + service: service, + zoneURL: apiURL + driver.Project + "/zones/" + driver.Zone, + globalURL: apiURL + driver.Project + "/global", + SwarmMaster: driver.SwarmMaster, + SwarmHost: driver.SwarmHost, + openPorts: driver.OpenPorts, + }, nil } func (c *ComputeUtil) diskName() string { return c.instanceName + "-disk" } -// disk returns the gce Disk. +func (c *ComputeUtil) diskType() string { + return apiURL + c.project + "/zones/" + c.zone + "/diskTypes/" + c.diskTypeURL +} + +// disk returns the persistent disk attached to the vm. func (c *ComputeUtil) disk() (*raw.Disk, error) { return c.service.Disks.Get(c.project, c.zone, c.diskName()).Do() } // deleteDisk deletes the persistent disk. func (c *ComputeUtil) deleteDisk() error { + disk, _ := c.disk() + if disk == nil { + return nil + } + log.Infof("Deleting disk.") op, err := c.service.Disks.Delete(c.project, c.zone, c.diskName()).Do() if err != nil { return err } + log.Infof("Waiting for disk to delete.") return c.waitForRegionalOp(op.Name) } +// staticAddress returns the external static IP address. +func (c *ComputeUtil) staticAddress() (string, error) { + // is the address a name? + isName, err := regexp.MatchString("[a-z]([-a-z0-9]*[a-z0-9])?", c.address) + if err != nil { + return "", err + } + + if !isName { + return c.address, nil + } + + // resolve the address by name + externalAddress, err := c.service.Addresses.Get(c.project, c.region(), c.address).Do() + if err != nil { + return "", err + } + + return externalAddress.Address, nil +} + +func (c *ComputeUtil) region() string { + return c.zone[:len(c.zone)-2] +} + func (c *ComputeUtil) firewallRule() (*raw.Firewall, error) { return c.service.Firewalls.Get(c.project, firewallRule).Do() } -func (c *ComputeUtil) createFirewallRule() error { - log.Infof("Creating firewall rule.") - rule := &raw.Firewall{ - Allowed: []*raw.FirewallAllowed{ - { - IPProtocol: "tcp", - Ports: []string{ - port, - }, - }, - }, - SourceRanges: []string{ - "0.0.0.0/0", - }, - TargetTags: []string{ - firewallTargetTag, - }, - Name: firewallRule, +func missingOpenedPorts(rule *raw.Firewall, ports []string) map[string][]string { + missing := map[string][]string{} + opened := map[string]bool{} + + for _, allowed := range rule.Allowed { + for _, allowedPort := range allowed.Ports { + opened[allowedPort+"/"+allowed.IPProtocol] = true + } } - op, err := c.service.Firewalls.Insert(c.project, rule).Do() + + for _, p := range ports { + port, proto := driverutil.SplitPortProto(p) + if !opened[port+"/"+proto] { + missing[proto] = append(missing[proto], port) + } + } + + return missing +} + +func (c *ComputeUtil) portsUsed() ([]string, error) { + ports := []string{dockerPort + "/tcp"} + + if c.SwarmMaster { + u, err := url.Parse(c.SwarmHost) + if err != nil { + return nil, fmt.Errorf("error authorizing port for swarm: %s", err) + } + + swarmPort := strings.Split(u.Host, ":")[1] + ports = append(ports, swarmPort+"/tcp") + } + for _, p := range c.openPorts { + port, proto := driverutil.SplitPortProto(p) + ports = append(ports, port+"/"+proto) + } + + return ports, nil +} + +// openFirewallPorts configures the firewall to open docker and swarm ports. +func (c *ComputeUtil) openFirewallPorts(d *Driver) error { + log.Infof("Opening firewall ports") + + create := false + rule, _ := c.firewallRule() + if rule == nil { + create = true + rule = &raw.Firewall{ + Name: firewallRule, + Allowed: []*raw.FirewallAllowed{}, + SourceRanges: []string{"0.0.0.0/0"}, + TargetTags: []string{firewallTargetTag}, + Network: c.globalURL + "/networks/" + d.Network, + } + } + + portsUsed, err := c.portsUsed() + if err != nil { + return err + } + + missingPorts := missingOpenedPorts(rule, portsUsed) + if len(missingPorts) == 0 { + return nil + } + for proto, ports := range missingPorts { + rule.Allowed = append(rule.Allowed, &raw.FirewallAllowed{ + IPProtocol: proto, + Ports: ports, + }) + } + + var op *raw.Operation + if create { + op, err = c.service.Firewalls.Insert(c.project, rule).Do() + } else { + op, err = c.service.Firewalls.Update(c.project, firewallRule, rule).Do() + } + if err != nil { return err } + return c.waitForGlobalOp(op.Name) } @@ -110,12 +234,13 @@ func (c *ComputeUtil) instance() (*raw.Instance, error) { // createInstance creates a GCE VM instance. func (c *ComputeUtil) createInstance(d *Driver) error { - log.Infof("Creating instance.") - // The rule will either exist or be nil in case of an error. - if rule, _ := c.firewallRule(); rule == nil { - if err := c.createFirewallRule(); err != nil { - return err - } + log.Infof("Creating instance") + + var net string + if strings.Contains(d.Network, "/networks/") { + net = d.Network + } else { + net = c.globalURL + "/networks/" + d.Network } instance := &raw.Instance{ @@ -125,30 +250,60 @@ func (c *ComputeUtil) createInstance(d *Driver) error { Disks: []*raw.AttachedDisk{ { Boot: true, - AutoDelete: false, + AutoDelete: true, Type: "PERSISTENT", Mode: "READ_WRITE", }, }, NetworkInterfaces: []*raw.NetworkInterface{ { - AccessConfigs: []*raw.AccessConfig{ - {Type: "ONE_TO_ONE_NAT"}, - }, - Network: c.globalURL + "/networks/default", + Network: net, }, }, Tags: &raw.Tags{ - Items: []string{ - firewallTargetTag, + Items: parseTags(d), + }, + ServiceAccounts: []*raw.ServiceAccount{ + { + Email: d.ServiceAccount, + Scopes: strings.Split(d.Scopes, ","), }, }, + Scheduling: &raw.Scheduling{ + Preemptible: c.preemptible, + }, } + + if strings.Contains(c.subnetwork, "/subnetworks/") { + instance.NetworkInterfaces[0].Subnetwork = c.subnetwork + } else if c.subnetwork != "" { + instance.NetworkInterfaces[0].Subnetwork = "projects/" + c.project + "/regions/" + c.region() + "/subnetworks/" + c.subnetwork + } + + if !c.useInternalIPOnly { + cfg := &raw.AccessConfig{ + Type: "ONE_TO_ONE_NAT", + } + instance.NetworkInterfaces[0].AccessConfigs = append(instance.NetworkInterfaces[0].AccessConfigs, cfg) + } + + if c.address != "" { + staticAddress, err := c.staticAddress() + if err != nil { + return err + } + + instance.NetworkInterfaces[0].AccessConfigs[0].NatIP = staticAddress + } + disk, err := c.disk() if disk == nil || err != nil { instance.Disks[0].InitializeParams = &raw.AttachedDiskInitializeParams{ DiskName: c.diskName(), - SourceImage: imageName, + SourceImage: "https://www.googleapis.com/compute/v1/projects/" + d.MachineImage, + // The maximum supported disk size is 1000GB, the cast should be fine. + DiskSizeGb: int64(d.DiskSize), + DiskType: c.diskType(), } } else { instance.Disks[0].Source = c.zoneURL + "/disks/" + c.instanceName + "-disk" @@ -158,7 +313,8 @@ func (c *ComputeUtil) createInstance(d *Driver) error { if err != nil { return err } - log.Infof("Waiting for Instance...") + + log.Infof("Waiting for Instance") if err = c.waitForRegionalOp(op.Name); err != nil { return err } @@ -167,77 +323,80 @@ func (c *ComputeUtil) createInstance(d *Driver) error { if err != nil { return err } - ip := instance.NetworkInterfaces[0].AccessConfigs[0].NatIP - c.waitForSSH(ip) - // Update the SSH Key - sshKey, err := ioutil.ReadFile(d.publicSSHKeyPath) - if err != nil { - return err - } - log.Infof("Uploading SSH Key") - op, err = c.service.Instances.SetMetadata(c.project, c.zone, c.instanceName, &raw.Metadata{ - Fingerprint: instance.Metadata.Fingerprint, - Items: []*raw.MetadataItems{ - { - Key: "sshKeys", - Value: c.userName + ":" + string(sshKey) + "\n", - }, - }, - }).Do() - if err != nil { - return err - } - log.Infof("Waiting for SSH Key") - err = c.waitForRegionalOp(op.Name) - if err != nil { - return err - } + return c.uploadSSHKey(instance, d.GetSSHKeyPath()) +} - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) +// configureInstance configures an existing instance for use with Docker Machine. +func (c *ComputeUtil) configureInstance(d *Driver) error { + log.Infof("Configuring instance") + instance, err := c.instance() if err != nil { return err } - if err := cmd.Run(); err != nil { + + if err := c.addFirewallTag(instance); err != nil { return err } - log.Debugf("Installing Docker") + return c.uploadSSHKey(instance, d.GetSSHKeyPath()) +} - cmd, err = d.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl -sL https://get.docker.com | sudo sh -; fi") - if err != nil { - return err +// addFirewallTag adds a tag to the instance to match the firewall rule. +func (c *ComputeUtil) addFirewallTag(instance *raw.Instance) error { + log.Infof("Adding tag for the firewall rule") + tags := instance.Tags + for _, tag := range tags.Items { + if tag == firewallTargetTag { + return nil + } } - if err := cmd.Run(); err != nil { - return err + tags.Items = append(tags.Items, firewallTargetTag) + + op, err := c.service.Instances.SetTags(c.project, c.zone, instance.Name, tags).Do() + if err != nil { + return err } - return nil + return c.waitForRegionalOp(op.Name) } -func (c *ComputeUtil) updateDocker(d *Driver) error { - log.Debugf("Upgrading Docker") +// uploadSSHKey updates the instance metadata with the given ssh key. +func (c *ComputeUtil) uploadSSHKey(instance *raw.Instance, sshKeyPath string) error { + log.Infof("Uploading SSH Key") - cmd, err := d.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") + sshKey, err := ioutil.ReadFile(sshKeyPath + ".pub") if err != nil { return err - } - if err := cmd.Run(); err != nil { - return err + metaDataValue := fmt.Sprintf("%s:%s %s\n", c.userName, strings.TrimSpace(string(sshKey)), c.userName) + + op, err := c.service.Instances.SetMetadata(c.project, c.zone, c.instanceName, &raw.Metadata{ + Fingerprint: instance.Metadata.Fingerprint, + Items: []*raw.MetadataItems{ + { + Key: "sshKeys", + Value: &metaDataValue, + }, + }, + }).Do() + + return c.waitForRegionalOp(op.Name) +} + +// parseTags computes the tags for the instance. +func parseTags(d *Driver) []string { + tags := []string{firewallTargetTag} + + if d.Tags != "" { + tags = append(tags, strings.Split(d.Tags, ",")...) } - return nil + return tags } // deleteInstance deletes the instance, leaving the persistent disk. @@ -247,27 +406,42 @@ func (c *ComputeUtil) deleteInstance() error { if err != nil { return err } + log.Infof("Waiting for instance to delete.") return c.waitForRegionalOp(op.Name) } -func (c *ComputeUtil) executeCommands(commands []string, ip, sshKeyPath string) error { - for _, command := range commands { - cmd := ssh.GetSSHCommand(ip, 22, c.userName, sshKeyPath, command) - if err := cmd.Run(); err != nil { - return fmt.Errorf("error executing command: %v %v", command, err) - } +// stopInstance stops the instance. +func (c *ComputeUtil) stopInstance() error { + op, err := c.service.Instances.Stop(c.project, c.zone, c.instanceName).Do() + if err != nil { + return err } - return nil + + log.Infof("Waiting for instance to stop.") + return c.waitForRegionalOp(op.Name) } +// startInstance starts the instance. +func (c *ComputeUtil) startInstance() error { + op, err := c.service.Instances.Start(c.project, c.zone, c.instanceName).Do() + if err != nil { + return err + } + + log.Infof("Waiting for instance to start.") + return c.waitForRegionalOp(op.Name) +} + +// waitForOp waits for the operation to finish. func (c *ComputeUtil) waitForOp(opGetter func() (*raw.Operation, error)) error { for { op, err := opGetter() if err != nil { return err } - log.Debugf("operation %q status: %s", op.Name, op.Status) + + log.Debugf("Operation %q status: %s", op.Name, op.Status) if op.Status == "DONE" { if op.Error != nil { return fmt.Errorf("Operation error: %v", *op.Error.Errors[0]) @@ -279,33 +453,51 @@ func (c *ComputeUtil) waitForOp(opGetter func() (*raw.Operation, error)) error { return nil } -// waitForOp waits for the GCE Operation to finish. +// waitForRegionalOp waits for the regional operation to finish. func (c *ComputeUtil) waitForRegionalOp(name string) error { return c.waitForOp(func() (*raw.Operation, error) { return c.service.ZoneOperations.Get(c.project, c.zone, name).Do() }) } +// waitForGlobalOp waits for the global operation to finish. func (c *ComputeUtil) waitForGlobalOp(name string) error { return c.waitForOp(func() (*raw.Operation, error) { return c.service.GlobalOperations.Get(c.project, name).Do() }) } -// waitForSSH waits for SSH to become ready on the instance. -func (c *ComputeUtil) waitForSSH(ip string) error { - log.Infof("Waiting for SSH...") - return ssh.WaitForTCP(fmt.Sprintf("%s:22", ip)) -} - // ip retrieves and returns the external IP address of the instance. func (c *ComputeUtil) ip() (string, error) { - if c.ipAddress == "" { - instance, err := c.service.Instances.Get(c.project, c.zone, c.instanceName).Do() - if err != nil { - return "", err - } - c.ipAddress = instance.NetworkInterfaces[0].AccessConfigs[0].NatIP + instance, err := c.service.Instances.Get(c.project, c.zone, c.instanceName).Do() + if err != nil { + return "", unwrapGoogleError(err) } - return c.ipAddress, nil + + nic := instance.NetworkInterfaces[0] + if c.useInternalIP { + return nic.NetworkIP, nil + } + return nic.AccessConfigs[0].NatIP, nil +} + +func unwrapGoogleError(err error) error { + if googleErr, ok := err.(*googleapi.Error); ok { + return errors.New(googleErr.Message) + } + + return err +} + +func isNotFound(err error) bool { + googleErr, ok := err.(*googleapi.Error) + if !ok { + return false + } + + if googleErr.Code == http.StatusNotFound { + return true + } + + return false } diff --git a/drivers/google/compute_util_test.go b/drivers/google/compute_util_test.go new file mode 100644 index 0000000000..c90b257115 --- /dev/null +++ b/drivers/google/compute_util_test.go @@ -0,0 +1,72 @@ +package google + +import ( + "testing" + + "github.com/stretchr/testify/assert" + raw "google.golang.org/api/compute/v1" +) + +func TestDefaultTag(t *testing.T) { + tags := parseTags(&Driver{Tags: ""}) + + assert.Equal(t, []string{"docker-machine"}, tags) +} + +func TestAdditionalTag(t *testing.T) { + tags := parseTags(&Driver{Tags: "tag1"}) + + assert.Equal(t, []string{"docker-machine", "tag1"}, tags) +} + +func TestAdditionalTags(t *testing.T) { + tags := parseTags(&Driver{Tags: "tag1,tag2"}) + + assert.Equal(t, []string{"docker-machine", "tag1", "tag2"}, tags) +} + +func TestPortsUsed(t *testing.T) { + var tests = []struct { + description string + computeUtil *ComputeUtil + expectedPorts []string + expectedError error + }{ + {"use docker port", &ComputeUtil{}, []string{"2376/tcp"}, nil}, + {"use docker and swarm port", &ComputeUtil{SwarmMaster: true, SwarmHost: "tcp://host:3376"}, []string{"2376/tcp", "3376/tcp"}, nil}, + {"use docker and non default swarm port", &ComputeUtil{SwarmMaster: true, SwarmHost: "tcp://host:4242"}, []string{"2376/tcp", "4242/tcp"}, nil}, + {"include additional ports", &ComputeUtil{openPorts: []string{"80", "2377/udp"}}, []string{"2376/tcp", "80/tcp", "2377/udp"}, nil}, + } + + for _, test := range tests { + ports, err := test.computeUtil.portsUsed() + + assert.Equal(t, test.expectedPorts, ports) + assert.Equal(t, test.expectedError, err) + } +} + +func TestMissingOpenedPorts(t *testing.T) { + var tests = []struct { + description string + allowed []*raw.FirewallAllowed + ports []string + expectedMissing map[string][]string + }{ + {"no port opened", []*raw.FirewallAllowed{}, []string{"2376"}, map[string][]string{"tcp": {"2376"}}}, + {"docker port opened", []*raw.FirewallAllowed{{IPProtocol: "tcp", Ports: []string{"2376"}}}, []string{"2376"}, map[string][]string{}}, + {"missing swarm port", []*raw.FirewallAllowed{{IPProtocol: "tcp", Ports: []string{"2376"}}}, []string{"2376", "3376"}, map[string][]string{"tcp": {"3376"}}}, + {"missing docker port", []*raw.FirewallAllowed{{IPProtocol: "tcp", Ports: []string{"3376"}}}, []string{"2376", "3376"}, map[string][]string{"tcp": {"2376"}}}, + {"both ports opened", []*raw.FirewallAllowed{{IPProtocol: "tcp", Ports: []string{"2376", "3376"}}}, []string{"2376", "3376"}, map[string][]string{}}, + {"more ports opened", []*raw.FirewallAllowed{{IPProtocol: "tcp", Ports: []string{"2376", "3376", "22", "1024-2048"}}}, []string{"2376", "3376"}, map[string][]string{}}, + {"additional missing", []*raw.FirewallAllowed{{IPProtocol: "tcp", Ports: []string{"2376", "2377/tcp"}}}, []string{"2377/udp", "80/tcp", "2376"}, map[string][]string{"tcp": {"80"}, "udp": {"2377"}}}, + } + + for _, test := range tests { + firewall := &raw.Firewall{Allowed: test.allowed} + + missingPorts := missingOpenedPorts(firewall, test.ports) + + assert.Equal(t, test.expectedMissing, missingPorts, test.description) + } +} diff --git a/drivers/google/google.go b/drivers/google/google.go index 0f2fccd5b4..18a07ee452 100644 --- a/drivers/google/google.go +++ b/drivers/google/google.go @@ -1,174 +1,332 @@ package google import ( + "errors" "fmt" - - "github.com/docker/machine/state" - - "os/exec" - "path" - - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" -) - -const ( - dockerConfigDir = "/etc/docker" + "net" + "strings" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" ) // Driver is a struct compatible with the docker.hosts.drivers.Driver interface. type Driver struct { - MachineName string - Zone string - MachineType string - storePath string - UserName string - Project string - CaCertPath string - PrivateKeyPath string - sshKeyPath string - publicSSHKeyPath string -} - -// CreateFlags are the command line flags used to create a driver. -type CreateFlags struct { - Zone *string - MachineType *string - UserName *string - Project *string + *drivers.BaseDriver + Zone string + MachineType string + MachineImage string + DiskType string + Address string + Network string + Subnetwork string + Preemptible bool + UseInternalIP bool + UseInternalIPOnly bool + ServiceAccount string + Scopes string + DiskSize int + Project string + Tags string + UseExisting bool + OpenPorts []string } -func init() { - drivers.Register("google", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} +const ( + defaultZone = "us-central1-a" + defaultUser = "docker-user" + defaultMachineType = "n1-standard-1" + defaultImageName = "ubuntu-os-cloud/global/images/ubuntu-1604-xenial-v20170721" + defaultServiceAccount = "default" + defaultScopes = "https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write" + defaultDiskType = "pd-standard" + defaultDiskSize = 10 + defaultNetwork = "default" + defaultSubnetwork = "" +) -// RegisterCreateFlags registers the flags this driver adds to +// GetCreateFlags registers the flags this driver adds to // "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ Name: "google-zone", Usage: "GCE Zone", - Value: "us-central1-a", + Value: defaultZone, EnvVar: "GOOGLE_ZONE", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "google-machine-type", Usage: "GCE Machine Type", - Value: "f1-micro", + Value: defaultMachineType, EnvVar: "GOOGLE_MACHINE_TYPE", }, - cli.StringFlag{ + mcnflag.StringFlag{ + Name: "google-machine-image", + Usage: "GCE Machine Image Absolute URL", + Value: defaultImageName, + EnvVar: "GOOGLE_MACHINE_IMAGE", + }, + mcnflag.StringFlag{ Name: "google-username", - Usage: "User Name", - Value: "docker-user", + Usage: "GCE User Name", + Value: defaultUser, EnvVar: "GOOGLE_USERNAME", }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "google-project", Usage: "GCE Project", EnvVar: "GOOGLE_PROJECT", }, + mcnflag.StringFlag{ + Name: "google-service-account", + Usage: "GCE Service Account for the VM (email address)", + Value: defaultServiceAccount, + EnvVar: "GOOGLE_SERVICE_ACCOUNT", + }, + mcnflag.StringFlag{ + Name: "google-scopes", + Usage: "GCE Scopes (comma-separated if multiple scopes)", + Value: defaultScopes, + EnvVar: "GOOGLE_SCOPES", + }, + mcnflag.IntFlag{ + Name: "google-disk-size", + Usage: "GCE Instance Disk Size (in GB)", + Value: defaultDiskSize, + EnvVar: "GOOGLE_DISK_SIZE", + }, + mcnflag.StringFlag{ + Name: "google-disk-type", + Usage: "GCE Instance Disk type", + Value: defaultDiskType, + EnvVar: "GOOGLE_DISK_TYPE", + }, + mcnflag.StringFlag{ + Name: "google-network", + Usage: "Specify network in which to provision vm", + Value: defaultNetwork, + EnvVar: "GOOGLE_NETWORK", + }, + mcnflag.StringFlag{ + Name: "google-subnetwork", + Usage: "Specify subnetwork in which to provision vm", + Value: defaultSubnetwork, + EnvVar: "GOOGLE_SUBNETWORK", + }, + mcnflag.StringFlag{ + Name: "google-address", + Usage: "GCE Instance External IP", + EnvVar: "GOOGLE_ADDRESS", + }, + mcnflag.BoolFlag{ + Name: "google-preemptible", + Usage: "GCE Instance Preemptibility", + EnvVar: "GOOGLE_PREEMPTIBLE", + }, + mcnflag.StringFlag{ + Name: "google-tags", + Usage: "GCE Instance Tags (comma-separated)", + EnvVar: "GOOGLE_TAGS", + Value: "", + }, + mcnflag.BoolFlag{ + Name: "google-use-internal-ip", + Usage: "Use internal GCE Instance IP rather than public one", + EnvVar: "GOOGLE_USE_INTERNAL_IP", + }, + mcnflag.BoolFlag{ + Name: "google-use-internal-ip-only", + Usage: "Configure GCE instance to not have an external IP address", + EnvVar: "GOOGLE_USE_INTERNAL_IP_ONLY", + }, + mcnflag.BoolFlag{ + Name: "google-use-existing", + Usage: "Don't create a new VM, use an existing one", + EnvVar: "GOOGLE_USE_EXISTING", + }, + mcnflag.StringSliceFlag{ + Name: "google-open-port", + Usage: "Make the specified port number accessible from the Internet, e.g, 8080/tcp", + }, } } // NewDriver creates a Driver with the specified storePath. -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { +func NewDriver(machineName string, storePath string) *Driver { return &Driver{ - MachineName: machineName, - storePath: storePath, - CaCertPath: caCert, - PrivateKeyPath: privateKey, - sshKeyPath: path.Join(storePath, "id_rsa"), - publicSSHKeyPath: path.Join(storePath, "id_rsa.pub"), - }, nil + Zone: defaultZone, + DiskType: defaultDiskType, + DiskSize: defaultDiskSize, + MachineType: defaultMachineType, + MachineImage: defaultImageName, + Network: defaultNetwork, + Subnetwork: defaultSubnetwork, + ServiceAccount: defaultServiceAccount, + Scopes: defaultScopes, + BaseDriver: &drivers.BaseDriver{ + SSHUser: defaultUser, + MachineName: machineName, + StorePath: storePath, + }, + } } -// DriverName returns the name of the driver. -func (driver *Driver) DriverName() string { - return "google" +// GetSSHHostname returns hostname for use with ssh +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } -// SetConfigFromFlags initializes the driver based on the command line flags. -func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.Zone = flags.String("google-zone") - driver.MachineType = flags.String("google-machine-type") - driver.UserName = flags.String("google-username") - driver.Project = flags.String("google-project") - if driver.Project == "" { - return fmt.Errorf("Please specify the Google Cloud Project name using the option --google-project.") +// GetSSHUsername returns username for use with ssh +func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker-user" } - return nil + return d.SSHUser } -func (driver *Driver) initApis() (*ComputeUtil, error) { - return newComputeUtil(driver) +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "google" } -func (d *Driver) PreCreateCheck() error { +// SetConfigFromFlags initializes the driver based on the command line flags. +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.Project = flags.String("google-project") + if d.Project == "" { + return errors.New("no Google Cloud Project name specified (--google-project)") + } + + d.Zone = flags.String("google-zone") + d.UseExisting = flags.Bool("google-use-existing") + if !d.UseExisting { + d.MachineType = flags.String("google-machine-type") + d.MachineImage = flags.String("google-machine-image") + d.MachineImage = strings.TrimPrefix(d.MachineImage, "https://www.googleapis.com/compute/v1/projects/") + d.DiskSize = flags.Int("google-disk-size") + d.DiskType = flags.String("google-disk-type") + d.Address = flags.String("google-address") + d.Network = flags.String("google-network") + d.Subnetwork = flags.String("google-subnetwork") + d.Preemptible = flags.Bool("google-preemptible") + d.UseInternalIP = flags.Bool("google-use-internal-ip") || flags.Bool("google-use-internal-ip-only") + d.UseInternalIPOnly = flags.Bool("google-use-internal-ip-only") + d.ServiceAccount = flags.String("google-service-account") + d.Scopes = flags.String("google-scopes") + d.Tags = flags.String("google-tags") + d.OpenPorts = flags.StringSlice("google-open-port") + } + d.SSHUser = flags.String("google-username") + d.SSHPort = 22 + d.SetSwarmConfigFromFlags(flags) + return nil } -// Create creates a GCE VM instance acting as a docker host. -func (driver *Driver) Create() error { - c, err := newComputeUtil(driver) +// PreCreateCheck is called to enforce pre-creation steps +func (d *Driver) PreCreateCheck() error { + c, err := newComputeUtil(d) if err != nil { return err } - log.Infof("Creating host...") + + // Check that the project exists. It will also check the credentials + // at the same time. + log.Infof("Check that the project exists") + + if _, err = c.service.Projects.Get(d.Project).Do(); err != nil { + return fmt.Errorf("Project with ID %q not found. %v", d.Project, err) + } + // Check if the instance already exists. There will be an error if the instance // doesn't exist, so just check instance for nil. - if instance, _ := c.instance(); instance != nil { - return fmt.Errorf("Instance %v already exists.", driver.MachineName) + log.Infof("Check if the instance already exists") + + instance, _ := c.instance() + if d.UseExisting { + if instance == nil { + return fmt.Errorf("unable to find instance %q in zone %q", d.MachineName, d.Zone) + } + } else { + if instance != nil { + return fmt.Errorf("instance %q already exists in zone %q", d.MachineName, d.Zone) + } } + return nil +} + +// Create creates a GCE VM instance acting as a docker host. +func (d *Driver) Create() error { log.Infof("Generating SSH Key") - if err := ssh.GenerateSSHKey(driver.sshKeyPath); err != nil { + + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { + return err + } + + log.Infof("Creating host...") + + c, err := newComputeUtil(d) + if err != nil { return err } - return c.createInstance(driver) + if err := c.openFirewallPorts(d); err != nil { + return err + } + + if d.UseExisting { + return c.configureInstance(d) + } + return c.createInstance(d) } // GetURL returns the URL of the remote docker daemon. -func (driver *Driver) GetURL() (string, error) { - ip, err := driver.GetIP() +func (d *Driver) GetURL() (string, error) { + ip, err := d.GetIP() if err != nil { return "", err } - url := fmt.Sprintf("tcp://%s:2376", ip) - return url, nil + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil } // GetIP returns the IP address of the GCE instance. -func (driver *Driver) GetIP() (string, error) { - c, err := newComputeUtil(driver) +func (d *Driver) GetIP() (string, error) { + c, err := newComputeUtil(d) if err != nil { return "", err } - return c.ip() + + ip, err := c.ip() + if err != nil { + return "", err + } + if ip == "" { + return "", drivers.ErrHostIsNotRunning + } + + return ip, nil } // GetState returns a docker.hosts.state.State value representing the current state of the host. -func (driver *Driver) GetState() (state.State, error) { - c, err := newComputeUtil(driver) +func (d *Driver) GetState() (state.State, error) { + c, err := newComputeUtil(d) if err != nil { return state.None, err } // All we care about is whether the disk exists, so we just check disk for a nil value. // There will be no error if disk is not nil. - disk, _ := c.disk() instance, _ := c.instance() - if instance == nil && disk == nil { - return state.None, nil - } - if instance == nil && disk != nil { + if instance == nil { + disk, _ := c.disk() + if disk == nil { + return state.None, nil + } return state.Stopped, nil } @@ -183,106 +341,85 @@ func (driver *Driver) GetState() (state.State, error) { return state.None, nil } -// Start creates a GCE instance and attaches it to the existing disk. -func (driver *Driver) Start() error { - c, err := newComputeUtil(driver) +// Start starts an existing GCE instance or create an instance with an existing disk. +func (d *Driver) Start() error { + c, err := newComputeUtil(d) if err != nil { return err } - return c.createInstance(driver) -} -// Stop deletes the GCE instance, but keeps the disk. -func (driver *Driver) Stop() error { - c, err := newComputeUtil(driver) + instance, err := c.instance() if err != nil { - return err - } - return c.deleteInstance() -} - -// Remove deletes the GCE instance and the disk. -func (driver *Driver) Remove() error { - c, err := newComputeUtil(driver) - if err != nil { - return err - } - s, err := driver.GetState() - if err != nil { - return err - } - if s == state.Running { - if err := c.deleteInstance(); err != nil { + if !isNotFound(err) { return err } } - return c.deleteDisk() -} -// Restart deletes and recreates the GCE instance, keeping the disk. -func (driver *Driver) Restart() error { - c, err := newComputeUtil(driver) - if err != nil { - return err - } - if err := c.deleteInstance(); err != nil { - return err + if instance == nil { + if err = c.createInstance(d); err != nil { + return err + } + } else { + if err := c.startInstance(); err != nil { + return err + } } - return c.createInstance(driver) -} - -// Kill deletes the GCE instance, but keeps the disk. -func (driver *Driver) Kill() error { - return driver.Stop() + d.IPAddress, err = d.GetIP() + return err } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") +// Stop stops an existing GCE instance. +func (d *Driver) Stop() error { + c, err := newComputeUtil(d) if err != nil { return err } - if err := cmd.Run(); err != nil { + + if err := c.stopInstance(); err != nil { return err } + d.IPAddress = "" return nil } -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { +// Restart restarts a machine which is known to be running. +func (d *Driver) Restart() error { + if err := d.Stop(); err != nil { return err } - return nil + return d.Start() } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir +// Kill stops an existing GCE instance. +func (d *Driver) Kill() error { + return d.Stop() } -// GetSSHCommand returns a command that will run over SSH on the GCE instance. -func (driver *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := driver.GetIP() +// Remove deletes the GCE instance and the disk. +func (d *Driver) Remove() error { + c, err := newComputeUtil(d) if err != nil { - return nil, err + return err } - return ssh.GetSSHCommand(ip, 22, driver.UserName, driver.sshKeyPath, args...), nil -} -// Upgrade upgrades the docker daemon on the host to the latest version. -func (driver *Driver) Upgrade() error { - c, err := newComputeUtil(driver) - if err != nil { - return err + if err := c.deleteInstance(); err != nil { + if isNotFound(err) { + log.Warn("Remote instance does not exist, proceeding with removing local reference") + } else { + return err + } } - return c.updateDocker(driver) + + if err := c.deleteDisk(); err != nil { + if isNotFound(err) { + log.Warn("Remote disk does not exist, proceeding") + } else { + return err + } + } + + return nil } diff --git a/drivers/google/google_test.go b/drivers/google/google_test.go new file mode 100644 index 0000000000..b72035ac2c --- /dev/null +++ b/drivers/google/google_test.go @@ -0,0 +1,24 @@ +package google + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("", "") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "google-project": "PROJECT", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/google/integration_test.go b/drivers/google/integration_test.go deleted file mode 100644 index 7c89c99cf8..0000000000 --- a/drivers/google/integration_test.go +++ /dev/null @@ -1,189 +0,0 @@ -package google - -import ( - "flag" - "io/ioutil" - "os" - "path" - "testing" - - log "github.com/Sirupsen/logrus" - "github.com/docker/machine/state" -) - -var ( - project = flag.String("project", "", "Project") - tokenPath = flag.String("token-path", "", "Token path") -) - -var ( - driver *Driver - c *ComputeUtil -) - -const ( - zone = "us-central1-a" -) - -func init() { - flag.Parse() - - if *project == "" { - log.Error("You must specify a GCE project using the --project flag. All tests will be skipped.") - return - } - - if *tokenPath == "" { - log.Error("You must specify a token using the --token-path flag. All tests will be skipped.") - return - } - - tmpDir, err := ioutil.TempDir("", "") - if err != nil { - log.Fatal(err) - } - - // go test can't take args from stdin, so the path to an existing token must be passed as a flag. - os.Link(*tokenPath, path.Join(tmpDir, "gce_token")) - - log.Fatal("hai") - - driver = &Driver{ - storePath: tmpDir, - MachineName: "test-instance", - Zone: "us-central1-a", - MachineType: "n1-standard-1", - UserName: os.Getenv("USER"), - Project: *project, - sshKeyPath: path.Join(tmpDir, "id_rsa"), - publicSSHKeyPath: path.Join(tmpDir, "id_rsa.pub"), - } - - c, err = newComputeUtil(driver) - if err != nil { - log.Fatal(err) - } -} - -func cleanupDisk() { - log.Println("Cleaning up disk.") - d, err := c.service.Disks.Get(*project, zone, "test-instance-disk").Do() - if d == nil { - return - } - op, err := c.service.Disks.Delete(*project, zone, "test-instance-disk").Do() - if err != nil { - log.Printf("Error cleaning up disk: %v", err) - return - } - err = c.waitForRegionalOp(op.Name) - if err != nil { - log.Printf("Error cleaning up disk: %v", err) - } -} - -func cleanupInstance() { - log.Println("Cleaning up instance.") - d, err := c.service.Instances.Get(*project, zone, "test-instance").Do() - if d == nil { - return - } - op, err := c.service.Instances.Delete(*project, zone, "test-instance").Do() - if err != nil { - log.Printf("Error cleaning up instance: %v", err) - return - } - err = c.waitForRegionalOp(op.Name) - if err != nil { - log.Printf("Error cleaning up instance: %v", err) - } -} - -func cleanup() { - cleanupInstance() - cleanupDisk() -} - -type operation struct { - Name string - Method func() error - DiskExpected bool - InstanceExpected bool - State state.State - Arguments []interface{} -} - -func TestBasicOperations(t *testing.T) { - if *project == "" || *tokenPath == "" { - t.Skip("Skipping tests because no --project or --token-path flag was passed.") - return - } - ops := []operation{ - { - Name: "Create", - Method: driver.Create, - DiskExpected: true, - InstanceExpected: true, - State: state.Running, - }, - { - Name: "Stop", - Method: driver.Stop, - DiskExpected: true, - InstanceExpected: false, - State: state.Stopped, - }, - { - Name: "Start", - Method: driver.Start, - DiskExpected: true, - InstanceExpected: true, - State: state.Running, - }, - { - Name: "Restart", - Method: driver.Restart, - DiskExpected: true, - InstanceExpected: true, - State: state.Running, - }, - { - Name: "Remove", - Method: driver.Remove, - DiskExpected: false, - InstanceExpected: false, - State: state.None, - }, - } - defer cleanup() - for _, op := range ops { - log.Info("Executing operation: ", op.Name) - err := op.Method() - if err != nil { - t.Fatal(err) - } - AssertDiskAndInstance(op.DiskExpected, op.InstanceExpected) - if s, _ := driver.GetState(); s != op.State { - t.Fatalf("State should be %v, but is: %v", op.State, s) - } - } -} - -func AssertDiskAndInstance(diskShouldExist, instShouldExist bool) { - d, err := c.service.Disks.Get(*project, zone, "test-instance-disk").Do() - if diskShouldExist { - if d == nil || err != nil { - log.Fatal("Error retrieving disk that should exist.") - } - } else if d != nil { - log.Fatal("Disk shouldn't exist but does.") - } - i, err := c.service.Instances.Get(*project, zone, "test-instance").Do() - if instShouldExist { - if i == nil || err != nil { - log.Fatal("error retrieving instance that should exist.") - } - } else if i != nil { - log.Fatal("Instance shouldnt exist but does.") - } -} diff --git a/drivers/hyperv/hyperv.go b/drivers/hyperv/hyperv.go new file mode 100644 index 0000000000..a980cf11f4 --- /dev/null +++ b/drivers/hyperv/hyperv.go @@ -0,0 +1,492 @@ +package hyperv + +import ( + "fmt" + "net" + "os" + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" +) + +type Driver struct { + *drivers.BaseDriver + Boot2DockerURL string + VSwitch string + DiskSize int + MemSize int + CPU int + MacAddr string + VLanID int + DisableDynamicMemory bool +} + +const ( + defaultDiskSize = 20000 + defaultMemory = 1024 + defaultCPU = 1 + defaultVLanID = 0 + defaultDisableDynamicMemory = false +) + +// NewDriver creates a new Hyper-v driver with default settings. +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + DiskSize: defaultDiskSize, + MemSize: defaultMemory, + CPU: defaultCPU, + DisableDynamicMemory: defaultDisableDynamicMemory, + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + } +} + +// GetCreateFlags registers the flags this driver adds to +// "docker hosts create" +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ + Name: "hyperv-boot2docker-url", + Usage: "URL of the boot2docker ISO. Defaults to the latest available version.", + EnvVar: "HYPERV_BOOT2DOCKER_URL", + }, + mcnflag.StringFlag{ + Name: "hyperv-virtual-switch", + Usage: "Virtual switch name. Defaults to first found.", + EnvVar: "HYPERV_VIRTUAL_SWITCH", + }, + mcnflag.IntFlag{ + Name: "hyperv-disk-size", + Usage: "Maximum size of dynamically expanding disk in MB.", + Value: defaultDiskSize, + EnvVar: "HYPERV_DISK_SIZE", + }, + mcnflag.IntFlag{ + Name: "hyperv-memory", + Usage: "Memory size for host in MB.", + Value: defaultMemory, + EnvVar: "HYPERV_MEMORY", + }, + mcnflag.IntFlag{ + Name: "hyperv-cpu-count", + Usage: "number of CPUs for the machine", + Value: defaultCPU, + EnvVar: "HYPERV_CPU_COUNT", + }, + mcnflag.StringFlag{ + Name: "hyperv-static-macaddress", + Usage: "Hyper-V network adapter's static MAC address.", + EnvVar: "HYPERV_STATIC_MACADDRESS", + }, + mcnflag.IntFlag{ + Name: "hyperv-vlan-id", + Usage: "Hyper-V network adapter's VLAN ID if any", + Value: defaultVLanID, + EnvVar: "HYPERV_VLAN_ID", + }, + mcnflag.BoolFlag{ + Name: "hyperv-disable-dynamic-memory", + Usage: "Disable dynamic memory management setting", + EnvVar: "HYPERV_DISABLE_DYNAMIC_MEMORY", + }, + } +} + +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.Boot2DockerURL = flags.String("hyperv-boot2docker-url") + d.VSwitch = flags.String("hyperv-virtual-switch") + d.DiskSize = flags.Int("hyperv-disk-size") + d.MemSize = flags.Int("hyperv-memory") + d.CPU = flags.Int("hyperv-cpu-count") + d.MacAddr = flags.String("hyperv-static-macaddress") + d.VLanID = flags.Int("hyperv-vlan-id") + d.SSHUser = "docker" + d.DisableDynamicMemory = flags.Bool("hyperv-disable-dynamic-memory") + d.SetSwarmConfigFromFlags(flags) + + return nil +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "hyperv" +} + +func (d *Driver) GetURL() (string, error) { + ip, err := d.GetIP() + if err != nil { + return "", err + } + + if ip == "" { + return "", nil + } + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil +} + +func (d *Driver) GetState() (state.State, error) { + stdout, err := cmdOut("(", "Hyper-V\\Get-VM", d.MachineName, ").state") + if err != nil { + return state.None, fmt.Errorf("Failed to find the VM status") + } + + resp := parseLines(stdout) + if len(resp) < 1 { + return state.None, nil + } + + switch resp[0] { + case "Running": + return state.Running, nil + case "Off": + return state.Stopped, nil + default: + return state.None, nil + } +} + +// PreCreateCheck checks that the machine creation process can be started safely. +func (d *Driver) PreCreateCheck() error { + // Check that powershell was found + if powershell == "" { + return ErrPowerShellNotFound + } + + // Check that hyperv is installed + if err := hypervAvailable(); err != nil { + return err + } + + // Check that the user is an Administrator + isAdmin, err := isAdministrator() + if err != nil { + return err + } + if !isAdmin { + return ErrNotAdministrator + } + + // Check that there is a virtual switch already configured + if _, err := d.chooseVirtualSwitch(); err != nil { + return err + } + + // Downloading boot2docker to cache should be done here to make sure + // that a download failure will not leave a machine half created. + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + err = b2dutils.UpdateISOCache(d.Boot2DockerURL) + return err +} + +func (d *Driver) Create() error { + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { + return err + } + + log.Infof("Creating SSH key...") + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { + return err + } + + log.Infof("Creating VM...") + virtualSwitch, err := d.chooseVirtualSwitch() + if err != nil { + return err + } + + log.Infof("Using switch %q", virtualSwitch) + + diskImage, err := d.generateDiskImage() + if err != nil { + return err + } + + if err := cmd("Hyper-V\\New-VM", + d.MachineName, + "-Path", fmt.Sprintf("'%s'", d.ResolveStorePath(".")), + "-SwitchName", quote(virtualSwitch), + "-MemoryStartupBytes", toMb(d.MemSize)); err != nil { + return err + } + if d.DisableDynamicMemory { + if err := cmd("Hyper-V\\Set-VMMemory", + "-VMName", d.MachineName, + "-DynamicMemoryEnabled", "$false"); err != nil { + return err + } + } + + if d.CPU > 1 { + if err := cmd("Hyper-V\\Set-VMProcessor", + d.MachineName, + "-Count", fmt.Sprintf("%d", d.CPU)); err != nil { + return err + } + } + + if d.MacAddr != "" { + if err := cmd("Hyper-V\\Set-VMNetworkAdapter", + "-VMName", d.MachineName, + "-StaticMacAddress", fmt.Sprintf("\"%s\"", d.MacAddr)); err != nil { + return err + } + } + + if d.VLanID > 0 { + if err := cmd("Hyper-V\\Set-VMNetworkAdapterVlan", + "-VMName", d.MachineName, + "-Access", + "-VlanId", fmt.Sprintf("%d", d.VLanID)); err != nil { + return err + } + } + + if err := cmd("Hyper-V\\Set-VMDvdDrive", + "-VMName", d.MachineName, + "-Path", quote(d.ResolveStorePath("boot2docker.iso"))); err != nil { + return err + } + + if err := cmd("Hyper-V\\Add-VMHardDiskDrive", + "-VMName", d.MachineName, + "-Path", quote(diskImage)); err != nil { + return err + } + + log.Infof("Starting VM...") + return d.Start() +} + +func (d *Driver) chooseVirtualSwitch() (string, error) { + if d.VSwitch == "" { + // Default to the first external switche and in the process avoid DockerNAT + stdout, err := cmdOut("[Console]::OutputEncoding = [Text.Encoding]::UTF8; (Hyper-V\\Get-VMSwitch -SwitchType External).Name") + if err != nil { + return "", err + } + + switches := parseLines(stdout) + + if len(switches) < 1 { + return "", fmt.Errorf("no External vswitch found. A valid vswitch must be available for this command to run. Check https://docs.docker.com/machine/drivers/hyper-v/") + } + + return switches[0], nil + } + + stdout, err := cmdOut("[Console]::OutputEncoding = [Text.Encoding]::UTF8; (Hyper-V\\Get-VMSwitch).Name") + if err != nil { + return "", err + } + + switches := parseLines(stdout) + + found := false + for _, name := range switches { + if name == d.VSwitch { + found = true + break + } + } + + if !found { + return "", fmt.Errorf("vswitch %q not found", d.VSwitch) + } + + return d.VSwitch, nil +} + +// waitForIP waits until the host has a valid IP +func (d *Driver) waitForIP() (string, error) { + log.Infof("Waiting for host to start...") + + for { + ip, _ := d.GetIP() + if ip != "" { + return ip, nil + } + + time.Sleep(1 * time.Second) + } +} + +// waitStopped waits until the host is stopped +func (d *Driver) waitStopped() error { + log.Infof("Waiting for host to stop...") + + for { + s, err := d.GetState() + if err != nil { + return err + } + + if s != state.Running { + return nil + } + + time.Sleep(1 * time.Second) + } +} + +// Start starts an host +func (d *Driver) Start() error { + if err := cmd("Hyper-V\\Start-VM", d.MachineName); err != nil { + return err + } + + ip, err := d.waitForIP() + if err != nil { + return err + } + + d.IPAddress = ip + + return nil +} + +// Stop stops an host +func (d *Driver) Stop() error { + if err := cmd("Hyper-V\\Stop-VM", d.MachineName); err != nil { + return err + } + + if err := d.waitStopped(); err != nil { + return err + } + + d.IPAddress = "" + + return nil +} + +// Remove removes an host +func (d *Driver) Remove() error { + s, err := d.GetState() + if err != nil { + return err + } + + if s == state.Running { + if err := d.Kill(); err != nil { + return err + } + } + + return cmd("Hyper-V\\Remove-VM", d.MachineName, "-Force") +} + +// Restart stops and starts an host +func (d *Driver) Restart() error { + err := d.Stop() + if err != nil { + return err + } + + return d.Start() +} + +// Kill force stops an host +func (d *Driver) Kill() error { + if err := cmd("Hyper-V\\Stop-VM", d.MachineName, "-TurnOff"); err != nil { + return err + } + + if err := d.waitStopped(); err != nil { + return err + } + + d.IPAddress = "" + + return nil +} + +func (d *Driver) GetIP() (string, error) { + s, err := d.GetState() + if err != nil { + return "", err + } + if s != state.Running { + return "", drivers.ErrHostIsNotRunning + } + + stdout, err := cmdOut("((", "Hyper-V\\Get-VM", d.MachineName, ").networkadapters[0]).ipaddresses[0]") + if err != nil { + return "", err + } + + resp := parseLines(stdout) + if len(resp) < 1 { + return "", fmt.Errorf("IP not found") + } + + return resp[0], nil +} + +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" +} + +// generateDiskImage creates a small fixed vhd, put the tar in, convert to dynamic, then resize +func (d *Driver) generateDiskImage() (string, error) { + diskImage := d.ResolveStorePath("disk.vhd") + fixed := d.ResolveStorePath("fixed.vhd") + + // Resizing vhds requires administrator privileges + // incase the user is only a hyper-v admin then create the disk at the target size to avoid resizing. + isWindowsAdmin, err := isWindowsAdministrator() + if err != nil { + return "", err + } + fixedDiskSize := "10MB" + if !isWindowsAdmin { + fixedDiskSize = toMb(d.DiskSize) + } + + log.Infof("Creating VHD") + if err := cmd("Hyper-V\\New-VHD", "-Path", quote(fixed), "-SizeBytes", fixedDiskSize, "-Fixed"); err != nil { + return "", err + } + + tarBuf, err := mcnutils.MakeDiskImage(d.publicSSHKeyPath()) + if err != nil { + return "", err + } + + file, err := os.OpenFile(fixed, os.O_WRONLY, 0644) + if err != nil { + return "", err + } + defer file.Close() + + file.Seek(0, os.SEEK_SET) + _, err = file.Write(tarBuf.Bytes()) + if err != nil { + return "", err + } + file.Close() + + if err := cmd("Hyper-V\\Convert-VHD", "-Path", quote(fixed), "-DestinationPath", quote(diskImage), "-VHDType", "Dynamic", "-DeleteSource"); err != nil { + return "", err + } + + if isWindowsAdmin { + if err := cmd("Hyper-V\\Resize-VHD", "-Path", quote(diskImage), "-SizeBytes", toMb(d.DiskSize)); err != nil { + return "", err + } + } + + return diskImage, nil +} diff --git a/drivers/hyperv/hyperv_test.go b/drivers/hyperv/hyperv_test.go new file mode 100644 index 0000000000..9f5886700e --- /dev/null +++ b/drivers/hyperv/hyperv_test.go @@ -0,0 +1,71 @@ +package hyperv + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromDefaultFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{}, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) + + sshPort, err := driver.GetSSHPort() + assert.Equal(t, 22, sshPort) + assert.NoError(t, err) + + assert.Equal(t, "", driver.Boot2DockerURL) + assert.Equal(t, "", driver.VSwitch) + assert.Equal(t, defaultDiskSize, driver.DiskSize) + assert.Equal(t, defaultMemory, driver.MemSize) + assert.Equal(t, defaultCPU, driver.CPU) + assert.Equal(t, "", driver.MacAddr) + assert.Equal(t, defaultVLanID, driver.VLanID) + assert.Equal(t, "docker", driver.GetSSHUsername()) + assert.Equal(t, defaultDisableDynamicMemory, driver.DisableDynamicMemory) +} + +func TestSetConfigFromCustomFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "hyperv-boot2docker-url": "B2D_URL", + "hyperv-virtual-switch": "TheSwitch", + "hyperv-disk-size": 100000, + "hyperv-memory": 4096, + "hyperv-cpu-count": 4, + "hyperv-static-macaddress": "00:0a:95:9d:68:16", + "hyperv-vlan-id": 2, + "hyperv-disable-dynamic-memory": true, + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) + + sshPort, err := driver.GetSSHPort() + assert.Equal(t, 22, sshPort) + assert.NoError(t, err) + + assert.Equal(t, "B2D_URL", driver.Boot2DockerURL) + assert.Equal(t, "TheSwitch", driver.VSwitch) + assert.Equal(t, 100000, driver.DiskSize) + assert.Equal(t, 4096, driver.MemSize) + assert.Equal(t, 4, driver.CPU) + assert.Equal(t, "00:0a:95:9d:68:16", driver.MacAddr) + assert.Equal(t, 2, driver.VLanID) + assert.Equal(t, "docker", driver.GetSSHUsername()) + assert.Equal(t, true, driver.DisableDynamicMemory) +} diff --git a/drivers/hyperv/powershell.go b/drivers/hyperv/powershell.go new file mode 100644 index 0000000000..5175791fd5 --- /dev/null +++ b/drivers/hyperv/powershell.go @@ -0,0 +1,114 @@ +package hyperv + +import ( + "bufio" + "bytes" + "errors" + "os/exec" + "strings" + + "fmt" + + "github.com/docker/machine/libmachine/log" +) + +var powershell string + +var ( + ErrPowerShellNotFound = errors.New("Powershell was not found in the path") + ErrNotAdministrator = errors.New("Hyper-v commands have to be run as an Administrator") + ErrNotInstalled = errors.New("Hyper-V PowerShell Module is not available") +) + +func init() { + powershell, _ = exec.LookPath("powershell.exe") +} + +func cmdOut(args ...string) (string, error) { + args = append([]string{"-NoProfile", "-NonInteractive"}, args...) + cmd := exec.Command(powershell, args...) + log.Debugf("[executing ==>] : %v %v", powershell, strings.Join(args, " ")) + var stdout bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err := cmd.Run() + log.Debugf("[stdout =====>] : %s", stdout.String()) + log.Debugf("[stderr =====>] : %s", stderr.String()) + return stdout.String(), err +} + +func cmd(args ...string) error { + _, err := cmdOut(args...) + return err +} + +func parseLines(stdout string) []string { + resp := []string{} + + s := bufio.NewScanner(strings.NewReader(stdout)) + for s.Scan() { + resp = append(resp, s.Text()) + } + + return resp +} + +func hypervAvailable() error { + stdout, err := cmdOut("@(Get-Module -ListAvailable hyper-v).Name | Get-Unique") + if err != nil { + return err + } + + resp := parseLines(stdout) + if resp[0] != "Hyper-V" { + return ErrNotInstalled + } + + return nil +} + +func isAdministrator() (bool, error) { + hypervAdmin := isHypervAdministrator() + + if hypervAdmin { + return true, nil + } + + windowsAdmin, err := isWindowsAdministrator() + + if err != nil { + return false, err + } + + return windowsAdmin, nil +} + +func isHypervAdministrator() bool { + stdout, err := cmdOut(`@([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("S-1-5-32-578")`) + if err != nil { + log.Debug(err) + return false + } + + resp := parseLines(stdout) + return resp[0] == "True" +} + +func isWindowsAdministrator() (bool, error) { + stdout, err := cmdOut(`@([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")`) + if err != nil { + return false, err + } + + resp := parseLines(stdout) + return resp[0] == "True", nil +} + +func quote(text string) string { + return fmt.Sprintf("'%s'", text) +} + +func toMb(value int) string { + return fmt.Sprintf("%dMB", value) +} diff --git a/drivers/none/driver.go b/drivers/none/driver.go new file mode 100644 index 0000000000..2e88dbef79 --- /dev/null +++ b/drivers/none/driver.go @@ -0,0 +1,113 @@ +package none + +import ( + "fmt" + neturl "net/url" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" +) + +const driverName = "none" + +// Driver is the driver used when no driver is selected. It is used to +// connect to existing Docker hosts by specifying the URL of the host as +// an option. +type Driver struct { + *drivers.BaseDriver + URL string +} + +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + } +} + +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ + Name: "url", + Usage: "URL of host when no driver is selected", + Value: "", + }, + } +} + +func (d *Driver) Create() error { + return nil +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return driverName +} + +func (d *Driver) GetIP() (string, error) { + return d.IPAddress, nil +} + +func (d *Driver) GetSSHHostname() (string, error) { + return "", nil +} + +func (d *Driver) GetSSHKeyPath() string { + return "" +} + +func (d *Driver) GetSSHPort() (int, error) { + return 0, nil +} + +func (d *Driver) GetSSHUsername() string { + return "" +} + +func (d *Driver) GetURL() (string, error) { + return d.URL, nil +} + +func (d *Driver) GetState() (state.State, error) { + return state.Running, nil +} + +func (d *Driver) Kill() error { + return fmt.Errorf("hosts without a driver cannot be killed") +} + +func (d *Driver) Remove() error { + return nil +} + +func (d *Driver) Restart() error { + return fmt.Errorf("hosts without a driver cannot be restarted") +} + +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + url := flags.String("url") + + if url == "" { + return fmt.Errorf("--url option is required when no driver is selected") + } + + d.URL = url + u, err := neturl.Parse(url) + if err != nil { + return err + } + + d.IPAddress = u.Host + return nil +} + +func (d *Driver) Start() error { + return fmt.Errorf("hosts without a driver cannot be started") +} + +func (d *Driver) Stop() error { + return fmt.Errorf("hosts without a driver cannot be stopped") +} diff --git a/drivers/none/none.go b/drivers/none/none.go deleted file mode 100644 index f65d9a1b2c..0000000000 --- a/drivers/none/none.go +++ /dev/null @@ -1,118 +0,0 @@ -package none - -import ( - "fmt" - "os/exec" - - "github.com/codegangsta/cli" - "github.com/docker/docker/api" - "github.com/docker/machine/drivers" - "github.com/docker/machine/state" -) - -// Driver is the driver used when no driver is selected. It is used to -// connect to existing Docker hosts by specifying the URL of the host as -// an option. -type Driver struct { - URL string -} - -func init() { - drivers.Register("none", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} - -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ - Name: "url", - Usage: "URL of host when no driver is selected", - Value: "", - }, - } -} - -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - return &Driver{}, nil -} - -func (d *Driver) DriverName() string { - return "none" -} - -func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - url := flags.String("url") - - if url == "" { - return fmt.Errorf("--url option is required when no driver is selected") - } - validatedUrl, err := api.ValidateHost(url) - if err != nil { - return err - } - - d.URL = validatedUrl - return nil -} - -func (d *Driver) GetURL() (string, error) { - return d.URL, nil -} - -func (d *Driver) GetIP() (string, error) { - return "", nil -} - -func (d *Driver) GetState() (state.State, error) { - return state.None, nil -} - -func (d *Driver) PreCreateCheck() error { - return nil -} - -func (d *Driver) Create() error { - return nil -} - -func (d *Driver) Start() error { - return fmt.Errorf("hosts without a driver cannot be started") -} - -func (d *Driver) Stop() error { - return fmt.Errorf("hosts without a driver cannot be stopped") -} - -func (d *Driver) Remove() error { - return nil -} - -func (d *Driver) Restart() error { - return fmt.Errorf("hosts without a driver cannot be restarted") -} - -func (d *Driver) Kill() error { - return fmt.Errorf("hosts without a driver cannot be killed") -} - -func (d *Driver) StartDocker() error { - return fmt.Errorf("hosts without a driver cannot start docker") -} - -func (d *Driver) StopDocker() error { - return fmt.Errorf("hosts without a driver cannot stop docker") -} - -func (d *Driver) GetDockerConfigDir() string { - return "" -} - -func (d *Driver) Upgrade() error { - return fmt.Errorf("hosts without a driver cannot be upgraded") -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return nil, fmt.Errorf("hosts without a driver do not support SSH") -} diff --git a/drivers/openstack/client.go b/drivers/openstack/client.go index 4329aa5206..8b47b86e49 100644 --- a/drivers/openstack/client.go +++ b/drivers/openstack/client.go @@ -1,14 +1,25 @@ package openstack import ( - log "github.com/Sirupsen/logrus" + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/version" "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/openstack" + compute_ips "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop" "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" "github.com/rackspace/gophercloud/openstack/compute/v2/images" "github.com/rackspace/gophercloud/openstack/compute/v2/servers" + "github.com/rackspace/gophercloud/openstack/identity/v2/tenants" "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "github.com/rackspace/gophercloud/openstack/networking/v2/networks" "github.com/rackspace/gophercloud/openstack/networking/v2/ports" @@ -18,6 +29,7 @@ import ( type Client interface { Authenticate(d *Driver) error InitComputeClient(d *Driver) error + InitIdentityClient(d *Driver) error InitNetworkClient(d *Driver) error CreateInstance(d *Driver) (string, error) @@ -26,31 +38,38 @@ type Client interface { StopInstance(d *Driver) error RestartInstance(d *Driver) error DeleteInstance(d *Driver) error - WaitForInstanceStatus(d *Driver, status string, timeout int) error - GetInstanceIpAddresses(d *Driver) ([]IpAddress, error) + WaitForInstanceStatus(d *Driver, status string) error + GetInstanceIPAddresses(d *Driver) ([]IPAddress, error) + GetPublicKey(keyPairName string) ([]byte, error) CreateKeyPair(d *Driver, name string, publicKey string) error DeleteKeyPair(d *Driver, name string) error - GetNetworkId(d *Driver) (string, error) - GetFlavorId(d *Driver) (string, error) - GetImageId(d *Driver) (string, error) - AssignFloatingIP(d *Driver, floatingIp *FloatingIp, portId string) error - GetFloatingIPs(d *Driver) ([]FloatingIp, error) - GetFloatingIpPoolId(d *Driver) (string, error) - GetInstancePortId(d *Driver) (string, error) + GetNetworkID(d *Driver) (string, error) + GetFlavorID(d *Driver) (string, error) + GetImageID(d *Driver) (string, error) + AssignFloatingIP(d *Driver, floatingIP *FloatingIP) error + GetFloatingIPs(d *Driver) ([]FloatingIP, error) + GetFloatingIPPoolID(d *Driver) (string, error) + GetInstancePortID(d *Driver) (string, error) + GetTenantID(d *Driver) (string, error) } type GenericClient struct { Provider *gophercloud.ProviderClient Compute *gophercloud.ServiceClient + Identity *gophercloud.ServiceClient Network *gophercloud.ServiceClient } func (c *GenericClient) CreateInstance(d *Driver) (string, error) { serverOpts := servers.CreateOpts{ - Name: d.MachineName, - FlavorRef: d.FlavorId, - ImageRef: d.ImageId, - SecurityGroups: d.SecurityGroups, + Name: d.MachineName, + FlavorRef: d.FlavorId, + ImageRef: d.ImageId, + UserData: d.UserData, + SecurityGroups: d.SecurityGroups, + AvailabilityZone: d.AvailabilityZone, + ConfigDrive: d.ConfigDrive, + Metadata: d.GetMetadata(), } if d.NetworkId != "" { serverOpts.Networks = []servers.Network{ @@ -60,13 +79,11 @@ func (c *GenericClient) CreateInstance(d *Driver) (string, error) { } } - log.WithFields(log.Fields{ - "Name": d.MachineName, - }).Info("Creating server...") + log.Info("Creating machine...") server, err := servers.Create(c.Compute, keypairs.CreateOptsExt{ - serverOpts, - d.KeyPairName, + CreateOptsBuilder: serverOpts, + KeyName: d.KeyPairName, }).Extract() if err != nil { return "", err @@ -79,18 +96,21 @@ const ( Fixed string = "fixed" ) -type IpAddress struct { +type IPAddress struct { Network string AddressType string Address string + Version int Mac string } -type FloatingIp struct { +type FloatingIP struct { Id string Ip string NetworkId string PortId string + Pool string + MachineId string } func (c *GenericClient) GetInstanceState(d *Driver) (string, error) { @@ -129,26 +149,45 @@ func (c *GenericClient) DeleteInstance(d *Driver) error { return nil } -func (c *GenericClient) WaitForInstanceStatus(d *Driver, status string, timeout int) error { - if err := servers.WaitForStatus(c.Compute, d.MachineId, status, timeout); err != nil { - return err - } - return nil +func (c *GenericClient) WaitForInstanceStatus(d *Driver, status string) error { + return mcnutils.WaitForSpecificOrError(func() (bool, error) { + current, err := servers.Get(c.Compute, d.MachineId).Extract() + if err != nil { + return true, err + } + + if current.Status == "ERROR" { + return true, fmt.Errorf("Instance creation failed. Instance is in ERROR state") + } + + if current.Status == status { + return true, nil + } + + return false, nil + }, (d.ActiveTimeout / 4), 4*time.Second) } -func (c *GenericClient) GetInstanceIpAddresses(d *Driver) ([]IpAddress, error) { +func (c *GenericClient) GetInstanceIPAddresses(d *Driver) ([]IPAddress, error) { server, err := c.GetServerDetail(d) if err != nil { return nil, err } - addresses := []IpAddress{} + addresses := []IPAddress{} for network, networkAddresses := range server.Addresses { for _, element := range networkAddresses.([]interface{}) { address := element.(map[string]interface{}) + version, ok := address["version"].(float64) + if !ok { + // Assume IPv4 if no version present. + version = 4 + } - addr := IpAddress{ - Network: network, - Address: address["addr"].(string), + addr := IPAddress{ + Network: network, + AddressType: Fixed, + Address: address["addr"].(string), + Version: int(version), } if tp, ok := address["OS-EXT-IPS:type"]; ok { @@ -161,21 +200,22 @@ func (c *GenericClient) GetInstanceIpAddresses(d *Driver) ([]IpAddress, error) { addresses = append(addresses, addr) } } + return addresses, nil } -func (c *GenericClient) GetNetworkId(d *Driver) (string, error) { - return c.getNetworkId(d, d.NetworkName) +func (c *GenericClient) GetNetworkID(d *Driver) (string, error) { + return c.getNetworkID(d, d.NetworkName) } -func (c *GenericClient) GetFloatingIpPoolId(d *Driver) (string, error) { - return c.getNetworkId(d, d.FloatingIpPool) +func (c *GenericClient) GetFloatingIPPoolID(d *Driver) (string, error) { + return c.getNetworkID(d, d.FloatingIpPool) } -func (c *GenericClient) getNetworkId(d *Driver, networkName string) (string, error) { +func (c *GenericClient) getNetworkID(d *Driver, networkName string) (string, error) { opts := networks.ListOpts{Name: networkName} pager := networks.List(c.Network, opts) - networkId := "" + networkID := "" err := pager.EachPage(func(page pagination.Page) (bool, error) { networkList, err := networks.ExtractNetworks(page) @@ -185,7 +225,7 @@ func (c *GenericClient) getNetworkId(d *Driver, networkName string) (string, err for _, n := range networkList { if n.Name == networkName { - networkId = n.ID + networkID = n.ID return false, nil } } @@ -193,12 +233,12 @@ func (c *GenericClient) getNetworkId(d *Driver, networkName string) (string, err return true, nil }) - return networkId, err + return networkID, err } -func (c *GenericClient) GetFlavorId(d *Driver) (string, error) { +func (c *GenericClient) GetFlavorID(d *Driver) (string, error) { pager := flavors.ListDetail(c.Compute, nil) - flavorId := "" + flavorID := "" err := pager.EachPage(func(page pagination.Page) (bool, error) { flavorList, err := flavors.ExtractFlavors(page) @@ -208,7 +248,7 @@ func (c *GenericClient) GetFlavorId(d *Driver) (string, error) { for _, f := range flavorList { if f.Name == d.FlavorName { - flavorId = f.ID + flavorID = f.ID return false, nil } } @@ -216,13 +256,13 @@ func (c *GenericClient) GetFlavorId(d *Driver) (string, error) { return true, nil }) - return flavorId, err + return flavorID, err } -func (c *GenericClient) GetImageId(d *Driver) (string, error) { +func (c *GenericClient) GetImageID(d *Driver) (string, error) { opts := images.ListOpts{Name: d.ImageName} pager := images.ListDetail(c.Compute, opts) - imageId := "" + imageID := "" err := pager.EachPage(func(page pagination.Page) (bool, error) { imageList, err := images.ExtractImages(page) @@ -232,7 +272,30 @@ func (c *GenericClient) GetImageId(d *Driver) (string, error) { for _, i := range imageList { if i.Name == d.ImageName { - imageId = i.ID + imageID = i.ID + return false, nil + } + } + + return true, nil + }) + + return imageID, err +} + +func (c *GenericClient) GetTenantID(d *Driver) (string, error) { + pager := tenants.List(c.Identity, nil) + tenantId := "" + + err := pager.EachPage(func(page pagination.Page) (bool, error) { + tenantList, err := tenants.ExtractTenants(page) + if err != nil { + return false, err + } + + for _, i := range tenantList { + if i.Name == d.TenantName { + tenantId = i.ID return false, nil } } @@ -240,7 +303,15 @@ func (c *GenericClient) GetImageId(d *Driver) (string, error) { return true, nil }) - return imageId, err + return tenantId, err +} + +func (c *GenericClient) GetPublicKey(keyPairName string) ([]byte, error) { + kp, err := keypairs.Get(c.Compute, keyPairName).Extract() + if err != nil { + return nil, err + } + return []byte(kp.PublicKey), nil } func (c *GenericClient) CreateKeyPair(d *Driver, name string, publicKey string) error { @@ -269,23 +340,48 @@ func (c *GenericClient) GetServerDetail(d *Driver) (*servers.Server, error) { return server, nil } -func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIp *FloatingIp, portId string) error { - if floatingIp.Id == "" { +func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIP *FloatingIP) error { + if d.ComputeNetwork { + return c.assignNovaFloatingIP(d, floatingIP) + } + return c.assignNeutronFloatingIP(d, floatingIP) +} + +func (c *GenericClient) assignNovaFloatingIP(d *Driver, floatingIP *FloatingIP) error { + if floatingIP.Ip == "" { + f, err := compute_ips.Create(c.Compute, compute_ips.CreateOpts{ + Pool: d.FloatingIpPool, + }).Extract() + if err != nil { + return err + } + floatingIP.Ip = f.IP + floatingIP.Pool = f.Pool + } + return compute_ips.Associate(c.Compute, d.MachineId, floatingIP.Ip).Err +} + +func (c *GenericClient) assignNeutronFloatingIP(d *Driver, floatingIP *FloatingIP) error { + portID, err := c.GetInstancePortID(d) + if err != nil { + return err + } + if floatingIP.Id == "" { f, err := floatingips.Create(c.Network, floatingips.CreateOpts{ FloatingNetworkID: d.FloatingIpPoolId, - PortID: portId, + PortID: portID, }).Extract() if err != nil { return err } - floatingIp.Id = f.ID - floatingIp.Ip = f.FloatingIP - floatingIp.NetworkId = f.FloatingNetworkID - floatingIp.PortId = f.PortID + floatingIP.Id = f.ID + floatingIP.Ip = f.FloatingIP + floatingIP.NetworkId = f.FloatingNetworkID + floatingIP.PortId = f.PortID return nil } - _, err := floatingips.Update(c.Network, floatingIp.Id, floatingips.UpdateOpts{ - PortID: portId, + _, err = floatingips.Update(c.Network, floatingIP.Id, floatingips.UpdateOpts{ + PortID: portID, }).Extract() if err != nil { return err @@ -293,19 +389,53 @@ func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIp *FloatingIp, port return nil } -func (c *GenericClient) GetFloatingIPs(d *Driver) ([]FloatingIp, error) { +func (c *GenericClient) GetFloatingIPs(d *Driver) ([]FloatingIP, error) { + if d.ComputeNetwork { + return c.getNovaNetworkFloatingIPs(d) + } + return c.getNeutronNetworkFloatingIPs(d) +} + +func (c *GenericClient) getNovaNetworkFloatingIPs(d *Driver) ([]FloatingIP, error) { + pager := compute_ips.List(c.Compute) + + ips := []FloatingIP{} + err := pager.EachPage(func(page pagination.Page) (continue_paging bool, err error) { + continue_paging, err = true, nil + ipListing, err := compute_ips.ExtractFloatingIPs(page) + + for _, ip := range ipListing { + if ip.InstanceID == "" && ip.Pool == d.FloatingIpPool { + ips = append(ips, FloatingIP{ + Id: ip.ID, + Ip: ip.IP, + Pool: ip.Pool, + }) + } + } + return + }) + return ips, err +} + +func (c *GenericClient) getNeutronNetworkFloatingIPs(d *Driver) ([]FloatingIP, error) { + log.Debug("Listing floating IPs", map[string]string{ + "FloatingNetworkId": d.FloatingIpPoolId, + "TenantID": d.TenantId, + }) pager := floatingips.List(c.Network, floatingips.ListOpts{ FloatingNetworkID: d.FloatingIpPoolId, + TenantID: d.TenantId, }) - ips := []FloatingIp{} + ips := []FloatingIP{} err := pager.EachPage(func(page pagination.Page) (bool, error) { floatingipList, err := floatingips.ExtractFloatingIPs(page) if err != nil { return false, err } for _, f := range floatingipList { - ips = append(ips, FloatingIp{ + ips = append(ips, FloatingIP{ Id: f.ID, Ip: f.FloatingIP, NetworkId: f.FloatingNetworkID, @@ -321,20 +451,20 @@ func (c *GenericClient) GetFloatingIPs(d *Driver) ([]FloatingIp, error) { return ips, nil } -func (c *GenericClient) GetInstancePortId(d *Driver) (string, error) { +func (c *GenericClient) GetInstancePortID(d *Driver) (string, error) { pager := ports.List(c.Network, ports.ListOpts{ DeviceID: d.MachineId, NetworkID: d.NetworkId, }) - var portId string + var portID string err := pager.EachPage(func(page pagination.Page) (bool, error) { portList, err := ports.ExtractPorts(page) if err != nil { return false, err } for _, port := range portList { - portId = port.ID + portID = port.ID return false, nil } return true, nil @@ -343,7 +473,7 @@ func (c *GenericClient) GetInstancePortId(d *Driver) (string, error) { if err != nil { return "", err } - return portId, nil + return portID, nil } func (c *GenericClient) InitComputeClient(d *Driver) error { @@ -362,6 +492,16 @@ func (c *GenericClient) InitComputeClient(d *Driver) error { return nil } +func (c *GenericClient) InitIdentityClient(d *Driver) error { + if c.Identity != nil { + return nil + } + + identity := openstack.NewIdentityV2(c.Provider) + c.Identity = identity + return nil +} + func (c *GenericClient) InitNetworkClient(d *Driver) error { if c.Network != nil { return nil @@ -393,15 +533,21 @@ func (c *GenericClient) Authenticate(d *Driver) error { return nil } - log.WithFields(log.Fields{ + log.Debug("Authenticating...", map[string]interface{}{ "AuthUrl": d.AuthUrl, + "Insecure": d.Insecure, + "CaCert": d.CaCert, + "DomainID": d.DomainID, + "DomainName": d.DomainName, "Username": d.Username, "TenantName": d.TenantName, "TenantID": d.TenantId, - }).Debug("Authenticating...") + }) opts := gophercloud.AuthOptions{ IdentityEndpoint: d.AuthUrl, + DomainID: d.DomainID, + DomainName: d.DomainName, Username: d.Username, Password: d.Password, TenantName: d.TenantName, @@ -409,11 +555,50 @@ func (c *GenericClient) Authenticate(d *Driver) error { AllowReauth: true, } - provider, err := openstack.AuthenticatedClient(opts) + provider, err := openstack.NewClient(opts.IdentityEndpoint) if err != nil { return err } + c.Provider = provider + c.Provider.UserAgent.Prepend(fmt.Sprintf("docker-machine/v%d", version.APIVersion)) + + err = c.SetTLSConfig(d) + if err != nil { + return err + } + + err = openstack.Authenticate(c.Provider, opts) + if err != nil { + return err + } + + return nil +} + +func (c *GenericClient) SetTLSConfig(d *Driver) error { + + config := &tls.Config{} + config.InsecureSkipVerify = d.Insecure + + if d.CaCert != "" { + // Use custom CA certificate(s) for root of trust + certpool := x509.NewCertPool() + pem, err := ioutil.ReadFile(d.CaCert) + if err != nil { + log.Error("Unable to read specified CA certificate(s)") + return err + } + + ok := certpool.AppendCertsFromPEM(pem) + if !ok { + return fmt.Errorf("Ill-formed CA certificate(s) PEM file") + } + config.RootCAs = certpool + } + + transport := &http.Transport{TLSClientConfig: config, Proxy: http.ProxyFromEnvironment} + c.Provider.HTTPClient.Transport = transport return nil } diff --git a/drivers/openstack/openstack.go b/drivers/openstack/openstack.go index 0f4a13c42d..7e305d840a 100644 --- a/drivers/openstack/openstack.go +++ b/drivers/openstack/openstack.go @@ -3,217 +3,289 @@ package openstack import ( "fmt" "io/ioutil" - "os/exec" - "path" - "strconv" + "net" + "net/http" "strings" "time" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/docker/utils" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" -) + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" -const ( - dockerConfigDir = "/etc/docker" + "github.com/rackspace/gophercloud" ) type Driver struct { - AuthUrl string - Username string - Password string - TenantName string - TenantId string - Region string - EndpointType string - MachineName string - MachineId string - FlavorName string - FlavorId string - ImageName string - ImageId string - KeyPairName string - NetworkName string - NetworkId string - SecurityGroups []string - FloatingIpPool string - FloatingIpPoolId string - SSHUser string - SSHPort int - Ip string - EnableDockerInstall bool - CaCertPath string - PrivateKeyPath string - storePath string - client Client -} - -type CreateFlags struct { - AuthUrl *string - Username *string - Password *string - TenantName *string - TenantId *string - Region *string - EndpointType *string - FlavorName *string - FlavorId *string - ImageName *string - ImageId *string - NetworkName *string - NetworkId *string - SecurityGroups *string - FloatingIpPool *string - SSHUser *string - SSHPort *int -} - -func init() { - drivers.Register("openstack", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) + *drivers.BaseDriver + AuthUrl string + ActiveTimeout int + Insecure bool + CaCert string + DomainID string + DomainName string + Username string + Password string + TenantName string + TenantId string + Region string + AvailabilityZone string + EndpointType string + MachineId string + FlavorName string + FlavorId string + ImageName string + ImageId string + KeyPairName string + NetworkName string + NetworkId string + UserData []byte + PrivateKeyFile string + SecurityGroups []string + FloatingIpPool string + ComputeNetwork bool + FloatingIpPoolId string + IpVersion int + ConfigDrive bool + metadata string + client Client + // ExistingKey keeps track of whether the key was created by us or we used an existing one. If an existing one was used, we shouldn't delete it when the machine is deleted. + ExistingKey bool } -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ +const ( + defaultSSHUser = "root" + defaultSSHPort = 22 + defaultActiveTimeout = 200 +) + +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ EnvVar: "OS_AUTH_URL", Name: "openstack-auth-url", Usage: "OpenStack authentication URL", Value: "", }, - cli.StringFlag{ + mcnflag.BoolFlag{ + EnvVar: "OS_INSECURE", + Name: "openstack-insecure", + Usage: "Disable TLS credential checking.", + }, + mcnflag.StringFlag{ + EnvVar: "OS_CACERT", + Name: "openstack-cacert", + Usage: "CA certificate bundle to verify against", + Value: "", + }, + mcnflag.StringFlag{ + EnvVar: "OS_DOMAIN_ID", + Name: "openstack-domain-id", + Usage: "OpenStack domain ID (identity v3 only)", + Value: "", + }, + mcnflag.StringFlag{ + EnvVar: "OS_DOMAIN_NAME", + Name: "openstack-domain-name", + Usage: "OpenStack domain name (identity v3 only)", + Value: "", + }, + mcnflag.StringFlag{ EnvVar: "OS_USERNAME", Name: "openstack-username", Usage: "OpenStack username", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_PASSWORD", Name: "openstack-password", Usage: "OpenStack password", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_TENANT_NAME", Name: "openstack-tenant-name", Usage: "OpenStack tenant name", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_TENANT_ID", Name: "openstack-tenant-id", Usage: "OpenStack tenant id", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_REGION_NAME", Name: "openstack-region", Usage: "OpenStack region name", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ + EnvVar: "OS_AVAILABILITY_ZONE", + Name: "openstack-availability-zone", + Usage: "OpenStack availability zone", + Value: "", + }, + mcnflag.StringFlag{ EnvVar: "OS_ENDPOINT_TYPE", Name: "openstack-endpoint-type", Usage: "OpenStack endpoint type (adminURL, internalURL or publicURL)", Value: "", }, - cli.StringFlag{ - Name: "openstack-flavor-id", - Usage: "OpenStack flavor id to use for the instance", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_FLAVOR_ID", + Name: "openstack-flavor-id", + Usage: "OpenStack flavor id to use for the instance", + Value: "", }, - cli.StringFlag{ - Name: "openstack-flavor-name", - Usage: "OpenStack flavor name to use for the instance", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_FLAVOR_NAME", + Name: "openstack-flavor-name", + Usage: "OpenStack flavor name to use for the instance", + Value: "", }, - cli.StringFlag{ - Name: "openstack-image-id", - Usage: "OpenStack image id to use for the instance", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_IMAGE_ID", + Name: "openstack-image-id", + Usage: "OpenStack image id to use for the instance", + Value: "", }, - cli.StringFlag{ - Name: "openstack-image-name", - Usage: "OpenStack image name to use for the instance", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_IMAGE_NAME", + Name: "openstack-image-name", + Usage: "OpenStack image name to use for the instance", + Value: "", }, - cli.StringFlag{ - Name: "openstack-net-id", - Usage: "OpenStack image name to use for the instance", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_KEYPAIR_NAME", + Name: "openstack-keypair-name", + Usage: "OpenStack keypair to use to SSH to the instance", + Value: "", }, - cli.StringFlag{ - Name: "openstack-net-name", - Usage: "OpenStack network name the machine will be connected on", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_NETWORK_ID", + Name: "openstack-net-id", + Usage: "OpenStack network id the machine will be connected on", + Value: "", }, - cli.StringFlag{ - Name: "openstack-sec-groups", - Usage: "OpenStack comma separated security groups for the machine", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_PRIVATE_KEY_FILE", + Name: "openstack-private-key-file", + Usage: "Private keyfile to use for SSH (absolute path)", + Value: "", }, - cli.StringFlag{ - Name: "openstack-floatingip-pool", - Usage: "OpenStack floating IP pool to get an IP from to assign to the instance", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_USER_DATA_FILE", + Name: "openstack-user-data-file", + Usage: "File containing an openstack userdata script", + Value: "", }, - cli.StringFlag{ - Name: "openstack-ssh-user", - Usage: "OpenStack SSH user", - Value: "root", + mcnflag.StringFlag{ + EnvVar: "OS_NETWORK_NAME", + Name: "openstack-net-name", + Usage: "OpenStack network name the machine will be connected on", + Value: "", }, - cli.IntFlag{ - Name: "openstack-ssh-port", - Usage: "OpenStack SSH port", - Value: 22, + mcnflag.StringFlag{ + EnvVar: "OS_SECURITY_GROUPS", + Name: "openstack-sec-groups", + Usage: "OpenStack comma separated security groups for the machine", + Value: "", }, - // Using a StringFlag rather than a BoolFlag because - // the BoolFlag default value is always false - cli.StringFlag{ - Name: "openstack-docker-install", - Usage: "Set if docker have to be installed on the machine", - Value: "true", + mcnflag.BoolFlag{ + EnvVar: "OS_NOVA_NETWORK", + Name: "openstack-nova-network", + Usage: "Use the nova networking services instead of neutron.", + }, + mcnflag.StringFlag{ + EnvVar: "OS_FLOATINGIP_POOL", + Name: "openstack-floatingip-pool", + Usage: "OpenStack floating IP pool to get an IP from to assign to the instance", + Value: "", + }, + mcnflag.IntFlag{ + EnvVar: "OS_IP_VERSION", + Name: "openstack-ip-version", + Usage: "OpenStack version of IP address assigned for the machine", + Value: 4, + }, + mcnflag.StringFlag{ + EnvVar: "OS_SSH_USER", + Name: "openstack-ssh-user", + Usage: "OpenStack SSH user", + Value: defaultSSHUser, + }, + mcnflag.IntFlag{ + EnvVar: "OS_SSH_PORT", + Name: "openstack-ssh-port", + Usage: "OpenStack SSH port", + Value: defaultSSHPort, + }, + mcnflag.IntFlag{ + EnvVar: "OS_ACTIVE_TIMEOUT", + Name: "openstack-active-timeout", + Usage: "OpenStack active timeout", + Value: defaultActiveTimeout, + }, + mcnflag.BoolFlag{ + EnvVar: "OS_CONFIG_DRIVE", + Name: "openstack-config-drive", + Usage: "Enables the OpenStack config drive for the instance", + }, + mcnflag.StringFlag{ + EnvVar: "OS_METADATA", + Name: "openstack-metadata", + Usage: "OpenStack Instance Metadata (e.g. key1,value1,key2,value2)", + Value: "", }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - log.WithFields(log.Fields{ - "machineName": machineName, - "storePath": storePath, - "caCert": caCert, - "privateKey": privateKey, - }).Debug("Instantiating OpenStack driver...") - - return NewDerivedDriver(machineName, storePath, &GenericClient{}, caCert, privateKey) +func NewDriver(hostName, storePath string) drivers.Driver { + return NewDerivedDriver(hostName, storePath) } -func NewDerivedDriver(machineName string, storePath string, client Client, caCert string, privateKey string) (*Driver, error) { +func NewDerivedDriver(hostName, storePath string) *Driver { return &Driver{ - MachineName: machineName, - storePath: storePath, - client: client, - CaCertPath: caCert, - PrivateKeyPath: privateKey, - }, nil + client: &GenericClient{}, + ActiveTimeout: defaultActiveTimeout, + BaseDriver: &drivers.BaseDriver{ + SSHUser: defaultSSHUser, + SSHPort: defaultSSHPort, + MachineName: hostName, + StorePath: storePath, + }, + } +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } +func (d *Driver) SetClient(client Client) { + d.client = client +} + +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return "openstack" } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.AuthUrl = flags.String("openstack-auth-url") + d.ActiveTimeout = flags.Int("openstack-active-timeout") + d.Insecure = flags.Bool("openstack-insecure") + d.CaCert = flags.String("openstack-cacert") + d.DomainID = flags.String("openstack-domain-id") + d.DomainName = flags.String("openstack-domain-name") d.Username = flags.String("openstack-username") d.Password = flags.String("openstack-password") d.TenantName = flags.String("openstack-tenant-name") d.TenantId = flags.String("openstack-tenant-id") d.Region = flags.String("openstack-region") + d.AvailabilityZone = flags.String("openstack-availability-zone") d.EndpointType = flags.String("openstack-endpoint-type") d.FlavorId = flags.String("openstack-flavor-id") d.FlavorName = flags.String("openstack-flavor-name") @@ -221,22 +293,39 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.ImageName = flags.String("openstack-image-name") d.NetworkId = flags.String("openstack-net-id") d.NetworkName = flags.String("openstack-net-name") + d.metadata = flags.String("openstack-metadata") if flags.String("openstack-sec-groups") != "" { d.SecurityGroups = strings.Split(flags.String("openstack-sec-groups"), ",") } d.FloatingIpPool = flags.String("openstack-floatingip-pool") + d.IpVersion = flags.Int("openstack-ip-version") + d.ComputeNetwork = flags.Bool("openstack-nova-network") d.SSHUser = flags.String("openstack-ssh-user") d.SSHPort = flags.Int("openstack-ssh-port") - - installDocker, err := strconv.ParseBool(flags.String("openstack-docker-install")) - if err != nil { - return err + d.ExistingKey = flags.String("openstack-keypair-name") != "" + d.KeyPairName = flags.String("openstack-keypair-name") + d.PrivateKeyFile = flags.String("openstack-private-key-file") + d.ConfigDrive = flags.Bool("openstack-config-drive") + + if flags.String("openstack-user-data-file") != "" { + userData, err := ioutil.ReadFile(flags.String("openstack-user-data-file")) + if err == nil { + d.UserData = userData + } else { + return err + } } - d.EnableDockerInstall = installDocker + + d.SetSwarmConfigFromFlags(flags) + return d.checkConfig() } func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } + ip, err := d.GetIP() if err != nil { return "", err @@ -244,15 +333,16 @@ func (d *Driver) GetURL() (string, error) { if ip == "" { return "", nil } - return fmt.Sprintf("tcp://%s:2376", ip), nil + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil } func (d *Driver) GetIP() (string, error) { - if d.Ip != "" { - return d.Ip, nil + if d.IPAddress != "" { + return d.IPAddress, nil } - log.WithField("MachineId", d.MachineId).Debug("Looking for the IP address...") + log.Debug("Looking for the IP address...", map[string]string{"MachineId": d.MachineId}) if err := d.initCompute(); err != nil { return "", err @@ -265,12 +355,12 @@ func (d *Driver) GetIP() (string, error) { // Looking for the IP address in a retry loop to deal with OpenStack latency for retryCount := 0; retryCount < 200; retryCount++ { - addresses, err := d.client.GetInstanceIpAddresses(d) + addresses, err := d.client.GetInstanceIPAddresses(d) if err != nil { return "", err } for _, a := range addresses { - if a.AddressType == addressType { + if a.AddressType == addressType && a.Version == d.IpVersion { return a.Address, nil } } @@ -280,7 +370,7 @@ func (d *Driver) GetIP() (string, error) { } func (d *Driver) GetState() (state.State, error) { - log.WithField("MachineId", d.MachineId).Debug("Get status for OpenStack instance...") + log.Debug("Get status for OpenStack instance...", map[string]string{"MachineId": d.MachineId}) if err := d.initCompute(); err != nil { return state.None, err } @@ -290,10 +380,10 @@ func (d *Driver) GetState() (state.State, error) { return state.None, err } - log.WithFields(log.Fields{ + log.Debug("State for OpenStack instance", map[string]string{ "MachineId": d.MachineId, "State": s, - }).Debug("State for OpenStack instance") + }) switch s { case "ACTIVE": @@ -312,18 +402,19 @@ func (d *Driver) GetState() (state.State, error) { return state.None, nil } -func (d *Driver) PreCreateCheck() error { - return nil -} - func (d *Driver) Create() error { - d.KeyPairName = fmt.Sprintf("%s-%s", d.MachineName, utils.GenerateRandomID()) - if err := d.resolveIds(); err != nil { return err } - if err := d.createSSHKey(); err != nil { - return err + if d.KeyPairName != "" { + if err := d.loadSSHKey(); err != nil { + return err + } + } else { + d.KeyPairName = fmt.Sprintf("%s-%s", d.MachineName, mcnutils.GenerateRandomID()) + if err := d.createSSHKey(); err != nil { + return err + } } if err := d.createMachine(); err != nil { return err @@ -332,158 +423,110 @@ func (d *Driver) Create() error { return err } if d.FloatingIpPool != "" { - if err := d.assignFloatingIp(); err != nil { + if err := d.assignFloatingIP(); err != nil { return err } } - if err := d.lookForIpAddress(); err != nil { + if err := d.lookForIPAddress(); err != nil { return err } - if err := d.waitForSSHServer(); err != nil { - return err - } - if d.EnableDockerInstall { - if err := d.installDocker(); err != nil { - return err - } - } return nil } func (d *Driver) Start() error { - log.WithField("MachineId", d.MachineId).Info("Starting OpenStack instance...") if err := d.initCompute(); err != nil { return err } - if err := d.client.StartInstance(d); err != nil { - return err - } - return d.waitForInstanceToStart() + + return d.client.StartInstance(d) } func (d *Driver) Stop() error { - log.WithField("MachineId", d.MachineId).Info("Stopping OpenStack instance...") if err := d.initCompute(); err != nil { return err } - if err := d.client.StopInstance(d); err != nil { - return err - } - - log.WithField("MachineId", d.MachineId).Info("Waiting for the OpenStack instance to stop...") - if err := d.client.WaitForInstanceStatus(d, "SHUTOFF", 200); err != nil { - return err - } - return nil -} -func (d *Driver) Remove() error { - log.WithField("MachineId", d.MachineId).Info("Deleting OpenStack instance...") - if err := d.initCompute(); err != nil { - return err - } - if err := d.client.DeleteInstance(d); err != nil { - return err - } - log.WithField("Name", d.KeyPairName).Info("Deleting Key Pair...") - if err := d.client.DeleteKeyPair(d, d.KeyPairName); err != nil { - return err - } - return nil + return d.client.StopInstance(d) } func (d *Driver) Restart() error { - log.WithField("MachineId", d.MachineId).Info("Restarting OpenStack instance...") if err := d.initCompute(); err != nil { return err } - if err := d.client.RestartInstance(d); err != nil { - return err - } - return d.waitForInstanceToStart() + + return d.client.RestartInstance(d) } func (d *Driver) Kill() error { return d.Stop() } -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { +func (d *Driver) Remove() error { + log.Debug("deleting instance...", map[string]string{"MachineId": d.MachineId}) + log.Info("Deleting OpenStack instance...") + if err := d.initCompute(); err != nil { return err } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err + if err := d.client.DeleteInstance(d); err != nil { + if gopherErr, ok := err.(*gophercloud.UnexpectedResponseCodeError); ok { + if gopherErr.Actual == http.StatusNotFound { + log.Warn("Remote instance does not exist, proceeding with removing local reference") + } else { + return err + } + } else { + return err + } } - if err := cmd.Run(); err != nil { - return err + if !d.ExistingKey { + log.Debug("deleting key pair...", map[string]string{"Name": d.KeyPairName}) + if err := d.client.DeleteKeyPair(d, d.KeyPairName); err != nil { + if gopherErr, ok := err.(*gophercloud.UnexpectedResponseCodeError); ok { + if gopherErr.Actual == http.StatusNotFound { + log.Warn("Keypair already deleted") + } else { + return err + } + } else { + return err + } + } } - return nil } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() - if err != nil { - return nil, err - } +func (d *Driver) GetMetadata() map[string]string { + metadata := make(map[string]string) - if len(args) != 0 && d.SSHUser != "root" { - cmd := strings.Replace(strings.Join(args, " "), "'", "\\'", -1) - args = []string{"sudo", "sh", "-c", fmt.Sprintf("'%s'", cmd)} + if d.metadata != "" { + items := strings.Split(d.metadata, ",") + if len(items) > 0 && len(items)%2 != 0 { + log.Warnf("Metadata are not key value in pairs. %d elements found", len(items)) + } + for i := 0; i < len(items)-1; i += 2 { + metadata[items[i]] = items[i+1] + } } - log.WithField("MachineId", d.MachineId).Debug("Command: %s", args) - return ssh.GetSSHCommand(ip, d.SSHPort, d.SSHUser, d.sshKeyPath(), args...), nil + return metadata } const ( errorMandatoryEnvOrOption string = "%s must be specified either using the environment variable %s or the CLI option %s" errorMandatoryOption string = "%s must be specified using the CLI option %s" errorExclusiveOptions string = "Either %s or %s must be specified, not both" - errorMandatoryTenantNameOrId string = "Tenant id or name must be provided either using one of the environment variables OS_TENANT_ID and OS_TENANT_NAME or one of the CLI options --openstack-tenant-id and --openstack-tenant-name" + errorBothOptions string = "Both %s and %s must be specified" + errorMandatoryTenantNameOrID string = "Tenant id or name must be provided either using one of the environment variables OS_TENANT_ID and OS_TENANT_NAME or one of the CLI options --openstack-tenant-id and --openstack-tenant-name" errorWrongEndpointType string = "Endpoint type must be 'publicURL', 'adminURL' or 'internalURL'" errorUnknownFlavorName string = "Unable to find flavor named %s" errorUnknownImageName string = "Unable to find image named %s" errorUnknownNetworkName string = "Unable to find network named %s" + errorUnknownTenantName string = "Unable to find tenant named %s" ) func (d *Driver) checkConfig() error { if d.AuthUrl == "" { - return fmt.Errorf(errorMandatoryEnvOrOption, "Autentication URL", "OS_AUTH_URL", "--openstack-auth-url") + return fmt.Errorf(errorMandatoryEnvOrOption, "Authentication URL", "OS_AUTH_URL", "--openstack-auth-url") } if d.Username == "" { return fmt.Errorf(errorMandatoryEnvOrOption, "Username", "OS_USERNAME", "--openstack-username") @@ -492,7 +535,7 @@ func (d *Driver) checkConfig() error { return fmt.Errorf(errorMandatoryEnvOrOption, "Password", "OS_PASSWORD", "--openstack-password") } if d.TenantName == "" && d.TenantId == "" { - return fmt.Errorf(errorMandatoryTenantNameOrId) + return fmt.Errorf(errorMandatoryTenantNameOrID) } if d.FlavorName == "" && d.FlavorId == "" { @@ -515,79 +558,82 @@ func (d *Driver) checkConfig() error { if d.EndpointType != "" && (d.EndpointType != "publicURL" && d.EndpointType != "adminURL" && d.EndpointType != "internalURL") { return fmt.Errorf(errorWrongEndpointType) } + if (d.KeyPairName != "" && d.PrivateKeyFile == "") || (d.KeyPairName == "" && d.PrivateKeyFile != "") { + return fmt.Errorf(errorBothOptions, "KeyPairName", "PrivateKeyFile") + } return nil } func (d *Driver) resolveIds() error { - if d.NetworkName != "" { + if d.NetworkName != "" && !d.ComputeNetwork { if err := d.initNetwork(); err != nil { return err } - networkId, err := d.client.GetNetworkId(d) + networkID, err := d.client.GetNetworkID(d) if err != nil { return err } - if networkId == "" { + if networkID == "" { return fmt.Errorf(errorUnknownNetworkName, d.NetworkName) } - d.NetworkId = networkId - log.WithFields(log.Fields{ + d.NetworkId = networkID + log.Debug("Found network id using its name", map[string]string{ "Name": d.NetworkName, "ID": d.NetworkId, - }).Debug("Found network id using its name") + }) } if d.FlavorName != "" { if err := d.initCompute(); err != nil { return err } - flavorId, err := d.client.GetFlavorId(d) + flavorID, err := d.client.GetFlavorID(d) if err != nil { return err } - if flavorId == "" { + if flavorID == "" { return fmt.Errorf(errorUnknownFlavorName, d.FlavorName) } - d.FlavorId = flavorId - log.WithFields(log.Fields{ + d.FlavorId = flavorID + log.Debug("Found flavor id using its name", map[string]string{ "Name": d.FlavorName, "ID": d.FlavorId, - }).Debug("Found flavor id using its name") + }) } if d.ImageName != "" { if err := d.initCompute(); err != nil { return err } - imageId, err := d.client.GetImageId(d) + imageID, err := d.client.GetImageID(d) if err != nil { return err } - if imageId == "" { + if imageID == "" { return fmt.Errorf(errorUnknownImageName, d.ImageName) } - d.ImageId = imageId - log.WithFields(log.Fields{ + d.ImageId = imageID + log.Debug("Found image id using its name", map[string]string{ "Name": d.ImageName, "ID": d.ImageId, - }).Debug("Found image id using its name") + }) } - if d.FloatingIpPool != "" { + if d.FloatingIpPool != "" && !d.ComputeNetwork { if err := d.initNetwork(); err != nil { return err } - f, err := d.client.GetFloatingIpPoolId(d) + f, err := d.client.GetFloatingIPPoolID(d) if err != nil { return err @@ -598,10 +644,31 @@ func (d *Driver) resolveIds() error { } d.FloatingIpPoolId = f - log.WithFields(log.Fields{ + log.Debug("Found floating IP pool id using its name", map[string]string{ "Name": d.FloatingIpPool, "ID": d.FloatingIpPoolId, - }).Debug("Found floating IP pool id using its name") + }) + } + + if d.TenantName != "" && d.TenantId == "" { + if err := d.initIdentity(); err != nil { + return err + } + tenantId, err := d.client.GetTenantID(d) + + if err != nil { + return err + } + + if tenantId == "" { + return fmt.Errorf(errorUnknownTenantName, d.TenantName) + } + + d.TenantId = tenantId + log.Debug("Found tenant id using its name", map[string]string{ + "Name": d.TenantName, + "ID": d.TenantId, + }) } return nil @@ -617,6 +684,16 @@ func (d *Driver) initCompute() error { return nil } +func (d *Driver) initIdentity() error { + if err := d.client.Authenticate(d); err != nil { + return err + } + if err := d.client.InitIdentityClient(d); err != nil { + return err + } + return nil +} + func (d *Driver) initNetwork() error { if err := d.client.Authenticate(d); err != nil { return err @@ -627,9 +704,34 @@ func (d *Driver) initNetwork() error { return nil } +func (d *Driver) loadSSHKey() error { + log.Debug("Loading Key Pair", d.KeyPairName) + if err := d.initCompute(); err != nil { + return err + } + log.Debug("Loading Private Key from", d.PrivateKeyFile) + privateKey, err := ioutil.ReadFile(d.PrivateKeyFile) + if err != nil { + return err + } + publicKey, err := d.client.GetPublicKey(d.KeyPairName) + if err != nil { + return err + } + if err := ioutil.WriteFile(d.privateSSHKeyPath(), privateKey, 0600); err != nil { + return err + } + if err := ioutil.WriteFile(d.publicSSHKeyPath(), publicKey, 0600); err != nil { + return err + } + + return nil +} + func (d *Driver) createSSHKey() error { - log.WithField("Name", d.KeyPairName).Debug("Creating Key Pair...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + sanitizeKeyPairName(&d.KeyPairName) + log.Debug("Creating Key Pair...", map[string]string{"Name": d.KeyPairName}) + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } publicKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) @@ -647,29 +749,31 @@ func (d *Driver) createSSHKey() error { } func (d *Driver) createMachine() error { - log.WithFields(log.Fields{ + log.Debug("Creating OpenStack instance...", map[string]string{ "FlavorId": d.FlavorId, "ImageId": d.ImageId, - }).Debug("Creating OpenStack instance...") + }) if err := d.initCompute(); err != nil { return err } - instanceId, err := d.client.CreateInstance(d) + instanceID, err := d.client.CreateInstance(d) if err != nil { return err } - d.MachineId = instanceId + d.MachineId = instanceID return nil } -func (d *Driver) assignFloatingIp() error { +func (d *Driver) assignFloatingIP() error { + var err error - if err := d.initNetwork(); err != nil { - return err + if d.ComputeNetwork { + err = d.initCompute() + } else { + err = d.initNetwork() } - portId, err := d.client.GetInstancePortId(d) if err != nil { return err } @@ -679,118 +783,67 @@ func (d *Driver) assignFloatingIp() error { return err } - var floatingIp *FloatingIp + var floatingIP *FloatingIP - log.WithFields(log.Fields{ + log.Debugf("Looking for an available floating IP", map[string]string{ "MachineId": d.MachineId, "Pool": d.FloatingIpPool, - }).Debugf("Looking for an available floating IP") + }) for _, ip := range ips { if ip.PortId == "" { - log.WithFields(log.Fields{ + log.Debug("Available floating IP found", map[string]string{ "MachineId": d.MachineId, "IP": ip.Ip, - }).Debugf("Available floating IP found") - floatingIp = &ip + }) + floatingIP = &ip break } } - if floatingIp == nil { - floatingIp = &FloatingIp{} - log.WithField("MachineId", d.MachineId).Debugf("No available floating IP found. Allocating a new one...") + if floatingIP == nil { + floatingIP = &FloatingIP{} + log.Debug("No available floating IP found. Allocating a new one...", map[string]string{"MachineId": d.MachineId}) } else { - log.WithField("MachineId", d.MachineId).Debugf("Assigning floating IP to the instance") + log.Debug("Assigning floating IP to the instance", map[string]string{"MachineId": d.MachineId}) } - if err := d.client.AssignFloatingIP(d, floatingIp, portId); err != nil { + if err := d.client.AssignFloatingIP(d, floatingIP); err != nil { return err } - d.Ip = floatingIp.Ip + d.IPAddress = floatingIP.Ip return nil } func (d *Driver) waitForInstanceActive() error { - log.WithField("MachineId", d.MachineId).Debug("Waiting for the OpenStack instance to be ACTIVE...") - if err := d.client.WaitForInstanceStatus(d, "ACTIVE", 200); err != nil { + log.Debug("Waiting for the OpenStack instance to be ACTIVE...", map[string]string{"MachineId": d.MachineId}) + if err := d.client.WaitForInstanceStatus(d, "ACTIVE"); err != nil { return err } return nil } -func (d *Driver) lookForIpAddress() error { +func (d *Driver) lookForIPAddress() error { ip, err := d.GetIP() if err != nil { return err } - d.Ip = ip - log.WithFields(log.Fields{ + d.IPAddress = ip + log.Debug("IP address found", map[string]string{ "IP": ip, "MachineId": d.MachineId, - }).Debug("IP address found") - return nil -} - -func (d *Driver) waitForSSHServer() error { - ip, err := d.GetIP() - if err != nil { - return err - } - log.WithFields(log.Fields{ - "MachineId": d.MachineId, - "IP": ip, - }).Debug("Waiting for the SSH server to be started...") - return ssh.WaitForTCP(fmt.Sprintf("%s:%d", ip, d.SSHPort)) -} - -func (d *Driver) waitForInstanceToStart() error { - if err := d.waitForInstanceActive(); err != nil { - return err - } - return d.waitForSSHServer() -} - -func (d *Driver) installDocker() error { - log.WithField("MachineId", d.MachineId).Debug("Installing docker daemon on the machine") - - if err := d.sshExec([]string{ - `apt-get install -y curl`, - `curl -sSL https://get.docker.com | sh`, - }); err != nil { - log.Error("The docker installation failed.") - log.Error( - "The driver assumes that your instance is running Ubuntu. If this is not the case, you should ", - "use the option --openstack-docker-install=false (or --{provider}-docker-install=false) when ", - "creating a machine, and then install and configure docker manually.", - ) - log.Error( - `Also, you can use "machine ssh" to manually configure docker on this host.`, - ) - - // Don't return this ssh error so that host creation succeeds and "machine ssh" and "machine rm" - // are usable. - } + }) return nil } -func (d *Driver) sshExec(commands []string) error { - for _, command := range commands { - sshCmd, err := d.GetSSHCommand(command) - if err != nil { - return err - } - if err := sshCmd.Run(); err != nil { - return err - } - } - return nil +func (d *Driver) privateSSHKeyPath() string { + return d.GetSSHKeyPath() } -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" } -func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" +func sanitizeKeyPairName(s *string) { + *s = strings.Replace(*s, ".", "_", -1) } diff --git a/drivers/openstack/openstack_test.go b/drivers/openstack/openstack_test.go new file mode 100644 index 0000000000..49134c0855 --- /dev/null +++ b/drivers/openstack/openstack_test.go @@ -0,0 +1,29 @@ +package openstack + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "openstack-auth-url": "http://url", + "openstack-username": "user", + "openstack-password": "pwd", + "openstack-tenant-id": "ID", + "openstack-flavor-id": "ID", + "openstack-image-id": "ID", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/rackspace/client.go b/drivers/rackspace/client.go index f771cae2da..b73263fd06 100644 --- a/drivers/rackspace/client.go +++ b/drivers/rackspace/client.go @@ -3,8 +3,9 @@ package rackspace import ( "fmt" - log "github.com/Sirupsen/logrus" "github.com/docker/machine/drivers/openstack" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/version" "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/rackspace" ) @@ -16,7 +17,6 @@ func unsupportedOpErr(operation string) error { // Client is a Rackspace specialization of the generic OpenStack driver. type Client struct { openstack.GenericClient - driver *Driver } @@ -26,9 +26,9 @@ func (c *Client) Authenticate(d *openstack.Driver) error { return nil } - log.WithFields(log.Fields{ + log.Debug("Authenticating to Rackspace.", map[string]string{ "Username": d.Username, - }).Debug("Authenticating to Rackspace.") + }) apiKey := c.driver.APIKey opts := gophercloud.AuthOptions{ @@ -36,10 +36,18 @@ func (c *Client) Authenticate(d *openstack.Driver) error { APIKey: apiKey, } - provider, err := rackspace.AuthenticatedClient(opts) + provider, err := rackspace.NewClient(rackspace.RackspaceUSIdentity) if err != nil { return err } + + provider.UserAgent.Prepend(fmt.Sprintf("docker-machine/v%d", version.APIVersion)) + + err = rackspace.Authenticate(provider, opts) + if err != nil { + return err + } + c.Provider = provider return nil @@ -55,13 +63,13 @@ func (c *Client) StopInstance(d *openstack.Driver) error { return unsupportedOpErr("stop") } -// GetInstanceIpAddresses can be short-circuited with the server's AccessIPv4Addr on Rackspace. -func (c *Client) GetInstanceIpAddresses(d *openstack.Driver) ([]openstack.IpAddress, error) { +// GetInstanceIPAddresses can be short-circuited with the server's AccessIPv4Addr on Rackspace. +func (c *Client) GetInstanceIPAddresses(d *openstack.Driver) ([]openstack.IPAddress, error) { server, err := c.GetServerDetail(d) if err != nil { return nil, err } - return []openstack.IpAddress{ + return []openstack.IPAddress{ { Network: "public", Address: server.AccessIPv4, diff --git a/drivers/rackspace/rackspace.go b/drivers/rackspace/rackspace.go index fac02d4e0a..5e6bb49720 100644 --- a/drivers/rackspace/rackspace.go +++ b/drivers/rackspace/rackspace.go @@ -3,14 +3,10 @@ package rackspace import ( "fmt" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" "github.com/docker/machine/drivers/openstack" -) - -const ( - dockerConfigDir = "/etc/docker" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" ) // Driver is a machine driver for Rackspace. It's a specialization of the generic OpenStack one. @@ -20,113 +16,101 @@ type Driver struct { APIKey string } -// CreateFlags stores the command-line arguments given to "machine create". -type CreateFlags struct { - Username *string - APIKey *string - Region *string - MachineName *string - EndpointType *string - ImageID *string - FlavorID *string - SSHUser *string - SSHPort *int - CaCertPath string - PrivateKeyPath string -} - -func init() { - drivers.Register("rackspace", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} +const ( + defaultRegionName = "IAD" + defaultEndpointType = "publicURL" + defaultFlavorID = "general1-1" + defaultSSHUser = "root" + defaultSSHPort = 22 + defaultDockerInstall = "true" + defaultActiveTimeout = 300 +) // GetCreateFlags registers the "machine create" flags recognized by this driver, including // their help text and defaults. -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ EnvVar: "OS_USERNAME", Name: "rackspace-username", Usage: "Rackspace account username", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_API_KEY", Name: "rackspace-api-key", Usage: "Rackspace API key", Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_REGION_NAME", Name: "rackspace-region", Usage: "Rackspace region name", - Value: "", + Value: defaultRegionName, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "OS_ENDPOINT_TYPE", Name: "rackspace-endpoint-type", Usage: "Rackspace endpoint type (adminURL, internalURL or the default publicURL)", - Value: "publicURL", + Value: defaultEndpointType, }, - cli.StringFlag{ - Name: "rackspace-image-id", - Usage: "Rackspace image ID. Default: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)", - Value: "", + mcnflag.StringFlag{ + EnvVar: "OS_IMAGE_ID", + Name: "rackspace-image-id", + Usage: "Rackspace image ID. Default: Ubuntu 16.04 LTS (Xenial Xerus) (PVHVM)", }, - cli.StringFlag{ - Name: "rackspace-flavor-id", - Usage: "Rackspace flavor ID. Default: General Purpose 1GB", - Value: "general1-1", + mcnflag.StringFlag{ + EnvVar: "OS_FLAVOR_ID", + Name: "rackspace-flavor-id", + Usage: "Rackspace flavor ID. Default: General Purpose 1GB", + Value: defaultFlavorID, }, - cli.StringFlag{ - Name: "rackspace-ssh-user", - Usage: "SSH user for the newly booted machine. Set to root by default", - Value: "root", + mcnflag.StringFlag{ + EnvVar: "OS_SSH_USER", + Name: "rackspace-ssh-user", + Usage: "SSH user for the newly booted machine. Set to root by default", + Value: defaultSSHUser, }, - cli.IntFlag{ - Name: "rackspace-ssh-port", - Usage: "SSH port for the newly booted machine. Set to 22 by default", - Value: 22, + mcnflag.IntFlag{ + EnvVar: "OS_SSH_PORT", + Name: "rackspace-ssh-port", + Usage: "SSH port for the newly booted machine. Set to 22 by default", + Value: defaultSSHPort, }, - cli.StringFlag{ + mcnflag.StringFlag{ Name: "rackspace-docker-install", Usage: "Set if docker have to be installed on the machine", - Value: "true", + Value: defaultDockerInstall, + }, + mcnflag.IntFlag{ + EnvVar: "OS_ACTIVE_TIMEOUT", + Name: "rackspace-active-timeout", + Usage: "Rackspace active timeout", + Value: defaultActiveTimeout, }, } } // NewDriver instantiates a Rackspace driver. -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - log.WithFields(log.Fields{ - "machineName": machineName, - "storePath": storePath, - "caCert": caCert, - "privateKey": privateKey, - }).Debug("Instantiating Rackspace driver.") - - client := &Client{} - inner, err := openstack.NewDerivedDriver(machineName, storePath, client, caCert, privateKey) - if err != nil { - return nil, err +func NewDriver(machineName, storePath string) drivers.Driver { + log.Debug("Instantiating Rackspace driver.", map[string]string{"machineName": machineName}) + + inner := openstack.NewDerivedDriver(machineName, storePath) + driver := &Driver{ + Driver: inner, } + inner.SetClient(&Client{ + driver: driver, + }) - driver := &Driver{Driver: inner} - client.driver = driver - return driver, nil + return driver } -// DriverName is the user-visible name of this driver. +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return "rackspace" } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - func missingEnvOrOption(setting, envVar, opt string) error { return fmt.Errorf( "%s must be specified either using the environment variable %s or the CLI option %s", @@ -138,6 +122,7 @@ func missingEnvOrOption(setting, envVar, opt string) error { // SetConfigFromFlags assigns and verifies the command-line arguments presented to the driver. func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.ActiveTimeout = flags.Int("rackspace-active-timeout") d.Username = flags.String("rackspace-username") d.APIKey = flags.String("rackspace-api-key") d.Region = flags.String("rackspace-region") @@ -146,7 +131,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.FlavorId = flags.String("rackspace-flavor-id") d.SSHUser = flags.String("rackspace-ssh-user") d.SSHPort = flags.Int("rackspace-ssh-port") - d.EnableDockerInstall = flags.String("rackspace-docker-install") == "true" + d.SetSwarmConfigFromFlags(flags) if d.Region == "" { return missingEnvOrOption("Region", "OS_REGION_NAME", "--rackspace-region") @@ -159,14 +144,14 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { } if d.ImageId == "" { - // Default to the Ubuntu 14.04 image. + // Default to the Ubuntu 16.04 image. // This is done here, rather than in the option registration, to keep the default value // from making "machine create --help" ugly. - d.ImageId = "598a4282-f14b-4e50-af4c-b3e52749d9f9" + d.ImageId = "821ba5f4-712d-4ec8-9c65-a3fa4bc500f9" } if d.EndpointType != "publicURL" && d.EndpointType != "adminURL" && d.EndpointType != "internalURL" { - return fmt.Errorf(`Invalid endpoint type "%s". Endpoint type must be publicURL, adminURL or internalURL.`, d.EndpointType) + return fmt.Errorf("invalid endpoint type %q (must be publicURL, adminURL or internalURL)", d.EndpointType) } return nil diff --git a/drivers/rackspace/rackspace_test.go b/drivers/rackspace/rackspace_test.go new file mode 100644 index 0000000000..79241538e4 --- /dev/null +++ b/drivers/rackspace/rackspace_test.go @@ -0,0 +1,27 @@ +package rackspace + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "rackspace-region": "REGION", + "rackspace-username": "user", + "rackspace-api-key": "KEY", + "rackspace-endpoint-type": "publicURL", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/softlayer/driver.go b/drivers/softlayer/driver.go index b19ea842fe..b2d37e889c 100644 --- a/drivers/softlayer/driver.go +++ b/drivers/softlayer/driver.go @@ -3,155 +3,181 @@ package softlayer import ( "fmt" "io/ioutil" + "net" "os" - "os/exec" - "path" "regexp" "time" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" ) const ( - dockerConfigDir = "/etc/docker" - ApiEndpoint = "https://api.softlayer.com/rest/v3" - DockerInstallUrl = "https://get.docker.com" + APIEndpoint = "https://api.softlayer.com/rest/v3" ) type Driver struct { - storePath string - IPAddress string - deviceConfig *deviceConfig - Id int - Client *Client - MachineName string - CaCertPath string - PrivateKeyPath string + *drivers.BaseDriver + deviceConfig *deviceConfig + Id int + Client *Client + SSHKeyID int } type deviceConfig struct { - DiskSize int - Cpu int - Hostname string - Domain string - Region string - Memory int - Image string - HourlyBilling bool - InstallScript string - LocalDisk bool - PrivateNet bool + DiskSize int + Cpu int + Hostname string + Domain string + Region string + Memory int + Image string + HourlyBilling bool + LocalDisk bool + PrivateNet bool + PublicVLAN int + PrivateVLAN int + NetworkMaxSpeed int } -func init() { - drivers.Register("softlayer", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) +const ( + defaultMemory = 1024 + defaultDiskSize = 0 + defaultRegion = "dal01" + defaultCpus = 1 + defaultImage = "UBUNTU_LATEST" + defaultPublicVLANIP = 0 + defaultPrivateVLANIP = 0 + defaultNetworkMaxSpeed = 100 +) + +func NewDriver(hostName, storePath string) drivers.Driver { + return &Driver{ + Client: &Client{ + Endpoint: APIEndpoint, + }, + deviceConfig: &deviceConfig{ + HourlyBilling: true, + DiskSize: defaultDiskSize, + Image: defaultImage, + Memory: defaultMemory, + Cpu: defaultCpus, + Region: defaultRegion, + PrivateVLAN: defaultPrivateVLANIP, + PublicVLAN: defaultPublicVLANIP, + NetworkMaxSpeed: defaultNetworkMaxSpeed, + }, + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } -func GetCreateFlags() []cli.Flag { +func (d *Driver) GetCreateFlags() []mcnflag.Flag { // Set hourly billing to true by default since codegangsta cli doesn't take default bool values if os.Getenv("SOFTLAYER_HOURLY_BILLING") == "" { os.Setenv("SOFTLAYER_HOURLY_BILLING", "true") } - return []cli.Flag{ - cli.IntFlag{ + return []mcnflag.Flag{ + mcnflag.IntFlag{ EnvVar: "SOFTLAYER_MEMORY", Name: "softlayer-memory", Usage: "Memory in MB for machine", - Value: 1024, + Value: defaultMemory, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "SOFTLAYER_DISK_SIZE", Name: "softlayer-disk-size", Usage: "Disk size for machine, a value of 0 uses the default size on softlayer", - Value: 0, + Value: defaultDiskSize, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_USER", Name: "softlayer-user", Usage: "softlayer user account name", - Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_API_KEY", Name: "softlayer-api-key", Usage: "softlayer user API key", - Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_REGION", Name: "softlayer-region", Usage: "softlayer region for machine", - Value: "dal01", + Value: defaultRegion, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "SOFTLAYER_CPU", Name: "softlayer-cpu", Usage: "number of CPU's for the machine", - Value: 1, + Value: defaultCpus, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_HOSTNAME", Name: "softlayer-hostname", - Usage: "hostname for the machine", - Value: "docker", + Usage: "hostname for the machine - defaults to machine name", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_DOMAIN", Name: "softlayer-domain", Usage: "domain name for machine", - Value: "", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_API_ENDPOINT", Name: "softlayer-api-endpoint", Usage: "softlayer api endpoint to use", - Value: ApiEndpoint, + Value: APIEndpoint, }, - cli.BoolFlag{ + mcnflag.BoolFlag{ EnvVar: "SOFTLAYER_HOURLY_BILLING", Name: "softlayer-hourly-billing", Usage: "set hourly billing for machine - on by default", }, - cli.BoolFlag{ + mcnflag.BoolFlag{ EnvVar: "SOFTLAYER_LOCAL_DISK", Name: "softlayer-local-disk", Usage: "use machine local disk instead of softlayer SAN", }, - cli.BoolFlag{ + mcnflag.BoolFlag{ EnvVar: "SOFTLAYER_PRIVATE_NET", Name: "softlayer-private-net-only", Usage: "Use only private networking", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "SOFTLAYER_IMAGE", Name: "softlayer-image", Usage: "OS image for machine", - Value: "UBUNTU_LATEST", + Value: defaultImage, + }, + mcnflag.IntFlag{ + EnvVar: "SOFTLAYER_PUBLIC_VLAN_ID", + Name: "softlayer-public-vlan-id", + Usage: "", + }, + mcnflag.IntFlag{ + EnvVar: "SOFTLAYER_PRIVATE_VLAN_ID", + Name: "softlayer-private-vlan-id", + Usage: "", }, - cli.StringFlag{ - EnvVar: "SOFTLAYER_INSTALL_SCRIPT", - Name: "softlayer-install-script", - Usage: "Install script to call after the machine is initialized (should install Docker)", - Value: DockerInstallUrl, + mcnflag.IntFlag{ + EnvVar: "SOFTLAYER_NETWORK_MAX_SPEED", + Name: "softlayer-network-max-speed", + Usage: "Max speed of public and private network", + Value: defaultNetworkMaxSpeed, }, } } func validateDeviceConfig(c *deviceConfig) error { - if c.Hostname == "" { - return fmt.Errorf("Missing required setting - --softlayer-hostname") - } if c.Domain == "" { return fmt.Errorf("Missing required setting - --softlayer-domain") } @@ -163,6 +189,16 @@ func validateDeviceConfig(c *deviceConfig) error { return fmt.Errorf("Missing required setting - --softlayer-cpu") } + if c.PrivateNet && c.PublicVLAN > 0 { + return fmt.Errorf("Can not specify both --softlayer-private-net-only and --softlayer-public-vlan-id") + } + if c.PublicVLAN > 0 && c.PrivateVLAN == 0 { + return fmt.Errorf("Missing required setting - --softlayer-private-vlan-id (because --softlayer-public-vlan-id is specified)") + } + if c.PrivateVLAN > 0 && !c.PrivateNet && c.PublicVLAN == 0 { + return fmt.Errorf("Missing required setting - --softlayer-public-vlan-id (because --softlayer-private-vlan-id is specified)") + } + return nil } @@ -190,23 +226,34 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { ApiKey: flags.String("softlayer-api-key"), } + d.SetSwarmConfigFromFlags(flags) + d.SSHUser = "root" + d.SSHPort = 22 + if err := validateClientConfig(d.Client); err != nil { return err } d.deviceConfig = &deviceConfig{ - Hostname: flags.String("softlayer-hostname"), - DiskSize: flags.Int("softlayer-disk-size"), - Cpu: flags.Int("softlayer-cpu"), - Domain: flags.String("softlayer-domain"), - Memory: flags.Int("softlayer-memory"), - PrivateNet: flags.Bool("softlayer-private-net-only"), - LocalDisk: flags.Bool("softlayer-local-disk"), - HourlyBilling: flags.Bool("softlayer-hourly-billing"), - InstallScript: flags.String("softlayer-install-script"), - Image: "UBUNTU_LATEST", - Region: flags.String("softlayer-region"), + Hostname: flags.String("softlayer-hostname"), + DiskSize: flags.Int("softlayer-disk-size"), + Cpu: flags.Int("softlayer-cpu"), + Domain: flags.String("softlayer-domain"), + Memory: flags.Int("softlayer-memory"), + PrivateNet: flags.Bool("softlayer-private-net-only"), + LocalDisk: flags.Bool("softlayer-local-disk"), + HourlyBilling: flags.Bool("softlayer-hourly-billing"), + Image: flags.String("softlayer-image"), + Region: flags.String("softlayer-region"), + PublicVLAN: flags.Int("softlayer-public-vlan-id"), + PrivateVLAN: flags.Int("softlayer-private-vlan-id"), + NetworkMaxSpeed: flags.Int("softlayer-network-max-speed"), + } + + if d.deviceConfig.Hostname == "" { + d.deviceConfig.Hostname = d.GetMachineName() } + return validateDeviceConfig(d.deviceConfig) } @@ -214,43 +261,16 @@ func (d *Driver) getClient() *Client { return d.Client } +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return "softlayer" } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err +func (d *Driver) GetURL() (string, error) { + if err := drivers.MustBeRunning(d); err != nil { + return "", err } - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) GetURL() (string, error) { ip, err := d.GetIP() if err != nil { return "", err @@ -258,14 +278,27 @@ func (d *Driver) GetURL() (string, error) { if ip == "" { return "", nil } - return "tcp://" + ip + ":2376", nil + + return "tcp://" + net.JoinHostPort(ip, "2376"), nil } func (d *Driver) GetIP() (string, error) { if d.IPAddress != "" { return d.IPAddress, nil } - return d.getClient().VirtualGuest().GetPublicIp(d.Id) + if d.deviceConfig != nil && d.deviceConfig.PrivateNet == true { + return d.getClient().VirtualGuest().GetPrivateIP(d.Id) + } + + if os.Getenv("SOFTLAYER_DOCKER_ON_PRIVATE_IP") == "" { + os.Setenv("SOFTLAYER_DOCKER_ON_PRIVATE_IP", "false") + } + + if os.Getenv("SOFTLAYER_DOCKER_ON_PRIVATE_IP") == "true" { + return d.getClient().VirtualGuest().GetPrivateIP(d.Id) + } else { + return d.getClient().VirtualGuest().GetPublicIP(d.Id) + } } func (d *Driver) GetState() (state.State, error) { @@ -285,55 +318,100 @@ func (d *Driver) GetState() (state.State, error) { return vmState, nil } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.IPAddress, 22, "root", d.sshKeyPath(), args...), nil +func (d *Driver) GetActiveTransaction() (string, error) { + t, err := d.getClient().VirtualGuest().ActiveTransaction(d.Id) + if err != nil { + return "", err + } + return t, nil } -func (d *Driver) PreCreateCheck() error { - return nil -} +func (d *Driver) waitForStart() { + log.Infof("Waiting for host to become available") + for { + s, err := d.GetState() + if err != nil { + log.Debugf("Failed to GetState - %+v", err) + continue + } -func (d *Driver) Create() error { - waitForStart := func() { - log.Infof("Waiting for host to become available") - for { - s, err := d.GetState() - if err != nil { - continue - } + if s == state.Running { + break + } else { + log.Debugf("Still waiting - state is %s...", s) + } + time.Sleep(2 * time.Second) + } +} - if s == state.Running { - break - } +func (d *Driver) getIP() (string, error) { + log.Infof("Getting Host IP") + for { + var ( + ip string + err error + ) + if d.deviceConfig.PrivateNet { + ip, err = d.getClient().VirtualGuest().GetPrivateIP(d.Id) + } else { + ip, err = d.getClient().VirtualGuest().GetPublicIP(d.Id) + } + if err != nil { time.Sleep(2 * time.Second) + continue } + + // if docker daemon is expected to run on private IP + // it will overwrite settings from PrivateNet + if os.Getenv("SOFTLAYER_DOCKER_ON_PRIVATE_IP") == "" { + os.Setenv("SOFTLAYER_DOCKER_ON_PRIVATE_IP", "false") + } + + if os.Getenv("SOFTLAYER_DOCKER_ON_PRIVATE_IP") == "true" { + ip, err = d.getClient().VirtualGuest().GetPrivateIP(d.Id) + } else { + ip, err = d.getClient().VirtualGuest().GetPublicIP(d.Id) + } + + // not a perfect regex, but should be just fine for our needs + exp := regexp.MustCompile(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`) + if exp.MatchString(ip) { + d.IPAddress = ip + return ip, nil + } + time.Sleep(2 * time.Second) } +} - getIp := func() { - log.Infof("Getting Host IP") - for { - var ( - ip string - err error - ) - if d.deviceConfig.PrivateNet { - ip, err = d.getClient().VirtualGuest().GetPrivateIp(d.Id) - } else { - ip, err = d.getClient().VirtualGuest().GetPublicIp(d.Id) - } - if err != nil { - time.Sleep(2 * time.Second) - continue - } - // not a perfect regex, but should be just fine for our needs - exp := regexp.MustCompile(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`) - if exp.MatchString(ip) { - d.IPAddress = ip +func (d *Driver) waitForSetupTransactions() { + log.Infof("Waiting for host setup transactions to complete") + // sometimes we'll hit a case where there's no active transaction, but if + // we check again in a few seconds, it moves to the next transaction. We + // don't want to get false-positives, so we check a few times in a row to make sure! + noActiveCount, maxNoActiveCount := 0, 3 + for { + t, err := d.GetActiveTransaction() + if err != nil { + noActiveCount = 0 + log.Debugf("Failed to GetActiveTransaction - %+v", err) + continue + } + + if t == "" { + if noActiveCount == maxNoActiveCount { break } - time.Sleep(2 * time.Second) + noActiveCount++ + } else { + noActiveCount = 0 + log.Debugf("Still waiting - active transaction is %s...", t) } + time.Sleep(2 * time.Second) } +} + +func (d *Driver) Create() error { + spec := d.buildHostSpec() log.Infof("Creating SSH key...") key, err := d.createSSHKey() @@ -341,20 +419,20 @@ func (d *Driver) Create() error { return err } - spec := d.buildHostSpec() - spec.SshKeys = []*SshKey{key} + log.Infof("SSH key %s (%d) created in SoftLayer", key.Label, key.Id) + d.SSHKeyID = key.Id + + spec.SshKeys = []*SSHKey{key} id, err := d.getClient().VirtualGuest().Create(spec) if err != nil { return fmt.Errorf("Error creating host: %q", err) } d.Id = id - getIp() - waitForStart() - ssh.WaitForTCP(d.IPAddress + ":22") - if err := d.setupHost(); err != nil { - fmt.Fprintf(os.Stderr, "Error setting up host config: %q", err) - } + d.getIP() + d.waitForStart() + d.waitForSetupTransactions() + return nil } @@ -365,19 +443,38 @@ func (d *Driver) buildHostSpec() *HostSpec { Cpu: d.deviceConfig.Cpu, Memory: d.deviceConfig.Memory, Datacenter: Datacenter{Name: d.deviceConfig.Region}, - InstallScript: d.deviceConfig.InstallScript, Os: d.deviceConfig.Image, HourlyBilling: d.deviceConfig.HourlyBilling, PrivateNetOnly: d.deviceConfig.PrivateNet, + LocalDisk: d.deviceConfig.LocalDisk, + } + + if d.deviceConfig.NetworkMaxSpeed > 0 { + spec.NetworkMaxSpeeds = []NetworkMaxSpeed{{MaxSpeed: d.deviceConfig.NetworkMaxSpeed}} } if d.deviceConfig.DiskSize > 0 { spec.BlockDevices = []BlockDevice{{Device: "0", DiskImage: DiskImage{Capacity: d.deviceConfig.DiskSize}}} } + if d.deviceConfig.PublicVLAN > 0 { + spec.PrimaryNetworkComponent = &NetworkComponent{ + NetworkVLAN: &NetworkVLAN{ + Id: d.deviceConfig.PublicVLAN, + }, + } + } + if d.deviceConfig.PrivateVLAN > 0 { + spec.PrimaryBackendNetworkComponent = &NetworkComponent{ + NetworkVLAN: &NetworkVLAN{ + Id: d.deviceConfig.PrivateVLAN, + }, + } + } + log.Debugf("Built host spec %#v", spec) return spec } -func (d *Driver) createSSHKey() (*SshKey, error) { - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { +func (d *Driver) createSSHKey() (*SSHKey, error) { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return nil, err } @@ -386,7 +483,7 @@ func (d *Driver) createSSHKey() (*SshKey, error) { return nil, err } - key, err := d.getClient().SshKey().Create(d.deviceConfig.Hostname, string(publicKey)) + key, err := d.getClient().SSHKey().Create(d.deviceConfig.Hostname, string(publicKey)) if err != nil { return nil, err } @@ -395,17 +492,11 @@ func (d *Driver) createSSHKey() (*SshKey, error) { } func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" -} - -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") + return d.GetSSHKeyPath() + ".pub" } -func (d *Driver) Kill() error { - return d.getClient().VirtualGuest().PowerOff(d.Id) -} func (d *Driver) Remove() error { + log.Infof("Canceling SoftLayer instance %d...", d.Id) var err error for i := 0; i < 5; i++ { if err = d.getClient().VirtualGuest().Cancel(d.Id); err != nil { @@ -414,48 +505,30 @@ func (d *Driver) Remove() error { } break } - return err -} -func (d *Driver) Restart() error { - return d.getClient().VirtualGuest().Reboot(d.Id) + if err != nil { + return err + } + + log.Infof("Removing SSH Key %d...", d.SSHKeyID) + if err = d.getClient().SSHKey().Delete(d.SSHKeyID); err != nil { + return err + } + + return nil } + func (d *Driver) Start() error { return d.getClient().VirtualGuest().PowerOn(d.Id) } + func (d *Driver) Stop() error { return d.getClient().VirtualGuest().PowerOff(d.Id) } -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() +func (d *Driver) Restart() error { + return d.getClient().VirtualGuest().Reboot(d.Id) } -func (d *Driver) setupHost() error { - log.Infof("Configuring host OS") - ssh.WaitForTCP(d.IPAddress + ":22") - // Wait to make sure docker is installed - for { - cmd, err := d.GetSSHCommand(`[ -f "$(which docker)" ] && [ -f "/etc/default/docker" ] || exit 1`) - if err != nil { - return err - } - if err := cmd.Run(); err == nil { - break - } - time.Sleep(2 * time.Second) - } - - return nil +func (d *Driver) Kill() error { + return d.Stop() } diff --git a/drivers/softlayer/driver_test.go b/drivers/softlayer/driver_test.go new file mode 100644 index 0000000000..ab8c6b4421 --- /dev/null +++ b/drivers/softlayer/driver_test.go @@ -0,0 +1,93 @@ +package softlayer + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/docker/machine/commands/commandstest" + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +const ( + testStoreDir = ".store-test" + machineTestName = "test-host" + machineTestCaCert = "test-cert" + machineTestPrivateKey = "test-key" +) + +func cleanup() error { + return os.RemoveAll(testStoreDir) +} + +func getTestStorePath() (string, error) { + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + return "", err + } + mcndirs.BaseDir = tmpDir + return tmpDir, nil +} + +func getDefaultTestDriverFlags() *commandstest.FakeFlagger { + return &commandstest.FakeFlagger{ + Data: map[string]interface{}{ + "name": "test", + "url": "unix:///var/run/docker.sock", + "softlayer-api-key": "12345", + "softlayer-user": "abcdefg", + "softlayer-api-endpoint": "https://api.softlayer.com/rest/v3", + "softlayer-image": "MY_TEST_IMAGE", + }, + } +} + +func getTestDriver() (*Driver, error) { + storePath, err := getTestStorePath() + if err != nil { + return nil, err + } + defer cleanup() + + d := NewDriver(machineTestName, storePath) + d.SetConfigFromFlags(getDefaultTestDriverFlags()) + drv := d.(*Driver) + return drv, nil +} + +func TestSetConfigFromFlagsSetsImage(t *testing.T) { + d, err := getTestDriver() + + if assert.NoError(t, err) { + assert.Equal(t, "MY_TEST_IMAGE", d.deviceConfig.Image) + } +} + +func TestHostnameDefaultsToMachineName(t *testing.T) { + d, err := getTestDriver() + if assert.NoError(t, err) { + assert.Equal(t, machineTestName, d.deviceConfig.Hostname) + } +} + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "softlayer-api-key": "KEY", + "softlayer-user": "user", + "softlayer-api-endpoint": "ENDPOINT", + "softlayer-domain": "DOMAIN", + "softlayer-region": "REGION", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/softlayer/softlayer.go b/drivers/softlayer/softlayer.go index e094b50459..6d10905dd8 100644 --- a/drivers/softlayer/softlayer.go +++ b/drivers/softlayer/softlayer.go @@ -16,21 +16,36 @@ type Client struct { } type HostSpec struct { - Hostname string `json:"hostname"` - Domain string `json:"domain"` - Cpu int `json:"startCpus"` - Memory int `json:"maxMemory"` - Datacenter Datacenter `json:"datacenter"` - SshKeys []*SshKey `json:"sshKeys"` - BlockDevices []BlockDevice `json:"blockDevices"` - InstallScript string `json:"postInstallScriptUri"` - PrivateNetOnly bool `json:"privateNetworkOnlyFlag"` - Os string `json:"operatingSystemReferenceCode"` - HourlyBilling bool `json:"hourlyBillingFlag"` - LocalDisk bool `json:"localDiskFlag"` + Hostname string `json:"hostname"` + Domain string `json:"domain"` + Cpu int `json:"startCpus"` + Memory int `json:"maxMemory"` + Datacenter Datacenter `json:"datacenter"` + SshKeys []*SSHKey `json:"sshKeys"` + BlockDevices []BlockDevice `json:"blockDevices"` + NetworkMaxSpeeds []NetworkMaxSpeed `json:"networkComponents"` + InstallScript string `json:"postInstallScriptUri"` + PrivateNetOnly bool `json:"privateNetworkOnlyFlag"` + Os string `json:"operatingSystemReferenceCode"` + HourlyBilling bool `json:"hourlyBillingFlag"` + LocalDisk bool `json:"localDiskFlag"` + PrimaryNetworkComponent *NetworkComponent `json:"primaryNetworkComponent,omitempty"` + PrimaryBackendNetworkComponent *NetworkComponent `json:"primaryBackendNetworkComponent,omitempty"` } -type SshKey struct { +type NetworkMaxSpeed struct { + MaxSpeed int `json:"maxSpeed"` +} + +type NetworkComponent struct { + NetworkVLAN *NetworkVLAN `json:"networkVlan"` +} + +type NetworkVLAN struct { + Id int `json:"id"` +} + +type SSHKey struct { Key string `json:"key,omitempty"` Id int `json:"id,omitempty"` Label string `json:"label,omitempty"` @@ -53,7 +68,7 @@ type sshKey struct { *Client } -type virtualGuest struct { +type VirtualGuest struct { *Client } @@ -85,11 +100,11 @@ func (c *Client) newRequest(method, uri string, body interface{}) ([]byte, error ) if body != nil { - bodyJson, err := json.Marshal(body) + bodyJSON, err := json.Marshal(body) if err != nil { return nil, err } - req, err = http.NewRequest(method, url, bytes.NewBuffer(bodyJson)) + req, err = http.NewRequest(method, url, bytes.NewBuffer(bodyJSON)) } else { req, err = http.NewRequest(method, url, nil) } @@ -99,7 +114,6 @@ func (c *Client) newRequest(method, uri string, body interface{}) ([]byte, error } req.SetBasicAuth(c.User, c.ApiKey) - req.Method = method resp, err := client.Do(req) if err != nil { @@ -122,7 +136,7 @@ func (c *Client) newRequest(method, uri string, body interface{}) ([]byte, error return data, nil } -func (c *Client) SshKey() *sshKey { +func (c *Client) SSHKey() *sshKey { return &sshKey{c} } @@ -130,11 +144,11 @@ func (c *sshKey) namespace() string { return "SoftLayer_Security_Ssh_Key" } -func (c *sshKey) Create(label, key string) (*SshKey, error) { +func (c *sshKey) Create(label, key string) (*SSHKey, error) { var ( method = "POST" uri = c.namespace() - body = SshKey{Key: key, Label: label} + body = SSHKey{Key: key, Label: label} ) data, err := c.newRequest(method, uri, map[string]interface{}{"parameters": []interface{}{body}}) @@ -142,7 +156,7 @@ func (c *sshKey) Create(label, key string) (*SshKey, error) { return nil, err } - var k SshKey + var k SSHKey if err := json.Unmarshal(data, &k); err != nil { return nil, err } @@ -150,15 +164,28 @@ func (c *sshKey) Create(label, key string) (*SshKey, error) { return &k, nil } -func (c *Client) VirtualGuest() *virtualGuest { - return &virtualGuest{c} +func (c *sshKey) Delete(id int) error { + var ( + method = "DELETE" + uri = fmt.Sprintf("%s/%v", c.namespace(), id) + ) + + _, err := c.newRequest(method, uri, nil) + if err != nil { + return err + } + return nil } -func (c *virtualGuest) namespace() string { +func (c *Client) VirtualGuest() *VirtualGuest { + return &VirtualGuest{c} +} + +func (c *VirtualGuest) namespace() string { return "SoftLayer_Virtual_Guest" } -func (c *virtualGuest) PowerState(id int) (string, error) { +func (c *VirtualGuest) PowerState(id int) (string, error) { type state struct { KeyName string `json:"keyName"` Name string `json:"name"` @@ -180,7 +207,40 @@ func (c *virtualGuest) PowerState(id int) (string, error) { return s.Name, nil } -func (c *virtualGuest) Create(spec *HostSpec) (int, error) { +func (c *VirtualGuest) ActiveTransaction(id int) (string, error) { + type transactionStatus struct { + AverageDuration string `json:"averageDuration"` + FriendlyName string `json:"friendlyName"` + Name string `json:"name"` + } + type transaction struct { + CreateDate string `json:"createDate"` + ElapsedSeconds int `json:"elapsedSeconds"` + GuestID int `json:"guestId"` + HardwareID int `json:"hardwareId"` + ID int `json:"id"` + ModifyDate string `json:"modifyDate"` + StatusChangeDate string `json:"statusChangeDate"` + TransactionStatus transactionStatus `json:"transactionStatus"` + } + var ( + method = "GET" + uri = fmt.Sprintf("%s/%v/getActiveTransaction.json", c.namespace(), id) + ) + + data, err := c.newRequest(method, uri, nil) + if err != nil { + return "", err + } + var t transaction + if err := json.Unmarshal(data, &t); err != nil { + return "", err + } + + return t.TransactionStatus.Name, nil +} + +func (c *VirtualGuest) Create(spec *HostSpec) (int, error) { var ( method = "POST" uri = c.namespace() + ".json" @@ -192,7 +252,7 @@ func (c *virtualGuest) Create(spec *HostSpec) (int, error) { } type createResp struct { - Id int `json:"id"` + ID int `json:"id"` } var r createResp @@ -200,10 +260,10 @@ func (c *virtualGuest) Create(spec *HostSpec) (int, error) { return -1, err } - return r.Id, nil + return r.ID, nil } -func (c *virtualGuest) Cancel(id int) error { +func (c *VirtualGuest) Cancel(id int) error { var ( method = "DELETE" uri = fmt.Sprintf("%s/%v", c.namespace(), id) @@ -216,7 +276,7 @@ func (c *virtualGuest) Cancel(id int) error { return nil } -func (c *virtualGuest) PowerOn(id int) error { +func (c *VirtualGuest) PowerOn(id int) error { var ( method = "GET" uri = fmt.Sprintf("%s/%v/powerOn.json", c.namespace(), id) @@ -229,7 +289,7 @@ func (c *virtualGuest) PowerOn(id int) error { return nil } -func (c *virtualGuest) PowerOff(id int) error { +func (c *VirtualGuest) PowerOff(id int) error { var ( method = "GET" uri = fmt.Sprintf("%s/%v/powerOff.json", c.namespace(), id) @@ -242,7 +302,7 @@ func (c *virtualGuest) PowerOff(id int) error { return nil } -func (c *virtualGuest) Pause(id int) error { +func (c *VirtualGuest) Pause(id int) error { var ( method = "GET" uri = fmt.Sprintf("%s/%v/pause.json", c.namespace(), id) @@ -255,7 +315,7 @@ func (c *virtualGuest) Pause(id int) error { return nil } -func (c *virtualGuest) Resume(id int) error { +func (c *VirtualGuest) Resume(id int) error { var ( method = "GET" uri = fmt.Sprintf("%s/%v/resume.json", c.namespace(), id) @@ -268,7 +328,7 @@ func (c *virtualGuest) Resume(id int) error { return nil } -func (c *virtualGuest) Reboot(id int) error { +func (c *VirtualGuest) Reboot(id int) error { var ( method = "GET" uri = fmt.Sprintf("%s/%v/rebootSoft.json", c.namespace(), id) @@ -281,7 +341,7 @@ func (c *virtualGuest) Reboot(id int) error { return nil } -func (c *virtualGuest) GetPublicIp(id int) (string, error) { +func (c *VirtualGuest) GetPublicIP(id int) (string, error) { var ( method = "GET" uri = fmt.Sprintf("%s/%v/getPrimaryIpAddress.json", c.namespace(), id) @@ -294,7 +354,7 @@ func (c *virtualGuest) GetPublicIp(id int) (string, error) { return strings.Replace(string(data), "\"", "", -1), nil } -func (c *virtualGuest) GetPrivateIp(id int) (string, error) { +func (c *VirtualGuest) GetPrivateIP(id int) (string, error) { var ( method = "GET" uri = fmt.Sprintf("%s/%v/getPrimaryBackendIpAddress.json", c.namespace(), id) diff --git a/drivers/utils.go b/drivers/utils.go deleted file mode 100644 index eed87885a8..0000000000 --- a/drivers/utils.go +++ /dev/null @@ -1,39 +0,0 @@ -package drivers - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/docker/machine/utils" -) - -func PublicKeyPath() string { - return filepath.Join(utils.GetHomeDir(), ".docker", "public-key.json") -} - -func AddPublicKeyToAuthorizedHosts(d Driver, authorizedKeysPath string) error { - f, err := os.Open(PublicKeyPath()) - if err != nil { - return err - } - defer f.Close() - - cmdString := fmt.Sprintf("mkdir -p %q && cat > %q", authorizedKeysPath, filepath.Join(authorizedKeysPath, "docker-host.json")) - cmd, err := d.GetSSHCommand(cmdString) - if err != nil { - return err - } - cmd.Stdin = f - return cmd.Run() -} - -func PublicKeyExists() (bool, error) { - _, err := os.Stat(PublicKeyPath()) - if err == nil { - return true, nil - } else if os.IsNotExist(err) { - return false, nil - } - return false, err -} diff --git a/drivers/virtualbox/disk.go b/drivers/virtualbox/disk.go new file mode 100644 index 0000000000..82f064f6f3 --- /dev/null +++ b/drivers/virtualbox/disk.go @@ -0,0 +1,141 @@ +package virtualbox + +import ( + "fmt" + "io" + "os" + "os/exec" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" +) + +type VirtualDisk struct { + UUID string + Path string +} + +type DiskCreator interface { + Create(size int, publicSSHKeyPath, diskPath string) error +} + +func NewDiskCreator() DiskCreator { + return &defaultDiskCreator{} +} + +type defaultDiskCreator struct{} + +// Make a boot2docker VM disk image. +func (c *defaultDiskCreator) Create(size int, publicSSHKeyPath, diskPath string) error { + log.Debugf("Creating %d MB hard disk image...", size) + + tarBuf, err := mcnutils.MakeDiskImage(publicSSHKeyPath) + if err != nil { + return err + } + + log.Debug("Calling inner createDiskImage") + + return createDiskImage(diskPath, size, tarBuf) +} + +// createDiskImage makes a disk image at dest with the given size in MB. If r is +// not nil, it will be read as a raw disk image to convert from. +func createDiskImage(dest string, size int, r io.Reader) error { + // Convert a raw image from stdin to the dest VMDK image. + sizeBytes := int64(size) << 20 // usually won't fit in 32-bit int (max 2GB) + // FIXME: why isn't this just using the vbm*() functions? + cmd := exec.Command(vboxManageCmd, "convertfromraw", "stdin", dest, + fmt.Sprintf("%d", sizeBytes), "--format", "VMDK") + + log.Debug(cmd) + + if os.Getenv("MACHINE_DEBUG") != "" { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } + + stdin, err := cmd.StdinPipe() + if err != nil { + return err + } + + log.Debug("Starting command") + + if err := cmd.Start(); err != nil { + return err + } + + log.Debug("Copying to stdin") + + n, err := io.Copy(stdin, r) + if err != nil { + return err + } + + log.Debug("Filling zeroes") + + // The total number of bytes written to stdin must match sizeBytes, or + // VBoxManage.exe on Windows will fail. Fill remaining with zeros. + if left := sizeBytes - n; left > 0 { + if err := zeroFill(stdin, left); err != nil { + return err + } + } + + log.Debug("Closing STDIN") + + // cmd won't exit until the stdin is closed. + if err := stdin.Close(); err != nil { + return err + } + + log.Debug("Waiting on cmd") + + return cmd.Wait() +} + +// zeroFill writes n zero bytes into w. +func zeroFill(w io.Writer, n int64) error { + const blocksize = 32 << 10 + zeros := make([]byte, blocksize) + var k int + var err error + for n > 0 { + if n > blocksize { + k, err = w.Write(zeros) + } else { + k, err = w.Write(zeros[:n]) + } + if err != nil { + return err + } + n -= int64(k) + } + return nil +} + +func getVMDiskInfo(name string, vbox VBoxManager) (*VirtualDisk, error) { + out, err := vbox.vbmOut("showvminfo", name, "--machinereadable") + if err != nil { + return nil, err + } + + disk := &VirtualDisk{} + + err = parseKeyValues(out, reEqualQuoteLine, func(key, val string) error { + switch key { + case "SATA-1-0": + disk.Path = val + case "SATA-ImageUUID-1-0": + disk.UUID = val + } + + return nil + }) + if err != nil { + return nil, err + } + + return disk, nil +} diff --git a/drivers/virtualbox/disk_test.go b/drivers/virtualbox/disk_test.go new file mode 100644 index 0000000000..b6c591956e --- /dev/null +++ b/drivers/virtualbox/disk_test.go @@ -0,0 +1,55 @@ +package virtualbox + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +const stdOutDiskInfo = ` +storagecontrollerbootable0="on" +"SATA-0-0"="/home/ehazlett/.boot2docker/boot2docker.iso" +"SATA-IsEjected"="off" +"SATA-1-0"="/home/ehazlett/vm/test/disk.vmdk" +"SATA-ImageUUID-1-0"="12345-abcdefg" +"SATA-2-0"="none" +nic1="nat"` + +func TestVMDiskInfo(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdOut: stdOutDiskInfo, + } + + disk, err := getVMDiskInfo("default", vbox) + + assert.Equal(t, "/home/ehazlett/vm/test/disk.vmdk", disk.Path) + assert.Equal(t, "12345-abcdefg", disk.UUID) + assert.NoError(t, err) +} + +func TestVMDiskInfoError(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + err: errors.New("BUG"), + } + + disk, err := getVMDiskInfo("default", vbox) + + assert.Nil(t, disk) + assert.EqualError(t, err, "BUG") +} + +func TestVMDiskInfoInvalidOutput(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdOut: "INVALID", + } + + disk, err := getVMDiskInfo("default", vbox) + + assert.Empty(t, disk.Path) + assert.Empty(t, disk.UUID) + assert.NoError(t, err) +} diff --git a/drivers/virtualbox/ip.go b/drivers/virtualbox/ip.go new file mode 100644 index 0000000000..be22a4fb7a --- /dev/null +++ b/drivers/virtualbox/ip.go @@ -0,0 +1,36 @@ +package virtualbox + +import ( + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/mcnutils" +) + +// IPWaiter waits for an IP to be configured. +type IPWaiter interface { + Wait(d *Driver) error +} + +func NewIPWaiter() IPWaiter { + return &sshIPWaiter{} +} + +type sshIPWaiter struct{} + +func (w *sshIPWaiter) Wait(d *Driver) error { + // Wait for SSH over NAT to be available before returning to user + if err := drivers.WaitForSSH(d); err != nil { + return err + } + + // Bail if we don't get an IP from DHCP after a given number of seconds. + if err := mcnutils.WaitForSpecific(d.hostOnlyIPAvailable, 5, 4*time.Second); err != nil { + return err + } + + var err error + d.IPAddress, err = d.GetIP() + + return err +} diff --git a/drivers/virtualbox/misc.go b/drivers/virtualbox/misc.go new file mode 100644 index 0000000000..3972a95443 --- /dev/null +++ b/drivers/virtualbox/misc.go @@ -0,0 +1,112 @@ +package virtualbox + +import ( + "bufio" + "math/rand" + "os" + + "time" + + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" +) + +// B2DUpdater describes the interactions with b2d. +type B2DUpdater interface { + UpdateISOCache(storePath, isoURL string) error + CopyIsoToMachineDir(storePath, machineName, isoURL string) error +} + +func NewB2DUpdater() B2DUpdater { + return &b2dUtilsUpdater{} +} + +type b2dUtilsUpdater struct{} + +func (u *b2dUtilsUpdater) CopyIsoToMachineDir(storePath, machineName, isoURL string) error { + return mcnutils.NewB2dUtils(storePath).CopyIsoToMachineDir(isoURL, machineName) +} + +func (u *b2dUtilsUpdater) UpdateISOCache(storePath, isoURL string) error { + return mcnutils.NewB2dUtils(storePath).UpdateISOCache(isoURL) +} + +// SSHKeyGenerator describes the generation of ssh keys. +type SSHKeyGenerator interface { + Generate(path string) error +} + +func NewSSHKeyGenerator() SSHKeyGenerator { + return &defaultSSHKeyGenerator{} +} + +type defaultSSHKeyGenerator struct{} + +func (g *defaultSSHKeyGenerator) Generate(path string) error { + return ssh.GenerateSSHKey(path) +} + +// LogsReader describes the reading of VBox.log +type LogsReader interface { + Read(path string) ([]string, error) +} + +func NewLogsReader() LogsReader { + return &vBoxLogsReader{} +} + +type vBoxLogsReader struct{} + +func (c *vBoxLogsReader) Read(path string) ([]string, error) { + file, err := os.Open(path) + if err != nil { + return []string{}, err + } + + defer file.Close() + + lines := []string{} + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + return lines, nil +} + +// RandomInter returns random int values. +type RandomInter interface { + RandomInt(n int) int +} + +func NewRandomInter() RandomInter { + src := rand.NewSource(time.Now().UnixNano()) + + return &defaultRandomInter{ + rand: rand.New(src), + } +} + +type defaultRandomInter struct { + rand *rand.Rand +} + +func (d *defaultRandomInter) RandomInt(n int) int { + return d.rand.Intn(n) +} + +// Sleeper sleeps for given duration. +type Sleeper interface { + Sleep(d time.Duration) +} + +func NewSleeper() Sleeper { + return &defaultSleeper{} +} + +type defaultSleeper struct{} + +func (s *defaultSleeper) Sleep(d time.Duration) { + time.Sleep(d) +} diff --git a/drivers/virtualbox/network.go b/drivers/virtualbox/network.go index 95f569a353..052684020d 100644 --- a/drivers/virtualbox/network.go +++ b/drivers/virtualbox/network.go @@ -1,17 +1,26 @@ package virtualbox import ( - "bufio" "errors" "fmt" "net" "regexp" - "strconv" "strings" + "time" + + "runtime" + + "github.com/docker/machine/libmachine/log" +) + +const ( + buggyNetmask = "0f000000" + dhcpPrefix = "HostInterfaceNetworking-" ) var ( - reHostonlyInterfaceCreated = regexp.MustCompile(`Interface '(.+)' was successfully created`) + reHostOnlyAdapterCreated = regexp.MustCompile(`Interface '(.+)' was successfully created`) + errNewHostOnlyAdapterNotVisible = errors.New("The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue") ) // Host-only network. @@ -20,69 +29,93 @@ type hostOnlyNetwork struct { GUID string DHCP bool IPv4 net.IPNet - IPv6 net.IPNet HwAddr net.HardwareAddr Medium string Status string NetworkName string // referenced in DHCP.NetworkName } -// Config changes the configuration of the host-only network. -func (n *hostOnlyNetwork) Save() error { +// HostInterfaces returns host network interface info. By default delegates to net.Interfaces() +type HostInterfaces interface { + Interfaces() ([]net.Interface, error) + Addrs(iface *net.Interface) ([]net.Addr, error) +} + +func NewHostInterfaces() HostInterfaces { + return &defaultHostInterfaces{} +} + +type defaultHostInterfaces struct { +} + +func (ni *defaultHostInterfaces) Interfaces() ([]net.Interface, error) { + return net.Interfaces() +} + +func (ni *defaultHostInterfaces) Addrs(iface *net.Interface) ([]net.Addr, error) { + return iface.Addrs() +} + +// Save changes the configuration of the host-only network. +func (n *hostOnlyNetwork) Save(vbox VBoxManager) error { + if err := n.SaveIPv4(vbox); err != nil { + return err + } + + if n.DHCP { + vbox.vbm("hostonlyif", "ipconfig", n.Name, "--dhcp") // not implemented as of VirtualBox 4.3 + } + + return nil +} + +// SaveIPv4 changes the ipv4 configuration of the host-only network. +func (n *hostOnlyNetwork) SaveIPv4(vbox VBoxManager) error { if n.IPv4.IP != nil && n.IPv4.Mask != nil { - if err := vbm("hostonlyif", "ipconfig", n.Name, "--ip", n.IPv4.IP.String(), "--netmask", net.IP(n.IPv4.Mask).String()); err != nil { - return err + if runtime.GOOS == "windows" { + log.Warn("Windows might ask for the permission to configure a network adapter. Sometimes, such confirmation window is minimized in the taskbar.") } - } - if n.IPv6.IP != nil && n.IPv6.Mask != nil { - prefixLen, _ := n.IPv6.Mask.Size() - if err := vbm("hostonlyif", "ipconfig", n.Name, "--ipv6", n.IPv6.IP.String(), "--netmasklengthv6", fmt.Sprintf("%d", prefixLen)); err != nil { + if err := vbox.vbm("hostonlyif", "ipconfig", n.Name, "--ip", n.IPv4.IP.String(), "--netmask", net.IP(n.IPv4.Mask).String()); err != nil { return err } } - if n.DHCP { - vbm("hostonlyif", "ipconfig", n.Name, "--dhcp") // not implemented as of VirtualBox 4.3 - } - return nil } -// createHostonlyNet creates a new host-only network. -func createHostonlyNet() (*hostOnlyNetwork, error) { - out, err := vbmOut("hostonlyif", "create") +// createHostonlyAdapter creates a new host-only network. +func createHostonlyAdapter(vbox VBoxManager) (*hostOnlyNetwork, error) { + if runtime.GOOS == "windows" { + log.Warn("Windows might ask for the permission to create a network adapter. Sometimes, such confirmation window is minimized in the taskbar.") + } + + out, err := vbox.vbmOut("hostonlyif", "create") if err != nil { return nil, err } - res := reHostonlyInterfaceCreated.FindStringSubmatch(string(out)) + + res := reHostOnlyAdapterCreated.FindStringSubmatch(string(out)) if res == nil { - return nil, errors.New("failed to create hostonly interface") + return nil, errors.New("Failed to create host-only adapter") } + return &hostOnlyNetwork{Name: res[1]}, nil } -// HostonlyNets gets all host-only networks in a map keyed by HostonlyNet.NetworkName. -func listHostOnlyNetworks() (map[string]*hostOnlyNetwork, error) { - out, err := vbmOut("list", "hostonlyifs") +// listHostOnlyAdapters gets all host-only adapters in a map keyed by NetworkName. +func listHostOnlyAdapters(vbox VBoxManager) (map[string]*hostOnlyNetwork, error) { + out, err := vbox.vbmOut("list", "hostonlyifs") if err != nil { return nil, err } - s := bufio.NewScanner(strings.NewReader(out)) - m := map[string]*hostOnlyNetwork{} + + byName := map[string]*hostOnlyNetwork{} + byIP := map[string]*hostOnlyNetwork{} n := &hostOnlyNetwork{} - for s.Scan() { - line := s.Text() - if line == "" { - m[n.NetworkName] = n - n = &hostOnlyNetwork{} - continue - } - res := reColonLine.FindStringSubmatch(line) - if res == nil { - continue - } - switch key, val := res[1], res[2]; key { + + err = parseKeyValues(out, reColonLine, func(key, val string) error { + switch key { case "Name": n.Name = val case "GUID": @@ -93,18 +126,10 @@ func listHostOnlyNetworks() (map[string]*hostOnlyNetwork, error) { n.IPv4.IP = net.ParseIP(val) case "NetworkMask": n.IPv4.Mask = parseIPv4Mask(val) - case "IPV6Address": - n.IPv6.IP = net.ParseIP(val) - case "IPV6NetworkMaskPrefixLength": - l, err := strconv.ParseUint(val, 10, 7) - if err != nil { - return nil, err - } - n.IPv6.Mask = net.CIDRMask(int(l), net.IPv6len*8) case "HardwareAddress": mac, err := net.ParseMAC(val) if err != nil { - return nil, err + return err } n.HwAddr = mac case "MediumType": @@ -113,55 +138,98 @@ func listHostOnlyNetworks() (map[string]*hostOnlyNetwork, error) { n.Status = val case "VBoxNetworkName": n.NetworkName = val + + if _, present := byName[n.NetworkName]; present { + return fmt.Errorf("VirtualBox is configured with multiple host-only adapters with the same name %q. Please remove one", n.NetworkName) + } + byName[n.NetworkName] = n + + if len(n.IPv4.IP) != 0 { + if _, present := byIP[n.IPv4.IP.String()]; present { + return fmt.Errorf("VirtualBox is configured with multiple host-only adapters with the same IP %q. Please remove one", n.IPv4.IP) + } + byIP[n.IPv4.IP.String()] = n + } + + n = &hostOnlyNetwork{} } - } - if err := s.Err(); err != nil { - return nil, err - } - return m, nil -} -func getHostOnlyNetwork(hostIP net.IP, netmask net.IPMask) (*hostOnlyNetwork, error) { - nets, err := listHostOnlyNetworks() + return nil + }) if err != nil { return nil, err } + + return byName, nil +} + +func getHostOnlyAdapter(nets map[string]*hostOnlyNetwork, hostIP net.IP, netmask net.IPMask) *hostOnlyNetwork { for _, n := range nets { + // Second part of this conditional handles a race where + // VirtualBox returns us the incorrect netmask value for the + // newly created adapter. if hostIP.Equal(n.IPv4.IP) && - netmask.String() == n.IPv4.Mask.String() { - return n, nil + (netmask.String() == n.IPv4.Mask.String() || n.IPv4.Mask.String() == buggyNetmask) { + log.Debugf("Found: %s", n.Name) + return n } } - return nil, nil + + log.Debug("Not found") + return nil } -func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, dhcpIP net.IP, dhcpUpperIP net.IP, dhcpLowerIP net.IP) (*hostOnlyNetwork, error) { - hostOnlyNet, err := getHostOnlyNetwork(hostIP, netmask) - if err != nil || hostOnlyNet != nil { - return hostOnlyNet, err +func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, nets map[string]*hostOnlyNetwork, vbox VBoxManager) (*hostOnlyNetwork, error) { + // Search for an existing host-only adapter. + hostOnlyAdapter := getHostOnlyAdapter(nets, hostIP, netmask) + if hostOnlyAdapter != nil { + return hostOnlyAdapter, nil } - // No existing host-only interface found. Create a new one. - hostOnlyNet, err = createHostonlyNet() + + // No existing host-only adapter found. Create a new one. + _, err := createHostonlyAdapter(vbox) if err != nil { - return nil, err + // Sometimes the host-only adapter fails to create. See https://www.virtualbox.org/ticket/14040 + // BUT, it is created in fact! So let's wait until it appears last in the list + log.Warnf("Creating a new host-only adapter produced an error: %s", err) + log.Warn("This is a known VirtualBox bug. Let's try to recover anyway...") } - hostOnlyNet.IPv4.IP = hostIP - hostOnlyNet.IPv4.Mask = netmask - if err := hostOnlyNet.Save(); err != nil { - return nil, err + + // It can take some time for an adapter to appear. Let's poll. + hostOnlyAdapter, err = waitForNewHostOnlyNetwork(nets, vbox) + if err != nil { + // Sometimes, Vbox says it created it but then it cannot be found... + return nil, errNewHostOnlyAdapterNotVisible } - dhcp := dhcpServer{} - dhcp.IPv4.IP = dhcpIP - dhcp.IPv4.Mask = netmask - dhcp.LowerIP = dhcpUpperIP - dhcp.UpperIP = dhcpLowerIP - dhcp.Enabled = true - if err := addHostonlyDHCP(hostOnlyNet.Name, dhcp); err != nil { + log.Warnf("Found a new host-only adapter: %q", hostOnlyAdapter.Name) + + hostOnlyAdapter.IPv4.IP = hostIP + hostOnlyAdapter.IPv4.Mask = netmask + if err := hostOnlyAdapter.Save(vbox); err != nil { return nil, err } - return hostOnlyNet, nil + return hostOnlyAdapter, nil +} + +func waitForNewHostOnlyNetwork(oldNets map[string]*hostOnlyNetwork, vbox VBoxManager) (*hostOnlyNetwork, error) { + for i := 0; i < 10; i++ { + time.Sleep(1 * time.Second) + + newNets, err := listHostOnlyAdapters(vbox) + if err != nil { + return nil, err + } + + for name, latestNet := range newNets { + if _, present := oldNets[name]; !present { + return latestNet, nil + } + } + } + + return nil, errors.New("Failed to find a new host-only adapter") } // DHCP server info. @@ -173,22 +241,59 @@ type dhcpServer struct { Enabled bool } -func addDHCPServer(kind, name string, d dhcpServer) error { - command := "modify" +// removeOrphanDHCPServers removed the DHCP servers linked to no host-only adapter +func removeOrphanDHCPServers(vbox VBoxManager) error { + dhcps, err := listDHCPServers(vbox) + if err != nil { + return err + } + + if len(dhcps) == 0 { + return nil + } + + log.Debug("Removing orphan DHCP servers...") + + nets, err := listHostOnlyAdapters(vbox) + if err != nil { + return err + } + + for name := range dhcps { + if strings.HasPrefix(name, dhcpPrefix) { + if _, present := nets[name]; !present { + if err := vbox.vbm("dhcpserver", "remove", "--netname", name); err != nil { + log.Warnf("Unable to remove orphan dhcp server %q: %s", name, err) + } + } + } + } + + return nil +} + +// addHostOnlyDHCPServer adds a DHCP server to a host-only network. +func addHostOnlyDHCPServer(ifname string, d dhcpServer, vbox VBoxManager) error { + name := dhcpPrefix + ifname - // On some platforms (OSX), creating a hostonlyinterface adds a default dhcpserver - // While on others (Windows?) it does not. - dhcps, err := getDHCPServers() + dhcps, err := listDHCPServers(vbox) if err != nil { return err } - if _, ok := dhcps[name]; !ok { - command = "add" + // On some platforms (OSX), creating a host-only adapter adds a default dhcpserver, + // while on others (Windows?) it does not. + command := "add" + if dhcp, ok := dhcps[name]; ok { + command = "modify" + if (dhcp.IPv4.IP.Equal(d.IPv4.IP)) && (dhcp.IPv4.Mask.String() == d.IPv4.Mask.String()) && (dhcp.LowerIP.Equal(d.LowerIP)) && (dhcp.UpperIP.Equal(d.UpperIP)) && (dhcp.Enabled == d.Enabled) { + // dhcp is up to date + return nil + } } args := []string{"dhcpserver", command, - kind, name, + "--netname", name, "--ip", d.IPv4.IP.String(), "--netmask", net.IP(d.IPv4.Mask).String(), "--lowerip", d.LowerIP.String(), @@ -199,41 +304,29 @@ func addDHCPServer(kind, name string, d dhcpServer) error { } else { args = append(args, "--disable") } - return vbm(args...) -} -// AddInternalDHCP adds a DHCP server to an internal network. -func addInternalDHCP(netname string, d dhcpServer) error { - return addDHCPServer("--netname", netname, d) -} + if runtime.GOOS == "windows" { + log.Warn("Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.") + } -// AddHostonlyDHCP adds a DHCP server to a host-only network. -func addHostonlyDHCP(ifname string, d dhcpServer) error { - return addDHCPServer("--netname", "HostInterfaceNetworking-"+ifname, d) + return vbox.vbm(args...) } -// DHCPs gets all DHCP server settings in a map keyed by DHCP.NetworkName. -func getDHCPServers() (map[string]*dhcpServer, error) { - out, err := vbmOut("list", "dhcpservers") +// listDHCPServers lists all DHCP server settings in a map keyed by DHCP.NetworkName. +func listDHCPServers(vbox VBoxManager) (map[string]*dhcpServer, error) { + out, err := vbox.vbmOut("list", "dhcpservers") if err != nil { return nil, err } - s := bufio.NewScanner(strings.NewReader(out)) + m := map[string]*dhcpServer{} dhcp := &dhcpServer{} - for s.Scan() { - line := s.Text() - if line == "" { - m[dhcp.NetworkName] = dhcp - dhcp = &dhcpServer{} - continue - } - res := reColonLine.FindStringSubmatch(line) - if res == nil { - continue - } - switch key, val := res[1], res[2]; key { + + err = parseKeyValues(out, reColonLine, func(key, val string) error { + switch key { case "NetworkName": + dhcp = &dhcpServer{} + m[val] = dhcp dhcp.NetworkName = val case "IP": dhcp.IPv4.IP = net.ParseIP(val) @@ -246,13 +339,71 @@ func getDHCPServers() (map[string]*dhcpServer, error) { case "Enabled": dhcp.Enabled = (val == "Yes") } + + return nil + }) + if err != nil { + return nil, err } - if err := s.Err(); err != nil { + + return m, nil +} + +// listHostInterfaces returns a map of net.IPNet addresses of host interfaces that are "UP" and not loopback adapters +// and not virtualbox host-only networks (given by excludeNets), keyed by CIDR string. +func listHostInterfaces(hif HostInterfaces, excludeNets map[string]*hostOnlyNetwork) (map[string]*net.IPNet, error) { + ifaces, err := hif.Interfaces() + if err != nil { return nil, err } + m := map[string]*net.IPNet{} + + for _, iface := range ifaces { + addrs, err := hif.Addrs(&iface) + if err != nil { + return nil, err + } + + // Check if an address of the interface is in the list of excluded addresses + ifaceExcluded := false + for _, a := range addrs { + switch ipnet := a.(type) { + case *net.IPNet: + _, excluded := excludeNets[ipnet.String()] + if excluded { + ifaceExcluded = true + break + } + } + } + + // If excluded, or not up, or a loopback interface, skip the interface + if ifaceExcluded || iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { + continue + } + + // This is a host interface, so add all its addresses to the map + for _, a := range addrs { + switch ipnet := a.(type) { + case *net.IPNet: + m[ipnet.String()] = ipnet + } + } + } return m, nil } +// checkIPNetCollision returns true if any host interfaces conflict with the host-only network mask passed as a parameter. +// This works with IPv4 or IPv6 ip addresses. +func checkIPNetCollision(hostonly *net.IPNet, hostIfaces map[string]*net.IPNet) (bool, error) { + for _, ifaceNet := range hostIfaces { + if hostonly.IP.Equal(ifaceNet.IP.Mask(ifaceNet.Mask)) { + return true, nil + } + } + return false, nil +} + // parseIPv4Mask parses IPv4 netmask written in IP form (e.g. 255.255.255.0). // This function should really belong to the net package. func parseIPv4Mask(s string) net.IPMask { diff --git a/drivers/virtualbox/network_test.go b/drivers/virtualbox/network_test.go new file mode 100644 index 0000000000..bcddc1a3b0 --- /dev/null +++ b/drivers/virtualbox/network_test.go @@ -0,0 +1,406 @@ +package virtualbox + +import ( + "net" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + stdOutOneHostOnlyNetwork = ` +Name: vboxnet0 +GUID: 786f6276-656e-4074-8000-0a0027000000 +DHCP: Disabled +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:00 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 + +` + stdOutTwoHostOnlyNetwork = ` +Name: vboxnet0 +GUID: 786f6276-656e-4074-8000-0a0027000000 +DHCP: Disabled +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:00 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 + +Name: vboxnet1 +GUID: 786f6276-656e-4174-8000-0a0027000001 +DHCP: Disabled +IPAddress: 169.254.37.187 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:01 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-vboxnet1 +` + stdOutListTwoDHCPServers = ` +NetworkName: HostInterfaceNetworking-vboxnet0 +IP: 192.168.99.6 +NetworkMask: 255.255.255.0 +lowerIPAddress: 192.168.99.100 +upperIPAddress: 192.168.99.254 +Enabled: Yes + +NetworkName: HostInterfaceNetworking-vboxnet1 +IP: 192.168.99.7 +NetworkMask: 255.255.255.0 +lowerIPAddress: 192.168.99.100 +upperIPAddress: 192.168.99.254 +Enabled: No +` +) + +type mockHostInterfaces struct { + mockIfaces []net.Interface + mockAddrs map[string]net.Addr +} + +func newMockHostInterfaces() *mockHostInterfaces { + return &mockHostInterfaces{ + mockAddrs: make(map[string]net.Addr), + } +} + +func (mhi *mockHostInterfaces) Interfaces() ([]net.Interface, error) { + return mhi.mockIfaces, nil +} + +func (mhi *mockHostInterfaces) Addrs(iface *net.Interface) ([]net.Addr, error) { + return []net.Addr{mhi.mockAddrs[iface.Name]}, nil +} + +func (mhi *mockHostInterfaces) addMockIface(ip string, mask int, iplen int, name string, flags net.Flags) (*net.IPNet, error) { + iface := &net.Interface{Name: name, Flags: flags} + mhi.mockIfaces = append(mhi.mockIfaces, *iface) + + ipnet := &net.IPNet{IP: net.ParseIP(ip), Mask: net.CIDRMask(mask, 8*iplen)} + if ipnet.IP == nil { + return nil, &net.ParseError{Type: "IP address", Text: ip} + } + mhi.mockAddrs[name] = ipnet + return ipnet, nil +} + +// Tests that when we have a host only network which matches our expectations, +// it gets returned correctly. +func TestGetHostOnlyNetworkHappy(t *testing.T) { + cidr := "192.168.99.0/24" + ip, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + t.Fatalf("Error parsing cidr: %s", err) + } + expectedHostOnlyNetwork := &hostOnlyNetwork{ + IPv4: *ipnet, + } + vboxNets := map[string]*hostOnlyNetwork{ + "HostInterfaceNetworking-vboxnet0": expectedHostOnlyNetwork, + } + + n := getHostOnlyAdapter(vboxNets, ip, ipnet.Mask) + if !reflect.DeepEqual(n, expectedHostOnlyNetwork) { + t.Fatalf("Expected result of calling getHostOnlyNetwork to be the same as expected but it was not:\nexpected: %+v\nactual: %+v\n", expectedHostOnlyNetwork, n) + } +} + +// Tests that we are able to properly detect when a host only network which +// matches our expectations can not be found. +func TestGetHostOnlyNetworkNotFound(t *testing.T) { + // Note that this has a different ip is different from "ip" below. + cidr := "192.168.99.0/24" + ip, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + t.Fatalf("Error parsing cidr: %s", err) + } + + ip = net.ParseIP("192.168.59.0").To4() + + // Suppose a vbox net is created, but it doesn't align with our + // expectation. + vboxNet := &hostOnlyNetwork{ + IPv4: *ipnet, + } + vboxNets := map[string]*hostOnlyNetwork{ + "HostInterfaceNetworking-vboxnet0": vboxNet, + } + + n := getHostOnlyAdapter(vboxNets, ip, ipnet.Mask) + if n != nil { + t.Fatalf("Expected vbox net to be nil but it has a value: %+v\n", n) + } +} + +// Tests a special case where Virtualbox creates the host only network +// successfully but mis-reports the netmask. +func TestGetHostOnlyNetworkWindows10Bug(t *testing.T) { + cidr := "192.168.99.0/24" + ip, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + t.Fatalf("Error parsing cidr: %s", err) + } + + // This is a faulty netmask: a VirtualBox bug causes it to be + // misreported. + ipnet.Mask = net.IPMask(net.ParseIP("15.0.0.0").To4()) + + expectedHostOnlyNetwork := &hostOnlyNetwork{ + IPv4: *ipnet, + } + + vboxNets := map[string]*hostOnlyNetwork{ + "HostInterfaceNetworking-vboxnet0": expectedHostOnlyNetwork, + } + + // The Mask that we are passing in will be the "legitimate" mask, so it + // must differ from the magic buggy mask. + n := getHostOnlyAdapter(vboxNets, ip, net.IPMask(net.ParseIP("255.255.255.0").To4())) + if !reflect.DeepEqual(n, expectedHostOnlyNetwork) { + t.Fatalf("Expected result of calling getHostOnlyNetwork to be the same as expected but it was not:\nexpected: %+v\nactual: %+v\n", expectedHostOnlyNetwork, n) + } +} + +func TestListHostOnlyNetworks(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: stdOutOneHostOnlyNetwork, + } + + nets, err := listHostOnlyAdapters(vbox) + + assert.Equal(t, 1, len(nets)) + assert.NoError(t, err) + + net, present := nets["HostInterfaceNetworking-vboxnet0"] + + assert.True(t, present) + assert.Equal(t, "vboxnet0", net.Name) + assert.Equal(t, "786f6276-656e-4074-8000-0a0027000000", net.GUID) + assert.False(t, net.DHCP) + assert.Equal(t, "192.168.99.1", net.IPv4.IP.String()) + assert.Equal(t, "ffffff00", net.IPv4.Mask.String()) + assert.Equal(t, "0a:00:27:00:00:00", net.HwAddr.String()) + assert.Equal(t, "Ethernet", net.Medium) + assert.Equal(t, "Up", net.Status) + assert.Equal(t, "HostInterfaceNetworking-vboxnet0", net.NetworkName) +} + +func TestListTwoHostOnlyNetworks(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: stdOutTwoHostOnlyNetwork, + } + + nets, err := listHostOnlyAdapters(vbox) + + assert.Equal(t, 2, len(nets)) + assert.NoError(t, err) + + net, present := nets["HostInterfaceNetworking-vboxnet1"] + + assert.True(t, present) + assert.Equal(t, "vboxnet1", net.Name) + assert.Equal(t, "786f6276-656e-4174-8000-0a0027000001", net.GUID) + assert.False(t, net.DHCP) + assert.Equal(t, "169.254.37.187", net.IPv4.IP.String()) + assert.Equal(t, "ffffff00", net.IPv4.Mask.String()) + assert.Equal(t, "0a:00:27:00:00:01", net.HwAddr.String()) + assert.Equal(t, "Ethernet", net.Medium) + assert.Equal(t, "Up", net.Status) + assert.Equal(t, "HostInterfaceNetworking-vboxnet1", net.NetworkName) +} + +func TestListHostOnlyNetworksDontRelyOnEmptyLinesForParsing(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: `Name: vboxnet0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 +Name: vboxnet1 +VBoxNetworkName: HostInterfaceNetworking-vboxnet1`, + } + + nets, err := listHostOnlyAdapters(vbox) + + assert.Equal(t, 2, len(nets)) + assert.NoError(t, err) + + net, present := nets["HostInterfaceNetworking-vboxnet1"] + assert.True(t, present) + assert.Equal(t, "vboxnet1", net.Name) + + net, present = nets["HostInterfaceNetworking-vboxnet0"] + assert.True(t, present) + assert.Equal(t, "vboxnet0", net.Name) +} + +func TestGetHostOnlyNetwork(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: stdOutOneHostOnlyNetwork, + } + nets, err := listHostOnlyAdapters(vbox) + assert.NoError(t, err) + + net, err := getOrCreateHostOnlyNetwork(net.ParseIP("192.168.99.1"), parseIPv4Mask("255.255.255.0"), nets, vbox) + + assert.NotNil(t, net) + assert.Equal(t, "HostInterfaceNetworking-vboxnet0", net.NetworkName) + assert.NoError(t, err) +} + +func TestFailIfTwoNetworksHaveSameIP(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: `Name: vboxnet0 +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 +Name: vboxnet1 +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet1`, + } + nets, err := listHostOnlyAdapters(vbox) + assert.Nil(t, nets) + assert.EqualError(t, err, `VirtualBox is configured with multiple host-only adapters with the same IP "192.168.99.1". Please remove one`) +} + +func TestFailIfTwoNetworksHaveSameName(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: `Name: vboxnet0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 +Name: vboxnet0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0`, + } + nets, err := listHostOnlyAdapters(vbox) + assert.Nil(t, nets) + assert.EqualError(t, err, `VirtualBox is configured with multiple host-only adapters with the same name "HostInterfaceNetworking-vboxnet0". Please remove one`) +} + +func TestGetDHCPServers(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list dhcpservers", + stdOut: stdOutListTwoDHCPServers, + } + + servers, err := listDHCPServers(vbox) + + assert.Equal(t, 2, len(servers)) + assert.NoError(t, err) + + server, present := servers["HostInterfaceNetworking-vboxnet0"] + assert.True(t, present) + assert.Equal(t, "HostInterfaceNetworking-vboxnet0", server.NetworkName) + assert.Equal(t, "192.168.99.6", server.IPv4.IP.String()) + assert.Equal(t, "192.168.99.100", server.LowerIP.String()) + assert.Equal(t, "192.168.99.254", server.UpperIP.String()) + assert.Equal(t, "ffffff00", server.IPv4.Mask.String()) + assert.True(t, server.Enabled) + + server, present = servers["HostInterfaceNetworking-vboxnet1"] + assert.True(t, present) + assert.Equal(t, "HostInterfaceNetworking-vboxnet1", server.NetworkName) + assert.Equal(t, "192.168.99.7", server.IPv4.IP.String()) + assert.Equal(t, "192.168.99.100", server.LowerIP.String()) + assert.Equal(t, "192.168.99.254", server.UpperIP.String()) + assert.Equal(t, "ffffff00", server.IPv4.Mask.String()) + assert.False(t, server.Enabled) +} + +// Tests detection of a conflict between prospective vbox host-only network and an IPV6 host interface +func TestCheckIPNetCollisionIPv6(t *testing.T) { + m := map[string]*net.IPNet{} + _, vboxHostOnly, err := net.ParseCIDR("2607:f8b0:400e:c04:ffff:ffff:ffff:ffff/64") + assert.Nil(t, err) + + hostIP, hostNet, err := net.ParseCIDR("2001:4998:c:a06::2:4008/64") + assert.Nil(t, err) + m[hostIP.String()] = &net.IPNet{IP: hostIP, Mask: hostNet.Mask} + + result, err := checkIPNetCollision(vboxHostOnly, m) + assert.Nil(t, err) + assert.False(t, result) + + hostIP, hostNet, err = net.ParseCIDR("2607:f8b0:400e:c04::6a/64") + assert.Nil(t, err) + m[hostIP.String()] = &net.IPNet{IP: hostIP, Mask: hostNet.Mask} + + result, err = checkIPNetCollision(vboxHostOnly, m) + assert.Nil(t, err) + assert.True(t, result) +} + +// Tests detection of a conflict between prospective vbox host-only network and an IPV4 host interface +func TestCheckIPNetCollisionIPv4(t *testing.T) { + m := map[string]*net.IPNet{} + _, vboxHostOnly, err := net.ParseCIDR("192.168.99.1/24") + assert.NoError(t, err) + + hostIP, hostNet, err := net.ParseCIDR("10.10.10.42/24") + assert.NoError(t, err) + m[hostIP.String()] = &net.IPNet{IP: hostIP, Mask: hostNet.Mask} + + result, err := checkIPNetCollision(vboxHostOnly, m) + assert.NoError(t, err) + assert.False(t, result) + + hostIP, hostNet, err = net.ParseCIDR("192.168.99.22/24") + assert.NoError(t, err) + m[hostIP.String()] = &net.IPNet{IP: hostIP, Mask: hostNet.Mask} + + result, err = checkIPNetCollision(vboxHostOnly, m) + assert.NoError(t, err) + assert.True(t, result) +} + +// Tests functionality of listHostInterfaces and verifies only non-loopback, active and non-excluded interfaces are returned +func TestListHostInterfaces(t *testing.T) { + mhi := newMockHostInterfaces() + excludes := map[string]*hostOnlyNetwork{} + + en0, err := mhi.addMockIface("10.10.0.22", 24, net.IPv4len, "en0", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + _, err = mhi.addMockIface("10.10.1.11", 24, net.IPv4len, "en1", net.FlagBroadcast /*not up*/) + assert.NoError(t, err) + _, err = mhi.addMockIface("127.0.0.1", 24, net.IPv4len, "lo0", net.FlagUp|net.FlagLoopback) + assert.NoError(t, err) + en0ipv6, err := mhi.addMockIface("2001:4998:c:a06::2:4008", 64, net.IPv6len, "en0ipv6", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + vboxnet0, err := mhi.addMockIface("192.168.99.1", 24, net.IPv4len, "vboxnet0", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + notvboxnet0, err := mhi.addMockIface("192.168.99.42", 24, net.IPv4len, "en2", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + + excludes["192.168.99.1/24"] = &hostOnlyNetwork{IPv4: *vboxnet0, Name: "HostInterfaceNetworking-vboxnet0"} + + m, err := listHostInterfaces(mhi, excludes) + assert.NoError(t, err) + assert.NotEmpty(t, m) + + assert.Contains(t, m, "10.10.0.22/24") + assert.Equal(t, en0, m["10.10.0.22/24"]) + + assert.Contains(t, m, "2001:4998:c:a06::2:4008/64") + assert.Equal(t, en0ipv6, m["2001:4998:c:a06::2:4008/64"]) + + assert.Contains(t, m, "192.168.99.42/24") + assert.Equal(t, notvboxnet0, m["192.168.99.42/24"]) + + assert.NotContains(t, m, "10.10.1.11/24") + assert.NotContains(t, m, "127.0.0.1/24") + assert.NotContains(t, m, "192.168.99.1/24") +} diff --git a/drivers/virtualbox/vbm.go b/drivers/virtualbox/vbm.go index 1e86096229..ea6eb8d57d 100644 --- a/drivers/virtualbox/vbm.go +++ b/drivers/virtualbox/vbm.go @@ -1,75 +1,165 @@ package virtualbox import ( + "bufio" "bytes" "errors" "fmt" - "os" "os/exec" "regexp" "strings" - log "github.com/Sirupsen/logrus" + "strconv" + + "time" + + "github.com/docker/machine/libmachine/log" +) + +const ( + retryCountOnObjectNotReadyError = 5 + objectNotReady = "error: The object is not ready" + retryDelay = 100 * time.Millisecond ) var ( - reVMNameUUID = regexp.MustCompile(`"(.+)" {([0-9a-f-]+)}`) - reVMInfoLine = regexp.MustCompile(`(?:"(.+)"|(.+))=(?:"(.*)"|(.*))`) reColonLine = regexp.MustCompile(`(.+):\s+(.*)`) + reEqualLine = regexp.MustCompile(`(.+)=(.*)`) + reEqualQuoteLine = regexp.MustCompile(`"(.+)"="(.*)"`) reMachineNotFound = regexp.MustCompile(`Could not find a registered machine named '(.+)'`) -) -var ( - ErrMachineExist = errors.New("machine already exists") ErrMachineNotExist = errors.New("machine does not exist") - ErrVBMNotFound = errors.New("VBoxManage not found") - vboxManageCmd = "VBoxManage" + ErrVBMNotFound = errors.New("VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path") + + vboxManageCmd = detectVBoxManageCmd() ) -func vbm(args ...string) error { - cmd := exec.Command(vboxManageCmd, args...) - if os.Getenv("DEBUG") != "" { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - log.Debugf("executing: %v %v", vboxManageCmd, strings.Join(args, " ")) - if err := cmd.Run(); err != nil { - if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound { - return ErrVBMNotFound - } - return fmt.Errorf("%v %v failed: %v", vboxManageCmd, strings.Join(args, " "), err) - } - return nil +// VBoxManager defines the interface to communicate to VirtualBox. +type VBoxManager interface { + vbm(args ...string) error + + vbmOut(args ...string) (string, error) + + vbmOutErr(args ...string) (string, string, error) } -func vbmOut(args ...string) (string, error) { - cmd := exec.Command(vboxManageCmd, args...) - if os.Getenv("DEBUG") != "" { - cmd.Stderr = os.Stderr - } - log.Debugf("executing: %v %v", vboxManageCmd, strings.Join(args, " ")) +// VBoxCmdManager communicates with VirtualBox through the commandline using `VBoxManage`. +type VBoxCmdManager struct { + runCmd func(cmd *exec.Cmd) error +} - b, err := cmd.Output() - if err != nil { - if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound { - err = ErrVBMNotFound - } +// NewVBoxManager creates a VBoxManager instance. +func NewVBoxManager() *VBoxCmdManager { + return &VBoxCmdManager{ + runCmd: func(cmd *exec.Cmd) error { return cmd.Run() }, } - return string(b), err } -func vbmOutErr(args ...string) (string, string, error) { +func (v *VBoxCmdManager) vbm(args ...string) error { + _, _, err := v.vbmOutErr(args...) + return err +} + +func (v *VBoxCmdManager) vbmOut(args ...string) (string, error) { + stdout, _, err := v.vbmOutErr(args...) + return stdout, err +} + +func (v *VBoxCmdManager) vbmOutErr(args ...string) (string, string, error) { + return v.vbmOutErrRetry(retryCountOnObjectNotReadyError, args...) +} + +func (v *VBoxCmdManager) vbmOutErrRetry(retry int, args ...string) (string, string, error) { cmd := exec.Command(vboxManageCmd, args...) - log.Debugf("executing: %v %v", vboxManageCmd, strings.Join(args, " ")) + log.Debugf("COMMAND: %v %v", vboxManageCmd, strings.Join(args, " ")) var stdout bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr - err := cmd.Run() + err := v.runCmd(cmd) + stderrStr := stderr.String() + if len(args) > 0 { + log.Debugf("STDOUT:\n{\n%v}", stdout.String()) + log.Debugf("STDERR:\n{\n%v}", stderrStr) + } + if err != nil { - if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound { + if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { err = ErrVBMNotFound } } - return stdout.String(), stderr.String(), err + + // Sometimes, we just need to retry... + if retry > 1 { + if strings.Contains(stderrStr, objectNotReady) { + time.Sleep(retryDelay) + return v.vbmOutErrRetry(retry-1, args...) + } + } + + if err == nil || strings.HasPrefix(err.Error(), "exit status ") { + // VBoxManage will sometimes not set the return code, but has a fatal error + // such as VBoxManage.exe: error: VT-x is not available. (VERR_VMX_NO_VMX) + if strings.Contains(stderrStr, "error:") { + err = fmt.Errorf("%v %v failed:\n%v", vboxManageCmd, strings.Join(args, " "), stderrStr) + } + } + + return stdout.String(), stderrStr, err +} + +func checkVBoxManageVersion(version string) error { + major, minor, err := parseVersion(version) + if (err != nil) || (major < 4) || (major == 4 && minor <= 2) { + return fmt.Errorf("We support Virtualbox starting with version 5. Your VirtualBox install is %q. Please upgrade at https://www.virtualbox.org", version) + } + + if major < 5 { + log.Warnf("You are using version %s of VirtualBox. If you encounter issues, you might want to upgrade to version 5 at https://www.virtualbox.org", version) + } + + return nil +} + +func parseVersion(version string) (int, int, error) { + parts := strings.Split(version, ".") + if len(parts) < 2 { + return 0, 0, fmt.Errorf("Invalid version: %q", version) + } + + major, err := strconv.Atoi(parts[0]) + if err != nil { + return 0, 0, fmt.Errorf("Invalid version: %q", version) + } + + minor, err := strconv.Atoi(parts[1]) + if err != nil { + return 0, 0, fmt.Errorf("Invalid version: %q", version) + } + + return major, minor, err +} + +func parseKeyValues(stdOut string, regexp *regexp.Regexp, callback func(key, val string) error) error { + r := strings.NewReader(stdOut) + s := bufio.NewScanner(r) + + for s.Scan() { + line := s.Text() + if line == "" { + continue + } + + res := regexp.FindStringSubmatch(line) + if res == nil { + continue + } + + key, val := res[1], res[2] + if err := callback(key, val); err != nil { + return err + } + } + + return s.Err() } diff --git a/drivers/virtualbox/vbm_test.go b/drivers/virtualbox/vbm_test.go new file mode 100644 index 0000000000..a1baa1b34f --- /dev/null +++ b/drivers/virtualbox/vbm_test.go @@ -0,0 +1,142 @@ +package virtualbox + +import ( + "testing" + + "os/exec" + + "errors" + + "fmt" + + "github.com/stretchr/testify/assert" +) + +func TestValidCheckVBoxManageVersion(t *testing.T) { + var tests = []struct { + version string + }{ + {"5.1"}, + {"5.0.8r103449"}, + {"5.0"}, + {"4.10"}, + {"4.3.1"}, + } + + for _, test := range tests { + err := checkVBoxManageVersion(test.version) + + assert.NoError(t, err) + } +} + +func TestInvalidCheckVBoxManageVersion(t *testing.T) { + var tests = []struct { + version string + expectedError string + }{ + {"3.9", `We support Virtualbox starting with version 5. Your VirtualBox install is "3.9". Please upgrade at https://www.virtualbox.org`}, + {"4.0", `We support Virtualbox starting with version 5. Your VirtualBox install is "4.0". Please upgrade at https://www.virtualbox.org`}, + {"4.1.1", `We support Virtualbox starting with version 5. Your VirtualBox install is "4.1.1". Please upgrade at https://www.virtualbox.org`}, + {"4.2.36-104064", `We support Virtualbox starting with version 5. Your VirtualBox install is "4.2.36-104064". Please upgrade at https://www.virtualbox.org`}, + {"X.Y", `We support Virtualbox starting with version 5. Your VirtualBox install is "X.Y". Please upgrade at https://www.virtualbox.org`}, + {"", `We support Virtualbox starting with version 5. Your VirtualBox install is "". Please upgrade at https://www.virtualbox.org`}, + } + + for _, test := range tests { + err := checkVBoxManageVersion(test.version) + + assert.EqualError(t, err, test.expectedError) + } +} + +func TestVbmOutErr(t *testing.T) { + var cmdRun *exec.Cmd + vBoxManager := NewVBoxManager() + vBoxManager.runCmd = func(cmd *exec.Cmd) error { + cmdRun = cmd + fmt.Fprint(cmd.Stdout, "Printed to StdOut") + fmt.Fprint(cmd.Stderr, "Printed to StdErr") + return nil + } + + stdOut, stdErr, err := vBoxManager.vbmOutErr("arg1", "arg2") + + assert.Equal(t, []string{vboxManageCmd, "arg1", "arg2"}, cmdRun.Args) + assert.Equal(t, "Printed to StdOut", stdOut) + assert.Equal(t, "Printed to StdErr", stdErr) + assert.NoError(t, err) +} + +func TestVbmOutErrError(t *testing.T) { + vBoxManager := NewVBoxManager() + vBoxManager.runCmd = func(cmd *exec.Cmd) error { return errors.New("BUG") } + + _, _, err := vBoxManager.vbmOutErr("arg1", "arg2") + + assert.EqualError(t, err, "BUG") +} + +func TestVbmOutErrNotFound(t *testing.T) { + vBoxManager := NewVBoxManager() + vBoxManager.runCmd = func(cmd *exec.Cmd) error { return &exec.Error{Err: exec.ErrNotFound} } + + _, _, err := vBoxManager.vbmOutErr("arg1", "arg2") + + assert.Equal(t, ErrVBMNotFound, err) +} + +func TestVbmOutErrFailingWithExitStatus(t *testing.T) { + vBoxManager := NewVBoxManager() + vBoxManager.runCmd = func(cmd *exec.Cmd) error { + fmt.Fprint(cmd.Stderr, "error: Unable to run vbox") + return errors.New("exit status BUG") + } + + _, _, err := vBoxManager.vbmOutErr("arg1", "arg2", "arg3") + + assert.EqualError(t, err, vboxManageCmd+" arg1 arg2 arg3 failed:\nerror: Unable to run vbox") +} + +func TestVbmOutErrRetryOnce(t *testing.T) { + var cmdRun *exec.Cmd + var runCount int + vBoxManager := NewVBoxManager() + vBoxManager.runCmd = func(cmd *exec.Cmd) error { + cmdRun = cmd + + runCount++ + if runCount == 1 { + fmt.Fprint(cmd.Stderr, "error: The object is not ready") + return errors.New("Fail the first time it's called") + } + + fmt.Fprint(cmd.Stdout, "Printed to StdOut") + return nil + } + + stdOut, stdErr, err := vBoxManager.vbmOutErr("command", "arg") + + assert.Equal(t, 2, runCount) + assert.Equal(t, []string{vboxManageCmd, "command", "arg"}, cmdRun.Args) + assert.Equal(t, "Printed to StdOut", stdOut) + assert.Empty(t, stdErr) + assert.NoError(t, err) +} + +func TestVbmOutErrRetryMax(t *testing.T) { + var runCount int + vBoxManager := NewVBoxManager() + vBoxManager.runCmd = func(cmd *exec.Cmd) error { + runCount++ + fmt.Fprint(cmd.Stderr, "error: The object is not ready") + return errors.New("Always fail") + } + + stdOut, stdErr, err := vBoxManager.vbmOutErr("command", "arg") + + assert.Equal(t, 5, runCount) + assert.Empty(t, stdOut) + assert.Equal(t, "error: The object is not ready", stdErr) + assert.Error(t, err) +} diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index c44f375eb2..3d79e4e978 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -1,11 +1,8 @@ package virtualbox import ( - "archive/tar" - "bytes" + "errors" "fmt" - "io" - "io/ioutil" "net" "os" "os/exec" @@ -16,69 +13,205 @@ import ( "strings" "time" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" - "github.com/docker/machine/utils" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/state" ) const ( - dockerConfigDir = "/var/lib/boot2docker" + defaultCPU = 1 + defaultMemory = 1024 + defaultBoot2DockerURL = "" + defaultBoot2DockerImportVM = "" + defaultHostOnlyCIDR = "192.168.99.1/24" + defaultHostOnlyNictype = "82540EM" + defaultHostOnlyPromiscMode = "deny" + defaultUIType = "headless" + defaultHostOnlyNoDHCP = false + defaultDiskSize = 20000 + defaultDNSProxy = true + defaultDNSResolver = false ) -type Driver struct { - MachineName string - SSHPort int - Memory int - DiskSize int - Boot2DockerURL string - CaCertPath string - PrivateKeyPath string - storePath string -} +var ( + ErrUnableToGenerateRandomIP = errors.New("unable to generate random IP") + ErrMustEnableVTX = errors.New("This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory") + ErrNotCompatibleWithHyperV = errors.New("This computer is running Hyper-V. VirtualBox won't boot a 64bits VM when Hyper-V is activated. Either use Hyper-V as a driver, or disable the Hyper-V hypervisor. (To skip this check, use --virtualbox-no-vtx-check)") + ErrNetworkAddrCidr = errors.New("host-only cidr must be specified with a host address, not a network address") + ErrNetworkAddrCollision = errors.New("host-only cidr conflicts with the network address of a host interface") +) -type CreateFlags struct { - Memory *int - DiskSize *int - Boot2DockerURL *string +type Driver struct { + *drivers.BaseDriver + VBoxManager + HostInterfaces + b2dUpdater B2DUpdater + sshKeyGenerator SSHKeyGenerator + diskCreator DiskCreator + logsReader LogsReader + ipWaiter IPWaiter + randomInter RandomInter + sleeper Sleeper + CPU int + Memory int + DiskSize int + NatNicType string + Boot2DockerURL string + Boot2DockerImportVM string + HostDNSResolver bool + HostOnlyCIDR string + HostOnlyNicType string + HostOnlyPromiscMode string + UIType string + HostOnlyNoDHCP bool + NoShare bool + DNSProxy bool + NoVTXCheck bool + ShareFolder string } -func init() { - drivers.Register("virtualbox", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) +// NewDriver creates a new VirtualBox driver with default settings. +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + VBoxManager: NewVBoxManager(), + b2dUpdater: NewB2DUpdater(), + sshKeyGenerator: NewSSHKeyGenerator(), + diskCreator: NewDiskCreator(), + logsReader: NewLogsReader(), + ipWaiter: NewIPWaiter(), + randomInter: NewRandomInter(), + sleeper: NewSleeper(), + HostInterfaces: NewHostInterfaces(), + Memory: defaultMemory, + CPU: defaultCPU, + DiskSize: defaultDiskSize, + NatNicType: defaultHostOnlyNictype, + HostOnlyCIDR: defaultHostOnlyCIDR, + HostOnlyNicType: defaultHostOnlyNictype, + HostOnlyPromiscMode: defaultHostOnlyPromiscMode, + UIType: defaultUIType, + HostOnlyNoDHCP: defaultHostOnlyNoDHCP, + DNSProxy: defaultDNSProxy, + HostDNSResolver: defaultDNSResolver, + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + } } -// RegisterCreateFlags registers the flags this driver adds to +// GetCreateFlags registers the flags this driver adds to // "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.IntFlag{ - Name: "virtualbox-memory", - Usage: "Size of memory for host in MB", - Value: 1024, +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.IntFlag{ + Name: "virtualbox-memory", + Usage: "Size of memory for host in MB", + Value: defaultMemory, + EnvVar: "VIRTUALBOX_MEMORY_SIZE", }, - cli.IntFlag{ - Name: "virtualbox-disk-size", - Usage: "Size of disk for host in MB", - Value: 20000, + mcnflag.IntFlag{ + Name: "virtualbox-cpu-count", + Usage: "number of CPUs for the machine (-1 to use the number of CPUs available)", + Value: defaultCPU, + EnvVar: "VIRTUALBOX_CPU_COUNT", }, - cli.StringFlag{ - EnvVar: "VIRTUALBOX_BOOT2DOCKER_URL", + mcnflag.IntFlag{ + Name: "virtualbox-disk-size", + Usage: "Size of disk for host in MB", + Value: defaultDiskSize, + EnvVar: "VIRTUALBOX_DISK_SIZE", + }, + mcnflag.StringFlag{ Name: "virtualbox-boot2docker-url", Usage: "The URL of the boot2docker image. Defaults to the latest available version", - Value: "", + Value: defaultBoot2DockerURL, + EnvVar: "VIRTUALBOX_BOOT2DOCKER_URL", + }, + mcnflag.StringFlag{ + Name: "virtualbox-import-boot2docker-vm", + Usage: "The name of a Boot2Docker VM to import", + Value: defaultBoot2DockerImportVM, + EnvVar: "VIRTUALBOX_BOOT2DOCKER_IMPORT_VM", + }, + mcnflag.BoolFlag{ + Name: "virtualbox-host-dns-resolver", + Usage: "Use the host DNS resolver", + EnvVar: "VIRTUALBOX_HOST_DNS_RESOLVER", + }, + mcnflag.StringFlag{ + Name: "virtualbox-nat-nictype", + Usage: "Specify the Network Adapter Type", + Value: defaultHostOnlyNictype, + EnvVar: "VIRTUALBOX_NAT_NICTYPE", + }, + mcnflag.StringFlag{ + Name: "virtualbox-hostonly-cidr", + Usage: "Specify the Host Only CIDR", + Value: defaultHostOnlyCIDR, + EnvVar: "VIRTUALBOX_HOSTONLY_CIDR", + }, + mcnflag.StringFlag{ + Name: "virtualbox-hostonly-nictype", + Usage: "Specify the Host Only Network Adapter Type", + Value: defaultHostOnlyNictype, + EnvVar: "VIRTUALBOX_HOSTONLY_NIC_TYPE", + }, + mcnflag.StringFlag{ + Name: "virtualbox-hostonly-nicpromisc", + Usage: "Specify the Host Only Network Adapter Promiscuous Mode", + Value: defaultHostOnlyPromiscMode, + EnvVar: "VIRTUALBOX_HOSTONLY_NIC_PROMISC", + }, + mcnflag.StringFlag{ + Name: "virtualbox-ui-type", + Usage: "Specify the UI Type: (gui|sdl|headless|separate)", + Value: defaultUIType, + EnvVar: "VIRTUALBOX_UI_TYPE", + }, + mcnflag.BoolFlag{ + Name: "virtualbox-hostonly-no-dhcp", + Usage: "Disable the Host Only DHCP Server", + EnvVar: "VIRTUALBOX_HOSTONLY_NO_DHCP", + }, + mcnflag.BoolFlag{ + Name: "virtualbox-no-share", + Usage: "Disable the mount of your home directory", + EnvVar: "VIRTUALBOX_NO_SHARE", + }, + mcnflag.BoolFlag{ + Name: "virtualbox-no-dns-proxy", + Usage: "Disable proxying all DNS requests to the host", + EnvVar: "VIRTUALBOX_NO_DNS_PROXY", + }, + mcnflag.BoolFlag{ + Name: "virtualbox-no-vtx-check", + Usage: "Disable checking for the availability of hardware virtualization before the vm is started", + EnvVar: "VIRTUALBOX_NO_VTX_CHECK", + }, + mcnflag.StringFlag{ + EnvVar: "VIRTUALBOX_SHARE_FOLDER", + Name: "virtualbox-share-folder", + Usage: "Mount the specified directory instead of the default home location. Format: dir:name", }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil +func (d *Driver) GetSSHHostname() (string, error) { + return "127.0.0.1", nil +} + +func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + + return d.SSHUser } +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return "virtualbox" } @@ -95,180 +228,212 @@ func (d *Driver) GetURL() (string, error) { } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.CPU = flags.Int("virtualbox-cpu-count") d.Memory = flags.Int("virtualbox-memory") d.DiskSize = flags.Int("virtualbox-disk-size") d.Boot2DockerURL = flags.String("virtualbox-boot2docker-url") + d.SetSwarmConfigFromFlags(flags) + d.SSHUser = "docker" + d.Boot2DockerImportVM = flags.String("virtualbox-import-boot2docker-vm") + d.HostDNSResolver = flags.Bool("virtualbox-host-dns-resolver") + d.NatNicType = flags.String("virtualbox-nat-nictype") + d.HostOnlyCIDR = flags.String("virtualbox-hostonly-cidr") + d.HostOnlyNicType = flags.String("virtualbox-hostonly-nictype") + d.HostOnlyPromiscMode = flags.String("virtualbox-hostonly-nicpromisc") + d.UIType = flags.String("virtualbox-ui-type") + d.HostOnlyNoDHCP = flags.Bool("virtualbox-hostonly-no-dhcp") + d.NoShare = flags.Bool("virtualbox-no-share") + d.DNSProxy = !flags.Bool("virtualbox-no-dns-proxy") + d.NoVTXCheck = flags.Bool("virtualbox-no-vtx-check") + d.ShareFolder = flags.String("virtualbox-share-folder") + return nil } -func cpIso(src, dest string) error { - buf, err := ioutil.ReadFile(src) +// PreCreateCheck checks that VBoxManage exists and works +func (d *Driver) PreCreateCheck() error { + // Check that VBoxManage exists and works + version, err := d.vbmOut("--version") if err != nil { return err } - if err := ioutil.WriteFile(dest, buf, 0600); err != nil { + + // Check that VBoxManage is of a supported version + if err = checkVBoxManageVersion(strings.TrimSpace(version)); err != nil { + return err + } + + if !d.NoVTXCheck { + if isHyperVInstalled() { + return ErrNotCompatibleWithHyperV + } + + if d.IsVTXDisabled() { + return ErrMustEnableVTX + } + } + + // Downloading boot2docker to cache should be done here to make sure + // that a download failure will not leave a machine half created. + if err := d.b2dUpdater.UpdateISOCache(d.StorePath, d.Boot2DockerURL); err != nil { + return err + } + + // Check that Host-only interfaces are ok + if _, err = listHostOnlyAdapters(d.VBoxManager); err != nil { return err } - return nil -} -func (d *Driver) PreCreateCheck() error { return nil } func (d *Driver) Create() error { - var ( - err error - isoURL string - ) - - // Check that VBoxManage exists and works - if err = vbm(); err != nil { + if err := d.CreateVM(); err != nil { return err } - d.SSHPort, err = getAvailableTCPPort() - if err != nil { + log.Info("Starting the VM...") + return d.Start() +} + +func (d *Driver) CreateVM() error { + if err := d.b2dUpdater.CopyIsoToMachineDir(d.StorePath, d.MachineName, d.Boot2DockerURL); err != nil { return err } - if d.Boot2DockerURL != "" { - isoURL = d.Boot2DockerURL - log.Infof("Downloading boot2docker.iso from %s...", isoURL) - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { - return err - } - } else { - // todo: check latest release URL, download if it's new - // until then always use "latest" - isoURL, err = utils.GetLatestBoot2DockerReleaseURL() + log.Info("Creating VirtualBox VM...") + + // import b2d VM if requested + if d.Boot2DockerImportVM != "" { + name := d.Boot2DockerImportVM + + // make sure vm is stopped + _ = d.vbm("controlvm", name, "poweroff") + + diskInfo, err := getVMDiskInfo(name, d.VBoxManager) if err != nil { return err } - // todo: use real constant for .docker - rootPath := filepath.Join(utils.GetHomeDir(), ".docker") - imgPath := filepath.Join(rootPath, "images") - commonIsoPath := filepath.Join(imgPath, "boot2docker.iso") - if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) { - log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath) - - // just in case boot2docker.iso has been manually deleted - if _, err := os.Stat(imgPath); os.IsNotExist(err) { - if err := os.Mkdir(imgPath, 0700); err != nil { - return err - } - } - - if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { - return err - } + if _, err := os.Stat(diskInfo.Path); err != nil { + return err } - isoDest := filepath.Join(d.storePath, "boot2docker.iso") - if err := cpIso(commonIsoPath, isoDest); err != nil { + if err := d.vbm("clonehd", diskInfo.Path, d.diskPath()); err != nil { return err } - } - log.Infof("Creating SSH key...") + log.Debugf("Importing VM settings...") + vmInfo, err := getVMInfo(name, d.VBoxManager) + if err != nil { + return err + } - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { - return err - } + d.CPU = vmInfo.CPUs + d.Memory = vmInfo.Memory - log.Infof("Creating VirtualBox VM...") + log.Debugf("Importing SSH key...") + keyPath := filepath.Join(mcnutils.GetHomeDir(), ".ssh", "id_boot2docker") + if err := mcnutils.CopyFile(keyPath, d.GetSSHKeyPath()); err != nil { + return err + } + } else { + log.Infof("Creating SSH key...") + if err := d.sshKeyGenerator.Generate(d.GetSSHKeyPath()); err != nil { + return err + } - if err := d.generateDiskImage(d.DiskSize); err != nil { - return err + log.Debugf("Creating disk image...") + if err := d.diskCreator.Create(d.DiskSize, d.publicSSHKeyPath(), d.diskPath()); err != nil { + return err + } } - if err := vbm("createvm", - "--basefolder", d.storePath, + if err := d.vbm("createvm", + "--basefolder", d.ResolveStorePath("."), "--name", d.MachineName, "--register"); err != nil { return err } - cpus := uint(runtime.NumCPU()) + log.Debugf("VM CPUS: %d", d.CPU) + log.Debugf("VM Memory: %d", d.Memory) + + cpus := d.CPU + if cpus < 1 { + cpus = int(runtime.NumCPU()) + } if cpus > 32 { cpus = 32 } - if err := vbm("modifyvm", d.MachineName, + hostDNSResolver := "off" + if d.HostDNSResolver { + hostDNSResolver = "on" + } + + dnsProxy := "off" + if d.DNSProxy { + dnsProxy = "on" + } + + var modifyFlags = []string{ + "modifyvm", d.MachineName, "--firmware", "bios", "--bioslogofadein", "off", "--bioslogofadeout", "off", - "--natdnshostresolver1", "on", "--bioslogodisplaytime", "0", "--biosbootmenu", "disabled", - "--ostype", "Linux26_64", "--cpus", fmt.Sprintf("%d", cpus), "--memory", fmt.Sprintf("%d", d.Memory), - "--acpi", "on", "--ioapic", "on", "--rtcuseutc", "on", + "--natdnshostresolver1", hostDNSResolver, + "--natdnsproxy1", dnsProxy, "--cpuhotplug", "off", "--pae", "on", - "--synthcpu", "off", "--hpet", "on", "--hwvirtex", "on", "--nestedpaging", "on", "--largepages", "on", "--vtxvpid", "on", "--accelerate3d", "off", - "--boot1", "dvd"); err != nil { - return err - } + "--boot1", "dvd"} - if err := vbm("modifyvm", d.MachineName, - "--nic1", "nat", - "--nictype1", "virtio", - "--cableconnected1", "on"); err != nil { - return err + if runtime.GOOS == "windows" && runtime.GOARCH == "386" { + modifyFlags = append(modifyFlags, "--longmode", "on") } - if err := vbm("modifyvm", d.MachineName, - "--natpf1", fmt.Sprintf("ssh,tcp,127.0.0.1,%d,,22", d.SSHPort)); err != nil { + if err := d.vbm(modifyFlags...); err != nil { return err } - hostOnlyNetwork, err := getOrCreateHostOnlyNetwork( - net.ParseIP("192.168.99.1"), - net.IPv4Mask(255, 255, 255, 0), - net.ParseIP("192.168.99.2"), - net.ParseIP("192.168.99.100"), - net.ParseIP("192.168.99.254")) - if err != nil { - return err - } - if err := vbm("modifyvm", d.MachineName, - "--nic2", "hostonly", - "--nictype2", "virtio", - "--hostonlyadapter2", hostOnlyNetwork.Name, - "--cableconnected2", "on"); err != nil { + if err := d.vbm("modifyvm", d.MachineName, + "--nic1", "nat", + "--nictype1", d.NatNicType, + "--cableconnected1", "on"); err != nil { return err } - if err := vbm("storagectl", d.MachineName, + if err := d.vbm("storagectl", d.MachineName, "--name", "SATA", "--add", "sata", "--hostiocache", "on"); err != nil { return err } - if err := vbm("storageattach", d.MachineName, + if err := d.vbm("storageattach", d.MachineName, "--storagectl", "SATA", "--port", "0", "--device", "0", "--type", "dvddrive", - "--medium", filepath.Join(d.storePath, "boot2docker.iso")); err != nil { + "--medium", d.ResolveStorePath("boot2docker.iso")); err != nil { return err } - if err := vbm("storageattach", d.MachineName, + if err := d.vbm("storageattach", d.MachineName, "--storagectl", "SATA", "--port", "1", "--device", "0", @@ -278,22 +443,21 @@ func (d *Driver) Create() error { } // let VBoxService do nice magic automounting (when it's used) - if err := vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountPrefix", "/"); err != nil { + if err := d.vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountPrefix", "/"); err != nil { return err } - if err := vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountDir", "/"); err != nil { + if err := d.vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountDir", "/"); err != nil { return err } - var shareName, shareDir string // TODO configurable at some point - switch runtime.GOOS { - case "darwin": - shareName = "Users" - shareDir = "/Users" - // TODO "linux" and "windows" + shareName, shareDir := getShareDriveAndName() + + if d.ShareFolder != "" { + shareDir, shareName = parseShareFolder(d.ShareFolder) } - if shareDir != "" { + if shareDir != "" && !d.NoShare { + log.Debugf("setting up shareDir '%s' -> '%s'", shareDir, shareName) if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) { return err } else if !os.IsNotExist(err) { @@ -305,50 +469,162 @@ func (d *Driver) Create() error { } // woo, shareDir exists! let's carry on! - if err := vbm("sharedfolder", "add", d.MachineName, "--name", shareName, "--hostpath", shareDir, "--automount"); err != nil { + if err := d.vbm("sharedfolder", "add", d.MachineName, "--name", shareName, "--hostpath", shareDir, "--automount"); err != nil { return err } // enable symlinks - if err := vbm("setextradata", d.MachineName, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/"+shareName, "1"); err != nil { + if err := d.vbm("setextradata", d.MachineName, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/"+shareName, "1"); err != nil { return err } } } - log.Infof("Starting VirtualBox VM...") + return nil +} - if err := d.Start(); err != nil { +func parseShareFolder(shareFolder string) (string, string) { + split := strings.Split(shareFolder, ":") + shareDir := strings.Join(split[:len(split)-1], ":") + shareName := split[len(split)-1] + return shareDir, shareName +} + +func (d *Driver) hostOnlyIPAvailable() bool { + ip, err := d.GetIP() + if err != nil { + log.Debugf("ERROR getting IP: %s", err) + return false + } + if ip == "" { + log.Debug("Strangely, there was no error attempting to get the IP, but it was still empty.") + return false + } + + log.Debugf("IP is %s", ip) + return true +} + +func (d *Driver) Start() error { + s, err := d.GetState() + if err != nil { + return err + } + + var hostOnlyAdapter *hostOnlyNetwork + if s == state.Stopped { + log.Infof("Check network to re-create if needed...") + + if hostOnlyAdapter, err = d.setupHostOnlyNetwork(d.MachineName); err != nil { + return fmt.Errorf("Error setting up host only network on machine start: %s", err) + } + } + + switch s { + case state.Stopped, state.Saved: + d.SSHPort, err = setPortForwarding(d, 1, "ssh", "tcp", 22, d.SSHPort) + if err != nil { + return err + } + + if err := d.vbm("startvm", d.MachineName, "--type", d.UIType); err != nil { + if lines, readErr := d.readVBoxLog(); readErr == nil && len(lines) > 0 { + return fmt.Errorf("Unable to start the VM: %s\nDetails: %s", err, lines[len(lines)-1]) + } + return fmt.Errorf("Unable to start the VM: %s", err) + } + case state.Paused: + if err := d.vbm("controlvm", d.MachineName, "resume", "--type", d.UIType); err != nil { + return err + } + log.Infof("Resuming VM ...") + default: + log.Infof("VM not in restartable state") + } + + if !d.NoVTXCheck { + // Verify that VT-X is not disabled in the started VM + vtxIsDisabled, err := d.IsVTXDisabledInTheVM() + if err != nil { + return fmt.Errorf("Checking if hardware virtualization is enabled failed: %s", err) + } + + if vtxIsDisabled { + return ErrMustEnableVTX + } + } + + log.Infof("Waiting for an IP...") + if err := d.ipWaiter.Wait(d); err != nil { return err } - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "sudo hostname %s && echo \"%s\" | sudo tee /var/lib/boot2docker/etc/hostname", - d.MachineName, - d.MachineName, - )) + if hostOnlyAdapter == nil { + return nil + } + + // Check that the host-only adapter we just created can still be found + // Sometimes it is corrupted after the VM is started. + nets, err := listHostOnlyAdapters(d.VBoxManager) if err != nil { return err + } + ip, network, err := parseAndValidateCIDR(d.HostOnlyCIDR) + if err != nil { + return err } - if err := cmd.Run(); err != nil { + + err = validateNoIPCollisions(d.HostInterfaces, network, nets) + if err != nil { return err + } + hostOnlyNet := getHostOnlyAdapter(nets, ip, network.Mask) + if hostOnlyNet != nil { + // OK, we found a valid host-only adapter + return nil } - return nil -} + // This happens a lot on windows. The adapter has an invalid IP and the VM has the same IP + log.Warn("The host-only adapter is corrupted. Let's stop the VM, fix the host-only adapter and restart the VM") + if err := d.Stop(); err != nil { + return err + } -func (d *Driver) Start() error { - if err := vbm("startvm", d.MachineName, "--type", "headless"); err != nil { + // We have to be sure the host-only adapter is not used by the VM + d.sleeper.Sleep(5 * time.Second) + + log.Debugf("Fixing %+v...", hostOnlyAdapter) + if err := hostOnlyAdapter.SaveIPv4(d.VBoxManager); err != nil { return err } - log.Infof("Waiting for VM to start...") - return ssh.WaitForTCP(fmt.Sprintf("localhost:%d", d.SSHPort)) + + // We have to be sure the adapter is updated before starting the VM + d.sleeper.Sleep(5 * time.Second) + + if err := d.vbm("startvm", d.MachineName, "--type", d.UIType); err != nil { + return fmt.Errorf("Unable to start the VM: %s", err) + } + + log.Infof("Waiting for an IP...") + return d.ipWaiter.Wait(d) } func (d *Driver) Stop() error { - if err := vbm("controlvm", d.MachineName, "acpipowerbutton"); err != nil { + currentState, err := d.GetState() + if err != nil { + return err + } + + if currentState == state.Paused { + if err := d.vbm("controlvm", d.MachineName, "resume"); err != nil { // , "--type", d.UIType + return err + } + log.Infof("Resuming VM ...") + } + + if err := d.vbm("controlvm", d.MachineName, "acpipowerbutton"); err != nil { return err } for { @@ -357,69 +633,56 @@ func (d *Driver) Stop() error { return err } if s == state.Running { - time.Sleep(1 * time.Second) + d.sleeper.Sleep(1 * time.Second) } else { break } } - return nil -} -func (d *Driver) Remove() error { - s, err := d.GetState() - if err != nil { - if err == ErrMachineNotExist { - log.Infof("machine does not exist, assuming it has been removed already") - return nil - } - return err - } - if s == state.Running { - if err := d.Kill(); err != nil { - return err - } - } - return vbm("unregistervm", "--delete", d.MachineName) + d.IPAddress = "" + + return nil } +// Restart restarts a machine which is known to be running. func (d *Driver) Restart() error { if err := d.Stop(); err != nil { - return err + return fmt.Errorf("Problem stopping the VM: %s", err) } - return d.Start() + + if err := d.Start(); err != nil { + return fmt.Errorf("Problem starting the VM: %s", err) + } + + d.IPAddress = "" + + return d.ipWaiter.Wait(d) } func (d *Driver) Kill() error { - return vbm("controlvm", d.MachineName, "poweroff") + return d.vbm("controlvm", d.MachineName, "poweroff") } -func (d *Driver) Upgrade() error { - log.Infof("Stopping machine...") - if err := d.Stop(); err != nil { - return err +func (d *Driver) Remove() error { + s, err := d.GetState() + if err == ErrMachineNotExist { + return nil } - - isoURL, err := utils.GetLatestBoot2DockerReleaseURL() if err != nil { return err } - log.Infof("Downloading boot2docker...") - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { - return err - } - - log.Infof("Starting machine...") - if err := d.Start(); err != nil { - return err + if s != state.Stopped && s != state.Saved { + if err := d.Kill(); err != nil { + return err + } } - return nil + return d.vbm("unregistervm", "--delete", d.MachineName) } func (d *Driver) GetState() (state.State, error) { - stdout, stderr, err := vbmOutErr("showvminfo", d.MachineName, - "--machinereadable") + stdout, stderr, err := d.vbmOutErr("showvminfo", d.MachineName, "--machinereadable") if err != nil { if reMachineNotFound.FindString(stderr) != "" { return state.Error, ErrMachineNotExist @@ -444,10 +707,65 @@ func (d *Driver) GetState() (state.State, error) { return state.None, nil } -func (d *Driver) setMachineNameIfNotSet() { - if d.MachineName == "" { - d.MachineName = fmt.Sprintf("docker-machine-unknown") +func (d *Driver) getHostOnlyMACAddress() (string, error) { + // Return the MAC address of the host-only adapter + // assigned to this machine. The returned address + // is lower-cased and does not contain colons. + + stdout, stderr, err := d.vbmOutErr("showvminfo", d.MachineName, "--machinereadable") + if err != nil { + if reMachineNotFound.FindString(stderr) != "" { + return "", ErrMachineNotExist + } + return "", err + } + + // First, we get the number of the host-only interface + re := regexp.MustCompile(`(?m)^hostonlyadapter([\d]+)`) + groups := re.FindStringSubmatch(stdout) + if len(groups) < 2 { + return "", errors.New("Machine does not have a host-only adapter") + } + + // Then we grab the MAC address based on that number + adapterNumber := groups[1] + re = regexp.MustCompile(fmt.Sprintf("(?m)^macaddress%s=\"(.*)\"", adapterNumber)) + groups = re.FindStringSubmatch(stdout) + if len(groups) < 2 { + return "", fmt.Errorf("Could not find MAC address for adapter %v", adapterNumber) + } + + return strings.ToLower(groups[1]), nil +} + +func (d *Driver) parseIPForMACFromIPAddr(ipAddrOutput string, macAddress string) (string, error) { + // Given the output of "ip addr show" on the VM, return the IPv4 address + // of the interface with the given MAC address. + + lines := strings.Split(ipAddrOutput, "\n") + returnNextIP := false + + for _, line := range lines { + line = strings.TrimSpace(line) + + if strings.HasPrefix(line, "link") { // line contains MAC address + vals := strings.Split(line, " ") + if len(vals) >= 2 { + macBlock := vals[1] + macWithoutColons := strings.Replace(macBlock, ":", "", -1) + if macWithoutColons == macAddress { // we are in the correct device block + returnNextIP = true + } + } + } else if strings.HasPrefix(line, "inet") && !strings.HasPrefix(line, "inet6") && returnNextIP { + vals := strings.Split(line, " ") + if len(vals) >= 2 { + return vals[1][:strings.Index(vals[1], "/")], nil + } + } } + + return "", fmt.Errorf("Could not find matching IP for MAC address %v", macAddress) } func (d *Driver) GetIP() (string, error) { @@ -461,200 +779,243 @@ func (d *Driver) GetIP() (string, error) { return "", drivers.ErrHostIsNotRunning } - cmd, err := d.GetSSHCommand("ip addr show dev eth1") + macAddress, err := d.getHostOnlyMACAddress() if err != nil { return "", err } - // reset to nil as if using from Host Stdout is already set when using DEBUG - cmd.Stdout = nil + log.Debugf("Host-only MAC: %s\n", macAddress) - b, err := cmd.Output() + output, err := drivers.RunSSHCommandFromDriver(d, "ip addr show") if err != nil { return "", err } - out := string(b) - log.Debugf("SSH returned: %s\nEND SSH\n", out) - // parse to find: inet 192.168.59.103/24 brd 192.168.59.255 scope global eth1 - lines := strings.Split(out, "\n") - for _, line := range lines { - vals := strings.Split(strings.TrimSpace(line), " ") - if len(vals) >= 2 && vals[0] == "inet" { - return vals[1][:strings.Index(vals[1], "/")], nil - } + + log.Debugf("SSH returned: %s\nEND SSH\n", output) + + ipAddress, err := d.parseIPForMACFromIPAddr(output, macAddress) + if err != nil { + return "", err } - return "", fmt.Errorf("No IP address found %s", out) + return ipAddress, nil } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand("localhost", d.SSHPort, "docker", d.sshKeyPath(), args...), nil +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") +func (d *Driver) diskPath() string { + return d.ResolveStorePath("disk.vmdk") +} - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") - if err != nil { - return err +func (d *Driver) setupHostOnlyNetwork(machineName string) (*hostOnlyNetwork, error) { + hostOnlyCIDR := d.HostOnlyCIDR + + // This is to assist in migrating from version 0.2 to 0.3 format + // it should be removed in a later release + if hostOnlyCIDR == "" { + hostOnlyCIDR = defaultHostOnlyCIDR } - if err := cmd.Run(); err != nil { - return err + + ip, network, err := parseAndValidateCIDR(hostOnlyCIDR) + if err != nil { + return nil, err } - return nil -} + nets, err := listHostOnlyAdapters(d.VBoxManager) + if err != nil { + return nil, err + } -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") + err = validateNoIPCollisions(d.HostInterfaces, network, nets) + if err != nil { + return nil, err + } - cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi") + log.Debugf("Searching for hostonly interface for IPv4: %s and Mask: %s", ip, network.Mask) + hostOnlyAdapter, err := getOrCreateHostOnlyNetwork(ip, network.Mask, nets, d.VBoxManager) if err != nil { - return err + return nil, err } - if err := cmd.Run(); err != nil { - return err + + if err := removeOrphanDHCPServers(d.VBoxManager); err != nil { + return nil, err } - return nil -} + dhcpAddr, err := getRandomIPinSubnet(d, ip) + if err != nil { + return nil, err + } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} + lowerIP, upperIP := getDHCPAddressRange(dhcpAddr, network) -func (d *Driver) sshKeyPath() string { - return filepath.Join(d.storePath, "id_rsa") -} + log.Debugf("Adding/Modifying DHCP server %q with address range %q - %q...", dhcpAddr, lowerIP, upperIP) -func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" -} + dhcp := dhcpServer{} + dhcp.IPv4.IP = dhcpAddr + dhcp.IPv4.Mask = network.Mask + dhcp.LowerIP = lowerIP + dhcp.UpperIP = upperIP + dhcp.Enabled = !d.HostOnlyNoDHCP + if err := addHostOnlyDHCPServer(hostOnlyAdapter.Name, dhcp, d.VBoxManager); err != nil { + return nil, err + } -func (d *Driver) diskPath() string { - return filepath.Join(d.storePath, "disk.vmdk") + if err := d.vbm("modifyvm", machineName, + "--nic2", "hostonly", + "--nictype2", d.HostOnlyNicType, + "--nicpromisc2", d.HostOnlyPromiscMode, + "--hostonlyadapter2", hostOnlyAdapter.Name, + "--cableconnected2", "on"); err != nil { + return nil, err + } + + return hostOnlyAdapter, nil } -// Make a boot2docker VM disk image. -func (d *Driver) generateDiskImage(size int) error { - log.Debugf("Creating %d MB hard disk image...", size) +func getDHCPAddressRange(dhcpAddr net.IP, network *net.IPNet) (lowerIP net.IP, upperIP net.IP) { + nAddr := network.IP.To4() + ones, bits := network.Mask.Size() - magicString := "boot2docker, please format-me" + if ones <= 24 { + // For a /24 subnet, use the original behavior of allowing the address range + // between x.x.x.100 and x.x.x.254. + lowerIP = net.IPv4(nAddr[0], nAddr[1], nAddr[2], byte(100)) + upperIP = net.IPv4(nAddr[0], nAddr[1], nAddr[2], byte(254)) + return + } - buf := new(bytes.Buffer) - tw := tar.NewWriter(buf) + // Start the lowerIP range one address above the selected DHCP address. + lowerIP = net.IPv4(nAddr[0], nAddr[1], nAddr[2], dhcpAddr.To4()[3]+1) - // magicString first so the automount script knows to format the disk - file := &tar.Header{Name: magicString, Size: int64(len(magicString))} - if err := tw.WriteHeader(file); err != nil { - return err - } - if _, err := tw.Write([]byte(magicString)); err != nil { - return err - } - // .ssh/key.pub => authorized_keys - file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700} - if err := tw.WriteHeader(file); err != nil { - return err - } - pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) + // The highest D-part of the address A.B.C.D in this subnet is at 2^n - 1, + // where n is the number of available bits in the subnet. Since the highest + // address is reserved for subnet broadcast, the highest *assignable* address + // is at (2^n - 1) - 1 == 2^n - 2. + maxAssignableSubnetAddress := (byte)((1 << (uint)(bits-ones)) - 2) + upperIP = net.IPv4(nAddr[0], nAddr[1], nAddr[2], maxAssignableSubnetAddress) + return +} + +func parseAndValidateCIDR(hostOnlyCIDR string) (net.IP, *net.IPNet, error) { + ip, network, err := net.ParseCIDR(hostOnlyCIDR) if err != nil { - return err + return nil, nil, err } - file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644} - if err := tw.WriteHeader(file); err != nil { - return err + + networkAddress := network.IP.To4() + if ip.Equal(networkAddress) { + return nil, nil, ErrNetworkAddrCidr } - if _, err := tw.Write([]byte(pubKey)); err != nil { - return err + + return ip, network, nil +} + +// validateNoIPCollisions ensures no conflicts between the host's network interfaces and the vbox host-only network that +// will be used for machine vm instances. +func validateNoIPCollisions(hif HostInterfaces, hostOnlyNet *net.IPNet, currHostOnlyNets map[string]*hostOnlyNetwork) error { + hostOnlyByCIDR := map[string]*hostOnlyNetwork{} + //listHostOnlyAdapters returns a map w/ virtualbox net names as key. Rekey to CIDRs + for _, n := range currHostOnlyNets { + ipnet := net.IPNet{IP: n.IPv4.IP, Mask: n.IPv4.Mask} + hostOnlyByCIDR[ipnet.String()] = n } - file = &tar.Header{Name: ".ssh/authorized_keys2", Size: int64(len(pubKey)), Mode: 0644} - if err := tw.WriteHeader(file); err != nil { + + m, err := listHostInterfaces(hif, hostOnlyByCIDR) + if err != nil { return err } - if _, err := tw.Write([]byte(pubKey)); err != nil { + + collision, err := checkIPNetCollision(hostOnlyNet, m) + if err != nil { return err } - if err := tw.Close(); err != nil { - return err + + if collision { + return ErrNetworkAddrCollision } - raw := bytes.NewReader(buf.Bytes()) - return createDiskImage(d.diskPath(), size, raw) + return nil } -// createDiskImage makes a disk image at dest with the given size in MB. If r is -// not nil, it will be read as a raw disk image to convert from. -func createDiskImage(dest string, size int, r io.Reader) error { - // Convert a raw image from stdin to the dest VMDK image. - sizeBytes := int64(size) << 20 // usually won't fit in 32-bit int (max 2GB) - // FIXME: why isn't this just using the vbm*() functions? - cmd := exec.Command(vboxManageCmd, "convertfromraw", "stdin", dest, - fmt.Sprintf("%d", sizeBytes), "--format", "VMDK") - - if os.Getenv("DEBUG") != "" { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr +// Select an available port, trying the specified +// port first, falling back on an OS selected port. +func getAvailableTCPPort(port int) (int, error) { + for i := 0; i <= 10; i++ { + ln, err := net.Listen("tcp4", fmt.Sprintf("127.0.0.1:%d", port)) + if err != nil { + return 0, err + } + defer ln.Close() + addr := ln.Addr().String() + addrParts := strings.SplitN(addr, ":", 2) + p, err := strconv.Atoi(addrParts[1]) + if err != nil { + return 0, err + } + if p != 0 { + port = p + return port, nil + } + port = 0 // Throw away the port hint before trying again + time.Sleep(1) } + return 0, fmt.Errorf("unable to allocate tcp port") +} - stdin, err := cmd.StdinPipe() +// Setup a NAT port forwarding entry. +func setPortForwarding(d *Driver, interfaceNum int, mapName, protocol string, guestPort, desiredHostPort int) (int, error) { + actualHostPort, err := getAvailableTCPPort(desiredHostPort) if err != nil { - return err + return -1, err } - if err := cmd.Start(); err != nil { - return err + if desiredHostPort != actualHostPort && desiredHostPort != 0 { + log.Debugf("NAT forwarding host port for guest port %d (%s) changed from %d to %d", + guestPort, mapName, desiredHostPort, actualHostPort) } - - n, err := io.Copy(stdin, r) - if err != nil { - return err + cmd := fmt.Sprintf("--natpf%d", interfaceNum) + d.vbm("modifyvm", d.MachineName, cmd, "delete", mapName) + if err := d.vbm("modifyvm", d.MachineName, + cmd, fmt.Sprintf("%s,%s,127.0.0.1,%d,,%d", mapName, protocol, actualHostPort, guestPort)); err != nil { + return -1, err } + return actualHostPort, nil +} - // The total number of bytes written to stdin must match sizeBytes, or - // VBoxManage.exe on Windows will fail. Fill remaining with zeros. - if left := sizeBytes - n; left > 0 { - if err := zeroFill(stdin, left); err != nil { - return err +// getRandomIPinSubnet returns a pseudo-random net.IP in the same +// subnet as the IP passed +func getRandomIPinSubnet(d *Driver, baseIP net.IP) (net.IP, error) { + var dhcpAddr net.IP + + nAddr := baseIP.To4() + // select pseudo-random DHCP addr; make sure not to clash with the host + // only try 5 times and bail if no random received + for i := 0; i < 5; i++ { + n := d.randomInter.RandomInt(24) + 1 + if byte(n) != nAddr[3] { + dhcpAddr = net.IPv4(nAddr[0], nAddr[1], nAddr[2], byte(n)) + break } } - // cmd won't exit until the stdin is closed. - if err := stdin.Close(); err != nil { - return err + if dhcpAddr == nil { + return nil, ErrUnableToGenerateRandomIP } - return cmd.Wait() + return dhcpAddr, nil } -// zeroFill writes n zero bytes into w. -func zeroFill(w io.Writer, n int64) error { - const blocksize = 32 << 10 - zeros := make([]byte, blocksize) - var k int - var err error - for n > 0 { - if n > blocksize { - k, err = w.Write(zeros) - } else { - k, err = w.Write(zeros[:n]) - } - if err != nil { - return err - } - n -= int64(k) +func detectVBoxManageCmdInPath() string { + cmd := "VBoxManage" + if path, err := exec.LookPath(cmd); err == nil { + return path } - return nil + return cmd } -func getAvailableTCPPort() (int, error) { - // FIXME: this has a race condition between finding an available port and - // virtualbox using that port. Perhaps we should randomly pick an unused - // port in a range not used by kernel for assigning ports - ln, err := net.Listen("tcp4", "127.0.0.1:0") - if err != nil { - return 0, err - } - defer ln.Close() - addr := ln.Addr().String() - addrParts := strings.SplitN(addr, ":", 2) - return strconv.Atoi(addrParts[1]) +func (d *Driver) readVBoxLog() ([]string, error) { + logPath := filepath.Join(d.ResolveStorePath(d.MachineName), "Logs", "VBox.log") + log.Debugf("Checking vm logs: %s", logPath) + + return d.logsReader.Read(logPath) } diff --git a/drivers/virtualbox/virtualbox_darwin.go b/drivers/virtualbox/virtualbox_darwin.go new file mode 100644 index 0000000000..0c225bde6d --- /dev/null +++ b/drivers/virtualbox/virtualbox_darwin.go @@ -0,0 +1,13 @@ +package virtualbox + +func detectVBoxManageCmd() string { + return detectVBoxManageCmdInPath() +} + +func getShareDriveAndName() (string, string) { + return "Users", "/Users" +} + +func isHyperVInstalled() bool { + return false +} diff --git a/drivers/virtualbox/virtualbox_darwin_test.go b/drivers/virtualbox/virtualbox_darwin_test.go new file mode 100644 index 0000000000..c7d65f05b1 --- /dev/null +++ b/drivers/virtualbox/virtualbox_darwin_test.go @@ -0,0 +1,15 @@ +package virtualbox + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestShareName(t *testing.T) { + name, dir := getShareDriveAndName() + + assert.Equal(t, name, "Users") + assert.Equal(t, dir, "/Users") + +} diff --git a/drivers/virtualbox/virtualbox_freebsd.go b/drivers/virtualbox/virtualbox_freebsd.go new file mode 100644 index 0000000000..f41429e2ec --- /dev/null +++ b/drivers/virtualbox/virtualbox_freebsd.go @@ -0,0 +1,13 @@ +package virtualbox + +func detectVBoxManageCmd() string { + return detectVBoxManageCmdInPath() +} + +func getShareDriveAndName() (string, string) { + return "hosthome", "/home" +} + +func isHyperVInstalled() bool { + return false +} diff --git a/drivers/virtualbox/virtualbox_linux.go b/drivers/virtualbox/virtualbox_linux.go new file mode 100644 index 0000000000..f41429e2ec --- /dev/null +++ b/drivers/virtualbox/virtualbox_linux.go @@ -0,0 +1,13 @@ +package virtualbox + +func detectVBoxManageCmd() string { + return detectVBoxManageCmdInPath() +} + +func getShareDriveAndName() (string, string) { + return "hosthome", "/home" +} + +func isHyperVInstalled() bool { + return false +} diff --git a/drivers/virtualbox/virtualbox_linux_test.go b/drivers/virtualbox/virtualbox_linux_test.go new file mode 100644 index 0000000000..7536db52f7 --- /dev/null +++ b/drivers/virtualbox/virtualbox_linux_test.go @@ -0,0 +1,14 @@ +package virtualbox + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestShareName(t *testing.T) { + name, dir := getShareDriveAndName() + + assert.Equal(t, name, "hosthome") + assert.Equal(t, dir, "/home") +} diff --git a/drivers/virtualbox/virtualbox_openbsd.go b/drivers/virtualbox/virtualbox_openbsd.go new file mode 100644 index 0000000000..f41429e2ec --- /dev/null +++ b/drivers/virtualbox/virtualbox_openbsd.go @@ -0,0 +1,13 @@ +package virtualbox + +func detectVBoxManageCmd() string { + return detectVBoxManageCmdInPath() +} + +func getShareDriveAndName() (string, string) { + return "hosthome", "/home" +} + +func isHyperVInstalled() bool { + return false +} diff --git a/drivers/virtualbox/virtualbox_test.go b/drivers/virtualbox/virtualbox_test.go new file mode 100644 index 0000000000..24899fefc7 --- /dev/null +++ b/drivers/virtualbox/virtualbox_test.go @@ -0,0 +1,732 @@ +package virtualbox + +import ( + "errors" + "fmt" + "net" + "reflect" + "runtime" + "strings" + "testing" + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +type VBoxManagerMock struct { + args string + stdOut string + stdErr string + err error +} + +func (v *VBoxManagerMock) vbm(args ...string) error { + _, _, err := v.vbmOutErr(args...) + return err +} + +func (v *VBoxManagerMock) vbmOut(args ...string) (string, error) { + stdout, _, err := v.vbmOutErr(args...) + return stdout, err +} + +func (v *VBoxManagerMock) vbmOutErr(args ...string) (string, string, error) { + if strings.Join(args, " ") == v.args { + return v.stdOut, v.stdErr, v.err + } + return "", "", errors.New("Invalid args") +} + +func newTestDriver(name string) *Driver { + return NewDriver(name, "") +} + +func TestDriverName(t *testing.T) { + driverName := newTestDriver("default").DriverName() + + assert.Equal(t, "virtualbox", driverName) +} + +func TestSSHHostname(t *testing.T) { + hostname, err := newTestDriver("default").GetSSHHostname() + + assert.Equal(t, "127.0.0.1", hostname) + assert.NoError(t, err) +} + +func TestDefaultSSHUsername(t *testing.T) { + username := newTestDriver("default").GetSSHUsername() + + assert.Equal(t, "docker", username) +} + +var parseShareFolderTestCases = []struct { + shareFolder string + expectedShareDir string + expectedShareName string +}{ + {"dir:name", "dir", "name"}, + {"C:\\dir:name", "C:\\dir", "name"}, + {"C:\\:name", "C:\\", "name"}, +} + +func TestParseShareFolder(t *testing.T) { + for _, parseShareFolderTestCase := range parseShareFolderTestCases { + shareDir, shareName := parseShareFolder(parseShareFolderTestCase.shareFolder) + + assert.Equal(t, shareDir, parseShareFolderTestCase.expectedShareDir) + assert.Equal(t, shareName, parseShareFolderTestCase.expectedShareName) + } +} + +func TestState(t *testing.T) { + var tests = []struct { + stdOut string + state state.State + }{ + {`VMState="running"`, state.Running}, + {`VMState="paused"`, state.Paused}, + {`VMState="saved"`, state.Saved}, + {`VMState="poweroff"`, state.Stopped}, + {`VMState="aborted"`, state.Stopped}, + {`VMState="whatever"`, state.None}, + {`VMState=`, state.None}, + } + + for _, expected := range tests { + driver := newTestDriver("default") + driver.VBoxManager = &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdOut: expected.stdOut, + } + + machineState, err := driver.GetState() + + assert.NoError(t, err) + assert.Equal(t, expected.state, machineState) + } +} + +func TestStateErrors(t *testing.T) { + var tests = []struct { + stdErr string + err error + finalErr error + }{ + {"Could not find a registered machine named 'unknown'", errors.New("Bug"), errors.New("machine does not exist")}, + {"", errors.New("Unexpected error"), errors.New("Unexpected error")}, + } + + for _, expected := range tests { + driver := newTestDriver("default") + driver.VBoxManager = &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdErr: expected.stdErr, + err: expected.err, + } + + machineState, err := driver.GetState() + + assert.Equal(t, err, expected.finalErr) + assert.Equal(t, state.Error, machineState) + } +} + +func TestGetRandomIPinSubnet(t *testing.T) { + driver := newTestDriver("default") + + // test IP 1.2.3.4 + testIP := net.IPv4(byte(1), byte(2), byte(3), byte(4)) + newIP, err := getRandomIPinSubnet(driver, testIP) + if err != nil { + t.Fatal(err) + } + + if testIP.Equal(newIP) { + t.Fatalf("expected different IP (source %s); received %s", testIP.String(), newIP.String()) + } + + if newIP[0] != testIP[0] { + t.Fatalf("expected first octet of %d; received %d", testIP[0], newIP[0]) + } + + if newIP[1] != testIP[1] { + t.Fatalf("expected second octet of %d; received %d", testIP[1], newIP[1]) + } + + if newIP[2] != testIP[2] { + t.Fatalf("expected third octet of %d; received %d", testIP[2], newIP[2]) + } +} + +func TestGetHostOnlyMACAddress(t *testing.T) { + driver := newTestDriver("default") + driver.VBoxManager = &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdOut: "unrelatedfield=whatever\nhostonlyadapter2=\"vboxnet1\"\nmacaddress2=\"004488AABBCC\"\n", + } + + result, err := driver.getHostOnlyMACAddress() + expected := "004488aabbcc" + assert.NoError(t, err) + assert.Equal(t, expected, result) +} + +func TestGetHostOnlyMACAddressWhenNoHostOnlyAdapter(t *testing.T) { + driver := newTestDriver("default") + driver.VBoxManager = &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdOut: "unrelatedfield=whatever\n", + } + + result, err := driver.getHostOnlyMACAddress() + assert.Empty(t, result) + assert.Equal(t, err, errors.New("Machine does not have a host-only adapter")) +} + +func TestParseIPForMACFromIPAddr(t *testing.T) { + driver := newTestDriver("default") + + ipAddrOutput := "1: eth0:\n link/ether 00:44:88:aa:bb:cc\n inet 1.2.3.4/24\n2: eth1:\n link/ether 11:55:99:dd:ee:ff\n inet 5.6.7.8/24" + + result, err := driver.parseIPForMACFromIPAddr(ipAddrOutput, "004488aabbcc") + assert.NoError(t, err) + assert.Equal(t, result, "1.2.3.4") + + result, err = driver.parseIPForMACFromIPAddr(ipAddrOutput, "115599ddeeff") + assert.NoError(t, err) + assert.Equal(t, result, "5.6.7.8") + + result, err = driver.parseIPForMACFromIPAddr(ipAddrOutput, "000000000000") + assert.Empty(t, result) + assert.Equal(t, err, errors.New("Could not find matching IP for MAC address 000000000000")) +} + +func TestGetIPErrors(t *testing.T) { + var tests = []struct { + stdOut string + err error + finalErr error + }{ + {`VMState="poweroff"`, nil, errors.New("Host is not running")}, + {"", errors.New("Unable to get state"), errors.New("Unable to get state")}, + } + + for _, expected := range tests { + driver := newTestDriver("default") + driver.VBoxManager = &VBoxManagerMock{ + args: "showvminfo default --machinereadable", + stdOut: expected.stdOut, + err: expected.err, + } + + ip, err := driver.GetIP() + + assert.Empty(t, ip) + assert.Equal(t, err, expected.finalErr) + + url, err := driver.GetURL() + + assert.Empty(t, url) + assert.Equal(t, err, expected.finalErr) + } +} + +func TestParseValidCIDR(t *testing.T) { + ip, network, err := parseAndValidateCIDR("192.168.100.1/24") + + assert.Equal(t, "192.168.100.1", ip.String()) + assert.Equal(t, "192.168.100.0", network.IP.String()) + assert.Equal(t, "ffffff00", network.Mask.String()) + assert.NoError(t, err) +} + +func TestInvalidCIDR(t *testing.T) { + ip, network, err := parseAndValidateCIDR("192.168.100.1") + + assert.EqualError(t, err, "invalid CIDR address: 192.168.100.1") + assert.Nil(t, ip) + assert.Nil(t, network) +} + +func TestInvalidNetworkIpCIDR(t *testing.T) { + ip, network, err := parseAndValidateCIDR("192.168.100.0/24") + + assert.Equal(t, ErrNetworkAddrCidr, err) + assert.Nil(t, ip) + assert.Nil(t, network) +} + +// Tests detection of a conflict between an existing vbox host-only network and a host network interface. This +// scenario would happen if the docker-machine was created with the host on one network, and then the host gets +// moved to another network (e.g. different wifi routers) +func TestCIDRHostIFaceCollisionExisting(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: stdOutTwoHostOnlyNetwork, + } + mhi := newMockHostInterfaces() + _, err := mhi.addMockIface("192.168.99.42", 24, net.IPv4len, "en0", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + + nets, err := listHostOnlyAdapters(vbox) + assert.NoError(t, err) + m, listErr := listHostInterfaces(mhi, nets) + assert.Nil(t, listErr) + assert.NotEmpty(t, m) + + _, network, cidrErr := net.ParseCIDR("192.168.99.1/24") + assert.Nil(t, cidrErr) + err = validateNoIPCollisions(mhi, network, nets) + assert.Equal(t, ErrNetworkAddrCollision, err) +} + +// Tests operation of validateNoIPCollisions when no conflicts exist. +func TestCIDRHostIFaceNoCollision(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: stdOutTwoHostOnlyNetwork, + } + mhi := newMockHostInterfaces() + _, err := mhi.addMockIface("10.10.0.22", 24, net.IPv4len, "en0", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + + nets, err := listHostOnlyAdapters(vbox) + assert.NoError(t, err) + m, listErr := listHostInterfaces(mhi, nets) + assert.Nil(t, listErr) + assert.NotEmpty(t, m) + + _, network, cidrErr := net.ParseCIDR("192.168.99.1/24") + assert.Nil(t, cidrErr) + err = validateNoIPCollisions(mhi, network, nets) + assert.NoError(t, err) +} + +// Tests detection of a conflict between a potential vbox host-only network and a host network interface. +func TestCIDRHostIFaceCollision(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: "", + } + mhi := newMockHostInterfaces() + _, err := mhi.addMockIface("192.168.99.42", 24, net.IPv4len, "en0", net.FlagUp|net.FlagBroadcast) + assert.NoError(t, err) + + nets, err := listHostOnlyAdapters(vbox) + assert.NoError(t, err) + m, listErr := listHostInterfaces(mhi, nets) + assert.Nil(t, listErr) + assert.NotEmpty(t, m) + + _, network, cidrErr := net.ParseCIDR("192.168.99.1/24") + assert.Nil(t, cidrErr) + err = validateNoIPCollisions(mhi, network, nets) + assert.Equal(t, ErrNetworkAddrCollision, err) +} + +// Tests the behavior of getDHCPAddressRange with a variety of subnets. +func TestGetDHCPAddressRange(t *testing.T) { + tests := []struct { + name string + dhcpAddrCIDR string + expectedLowerIP net.IP + expectedUpperIP net.IP + }{ + { + "Test /8 CIDR", + "10.0.0.14/8", + net.ParseIP("10.0.0.100"), + net.ParseIP("10.0.0.254"), + }, + { + "Test /24 CIDR", + "192.168.99.7/24", + net.ParseIP("192.168.99.100"), + net.ParseIP("192.168.99.254"), + }, + { + "Test /25 CIDR", + "100.121.20.19/25", + net.ParseIP("100.121.20.20"), + net.ParseIP("100.121.20.126"), + }, + { + "Test /28 CIDR", + "100.121.10.8/28", + net.ParseIP("100.121.10.9"), + net.ParseIP("100.121.10.14"), + }, + } + + getTestArgsFromCIDR := func(cidr string) (dhcpAddr net.IP, network *net.IPNet) { + var err error + dhcpAddr, network, err = net.ParseCIDR(cidr) + assert.NoError(t, err, "Invalid CIDR %s", cidr) + return + } + + for _, tt := range tests { + dhcpAddr, network := getTestArgsFromCIDR(tt.dhcpAddrCIDR) + t.Run(tt.name, func(t *testing.T) { + lowerIP, upperIP := getDHCPAddressRange(dhcpAddr, network) + if !reflect.DeepEqual(lowerIP, tt.expectedLowerIP) { + t.Errorf("getDHCPAddressRange() lowerIP = %v, want %v", lowerIP, tt.expectedLowerIP) + } + if !reflect.DeepEqual(upperIP, tt.expectedUpperIP) { + t.Errorf("getDHCPAddressRange() upperIP = %v, want %v", upperIP, tt.expectedUpperIP) + } + }) + } +} + +func TestSetConfigFromFlags(t *testing.T) { + driver := newTestDriver("default") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{}, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} + +type MockCreateOperations struct { + test *testing.T + expectedCalls []Call + call int +} + +type Call struct { + signature string + output string + err error +} + +func (v *MockCreateOperations) vbm(args ...string) error { + _, _, err := v.vbmOutErr(args...) + return err +} + +func (v *MockCreateOperations) vbmOut(args ...string) (string, error) { + stdout, _, err := v.vbmOutErr(args...) + return stdout, err +} + +func (v *MockCreateOperations) vbmOutErr(args ...string) (string, string, error) { + output, err := v.doCall("vbm " + strings.Join(args, " ")) + return output, "", err +} + +func (v *MockCreateOperations) UpdateISOCache(storePath, isoURL string) error { + _, err := v.doCall("UpdateISOCache " + storePath + " " + isoURL) + return err +} + +func (v *MockCreateOperations) CopyIsoToMachineDir(storePath, machineName, isoURL string) error { + _, err := v.doCall("CopyIsoToMachineDir " + storePath + " " + machineName + " " + isoURL) + return err +} + +func (v *MockCreateOperations) Generate(path string) error { + _, err := v.doCall("Generate " + path) + return err +} + +func (v *MockCreateOperations) Create(size int, publicSSHKeyPath, diskPath string) error { + _, err := v.doCall("Create " + fmt.Sprintf("%d %s %s", size, publicSSHKeyPath, diskPath)) + return err +} + +func (v *MockCreateOperations) Read(path string) ([]string, error) { + _, err := v.doCall("Read " + path) + return []string{}, err +} + +func (v *MockCreateOperations) Wait(d *Driver) error { + _, err := v.doCall("WaitIP") + return err +} + +func (v *MockCreateOperations) RandomInt(n int) int { + return 5 +} + +func (v *MockCreateOperations) Sleep(d time.Duration) { + v.doCall("Sleep " + fmt.Sprintf("%v", d)) +} + +func (v *MockCreateOperations) Interfaces() ([]net.Interface, error) { + _, err := v.doCall("Interfaces") + return []net.Interface{}, err +} + +func (v *MockCreateOperations) Addrs(iface *net.Interface) ([]net.Addr, error) { + _, err := v.doCall("Addrs " + fmt.Sprintf("%v", iface)) + return []net.Addr{}, err +} + +func (v *MockCreateOperations) expectCall(callSignature, output string, err error) { + v.expectedCalls = append(v.expectedCalls, Call{ + signature: callSignature, + output: output, + err: err, + }) +} + +func (v *MockCreateOperations) doCall(callSignature string) (string, error) { + if v.call >= len(v.expectedCalls) { + v.test.Fatal("Unexpected call", callSignature) + + } + + call := v.expectedCalls[v.call] + if call.signature != "IGNORE CALL" && (callSignature != call.signature) { + v.test.Fatal("Unexpected call", callSignature) + } + + v.call++ + + return call.output, call.err +} + +func mockCalls(t *testing.T, driver *Driver, expectedCalls []Call) { + mockOperations := &MockCreateOperations{ + test: t, + expectedCalls: expectedCalls, + } + + driver.Boot2DockerURL = "http://b2d.org" + driver.VBoxManager = mockOperations + driver.b2dUpdater = mockOperations + driver.sshKeyGenerator = mockOperations + driver.diskCreator = mockOperations + driver.logsReader = mockOperations + driver.ipWaiter = mockOperations + driver.randomInter = mockOperations + driver.sleeper = mockOperations + driver.HostInterfaces = mockOperations +} + +func TestCreateVM(t *testing.T) { + shareName, shareDir := getShareDriveAndName() + + modifyVMcommand := "vbm modifyvm default --firmware bios --bioslogofadein off --bioslogofadeout off --bioslogodisplaytime 0 --biosbootmenu disabled --ostype Linux26_64 --cpus 1 --memory 1024 --acpi on --ioapic on --rtcuseutc on --natdnshostresolver1 off --natdnsproxy1 on --cpuhotplug off --pae on --hpet on --hwvirtex on --nestedpaging on --largepages on --vtxvpid on --accelerate3d off --boot1 dvd" + if runtime.GOOS == "windows" && runtime.GOARCH == "386" { + modifyVMcommand += " --longmode on" + } + + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"CopyIsoToMachineDir path default http://b2d.org", "", nil}, + {"Generate path/machines/default/id_rsa", "", nil}, + {"Create 20000 path/machines/default/id_rsa.pub path/machines/default/disk.vmdk", "", nil}, + {"vbm createvm --basefolder path/machines/default --name default --register", "", nil}, + {modifyVMcommand, "", nil}, + {"vbm modifyvm default --nic1 nat --nictype1 82540EM --cableconnected1 on", "", nil}, + {"vbm storagectl default --name SATA --add sata --hostiocache on", "", nil}, + {"vbm storageattach default --storagectl SATA --port 0 --device 0 --type dvddrive --medium path/machines/default/boot2docker.iso", "", nil}, + {"vbm storageattach default --storagectl SATA --port 1 --device 0 --type hdd --medium path/machines/default/disk.vmdk", "", nil}, + {"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountPrefix /", "", nil}, + {"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountDir /", "", nil}, + {"vbm sharedfolder add default --name " + shareName + " --hostpath " + shareDir + " --automount", "", nil}, + {"vbm setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/" + shareName + " 1", "", nil}, + }) + + err := driver.CreateVM() + + assert.NoError(t, err) +} + +func TestCreateVMWithSpecificNatNicType(t *testing.T) { + shareName, shareDir := getShareDriveAndName() + + modifyVMcommand := "vbm modifyvm default --firmware bios --bioslogofadein off --bioslogofadeout off --bioslogodisplaytime 0 --biosbootmenu disabled --ostype Linux26_64 --cpus 1 --memory 1024 --acpi on --ioapic on --rtcuseutc on --natdnshostresolver1 off --natdnsproxy1 on --cpuhotplug off --pae on --hpet on --hwvirtex on --nestedpaging on --largepages on --vtxvpid on --accelerate3d off --boot1 dvd" + if runtime.GOOS == "windows" && runtime.GOARCH == "386" { + modifyVMcommand += " --longmode on" + } + + driver := NewDriver("default", "path") + driver.NatNicType = "Am79C973" + mockCalls(t, driver, []Call{ + {"CopyIsoToMachineDir path default http://b2d.org", "", nil}, + {"Generate path/machines/default/id_rsa", "", nil}, + {"Create 20000 path/machines/default/id_rsa.pub path/machines/default/disk.vmdk", "", nil}, + {"vbm createvm --basefolder path/machines/default --name default --register", "", nil}, + {modifyVMcommand, "", nil}, + {"vbm modifyvm default --nic1 nat --nictype1 Am79C973 --cableconnected1 on", "", nil}, + {"vbm storagectl default --name SATA --add sata --hostiocache on", "", nil}, + {"vbm storageattach default --storagectl SATA --port 0 --device 0 --type dvddrive --medium path/machines/default/boot2docker.iso", "", nil}, + {"vbm storageattach default --storagectl SATA --port 1 --device 0 --type hdd --medium path/machines/default/disk.vmdk", "", nil}, + {"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountPrefix /", "", nil}, + {"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountDir /", "", nil}, + {"vbm sharedfolder add default --name " + shareName + " --hostpath " + shareDir + " --automount", "", nil}, + {"vbm setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/" + shareName + " 1", "", nil}, + }) + + err := driver.CreateVM() + + assert.NoError(t, err) +} + +func TestStart(t *testing.T) { + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil}, + {"vbm list hostonlyifs", "", nil}, + {"Interfaces", "", nil}, + {"vbm hostonlyif create", "Interface 'VirtualBox Host-Only Ethernet Adapter' was successfully created", nil}, + {"vbm list hostonlyifs", ` +Name: VirtualBox Host-Only Ethernet Adapter +GUID: 786f6276-656e-4074-8000-0a0027000000 +DHCP: Disabled +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:00 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil}, + {"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil}, + {"vbm list dhcpservers", "", nil}, + {"vbm list dhcpservers", "", nil}, + {"vbm dhcpserver add --netname HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.6 --netmask 255.255.255.0 --lowerip 192.168.99.100 --upperip 192.168.99.254 --enable", "", nil}, + {"vbm modifyvm default --nic2 hostonly --nictype2 82540EM --nicpromisc2 deny --hostonlyadapter2 VirtualBox Host-Only Ethernet Adapter --cableconnected2 on", "", nil}, + {"IGNORE CALL", "", nil}, + {"IGNORE CALL", "", nil}, + {"vbm startvm default --type headless", "", nil}, + {"Read path/machines/default/default/Logs/VBox.log", "", nil}, + {"WaitIP", "", nil}, + {"vbm list hostonlyifs", ` +Name: VirtualBox Host-Only Ethernet Adapter +GUID: 786f6276-656e-4074-8000-0a0027000000 +DHCP: Disabled +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:00 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil}, + {"Interfaces", "", nil}, + }) + + err := driver.Start() + + assert.NoError(t, err) +} + +func TestStartWithHostOnlyAdapterCreationBug(t *testing.T) { + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil}, + {"vbm list hostonlyifs", "", nil}, + {"Interfaces", "", nil}, + {"vbm hostonlyif create", "", errors.New("error: Failed to create the host-only adapter")}, + {"vbm list hostonlyifs", "", nil}, + {"vbm list hostonlyifs", ` +Name: VirtualBox Host-Only Ethernet Adapter +GUID: 786f6276-656e-4074-8000-0a0027000000 +DHCP: Disabled +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:00 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil}, + {"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil}, + {"vbm list dhcpservers", "", nil}, + {"vbm list dhcpservers", "", nil}, + {"vbm dhcpserver add --netname HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.6 --netmask 255.255.255.0 --lowerip 192.168.99.100 --upperip 192.168.99.254 --enable", "", nil}, + {"vbm modifyvm default --nic2 hostonly --nictype2 82540EM --nicpromisc2 deny --hostonlyadapter2 VirtualBox Host-Only Ethernet Adapter --cableconnected2 on", "", nil}, + {"IGNORE CALL", "", nil}, + {"IGNORE CALL", "", nil}, + {"vbm startvm default --type headless", "", nil}, + {"Read path/machines/default/default/Logs/VBox.log", "", nil}, + {"WaitIP", "", nil}, + {"vbm list hostonlyifs", ` +Name: VirtualBox Host-Only Ethernet Adapter +GUID: 786f6276-656e-4074-8000-0a0027000000 +DHCP: Disabled +IPAddress: 192.168.99.100 +NetworkMask: 255.255.255.0 +IPV6Address: +IPV6NetworkMaskPrefixLength: 0 +HardwareAddress: 0a:00:27:00:00:00 +MediumType: Ethernet +Status: Up +VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil}, + {"Interfaces", "", nil}, + {"vbm showvminfo default --machinereadable", `VMState="running"`, nil}, + {"vbm controlvm default acpipowerbutton", "", nil}, + {"vbm showvminfo default --machinereadable", `VMState="stopped"`, nil}, + {"Sleep 5s", "", nil}, + {"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil}, + {"Sleep 5s", "", nil}, + {"vbm startvm default --type headless", "", nil}, + {"WaitIP", "", nil}, + }) + + err := driver.Start() + + assert.NoError(t, err) +} + +func TestRemoveStopped(t *testing.T) { + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil}, + {"vbm unregistervm --delete default", "", nil}, + }) + + err := driver.Remove() + + assert.NoError(t, err) +} + +func TestRemoveStarted(t *testing.T) { + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"vbm showvminfo default --machinereadable", `VMState="running"`, nil}, + {"vbm controlvm default poweroff", "", nil}, + {"vbm unregistervm --delete default", "", nil}, + }) + + err := driver.Remove() + + assert.NoError(t, err) +} + +func TestRemoveSaved(t *testing.T) { + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"vbm showvminfo default --machinereadable", `VMState="saved"`, nil}, + {"vbm unregistervm --delete default", "", nil}, + }) + + err := driver.Remove() + + assert.NoError(t, err) +} + +func TestRemovePaused(t *testing.T) { + driver := NewDriver("default", "path") + mockCalls(t, driver, []Call{ + {"vbm showvminfo default --machinereadable", `VMState="running"`, nil}, + {"vbm controlvm default poweroff", "", nil}, + {"vbm unregistervm --delete default", "", nil}, + }) + + err := driver.Remove() + + assert.NoError(t, err) +} diff --git a/drivers/virtualbox/virtualbox_windows.go b/drivers/virtualbox/virtualbox_windows.go new file mode 100644 index 0000000000..ff3fe986ab --- /dev/null +++ b/drivers/virtualbox/virtualbox_windows.go @@ -0,0 +1,105 @@ +package virtualbox + +import ( + "strings" + + "fmt" + "os" + "os/exec" + "path/filepath" + + "github.com/docker/machine/libmachine/log" + "golang.org/x/sys/windows/registry" +) + +// cmdOutput runs a shell command and returns its output. +func cmdOutput(name string, args ...string) (string, error) { + cmd := exec.Command(name, args...) + log.Debugf("COMMAND: %v %v", name, strings.Join(args, " ")) + + stdout, err := cmd.Output() + if err != nil { + return "", err + } + + log.Debugf("STDOUT:\n{\n%v}", string(stdout)) + + return string(stdout), nil +} + +func detectVBoxManageCmd() string { + cmd := "VBoxManage" + if p := os.Getenv("VBOX_INSTALL_PATH"); p != "" { + if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { + return path + } + } + + if p := os.Getenv("VBOX_MSI_INSTALL_PATH"); p != "" { + if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { + return path + } + } + + // Look in default installation path for VirtualBox version > 5 + if path, err := exec.LookPath(filepath.Join("C:\\Program Files\\Oracle\\VirtualBox", cmd)); err == nil { + return path + } + + // Look in windows registry + if p, err := findVBoxInstallDirInRegistry(); err == nil { + if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { + return path + } + } + + return detectVBoxManageCmdInPath() //fallback to path +} + +func findVBoxInstallDirInRegistry() (string, error) { + registryKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Oracle\VirtualBox`, registry.QUERY_VALUE) + if err != nil { + errorMessage := fmt.Sprintf("Can't find VirtualBox registry entries, is VirtualBox really installed properly? %s", err) + log.Debugf(errorMessage) + return "", fmt.Errorf(errorMessage) + } + + defer registryKey.Close() + + installDir, _, err := registryKey.GetStringValue("InstallDir") + if err != nil { + errorMessage := fmt.Sprintf("Can't find InstallDir registry key within VirtualBox registries entries, is VirtualBox really installed properly? %s", err) + log.Debugf(errorMessage) + return "", fmt.Errorf(errorMessage) + } + + return installDir, nil +} + +func getShareDriveAndName() (string, string) { + return "c/Users", "\\\\?\\c:\\Users" +} + +func isHyperVInstalled() bool { + // check if hyper-v is installed + _, err := exec.LookPath("vmms.exe") + if err != nil { + errmsg := "Hyper-V is not installed." + log.Debugf(errmsg, err) + return false + } + + // check to see if a hypervisor is present. if hyper-v is installed and enabled, + // display an error explaining the incompatibility between virtualbox and hyper-v. + output, err := cmdOutput("wmic", "computersystem", "get", "hypervisorpresent") + + if err != nil { + errmsg := "Could not check to see if Hyper-V is running." + log.Debugf(errmsg, err) + return false + } + + enabled := strings.Contains(output, "TRUE") + return enabled + +} diff --git a/drivers/virtualbox/vm.go b/drivers/virtualbox/vm.go new file mode 100644 index 0000000000..cd95ada767 --- /dev/null +++ b/drivers/virtualbox/vm.go @@ -0,0 +1,41 @@ +package virtualbox + +import "strconv" + +type VM struct { + CPUs int + Memory int +} + +func getVMInfo(name string, vbox VBoxManager) (*VM, error) { + out, err := vbox.vbmOut("showvminfo", name, "--machinereadable") + if err != nil { + return nil, err + } + + vm := &VM{} + + err = parseKeyValues(out, reEqualLine, func(key, val string) error { + switch key { + case "cpus": + v, err := strconv.Atoi(val) + if err != nil { + return err + } + vm.CPUs = v + case "memory": + v, err := strconv.Atoi(val) + if err != nil { + return err + } + vm.Memory = v + } + + return nil + }) + if err != nil { + return nil, err + } + + return vm, nil +} diff --git a/drivers/virtualbox/vm_test.go b/drivers/virtualbox/vm_test.go new file mode 100644 index 0000000000..a90ffbf1dd --- /dev/null +++ b/drivers/virtualbox/vm_test.go @@ -0,0 +1,44 @@ +package virtualbox + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +var stdOutVMInfo = ` +storagecontrollerbootable0="on" +memory=1024 +cpus=2 +"SATA-0-0"="/home/ehazlett/.boot2docker/boot2docker.iso" +"SATA-IsEjected"="off" +"SATA-1-0"="/home/ehazlett/vm/test/disk.vmdk" +"SATA-ImageUUID-1-0"="12345-abcdefg" +"SATA-2-0"="none" +nic1="nat"` + +func TestVMInfo(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "showvminfo host --machinereadable", + stdOut: stdOutVMInfo, + } + + vm, err := getVMInfo("host", vbox) + + assert.Equal(t, 2, vm.CPUs) + assert.Equal(t, 1024, vm.Memory) + assert.NoError(t, err) +} + +func TestVMInfoError(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "showvminfo host --machinereadable", + err: errors.New("BUG"), + } + + vm, err := getVMInfo("host", vbox) + + assert.Nil(t, vm) + assert.EqualError(t, err, "BUG") +} diff --git a/drivers/virtualbox/vtx.go b/drivers/virtualbox/vtx.go new file mode 100644 index 0000000000..7adb631fe9 --- /dev/null +++ b/drivers/virtualbox/vtx.go @@ -0,0 +1,28 @@ +package virtualbox + +import "strings" + +// IsVTXDisabledInTheVM checks if VT-X is disabled in the started vm. +func (d *Driver) IsVTXDisabledInTheVM() (bool, error) { + lines, err := d.readVBoxLog() + if err != nil { + return true, err + } + + for _, line := range lines { + if strings.Contains(line, "VT-x is disabled") && !strings.Contains(line, "Falling back to raw-mode: VT-x is disabled in the BIOS for all CPU modes") { + return true, nil + } + if strings.Contains(line, "the host CPU does NOT support HW virtualization") { + return true, nil + } + if strings.Contains(line, "VERR_VMX_UNABLE_TO_START_VM") { + return true, nil + } + if strings.Contains(line, "Power up failed") && strings.Contains(line, "VERR_VMX_NO_VMX") { + return true, nil + } + } + + return false, nil +} diff --git a/drivers/virtualbox/vtx_intel.go b/drivers/virtualbox/vtx_intel.go new file mode 100644 index 0000000000..852f451d13 --- /dev/null +++ b/drivers/virtualbox/vtx_intel.go @@ -0,0 +1,14 @@ +// +build 386 amd64 + +package virtualbox + +import "github.com/intel-go/cpuid" + +// IsVTXDisabled checks if VT-x is disabled in the CPU. +func (d *Driver) IsVTXDisabled() bool { + if cpuid.HasFeature(cpuid.VMX) || cpuid.HasExtraFeature(cpuid.SVM) { + return false + } + + return true +} diff --git a/drivers/virtualbox/vtx_other.go b/drivers/virtualbox/vtx_other.go new file mode 100644 index 0000000000..5dbfd17553 --- /dev/null +++ b/drivers/virtualbox/vtx_other.go @@ -0,0 +1,8 @@ +// +build !386,!amd64 + +package virtualbox + +// IsVTXDisabled checks if VT-x is disabled in the CPU. +func (d *Driver) IsVTXDisabled() bool { + return true +} diff --git a/drivers/virtualbox/vtx_test.go b/drivers/virtualbox/vtx_test.go new file mode 100644 index 0000000000..da90b15ab5 --- /dev/null +++ b/drivers/virtualbox/vtx_test.go @@ -0,0 +1,72 @@ +package virtualbox + +import ( + "testing" + + "errors" + + "github.com/stretchr/testify/assert" +) + +type MockLogsReader struct { + content []string + err error +} + +func (r *MockLogsReader) Read(path string) ([]string, error) { + return r.content, r.err +} + +func TestIsVTXEnabledInTheVM(t *testing.T) { + driver := NewDriver("default", "path") + + var tests = []struct { + description string + content []string + err error + }{ + {"Empty log", []string{}, nil}, + {"Raw mode", []string{"Falling back to raw-mode: VT-x is disabled in the BIOS for all CPU modes"}, nil}, + {"Raw mode", []string{"HM: HMR3Init: Falling back to raw-mode: VT-x is not available"}, nil}, + } + + for _, test := range tests { + driver.logsReader = &MockLogsReader{ + content: test.content, + err: test.err, + } + + disabled, err := driver.IsVTXDisabledInTheVM() + + assert.False(t, disabled, test.description) + assert.Equal(t, test.err, err) + } +} + +func TestIsVTXDisabledInTheVM(t *testing.T) { + driver := NewDriver("default", "path") + + var tests = []struct { + description string + content []string + err error + }{ + {"VT-x Disabled", []string{"VT-x is disabled"}, nil}, + {"No HW virtualization", []string{"the host CPU does NOT support HW virtualization"}, nil}, + {"Unable to start VM", []string{"VERR_VMX_UNABLE_TO_START_VM"}, nil}, + {"Power up failed", []string{"00:00:00.318604 Power up failed (vrc=VERR_VMX_NO_VMX, rc=NS_ERROR_FAILURE (0X80004005))"}, nil}, + {"Unable to read log", nil, errors.New("Unable to read log")}, + } + + for _, test := range tests { + driver.logsReader = &MockLogsReader{ + content: test.content, + err: test.err, + } + + disabled, err := driver.IsVTXDisabledInTheVM() + + assert.True(t, disabled, test.description) + assert.Equal(t, test.err, err) + } +} diff --git a/drivers/vmwarefusion/fusion.go b/drivers/vmwarefusion/fusion.go index 391b3aeeb5..be433e5fe7 100644 --- a/drivers/vmwarefusion/fusion.go +++ b/drivers/vmwarefusion/fusion.go @@ -1,487 +1,9 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ +// +build !darwin package vmwarefusion -import ( - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "os/exec" - "path" - "path/filepath" - "regexp" - "strings" - "text/template" - "time" +import "github.com/docker/machine/libmachine/drivers" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" - "github.com/docker/machine/utils" - cssh "golang.org/x/crypto/ssh" -) - -const ( - B2D_USER = "docker" - B2D_PASS = "tcuser" - dockerConfigDir = "/var/lib/boot2docker" -) - -// Driver for VMware Fusion -type Driver struct { - MachineName string - IPAddress string - Memory int - DiskSize int - ISO string - Boot2DockerURL string - CaCertPath string - PrivateKeyPath string - - storePath string -} - -type CreateFlags struct { - Boot2DockerURL *string - Memory *int - DiskSize *int -} - -func init() { - drivers.Register("vmwarefusion", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} - -// GetCreateFlags registers the flags this driver adds to -// "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ - EnvVar: "FUSION_BOOT2DOCKER_URL", - Name: "vmwarefusion-boot2docker-url", - Usage: "Fusion URL for boot2docker image", - }, - cli.IntFlag{ - EnvVar: "FUSION_MEMORY_SIZE", - Name: "vmwarefusion-memory-size", - Usage: "Fusion size of memory for host VM (in MB)", - Value: 1024, - }, - cli.IntFlag{ - EnvVar: "FUSION_DISK_SIZE", - Name: "vmwarefusion-disk-size", - Usage: "Fusion size of disk for host VM (in MB)", - Value: 20000, - }, - } -} - -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil -} - -func (d *Driver) DriverName() string { - return "vmwarefusion" -} - -func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - d.Memory = flags.Int("vmwarefusion-memory-size") - d.DiskSize = flags.Int("vmwarefusion-disk-size") - d.Boot2DockerURL = flags.String("vmwarefusion-boot2docker-url") - d.ISO = path.Join(d.storePath, "boot2docker.iso") - - return nil -} - -func (d *Driver) GetURL() (string, error) { - ip, err := d.GetIP() - if err != nil { - return "", err - } - if ip == "" { - return "", nil - } - return fmt.Sprintf("tcp://%s:2376", ip), nil -} - -func (d *Driver) GetIP() (string, error) { - ip, err := d.getIPfromDHCPLease() - if err != nil { - return "", err - } - - return ip, nil -} - -func (d *Driver) GetState() (state.State, error) { - // VMRUN only tells use if the vm is running or not - if stdout, _, _ := vmrun("list"); strings.Contains(stdout, d.vmxPath()) { - return state.Running, nil - } - return state.Stopped, nil -} - -func (d *Driver) PreCreateCheck() error { - return nil -} - -func (d *Driver) Create() error { - - var ( - isoURL string - err error - ) - - if d.Boot2DockerURL != "" { - isoURL = d.Boot2DockerURL - log.Infof("Downloading boot2docker.iso from %s...", isoURL) - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { - return err - } - } else { - // todo: check latest release URL, download if it's new - // until then always use "latest" - isoURL, err = utils.GetLatestBoot2DockerReleaseURL() - if err != nil { - return err - } - - // todo: use real constant for .docker - rootPath := filepath.Join(utils.GetHomeDir(), ".docker") - imgPath := filepath.Join(rootPath, "images") - commonIsoPath := filepath.Join(imgPath, "boot2docker.iso") - if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) { - log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath) - - // just in case boot2docker.iso has been manually deleted - if _, err := os.Stat(imgPath); os.IsNotExist(err) { - if err := os.Mkdir(imgPath, 0700); err != nil { - return err - } - } - - if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { - return err - } - } - - isoDest := filepath.Join(d.storePath, "boot2docker.iso") - if err := utils.CopyFile(commonIsoPath, isoDest); err != nil { - return err - } - } - - log.Infof("Creating SSH key...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { - return err - } - - log.Infof("Creating VM...") - if err := os.MkdirAll(d.storePath, 0755); err != nil { - return err - } - - if _, err := os.Stat(d.vmxPath()); err == nil { - return ErrMachineExist - } - - // Generate vmx config file from template - vmxt := template.Must(template.New("vmx").Parse(vmx)) - vmxfile, err := os.Create(d.vmxPath()) - if err != nil { - return err - } - vmxt.Execute(vmxfile, d) - - // Generate vmdk file - diskImg := filepath.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.MachineName)) - if _, err := os.Stat(diskImg); err != nil { - if !os.IsNotExist(err) { - return err - } - - if err := vdiskmanager(diskImg, d.DiskSize); err != nil { - return err - } - } - - if err := d.Start(); err != nil { - return err - } - - var ip string - - log.Infof("Waiting for VM to come online...") - for i := 1; i <= 60; i++ { - ip, err = d.getIPfromDHCPLease() - if err != nil { - log.Debugf("Not there yet %d/%d, error: %s", i, 60, err) - time.Sleep(2 * time.Second) - continue - } - - if ip != "" { - log.Debugf("Got an ip: %s", ip) - break - } - } - - if ip == "" { - return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting") - } - - d.IPAddress = ip - - key, err := ioutil.ReadFile(d.publicSSHKeyPath()) - if err != nil { - return err - } - - // so, vmrun above will not work without vmtools in b2d. since getting stuff into TCL - // is much more painful, we simply use the b2d password to get the initial public key - // onto the machine. from then on we use the pub key. meh. - sshConfig := &cssh.ClientConfig{ - User: B2D_USER, - Auth: []cssh.AuthMethod{ - cssh.Password(B2D_PASS), - }, - } - sshClient, err := cssh.Dial("tcp", fmt.Sprintf("%s:22", ip), sshConfig) - if err != nil { - return err - } - session, err := sshClient.NewSession() - if err != nil { - return err - } - if err := session.Run(fmt.Sprintf("mkdir /home/docker/.ssh && echo \"%s\" > /home/docker/.ssh/authorized_keys", string(key))); err != nil { - return err - } - session.Close() - - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) Start() error { - vmrun("start", d.vmxPath(), "nogui") - return nil -} - -func (d *Driver) Stop() error { - vmrun("stop", d.vmxPath(), "nogui") - return nil -} - -func (d *Driver) Remove() error { - - s, _ := d.GetState() - if s == state.Running { - if err := d.Kill(); err != nil { - return fmt.Errorf("Error stopping VM before deletion") - } - } - - vmrun("deleteVM", d.vmxPath(), "nogui") - return nil -} - -func (d *Driver) Restart() error { - vmrun("reset", d.vmxPath(), "nogui") - return nil -} - -func (d *Driver) Kill() error { - vmrun("stop", d.vmxPath(), "nogui") - return nil -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) Upgrade() error { - return nil -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() - if err != nil { - return nil, err - } - return ssh.GetSSHCommand(ip, 22, "docker", d.sshKeyPath(), args...), nil -} - -func (d *Driver) vmxPath() string { - return path.Join(d.storePath, fmt.Sprintf("%s.vmx", d.MachineName)) -} - -func (d *Driver) vmdkPath() string { - return path.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.MachineName)) -} - -// Download boot2docker ISO image for the given tag and save it at dest. -func downloadISO(dir, file, url string) error { - rsp, err := http.Get(url) - if err != nil { - return err - } - defer rsp.Body.Close() - - // Download to a temp file first then rename it to avoid partial download. - f, err := ioutil.TempFile(dir, file+".tmp") - if err != nil { - return err - } - defer os.Remove(f.Name()) - if _, err := io.Copy(f, rsp.Body); err != nil { - // TODO: display download progress? - return err - } - if err := f.Close(); err != nil { - return err - } - if err := os.Rename(f.Name(), path.Join(dir, file)); err != nil { - return err - } - return nil -} - -func (d *Driver) getIPfromDHCPLease() (string, error) { - var vmxfh *os.File - var dhcpfh *os.File - var vmxcontent []byte - var dhcpcontent []byte - var macaddr string - var err error - var lastipmatch string - var currentip string - var lastleaseendtime time.Time - var currentleadeendtime time.Time - - // DHCP lease table for NAT vmnet interface - var dhcpfile = "/var/db/vmware/vmnet-dhcpd-vmnet8.leases" - - if vmxfh, err = os.Open(d.vmxPath()); err != nil { - return "", err - } - defer vmxfh.Close() - - if vmxcontent, err = ioutil.ReadAll(vmxfh); err != nil { - return "", err - } - - // Look for generatedAddress as we're passing a VMX with addressType = "generated". - vmxparse := regexp.MustCompile(`^ethernet0.generatedAddress\s*=\s*"(.*?)"\s*$`) - for _, line := range strings.Split(string(vmxcontent), "\n") { - if matches := vmxparse.FindStringSubmatch(line); matches == nil { - continue - } else { - macaddr = strings.ToLower(matches[1]) - } - } - - if macaddr == "" { - return "", fmt.Errorf("couldn't find MAC address in VMX file %s", d.vmxPath()) - } - - log.Debugf("MAC address in VMX: %s", macaddr) - if dhcpfh, err = os.Open(dhcpfile); err != nil { - return "", err - } - defer dhcpfh.Close() - - if dhcpcontent, err = ioutil.ReadAll(dhcpfh); err != nil { - return "", err - } - - // Get the IP from the lease table. - leaseip := regexp.MustCompile(`^lease (.+?) {$`) - // Get the lease end date time. - leaseend := regexp.MustCompile(`^\s*ends \d (.+?);$`) - // Get the MAC address associated. - leasemac := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) - - for _, line := range strings.Split(string(dhcpcontent), "\n") { - - if matches := leaseip.FindStringSubmatch(line); matches != nil { - lastipmatch = matches[1] - continue - } - - if matches := leaseend.FindStringSubmatch(line); matches != nil { - lastleaseendtime, _ = time.Parse("2006/01/02 15:04:05", matches[1]) - continue - } - - if matches := leasemac.FindStringSubmatch(line); matches != nil && matches[1] == macaddr && currentleadeendtime.Before(lastleaseendtime) { - currentip = lastipmatch - currentleadeendtime = lastleaseendtime - } - } - - if currentip == "" { - return "", fmt.Errorf("IP not found for MAC %s in DHCP leases", macaddr) - } - - log.Debugf("IP found in DHCP lease table: %s", currentip) - return currentip, nil - -} - -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") -} - -func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" +func NewDriver(hostName, storePath string) drivers.Driver { + return drivers.NewDriverNotSupported("vmwarefusion", hostName, storePath) } diff --git a/drivers/vmwarefusion/fusion_darwin.go b/drivers/vmwarefusion/fusion_darwin.go new file mode 100644 index 0000000000..fb22c96ab5 --- /dev/null +++ b/drivers/vmwarefusion/fusion_darwin.go @@ -0,0 +1,785 @@ +/* + * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. + */ + +package vmwarefusion + +import ( + "archive/tar" + "bytes" + "fmt" + "io/ioutil" + "net" + "os" + "path/filepath" + "regexp" + "runtime" + "strings" + "text/template" + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" + cryptossh "golang.org/x/crypto/ssh" +) + +const ( + B2DUser = "docker" + B2DPass = "tcuser" + isoFilename = "boot2docker.iso" + isoConfigDrive = "configdrive.iso" +) + +// Driver for VMware Fusion +type Driver struct { + *drivers.BaseDriver + Memory int + DiskSize int + CPU int + ISO string + Boot2DockerURL string + + SSHPassword string + ConfigDriveISO string + ConfigDriveURL string + NoShare bool +} + +const ( + defaultSSHUser = B2DUser + defaultSSHPass = B2DPass + defaultDiskSize = 20000 + defaultCPU = 1 + defaultMemory = 1024 +) + +// GetCreateFlags registers the flags this driver adds to +// "docker hosts create" +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ + EnvVar: "FUSION_BOOT2DOCKER_URL", + Name: "vmwarefusion-boot2docker-url", + Usage: "Fusion URL for boot2docker image", + Value: "", + }, + mcnflag.StringFlag{ + EnvVar: "FUSION_CONFIGDRIVE_URL", + Name: "vmwarefusion-configdrive-url", + Usage: "Fusion URL for cloud-init configdrive", + Value: "", + }, + mcnflag.IntFlag{ + EnvVar: "FUSION_CPU_COUNT", + Name: "vmwarefusion-cpu-count", + Usage: "number of CPUs for the machine (-1 to use the number of CPUs available)", + Value: defaultCPU, + }, + mcnflag.IntFlag{ + EnvVar: "FUSION_MEMORY_SIZE", + Name: "vmwarefusion-memory-size", + Usage: "Fusion size of memory for host VM (in MB)", + Value: defaultMemory, + }, + mcnflag.IntFlag{ + EnvVar: "FUSION_DISK_SIZE", + Name: "vmwarefusion-disk-size", + Usage: "Fusion size of disk for host VM (in MB)", + Value: defaultDiskSize, + }, + mcnflag.StringFlag{ + EnvVar: "FUSION_SSH_USER", + Name: "vmwarefusion-ssh-user", + Usage: "SSH user", + Value: defaultSSHUser, + }, + mcnflag.StringFlag{ + EnvVar: "FUSION_SSH_PASSWORD", + Name: "vmwarefusion-ssh-password", + Usage: "SSH password", + Value: defaultSSHPass, + }, + mcnflag.BoolFlag{ + EnvVar: "FUSION_NO_SHARE", + Name: "vmwarefusion-no-share", + Usage: "Disable the mount of your home directory", + }, + } +} + +func NewDriver(hostName, storePath string) drivers.Driver { + return &Driver{ + CPU: defaultCPU, + Memory: defaultMemory, + DiskSize: defaultDiskSize, + SSHPassword: defaultSSHPass, + BaseDriver: &drivers.BaseDriver{ + SSHUser: defaultSSHUser, + MachineName: hostName, + StorePath: storePath, + }, + } +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + + return d.SSHUser +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "vmwarefusion" +} + +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.Memory = flags.Int("vmwarefusion-memory-size") + d.CPU = flags.Int("vmwarefusion-cpu-count") + d.DiskSize = flags.Int("vmwarefusion-disk-size") + d.Boot2DockerURL = flags.String("vmwarefusion-boot2docker-url") + d.ConfigDriveURL = flags.String("vmwarefusion-configdrive-url") + d.ISO = d.ResolveStorePath(isoFilename) + d.ConfigDriveISO = d.ResolveStorePath(isoConfigDrive) + d.SetSwarmConfigFromFlags(flags) + d.SSHUser = flags.String("vmwarefusion-ssh-user") + d.SSHPassword = flags.String("vmwarefusion-ssh-password") + d.SSHPort = 22 + d.NoShare = flags.Bool("vmwarefusion-no-share") + + // We support a maximum of 16 cpu to be consistent with Virtual Hardware 10 + // specs. + if d.CPU < 1 { + d.CPU = int(runtime.NumCPU()) + } + if d.CPU > 16 { + d.CPU = 16 + } + + return nil +} + +func (d *Driver) GetURL() (string, error) { + ip, err := d.GetIP() + if err != nil { + return "", err + } + if ip == "" { + return "", nil + } + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil +} + +func (d *Driver) GetIP() (string, error) { + s, err := d.GetState() + if err != nil { + return "", err + } + if s != state.Running { + return "", drivers.ErrHostIsNotRunning + } + + // determine MAC address for VM + macaddr, err := d.getMacAddressFromVmx() + if err != nil { + return "", err + } + + // attempt to find the address in the vmnet configuration + if ip, err := d.getIPfromVmnetConfiguration(macaddr); err == nil { + return ip, err + } + + // address not found in vmnet so look for a DHCP lease + ip, err := d.getIPfromDHCPLease(macaddr) + if err != nil { + return "", err + } + + return ip, nil +} + +func (d *Driver) GetState() (state.State, error) { + // VMRUN only tells use if the vm is running or not + vmxp, err := filepath.EvalSymlinks(d.vmxPath()) + if err != nil { + return state.Error, err + } + if stdout, _, _ := vmrun("list"); strings.Contains(stdout, vmxp) { + return state.Running, nil + } + return state.Stopped, nil +} + +// PreCreateCheck checks that the machine creation process can be started safely. +func (d *Driver) PreCreateCheck() error { + // Downloading boot2docker to cache should be done here to make sure + // that a download failure will not leave a machine half created. + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + + return b2dutils.UpdateISOCache(d.Boot2DockerURL) +} + +func (d *Driver) Create() error { + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { + return err + } + + // download cloud-init config drive + if d.ConfigDriveURL != "" { + if err := b2dutils.DownloadISO(d.ResolveStorePath("."), isoConfigDrive, d.ConfigDriveURL); err != nil { + return err + } + } + + log.Infof("Creating SSH key...") + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { + return err + } + + log.Infof("Creating VM...") + if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil { + return err + } + + if _, err := os.Stat(d.vmxPath()); err == nil { + return ErrMachineExist + } + + // Generate vmx config file from template + vmxt := template.Must(template.New("vmx").Parse(vmx)) + vmxfile, err := os.Create(d.vmxPath()) + if err != nil { + return err + } + vmxt.Execute(vmxfile, d) + + // Generate vmdk file + diskImg := d.ResolveStorePath(fmt.Sprintf("%s.vmdk", d.MachineName)) + if _, err := os.Stat(diskImg); err != nil { + if !os.IsNotExist(err) { + return err + } + + if err := vdiskmanager(diskImg, d.DiskSize); err != nil { + return err + } + } + + log.Infof("Starting %s...", d.MachineName) + _, _, err = vmrun("start", d.vmxPath(), "nogui") + if err != nil { + return err + } + + var ip string + + log.Infof("Waiting for VM to come online...") + for i := 1; i <= 60; i++ { + ip, err = d.GetIP() + if err != nil { + log.Debugf("Not there yet %d/%d, error: %s", i, 60, err) + time.Sleep(2 * time.Second) + continue + } + + if ip != "" { + log.Debugf("Got an ip: %s", ip) + conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, 22), time.Duration(2*time.Second)) + if err != nil { + log.Debugf("SSH Daemon not responding yet: %s", err) + time.Sleep(2 * time.Second) + continue + } + conn.Close() + break + } + } + + if ip == "" { + return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting") + } + + // we got an IP, let's copy ssh keys over + d.IPAddress = ip + + // Do not execute the rest of boot2docker specific configuration + // The upload of the public ssh key uses a ssh connection, + // this works without installed vmware client tools + if d.ConfigDriveURL != "" { + var keyfh *os.File + var keycontent []byte + + log.Infof("Copy public SSH key to %s [%s]", d.MachineName, d.IPAddress) + + // create .ssh folder in users home + if err := executeSSHCommand(fmt.Sprintf("mkdir -p /home/%s/.ssh", d.SSHUser), d); err != nil { + return err + } + + // read generated public ssh key + if keyfh, err = os.Open(d.publicSSHKeyPath()); err != nil { + return err + } + defer keyfh.Close() + + if keycontent, err = ioutil.ReadAll(keyfh); err != nil { + return err + } + + // add public ssh key to authorized_keys + if err := executeSSHCommand(fmt.Sprintf("echo '%s' > /home/%s/.ssh/authorized_keys", string(keycontent), d.SSHUser), d); err != nil { + return err + } + + // make it secure + if err := executeSSHCommand(fmt.Sprintf("chmod 600 /home/%s/.ssh/authorized_keys", d.SSHUser), d); err != nil { + return err + } + + log.Debugf("Leaving create sequence early, configdrive found") + return nil + } + + // Generate a tar keys bundle + if err := d.generateKeyBundle(); err != nil { + return err + } + + // Test if /var/lib/boot2docker exists + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "directoryExistsInGuest", d.vmxPath(), "/var/lib/boot2docker") + if err != nil { + return err + } + + // Copy SSH keys bundle + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "CopyFileFromHostToGuest", d.vmxPath(), d.ResolveStorePath("userdata.tar"), "/home/docker/userdata.tar") + if err != nil { + return err + } + + // Expand tar file. + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo sh -c \"tar xvf /home/docker/userdata.tar -C /home/docker > /var/log/userdata.log 2>&1 && chown -R docker:staff /home/docker\"") + if err != nil { + return err + } + + // copy to /var/lib/boot2docker + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo /bin/mv /home/docker/userdata.tar /var/lib/boot2docker/userdata.tar") + if err != nil { + return err + } + + // Enable Shared Folders + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "enableSharedFolders", d.vmxPath()) + if err != nil { + return err + } + + var shareName, shareDir string // TODO configurable at some point + switch runtime.GOOS { + case "darwin": + shareName = "Users" + shareDir = "/Users" + // TODO "linux" and "windows" + } + + if shareDir != "" && !d.NoShare { + if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) { + return err + } else if !os.IsNotExist(err) { + // add shared folder, create mountpoint and mount it. + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "addSharedFolder", d.vmxPath(), shareName, shareDir) + if err != nil { + return err + } + command := "([ ! -d " + shareDir + " ]&& sudo mkdir " + shareDir + "; sudo mount --bind /mnt/hgfs/" + shareDir + " " + shareDir + ") || ([ -f /usr/local/bin/vmhgfs-fuse ]&& sudo /usr/local/bin/vmhgfs-fuse -o allow_other .host:/" + shareName + " " + shareDir + ") || sudo mount -t vmhgfs -o uid=$(id -u),gid=$(id -g) .host:/" + shareName + " " + shareDir + _, _, err = vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", command) + if err != nil { + return err + } + } + } + return nil +} + +func (d *Driver) Start() error { + vmrun("start", d.vmxPath(), "nogui") + + // Do not execute the rest of boot2docker specific configuration, exit here + if d.ConfigDriveURL != "" { + log.Debugf("Leaving start sequence early, configdrive found") + return nil + } + + log.Debugf("Mounting Shared Folders...") + var shareName, shareDir string // TODO configurable at some point + switch runtime.GOOS { + case "darwin": + shareName = "Users" + shareDir = "/Users" + // TODO "linux" and "windows" + } + + if shareDir != "" { + if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) { + return err + } else if !os.IsNotExist(err) { + // create mountpoint and mount shared folder + command := "([ ! -d " + shareDir + " ]&& sudo mkdir " + shareDir + "; sudo mount --bind /mnt/hgfs/" + shareDir + " " + shareDir + ") || ([ -f /usr/local/bin/vmhgfs-fuse ]&& sudo /usr/local/bin/vmhgfs-fuse -o nonempty -o allow_other .host:/" + shareName + " " + shareDir + ") || sudo mount -t vmhgfs -o uid=$(id -u),gid=$(id -g) .host:/" + shareName + " " + shareDir + vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", command) + } + } + + return nil +} + +func (d *Driver) Stop() error { + _, _, err := vmrun("stop", d.vmxPath(), "nogui") + return err +} + +func (d *Driver) Restart() error { + // Stop VM gracefully + if err := d.Stop(); err != nil { + return err + } + // Start it again and mount shared folder + return d.Start() +} + +func (d *Driver) Kill() error { + _, _, err := vmrun("stop", d.vmxPath(), "hard nogui") + return err +} + +func (d *Driver) Remove() error { + s, _ := d.GetState() + if s == state.Running { + if err := d.Kill(); err != nil { + return fmt.Errorf("Error stopping VM before deletion") + } + } + log.Infof("Deleting %s...", d.MachineName) + vmrun("deleteVM", d.vmxPath(), "nogui") + return nil +} + +func (d *Driver) Upgrade() error { + return fmt.Errorf("VMware Fusion does not currently support the upgrade operation") +} + +func (d *Driver) vmxPath() string { + return d.ResolveStorePath(fmt.Sprintf("%s.vmx", d.MachineName)) +} + +func (d *Driver) vmdkPath() string { + return d.ResolveStorePath(fmt.Sprintf("%s.vmdk", d.MachineName)) +} + +func (d *Driver) getMacAddressFromVmx() (string, error) { + var vmxfh *os.File + var vmxcontent []byte + var err error + + if vmxfh, err = os.Open(d.vmxPath()); err != nil { + return "", err + } + defer vmxfh.Close() + + if vmxcontent, err = ioutil.ReadAll(vmxfh); err != nil { + return "", err + } + + // Look for generatedAddress as we're passing a VMX with addressType = "generated". + var macaddr string + vmxparse := regexp.MustCompile(`^ethernet0.generatedAddress\s*=\s*"(.*?)"\s*$`) + for _, line := range strings.Split(string(vmxcontent), "\n") { + if matches := vmxparse.FindStringSubmatch(line); matches == nil { + continue + } else { + macaddr = strings.ToLower(matches[1]) + } + } + + if macaddr == "" { + return "", fmt.Errorf("couldn't find MAC address in VMX file %s", d.vmxPath()) + } + + log.Debugf("MAC address in VMX: %s", macaddr) + + return macaddr, nil +} + +func (d *Driver) getIPfromVmnetConfiguration(macaddr string) (string, error) { + + // DHCP lease table for NAT vmnet interface + confFiles, _ := filepath.Glob("/Library/Preferences/VMware Fusion/vmnet*/dhcpd.conf") + for _, conffile := range confFiles { + log.Debugf("Trying to find IP address in configuration file: %s", conffile) + if ipaddr, err := d.getIPfromVmnetConfigurationFile(conffile, macaddr); err == nil { + return ipaddr, err + } + } + + return "", fmt.Errorf("IP not found for MAC %s in vmnet configuration files", macaddr) +} + +func (d *Driver) getIPfromVmnetConfigurationFile(conffile, macaddr string) (string, error) { + var conffh *os.File + var confcontent []byte + + var currentip string + var lastipmatch string + var lastmacmatch string + + var err error + + if conffh, err = os.Open(conffile); err != nil { + return "", err + } + defer conffh.Close() + + if confcontent, err = ioutil.ReadAll(conffh); err != nil { + return "", err + } + + // find all occurrences of 'host .* { .. }' and extract + // out of the inner block the MAC and IP addresses + + // key = MAC, value = IP + m := make(map[string]string) + + // Begin of a host block, that contains the IP, MAC + hostbegin := regexp.MustCompile(`^host (.+?) {`) + // End of a host block + hostend := regexp.MustCompile(`^}`) + + // Get the IP address. + ip := regexp.MustCompile(`^\s*fixed-address (.+?);$`) + // Get the MAC address associated. + mac := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) + + // we use a block depth so that just in case inner blocks exists + // we are not being fooled by them + blockdepth := 0 + for _, line := range strings.Split(string(confcontent), "\n") { + + if matches := hostbegin.FindStringSubmatch(line); matches != nil { + blockdepth = blockdepth + 1 + continue + } + + // we are only in interested in endings if we in a block. Otherwise we will count + // ending of non host blocks as well + if matches := hostend.FindStringSubmatch(line); blockdepth > 0 && matches != nil { + blockdepth = blockdepth - 1 + + if blockdepth == 0 { + // add data + m[lastmacmatch] = lastipmatch + + // reset all temp var holders + lastipmatch = "" + lastmacmatch = "" + } + + continue + } + + // only if we are within the first level of a block + // we are looking for addresses to extract + if blockdepth == 1 { + if matches := ip.FindStringSubmatch(line); matches != nil { + lastipmatch = matches[1] + continue + } + + if matches := mac.FindStringSubmatch(line); matches != nil { + lastmacmatch = strings.ToLower(matches[1]) + continue + } + } + } + + log.Debugf("Following IPs found %s", m) + + // map is filled to now lets check if we have a MAC associated to an IP + currentip, ok := m[strings.ToLower(macaddr)] + + if !ok { + return "", fmt.Errorf("IP not found for MAC %s in vmnet configuration", macaddr) + } + + log.Debugf("IP found in vmnet configuration file: %s", currentip) + + return currentip, nil + +} + +func (d *Driver) getIPfromDHCPLease(macaddr string) (string, error) { + + // DHCP lease table for NAT vmnet interface + leasesFiles, _ := filepath.Glob("/var/db/vmware/*.leases") + for _, dhcpfile := range leasesFiles { + log.Debugf("Trying to find IP address in leases file: %s", dhcpfile) + if ipaddr, err := d.getIPfromDHCPLeaseFile(dhcpfile, macaddr); err == nil { + return ipaddr, err + } + } + + return "", fmt.Errorf("IP not found for MAC %s in DHCP leases", macaddr) +} + +func (d *Driver) getIPfromDHCPLeaseFile(dhcpfile, macaddr string) (string, error) { + + var dhcpfh *os.File + var dhcpcontent []byte + var lastipmatch string + var currentip string + var lastleaseendtime time.Time + var currentleadeendtime time.Time + var err error + + if dhcpfh, err = os.Open(dhcpfile); err != nil { + return "", err + } + defer dhcpfh.Close() + + if dhcpcontent, err = ioutil.ReadAll(dhcpfh); err != nil { + return "", err + } + + // Get the IP from the lease table. + leaseip := regexp.MustCompile(`^lease (.+?) {$`) + // Get the lease end date time. + leaseend := regexp.MustCompile(`^\s*ends \d (.+?);$`) + // Get the MAC address associated. + leasemac := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) + + for _, line := range strings.Split(string(dhcpcontent), "\n") { + + if matches := leaseip.FindStringSubmatch(line); matches != nil { + lastipmatch = matches[1] + continue + } + + if matches := leaseend.FindStringSubmatch(line); matches != nil { + lastleaseendtime, _ = time.Parse("2006/01/02 15:04:05", matches[1]) + continue + } + + if matches := leasemac.FindStringSubmatch(line); matches != nil && matches[1] == macaddr && currentleadeendtime.Before(lastleaseendtime) { + currentip = lastipmatch + currentleadeendtime = lastleaseendtime + } + } + + if currentip == "" { + return "", fmt.Errorf("IP not found for MAC %s in DHCP leases", macaddr) + } + + log.Debugf("IP found in DHCP lease table: %s", currentip) + + return currentip, nil +} + +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" +} + +// Make a boot2docker userdata.tar key bundle +func (d *Driver) generateKeyBundle() error { + log.Debugf("Creating Tar key bundle...") + + magicString := "boot2docker, this is vmware speaking" + + tf, err := os.Create(d.ResolveStorePath("userdata.tar")) + if err != nil { + return err + } + defer tf.Close() + var fileWriter = tf + + tw := tar.NewWriter(fileWriter) + defer tw.Close() + + // magicString first so we can figure out who originally wrote the tar. + file := &tar.Header{Name: magicString, Size: int64(len(magicString))} + if err := tw.WriteHeader(file); err != nil { + return err + } + if _, err := tw.Write([]byte(magicString)); err != nil { + return err + } + // .ssh/key.pub => authorized_keys + file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700} + if err := tw.WriteHeader(file); err != nil { + return err + } + pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) + if err != nil { + return err + } + file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return err + } + if _, err := tw.Write([]byte(pubKey)); err != nil { + return err + } + file = &tar.Header{Name: ".ssh/authorized_keys2", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return err + } + if _, err := tw.Write([]byte(pubKey)); err != nil { + return err + } + return tw.Close() +} + +// execute command over SSH with user / password authentication +func executeSSHCommand(command string, d *Driver) error { + log.Debugf("Execute executeSSHCommand: %s", command) + + config := &cryptossh.ClientConfig{ + User: d.SSHUser, + Auth: []cryptossh.AuthMethod{ + cryptossh.Password(d.SSHPassword), + }, + } + + client, err := cryptossh.Dial("tcp", fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), config) + if err != nil { + log.Debugf("Failed to dial:", err) + return err + } + + session, err := client.NewSession() + if err != nil { + log.Debugf("Failed to create session: " + err.Error()) + return err + } + defer session.Close() + + var b bytes.Buffer + session.Stdout = &b + + if err := session.Run(command); err != nil { + log.Debugf("Failed to run: " + err.Error()) + return err + } + log.Debugf("Stdout from executeSSHCommand: %s", b.String()) + + return nil +} diff --git a/drivers/vmwarefusion/fusion_darwin_test.go b/drivers/vmwarefusion/fusion_darwin_test.go new file mode 100644 index 0000000000..da58950fab --- /dev/null +++ b/drivers/vmwarefusion/fusion_darwin_test.go @@ -0,0 +1,22 @@ +package vmwarefusion + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{}, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/vmwarefusion/vmrun.go b/drivers/vmwarefusion/vmrun.go deleted file mode 100644 index 4850a81b06..0000000000 --- a/drivers/vmwarefusion/vmrun.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package vmwarefusion - -import ( - "bytes" - "errors" - "fmt" - "os" - "os/exec" - "strings" - - log "github.com/Sirupsen/logrus" -) - -var ( - vmrunbin = "/Applications/VMware Fusion.app/Contents/Library/vmrun" - vdiskmanbin = "/Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager" -) - -var ( - ErrMachineExist = errors.New("machine already exists") - ErrMachineNotExist = errors.New("machine does not exist") - ErrVMRUNNotFound = errors.New("VMRUN not found") -) - -func vmrun(args ...string) (string, string, error) { - cmd := exec.Command(vmrunbin, args...) - if os.Getenv("DEBUG") != "" { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - - var stdout bytes.Buffer - var stderr bytes.Buffer - cmd.Stdout, cmd.Stderr = &stdout, &stderr - log.Debugf("executing: %v %v", vmrunbin, strings.Join(args, " ")) - - err := cmd.Run() - if err != nil { - if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound { - err = ErrVMRUNNotFound - } - } - - return stdout.String(), stderr.String(), err -} - -// Make a vmdk disk image with the given size (in MB). -func vdiskmanager(dest string, size int) error { - cmd := exec.Command(vdiskmanbin, "-c", "-t", "0", "-s", fmt.Sprintf("%dMB", size), "-a", "lsilogic", dest) - if os.Getenv("DEBUG") != "" { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - - if stdout := cmd.Run(); stdout != nil { - if ee, ok := stdout.(*exec.Error); ok && ee == exec.ErrNotFound { - return ErrVMRUNNotFound - } - } - return nil -} diff --git a/drivers/vmwarefusion/vmrun_darwin.go b/drivers/vmwarefusion/vmrun_darwin.go new file mode 100644 index 0000000000..3039ea177c --- /dev/null +++ b/drivers/vmwarefusion/vmrun_darwin.go @@ -0,0 +1,78 @@ +/* + * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. + */ + +package vmwarefusion + +import ( + "bytes" + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "syscall" + + "github.com/docker/machine/libmachine/log" +) + +var ( + vmrunbin = setVmwareCmd("vmrun") + vdiskmanbin = setVmwareCmd("vmware-vdiskmanager") +) + +var ( + ErrMachineExist = errors.New("machine already exists") + ErrMachineNotExist = errors.New("machine does not exist") + ErrVMRUNNotFound = errors.New("VMRUN not found") +) + +// detect the vmrun and vmware-vdiskmanager cmds' path if needed +func setVmwareCmd(cmd string) string { + if path, err := exec.LookPath(cmd); err == nil { + return path + } + return filepath.Join("/Applications/VMware Fusion.app/Contents/Library/", cmd) +} + +func vmrun(args ...string) (string, string, error) { + // vmrun with nogui on VMware Fusion through at least 8.0.1 doesn't work right + // if the umask is set to not allow world-readable permissions + _ = syscall.Umask(022) + cmd := exec.Command(vmrunbin, args...) + if os.Getenv("MACHINE_DEBUG") != "" { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } + + var stdout bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout, cmd.Stderr = &stdout, &stderr + log.Debugf("executing: %v %v", vmrunbin, strings.Join(args, " ")) + + err := cmd.Run() + if err != nil { + if ee, ok := err.(*exec.Error); ok && ee == exec.ErrNotFound { + err = ErrVMRUNNotFound + } + } + + return stdout.String(), stderr.String(), err +} + +// Make a vmdk disk image with the given size (in MB). +func vdiskmanager(dest string, size int) error { + cmd := exec.Command(vdiskmanbin, "-c", "-t", "0", "-s", fmt.Sprintf("%dMB", size), "-a", "lsilogic", dest) + if os.Getenv("MACHINE_DEBUG") != "" { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } + + if stdout := cmd.Run(); stdout != nil { + if ee, ok := stdout.(*exec.Error); ok && ee == exec.ErrNotFound { + return ErrVMRUNNotFound + } + } + return nil +} diff --git a/drivers/vmwarefusion/vmx.go b/drivers/vmwarefusion/vmx.go deleted file mode 100644 index 3f46f633e4..0000000000 --- a/drivers/vmwarefusion/vmx.go +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package vmwarefusion - -const vmx = ` -.encoding = "UTF-8" -config.version = "8" -displayName = "{{.MachineName}}" -ethernet0.addressType = "generated" -ethernet0.connectionType = "nat" -ethernet0.linkStatePropagation.enable = "TRUE" -ethernet0.present = "TRUE" -ethernet0.virtualDev = "e1000" -ethernet0.wakeOnPcktRcv = "FALSE" -floppy0.present = "FALSE" -guestOS = "other26xlinux-64" -hpet0.present = "TRUE" -ide1:0.deviceType = "cdrom-image" -ide1:0.fileName = "{{.ISO}}" -ide1:0.present = "TRUE" -mem.hotadd = "TRUE" -memsize = "{{.Memory}}" -powerType.powerOff = "hard" -powerType.powerOn = "hard" -powerType.reset = "hard" -powerType.suspend = "hard" -scsi0.present = "TRUE" -scsi0.virtualDev = "lsilogic" -scsi0:0.fileName = "{{.MachineName}}.vmdk" -scsi0:0.present = "TRUE" -virtualHW.productCompatibility = "hosted" -virtualHW.version = "10" -msg.autoanswer = "TRUE" -uuid.action = "create" -` diff --git a/drivers/vmwarefusion/vmx_darwin.go b/drivers/vmwarefusion/vmx_darwin.go new file mode 100644 index 0000000000..0ca6e63b28 --- /dev/null +++ b/drivers/vmwarefusion/vmx_darwin.go @@ -0,0 +1,72 @@ +/* + * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. + */ + +package vmwarefusion + +const vmx = ` +.encoding = "UTF-8" +config.version = "8" +displayName = "{{.MachineName}}" +ethernet0.present = "TRUE" +ethernet0.connectionType = "nat" +ethernet0.virtualDev = "vmxnet3" +ethernet0.wakeOnPcktRcv = "FALSE" +ethernet0.addressType = "generated" +ethernet0.linkStatePropagation.enable = "TRUE" +pciBridge0.present = "TRUE" +pciBridge4.present = "TRUE" +pciBridge4.virtualDev = "pcieRootPort" +pciBridge4.functions = "8" +pciBridge5.present = "TRUE" +pciBridge5.virtualDev = "pcieRootPort" +pciBridge5.functions = "8" +pciBridge6.present = "TRUE" +pciBridge6.virtualDev = "pcieRootPort" +pciBridge6.functions = "8" +pciBridge7.present = "TRUE" +pciBridge7.virtualDev = "pcieRootPort" +pciBridge7.functions = "8" +pciBridge0.pciSlotNumber = "17" +pciBridge4.pciSlotNumber = "21" +pciBridge5.pciSlotNumber = "22" +pciBridge6.pciSlotNumber = "23" +pciBridge7.pciSlotNumber = "24" +scsi0.pciSlotNumber = "160" +usb.pciSlotNumber = "32" +ethernet0.pciSlotNumber = "192" +sound.pciSlotNumber = "33" +vmci0.pciSlotNumber = "35" +sata0.pciSlotNumber = "36" +floppy0.present = "FALSE" +guestOS = "other3xlinux-64" +hpet0.present = "TRUE" +sata0.present = "TRUE" +sata0:1.present = "TRUE" +sata0:1.fileName = "{{.ISO}}" +sata0:1.deviceType = "cdrom-image" +{{ if .ConfigDriveURL }} +sata0:2.present = "TRUE" +sata0:2.fileName = "{{.ConfigDriveISO}}" +sata0:2.deviceType = "cdrom-image" +{{ end }} +vmci0.present = "TRUE" +mem.hotadd = "TRUE" +memsize = "{{.Memory}}" +powerType.powerOff = "soft" +powerType.powerOn = "soft" +powerType.reset = "soft" +powerType.suspend = "soft" +scsi0.present = "TRUE" +scsi0.virtualDev = "pvscsi" +scsi0:0.fileName = "{{.MachineName}}.vmdk" +scsi0:0.present = "TRUE" +tools.synctime = "TRUE" +virtualHW.productCompatibility = "hosted" +virtualHW.version = "10" +msg.autoanswer = "TRUE" +uuid.action = "create" +numvcpus = "{{.CPU}}" +hgfs.mapRootShare = "FALSE" +hgfs.linkRootShare = "FALSE" +` diff --git a/drivers/vmwarevcloudair/vcloudair.go b/drivers/vmwarevcloudair/vcloudair.go index 0a7360f631..163295165d 100644 --- a/drivers/vmwarevcloudair/vcloudair.go +++ b/drivers/vmwarevcloudair/vcloudair.go @@ -7,215 +7,200 @@ package vmwarevcloudair import ( "fmt" "io/ioutil" - "os/exec" - "path" + "net" + "strconv" "strings" "github.com/vmware/govcloudair" - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/docker/utils" - "github.com/docker/machine/drivers" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" -) - -const ( - dockerConfigDir = "/etc/docker" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" ) type Driver struct { - UserName string - UserPassword string - ComputeID string - VDCID string - OrgVDCNet string - EdgeGateway string - PublicIP string - Catalog string - CatalogItem string - MachineName string - SSHPort int - DockerPort int - Provision bool - CPUCount int - MemorySize int - CaCertPath string - PrivateKeyPath string - - VAppID string - storePath string -} - -type CreateFlags struct { - UserName *string - UserPassword *string - ComputeID *string - VDCID *string - OrgVDCNet *string - EdgeGateway *string - PublicIP *string - Catalog *string - CatalogItem *string - Name *string - SSHPort *int - DockerPort *int - Provision *bool - CPUCount *int - MemorySize *int + *drivers.BaseDriver + UserName string + UserPassword string + ComputeID string + VDCID string + OrgVDCNet string + EdgeGateway string + PublicIP string + Catalog string + CatalogItem string + DockerPort int + CPUCount int + MemorySize int + VAppID string } -func init() { - drivers.Register("vmwarevcloudair", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} +const ( + defaultCatalog = "Public Catalog" + defaultCatalogItem = "Ubuntu Server 12.04 LTS (amd64 20150127)" + defaultCpus = 1 + defaultMemory = 2048 + defaultSSHPort = 22 + defaultDockerPort = 2376 +) // GetCreateFlags registers the flags this driver adds to // "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.StringFlag{ +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_USERNAME", Name: "vmwarevcloudair-username", Usage: "vCloud Air username", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_PASSWORD", Name: "vmwarevcloudair-password", Usage: "vCloud Air password", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_COMPUTEID", Name: "vmwarevcloudair-computeid", Usage: "vCloud Air Compute ID (if using Dedicated Cloud)", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_VDCID", Name: "vmwarevcloudair-vdcid", Usage: "vCloud Air VDC ID", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_ORGVDCNETWORK", Name: "vmwarevcloudair-orgvdcnetwork", Usage: "vCloud Air Org VDC Network (Default is -default-routed)", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_EDGEGATEWAY", Name: "vmwarevcloudair-edgegateway", Usage: "vCloud Air Org Edge Gateway (Default is )", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_PUBLICIP", Name: "vmwarevcloudair-publicip", Usage: "vCloud Air Org Public IP to use", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_CATALOG", Name: "vmwarevcloudair-catalog", Usage: "vCloud Air Catalog (default is Public Catalog)", - Value: "Public Catalog", + Value: defaultCatalog, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VCLOUDAIR_CATALOGITEM", Name: "vmwarevcloudair-catalogitem", Usage: "vCloud Air Catalog Item (default is Ubuntu Precise)", - Value: "Ubuntu Server 12.04 LTS (amd64 20140927)", - }, - - // BoolTFlag is true by default. - cli.BoolTFlag{ - EnvVar: "VCLOUDAIR_PROVISION", - Name: "vmwarevcloudair-provision", - Usage: "vCloud Air Install Docker binaries (default is true)", + Value: defaultCatalogItem, }, - - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "VCLOUDAIR_CPU_COUNT", Name: "vmwarevcloudair-cpu-count", Usage: "vCloud Air VM Cpu Count (default 1)", - Value: 1, + Value: defaultCpus, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "VCLOUDAIR_MEMORY_SIZE", Name: "vmwarevcloudair-memory-size", Usage: "vCloud Air VM Memory Size in MB (default 2048)", - Value: 2048, + Value: defaultMemory, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "VCLOUDAIR_SSH_PORT", Name: "vmwarevcloudair-ssh-port", Usage: "vCloud Air SSH port", - Value: 22, + Value: defaultSSHPort, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "VCLOUDAIR_DOCKER_PORT", Name: "vmwarevcloudair-docker-port", Usage: "vCloud Air Docker port", - Value: 2376, + Value: defaultDockerPort, + }, + } +} + +func NewDriver(hostName, storePath string) drivers.Driver { + return &Driver{ + Catalog: defaultCatalog, + CatalogItem: defaultCatalogItem, + CPUCount: defaultCpus, + MemorySize: defaultMemory, + DockerPort: defaultDockerPort, + BaseDriver: &drivers.BaseDriver{ + SSHPort: defaultSSHPort, + MachineName: hostName, + StorePath: storePath, }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - driver := &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey} - return driver, nil +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } -// Driver interface implementation -func (driver *Driver) DriverName() string { +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { return "vmwarevcloudair" } -func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.UserName = flags.String("vmwarevcloudair-username") - driver.UserPassword = flags.String("vmwarevcloudair-password") - driver.VDCID = flags.String("vmwarevcloudair-vdcid") - driver.PublicIP = flags.String("vmwarevcloudair-publicip") + d.UserName = flags.String("vmwarevcloudair-username") + d.UserPassword = flags.String("vmwarevcloudair-password") + d.VDCID = flags.String("vmwarevcloudair-vdcid") + d.PublicIP = flags.String("vmwarevcloudair-publicip") + d.SetSwarmConfigFromFlags(flags) // Check for required Params - if driver.UserName == "" || driver.UserPassword == "" || driver.VDCID == "" || driver.PublicIP == "" { + if d.UserName == "" || d.UserPassword == "" || d.VDCID == "" || d.PublicIP == "" { return fmt.Errorf("Please specify vcloudair mandatory params using options: -vmwarevcloudair-username -vmwarevcloudair-password -vmwarevcloudair-vdcid and -vmwarevcloudair-publicip") } // If ComputeID is not set we're using a VPC, hence setting ComputeID = VDCID if flags.String("vmwarevcloudair-computeid") == "" { - driver.ComputeID = flags.String("vmwarevcloudair-vdcid") + d.ComputeID = flags.String("vmwarevcloudair-vdcid") } else { - driver.ComputeID = flags.String("vmwarevcloudair-computeid") + d.ComputeID = flags.String("vmwarevcloudair-computeid") } // If the Org VDC Network is empty, set it to the default routed network. if flags.String("vmwarevcloudair-orgvdcnetwork") == "" { - driver.OrgVDCNet = flags.String("vmwarevcloudair-vdcid") + "-default-routed" + d.OrgVDCNet = flags.String("vmwarevcloudair-vdcid") + "-default-routed" } else { - driver.OrgVDCNet = flags.String("vmwarevcloudair-orgvdcnetwork") + d.OrgVDCNet = flags.String("vmwarevcloudair-orgvdcnetwork") } // If the Edge Gateway is empty, just set it to the default edge gateway. if flags.String("vmwarevcloudair-edgegateway") == "" { - driver.EdgeGateway = flags.String("vmwarevcloudair-vdcid") + d.EdgeGateway = flags.String("vmwarevcloudair-vdcid") } else { - driver.EdgeGateway = flags.String("vmwarevcloudair-edgegateway") + d.EdgeGateway = flags.String("vmwarevcloudair-edgegateway") } - driver.Catalog = flags.String("vmwarevcloudair-catalog") - driver.CatalogItem = flags.String("vmwarevcloudair-catalogitem") + d.Catalog = flags.String("vmwarevcloudair-catalog") + d.CatalogItem = flags.String("vmwarevcloudair-catalogitem") - driver.DockerPort = flags.Int("vmwarevcloudair-docker-port") - driver.SSHPort = flags.Int("vmwarevcloudair-ssh-port") - driver.Provision = flags.Bool("vmwarevcloudair-provision") - driver.CPUCount = flags.Int("vmwarevcloudair-cpu-count") - driver.MemorySize = flags.Int("vmwarevcloudair-memory-size") + d.DockerPort = flags.Int("vmwarevcloudair-docker-port") + d.SSHUser = "root" + d.SSHPort = flags.Int("vmwarevcloudair-ssh-port") + d.CPUCount = flags.Int("vmwarevcloudair-cpu-count") + d.MemorySize = flags.Int("vmwarevcloudair-memory-size") return nil } func (d *Driver) GetURL() (string, error) { - return fmt.Sprintf("tcp://%s:%d", d.PublicIP, d.DockerPort), nil + if err := drivers.MustBeRunning(d); err != nil { + return "", err + } + + return fmt.Sprintf("tcp://%s", net.JoinHostPort(d.PublicIP, strconv.Itoa(d.DockerPort))), nil } func (d *Driver) GetIP() (string, error) { @@ -223,7 +208,6 @@ func (d *Driver) GetIP() (string, error) { } func (d *Driver) GetState() (state.State, error) { - p, err := govcloudair.NewClient() if err != nil { return state.Error, err @@ -257,15 +241,9 @@ func (d *Driver) GetState() (state.State, error) { return state.Stopped, nil } return state.None, nil - -} - -func (d *Driver) PreCreateCheck() error { - return nil } func (d *Driver) Create() error { - key, err := d.createSSHKey() if err != nil { return err @@ -384,54 +362,6 @@ func (d *Driver) Create() error { return err } - log.Infof("Waiting for SSH...") - - if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.PublicIP, d.SSHPort)); err != nil { - return err - } - - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - connTest := "ping -c 3 www.google.com >/dev/null 2>&1 && ( echo \"Connectivity and DNS tests passed.\" ) || ( echo \"Connectivity and DNS tests failed, trying to add Nameserver to resolv.conf\"; echo \"nameserver 8.8.8.8\" >> /etc/resolv.conf )" - - log.Debugf("Connectivity and DNS sanity test...") - cmd, err = d.GetSSHCommand(connTest) - if err != nil { - return err - } - - if err := cmd.Run(); err != nil { - return err - } - - if d.Provision { - dockerInstall := "curl -sSL https://get.docker.com | sudo sh" - - log.Infof("Installing Docker...") - - cmd, err = d.GetSSHCommand(dockerInstall) - if err != nil { - return err - } - - if err = cmd.Run(); err != nil { - return err - } - - } - log.Debugf("Disconnecting from vCloud Air...") if err = p.Disconnect(); err != nil { @@ -441,12 +371,11 @@ func (d *Driver) Create() error { // Set VAppID with ID of the created VApp d.VAppID = vapp.VApp.ID - return nil - + d.IPAddress, err = d.GetIP() + return err } func (d *Driver) Remove() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -516,16 +445,11 @@ func (d *Driver) Remove() error { return err } - if err = p.Disconnect(); err != nil { - return err - } - - return nil - + err = p.Disconnect() + return err } func (d *Driver) Start() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -564,12 +488,11 @@ func (d *Driver) Start() error { return err } - return nil - + d.IPAddress, err = d.GetIP() + return err } func (d *Driver) Stop() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -587,33 +510,24 @@ func (d *Driver) Stop() error { return err } - status, err := vapp.GetStatus() + task, err := vapp.Shutdown() if err != nil { return err } - - if status == "POWERED_ON" { - log.Infof("Shutting down %s...", d.MachineName) - task, err := vapp.Shutdown() - if err != nil { - return err - } - if err = task.WaitTaskCompletion(); err != nil { - return err - } - + if err = task.WaitTaskCompletion(); err != nil { + return err } if err = p.Disconnect(); err != nil { return err } - return nil + d.IPAddress = "" + return nil } func (d *Driver) Restart() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -631,45 +545,23 @@ func (d *Driver) Restart() error { return err } - status, err := vapp.GetStatus() + task, err := vapp.Reset() if err != nil { return err } - - if status == "POWERED_ON" { - // If it's powered on, restart the machine - log.Infof("Restarting %s...", d.MachineName) - task, err := vapp.Reset() - if err != nil { - return err - } - if err = task.WaitTaskCompletion(); err != nil { - return err - } - - } else { - // If it's not powered on, start it. - log.Infof("Docker host %s is powered off, powering it back on...", d.MachineName) - task, err := vapp.PowerOn() - if err != nil { - return err - } - if err = task.WaitTaskCompletion(); err != nil { - return err - } - + if err = task.WaitTaskCompletion(); err != nil { + return err } if err = p.Disconnect(); err != nil { return err } - return nil - + d.IPAddress, err = d.GetIP() + return err } func (d *Driver) Kill() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -687,93 +579,32 @@ func (d *Driver) Kill() error { return err } - status, err := vapp.GetStatus() + task, err := vapp.PowerOff() if err != nil { return err } - - if status == "POWERED_ON" { - log.Infof("Stopping %s...", d.MachineName) - task, err := vapp.PowerOff() - if err != nil { - return err - } - if err = task.WaitTaskCompletion(); err != nil { - return err - } - - } - - if err = p.Disconnect(); err != nil { + if err = task.WaitTaskCompletion(); err != nil { return err } - return nil - -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { + if err = p.Disconnect(); err != nil { return err } - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } + d.IPAddress = "" return nil } -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.PublicIP, d.SSHPort, "root", d.sshKeyPath(), args...), nil -} - // Helpers func generateVMName() string { - randomID := utils.TruncateID(utils.GenerateRandomID()) + randomID := mcnutils.TruncateID(mcnutils.GenerateRandomID()) return fmt.Sprintf("docker-host-%s", randomID) } func (d *Driver) createSSHKey() (string, error) { - - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return "", err } @@ -785,10 +616,6 @@ func (d *Driver) createSSHKey() (string, error) { return string(publicKey), nil } -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } diff --git a/drivers/vmwarevcloudair/vcloudlair_test.go b/drivers/vmwarevcloudair/vcloudlair_test.go new file mode 100644 index 0000000000..e92ee55809 --- /dev/null +++ b/drivers/vmwarevcloudair/vcloudlair_test.go @@ -0,0 +1,27 @@ +package vmwarevcloudair + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{ + "vmwarevcloudair-username": "root", + "vmwarevcloudair-password": "pwd", + "vmwarevcloudair-vdcid": "ID", + "vmwarevcloudair-publicip": "IP", + }, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/drivers/vmwarevsphere/errors/config_error.go b/drivers/vmwarevsphere/errors/config_error.go deleted file mode 100644 index 23e0ab4b7b..0000000000 --- a/drivers/vmwarevsphere/errors/config_error.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import "fmt" - -type IncompleteVsphereConfigError struct { - component string -} - -func NewIncompleteVsphereConfigError(component string) error { - err := IncompleteVsphereConfigError{ - component: component, - } - return &err -} - -func (err *IncompleteVsphereConfigError) Error() string { - return fmt.Sprintf("Incomplete vSphere information: missing %s", err.component) -} diff --git a/drivers/vmwarevsphere/errors/datastore_error.go b/drivers/vmwarevsphere/errors/datastore_error.go deleted file mode 100644 index 64439281e1..0000000000 --- a/drivers/vmwarevsphere/errors/datastore_error.go +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import "fmt" - -type DatastoreError struct { - datastore string - operation string - reason string -} - -func NewDatastoreError(datastore, operation, reason string) error { - err := DatastoreError{ - datastore: datastore, - operation: operation, - reason: reason, - } - return &err -} - -func (err *DatastoreError) Error() string { - return fmt.Sprintf("Unable to %s on datastore %s due to %s", err.operation, err.datastore, err.reason) -} diff --git a/drivers/vmwarevsphere/errors/errors.go b/drivers/vmwarevsphere/errors/errors.go deleted file mode 100644 index 241127534b..0000000000 --- a/drivers/vmwarevsphere/errors/errors.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import ( - original "errors" - "fmt" -) - -func New(message string) error { - return original.New(message) -} - -func NewWithFmt(message string, args ...interface{}) error { - return original.New(fmt.Sprintf(message, args...)) -} - -func NewWithError(message string, err error) error { - return NewWithFmt("%s: %s", message, err.Error()) -} diff --git a/drivers/vmwarevsphere/errors/govc_error.go b/drivers/vmwarevsphere/errors/govc_error.go deleted file mode 100644 index 0cbf9841e1..0000000000 --- a/drivers/vmwarevsphere/errors/govc_error.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import "fmt" - -type GovcNotFoundError struct { - path string -} - -func NewGovcNotFoundError(path string) error { - err := GovcNotFoundError{ - path: path, - } - return &err -} - -func (err *GovcNotFoundError) Error() string { - return fmt.Sprintf("govc not found: %s", err.path) -} diff --git a/drivers/vmwarevsphere/errors/guest_error.go b/drivers/vmwarevsphere/errors/guest_error.go deleted file mode 100644 index 4dffe821cb..0000000000 --- a/drivers/vmwarevsphere/errors/guest_error.go +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import "fmt" - -type GuestError struct { - vm string - operation string - reason string -} - -func NewGuestError(vm, operation, reason string) error { - err := GuestError{ - vm: vm, - operation: operation, - reason: reason, - } - return &err -} - -func (err *GuestError) Error() string { - return fmt.Sprintf("Unable to %s on vm %s due to %s", err.operation, err.vm, err.reason) -} diff --git a/drivers/vmwarevsphere/errors/login_error.go b/drivers/vmwarevsphere/errors/login_error.go deleted file mode 100644 index b72569fc0d..0000000000 --- a/drivers/vmwarevsphere/errors/login_error.go +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -type InvalidLoginError struct { -} - -func NewInvalidLoginError() error { - err := InvalidLoginError{} - return &err -} - -func (err *InvalidLoginError) Error() string { - return "cannot complete operation due to incorrect vSphere username or password" -} diff --git a/drivers/vmwarevsphere/errors/state_error.go b/drivers/vmwarevsphere/errors/state_error.go deleted file mode 100644 index 43d92ad078..0000000000 --- a/drivers/vmwarevsphere/errors/state_error.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import "fmt" - -type InvalidStateError struct { - vm string -} - -func NewInvalidStateError(vm string) error { - err := InvalidStateError{ - vm: vm, - } - return &err -} - -func (err *InvalidStateError) Error() string { - return fmt.Sprintf("Machine %s state invalid", err.vm) -} diff --git a/drivers/vmwarevsphere/errors/vm_error.go b/drivers/vmwarevsphere/errors/vm_error.go deleted file mode 100644 index 25e1d3c597..0000000000 --- a/drivers/vmwarevsphere/errors/vm_error.go +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package errors - -import "fmt" - -type VmError struct { - operation string - vm string - reason string -} - -func NewVmError(operation, vm, reason string) error { - err := VmError{ - vm: vm, - operation: operation, - reason: reason, - } - return &err -} - -func (err *VmError) Error() string { - return fmt.Sprintf("Unable to %s docker host %s: %s", err.operation, err.vm, err.reason) -} diff --git a/drivers/vmwarevsphere/govc.go b/drivers/vmwarevsphere/govc.go deleted file mode 100644 index 9e110bea3c..0000000000 --- a/drivers/vmwarevsphere/govc.go +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package vmwarevsphere - -import ( - "bytes" - "os/exec" - "strings" - - log "github.com/Sirupsen/logrus" -) - -var ( - GovcCmd = "govc" -) - -func govc(args ...string) error { - cmd := exec.Command(GovcCmd, args...) - - log.Debugf("executing: %v %v", GovcCmd, strings.Join(args, " ")) - - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -func govcOutErr(args ...string) (string, string, error) { - cmd := exec.Command(GovcCmd, args...) - - log.Debugf("executing: %v %v", GovcCmd, strings.Join(args, " ")) - - var stdout bytes.Buffer - var stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - return stdout.String(), stderr.String(), err -} diff --git a/drivers/vmwarevsphere/vc_conn.go b/drivers/vmwarevsphere/vc_conn.go deleted file mode 100644 index 67c665966d..0000000000 --- a/drivers/vmwarevsphere/vc_conn.go +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. - */ - -package vmwarevsphere - -import ( - "fmt" - "strconv" - "strings" - - log "github.com/Sirupsen/logrus" - "github.com/docker/machine/drivers/vmwarevsphere/errors" -) - -type VcConn struct { - driver *Driver -} - -func NewVcConn(driver *Driver) VcConn { - return VcConn{driver: driver} -} - -func (conn VcConn) DatastoreLs(path string) (string, error) { - args := []string{"datastore.ls"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, path) - stdout, stderr, err := govcOutErr(args...) - if stderr == "" && err == nil { - return stdout, nil - } - return "", errors.NewDatastoreError(conn.driver.Datastore, "ls", stderr) -} - -func (conn VcConn) DatastoreMkdir(dirName string) error { - _, err := conn.DatastoreLs(dirName) - if err == nil { - return nil - } - - log.Infof("Creating directory %s on datastore %s of vCenter %s... ", - dirName, conn.driver.Datastore, conn.driver.IP) - - args := []string{"datastore.mkdir"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, dirName) - _, stderr, err := govcOutErr(args...) - if stderr == "" && err == nil { - return nil - } else { - return errors.NewDatastoreError(conn.driver.Datastore, "mkdir", stderr) - } -} - -func (conn VcConn) DatastoreUpload(localPath string) error { - stdout, err := conn.DatastoreLs(DATASTORE_DIR) - if err == nil && strings.Contains(stdout, B2D_ISO_NAME) { - log.Infof("boot2docker ISO already uploaded, skipping upload... ") - return nil - } - - log.Infof("Uploading %s to %s on datastore %s of vCenter %s... ", - localPath, DATASTORE_DIR, conn.driver.Datastore, conn.driver.IP) - - dsPath := fmt.Sprintf("%s/%s", DATASTORE_DIR, B2D_ISO_NAME) - args := []string{"datastore.upload"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, localPath) - args = append(args, dsPath) - _, stderr, err := govcOutErr(args...) - if stderr == "" && err == nil { - return nil - } else { - return errors.NewDatastoreError(conn.driver.Datacenter, "upload", stderr) - } -} - -func (conn VcConn) VmInfo() (string, error) { - args := []string{"vm.info"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, conn.driver.MachineName) - - stdout, stderr, err := govcOutErr(args...) - if strings.Contains(stdout, "Name") && stderr == "" && err == nil { - return stdout, nil - } else { - return "", errors.NewVmError("find", conn.driver.MachineName, "VM not found") - } -} - -func (conn VcConn) VmCreate(isoPath string) error { - log.Infof("Creating virtual machine %s of vCenter %s... ", - conn.driver.MachineName, conn.driver.IP) - - args := []string{"vm.create"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--net=%s", conn.driver.Network)) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) - args = append(args, fmt.Sprintf("--iso=%s", isoPath)) - memory := strconv.Itoa(conn.driver.Memory) - args = append(args, fmt.Sprintf("--m=%s", memory)) - cpu := strconv.Itoa(conn.driver.CPU) - args = append(args, fmt.Sprintf("--c=%s", cpu)) - args = append(args, "--disk.controller=scsi") - args = append(args, "--on=false") - if conn.driver.Pool != "" { - args = append(args, fmt.Sprintf("--pool=%s", conn.driver.Pool)) - } - if conn.driver.HostIP != "" { - args = append(args, fmt.Sprintf("--host.ip=%s", conn.driver.HostIP)) - } - args = append(args, conn.driver.MachineName) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewVmError("create", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) VmPowerOn() error { - log.Infof("Powering on virtual machine %s of vCenter %s... ", - conn.driver.MachineName, conn.driver.IP) - - args := []string{"vm.power"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, "-on") - args = append(args, conn.driver.MachineName) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewVmError("power on", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) VmPowerOff() error { - log.Infof("Powering off virtual machine %s of vCenter %s... ", - conn.driver.MachineName, conn.driver.IP) - - args := []string{"vm.power"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, "-off") - args = append(args, conn.driver.MachineName) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewVmError("power on", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) VmDestroy() error { - log.Infof("Deleting virtual machine %s of vCenter %s... ", - conn.driver.MachineName, conn.driver.IP) - - args := []string{"vm.destroy"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, conn.driver.MachineName) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewVmError("delete", conn.driver.MachineName, stderr) - } - -} - -func (conn VcConn) VmDiskCreate() error { - args := []string{"vm.disk.create"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) - args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) - args = append(args, fmt.Sprintf("--name=%s", conn.driver.MachineName)) - diskSize := strconv.Itoa(conn.driver.DiskSize) - args = append(args, fmt.Sprintf("--size=%sMiB", diskSize)) - - _, stderr, err := govcOutErr(args...) - if stderr == "" && err == nil { - return nil - } else { - return errors.NewVmError("add network", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) VmAttachNetwork() error { - args := []string{"vm.network.add"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) - args = append(args, fmt.Sprintf("--net=%s", conn.driver.Network)) - - _, stderr, err := govcOutErr(args...) - if stderr == "" && err == nil { - return nil - } else { - return errors.NewVmError("add network", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) VmFetchIp() (string, error) { - args := []string{"vm.ip"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, conn.driver.MachineName) - stdout, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return stdout, nil - } else { - return "", errors.NewVmError("fetching IP", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) GuestMkdir(guestUser, guestPass, dirName string) error { - args := []string{"guest.mkdir"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) - args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) - args = append(args, "-p") - args = append(args, dirName) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewGuestError("mkdir", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) GuestUpload(guestUser, guestPass, localPath, remotePath string) error { - args := []string{"guest.upload"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) - args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) - args = append(args, "-f") - args = append(args, localPath) - args = append(args, remotePath) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewGuestError("upload", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) GuestDownload(guestUser, guestPass, remotePath, localPath string) error { - args := []string{"guest.download"} - args = conn.AppendConnectionString(args) - args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) - args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) - args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) - args = append(args, remotePath) - args = append(args, localPath) - _, stderr, err := govcOutErr(args...) - - if stderr == "" && err == nil { - return nil - } else { - return errors.NewGuestError("download", conn.driver.MachineName, stderr) - } -} - -func (conn VcConn) AppendConnectionString(args []string) []string { - args = append(args, fmt.Sprintf("--u=%s:%s@%s", conn.driver.Username, conn.driver.Password, conn.driver.IP)) - args = append(args, "--k=true") - return args -} diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index 9a35f4a0d3..9ad81de677 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -5,322 +5,711 @@ package vmwarevsphere import ( + "archive/tar" + "encoding/base64" "fmt" - "io" "io/ioutil" - "net/http" + "net" + "net/url" "os" - "os/exec" - "path" - "path/filepath" "strings" + "time" - log "github.com/Sirupsen/logrus" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" - "github.com/codegangsta/cli" - "github.com/docker/machine/drivers" - "github.com/docker/machine/drivers/vmwarevsphere/errors" - "github.com/docker/machine/ssh" - "github.com/docker/machine/state" - "github.com/docker/machine/utils" - cssh "golang.org/x/crypto/ssh" + "errors" + + "github.com/vmware/govmomi" + "github.com/vmware/govmomi/find" + "github.com/vmware/govmomi/guest" + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" ) const ( - DATASTORE_DIR = "boot2docker-iso" - B2D_ISO_NAME = "boot2docker.iso" - DEFAULT_CPU_NUMBER = 2 - dockerConfigDir = "/var/lib/boot2docker" - B2D_USER = "docker" - B2D_PASS = "tcuser" + // dockerBridgeIP is the default IP address of the docker0 bridge. + dockerBridgeIP = "172.17.0.1" + isoFilename = "boot2docker.iso" + // B2DUser is the guest User for tools login + B2DUser = "docker" + // B2DPass is the guest Pass for tools login + B2DPass = "tcuser" ) type Driver struct { - MachineName string - SSHPort int - CPU int + *drivers.BaseDriver Memory int DiskSize int - Boot2DockerURL string - IP string - Username string - Password string - Network string - Datastore string - Datacenter string - Pool string - HostIP string - StorePath string + CPU int ISO string - CaCertPath string - PrivateKeyPath string + Boot2DockerURL string + CPUS int - storePath string -} + IP string + Port int + Username string + Password string + Network string + Networks []string + Datastore string + Datacenter string + Folder string + Pool string + HostSystem string + CfgParams []string + CloudInit string -type CreateFlags struct { - CPU *int - Memory *int - DiskSize *int - Boot2DockerURL *string - IP *string - Username *string - Password *string - Network *string - Datastore *string - Datacenter *string - Pool *string - HostIP *string + SSHPassword string } -func init() { - drivers.Register("vmwarevsphere", &drivers.RegisteredDriver{ - New: NewDriver, - GetCreateFlags: GetCreateFlags, - }) -} +const ( + defaultSSHUser = B2DUser + defaultSSHPass = B2DPass + defaultCpus = 2 + defaultMemory = 2048 + defaultDiskSize = 20480 + defaultSDKPort = 443 +) // GetCreateFlags registers the flags this driver adds to -// "docker hosts create" -func GetCreateFlags() []cli.Flag { - return []cli.Flag{ - cli.IntFlag{ +// "docker-machine create" +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return []mcnflag.Flag{ + mcnflag.IntFlag{ EnvVar: "VSPHERE_CPU_COUNT", Name: "vmwarevsphere-cpu-count", Usage: "vSphere CPU number for docker VM", - Value: 2, + Value: defaultCpus, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "VSPHERE_MEMORY_SIZE", Name: "vmwarevsphere-memory-size", Usage: "vSphere size of memory for docker VM (in MB)", - Value: 2048, + Value: defaultMemory, }, - cli.IntFlag{ + mcnflag.IntFlag{ EnvVar: "VSPHERE_DISK_SIZE", Name: "vmwarevsphere-disk-size", Usage: "vSphere size of disk for docker VM (in MB)", - Value: 20000, + Value: defaultDiskSize, }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VSPHERE_BOOT2DOCKER_URL", Name: "vmwarevsphere-boot2docker-url", Usage: "vSphere URL for boot2docker image", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VSPHERE_VCENTER", Name: "vmwarevsphere-vcenter", Usage: "vSphere IP/hostname for vCenter", }, - cli.StringFlag{ + mcnflag.IntFlag{ + EnvVar: "VSPHERE_VCENTER_PORT", + Name: "vmwarevsphere-vcenter-port", + Usage: "vSphere Port for vCenter", + Value: defaultSDKPort, + }, + mcnflag.StringFlag{ EnvVar: "VSPHERE_USERNAME", Name: "vmwarevsphere-username", Usage: "vSphere username", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VSPHERE_PASSWORD", Name: "vmwarevsphere-password", Usage: "vSphere password", }, - cli.StringFlag{ + mcnflag.StringSliceFlag{ EnvVar: "VSPHERE_NETWORK", Name: "vmwarevsphere-network", Usage: "vSphere network where the docker VM will be attached", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VSPHERE_DATASTORE", Name: "vmwarevsphere-datastore", Usage: "vSphere datastore for docker VM", }, - cli.StringFlag{ + mcnflag.StringFlag{ EnvVar: "VSPHERE_DATACENTER", Name: "vmwarevsphere-datacenter", Usage: "vSphere datacenter for docker VM", }, - cli.StringFlag{ + mcnflag.StringFlag{ + EnvVar: "VSPHERE_FOLDER", + Name: "vmwarevsphere-folder", + Usage: "vSphere folder for the docker VM. This folder must already exist in the datacenter.", + }, + mcnflag.StringFlag{ EnvVar: "VSPHERE_POOL", Name: "vmwarevsphere-pool", Usage: "vSphere resource pool for docker VM", }, - cli.StringFlag{ - EnvVar: "VSPHERE_COMPUTE_IP", - Name: "vmwarevsphere-compute-ip", - Usage: "vSphere compute host IP where the docker VM will be instantiated", + mcnflag.StringFlag{ + EnvVar: "VSPHERE_HOSTSYSTEM", + Name: "vmwarevsphere-hostsystem", + Usage: "vSphere compute resource where the docker VM will be instantiated. This can be omitted if using a cluster with DRS.", + }, + mcnflag.StringSliceFlag{ + EnvVar: "VSPHERE_CFGPARAM", + Name: "vmwarevsphere-cfgparam", + Usage: "vSphere vm configuration parameters (used for guestinfo)", + }, + mcnflag.StringFlag{ + EnvVar: "VSPHERE_CLOUDINIT", + Name: "vmwarevsphere-cloudinit", + Usage: "vSphere cloud-init file or url to set in the guestinfo", + }, + } +} + +func NewDriver(hostName, storePath string) drivers.Driver { + return &Driver{ + CPUS: defaultCpus, + Memory: defaultMemory, + DiskSize: defaultDiskSize, + SSHPassword: defaultSSHPass, + Port: defaultSDKPort, + BaseDriver: &drivers.BaseDriver{ + SSHUser: defaultSSHUser, + MachineName: hostName, + StorePath: storePath, }, } } -func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - return &Driver{MachineName: machineName, StorePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() } +func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + + return d.SSHUser +} + +// DriverName returns the name of the driver func (d *Driver) DriverName() string { return "vmwarevsphere" } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.SSHUser = "docker" d.SSHPort = 22 d.CPU = flags.Int("vmwarevsphere-cpu-count") d.Memory = flags.Int("vmwarevsphere-memory-size") d.DiskSize = flags.Int("vmwarevsphere-disk-size") d.Boot2DockerURL = flags.String("vmwarevsphere-boot2docker-url") d.IP = flags.String("vmwarevsphere-vcenter") + d.Port = flags.Int("vmwarevsphere-vcenter-port") d.Username = flags.String("vmwarevsphere-username") d.Password = flags.String("vmwarevsphere-password") - d.Network = flags.String("vmwarevsphere-network") + d.Networks = flags.StringSlice("vmwarevsphere-network") d.Datastore = flags.String("vmwarevsphere-datastore") d.Datacenter = flags.String("vmwarevsphere-datacenter") + // Sanitize input on ingress. + d.Folder = strings.Trim(flags.String("vmwarevsphere-folder"), "/") d.Pool = flags.String("vmwarevsphere-pool") - d.HostIP = flags.String("vmwarevsphere-compute-ip") + d.HostSystem = flags.String("vmwarevsphere-hostsystem") + d.CfgParams = flags.StringSlice("vmwarevsphere-cfgparam") + d.CloudInit = flags.String("vmwarevsphere-cloudinit") + d.SetSwarmConfigFromFlags(flags) - d.ISO = path.Join(d.storePath, "boot2docker.iso") + d.ISO = d.ResolveStorePath(isoFilename) return nil } func (d *Driver) GetURL() (string, error) { - ip, _ := d.GetIP() + + ip, err := d.GetIP() + if err != nil { + return "", err + } if ip == "" { return "", nil } - return fmt.Sprintf("tcp://%s:2376", ip), nil + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil } func (d *Driver) GetIP() (string, error) { status, err := d.GetState() if status != state.Running { - return "", errors.NewInvalidStateError(d.MachineName) + return "", drivers.ErrHostIsNotRunning + } + + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := d.vsphereLogin(ctx) + if err != nil { + return "", err + } + defer c.Logout(ctx) + + vm, err := d.fetchVM(ctx, c, d.MachineName) + if err != nil { + return "", err } - vcConn := NewVcConn(d) - rawIp, err := vcConn.VmFetchIp() + + configuredMacIPs, err := vm.WaitForNetIP(ctx, false) if err != nil { return "", err } - ip := strings.Trim(strings.Split(rawIp, "\n")[0], " ") - return ip, nil + + for _, ips := range configuredMacIPs { + if len(ips) >= 0 { + // Prefer IPv4 address, but fall back to first/IPv6 + preferredIP := ips[0] + for _, ip := range ips { + // In addition to non IPv4 addresses, try to filter + // out link local addresses and the default address of + // the Docker0 bridge + netIP := net.ParseIP(ip) + if netIP.To4() != nil && netIP.IsGlobalUnicast() && !netIP.Equal(net.ParseIP(dockerBridgeIP)) { + preferredIP = ip + break + } + } + return preferredIP, nil + } + } + + return "", errors.New("No IP despite waiting for one - check DHCP status") } func (d *Driver) GetState() (state.State, error) { - vcConn := NewVcConn(d) - stdout, err := vcConn.VmInfo() + + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := d.vsphereLogin(ctx) if err != nil { return state.None, err } + defer c.Logout(ctx) - if strings.Contains(stdout, "poweredOn") { + vm, err := d.fetchVM(ctx, c, d.MachineName) + if err != nil { + return state.None, err + } + + var mvm mo.VirtualMachine + + err = c.RetrieveOne(ctx, vm.Reference(), nil, &mvm) + if err != nil { + return state.None, nil + } + + s := mvm.Summary + + if strings.Contains(string(s.Runtime.PowerState), "poweredOn") { return state.Running, nil - } else if strings.Contains(stdout, "poweredOff") { + } else if strings.Contains(string(s.Runtime.PowerState), "poweredOff") { return state.Stopped, nil } return state.None, nil } +// PreCreateCheck checks that the machine creation process can be started safely. func (d *Driver) PreCreateCheck() error { + log.Debug("Connecting to vSphere for pre-create checks...") + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := d.vsphereLogin(ctx) + if err != nil { + return err + } + defer c.Logout(ctx) + + // Create a new finder + f := find.NewFinder(c.Client, true) + + dc, err := f.DatacenterOrDefault(ctx, d.Datacenter) + if err != nil { + return err + } + + f.SetDatacenter(dc) + + // Folder + if d.Folder != "" { + // Find the specified Folder to create the VM in. + folders, err := dc.Folders(ctx) + if err != nil { + return err + } + folder, err := f.Folder(ctx, fmt.Sprintf("%s/%s", folders.VmFolder.InventoryPath, d.Folder)) + // It's an error to not find the folder, or for the search itself to fail. + if err != nil { + // The search itself failed. + return err + } + if folder == nil { + return fmt.Errorf("failed to find VM Folder '%s'", d.Folder) + } + } + + if _, err := f.DatastoreOrDefault(ctx, d.Datastore); err != nil { + return err + } + + // TODO: if the user has both the VSPHERE_NETWORK defined and adds --vmwarevsphere-network + // both are used at the same time - probably should detect that and remove the one from ENV + if len(d.Networks) == 0 { + // machine assumes there will be a network + d.Networks = append(d.Networks, "VM Network") + } + for _, netName := range d.Networks { + if _, err := f.NetworkOrDefault(ctx, netName); err != nil { + return err + } + } + // d.Network needs to remain a string to cope with existing machines :/ + d.Network = d.Networks[0] + + var hs *object.HostSystem + if d.HostSystem != "" { + var err error + hs, err = f.HostSystemOrDefault(ctx, d.HostSystem) + if err != nil { + return err + } + } + + // ResourcePool + if d.Pool != "" { + // Find specified Resource Pool + if _, err := f.ResourcePool(ctx, d.Pool); err != nil { + return err + } + } else if hs != nil { + // Pick default Resource Pool for Host System + if _, err := hs.ResourcePool(ctx); err != nil { + return err + } + } else { + // Pick the default Resource Pool for the Datacenter. + if _, err := f.DefaultResourcePool(ctx); err != nil { + return err + } + } + return nil } -// the current implementation does the following: +// Create has the following implementation: // 1. check whether the docker directory contains the boot2docker ISO -// 2. generate an SSH keypair +// 2. generate an SSH keypair and bundle it in a tar. // 3. create a virtual machine with the boot2docker ISO mounted; // 4. reconfigure the virtual machine network and disk size; func (d *Driver) Create() error { - if err := d.checkVsphereConfig(); err != nil { + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { + return err + } + + log.Infof("Generating SSH Keypair...") + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } - var ( - isoURL string - err error - ) + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - if d.Boot2DockerURL != "" { - isoURL = d.Boot2DockerURL - log.Infof("Downloading boot2docker.iso from %s...", isoURL) - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { + c, err := d.vsphereLogin(ctx) + if err != nil { + return err + } + defer c.Logout(ctx) + + // Create a new finder + f := find.NewFinder(c.Client, true) + + dc, err := f.DatacenterOrDefault(ctx, d.Datacenter) + if err != nil { + return err + } + + f.SetDatacenter(dc) + + dss, err := f.DatastoreOrDefault(ctx, d.Datastore) + if err != nil { + return err + } + + networks := make(map[string]object.NetworkReference) + for _, netName := range d.Networks { + net, err := f.NetworkOrDefault(ctx, netName) + if err != nil { + return err + } + networks[netName] = net + } + + var hs *object.HostSystem + if d.HostSystem != "" { + var err error + hs, err = f.HostSystemOrDefault(ctx, d.HostSystem) + if err != nil { + return err + } + } + + var rp *object.ResourcePool + if d.Pool != "" { + // Find specified Resource Pool + rp, err = f.ResourcePool(ctx, d.Pool) + if err != nil { + return err + } + } else if d.HostSystem != "" { + // Pick default Resource Pool for Host System + rp, err = hs.ResourcePool(ctx) + if err != nil { return err } } else { - // todo: check latest release URL, download if it's new - // until then always use "latest" - isoURL, err = utils.GetLatestBoot2DockerReleaseURL() + // Pick the default Resource Pool for the Datacenter. + rp, err = f.DefaultResourcePool(ctx) if err != nil { return err } + } - rootPath := utils.GetDockerDir() - imgPath := filepath.Join(rootPath, "images") - commonIsoPath := filepath.Join(imgPath, "boot2docker.iso") - if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) { - log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath) + spec := types.VirtualMachineConfigSpec{ + Name: d.MachineName, + GuestId: "otherLinux64Guest", + Files: &types.VirtualMachineFileInfo{VmPathName: fmt.Sprintf("[%s]", dss.Name())}, + NumCPUs: int32(d.CPU), + MemoryMB: int64(d.Memory), + } - // just in case boot2docker.iso has been manually deleted - if _, err := os.Stat(imgPath); os.IsNotExist(err) { - if err := os.Mkdir(imgPath, 0700); err != nil { - return err - } - } + scsi, err := object.SCSIControllerTypes().CreateSCSIController("pvscsi") + if err != nil { + return err + } - if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { - return err - } - } + spec.DeviceChange = append(spec.DeviceChange, &types.VirtualDeviceConfigSpec{ + Operation: types.VirtualDeviceConfigSpecOperationAdd, + Device: scsi, + }) - isoDest := filepath.Join(d.storePath, "boot2docker.iso") - if err := utils.CopyFile(commonIsoPath, isoDest); err != nil { + log.Infof("Creating VM...") + folders, err := dc.Folders(ctx) + folder := folders.VmFolder + if d.Folder != "" { + folder, err = f.Folder(ctx, fmt.Sprintf("%s/%s", folders.VmFolder.InventoryPath, d.Folder)) + if err != nil { return err } } + task, err := folder.CreateVM(ctx, spec, rp, hs) + if err != nil { + return err + } - log.Infof("Generating SSH Keypair...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + info, err := task.WaitForResult(ctx, nil) + if err != nil { return err } - vcConn := NewVcConn(d) log.Infof("Uploading Boot2docker ISO ...") - if err := vcConn.DatastoreMkdir(DATASTORE_DIR); err != nil { + dsurl, err := dss.URL(ctx, dc, fmt.Sprintf("%s/%s", d.MachineName, isoFilename)) + if err != nil { return err } + p := soap.DefaultUpload + if err = c.Client.UploadFile(d.ISO, dsurl, &p); err != nil { + return err + } + + // Retrieve the new VM + vm := object.NewVirtualMachine(c.Client, info.Result.(types.ManagedObjectReference)) - if _, err := os.Stat(d.ISO); os.IsNotExist(err) { - log.Errorf("Unable to find boot2docker ISO at %s", d.ISO) - return errors.NewIncompleteVsphereConfigError(d.ISO) + devices, err := vm.Device(ctx) + if err != nil { + return err } - if err := vcConn.DatastoreUpload(d.ISO); err != nil { + var add []types.BaseVirtualDevice + + controller, err := devices.FindDiskController("scsi") + if err != nil { return err } - isoPath := fmt.Sprintf("%s/%s", DATASTORE_DIR, B2D_ISO_NAME) - if err := vcConn.VmCreate(isoPath); err != nil { + disk := devices.CreateDisk(controller, dss.Reference(), + dss.Path(fmt.Sprintf("%s/%s.vmdk", d.MachineName, d.MachineName))) + + // Convert MB to KB + disk.CapacityInKB = int64(d.DiskSize) * 1024 + + add = append(add, disk) + ide, err := devices.FindIDEController("") + if err != nil { return err } - log.Infof("Configuring the virtual machine %s... ", d.MachineName) - if err := vcConn.VmDiskCreate(); err != nil { + cdrom, err := devices.CreateCdrom(ide) + if err != nil { return err } - if err := vcConn.VmAttachNetwork(); err != nil { + add = append(add, devices.InsertIso(cdrom, dss.Path(fmt.Sprintf("%s/%s", d.MachineName, isoFilename)))) + + for _, netName := range d.Networks { + backing, err := networks[netName].EthernetCardBackingInfo(ctx) + if err != nil { + return err + } + + netdev, err := object.EthernetCardTypes().CreateEthernetCard("vmxnet3", backing) + if err != nil { + return err + } + + log.Infof("adding network: %s", netName) + add = append(add, netdev) + } + + log.Infof("Reconfiguring VM") + if vm.AddDevice(ctx, add...); err != nil { return err } - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) + // Adding some guestinfo data + var opts []types.BaseOptionValue + for _, param := range d.CfgParams { + v := strings.SplitN(param, "=", 2) + key := v[0] + value := "" + if len(v) > 1 { + value = v[1] + } + fmt.Printf("Setting %s to %s\n", key, value) + opts = append(opts, &types.OptionValue{ + Key: key, + Value: value, + }) + } + if d.CloudInit != "" { + if _, err := url.ParseRequestURI(d.CloudInit); err == nil { + log.Infof("setting guestinfo.cloud-init.data.url to %s\n", d.CloudInit) + opts = append(opts, &types.OptionValue{ + Key: "guestinfo.cloud-init.config.url", + Value: d.CloudInit, + }) + } else { + if _, err := os.Stat(d.CloudInit); err == nil { + if value, err := ioutil.ReadFile(d.CloudInit); err == nil { + log.Infof("setting guestinfo.cloud-init.data to encoded content of %s\n", d.CloudInit) + encoded := base64.StdEncoding.EncodeToString(value) + opts = append(opts, &types.OptionValue{ + Key: "guestinfo.cloud-init.config.data", + Value: encoded, + }) + opts = append(opts, &types.OptionValue{ + Key: "guestinfo.cloud-init.data.encoding", + Value: "base64", + }) + } + } + } + } + + task, err = vm.Reconfigure(ctx, types.VirtualMachineConfigSpec{ + ExtraConfig: opts, + }) if err != nil { return err } - if err := cmd.Run(); err != nil { + task.Wait(ctx) + + if err := d.Start(); err != nil { return err } - if err := d.Start(); err != nil { + log.Infof("Provisioning certs and ssh keys...") + // Generate a tar keys bundle + if err := d.generateKeyBundle(); err != nil { + return err + } + + opman := guest.NewOperationsManager(c.Client, vm.Reference()) + + fileman, err := opman.FileManager(ctx) + if err != nil { + return err + } + + src := d.ResolveStorePath("userdata.tar") + s, err := os.Stat(src) + if err != nil { + return err + } + + auth := AuthFlag{} + flag := FileAttrFlag{} + auth.auth.Username = B2DUser + auth.auth.Password = B2DPass + flag.SetPerms(0, 0, 660) + url, err := fileman.InitiateFileTransferToGuest(ctx, auth.Auth(), "/home/docker/userdata.tar", flag.Attr(), s.Size(), true) + if err != nil { + return err + } + u, err := c.Client.ParseURL(url) + if err != nil { + return err + } + if err = c.Client.UploadFile(src, u, nil); err != nil { + return err + } + + procman, err := opman.ProcessManager(ctx) + if err != nil { + return err + } + + // first, untar - only boot2docker has /var/lib/boot2docker + // TODO: don't hard-code to docker & staff - they are also just b2d + var env []string + guestspec := types.GuestProgramSpec{ + ProgramPath: "/usr/bin/sudo", + Arguments: "/usr/bin/sudo /bin/sh -c \"tar xvf /home/docker/userdata.tar -C /home/docker > /var/log/userdata.log 2>&1 && chown -R docker:staff /home/docker\"", + WorkingDirectory: "", + EnvVariables: env, + } + + _, err = procman.StartProgram(ctx, auth.Auth(), &guestspec) + if err != nil { + return err + } + + // now move to /var/lib/boot2docker if its there + guestspec = types.GuestProgramSpec{ + ProgramPath: "/usr/bin/sudo", + Arguments: "/bin/mv /home/docker/userdata.tar /var/lib/boot2docker/userdata.tar", + WorkingDirectory: "", + EnvVariables: env, + } + + _, err = procman.StartProgram(ctx, auth.Auth(), &guestspec) + if err != nil { return err } @@ -339,82 +728,60 @@ func (d *Driver) Start() error { return nil case state.Stopped: // TODO add transactional or error handling in the following steps - vcConn := NewVcConn(d) - err := vcConn.VmPowerOn() - if err != nil { - return err - } - // this step waits for the vm to start and fetch its ip address; - // this guarantees that the opem-vmtools has started working... - _, err = vcConn.VmFetchIp() - if err != nil { - return err - } + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - log.Infof("Configuring virtual machine %s... ", d.MachineName) - - key, err := ioutil.ReadFile(d.publicSSHKeyPath()) + c, err := d.vsphereLogin(ctx) if err != nil { return err } + defer c.Logout(ctx) - // so, vmrun above will not work without vmtools in b2d. since getting stuff into TCL - // is much more painful, we simply use the b2d password to get the initial public key - // onto the machine. from then on we use the pub key. meh. - sshConfig := &cssh.ClientConfig{ - User: B2D_USER, - Auth: []cssh.AuthMethod{ - cssh.Password(B2D_PASS), - }, - } - - ip, err := d.GetIP() + vm, err := d.fetchVM(ctx, c, d.MachineName) if err != nil { return err } - sshClient, err := cssh.Dial("tcp", fmt.Sprintf("%s:22", ip), sshConfig) + task, err := vm.PowerOn(ctx) if err != nil { return err } - session, err := sshClient.NewSession() + + _, err = task.WaitForResult(ctx, nil) if err != nil { return err } - if err := session.Run(fmt.Sprintf("mkdir /home/docker/.ssh && echo \"%s\" > /home/docker/.ssh/authorized_keys", string(key))); err != nil { + + log.Infof("Waiting for VMware Tools to come online...") + if d.IPAddress, err = d.GetIP(); err != nil { return err } - session.Close() - - return nil } - return errors.NewInvalidStateError(d.MachineName) + return nil } func (d *Driver) Stop() error { - vcConn := NewVcConn(d) - err := vcConn.VmPowerOff() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := d.vsphereLogin(ctx) if err != nil { return err } - return err -} + defer c.Logout(ctx) -func (d *Driver) Remove() error { - machineState, err := d.GetState() + vm, err := d.fetchVM(ctx, c, d.MachineName) if err != nil { return err } - if machineState == state.Running { - if err = d.Stop(); err != nil { - return fmt.Errorf("can't stop VM: %s", err) - } - } - vcConn := NewVcConn(d) - err = vcConn.VmDestroy() - if err != nil { + + if err := vm.ShutdownGuest(ctx); err != nil { return err } + + d.IPAddress = "" + return nil } @@ -422,110 +789,252 @@ func (d *Driver) Restart() error { if err := d.Stop(); err != nil { return err } + + // Check for 120 seconds for the machine to stop + for i := 1; i <= 60; i++ { + machineState, err := d.GetState() + if err != nil { + return err + } + if machineState == state.Running { + log.Debugf("Not there yet %d/%d", i, 60) + time.Sleep(2 * time.Second) + continue + } + if machineState == state.Stopped { + break + } + } + + machineState, err := d.GetState() + // If the VM is still running after 120 seconds just kill it. + if machineState == state.Running { + if err = d.Kill(); err != nil { + return fmt.Errorf("can't stop VM: %s", err) + } + } + return d.Start() } func (d *Driver) Kill() error { - return d.Stop() -} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := d.vsphereLogin(ctx) + if err != nil { + return err + } + defer c.Logout(ctx) -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") + vm, err := d.fetchVM(ctx, c, d.MachineName) + if err != nil { + return err + } - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") + task, err := vm.PowerOff(ctx) if err != nil { return err } - if err := cmd.Run(); err != nil { + + _, err = task.WaitForResult(ctx, nil) + if err != nil { return err } + d.IPAddress = "" + return nil } -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") +func (d *Driver) Remove() error { + machineState, err := d.GetState() + if err != nil { + return err + } + if machineState == state.Running { + if err = d.Kill(); err != nil { + return fmt.Errorf("can't stop VM: %s", err) + } + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker stop") + c, err := d.vsphereLogin(ctx) if err != nil { return err } - if err := cmd.Run(); err != nil { + defer c.Logout(ctx) + + // Create a new finder + f := find.NewFinder(c.Client, true) + + dc, err := f.DatacenterOrDefault(ctx, d.Datacenter) + if err != nil { return err } - return nil -} + f.SetDatacenter(dc) -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} + dss, err := f.DatastoreOrDefault(ctx, d.Datastore) + if err != nil { + return err + } -func (d *Driver) Upgrade() error { - return fmt.Errorf("upgrade is not supported for vsphere driver at this moment") -} + // Remove B2D Iso from VM folder + m := object.NewFileManager(c.Client) + task, err := m.DeleteDatastoreFile(ctx, dss.Path(fmt.Sprintf("%s/%s", d.MachineName, isoFilename)), dc) + if err != nil { + return err + } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() + err = task.Wait(ctx) if err != nil { - return nil, err + if types.IsFileNotFound(err) { + // Ignore error + return nil + } + } + + vm, err := d.fetchVM(ctx, c, d.MachineName) + if err != nil { + return err + } + + task, err = vm.Destroy(ctx) + if err != nil { + return err + } + + _, err = task.WaitForResult(ctx, nil) + if err != nil { + return err } - return ssh.GetSSHCommand(ip, d.SSHPort, "docker", d.sshKeyPath(), args...), nil + return nil } -func (d *Driver) sshKeyPath() string { - return filepath.Join(d.StorePath, "id_docker_host_vsphere") +func (d *Driver) Upgrade() error { + return fmt.Errorf("upgrade is not supported for vsphere driver at this moment") } func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } -func (d *Driver) checkVsphereConfig() error { - if d.IP == "" { - return errors.NewIncompleteVsphereConfigError("vSphere IP") +// Make a boot2docker userdata.tar key bundle +func (d *Driver) generateKeyBundle() error { + log.Debugf("Creating Tar key bundle...") + + magicString := "boot2docker, this is vmware speaking" + + tf, err := os.Create(d.ResolveStorePath("userdata.tar")) + if err != nil { + return err + } + defer tf.Close() + var fileWriter = tf + + tw := tar.NewWriter(fileWriter) + defer tw.Close() + + // magicString first so we can figure out who originally wrote the tar. + file := &tar.Header{Name: magicString, Size: int64(len(magicString))} + if err := tw.WriteHeader(file); err != nil { + return err } - if d.Username == "" { - return errors.NewIncompleteVsphereConfigError("vSphere username") + if _, err := tw.Write([]byte(magicString)); err != nil { + return err } - if d.Password == "" { - return errors.NewIncompleteVsphereConfigError("vSphere password") + // .ssh/key.pub => authorized_keys + file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700} + if err := tw.WriteHeader(file); err != nil { + return err } - if d.Network == "" { - return errors.NewIncompleteVsphereConfigError("vSphere network") + pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) + if err != nil { + return err } - if d.Datastore == "" { - return errors.NewIncompleteVsphereConfigError("vSphere datastore") + file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return err } - if d.Datacenter == "" { - return errors.NewIncompleteVsphereConfigError("vSphere datacenter") + if _, err := tw.Write([]byte(pubKey)); err != nil { + return err } - return nil + file = &tar.Header{Name: ".ssh/authorized_keys2", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return err + } + if _, err := tw.Write([]byte(pubKey)); err != nil { + return err + } + err = tw.Close() + return err } -// Download boot2docker ISO image for the given tag and save it at dest. -func downloadISO(dir, file, url string) error { - rsp, err := http.Get(url) +func (d *Driver) vsphereLogin(ctx context.Context) (*govmomi.Client, error) { + + // Parse URL from string + u, err := url.Parse(fmt.Sprintf("https://%s:%d/sdk", d.IP, d.Port)) if err != nil { - return err + return nil, err } - defer rsp.Body.Close() + // set username and password for the URL + u.User = url.UserPassword(d.Username, d.Password) - // Download to a temp file first then rename it to avoid partial download. - f, err := ioutil.TempFile(dir, file+".tmp") + // Connect and log in to ESX or vCenter + c, err := govmomi.NewClient(ctx, u, true) if err != nil { - return err + return nil, err } - defer os.Remove(f.Name()) - if _, err := io.Copy(f, rsp.Body); err != nil { - // TODO: display download progress? - return err + + return c, nil +} + +func (d *Driver) fetchVM(ctx context.Context, c *govmomi.Client, vmname string) (*object.VirtualMachine, error) { + + // Create a new finder + f := find.NewFinder(c.Client, true) + + var vm *object.VirtualMachine + var err error + + dc, err := f.DatacenterOrDefault(ctx, d.Datacenter) + if err != nil { + return vm, err } - if err := f.Close(); err != nil { - return err + + f.SetDatacenter(dc) + + vmPath := vmname + if d.Folder != "" { + vmPath = fmt.Sprintf("%s/%s", d.Folder, vmname) } - if err := os.Rename(f.Name(), path.Join(dir, file)); err != nil { - return err + vm, err = f.VirtualMachine(ctx, vmPath) + if err != nil { + return vm, err } - return nil + return vm, nil +} + +type AuthFlag struct { + auth types.NamePasswordAuthentication +} + +func (f *AuthFlag) Auth() types.BaseGuestAuthentication { + return &f.auth +} + +type FileAttrFlag struct { + types.GuestPosixFileAttributes +} + +func (f *FileAttrFlag) SetPerms(owner, group, perms int) { + f.OwnerId = int32(owner) + f.GroupId = int32(group) + f.Permissions = int64(perms) +} + +func (f *FileAttrFlag) Attr() types.BaseGuestFileAttributes { + return &f.GuestPosixFileAttributes } diff --git a/drivers/vmwarevsphere/vsphere_test.go b/drivers/vmwarevsphere/vsphere_test.go new file mode 100644 index 0000000000..d3d7af3aeb --- /dev/null +++ b/drivers/vmwarevsphere/vsphere_test.go @@ -0,0 +1,22 @@ +package vmwarevsphere + +import ( + "testing" + + "github.com/docker/machine/libmachine/drivers" + "github.com/stretchr/testify/assert" +) + +func TestSetConfigFromFlags(t *testing.T) { + driver := NewDriver("default", "path") + + checkFlags := &drivers.CheckDriverOptions{ + FlagsValues: map[string]interface{}{}, + CreateFlags: driver.GetCreateFlags(), + } + + err := driver.SetConfigFromFlags(checkFlags) + + assert.NoError(t, err) + assert.Empty(t, checkFlags.InvalidFlags) +} diff --git a/experimental/README.md b/experimental/README.md new file mode 100644 index 0000000000..633e33ada2 --- /dev/null +++ b/experimental/README.md @@ -0,0 +1,22 @@ +# Docker Machine Experimental Features + +Docker Machine’s experimental features gives you access to bleeding edge features. By identifying experimental features, you can try out features early and give feedback to the Docker Machine maintainers. In this way, we hope to refine our feature designs by exposing them earlier to real-world usage. + +This page describes the experimental features in Docker Machine. Docker Machine is currently in beta. Neither it nor its experimental features are ready for production use. + +The information below describes each feature and the Github pull requests and +issues associated with it. If necessary, links are provided to additional +documentation on an issue. As an active Docker user and community member, +please feel free to provide any feedback on these features you wish. + +## Current experimental features + +Currently, you can experiment with [migrating a Boot2Docker created VM to Docker Machine](b2d_migration.md). Also, consider reviewing our [rough plan for the migration](b2d_migration_tasks.md). + +Additional experimental features include support for Red Hat, Debian, CentOS, Fedora, and RancherOS as base OSes. These features have no separate feature documentation. We simply encourage you to try them. + +## How to comment on an experimental feature + +Each feature's documentation includes a list of proposal pull requests or PRs associated with the feature. If you want to comment on or suggest a change to a feature, please add it to the existing feature PR. + +Issues or problems with a feature? Inquire for help on the `#docker-machine` IRC channel or in on the [Docker Google group](https://groups.google.com/forum/#!forum/docker-user). diff --git a/experimental/b2d_migration.md b/experimental/b2d_migration.md new file mode 100644 index 0000000000..1fe85f9388 --- /dev/null +++ b/experimental/b2d_migration.md @@ -0,0 +1,62 @@ +# Migrate from Boot2Docker CLI to Docker Machine + +This guide explains migrating from the Boot2Docker CLI to Docker Machine. + +This guide assumes basic knowledge of the Boot2Docker CLI and Docker Machine. If you are not familiar, please review those docs prior to migrating. + +There are a few differences between the Boot2Docker CLI commands and Machine. Please review the table below for the Boot2Docker command and the corresponding Machine command. You can also see details on Machine commands in the official [Docker Machine Docs](http://docs.docker.com/machine/#subcommands). + +# Migrating + +In order to migrate a Boot2Docker VM to Docker Machine, you must have Docker Machine installed. If you do not have Docker Machine, please see the [install docs](http://docs.docker.com/machine/#installation) before proceeding. + +> Note: when migrating to Docker Machine, this will also update Docker to the latest stable version + +To migrate a Boot2Docker VM, run the following command where `` is the name of your Boot2Docker VM and `` is the name of the new Machine (i.e. `dev`): + +> To get the name of your Boot2Docker VM, use the `boot2docker config` command. Default: `boot2docker-vm`. + + docker-machine create -d virtualbox --virtualbox-import-boot2docker-vm + +> Note: this will stop the Boot2Docker VM in order to safely copy the virtual disk + +You should see output similar to the following: + + $> docker-machine create -d virtualbox --virtualbox-import-boot2docker-vm boot2docker-vm dev + INFO[0000] Creating VirtualBox VM... + INFO[0001] Starting VirtualBox VM... + INFO[0001] Waiting for VM to start... + INFO[0035] "dev" has been created and is now the active machine. + INFO[0035] To point your Docker client at it, run this in your shell: eval "$(docker-machine env dev)" + +You now should have a Machine that contains all of the Docker data from the Boot2Docker VM. See the Docker Machine [usage docs](http://docs.docker.com/machine/#getting-started-with-docker-machine-using-a-local-vm) for details on working with Machine. + +# Cleanup + +When migrating a Boot2Docker VM to Docker Machine the Boot2Docker VM is left intact. Once you have verified that all of your Docker data (containers, images, etc) are in the new Machine, you can remove the Boot2Docker VM using `boot2docker delete`. + +# Command Comparison + +| boot2docker cli | machine | machine description | +| --------------- | ----------- | -------------------------------------------------------------------------------------- | +| init | create | creates a new docker host | +| up | start | starts a stopped machine | +| ssh | ssh | runs a command or interactive ssh session on the machine | +| save | - | n/a | +| down | stop | stops a running machine | +| poweroff | stop | stops a running machine | +| reset | restart | restarts a running machine | +| config | inspect (*) | shows details about machine | +| status | ls (**) | shows a list of all machines | +| info | inspect (*) | shows details about machine | +| ip | url (***) | shows the Docker URL for the machine | +| shellinit | env | shows the environment configuration needed to configure the Docker CLI for the machine | +| delete | rm | removes a machine | +| download | - | | +| upgrade | upgrade | upgrades Docker on the machine to the latest stable release | + +\* provides similar functionality but not exact + +** `ls` will show all machines including their status + +*** the `url` command reports the entire Docker URL including the IP / Hostname diff --git a/experimental/b2d_migration_tasks.md b/experimental/b2d_migration_tasks.md new file mode 100644 index 0000000000..1e633635af --- /dev/null +++ b/experimental/b2d_migration_tasks.md @@ -0,0 +1,49 @@ + + +# Boot2Docker Migration + +This document is a rough guide to what will need to be completed to support +migrating from boot2docker-cli to Machine. It is not meant to be a user guide +but more so an internal guide to what we will want to support. + +## Existing Boot2Docker Instances + +We will need to import the disk to "migrate" the existing Docker data to the +new Machine. This should not be too much work as instead of creating the +virtual disk we will simply copy this one. From there, provisioning should +happen as normal (cert regeneration, option configuration, etc). + +## CLI + +Currently almost every b2d command has a comparable Machine command. I do not +feel we need to have the exact same naming but we will want to create a +migration user guide to inform the users of what is different. + +## Boot2Docker Host Alias + +Boot2Docker also modifies the local system host file to create a `boot2docker` +alias that can be used by the host system. We will need to decide if we want +to support this and, if so, how to implement. Perhaps local aliases for each +Machine name? + +## Installer and Initial Setup + +There is a Boot2Docker installer that assists the users in getting started. +It installs VirtualBox along with the b2d CLI. We will need something similar. +This will probably be part of a larger installation project with the various +Docker platform tools. + +## Updates + +Machine already supports the `upgrade` command to update the Machine instances. +I'm not sure if we want to add a mechanism to update the local Machine binary +and/or the Docker CLI binary as well. We will need to discuss. diff --git a/host.go b/host.go deleted file mode 100644 index 1a157b0a32..0000000000 --- a/host.go +++ /dev/null @@ -1,356 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net" - "net/url" - "os" - "path" - "path/filepath" - "regexp" - "strconv" - "strings" - "time" - - log "github.com/Sirupsen/logrus" - "github.com/docker/machine/drivers" - "github.com/docker/machine/utils" -) - -var ( - validHostNameChars = `[a-zA-Z0-9\-\.]` - validHostNamePattern = regexp.MustCompile(`^` + validHostNameChars + `+$`) - ErrInvalidHostname = errors.New("Invalid hostname specified") -) - -type Host struct { - Name string `json:"-"` - DriverName string - Driver drivers.Driver - CaCertPath string - ServerCertPath string - ServerKeyPath string - PrivateKeyPath string - ClientCertPath string - storePath string -} - -type DockerConfig struct { - EngineConfig string - EngineConfigPath string -} - -type hostConfig struct { - DriverName string -} - -func waitForDocker(addr string) error { - for { - conn, err := net.DialTimeout("tcp", addr, time.Second*5) - if err != nil { - time.Sleep(time.Second * 5) - continue - } - conn.Close() - break - } - return nil -} - -func NewHost(name, driverName, storePath, caCert, privateKey string) (*Host, error) { - driver, err := drivers.NewDriver(driverName, name, storePath, caCert, privateKey) - if err != nil { - return nil, err - } - return &Host{ - Name: name, - DriverName: driverName, - Driver: driver, - CaCertPath: caCert, - PrivateKeyPath: privateKey, - storePath: storePath, - }, nil -} - -func LoadHost(name string, storePath string) (*Host, error) { - if _, err := os.Stat(storePath); os.IsNotExist(err) { - return nil, fmt.Errorf("Host %q does not exist", name) - } - - host := &Host{Name: name, storePath: storePath} - if err := host.LoadConfig(); err != nil { - return nil, err - } - return host, nil -} - -func ValidateHostName(name string) (string, error) { - if !validHostNamePattern.MatchString(name) { - return name, ErrInvalidHostname - } - return name, nil -} - -func GenerateClientCertificate(caCertPath, privateKeyPath string) error { - var ( - org = "docker-machine" - bits = 2048 - ) - - clientCertPath := filepath.Join(utils.GetMachineDir(), "cert.pem") - clientKeyPath := filepath.Join(utils.GetMachineDir(), "key.pem") - - log.Debugf("generating client cert: %s", clientCertPath) - if err := utils.GenerateCert([]string{""}, clientCertPath, clientKeyPath, caCertPath, privateKeyPath, org, bits); err != nil { - return fmt.Errorf("error generating client cert: %s", err) - } - - return nil -} - -func (h *Host) ConfigureAuth() error { - d := h.Driver - - if d.DriverName() == "none" { - return nil - } - - ip, err := h.Driver.GetIP() - if err != nil { - return err - } - - serverCertPath := filepath.Join(h.storePath, "server.pem") - serverKeyPath := filepath.Join(h.storePath, "server-key.pem") - - org := h.Name - bits := 2048 - - log.Debugf("generating server cert: %s", serverCertPath) - - if err := utils.GenerateCert([]string{ip}, serverCertPath, serverKeyPath, h.CaCertPath, h.PrivateKeyPath, org, bits); err != nil { - return fmt.Errorf("error generating server cert: %s", err) - } - - if err := d.StopDocker(); err != nil { - return err - } - - cmd, err := d.GetSSHCommand(fmt.Sprintf("sudo mkdir -p %s", d.GetDockerConfigDir())) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - // upload certs and configure TLS auth - caCert, err := ioutil.ReadFile(h.CaCertPath) - if err != nil { - return err - } - - // due to windows clients, we cannot use filepath.Join as the paths - // will be mucked on the linux hosts - machineCaCertPath := path.Join(d.GetDockerConfigDir(), "ca.pem") - - serverCert, err := ioutil.ReadFile(serverCertPath) - if err != nil { - return err - } - machineServerCertPath := path.Join(d.GetDockerConfigDir(), "server.pem") - - serverKey, err := ioutil.ReadFile(serverKeyPath) - if err != nil { - return err - } - machineServerKeyPath := path.Join(d.GetDockerConfigDir(), "server-key.pem") - - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(caCert), machineCaCertPath)) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(serverKey), machineServerKeyPath)) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(serverCert), machineServerCertPath)) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - dockerUrl, err := h.Driver.GetURL() - if err != nil { - return err - } - u, err := url.Parse(dockerUrl) - if err != nil { - return err - } - dockerPort := 2376 - parts := strings.Split(u.Host, ":") - if len(parts) == 2 { - dPort, err := strconv.Atoi(parts[1]) - if err != nil { - return err - } - dockerPort = dPort - } - - cfg := h.generateDockerConfig(dockerPort, machineCaCertPath, machineServerKeyPath, machineServerCertPath) - - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", cfg.EngineConfig, cfg.EngineConfigPath)) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - if err := d.StartDocker(); err != nil { - return err - } - - return nil -} - -func (h *Host) generateDockerConfig(dockerPort int, caCertPath string, serverKeyPath string, serverCertPath string) *DockerConfig { - d := h.Driver - var ( - daemonOpts string - daemonOptsCfg string - daemonCfg string - ) - - // TODO @ehazlett: template? - defaultDaemonOpts := fmt.Sprintf(`--tlsverify \ ---tlscacert=%s \ ---tlskey=%s \ ---tlscert=%s`, caCertPath, serverKeyPath, serverCertPath) - - switch d.DriverName() { - case "virtualbox", "vmwarefusion", "vmwarevsphere": - daemonOpts = fmt.Sprintf("-H tcp://0.0.0.0:%d", dockerPort) - daemonOptsCfg = filepath.Join(d.GetDockerConfigDir(), "profile") - opts := fmt.Sprintf("%s %s", defaultDaemonOpts, daemonOpts) - daemonCfg = fmt.Sprintf(`EXTRA_ARGS='%s' -CACERT=%s -SERVERCERT=%s -SERVERKEY=%s -DOCKER_TLS=no`, opts, caCertPath, serverKeyPath, serverCertPath) - default: - daemonOpts = fmt.Sprintf("--host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:%d", dockerPort) - daemonOptsCfg = "/etc/default/docker" - opts := fmt.Sprintf("%s %s", defaultDaemonOpts, daemonOpts) - daemonCfg = fmt.Sprintf("export DOCKER_OPTS='%s'", opts) - } - - return &DockerConfig{ - EngineConfig: daemonCfg, - EngineConfigPath: daemonOptsCfg, - } -} - -func (h *Host) Create(name string) error { - name, err := ValidateHostName(name) - if err != nil { - return err - } - - if err := h.Driver.Create(); err != nil { - return err - } - - if err := h.SaveConfig(); err != nil { - return err - } - - return nil -} - -func (h *Host) Start() error { - return h.Driver.Start() -} - -func (h *Host) Stop() error { - return h.Driver.Stop() -} - -func (h *Host) Upgrade() error { - return h.Driver.Upgrade() -} - -func (h *Host) Remove(force bool) error { - if err := h.Driver.Remove(); err != nil { - if !force { - return err - } - } - return h.removeStorePath() -} - -func (h *Host) removeStorePath() error { - file, err := os.Stat(h.storePath) - if err != nil { - return err - } - if !file.IsDir() { - return fmt.Errorf("%q is not a directory", h.storePath) - } - return os.RemoveAll(h.storePath) -} - -func (h *Host) GetURL() (string, error) { - return h.Driver.GetURL() -} - -func (h *Host) LoadConfig() error { - data, err := ioutil.ReadFile(filepath.Join(h.storePath, "config.json")) - if err != nil { - return err - } - - // First pass: find the driver name and load the driver - var config hostConfig - if err := json.Unmarshal(data, &config); err != nil { - return err - } - - driver, err := drivers.NewDriver(config.DriverName, h.Name, h.storePath, h.CaCertPath, h.PrivateKeyPath) - if err != nil { - return err - } - h.Driver = driver - - // Second pass: unmarshal driver config into correct driver - if err := json.Unmarshal(data, &h); err != nil { - return err - } - - return nil -} - -func (h *Host) SaveConfig() error { - data, err := json.Marshal(h) - if err != nil { - return err - } - if err := ioutil.WriteFile(filepath.Join(h.storePath, "config.json"), data, 0600); err != nil { - return err - } - return nil -} diff --git a/host_test.go b/host_test.go deleted file mode 100644 index bc3baf7eb0..0000000000 --- a/host_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package main - -import ( - "fmt" - "regexp" - "strings" - "testing" - - _ "github.com/docker/machine/drivers/none" -) - -func TestValidateHostnameValid(t *testing.T) { - hosts := []string{ - "zomg", - "test-ing", - "some.h0st", - } - - for _, v := range hosts { - h, err := ValidateHostName(v) - if err != nil { - t.Fatal("Invalid hostname") - } - - if h != v { - t.Fatal("Hostname doesn't match") - } - } -} - -func TestValidateHostnameInvalid(t *testing.T) { - hosts := []string{ - "zom_g", - "test$ing", - "some😄host", - } - - for _, v := range hosts { - _, err := ValidateHostName(v) - if err == nil { - t.Fatal("No error returned") - } - } -} - -func TestMachinePort(t *testing.T) { - dockerPort := 2376 - bindUrl := fmt.Sprintf("tcp://0.0.0.0:%d", dockerPort) - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": bindUrl, - }, - } - - store := NewStore("", "", "") - - _, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - - host, err := store.Load("test") - cfg := host.generateDockerConfig(dockerPort, "", "", "") - - re := regexp.MustCompile("--host=tcp://.*:(.+)") - m := re.FindStringSubmatch(cfg.EngineConfig) - if len(m) == 0 { - t.Errorf("could not find port %d in engine config", dockerPort) - } - - b := m[0] - u := strings.Split(b, "=") - url := u[1] - url = strings.Replace(url, "'", "", -1) - if url != bindUrl { - t.Errorf("expected url %s; received %s", bindUrl, url) - } - - if err := store.Remove("test", true); err != nil { - t.Fatal(err) - } -} - -func TestMachineCustomPort(t *testing.T) { - dockerPort := 3376 - bindUrl := fmt.Sprintf("tcp://0.0.0.0:%d", dockerPort) - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": bindUrl, - }, - } - - store := NewStore("", "", "") - - _, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - - host, err := store.Load("test") - cfg := host.generateDockerConfig(dockerPort, "", "", "") - - re := regexp.MustCompile("--host=tcp://.*:(.+)") - m := re.FindStringSubmatch(cfg.EngineConfig) - if len(m) == 0 { - t.Errorf("could not find port %d in engine config", dockerPort) - } - - b := m[0] - u := strings.Split(b, "=") - url := u[1] - url = strings.Replace(url, "'", "", -1) - if url != bindUrl { - t.Errorf("expected url %s; received %s", bindUrl, url) - } - - if err := store.Remove("test", true); err != nil { - t.Fatal(err) - } -} diff --git a/its/cli/create_rm_test.go b/its/cli/create_rm_test.go new file mode 100644 index 0000000000..dc00c8a4bd --- /dev/null +++ b/its/cli/create_rm_test.go @@ -0,0 +1,79 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestCreateRm(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.Run("non-existent driver fails", func() { + test.Machine("create -d bogus bogus").Should().Fail(`Driver "bogus" not found. Do you have the plugin binary "docker-machine-driver-bogus" accessible in your PATH?`) + }) + + test.Run("non-existent driver fails", func() { + test.Machine("create -d bogus bogus").Should().Fail(`Driver "bogus" not found. Do you have the plugin binary "docker-machine-driver-bogus" accessible in your PATH?`) + }) + + test.Run("create with no name fails", func() { + test.Machine("create -d none").Should().Fail(`Error: No machine name specified`) + }) + + test.Run("create with invalid name fails", func() { + test.Machine("create -d none --url none ∞").Should().Fail(`Error creating machine: Invalid hostname specified. Allowed hostname chars are: 0-9a-zA-Z . -`) + }) + + test.Run("create with invalid name fails", func() { + test.Machine("create -d none --url none -").Should().Fail(`Error creating machine: Invalid hostname specified. Allowed hostname chars are: 0-9a-zA-Z . -`) + }) + + test.Run("create with invalid name fails", func() { + test.Machine("create -d none --url none .").Should().Fail(`Error creating machine: Invalid hostname specified. Allowed hostname chars are: 0-9a-zA-Z . -`) + }) + + test.Run("create with invalid name fails", func() { + test.Machine("create -d none --url none ..").Should().Fail(`Error creating machine: Invalid hostname specified. Allowed hostname chars are: 0-9a-zA-Z . -`) + }) + + test.Run("create with weird but valid name succeeds", func() { + test.Machine("create -d none --url none a").Should().Succeed() + }) + + test.Run("fail with extra argument", func() { + test.Machine("create -d none --url none a extra").Should().Fail(`Invalid command line. Found extra arguments [extra]`) + }) + + test.Run("create with weird but valid name", func() { + test.Machine("create -d none --url none 0").Should().Succeed() + }) + + test.Run("rm with no name fails", func() { + test.Machine("rm -y").Should().Fail(`Error: Expected to get one or more machine names as arguments`) + }) + + test.Run("rm non existent machine fails", func() { + test.Machine("rm ∞ -y").Should().Fail(`Error removing host "∞": Docker machine "∞" does not exist.`) + }) + + test.Run("rm existing machine", func() { + test.Machine("rm 0 -y").Should().Succeed() + }) + + test.Run("rm ask user confirmation when -y is not provided", func() { + test.Machine("create -d none --url none ba").Should().Succeed() + test.Cmd("echo y | machine rm ba").Should().Succeed() + }) + + test.Run("rm deny user confirmation when -y is not provided", func() { + test.Machine("create -d none --url none ab").Should().Succeed() + test.Cmd("echo n | machine rm ab").Should().Succeed() + }) + + test.Run("rm never prompt user confirmation when -f is provided", func() { + test.Machine("create -d none --url none c").Should().Succeed() + test.Machine("rm -f c").Should().Succeed("Successfully removed c") + }) +} diff --git a/its/cli/driver_help_test.go b/its/cli/driver_help_test.go new file mode 100644 index 0000000000..ea69491ace --- /dev/null +++ b/its/cli/driver_help_test.go @@ -0,0 +1,26 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestDriverHelp(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.SkipDriver("ci-test") + + test.Run("no --help flag or command specified", func() { + test.Machine("create -d $DRIVER").Should().Fail("Error: No machine name specified") + }) + + test.Run("-h flag specified", func() { + test.Machine("create -d $DRIVER -h").Should().Succeed(test.DriverName()) + }) + + test.Run("--help flag specified", func() { + test.Machine("create -d $DRIVER --help").Should().Succeed(test.DriverName()) + }) +} diff --git a/its/cli/help_test.go b/its/cli/help_test.go new file mode 100644 index 0000000000..3a1d0582c9 --- /dev/null +++ b/its/cli/help_test.go @@ -0,0 +1,96 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestHelp(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.Run("cli: show info", func() { + test.Machine("").Should().Succeed("Usage:", "Create and manage machines running Docker") + }) + + test.Run("cli: show active help", func() { + test.Machine("active -h").Should().Succeed("machine active") + }) + + test.Run("cli: show config help", func() { + test.Machine("config -h").Should().Succeed("machine config") + }) + + test.Run("cli: show create help", func() { + test.Machine("create -h").Should().Succeed("machine create") + }) + + test.Run("cli: show env help", func() { + test.Machine("env -h").Should().Succeed("machine env") + }) + + test.Run("cli: show inspect help", func() { + test.Machine("inspect -h").Should().Succeed("machine inspect") + }) + + test.Run("cli: show ip help", func() { + test.Machine("ip -h").Should().Succeed("machine ip") + }) + + test.Run("cli: show kill help", func() { + test.Machine("kill -h").Should().Succeed("machine kill") + }) + + test.Run("cli: show ls help", func() { + test.Machine("ls -h").Should().Succeed("machine ls") + }) + + test.Run("cli: show regenerate-certs help", func() { + test.Machine("regenerate-certs -h").Should().Succeed("machine regenerate-certs") + }) + + test.Run("cli: show restart help", func() { + test.Machine("restart -h").Should().Succeed("machine restart") + }) + + test.Run("cli: show rm help", func() { + test.Machine("rm -h").Should().Succeed("machine rm") + }) + + test.Run("cli: show scp help", func() { + test.Machine("scp -h").Should().Succeed("machine scp") + }) + + test.Run("cli: show ssh help", func() { + test.Machine("ssh -h").Should().Succeed("machine ssh") + }) + + test.Run("cli: show start help", func() { + test.Machine("start -h").Should().Succeed("machine start") + }) + + test.Run("cli: show status help", func() { + test.Machine("status -h").Should().Succeed("machine status") + }) + + test.Run("cli: show stop help", func() { + test.Machine("stop -h").Should().Succeed("machine stop") + }) + + test.Run("cli: show upgrade help", func() { + test.Machine("upgrade -h").Should().Succeed("machine upgrade") + }) + + test.Run("cli: show url help", func() { + test.Machine("url -h").Should().Succeed("machine url") + }) + + test.Run("cli: show version", func() { + test.Machine("-v").Should().Succeed("version") + }) + + test.Run("cli: show help", func() { + test.Machine("--help").Should().Succeed("Usage:") + }) +} diff --git a/its/cli/inspect_test.go b/its/cli/inspect_test.go new file mode 100644 index 0000000000..6a632f21cc --- /dev/null +++ b/its/cli/inspect_test.go @@ -0,0 +1,16 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestInspect(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.Run("inspect: show error in case of no args", func() { + test.Machine("inspect").Should().Fail(`Error: No machine name(s) specified and no "default" machine exists`) + }) +} diff --git a/its/cli/ls_test.go b/its/cli/ls_test.go new file mode 100644 index 0000000000..239cd77136 --- /dev/null +++ b/its/cli/ls_test.go @@ -0,0 +1,189 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestLs(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.Run("setup", func() { + test.Machine("create -d none --url url5 --engine-label app=1 testmachine5").Should().Succeed() + test.Machine("create -d none --url url4 --engine-label foo=bar --engine-label app=1 testmachine4").Should().Succeed() + test.Machine("create -d none --url url3 testmachine3").Should().Succeed() + test.Machine("create -d none --url url2 testmachine2").Should().Succeed() + test.Machine("create -d none --url url1 testmachine").Should().Succeed() + }) + + test.Run("ls: no filter", func() { + test.Machine("ls").Should().Succeed(). + ContainLines(6). + MatchLine(0, "NAME[ ]+ACTIVE[ ]+DRIVER[ ]+STATE[ ]+URL[ ]+SWARM[ ]+DOCKER[ ]+ERRORS"). + MatchLine(1, "testmachine[ ]+-[ ]+none[ ]+Running[ ]+url1[ ]+Unknown[ ]+Unable to query docker version: .*"). + MatchLine(2, "testmachine2[ ]+-[ ]+none[ ]+Running[ ]+url2[ ]+Unknown[ ]+Unable to query docker version: .*"). + MatchLine(3, "testmachine3[ ]+-[ ]+none[ ]+Running[ ]+url3[ ]+Unknown[ ]+Unable to query docker version: .*"). + MatchLine(4, "testmachine4[ ]+-[ ]+none[ ]+Running[ ]+url4[ ]+Unknown[ ]+Unable to query docker version: .*"). + MatchLine(5, "testmachine5[ ]+-[ ]+none[ ]+Running[ ]+url5[ ]+Unknown[ ]+Unable to query docker version: .*") + }) + + test.Run("ls: filter on label", func() { + test.Machine("ls --filter label=foo=bar").Should().Succeed(). + ContainLines(2). + ContainLine(0, "NAME"). + ContainLine(1, "testmachine4") + }) + + test.Run("ls: multiple filters on label", func() { + test.Machine("ls --filter label=foo=bar --filter label=app=1").Should().Succeed(). + ContainLines(3). + ContainLine(0, "NAME"). + ContainLine(1, "testmachine4"). + ContainLine(2, "testmachine5") + }) + + test.Run("ls: non-existing filter on label", func() { + test.Machine("ls --filter label=invalid=filter").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + }) + + test.Run("ls: filter on driver", func() { + test.Machine("ls --filter driver=none").Should().Succeed(). + ContainLines(6). + ContainLine(0, "NAME"). + ContainLine(1, "testmachine"). + ContainLine(2, "testmachine2"). + ContainLine(3, "testmachine3"). + ContainLine(4, "testmachine4"). + ContainLine(5, "testmachine5") + }) + + test.Run("ls: filter on driver", func() { + test.Machine("ls -q --filter driver=none").Should().Succeed(). + ContainLines(5). + EqualLine(0, "testmachine"). + EqualLine(1, "testmachine2"). + EqualLine(2, "testmachine3") + }) + + test.Run("ls: filter on state", func() { + test.Machine("ls --filter state=Running").Should().Succeed(). + ContainLines(6). + ContainLine(0, "NAME"). + ContainLine(1, "testmachine"). + ContainLine(2, "testmachine2"). + ContainLine(3, "testmachine3") + + test.Machine("ls -q --filter state=Running").Should().Succeed(). + ContainLines(5). + EqualLine(0, "testmachine"). + EqualLine(1, "testmachine2"). + EqualLine(2, "testmachine3") + + test.Machine("ls --filter state=None").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + + test.Machine("ls --filter state=Paused").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + + test.Machine("ls --filter state=Saved").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + + test.Machine("ls --filter state=Stopped").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + + test.Machine("ls --filter state=Stopping").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + + test.Machine("ls --filter state=Starting").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + + test.Machine("ls --filter state=Error").Should().Succeed(). + ContainLines(1). + ContainLine(0, "NAME") + }) + + test.Run("ls: filter on name", func() { + test.Machine("ls --filter name=testmachine2").Should().Succeed(). + ContainLines(2). + ContainLine(0, "NAME"). + ContainLine(1, "testmachine2") + + test.Machine("ls -q --filter name=testmachine3").Should().Succeed(). + ContainLines(1). + EqualLine(0, "testmachine3") + }) + + test.Run("ls: filter on name with regex", func() { + test.Machine("ls --filter name=^t.*e[3-5]").Should().Succeed(). + ContainLines(4). + ContainLine(0, "NAME"). + ContainLine(1, "testmachine3"). + ContainLine(2, "testmachine4"). + ContainLine(3, "testmachine5") + + test.Machine("ls -q --filter name=^t.*e[45]").Should().Succeed(). + ContainLines(2). + EqualLine(0, "testmachine4"). + EqualLine(1, "testmachine5") + }) + + test.Run("setup swarm", func() { + test.Machine("create -d none --url tcp://127.0.0.1:2375 --swarm --swarm-master --swarm-discovery token://deadbeef testswarm").Should().Succeed() + test.Machine("create -d none --url tcp://127.0.0.1:2375 --swarm --swarm-discovery token://deadbeef testswarm2").Should().Succeed() + test.Machine("create -d none --url tcp://127.0.0.1:2375 --swarm --swarm-discovery token://deadbeef testswarm3").Should().Succeed() + }) + + test.Run("ls: filter on swarm", func() { + test.Machine("ls --filter swarm=testswarm").Should().Succeed(). + ContainLines(4). + ContainLine(0, "NAME"). + ContainLine(1, "testswarm"). + ContainLine(2, "testswarm2"). + ContainLine(3, "testswarm3") + }) + + test.Run("ls: multi filter", func() { + test.Machine("ls -q --filter swarm=testswarm --filter name=^t.*e --filter driver=none --filter state=Running").Should().Succeed(). + ContainLines(3). + EqualLine(0, "testswarm"). + EqualLine(1, "testswarm2"). + EqualLine(2, "testswarm3") + }) + + test.Run("ls: format on driver", func() { + test.Machine("ls --format {{.DriverName}}").Should().Succeed(). + ContainLines(8). + EqualLine(0, "none"). + EqualLine(1, "none"). + EqualLine(2, "none"). + EqualLine(3, "none"). + EqualLine(4, "none"). + EqualLine(5, "none"). + EqualLine(6, "none"). + EqualLine(7, "none") + }) + + test.Run("ls: format on name and driver", func() { + test.Machine("ls --format 'table {{.Name}}: {{.DriverName}}'").Should().Succeed(). + ContainLines(9). + ContainLine(0, "NAME"). + EqualLine(1, "testmachine: none"). + EqualLine(2, "testmachine2: none"). + EqualLine(3, "testmachine3: none"). + EqualLine(4, "testmachine4: none"). + EqualLine(5, "testmachine5: none"). + EqualLine(6, "testswarm: none"). + EqualLine(7, "testswarm2: none"). + EqualLine(8, "testswarm3: none") + }) +} diff --git a/its/cli/status_test.go b/its/cli/status_test.go new file mode 100644 index 0000000000..8bea4c01c8 --- /dev/null +++ b/its/cli/status_test.go @@ -0,0 +1,16 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestStatus(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.Run("status: show error in case of no args", func() { + test.Machine("status").Should().Fail(`Error: No machine name(s) specified and no "default" machine exists`) + }) +} diff --git a/its/cli/url_test.go b/its/cli/url_test.go new file mode 100644 index 0000000000..cd46a5bc6b --- /dev/null +++ b/its/cli/url_test.go @@ -0,0 +1,16 @@ +package cli + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestUrl(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.Run("url: show error in case of no args", func() { + test.Machine("url").Should().Fail(`Error: No machine name(s) specified and no "default" machine exists`) + }) +} diff --git a/its/tester.go b/its/tester.go new file mode 100644 index 0000000000..b5857e5652 --- /dev/null +++ b/its/tester.go @@ -0,0 +1,363 @@ +package its + +import ( + "os/exec" + "regexp" + "strings" + "testing" + + "io/ioutil" + + "os" + + "fmt" + + "path/filepath" + "runtime" +) + +var ( + regexpCommandLine = regexp.MustCompile("('[^']*')|(\\S+)") +) + +type IntegrationTest interface { + RequireDriver(driverName string) + + SkipDriver(driverName string) + + SkipDrivers(driverNames ...string) + + ForceDriver(driverName string) + + Run(description string, action func()) + + Cmd(commandLine string) IntegrationTest + + Machine(commandLine string) IntegrationTest + + DriverName() string + + Should() Assertions + + TearDown() +} + +type Assertions interface { + Succeed(messages ...string) Assertions + + Fail(errorMessages ...string) Assertions + + ContainLines(count int) Assertions + + ContainLine(index int, text string) Assertions + + MatchLine(index int, template string) Assertions + + EqualLine(index int, text string) Assertions +} + +func NewTest(t *testing.T) IntegrationTest { + storagePath, _ := ioutil.TempDir("", "docker") + + return &dockerMachineTest{ + t: t, + storagePath: storagePath, + } +} + +type dockerMachineTest struct { + t *testing.T + storagePath string + dockerMachineBinary string + description string + skip bool + rawOutput string + lines []string + err error + fatal bool + failed bool +} + +func (dmt *dockerMachineTest) RequireDriver(driverName string) { + dmt.skipIf(dmt.DriverName() != driverName) +} + +func (dmt *dockerMachineTest) SkipDriver(driverName string) { + dmt.skipIf(dmt.DriverName() == driverName) +} + +func (dmt *dockerMachineTest) SkipDrivers(driverNames ...string) { + for _, driverName := range driverNames { + dmt.skipIf(dmt.DriverName() == driverName) + } +} + +func (dmt *dockerMachineTest) ForceDriver(driverName string) { + os.Setenv("DRIVER", driverName) +} + +func (dmt *dockerMachineTest) skipIf(condition bool) { + if condition { + dmt.skip = true + } +} + +func (dmt *dockerMachineTest) Run(description string, action func()) { + dmt.description = description + dmt.rawOutput = "" + dmt.lines = nil + dmt.err = nil + dmt.failed = false + + if dmt.skip { + fmt.Printf("%s %s\n", yellow("[SKIP]"), description) + } else { + fmt.Printf("%s %s", yellow("[..]"), description) + action() + + if dmt.fatal || dmt.failed { + fmt.Printf("\r%s %s\n", red("[KO]"), description) + } else { + fmt.Printf("\r%s %s\n", green("[OK]"), description) + } + } +} + +func red(message string) string { + if runtime.GOOS == "windows" { + return message + } + return "\033[1;31m" + message + "\033[0m" +} + +func green(message string) string { + if runtime.GOOS == "windows" { + return message + } + return "\033[1;32m" + message + "\033[0m" +} + +func yellow(message string) string { + if runtime.GOOS == "windows" { + return message + } + return "\033[1;33m" + message + "\033[0m" +} + +func (dmt *dockerMachineTest) DriverName() string { + driver := os.Getenv("DRIVER") + if driver != "" { + return driver + } + + return "virtualbox" +} + +func (dmt *dockerMachineTest) Should() Assertions { + return dmt +} + +func (dmt *dockerMachineTest) testedBinary() string { + if dmt.dockerMachineBinary != "" { + return dmt.dockerMachineBinary + } + + var binary string + if runtime.GOOS == "windows" { + binary = "docker-machine.exe" + } else { + binary = "docker-machine" + } + + _, file, _, _ := runtime.Caller(0) + dir := filepath.Dir(file) + + for dir != "/" { + path := filepath.Join(dir, "bin", binary) + + _, err := os.Stat(path) + if err == nil { + dmt.dockerMachineBinary = path + return path + } + + dir = filepath.Dir(dir) + } + + if !dmt.fatal { + dmt.fatal = true + dmt.t.Errorf("Binary not found: %s", binary) + } + + return "" +} + +func (dmt *dockerMachineTest) Cmd(commandLine string) IntegrationTest { + if dmt.fatal { + return dmt + } + + commandLine = dmt.replaceDriver(commandLine) + commandLine = dmt.replaceMachinePath(commandLine) + + return dmt.cmd("bash", "-c", commandLine) +} + +func (dmt *dockerMachineTest) Machine(commandLine string) IntegrationTest { + if dmt.fatal { + return dmt + } + + commandLine = dmt.replaceDriver(commandLine) + + return dmt.cmd(dmt.testedBinary(), parseFields(commandLine)...) +} + +func (dmt *dockerMachineTest) cmd(command string, args ...string) IntegrationTest { + cmd := exec.Command(command, args...) + cmd.Env = append(os.Environ(), "MACHINE_STORAGE_PATH="+dmt.storagePath) + + combinedOutput, err := cmd.CombinedOutput() + + dmt.rawOutput = string(combinedOutput) + dmt.lines = strings.Split(strings.TrimSpace(dmt.rawOutput), "\n") + dmt.err = err + + return dmt +} + +func (dmt *dockerMachineTest) replaceMachinePath(commandLine string) string { + return strings.Replace(commandLine, "machine", dmt.testedBinary(), -1) +} + +func (dmt *dockerMachineTest) replaceDriver(commandLine string) string { + return strings.Replace(commandLine, "$DRIVER", dmt.DriverName(), -1) +} + +func parseFields(commandLine string) []string { + fields := regexpCommandLine.FindAllString(commandLine, -1) + + for i := range fields { + if len(fields[i]) > 2 && strings.HasPrefix(fields[i], "'") && strings.HasSuffix(fields[i], "'") { + fields[i] = fields[i][1 : len(fields[i])-1] + } + } + + return fields +} + +func (dmt *dockerMachineTest) TearDown() { + machines := filepath.Join(dmt.storagePath, "machines") + + dirs, _ := ioutil.ReadDir(machines) + for _, dir := range dirs { + dmt.Cmd("machine rm -f " + dir.Name()) + } + + os.RemoveAll(dmt.storagePath) +} + +func (dmt *dockerMachineTest) ContainLines(count int) Assertions { + if dmt.fatal { + return dmt + } + + if count != len(dmt.lines) { + return dmt.failExpected("%d lines but got %d\n%s", count, len(dmt.lines), dmt.rawOutput) + } + + return dmt +} + +func (dmt *dockerMachineTest) ContainLine(index int, text string) Assertions { + if dmt.fatal { + return dmt + } + + if index >= len(dmt.lines) { + return dmt.failExpected("at least %d lines\nGot %d", index+1, len(dmt.lines)) + } + + if !strings.Contains(dmt.lines[index], text) { + return dmt.failExpected("line %d to contain '%s'\nGot '%s'", index, text, dmt.lines[index]) + } + + return dmt +} + +func (dmt *dockerMachineTest) MatchLine(index int, template string) Assertions { + if dmt.fatal { + return dmt + } + + if index >= len(dmt.lines) { + return dmt.failExpected("at least %d lines\nGot %d", index+1, len(dmt.lines)) + } + + if !regexp.MustCompile(template).MatchString(dmt.lines[index]) { + return dmt.failExpected("line %d to match '%s'\nGot '%s'", index, template, dmt.lines[index]) + } + + return dmt +} + +func (dmt *dockerMachineTest) EqualLine(index int, text string) Assertions { + if dmt.fatal { + return dmt + } + + if index >= len(dmt.lines) { + return dmt.failExpected("at least %d lines\nGot %d", index+1, len(dmt.lines)) + } + + if text != dmt.lines[index] { + return dmt.failExpected("line %d to be '%s'\nGot '%s'", index, text, dmt.lines[index]) + } + + return dmt +} + +func (dmt *dockerMachineTest) Succeed(messages ...string) Assertions { + if dmt.fatal { + return dmt + } + + if dmt.err != nil { + return dmt.failExpected("to succeed\nFailed with %s\n%s", dmt.err, dmt.rawOutput) + } + + for _, message := range messages { + if !strings.Contains(dmt.rawOutput, message) { + return dmt.failExpected("output to contain '%s'\nGot '%s'", message, dmt.rawOutput) + } + } + + return dmt +} + +func (dmt *dockerMachineTest) Fail(errorMessages ...string) Assertions { + if dmt.fatal { + return dmt + } + + if dmt.err == nil { + return dmt.failExpected("to fail\nGot success\n%s", dmt.rawOutput) + } + + for _, message := range errorMessages { + if !strings.Contains(dmt.rawOutput, message) { + return dmt.failExpected("output to contain '%s'\nGot '%s'", message, dmt.rawOutput) + } + } + + return dmt +} + +func (dmt *dockerMachineTest) failExpected(message string, args ...interface{}) Assertions { + allArgs := append([]interface{}{dmt.description}, args...) + + dmt.failed = true + dmt.t.Errorf("%s\nExpected "+message, allArgs...) + + return dmt +} diff --git a/its/thirdparty/commands_test.go b/its/thirdparty/commands_test.go new file mode 100644 index 0000000000..945ece7667 --- /dev/null +++ b/its/thirdparty/commands_test.go @@ -0,0 +1,34 @@ +package thirdparty + +import ( + "testing" + + "github.com/docker/machine/its" +) + +func TestThirdPartyCompatibility(t *testing.T) { + test := its.NewTest(t) + defer test.TearDown() + + test.RequireDriver("ci-test") + + test.Run("create", func() { + test.Machine("create -d $DRIVER --url url default").Should().Succeed() + }) + + test.Run("ls", func() { + test.Machine("ls -q").Should().Succeed().ContainLines(1).EqualLine(0, "default") + }) + + test.Run("url", func() { + test.Machine("url default").Should().Succeed("url") + }) + + test.Run("status", func() { + test.Machine("status default").Should().Succeed("Running") + }) + + test.Run("rm", func() { + test.Machine("rm -y default").Should().Succeed() + }) +} diff --git a/libmachine/auth/auth.go b/libmachine/auth/auth.go new file mode 100644 index 0000000000..86ae79d232 --- /dev/null +++ b/libmachine/auth/auth.go @@ -0,0 +1,18 @@ +package auth + +type Options struct { + CertDir string + CaCertPath string + CaPrivateKeyPath string + CaCertRemotePath string + ServerCertPath string + ServerKeyPath string + ClientKeyPath string + ServerCertRemotePath string + ServerKeyRemotePath string + ClientCertPath string + ServerCertSANs []string + // StorePath is left in for historical reasons, but not really meant to + // be used directly. + StorePath string +} diff --git a/libmachine/cert/bootstrap.go b/libmachine/cert/bootstrap.go new file mode 100644 index 0000000000..59543bcb05 --- /dev/null +++ b/libmachine/cert/bootstrap.go @@ -0,0 +1,136 @@ +package cert + +import ( + "errors" + "fmt" + "os" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" +) + +func createCACert(authOptions *auth.Options, caOrg string, bits int) error { + caCertPath := authOptions.CaCertPath + caPrivateKeyPath := authOptions.CaPrivateKeyPath + + log.Infof("Creating CA: %s", caCertPath) + + // check if the key path exists; if so, error + if _, err := os.Stat(caPrivateKeyPath); err == nil { + return errors.New("certificate authority key already exists") + } + + if err := GenerateCACertificate(caCertPath, caPrivateKeyPath, caOrg, bits); err != nil { + return fmt.Errorf("generating CA certificate failed: %s", err) + } + + return nil +} + +func createCert(authOptions *auth.Options, org string, bits int) error { + certDir := authOptions.CertDir + caCertPath := authOptions.CaCertPath + caPrivateKeyPath := authOptions.CaPrivateKeyPath + clientCertPath := authOptions.ClientCertPath + clientKeyPath := authOptions.ClientKeyPath + + log.Infof("Creating client certificate: %s", clientCertPath) + + if _, err := os.Stat(certDir); err != nil { + if os.IsNotExist(err) { + if err := os.Mkdir(certDir, 0700); err != nil { + return fmt.Errorf("failure creating machine client cert dir: %s", err) + } + } else { + return err + } + } + + // check if the key path exists; if so, error + if _, err := os.Stat(clientKeyPath); err == nil { + return errors.New("client key already exists") + } + + // Used to generate the client certificate. + certOptions := &Options{ + Hosts: []string{""}, + CertFile: clientCertPath, + KeyFile: clientKeyPath, + CAFile: caCertPath, + CAKeyFile: caPrivateKeyPath, + Org: org, + Bits: bits, + SwarmMaster: false, + } + + if err := GenerateCert(certOptions); err != nil { + return fmt.Errorf("failure generating client certificate: %s", err) + } + + return nil +} + +func BootstrapCertificates(authOptions *auth.Options) error { + certDir := authOptions.CertDir + caCertPath := authOptions.CaCertPath + clientCertPath := authOptions.ClientCertPath + clientKeyPath := authOptions.ClientKeyPath + caPrivateKeyPath := authOptions.CaPrivateKeyPath + + // TODO: I'm not super happy about this use of "org", the user should + // have to specify it explicitly instead of implicitly basing it on + // $USER. + caOrg := mcnutils.GetUsername() + org := caOrg + "." + + bits := 2048 + + if _, err := os.Stat(certDir); err != nil { + if os.IsNotExist(err) { + if err := os.MkdirAll(certDir, 0700); err != nil { + return fmt.Errorf("creating machine certificate dir failed: %s", err) + } + } else { + return err + } + } + + if _, err := os.Stat(caCertPath); os.IsNotExist(err) { + if err := createCACert(authOptions, caOrg, bits); err != nil { + return err + } + } else { + current, err := CheckCertificateDate(caCertPath) + if err != nil { + return err + } + if !current { + log.Info("CA certificate is outdated and needs to be regenerated") + os.Remove(caPrivateKeyPath) + if err := createCACert(authOptions, caOrg, bits); err != nil { + return err + } + } + } + + if _, err := os.Stat(clientCertPath); os.IsNotExist(err) { + if err := createCert(authOptions, org, bits); err != nil { + return err + } + } else { + current, err := CheckCertificateDate(clientCertPath) + if err != nil { + return err + } + if !current { + log.Info("Client certificate is outdated and needs to be regenerated") + os.Remove(clientKeyPath) + if err := createCert(authOptions, org, bits); err != nil { + return err + } + } + } + + return nil +} diff --git a/libmachine/cert/cert.go b/libmachine/cert/cert.go new file mode 100644 index 0000000000..a0d9c732ed --- /dev/null +++ b/libmachine/cert/cert.go @@ -0,0 +1,294 @@ +package cert + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "io/ioutil" + "math/big" + "net" + "os" + "time" + + "errors" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/log" +) + +var defaultGenerator = NewX509CertGenerator() + +type Options struct { + Hosts []string + CertFile, KeyFile, CAFile, CAKeyFile, Org string + Bits int + SwarmMaster bool +} + +type Generator interface { + GenerateCACertificate(certFile, keyFile, org string, bits int) error + GenerateCert(opts *Options) error + ReadTLSConfig(addr string, authOptions *auth.Options) (*tls.Config, error) + ValidateCertificate(addr string, authOptions *auth.Options) (bool, error) +} + +type X509CertGenerator struct{} + +func NewX509CertGenerator() Generator { + return &X509CertGenerator{} +} + +func GenerateCACertificate(certFile, keyFile, org string, bits int) error { + return defaultGenerator.GenerateCACertificate(certFile, keyFile, org, bits) +} + +func GenerateCert(opts *Options) error { + return defaultGenerator.GenerateCert(opts) +} + +func ValidateCertificate(addr string, authOptions *auth.Options) (bool, error) { + return defaultGenerator.ValidateCertificate(addr, authOptions) +} + +func ReadTLSConfig(addr string, authOptions *auth.Options) (*tls.Config, error) { + return defaultGenerator.ReadTLSConfig(addr, authOptions) +} + +func SetCertGenerator(cg Generator) { + defaultGenerator = cg +} + +func (xcg *X509CertGenerator) getTLSConfig(caCert, cert, key []byte, allowInsecure bool) (*tls.Config, error) { + // TLS config + var tlsConfig tls.Config + tlsConfig.InsecureSkipVerify = allowInsecure + certPool := x509.NewCertPool() + + ok := certPool.AppendCertsFromPEM(caCert) + if !ok { + return &tlsConfig, errors.New("There was an error reading certificate") + } + + tlsConfig.RootCAs = certPool + keypair, err := tls.X509KeyPair(cert, key) + if err != nil { + return &tlsConfig, err + } + tlsConfig.Certificates = []tls.Certificate{keypair} + + return &tlsConfig, nil +} + +func (xcg *X509CertGenerator) newCertificate(org string) (*x509.Certificate, error) { + now := time.Now() + // need to set notBefore slightly in the past to account for time + // skew in the VMs otherwise the certs sometimes are not yet valid + notBefore := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-5, 0, 0, time.Local) + notAfter := notBefore.Add(time.Hour * 24 * 1080) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return nil, err + } + + return &x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{org}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement, + BasicConstraintsValid: true, + }, nil + +} + +// GenerateCACertificate generates a new certificate authority from the specified org +// and bit size and stores the resulting certificate and key file +// in the arguments. +func (xcg *X509CertGenerator) GenerateCACertificate(certFile, keyFile, org string, bits int) error { + template, err := xcg.newCertificate(org) + if err != nil { + return err + } + + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + template.KeyUsage |= x509.KeyUsageKeyEncipherment + template.KeyUsage |= x509.KeyUsageKeyAgreement + + priv, err := rsa.GenerateKey(rand.Reader, bits) + if err != nil { + return err + } + + derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv) + if err != nil { + return err + } + + certOut, err := os.Create(certFile) + if err != nil { + return err + } + + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + + keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + + } + + pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) + keyOut.Close() + + return nil +} + +// GenerateCert generates a new certificate signed using the provided +// certificate authority files and stores the result in the certificate +// file and key provided. The provided host names are set to the +// appropriate certificate fields. +func (xcg *X509CertGenerator) GenerateCert(opts *Options) error { + template, err := xcg.newCertificate(opts.Org) + if err != nil { + return err + } + // client + if len(opts.Hosts) == 1 && opts.Hosts[0] == "" { + template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} + template.KeyUsage = x509.KeyUsageDigitalSignature + } else { // server + template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} + if opts.SwarmMaster { + // Extend the Swarm master's server certificate + // permissions to also be able to connect to downstream + // nodes as a client. + template.ExtKeyUsage = append(template.ExtKeyUsage, x509.ExtKeyUsageClientAuth) + } + for _, h := range opts.Hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + } + + tlsCert, err := tls.LoadX509KeyPair(opts.CAFile, opts.CAKeyFile) + if err != nil { + return err + } + + priv, err := rsa.GenerateKey(rand.Reader, opts.Bits) + if err != nil { + return err + } + + x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0]) + if err != nil { + return err + } + + derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey) + if err != nil { + return err + } + + certOut, err := os.Create(opts.CertFile) + if err != nil { + return err + } + + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + + keyOut, err := os.OpenFile(opts.KeyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + + pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) + keyOut.Close() + + return nil +} + +// ReadTLSConfig reads the tls config for a machine. +func (xcg *X509CertGenerator) ReadTLSConfig(addr string, authOptions *auth.Options) (*tls.Config, error) { + caCertPath := authOptions.CaCertPath + clientCertPath := authOptions.ClientCertPath + clientKeyPath := authOptions.ClientKeyPath + + log.Debugf("Reading CA certificate from %s", caCertPath) + caCert, err := ioutil.ReadFile(caCertPath) + if err != nil { + return nil, err + } + + log.Debugf("Reading client certificate from %s", clientCertPath) + clientCert, err := ioutil.ReadFile(clientCertPath) + if err != nil { + return nil, err + } + + log.Debugf("Reading client key from %s", clientKeyPath) + clientKey, err := ioutil.ReadFile(clientKeyPath) + if err != nil { + return nil, err + } + + return xcg.getTLSConfig(caCert, clientCert, clientKey, false) +} + +// ValidateCertificate validate the certificate installed on the vm. +func (xcg *X509CertGenerator) ValidateCertificate(addr string, authOptions *auth.Options) (bool, error) { + tlsConfig, err := xcg.ReadTLSConfig(addr, authOptions) + if err != nil { + return false, err + } + + dialer := &net.Dialer{ + Timeout: time.Second * 20, + } + + _, err = tls.DialWithDialer(dialer, "tcp", addr, tlsConfig) + if err != nil { + return false, err + } + + return true, nil +} + +func CheckCertificateDate(certPath string) (bool, error) { + log.Debugf("Reading certificate data from %s", certPath) + certBytes, err := ioutil.ReadFile(certPath) + if err != nil { + return false, err + } + + log.Debug("Decoding PEM data...") + pemBlock, _ := pem.Decode(certBytes) + if pemBlock == nil { + return false, errors.New("Failed to decode PEM data") + } + + log.Debug("Parsing certificate...") + cert, err := x509.ParseCertificate(pemBlock.Bytes) + if err != nil { + return false, err + } + if time.Now().After(cert.NotAfter) { + return false, nil + } + + return true, nil +} diff --git a/libmachine/cert/cert_test.go b/libmachine/cert/cert_test.go new file mode 100644 index 0000000000..f5b5ecba95 --- /dev/null +++ b/libmachine/cert/cert_test.go @@ -0,0 +1,81 @@ +package cert + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestGenerateCACertificate(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + t.Fatal(err) + } + // cleanup + defer os.RemoveAll(tmpDir) + + caCertPath := filepath.Join(tmpDir, "ca.pem") + caKeyPath := filepath.Join(tmpDir, "key.pem") + testOrg := "test-org" + bits := 2048 + if err := GenerateCACertificate(caCertPath, caKeyPath, testOrg, bits); err != nil { + t.Fatal(err) + } + + if _, err := os.Stat(caCertPath); err != nil { + t.Fatal(err) + } + if _, err := os.Stat(caKeyPath); err != nil { + t.Fatal(err) + } +} + +func TestGenerateCert(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + t.Fatal(err) + } + // cleanup + defer os.RemoveAll(tmpDir) + + caCertPath := filepath.Join(tmpDir, "ca.pem") + caKeyPath := filepath.Join(tmpDir, "key.pem") + certPath := filepath.Join(tmpDir, "cert.pem") + keyPath := filepath.Join(tmpDir, "cert-key.pem") + testOrg := "test-org" + bits := 2048 + if err := GenerateCACertificate(caCertPath, caKeyPath, testOrg, bits); err != nil { + t.Fatal(err) + } + + if _, err := os.Stat(caCertPath); err != nil { + t.Fatal(err) + } + if _, err := os.Stat(caKeyPath); err != nil { + t.Fatal(err) + } + + opts := &Options{ + Hosts: []string{}, + CertFile: certPath, + CAKeyFile: caKeyPath, + CAFile: caCertPath, + KeyFile: keyPath, + Org: testOrg, + Bits: bits, + SwarmMaster: false, + } + + if err := GenerateCert(opts); err != nil { + t.Fatal(err) + } + + if _, err := os.Stat(certPath); err != nil { + t.Fatalf("certificate not created at %s", certPath) + } + + if _, err := os.Stat(keyPath); err != nil { + t.Fatalf("key not created at %s", keyPath) + } +} diff --git a/libmachine/check/check.go b/libmachine/check/check.go new file mode 100644 index 0000000000..49fbce2820 --- /dev/null +++ b/libmachine/check/check.go @@ -0,0 +1,118 @@ +package check + +import ( + "errors" + "fmt" + "net/url" + "strings" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/cert" + "github.com/docker/machine/libmachine/host" +) + +var ( + DefaultConnChecker ConnChecker + ErrSwarmNotStarted = errors.New("Connection to Swarm cannot be checked but the certs are valid. Maybe swarm is not started") +) + +func init() { + DefaultConnChecker = &MachineConnChecker{} +} + +// ErrCertInvalid for when the cert is computed to be invalid. +type ErrCertInvalid struct { + wrappedErr error + hostURL string +} + +func (e ErrCertInvalid) Error() string { + return fmt.Sprintf(`There was an error validating certificates for host %q: %s +You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'. +Be advised that this will trigger a Docker daemon restart which might stop running containers. +`, e.hostURL, e.wrappedErr) +} + +type ConnChecker interface { + Check(*host.Host, bool) (dockerHost string, authOptions *auth.Options, err error) +} + +type MachineConnChecker struct{} + +func (mcc *MachineConnChecker) Check(h *host.Host, swarm bool) (string, *auth.Options, error) { + dockerHost, err := h.Driver.GetURL() + if err != nil { + return "", &auth.Options{}, err + } + + dockerURL := dockerHost + if swarm { + dockerURL, err = parseSwarm(dockerHost, h) + if err != nil { + return "", &auth.Options{}, err + } + } + + u, err := url.Parse(dockerURL) + if err != nil { + return "", &auth.Options{}, fmt.Errorf("Error parsing URL: %s", err) + } + + authOptions := h.AuthOptions() + + if err := checkCert(u.Host, authOptions); err != nil { + if swarm { + // Connection to the swarm port cannot be checked. Maybe it's just the swarm containers that are down + // TODO: check the containers and restart them + // Let's check the non-swarm connection to give a better error message to the user. + if _, _, err := mcc.Check(h, false); err == nil { + return "", &auth.Options{}, ErrSwarmNotStarted + } + } + + return "", &auth.Options{}, fmt.Errorf("Error checking and/or regenerating the certs: %s", err) + } + + return dockerURL, authOptions, nil +} + +func checkCert(hostURL string, authOptions *auth.Options) error { + valid, err := cert.ValidateCertificate(hostURL, authOptions) + if !valid || err != nil { + return ErrCertInvalid{ + wrappedErr: err, + hostURL: hostURL, + } + } + + return nil +} + +// TODO: This could use a unit test. +func parseSwarm(hostURL string, h *host.Host) (string, error) { + swarmOptions := h.HostOptions.SwarmOptions + + if !swarmOptions.Master { + return "", fmt.Errorf("%q is not a swarm master. The --swarm flag is intended for use with swarm masters", h.Name) + } + + u, err := url.Parse(swarmOptions.Host) + if err != nil { + return "", fmt.Errorf("There was an error parsing the url: %s", err) + } + parts := strings.Split(u.Host, ":") + swarmPort := parts[1] + + // get IP of machine to replace in case swarm host is 0.0.0.0 + mURL, err := url.Parse(hostURL) + if err != nil { + return "", fmt.Errorf("There was an error parsing the url: %s", err) + } + + mParts := strings.Split(mURL.Host, ":") + machineIP := mParts[0] + + hostURL = fmt.Sprintf("tcp://%s:%s", machineIP, swarmPort) + + return hostURL, nil +} diff --git a/libmachine/check/check_test.go b/libmachine/check/check_test.go new file mode 100644 index 0000000000..948c08a8c5 --- /dev/null +++ b/libmachine/check/check_test.go @@ -0,0 +1,60 @@ +package check + +import ( + "errors" + "testing" + + "crypto/tls" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/cert" + "github.com/stretchr/testify/assert" +) + +type FakeValidateCertificate struct { + IsValid bool + Err error +} + +type FakeCertGenerator struct { + fakeValidateCertificate *FakeValidateCertificate +} + +func (fcg FakeCertGenerator) GenerateCACertificate(certFile, keyFile, org string, bits int) error { + return nil +} + +func (fcg FakeCertGenerator) GenerateCert(opts *cert.Options) error { + return nil +} + +func (fcg FakeCertGenerator) ValidateCertificate(addr string, authOptions *auth.Options) (bool, error) { + return fcg.fakeValidateCertificate.IsValid, fcg.fakeValidateCertificate.Err +} + +func (fcg FakeCertGenerator) ReadTLSConfig(addr string, authOptions *auth.Options) (*tls.Config, error) { + return nil, nil +} + +func TestCheckCert(t *testing.T) { + errCertsExpired := errors.New("Certs have expired") + + cases := []struct { + hostURL string + authOptions *auth.Options + valid bool + checkErr error + expectedErr error + }{ + {"192.168.99.100:2376", &auth.Options{}, true, nil, nil}, + {"192.168.99.100:2376", &auth.Options{}, false, nil, ErrCertInvalid{wrappedErr: nil, hostURL: "192.168.99.100:2376"}}, + {"192.168.99.100:2376", &auth.Options{}, false, errCertsExpired, ErrCertInvalid{wrappedErr: errCertsExpired, hostURL: "192.168.99.100:2376"}}, + } + + for _, c := range cases { + fcg := FakeCertGenerator{fakeValidateCertificate: &FakeValidateCertificate{c.valid, c.checkErr}} + cert.SetCertGenerator(fcg) + err := checkCert(c.hostURL, c.authOptions) + assert.Equal(t, c.expectedErr, err) + } +} diff --git a/libmachine/crashreport/crash_report.go b/libmachine/crashreport/crash_report.go new file mode 100644 index 0000000000..1ac24a9329 --- /dev/null +++ b/libmachine/crashreport/crash_report.go @@ -0,0 +1,149 @@ +package crashreport + +import ( + "fmt" + "os" + "runtime" + + "bytes" + + "os/exec" + + "path/filepath" + + "errors" + + "io/ioutil" + + "github.com/bugsnag/bugsnag-go" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/shell" + "github.com/docker/machine/version" +) + +const ( + defaultAPIKey = "a9697f9a010c33ee218a65e5b1f3b0c1" + noreportAPIKey = "no-report" +) + +type CrashReporter interface { + Send(err CrashError) error +} + +// CrashError describes an error that should be reported to bugsnag +type CrashError struct { + Cause error + Command string + Context string + DriverName string + LogFilePath string +} + +func (e CrashError) Error() string { + return e.Cause.Error() +} + +type BugsnagCrashReporter struct { + baseDir string + apiKey string +} + +// NewCrashReporter creates a new bugsnag based CrashReporter. Needs an apiKey. +var NewCrashReporter = func(baseDir string, apiKey string) CrashReporter { + if apiKey == "" { + apiKey = defaultAPIKey + } + + return &BugsnagCrashReporter{ + baseDir: baseDir, + apiKey: apiKey, + } +} + +// Send sends a crash report to bugsnag via an http call. +func (r *BugsnagCrashReporter) Send(err CrashError) error { + if r.noReportFileExist() || r.apiKey == noreportAPIKey { + log.Debug("Opting out of crash reporting.") + return nil + } + + if r.apiKey == "" { + return errors.New("no api key has been set") + } + + bugsnag.Configure(bugsnag.Configuration{ + APIKey: r.apiKey, + // XXX we need to abuse bugsnag metrics to get the OS/ARCH information as a usable filter + // Can do that with either "stage" or "hostname" + ReleaseStage: fmt.Sprintf("%s (%s)", runtime.GOOS, runtime.GOARCH), + ProjectPackages: []string{"github.com/docker/machine/[^v]*"}, + AppVersion: version.FullVersion(), + Synchronous: true, + PanicHandler: func() {}, + Logger: new(logger), + }) + + metaData := bugsnag.MetaData{} + + metaData.Add("app", "compiler", fmt.Sprintf("%s (%s)", runtime.Compiler, runtime.Version())) + metaData.Add("device", "os", runtime.GOOS) + metaData.Add("device", "arch", runtime.GOARCH) + + detectRunningShell(&metaData) + detectUname(&metaData) + detectOSVersion(&metaData) + addFile(err.LogFilePath, &metaData) + + var buffer bytes.Buffer + for _, message := range log.History() { + buffer.WriteString(message + "\n") + } + metaData.Add("history", "trace", buffer.String()) + + return bugsnag.Notify(err.Cause, metaData, bugsnag.SeverityError, bugsnag.Context{String: err.Context}, bugsnag.ErrorClass{Name: fmt.Sprintf("%s/%s", err.DriverName, err.Command)}) +} + +func (r *BugsnagCrashReporter) noReportFileExist() bool { + optOutFilePath := filepath.Join(r.baseDir, "no-error-report") + if _, err := os.Stat(optOutFilePath); os.IsNotExist(err) { + return false + } + return true +} + +func addFile(path string, metaData *bugsnag.MetaData) { + if path == "" { + return + } + file, err := os.Open(path) + if err != nil { + log.Debug(err) + return + } + data, err := ioutil.ReadAll(file) + if err != nil { + log.Debug(err) + return + } + metaData.Add("logfile", filepath.Base(path), string(data)) +} + +func detectRunningShell(metaData *bugsnag.MetaData) { + shell, err := shell.Detect() + if err == nil { + metaData.Add("device", "shell", shell) + } +} + +func detectUname(metaData *bugsnag.MetaData) { + cmd := exec.Command("uname", "-s") + output, err := cmd.Output() + if err != nil { + return + } + metaData.Add("device", "uname", string(output)) +} + +func detectOSVersion(metaData *bugsnag.MetaData) { + metaData.Add("device", "os version", localOSVersion()) +} diff --git a/libmachine/crashreport/crash_report_logger.go b/libmachine/crashreport/crash_report_logger.go new file mode 100644 index 0000000000..c124376939 --- /dev/null +++ b/libmachine/crashreport/crash_report_logger.go @@ -0,0 +1,9 @@ +package crashreport + +import "github.com/docker/machine/libmachine/log" + +type logger struct{} + +func (d *logger) Printf(fmtString string, args ...interface{}) { + log.Debugf(fmtString, args) +} diff --git a/libmachine/crashreport/crash_report_test.go b/libmachine/crashreport/crash_report_test.go new file mode 100644 index 0000000000..b71e4367bc --- /dev/null +++ b/libmachine/crashreport/crash_report_test.go @@ -0,0 +1,39 @@ +package crashreport + +import ( + "testing" + + "io/ioutil" + + "os" + "path/filepath" + + "github.com/bugsnag/bugsnag-go" + "github.com/stretchr/testify/assert" +) + +func TestFileIsNotReadWhenNotExisting(t *testing.T) { + metaData := bugsnag.MetaData{} + addFile("not existing", &metaData) + assert.Empty(t, metaData) +} + +func TestRead(t *testing.T) { + metaData := bugsnag.MetaData{} + content := "foo\nbar\nqix\n" + fileName := createTempFile(t, content) + defer os.Remove(fileName) + addFile(fileName, &metaData) + assert.Equal(t, "foo\nbar\nqix\n", metaData["logfile"][filepath.Base(fileName)]) +} + +func createTempFile(t *testing.T, content string) string { + file, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(file.Name(), []byte(content), 0644); err != nil { + t.Fatal(err) + } + return file.Name() +} diff --git a/libmachine/crashreport/os_darwin.go b/libmachine/crashreport/os_darwin.go new file mode 100644 index 0000000000..2e887e4d10 --- /dev/null +++ b/libmachine/crashreport/os_darwin.go @@ -0,0 +1,12 @@ +package crashreport + +import "os/exec" + +func localOSVersion() string { + command := exec.Command("bash", "-c", `sw_vers | grep ProductVersion | cut -d$'\t' -f2`) + output, err := command.Output() + if err != nil { + return "" + } + return string(output) +} diff --git a/libmachine/crashreport/os_freebsd.go b/libmachine/crashreport/os_freebsd.go new file mode 100644 index 0000000000..bea85cfc39 --- /dev/null +++ b/libmachine/crashreport/os_freebsd.go @@ -0,0 +1,12 @@ +package crashreport + +import "os/exec" + +func localOSVersion() string { + command := exec.Command("uname", "-r") + output, err := command.Output() + if err != nil { + return "" + } + return string(output) +} diff --git a/libmachine/crashreport/os_linux.go b/libmachine/crashreport/os_linux.go new file mode 100644 index 0000000000..31b72a89b0 --- /dev/null +++ b/libmachine/crashreport/os_linux.go @@ -0,0 +1,12 @@ +package crashreport + +import "os/exec" + +func localOSVersion() string { + command := exec.Command("bash", "-c", `cat /etc/os-release | grep 'VERSION=' | cut -d'=' -f2`) + output, err := command.Output() + if err != nil { + return "" + } + return string(output) +} diff --git a/libmachine/crashreport/os_openbsd.go b/libmachine/crashreport/os_openbsd.go new file mode 100644 index 0000000000..bea85cfc39 --- /dev/null +++ b/libmachine/crashreport/os_openbsd.go @@ -0,0 +1,12 @@ +package crashreport + +import "os/exec" + +func localOSVersion() string { + command := exec.Command("uname", "-r") + output, err := command.Output() + if err != nil { + return "" + } + return string(output) +} diff --git a/libmachine/crashreport/os_windows.go b/libmachine/crashreport/os_windows.go new file mode 100644 index 0000000000..fff0265382 --- /dev/null +++ b/libmachine/crashreport/os_windows.go @@ -0,0 +1,47 @@ +package crashreport + +import ( + "os/exec" + "strings" +) + +func localOSVersion() string { + command := exec.Command("ver") + output, err := command.Output() + if err == nil { + return parseVerOutput(string(output)) + } + + command = exec.Command("systeminfo") + output, err = command.Output() + if err == nil { + return parseSystemInfoOutput(string(output)) + } + + return "" +} + +func parseSystemInfoOutput(output string) string { + lines := strings.Split(string(output), "\n") + for _, line := range lines { + if strings.HasPrefix(line, "OS Version:") { + return strings.TrimSpace(line[len("OS Version:"):]) + } + } + + // If we couldn't find the version, maybe the output is not in English + // Let's parse the fourth line since it seems to be the one always used + // for the version. + if len(lines) >= 4 { + parts := strings.Split(lines[3], ":") + if len(parts) == 2 { + return strings.TrimSpace(parts[1]) + } + } + + return "" +} + +func parseVerOutput(output string) string { + return strings.TrimSpace(output) +} diff --git a/libmachine/crashreport/os_windows_test.go b/libmachine/crashreport/os_windows_test.go new file mode 100644 index 0000000000..b9cdcdc983 --- /dev/null +++ b/libmachine/crashreport/os_windows_test.go @@ -0,0 +1,47 @@ +package crashreport + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParseVerOutput(t *testing.T) { + output := ` + +Microsoft Windows [version 6.3.9600] + +` + + assert.Equal(t, "Microsoft Windows [version 6.3.9600]", parseVerOutput(output)) +} + +func TestParseSystemInfoOutput(t *testing.T) { + output := ` +Host Name: DESKTOP-3A5PULA +OS Name: Microsoft Windows 10 Enterprise +OS Version: 10.0.10240 N/A Build 10240 +OS Manufacturer: Microsoft Corporation +OS Configuration: Standalone Workstation +OS Build Type: Multiprocessor Free +Registered Owner: Windows User +` + + assert.Equal(t, "10.0.10240 N/A Build 10240", parseSystemInfoOutput(output)) +} + +func TestParseNonEnglishSystemInfoOutput(t *testing.T) { + output := ` +Ignored: ... +Ignored: ... +Version du Système: 10.0.10350 +` + + assert.Equal(t, "10.0.10350", parseSystemInfoOutput(output)) +} + +func TestParseInvalidSystemInfoOutput(t *testing.T) { + output := "Invalid" + + assert.Empty(t, parseSystemInfoOutput(output)) +} diff --git a/libmachine/drivers/base.go b/libmachine/drivers/base.go new file mode 100644 index 0000000000..4ed066432c --- /dev/null +++ b/libmachine/drivers/base.go @@ -0,0 +1,94 @@ +package drivers + +import ( + "errors" + "path/filepath" +) + +const ( + DefaultSSHUser = "root" + DefaultSSHPort = 22 + DefaultEngineInstallURL = "https://get.docker.com" +) + +// BaseDriver - Embed this struct into drivers to provide the common set +// of fields and functions. +type BaseDriver struct { + IPAddress string + MachineName string + SSHUser string + SSHPort int + SSHKeyPath string + StorePath string + SwarmMaster bool + SwarmHost string + SwarmDiscovery string +} + +// DriverName returns the name of the driver +func (d *BaseDriver) DriverName() string { + return "unknown" +} + +// GetMachineName returns the machine name +func (d *BaseDriver) GetMachineName() string { + return d.MachineName +} + +// GetIP returns the ip +func (d *BaseDriver) GetIP() (string, error) { + if d.IPAddress == "" { + return "", errors.New("IP address is not set") + } + return d.IPAddress, nil +} + +// GetSSHKeyPath returns the ssh key path +func (d *BaseDriver) GetSSHKeyPath() string { + if d.SSHKeyPath == "" { + d.SSHKeyPath = d.ResolveStorePath("id_rsa") + } + return d.SSHKeyPath +} + +// GetSSHPort returns the ssh port, 22 if not specified +func (d *BaseDriver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = DefaultSSHPort + } + + return d.SSHPort, nil +} + +// GetSSHUsername returns the ssh user name, root if not specified +func (d *BaseDriver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = DefaultSSHUser + } + return d.SSHUser +} + +// PreCreateCheck is called to enforce pre-creation steps +func (d *BaseDriver) PreCreateCheck() error { + return nil +} + +// ResolveStorePath returns the store path where the machine is +func (d *BaseDriver) ResolveStorePath(file string) string { + return filepath.Join(d.StorePath, "machines", d.MachineName, file) +} + +// SetSwarmConfigFromFlags configures the driver for swarm +func (d *BaseDriver) SetSwarmConfigFromFlags(flags DriverOptions) { + d.SwarmMaster = flags.Bool("swarm-master") + d.SwarmHost = flags.String("swarm-host") + d.SwarmDiscovery = flags.String("swarm-discovery") +} + +func EngineInstallURLFlagSet(flags DriverOptions) bool { + return EngineInstallURLSet(flags.String("engine-install-url")) +} + +func EngineInstallURLSet(url string) bool { + return url != DefaultEngineInstallURL && url != "" +} diff --git a/libmachine/drivers/base_test.go b/libmachine/drivers/base_test.go new file mode 100644 index 0000000000..0b824aaf7a --- /dev/null +++ b/libmachine/drivers/base_test.go @@ -0,0 +1,50 @@ +package drivers + +import ( + "errors" + "testing" + + "github.com/docker/machine/libmachine/mcnflag" + "github.com/stretchr/testify/assert" +) + +func TestIP(t *testing.T) { + cases := []struct { + baseDriver *BaseDriver + expectedIP string + expectedErr error + }{ + {&BaseDriver{}, "", errors.New("IP address is not set")}, + {&BaseDriver{IPAddress: "2001:4860:0:2001::68"}, "2001:4860:0:2001::68", nil}, + {&BaseDriver{IPAddress: "192.168.0.1"}, "192.168.0.1", nil}, + {&BaseDriver{IPAddress: "::1"}, "::1", nil}, + {&BaseDriver{IPAddress: "hostname"}, "hostname", nil}, + } + + for _, c := range cases { + ip, err := c.baseDriver.GetIP() + assert.Equal(t, c.expectedIP, ip) + assert.Equal(t, c.expectedErr, err) + } +} + +func TestEngineInstallUrlFlagEmpty(t *testing.T) { + assert.False(t, EngineInstallURLFlagSet(&CheckDriverOptions{})) +} + +func createDriverOptionWithEngineInstall(url string) *CheckDriverOptions { + return &CheckDriverOptions{ + FlagsValues: map[string]interface{}{"engine-install-url": url}, + CreateFlags: []mcnflag.Flag{mcnflag.StringFlag{Name: "engine-install-url", Value: ""}}, + } +} + +func TestEngineInstallUrlFlagDefault(t *testing.T) { + options := createDriverOptionWithEngineInstall(DefaultEngineInstallURL) + assert.False(t, EngineInstallURLFlagSet(options)) +} + +func TestEngineInstallUrlFlagSet(t *testing.T) { + options := createDriverOptionWithEngineInstall("https://test.docker.com") + assert.True(t, EngineInstallURLFlagSet(options)) +} diff --git a/libmachine/drivers/check.go b/libmachine/drivers/check.go new file mode 100644 index 0000000000..677247186d --- /dev/null +++ b/libmachine/drivers/check.go @@ -0,0 +1,84 @@ +package drivers + +import "github.com/docker/machine/libmachine/mcnflag" + +// CheckDriverOptions implements DriverOptions and is used to validate flag parsing +type CheckDriverOptions struct { + FlagsValues map[string]interface{} + CreateFlags []mcnflag.Flag + InvalidFlags []string +} + +func (o *CheckDriverOptions) String(key string) string { + for _, flag := range o.CreateFlags { + if flag.String() == key { + f, ok := flag.(mcnflag.StringFlag) + if !ok { + o.InvalidFlags = append(o.InvalidFlags, flag.String()) + } + + value, present := o.FlagsValues[key].(string) + if present { + return value + } + return f.Value + } + } + + return "" +} + +func (o *CheckDriverOptions) StringSlice(key string) []string { + for _, flag := range o.CreateFlags { + if flag.String() == key { + f, ok := flag.(mcnflag.StringSliceFlag) + if !ok { + o.InvalidFlags = append(o.InvalidFlags, flag.String()) + } + + value, present := o.FlagsValues[key].([]string) + if present { + return value + } + return f.Value + } + } + + return nil +} + +func (o *CheckDriverOptions) Int(key string) int { + for _, flag := range o.CreateFlags { + if flag.String() == key { + f, ok := flag.(mcnflag.IntFlag) + if !ok { + o.InvalidFlags = append(o.InvalidFlags, flag.String()) + } + + value, present := o.FlagsValues[key].(int) + if present { + return value + } + return f.Value + } + } + + return 0 +} + +func (o *CheckDriverOptions) Bool(key string) bool { + for _, flag := range o.CreateFlags { + if flag.String() == key { + _, ok := flag.(mcnflag.BoolFlag) + if !ok { + o.InvalidFlags = append(o.InvalidFlags, flag.String()) + } + } + } + + value, present := o.FlagsValues[key].(bool) + if present { + return value + } + return false +} diff --git a/libmachine/drivers/drivers.go b/libmachine/drivers/drivers.go new file mode 100644 index 0000000000..dbc37d0e12 --- /dev/null +++ b/libmachine/drivers/drivers.go @@ -0,0 +1,109 @@ +package drivers + +import ( + "errors" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" +) + +// Driver defines how a host is created and controlled. Different types of +// driver represent different ways hosts can be created (e.g. different +// hypervisors, different cloud providers) +type Driver interface { + // Create a host using the driver's config + Create() error + + // DriverName returns the name of the driver + DriverName() string + + // GetCreateFlags returns the mcnflag.Flag slice representing the flags + // that can be set, their descriptions and defaults. + GetCreateFlags() []mcnflag.Flag + + // GetIP returns an IP or hostname that this host is available at + // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net + GetIP() (string, error) + + // GetMachineName returns the name of the machine + GetMachineName() string + + // GetSSHHostname returns hostname for use with ssh + GetSSHHostname() (string, error) + + // GetSSHKeyPath returns key path for use with ssh + GetSSHKeyPath() string + + // GetSSHPort returns port for use with ssh + GetSSHPort() (int, error) + + // GetSSHUsername returns username for use with ssh + GetSSHUsername() string + + // GetURL returns a Docker compatible host URL for connecting to this host + // e.g. tcp://1.2.3.4:2376 + GetURL() (string, error) + + // GetState returns the state that the host is in (running, stopped, etc) + GetState() (state.State, error) + + // Kill stops a host forcefully + Kill() error + + // PreCreateCheck allows for pre-create operations to make sure a driver is ready for creation + PreCreateCheck() error + + // Remove a host + Remove() error + + // Restart a host. This may just call Stop(); Start() if the provider does not + // have any special restart behaviour. + Restart() error + + // SetConfigFromFlags configures the driver with the object that was returned + // by RegisterCreateFlags + SetConfigFromFlags(opts DriverOptions) error + + // Start a host + Start() error + + // Stop a host gracefully + Stop() error +} + +var ErrHostIsNotRunning = errors.New("Host is not running") + +type DriverOptions interface { + String(key string) string + StringSlice(key string) []string + Int(key string) int + Bool(key string) bool +} + +func MachineInState(d Driver, desiredState state.State) func() bool { + return func() bool { + currentState, err := d.GetState() + if err != nil { + log.Debugf("Error getting machine state: %s", err) + } + if currentState == desiredState { + return true + } + return false + } +} + +// MustBeRunning will return an error if the machine is not in a running state. +func MustBeRunning(d Driver) error { + s, err := d.GetState() + if err != nil { + return err + } + + if s != state.Running { + return ErrHostIsNotRunning + } + + return nil +} diff --git a/libmachine/drivers/notsupported.go b/libmachine/drivers/notsupported.go new file mode 100644 index 0000000000..59a1d4e538 --- /dev/null +++ b/libmachine/drivers/notsupported.go @@ -0,0 +1,89 @@ +package drivers + +import ( + "fmt" + + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" +) + +type DriverNotSupported struct { + *BaseDriver + Name string +} + +type NotSupported struct { + DriverName string +} + +func (e NotSupported) Error() string { + return fmt.Sprintf("Driver %q not supported on this platform.", e.DriverName) +} + +// NewDriverNotSupported creates a placeholder Driver that replaces +// a driver that is not supported on a given platform. eg fusion on linux. +func NewDriverNotSupported(driverName, hostName, storePath string) Driver { + return &DriverNotSupported{ + BaseDriver: &BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + Name: driverName, + } +} + +func (d *DriverNotSupported) DriverName() string { + return d.Name +} + +func (d *DriverNotSupported) PreCreateCheck() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) GetCreateFlags() []mcnflag.Flag { + return nil +} + +func (d *DriverNotSupported) SetConfigFromFlags(flags DriverOptions) error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) GetURL() (string, error) { + return "", NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) GetSSHHostname() (string, error) { + return "", NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) GetState() (state.State, error) { + return state.Error, NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Create() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Remove() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Start() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Stop() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Restart() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Kill() error { + return NotSupported{d.DriverName()} +} + +func (d *DriverNotSupported) Upgrade() error { + return NotSupported{d.DriverName()} +} diff --git a/libmachine/drivers/plugin/localbinary/plugin.go b/libmachine/drivers/plugin/localbinary/plugin.go new file mode 100644 index 0000000000..c431c7eda9 --- /dev/null +++ b/libmachine/drivers/plugin/localbinary/plugin.go @@ -0,0 +1,250 @@ +package localbinary + +import ( + "bufio" + "fmt" + "io" + "os" + "os/exec" + "strings" + "time" + + "github.com/docker/machine/libmachine/log" +) + +var ( + // Timeout where we will bail if we're not able to properly contact the + // plugin server. + defaultTimeout = 10 * time.Second + CurrentBinaryIsDockerMachine = false + CoreDrivers = []string{"amazonec2", "azure", "digitalocean", + "exoscale", "generic", "google", "hyperv", "none", "openstack", + "rackspace", "softlayer", "virtualbox", "vmwarefusion", + "vmwarevcloudair", "vmwarevsphere"} +) + +const ( + pluginOut = "(%s) %s" + pluginErr = "(%s) DBG | %s" + PluginEnvKey = "MACHINE_PLUGIN_TOKEN" + PluginEnvVal = "42" + PluginEnvDriverName = "MACHINE_PLUGIN_DRIVER_NAME" +) + +type PluginStreamer interface { + // Return a channel for receiving the output of the stream line by + // line. + // + // It happens to be the case that we do this all inside of the main + // plugin struct today, but that may not be the case forever. + AttachStream(*bufio.Scanner) <-chan string +} + +type PluginServer interface { + // Get the address where the plugin server is listening. + Address() (string, error) + + // Serve kicks off the plugin server. + Serve() error + + // Close shuts down the initialized server. + Close() error +} + +type McnBinaryExecutor interface { + // Execute the driver plugin. Returns scanners for plugin binary + // stdout and stderr. + Start() (*bufio.Scanner, *bufio.Scanner, error) + + // Stop reading from the plugins in question. + Close() error +} + +// DriverPlugin interface wraps the underlying mechanics of starting a driver +// plugin server and then figuring out where it can be dialed. +type DriverPlugin interface { + PluginServer + PluginStreamer +} + +type Plugin struct { + Executor McnBinaryExecutor + Addr string + MachineName string + addrCh chan string + stopCh chan struct{} + timeout time.Duration +} + +type Executor struct { + pluginStdout, pluginStderr io.ReadCloser + DriverName string + cmd *exec.Cmd + binaryPath string +} + +type ErrPluginBinaryNotFound struct { + driverName string + driverPath string +} + +func (e ErrPluginBinaryNotFound) Error() string { + return fmt.Sprintf("Driver %q not found. Do you have the plugin binary %q accessible in your PATH?", e.driverName, e.driverPath) +} + +// driverPath finds the path of a driver binary by its name. +// + If the driver is a core driver, there is no separate driver binary. We reuse current binary if it's `docker-machine` +// or we assume `docker-machine` is in the PATH. +// + If the driver is NOT a core driver, then the separate binary must be in the PATH and it's name must be +// `docker-machine-driver-driverName` +func driverPath(driverName string) string { + for _, coreDriver := range CoreDrivers { + if coreDriver == driverName { + if CurrentBinaryIsDockerMachine { + return os.Args[0] + } + + return "docker-machine" + } + } + + return fmt.Sprintf("docker-machine-driver-%s", driverName) +} + +func NewPlugin(driverName string) (*Plugin, error) { + driverPath := driverPath(driverName) + binaryPath, err := exec.LookPath(driverPath) + if err != nil { + return nil, ErrPluginBinaryNotFound{driverName, driverPath} + } + + log.Debugf("Found binary path at %s", binaryPath) + + return &Plugin{ + stopCh: make(chan struct{}), + addrCh: make(chan string, 1), + Executor: &Executor{ + DriverName: driverName, + binaryPath: binaryPath, + }, + }, nil +} + +func (lbe *Executor) Start() (*bufio.Scanner, *bufio.Scanner, error) { + var err error + + log.Debugf("Launching plugin server for driver %s", lbe.DriverName) + + lbe.cmd = exec.Command(lbe.binaryPath) + + lbe.pluginStdout, err = lbe.cmd.StdoutPipe() + if err != nil { + return nil, nil, fmt.Errorf("Error getting cmd stdout pipe: %s", err) + } + + lbe.pluginStderr, err = lbe.cmd.StderrPipe() + if err != nil { + return nil, nil, fmt.Errorf("Error getting cmd stderr pipe: %s", err) + } + + outScanner := bufio.NewScanner(lbe.pluginStdout) + errScanner := bufio.NewScanner(lbe.pluginStderr) + + os.Setenv(PluginEnvKey, PluginEnvVal) + os.Setenv(PluginEnvDriverName, lbe.DriverName) + + if err := lbe.cmd.Start(); err != nil { + return nil, nil, fmt.Errorf("Error starting plugin binary: %s", err) + } + + return outScanner, errScanner, nil +} + +func (lbe *Executor) Close() error { + if err := lbe.cmd.Wait(); err != nil { + return fmt.Errorf("Error waiting for binary close: %s", err) + } + + return nil +} + +func stream(scanner *bufio.Scanner, streamOutCh chan<- string, stopCh <-chan struct{}) { + for scanner.Scan() { + line := scanner.Text() + if err := scanner.Err(); err != nil { + log.Warnf("Scanning stream: %s", err) + } + select { + case streamOutCh <- strings.Trim(line, "\n"): + case <-stopCh: + return + } + } +} + +func (lbp *Plugin) AttachStream(scanner *bufio.Scanner) <-chan string { + streamOutCh := make(chan string) + go stream(scanner, streamOutCh, lbp.stopCh) + return streamOutCh +} + +func (lbp *Plugin) execServer() error { + outScanner, errScanner, err := lbp.Executor.Start() + if err != nil { + return err + } + + // Scan just one line to get the address, then send it to the relevant + // channel. + outScanner.Scan() + addr := outScanner.Text() + if err := outScanner.Err(); err != nil { + return fmt.Errorf("Reading plugin address failed: %s", err) + } + + lbp.addrCh <- strings.TrimSpace(addr) + + stdOutCh := lbp.AttachStream(outScanner) + stdErrCh := lbp.AttachStream(errScanner) + + for { + select { + case out := <-stdOutCh: + log.Infof(pluginOut, lbp.MachineName, out) + case err := <-stdErrCh: + log.Debugf(pluginErr, lbp.MachineName, err) + case <-lbp.stopCh: + if err := lbp.Executor.Close(); err != nil { + return fmt.Errorf("Error closing local plugin binary: %s", err) + } + return nil + } + } +} + +func (lbp *Plugin) Serve() error { + return lbp.execServer() +} + +func (lbp *Plugin) Address() (string, error) { + if lbp.Addr == "" { + if lbp.timeout == 0 { + lbp.timeout = defaultTimeout + } + + select { + case lbp.Addr = <-lbp.addrCh: + log.Debugf("Plugin server listening at address %s", lbp.Addr) + close(lbp.addrCh) + return lbp.Addr, nil + case <-time.After(lbp.timeout): + return "", fmt.Errorf("Failed to dial the plugin server in %s", lbp.timeout) + } + } + return lbp.Addr, nil +} + +func (lbp *Plugin) Close() error { + close(lbp.stopCh) + return nil +} diff --git a/libmachine/drivers/plugin/localbinary/plugin_test.go b/libmachine/drivers/plugin/localbinary/plugin_test.go new file mode 100644 index 0000000000..c8d0cbb49f --- /dev/null +++ b/libmachine/drivers/plugin/localbinary/plugin_test.go @@ -0,0 +1,159 @@ +package localbinary + +import ( + "bufio" + "fmt" + "io" + "testing" + "time" + + "os" + + "github.com/docker/machine/libmachine/log" + "github.com/stretchr/testify/assert" +) + +type FakeExecutor struct { + stdout, stderr io.ReadCloser + closed bool +} + +func (fe *FakeExecutor) Start() (*bufio.Scanner, *bufio.Scanner, error) { + return bufio.NewScanner(fe.stdout), bufio.NewScanner(fe.stderr), nil +} + +func (fe *FakeExecutor) Close() error { + fe.closed = true + return nil +} + +func TestLocalBinaryPluginAddress(t *testing.T) { + lbp := &Plugin{} + expectedAddr := "127.0.0.1:12345" + + lbp.addrCh = make(chan string, 1) + lbp.addrCh <- expectedAddr + + // Call the first time to read from the channel + addr, err := lbp.Address() + if err != nil { + t.Fatalf("Expected no error, instead got %s", err) + } + if addr != expectedAddr { + t.Fatal("Expected did not match actual address") + } + + // Call the second time to read the "cached" address value + addr, err = lbp.Address() + if err != nil { + t.Fatalf("Expected no error, instead got %s", err) + } + if addr != expectedAddr { + t.Fatal("Expected did not match actual address") + } +} + +func TestLocalBinaryPluginAddressTimeout(t *testing.T) { + if testing.Short() { + t.Skip("Skipping timeout test") + } + + lbp := &Plugin{ + addrCh: make(chan string, 1), + timeout: 1 * time.Second, + } + + addr, err := lbp.Address() + + assert.Empty(t, addr) + assert.EqualError(t, err, "Failed to dial the plugin server in 1s") +} + +func TestLocalBinaryPluginClose(t *testing.T) { + lbp := &Plugin{} + lbp.stopCh = make(chan struct{}) + go lbp.Close() + _, isOpen := <-lbp.stopCh + if isOpen { + t.Fatal("Close did not send a stop message on the proper channel") + } +} + +func TestExecServer(t *testing.T) { + logOutReader, logOutWriter := io.Pipe() + logErrReader, logErrWriter := io.Pipe() + + log.SetDebug(true) + log.SetOutWriter(logOutWriter) + log.SetErrWriter(logErrWriter) + + defer func() { + log.SetDebug(false) + log.SetOutWriter(os.Stdout) + log.SetErrWriter(os.Stderr) + }() + + stdoutReader, stdoutWriter := io.Pipe() + stderrReader, stderrWriter := io.Pipe() + + fe := &FakeExecutor{ + stdout: stdoutReader, + stderr: stderrReader, + } + + machineName := "test" + lbp := &Plugin{ + MachineName: machineName, + Executor: fe, + addrCh: make(chan string, 1), + stopCh: make(chan struct{}), + } + + finalErr := make(chan error) + + // Start the docker-machine-foo plugin server + go func() { + finalErr <- lbp.execServer() + }() + + logOutScanner := bufio.NewScanner(logOutReader) + logErrScanner := bufio.NewScanner(logErrReader) + + // Write the ip address + expectedAddr := "127.0.0.1:12345" + if _, err := io.WriteString(stdoutWriter, expectedAddr+"\n"); err != nil { + t.Fatalf("Error attempting to write plugin address: %s", err) + } + + if addr := <-lbp.addrCh; addr != expectedAddr { + t.Fatalf("Expected to read the expected address properly in server but did not") + } + + // Write a log in stdout + expectedPluginOut := "Doing some fun plugin stuff..." + if _, err := io.WriteString(stdoutWriter, expectedPluginOut+"\n"); err != nil { + t.Fatalf("Error attempting to write to out in plugin: %s", err) + } + + expectedOut := fmt.Sprintf(pluginOut, machineName, expectedPluginOut) + if logOutScanner.Scan(); logOutScanner.Text() != expectedOut { + t.Fatalf("Output written to log was not what we expected\nexpected: %s\nactual: %s", expectedOut, logOutScanner.Text()) + } + + // Write a log in stderr + expectedPluginErr := "Uh oh, something in plugin went wrong..." + if _, err := io.WriteString(stderrWriter, expectedPluginErr+"\n"); err != nil { + t.Fatalf("Error attempting to write to err in plugin: %s", err) + } + + expectedErr := fmt.Sprintf(pluginErr, machineName, expectedPluginErr) + if logErrScanner.Scan(); logErrScanner.Text() != expectedErr { + t.Fatalf("Error written to log was not what we expected\nexpected: %s\nactual: %s", expectedErr, logErrScanner.Text()) + } + + lbp.Close() + + if err := <-finalErr; err != nil { + t.Fatalf("Error serving: %s", err) + } +} diff --git a/libmachine/drivers/plugin/register_driver.go b/libmachine/drivers/plugin/register_driver.go new file mode 100644 index 0000000000..27e0dbc33d --- /dev/null +++ b/libmachine/drivers/plugin/register_driver.go @@ -0,0 +1,63 @@ +package plugin + +import ( + "fmt" + "net" + "net/http" + "net/rpc" + "os" + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/drivers/plugin/localbinary" + "github.com/docker/machine/libmachine/drivers/rpc" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/version" +) + +var ( + heartbeatTimeout = 10 * time.Second +) + +func RegisterDriver(d drivers.Driver) { + if os.Getenv(localbinary.PluginEnvKey) != localbinary.PluginEnvVal { + fmt.Fprintf(os.Stderr, `This is a Docker Machine plugin binary. +Plugin binaries are not intended to be invoked directly. +Please use this plugin through the main 'docker-machine' binary. +(API version: %d) +`, version.APIVersion) + os.Exit(1) + } + + log.SetDebug(true) + os.Setenv("MACHINE_DEBUG", "1") + + rpcd := rpcdriver.NewRPCServerDriver(d) + rpc.RegisterName(rpcdriver.RPCServiceNameV0, rpcd) + rpc.RegisterName(rpcdriver.RPCServiceNameV1, rpcd) + rpc.HandleHTTP() + + listener, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + fmt.Fprintf(os.Stderr, "Error loading RPC server: %s\n", err) + os.Exit(1) + } + defer listener.Close() + + fmt.Println(listener.Addr()) + + go http.Serve(listener, nil) + + for { + select { + case <-rpcd.CloseCh: + log.Debug("Closing plugin on server side") + os.Exit(0) + case <-rpcd.HeartbeatCh: + continue + case <-time.After(heartbeatTimeout): + // TODO: Add heartbeat retry logic + os.Exit(1) + } + } +} diff --git a/libmachine/drivers/rpc/client_driver.go b/libmachine/drivers/rpc/client_driver.go new file mode 100644 index 0000000000..5ce22cdcd6 --- /dev/null +++ b/libmachine/drivers/rpc/client_driver.go @@ -0,0 +1,367 @@ +package rpcdriver + +import ( + "fmt" + "net/rpc" + "sync" + "time" + + "io" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/drivers/plugin/localbinary" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/version" +) + +var ( + heartbeatInterval = 5 * time.Second +) + +type RPCClientDriverFactory interface { + NewRPCClientDriver(driverName string, rawDriver []byte) (*RPCClientDriver, error) + io.Closer +} + +type DefaultRPCClientDriverFactory struct { + openedDrivers []*RPCClientDriver + openedDriversLock sync.Locker +} + +func NewRPCClientDriverFactory() RPCClientDriverFactory { + return &DefaultRPCClientDriverFactory{ + openedDrivers: []*RPCClientDriver{}, + openedDriversLock: &sync.Mutex{}, + } +} + +type RPCClientDriver struct { + plugin localbinary.DriverPlugin + heartbeatDoneCh chan bool + Client *InternalClient +} + +type RPCCall struct { + ServiceMethod string + Args interface{} + Reply interface{} +} + +type InternalClient struct { + MachineName string + RPCClient *rpc.Client + rpcServiceName string +} + +const ( + RPCServiceNameV0 = `RpcServerDriver` + RPCServiceNameV1 = `RPCServerDriver` + + HeartbeatMethod = `.Heartbeat` + GetVersionMethod = `.GetVersion` + CloseMethod = `.Close` + GetCreateFlagsMethod = `.GetCreateFlags` + SetConfigRawMethod = `.SetConfigRaw` + GetConfigRawMethod = `.GetConfigRaw` + DriverNameMethod = `.DriverName` + SetConfigFromFlagsMethod = `.SetConfigFromFlags` + GetURLMethod = `.GetURL` + GetMachineNameMethod = `.GetMachineName` + GetIPMethod = `.GetIP` + GetSSHHostnameMethod = `.GetSSHHostname` + GetSSHKeyPathMethod = `.GetSSHKeyPath` + GetSSHPortMethod = `.GetSSHPort` + GetSSHUsernameMethod = `.GetSSHUsername` + GetStateMethod = `.GetState` + PreCreateCheckMethod = `.PreCreateCheck` + CreateMethod = `.Create` + RemoveMethod = `.Remove` + StartMethod = `.Start` + StopMethod = `.Stop` + RestartMethod = `.Restart` + KillMethod = `.Kill` + UpgradeMethod = `.Upgrade` +) + +func (ic *InternalClient) Call(serviceMethod string, args interface{}, reply interface{}) error { + if serviceMethod != HeartbeatMethod { + log.Debugf("(%s) Calling %+v", ic.MachineName, serviceMethod) + } + return ic.RPCClient.Call(ic.rpcServiceName+serviceMethod, args, reply) +} + +func (ic *InternalClient) switchToV0() { + ic.rpcServiceName = RPCServiceNameV0 +} + +func NewInternalClient(rpcclient *rpc.Client) *InternalClient { + return &InternalClient{ + RPCClient: rpcclient, + rpcServiceName: RPCServiceNameV1, + } +} + +func (f *DefaultRPCClientDriverFactory) Close() error { + f.openedDriversLock.Lock() + defer f.openedDriversLock.Unlock() + + for _, openedDriver := range f.openedDrivers { + if err := openedDriver.close(); err != nil { + // No need to display an error. + // There's nothing we can do and it doesn't add value to the user. + } + } + f.openedDrivers = []*RPCClientDriver{} + + return nil +} + +func (f *DefaultRPCClientDriverFactory) NewRPCClientDriver(driverName string, rawDriver []byte) (*RPCClientDriver, error) { + mcnName := "" + + p, err := localbinary.NewPlugin(driverName) + if err != nil { + return nil, err + } + + go func() { + if err := p.Serve(); err != nil { + // TODO: Is this best approach? + log.Warn(err) + return + } + }() + + addr, err := p.Address() + if err != nil { + return nil, fmt.Errorf("Error attempting to get plugin server address for RPC: %s", err) + } + + rpcclient, err := rpc.DialHTTP("tcp", addr) + if err != nil { + return nil, err + } + + c := &RPCClientDriver{ + Client: NewInternalClient(rpcclient), + heartbeatDoneCh: make(chan bool), + } + + f.openedDriversLock.Lock() + f.openedDrivers = append(f.openedDrivers, c) + f.openedDriversLock.Unlock() + + var serverVersion int + if err := c.Client.Call(GetVersionMethod, struct{}{}, &serverVersion); err != nil { + // this is the first call we make to the server. We try to play nice with old pre 0.5.1 client, + // by gracefully trying old RPCServiceName, we do this only once, and keep the result for future calls. + log.Debugf(err.Error()) + log.Debugf("Client (%s) with %s does not work, re-attempting with %s", c.Client.MachineName, RPCServiceNameV1, RPCServiceNameV0) + c.Client.switchToV0() + if err := c.Client.Call(GetVersionMethod, struct{}{}, &serverVersion); err != nil { + return nil, err + } + } + + if serverVersion != version.APIVersion { + return nil, fmt.Errorf("Driver binary uses an incompatible API version (%d)", serverVersion) + } + log.Debug("Using API Version ", serverVersion) + + go func(c *RPCClientDriver) { + for { + select { + case <-c.heartbeatDoneCh: + return + case <-time.After(heartbeatInterval): + if err := c.Client.Call(HeartbeatMethod, struct{}{}, nil); err != nil { + log.Warnf("Wrapper Docker Machine process exiting due to closed plugin server (%s)", err) + if err := c.close(); err != nil { + log.Warn(err) + } + } + } + } + }(c) + + if err := c.SetConfigRaw(rawDriver); err != nil { + return nil, err + } + + mcnName = c.GetMachineName() + p.MachineName = mcnName + c.Client.MachineName = mcnName + c.plugin = p + + return c, nil +} + +func (c *RPCClientDriver) MarshalJSON() ([]byte, error) { + return c.GetConfigRaw() +} + +func (c *RPCClientDriver) UnmarshalJSON(data []byte) error { + return c.SetConfigRaw(data) +} + +func (c *RPCClientDriver) close() error { + c.heartbeatDoneCh <- true + close(c.heartbeatDoneCh) + + log.Debug("Making call to close driver server") + + if err := c.Client.Call(CloseMethod, struct{}{}, nil); err != nil { + log.Debugf("Failed to make call to close driver server: %s", err) + } else { + log.Debug("Successfully made call to close driver server") + } + + log.Debug("Making call to close connection to plugin binary") + + return c.plugin.Close() +} + +// Helper method to make requests which take no arguments and return simply a +// string, e.g. "GetIP". +func (c *RPCClientDriver) rpcStringCall(method string) (string, error) { + var info string + + if err := c.Client.Call(method, struct{}{}, &info); err != nil { + return "", err + } + + return info, nil +} + +func (c *RPCClientDriver) GetCreateFlags() []mcnflag.Flag { + var flags []mcnflag.Flag + + if err := c.Client.Call(GetCreateFlagsMethod, struct{}{}, &flags); err != nil { + log.Warnf("Error attempting call to get create flags: %s", err) + } + + return flags +} + +func (c *RPCClientDriver) SetConfigRaw(data []byte) error { + return c.Client.Call(SetConfigRawMethod, data, nil) +} + +func (c *RPCClientDriver) GetConfigRaw() ([]byte, error) { + var data []byte + + if err := c.Client.Call(GetConfigRawMethod, struct{}{}, &data); err != nil { + return nil, err + } + + return data, nil +} + +// DriverName returns the name of the driver +func (c *RPCClientDriver) DriverName() string { + driverName, err := c.rpcStringCall(DriverNameMethod) + if err != nil { + log.Warnf("Error attempting call to get driver name: %s", err) + } + + return driverName +} + +func (c *RPCClientDriver) SetConfigFromFlags(flags drivers.DriverOptions) error { + return c.Client.Call(SetConfigFromFlagsMethod, &flags, nil) +} + +func (c *RPCClientDriver) GetURL() (string, error) { + return c.rpcStringCall(GetURLMethod) +} + +func (c *RPCClientDriver) GetMachineName() string { + name, err := c.rpcStringCall(GetMachineNameMethod) + if err != nil { + log.Warnf("Error attempting call to get machine name: %s", err) + } + + return name +} + +func (c *RPCClientDriver) GetIP() (string, error) { + return c.rpcStringCall(GetIPMethod) +} + +func (c *RPCClientDriver) GetSSHHostname() (string, error) { + return c.rpcStringCall(GetSSHHostnameMethod) +} + +// GetSSHKeyPath returns the key path +// TODO: This method doesn't even make sense to have with RPC. +func (c *RPCClientDriver) GetSSHKeyPath() string { + path, err := c.rpcStringCall(GetSSHKeyPathMethod) + if err != nil { + log.Warnf("Error attempting call to get SSH key path: %s", err) + } + + return path +} + +func (c *RPCClientDriver) GetSSHPort() (int, error) { + var port int + + if err := c.Client.Call(GetSSHPortMethod, struct{}{}, &port); err != nil { + return 0, err + } + + return port, nil +} + +func (c *RPCClientDriver) GetSSHUsername() string { + username, err := c.rpcStringCall(GetSSHUsernameMethod) + if err != nil { + log.Warnf("Error attempting call to get SSH username: %s", err) + } + + return username +} + +func (c *RPCClientDriver) GetState() (state.State, error) { + var s state.State + + if err := c.Client.Call(GetStateMethod, struct{}{}, &s); err != nil { + return state.Error, err + } + + return s, nil +} + +func (c *RPCClientDriver) PreCreateCheck() error { + return c.Client.Call(PreCreateCheckMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Create() error { + return c.Client.Call(CreateMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Remove() error { + return c.Client.Call(RemoveMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Start() error { + return c.Client.Call(StartMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Stop() error { + return c.Client.Call(StopMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Restart() error { + return c.Client.Call(RestartMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Kill() error { + return c.Client.Call(KillMethod, struct{}{}, nil) +} + +func (c *RPCClientDriver) Upgrade() error { + return c.Client.Call(UpgradeMethod, struct{}{}, nil) +} diff --git a/libmachine/drivers/rpc/server_driver.go b/libmachine/drivers/rpc/server_driver.go new file mode 100644 index 0000000000..6fb3f3d5d8 --- /dev/null +++ b/libmachine/drivers/rpc/server_driver.go @@ -0,0 +1,227 @@ +package rpcdriver + +import ( + "encoding/gob" + "encoding/json" + "fmt" + "runtime/debug" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/version" +) + +type Stacker interface { + Stack() []byte +} + +type StandardStack struct{} + +func (ss *StandardStack) Stack() []byte { + return debug.Stack() +} + +var ( + stdStacker Stacker = &StandardStack{} +) + +func init() { + gob.Register(new(RPCFlags)) + gob.Register(new(mcnflag.IntFlag)) + gob.Register(new(mcnflag.StringFlag)) + gob.Register(new(mcnflag.StringSliceFlag)) + gob.Register(new(mcnflag.BoolFlag)) +} + +type RPCFlags struct { + Values map[string]interface{} +} + +func (r RPCFlags) Get(key string) interface{} { + val, ok := r.Values[key] + if !ok { + log.Warnf("Trying to access option %s which does not exist", key) + log.Warn("THIS ***WILL*** CAUSE UNEXPECTED BEHAVIOR") + } + return val +} + +func (r RPCFlags) String(key string) string { + val, ok := r.Get(key).(string) + if !ok { + log.Warnf("Type assertion did not go smoothly to string for key %s", key) + } + return val +} + +func (r RPCFlags) StringSlice(key string) []string { + val, ok := r.Get(key).([]string) + if !ok { + log.Warnf("Type assertion did not go smoothly to string slice for key %s", key) + } + return val +} + +func (r RPCFlags) Int(key string) int { + val, ok := r.Get(key).(int) + if !ok { + log.Warnf("Type assertion did not go smoothly to int for key %s", key) + } + return val +} + +func (r RPCFlags) Bool(key string) bool { + val, ok := r.Get(key).(bool) + if !ok { + log.Warnf("Type assertion did not go smoothly to bool for key %s", key) + } + return val +} + +type RPCServerDriver struct { + ActualDriver drivers.Driver + CloseCh chan bool + HeartbeatCh chan bool +} + +func NewRPCServerDriver(d drivers.Driver) *RPCServerDriver { + return &RPCServerDriver{ + ActualDriver: d, + CloseCh: make(chan bool), + HeartbeatCh: make(chan bool), + } +} + +func (r *RPCServerDriver) Close(_, _ *struct{}) error { + r.CloseCh <- true + return nil +} + +func (r *RPCServerDriver) GetVersion(_ *struct{}, reply *int) error { + *reply = version.APIVersion + return nil +} + +func (r *RPCServerDriver) GetConfigRaw(_ *struct{}, reply *[]byte) error { + driverData, err := json.Marshal(r.ActualDriver) + if err != nil { + return err + } + + *reply = driverData + + return nil +} + +func (r *RPCServerDriver) GetCreateFlags(_ *struct{}, reply *[]mcnflag.Flag) error { + *reply = r.ActualDriver.GetCreateFlags() + return nil +} + +func (r *RPCServerDriver) SetConfigRaw(data []byte, _ *struct{}) error { + return json.Unmarshal(data, &r.ActualDriver) +} + +func trapPanic(err *error) { + if r := recover(); r != nil { + *err = fmt.Errorf("Panic in the driver: %s\n%s", r.(error), stdStacker.Stack()) + } +} + +func (r *RPCServerDriver) Create(_, _ *struct{}) (err error) { + // In an ideal world, plugins wouldn't ever panic. However, panics + // have been known to happen and cause issues. Therefore, we recover + // and do not crash the RPC server completely in the case of a panic + // during create. + defer trapPanic(&err) + + err = r.ActualDriver.Create() + + return err +} + +func (r *RPCServerDriver) DriverName(_ *struct{}, reply *string) error { + *reply = r.ActualDriver.DriverName() + return nil +} + +func (r *RPCServerDriver) GetIP(_ *struct{}, reply *string) error { + ip, err := r.ActualDriver.GetIP() + *reply = ip + return err +} + +func (r *RPCServerDriver) GetMachineName(_ *struct{}, reply *string) error { + *reply = r.ActualDriver.GetMachineName() + return nil +} + +func (r *RPCServerDriver) GetSSHHostname(_ *struct{}, reply *string) error { + hostname, err := r.ActualDriver.GetSSHHostname() + *reply = hostname + return err +} + +func (r *RPCServerDriver) GetSSHKeyPath(_ *struct{}, reply *string) error { + *reply = r.ActualDriver.GetSSHKeyPath() + return nil +} + +// GetSSHPort returns port for use with ssh +func (r *RPCServerDriver) GetSSHPort(_ *struct{}, reply *int) error { + port, err := r.ActualDriver.GetSSHPort() + *reply = port + return err +} + +func (r *RPCServerDriver) GetSSHUsername(_ *struct{}, reply *string) error { + *reply = r.ActualDriver.GetSSHUsername() + return nil +} + +func (r *RPCServerDriver) GetURL(_ *struct{}, reply *string) error { + info, err := r.ActualDriver.GetURL() + *reply = info + return err +} + +func (r *RPCServerDriver) GetState(_ *struct{}, reply *state.State) error { + s, err := r.ActualDriver.GetState() + *reply = s + return err +} + +func (r *RPCServerDriver) Kill(_ *struct{}, _ *struct{}) error { + return r.ActualDriver.Kill() +} + +func (r *RPCServerDriver) PreCreateCheck(_ *struct{}, _ *struct{}) error { + return r.ActualDriver.PreCreateCheck() +} + +func (r *RPCServerDriver) Remove(_ *struct{}, _ *struct{}) error { + return r.ActualDriver.Remove() +} + +func (r *RPCServerDriver) Restart(_ *struct{}, _ *struct{}) error { + return r.ActualDriver.Restart() +} + +func (r *RPCServerDriver) SetConfigFromFlags(flags *drivers.DriverOptions, _ *struct{}) error { + return r.ActualDriver.SetConfigFromFlags(*flags) +} + +func (r *RPCServerDriver) Start(_ *struct{}, _ *struct{}) error { + return r.ActualDriver.Start() +} + +func (r *RPCServerDriver) Stop(_ *struct{}, _ *struct{}) error { + return r.ActualDriver.Stop() +} + +func (r *RPCServerDriver) Heartbeat(_ *struct{}, _ *struct{}) error { + r.HeartbeatCh <- true + return nil +} diff --git a/libmachine/drivers/rpc/server_driver_test.go b/libmachine/drivers/rpc/server_driver_test.go new file mode 100644 index 0000000000..952684df39 --- /dev/null +++ b/libmachine/drivers/rpc/server_driver_test.go @@ -0,0 +1,75 @@ +package rpcdriver + +import ( + "errors" + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/stretchr/testify/assert" +) + +type panicDriver struct { + *fakedriver.Driver + panicErr error + returnErr error +} + +type FakeStacker struct { + trace []byte +} + +func (fs *FakeStacker) Stack() []byte { + return fs.trace +} + +func (p *panicDriver) Create() error { + if p.panicErr != nil { + panic(p.panicErr) + } + return p.returnErr +} + +func TestRPCServerDriverCreate(t *testing.T) { + testCases := []struct { + description string + expectedErr error + serverDriver *RPCServerDriver + stacker Stacker + }{ + { + description: "Happy path", + expectedErr: nil, + serverDriver: &RPCServerDriver{ + ActualDriver: &panicDriver{ + returnErr: nil, + }, + }, + }, + { + description: "Normal error, no panic", + expectedErr: errors.New("API not available"), + serverDriver: &RPCServerDriver{ + ActualDriver: &panicDriver{ + returnErr: errors.New("API not available"), + }, + }, + }, + { + description: "Panic happened during create", + expectedErr: errors.New("Panic in the driver: index out of range\nSTACK TRACE"), + serverDriver: &RPCServerDriver{ + ActualDriver: &panicDriver{ + panicErr: errors.New("index out of range"), + }, + }, + stacker: &FakeStacker{ + trace: []byte("STACK TRACE"), + }, + }, + } + + for _, tc := range testCases { + stdStacker = tc.stacker + assert.Equal(t, tc.expectedErr, tc.serverDriver.Create(nil, nil)) + } +} diff --git a/libmachine/drivers/serial.go b/libmachine/drivers/serial.go new file mode 100644 index 0000000000..056704eefd --- /dev/null +++ b/libmachine/drivers/serial.go @@ -0,0 +1,172 @@ +package drivers + +import ( + "sync" + + "encoding/json" + + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" +) + +var stdLock = &sync.Mutex{} + +// SerialDriver is a wrapper struct which is used to ensure that RPC calls +// to a driver only occur one at a time. +// Some providers, e.g. virtualbox, should not run driver operations at the +// same time as other driver instances of the same type. Otherwise, we scrape +// up against VirtualBox's own locking mechanisms. +// +// It would be preferable to simply have a lock around, say, the VBoxManage +// command, but with our current one-server-process-per-machine model it is +// impossible to dictate this locking on the server side. +type SerialDriver struct { + Driver + sync.Locker +} + +func NewSerialDriver(innerDriver Driver) Driver { + return newSerialDriverWithLock(innerDriver, stdLock) +} + +func newSerialDriverWithLock(innerDriver Driver, lock sync.Locker) Driver { + return &SerialDriver{ + Driver: innerDriver, + Locker: lock, + } +} + +// Create a host using the driver's config +func (d *SerialDriver) Create() error { + d.Lock() + defer d.Unlock() + return d.Driver.Create() +} + +// DriverName returns the name of the driver as it is registered +func (d *SerialDriver) DriverName() string { + d.Lock() + defer d.Unlock() + return d.Driver.DriverName() +} + +// GetCreateFlags returns the mcnflag.Flag slice representing the flags +// that can be set, their descriptions and defaults. +func (d *SerialDriver) GetCreateFlags() []mcnflag.Flag { + d.Lock() + defer d.Unlock() + return d.Driver.GetCreateFlags() +} + +// GetIP returns an IP or hostname that this host is available at +// e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net +func (d *SerialDriver) GetIP() (string, error) { + d.Lock() + defer d.Unlock() + return d.Driver.GetIP() +} + +// GetMachineName returns the name of the machine +func (d *SerialDriver) GetMachineName() string { + d.Lock() + defer d.Unlock() + return d.Driver.GetMachineName() +} + +// GetSSHHostname returns hostname for use with ssh +func (d *SerialDriver) GetSSHHostname() (string, error) { + d.Lock() + defer d.Unlock() + return d.Driver.GetSSHHostname() +} + +// GetSSHKeyPath returns key path for use with ssh +func (d *SerialDriver) GetSSHKeyPath() string { + d.Lock() + defer d.Unlock() + return d.Driver.GetSSHKeyPath() +} + +// GetSSHPort returns port for use with ssh +func (d *SerialDriver) GetSSHPort() (int, error) { + d.Lock() + defer d.Unlock() + return d.Driver.GetSSHPort() +} + +// GetSSHUsername returns username for use with ssh +func (d *SerialDriver) GetSSHUsername() string { + d.Lock() + defer d.Unlock() + return d.Driver.GetSSHUsername() +} + +// GetURL returns a Docker compatible host URL for connecting to this host +// e.g. tcp://1.2.3.4:2376 +func (d *SerialDriver) GetURL() (string, error) { + d.Lock() + defer d.Unlock() + return d.Driver.GetURL() +} + +// GetState returns the state that the host is in (running, stopped, etc) +func (d *SerialDriver) GetState() (state.State, error) { + d.Lock() + defer d.Unlock() + return d.Driver.GetState() +} + +// Kill stops a host forcefully +func (d *SerialDriver) Kill() error { + d.Lock() + defer d.Unlock() + return d.Driver.Kill() +} + +// PreCreateCheck allows for pre-create operations to make sure a driver is ready for creation +func (d *SerialDriver) PreCreateCheck() error { + d.Lock() + defer d.Unlock() + return d.Driver.PreCreateCheck() +} + +// Remove a host +func (d *SerialDriver) Remove() error { + d.Lock() + defer d.Unlock() + return d.Driver.Remove() +} + +// Restart a host. This may just call Stop(); Start() if the provider does not +// have any special restart behaviour. +func (d *SerialDriver) Restart() error { + d.Lock() + defer d.Unlock() + return d.Driver.Restart() +} + +// SetConfigFromFlags configures the driver with the object that was returned +// by RegisterCreateFlags +func (d *SerialDriver) SetConfigFromFlags(opts DriverOptions) error { + d.Lock() + defer d.Unlock() + return d.Driver.SetConfigFromFlags(opts) +} + +// Start a host +func (d *SerialDriver) Start() error { + d.Lock() + defer d.Unlock() + return d.Driver.Start() +} + +// Stop a host gracefully +func (d *SerialDriver) Stop() error { + d.Lock() + defer d.Unlock() + return d.Driver.Stop() +} + +func (d *SerialDriver) MarshalJSON() ([]byte, error) { + return json.Marshal(d.Driver) +} diff --git a/libmachine/drivers/serial_test.go b/libmachine/drivers/serial_test.go new file mode 100644 index 0000000000..d0a06a46be --- /dev/null +++ b/libmachine/drivers/serial_test.go @@ -0,0 +1,296 @@ +package drivers + +import ( + "testing" + + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/state" + "github.com/stretchr/testify/assert" +) + +type CallRecorder struct { + calls []string +} + +func (c *CallRecorder) record(call string) { + c.calls = append(c.calls, call) +} + +type MockLocker struct { + calls *CallRecorder +} + +func (l *MockLocker) Lock() { + l.calls.record("Lock") +} + +func (l *MockLocker) Unlock() { + l.calls.record("Unlock") +} + +type MockDriver struct { + calls *CallRecorder + driverName string + flags []mcnflag.Flag + ip string + machineName string + sshHostname string + sshKeyPath string + sshPort int + sshUsername string + url string + state state.State +} + +func (d *MockDriver) Create() error { + d.calls.record("Create") + return nil +} + +func (d *MockDriver) DriverName() string { + d.calls.record("DriverName") + return d.driverName +} + +func (d *MockDriver) GetCreateFlags() []mcnflag.Flag { + d.calls.record("GetCreateFlags") + return d.flags +} + +func (d *MockDriver) GetIP() (string, error) { + d.calls.record("GetIP") + return d.ip, nil +} + +func (d *MockDriver) GetMachineName() string { + d.calls.record("GetMachineName") + return d.machineName +} + +func (d *MockDriver) GetSSHHostname() (string, error) { + d.calls.record("GetSSHHostname") + return d.sshHostname, nil +} + +func (d *MockDriver) GetSSHKeyPath() string { + d.calls.record("GetSSHKeyPath") + return d.sshKeyPath +} + +func (d *MockDriver) GetSSHPort() (int, error) { + d.calls.record("GetSSHPort") + return d.sshPort, nil +} + +func (d *MockDriver) GetSSHUsername() string { + d.calls.record("GetSSHUsername") + return d.sshUsername +} + +func (d *MockDriver) GetURL() (string, error) { + d.calls.record("GetURL") + return d.url, nil +} + +func (d *MockDriver) GetState() (state.State, error) { + d.calls.record("GetState") + return d.state, nil +} + +func (d *MockDriver) Kill() error { + d.calls.record("Kill") + return nil +} + +func (d *MockDriver) PreCreateCheck() error { + d.calls.record("PreCreateCheck") + return nil +} + +func (d *MockDriver) Remove() error { + d.calls.record("Remove") + return nil +} + +func (d *MockDriver) Restart() error { + d.calls.record("Restart") + return nil +} + +func (d *MockDriver) SetConfigFromFlags(opts DriverOptions) error { + d.calls.record("SetConfigFromFlags") + return nil +} + +func (d *MockDriver) Start() error { + d.calls.record("Start") + return nil +} + +func (d *MockDriver) Stop() error { + d.calls.record("Stop") + return nil +} + +func TestSerialDriverCreate(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + err := driver.Create() + + assert.NoError(t, err) + assert.Equal(t, []string{"Lock", "Create", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverDriverName(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{driverName: "DRIVER", calls: callRecorder}, &MockLocker{calls: callRecorder}) + driverName := driver.DriverName() + + assert.Equal(t, "DRIVER", driverName) + assert.Equal(t, []string{"Lock", "DriverName", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetIP(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{ip: "IP", calls: callRecorder}, &MockLocker{calls: callRecorder}) + ip, _ := driver.GetIP() + + assert.Equal(t, "IP", ip) + assert.Equal(t, []string{"Lock", "GetIP", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetMachineName(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{machineName: "MACHINE_NAME", calls: callRecorder}, &MockLocker{calls: callRecorder}) + machineName := driver.GetMachineName() + + assert.Equal(t, "MACHINE_NAME", machineName) + assert.Equal(t, []string{"Lock", "GetMachineName", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetSSHHostname(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{sshHostname: "SSH_HOSTNAME", calls: callRecorder}, &MockLocker{calls: callRecorder}) + sshHostname, _ := driver.GetSSHHostname() + + assert.Equal(t, "SSH_HOSTNAME", sshHostname) + assert.Equal(t, []string{"Lock", "GetSSHHostname", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetSSHKeyPath(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{sshKeyPath: "PATH", calls: callRecorder}, &MockLocker{calls: callRecorder}) + path := driver.GetSSHKeyPath() + + assert.Equal(t, "PATH", path) + assert.Equal(t, []string{"Lock", "GetSSHKeyPath", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetSSHPort(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{sshPort: 42, calls: callRecorder}, &MockLocker{calls: callRecorder}) + sshPort, _ := driver.GetSSHPort() + + assert.Equal(t, 42, sshPort) + assert.Equal(t, []string{"Lock", "GetSSHPort", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetSSHUsername(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{sshUsername: "SSH_USER", calls: callRecorder}, &MockLocker{calls: callRecorder}) + sshUsername := driver.GetSSHUsername() + + assert.Equal(t, "SSH_USER", sshUsername) + assert.Equal(t, []string{"Lock", "GetSSHUsername", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetURL(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{url: "URL", calls: callRecorder}, &MockLocker{calls: callRecorder}) + url, _ := driver.GetURL() + + assert.Equal(t, "URL", url) + assert.Equal(t, []string{"Lock", "GetURL", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverGetState(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{state: state.Running, calls: callRecorder}, &MockLocker{calls: callRecorder}) + machineState, _ := driver.GetState() + + assert.Equal(t, state.Running, machineState) + assert.Equal(t, []string{"Lock", "GetState", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverKill(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.Kill() + + assert.Equal(t, []string{"Lock", "Kill", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverPreCreateCheck(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.PreCreateCheck() + + assert.Equal(t, []string{"Lock", "PreCreateCheck", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverRemove(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.Remove() + + assert.Equal(t, []string{"Lock", "Remove", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverRestart(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.Restart() + + assert.Equal(t, []string{"Lock", "Restart", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverSetConfigFromFlags(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.SetConfigFromFlags(nil) + + assert.Equal(t, []string{"Lock", "SetConfigFromFlags", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverStart(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.Start() + + assert.Equal(t, []string{"Lock", "Start", "Unlock"}, callRecorder.calls) +} + +func TestSerialDriverStop(t *testing.T) { + callRecorder := &CallRecorder{} + + driver := newSerialDriverWithLock(&MockDriver{calls: callRecorder}, &MockLocker{calls: callRecorder}) + driver.Stop() + + assert.Equal(t, []string{"Lock", "Stop", "Unlock"}, callRecorder.calls) +} diff --git a/libmachine/drivers/utils.go b/libmachine/drivers/utils.go new file mode 100644 index 0000000000..b023f16899 --- /dev/null +++ b/libmachine/drivers/utils.go @@ -0,0 +1,73 @@ +package drivers + +import ( + "fmt" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" +) + +func GetSSHClientFromDriver(d Driver) (ssh.Client, error) { + address, err := d.GetSSHHostname() + if err != nil { + return nil, err + } + + port, err := d.GetSSHPort() + if err != nil { + return nil, err + } + + var auth *ssh.Auth + if d.GetSSHKeyPath() == "" { + auth = &ssh.Auth{} + } else { + auth = &ssh.Auth{ + Keys: []string{d.GetSSHKeyPath()}, + } + } + + client, err := ssh.NewClient(d.GetSSHUsername(), address, port, auth) + return client, err + +} + +func RunSSHCommandFromDriver(d Driver, command string) (string, error) { + client, err := GetSSHClientFromDriver(d) + if err != nil { + return "", err + } + + log.Debugf("About to run SSH command:\n%s", command) + + output, err := client.Output(command) + log.Debugf("SSH cmd err, output: %v: %s", err, output) + if err != nil { + return "", fmt.Errorf(`ssh command error: +command : %s +err : %v +output : %s`, command, err, output) + } + + return output, nil +} + +func sshAvailableFunc(d Driver) func() bool { + return func() bool { + log.Debug("Getting to WaitForSSH function...") + if _, err := RunSSHCommandFromDriver(d, "exit 0"); err != nil { + log.Debugf("Error getting ssh command 'exit 0' : %s", err) + return false + } + return true + } +} + +func WaitForSSH(d Driver) error { + // Try to dial SSH for 30 seconds before timing out. + if err := mcnutils.WaitFor(sshAvailableFunc(d)); err != nil { + return fmt.Errorf("Too many retries waiting for SSH to be available. Last error: %s", err) + } + return nil +} diff --git a/libmachine/engine/engine.go b/libmachine/engine/engine.go new file mode 100644 index 0000000000..2910432c19 --- /dev/null +++ b/libmachine/engine/engine.go @@ -0,0 +1,21 @@ +package engine + +const ( + DefaultPort = 2376 +) + +type Options struct { + ArbitraryFlags []string + DNS []string `json:"Dns"` + GraphDir string + Env []string + Ipv6 bool + InsecureRegistry []string + Labels []string + LogLevel string + StorageDriver string + SelinuxEnabled bool + TLSVerify bool `json:"TlsVerify"` + RegistryMirror []string + InstallURL string +} diff --git a/libmachine/examples/main.go b/libmachine/examples/main.go new file mode 100644 index 0000000000..7decc83cb8 --- /dev/null +++ b/libmachine/examples/main.go @@ -0,0 +1,145 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "os" + + "github.com/docker/machine/drivers/virtualbox" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/log" +) + +func usage() { + fmt.Println("Usage: go run main.go \n" + + "Available examples: create streaming.") + os.Exit(1) +} + +// Sample Virtualbox create independent of Machine CLI. +func create() { + log.SetDebug(true) + + client := libmachine.NewClient("/tmp/automatic", "/tmp/automatic/certs") + defer client.Close() + + hostName := "myfunhost" + + // Set some options on the provider... + driver := virtualbox.NewDriver(hostName, "/tmp/automatic") + driver.CPU = 2 + driver.Memory = 2048 + + data, err := json.Marshal(driver) + if err != nil { + log.Error(err) + return + } + + h, err := client.NewHost("virtualbox", data) + if err != nil { + log.Error(err) + return + } + + h.HostOptions.EngineOptions.StorageDriver = "overlay" + + if err := client.Create(h); err != nil { + log.Error(err) + return + } + + out, err := h.RunSSHCommand("df -h") + if err != nil { + log.Error(err) + return + } + + fmt.Printf("Results of your disk space query:\n%s\n", out) + + fmt.Println("Powering down machine now...") + if err := h.Stop(); err != nil { + log.Error(err) + return + } +} + +// Streaming the output of an SSH session in virtualbox. +func streaming() { + log.SetDebug(true) + + client := libmachine.NewClient("/tmp/automatic", "/tmp/automatic/certs") + defer client.Close() + + hostName := "myfunhost" + + // Set some options on the provider... + driver := virtualbox.NewDriver(hostName, "/tmp/automatic") + data, err := json.Marshal(driver) + if err != nil { + log.Error(err) + return + } + + h, err := client.NewHost("virtualbox", data) + if err != nil { + log.Error(err) + return + } + + if err := client.Create(h); err != nil { + log.Error(err) + return + } + + h.HostOptions.EngineOptions.StorageDriver = "overlay" + + sshClient, err := h.CreateSSHClient() + if err != nil { + log.Error(err) + return + } + + stdout, stderr, err := sshClient.Start("yes | head -n 10000") + if err != nil { + log.Error(err) + return + } + defer func() { + _ = stdout.Close() + _ = stderr.Close() + }() + + scanner := bufio.NewScanner(stdout) + for scanner.Scan() { + fmt.Println(scanner.Text()) + } + if err := scanner.Err(); err != nil { + log.Error(err) + } + if err := sshClient.Wait(); err != nil { + log.Error(err) + } + + fmt.Println("Powering down machine now...") + if err := h.Stop(); err != nil { + log.Error(err) + return + } +} + +func main() { + if len(os.Args) != 2 { + usage() + } + + switch os.Args[1] { + case "create": + create() + case "streaming": + streaming() + default: + usage() + } +} diff --git a/libmachine/host/host.go b/libmachine/host/host.go new file mode 100644 index 0000000000..d36e187eba --- /dev/null +++ b/libmachine/host/host.go @@ -0,0 +1,286 @@ +package host + +import ( + "regexp" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/cert" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcndockerclient" + "github.com/docker/machine/libmachine/mcnerror" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/swarm" + "github.com/docker/machine/libmachine/versioncmp" +) + +var ( + validHostNamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9\-\.]*$`) + stdSSHClientCreator SSHClientCreator = &StandardSSHClientCreator{} +) + +type SSHClientCreator interface { + CreateSSHClient(d drivers.Driver) (ssh.Client, error) +} + +type StandardSSHClientCreator struct { + drivers.Driver +} + +func SetSSHClientCreator(creator SSHClientCreator) { + stdSSHClientCreator = creator +} + +type Host struct { + ConfigVersion int + Driver drivers.Driver + DriverName string + HostOptions *Options + Name string + RawDriver []byte `json:"-"` +} + +type Options struct { + Driver string + Memory int + Disk int + EngineOptions *engine.Options + SwarmOptions *swarm.Options + AuthOptions *auth.Options +} + +type Metadata struct { + ConfigVersion int + DriverName string + HostOptions Options +} + +func ValidateHostName(name string) bool { + return validHostNamePattern.MatchString(name) +} + +func (h *Host) RunSSHCommand(command string) (string, error) { + return drivers.RunSSHCommandFromDriver(h.Driver, command) +} + +func (h *Host) CreateSSHClient() (ssh.Client, error) { + return stdSSHClientCreator.CreateSSHClient(h.Driver) +} + +func (creator *StandardSSHClientCreator) CreateSSHClient(d drivers.Driver) (ssh.Client, error) { + addr, err := d.GetSSHHostname() + if err != nil { + return &ssh.ExternalClient{}, err + } + + port, err := d.GetSSHPort() + if err != nil { + return &ssh.ExternalClient{}, err + } + + auth := &ssh.Auth{} + if d.GetSSHKeyPath() != "" { + auth.Keys = []string{d.GetSSHKeyPath()} + } + + return ssh.NewClient(d.GetSSHUsername(), addr, port, auth) +} + +func (h *Host) runActionForState(action func() error, desiredState state.State) error { + if drivers.MachineInState(h.Driver, desiredState)() { + return mcnerror.ErrHostAlreadyInState{ + Name: h.Name, + State: desiredState, + } + } + + if err := action(); err != nil { + return err + } + + return mcnutils.WaitFor(drivers.MachineInState(h.Driver, desiredState)) +} + +func (h *Host) WaitForDocker() error { + provisioner, err := provision.DetectProvisioner(h.Driver) + if err != nil { + return err + } + + return provision.WaitForDocker(provisioner, engine.DefaultPort) +} + +func (h *Host) Start() error { + log.Infof("Starting %q...", h.Name) + if err := h.runActionForState(h.Driver.Start, state.Running); err != nil { + return err + } + + log.Infof("Machine %q was started.", h.Name) + + return h.WaitForDocker() +} + +func (h *Host) Stop() error { + log.Infof("Stopping %q...", h.Name) + if err := h.runActionForState(h.Driver.Stop, state.Stopped); err != nil { + return err + } + + log.Infof("Machine %q was stopped.", h.Name) + return nil +} + +func (h *Host) Kill() error { + log.Infof("Killing %q...", h.Name) + if err := h.runActionForState(h.Driver.Kill, state.Stopped); err != nil { + return err + } + + log.Infof("Machine %q was killed.", h.Name) + return nil +} + +func (h *Host) Restart() error { + log.Infof("Restarting %q...", h.Name) + if drivers.MachineInState(h.Driver, state.Stopped)() { + if err := h.Start(); err != nil { + return err + } + } else if drivers.MachineInState(h.Driver, state.Running)() { + if err := h.Driver.Restart(); err != nil { + return err + } + if err := mcnutils.WaitFor(drivers.MachineInState(h.Driver, state.Running)); err != nil { + return err + } + } + + return h.WaitForDocker() +} + +func (h *Host) DockerVersion() (string, error) { + url, err := h.Driver.GetURL() + if err != nil { + return "", err + } + + dockerHost := &mcndockerclient.RemoteDocker{ + HostURL: url, + AuthOption: h.AuthOptions(), + } + dockerVersion, err := mcndockerclient.DockerVersion(dockerHost) + if err != nil { + return "", err + } + + return dockerVersion, nil +} + +func (h *Host) Upgrade() error { + machineState, err := h.Driver.GetState() + if err != nil { + return err + } + + if machineState != state.Running { + log.Info("Starting machine so machine can be upgraded...") + if err := h.Start(); err != nil { + return err + } + } + + provisioner, err := provision.DetectProvisioner(h.Driver) + if err != nil { + return err + } + + dockerVersion, err := h.DockerVersion() + if err != nil { + return err + } + + // If we're upgrading from a pre-CE (e.g., 1.13.1) release to a CE + // release (e.g., 17.03.0-ce), we should simply uninstall and + // re-install from scratch, since the official package names will + // change from 'docker-engine' to 'docker-ce'. + if versioncmp.LessThanOrEqualTo(dockerVersion, provision.LastReleaseBeforeCEVersioning) && + // RancherOS and boot2docker, being 'static ISO builds', have + // an upgrade process which simply grabs the latest if it's + // different, and so do not need to jump through this hoop to + // upgrade safely. + provisioner.String() != "rancheros" && + provisioner.String() != "boot2docker" { + + // Name of package 'docker-engine' will fall through in this + // case, so that we execute, e.g., + // + // 'sudo apt-get purge -y docker-engine' + if err := provisioner.Package("docker-engine", pkgaction.Purge); err != nil { + return err + } + + // Then we kick off the normal provisioning process which will + // go off and install Docker (get.docker.com script should work + // fine to install Docker from scratch after removing the old + // packages, and images/containers etc. should be preserved in + // /var/lib/docker) + return h.Provision() + } + + log.Info("Upgrading docker...") + if err := provisioner.Package("docker", pkgaction.Upgrade); err != nil { + return err + } + + log.Info("Restarting docker...") + return provisioner.Service("docker", serviceaction.Restart) +} + +func (h *Host) URL() (string, error) { + return h.Driver.GetURL() +} + +func (h *Host) AuthOptions() *auth.Options { + if h.HostOptions == nil { + return nil + } + return h.HostOptions.AuthOptions +} + +func (h *Host) ConfigureAuth() error { + provisioner, err := provision.DetectProvisioner(h.Driver) + if err != nil { + return err + } + + // TODO: This is kind of a hack (or is it? I'm not really sure until + // we have more clearly defined outlook on what the responsibilities + // and modularity of the provisioners should be). + // + // Call provision to re-provision the certs properly. + return provisioner.Provision(swarm.Options{}, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions) +} + +func (h *Host) ConfigureAllAuth() error { + log.Info("Regenerating local certificates") + if err := cert.BootstrapCertificates(h.AuthOptions()); err != nil { + return err + } + return h.ConfigureAuth() +} + +func (h *Host) Provision() error { + provisioner, err := provision.DetectProvisioner(h.Driver) + if err != nil { + return err + } + + return provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions) +} diff --git a/libmachine/host/host_test.go b/libmachine/host/host_test.go new file mode 100644 index 0000000000..a418506ecf --- /dev/null +++ b/libmachine/host/host_test.go @@ -0,0 +1,57 @@ +package host + +import ( + "testing" + + "github.com/docker/machine/drivers/fakedriver" + _ "github.com/docker/machine/drivers/none" + "github.com/docker/machine/libmachine/provision" + "github.com/docker/machine/libmachine/state" +) + +func TestValidateHostnameValid(t *testing.T) { + hosts := []string{ + "zomg", + "test-ing", + "some.h0st", + } + + for _, v := range hosts { + isValid := ValidateHostName(v) + if !isValid { + t.Fatalf("Thought a valid hostname was invalid: %s", v) + } + } +} + +func TestValidateHostnameInvalid(t *testing.T) { + hosts := []string{ + "zom_g", + "test$ing", + "some😄host", + } + + for _, v := range hosts { + isValid := ValidateHostName(v) + if isValid { + t.Fatalf("Thought an invalid hostname was valid: %s", v) + } + } +} + +func TestStart(t *testing.T) { + defer provision.SetDetector(&provision.StandardDetector{}) + provision.SetDetector(&provision.FakeDetector{ + Provisioner: provision.NewNetstatProvisioner(), + }) + + host := &Host{ + Driver: &fakedriver.Driver{ + MockState: state.Stopped, + }, + } + + if err := host.Start(); err != nil { + t.Fatalf("Expected no error but got one: %s", err) + } +} diff --git a/libmachine/host/host_v0.go b/libmachine/host/host_v0.go new file mode 100644 index 0000000000..a36db5fea0 --- /dev/null +++ b/libmachine/host/host_v0.go @@ -0,0 +1,35 @@ +package host + +import "github.com/docker/machine/libmachine/drivers" + +type V0 struct { + Name string `json:"-"` + Driver drivers.Driver + DriverName string + ConfigVersion int + HostOptions *Options + + StorePath string + CaCertPath string + PrivateKeyPath string + ServerCertPath string + ServerKeyPath string + ClientCertPath string + SwarmHost string + SwarmMaster bool + SwarmDiscovery string + ClientKeyPath string +} + +type MetadataV0 struct { + HostOptions Options + DriverName string + + ConfigVersion int + StorePath string + CaCertPath string + PrivateKeyPath string + ServerCertPath string + ServerKeyPath string + ClientCertPath string +} diff --git a/libmachine/host/host_v2.go b/libmachine/host/host_v2.go new file mode 100644 index 0000000000..8157e5f914 --- /dev/null +++ b/libmachine/host/host_v2.go @@ -0,0 +1,11 @@ +package host + +import "github.com/docker/machine/libmachine/drivers" + +type V2 struct { + ConfigVersion int + Driver drivers.Driver + DriverName string + HostOptions *Options + Name string +} diff --git a/libmachine/host/migrate.go b/libmachine/host/migrate.go new file mode 100644 index 0000000000..7134240de6 --- /dev/null +++ b/libmachine/host/migrate.go @@ -0,0 +1,120 @@ +package host + +import ( + "encoding/json" + "errors" + "fmt" + "path/filepath" + + "github.com/docker/machine/drivers/none" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/version" +) + +var ( + errConfigFromFuture = errors.New("config version is from the future -- you should upgrade your Docker Machine client") +) + +type RawDataDriver struct { + *none.Driver + Data []byte // passed directly back when invoking json.Marshal on this type +} + +func (r *RawDataDriver) MarshalJSON() ([]byte, error) { + return r.Data, nil +} + +func (r *RawDataDriver) UnmarshalJSON(data []byte) error { + r.Data = data + return nil +} + +func getMigratedHostMetadata(data []byte) (*Metadata, error) { + // HostMetadata is for a "first pass" so we can then load the driver + var ( + hostMetadata *MetadataV0 + ) + + if err := json.Unmarshal(data, &hostMetadata); err != nil { + return &Metadata{}, err + } + + migratedHostMetadata := MigrateHostMetadataV0ToHostMetadataV1(hostMetadata) + + return migratedHostMetadata, nil +} + +func MigrateHost(h *Host, data []byte) (*Host, bool, error) { + var ( + migrationNeeded = false + migrationPerformed = false + hostV1 *V1 + hostV2 *V2 + ) + + migratedHostMetadata, err := getMigratedHostMetadata(data) + if err != nil { + return nil, false, err + } + + globalStorePath := filepath.Dir(filepath.Dir(migratedHostMetadata.HostOptions.AuthOptions.StorePath)) + + driver := &RawDataDriver{none.NewDriver(h.Name, globalStorePath), nil} + + if migratedHostMetadata.ConfigVersion > version.ConfigVersion { + return nil, false, errConfigFromFuture + } + + if migratedHostMetadata.ConfigVersion == version.ConfigVersion { + h.Driver = driver + if err := json.Unmarshal(data, &h); err != nil { + return nil, migrationPerformed, fmt.Errorf("Error unmarshalling most recent host version: %s", err) + } + } else { + migrationNeeded = true + } + + if migrationNeeded { + migrationPerformed = true + for h.ConfigVersion = migratedHostMetadata.ConfigVersion; h.ConfigVersion < version.ConfigVersion; h.ConfigVersion++ { + log.Debugf("Migrating to config v%d", h.ConfigVersion) + switch h.ConfigVersion { + case 0: + hostV0 := &V0{ + Driver: driver, + } + if err := json.Unmarshal(data, &hostV0); err != nil { + return nil, migrationPerformed, fmt.Errorf("Error unmarshalling host config version 0: %s", err) + } + hostV1 = MigrateHostV0ToHostV1(hostV0) + case 1: + if hostV1 == nil { + hostV1 = &V1{ + Driver: driver, + } + if err := json.Unmarshal(data, &hostV1); err != nil { + return nil, migrationPerformed, fmt.Errorf("Error unmarshalling host config version 1: %s", err) + } + } + hostV2 = MigrateHostV1ToHostV2(hostV1) + case 2: + if hostV2 == nil { + hostV2 = &V2{ + Driver: driver, + } + if err := json.Unmarshal(data, &hostV2); err != nil { + return nil, migrationPerformed, fmt.Errorf("Error unmarshalling host config version 2: %s", err) + } + } + h = MigrateHostV2ToHostV3(hostV2, data, globalStorePath) + driver.Data = h.RawDriver + h.Driver = driver + case 3: + } + } + } + + h.RawDriver = driver.Data + + return h, migrationPerformed, nil +} diff --git a/libmachine/host/migrate_test.go b/libmachine/host/migrate_test.go new file mode 100644 index 0000000000..7b839bbc59 --- /dev/null +++ b/libmachine/host/migrate_test.go @@ -0,0 +1,180 @@ +package host + +import ( + "testing" + + "github.com/docker/machine/drivers/none" + "github.com/docker/machine/libmachine/auth" + "github.com/stretchr/testify/assert" +) + +func TestMigrateHost(t *testing.T) { + testCases := []struct { + description string + hostBefore *Host + rawData []byte + expectedHostAfter *Host + expectedMigrationPerformed bool + expectedMigrationError error + }{ + { + // Point of this test is largely that no matter what was in RawDriver + // before, it should load into the Host struct based on what is actually + // in the Driver field. + // + // Note that we don't check for the presence of RawDriver's literal "on + // disk" here. It's intentional. + description: "Config version 3 load with existing RawDriver on disk", + hostBefore: &Host{ + Name: "default", + }, + rawData: []byte(`{ + "ConfigVersion": 3, + "Driver": {"MachineName": "default"}, + "DriverName": "virtualbox", + "HostOptions": { + "Driver": "", + "Memory": 0, + "Disk": 0, + "AuthOptions": { + "StorePath": "/Users/nathanleclaire/.docker/machine/machines/default" + } + }, + "Name": "default", + "RawDriver": "eyJWQm94TWFuYWdlciI6e30sIklQQWRkcmVzcyI6IjE5Mi4xNjguOTkuMTAwIiwiTWFjaGluZU5hbWUiOiJkZWZhdWx0IiwiU1NIVXNlciI6ImRvY2tlciIsIlNTSFBvcnQiOjU4MTQ1LCJTU0hLZXlQYXRoIjoiL1VzZXJzL25hdGhhbmxlY2xhaXJlLy5kb2NrZXIvbWFjaGluZS9tYWNoaW5lcy9kZWZhdWx0L2lkX3JzYSIsIlN0b3JlUGF0aCI6Ii9Vc2Vycy9uYXRoYW5sZWNsYWlyZS8uZG9ja2VyL21hY2hpbmUiLCJTd2FybU1hc3RlciI6ZmFsc2UsIlN3YXJtSG9zdCI6InRjcDovLzAuMC4wLjA6MzM3NiIsIlN3YXJtRGlzY292ZXJ5IjoiIiwiQ1BVIjoxLCJNZW1vcnkiOjEwMjQsIkRpc2tTaXplIjoyMDAwMCwiQm9vdDJEb2NrZXJVUkwiOiIiLCJCb290MkRvY2tlckltcG9ydFZNIjoiIiwiSG9zdE9ubHlDSURSIjoiMTkyLjE2OC45OS4xLzI0IiwiSG9zdE9ubHlOaWNUeXBlIjoiODI1NDBFTSIsIkhvc3RPbmx5UHJvbWlzY01vZGUiOiJkZW55IiwiTm9TaGFyZSI6ZmFsc2V9" +}`), + expectedHostAfter: &Host{ + ConfigVersion: 3, + HostOptions: &Options{ + AuthOptions: &auth.Options{ + StorePath: "/Users/nathanleclaire/.docker/machine/machines/default", + }, + }, + Name: "default", + DriverName: "virtualbox", + RawDriver: []byte(`{"MachineName": "default"}`), + Driver: &RawDataDriver{ + Data: []byte(`{"MachineName": "default"}`), + + // TODO (nathanleclaire): The "." argument here is a already existing + // bug (or at least likely to cause them in the future) and most + // likely should be "/Users/nathanleclaire/.docker/machine" + // + // These default StorePath settings get over-written when we + // instantiate the plugin driver, but this seems entirely incidental. + Driver: none.NewDriver("default", "."), + }, + }, + expectedMigrationPerformed: false, + expectedMigrationError: nil, + }, + { + description: "Config version 4 (from the FUTURE) on disk", + hostBefore: &Host{ + Name: "default", + }, + rawData: []byte(`{ + "ConfigVersion": 4, + "Driver": {"MachineName": "default"}, + "DriverName": "virtualbox", + "HostOptions": { + "Driver": "", + "Memory": 0, + "Disk": 0, + "AuthOptions": { + "StorePath": "/Users/nathanleclaire/.docker/machine/machines/default" + } + }, + "Name": "default" +}`), + expectedHostAfter: nil, + expectedMigrationPerformed: false, + expectedMigrationError: errConfigFromFuture, + }, + { + description: "Config version 3 load WITHOUT any existing RawDriver field on disk", + hostBefore: &Host{ + Name: "default", + }, + rawData: []byte(`{ + "ConfigVersion": 3, + "Driver": {"MachineName": "default"}, + "DriverName": "virtualbox", + "HostOptions": { + "Driver": "", + "Memory": 0, + "Disk": 0, + "AuthOptions": { + "StorePath": "/Users/nathanleclaire/.docker/machine/machines/default" + } + }, + "Name": "default" +}`), + expectedHostAfter: &Host{ + ConfigVersion: 3, + HostOptions: &Options{ + AuthOptions: &auth.Options{ + StorePath: "/Users/nathanleclaire/.docker/machine/machines/default", + }, + }, + Name: "default", + DriverName: "virtualbox", + RawDriver: []byte(`{"MachineName": "default"}`), + Driver: &RawDataDriver{ + Data: []byte(`{"MachineName": "default"}`), + + // TODO: See note above. + Driver: none.NewDriver("default", "."), + }, + }, + expectedMigrationPerformed: false, + expectedMigrationError: nil, + }, + { + description: "Config version 2 load and migrate. Ensure StorePath gets set properly.", + hostBefore: &Host{ + Name: "default", + }, + rawData: []byte(`{ + "ConfigVersion": 2, + "Driver": {"MachineName": "default"}, + "DriverName": "virtualbox", + "HostOptions": { + "Driver": "", + "Memory": 0, + "Disk": 0, + "AuthOptions": { + "StorePath": "/Users/nathanleclaire/.docker/machine/machines/default" + } + }, + "StorePath": "/Users/nathanleclaire/.docker/machine/machines/default", + "Name": "default" +}`), + expectedHostAfter: &Host{ + ConfigVersion: 3, + HostOptions: &Options{ + AuthOptions: &auth.Options{ + StorePath: "/Users/nathanleclaire/.docker/machine/machines/default", + }, + }, + Name: "default", + DriverName: "virtualbox", + RawDriver: []byte(`{"MachineName":"default","StorePath":"/Users/nathanleclaire/.docker/machine"}`), + Driver: &RawDataDriver{ + Data: []byte(`{"MachineName":"default","StorePath":"/Users/nathanleclaire/.docker/machine"}`), + Driver: none.NewDriver("default", "/Users/nathanleclaire/.docker/machine"), + }, + }, + expectedMigrationPerformed: true, + expectedMigrationError: nil, + }, + } + + for _, tc := range testCases { + actualHostAfter, actualMigrationPerformed, actualMigrationError := MigrateHost(tc.hostBefore, tc.rawData) + + assert.Equal(t, tc.expectedHostAfter, actualHostAfter) + assert.Equal(t, tc.expectedMigrationPerformed, actualMigrationPerformed) + assert.Equal(t, tc.expectedMigrationError, actualMigrationError) + } +} diff --git a/libmachine/host/migrate_v0_v1.go b/libmachine/host/migrate_v0_v1.go new file mode 100644 index 0000000000..6460d38e65 --- /dev/null +++ b/libmachine/host/migrate_v0_v1.go @@ -0,0 +1,73 @@ +package host + +import ( + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/swarm" +) + +// In the 0.1.0 => 0.2.0 transition, the JSON representation of +// machines changed from a "flat" to a more "nested" structure +// for various options and configuration settings. To preserve +// compatibility with existing machines, these migration functions +// have been introduced. They preserve backwards compat at the expense +// of some duplicated information. + +// MigrateHostV0ToHostV1 validates host config and modifies if needed +// this is used for configuration updates +func MigrateHostV0ToHostV1(hostV0 *V0) *V1 { + hostV1 := &V1{ + Driver: hostV0.Driver, + DriverName: hostV0.DriverName, + } + + hostV1.HostOptions = &OptionsV1{} + hostV1.HostOptions.EngineOptions = &engine.Options{ + TLSVerify: true, + InstallURL: "https://get.docker.com", + } + hostV1.HostOptions.SwarmOptions = &swarm.Options{ + Address: "", + Discovery: hostV0.SwarmDiscovery, + Host: hostV0.SwarmHost, + Master: hostV0.SwarmMaster, + } + hostV1.HostOptions.AuthOptions = &AuthOptionsV1{ + StorePath: hostV0.StorePath, + CaCertPath: hostV0.CaCertPath, + CaCertRemotePath: "", + ServerCertPath: hostV0.ServerCertPath, + ServerKeyPath: hostV0.ServerKeyPath, + ClientKeyPath: hostV0.ClientKeyPath, + ServerCertRemotePath: "", + ServerKeyRemotePath: "", + PrivateKeyPath: hostV0.PrivateKeyPath, + ClientCertPath: hostV0.ClientCertPath, + } + + return hostV1 +} + +// MigrateHostMetadataV0ToHostMetadataV1 fills nested host metadata and modifies if needed +// this is used for configuration updates +func MigrateHostMetadataV0ToHostMetadataV1(m *MetadataV0) *Metadata { + hostMetadata := &Metadata{} + hostMetadata.DriverName = m.DriverName + hostMetadata.HostOptions.EngineOptions = &engine.Options{} + hostMetadata.HostOptions.AuthOptions = &auth.Options{ + StorePath: m.StorePath, + CaCertPath: m.CaCertPath, + CaCertRemotePath: "", + ServerCertPath: m.ServerCertPath, + ServerKeyPath: m.ServerKeyPath, + ClientKeyPath: "", + ServerCertRemotePath: "", + ServerKeyRemotePath: "", + CaPrivateKeyPath: m.PrivateKeyPath, + ClientCertPath: m.ClientCertPath, + } + + hostMetadata.ConfigVersion = m.ConfigVersion + + return hostMetadata +} diff --git a/libmachine/host/migrate_v0_v1_test.go b/libmachine/host/migrate_v0_v1_test.go new file mode 100644 index 0000000000..689c74b63d --- /dev/null +++ b/libmachine/host/migrate_v0_v1_test.go @@ -0,0 +1,89 @@ +package host + +import ( + "reflect" + "testing" + + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/swarm" +) + +func TestMigrateHostV0ToV1(t *testing.T) { + mcndirs.BaseDir = "/tmp/migration" + originalHost := &V0{ + HostOptions: nil, + SwarmDiscovery: "token://foobar", + SwarmHost: "1.2.3.4:2376", + SwarmMaster: true, + CaCertPath: "/tmp/migration/certs/ca.pem", + PrivateKeyPath: "/tmp/migration/certs/ca-key.pem", + ClientCertPath: "/tmp/migration/certs/cert.pem", + ClientKeyPath: "/tmp/migration/certs/key.pem", + ServerCertPath: "/tmp/migration/certs/server.pem", + ServerKeyPath: "/tmp/migration/certs/server-key.pem", + } + hostOptions := &OptionsV1{ + SwarmOptions: &swarm.Options{ + Master: true, + Discovery: "token://foobar", + Host: "1.2.3.4:2376", + }, + AuthOptions: &AuthOptionsV1{ + CaCertPath: "/tmp/migration/certs/ca.pem", + PrivateKeyPath: "/tmp/migration/certs/ca-key.pem", + ClientCertPath: "/tmp/migration/certs/cert.pem", + ClientKeyPath: "/tmp/migration/certs/key.pem", + ServerCertPath: "/tmp/migration/certs/server.pem", + ServerKeyPath: "/tmp/migration/certs/server-key.pem", + }, + EngineOptions: &engine.Options{ + InstallURL: "https://get.docker.com", + TLSVerify: true, + }, + } + + expectedHost := &V1{ + HostOptions: hostOptions, + } + + host := MigrateHostV0ToHostV1(originalHost) + + if !reflect.DeepEqual(host, expectedHost) { + t.Logf("\n%+v\n%+v", host, expectedHost) + t.Logf("\n%+v\n%+v", host.HostOptions, expectedHost.HostOptions) + t.Fatal("Expected these structs to be equal, they were different") + } +} + +func TestMigrateHostMetadataV0ToV1(t *testing.T) { + metadata := &MetadataV0{ + HostOptions: Options{ + EngineOptions: nil, + AuthOptions: nil, + }, + StorePath: "/tmp/store", + CaCertPath: "/tmp/store/certs/ca.pem", + ServerCertPath: "/tmp/store/certs/server.pem", + } + expectedAuthOptions := &auth.Options{ + StorePath: "/tmp/store", + CaCertPath: "/tmp/store/certs/ca.pem", + ServerCertPath: "/tmp/store/certs/server.pem", + } + + expectedMetadata := &Metadata{ + HostOptions: Options{ + EngineOptions: &engine.Options{}, + AuthOptions: expectedAuthOptions, + }, + } + + m := MigrateHostMetadataV0ToHostMetadataV1(metadata) + + if !reflect.DeepEqual(m, expectedMetadata) { + t.Logf("\n%+v\n%+v", m, expectedMetadata) + t.Fatal("Expected these structs to be equal, they were different") + } +} diff --git a/libmachine/host/migrate_v0_v3_test.go b/libmachine/host/migrate_v0_v3_test.go new file mode 100644 index 0000000000..b5aecfd292 --- /dev/null +++ b/libmachine/host/migrate_v0_v3_test.go @@ -0,0 +1,23 @@ +package host + +import "testing" + +var ( + v0conf = []byte(`{"DriverName":"virtualbox","Driver":{"IPAddress":"192.168.99.100","SSHUser":"docker","SSHPort":53507,"MachineName":"dev","CaCertPath":"/Users/ljrittle/.docker/machine/certs/ca.pem","PrivateKeyPath":"/Users/ljrittle/.docker/machine/certs/ca-key.pem","SwarmMaster":false,"SwarmHost":"tcp://0.0.0.0:3376","SwarmDiscovery":"","CPU":-1,"Memory":1024,"DiskSize":20000,"Boot2DockerURL":"","Boot2DockerImportVM":"","HostOnlyCIDR":""},"StorePath":"/Users/ljrittle/.docker/machine/machines/dev","HostOptions":{"Driver":"","Memory":0,"Disk":0,"EngineOptions":{"ArbitraryFlags":null,"Dns":null,"GraphDir":"","Ipv6":false,"InsecureRegistry":null,"Labels":null,"LogLevel":"","StorageDriver":"","SelinuxEnabled":false,"TlsCaCert":"","TlsCert":"","TlsKey":"","TlsVerify":false,"RegistryMirror":null,"InstallURL":""},"SwarmOptions":{"IsSwarm":false,"Address":"","Discovery":"","Master":false,"Host":"tcp://0.0.0.0:3376","Image":"","Strategy":"","Heartbeat":0,"Overcommit":0,"TlsCaCert":"","TlsCert":"","TlsKey":"","TlsVerify":false,"ArbitraryFlags":null},"AuthOptions":{"StorePath":"/Users/ljrittle/.docker/machine/machines/dev","CaCertPath":"/Users/ljrittle/.docker/machine/certs/ca.pem","CaCertRemotePath":"","ServerCertPath":"/Users/ljrittle/.docker/machine/certs/server.pem","ServerKeyPath":"/Users/ljrittle/.docker/machine/certs/server-key.pem","ClientKeyPath":"/Users/ljrittle/.docker/machine/certs/key.pem","ServerCertRemotePath":"","ServerKeyRemotePath":"","PrivateKeyPath":"/Users/ljrittle/.docker/machine/certs/ca-key.pem","ClientCertPath":"/Users/ljrittle/.docker/machine/certs/cert.pem"}}}`) +) + +func TestMigrateHostV0ToHostV3(t *testing.T) { + h := &Host{} + migratedHost, migrationPerformed, err := MigrateHost(h, v0conf) + if err != nil { + t.Fatalf("Error attempting to migrate host: %s", err) + } + + if !migrationPerformed { + t.Fatal("Expected a migration to be reported as performed but it was not") + } + + if migratedHost.DriverName != "virtualbox" { + t.Fatalf("Expected %q, got %q for the driver name", "virtualbox", migratedHost.DriverName) + } +} diff --git a/libmachine/host/migrate_v1_v2.go b/libmachine/host/migrate_v1_v2.go new file mode 100644 index 0000000000..6931993d13 --- /dev/null +++ b/libmachine/host/migrate_v1_v2.go @@ -0,0 +1,78 @@ +package host + +import ( + "path/filepath" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/swarm" +) + +type AuthOptionsV1 struct { + StorePath string + CaCertPath string + CaCertRemotePath string + ServerCertPath string + ServerKeyPath string + ClientKeyPath string + ServerCertRemotePath string + ServerKeyRemotePath string + PrivateKeyPath string + ClientCertPath string +} + +type OptionsV1 struct { + Driver string + Memory int + Disk int + EngineOptions *engine.Options + SwarmOptions *swarm.Options + AuthOptions *AuthOptionsV1 +} + +type V1 struct { + ConfigVersion int + Driver drivers.Driver + DriverName string + HostOptions *OptionsV1 + Name string `json:"-"` + StorePath string +} + +func MigrateHostV1ToHostV2(hostV1 *V1) *V2 { + // Changed: Put StorePath directly in AuthOptions (for provisioning), + // and AuthOptions.PrivateKeyPath => AuthOptions.CaPrivateKeyPath + // Also, CertDir has been added. + + globalStorePath := filepath.Dir(filepath.Dir(hostV1.StorePath)) + + h := &V2{ + ConfigVersion: hostV1.ConfigVersion, + Driver: hostV1.Driver, + Name: hostV1.Driver.GetMachineName(), + DriverName: hostV1.DriverName, + HostOptions: &Options{ + Driver: hostV1.HostOptions.Driver, + Memory: hostV1.HostOptions.Memory, + Disk: hostV1.HostOptions.Disk, + EngineOptions: hostV1.HostOptions.EngineOptions, + SwarmOptions: hostV1.HostOptions.SwarmOptions, + AuthOptions: &auth.Options{ + CertDir: filepath.Join(globalStorePath, "certs"), + CaCertPath: hostV1.HostOptions.AuthOptions.CaCertPath, + CaPrivateKeyPath: hostV1.HostOptions.AuthOptions.PrivateKeyPath, + CaCertRemotePath: hostV1.HostOptions.AuthOptions.CaCertRemotePath, + ServerCertPath: hostV1.HostOptions.AuthOptions.ServerCertPath, + ServerKeyPath: hostV1.HostOptions.AuthOptions.ServerKeyPath, + ClientKeyPath: hostV1.HostOptions.AuthOptions.ClientKeyPath, + ServerCertRemotePath: hostV1.HostOptions.AuthOptions.ServerCertRemotePath, + ServerKeyRemotePath: hostV1.HostOptions.AuthOptions.ServerKeyRemotePath, + ClientCertPath: hostV1.HostOptions.AuthOptions.ClientCertPath, + StorePath: globalStorePath, + }, + }, + } + + return h +} diff --git a/libmachine/host/migrate_v1_v2_test.go b/libmachine/host/migrate_v1_v2_test.go new file mode 100644 index 0000000000..f7f99f4fc4 --- /dev/null +++ b/libmachine/host/migrate_v1_v2_test.go @@ -0,0 +1,108 @@ +package host + +import ( + "path/filepath" + "testing" +) + +var ( + v1conf = []byte(`{ + "ConfigVersion": 1, + "Driver": { + "IPAddress": "192.168.99.100", + "SSHUser": "docker", + "SSHPort": 64477, + "MachineName": "foobar", + "CaCertPath": "/Users/catbug/.docker/machine/certs/ca.pem", + "PrivateKeyPath": "/Users/catbug/.docker/machine/certs/ca-key.pem", + "SwarmMaster": false, + "SwarmHost": "tcp://0.0.0.0:3376", + "SwarmDiscovery": "", + "CPU": 1, + "Memory": 1024, + "DiskSize": 20000, + "Boot2DockerURL": "", + "Boot2DockerImportVM": "", + "HostOnlyCIDR": "192.168.99.1/24" + }, + "DriverName": "virtualbox", + "HostOptions": { + "Driver": "", + "Memory": 0, + "Disk": 0, + "EngineOptions": { + "ArbitraryFlags": [], + "Dns": null, + "GraphDir": "", + "Env": [], + "Ipv6": false, + "InsecureRegistry": [], + "Labels": [], + "LogLevel": "", + "StorageDriver": "", + "SelinuxEnabled": false, + "TlsCaCert": "", + "TlsCert": "", + "TlsKey": "", + "TlsVerify": true, + "RegistryMirror": [], + "InstallURL": "https://get.docker.com" + }, + "SwarmOptions": { + "IsSwarm": false, + "Address": "", + "Discovery": "", + "Master": false, + "Host": "tcp://0.0.0.0:3376", + "Image": "swarm:latest", + "Strategy": "spread", + "Heartbeat": 0, + "Overcommit": 0, + "TlsCaCert": "", + "TlsCert": "", + "TlsKey": "", + "TlsVerify": false, + "ArbitraryFlags": [] + }, + "AuthOptions": { + "StorePath": "", + "CaCertPath": "/Users/catbug/.docker/machine/certs/ca.pem", + "CaCertRemotePath": "", + "ServerCertPath": "/Users/catbug/.docker/machine/machines/foobar/server.pem", + "ServerKeyPath": "/Users/catbug/.docker/machine/machines/foobar/server-key.pem", + "ClientKeyPath": "/Users/catbug/.docker/machine/certs/key.pem", + "ServerCertRemotePath": "", + "ServerKeyRemotePath": "", + "PrivateKeyPath": "/Users/catbug/.docker/machine/certs/ca-key.pem", + "ClientCertPath": "/Users/catbug/.docker/machine/certs/cert.pem" + } + }, + "StorePath": "/Users/catbug/.docker/machine/machines/foobar" +}`) +) + +func TestMigrateHostV1ToHostV2(t *testing.T) { + h := &Host{} + expectedGlobalStorePath := "/Users/catbug/.docker/machine" + expectedCaPrivateKeyPath := "/Users/catbug/.docker/machine/certs/ca-key.pem" + migratedHost, migrationPerformed, err := MigrateHost(h, v1conf) + if err != nil { + t.Fatalf("Error attempting to migrate host: %s", err) + } + + if !migrationPerformed { + t.Fatal("Expected a migration to be reported as performed but it was not") + } + + if migratedHost.HostOptions.AuthOptions.StorePath != expectedGlobalStorePath { + t.Fatalf("Expected %q, got %q for the store path in AuthOptions", migratedHost.HostOptions.AuthOptions.StorePath, expectedGlobalStorePath) + } + + if migratedHost.HostOptions.AuthOptions.CaPrivateKeyPath != expectedCaPrivateKeyPath { + t.Fatalf("Expected %q, got %q for the private key path in AuthOptions", migratedHost.HostOptions.AuthOptions.CaPrivateKeyPath, expectedCaPrivateKeyPath) + } + + if migratedHost.HostOptions.AuthOptions.CertDir != filepath.Join(expectedGlobalStorePath, "certs") { + t.Fatalf("Expected %q, got %q for the cert dir in AuthOptions", migratedHost.HostOptions.AuthOptions.CaPrivateKeyPath, expectedGlobalStorePath) + } +} diff --git a/libmachine/host/migrate_v2_v3.go b/libmachine/host/migrate_v2_v3.go new file mode 100644 index 0000000000..12bcbe5f06 --- /dev/null +++ b/libmachine/host/migrate_v2_v3.go @@ -0,0 +1,49 @@ +package host + +import ( + "bytes" + "encoding/json" + + "github.com/docker/machine/libmachine/log" +) + +type RawHost struct { + Driver *json.RawMessage +} + +func MigrateHostV2ToHostV3(hostV2 *V2, data []byte, storePath string) *Host { + // Migrate to include RawDriver so that driver plugin will work + // smoothly. + rawHost := &RawHost{} + if err := json.Unmarshal(data, &rawHost); err != nil { + log.Warnf("Could not unmarshal raw host for RawDriver information: %s", err) + } + + m := make(map[string]interface{}) + + // Must migrate to include store path in driver since it was not + // previously stored in drivers directly + d := json.NewDecoder(bytes.NewReader(*rawHost.Driver)) + d.UseNumber() + if err := d.Decode(&m); err != nil { + log.Warnf("Could not unmarshal raw host into map[string]interface{}: %s", err) + } + + m["StorePath"] = storePath + + // Now back to []byte + rawDriver, err := json.Marshal(m) + if err != nil { + log.Warnf("Could not re-marshal raw driver: %s", err) + } + + h := &Host{ + ConfigVersion: 2, + DriverName: hostV2.DriverName, + Name: hostV2.Name, + HostOptions: hostV2.HostOptions, + RawDriver: rawDriver, + } + + return h +} diff --git a/libmachine/hosttest/default_test_host.go b/libmachine/hosttest/default_test_host.go new file mode 100644 index 0000000000..143a1201cf --- /dev/null +++ b/libmachine/hosttest/default_test_host.go @@ -0,0 +1,78 @@ +package hosttest + +import ( + "github.com/docker/machine/drivers/none" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/swarm" + "github.com/docker/machine/libmachine/version" +) + +const ( + DefaultHostName = "test-host" + HostTestCaCert = "test-cert" + HostTestPrivateKey = "test-key" +) + +type DriverOptionsMock struct { + Data map[string]interface{} +} + +func (d DriverOptionsMock) String(key string) string { + return d.Data[key].(string) +} + +func (d DriverOptionsMock) StringSlice(key string) []string { + return d.Data[key].([]string) +} + +func (d DriverOptionsMock) Int(key string) int { + return d.Data[key].(int) +} + +func (d DriverOptionsMock) Bool(key string) bool { + return d.Data[key].(bool) +} + +func GetTestDriverFlags() *DriverOptionsMock { + flags := &DriverOptionsMock{ + Data: map[string]interface{}{ + "name": DefaultHostName, + "url": "unix:///var/run/docker.sock", + "swarm": false, + "swarm-host": "", + "swarm-master": false, + "swarm-discovery": "", + }, + } + return flags +} + +func GetDefaultTestHost() (*host.Host, error) { + hostOptions := &host.Options{ + EngineOptions: &engine.Options{}, + SwarmOptions: &swarm.Options{}, + AuthOptions: &auth.Options{ + CaCertPath: HostTestCaCert, + CaPrivateKeyPath: HostTestPrivateKey, + }, + } + + driver := none.NewDriver(DefaultHostName, "/tmp/artifacts") + + host := &host.Host{ + ConfigVersion: version.ConfigVersion, + Name: DefaultHostName, + Driver: driver, + DriverName: "none", + HostOptions: hostOptions, + } + + flags := GetTestDriverFlags() + if err := host.Driver.SetConfigFromFlags(flags); err != nil { + return nil, err + } + + return host, nil +} diff --git a/libmachine/libmachine.go b/libmachine/libmachine.go new file mode 100644 index 0000000000..5d0c8fbc86 --- /dev/null +++ b/libmachine/libmachine.go @@ -0,0 +1,188 @@ +package libmachine + +import ( + "fmt" + "path/filepath" + + "io" + + "github.com/docker/machine/drivers/errdriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/cert" + "github.com/docker/machine/libmachine/check" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/drivers/plugin/localbinary" + "github.com/docker/machine/libmachine/drivers/rpc" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnerror" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/persist" + "github.com/docker/machine/libmachine/provision" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/swarm" + "github.com/docker/machine/libmachine/version" +) + +type API interface { + io.Closer + NewHost(driverName string, rawDriver []byte) (*host.Host, error) + Create(h *host.Host) error + persist.Store + GetMachinesDir() string +} + +type Client struct { + certsDir string + IsDebug bool + SSHClientType ssh.ClientType + GithubAPIToken string + *persist.Filestore + clientDriverFactory rpcdriver.RPCClientDriverFactory +} + +func NewClient(storePath, certsDir string) *Client { + return &Client{ + certsDir: certsDir, + IsDebug: false, + SSHClientType: ssh.External, + Filestore: persist.NewFilestore(storePath, certsDir, certsDir), + clientDriverFactory: rpcdriver.NewRPCClientDriverFactory(), + } +} + +func (api *Client) NewHost(driverName string, rawDriver []byte) (*host.Host, error) { + driver, err := api.clientDriverFactory.NewRPCClientDriver(driverName, rawDriver) + if err != nil { + return nil, err + } + + return &host.Host{ + ConfigVersion: version.ConfigVersion, + Name: driver.GetMachineName(), + Driver: driver, + DriverName: driver.DriverName(), + HostOptions: &host.Options{ + AuthOptions: &auth.Options{ + CertDir: api.certsDir, + CaCertPath: filepath.Join(api.certsDir, "ca.pem"), + CaPrivateKeyPath: filepath.Join(api.certsDir, "ca-key.pem"), + ClientCertPath: filepath.Join(api.certsDir, "cert.pem"), + ClientKeyPath: filepath.Join(api.certsDir, "key.pem"), + ServerCertPath: filepath.Join(api.GetMachinesDir(), "server.pem"), + ServerKeyPath: filepath.Join(api.GetMachinesDir(), "server-key.pem"), + }, + EngineOptions: &engine.Options{ + InstallURL: drivers.DefaultEngineInstallURL, + StorageDriver: "overlay2", + TLSVerify: true, + }, + SwarmOptions: &swarm.Options{ + Host: "tcp://0.0.0.0:3376", + Image: "swarm:latest", + Strategy: "spread", + }, + }, + }, nil +} + +func (api *Client) Load(name string) (*host.Host, error) { + h, err := api.Filestore.Load(name) + if err != nil { + return nil, err + } + + d, err := api.clientDriverFactory.NewRPCClientDriver(h.DriverName, h.RawDriver) + if err != nil { + // Not being able to find a driver binary is a "known error" + if _, ok := err.(localbinary.ErrPluginBinaryNotFound); ok { + h.Driver = errdriver.NewDriver(h.DriverName) + return h, nil + } + return nil, err + } + + if h.DriverName == "virtualbox" { + h.Driver = drivers.NewSerialDriver(d) + } else { + h.Driver = d + } + + return h, nil +} + +// Create is the wrapper method which covers all of the boilerplate around +// actually creating, provisioning, and persisting an instance in the store. +func (api *Client) Create(h *host.Host) error { + if err := cert.BootstrapCertificates(h.AuthOptions()); err != nil { + return fmt.Errorf("Error generating certificates: %s", err) + } + + log.Info("Running pre-create checks...") + + if err := h.Driver.PreCreateCheck(); err != nil { + return mcnerror.ErrDuringPreCreate{ + Cause: err, + } + } + + if err := api.Save(h); err != nil { + return fmt.Errorf("Error saving host to store before attempting creation: %s", err) + } + + log.Info("Creating machine...") + + if err := api.performCreate(h); err != nil { + return fmt.Errorf("Error creating machine: %s", err) + } + + log.Debug("Reticulating splines...") + + return nil +} + +func (api *Client) performCreate(h *host.Host) error { + if err := h.Driver.Create(); err != nil { + return fmt.Errorf("Error in driver during machine creation: %s", err) + } + + if err := api.Save(h); err != nil { + return fmt.Errorf("Error saving host to store after attempting creation: %s", err) + } + + // TODO: Not really a fan of just checking "none" or "ci-test" here. + if h.Driver.DriverName() == "none" || h.Driver.DriverName() == "ci-test" { + return nil + } + + log.Info("Waiting for machine to be running, this may take a few minutes...") + if err := mcnutils.WaitFor(drivers.MachineInState(h.Driver, state.Running)); err != nil { + return fmt.Errorf("Error waiting for machine to be running: %s", err) + } + + log.Info("Detecting operating system of created instance...") + provisioner, err := provision.DetectProvisioner(h.Driver) + if err != nil { + return fmt.Errorf("Error detecting OS: %s", err) + } + + log.Infof("Provisioning with %s...", provisioner.String()) + if err := provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil { + return fmt.Errorf("Error running provisioning: %s", err) + } + + // We should check the connection to docker here + log.Info("Checking connection to Docker...") + if _, _, err = check.DefaultConnChecker.Check(h, false); err != nil { + return fmt.Errorf("Error checking the host: %s", err) + } + + log.Info("Docker is up and running!") + return nil +} + +func (api *Client) Close() error { + return api.clientDriverFactory.Close() +} diff --git a/libmachine/libmachinetest/fake_api.go b/libmachine/libmachinetest/fake_api.go new file mode 100644 index 0000000000..4566257aeb --- /dev/null +++ b/libmachine/libmachinetest/fake_api.go @@ -0,0 +1,88 @@ +package libmachinetest + +import ( + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/mcnerror" + "github.com/docker/machine/libmachine/state" +) + +type FakeAPI struct { + Hosts []*host.Host +} + +func (api *FakeAPI) NewPluginDriver(string, []byte) (drivers.Driver, error) { + return nil, nil +} + +func (api *FakeAPI) Close() error { + return nil +} + +func (api *FakeAPI) NewHost(driverName string, rawDriver []byte) (*host.Host, error) { + return nil, nil +} + +func (api *FakeAPI) Create(h *host.Host) error { + return nil +} + +func (api *FakeAPI) Exists(name string) (bool, error) { + for _, host := range api.Hosts { + if name == host.Name { + return true, nil + } + } + + return false, nil +} + +func (api *FakeAPI) List() ([]string, error) { + return []string{}, nil +} + +func (api *FakeAPI) Load(name string) (*host.Host, error) { + for _, host := range api.Hosts { + if name == host.Name { + return host, nil + } + } + + return nil, mcnerror.ErrHostDoesNotExist{ + Name: name, + } +} + +func (api *FakeAPI) Remove(name string) error { + newHosts := []*host.Host{} + + for _, host := range api.Hosts { + if name != host.Name { + newHosts = append(newHosts, host) + } + } + + api.Hosts = newHosts + + return nil +} + +func (api *FakeAPI) Save(host *host.Host) error { + return nil +} + +func (api FakeAPI) GetMachinesDir() string { + return "" +} + +func State(api libmachine.API, name string) state.State { + host, _ := api.Load(name) + machineState, _ := host.Driver.GetState() + return machineState +} + +func Exists(api libmachine.API, name string) bool { + exists, _ := api.Exists(name) + return exists +} diff --git a/libmachine/log/fmt_machine_logger.go b/libmachine/log/fmt_machine_logger.go new file mode 100644 index 0000000000..285e69949f --- /dev/null +++ b/libmachine/log/fmt_machine_logger.go @@ -0,0 +1,84 @@ +package log + +import ( + "fmt" + "io" + "os" +) + +type FmtMachineLogger struct { + outWriter io.Writer + errWriter io.Writer + debug bool + history *HistoryRecorder +} + +// NewFmtMachineLogger creates a MachineLogger implementation used by the drivers +func NewFmtMachineLogger() MachineLogger { + return &FmtMachineLogger{ + outWriter: os.Stdout, + errWriter: os.Stderr, + debug: false, + history: NewHistoryRecorder(), + } +} + +func (ml *FmtMachineLogger) SetDebug(debug bool) { + ml.debug = debug +} + +func (ml *FmtMachineLogger) SetOutWriter(out io.Writer) { + ml.outWriter = out +} + +func (ml *FmtMachineLogger) SetErrWriter(err io.Writer) { + ml.errWriter = err +} + +func (ml *FmtMachineLogger) Debug(args ...interface{}) { + ml.history.Record(args...) + if ml.debug { + fmt.Fprintln(ml.errWriter, args...) + } +} + +func (ml *FmtMachineLogger) Debugf(fmtString string, args ...interface{}) { + ml.history.Recordf(fmtString, args...) + if ml.debug { + fmt.Fprintf(ml.errWriter, fmtString+"\n", args...) + } +} + +func (ml *FmtMachineLogger) Error(args ...interface{}) { + ml.history.Record(args...) + fmt.Fprintln(ml.errWriter, args...) +} + +func (ml *FmtMachineLogger) Errorf(fmtString string, args ...interface{}) { + ml.history.Recordf(fmtString, args...) + fmt.Fprintf(ml.errWriter, fmtString+"\n", args...) +} + +func (ml *FmtMachineLogger) Info(args ...interface{}) { + ml.history.Record(args...) + fmt.Fprintln(ml.outWriter, args...) +} + +func (ml *FmtMachineLogger) Infof(fmtString string, args ...interface{}) { + ml.history.Recordf(fmtString, args...) + fmt.Fprintf(ml.outWriter, fmtString+"\n", args...) +} + +func (ml *FmtMachineLogger) Warn(args ...interface{}) { + ml.history.Record(args...) + fmt.Fprintln(ml.outWriter, args...) +} + +func (ml *FmtMachineLogger) Warnf(fmtString string, args ...interface{}) { + ml.history.Recordf(fmtString, args...) + fmt.Fprintf(ml.outWriter, fmtString+"\n", args...) +} + +func (ml *FmtMachineLogger) History() []string { + return ml.history.records +} diff --git a/libmachine/log/fmt_machine_logger_test.go b/libmachine/log/fmt_machine_logger_test.go new file mode 100644 index 0000000000..daa0d5aa70 --- /dev/null +++ b/libmachine/log/fmt_machine_logger_test.go @@ -0,0 +1,97 @@ +package log + +import ( + "bufio" + "io" + "io/ioutil" + "testing" + + "github.com/stretchr/testify/assert" +) + +func captureOutput(testLogger MachineLogger, lambda func()) string { + pipeReader, pipeWriter := io.Pipe() + scanner := bufio.NewScanner(pipeReader) + testLogger.SetOutWriter(pipeWriter) + go lambda() + scanner.Scan() + return scanner.Text() +} + +func captureError(testLogger MachineLogger, lambda func()) string { + pipeReader, pipeWriter := io.Pipe() + scanner := bufio.NewScanner(pipeReader) + testLogger.SetErrWriter(pipeWriter) + go lambda() + scanner.Scan() + return scanner.Text() +} + +func TestSetDebugToTrue(t *testing.T) { + testLogger := NewFmtMachineLogger().(*FmtMachineLogger) + testLogger.SetDebug(true) + assert.Equal(t, true, testLogger.debug) +} + +func TestSetDebugToFalse(t *testing.T) { + testLogger := NewFmtMachineLogger().(*FmtMachineLogger) + testLogger.SetDebug(true) + testLogger.SetDebug(false) + assert.Equal(t, false, testLogger.debug) +} + +func TestSetOut(t *testing.T) { + testLogger := NewFmtMachineLogger().(*FmtMachineLogger) + testLogger.SetOutWriter(ioutil.Discard) + assert.Equal(t, ioutil.Discard, testLogger.outWriter) +} + +func TestSetErr(t *testing.T) { + testLogger := NewFmtMachineLogger().(*FmtMachineLogger) + testLogger.SetErrWriter(ioutil.Discard) + assert.Equal(t, ioutil.Discard, testLogger.errWriter) +} + +func TestDebug(t *testing.T) { + testLogger := NewFmtMachineLogger() + testLogger.SetDebug(true) + + result := captureError(testLogger, func() { testLogger.Debug("debug") }) + + assert.Equal(t, result, "debug") +} + +func TestInfo(t *testing.T) { + testLogger := NewFmtMachineLogger() + + result := captureOutput(testLogger, func() { testLogger.Info("info") }) + + assert.Equal(t, result, "info") +} + +func TestWarn(t *testing.T) { + testLogger := NewFmtMachineLogger() + + result := captureOutput(testLogger, func() { testLogger.Warn("warn") }) + + assert.Equal(t, result, "warn") +} + +func TestError(t *testing.T) { + testLogger := NewFmtMachineLogger() + + result := captureError(testLogger, func() { testLogger.Error("error") }) + + assert.Equal(t, result, "error") +} + +func TestEntriesAreCollected(t *testing.T) { + testLogger := NewFmtMachineLogger() + testLogger.Debug("debug") + testLogger.Info("info") + testLogger.Error("error") + assert.Equal(t, 3, len(testLogger.History())) + assert.Equal(t, "debug", testLogger.History()[0]) + assert.Equal(t, "info", testLogger.History()[1]) + assert.Equal(t, "error", testLogger.History()[2]) +} diff --git a/libmachine/log/history_recorder.go b/libmachine/log/history_recorder.go new file mode 100644 index 0000000000..defdbad691 --- /dev/null +++ b/libmachine/log/history_recorder.go @@ -0,0 +1,34 @@ +package log + +import ( + "fmt" + "sync" +) + +type HistoryRecorder struct { + lock *sync.Mutex + records []string +} + +func NewHistoryRecorder() *HistoryRecorder { + return &HistoryRecorder{ + lock: &sync.Mutex{}, + records: []string{}, + } +} + +func (ml *HistoryRecorder) History() []string { + return ml.records +} + +func (ml *HistoryRecorder) Record(args ...interface{}) { + ml.lock.Lock() + defer ml.lock.Unlock() + ml.records = append(ml.records, fmt.Sprint(args...)) +} + +func (ml *HistoryRecorder) Recordf(fmtString string, args ...interface{}) { + ml.lock.Lock() + defer ml.lock.Unlock() + ml.records = append(ml.records, fmt.Sprintf(fmtString, args...)) +} diff --git a/libmachine/log/history_recorder_test.go b/libmachine/log/history_recorder_test.go new file mode 100644 index 0000000000..5e30520a66 --- /dev/null +++ b/libmachine/log/history_recorder_test.go @@ -0,0 +1,21 @@ +package log + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRecording(t *testing.T) { + recorder := NewHistoryRecorder() + recorder.Record("foo") + recorder.Record("bar") + recorder.Record("qix") + assert.Equal(t, recorder.History(), []string{"foo", "bar", "qix"}) +} + +func TestFormattedRecording(t *testing.T) { + recorder := NewHistoryRecorder() + recorder.Recordf("%s, %s and %s", "foo", "bar", "qix") + assert.Equal(t, recorder.History()[0], "foo, bar and qix") +} diff --git a/libmachine/log/log.go b/libmachine/log/log.go new file mode 100644 index 0000000000..5a5823bc87 --- /dev/null +++ b/libmachine/log/log.go @@ -0,0 +1,74 @@ +package log + +import ( + "io" + "regexp" +) + +const redactedText = "" + +var ( + logger = NewFmtMachineLogger() + + // (?s) enables '.' to match '\n' -- see https://golang.org/pkg/regexp/syntax/ + certRegex = regexp.MustCompile("(?s)-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----") + keyRegex = regexp.MustCompile("(?s)-----BEGIN RSA PRIVATE KEY-----.*-----END RSA PRIVATE KEY-----") +) + +func stripSecrets(original []string) []string { + stripped := []string{} + for _, line := range original { + line = certRegex.ReplaceAllString(line, redactedText) + line = keyRegex.ReplaceAllString(line, redactedText) + stripped = append(stripped, line) + } + return stripped +} + +func Debug(args ...interface{}) { + logger.Debug(args...) +} + +func Debugf(fmtString string, args ...interface{}) { + logger.Debugf(fmtString, args...) +} + +func Error(args ...interface{}) { + logger.Error(args...) +} + +func Errorf(fmtString string, args ...interface{}) { + logger.Errorf(fmtString, args...) +} + +func Info(args ...interface{}) { + logger.Info(args...) +} + +func Infof(fmtString string, args ...interface{}) { + logger.Infof(fmtString, args...) +} + +func Warn(args ...interface{}) { + logger.Warn(args...) +} + +func Warnf(fmtString string, args ...interface{}) { + logger.Warnf(fmtString, args...) +} + +func SetDebug(debug bool) { + logger.SetDebug(debug) +} + +func SetOutWriter(out io.Writer) { + logger.SetOutWriter(out) +} + +func SetErrWriter(err io.Writer) { + logger.SetErrWriter(err) +} + +func History() []string { + return stripSecrets(logger.History()) +} diff --git a/libmachine/log/log_test.go b/libmachine/log/log_test.go new file mode 100644 index 0000000000..2343ab98ff --- /dev/null +++ b/libmachine/log/log_test.go @@ -0,0 +1,91 @@ +package log + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStripSecrets(t *testing.T) { + testCases := []struct { + description string + input []string + expected []string + }{ + { + description: "Log that does contain certs should have them stripped", + input: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIRAMMHbb4WFRVYsCOIrfM3dqkwDQYJKoZIhvcNAQELBQAw +GTEXMBUGA1UEChMObmF0aGFubGVjbGFpcmUwHhcNMTUxMDEwMDE1MDAwWhcNMTgw +OTI0MDE1MDAwWjAZMRcwFQYDVQQKEw5uYXRoYW5sZWNsYWlyZTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANLMyaAZPThE6lXtXYfUMZeF0pEfO4BQ7Rv8 +Q9/aIKwm8SlKNm+g+6+RoexsiaPXmAkqk04kg+f9WRgtUKC3nhaiUwTqx2HtxowY +Kp7VVW9QyzwCP1r04WTNTdICzhwM5GfaCMKLmibVUfh9GqIYg4Z6eFly7t0PaN1P +uaLClow1e4sWgAgkpIx7ko9ZtW+73knAnp9PPoH4KPBLS+sIPNGh62WsDlvQrOnq +KDiBPIAAMxu2UefIPeGe6xxFuCG89RoJYYsB627IaR8R8iGJMwjJsiAiObGu6z8M +lcWxT4dC+cEIDRu+XQmavJlAydBeHY6/gtJXzsyRExHTyDwi8xkCAwEAAaMjMCEw +DgYDVR0PAQH/BAQDAgKsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAA5CBXPgjvxfY5bR+f6YfcDcKBWxOQ5zN+OH6jWpVzJMEUWp/ZvTQ1GcV1CT +J4HDMRUOL6lQigZDKR6OJ0g/pD4cDGEQlCuPDXx0O8eenxj9TQ+X+qdtxQNkgjId +QWj3k3JDHCh4BQ7h1ZJIg4SnGCUsrQQ+M8TS4Z0YZ/bZ6ZTktJgQgWMn9Uum1GN9 +hXJ/fa/E9OJuRxTXou7J0WwrV9aX9sEM9syOANR88PcA1fSE7+wNSdj5ZCfY6mQn +II9e8NZEf5ktPXCNi0LKI6R1berejwQI3KKHEFbdZ8SKn93HgDh/Ip/dFctj+zBt +CAlTWS3abehlCERn6Ze9IfZBtpI= +-----END CERTIFICATE-----' | sudo tee /etc/docker/ca.pem`, + }, + expected: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '' | sudo tee /etc/docker/ca.pem`, + }, + }, + { + description: "Log that does contain private keys should have them stripped", + input: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '-----BEGIN RSA PRIVATE KEY----- +MIIC4DCCAcigAwIBAgIRAMMHbb4WFRVYsCOIrfM3dqkwDQYJKoZIhvcNAQELBQAw +GTEXMBUGA1UEChMObmF0aGFubGVjbGFpcmUwHhcNMTUxMDEwMDE1MDAwWhcNMTgw +OTI0MDE1MDAwWjAZMRcwFQYDVQQKEw5uYXRoYW5sZWNsYWlyZTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANLMyaAZPThE6lXtXYfUMZeF0pEfO4BQ7Rv8 +Q9/aIKwm8SlKNm+g+6+RoexsiaPXmAkqk04kg+f9WRgtUKC3nhaiUwTqx2HtxowY +Kp7VVW9QyzwCP1r04WTNTdICzhwM5GfaCMKLmibVUfh9GqIYg4Z6eFly7t0PaN1P +uaLClow1e4sWgAgkpIx7ko9ZtW+73knAnp9PPoH4KPBLS+sIPNGh62WsDlvQrOnq +KDiBPIAAMxu2UefIPeGe6xxFuCG89RoJYYsB627IaR8R8iGJMwjJsiAiObGu6z8M +lcWxT4dC+cEIDRu+XQmavJlAydBeHY6/gtJXzsyRExHTyDwi8xkCAwEAAaMjMCEw +DgYDVR0PAQH/BAQDAgKsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAA5CBXPgjvxfY5bR+f6YfcDcKBWxOQ5zN+OH6jWpVzJMEUWp/ZvTQ1GcV1CT +J4HDMRUOL6lQigZDKR6OJ0g/pD4cDGEQlCuPDXx0O8eenxj9TQ+X+qdtxQNkgjId +QWj3k3JDHCh4BQ7h1ZJIg4SnGCUsrQQ+M8TS4Z0YZ/bZ6ZTktJgQgWMn9Uum1GN9 +hXJ/fa/E9OJuRxTXou7J0WwrV9aX9sEM9syOANR88PcA1fSE7+wNSdj5ZCfY6mQn +II9e8NZEf5ktPXCNi0LKI6R1berejwQI3KKHEFbdZ8SKn93HgDh/Ip/dFctj+zBt +CAlTWS3abehlCERn6Ze9IfZBtpI= +-----END RSA PRIVATE KEY-----' | sudo tee /etc/docker/server-key.pem`, + }, + expected: []string{ + "Some mundane log lines", + "IP is foo.bar", + `Secret here: printf '%s' '' | sudo tee /etc/docker/server-key.pem`, + }, + }, + { + description: "Log that does not contain secrets should not change", + input: []string{ + "Some mundane log lines", + "IP is foo.bar", + }, + expected: []string{ + "Some mundane log lines", + "IP is foo.bar", + }, + }, + } + + for _, tc := range testCases { + assert.Equal(t, tc.expected, stripSecrets(tc.input)) + } +} diff --git a/libmachine/log/machine_logger.go b/libmachine/log/machine_logger.go new file mode 100644 index 0000000000..19f613e230 --- /dev/null +++ b/libmachine/log/machine_logger.go @@ -0,0 +1,24 @@ +package log + +import "io" + +type MachineLogger interface { + SetDebug(debug bool) + + SetOutWriter(io.Writer) + SetErrWriter(io.Writer) + + Debug(args ...interface{}) + Debugf(fmtString string, args ...interface{}) + + Error(args ...interface{}) + Errorf(fmtString string, args ...interface{}) + + Info(args ...interface{}) + Infof(fmtString string, args ...interface{}) + + Warn(args ...interface{}) + Warnf(fmtString string, args ...interface{}) + + History() []string +} diff --git a/libmachine/mcndockerclient/docker_client.go b/libmachine/mcndockerclient/docker_client.go new file mode 100644 index 0000000000..828dc7614e --- /dev/null +++ b/libmachine/mcndockerclient/docker_client.go @@ -0,0 +1,47 @@ +package mcndockerclient + +import ( + "fmt" + + "github.com/docker/machine/libmachine/cert" + "github.com/samalba/dockerclient" +) + +// DockerClient creates a docker client for a given host. +func DockerClient(dockerHost DockerHost) (*dockerclient.DockerClient, error) { + url, err := dockerHost.URL() + if err != nil { + return nil, err + } + + tlsConfig, err := cert.ReadTLSConfig(url, dockerHost.AuthOptions()) + if err != nil { + return nil, fmt.Errorf("Unable to read TLS config: %s", err) + } + + return dockerclient.NewDockerClient(url, tlsConfig) +} + +// CreateContainer creates a docker container. +func CreateContainer(dockerHost DockerHost, config *dockerclient.ContainerConfig, name string) error { + docker, err := DockerClient(dockerHost) + if err != nil { + return err + } + + if err = docker.PullImage(config.Image, nil); err != nil { + return fmt.Errorf("Unable to pull image: %s", err) + } + + var authConfig *dockerclient.AuthConfig + containerID, err := docker.CreateContainer(config, name, authConfig) + if err != nil { + return fmt.Errorf("Error while creating container: %s", err) + } + + if err = docker.StartContainer(containerID, &config.HostConfig); err != nil { + return fmt.Errorf("Error while starting container: %s", err) + } + + return nil +} diff --git a/libmachine/mcndockerclient/docker_host.go b/libmachine/mcndockerclient/docker_host.go new file mode 100644 index 0000000000..43d774edb3 --- /dev/null +++ b/libmachine/mcndockerclient/docker_host.go @@ -0,0 +1,41 @@ +package mcndockerclient + +import ( + "fmt" + + "github.com/docker/machine/libmachine/auth" +) + +type URLer interface { + // URL returns the Docker host URL + URL() (string, error) +} + +type AuthOptionser interface { + // AuthOptions returns the authOptions + AuthOptions() *auth.Options +} + +type DockerHost interface { + URLer + AuthOptionser +} + +type RemoteDocker struct { + HostURL string + AuthOption *auth.Options +} + +// URL returns the Docker host URL +func (rd *RemoteDocker) URL() (string, error) { + if rd.HostURL == "" { + return "", fmt.Errorf("Docker Host URL not set") + } + + return rd.HostURL, nil +} + +// AuthOptions returns the authOptions +func (rd *RemoteDocker) AuthOptions() *auth.Options { + return rd.AuthOption +} diff --git a/libmachine/mcndockerclient/docker_versioner.go b/libmachine/mcndockerclient/docker_versioner.go new file mode 100644 index 0000000000..b8279c777e --- /dev/null +++ b/libmachine/mcndockerclient/docker_versioner.go @@ -0,0 +1,29 @@ +package mcndockerclient + +import "fmt" + +var CurrentDockerVersioner DockerVersioner = &defaultDockerVersioner{} + +type DockerVersioner interface { + DockerVersion(host DockerHost) (string, error) +} + +func DockerVersion(host DockerHost) (string, error) { + return CurrentDockerVersioner.DockerVersion(host) +} + +type defaultDockerVersioner struct{} + +func (dv *defaultDockerVersioner) DockerVersion(host DockerHost) (string, error) { + client, err := DockerClient(host) + if err != nil { + return "", fmt.Errorf("Unable to query docker version: %s", err) + } + + version, err := client.Version() + if err != nil { + return "", fmt.Errorf("Unable to query docker version: %s", err) + } + + return version.Version, nil +} diff --git a/libmachine/mcndockerclient/fake_docker_versioner.go b/libmachine/mcndockerclient/fake_docker_versioner.go new file mode 100644 index 0000000000..32c4bb4cdf --- /dev/null +++ b/libmachine/mcndockerclient/fake_docker_versioner.go @@ -0,0 +1,14 @@ +package mcndockerclient + +type FakeDockerVersioner struct { + Version string + Err error +} + +func (dv *FakeDockerVersioner) DockerVersion(host DockerHost) (string, error) { + if dv.Err != nil { + return "", dv.Err + } + + return dv.Version, nil +} diff --git a/libmachine/mcnerror/errors.go b/libmachine/mcnerror/errors.go new file mode 100644 index 0000000000..6efc3c5c47 --- /dev/null +++ b/libmachine/mcnerror/errors.go @@ -0,0 +1,46 @@ +package mcnerror + +import ( + "errors" + "fmt" + "strings" + + "github.com/docker/machine/libmachine/state" +) + +var ( + ErrInvalidHostname = errors.New("Invalid hostname specified. Allowed hostname chars are: 0-9a-zA-Z . -") +) + +type ErrHostDoesNotExist struct { + Name string +} + +func (e ErrHostDoesNotExist) Error() string { + return fmt.Sprintf("Docker machine %q does not exist. Use \"docker-machine ls\" to list machines. Use \"docker-machine create\" to add a new one.", e.Name) +} + +type ErrHostAlreadyExists struct { + Name string +} + +func (e ErrHostAlreadyExists) Error() string { + return fmt.Sprintf("Docker machine %q already exists", e.Name) +} + +type ErrDuringPreCreate struct { + Cause error +} + +func (e ErrDuringPreCreate) Error() string { + return fmt.Sprintf("Error with pre-create check: %q", e.Cause) +} + +type ErrHostAlreadyInState struct { + Name string + State state.State +} + +func (e ErrHostAlreadyInState) Error() string { + return fmt.Sprintf("Machine %q is already %s.", e.Name, strings.ToLower(e.State.String())) +} diff --git a/libmachine/mcnflag/flag.go b/libmachine/mcnflag/flag.go new file mode 100644 index 0000000000..ec24d130ae --- /dev/null +++ b/libmachine/mcnflag/flag.go @@ -0,0 +1,71 @@ +package mcnflag + +import "fmt" + +type Flag interface { + fmt.Stringer + Default() interface{} +} + +type StringFlag struct { + Name string + Usage string + EnvVar string + Value string +} + +// TODO: Could this be done more succinctly using embedding? +func (f StringFlag) String() string { + return f.Name +} + +func (f StringFlag) Default() interface{} { + return f.Value +} + +type StringSliceFlag struct { + Name string + Usage string + EnvVar string + Value []string +} + +// TODO: Could this be done more succinctly using embedding? +func (f StringSliceFlag) String() string { + return f.Name +} + +func (f StringSliceFlag) Default() interface{} { + return f.Value +} + +type IntFlag struct { + Name string + Usage string + EnvVar string + Value int +} + +// TODO: Could this be done more succinctly using embedding? +func (f IntFlag) String() string { + return f.Name +} + +func (f IntFlag) Default() interface{} { + return f.Value +} + +type BoolFlag struct { + Name string + Usage string + EnvVar string +} + +// TODO: Could this be done more succinctly using embedding? +func (f BoolFlag) String() string { + return f.Name +} + +func (f BoolFlag) Default() interface{} { + return nil +} diff --git a/libmachine/mcnutils/b2d.go b/libmachine/mcnutils/b2d.go new file mode 100644 index 0000000000..f269195422 --- /dev/null +++ b/libmachine/mcnutils/b2d.go @@ -0,0 +1,542 @@ +package mcnutils + +import ( + "archive/tar" + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net" + "net/http" + "net/url" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/version" +) + +const ( + defaultURL = "https://api.github.com/repos/boot2docker/boot2docker/releases" + defaultISOFilename = "boot2docker.iso" + defaultVolumeIDOffset = int64(0x8028) + versionPrefix = "-v" + defaultVolumeIDLength = 32 +) + +var ( + GithubAPIToken string +) + +var ( + errGitHubAPIResponse = errors.New(`failure getting a version tag from the Github API response (are you getting rate limited by Github?)`) +) + +var ( + AUFSBugB2DVersions = map[string]string{ + "v1.9.1": "https://github.com/docker/docker/issues/18180", + } +) + +func defaultTimeout(network, addr string) (net.Conn, error) { + return net.Dial(network, addr) +} + +func getClient() *http.Client { + transport := http.Transport{ + DisableKeepAlives: true, + Proxy: http.ProxyFromEnvironment, + Dial: defaultTimeout, + } + + return &http.Client{ + Transport: &transport, + } +} + +func getRequest(apiURL string) (*http.Request, error) { + req, err := http.NewRequest("GET", apiURL, nil) + if err != nil { + return nil, err + } + + if GithubAPIToken != "" { + req.Header.Add("Authorization", fmt.Sprintf("token %s", GithubAPIToken)) + } + + return req, nil +} + +// releaseGetter is a client that gets release information of a product and downloads it. +type releaseGetter interface { + // filename returns filename of the product. + filename() string + // getReleaseTag gets a release tag from the given URL. + getReleaseTag(apiURL string) (string, error) + // getReleaseURL gets the latest release download URL from the given URL. + getReleaseURL(apiURL string) (string, error) + // download downloads a file from the given dlURL and saves it under dir. + download(dir, file, dlURL string) error +} + +// b2dReleaseGetter implements the releaseGetter interface for getting the release of Boot2Docker. +type b2dReleaseGetter struct { + isoFilename string +} + +func (b *b2dReleaseGetter) filename() string { + if b == nil { + return "" + } + return b.isoFilename +} + +// getReleaseTag gets the release tag of Boot2Docker from apiURL. +func (*b2dReleaseGetter) getReleaseTag(apiURL string) (string, error) { + if apiURL == "" { + apiURL = defaultURL + } + + if !version.RC() { + // Just go straight to the convenience URL for "/latest" if we + // are a non-release candidate version. "/latest" won't return + // non-RCs, so that's what we use for stable releases of + // Machine. + apiURL = apiURL + "/latest" + } + + client := getClient() + req, err := getRequest(apiURL) + if err != nil { + return "", err + } + rsp, err := client.Do(req) + if err != nil { + return "", err + } + defer rsp.Body.Close() + + // If we call the API endpoint + // "/repos/boot2docker/boot2docker/releases" without specifying + // "/latest", we will receive a list of releases instead of a single + // one, and we should decode accordingly. + if version.RC() { + var tags []struct { + TagName string `json:"tag_name"` + } + if err := json.NewDecoder(rsp.Body).Decode(&tags); err != nil { + return "", err + } + t := tags[0] + if t.TagName == "" { + return "", errGitHubAPIResponse + } + return t.TagName, nil + } + + // Otherwise, we get back just one release, which we can decode to get + // the tag. + var t struct { + TagName string `json:"tag_name"` + } + if err := json.NewDecoder(rsp.Body).Decode(&t); err != nil { + return "", err + } + if t.TagName == "" { + return "", errGitHubAPIResponse + } + return t.TagName, nil +} + +// getReleaseURL gets the latest release URL of Boot2Docker. +func (b *b2dReleaseGetter) getReleaseURL(apiURL string) (string, error) { + if apiURL == "" { + apiURL = defaultURL + } + + // match github (enterprise) release urls: + // https://api.github.com/repos/../../releases or + // https://some.github.enterprise/api/v3/repos/../../releases + re := regexp.MustCompile("(https?)://([^/]+)(/api/v3)?/repos/([^/]+)/([^/]+)/releases") + matches := re.FindStringSubmatch(apiURL) + if len(matches) != 6 { + // does not match a github releases api URL + return apiURL, nil + } + + scheme, host, org, repo := matches[1], matches[2], matches[4], matches[5] + if host == "api.github.com" { + host = "github.com" + } + + tag, err := b.getReleaseTag(apiURL) + if err != nil { + return "", err + } + + log.Infof("Latest release for %s/%s/%s is %s", host, org, repo, tag) + bugURL, ok := AUFSBugB2DVersions[tag] + if ok { + log.Warnf(` +Boot2Docker %s has a known issue with AUFS. +See here for more details: %s +Consider specifying another storage driver (e.g. 'overlay') using '--engine-storage-driver' instead. +`, tag, bugURL) + } + url := fmt.Sprintf("%s://%s/%s/%s/releases/download/%s/%s", scheme, host, org, repo, tag, b.isoFilename) + return url, nil +} + +func (*b2dReleaseGetter) download(dir, file, isoURL string) error { + u, err := url.Parse(isoURL) + + var src io.ReadCloser + if u.Scheme == "file" || u.Scheme == "" { + s, err := os.Open(u.Path) + if err != nil { + return err + } + + src = s + } else { + client := getClient() + s, err := client.Get(isoURL) + if err != nil { + return err + } + + src = &ReaderWithProgress{ + ReadCloser: s.Body, + out: os.Stdout, + expectedLength: s.ContentLength, + } + } + + defer src.Close() + + // Download to a temp file first then rename it to avoid partial download. + f, err := ioutil.TempFile(dir, file+".tmp") + if err != nil { + return err + } + + defer func() { + if err := removeFileIfExists(f.Name()); err != nil { + log.Warnf("Error removing file: %s", err) + } + }() + + if _, err := io.Copy(f, src); err != nil { + return err + } + + if err := f.Close(); err != nil { + return err + } + + // Dest is the final path of the boot2docker.iso file. + dest := filepath.Join(dir, file) + + // Windows can't rename in place, so remove the old file before + // renaming the temporary downloaded file. + if err := removeFileIfExists(dest); err != nil { + return err + } + + return os.Rename(f.Name(), dest) +} + +// iso is an ISO volume. +type iso interface { + // path returns the path of the ISO. + path() string + // exists reports whether the ISO exists. + exists() bool + // version returns version information of the ISO. + version() (string, error) +} + +// b2dISO represents a Boot2Docker ISO. It implements the ISO interface. +type b2dISO struct { + // path of Boot2Docker ISO + commonIsoPath string + + // offset and length of ISO volume ID + // cf. http://serverfault.com/questions/361474/is-there-a-way-to-change-a-iso-files-volume-id-from-the-command-line + volumeIDOffset int64 + volumeIDLength int +} + +func (b *b2dISO) path() string { + if b == nil { + return "" + } + return b.commonIsoPath +} + +func (b *b2dISO) exists() bool { + if b == nil { + return false + } + + _, err := os.Stat(b.commonIsoPath) + return !os.IsNotExist(err) +} + +// version scans the volume ID in b and returns its version tag. +func (b *b2dISO) version() (string, error) { + if b == nil { + return "", nil + } + + iso, err := os.Open(b.commonIsoPath) + if err != nil { + return "", err + } + defer iso.Close() + + isoMetadata := make([]byte, b.volumeIDLength) + _, err = iso.ReadAt(isoMetadata, b.volumeIDOffset) + if err != nil { + return "", err + } + + trimmedVersion := strings.TrimSpace(string(isoMetadata)) + + versionIndex := strings.Index(trimmedVersion, versionPrefix) + if versionIndex == -1 { + return "", fmt.Errorf("Did not find prefix %q in version string", versionPrefix) + } + + // Original magic file string looks similar to this: "Boot2Docker-v0.1.0 " + // This will return "v0.1.0" given the above string + vers := trimmedVersion[versionIndex+1:] + + log.Debug("local Boot2Docker ISO version: ", vers) + return vers, nil +} + +func removeFileIfExists(name string) error { + if _, err := os.Stat(name); err == nil { + if err := os.Remove(name); err != nil { + return fmt.Errorf("Error removing temporary download file: %s", err) + } + } + return nil +} + +type B2dUtils struct { + releaseGetter + iso + storePath string + imgCachePath string +} + +func NewB2dUtils(storePath string) *B2dUtils { + imgCachePath := filepath.Join(storePath, "cache") + + return &B2dUtils{ + releaseGetter: &b2dReleaseGetter{isoFilename: defaultISOFilename}, + iso: &b2dISO{ + commonIsoPath: filepath.Join(imgCachePath, defaultISOFilename), + volumeIDOffset: defaultVolumeIDOffset, + volumeIDLength: defaultVolumeIDLength, + }, + storePath: storePath, + imgCachePath: imgCachePath, + } +} + +// DownloadISO downloads boot2docker ISO image for the given tag and save it at dest. +func (b *B2dUtils) DownloadISO(dir, file, isoURL string) error { + log.Infof("Downloading %s from %s...", b.path(), isoURL) + return b.download(dir, file, isoURL) +} + +type ReaderWithProgress struct { + io.ReadCloser + out io.Writer + bytesTransferred int64 + expectedLength int64 + nextPercentToPrint int64 +} + +func (r *ReaderWithProgress) Read(p []byte) (int, error) { + n, err := r.ReadCloser.Read(p) + + if n > 0 { + r.bytesTransferred += int64(n) + percentage := r.bytesTransferred * 100 / r.expectedLength + + for percentage >= r.nextPercentToPrint { + if r.nextPercentToPrint%10 == 0 { + fmt.Fprintf(r.out, "%d%%", r.nextPercentToPrint) + } else if r.nextPercentToPrint%2 == 0 { + fmt.Fprint(r.out, ".") + } + r.nextPercentToPrint += 2 + } + } + + return n, err +} + +func (r *ReaderWithProgress) Close() error { + fmt.Fprintln(r.out) + return r.ReadCloser.Close() +} + +func (b *B2dUtils) DownloadLatestBoot2Docker(apiURL string) error { + latestReleaseURL, err := b.getReleaseURL(apiURL) + if err != nil { + return err + } + + return b.DownloadISOFromURL(latestReleaseURL) +} + +func (b *B2dUtils) DownloadISOFromURL(latestReleaseURL string) error { + return b.DownloadISO(b.imgCachePath, b.filename(), latestReleaseURL) +} + +func (b *B2dUtils) UpdateISOCache(isoURL string) error { + // recreate the cache dir if it has been manually deleted + if _, err := os.Stat(b.imgCachePath); os.IsNotExist(err) { + log.Infof("Image cache directory does not exist, creating it at %s...", b.imgCachePath) + if err := os.Mkdir(b.imgCachePath, 0700); err != nil { + return err + } + } + + exists := b.exists() + + if isoURL != "" { + if exists { + // Warn that the b2d iso won't be updated if isoURL is set + log.Warnf("Boot2Docker URL was explicitly set to %q at create time, so Docker Machine cannot upgrade this machine to the latest version.", isoURL) + } + // Non-default B2D are not cached + return nil + } + + if !exists { + log.Info("No default Boot2Docker ISO found locally, downloading the latest release...") + return b.DownloadLatestBoot2Docker("") + } + + latest := b.isLatest() + if !latest { + log.Info("Default Boot2Docker ISO is out-of-date, downloading the latest release...") + return b.DownloadLatestBoot2Docker("") + } + + return nil +} + +func (b *B2dUtils) CopyIsoToMachineDir(isoURL, machineName string) error { + if err := b.UpdateISOCache(isoURL); err != nil { + return err + } + + // TODO: This is a bit off-color. + machineDir := filepath.Join(b.storePath, "machines", machineName) + machineIsoPath := filepath.Join(machineDir, b.filename()) + + // By default just copy the existing "cached" iso to the machine's directory... + if isoURL == "" { + log.Infof("Copying %s to %s...", b.path(), machineIsoPath) + return CopyFile(b.path(), machineIsoPath) + } + + // if ISO is specified, check if it matches a github releases url or fallback to a direct download + downloadURL, err := b.getReleaseURL(isoURL) + if err != nil { + return err + } + + return b.DownloadISO(machineDir, b.filename(), downloadURL) +} + +// isLatest checks the latest release tag and +// reports whether the local ISO cache is the latest version. +// +// It returns false if failing to get the local ISO version +// and true if failing to fetch the latest release tag. +func (b *B2dUtils) isLatest() bool { + localVer, err := b.version() + if err != nil { + log.Warn("Unable to get the local Boot2Docker ISO version: ", err) + return false + } + + latestVer, err := b.getReleaseTag("") + if err != nil { + log.Warn("Unable to get the latest Boot2Docker ISO release version: ", err) + return true + } + + return localVer == latestVer +} + +// MakeDiskImage makes a boot2docker VM disk image. +// See https://github.com/boot2docker/boot2docker/blob/master/rootfs/rootfs/etc/rc.d/automount +func MakeDiskImage(publicSSHKeyPath string) (*bytes.Buffer, error) { + magicString := "boot2docker, please format-me" + + buf := new(bytes.Buffer) + tw := tar.NewWriter(buf) + + // magicString first so the automount script knows to format the disk + file := &tar.Header{Name: magicString, Size: int64(len(magicString))} + + log.Debug("Writing magic tar header") + + if err := tw.WriteHeader(file); err != nil { + return nil, err + } + + if _, err := tw.Write([]byte(magicString)); err != nil { + return nil, err + } + + // .ssh/key.pub => authorized_keys + file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700} + if err := tw.WriteHeader(file); err != nil { + return nil, err + } + + log.Debug("Writing SSH key tar header") + + pubKey, err := ioutil.ReadFile(publicSSHKeyPath) + if err != nil { + return nil, err + } + + file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return nil, err + } + + if _, err := tw.Write([]byte(pubKey)); err != nil { + return nil, err + } + + file = &tar.Header{Name: ".ssh/authorized_keys2", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return nil, err + } + + if _, err := tw.Write([]byte(pubKey)); err != nil { + return nil, err + } + + if err := tw.Close(); err != nil { + return nil, err + } + + return buf, nil +} diff --git a/libmachine/mcnutils/b2d_test.go b/libmachine/mcnutils/b2d_test.go new file mode 100644 index 0000000000..cf1cfad426 --- /dev/null +++ b/libmachine/mcnutils/b2d_test.go @@ -0,0 +1,339 @@ +package mcnutils + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/version" + "github.com/stretchr/testify/assert" +) + +func TestGetReleaseURL(t *testing.T) { + testCases := []struct { + apiURL string + isoURL string + machineVersion string + response string + }{ + {"/repos/org/repo/releases/latest", "/org/repo/releases/download/v0.1/boot2docker.iso", "v0.7.0", `{"tag_name": "v0.1"}`}, + + // Note the difference in this one: It's an RC version. + {"/repos/org/repo/releases", "/org/repo/releases/download/v0.2-rc1/boot2docker.iso", "v0.7.0-rc2", `[{"tag_name": "v0.2-rc1"}, {"tag_name": "v0.1"}]`}, + + {"http://dummy.com/boot2docker.iso", "http://dummy.com/boot2docker.iso", "v0.7.0", `{"tag_name": "v0.1"}`}, + } + + for _, tt := range testCases { + testServer := newTestServer(tt.response) + + // TODO: Modifying this package level variable is not elegant, + // but it is effective. Ideally this should be exposed through + // an interface. + actualMachineVersion := version.Version + version.Version = tt.machineVersion + b := NewB2dUtils("/tmp/isos") + isoURL, err := b.getReleaseURL(testServer.URL + tt.apiURL) + + assert.NoError(t, err) + assert.Equal(t, testServer.URL+tt.isoURL, isoURL) + version.Version = actualMachineVersion + + testServer.Close() + } +} + +func TestGetReleaseURLError(t *testing.T) { + // GitHub API error response in case of rate limit + ts := newTestServer(`{"message": "API rate limit exceeded for 127.0.0.1.", + "documentation_url": "https://developer.github.com/v3/#rate-limiting"}`) + defer ts.Close() + + testCases := []struct { + apiURL string + }{ + {ts.URL + "/repos/org/repo/releases/latest"}, + {"http://127.0.0.1/repos/org/repo/releases/latest"}, // dummy API URL. cannot connect it. + } + + for _, tt := range testCases { + b := NewB2dUtils("/tmp/isos") + _, err := b.getReleaseURL(tt.apiURL) + + assert.Error(t, err) + } +} + +func TestVersion(t *testing.T) { + testCases := []string{ + "v0.1.0", + "v0.2.0-rc1", + } + + for _, vers := range testCases { + isopath, off, err := newDummyISO("", defaultISOFilename, vers) + + assert.NoError(t, err) + + b := &b2dISO{ + commonIsoPath: isopath, + volumeIDOffset: off, + volumeIDLength: defaultVolumeIDLength, + } + + got, err := b.version() + + assert.NoError(t, err) + assert.Equal(t, vers, string(got)) + removeFileIfExists(isopath) + } +} + +func TestDownloadISO(t *testing.T) { + testData := "test-download" + ts := newTestServer(testData) + defer ts.Close() + + filename := "test" + + tmpDir, err := ioutil.TempDir("", "machine-test-") + + assert.NoError(t, err) + + b := NewB2dUtils("/tmp/artifacts") + err = b.DownloadISO(tmpDir, filename, ts.URL) + + assert.NoError(t, err) + + data, err := ioutil.ReadFile(filepath.Join(tmpDir, filename)) + + assert.NoError(t, err) + assert.Equal(t, testData, string(data)) +} + +func TestGetRequest(t *testing.T) { + testCases := []struct { + token string + want string + }{ + {"", ""}, + {"CATBUG", "token CATBUG"}, + } + + for _, tt := range testCases { + GithubAPIToken = tt.token + + req, err := getRequest("http://some.github.api") + + assert.NoError(t, err) + assert.Equal(t, tt.want, req.Header.Get("Authorization")) + } +} + +type MockReadCloser struct { + blockLengths []int + currentBlock int +} + +func (r *MockReadCloser) Read(p []byte) (n int, err error) { + n = r.blockLengths[r.currentBlock] + r.currentBlock++ + return +} + +func (r *MockReadCloser) Close() error { + return nil +} + +func TestReaderWithProgress(t *testing.T) { + readCloser := MockReadCloser{blockLengths: []int{5, 45, 50}} + output := new(bytes.Buffer) + buffer := make([]byte, 100) + + readerWithProgress := ReaderWithProgress{ + ReadCloser: &readCloser, + out: output, + expectedLength: 100, + } + + readerWithProgress.Read(buffer) + assert.Equal(t, "0%..", output.String()) + + readerWithProgress.Read(buffer) + assert.Equal(t, "0%....10%....20%....30%....40%....50%", output.String()) + + readerWithProgress.Read(buffer) + assert.Equal(t, "0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%", output.String()) + + readerWithProgress.Close() + assert.Equal(t, "0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%\n", output.String()) +} + +type mockReleaseGetter struct { + ver string + apiErr error + verCh chan<- string +} + +func (m *mockReleaseGetter) filename() string { + return defaultISOFilename +} + +func (m *mockReleaseGetter) getReleaseTag(apiURL string) (string, error) { + return m.ver, m.apiErr +} + +func (m *mockReleaseGetter) getReleaseURL(apiURL string) (string, error) { + return "http://127.0.0.1/dummy", m.apiErr +} + +func (m *mockReleaseGetter) download(dir, file, isoURL string) error { + path := filepath.Join(dir, file) + var err error + if _, e := os.Stat(path); os.IsNotExist(e) { + err = ioutil.WriteFile(path, dummyISOData(" ", m.ver), 0644) + } + + // send a signal of downloading the latest version + m.verCh <- m.ver + return err +} + +type mockISO struct { + isopath string + exist bool + ver string + verCh <-chan string +} + +func (m *mockISO) path() string { + return m.isopath +} + +func (m *mockISO) exists() bool { + return m.exist +} + +func (m *mockISO) version() (string, error) { + select { + // receive version of a downloaded iso + case ver := <-m.verCh: + return ver, nil + default: + return m.ver, nil + } +} + +func TestCopyDefaultISOToMachine(t *testing.T) { + apiErr := errors.New("api error") + + testCases := []struct { + machineName string + create bool + localVer string + latestVer string + apiErr error + wantVer string + }{ + {"none", false, "", "v1.0.0", nil, "v1.0.0"}, // none => downloading + {"latest", true, "v1.0.0", "v1.0.0", nil, "v1.0.0"}, // latest iso => as is + {"old-badurl", true, "v0.1.0", "", apiErr, "v0.1.0"}, // old iso with bad api => as is + {"old", true, "v0.1.0", "v1.0.0", nil, "v1.0.0"}, // old iso => updating + } + + var isopath string + var err error + verCh := make(chan string, 1) + for _, tt := range testCases { + if tt.create { + isopath, _, err = newDummyISO("cache", defaultISOFilename, tt.localVer) + } else { + if dir, e := ioutil.TempDir("", "machine-test"); e == nil { + isopath = filepath.Join(dir, "cache", defaultISOFilename) + } + } + + // isopath: "$TMPDIR/machine-test-xxxxxx/cache/boot2docker.iso" + // tmpDir: "$TMPDIR/machine-test-xxxxxx" + imgCachePath := filepath.Dir(isopath) + storePath := filepath.Dir(imgCachePath) + + b := &B2dUtils{ + releaseGetter: &mockReleaseGetter{ + ver: tt.latestVer, + apiErr: tt.apiErr, + verCh: verCh, + }, + iso: &mockISO{ + isopath: isopath, + exist: tt.create, + ver: tt.localVer, + verCh: verCh, + }, + storePath: storePath, + imgCachePath: imgCachePath, + } + + dir := filepath.Join(storePath, "machines", tt.machineName) + err = os.MkdirAll(dir, 0700) + assert.NoError(t, err, "machine: %s", tt.machineName) + + err = b.CopyIsoToMachineDir("", tt.machineName) + assert.NoError(t, err) + + dest := filepath.Join(dir, b.filename()) + _, pathErr := os.Stat(dest) + + assert.NoError(t, err, "machine: %s", tt.machineName) + assert.True(t, !os.IsNotExist(pathErr), "machine: %s", tt.machineName) + + ver, err := b.version() + + assert.NoError(t, err, "machine: %s", tt.machineName) + assert.Equal(t, tt.wantVer, ver, "machine: %s", tt.machineName) + + err = removeFileIfExists(isopath) + assert.NoError(t, err, "machine: %s", tt.machineName) + } +} + +// newTestServer creates a new httptest.Server that returns respText as a response body. +func newTestServer(respText string) *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(respText)) + })) +} + +// newDummyISO creates a dummy ISO file that contains the given version info, +// and returns its path and offset value to fetch the version info. +func newDummyISO(dir, name, version string) (string, int64, error) { + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + return "", 0, err + } + + tmpDir = filepath.Join(tmpDir, dir) + if e := os.MkdirAll(tmpDir, 755); e != nil { + return "", 0, err + } + + isopath := filepath.Join(tmpDir, name) + log.Info("TEST: dummy ISO created at ", isopath) + + // dummy ISO data mimicking the real byte data of a Boot2Docker ISO image + padding := " " + data := dummyISOData(padding, version) + return isopath, int64(len(padding)), ioutil.WriteFile(isopath, data, 0644) +} + +// dummyISOData returns mock data that contains given padding and version. +func dummyISOData(padding, version string) []byte { + return []byte(fmt.Sprintf("%sBoot2Docker-%s ", padding, version)) +} diff --git a/libmachine/mcnutils/utils.go b/libmachine/mcnutils/utils.go new file mode 100644 index 0000000000..a3992ed164 --- /dev/null +++ b/libmachine/mcnutils/utils.go @@ -0,0 +1,133 @@ +package mcnutils + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "io" + "os" + "runtime" + "strconv" + "time" +) + +type MultiError struct { + Errs []error +} + +func (e MultiError) Error() string { + aggregate := "" + for _, err := range e.Errs { + aggregate += err.Error() + "\n" + } + return aggregate +} + +// GetHomeDir returns the home directory +// TODO: Having this here just strikes me as dangerous, but some of the drivers +// depend on it ;_; +func GetHomeDir() string { + if runtime.GOOS == "windows" { + return os.Getenv("USERPROFILE") + } + return os.Getenv("HOME") +} + +func GetUsername() string { + u := "unknown" + osUser := "" + + switch runtime.GOOS { + case "darwin", "linux": + osUser = os.Getenv("USER") + case "windows": + osUser = os.Getenv("USERNAME") + } + + if osUser != "" { + u = osUser + } + + return u +} + +func CopyFile(src, dst string) error { + in, err := os.Open(src) + if err != nil { + return err + } + + defer in.Close() + + out, err := os.Create(dst) + if err != nil { + return err + } + + defer out.Close() + + if _, err = io.Copy(out, in); err != nil { + return err + } + + fi, err := os.Stat(src) + if err != nil { + return err + } + + return os.Chmod(dst, fi.Mode()) +} + +func WaitForSpecificOrError(f func() (bool, error), maxAttempts int, waitInterval time.Duration) error { + for i := 0; i < maxAttempts; i++ { + stop, err := f() + if err != nil { + return err + } + if stop { + return nil + } + time.Sleep(waitInterval) + } + return fmt.Errorf("Maximum number of retries (%d) exceeded", maxAttempts) +} + +func WaitForSpecific(f func() bool, maxAttempts int, waitInterval time.Duration) error { + return WaitForSpecificOrError(func() (bool, error) { + return f(), nil + }, maxAttempts, waitInterval) +} + +func WaitFor(f func() bool) error { + return WaitForSpecific(f, 60, 3*time.Second) +} + +// TruncateID returns a shorten id +// Following two functions are from github.com/docker/docker/utils module. It +// was way overkill to include the whole module, so we just have these bits +// that we're using here. +func TruncateID(id string) string { + shortLen := 12 + if len(id) < shortLen { + shortLen = len(id) + } + return id[:shortLen] +} + +// GenerateRandomID returns an unique id +func GenerateRandomID() string { + for { + id := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, id); err != nil { + panic(err) // This shouldn't happen + } + value := hex.EncodeToString(id) + // if we try to parse the truncated for as an int and we don't have + // an error then the value is all numeric and causes issues when + // used as a hostname. ref #3869 + if _, err := strconv.ParseInt(TruncateID(value), 10, 64); err == nil { + continue + } + return value + } +} diff --git a/libmachine/mcnutils/utils_test.go b/libmachine/mcnutils/utils_test.go new file mode 100644 index 0000000000..036e2b72f4 --- /dev/null +++ b/libmachine/mcnutils/utils_test.go @@ -0,0 +1,101 @@ +package mcnutils + +import ( + "io/ioutil" + "os" + "path/filepath" + "runtime" + "testing" +) + +func TestCopyFile(t *testing.T) { + testStr := "test-machine" + + srcFile, err := ioutil.TempFile("", "machine-test-") + if err != nil { + t.Fatal(err) + } + srcFi, err := srcFile.Stat() + if err != nil { + t.Fatal(err) + } + + srcFile.Write([]byte(testStr)) + srcFile.Close() + + srcFilePath := filepath.Join(os.TempDir(), srcFi.Name()) + + destFile, err := ioutil.TempFile("", "machine-copy-test-") + if err != nil { + t.Fatal(err) + } + + destFi, err := destFile.Stat() + if err != nil { + t.Fatal(err) + } + + destFile.Close() + + destFilePath := filepath.Join(os.TempDir(), destFi.Name()) + + if err := CopyFile(srcFilePath, destFilePath); err != nil { + t.Fatal(err) + } + + data, err := ioutil.ReadFile(destFilePath) + if err != nil { + t.Fatal(err) + } + + if string(data) != testStr { + t.Fatalf("expected data \"%s\"; received \"%s\"", testStr, string(data)) + } +} + +func TestGetUsername(t *testing.T) { + currentUser := "unknown" + switch runtime.GOOS { + case "darwin", "linux": + currentUser = os.Getenv("USER") + case "windows": + currentUser = os.Getenv("USERNAME") + } + + username := GetUsername() + if username != currentUser { + t.Fatalf("expected username %s; received %s", currentUser, username) + } +} + +func TestGenerateRandomID(t *testing.T) { + id := GenerateRandomID() + + if len(id) != 64 { + t.Fatalf("Id returned is incorrect: %s", id) + } +} + +func TestShortenId(t *testing.T) { + id := GenerateRandomID() + truncID := TruncateID(id) + if len(truncID) != 12 { + t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID) + } +} + +func TestShortenIdEmpty(t *testing.T) { + id := "" + truncID := TruncateID(id) + if len(truncID) > len(id) { + t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID) + } +} + +func TestShortenIdInvalid(t *testing.T) { + id := "1234" + truncID := TruncateID(id) + if len(truncID) != len(id) { + t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID) + } +} diff --git a/libmachine/persist/filestore.go b/libmachine/persist/filestore.go new file mode 100644 index 0000000000..ea79f44a5f --- /dev/null +++ b/libmachine/persist/filestore.go @@ -0,0 +1,161 @@ +package persist + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/mcnerror" +) + +type Filestore struct { + Path string + CaCertPath string + CaPrivateKeyPath string +} + +func NewFilestore(path, caCertPath, caPrivateKeyPath string) *Filestore { + return &Filestore{ + Path: path, + CaCertPath: caCertPath, + CaPrivateKeyPath: caPrivateKeyPath, + } +} + +func (s Filestore) GetMachinesDir() string { + return filepath.Join(s.Path, "machines") +} + +func (s Filestore) saveToFile(data []byte, file string) error { + if _, err := os.Stat(file); os.IsNotExist(err) { + return ioutil.WriteFile(file, data, 0600) + } + + tmpfi, err := ioutil.TempFile(filepath.Dir(file), "config.json.tmp") + if err != nil { + return err + } + defer os.Remove(tmpfi.Name()) + + if err = ioutil.WriteFile(tmpfi.Name(), data, 0600); err != nil { + return err + } + + if err = tmpfi.Close(); err != nil { + return err + } + + if err = os.Remove(file); err != nil { + return err + } + + err = os.Rename(tmpfi.Name(), file) + return err +} + +func (s Filestore) Save(host *host.Host) error { + data, err := json.MarshalIndent(host, "", " ") + if err != nil { + return err + } + + hostPath := filepath.Join(s.GetMachinesDir(), host.Name) + + // Ensure that the directory we want to save to exists. + if err := os.MkdirAll(hostPath, 0700); err != nil { + return err + } + + return s.saveToFile(data, filepath.Join(hostPath, "config.json")) +} + +func (s Filestore) Remove(name string) error { + hostPath := filepath.Join(s.GetMachinesDir(), name) + return os.RemoveAll(hostPath) +} + +func (s Filestore) List() ([]string, error) { + dir, err := ioutil.ReadDir(s.GetMachinesDir()) + if err != nil && !os.IsNotExist(err) { + return nil, err + } + + hostNames := []string{} + + for _, file := range dir { + if file.IsDir() && !strings.HasPrefix(file.Name(), ".") { + hostNames = append(hostNames, file.Name()) + } + } + + return hostNames, nil +} + +func (s Filestore) Exists(name string) (bool, error) { + _, err := os.Stat(filepath.Join(s.GetMachinesDir(), name)) + + if os.IsNotExist(err) { + return false, nil + } else if err == nil { + return true, nil + } + + return false, err +} + +func (s Filestore) loadConfig(h *host.Host) error { + data, err := ioutil.ReadFile(filepath.Join(s.GetMachinesDir(), h.Name, "config.json")) + if err != nil { + return err + } + + // Remember the machine name so we don't have to pass it through each + // struct in the migration. + name := h.Name + + migratedHost, migrationPerformed, err := host.MigrateHost(h, data) + if err != nil { + return fmt.Errorf("Error getting migrated host: %s", err) + } + + *h = *migratedHost + + h.Name = name + + // If we end up performing a migration, we should save afterwards so we don't have to do it again on subsequent invocations. + if migrationPerformed { + if err := s.saveToFile(data, filepath.Join(s.GetMachinesDir(), h.Name, "config.json.bak")); err != nil { + return fmt.Errorf("Error attempting to save backup after migration: %s", err) + } + + if err := s.Save(h); err != nil { + return fmt.Errorf("Error saving config after migration was performed: %s", err) + } + } + + return nil +} + +func (s Filestore) Load(name string) (*host.Host, error) { + hostPath := filepath.Join(s.GetMachinesDir(), name) + + if _, err := os.Stat(hostPath); os.IsNotExist(err) { + return nil, mcnerror.ErrHostDoesNotExist{ + Name: name, + } + } + + host := &host.Host{ + Name: name, + } + + if err := s.loadConfig(host); err != nil { + return nil, err + } + + return host, nil +} diff --git a/libmachine/persist/filestore_test.go b/libmachine/persist/filestore_test.go new file mode 100644 index 0000000000..243d565b0b --- /dev/null +++ b/libmachine/persist/filestore_test.go @@ -0,0 +1,249 @@ +package persist + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "regexp" + "testing" + + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/drivers/none" + "github.com/docker/machine/libmachine/host" + "github.com/docker/machine/libmachine/hosttest" +) + +func cleanup() { + os.RemoveAll(os.Getenv("MACHINE_STORAGE_PATH")) +} + +func getTestStore() Filestore { + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + mcndirs.BaseDir = tmpDir + + return Filestore{ + Path: tmpDir, + CaCertPath: filepath.Join(tmpDir, "certs", "ca-cert.pem"), + CaPrivateKeyPath: filepath.Join(tmpDir, "certs", "ca-key.pem"), + } +} + +func TestStoreSave(t *testing.T) { + defer cleanup() + + store := getTestStore() + + h, err := hosttest.GetDefaultTestHost() + if err != nil { + t.Fatal(err) + } + + if err := store.Save(h); err != nil { + t.Fatal(err) + } + + path := filepath.Join(store.GetMachinesDir(), h.Name) + if _, err := os.Stat(path); os.IsNotExist(err) { + t.Fatalf("Host path doesn't exist: %s", path) + } + + files, _ := ioutil.ReadDir(path) + for _, f := range files { + r, err := regexp.Compile("config.json.tmp*") + if err != nil { + t.Fatalf("Failed to compile regexp string") + } + if r.MatchString(f.Name()) { + t.Fatalf("Failed to remove temp filestore:%s", f.Name()) + } + } +} + +func TestStoreSaveOmitRawDriver(t *testing.T) { + defer cleanup() + + store := getTestStore() + + h, err := hosttest.GetDefaultTestHost() + if err != nil { + t.Fatal(err) + } + + if err := store.Save(h); err != nil { + t.Fatal(err) + } + + configJSONPath := filepath.Join(store.GetMachinesDir(), h.Name, "config.json") + + f, err := os.Open(configJSONPath) + if err != nil { + t.Fatal(err) + } + + configData, err := ioutil.ReadAll(f) + if err != nil { + t.Fatal(err) + } + + fakeHost := make(map[string]interface{}) + + if err := json.Unmarshal(configData, &fakeHost); err != nil { + t.Fatal(err) + } + + if rawDriver, ok := fakeHost["RawDriver"]; ok { + t.Fatal("Should not have gotten a value for RawDriver reading host from disk but got one: ", rawDriver) + } + +} + +func TestStoreRemove(t *testing.T) { + defer cleanup() + + store := getTestStore() + + h, err := hosttest.GetDefaultTestHost() + if err != nil { + t.Fatal(err) + } + + if err := store.Save(h); err != nil { + t.Fatal(err) + } + + path := filepath.Join(store.GetMachinesDir(), h.Name) + if _, err := os.Stat(path); os.IsNotExist(err) { + t.Fatalf("Host path doesn't exist: %s", path) + } + + err = store.Remove(h.Name) + if err != nil { + t.Fatal(err) + } + + if _, err := os.Stat(path); err == nil { + t.Fatalf("Host path still exists after remove: %s", path) + } +} + +func TestStoreList(t *testing.T) { + defer cleanup() + + store := getTestStore() + + h, err := hosttest.GetDefaultTestHost() + if err != nil { + t.Fatal(err) + } + + if err := store.Save(h); err != nil { + t.Fatal(err) + } + + hosts, err := store.List() + if len(hosts) != 1 { + t.Fatalf("List returned %d items, expected 1", len(hosts)) + } + + if hosts[0] != h.Name { + t.Fatalf("hosts[0] name is incorrect, got: %s", hosts[0]) + } +} + +func TestStoreExists(t *testing.T) { + defer cleanup() + store := getTestStore() + + h, err := hosttest.GetDefaultTestHost() + if err != nil { + t.Fatal(err) + } + + exists, err := store.Exists(h.Name) + if exists { + t.Fatal("Host should not exist before saving") + } + + if err := store.Save(h); err != nil { + t.Fatal(err) + } + + exists, err = store.Exists(h.Name) + if err != nil { + t.Fatal(err) + } + + if !exists { + t.Fatal("Host should exist after saving") + } + + if err := store.Remove(h.Name); err != nil { + t.Fatal(err) + } + + exists, err = store.Exists(h.Name) + if err != nil { + t.Fatal(err) + } + + if exists { + t.Fatal("Host should not exist after removing") + } +} + +func TestStoreLoad(t *testing.T) { + defer cleanup() + + expectedURL := "unix:///foo/baz" + flags := hosttest.GetTestDriverFlags() + flags.Data["url"] = expectedURL + + store := getTestStore() + + h, err := hosttest.GetDefaultTestHost() + if err != nil { + t.Fatal(err) + } + + if err := h.Driver.SetConfigFromFlags(flags); err != nil { + t.Fatal(err) + } + + if err := store.Save(h); err != nil { + t.Fatal(err) + } + + h, err = store.Load(h.Name) + if err != nil { + t.Fatal(err) + } + + rawDataDriver, ok := h.Driver.(*host.RawDataDriver) + if !ok { + t.Fatal("Expected driver loaded from store to be of type *host.RawDataDriver and it was not") + } + + realDriver := none.NewDriver(h.Name, store.Path) + + if err := json.Unmarshal(rawDataDriver.Data, &realDriver); err != nil { + t.Fatalf("Error unmarshaling rawDataDriver data into concrete 'none' driver: %s", err) + } + + h.Driver = realDriver + + actualURL, err := h.URL() + if err != nil { + t.Fatal(err) + } + + if actualURL != expectedURL { + t.Fatalf("GetURL is not %q, got %q", expectedURL, actualURL) + } +} diff --git a/libmachine/persist/persisttest/fakestore.go b/libmachine/persist/persisttest/fakestore.go new file mode 100644 index 0000000000..96c42ce0fa --- /dev/null +++ b/libmachine/persist/persisttest/fakestore.go @@ -0,0 +1,63 @@ +package persisttest + +import "github.com/docker/machine/libmachine/host" + +type FakeStore struct { + Hosts []*host.Host + ExistsErr, ListErr, LoadErr, RemoveErr, SaveErr error +} + +func (fs *FakeStore) Exists(name string) (bool, error) { + if fs.ExistsErr != nil { + return false, fs.ExistsErr + } + for _, h := range fs.Hosts { + if h.Name == name { + return true, nil + } + } + + return false, nil +} + +func (fs *FakeStore) List() ([]string, error) { + names := []string{} + for _, h := range fs.Hosts { + names = append(names, h.Name) + } + return names, fs.ListErr +} + +func (fs *FakeStore) Load(name string) (*host.Host, error) { + if fs.LoadErr != nil { + return nil, fs.LoadErr + } + for _, h := range fs.Hosts { + if h.Name == name { + return h, nil + } + } + + return nil, nil +} + +func (fs *FakeStore) Remove(name string) error { + if fs.RemoveErr != nil { + return fs.RemoveErr + } + for i, h := range fs.Hosts { + if h.Name == name { + fs.Hosts = append(fs.Hosts[:i], fs.Hosts[i+1:]...) + return nil + } + } + return nil +} + +func (fs *FakeStore) Save(host *host.Host) error { + if fs.SaveErr == nil { + fs.Hosts = append(fs.Hosts, host) + return nil + } + return fs.SaveErr +} diff --git a/libmachine/persist/persisttest/fakestore_test.go b/libmachine/persist/persisttest/fakestore_test.go new file mode 100644 index 0000000000..9fbffd93a7 --- /dev/null +++ b/libmachine/persist/persisttest/fakestore_test.go @@ -0,0 +1,124 @@ +package persisttest + +import ( + "fmt" + "reflect" + "testing" + + "github.com/docker/machine/libmachine/host" +) + +func TestExists(t *testing.T) { + store := FakeStore{ + Hosts: []*host.Host{{Name: "my-host"}}, + } + exist, err := store.Exists("my-host") + if err != nil { + t.Fatal(err) + } + if exist == false { + t.Fatal("Expected host 'my-host' to exist") + } + exist, err = store.Exists("not-found") + if err != nil { + t.Fatal(err) + } + if exist == true { + t.Fatal("Expected host 'not-found' to no exist") + } + store.ExistsErr = fmt.Errorf("error checking host") + exist, err = store.Exists("my-host") + if err != store.ExistsErr { + t.Fatalf("Expected err %s.", store.ExistsErr) + } +} + +func TestList(t *testing.T) { + store := FakeStore{ + Hosts: []*host.Host{{Name: "my-host"}, {Name: "my-host-2"}}, + } + list, err := store.List() + if err != nil { + t.Fatal(err) + } + expected := []string{"my-host", "my-host-2"} + if !reflect.DeepEqual(list, expected) { + t.Fatalf("Expected hosts to be %s. Got %s.", expected, list) + } + store.ListErr = fmt.Errorf("error listing") + list, err = store.List() + if err != store.ListErr { + t.Fatal(err) + } +} + +func TestLoad(t *testing.T) { + expectedHost := &host.Host{Name: "my-host"} + store := FakeStore{ + Hosts: []*host.Host{expectedHost}, + } + h, err := store.Load("my-host") + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(expectedHost, h) { + t.Fatalf("Wrong host. Expected %v. Got %v.", expectedHost, h) + } + h, err = store.Load("not-found") + if err != nil { + t.Fatal(err) + } + if h != nil { + t.Fatalf("Expected nil host. Got %v.", h) + } + store.LoadErr = fmt.Errorf("error loading") + h, err = store.Load("my-host") + if err != store.LoadErr { + t.Fatalf("Wrong error. Expected %s. Got %s.", store.LoadErr, err) + } + if h != nil { + t.Fatalf("Expected nil host. Got %v.", h) + } +} + +func TestRemove(t *testing.T) { + store := FakeStore{ + Hosts: []*host.Host{{Name: "my-host"}}, + } + err := store.Remove("not-found") + if err != nil { + t.Fatal(err) + } + err = store.Remove("my-host") + if err != nil { + t.Fatal(err) + } + if len(store.Hosts) != 0 { + t.Fatalf("Expected hosts length to be zero. Got %d", len(store.Hosts)) + } + store.RemoveErr = fmt.Errorf("error removing") + err = store.Remove("my-host") + if err != store.RemoveErr { + t.Fatal(err) + } +} + +func TestSave(t *testing.T) { + store := FakeStore{} + err := store.Save(&host.Host{Name: "my-host"}) + if err != nil { + t.Fatal(err) + } + expectedHosts := []*host.Host{{Name: "my-host"}} + if !reflect.DeepEqual(store.Hosts, expectedHosts) { + t.Fatalf("Expected hosts to be %v. Got %v.", expectedHosts, store.Hosts) + } + store.SaveErr = fmt.Errorf("error saving") + err = store.Save(&host.Host{Name: "new-host"}) + if err != store.SaveErr { + t.Fatal(err) + } + if !reflect.DeepEqual(store.Hosts, expectedHosts) { + t.Fatalf("Expected hosts to be %v. Got %v.", expectedHosts, store.Hosts) + } +} diff --git a/libmachine/persist/store.go b/libmachine/persist/store.go new file mode 100644 index 0000000000..1d9d489bfd --- /dev/null +++ b/libmachine/persist/store.go @@ -0,0 +1,47 @@ +package persist + +import ( + "github.com/docker/machine/libmachine/host" +) + +type Store interface { + // Exists returns whether a machine exists or not + Exists(name string) (bool, error) + + // List returns a list of all hosts in the store + List() ([]string, error) + + // Load loads a host by name + Load(name string) (*host.Host, error) + + // Remove removes a machine from the store + Remove(name string) error + + // Save persists a machine in the store + Save(host *host.Host) error +} + +func LoadHosts(s Store, hostNames []string) ([]*host.Host, map[string]error) { + loadedHosts := []*host.Host{} + errors := map[string]error{} + + for _, hostName := range hostNames { + h, err := s.Load(hostName) + if err != nil { + errors[hostName] = err + } else { + loadedHosts = append(loadedHosts, h) + } + } + + return loadedHosts, errors +} + +func LoadAllHosts(s Store) ([]*host.Host, map[string]error, error) { + hostNames, err := s.List() + if err != nil { + return nil, nil, err + } + loadedHosts, hostInError := LoadHosts(s, hostNames) + return loadedHosts, hostInError, nil +} diff --git a/libmachine/provider/provider.go b/libmachine/provider/provider.go new file mode 100644 index 0000000000..294c283c6f --- /dev/null +++ b/libmachine/provider/provider.go @@ -0,0 +1,13 @@ +package provider + +import "github.com/docker/machine/libmachine/host" + +type Provider interface { + // IsValid checks whether or not the Provider can successfully create + // machines. If the check does not pass, the provider is no good. + IsValid() bool + + // Create calls out to the driver this provider is associated with, to + // actually create the resource. + Create() (host.Host, error) +} diff --git a/libmachine/provision/arch.go b/libmachine/provision/arch.go new file mode 100644 index 0000000000..86dc90cd74 --- /dev/null +++ b/libmachine/provision/arch.go @@ -0,0 +1,152 @@ +package provision + +import ( + "fmt" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +func init() { + Register("Arch", &RegisteredProvisioner{ + New: NewArchProvisioner, + }) +} + +func NewArchProvisioner(d drivers.Driver) Provisioner { + return &ArchProvisioner{ + NewSystemdProvisioner("arch", d), + } +} + +type ArchProvisioner struct { + SystemdProvisioner +} + +func (provisioner *ArchProvisioner) String() string { + return "arch" +} + +func (provisioner *ArchProvisioner) CompatibleWithHost() bool { + return provisioner.OsReleaseInfo.ID == provisioner.OsReleaseID || provisioner.OsReleaseInfo.IDLike == provisioner.OsReleaseID +} + +func (provisioner *ArchProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + updateMetadata := true + + switch action { + case pkgaction.Install, pkgaction.Upgrade: + packageAction = "S" + case pkgaction.Remove: + packageAction = "R" + updateMetadata = false + } + + switch name { + case "docker-engine": + name = "docker" + case "docker": + name = "docker" + } + + pacmanOpts := "-" + packageAction + if updateMetadata { + pacmanOpts = pacmanOpts + "y" + } + + pacmanOpts = pacmanOpts + " --noconfirm --noprogressbar" + + command := fmt.Sprintf("sudo -E pacman %s %s", pacmanOpts, name) + + log.Debugf("package: action=%s name=%s", action.String(), name) + + if _, err := provisioner.SSHCommand(command); err != nil { + return err + } + + return nil +} + +func (provisioner *ArchProvisioner) dockerDaemonResponding() bool { + log.Debug("checking docker daemon") + + if out, err := provisioner.SSHCommand("sudo docker version"); err != nil { + log.Warnf("Error getting SSH command to check if the daemon is up: %s", err) + log.Debugf("'sudo docker version' output:\n%s", out) + return false + } + + // The daemon is up if the command worked. Carry on. + return true +} + +func (provisioner *ArchProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + storageDriver, err := decideStorageDriver(provisioner, "overlay2", engineOptions.StorageDriver) + if err != nil { + return err + } + provisioner.EngineOptions.StorageDriver = storageDriver + + // HACK: since Arch does not come with sudo by default we install + log.Debug("Installing sudo") + if _, err := provisioner.SSHCommand("if ! type sudo; then pacman -Sy --noconfirm --noprogressbar sudo; fi"); err != nil { + return err + } + + log.Debug("Setting hostname") + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + log.Debug("Installing base packages") + for _, pkg := range provisioner.Packages { + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + log.Debug("Installing docker") + if err := provisioner.Package("docker", pkgaction.Install); err != nil { + return err + } + + log.Debug("Starting systemd docker service") + if err := provisioner.Service("docker", serviceaction.Start); err != nil { + return err + } + + log.Debug("Waiting for docker daemon") + if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + log.Debug("Configuring auth") + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + log.Debug("Configuring swarm") + if err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions); err != nil { + return err + } + + // enable in systemd + log.Debug("Enabling docker in systemd") + err = provisioner.Service("docker", serviceaction.Enable) + return err +} diff --git a/libmachine/provision/arch_test.go b/libmachine/provision/arch_test.go new file mode 100644 index 0000000000..6533ed39a2 --- /dev/null +++ b/libmachine/provision/arch_test.go @@ -0,0 +1,20 @@ +package provision + +import ( + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/provisiontest" + "github.com/docker/machine/libmachine/swarm" +) + +func TestArchDefaultStorageDriver(t *testing.T) { + p := NewArchProvisioner(&fakedriver.Driver{}).(*ArchProvisioner) + p.SSHCommander = provisiontest.NewFakeSSHCommander(provisiontest.FakeSSHCommanderOptions{}) + p.Provision(swarm.Options{}, auth.Options{}, engine.Options{}) + if p.EngineOptions.StorageDriver != "overlay2" { + t.Fatal("Default storage driver should be overlay2") + } +} diff --git a/libmachine/provision/boot2docker.go b/libmachine/provision/boot2docker.go new file mode 100644 index 0000000000..ebe3b523ad --- /dev/null +++ b/libmachine/provision/boot2docker.go @@ -0,0 +1,268 @@ +package provision + +import ( + "bytes" + "encoding/json" + "fmt" + "net" + "path" + "text/template" + "time" + + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/swarm" +) + +func init() { + Register("boot2docker", &RegisteredProvisioner{ + New: NewBoot2DockerProvisioner, + }) +} + +func NewBoot2DockerProvisioner(d drivers.Driver) Provisioner { + return &Boot2DockerProvisioner{ + Driver: d, + } +} + +type Boot2DockerProvisioner struct { + OsReleaseInfo *OsRelease + Driver drivers.Driver + AuthOptions auth.Options + EngineOptions engine.Options + SwarmOptions swarm.Options +} + +func (provisioner *Boot2DockerProvisioner) String() string { + return "boot2docker" +} + +func (provisioner *Boot2DockerProvisioner) Service(name string, action serviceaction.ServiceAction) error { + _, err := provisioner.SSHCommand(fmt.Sprintf("sudo /etc/init.d/%s %s", name, action.String())) + return err +} + +func (provisioner *Boot2DockerProvisioner) upgradeIso() error { + // TODO: Ideally, we should not read from mcndirs directory at all. + // The driver should be able to communicate how and where to place the + // relevant files. + b2dutils := mcnutils.NewB2dUtils(mcndirs.GetBaseDir()) + + // Check if the driver has specified a custom b2d url + jsonDriver, err := json.Marshal(provisioner.GetDriver()) + if err != nil { + return err + } + var d struct { + Boot2DockerURL string + } + json.Unmarshal(jsonDriver, &d) + + log.Info("Stopping machine to do the upgrade...") + + if err := provisioner.Driver.Stop(); err != nil { + return err + } + + if err := mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { + return err + } + + machineName := provisioner.GetDriver().GetMachineName() + + log.Infof("Upgrading machine %q...", machineName) + + // Either download the latest version of the b2d url that was explicitly + // specified when creating the VM or copy the (updated) default ISO + if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, machineName); err != nil { + return err + } + + log.Infof("Starting machine back up...") + + if err := provisioner.Driver.Start(); err != nil { + return err + } + + return mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) +} + +func (provisioner *Boot2DockerProvisioner) Package(name string, action pkgaction.PackageAction) error { + if name == "docker" && action == pkgaction.Upgrade { + if err := provisioner.upgradeIso(); err != nil { + return err + } + } + return nil +} + +func (provisioner *Boot2DockerProvisioner) Hostname() (string, error) { + return provisioner.SSHCommand("hostname") +} + +func (provisioner *Boot2DockerProvisioner) SetHostname(hostname string) error { + if _, err := provisioner.SSHCommand(fmt.Sprintf( + "sudo /usr/bin/sethostname %s && echo %q | sudo tee /var/lib/boot2docker/etc/hostname", + hostname, + hostname, + )); err != nil { + return err + } + + return nil +} + +func (provisioner *Boot2DockerProvisioner) GetDockerOptionsDir() string { + return "/var/lib/boot2docker" +} + +func (provisioner *Boot2DockerProvisioner) GetAuthOptions() auth.Options { + return provisioner.AuthOptions +} + +func (provisioner *Boot2DockerProvisioner) GetSwarmOptions() swarm.Options { + return provisioner.SwarmOptions +} + +func (provisioner *Boot2DockerProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { + var ( + engineCfg bytes.Buffer + ) + + driverNameLabel := fmt.Sprintf("provider=%s", provisioner.Driver.DriverName()) + provisioner.EngineOptions.Labels = append(provisioner.EngineOptions.Labels, driverNameLabel) + + engineConfigTmpl := ` +EXTRA_ARGS=' +{{ range .EngineOptions.Labels }}--label {{.}} +{{ end }}{{ range .EngineOptions.InsecureRegistry }}--insecure-registry {{.}} +{{ end }}{{ range .EngineOptions.RegistryMirror }}--registry-mirror {{.}} +{{ end }}{{ range .EngineOptions.ArbitraryFlags }}--{{.}} +{{ end }} +' +CACERT={{.AuthOptions.CaCertRemotePath}} +DOCKER_HOST='-H tcp://0.0.0.0:{{.DockerPort}}' +DOCKER_STORAGE={{.EngineOptions.StorageDriver}} +DOCKER_TLS=auto +SERVERKEY={{.AuthOptions.ServerKeyRemotePath}} +SERVERCERT={{.AuthOptions.ServerCertRemotePath}} + +{{range .EngineOptions.Env}}export \"{{ printf "%q" . }}\" +{{end}} +` + t, err := template.New("engineConfig").Parse(engineConfigTmpl) + if err != nil { + return nil, err + } + + engineConfigContext := EngineConfigContext{ + DockerPort: dockerPort, + AuthOptions: provisioner.AuthOptions, + EngineOptions: provisioner.EngineOptions, + } + + t.Execute(&engineCfg, engineConfigContext) + + daemonOptsDir := path.Join(provisioner.GetDockerOptionsDir(), "profile") + return &DockerOptions{ + EngineOptions: engineCfg.String(), + EngineOptionsPath: daemonOptsDir, + }, nil +} + +func (provisioner *Boot2DockerProvisioner) CompatibleWithHost() bool { + return provisioner.OsReleaseInfo.ID == "boot2docker" +} + +func (provisioner *Boot2DockerProvisioner) SetOsReleaseInfo(info *OsRelease) { + provisioner.OsReleaseInfo = info +} + +func (provisioner *Boot2DockerProvisioner) GetOsReleaseInfo() (*OsRelease, error) { + return provisioner.OsReleaseInfo, nil +} + +func (provisioner *Boot2DockerProvisioner) AttemptIPContact(dockerPort int) { + ip, err := provisioner.Driver.GetIP() + if err != nil { + log.Warnf("Could not get IP address for created machine: %s", err) + return + } + + if conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, dockerPort), 5*time.Second); err != nil { + log.Warnf(` +This machine has been allocated an IP address, but Docker Machine could not +reach it successfully. + +SSH for the machine should still work, but connecting to exposed ports, such as +the Docker daemon port (usually :%d), may not work properly. + +You may need to add the route manually, or use another related workaround. + +This could be due to a VPN, proxy, or host file configuration issue. + +You also might want to clear any VirtualBox host only interfaces you are not using.`, engine.DefaultPort) + } else { + conn.Close() + } +} + +func (provisioner *Boot2DockerProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + var ( + err error + ) + + defer func() { + if err == nil { + provisioner.AttemptIPContact(engine.DefaultPort) + } + }() + + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + if provisioner.EngineOptions.StorageDriver == "" { + provisioner.EngineOptions.StorageDriver = "overlay2" + } + + if err = provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + // b2d hosts need to wait for the daemon to be up + // before continuing with provisioning + if err = WaitForDocker(provisioner, engine.DefaultPort); err != nil { + return err + } + + if err = makeDockerOptionsDir(provisioner); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + if err = ConfigureAuth(provisioner); err != nil { + return err + } + + err = configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions) + return err +} + +func (provisioner *Boot2DockerProvisioner) SSHCommand(args string) (string, error) { + return drivers.RunSSHCommandFromDriver(provisioner.Driver, args) +} + +func (provisioner *Boot2DockerProvisioner) GetDriver() drivers.Driver { + return provisioner.Driver +} diff --git a/libmachine/provision/centos.go b/libmachine/provision/centos.go new file mode 100644 index 0000000000..11c01a3953 --- /dev/null +++ b/libmachine/provision/centos.go @@ -0,0 +1,25 @@ +package provision + +import ( + "github.com/docker/machine/libmachine/drivers" +) + +func init() { + Register("Centos", &RegisteredProvisioner{ + New: NewCentosProvisioner, + }) +} + +func NewCentosProvisioner(d drivers.Driver) Provisioner { + return &CentosProvisioner{ + NewRedHatProvisioner("centos", d), + } +} + +type CentosProvisioner struct { + *RedHatProvisioner +} + +func (provisioner *CentosProvisioner) String() string { + return "centos" +} diff --git a/libmachine/provision/configure_swarm.go b/libmachine/provision/configure_swarm.go new file mode 100644 index 0000000000..5d7545caec --- /dev/null +++ b/libmachine/provision/configure_swarm.go @@ -0,0 +1,149 @@ +package provision + +import ( + "fmt" + "net/url" + "strconv" + "strings" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcndockerclient" + "github.com/docker/machine/libmachine/swarm" + "github.com/samalba/dockerclient" +) + +func configureSwarm(p Provisioner, swarmOptions swarm.Options, authOptions auth.Options) error { + if !swarmOptions.IsSwarm { + return nil + } + + log.Info("Configuring swarm...") + + ip, err := p.GetDriver().GetIP() + if err != nil { + return err + } + + u, err := url.Parse(swarmOptions.Host) + if err != nil { + return err + } + + enginePort := engine.DefaultPort + engineURL, err := p.GetDriver().GetURL() + if err != nil { + return err + } + + parts := strings.Split(engineURL, ":") + if len(parts) == 3 { + dPort, err := strconv.Atoi(parts[2]) + if err != nil { + return err + } + enginePort = dPort + } + + parts = strings.Split(u.Host, ":") + port := parts[1] + + dockerDir := p.GetDockerOptionsDir() + dockerHost := &mcndockerclient.RemoteDocker{ + HostURL: fmt.Sprintf("tcp://%s:%d", ip, enginePort), + AuthOption: &authOptions, + } + advertiseInfo := fmt.Sprintf("%s:%d", ip, enginePort) + + if swarmOptions.Master { + advertiseMasterInfo := fmt.Sprintf("%s:%s", ip, "3376") + cmd := fmt.Sprintf("manage --tlsverify --tlscacert=%s --tlscert=%s --tlskey=%s -H %s --strategy %s --advertise %s", + authOptions.CaCertRemotePath, + authOptions.ServerCertRemotePath, + authOptions.ServerKeyRemotePath, + swarmOptions.Host, + swarmOptions.Strategy, + advertiseMasterInfo, + ) + if swarmOptions.IsExperimental { + cmd = "--experimental " + cmd + } + + cmdMaster := strings.Fields(cmd) + for _, option := range swarmOptions.ArbitraryFlags { + cmdMaster = append(cmdMaster, "--"+option) + } + + //Discovery must be at end of command + cmdMaster = append(cmdMaster, swarmOptions.Discovery) + + hostBind := fmt.Sprintf("%s:%s", dockerDir, dockerDir) + masterHostConfig := dockerclient.HostConfig{ + RestartPolicy: dockerclient.RestartPolicy{ + Name: "always", + MaximumRetryCount: 0, + }, + Binds: []string{hostBind}, + PortBindings: map[string][]dockerclient.PortBinding{ + fmt.Sprintf("%s/tcp", port): { + { + HostIp: "0.0.0.0", + HostPort: port, + }, + }, + }, + } + + swarmMasterConfig := &dockerclient.ContainerConfig{ + Image: swarmOptions.Image, + Env: swarmOptions.Env, + ExposedPorts: map[string]struct{}{ + "2375/tcp": {}, + fmt.Sprintf("%s/tcp", port): {}, + }, + Cmd: cmdMaster, + HostConfig: masterHostConfig, + } + + err = mcndockerclient.CreateContainer(dockerHost, swarmMasterConfig, "swarm-agent-master") + if err != nil { + return err + } + } + + if swarmOptions.Agent { + workerHostConfig := dockerclient.HostConfig{ + RestartPolicy: dockerclient.RestartPolicy{ + Name: "always", + MaximumRetryCount: 0, + }, + } + + cmdWorker := []string{ + "join", + "--advertise", + advertiseInfo, + } + for _, option := range swarmOptions.ArbitraryJoinFlags { + cmdWorker = append(cmdWorker, "--"+option) + } + cmdWorker = append(cmdWorker, swarmOptions.Discovery) + + swarmWorkerConfig := &dockerclient.ContainerConfig{ + Image: swarmOptions.Image, + Env: swarmOptions.Env, + Cmd: cmdWorker, + HostConfig: workerHostConfig, + } + if swarmOptions.IsExperimental { + swarmWorkerConfig.Cmd = append([]string{"--experimental"}, swarmWorkerConfig.Cmd...) + } + + err = mcndockerclient.CreateContainer(dockerHost, swarmWorkerConfig, "swarm-agent") + if err != nil { + return err + } + } + return nil +} diff --git a/libmachine/provision/coreos.go b/libmachine/provision/coreos.go new file mode 100644 index 0000000000..bbb798b70c --- /dev/null +++ b/libmachine/provision/coreos.go @@ -0,0 +1,132 @@ +package provision + +import ( + "bytes" + "fmt" + "text/template" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/swarm" + "github.com/docker/machine/libmachine/versioncmp" +) + +const ( + hostTmpl = `sudo tee /var/tmp/hostname.yml << EOF +#cloud-config + +hostname: %s +EOF +` +) + +func init() { + Register("CoreOS", &RegisteredProvisioner{ + New: NewCoreOSProvisioner, + }) +} + +func NewCoreOSProvisioner(d drivers.Driver) Provisioner { + return &CoreOSProvisioner{ + NewSystemdProvisioner("coreos", d), + } +} + +type CoreOSProvisioner struct { + SystemdProvisioner +} + +func (provisioner *CoreOSProvisioner) String() string { + return "coreOS" +} + +func (provisioner *CoreOSProvisioner) SetHostname(hostname string) error { + log.Debugf("SetHostname: %s", hostname) + + if _, err := provisioner.SSHCommand(fmt.Sprintf(hostTmpl, hostname)); err != nil { + return err + } + + if _, err := provisioner.SSHCommand("sudo systemctl start system-cloudinit@var-tmp-hostname.yml.service"); err != nil { + return err + } + + return nil +} + +func (provisioner *CoreOSProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { + var ( + engineCfg bytes.Buffer + ) + + driverNameLabel := fmt.Sprintf("provider=%s", provisioner.Driver.DriverName()) + provisioner.EngineOptions.Labels = append(provisioner.EngineOptions.Labels, driverNameLabel) + + dockerVersion, err := DockerClientVersion(provisioner) + if err != nil { + return nil, err + } + + arg := "daemon" + if versioncmp.GreaterThanOrEqualTo(dockerVersion, "1.12.0") { + arg = "" + } + + engineConfigTmpl := `[Service] +Environment=TMPDIR=/var/tmp +ExecStart= +ExecStart=/usr/lib/coreos/dockerd ` + arg + ` --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:{{.DockerPort}} --tlsverify --tlscacert {{.AuthOptions.CaCertRemotePath}} --tlscert {{.AuthOptions.ServerCertRemotePath}} --tlskey {{.AuthOptions.ServerKeyRemotePath}}{{ range .EngineOptions.Labels }} --label {{.}}{{ end }}{{ range .EngineOptions.InsecureRegistry }} --insecure-registry {{.}}{{ end }}{{ range .EngineOptions.RegistryMirror }} --registry-mirror {{.}}{{ end }}{{ range .EngineOptions.ArbitraryFlags }} --{{.}}{{ end }} \$DOCKER_OPTS \$DOCKER_OPT_BIP \$DOCKER_OPT_MTU \$DOCKER_OPT_IPMASQ +Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} +` + + t, err := template.New("engineConfig").Parse(engineConfigTmpl) + if err != nil { + return nil, err + } + + engineConfigContext := EngineConfigContext{ + DockerPort: dockerPort, + AuthOptions: provisioner.AuthOptions, + EngineOptions: provisioner.EngineOptions, + } + + t.Execute(&engineCfg, engineConfigContext) + + return &DockerOptions{ + EngineOptions: engineCfg.String(), + EngineOptionsPath: provisioner.DaemonOptionsFile, + }, nil +} + +func (provisioner *CoreOSProvisioner) Package(name string, action pkgaction.PackageAction) error { + return nil +} + +func (provisioner *CoreOSProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + if err := makeDockerOptionsDir(provisioner); err != nil { + return err + } + + log.Debugf("Preparing certificates") + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + log.Debugf("Setting up certificates") + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + log.Debug("Configuring swarm") + err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions) + return err +} diff --git a/libmachine/provision/debian.go b/libmachine/provision/debian.go new file mode 100644 index 0000000000..ce8bcc5e17 --- /dev/null +++ b/libmachine/provision/debian.go @@ -0,0 +1,139 @@ +package provision + +import ( + "fmt" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +func init() { + Register("Debian", &RegisteredProvisioner{ + New: NewDebianProvisioner, + }) +} + +func NewDebianProvisioner(d drivers.Driver) Provisioner { + return &DebianProvisioner{ + NewSystemdProvisioner("debian", d), + } +} + +type DebianProvisioner struct { + SystemdProvisioner +} + +func (provisioner *DebianProvisioner) String() string { + return "debian" +} + +func (provisioner *DebianProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + updateMetadata := true + + switch action { + case pkgaction.Install, pkgaction.Upgrade: + packageAction = "install" + case pkgaction.Remove: + packageAction = "remove" + updateMetadata = false + case pkgaction.Purge: + packageAction = "purge" + updateMetadata = false + } + + switch name { + case "docker": + name = "docker-engine" + } + + if updateMetadata { + if err := waitForLockAptGetUpdate(provisioner); err != nil { + return err + } + } + + command := fmt.Sprintf("DEBIAN_FRONTEND=noninteractive sudo -E apt-get %s -y %s", packageAction, name) + + log.Debugf("package: action=%s name=%s", action.String(), name) + + return waitForLock(provisioner, command) +} + +func (provisioner *DebianProvisioner) dockerDaemonResponding() bool { + log.Debug("checking docker daemon") + + if out, err := provisioner.SSHCommand("sudo docker version"); err != nil { + log.Warnf("Error getting SSH command to check if the daemon is up: %s", err) + log.Debugf("'sudo docker version' output:\n%s", out) + return false + } + + // The daemon is up if the command worked. Carry on. + return true +} + +func (provisioner *DebianProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + storageDriver, err := decideStorageDriver(provisioner, "overlay2", engineOptions.StorageDriver) + if err != nil { + return err + } + provisioner.EngineOptions.StorageDriver = storageDriver + + // HACK: since debian does not come with sudo by default we install + log.Debug("installing sudo") + if _, err := provisioner.SSHCommand("if ! type sudo; then apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y sudo; fi"); err != nil { + return err + } + + log.Debug("setting hostname") + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + log.Debug("installing base packages") + for _, pkg := range provisioner.Packages { + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + log.Debug("installing docker") + if err := installDockerGeneric(provisioner, engineOptions.InstallURL); err != nil { + return err + } + + log.Debug("waiting for docker daemon") + if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + log.Debug("configuring auth") + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + log.Debug("configuring swarm") + if err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions); err != nil { + return err + } + + // enable in systemd + log.Debug("enabling docker in systemd") + err = provisioner.Service("docker", serviceaction.Enable) + return err +} diff --git a/libmachine/provision/debian_test.go b/libmachine/provision/debian_test.go new file mode 100644 index 0000000000..318061b1de --- /dev/null +++ b/libmachine/provision/debian_test.go @@ -0,0 +1,20 @@ +package provision + +import ( + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/provisiontest" + "github.com/docker/machine/libmachine/swarm" +) + +func TestDebianDefaultStorageDriver(t *testing.T) { + p := NewDebianProvisioner(&fakedriver.Driver{}).(*DebianProvisioner) + p.SSHCommander = provisiontest.NewFakeSSHCommander(provisiontest.FakeSSHCommanderOptions{}) + p.Provision(swarm.Options{}, auth.Options{}, engine.Options{}) + if p.EngineOptions.StorageDriver != "overlay2" { + t.Fatal("Default storage driver should be overlay2") + } +} diff --git a/libmachine/provision/engine_config_context.go b/libmachine/provision/engine_config_context.go new file mode 100644 index 0000000000..7a7e9a8082 --- /dev/null +++ b/libmachine/provision/engine_config_context.go @@ -0,0 +1,13 @@ +package provision + +import ( + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" +) + +type EngineConfigContext struct { + DockerPort int + AuthOptions auth.Options + EngineOptions engine.Options + DockerOptionsDir string +} diff --git a/libmachine/provision/errors.go b/libmachine/provision/errors.go new file mode 100644 index 0000000000..46348b90eb --- /dev/null +++ b/libmachine/provision/errors.go @@ -0,0 +1,24 @@ +package provision + +import ( + "errors" + "fmt" +) + +var ( + ErrDetectionFailed = errors.New("OS type not recognized") +) + +type ErrDaemonAvailable struct { + wrappedErr error +} + +func (e ErrDaemonAvailable) Error() string { + return fmt.Sprintf("Unable to verify the Docker daemon is listening: %s", e.wrappedErr) +} + +func NewErrDaemonAvailable(err error) ErrDaemonAvailable { + return ErrDaemonAvailable{ + wrappedErr: err, + } +} diff --git a/libmachine/provision/fake_provisioner.go b/libmachine/provision/fake_provisioner.go new file mode 100644 index 0000000000..7d4caaed9a --- /dev/null +++ b/libmachine/provision/fake_provisioner.go @@ -0,0 +1,110 @@ +package provision + +import ( + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +type FakeDetector struct { + Provisioner +} + +func (fd *FakeDetector) DetectProvisioner(d drivers.Driver) (Provisioner, error) { + return fd.Provisioner, nil +} + +type FakeProvisioner struct{} + +func NewFakeProvisioner(d drivers.Driver) Provisioner { + return &FakeProvisioner{} +} + +func (fp *FakeProvisioner) SSHCommand(args string) (string, error) { + return "", nil +} + +func (fp *FakeProvisioner) String() string { + return "fakeprovisioner" +} + +func (fp *FakeProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { + return nil, nil +} + +func (fp *FakeProvisioner) GetDockerOptionsDir() string { + return "" +} + +func (fp *FakeProvisioner) GetAuthOptions() auth.Options { + return auth.Options{} +} + +func (fp *FakeProvisioner) GetSwarmOptions() swarm.Options { + return swarm.Options{} +} + +func (fp *FakeProvisioner) Package(name string, action pkgaction.PackageAction) error { + return nil +} + +func (fp *FakeProvisioner) Hostname() (string, error) { + return "", nil +} + +func (fp *FakeProvisioner) SetHostname(hostname string) error { + return nil +} + +func (fp *FakeProvisioner) CompatibleWithHost() bool { + return true +} + +func (fp *FakeProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + return nil +} + +func (fp *FakeProvisioner) Service(name string, action serviceaction.ServiceAction) error { + return nil +} + +func (fp *FakeProvisioner) GetDriver() drivers.Driver { + return nil +} + +func (fp *FakeProvisioner) SetOsReleaseInfo(info *OsRelease) {} + +func (fp *FakeProvisioner) GetOsReleaseInfo() (*OsRelease, error) { + return nil, nil +} + +type NetstatProvisioner struct { + *FakeProvisioner +} + +func (p *NetstatProvisioner) SSHCommand(args string) (string, error) { + return `Active Internet connections (servers and established) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN +tcp 0 72 192.168.25.141:ssh 192.168.25.1:63235 ESTABLISHED +tcp 0 0 :::2376 :::* LISTEN +tcp 0 0 :::ssh :::* LISTEN +Active UNIX domain sockets (servers and established) +Proto RefCnt Flags Type State I-Node Path +unix 2 [ ACC ] STREAM LISTENING 17990 /var/run/acpid.socket +unix 2 [ ACC ] SEQPACKET LISTENING 14233 /run/udev/control +unix 2 [ ACC ] STREAM LISTENING 19365 /var/run/docker.sock +unix 3 [ ] STREAM CONNECTED 19774 +unix 3 [ ] STREAM CONNECTED 19775 +unix 3 [ ] DGRAM 14243 +unix 3 [ ] DGRAM 14242`, nil +} + +func NewNetstatProvisioner() Provisioner { + return &NetstatProvisioner{ + &FakeProvisioner{}, + } +} diff --git a/libmachine/provision/fedora.go b/libmachine/provision/fedora.go new file mode 100644 index 0000000000..71989c02a2 --- /dev/null +++ b/libmachine/provision/fedora.go @@ -0,0 +1,25 @@ +package provision + +import ( + "github.com/docker/machine/libmachine/drivers" +) + +func init() { + Register("Fedora", &RegisteredProvisioner{ + New: NewFedoraProvisioner, + }) +} + +func NewFedoraProvisioner(d drivers.Driver) Provisioner { + return &FedoraProvisioner{ + NewRedHatProvisioner("fedora", d), + } +} + +type FedoraProvisioner struct { + *RedHatProvisioner +} + +func (provisioner *FedoraProvisioner) String() string { + return "fedora" +} diff --git a/libmachine/provision/generic.go b/libmachine/provision/generic.go new file mode 100644 index 0000000000..24ad1b5599 --- /dev/null +++ b/libmachine/provision/generic.go @@ -0,0 +1,138 @@ +package provision + +import ( + "bytes" + "fmt" + "text/template" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/swarm" +) + +type GenericProvisioner struct { + SSHCommander + OsReleaseID string + DockerOptionsDir string + DaemonOptionsFile string + Packages []string + OsReleaseInfo *OsRelease + Driver drivers.Driver + AuthOptions auth.Options + EngineOptions engine.Options + SwarmOptions swarm.Options +} + +type GenericSSHCommander struct { + Driver drivers.Driver +} + +func (sshCmder GenericSSHCommander) SSHCommand(args string) (string, error) { + return drivers.RunSSHCommandFromDriver(sshCmder.Driver, args) +} + +func (provisioner *GenericProvisioner) Hostname() (string, error) { + return provisioner.SSHCommand("hostname") +} + +func (provisioner *GenericProvisioner) SetHostname(hostname string) error { + if _, err := provisioner.SSHCommand(fmt.Sprintf( + "sudo hostname %s && echo %q | sudo tee /etc/hostname", + hostname, + hostname, + )); err != nil { + return err + } + + // ubuntu/debian use 127.0.1.1 for non "localhost" loopback hostnames: https://www.debian.org/doc/manuals/debian-reference/ch05.en.html#_the_hostname_resolution + if _, err := provisioner.SSHCommand(fmt.Sprintf(` + if ! grep -xq '.*\s%s' /etc/hosts; then + if grep -xq '127.0.1.1\s.*' /etc/hosts; then + sudo sed -i 's/^127.0.1.1\s.*/127.0.1.1 %s/g' /etc/hosts; + else + echo '127.0.1.1 %s' | sudo tee -a /etc/hosts; + fi + fi`, + hostname, + hostname, + hostname, + )); err != nil { + return err + } + + return nil +} + +func (provisioner *GenericProvisioner) GetDockerOptionsDir() string { + return provisioner.DockerOptionsDir +} + +func (provisioner *GenericProvisioner) CompatibleWithHost() bool { + return provisioner.OsReleaseInfo.ID == provisioner.OsReleaseID +} + +func (provisioner *GenericProvisioner) GetAuthOptions() auth.Options { + return provisioner.AuthOptions +} + +func (provisioner *GenericProvisioner) GetSwarmOptions() swarm.Options { + return provisioner.SwarmOptions +} + +func (provisioner *GenericProvisioner) SetOsReleaseInfo(info *OsRelease) { + provisioner.OsReleaseInfo = info +} + +func (provisioner *GenericProvisioner) GetOsReleaseInfo() (*OsRelease, error) { + return provisioner.OsReleaseInfo, nil +} + +func (provisioner *GenericProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { + var ( + engineCfg bytes.Buffer + ) + + driverNameLabel := fmt.Sprintf("provider=%s", provisioner.Driver.DriverName()) + provisioner.EngineOptions.Labels = append(provisioner.EngineOptions.Labels, driverNameLabel) + + engineConfigTmpl := ` +DOCKER_OPTS=' +-H tcp://0.0.0.0:{{.DockerPort}} +-H unix:///var/run/docker.sock +--storage-driver {{.EngineOptions.StorageDriver}} +--tlsverify +--tlscacert {{.AuthOptions.CaCertRemotePath}} +--tlscert {{.AuthOptions.ServerCertRemotePath}} +--tlskey {{.AuthOptions.ServerKeyRemotePath}} +{{ range .EngineOptions.Labels }}--label {{.}} +{{ end }}{{ range .EngineOptions.InsecureRegistry }}--insecure-registry {{.}} +{{ end }}{{ range .EngineOptions.RegistryMirror }}--registry-mirror {{.}} +{{ end }}{{ range .EngineOptions.ArbitraryFlags }}--{{.}} +{{ end }} +' +{{range .EngineOptions.Env}}export \"{{ printf "%q" . }}\" +{{end}} +` + t, err := template.New("engineConfig").Parse(engineConfigTmpl) + if err != nil { + return nil, err + } + + engineConfigContext := EngineConfigContext{ + DockerPort: dockerPort, + AuthOptions: provisioner.AuthOptions, + EngineOptions: provisioner.EngineOptions, + } + + t.Execute(&engineCfg, engineConfigContext) + + return &DockerOptions{ + EngineOptions: engineCfg.String(), + EngineOptionsPath: provisioner.DaemonOptionsFile, + }, nil +} + +func (provisioner *GenericProvisioner) GetDriver() drivers.Driver { + return provisioner.Driver +} diff --git a/libmachine/provision/oraclelinux.go b/libmachine/provision/oraclelinux.go new file mode 100644 index 0000000000..56d263741d --- /dev/null +++ b/libmachine/provision/oraclelinux.go @@ -0,0 +1,25 @@ +package provision + +import ( + "github.com/docker/machine/libmachine/drivers" +) + +func init() { + Register("OracleLinux", &RegisteredProvisioner{ + New: NewOracleLinuxProvisioner, + }) +} + +func NewOracleLinuxProvisioner(d drivers.Driver) Provisioner { + return &OracleLinuxProvisioner{ + NewRedHatProvisioner("ol", d), + } +} + +type OracleLinuxProvisioner struct { + *RedHatProvisioner +} + +func (provisioner *OracleLinuxProvisioner) String() string { + return "ol" +} diff --git a/libmachine/provision/os_release.go b/libmachine/provision/os_release.go new file mode 100644 index 0000000000..4c3bdf2a13 --- /dev/null +++ b/libmachine/provision/os_release.go @@ -0,0 +1,91 @@ +package provision + +import ( + "bufio" + "bytes" + "fmt" + "reflect" + "strings" + + "github.com/docker/machine/libmachine/log" +) + +// The /etc/os-release file contains operating system identification data +// See http://www.freedesktop.org/software/systemd/man/os-release.html for more details + +// OsRelease reflects values in /etc/os-release +// Values in this struct must always be string +// or the reflection will not work properly. +type OsRelease struct { + AnsiColor string `osr:"ANSI_COLOR"` + Name string `osr:"NAME"` + Version string `osr:"VERSION"` + Variant string `osr:"VARIANT"` + VariantID string `osr:"VARIANT_ID"` + ID string `osr:"ID"` + IDLike string `osr:"ID_LIKE"` + PrettyName string `osr:"PRETTY_NAME"` + VersionID string `osr:"VERSION_ID"` + HomeURL string `osr:"HOME_URL"` + SupportURL string `osr:"SUPPORT_URL"` + BugReportURL string `osr:"BUG_REPORT_URL"` +} + +func stripQuotes(val string) string { + if len(val) > 0 && val[0] == '"' { + return val[1 : len(val)-1] + } + return val +} + +func (osr *OsRelease) setIfPossible(key, val string) error { + v := reflect.ValueOf(osr).Elem() + for i := 0; i < v.NumField(); i++ { + fieldValue := v.Field(i) + fieldType := v.Type().Field(i) + originalName := fieldType.Tag.Get("osr") + if key == originalName && fieldValue.Kind() == reflect.String { + fieldValue.SetString(val) + return nil + } + } + return fmt.Errorf("Couldn't set key %s, no corresponding struct field found", key) +} + +func parseLine(osrLine string) (string, string, error) { + if osrLine == "" { + return "", "", nil + } + + vals := strings.Split(osrLine, "=") + if len(vals) != 2 { + return "", "", fmt.Errorf("Expected %s to split by '=' char into two strings, instead got %d strings", osrLine, len(vals)) + } + key := vals[0] + val := stripQuotes(vals[1]) + return key, val, nil +} + +func (osr *OsRelease) ParseOsRelease(osReleaseContents []byte) error { + r := bytes.NewReader(osReleaseContents) + scanner := bufio.NewScanner(r) + for scanner.Scan() { + key, val, err := parseLine(scanner.Text()) + if err != nil { + log.Warnf("Warning: got an invalid line error parsing /etc/os-release: %s", err) + continue + } + if err := osr.setIfPossible(key, val); err != nil { + log.Debug(err) + } + } + return nil +} + +func NewOsRelease(contents []byte) (*OsRelease, error) { + osr := &OsRelease{} + if err := osr.ParseOsRelease(contents); err != nil { + return nil, err + } + return osr, nil +} diff --git a/libmachine/provision/os_release_test.go b/libmachine/provision/os_release_test.go new file mode 100644 index 0000000000..87ffefd54d --- /dev/null +++ b/libmachine/provision/os_release_test.go @@ -0,0 +1,211 @@ +package provision + +import ( + "reflect" + "testing" +) + +func TestParseOsRelease(t *testing.T) { + // These example osr files stolen shamelessly from + // https://github.com/docker/docker/blob/master/pkg/parsers/operatingsystem/operatingsystem_test.go + // cheers @tiborvass + var ( + ubuntuTrusty = []byte(`NAME="Ubuntu" +VERSION="14.04, Trusty Tahr" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 14.04 LTS" +VERSION_ID="14.04" +HOME_URL="http://www.ubuntu.com/" +SUPPORT_URL="http://help.ubuntu.com/" +BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" +`) + gentoo = []byte(`NAME=Gentoo +ID=gentoo +PRETTY_NAME="Gentoo/Linux" +ANSI_COLOR="1;32" +HOME_URL="http://www.gentoo.org/" +SUPPORT_URL="http://www.gentoo.org/main/en/support.xml" +BUG_REPORT_URL="https://bugs.gentoo.org/" +`) + noPrettyName = []byte(`NAME="Ubuntu" +VERSION="14.04, Trusty Tahr" +ID=ubuntu +ID_LIKE=debian +VERSION_ID="14.04" +HOME_URL="http://www.ubuntu.com/" +SUPPORT_URL="http://help.ubuntu.com/" +BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" +`) + centos = []byte(`NAME="CentOS Linux" +VERSION="7 (Core)" +ID="centos" +ID_LIKE="rhel fedora" +VERSION_ID="7" +PRETTY_NAME="CentOS Linux 7 (Core)" +ANSI_COLOR="0;31" +HOME_URL="https://www.centos.org/" +BUG_REPORT_URL="https://bugs.centos.org/" +`) + fedora = []byte(`NAME=Fedora +VERSION="23 (Twenty Three)" +ID=fedora +VERSION_ID=23 +VARIANT="Server Edition" +VARIANT_ID=server +PRETTY_NAME="Fedora 23 (Twenty Three)" +ANSI_COLOR="0;34" +HOME_URL="https://fedoraproject.org/" +BUG_REPORT_URL="https://bugzilla.redhat.com/" +`) + ) + + osr, err := NewOsRelease(ubuntuTrusty) + if err != nil { + t.Fatalf("Unexpected error parsing os release: %s", err) + } + + expectedOsr := OsRelease{ + AnsiColor: "", + Name: "Ubuntu", + Version: "14.04, Trusty Tahr", + ID: "ubuntu", + IDLike: "debian", + PrettyName: "Ubuntu 14.04 LTS", + VersionID: "14.04", + HomeURL: "http://www.ubuntu.com/", + SupportURL: "http://help.ubuntu.com/", + BugReportURL: "http://bugs.launchpad.net/ubuntu/", + } + + if !reflect.DeepEqual(*osr, expectedOsr) { + t.Fatal("Error with ubuntu osr parsing: structs do not match") + } + + osr, err = NewOsRelease(gentoo) + if err != nil { + t.Fatalf("Unexpected error parsing os release: %s", err) + } + + expectedOsr = OsRelease{ + AnsiColor: "1;32", + Name: "Gentoo", + Version: "", + ID: "gentoo", + IDLike: "", + PrettyName: "Gentoo/Linux", + VersionID: "", + HomeURL: "http://www.gentoo.org/", + SupportURL: "http://www.gentoo.org/main/en/support.xml", + BugReportURL: "https://bugs.gentoo.org/", + } + + if !reflect.DeepEqual(*osr, expectedOsr) { + t.Fatal("Error with gentoo osr parsing: structs do not match") + } + + osr, err = NewOsRelease(noPrettyName) + if err != nil { + t.Fatalf("Unexpected error parsing os release: %s", err) + } + + expectedOsr = OsRelease{ + AnsiColor: "", + Name: "Ubuntu", + Version: "14.04, Trusty Tahr", + ID: "ubuntu", + IDLike: "debian", + PrettyName: "", + VersionID: "14.04", + HomeURL: "http://www.ubuntu.com/", + SupportURL: "http://help.ubuntu.com/", + BugReportURL: "http://bugs.launchpad.net/ubuntu/", + } + + if !reflect.DeepEqual(*osr, expectedOsr) { + t.Fatal("Error with noPrettyName osr parsing: structs do not match") + } + + osr, err = NewOsRelease(centos) + if err != nil { + t.Fatalf("Unexpected error parsing os release: %s", err) + } + + expectedOsr = OsRelease{ + Name: "CentOS Linux", + Version: "7 (Core)", + ID: "centos", + IDLike: "rhel fedora", + PrettyName: "CentOS Linux 7 (Core)", + AnsiColor: "0;31", + VersionID: "7", + HomeURL: "https://www.centos.org/", + BugReportURL: "https://bugs.centos.org/", + } + + if !reflect.DeepEqual(*osr, expectedOsr) { + t.Fatal("Error with centos osr parsing: structs do not match") + } + + osr, err = NewOsRelease(fedora) + if err != nil { + t.Fatalf("Unexpected error parsing os release: %s", err) + } + + expectedOsr = OsRelease{ + Name: "Fedora", + Version: "23 (Twenty Three)", + ID: "fedora", + PrettyName: "Fedora 23 (Twenty Three)", + Variant: "Server Edition", + VariantID: "server", + AnsiColor: "0;34", + VersionID: "23", + HomeURL: "https://fedoraproject.org/", + BugReportURL: "https://bugzilla.redhat.com/", + } + + if !reflect.DeepEqual(*osr, expectedOsr) { + t.Fatal("Error with fedora osr parsing: structs do not match") + } +} + +func TestParseLine(t *testing.T) { + var ( + withQuotes = "ID=\"ubuntu\"" + withoutQuotes = "ID=gentoo" + wtf = "LOTS=OF=EQUALS" + blank = "" + ) + + key, val, err := parseLine(withQuotes) + if key != "ID" { + t.Fatalf("Expected ID, got %s", key) + } + if val != "ubuntu" { + t.Fatalf("Expected ubuntu, got %s", val) + } + if err != nil { + t.Fatalf("Got error on parseLine with quotes: %s", err) + } + key, val, err = parseLine(withoutQuotes) + if key != "ID" { + t.Fatalf("Expected ID, got %s", key) + } + if val != "gentoo" { + t.Fatalf("Expected gentoo, got %s", val) + } + if err != nil { + t.Fatalf("Got error on parseLine without quotes: %s", err) + } + key, val, err = parseLine(wtf) + if err == nil { + t.Fatal("Expected to get an error on parseLine, got nil") + } + key, val, err = parseLine(blank) + if key != "" || val != "" { + t.Fatalf("Expected empty response on parseLine, got key: %s val: %s", key, val) + } else if err != nil { + t.Fatalf("Expected nil err response on parseLine, got %s", err) + } +} diff --git a/libmachine/provision/pkgaction/pkg_action.go b/libmachine/provision/pkgaction/pkg_action.go new file mode 100644 index 0000000000..b7cf7e3279 --- /dev/null +++ b/libmachine/provision/pkgaction/pkg_action.go @@ -0,0 +1,25 @@ +package pkgaction + +type PackageAction int + +const ( + Install PackageAction = iota + Remove + Upgrade + Purge +) + +var packageActions = []string{ + "install", + "remove", + "upgrade", + "purge", +} + +func (s PackageAction) String() string { + if int(s) >= 0 && int(s) < len(packageActions) { + return packageActions[s] + } + + return "" +} diff --git a/libmachine/provision/pkgaction/pkg_action_test.go b/libmachine/provision/pkgaction/pkg_action_test.go new file mode 100644 index 0000000000..3ca8f28411 --- /dev/null +++ b/libmachine/provision/pkgaction/pkg_action_test.go @@ -0,0 +1,9 @@ +package pkgaction + +import "testing" + +func TestActionValue(t *testing.T) { + if Install.String() != "install" { + t.Fatalf("Expected %q but got %q", "install", Install.String()) + } +} diff --git a/libmachine/provision/provisioner.go b/libmachine/provision/provisioner.go new file mode 100644 index 0000000000..81fc1ebedf --- /dev/null +++ b/libmachine/provision/provisioner.go @@ -0,0 +1,132 @@ +package provision + +import ( + "fmt" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +var ( + provisioners = make(map[string]*RegisteredProvisioner) + detector Detector = &StandardDetector{} +) + +const ( + LastReleaseBeforeCEVersioning = "1.13.1" +) + +type SSHCommander interface { + // Short-hand for accessing an SSH command from the driver. + SSHCommand(args string) (string, error) +} + +type Detector interface { + DetectProvisioner(d drivers.Driver) (Provisioner, error) +} + +type StandardDetector struct{} + +func SetDetector(newDetector Detector) { + detector = newDetector +} + +// Provisioner defines distribution specific actions +type Provisioner interface { + fmt.Stringer + SSHCommander + + // Create the files for the daemon to consume configuration settings (return struct of content and path) + GenerateDockerOptions(dockerPort int) (*DockerOptions, error) + + // Get the directory where the settings files for docker are to be found + GetDockerOptionsDir() string + + // Return the auth options used to configure remote connection for the daemon. + GetAuthOptions() auth.Options + + // Get the swarm options associated with this host. + GetSwarmOptions() swarm.Options + + // Run a package action e.g. install + Package(name string, action pkgaction.PackageAction) error + + // Get Hostname + Hostname() (string, error) + + // Set hostname + SetHostname(hostname string) error + + // Figure out if this is the right provisioner to use based on /etc/os-release info + CompatibleWithHost() bool + + // Do the actual provisioning piece: + // 1. Set the hostname on the instance. + // 2. Install Docker if it is not present. + // 3. Configure the daemon to accept connections over TLS. + // 4. Copy the needed certificates to the server and local config dir. + // 5. Configure / activate swarm if applicable. + Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error + + // Perform action on a named service e.g. stop + Service(name string, action serviceaction.ServiceAction) error + + // Get the driver which is contained in the provisioner. + GetDriver() drivers.Driver + + // Set the OS Release info depending on how it's represented + // internally + SetOsReleaseInfo(info *OsRelease) + + // Get the OS Release info for the current provisioner + GetOsReleaseInfo() (*OsRelease, error) +} + +// RegisteredProvisioner creates a new provisioner +type RegisteredProvisioner struct { + New func(d drivers.Driver) Provisioner +} + +func Register(name string, p *RegisteredProvisioner) { + provisioners[name] = p +} + +func DetectProvisioner(d drivers.Driver) (Provisioner, error) { + return detector.DetectProvisioner(d) +} + +func (detector StandardDetector) DetectProvisioner(d drivers.Driver) (Provisioner, error) { + log.Info("Waiting for SSH to be available...") + if err := drivers.WaitForSSH(d); err != nil { + return nil, err + } + + log.Info("Detecting the provisioner...") + + osReleaseOut, err := drivers.RunSSHCommandFromDriver(d, "cat /etc/os-release") + if err != nil { + return nil, fmt.Errorf("Error getting SSH command: %s", err) + } + + osReleaseInfo, err := NewOsRelease([]byte(osReleaseOut)) + if err != nil { + return nil, fmt.Errorf("Error parsing /etc/os-release file: %s", err) + } + + for _, p := range provisioners { + provisioner := p.New(d) + provisioner.SetOsReleaseInfo(osReleaseInfo) + + if provisioner.CompatibleWithHost() { + log.Debugf("found compatible host: %s", osReleaseInfo.ID) + return provisioner, nil + } + } + + return nil, ErrDetectionFailed +} diff --git a/libmachine/provision/provisiontest/sshcommander.go b/libmachine/provision/provisiontest/sshcommander.go new file mode 100644 index 0000000000..3f9f8b71d2 --- /dev/null +++ b/libmachine/provision/provisiontest/sshcommander.go @@ -0,0 +1,39 @@ +//Package provisiontest provides utilities for testing provisioners +package provisiontest + +import "errors" + +//FakeSSHCommanderOptions is intended to create a FakeSSHCommander without actually knowing the underlying sshcommands by passing it to NewSSHCommander +type FakeSSHCommanderOptions struct { + //Result of the ssh command to look up the FilesystemType + FilesystemType string +} + +//FakeSSHCommander is an implementation of provision.SSHCommander to provide predictable responses set by testing code +//Extend it when needed +type FakeSSHCommander struct { + Responses map[string]string +} + +//NewFakeSSHCommander creates a FakeSSHCommander without actually knowing the underlying sshcommands +func NewFakeSSHCommander(options FakeSSHCommanderOptions) *FakeSSHCommander { + if options.FilesystemType == "" { + options.FilesystemType = "ext4" + } + sshCmder := &FakeSSHCommander{ + Responses: map[string]string{ + "stat -f -c %T /var/lib": options.FilesystemType + "\n", + }, + } + + return sshCmder +} + +//SSHCommand is an implementation of provision.SSHCommander.SSHCommand to provide predictable responses set by testing code +func (sshCmder *FakeSSHCommander) SSHCommand(args string) (string, error) { + response, commandRegistered := sshCmder.Responses[args] + if !commandRegistered { + return "", errors.New("Command not registered in FakeSSHCommander") + } + return response, nil +} diff --git a/libmachine/provision/provisiontest/sshcommander_test.go b/libmachine/provision/provisiontest/sshcommander_test.go new file mode 100644 index 0000000000..037a454a08 --- /dev/null +++ b/libmachine/provision/provisiontest/sshcommander_test.go @@ -0,0 +1,28 @@ +package provisiontest + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCreateFakeSSHCommander(t *testing.T) { + sshCmder := NewFakeSSHCommander(FakeSSHCommanderOptions{FilesystemType: "btrfs"}) + output, err := sshCmder.SSHCommand("stat -f -c %T /var/lib") + if err != nil || output != "btrfs\n" { + t.Fatal("FakeSSHCommander should have returned btrfs and no error but returned '", output, "' and error", err) + } +} + +func TestStatSSHCommand(t *testing.T) { + sshCmder := FakeSSHCommander{ + Responses: map[string]string{"sshcommand": "sshcommandresponse"}, + } + + output, err := sshCmder.SSHCommand("sshcommand") + assert.NoError(t, err) + assert.Equal(t, "sshcommandresponse", output) + + output, err = sshCmder.SSHCommand("errorcommand") + assert.Error(t, err) +} diff --git a/libmachine/provision/rancheros.go b/libmachine/provision/rancheros.go new file mode 100644 index 0000000000..a980b2bb79 --- /dev/null +++ b/libmachine/provision/rancheros.go @@ -0,0 +1,250 @@ +package provision + +import ( + "bufio" + "fmt" + "net/http" + "strings" + + "github.com/docker/machine/commands/mcndirs" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/state" + "github.com/docker/machine/libmachine/swarm" +) + +const ( + versionsURL = "http://releases.rancher.com/os/versions.yml" + isoURL = "https://github.com/rancherio/os/releases/download/%s/machine-rancheros.iso" + hostnameTmpl = `sudo mkdir -p /var/lib/rancher/conf/cloud-config.d/ +sudo tee /var/lib/rancher/conf/cloud-config.d/machine-hostname.yml << EOF +#cloud-config + +hostname: %s +EOF +` +) + +func init() { + Register("RancherOS", &RegisteredProvisioner{ + New: NewRancherProvisioner, + }) +} + +func NewRancherProvisioner(d drivers.Driver) Provisioner { + return &RancherProvisioner{ + GenericProvisioner{ + SSHCommander: GenericSSHCommander{Driver: d}, + DockerOptionsDir: "/var/lib/rancher/conf", + DaemonOptionsFile: "/var/lib/rancher/conf/docker", + OsReleaseID: "rancheros", + Driver: d, + }, + } +} + +type RancherProvisioner struct { + GenericProvisioner +} + +func (provisioner *RancherProvisioner) String() string { + return "rancheros" +} + +func (provisioner *RancherProvisioner) Service(name string, action serviceaction.ServiceAction) error { + command := fmt.Sprintf("sudo system-docker %s %s", action.String(), name) + + if _, err := provisioner.SSHCommand(command); err != nil { + return err + } + + return nil +} + +func (provisioner *RancherProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + if name == "docker" && action == pkgaction.Upgrade { + return provisioner.upgrade() + } + + switch action { + case pkgaction.Install: + packageAction = "enabled" + case pkgaction.Remove: + packageAction = "disable" + case pkgaction.Upgrade: + // TODO: support upgrade + packageAction = "upgrade" + } + + command := fmt.Sprintf("sudo rancherctl service %s %s", packageAction, name) + + if _, err := provisioner.SSHCommand(command); err != nil { + return err + } + + return nil +} + +func (provisioner *RancherProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + log.Debugf("Running RancherOS provisioner on %s", provisioner.Driver.GetMachineName()) + + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + if provisioner.EngineOptions.StorageDriver == "" { + provisioner.EngineOptions.StorageDriver = "overlay" + } else if provisioner.EngineOptions.StorageDriver != "overlay" { + return fmt.Errorf("Unsupported storage driver: %s", provisioner.EngineOptions.StorageDriver) + } + + log.Debugf("Setting hostname %s", provisioner.Driver.GetMachineName()) + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + for _, pkg := range provisioner.Packages { + log.Debugf("Installing package %s", pkg) + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + if engineOptions.InstallURL == drivers.DefaultEngineInstallURL { + log.Debugf("Skipping docker engine default: %s", engineOptions.InstallURL) + } else { + log.Debugf("Selecting docker engine: %s", engineOptions.InstallURL) + if err := selectDocker(provisioner, engineOptions.InstallURL); err != nil { + return err + } + } + + log.Debugf("Preparing certificates") + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + log.Debugf("Setting up certificates") + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + log.Debugf("Configuring swarm") + err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions) + return err +} + +func (provisioner *RancherProvisioner) SetHostname(hostname string) error { + // /etc/hosts is bind mounted from Docker, this is hack to that the generic provisioner doesn't try to mv /etc/hosts + if _, err := provisioner.SSHCommand("sed /127.0.1.1/d /etc/hosts > /tmp/hosts && cat /tmp/hosts | sudo tee /etc/hosts"); err != nil { + return err + } + + if err := provisioner.GenericProvisioner.SetHostname(hostname); err != nil { + return err + } + + if _, err := provisioner.SSHCommand(fmt.Sprintf(hostnameTmpl, hostname)); err != nil { + return err + } + + return nil +} + +func (provisioner *RancherProvisioner) upgrade() error { + switch provisioner.Driver.DriverName() { + case "virtualbox": + return provisioner.upgradeIso() + default: + log.Infof("Running upgrade") + if _, err := provisioner.SSHCommand("sudo rancherctl os upgrade -f --no-reboot"); err != nil { + return err + } + + log.Infof("Upgrade succeeded, rebooting") + // ignore errors here because the SSH connection will close + provisioner.SSHCommand("sudo reboot") + + return nil + } +} + +func (provisioner *RancherProvisioner) upgradeIso() error { + // Largely copied from Boot2Docker provisioner, we should find a way to share this code + log.Info("Stopping machine to do the upgrade...") + + if err := provisioner.Driver.Stop(); err != nil { + return err + } + + if err := mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { + return err + } + + machineName := provisioner.GetDriver().GetMachineName() + + log.Infof("Upgrading machine %s...", machineName) + + // TODO: Ideally, we should not read from mcndirs directory at all. + // The driver should be able to communicate how and where to place the + // relevant files. + b2dutils := mcnutils.NewB2dUtils(mcndirs.GetBaseDir()) + + url, err := provisioner.getLatestISOURL() + if err != nil { + return err + } + + if err := b2dutils.DownloadISOFromURL(url); err != nil { + return err + } + + // Copy the latest version of boot2docker ISO to the machine's directory + if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { + return err + } + + log.Infof("Starting machine back up...") + + if err := provisioner.Driver.Start(); err != nil { + return err + } + + return mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) +} + +func (provisioner *RancherProvisioner) getLatestISOURL() (string, error) { + log.Debugf("Reading %s", versionsURL) + resp, err := http.Get(versionsURL) + if err != nil { + return "", err + } + defer resp.Body.Close() + + // Don't want to pull in yaml parser, we'll do this manually + scanner := bufio.NewScanner(resp.Body) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "current: ") { + log.Debugf("Found %s", line) + return fmt.Sprintf(isoURL, strings.Split(line, ":")[2]), err + } + } + + return "", fmt.Errorf("Failed to find current version") +} + +func selectDocker(p Provisioner, baseURL string) error { + // TODO: detect if its a cloud-init, or a ros setting - and use that.. + if output, err := p.SSHCommand(fmt.Sprintf("wget -O- %s | sh -", baseURL)); err != nil { + return fmt.Errorf("error selecting docker: (%s) %s", err, output) + } + + return nil +} diff --git a/libmachine/provision/redhat.go b/libmachine/provision/redhat.go new file mode 100644 index 0000000000..385bfde4f1 --- /dev/null +++ b/libmachine/provision/redhat.go @@ -0,0 +1,212 @@ +package provision + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "text/template" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +var ( + ErrUnknownYumOsRelease = errors.New("unknown OS for Yum repository") + engineConfigTemplate = `[Service] +ExecStart= +ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:{{.DockerPort}} -H unix:///var/run/docker.sock --storage-driver {{.EngineOptions.StorageDriver}} --tlsverify --tlscacert {{.AuthOptions.CaCertRemotePath}} --tlscert {{.AuthOptions.ServerCertRemotePath}} --tlskey {{.AuthOptions.ServerKeyRemotePath}} {{ range .EngineOptions.Labels }}--label {{.}} {{ end }}{{ range .EngineOptions.InsecureRegistry }}--insecure-registry {{.}} {{ end }}{{ range .EngineOptions.RegistryMirror }}--registry-mirror {{.}} {{ end }}{{ range .EngineOptions.ArbitraryFlags }}--{{.}} {{ end }} +Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} +` + majorVersionRE = regexp.MustCompile(`^(\d+)(\..*)?`) +) + +type PackageListInfo struct { + OsRelease string + OsReleaseVersion string +} + +func init() { + Register("RedHat", &RegisteredProvisioner{ + New: func(d drivers.Driver) Provisioner { + return NewRedHatProvisioner("rhel", d) + }, + }) +} + +func NewRedHatProvisioner(osReleaseID string, d drivers.Driver) *RedHatProvisioner { + systemdProvisioner := NewSystemdProvisioner(osReleaseID, d) + systemdProvisioner.SSHCommander = RedHatSSHCommander{Driver: d} + return &RedHatProvisioner{ + systemdProvisioner, + } +} + +type RedHatProvisioner struct { + SystemdProvisioner +} + +func (provisioner *RedHatProvisioner) String() string { + return "redhat" +} + +func (provisioner *RedHatProvisioner) SetHostname(hostname string) error { + // we have to have SetHostname here as well to use the RedHat provisioner + // SSHCommand to add the tty allocation + if _, err := provisioner.SSHCommand(fmt.Sprintf( + "sudo hostname %s && echo %q | sudo tee /etc/hostname", + hostname, + hostname, + )); err != nil { + return err + } + + if _, err := provisioner.SSHCommand(fmt.Sprintf( + "if grep -xq 127.0.1.1.* /etc/hosts; then sudo sed -i 's/^127.0.1.1.*/127.0.1.1 %s/g' /etc/hosts; else echo '127.0.1.1 %s' | sudo tee -a /etc/hosts; fi", + hostname, + hostname, + )); err != nil { + return err + } + + return nil +} + +func (provisioner *RedHatProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + switch action { + case pkgaction.Install: + packageAction = "install" + case pkgaction.Remove: + packageAction = "remove" + case pkgaction.Purge: + packageAction = "remove" + case pkgaction.Upgrade: + packageAction = "upgrade" + } + + command := fmt.Sprintf("sudo -E yum %s -y %s", packageAction, name) + + if _, err := provisioner.SSHCommand(command); err != nil { + return err + } + + return nil +} + +func installDocker(provisioner *RedHatProvisioner) error { + if err := installDockerGeneric(provisioner, provisioner.EngineOptions.InstallURL); err != nil { + return err + } + + if err := provisioner.Service("docker", serviceaction.Restart); err != nil { + return err + } + + err := provisioner.Service("docker", serviceaction.Enable) + return err +} + +func (provisioner *RedHatProvisioner) dockerDaemonResponding() bool { + log.Debug("checking docker daemon") + + if out, err := provisioner.SSHCommand("sudo docker version"); err != nil { + log.Warnf("Error getting SSH command to check if the daemon is up: %s", err) + log.Debugf("'sudo docker version' output:\n%s", out) + return false + } + + // The daemon is up if the command worked. Carry on. + return true +} + +func (provisioner *RedHatProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + // set default storage driver for redhat + storageDriver, err := decideStorageDriver(provisioner, "overlay2", engineOptions.StorageDriver) + if err != nil { + return err + } + provisioner.EngineOptions.StorageDriver = storageDriver + + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + for _, pkg := range provisioner.Packages { + log.Debugf("installing base package: name=%s", pkg) + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + // update OS -- this is needed for libdevicemapper and the docker install + if _, err := provisioner.SSHCommand("sudo -E yum -y update -x docker-*"); err != nil { + return err + } + + // install docker + if err := installDocker(provisioner); err != nil { + return err + } + + if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil { + return err + } + + if err := makeDockerOptionsDir(provisioner); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + err = configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions) + return err +} + +func (provisioner *RedHatProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { + var ( + engineCfg bytes.Buffer + configPath = provisioner.DaemonOptionsFile + ) + + driverNameLabel := fmt.Sprintf("provider=%s", provisioner.Driver.DriverName()) + provisioner.EngineOptions.Labels = append(provisioner.EngineOptions.Labels, driverNameLabel) + + // systemd / redhat will not load options if they are on newlines + // instead, it just continues with a different set of options; yeah... + t, err := template.New("engineConfig").Parse(engineConfigTemplate) + if err != nil { + return nil, err + } + + engineConfigContext := EngineConfigContext{ + DockerPort: dockerPort, + AuthOptions: provisioner.AuthOptions, + EngineOptions: provisioner.EngineOptions, + DockerOptionsDir: provisioner.DockerOptionsDir, + } + + t.Execute(&engineCfg, engineConfigContext) + + daemonOptsDir := configPath + return &DockerOptions{ + EngineOptions: engineCfg.String(), + EngineOptionsPath: daemonOptsDir, + }, nil +} diff --git a/libmachine/provision/redhat_ssh_commander.go b/libmachine/provision/redhat_ssh_commander.go new file mode 100644 index 0000000000..b94e27ba2d --- /dev/null +++ b/libmachine/provision/redhat_ssh_commander.go @@ -0,0 +1,45 @@ +package provision + +import ( + "fmt" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/ssh" +) + +type RedHatSSHCommander struct { + Driver drivers.Driver +} + +func (sshCmder RedHatSSHCommander) SSHCommand(args string) (string, error) { + client, err := drivers.GetSSHClientFromDriver(sshCmder.Driver) + if err != nil { + return "", err + } + + log.Debugf("About to run SSH command:\n%s", args) + + // redhat needs "-t" for tty allocation on ssh therefore we check for the + // external client and add as needed. + // Note: CentOS 7.0 needs multiple "-tt" to force tty allocation when ssh has + // no local tty. + var output string + switch c := client.(type) { + case *ssh.ExternalClient: + c.BaseArgs = append(c.BaseArgs, "-tt") + output, err = c.Output(args) + case *ssh.NativeClient: + output, err = c.OutputWithPty(args) + } + + log.Debugf("SSH cmd err, output: %v: %s", err, output) + if err != nil { + return "", fmt.Errorf(`something went wrong running an SSH command +command : %s +err : %v +output : %s`, args, err, output) + } + + return output, nil +} diff --git a/libmachine/provision/redhat_test.go b/libmachine/provision/redhat_test.go new file mode 100644 index 0000000000..91ba2a1e2d --- /dev/null +++ b/libmachine/provision/redhat_test.go @@ -0,0 +1,20 @@ +package provision + +import ( + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/provisiontest" + "github.com/docker/machine/libmachine/swarm" +) + +func TestRedHatDefaultStorageDriver(t *testing.T) { + p := NewRedHatProvisioner("", &fakedriver.Driver{}) + p.SSHCommander = provisiontest.NewFakeSSHCommander(provisiontest.FakeSSHCommanderOptions{}) + p.Provision(swarm.Options{}, auth.Options{}, engine.Options{}) + if p.EngineOptions.StorageDriver != "overlay2" { + t.Fatal("Default storage driver should be overlay2") + } +} diff --git a/libmachine/provision/serviceaction/service_action.go b/libmachine/provision/serviceaction/service_action.go new file mode 100644 index 0000000000..b2e22e5936 --- /dev/null +++ b/libmachine/provision/serviceaction/service_action.go @@ -0,0 +1,29 @@ +package serviceaction + +type ServiceAction int + +const ( + Restart ServiceAction = iota + Start + Stop + Enable + Disable + DaemonReload +) + +var serviceActions = []string{ + "restart", + "start", + "stop", + "enable", + "disable", + "daemon-reload", +} + +func (s ServiceAction) String() string { + if int(s) >= 0 && int(s) < len(serviceActions) { + return serviceActions[s] + } + + return "" +} diff --git a/libmachine/provision/serviceaction/service_action_test.go b/libmachine/provision/serviceaction/service_action_test.go new file mode 100644 index 0000000000..b2072a5f04 --- /dev/null +++ b/libmachine/provision/serviceaction/service_action_test.go @@ -0,0 +1,9 @@ +package serviceaction + +import "testing" + +func TestActionValue(t *testing.T) { + if Restart.String() != "restart" { + t.Fatalf("Expected %s but got %s", "install", Restart.String()) + } +} diff --git a/libmachine/provision/suse.go b/libmachine/provision/suse.go new file mode 100644 index 0000000000..647a4e0494 --- /dev/null +++ b/libmachine/provision/suse.go @@ -0,0 +1,195 @@ +package provision + +import ( + "fmt" + "strings" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +func init() { + Register("SUSE", &RegisteredProvisioner{ + New: NewSUSEProvisioner, + }) +} + +func NewSUSEProvisioner(d drivers.Driver) Provisioner { + return &SUSEProvisioner{ + NewSystemdProvisioner("SUSE", d), + } +} + +type SUSEProvisioner struct { + SystemdProvisioner +} + +func (provisioner *SUSEProvisioner) CompatibleWithHost() bool { + ids := strings.Split(provisioner.OsReleaseInfo.IDLike, " ") + for _, id := range ids { + if id == "suse" { + return true + } + } + return false +} + +func (provisioner *SUSEProvisioner) String() string { + return "SUSE" +} + +func (provisioner *SUSEProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + switch action { + case pkgaction.Install: + packageAction = "in" + // This is an optimization that reduces the provisioning time of certain + // systems in a significant way. + // The invocation of "zypper in " causes the download of the metadata + // of all the repositories that have never been refreshed or that have + // automatic refresh toggled and have not been refreshed recently. + // Refreshing the repository metadata can take quite some time and can cause + // longer provisioning times for machines that have been pre-optimized for + // docker by including all the needed packages. + if _, err := provisioner.SSHCommand(fmt.Sprintf("rpm -q %s", name)); err == nil { + log.Debugf("%s is already installed, skipping operation", name) + return nil + } + case pkgaction.Remove: + packageAction = "rm" + case pkgaction.Upgrade: + packageAction = "up" + } + + command := fmt.Sprintf("sudo -E zypper -n %s %s", packageAction, name) + + log.Debugf("zypper: action=%s name=%s", action.String(), name) + + if _, err := provisioner.SSHCommand(command); err != nil { + return err + } + + return nil +} + +func (provisioner *SUSEProvisioner) dockerDaemonResponding() bool { + log.Debug("checking docker daemon") + + if out, err := provisioner.SSHCommand("sudo docker version"); err != nil { + log.Warnf("Error getting SSH command to check if the daemon is up: %s", err) + log.Debugf("'sudo docker version' output:\n%s", out) + return false + } + + // The daemon is up if the command worked. Carry on. + return true +} + +func (provisioner *SUSEProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + // figure out the filesystem used by /var/lib/docker + fs, err := provisioner.SSHCommand("stat -f -c %T /var/lib/docker") + if err != nil { + // figure out the filesystem used by /var/lib + fs, err = provisioner.SSHCommand("stat -f -c %T /var/lib/") + if err != nil { + return err + } + } + graphDriver := "overlay" + if strings.Contains(fs, "btrfs") { + graphDriver = "btrfs" + } + + storageDriver, err := decideStorageDriver(provisioner, graphDriver, engineOptions.StorageDriver) + if err != nil { + return err + } + provisioner.EngineOptions.StorageDriver = storageDriver + + log.Debug("Setting hostname") + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + if !strings.HasPrefix(strings.ToLower(provisioner.OsReleaseInfo.ID), "opensuse") { + // This is a SLE machine, enable the containers module to have access + // to the docker packages + if _, err := provisioner.SSHCommand("sudo -E SUSEConnect -p sle-module-containers/12/$(uname -m) -r ''"); err != nil { + return fmt.Errorf( + "Error while adding the 'containers' module, make sure this machine is registered either against SUSE Customer Center (SCC) or to a local Subscription Management Tool (SMT): %v", + err) + } + } + + log.Debug("Installing base packages") + for _, pkg := range provisioner.Packages { + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + log.Debug("Installing docker") + if err := provisioner.Package("docker", pkgaction.Install); err != nil { + return err + } + + // create symlinks for containerd, containerd-shim and optional runc. + // We have to do that because machine overrides the openSUSE systemd + // unit of docker + if _, err := provisioner.SSHCommand("yes no | sudo -E ln -si /usr/sbin/runc /usr/sbin/docker-runc"); err != nil { + return err + } + if _, err := provisioner.SSHCommand("sudo -E ln -sf /usr/sbin/containerd /usr/sbin/docker-containerd"); err != nil { + return err + } + if _, err := provisioner.SSHCommand("sudo -E ln -sf /usr/sbin/containerd-shim /usr/sbin/docker-containerd-shim"); err != nil { + return err + } + + // Is yast2 firewall installed? + if _, installed := provisioner.SSHCommand("rpm -q yast2-firewall"); installed == nil { + // Open the firewall port required by docker + if _, err := provisioner.SSHCommand("sudo -E /sbin/yast2 firewall services add ipprotocol=tcp tcpport=2376 zone=EXT"); err != nil { + return err + } + } + + log.Debug("Starting systemd docker service") + if err := provisioner.Service("docker", serviceaction.Start); err != nil { + return err + } + + log.Debug("Waiting for docker daemon") + if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + log.Debug("Configuring auth") + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + log.Debug("Configuring swarm") + if err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions); err != nil { + return err + } + + // enable in systemd + log.Debug("Enabling docker in systemd") + err = provisioner.Service("docker", serviceaction.Enable) + return err +} diff --git a/libmachine/provision/systemd.go b/libmachine/provision/systemd.go new file mode 100644 index 0000000000..90d0260323 --- /dev/null +++ b/libmachine/provision/systemd.go @@ -0,0 +1,101 @@ +package provision + +import ( + "bytes" + "fmt" + "text/template" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/versioncmp" +) + +type SystemdProvisioner struct { + GenericProvisioner +} + +func (p *SystemdProvisioner) String() string { + return "redhat" +} + +func NewSystemdProvisioner(osReleaseID string, d drivers.Driver) SystemdProvisioner { + return SystemdProvisioner{ + GenericProvisioner{ + SSHCommander: GenericSSHCommander{Driver: d}, + DockerOptionsDir: "/etc/docker", + DaemonOptionsFile: "/etc/systemd/system/docker.service.d/10-machine.conf", + OsReleaseID: osReleaseID, + Packages: []string{ + "curl", + }, + Driver: d, + }, + } +} + +func (p *SystemdProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { + var ( + engineCfg bytes.Buffer + ) + + driverNameLabel := fmt.Sprintf("provider=%s", p.Driver.DriverName()) + p.EngineOptions.Labels = append(p.EngineOptions.Labels, driverNameLabel) + + dockerVersion, err := DockerClientVersion(p) + if err != nil { + return nil, err + } + + arg := "dockerd" + if versioncmp.LessThan(dockerVersion, "1.12.0") { + arg = "docker daemon" + } + + engineConfigTmpl := `[Service] +ExecStart= +ExecStart=/usr/bin/` + arg + ` -H tcp://0.0.0.0:{{.DockerPort}} -H unix:///var/run/docker.sock --storage-driver {{.EngineOptions.StorageDriver}} --tlsverify --tlscacert {{.AuthOptions.CaCertRemotePath}} --tlscert {{.AuthOptions.ServerCertRemotePath}} --tlskey {{.AuthOptions.ServerKeyRemotePath}} {{ range .EngineOptions.Labels }}--label {{.}} {{ end }}{{ range .EngineOptions.InsecureRegistry }}--insecure-registry {{.}} {{ end }}{{ range .EngineOptions.RegistryMirror }}--registry-mirror {{.}} {{ end }}{{ range .EngineOptions.ArbitraryFlags }}--{{.}} {{ end }} +Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} +` + t, err := template.New("engineConfig").Parse(engineConfigTmpl) + if err != nil { + return nil, err + } + + engineConfigContext := EngineConfigContext{ + DockerPort: dockerPort, + AuthOptions: p.AuthOptions, + EngineOptions: p.EngineOptions, + } + + t.Execute(&engineCfg, engineConfigContext) + + return &DockerOptions{ + EngineOptions: engineCfg.String(), + EngineOptionsPath: p.DaemonOptionsFile, + }, nil +} + +func (p *SystemdProvisioner) Service(name string, action serviceaction.ServiceAction) error { + reloadDaemon := false + switch action { + case serviceaction.Start, serviceaction.Restart: + reloadDaemon = true + } + + // systemd needs reloaded when config changes on disk; we cannot + // be sure exactly when it changes from the provisioner so + // we call a reload on every restart to be safe + if reloadDaemon { + if _, err := p.SSHCommand("sudo systemctl daemon-reload"); err != nil { + return err + } + } + + command := fmt.Sprintf("sudo systemctl -f %s %s", action.String(), name) + + if _, err := p.SSHCommand(command); err != nil { + return err + } + + return nil +} diff --git a/libmachine/provision/ubuntu_systemd.go b/libmachine/provision/ubuntu_systemd.go new file mode 100644 index 0000000000..9cf16f9e57 --- /dev/null +++ b/libmachine/provision/ubuntu_systemd.go @@ -0,0 +1,149 @@ +package provision + +import ( + "fmt" + "strconv" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +func init() { + Register("Ubuntu-SystemD", &RegisteredProvisioner{ + New: NewUbuntuSystemdProvisioner, + }) +} + +func NewUbuntuSystemdProvisioner(d drivers.Driver) Provisioner { + return &UbuntuSystemdProvisioner{ + NewSystemdProvisioner("ubuntu", d), + } +} + +type UbuntuSystemdProvisioner struct { + SystemdProvisioner +} + +func (provisioner *UbuntuSystemdProvisioner) String() string { + return "ubuntu(systemd)" +} + +func (provisioner *UbuntuSystemdProvisioner) CompatibleWithHost() bool { + const FirstUbuntuSystemdVersion = 15.04 + + isUbuntu := provisioner.OsReleaseInfo.ID == provisioner.OsReleaseID + if !isUbuntu { + return false + } + versionNumber, err := strconv.ParseFloat(provisioner.OsReleaseInfo.VersionID, 64) + if err != nil { + return false + } + return versionNumber >= FirstUbuntuSystemdVersion + +} + +func (provisioner *UbuntuSystemdProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + updateMetadata := true + + switch action { + case pkgaction.Install, pkgaction.Upgrade: + packageAction = "install" + case pkgaction.Remove: + packageAction = "remove" + updateMetadata = false + case pkgaction.Purge: + packageAction = "purge" + updateMetadata = false + } + + switch name { + case "docker": + name = "docker-ce" + } + + if updateMetadata { + if err := waitForLockAptGetUpdate(provisioner); err != nil { + return err + } + } + + command := fmt.Sprintf("DEBIAN_FRONTEND=noninteractive sudo -E apt-get %s -y %s", packageAction, name) + + log.Debugf("package: action=%s name=%s", action.String(), name) + + return waitForLock(provisioner, command) +} + +func (provisioner *UbuntuSystemdProvisioner) dockerDaemonResponding() bool { + log.Debug("checking docker daemon") + + if out, err := provisioner.SSHCommand("sudo docker version"); err != nil { + log.Warnf("Error getting SSH command to check if the daemon is up: %s", err) + log.Debugf("'sudo docker version' output:\n%s", out) + return false + } + + // The daemon is up if the command worked. Carry on. + return true +} + +func (provisioner *UbuntuSystemdProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + storageDriver, err := decideStorageDriver(provisioner, "overlay2", engineOptions.StorageDriver) + if err != nil { + return err + } + provisioner.EngineOptions.StorageDriver = storageDriver + + log.Debug("setting hostname") + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + log.Debug("installing base packages") + for _, pkg := range provisioner.Packages { + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + log.Info("Installing Docker...") + if err := installDockerGeneric(provisioner, engineOptions.InstallURL); err != nil { + return err + } + + log.Debug("waiting for docker daemon") + if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + log.Debug("configuring auth") + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + log.Debug("configuring swarm") + if err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions); err != nil { + return err + } + + // enable in systemd + log.Debug("enabling docker in systemd") + err = provisioner.Service("docker", serviceaction.Enable) + return err +} diff --git a/libmachine/provision/ubuntu_systemd_test.go b/libmachine/provision/ubuntu_systemd_test.go new file mode 100644 index 0000000000..92fcf891a3 --- /dev/null +++ b/libmachine/provision/ubuntu_systemd_test.go @@ -0,0 +1,44 @@ +package provision + +import ( + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/provisiontest" + "github.com/docker/machine/libmachine/swarm" +) + +func TestUbuntuSystemdCompatibleWithHost(t *testing.T) { + info := &OsRelease{ + ID: "ubuntu", + VersionID: "15.04", + } + p := NewUbuntuSystemdProvisioner(nil) + p.SetOsReleaseInfo(info) + + compatible := p.CompatibleWithHost() + + if !compatible { + t.Fatalf("expected to be compatible with ubuntu 15.04") + } + + info.VersionID = "14.04" + + compatible = p.CompatibleWithHost() + + if compatible { + t.Fatalf("expected to NOT be compatible with ubuntu 14.04") + } + +} + +func TestUbuntuSystemdDefaultStorageDriver(t *testing.T) { + p := NewUbuntuSystemdProvisioner(&fakedriver.Driver{}).(*UbuntuSystemdProvisioner) + p.SSHCommander = provisiontest.NewFakeSSHCommander(provisiontest.FakeSSHCommanderOptions{}) + p.Provision(swarm.Options{}, auth.Options{}, engine.Options{}) + if p.EngineOptions.StorageDriver != "overlay2" { + t.Fatal("Default storage driver should be overlay2") + } +} diff --git a/libmachine/provision/ubuntu_upstart.go b/libmachine/provision/ubuntu_upstart.go new file mode 100644 index 0000000000..7f62ab2328 --- /dev/null +++ b/libmachine/provision/ubuntu_upstart.go @@ -0,0 +1,158 @@ +package provision + +import ( + "fmt" + "strconv" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" +) + +func init() { + Register("Ubuntu-UpStart", &RegisteredProvisioner{ + New: NewUbuntuProvisioner, + }) +} + +func NewUbuntuProvisioner(d drivers.Driver) Provisioner { + return &UbuntuProvisioner{ + GenericProvisioner{ + SSHCommander: GenericSSHCommander{Driver: d}, + DockerOptionsDir: "/etc/docker", + DaemonOptionsFile: "/etc/default/docker", + OsReleaseID: "ubuntu", + Packages: []string{ + "curl", + }, + Driver: d, + }, + } +} + +type UbuntuProvisioner struct { + GenericProvisioner +} + +func (provisioner *UbuntuProvisioner) String() string { + return "ubuntu(upstart)" +} + +func (provisioner *UbuntuProvisioner) CompatibleWithHost() bool { + const FirstUbuntuSystemdVersion = 15.04 + isUbuntu := provisioner.OsReleaseInfo.ID == provisioner.OsReleaseID + if !isUbuntu { + return false + } + versionNumber, err := strconv.ParseFloat(provisioner.OsReleaseInfo.VersionID, 64) + if err != nil { + return false + } + + return versionNumber < FirstUbuntuSystemdVersion + +} + +func (provisioner *UbuntuProvisioner) Service(name string, action serviceaction.ServiceAction) error { + command := fmt.Sprintf("sudo service %s %s", name, action.String()) + + if _, err := provisioner.SSHCommand(command); err != nil { + return err + } + + return nil +} + +func (provisioner *UbuntuProvisioner) Package(name string, action pkgaction.PackageAction) error { + var packageAction string + + updateMetadata := true + + switch action { + case pkgaction.Install, pkgaction.Upgrade: + packageAction = "install" + case pkgaction.Remove, pkgaction.Purge: + packageAction = "remove" + updateMetadata = false + } + + switch name { + case "docker": + name = "docker-engine" + } + + if updateMetadata { + if err := waitForLockAptGetUpdate(provisioner); err != nil { + return err + } + } + + command := fmt.Sprintf("DEBIAN_FRONTEND=noninteractive sudo -E apt-get %s -y -o Dpkg::Options::=\"--force-confnew\" %s", packageAction, name) + + log.Debugf("package: action=%s name=%s", action.String(), name) + + return waitForLock(provisioner, command) +} + +func (provisioner *UbuntuProvisioner) dockerDaemonResponding() bool { + log.Debug("checking docker daemon") + + if out, err := provisioner.SSHCommand("sudo docker version"); err != nil { + log.Warnf("Error getting SSH command to check if the daemon is up: %s", err) + log.Debugf("'sudo docker version' output:\n%s", out) + return false + } + + // The daemon is up if the command worked. Carry on. + return true +} + +func (provisioner *UbuntuProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + provisioner.SwarmOptions = swarmOptions + provisioner.AuthOptions = authOptions + provisioner.EngineOptions = engineOptions + swarmOptions.Env = engineOptions.Env + + storageDriver, err := decideStorageDriver(provisioner, "overlay2", engineOptions.StorageDriver) + if err != nil { + return err + } + provisioner.EngineOptions.StorageDriver = storageDriver + + if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil { + return err + } + + for _, pkg := range provisioner.Packages { + if err := provisioner.Package(pkg, pkgaction.Install); err != nil { + return err + } + } + + log.Info("Installing Docker...") + if err := installDockerGeneric(provisioner, engineOptions.InstallURL); err != nil { + return err + } + + if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil { + return err + } + + if err := makeDockerOptionsDir(provisioner); err != nil { + return err + } + + provisioner.AuthOptions = setRemoteAuthOptions(provisioner) + + if err := ConfigureAuth(provisioner); err != nil { + return err + } + + err = configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions) + return err +} diff --git a/libmachine/provision/ubuntu_upstart_test.go b/libmachine/provision/ubuntu_upstart_test.go new file mode 100644 index 0000000000..9b62e64e59 --- /dev/null +++ b/libmachine/provision/ubuntu_upstart_test.go @@ -0,0 +1,44 @@ +package provision + +import ( + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/provisiontest" + "github.com/docker/machine/libmachine/swarm" +) + +func TestUbuntuCompatibleWithHost(t *testing.T) { + info := &OsRelease{ + ID: "ubuntu", + VersionID: "14.04", + } + p := NewUbuntuProvisioner(nil) + p.SetOsReleaseInfo(info) + + compatible := p.CompatibleWithHost() + + if !compatible { + t.Fatalf("expected to be compatible with ubuntu 14.04") + } + + info.VersionID = "15.04" + + compatible = p.CompatibleWithHost() + + if compatible { + t.Fatalf("expected to NOT be compatible with ubuntu 15.04") + } + +} + +func TestUbuntuDefaultStorageDriver(t *testing.T) { + p := NewUbuntuProvisioner(&fakedriver.Driver{}).(*UbuntuProvisioner) + p.SSHCommander = provisiontest.NewFakeSSHCommander(provisiontest.FakeSSHCommanderOptions{}) + p.Provision(swarm.Options{}, auth.Options{}, engine.Options{}) + if p.EngineOptions.StorageDriver != "overlay2" { + t.Fatal("Default storage driver should be overlay2") + } +} diff --git a/libmachine/provision/utils.go b/libmachine/provision/utils.go new file mode 100644 index 0000000000..e91ed85666 --- /dev/null +++ b/libmachine/provision/utils.go @@ -0,0 +1,322 @@ +package provision + +import ( + "fmt" + "io/ioutil" + "net/url" + "path" + "path/filepath" + "regexp" + "strconv" + "strings" + "time" + + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/cert" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/provision/serviceaction" +) + +type DockerOptions struct { + EngineOptions string + EngineOptionsPath string +} + +func installDockerGeneric(p Provisioner, baseURL string) error { + // install docker - until cloudinit we use ubuntu everywhere so we + // just install it using the docker repos + if output, err := p.SSHCommand(fmt.Sprintf("if ! type docker; then curl -sSL %s | sh -; fi", baseURL)); err != nil { + return fmt.Errorf("error installing docker: %s", output) + } + + return nil +} + +func makeDockerOptionsDir(p Provisioner) error { + dockerDir := p.GetDockerOptionsDir() + if _, err := p.SSHCommand(fmt.Sprintf("sudo mkdir -p %s", dockerDir)); err != nil { + return err + } + + return nil +} + +func setRemoteAuthOptions(p Provisioner) auth.Options { + dockerDir := p.GetDockerOptionsDir() + authOptions := p.GetAuthOptions() + + // due to windows clients, we cannot use filepath.Join as the paths + // will be mucked on the linux hosts + authOptions.CaCertRemotePath = path.Join(dockerDir, "ca.pem") + authOptions.ServerCertRemotePath = path.Join(dockerDir, "server.pem") + authOptions.ServerKeyRemotePath = path.Join(dockerDir, "server-key.pem") + + return authOptions +} + +func ConfigureAuth(p Provisioner) error { + var ( + err error + ) + + driver := p.GetDriver() + machineName := driver.GetMachineName() + authOptions := p.GetAuthOptions() + swarmOptions := p.GetSwarmOptions() + org := mcnutils.GetUsername() + "." + machineName + bits := 2048 + + ip, err := driver.GetIP() + if err != nil { + return err + } + + log.Info("Copying certs to the local machine directory...") + + if err := mcnutils.CopyFile(authOptions.CaCertPath, filepath.Join(authOptions.StorePath, "ca.pem")); err != nil { + return fmt.Errorf("Copying ca.pem to machine dir failed: %s", err) + } + + if err := mcnutils.CopyFile(authOptions.ClientCertPath, filepath.Join(authOptions.StorePath, "cert.pem")); err != nil { + return fmt.Errorf("Copying cert.pem to machine dir failed: %s", err) + } + + if err := mcnutils.CopyFile(authOptions.ClientKeyPath, filepath.Join(authOptions.StorePath, "key.pem")); err != nil { + return fmt.Errorf("Copying key.pem to machine dir failed: %s", err) + } + + // The Host IP is always added to the certificate's SANs list + hosts := append(authOptions.ServerCertSANs, ip, "localhost") + log.Debugf("generating server cert: %s ca-key=%s private-key=%s org=%s san=%s", + authOptions.ServerCertPath, + authOptions.CaCertPath, + authOptions.CaPrivateKeyPath, + org, + hosts, + ) + + // TODO: Switch to passing just authOptions to this func + // instead of all these individual fields + err = cert.GenerateCert(&cert.Options{ + Hosts: hosts, + CertFile: authOptions.ServerCertPath, + KeyFile: authOptions.ServerKeyPath, + CAFile: authOptions.CaCertPath, + CAKeyFile: authOptions.CaPrivateKeyPath, + Org: org, + Bits: bits, + SwarmMaster: swarmOptions.Master, + }) + + if err != nil { + return fmt.Errorf("error generating server cert: %s", err) + } + + if err := p.Service("docker", serviceaction.Stop); err != nil { + return err + } + + if _, err := p.SSHCommand(`if [ ! -z "$(ip link show docker0)" ]; then sudo ip link delete docker0; fi`); err != nil { + return err + } + + // upload certs and configure TLS auth + caCert, err := ioutil.ReadFile(authOptions.CaCertPath) + if err != nil { + return err + } + + serverCert, err := ioutil.ReadFile(authOptions.ServerCertPath) + if err != nil { + return err + } + serverKey, err := ioutil.ReadFile(authOptions.ServerKeyPath) + if err != nil { + return err + } + + log.Info("Copying certs to the remote machine...") + + // printf will choke if we don't pass a format string because of the + // dashes, so that's the reason for the '%%s' + certTransferCmdFmt := "printf '%%s' '%s' | sudo tee %s" + + // These ones are for Jessie and Mike <3 <3 <3 + if _, err := p.SSHCommand(fmt.Sprintf(certTransferCmdFmt, string(caCert), authOptions.CaCertRemotePath)); err != nil { + return err + } + + if _, err := p.SSHCommand(fmt.Sprintf(certTransferCmdFmt, string(serverCert), authOptions.ServerCertRemotePath)); err != nil { + return err + } + + if _, err := p.SSHCommand(fmt.Sprintf(certTransferCmdFmt, string(serverKey), authOptions.ServerKeyRemotePath)); err != nil { + return err + } + + dockerURL, err := driver.GetURL() + if err != nil { + return err + } + u, err := url.Parse(dockerURL) + if err != nil { + return err + } + dockerPort := engine.DefaultPort + parts := strings.Split(u.Host, ":") + if len(parts) == 2 { + dPort, err := strconv.Atoi(parts[1]) + if err != nil { + return err + } + dockerPort = dPort + } + + dkrcfg, err := p.GenerateDockerOptions(dockerPort) + if err != nil { + return err + } + + log.Info("Setting Docker configuration on the remote daemon...") + + if _, err = p.SSHCommand(fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | sudo tee %s", path.Dir(dkrcfg.EngineOptionsPath), dkrcfg.EngineOptions, dkrcfg.EngineOptionsPath)); err != nil { + return err + } + + if err := p.Service("docker", serviceaction.Start); err != nil { + return err + } + + return WaitForDocker(p, dockerPort) +} + +func matchNetstatOut(reDaemonListening, netstatOut string) bool { + // TODO: I would really prefer this be a Scanner directly on + // the STDOUT of the executed command than to do all the string + // manipulation hokey-pokey. + // + // TODO: Unit test this matching. + for _, line := range strings.Split(netstatOut, "\n") { + match, err := regexp.MatchString(reDaemonListening, line) + if err != nil { + log.Warnf("Regex warning: %s", err) + } + if match && line != "" { + return true + } + } + + return false +} + +func decideStorageDriver(p Provisioner, defaultDriver, suppliedDriver string) (string, error) { + if suppliedDriver != "" { + return suppliedDriver, nil + } + bestSuitedDriver := "" + + defer func() { + if bestSuitedDriver != "" { + log.Debugf("No storagedriver specified, using %s\n", bestSuitedDriver) + } + }() + + if defaultDriver != "aufs" { + bestSuitedDriver = defaultDriver + } else { + remoteFilesystemType, err := getFilesystemType(p, "/var/lib") + if err != nil { + return "", err + } + if remoteFilesystemType == "btrfs" { + bestSuitedDriver = "btrfs" + } else { + bestSuitedDriver = defaultDriver + } + } + return bestSuitedDriver, nil + +} + +func getFilesystemType(p Provisioner, directory string) (string, error) { + statCommandOutput, err := p.SSHCommand("stat -f -c %T " + directory) + if err != nil { + err = fmt.Errorf("Error looking up filesystem type: %s", err) + return "", err + } + + fstype := strings.TrimSpace(statCommandOutput) + return fstype, nil +} + +func checkDaemonUp(p Provisioner, dockerPort int) func() bool { + reDaemonListening := fmt.Sprintf(":%d\\s+.*:.*", dockerPort) + return func() bool { + // HACK: Check netstat's output to see if anyone's listening on the Docker API port. + netstatOut, err := p.SSHCommand("if ! type netstat 1>/dev/null; then ss -tln; else netstat -tln; fi") + if err != nil { + log.Warnf("Error running SSH command: %s", err) + return false + } + + return matchNetstatOut(reDaemonListening, netstatOut) + } +} + +func WaitForDocker(p Provisioner, dockerPort int) error { + if err := mcnutils.WaitForSpecific(checkDaemonUp(p, dockerPort), 10, 3*time.Second); err != nil { + return NewErrDaemonAvailable(err) + } + + return nil +} + +// DockerClientVersion returns the version of the Docker client on the host +// that ssh is connected to, e.g. "1.12.1". +func DockerClientVersion(ssh SSHCommander) (string, error) { + // `docker version --format {{.Client.Version}}` would be preferable, but + // that fails if the server isn't running yet. + // + // output is expected to be something like + // + // Docker version 1.12.1, build 7a86f89 + output, err := ssh.SSHCommand("docker --version") + if err != nil { + return "", err + } + + words := strings.Fields(output) + if len(words) < 3 || words[0] != "Docker" || words[1] != "version" { + return "", fmt.Errorf("DockerClientVersion: cannot parse version string from %q", output) + } + + return strings.TrimRight(words[2], ","), nil +} + +func waitForLockAptGetUpdate(ssh SSHCommander) error { + return waitForLock(ssh, "sudo apt-get update") +} + +func waitForLock(ssh SSHCommander, cmd string) error { + var sshErr error + err := mcnutils.WaitFor(func() bool { + _, sshErr = ssh.SSHCommand(cmd) + if sshErr != nil { + if strings.Contains(sshErr.Error(), "Could not get lock") { + sshErr = nil + return false + } + return true + } + return true + }) + if sshErr != nil { + return fmt.Errorf("Error running %q: %s", cmd, sshErr) + } + if err != nil { + return fmt.Errorf("Failed to obtain lock: %s", err) + } + return nil +} diff --git a/libmachine/provision/utils_test.go b/libmachine/provision/utils_test.go new file mode 100644 index 0000000000..abcb781e20 --- /dev/null +++ b/libmachine/provision/utils_test.go @@ -0,0 +1,284 @@ +package provision + +import ( + "fmt" + "regexp" + "strings" + "testing" + + "github.com/docker/machine/drivers/fakedriver" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/provision/pkgaction" + "github.com/docker/machine/libmachine/provision/provisiontest" + "github.com/docker/machine/libmachine/provision/serviceaction" + "github.com/docker/machine/libmachine/swarm" + "github.com/stretchr/testify/assert" +) + +var ( + reDaemonListening = ":2376\\s+.*:.*" +) + +func TestMatchNetstatOutMissing(t *testing.T) { + nsOut := `Active Internet connections (servers and established) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN +tcp 0 0 0.0.0.0:237 0.0.0.0:* LISTEN +tcp6 0 0 :::22 :::* LISTEN +tcp6 0 0 :::23760 :::* LISTEN` + if matchNetstatOut(reDaemonListening, nsOut) { + t.Fatal("Expected not to match the netstat output as showing the daemon listening but got a match") + } +} + +func TestMatchNetstatOutPresent(t *testing.T) { + nsOut := `Active Internet connections (servers and established) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN +tcp6 0 0 :::2376 :::* LISTEN +tcp6 0 0 :::22 :::* LISTEN` + if !matchNetstatOut(reDaemonListening, nsOut) { + t.Fatal("Expected to match the netstat output as showing the daemon listening but didn't") + } +} + +func TestMatchSsOutMissing(t *testing.T) { + ssOut := `State Recv-Q Send-Q Local Address:Port Peer Address:Port +LISTEN 0 128 *:22 *:* +LISTEN 0 128 :::22 :::* +LISTEN 0 128 :::23760 :::* ` + if matchNetstatOut(reDaemonListening, ssOut) { + t.Fatal("Expected not to match the ss output as showing the daemon listening but got a match") + } +} + +func TestMatchSsOutPresent(t *testing.T) { + ssOut := `State Recv-Q Send-Q Local Address:Port Peer Address:Port +LISTEN 0 128 *:22 *:* +LISTEN 0 128 :::22 :::* +LISTEN 0 128 :::2376 :::* ` + if !matchNetstatOut(reDaemonListening, ssOut) { + t.Fatal("Expected to match the ss output as showing the daemon listening but didn't") + } +} + +func TestGenerateDockerOptionsBoot2Docker(t *testing.T) { + p := &Boot2DockerProvisioner{ + Driver: &fakedriver.Driver{}, + } + dockerPort := 1234 + p.AuthOptions = auth.Options{ + CaCertRemotePath: "/test/ca-cert", + ServerKeyRemotePath: "/test/server-key", + ServerCertRemotePath: "/test/server-cert", + } + engineConfigPath := "/var/lib/boot2docker/profile" + + dockerCfg, err := p.GenerateDockerOptions(dockerPort) + if err != nil { + t.Fatal(err) + } + + if dockerCfg.EngineOptionsPath != engineConfigPath { + t.Fatalf("expected engine path %s; received %s", engineConfigPath, dockerCfg.EngineOptionsPath) + } + + if strings.Index(dockerCfg.EngineOptions, fmt.Sprintf("-H tcp://0.0.0.0:%d", dockerPort)) == -1 { + t.Fatalf("-H docker port invalid; expected %d", dockerPort) + } + + if strings.Index(dockerCfg.EngineOptions, fmt.Sprintf("CACERT=%s", p.AuthOptions.CaCertRemotePath)) == -1 { + t.Fatalf("CACERT option invalid; expected %s", p.AuthOptions.CaCertRemotePath) + } + + if strings.Index(dockerCfg.EngineOptions, fmt.Sprintf("SERVERKEY=%s", p.AuthOptions.ServerKeyRemotePath)) == -1 { + t.Fatalf("SERVERKEY option invalid; expected %s", p.AuthOptions.ServerKeyRemotePath) + } + + if strings.Index(dockerCfg.EngineOptions, fmt.Sprintf("SERVERCERT=%s", p.AuthOptions.ServerCertRemotePath)) == -1 { + t.Fatalf("SERVERCERT option invalid; expected %s", p.AuthOptions.ServerCertRemotePath) + } +} + +func TestMachinePortBoot2Docker(t *testing.T) { + p := &Boot2DockerProvisioner{ + Driver: &fakedriver.Driver{}, + } + dockerPort := engine.DefaultPort + bindURL := fmt.Sprintf("tcp://0.0.0.0:%d", dockerPort) + p.AuthOptions = auth.Options{ + CaCertRemotePath: "/test/ca-cert", + ServerKeyRemotePath: "/test/server-key", + ServerCertRemotePath: "/test/server-cert", + } + + cfg, err := p.GenerateDockerOptions(dockerPort) + if err != nil { + t.Fatal(err) + } + re := regexp.MustCompile("-H tcp://.*:(.+)") + m := re.FindStringSubmatch(cfg.EngineOptions) + if len(m) == 0 { + t.Errorf("could not find port %d in engine config", dockerPort) + } + + b := m[0] + u := strings.Split(b, " ") + url := u[1] + url = strings.Replace(url, "'", "", -1) + url = strings.Replace(url, "\\\"", "", -1) + if url != bindURL { + t.Errorf("expected url %s; received %s", bindURL, url) + } +} + +func TestMachineCustomPortBoot2Docker(t *testing.T) { + p := &Boot2DockerProvisioner{ + Driver: &fakedriver.Driver{}, + } + dockerPort := 3376 + bindURL := fmt.Sprintf("tcp://0.0.0.0:%d", dockerPort) + p.AuthOptions = auth.Options{ + CaCertRemotePath: "/test/ca-cert", + ServerKeyRemotePath: "/test/server-key", + ServerCertRemotePath: "/test/server-cert", + } + + cfg, err := p.GenerateDockerOptions(dockerPort) + if err != nil { + t.Fatal(err) + } + + re := regexp.MustCompile("-H tcp://.*:(.+)") + m := re.FindStringSubmatch(cfg.EngineOptions) + if len(m) == 0 { + t.Errorf("could not find port %d in engine config", dockerPort) + } + + b := m[0] + u := strings.Split(b, " ") + url := u[1] + url = strings.Replace(url, "'", "", -1) + url = strings.Replace(url, "\\\"", "", -1) + if url != bindURL { + t.Errorf("expected url %s; received %s", bindURL, url) + } +} + +func TestUbuntuSystemdDaemonBinary(t *testing.T) { + p := NewUbuntuSystemdProvisioner(&fakedriver.Driver{}).(*UbuntuSystemdProvisioner) + cases := []struct { + output, want string + }{ + {"Docker version 1.9.1\n", "docker daemon"}, + {"Docker version 1.11.2\n", "docker daemon"}, + {"Docker version 1.12.0\n", "dockerd"}, + {"Docker version 1.13.0\n", "dockerd"}, + } + + sshCmder := &provisiontest.FakeSSHCommander{ + Responses: make(map[string]string), + } + p.SSHCommander = sshCmder + + for _, tc := range cases { + sshCmder.Responses["docker --version"] = tc.output + opts, err := p.GenerateDockerOptions(1234) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(opts.EngineOptions, tc.want) { + t.Fatal("incorrect docker daemon binary in engine options") + } + } +} + +type fakeProvisioner struct { + GenericProvisioner +} + +func (provisioner *fakeProvisioner) Package(name string, action pkgaction.PackageAction) error { + return nil +} + +func (provisioner *fakeProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { + return nil +} + +func (provisioner *fakeProvisioner) Service(name string, action serviceaction.ServiceAction) error { + return nil +} + +func (provisioner *fakeProvisioner) String() string { + return "fake" +} + +func TestDecideStorageDriver(t *testing.T) { + var tests = []struct { + suppliedDriver string + defaultDriver string + remoteFilesystemType string + expectedDriver string + }{ + {"", "aufs", "ext4", "aufs"}, + {"", "aufs", "btrfs", "btrfs"}, + {"", "overlay", "btrfs", "overlay"}, + {"devicemapper", "aufs", "ext4", "devicemapper"}, + {"devicemapper", "aufs", "btrfs", "devicemapper"}, + } + + p := &fakeProvisioner{GenericProvisioner{ + Driver: &fakedriver.Driver{}, + }} + for _, test := range tests { + p.SSHCommander = provisiontest.NewFakeSSHCommander( + provisiontest.FakeSSHCommanderOptions{ + FilesystemType: test.remoteFilesystemType, + }, + ) + storageDriver, err := decideStorageDriver(p, test.defaultDriver, test.suppliedDriver) + assert.NoError(t, err) + assert.Equal(t, test.expectedDriver, storageDriver) + } +} + +func TestGetFilesystemType(t *testing.T) { + p := &fakeProvisioner{GenericProvisioner{ + Driver: &fakedriver.Driver{}, + }} + p.SSHCommander = &provisiontest.FakeSSHCommander{ + Responses: map[string]string{ + "stat -f -c %T /var/lib": "btrfs\n", + }, + } + fsType, err := getFilesystemType(p, "/var/lib") + assert.NoError(t, err) + assert.Equal(t, "btrfs", fsType) +} + +func TestDockerClientVersion(t *testing.T) { + cases := []struct { + output, want string + }{ + {"Docker version 1.9.1, build a34a1d5\n", "1.9.1"}, + {"Docker version 1.9.1\n", "1.9.1"}, + {"Docker version 1.13.0-rc1, build deadbeef\n", "1.13.0-rc1"}, + {"Docker version 1.13.0-dev, build deadbeef\n", "1.13.0-dev"}, + } + + sshCmder := &provisiontest.FakeSSHCommander{ + Responses: make(map[string]string), + } + + for _, tc := range cases { + sshCmder.Responses["docker --version"] = tc.output + got, err := DockerClientVersion(sshCmder) + if err != nil { + t.Fatal(err) + } + if got != tc.want { + t.Errorf("Unexpected version string from %q; got %q, want %q", tc.output, tc.want, got) + } + } +} diff --git a/libmachine/shell/shell.go b/libmachine/shell/shell.go new file mode 100644 index 0000000000..d0a271c9a9 --- /dev/null +++ b/libmachine/shell/shell.go @@ -0,0 +1,26 @@ +// +build !windows + +package shell + +import ( + "errors" + "fmt" + "os" + "path/filepath" +) + +var ( + ErrUnknownShell = errors.New("Error: Unknown shell") +) + +// Detect detects user's current shell. +func Detect() (string, error) { + shell := os.Getenv("SHELL") + + if shell == "" { + fmt.Printf("The default lines below are for a sh/bash shell, you can specify the shell you're using, with the --shell flag.\n\n") + return "", ErrUnknownShell + } + + return filepath.Base(shell), nil +} diff --git a/libmachine/shell/shell_test.go b/libmachine/shell/shell_test.go new file mode 100644 index 0000000000..97ef34f24f --- /dev/null +++ b/libmachine/shell/shell_test.go @@ -0,0 +1,28 @@ +package shell + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDetectBash(t *testing.T) { + defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL")) + os.Setenv("SHELL", "/bin/bash") + + shell, err := Detect() + + assert.Equal(t, "bash", shell) + assert.NoError(t, err) +} + +func TestDetectFish(t *testing.T) { + defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL")) + os.Setenv("SHELL", "/bin/fish") + + shell, err := Detect() + + assert.Equal(t, "fish", shell) + assert.NoError(t, err) +} diff --git a/libmachine/shell/shell_unix_test.go b/libmachine/shell/shell_unix_test.go new file mode 100644 index 0000000000..b9382071b3 --- /dev/null +++ b/libmachine/shell/shell_unix_test.go @@ -0,0 +1,20 @@ +// +build !windows + +package shell + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestUnknownShell(t *testing.T) { + defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL")) + os.Setenv("SHELL", "") + + shell, err := Detect() + + assert.Equal(t, err, ErrUnknownShell) + assert.Empty(t, shell) +} diff --git a/libmachine/shell/shell_windows.go b/libmachine/shell/shell_windows.go new file mode 100644 index 0000000000..89cd2c8b0a --- /dev/null +++ b/libmachine/shell/shell_windows.go @@ -0,0 +1,84 @@ +package shell + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "syscall" + "unsafe" +) + +// re-implementation of private function in https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go#L945 +func getProcessEntry(pid int) (pe *syscall.ProcessEntry32, err error) { + snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err + } + defer syscall.CloseHandle(syscall.Handle(snapshot)) + + var processEntry syscall.ProcessEntry32 + processEntry.Size = uint32(unsafe.Sizeof(processEntry)) + err = syscall.Process32First(snapshot, &processEntry) + if err != nil { + return nil, err + } + + for { + if processEntry.ProcessID == uint32(pid) { + pe = &processEntry + return + } + + err = syscall.Process32Next(snapshot, &processEntry) + if err != nil { + return nil, err + } + } +} + +// getNameAndItsPpid returns the exe file name its parent process id. +func getNameAndItsPpid(pid int) (exefile string, parentid int, err error) { + pe, err := getProcessEntry(pid) + if err != nil { + return "", 0, err + } + + name := syscall.UTF16ToString(pe.ExeFile[:]) + return name, int(pe.ParentProcessID), nil +} + +func Detect() (string, error) { + shell := os.Getenv("SHELL") + + if shell == "" { + shell, shellppid, err := getNameAndItsPpid(os.Getppid()) + if err != nil { + return "cmd", err // defaulting to cmd + } + if strings.Contains(strings.ToLower(shell), "powershell") { + return "powershell", nil + } else if strings.Contains(strings.ToLower(shell), "cmd") { + return "cmd", nil + } else { + shell, _, err := getNameAndItsPpid(shellppid) + if err != nil { + return "cmd", err // defaulting to cmd + } + if strings.Contains(strings.ToLower(shell), "powershell") { + return "powershell", nil + } else if strings.Contains(strings.ToLower(shell), "cmd") { + return "cmd", nil + } else { + fmt.Printf("You can further specify your shell with either 'cmd' or 'powershell' with the --shell flag.\n\n") + return "cmd", nil // this could be either powershell or cmd, defaulting to cmd + } + } + } + + if os.Getenv("__fish_bin_dir") != "" { + return "fish", nil + } + + return filepath.Base(shell), nil +} diff --git a/libmachine/shell/shell_windows_test.go b/libmachine/shell/shell_windows_test.go new file mode 100644 index 0000000000..81c0c50705 --- /dev/null +++ b/libmachine/shell/shell_windows_test.go @@ -0,0 +1,41 @@ +package shell + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDetect(t *testing.T) { + defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL")) + os.Setenv("SHELL", "") + + shell, err := Detect() + + assert.Equal(t, "powershell", shell) + assert.NoError(t, err) +} + +func TestGetNameAndItsPpidOfCurrent(t *testing.T) { + shell, shellppid, err := getNameAndItsPpid(os.Getpid()) + + assert.Equal(t, "shell.test.exe", shell) + assert.Equal(t, os.Getppid(), shellppid) + assert.NoError(t, err) +} + +func TestGetNameAndItsPpidOfParent(t *testing.T) { + shell, _, err := getNameAndItsPpid(os.Getppid()) + + assert.Equal(t, "go.exe", shell) + assert.NoError(t, err) +} + +func TestGetNameAndItsPpidOfGrandParent(t *testing.T) { + shell, shellppid, err := getNameAndItsPpid(os.Getppid()) + shell, shellppid, err = getNameAndItsPpid(shellppid) + + assert.Equal(t, "powershell.exe", shell) + assert.NoError(t, err) +} diff --git a/libmachine/ssh/client.go b/libmachine/ssh/client.go new file mode 100644 index 0000000000..780b11a5ff --- /dev/null +++ b/libmachine/ssh/client.go @@ -0,0 +1,447 @@ +package ssh + +import ( + "fmt" + "io" + "io/ioutil" + "net" + "os" + "os/exec" + "runtime" + "strconv" + "strings" + + "github.com/docker/docker/pkg/term" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnutils" + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/terminal" +) + +type Client interface { + Output(command string) (string, error) + Shell(args ...string) error + + // Start starts the specified command without waiting for it to finish. You + // have to call the Wait function for that. + // + // The first two io.ReadCloser are the standard output and the standard + // error of the executing command respectively. The returned error follows + // the same logic as in the exec.Cmd.Start function. + Start(command string) (io.ReadCloser, io.ReadCloser, error) + + // Wait waits for the command started by the Start function to exit. The + // returned error follows the same logic as in the exec.Cmd.Wait function. + Wait() error +} + +type ExternalClient struct { + BaseArgs []string + BinaryPath string + cmd *exec.Cmd +} + +type NativeClient struct { + Config ssh.ClientConfig + Hostname string + Port int + openSession *ssh.Session + openClient *ssh.Client +} + +type Auth struct { + Passwords []string + Keys []string +} + +type ClientType string + +const ( + maxDialAttempts = 10 +) + +const ( + External ClientType = "external" + Native ClientType = "native" +) + +var ( + baseSSHArgs = []string{ + "-F", "/dev/null", + "-o", "ConnectionAttempts=3", // retry 3 times if SSH connection fails + "-o", "ConnectTimeout=10", // timeout after 10 seconds + "-o", "ControlMaster=no", // disable ssh multiplexing + "-o", "ControlPath=none", + "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." + "-o", "PasswordAuthentication=no", + "-o", "ServerAliveInterval=60", // prevents connection to be dropped if command takes too long + "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null", + } + defaultClientType = External +) + +func SetDefaultClient(clientType ClientType) { + // Allow over-riding of default client type, so that even if ssh binary + // is found in PATH we can still use the Go native implementation if + // desired. + switch clientType { + case External: + defaultClientType = External + case Native: + defaultClientType = Native + } +} + +func NewClient(user string, host string, port int, auth *Auth) (Client, error) { + sshBinaryPath, err := exec.LookPath("ssh") + if err != nil { + log.Debug("SSH binary not found, using native Go implementation") + client, err := NewNativeClient(user, host, port, auth) + log.Debug(client) + return client, err + } + + if defaultClientType == Native { + log.Debug("Using SSH client type: native") + client, err := NewNativeClient(user, host, port, auth) + log.Debug(client) + return client, err + } + + log.Debug("Using SSH client type: external") + client, err := NewExternalClient(sshBinaryPath, user, host, port, auth) + log.Debug(client) + return client, err +} + +func NewNativeClient(user, host string, port int, auth *Auth) (Client, error) { + config, err := NewNativeConfig(user, auth) + if err != nil { + return nil, fmt.Errorf("Error getting config for native Go SSH: %s", err) + } + + return &NativeClient{ + Config: config, + Hostname: host, + Port: port, + }, nil +} + +func NewNativeConfig(user string, auth *Auth) (ssh.ClientConfig, error) { + var ( + authMethods []ssh.AuthMethod + ) + + for _, k := range auth.Keys { + key, err := ioutil.ReadFile(k) + if err != nil { + return ssh.ClientConfig{}, err + } + + privateKey, err := ssh.ParsePrivateKey(key) + if err != nil { + return ssh.ClientConfig{}, err + } + + authMethods = append(authMethods, ssh.PublicKeys(privateKey)) + } + + for _, p := range auth.Passwords { + authMethods = append(authMethods, ssh.Password(p)) + } + + return ssh.ClientConfig{ + User: user, + Auth: authMethods, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + }, nil +} + +func (client *NativeClient) dialSuccess() bool { + conn, err := ssh.Dial("tcp", net.JoinHostPort(client.Hostname, strconv.Itoa(client.Port)), &client.Config) + if err != nil { + log.Debugf("Error dialing TCP: %s", err) + return false + } + closeConn(conn) + return true +} + +func (client *NativeClient) session(command string) (*ssh.Client, *ssh.Session, error) { + if err := mcnutils.WaitFor(client.dialSuccess); err != nil { + return nil, nil, fmt.Errorf("Error attempting SSH client dial: %s", err) + } + + conn, err := ssh.Dial("tcp", net.JoinHostPort(client.Hostname, strconv.Itoa(client.Port)), &client.Config) + if err != nil { + return nil, nil, fmt.Errorf("Mysterious error dialing TCP for SSH (we already succeeded at least once) : %s", err) + } + session, err := conn.NewSession() + + return conn, session, err +} + +func (client *NativeClient) Output(command string) (string, error) { + conn, session, err := client.session(command) + if err != nil { + return "", nil + } + defer closeConn(conn) + defer session.Close() + + output, err := session.CombinedOutput(command) + + return string(output), err +} + +func (client *NativeClient) OutputWithPty(command string) (string, error) { + conn, session, err := client.session(command) + if err != nil { + return "", nil + } + defer closeConn(conn) + defer session.Close() + + fd := int(os.Stdout.Fd()) + + termWidth, termHeight, err := terminal.GetSize(fd) + if err != nil { + return "", err + } + + modes := ssh.TerminalModes{ + ssh.ECHO: 0, + ssh.TTY_OP_ISPEED: 14400, + ssh.TTY_OP_OSPEED: 14400, + } + + // request tty -- fixes error with hosts that use + // "Defaults requiretty" in /etc/sudoers - I'm looking at you RedHat + if err := session.RequestPty("xterm", termHeight, termWidth, modes); err != nil { + return "", err + } + + output, err := session.CombinedOutput(command) + + return string(output), err +} + +func (client *NativeClient) Start(command string) (io.ReadCloser, io.ReadCloser, error) { + conn, session, err := client.session(command) + if err != nil { + return nil, nil, err + } + + stdout, err := session.StdoutPipe() + if err != nil { + return nil, nil, err + } + stderr, err := session.StderrPipe() + if err != nil { + return nil, nil, err + } + if err := session.Start(command); err != nil { + return nil, nil, err + } + + client.openClient = conn + client.openSession = session + return ioutil.NopCloser(stdout), ioutil.NopCloser(stderr), nil +} + +func (client *NativeClient) Wait() error { + err := client.openSession.Wait() + if err != nil { + return err + } + + _ = client.openSession.Close() + + err = client.openClient.Close() + if err != nil { + return err + } + + client.openSession = nil + client.openClient = nil + return nil +} + +func (client *NativeClient) Shell(args ...string) error { + var ( + termWidth, termHeight int + ) + conn, err := ssh.Dial("tcp", net.JoinHostPort(client.Hostname, strconv.Itoa(client.Port)), &client.Config) + if err != nil { + return err + } + defer closeConn(conn) + + session, err := conn.NewSession() + if err != nil { + return err + } + + defer session.Close() + + session.Stdout = os.Stdout + session.Stderr = os.Stderr + session.Stdin = os.Stdin + + modes := ssh.TerminalModes{ + ssh.ECHO: 1, + } + + fd := os.Stdin.Fd() + + if term.IsTerminal(fd) { + oldState, err := term.MakeRaw(fd) + if err != nil { + return err + } + + defer term.RestoreTerminal(fd, oldState) + + winsize, err := term.GetWinsize(fd) + if err != nil { + termWidth = 80 + termHeight = 24 + } else { + termWidth = int(winsize.Width) + termHeight = int(winsize.Height) + } + } + + if err := session.RequestPty("xterm", termHeight, termWidth, modes); err != nil { + return err + } + + if len(args) == 0 { + if err := session.Shell(); err != nil { + return err + } + if err := session.Wait(); err != nil { + return err + } + } else { + if err := session.Run(strings.Join(args, " ")); err != nil { + return err + } + } + return nil +} + +func NewExternalClient(sshBinaryPath, user, host string, port int, auth *Auth) (*ExternalClient, error) { + client := &ExternalClient{ + BinaryPath: sshBinaryPath, + } + + args := append(baseSSHArgs, fmt.Sprintf("%s@%s", user, host)) + + // If no identities are explicitly provided, also look at the identities + // offered by ssh-agent + if len(auth.Keys) > 0 { + args = append(args, "-o", "IdentitiesOnly=yes") + } + + // Specify which private keys to use to authorize the SSH request. + for _, privateKeyPath := range auth.Keys { + if privateKeyPath != "" { + // Check each private key before use it + fi, err := os.Stat(privateKeyPath) + if err != nil { + // Abort if key not accessible + return nil, err + } + if runtime.GOOS != "windows" { + mode := fi.Mode() + log.Debugf("Using SSH private key: %s (%s)", privateKeyPath, mode) + // Private key file should have strict permissions + perm := mode.Perm() + if perm&0400 == 0 { + return nil, fmt.Errorf("'%s' is not readable", privateKeyPath) + } + if perm&0077 != 0 { + return nil, fmt.Errorf("permissions %#o for '%s' are too open", perm, privateKeyPath) + } + } + args = append(args, "-i", privateKeyPath) + } + } + + // Set which port to use for SSH. + args = append(args, "-p", fmt.Sprintf("%d", port)) + + client.BaseArgs = args + + return client, nil +} + +func getSSHCmd(binaryPath string, args ...string) *exec.Cmd { + return exec.Command(binaryPath, args...) +} + +func (client *ExternalClient) Output(command string) (string, error) { + args := append(client.BaseArgs, command) + cmd := getSSHCmd(client.BinaryPath, args...) + output, err := cmd.CombinedOutput() + return string(output), err +} + +func (client *ExternalClient) Shell(args ...string) error { + args = append(client.BaseArgs, args...) + cmd := getSSHCmd(client.BinaryPath, args...) + + log.Debug(cmd) + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + return cmd.Run() +} + +func (client *ExternalClient) Start(command string) (io.ReadCloser, io.ReadCloser, error) { + args := append(client.BaseArgs, command) + cmd := getSSHCmd(client.BinaryPath, args...) + + log.Debug(cmd) + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + if closeErr := stdout.Close(); closeErr != nil { + return nil, nil, fmt.Errorf("%s, %s", err, closeErr) + } + return nil, nil, err + } + if err := cmd.Start(); err != nil { + stdOutCloseErr := stdout.Close() + stdErrCloseErr := stderr.Close() + if stdOutCloseErr != nil || stdErrCloseErr != nil { + return nil, nil, fmt.Errorf("%s, %s, %s", + err, stdOutCloseErr, stdErrCloseErr) + } + return nil, nil, err + } + + client.cmd = cmd + return stdout, stderr, nil +} + +func (client *ExternalClient) Wait() error { + err := client.cmd.Wait() + client.cmd = nil + return err +} + +func closeConn(c io.Closer) { + err := c.Close() + if err != nil { + log.Debugf("Error closing SSH Client: %s", err) + } +} diff --git a/libmachine/ssh/client_test.go b/libmachine/ssh/client_test.go new file mode 100644 index 0000000000..5610c1c0e6 --- /dev/null +++ b/libmachine/ssh/client_test.go @@ -0,0 +1,106 @@ +package ssh + +import ( + "fmt" + "io/ioutil" + "os" + "runtime" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetSSHCmdArgs(t *testing.T) { + cases := []struct { + binaryPath string + args []string + expectedArgs []string + }{ + { + binaryPath: "/usr/local/bin/ssh", + args: []string{ + "docker@localhost", + "apt-get install -y htop", + }, + expectedArgs: []string{ + "/usr/local/bin/ssh", + "docker@localhost", + "apt-get install -y htop", + }, + }, + { + binaryPath: "C:\\Program Files\\Git\\bin\\ssh.exe", + args: []string{ + "docker@localhost", + "sudo /usr/bin/sethostname foobar && echo 'foobar' | sudo tee /var/lib/boot2docker/etc/hostname", + }, + expectedArgs: []string{ + "C:\\Program Files\\Git\\bin\\ssh.exe", + "docker@localhost", + "sudo /usr/bin/sethostname foobar && echo 'foobar' | sudo tee /var/lib/boot2docker/etc/hostname", + }, + }, + } + + for _, c := range cases { + cmd := getSSHCmd(c.binaryPath, c.args...) + assert.Equal(t, cmd.Args, c.expectedArgs) + } +} + +func TestNewExternalClient(t *testing.T) { + keyFile, err := ioutil.TempFile("", "docker-machine-tests-dummy-private-key") + if err != nil { + t.Fatal(err) + } + defer keyFile.Close() + + keyFilename := keyFile.Name() + defer os.Remove(keyFilename) + + cases := []struct { + sshBinaryPath string + user string + host string + port int + auth *Auth + perm os.FileMode + expectedError string + skipOS string + }{ + { + auth: &Auth{Keys: []string{"/tmp/private-key-not-exist"}}, + expectedError: "stat /tmp/private-key-not-exist: no such file or directory", + skipOS: "none", + }, + { + auth: &Auth{Keys: []string{keyFilename}}, + perm: 0400, + skipOS: "windows", + }, + { + auth: &Auth{Keys: []string{keyFilename}}, + perm: 0100, + expectedError: fmt.Sprintf("'%s' is not readable", keyFilename), + skipOS: "windows", + }, + { + auth: &Auth{Keys: []string{keyFilename}}, + perm: 0644, + expectedError: fmt.Sprintf("permissions 0644 for '%s' are too open", keyFilename), + skipOS: "windows", + }, + } + + for _, c := range cases { + if runtime.GOOS != c.skipOS { + keyFile.Chmod(c.perm) + _, err := NewExternalClient(c.sshBinaryPath, c.user, c.host, c.port, c.auth) + if c.expectedError != "" { + assert.EqualError(t, err, c.expectedError) + } else { + assert.Equal(t, err, nil) + } + } + } +} diff --git a/libmachine/ssh/keys.go b/libmachine/ssh/keys.go new file mode 100644 index 0000000000..4d806419c1 --- /dev/null +++ b/libmachine/ssh/keys.go @@ -0,0 +1,124 @@ +package ssh + +import ( + "crypto/md5" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "fmt" + "io" + "os" + "runtime" + + gossh "golang.org/x/crypto/ssh" +) + +var ( + ErrKeyGeneration = errors.New("Unable to generate key") + ErrValidation = errors.New("Unable to validate key") + ErrPublicKey = errors.New("Unable to convert public key") + ErrUnableToWriteFile = errors.New("Unable to write file") +) + +type KeyPair struct { + PrivateKey []byte + PublicKey []byte +} + +// NewKeyPair generates a new SSH keypair +// This will return a private & public key encoded as DER. +func NewKeyPair() (keyPair *KeyPair, err error) { + priv, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, ErrKeyGeneration + } + + if err := priv.Validate(); err != nil { + return nil, ErrValidation + } + + privDer := x509.MarshalPKCS1PrivateKey(priv) + + pubSSH, err := gossh.NewPublicKey(&priv.PublicKey) + if err != nil { + return nil, ErrPublicKey + } + + return &KeyPair{ + PrivateKey: privDer, + PublicKey: gossh.MarshalAuthorizedKey(pubSSH), + }, nil +} + +// WriteToFile writes keypair to files +func (kp *KeyPair) WriteToFile(privateKeyPath string, publicKeyPath string) error { + files := []struct { + File string + Type string + Value []byte + }{ + { + File: privateKeyPath, + Value: pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Headers: nil, Bytes: kp.PrivateKey}), + }, + { + File: publicKeyPath, + Value: kp.PublicKey, + }, + } + + for _, v := range files { + f, err := os.Create(v.File) + if err != nil { + return ErrUnableToWriteFile + } + + if _, err := f.Write(v.Value); err != nil { + return ErrUnableToWriteFile + } + + // windows does not support chmod + switch runtime.GOOS { + case "darwin", "freebsd", "linux", "openbsd": + if err := f.Chmod(0600); err != nil { + return err + } + } + } + + return nil +} + +// Fingerprint calculates the fingerprint of the public key +func (kp *KeyPair) Fingerprint() string { + b, _ := base64.StdEncoding.DecodeString(string(kp.PublicKey)) + h := md5.New() + + io.WriteString(h, string(b)) + + return fmt.Sprintf("%x", h.Sum(nil)) +} + +// GenerateSSHKey generates SSH keypair based on path of the private key +// The public key would be generated to the same path with ".pub" added +func GenerateSSHKey(path string) error { + if _, err := os.Stat(path); err != nil { + if !os.IsNotExist(err) { + return fmt.Errorf("Desired directory for SSH keys does not exist: %s", err) + } + + kp, err := NewKeyPair() + if err != nil { + return fmt.Errorf("Error generating key pair: %s", err) + } + + if err := kp.WriteToFile(path, fmt.Sprintf("%s.pub", path)); err != nil { + return fmt.Errorf("Error writing keys to file(s): %s", err) + } + } + + return nil +} diff --git a/libmachine/ssh/keys_test.go b/libmachine/ssh/keys_test.go new file mode 100644 index 0000000000..07e3b8321b --- /dev/null +++ b/libmachine/ssh/keys_test.go @@ -0,0 +1,21 @@ +package ssh + +import ( + "encoding/pem" + "testing" +) + +func TestNewKeyPair(t *testing.T) { + pair, err := NewKeyPair() + if err != nil { + t.Fatal(err) + } + + if privPem := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Headers: nil, Bytes: pair.PrivateKey}); len(privPem) == 0 { + t.Fatal("No PEM returned") + } + + if fingerprint := pair.Fingerprint(); len(fingerprint) == 0 { + t.Fatal("Unable to generate fingerprint") + } +} diff --git a/libmachine/ssh/ssh_test.go b/libmachine/ssh/ssh_test.go new file mode 100644 index 0000000000..8722dc72a0 --- /dev/null +++ b/libmachine/ssh/ssh_test.go @@ -0,0 +1,28 @@ +package ssh + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestGenerateSSHKey(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + t.Fatal(err) + } + + filename := filepath.Join(tmpDir, "sshkey") + + if err := GenerateSSHKey(filename); err != nil { + t.Fatal(err) + } + + if _, err := os.Stat(filename); err != nil { + t.Fatalf("expected ssh key at %s", filename) + } + + // cleanup + _ = os.RemoveAll(tmpDir) +} diff --git a/libmachine/ssh/sshtest/fake_client.go b/libmachine/ssh/sshtest/fake_client.go new file mode 100644 index 0000000000..2b333b5560 --- /dev/null +++ b/libmachine/ssh/sshtest/fake_client.go @@ -0,0 +1,31 @@ +package sshtest + +import "io" + +type CmdResult struct { + Out string + Err error +} + +type FakeClient struct { + ActivatedShell []string + Outputs map[string]CmdResult +} + +func (fsc *FakeClient) Output(command string) (string, error) { + outerr := fsc.Outputs[command] + return outerr.Out, outerr.Err +} + +func (fsc *FakeClient) Shell(args ...string) error { + fsc.ActivatedShell = args + return nil +} + +func (fsc *FakeClient) Start(command string) (io.ReadCloser, io.ReadCloser, error) { + return nil, nil, nil +} + +func (fsc *FakeClient) Wait() error { + return nil +} diff --git a/state/state.go b/libmachine/state/state.go similarity index 93% rename from state/state.go rename to libmachine/state/state.go index 18f95e1507..385a173be7 100644 --- a/state/state.go +++ b/libmachine/state/state.go @@ -12,6 +12,7 @@ const ( Stopping Starting Error + Timeout ) var states = []string{ @@ -23,13 +24,13 @@ var states = []string{ "Stopping", "Starting", "Error", + "Timeout", } // Given a State type, returns its string representation func (s State) String() string { if int(s) >= 0 && int(s) < len(states) { return states[s] - } else { - return "" } + return "" } diff --git a/state/state_test.go b/libmachine/state/state_test.go similarity index 100% rename from state/state_test.go rename to libmachine/state/state_test.go diff --git a/libmachine/swarm/swarm.go b/libmachine/swarm/swarm.go new file mode 100644 index 0000000000..ee45288390 --- /dev/null +++ b/libmachine/swarm/swarm.go @@ -0,0 +1,22 @@ +package swarm + +const ( + DiscoveryServiceEndpoint = "https://discovery-stage.hub.docker.com/v1" +) + +type Options struct { + IsSwarm bool + Address string + Discovery string + Agent bool + Master bool + Host string + Image string + Strategy string + Heartbeat int + Overcommit float64 + ArbitraryFlags []string + ArbitraryJoinFlags []string + Env []string + IsExperimental bool +} diff --git a/libmachine/version/version.go b/libmachine/version/version.go new file mode 100644 index 0000000000..3cacffdb0c --- /dev/null +++ b/libmachine/version/version.go @@ -0,0 +1,11 @@ +package version + +var ( + // APIVersion dictates which version of the libmachine API this is. + APIVersion = 1 + + // ConfigVersion dictates which version of the config.json format is + // used. It needs to be bumped if there is a breaking change, and + // therefore migration, introduced to the config file format. + ConfigVersion = 3 +) diff --git a/libmachine/versioncmp/compare.go b/libmachine/versioncmp/compare.go new file mode 100644 index 0000000000..2df82cef6e --- /dev/null +++ b/libmachine/versioncmp/compare.go @@ -0,0 +1,121 @@ +// Package versioncmp provides functions for comparing version strings. +// +// Version strings are dot-separated integers with an optional +// pre-release suffix. A pre-release suffix is an arbitrary string with a +// leading dash character. All functions ignore these suffixes, so "1.2" and +// "1.2-rc" are considered equivalent. +package versioncmp + +import ( + "strconv" + "strings" +) + +const ( + rcString = "-rc" + ceEdition = "-ce" +) + +// compare compares two versions of Docker to decipher which came first. +// +// compare returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise. +func compare(v1, v2 string) int { + // Replace RC string with "." to make the RC number appear as simply + // another sub-version. + v1 = strings.Replace(v1, rcString, ".", -1) + v2 = strings.Replace(v2, rcString, ".", -1) + + // All releases before the community edition (differentiated by + // presence of the "ce" string in the version string) are "less than" + // any community edition release (first occurring in March 2017). + if strings.Contains(v1, ceEdition) && !strings.Contains(v2, ceEdition) { + return 1 + } + if !strings.Contains(v1, ceEdition) && strings.Contains(v2, ceEdition) { + return -1 + } + + // Without this tag, both are pre-CE versions. + if !strings.Contains(v1, ceEdition) && !strings.Contains(v2, ceEdition) { + return compareNumeric(v1, v2) + } + + return compareCE(v1, v2) +} + +// compareCE ("Community Edition") will differentiate between versions of +// Docker that use the versioning scheme +// {{release-year}}.{{release-month}}-{{ce|ee}}-{{rcnum|""}} +// +// This will be every release after 1.13.1. +func compareCE(v1, v2 string) int { + return compareNumeric( + strings.Replace(v1, ceEdition, "", -1), + strings.Replace(v2, ceEdition, "", -1), + ) +} + +// compareNumeric compares two version that use pre-17.03 Docker. +// +// Non-numeric segments in either argument are considered equal, so +// compare("1.a", "1.b") == 0, but compare("2.a", "1.b") == 1. +func compareNumeric(v1, v2 string) int { + if n := strings.IndexByte(v1, '-'); n != -1 { + v1 = v1[:n] + } + if n := strings.IndexByte(v2, '-'); n != -1 { + v2 = v2[:n] + } + var ( + currTab = strings.Split(v1, ".") + otherTab = strings.Split(v2, ".") + ) + + max := len(currTab) + if len(otherTab) > max { + max = len(otherTab) + } + for i := 0; i < max; i++ { + var currInt, otherInt int + + if len(currTab) > i { + currInt, _ = strconv.Atoi(currTab[i]) + } + if len(otherTab) > i { + otherInt, _ = strconv.Atoi(otherTab[i]) + } + if currInt > otherInt { + return 1 + } + if otherInt > currInt { + return -1 + } + } + return 0 +} + +// LessThan checks if a version is less than another. +func LessThan(v, other string) bool { + return compare(v, other) == -1 +} + +// LessThanOrEqualTo checks if a version is less than or equal to another. +func LessThanOrEqualTo(v, other string) bool { + return compare(v, other) <= 0 +} + +// GreaterThan checks if a version is greater than another. +func GreaterThan(v, other string) bool { + return compare(v, other) == 1 +} + +// GreaterThanOrEqualTo checks if a version is greater than or equal to +// another. +func GreaterThanOrEqualTo(v, other string) bool { + return compare(v, other) >= 0 +} + +// Equal checks if a version is equal to another. +func Equal(v, other string) bool { + return compare(v, other) == 0 +} diff --git a/libmachine/versioncmp/compare_test.go b/libmachine/versioncmp/compare_test.go new file mode 100644 index 0000000000..cd7a9d907f --- /dev/null +++ b/libmachine/versioncmp/compare_test.go @@ -0,0 +1,237 @@ +package versioncmp + +import ( + "testing" +) + +func TestCompare(t *testing.T) { + cases := []struct { + v1, v2 string + want int + }{ + {"1.12", "1.12", 0}, + {"1.0.0", "1", 0}, + {"1", "1.0.0", 0}, + {"1.05.00.0156", "1.0.221.9289", 1}, + {"1", "1.0.1", -1}, + {"1.0.1", "1", 1}, + {"1.0.1", "1.0.2", -1}, + {"1.0.2", "1.0.3", -1}, + {"1.0.3", "1.1", -1}, + {"1.1", "1.1.1", -1}, + {"1.a", "1.b", 0}, + {"1.a", "2.b", -1}, + {"1.1", "1.1.0", 0}, + {"1.1.1", "1.1.2", -1}, + {"1.1.2", "1.2", -1}, + {"1.12.1", "1.13.0-rc1", -1}, + {"1.13.0-rc1", "1.13.0-rc2", -1}, + {"1.13.0-rc1", "1.13.1-rc1", -1}, + {"17.03.0-ce", "17.03.0-ce", 0}, + {"17.03.1-ce", "17.03.2-ce", -1}, + {"17.06.6-ce", "17.09.2-ce", -1}, + {"17.03.0-ce", "17.06.0-ce", -1}, + {"17.03.0-ce-rc2", "17.03.0-ce-rc1", 1}, + {"17.03.0-ce-rc1", "18.03.0-ce-rc1", -1}, + {"17.06.0-ce-rc2", "1.12.0", 1}, + {"1.12.0", "17.06.0-ce-rc2", -1}, + } + + for _, tc := range cases { + if got := compare(tc.v1, tc.v2); got != tc.want { + t.Errorf("compare(%q, %q) == %d, want %d", tc.v1, tc.v2, got, tc.want) + } + } +} + +func TestLessThan(t *testing.T) { + cases := []struct { + v1, v2 string + want bool + }{ + {"1.12", "1.12", false}, + {"1.0.0", "1", false}, + {"1", "1.0.0", false}, + {"1.05.00.0156", "1.0.221.9289", false}, + {"1", "1.0.1", true}, + {"1.0.1", "1", false}, + {"1.0.1", "1.0.2", true}, + {"1.0.2", "1.0.3", true}, + {"1.0.3", "1.1", true}, + {"1.1", "1.1.1", true}, + {"1.a", "1.b", false}, + {"1.a", "2.b", true}, + {"1.1", "1.1.0", false}, + {"1.1.1", "1.1.2", true}, + {"1.1.2", "1.2", true}, + {"1.12.1", "1.13.0-rc1", true}, + {"1.13.0-rc1", "1.13.0-rc2", true}, + {"1.13.0-rc1", "1.13.1-rc1", true}, + {"17.03.0-ce", "17.03.0-ce", false}, + {"17.03.1-ce", "17.03.2-ce", true}, + {"17.06.6-ce", "17.09.2-ce", true}, + {"17.03.0-ce", "17.06.0-ce", true}, + {"17.03.0-ce-rc2", "17.03.0-ce-rc1", false}, + {"17.03.0-ce-rc1", "18.03.0-ce-rc1", true}, + {"17.06.0-ce", "1.12.0", false}, + } + for _, tc := range cases { + if got := LessThan(tc.v1, tc.v2); got != tc.want { + t.Errorf("LessThan(%q, %q) == %v, want %v", tc.v1, tc.v2, got, tc.want) + } + } +} + +func TestLessThanOrEqualTo(t *testing.T) { + cases := []struct { + v1, v2 string + want bool + }{ + {"1.12", "1.12", true}, + {"1.0.0", "1", true}, + {"1", "1.0.0", true}, + {"1.05.00.0156", "1.0.221.9289", false}, + {"1", "1.0.1", true}, + {"1.0.1", "1", false}, + {"1.0.1", "1.0.2", true}, + {"1.0.2", "1.0.3", true}, + {"1.0.3", "1.1", true}, + {"1.1", "1.1.1", true}, + {"1.a", "1.b", true}, + {"1.a", "2.b", true}, + {"1.1", "1.1.0", true}, + {"1.1.1", "1.1.2", true}, + {"1.1.2", "1.2", true}, + {"1.12.1", "1.13.0-rc1", true}, + {"1.13.0-rc1", "1.13.0-rc2", true}, + {"1.13.0-rc1", "1.13.1-rc1", true}, + {"17.03.0-ce", "17.03.0-ce", true}, + {"17.03.1-ce", "17.03.2-ce", true}, + {"17.06.6-ce", "17.09.2-ce", true}, + {"17.03.0-ce", "17.06.0-ce", true}, + {"17.03.0-ce-rc2", "17.03.0-ce-rc1", false}, + {"17.03.0-ce-rc1", "18.03.0-ce-rc1", true}, + {"17.06.0-ce", "1.12.0", false}, + } + for _, tc := range cases { + if got := LessThanOrEqualTo(tc.v1, tc.v2); got != tc.want { + t.Errorf("LessThanOrEqualTo(%q, %q) == %v, want %v", tc.v1, tc.v2, got, tc.want) + } + } +} + +func TestGreaterThan(t *testing.T) { + cases := []struct { + v1, v2 string + want bool + }{ + {"1.12", "1.12", false}, + {"1.0.0", "1", false}, + {"1", "1.0.0", false}, + {"1.05.00.0156", "1.0.221.9289", true}, + {"1", "1.0.1", false}, + {"1.0.1", "1", true}, + {"1.0.1", "1.0.2", false}, + {"1.0.2", "1.0.3", false}, + {"1.0.3", "1.1", false}, + {"1.1", "1.1.1", false}, + {"1.a", "1.b", false}, + {"1.a", "2.b", false}, + {"1.1", "1.1.0", false}, + {"1.1.1", "1.1.2", false}, + {"1.1.2", "1.2", false}, + {"1.12.1", "1.13.0-rc1", false}, + {"1.13.0-rc1", "1.13.0-rc2", false}, + {"1.13.0-rc1", "1.13.1-rc1", false}, + {"17.03.0-ce", "17.03.0-ce", false}, + {"17.03.1-ce", "17.03.2-ce", false}, + {"17.06.6-ce", "17.09.2-ce", false}, + {"17.03.0-ce", "17.06.0-ce", false}, + {"17.03.0-ce-rc2", "17.03.0-ce-rc1", true}, + {"17.03.0-ce-rc1", "18.03.0-ce-rc1", false}, + {"17.06.0-ce", "1.12.0", true}, + } + for _, tc := range cases { + if got := GreaterThan(tc.v1, tc.v2); got != tc.want { + t.Errorf("GreaterThan(%q, %q) == %v, want %v", tc.v1, tc.v2, got, tc.want) + } + } +} + +func TestGreaterThanOrEqualTo(t *testing.T) { + cases := []struct { + v1, v2 string + want bool + }{ + {"1.12", "1.12", true}, + {"1.0.0", "1", true}, + {"1", "1.0.0", true}, + {"1.05.00.0156", "1.0.221.9289", true}, + {"1", "1.0.1", false}, + {"1.0.1", "1", true}, + {"1.0.1", "1.0.2", false}, + {"1.0.2", "1.0.3", false}, + {"1.0.3", "1.1", false}, + {"1.1", "1.1.1", false}, + {"1.a", "1.b", true}, + {"1.a", "2.b", false}, + {"1.1", "1.1.0", true}, + {"1.1.1", "1.1.2", false}, + {"1.1.2", "1.2", false}, + {"1.12.1", "1.13.0-rc1", false}, + {"1.13.0-rc1", "1.13.0-rc2", false}, + {"1.13.0-rc1", "1.13.1-rc1", false}, + {"17.03.0-ce", "17.03.0-ce", true}, + {"17.03.1-ce", "17.03.2-ce", false}, + {"17.06.6-ce", "17.09.2-ce", false}, + {"17.03.0-ce", "17.06.0-ce", false}, + {"17.03.0-ce-rc2", "17.03.0-ce-rc1", true}, + {"17.03.0-ce-rc1", "18.03.0-ce-rc1", false}, + {"17.06.0-ce", "1.12.0", true}, + } + for _, tc := range cases { + if got := GreaterThanOrEqualTo(tc.v1, tc.v2); got != tc.want { + t.Errorf("GreaterThanOrEqualTo(%q, %q) == %v, want %v", tc.v1, tc.v2, got, tc.want) + } + } +} + +func TestEqual(t *testing.T) { + cases := []struct { + v1, v2 string + want bool + }{ + {"1.12", "1.12", true}, + {"1.0.0", "1", true}, + {"1", "1.0.0", true}, + {"1.05.00.0156", "1.0.221.9289", false}, + {"1", "1.0.1", false}, + {"1.0.1", "1", false}, + {"1.0.1", "1.0.2", false}, + {"1.0.2", "1.0.3", false}, + {"1.0.3", "1.1", false}, + {"1.1", "1.1.1", false}, + {"1.a", "1.b", true}, + {"1.a", "2.b", false}, + {"1.1", "1.1.0", true}, + {"1.1.1", "1.1.2", false}, + {"1.1.2", "1.2", false}, + {"1.12.1", "1.13.0-rc1", false}, + {"1.13.0-rc1", "1.13.0-rc2", false}, + {"1.13.0-rc1", "1.13.1-rc1", false}, + {"17.03.0-ce", "17.03.0-ce", true}, + {"17.03.1-ce", "17.03.2-ce", false}, + {"17.06.6-ce", "17.09.2-ce", false}, + {"17.03.0-ce", "17.06.0-ce", false}, + {"17.03.0-ce-rc2", "17.03.0-ce-rc1", false}, + {"17.03.0-ce-rc1", "18.03.0-ce-rc1", false}, + {"17.06.0-ce-rc2", "1.12.0", false}, + {"1.12.0", "17.06.0-ce-rc2", false}, + {"17.06.0-ce", "1.12.0", false}, + } + for _, tc := range cases { + if got := Equal(tc.v1, tc.v2); got != tc.want { + t.Errorf("Equal(%q, %q) == %v, want %v", tc.v1, tc.v2, got, tc.want) + } + } +} diff --git a/log.go b/log.go deleted file mode 100644 index cdbbd4408f..0000000000 --- a/log.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import ( - "os" - - log "github.com/Sirupsen/logrus" -) - -func initLogging(lvl log.Level) { - log.SetOutput(os.Stderr) - log.SetLevel(lvl) -} diff --git a/main.go b/main.go deleted file mode 100644 index f06d0ae1ad..0000000000 --- a/main.go +++ /dev/null @@ -1,129 +0,0 @@ -package main - -import ( - "os" - "path" - "path/filepath" - - log "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/machine/utils" -) - -func before(c *cli.Context) error { - caCertPath := c.GlobalString("tls-ca-cert") - caKeyPath := c.GlobalString("tls-ca-key") - clientCertPath := c.GlobalString("tls-client-cert") - clientKeyPath := c.GlobalString("tls-client-key") - - org := utils.GetUsername() - bits := 2048 - - if _, err := os.Stat(utils.GetMachineDir()); err != nil { - if os.IsNotExist(err) { - if err := os.MkdirAll(utils.GetMachineDir(), 0700); err != nil { - log.Fatalf("Error creating machine config dir: %s", err) - } - } else { - log.Fatal(err) - } - } - - if _, err := os.Stat(caCertPath); os.IsNotExist(err) { - log.Infof("Creating CA: %s", caCertPath) - - // check if the key path exists; if so, error - if _, err := os.Stat(caKeyPath); err == nil { - log.Fatalf("The CA key already exists. Please remove it or specify a different key/cert.") - } - - if err := utils.GenerateCACertificate(caCertPath, caKeyPath, org, bits); err != nil { - log.Infof("Error generating CA certificate: %s", err) - } - } - - if _, err := os.Stat(clientCertPath); os.IsNotExist(err) { - log.Infof("Creating client certificate: %s", clientCertPath) - - if _, err := os.Stat(utils.GetMachineClientCertDir()); err != nil { - if os.IsNotExist(err) { - if err := os.Mkdir(utils.GetMachineClientCertDir(), 0700); err != nil { - log.Fatalf("Error creating machine client cert dir: %s", err) - } - } else { - log.Fatal(err) - } - } - - // check if the key path exists; if so, error - if _, err := os.Stat(clientKeyPath); err == nil { - log.Fatalf("The client key already exists. Please remove it or specify a different key/cert.") - } - - if err := utils.GenerateCert([]string{""}, clientCertPath, clientKeyPath, caCertPath, caKeyPath, org, bits); err != nil { - log.Fatalf("Error generating client certificate: %s", err) - } - - // copy ca.pem to client cert dir for docker client - if err := utils.CopyFile(caCertPath, filepath.Join(utils.GetMachineClientCertDir(), "ca.pem")); err != nil { - log.Fatalf("Error copying ca.pem to client cert dir: %s", err) - } - } - - return nil -} - -func main() { - for _, f := range os.Args { - if f == "-D" || f == "--debug" || f == "-debug" { - os.Setenv("DEBUG", "1") - initLogging(log.DebugLevel) - } - } - - app := cli.NewApp() - app.Name = path.Base(os.Args[0]) - app.Commands = Commands - app.CommandNotFound = cmdNotFound - app.Usage = "Create and manage machines running Docker." - app.Before = before - app.Version = VERSION - - app.Flags = []cli.Flag{ - cli.BoolFlag{ - Name: "debug, D", - Usage: "Enable debug mode", - }, - cli.StringFlag{ - EnvVar: "MACHINE_STORAGE_PATH", - Name: "storage-path", - Usage: "Configures storage path", - }, - cli.StringFlag{ - EnvVar: "MACHINE_TLS_CA_CERT", - Name: "tls-ca-cert", - Usage: "CA to verify remotes against", - Value: filepath.Join(utils.GetMachineDir(), "ca.pem"), - }, - cli.StringFlag{ - EnvVar: "MACHINE_TLS_CA_KEY", - Name: "tls-ca-key", - Usage: "Private key to generate certificates", - Value: filepath.Join(utils.GetMachineDir(), "key.pem"), - }, - cli.StringFlag{ - EnvVar: "MACHINE_TLS_CLIENT_CERT", - Name: "tls-client-cert", - Usage: "Client cert to use for TLS", - Value: filepath.Join(utils.GetMachineClientCertDir(), "cert.pem"), - }, - cli.StringFlag{ - EnvVar: "MACHINE_TLS_CLIENT_KEY", - Name: "tls-client-key", - Usage: "Private key used in client TLS auth", - Value: filepath.Join(utils.GetMachineClientCertDir(), "key.pem"), - }, - } - - app.Run(os.Args) -} diff --git a/mk/build.mk b/mk/build.mk new file mode 100644 index 0000000000..b3af995509 --- /dev/null +++ b/mk/build.mk @@ -0,0 +1,37 @@ +extension = $(patsubst windows,.exe,$(filter windows,$(1))) + +# Valid target combinations +VALID_OS_ARCH := "[darwin/amd64][linux/amd64][linux/arm][linux/arm64][openbsd/amd64][windows/amd64][windows/386]" + +os.darwin := Darwin +os.linux := Linux +os.openbsd := OpenBSD +os.windows := Windows + +arch.amd64 := x86_64 +arch.arm := armhf +arch.arm64 := aarch64 +arch.386 := i386 + +define gocross + $(if $(findstring [$(1)/$(2)],$(VALID_OS_ARCH)), \ + GOOS=$(1) GOARCH=$(2) CGO_ENABLED=0 \ + $(GO) build \ + -o $(PREFIX)/bin/$(PKG_NAME)-${os.$(1)}-${arch.$(2)}$(call extension,$(GOOS)) \ + -a $(VERBOSE_GO) -tags "static_build netgo $(BUILDTAGS)" -installsuffix netgo \ + -ldflags "$(GO_LDFLAGS) -extldflags -static" $(GO_GCFLAGS) ./cmd/docker-machine;) +endef + +build-clean: + rm -Rf $(PREFIX)/bin/* + +build-x: $(shell find . -type f -name '*.go') + $(foreach GOARCH,$(TARGET_ARCH),$(foreach GOOS,$(TARGET_OS),$(call gocross,$(GOOS),$(GOARCH)))) + +$(PREFIX)/bin/$(PKG_NAME)$(call extension,$(GOOS)): $(shell find . -type f -name '*.go') + $(GO) build \ + -o $@ \ + $(VERBOSE_GO) -tags "$(BUILDTAGS)" \ + -ldflags "$(GO_LDFLAGS)" $(GO_GCFLAGS) ./cmd/docker-machine + +build: $(PREFIX)/bin/$(PKG_NAME)$(call extension,$(GOOS)) diff --git a/mk/coverage.mk b/mk/coverage.mk new file mode 100644 index 0000000000..9e18ada666 --- /dev/null +++ b/mk/coverage.mk @@ -0,0 +1,45 @@ +# COVERAGE_OUTPUT dir is a temp dir (OSX/Linux compatible), unless explicitly specified through env COVERAGE_DIR +COVERAGE_OUTPUT := $(COVERAGE_DIR) +ifeq ($(COVERAGE_OUTPUT),) + COVERAGE_OUTPUT := $(shell mktemp -d 2>/dev/null || mktemp -d -t machine-coverage) +endif + +# Final cover file, html, and mode +COVERAGE_PROFILE := $(COVERAGE_OUTPUT)/profile.out +COVERAGE_HTML := $(COVERAGE_OUTPUT)/index.html +COVERAGE_MODE := set + +# Goveralls dependency +GOVERALLS_BIN := $(GOPATH)/bin/goveralls +GOVERALLS := $(shell [ -x $(GOVERALLS_BIN) ] && echo $(GOVERALLS_BIN) || echo '') + +# Generate coverage +coverage-generate: $(COVERAGE_PROFILE) + +# Send the results to coveralls +coverage-send: $(COVERAGE_PROFILE) + $(if $(GOVERALLS), , $(error Please install goveralls: go get github.com/mattn/goveralls)) + @$(GOVERALLS) -service travis-ci -coverprofile="$(COVERAGE_PROFILE)" + +# Generate html report +coverage-html: $(COVERAGE_HTML) + @open "$(COVERAGE_HTML)" + +# Serve over http - useful only if building remote/headless +coverage-serve: $(COVERAGE_HTML) + @cd "$(COVERAGE_OUTPUT)" && python -m SimpleHTTPServer 8000 + +# Clean up coverage coverage output +coverage-clean: + @rm -Rf "$(COVERAGE_OUTPUT)/coverage" + @rm -f "$(COVERAGE_HTML)" + @rm -f "$(COVERAGE_PROFILE)" + +$(COVERAGE_PROFILE): $(shell find . -type f -name '*.go') + @mkdir -p "$(COVERAGE_OUTPUT)/coverage" + @$(foreach PKG,$(PKGS), go test $(VERBOSE_GO) -tags "$(BUILDTAGS)" -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_OUTPUT)/coverage/`echo $(PKG) | tr "/" "-"`.cover" "$(PKG)";) + @echo "mode: $(COVERAGE_MODE)" > "$(COVERAGE_PROFILE)" + @grep -h -v "^mode:" "$(COVERAGE_OUTPUT)/coverage"/*.cover >> "$(COVERAGE_PROFILE)" + +$(COVERAGE_HTML): $(COVERAGE_PROFILE) + $(GO) tool cover -html="$(COVERAGE_PROFILE)" -o "$(COVERAGE_HTML)" diff --git a/mk/dev.mk b/mk/dev.mk new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mk/main.mk b/mk/main.mk new file mode 100644 index 0000000000..071ca40494 --- /dev/null +++ b/mk/main.mk @@ -0,0 +1,55 @@ +# Initialize version and gc flags +GO_LDFLAGS := -X `go list ./version`.GitCommit=`git rev-parse --short HEAD 2>/dev/null` +GO_GCFLAGS := + +# Full package list +PKGS := $(shell go list -tags "$(BUILDTAGS)" ./... | grep -v "/vendor/" | grep -v "/cmd") + +# Resolving binary dependencies for specific targets +GOLINT_BIN := $(GOPATH)/bin/golint +GOLINT := $(shell [ -x $(GOLINT_BIN) ] && echo $(GOLINT_BIN) || echo '') + +# Honor debug +ifeq ($(DEBUG),true) + # Disable function inlining and variable registerization + GO_GCFLAGS := -gcflags "-N -l" +else + # Turn of DWARF debugging information and strip the binary otherwise + GO_LDFLAGS := $(GO_LDFLAGS) -w -s +endif + +# Honor static +ifeq ($(STATIC),true) + # Append to the version + GO_LDFLAGS := $(GO_LDFLAGS) -extldflags -static +endif + +# Honor verbose +VERBOSE_GO := +GO := go +ifeq ($(VERBOSE),true) + VERBOSE_GO := -v +endif + +include mk/build.mk +include mk/coverage.mk +include mk/dev.mk +include mk/test.mk +include mk/validate.mk + +.all_build: build build-clean build-x +.all_coverage: coverage-generate coverage-html coverage-send coverage-serve coverage-clean +.all_release: release-checksum release +.all_test: test-short test-long test-integration +.all_validate: dco fmt vet lint + +default: build + +install: + cp $(PREFIX)/bin/$(PKG_NAME) /usr/local/bin + +clean: coverage-clean build-clean +test: dco fmt test-short lint vet +validate: dco fmt lint vet test-long + +.PHONY: .all_build .all_coverage .all_release .all_test .all_validate test build validate clean diff --git a/mk/test.mk b/mk/test.mk new file mode 100644 index 0000000000..c0c9df905e --- /dev/null +++ b/mk/test.mk @@ -0,0 +1,11 @@ +# Quick test. You can bypass long tests using: `if testing.Short() { t.Skip("Skipping in short mode.") }` +test-short: + $(GO) test $(VERBOSE_GO) -test.short -tags "$(BUILDTAGS)" $(PKGS) + +# Runs long tests also, plus race detection +test-long: + $(GO) test $(VERBOSE_GO) -race -tags "$(BUILDTAGS)" $(PKGS) + +test-integration: build + $(eval TESTSUITE=$(filter-out $@,$(MAKECMDGOALS))) + test/integration/run-bats.sh $(TESTSUITE) diff --git a/mk/validate.mk b/mk/validate.mk new file mode 100644 index 0000000000..4e386ec467 --- /dev/null +++ b/mk/validate.mk @@ -0,0 +1,20 @@ +# Validate DCO on all history +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) + +# XXX vendorized script miss exec bit, hence the gymnastic +# plus the path resolution... +# TODO migrate away from the shell script and have a make equivalent instead +dco: + @echo `bash $(current_dir)/../script/validate-dco` + +fmt: + @test -z "$$(gofmt -s -l . 2>&1 | grep -v vendor/ | tee /dev/stderr)" + +vet: + @test -z "$$(go vet $(PKGS) 2>&1 | tee /dev/stderr)" + +lint: + $(if $(GOLINT), , \ + $(error Please install golint: go get -u golang.org/x/lint/golint)) + @test -z "$$($(GOLINT) ./... 2>&1 | grep -v vendor/ | grep -v "cli/" | grep -v "amazonec2/" |grep -v "openstack/" |grep -v "softlayer/" | grep -v "should have comment" | tee /dev/stderr)" diff --git a/script/build b/script/build deleted file mode 100755 index 3718840bc6..0000000000 --- a/script/build +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -if [ -z "$1" ]; then - OS_PLATFORM_ARG=(-os="darwin linux windows") -else - OS_PLATFORM_ARG=($1) -fi - -if [ -z "$2" ]; then - OS_ARCH_ARG=(-arch="386 amd64") -else - OS_ARCH_ARG=($2) -fi - -rm -f docker-machine* -docker build -t docker-machine . -exec docker run --rm -v `pwd`:/go/src/github.com/docker/machine docker-machine gox "${OS_PLATFORM_ARG[@]}" "${OS_ARCH_ARG[@]}" -output="docker-machine_{{.OS}}-{{.Arch}}" diff --git a/script/build_in_container.sh b/script/build_in_container.sh new file mode 100755 index 0000000000..130bb84f6c --- /dev/null +++ b/script/build_in_container.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e + +DOCKER_IMAGE_NAME="docker-machine-build" +DOCKER_CONTAINER_NAME="docker-machine-build-container" + +if [[ $(docker ps -a | grep $DOCKER_CONTAINER_NAME) != "" ]]; then + docker rm -f $DOCKER_CONTAINER_NAME 2>/dev/null +fi + +docker build -t $DOCKER_IMAGE_NAME . + +docker run --name $DOCKER_CONTAINER_NAME \ + -e DEBUG \ + -e STATIC \ + -e VERBOSE \ + -e BUILDTAGS \ + -e PARALLEL \ + -e COVERAGE_DIR \ + -e TARGET_OS \ + -e TARGET_ARCH \ + -e PREFIX \ + -e TRAVIS_JOB_ID \ + -e TRAVIS_PULL_REQUEST \ + $DOCKER_IMAGE_NAME \ + make "$@" + +if [[ "$@" == *"clean"* ]] && [[ -d bin ]]; then + rm -Rf bin +fi + +docker cp $DOCKER_CONTAINER_NAME:/go/src/github.com/docker/machine/bin . diff --git a/script/release b/script/release deleted file mode 100755 index 4d6d49a778..0000000000 --- a/script/release +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -set -e -if [ -z "$1" ]; then - echo "Pass the version number as the first arg. E.g.: script/release 1.2.3" - exit 1 -fi -VERSION=$1 -if [ -z "$GITHUB_TOKEN" ]; then - echo "GITHUB_TOKEN must be set for github-release" - exit 1 -fi - -script/build -git tag $VERSION -git push --tags -docker run --rm -e GITHUB_TOKEN docker-machine github-release release \ - --user docker \ - --repo machine \ - --tag $VERSION \ - --name $VERSION \ - --description "" \ - --pre-release \ -for BINARY in docker-machine_*; do - docker run --rm -e GITHUB_TOKEN -v `pwd`:/go/src/github.com/docker/machine \ - docker-machine github-release upload \ - --user docker \ - --repo machine \ - --tag $VERSION \ - --name $BINARY \ - --file $BINARY -done - diff --git a/script/release.sh b/script/release.sh new file mode 100755 index 0000000000..e937b8cafb --- /dev/null +++ b/script/release.sh @@ -0,0 +1,260 @@ +#!/bin/bash + +GITHUB_USER=docker +GITHUB_REPO=machine +PROJECT_URL="git@github.com:${GITHUB_USER}/${GITHUB_REPO}" + +function usage { + echo "Usage: " + echo " GITHUB_TOKEN=XXXXX ${0} [X.Y.Z]" +} + +function display { + echo "🐳 $1" + echo +} + +function checkError { + if [[ "$?" -ne 0 ]]; then + echo "😡 $1" + exit 1 + fi +} + +function createMachine { + docker-machine rm -f release 2> /dev/null + docker-machine create -d virtualbox --virtualbox-cpu-count=2 --virtualbox-memory=2048 release +} + +if [[ -z "${GITHUB_TOKEN}" ]]; then + echo "GITHUB_TOKEN missing" + usage + exit 1 +fi + +VERSION=$1 + +if [[ -z "${VERSION}" ]]; then + echo "Missing version argument" + usage + exit 1 +fi + +if [[ ! "${VERSION}" =~ ^[0-9]\.[0-9]+(\.[0-9])+(-rc[1-9][0-9]*)?$ ]]; then + echo "Invalid version. It should look like 0.5.1, 0.6 or 0.5.1-rc2" + exit 1 +fi + +command -v git > /dev/null 2>&1 +checkError "You obviously need git, please consider installing it..." + +command -v github-release > /dev/null 2>&1 +checkError "github-release is not installed, go get -u github.com/aktau/github-release or check https://github.com/aktau/github-release, aborting." + +command -v openssl > /dev/null 2>&1 +checkError "You need openssl to generate binaries signature, brew install it, aborting." + +command -v docker-machine > /dev/null 2>&1 +checkError "You must have a docker-machine in your path" + +GITHUB_VERSION="v${VERSION}" +RELEASE_DIR="$(dirname "$(git rev-parse --show-toplevel)")/release-${VERSION}" +GITHUB_RELEASE_FILE="github-release-${VERSION}.md" + +LAST_RELEASE_VERSION=$(git describe --tags $(git rev-list --tags --max-count=1)) +checkError "Unable to find current version tag" + +display "Starting release from ${LAST_RELEASE_VERSION} to ${GITHUB_VERSION} on ${PROJECT_URL} with token ${GITHUB_TOKEN}" +if [[ "${GITHUB_USER}" == "docker" ]]; then + display "THIS IS A REAL RELEASE, on OFFICIAL DOCKER REPO" +fi +while true; do + read -p "🐳 Do you want to proceed with this release? (y/n) > " yn + echo "" + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "😡 Please answer yes or no.";; + esac +done + +display "Checking machine 'release' status" +MACHINE_STATUS=$(docker-machine status release) +if [[ "$?" -ne 0 ]]; then + display "Machine 'release' does not exist, creating it" + createMachine +else + if [[ "${MACHINE_STATUS}" != "Running" ]]; then + display "Machine 'release' is not running, trying to start it" + docker-machine start release + docker-machine env release + if [[ "$?" -ne 0 ]]; then + display "Machine 'release' could not be started, removing and creating a fresh new one" + createMachine + fi + display "Loosing 5 seconds to the VirtualBox gods" + sleep 5 + fi +fi + +eval "$(docker-machine env release)" +checkError "Machine 'release' is in a weird state, aborting" + +if [[ -d "${RELEASE_DIR}" ]]; then + display "Cleaning up ${RELEASE_DIR}" + rm -rdf "${RELEASE_DIR}" + checkError "Can't clean up ${RELEASE_DIR}. You should do it manually and retry" +fi + +display "Cloning into ${RELEASE_DIR} from ${PROJECT_URL}" + +mkdir -p "${RELEASE_DIR}" +checkError "Can't create ${RELEASE_DIR}, aborting" +git clone -q "${PROJECT_URL}" "${RELEASE_DIR}" +checkError "Can't clone into ${RELEASE_DIR}, aborting" + +cd "${RELEASE_DIR}" + +display "Bump version number to ${VERSION}" + +# Why 'sed' and then 'mv' instead of 'sed -i'? BSD / GNU sed compatibility. +# Macs have BSD sed by default, Linux has GNU sed. See +# http://unix.stackexchange.com/questions/92895/how-to-achieve-portability-with-sed-i-in-place-editing +sed -e "s/Version = \".*\"$/Version = \"${VERSION}\"/g" version/version.go >version/version.go.new +checkError "Unable to change version in version/version.go" +mv -- version/version.go.new version/version.go + +git add version/version.go +git commit -q -m"Bump version to ${VERSION}" -s +checkError "Can't git commit the version upgrade, aborting" + +display "Building in-container style" +USE_CONTAINER=true make clean build validate build-x +checkError "Build error, aborting" + +display "Generating github release" +cp -f script/release/github-release-template.md "${GITHUB_RELEASE_FILE}" +checkError "Can't find github release template" +CONTRIBUTORS=$(git log "${LAST_RELEASE_VERSION}".. --format="%aN" --reverse | sort | uniq | awk '{printf "- %s\n", $0 }') +CHANGELOG=$(git log "${LAST_RELEASE_VERSION}".. --oneline | grep -v 'Merge pull request') + +CHECKSUM="" +rm -f sha256sum.txt md5sum.txt +for file in $(ls bin/docker-machine-*); do + SHA256=$(openssl dgst -sha256 < "${file}") + MD5=$(openssl dgst -md5 < "${file}") + LINE=$(printf "\n * **%s**\n * sha256 \`%s\`\n * md5 \`%s\`\n\n" "$(basename ${file})" "${SHA256}" "${MD5}") + CHECKSUM="${CHECKSUM}${LINE}" + echo "${SHA256} ${file:4}" >> sha256sum.txt + echo "${MD5} ${file:4}" >> md5sum.txt +done + +TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}") +echo "${TEMPLATE//\{\{VERSION\}\}/$GITHUB_VERSION}" > "${GITHUB_RELEASE_FILE}" +checkError "Couldn't replace [ ${GITHUB_VERSION} ]" + +TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}") +echo "${TEMPLATE//\{\{CHANGELOG\}\}/$CHANGELOG}" > "${GITHUB_RELEASE_FILE}" +checkError "Couldn't replace [ ${CHANGELOG} ]" + +TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}") +echo "${TEMPLATE//\{\{CONTRIBUTORS\}\}/$CONTRIBUTORS}" > "${GITHUB_RELEASE_FILE}" +checkError "Couldn't replace [ ${CONTRIBUTORS} ]" + +TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}") +echo "${TEMPLATE//\{\{CHECKSUM\}\}/$CHECKSUM}" > "${GITHUB_RELEASE_FILE}" +checkError "Couldn't replace [ ${CHECKSUM} ]" + +RELEASE_DOCUMENTATION="$(cat ${GITHUB_RELEASE_FILE})" + +display "Tagging and pushing tags" +git remote | grep -q remote.prod.url +if [[ "$?" -ne 0 ]]; then + display "Adding 'remote.prod.url' remote git url" + git remote add remote.prod.url "${PROJECT_URL}" +fi + +display "Checking if remote tag ${GITHUB_VERSION} already exists" +git ls-remote --tags 2> /dev/null | grep -q "${GITHUB_VERSION}" # returns 0 if found, 1 if not +if [[ "$?" -ne 1 ]]; then + display "Deleting previous tag ${GITHUB_VERSION}" + git tag -d "${GITHUB_VERSION}" &> /dev/null + git push -q origin :refs/tags/"${GITHUB_VERSION}" +else + echo "Tag ${GITHUB_VERSION} does not exist... yet" +fi + +display "Tagging release on github" +git tag "${GITHUB_VERSION}" +git push -q remote.prod.url "${GITHUB_VERSION}" +checkError "Could not push to remote url" + +display "Checking if release already exists" +github-release info \ + --security-token "${GITHUB_TOKEN}" \ + --user "${GITHUB_USER}" \ + --repo "${GITHUB_REPO}" \ + --tag "${GITHUB_VERSION}" > /dev/null 2>&1 + +if [[ "$?" -ne 1 ]]; then + display "Release already exists, cleaning it up" + github-release delete \ + --security-token "${GITHUB_TOKEN}" \ + --user "${GITHUB_USER}" \ + --repo "${GITHUB_REPO}" \ + --tag "${GITHUB_VERSION}" + checkError "Could not delete release, aborting" +fi + +display "Creating release on github" +github-release release \ + --security-token "${GITHUB_TOKEN}" \ + --user "${GITHUB_USER}" \ + --repo "${GITHUB_REPO}" \ + --tag "${GITHUB_VERSION}" \ + --name "${GITHUB_VERSION}" \ + --description "${RELEASE_DOCUMENTATION}" \ + --pre-release +checkError "Could not create release, aborting" + +display "Uploading binaries" +for file in $(ls bin/docker-machine-*); do + display "Uploading ${file}..." + github-release upload \ + --security-token "${GITHUB_TOKEN}" \ + --user "${GITHUB_USER}" \ + --repo "${GITHUB_REPO}" \ + --tag "${GITHUB_VERSION}" \ + --name "$(basename "${file}")" \ + --file "${file}" + if [[ "$?" -ne 0 ]]; then + display "Could not upload ${file}, continuing with others" + fi +done + +display "Uploading sha256sum.txt and md5sum.txt" +for file in sha256sum.txt md5sum.txt; do + display "Uploading ${file}..." + github-release upload \ + --security-token "${GITHUB_TOKEN}" \ + --user "${GITHUB_USER}" \ + --repo "${GITHUB_REPO}" \ + --tag "${GITHUB_VERSION}" \ + --name "$(basename "${file}")" \ + --file "${file}" + if [[ "$?" -ne 0 ]]; then + display "Could not upload ${file}, continuing with others" + fi +done + +git remote rm remote.prod.url + +rm ${GITHUB_RELEASE_FILE} + +echo "There is a couple of tasks your still need to do manually:" +echo " 1. Open the release notes created for you on github https://github.com/${GITHUB_USER}/${GITHUB_REPO}/releases/tag/${GITHUB_VERSION}, you'll have a chance to enhance commit details a bit" +echo " 2. Once you're happy with your release notes on github, copy the list of changes to the CHANGELOG.md" +echo " 3. Update the documentation branch" +echo " 4. Test the binaries linked from the github release page" +echo " 5. Change version/version.go to the next dev version" +echo " 6. Party !!" diff --git a/script/release/github-release-template.md b/script/release/github-release-template.md new file mode 100644 index 0000000000..3c7051fe05 --- /dev/null +++ b/script/release/github-release-template.md @@ -0,0 +1,49 @@ +## Installation + +If you're a Mac or Windows user, the [Docker Toolbox](https://www.docker.com/docker-toolbox) will install Docker Machine {{VERSION}} for you, alongside the latest versions of the Docker Engine, Compose and Kitematic. + +You can use the usual commands to install or upgrade: + +On OS X +```console +$ curl -L https://github.com/docker/machine/releases/download/{{VERSION}}/docker-machine-`uname -s`-`uname -m` >/usr/local/bin/docker-machine && \ + chmod +x /usr/local/bin/docker-machine +``` +On Linux +```console +$ curl -L https://github.com/docker/machine/releases/download/{{VERSION}}/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && + chmod +x /tmp/docker-machine && + sudo cp /tmp/docker-machine /usr/local/bin/docker-machine +``` +On Windows with git bash +```console +$ if [[ ! -d "$HOME/bin" ]]; then mkdir -p "$HOME/bin"; fi && \ +curl -L https://github.com/docker/machine/releases/download/{{VERSION}}/docker-machine-Windows-x86_64.exe > "$HOME/bin/docker-machine.exe" && \ +chmod +x "$HOME/bin/docker-machine.exe" +``` + +Otherwise, download one of the releases from the [release page](https://github.com/docker/machine/releases/) directly. + +See the install [docs](https://docs.docker.com/machine/install-machine/) for more install options and instructions. + +## Changelog + +*Edit the changelog below by hand* + +{{CHANGELOG}} + +## Thank You + +Thank you very much to our active users and contributors. If you have filed detailed bug reports, THANK YOU! +Please continue to do so if you encounter any issues. It's your hard work that makes Docker Machine better. + +The following authors contributed changes to this release: + +{{CONTRIBUTORS}} + +Great thanks to all of the above! We appreciate it. Keep up the great work! + +## Checksums + +{{CHECKSUM}} + diff --git a/script/run-integration-tests b/script/run-integration-tests deleted file mode 100755 index 6f3163c2b5..0000000000 --- a/script/run-integration-tests +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -godep go test -v ./_integration-test - diff --git a/script/test b/script/test deleted file mode 100755 index e9479e2945..0000000000 --- a/script/test +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -set -e -docker build -t docker-machine . -exec docker run --rm docker-machine go test -v -short ./... diff --git a/script/validate-git-marks b/script/validate-git-marks deleted file mode 100755 index 24f048425d..0000000000 --- a/script/validate-git-marks +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -IN_MARK=$(grep -r "^<<<<<<<" *) -if [ $? -eq 0 ]; then - echo "-- Git conflict marks have been found, please correct them :" - echo "$IN_MARK" - exit 1 -fi - -OUT_MARK=$(grep -r "^>>>>>>>" *) -if [ $? -eq 0 ]; then - echo "-- Git conflict marks have been found, please correct them :" - echo "$OUT_MARK" - exit 1 -fi - -SEPARATE_MARK=$(grep -r "^=======$" *) -if [ $? -eq 0 ]; then - echo "-- Git conflict marks have been found, please correct them :" - echo "$SEPARATE_MARK" - exit 1 -fi - -echo "-- Congratulations : no git conflict marks have been found !" diff --git a/script/validate-gofmt b/script/validate-gofmt deleted file mode 100755 index c565976b41..0000000000 --- a/script/validate-gofmt +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -source "$(dirname "$BASH_SOURCE")/.validate" - -IFS=$'\n' -files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps/' || true) ) -unset IFS - -badFiles=() -for f in "${files[@]}"; do - # we use "git show" here to validate that what's committed is formatted - if [ "$(git show "$VALIDATE_HEAD:$f" | gofmt -s -l)" ]; then - badFiles+=( "$f" ) - fi -done - -if [ ${#badFiles[@]} -eq 0 ]; then - echo 'Congratulations! All Go source files are properly formatted.' -else - { - echo "These files are not properly gofmt'd:" - for f in "${badFiles[@]}"; do - echo " - $f" - done - echo - echo 'Please reformat the above files using "gofmt -s -w" and commit the result.' - echo - } >&2 - false -fi diff --git a/ssh/ssh.go b/ssh/ssh.go deleted file mode 100644 index 080dd1236b..0000000000 --- a/ssh/ssh.go +++ /dev/null @@ -1,77 +0,0 @@ -package ssh - -import ( - "fmt" - "net" - "os" - "os/exec" - "strings" - - log "github.com/Sirupsen/logrus" -) - -func GetSSHCommand(host string, port int, user string, sshKey string, args ...string) *exec.Cmd { - - defaultSSHArgs := []string{ - "-o", "IdentitiesOnly=yes", - "-o", "StrictHostKeyChecking=no", - "-o", "UserKnownHostsFile=/dev/null", - "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." - "-p", fmt.Sprintf("%d", port), - "-i", sshKey, - fmt.Sprintf("%s@%s", user, host), - } - - sshArgs := append(defaultSSHArgs, args...) - cmd := exec.Command("ssh", sshArgs...) - cmd.Stderr = os.Stderr - - if os.Getenv("DEBUG") != "" { - cmd.Stdout = os.Stdout - } - - log.Debugf("executing: %v", strings.Join(cmd.Args, " ")) - - return cmd -} - -func GenerateSSHKey(path string) error { - if _, err := exec.LookPath("ssh-keygen"); err != nil { - return fmt.Errorf("ssh-keygen not found in the path, please install ssh-keygen") - } - - if _, err := os.Stat(path); err != nil { - if !os.IsNotExist(err) { - return err - } - - cmd := exec.Command("ssh-keygen", "-t", "rsa", "-N", "", "-f", path) - - if os.Getenv("DEBUG") != "" { - cmd.Stdout = os.Stdout - } - - cmd.Stderr = os.Stderr - log.Debugf("executing: %v %v\n", cmd.Path, strings.Join(cmd.Args, " ")) - - if err := cmd.Run(); err != nil { - return err - } - } - return nil -} - -func WaitForTCP(addr string) error { - for { - conn, err := net.Dial("tcp", addr) - if err != nil { - continue - } - defer conn.Close() - if _, err = conn.Read(make([]byte, 1)); err != nil { - continue - } - break - } - return nil -} diff --git a/store.go b/store.go deleted file mode 100644 index 235ea4a247..0000000000 --- a/store.go +++ /dev/null @@ -1,166 +0,0 @@ -package main - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - - log "github.com/Sirupsen/logrus" - "github.com/docker/machine/drivers" - "github.com/docker/machine/utils" -) - -// Store persists hosts on the filesystem -type Store struct { - Path string - CaCertPath string - PrivateKeyPath string -} - -func NewStore(rootPath string, caCert string, privateKey string) *Store { - if rootPath == "" { - rootPath = utils.GetMachineDir() - } - - return &Store{Path: rootPath, CaCertPath: caCert, PrivateKeyPath: privateKey} -} - -func (s *Store) Create(name string, driverName string, flags drivers.DriverOptions) (*Host, error) { - exists, err := s.Exists(name) - if err != nil { - return nil, err - } - if exists { - return nil, fmt.Errorf("Machine %s already exists", name) - } - - hostPath := filepath.Join(s.Path, name) - - host, err := NewHost(name, driverName, hostPath, s.CaCertPath, s.PrivateKeyPath) - if err != nil { - return host, err - } - if flags != nil { - if err := host.Driver.SetConfigFromFlags(flags); err != nil { - return host, err - } - } - - if err := host.Driver.PreCreateCheck(); err != nil { - return nil, err - } - - if err := os.MkdirAll(hostPath, 0700); err != nil { - return nil, err - } - - if err := host.SaveConfig(); err != nil { - return host, err - } - - if err := host.Create(name); err != nil { - return host, err - } - - if err := host.ConfigureAuth(); err != nil { - return host, err - } - - return host, nil -} - -func (s *Store) Remove(name string, force bool) error { - active, err := s.GetActive() - if err != nil { - return err - } - - if active != nil && active.Name == name { - if err := s.RemoveActive(); err != nil { - return err - } - } - - host, err := s.Load(name) - if err != nil { - return err - } - return host.Remove(force) -} - -func (s *Store) List() ([]Host, error) { - dir, err := ioutil.ReadDir(s.Path) - if err != nil && !os.IsNotExist(err) { - return nil, err - } - - hosts := []Host{} - - for _, file := range dir { - // don't load hidden dirs; used for configs - if file.IsDir() && strings.Index(file.Name(), ".") != 0 { - host, err := s.Load(file.Name()) - if err != nil { - log.Errorf("error loading host %q: %s", file.Name(), err) - continue - } - hosts = append(hosts, *host) - } - } - return hosts, nil -} - -func (s *Store) Exists(name string) (bool, error) { - _, err := os.Stat(filepath.Join(s.Path, name)) - if os.IsNotExist(err) { - return false, nil - } else if err == nil { - return true, nil - } - return false, err -} - -func (s *Store) Load(name string) (*Host, error) { - hostPath := filepath.Join(s.Path, name) - return LoadHost(name, hostPath) -} - -func (s *Store) GetActive() (*Host, error) { - hostName, err := ioutil.ReadFile(s.activePath()) - if os.IsNotExist(err) { - return nil, nil - } else if err != nil { - return nil, err - } - return s.Load(string(hostName)) -} - -func (s *Store) IsActive(host *Host) (bool, error) { - active, err := s.GetActive() - if err != nil { - return false, err - } - if active == nil { - return false, nil - } - return active.Name == host.Name, nil -} - -func (s *Store) SetActive(host *Host) error { - if err := os.MkdirAll(filepath.Dir(s.activePath()), 0700); err != nil { - return err - } - return ioutil.WriteFile(s.activePath(), []byte(host.Name), 0600) -} - -func (s *Store) RemoveActive() error { - return os.Remove(s.activePath()) -} - -// activePath returns the path to the file that stores the name of the -// active host -func (s *Store) activePath() string { - return filepath.Join(s.Path, ".active") -} diff --git a/store_test.go b/store_test.go deleted file mode 100644 index ea9bafa788..0000000000 --- a/store_test.go +++ /dev/null @@ -1,235 +0,0 @@ -package main - -import ( - "os" - "path" - "path/filepath" - "testing" - - _ "github.com/docker/machine/drivers/none" - "github.com/docker/machine/utils" -) - -type DriverOptionsMock struct { - Data map[string]interface{} -} - -func (d DriverOptionsMock) String(key string) string { - return d.Data[key].(string) -} - -func (d DriverOptionsMock) Int(key string) int { - return d.Data[key].(int) -} - -func (d DriverOptionsMock) Bool(key string) bool { - return d.Data[key].(bool) -} - -func clearHosts() error { - return os.RemoveAll(path.Join(utils.GetHomeDir(), ".docker", "machines")) -} - -func TestStoreCreate(t *testing.T) { - if err := clearHosts(); err != nil { - t.Fatal(err) - } - - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": "unix:///var/run/docker.sock", - }, - } - - store := NewStore("", "", "") - - host, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - if host.Name != "test" { - t.Fatal("Host name is incorrect") - } - path := filepath.Join(utils.GetHomeDir(), ".docker", "machines", "test") - if _, err := os.Stat(path); os.IsNotExist(err) { - t.Fatalf("Host path doesn't exist: %s", path) - } -} - -func TestStoreRemove(t *testing.T) { - if err := clearHosts(); err != nil { - t.Fatal(err) - } - - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": "unix:///var/run/docker.sock", - }, - } - - store := NewStore("", "", "") - _, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - path := filepath.Join(utils.GetHomeDir(), ".docker", "machines", "test") - if _, err := os.Stat(path); os.IsNotExist(err) { - t.Fatalf("Host path doesn't exist: %s", path) - } - err = store.Remove("test", false) - if err != nil { - t.Fatal(err) - } - if _, err := os.Stat(path); err == nil { - t.Fatalf("Host path still exists after remove: %s", path) - } -} - -func TestStoreList(t *testing.T) { - if err := clearHosts(); err != nil { - t.Fatal(err) - } - - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": "unix:///var/run/docker.sock", - }, - } - - store := NewStore("", "", "") - _, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - hosts, err := store.List() - if len(hosts) != 1 { - t.Fatalf("List returned %d items", len(hosts)) - } - if hosts[0].Name != "test" { - t.Fatalf("hosts[0] name is incorrect, got: %s", hosts[0].Name) - } -} - -func TestStoreExists(t *testing.T) { - if err := clearHosts(); err != nil { - t.Fatal(err) - } - - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": "unix:///var/run/docker.sock", - }, - } - - store := NewStore("", "", "") - exists, err := store.Exists("test") - if exists { - t.Fatal("Exists returned true when it should have been false") - } - _, err = store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - exists, err = store.Exists("test") - if err != nil { - t.Fatal(err) - } - if !exists { - t.Fatal("Exists returned false when it should have been true") - } -} - -func TestStoreLoad(t *testing.T) { - if err := clearHosts(); err != nil { - t.Fatal(err) - } - - expectedURL := "unix:///foo/baz" - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": expectedURL, - }, - } - - store := NewStore("", "", "") - _, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - - store = NewStore("", "", "") - host, err := store.Load("test") - if host.Name != "test" { - t.Fatal("Host name is incorrect") - } - actualURL, err := host.GetURL() - if err != nil { - t.Fatal(err) - } - if actualURL != expectedURL { - t.Fatalf("GetURL is not %q, got %q", expectedURL, expectedURL) - } -} - -func TestStoreGetSetActive(t *testing.T) { - if err := clearHosts(); err != nil { - t.Fatal(err) - } - - flags := &DriverOptionsMock{ - Data: map[string]interface{}{ - "url": "unix:///var/run/docker.sock", - }, - } - - store := NewStore("", "", "") - - // No hosts set - host, err := store.GetActive() - if err != nil { - t.Fatal(err) - } - - if host != nil { - t.Fatalf("GetActive: Active host should not exist") - } - - // Set normal host - originalHost, err := store.Create("test", "none", flags) - if err != nil { - t.Fatal(err) - } - - if err := store.SetActive(originalHost); err != nil { - t.Fatal(err) - } - - host, err = store.GetActive() - if err != nil { - t.Fatal(err) - } - if host.Name != "test" { - t.Fatalf("Active host is not 'test', got %s", host.Name) - } - isActive, err := store.IsActive(host) - if err != nil { - t.Fatal(err) - } - if isActive != true { - t.Fatal("IsActive: Active host is not test") - } - - // remove active host altogether - if err := store.RemoveActive(); err != nil { - t.Fatal(err) - } - - host, err = store.GetActive() - if err != nil { - t.Fatal(err) - } - - if host != nil { - t.Fatalf("Active host %s is not nil", host.Name) - } -} diff --git a/test/integration/.gitignore b/test/integration/.gitignore new file mode 100644 index 0000000000..9bb348ea1a --- /dev/null +++ b/test/integration/.gitignore @@ -0,0 +1 @@ +env-* diff --git a/test/integration/amazonec2/amazon.bats b/test/integration/amazonec2/amazon.bats new file mode 100644 index 0000000000..2801943993 --- /dev/null +++ b/test/integration/amazonec2/amazon.bats @@ -0,0 +1,16 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER amazonec2 + +use_disposable_machine + +require_env AWS_ACCESS_KEY_ID +require_env AWS_SECRET_ACCESS_KEY + +@test "$DRIVER: Should Create a default host" { + run machine create -d amazonec2 $NAME + echo ${output} + [ "$status" -eq 0 ] +} diff --git a/test/integration/amazonec2/create-ebsinstance.bats b/test/integration/amazonec2/create-ebsinstance.bats new file mode 100644 index 0000000000..2b2661bc54 --- /dev/null +++ b/test/integration/amazonec2/create-ebsinstance.bats @@ -0,0 +1,27 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER amazonec2 + +use_disposable_machine + +require_env AWS_ACCESS_KEY_ID +require_env AWS_SECRET_ACCESS_KEY +require_env AWS_VPC_ID + +require_env AWS_DEFAULT_REGION +require_env AWS_ZONE + +@test "$DRIVER: Should Create an EBS Optimized Instance" { + #Use Instance Type that supports EBS Optimize + run machine create -d amazonec2 --amazonec2-instance-type=m4.large --amazonec2-use-ebs-optimized-instance $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: Check the machine is up" { + run docker $(machine config $NAME) run --rm -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION -e AWS_ZONE=$AWS_ZONE -e AWS_VPC_ID=$AWS_VPC_ID blendle/aws-cli ec2 describe-instances --filters Name=tag:Name,Values=$NAME Name=instance-state-name,Values=running --query 'Reservations[0].Instances[0].EbsOptimized' --output text + echo ${output} + [[ ${lines[*]:-1} =~ "True" ]] +} \ No newline at end of file diff --git a/test/integration/amazonec2/createwithkeypair.bats b/test/integration/amazonec2/createwithkeypair.bats new file mode 100644 index 0000000000..c62486c235 --- /dev/null +++ b/test/integration/amazonec2/createwithkeypair.bats @@ -0,0 +1,32 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER amazonec2 + +use_disposable_machine + +require_env AWS_ACCESS_KEY_ID + +require_env AWS_SECRET_ACCESS_KEY + +export AWS_SSH_DIR="$MACHINE_STORAGE_PATH/mcnkeys" + +export AWS_SSH_KEYPATH=$AWS_SSH_DIR/id_rsa + +@test "$DRIVER: Should Create Instance with Pre existing SSH Key" { + + mkdir -p $AWS_SSH_DIR + + run ssh-keygen -f $AWS_SSH_KEYPATH -t rsa -N '' + + machine create -d amazonec2 $NAME + + run diff $AWS_SSH_KEYPATH $MACHINE_STORAGE_PATH/machines/$NAME/id_rsa + [[ $output == "" ]] + + run diff $AWS_SSH_KEYPATH.pub $MACHINE_STORAGE_PATH/machines/$NAME/id_rsa.pub + [[ $output == "" ]] + + +} \ No newline at end of file diff --git a/test/integration/core/certs-extra-san.bats b/test/integration/core/certs-extra-san.bats new file mode 100644 index 0000000000..0e91d78423 --- /dev/null +++ b/test/integration/core/certs-extra-san.bats @@ -0,0 +1,22 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_disposable_machine + +@test "$DRIVER: create" { + run machine create --tls-san foo.bar.tld --tls-san 10.42.42.42 -d $DRIVER $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: verify that server cert contains the extra SANs" { + machine ssh $NAME -- openssl x509 -in /var/lib/boot2docker/server.pem -text | grep 'DNS:foo.bar.tld' + machine ssh $NAME -- openssl x509 -in /var/lib/boot2docker/server.pem -text | grep 'IP Address:10.42.42.42' +} + +@test "$DRIVER: verify that server cert SANs are still there after 'regenerate-certs'" { + machine regenerate-certs -f $NAME + machine ssh $NAME -- openssl x509 -in /var/lib/boot2docker/server.pem -text | grep 'DNS:foo.bar.tld' + machine ssh $NAME -- openssl x509 -in /var/lib/boot2docker/server.pem -text | grep 'IP Address:10.42.42.42' +} diff --git a/test/integration/core/core-commands.bats b/test/integration/core/core-commands.bats new file mode 100644 index 0000000000..4bfe5b1d37 --- /dev/null +++ b/test/integration/core/core-commands.bats @@ -0,0 +1,155 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_shared_machine + +@test "$DRIVER: machine should not exist" { + run machine inspect UNKNOWN + echo ${output} + [ "$status" -eq 1 ] + [[ ${lines[0]} =~ "Docker machine \"UNKNOWN\" does not exist" ]] +} + +@test "$DRIVER: appears with ls" { + run machine ls -q + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[0]} == "$NAME" ]] +} + +@test "$DRIVER: has status 'started' appearing in ls" { + run machine ls -q --filter state=Running + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[0]} == "$NAME" ]] +} + +@test "$DRIVER: create with same name again fails" { + run machine create -d $DRIVER $NAME + echo ${output} + [ "$status" -eq 1 ] + [[ ${lines[0]} == "Docker machine \"$NAME\" already exists" ]] +} + +@test "$DRIVER: run busybox container" { + run docker $(machine config $NAME) run busybox echo hello world + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: url" { + run machine url $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: ip" { + run machine ip $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: ssh" { + run machine ssh $NAME -- ls -lah / + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[0]} =~ "total" ]] +} + +@test "$DRIVER: version" { + run machine version $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: docker commands with the socket should work" { + run machine ssh $NAME -- sudo docker version + echo ${output} +} + +@test "$DRIVER: stop" { + run machine stop $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show stopped after stop" { + run machine ls + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Stopped"* ]] +} + +@test "$DRIVER: url should show an error when machine is stopped" { + run machine url $NAME + echo ${output} + [ "$status" -eq 1 ] + [[ ${output} == *"Host is not running"* ]] +} + +@test "$DRIVER: env should show an error when machine is stopped" { + run machine env $NAME + echo ${output} + [ "$status" -eq 1 ] + [[ ${output} == *"Host is not running"* ]] +} + +@test "$DRIVER: version should show an error when machine is stopped" { + run machine version $NAME + echo ${output} + [ "$status" -eq 1 ] + [[ ${output} == *"Host is not running"* ]] +} + +@test "$DRIVER: machine should upgrade even when machine is stopped" { + run machine upgrade $NAME + echo ${output} + [[ "$status" -eq 0 ]] +} + +@test "$DRIVER: start should show an error after upgrade" { + run machine start $NAME + echo ${output} + [ "$status" -eq 1 ] +} + +@test "$DRIVER: machine should show running after start" { + run machine ls --timeout 20 + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Running"* ]] +} + +@test "$DRIVER: kill" { + run machine kill $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show stopped after kill" { + run machine ls + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Stopped"* ]] +} + +@test "$DRIVER: restart" { + run machine restart $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show running after restart" { + run machine ls --timeout 20 + echo ${output} + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Running"* ]] +} + +@test "$DRIVER: status" { + run machine status $NAME + echo ${output} + [ "$status" -eq 0 ] + [[ ${output} == *"Running"* ]] +} diff --git a/test/integration/core/crashreport.bats b/test/integration/core/crashreport.bats new file mode 100644 index 0000000000..bbc9184350 --- /dev/null +++ b/test/integration/core/crashreport.bats @@ -0,0 +1,15 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_disposable_machine + +@test "$DRIVER: should send bugsnag report" { + # we exploit a 'bug' where vboxmanage wont allow a machine created with 1mb of RAM + run machine --bugsnag-api-token nonexisting -D create -d virtualbox --virtualbox-memory 1 $NAME + echo ${output} + [ "$status" -eq 1 ] + [[ ${output} == *"notifying bugsnag"* ]] +} diff --git a/test/integration/core/engine-options.bats b/test/integration/core/engine-options.bats new file mode 100644 index 0000000000..be06a028b1 --- /dev/null +++ b/test/integration/core/engine-options.bats @@ -0,0 +1,42 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_disposable_machine + +@test "$DRIVER: create with supported engine options" { + run machine create -d $DRIVER \ + --engine-label spam=eggs \ + --engine-storage-driver overlay \ + --engine-insecure-registry registry.myco.com \ + --engine-env=TEST=VALUE \ + --engine-opt log-driver=none \ + $NAME + echo "$output" + [ $status -eq 0 ] +} + +@test "$DRIVER: check for engine label" { + spamlabel=$(docker $(machine config $NAME) info | grep spam) + [[ $spamlabel =~ "spam=eggs" ]] +} + +@test "$DRIVER: check for engine storage driver" { + storage_driver_info=$(docker $(machine config $NAME) info | grep "Storage Driver") + [[ $storage_driver_info =~ "overlay" ]] +} + +@test "$DRIVER: test docker process envs" { + # get pid of docker process, check process envs for set Environment Variable from above test + run machine ssh $NAME 'sudo cat /proc/$(pgrep -f $(which dockerd))/environ' + echo ${output} + [ $status -eq 0 ] + [[ "${output}" =~ "TEST=VALUE" ]] +} + +@test "$DRIVER: check created engine option (log driver)" { + docker $(machine config $NAME) run --name nolog busybox echo this should not be logged + run docker $(machine config $NAME) inspect -f '{{.HostConfig.LogConfig.Type}}' nolog + echo ${output} + [ ${output} == "none" ] +} diff --git a/test/integration/core/env_shell.bats b/test/integration/core/env_shell.bats new file mode 100755 index 0000000000..a251e47188 --- /dev/null +++ b/test/integration/core/env_shell.bats @@ -0,0 +1,120 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_shared_machine + +@test "$DRIVER: test basic bash / zsh notation" { + run machine env $NAME + [[ ${lines[0]} == "export DOCKER_TLS_VERIFY=\"1\"" ]] + [[ ${lines[1]} == "export DOCKER_HOST=\"$(machine url $NAME)\"" ]] + [[ ${lines[2]} == "export DOCKER_CERT_PATH=\"$MACHINE_STORAGE_PATH/machines/$NAME\"" ]] + [[ ${lines[3]} == "export DOCKER_MACHINE_NAME=\"$NAME\"" ]] +} + +@test "$DRIVER: test powershell notation" { + run machine env --shell powershell --no-proxy $NAME + [[ ${lines[0]} == "\$Env:DOCKER_TLS_VERIFY = \"1\"" ]] + [[ ${lines[1]} == "\$Env:DOCKER_HOST = \"$(machine url $NAME)\"" ]] + [[ ${lines[2]} == "\$Env:DOCKER_CERT_PATH = \"$MACHINE_STORAGE_PATH/machines/$NAME\"" ]] + [[ ${lines[3]} == "\$Env:DOCKER_MACHINE_NAME = \"$NAME\"" ]] + [[ ${lines[4]} == "\$Env:NO_PROXY = \"$(machine ip $NAME)\"" ]] +} + +@test "$DRIVER: test bash / zsh notation with no-proxy" { + run machine env --no-proxy $NAME + [[ ${lines[0]} == "export DOCKER_TLS_VERIFY=\"1\"" ]] + [[ ${lines[1]} == "export DOCKER_HOST=\"$(machine url $NAME)\"" ]] + [[ ${lines[2]} == "export DOCKER_CERT_PATH=\"$MACHINE_STORAGE_PATH/machines/$NAME\"" ]] + [[ ${lines[3]} == "export DOCKER_MACHINE_NAME=\"$NAME\"" ]] + [[ ${lines[4]} == "export NO_PROXY=\"$(machine ip $NAME)\"" ]] +} + +@test "$DRIVER: test cmd.exe notation" { + run machine env --shell cmd --no-proxy $NAME + [[ ${lines[0]} == "SET DOCKER_TLS_VERIFY=1" ]] + [[ ${lines[1]} == "SET DOCKER_HOST=$(machine url $NAME)" ]] + [[ ${lines[2]} == "SET DOCKER_CERT_PATH=$MACHINE_STORAGE_PATH/machines/$NAME" ]] + [[ ${lines[3]} == "SET DOCKER_MACHINE_NAME=$NAME" ]] + [[ ${lines[4]} == "SET NO_PROXY=$(machine ip $NAME)" ]] +} + +@test "$DRIVER: test fish notation" { + run machine env --shell fish --no-proxy $NAME + [[ ${lines[0]} == "set -gx DOCKER_TLS_VERIFY \"1\";" ]] + [[ ${lines[1]} == "set -gx DOCKER_HOST \"$(machine url $NAME)\";" ]] + [[ ${lines[2]} == "set -gx DOCKER_CERT_PATH \"$MACHINE_STORAGE_PATH/machines/$NAME\";" ]] + [[ ${lines[3]} == "set -gx DOCKER_MACHINE_NAME \"$NAME\";" ]] + [[ ${lines[4]} == "set -gx NO_PROXY \"$(machine ip $NAME)\";" ]] +} + +@test "$DRIVER: test emacs notation" { + run machine env --shell emacs --no-proxy $NAME + [[ ${lines[0]} == "(setenv \"DOCKER_TLS_VERIFY\" \"1\")" ]] + [[ ${lines[1]} == "(setenv \"DOCKER_HOST\" \"$(machine url $NAME)\")" ]] + [[ ${lines[2]} == "(setenv \"DOCKER_CERT_PATH\" \"$MACHINE_STORAGE_PATH/machines/$NAME\")" ]] + [[ ${lines[3]} == "(setenv \"DOCKER_MACHINE_NAME\" \"$NAME\")" ]] + [[ ${lines[4]} == "(setenv \"NO_PROXY\" \"$(machine ip $NAME)\")" ]] +} + +@test "$DRIVER: test no proxy with NO_PROXY already set" { + export NO_PROXY=localhost + run machine env --no-proxy $NAME + [[ ${lines[4]} == "export NO_PROXY=\"localhost,$(machine ip $NAME)\"" ]] +} + +@test "$DRIVER: test unset with an args should fail" { + run machine env -u $NAME + [ "$status" -eq 1 ] + [[ ${lines} == "Error: Expected no machine name when the -u flag is present" ]] +} + + +@test "$DRIVER: test bash/zsh unset" { + run machine env -u + [[ ${lines[0]} == "unset DOCKER_TLS_VERIFY" ]] + [[ ${lines[1]} == "unset DOCKER_HOST" ]] + [[ ${lines[2]} == "unset DOCKER_CERT_PATH" ]] + [[ ${lines[3]} == "unset DOCKER_MACHINE_NAME" ]] +} + +@test "$DRIVER: test unset killing no proxy" { + run machine env --no-proxy -u + [[ ${lines[0]} == "unset DOCKER_TLS_VERIFY" ]] + [[ ${lines[1]} == "unset DOCKER_HOST" ]] + [[ ${lines[2]} == "unset DOCKER_CERT_PATH" ]] + [[ ${lines[3]} == "unset DOCKER_MACHINE_NAME" ]] + [[ ${lines[4]} == "unset NO_PROXY" ]] +} + +@test "$DRIVER: unset powershell" { + run machine env --shell powershell -u + [[ ${lines[0]} == 'Remove-Item Env:\\DOCKER_TLS_VERIFY' ]] + [[ ${lines[1]} == 'Remove-Item Env:\\DOCKER_HOST' ]] + [[ ${lines[2]} == 'Remove-Item Env:\\DOCKER_CERT_PATH' ]] + [[ ${lines[3]} == 'Remove-Item Env:\\DOCKER_MACHINE_NAME' ]] +} + +@test "$DRIVER: unset with fish shell" { + run machine env --shell fish -u + [[ ${lines[0]} == "set -e DOCKER_TLS_VERIFY;" ]] + [[ ${lines[1]} == "set -e DOCKER_HOST;" ]] + [[ ${lines[2]} == "set -e DOCKER_CERT_PATH;" ]] + [[ ${lines[3]} == "set -e DOCKER_MACHINE_NAME;" ]] +} + +@test "$DRIVER: unset with cmd shell" { + run machine env --shell cmd -u + [[ ${lines[0]} == "SET DOCKER_TLS_VERIFY=" ]] + [[ ${lines[1]} == "SET DOCKER_HOST=" ]] + [[ ${lines[2]} == "SET DOCKER_CERT_PATH=" ]] + [[ ${lines[3]} == "SET DOCKER_MACHINE_NAME=" ]] +} + +@test "$DRIVER: unset with emacs shell" { + run machine env --shell emacs -u + [[ ${lines[0]} == "(setenv \"DOCKER_TLS_VERIFY\" nil)" ]] + [[ ${lines[1]} == "(setenv \"DOCKER_HOST\" nil)" ]] + [[ ${lines[2]} == "(setenv \"DOCKER_CERT_PATH\" nil)" ]] + [[ ${lines[3]} == "(setenv \"DOCKER_MACHINE_NAME\" nil)" ]] +} diff --git a/test/integration/core/inspect_format.bats b/test/integration/core/inspect_format.bats new file mode 100644 index 0000000000..41996de7a3 --- /dev/null +++ b/test/integration/core/inspect_format.bats @@ -0,0 +1,27 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_shared_machine + +@test "$DRIVER: inspect format template" { + run machine inspect -f '{{.DriverName}}' $NAME + [[ "$output" == "$DRIVER" ]] +} + +@test "$DRIVER: inspect format template json directive" { + run machine inspect -f '{{json .DriverName}}' $NAME + [[ "$output" == "\"$DRIVER\"" ]] +} + +@test "$DRIVER: inspect format template pretty json directive" { + linecount=$(machine inspect -f '{{prettyjson .Driver}}' $NAME | wc -l) + [[ "$linecount" -gt 1 ]] +} + +@test "$DRIVER: check .Driver output is not flawed" { + only_if_env DRIVER virtualbox + run machine inspect -f '{{.Driver.SSHUser}}' $NAME + [ "$status" -eq 0 ] + [[ ${output} == "docker" ]] +} diff --git a/test/integration/core/regenerate-certs.bats b/test/integration/core/regenerate-certs.bats new file mode 100644 index 0000000000..121bdec325 --- /dev/null +++ b/test/integration/core/regenerate-certs.bats @@ -0,0 +1,15 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_shared_machine + +@test "$DRIVER: regenerate the certs" { + run machine regenerate-certs -f $NAME + [[ ${status} -eq 0 ]] +} + +@test "$DRIVER: make sure docker still works" { + run docker $(machine config $NAME) version + [[ ${status} -eq 0 ]] +} diff --git a/test/integration/core/scp.bats b/test/integration/core/scp.bats new file mode 100644 index 0000000000..6e00c51651 --- /dev/null +++ b/test/integration/core/scp.bats @@ -0,0 +1,32 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_shared_machine +export SECOND_MACHINE="$NAME-2" + +@test "$DRIVER: test machine scp command from remote to host" { + machine ssh $NAME 'echo A file created remotely! >/tmp/foo.txt' + machine scp $NAME:/tmp/foo.txt . + [[ $(cat foo.txt) == "A file created remotely!" ]] +} + +@test "$DRIVER: test machine scp command from host to remote" { + teardown () { + rm foo.txt + } + echo A file created locally! >foo.txt + machine scp foo.txt $NAME:/tmp/foo.txt + [[ $(machine ssh $NAME cat /tmp/foo.txt) == "A file created locally!" ]] +} + +@test "$DRIVER: create machine to test transferring files from machine to machine" { + run machine create -d $DRIVER $SECOND_MACHINE + [[ ${status} -eq 0 ]] +} + +@test "$DRIVER: scp from one machine to another" { + run machine ssh $NAME 'echo A file hopping around! >/tmp/foo.txt' + run machine scp $NAME:/tmp/foo.txt $SECOND_MACHINE:/tmp/foo.txt + [[ $(machine ssh ${SECOND_MACHINE} cat /tmp/foo.txt) == "A file hopping around!" ]] +} diff --git a/test/integration/core/ssh-backends.bats b/test/integration/core/ssh-backends.bats new file mode 100644 index 0000000000..b1b5f59e8e --- /dev/null +++ b/test/integration/core/ssh-backends.bats @@ -0,0 +1,40 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +use_shared_machine + +@test "$DRIVER: test external ssh backend" { + run machine ssh $NAME df -h + [[ "$status" -eq 0 ]] +} + +@test "$DRIVER: test command did what it purported to -- external ssh" { + run machine ssh $NAME echo foo + [[ "$output" == "foo" ]] +} + +@test "$DRIVER: test native ssh backend" { + run machine --native-ssh ssh $NAME df -h + [[ "$status" -eq 0 ]] +} + +@test "$DRIVER: test command did what it purported to -- native ssh" { + run machine --native-ssh ssh $NAME echo foo + [[ "$output" =~ "foo" ]] +} + +@test "$DRIVER: ensure that ssh extra arguments work" { + # don't run this test if we can't use external SSH + which ssh + if [[ $? -ne 0 ]]; then + skip + fi + + # this will not fare well if -C doesn't get interpreted as "use compression" + # like intended + run machine ssh $NAME -C echo foo + + [[ "$status" -eq 0 ]] + [[ "$output" == "foo" ]] +} diff --git a/test/integration/core/swarm-options.bats b/test/integration/core/swarm-options.bats new file mode 100644 index 0000000000..6c219826a8 --- /dev/null +++ b/test/integration/core/swarm-options.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +export TOKEN=$(curl -sS -X POST "https://discovery.hub.docker.com/v1/clusters") + +@test "create swarm master" { + run machine create -d $DRIVER --swarm --swarm-master --swarm-discovery "token://$TOKEN" --swarm-strategy binpack --swarm-opt heartbeat=5s queenbee + echo ${output} + [[ "$status" -eq 0 ]] +} + +@test "create swarm node" { + run machine create -d $DRIVER --swarm --swarm-discovery "token://$TOKEN" workerbee + [[ "$status" -eq 0 ]] +} + +@test "ensure strategy is correct" { + strategy=$(docker $(machine config --swarm queenbee) info | grep "Strategy:" | awk '{ print $2 }') + echo ${strategy} + [[ "$strategy" == "binpack" ]] +} + +@test "ensure heartbeat" { + heartbeat_arg=$(docker $(machine config queenbee) inspect -f '{{index .Args}}' swarm-agent-master) + echo ${heartbeat_arg} + [[ "$heartbeat_arg" =~ "--heartbeat=5s" ]] +} + +@test "ls command should not show as swarm active if normal active" { + eval $(machine env queenbee) + run machine ls --filter name=queenbee + [[ ${lines[1]} != *"* (swarm)"* ]] +} + +@test "ls command should show as swarm active" { + eval $(machine env --swarm queenbee) + run machine ls --filter name=queenbee + echo ${output} + [[ ${lines[1]} == *"* (swarm)"* ]] +} + +@test "active command should show the host as active if normal active" { + eval $(machine env queenbee) + run machine active + echo ${output} + [[ ${lines[0]} == "queenbee" ]] +} + +@test "active command should show the host as active if swarm active" { + eval $(machine env --swarm queenbee) + run machine active + echo ${output} + [[ ${lines[0]} == "queenbee" ]] +} diff --git a/test/integration/helpers.bash b/test/integration/helpers.bash new file mode 100644 index 0000000000..7138ed741f --- /dev/null +++ b/test/integration/helpers.bash @@ -0,0 +1,50 @@ +#!/bin/bash + +function echo_to_log { + echo "$BATS_TEST_NAME +---------- +$output +---------- + +" >> ${BATS_LOG} +} + +function teardown { + echo_to_log +} + +function errecho { + >&2 echo "$@" +} + +function only_if_env { + if [[ ${!1} != "$2" ]]; then + errecho "This test requires the $1 environment variable to be set to $2. Skipping..." + skip + fi +} + +function require_env { + if [[ -z ${!1} ]]; then + errecho "This test requires the $1 environment variable to be set in order to run." + exit 1 + fi +} + +function use_disposable_machine { + if [[ -z "$NAME" ]]; then + export NAME="bats-$DRIVER-test-$(date +%s)" + fi +} + +function use_shared_machine { + if [[ -z "$NAME" ]]; then + export NAME="$SHARED_NAME" + if [[ $(machine ls -q --filter name=$NAME | wc -l) -eq 0 ]]; then + machine create -d $DRIVER $NAME &>/dev/null + fi + fi +} + +# Make sure these aren't set while tests run (can cause confusing behavior) +unset DOCKER_HOST DOCKER_TLS_VERIFY DOCKER_CERT_DIR diff --git a/test/integration/run-bats.sh b/test/integration/run-bats.sh new file mode 100755 index 0000000000..0693717379 --- /dev/null +++ b/test/integration/run-bats.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +set -e + +# Wrapper script to run bats tests for various drivers. +# Usage: DRIVER=[driver] ./run-bats.sh [subtest] + +function quiet_run () { + if [[ "$VERBOSE" == "1" ]]; then + "$@" + else + "$@" &>/dev/null + fi +} + +function cleanup_machines() { + for MACHINE_NAME in $(machine ls -q); do + if [[ "$MACHINE_NAME" != "$SHARED_NAME" ]] || [[ "$1" == "ALL" ]]; then + quiet_run machine rm -f $MACHINE_NAME + fi + done +} + +function cleanup_store() { + if [[ -d "$MACHINE_STORAGE_PATH" ]]; then + rm -r "$MACHINE_STORAGE_PATH" + fi +} + +function machine() { + "$MACHINE_ROOT"/bin/"$MACHINE_BIN_NAME" "$@" +} + +function run_bats() { + for bats_file in $(find "$1" -name \*.bats); do + echo "=> $bats_file" + + # BATS returns non-zero to indicate the tests have failed, we shouldn't + # necessarily bail in this case, so that's the reason for the e toggle. + set +e + bats "$bats_file" + if [[ $? -ne 0 ]]; then + EXIT_STATUS=1 + fi + set -e + + echo + + if [[ "$NO_SHARE_MACHINES" == "1" ]]; then + cleanup_machines "ALL" + else + cleanup_machines "NON-SHARED" + fi + done +} + +# Set this ourselves in case bats call fails +EXIT_STATUS=0 +export BATS_FILE="$1" + +# Check we're not running bash 3.x +if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then + echo "Bash 4.1 or later is required to run these tests" + exit 1 +fi + +# If bash 4.x, check the minor version is 1 or later +if [ "${BASH_VERSINFO[0]}" -eq 4 ] && [ "${BASH_VERSINFO[1]}" -lt 1 ]; then + echo "Bash 4.1 or later is required to run these tests" + exit 1 +fi + +if [[ -z "$DRIVER" ]]; then + echo "You must specify the DRIVER environment variable." + exit 1 +fi + +if [[ -z "$BATS_FILE" ]]; then + echo "You must specify a bats test to run." + exit 1 +fi + +if [[ ! -e "$BATS_FILE" ]]; then + echo "Requested bats file or directory not found: $BATS_FILE" + exit 1 +fi + +# TODO: Should the script bail out if these are set already? +export BASE_TEST_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +export MACHINE_ROOT="$BASE_TEST_DIR/../.." +export MACHINE_STORAGE_PATH="/tmp/machine-bats-test-$DRIVER" +export MACHINE_BIN_NAME=docker-machine +export BATS_LOG="$MACHINE_ROOT/bats.log" +export B2D_LOCATION=~/.docker/machine/cache/boot2docker.iso +export SHARED_NAME="bats-$DRIVER-test-shared-$(date +%s)" +export MACHINE_BUGSNAG_API_TOKEN=no-report + +# This function gets used in the integration tests, so export it. +export -f machine + +> "$BATS_LOG" + +cleanup_machines "ALL" +cleanup_store + +if [[ -f "$B2D_LOCATION" ]]; then + if [[ "$B2D_CACHE" == "1" ]]; then + mkdir -p "${MACHINE_STORAGE_PATH}/cache" + cp $B2D_LOCATION "${MACHINE_STORAGE_PATH}/cache/boot2docker.iso" + else + echo "INFO: Run the tests with B2D_CACHE=1 to avoid downloading the boot2docker iso each time." + fi +fi + +run_bats "$BATS_FILE" + +cleanup_machines "ALL" +cleanup_store + +exit ${EXIT_STATUS} diff --git a/test/integration/virtualbox/certs-checksum.bats b/test/integration/virtualbox/certs-checksum.bats new file mode 100644 index 0000000000..4e35c4aa87 --- /dev/null +++ b/test/integration/virtualbox/certs-checksum.bats @@ -0,0 +1,24 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_shared_machine + +@test "$DRIVER: verify that server cert checksum matches local checksum" { + # TODO: This test is tightly coupled to VirtualBox right now, but should be + # available for all providers ideally. + # + # TODO: Does this test work OK on Linux? cc @ehazlett + # + # Have to create this directory and file or else the OpenSSL checksum will barf. + machine ssh $NAME -- sudo mkdir -p /usr/local/ssl + machine ssh $NAME -- sudo touch /usr/local/ssl/openssl.cnf + + SERVER_CHECKSUM=$(machine ssh $NAME -- openssl dgst -sha256 /var/lib/boot2docker/ca.pem | awk '{ print $2 }') + LOCAL_CHECKSUM=$(openssl dgst -sha256 $MACHINE_STORAGE_PATH/certs/ca.pem | awk '{ print $2 }') + echo ${SERVER_CHECKSUM} + echo ${LOCAL_CHECKSUM} + [[ ${SERVER_CHECKSUM} == ${LOCAL_CHECKSUM} ]] +} diff --git a/test/integration/virtualbox/create-with-upgrading.bats b/test/integration/virtualbox/create-with-upgrading.bats new file mode 100644 index 0000000000..ad8e2777c4 --- /dev/null +++ b/test/integration/virtualbox/create-with-upgrading.bats @@ -0,0 +1,29 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_disposable_machine + +export CACHE_DIR="$MACHINE_STORAGE_PATH/cache" +export ISO_PATH="$CACHE_DIR/boot2docker.iso" +export OLD_ISO_URL="https://github.com/boot2docker/boot2docker/releases/download/v1.4.1/boot2docker.iso" + +@test "$DRIVER: download the old version iso" { + run mkdir -p $CACHE_DIR + run curl $OLD_ISO_URL -L -o $ISO_PATH + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: create with upgrading" { + run machine create -d $DRIVER $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: create is correct version" { + SERVER_VERSION=$(docker $(machine config $NAME) version | grep 'Server version' | awk '{ print $3; }') + [[ "$SERVER_VERSION" != "1.4.1" ]] +} diff --git a/test/integration/virtualbox/custom-mem-disk.bats b/test/integration/virtualbox/custom-mem-disk.bats new file mode 100644 index 0000000000..5828b4fc3f --- /dev/null +++ b/test/integration/virtualbox/custom-mem-disk.bats @@ -0,0 +1,58 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_disposable_machine + +# Default memsize is 1024MB and disksize is 20000MB +# These values are defined in drivers/virtualbox/virtualbox.go +export DEFAULT_MEMSIZE=1024 +export DEFAULT_DISKSIZE=20000 +export CUSTOM_MEMSIZE=1536 +export CUSTOM_DISKSIZE=10000 +export CUSTOM_CPUCOUNT=1 + +function findDiskSize() { + # SATA-0-0 is usually the boot2disk.iso image + # We assume that SATA 1-0 is root disk VMDK and grab this UUID + # e.g. "SATA-ImageUUID-1-0"="fb5f33a7-e4e3-4cb9-877c-f9415ae2adea" + # TODO(slashk): does this work on Windows ? + run bash -c "VBoxManage showvminfo --machinereadable $NAME | grep SATA-ImageUUID-1-0 | cut -d'=' -f2" + run bash -c "VBoxManage showhdinfo $output | grep "Capacity:" | awk -F' ' '{ print $2 }'" +} + +function findMemorySize() { + run bash -c "VBoxManage showvminfo --machinereadable $NAME | grep memory= | cut -d'=' -f2" +} + +function findCPUCount() { + run bash -c "VBoxManage showvminfo --machinereadable $NAME | grep cpus= | cut -d'=' -f2" +} + +@test "$DRIVER: create with custom disk, cpu count and memory size flags" { + run machine create -d $DRIVER --virtualbox-cpu-count $CUSTOM_CPUCOUNT --virtualbox-disk-size $CUSTOM_DISKSIZE --virtualbox-memory $CUSTOM_MEMSIZE $NAME + [ "$status" -eq 0 ] +} + +@test "$DRIVER: check custom machine memory size" { + findMemorySize + [[ ${output} == "$CUSTOM_MEMSIZE" ]] +} + +@test "$DRIVER: check custom machine disksize" { + findDiskSize + [[ ${output} == *"$CUSTOM_DISKSIZE"* ]] +} + +@test "$DRIVER: check custom machine cpucount" { + findCPUCount + [[ ${output} == "$CUSTOM_CPUCOUNT" ]] +} + +@test "$DRIVER: machine should show running after create" { + run machine ls + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Running"* ]] +} diff --git a/test/integration/virtualbox/dns.bats b/test/integration/virtualbox/dns.bats new file mode 100644 index 0000000000..7b7afca0f8 --- /dev/null +++ b/test/integration/virtualbox/dns.bats @@ -0,0 +1,17 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_disposable_machine + +@test "$DRIVER: Create a vm with a dns proxy set" { + run machine create -d $DRIVER --virtualbox-dns-proxy=true $NAME + [[ ${status} -eq 0 ]] +} + +@test "$DRIVER: Check DNSProxy flag is properly set during machine creation" { + run bash -c "cat ${MACHINE_STORAGE_PATH}/machines/$NAME/$NAME/Logs/VBox.log | grep DNSProxy | grep '(1)'" + [[ ${status} -eq 0 ]] +} \ No newline at end of file diff --git a/test/integration/virtualbox/guards.bats b/test/integration/virtualbox/guards.bats new file mode 100644 index 0000000000..e10d8588aa --- /dev/null +++ b/test/integration/virtualbox/guards.bats @@ -0,0 +1,17 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_disposable_machine + +@test "$DRIVER: Should not allow machine creation with bad ISO" { + run machine create -d virtualbox --virtualbox-boot2docker-url http://dev.null:9111/bad.iso $NAME + [[ ${status} -eq 1 ]] +} + +@test "$DRIVER: Should not allow machine creation with engine-install-url" { + run machine create --engine-install-url https://test.docker.com -d virtualbox $NAME + [[ ${output} == *"--engine-install-url cannot be used"* ]] +} \ No newline at end of file diff --git a/test/integration/virtualbox/pause-save-start.bats b/test/integration/virtualbox/pause-save-start.bats new file mode 100644 index 0000000000..2102aefc38 --- /dev/null +++ b/test/integration/virtualbox/pause-save-start.bats @@ -0,0 +1,52 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_shared_machine + +@test "$DRIVER: VBoxManage pause" { + run VBoxManage controlvm $NAME pause + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show paused after VBoxManage pause" { + run machine ls + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Paused"* ]] +} + +@test "$DRIVER: start after paused" { + run machine start $NAME + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show running after start" { + run machine ls + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Running"* ]] +} + +@test "$DRIVER: VBoxManage savestate" { + run VBoxManage controlvm $NAME savestate + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show saved after VBoxManage savestate" { + run machine ls + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"$NAME"* ]] + [[ ${lines[1]} == *"Saved"* ]] +} + +@test "$DRIVER: start after saved" { + run machine start $NAME + [ "$status" -eq 0 ] +} + +@test "$DRIVER: machine should show running after start" { + run machine ls + [ "$status" -eq 0 ] + [[ ${lines[1]} == *"Running"* ]] +} diff --git a/test/integration/virtualbox/upgrade.bats b/test/integration/virtualbox/upgrade.bats new file mode 100644 index 0000000000..dc906b77fe --- /dev/null +++ b/test/integration/virtualbox/upgrade.bats @@ -0,0 +1,30 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +only_if_env DRIVER virtualbox + +use_disposable_machine + +export OLD_ISO_URL="https://github.com/boot2docker/boot2docker/releases/download/v1.4.1/boot2docker.iso" + +@test "$DRIVER: create for upgrade" { + run machine create -d virtualbox --virtualbox-boot2docker-url $OLD_ISO_URL $NAME +} + +@test "$DRIVER: verify that docker version is old" { + # Have to run this over SSH due to client/server mismatch restriction + SERVER_VERSION=$(machine ssh $NAME docker version | grep 'Server version' | awk '{ print $3; }') + [[ "$SERVER_VERSION" == "1.4.1" ]] +} + +@test "$DRIVER: upgrade" { + run machine upgrade $NAME + echo ${output} + [ "$status" -eq 0 ] +} + +@test "$DRIVER: upgrade is correct version" { + SERVER_VERSION=$(docker $(machine config $NAME) version | grep 'Server version' | awk '{ print $3; }') + [[ "$SERVER_VERSION" != "1.4.1" ]] +} diff --git a/test/provision/rancheros.bats b/test/provision/rancheros.bats new file mode 100644 index 0000000000..62c726f263 --- /dev/null +++ b/test/provision/rancheros.bats @@ -0,0 +1,19 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + + +# this should move to the makefile + +if [[ "$DRIVER" != "virtualbox" ]]; then + exit 0 +fi + +export RANCHEROS_VERSION="v0.3.1" +export RANCHEROS_ISO="https://github.com/rancherio/os/releases/download/$RANCHEROS_VERSION/machine-rancheros.iso" + +@test "$DRIVER: create with RancherOS ISO" { + VIRTUALBOX_BOOT2DOCKER_URL="$RANCHEROS_ISO" run ${BASE_TEST_DIR}/run-bats.sh ${BASE_TEST_DIR}/core + echo ${output} + [ ${status} -eq 0 ] +} diff --git a/test/provision/redhat.bats b/test/provision/redhat.bats new file mode 100644 index 0000000000..f2b249a640 --- /dev/null +++ b/test/provision/redhat.bats @@ -0,0 +1,20 @@ +#!/usr/bin/env bats + +load ${BASE_TEST_DIR}/helpers.bash + +# this should move to the makefile + +if [[ "$DRIVER" != "amazonec2" ]]; then + exit 0 +fi + +require_env AWS_VPC_ID +require_env AWS_ACCESS_KEY_ID +require_env AWS_SECRET_ACCESS_KEY + +@test "$DRIVER: create using RedHat AMI" { + # Oh snap, recursive stuff!! + AWS_AMI=ami-12663b7a AWS_SSH_USER=ec2-user run ${BASE_TEST_DIR}/run-bats.sh ${BASE_TEST_DIR}/core + echo ${output} + [ ${status} -eq 0 ] +} diff --git a/utils/b2d.go b/utils/b2d.go deleted file mode 100644 index 4b200db0ca..0000000000 --- a/utils/b2d.go +++ /dev/null @@ -1,62 +0,0 @@ -package utils - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "path/filepath" -) - -// Get the latest boot2docker release tag name (e.g. "v0.6.0"). -// FIXME: find or create some other way to get the "latest release" of boot2docker since the GitHub API has a pretty low rate limit on API requests -func GetLatestBoot2DockerReleaseURL() (string, error) { - rsp, err := http.Get("https://api.github.com/repos/boot2docker/boot2docker/releases") - if err != nil { - return "", err - } - defer rsp.Body.Close() - - var t []struct { - TagName string `json:"tag_name"` - } - if err := json.NewDecoder(rsp.Body).Decode(&t); err != nil { - return "", err - } - if len(t) == 0 { - return "", fmt.Errorf("no releases found") - } - - tag := t[0].TagName - url := fmt.Sprintf("https://github.com/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", tag) - return url, nil -} - -// Download boot2docker ISO image for the given tag and save it at dest. -func DownloadISO(dir, file, url string) error { - rsp, err := http.Get(url) - if err != nil { - return err - } - defer rsp.Body.Close() - - // Download to a temp file first then rename it to avoid partial download. - f, err := ioutil.TempFile(dir, file+".tmp") - if err != nil { - return err - } - defer os.Remove(f.Name()) - if _, err := io.Copy(f, rsp.Body); err != nil { - // TODO: display download progress? - return err - } - if err := f.Close(); err != nil { - return err - } - if err := os.Rename(f.Name(), filepath.Join(dir, file)); err != nil { - return err - } - return nil -} diff --git a/utils/certs.go b/utils/certs.go deleted file mode 100644 index 70b8a6cde9..0000000000 --- a/utils/certs.go +++ /dev/null @@ -1,150 +0,0 @@ -package utils - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/tls" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "math/big" - "net" - "os" - "time" -) - -func newCertificate(org string) (*x509.Certificate, error) { - now := time.Now() - // need to set notBefore slightly in the past to account for time - // skew in the VMs otherwise the certs sometimes are not yet valid - notBefore := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-5, 0, 0, time.Local) - notAfter := notBefore.Add(time.Hour * 24 * 1080) - - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - return nil, err - } - - return &x509.Certificate{ - SerialNumber: serialNumber, - Subject: pkix.Name{ - Organization: []string{org}, - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - BasicConstraintsValid: true, - }, nil - -} - -// GenerateCACertificate generates a new certificate authority from the specified org -// and bit size and stores the resulting certificate and key file -// in the arguments. -func GenerateCACertificate(certFile, keyFile, org string, bits int) error { - template, err := newCertificate(org) - if err != nil { - return err - } - - template.IsCA = true - template.KeyUsage |= x509.KeyUsageCertSign - - priv, err := rsa.GenerateKey(rand.Reader, bits) - if err != nil { - return err - } - - derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv) - if err != nil { - return err - } - - certOut, err := os.Create(certFile) - if err != nil { - return err - } - - pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) - certOut.Close() - - keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return err - - } - - pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) - keyOut.Close() - - return nil -} - -// GenerateCert generates a new certificate signed using the provided -// certificate authority files and stores the result in the certificate -// file and key provided. The provided host names are set to the -// appropriate certificate fields. -func GenerateCert(hosts []string, certFile, keyFile, caFile, caKeyFile, org string, bits int) error { - template, err := newCertificate(org) - if err != nil { - return err - } - // client - if len(hosts) == 1 && hosts[0] == "" { - template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth} - template.KeyUsage = x509.KeyUsageDigitalSignature - } else { // server - for _, h := range hosts { - if ip := net.ParseIP(h); ip != nil { - template.IPAddresses = append(template.IPAddresses, ip) - - } else { - template.DNSNames = append(template.DNSNames, h) - } - } - } - - tlsCert, err := tls.LoadX509KeyPair(caFile, caKeyFile) - if err != nil { - return err - - } - - priv, err := rsa.GenerateKey(rand.Reader, bits) - if err != nil { - return err - - } - - x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0]) - if err != nil { - return err - } - - derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey) - if err != nil { - return err - } - - certOut, err := os.Create(certFile) - if err != nil { - return err - - } - - pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) - certOut.Close() - - keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return err - - } - - pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) - keyOut.Close() - - return nil -} diff --git a/utils/utils.go b/utils/utils.go deleted file mode 100644 index 63019114a2..0000000000 --- a/utils/utils.go +++ /dev/null @@ -1,65 +0,0 @@ -package utils - -import ( - "io" - "os" - "path/filepath" - "runtime" -) - -func GetHomeDir() string { - if runtime.GOOS == "windows" { - return os.Getenv("USERPROFILE") - } - return os.Getenv("HOME") -} - -func GetDockerDir() string { - return filepath.Join(GetHomeDir(), ".docker") -} - -func GetMachineDir() string { - return filepath.Join(GetDockerDir(), "machines") -} - -func GetMachineClientCertDir() string { - return filepath.Join(GetMachineDir(), ".client") -} - -func GetUsername() string { - u := "unknown" - osUser := "" - - switch runtime.GOOS { - case "darwin", "linux": - osUser = os.Getenv("USER") - case "windows": - osUser = os.Getenv("USERNAME") - } - - if osUser != "" { - u = osUser - } - - return u -} - -func CopyFile(src, dst string) error { - in, err := os.Open(src) - if err != nil { - return err - } - - defer in.Close() - - out, err := os.Create(dst) - if err != nil { - return err - } - - if _, err = io.Copy(out, in); err != nil { - return err - } - - return nil -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/LICENSE b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE new file mode 100644 index 0000000000..af39a91e70 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Microsoft Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go new file mode 100644 index 0000000000..013a6af9ac --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go @@ -0,0 +1,358 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// AvailabilitySetsClient is the the Compute Management Client. +type AvailabilitySetsClient struct { + ManagementClient +} + +// NewAvailabilitySetsClient creates an instance of the AvailabilitySetsClient +// client. +func NewAvailabilitySetsClient(subscriptionID string) AvailabilitySetsClient { + return NewAvailabilitySetsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewAvailabilitySetsClientWithBaseURI creates an instance of the +// AvailabilitySetsClient client. +func NewAvailabilitySetsClientWithBaseURI(baseURI string, subscriptionID string) AvailabilitySetsClient { + return AvailabilitySetsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the operation to create or update the availability set. +// +// resourceGroupName is the name of the resource group. name is parameters +// supplied to the Create Availability Set operation. parameters is +// parameters supplied to the Create Availability Set operation. +func (client AvailabilitySetsClient) CreateOrUpdate(resourceGroupName string, name string, parameters AvailabilitySet) (result AvailabilitySet, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, name, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client AvailabilitySetsClient) CreateOrUpdatePreparer(resourceGroupName string, name string, parameters AvailabilitySet) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": autorest.Encode("path", name), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/availabilitySets/{name}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client AvailabilitySetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client AvailabilitySetsClient) CreateOrUpdateResponder(resp *http.Response) (result AvailabilitySet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete the operation to delete the availability set. +// +// resourceGroupName is the name of the resource group. availabilitySetName is +// the name of the availability set. +func (client AvailabilitySetsClient) Delete(resourceGroupName string, availabilitySetName string) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, availabilitySetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client AvailabilitySetsClient) DeletePreparer(resourceGroupName string, availabilitySetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "availabilitySetName": autorest.Encode("path", availabilitySetName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/availabilitySets/{availabilitySetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client AvailabilitySetsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client AvailabilitySetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the operation to get the availability set. +// +// resourceGroupName is the name of the resource group. availabilitySetName is +// the name of the availability set. +func (client AvailabilitySetsClient) Get(resourceGroupName string, availabilitySetName string) (result AvailabilitySet, err error) { + req, err := client.GetPreparer(resourceGroupName, availabilitySetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client AvailabilitySetsClient) GetPreparer(resourceGroupName string, availabilitySetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "availabilitySetName": autorest.Encode("path", availabilitySetName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/availabilitySets/{availabilitySetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client AvailabilitySetsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client AvailabilitySetsClient) GetResponder(resp *http.Response) (result AvailabilitySet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the operation to list the availability sets. +// +// resourceGroupName is the name of the resource group. +func (client AvailabilitySetsClient) List(resourceGroupName string) (result AvailabilitySetListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client AvailabilitySetsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/availabilitySets", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client AvailabilitySetsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client AvailabilitySetsClient) ListResponder(resp *http.Response) (result AvailabilitySetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAvailableSizes lists all available virtual machine sizes that can be +// used to create a new virtual machine in an existing availability set. +// +// resourceGroupName is the name of the resource group. availabilitySetName is +// the name of the availability set. +func (client AvailabilitySetsClient) ListAvailableSizes(resourceGroupName string, availabilitySetName string) (result VirtualMachineSizeListResult, err error) { + req, err := client.ListAvailableSizesPreparer(resourceGroupName, availabilitySetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "ListAvailableSizes", nil, "Failure preparing request") + } + + resp, err := client.ListAvailableSizesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "ListAvailableSizes", resp, "Failure sending request") + } + + result, err = client.ListAvailableSizesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.AvailabilitySetsClient", "ListAvailableSizes", resp, "Failure responding to request") + } + + return +} + +// ListAvailableSizesPreparer prepares the ListAvailableSizes request. +func (client AvailabilitySetsClient) ListAvailableSizesPreparer(resourceGroupName string, availabilitySetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "availabilitySetName": autorest.Encode("path", availabilitySetName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/availabilitySets/{availabilitySetName}/vmSizes", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAvailableSizesSender sends the ListAvailableSizes request. The method will close the +// http.Response Body if it receives an error. +func (client AvailabilitySetsClient) ListAvailableSizesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAvailableSizesResponder handles the response to the ListAvailableSizes request. The method always +// closes the http.Response Body. +func (client AvailabilitySetsClient) ListAvailableSizesResponder(resp *http.Response) (result VirtualMachineSizeListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/client.go new file mode 100644 index 0000000000..e8f3fb3e6d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/client.go @@ -0,0 +1,58 @@ +// Package compute implements the Azure ARM Compute service API version +// 2016-03-30. +// +// The Compute Management Client. +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Compute + APIVersion = "2016-03-30" + + // DefaultBaseURI is the default URI used for the service Compute + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Compute. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/models.go new file mode 100644 index 0000000000..e38a3a1222 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/models.go @@ -0,0 +1,1180 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// CachingTypes enumerates the values for caching types. +type CachingTypes string + +const ( + // None specifies the none state for caching types. + None CachingTypes = "None" + // ReadOnly specifies the read only state for caching types. + ReadOnly CachingTypes = "ReadOnly" + // ReadWrite specifies the read write state for caching types. + ReadWrite CachingTypes = "ReadWrite" +) + +// ComponentNames enumerates the values for component names. +type ComponentNames string + +const ( + // MicrosoftWindowsShellSetup specifies the microsoft windows shell setup + // state for component names. + MicrosoftWindowsShellSetup ComponentNames = "Microsoft-Windows-Shell-Setup" +) + +// DiskCreateOptionTypes enumerates the values for disk create option types. +type DiskCreateOptionTypes string + +const ( + // Attach specifies the attach state for disk create option types. + Attach DiskCreateOptionTypes = "attach" + // Empty specifies the empty state for disk create option types. + Empty DiskCreateOptionTypes = "empty" + // FromImage specifies the from image state for disk create option types. + FromImage DiskCreateOptionTypes = "fromImage" +) + +// InstanceViewTypes enumerates the values for instance view types. +type InstanceViewTypes string + +const ( + // InstanceView specifies the instance view state for instance view types. + InstanceView InstanceViewTypes = "instanceView" +) + +// OperatingSystemTypes enumerates the values for operating system types. +type OperatingSystemTypes string + +const ( + // Linux specifies the linux state for operating system types. + Linux OperatingSystemTypes = "Linux" + // Windows specifies the windows state for operating system types. + Windows OperatingSystemTypes = "Windows" +) + +// PassNames enumerates the values for pass names. +type PassNames string + +const ( + // OobeSystem specifies the oobe system state for pass names. + OobeSystem PassNames = "oobeSystem" +) + +// ProtocolTypes enumerates the values for protocol types. +type ProtocolTypes string + +const ( + // HTTP specifies the http state for protocol types. + HTTP ProtocolTypes = "Http" + // HTTPS specifies the https state for protocol types. + HTTPS ProtocolTypes = "Https" +) + +// SettingNames enumerates the values for setting names. +type SettingNames string + +const ( + // AutoLogon specifies the auto logon state for setting names. + AutoLogon SettingNames = "AutoLogon" + // FirstLogonCommands specifies the first logon commands state for setting + // names. + FirstLogonCommands SettingNames = "FirstLogonCommands" +) + +// StatusLevelTypes enumerates the values for status level types. +type StatusLevelTypes string + +const ( + // Error specifies the error state for status level types. + Error StatusLevelTypes = "Error" + // Info specifies the info state for status level types. + Info StatusLevelTypes = "Info" + // Warning specifies the warning state for status level types. + Warning StatusLevelTypes = "Warning" +) + +// UpgradeMode enumerates the values for upgrade mode. +type UpgradeMode string + +const ( + // Automatic specifies the automatic state for upgrade mode. + Automatic UpgradeMode = "Automatic" + // Manual specifies the manual state for upgrade mode. + Manual UpgradeMode = "Manual" +) + +// VirtualMachineScaleSetSkuScaleType enumerates the values for virtual +// machine scale set sku scale type. +type VirtualMachineScaleSetSkuScaleType string + +const ( + // VirtualMachineScaleSetSkuScaleTypeAutomatic specifies the virtual + // machine scale set sku scale type automatic state for virtual machine + // scale set sku scale type. + VirtualMachineScaleSetSkuScaleTypeAutomatic VirtualMachineScaleSetSkuScaleType = "Automatic" + // VirtualMachineScaleSetSkuScaleTypeNone specifies the virtual machine + // scale set sku scale type none state for virtual machine scale set sku + // scale type. + VirtualMachineScaleSetSkuScaleTypeNone VirtualMachineScaleSetSkuScaleType = "None" +) + +// VirtualMachineSizeTypes enumerates the values for virtual machine size +// types. +type VirtualMachineSizeTypes string + +const ( + // BasicA0 specifies the basic a0 state for virtual machine size types. + BasicA0 VirtualMachineSizeTypes = "Basic_A0" + // BasicA1 specifies the basic a1 state for virtual machine size types. + BasicA1 VirtualMachineSizeTypes = "Basic_A1" + // BasicA2 specifies the basic a2 state for virtual machine size types. + BasicA2 VirtualMachineSizeTypes = "Basic_A2" + // BasicA3 specifies the basic a3 state for virtual machine size types. + BasicA3 VirtualMachineSizeTypes = "Basic_A3" + // BasicA4 specifies the basic a4 state for virtual machine size types. + BasicA4 VirtualMachineSizeTypes = "Basic_A4" + // StandardA0 specifies the standard a0 state for virtual machine size + // types. + StandardA0 VirtualMachineSizeTypes = "Standard_A0" + // StandardA1 specifies the standard a1 state for virtual machine size + // types. + StandardA1 VirtualMachineSizeTypes = "Standard_A1" + // StandardA10 specifies the standard a10 state for virtual machine size + // types. + StandardA10 VirtualMachineSizeTypes = "Standard_A10" + // StandardA11 specifies the standard a11 state for virtual machine size + // types. + StandardA11 VirtualMachineSizeTypes = "Standard_A11" + // StandardA2 specifies the standard a2 state for virtual machine size + // types. + StandardA2 VirtualMachineSizeTypes = "Standard_A2" + // StandardA3 specifies the standard a3 state for virtual machine size + // types. + StandardA3 VirtualMachineSizeTypes = "Standard_A3" + // StandardA4 specifies the standard a4 state for virtual machine size + // types. + StandardA4 VirtualMachineSizeTypes = "Standard_A4" + // StandardA5 specifies the standard a5 state for virtual machine size + // types. + StandardA5 VirtualMachineSizeTypes = "Standard_A5" + // StandardA6 specifies the standard a6 state for virtual machine size + // types. + StandardA6 VirtualMachineSizeTypes = "Standard_A6" + // StandardA7 specifies the standard a7 state for virtual machine size + // types. + StandardA7 VirtualMachineSizeTypes = "Standard_A7" + // StandardA8 specifies the standard a8 state for virtual machine size + // types. + StandardA8 VirtualMachineSizeTypes = "Standard_A8" + // StandardA9 specifies the standard a9 state for virtual machine size + // types. + StandardA9 VirtualMachineSizeTypes = "Standard_A9" + // StandardD1 specifies the standard d1 state for virtual machine size + // types. + StandardD1 VirtualMachineSizeTypes = "Standard_D1" + // StandardD11 specifies the standard d11 state for virtual machine size + // types. + StandardD11 VirtualMachineSizeTypes = "Standard_D11" + // StandardD11V2 specifies the standard d11v2 state for virtual machine + // size types. + StandardD11V2 VirtualMachineSizeTypes = "Standard_D11_v2" + // StandardD12 specifies the standard d12 state for virtual machine size + // types. + StandardD12 VirtualMachineSizeTypes = "Standard_D12" + // StandardD12V2 specifies the standard d12v2 state for virtual machine + // size types. + StandardD12V2 VirtualMachineSizeTypes = "Standard_D12_v2" + // StandardD13 specifies the standard d13 state for virtual machine size + // types. + StandardD13 VirtualMachineSizeTypes = "Standard_D13" + // StandardD13V2 specifies the standard d13v2 state for virtual machine + // size types. + StandardD13V2 VirtualMachineSizeTypes = "Standard_D13_v2" + // StandardD14 specifies the standard d14 state for virtual machine size + // types. + StandardD14 VirtualMachineSizeTypes = "Standard_D14" + // StandardD14V2 specifies the standard d14v2 state for virtual machine + // size types. + StandardD14V2 VirtualMachineSizeTypes = "Standard_D14_v2" + // StandardD15V2 specifies the standard d15v2 state for virtual machine + // size types. + StandardD15V2 VirtualMachineSizeTypes = "Standard_D15_v2" + // StandardD1V2 specifies the standard d1v2 state for virtual machine size + // types. + StandardD1V2 VirtualMachineSizeTypes = "Standard_D1_v2" + // StandardD2 specifies the standard d2 state for virtual machine size + // types. + StandardD2 VirtualMachineSizeTypes = "Standard_D2" + // StandardD2V2 specifies the standard d2v2 state for virtual machine size + // types. + StandardD2V2 VirtualMachineSizeTypes = "Standard_D2_v2" + // StandardD3 specifies the standard d3 state for virtual machine size + // types. + StandardD3 VirtualMachineSizeTypes = "Standard_D3" + // StandardD3V2 specifies the standard d3v2 state for virtual machine size + // types. + StandardD3V2 VirtualMachineSizeTypes = "Standard_D3_v2" + // StandardD4 specifies the standard d4 state for virtual machine size + // types. + StandardD4 VirtualMachineSizeTypes = "Standard_D4" + // StandardD4V2 specifies the standard d4v2 state for virtual machine size + // types. + StandardD4V2 VirtualMachineSizeTypes = "Standard_D4_v2" + // StandardD5V2 specifies the standard d5v2 state for virtual machine size + // types. + StandardD5V2 VirtualMachineSizeTypes = "Standard_D5_v2" + // StandardDS1 specifies the standard ds1 state for virtual machine size + // types. + StandardDS1 VirtualMachineSizeTypes = "Standard_DS1" + // StandardDS11 specifies the standard ds11 state for virtual machine size + // types. + StandardDS11 VirtualMachineSizeTypes = "Standard_DS11" + // StandardDS11V2 specifies the standard ds11v2 state for virtual machine + // size types. + StandardDS11V2 VirtualMachineSizeTypes = "Standard_DS11_v2" + // StandardDS12 specifies the standard ds12 state for virtual machine size + // types. + StandardDS12 VirtualMachineSizeTypes = "Standard_DS12" + // StandardDS12V2 specifies the standard ds12v2 state for virtual machine + // size types. + StandardDS12V2 VirtualMachineSizeTypes = "Standard_DS12_v2" + // StandardDS13 specifies the standard ds13 state for virtual machine size + // types. + StandardDS13 VirtualMachineSizeTypes = "Standard_DS13" + // StandardDS13V2 specifies the standard ds13v2 state for virtual machine + // size types. + StandardDS13V2 VirtualMachineSizeTypes = "Standard_DS13_v2" + // StandardDS14 specifies the standard ds14 state for virtual machine size + // types. + StandardDS14 VirtualMachineSizeTypes = "Standard_DS14" + // StandardDS14V2 specifies the standard ds14v2 state for virtual machine + // size types. + StandardDS14V2 VirtualMachineSizeTypes = "Standard_DS14_v2" + // StandardDS15V2 specifies the standard ds15v2 state for virtual machine + // size types. + StandardDS15V2 VirtualMachineSizeTypes = "Standard_DS15_v2" + // StandardDS1V2 specifies the standard ds1v2 state for virtual machine + // size types. + StandardDS1V2 VirtualMachineSizeTypes = "Standard_DS1_v2" + // StandardDS2 specifies the standard ds2 state for virtual machine size + // types. + StandardDS2 VirtualMachineSizeTypes = "Standard_DS2" + // StandardDS2V2 specifies the standard ds2v2 state for virtual machine + // size types. + StandardDS2V2 VirtualMachineSizeTypes = "Standard_DS2_v2" + // StandardDS3 specifies the standard ds3 state for virtual machine size + // types. + StandardDS3 VirtualMachineSizeTypes = "Standard_DS3" + // StandardDS3V2 specifies the standard ds3v2 state for virtual machine + // size types. + StandardDS3V2 VirtualMachineSizeTypes = "Standard_DS3_v2" + // StandardDS4 specifies the standard ds4 state for virtual machine size + // types. + StandardDS4 VirtualMachineSizeTypes = "Standard_DS4" + // StandardDS4V2 specifies the standard ds4v2 state for virtual machine + // size types. + StandardDS4V2 VirtualMachineSizeTypes = "Standard_DS4_v2" + // StandardDS5V2 specifies the standard ds5v2 state for virtual machine + // size types. + StandardDS5V2 VirtualMachineSizeTypes = "Standard_DS5_v2" + // StandardG1 specifies the standard g1 state for virtual machine size + // types. + StandardG1 VirtualMachineSizeTypes = "Standard_G1" + // StandardG2 specifies the standard g2 state for virtual machine size + // types. + StandardG2 VirtualMachineSizeTypes = "Standard_G2" + // StandardG3 specifies the standard g3 state for virtual machine size + // types. + StandardG3 VirtualMachineSizeTypes = "Standard_G3" + // StandardG4 specifies the standard g4 state for virtual machine size + // types. + StandardG4 VirtualMachineSizeTypes = "Standard_G4" + // StandardG5 specifies the standard g5 state for virtual machine size + // types. + StandardG5 VirtualMachineSizeTypes = "Standard_G5" + // StandardGS1 specifies the standard gs1 state for virtual machine size + // types. + StandardGS1 VirtualMachineSizeTypes = "Standard_GS1" + // StandardGS2 specifies the standard gs2 state for virtual machine size + // types. + StandardGS2 VirtualMachineSizeTypes = "Standard_GS2" + // StandardGS3 specifies the standard gs3 state for virtual machine size + // types. + StandardGS3 VirtualMachineSizeTypes = "Standard_GS3" + // StandardGS4 specifies the standard gs4 state for virtual machine size + // types. + StandardGS4 VirtualMachineSizeTypes = "Standard_GS4" + // StandardGS5 specifies the standard gs5 state for virtual machine size + // types. + StandardGS5 VirtualMachineSizeTypes = "Standard_GS5" +) + +// AdditionalUnattendContent is additional XML formatted information that can +// be included in the Unattend.xml file, which is used by Windows Setup. +// Contents are defined by setting name, component name, and the pass in +// which the content is a applied. +type AdditionalUnattendContent struct { + PassName PassNames `json:"passName,omitempty"` + ComponentName ComponentNames `json:"componentName,omitempty"` + SettingName SettingNames `json:"settingName,omitempty"` + Content *string `json:"content,omitempty"` +} + +// APIEntityReference is the API entity reference. +type APIEntityReference struct { + ID *string `json:"id,omitempty"` +} + +// APIError is api error. +type APIError struct { + Details *[]APIErrorBase `json:"details,omitempty"` + Innererror *InnerError `json:"innererror,omitempty"` + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// APIErrorBase is api error base. +type APIErrorBase struct { + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// AvailabilitySet is create or update Availability Set parameters. +type AvailabilitySet struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *AvailabilitySetProperties `json:"properties,omitempty"` +} + +// AvailabilitySetListResult is the List Availability Set operation response. +type AvailabilitySetListResult struct { + autorest.Response `json:"-"` + Value *[]AvailabilitySet `json:"value,omitempty"` +} + +// AvailabilitySetProperties is the instance view of a resource. +type AvailabilitySetProperties struct { + PlatformUpdateDomainCount *int32 `json:"platformUpdateDomainCount,omitempty"` + PlatformFaultDomainCount *int32 `json:"platformFaultDomainCount,omitempty"` + VirtualMachines *[]SubResource `json:"virtualMachines,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// BootDiagnostics is describes Boot Diagnostics. +type BootDiagnostics struct { + Enabled *bool `json:"enabled,omitempty"` + StorageURI *string `json:"storageUri,omitempty"` +} + +// BootDiagnosticsInstanceView is the instance view of a virtual machine boot +// diagnostics. +type BootDiagnosticsInstanceView struct { + ConsoleScreenshotBlobURI *string `json:"consoleScreenshotBlobUri,omitempty"` + SerialConsoleLogBlobURI *string `json:"serialConsoleLogBlobUri,omitempty"` +} + +// DataDisk is describes a data disk. +type DataDisk struct { + Lun *int32 `json:"lun,omitempty"` + Name *string `json:"name,omitempty"` + Vhd *VirtualHardDisk `json:"vhd,omitempty"` + Image *VirtualHardDisk `json:"image,omitempty"` + Caching CachingTypes `json:"caching,omitempty"` + CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` +} + +// DataDiskImage is contains the data disk images information. +type DataDiskImage struct { + Lun *int32 `json:"lun,omitempty"` +} + +// DiagnosticsProfile is describes a diagnostics profile. +type DiagnosticsProfile struct { + BootDiagnostics *BootDiagnostics `json:"bootDiagnostics,omitempty"` +} + +// DiskEncryptionSettings is describes a Encryption Settings for a Disk +type DiskEncryptionSettings struct { + DiskEncryptionKey *KeyVaultSecretReference `json:"diskEncryptionKey,omitempty"` + KeyEncryptionKey *KeyVaultKeyReference `json:"keyEncryptionKey,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +// DiskInstanceView is the instance view of the disk. +type DiskInstanceView struct { + Name *string `json:"name,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// HardwareProfile is describes a hardware profile. +type HardwareProfile struct { + VMSize VirtualMachineSizeTypes `json:"vmSize,omitempty"` +} + +// ImageReference is the image reference. +type ImageReference struct { + Publisher *string `json:"publisher,omitempty"` + Offer *string `json:"offer,omitempty"` + Sku *string `json:"sku,omitempty"` + Version *string `json:"version,omitempty"` +} + +// InnerError is inner error details. +type InnerError struct { + Exceptiontype *string `json:"exceptiontype,omitempty"` + Errordetail *string `json:"errordetail,omitempty"` +} + +// InstanceViewStatus is instance view status. +type InstanceViewStatus struct { + Code *string `json:"code,omitempty"` + Level StatusLevelTypes `json:"level,omitempty"` + DisplayStatus *string `json:"displayStatus,omitempty"` + Message *string `json:"message,omitempty"` + Time *date.Time `json:"time,omitempty"` +} + +// KeyVaultKeyReference is describes a reference to Key Vault Key +type KeyVaultKeyReference struct { + KeyURL *string `json:"keyUrl,omitempty"` + SourceVault *SubResource `json:"sourceVault,omitempty"` +} + +// KeyVaultSecretReference is describes a reference to Key Vault Secret +type KeyVaultSecretReference struct { + SecretURL *string `json:"secretUrl,omitempty"` + SourceVault *SubResource `json:"sourceVault,omitempty"` +} + +// LinuxConfiguration is describes Windows Configuration of the OS Profile. +type LinuxConfiguration struct { + DisablePasswordAuthentication *bool `json:"disablePasswordAuthentication,omitempty"` + SSH *SSHConfiguration `json:"ssh,omitempty"` +} + +// ListUsagesResult is the List Usages operation response. +type ListUsagesResult struct { + autorest.Response `json:"-"` + Value *[]Usage `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ListUsagesResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ListUsagesResult) ListUsagesResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ListVirtualMachineExtensionImage is +type ListVirtualMachineExtensionImage struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineExtensionImage `json:"value,omitempty"` +} + +// ListVirtualMachineImageResource is +type ListVirtualMachineImageResource struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineImageResource `json:"value,omitempty"` +} + +// LongRunningOperationProperties is compute-specific operation properties, +// including output +type LongRunningOperationProperties struct { + Output *map[string]interface{} `json:"output,omitempty"` +} + +// NetworkInterfaceReference is describes a network interface reference. +type NetworkInterfaceReference struct { + ID *string `json:"id,omitempty"` + Properties *NetworkInterfaceReferenceProperties `json:"properties,omitempty"` +} + +// NetworkInterfaceReferenceProperties is describes a network interface +// reference properties. +type NetworkInterfaceReferenceProperties struct { + Primary *bool `json:"primary,omitempty"` +} + +// NetworkProfile is describes a network profile. +type NetworkProfile struct { + NetworkInterfaces *[]NetworkInterfaceReference `json:"networkInterfaces,omitempty"` +} + +// OSDisk is describes an Operating System disk. +type OSDisk struct { + OsType OperatingSystemTypes `json:"osType,omitempty"` + EncryptionSettings *DiskEncryptionSettings `json:"encryptionSettings,omitempty"` + Name *string `json:"name,omitempty"` + Vhd *VirtualHardDisk `json:"vhd,omitempty"` + Image *VirtualHardDisk `json:"image,omitempty"` + Caching CachingTypes `json:"caching,omitempty"` + CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` +} + +// OSDiskImage is contains the os disk image information. +type OSDiskImage struct { + OperatingSystem OperatingSystemTypes `json:"operatingSystem,omitempty"` +} + +// OSProfile is describes an OS profile. +type OSProfile struct { + ComputerName *string `json:"computerName,omitempty"` + AdminUsername *string `json:"adminUsername,omitempty"` + AdminPassword *string `json:"adminPassword,omitempty"` + CustomData *string `json:"customData,omitempty"` + WindowsConfiguration *WindowsConfiguration `json:"windowsConfiguration,omitempty"` + LinuxConfiguration *LinuxConfiguration `json:"linuxConfiguration,omitempty"` + Secrets *[]VaultSecretGroup `json:"secrets,omitempty"` +} + +// Plan is plan for the resource. +type Plan struct { + Name *string `json:"name,omitempty"` + Publisher *string `json:"publisher,omitempty"` + Product *string `json:"product,omitempty"` + PromotionCode *string `json:"promotionCode,omitempty"` +} + +// PurchasePlan is used for establishing the purchase context of any 3rd Party +// artifact through MarketPlace. +type PurchasePlan struct { + Publisher *string `json:"publisher,omitempty"` + Name *string `json:"name,omitempty"` + Product *string `json:"product,omitempty"` +} + +// Resource is +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// Sku is describes a virtual machine scale set sku. +type Sku struct { + Name *string `json:"name,omitempty"` + Tier *string `json:"tier,omitempty"` + Capacity *int64 `json:"capacity,omitempty"` +} + +// SSHConfiguration is sSH configuration for Linux based VMs running on Azure +type SSHConfiguration struct { + PublicKeys *[]SSHPublicKey `json:"publicKeys,omitempty"` +} + +// SSHPublicKey is contains information about SSH certificate public key and +// the path on the Linux VM where the public key is placed. +type SSHPublicKey struct { + Path *string `json:"path,omitempty"` + KeyData *string `json:"keyData,omitempty"` +} + +// StorageProfile is describes a storage profile. +type StorageProfile struct { + ImageReference *ImageReference `json:"imageReference,omitempty"` + OsDisk *OSDisk `json:"osDisk,omitempty"` + DataDisks *[]DataDisk `json:"dataDisks,omitempty"` +} + +// SubResource is +type SubResource struct { + ID *string `json:"id,omitempty"` +} + +// UpgradePolicy is describes an upgrade policy - automatic or manual. +type UpgradePolicy struct { + Mode UpgradeMode `json:"mode,omitempty"` +} + +// Usage is describes Compute Resource Usage. +type Usage struct { + Unit *string `json:"unit,omitempty"` + CurrentValue *int32 `json:"currentValue,omitempty"` + Limit *int64 `json:"limit,omitempty"` + Name *UsageName `json:"name,omitempty"` +} + +// UsageName is the Usage Names. +type UsageName struct { + Value *string `json:"value,omitempty"` + LocalizedValue *string `json:"localizedValue,omitempty"` +} + +// VaultCertificate is describes a single certificate reference in a Key +// Vault, and where the certificate should reside on the VM. +type VaultCertificate struct { + CertificateURL *string `json:"certificateUrl,omitempty"` + CertificateStore *string `json:"certificateStore,omitempty"` +} + +// VaultSecretGroup is describes a set of certificates which are all in the +// same Key Vault. +type VaultSecretGroup struct { + SourceVault *SubResource `json:"sourceVault,omitempty"` + VaultCertificates *[]VaultCertificate `json:"vaultCertificates,omitempty"` +} + +// VirtualHardDisk is describes the uri of a disk. +type VirtualHardDisk struct { + URI *string `json:"uri,omitempty"` +} + +// VirtualMachine is describes a Virtual Machine. +type VirtualMachine struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Plan *Plan `json:"plan,omitempty"` + Properties *VirtualMachineProperties `json:"properties,omitempty"` + Resources *[]VirtualMachineExtension `json:"resources,omitempty"` +} + +// VirtualMachineAgentInstanceView is the instance view of the VM Agent +// running on the virtual machine. +type VirtualMachineAgentInstanceView struct { + VMAgentVersion *string `json:"vmAgentVersion,omitempty"` + ExtensionHandlers *[]VirtualMachineExtensionHandlerInstanceView `json:"extensionHandlers,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// VirtualMachineCaptureParameters is capture Virtual Machine parameters. +type VirtualMachineCaptureParameters struct { + VhdPrefix *string `json:"vhdPrefix,omitempty"` + DestinationContainerName *string `json:"destinationContainerName,omitempty"` + OverwriteVhds *bool `json:"overwriteVhds,omitempty"` +} + +// VirtualMachineCaptureResult is resource Id. +type VirtualMachineCaptureResult struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *VirtualMachineCaptureResultProperties `json:"properties,omitempty"` +} + +// VirtualMachineCaptureResultProperties is compute-specific operation +// properties, including output +type VirtualMachineCaptureResultProperties struct { + Output *map[string]interface{} `json:"output,omitempty"` +} + +// VirtualMachineExtension is describes a Virtual Machine Extension. +type VirtualMachineExtension struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VirtualMachineExtensionProperties `json:"properties,omitempty"` +} + +// VirtualMachineExtensionHandlerInstanceView is the instance view of a +// virtual machine extension handler. +type VirtualMachineExtensionHandlerInstanceView struct { + Type *string `json:"type,omitempty"` + TypeHandlerVersion *string `json:"typeHandlerVersion,omitempty"` + Status *InstanceViewStatus `json:"status,omitempty"` +} + +// VirtualMachineExtensionImage is describes a Virtual Machine Extension Image. +type VirtualMachineExtensionImage struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VirtualMachineExtensionImageProperties `json:"properties,omitempty"` +} + +// VirtualMachineExtensionImageProperties is describes the properties of a +// Virtual Machine Extension Image. +type VirtualMachineExtensionImageProperties struct { + OperatingSystem *string `json:"operatingSystem,omitempty"` + ComputeRole *string `json:"computeRole,omitempty"` + HandlerSchema *string `json:"handlerSchema,omitempty"` + VMScaleSetEnabled *bool `json:"vmScaleSetEnabled,omitempty"` + SupportsMultipleExtensions *bool `json:"supportsMultipleExtensions,omitempty"` +} + +// VirtualMachineExtensionInstanceView is the instance view of a virtual +// machine extension. +type VirtualMachineExtensionInstanceView struct { + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + TypeHandlerVersion *string `json:"typeHandlerVersion,omitempty"` + Substatuses *[]InstanceViewStatus `json:"substatuses,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// VirtualMachineExtensionProperties is describes the properties of a Virtual +// Machine Extension. +type VirtualMachineExtensionProperties struct { + ForceUpdateTag *string `json:"forceUpdateTag,omitempty"` + Publisher *string `json:"publisher,omitempty"` + Type *string `json:"type,omitempty"` + TypeHandlerVersion *string `json:"typeHandlerVersion,omitempty"` + AutoUpgradeMinorVersion *bool `json:"autoUpgradeMinorVersion,omitempty"` + Settings *map[string]interface{} `json:"settings,omitempty"` + ProtectedSettings *map[string]interface{} `json:"protectedSettings,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + InstanceView *VirtualMachineExtensionInstanceView `json:"instanceView,omitempty"` +} + +// VirtualMachineImage is describes a Virtual Machine Image. +type VirtualMachineImage struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VirtualMachineImageProperties `json:"properties,omitempty"` +} + +// VirtualMachineImageProperties is describes the properties of a Virtual +// Machine Image. +type VirtualMachineImageProperties struct { + Plan *PurchasePlan `json:"plan,omitempty"` + OsDiskImage *OSDiskImage `json:"osDiskImage,omitempty"` + DataDiskImages *[]DataDiskImage `json:"dataDiskImages,omitempty"` +} + +// VirtualMachineImageResource is virtual machine image resource information. +type VirtualMachineImageResource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// VirtualMachineInstanceView is the instance view of a virtual machine. +type VirtualMachineInstanceView struct { + PlatformUpdateDomain *int32 `json:"platformUpdateDomain,omitempty"` + PlatformFaultDomain *int32 `json:"platformFaultDomain,omitempty"` + RdpThumbPrint *string `json:"rdpThumbPrint,omitempty"` + VMAgent *VirtualMachineAgentInstanceView `json:"vmAgent,omitempty"` + Disks *[]DiskInstanceView `json:"disks,omitempty"` + Extensions *[]VirtualMachineExtensionInstanceView `json:"extensions,omitempty"` + BootDiagnostics *BootDiagnosticsInstanceView `json:"bootDiagnostics,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// VirtualMachineListResult is the List Virtual Machine operation response. +type VirtualMachineListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachine `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualMachineListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualMachineListResult) VirtualMachineListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualMachineProperties is describes the properties of a Virtual Machine. +type VirtualMachineProperties struct { + HardwareProfile *HardwareProfile `json:"hardwareProfile,omitempty"` + StorageProfile *StorageProfile `json:"storageProfile,omitempty"` + OsProfile *OSProfile `json:"osProfile,omitempty"` + NetworkProfile *NetworkProfile `json:"networkProfile,omitempty"` + DiagnosticsProfile *DiagnosticsProfile `json:"diagnosticsProfile,omitempty"` + AvailabilitySet *SubResource `json:"availabilitySet,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + InstanceView *VirtualMachineInstanceView `json:"instanceView,omitempty"` + LicenseType *string `json:"licenseType,omitempty"` + VMID *string `json:"vmId,omitempty"` +} + +// VirtualMachineScaleSet is describes a Virtual Machine Scale Set. +type VirtualMachineScaleSet struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Sku *Sku `json:"sku,omitempty"` + Properties *VirtualMachineScaleSetProperties `json:"properties,omitempty"` +} + +// VirtualMachineScaleSetExtension is describes a Virtual Machine Scale Set +// Extension. +type VirtualMachineScaleSetExtension struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *VirtualMachineScaleSetExtensionProperties `json:"properties,omitempty"` +} + +// VirtualMachineScaleSetExtensionProfile is describes a virtual machine scale +// set extension profile. +type VirtualMachineScaleSetExtensionProfile struct { + Extensions *[]VirtualMachineScaleSetExtension `json:"extensions,omitempty"` +} + +// VirtualMachineScaleSetExtensionProperties is describes the properties of a +// Virtual Machine Scale Set Extension. +type VirtualMachineScaleSetExtensionProperties struct { + Publisher *string `json:"publisher,omitempty"` + Type *string `json:"type,omitempty"` + TypeHandlerVersion *string `json:"typeHandlerVersion,omitempty"` + AutoUpgradeMinorVersion *bool `json:"autoUpgradeMinorVersion,omitempty"` + Settings *map[string]interface{} `json:"settings,omitempty"` + ProtectedSettings *map[string]interface{} `json:"protectedSettings,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VirtualMachineScaleSetInstanceView is the instance view of a virtual +// machine scale set. +type VirtualMachineScaleSetInstanceView struct { + autorest.Response `json:"-"` + VirtualMachine *VirtualMachineScaleSetInstanceViewStatusesSummary `json:"virtualMachine,omitempty"` + Extensions *[]VirtualMachineScaleSetVMExtensionsSummary `json:"extensions,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// VirtualMachineScaleSetInstanceViewStatusesSummary is instance view statuses +// summary for virtual machines of a virtual machine scale set. +type VirtualMachineScaleSetInstanceViewStatusesSummary struct { + StatusesSummary *[]VirtualMachineStatusCodeCount `json:"statusesSummary,omitempty"` +} + +// VirtualMachineScaleSetIPConfiguration is describes a virtual machine scale +// set network profile's IP configuration. +type VirtualMachineScaleSetIPConfiguration struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *VirtualMachineScaleSetIPConfigurationProperties `json:"properties,omitempty"` +} + +// VirtualMachineScaleSetIPConfigurationProperties is describes a virtual +// machine scale set network profile's IP configuration properties. +type VirtualMachineScaleSetIPConfigurationProperties struct { + Subnet *APIEntityReference `json:"subnet,omitempty"` + ApplicationGatewayBackendAddressPools *[]SubResource `json:"applicationGatewayBackendAddressPools,omitempty"` + LoadBalancerBackendAddressPools *[]SubResource `json:"loadBalancerBackendAddressPools,omitempty"` + LoadBalancerInboundNatPools *[]SubResource `json:"loadBalancerInboundNatPools,omitempty"` +} + +// VirtualMachineScaleSetListResult is the List Virtual Machine operation +// response. +type VirtualMachineScaleSetListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineScaleSet `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualMachineScaleSetListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualMachineScaleSetListResult) VirtualMachineScaleSetListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualMachineScaleSetListSkusResult is the Virtual Machine Scale Set List +// Skus operation response. +type VirtualMachineScaleSetListSkusResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineScaleSetSku `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualMachineScaleSetListSkusResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualMachineScaleSetListSkusResult) VirtualMachineScaleSetListSkusResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualMachineScaleSetListWithLinkResult is the List Virtual Machine +// operation response. +type VirtualMachineScaleSetListWithLinkResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineScaleSet `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualMachineScaleSetListWithLinkResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualMachineScaleSetListWithLinkResult) VirtualMachineScaleSetListWithLinkResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualMachineScaleSetNetworkConfiguration is describes a virtual machine +// scale set network profile's network configurations. +type VirtualMachineScaleSetNetworkConfiguration struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *VirtualMachineScaleSetNetworkConfigurationProperties `json:"properties,omitempty"` +} + +// VirtualMachineScaleSetNetworkConfigurationProperties is describes a virtual +// machine scale set network profile's IP configuration. +type VirtualMachineScaleSetNetworkConfigurationProperties struct { + Primary *bool `json:"primary,omitempty"` + IPConfigurations *[]VirtualMachineScaleSetIPConfiguration `json:"ipConfigurations,omitempty"` +} + +// VirtualMachineScaleSetNetworkProfile is describes a virtual machine scale +// set network profile. +type VirtualMachineScaleSetNetworkProfile struct { + NetworkInterfaceConfigurations *[]VirtualMachineScaleSetNetworkConfiguration `json:"networkInterfaceConfigurations,omitempty"` +} + +// VirtualMachineScaleSetOSDisk is describes a virtual machine scale set +// operating system disk. +type VirtualMachineScaleSetOSDisk struct { + Name *string `json:"name,omitempty"` + Caching CachingTypes `json:"caching,omitempty"` + CreateOption DiskCreateOptionTypes `json:"createOption,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + Image *VirtualHardDisk `json:"image,omitempty"` + VhdContainers *[]string `json:"vhdContainers,omitempty"` +} + +// VirtualMachineScaleSetOSProfile is describes a virtual machine scale set OS +// profile. +type VirtualMachineScaleSetOSProfile struct { + ComputerNamePrefix *string `json:"computerNamePrefix,omitempty"` + AdminUsername *string `json:"adminUsername,omitempty"` + AdminPassword *string `json:"adminPassword,omitempty"` + CustomData *string `json:"customData,omitempty"` + WindowsConfiguration *WindowsConfiguration `json:"windowsConfiguration,omitempty"` + LinuxConfiguration *LinuxConfiguration `json:"linuxConfiguration,omitempty"` + Secrets *[]VaultSecretGroup `json:"secrets,omitempty"` +} + +// VirtualMachineScaleSetProperties is describes the properties of a Virtual +// Machine Scale Set. +type VirtualMachineScaleSetProperties struct { + UpgradePolicy *UpgradePolicy `json:"upgradePolicy,omitempty"` + VirtualMachineProfile *VirtualMachineScaleSetVMProfile `json:"virtualMachineProfile,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + OverProvision *bool `json:"overProvision,omitempty"` +} + +// VirtualMachineScaleSetSku is describes an available virtual machine scale +// set sku. +type VirtualMachineScaleSetSku struct { + ResourceType *string `json:"resourceType,omitempty"` + Sku *Sku `json:"sku,omitempty"` + Capacity *VirtualMachineScaleSetSkuCapacity `json:"capacity,omitempty"` +} + +// VirtualMachineScaleSetSkuCapacity is describes scaling information of a sku. +type VirtualMachineScaleSetSkuCapacity struct { + Minimum *int64 `json:"minimum,omitempty"` + Maximum *int64 `json:"maximum,omitempty"` + DefaultCapacity *int64 `json:"defaultCapacity,omitempty"` + ScaleType VirtualMachineScaleSetSkuScaleType `json:"scaleType,omitempty"` +} + +// VirtualMachineScaleSetStorageProfile is describes a virtual machine scale +// set storage profile. +type VirtualMachineScaleSetStorageProfile struct { + ImageReference *ImageReference `json:"imageReference,omitempty"` + OsDisk *VirtualMachineScaleSetOSDisk `json:"osDisk,omitempty"` +} + +// VirtualMachineScaleSetVM is describes a virtual machine scale set virtual +// machine. +type VirtualMachineScaleSetVM struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + InstanceID *string `json:"instanceId,omitempty"` + Sku *Sku `json:"sku,omitempty"` + Properties *VirtualMachineScaleSetVMProperties `json:"properties,omitempty"` + Plan *Plan `json:"plan,omitempty"` + Resources *[]VirtualMachineExtension `json:"resources,omitempty"` +} + +// VirtualMachineScaleSetVMExtensionsSummary is extensions summary for virtual +// machines of a virtual machine scale set. +type VirtualMachineScaleSetVMExtensionsSummary struct { + Name *string `json:"name,omitempty"` + StatusesSummary *[]VirtualMachineStatusCodeCount `json:"statusesSummary,omitempty"` +} + +// VirtualMachineScaleSetVMInstanceIDs is specifies the list of virtual +// machine scale set instance IDs. +type VirtualMachineScaleSetVMInstanceIDs struct { + InstanceIds *[]string `json:"instanceIds,omitempty"` +} + +// VirtualMachineScaleSetVMInstanceRequiredIDs is specifies the list of +// virtual machine scale set instance IDs. +type VirtualMachineScaleSetVMInstanceRequiredIDs struct { + InstanceIds *[]string `json:"instanceIds,omitempty"` +} + +// VirtualMachineScaleSetVMInstanceView is the instance view of a virtual +// machine scale set VM. +type VirtualMachineScaleSetVMInstanceView struct { + autorest.Response `json:"-"` + PlatformUpdateDomain *int32 `json:"platformUpdateDomain,omitempty"` + PlatformFaultDomain *int32 `json:"platformFaultDomain,omitempty"` + RdpThumbPrint *string `json:"rdpThumbPrint,omitempty"` + VMAgent *VirtualMachineAgentInstanceView `json:"vmAgent,omitempty"` + Disks *[]DiskInstanceView `json:"disks,omitempty"` + Extensions *[]VirtualMachineExtensionInstanceView `json:"extensions,omitempty"` + BootDiagnostics *BootDiagnosticsInstanceView `json:"bootDiagnostics,omitempty"` + Statuses *[]InstanceViewStatus `json:"statuses,omitempty"` +} + +// VirtualMachineScaleSetVMListResult is the List Virtual Machine Scale Set +// VMs operation response. +type VirtualMachineScaleSetVMListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineScaleSetVM `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualMachineScaleSetVMListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualMachineScaleSetVMListResult) VirtualMachineScaleSetVMListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualMachineScaleSetVMProfile is describes a virtual machine scale set +// virtual machine profile. +type VirtualMachineScaleSetVMProfile struct { + OsProfile *VirtualMachineScaleSetOSProfile `json:"osProfile,omitempty"` + StorageProfile *VirtualMachineScaleSetStorageProfile `json:"storageProfile,omitempty"` + NetworkProfile *VirtualMachineScaleSetNetworkProfile `json:"networkProfile,omitempty"` + ExtensionProfile *VirtualMachineScaleSetExtensionProfile `json:"extensionProfile,omitempty"` +} + +// VirtualMachineScaleSetVMProperties is describes the properties of a virtual +// machine scale set virtual machine. +type VirtualMachineScaleSetVMProperties struct { + LatestModelApplied *bool `json:"latestModelApplied,omitempty"` + InstanceView *VirtualMachineInstanceView `json:"instanceView,omitempty"` + HardwareProfile *HardwareProfile `json:"hardwareProfile,omitempty"` + StorageProfile *StorageProfile `json:"storageProfile,omitempty"` + OsProfile *OSProfile `json:"osProfile,omitempty"` + NetworkProfile *NetworkProfile `json:"networkProfile,omitempty"` + DiagnosticsProfile *DiagnosticsProfile `json:"diagnosticsProfile,omitempty"` + AvailabilitySet *SubResource `json:"availabilitySet,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + LicenseType *string `json:"licenseType,omitempty"` +} + +// VirtualMachineSize is describes the properties of a VM size. +type VirtualMachineSize struct { + Name *string `json:"name,omitempty"` + NumberOfCores *int32 `json:"numberOfCores,omitempty"` + OsDiskSizeInMB *int32 `json:"osDiskSizeInMB,omitempty"` + ResourceDiskSizeInMB *int32 `json:"resourceDiskSizeInMB,omitempty"` + MemoryInMB *int32 `json:"memoryInMB,omitempty"` + MaxDataDiskCount *int32 `json:"maxDataDiskCount,omitempty"` +} + +// VirtualMachineSizeListResult is the List Virtual Machine operation response. +type VirtualMachineSizeListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineSize `json:"value,omitempty"` +} + +// VirtualMachineStatusCodeCount is the status code and count of the virtual +// machine scale set instance view status summary. +type VirtualMachineStatusCodeCount struct { + Code *string `json:"code,omitempty"` + Count *int32 `json:"count,omitempty"` +} + +// WindowsConfiguration is describes Windows Configuration of the OS Profile. +type WindowsConfiguration struct { + ProvisionVMAgent *bool `json:"provisionVMAgent,omitempty"` + EnableAutomaticUpdates *bool `json:"enableAutomaticUpdates,omitempty"` + TimeZone *string `json:"timeZone,omitempty"` + AdditionalUnattendContent *[]AdditionalUnattendContent `json:"additionalUnattendContent,omitempty"` + WinRM *WinRMConfiguration `json:"winRM,omitempty"` +} + +// WinRMConfiguration is describes Windows Remote Management configuration of +// the VM +type WinRMConfiguration struct { + Listeners *[]WinRMListener `json:"listeners,omitempty"` +} + +// WinRMListener is describes Protocol and thumbprint of Windows Remote +// Management listener +type WinRMListener struct { + Protocol ProtocolTypes `json:"protocol,omitempty"` + CertificateURL *string `json:"certificateUrl,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go new file mode 100644 index 0000000000..474c7ca9fc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go @@ -0,0 +1,134 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// UsageOperationsClient is the the Compute Management Client. +type UsageOperationsClient struct { + ManagementClient +} + +// NewUsageOperationsClient creates an instance of the UsageOperationsClient +// client. +func NewUsageOperationsClient(subscriptionID string) UsageOperationsClient { + return NewUsageOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewUsageOperationsClientWithBaseURI creates an instance of the +// UsageOperationsClient client. +func NewUsageOperationsClientWithBaseURI(baseURI string, subscriptionID string) UsageOperationsClient { + return UsageOperationsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List lists compute usages for a subscription. +// +// location is the location upon which resource usage is queried. +func (client UsageOperationsClient) List(location string) (result ListUsagesResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: location, + Constraints: []validation.Constraint{{Target: "location", Name: validation.Pattern, Rule: `^[-\w\._]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.UsageOperationsClient", "List") + } + + req, err := client.ListPreparer(location) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.UsageOperationsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.UsageOperationsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.UsageOperationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client UsageOperationsClient) ListPreparer(location string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/usages", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client UsageOperationsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client UsageOperationsClient) ListResponder(resp *http.Response) (result ListUsagesResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client UsageOperationsClient) ListNextResults(lastResults ListUsagesResult) (result ListUsagesResult, err error) { + req, err := lastResults.ListUsagesResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.UsageOperationsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.UsageOperationsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.UsageOperationsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/version.go new file mode 100644 index 0000000000..3ebd0b807d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/version.go @@ -0,0 +1,43 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "5" + minor = "0" + patch = "0" + // Always begin a "tag" with a dash (as per http://semver.org) + tag = "-beta" + semVerFormat = "%s.%s.%s%s" + userAgentFormat = "Azure-SDK-for-Go/%s arm-%s/%s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "compute", "2016-03-30") +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go new file mode 100644 index 0000000000..089ebe10e8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go @@ -0,0 +1,238 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualMachineExtensionImagesClient is the the Compute Management Client. +type VirtualMachineExtensionImagesClient struct { + ManagementClient +} + +// NewVirtualMachineExtensionImagesClient creates an instance of the +// VirtualMachineExtensionImagesClient client. +func NewVirtualMachineExtensionImagesClient(subscriptionID string) VirtualMachineExtensionImagesClient { + return NewVirtualMachineExtensionImagesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachineExtensionImagesClientWithBaseURI creates an instance of +// the VirtualMachineExtensionImagesClient client. +func NewVirtualMachineExtensionImagesClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachineExtensionImagesClient { + return VirtualMachineExtensionImagesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Get gets a virtual machine extension image. +// +func (client VirtualMachineExtensionImagesClient) Get(location string, publisherName string, typeParameter string, version string) (result VirtualMachineExtensionImage, err error) { + req, err := client.GetPreparer(location, publisherName, typeParameter, version) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualMachineExtensionImagesClient) GetPreparer(location string, publisherName string, typeParameter string, version string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "publisherName": autorest.Encode("path", publisherName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "type": autorest.Encode("path", typeParameter), + "version": autorest.Encode("path", version), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmextension/types/{type}/versions/{version}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionImagesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionImagesClient) GetResponder(resp *http.Response) (result VirtualMachineExtensionImage, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListTypes gets a list of virtual machine extension image types. +// +func (client VirtualMachineExtensionImagesClient) ListTypes(location string, publisherName string) (result ListVirtualMachineExtensionImage, err error) { + req, err := client.ListTypesPreparer(location, publisherName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "ListTypes", nil, "Failure preparing request") + } + + resp, err := client.ListTypesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "ListTypes", resp, "Failure sending request") + } + + result, err = client.ListTypesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "ListTypes", resp, "Failure responding to request") + } + + return +} + +// ListTypesPreparer prepares the ListTypes request. +func (client VirtualMachineExtensionImagesClient) ListTypesPreparer(location string, publisherName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "publisherName": autorest.Encode("path", publisherName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmextension/types", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListTypesSender sends the ListTypes request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionImagesClient) ListTypesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListTypesResponder handles the response to the ListTypes request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionImagesClient) ListTypesResponder(resp *http.Response) (result ListVirtualMachineExtensionImage, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListVersions gets a list of virtual machine extension image versions. +// +// filter is the filter to apply on the operation. +func (client VirtualMachineExtensionImagesClient) ListVersions(location string, publisherName string, typeParameter string, filter string, top *int32, orderby string) (result ListVirtualMachineExtensionImage, err error) { + req, err := client.ListVersionsPreparer(location, publisherName, typeParameter, filter, top, orderby) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "ListVersions", nil, "Failure preparing request") + } + + resp, err := client.ListVersionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "ListVersions", resp, "Failure sending request") + } + + result, err = client.ListVersionsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionImagesClient", "ListVersions", resp, "Failure responding to request") + } + + return +} + +// ListVersionsPreparer prepares the ListVersions request. +func (client VirtualMachineExtensionImagesClient) ListVersionsPreparer(location string, publisherName string, typeParameter string, filter string, top *int32, orderby string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "publisherName": autorest.Encode("path", publisherName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "type": autorest.Encode("path", typeParameter), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + if len(orderby) > 0 { + queryParameters["$orderby"] = autorest.Encode("query", orderby) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmextension/types/{type}/versions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListVersionsSender sends the ListVersions request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionImagesClient) ListVersionsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListVersionsResponder handles the response to the ListVersions request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionImagesClient) ListVersionsResponder(resp *http.Response) (result ListVirtualMachineExtensionImage, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go new file mode 100644 index 0000000000..dbbce547af --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go @@ -0,0 +1,261 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// VirtualMachineExtensionsClient is the the Compute Management Client. +type VirtualMachineExtensionsClient struct { + ManagementClient +} + +// NewVirtualMachineExtensionsClient creates an instance of the +// VirtualMachineExtensionsClient client. +func NewVirtualMachineExtensionsClient(subscriptionID string) VirtualMachineExtensionsClient { + return NewVirtualMachineExtensionsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachineExtensionsClientWithBaseURI creates an instance of the +// VirtualMachineExtensionsClient client. +func NewVirtualMachineExtensionsClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachineExtensionsClient { + return VirtualMachineExtensionsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the operation to create or update the extension. This method +// may poll for completion. Polling can be canceled by passing the cancel +// channel argument. The channel will be used to cancel polling and any +// outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine where the extension should be create or updated. +// vmExtensionName is the name of the virtual machine extension. +// extensionParameters is parameters supplied to the Create Virtual Machine +// Extension operation. +func (client VirtualMachineExtensionsClient) CreateOrUpdate(resourceGroupName string, vmName string, vmExtensionName string, extensionParameters VirtualMachineExtension, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: extensionParameters, + Constraints: []validation.Constraint{{Target: "extensionParameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "extensionParameters.Properties.ProvisioningState", Name: validation.ReadOnly, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachineExtensionsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, vmName, vmExtensionName, extensionParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualMachineExtensionsClient) CreateOrUpdatePreparer(resourceGroupName string, vmName string, vmExtensionName string, extensionParameters VirtualMachineExtension, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmExtensionName": autorest.Encode("path", vmExtensionName), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/extensions/{vmExtensionName}", pathParameters), + autorest.WithJSON(extensionParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the operation to delete the extension. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine where the extension should be deleted. vmExtensionName +// is the name of the virtual machine extension. +func (client VirtualMachineExtensionsClient) Delete(resourceGroupName string, vmName string, vmExtensionName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, vmName, vmExtensionName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualMachineExtensionsClient) DeletePreparer(resourceGroupName string, vmName string, vmExtensionName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmExtensionName": autorest.Encode("path", vmExtensionName), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/extensions/{vmExtensionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the operation to get the extension. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine containing the extension. vmExtensionName is the name +// of the virtual machine extension. expand is the expand expression to apply +// on the operation. +func (client VirtualMachineExtensionsClient) Get(resourceGroupName string, vmName string, vmExtensionName string, expand string) (result VirtualMachineExtension, err error) { + req, err := client.GetPreparer(resourceGroupName, vmName, vmExtensionName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualMachineExtensionsClient) GetPreparer(resourceGroupName string, vmName string, vmExtensionName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmExtensionName": autorest.Encode("path", vmExtensionName), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/extensions/{vmExtensionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionsClient) GetResponder(resp *http.Response) (result VirtualMachineExtension, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go new file mode 100644 index 0000000000..50d9614602 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go @@ -0,0 +1,362 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualMachineImagesClient is the the Compute Management Client. +type VirtualMachineImagesClient struct { + ManagementClient +} + +// NewVirtualMachineImagesClient creates an instance of the +// VirtualMachineImagesClient client. +func NewVirtualMachineImagesClient(subscriptionID string) VirtualMachineImagesClient { + return NewVirtualMachineImagesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachineImagesClientWithBaseURI creates an instance of the +// VirtualMachineImagesClient client. +func NewVirtualMachineImagesClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachineImagesClient { + return VirtualMachineImagesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Get gets a virtual machine image. +// +func (client VirtualMachineImagesClient) Get(location string, publisherName string, offer string, skus string, version string) (result VirtualMachineImage, err error) { + req, err := client.GetPreparer(location, publisherName, offer, skus, version) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualMachineImagesClient) GetPreparer(location string, publisherName string, offer string, skus string, version string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "offer": autorest.Encode("path", offer), + "publisherName": autorest.Encode("path", publisherName), + "skus": autorest.Encode("path", skus), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "version": autorest.Encode("path", version), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmimage/offers/{offer}/skus/{skus}/versions/{version}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineImagesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualMachineImagesClient) GetResponder(resp *http.Response) (result VirtualMachineImage, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of virtual machine images. +// +// filter is the filter to apply on the operation. +func (client VirtualMachineImagesClient) List(location string, publisherName string, offer string, skus string, filter string, top *int32, orderby string) (result ListVirtualMachineImageResource, err error) { + req, err := client.ListPreparer(location, publisherName, offer, skus, filter, top, orderby) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualMachineImagesClient) ListPreparer(location string, publisherName string, offer string, skus string, filter string, top *int32, orderby string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "offer": autorest.Encode("path", offer), + "publisherName": autorest.Encode("path", publisherName), + "skus": autorest.Encode("path", skus), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + if len(orderby) > 0 { + queryParameters["$orderby"] = autorest.Encode("query", orderby) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmimage/offers/{offer}/skus/{skus}/versions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineImagesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualMachineImagesClient) ListResponder(resp *http.Response) (result ListVirtualMachineImageResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListOffers gets a list of virtual machine image offers. +// +func (client VirtualMachineImagesClient) ListOffers(location string, publisherName string) (result ListVirtualMachineImageResource, err error) { + req, err := client.ListOffersPreparer(location, publisherName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListOffers", nil, "Failure preparing request") + } + + resp, err := client.ListOffersSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListOffers", resp, "Failure sending request") + } + + result, err = client.ListOffersResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListOffers", resp, "Failure responding to request") + } + + return +} + +// ListOffersPreparer prepares the ListOffers request. +func (client VirtualMachineImagesClient) ListOffersPreparer(location string, publisherName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "publisherName": autorest.Encode("path", publisherName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmimage/offers", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListOffersSender sends the ListOffers request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineImagesClient) ListOffersSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListOffersResponder handles the response to the ListOffers request. The method always +// closes the http.Response Body. +func (client VirtualMachineImagesClient) ListOffersResponder(resp *http.Response) (result ListVirtualMachineImageResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListPublishers gets a list of virtual machine image publishers. +// +func (client VirtualMachineImagesClient) ListPublishers(location string) (result ListVirtualMachineImageResource, err error) { + req, err := client.ListPublishersPreparer(location) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListPublishers", nil, "Failure preparing request") + } + + resp, err := client.ListPublishersSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListPublishers", resp, "Failure sending request") + } + + result, err = client.ListPublishersResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListPublishers", resp, "Failure responding to request") + } + + return +} + +// ListPublishersPreparer prepares the ListPublishers request. +func (client VirtualMachineImagesClient) ListPublishersPreparer(location string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListPublishersSender sends the ListPublishers request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineImagesClient) ListPublishersSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListPublishersResponder handles the response to the ListPublishers request. The method always +// closes the http.Response Body. +func (client VirtualMachineImagesClient) ListPublishersResponder(resp *http.Response) (result ListVirtualMachineImageResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSkus gets a list of virtual machine image skus. +// +func (client VirtualMachineImagesClient) ListSkus(location string, publisherName string, offer string) (result ListVirtualMachineImageResource, err error) { + req, err := client.ListSkusPreparer(location, publisherName, offer) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListSkus", nil, "Failure preparing request") + } + + resp, err := client.ListSkusSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListSkus", resp, "Failure sending request") + } + + result, err = client.ListSkusResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineImagesClient", "ListSkus", resp, "Failure responding to request") + } + + return +} + +// ListSkusPreparer prepares the ListSkus request. +func (client VirtualMachineImagesClient) ListSkusPreparer(location string, publisherName string, offer string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "offer": autorest.Encode("path", offer), + "publisherName": autorest.Encode("path", publisherName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/publishers/{publisherName}/artifacttypes/vmimage/offers/{offer}/skus", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSkusSender sends the ListSkus request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineImagesClient) ListSkusSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListSkusResponder handles the response to the ListSkus request. The method always +// closes the http.Response Body. +func (client VirtualMachineImagesClient) ListSkusResponder(resp *http.Response) (result ListVirtualMachineImageResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go new file mode 100644 index 0000000000..8b044e7744 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go @@ -0,0 +1,984 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// VirtualMachinesClient is the the Compute Management Client. +type VirtualMachinesClient struct { + ManagementClient +} + +// NewVirtualMachinesClient creates an instance of the VirtualMachinesClient +// client. +func NewVirtualMachinesClient(subscriptionID string) VirtualMachinesClient { + return NewVirtualMachinesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachinesClientWithBaseURI creates an instance of the +// VirtualMachinesClient client. +func NewVirtualMachinesClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachinesClient { + return VirtualMachinesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Capture captures the VM by copying virtual hard disks of the VM and outputs +// a template that can be used to create similar VMs. This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. parameters is parameters supplied to the Capture +// Virtual Machine operation. +func (client VirtualMachinesClient) Capture(resourceGroupName string, vmName string, parameters VirtualMachineCaptureParameters, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.VhdPrefix", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.DestinationContainerName", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.OverwriteVhds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachinesClient", "Capture") + } + + req, err := client.CapturePreparer(resourceGroupName, vmName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Capture", nil, "Failure preparing request") + } + + resp, err := client.CaptureSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Capture", resp, "Failure sending request") + } + + result, err = client.CaptureResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Capture", resp, "Failure responding to request") + } + + return +} + +// CapturePreparer prepares the Capture request. +func (client VirtualMachinesClient) CapturePreparer(resourceGroupName string, vmName string, parameters VirtualMachineCaptureParameters, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/capture", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CaptureSender sends the Capture request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) CaptureSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CaptureResponder handles the response to the Capture request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) CaptureResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// CreateOrUpdate the operation to create or update a virtual machine. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. parameters is parameters supplied to the Create +// Virtual Machine operation. +func (client VirtualMachinesClient) CreateOrUpdate(resourceGroupName string, vmName string, parameters VirtualMachine, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.StorageProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.StorageProfile.OsDisk", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties.StorageProfile.OsDisk.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + {Target: "parameters.Properties.StorageProfile.OsDisk.Name", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties.StorageProfile.OsDisk.Vhd", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + {Target: "parameters.Properties.ProvisioningState", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "parameters.Properties.InstanceView", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "parameters.Properties.VMID", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}, + {Target: "parameters.Resources", Name: validation.ReadOnly, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachinesClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, vmName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualMachinesClient) CreateOrUpdatePreparer(resourceGroupName string, vmName string, parameters VirtualMachine, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Deallocate shuts down the Virtual Machine and releases the compute +// resources. You are not billed for the compute resources that this Virtual +// Machine uses. This method may poll for completion. Polling can be canceled +// by passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) Deallocate(resourceGroupName string, vmName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeallocatePreparer(resourceGroupName, vmName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Deallocate", nil, "Failure preparing request") + } + + resp, err := client.DeallocateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Deallocate", resp, "Failure sending request") + } + + result, err = client.DeallocateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Deallocate", resp, "Failure responding to request") + } + + return +} + +// DeallocatePreparer prepares the Deallocate request. +func (client VirtualMachinesClient) DeallocatePreparer(resourceGroupName string, vmName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/deallocate", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeallocateSender sends the Deallocate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) DeallocateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeallocateResponder handles the response to the Deallocate request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) DeallocateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the operation to delete a virtual machine. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) Delete(resourceGroupName string, vmName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, vmName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualMachinesClient) DeletePreparer(resourceGroupName string, vmName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Generalize sets the state of the VM as Generalized. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) Generalize(resourceGroupName string, vmName string) (result autorest.Response, err error) { + req, err := client.GeneralizePreparer(resourceGroupName, vmName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Generalize", nil, "Failure preparing request") + } + + resp, err := client.GeneralizeSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Generalize", resp, "Failure sending request") + } + + result, err = client.GeneralizeResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Generalize", resp, "Failure responding to request") + } + + return +} + +// GeneralizePreparer prepares the Generalize request. +func (client VirtualMachinesClient) GeneralizePreparer(resourceGroupName string, vmName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/generalize", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GeneralizeSender sends the Generalize request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) GeneralizeSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GeneralizeResponder handles the response to the Generalize request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) GeneralizeResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the operation to get a virtual machine. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. expand is the expand expression to apply on the +// operation. Possible values include: 'instanceView' +func (client VirtualMachinesClient) Get(resourceGroupName string, vmName string, expand InstanceViewTypes) (result VirtualMachine, err error) { + req, err := client.GetPreparer(resourceGroupName, vmName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualMachinesClient) GetPreparer(resourceGroupName string, vmName string, expand InstanceViewTypes) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(string(expand)) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) GetResponder(resp *http.Response) (result VirtualMachine, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the operation to list virtual machines under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client VirtualMachinesClient) List(resourceGroupName string) (result VirtualMachineListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualMachinesClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) ListResponder(resp *http.Response) (result VirtualMachineListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualMachinesClient) ListNextResults(lastResults VirtualMachineListResult) (result VirtualMachineListResult, err error) { + req, err := lastResults.VirtualMachineListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll gets the list of Virtual Machines in the subscription. Use nextLink +// property in the response to get the next page of Virtual Machines. Do this +// till nextLink is not null to fetch all the Virtual Machines. +func (client VirtualMachinesClient) ListAll() (result VirtualMachineListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client VirtualMachinesClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachines", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) ListAllResponder(resp *http.Response) (result VirtualMachineListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client VirtualMachinesClient) ListAllNextResults(lastResults VirtualMachineListResult) (result VirtualMachineListResult, err error) { + req, err := lastResults.VirtualMachineListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} + +// ListAvailableSizes lists all available virtual machine sizes it can be +// resized to for a virtual machine. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) ListAvailableSizes(resourceGroupName string, vmName string) (result VirtualMachineSizeListResult, err error) { + req, err := client.ListAvailableSizesPreparer(resourceGroupName, vmName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAvailableSizes", nil, "Failure preparing request") + } + + resp, err := client.ListAvailableSizesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAvailableSizes", resp, "Failure sending request") + } + + result, err = client.ListAvailableSizesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "ListAvailableSizes", resp, "Failure responding to request") + } + + return +} + +// ListAvailableSizesPreparer prepares the ListAvailableSizes request. +func (client VirtualMachinesClient) ListAvailableSizesPreparer(resourceGroupName string, vmName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/vmSizes", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAvailableSizesSender sends the ListAvailableSizes request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) ListAvailableSizesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAvailableSizesResponder handles the response to the ListAvailableSizes request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) ListAvailableSizesResponder(resp *http.Response) (result VirtualMachineSizeListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// PowerOff the operation to power off (stop) a virtual machine. This method +// may poll for completion. Polling can be canceled by passing the cancel +// channel argument. The channel will be used to cancel polling and any +// outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) PowerOff(resourceGroupName string, vmName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.PowerOffPreparer(resourceGroupName, vmName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "PowerOff", nil, "Failure preparing request") + } + + resp, err := client.PowerOffSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "PowerOff", resp, "Failure sending request") + } + + result, err = client.PowerOffResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "PowerOff", resp, "Failure responding to request") + } + + return +} + +// PowerOffPreparer prepares the PowerOff request. +func (client VirtualMachinesClient) PowerOffPreparer(resourceGroupName string, vmName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/powerOff", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// PowerOffSender sends the PowerOff request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) PowerOffSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// PowerOffResponder handles the response to the PowerOff request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) PowerOffResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Redeploy the operation to redeploy a virtual machine. This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) Redeploy(resourceGroupName string, vmName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.RedeployPreparer(resourceGroupName, vmName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Redeploy", nil, "Failure preparing request") + } + + resp, err := client.RedeploySender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Redeploy", resp, "Failure sending request") + } + + result, err = client.RedeployResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Redeploy", resp, "Failure responding to request") + } + + return +} + +// RedeployPreparer prepares the Redeploy request. +func (client VirtualMachinesClient) RedeployPreparer(resourceGroupName string, vmName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/redeploy", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RedeploySender sends the Redeploy request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) RedeploySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RedeployResponder handles the response to the Redeploy request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) RedeployResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Restart the operation to restart a virtual machine. This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) Restart(resourceGroupName string, vmName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.RestartPreparer(resourceGroupName, vmName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Restart", nil, "Failure preparing request") + } + + resp, err := client.RestartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Restart", resp, "Failure sending request") + } + + result, err = client.RestartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Restart", resp, "Failure responding to request") + } + + return +} + +// RestartPreparer prepares the Restart request. +func (client VirtualMachinesClient) RestartPreparer(resourceGroupName string, vmName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/restart", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RestartSender sends the Restart request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) RestartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RestartResponder handles the response to the Restart request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) RestartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Start the operation to start a virtual machine. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmName is the name of +// the virtual machine. +func (client VirtualMachinesClient) Start(resourceGroupName string, vmName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.StartPreparer(resourceGroupName, vmName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Start", nil, "Failure preparing request") + } + + resp, err := client.StartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Start", resp, "Failure sending request") + } + + result, err = client.StartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "Start", resp, "Failure responding to request") + } + + return +} + +// StartPreparer prepares the Start request. +func (client VirtualMachinesClient) StartPreparer(resourceGroupName string, vmName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", vmName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/start", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// StartSender sends the Start request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) StartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// StartResponder handles the response to the Start request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) StartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go new file mode 100644 index 0000000000..f2b92a26a0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go @@ -0,0 +1,1096 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// VirtualMachineScaleSetsClient is the the Compute Management Client. +type VirtualMachineScaleSetsClient struct { + ManagementClient +} + +// NewVirtualMachineScaleSetsClient creates an instance of the +// VirtualMachineScaleSetsClient client. +func NewVirtualMachineScaleSetsClient(subscriptionID string) VirtualMachineScaleSetsClient { + return NewVirtualMachineScaleSetsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachineScaleSetsClientWithBaseURI creates an instance of the +// VirtualMachineScaleSetsClient client. +func NewVirtualMachineScaleSetsClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachineScaleSetsClient { + return VirtualMachineScaleSetsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate allows you to create or update a virtual machine scale set +// by providing parameters or a path to pre-configured parameter file. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. name is parameters +// supplied to the Create Virtual Machine Scale Set operation. parameters is +// parameters supplied to the Create Virtual Machine Scale Set operation. +func (client VirtualMachineScaleSetsClient) CreateOrUpdate(resourceGroupName string, name string, parameters VirtualMachineScaleSet, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.VirtualMachineProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.VirtualMachineProfile.StorageProfile", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.VirtualMachineProfile.StorageProfile.OsDisk", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.VirtualMachineProfile.StorageProfile.OsDisk.Name", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + }}, + {Target: "parameters.Properties.ProvisioningState", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachineScaleSetsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, name, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualMachineScaleSetsClient) CreateOrUpdatePreparer(resourceGroupName string, name string, parameters VirtualMachineScaleSet, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": autorest.Encode("path", name), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{name}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Deallocate allows you to deallocate virtual machines in a virtual machine +// scale set. Shuts down the virtual machines and releases the compute +// resources. You are not billed for the compute resources that this virtual +// machine scale set uses. This method may poll for completion. Polling can +// be canceled by passing the cancel channel argument. The channel will be +// used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. vmInstanceIDs is the list of +// virtual machine scale set instance IDs. +func (client VirtualMachineScaleSetsClient) Deallocate(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeallocatePreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Deallocate", nil, "Failure preparing request") + } + + resp, err := client.DeallocateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Deallocate", resp, "Failure sending request") + } + + result, err = client.DeallocateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Deallocate", resp, "Failure responding to request") + } + + return +} + +// DeallocatePreparer prepares the Deallocate request. +func (client VirtualMachineScaleSetsClient) DeallocatePreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/deallocate", pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeallocateSender sends the Deallocate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) DeallocateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeallocateResponder handles the response to the Deallocate request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) DeallocateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete allows you to delete a virtual machine scale set. This method may +// poll for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. +func (client VirtualMachineScaleSetsClient) Delete(resourceGroupName string, vmScaleSetName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, vmScaleSetName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualMachineScaleSetsClient) DeletePreparer(resourceGroupName string, vmScaleSetName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// DeleteInstances allows you to delete virtual machines in a virtual machine +// scale set. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. vmInstanceIDs is the list of +// virtual machine scale set instance IDs. +func (client VirtualMachineScaleSetsClient) DeleteInstances(resourceGroupName string, vmScaleSetName string, vmInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: vmInstanceIDs, + Constraints: []validation.Constraint{{Target: "vmInstanceIDs.InstanceIds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachineScaleSetsClient", "DeleteInstances") + } + + req, err := client.DeleteInstancesPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "DeleteInstances", nil, "Failure preparing request") + } + + resp, err := client.DeleteInstancesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "DeleteInstances", resp, "Failure sending request") + } + + result, err = client.DeleteInstancesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "DeleteInstances", resp, "Failure responding to request") + } + + return +} + +// DeleteInstancesPreparer prepares the DeleteInstances request. +func (client VirtualMachineScaleSetsClient) DeleteInstancesPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/delete", pathParameters), + autorest.WithJSON(vmInstanceIDs), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteInstancesSender sends the DeleteInstances request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) DeleteInstancesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteInstancesResponder handles the response to the DeleteInstances request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) DeleteInstancesResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get display information about a virtual machine scale set. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. +func (client VirtualMachineScaleSetsClient) Get(resourceGroupName string, vmScaleSetName string) (result VirtualMachineScaleSet, err error) { + req, err := client.GetPreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualMachineScaleSetsClient) GetPreparer(resourceGroupName string, vmScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) GetResponder(resp *http.Response) (result VirtualMachineScaleSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetInstanceView displays status of a virtual machine scale set instance. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. +func (client VirtualMachineScaleSetsClient) GetInstanceView(resourceGroupName string, vmScaleSetName string) (result VirtualMachineScaleSetInstanceView, err error) { + req, err := client.GetInstanceViewPreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "GetInstanceView", nil, "Failure preparing request") + } + + resp, err := client.GetInstanceViewSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "GetInstanceView", resp, "Failure sending request") + } + + result, err = client.GetInstanceViewResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "GetInstanceView", resp, "Failure responding to request") + } + + return +} + +// GetInstanceViewPreparer prepares the GetInstanceView request. +func (client VirtualMachineScaleSetsClient) GetInstanceViewPreparer(resourceGroupName string, vmScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/instanceView", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetInstanceViewSender sends the GetInstanceView request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) GetInstanceViewSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetInstanceViewResponder handles the response to the GetInstanceView request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) GetInstanceViewResponder(resp *http.Response) (result VirtualMachineScaleSetInstanceView, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists all virtual machine scale sets under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client VirtualMachineScaleSetsClient) List(resourceGroupName string) (result VirtualMachineScaleSetListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualMachineScaleSetsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) ListResponder(resp *http.Response) (result VirtualMachineScaleSetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualMachineScaleSetsClient) ListNextResults(lastResults VirtualMachineScaleSetListResult) (result VirtualMachineScaleSetListResult, err error) { + req, err := lastResults.VirtualMachineScaleSetListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll lists all Virtual Machine Scale Sets in the subscription. Use +// nextLink property in the response to get the next page of Virtual Machine +// Scale Sets. Do this till nextLink is not null to fetch all the Virtual +// Machine Scale Sets. +func (client VirtualMachineScaleSetsClient) ListAll() (result VirtualMachineScaleSetListWithLinkResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client VirtualMachineScaleSetsClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachineScaleSets", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) ListAllResponder(resp *http.Response) (result VirtualMachineScaleSetListWithLinkResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client VirtualMachineScaleSetsClient) ListAllNextResults(lastResults VirtualMachineScaleSetListWithLinkResult) (result VirtualMachineScaleSetListWithLinkResult, err error) { + req, err := lastResults.VirtualMachineScaleSetListWithLinkResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} + +// ListSkus displays available skus for your virtual machine scale set +// including the minimum and maximum vm instances allowed for a particular +// sku. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. +func (client VirtualMachineScaleSetsClient) ListSkus(resourceGroupName string, vmScaleSetName string) (result VirtualMachineScaleSetListSkusResult, err error) { + req, err := client.ListSkusPreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListSkus", nil, "Failure preparing request") + } + + resp, err := client.ListSkusSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListSkus", resp, "Failure sending request") + } + + result, err = client.ListSkusResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListSkus", resp, "Failure responding to request") + } + + return +} + +// ListSkusPreparer prepares the ListSkus request. +func (client VirtualMachineScaleSetsClient) ListSkusPreparer(resourceGroupName string, vmScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/skus", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSkusSender sends the ListSkus request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) ListSkusSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListSkusResponder handles the response to the ListSkus request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) ListSkusResponder(resp *http.Response) (result VirtualMachineScaleSetListSkusResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSkusNextResults retrieves the next set of results, if any. +func (client VirtualMachineScaleSetsClient) ListSkusNextResults(lastResults VirtualMachineScaleSetListSkusResult) (result VirtualMachineScaleSetListSkusResult, err error) { + req, err := lastResults.VirtualMachineScaleSetListSkusResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListSkus", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSkusSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListSkus", resp, "Failure sending next results request") + } + + result, err = client.ListSkusResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "ListSkus", resp, "Failure responding to next results request") + } + + return +} + +// PowerOff allows you to power off (stop) virtual machines in a virtual +// machine scale set. Note that resources are still attached and you are +// getting charged for the resources. Use deallocate to release resources. +// This method may poll for completion. Polling can be canceled by passing +// the cancel channel argument. The channel will be used to cancel polling +// and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. vmInstanceIDs is the list of +// virtual machine scale set instance IDs. +func (client VirtualMachineScaleSetsClient) PowerOff(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.PowerOffPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "PowerOff", nil, "Failure preparing request") + } + + resp, err := client.PowerOffSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "PowerOff", resp, "Failure sending request") + } + + result, err = client.PowerOffResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "PowerOff", resp, "Failure responding to request") + } + + return +} + +// PowerOffPreparer prepares the PowerOff request. +func (client VirtualMachineScaleSetsClient) PowerOffPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/poweroff", pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// PowerOffSender sends the PowerOff request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) PowerOffSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// PowerOffResponder handles the response to the PowerOff request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) PowerOffResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Reimage allows you to re-image(update the version of the installed +// operating system) virtual machines in a virtual machine scale set. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. +func (client VirtualMachineScaleSetsClient) Reimage(resourceGroupName string, vmScaleSetName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ReimagePreparer(resourceGroupName, vmScaleSetName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Reimage", nil, "Failure preparing request") + } + + resp, err := client.ReimageSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Reimage", resp, "Failure sending request") + } + + result, err = client.ReimageResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Reimage", resp, "Failure responding to request") + } + + return +} + +// ReimagePreparer prepares the Reimage request. +func (client VirtualMachineScaleSetsClient) ReimagePreparer(resourceGroupName string, vmScaleSetName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/reimage", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ReimageSender sends the Reimage request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) ReimageSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ReimageResponder handles the response to the Reimage request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) ReimageResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Restart allows you to restart virtual machines in a virtual machine scale +// set. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. vmInstanceIDs is the list of +// virtual machine scale set instance IDs. +func (client VirtualMachineScaleSetsClient) Restart(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.RestartPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Restart", nil, "Failure preparing request") + } + + resp, err := client.RestartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Restart", resp, "Failure sending request") + } + + result, err = client.RestartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Restart", resp, "Failure responding to request") + } + + return +} + +// RestartPreparer prepares the Restart request. +func (client VirtualMachineScaleSetsClient) RestartPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/restart", pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RestartSender sends the Restart request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) RestartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RestartResponder handles the response to the Restart request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) RestartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Start allows you to start virtual machines in a virtual machine scale set. +// This method may poll for completion. Polling can be canceled by passing +// the cancel channel argument. The channel will be used to cancel polling +// and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. vmInstanceIDs is the list of +// virtual machine scale set instance IDs. +func (client VirtualMachineScaleSetsClient) Start(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.StartPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Start", nil, "Failure preparing request") + } + + resp, err := client.StartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Start", resp, "Failure sending request") + } + + result, err = client.StartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "Start", resp, "Failure responding to request") + } + + return +} + +// StartPreparer prepares the Start request. +func (client VirtualMachineScaleSetsClient) StartPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/start", pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// StartSender sends the Start request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) StartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// StartResponder handles the response to the Start request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) StartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// UpdateInstances allows you to manually upgrade virtual machines in a +// virtual machine scale set. This method may poll for completion. Polling +// can be canceled by passing the cancel channel argument. The channel will +// be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. vmInstanceIDs is the list of +// virtual machine scale set instance IDs. +func (client VirtualMachineScaleSetsClient) UpdateInstances(resourceGroupName string, vmScaleSetName string, vmInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: vmInstanceIDs, + Constraints: []validation.Constraint{{Target: "vmInstanceIDs.InstanceIds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachineScaleSetsClient", "UpdateInstances") + } + + req, err := client.UpdateInstancesPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "UpdateInstances", nil, "Failure preparing request") + } + + resp, err := client.UpdateInstancesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "UpdateInstances", resp, "Failure sending request") + } + + result, err = client.UpdateInstancesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "UpdateInstances", resp, "Failure responding to request") + } + + return +} + +// UpdateInstancesPreparer prepares the UpdateInstances request. +func (client VirtualMachineScaleSetsClient) UpdateInstancesPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/manualupgrade", pathParameters), + autorest.WithJSON(vmInstanceIDs), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateInstancesSender sends the UpdateInstances request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) UpdateInstancesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateInstancesResponder handles the response to the UpdateInstances request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) UpdateInstancesResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go new file mode 100644 index 0000000000..37f2be3176 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go @@ -0,0 +1,689 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualMachineScaleSetVMsClient is the the Compute Management Client. +type VirtualMachineScaleSetVMsClient struct { + ManagementClient +} + +// NewVirtualMachineScaleSetVMsClient creates an instance of the +// VirtualMachineScaleSetVMsClient client. +func NewVirtualMachineScaleSetVMsClient(subscriptionID string) VirtualMachineScaleSetVMsClient { + return NewVirtualMachineScaleSetVMsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachineScaleSetVMsClientWithBaseURI creates an instance of the +// VirtualMachineScaleSetVMsClient client. +func NewVirtualMachineScaleSetVMsClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachineScaleSetVMsClient { + return VirtualMachineScaleSetVMsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Deallocate allows you to deallocate a virtual machine scale set virtual +// machine. Shuts down the virtual machine and releases the compute +// resources. You are not billed for the compute resources that this virtual +// machine uses. This method may poll for completion. Polling can be canceled +// by passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) Deallocate(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeallocatePreparer(resourceGroupName, vmScaleSetName, instanceID, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Deallocate", nil, "Failure preparing request") + } + + resp, err := client.DeallocateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Deallocate", resp, "Failure sending request") + } + + result, err = client.DeallocateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Deallocate", resp, "Failure responding to request") + } + + return +} + +// DeallocatePreparer prepares the Deallocate request. +func (client VirtualMachineScaleSetVMsClient) DeallocatePreparer(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/deallocate", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeallocateSender sends the Deallocate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) DeallocateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeallocateResponder handles the response to the Deallocate request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) DeallocateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete allows you to delete a virtual machine scale set. This method may +// poll for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) Delete(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, vmScaleSetName, instanceID, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualMachineScaleSetVMsClient) DeletePreparer(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get displays information about a virtual machine scale set virtual machine. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) Get(resourceGroupName string, vmScaleSetName string, instanceID string) (result VirtualMachineScaleSetVM, err error) { + req, err := client.GetPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualMachineScaleSetVMsClient) GetPreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) GetResponder(resp *http.Response) (result VirtualMachineScaleSetVM, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetInstanceView displays the status of a virtual machine scale set virtual +// machine. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) GetInstanceView(resourceGroupName string, vmScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMInstanceView, err error) { + req, err := client.GetInstanceViewPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "GetInstanceView", nil, "Failure preparing request") + } + + resp, err := client.GetInstanceViewSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "GetInstanceView", resp, "Failure sending request") + } + + result, err = client.GetInstanceViewResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "GetInstanceView", resp, "Failure responding to request") + } + + return +} + +// GetInstanceViewPreparer prepares the GetInstanceView request. +func (client VirtualMachineScaleSetVMsClient) GetInstanceViewPreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/instanceView", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetInstanceViewSender sends the GetInstanceView request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) GetInstanceViewSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetInstanceViewResponder handles the response to the GetInstanceView request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) GetInstanceViewResponder(resp *http.Response) (result VirtualMachineScaleSetVMInstanceView, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists all virtual machines in a VM scale sets. +// +// resourceGroupName is the name of the resource group. +// virtualMachineScaleSetName is the name of the virtual machine scale set. +// filter is the filter to apply on the operation. selectParameter is the +// list parameters. expand is the expand expression to apply on the +// operation. +func (client VirtualMachineScaleSetVMsClient) List(resourceGroupName string, virtualMachineScaleSetName string, filter string, selectParameter string, expand string) (result VirtualMachineScaleSetVMListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, virtualMachineScaleSetName, filter, selectParameter, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualMachineScaleSetVMsClient) ListPreparer(resourceGroupName string, virtualMachineScaleSetName string, filter string, selectParameter string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualMachineScaleSetName": autorest.Encode("path", virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(selectParameter) > 0 { + queryParameters["$select"] = autorest.Encode("query", selectParameter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) ListResponder(resp *http.Response) (result VirtualMachineScaleSetVMListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualMachineScaleSetVMsClient) ListNextResults(lastResults VirtualMachineScaleSetVMListResult) (result VirtualMachineScaleSetVMListResult, err error) { + req, err := lastResults.VirtualMachineScaleSetVMListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// PowerOff allows you to power off (stop) a virtual machine in a VM scale +// set. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) PowerOff(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.PowerOffPreparer(resourceGroupName, vmScaleSetName, instanceID, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "PowerOff", nil, "Failure preparing request") + } + + resp, err := client.PowerOffSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "PowerOff", resp, "Failure sending request") + } + + result, err = client.PowerOffResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "PowerOff", resp, "Failure responding to request") + } + + return +} + +// PowerOffPreparer prepares the PowerOff request. +func (client VirtualMachineScaleSetVMsClient) PowerOffPreparer(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/poweroff", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// PowerOffSender sends the PowerOff request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) PowerOffSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// PowerOffResponder handles the response to the PowerOff request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) PowerOffResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Reimage allows you to re-image(update the version of the installed +// operating system) a virtual machine scale set instance. This method may +// poll for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) Reimage(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ReimagePreparer(resourceGroupName, vmScaleSetName, instanceID, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Reimage", nil, "Failure preparing request") + } + + resp, err := client.ReimageSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Reimage", resp, "Failure sending request") + } + + result, err = client.ReimageResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Reimage", resp, "Failure responding to request") + } + + return +} + +// ReimagePreparer prepares the Reimage request. +func (client VirtualMachineScaleSetVMsClient) ReimagePreparer(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/reimage", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ReimageSender sends the Reimage request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) ReimageSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ReimageResponder handles the response to the Reimage request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) ReimageResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Restart allows you to restart a virtual machine in a VM scale set. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) Restart(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.RestartPreparer(resourceGroupName, vmScaleSetName, instanceID, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Restart", nil, "Failure preparing request") + } + + resp, err := client.RestartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Restart", resp, "Failure sending request") + } + + result, err = client.RestartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Restart", resp, "Failure responding to request") + } + + return +} + +// RestartPreparer prepares the Restart request. +func (client VirtualMachineScaleSetVMsClient) RestartPreparer(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/restart", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RestartSender sends the Restart request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) RestartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RestartResponder handles the response to the Restart request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) RestartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Start allows you to start a virtual machine in a VM scale set. This method +// may poll for completion. Polling can be canceled by passing the cancel +// channel argument. The channel will be used to cancel polling and any +// outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. vmScaleSetName is the +// name of the virtual machine scale set. instanceID is the instance id of +// the virtual machine. +func (client VirtualMachineScaleSetVMsClient) Start(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.StartPreparer(resourceGroupName, vmScaleSetName, instanceID, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Start", nil, "Failure preparing request") + } + + resp, err := client.StartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Start", resp, "Failure sending request") + } + + result, err = client.StartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsClient", "Start", resp, "Failure responding to request") + } + + return +} + +// StartPreparer prepares the Start request. +func (client VirtualMachineScaleSetVMsClient) StartPreparer(resourceGroupName string, vmScaleSetName string, instanceID string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": autorest.Encode("path", instanceID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/start", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// StartSender sends the Start request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetVMsClient) StartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// StartResponder handles the response to the Start request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetVMsClient) StartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go new file mode 100644 index 0000000000..507e9f157e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go @@ -0,0 +1,111 @@ +package compute + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// VirtualMachineSizesClient is the the Compute Management Client. +type VirtualMachineSizesClient struct { + ManagementClient +} + +// NewVirtualMachineSizesClient creates an instance of the +// VirtualMachineSizesClient client. +func NewVirtualMachineSizesClient(subscriptionID string) VirtualMachineSizesClient { + return NewVirtualMachineSizesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualMachineSizesClientWithBaseURI creates an instance of the +// VirtualMachineSizesClient client. +func NewVirtualMachineSizesClientWithBaseURI(baseURI string, subscriptionID string) VirtualMachineSizesClient { + return VirtualMachineSizesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List lists all available virtual machine sizes for a subscription in a +// location. +// +// location is the location upon which virtual-machine-sizes is queried. +func (client VirtualMachineSizesClient) List(location string) (result VirtualMachineSizeListResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: location, + Constraints: []validation.Constraint{{Target: "location", Name: validation.Pattern, Rule: `^[-\w\._]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "compute.VirtualMachineSizesClient", "List") + } + + req, err := client.ListPreparer(location) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineSizesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineSizesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineSizesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualMachineSizesClient) ListPreparer(location string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/vmSizes", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineSizesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualMachineSizesClient) ListResponder(resp *http.Response) (result VirtualMachineSizeListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go new file mode 100644 index 0000000000..99f6ff6260 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go @@ -0,0 +1,560 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// ApplicationGatewaysClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type ApplicationGatewaysClient struct { + ManagementClient +} + +// NewApplicationGatewaysClient creates an instance of the +// ApplicationGatewaysClient client. +func NewApplicationGatewaysClient(subscriptionID string) ApplicationGatewaysClient { + return NewApplicationGatewaysClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewApplicationGatewaysClientWithBaseURI creates an instance of the +// ApplicationGatewaysClient client. +func NewApplicationGatewaysClientWithBaseURI(baseURI string, subscriptionID string) ApplicationGatewaysClient { + return ApplicationGatewaysClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put ApplicationGateway operation creates/updates a +// ApplicationGateway This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. applicationGatewayName +// is the name of the ApplicationGateway. parameters is parameters supplied +// to the create/delete ApplicationGateway operation +func (client ApplicationGatewaysClient) CreateOrUpdate(resourceGroupName string, applicationGatewayName string, parameters ApplicationGateway, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.OperationalState", Name: validation.ReadOnly, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.ApplicationGatewaysClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, applicationGatewayName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ApplicationGatewaysClient) CreateOrUpdatePreparer(resourceGroupName string, applicationGatewayName string, parameters ApplicationGateway, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "applicationGatewayName": autorest.Encode("path", applicationGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete ApplicationGateway operation deletes the specified +// application gateway. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. applicationGatewayName +// is the name of the application gateway. +func (client ApplicationGatewaysClient) Delete(resourceGroupName string, applicationGatewayName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, applicationGatewayName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ApplicationGatewaysClient) DeletePreparer(resourceGroupName string, applicationGatewayName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "applicationGatewayName": autorest.Encode("path", applicationGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusNoContent, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get ApplicationGateway operation retrieves information about the +// specified application gateway. +// +// resourceGroupName is the name of the resource group. applicationGatewayName +// is the name of the application gateway. +func (client ApplicationGatewaysClient) Get(resourceGroupName string, applicationGatewayName string) (result ApplicationGateway, err error) { + req, err := client.GetPreparer(resourceGroupName, applicationGatewayName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ApplicationGatewaysClient) GetPreparer(resourceGroupName string, applicationGatewayName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "applicationGatewayName": autorest.Encode("path", applicationGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) GetResponder(resp *http.Response) (result ApplicationGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List ApplicationGateway operation retrieves all the application +// gateways in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client ApplicationGatewaysClient) List(resourceGroupName string) (result ApplicationGatewayListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ApplicationGatewaysClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) ListResponder(resp *http.Response) (result ApplicationGatewayListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ApplicationGatewaysClient) ListNextResults(lastResults ApplicationGatewayListResult) (result ApplicationGatewayListResult, err error) { + req, err := lastResults.ApplicationGatewayListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the List ApplicationGateway operation retrieves all the application +// gateways in a subscription. +func (client ApplicationGatewaysClient) ListAll() (result ApplicationGatewayListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client ApplicationGatewaysClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/applicationGateways", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) ListAllResponder(resp *http.Response) (result ApplicationGatewayListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client ApplicationGatewaysClient) ListAllNextResults(lastResults ApplicationGatewayListResult) (result ApplicationGatewayListResult, err error) { + req, err := lastResults.ApplicationGatewayListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} + +// Start the Start ApplicationGateway operation starts application gateway in +// the specified resource group through Network resource provider. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. applicationGatewayName +// is the name of the application gateway. +func (client ApplicationGatewaysClient) Start(resourceGroupName string, applicationGatewayName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.StartPreparer(resourceGroupName, applicationGatewayName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Start", nil, "Failure preparing request") + } + + resp, err := client.StartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Start", resp, "Failure sending request") + } + + result, err = client.StartResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Start", resp, "Failure responding to request") + } + + return +} + +// StartPreparer prepares the Start request. +func (client ApplicationGatewaysClient) StartPreparer(resourceGroupName string, applicationGatewayName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "applicationGatewayName": autorest.Encode("path", applicationGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/start", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// StartSender sends the Start request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) StartSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// StartResponder handles the response to the Start request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) StartResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Stop the STOP ApplicationGateway operation stops application gateway in the +// specified resource group through Network resource provider. This method +// may poll for completion. Polling can be canceled by passing the cancel +// channel argument. The channel will be used to cancel polling and any +// outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. applicationGatewayName +// is the name of the application gateway. +func (client ApplicationGatewaysClient) Stop(resourceGroupName string, applicationGatewayName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.StopPreparer(resourceGroupName, applicationGatewayName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Stop", nil, "Failure preparing request") + } + + resp, err := client.StopSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Stop", resp, "Failure sending request") + } + + result, err = client.StopResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysClient", "Stop", resp, "Failure responding to request") + } + + return +} + +// StopPreparer prepares the Stop request. +func (client ApplicationGatewaysClient) StopPreparer(resourceGroupName string, applicationGatewayName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "applicationGatewayName": autorest.Encode("path", applicationGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/stop", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// StopSender sends the Stop request. The method will close the +// http.Response Body if it receives an error. +func (client ApplicationGatewaysClient) StopSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// StopResponder handles the response to the Stop request. The method always +// closes the http.Response Body. +func (client ApplicationGatewaysClient) StopResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/client.go new file mode 100644 index 0000000000..b2ab581739 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/client.go @@ -0,0 +1,130 @@ +// Package network implements the Azure ARM Network service API version +// 2016-09-01. +// +// The Microsoft Azure Network management API provides a RESTful set of web +// services that interact with Microsoft Azure Networks service to manage +// your network resources. The API has entities that capture the relationship +// between an end user and the Microsoft Azure Networks service. +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +const ( + // APIVersion is the version of the Network + APIVersion = "2016-09-01" + + // DefaultBaseURI is the default URI used for the service Network + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Network. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + SubscriptionID: subscriptionID, + } +} + +// CheckDNSNameAvailability checks whether a domain name in the cloudapp.net +// zone is available for use. +// +// location is the location of the domain name domainNameLabel is the domain +// name to be verified. It must conform to the following regular expression: +// ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. +func (client ManagementClient) CheckDNSNameAvailability(location string, domainNameLabel string) (result DNSNameAvailabilityResult, err error) { + req, err := client.CheckDNSNameAvailabilityPreparer(location, domainNameLabel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ManagementClient", "CheckDNSNameAvailability", nil, "Failure preparing request") + } + + resp, err := client.CheckDNSNameAvailabilitySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ManagementClient", "CheckDNSNameAvailability", resp, "Failure sending request") + } + + result, err = client.CheckDNSNameAvailabilityResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ManagementClient", "CheckDNSNameAvailability", resp, "Failure responding to request") + } + + return +} + +// CheckDNSNameAvailabilityPreparer prepares the CheckDNSNameAvailability request. +func (client ManagementClient) CheckDNSNameAvailabilityPreparer(location string, domainNameLabel string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(domainNameLabel) > 0 { + queryParameters["domainNameLabel"] = autorest.Encode("query", domainNameLabel) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/locations/{location}/CheckDnsNameAvailability", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CheckDNSNameAvailabilitySender sends the CheckDNSNameAvailability request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) CheckDNSNameAvailabilitySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CheckDNSNameAvailabilityResponder handles the response to the CheckDNSNameAvailability request. The method always +// closes the http.Response Body. +func (client ManagementClient) CheckDNSNameAvailabilityResponder(resp *http.Response) (result DNSNameAvailabilityResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go new file mode 100644 index 0000000000..86b8faa78c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go @@ -0,0 +1,343 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ExpressRouteCircuitAuthorizationsClient is the the Microsoft Azure Network +// management API provides a RESTful set of web services that interact with +// Microsoft Azure Networks service to manage your network resources. The API +// has entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type ExpressRouteCircuitAuthorizationsClient struct { + ManagementClient +} + +// NewExpressRouteCircuitAuthorizationsClient creates an instance of the +// ExpressRouteCircuitAuthorizationsClient client. +func NewExpressRouteCircuitAuthorizationsClient(subscriptionID string) ExpressRouteCircuitAuthorizationsClient { + return NewExpressRouteCircuitAuthorizationsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewExpressRouteCircuitAuthorizationsClientWithBaseURI creates an instance +// of the ExpressRouteCircuitAuthorizationsClient client. +func NewExpressRouteCircuitAuthorizationsClientWithBaseURI(baseURI string, subscriptionID string) ExpressRouteCircuitAuthorizationsClient { + return ExpressRouteCircuitAuthorizationsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put Authorization operation creates/updates an +// authorization in the specified ExpressRouteCircuits This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route circuit. authorizationName is the name of the +// authorization. authorizationParameters is parameters supplied to the +// create/update ExpressRouteCircuitAuthorization operation +func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdate(resourceGroupName string, circuitName string, authorizationName string, authorizationParameters ExpressRouteCircuitAuthorization, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, circuitName, authorizationName, authorizationParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdatePreparer(resourceGroupName string, circuitName string, authorizationName string, authorizationParameters ExpressRouteCircuitAuthorization, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "authorizationName": autorest.Encode("path", authorizationName), + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations/{authorizationName}", pathParameters), + autorest.WithJSON(authorizationParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete authorization operation deletes the specified +// authorization from the specified ExpressRouteCircuit. This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route circuit. authorizationName is the name of the +// authorization. +func (client ExpressRouteCircuitAuthorizationsClient) Delete(resourceGroupName string, circuitName string, authorizationName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, circuitName, authorizationName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ExpressRouteCircuitAuthorizationsClient) DeletePreparer(resourceGroupName string, circuitName string, authorizationName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "authorizationName": autorest.Encode("path", authorizationName), + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations/{authorizationName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitAuthorizationsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitAuthorizationsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the GET authorization operation retrieves the specified authorization +// from the specified ExpressRouteCircuit. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route circuit. authorizationName is the name of the +// authorization. +func (client ExpressRouteCircuitAuthorizationsClient) Get(resourceGroupName string, circuitName string, authorizationName string) (result ExpressRouteCircuitAuthorization, err error) { + req, err := client.GetPreparer(resourceGroupName, circuitName, authorizationName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ExpressRouteCircuitAuthorizationsClient) GetPreparer(resourceGroupName string, circuitName string, authorizationName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "authorizationName": autorest.Encode("path", authorizationName), + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations/{authorizationName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitAuthorizationsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitAuthorizationsClient) GetResponder(resp *http.Response) (result ExpressRouteCircuitAuthorization, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List authorization operation retrieves all the authorizations in +// an ExpressRouteCircuit. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. +func (client ExpressRouteCircuitAuthorizationsClient) List(resourceGroupName string, circuitName string) (result AuthorizationListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExpressRouteCircuitAuthorizationsClient) ListPreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitAuthorizationsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitAuthorizationsClient) ListResponder(resp *http.Response) (result AuthorizationListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitAuthorizationsClient) ListNextResults(lastResults AuthorizationListResult) (result AuthorizationListResult, err error) { + req, err := lastResults.AuthorizationListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go new file mode 100644 index 0000000000..ddbff0acf5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go @@ -0,0 +1,339 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ExpressRouteCircuitPeeringsClient is the the Microsoft Azure Network +// management API provides a RESTful set of web services that interact with +// Microsoft Azure Networks service to manage your network resources. The API +// has entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type ExpressRouteCircuitPeeringsClient struct { + ManagementClient +} + +// NewExpressRouteCircuitPeeringsClient creates an instance of the +// ExpressRouteCircuitPeeringsClient client. +func NewExpressRouteCircuitPeeringsClient(subscriptionID string) ExpressRouteCircuitPeeringsClient { + return NewExpressRouteCircuitPeeringsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewExpressRouteCircuitPeeringsClientWithBaseURI creates an instance of the +// ExpressRouteCircuitPeeringsClient client. +func NewExpressRouteCircuitPeeringsClientWithBaseURI(baseURI string, subscriptionID string) ExpressRouteCircuitPeeringsClient { + return ExpressRouteCircuitPeeringsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put Peering operation creates/updates an peering in the +// specified ExpressRouteCircuits This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The +// channel will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route circuit. peeringName is the name of the peering. +// peeringParameters is parameters supplied to the create/update +// ExpressRouteCircuit Peering operation +func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdate(resourceGroupName string, circuitName string, peeringName string, peeringParameters ExpressRouteCircuitPeering, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, circuitName, peeringName, peeringParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdatePreparer(resourceGroupName string, circuitName string, peeringName string, peeringParameters ExpressRouteCircuitPeering, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}", pathParameters), + autorest.WithJSON(peeringParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete peering operation deletes the specified peering from the +// ExpressRouteCircuit. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route circuit. peeringName is the name of the peering. +func (client ExpressRouteCircuitPeeringsClient) Delete(resourceGroupName string, circuitName string, peeringName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, circuitName, peeringName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ExpressRouteCircuitPeeringsClient) DeletePreparer(resourceGroupName string, circuitName string, peeringName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitPeeringsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitPeeringsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the GET peering operation retrieves the specified authorization from +// the ExpressRouteCircuit. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route circuit. peeringName is the name of the peering. +func (client ExpressRouteCircuitPeeringsClient) Get(resourceGroupName string, circuitName string, peeringName string) (result ExpressRouteCircuitPeering, err error) { + req, err := client.GetPreparer(resourceGroupName, circuitName, peeringName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ExpressRouteCircuitPeeringsClient) GetPreparer(resourceGroupName string, circuitName string, peeringName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitPeeringsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitPeeringsClient) GetResponder(resp *http.Response) (result ExpressRouteCircuitPeering, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List peering operation retrieves all the peerings in an +// ExpressRouteCircuit. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. +func (client ExpressRouteCircuitPeeringsClient) List(resourceGroupName string, circuitName string) (result ExpressRouteCircuitPeeringListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExpressRouteCircuitPeeringsClient) ListPreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitPeeringsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitPeeringsClient) ListResponder(resp *http.Response) (result ExpressRouteCircuitPeeringListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitPeeringsClient) ListNextResults(lastResults ExpressRouteCircuitPeeringListResult) (result ExpressRouteCircuitPeeringListResult, err error) { + req, err := lastResults.ExpressRouteCircuitPeeringListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go new file mode 100644 index 0000000000..9e46f8f94f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go @@ -0,0 +1,761 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ExpressRouteCircuitsClient is the the Microsoft Azure Network management +// API provides a RESTful set of web services that interact with Microsoft +// Azure Networks service to manage your network resources. The API has +// entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type ExpressRouteCircuitsClient struct { + ManagementClient +} + +// NewExpressRouteCircuitsClient creates an instance of the +// ExpressRouteCircuitsClient client. +func NewExpressRouteCircuitsClient(subscriptionID string) ExpressRouteCircuitsClient { + return NewExpressRouteCircuitsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewExpressRouteCircuitsClientWithBaseURI creates an instance of the +// ExpressRouteCircuitsClient client. +func NewExpressRouteCircuitsClientWithBaseURI(baseURI string, subscriptionID string) ExpressRouteCircuitsClient { + return ExpressRouteCircuitsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put ExpressRouteCircuit operation creates/updates a +// ExpressRouteCircuit This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. parameters is parameters supplied to the +// create/delete ExpressRouteCircuit operation +func (client ExpressRouteCircuitsClient) CreateOrUpdate(resourceGroupName string, circuitName string, parameters ExpressRouteCircuit, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, circuitName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ExpressRouteCircuitsClient) CreateOrUpdatePreparer(resourceGroupName string, circuitName string, parameters ExpressRouteCircuit, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete ExpressRouteCircuit operation deletes the specified +// ExpressRouteCircuit. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the express route Circuit. +func (client ExpressRouteCircuitsClient) Delete(resourceGroupName string, circuitName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, circuitName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ExpressRouteCircuitsClient) DeletePreparer(resourceGroupName string, circuitName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get ExpressRouteCircuit operation retrieves information about the +// specified ExpressRouteCircuit. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. +func (client ExpressRouteCircuitsClient) Get(resourceGroupName string, circuitName string) (result ExpressRouteCircuit, err error) { + req, err := client.GetPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ExpressRouteCircuitsClient) GetPreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) GetResponder(resp *http.Response) (result ExpressRouteCircuit, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetPeeringStats the List stats ExpressRouteCircuit operation retrieves all +// the stats from a ExpressRouteCircuits in a resource group. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. peeringName is the name of the peering. +func (client ExpressRouteCircuitsClient) GetPeeringStats(resourceGroupName string, circuitName string, peeringName string) (result ExpressRouteCircuitStats, err error) { + req, err := client.GetPeeringStatsPreparer(resourceGroupName, circuitName, peeringName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "GetPeeringStats", nil, "Failure preparing request") + } + + resp, err := client.GetPeeringStatsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "GetPeeringStats", resp, "Failure sending request") + } + + result, err = client.GetPeeringStatsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "GetPeeringStats", resp, "Failure responding to request") + } + + return +} + +// GetPeeringStatsPreparer prepares the GetPeeringStats request. +func (client ExpressRouteCircuitsClient) GetPeeringStatsPreparer(resourceGroupName string, circuitName string, peeringName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}/stats", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetPeeringStatsSender sends the GetPeeringStats request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) GetPeeringStatsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetPeeringStatsResponder handles the response to the GetPeeringStats request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) GetPeeringStatsResponder(resp *http.Response) (result ExpressRouteCircuitStats, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetStats the List stats ExpressRouteCircuit operation retrieves all the +// stats from a ExpressRouteCircuits in a resource group. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. +func (client ExpressRouteCircuitsClient) GetStats(resourceGroupName string, circuitName string) (result ExpressRouteCircuitStats, err error) { + req, err := client.GetStatsPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "GetStats", nil, "Failure preparing request") + } + + resp, err := client.GetStatsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "GetStats", resp, "Failure sending request") + } + + result, err = client.GetStatsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "GetStats", resp, "Failure responding to request") + } + + return +} + +// GetStatsPreparer prepares the GetStats request. +func (client ExpressRouteCircuitsClient) GetStatsPreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/stats", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetStatsSender sends the GetStats request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) GetStatsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetStatsResponder handles the response to the GetStats request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) GetStatsResponder(resp *http.Response) (result ExpressRouteCircuitStats, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List ExpressRouteCircuit operation retrieves all the +// ExpressRouteCircuits in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client ExpressRouteCircuitsClient) List(resourceGroupName string) (result ExpressRouteCircuitListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExpressRouteCircuitsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListResponder(resp *http.Response) (result ExpressRouteCircuitListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitsClient) ListNextResults(lastResults ExpressRouteCircuitListResult) (result ExpressRouteCircuitListResult, err error) { + req, err := lastResults.ExpressRouteCircuitListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the List ExpressRouteCircuit operation retrieves all the +// ExpressRouteCircuits in a subscription. +func (client ExpressRouteCircuitsClient) ListAll() (result ExpressRouteCircuitListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client ExpressRouteCircuitsClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/expressRouteCircuits", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListAllResponder(resp *http.Response) (result ExpressRouteCircuitListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitsClient) ListAllNextResults(lastResults ExpressRouteCircuitListResult) (result ExpressRouteCircuitListResult, err error) { + req, err := lastResults.ExpressRouteCircuitListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} + +// ListArpTable the ListArpTable from ExpressRouteCircuit operation retrieves +// the currently advertised arp table associated with the +// ExpressRouteCircuits in a resource group. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. peeringName is the name of the peering. devicePath is +// the path of the device. +func (client ExpressRouteCircuitsClient) ListArpTable(resourceGroupName string, circuitName string, peeringName string, devicePath string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ListArpTablePreparer(resourceGroupName, circuitName, peeringName, devicePath, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListArpTable", nil, "Failure preparing request") + } + + resp, err := client.ListArpTableSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListArpTable", resp, "Failure sending request") + } + + result, err = client.ListArpTableResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListArpTable", resp, "Failure responding to request") + } + + return +} + +// ListArpTablePreparer prepares the ListArpTable request. +func (client ExpressRouteCircuitsClient) ListArpTablePreparer(resourceGroupName string, circuitName string, peeringName string, devicePath string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "devicePath": autorest.Encode("path", devicePath), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}/arpTables/{devicePath}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ListArpTableSender sends the ListArpTable request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) ListArpTableSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ListArpTableResponder handles the response to the ListArpTable request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListArpTableResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// ListRoutesTable the ListRoutesTable from ExpressRouteCircuit operation +// retrieves the currently advertised routes table associated with the +// ExpressRouteCircuits in a resource group. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. peeringName is the name of the peering. devicePath is +// the path of the device. +func (client ExpressRouteCircuitsClient) ListRoutesTable(resourceGroupName string, circuitName string, peeringName string, devicePath string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ListRoutesTablePreparer(resourceGroupName, circuitName, peeringName, devicePath, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListRoutesTable", nil, "Failure preparing request") + } + + resp, err := client.ListRoutesTableSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListRoutesTable", resp, "Failure sending request") + } + + result, err = client.ListRoutesTableResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListRoutesTable", resp, "Failure responding to request") + } + + return +} + +// ListRoutesTablePreparer prepares the ListRoutesTable request. +func (client ExpressRouteCircuitsClient) ListRoutesTablePreparer(resourceGroupName string, circuitName string, peeringName string, devicePath string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "devicePath": autorest.Encode("path", devicePath), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}/routeTables/{devicePath}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ListRoutesTableSender sends the ListRoutesTable request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) ListRoutesTableSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ListRoutesTableResponder handles the response to the ListRoutesTable request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListRoutesTableResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// ListRoutesTableSummary the ListRoutesTable from ExpressRouteCircuit +// operation retrieves the currently advertised routes table associated with +// the ExpressRouteCircuits in a resource group. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. peeringName is the name of the peering. devicePath is +// the path of the device. +func (client ExpressRouteCircuitsClient) ListRoutesTableSummary(resourceGroupName string, circuitName string, peeringName string, devicePath string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ListRoutesTableSummaryPreparer(resourceGroupName, circuitName, peeringName, devicePath, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListRoutesTableSummary", nil, "Failure preparing request") + } + + resp, err := client.ListRoutesTableSummarySender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListRoutesTableSummary", resp, "Failure sending request") + } + + result, err = client.ListRoutesTableSummaryResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsClient", "ListRoutesTableSummary", resp, "Failure responding to request") + } + + return +} + +// ListRoutesTableSummaryPreparer prepares the ListRoutesTableSummary request. +func (client ExpressRouteCircuitsClient) ListRoutesTableSummaryPreparer(resourceGroupName string, circuitName string, peeringName string, devicePath string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": autorest.Encode("path", circuitName), + "devicePath": autorest.Encode("path", devicePath), + "peeringName": autorest.Encode("path", peeringName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}/routeTablesSummary/{devicePath}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ListRoutesTableSummarySender sends the ListRoutesTableSummary request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) ListRoutesTableSummarySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ListRoutesTableSummaryResponder handles the response to the ListRoutesTableSummary request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListRoutesTableSummaryResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go new file mode 100644 index 0000000000..b65d60cf8d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go @@ -0,0 +1,129 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ExpressRouteServiceProvidersClient is the the Microsoft Azure Network +// management API provides a RESTful set of web services that interact with +// Microsoft Azure Networks service to manage your network resources. The API +// has entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type ExpressRouteServiceProvidersClient struct { + ManagementClient +} + +// NewExpressRouteServiceProvidersClient creates an instance of the +// ExpressRouteServiceProvidersClient client. +func NewExpressRouteServiceProvidersClient(subscriptionID string) ExpressRouteServiceProvidersClient { + return NewExpressRouteServiceProvidersClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewExpressRouteServiceProvidersClientWithBaseURI creates an instance of the +// ExpressRouteServiceProvidersClient client. +func NewExpressRouteServiceProvidersClientWithBaseURI(baseURI string, subscriptionID string) ExpressRouteServiceProvidersClient { + return ExpressRouteServiceProvidersClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List the List ExpressRouteServiceProvider operation retrieves all the +// available ExpressRouteServiceProviders. +func (client ExpressRouteServiceProvidersClient) List() (result ExpressRouteServiceProviderListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteServiceProvidersClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteServiceProvidersClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteServiceProvidersClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExpressRouteServiceProvidersClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/expressRouteServiceProviders", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteServiceProvidersClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ExpressRouteServiceProvidersClient) ListResponder(resp *http.Response) (result ExpressRouteServiceProviderListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ExpressRouteServiceProvidersClient) ListNextResults(lastResults ExpressRouteServiceProviderListResult) (result ExpressRouteServiceProviderListResult, err error) { + req, err := lastResults.ExpressRouteServiceProviderListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.ExpressRouteServiceProvidersClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.ExpressRouteServiceProvidersClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.ExpressRouteServiceProvidersClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go new file mode 100644 index 0000000000..4a5309a8cc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go @@ -0,0 +1,821 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// InterfacesClient is the the Microsoft Azure Network management API provides +// a RESTful set of web services that interact with Microsoft Azure Networks +// service to manage your network resources. The API has entities that +// capture the relationship between an end user and the Microsoft Azure +// Networks service. +type InterfacesClient struct { + ManagementClient +} + +// NewInterfacesClient creates an instance of the InterfacesClient client. +func NewInterfacesClient(subscriptionID string) InterfacesClient { + return NewInterfacesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewInterfacesClientWithBaseURI creates an instance of the InterfacesClient +// client. +func NewInterfacesClientWithBaseURI(baseURI string, subscriptionID string) InterfacesClient { + return InterfacesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put NetworkInterface operation creates/updates a +// networkInterface This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. networkInterfaceName +// is the name of the network interface. parameters is parameters supplied to +// the create/update NetworkInterface operation +func (client InterfacesClient) CreateOrUpdate(resourceGroupName string, networkInterfaceName string, parameters Interface, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.NetworkSecurityGroup", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.NetworkSecurityGroup.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.NetworkSecurityGroup.Properties.NetworkInterfaces", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "parameters.Properties.NetworkSecurityGroup.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.InterfacesClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, networkInterfaceName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client InterfacesClient) CreateOrUpdatePreparer(resourceGroupName string, networkInterfaceName string, parameters Interface, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": autorest.Encode("path", networkInterfaceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkInterfaces/{networkInterfaceName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client InterfacesClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete netwokInterface operation deletes the specified +// netwokInterface. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. networkInterfaceName +// is the name of the network interface. +func (client InterfacesClient) Delete(resourceGroupName string, networkInterfaceName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, networkInterfaceName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client InterfacesClient) DeletePreparer(resourceGroupName string, networkInterfaceName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": autorest.Encode("path", networkInterfaceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkInterfaces/{networkInterfaceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client InterfacesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get network interface operation retrieves information about the +// specified network interface. +// +// resourceGroupName is the name of the resource group. networkInterfaceName +// is the name of the network interface. expand is expand references +// resources. +func (client InterfacesClient) Get(resourceGroupName string, networkInterfaceName string, expand string) (result Interface, err error) { + req, err := client.GetPreparer(resourceGroupName, networkInterfaceName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client InterfacesClient) GetPreparer(resourceGroupName string, networkInterfaceName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": autorest.Encode("path", networkInterfaceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkInterfaces/{networkInterfaceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client InterfacesClient) GetResponder(resp *http.Response) (result Interface, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetEffectiveRouteTable the get effective routetable operation retrieves all +// the route tables applied on a networkInterface. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. networkInterfaceName +// is the name of the network interface. +func (client InterfacesClient) GetEffectiveRouteTable(resourceGroupName string, networkInterfaceName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.GetEffectiveRouteTablePreparer(resourceGroupName, networkInterfaceName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "GetEffectiveRouteTable", nil, "Failure preparing request") + } + + resp, err := client.GetEffectiveRouteTableSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "GetEffectiveRouteTable", resp, "Failure sending request") + } + + result, err = client.GetEffectiveRouteTableResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "GetEffectiveRouteTable", resp, "Failure responding to request") + } + + return +} + +// GetEffectiveRouteTablePreparer prepares the GetEffectiveRouteTable request. +func (client InterfacesClient) GetEffectiveRouteTablePreparer(resourceGroupName string, networkInterfaceName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": autorest.Encode("path", networkInterfaceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkInterfaces/{networkInterfaceName}/effectiveRouteTable", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GetEffectiveRouteTableSender sends the GetEffectiveRouteTable request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) GetEffectiveRouteTableSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GetEffectiveRouteTableResponder handles the response to the GetEffectiveRouteTable request. The method always +// closes the http.Response Body. +func (client InterfacesClient) GetEffectiveRouteTableResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// GetVirtualMachineScaleSetNetworkInterface the Get network interface +// operation retrieves information about the specified network interface in a +// virtual machine scale set. +// +// resourceGroupName is the name of the resource group. +// virtualMachineScaleSetName is the name of the virtual machine scale set. +// virtualmachineIndex is the virtual machine index. networkInterfaceName is +// the name of the network interface. expand is expand references resources. +func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterface(resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, expand string) (result Interface, err error) { + req, err := client.GetVirtualMachineScaleSetNetworkInterfacePreparer(resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "GetVirtualMachineScaleSetNetworkInterface", nil, "Failure preparing request") + } + + resp, err := client.GetVirtualMachineScaleSetNetworkInterfaceSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "GetVirtualMachineScaleSetNetworkInterface", resp, "Failure sending request") + } + + result, err = client.GetVirtualMachineScaleSetNetworkInterfaceResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "GetVirtualMachineScaleSetNetworkInterface", resp, "Failure responding to request") + } + + return +} + +// GetVirtualMachineScaleSetNetworkInterfacePreparer prepares the GetVirtualMachineScaleSetNetworkInterface request. +func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterfacePreparer(resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": autorest.Encode("path", networkInterfaceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualmachineIndex": autorest.Encode("path", virtualmachineIndex), + "virtualMachineScaleSetName": autorest.Encode("path", virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex}/networkInterfaces/{networkInterfaceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetVirtualMachineScaleSetNetworkInterfaceSender sends the GetVirtualMachineScaleSetNetworkInterface request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterfaceSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetVirtualMachineScaleSetNetworkInterfaceResponder handles the response to the GetVirtualMachineScaleSetNetworkInterface request. The method always +// closes the http.Response Body. +func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterfaceResponder(resp *http.Response) (result Interface, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List networkInterfaces operation retrieves all the +// networkInterfaces in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client InterfacesClient) List(resourceGroupName string) (result InterfaceListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client InterfacesClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkInterfaces", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client InterfacesClient) ListResponder(resp *http.Response) (result InterfaceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client InterfacesClient) ListNextResults(lastResults InterfaceListResult) (result InterfaceListResult, err error) { + req, err := lastResults.InterfaceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the List networkInterfaces operation retrieves all the +// networkInterfaces in a subscription. +func (client InterfacesClient) ListAll() (result InterfaceListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client InterfacesClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/networkInterfaces", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client InterfacesClient) ListAllResponder(resp *http.Response) (result InterfaceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client InterfacesClient) ListAllNextResults(lastResults InterfaceListResult) (result InterfaceListResult, err error) { + req, err := lastResults.InterfaceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} + +// ListEffectiveNetworkSecurityGroups the list effective network security +// group operation retrieves all the network security groups applied on a +// networkInterface. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. networkInterfaceName +// is the name of the network interface. +func (client InterfacesClient) ListEffectiveNetworkSecurityGroups(resourceGroupName string, networkInterfaceName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ListEffectiveNetworkSecurityGroupsPreparer(resourceGroupName, networkInterfaceName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListEffectiveNetworkSecurityGroups", nil, "Failure preparing request") + } + + resp, err := client.ListEffectiveNetworkSecurityGroupsSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListEffectiveNetworkSecurityGroups", resp, "Failure sending request") + } + + result, err = client.ListEffectiveNetworkSecurityGroupsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListEffectiveNetworkSecurityGroups", resp, "Failure responding to request") + } + + return +} + +// ListEffectiveNetworkSecurityGroupsPreparer prepares the ListEffectiveNetworkSecurityGroups request. +func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsPreparer(resourceGroupName string, networkInterfaceName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": autorest.Encode("path", networkInterfaceName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkInterfaces/{networkInterfaceName}/effectiveNetworkSecurityGroups", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ListEffectiveNetworkSecurityGroupsSender sends the ListEffectiveNetworkSecurityGroups request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ListEffectiveNetworkSecurityGroupsResponder handles the response to the ListEffectiveNetworkSecurityGroups request. The method always +// closes the http.Response Body. +func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// ListVirtualMachineScaleSetNetworkInterfaces the list network interface +// operation retrieves information about all network interfaces in a virtual +// machine scale set. +// +// resourceGroupName is the name of the resource group. +// virtualMachineScaleSetName is the name of the virtual machine scale set. +func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfaces(resourceGroupName string, virtualMachineScaleSetName string) (result InterfaceListResult, err error) { + req, err := client.ListVirtualMachineScaleSetNetworkInterfacesPreparer(resourceGroupName, virtualMachineScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", nil, "Failure preparing request") + } + + resp, err := client.ListVirtualMachineScaleSetNetworkInterfacesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", resp, "Failure sending request") + } + + result, err = client.ListVirtualMachineScaleSetNetworkInterfacesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", resp, "Failure responding to request") + } + + return +} + +// ListVirtualMachineScaleSetNetworkInterfacesPreparer prepares the ListVirtualMachineScaleSetNetworkInterfaces request. +func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfacesPreparer(resourceGroupName string, virtualMachineScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualMachineScaleSetName": autorest.Encode("path", virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/networkInterfaces", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListVirtualMachineScaleSetNetworkInterfacesSender sends the ListVirtualMachineScaleSetNetworkInterfaces request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfacesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListVirtualMachineScaleSetNetworkInterfacesResponder handles the response to the ListVirtualMachineScaleSetNetworkInterfaces request. The method always +// closes the http.Response Body. +func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfacesResponder(resp *http.Response) (result InterfaceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListVirtualMachineScaleSetNetworkInterfacesNextResults retrieves the next set of results, if any. +func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfacesNextResults(lastResults InterfaceListResult) (result InterfaceListResult, err error) { + req, err := lastResults.InterfaceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListVirtualMachineScaleSetNetworkInterfacesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", resp, "Failure sending next results request") + } + + result, err = client.ListVirtualMachineScaleSetNetworkInterfacesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", resp, "Failure responding to next results request") + } + + return +} + +// ListVirtualMachineScaleSetVMNetworkInterfaces the list network interface +// operation retrieves information about all network interfaces in a virtual +// machine from a virtual machine scale set. +// +// resourceGroupName is the name of the resource group. +// virtualMachineScaleSetName is the name of the virtual machine scale set. +// virtualmachineIndex is the virtual machine index. +func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfaces(resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string) (result InterfaceListResult, err error) { + req, err := client.ListVirtualMachineScaleSetVMNetworkInterfacesPreparer(resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", nil, "Failure preparing request") + } + + resp, err := client.ListVirtualMachineScaleSetVMNetworkInterfacesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", resp, "Failure sending request") + } + + result, err = client.ListVirtualMachineScaleSetVMNetworkInterfacesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", resp, "Failure responding to request") + } + + return +} + +// ListVirtualMachineScaleSetVMNetworkInterfacesPreparer prepares the ListVirtualMachineScaleSetVMNetworkInterfaces request. +func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfacesPreparer(resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualmachineIndex": autorest.Encode("path", virtualmachineIndex), + "virtualMachineScaleSetName": autorest.Encode("path", virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex}/networkInterfaces", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListVirtualMachineScaleSetVMNetworkInterfacesSender sends the ListVirtualMachineScaleSetVMNetworkInterfaces request. The method will close the +// http.Response Body if it receives an error. +func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfacesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListVirtualMachineScaleSetVMNetworkInterfacesResponder handles the response to the ListVirtualMachineScaleSetVMNetworkInterfaces request. The method always +// closes the http.Response Body. +func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfacesResponder(resp *http.Response) (result InterfaceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListVirtualMachineScaleSetVMNetworkInterfacesNextResults retrieves the next set of results, if any. +func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfacesNextResults(lastResults InterfaceListResult) (result InterfaceListResult, err error) { + req, err := lastResults.InterfaceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListVirtualMachineScaleSetVMNetworkInterfacesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", resp, "Failure sending next results request") + } + + result, err = client.ListVirtualMachineScaleSetVMNetworkInterfacesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go new file mode 100644 index 0000000000..3426ea03a6 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go @@ -0,0 +1,419 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// LoadBalancersClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type LoadBalancersClient struct { + ManagementClient +} + +// NewLoadBalancersClient creates an instance of the LoadBalancersClient +// client. +func NewLoadBalancersClient(subscriptionID string) LoadBalancersClient { + return NewLoadBalancersClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewLoadBalancersClientWithBaseURI creates an instance of the +// LoadBalancersClient client. +func NewLoadBalancersClientWithBaseURI(baseURI string, subscriptionID string) LoadBalancersClient { + return LoadBalancersClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put LoadBalancer operation creates/updates a +// LoadBalancer This method may poll for completion. Polling can be canceled +// by passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. loadBalancerName is +// the name of the loadBalancer. parameters is parameters supplied to the +// create/delete LoadBalancer operation +func (client LoadBalancersClient) CreateOrUpdate(resourceGroupName string, loadBalancerName string, parameters LoadBalancer, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, loadBalancerName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client LoadBalancersClient) CreateOrUpdatePreparer(resourceGroupName string, loadBalancerName string, parameters LoadBalancer, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "loadBalancerName": autorest.Encode("path", loadBalancerName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/loadBalancers/{loadBalancerName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client LoadBalancersClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client LoadBalancersClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete LoadBalancer operation deletes the specified load +// balancer. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. loadBalancerName is +// the name of the loadBalancer. +func (client LoadBalancersClient) Delete(resourceGroupName string, loadBalancerName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, loadBalancerName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client LoadBalancersClient) DeletePreparer(resourceGroupName string, loadBalancerName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "loadBalancerName": autorest.Encode("path", loadBalancerName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/loadBalancers/{loadBalancerName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client LoadBalancersClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client LoadBalancersClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get LoadBalancer operation retrieves information about the +// specified LoadBalancer. +// +// resourceGroupName is the name of the resource group. loadBalancerName is +// the name of the loadBalancer. expand is expand references resources. +func (client LoadBalancersClient) Get(resourceGroupName string, loadBalancerName string, expand string) (result LoadBalancer, err error) { + req, err := client.GetPreparer(resourceGroupName, loadBalancerName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client LoadBalancersClient) GetPreparer(resourceGroupName string, loadBalancerName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "loadBalancerName": autorest.Encode("path", loadBalancerName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/loadBalancers/{loadBalancerName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client LoadBalancersClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client LoadBalancersClient) GetResponder(resp *http.Response) (result LoadBalancer, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List loadBalancer operation retrieves all the load balancers in a +// resource group. +// +// resourceGroupName is the name of the resource group. +func (client LoadBalancersClient) List(resourceGroupName string) (result LoadBalancerListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client LoadBalancersClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/loadBalancers", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client LoadBalancersClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client LoadBalancersClient) ListResponder(resp *http.Response) (result LoadBalancerListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client LoadBalancersClient) ListNextResults(lastResults LoadBalancerListResult) (result LoadBalancerListResult, err error) { + req, err := lastResults.LoadBalancerListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the List loadBalancer operation retrieves all the load balancers in +// a subscription. +func (client LoadBalancersClient) ListAll() (result LoadBalancerListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client LoadBalancersClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/loadBalancers", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client LoadBalancersClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client LoadBalancersClient) ListAllResponder(resp *http.Response) (result LoadBalancerListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client LoadBalancersClient) ListAllNextResults(lastResults LoadBalancerListResult) (result LoadBalancerListResult, err error) { + req, err := lastResults.LoadBalancerListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LoadBalancersClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LoadBalancersClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go new file mode 100644 index 0000000000..847054dc47 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go @@ -0,0 +1,336 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// LocalNetworkGatewaysClient is the the Microsoft Azure Network management +// API provides a RESTful set of web services that interact with Microsoft +// Azure Networks service to manage your network resources. The API has +// entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type LocalNetworkGatewaysClient struct { + ManagementClient +} + +// NewLocalNetworkGatewaysClient creates an instance of the +// LocalNetworkGatewaysClient client. +func NewLocalNetworkGatewaysClient(subscriptionID string) LocalNetworkGatewaysClient { + return NewLocalNetworkGatewaysClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewLocalNetworkGatewaysClientWithBaseURI creates an instance of the +// LocalNetworkGatewaysClient client. +func NewLocalNetworkGatewaysClientWithBaseURI(baseURI string, subscriptionID string) LocalNetworkGatewaysClient { + return LocalNetworkGatewaysClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put LocalNetworkGateway operation creates/updates a +// local network gateway in the specified resource group through Network +// resource provider. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// localNetworkGatewayName is the name of the local network gateway. +// parameters is parameters supplied to the Begin Create or update Local +// Network Gateway operation through Network resource provider. +func (client LocalNetworkGatewaysClient) CreateOrUpdate(resourceGroupName string, localNetworkGatewayName string, parameters LocalNetworkGateway, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, localNetworkGatewayName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client LocalNetworkGatewaysClient) CreateOrUpdatePreparer(resourceGroupName string, localNetworkGatewayName string, parameters LocalNetworkGateway, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "localNetworkGatewayName": autorest.Encode("path", localNetworkGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/localNetworkGateways/{localNetworkGatewayName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client LocalNetworkGatewaysClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client LocalNetworkGatewaysClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the Delete LocalNetworkGateway operation deletes the specified local +// network Gateway through Network resource provider. This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. +// localNetworkGatewayName is the name of the local network gateway. +func (client LocalNetworkGatewaysClient) Delete(resourceGroupName string, localNetworkGatewayName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, localNetworkGatewayName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client LocalNetworkGatewaysClient) DeletePreparer(resourceGroupName string, localNetworkGatewayName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "localNetworkGatewayName": autorest.Encode("path", localNetworkGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/localNetworkGateways/{localNetworkGatewayName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client LocalNetworkGatewaysClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client LocalNetworkGatewaysClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get LocalNetworkGateway operation retrieves information about the +// specified local network gateway through Network resource provider. +// +// resourceGroupName is the name of the resource group. +// localNetworkGatewayName is the name of the local network gateway. +func (client LocalNetworkGatewaysClient) Get(resourceGroupName string, localNetworkGatewayName string) (result LocalNetworkGateway, err error) { + req, err := client.GetPreparer(resourceGroupName, localNetworkGatewayName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client LocalNetworkGatewaysClient) GetPreparer(resourceGroupName string, localNetworkGatewayName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "localNetworkGatewayName": autorest.Encode("path", localNetworkGatewayName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/localNetworkGateways/{localNetworkGatewayName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client LocalNetworkGatewaysClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client LocalNetworkGatewaysClient) GetResponder(resp *http.Response) (result LocalNetworkGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List LocalNetworkGateways operation retrieves all the local +// network gateways stored. +// +// resourceGroupName is the name of the resource group. +func (client LocalNetworkGatewaysClient) List(resourceGroupName string) (result LocalNetworkGatewayListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client LocalNetworkGatewaysClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/localNetworkGateways", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client LocalNetworkGatewaysClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client LocalNetworkGatewaysClient) ListResponder(resp *http.Response) (result LocalNetworkGatewayListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client LocalNetworkGatewaysClient) ListNextResults(lastResults LocalNetworkGatewayListResult) (result LocalNetworkGatewayListResult, err error) { + req, err := lastResults.LocalNetworkGatewayListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/models.go new file mode 100644 index 0000000000..7158b03839 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/models.go @@ -0,0 +1,2069 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// ApplicationGatewayCookieBasedAffinity enumerates the values for application +// gateway cookie based affinity. +type ApplicationGatewayCookieBasedAffinity string + +const ( + // Disabled specifies the disabled state for application gateway cookie + // based affinity. + Disabled ApplicationGatewayCookieBasedAffinity = "Disabled" + // Enabled specifies the enabled state for application gateway cookie + // based affinity. + Enabled ApplicationGatewayCookieBasedAffinity = "Enabled" +) + +// ApplicationGatewayOperationalState enumerates the values for application +// gateway operational state. +type ApplicationGatewayOperationalState string + +const ( + // Running specifies the running state for application gateway operational + // state. + Running ApplicationGatewayOperationalState = "Running" + // Starting specifies the starting state for application gateway + // operational state. + Starting ApplicationGatewayOperationalState = "Starting" + // Stopped specifies the stopped state for application gateway operational + // state. + Stopped ApplicationGatewayOperationalState = "Stopped" + // Stopping specifies the stopping state for application gateway + // operational state. + Stopping ApplicationGatewayOperationalState = "Stopping" +) + +// ApplicationGatewayProtocol enumerates the values for application gateway +// protocol. +type ApplicationGatewayProtocol string + +const ( + // HTTP specifies the http state for application gateway protocol. + HTTP ApplicationGatewayProtocol = "Http" + // HTTPS specifies the https state for application gateway protocol. + HTTPS ApplicationGatewayProtocol = "Https" +) + +// ApplicationGatewayRequestRoutingRuleType enumerates the values for +// application gateway request routing rule type. +type ApplicationGatewayRequestRoutingRuleType string + +const ( + // Basic specifies the basic state for application gateway request routing + // rule type. + Basic ApplicationGatewayRequestRoutingRuleType = "Basic" + // PathBasedRouting specifies the path based routing state for application + // gateway request routing rule type. + PathBasedRouting ApplicationGatewayRequestRoutingRuleType = "PathBasedRouting" +) + +// ApplicationGatewaySkuName enumerates the values for application gateway sku +// name. +type ApplicationGatewaySkuName string + +const ( + // StandardLarge specifies the standard large state for application + // gateway sku name. + StandardLarge ApplicationGatewaySkuName = "Standard_Large" + // StandardMedium specifies the standard medium state for application + // gateway sku name. + StandardMedium ApplicationGatewaySkuName = "Standard_Medium" + // StandardSmall specifies the standard small state for application + // gateway sku name. + StandardSmall ApplicationGatewaySkuName = "Standard_Small" +) + +// ApplicationGatewaySslProtocol enumerates the values for application gateway +// ssl protocol. +type ApplicationGatewaySslProtocol string + +const ( + // TLSv10 specifies the tl sv 10 state for application gateway ssl + // protocol. + TLSv10 ApplicationGatewaySslProtocol = "TLSv1_0" + // TLSv11 specifies the tl sv 11 state for application gateway ssl + // protocol. + TLSv11 ApplicationGatewaySslProtocol = "TLSv1_1" + // TLSv12 specifies the tl sv 12 state for application gateway ssl + // protocol. + TLSv12 ApplicationGatewaySslProtocol = "TLSv1_2" +) + +// ApplicationGatewayTier enumerates the values for application gateway tier. +type ApplicationGatewayTier string + +const ( + // Standard specifies the standard state for application gateway tier. + Standard ApplicationGatewayTier = "Standard" +) + +// AuthorizationUseStatus enumerates the values for authorization use status. +type AuthorizationUseStatus string + +const ( + // Available specifies the available state for authorization use status. + Available AuthorizationUseStatus = "Available" + // InUse specifies the in use state for authorization use status. + InUse AuthorizationUseStatus = "InUse" +) + +// EffectiveRouteSource enumerates the values for effective route source. +type EffectiveRouteSource string + +const ( + // EffectiveRouteSourceDefault specifies the effective route source + // default state for effective route source. + EffectiveRouteSourceDefault EffectiveRouteSource = "Default" + // EffectiveRouteSourceUnknown specifies the effective route source + // unknown state for effective route source. + EffectiveRouteSourceUnknown EffectiveRouteSource = "Unknown" + // EffectiveRouteSourceUser specifies the effective route source user + // state for effective route source. + EffectiveRouteSourceUser EffectiveRouteSource = "User" + // EffectiveRouteSourceVirtualNetworkGateway specifies the effective route + // source virtual network gateway state for effective route source. + EffectiveRouteSourceVirtualNetworkGateway EffectiveRouteSource = "VirtualNetworkGateway" +) + +// EffectiveRouteState enumerates the values for effective route state. +type EffectiveRouteState string + +const ( + // Active specifies the active state for effective route state. + Active EffectiveRouteState = "Active" + // Invalid specifies the invalid state for effective route state. + Invalid EffectiveRouteState = "Invalid" +) + +// ExpressRouteCircuitPeeringAdvertisedPublicPrefixState enumerates the values +// for express route circuit peering advertised public prefix state. +type ExpressRouteCircuitPeeringAdvertisedPublicPrefixState string + +const ( + // Configured specifies the configured state for express route circuit + // peering advertised public prefix state. + Configured ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "Configured" + // Configuring specifies the configuring state for express route circuit + // peering advertised public prefix state. + Configuring ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "Configuring" + // NotConfigured specifies the not configured state for express route + // circuit peering advertised public prefix state. + NotConfigured ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "NotConfigured" + // ValidationNeeded specifies the validation needed state for express + // route circuit peering advertised public prefix state. + ValidationNeeded ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "ValidationNeeded" +) + +// ExpressRouteCircuitPeeringState enumerates the values for express route +// circuit peering state. +type ExpressRouteCircuitPeeringState string + +const ( + // ExpressRouteCircuitPeeringStateDisabled specifies the express route + // circuit peering state disabled state for express route circuit peering + // state. + ExpressRouteCircuitPeeringStateDisabled ExpressRouteCircuitPeeringState = "Disabled" + // ExpressRouteCircuitPeeringStateEnabled specifies the express route + // circuit peering state enabled state for express route circuit peering + // state. + ExpressRouteCircuitPeeringStateEnabled ExpressRouteCircuitPeeringState = "Enabled" +) + +// ExpressRouteCircuitPeeringType enumerates the values for express route +// circuit peering type. +type ExpressRouteCircuitPeeringType string + +const ( + // AzurePrivatePeering specifies the azure private peering state for + // express route circuit peering type. + AzurePrivatePeering ExpressRouteCircuitPeeringType = "AzurePrivatePeering" + // AzurePublicPeering specifies the azure public peering state for express + // route circuit peering type. + AzurePublicPeering ExpressRouteCircuitPeeringType = "AzurePublicPeering" + // MicrosoftPeering specifies the microsoft peering state for express + // route circuit peering type. + MicrosoftPeering ExpressRouteCircuitPeeringType = "MicrosoftPeering" +) + +// ExpressRouteCircuitSkuFamily enumerates the values for express route +// circuit sku family. +type ExpressRouteCircuitSkuFamily string + +const ( + // MeteredData specifies the metered data state for express route circuit + // sku family. + MeteredData ExpressRouteCircuitSkuFamily = "MeteredData" + // UnlimitedData specifies the unlimited data state for express route + // circuit sku family. + UnlimitedData ExpressRouteCircuitSkuFamily = "UnlimitedData" +) + +// ExpressRouteCircuitSkuTier enumerates the values for express route circuit +// sku tier. +type ExpressRouteCircuitSkuTier string + +const ( + // ExpressRouteCircuitSkuTierPremium specifies the express route circuit + // sku tier premium state for express route circuit sku tier. + ExpressRouteCircuitSkuTierPremium ExpressRouteCircuitSkuTier = "Premium" + // ExpressRouteCircuitSkuTierStandard specifies the express route circuit + // sku tier standard state for express route circuit sku tier. + ExpressRouteCircuitSkuTierStandard ExpressRouteCircuitSkuTier = "Standard" +) + +// IPAllocationMethod enumerates the values for ip allocation method. +type IPAllocationMethod string + +const ( + // Dynamic specifies the dynamic state for ip allocation method. + Dynamic IPAllocationMethod = "Dynamic" + // Static specifies the static state for ip allocation method. + Static IPAllocationMethod = "Static" +) + +// IPVersion enumerates the values for ip version. +type IPVersion string + +const ( + // IPv4 specifies the i pv 4 state for ip version. + IPv4 IPVersion = "IPv4" + // IPv6 specifies the i pv 6 state for ip version. + IPv6 IPVersion = "IPv6" +) + +// LoadDistribution enumerates the values for load distribution. +type LoadDistribution string + +const ( + // Default specifies the default state for load distribution. + Default LoadDistribution = "Default" + // SourceIP specifies the source ip state for load distribution. + SourceIP LoadDistribution = "SourceIP" + // SourceIPProtocol specifies the source ip protocol state for load + // distribution. + SourceIPProtocol LoadDistribution = "SourceIPProtocol" +) + +// OperationStatus enumerates the values for operation status. +type OperationStatus string + +const ( + // Failed specifies the failed state for operation status. + Failed OperationStatus = "Failed" + // InProgress specifies the in progress state for operation status. + InProgress OperationStatus = "InProgress" + // Succeeded specifies the succeeded state for operation status. + Succeeded OperationStatus = "Succeeded" +) + +// ProbeProtocol enumerates the values for probe protocol. +type ProbeProtocol string + +const ( + // ProbeProtocolHTTP specifies the probe protocol http state for probe + // protocol. + ProbeProtocolHTTP ProbeProtocol = "Http" + // ProbeProtocolTCP specifies the probe protocol tcp state for probe + // protocol. + ProbeProtocolTCP ProbeProtocol = "Tcp" +) + +// ProcessorArchitecture enumerates the values for processor architecture. +type ProcessorArchitecture string + +const ( + // Amd64 specifies the amd 64 state for processor architecture. + Amd64 ProcessorArchitecture = "Amd64" + // X86 specifies the x86 state for processor architecture. + X86 ProcessorArchitecture = "X86" +) + +// RouteNextHopType enumerates the values for route next hop type. +type RouteNextHopType string + +const ( + // RouteNextHopTypeInternet specifies the route next hop type internet + // state for route next hop type. + RouteNextHopTypeInternet RouteNextHopType = "Internet" + // RouteNextHopTypeNone specifies the route next hop type none state for + // route next hop type. + RouteNextHopTypeNone RouteNextHopType = "None" + // RouteNextHopTypeVirtualAppliance specifies the route next hop type + // virtual appliance state for route next hop type. + RouteNextHopTypeVirtualAppliance RouteNextHopType = "VirtualAppliance" + // RouteNextHopTypeVirtualNetworkGateway specifies the route next hop type + // virtual network gateway state for route next hop type. + RouteNextHopTypeVirtualNetworkGateway RouteNextHopType = "VirtualNetworkGateway" + // RouteNextHopTypeVnetLocal specifies the route next hop type vnet local + // state for route next hop type. + RouteNextHopTypeVnetLocal RouteNextHopType = "VnetLocal" +) + +// SecurityRuleAccess enumerates the values for security rule access. +type SecurityRuleAccess string + +const ( + // Allow specifies the allow state for security rule access. + Allow SecurityRuleAccess = "Allow" + // Deny specifies the deny state for security rule access. + Deny SecurityRuleAccess = "Deny" +) + +// SecurityRuleDirection enumerates the values for security rule direction. +type SecurityRuleDirection string + +const ( + // Inbound specifies the inbound state for security rule direction. + Inbound SecurityRuleDirection = "Inbound" + // Outbound specifies the outbound state for security rule direction. + Outbound SecurityRuleDirection = "Outbound" +) + +// SecurityRuleProtocol enumerates the values for security rule protocol. +type SecurityRuleProtocol string + +const ( + // Asterisk specifies the asterisk state for security rule protocol. + Asterisk SecurityRuleProtocol = "*" + // TCP specifies the tcp state for security rule protocol. + TCP SecurityRuleProtocol = "Tcp" + // UDP specifies the udp state for security rule protocol. + UDP SecurityRuleProtocol = "Udp" +) + +// ServiceProviderProvisioningState enumerates the values for service provider +// provisioning state. +type ServiceProviderProvisioningState string + +const ( + // Deprovisioning specifies the deprovisioning state for service provider + // provisioning state. + Deprovisioning ServiceProviderProvisioningState = "Deprovisioning" + // NotProvisioned specifies the not provisioned state for service provider + // provisioning state. + NotProvisioned ServiceProviderProvisioningState = "NotProvisioned" + // Provisioned specifies the provisioned state for service provider + // provisioning state. + Provisioned ServiceProviderProvisioningState = "Provisioned" + // Provisioning specifies the provisioning state for service provider + // provisioning state. + Provisioning ServiceProviderProvisioningState = "Provisioning" +) + +// TransportProtocol enumerates the values for transport protocol. +type TransportProtocol string + +const ( + // TransportProtocolTCP specifies the transport protocol tcp state for + // transport protocol. + TransportProtocolTCP TransportProtocol = "Tcp" + // TransportProtocolUDP specifies the transport protocol udp state for + // transport protocol. + TransportProtocolUDP TransportProtocol = "Udp" +) + +// VirtualNetworkGatewayConnectionStatus enumerates the values for virtual +// network gateway connection status. +type VirtualNetworkGatewayConnectionStatus string + +const ( + // Connected specifies the connected state for virtual network gateway + // connection status. + Connected VirtualNetworkGatewayConnectionStatus = "Connected" + // Connecting specifies the connecting state for virtual network gateway + // connection status. + Connecting VirtualNetworkGatewayConnectionStatus = "Connecting" + // NotConnected specifies the not connected state for virtual network + // gateway connection status. + NotConnected VirtualNetworkGatewayConnectionStatus = "NotConnected" + // Unknown specifies the unknown state for virtual network gateway + // connection status. + Unknown VirtualNetworkGatewayConnectionStatus = "Unknown" +) + +// VirtualNetworkGatewayConnectionType enumerates the values for virtual +// network gateway connection type. +type VirtualNetworkGatewayConnectionType string + +const ( + // ExpressRoute specifies the express route state for virtual network + // gateway connection type. + ExpressRoute VirtualNetworkGatewayConnectionType = "ExpressRoute" + // IPsec specifies the i psec state for virtual network gateway connection + // type. + IPsec VirtualNetworkGatewayConnectionType = "IPsec" + // Vnet2Vnet specifies the vnet 2 vnet state for virtual network gateway + // connection type. + Vnet2Vnet VirtualNetworkGatewayConnectionType = "Vnet2Vnet" + // VPNClient specifies the vpn client state for virtual network gateway + // connection type. + VPNClient VirtualNetworkGatewayConnectionType = "VPNClient" +) + +// VirtualNetworkGatewaySkuName enumerates the values for virtual network +// gateway sku name. +type VirtualNetworkGatewaySkuName string + +const ( + // VirtualNetworkGatewaySkuNameBasic specifies the virtual network gateway + // sku name basic state for virtual network gateway sku name. + VirtualNetworkGatewaySkuNameBasic VirtualNetworkGatewaySkuName = "Basic" + // VirtualNetworkGatewaySkuNameHighPerformance specifies the virtual + // network gateway sku name high performance state for virtual network + // gateway sku name. + VirtualNetworkGatewaySkuNameHighPerformance VirtualNetworkGatewaySkuName = "HighPerformance" + // VirtualNetworkGatewaySkuNameStandard specifies the virtual network + // gateway sku name standard state for virtual network gateway sku name. + VirtualNetworkGatewaySkuNameStandard VirtualNetworkGatewaySkuName = "Standard" + // VirtualNetworkGatewaySkuNameUltraPerformance specifies the virtual + // network gateway sku name ultra performance state for virtual network + // gateway sku name. + VirtualNetworkGatewaySkuNameUltraPerformance VirtualNetworkGatewaySkuName = "UltraPerformance" +) + +// VirtualNetworkGatewaySkuTier enumerates the values for virtual network +// gateway sku tier. +type VirtualNetworkGatewaySkuTier string + +const ( + // VirtualNetworkGatewaySkuTierBasic specifies the virtual network gateway + // sku tier basic state for virtual network gateway sku tier. + VirtualNetworkGatewaySkuTierBasic VirtualNetworkGatewaySkuTier = "Basic" + // VirtualNetworkGatewaySkuTierHighPerformance specifies the virtual + // network gateway sku tier high performance state for virtual network + // gateway sku tier. + VirtualNetworkGatewaySkuTierHighPerformance VirtualNetworkGatewaySkuTier = "HighPerformance" + // VirtualNetworkGatewaySkuTierStandard specifies the virtual network + // gateway sku tier standard state for virtual network gateway sku tier. + VirtualNetworkGatewaySkuTierStandard VirtualNetworkGatewaySkuTier = "Standard" + // VirtualNetworkGatewaySkuTierUltraPerformance specifies the virtual + // network gateway sku tier ultra performance state for virtual network + // gateway sku tier. + VirtualNetworkGatewaySkuTierUltraPerformance VirtualNetworkGatewaySkuTier = "UltraPerformance" +) + +// VirtualNetworkGatewayType enumerates the values for virtual network gateway +// type. +type VirtualNetworkGatewayType string + +const ( + // VirtualNetworkGatewayTypeExpressRoute specifies the virtual network + // gateway type express route state for virtual network gateway type. + VirtualNetworkGatewayTypeExpressRoute VirtualNetworkGatewayType = "ExpressRoute" + // VirtualNetworkGatewayTypeVpn specifies the virtual network gateway type + // vpn state for virtual network gateway type. + VirtualNetworkGatewayTypeVpn VirtualNetworkGatewayType = "Vpn" +) + +// VirtualNetworkPeeringState enumerates the values for virtual network +// peering state. +type VirtualNetworkPeeringState string + +const ( + // VirtualNetworkPeeringStateConnected specifies the virtual network + // peering state connected state for virtual network peering state. + VirtualNetworkPeeringStateConnected VirtualNetworkPeeringState = "Connected" + // VirtualNetworkPeeringStateDisconnected specifies the virtual network + // peering state disconnected state for virtual network peering state. + VirtualNetworkPeeringStateDisconnected VirtualNetworkPeeringState = "Disconnected" + // VirtualNetworkPeeringStateInitiated specifies the virtual network + // peering state initiated state for virtual network peering state. + VirtualNetworkPeeringStateInitiated VirtualNetworkPeeringState = "Initiated" +) + +// VpnType enumerates the values for vpn type. +type VpnType string + +const ( + // PolicyBased specifies the policy based state for vpn type. + PolicyBased VpnType = "PolicyBased" + // RouteBased specifies the route based state for vpn type. + RouteBased VpnType = "RouteBased" +) + +// AddressSpace is addressSpace contains an array of IP address ranges that +// can be used by subnets +type AddressSpace struct { + AddressPrefixes *[]string `json:"addressPrefixes,omitempty"` +} + +// ApplicationGateway is applicationGateways resource +type ApplicationGateway struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *ApplicationGatewayPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayAuthenticationCertificate is authentication certificates +// of application gateway +type ApplicationGatewayAuthenticationCertificate struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayAuthenticationCertificatePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayAuthenticationCertificatePropertiesFormat is properties +// of Authentication certificates of application gateway +type ApplicationGatewayAuthenticationCertificatePropertiesFormat struct { + Data *string `json:"data,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayBackendAddress is backend Address of application gateway +type ApplicationGatewayBackendAddress struct { + Fqdn *string `json:"fqdn,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` +} + +// ApplicationGatewayBackendAddressPool is backend Address Pool of application +// gateway +type ApplicationGatewayBackendAddressPool struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayBackendAddressPoolPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayBackendAddressPoolPropertiesFormat is properties of +// Backend Address Pool of application gateway +type ApplicationGatewayBackendAddressPoolPropertiesFormat struct { + BackendIPConfigurations *[]InterfaceIPConfiguration `json:"backendIPConfigurations,omitempty"` + BackendAddresses *[]ApplicationGatewayBackendAddress `json:"backendAddresses,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayBackendHTTPSettings is backend address pool settings of +// application gateway +type ApplicationGatewayBackendHTTPSettings struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayBackendHTTPSettingsPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayBackendHTTPSettingsPropertiesFormat is properties of +// Backend address pool settings of application gateway +type ApplicationGatewayBackendHTTPSettingsPropertiesFormat struct { + Port *int32 `json:"port,omitempty"` + Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"` + CookieBasedAffinity ApplicationGatewayCookieBasedAffinity `json:"cookieBasedAffinity,omitempty"` + RequestTimeout *int32 `json:"requestTimeout,omitempty"` + Probe *SubResource `json:"probe,omitempty"` + AuthenticationCertificates *[]SubResource `json:"authenticationCertificates,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayFrontendIPConfiguration is frontend IP configuration of +// application gateway +type ApplicationGatewayFrontendIPConfiguration struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayFrontendIPConfigurationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayFrontendIPConfigurationPropertiesFormat is properties of +// Frontend IP configuration of application gateway +type ApplicationGatewayFrontendIPConfigurationPropertiesFormat struct { + PrivateIPAddress *string `json:"privateIPAddress,omitempty"` + PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"` + Subnet *SubResource `json:"subnet,omitempty"` + PublicIPAddress *SubResource `json:"publicIPAddress,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayFrontendPort is frontend Port of application gateway +type ApplicationGatewayFrontendPort struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayFrontendPortPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayFrontendPortPropertiesFormat is properties of Frontend +// Port of application gateway +type ApplicationGatewayFrontendPortPropertiesFormat struct { + Port *int32 `json:"port,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayHTTPListener is http listener of application gateway +type ApplicationGatewayHTTPListener struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayHTTPListenerPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayHTTPListenerPropertiesFormat is properties of Http +// listener of application gateway +type ApplicationGatewayHTTPListenerPropertiesFormat struct { + FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"` + FrontendPort *SubResource `json:"frontendPort,omitempty"` + Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"` + HostName *string `json:"hostName,omitempty"` + SslCertificate *SubResource `json:"sslCertificate,omitempty"` + RequireServerNameIndication *bool `json:"requireServerNameIndication,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayIPConfiguration is iP configuration of application gateway +type ApplicationGatewayIPConfiguration struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayIPConfigurationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayIPConfigurationPropertiesFormat is properties of IP +// configuration of application gateway +type ApplicationGatewayIPConfigurationPropertiesFormat struct { + Subnet *SubResource `json:"subnet,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayListResult is response for ListApplicationGateways Api +// service call +type ApplicationGatewayListResult struct { + autorest.Response `json:"-"` + Value *[]ApplicationGateway `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ApplicationGatewayListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ApplicationGatewayListResult) ApplicationGatewayListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ApplicationGatewayPathRule is path rule of URL path map of application +// gateway +type ApplicationGatewayPathRule struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayPathRulePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayPathRulePropertiesFormat is properties of probe of +// application gateway +type ApplicationGatewayPathRulePropertiesFormat struct { + Paths *[]string `json:"paths,omitempty"` + BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"` + BackendHTTPSettings *SubResource `json:"backendHttpSettings,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayProbe is probe of application gateway +type ApplicationGatewayProbe struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayProbePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayProbePropertiesFormat is properties of probe of +// application gateway +type ApplicationGatewayProbePropertiesFormat struct { + Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"` + Host *string `json:"host,omitempty"` + Path *string `json:"path,omitempty"` + Interval *int32 `json:"interval,omitempty"` + Timeout *int32 `json:"timeout,omitempty"` + UnhealthyThreshold *int32 `json:"unhealthyThreshold,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayPropertiesFormat is properties of Application Gateway +type ApplicationGatewayPropertiesFormat struct { + Sku *ApplicationGatewaySku `json:"sku,omitempty"` + SslPolicy *ApplicationGatewaySslPolicy `json:"sslPolicy,omitempty"` + OperationalState ApplicationGatewayOperationalState `json:"operationalState,omitempty"` + GatewayIPConfigurations *[]ApplicationGatewayIPConfiguration `json:"gatewayIPConfigurations,omitempty"` + AuthenticationCertificates *[]ApplicationGatewayAuthenticationCertificate `json:"authenticationCertificates,omitempty"` + SslCertificates *[]ApplicationGatewaySslCertificate `json:"sslCertificates,omitempty"` + FrontendIPConfigurations *[]ApplicationGatewayFrontendIPConfiguration `json:"frontendIPConfigurations,omitempty"` + FrontendPorts *[]ApplicationGatewayFrontendPort `json:"frontendPorts,omitempty"` + Probes *[]ApplicationGatewayProbe `json:"probes,omitempty"` + BackendAddressPools *[]ApplicationGatewayBackendAddressPool `json:"backendAddressPools,omitempty"` + BackendHTTPSettingsCollection *[]ApplicationGatewayBackendHTTPSettings `json:"backendHttpSettingsCollection,omitempty"` + HTTPListeners *[]ApplicationGatewayHTTPListener `json:"httpListeners,omitempty"` + URLPathMaps *[]ApplicationGatewayURLPathMap `json:"urlPathMaps,omitempty"` + RequestRoutingRules *[]ApplicationGatewayRequestRoutingRule `json:"requestRoutingRules,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewayRequestRoutingRule is request routing rule of application +// gateway +type ApplicationGatewayRequestRoutingRule struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayRequestRoutingRulePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayRequestRoutingRulePropertiesFormat is properties of +// Request routing rule of application gateway +type ApplicationGatewayRequestRoutingRulePropertiesFormat struct { + RuleType ApplicationGatewayRequestRoutingRuleType `json:"ruleType,omitempty"` + BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"` + BackendHTTPSettings *SubResource `json:"backendHttpSettings,omitempty"` + HTTPListener *SubResource `json:"httpListener,omitempty"` + URLPathMap *SubResource `json:"urlPathMap,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewaySku is sKU of application gateway +type ApplicationGatewaySku struct { + Name ApplicationGatewaySkuName `json:"name,omitempty"` + Tier ApplicationGatewayTier `json:"tier,omitempty"` + Capacity *int32 `json:"capacity,omitempty"` +} + +// ApplicationGatewaySslCertificate is sSL certificates of application gateway +type ApplicationGatewaySslCertificate struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewaySslCertificatePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewaySslCertificatePropertiesFormat is properties of SSL +// certificates of application gateway +type ApplicationGatewaySslCertificatePropertiesFormat struct { + Data *string `json:"data,omitempty"` + Password *string `json:"password,omitempty"` + PublicCertData *string `json:"publicCertData,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ApplicationGatewaySslPolicy is application gateway SSL policy +type ApplicationGatewaySslPolicy struct { + DisabledSslProtocols *[]ApplicationGatewaySslProtocol `json:"disabledSslProtocols,omitempty"` +} + +// ApplicationGatewayURLPathMap is urlPathMap of application gateway +type ApplicationGatewayURLPathMap struct { + ID *string `json:"id,omitempty"` + Properties *ApplicationGatewayURLPathMapPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ApplicationGatewayURLPathMapPropertiesFormat is properties of UrlPathMap of +// application gateway +type ApplicationGatewayURLPathMapPropertiesFormat struct { + DefaultBackendAddressPool *SubResource `json:"defaultBackendAddressPool,omitempty"` + DefaultBackendHTTPSettings *SubResource `json:"defaultBackendHttpSettings,omitempty"` + PathRules *[]ApplicationGatewayPathRule `json:"pathRules,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// AuthorizationListResult is response for ListAuthorizations Api service +// callRetrieves all authorizations that belongs to an ExpressRouteCircuit +type AuthorizationListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuitAuthorization `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// AuthorizationListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client AuthorizationListResult) AuthorizationListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// AuthorizationPropertiesFormat is +type AuthorizationPropertiesFormat struct { + AuthorizationKey *string `json:"authorizationKey,omitempty"` + AuthorizationUseStatus AuthorizationUseStatus `json:"authorizationUseStatus,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// AzureAsyncOperationResult is the response body contains the status of the +// specified asynchronous operation, indicating whether it has succeeded, is +// in progress, or has failed. Note that this status is distinct from the +// HTTP status code returned for the Get Operation Status operation itself. +// If the asynchronous operation succeeded, the response body includes the +// HTTP status code for the successful request. If the asynchronous operation +// failed, the response body includes the HTTP status code for the failed +// request and error information regarding the failure. +type AzureAsyncOperationResult struct { + Status OperationStatus `json:"status,omitempty"` + Error *Error `json:"error,omitempty"` +} + +// BackendAddressPool is pool of backend IP addresses +type BackendAddressPool struct { + ID *string `json:"id,omitempty"` + Properties *BackendAddressPoolPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// BackendAddressPoolPropertiesFormat is properties of BackendAddressPool +type BackendAddressPoolPropertiesFormat struct { + BackendIPConfigurations *[]InterfaceIPConfiguration `json:"backendIPConfigurations,omitempty"` + LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"` + OutboundNatRule *SubResource `json:"outboundNatRule,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// BgpSettings is +type BgpSettings struct { + Asn *int64 `json:"asn,omitempty"` + BgpPeeringAddress *string `json:"bgpPeeringAddress,omitempty"` + PeerWeight *int32 `json:"peerWeight,omitempty"` +} + +// ConnectionResetSharedKey is +type ConnectionResetSharedKey struct { + autorest.Response `json:"-"` + KeyLength *int64 `json:"keyLength,omitempty"` +} + +// ConnectionSharedKey is response for GetConnectionSharedKey Api service call +type ConnectionSharedKey struct { + autorest.Response `json:"-"` + Value *string `json:"value,omitempty"` +} + +// ConnectionSharedKeyResult is response for CheckConnectionSharedKey Api +// service call +type ConnectionSharedKeyResult struct { + autorest.Response `json:"-"` + Value *string `json:"value,omitempty"` +} + +// DhcpOptions is dHCPOptions contains an array of DNS servers available to +// VMs deployed in the virtual networkStandard DHCP option for a subnet +// overrides VNET DHCP options. +type DhcpOptions struct { + DNSServers *[]string `json:"dnsServers,omitempty"` +} + +// DNSNameAvailabilityResult is response for CheckDnsNameAvailability Api +// service call +type DNSNameAvailabilityResult struct { + autorest.Response `json:"-"` + Available *bool `json:"available,omitempty"` +} + +// EffectiveNetworkSecurityGroup is effective NetworkSecurityGroup +type EffectiveNetworkSecurityGroup struct { + NetworkSecurityGroup *SubResource `json:"networkSecurityGroup,omitempty"` + Association *EffectiveNetworkSecurityGroupAssociation `json:"association,omitempty"` + EffectiveSecurityRules *[]EffectiveNetworkSecurityRule `json:"effectiveSecurityRules,omitempty"` +} + +// EffectiveNetworkSecurityGroupAssociation is effective NetworkSecurityGroup +// association +type EffectiveNetworkSecurityGroupAssociation struct { + Subnet *SubResource `json:"subnet,omitempty"` + NetworkInterface *SubResource `json:"networkInterface,omitempty"` +} + +// EffectiveNetworkSecurityGroupListResult is response for list effective +// network security groups api service call +type EffectiveNetworkSecurityGroupListResult struct { + autorest.Response `json:"-"` + Value *[]EffectiveNetworkSecurityGroup `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// EffectiveNetworkSecurityRule is effective NetworkSecurityRules +type EffectiveNetworkSecurityRule struct { + Name *string `json:"name,omitempty"` + Protocol SecurityRuleProtocol `json:"protocol,omitempty"` + SourcePortRange *string `json:"sourcePortRange,omitempty"` + DestinationPortRange *string `json:"destinationPortRange,omitempty"` + SourceAddressPrefix *string `json:"sourceAddressPrefix,omitempty"` + DestinationAddressPrefix *string `json:"destinationAddressPrefix,omitempty"` + ExpandedSourceAddressPrefix *[]string `json:"expandedSourceAddressPrefix,omitempty"` + ExpandedDestinationAddressPrefix *[]string `json:"expandedDestinationAddressPrefix,omitempty"` + Access SecurityRuleAccess `json:"access,omitempty"` + Priority *int32 `json:"priority,omitempty"` + Direction SecurityRuleDirection `json:"direction,omitempty"` +} + +// EffectiveRoute is effective Route +type EffectiveRoute struct { + Name *string `json:"name,omitempty"` + Source EffectiveRouteSource `json:"source,omitempty"` + State EffectiveRouteState `json:"state,omitempty"` + AddressPrefix *[]string `json:"addressPrefix,omitempty"` + NextHopIPAddress *[]string `json:"nextHopIpAddress,omitempty"` + NextHopType RouteNextHopType `json:"nextHopType,omitempty"` +} + +// EffectiveRouteListResult is response for list effective route api service +// call +type EffectiveRouteListResult struct { + autorest.Response `json:"-"` + Value *[]EffectiveRoute `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// Error is +type Error struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Target *string `json:"target,omitempty"` + Details *[]ErrorDetails `json:"details,omitempty"` + InnerError *string `json:"innerError,omitempty"` +} + +// ErrorDetails is +type ErrorDetails struct { + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// ExpressRouteCircuit is expressRouteCircuit resource +type ExpressRouteCircuit struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Sku *ExpressRouteCircuitSku `json:"sku,omitempty"` + Properties *ExpressRouteCircuitPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ExpressRouteCircuitArpTable is the arp table associated with the +// ExpressRouteCircuit +type ExpressRouteCircuitArpTable struct { + Age *int32 `json:"age,omitempty"` + Interface *string `json:"interface,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` + MacAddress *string `json:"macAddress,omitempty"` +} + +// ExpressRouteCircuitAuthorization is authorization in a ExpressRouteCircuit +// resource +type ExpressRouteCircuitAuthorization struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *AuthorizationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ExpressRouteCircuitListResult is response for ListExpressRouteCircuit Api +// service call +type ExpressRouteCircuitListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuit `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteCircuitListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ExpressRouteCircuitListResult) ExpressRouteCircuitListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ExpressRouteCircuitPeering is peering in a ExpressRouteCircuit resource +type ExpressRouteCircuitPeering struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *ExpressRouteCircuitPeeringPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ExpressRouteCircuitPeeringConfig is specifies the peering config +type ExpressRouteCircuitPeeringConfig struct { + AdvertisedPublicPrefixes *[]string `json:"advertisedPublicPrefixes,omitempty"` + AdvertisedPublicPrefixesState ExpressRouteCircuitPeeringAdvertisedPublicPrefixState `json:"advertisedPublicPrefixesState,omitempty"` + CustomerASN *int32 `json:"customerASN,omitempty"` + RoutingRegistryName *string `json:"routingRegistryName,omitempty"` +} + +// ExpressRouteCircuitPeeringListResult is response for ListPeering Api +// service callRetrieves all Peerings that belongs to an ExpressRouteCircuit +type ExpressRouteCircuitPeeringListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuitPeering `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteCircuitPeeringListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ExpressRouteCircuitPeeringListResult) ExpressRouteCircuitPeeringListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ExpressRouteCircuitPeeringPropertiesFormat is +type ExpressRouteCircuitPeeringPropertiesFormat struct { + PeeringType ExpressRouteCircuitPeeringType `json:"peeringType,omitempty"` + State ExpressRouteCircuitPeeringState `json:"state,omitempty"` + AzureASN *int32 `json:"azureASN,omitempty"` + PeerASN *int32 `json:"peerASN,omitempty"` + PrimaryPeerAddressPrefix *string `json:"primaryPeerAddressPrefix,omitempty"` + SecondaryPeerAddressPrefix *string `json:"secondaryPeerAddressPrefix,omitempty"` + PrimaryAzurePort *string `json:"primaryAzurePort,omitempty"` + SecondaryAzurePort *string `json:"secondaryAzurePort,omitempty"` + SharedKey *string `json:"sharedKey,omitempty"` + VlanID *int32 `json:"vlanId,omitempty"` + MicrosoftPeeringConfig *ExpressRouteCircuitPeeringConfig `json:"microsoftPeeringConfig,omitempty"` + Stats *ExpressRouteCircuitStats `json:"stats,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + GatewayManagerEtag *string `json:"gatewayManagerEtag,omitempty"` + LastModifiedBy *string `json:"lastModifiedBy,omitempty"` +} + +// ExpressRouteCircuitPropertiesFormat is properties of ExpressRouteCircuit +type ExpressRouteCircuitPropertiesFormat struct { + AllowClassicOperations *bool `json:"allowClassicOperations,omitempty"` + CircuitProvisioningState *string `json:"circuitProvisioningState,omitempty"` + ServiceProviderProvisioningState ServiceProviderProvisioningState `json:"serviceProviderProvisioningState,omitempty"` + Authorizations *[]ExpressRouteCircuitAuthorization `json:"authorizations,omitempty"` + Peerings *[]ExpressRouteCircuitPeering `json:"peerings,omitempty"` + ServiceKey *string `json:"serviceKey,omitempty"` + ServiceProviderNotes *string `json:"serviceProviderNotes,omitempty"` + ServiceProviderProperties *ExpressRouteCircuitServiceProviderProperties `json:"serviceProviderProperties,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + GatewayManagerEtag *string `json:"gatewayManagerEtag,omitempty"` +} + +// ExpressRouteCircuitRoutesTable is the routes table associated with the +// ExpressRouteCircuit +type ExpressRouteCircuitRoutesTable struct { + Network *string `json:"network,omitempty"` + NextHop *string `json:"nextHop,omitempty"` + LocPrf *string `json:"locPrf,omitempty"` + Weight *int32 `json:"weight,omitempty"` + Path *string `json:"path,omitempty"` +} + +// ExpressRouteCircuitRoutesTableSummary is the routes table associated with +// the ExpressRouteCircuit +type ExpressRouteCircuitRoutesTableSummary struct { + Neighbor *string `json:"neighbor,omitempty"` + V *int32 `json:"v,omitempty"` + As *int32 `json:"as,omitempty"` + UpDown *string `json:"upDown,omitempty"` + StatePfxRcd *string `json:"statePfxRcd,omitempty"` +} + +// ExpressRouteCircuitsArpTableListResult is response for ListArpTable +// associated with the Express Route Circuits Api +type ExpressRouteCircuitsArpTableListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuitArpTable `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteCircuitServiceProviderProperties is contains +// ServiceProviderProperties in an ExpressRouteCircuit +type ExpressRouteCircuitServiceProviderProperties struct { + ServiceProviderName *string `json:"serviceProviderName,omitempty"` + PeeringLocation *string `json:"peeringLocation,omitempty"` + BandwidthInMbps *int32 `json:"bandwidthInMbps,omitempty"` +} + +// ExpressRouteCircuitSku is contains sku in an ExpressRouteCircuit +type ExpressRouteCircuitSku struct { + Name *string `json:"name,omitempty"` + Tier ExpressRouteCircuitSkuTier `json:"tier,omitempty"` + Family ExpressRouteCircuitSkuFamily `json:"family,omitempty"` +} + +// ExpressRouteCircuitsRoutesTableListResult is response for ListRoutesTable +// associated with the Express Route Circuits Api +type ExpressRouteCircuitsRoutesTableListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuitRoutesTable `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteCircuitsRoutesTableSummaryListResult is response for +// ListRoutesTable associated with the Express Route Circuits Api +type ExpressRouteCircuitsRoutesTableSummaryListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuitRoutesTableSummary `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteCircuitStats is contains Stats associated with the peering +type ExpressRouteCircuitStats struct { + autorest.Response `json:"-"` + PrimarybytesIn *int64 `json:"primarybytesIn,omitempty"` + PrimarybytesOut *int64 `json:"primarybytesOut,omitempty"` + SecondarybytesIn *int64 `json:"secondarybytesIn,omitempty"` + SecondarybytesOut *int64 `json:"secondarybytesOut,omitempty"` +} + +// ExpressRouteServiceProvider is expressRouteResourceProvider object +type ExpressRouteServiceProvider struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *ExpressRouteServiceProviderPropertiesFormat `json:"properties,omitempty"` +} + +// ExpressRouteServiceProviderBandwidthsOffered is contains Bandwidths offered +// in ExpressRouteServiceProviders +type ExpressRouteServiceProviderBandwidthsOffered struct { + OfferName *string `json:"offerName,omitempty"` + ValueInMbps *int32 `json:"valueInMbps,omitempty"` +} + +// ExpressRouteServiceProviderListResult is response for +// ListExpressRouteServiceProvider Api service call +type ExpressRouteServiceProviderListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteServiceProvider `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteServiceProviderListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ExpressRouteServiceProviderListResult) ExpressRouteServiceProviderListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ExpressRouteServiceProviderPropertiesFormat is properties of +// ExpressRouteServiceProvider +type ExpressRouteServiceProviderPropertiesFormat struct { + PeeringLocations *[]string `json:"peeringLocations,omitempty"` + BandwidthsOffered *[]ExpressRouteServiceProviderBandwidthsOffered `json:"bandwidthsOffered,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// FrontendIPConfiguration is frontend IP address of the load balancer +type FrontendIPConfiguration struct { + ID *string `json:"id,omitempty"` + Properties *FrontendIPConfigurationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// FrontendIPConfigurationPropertiesFormat is properties of Frontend IP +// Configuration of the load balancer +type FrontendIPConfigurationPropertiesFormat struct { + InboundNatRules *[]SubResource `json:"inboundNatRules,omitempty"` + InboundNatPools *[]SubResource `json:"inboundNatPools,omitempty"` + OutboundNatRules *[]SubResource `json:"outboundNatRules,omitempty"` + LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"` + PrivateIPAddress *string `json:"privateIPAddress,omitempty"` + PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"` + Subnet *Subnet `json:"subnet,omitempty"` + PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// InboundNatPool is inbound NAT pool of the load balancer +type InboundNatPool struct { + ID *string `json:"id,omitempty"` + Properties *InboundNatPoolPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// InboundNatPoolPropertiesFormat is properties of Inbound NAT pool +type InboundNatPoolPropertiesFormat struct { + FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"` + Protocol TransportProtocol `json:"protocol,omitempty"` + FrontendPortRangeStart *int32 `json:"frontendPortRangeStart,omitempty"` + FrontendPortRangeEnd *int32 `json:"frontendPortRangeEnd,omitempty"` + BackendPort *int32 `json:"backendPort,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// InboundNatRule is inbound NAT rule of the loadbalancer +type InboundNatRule struct { + ID *string `json:"id,omitempty"` + Properties *InboundNatRulePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// InboundNatRulePropertiesFormat is properties of Inbound NAT rule +type InboundNatRulePropertiesFormat struct { + FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"` + BackendIPConfiguration *InterfaceIPConfiguration `json:"backendIPConfiguration,omitempty"` + Protocol TransportProtocol `json:"protocol,omitempty"` + FrontendPort *int32 `json:"frontendPort,omitempty"` + BackendPort *int32 `json:"backendPort,omitempty"` + IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"` + EnableFloatingIP *bool `json:"enableFloatingIP,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Interface is a NetworkInterface in a resource group +type Interface struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *InterfacePropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// InterfaceDNSSettings is dns settings of a network interface +type InterfaceDNSSettings struct { + DNSServers *[]string `json:"dnsServers,omitempty"` + AppliedDNSServers *[]string `json:"appliedDnsServers,omitempty"` + InternalDNSNameLabel *string `json:"internalDnsNameLabel,omitempty"` + InternalFqdn *string `json:"internalFqdn,omitempty"` + InternalDomainNameSuffix *string `json:"internalDomainNameSuffix,omitempty"` +} + +// InterfaceIPConfiguration is iPConfiguration in a NetworkInterface +type InterfaceIPConfiguration struct { + ID *string `json:"id,omitempty"` + Properties *InterfaceIPConfigurationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// InterfaceIPConfigurationPropertiesFormat is properties of IPConfiguration +type InterfaceIPConfigurationPropertiesFormat struct { + ApplicationGatewayBackendAddressPools *[]ApplicationGatewayBackendAddressPool `json:"applicationGatewayBackendAddressPools,omitempty"` + LoadBalancerBackendAddressPools *[]BackendAddressPool `json:"loadBalancerBackendAddressPools,omitempty"` + LoadBalancerInboundNatRules *[]InboundNatRule `json:"loadBalancerInboundNatRules,omitempty"` + PrivateIPAddress *string `json:"privateIPAddress,omitempty"` + PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"` + PrivateIPAddressVersion IPVersion `json:"privateIPAddressVersion,omitempty"` + Subnet *Subnet `json:"subnet,omitempty"` + Primary *bool `json:"primary,omitempty"` + PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// InterfaceListResult is response for ListNetworkInterface Api service call +type InterfaceListResult struct { + autorest.Response `json:"-"` + Value *[]Interface `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// InterfaceListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client InterfaceListResult) InterfaceListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// InterfacePropertiesFormat is networkInterface properties. +type InterfacePropertiesFormat struct { + VirtualMachine *SubResource `json:"virtualMachine,omitempty"` + NetworkSecurityGroup *SecurityGroup `json:"networkSecurityGroup,omitempty"` + IPConfigurations *[]InterfaceIPConfiguration `json:"ipConfigurations,omitempty"` + DNSSettings *InterfaceDNSSettings `json:"dnsSettings,omitempty"` + MacAddress *string `json:"macAddress,omitempty"` + Primary *bool `json:"primary,omitempty"` + AcceleratedNetworkingEnabled *bool `json:"acceleratedNetworkingEnabled,omitempty"` + EnableIPForwarding *bool `json:"enableIPForwarding,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// IPAddressAvailabilityResult is response for CheckIPAddressAvailability Api +// service call +type IPAddressAvailabilityResult struct { + autorest.Response `json:"-"` + Available *bool `json:"available,omitempty"` + AvailableIPAddresses *[]string `json:"availableIPAddresses,omitempty"` +} + +// IPConfiguration is iPConfiguration +type IPConfiguration struct { + ID *string `json:"id,omitempty"` + Properties *IPConfigurationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// IPConfigurationPropertiesFormat is properties of IPConfiguration +type IPConfigurationPropertiesFormat struct { + PrivateIPAddress *string `json:"privateIPAddress,omitempty"` + PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"` + Subnet *Subnet `json:"subnet,omitempty"` + PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// LoadBalancer is loadBalancer resource +type LoadBalancer struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *LoadBalancerPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// LoadBalancerListResult is response for ListLoadBalancers Api service call +type LoadBalancerListResult struct { + autorest.Response `json:"-"` + Value *[]LoadBalancer `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// LoadBalancerListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client LoadBalancerListResult) LoadBalancerListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// LoadBalancerPropertiesFormat is properties of Load Balancer +type LoadBalancerPropertiesFormat struct { + FrontendIPConfigurations *[]FrontendIPConfiguration `json:"frontendIPConfigurations,omitempty"` + BackendAddressPools *[]BackendAddressPool `json:"backendAddressPools,omitempty"` + LoadBalancingRules *[]LoadBalancingRule `json:"loadBalancingRules,omitempty"` + Probes *[]Probe `json:"probes,omitempty"` + InboundNatRules *[]InboundNatRule `json:"inboundNatRules,omitempty"` + InboundNatPools *[]InboundNatPool `json:"inboundNatPools,omitempty"` + OutboundNatRules *[]OutboundNatRule `json:"outboundNatRules,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// LoadBalancingRule is rules of the load balancer +type LoadBalancingRule struct { + ID *string `json:"id,omitempty"` + Properties *LoadBalancingRulePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// LoadBalancingRulePropertiesFormat is properties of the load balancer +type LoadBalancingRulePropertiesFormat struct { + FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"` + BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"` + Probe *SubResource `json:"probe,omitempty"` + Protocol TransportProtocol `json:"protocol,omitempty"` + LoadDistribution LoadDistribution `json:"loadDistribution,omitempty"` + FrontendPort *int32 `json:"frontendPort,omitempty"` + BackendPort *int32 `json:"backendPort,omitempty"` + IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"` + EnableFloatingIP *bool `json:"enableFloatingIP,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// LocalNetworkGateway is a common class for general resource information +type LocalNetworkGateway struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *LocalNetworkGatewayPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// LocalNetworkGatewayListResult is response for ListLocalNetworkGateways Api +// service call +type LocalNetworkGatewayListResult struct { + autorest.Response `json:"-"` + Value *[]LocalNetworkGateway `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// LocalNetworkGatewayListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client LocalNetworkGatewayListResult) LocalNetworkGatewayListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// LocalNetworkGatewayPropertiesFormat is localNetworkGateway properties +type LocalNetworkGatewayPropertiesFormat struct { + LocalNetworkAddressSpace *AddressSpace `json:"localNetworkAddressSpace,omitempty"` + GatewayIPAddress *string `json:"gatewayIpAddress,omitempty"` + BgpSettings *BgpSettings `json:"bgpSettings,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// OutboundNatRule is outbound NAT pool of the load balancer +type OutboundNatRule struct { + ID *string `json:"id,omitempty"` + Properties *OutboundNatRulePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// OutboundNatRulePropertiesFormat is outbound NAT pool of the load balancer +type OutboundNatRulePropertiesFormat struct { + AllocatedOutboundPorts *int32 `json:"allocatedOutboundPorts,omitempty"` + FrontendIPConfigurations *[]SubResource `json:"frontendIPConfigurations,omitempty"` + BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Probe is load balancer Probe +type Probe struct { + ID *string `json:"id,omitempty"` + Properties *ProbePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ProbePropertiesFormat is +type ProbePropertiesFormat struct { + LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"` + Protocol ProbeProtocol `json:"protocol,omitempty"` + Port *int32 `json:"port,omitempty"` + IntervalInSeconds *int32 `json:"intervalInSeconds,omitempty"` + NumberOfProbes *int32 `json:"numberOfProbes,omitempty"` + RequestPath *string `json:"requestPath,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// PublicIPAddress is publicIPAddress resource +type PublicIPAddress struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *PublicIPAddressPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// PublicIPAddressDNSSettings is contains FQDN of the DNS record associated +// with the public IP address +type PublicIPAddressDNSSettings struct { + DomainNameLabel *string `json:"domainNameLabel,omitempty"` + Fqdn *string `json:"fqdn,omitempty"` + ReverseFqdn *string `json:"reverseFqdn,omitempty"` +} + +// PublicIPAddressListResult is response for ListPublicIpAddresses Api service +// call +type PublicIPAddressListResult struct { + autorest.Response `json:"-"` + Value *[]PublicIPAddress `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// PublicIPAddressListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client PublicIPAddressListResult) PublicIPAddressListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// PublicIPAddressPropertiesFormat is publicIpAddress properties +type PublicIPAddressPropertiesFormat struct { + PublicIPAllocationMethod IPAllocationMethod `json:"publicIPAllocationMethod,omitempty"` + PublicIPAddressVersion IPVersion `json:"publicIPAddressVersion,omitempty"` + IPConfiguration *IPConfiguration `json:"ipConfiguration,omitempty"` + DNSSettings *PublicIPAddressDNSSettings `json:"dnsSettings,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` + IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Resource is +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceNavigationLink is resourceNavigationLink resource +type ResourceNavigationLink struct { + ID *string `json:"id,omitempty"` + Properties *ResourceNavigationLinkFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// ResourceNavigationLinkFormat is properties of ResourceNavigationLink +type ResourceNavigationLinkFormat struct { + LinkedResourceType *string `json:"linkedResourceType,omitempty"` + Link *string `json:"link,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Route is route resource +type Route struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *RoutePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// RouteListResult is response for ListRoute Api service call +type RouteListResult struct { + autorest.Response `json:"-"` + Value *[]Route `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// RouteListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client RouteListResult) RouteListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// RoutePropertiesFormat is route resource +type RoutePropertiesFormat struct { + AddressPrefix *string `json:"addressPrefix,omitempty"` + NextHopType RouteNextHopType `json:"nextHopType,omitempty"` + NextHopIPAddress *string `json:"nextHopIpAddress,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// RouteTable is routeTable resource +type RouteTable struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *RouteTablePropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// RouteTableListResult is response for ListRouteTable Api service call +type RouteTableListResult struct { + autorest.Response `json:"-"` + Value *[]RouteTable `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// RouteTableListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client RouteTableListResult) RouteTableListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// RouteTablePropertiesFormat is route Table resource +type RouteTablePropertiesFormat struct { + Routes *[]Route `json:"routes,omitempty"` + Subnets *[]Subnet `json:"subnets,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// SecurityGroup is networkSecurityGroup resource +type SecurityGroup struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SecurityGroupPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// SecurityGroupListResult is response for ListNetworkSecurityGroups Api +// service call +type SecurityGroupListResult struct { + autorest.Response `json:"-"` + Value *[]SecurityGroup `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SecurityGroupListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SecurityGroupListResult) SecurityGroupListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SecurityGroupPropertiesFormat is network Security Group resource +type SecurityGroupPropertiesFormat struct { + SecurityRules *[]SecurityRule `json:"securityRules,omitempty"` + DefaultSecurityRules *[]SecurityRule `json:"defaultSecurityRules,omitempty"` + NetworkInterfaces *[]Interface `json:"networkInterfaces,omitempty"` + Subnets *[]Subnet `json:"subnets,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// SecurityRule is network security rule +type SecurityRule struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *SecurityRulePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// SecurityRuleListResult is response for ListSecurityRule Api service +// callRetrieves all security rules that belongs to a network security group +type SecurityRuleListResult struct { + autorest.Response `json:"-"` + Value *[]SecurityRule `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SecurityRuleListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SecurityRuleListResult) SecurityRuleListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SecurityRulePropertiesFormat is +type SecurityRulePropertiesFormat struct { + Description *string `json:"description,omitempty"` + Protocol SecurityRuleProtocol `json:"protocol,omitempty"` + SourcePortRange *string `json:"sourcePortRange,omitempty"` + DestinationPortRange *string `json:"destinationPortRange,omitempty"` + SourceAddressPrefix *string `json:"sourceAddressPrefix,omitempty"` + DestinationAddressPrefix *string `json:"destinationAddressPrefix,omitempty"` + Access SecurityRuleAccess `json:"access,omitempty"` + Priority *int32 `json:"priority,omitempty"` + Direction SecurityRuleDirection `json:"direction,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// String is +type String struct { + autorest.Response `json:"-"` + Value *string `json:"value,omitempty"` +} + +// Subnet is subnet in a VirtualNework resource +type Subnet struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *SubnetPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// SubnetListResult is response for ListSubnets Api service callRetrieves all +// subnet that belongs to a virtual network +type SubnetListResult struct { + autorest.Response `json:"-"` + Value *[]Subnet `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SubnetListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SubnetListResult) SubnetListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SubnetPropertiesFormat is +type SubnetPropertiesFormat struct { + AddressPrefix *string `json:"addressPrefix,omitempty"` + NetworkSecurityGroup *SecurityGroup `json:"networkSecurityGroup,omitempty"` + RouteTable *RouteTable `json:"routeTable,omitempty"` + IPConfigurations *[]IPConfiguration `json:"ipConfigurations,omitempty"` + ResourceNavigationLinks *[]ResourceNavigationLink `json:"resourceNavigationLinks,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// SubResource is +type SubResource struct { + ID *string `json:"id,omitempty"` +} + +// Usage is describes Network Resource Usage. +type Usage struct { + Unit *string `json:"unit,omitempty"` + CurrentValue *int64 `json:"currentValue,omitempty"` + Limit *int64 `json:"limit,omitempty"` + Name *UsageName `json:"name,omitempty"` +} + +// UsageName is the Usage Names. +type UsageName struct { + Value *string `json:"value,omitempty"` + LocalizedValue *string `json:"localizedValue,omitempty"` +} + +// UsagesListResult is the List Usages operation response. +type UsagesListResult struct { + autorest.Response `json:"-"` + Value *[]Usage `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// UsagesListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client UsagesListResult) UsagesListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualNetwork is virtual Network resource +type VirtualNetwork struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VirtualNetworkPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VirtualNetworkGateway is a common class for general resource information +type VirtualNetworkGateway struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VirtualNetworkGatewayPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VirtualNetworkGatewayConnection is a common class for general resource +// information +type VirtualNetworkGatewayConnection struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VirtualNetworkGatewayConnectionPropertiesFormat `json:"properties,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VirtualNetworkGatewayConnectionListResult is response for +// ListVirtualNetworkGatewayConnections Api service call +type VirtualNetworkGatewayConnectionListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualNetworkGatewayConnection `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualNetworkGatewayConnectionListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualNetworkGatewayConnectionListResult) VirtualNetworkGatewayConnectionListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualNetworkGatewayConnectionPropertiesFormat is +// virtualNetworkGatewayConnection properties +type VirtualNetworkGatewayConnectionPropertiesFormat struct { + AuthorizationKey *string `json:"authorizationKey,omitempty"` + VirtualNetworkGateway1 *VirtualNetworkGateway `json:"virtualNetworkGateway1,omitempty"` + VirtualNetworkGateway2 *VirtualNetworkGateway `json:"virtualNetworkGateway2,omitempty"` + LocalNetworkGateway2 *LocalNetworkGateway `json:"localNetworkGateway2,omitempty"` + ConnectionType VirtualNetworkGatewayConnectionType `json:"connectionType,omitempty"` + RoutingWeight *int32 `json:"routingWeight,omitempty"` + SharedKey *string `json:"sharedKey,omitempty"` + ConnectionStatus VirtualNetworkGatewayConnectionStatus `json:"connectionStatus,omitempty"` + EgressBytesTransferred *int64 `json:"egressBytesTransferred,omitempty"` + IngressBytesTransferred *int64 `json:"ingressBytesTransferred,omitempty"` + Peer *SubResource `json:"peer,omitempty"` + EnableBgp *bool `json:"enableBgp,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VirtualNetworkGatewayIPConfiguration is ipConfiguration for Virtual network +// gateway +type VirtualNetworkGatewayIPConfiguration struct { + ID *string `json:"id,omitempty"` + Properties *VirtualNetworkGatewayIPConfigurationPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VirtualNetworkGatewayIPConfigurationPropertiesFormat is properties of +// VirtualNetworkGatewayIPConfiguration +type VirtualNetworkGatewayIPConfigurationPropertiesFormat struct { + PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"` + Subnet *SubResource `json:"subnet,omitempty"` + PublicIPAddress *SubResource `json:"publicIPAddress,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VirtualNetworkGatewayListResult is response for ListVirtualNetworkGateways +// Api service call +type VirtualNetworkGatewayListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualNetworkGateway `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualNetworkGatewayListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualNetworkGatewayListResult) VirtualNetworkGatewayListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualNetworkGatewayPropertiesFormat is virtualNetworkGateway properties +type VirtualNetworkGatewayPropertiesFormat struct { + IPConfigurations *[]VirtualNetworkGatewayIPConfiguration `json:"ipConfigurations,omitempty"` + GatewayType VirtualNetworkGatewayType `json:"gatewayType,omitempty"` + VpnType VpnType `json:"vpnType,omitempty"` + EnableBgp *bool `json:"enableBgp,omitempty"` + ActiveActive *bool `json:"activeActive,omitempty"` + GatewayDefaultSite *SubResource `json:"gatewayDefaultSite,omitempty"` + Sku *VirtualNetworkGatewaySku `json:"sku,omitempty"` + VpnClientConfiguration *VpnClientConfiguration `json:"vpnClientConfiguration,omitempty"` + BgpSettings *BgpSettings `json:"bgpSettings,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VirtualNetworkGatewaySku is virtualNetworkGatewaySku details +type VirtualNetworkGatewaySku struct { + Name VirtualNetworkGatewaySkuName `json:"name,omitempty"` + Tier VirtualNetworkGatewaySkuTier `json:"tier,omitempty"` + Capacity *int32 `json:"capacity,omitempty"` +} + +// VirtualNetworkListResult is response for ListVirtualNetworks Api service +// call +type VirtualNetworkListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualNetwork `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualNetworkListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualNetworkListResult) VirtualNetworkListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualNetworkPeering is peerings in a VirtualNework resource +type VirtualNetworkPeering struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Properties *VirtualNetworkPeeringPropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VirtualNetworkPeeringListResult is response for ListSubnets Api service +// callRetrieves all subnet that belongs to a virtual network +type VirtualNetworkPeeringListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualNetworkPeering `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualNetworkPeeringListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VirtualNetworkPeeringListResult) VirtualNetworkPeeringListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// VirtualNetworkPeeringPropertiesFormat is +type VirtualNetworkPeeringPropertiesFormat struct { + AllowVirtualNetworkAccess *bool `json:"allowVirtualNetworkAccess,omitempty"` + AllowForwardedTraffic *bool `json:"allowForwardedTraffic,omitempty"` + AllowGatewayTransit *bool `json:"allowGatewayTransit,omitempty"` + UseRemoteGateways *bool `json:"useRemoteGateways,omitempty"` + RemoteVirtualNetwork *SubResource `json:"remoteVirtualNetwork,omitempty"` + PeeringState VirtualNetworkPeeringState `json:"peeringState,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VirtualNetworkPropertiesFormat is +type VirtualNetworkPropertiesFormat struct { + AddressSpace *AddressSpace `json:"addressSpace,omitempty"` + DhcpOptions *DhcpOptions `json:"dhcpOptions,omitempty"` + Subnets *[]Subnet `json:"subnets,omitempty"` + VirtualNetworkPeerings *[]VirtualNetworkPeering `json:"VirtualNetworkPeerings,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VpnClientConfiguration is vpnClientConfiguration for P2S client +type VpnClientConfiguration struct { + VpnClientAddressPool *AddressSpace `json:"vpnClientAddressPool,omitempty"` + VpnClientRootCertificates *[]VpnClientRootCertificate `json:"vpnClientRootCertificates,omitempty"` + VpnClientRevokedCertificates *[]VpnClientRevokedCertificate `json:"vpnClientRevokedCertificates,omitempty"` +} + +// VpnClientParameters is vpnClientParameters +type VpnClientParameters struct { + ProcessorArchitecture ProcessorArchitecture `json:"ProcessorArchitecture,omitempty"` +} + +// VpnClientRevokedCertificate is vPN client revoked certificate of virtual +// network gateway +type VpnClientRevokedCertificate struct { + ID *string `json:"id,omitempty"` + Properties *VpnClientRevokedCertificatePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VpnClientRevokedCertificatePropertiesFormat is properties of the revoked +// VPN client certificate of virtual network gateway +type VpnClientRevokedCertificatePropertiesFormat struct { + Thumbprint *string `json:"thumbprint,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// VpnClientRootCertificate is vPN client root certificate of virtual network +// gateway +type VpnClientRootCertificate struct { + ID *string `json:"id,omitempty"` + Properties *VpnClientRootCertificatePropertiesFormat `json:"properties,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +// VpnClientRootCertificatePropertiesFormat is properties of SSL certificates +// of application gateway +type VpnClientRootCertificatePropertiesFormat struct { + PublicCertData *string `json:"publicCertData,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go new file mode 100644 index 0000000000..40bf7cc569 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go @@ -0,0 +1,448 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// PublicIPAddressesClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type PublicIPAddressesClient struct { + ManagementClient +} + +// NewPublicIPAddressesClient creates an instance of the +// PublicIPAddressesClient client. +func NewPublicIPAddressesClient(subscriptionID string) PublicIPAddressesClient { + return NewPublicIPAddressesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewPublicIPAddressesClientWithBaseURI creates an instance of the +// PublicIPAddressesClient client. +func NewPublicIPAddressesClientWithBaseURI(baseURI string, subscriptionID string) PublicIPAddressesClient { + return PublicIPAddressesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put PublicIPAddress operation creates/updates a +// stable/dynamic PublicIP address This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The +// channel will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. publicIPAddressName is +// the name of the publicIpAddress. parameters is parameters supplied to the +// create/update PublicIPAddress operation +func (client PublicIPAddressesClient) CreateOrUpdate(resourceGroupName string, publicIPAddressName string, parameters PublicIPAddress, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.NetworkSecurityGroup", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.NetworkSecurityGroup.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.NetworkSecurityGroup.Properties.NetworkInterfaces", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.NetworkSecurityGroup.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}, + }}, + {Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.RouteTable", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.RouteTable.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.RouteTable.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}}}, + }}, + {Target: "parameters.Properties.IPConfiguration.Properties.Subnet.Properties.IPConfigurations", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}, + }}, + {Target: "parameters.Properties.IPConfiguration.Properties.PublicIPAddress", Name: validation.Null, Rule: false, Chain: nil}, + }}, + }}, + {Target: "parameters.Properties.IPConfiguration", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.PublicIPAddressesClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, publicIPAddressName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client PublicIPAddressesClient) CreateOrUpdatePreparer(resourceGroupName string, publicIPAddressName string, parameters PublicIPAddress, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "publicIpAddressName": autorest.Encode("path", publicIPAddressName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPAddresses/{publicIpAddressName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client PublicIPAddressesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client PublicIPAddressesClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete publicIpAddress operation deletes the specified +// publicIpAddress. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. publicIPAddressName is +// the name of the subnet. +func (client PublicIPAddressesClient) Delete(resourceGroupName string, publicIPAddressName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, publicIPAddressName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client PublicIPAddressesClient) DeletePreparer(resourceGroupName string, publicIPAddressName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "publicIpAddressName": autorest.Encode("path", publicIPAddressName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPAddresses/{publicIpAddressName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client PublicIPAddressesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client PublicIPAddressesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get publicIpAddress operation retrieves information about the +// specified pubicIpAddress +// +// resourceGroupName is the name of the resource group. publicIPAddressName is +// the name of the subnet. expand is expand references resources. +func (client PublicIPAddressesClient) Get(resourceGroupName string, publicIPAddressName string, expand string) (result PublicIPAddress, err error) { + req, err := client.GetPreparer(resourceGroupName, publicIPAddressName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client PublicIPAddressesClient) GetPreparer(resourceGroupName string, publicIPAddressName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "publicIpAddressName": autorest.Encode("path", publicIPAddressName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPAddresses/{publicIpAddressName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client PublicIPAddressesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client PublicIPAddressesClient) GetResponder(resp *http.Response) (result PublicIPAddress, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List publicIpAddress operation retrieves all the publicIpAddresses +// in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client PublicIPAddressesClient) List(resourceGroupName string) (result PublicIPAddressListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client PublicIPAddressesClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPAddresses", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client PublicIPAddressesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client PublicIPAddressesClient) ListResponder(resp *http.Response) (result PublicIPAddressListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client PublicIPAddressesClient) ListNextResults(lastResults PublicIPAddressListResult) (result PublicIPAddressListResult, err error) { + req, err := lastResults.PublicIPAddressListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the List publicIpAddress operation retrieves all the +// publicIpAddresses in a subscription. +func (client PublicIPAddressesClient) ListAll() (result PublicIPAddressListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client PublicIPAddressesClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/publicIPAddresses", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client PublicIPAddressesClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client PublicIPAddressesClient) ListAllResponder(resp *http.Response) (result PublicIPAddressListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client PublicIPAddressesClient) ListAllNextResults(lastResults PublicIPAddressListResult) (result PublicIPAddressListResult, err error) { + req, err := lastResults.PublicIPAddressListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/routes.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/routes.go new file mode 100644 index 0000000000..fd0c681789 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/routes.go @@ -0,0 +1,337 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// RoutesClient is the the Microsoft Azure Network management API provides a +// RESTful set of web services that interact with Microsoft Azure Networks +// service to manage your network resources. The API has entities that +// capture the relationship between an end user and the Microsoft Azure +// Networks service. +type RoutesClient struct { + ManagementClient +} + +// NewRoutesClient creates an instance of the RoutesClient client. +func NewRoutesClient(subscriptionID string) RoutesClient { + return NewRoutesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewRoutesClientWithBaseURI creates an instance of the RoutesClient client. +func NewRoutesClientWithBaseURI(baseURI string, subscriptionID string) RoutesClient { + return RoutesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put route operation creates/updates a route in the +// specified route table This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. routeName is the name of the route. +// routeParameters is parameters supplied to the create/update route +// operation +func (client RoutesClient) CreateOrUpdate(resourceGroupName string, routeTableName string, routeName string, routeParameters Route, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, routeTableName, routeName, routeParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RoutesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RoutesClient) CreateOrUpdatePreparer(resourceGroupName string, routeTableName string, routeName string, routeParameters Route, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeName": autorest.Encode("path", routeName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes/{routeName}", pathParameters), + autorest.WithJSON(routeParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client RoutesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RoutesClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete route operation deletes the specified route from a route +// table. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. routeName is the name of the route. +func (client RoutesClient) Delete(resourceGroupName string, routeTableName string, routeName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, routeTableName, routeName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RoutesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RoutesClient) DeletePreparer(resourceGroupName string, routeTableName string, routeName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeName": autorest.Encode("path", routeName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes/{routeName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client RoutesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client RoutesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get route operation retrieves information about the specified route +// from the route table. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. routeName is the name of the route. +func (client RoutesClient) Get(resourceGroupName string, routeTableName string, routeName string) (result Route, err error) { + req, err := client.GetPreparer(resourceGroupName, routeTableName, routeName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RoutesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RoutesClient) GetPreparer(resourceGroupName string, routeTableName string, routeName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeName": autorest.Encode("path", routeName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes/{routeName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client RoutesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client RoutesClient) GetResponder(resp *http.Response) (result Route, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List network security rule operation retrieves all the routes in a +// route table. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. +func (client RoutesClient) List(resourceGroupName string, routeTableName string) (result RouteListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, routeTableName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RoutesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client RoutesClient) ListPreparer(resourceGroupName string, routeTableName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client RoutesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client RoutesClient) ListResponder(resp *http.Response) (result RouteListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client RoutesClient) ListNextResults(lastResults RouteListResult) (result RouteListResult, err error) { + req, err := lastResults.RouteListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RoutesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RoutesClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go new file mode 100644 index 0000000000..81e5a0e996 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go @@ -0,0 +1,424 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// RouteTablesClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type RouteTablesClient struct { + ManagementClient +} + +// NewRouteTablesClient creates an instance of the RouteTablesClient client. +func NewRouteTablesClient(subscriptionID string) RouteTablesClient { + return NewRouteTablesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewRouteTablesClientWithBaseURI creates an instance of the +// RouteTablesClient client. +func NewRouteTablesClientWithBaseURI(baseURI string, subscriptionID string) RouteTablesClient { + return RouteTablesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put RouteTable operation creates/updates a route table +// in the specified resource group. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The +// channel will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. parameters is parameters supplied to the +// create/update Route Table operation +func (client RouteTablesClient) CreateOrUpdate(resourceGroupName string, routeTableName string, parameters RouteTable, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.RouteTablesClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, routeTableName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RouteTablesClient) CreateOrUpdatePreparer(resourceGroupName string, routeTableName string, parameters RouteTable, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client RouteTablesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RouteTablesClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the Delete RouteTable operation deletes the specified Route Table +// This method may poll for completion. Polling can be canceled by passing +// the cancel channel argument. The channel will be used to cancel polling +// and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. +func (client RouteTablesClient) Delete(resourceGroupName string, routeTableName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, routeTableName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RouteTablesClient) DeletePreparer(resourceGroupName string, routeTableName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client RouteTablesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client RouteTablesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get RouteTables operation retrieves information about the specified +// route table. +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. expand is expand references resources. +func (client RouteTablesClient) Get(resourceGroupName string, routeTableName string, expand string) (result RouteTable, err error) { + req, err := client.GetPreparer(resourceGroupName, routeTableName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RouteTablesClient) GetPreparer(resourceGroupName string, routeTableName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "routeTableName": autorest.Encode("path", routeTableName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client RouteTablesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client RouteTablesClient) GetResponder(resp *http.Response) (result RouteTable, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the list RouteTables returns all route tables in a resource group +// +// resourceGroupName is the name of the resource group. +func (client RouteTablesClient) List(resourceGroupName string) (result RouteTableListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client RouteTablesClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client RouteTablesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client RouteTablesClient) ListResponder(resp *http.Response) (result RouteTableListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client RouteTablesClient) ListNextResults(lastResults RouteTableListResult) (result RouteTableListResult, err error) { + req, err := lastResults.RouteTableListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the list RouteTables returns all route tables in a subscription +func (client RouteTablesClient) ListAll() (result RouteTableListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client RouteTablesClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/routeTables", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client RouteTablesClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client RouteTablesClient) ListAllResponder(resp *http.Response) (result RouteTableListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client RouteTablesClient) ListAllNextResults(lastResults RouteTableListResult) (result RouteTableListResult, err error) { + req, err := lastResults.RouteTableListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.RouteTablesClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.RouteTablesClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go new file mode 100644 index 0000000000..187ca8b981 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go @@ -0,0 +1,432 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SecurityGroupsClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type SecurityGroupsClient struct { + ManagementClient +} + +// NewSecurityGroupsClient creates an instance of the SecurityGroupsClient +// client. +func NewSecurityGroupsClient(subscriptionID string) SecurityGroupsClient { + return NewSecurityGroupsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSecurityGroupsClientWithBaseURI creates an instance of the +// SecurityGroupsClient client. +func NewSecurityGroupsClientWithBaseURI(baseURI string, subscriptionID string) SecurityGroupsClient { + return SecurityGroupsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put NetworkSecurityGroup operation creates/updates a +// network security group in the specified resource group. This method may +// poll for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. +// parameters is parameters supplied to the create/update Network Security +// Group operation +func (client SecurityGroupsClient) CreateOrUpdate(resourceGroupName string, networkSecurityGroupName string, parameters SecurityGroup, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.NetworkInterfaces", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "parameters.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.SecurityGroupsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, networkSecurityGroupName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SecurityGroupsClient) CreateOrUpdatePreparer(resourceGroupName string, networkSecurityGroupName string, parameters SecurityGroup, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityGroupsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client SecurityGroupsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the Delete NetworkSecurityGroup operation deletes the specified +// network security group This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. +func (client SecurityGroupsClient) Delete(resourceGroupName string, networkSecurityGroupName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, networkSecurityGroupName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client SecurityGroupsClient) DeletePreparer(resourceGroupName string, networkSecurityGroupName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityGroupsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client SecurityGroupsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get NetworkSecurityGroups operation retrieves information about the +// specified network security group. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. expand +// is expand references resources. +func (client SecurityGroupsClient) Get(resourceGroupName string, networkSecurityGroupName string, expand string) (result SecurityGroup, err error) { + req, err := client.GetPreparer(resourceGroupName, networkSecurityGroupName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SecurityGroupsClient) GetPreparer(resourceGroupName string, networkSecurityGroupName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityGroupsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SecurityGroupsClient) GetResponder(resp *http.Response) (result SecurityGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the list NetworkSecurityGroups returns all network security groups in +// a resource group +// +// resourceGroupName is the name of the resource group. +func (client SecurityGroupsClient) List(resourceGroupName string) (result SecurityGroupListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SecurityGroupsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityGroupsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SecurityGroupsClient) ListResponder(resp *http.Response) (result SecurityGroupListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client SecurityGroupsClient) ListNextResults(lastResults SecurityGroupListResult) (result SecurityGroupListResult, err error) { + req, err := lastResults.SecurityGroupListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the list NetworkSecurityGroups returns all network security groups +// in a subscription +func (client SecurityGroupsClient) ListAll() (result SecurityGroupListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client SecurityGroupsClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/networkSecurityGroups", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityGroupsClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client SecurityGroupsClient) ListAllResponder(resp *http.Response) (result SecurityGroupListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client SecurityGroupsClient) ListAllNextResults(lastResults SecurityGroupListResult) (result SecurityGroupListResult, err error) { + req, err := lastResults.SecurityGroupListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityGroupsClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go new file mode 100644 index 0000000000..c5ed15e557 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go @@ -0,0 +1,353 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SecurityRulesClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type SecurityRulesClient struct { + ManagementClient +} + +// NewSecurityRulesClient creates an instance of the SecurityRulesClient +// client. +func NewSecurityRulesClient(subscriptionID string) SecurityRulesClient { + return NewSecurityRulesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSecurityRulesClientWithBaseURI creates an instance of the +// SecurityRulesClient client. +func NewSecurityRulesClientWithBaseURI(baseURI string, subscriptionID string) SecurityRulesClient { + return SecurityRulesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put network security rule operation creates/updates a +// security rule in the specified network security group This method may poll +// for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. +// securityRuleName is the name of the security rule. securityRuleParameters +// is parameters supplied to the create/update network security rule +// operation +func (client SecurityRulesClient) CreateOrUpdate(resourceGroupName string, networkSecurityGroupName string, securityRuleName string, securityRuleParameters SecurityRule, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: securityRuleParameters, + Constraints: []validation.Constraint{{Target: "securityRuleParameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "securityRuleParameters.Properties.SourceAddressPrefix", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "securityRuleParameters.Properties.DestinationAddressPrefix", Name: validation.Null, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.SecurityRulesClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, networkSecurityGroupName, securityRuleName, securityRuleParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityRulesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SecurityRulesClient) CreateOrUpdatePreparer(resourceGroupName string, networkSecurityGroupName string, securityRuleName string, securityRuleParameters SecurityRule, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "securityRuleName": autorest.Encode("path", securityRuleName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}/securityRules/{securityRuleName}", pathParameters), + autorest.WithJSON(securityRuleParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityRulesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client SecurityRulesClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete network security rule operation deletes the specified +// network security rule. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. +// securityRuleName is the name of the security rule. +func (client SecurityRulesClient) Delete(resourceGroupName string, networkSecurityGroupName string, securityRuleName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, networkSecurityGroupName, securityRuleName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityRulesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client SecurityRulesClient) DeletePreparer(resourceGroupName string, networkSecurityGroupName string, securityRuleName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "securityRuleName": autorest.Encode("path", securityRuleName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}/securityRules/{securityRuleName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityRulesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client SecurityRulesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get NetworkSecurityRule operation retrieves information about the +// specified network security rule. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. +// securityRuleName is the name of the security rule. +func (client SecurityRulesClient) Get(resourceGroupName string, networkSecurityGroupName string, securityRuleName string) (result SecurityRule, err error) { + req, err := client.GetPreparer(resourceGroupName, networkSecurityGroupName, securityRuleName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityRulesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SecurityRulesClient) GetPreparer(resourceGroupName string, networkSecurityGroupName string, securityRuleName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "securityRuleName": autorest.Encode("path", securityRuleName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}/securityRules/{securityRuleName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityRulesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SecurityRulesClient) GetResponder(resp *http.Response) (result SecurityRule, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List network security rule operation retrieves all the security +// rules in a network security group. +// +// resourceGroupName is the name of the resource group. +// networkSecurityGroupName is the name of the network security group. +func (client SecurityRulesClient) List(resourceGroupName string, networkSecurityGroupName string) (result SecurityRuleListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, networkSecurityGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityRulesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SecurityRulesClient) ListPreparer(resourceGroupName string, networkSecurityGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkSecurityGroupName": autorest.Encode("path", networkSecurityGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}/securityRules", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SecurityRulesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SecurityRulesClient) ListResponder(resp *http.Response) (result SecurityRuleListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client SecurityRulesClient) ListNextResults(lastResults SecurityRuleListResult) (result SecurityRuleListResult, err error) { + req, err := lastResults.SecurityRuleListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SecurityRulesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SecurityRulesClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go new file mode 100644 index 0000000000..3e27f4849c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go @@ -0,0 +1,360 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SubnetsClient is the the Microsoft Azure Network management API provides a +// RESTful set of web services that interact with Microsoft Azure Networks +// service to manage your network resources. The API has entities that +// capture the relationship between an end user and the Microsoft Azure +// Networks service. +type SubnetsClient struct { + ManagementClient +} + +// NewSubnetsClient creates an instance of the SubnetsClient client. +func NewSubnetsClient(subscriptionID string) SubnetsClient { + return NewSubnetsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSubnetsClientWithBaseURI creates an instance of the SubnetsClient client. +func NewSubnetsClientWithBaseURI(baseURI string, subscriptionID string) SubnetsClient { + return SubnetsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put Subnet operation creates/updates a subnet in the +// specified virtual network This method may poll for completion. Polling can +// be canceled by passing the cancel channel argument. The channel will be +// used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. subnetName is the name of the subnet. +// subnetParameters is parameters supplied to the create/update Subnet +// operation +func (client SubnetsClient) CreateOrUpdate(resourceGroupName string, virtualNetworkName string, subnetName string, subnetParameters Subnet, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: subnetParameters, + Constraints: []validation.Constraint{{Target: "subnetParameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "subnetParameters.Properties.NetworkSecurityGroup", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "subnetParameters.Properties.NetworkSecurityGroup.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "subnetParameters.Properties.NetworkSecurityGroup.Properties.NetworkInterfaces", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "subnetParameters.Properties.NetworkSecurityGroup.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}, + }}, + {Target: "subnetParameters.Properties.RouteTable", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "subnetParameters.Properties.RouteTable.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "subnetParameters.Properties.RouteTable.Properties.Subnets", Name: validation.ReadOnly, Rule: true, Chain: nil}}}, + }}, + {Target: "subnetParameters.Properties.IPConfigurations", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.SubnetsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, virtualNetworkName, subnetName, subnetParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SubnetsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SubnetsClient) CreateOrUpdatePreparer(resourceGroupName string, virtualNetworkName string, subnetName string, subnetParameters Subnet, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subnetName": autorest.Encode("path", subnetName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName}", pathParameters), + autorest.WithJSON(subnetParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client SubnetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client SubnetsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete subnet operation deletes the specified subnet. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. subnetName is the name of the subnet. +func (client SubnetsClient) Delete(resourceGroupName string, virtualNetworkName string, subnetName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, virtualNetworkName, subnetName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SubnetsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client SubnetsClient) DeletePreparer(resourceGroupName string, virtualNetworkName string, subnetName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subnetName": autorest.Encode("path", subnetName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client SubnetsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client SubnetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get subnet operation retrieves information about the specified +// subnet. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. subnetName is the name of the subnet. +// expand is expand references resources. +func (client SubnetsClient) Get(resourceGroupName string, virtualNetworkName string, subnetName string, expand string) (result Subnet, err error) { + req, err := client.GetPreparer(resourceGroupName, virtualNetworkName, subnetName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SubnetsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SubnetsClient) GetPreparer(resourceGroupName string, virtualNetworkName string, subnetName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subnetName": autorest.Encode("path", subnetName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SubnetsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SubnetsClient) GetResponder(resp *http.Response) (result Subnet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List subnets operation retrieves all the subnets in a virtual +// network. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. +func (client SubnetsClient) List(resourceGroupName string, virtualNetworkName string) (result SubnetListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, virtualNetworkName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SubnetsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SubnetsClient) ListPreparer(resourceGroupName string, virtualNetworkName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SubnetsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SubnetsClient) ListResponder(resp *http.Response) (result SubnetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client SubnetsClient) ListNextResults(lastResults SubnetListResult) (result SubnetListResult, err error) { + req, err := lastResults.SubnetListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.SubnetsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.SubnetsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/usages.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/usages.go new file mode 100644 index 0000000000..8c246fecac --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/usages.go @@ -0,0 +1,136 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// UsagesClient is the the Microsoft Azure Network management API provides a +// RESTful set of web services that interact with Microsoft Azure Networks +// service to manage your network resources. The API has entities that +// capture the relationship between an end user and the Microsoft Azure +// Networks service. +type UsagesClient struct { + ManagementClient +} + +// NewUsagesClient creates an instance of the UsagesClient client. +func NewUsagesClient(subscriptionID string) UsagesClient { + return NewUsagesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewUsagesClientWithBaseURI creates an instance of the UsagesClient client. +func NewUsagesClientWithBaseURI(baseURI string, subscriptionID string) UsagesClient { + return UsagesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List lists compute usages for a subscription. +// +// location is the location upon which resource usage is queried. +func (client UsagesClient) List(location string) (result UsagesListResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: location, + Constraints: []validation.Constraint{{Target: "location", Name: validation.Pattern, Rule: `^[-\w\._]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "network.UsagesClient", "List") + } + + req, err := client.ListPreparer(location) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.UsagesClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.UsagesClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.UsagesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client UsagesClient) ListPreparer(location string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "location": autorest.Encode("path", location), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/locations/{location}/usages", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client UsagesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client UsagesClient) ListResponder(resp *http.Response) (result UsagesListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client UsagesClient) ListNextResults(lastResults UsagesListResult) (result UsagesListResult, err error) { + req, err := lastResults.UsagesListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.UsagesClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.UsagesClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.UsagesClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/version.go new file mode 100644 index 0000000000..aab274aea5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/version.go @@ -0,0 +1,43 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "5" + minor = "0" + patch = "0" + // Always begin a "tag" with a dash (as per http://semver.org) + tag = "-beta" + semVerFormat = "%s.%s.%s%s" + userAgentFormat = "Azure-SDK-for-Go/%s arm-%s/%s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "network", "2016-09-01") +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go new file mode 100644 index 0000000000..a7feb8fe26 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go @@ -0,0 +1,555 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualNetworkGatewayConnectionsClient is the the Microsoft Azure Network +// management API provides a RESTful set of web services that interact with +// Microsoft Azure Networks service to manage your network resources. The API +// has entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type VirtualNetworkGatewayConnectionsClient struct { + ManagementClient +} + +// NewVirtualNetworkGatewayConnectionsClient creates an instance of the +// VirtualNetworkGatewayConnectionsClient client. +func NewVirtualNetworkGatewayConnectionsClient(subscriptionID string) VirtualNetworkGatewayConnectionsClient { + return NewVirtualNetworkGatewayConnectionsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualNetworkGatewayConnectionsClientWithBaseURI creates an instance of +// the VirtualNetworkGatewayConnectionsClient client. +func NewVirtualNetworkGatewayConnectionsClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworkGatewayConnectionsClient { + return VirtualNetworkGatewayConnectionsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put VirtualNetworkGatewayConnection operation +// creates/updates a virtual network gateway connection in the specified +// resource group through Network resource provider. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayConnectionName is the name of the virtual network +// gateway connection. parameters is parameters supplied to the Begin Create +// or update Virtual Network Gateway connection operation through Network +// resource provider. +func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdate(resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters VirtualNetworkGatewayConnection, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, virtualNetworkGatewayConnectionName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdatePreparer(resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters VirtualNetworkGatewayConnection, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayConnectionName": autorest.Encode("path", virtualNetworkGatewayConnectionName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{virtualNetworkGatewayConnectionName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the Delete VirtualNetworkGatewayConnection operation deletes the +// specified virtual network Gateway connection through Network resource +// provider. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayConnectionName is the name of the virtual network +// gateway connection. +func (client VirtualNetworkGatewayConnectionsClient) Delete(resourceGroupName string, virtualNetworkGatewayConnectionName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, virtualNetworkGatewayConnectionName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualNetworkGatewayConnectionsClient) DeletePreparer(resourceGroupName string, virtualNetworkGatewayConnectionName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayConnectionName": autorest.Encode("path", virtualNetworkGatewayConnectionName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{virtualNetworkGatewayConnectionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get VirtualNetworkGatewayConnection operation retrieves information +// about the specified virtual network gateway connection through Network +// resource provider. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayConnectionName is the name of the virtual network +// gateway connection. +func (client VirtualNetworkGatewayConnectionsClient) Get(resourceGroupName string, virtualNetworkGatewayConnectionName string) (result VirtualNetworkGatewayConnection, err error) { + req, err := client.GetPreparer(resourceGroupName, virtualNetworkGatewayConnectionName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualNetworkGatewayConnectionsClient) GetPreparer(resourceGroupName string, virtualNetworkGatewayConnectionName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayConnectionName": autorest.Encode("path", virtualNetworkGatewayConnectionName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{virtualNetworkGatewayConnectionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) GetResponder(resp *http.Response) (result VirtualNetworkGatewayConnection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSharedKey the Get VirtualNetworkGatewayConnectionSharedKey operation +// retrieves information about the specified virtual network gateway +// connection shared key through Network resource provider. +// +// resourceGroupName is the name of the resource group. +// connectionSharedKeyName is the virtual network gateway connection shared +// key name. +func (client VirtualNetworkGatewayConnectionsClient) GetSharedKey(resourceGroupName string, connectionSharedKeyName string) (result ConnectionSharedKeyResult, err error) { + req, err := client.GetSharedKeyPreparer(resourceGroupName, connectionSharedKeyName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "GetSharedKey", nil, "Failure preparing request") + } + + resp, err := client.GetSharedKeySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "GetSharedKey", resp, "Failure sending request") + } + + result, err = client.GetSharedKeyResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "GetSharedKey", resp, "Failure responding to request") + } + + return +} + +// GetSharedKeyPreparer prepares the GetSharedKey request. +func (client VirtualNetworkGatewayConnectionsClient) GetSharedKeyPreparer(resourceGroupName string, connectionSharedKeyName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "connectionSharedKeyName": autorest.Encode("path", connectionSharedKeyName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{connectionSharedKeyName}/sharedkey", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSharedKeySender sends the GetSharedKey request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) GetSharedKeySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetSharedKeyResponder handles the response to the GetSharedKey request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) GetSharedKeyResponder(resp *http.Response) (result ConnectionSharedKeyResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List VirtualNetworkGatewayConnections operation retrieves all the +// virtual network gateways connections created. +// +// resourceGroupName is the name of the resource group. +func (client VirtualNetworkGatewayConnectionsClient) List(resourceGroupName string) (result VirtualNetworkGatewayConnectionListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualNetworkGatewayConnectionsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) ListResponder(resp *http.Response) (result VirtualNetworkGatewayConnectionListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualNetworkGatewayConnectionsClient) ListNextResults(lastResults VirtualNetworkGatewayConnectionListResult) (result VirtualNetworkGatewayConnectionListResult, err error) { + req, err := lastResults.VirtualNetworkGatewayConnectionListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ResetSharedKey the VirtualNetworkGatewayConnectionResetSharedKey operation +// resets the virtual network gateway connection shared key for passed +// virtual network gateway connection in the specified resource group through +// Network resource provider. This method may poll for completion. Polling +// can be canceled by passing the cancel channel argument. The channel will +// be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayConnectionName is the virtual network gateway +// connection reset shared key Name. parameters is parameters supplied to the +// Begin Reset Virtual Network Gateway connection shared key operation +// through Network resource provider. +func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKey(resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters ConnectionResetSharedKey, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ResetSharedKeyPreparer(resourceGroupName, virtualNetworkGatewayConnectionName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "ResetSharedKey", nil, "Failure preparing request") + } + + resp, err := client.ResetSharedKeySender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "ResetSharedKey", resp, "Failure sending request") + } + + result, err = client.ResetSharedKeyResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "ResetSharedKey", resp, "Failure responding to request") + } + + return +} + +// ResetSharedKeyPreparer prepares the ResetSharedKey request. +func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeyPreparer(resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters ConnectionResetSharedKey, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayConnectionName": autorest.Encode("path", virtualNetworkGatewayConnectionName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{virtualNetworkGatewayConnectionName}/sharedkey/reset", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ResetSharedKeySender sends the ResetSharedKey request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ResetSharedKeyResponder handles the response to the ResetSharedKey request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeyResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// SetSharedKey the Put VirtualNetworkGatewayConnectionSharedKey operation +// sets the virtual network gateway connection shared key for passed virtual +// network gateway connection in the specified resource group through Network +// resource provider. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayConnectionName is the virtual network gateway +// connection name. parameters is parameters supplied to the Begin Set +// Virtual Network Gateway connection Shared key operation throughNetwork +// resource provider. +func (client VirtualNetworkGatewayConnectionsClient) SetSharedKey(resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters ConnectionSharedKey, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.SetSharedKeyPreparer(resourceGroupName, virtualNetworkGatewayConnectionName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "SetSharedKey", nil, "Failure preparing request") + } + + resp, err := client.SetSharedKeySender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "SetSharedKey", resp, "Failure sending request") + } + + result, err = client.SetSharedKeyResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsClient", "SetSharedKey", resp, "Failure responding to request") + } + + return +} + +// SetSharedKeyPreparer prepares the SetSharedKey request. +func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeyPreparer(resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters ConnectionSharedKey, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayConnectionName": autorest.Encode("path", virtualNetworkGatewayConnectionName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{virtualNetworkGatewayConnectionName}/sharedkey", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// SetSharedKeySender sends the SetSharedKey request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// SetSharedKeyResponder handles the response to the SetSharedKey request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeyResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go new file mode 100644 index 0000000000..12e12bc42c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go @@ -0,0 +1,477 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualNetworkGatewaysClient is the the Microsoft Azure Network management +// API provides a RESTful set of web services that interact with Microsoft +// Azure Networks service to manage your network resources. The API has +// entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type VirtualNetworkGatewaysClient struct { + ManagementClient +} + +// NewVirtualNetworkGatewaysClient creates an instance of the +// VirtualNetworkGatewaysClient client. +func NewVirtualNetworkGatewaysClient(subscriptionID string) VirtualNetworkGatewaysClient { + return NewVirtualNetworkGatewaysClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualNetworkGatewaysClientWithBaseURI creates an instance of the +// VirtualNetworkGatewaysClient client. +func NewVirtualNetworkGatewaysClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworkGatewaysClient { + return VirtualNetworkGatewaysClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put VirtualNetworkGateway operation creates/updates a +// virtual network gateway in the specified resource group through Network +// resource provider. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayName is the name of the virtual network gateway. +// parameters is parameters supplied to the Begin Create or update Virtual +// Network Gateway operation through Network resource provider. +func (client VirtualNetworkGatewaysClient) CreateOrUpdate(resourceGroupName string, virtualNetworkGatewayName string, parameters VirtualNetworkGateway, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, virtualNetworkGatewayName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualNetworkGatewaysClient) CreateOrUpdatePreparer(resourceGroupName string, virtualNetworkGatewayName string, parameters VirtualNetworkGateway, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayName": autorest.Encode("path", virtualNetworkGatewayName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewaysClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewaysClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the Delete VirtualNetworkGateway operation deletes the specified +// virtual network Gateway through Network resource provider. This method may +// poll for completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayName is the name of the virtual network gateway. +func (client VirtualNetworkGatewaysClient) Delete(resourceGroupName string, virtualNetworkGatewayName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, virtualNetworkGatewayName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualNetworkGatewaysClient) DeletePreparer(resourceGroupName string, virtualNetworkGatewayName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayName": autorest.Encode("path", virtualNetworkGatewayName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewaysClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewaysClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Generatevpnclientpackage the Generatevpnclientpackage operation generates +// Vpn client package for P2S client of the virtual network gateway in the +// specified resource group through Network resource provider. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayName is the name of the virtual network gateway. +// parameters is parameters supplied to the Begin Generating Virtual Network +// Gateway Vpn client package operation through Network resource provider. +func (client VirtualNetworkGatewaysClient) Generatevpnclientpackage(resourceGroupName string, virtualNetworkGatewayName string, parameters VpnClientParameters) (result String, err error) { + req, err := client.GeneratevpnclientpackagePreparer(resourceGroupName, virtualNetworkGatewayName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Generatevpnclientpackage", nil, "Failure preparing request") + } + + resp, err := client.GeneratevpnclientpackageSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Generatevpnclientpackage", resp, "Failure sending request") + } + + result, err = client.GeneratevpnclientpackageResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Generatevpnclientpackage", resp, "Failure responding to request") + } + + return +} + +// GeneratevpnclientpackagePreparer prepares the Generatevpnclientpackage request. +func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackagePreparer(resourceGroupName string, virtualNetworkGatewayName string, parameters VpnClientParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayName": autorest.Encode("path", virtualNetworkGatewayName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/generatevpnclientpackage", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GeneratevpnclientpackageSender sends the Generatevpnclientpackage request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GeneratevpnclientpackageResponder handles the response to the Generatevpnclientpackage request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageResponder(resp *http.Response) (result String, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get the Get VirtualNetworkGateway operation retrieves information about the +// specified virtual network gateway through Network resource provider. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayName is the name of the virtual network gateway. +func (client VirtualNetworkGatewaysClient) Get(resourceGroupName string, virtualNetworkGatewayName string) (result VirtualNetworkGateway, err error) { + req, err := client.GetPreparer(resourceGroupName, virtualNetworkGatewayName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualNetworkGatewaysClient) GetPreparer(resourceGroupName string, virtualNetworkGatewayName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayName": autorest.Encode("path", virtualNetworkGatewayName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewaysClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewaysClient) GetResponder(resp *http.Response) (result VirtualNetworkGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List VirtualNetworkGateways operation retrieves all the virtual +// network gateways stored. +// +// resourceGroupName is the name of the resource group. +func (client VirtualNetworkGatewaysClient) List(resourceGroupName string) (result VirtualNetworkGatewayListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualNetworkGatewaysClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewaysClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewaysClient) ListResponder(resp *http.Response) (result VirtualNetworkGatewayListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualNetworkGatewaysClient) ListNextResults(lastResults VirtualNetworkGatewayListResult) (result VirtualNetworkGatewayListResult, err error) { + req, err := lastResults.VirtualNetworkGatewayListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// Reset the Reset VirtualNetworkGateway operation resets the primary of the +// virtual network gateway in the specified resource group through Network +// resource provider. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. +// virtualNetworkGatewayName is the name of the virtual network gateway. +// parameters is parameters supplied to the Begin Reset Virtual Network +// Gateway operation through Network resource provider. +func (client VirtualNetworkGatewaysClient) Reset(resourceGroupName string, virtualNetworkGatewayName string, parameters VirtualNetworkGateway, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.ResetPreparer(resourceGroupName, virtualNetworkGatewayName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Reset", nil, "Failure preparing request") + } + + resp, err := client.ResetSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Reset", resp, "Failure sending request") + } + + result, err = client.ResetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "Reset", resp, "Failure responding to request") + } + + return +} + +// ResetPreparer prepares the Reset request. +func (client VirtualNetworkGatewaysClient) ResetPreparer(resourceGroupName string, virtualNetworkGatewayName string, parameters VirtualNetworkGateway, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkGatewayName": autorest.Encode("path", virtualNetworkGatewayName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/reset", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// ResetSender sends the Reset request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkGatewaysClient) ResetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// ResetResponder handles the response to the Reset request. The method always +// closes the http.Response Body. +func (client VirtualNetworkGatewaysClient) ResetResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkpeerings.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkpeerings.go new file mode 100644 index 0000000000..ba9dc74a85 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkpeerings.go @@ -0,0 +1,342 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualNetworkPeeringsClient is the the Microsoft Azure Network management +// API provides a RESTful set of web services that interact with Microsoft +// Azure Networks service to manage your network resources. The API has +// entities that capture the relationship between an end user and the +// Microsoft Azure Networks service. +type VirtualNetworkPeeringsClient struct { + ManagementClient +} + +// NewVirtualNetworkPeeringsClient creates an instance of the +// VirtualNetworkPeeringsClient client. +func NewVirtualNetworkPeeringsClient(subscriptionID string) VirtualNetworkPeeringsClient { + return NewVirtualNetworkPeeringsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualNetworkPeeringsClientWithBaseURI creates an instance of the +// VirtualNetworkPeeringsClient client. +func NewVirtualNetworkPeeringsClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworkPeeringsClient { + return VirtualNetworkPeeringsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate the Put virtual network peering operation creates/updates a +// peering in the specified virtual network This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. virtualNetworkPeeringName is the name of +// the peering. virtualNetworkPeeringParameters is parameters supplied to the +// create/update virtual network peering operation +func (client VirtualNetworkPeeringsClient) CreateOrUpdate(resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string, virtualNetworkPeeringParameters VirtualNetworkPeering, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, virtualNetworkName, virtualNetworkPeeringName, virtualNetworkPeeringParameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualNetworkPeeringsClient) CreateOrUpdatePreparer(resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string, virtualNetworkPeeringParameters VirtualNetworkPeering, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + "virtualNetworkPeeringName": autorest.Encode("path", virtualNetworkPeeringName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/virtualNetworkPeerings/{virtualNetworkPeeringName}", pathParameters), + autorest.WithJSON(virtualNetworkPeeringParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkPeeringsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualNetworkPeeringsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the delete virtual network peering operation deletes the specified +// peering. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. virtualNetworkPeeringName is the name of +// the virtual network peering. +func (client VirtualNetworkPeeringsClient) Delete(resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, virtualNetworkName, virtualNetworkPeeringName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualNetworkPeeringsClient) DeletePreparer(resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + "virtualNetworkPeeringName": autorest.Encode("path", virtualNetworkPeeringName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/virtualNetworkPeerings/{virtualNetworkPeeringName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkPeeringsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualNetworkPeeringsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get virtual network peering operation retrieves information about +// the specified virtual network peering. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. virtualNetworkPeeringName is the name of +// the virtual network peering. +func (client VirtualNetworkPeeringsClient) Get(resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string) (result VirtualNetworkPeering, err error) { + req, err := client.GetPreparer(resourceGroupName, virtualNetworkName, virtualNetworkPeeringName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualNetworkPeeringsClient) GetPreparer(resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + "virtualNetworkPeeringName": autorest.Encode("path", virtualNetworkPeeringName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/virtualNetworkPeerings/{virtualNetworkPeeringName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkPeeringsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualNetworkPeeringsClient) GetResponder(resp *http.Response) (result VirtualNetworkPeering, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List virtual network peerings operation retrieves all the peerings +// in a virtual network. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. +func (client VirtualNetworkPeeringsClient) List(resourceGroupName string, virtualNetworkName string) (result VirtualNetworkPeeringListResult, err error) { + req, err := client.ListPreparer(resourceGroupName, virtualNetworkName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualNetworkPeeringsClient) ListPreparer(resourceGroupName string, virtualNetworkName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/virtualNetworkPeerings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworkPeeringsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualNetworkPeeringsClient) ListResponder(resp *http.Response) (result VirtualNetworkPeeringListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualNetworkPeeringsClient) ListNextResults(lastResults VirtualNetworkPeeringListResult) (result VirtualNetworkPeeringListResult, err error) { + req, err := lastResults.VirtualNetworkPeeringListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go new file mode 100644 index 0000000000..89758841bc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go @@ -0,0 +1,488 @@ +package network + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// VirtualNetworksClient is the the Microsoft Azure Network management API +// provides a RESTful set of web services that interact with Microsoft Azure +// Networks service to manage your network resources. The API has entities +// that capture the relationship between an end user and the Microsoft Azure +// Networks service. +type VirtualNetworksClient struct { + ManagementClient +} + +// NewVirtualNetworksClient creates an instance of the VirtualNetworksClient +// client. +func NewVirtualNetworksClient(subscriptionID string) VirtualNetworksClient { + return NewVirtualNetworksClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVirtualNetworksClientWithBaseURI creates an instance of the +// VirtualNetworksClient client. +func NewVirtualNetworksClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworksClient { + return VirtualNetworksClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckIPAddressAvailability checks whether a private Ip address is available +// for use. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. ipAddress is the private IP address to be +// verified. +func (client VirtualNetworksClient) CheckIPAddressAvailability(resourceGroupName string, virtualNetworkName string, ipAddress string) (result IPAddressAvailabilityResult, err error) { + req, err := client.CheckIPAddressAvailabilityPreparer(resourceGroupName, virtualNetworkName, ipAddress) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "CheckIPAddressAvailability", nil, "Failure preparing request") + } + + resp, err := client.CheckIPAddressAvailabilitySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "CheckIPAddressAvailability", resp, "Failure sending request") + } + + result, err = client.CheckIPAddressAvailabilityResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "CheckIPAddressAvailability", resp, "Failure responding to request") + } + + return +} + +// CheckIPAddressAvailabilityPreparer prepares the CheckIPAddressAvailability request. +func (client VirtualNetworksClient) CheckIPAddressAvailabilityPreparer(resourceGroupName string, virtualNetworkName string, ipAddress string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(ipAddress) > 0 { + queryParameters["ipAddress"] = autorest.Encode("query", ipAddress) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/CheckIPAddressAvailability", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CheckIPAddressAvailabilitySender sends the CheckIPAddressAvailability request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworksClient) CheckIPAddressAvailabilitySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CheckIPAddressAvailabilityResponder handles the response to the CheckIPAddressAvailability request. The method always +// closes the http.Response Body. +func (client VirtualNetworksClient) CheckIPAddressAvailabilityResponder(resp *http.Response) (result IPAddressAvailabilityResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdate the Put VirtualNetwork operation creates/updates a virtual +// network in the specified resource group. This method may poll for +// completion. Polling can be canceled by passing the cancel channel +// argument. The channel will be used to cancel polling and any outstanding +// HTTP requests. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. parameters is parameters supplied to the +// create/update Virtual Network operation +func (client VirtualNetworksClient) CreateOrUpdate(resourceGroupName string, virtualNetworkName string, parameters VirtualNetwork, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, virtualNetworkName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualNetworksClient) CreateOrUpdatePreparer(resourceGroupName string, virtualNetworkName string, parameters VirtualNetwork, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworksClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualNetworksClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the Delete VirtualNetwork operation deletes the specified virtual +// network This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. +func (client VirtualNetworksClient) Delete(resourceGroupName string, virtualNetworkName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, virtualNetworkName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualNetworksClient) DeletePreparer(resourceGroupName string, virtualNetworkName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworksClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VirtualNetworksClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusNoContent, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get VirtualNetwork operation retrieves information about the +// specified virtual network. +// +// resourceGroupName is the name of the resource group. virtualNetworkName is +// the name of the virtual network. expand is expand references resources. +func (client VirtualNetworksClient) Get(resourceGroupName string, virtualNetworkName string, expand string) (result VirtualNetwork, err error) { + req, err := client.GetPreparer(resourceGroupName, virtualNetworkName, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VirtualNetworksClient) GetPreparer(resourceGroupName string, virtualNetworkName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "virtualNetworkName": autorest.Encode("path", virtualNetworkName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworksClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client VirtualNetworksClient) GetResponder(resp *http.Response) (result VirtualNetwork, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the list VirtualNetwork returns all Virtual Networks in a resource +// group +// +// resourceGroupName is the name of the resource group. +func (client VirtualNetworksClient) List(resourceGroupName string) (result VirtualNetworkListResult, err error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualNetworksClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworksClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client VirtualNetworksClient) ListResponder(resp *http.Response) (result VirtualNetworkListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client VirtualNetworksClient) ListNextResults(lastResults VirtualNetworkListResult) (result VirtualNetworkListResult, err error) { + req, err := lastResults.VirtualNetworkListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListAll the list VirtualNetwork returns all Virtual Networks in a +// subscription +func (client VirtualNetworksClient) ListAll() (result VirtualNetworkListResult, err error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "ListAll", nil, "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "ListAll", resp, "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "ListAll", resp, "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client VirtualNetworksClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/virtualNetworks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualNetworksClient) ListAllSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client VirtualNetworksClient) ListAllResponder(resp *http.Response) (result VirtualNetworkListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAllNextResults retrieves the next set of results, if any. +func (client VirtualNetworksClient) ListAllNextResults(lastResults VirtualNetworkListResult) (result VirtualNetworkListResult, err error) { + req, err := lastResults.VirtualNetworkListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "ListAll", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "ListAll", resp, "Failure sending next results request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "network.VirtualNetworksClient", "ListAll", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/client.go new file mode 100644 index 0000000000..3d6c5273fe --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/client.go @@ -0,0 +1,57 @@ +// Package resources implements the Azure ARM Resources service API version +// 2016-07-01. +// +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Resources + APIVersion = "2016-07-01" + + // DefaultBaseURI is the default URI used for the service Resources + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Resources. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/deploymentoperations.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/deploymentoperations.go new file mode 100644 index 0000000000..2144840d2d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/deploymentoperations.go @@ -0,0 +1,216 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// DeploymentOperationsClient is the client for the DeploymentOperations +// methods of the Resources service. +type DeploymentOperationsClient struct { + ManagementClient +} + +// NewDeploymentOperationsClient creates an instance of the +// DeploymentOperationsClient client. +func NewDeploymentOperationsClient(subscriptionID string) DeploymentOperationsClient { + return NewDeploymentOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewDeploymentOperationsClientWithBaseURI creates an instance of the +// DeploymentOperationsClient client. +func NewDeploymentOperationsClientWithBaseURI(baseURI string, subscriptionID string) DeploymentOperationsClient { + return DeploymentOperationsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Get get a list of deployments operations. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment. operationID is +// operation Id. +func (client DeploymentOperationsClient) Get(resourceGroupName string, deploymentName string, operationID string) (result DeploymentOperation, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentOperationsClient", "Get") + } + + req, err := client.GetPreparer(resourceGroupName, deploymentName, operationID) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client DeploymentOperationsClient) GetPreparer(resourceGroupName string, deploymentName string, operationID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "operationId": autorest.Encode("path", operationID), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations/{operationId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentOperationsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client DeploymentOperationsClient) GetResponder(resp *http.Response) (result DeploymentOperation, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of deployments operations. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment. top is query +// parameters. +func (client DeploymentOperationsClient) List(resourceGroupName string, deploymentName string, top *int32) (result DeploymentOperationsListResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentOperationsClient", "List") + } + + req, err := client.ListPreparer(resourceGroupName, deploymentName, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client DeploymentOperationsClient) ListPreparer(resourceGroupName string, deploymentName string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentOperationsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client DeploymentOperationsClient) ListResponder(resp *http.Response) (result DeploymentOperationsListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client DeploymentOperationsClient) ListNextResults(lastResults DeploymentOperationsListResult) (result DeploymentOperationsListResult, err error) { + req, err := lastResults.DeploymentOperationsListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/deployments.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/deployments.go new file mode 100644 index 0000000000..236bf0df6a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/deployments.go @@ -0,0 +1,666 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// DeploymentsClient is the client for the Deployments methods of the +// Resources service. +type DeploymentsClient struct { + ManagementClient +} + +// NewDeploymentsClient creates an instance of the DeploymentsClient client. +func NewDeploymentsClient(subscriptionID string) DeploymentsClient { + return NewDeploymentsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewDeploymentsClientWithBaseURI creates an instance of the +// DeploymentsClient client. +func NewDeploymentsClientWithBaseURI(baseURI string, subscriptionID string) DeploymentsClient { + return DeploymentsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Cancel cancel a currently running template deployment. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment. +func (client DeploymentsClient) Cancel(resourceGroupName string, deploymentName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Cancel") + } + + req, err := client.CancelPreparer(resourceGroupName, deploymentName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Cancel", nil, "Failure preparing request") + } + + resp, err := client.CancelSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Cancel", resp, "Failure sending request") + } + + result, err = client.CancelResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Cancel", resp, "Failure responding to request") + } + + return +} + +// CancelPreparer prepares the Cancel request. +func (client DeploymentsClient) CancelPreparer(resourceGroupName string, deploymentName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CancelSender sends the Cancel request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) CancelSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CancelResponder handles the response to the Cancel request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) CancelResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// CheckExistence checks whether deployment exists. +// +// resourceGroupName is the name of the resource group to check. The name is +// case insensitive. deploymentName is the name of the deployment. +func (client DeploymentsClient) CheckExistence(resourceGroupName string, deploymentName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "CheckExistence") + } + + req, err := client.CheckExistencePreparer(resourceGroupName, deploymentName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CheckExistence", nil, "Failure preparing request") + } + + resp, err := client.CheckExistenceSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CheckExistence", resp, "Failure sending request") + } + + result, err = client.CheckExistenceResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CheckExistence", resp, "Failure responding to request") + } + + return +} + +// CheckExistencePreparer prepares the CheckExistence request. +func (client DeploymentsClient) CheckExistencePreparer(resourceGroupName string, deploymentName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsHead(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CheckExistenceSender sends the CheckExistence request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) CheckExistenceSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CheckExistenceResponder handles the response to the CheckExistence request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) CheckExistenceResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound), + autorest.ByClosing()) + result.Response = resp + return +} + +// CreateOrUpdate create a named template deployment using a template. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment. parameters is +// additional parameters supplied to the operation. +func (client DeploymentsClient) CreateOrUpdate(resourceGroupName string, deploymentName string, parameters Deployment, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink.URI", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.Properties.ParametersLink", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.ParametersLink.URI", Name: validation.Null, Rule: true, Chain: nil}}}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, deploymentName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client DeploymentsClient) CreateOrUpdatePreparer(resourceGroupName string, deploymentName string, parameters Deployment, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete delete deployment. This method may poll for completion. Polling can +// be canceled by passing the cancel channel argument. The channel will be +// used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment to be deleted. +func (client DeploymentsClient) Delete(resourceGroupName string, deploymentName string, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Delete") + } + + req, err := client.DeletePreparer(resourceGroupName, deploymentName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client DeploymentsClient) DeletePreparer(resourceGroupName string, deploymentName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// ExportTemplate exports a deployment template. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment. +func (client DeploymentsClient) ExportTemplate(resourceGroupName string, deploymentName string) (result DeploymentExportResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "ExportTemplate") + } + + req, err := client.ExportTemplatePreparer(resourceGroupName, deploymentName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "ExportTemplate", nil, "Failure preparing request") + } + + resp, err := client.ExportTemplateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "ExportTemplate", resp, "Failure sending request") + } + + result, err = client.ExportTemplateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "ExportTemplate", resp, "Failure responding to request") + } + + return +} + +// ExportTemplatePreparer prepares the ExportTemplate request. +func (client DeploymentsClient) ExportTemplatePreparer(resourceGroupName string, deploymentName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ExportTemplateSender sends the ExportTemplate request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) ExportTemplateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ExportTemplateResponder handles the response to the ExportTemplate request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) ExportTemplateResponder(resp *http.Response) (result DeploymentExportResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get get a deployment. +// +// resourceGroupName is the name of the resource group to get. The name is +// case insensitive. deploymentName is the name of the deployment. +func (client DeploymentsClient) Get(resourceGroupName string, deploymentName string) (result DeploymentExtended, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Get") + } + + req, err := client.GetPreparer(resourceGroupName, deploymentName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client DeploymentsClient) GetPreparer(resourceGroupName string, deploymentName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) GetResponder(resp *http.Response) (result DeploymentExtended, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List get a list of deployments. +// +// resourceGroupName is the name of the resource group to filter by. The name +// is case insensitive. filter is the filter to apply on the operation. top +// is query parameters. If null is passed returns all deployments. +func (client DeploymentsClient) List(resourceGroupName string, filter string, top *int32) (result DeploymentListResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "List") + } + + req, err := client.ListPreparer(resourceGroupName, filter, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client DeploymentsClient) ListPreparer(resourceGroupName string, filter string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) ListResponder(resp *http.Response) (result DeploymentListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client DeploymentsClient) ListNextResults(lastResults DeploymentListResult) (result DeploymentListResult, err error) { + req, err := lastResults.DeploymentListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// Validate validate a deployment template. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. deploymentName is the name of the deployment. parameters is +// deployment to validate. +func (client DeploymentsClient) Validate(resourceGroupName string, deploymentName string, parameters Deployment) (result DeploymentValidateResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink.URI", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.Properties.ParametersLink", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.ParametersLink.URI", Name: validation.Null, Rule: true, Chain: nil}}}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Validate") + } + + req, err := client.ValidatePreparer(resourceGroupName, deploymentName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Validate", nil, "Failure preparing request") + } + + resp, err := client.ValidateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Validate", resp, "Failure sending request") + } + + result, err = client.ValidateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Validate", resp, "Failure responding to request") + } + + return +} + +// ValidatePreparer prepares the Validate request. +func (client DeploymentsClient) ValidatePreparer(resourceGroupName string, deploymentName string, parameters Deployment) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": autorest.Encode("path", deploymentName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/validate", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ValidateSender sends the Validate request. The method will close the +// http.Response Body if it receives an error. +func (client DeploymentsClient) ValidateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ValidateResponder handles the response to the Validate request. The method always +// closes the http.Response Body. +func (client DeploymentsClient) ValidateResponder(resp *http.Response) (result DeploymentValidateResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusBadRequest), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/groups.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/groups.go new file mode 100644 index 0000000000..c8eaff6378 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/groups.go @@ -0,0 +1,678 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// GroupsClient is the client for the Groups methods of the Resources service. +type GroupsClient struct { + ManagementClient +} + +// NewGroupsClient creates an instance of the GroupsClient client. +func NewGroupsClient(subscriptionID string) GroupsClient { + return NewGroupsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGroupsClientWithBaseURI creates an instance of the GroupsClient client. +func NewGroupsClientWithBaseURI(baseURI string, subscriptionID string) GroupsClient { + return GroupsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckExistence checks whether resource group exists. +// +// resourceGroupName is the name of the resource group to check. The name is +// case insensitive. +func (client GroupsClient) CheckExistence(resourceGroupName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "CheckExistence") + } + + req, err := client.CheckExistencePreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "CheckExistence", nil, "Failure preparing request") + } + + resp, err := client.CheckExistenceSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "CheckExistence", resp, "Failure sending request") + } + + result, err = client.CheckExistenceResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "CheckExistence", resp, "Failure responding to request") + } + + return +} + +// CheckExistencePreparer prepares the CheckExistence request. +func (client GroupsClient) CheckExistencePreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsHead(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CheckExistenceSender sends the CheckExistence request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) CheckExistenceSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CheckExistenceResponder handles the response to the CheckExistence request. The method always +// closes the http.Response Body. +func (client GroupsClient) CheckExistenceResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound), + autorest.ByClosing()) + result.Response = resp + return +} + +// CreateOrUpdate create a resource group. +// +// resourceGroupName is the name of the resource group to be created or +// updated. parameters is parameters supplied to the create or update +// resource group service operation. +func (client GroupsClient) CreateOrUpdate(resourceGroupName string, parameters ResourceGroup) (result ResourceGroup, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.ProvisioningState", Name: validation.ReadOnly, Rule: true, Chain: nil}}}, + {Target: "parameters.Location", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.ID", Name: validation.ReadOnly, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client GroupsClient) CreateOrUpdatePreparer(resourceGroupName string, parameters ResourceGroup) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client GroupsClient) CreateOrUpdateResponder(resp *http.Response) (result ResourceGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete resource group. This method may poll for completion. Polling +// can be canceled by passing the cancel channel argument. The channel will +// be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group to be deleted. The name +// is case insensitive. +func (client GroupsClient) Delete(resourceGroupName string, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "Delete") + } + + req, err := client.DeletePreparer(resourceGroupName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client GroupsClient) DeletePreparer(resourceGroupName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client GroupsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// ExportTemplate captures the specified resource group as a template. +// +// resourceGroupName is the name of the resource group to be created or +// updated. parameters is parameters supplied to the export template resource +// group operation. +func (client GroupsClient) ExportTemplate(resourceGroupName string, parameters ExportTemplateRequest) (result ResourceGroupExportResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "ExportTemplate") + } + + req, err := client.ExportTemplatePreparer(resourceGroupName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ExportTemplate", nil, "Failure preparing request") + } + + resp, err := client.ExportTemplateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ExportTemplate", resp, "Failure sending request") + } + + result, err = client.ExportTemplateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ExportTemplate", resp, "Failure responding to request") + } + + return +} + +// ExportTemplatePreparer prepares the ExportTemplate request. +func (client GroupsClient) ExportTemplatePreparer(resourceGroupName string, parameters ExportTemplateRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/exportTemplate", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ExportTemplateSender sends the ExportTemplate request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) ExportTemplateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ExportTemplateResponder handles the response to the ExportTemplate request. The method always +// closes the http.Response Body. +func (client GroupsClient) ExportTemplateResponder(resp *http.Response) (result ResourceGroupExportResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get get a resource group. +// +// resourceGroupName is the name of the resource group to get. The name is +// case insensitive. +func (client GroupsClient) Get(resourceGroupName string) (result ResourceGroup, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "Get") + } + + req, err := client.GetPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client GroupsClient) GetPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client GroupsClient) GetResponder(resp *http.Response) (result ResourceGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a collection of resource groups. +// +// filter is the filter to apply on the operation. top is query parameters. If +// null is passed returns all resource groups. +func (client GroupsClient) List(filter string, top *int32) (result ResourceGroupListResult, err error) { + req, err := client.ListPreparer(filter, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client GroupsClient) ListPreparer(filter string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client GroupsClient) ListResponder(resp *http.Response) (result ResourceGroupListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client GroupsClient) ListNextResults(lastResults ResourceGroupListResult) (result ResourceGroupListResult, err error) { + req, err := lastResults.ResourceGroupListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListResources get all of the resources under a subscription. +// +// resourceGroupName is query parameters. If null is passed returns all +// resource groups. filter is the filter to apply on the operation. expand is +// the $expand query parameter top is query parameters. If null is passed +// returns all resource groups. +func (client GroupsClient) ListResources(resourceGroupName string, filter string, expand string, top *int32) (result ResourceListResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "ListResources") + } + + req, err := client.ListResourcesPreparer(resourceGroupName, filter, expand, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", nil, "Failure preparing request") + } + + resp, err := client.ListResourcesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure sending request") + } + + result, err = client.ListResourcesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure responding to request") + } + + return +} + +// ListResourcesPreparer prepares the ListResources request. +func (client GroupsClient) ListResourcesPreparer(resourceGroupName string, filter string, expand string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/resources", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListResourcesSender sends the ListResources request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) ListResourcesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResourcesResponder handles the response to the ListResources request. The method always +// closes the http.Response Body. +func (client GroupsClient) ListResourcesResponder(resp *http.Response) (result ResourceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListResourcesNextResults retrieves the next set of results, if any. +func (client GroupsClient) ListResourcesNextResults(lastResults ResourceListResult) (result ResourceListResult, err error) { + req, err := lastResults.ResourceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListResourcesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure sending next results request") + } + + result, err = client.ListResourcesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure responding to next results request") + } + + return +} + +// Patch resource groups can be updated through a simple PATCH operation to a +// group address. The format of the request is the same as that for creating +// a resource groups, though if a field is unspecified current value will be +// carried over. +// +// resourceGroupName is the name of the resource group to be created or +// updated. The name is case insensitive. parameters is parameters supplied +// to the update state resource group service operation. +func (client GroupsClient) Patch(resourceGroupName string, parameters ResourceGroup) (result ResourceGroup, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.ID", Name: validation.ReadOnly, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "Patch") + } + + req, err := client.PatchPreparer(resourceGroupName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "Patch", nil, "Failure preparing request") + } + + resp, err := client.PatchSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "Patch", resp, "Failure sending request") + } + + result, err = client.PatchResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Patch", resp, "Failure responding to request") + } + + return +} + +// PatchPreparer prepares the Patch request. +func (client GroupsClient) PatchPreparer(resourceGroupName string, parameters ResourceGroup) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// PatchSender sends the Patch request. The method will close the +// http.Response Body if it receives an error. +func (client GroupsClient) PatchSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// PatchResponder handles the response to the Patch request. The method always +// closes the http.Response Body. +func (client GroupsClient) PatchResponder(resp *http.Response) (result ResourceGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/models.go new file mode 100644 index 0000000000..32e5b1b37f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/models.go @@ -0,0 +1,463 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// DeploymentMode enumerates the values for deployment mode. +type DeploymentMode string + +const ( + // Complete specifies the complete state for deployment mode. + Complete DeploymentMode = "Complete" + // Incremental specifies the incremental state for deployment mode. + Incremental DeploymentMode = "Incremental" +) + +// ResourceIdentityType enumerates the values for resource identity type. +type ResourceIdentityType string + +const ( + // SystemAssigned specifies the system assigned state for resource + // identity type. + SystemAssigned ResourceIdentityType = "SystemAssigned" +) + +// AliasPathType is the type of the paths for alias. +type AliasPathType struct { + Path *string `json:"path,omitempty"` + APIVersions *[]string `json:"apiVersions,omitempty"` +} + +// AliasType is the alias type. +type AliasType struct { + Name *string `json:"name,omitempty"` + Paths *[]AliasPathType `json:"paths,omitempty"` +} + +// BasicDependency is deployment dependency information. +type BasicDependency struct { + ID *string `json:"id,omitempty"` + ResourceType *string `json:"resourceType,omitempty"` + ResourceName *string `json:"resourceName,omitempty"` +} + +// DebugSetting is +type DebugSetting struct { + DetailLevel *string `json:"detailLevel,omitempty"` +} + +// Dependency is deployment dependency information. +type Dependency struct { + DependsOn *[]BasicDependency `json:"dependsOn,omitempty"` + ID *string `json:"id,omitempty"` + ResourceType *string `json:"resourceType,omitempty"` + ResourceName *string `json:"resourceName,omitempty"` +} + +// Deployment is deployment operation parameters. +type Deployment struct { + Properties *DeploymentProperties `json:"properties,omitempty"` +} + +// DeploymentExportResult is the deployment export result. +type DeploymentExportResult struct { + autorest.Response `json:"-"` + Template *map[string]interface{} `json:"template,omitempty"` +} + +// DeploymentExtended is deployment information. +type DeploymentExtended struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *DeploymentPropertiesExtended `json:"properties,omitempty"` +} + +// DeploymentExtendedFilter is deployment filter. +type DeploymentExtendedFilter struct { + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// DeploymentListResult is list of deployments. +type DeploymentListResult struct { + autorest.Response `json:"-"` + Value *[]DeploymentExtended `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// DeploymentListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client DeploymentListResult) DeploymentListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// DeploymentOperation is deployment operation information. +type DeploymentOperation struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + OperationID *string `json:"operationId,omitempty"` + Properties *DeploymentOperationProperties `json:"properties,omitempty"` +} + +// DeploymentOperationProperties is deployment operation properties. +type DeploymentOperationProperties struct { + ProvisioningState *string `json:"provisioningState,omitempty"` + Timestamp *date.Time `json:"timestamp,omitempty"` + ServiceRequestID *string `json:"serviceRequestId,omitempty"` + StatusCode *string `json:"statusCode,omitempty"` + StatusMessage *map[string]interface{} `json:"statusMessage,omitempty"` + TargetResource *TargetResource `json:"targetResource,omitempty"` + Request *HTTPMessage `json:"request,omitempty"` + Response *HTTPMessage `json:"response,omitempty"` +} + +// DeploymentOperationsListResult is list of deployment operations. +type DeploymentOperationsListResult struct { + autorest.Response `json:"-"` + Value *[]DeploymentOperation `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// DeploymentOperationsListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client DeploymentOperationsListResult) DeploymentOperationsListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// DeploymentProperties is deployment properties. +type DeploymentProperties struct { + Template *map[string]interface{} `json:"template,omitempty"` + TemplateLink *TemplateLink `json:"templateLink,omitempty"` + Parameters *map[string]interface{} `json:"parameters,omitempty"` + ParametersLink *ParametersLink `json:"parametersLink,omitempty"` + Mode DeploymentMode `json:"mode,omitempty"` + DebugSetting *DebugSetting `json:"debugSetting,omitempty"` +} + +// DeploymentPropertiesExtended is deployment properties with additional +// details. +type DeploymentPropertiesExtended struct { + ProvisioningState *string `json:"provisioningState,omitempty"` + CorrelationID *string `json:"correlationId,omitempty"` + Timestamp *date.Time `json:"timestamp,omitempty"` + Outputs *map[string]interface{} `json:"outputs,omitempty"` + Providers *[]Provider `json:"providers,omitempty"` + Dependencies *[]Dependency `json:"dependencies,omitempty"` + Template *map[string]interface{} `json:"template,omitempty"` + TemplateLink *TemplateLink `json:"templateLink,omitempty"` + Parameters *map[string]interface{} `json:"parameters,omitempty"` + ParametersLink *ParametersLink `json:"parametersLink,omitempty"` + Mode DeploymentMode `json:"mode,omitempty"` + DebugSetting *DebugSetting `json:"debugSetting,omitempty"` +} + +// DeploymentValidateResult is information from validate template deployment +// response. +type DeploymentValidateResult struct { + autorest.Response `json:"-"` + Error *ResourceManagementErrorWithDetails `json:"error,omitempty"` + Properties *DeploymentPropertiesExtended `json:"properties,omitempty"` +} + +// ExportTemplateRequest is export resource group template request parameters. +type ExportTemplateRequest struct { + Resources *[]string `json:"resources,omitempty"` + Options *string `json:"options,omitempty"` +} + +// GenericResource is resource information. +type GenericResource struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Plan *Plan `json:"plan,omitempty"` + Properties *map[string]interface{} `json:"properties,omitempty"` + Kind *string `json:"kind,omitempty"` + ManagedBy *string `json:"managedBy,omitempty"` + Sku *Sku `json:"sku,omitempty"` + Identity *Identity `json:"identity,omitempty"` +} + +// GenericResourceFilter is resource filter. +type GenericResourceFilter struct { + ResourceType *string `json:"resourceType,omitempty"` + Tagname *string `json:"tagname,omitempty"` + Tagvalue *string `json:"tagvalue,omitempty"` +} + +// HTTPMessage is +type HTTPMessage struct { + Content *map[string]interface{} `json:"content,omitempty"` +} + +// Identity is identity for the resource. +type Identity struct { + PrincipalID *string `json:"principalId,omitempty"` + TenantID *string `json:"tenantId,omitempty"` + Type ResourceIdentityType `json:"type,omitempty"` +} + +// MoveInfo is parameters of move resources. +type MoveInfo struct { + Resources *[]string `json:"resources,omitempty"` + TargetResourceGroup *string `json:"targetResourceGroup,omitempty"` +} + +// ParametersLink is entity representing the reference to the deployment +// paramaters. +type ParametersLink struct { + URI *string `json:"uri,omitempty"` + ContentVersion *string `json:"contentVersion,omitempty"` +} + +// Plan is plan for the resource. +type Plan struct { + Name *string `json:"name,omitempty"` + Publisher *string `json:"publisher,omitempty"` + Product *string `json:"product,omitempty"` + PromotionCode *string `json:"promotionCode,omitempty"` +} + +// Provider is resource provider information. +type Provider struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Namespace *string `json:"namespace,omitempty"` + RegistrationState *string `json:"registrationState,omitempty"` + ResourceTypes *[]ProviderResourceType `json:"resourceTypes,omitempty"` +} + +// ProviderListResult is list of resource providers. +type ProviderListResult struct { + autorest.Response `json:"-"` + Value *[]Provider `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ProviderListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ProviderListResult) ProviderListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ProviderResourceType is resource type managed by the resource provider. +type ProviderResourceType struct { + ResourceType *string `json:"resourceType,omitempty"` + Locations *[]string `json:"locations,omitempty"` + Aliases *[]AliasType `json:"aliases,omitempty"` + APIVersions *[]string `json:"apiVersions,omitempty"` + ZoneMappings *[]ZoneMappingType `json:"zoneMappings,omitempty"` + Properties *map[string]*string `json:"properties,omitempty"` +} + +// Resource is +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceGroup is resource group information. +type ResourceGroup struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *ResourceGroupProperties `json:"properties,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceGroupExportResult is +type ResourceGroupExportResult struct { + autorest.Response `json:"-"` + Template *map[string]interface{} `json:"template,omitempty"` + Error *ResourceManagementErrorWithDetails `json:"error,omitempty"` +} + +// ResourceGroupFilter is resource group filter. +type ResourceGroupFilter struct { + TagName *string `json:"tagName,omitempty"` + TagValue *string `json:"tagValue,omitempty"` +} + +// ResourceGroupListResult is list of resource groups. +type ResourceGroupListResult struct { + autorest.Response `json:"-"` + Value *[]ResourceGroup `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ResourceGroupListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ResourceGroupListResult) ResourceGroupListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ResourceGroupProperties is the resource group properties. +type ResourceGroupProperties struct { + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ResourceListResult is list of resource groups. +type ResourceListResult struct { + autorest.Response `json:"-"` + Value *[]GenericResource `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ResourceListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ResourceListResult) ResourceListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ResourceManagementErrorWithDetails is +type ResourceManagementErrorWithDetails struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Target *string `json:"target,omitempty"` + Details *[]ResourceManagementErrorWithDetails `json:"details,omitempty"` +} + +// ResourceProviderOperationDisplayProperties is resource provider operation's +// display properties. +type ResourceProviderOperationDisplayProperties struct { + Publisher *string `json:"publisher,omitempty"` + Provider *string `json:"provider,omitempty"` + Resource *string `json:"resource,omitempty"` + Operation *string `json:"operation,omitempty"` + Description *string `json:"description,omitempty"` +} + +// Sku is sku for the resource. +type Sku struct { + Name *string `json:"name,omitempty"` + Tier *string `json:"tier,omitempty"` + Size *string `json:"size,omitempty"` + Family *string `json:"family,omitempty"` + Model *string `json:"model,omitempty"` + Capacity *int32 `json:"capacity,omitempty"` +} + +// SubResource is +type SubResource struct { + ID *string `json:"id,omitempty"` +} + +// TagCount is tag count. +type TagCount struct { + Type *string `json:"type,omitempty"` + Value *string `json:"value,omitempty"` +} + +// TagDetails is tag details. +type TagDetails struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + TagName *string `json:"tagName,omitempty"` + Count *TagCount `json:"count,omitempty"` + Values *[]TagValue `json:"values,omitempty"` +} + +// TagsListResult is list of subscription tags. +type TagsListResult struct { + autorest.Response `json:"-"` + Value *[]TagDetails `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// TagsListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client TagsListResult) TagsListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// TagValue is tag information. +type TagValue struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + TagValueProperty *string `json:"tagValue,omitempty"` + Count *TagCount `json:"count,omitempty"` +} + +// TargetResource is target resource. +type TargetResource struct { + ID *string `json:"id,omitempty"` + ResourceName *string `json:"resourceName,omitempty"` + ResourceType *string `json:"resourceType,omitempty"` +} + +// TemplateLink is entity representing the reference to the template. +type TemplateLink struct { + URI *string `json:"uri,omitempty"` + ContentVersion *string `json:"contentVersion,omitempty"` +} + +// ZoneMappingType is zone mapping type. +type ZoneMappingType struct { + Location *string `json:"location,omitempty"` + Zones *[]string `json:"zones,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/providers.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/providers.go new file mode 100644 index 0000000000..5a9470f53b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/providers.go @@ -0,0 +1,322 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ProvidersClient is the client for the Providers methods of the Resources +// service. +type ProvidersClient struct { + ManagementClient +} + +// NewProvidersClient creates an instance of the ProvidersClient client. +func NewProvidersClient(subscriptionID string) ProvidersClient { + return NewProvidersClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewProvidersClientWithBaseURI creates an instance of the ProvidersClient +// client. +func NewProvidersClientWithBaseURI(baseURI string, subscriptionID string) ProvidersClient { + return ProvidersClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Get gets a resource provider. +// +// resourceProviderNamespace is namespace of the resource provider. expand is +// the $expand query parameter. e.g. To include property aliases in response, +// use $expand=resourceTypes/aliases. +func (client ProvidersClient) Get(resourceProviderNamespace string, expand string) (result Provider, err error) { + req, err := client.GetPreparer(resourceProviderNamespace, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ProvidersClient) GetPreparer(resourceProviderNamespace string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ProvidersClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ProvidersClient) GetResponder(resp *http.Response) (result Provider, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of resource providers. +// +// top is query parameters. If null is passed returns all deployments. expand +// is the $expand query parameter. e.g. To include property aliases in +// response, use $expand=resourceTypes/aliases. +func (client ProvidersClient) List(top *int32, expand string) (result ProviderListResult, err error) { + req, err := client.ListPreparer(top, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ProvidersClient) ListPreparer(top *int32, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ProvidersClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ProvidersClient) ListResponder(resp *http.Response) (result ProviderListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ProvidersClient) ListNextResults(lastResults ProviderListResult) (result ProviderListResult, err error) { + req, err := lastResults.ProviderListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// Register registers provider to be used with a subscription. +// +// resourceProviderNamespace is namespace of the resource provider. +func (client ProvidersClient) Register(resourceProviderNamespace string) (result Provider, err error) { + req, err := client.RegisterPreparer(resourceProviderNamespace) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "Register", nil, "Failure preparing request") + } + + resp, err := client.RegisterSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "Register", resp, "Failure sending request") + } + + result, err = client.RegisterResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "Register", resp, "Failure responding to request") + } + + return +} + +// RegisterPreparer prepares the Register request. +func (client ProvidersClient) RegisterPreparer(resourceProviderNamespace string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// RegisterSender sends the Register request. The method will close the +// http.Response Body if it receives an error. +func (client ProvidersClient) RegisterSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// RegisterResponder handles the response to the Register request. The method always +// closes the http.Response Body. +func (client ProvidersClient) RegisterResponder(resp *http.Response) (result Provider, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Unregister unregisters provider from a subscription. +// +// resourceProviderNamespace is namespace of the resource provider. +func (client ProvidersClient) Unregister(resourceProviderNamespace string) (result Provider, err error) { + req, err := client.UnregisterPreparer(resourceProviderNamespace) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "Unregister", nil, "Failure preparing request") + } + + resp, err := client.UnregisterSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "Unregister", resp, "Failure sending request") + } + + result, err = client.UnregisterResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "Unregister", resp, "Failure responding to request") + } + + return +} + +// UnregisterPreparer prepares the Unregister request. +func (client ProvidersClient) UnregisterPreparer(resourceProviderNamespace string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/unregister", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// UnregisterSender sends the Unregister request. The method will close the +// http.Response Body if it receives an error. +func (client ProvidersClient) UnregisterSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// UnregisterResponder handles the response to the Unregister request. The method always +// closes the http.Response Body. +func (client ProvidersClient) UnregisterResponder(resp *http.Response) (result Provider, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/resources.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/resources.go new file mode 100644 index 0000000000..f21b50580a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/resources.go @@ -0,0 +1,523 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// Client is the client for the Resources methods of the Resources service. +type Client struct { + ManagementClient +} + +// NewClient creates an instance of the Client client. +func NewClient(subscriptionID string) Client { + return NewClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewClientWithBaseURI creates an instance of the Client client. +func NewClientWithBaseURI(baseURI string, subscriptionID string) Client { + return Client{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckExistence checks whether resource exists. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. resourceProviderNamespace is resource identity. +// parentResourcePath is resource identity. resourceType is resource +// identity. resourceName is resource identity. +func (client Client) CheckExistence(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.Client", "CheckExistence") + } + + req, err := client.CheckExistencePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "CheckExistence", nil, "Failure preparing request") + } + + resp, err := client.CheckExistenceSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.Client", "CheckExistence", resp, "Failure sending request") + } + + result, err = client.CheckExistenceResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "CheckExistence", resp, "Failure responding to request") + } + + return +} + +// CheckExistencePreparer prepares the CheckExistence request. +func (client Client) CheckExistencePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", resourceName), + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsHead(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CheckExistenceSender sends the CheckExistence request. The method will close the +// http.Response Body if it receives an error. +func (client Client) CheckExistenceSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CheckExistenceResponder handles the response to the CheckExistence request. The method always +// closes the http.Response Body. +func (client Client) CheckExistenceResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound), + autorest.ByClosing()) + result.Response = resp + return +} + +// CreateOrUpdate create a resource. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. resourceProviderNamespace is resource identity. +// parentResourcePath is resource identity. resourceType is resource +// identity. resourceName is resource identity. parameters is create or +// update resource parameters. +func (client Client) CreateOrUpdate(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (result GenericResource, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Identity", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Identity.PrincipalID", Name: validation.ReadOnly, Rule: true, Chain: nil}, + {Target: "parameters.Identity.TenantID", Name: validation.ReadOnly, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.Client", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.Client", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client Client) CreateOrUpdatePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", resourceName), + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client Client) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client Client) CreateOrUpdateResponder(resp *http.Response) (result GenericResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete resource and all of its resources. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. resourceProviderNamespace is resource identity. +// parentResourcePath is resource identity. resourceType is resource +// identity. resourceName is resource identity. +func (client Client) Delete(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.Client", "Delete") + } + + req, err := client.DeletePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.Client", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client Client) DeletePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", resourceName), + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client Client) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get returns a resource belonging to a resource group. +// +// resourceGroupName is the name of the resource group. The name is case +// insensitive. resourceProviderNamespace is resource identity. +// parentResourcePath is resource identity. resourceType is resource +// identity. resourceName is resource identity. +func (client Client) Get(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result GenericResource, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.Client", "Get") + } + + req, err := client.GetPreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.Client", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client Client) GetPreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", resourceName), + "resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client Client) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client Client) GetResponder(resp *http.Response) (result GenericResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List get all of the resources under a subscription. +// +// filter is the filter to apply on the operation. expand is the $expand query +// parameter. top is query parameters. If null is passed returns all resource +// groups. +func (client Client) List(filter string, expand string, top *int32) (result ResourceListResult, err error) { + req, err := client.ListPreparer(filter, expand, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.Client", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client Client) ListPreparer(filter string, expand string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resources", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client Client) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client Client) ListResponder(resp *http.Response) (result ResourceListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client Client) ListNextResults(lastResults ResourceListResult) (result ResourceListResult, err error) { + req, err := lastResults.ResourceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.Client", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "List", resp, "Failure responding to next results request") + } + + return +} + +// MoveResources move resources from one resource group to another. The +// resources being moved should all be in the same resource group. This +// method may poll for completion. Polling can be canceled by passing the +// cancel channel argument. The channel will be used to cancel polling and +// any outstanding HTTP requests. +// +// sourceResourceGroupName is source resource group name. parameters is move +// resources' parameters. +func (client Client) MoveResources(sourceResourceGroupName string, parameters MoveInfo, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: sourceResourceGroupName, + Constraints: []validation.Constraint{{Target: "sourceResourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "sourceResourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "sourceResourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "resources.Client", "MoveResources") + } + + req, err := client.MoveResourcesPreparer(sourceResourceGroupName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.Client", "MoveResources", nil, "Failure preparing request") + } + + resp, err := client.MoveResourcesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.Client", "MoveResources", resp, "Failure sending request") + } + + result, err = client.MoveResourcesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.Client", "MoveResources", resp, "Failure responding to request") + } + + return +} + +// MoveResourcesPreparer prepares the MoveResources request. +func (client Client) MoveResourcesPreparer(sourceResourceGroupName string, parameters MoveInfo, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "sourceResourceGroupName": autorest.Encode("path", sourceResourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/moveResources", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// MoveResourcesSender sends the MoveResources request. The method will close the +// http.Response Body if it receives an error. +func (client Client) MoveResourcesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// MoveResourcesResponder handles the response to the MoveResources request. The method always +// closes the http.Response Body. +func (client Client) MoveResourcesResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/tags.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/tags.go new file mode 100644 index 0000000000..ffe8d13220 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/tags.go @@ -0,0 +1,366 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// TagsClient is the client for the Tags methods of the Resources service. +type TagsClient struct { + ManagementClient +} + +// NewTagsClient creates an instance of the TagsClient client. +func NewTagsClient(subscriptionID string) TagsClient { + return NewTagsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewTagsClientWithBaseURI creates an instance of the TagsClient client. +func NewTagsClientWithBaseURI(baseURI string, subscriptionID string) TagsClient { + return TagsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate create a subscription resource tag. +// +// tagName is the name of the tag. +func (client TagsClient) CreateOrUpdate(tagName string) (result TagDetails, err error) { + req, err := client.CreateOrUpdatePreparer(tagName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client TagsClient) CreateOrUpdatePreparer(tagName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "tagName": autorest.Encode("path", tagName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client TagsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client TagsClient) CreateOrUpdateResponder(resp *http.Response) (result TagDetails, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateValue create a subscription resource tag value. +// +// tagName is the name of the tag. tagValue is the value of the tag. +func (client TagsClient) CreateOrUpdateValue(tagName string, tagValue string) (result TagValue, err error) { + req, err := client.CreateOrUpdateValuePreparer(tagName, tagValue) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdateValue", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateValueSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdateValue", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateValueResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdateValue", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdateValuePreparer prepares the CreateOrUpdateValue request. +func (client TagsClient) CreateOrUpdateValuePreparer(tagName string, tagValue string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "tagName": autorest.Encode("path", tagName), + "tagValue": autorest.Encode("path", tagValue), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateValueSender sends the CreateOrUpdateValue request. The method will close the +// http.Response Body if it receives an error. +func (client TagsClient) CreateOrUpdateValueSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateValueResponder handles the response to the CreateOrUpdateValue request. The method always +// closes the http.Response Body. +func (client TagsClient) CreateOrUpdateValueResponder(resp *http.Response) (result TagValue, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete a subscription resource tag. +// +// tagName is the name of the tag. +func (client TagsClient) Delete(tagName string) (result autorest.Response, err error) { + req, err := client.DeletePreparer(tagName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.TagsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client TagsClient) DeletePreparer(tagName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "tagName": autorest.Encode("path", tagName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client TagsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client TagsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// DeleteValue delete a subscription resource tag value. +// +// tagName is the name of the tag. tagValue is the value of the tag. +func (client TagsClient) DeleteValue(tagName string, tagValue string) (result autorest.Response, err error) { + req, err := client.DeleteValuePreparer(tagName, tagValue) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "DeleteValue", nil, "Failure preparing request") + } + + resp, err := client.DeleteValueSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "DeleteValue", resp, "Failure sending request") + } + + result, err = client.DeleteValueResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.TagsClient", "DeleteValue", resp, "Failure responding to request") + } + + return +} + +// DeleteValuePreparer prepares the DeleteValue request. +func (client TagsClient) DeleteValuePreparer(tagName string, tagValue string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "tagName": autorest.Encode("path", tagName), + "tagValue": autorest.Encode("path", tagValue), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteValueSender sends the DeleteValue request. The method will close the +// http.Response Body if it receives an error. +func (client TagsClient) DeleteValueSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteValueResponder handles the response to the DeleteValue request. The method always +// closes the http.Response Body. +func (client TagsClient) DeleteValueResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// List get a list of subscription resource tags. +func (client TagsClient) List() (result TagsListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client TagsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client TagsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client TagsClient) ListResponder(resp *http.Response) (result TagsListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client TagsClient) ListNextResults(lastResults TagsListResult) (result TagsListResult, err error) { + req, err := lastResults.TagsListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/version.go new file mode 100644 index 0000000000..0574d6b275 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/version.go @@ -0,0 +1,43 @@ +package resources + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "5" + minor = "0" + patch = "0" + // Always begin a "tag" with a dash (as per http://semver.org) + tag = "-beta" + semVerFormat = "%s.%s.%s%s" + userAgentFormat = "Azure-SDK-for-Go/%s arm-%s/%s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "resources", "2016-07-01") +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/client.go new file mode 100644 index 0000000000..d38fe8a6cf --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/client.go @@ -0,0 +1,55 @@ +// Package subscriptions implements the Azure ARM Subscriptions service API +// version 2015-11-01. +// +package subscriptions + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Subscriptions + APIVersion = "2015-11-01" + + // DefaultBaseURI is the default URI used for the service Subscriptions + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Subscriptions. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string +} + +// New creates an instance of the ManagementClient client. +func New() ManagementClient { + return NewWithBaseURI(DefaultBaseURI) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/models.go new file mode 100644 index 0000000000..9235a5732a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/models.go @@ -0,0 +1,101 @@ +package subscriptions + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// Location is location information. +type Location struct { + ID *string `json:"id,omitempty"` + SubscriptionID *string `json:"subscriptionId,omitempty"` + Name *string `json:"name,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Latitude *string `json:"latitude,omitempty"` + Longitude *string `json:"longitude,omitempty"` +} + +// LocationListResult is location list operation response. +type LocationListResult struct { + autorest.Response `json:"-"` + Value *[]Location `json:"value,omitempty"` +} + +// Subscription is subscription information. +type Subscription struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + SubscriptionID *string `json:"subscriptionId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + State *string `json:"state,omitempty"` + SubscriptionPolicies *SubscriptionPolicies `json:"subscriptionPolicies,omitempty"` +} + +// SubscriptionListResult is subscription list operation response. +type SubscriptionListResult struct { + autorest.Response `json:"-"` + Value *[]Subscription `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SubscriptionListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SubscriptionListResult) SubscriptionListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SubscriptionPolicies is subscription policies. +type SubscriptionPolicies struct { + LocationPlacementID *string `json:"locationPlacementId,omitempty"` + QuotaID *string `json:"quotaId,omitempty"` +} + +// TenantIDDescription is tenant Id information +type TenantIDDescription struct { + ID *string `json:"id,omitempty"` + TenantID *string `json:"tenantId,omitempty"` +} + +// TenantListResult is tenant Ids information. +type TenantListResult struct { + autorest.Response `json:"-"` + Value *[]TenantIDDescription `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// TenantListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client TenantListResult) TenantListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/subscriptions.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/subscriptions.go new file mode 100644 index 0000000000..ad95168ec3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/subscriptions.go @@ -0,0 +1,239 @@ +package subscriptions + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// Client is the client for the Subscriptions methods of the Subscriptions +// service. +type Client struct { + ManagementClient +} + +// NewClient creates an instance of the Client client. +func NewClient() Client { + return NewClientWithBaseURI(DefaultBaseURI) +} + +// NewClientWithBaseURI creates an instance of the Client client. +func NewClientWithBaseURI(baseURI string) Client { + return Client{NewWithBaseURI(baseURI)} +} + +// Get gets details about particular subscription. +// +// subscriptionID is id of the subscription. +func (client Client) Get(subscriptionID string) (result Subscription, err error) { + req, err := client.GetPreparer(subscriptionID) + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "subscriptions.Client", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client Client) GetPreparer(subscriptionID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", subscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client Client) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client Client) GetResponder(resp *http.Response) (result Subscription, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of the subscriptionIds. +func (client Client) List() (result SubscriptionListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "subscriptions.Client", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client Client) ListPreparer() (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions"), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client Client) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client Client) ListResponder(resp *http.Response) (result SubscriptionListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client Client) ListNextResults(lastResults SubscriptionListResult) (result SubscriptionListResult, err error) { + req, err := lastResults.SubscriptionListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "subscriptions.Client", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListLocations gets a list of the subscription locations. +// +// subscriptionID is id of the subscription +func (client Client) ListLocations(subscriptionID string) (result LocationListResult, err error) { + req, err := client.ListLocationsPreparer(subscriptionID) + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "ListLocations", nil, "Failure preparing request") + } + + resp, err := client.ListLocationsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions.Client", "ListLocations", resp, "Failure sending request") + } + + result, err = client.ListLocationsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "subscriptions.Client", "ListLocations", resp, "Failure responding to request") + } + + return +} + +// ListLocationsPreparer prepares the ListLocations request. +func (client Client) ListLocationsPreparer(subscriptionID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", subscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/locations", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListLocationsSender sends the ListLocations request. The method will close the +// http.Response Body if it receives an error. +func (client Client) ListLocationsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListLocationsResponder handles the response to the ListLocations request. The method always +// closes the http.Response Body. +func (client Client) ListLocationsResponder(resp *http.Response) (result LocationListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/tenants.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/tenants.go new file mode 100644 index 0000000000..b20e3860f9 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/tenants.go @@ -0,0 +1,119 @@ +package subscriptions + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// TenantsClient is the client for the Tenants methods of the Subscriptions +// service. +type TenantsClient struct { + ManagementClient +} + +// NewTenantsClient creates an instance of the TenantsClient client. +func NewTenantsClient() TenantsClient { + return NewTenantsClientWithBaseURI(DefaultBaseURI) +} + +// NewTenantsClientWithBaseURI creates an instance of the TenantsClient client. +func NewTenantsClientWithBaseURI(baseURI string) TenantsClient { + return TenantsClient{NewWithBaseURI(baseURI)} +} + +// List gets a list of the tenantIds. +func (client TenantsClient) List() (result TenantListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions.TenantsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions.TenantsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "subscriptions.TenantsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client TenantsClient) ListPreparer() (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/tenants"), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client TenantsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client TenantsClient) ListResponder(resp *http.Response) (result TenantListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client TenantsClient) ListNextResults(lastResults TenantListResult) (result TenantListResult, err error) { + req, err := lastResults.TenantListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions.TenantsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions.TenantsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "subscriptions.TenantsClient", "List", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/version.go new file mode 100644 index 0000000000..c85dc179cd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions/version.go @@ -0,0 +1,43 @@ +package subscriptions + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "5" + minor = "0" + patch = "0" + // Always begin a "tag" with a dash (as per http://semver.org) + tag = "-beta" + semVerFormat = "%s.%s.%s%s" + userAgentFormat = "Azure-SDK-for-Go/%s arm-%s/%s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "subscriptions", "2015-11-01") +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go new file mode 100644 index 0000000000..d9c54e795e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go @@ -0,0 +1,711 @@ +package storage + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// AccountsClient is the the Storage Management Client. +type AccountsClient struct { + ManagementClient +} + +// NewAccountsClient creates an instance of the AccountsClient client. +func NewAccountsClient(subscriptionID string) AccountsClient { + return NewAccountsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewAccountsClientWithBaseURI creates an instance of the AccountsClient +// client. +func NewAccountsClientWithBaseURI(baseURI string, subscriptionID string) AccountsClient { + return AccountsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckNameAvailability checks that account name is valid and is not in use. +// +// accountName is the name of the storage account within the specified +// resource group. Storage account names must be between 3 and 24 characters +// in length and use numbers and lower-case letters only. +func (client AccountsClient) CheckNameAvailability(accountName AccountCheckNameAvailabilityParameters) (result CheckNameAvailabilityResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName.Name", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "accountName.Type", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "CheckNameAvailability") + } + + req, err := client.CheckNameAvailabilityPreparer(accountName) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "CheckNameAvailability", nil, "Failure preparing request") + } + + resp, err := client.CheckNameAvailabilitySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "CheckNameAvailability", resp, "Failure sending request") + } + + result, err = client.CheckNameAvailabilityResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "CheckNameAvailability", resp, "Failure responding to request") + } + + return +} + +// CheckNameAvailabilityPreparer prepares the CheckNameAvailability request. +func (client AccountsClient) CheckNameAvailabilityPreparer(accountName AccountCheckNameAvailabilityParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/checkNameAvailability", pathParameters), + autorest.WithJSON(accountName), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CheckNameAvailabilitySender sends the CheckNameAvailability request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) CheckNameAvailabilitySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CheckNameAvailabilityResponder handles the response to the CheckNameAvailability request. The method always +// closes the http.Response Body. +func (client AccountsClient) CheckNameAvailabilityResponder(resp *http.Response) (result CheckNameAvailabilityResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Create asynchronously creates a new storage account with the specified +// parameters. If an account is already created and subsequent create request +// is issued with different properties, the account properties will be +// updated. If an account is already created and subsequent create or update +// request is issued with exact same set of properties, the request will +// succeed. This method may poll for completion. Polling can be canceled by +// passing the cancel channel argument. The channel will be used to cancel +// polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group within the user's +// subscription. accountName is the name of the storage account within the +// specified resource group. Storage account names must be between 3 and 24 +// characters in length and use numbers and lower-case letters only. +// parameters is the parameters to provide for the created account. +func (client AccountsClient) Create(resourceGroupName string, accountName string, parameters AccountCreateParameters, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil}, + {Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Sku", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.Sku.Tier", Name: validation.ReadOnly, Rule: true, Chain: nil}}}, + {Target: "parameters.Location", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.CustomDomain", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.CustomDomain.Name", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.Properties.Encryption", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.Encryption.Services", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.Encryption.Services.Blob", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.Encryption.Services.Blob.LastEnabledTime", Name: validation.ReadOnly, Rule: true, Chain: nil}}}, + }}, + {Target: "parameters.Properties.Encryption.KeySource", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "Create") + } + + req, err := client.CreatePreparer(resourceGroupName, accountName, parameters, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", nil, "Failure preparing request") + } + + resp, err := client.CreateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", resp, "Failure sending request") + } + + result, err = client.CreateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", resp, "Failure responding to request") + } + + return +} + +// CreatePreparer prepares the Create request. +func (client AccountsClient) CreatePreparer(resourceGroupName string, accountName string, parameters AccountCreateParameters, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "accountName": autorest.Encode("path", accountName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateSender sends the Create request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) CreateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateResponder handles the response to the Create request. The method always +// closes the http.Response Body. +func (client AccountsClient) CreateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete deletes a storage account in Microsoft Azure. +// +// resourceGroupName is the name of the resource group within the user's +// subscription. accountName is the name of the storage account within the +// specified resource group. Storage account names must be between 3 and 24 +// characters in length and use numbers and lower-case letters only. +func (client AccountsClient) Delete(resourceGroupName string, accountName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil}, + {Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "Delete") + } + + req, err := client.DeletePreparer(resourceGroupName, accountName) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client AccountsClient) DeletePreparer(resourceGroupName string, accountName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "accountName": autorest.Encode("path", accountName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client AccountsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// GetProperties returns the properties for the specified storage account +// including but not limited to name, account type, location, and account +// status. The ListKeys operation should be used to retrieve storage keys. +// +// resourceGroupName is the name of the resource group within the user's +// subscription. accountName is the name of the storage account within the +// specified resource group. Storage account names must be between 3 and 24 +// characters in length and use numbers and lower-case letters only. +func (client AccountsClient) GetProperties(resourceGroupName string, accountName string) (result Account, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil}, + {Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "GetProperties") + } + + req, err := client.GetPropertiesPreparer(resourceGroupName, accountName) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "GetProperties", nil, "Failure preparing request") + } + + resp, err := client.GetPropertiesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "GetProperties", resp, "Failure sending request") + } + + result, err = client.GetPropertiesResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "GetProperties", resp, "Failure responding to request") + } + + return +} + +// GetPropertiesPreparer prepares the GetProperties request. +func (client AccountsClient) GetPropertiesPreparer(resourceGroupName string, accountName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "accountName": autorest.Encode("path", accountName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetPropertiesSender sends the GetProperties request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) GetPropertiesSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetPropertiesResponder handles the response to the GetProperties request. The method always +// closes the http.Response Body. +func (client AccountsClient) GetPropertiesResponder(resp *http.Response) (result Account, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists all the storage accounts available under the subscription. Note +// that storage keys are not returned; use the ListKeys operation for this. +func (client AccountsClient) List() (result AccountListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client AccountsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client AccountsClient) ListResponder(resp *http.Response) (result AccountListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroup lists all the storage accounts available under the +// given resource group. Note that storage keys are not returned; use the +// ListKeys operation for this. +// +// resourceGroupName is the name of the resource group within the user's +// subscription. +func (client AccountsClient) ListByResourceGroup(resourceGroupName string) (result AccountListResult, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "ListByResourceGroup", nil, "Failure preparing request") + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "ListByResourceGroup", resp, "Failure sending request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client AccountsClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client AccountsClient) ListByResourceGroupResponder(resp *http.Response) (result AccountListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListKeys lists the access keys for the specified storage account. +// +// resourceGroupName is the name of the resource group. accountName is the +// name of the storage account. +func (client AccountsClient) ListKeys(resourceGroupName string, accountName string) (result AccountListKeysResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil}, + {Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "ListKeys") + } + + req, err := client.ListKeysPreparer(resourceGroupName, accountName) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "ListKeys", nil, "Failure preparing request") + } + + resp, err := client.ListKeysSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "ListKeys", resp, "Failure sending request") + } + + result, err = client.ListKeysResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListKeys", resp, "Failure responding to request") + } + + return +} + +// ListKeysPreparer prepares the ListKeys request. +func (client AccountsClient) ListKeysPreparer(resourceGroupName string, accountName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "accountName": autorest.Encode("path", accountName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/listKeys", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListKeysSender sends the ListKeys request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) ListKeysSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListKeysResponder handles the response to the ListKeys request. The method always +// closes the http.Response Body. +func (client AccountsClient) ListKeysResponder(resp *http.Response) (result AccountListKeysResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RegenerateKey regenerates the access keys for the specified storage account. +// +// resourceGroupName is the name of the resource group within the user's +// subscription. accountName is the name of the storage account within the +// specified resource group. Storage account names must be between 3 and 24 +// characters in length and use numbers and lower-case letters only. +// regenerateKey is specifies name of the key which should be regenerated. +// key1 or key2 for the default keys +func (client AccountsClient) RegenerateKey(resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (result AccountListKeysResult, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil}, + {Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}, + {TargetValue: regenerateKey, + Constraints: []validation.Constraint{{Target: "regenerateKey.KeyName", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "RegenerateKey") + } + + req, err := client.RegenerateKeyPreparer(resourceGroupName, accountName, regenerateKey) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "RegenerateKey", nil, "Failure preparing request") + } + + resp, err := client.RegenerateKeySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "RegenerateKey", resp, "Failure sending request") + } + + result, err = client.RegenerateKeyResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "RegenerateKey", resp, "Failure responding to request") + } + + return +} + +// RegenerateKeyPreparer prepares the RegenerateKey request. +func (client AccountsClient) RegenerateKeyPreparer(resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "accountName": autorest.Encode("path", accountName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/regenerateKey", pathParameters), + autorest.WithJSON(regenerateKey), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// RegenerateKeySender sends the RegenerateKey request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) RegenerateKeySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// RegenerateKeyResponder handles the response to the RegenerateKey request. The method always +// closes the http.Response Body. +func (client AccountsClient) RegenerateKeyResponder(resp *http.Response) (result AccountListKeysResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Update the update operation can be used to update the account type, +// encryption, or tags for a storage account. It can also be used to map the +// account to a custom domain. Only one custom domain is supported per +// storage account and. replacement/change of custom domain is not supported. +// In order to replace an old custom domain, the old value must be +// cleared/unregistered before a new value may be set. Update of multiple +// properties is supported. This call does not change the storage keys for +// the account. If you want to change storage account keys, use the +// regenerate keys operation. The location and name of the storage account +// cannot be changed after creation. +// +// resourceGroupName is the name of the resource group within the user's +// subscription. accountName is the name of the storage account within the +// specified resource group. Storage account names must be between 3 and 24 +// characters in length and use numbers and lower-case letters only. +// parameters is the parameters to provide for the updated account. +func (client AccountsClient) Update(resourceGroupName string, accountName string, parameters AccountUpdateParameters) (result Account, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: accountName, + Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil}, + {Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "Update") + } + + req, err := client.UpdatePreparer(resourceGroupName, accountName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "Update", nil, "Failure preparing request") + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.AccountsClient", "Update", resp, "Failure sending request") + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client AccountsClient) UpdatePreparer(resourceGroupName string, accountName string, parameters AccountUpdateParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "accountName": autorest.Encode("path", accountName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client AccountsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client AccountsClient) UpdateResponder(resp *http.Response) (result Account, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/client.go new file mode 100644 index 0000000000..68708dbf24 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/client.go @@ -0,0 +1,58 @@ +// Package storage implements the Azure ARM Storage service API version +// 2016-01-01. +// +// The Storage Management Client. +package storage + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Storage + APIVersion = "2016-01-01" + + // DefaultBaseURI is the default URI used for the service Storage + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Storage. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/models.go new file mode 100644 index 0000000000..a4a4d2be41 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/models.go @@ -0,0 +1,295 @@ +package storage + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" +) + +// AccessTier enumerates the values for access tier. +type AccessTier string + +const ( + // Cool specifies the cool state for access tier. + Cool AccessTier = "Cool" + // Hot specifies the hot state for access tier. + Hot AccessTier = "Hot" +) + +// AccountStatus enumerates the values for account status. +type AccountStatus string + +const ( + // Available specifies the available state for account status. + Available AccountStatus = "Available" + // Unavailable specifies the unavailable state for account status. + Unavailable AccountStatus = "Unavailable" +) + +// KeyPermission enumerates the values for key permission. +type KeyPermission string + +const ( + // FULL specifies the full state for key permission. + FULL KeyPermission = "FULL" + // READ specifies the read state for key permission. + READ KeyPermission = "READ" +) + +// Kind enumerates the values for kind. +type Kind string + +const ( + // BlobStorage specifies the blob storage state for kind. + BlobStorage Kind = "BlobStorage" + // Storage specifies the storage state for kind. + Storage Kind = "Storage" +) + +// ProvisioningState enumerates the values for provisioning state. +type ProvisioningState string + +const ( + // Creating specifies the creating state for provisioning state. + Creating ProvisioningState = "Creating" + // ResolvingDNS specifies the resolving dns state for provisioning state. + ResolvingDNS ProvisioningState = "ResolvingDNS" + // Succeeded specifies the succeeded state for provisioning state. + Succeeded ProvisioningState = "Succeeded" +) + +// Reason enumerates the values for reason. +type Reason string + +const ( + // AccountNameInvalid specifies the account name invalid state for reason. + AccountNameInvalid Reason = "AccountNameInvalid" + // AlreadyExists specifies the already exists state for reason. + AlreadyExists Reason = "AlreadyExists" +) + +// SkuName enumerates the values for sku name. +type SkuName string + +const ( + // PremiumLRS specifies the premium lrs state for sku name. + PremiumLRS SkuName = "Premium_LRS" + // StandardGRS specifies the standard grs state for sku name. + StandardGRS SkuName = "Standard_GRS" + // StandardLRS specifies the standard lrs state for sku name. + StandardLRS SkuName = "Standard_LRS" + // StandardRAGRS specifies the standard ragrs state for sku name. + StandardRAGRS SkuName = "Standard_RAGRS" + // StandardZRS specifies the standard zrs state for sku name. + StandardZRS SkuName = "Standard_ZRS" +) + +// SkuTier enumerates the values for sku tier. +type SkuTier string + +const ( + // Premium specifies the premium state for sku tier. + Premium SkuTier = "Premium" + // Standard specifies the standard state for sku tier. + Standard SkuTier = "Standard" +) + +// UsageUnit enumerates the values for usage unit. +type UsageUnit string + +const ( + // Bytes specifies the bytes state for usage unit. + Bytes UsageUnit = "Bytes" + // BytesPerSecond specifies the bytes per second state for usage unit. + BytesPerSecond UsageUnit = "BytesPerSecond" + // Count specifies the count state for usage unit. + Count UsageUnit = "Count" + // CountsPerSecond specifies the counts per second state for usage unit. + CountsPerSecond UsageUnit = "CountsPerSecond" + // Percent specifies the percent state for usage unit. + Percent UsageUnit = "Percent" + // Seconds specifies the seconds state for usage unit. + Seconds UsageUnit = "Seconds" +) + +// Account is the storage account. +type Account struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Sku *Sku `json:"sku,omitempty"` + Kind Kind `json:"kind,omitempty"` + Properties *AccountProperties `json:"properties,omitempty"` +} + +// AccountCheckNameAvailabilityParameters is +type AccountCheckNameAvailabilityParameters struct { + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` +} + +// AccountCreateParameters is the parameters to provide for the account. +type AccountCreateParameters struct { + Sku *Sku `json:"sku,omitempty"` + Kind Kind `json:"kind,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *AccountPropertiesCreateParameters `json:"properties,omitempty"` +} + +// AccountKey is an access key for the storage account. +type AccountKey struct { + KeyName *string `json:"keyName,omitempty"` + Value *string `json:"value,omitempty"` + Permissions KeyPermission `json:"permissions,omitempty"` +} + +// AccountListKeysResult is the ListKeys operation response. +type AccountListKeysResult struct { + autorest.Response `json:"-"` + Keys *[]AccountKey `json:"keys,omitempty"` +} + +// AccountListResult is the list storage accounts operation response. +type AccountListResult struct { + autorest.Response `json:"-"` + Value *[]Account `json:"value,omitempty"` +} + +// AccountProperties is +type AccountProperties struct { + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` + PrimaryEndpoints *Endpoints `json:"primaryEndpoints,omitempty"` + PrimaryLocation *string `json:"primaryLocation,omitempty"` + StatusOfPrimary AccountStatus `json:"statusOfPrimary,omitempty"` + LastGeoFailoverTime *date.Time `json:"lastGeoFailoverTime,omitempty"` + SecondaryLocation *string `json:"secondaryLocation,omitempty"` + StatusOfSecondary AccountStatus `json:"statusOfSecondary,omitempty"` + CreationTime *date.Time `json:"creationTime,omitempty"` + CustomDomain *CustomDomain `json:"customDomain,omitempty"` + SecondaryEndpoints *Endpoints `json:"secondaryEndpoints,omitempty"` + Encryption *Encryption `json:"encryption,omitempty"` + AccessTier AccessTier `json:"accessTier,omitempty"` +} + +// AccountPropertiesCreateParameters is +type AccountPropertiesCreateParameters struct { + CustomDomain *CustomDomain `json:"customDomain,omitempty"` + Encryption *Encryption `json:"encryption,omitempty"` + AccessTier AccessTier `json:"accessTier,omitempty"` +} + +// AccountPropertiesUpdateParameters is +type AccountPropertiesUpdateParameters struct { + CustomDomain *CustomDomain `json:"customDomain,omitempty"` + Encryption *Encryption `json:"encryption,omitempty"` + AccessTier AccessTier `json:"accessTier,omitempty"` +} + +// AccountRegenerateKeyParameters is +type AccountRegenerateKeyParameters struct { + KeyName *string `json:"keyName,omitempty"` +} + +// AccountUpdateParameters is the parameters to provide for the account. +type AccountUpdateParameters struct { + Sku *Sku `json:"sku,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *AccountPropertiesUpdateParameters `json:"properties,omitempty"` +} + +// CheckNameAvailabilityResult is the CheckNameAvailability operation response. +type CheckNameAvailabilityResult struct { + autorest.Response `json:"-"` + NameAvailable *bool `json:"nameAvailable,omitempty"` + Reason Reason `json:"reason,omitempty"` + Message *string `json:"message,omitempty"` +} + +// CustomDomain is the custom domain assigned to this storage account. This +// can be set via Update. +type CustomDomain struct { + Name *string `json:"name,omitempty"` + UseSubDomain *bool `json:"useSubDomain,omitempty"` +} + +// Encryption is the encryption settings on the account. +type Encryption struct { + Services *EncryptionServices `json:"services,omitempty"` + KeySource *string `json:"keySource,omitempty"` +} + +// EncryptionService is an encrypted service. +type EncryptionService struct { + Enabled *bool `json:"enabled,omitempty"` + LastEnabledTime *date.Time `json:"lastEnabledTime,omitempty"` +} + +// EncryptionServices is the encrypted services. +type EncryptionServices struct { + Blob *EncryptionService `json:"blob,omitempty"` +} + +// Endpoints is the URIs that are used to perform a retrieval of a public +// blob, queue or table object. +type Endpoints struct { + Blob *string `json:"blob,omitempty"` + Queue *string `json:"queue,omitempty"` + Table *string `json:"table,omitempty"` + File *string `json:"file,omitempty"` +} + +// Resource is +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// Sku is the SKU of the storage account. +type Sku struct { + Name SkuName `json:"name,omitempty"` + Tier SkuTier `json:"tier,omitempty"` +} + +// Usage is describes Storage Resource Usage. +type Usage struct { + Unit UsageUnit `json:"unit,omitempty"` + CurrentValue *int32 `json:"currentValue,omitempty"` + Limit *int32 `json:"limit,omitempty"` + Name *UsageName `json:"name,omitempty"` +} + +// UsageListResult is the List Usages operation response. +type UsageListResult struct { + autorest.Response `json:"-"` + Value *[]Usage `json:"value,omitempty"` +} + +// UsageName is the Usage Names. +type UsageName struct { + Value *string `json:"value,omitempty"` + LocalizedValue *string `json:"localizedValue,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go new file mode 100644 index 0000000000..866efc9c31 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go @@ -0,0 +1,101 @@ +package storage + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// UsageOperationsClient is the the Storage Management Client. +type UsageOperationsClient struct { + ManagementClient +} + +// NewUsageOperationsClient creates an instance of the UsageOperationsClient +// client. +func NewUsageOperationsClient(subscriptionID string) UsageOperationsClient { + return NewUsageOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewUsageOperationsClientWithBaseURI creates an instance of the +// UsageOperationsClient client. +func NewUsageOperationsClientWithBaseURI(baseURI string, subscriptionID string) UsageOperationsClient { + return UsageOperationsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List gets the current usage count and the limit for the resources under the +// subscription. +func (client UsageOperationsClient) List() (result UsageListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "storage.UsageOperationsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "storage.UsageOperationsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "storage.UsageOperationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client UsageOperationsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/usages", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client UsageOperationsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client UsageOperationsClient) ListResponder(resp *http.Response) (result UsageListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/version.go new file mode 100644 index 0000000000..cfdcee618d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/storage/version.go @@ -0,0 +1,43 @@ +package storage + +// Copyright (c) Microsoft and contributors. 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. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "5" + minor = "0" + patch = "0" + // Always begin a "tag" with a dash (as per http://semver.org) + tag = "-beta" + semVerFormat = "%s.%s.%s%s" + userAgentFormat = "Azure-SDK-for-Go/%s arm-%s/%s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "storage", "2016-01-01") +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md new file mode 100644 index 0000000000..0ab099848b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md @@ -0,0 +1,5 @@ +# Azure Storage SDK for Go + +The `github.com/Azure/azure-sdk-for-go/storage` package is used to perform operations in Azure Storage Service. To manage your storage accounts (Azure Resource Manager / ARM), use the [github.com/Azure/azure-sdk-for-go/arm/storage](../arm/storage) package. For your classic storage accounts (Azure Service Management / ASM), use [github.com/Azure/azure-sdk-for-go/management/storageservice](../management/storageservice) package. + +This package includes support for [Azure Storage Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/) \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go new file mode 100644 index 0000000000..4207cfec6e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go @@ -0,0 +1,1133 @@ +package storage + +import ( + "bytes" + "encoding/xml" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" +) + +// BlobStorageClient contains operations for Microsoft Azure Blob Storage +// Service. +type BlobStorageClient struct { + client Client +} + +// A Container is an entry in ContainerListResponse. +type Container struct { + Name string `xml:"Name"` + Properties ContainerProperties `xml:"Properties"` + // TODO (ahmetalpbalkan) Metadata +} + +// ContainerProperties contains various properties of a container returned from +// various endpoints like ListContainers. +type ContainerProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` + LeaseStatus string `xml:"LeaseStatus"` + LeaseState string `xml:"LeaseState"` + LeaseDuration string `xml:"LeaseDuration"` + // TODO (ahmetalpbalkan) remaining fields +} + +// ContainerListResponse contains the response fields from +// ListContainers call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +type ContainerListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + NextMarker string `xml:"NextMarker"` + MaxResults int64 `xml:"MaxResults"` + Containers []Container `xml:"Containers>Container"` +} + +// A Blob is an entry in BlobListResponse. +type Blob struct { + Name string `xml:"Name"` + Properties BlobProperties `xml:"Properties"` + Metadata BlobMetadata `xml:"Metadata"` +} + +// BlobMetadata is a set of custom name/value pairs. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179404.aspx +type BlobMetadata map[string]string + +type blobMetadataEntries struct { + Entries []blobMetadataEntry `xml:",any"` +} +type blobMetadataEntry struct { + XMLName xml.Name + Value string `xml:",chardata"` +} + +// UnmarshalXML converts the xml:Metadata into Metadata map +func (bm *BlobMetadata) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var entries blobMetadataEntries + if err := d.DecodeElement(&entries, &start); err != nil { + return err + } + for _, entry := range entries.Entries { + if *bm == nil { + *bm = make(BlobMetadata) + } + (*bm)[strings.ToLower(entry.XMLName.Local)] = entry.Value + } + return nil +} + +// MarshalXML implements the xml.Marshaler interface. It encodes +// metadata name/value pairs as they would appear in an Azure +// ListBlobs response. +func (bm BlobMetadata) MarshalXML(enc *xml.Encoder, start xml.StartElement) error { + entries := make([]blobMetadataEntry, 0, len(bm)) + for k, v := range bm { + entries = append(entries, blobMetadataEntry{ + XMLName: xml.Name{Local: http.CanonicalHeaderKey(k)}, + Value: v, + }) + } + return enc.EncodeElement(blobMetadataEntries{ + Entries: entries, + }, start) +} + +// BlobProperties contains various properties of a blob +// returned in various endpoints like ListBlobs or GetBlobProperties. +type BlobProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` + ContentMD5 string `xml:"Content-MD5"` + ContentLength int64 `xml:"Content-Length"` + ContentType string `xml:"Content-Type"` + ContentEncoding string `xml:"Content-Encoding"` + CacheControl string `xml:"Cache-Control"` + ContentLanguage string `xml:"Cache-Language"` + BlobType BlobType `xml:"x-ms-blob-blob-type"` + SequenceNumber int64 `xml:"x-ms-blob-sequence-number"` + CopyID string `xml:"CopyId"` + CopyStatus string `xml:"CopyStatus"` + CopySource string `xml:"CopySource"` + CopyProgress string `xml:"CopyProgress"` + CopyCompletionTime string `xml:"CopyCompletionTime"` + CopyStatusDescription string `xml:"CopyStatusDescription"` + LeaseStatus string `xml:"LeaseStatus"` +} + +// BlobHeaders contains various properties of a blob and is an entry +// in SetBlobProperties +type BlobHeaders struct { + ContentMD5 string `header:"x-ms-blob-content-md5"` + ContentLanguage string `header:"x-ms-blob-content-language"` + ContentEncoding string `header:"x-ms-blob-content-encoding"` + ContentType string `header:"x-ms-blob-content-type"` + CacheControl string `header:"x-ms-blob-cache-control"` +} + +// BlobListResponse contains the response fields from ListBlobs call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +type BlobListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + NextMarker string `xml:"NextMarker"` + MaxResults int64 `xml:"MaxResults"` + Blobs []Blob `xml:"Blobs>Blob"` + + // BlobPrefix is used to traverse blobs as if it were a file system. + // It is returned if ListBlobsParameters.Delimiter is specified. + // The list here can be thought of as "folders" that may contain + // other folders or blobs. + BlobPrefixes []string `xml:"Blobs>BlobPrefix>Name"` + + // Delimiter is used to traverse blobs as if it were a file system. + // It is returned if ListBlobsParameters.Delimiter is specified. + Delimiter string `xml:"Delimiter"` +} + +// ListContainersParameters defines the set of customizable parameters to make a +// List Containers call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +type ListContainersParameters struct { + Prefix string + Marker string + Include string + MaxResults uint + Timeout uint +} + +func (p ListContainersParameters) getParameters() url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// ListBlobsParameters defines the set of customizable +// parameters to make a List Blobs call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +type ListBlobsParameters struct { + Prefix string + Delimiter string + Marker string + Include string + MaxResults uint + Timeout uint +} + +func (p ListBlobsParameters) getParameters() url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Delimiter != "" { + out.Set("delimiter", p.Delimiter) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// BlobType defines the type of the Azure Blob. +type BlobType string + +// Types of page blobs +const ( + BlobTypeBlock BlobType = "BlockBlob" + BlobTypePage BlobType = "PageBlob" + BlobTypeAppend BlobType = "AppendBlob" +) + +// PageWriteType defines the type updates that are going to be +// done on the page blob. +type PageWriteType string + +// Types of operations on page blobs +const ( + PageWriteTypeUpdate PageWriteType = "update" + PageWriteTypeClear PageWriteType = "clear" +) + +const ( + blobCopyStatusPending = "pending" + blobCopyStatusSuccess = "success" + blobCopyStatusAborted = "aborted" + blobCopyStatusFailed = "failed" +) + +// BlockListType is used to filter out types of blocks in a Get Blocks List call +// for a block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx for all +// block types. +type BlockListType string + +// Filters for listing blocks in block blobs +const ( + BlockListTypeAll BlockListType = "all" + BlockListTypeCommitted BlockListType = "committed" + BlockListTypeUncommitted BlockListType = "uncommitted" +) + +// ContainerAccessType defines the access level to the container from a public +// request. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx and "x-ms- +// blob-public-access" header. +type ContainerAccessType string + +// Access options for containers +const ( + ContainerAccessTypePrivate ContainerAccessType = "" + ContainerAccessTypeBlob ContainerAccessType = "blob" + ContainerAccessTypeContainer ContainerAccessType = "container" +) + +// Maximum sizes (per REST API) for various concepts +const ( + MaxBlobBlockSize = 4 * 1024 * 1024 + MaxBlobPageSize = 4 * 1024 * 1024 +) + +// BlockStatus defines states a block for a block blob can +// be in. +type BlockStatus string + +// List of statuses that can be used to refer to a block in a block list +const ( + BlockStatusUncommitted BlockStatus = "Uncommitted" + BlockStatusCommitted BlockStatus = "Committed" + BlockStatusLatest BlockStatus = "Latest" +) + +// Block is used to create Block entities for Put Block List +// call. +type Block struct { + ID string + Status BlockStatus +} + +// BlockListResponse contains the response fields from Get Block List call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx +type BlockListResponse struct { + XMLName xml.Name `xml:"BlockList"` + CommittedBlocks []BlockResponse `xml:"CommittedBlocks>Block"` + UncommittedBlocks []BlockResponse `xml:"UncommittedBlocks>Block"` +} + +// BlockResponse contains the block information returned +// in the GetBlockListCall. +type BlockResponse struct { + Name string `xml:"Name"` + Size int64 `xml:"Size"` +} + +// GetPageRangesResponse contains the reponse fields from +// Get Page Ranges call. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +type GetPageRangesResponse struct { + XMLName xml.Name `xml:"PageList"` + PageList []PageRange `xml:"PageRange"` +} + +// PageRange contains information about a page of a page blob from +// Get Pages Range call. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +type PageRange struct { + Start int64 `xml:"Start"` + End int64 `xml:"End"` +} + +var ( + errBlobCopyAborted = errors.New("storage: blob copy is aborted") + errBlobCopyIDMismatch = errors.New("storage: blob copy id is a mismatch") +) + +// ListContainers returns the list of containers in a storage account along with +// pagination token and other response details. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +func (b BlobStorageClient) ListContainers(params ListContainersParameters) (ContainerListResponse, error) { + q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) + uri := b.client.getEndpoint(blobServiceName, "", q) + headers := b.client.getStandardHeaders() + + var out ContainerListResponse + resp, err := b.client.exec("GET", uri, headers, nil) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// CreateContainer creates a blob container within the storage account +// with given name and access level. Returns error if container already exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx +func (b BlobStorageClient) CreateContainer(name string, access ContainerAccessType) error { + resp, err := b.createContainer(name, access) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// CreateContainerIfNotExists creates a blob container if it does not exist. Returns +// true if container is newly created or false if container already exists. +func (b BlobStorageClient) CreateContainerIfNotExists(name string, access ContainerAccessType) (bool, error) { + resp, err := b.createContainer(name, access) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { + return resp.statusCode == http.StatusCreated, nil + } + } + return false, err +} + +func (b BlobStorageClient) createContainer(name string, access ContainerAccessType) (*storageResponse, error) { + verb := "PUT" + uri := b.client.getEndpoint(blobServiceName, pathForContainer(name), url.Values{"restype": {"container"}}) + + headers := b.client.getStandardHeaders() + if access != "" { + headers["x-ms-blob-public-access"] = string(access) + } + return b.client.exec(verb, uri, headers, nil) +} + +// ContainerExists returns true if a container with given name exists +// on the storage account, otherwise returns false. +func (b BlobStorageClient) ContainerExists(name string) (bool, error) { + verb := "HEAD" + uri := b.client.getEndpoint(blobServiceName, pathForContainer(name), url.Values{"restype": {"container"}}) + headers := b.client.getStandardHeaders() + + resp, err := b.client.exec(verb, uri, headers, nil) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, nil + } + } + return false, err +} + +// DeleteContainer deletes the container with given name on the storage +// account. If the container does not exist returns error. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx +func (b BlobStorageClient) DeleteContainer(name string) error { + resp, err := b.deleteContainer(name) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) +} + +// DeleteContainerIfExists deletes the container with given name on the storage +// account if it exists. Returns true if container is deleted with this call, or +// false if the container did not exist at the time of the Delete Container +// operation. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx +func (b BlobStorageClient) DeleteContainerIfExists(name string) (bool, error) { + resp, err := b.deleteContainer(name) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +func (b BlobStorageClient) deleteContainer(name string) (*storageResponse, error) { + verb := "DELETE" + uri := b.client.getEndpoint(blobServiceName, pathForContainer(name), url.Values{"restype": {"container"}}) + + headers := b.client.getStandardHeaders() + return b.client.exec(verb, uri, headers, nil) +} + +// ListBlobs returns an object that contains list of blobs in the container, +// pagination token and other information in the response of List Blobs call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +func (b BlobStorageClient) ListBlobs(container string, params ListBlobsParameters) (BlobListResponse, error) { + q := mergeParams(params.getParameters(), url.Values{ + "restype": {"container"}, + "comp": {"list"}}) + uri := b.client.getEndpoint(blobServiceName, pathForContainer(container), q) + headers := b.client.getStandardHeaders() + + var out BlobListResponse + resp, err := b.client.exec("GET", uri, headers, nil) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// BlobExists returns true if a blob with given name exists on the specified +// container of the storage account. +func (b BlobStorageClient) BlobExists(container, name string) (bool, error) { + verb := "HEAD" + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + headers := b.client.getStandardHeaders() + resp, err := b.client.exec(verb, uri, headers, nil) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, nil + } + } + return false, err +} + +// GetBlobURL gets the canonical URL to the blob with the specified name in the +// specified container. This method does not create a publicly accessible URL if +// the blob or container is private and this method does not check if the blob +// exists. +func (b BlobStorageClient) GetBlobURL(container, name string) string { + if container == "" { + container = "$root" + } + return b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) +} + +// GetBlob returns a stream to read the blob. Caller must call Close() the +// reader to close on the underlying connection. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx +func (b BlobStorageClient) GetBlob(container, name string) (io.ReadCloser, error) { + resp, err := b.getBlobRange(container, name, "", nil) + if err != nil { + return nil, err + } + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + return resp.body, nil +} + +// GetBlobRange reads the specified range of a blob to a stream. The bytesRange +// string must be in a format like "0-", "10-100" as defined in HTTP 1.1 spec. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx +func (b BlobStorageClient) GetBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (io.ReadCloser, error) { + resp, err := b.getBlobRange(container, name, bytesRange, extraHeaders) + if err != nil { + return nil, err + } + + if err := checkRespCode(resp.statusCode, []int{http.StatusPartialContent}); err != nil { + return nil, err + } + return resp.body, nil +} + +func (b BlobStorageClient) getBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (*storageResponse, error) { + verb := "GET" + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + + headers := b.client.getStandardHeaders() + if bytesRange != "" { + headers["Range"] = fmt.Sprintf("bytes=%s", bytesRange) + } + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(verb, uri, headers, nil) + if err != nil { + return nil, err + } + return resp, err +} + +// GetBlobProperties provides various information about the specified +// blob. See https://msdn.microsoft.com/en-us/library/azure/dd179394.aspx +func (b BlobStorageClient) GetBlobProperties(container, name string) (*BlobProperties, error) { + verb := "HEAD" + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + + headers := b.client.getStandardHeaders() + resp, err := b.client.exec(verb, uri, headers, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + var contentLength int64 + contentLengthStr := resp.headers.Get("Content-Length") + if contentLengthStr != "" { + contentLength, err = strconv.ParseInt(contentLengthStr, 0, 64) + if err != nil { + return nil, err + } + } + + var sequenceNum int64 + sequenceNumStr := resp.headers.Get("x-ms-blob-sequence-number") + if sequenceNumStr != "" { + sequenceNum, err = strconv.ParseInt(sequenceNumStr, 0, 64) + if err != nil { + return nil, err + } + } + + return &BlobProperties{ + LastModified: resp.headers.Get("Last-Modified"), + Etag: resp.headers.Get("Etag"), + ContentMD5: resp.headers.Get("Content-MD5"), + ContentLength: contentLength, + ContentEncoding: resp.headers.Get("Content-Encoding"), + ContentType: resp.headers.Get("Content-Type"), + CacheControl: resp.headers.Get("Cache-Control"), + ContentLanguage: resp.headers.Get("Content-Language"), + SequenceNumber: sequenceNum, + CopyCompletionTime: resp.headers.Get("x-ms-copy-completion-time"), + CopyStatusDescription: resp.headers.Get("x-ms-copy-status-description"), + CopyID: resp.headers.Get("x-ms-copy-id"), + CopyProgress: resp.headers.Get("x-ms-copy-progress"), + CopySource: resp.headers.Get("x-ms-copy-source"), + CopyStatus: resp.headers.Get("x-ms-copy-status"), + BlobType: BlobType(resp.headers.Get("x-ms-blob-type")), + LeaseStatus: resp.headers.Get("x-ms-lease-status"), + }, nil +} + +// SetBlobProperties replaces the BlobHeaders for the specified blob. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetBlobProperties. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691966.aspx +func (b BlobStorageClient) SetBlobProperties(container, name string, blobHeaders BlobHeaders) error { + params := url.Values{"comp": {"properties"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + extraHeaders := headersFromStruct(blobHeaders) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// SetBlobMetadata replaces the metadata for the specified blob. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetBlobMetadata. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (b BlobStorageClient) SetBlobMetadata(container, name string, metadata map[string]string, extraHeaders map[string]string) error { + params := url.Values{"comp": {"metadata"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + for k, v := range metadata { + headers[userDefinedMetadataHeaderPrefix+k] = v + } + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// GetBlobMetadata returns all user-defined metadata for the specified blob. +// +// All metadata keys will be returned in lower case. (HTTP header +// names are case-insensitive.) +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (b BlobStorageClient) GetBlobMetadata(container, name string) (map[string]string, error) { + params := url.Values{"comp": {"metadata"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + resp, err := b.client.exec("GET", uri, headers, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + metadata := make(map[string]string) + for k, v := range resp.headers { + // Can't trust CanonicalHeaderKey() to munge case + // reliably. "_" is allowed in identifiers: + // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx + // https://msdn.microsoft.com/library/aa664670(VS.71).aspx + // http://tools.ietf.org/html/rfc7230#section-3.2 + // ...but "_" is considered invalid by + // CanonicalMIMEHeaderKey in + // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 + // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". + k = strings.ToLower(k) + if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { + continue + } + // metadata["foo"] = content of the last X-Ms-Meta-Foo header + k = k[len(userDefinedMetadataHeaderPrefix):] + metadata[k] = v[len(v)-1] + } + return metadata, nil +} + +// CreateBlockBlob initializes an empty block blob with no blocks. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) CreateBlockBlob(container, name string) error { + return b.CreateBlockBlobFromReader(container, name, 0, nil, nil) +} + +// CreateBlockBlobFromReader initializes a block blob using data from +// reader. Size must be the number of bytes read from reader. To +// create an empty blob, use size==0 and reader==nil. +// +// The API rejects requests with size > 64 MiB (but this limit is not +// checked by the SDK). To write a larger blob, use CreateBlockBlob, +// PutBlock, and PutBlockList. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) CreateBlockBlobFromReader(container, name string, size uint64, blob io.Reader, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeBlock) + headers["Content-Length"] = fmt.Sprintf("%d", size) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, blob) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutBlock saves the given data chunk to the specified block blob with +// given ID. +// +// The API rejects chunks larger than 4 MiB (but this limit is not +// checked by the SDK). +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx +func (b BlobStorageClient) PutBlock(container, name, blockID string, chunk []byte) error { + return b.PutBlockWithLength(container, name, blockID, uint64(len(chunk)), bytes.NewReader(chunk), nil) +} + +// PutBlockWithLength saves the given data stream of exactly specified size to +// the block blob with given ID. It is an alternative to PutBlocks where data +// comes as stream but the length is known in advance. +// +// The API rejects requests with size > 4 MiB (but this limit is not +// checked by the SDK). +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx +func (b BlobStorageClient) PutBlockWithLength(container, name, blockID string, size uint64, blob io.Reader, extraHeaders map[string]string) error { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"block"}, "blockid": {blockID}}) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeBlock) + headers["Content-Length"] = fmt.Sprintf("%v", size) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, blob) + if err != nil { + return err + } + + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutBlockList saves list of blocks to the specified block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx +func (b BlobStorageClient) PutBlockList(container, name string, blocks []Block) error { + blockListXML := prepareBlockListRequest(blocks) + + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"blocklist"}}) + headers := b.client.getStandardHeaders() + headers["Content-Length"] = fmt.Sprintf("%v", len(blockListXML)) + + resp, err := b.client.exec("PUT", uri, headers, strings.NewReader(blockListXML)) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// GetBlockList retrieves list of blocks in the specified block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx +func (b BlobStorageClient) GetBlockList(container, name string, blockType BlockListType) (BlockListResponse, error) { + params := url.Values{"comp": {"blocklist"}, "blocklisttype": {string(blockType)}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + var out BlockListResponse + resp, err := b.client.exec("GET", uri, headers, nil) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// PutPageBlob initializes an empty page blob with specified name and maximum +// size in bytes (size must be aligned to a 512-byte boundary). A page blob must +// be created using this method before writing pages. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) PutPageBlob(container, name string, size int64, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypePage) + headers["x-ms-blob-content-length"] = fmt.Sprintf("%v", size) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutPage writes a range of pages to a page blob or clears the given range. +// In case of 'clear' writes, given chunk is discarded. Ranges must be aligned +// with 512-byte boundaries and chunk must be of size multiplies by 512. +// +// See https://msdn.microsoft.com/en-us/library/ee691975.aspx +func (b BlobStorageClient) PutPage(container, name string, startByte, endByte int64, writeType PageWriteType, chunk []byte, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"page"}}) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypePage) + headers["x-ms-page-write"] = string(writeType) + headers["x-ms-range"] = fmt.Sprintf("bytes=%v-%v", startByte, endByte) + for k, v := range extraHeaders { + headers[k] = v + } + var contentLength int64 + var data io.Reader + if writeType == PageWriteTypeClear { + contentLength = 0 + data = bytes.NewReader([]byte{}) + } else { + contentLength = int64(len(chunk)) + data = bytes.NewReader(chunk) + } + headers["Content-Length"] = fmt.Sprintf("%v", contentLength) + + resp, err := b.client.exec("PUT", uri, headers, data) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// GetPageRanges returns the list of valid page ranges for a page blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +func (b BlobStorageClient) GetPageRanges(container, name string) (GetPageRangesResponse, error) { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"pagelist"}}) + headers := b.client.getStandardHeaders() + + var out GetPageRangesResponse + resp, err := b.client.exec("GET", uri, headers, nil) + if err != nil { + return out, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return out, err + } + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// PutAppendBlob initializes an empty append blob with specified name. An +// append blob must be created using this method before appending blocks. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) PutAppendBlob(container, name string, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeAppend) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// AppendBlock appends a block to an append blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/mt427365.aspx +func (b BlobStorageClient) AppendBlock(container, name string, chunk []byte, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"appendblock"}}) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeAppend) + headers["Content-Length"] = fmt.Sprintf("%v", len(chunk)) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, bytes.NewReader(chunk)) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// CopyBlob starts a blob copy operation and waits for the operation to +// complete. sourceBlob parameter must be a canonical URL to the blob (can be +// obtained using GetBlobURL method.) There is no SLA on blob copy and therefore +// this helper method works faster on smaller files. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx +func (b BlobStorageClient) CopyBlob(container, name, sourceBlob string) error { + copyID, err := b.startBlobCopy(container, name, sourceBlob) + if err != nil { + return err + } + + return b.waitForBlobCopy(container, name, copyID) +} + +func (b BlobStorageClient) startBlobCopy(container, name, sourceBlob string) (string, error) { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + + headers := b.client.getStandardHeaders() + headers["x-ms-copy-source"] = sourceBlob + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return "", err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil { + return "", err + } + + copyID := resp.headers.Get("x-ms-copy-id") + if copyID == "" { + return "", errors.New("Got empty copy id header") + } + return copyID, nil +} + +func (b BlobStorageClient) waitForBlobCopy(container, name, copyID string) error { + for { + props, err := b.GetBlobProperties(container, name) + if err != nil { + return err + } + + if props.CopyID != copyID { + return errBlobCopyIDMismatch + } + + switch props.CopyStatus { + case blobCopyStatusSuccess: + return nil + case blobCopyStatusPending: + continue + case blobCopyStatusAborted: + return errBlobCopyAborted + case blobCopyStatusFailed: + return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", props.CopyID, props.CopyStatusDescription) + default: + return fmt.Errorf("storage: unhandled blob copy status: '%s'", props.CopyStatus) + } + } +} + +// DeleteBlob deletes the given blob from the specified container. +// If the blob does not exists at the time of the Delete Blob operation, it +// returns error. See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx +func (b BlobStorageClient) DeleteBlob(container, name string, extraHeaders map[string]string) error { + resp, err := b.deleteBlob(container, name, extraHeaders) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) +} + +// DeleteBlobIfExists deletes the given blob from the specified container If the +// blob is deleted with this call, returns true. Otherwise returns false. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx +func (b BlobStorageClient) DeleteBlobIfExists(container, name string, extraHeaders map[string]string) (bool, error) { + resp, err := b.deleteBlob(container, name, extraHeaders) + if resp != nil && (resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound) { + return resp.statusCode == http.StatusAccepted, nil + } + defer resp.body.Close() + return false, err +} + +func (b BlobStorageClient) deleteBlob(container, name string, extraHeaders map[string]string) (*storageResponse, error) { + verb := "DELETE" + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + headers := b.client.getStandardHeaders() + for k, v := range extraHeaders { + headers[k] = v + } + + return b.client.exec(verb, uri, headers, nil) +} + +// helper method to construct the path to a container given its name +func pathForContainer(name string) string { + return fmt.Sprintf("/%s", name) +} + +// helper method to construct the path to a blob given its container and blob +// name +func pathForBlob(container, name string) string { + return fmt.Sprintf("/%s/%s", container, name) +} + +// GetBlobSASURI creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx +func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Time, permissions string) (string, error) { + var ( + signedPermissions = permissions + blobURL = b.GetBlobURL(container, name) + ) + canonicalizedResource, err := b.client.buildCanonicalizedResource(blobURL) + + if err != nil { + return "", err + } + + // "The canonicalizedresouce portion of the string is a canonical path to the signed resource. + // It must include the service name (blob, table, queue or file) for version 2015-02-21 or + // later, the storage account name, and the resource name, and must be URL-decoded. + // -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + + // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). + canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) + + canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) + if err != nil { + return "", err + } + + signedExpiry := expiry.UTC().Format(time.RFC3339) + signedResource := "b" + + stringToSign, err := blobSASStringToSign(b.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions) + if err != nil { + return "", err + } + + sig := b.client.computeHmac256(stringToSign) + sasParams := url.Values{ + "sv": {b.client.apiVersion}, + "se": {signedExpiry}, + "sr": {signedResource}, + "sp": {signedPermissions}, + "sig": {sig}, + } + + sasURL, err := url.Parse(blobURL) + if err != nil { + return "", err + } + sasURL.RawQuery = sasParams.Encode() + return sasURL.String(), nil +} + +func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string) (string, error) { + var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string + + if signedVersion >= "2015-02-21" { + canonicalizedResource = "/blob" + canonicalizedResource + } + + // reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + if signedVersion >= "2013-08-15" { + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion, rscc, rscd, rsce, rscl, rsct), nil + } + return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15") +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go new file mode 100644 index 0000000000..2816e03ec6 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go @@ -0,0 +1,551 @@ +// Package storage provides clients for Microsoft Azure Storage Services. +package storage + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "regexp" + "sort" + "strconv" + "strings" +) + +const ( + // DefaultBaseURL is the domain name used for storage requests when a + // default client is created. + DefaultBaseURL = "core.windows.net" + + // DefaultAPIVersion is the Azure Storage API version string used when a + // basic client is created. + DefaultAPIVersion = "2015-02-21" + + defaultUseHTTPS = true + + // StorageEmulatorAccountName is the fixed storage account used by Azure Storage Emulator + StorageEmulatorAccountName = "devstoreaccount1" + + // StorageEmulatorAccountKey is the the fixed storage account used by Azure Storage Emulator + StorageEmulatorAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + + blobServiceName = "blob" + tableServiceName = "table" + queueServiceName = "queue" + fileServiceName = "file" + + storageEmulatorBlob = "127.0.0.1:10000" + storageEmulatorTable = "127.0.0.1:10002" + storageEmulatorQueue = "127.0.0.1:10001" +) + +// Client is the object that needs to be constructed to perform +// operations on the storage account. +type Client struct { + // HTTPClient is the http.Client used to initiate API + // requests. If it is nil, http.DefaultClient is used. + HTTPClient *http.Client + + accountName string + accountKey []byte + useHTTPS bool + baseURL string + apiVersion string +} + +type storageResponse struct { + statusCode int + headers http.Header + body io.ReadCloser +} + +type odataResponse struct { + storageResponse + odata odataErrorMessage +} + +// AzureStorageServiceError contains fields of the error response from +// Azure Storage Service REST API. See https://msdn.microsoft.com/en-us/library/azure/dd179382.aspx +// Some fields might be specific to certain calls. +type AzureStorageServiceError struct { + Code string `xml:"Code"` + Message string `xml:"Message"` + AuthenticationErrorDetail string `xml:"AuthenticationErrorDetail"` + QueryParameterName string `xml:"QueryParameterName"` + QueryParameterValue string `xml:"QueryParameterValue"` + Reason string `xml:"Reason"` + StatusCode int + RequestID string +} + +type odataErrorMessageMessage struct { + Lang string `json:"lang"` + Value string `json:"value"` +} + +type odataErrorMessageInternal struct { + Code string `json:"code"` + Message odataErrorMessageMessage `json:"message"` +} + +type odataErrorMessage struct { + Err odataErrorMessageInternal `json:"odata.error"` +} + +// UnexpectedStatusCodeError is returned when a storage service responds with neither an error +// nor with an HTTP status code indicating success. +type UnexpectedStatusCodeError struct { + allowed []int + got int +} + +func (e UnexpectedStatusCodeError) Error() string { + s := func(i int) string { return fmt.Sprintf("%d %s", i, http.StatusText(i)) } + + got := s(e.got) + expected := []string{} + for _, v := range e.allowed { + expected = append(expected, s(v)) + } + return fmt.Sprintf("storage: status code from service response is %s; was expecting %s", got, strings.Join(expected, " or ")) +} + +// Got is the actual status code returned by Azure. +func (e UnexpectedStatusCodeError) Got() int { + return e.got +} + +// NewBasicClient constructs a Client with given storage service name and +// key. +func NewBasicClient(accountName, accountKey string) (Client, error) { + if accountName == StorageEmulatorAccountName { + return NewEmulatorClient() + } + return NewClient(accountName, accountKey, DefaultBaseURL, DefaultAPIVersion, defaultUseHTTPS) +} + +//NewEmulatorClient contructs a Client intended to only work with Azure +//Storage Emulator +func NewEmulatorClient() (Client, error) { + return NewClient(StorageEmulatorAccountName, StorageEmulatorAccountKey, DefaultBaseURL, DefaultAPIVersion, false) +} + +// NewClient constructs a Client. This should be used if the caller wants +// to specify whether to use HTTPS, a specific REST API version or a custom +// storage endpoint than Azure Public Cloud. +func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, useHTTPS bool) (Client, error) { + var c Client + if accountName == "" { + return c, fmt.Errorf("azure: account name required") + } else if accountKey == "" { + return c, fmt.Errorf("azure: account key required") + } else if blobServiceBaseURL == "" { + return c, fmt.Errorf("azure: base storage service url required") + } + + key, err := base64.StdEncoding.DecodeString(accountKey) + if err != nil { + return c, fmt.Errorf("azure: malformed storage account key: %v", err) + } + + return Client{ + accountName: accountName, + accountKey: key, + useHTTPS: useHTTPS, + baseURL: blobServiceBaseURL, + apiVersion: apiVersion, + }, nil +} + +func (c Client) getBaseURL(service string) string { + scheme := "http" + if c.useHTTPS { + scheme = "https" + } + host := "" + if c.accountName == StorageEmulatorAccountName { + switch service { + case blobServiceName: + host = storageEmulatorBlob + case tableServiceName: + host = storageEmulatorTable + case queueServiceName: + host = storageEmulatorQueue + } + } else { + host = fmt.Sprintf("%s.%s.%s", c.accountName, service, c.baseURL) + } + + u := &url.URL{ + Scheme: scheme, + Host: host} + return u.String() +} + +func (c Client) getEndpoint(service, path string, params url.Values) string { + u, err := url.Parse(c.getBaseURL(service)) + if err != nil { + // really should not be happening + panic(err) + } + + // API doesn't accept path segments not starting with '/' + if !strings.HasPrefix(path, "/") { + path = fmt.Sprintf("/%v", path) + } + + if c.accountName == StorageEmulatorAccountName { + path = fmt.Sprintf("/%v%v", StorageEmulatorAccountName, path) + } + + u.Path = path + u.RawQuery = params.Encode() + return u.String() +} + +// GetBlobService returns a BlobStorageClient which can operate on the blob +// service of the storage account. +func (c Client) GetBlobService() BlobStorageClient { + return BlobStorageClient{c} +} + +// GetQueueService returns a QueueServiceClient which can operate on the queue +// service of the storage account. +func (c Client) GetQueueService() QueueServiceClient { + return QueueServiceClient{c} +} + +// GetTableService returns a TableServiceClient which can operate on the table +// service of the storage account. +func (c Client) GetTableService() TableServiceClient { + return TableServiceClient{c} +} + +// GetFileService returns a FileServiceClient which can operate on the file +// service of the storage account. +func (c Client) GetFileService() FileServiceClient { + return FileServiceClient{c} +} + +func (c Client) createAuthorizationHeader(canonicalizedString string) string { + signature := c.computeHmac256(canonicalizedString) + return fmt.Sprintf("%s %s:%s", "SharedKey", c.getCanonicalizedAccountName(), signature) +} + +func (c Client) getAuthorizationHeader(verb, url string, headers map[string]string) (string, error) { + canonicalizedResource, err := c.buildCanonicalizedResource(url) + if err != nil { + return "", err + } + + canonicalizedString := c.buildCanonicalizedString(verb, headers, canonicalizedResource) + return c.createAuthorizationHeader(canonicalizedString), nil +} + +func (c Client) getStandardHeaders() map[string]string { + return map[string]string{ + "x-ms-version": c.apiVersion, + "x-ms-date": currentTimeRfc1123Formatted(), + } +} + +func (c Client) getCanonicalizedAccountName() string { + // since we may be trying to access a secondary storage account, we need to + // remove the -secondary part of the storage name + return strings.TrimSuffix(c.accountName, "-secondary") +} + +func (c Client) buildCanonicalizedHeader(headers map[string]string) string { + cm := make(map[string]string) + + for k, v := range headers { + headerName := strings.TrimSpace(strings.ToLower(k)) + match, _ := regexp.MatchString("x-ms-", headerName) + if match { + cm[headerName] = v + } + } + + if len(cm) == 0 { + return "" + } + + keys := make([]string, 0, len(cm)) + for key := range cm { + keys = append(keys, key) + } + + sort.Strings(keys) + + ch := "" + + for i, key := range keys { + if i == len(keys)-1 { + ch += fmt.Sprintf("%s:%s", key, cm[key]) + } else { + ch += fmt.Sprintf("%s:%s\n", key, cm[key]) + } + } + return ch +} + +func (c Client) buildCanonicalizedResourceTable(uri string) (string, error) { + errMsg := "buildCanonicalizedResourceTable error: %s" + u, err := url.Parse(uri) + if err != nil { + return "", fmt.Errorf(errMsg, err.Error()) + } + + cr := "/" + c.getCanonicalizedAccountName() + + if len(u.Path) > 0 { + cr += u.Path + } + + return cr, nil +} + +func (c Client) buildCanonicalizedResource(uri string) (string, error) { + errMsg := "buildCanonicalizedResource error: %s" + u, err := url.Parse(uri) + if err != nil { + return "", fmt.Errorf(errMsg, err.Error()) + } + + cr := "/" + c.getCanonicalizedAccountName() + + if len(u.Path) > 0 { + // Any portion of the CanonicalizedResource string that is derived from + // the resource's URI should be encoded exactly as it is in the URI. + // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx + cr += u.EscapedPath() + } + + params, err := url.ParseQuery(u.RawQuery) + if err != nil { + return "", fmt.Errorf(errMsg, err.Error()) + } + + if len(params) > 0 { + cr += "\n" + keys := make([]string, 0, len(params)) + for key := range params { + keys = append(keys, key) + } + + sort.Strings(keys) + + for i, key := range keys { + if len(params[key]) > 1 { + sort.Strings(params[key]) + } + + if i == len(keys)-1 { + cr += fmt.Sprintf("%s:%s", key, strings.Join(params[key], ",")) + } else { + cr += fmt.Sprintf("%s:%s\n", key, strings.Join(params[key], ",")) + } + } + } + + return cr, nil +} + +func (c Client) buildCanonicalizedString(verb string, headers map[string]string, canonicalizedResource string) string { + contentLength := headers["Content-Length"] + if contentLength == "0" { + contentLength = "" + } + canonicalizedString := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", + verb, + headers["Content-Encoding"], + headers["Content-Language"], + contentLength, + headers["Content-MD5"], + headers["Content-Type"], + headers["Date"], + headers["If-Modified-Since"], + headers["If-Match"], + headers["If-None-Match"], + headers["If-Unmodified-Since"], + headers["Range"], + c.buildCanonicalizedHeader(headers), + canonicalizedResource) + + return canonicalizedString +} + +func (c Client) exec(verb, url string, headers map[string]string, body io.Reader) (*storageResponse, error) { + authHeader, err := c.getAuthorizationHeader(verb, url, headers) + if err != nil { + return nil, err + } + headers["Authorization"] = authHeader + if err != nil { + return nil, err + } + + req, err := http.NewRequest(verb, url, body) + if err != nil { + return nil, errors.New("azure/storage: error creating request: " + err.Error()) + } + + if clstr, ok := headers["Content-Length"]; ok { + // content length header is being signed, but completely ignored by golang. + // instead we have to use the ContentLength property on the request struct + // (see https://golang.org/src/net/http/request.go?s=18140:18370#L536 and + // https://golang.org/src/net/http/transfer.go?s=1739:2467#L49) + req.ContentLength, err = strconv.ParseInt(clstr, 10, 64) + if err != nil { + return nil, err + } + } + for k, v := range headers { + req.Header.Add(k, v) + } + + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + + statusCode := resp.StatusCode + if statusCode >= 400 && statusCode <= 505 { + var respBody []byte + respBody, err = readResponseBody(resp) + if err != nil { + return nil, err + } + + if len(respBody) == 0 { + // no error in response body + err = fmt.Errorf("storage: service returned without a response body (%s)", resp.Status) + } else { + // response contains storage service error object, unmarshal + storageErr, errIn := serviceErrFromXML(respBody, resp.StatusCode, resp.Header.Get("x-ms-request-id")) + if err != nil { // error unmarshaling the error response + err = errIn + } + err = storageErr + } + return &storageResponse{ + statusCode: resp.StatusCode, + headers: resp.Header, + body: ioutil.NopCloser(bytes.NewReader(respBody)), /* restore the body */ + }, err + } + + return &storageResponse{ + statusCode: resp.StatusCode, + headers: resp.Header, + body: resp.Body}, nil +} + +func (c Client) execInternalJSON(verb, url string, headers map[string]string, body io.Reader) (*odataResponse, error) { + req, err := http.NewRequest(verb, url, body) + for k, v := range headers { + req.Header.Add(k, v) + } + + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + + respToRet := &odataResponse{} + respToRet.body = resp.Body + respToRet.statusCode = resp.StatusCode + respToRet.headers = resp.Header + + statusCode := resp.StatusCode + if statusCode >= 400 && statusCode <= 505 { + var respBody []byte + respBody, err = readResponseBody(resp) + if err != nil { + return nil, err + } + + if len(respBody) == 0 { + // no error in response body + err = fmt.Errorf("storage: service returned without a response body (%d)", resp.StatusCode) + return respToRet, err + } + // try unmarshal as odata.error json + err = json.Unmarshal(respBody, &respToRet.odata) + return respToRet, err + } + + return respToRet, nil +} + +func (c Client) createSharedKeyLite(url string, headers map[string]string) (string, error) { + can, err := c.buildCanonicalizedResourceTable(url) + + if err != nil { + return "", err + } + strToSign := headers["x-ms-date"] + "\n" + can + + hmac := c.computeHmac256(strToSign) + return fmt.Sprintf("SharedKeyLite %s:%s", c.accountName, hmac), nil +} + +func (c Client) execTable(verb, url string, headers map[string]string, body io.Reader) (*odataResponse, error) { + var err error + headers["Authorization"], err = c.createSharedKeyLite(url, headers) + if err != nil { + return nil, err + } + + return c.execInternalJSON(verb, url, headers, body) +} + +func readResponseBody(resp *http.Response) ([]byte, error) { + defer resp.Body.Close() + out, err := ioutil.ReadAll(resp.Body) + if err == io.EOF { + err = nil + } + return out, err +} + +func serviceErrFromXML(body []byte, statusCode int, requestID string) (AzureStorageServiceError, error) { + var storageErr AzureStorageServiceError + if err := xml.Unmarshal(body, &storageErr); err != nil { + return storageErr, err + } + storageErr.StatusCode = statusCode + storageErr.RequestID = requestID + return storageErr, nil +} + +func (e AzureStorageServiceError) Error() string { + return fmt.Sprintf("storage: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=%s, RequestId=%s, QueryParameterName=%s, QueryParameterValue=%s", + e.StatusCode, e.Code, e.Message, e.RequestID, e.QueryParameterName, e.QueryParameterValue) +} + +// checkRespCode returns UnexpectedStatusError if the given response code is not +// one of the allowed status codes; otherwise nil. +func checkRespCode(respCode int, allowed []int) error { + for _, v := range allowed { + if respCode == v { + return nil + } + } + return UnexpectedStatusCodeError{allowed, respCode} +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go new file mode 100644 index 0000000000..2397587c88 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go @@ -0,0 +1,352 @@ +package storage + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + "strings" +) + +// FileServiceClient contains operations for Microsoft Azure File Service. +type FileServiceClient struct { + client Client +} + +// A Share is an entry in ShareListResponse. +type Share struct { + Name string `xml:"Name"` + Properties ShareProperties `xml:"Properties"` +} + +// ShareProperties contains various properties of a share returned from +// various endpoints like ListShares. +type ShareProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` + Quota string `xml:"Quota"` +} + +// ShareListResponse contains the response fields from +// ListShares call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx +type ShareListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + NextMarker string `xml:"NextMarker"` + MaxResults int64 `xml:"MaxResults"` + Shares []Share `xml:"Shares>Share"` +} + +// ListSharesParameters defines the set of customizable parameters to make a +// List Shares call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx +type ListSharesParameters struct { + Prefix string + Marker string + Include string + MaxResults uint + Timeout uint +} + +// ShareHeaders contains various properties of a file and is an entry +// in SetShareProperties +type ShareHeaders struct { + Quota string `header:"x-ms-share-quota"` +} + +func (p ListSharesParameters) getParameters() url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// pathForFileShare returns the URL path segment for a File Share resource +func pathForFileShare(name string) string { + return fmt.Sprintf("/%s", name) +} + +// ListShares returns the list of shares in a storage account along with +// pagination token and other response details. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +func (f FileServiceClient) ListShares(params ListSharesParameters) (ShareListResponse, error) { + q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) + uri := f.client.getEndpoint(fileServiceName, "", q) + headers := f.client.getStandardHeaders() + + var out ShareListResponse + resp, err := f.client.exec("GET", uri, headers, nil) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// CreateShare operation creates a new share under the specified account. If the +// share with the same name already exists, the operation fails. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx +func (f FileServiceClient) CreateShare(name string) error { + resp, err := f.createShare(name) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// ShareExists returns true if a share with given name exists +// on the storage account, otherwise returns false. +func (f FileServiceClient) ShareExists(name string) (bool, error) { + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}}) + headers := f.client.getStandardHeaders() + + resp, err := f.client.exec("HEAD", uri, headers, nil) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, nil + } + } + return false, err +} + +// GetShareURL gets the canonical URL to the share with the specified name in the +// specified container. This method does not create a publicly accessible URL if +// the file is private and this method does not check if the file +// exists. +func (f FileServiceClient) GetShareURL(name string) string { + return f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{}) +} + +// CreateShareIfNotExists creates a new share under the specified account if +// it does not exist. Returns true if container is newly created or false if +// container already exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx +func (f FileServiceClient) CreateShareIfNotExists(name string) (bool, error) { + resp, err := f.createShare(name) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { + return resp.statusCode == http.StatusCreated, nil + } + } + return false, err +} + +// CreateShare creates a Azure File Share and returns its response +func (f FileServiceClient) createShare(name string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}}) + headers := f.client.getStandardHeaders() + return f.client.exec("PUT", uri, headers, nil) +} + +// GetShareProperties provides various information about the specified +// file. See https://msdn.microsoft.com/en-us/library/azure/dn689099.aspx +func (f FileServiceClient) GetShareProperties(name string) (*ShareProperties, error) { + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}}) + + headers := f.client.getStandardHeaders() + resp, err := f.client.exec("HEAD", uri, headers, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + return &ShareProperties{ + LastModified: resp.headers.Get("Last-Modified"), + Etag: resp.headers.Get("Etag"), + Quota: resp.headers.Get("x-ms-share-quota"), + }, nil +} + +// SetShareProperties replaces the ShareHeaders for the specified file. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by SetShareProperties. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/mt427368.aspx +func (f FileServiceClient) SetShareProperties(name string, shareHeaders ShareHeaders) error { + params := url.Values{} + params.Set("restype", "share") + params.Set("comp", "properties") + + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), params) + headers := f.client.getStandardHeaders() + + extraHeaders := headersFromStruct(shareHeaders) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := f.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// DeleteShare operation marks the specified share for deletion. The share +// and any files contained within it are later deleted during garbage +// collection. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx +func (f FileServiceClient) DeleteShare(name string) error { + resp, err := f.deleteShare(name) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) +} + +// DeleteShareIfExists operation marks the specified share for deletion if it +// exists. The share and any files contained within it are later deleted during +// garbage collection. Returns true if share existed and deleted with this call, +// false otherwise. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx +func (f FileServiceClient) DeleteShareIfExists(name string) (bool, error) { + resp, err := f.deleteShare(name) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +// deleteShare makes the call to Delete Share operation endpoint and returns +// the response +func (f FileServiceClient) deleteShare(name string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}}) + return f.client.exec("DELETE", uri, f.client.getStandardHeaders(), nil) +} + +// SetShareMetadata replaces the metadata for the specified Share. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetShareMetadata. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (f FileServiceClient) SetShareMetadata(name string, metadata map[string]string, extraHeaders map[string]string) error { + params := url.Values{} + params.Set("restype", "share") + params.Set("comp", "metadata") + + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), params) + headers := f.client.getStandardHeaders() + for k, v := range metadata { + headers[userDefinedMetadataHeaderPrefix+k] = v + } + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := f.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// GetShareMetadata returns all user-defined metadata for the specified share. +// +// All metadata keys will be returned in lower case. (HTTP header +// names are case-insensitive.) +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (f FileServiceClient) GetShareMetadata(name string) (map[string]string, error) { + params := url.Values{} + params.Set("restype", "share") + params.Set("comp", "metadata") + + uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), params) + headers := f.client.getStandardHeaders() + + resp, err := f.client.exec("GET", uri, headers, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + metadata := make(map[string]string) + for k, v := range resp.headers { + // Can't trust CanonicalHeaderKey() to munge case + // reliably. "_" is allowed in identifiers: + // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx + // https://msdn.microsoft.com/library/aa664670(VS.71).aspx + // http://tools.ietf.org/html/rfc7230#section-3.2 + // ...but "_" is considered invalid by + // CanonicalMIMEHeaderKey in + // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 + // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". + k = strings.ToLower(k) + if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { + continue + } + // metadata["foo"] = content of the last X-Ms-Meta-Foo header + k = k[len(userDefinedMetadataHeaderPrefix):] + metadata[k] = v[len(v)-1] + } + return metadata, nil +} + +//checkForStorageEmulator determines if the client is setup for use with +//Azure Storage Emulator, and returns a relevant error +func (f FileServiceClient) checkForStorageEmulator() error { + if f.client.accountName == StorageEmulatorAccountName { + return fmt.Errorf("Error: File service is not currently supported by Azure Storage Emulator") + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go new file mode 100644 index 0000000000..3ecf4aca0d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go @@ -0,0 +1,306 @@ +package storage + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" +) + +const ( + // casing is per Golang's http.Header canonicalizing the header names. + approximateMessagesCountHeader = "X-Ms-Approximate-Messages-Count" + userDefinedMetadataHeaderPrefix = "X-Ms-Meta-" +) + +// QueueServiceClient contains operations for Microsoft Azure Queue Storage +// Service. +type QueueServiceClient struct { + client Client +} + +func pathForQueue(queue string) string { return fmt.Sprintf("/%s", queue) } +func pathForQueueMessages(queue string) string { return fmt.Sprintf("/%s/messages", queue) } +func pathForMessage(queue, name string) string { return fmt.Sprintf("/%s/messages/%s", queue, name) } + +type putMessageRequest struct { + XMLName xml.Name `xml:"QueueMessage"` + MessageText string `xml:"MessageText"` +} + +// PutMessageParameters is the set of options can be specified for Put Messsage +// operation. A zero struct does not use any preferences for the request. +type PutMessageParameters struct { + VisibilityTimeout int + MessageTTL int +} + +func (p PutMessageParameters) getParameters() url.Values { + out := url.Values{} + if p.VisibilityTimeout != 0 { + out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + } + if p.MessageTTL != 0 { + out.Set("messagettl", strconv.Itoa(p.MessageTTL)) + } + return out +} + +// GetMessagesParameters is the set of options can be specified for Get +// Messsages operation. A zero struct does not use any preferences for the +// request. +type GetMessagesParameters struct { + NumOfMessages int + VisibilityTimeout int +} + +func (p GetMessagesParameters) getParameters() url.Values { + out := url.Values{} + if p.NumOfMessages != 0 { + out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) + } + if p.VisibilityTimeout != 0 { + out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + } + return out +} + +// PeekMessagesParameters is the set of options can be specified for Peek +// Messsage operation. A zero struct does not use any preferences for the +// request. +type PeekMessagesParameters struct { + NumOfMessages int +} + +func (p PeekMessagesParameters) getParameters() url.Values { + out := url.Values{"peekonly": {"true"}} // Required for peek operation + if p.NumOfMessages != 0 { + out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) + } + return out +} + +// GetMessagesResponse represents a response returned from Get Messages +// operation. +type GetMessagesResponse struct { + XMLName xml.Name `xml:"QueueMessagesList"` + QueueMessagesList []GetMessageResponse `xml:"QueueMessage"` +} + +// GetMessageResponse represents a QueueMessage object returned from Get +// Messages operation response. +type GetMessageResponse struct { + MessageID string `xml:"MessageId"` + InsertionTime string `xml:"InsertionTime"` + ExpirationTime string `xml:"ExpirationTime"` + PopReceipt string `xml:"PopReceipt"` + TimeNextVisible string `xml:"TimeNextVisible"` + DequeueCount int `xml:"DequeueCount"` + MessageText string `xml:"MessageText"` +} + +// PeekMessagesResponse represents a response returned from Get Messages +// operation. +type PeekMessagesResponse struct { + XMLName xml.Name `xml:"QueueMessagesList"` + QueueMessagesList []PeekMessageResponse `xml:"QueueMessage"` +} + +// PeekMessageResponse represents a QueueMessage object returned from Peek +// Messages operation response. +type PeekMessageResponse struct { + MessageID string `xml:"MessageId"` + InsertionTime string `xml:"InsertionTime"` + ExpirationTime string `xml:"ExpirationTime"` + DequeueCount int `xml:"DequeueCount"` + MessageText string `xml:"MessageText"` +} + +// QueueMetadataResponse represents user defined metadata and queue +// properties on a specific queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx +type QueueMetadataResponse struct { + ApproximateMessageCount int + UserDefinedMetadata map[string]string +} + +// SetMetadata operation sets user-defined metadata on the specified queue. +// Metadata is associated with the queue as name-value pairs. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179348.aspx +func (c QueueServiceClient) SetMetadata(name string, metadata map[string]string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) + headers := c.client.getStandardHeaders() + for k, v := range metadata { + headers[userDefinedMetadataHeaderPrefix+k] = v + } + + resp, err := c.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// GetMetadata operation retrieves user-defined metadata and queue +// properties on the specified queue. Metadata is associated with +// the queue as name-values pairs. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx +// +// Because the way Golang's http client (and http.Header in particular) +// canonicalize header names, the returned metadata names would always +// be all lower case. +func (c QueueServiceClient) GetMetadata(name string) (QueueMetadataResponse, error) { + qm := QueueMetadataResponse{} + qm.UserDefinedMetadata = make(map[string]string) + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) + headers := c.client.getStandardHeaders() + resp, err := c.client.exec("GET", uri, headers, nil) + if err != nil { + return qm, err + } + defer resp.body.Close() + + for k, v := range resp.headers { + if len(v) != 1 { + return qm, fmt.Errorf("Unexpected number of values (%d) in response header '%s'", len(v), k) + } + + value := v[0] + + if k == approximateMessagesCountHeader { + qm.ApproximateMessageCount, err = strconv.Atoi(value) + if err != nil { + return qm, fmt.Errorf("Unexpected value in response header '%s': '%s' ", k, value) + } + } else if strings.HasPrefix(k, userDefinedMetadataHeaderPrefix) { + name := strings.TrimPrefix(k, userDefinedMetadataHeaderPrefix) + qm.UserDefinedMetadata[strings.ToLower(name)] = value + } + } + + return qm, checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// CreateQueue operation creates a queue under the given account. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179342.aspx +func (c QueueServiceClient) CreateQueue(name string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) + headers := c.client.getStandardHeaders() + resp, err := c.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// DeleteQueue operation permanently deletes the specified queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179436.aspx +func (c QueueServiceClient) DeleteQueue(name string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) + resp, err := c.client.exec("DELETE", uri, c.client.getStandardHeaders(), nil) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// QueueExists returns true if a queue with given name exists. +func (c QueueServiceClient) QueueExists(name string) (bool, error) { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": {"metadata"}}) + resp, err := c.client.exec("GET", uri, c.client.getStandardHeaders(), nil) + if resp != nil && (resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound) { + return resp.statusCode == http.StatusOK, nil + } + + return false, err +} + +// PutMessage operation adds a new message to the back of the message queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179346.aspx +func (c QueueServiceClient) PutMessage(queue string, message string, params PutMessageParameters) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) + req := putMessageRequest{MessageText: message} + body, nn, err := xmlMarshal(req) + if err != nil { + return err + } + headers := c.client.getStandardHeaders() + headers["Content-Length"] = strconv.Itoa(nn) + resp, err := c.client.exec("POST", uri, headers, body) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// ClearMessages operation deletes all messages from the specified queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179454.aspx +func (c QueueServiceClient) ClearMessages(queue string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), url.Values{}) + resp, err := c.client.exec("DELETE", uri, c.client.getStandardHeaders(), nil) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// GetMessages operation retrieves one or more messages from the front of the +// queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179474.aspx +func (c QueueServiceClient) GetMessages(queue string, params GetMessagesParameters) (GetMessagesResponse, error) { + var r GetMessagesResponse + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) + resp, err := c.client.exec("GET", uri, c.client.getStandardHeaders(), nil) + if err != nil { + return r, err + } + defer resp.body.Close() + err = xmlUnmarshal(resp.body, &r) + return r, err +} + +// PeekMessages retrieves one or more messages from the front of the queue, but +// does not alter the visibility of the message. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179472.aspx +func (c QueueServiceClient) PeekMessages(queue string, params PeekMessagesParameters) (PeekMessagesResponse, error) { + var r PeekMessagesResponse + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) + resp, err := c.client.exec("GET", uri, c.client.getStandardHeaders(), nil) + if err != nil { + return r, err + } + defer resp.body.Close() + err = xmlUnmarshal(resp.body, &r) + return r, err +} + +// DeleteMessage operation deletes the specified message. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179347.aspx +func (c QueueServiceClient) DeleteMessage(queue, messageID, popReceipt string) error { + uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), url.Values{ + "popreceipt": {popReceipt}}) + resp, err := c.client.exec("DELETE", uri, c.client.getStandardHeaders(), nil) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go new file mode 100644 index 0000000000..39e9975035 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go @@ -0,0 +1,129 @@ +package storage + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "net/url" +) + +// TableServiceClient contains operations for Microsoft Azure Table Storage +// Service. +type TableServiceClient struct { + client Client +} + +// AzureTable is the typedef of the Azure Table name +type AzureTable string + +const ( + tablesURIPath = "/Tables" +) + +type createTableRequest struct { + TableName string `json:"TableName"` +} + +func pathForTable(table AzureTable) string { return fmt.Sprintf("%s", table) } + +func (c *TableServiceClient) getStandardHeaders() map[string]string { + return map[string]string{ + "x-ms-version": "2015-02-21", + "x-ms-date": currentTimeRfc1123Formatted(), + "Accept": "application/json;odata=nometadata", + "Accept-Charset": "UTF-8", + "Content-Type": "application/json", + } +} + +// QueryTables returns the tables created in the +// *TableServiceClient storage account. +func (c *TableServiceClient) QueryTables() ([]AzureTable, error) { + uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) + + headers := c.getStandardHeaders() + headers["Content-Length"] = "0" + + resp, err := c.client.execTable("GET", uri, headers, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + buf := new(bytes.Buffer) + buf.ReadFrom(resp.body) + + var respArray queryTablesResponse + if err := json.Unmarshal(buf.Bytes(), &respArray); err != nil { + return nil, err + } + + s := make([]AzureTable, len(respArray.TableName)) + for i, elem := range respArray.TableName { + s[i] = AzureTable(elem.TableName) + } + + return s, nil +} + +// CreateTable creates the table given the specific +// name. This function fails if the name is not compliant +// with the specification or the tables already exists. +func (c *TableServiceClient) CreateTable(table AzureTable) error { + uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) + + headers := c.getStandardHeaders() + + req := createTableRequest{TableName: string(table)} + buf := new(bytes.Buffer) + + if err := json.NewEncoder(buf).Encode(req); err != nil { + return err + } + + headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) + + resp, err := c.client.execTable("POST", uri, headers, buf) + + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { + return err + } + + return nil +} + +// DeleteTable deletes the table given the specific +// name. This function fails if the table is not present. +// Be advised: DeleteTable deletes all the entries +// that may be present. +func (c *TableServiceClient) DeleteTable(table AzureTable) error { + uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) + uri += fmt.Sprintf("('%s')", string(table)) + + headers := c.getStandardHeaders() + + headers["Content-Length"] = "0" + + resp, err := c.client.execTable("DELETE", uri, headers, nil) + + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go new file mode 100644 index 0000000000..1b5919cd13 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go @@ -0,0 +1,355 @@ +package storage + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "reflect" +) + +const ( + partitionKeyNode = "PartitionKey" + rowKeyNode = "RowKey" + tag = "table" + tagIgnore = "-" + continuationTokenPartitionKeyHeader = "X-Ms-Continuation-Nextpartitionkey" + continuationTokenRowHeader = "X-Ms-Continuation-Nextrowkey" + maxTopParameter = 1000 +) + +type queryTablesResponse struct { + TableName []struct { + TableName string `json:"TableName"` + } `json:"value"` +} + +const ( + tableOperationTypeInsert = iota + tableOperationTypeUpdate = iota + tableOperationTypeMerge = iota + tableOperationTypeInsertOrReplace = iota + tableOperationTypeInsertOrMerge = iota +) + +type tableOperation int + +// TableEntity interface specifies +// the functions needed to support +// marshaling and unmarshaling into +// Azure Tables. The struct must only contain +// simple types because Azure Tables do not +// support hierarchy. +type TableEntity interface { + PartitionKey() string + RowKey() string + SetPartitionKey(string) error + SetRowKey(string) error +} + +// ContinuationToken is an opaque (ie not useful to inspect) +// struct that Get... methods can return if there are more +// entries to be returned than the ones already +// returned. Just pass it to the same function to continue +// receiving the remaining entries. +type ContinuationToken struct { + NextPartitionKey string + NextRowKey string +} + +type getTableEntriesResponse struct { + Elements []map[string]interface{} `json:"value"` +} + +// QueryTableEntities queries the specified table and returns the unmarshaled +// entities of type retType. +// top parameter limits the returned entries up to top. Maximum top +// allowed by Azure API is 1000. In case there are more than top entries to be +// returned the function will return a non nil *ContinuationToken. You can call the +// same function again passing the received ContinuationToken as previousContToken +// parameter in order to get the following entries. The query parameter +// is the odata query. To retrieve all the entries pass the empty string. +// The function returns a pointer to a TableEntity slice, the *ContinuationToken +// if there are more entries to be returned and an error in case something went +// wrong. +// +// Example: +// entities, cToken, err = tSvc.QueryTableEntities("table", cToken, reflect.TypeOf(entity), 20, "") +func (c *TableServiceClient) QueryTableEntities(tableName AzureTable, previousContToken *ContinuationToken, retType reflect.Type, top int, query string) ([]TableEntity, *ContinuationToken, error) { + if top > maxTopParameter { + return nil, nil, fmt.Errorf("top accepts at maximum %d elements. Requested %d instead", maxTopParameter, top) + } + + uri := c.client.getEndpoint(tableServiceName, pathForTable(tableName), url.Values{}) + uri += fmt.Sprintf("?$top=%d", top) + if query != "" { + uri += fmt.Sprintf("&$filter=%s", url.QueryEscape(query)) + } + + if previousContToken != nil { + uri += fmt.Sprintf("&NextPartitionKey=%s&NextRowKey=%s", previousContToken.NextPartitionKey, previousContToken.NextRowKey) + } + + headers := c.getStandardHeaders() + + headers["Content-Length"] = "0" + + resp, err := c.client.execTable("GET", uri, headers, nil) + + if err != nil { + return nil, nil, err + } + + contToken := extractContinuationTokenFromHeaders(resp.headers) + + if err != nil { + return nil, contToken, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, contToken, err + } + + retEntries, err := deserializeEntity(retType, resp.body) + if err != nil { + return nil, contToken, err + } + + return retEntries, contToken, nil +} + +// InsertEntity inserts an entity in the specified table. +// The function fails if there is an entity with the same +// PartitionKey and RowKey in the table. +func (c *TableServiceClient) InsertEntity(table AzureTable, entity TableEntity) error { + var err error + + if sc, err := c.execTable(table, entity, false, "POST"); err != nil { + return checkRespCode(sc, []int{http.StatusCreated}) + } + + return err +} + +func (c *TableServiceClient) execTable(table AzureTable, entity TableEntity, specifyKeysInURL bool, method string) (int, error) { + uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) + if specifyKeysInURL { + uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) + } + + headers := c.getStandardHeaders() + + var buf bytes.Buffer + + if err := injectPartitionAndRowKeys(entity, &buf); err != nil { + return 0, err + } + + headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) + + var err error + var resp *odataResponse + + resp, err = c.client.execTable(method, uri, headers, &buf) + + if err != nil { + return 0, err + } + + defer resp.body.Close() + + return resp.statusCode, nil +} + +// UpdateEntity updates the contents of an entity with the +// one passed as parameter. The function fails if there is no entity +// with the same PartitionKey and RowKey in the table. +func (c *TableServiceClient) UpdateEntity(table AzureTable, entity TableEntity) error { + var err error + + if sc, err := c.execTable(table, entity, true, "PUT"); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return err +} + +// MergeEntity merges the contents of an entity with the +// one passed as parameter. +// The function fails if there is no entity +// with the same PartitionKey and RowKey in the table. +func (c *TableServiceClient) MergeEntity(table AzureTable, entity TableEntity) error { + var err error + + if sc, err := c.execTable(table, entity, true, "MERGE"); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return err +} + +// DeleteEntityWithoutCheck deletes the entity matching by +// PartitionKey and RowKey. There is no check on IfMatch +// parameter so the entity is always deleted. +// The function fails if there is no entity +// with the same PartitionKey and RowKey in the table. +func (c *TableServiceClient) DeleteEntityWithoutCheck(table AzureTable, entity TableEntity) error { + return c.DeleteEntity(table, entity, "*") +} + +// DeleteEntity deletes the entity matching by +// PartitionKey, RowKey and ifMatch field. +// The function fails if there is no entity +// with the same PartitionKey and RowKey in the table or +// the ifMatch is different. +func (c *TableServiceClient) DeleteEntity(table AzureTable, entity TableEntity, ifMatch string) error { + uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) + uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) + + headers := c.getStandardHeaders() + + headers["Content-Length"] = "0" + headers["If-Match"] = ifMatch + + resp, err := c.client.execTable("DELETE", uri, headers, nil) + + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return nil +} + +// InsertOrReplaceEntity inserts an entity in the specified table +// or replaced the existing one. +func (c *TableServiceClient) InsertOrReplaceEntity(table AzureTable, entity TableEntity) error { + var err error + + if sc, err := c.execTable(table, entity, true, "PUT"); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return err +} + +// InsertOrMergeEntity inserts an entity in the specified table +// or merges the existing one. +func (c *TableServiceClient) InsertOrMergeEntity(table AzureTable, entity TableEntity) error { + var err error + + if sc, err := c.execTable(table, entity, true, "MERGE"); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return err +} + +func injectPartitionAndRowKeys(entity TableEntity, buf *bytes.Buffer) error { + if err := json.NewEncoder(buf).Encode(entity); err != nil { + return err + } + + dec := make(map[string]interface{}) + if err := json.NewDecoder(buf).Decode(&dec); err != nil { + return err + } + + // Inject PartitionKey and RowKey + dec[partitionKeyNode] = entity.PartitionKey() + dec[rowKeyNode] = entity.RowKey() + + // Remove tagged fields + // The tag is defined in the const section + // This is useful to avoid storing the PartitionKey and RowKey twice. + numFields := reflect.ValueOf(entity).Elem().NumField() + for i := 0; i < numFields; i++ { + f := reflect.ValueOf(entity).Elem().Type().Field(i) + + if f.Tag.Get(tag) == tagIgnore { + // we must look for its JSON name in the dictionary + // as the user can rename it using a tag + jsonName := f.Name + if f.Tag.Get("json") != "" { + jsonName = f.Tag.Get("json") + } + delete(dec, jsonName) + } + } + + buf.Reset() + + if err := json.NewEncoder(buf).Encode(&dec); err != nil { + return err + } + + return nil +} + +func deserializeEntity(retType reflect.Type, reader io.Reader) ([]TableEntity, error) { + buf := new(bytes.Buffer) + + var ret getTableEntriesResponse + if err := json.NewDecoder(reader).Decode(&ret); err != nil { + return nil, err + } + + tEntries := make([]TableEntity, len(ret.Elements)) + + for i, entry := range ret.Elements { + + buf.Reset() + if err := json.NewEncoder(buf).Encode(entry); err != nil { + return nil, err + } + + dec := make(map[string]interface{}) + if err := json.NewDecoder(buf).Decode(&dec); err != nil { + return nil, err + } + + var pKey, rKey string + // strip pk and rk + for key, val := range dec { + switch key { + case partitionKeyNode: + pKey = val.(string) + case rowKeyNode: + rKey = val.(string) + } + } + + delete(dec, partitionKeyNode) + delete(dec, rowKeyNode) + + buf.Reset() + if err := json.NewEncoder(buf).Encode(dec); err != nil { + return nil, err + } + + // Create a empty retType instance + tEntries[i] = reflect.New(retType.Elem()).Interface().(TableEntity) + // Popolate it with the values + if err := json.NewDecoder(buf).Decode(&tEntries[i]); err != nil { + return nil, err + } + + // Reset PartitionKey and RowKey + tEntries[i].SetPartitionKey(pKey) + tEntries[i].SetRowKey(rKey) + } + + return tEntries, nil +} + +func extractContinuationTokenFromHeaders(h http.Header) *ContinuationToken { + ct := ContinuationToken{h.Get(continuationTokenPartitionKeyHeader), h.Get(continuationTokenRowHeader)} + + if ct.NextPartitionKey != "" && ct.NextRowKey != "" { + return &ct + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go new file mode 100644 index 0000000000..d71c6ce55d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go @@ -0,0 +1,85 @@ +package storage + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "time" +) + +func (c Client) computeHmac256(message string) string { + h := hmac.New(sha256.New, c.accountKey) + h.Write([]byte(message)) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func currentTimeRfc1123Formatted() string { + return timeRfc1123Formatted(time.Now().UTC()) +} + +func timeRfc1123Formatted(t time.Time) string { + return t.Format(http.TimeFormat) +} + +func mergeParams(v1, v2 url.Values) url.Values { + out := url.Values{} + for k, v := range v1 { + out[k] = v + } + for k, v := range v2 { + vals, ok := out[k] + if ok { + vals = append(vals, v...) + out[k] = vals + } else { + out[k] = v + } + } + return out +} + +func prepareBlockListRequest(blocks []Block) string { + s := `` + for _, v := range blocks { + s += fmt.Sprintf("<%s>%s", v.Status, v.ID, v.Status) + } + s += `` + return s +} + +func xmlUnmarshal(body io.Reader, v interface{}) error { + data, err := ioutil.ReadAll(body) + if err != nil { + return err + } + return xml.Unmarshal(data, v) +} + +func xmlMarshal(v interface{}) (io.Reader, int, error) { + b, err := xml.Marshal(v) + if err != nil { + return nil, 0, err + } + return bytes.NewReader(b), len(b), nil +} + +func headersFromStruct(v interface{}) map[string]string { + headers := make(map[string]string) + value := reflect.ValueOf(v) + for i := 0; i < value.NumField(); i++ { + key := value.Type().Field(i).Tag.Get("header") + val := value.Field(i).String() + if val != "" { + headers[key] = val + } + } + return headers +} diff --git a/vendor/github.com/Azure/go-ansiterm/LICENSE b/vendor/github.com/Azure/go-ansiterm/LICENSE new file mode 100644 index 0000000000..e3d9a64d1d --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/Azure/go-ansiterm/README.md b/vendor/github.com/Azure/go-ansiterm/README.md new file mode 100644 index 0000000000..261c041e7a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/README.md @@ -0,0 +1,12 @@ +# go-ansiterm + +This is a cross platform Ansi Terminal Emulation library. It reads a stream of Ansi characters and produces the appropriate function calls. The results of the function calls are platform dependent. + +For example the parser might receive "ESC, [, A" as a stream of three characters. This is the code for Cursor Up (http://www.vt100.net/docs/vt510-rm/CUU). The parser then calls the cursor up function (CUU()) on an event handler. The event handler determines what platform specific work must be done to cause the cursor to move up one position. + +The parser (parser.go) is a partial implementation of this state machine (http://vt100.net/emu/vt500_parser.png). There are also two event handler implementations, one for tests (test_event_handler.go) to validate that the expected events are being produced and called, the other is a Windows implementation (winterm/win_event_handler.go). + +See parser_test.go for examples exercising the state machine and generating appropriate function calls. + +----- +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/vendor/github.com/Azure/go-ansiterm/constants.go b/vendor/github.com/Azure/go-ansiterm/constants.go new file mode 100644 index 0000000000..96504a33bc --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/constants.go @@ -0,0 +1,188 @@ +package ansiterm + +const LogEnv = "DEBUG_TERMINAL" + +// ANSI constants +// References: +// -- http://www.ecma-international.org/publications/standards/Ecma-048.htm +// -- http://man7.org/linux/man-pages/man4/console_codes.4.html +// -- http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html +// -- http://en.wikipedia.org/wiki/ANSI_escape_code +// -- http://vt100.net/emu/dec_ansi_parser +// -- http://vt100.net/emu/vt500_parser.svg +// -- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html +// -- http://www.inwap.com/pdp10/ansicode.txt +const ( + // ECMA-48 Set Graphics Rendition + // Note: + // -- Constants leading with an underscore (e.g., _ANSI_xxx) are unsupported or reserved + // -- Fonts could possibly be supported via SetCurrentConsoleFontEx + // -- Windows does not expose the per-window cursor (i.e., caret) blink times + ANSI_SGR_RESET = 0 + ANSI_SGR_BOLD = 1 + ANSI_SGR_DIM = 2 + _ANSI_SGR_ITALIC = 3 + ANSI_SGR_UNDERLINE = 4 + _ANSI_SGR_BLINKSLOW = 5 + _ANSI_SGR_BLINKFAST = 6 + ANSI_SGR_REVERSE = 7 + _ANSI_SGR_INVISIBLE = 8 + _ANSI_SGR_LINETHROUGH = 9 + _ANSI_SGR_FONT_00 = 10 + _ANSI_SGR_FONT_01 = 11 + _ANSI_SGR_FONT_02 = 12 + _ANSI_SGR_FONT_03 = 13 + _ANSI_SGR_FONT_04 = 14 + _ANSI_SGR_FONT_05 = 15 + _ANSI_SGR_FONT_06 = 16 + _ANSI_SGR_FONT_07 = 17 + _ANSI_SGR_FONT_08 = 18 + _ANSI_SGR_FONT_09 = 19 + _ANSI_SGR_FONT_10 = 20 + _ANSI_SGR_DOUBLEUNDERLINE = 21 + ANSI_SGR_BOLD_DIM_OFF = 22 + _ANSI_SGR_ITALIC_OFF = 23 + ANSI_SGR_UNDERLINE_OFF = 24 + _ANSI_SGR_BLINK_OFF = 25 + _ANSI_SGR_RESERVED_00 = 26 + ANSI_SGR_REVERSE_OFF = 27 + _ANSI_SGR_INVISIBLE_OFF = 28 + _ANSI_SGR_LINETHROUGH_OFF = 29 + ANSI_SGR_FOREGROUND_BLACK = 30 + ANSI_SGR_FOREGROUND_RED = 31 + ANSI_SGR_FOREGROUND_GREEN = 32 + ANSI_SGR_FOREGROUND_YELLOW = 33 + ANSI_SGR_FOREGROUND_BLUE = 34 + ANSI_SGR_FOREGROUND_MAGENTA = 35 + ANSI_SGR_FOREGROUND_CYAN = 36 + ANSI_SGR_FOREGROUND_WHITE = 37 + _ANSI_SGR_RESERVED_01 = 38 + ANSI_SGR_FOREGROUND_DEFAULT = 39 + ANSI_SGR_BACKGROUND_BLACK = 40 + ANSI_SGR_BACKGROUND_RED = 41 + ANSI_SGR_BACKGROUND_GREEN = 42 + ANSI_SGR_BACKGROUND_YELLOW = 43 + ANSI_SGR_BACKGROUND_BLUE = 44 + ANSI_SGR_BACKGROUND_MAGENTA = 45 + ANSI_SGR_BACKGROUND_CYAN = 46 + ANSI_SGR_BACKGROUND_WHITE = 47 + _ANSI_SGR_RESERVED_02 = 48 + ANSI_SGR_BACKGROUND_DEFAULT = 49 + // 50 - 65: Unsupported + + ANSI_MAX_CMD_LENGTH = 4096 + + MAX_INPUT_EVENTS = 128 + DEFAULT_WIDTH = 80 + DEFAULT_HEIGHT = 24 + + ANSI_BEL = 0x07 + ANSI_BACKSPACE = 0x08 + ANSI_TAB = 0x09 + ANSI_LINE_FEED = 0x0A + ANSI_VERTICAL_TAB = 0x0B + ANSI_FORM_FEED = 0x0C + ANSI_CARRIAGE_RETURN = 0x0D + ANSI_ESCAPE_PRIMARY = 0x1B + ANSI_ESCAPE_SECONDARY = 0x5B + ANSI_OSC_STRING_ENTRY = 0x5D + ANSI_COMMAND_FIRST = 0x40 + ANSI_COMMAND_LAST = 0x7E + DCS_ENTRY = 0x90 + CSI_ENTRY = 0x9B + OSC_STRING = 0x9D + ANSI_PARAMETER_SEP = ";" + ANSI_CMD_G0 = '(' + ANSI_CMD_G1 = ')' + ANSI_CMD_G2 = '*' + ANSI_CMD_G3 = '+' + ANSI_CMD_DECPNM = '>' + ANSI_CMD_DECPAM = '=' + ANSI_CMD_OSC = ']' + ANSI_CMD_STR_TERM = '\\' + + KEY_CONTROL_PARAM_2 = ";2" + KEY_CONTROL_PARAM_3 = ";3" + KEY_CONTROL_PARAM_4 = ";4" + KEY_CONTROL_PARAM_5 = ";5" + KEY_CONTROL_PARAM_6 = ";6" + KEY_CONTROL_PARAM_7 = ";7" + KEY_CONTROL_PARAM_8 = ";8" + KEY_ESC_CSI = "\x1B[" + KEY_ESC_N = "\x1BN" + KEY_ESC_O = "\x1BO" + + FILL_CHARACTER = ' ' +) + +func getByteRange(start byte, end byte) []byte { + bytes := make([]byte, 0, 32) + for i := start; i <= end; i++ { + bytes = append(bytes, byte(i)) + } + + return bytes +} + +var toGroundBytes = getToGroundBytes() +var executors = getExecuteBytes() + +// SPACE 20+A0 hex Always and everywhere a blank space +// Intermediate 20-2F hex !"#$%&'()*+,-./ +var intermeds = getByteRange(0x20, 0x2F) + +// Parameters 30-3F hex 0123456789:;<=>? +// CSI Parameters 30-39, 3B hex 0123456789; +var csiParams = getByteRange(0x30, 0x3F) + +var csiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...) + +// Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +var upperCase = getByteRange(0x40, 0x5F) + +// Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~ +var lowerCase = getByteRange(0x60, 0x7E) + +// Alphabetics 40-7E hex (all of upper and lower case) +var alphabetics = append(upperCase, lowerCase...) + +var printables = getByteRange(0x20, 0x7F) + +var escapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E) +var escapeToGroundBytes = getEscapeToGroundBytes() + +// See http://www.vt100.net/emu/vt500_parser.png for description of the complex +// byte ranges below + +func getEscapeToGroundBytes() []byte { + escapeToGroundBytes := getByteRange(0x30, 0x4F) + escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x51, 0x57)...) + escapeToGroundBytes = append(escapeToGroundBytes, 0x59) + escapeToGroundBytes = append(escapeToGroundBytes, 0x5A) + escapeToGroundBytes = append(escapeToGroundBytes, 0x5C) + escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x60, 0x7E)...) + return escapeToGroundBytes +} + +func getExecuteBytes() []byte { + executeBytes := getByteRange(0x00, 0x17) + executeBytes = append(executeBytes, 0x19) + executeBytes = append(executeBytes, getByteRange(0x1C, 0x1F)...) + return executeBytes +} + +func getToGroundBytes() []byte { + groundBytes := []byte{0x18} + groundBytes = append(groundBytes, 0x1A) + groundBytes = append(groundBytes, getByteRange(0x80, 0x8F)...) + groundBytes = append(groundBytes, getByteRange(0x91, 0x97)...) + groundBytes = append(groundBytes, 0x99) + groundBytes = append(groundBytes, 0x9A) + groundBytes = append(groundBytes, 0x9C) + return groundBytes +} + +// Delete 7F hex Always and everywhere ignored +// C1 Control 80-9F hex 32 additional control characters +// G1 Displayable A1-FE hex 94 additional displayable characters +// Special A0+FF hex Same as SPACE and DELETE diff --git a/vendor/github.com/Azure/go-ansiterm/context.go b/vendor/github.com/Azure/go-ansiterm/context.go new file mode 100644 index 0000000000..8d66e777c0 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/context.go @@ -0,0 +1,7 @@ +package ansiterm + +type ansiContext struct { + currentChar byte + paramBuffer []byte + interBuffer []byte +} diff --git a/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go b/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go new file mode 100644 index 0000000000..bcbe00d0c5 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go @@ -0,0 +1,49 @@ +package ansiterm + +type csiEntryState struct { + baseState +} + +func (csiState csiEntryState) Handle(b byte) (s state, e error) { + csiState.parser.logf("CsiEntry::Handle %#x", b) + + nextState, err := csiState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(alphabetics, b): + return csiState.parser.ground, nil + case sliceContains(csiCollectables, b): + return csiState.parser.csiParam, nil + case sliceContains(executors, b): + return csiState, csiState.parser.execute() + } + + return csiState, nil +} + +func (csiState csiEntryState) Transition(s state) error { + csiState.parser.logf("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name()) + csiState.baseState.Transition(s) + + switch s { + case csiState.parser.ground: + return csiState.parser.csiDispatch() + case csiState.parser.csiParam: + switch { + case sliceContains(csiParams, csiState.parser.context.currentChar): + csiState.parser.collectParam() + case sliceContains(intermeds, csiState.parser.context.currentChar): + csiState.parser.collectInter() + } + } + + return nil +} + +func (csiState csiEntryState) Enter() error { + csiState.parser.clear() + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/csi_param_state.go b/vendor/github.com/Azure/go-ansiterm/csi_param_state.go new file mode 100644 index 0000000000..7ed5e01c34 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/csi_param_state.go @@ -0,0 +1,38 @@ +package ansiterm + +type csiParamState struct { + baseState +} + +func (csiState csiParamState) Handle(b byte) (s state, e error) { + csiState.parser.logf("CsiParam::Handle %#x", b) + + nextState, err := csiState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(alphabetics, b): + return csiState.parser.ground, nil + case sliceContains(csiCollectables, b): + csiState.parser.collectParam() + return csiState, nil + case sliceContains(executors, b): + return csiState, csiState.parser.execute() + } + + return csiState, nil +} + +func (csiState csiParamState) Transition(s state) error { + csiState.parser.logf("CsiParam::Transition %s --> %s", csiState.Name(), s.Name()) + csiState.baseState.Transition(s) + + switch s { + case csiState.parser.ground: + return csiState.parser.csiDispatch() + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go b/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go new file mode 100644 index 0000000000..1c719db9e4 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go @@ -0,0 +1,36 @@ +package ansiterm + +type escapeIntermediateState struct { + baseState +} + +func (escState escapeIntermediateState) Handle(b byte) (s state, e error) { + escState.parser.logf("escapeIntermediateState::Handle %#x", b) + nextState, err := escState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(intermeds, b): + return escState, escState.parser.collectInter() + case sliceContains(executors, b): + return escState, escState.parser.execute() + case sliceContains(escapeIntermediateToGroundBytes, b): + return escState.parser.ground, nil + } + + return escState, nil +} + +func (escState escapeIntermediateState) Transition(s state) error { + escState.parser.logf("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name()) + escState.baseState.Transition(s) + + switch s { + case escState.parser.ground: + return escState.parser.escDispatch() + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/escape_state.go b/vendor/github.com/Azure/go-ansiterm/escape_state.go new file mode 100644 index 0000000000..6390abd231 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/escape_state.go @@ -0,0 +1,47 @@ +package ansiterm + +type escapeState struct { + baseState +} + +func (escState escapeState) Handle(b byte) (s state, e error) { + escState.parser.logf("escapeState::Handle %#x", b) + nextState, err := escState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case b == ANSI_ESCAPE_SECONDARY: + return escState.parser.csiEntry, nil + case b == ANSI_OSC_STRING_ENTRY: + return escState.parser.oscString, nil + case sliceContains(executors, b): + return escState, escState.parser.execute() + case sliceContains(escapeToGroundBytes, b): + return escState.parser.ground, nil + case sliceContains(intermeds, b): + return escState.parser.escapeIntermediate, nil + } + + return escState, nil +} + +func (escState escapeState) Transition(s state) error { + escState.parser.logf("Escape::Transition %s --> %s", escState.Name(), s.Name()) + escState.baseState.Transition(s) + + switch s { + case escState.parser.ground: + return escState.parser.escDispatch() + case escState.parser.escapeIntermediate: + return escState.parser.collectInter() + } + + return nil +} + +func (escState escapeState) Enter() error { + escState.parser.clear() + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/event_handler.go b/vendor/github.com/Azure/go-ansiterm/event_handler.go new file mode 100644 index 0000000000..98087b38c2 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/event_handler.go @@ -0,0 +1,90 @@ +package ansiterm + +type AnsiEventHandler interface { + // Print + Print(b byte) error + + // Execute C0 commands + Execute(b byte) error + + // CUrsor Up + CUU(int) error + + // CUrsor Down + CUD(int) error + + // CUrsor Forward + CUF(int) error + + // CUrsor Backward + CUB(int) error + + // Cursor to Next Line + CNL(int) error + + // Cursor to Previous Line + CPL(int) error + + // Cursor Horizontal position Absolute + CHA(int) error + + // Vertical line Position Absolute + VPA(int) error + + // CUrsor Position + CUP(int, int) error + + // Horizontal and Vertical Position (depends on PUM) + HVP(int, int) error + + // Text Cursor Enable Mode + DECTCEM(bool) error + + // Origin Mode + DECOM(bool) error + + // 132 Column Mode + DECCOLM(bool) error + + // Erase in Display + ED(int) error + + // Erase in Line + EL(int) error + + // Insert Line + IL(int) error + + // Delete Line + DL(int) error + + // Insert Character + ICH(int) error + + // Delete Character + DCH(int) error + + // Set Graphics Rendition + SGR([]int) error + + // Pan Down + SU(int) error + + // Pan Up + SD(int) error + + // Device Attributes + DA([]string) error + + // Set Top and Bottom Margins + DECSTBM(int, int) error + + // Index + IND() error + + // Reverse Index + RI() error + + // Flush updates from previous commands + Flush() error +} diff --git a/vendor/github.com/Azure/go-ansiterm/ground_state.go b/vendor/github.com/Azure/go-ansiterm/ground_state.go new file mode 100644 index 0000000000..52451e9469 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/ground_state.go @@ -0,0 +1,24 @@ +package ansiterm + +type groundState struct { + baseState +} + +func (gs groundState) Handle(b byte) (s state, e error) { + gs.parser.context.currentChar = b + + nextState, err := gs.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(printables, b): + return gs, gs.parser.print() + + case sliceContains(executors, b): + return gs, gs.parser.execute() + } + + return gs, nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/osc_string_state.go b/vendor/github.com/Azure/go-ansiterm/osc_string_state.go new file mode 100644 index 0000000000..593b10ab69 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/osc_string_state.go @@ -0,0 +1,31 @@ +package ansiterm + +type oscStringState struct { + baseState +} + +func (oscState oscStringState) Handle(b byte) (s state, e error) { + oscState.parser.logf("OscString::Handle %#x", b) + nextState, err := oscState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case isOscStringTerminator(b): + return oscState.parser.ground, nil + } + + return oscState, nil +} + +// See below for OSC string terminators for linux +// http://man7.org/linux/man-pages/man4/console_codes.4.html +func isOscStringTerminator(b byte) bool { + + if b == ANSI_BEL || b == 0x5C { + return true + } + + return false +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser.go b/vendor/github.com/Azure/go-ansiterm/parser.go new file mode 100644 index 0000000000..03cec7ada6 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser.go @@ -0,0 +1,151 @@ +package ansiterm + +import ( + "errors" + "log" + "os" +) + +type AnsiParser struct { + currState state + eventHandler AnsiEventHandler + context *ansiContext + csiEntry state + csiParam state + dcsEntry state + escape state + escapeIntermediate state + error state + ground state + oscString state + stateMap []state + + logf func(string, ...interface{}) +} + +type Option func(*AnsiParser) + +func WithLogf(f func(string, ...interface{})) Option { + return func(ap *AnsiParser) { + ap.logf = f + } +} + +func CreateParser(initialState string, evtHandler AnsiEventHandler, opts ...Option) *AnsiParser { + ap := &AnsiParser{ + eventHandler: evtHandler, + context: &ansiContext{}, + } + for _, o := range opts { + o(ap) + } + + if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" { + logFile, _ := os.Create("ansiParser.log") + logger := log.New(logFile, "", log.LstdFlags) + if ap.logf != nil { + l := ap.logf + ap.logf = func(s string, v ...interface{}) { + l(s, v...) + logger.Printf(s, v...) + } + } else { + ap.logf = logger.Printf + } + } + + if ap.logf == nil { + ap.logf = func(string, ...interface{}) {} + } + + ap.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: ap}} + ap.csiParam = csiParamState{baseState{name: "CsiParam", parser: ap}} + ap.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: ap}} + ap.escape = escapeState{baseState{name: "Escape", parser: ap}} + ap.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: ap}} + ap.error = errorState{baseState{name: "Error", parser: ap}} + ap.ground = groundState{baseState{name: "Ground", parser: ap}} + ap.oscString = oscStringState{baseState{name: "OscString", parser: ap}} + + ap.stateMap = []state{ + ap.csiEntry, + ap.csiParam, + ap.dcsEntry, + ap.escape, + ap.escapeIntermediate, + ap.error, + ap.ground, + ap.oscString, + } + + ap.currState = getState(initialState, ap.stateMap) + + ap.logf("CreateParser: parser %p", ap) + return ap +} + +func getState(name string, states []state) state { + for _, el := range states { + if el.Name() == name { + return el + } + } + + return nil +} + +func (ap *AnsiParser) Parse(bytes []byte) (int, error) { + for i, b := range bytes { + if err := ap.handle(b); err != nil { + return i, err + } + } + + return len(bytes), ap.eventHandler.Flush() +} + +func (ap *AnsiParser) handle(b byte) error { + ap.context.currentChar = b + newState, err := ap.currState.Handle(b) + if err != nil { + return err + } + + if newState == nil { + ap.logf("WARNING: newState is nil") + return errors.New("New state of 'nil' is invalid.") + } + + if newState != ap.currState { + if err := ap.changeState(newState); err != nil { + return err + } + } + + return nil +} + +func (ap *AnsiParser) changeState(newState state) error { + ap.logf("ChangeState %s --> %s", ap.currState.Name(), newState.Name()) + + // Exit old state + if err := ap.currState.Exit(); err != nil { + ap.logf("Exit state '%s' failed with : '%v'", ap.currState.Name(), err) + return err + } + + // Perform transition action + if err := ap.currState.Transition(newState); err != nil { + ap.logf("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err) + return err + } + + // Enter new state + if err := newState.Enter(); err != nil { + ap.logf("Enter state '%s' failed with: '%v'", newState.Name(), err) + return err + } + + ap.currState = newState + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go b/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go new file mode 100644 index 0000000000..de0a1f9cde --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go @@ -0,0 +1,99 @@ +package ansiterm + +import ( + "strconv" +) + +func parseParams(bytes []byte) ([]string, error) { + paramBuff := make([]byte, 0, 0) + params := []string{} + + for _, v := range bytes { + if v == ';' { + if len(paramBuff) > 0 { + // Completed parameter, append it to the list + s := string(paramBuff) + params = append(params, s) + paramBuff = make([]byte, 0, 0) + } + } else { + paramBuff = append(paramBuff, v) + } + } + + // Last parameter may not be terminated with ';' + if len(paramBuff) > 0 { + s := string(paramBuff) + params = append(params, s) + } + + return params, nil +} + +func parseCmd(context ansiContext) (string, error) { + return string(context.currentChar), nil +} + +func getInt(params []string, dflt int) int { + i := getInts(params, 1, dflt)[0] + return i +} + +func getInts(params []string, minCount int, dflt int) []int { + ints := []int{} + + for _, v := range params { + i, _ := strconv.Atoi(v) + // Zero is mapped to the default value in VT100. + if i == 0 { + i = dflt + } + ints = append(ints, i) + } + + if len(ints) < minCount { + remaining := minCount - len(ints) + for i := 0; i < remaining; i++ { + ints = append(ints, dflt) + } + } + + return ints +} + +func (ap *AnsiParser) modeDispatch(param string, set bool) error { + switch param { + case "?3": + return ap.eventHandler.DECCOLM(set) + case "?6": + return ap.eventHandler.DECOM(set) + case "?25": + return ap.eventHandler.DECTCEM(set) + } + return nil +} + +func (ap *AnsiParser) hDispatch(params []string) error { + if len(params) == 1 { + return ap.modeDispatch(params[0], true) + } + + return nil +} + +func (ap *AnsiParser) lDispatch(params []string) error { + if len(params) == 1 { + return ap.modeDispatch(params[0], false) + } + + return nil +} + +func getEraseParam(params []string) int { + param := getInt(params, 0) + if param < 0 || 3 < param { + param = 0 + } + + return param +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser_actions.go b/vendor/github.com/Azure/go-ansiterm/parser_actions.go new file mode 100644 index 0000000000..0bb5e51e9a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser_actions.go @@ -0,0 +1,119 @@ +package ansiterm + +func (ap *AnsiParser) collectParam() error { + currChar := ap.context.currentChar + ap.logf("collectParam %#x", currChar) + ap.context.paramBuffer = append(ap.context.paramBuffer, currChar) + return nil +} + +func (ap *AnsiParser) collectInter() error { + currChar := ap.context.currentChar + ap.logf("collectInter %#x", currChar) + ap.context.paramBuffer = append(ap.context.interBuffer, currChar) + return nil +} + +func (ap *AnsiParser) escDispatch() error { + cmd, _ := parseCmd(*ap.context) + intermeds := ap.context.interBuffer + ap.logf("escDispatch currentChar: %#x", ap.context.currentChar) + ap.logf("escDispatch: %v(%v)", cmd, intermeds) + + switch cmd { + case "D": // IND + return ap.eventHandler.IND() + case "E": // NEL, equivalent to CRLF + err := ap.eventHandler.Execute(ANSI_CARRIAGE_RETURN) + if err == nil { + err = ap.eventHandler.Execute(ANSI_LINE_FEED) + } + return err + case "M": // RI + return ap.eventHandler.RI() + } + + return nil +} + +func (ap *AnsiParser) csiDispatch() error { + cmd, _ := parseCmd(*ap.context) + params, _ := parseParams(ap.context.paramBuffer) + ap.logf("Parsed params: %v with length: %d", params, len(params)) + + ap.logf("csiDispatch: %v(%v)", cmd, params) + + switch cmd { + case "@": + return ap.eventHandler.ICH(getInt(params, 1)) + case "A": + return ap.eventHandler.CUU(getInt(params, 1)) + case "B": + return ap.eventHandler.CUD(getInt(params, 1)) + case "C": + return ap.eventHandler.CUF(getInt(params, 1)) + case "D": + return ap.eventHandler.CUB(getInt(params, 1)) + case "E": + return ap.eventHandler.CNL(getInt(params, 1)) + case "F": + return ap.eventHandler.CPL(getInt(params, 1)) + case "G": + return ap.eventHandler.CHA(getInt(params, 1)) + case "H": + ints := getInts(params, 2, 1) + x, y := ints[0], ints[1] + return ap.eventHandler.CUP(x, y) + case "J": + param := getEraseParam(params) + return ap.eventHandler.ED(param) + case "K": + param := getEraseParam(params) + return ap.eventHandler.EL(param) + case "L": + return ap.eventHandler.IL(getInt(params, 1)) + case "M": + return ap.eventHandler.DL(getInt(params, 1)) + case "P": + return ap.eventHandler.DCH(getInt(params, 1)) + case "S": + return ap.eventHandler.SU(getInt(params, 1)) + case "T": + return ap.eventHandler.SD(getInt(params, 1)) + case "c": + return ap.eventHandler.DA(params) + case "d": + return ap.eventHandler.VPA(getInt(params, 1)) + case "f": + ints := getInts(params, 2, 1) + x, y := ints[0], ints[1] + return ap.eventHandler.HVP(x, y) + case "h": + return ap.hDispatch(params) + case "l": + return ap.lDispatch(params) + case "m": + return ap.eventHandler.SGR(getInts(params, 1, 0)) + case "r": + ints := getInts(params, 2, 1) + top, bottom := ints[0], ints[1] + return ap.eventHandler.DECSTBM(top, bottom) + default: + ap.logf("ERROR: Unsupported CSI command: '%s', with full context: %v", cmd, ap.context) + return nil + } + +} + +func (ap *AnsiParser) print() error { + return ap.eventHandler.Print(ap.context.currentChar) +} + +func (ap *AnsiParser) clear() error { + ap.context = &ansiContext{} + return nil +} + +func (ap *AnsiParser) execute() error { + return ap.eventHandler.Execute(ap.context.currentChar) +} diff --git a/vendor/github.com/Azure/go-ansiterm/states.go b/vendor/github.com/Azure/go-ansiterm/states.go new file mode 100644 index 0000000000..f2ea1fcd12 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/states.go @@ -0,0 +1,71 @@ +package ansiterm + +type stateID int + +type state interface { + Enter() error + Exit() error + Handle(byte) (state, error) + Name() string + Transition(state) error +} + +type baseState struct { + name string + parser *AnsiParser +} + +func (base baseState) Enter() error { + return nil +} + +func (base baseState) Exit() error { + return nil +} + +func (base baseState) Handle(b byte) (s state, e error) { + + switch { + case b == CSI_ENTRY: + return base.parser.csiEntry, nil + case b == DCS_ENTRY: + return base.parser.dcsEntry, nil + case b == ANSI_ESCAPE_PRIMARY: + return base.parser.escape, nil + case b == OSC_STRING: + return base.parser.oscString, nil + case sliceContains(toGroundBytes, b): + return base.parser.ground, nil + } + + return nil, nil +} + +func (base baseState) Name() string { + return base.name +} + +func (base baseState) Transition(s state) error { + if s == base.parser.ground { + execBytes := []byte{0x18} + execBytes = append(execBytes, 0x1A) + execBytes = append(execBytes, getByteRange(0x80, 0x8F)...) + execBytes = append(execBytes, getByteRange(0x91, 0x97)...) + execBytes = append(execBytes, 0x99) + execBytes = append(execBytes, 0x9A) + + if sliceContains(execBytes, base.parser.context.currentChar) { + return base.parser.execute() + } + } + + return nil +} + +type dcsEntryState struct { + baseState +} + +type errorState struct { + baseState +} diff --git a/vendor/github.com/Azure/go-ansiterm/utilities.go b/vendor/github.com/Azure/go-ansiterm/utilities.go new file mode 100644 index 0000000000..392114493a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/utilities.go @@ -0,0 +1,21 @@ +package ansiterm + +import ( + "strconv" +) + +func sliceContains(bytes []byte, b byte) bool { + for _, v := range bytes { + if v == b { + return true + } + } + + return false +} + +func convertBytesToInteger(bytes []byte) int { + s := string(bytes) + i, _ := strconv.Atoi(s) + return i +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go b/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go new file mode 100644 index 0000000000..a673279726 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go @@ -0,0 +1,182 @@ +// +build windows + +package winterm + +import ( + "fmt" + "os" + "strconv" + "strings" + "syscall" + + "github.com/Azure/go-ansiterm" +) + +// Windows keyboard constants +// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx. +const ( + VK_PRIOR = 0x21 // PAGE UP key + VK_NEXT = 0x22 // PAGE DOWN key + VK_END = 0x23 // END key + VK_HOME = 0x24 // HOME key + VK_LEFT = 0x25 // LEFT ARROW key + VK_UP = 0x26 // UP ARROW key + VK_RIGHT = 0x27 // RIGHT ARROW key + VK_DOWN = 0x28 // DOWN ARROW key + VK_SELECT = 0x29 // SELECT key + VK_PRINT = 0x2A // PRINT key + VK_EXECUTE = 0x2B // EXECUTE key + VK_SNAPSHOT = 0x2C // PRINT SCREEN key + VK_INSERT = 0x2D // INS key + VK_DELETE = 0x2E // DEL key + VK_HELP = 0x2F // HELP key + VK_F1 = 0x70 // F1 key + VK_F2 = 0x71 // F2 key + VK_F3 = 0x72 // F3 key + VK_F4 = 0x73 // F4 key + VK_F5 = 0x74 // F5 key + VK_F6 = 0x75 // F6 key + VK_F7 = 0x76 // F7 key + VK_F8 = 0x77 // F8 key + VK_F9 = 0x78 // F9 key + VK_F10 = 0x79 // F10 key + VK_F11 = 0x7A // F11 key + VK_F12 = 0x7B // F12 key + + RIGHT_ALT_PRESSED = 0x0001 + LEFT_ALT_PRESSED = 0x0002 + RIGHT_CTRL_PRESSED = 0x0004 + LEFT_CTRL_PRESSED = 0x0008 + SHIFT_PRESSED = 0x0010 + NUMLOCK_ON = 0x0020 + SCROLLLOCK_ON = 0x0040 + CAPSLOCK_ON = 0x0080 + ENHANCED_KEY = 0x0100 +) + +type ansiCommand struct { + CommandBytes []byte + Command string + Parameters []string + IsSpecial bool +} + +func newAnsiCommand(command []byte) *ansiCommand { + + if isCharacterSelectionCmdChar(command[1]) { + // Is Character Set Selection commands + return &ansiCommand{ + CommandBytes: command, + Command: string(command), + IsSpecial: true, + } + } + + // last char is command character + lastCharIndex := len(command) - 1 + + ac := &ansiCommand{ + CommandBytes: command, + Command: string(command[lastCharIndex]), + IsSpecial: false, + } + + // more than a single escape + if lastCharIndex != 0 { + start := 1 + // skip if double char escape sequence + if command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY { + start++ + } + // convert this to GetNextParam method + ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP) + } + + return ac +} + +func (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 { + if index < 0 || index >= len(ac.Parameters) { + return defaultValue + } + + param, err := strconv.ParseInt(ac.Parameters[index], 10, 16) + if err != nil { + return defaultValue + } + + return int16(param) +} + +func (ac *ansiCommand) String() string { + return fmt.Sprintf("0x%v \"%v\" (\"%v\")", + bytesToHex(ac.CommandBytes), + ac.Command, + strings.Join(ac.Parameters, "\",\"")) +} + +// isAnsiCommandChar returns true if the passed byte falls within the range of ANSI commands. +// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html. +func isAnsiCommandChar(b byte) bool { + switch { + case ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY: + return true + case b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_OSC || b == ansiterm.ANSI_CMD_DECPAM || b == ansiterm.ANSI_CMD_DECPNM: + // non-CSI escape sequence terminator + return true + case b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL: + // String escape sequence terminator + return true + } + return false +} + +func isXtermOscSequence(command []byte, current byte) bool { + return (len(command) >= 2 && command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_CMD_OSC && current != ansiterm.ANSI_BEL) +} + +func isCharacterSelectionCmdChar(b byte) bool { + return (b == ansiterm.ANSI_CMD_G0 || b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_G2 || b == ansiterm.ANSI_CMD_G3) +} + +// bytesToHex converts a slice of bytes to a human-readable string. +func bytesToHex(b []byte) string { + hex := make([]string, len(b)) + for i, ch := range b { + hex[i] = fmt.Sprintf("%X", ch) + } + return strings.Join(hex, "") +} + +// ensureInRange adjusts the passed value, if necessary, to ensure it is within +// the passed min / max range. +func ensureInRange(n int16, min int16, max int16) int16 { + if n < min { + return min + } else if n > max { + return max + } else { + return n + } +} + +func GetStdFile(nFile int) (*os.File, uintptr) { + var file *os.File + switch nFile { + case syscall.STD_INPUT_HANDLE: + file = os.Stdin + case syscall.STD_OUTPUT_HANDLE: + file = os.Stdout + case syscall.STD_ERROR_HANDLE: + file = os.Stderr + default: + panic(fmt.Errorf("Invalid standard handle identifier: %v", nFile)) + } + + fd, err := syscall.GetStdHandle(nFile) + if err != nil { + panic(fmt.Errorf("Invalid standard handle identifier: %v -- %v", nFile, err)) + } + + return file, uintptr(fd) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/api.go b/vendor/github.com/Azure/go-ansiterm/winterm/api.go new file mode 100644 index 0000000000..6055e33b91 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/api.go @@ -0,0 +1,327 @@ +// +build windows + +package winterm + +import ( + "fmt" + "syscall" + "unsafe" +) + +//=========================================================================================================== +// IMPORTANT NOTE: +// +// The methods below make extensive use of the "unsafe" package to obtain the required pointers. +// Beginning in Go 1.3, the garbage collector may release local variables (e.g., incoming arguments, stack +// variables) the pointers reference *before* the API completes. +// +// As a result, in those cases, the code must hint that the variables remain in active by invoking the +// dummy method "use" (see below). Newer versions of Go are planned to change the mechanism to no longer +// require unsafe pointers. +// +// If you add or modify methods, ENSURE protection of local variables through the "use" builtin to inform +// the garbage collector the variables remain in use if: +// +// -- The value is not a pointer (e.g., int32, struct) +// -- The value is not referenced by the method after passing the pointer to Windows +// +// See http://golang.org/doc/go1.3. +//=========================================================================================================== + +var ( + kernel32DLL = syscall.NewLazyDLL("kernel32.dll") + + getConsoleCursorInfoProc = kernel32DLL.NewProc("GetConsoleCursorInfo") + setConsoleCursorInfoProc = kernel32DLL.NewProc("SetConsoleCursorInfo") + setConsoleCursorPositionProc = kernel32DLL.NewProc("SetConsoleCursorPosition") + setConsoleModeProc = kernel32DLL.NewProc("SetConsoleMode") + getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") + setConsoleScreenBufferSizeProc = kernel32DLL.NewProc("SetConsoleScreenBufferSize") + scrollConsoleScreenBufferProc = kernel32DLL.NewProc("ScrollConsoleScreenBufferA") + setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute") + setConsoleWindowInfoProc = kernel32DLL.NewProc("SetConsoleWindowInfo") + writeConsoleOutputProc = kernel32DLL.NewProc("WriteConsoleOutputW") + readConsoleInputProc = kernel32DLL.NewProc("ReadConsoleInputW") + waitForSingleObjectProc = kernel32DLL.NewProc("WaitForSingleObject") +) + +// Windows Console constants +const ( + // Console modes + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. + ENABLE_PROCESSED_INPUT = 0x0001 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_WINDOW_INPUT = 0x0008 + ENABLE_MOUSE_INPUT = 0x0010 + ENABLE_INSERT_MODE = 0x0020 + ENABLE_QUICK_EDIT_MODE = 0x0040 + ENABLE_EXTENDED_FLAGS = 0x0080 + ENABLE_AUTO_POSITION = 0x0100 + ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200 + + ENABLE_PROCESSED_OUTPUT = 0x0001 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + DISABLE_NEWLINE_AUTO_RETURN = 0x0008 + ENABLE_LVB_GRID_WORLDWIDE = 0x0010 + + // Character attributes + // Note: + // -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan). + // Clearing all foreground or background colors results in black; setting all creates white. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes. + FOREGROUND_BLUE uint16 = 0x0001 + FOREGROUND_GREEN uint16 = 0x0002 + FOREGROUND_RED uint16 = 0x0004 + FOREGROUND_INTENSITY uint16 = 0x0008 + FOREGROUND_MASK uint16 = 0x000F + + BACKGROUND_BLUE uint16 = 0x0010 + BACKGROUND_GREEN uint16 = 0x0020 + BACKGROUND_RED uint16 = 0x0040 + BACKGROUND_INTENSITY uint16 = 0x0080 + BACKGROUND_MASK uint16 = 0x00F0 + + COMMON_LVB_MASK uint16 = 0xFF00 + COMMON_LVB_REVERSE_VIDEO uint16 = 0x4000 + COMMON_LVB_UNDERSCORE uint16 = 0x8000 + + // Input event types + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. + KEY_EVENT = 0x0001 + MOUSE_EVENT = 0x0002 + WINDOW_BUFFER_SIZE_EVENT = 0x0004 + MENU_EVENT = 0x0008 + FOCUS_EVENT = 0x0010 + + // WaitForSingleObject return codes + WAIT_ABANDONED = 0x00000080 + WAIT_FAILED = 0xFFFFFFFF + WAIT_SIGNALED = 0x0000000 + WAIT_TIMEOUT = 0x00000102 + + // WaitForSingleObject wait duration + WAIT_INFINITE = 0xFFFFFFFF + WAIT_ONE_SECOND = 1000 + WAIT_HALF_SECOND = 500 + WAIT_QUARTER_SECOND = 250 +) + +// Windows API Console types +// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD) +// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment +type ( + CHAR_INFO struct { + UnicodeChar uint16 + Attributes uint16 + } + + CONSOLE_CURSOR_INFO struct { + Size uint32 + Visible int32 + } + + CONSOLE_SCREEN_BUFFER_INFO struct { + Size COORD + CursorPosition COORD + Attributes uint16 + Window SMALL_RECT + MaximumWindowSize COORD + } + + COORD struct { + X int16 + Y int16 + } + + SMALL_RECT struct { + Left int16 + Top int16 + Right int16 + Bottom int16 + } + + // INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. + INPUT_RECORD struct { + EventType uint16 + KeyEvent KEY_EVENT_RECORD + } + + KEY_EVENT_RECORD struct { + KeyDown int32 + RepeatCount uint16 + VirtualKeyCode uint16 + VirtualScanCode uint16 + UnicodeChar uint16 + ControlKeyState uint32 + } + + WINDOW_BUFFER_SIZE struct { + Size COORD + } +) + +// boolToBOOL converts a Go bool into a Windows int32. +func boolToBOOL(f bool) int32 { + if f { + return int32(1) + } else { + return int32(0) + } +} + +// GetConsoleCursorInfo retrieves information about the size and visiblity of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683163(v=vs.85).aspx. +func GetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error { + r1, r2, err := getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0) + return checkError(r1, r2, err) +} + +// SetConsoleCursorInfo sets the size and visiblity of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx. +func SetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error { + r1, r2, err := setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0) + return checkError(r1, r2, err) +} + +// SetConsoleCursorPosition location of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx. +func SetConsoleCursorPosition(handle uintptr, coord COORD) error { + r1, r2, err := setConsoleCursorPositionProc.Call(handle, coordToPointer(coord)) + use(coord) + return checkError(r1, r2, err) +} + +// GetConsoleMode gets the console mode for given file descriptor +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx. +func GetConsoleMode(handle uintptr) (mode uint32, err error) { + err = syscall.GetConsoleMode(syscall.Handle(handle), &mode) + return mode, err +} + +// SetConsoleMode sets the console mode for given file descriptor +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. +func SetConsoleMode(handle uintptr, mode uint32) error { + r1, r2, err := setConsoleModeProc.Call(handle, uintptr(mode), 0) + use(mode) + return checkError(r1, r2, err) +} + +// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer. +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx. +func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) { + info := CONSOLE_SCREEN_BUFFER_INFO{} + err := checkError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)) + if err != nil { + return nil, err + } + return &info, nil +} + +func ScrollConsoleScreenBuffer(handle uintptr, scrollRect SMALL_RECT, clipRect SMALL_RECT, destOrigin COORD, char CHAR_INFO) error { + r1, r2, err := scrollConsoleScreenBufferProc.Call(handle, uintptr(unsafe.Pointer(&scrollRect)), uintptr(unsafe.Pointer(&clipRect)), coordToPointer(destOrigin), uintptr(unsafe.Pointer(&char))) + use(scrollRect) + use(clipRect) + use(destOrigin) + use(char) + return checkError(r1, r2, err) +} + +// SetConsoleScreenBufferSize sets the size of the console screen buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686044(v=vs.85).aspx. +func SetConsoleScreenBufferSize(handle uintptr, coord COORD) error { + r1, r2, err := setConsoleScreenBufferSizeProc.Call(handle, coordToPointer(coord)) + use(coord) + return checkError(r1, r2, err) +} + +// SetConsoleTextAttribute sets the attributes of characters written to the +// console screen buffer by the WriteFile or WriteConsole function. +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx. +func SetConsoleTextAttribute(handle uintptr, attribute uint16) error { + r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0) + use(attribute) + return checkError(r1, r2, err) +} + +// SetConsoleWindowInfo sets the size and position of the console screen buffer's window. +// Note that the size and location must be within and no larger than the backing console screen buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx. +func SetConsoleWindowInfo(handle uintptr, isAbsolute bool, rect SMALL_RECT) error { + r1, r2, err := setConsoleWindowInfoProc.Call(handle, uintptr(boolToBOOL(isAbsolute)), uintptr(unsafe.Pointer(&rect))) + use(isAbsolute) + use(rect) + return checkError(r1, r2, err) +} + +// WriteConsoleOutput writes the CHAR_INFOs from the provided buffer to the active console buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687404(v=vs.85).aspx. +func WriteConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) error { + r1, r2, err := writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), coordToPointer(bufferSize), coordToPointer(bufferCoord), uintptr(unsafe.Pointer(writeRegion))) + use(buffer) + use(bufferSize) + use(bufferCoord) + return checkError(r1, r2, err) +} + +// ReadConsoleInput reads (and removes) data from the console input buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx. +func ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) error { + r1, r2, err := readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), uintptr(len(buffer)), uintptr(unsafe.Pointer(count))) + use(buffer) + return checkError(r1, r2, err) +} + +// WaitForSingleObject waits for the passed handle to be signaled. +// It returns true if the handle was signaled; false otherwise. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx. +func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) { + r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait))) + switch r1 { + case WAIT_ABANDONED, WAIT_TIMEOUT: + return false, nil + case WAIT_SIGNALED: + return true, nil + } + use(msWait) + return false, err +} + +// String helpers +func (info CONSOLE_SCREEN_BUFFER_INFO) String() string { + return fmt.Sprintf("Size(%v) Cursor(%v) Window(%v) Max(%v)", info.Size, info.CursorPosition, info.Window, info.MaximumWindowSize) +} + +func (coord COORD) String() string { + return fmt.Sprintf("%v,%v", coord.X, coord.Y) +} + +func (rect SMALL_RECT) String() string { + return fmt.Sprintf("(%v,%v),(%v,%v)", rect.Left, rect.Top, rect.Right, rect.Bottom) +} + +// checkError evaluates the results of a Windows API call and returns the error if it failed. +func checkError(r1, r2 uintptr, err error) error { + // Windows APIs return non-zero to indicate success + if r1 != 0 { + return nil + } + + // Return the error if provided, otherwise default to EINVAL + if err != nil { + return err + } + return syscall.EINVAL +} + +// coordToPointer converts a COORD into a uintptr (by fooling the type system). +func coordToPointer(c COORD) uintptr { + // Note: This code assumes the two SHORTs are correctly laid out; the "cast" to uint32 is just to get a pointer to pass. + return uintptr(*((*uint32)(unsafe.Pointer(&c)))) +} + +// use is a no-op, but the compiler cannot see that it is. +// Calling use(p) ensures that p is kept live until that point. +func use(p interface{}) {} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go b/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go new file mode 100644 index 0000000000..cbec8f728f --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go @@ -0,0 +1,100 @@ +// +build windows + +package winterm + +import "github.com/Azure/go-ansiterm" + +const ( + FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + BACKGROUND_COLOR_MASK = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE +) + +// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the +// request represented by the passed ANSI mode. +func collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) { + switch ansiMode { + + // Mode styles + case ansiterm.ANSI_SGR_BOLD: + windowsMode = windowsMode | FOREGROUND_INTENSITY + + case ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF: + windowsMode &^= FOREGROUND_INTENSITY + + case ansiterm.ANSI_SGR_UNDERLINE: + windowsMode = windowsMode | COMMON_LVB_UNDERSCORE + + case ansiterm.ANSI_SGR_REVERSE: + inverted = true + + case ansiterm.ANSI_SGR_REVERSE_OFF: + inverted = false + + case ansiterm.ANSI_SGR_UNDERLINE_OFF: + windowsMode &^= COMMON_LVB_UNDERSCORE + + // Foreground colors + case ansiterm.ANSI_SGR_FOREGROUND_DEFAULT: + windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK) + + case ansiterm.ANSI_SGR_FOREGROUND_BLACK: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) + + case ansiterm.ANSI_SGR_FOREGROUND_RED: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED + + case ansiterm.ANSI_SGR_FOREGROUND_GREEN: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN + + case ansiterm.ANSI_SGR_FOREGROUND_YELLOW: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN + + case ansiterm.ANSI_SGR_FOREGROUND_BLUE: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_MAGENTA: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_CYAN: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_WHITE: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + + // Background colors + case ansiterm.ANSI_SGR_BACKGROUND_DEFAULT: + // Black with no intensity + windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK) + + case ansiterm.ANSI_SGR_BACKGROUND_BLACK: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) + + case ansiterm.ANSI_SGR_BACKGROUND_RED: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED + + case ansiterm.ANSI_SGR_BACKGROUND_GREEN: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN + + case ansiterm.ANSI_SGR_BACKGROUND_YELLOW: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN + + case ansiterm.ANSI_SGR_BACKGROUND_BLUE: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_MAGENTA: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_CYAN: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_WHITE: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE + } + + return windowsMode, inverted +} + +// invertAttributes inverts the foreground and background colors of a Windows attributes value +func invertAttributes(windowsMode uint16) uint16 { + return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go b/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go new file mode 100644 index 0000000000..3ee06ea728 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go @@ -0,0 +1,101 @@ +// +build windows + +package winterm + +const ( + horizontal = iota + vertical +) + +func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT { + if h.originMode { + sr := h.effectiveSr(info.Window) + return SMALL_RECT{ + Top: sr.top, + Bottom: sr.bottom, + Left: 0, + Right: info.Size.X - 1, + } + } else { + return SMALL_RECT{ + Top: info.Window.Top, + Bottom: info.Window.Bottom, + Left: 0, + Right: info.Size.X - 1, + } + } +} + +// setCursorPosition sets the cursor to the specified position, bounded to the screen size +func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error { + position.X = ensureInRange(position.X, window.Left, window.Right) + position.Y = ensureInRange(position.Y, window.Top, window.Bottom) + err := SetConsoleCursorPosition(h.fd, position) + if err != nil { + return err + } + h.logf("Cursor position set: (%d, %d)", position.X, position.Y) + return err +} + +func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error { + return h.moveCursor(vertical, param) +} + +func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error { + return h.moveCursor(horizontal, param) +} + +func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + switch moveMode { + case horizontal: + position.X += int16(param) + case vertical: + position.Y += int16(param) + } + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) moveCursorLine(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + position.X = 0 + position.Y += int16(param) + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + position.X = int16(param) - 1 + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go b/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go new file mode 100644 index 0000000000..244b5fa25e --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go @@ -0,0 +1,84 @@ +// +build windows + +package winterm + +import "github.com/Azure/go-ansiterm" + +func (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error { + // Ignore an invalid (negative area) request + if toCoord.Y < fromCoord.Y { + return nil + } + + var err error + + var coordStart = COORD{} + var coordEnd = COORD{} + + xCurrent, yCurrent := fromCoord.X, fromCoord.Y + xEnd, yEnd := toCoord.X, toCoord.Y + + // Clear any partial initial line + if xCurrent > 0 { + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yCurrent + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + xCurrent = 0 + yCurrent += 1 + } + + // Clear intervening rectangular section + if yCurrent < yEnd { + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yEnd-1 + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + xCurrent = 0 + yCurrent = yEnd + } + + // Clear remaining partial ending line + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yEnd + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) clearRect(attributes uint16, fromCoord COORD, toCoord COORD) error { + region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X} + width := toCoord.X - fromCoord.X + 1 + height := toCoord.Y - fromCoord.Y + 1 + size := uint32(width) * uint32(height) + + if size <= 0 { + return nil + } + + buffer := make([]CHAR_INFO, size) + + char := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes} + for i := 0; i < int(size); i++ { + buffer[i] = char + } + + err := WriteConsoleOutput(h.fd, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, ®ion) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go b/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go new file mode 100644 index 0000000000..2d27fa1d02 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go @@ -0,0 +1,118 @@ +// +build windows + +package winterm + +// effectiveSr gets the current effective scroll region in buffer coordinates +func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion { + top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom) + bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom) + if top >= bottom { + top = window.Top + bottom = window.Bottom + } + return scrollRegion{top: top, bottom: bottom} +} + +func (h *windowsAnsiEventHandler) scrollUp(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + sr := h.effectiveSr(info.Window) + return h.scroll(param, sr, info) +} + +func (h *windowsAnsiEventHandler) scrollDown(param int) error { + return h.scrollUp(-param) +} + +func (h *windowsAnsiEventHandler) deleteLines(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + start := info.CursorPosition.Y + sr := h.effectiveSr(info.Window) + // Lines cannot be inserted or deleted outside the scrolling region. + if start >= sr.top && start <= sr.bottom { + sr.top = start + return h.scroll(param, sr, info) + } else { + return nil + } +} + +func (h *windowsAnsiEventHandler) insertLines(param int) error { + return h.deleteLines(-param) +} + +// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates. +func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error { + h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom) + h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom) + + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: sr.top, + Bottom: sr.bottom, + Left: 0, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: 0, + Y: sr.top - int16(param), + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} + +func (h *windowsAnsiEventHandler) deleteCharacters(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + return h.scrollLine(param, info.CursorPosition, info) +} + +func (h *windowsAnsiEventHandler) insertCharacters(param int) error { + return h.deleteCharacters(-param) +} + +// scrollLine scrolls a line horizontally starting at the provided position by a number of columns. +func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error { + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: position.Y, + Bottom: position.Y, + Left: position.X, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: position.X - int16(columns), + Y: position.Y, + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go b/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go new file mode 100644 index 0000000000..afa7635d77 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go @@ -0,0 +1,9 @@ +// +build windows + +package winterm + +// AddInRange increments a value by the passed quantity while ensuring the values +// always remain within the supplied min / max range. +func addInRange(n int16, increment int16, min int16, max int16) int16 { + return ensureInRange(n+increment, min, max) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go new file mode 100644 index 0000000000..2d40fb75ad --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go @@ -0,0 +1,743 @@ +// +build windows + +package winterm + +import ( + "bytes" + "log" + "os" + "strconv" + + "github.com/Azure/go-ansiterm" +) + +type windowsAnsiEventHandler struct { + fd uintptr + file *os.File + infoReset *CONSOLE_SCREEN_BUFFER_INFO + sr scrollRegion + buffer bytes.Buffer + attributes uint16 + inverted bool + wrapNext bool + drewMarginByte bool + originMode bool + marginByte byte + curInfo *CONSOLE_SCREEN_BUFFER_INFO + curPos COORD + logf func(string, ...interface{}) +} + +type Option func(*windowsAnsiEventHandler) + +func WithLogf(f func(string, ...interface{})) Option { + return func(w *windowsAnsiEventHandler) { + w.logf = f + } +} + +func CreateWinEventHandler(fd uintptr, file *os.File, opts ...Option) ansiterm.AnsiEventHandler { + infoReset, err := GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil + } + + h := &windowsAnsiEventHandler{ + fd: fd, + file: file, + infoReset: infoReset, + attributes: infoReset.Attributes, + } + for _, o := range opts { + o(h) + } + + if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { + logFile, _ := os.Create("winEventHandler.log") + logger := log.New(logFile, "", log.LstdFlags) + if h.logf != nil { + l := h.logf + h.logf = func(s string, v ...interface{}) { + l(s, v...) + logger.Printf(s, v...) + } + } else { + h.logf = logger.Printf + } + } + + if h.logf == nil { + h.logf = func(string, ...interface{}) {} + } + + return h +} + +type scrollRegion struct { + top int16 + bottom int16 +} + +// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the +// current cursor position and scroll region settings, in which case it returns +// true. If no special handling is necessary, then it does nothing and returns +// false. +// +// In the false case, the caller should ensure that a carriage return +// and line feed are inserted or that the text is otherwise wrapped. +func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) { + if h.wrapNext { + if err := h.Flush(); err != nil { + return false, err + } + h.clearWrap() + } + pos, info, err := h.getCurrentInfo() + if err != nil { + return false, err + } + sr := h.effectiveSr(info.Window) + if pos.Y == sr.bottom { + // Scrolling is necessary. Let Windows automatically scroll if the scrolling region + // is the full window. + if sr.top == info.Window.Top && sr.bottom == info.Window.Bottom { + if includeCR { + pos.X = 0 + h.updatePos(pos) + } + return false, nil + } + + // A custom scroll region is active. Scroll the window manually to simulate + // the LF. + if err := h.Flush(); err != nil { + return false, err + } + h.logf("Simulating LF inside scroll region") + if err := h.scrollUp(1); err != nil { + return false, err + } + if includeCR { + pos.X = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return false, err + } + } + return true, nil + + } else if pos.Y < info.Window.Bottom { + // Let Windows handle the LF. + pos.Y++ + if includeCR { + pos.X = 0 + } + h.updatePos(pos) + return false, nil + } else { + // The cursor is at the bottom of the screen but outside the scroll + // region. Skip the LF. + h.logf("Simulating LF outside scroll region") + if includeCR { + if err := h.Flush(); err != nil { + return false, err + } + pos.X = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return false, err + } + } + return true, nil + } +} + +// executeLF executes a LF without a CR. +func (h *windowsAnsiEventHandler) executeLF() error { + handled, err := h.simulateLF(false) + if err != nil { + return err + } + if !handled { + // Windows LF will reset the cursor column position. Write the LF + // and restore the cursor position. + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED) + if pos.X != 0 { + if err := h.Flush(); err != nil { + return err + } + h.logf("Resetting cursor position for LF without CR") + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + } + } + return nil +} + +func (h *windowsAnsiEventHandler) Print(b byte) error { + if h.wrapNext { + h.buffer.WriteByte(h.marginByte) + h.clearWrap() + if _, err := h.simulateLF(true); err != nil { + return err + } + } + pos, info, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X == info.Size.X-1 { + h.wrapNext = true + h.marginByte = b + } else { + pos.X++ + h.updatePos(pos) + h.buffer.WriteByte(b) + } + return nil +} + +func (h *windowsAnsiEventHandler) Execute(b byte) error { + switch b { + case ansiterm.ANSI_TAB: + h.logf("Execute(TAB)") + // Move to the next tab stop, but preserve auto-wrap if already set. + if !h.wrapNext { + pos, info, err := h.getCurrentInfo() + if err != nil { + return err + } + pos.X = (pos.X + 8) - pos.X%8 + if pos.X >= info.Size.X { + pos.X = info.Size.X - 1 + } + if err := h.Flush(); err != nil { + return err + } + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + } + return nil + + case ansiterm.ANSI_BEL: + h.buffer.WriteByte(ansiterm.ANSI_BEL) + return nil + + case ansiterm.ANSI_BACKSPACE: + if h.wrapNext { + if err := h.Flush(); err != nil { + return err + } + h.clearWrap() + } + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X > 0 { + pos.X-- + h.updatePos(pos) + h.buffer.WriteByte(ansiterm.ANSI_BACKSPACE) + } + return nil + + case ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED: + // Treat as true LF. + return h.executeLF() + + case ansiterm.ANSI_LINE_FEED: + // Simulate a CR and LF for now since there is no way in go-ansiterm + // to tell if the LF should include CR (and more things break when it's + // missing than when it's incorrectly added). + handled, err := h.simulateLF(true) + if handled || err != nil { + return err + } + return h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED) + + case ansiterm.ANSI_CARRIAGE_RETURN: + if h.wrapNext { + if err := h.Flush(); err != nil { + return err + } + h.clearWrap() + } + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X != 0 { + pos.X = 0 + h.updatePos(pos) + h.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN) + } + return nil + + default: + return nil + } +} + +func (h *windowsAnsiEventHandler) CUU(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUU: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorVertical(-param) +} + +func (h *windowsAnsiEventHandler) CUD(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUD: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorVertical(param) +} + +func (h *windowsAnsiEventHandler) CUF(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUF: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorHorizontal(param) +} + +func (h *windowsAnsiEventHandler) CUB(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUB: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorHorizontal(-param) +} + +func (h *windowsAnsiEventHandler) CNL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CNL: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorLine(param) +} + +func (h *windowsAnsiEventHandler) CPL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CPL: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorLine(-param) +} + +func (h *windowsAnsiEventHandler) CHA(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CHA: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorColumn(param) +} + +func (h *windowsAnsiEventHandler) VPA(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("VPA: [[%d]]", param) + h.clearWrap() + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + window := h.getCursorWindow(info) + position := info.CursorPosition + position.Y = window.Top + int16(param) - 1 + return h.setCursorPosition(position, window) +} + +func (h *windowsAnsiEventHandler) CUP(row int, col int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUP: [[%d %d]]", row, col) + h.clearWrap() + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + window := h.getCursorWindow(info) + position := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1} + return h.setCursorPosition(position, window) +} + +func (h *windowsAnsiEventHandler) HVP(row int, col int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("HVP: [[%d %d]]", row, col) + h.clearWrap() + return h.CUP(row, col) +} + +func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECTCEM: [%v]", []string{strconv.FormatBool(visible)}) + h.clearWrap() + return nil +} + +func (h *windowsAnsiEventHandler) DECOM(enable bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECOM: [%v]", []string{strconv.FormatBool(enable)}) + h.clearWrap() + h.originMode = enable + return h.CUP(1, 1) +} + +func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECCOLM: [%v]", []string{strconv.FormatBool(use132)}) + h.clearWrap() + if err := h.ED(2); err != nil { + return err + } + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + targetWidth := int16(80) + if use132 { + targetWidth = 132 + } + if info.Size.X < targetWidth { + if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { + h.logf("set buffer failed: %v", err) + return err + } + } + window := info.Window + window.Left = 0 + window.Right = targetWidth - 1 + if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { + h.logf("set window failed: %v", err) + return err + } + if info.Size.X > targetWidth { + if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { + h.logf("set buffer failed: %v", err) + return err + } + } + return SetConsoleCursorPosition(h.fd, COORD{0, 0}) +} + +func (h *windowsAnsiEventHandler) ED(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("ED: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + + // [J -- Erases from the cursor to the end of the screen, including the cursor position. + // [1J -- Erases from the beginning of the screen to the cursor, including the cursor position. + // [2J -- Erases the complete display. The cursor does not move. + // Notes: + // -- Clearing the entire buffer, versus just the Window, works best for Windows Consoles + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + var start COORD + var end COORD + + switch param { + case 0: + start = info.CursorPosition + end = COORD{info.Size.X - 1, info.Size.Y - 1} + + case 1: + start = COORD{0, 0} + end = info.CursorPosition + + case 2: + start = COORD{0, 0} + end = COORD{info.Size.X - 1, info.Size.Y - 1} + } + + err = h.clearRange(h.attributes, start, end) + if err != nil { + return err + } + + // If the whole buffer was cleared, move the window to the top while preserving + // the window-relative cursor position. + if param == 2 { + pos := info.CursorPosition + window := info.Window + pos.Y -= window.Top + window.Bottom -= window.Top + window.Top = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { + return err + } + } + + return nil +} + +func (h *windowsAnsiEventHandler) EL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("EL: [%v]", strconv.Itoa(param)) + h.clearWrap() + + // [K -- Erases from the cursor to the end of the line, including the cursor position. + // [1K -- Erases from the beginning of the line to the cursor, including the cursor position. + // [2K -- Erases the complete line. + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + var start COORD + var end COORD + + switch param { + case 0: + start = info.CursorPosition + end = COORD{info.Size.X, info.CursorPosition.Y} + + case 1: + start = COORD{0, info.CursorPosition.Y} + end = info.CursorPosition + + case 2: + start = COORD{0, info.CursorPosition.Y} + end = COORD{info.Size.X, info.CursorPosition.Y} + } + + err = h.clearRange(h.attributes, start, end) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) IL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("IL: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertLines(param) +} + +func (h *windowsAnsiEventHandler) DL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DL: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteLines(param) +} + +func (h *windowsAnsiEventHandler) ICH(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("ICH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertCharacters(param) +} + +func (h *windowsAnsiEventHandler) DCH(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DCH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteCharacters(param) +} + +func (h *windowsAnsiEventHandler) SGR(params []int) error { + if err := h.Flush(); err != nil { + return err + } + strings := []string{} + for _, v := range params { + strings = append(strings, strconv.Itoa(v)) + } + + h.logf("SGR: [%v]", strings) + + if len(params) <= 0 { + h.attributes = h.infoReset.Attributes + h.inverted = false + } else { + for _, attr := range params { + + if attr == ansiterm.ANSI_SGR_RESET { + h.attributes = h.infoReset.Attributes + h.inverted = false + continue + } + + h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr)) + } + } + + attributes := h.attributes + if h.inverted { + attributes = invertAttributes(attributes) + } + err := SetConsoleTextAttribute(h.fd, attributes) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) SU(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("SU: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.scrollUp(param) +} + +func (h *windowsAnsiEventHandler) SD(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("SD: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.scrollDown(param) +} + +func (h *windowsAnsiEventHandler) DA(params []string) error { + h.logf("DA: [%v]", params) + // DA cannot be implemented because it must send data on the VT100 input stream, + // which is not available to go-ansiterm. + return nil +} + +func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECSTBM: [%d, %d]", top, bottom) + + // Windows is 0 indexed, Linux is 1 indexed + h.sr.top = int16(top - 1) + h.sr.bottom = int16(bottom - 1) + + // This command also moves the cursor to the origin. + h.clearWrap() + return h.CUP(1, 1) +} + +func (h *windowsAnsiEventHandler) RI() error { + if err := h.Flush(); err != nil { + return err + } + h.logf("RI: []") + h.clearWrap() + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + sr := h.effectiveSr(info.Window) + if info.CursorPosition.Y == sr.top { + return h.scrollDown(1) + } + + return h.moveCursorVertical(-1) +} + +func (h *windowsAnsiEventHandler) IND() error { + h.logf("IND: []") + return h.executeLF() +} + +func (h *windowsAnsiEventHandler) Flush() error { + h.curInfo = nil + if h.buffer.Len() > 0 { + h.logf("Flush: [%s]", h.buffer.Bytes()) + if _, err := h.buffer.WriteTo(h.file); err != nil { + return err + } + } + + if h.wrapNext && !h.drewMarginByte { + h.logf("Flush: drawing margin byte '%c'", h.marginByte) + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + charInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}} + size := COORD{1, 1} + position := COORD{0, 0} + region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y} + if err := WriteConsoleOutput(h.fd, charInfo, size, position, ®ion); err != nil { + return err + } + h.drewMarginByte = true + } + return nil +} + +// cacheConsoleInfo ensures that the current console screen information has been queried +// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos. +func (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) { + if h.curInfo == nil { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return COORD{}, nil, err + } + h.curInfo = info + h.curPos = info.CursorPosition + } + return h.curPos, h.curInfo, nil +} + +func (h *windowsAnsiEventHandler) updatePos(pos COORD) { + if h.curInfo == nil { + panic("failed to call getCurrentInfo before calling updatePos") + } + h.curPos = pos +} + +// clearWrap clears the state where the cursor is in the margin +// waiting for the next character before wrapping the line. This must +// be done before most operations that act on the cursor. +func (h *windowsAnsiEventHandler) clearWrap() { + h.wrapNext = false + h.drewMarginByte = false +} diff --git a/vendor/github.com/Azure/go-autorest/LICENSE b/vendor/github.com/Azure/go-autorest/LICENSE new file mode 100644 index 0000000000..b9d6a27ea9 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2015 Microsoft Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go new file mode 100644 index 0000000000..9804f401ef --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/autorest.go @@ -0,0 +1,114 @@ +/* +Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines +and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/) +generated Go code. + +The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, +and Responding. A typical pattern is: + + req, err := Prepare(&http.Request{}, + token.WithAuthorization()) + + resp, err := Send(req, + WithLogging(logger), + DoErrorIfStatusCode(http.StatusInternalServerError), + DoCloseIfError(), + DoRetryForAttempts(5, time.Second)) + + err = Respond(resp, + ByClosing()) + +Each phase relies on decorators to modify and / or manage processing. Decorators may first modify +and then pass the data along, pass the data first and then modify the result, or wrap themselves +around passing the data (such as a logger might do). Decorators run in the order provided. For +example, the following: + + req, err := Prepare(&http.Request{}, + WithBaseURL("https://microsoft.com/"), + WithPath("a"), + WithPath("b"), + WithPath("c")) + +will set the URL to: + + https://microsoft.com/a/b/c + +Preparers and Responders may be shared and re-used (assuming the underlying decorators support +sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders +shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, +all bound together by means of input / output channels. + +Decorators hold their passed state within a closure (such as the path components in the example +above). Be careful to share Preparers and Responders only in a context where such held state +applies. For example, it may not make sense to share a Preparer that applies a query string from a +fixed set of values. Similarly, sharing a Responder that reads the response body into a passed +struct (e.g., ByUnmarshallingJson) is likely incorrect. + +Lastly, the Swagger specification (https://swagger.io) that drives AutoRest +(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The +github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure +correct parsing and formatting. + +Errors raised by autorest objects and methods will conform to the autorest.Error interface. + +See the included examples for more detail. For details on the suggested use of this package by +generated clients, see the Client described below. +*/ +package autorest + +import ( + "net/http" + "time" +) + +const ( + // HeaderLocation specifies the HTTP Location header. + HeaderLocation = "Location" + + // HeaderRetryAfter specifies the HTTP Retry-After header. + HeaderRetryAfter = "Retry-After" +) + +// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set +// and false otherwise. +func ResponseHasStatusCode(resp *http.Response, codes ...int) bool { + return containsInt(codes, resp.StatusCode) +} + +// GetLocation retrieves the URL from the Location header of the passed response. +func GetLocation(resp *http.Response) string { + return resp.Header.Get(HeaderLocation) +} + +// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If +// the header is absent or is malformed, it will return the supplied default delay time.Duration. +func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration { + retry := resp.Header.Get(HeaderRetryAfter) + if retry == "" { + return defaultDelay + } + + d, err := time.ParseDuration(retry + "s") + if err != nil { + return defaultDelay + } + + return d +} + +// NewPollingRequest allocates and returns a new http.Request to poll for the passed response. +func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) { + location := GetLocation(resp) + if location == "" { + return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling") + } + + req, err := Prepare(&http.Request{Cancel: cancel}, + AsGet(), + WithBaseURL(location)) + if err != nil { + return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location) + } + + return req, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go new file mode 100644 index 0000000000..280d32a61d --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go @@ -0,0 +1,307 @@ +package azure + +import ( + "bytes" + "fmt" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "io/ioutil" + "net/http" + "strings" + "time" +) + +const ( + headerAsyncOperation = "Azure-AsyncOperation" +) + +const ( + methodDelete = "DELETE" + methodPatch = "PATCH" + methodPost = "POST" + methodPut = "PUT" + methodGet = "GET" + + operationInProgress string = "InProgress" + operationCanceled string = "Canceled" + operationFailed string = "Failed" + operationSucceeded string = "Succeeded" +) + +// DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure +// long-running operation. It will delay between requests for the duration specified in the +// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by +// closing the optional channel on the http.Request. +func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator { + return func(s autorest.Sender) autorest.Sender { + return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + resp, err = s.Do(r) + if err != nil { + return resp, err + } + pollingCodes := []int{http.StatusAccepted, http.StatusCreated, http.StatusOK} + if !autorest.ResponseHasStatusCode(resp, pollingCodes...) { + return resp, nil + } + + ps := pollingState{} + for err == nil { + err = updatePollingState(resp, &ps) + if err != nil { + break + } + if ps.hasTerminated() { + if !ps.hasSucceeded() { + err = ps + } + break + } + + r, err = newPollingRequest(resp, ps) + if err != nil { + return resp, err + } + + delay = autorest.GetRetryAfter(resp, delay) + resp, err = autorest.SendWithSender(s, r, + autorest.AfterDelay(delay)) + } + + return resp, err + }) + } +} + +func getAsyncOperation(resp *http.Response) string { + return resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) +} + +func hasSucceeded(state string) bool { + return state == operationSucceeded +} + +func hasTerminated(state string) bool { + switch state { + case operationCanceled, operationFailed, operationSucceeded: + return true + default: + return false + } +} + +func hasFailed(state string) bool { + return state == operationFailed +} + +type provisioningTracker interface { + state() string + hasSucceeded() bool + hasTerminated() bool +} + +type operationResource struct { + // Note: + // The specification states services should return the "id" field. However some return it as + // "operationId". + ID string `json:"id"` + OperationID string `json:"operationId"` + Name string `json:"name"` + Status string `json:"status"` + Properties map[string]interface{} `json:"properties"` + OperationError ServiceError `json:"error"` + StartTime date.Time `json:"startTime"` + EndTime date.Time `json:"endTime"` + PercentComplete float64 `json:"percentComplete"` +} + +func (or operationResource) state() string { + return or.Status +} + +func (or operationResource) hasSucceeded() bool { + return hasSucceeded(or.state()) +} + +func (or operationResource) hasTerminated() bool { + return hasTerminated(or.state()) +} + +type provisioningProperties struct { + ProvisioningState string `json:"provisioningState"` +} + +type provisioningStatus struct { + Properties provisioningProperties `json:"properties,omitempty"` + ProvisioningError ServiceError `json:"error,omitempty"` +} + +func (ps provisioningStatus) state() string { + return ps.Properties.ProvisioningState +} + +func (ps provisioningStatus) hasSucceeded() bool { + return hasSucceeded(ps.state()) +} + +func (ps provisioningStatus) hasTerminated() bool { + return hasTerminated(ps.state()) +} + +func (ps provisioningStatus) hasProvisioningError() bool { + return ps.ProvisioningError != ServiceError{} +} + +type pollingResponseFormat string + +const ( + usesOperationResponse pollingResponseFormat = "OperationResponse" + usesProvisioningStatus pollingResponseFormat = "ProvisioningStatus" + formatIsUnknown pollingResponseFormat = "" +) + +type pollingState struct { + responseFormat pollingResponseFormat + uri string + state string + code string + message string +} + +func (ps pollingState) hasSucceeded() bool { + return hasSucceeded(ps.state) +} + +func (ps pollingState) hasTerminated() bool { + return hasTerminated(ps.state) +} + +func (ps pollingState) hasFailed() bool { + return hasFailed(ps.state) +} + +func (ps pollingState) Error() string { + return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.state, ps.code, ps.message) +} + +// updatePollingState maps the operation status -- retrieved from either a provisioningState +// field, the status field of an OperationResource, or inferred from the HTTP status code -- +// into a well-known states. Since the process begins from the initial request, the state +// always comes from either a the provisioningState returned or is inferred from the HTTP +// status code. Subsequent requests will read an Azure OperationResource object if the +// service initially returned the Azure-AsyncOperation header. The responseFormat field notes +// the expected response format. +func updatePollingState(resp *http.Response, ps *pollingState) error { + // Determine the response shape + // -- The first response will always be a provisioningStatus response; only the polling requests, + // depending on the header returned, may be something otherwise. + var pt provisioningTracker + if ps.responseFormat == usesOperationResponse { + pt = &operationResource{} + } else { + pt = &provisioningStatus{} + } + + // If this is the first request (that is, the polling response shape is unknown), determine how + // to poll and what to expect + if ps.responseFormat == formatIsUnknown { + req := resp.Request + if req == nil { + return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Original HTTP request is missing") + } + + // Prefer the Azure-AsyncOperation header + ps.uri = getAsyncOperation(resp) + if ps.uri != "" { + ps.responseFormat = usesOperationResponse + } else { + ps.responseFormat = usesProvisioningStatus + } + + // Else, use the Location header + if ps.uri == "" { + ps.uri = autorest.GetLocation(resp) + } + + // Lastly, requests against an existing resource, use the last request URI + if ps.uri == "" { + m := strings.ToUpper(req.Method) + if m == methodPatch || m == methodPut || m == methodGet { + ps.uri = req.URL.String() + } + } + } + + // Read and interpret the response (saving the Body in case no polling is necessary) + b := &bytes.Buffer{} + err := autorest.Respond(resp, + autorest.ByCopying(b), + autorest.ByUnmarshallingJSON(pt), + autorest.ByClosing()) + resp.Body = ioutil.NopCloser(b) + if err != nil { + return err + } + + // Interpret the results + // -- Terminal states apply regardless + // -- Unknown states are per-service inprogress states + // -- Otherwise, infer state from HTTP status code + if pt.hasTerminated() { + ps.state = pt.state() + } else if pt.state() != "" { + ps.state = operationInProgress + } else { + switch resp.StatusCode { + case http.StatusAccepted: + ps.state = operationInProgress + + case http.StatusNoContent, http.StatusCreated, http.StatusOK: + ps.state = operationSucceeded + + default: + ps.state = operationFailed + } + } + + if ps.state == operationInProgress && ps.uri == "" { + return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Unable to obtain polling URI for %s %s", resp.Request.Method, resp.Request.URL) + } + + // For failed operation, check for error code and message in + // -- Operation resource + // -- Response + // -- Otherwise, Unknown + if ps.hasFailed() { + if ps.responseFormat == usesOperationResponse { + or := pt.(*operationResource) + ps.code = or.OperationError.Code + ps.message = or.OperationError.Message + } else { + p := pt.(*provisioningStatus) + if p.hasProvisioningError() { + ps.code = p.ProvisioningError.Code + ps.message = p.ProvisioningError.Message + } else { + ps.code = "Unknown" + ps.message = "None" + } + } + } + return nil +} + +func newPollingRequest(resp *http.Response, ps pollingState) (*http.Request, error) { + req := resp.Request + if req == nil { + return nil, autorest.NewError("azure", "newPollingRequest", "Azure Polling Error - Original HTTP request is missing") + } + + reqPoll, err := autorest.Prepare(&http.Request{Cancel: req.Cancel}, + autorest.AsGet(), + autorest.WithBaseURL(ps.uri)) + if err != nil { + return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.uri) + } + + return reqPoll, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go new file mode 100644 index 0000000000..3f4d13421a --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go @@ -0,0 +1,180 @@ +/* +Package azure provides Azure-specific implementations used with AutoRest. + +See the included examples for more detail. +*/ +package azure + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + + "github.com/Azure/go-autorest/autorest" +) + +const ( + // HeaderClientID is the Azure extension header to set a user-specified request ID. + HeaderClientID = "x-ms-client-request-id" + + // HeaderReturnClientID is the Azure extension header to set if the user-specified request ID + // should be included in the response. + HeaderReturnClientID = "x-ms-return-client-request-id" + + // HeaderRequestID is the Azure extension header of the service generated request ID returned + // in the response. + HeaderRequestID = "x-ms-request-id" +) + +// ServiceError encapsulates the error response from an Azure service. +type ServiceError struct { + Code string `json:"code"` + Message string `json:"message"` + Details *[]interface{} `json:"details"` +} + +func (se ServiceError) Error() string { + if se.Details != nil { + d, err := json.Marshal(*(se.Details)) + if err != nil { + return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, *se.Details) + } + return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, string(d)) + } + return fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) +} + +// RequestError describes an error response returned by Azure service. +type RequestError struct { + autorest.DetailedError + + // The error returned by the Azure service. + ServiceError *ServiceError `json:"error"` + + // The request id (from the x-ms-request-id-header) of the request. + RequestID string +} + +// Error returns a human-friendly error message from service error. +func (e RequestError) Error() string { + return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v", + e.StatusCode, e.ServiceError) +} + +// IsAzureError returns true if the passed error is an Azure Service error; false otherwise. +func IsAzureError(e error) bool { + _, ok := e.(*RequestError) + return ok +} + +// NewErrorWithError creates a new Error conforming object from the +// passed packageType, method, statusCode of the given resp (UndefinedStatusCode +// if resp is nil), message, and original error. message is treated as a format +// string to which the optional args apply. +func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError { + if v, ok := original.(*RequestError); ok { + return *v + } + + statusCode := autorest.UndefinedStatusCode + if resp != nil { + statusCode = resp.StatusCode + } + return RequestError{ + DetailedError: autorest.DetailedError{ + Original: original, + PackageType: packageType, + Method: method, + StatusCode: statusCode, + Message: fmt.Sprintf(message, args...), + }, + } +} + +// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of +// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g., +// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id +// header to true such that UUID accompanies the http.Response. +func WithReturningClientID(uuid string) autorest.PrepareDecorator { + preparer := autorest.CreatePreparer( + WithClientID(uuid), + WithReturnClientID(true)) + + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err != nil { + return r, err + } + return preparer.Prepare(r) + }) + } +} + +// WithClientID returns a PrepareDecorator that adds an HTTP extension header of +// x-ms-client-request-id whose value is passed, undecorated UUID (e.g., +// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). +func WithClientID(uuid string) autorest.PrepareDecorator { + return autorest.WithHeader(HeaderClientID, uuid) +} + +// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of +// x-ms-return-client-request-id whose boolean value indicates if the value of the +// x-ms-client-request-id header should be included in the http.Response. +func WithReturnClientID(b bool) autorest.PrepareDecorator { + return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b)) +} + +// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the +// http.Request sent to the service (and returned in the http.Response) +func ExtractClientID(resp *http.Response) string { + return autorest.ExtractHeaderValue(HeaderClientID, resp) +} + +// ExtractRequestID extracts the Azure server generated request identifier from the +// x-ms-request-id header. +func ExtractRequestID(resp *http.Response) string { + return autorest.ExtractHeaderValue(HeaderRequestID, resp) +} + +// WithErrorUnlessStatusCode returns a RespondDecorator that emits an +// azure.RequestError by reading the response body unless the response HTTP status code +// is among the set passed. +// +// If there is a chance service may return responses other than the Azure error +// format and the response cannot be parsed into an error, a decoding error will +// be returned containing the response body. In any case, the Responder will +// return an error if the status code is not satisfied. +// +// If this Responder returns an error, the response body will be replaced with +// an in-memory reader, which needs no further closing. +func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { + return func(r autorest.Responder) autorest.Responder { + return autorest.ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) { + var e RequestError + defer resp.Body.Close() + + // Copy and replace the Body in case it does not contain an error object. + // This will leave the Body available to the caller. + b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &e) + resp.Body = ioutil.NopCloser(&b) + if decodeErr != nil { + return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr) + } else if e.ServiceError == nil { + e.ServiceError = &ServiceError{Code: "Unknown", Message: "Unknown service error"} + } + + e.RequestID = ExtractRequestID(resp) + if e.StatusCode == nil { + e.StatusCode = resp.StatusCode + } + err = &e + } + return err + }) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/config.go b/vendor/github.com/Azure/go-autorest/autorest/azure/config.go new file mode 100644 index 0000000000..bea30b0d67 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/config.go @@ -0,0 +1,13 @@ +package azure + +import ( + "net/url" +) + +// OAuthConfig represents the endpoints needed +// in OAuth operations +type OAuthConfig struct { + AuthorizeEndpoint url.URL + TokenEndpoint url.URL + DeviceCodeEndpoint url.URL +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/azure/devicetoken.go new file mode 100644 index 0000000000..e1d5498a80 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/devicetoken.go @@ -0,0 +1,193 @@ +package azure + +/* + This file is largely based on rjw57/oauth2device's code, with the follow differences: + * scope -> resource, and only allow a single one + * receive "Message" in the DeviceCode struct and show it to users as the prompt + * azure-xplat-cli has the following behavior that this emulates: + - does not send client_secret during the token exchange + - sends resource again in the token exchange request +*/ + +import ( + "fmt" + "net/http" + "net/url" + "time" + + "github.com/Azure/go-autorest/autorest" +) + +const ( + logPrefix = "autorest/azure/devicetoken:" +) + +var ( + // ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow + ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix) + + // ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow + ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix) + + // ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow + ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix) + + // ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow + ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix) + + // ErrDeviceSlowDown represents the service telling us we're polling too often during device flow + ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix) + + errCodeSendingFails = "Error occurred while sending request for Device Authorization Code" + errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint" + errTokenSendingFails = "Error occurred while sending request with device code for a token" + errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)" +) + +// DeviceCode is the object returned by the device auth endpoint +// It contains information to instruct the user to complete the auth flow +type DeviceCode struct { + DeviceCode *string `json:"device_code,omitempty"` + UserCode *string `json:"user_code,omitempty"` + VerificationURL *string `json:"verification_url,omitempty"` + ExpiresIn *int64 `json:"expires_in,string,omitempty"` + Interval *int64 `json:"interval,string,omitempty"` + + Message *string `json:"message"` // Azure specific + Resource string // store the following, stored when initiating, used when exchanging + OAuthConfig OAuthConfig + ClientID string +} + +// TokenError is the object returned by the token exchange endpoint +// when something is amiss +type TokenError struct { + Error *string `json:"error,omitempty"` + ErrorCodes []int `json:"error_codes,omitempty"` + ErrorDescription *string `json:"error_description,omitempty"` + Timestamp *string `json:"timestamp,omitempty"` + TraceID *string `json:"trace_id,omitempty"` +} + +// DeviceToken is the object return by the token exchange endpoint +// It can either look like a Token or an ErrorToken, so put both here +// and check for presence of "Error" to know if we are in error state +type deviceToken struct { + Token + TokenError +} + +// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode +// that can be used with CheckForUserCompletion or WaitForUserCompletion. +func InitiateDeviceAuth(client *autorest.Client, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { + req, _ := autorest.Prepare( + &http.Request{}, + autorest.AsPost(), + autorest.AsFormURLEncoded(), + autorest.WithBaseURL(oauthConfig.DeviceCodeEndpoint.String()), + autorest.WithFormData(url.Values{ + "client_id": []string{clientID}, + "resource": []string{resource}, + }), + ) + + resp, err := autorest.SendWithSender(client, req) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err) + } + + var code DeviceCode + err = autorest.Respond( + resp, + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&code), + autorest.ByClosing()) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err) + } + + code.ClientID = clientID + code.Resource = resource + code.OAuthConfig = oauthConfig + + return &code, nil +} + +// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint +// to see if the device flow has: been completed, timed out, or otherwise failed +func CheckForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token, error) { + req, _ := autorest.Prepare( + &http.Request{}, + autorest.AsPost(), + autorest.AsFormURLEncoded(), + autorest.WithBaseURL(code.OAuthConfig.TokenEndpoint.String()), + autorest.WithFormData(url.Values{ + "client_id": []string{code.ClientID}, + "code": []string{*code.DeviceCode}, + "grant_type": []string{OAuthGrantTypeDeviceCode}, + "resource": []string{code.Resource}, + }), + ) + + resp, err := autorest.SendWithSender(client, req) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err) + } + + var token deviceToken + err = autorest.Respond( + resp, + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusBadRequest), + autorest.ByUnmarshallingJSON(&token), + autorest.ByClosing()) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err) + } + + if token.Error == nil { + return &token.Token, nil + } + + switch *token.Error { + case "authorization_pending": + return nil, ErrDeviceAuthorizationPending + case "slow_down": + return nil, ErrDeviceSlowDown + case "access_denied": + return nil, ErrDeviceAccessDenied + case "code_expired": + return nil, ErrDeviceCodeExpired + default: + return nil, ErrDeviceGeneric + } +} + +// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs. +// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. +func WaitForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token, error) { + intervalDuration := time.Duration(*code.Interval) * time.Second + waitDuration := intervalDuration + + for { + token, err := CheckForUserCompletion(client, code) + + if err == nil { + return token, nil + } + + switch err { + case ErrDeviceSlowDown: + waitDuration += waitDuration + case ErrDeviceAuthorizationPending: + // noop + default: // everything else is "fatal" to us + return nil, err + } + + if waitDuration > (intervalDuration * 3) { + return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix) + } + + time.Sleep(waitDuration) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go new file mode 100644 index 0000000000..ebf754eab4 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go @@ -0,0 +1,147 @@ +package azure + +import ( + "fmt" + "net/url" + "strings" +) + +const ( + activeDirectoryAPIVersion = "1.0" +) + +var environments = map[string]Environment{ + "AZURECHINACLOUD": ChinaCloud, + "AZUREGERMANCLOUD": GermanCloud, + "AZUREPUBLICCLOUD": PublicCloud, + "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, +} + +// Environment represents a set of endpoints for each of Azure's Clouds. +type Environment struct { + Name string `json:"name"` + ManagementPortalURL string `json:"managementPortalURL"` + PublishSettingsURL string `json:"publishSettingsURL"` + ServiceManagementEndpoint string `json:"serviceManagementEndpoint"` + ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` + ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` + GalleryEndpoint string `json:"galleryEndpoint"` + KeyVaultEndpoint string `json:"keyVaultEndpoint"` + GraphEndpoint string `json:"graphEndpoint"` + StorageEndpointSuffix string `json:"storageEndpointSuffix"` + SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` + TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` + KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"` + ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"` +} + +var ( + // PublicCloud is the default public Azure cloud environment + PublicCloud = Environment{ + Name: "AzurePublicCloud", + ManagementPortalURL: "https://manage.windowsazure.com/", + PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.windows.net/", + ResourceManagerEndpoint: "https://management.azure.com/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", + GalleryEndpoint: "https://gallery.azure.com/", + KeyVaultEndpoint: "https://vault.azure.net/", + GraphEndpoint: "https://graph.windows.net/", + StorageEndpointSuffix: "core.windows.net", + SQLDatabaseDNSSuffix: "database.windows.net", + TrafficManagerDNSSuffix: "trafficmanager.net", + KeyVaultDNSSuffix: "vault.azure.net", + ServiceBusEndpointSuffix: "servicebus.azure.com", + } + + // USGovernmentCloud is the cloud environment for the US Government + USGovernmentCloud = Environment{ + Name: "AzureUSGovernmentCloud", + ManagementPortalURL: "https://manage.windowsazure.us/", + PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", + ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", + GalleryEndpoint: "https://gallery.usgovcloudapi.net/", + KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", + GraphEndpoint: "https://graph.usgovcloudapi.net/", + StorageEndpointSuffix: "core.usgovcloudapi.net", + SQLDatabaseDNSSuffix: "database.usgovcloudapi.net", + TrafficManagerDNSSuffix: "usgovtrafficmanager.net", + KeyVaultDNSSuffix: "vault.usgovcloudapi.net", + ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net", + } + + // ChinaCloud is the cloud environment operated in China + ChinaCloud = Environment{ + Name: "AzureChinaCloud", + ManagementPortalURL: "https://manage.chinacloudapi.com/", + PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/", + ResourceManagerEndpoint: "https://management.chinacloudapi.cn/", + ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/?api-version=1.0", + GalleryEndpoint: "https://gallery.chinacloudapi.cn/", + KeyVaultEndpoint: "https://vault.azure.cn/", + GraphEndpoint: "https://graph.chinacloudapi.cn/", + StorageEndpointSuffix: "core.chinacloudapi.cn", + SQLDatabaseDNSSuffix: "database.chinacloudapi.cn", + TrafficManagerDNSSuffix: "trafficmanager.cn", + KeyVaultDNSSuffix: "vault.azure.cn", + ServiceBusEndpointSuffix: "servicebus.chinacloudapi.net", + } + + // GermanCloud is the cloud environment operated in Germany + GermanCloud = Environment{ + Name: "AzureGermanCloud", + ManagementPortalURL: "http://portal.microsoftazure.de/", + PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.cloudapi.de/", + ResourceManagerEndpoint: "https://management.microsoftazure.de/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.de/", + GalleryEndpoint: "https://gallery.cloudapi.de/", + KeyVaultEndpoint: "https://vault.microsoftazure.de/", + GraphEndpoint: "https://graph.cloudapi.de/", + StorageEndpointSuffix: "core.cloudapi.de", + SQLDatabaseDNSSuffix: "database.cloudapi.de", + TrafficManagerDNSSuffix: "azuretrafficmanager.de", + KeyVaultDNSSuffix: "vault.microsoftazure.de", + ServiceBusEndpointSuffix: "servicebus.cloudapi.de", + } +) + +// EnvironmentFromName returns an Environment based on the common name specified +func EnvironmentFromName(name string) (Environment, error) { + name = strings.ToUpper(name) + env, ok := environments[name] + if !ok { + return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) + } + return env, nil +} + +// OAuthConfigForTenant returns an OAuthConfig with tenant specific urls +func (env Environment) OAuthConfigForTenant(tenantID string) (*OAuthConfig, error) { + template := "%s/oauth2/%s?api-version=%s" + u, err := url.Parse(env.ActiveDirectoryEndpoint) + if err != nil { + return nil, err + } + authorizeURL, err := u.Parse(fmt.Sprintf(template, tenantID, "authorize", activeDirectoryAPIVersion)) + if err != nil { + return nil, err + } + tokenURL, err := u.Parse(fmt.Sprintf(template, tenantID, "token", activeDirectoryAPIVersion)) + if err != nil { + return nil, err + } + deviceCodeURL, err := u.Parse(fmt.Sprintf(template, tenantID, "devicecode", activeDirectoryAPIVersion)) + if err != nil { + return nil, err + } + + return &OAuthConfig{ + AuthorizeEndpoint: *authorizeURL, + TokenEndpoint: *tokenURL, + DeviceCodeEndpoint: *deviceCodeURL, + }, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/persist.go b/vendor/github.com/Azure/go-autorest/autorest/azure/persist.go new file mode 100644 index 0000000000..d5cf62ddc7 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/persist.go @@ -0,0 +1,59 @@ +package azure + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +// LoadToken restores a Token object from a file located at 'path'. +func LoadToken(path string) (*Token, error) { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) + } + defer file.Close() + + var token Token + + dec := json.NewDecoder(file) + if err = dec.Decode(&token); err != nil { + return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err) + } + return &token, nil +} + +// SaveToken persists an oauth token at the given location on disk. +// It moves the new file into place so it can safely be used to replace an existing file +// that maybe accessed by multiple processes. +func SaveToken(path string, mode os.FileMode, token Token) error { + dir := filepath.Dir(path) + err := os.MkdirAll(dir, os.ModePerm) + if err != nil { + return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err) + } + + newFile, err := ioutil.TempFile(dir, "token") + if err != nil { + return fmt.Errorf("failed to create the temp file to write the token: %v", err) + } + tempPath := newFile.Name() + + if err := json.NewEncoder(newFile).Encode(token); err != nil { + return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err) + } + if err := newFile.Close(); err != nil { + return fmt.Errorf("failed to close temp file %s: %v", tempPath, err) + } + + // Atomic replace to avoid multi-writer file corruptions + if err := os.Rename(tempPath, path); err != nil { + return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err) + } + if err := os.Chmod(path, mode); err != nil { + return fmt.Errorf("failed to chmod the token file %s: %v", path, err) + } + return nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/token.go b/vendor/github.com/Azure/go-autorest/autorest/azure/token.go new file mode 100644 index 0000000000..db9a8fa02a --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/token.go @@ -0,0 +1,363 @@ +package azure + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "encoding/base64" + "fmt" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/Azure/go-autorest/autorest" + "github.com/dgrijalva/jwt-go" +) + +const ( + defaultRefresh = 5 * time.Minute + tokenBaseDate = "1970-01-01T00:00:00Z" + + // OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow + OAuthGrantTypeDeviceCode = "device_code" + + // OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows + OAuthGrantTypeClientCredentials = "client_credentials" + + // OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows + OAuthGrantTypeRefreshToken = "refresh_token" +) + +var expirationBase time.Time + +func init() { + expirationBase, _ = time.Parse(time.RFC3339, tokenBaseDate) +} + +// TokenRefreshCallback is the type representing callbacks that will be called after +// a successful token refresh +type TokenRefreshCallback func(Token) error + +// Token encapsulates the access token used to authorize Azure requests. +type Token struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + + ExpiresIn string `json:"expires_in"` + ExpiresOn string `json:"expires_on"` + NotBefore string `json:"not_before"` + + Resource string `json:"resource"` + Type string `json:"token_type"` +} + +// Expires returns the time.Time when the Token expires. +func (t Token) Expires() time.Time { + s, err := strconv.Atoi(t.ExpiresOn) + if err != nil { + s = -3600 + } + return expirationBase.Add(time.Duration(s) * time.Second).UTC() +} + +// IsExpired returns true if the Token is expired, false otherwise. +func (t Token) IsExpired() bool { + return t.WillExpireIn(0) +} + +// WillExpireIn returns true if the Token will expire after the passed time.Duration interval +// from now, false otherwise. +func (t Token) WillExpireIn(d time.Duration) bool { + return !t.Expires().After(time.Now().Add(d)) +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "Bearer " followed by the AccessToken of the Token. +func (t *Token) WithAuthorization() autorest.PrepareDecorator { + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + return (autorest.WithBearerAuthorization(t.AccessToken)(p)).Prepare(r) + }) + } +} + +// ServicePrincipalNoSecret represents a secret type that contains no secret +// meaning it is not valid for fetching a fresh token. This is used by Manual +type ServicePrincipalNoSecret struct { +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret +// It only returns an error for the ServicePrincipalNoSecret type +func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token.") +} + +// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form +// that is submitted when acquiring an oAuth token. +type ServicePrincipalSecret interface { + SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error +} + +// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization. +type ServicePrincipalTokenSecret struct { + ClientSecret string +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +// It will populate the form submitted during oAuth Token Acquisition using the client_secret. +func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("client_secret", tokenSecret.ClientSecret) + return nil +} + +// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs. +type ServicePrincipalCertificateSecret struct { + Certificate *x509.Certificate + PrivateKey *rsa.PrivateKey +} + +// SignJwt returns the JWT signed with the certificate's private key. +func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { + hasher := sha1.New() + _, err := hasher.Write(secret.Certificate.Raw) + if err != nil { + return "", err + } + + thumbprint := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) + + // The jti (JWT ID) claim provides a unique identifier for the JWT. + jti := make([]byte, 20) + _, err = rand.Read(jti) + if err != nil { + return "", err + } + + token := jwt.New(jwt.SigningMethodRS256) + token.Header["x5t"] = thumbprint + token.Claims = jwt.MapClaims{ + "aud": spt.oauthConfig.TokenEndpoint, + "iss": spt.clientID, + "sub": spt.clientID, + "jti": base64.URLEncoding.EncodeToString(jti), + "nbf": time.Now().Unix(), + "exp": time.Now().Add(time.Hour * 24).Unix(), + } + + signedString, err := token.SignedString(secret.PrivateKey) + return signedString, err +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +// It will populate the form submitted during oAuth Token Acquisition using a JWT signed with a certificate. +func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + jwt, err := secret.SignJwt(spt) + if err != nil { + return err + } + + v.Set("client_assertion", jwt) + v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") + return nil +} + +// ServicePrincipalToken encapsulates a Token created for a Service Principal. +type ServicePrincipalToken struct { + Token + + secret ServicePrincipalSecret + oauthConfig OAuthConfig + clientID string + resource string + autoRefresh bool + refreshWithin time.Duration + sender autorest.Sender + + refreshCallbacks []TokenRefreshCallback +} + +// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. +func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + spt := &ServicePrincipalToken{ + oauthConfig: oauthConfig, + secret: secret, + clientID: id, + resource: resource, + autoRefresh: true, + refreshWithin: defaultRefresh, + sender: &http.Client{}, + refreshCallbacks: callbacks, + } + return spt, nil +} + +// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token +func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + spt, err := NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalNoSecret{}, + callbacks...) + if err != nil { + return nil, err + } + + spt.Token = token + + return spt, nil +} + +// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal +// credentials scoped to the named resource. +func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalTokenSecret{ + ClientSecret: secret, + }, + callbacks..., + ) +} + +// NewServicePrincipalTokenFromCertificate create a ServicePrincipalToken from the supplied pkcs12 bytes. +func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalCertificateSecret{ + PrivateKey: privateKey, + Certificate: certificate, + }, + callbacks..., + ) +} + +// EnsureFresh will refresh the token if it will expire within the refresh window (as set by +// RefreshWithin). +func (spt *ServicePrincipalToken) EnsureFresh() error { + if spt.WillExpireIn(spt.refreshWithin) { + return spt.Refresh() + } + return nil +} + +// InvokeRefreshCallbacks calls any TokenRefreshCallbacks that were added to the SPT during initialization +func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { + if spt.refreshCallbacks != nil { + for _, callback := range spt.refreshCallbacks { + err := callback(spt.Token) + if err != nil { + return autorest.NewErrorWithError(err, + "azure.ServicePrincipalToken", "InvokeRefreshCallbacks", nil, "A TokenRefreshCallback handler returned an error") + } + } + } + return nil +} + +// Refresh obtains a fresh token for the Service Principal. +func (spt *ServicePrincipalToken) Refresh() error { + return spt.refreshInternal(spt.resource) +} + +// RefreshExchange refreshes the token, but for a different resource. +func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { + return spt.refreshInternal(resource) +} + +func (spt *ServicePrincipalToken) refreshInternal(resource string) error { + v := url.Values{} + v.Set("client_id", spt.clientID) + v.Set("resource", resource) + + if spt.RefreshToken != "" { + v.Set("grant_type", OAuthGrantTypeRefreshToken) + v.Set("refresh_token", spt.RefreshToken) + } else { + v.Set("grant_type", OAuthGrantTypeClientCredentials) + err := spt.secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + } + + req, _ := autorest.Prepare(&http.Request{}, + autorest.AsPost(), + autorest.AsFormURLEncoded(), + autorest.WithBaseURL(spt.oauthConfig.TokenEndpoint.String()), + autorest.WithFormData(v)) + + resp, err := autorest.SendWithSender(spt.sender, req) + if err != nil { + return autorest.NewErrorWithError(err, + "azure.ServicePrincipalToken", "Refresh", resp, "Failure sending request for Service Principal %s", + spt.clientID) + } + + var newToken Token + err = autorest.Respond(resp, + autorest.WithErrorUnlessOK(), + autorest.ByUnmarshallingJSON(&newToken), + autorest.ByClosing()) + if err != nil { + return autorest.NewErrorWithError(err, + "azure.ServicePrincipalToken", "Refresh", resp, "Failure handling response to Service Principal %s request", + spt.clientID) + } + + spt.Token = newToken + + err = spt.InvokeRefreshCallbacks(newToken) + if err != nil { + // its already wrapped inside InvokeRefreshCallbacks + return err + } + + return nil +} + +// SetAutoRefresh enables or disables automatic refreshing of stale tokens. +func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) { + spt.autoRefresh = autoRefresh +} + +// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will +// refresh the token. +func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { + spt.refreshWithin = d + return +} + +// SetSender sets the autorest.Sender used when obtaining the Service Principal token. An +// undecorated http.Client is used by default. +func (spt *ServicePrincipalToken) SetSender(s autorest.Sender) { + spt.sender = s +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "Bearer " followed by the AccessToken of the ServicePrincipalToken. +// +// By default, the token will automatically refresh if nearly expired (as determined by the +// RefreshWithin interval). Use the AutoRefresh method to enable or disable automatically refreshing +// tokens. +func (spt *ServicePrincipalToken) WithAuthorization() autorest.PrepareDecorator { + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + if spt.autoRefresh { + err := spt.EnsureFresh() + if err != nil { + return r, autorest.NewErrorWithError(err, + "azure.ServicePrincipalToken", "WithAuthorization", nil, "Failed to refresh Service Principal Token for request to %s", + r.URL) + } + } + return (autorest.WithBearerAuthorization(spt.AccessToken)(p)).Prepare(r) + }) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go new file mode 100644 index 0000000000..b55b3d1035 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/client.go @@ -0,0 +1,212 @@ +package autorest + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "net/http/cookiejar" + "time" +) + +const ( + // DefaultPollingDelay is a reasonable delay between polling requests. + DefaultPollingDelay = 60 * time.Second + + // DefaultPollingDuration is a reasonable total polling duration. + DefaultPollingDuration = 15 * time.Minute + + // DefaultRetryAttempts is number of attempts for retry status codes (5xx). + DefaultRetryAttempts = 3 +) + +var statusCodesForRetry = []int{ + http.StatusRequestTimeout, // 408 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 +} + +const ( + requestFormat = `HTTP Request Begin =================================================== +%s +===================================================== HTTP Request End +` + responseFormat = `HTTP Response Begin =================================================== +%s +===================================================== HTTP Response End +` +) + +// Response serves as the base for all responses from generated clients. It provides access to the +// last http.Response. +type Response struct { + *http.Response `json:"-"` +} + +// LoggingInspector implements request and response inspectors that log the full request and +// response to a supplied log. +type LoggingInspector struct { + Logger *log.Logger +} + +// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The +// body is restored after being emitted. +// +// Note: Since it reads the entire Body, this decorator should not be used where body streaming is +// important. It is best used to trace JSON or similar body values. +func (li LoggingInspector) WithInspection() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + var body, b bytes.Buffer + + defer r.Body.Close() + + r.Body = ioutil.NopCloser(io.TeeReader(r.Body, &body)) + if err := r.Write(&b); err != nil { + return nil, fmt.Errorf("Failed to write response: %v", err) + } + + li.Logger.Printf(requestFormat, b.String()) + + r.Body = ioutil.NopCloser(&body) + return p.Prepare(r) + }) + } +} + +// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The +// body is restored after being emitted. +// +// Note: Since it reads the entire Body, this decorator should not be used where body streaming is +// important. It is best used to trace JSON or similar body values. +func (li LoggingInspector) ByInspecting() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + var body, b bytes.Buffer + defer resp.Body.Close() + resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, &body)) + if err := resp.Write(&b); err != nil { + return fmt.Errorf("Failed to write response: %v", err) + } + + li.Logger.Printf(responseFormat, b.String()) + + resp.Body = ioutil.NopCloser(&body) + return r.Respond(resp) + }) + } +} + +// Client is the base for autorest generated clients. It provides default, "do nothing" +// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the +// standard, undecorated http.Client as a default Sender. +// +// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and +// return responses that compose with Response. +// +// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom +// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit +// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence +// sending the request by providing a decorated Sender. +type Client struct { + Authorizer Authorizer + Sender Sender + RequestInspector PrepareDecorator + ResponseInspector RespondDecorator + + // PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header + PollingDelay time.Duration + + // PollingDuration sets the maximum polling time after which an error is returned. + PollingDuration time.Duration + + // RetryAttempts sets the default number of retry attempts for client. + RetryAttempts int + + // RetryDuration sets the delay duration for retries. + RetryDuration time.Duration + + // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent + // through the Do method. + UserAgent string + + Jar http.CookieJar +} + +// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed +// string. +func NewClientWithUserAgent(ua string) Client { + return Client{ + PollingDelay: DefaultPollingDelay, + PollingDuration: DefaultPollingDuration, + RetryAttempts: DefaultRetryAttempts, + RetryDuration: 30 * time.Second, + UserAgent: ua, + } +} + +// Do implements the Sender interface by invoking the active Sender after applying authorization. +// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent +// is set, apply set the User-Agent header. +func (c Client) Do(r *http.Request) (*http.Response, error) { + if r.UserAgent() == "" { + r, _ = Prepare(r, + WithUserAgent(c.UserAgent)) + } + r, err := Prepare(r, + c.WithInspection(), + c.WithAuthorization()) + if err != nil { + return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") + } + resp, err := SendWithSender(c.sender(), r, + DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...)) + Respond(resp, + c.ByInspecting()) + return resp, err +} + +// sender returns the Sender to which to send requests. +func (c Client) sender() Sender { + if c.Sender == nil { + j, _ := cookiejar.New(nil) + return &http.Client{Jar: j} + } + return c.Sender +} + +// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator +// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer. +func (c Client) WithAuthorization() PrepareDecorator { + return c.authorizer().WithAuthorization() +} + +// authorizer returns the Authorizer to use. +func (c Client) authorizer() Authorizer { + if c.Authorizer == nil { + return NullAuthorizer{} + } + return c.Authorizer +} + +// WithInspection is a convenience method that passes the request to the supplied RequestInspector, +// if present, or returns the WithNothing PrepareDecorator otherwise. +func (c Client) WithInspection() PrepareDecorator { + if c.RequestInspector == nil { + return WithNothing() + } + return c.RequestInspector +} + +// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector, +// if present, or returns the ByIgnoring RespondDecorator otherwise. +func (c Client) ByInspecting() RespondDecorator { + if c.ResponseInspector == nil { + return ByIgnoring() + } + return c.ResponseInspector +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go new file mode 100644 index 0000000000..80ca60e9b0 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/date.go @@ -0,0 +1,82 @@ +/* +Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) +defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of +time.Time types. And both convert to time.Time through a ToTime method. +*/ +package date + +import ( + "fmt" + "time" +) + +const ( + fullDate = "2006-01-02" + fullDateJSON = `"2006-01-02"` + dateFormat = "%04d-%02d-%02d" + jsonFormat = `"%04d-%02d-%02d"` +) + +// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e., +// 2006-01-02). +type Date struct { + time.Time +} + +// ParseDate create a new Date from the passed string. +func ParseDate(date string) (d Date, err error) { + return parseDate(date, fullDate) +} + +func parseDate(date string, format string) (Date, error) { + d, err := time.Parse(format, date) + return Date{Time: d}, err +} + +// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d Date) MarshalBinary() ([]byte, error) { + return d.MarshalText() +} + +// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d *Date) UnmarshalBinary(data []byte) error { + return d.UnmarshalText(data) +} + +// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d Date) MarshalJSON() (json []byte, err error) { + return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil +} + +// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d *Date) UnmarshalJSON(data []byte) (err error) { + d.Time, err = time.Parse(fullDateJSON, string(data)) + return err +} + +// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d Date) MarshalText() (text []byte, err error) { + return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil +} + +// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d *Date) UnmarshalText(data []byte) (err error) { + d.Time, err = time.Parse(fullDate, string(data)) + return err +} + +// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02). +func (d Date) String() string { + return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day()) +} + +// ToTime returns a Date as a time.Time +func (d Date) ToTime() time.Time { + return d.Time +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go new file mode 100644 index 0000000000..c1af629634 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/time.go @@ -0,0 +1,89 @@ +package date + +import ( + "regexp" + "time" +) + +// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. +const ( + azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"` + azureUtcFormat = "2006-01-02T15:04:05.999999999" + rfc3339JSON = `"` + time.RFC3339Nano + `"` + rfc3339 = time.RFC3339Nano + tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$` +) + +// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +type Time struct { + time.Time +} + +// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) MarshalBinary() ([]byte, error) { + return t.Time.MarshalText() +} + +// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time +// (i.e., 2006-01-02T15:04:05Z). +func (t *Time) UnmarshalBinary(data []byte) error { + return t.UnmarshalText(data) +} + +// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) MarshalJSON() (json []byte, err error) { + return t.Time.MarshalJSON() +} + +// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time +// (i.e., 2006-01-02T15:04:05Z). +func (t *Time) UnmarshalJSON(data []byte) (err error) { + timeFormat := azureUtcFormatJSON + match, err := regexp.Match(tzOffsetRegex, data) + if err != nil { + return err + } else if match { + timeFormat = rfc3339JSON + } + t.Time, err = ParseTime(timeFormat, string(data)) + return err +} + +// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) MarshalText() (text []byte, err error) { + return t.Time.MarshalText() +} + +// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time +// (i.e., 2006-01-02T15:04:05Z). +func (t *Time) UnmarshalText(data []byte) (err error) { + timeFormat := azureUtcFormat + match, err := regexp.Match(tzOffsetRegex, data) + if err != nil { + return err + } else if match { + timeFormat = rfc3339 + } + t.Time, err = ParseTime(timeFormat, string(data)) + return err +} + +// String returns the Time formatted as an RFC3339 date-time string (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) String() string { + // Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does. + b, err := t.MarshalText() + if err != nil { + return "" + } + return string(b) +} + +// ToTime returns a Time as a time.Time +func (t Time) ToTime() time.Time { + return t.Time +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go new file mode 100644 index 0000000000..11995fb9f2 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go @@ -0,0 +1,86 @@ +package date + +import ( + "errors" + "time" +) + +const ( + rfc1123JSON = `"` + time.RFC1123 + `"` + rfc1123 = time.RFC1123 +) + +// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +type TimeRFC1123 struct { + time.Time +} + +// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time +// (i.e., Mon, 02 Jan 2006 15:04:05 MST). +func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) { + t.Time, err = ParseTime(rfc1123JSON, string(data)) + if err != nil { + return err + } + return nil +} + +// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) MarshalJSON() ([]byte, error) { + if y := t.Year(); y < 0 || y >= 10000 { + return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") + } + b := []byte(t.Format(rfc1123JSON)) + return b, nil +} + +// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) MarshalText() ([]byte, error) { + if y := t.Year(); y < 0 || y >= 10000 { + return nil, errors.New("Time.MarshalText: year outside of range [0,9999]") + } + + b := []byte(t.Format(rfc1123)) + return b, nil +} + +// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time +// (i.e., Mon, 02 Jan 2006 15:04:05 MST). +func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) { + t.Time, err = ParseTime(rfc1123, string(data)) + if err != nil { + return err + } + return nil +} + +// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) MarshalBinary() ([]byte, error) { + return t.MarshalText() +} + +// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time +// (i.e., Mon, 02 Jan 2006 15:04:05 MST). +func (t *TimeRFC1123) UnmarshalBinary(data []byte) error { + return t.UnmarshalText(data) +} + +// ToTime returns a Time as a time.Time +func (t TimeRFC1123) ToTime() time.Time { + return t.Time +} + +// String returns the Time formatted as an RFC1123 date-time string (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) String() string { + // Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does. + b, err := t.MarshalText() + if err != nil { + return "" + } + return string(b) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go new file mode 100644 index 0000000000..207b1a240a --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go @@ -0,0 +1,11 @@ +package date + +import ( + "strings" + "time" +) + +// ParseTime to parse Time string to specified format. +func ParseTime(format string, t string) (d time.Time, err error) { + return time.Parse(format, strings.ToUpper(t)) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/error.go b/vendor/github.com/Azure/go-autorest/autorest/error.go new file mode 100644 index 0000000000..2e4fc79c10 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/error.go @@ -0,0 +1,77 @@ +package autorest + +import ( + "fmt" + "net/http" +) + +const ( + // UndefinedStatusCode is used when HTTP status code is not available for an error. + UndefinedStatusCode = 0 +) + +// DetailedError encloses a error with details of the package, method, and associated HTTP +// status code (if any). +type DetailedError struct { + Original error + + // PackageType is the package type of the object emitting the error. For types, the value + // matches that produced the the '%T' format specifier of the fmt package. For other elements, + // such as functions, it is just the package name (e.g., "autorest"). + PackageType string + + // Method is the name of the method raising the error. + Method string + + // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error. + StatusCode interface{} + + // Message is the error message. + Message string +} + +// NewError creates a new Error conforming object from the passed packageType, method, and +// message. message is treated as a format string to which the optional args apply. +func NewError(packageType string, method string, message string, args ...interface{}) DetailedError { + return NewErrorWithError(nil, packageType, method, nil, message, args...) +} + +// NewErrorWithResponse creates a new Error conforming object from the passed +// packageType, method, statusCode of the given resp (UndefinedStatusCode if +// resp is nil), and message. message is treated as a format string to which the +// optional args apply. +func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { + return NewErrorWithError(nil, packageType, method, resp, message, args...) +} + +// NewErrorWithError creates a new Error conforming object from the +// passed packageType, method, statusCode of the given resp (UndefinedStatusCode +// if resp is nil), message, and original error. message is treated as a format +// string to which the optional args apply. +func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { + if v, ok := original.(DetailedError); ok { + return v + } + + statusCode := UndefinedStatusCode + if resp != nil { + statusCode = resp.StatusCode + } + + return DetailedError{ + Original: original, + PackageType: packageType, + Method: method, + StatusCode: statusCode, + Message: fmt.Sprintf(message, args...), + } +} + +// Error returns a formatted containing all available details (i.e., PackageType, Method, +// StatusCode, Message, and original error (if any)). +func (e DetailedError) Error() string { + if e.Original == nil { + return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode) + } + return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go new file mode 100644 index 0000000000..5b2c52704a --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/preparer.go @@ -0,0 +1,433 @@ +package autorest + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "net/url" + "strings" +) + +const ( + mimeTypeJSON = "application/json" + mimeTypeFormPost = "application/x-www-form-urlencoded" + + headerAuthorization = "Authorization" + headerContentType = "Content-Type" + headerUserAgent = "User-Agent" +) + +// Preparer is the interface that wraps the Prepare method. +// +// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations +// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used. +type Preparer interface { + Prepare(*http.Request) (*http.Request, error) +} + +// PreparerFunc is a method that implements the Preparer interface. +type PreparerFunc func(*http.Request) (*http.Request, error) + +// Prepare implements the Preparer interface on PreparerFunc. +func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) { + return pf(r) +} + +// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the +// http.Request and pass it along or, first, pass the http.Request along then affect the result. +type PrepareDecorator func(Preparer) Preparer + +// CreatePreparer creates, decorates, and returns a Preparer. +// Without decorators, the returned Preparer returns the passed http.Request unmodified. +// Preparers are safe to share and re-use. +func CreatePreparer(decorators ...PrepareDecorator) Preparer { + return DecoratePreparer( + Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })), + decorators...) +} + +// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it +// applies to the Preparer. Decorators are applied in the order received, but their affect upon the +// request depends on whether they are a pre-decorator (change the http.Request and then pass it +// along) or a post-decorator (pass the http.Request along and alter it on return). +func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer { + for _, decorate := range decorators { + p = decorate(p) + } + return p +} + +// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators. +// It creates a Preparer from the decorators which it then applies to the passed http.Request. +func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) { + if r == nil { + return nil, NewError("autorest", "Prepare", "Invoked without an http.Request") + } + return CreatePreparer(decorators...).Prepare(r) +} + +// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed +// http.Request. +func WithNothing() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + return p.Prepare(r) + }) + } +} + +// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to +// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before +// adding the header. +func WithHeader(header string, value string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(header), value) + } + return r, err + }) + } +} + +// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "Bearer " followed by the supplied token. +func WithBearerAuthorization(token string) PrepareDecorator { + return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token)) +} + +// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value +// is the passed contentType. +func AsContentType(contentType string) PrepareDecorator { + return WithHeader(headerContentType, contentType) +} + +// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the +// passed string. +func WithUserAgent(ua string) PrepareDecorator { + return WithHeader(headerUserAgent, ua) +} + +// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is +// "application/x-www-form-urlencoded". +func AsFormURLEncoded() PrepareDecorator { + return AsContentType(mimeTypeFormPost) +} + +// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is +// "application/json". +func AsJSON() PrepareDecorator { + return AsContentType(mimeTypeJSON) +} + +// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The +// decorator does not validate that the passed method string is a known HTTP method. +func WithMethod(method string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r.Method = method + return p.Prepare(r) + }) + } +} + +// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE. +func AsDelete() PrepareDecorator { return WithMethod("DELETE") } + +// AsGet returns a PrepareDecorator that sets the HTTP method to GET. +func AsGet() PrepareDecorator { return WithMethod("GET") } + +// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD. +func AsHead() PrepareDecorator { return WithMethod("HEAD") } + +// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS. +func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") } + +// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH. +func AsPatch() PrepareDecorator { return WithMethod("PATCH") } + +// AsPost returns a PrepareDecorator that sets the HTTP method to POST. +func AsPost() PrepareDecorator { return WithMethod("POST") } + +// AsPut returns a PrepareDecorator that sets the HTTP method to PUT. +func AsPut() PrepareDecorator { return WithMethod("PUT") } + +// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed +// from the supplied baseUrl. +func WithBaseURL(baseURL string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + var u *url.URL + if u, err = url.Parse(baseURL); err != nil { + return r, err + } + if u.Scheme == "" { + err = fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) + } + if err == nil { + r.URL = u + } + } + return r, err + }) + } +} + +// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the +// http.Request body. +func WithFormData(v url.Values) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + s := v.Encode() + r.ContentLength = int64(len(s)) + r.Body = ioutil.NopCloser(strings.NewReader(s)) + } + return r, err + }) + } +} + +// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters +// into the http.Request body. +func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + var body bytes.Buffer + writer := multipart.NewWriter(&body) + for key, value := range formDataParameters { + if rc, ok := value.(io.ReadCloser); ok { + var fd io.Writer + if fd, err = writer.CreateFormFile(key, key); err != nil { + return r, err + } + if _, err = io.Copy(fd, rc); err != nil { + return r, err + } + } else { + if err = writer.WriteField(key, ensureValueString(value)); err != nil { + return r, err + } + } + } + if err = writer.Close(); err != nil { + return r, err + } + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) + r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) + r.ContentLength = int64(body.Len()) + return r, err + } + return r, err + }) + } +} + +// WithFile returns a PrepareDecorator that sends file in request body. +func WithFile(f io.ReadCloser) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + b, err := ioutil.ReadAll(f) + if err != nil { + return r, err + } + r.Body = ioutil.NopCloser(bytes.NewReader(b)) + r.ContentLength = int64(len(b)) + } + return r, err + }) + } +} + +// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request +// and sets the Content-Length header. +func WithBool(v bool) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the +// request and sets the Content-Length header. +func WithFloat32(v float32) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the +// request and sets the Content-Length header. +func WithFloat64(v float64) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request +// and sets the Content-Length header. +func WithInt32(v int32) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request +// and sets the Content-Length header. +func WithInt64(v int64) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithString returns a PrepareDecorator that encodes the passed string into the body of the request +// and sets the Content-Length header. +func WithString(v string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + r.ContentLength = int64(len(v)) + r.Body = ioutil.NopCloser(strings.NewReader(v)) + } + return r, err + }) + } +} + +// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the +// request and sets the Content-Length header. +func WithJSON(v interface{}) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + b, err := json.Marshal(v) + if err == nil { + r.ContentLength = int64(len(b)) + r.Body = ioutil.NopCloser(bytes.NewReader(b)) + } + } + return r, err + }) + } +} + +// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path +// is absolute (that is, it begins with a "/"), it replaces the existing path. +func WithPath(path string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithPath", "Invoked with a nil URL") + } + if r.URL, err = parseURL(r.URL, path); err != nil { + return r, err + } + } + return r, err + }) + } +} + +// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the +// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The +// values will be escaped (aka URL encoded) before insertion into the path. +func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { + parameters := escapeValueStrings(ensureValueStrings(pathParameters)) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL") + } + for key, value := range parameters { + path = strings.Replace(path, "{"+key+"}", value, -1) + } + if r.URL, err = parseURL(r.URL, path); err != nil { + return r, err + } + } + return r, err + }) + } +} + +// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the +// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. +func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { + parameters := ensureValueStrings(pathParameters) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL") + } + for key, value := range parameters { + path = strings.Replace(path, "{"+key+"}", value, -1) + } + + if r.URL, err = parseURL(r.URL, path); err != nil { + return r, err + } + } + return r, err + }) + } +} + +func parseURL(u *url.URL, path string) (*url.URL, error) { + p := strings.TrimRight(u.String(), "/") + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + return url.Parse(p + path) +} + +// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters +// given in the supplied map (i.e., key=value). +func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator { + parameters := ensureValueStrings(queryParameters) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL") + } + v := r.URL.Query() + for key, value := range parameters { + v.Add(key, value) + } + r.URL.RawQuery = createQuery(v) + } + return r, err + }) + } +} + +// Authorizer is the interface that provides a PrepareDecorator used to supply request +// authorization. Most often, the Authorizer decorator runs last so it has access to the full +// state of the formed HTTP request. +type Authorizer interface { + WithAuthorization() PrepareDecorator +} + +// NullAuthorizer implements a default, "do nothing" Authorizer. +type NullAuthorizer struct{} + +// WithAuthorization returns a PrepareDecorator that does nothing. +func (na NullAuthorizer) WithAuthorization() PrepareDecorator { + return WithNothing() +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/responder.go b/vendor/github.com/Azure/go-autorest/autorest/responder.go new file mode 100644 index 0000000000..e377ad48af --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/responder.go @@ -0,0 +1,208 @@ +package autorest + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" + "strings" +) + +// Responder is the interface that wraps the Respond method. +// +// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold +// state since Responders may be shared and re-used. +type Responder interface { + Respond(*http.Response) error +} + +// ResponderFunc is a method that implements the Responder interface. +type ResponderFunc func(*http.Response) error + +// Respond implements the Responder interface on ResponderFunc. +func (rf ResponderFunc) Respond(r *http.Response) error { + return rf(r) +} + +// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to +// the http.Response and pass it along or, first, pass the http.Response along then react. +type RespondDecorator func(Responder) Responder + +// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned +// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share +// and re-used: It depends on the applied decorators. For example, a standard decorator that closes +// the response body is fine to share whereas a decorator that reads the body into a passed struct +// is not. +// +// To prevent memory leaks, ensure that at least one Responder closes the response body. +func CreateResponder(decorators ...RespondDecorator) Responder { + return DecorateResponder( + Responder(ResponderFunc(func(r *http.Response) error { return nil })), + decorators...) +} + +// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it +// applies to the Responder. Decorators are applied in the order received, but their affect upon the +// request depends on whether they are a pre-decorator (react to the http.Response and then pass it +// along) or a post-decorator (pass the http.Response along and then react). +func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder { + for _, decorate := range decorators { + r = decorate(r) + } + return r +} + +// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators. +// It creates a Responder from the decorators it then applies to the passed http.Response. +func Respond(r *http.Response, decorators ...RespondDecorator) error { + if r == nil { + return nil + } + return CreateResponder(decorators...).Respond(r) +} + +// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined +// to the next RespondDecorator. +func ByIgnoring() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + return r.Respond(resp) + }) + } +} + +// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as +// the Body is read. +func ByCopying(b *bytes.Buffer) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && resp != nil && resp.Body != nil { + resp.Body = TeeReadCloser(resp.Body, b) + } + return err + }) + } +} + +// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it +// closes the response body. Since the passed Responder is invoked prior to closing the response +// body, the decorator may occur anywhere within the set. +func ByClosing() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if resp != nil && resp.Body != nil { + if err := resp.Body.Close(); err != nil { + return fmt.Errorf("Error closing the response body: %v", err) + } + } + return err + }) + } +} + +// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which +// it closes the response if the passed Responder returns an error and the response body exists. +func ByClosingIfError() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err != nil && resp != nil && resp.Body != nil { + if err := resp.Body.Close(); err != nil { + return fmt.Errorf("Error closing the response body: %v", err) + } + } + return err + }) + } +} + +// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the +// response Body into the value pointed to by v. +func ByUnmarshallingJSON(v interface{}) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil { + b, errInner := ioutil.ReadAll(resp.Body) + if errInner != nil { + err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) + } else if len(strings.Trim(string(b), " ")) > 0 { + errInner = json.Unmarshal(b, v) + if errInner != nil { + err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b)) + } + } + } + return err + }) + } +} + +// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the +// response Body into the value pointed to by v. +func ByUnmarshallingXML(v interface{}) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil { + b, errInner := ioutil.ReadAll(resp.Body) + if errInner != nil { + err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) + } else { + errInner = xml.Unmarshal(b, v) + if errInner != nil { + err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b)) + } + } + } + return err + }) + } +} + +// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response +// StatusCode is among the set passed. Since these are artificial errors, the response body +// may still require closing. +func WithErrorUnlessStatusCode(codes ...int) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && !ResponseHasStatusCode(resp, codes...) { + err = NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s", + resp.Request.Method, + resp.Request.URL, + resp.Status) + } + return err + }) + } +} + +// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is +// anything other than HTTP 200. +func WithErrorUnlessOK() RespondDecorator { + return WithErrorUnlessStatusCode(http.StatusOK) +} + +// ExtractHeader extracts all values of the specified header from the http.Response. It returns an +// empty string slice if the passed http.Response is nil or the header does not exist. +func ExtractHeader(header string, resp *http.Response) []string { + if resp != nil && resp.Header != nil { + return resp.Header[http.CanonicalHeaderKey(header)] + } + return nil +} + +// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It +// returns an empty string if the passed http.Response is nil or the header does not exist. +func ExtractHeaderValue(header string, resp *http.Response) string { + h := ExtractHeader(header, resp) + if len(h) > 0 { + return h[0] + } + return "" +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go new file mode 100644 index 0000000000..93e6489e9c --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/sender.go @@ -0,0 +1,267 @@ +package autorest + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "math" + "net/http" + "time" +) + +// Sender is the interface that wraps the Do method to send HTTP requests. +// +// The standard http.Client conforms to this interface. +type Sender interface { + Do(*http.Request) (*http.Response, error) +} + +// SenderFunc is a method that implements the Sender interface. +type SenderFunc func(*http.Request) (*http.Response, error) + +// Do implements the Sender interface on SenderFunc. +func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { + return sf(r) +} + +// SendDecorator takes and possibily decorates, by wrapping, a Sender. Decorators may affect the +// http.Request and pass it along or, first, pass the http.Request along then react to the +// http.Response result. +type SendDecorator func(Sender) Sender + +// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. +func CreateSender(decorators ...SendDecorator) Sender { + return DecorateSender(&http.Client{}, decorators...) +} + +// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to +// the Sender. Decorators are applied in the order received, but their affect upon the request +// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a +// post-decorator (pass the http.Request along and react to the results in http.Response). +func DecorateSender(s Sender, decorators ...SendDecorator) Sender { + for _, decorate := range decorators { + s = decorate(s) + } + return s +} + +// Send sends, by means of the default http.Client, the passed http.Request, returning the +// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which +// it will apply the http.Client before invoking the Do method. +// +// Send is a convenience method and not recommended for production. Advanced users should use +// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client). +// +// Send will not poll or retry requests. +func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) { + return SendWithSender(&http.Client{}, r, decorators...) +} + +// SendWithSender sends the passed http.Request, through the provided Sender, returning the +// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which +// it will apply the http.Client before invoking the Do method. +// +// SendWithSender will not poll or retry requests. +func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) { + return DecorateSender(s, decorators...).Do(r) +} + +// AfterDelay returns a SendDecorator that delays for the passed time.Duration before +// invoking the Sender. The delay may be terminated by closing the optional channel on the +// http.Request. If canceled, no further Senders are invoked. +func AfterDelay(d time.Duration) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + if !DelayForBackoff(d, 1, r.Cancel) { + return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") + } + return s.Do(r) + }) + } +} + +// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request. +func AsIs() SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + return s.Do(r) + }) + } +} + +// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which +// it closes the response if the passed Sender returns an error and the response body exists. +func DoCloseIfError() SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) + if err != nil { + Respond(resp, ByClosing()) + } + return resp, err + }) + } +} + +// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is +// among the set passed. Since these are artificial errors, the response body may still require +// closing. +func DoErrorIfStatusCode(codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) + if err == nil && ResponseHasStatusCode(resp, codes...) { + err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s", + resp.Request.Method, + resp.Request.URL, + resp.Status) + } + return resp, err + }) + } +} + +// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response +// StatusCode is among the set passed. Since these are artificial errors, the response body +// may still require closing. +func DoErrorUnlessStatusCode(codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) + if err == nil && !ResponseHasStatusCode(resp, codes...) { + err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s", + resp.Request.Method, + resp.Request.URL, + resp.Status) + } + return resp, err + }) + } +} + +// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the +// passed status codes. It expects the http.Response to contain a Location header providing the +// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than +// the supplied duration. It will delay between requests for the duration specified in the +// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by +// closing the optional channel on the http.Request. +func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + resp, err = s.Do(r) + + if err == nil && ResponseHasStatusCode(resp, codes...) { + r, err = NewPollingRequest(resp, r.Cancel) + + for err == nil && ResponseHasStatusCode(resp, codes...) { + Respond(resp, + ByClosing()) + resp, err = SendWithSender(s, r, + AfterDelay(GetRetryAfter(resp, delay))) + } + } + + return resp, err + }) + } +} + +// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified +// number of attempts, exponentially backing off between requests using the supplied backoff +// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on +// the http.Request. +func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + for attempt := 0; attempt < attempts; attempt++ { + resp, err = s.Do(r) + if err == nil { + return resp, err + } + DelayForBackoff(backoff, attempt, r.Cancel) + } + return resp, err + }) + } +} + +// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified +// number of attempts, exponentially backing off between requests using the supplied backoff +// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on +// the http.Request. +func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + b := []byte{} + if r.Body != nil { + b, err = ioutil.ReadAll(r.Body) + if err != nil { + return resp, err + } + } + + // Increment to add the first call (attempts denotes number of retries) + attempts++ + for attempt := 0; attempt < attempts; attempt++ { + r.Body = ioutil.NopCloser(bytes.NewBuffer(b)) + resp, err = s.Do(r) + if err != nil || !ResponseHasStatusCode(resp, codes...) { + return resp, err + } + DelayForBackoff(backoff, attempt, r.Cancel) + } + return resp, err + }) + } +} + +// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal +// to or greater than the specified duration, exponentially backing off between requests using the +// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the +// optional channel on the http.Request. +func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + end := time.Now().Add(d) + for attempt := 0; time.Now().Before(end); attempt++ { + resp, err = s.Do(r) + if err == nil { + return resp, err + } + DelayForBackoff(backoff, attempt, r.Cancel) + } + return resp, err + }) + } +} + +// WithLogging returns a SendDecorator that implements simple before and after logging of the +// request. +func WithLogging(logger *log.Logger) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + logger.Printf("Sending %s %s", r.Method, r.URL) + resp, err := s.Do(r) + if err != nil { + logger.Printf("%s %s received error '%v'", r.Method, r.URL, err) + } else { + logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status) + } + return resp, err + }) + } +} + +// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of +// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set +// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early, +// returns false. +func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool { + select { + case <-time.After(time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second): + return true + case <-cancel: + return false + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go new file mode 100644 index 0000000000..7b180b866b --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go @@ -0,0 +1,133 @@ +/* +Package to provides helpers to ease working with pointer values of marshalled structures. +*/ +package to + +// String returns a string value for the passed string pointer. It returns the empty string if the +// pointer is nil. +func String(s *string) string { + if s != nil { + return *s + } + return "" +} + +// StringPtr returns a pointer to the passed string. +func StringPtr(s string) *string { + return &s +} + +// StringSlice returns a string slice value for the passed string slice pointer. It returns a nil +// slice if the pointer is nil. +func StringSlice(s *[]string) []string { + if s != nil { + return *s + } + return nil +} + +// StringSlicePtr returns a pointer to the passed string slice. +func StringSlicePtr(s []string) *[]string { + return &s +} + +// StringMap returns a map of strings built from the map of string pointers. The empty string is +// used for nil pointers. +func StringMap(msp map[string]*string) map[string]string { + ms := make(map[string]string, len(msp)) + for k, sp := range msp { + if sp != nil { + ms[k] = *sp + } else { + ms[k] = "" + } + } + return ms +} + +// StringMapPtr returns a pointer to a map of string pointers built from the passed map of strings. +func StringMapPtr(ms map[string]string) *map[string]*string { + msp := make(map[string]*string, len(ms)) + for k, s := range ms { + msp[k] = StringPtr(s) + } + return &msp +} + +// Bool returns a bool value for the passed bool pointer. It returns false if the pointer is nil. +func Bool(b *bool) bool { + if b != nil { + return *b + } + return false +} + +// BoolPtr returns a pointer to the passed bool. +func BoolPtr(b bool) *bool { + return &b +} + +// Int returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int(i *int) int { + if i != nil { + return *i + } + return 0 +} + +// IntPtr returns a pointer to the passed int. +func IntPtr(i int) *int { + return &i +} + +// Int32 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int32(i *int32) int32 { + if i != nil { + return *i + } + return 0 +} + +// Int32Ptr returns a pointer to the passed int32. +func Int32Ptr(i int32) *int32 { + return &i +} + +// Int64 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int64(i *int64) int64 { + if i != nil { + return *i + } + return 0 +} + +// Int64Ptr returns a pointer to the passed int64. +func Int64Ptr(i int64) *int64 { + return &i +} + +// Float32 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +func Float32(i *float32) float32 { + if i != nil { + return *i + } + return 0.0 +} + +// Float32Ptr returns a pointer to the passed float32. +func Float32Ptr(i float32) *float32 { + return &i +} + +// Float64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +func Float64(i *float64) float64 { + if i != nil { + return *i + } + return 0.0 +} + +// Float64Ptr returns a pointer to the passed float64. +func Float64Ptr(i float64) *float64 { + return &i +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go new file mode 100644 index 0000000000..78067148b2 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/utility.go @@ -0,0 +1,178 @@ +package autorest + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "net/url" + "reflect" + "sort" + "strings" +) + +// EncodedAs is a series of constants specifying various data encodings +type EncodedAs string + +const ( + // EncodedAsJSON states that data is encoded as JSON + EncodedAsJSON EncodedAs = "JSON" + + // EncodedAsXML states that data is encoded as Xml + EncodedAsXML EncodedAs = "XML" +) + +// Decoder defines the decoding method json.Decoder and xml.Decoder share +type Decoder interface { + Decode(v interface{}) error +} + +// NewDecoder creates a new decoder appropriate to the passed encoding. +// encodedAs specifies the type of encoding and r supplies the io.Reader containing the +// encoded data. +func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder { + if encodedAs == EncodedAsJSON { + return json.NewDecoder(r) + } else if encodedAs == EncodedAsXML { + return xml.NewDecoder(r) + } + return nil +} + +// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy +// is especially useful if there is a chance the data will fail to decode. +// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v +// is the decoding destination. +func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error) { + b := bytes.Buffer{} + return b, NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v) +} + +// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc. +// It utilizes io.TeeReader to copy the data read and has the same behavior when reading. +// Further, when it is closed, it ensures that rc is closed as well. +func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser { + return &teeReadCloser{rc, io.TeeReader(rc, w)} +} + +type teeReadCloser struct { + rc io.ReadCloser + r io.Reader +} + +func (t *teeReadCloser) Read(p []byte) (int, error) { + return t.r.Read(p) +} + +func (t *teeReadCloser) Close() error { + return t.rc.Close() +} + +func containsInt(ints []int, n int) bool { + for _, i := range ints { + if i == n { + return true + } + } + return false +} + +func escapeValueStrings(m map[string]string) map[string]string { + for key, value := range m { + m[key] = url.QueryEscape(value) + } + return m +} + +func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string { + mapOfStrings := make(map[string]string) + for key, value := range mapOfInterface { + mapOfStrings[key] = ensureValueString(value) + } + return mapOfStrings +} + +func ensureValueString(value interface{}) string { + if value == nil { + return "" + } + switch v := value.(type) { + case string: + return v + case []byte: + return string(v) + default: + return fmt.Sprintf("%v", v) + } +} + +// MapToValues method converts map[string]interface{} to url.Values. +func MapToValues(m map[string]interface{}) url.Values { + v := url.Values{} + for key, value := range m { + x := reflect.ValueOf(value) + if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { + for i := 0; i < x.Len(); i++ { + v.Add(key, ensureValueString(x.Index(i))) + } + } else { + v.Add(key, ensureValueString(value)) + } + } + return v +} + +// String method converts interface v to string. If interface is a list, it +// joins list elements using separator. +func String(v interface{}, sep ...string) string { + if len(sep) > 0 { + return ensureValueString(strings.Join(v.([]string), sep[0])) + } + return ensureValueString(v) +} + +// Encode method encodes url path and query parameters. +func Encode(location string, v interface{}, sep ...string) string { + s := String(v, sep...) + switch strings.ToLower(location) { + case "path": + return pathEscape(s) + case "query": + return queryEscape(s) + default: + return s + } +} + +func pathEscape(s string) string { + return strings.Replace(url.QueryEscape(s), "+", "%20", -1) +} + +func queryEscape(s string) string { + return url.QueryEscape(s) +} + +// This method is same as Encode() method of "net/url" go package, +// except it does not encode the query parameters because they +// already come encoded. It formats values map in query format (bar=foo&a=b). +func createQuery(v url.Values) string { + var buf bytes.Buffer + keys := make([]string, 0, len(v)) + for k := range v { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + vs := v[k] + prefix := url.QueryEscape(k) + "=" + for _, v := range vs { + if buf.Len() > 0 { + buf.WriteByte('&') + } + buf.WriteString(prefix) + buf.WriteString(v) + } + } + return buf.String() +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go b/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go new file mode 100644 index 0000000000..d7b0eadc55 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go @@ -0,0 +1,373 @@ +/* +Package validation provides methods for validating parameter value using reflection. +*/ +package validation + +import ( + "fmt" + "reflect" + "regexp" + "strings" +) + +// Constraint stores constraint name, target field name +// Rule and chain validations. +type Constraint struct { + + // Target field name for validation. + Target string + + // Constraint name e.g. minLength, MaxLength, Pattern, etc. + Name string + + // Rule for constraint e.g. greater than 10, less than 5 etc. + Rule interface{} + + // Chain Validations for struct type + Chain []Constraint +} + +// Validation stores parameter-wise validation. +type Validation struct { + TargetValue interface{} + Constraints []Constraint +} + +// Constraint list +const ( + Empty = "Empty" + Null = "Null" + ReadOnly = "ReadOnly" + Pattern = "Pattern" + MaxLength = "MaxLength" + MinLength = "MinLength" + MaxItems = "MaxItems" + MinItems = "MinItems" + MultipleOf = "MultipleOf" + UniqueItems = "UniqueItems" + InclusiveMaximum = "InclusiveMaximum" + ExclusiveMaximum = "ExclusiveMaximum" + ExclusiveMinimum = "ExclusiveMinimum" + InclusiveMinimum = "InclusiveMinimum" +) + +// Validate method validates constraints on parameter +// passed in validation array. +func Validate(m []Validation) error { + for _, item := range m { + v := reflect.ValueOf(item.TargetValue) + for _, constraint := range item.Constraints { + var err error + switch v.Kind() { + case reflect.Ptr: + err = validatePtr(v, constraint) + case reflect.String: + err = validateString(v, constraint) + case reflect.Struct: + err = validateStruct(v, constraint) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + err = validateInt(v, constraint) + case reflect.Float32, reflect.Float64: + err = validateFloat(v, constraint) + case reflect.Array, reflect.Slice, reflect.Map: + err = validateArrayMap(v, constraint) + default: + err = createError(v, constraint, fmt.Sprintf("unknown type %v", v.Kind())) + } + + if err != nil { + return err + } + } + } + return nil +} + +func validateStruct(x reflect.Value, v Constraint, name ...string) error { + //Get field name from target name which is in format a.b.c + s := strings.Split(v.Target, ".") + f := x.FieldByName(s[len(s)-1]) + if isZero(f) { + return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.Target)) + } + + if err := Validate([]Validation{ + { + TargetValue: getInterfaceValue(f), + Constraints: []Constraint{v}, + }, + }); err != nil { + return err + } + return nil +} + +func validatePtr(x reflect.Value, v Constraint) error { + if v.Name == ReadOnly { + if !x.IsNil() { + return createError(x.Elem(), v, "readonly parameter; must send as nil or empty in request") + } + return nil + } + if x.IsNil() { + return checkNil(x, v) + } + if v.Chain != nil { + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(x.Elem()), + Constraints: v.Chain, + }, + }) + } + return nil +} + +func validateInt(x reflect.Value, v Constraint) error { + i := x.Int() + r, ok := v.Rule.(int) + if !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) + } + switch v.Name { + case MultipleOf: + if i%int64(r) != 0 { + return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r)) + } + case ExclusiveMinimum: + if i <= int64(r) { + return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) + } + case ExclusiveMaximum: + if i >= int64(r) { + return createError(x, v, fmt.Sprintf("value must be less than %v", r)) + } + case InclusiveMinimum: + if i < int64(r) { + return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) + } + case InclusiveMaximum: + if i > int64(r) { + return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) + } + default: + return createError(x, v, fmt.Sprintf("constraint %v is not applicable for type integer", v.Name)) + } + return nil +} + +func validateFloat(x reflect.Value, v Constraint) error { + f := x.Float() + r, ok := v.Rule.(float64) + if !ok { + return createError(x, v, fmt.Sprintf("rule must be float value for %v constraint; got: %v", v.Name, v.Rule)) + } + switch v.Name { + case ExclusiveMinimum: + if f <= r { + return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) + } + case ExclusiveMaximum: + if f >= r { + return createError(x, v, fmt.Sprintf("value must be less than %v", r)) + } + case InclusiveMinimum: + if f < r { + return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) + } + case InclusiveMaximum: + if f > r { + return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) + } + default: + return createError(x, v, fmt.Sprintf("constraint %s is not applicable for type float", v.Name)) + } + return nil +} + +func validateString(x reflect.Value, v Constraint) error { + s := x.String() + switch v.Name { + case Empty: + if len(s) == 0 { + return checkEmpty(x, v) + } + case Pattern: + reg, err := regexp.Compile(v.Rule.(string)) + if err != nil { + return createError(x, v, err.Error()) + } + if !reg.MatchString(s) { + return createError(x, v, fmt.Sprintf("value doesn't match pattern %v", v.Rule)) + } + case MaxLength: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) + } + if len(s) > v.Rule.(int) { + return createError(x, v, fmt.Sprintf("value length must be less than %v", v.Rule)) + } + case MinLength: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) + } + if len(s) < v.Rule.(int) { + return createError(x, v, fmt.Sprintf("value length must be greater than %v", v.Rule)) + } + case ReadOnly: + if len(s) > 0 { + return createError(reflect.ValueOf(s), v, "readonly parameter; must send as nil or empty in request") + } + default: + return createError(x, v, fmt.Sprintf("constraint %s is not applicable to string type", v.Name)) + } + + if v.Chain != nil { + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(x), + Constraints: v.Chain, + }, + }) + } + return nil +} + +func validateArrayMap(x reflect.Value, v Constraint) error { + switch v.Name { + case Null: + if x.IsNil() { + return checkNil(x, v) + } + case Empty: + if x.IsNil() || x.Len() == 0 { + return checkEmpty(x, v) + } + case MaxItems: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule)) + } + if x.Len() > v.Rule.(int) { + return createError(x, v, fmt.Sprintf("maximum item limit is %v; got: %v", v.Rule, x.Len())) + } + case MinItems: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule)) + } + if x.Len() < v.Rule.(int) { + return createError(x, v, fmt.Sprintf("minimum item limit is %v; got: %v", v.Rule, x.Len())) + } + case UniqueItems: + if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { + if !checkForUniqueInArray(x) { + return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x)) + } + } else if x.Kind() == reflect.Map { + if !checkForUniqueInMap(x) { + return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x)) + } + } else { + return createError(x, v, fmt.Sprintf("type must be array, slice or map for constraint %v; got: %v", v.Name, x.Kind())) + } + case ReadOnly: + if x.Len() != 0 { + return createError(x, v, "readonly parameter; must send as nil or empty in request") + } + default: + return createError(x, v, fmt.Sprintf("constraint %v is not applicable to array, slice and map type", v.Name)) + } + + if v.Chain != nil { + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(x), + Constraints: v.Chain, + }, + }) + } + return nil +} + +func checkNil(x reflect.Value, v Constraint) error { + if _, ok := v.Rule.(bool); !ok { + return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule)) + } + if v.Rule.(bool) { + return createError(x, v, "value can not be null; required parameter") + } + return nil +} + +func checkEmpty(x reflect.Value, v Constraint) error { + if _, ok := v.Rule.(bool); !ok { + return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule)) + } + + if v.Rule.(bool) { + return createError(x, v, "value can not be null or empty; required parameter") + } + return nil +} + +func checkForUniqueInArray(x reflect.Value) bool { + if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 { + return false + } + arrOfInterface := make([]interface{}, x.Len()) + + for i := 0; i < x.Len(); i++ { + arrOfInterface[i] = x.Index(i).Interface() + } + + m := make(map[interface{}]bool) + for _, val := range arrOfInterface { + if m[val] { + return false + } + m[val] = true + } + return true +} + +func checkForUniqueInMap(x reflect.Value) bool { + if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 { + return false + } + mapOfInterface := make(map[interface{}]interface{}, x.Len()) + + keys := x.MapKeys() + for _, k := range keys { + mapOfInterface[k.Interface()] = x.MapIndex(k).Interface() + } + + m := make(map[interface{}]bool) + for _, val := range mapOfInterface { + if m[val] { + return false + } + m[val] = true + } + return true +} + +func getInterfaceValue(x reflect.Value) interface{} { + if x.Kind() == reflect.Invalid { + return nil + } + return x.Interface() +} + +func isZero(x interface{}) bool { + return x == reflect.Zero(reflect.TypeOf(x)).Interface() +} + +func createError(x reflect.Value, v Constraint, err string) error { + return fmt.Errorf("autorest/validation: validation failed: parameter=%s constraint=%s value=%#v details: %s", + v.Target, v.Name, getInterfaceValue(x), err) +} + +// NewErrorWithValidationError appends package type and method name in +// validation error. +func NewErrorWithValidationError(err error, packageType, method string) error { + return fmt.Errorf("%s#%s: Invalid input: %v", packageType, method, err) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go new file mode 100644 index 0000000000..8031a332cd --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/version.go @@ -0,0 +1,18 @@ +package autorest + +import ( + "fmt" +) + +const ( + major = "7" + minor = "0" + patch = "0" + tag = "" + semVerFormat = "%s.%s.%s%s" +) + +// Version returns the semantic version (see http://semver.org). +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/LICENSE-2.0.txt b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt similarity index 100% rename from Godeps/_workspace/src/github.com/MSOpenTech/azure-sdk-for-go/LICENSE-2.0.txt rename to vendor/github.com/aws/aws-sdk-go/LICENSE.txt diff --git a/vendor/github.com/aws/aws-sdk-go/NOTICE.txt b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt new file mode 100644 index 0000000000..5f14d1162e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt @@ -0,0 +1,3 @@ +AWS SDK for Go +Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2014-2015 Stripe, Inc. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go new file mode 100644 index 0000000000..56fdfc2bfc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go @@ -0,0 +1,145 @@ +// Package awserr represents API error interface accessors for the SDK. +package awserr + +// An Error wraps lower level errors with code, message and an original error. +// The underlying concrete error type may also satisfy other interfaces which +// can be to used to obtain more specific information about the error. +// +// Calling Error() or String() will always include the full information about +// an error based on its underlying type. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Get error details +// log.Println("Error:", awsErr.Code(), awsErr.Message()) +// +// // Prints out full error message, including original error if there was one. +// log.Println("Error:", awsErr.Error()) +// +// // Get original error +// if origErr := awsErr.OrigErr(); origErr != nil { +// // operate on original error. +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type Error interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErr() error +} + +// BatchError is a batch of errors which also wraps lower level errors with +// code, message, and original errors. Calling Error() will include all errors +// that occurred in the batch. +// +// Deprecated: Replaced with BatchedErrors. Only defined for backwards +// compatibility. +type BatchError interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// BatchedErrors is a batch of errors which also wraps lower level errors with +// code, message, and original errors. Calling Error() will include all errors +// that occurred in the batch. +// +// Replaces BatchError +type BatchedErrors interface { + // Satisfy the base Error interface. + Error + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// New returns an Error object described by the code, message, and origErr. +// +// If origErr satisfies the Error interface it will not be wrapped within a new +// Error object and will instead be returned. +func New(code, message string, origErr error) Error { + var errs []error + if origErr != nil { + errs = append(errs, origErr) + } + return newBaseError(code, message, errs) +} + +// NewBatchError returns an BatchedErrors with a collection of errors as an +// array of errors. +func NewBatchError(code, message string, errs []error) BatchedErrors { + return newBaseError(code, message, errs) +} + +// A RequestFailure is an interface to extract request failure information from +// an Error such as the request ID of the failed request returned by a service. +// RequestFailures may not always have a requestID value if the request failed +// prior to reaching the service such as a connection error. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if reqerr, ok := err.(RequestFailure); ok { +// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID()) +// } else { +// log.Println("Error:", err.Error()) +// } +// } +// +// Combined with awserr.Error: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Generic AWS Error with Code, Message, and original error (if any) +// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) +// +// if reqErr, ok := err.(awserr.RequestFailure); ok { +// // A service error occurred +// fmt.Println(reqErr.StatusCode(), reqErr.RequestID()) +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type RequestFailure interface { + Error + + // The status code of the HTTP response. + StatusCode() int + + // The request ID returned by the service for a request failure. This will + // be empty if no request ID is available such as the request failed due + // to a connection error. + RequestID() string +} + +// NewRequestFailure returns a new request error wrapper for the given Error +// provided. +func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure { + return newRequestError(err, statusCode, reqID) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go new file mode 100644 index 0000000000..0202a008f5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go @@ -0,0 +1,194 @@ +package awserr + +import "fmt" + +// SprintError returns a string of the formatted error code. +// +// Both extra and origErr are optional. If they are included their lines +// will be added, but if they are not included their lines will be ignored. +func SprintError(code, message, extra string, origErr error) string { + msg := fmt.Sprintf("%s: %s", code, message) + if extra != "" { + msg = fmt.Sprintf("%s\n\t%s", msg, extra) + } + if origErr != nil { + msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error()) + } + return msg +} + +// A baseError wraps the code and message which defines an error. It also +// can be used to wrap an original error object. +// +// Should be used as the root for errors satisfying the awserr.Error. Also +// for any error which does not fit into a specific error wrapper type. +type baseError struct { + // Classification of error + code string + + // Detailed information about error + message string + + // Optional original error this error is based off of. Allows building + // chained errors. + errs []error +} + +// newBaseError returns an error object for the code, message, and errors. +// +// code is a short no whitespace phrase depicting the classification of +// the error that is being created. +// +// message is the free flow string containing detailed information about the +// error. +// +// origErrs is the error objects which will be nested under the new errors to +// be returned. +func newBaseError(code, message string, origErrs []error) *baseError { + b := &baseError{ + code: code, + message: message, + errs: origErrs, + } + + return b +} + +// Error returns the string representation of the error. +// +// See ErrorWithExtra for formatting. +// +// Satisfies the error interface. +func (b baseError) Error() string { + size := len(b.errs) + if size > 0 { + return SprintError(b.code, b.message, "", errorList(b.errs)) + } + + return SprintError(b.code, b.message, "", nil) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (b baseError) String() string { + return b.Error() +} + +// Code returns the short phrase depicting the classification of the error. +func (b baseError) Code() string { + return b.code +} + +// Message returns the error details message. +func (b baseError) Message() string { + return b.message +} + +// OrigErr returns the original error if one was set. Nil is returned if no +// error was set. This only returns the first element in the list. If the full +// list is needed, use BatchedErrors. +func (b baseError) OrigErr() error { + switch len(b.errs) { + case 0: + return nil + case 1: + return b.errs[0] + default: + if err, ok := b.errs[0].(Error); ok { + return NewBatchError(err.Code(), err.Message(), b.errs[1:]) + } + return NewBatchError("BatchedErrors", + "multiple errors occurred", b.errs) + } +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (b baseError) OrigErrs() []error { + return b.errs +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError Error + +// A requestError wraps a request or service error. +// +// Composed of baseError for code, message, and original error. +type requestError struct { + awsError + statusCode int + requestID string +} + +// newRequestError returns a wrapped error with additional information for +// request status code, and service requestID. +// +// Should be used to wrap all request which involve service requests. Even if +// the request failed without a service response, but had an HTTP status code +// that may be meaningful. +// +// Also wraps original errors via the baseError. +func newRequestError(err Error, statusCode int, requestID string) *requestError { + return &requestError{ + awsError: err, + statusCode: statusCode, + requestID: requestID, + } +} + +// Error returns the string representation of the error. +// Satisfies the error interface. +func (r requestError) Error() string { + extra := fmt.Sprintf("status code: %d, request id: %s", + r.statusCode, r.requestID) + return SprintError(r.Code(), r.Message(), extra, r.OrigErr()) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (r requestError) String() string { + return r.Error() +} + +// StatusCode returns the wrapped status code for the error +func (r requestError) StatusCode() int { + return r.statusCode +} + +// RequestID returns the wrapped requestID +func (r requestError) RequestID() string { + return r.requestID +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (r requestError) OrigErrs() []error { + if b, ok := r.awsError.(BatchedErrors); ok { + return b.OrigErrs() + } + return []error{r.OrigErr()} +} + +// An error list that satisfies the golang interface +type errorList []error + +// Error returns the string representation of the error. +// +// Satisfies the error interface. +func (e errorList) Error() string { + msg := "" + // How do we want to handle the array size being zero + if size := len(e); size > 0 { + for i := 0; i < size; i++ { + msg += fmt.Sprintf("%s", e[i].Error()) + // We check the next index to see if it is within the slice. + // If it is, then we append a newline. We do this, because unit tests + // could be broken with the additional '\n' + if i+1 < size { + msg += "\n" + } + } + } + return msg +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go new file mode 100644 index 0000000000..1a3d106d5c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go @@ -0,0 +1,108 @@ +package awsutil + +import ( + "io" + "reflect" + "time" +) + +// Copy deeply copies a src structure to dst. Useful for copying request and +// response structures. +// +// Can copy between structs of different type, but will only copy fields which +// are assignable, and exist in both structs. Fields which are not assignable, +// or do not exist in both structs are ignored. +func Copy(dst, src interface{}) { + dstval := reflect.ValueOf(dst) + if !dstval.IsValid() { + panic("Copy dst cannot be nil") + } + + rcopy(dstval, reflect.ValueOf(src), true) +} + +// CopyOf returns a copy of src while also allocating the memory for dst. +// src must be a pointer type or this operation will fail. +func CopyOf(src interface{}) (dst interface{}) { + dsti := reflect.New(reflect.TypeOf(src).Elem()) + dst = dsti.Interface() + rcopy(dsti, reflect.ValueOf(src), true) + return +} + +// rcopy performs a recursive copy of values from the source to destination. +// +// root is used to skip certain aspects of the copy which are not valid +// for the root node of a object. +func rcopy(dst, src reflect.Value, root bool) { + if !src.IsValid() { + return + } + + switch src.Kind() { + case reflect.Ptr: + if _, ok := src.Interface().(io.Reader); ok { + if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { + dst.Elem().Set(src) + } else if dst.CanSet() { + dst.Set(src) + } + } else { + e := src.Type().Elem() + if dst.CanSet() && !src.IsNil() { + if _, ok := src.Interface().(*time.Time); !ok { + dst.Set(reflect.New(e)) + } else { + tempValue := reflect.New(e) + tempValue.Elem().Set(src.Elem()) + // Sets time.Time's unexported values + dst.Set(tempValue) + } + } + if src.Elem().IsValid() { + // Keep the current root state since the depth hasn't changed + rcopy(dst.Elem(), src.Elem(), root) + } + } + case reflect.Struct: + t := dst.Type() + for i := 0; i < t.NumField(); i++ { + name := t.Field(i).Name + srcVal := src.FieldByName(name) + dstVal := dst.FieldByName(name) + if srcVal.IsValid() && dstVal.CanSet() { + rcopy(dstVal, srcVal, false) + } + } + case reflect.Slice: + if src.IsNil() { + break + } + + s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) + dst.Set(s) + for i := 0; i < src.Len(); i++ { + rcopy(dst.Index(i), src.Index(i), false) + } + case reflect.Map: + if src.IsNil() { + break + } + + s := reflect.MakeMap(src.Type()) + dst.Set(s) + for _, k := range src.MapKeys() { + v := src.MapIndex(k) + v2 := reflect.New(v.Type()).Elem() + rcopy(v2, v, false) + dst.SetMapIndex(k, v2) + } + default: + // Assign the value if possible. If its not assignable, the value would + // need to be converted and the impact of that may be unexpected, or is + // not compatible with the dst type. + if src.Type().AssignableTo(dst.Type()) { + dst.Set(src) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go new file mode 100644 index 0000000000..59fa4a558a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go @@ -0,0 +1,27 @@ +package awsutil + +import ( + "reflect" +) + +// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual. +// In addition to this, this method will also dereference the input values if +// possible so the DeepEqual performed will not fail if one parameter is a +// pointer and the other is not. +// +// DeepEqual will not perform indirection of nested values of the input parameters. +func DeepEqual(a, b interface{}) bool { + ra := reflect.Indirect(reflect.ValueOf(a)) + rb := reflect.Indirect(reflect.ValueOf(b)) + + if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid { + // If the elements are both nil, and of the same type the are equal + // If they are of different types they are not equal + return reflect.TypeOf(a) == reflect.TypeOf(b) + } else if raValid != rbValid { + // Both values must be valid to be equal + return false + } + + return reflect.DeepEqual(ra.Interface(), rb.Interface()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go new file mode 100644 index 0000000000..11c52c3896 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go @@ -0,0 +1,222 @@ +package awsutil + +import ( + "reflect" + "regexp" + "strconv" + "strings" + + "github.com/jmespath/go-jmespath" +) + +var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`) + +// rValuesAtPath returns a slice of values found in value v. The values +// in v are explored recursively so all nested values are collected. +func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value { + pathparts := strings.Split(path, "||") + if len(pathparts) > 1 { + for _, pathpart := range pathparts { + vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm) + if len(vals) > 0 { + return vals + } + } + return nil + } + + values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))} + components := strings.Split(path, ".") + for len(values) > 0 && len(components) > 0 { + var index *int64 + var indexStar bool + c := strings.TrimSpace(components[0]) + if c == "" { // no actual component, illegal syntax + return nil + } else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] { + // TODO normalize case for user + return nil // don't support unexported fields + } + + // parse this component + if m := indexRe.FindStringSubmatch(c); m != nil { + c = m[1] + if m[2] == "" { + index = nil + indexStar = true + } else { + i, _ := strconv.ParseInt(m[2], 10, 32) + index = &i + indexStar = false + } + } + + nextvals := []reflect.Value{} + for _, value := range values { + // pull component name out of struct member + if value.Kind() != reflect.Struct { + continue + } + + if c == "*" { // pull all members + for i := 0; i < value.NumField(); i++ { + if f := reflect.Indirect(value.Field(i)); f.IsValid() { + nextvals = append(nextvals, f) + } + } + continue + } + + value = value.FieldByNameFunc(func(name string) bool { + if c == name { + return true + } else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) { + return true + } + return false + }) + + if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 { + if !value.IsNil() { + value.Set(reflect.Zero(value.Type())) + } + return []reflect.Value{value} + } + + if createPath && value.Kind() == reflect.Ptr && value.IsNil() { + // TODO if the value is the terminus it should not be created + // if the value to be set to its position is nil. + value.Set(reflect.New(value.Type().Elem())) + value = value.Elem() + } else { + value = reflect.Indirect(value) + } + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + + if indexStar || index != nil { + nextvals = []reflect.Value{} + for _, valItem := range values { + value := reflect.Indirect(valItem) + if value.Kind() != reflect.Slice { + continue + } + + if indexStar { // grab all indices + for i := 0; i < value.Len(); i++ { + idx := reflect.Indirect(value.Index(i)) + if idx.IsValid() { + nextvals = append(nextvals, idx) + } + } + continue + } + + // pull out index + i := int(*index) + if i >= value.Len() { // check out of bounds + if createPath { + // TODO resize slice + } else { + continue + } + } else if i < 0 { // support negative indexing + i = value.Len() + i + } + value = reflect.Indirect(value.Index(i)) + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + } + + components = components[1:] + } + return values +} + +// ValuesAtPath returns a list of values at the case insensitive lexical +// path inside of a structure. +func ValuesAtPath(i interface{}, path string) ([]interface{}, error) { + result, err := jmespath.Search(path, i) + if err != nil { + return nil, err + } + + v := reflect.ValueOf(result) + if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) { + return nil, nil + } + if s, ok := result.([]interface{}); ok { + return s, err + } + if v.Kind() == reflect.Map && v.Len() == 0 { + return nil, nil + } + if v.Kind() == reflect.Slice { + out := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + out[i] = v.Index(i).Interface() + } + return out, nil + } + + return []interface{}{result}, nil +} + +// SetValueAtPath sets a value at the case insensitive lexical path inside +// of a structure. +func SetValueAtPath(i interface{}, path string, v interface{}) { + if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil { + for _, rval := range rvals { + if rval.Kind() == reflect.Ptr && rval.IsNil() { + continue + } + setValue(rval, v) + } + } +} + +func setValue(dstVal reflect.Value, src interface{}) { + if dstVal.Kind() == reflect.Ptr { + dstVal = reflect.Indirect(dstVal) + } + srcVal := reflect.ValueOf(src) + + if !srcVal.IsValid() { // src is literal nil + if dstVal.CanAddr() { + // Convert to pointer so that pointer's value can be nil'ed + // dstVal = dstVal.Addr() + } + dstVal.Set(reflect.Zero(dstVal.Type())) + + } else if srcVal.Kind() == reflect.Ptr { + if srcVal.IsNil() { + srcVal = reflect.Zero(dstVal.Type()) + } else { + srcVal = reflect.ValueOf(src).Elem() + } + dstVal.Set(srcVal) + } else { + dstVal.Set(srcVal) + } + +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go new file mode 100644 index 0000000000..fc38172fec --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go @@ -0,0 +1,107 @@ +package awsutil + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strings" +) + +// Prettify returns the string representation of a value. +func Prettify(i interface{}) string { + var buf bytes.Buffer + prettify(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +// prettify will recursively walk value v to build a textual +// representation of the value. +func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + strtype := v.Type().String() + if strtype == "time.Time" { + fmt.Fprintf(buf, "%s", v.Interface()) + break + } else if strings.HasPrefix(strtype, "io.") { + buf.WriteString("") + break + } + + buf.WriteString("{\n") + + names := []string{} + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + f := v.Field(i) + if name[0:1] == strings.ToLower(name[0:1]) { + continue // ignore unexported fields + } + if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() { + continue // ignore unset fields + } + names = append(names, name) + } + + for i, n := range names { + val := v.FieldByName(n) + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(n + ": ") + prettify(val, indent+2, buf) + + if i < len(names)-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + prettify(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + prettify(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + if !v.IsValid() { + fmt.Fprint(buf, "") + return + } + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + case io.ReadSeeker, io.Reader: + format = "buffer(%p)" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go new file mode 100644 index 0000000000..b6432f1a11 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go @@ -0,0 +1,89 @@ +package awsutil + +import ( + "bytes" + "fmt" + "reflect" + "strings" +) + +// StringValue returns the string representation of a value. +func StringValue(i interface{}) string { + var buf bytes.Buffer + stringValue(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + buf.WriteString("{\n") + + names := []string{} + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + f := v.Field(i) + if name[0:1] == strings.ToLower(name[0:1]) { + continue // ignore unexported fields + } + if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() { + continue // ignore unset fields + } + names = append(names, name) + } + + for i, n := range names { + val := v.FieldByName(n) + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(n + ": ") + stringValue(val, indent+2, buf) + + if i < len(names)-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + stringValue(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + stringValue(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go new file mode 100644 index 0000000000..4003c04b01 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go @@ -0,0 +1,139 @@ +package client + +import ( + "fmt" + "io/ioutil" + "net/http/httputil" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// A Config provides configuration to a service client instance. +type Config struct { + Config *aws.Config + Handlers request.Handlers + Endpoint, SigningRegion string +} + +// ConfigProvider provides a generic way for a service client to receive +// the ClientConfig without circular dependencies. +type ConfigProvider interface { + ClientConfig(serviceName string, cfgs ...*aws.Config) Config +} + +// A Client implements the base client request and response handling +// used by all service clients. +type Client struct { + request.Retryer + metadata.ClientInfo + + Config aws.Config + Handlers request.Handlers +} + +// New will return a pointer to a new initialized service client. +func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client { + svc := &Client{ + Config: cfg, + ClientInfo: info, + Handlers: handlers, + } + + switch retryer, ok := cfg.Retryer.(request.Retryer); { + case ok: + svc.Retryer = retryer + case cfg.Retryer != nil && cfg.Logger != nil: + s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer) + cfg.Logger.Log(s) + fallthrough + default: + maxRetries := aws.IntValue(cfg.MaxRetries) + if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries { + maxRetries = 3 + } + svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries} + } + + svc.AddDebugHandlers() + + for _, option := range options { + option(svc) + } + + return svc +} + +// NewRequest returns a new Request pointer for the service API +// operation and parameters. +func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { + return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data) +} + +// AddDebugHandlers injects debug logging handlers into the service to log request +// debug information. +func (c *Client) AddDebugHandlers() { + if !c.Config.LogLevel.AtLeast(aws.LogDebug) { + return + } + + c.Handlers.Send.PushFront(logRequest) + c.Handlers.Send.PushBack(logResponse) +} + +const logReqMsg = `DEBUG: Request %s/%s Details: +---[ REQUEST POST-SIGN ]----------------------------- +%s +-----------------------------------------------------` + +const logReqErrMsg = `DEBUG ERROR: Request %s/%s: +---[ REQUEST DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + +func logRequest(r *request.Request) { + logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + if logBody { + // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's + // Body as a NoOpCloser and will not be reset after read by the HTTP + // client reader. + r.Body.Seek(r.BodyStart, 0) + r.HTTPRequest.Body = ioutil.NopCloser(r.Body) + } + + r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody))) +} + +const logRespMsg = `DEBUG: Response %s/%s Details: +---[ RESPONSE ]-------------------------------------- +%s +-----------------------------------------------------` + +const logRespErrMsg = `DEBUG ERROR: Response %s/%s: +---[ RESPONSE DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + +func logResponse(r *request.Request) { + var msg = "no response data" + if r.HTTPResponse != nil { + logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + msg = string(dumpedBody) + } else if r.Error != nil { + msg = r.Error.Error() + } + r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg)) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go new file mode 100644 index 0000000000..43a3676b79 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go @@ -0,0 +1,90 @@ +package client + +import ( + "math/rand" + "sync" + "time" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// DefaultRetryer implements basic retry logic using exponential backoff for +// most services. If you want to implement custom retry logic, implement the +// request.Retryer interface or create a structure type that composes this +// struct and override the specific methods. For example, to override only +// the MaxRetries method: +// +// type retryer struct { +// service.DefaultRetryer +// } +// +// // This implementation always has 100 max retries +// func (d retryer) MaxRetries() uint { return 100 } +type DefaultRetryer struct { + NumMaxRetries int +} + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API request. +func (d DefaultRetryer) MaxRetries() int { + return d.NumMaxRetries +} + +var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) + +// RetryRules returns the delay duration before retrying this request again +func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { + // Set the upper limit of delay in retrying at ~five minutes + minTime := 30 + throttle := d.shouldThrottle(r) + if throttle { + minTime = 500 + } + + retryCount := r.RetryCount + if retryCount > 13 { + retryCount = 13 + } else if throttle && retryCount > 8 { + retryCount = 8 + } + + delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime) + return time.Duration(delay) * time.Millisecond +} + +// ShouldRetry returns true if the request should be retried. +func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { + if r.HTTPResponse.StatusCode >= 500 { + return true + } + return r.IsErrorRetryable() || d.shouldThrottle(r) +} + +// ShouldThrottle returns true if the request should be throttled. +func (d DefaultRetryer) shouldThrottle(r *request.Request) bool { + if r.HTTPResponse.StatusCode == 502 || + r.HTTPResponse.StatusCode == 503 || + r.HTTPResponse.StatusCode == 504 { + return true + } + return r.IsErrorThrottle() +} + +// lockedSource is a thread-safe implementation of rand.Source +type lockedSource struct { + lk sync.Mutex + src rand.Source +} + +func (r *lockedSource) Int63() (n int64) { + r.lk.Lock() + n = r.src.Int63() + r.lk.Unlock() + return +} + +func (r *lockedSource) Seed(seed int64) { + r.lk.Lock() + r.src.Seed(seed) + r.lk.Unlock() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go new file mode 100644 index 0000000000..4778056ddf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go @@ -0,0 +1,12 @@ +package metadata + +// ClientInfo wraps immutable data from the client.Client structure. +type ClientInfo struct { + ServiceName string + APIVersion string + Endpoint string + SigningName string + SigningRegion string + JSONVersion string + TargetPrefix string +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go new file mode 100644 index 0000000000..fca922584f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -0,0 +1,422 @@ +package aws + +import ( + "net/http" + "time" + + "github.com/aws/aws-sdk-go/aws/credentials" +) + +// UseServiceDefaultRetries instructs the config to use the service's own +// default number of retries. This will be the default action if +// Config.MaxRetries is nil also. +const UseServiceDefaultRetries = -1 + +// RequestRetryer is an alias for a type that implements the request.Retryer +// interface. +type RequestRetryer interface{} + +// A Config provides service configuration for service clients. By default, +// all clients will use the defaults.DefaultConfig tructure. +// +// // Create Session with MaxRetry configuration to be shared by multiple +// // service clients. +// sess, err := session.NewSession(&aws.Config{ +// MaxRetries: aws.Int(3), +// }) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, &aws.Config{ +// Region: aws.String("us-west-2"), +// }) +type Config struct { + // Enables verbose error printing of all credential chain errors. + // Should be used when wanting to see all errors while attempting to + // retrieve credentials. + CredentialsChainVerboseErrors *bool + + // The credentials object to use when signing requests. Defaults to a + // chain of credential providers to search for credentials in environment + // variables, shared credential file, and EC2 Instance Roles. + Credentials *credentials.Credentials + + // An optional endpoint URL (hostname only or fully qualified URI) + // that overrides the default generated endpoint for a client. Set this + // to `""` to use the default generated endpoint. + // + // @note You must still provide a `Region` value when specifying an + // endpoint for a client. + Endpoint *string + + // The region to send requests to. This parameter is required and must + // be configured globally or on a per-client basis unless otherwise + // noted. A full list of regions is found in the "Regions and Endpoints" + // document. + // + // @see http://docs.aws.amazon.com/general/latest/gr/rande.html + // AWS Regions and Endpoints + Region *string + + // Set this to `true` to disable SSL when sending requests. Defaults + // to `false`. + DisableSSL *bool + + // The HTTP client to use when sending requests. Defaults to + // `http.DefaultClient`. + HTTPClient *http.Client + + // An integer value representing the logging level. The default log level + // is zero (LogOff), which represents no logging. To enable logging set + // to a LogLevel Value. + LogLevel *LogLevelType + + // The logger writer interface to write logging messages to. Defaults to + // standard out. + Logger Logger + + // The maximum number of times that a request will be retried for failures. + // Defaults to -1, which defers the max retry setting to the service + // specific configuration. + MaxRetries *int + + // Retryer guides how HTTP requests should be retried in case of + // recoverable failures. + // + // When nil or the value does not implement the request.Retryer interface, + // the request.DefaultRetryer will be used. + // + // When both Retryer and MaxRetries are non-nil, the former is used and + // the latter ignored. + // + // To set the Retryer field in a type-safe manner and with chaining, use + // the request.WithRetryer helper function: + // + // cfg := request.WithRetryer(aws.NewConfig(), myRetryer) + // + Retryer RequestRetryer + + // Disables semantic parameter validation, which validates input for + // missing required fields and/or other semantic request input errors. + DisableParamValidation *bool + + // Disables the computation of request and response checksums, e.g., + // CRC32 checksums in Amazon DynamoDB. + DisableComputeChecksums *bool + + // Set this to `true` to force the request to use path-style addressing, + // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client + // will use virtual hosted bucket addressing when possible + // (`http://BUCKET.s3.amazonaws.com/KEY`). + // + // @note This configuration option is specific to the Amazon S3 service. + // @see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html + // Amazon S3: Virtual Hosting of Buckets + S3ForcePathStyle *bool + + // Set this to `true` to disable the SDK adding the `Expect: 100-Continue` + // header to PUT requests over 2MB of content. 100-Continue instructs the + // HTTP client not to send the body until the service responds with a + // `continue` status. This is useful to prevent sending the request body + // until after the request is authenticated, and validated. + // + // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html + // + // 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s + // `ExpectContinueTimeout` for information on adjusting the continue wait + // timeout. https://golang.org/pkg/net/http/#Transport + // + // You should use this flag to disble 100-Continue if you experience issues + // with proxies or third party S3 compatible services. + S3Disable100Continue *bool + + // Set this to `true` to enable S3 Accelerate feature. For all operations + // compatible with S3 Accelerate will use the accelerate endpoint for + // requests. Requests not compatible will fall back to normal S3 requests. + // + // The bucket must be enable for accelerate to be used with S3 client with + // accelerate enabled. If the bucket is not enabled for accelerate an error + // will be returned. The bucket name must be DNS compatible to also work + // with accelerate. + // + // Not compatible with UseDualStack requests will fail if both flags are + // specified. + S3UseAccelerate *bool + + // Set this to `true` to disable the EC2Metadata client from overriding the + // default http.Client's Timeout. This is helpful if you do not want the + // EC2Metadata client to create a new http.Client. This options is only + // meaningful if you're not already using a custom HTTP client with the + // SDK. Enabled by default. + // + // Must be set and provided to the session.NewSession() in order to disable + // the EC2Metadata overriding the timeout for default credentials chain. + // + // Example: + // sess, err := session.NewSession(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true)) + // + // svc := s3.New(sess) + // + EC2MetadataDisableTimeoutOverride *bool + + // Instructs the endpiont to be generated for a service client to + // be the dual stack endpoint. The dual stack endpoint will support + // both IPv4 and IPv6 addressing. + // + // Setting this for a service which does not support dual stack will fail + // to make requets. It is not recommended to set this value on the session + // as it will apply to all service clients created with the session. Even + // services which don't support dual stack endpoints. + // + // If the Endpoint config value is also provided the UseDualStack flag + // will be ignored. + // + // Only supported with. + // + // sess, err := session.NewSession() + // + // svc := s3.New(sess, &aws.Config{ + // UseDualStack: aws.Bool(true), + // }) + UseDualStack *bool + + // SleepDelay is an override for the func the SDK will call when sleeping + // during the lifecycle of a request. Specifically this will be used for + // request delays. This value should only be used for testing. To adjust + // the delay of a request see the aws/client.DefaultRetryer and + // aws/request.Retryer. + SleepDelay func(time.Duration) +} + +// NewConfig returns a new Config pointer that can be chained with builder +// methods to set multiple configuration values inline without using pointers. +// +// // Create Session with MaxRetry configuration to be shared by multiple +// // service clients. +// sess, err := session.NewSession(aws.NewConfig(). +// WithMaxRetries(3), +// ) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, aws.NewConfig(). +// WithRegion("us-west-2"), +// ) +func NewConfig() *Config { + return &Config{} +} + +// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning +// a Config pointer. +func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config { + c.CredentialsChainVerboseErrors = &verboseErrs + return c +} + +// WithCredentials sets a config Credentials value returning a Config pointer +// for chaining. +func (c *Config) WithCredentials(creds *credentials.Credentials) *Config { + c.Credentials = creds + return c +} + +// WithEndpoint sets a config Endpoint value returning a Config pointer for +// chaining. +func (c *Config) WithEndpoint(endpoint string) *Config { + c.Endpoint = &endpoint + return c +} + +// WithRegion sets a config Region value returning a Config pointer for +// chaining. +func (c *Config) WithRegion(region string) *Config { + c.Region = ®ion + return c +} + +// WithDisableSSL sets a config DisableSSL value returning a Config pointer +// for chaining. +func (c *Config) WithDisableSSL(disable bool) *Config { + c.DisableSSL = &disable + return c +} + +// WithHTTPClient sets a config HTTPClient value returning a Config pointer +// for chaining. +func (c *Config) WithHTTPClient(client *http.Client) *Config { + c.HTTPClient = client + return c +} + +// WithMaxRetries sets a config MaxRetries value returning a Config pointer +// for chaining. +func (c *Config) WithMaxRetries(max int) *Config { + c.MaxRetries = &max + return c +} + +// WithDisableParamValidation sets a config DisableParamValidation value +// returning a Config pointer for chaining. +func (c *Config) WithDisableParamValidation(disable bool) *Config { + c.DisableParamValidation = &disable + return c +} + +// WithDisableComputeChecksums sets a config DisableComputeChecksums value +// returning a Config pointer for chaining. +func (c *Config) WithDisableComputeChecksums(disable bool) *Config { + c.DisableComputeChecksums = &disable + return c +} + +// WithLogLevel sets a config LogLevel value returning a Config pointer for +// chaining. +func (c *Config) WithLogLevel(level LogLevelType) *Config { + c.LogLevel = &level + return c +} + +// WithLogger sets a config Logger value returning a Config pointer for +// chaining. +func (c *Config) WithLogger(logger Logger) *Config { + c.Logger = logger + return c +} + +// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config +// pointer for chaining. +func (c *Config) WithS3ForcePathStyle(force bool) *Config { + c.S3ForcePathStyle = &force + return c +} + +// WithS3Disable100Continue sets a config S3Disable100Continue value returning +// a Config pointer for chaining. +func (c *Config) WithS3Disable100Continue(disable bool) *Config { + c.S3Disable100Continue = &disable + return c +} + +// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config +// pointer for chaining. +func (c *Config) WithS3UseAccelerate(enable bool) *Config { + c.S3UseAccelerate = &enable + return c +} + +// WithUseDualStack sets a config UseDualStack value returning a Config +// pointer for chaining. +func (c *Config) WithUseDualStack(enable bool) *Config { + c.UseDualStack = &enable + return c +} + +// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value +// returning a Config pointer for chaining. +func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config { + c.EC2MetadataDisableTimeoutOverride = &enable + return c +} + +// WithSleepDelay overrides the function used to sleep while waiting for the +// next retry. Defaults to time.Sleep. +func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config { + c.SleepDelay = fn + return c +} + +// MergeIn merges the passed in configs into the existing config object. +func (c *Config) MergeIn(cfgs ...*Config) { + for _, other := range cfgs { + mergeInConfig(c, other) + } +} + +func mergeInConfig(dst *Config, other *Config) { + if other == nil { + return + } + + if other.CredentialsChainVerboseErrors != nil { + dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors + } + + if other.Credentials != nil { + dst.Credentials = other.Credentials + } + + if other.Endpoint != nil { + dst.Endpoint = other.Endpoint + } + + if other.Region != nil { + dst.Region = other.Region + } + + if other.DisableSSL != nil { + dst.DisableSSL = other.DisableSSL + } + + if other.HTTPClient != nil { + dst.HTTPClient = other.HTTPClient + } + + if other.LogLevel != nil { + dst.LogLevel = other.LogLevel + } + + if other.Logger != nil { + dst.Logger = other.Logger + } + + if other.MaxRetries != nil { + dst.MaxRetries = other.MaxRetries + } + + if other.Retryer != nil { + dst.Retryer = other.Retryer + } + + if other.DisableParamValidation != nil { + dst.DisableParamValidation = other.DisableParamValidation + } + + if other.DisableComputeChecksums != nil { + dst.DisableComputeChecksums = other.DisableComputeChecksums + } + + if other.S3ForcePathStyle != nil { + dst.S3ForcePathStyle = other.S3ForcePathStyle + } + + if other.S3Disable100Continue != nil { + dst.S3Disable100Continue = other.S3Disable100Continue + } + + if other.S3UseAccelerate != nil { + dst.S3UseAccelerate = other.S3UseAccelerate + } + + if other.UseDualStack != nil { + dst.UseDualStack = other.UseDualStack + } + + if other.EC2MetadataDisableTimeoutOverride != nil { + dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride + } + + if other.SleepDelay != nil { + dst.SleepDelay = other.SleepDelay + } +} + +// Copy will return a shallow copy of the Config object. If any additional +// configurations are provided they will be merged into the new config returned. +func (c *Config) Copy(cfgs ...*Config) *Config { + dst := &Config{} + dst.MergeIn(c) + + for _, cfg := range cfgs { + dst.MergeIn(cfg) + } + + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go new file mode 100644 index 0000000000..3b73a7da7f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go @@ -0,0 +1,369 @@ +package aws + +import "time" + +// String returns a pointer to the string value passed in. +func String(v string) *string { + return &v +} + +// StringValue returns the value of the string pointer passed in or +// "" if the pointer is nil. +func StringValue(v *string) string { + if v != nil { + return *v + } + return "" +} + +// StringSlice converts a slice of string values into a slice of +// string pointers +func StringSlice(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringValueSlice converts a slice of string pointers into a slice of +// string values +func StringValueSlice(src []*string) []string { + dst := make([]string, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// StringMap converts a string map of string values into a string +// map of string pointers +func StringMap(src map[string]string) map[string]*string { + dst := make(map[string]*string) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// StringValueMap converts a string map of string pointers into a string +// map of string values +func StringValueMap(src map[string]*string) map[string]string { + dst := make(map[string]string) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Bool returns a pointer to the bool value passed in. +func Bool(v bool) *bool { + return &v +} + +// BoolValue returns the value of the bool pointer passed in or +// false if the pointer is nil. +func BoolValue(v *bool) bool { + if v != nil { + return *v + } + return false +} + +// BoolSlice converts a slice of bool values into a slice of +// bool pointers +func BoolSlice(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolValueSlice converts a slice of bool pointers into a slice of +// bool values +func BoolValueSlice(src []*bool) []bool { + dst := make([]bool, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// BoolMap converts a string map of bool values into a string +// map of bool pointers +func BoolMap(src map[string]bool) map[string]*bool { + dst := make(map[string]*bool) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// BoolValueMap converts a string map of bool pointers into a string +// map of bool values +func BoolValueMap(src map[string]*bool) map[string]bool { + dst := make(map[string]bool) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int returns a pointer to the int value passed in. +func Int(v int) *int { + return &v +} + +// IntValue returns the value of the int pointer passed in or +// 0 if the pointer is nil. +func IntValue(v *int) int { + if v != nil { + return *v + } + return 0 +} + +// IntSlice converts a slice of int values into a slice of +// int pointers +func IntSlice(src []int) []*int { + dst := make([]*int, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// IntValueSlice converts a slice of int pointers into a slice of +// int values +func IntValueSlice(src []*int) []int { + dst := make([]int, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// IntMap converts a string map of int values into a string +// map of int pointers +func IntMap(src map[string]int) map[string]*int { + dst := make(map[string]*int) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// IntValueMap converts a string map of int pointers into a string +// map of int values +func IntValueMap(src map[string]*int) map[string]int { + dst := make(map[string]int) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int64 returns a pointer to the int64 value passed in. +func Int64(v int64) *int64 { + return &v +} + +// Int64Value returns the value of the int64 pointer passed in or +// 0 if the pointer is nil. +func Int64Value(v *int64) int64 { + if v != nil { + return *v + } + return 0 +} + +// Int64Slice converts a slice of int64 values into a slice of +// int64 pointers +func Int64Slice(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64ValueSlice converts a slice of int64 pointers into a slice of +// int64 values +func Int64ValueSlice(src []*int64) []int64 { + dst := make([]int64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int64Map converts a string map of int64 values into a string +// map of int64 pointers +func Int64Map(src map[string]int64) map[string]*int64 { + dst := make(map[string]*int64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int64ValueMap converts a string map of int64 pointers into a string +// map of int64 values +func Int64ValueMap(src map[string]*int64) map[string]int64 { + dst := make(map[string]int64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float64 returns a pointer to the float64 value passed in. +func Float64(v float64) *float64 { + return &v +} + +// Float64Value returns the value of the float64 pointer passed in or +// 0 if the pointer is nil. +func Float64Value(v *float64) float64 { + if v != nil { + return *v + } + return 0 +} + +// Float64Slice converts a slice of float64 values into a slice of +// float64 pointers +func Float64Slice(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64ValueSlice converts a slice of float64 pointers into a slice of +// float64 values +func Float64ValueSlice(src []*float64) []float64 { + dst := make([]float64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float64Map converts a string map of float64 values into a string +// map of float64 pointers +func Float64Map(src map[string]float64) map[string]*float64 { + dst := make(map[string]*float64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float64ValueMap converts a string map of float64 pointers into a string +// map of float64 values +func Float64ValueMap(src map[string]*float64) map[string]float64 { + dst := make(map[string]float64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Time returns a pointer to the time.Time value passed in. +func Time(v time.Time) *time.Time { + return &v +} + +// TimeValue returns the value of the time.Time pointer passed in or +// time.Time{} if the pointer is nil. +func TimeValue(v *time.Time) time.Time { + if v != nil { + return *v + } + return time.Time{} +} + +// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC". +// The result is undefined if the Unix time cannot be represented by an int64. +// Which includes calling TimeUnixMilli on a zero Time is undefined. +// +// This utility is useful for service API's such as CloudWatch Logs which require +// their unix time values to be in milliseconds. +// +// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information. +func TimeUnixMilli(t time.Time) int64 { + return t.UnixNano() / int64(time.Millisecond/time.Nanosecond) +} + +// TimeSlice converts a slice of time.Time values into a slice of +// time.Time pointers +func TimeSlice(src []time.Time) []*time.Time { + dst := make([]*time.Time, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// TimeValueSlice converts a slice of time.Time pointers into a slice of +// time.Time values +func TimeValueSlice(src []*time.Time) []time.Time { + dst := make([]time.Time, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// TimeMap converts a string map of time.Time values into a string +// map of time.Time pointers +func TimeMap(src map[string]time.Time) map[string]*time.Time { + dst := make(map[string]*time.Time) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// TimeValueMap converts a string map of time.Time pointers into a string +// map of time.Time values +func TimeValueMap(src map[string]*time.Time) map[string]time.Time { + dst := make(map[string]time.Time) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go new file mode 100644 index 0000000000..8456e29b56 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go @@ -0,0 +1,152 @@ +package corehandlers + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "regexp" + "runtime" + "strconv" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// Interface for matching types which also have a Len method. +type lener interface { + Len() int +} + +// BuildContentLengthHandler builds the content length of a request based on the body, +// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable +// to determine request body length and no "Content-Length" was specified it will panic. +// +// The Content-Length will only be aded to the request if the length of the body +// is greater than 0. If the body is empty or the current `Content-Length` +// header is <= 0, the header will also be stripped. +var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) { + var length int64 + + if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" { + length, _ = strconv.ParseInt(slength, 10, 64) + } else { + switch body := r.Body.(type) { + case nil: + length = 0 + case lener: + length = int64(body.Len()) + case io.Seeker: + r.BodyStart, _ = body.Seek(0, 1) + end, _ := body.Seek(0, 2) + body.Seek(r.BodyStart, 0) // make sure to seek back to original location + length = end - r.BodyStart + default: + panic("Cannot get length of body, must provide `ContentLength`") + } + } + + if length > 0 { + r.HTTPRequest.ContentLength = length + r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length)) + } else { + r.HTTPRequest.ContentLength = 0 + r.HTTPRequest.Header.Del("Content-Length") + } +}} + +// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent. +var SDKVersionUserAgentHandler = request.NamedHandler{ + Name: "core.SDKVersionUserAgentHandler", + Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion, + runtime.Version(), runtime.GOOS, runtime.GOARCH), +} + +var reStatusCode = regexp.MustCompile(`^(\d{3})`) + +// SendHandler is a request handler to send service request using HTTP client. +var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) { + var err error + r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest) + if err != nil { + // Prevent leaking if an HTTPResponse was returned. Clean up + // the body. + if r.HTTPResponse != nil { + r.HTTPResponse.Body.Close() + } + // Capture the case where url.Error is returned for error processing + // response. e.g. 301 without location header comes back as string + // error and r.HTTPResponse is nil. Other url redirect errors will + // comeback in a similar method. + if e, ok := err.(*url.Error); ok && e.Err != nil { + if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { + code, _ := strconv.ParseInt(s[1], 10, 64) + r.HTTPResponse = &http.Response{ + StatusCode: int(code), + Status: http.StatusText(int(code)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + return + } + } + if r.HTTPResponse == nil { + // Add a dummy request response object to ensure the HTTPResponse + // value is consistent. + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + } + // Catch all other request errors. + r.Error = awserr.New("RequestError", "send request failed", err) + r.Retryable = aws.Bool(true) // network errors are retryable + } +}} + +// ValidateResponseHandler is a request handler to validate service response. +var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) { + if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 { + // this may be replaced by an UnmarshalError handler + r.Error = awserr.New("UnknownError", "unknown error", nil) + } +}} + +// AfterRetryHandler performs final checks to determine if the request should +// be retried and how long to delay. +var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable == nil { + r.Retryable = aws.Bool(r.ShouldRetry(r)) + } + + if r.WillRetry() { + r.RetryDelay = r.RetryRules(r) + r.Config.SleepDelay(r.RetryDelay) + + // when the expired token exception occurs the credentials + // need to be expired locally so that the next request to + // get credentials will trigger a credentials refresh. + if r.IsErrorExpired() { + r.Config.Credentials.Expire() + } + + r.RetryCount++ + r.Error = nil + } +}} + +// ValidateEndpointHandler is a request handler to validate a request had the +// appropriate Region and Endpoint set. Will set r.Error if the endpoint or +// region is not valid. +var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) { + if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" { + r.Error = aws.ErrMissingRegion + } else if r.ClientInfo.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +}} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go new file mode 100644 index 0000000000..7d50b1557c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go @@ -0,0 +1,17 @@ +package corehandlers + +import "github.com/aws/aws-sdk-go/aws/request" + +// ValidateParametersHandler is a request handler to validate the input parameters. +// Validating parameters only has meaning if done prior to the request being sent. +var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) { + if !r.ParamsFilled() { + return + } + + if v, ok := r.Params.(request.Validator); ok { + if err := v.Validate(); err != nil { + r.Error = err + } + } +}} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go new file mode 100644 index 0000000000..857311f64c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go @@ -0,0 +1,100 @@ +package credentials + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" +) + +var ( + // ErrNoValidProvidersFoundInChain Is returned when there are no valid + // providers in the ChainProvider. + // + // This has been deprecated. For verbose error messaging set + // aws.Config.CredentialsChainVerboseErrors to true + // + // @readonly + ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", + `no valid providers in chain. Deprecated. + For verbose messaging see aws.Config.CredentialsChainVerboseErrors`, + nil) +) + +// A ChainProvider will search for a provider which returns credentials +// and cache that provider until Retrieve is called again. +// +// The ChainProvider provides a way of chaining multiple providers together +// which will pick the first available using priority order of the Providers +// in the list. +// +// If none of the Providers retrieve valid credentials Value, ChainProvider's +// Retrieve() will return the error ErrNoValidProvidersFoundInChain. +// +// If a Provider is found which returns valid credentials Value ChainProvider +// will cache that Provider for all calls to IsExpired(), until Retrieve is +// called again. +// +// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. +// In this example EnvProvider will first check if any credentials are available +// vai the environment variables. If there are none ChainProvider will check +// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider +// does not return any credentials ChainProvider will return the error +// ErrNoValidProvidersFoundInChain +// +// creds := NewChainCredentials( +// []Provider{ +// &EnvProvider{}, +// &EC2RoleProvider{ +// Client: ec2metadata.New(sess), +// }, +// }) +// +// // Usage of ChainCredentials with aws.Config +// svc := ec2.New(&aws.Config{Credentials: creds}) +// +type ChainProvider struct { + Providers []Provider + curr Provider + VerboseErrors bool +} + +// NewChainCredentials returns a pointer to a new Credentials object +// wrapping a chain of providers. +func NewChainCredentials(providers []Provider) *Credentials { + return NewCredentials(&ChainProvider{ + Providers: append([]Provider{}, providers...), + }) +} + +// Retrieve returns the credentials value or error if no provider returned +// without error. +// +// If a provider is found it will be cached and any calls to IsExpired() +// will return the expired state of the cached provider. +func (c *ChainProvider) Retrieve() (Value, error) { + var errs []error + for _, p := range c.Providers { + creds, err := p.Retrieve() + if err == nil { + c.curr = p + return creds, nil + } + errs = append(errs, err) + } + c.curr = nil + + var err error + err = ErrNoValidProvidersFoundInChain + if c.VerboseErrors { + err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs) + } + return Value{}, err +} + +// IsExpired will returned the expired state of the currently cached provider +// if there is one. If there is no current provider, true will be returned. +func (c *ChainProvider) IsExpired() bool { + if c.curr != nil { + return c.curr.IsExpired() + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go new file mode 100644 index 0000000000..7b8ebf5f9d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go @@ -0,0 +1,223 @@ +// Package credentials provides credential retrieval and management +// +// The Credentials is the primary method of getting access to and managing +// credentials Values. Using dependency injection retrieval of the credential +// values is handled by a object which satisfies the Provider interface. +// +// By default the Credentials.Get() will cache the successful result of a +// Provider's Retrieve() until Provider.IsExpired() returns true. At which +// point Credentials will call Provider's Retrieve() to get new credential Value. +// +// The Provider is responsible for determining when credentials Value have expired. +// It is also important to note that Credentials will always call Retrieve the +// first time Credentials.Get() is called. +// +// Example of using the environment variable credentials. +// +// creds := NewEnvCredentials() +// +// // Retrieve the credentials value +// credValue, err := creds.Get() +// if err != nil { +// // handle error +// } +// +// Example of forcing credentials to expire and be refreshed on the next Get(). +// This may be helpful to proactively expire credentials and refresh them sooner +// than they would naturally expire on their own. +// +// creds := NewCredentials(&EC2RoleProvider{}) +// creds.Expire() +// credsValue, err := creds.Get() +// // New credentials will be retrieved instead of from cache. +// +// +// Custom Provider +// +// Each Provider built into this package also provides a helper method to generate +// a Credentials pointer setup with the provider. To use a custom Provider just +// create a type which satisfies the Provider interface and pass it to the +// NewCredentials method. +// +// type MyProvider struct{} +// func (m *MyProvider) Retrieve() (Value, error) {...} +// func (m *MyProvider) IsExpired() bool {...} +// +// creds := NewCredentials(&MyProvider{}) +// credValue, err := creds.Get() +// +package credentials + +import ( + "sync" + "time" +) + +// AnonymousCredentials is an empty Credential object that can be used as +// dummy placeholder credentials for requests that do not need signed. +// +// This Credentials can be used to configure a service to not sign requests +// when making service API calls. For example, when accessing public +// s3 buckets. +// +// svc := s3.New(&aws.Config{Credentials: AnonymousCredentials}) +// // Access public S3 buckets. +// +// @readonly +var AnonymousCredentials = NewStaticCredentials("", "", "") + +// A Value is the AWS credentials value for individual credential fields. +type Value struct { + // AWS Access key ID + AccessKeyID string + + // AWS Secret Access Key + SecretAccessKey string + + // AWS Session Token + SessionToken string + + // Provider used to get credentials + ProviderName string +} + +// A Provider is the interface for any component which will provide credentials +// Value. A provider is required to manage its own Expired state, and what to +// be expired means. +// +// The Provider should not need to implement its own mutexes, because +// that will be managed by Credentials. +type Provider interface { + // Refresh returns nil if it successfully retrieved the value. + // Error is returned if the value were not obtainable, or empty. + Retrieve() (Value, error) + + // IsExpired returns if the credentials are no longer valid, and need + // to be retrieved. + IsExpired() bool +} + +// A Expiry provides shared expiration logic to be used by credentials +// providers to implement expiry functionality. +// +// The best method to use this struct is as an anonymous field within the +// provider's struct. +// +// Example: +// type EC2RoleProvider struct { +// Expiry +// ... +// } +type Expiry struct { + // The date/time when to expire on + expiration time.Time + + // If set will be used by IsExpired to determine the current time. + // Defaults to time.Now if CurrentTime is not set. Available for testing + // to be able to mock out the current time. + CurrentTime func() time.Time +} + +// SetExpiration sets the expiration IsExpired will check when called. +// +// If window is greater than 0 the expiration time will be reduced by the +// window value. +// +// Using a window is helpful to trigger credentials to expire sooner than +// the expiration time given to ensure no requests are made with expired +// tokens. +func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) { + e.expiration = expiration + if window > 0 { + e.expiration = e.expiration.Add(-window) + } +} + +// IsExpired returns if the credentials are expired. +func (e *Expiry) IsExpired() bool { + if e.CurrentTime == nil { + e.CurrentTime = time.Now + } + return e.expiration.Before(e.CurrentTime()) +} + +// A Credentials provides synchronous safe retrieval of AWS credentials Value. +// Credentials will cache the credentials value until they expire. Once the value +// expires the next Get will attempt to retrieve valid credentials. +// +// Credentials is safe to use across multiple goroutines and will manage the +// synchronous state so the Providers do not need to implement their own +// synchronization. +// +// The first Credentials.Get() will always call Provider.Retrieve() to get the +// first instance of the credentials Value. All calls to Get() after that +// will return the cached credentials Value until IsExpired() returns true. +type Credentials struct { + creds Value + forceRefresh bool + m sync.Mutex + + provider Provider +} + +// NewCredentials returns a pointer to a new Credentials with the provider set. +func NewCredentials(provider Provider) *Credentials { + return &Credentials{ + provider: provider, + forceRefresh: true, + } +} + +// Get returns the credentials value, or error if the credentials Value failed +// to be retrieved. +// +// Will return the cached credentials Value if it has not expired. If the +// credentials Value has expired the Provider's Retrieve() will be called +// to refresh the credentials. +// +// If Credentials.Expire() was called the credentials Value will be force +// expired, and the next call to Get() will cause them to be refreshed. +func (c *Credentials) Get() (Value, error) { + c.m.Lock() + defer c.m.Unlock() + + if c.isExpired() { + creds, err := c.provider.Retrieve() + if err != nil { + return Value{}, err + } + c.creds = creds + c.forceRefresh = false + } + + return c.creds, nil +} + +// Expire expires the credentials and forces them to be retrieved on the +// next call to Get(). +// +// This will override the Provider's expired state, and force Credentials +// to call the Provider's Retrieve(). +func (c *Credentials) Expire() { + c.m.Lock() + defer c.m.Unlock() + + c.forceRefresh = true +} + +// IsExpired returns if the credentials are no longer valid, and need +// to be retrieved. +// +// If the Credentials were forced to be expired with Expire() this will +// reflect that override. +func (c *Credentials) IsExpired() bool { + c.m.Lock() + defer c.m.Unlock() + + return c.isExpired() +} + +// isExpired helper method wrapping the definition of expired credentials. +func (c *Credentials) isExpired() bool { + return c.forceRefresh || c.provider.IsExpired() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go new file mode 100644 index 0000000000..aa9d689a01 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go @@ -0,0 +1,178 @@ +package ec2rolecreds + +import ( + "bufio" + "encoding/json" + "fmt" + "path" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/ec2metadata" +) + +// ProviderName provides a name of EC2Role provider +const ProviderName = "EC2RoleProvider" + +// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if +// those credentials are expired. +// +// Example how to configure the EC2RoleProvider with custom http Client, Endpoint +// or ExpiryWindow +// +// p := &ec2rolecreds.EC2RoleProvider{ +// // Pass in a custom timeout to be used when requesting +// // IAM EC2 Role credentials. +// Client: ec2metadata.New(sess, aws.Config{ +// HTTPClient: &http.Client{Timeout: 10 * time.Second}, +// }), +// +// // Do not use early expiry of credentials. If a non zero value is +// // specified the credentials will be expired early +// ExpiryWindow: 0, +// } +type EC2RoleProvider struct { + credentials.Expiry + + // Required EC2Metadata client to use when connecting to EC2 metadata service. + Client *ec2metadata.EC2Metadata + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping +// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client. +// The ConfigProvider is satisfied by the session.Session type. +func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials { + p := &EC2RoleProvider{ + Client: ec2metadata.New(c), + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping +// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2 +// metadata service. +func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials { + p := &EC2RoleProvider{ + Client: client, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve retrieves credentials from the EC2 service. +// Error will be returned if the request fails, or unable to extract +// the desired credentials. +func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) { + credsList, err := requestCredList(m.Client) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + if len(credsList) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) + } + credsName := credsList[0] + + roleCreds, err := requestCred(m.Client, credsName) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: roleCreds.AccessKeyID, + SecretAccessKey: roleCreds.SecretAccessKey, + SessionToken: roleCreds.Token, + ProviderName: ProviderName, + }, nil +} + +// A ec2RoleCredRespBody provides the shape for unmarshalling credential +// request responses. +type ec2RoleCredRespBody struct { + // Success State + Expiration time.Time + AccessKeyID string + SecretAccessKey string + Token string + + // Error state + Code string + Message string +} + +const iamSecurityCredsPath = "/iam/security-credentials" + +// requestCredList requests a list of credentials from the EC2 service. +// If there are no credentials, or there is an error making or receiving the request +func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) { + resp, err := client.GetMetadata(iamSecurityCredsPath) + if err != nil { + return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err) + } + + credsList := []string{} + s := bufio.NewScanner(strings.NewReader(resp)) + for s.Scan() { + credsList = append(credsList, s.Text()) + } + + if err := s.Err(); err != nil { + return nil, awserr.New("SerializationError", "failed to read EC2 instance role from metadata service", err) + } + + return credsList, nil +} + +// requestCred requests the credentials for a specific credentials from the EC2 service. +// +// If the credentials cannot be found, or there is an error reading the response +// and error will be returned. +func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) { + resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName)) + if err != nil { + return ec2RoleCredRespBody{}, + awserr.New("EC2RoleRequestError", + fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName), + err) + } + + respCreds := ec2RoleCredRespBody{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { + return ec2RoleCredRespBody{}, + awserr.New("SerializationError", + fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName), + err) + } + + if respCreds.Code != "Success" { + // If an error code was returned something failed requesting the role. + return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil) + } + + return respCreds, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go new file mode 100644 index 0000000000..a4cec5c553 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go @@ -0,0 +1,191 @@ +// Package endpointcreds provides support for retrieving credentials from an +// arbitrary HTTP endpoint. +// +// The credentials endpoint Provider can receive both static and refreshable +// credentials that will expire. Credentials are static when an "Expiration" +// value is not provided in the endpoint's response. +// +// Static credentials will never expire once they have been retrieved. The format +// of the static credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// } +// +// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration +// value in the response. The format of the refreshable credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// "Token" : "AQoDY....=", +// "Expiration" : "2016-02-25T06:03:31Z" +// } +// +// Errors should be returned in the following format and only returned with 400 +// or 500 HTTP status codes. +// { +// "code": "ErrorCode", +// "message": "Helpful error message." +// } +package endpointcreds + +import ( + "encoding/json" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" +) + +// ProviderName is the name of the credentials provider. +const ProviderName = `CredentialsEndpointProvider` + +// Provider satisfies the credentials.Provider interface, and is a client to +// retrieve credentials from an arbitrary endpoint. +type Provider struct { + staticCreds bool + credentials.Expiry + + // Requires a AWS Client to make HTTP requests to the endpoint with. + // the Endpoint the request will be made to is provided by the aws.Config's + // Endpoint value. + Client *client.Client + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewProviderClient returns a credentials Provider for retrieving AWS credentials +// from arbitrary endpoint. +func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider { + p := &Provider{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: "CredentialsEndpoint", + Endpoint: endpoint, + }, + handlers, + ), + } + + p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler) + p.Client.Handlers.UnmarshalError.PushBack(unmarshalError) + p.Client.Handlers.Validate.Clear() + p.Client.Handlers.Validate.PushBack(validateEndpointHandler) + + for _, option := range options { + option(p) + } + + return p +} + +// NewCredentialsClient returns a Credentials wrapper for retrieving credentials +// from an arbitrary endpoint concurrently. The client will request the +func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials { + return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...)) +} + +// IsExpired returns true if the credentials retrieved are expired, or not yet +// retrieved. +func (p *Provider) IsExpired() bool { + if p.staticCreds { + return false + } + return p.Expiry.IsExpired() +} + +// Retrieve will attempt to request the credentials from the endpoint the Provider +// was configured for. And error will be returned if the retrieval fails. +func (p *Provider) Retrieve() (credentials.Value, error) { + resp, err := p.getCredentials() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, + awserr.New("CredentialsEndpointError", "failed to load credentials", err) + } + + if resp.Expiration != nil { + p.SetExpiration(*resp.Expiration, p.ExpiryWindow) + } else { + p.staticCreds = true + } + + return credentials.Value{ + AccessKeyID: resp.AccessKeyID, + SecretAccessKey: resp.SecretAccessKey, + SessionToken: resp.Token, + ProviderName: ProviderName, + }, nil +} + +type getCredentialsOutput struct { + Expiration *time.Time + AccessKeyID string + SecretAccessKey string + Token string +} + +type errorOutput struct { + Code string `json:"code"` + Message string `json:"message"` +} + +func (p *Provider) getCredentials() (*getCredentialsOutput, error) { + op := &request.Operation{ + Name: "GetCredentials", + HTTPMethod: "GET", + } + + out := &getCredentialsOutput{} + req := p.Client.NewRequest(op, nil, out) + req.HTTPRequest.Header.Set("Accept", "application/json") + + return out, req.Send() +} + +func validateEndpointHandler(r *request.Request) { + if len(r.ClientInfo.Endpoint) == 0 { + r.Error = aws.ErrMissingEndpoint + } +} + +func unmarshalHandler(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + out := r.Data.(*getCredentialsOutput) + if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil { + r.Error = awserr.New("SerializationError", + "failed to decode endpoint credentials", + err, + ) + } +} + +func unmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var errOut errorOutput + if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil { + r.Error = awserr.New("SerializationError", + "failed to decode endpoint credentials", + err, + ) + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New(errOut.Code, errOut.Message, nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go new file mode 100644 index 0000000000..96655bc46a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go @@ -0,0 +1,77 @@ +package credentials + +import ( + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// EnvProviderName provides a name of Env provider +const EnvProviderName = "EnvProvider" + +var ( + // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be + // found in the process's environment. + // + // @readonly + ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) + + // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key + // can't be found in the process's environment. + // + // @readonly + ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) +) + +// A EnvProvider retrieves credentials from the environment variables of the +// running process. Environment credentials never expire. +// +// Environment variables used: +// +// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY +// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY +type EnvProvider struct { + retrieved bool +} + +// NewEnvCredentials returns a pointer to a new Credentials object +// wrapping the environment variable provider. +func NewEnvCredentials() *Credentials { + return NewCredentials(&EnvProvider{}) +} + +// Retrieve retrieves the keys from the environment. +func (e *EnvProvider) Retrieve() (Value, error) { + e.retrieved = false + + id := os.Getenv("AWS_ACCESS_KEY_ID") + if id == "" { + id = os.Getenv("AWS_ACCESS_KEY") + } + + secret := os.Getenv("AWS_SECRET_ACCESS_KEY") + if secret == "" { + secret = os.Getenv("AWS_SECRET_KEY") + } + + if id == "" { + return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound + } + + if secret == "" { + return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound + } + + e.retrieved = true + return Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: os.Getenv("AWS_SESSION_TOKEN"), + ProviderName: EnvProviderName, + }, nil +} + +// IsExpired returns if the credentials have been retrieved. +func (e *EnvProvider) IsExpired() bool { + return !e.retrieved +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini b/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini new file mode 100644 index 0000000000..7fc91d9d20 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini @@ -0,0 +1,12 @@ +[default] +aws_access_key_id = accessKey +aws_secret_access_key = secret +aws_session_token = token + +[no_token] +aws_access_key_id = accessKey +aws_secret_access_key = secret + +[with_colon] +aws_access_key_id: accessKey +aws_secret_access_key: secret diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go new file mode 100644 index 0000000000..7fb7cbf0db --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go @@ -0,0 +1,151 @@ +package credentials + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/go-ini/ini" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// SharedCredsProviderName provides a name of SharedCreds provider +const SharedCredsProviderName = "SharedCredentialsProvider" + +var ( + // ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found. + // + // @readonly + ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil) +) + +// A SharedCredentialsProvider retrieves credentials from the current user's home +// directory, and keeps track if those credentials are expired. +// +// Profile ini file example: $HOME/.aws/credentials +type SharedCredentialsProvider struct { + // Path to the shared credentials file. + // + // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the + // env value is empty will default to current user's home directory. + // Linux/OSX: "$HOME/.aws/credentials" + // Windows: "%USERPROFILE%\.aws\credentials" + Filename string + + // AWS Profile to extract credentials from the shared credentials file. If empty + // will default to environment variable "AWS_PROFILE" or "default" if + // environment variable is also not set. + Profile string + + // retrieved states if the credentials have been successfully retrieved. + retrieved bool +} + +// NewSharedCredentials returns a pointer to a new Credentials object +// wrapping the Profile file provider. +func NewSharedCredentials(filename, profile string) *Credentials { + return NewCredentials(&SharedCredentialsProvider{ + Filename: filename, + Profile: profile, + }) +} + +// Retrieve reads and extracts the shared credentials from the current +// users home directory. +func (p *SharedCredentialsProvider) Retrieve() (Value, error) { + p.retrieved = false + + filename, err := p.filename() + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, err + } + + creds, err := loadProfile(filename, p.profile()) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, err + } + + p.retrieved = true + return creds, nil +} + +// IsExpired returns if the shared credentials have expired. +func (p *SharedCredentialsProvider) IsExpired() bool { + return !p.retrieved +} + +// loadProfiles loads from the file pointed to by shared credentials filename for profile. +// The credentials retrieved from the profile will be returned or error. Error will be +// returned if it fails to read from the file, or the data is invalid. +func loadProfile(filename, profile string) (Value, error) { + config, err := ini.Load(filename) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err) + } + iniProfile, err := config.GetSection(profile) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", err) + } + + id, err := iniProfile.GetKey("aws_access_key_id") + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey", + fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename), + err) + } + + secret, err := iniProfile.GetKey("aws_secret_access_key") + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret", + fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename), + nil) + } + + // Default to empty string if not found + token := iniProfile.Key("aws_session_token") + + return Value{ + AccessKeyID: id.String(), + SecretAccessKey: secret.String(), + SessionToken: token.String(), + ProviderName: SharedCredsProviderName, + }, nil +} + +// filename returns the filename to use to read AWS shared credentials. +// +// Will return an error if the user's home directory path cannot be found. +func (p *SharedCredentialsProvider) filename() (string, error) { + if p.Filename == "" { + if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); p.Filename != "" { + return p.Filename, nil + } + + homeDir := os.Getenv("HOME") // *nix + if homeDir == "" { // Windows + homeDir = os.Getenv("USERPROFILE") + } + if homeDir == "" { + return "", ErrSharedCredentialsHomeNotFound + } + + p.Filename = filepath.Join(homeDir, ".aws", "credentials") + } + + return p.Filename, nil +} + +// profile returns the AWS shared credentials profile. If empty will read +// environment variable "AWS_PROFILE". If that is not set profile will +// return "default". +func (p *SharedCredentialsProvider) profile() string { + if p.Profile == "" { + p.Profile = os.Getenv("AWS_PROFILE") + } + if p.Profile == "" { + p.Profile = "default" + } + + return p.Profile +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go new file mode 100644 index 0000000000..4f5dab3fcc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go @@ -0,0 +1,57 @@ +package credentials + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// StaticProviderName provides a name of Static provider +const StaticProviderName = "StaticProvider" + +var ( + // ErrStaticCredentialsEmpty is emitted when static credentials are empty. + // + // @readonly + ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) +) + +// A StaticProvider is a set of credentials which are set programmatically, +// and will never expire. +type StaticProvider struct { + Value +} + +// NewStaticCredentials returns a pointer to a new Credentials object +// wrapping a static credentials value provider. +func NewStaticCredentials(id, secret, token string) *Credentials { + return NewCredentials(&StaticProvider{Value: Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: token, + }}) +} + +// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object +// wrapping the static credentials value provide. Same as NewStaticCredentials +// but takes the creds Value instead of individual fields +func NewStaticCredentialsFromCreds(creds Value) *Credentials { + return NewCredentials(&StaticProvider{Value: creds}) +} + +// Retrieve returns the credentials or error if the credentials are invalid. +func (s *StaticProvider) Retrieve() (Value, error) { + if s.AccessKeyID == "" || s.SecretAccessKey == "" { + return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty + } + + if len(s.Value.ProviderName) == 0 { + s.Value.ProviderName = StaticProviderName + } + return s.Value, nil +} + +// IsExpired returns if the credentials are expired. +// +// For StaticProvider, the credentials never expired. +func (s *StaticProvider) IsExpired() bool { + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go new file mode 100644 index 0000000000..30c847ae22 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go @@ -0,0 +1,161 @@ +// Package stscreds are credential Providers to retrieve STS AWS credentials. +// +// STS provides multiple ways to retrieve credentials which can be used when making +// future AWS service API operation calls. +package stscreds + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/service/sts" +) + +// ProviderName provides a name of AssumeRole provider +const ProviderName = "AssumeRoleProvider" + +// AssumeRoler represents the minimal subset of the STS client API used by this provider. +type AssumeRoler interface { + AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) +} + +// DefaultDuration is the default amount of time in minutes that the credentials +// will be valid for. +var DefaultDuration = time.Duration(15) * time.Minute + +// AssumeRoleProvider retrieves temporary credentials from the STS service, and +// keeps track of their expiration time. This provider must be used explicitly, +// as it is not included in the credentials chain. +type AssumeRoleProvider struct { + credentials.Expiry + + // STS client to make assume role request with. + Client AssumeRoler + + // Role to be assumed. + RoleARN string + + // Session name, if you wish to reuse the credentials elsewhere. + RoleSessionName string + + // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // Optional ExternalID to pass along, defaults to nil if not set. + ExternalID *string + + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + SerialNumber *string + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + TokenCode *string + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes a Config provider to create the STS client. The ConfigProvider is +// satisfied by the session.Session type. +func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: sts.New(c), + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes an AssumeRoler which can be satisfiede by the STS client. +func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: svc, + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve generates a new set of temporary credentials using STS. +func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { + + // Apply defaults where parameters are not set. + if p.RoleSessionName == "" { + // Try to work out a role name that will hopefully end up unique. + p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano()) + } + if p.Duration == 0 { + // Expire as often as AWS permits. + p.Duration = DefaultDuration + } + input := &sts.AssumeRoleInput{ + DurationSeconds: aws.Int64(int64(p.Duration / time.Second)), + RoleArn: aws.String(p.RoleARN), + RoleSessionName: aws.String(p.RoleSessionName), + ExternalId: p.ExternalID, + } + if p.Policy != nil { + input.Policy = p.Policy + } + if p.SerialNumber != nil && p.TokenCode != nil { + input.SerialNumber = p.SerialNumber + input.TokenCode = p.TokenCode + } + roleOutput, err := p.Client.AssumeRole(input) + + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + // We will proactively generate new credentials before they expire. + p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: *roleOutput.Credentials.AccessKeyId, + SecretAccessKey: *roleOutput.Credentials.SecretAccessKey, + SessionToken: *roleOutput.Credentials.SessionToken, + ProviderName: ProviderName, + }, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go new file mode 100644 index 0000000000..10b7d86490 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -0,0 +1,129 @@ +// Package defaults is a collection of helpers to retrieve the SDK's default +// configuration and handlers. +// +// Generally this package shouldn't be used directly, but session.Session +// instead. This package is useful when you need to reset the defaults +// of a session or service client to the SDK defaults before setting +// additional parameters. +package defaults + +import ( + "fmt" + "net/http" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" + "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds" + "github.com/aws/aws-sdk-go/aws/ec2metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/endpoints" +) + +// A Defaults provides a collection of default values for SDK clients. +type Defaults struct { + Config *aws.Config + Handlers request.Handlers +} + +// Get returns the SDK's default values with Config and handlers pre-configured. +func Get() Defaults { + cfg := Config() + handlers := Handlers() + cfg.Credentials = CredChain(cfg, handlers) + + return Defaults{ + Config: cfg, + Handlers: handlers, + } +} + +// Config returns the default configuration without credentials. +// To retrieve a config with credentials also included use +// `defaults.Get().Config` instead. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the configuration of an +// existing service client or session. +func Config() *aws.Config { + return aws.NewConfig(). + WithCredentials(credentials.AnonymousCredentials). + WithRegion(os.Getenv("AWS_REGION")). + WithHTTPClient(http.DefaultClient). + WithMaxRetries(aws.UseServiceDefaultRetries). + WithLogger(aws.NewDefaultLogger()). + WithLogLevel(aws.LogOff). + WithSleepDelay(time.Sleep) +} + +// Handlers returns the default request handlers. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the request handlers of an +// existing service client or session. +func Handlers() request.Handlers { + var handlers request.Handlers + + handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) + handlers.Validate.AfterEachFn = request.HandlerListStopOnError + handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) + handlers.Build.AfterEachFn = request.HandlerListStopOnError + handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) + handlers.Send.PushBackNamed(corehandlers.SendHandler) + handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) + handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) + + return handlers +} + +// CredChain returns the default credential chain. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the credentials of an +// existing service client or session's Config. +func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { + return credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: []credentials.Provider{ + &credentials.EnvProvider{}, + &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, + RemoteCredProvider(*cfg, handlers), + }, + }) +} + +// RemoteCredProvider returns a credenitials provider for the default remote +// endpoints such as EC2 or ECS Roles. +func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { + ecsCredURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") + + if len(ecsCredURI) > 0 { + return ecsCredProvider(cfg, handlers, ecsCredURI) + } + + return ec2RoleProvider(cfg, handlers) +} + +func ecsCredProvider(cfg aws.Config, handlers request.Handlers, uri string) credentials.Provider { + const host = `169.254.170.2` + + return endpointcreds.NewProviderClient(cfg, handlers, + fmt.Sprintf("http://%s%s", host, uri), + func(p *endpointcreds.Provider) { + p.ExpiryWindow = 5 * time.Minute + }, + ) +} + +func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { + endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, + aws.StringValue(cfg.Region), true, false) + + return &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.NewClient(cfg, handlers, endpoint, signingRegion), + ExpiryWindow: 5 * time.Minute, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go new file mode 100644 index 0000000000..669c813a00 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go @@ -0,0 +1,140 @@ +package ec2metadata + +import ( + "encoding/json" + "fmt" + "path" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// GetMetadata uses the path provided to request information from the EC2 +// instance metdata service. The content will be returned as a string, or +// error if the request failed. +func (c *EC2Metadata) GetMetadata(p string) (string, error) { + op := &request.Operation{ + Name: "GetMetadata", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "meta-data", p), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + + return output.Content, req.Send() +} + +// GetDynamicData uses the path provided to request information from the EC2 +// instance metadata service for dynamic data. The content will be returned +// as a string, or error if the request failed. +func (c *EC2Metadata) GetDynamicData(p string) (string, error) { + op := &request.Operation{ + Name: "GetDynamicData", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "dynamic", p), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + + return output.Content, req.Send() +} + +// GetInstanceIdentityDocument retrieves an identity document describing an +// instance. Error is returned if the request fails or is unable to parse +// the response. +func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) { + resp, err := c.GetDynamicData("instance-identity/document") + if err != nil { + return EC2InstanceIdentityDocument{}, + awserr.New("EC2MetadataRequestError", + "failed to get EC2 instance identity document", err) + } + + doc := EC2InstanceIdentityDocument{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil { + return EC2InstanceIdentityDocument{}, + awserr.New("SerializationError", + "failed to decode EC2 instance identity document", err) + } + + return doc, nil +} + +// IAMInfo retrieves IAM info from the metadata API +func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) { + resp, err := c.GetMetadata("iam/info") + if err != nil { + return EC2IAMInfo{}, + awserr.New("EC2MetadataRequestError", + "failed to get EC2 IAM info", err) + } + + info := EC2IAMInfo{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil { + return EC2IAMInfo{}, + awserr.New("SerializationError", + "failed to decode EC2 IAM info", err) + } + + if info.Code != "Success" { + errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code) + return EC2IAMInfo{}, + awserr.New("EC2MetadataError", errMsg, nil) + } + + return info, nil +} + +// Region returns the region the instance is running in. +func (c *EC2Metadata) Region() (string, error) { + resp, err := c.GetMetadata("placement/availability-zone") + if err != nil { + return "", err + } + + // returns region without the suffix. Eg: us-west-2a becomes us-west-2 + return resp[:len(resp)-1], nil +} + +// Available returns if the application has access to the EC2 Metadata service. +// Can be used to determine if application is running within an EC2 Instance and +// the metadata service is available. +func (c *EC2Metadata) Available() bool { + if _, err := c.GetMetadata("instance-id"); err != nil { + return false + } + + return true +} + +// An EC2IAMInfo provides the shape for unmarshalling +// an IAM info from the metadata API +type EC2IAMInfo struct { + Code string + LastUpdated time.Time + InstanceProfileArn string + InstanceProfileID string +} + +// An EC2InstanceIdentityDocument provides the shape for unmarshalling +// an instance identity document +type EC2InstanceIdentityDocument struct { + DevpayProductCodes []string `json:"devpayProductCodes"` + AvailabilityZone string `json:"availabilityZone"` + PrivateIP string `json:"privateIp"` + Version string `json:"version"` + Region string `json:"region"` + InstanceID string `json:"instanceId"` + BillingProducts []string `json:"billingProducts"` + InstanceType string `json:"instanceType"` + AccountID string `json:"accountId"` + PendingTime time.Time `json:"pendingTime"` + ImageID string `json:"imageId"` + KernelID string `json:"kernelId"` + RamdiskID string `json:"ramdiskId"` + Architecture string `json:"architecture"` +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go new file mode 100644 index 0000000000..5b4379dbd8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go @@ -0,0 +1,124 @@ +// Package ec2metadata provides the client for making API calls to the +// EC2 Metadata service. +package ec2metadata + +import ( + "bytes" + "errors" + "io" + "net/http" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// ServiceName is the name of the service. +const ServiceName = "ec2metadata" + +// A EC2Metadata is an EC2 Metadata service Client. +type EC2Metadata struct { + *client.Client +} + +// New creates a new instance of the EC2Metadata client with a session. +// This client is safe to use across multiple goroutines. +// +// +// Example: +// // Create a EC2Metadata client from just a session. +// svc := ec2metadata.New(mySession) +// +// // Create a EC2Metadata client with additional configuration +// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody)) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata { + c := p.ClientConfig(ServiceName, cfgs...) + return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) +} + +// NewClient returns a new EC2Metadata client. Should be used to create +// a client when not using a session. Generally using just New with a session +// is preferred. +// +// If an unmodified HTTP client is provided from the stdlib default, or no client +// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened. +// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default. +func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata { + if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) { + // If the http client is unmodified and this feature is not disabled + // set custom timeouts for EC2Metadata requests. + cfg.HTTPClient = &http.Client{ + // use a shorter timeout than default because the metadata + // service is local if it is running, and to fail faster + // if not running on an ec2 instance. + Timeout: 5 * time.Second, + } + } + + svc := &EC2Metadata{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + Endpoint: endpoint, + APIVersion: "latest", + }, + handlers, + ), + } + + svc.Handlers.Unmarshal.PushBack(unmarshalHandler) + svc.Handlers.UnmarshalError.PushBack(unmarshalError) + svc.Handlers.Validate.Clear() + svc.Handlers.Validate.PushBack(validateEndpointHandler) + + // Add additional options to the service config + for _, option := range opts { + option(svc.Client) + } + + return svc +} + +func httpClientZero(c *http.Client) bool { + return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0) +} + +type metadataOutput struct { + Content string +} + +func unmarshalHandler(r *request.Request) { + defer r.HTTPResponse.Body.Close() + b := &bytes.Buffer{} + if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { + r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) + return + } + + if data, ok := r.Data.(*metadataOutput); ok { + data.Content = b.String() + } +} + +func unmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + b := &bytes.Buffer{} + if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { + r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) + return + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())) +} + +func validateEndpointHandler(r *request.Request) { + if r.ClientInfo.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/errors.go b/vendor/github.com/aws/aws-sdk-go/aws/errors.go new file mode 100644 index 0000000000..5766361686 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/errors.go @@ -0,0 +1,17 @@ +package aws + +import "github.com/aws/aws-sdk-go/aws/awserr" + +var ( + // ErrMissingRegion is an error that is returned if region configuration is + // not found. + // + // @readonly + ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) + + // ErrMissingEndpoint is an error that is returned if an endpoint cannot be + // resolved for a service. + // + // @readonly + ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/logger.go new file mode 100644 index 0000000000..db87188e20 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/logger.go @@ -0,0 +1,112 @@ +package aws + +import ( + "log" + "os" +) + +// A LogLevelType defines the level logging should be performed at. Used to instruct +// the SDK which statements should be logged. +type LogLevelType uint + +// LogLevel returns the pointer to a LogLevel. Should be used to workaround +// not being able to take the address of a non-composite literal. +func LogLevel(l LogLevelType) *LogLevelType { + return &l +} + +// Value returns the LogLevel value or the default value LogOff if the LogLevel +// is nil. Safe to use on nil value LogLevelTypes. +func (l *LogLevelType) Value() LogLevelType { + if l != nil { + return *l + } + return LogOff +} + +// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be +// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If +// LogLevel is nill, will default to LogOff comparison. +func (l *LogLevelType) Matches(v LogLevelType) bool { + c := l.Value() + return c&v == v +} + +// AtLeast returns true if this LogLevel is at least high enough to satisfies v. +// Is safe to use on nil value LogLevelTypes. If LogLevel is nill, will default +// to LogOff comparison. +func (l *LogLevelType) AtLeast(v LogLevelType) bool { + c := l.Value() + return c >= v +} + +const ( + // LogOff states that no logging should be performed by the SDK. This is the + // default state of the SDK, and should be use to disable all logging. + LogOff LogLevelType = iota * 0x1000 + + // LogDebug state that debug output should be logged by the SDK. This should + // be used to inspect request made and responses received. + LogDebug +) + +// Debug Logging Sub Levels +const ( + // LogDebugWithSigning states that the SDK should log request signing and + // presigning events. This should be used to log the signing details of + // requests for debugging. Will also enable LogDebug. + LogDebugWithSigning LogLevelType = LogDebug | (1 << iota) + + // LogDebugWithHTTPBody states the SDK should log HTTP request and response + // HTTP bodys in addition to the headers and path. This should be used to + // see the body content of requests and responses made while using the SDK + // Will also enable LogDebug. + LogDebugWithHTTPBody + + // LogDebugWithRequestRetries states the SDK should log when service requests will + // be retried. This should be used to log when you want to log when service + // requests are being retried. Will also enable LogDebug. + LogDebugWithRequestRetries + + // LogDebugWithRequestErrors states the SDK should log when service requests fail + // to build, send, validate, or unmarshal. + LogDebugWithRequestErrors +) + +// A Logger is a minimalistic interface for the SDK to log messages to. Should +// be used to provide custom logging writers for the SDK to use. +type Logger interface { + Log(...interface{}) +} + +// A LoggerFunc is a convenience type to convert a function taking a variadic +// list of arguments and wrap it so the Logger interface can be used. +// +// Example: +// s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) { +// fmt.Fprintln(os.Stdout, args...) +// })}) +type LoggerFunc func(...interface{}) + +// Log calls the wrapped function with the arguments provided +func (f LoggerFunc) Log(args ...interface{}) { + f(args...) +} + +// NewDefaultLogger returns a Logger which will write log messages to stdout, and +// use same formatting runes as the stdlib log.Logger +func NewDefaultLogger() Logger { + return &defaultLogger{ + logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +// A defaultLogger provides a minimalistic logger satisfying the Logger interface. +type defaultLogger struct { + logger *log.Logger +} + +// Log logs the parameters to the stdlib logger. See log.Println. +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go new file mode 100644 index 0000000000..5279c19c09 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go @@ -0,0 +1,187 @@ +package request + +import ( + "fmt" + "strings" +) + +// A Handlers provides a collection of request handlers for various +// stages of handling requests. +type Handlers struct { + Validate HandlerList + Build HandlerList + Sign HandlerList + Send HandlerList + ValidateResponse HandlerList + Unmarshal HandlerList + UnmarshalMeta HandlerList + UnmarshalError HandlerList + Retry HandlerList + AfterRetry HandlerList +} + +// Copy returns of this handler's lists. +func (h *Handlers) Copy() Handlers { + return Handlers{ + Validate: h.Validate.copy(), + Build: h.Build.copy(), + Sign: h.Sign.copy(), + Send: h.Send.copy(), + ValidateResponse: h.ValidateResponse.copy(), + Unmarshal: h.Unmarshal.copy(), + UnmarshalError: h.UnmarshalError.copy(), + UnmarshalMeta: h.UnmarshalMeta.copy(), + Retry: h.Retry.copy(), + AfterRetry: h.AfterRetry.copy(), + } +} + +// Clear removes callback functions for all handlers +func (h *Handlers) Clear() { + h.Validate.Clear() + h.Build.Clear() + h.Send.Clear() + h.Sign.Clear() + h.Unmarshal.Clear() + h.UnmarshalMeta.Clear() + h.UnmarshalError.Clear() + h.ValidateResponse.Clear() + h.Retry.Clear() + h.AfterRetry.Clear() +} + +// A HandlerListRunItem represents an entry in the HandlerList which +// is being run. +type HandlerListRunItem struct { + Index int + Handler NamedHandler + Request *Request +} + +// A HandlerList manages zero or more handlers in a list. +type HandlerList struct { + list []NamedHandler + + // Called after each request handler in the list is called. If set + // and the func returns true the HandlerList will continue to iterate + // over the request handlers. If false is returned the HandlerList + // will stop iterating. + // + // Should be used if extra logic to be performed between each handler + // in the list. This can be used to terminate a list's iteration + // based on a condition such as error like, HandlerListStopOnError. + // Or for logging like HandlerListLogItem. + AfterEachFn func(item HandlerListRunItem) bool +} + +// A NamedHandler is a struct that contains a name and function callback. +type NamedHandler struct { + Name string + Fn func(*Request) +} + +// copy creates a copy of the handler list. +func (l *HandlerList) copy() HandlerList { + n := HandlerList{ + AfterEachFn: l.AfterEachFn, + } + n.list = append([]NamedHandler{}, l.list...) + return n +} + +// Clear clears the handler list. +func (l *HandlerList) Clear() { + l.list = []NamedHandler{} +} + +// Len returns the number of handlers in the list. +func (l *HandlerList) Len() int { + return len(l.list) +} + +// PushBack pushes handler f to the back of the handler list. +func (l *HandlerList) PushBack(f func(*Request)) { + l.list = append(l.list, NamedHandler{"__anonymous", f}) +} + +// PushFront pushes handler f to the front of the handler list. +func (l *HandlerList) PushFront(f func(*Request)) { + l.list = append([]NamedHandler{{"__anonymous", f}}, l.list...) +} + +// PushBackNamed pushes named handler f to the back of the handler list. +func (l *HandlerList) PushBackNamed(n NamedHandler) { + l.list = append(l.list, n) +} + +// PushFrontNamed pushes named handler f to the front of the handler list. +func (l *HandlerList) PushFrontNamed(n NamedHandler) { + l.list = append([]NamedHandler{n}, l.list...) +} + +// Remove removes a NamedHandler n +func (l *HandlerList) Remove(n NamedHandler) { + newlist := []NamedHandler{} + for _, m := range l.list { + if m.Name != n.Name { + newlist = append(newlist, m) + } + } + l.list = newlist +} + +// Run executes all handlers in the list with a given request object. +func (l *HandlerList) Run(r *Request) { + for i, h := range l.list { + h.Fn(r) + item := HandlerListRunItem{ + Index: i, Handler: h, Request: r, + } + if l.AfterEachFn != nil && !l.AfterEachFn(item) { + return + } + } +} + +// HandlerListLogItem logs the request handler and the state of the +// request's Error value. Always returns true to continue iterating +// request handlers in a HandlerList. +func HandlerListLogItem(item HandlerListRunItem) bool { + if item.Request.Config.Logger == nil { + return true + } + item.Request.Config.Logger.Log("DEBUG: RequestHandler", + item.Index, item.Handler.Name, item.Request.Error) + + return true +} + +// HandlerListStopOnError returns false to stop the HandlerList iterating +// over request handlers if Request.Error is not nil. True otherwise +// to continue iterating. +func HandlerListStopOnError(item HandlerListRunItem) bool { + return item.Request.Error == nil +} + +// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request +// header. If the extra parameters are provided they will be added as metadata to the +// name/version pair resulting in the following format. +// "name/version (extra0; extra1; ...)" +// The user agent part will be concatenated with this current request's user agent string. +func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) { + ua := fmt.Sprintf("%s/%s", name, version) + if len(extra) > 0 { + ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; ")) + } + return func(r *Request) { + AddToUserAgent(r, ua) + } +} + +// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header. +// The input string will be concatenated with the current request's user agent string. +func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) { + return func(r *Request) { + AddToUserAgent(r, s) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go new file mode 100644 index 0000000000..a4087f20e8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go @@ -0,0 +1,33 @@ +// +build go1.5 + +package request + +import ( + "io" + "net/http" + "net/url" +) + +func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { + req := &http.Request{ + URL: &url.URL{}, + Header: http.Header{}, + Close: r.Close, + Body: body, + Host: r.Host, + Method: r.Method, + Proto: r.Proto, + ContentLength: r.ContentLength, + // Cancel will be deprecated in 1.7 and will be replaced with Context + Cancel: r.Cancel, + } + + *req.URL = *r.URL + for k, v := range r.Header { + for _, vv := range v { + req.Header.Add(k, vv) + } + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go new file mode 100644 index 0000000000..75da021efe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go @@ -0,0 +1,31 @@ +// +build !go1.5 + +package request + +import ( + "io" + "net/http" + "net/url" +) + +func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { + req := &http.Request{ + URL: &url.URL{}, + Header: http.Header{}, + Close: r.Close, + Body: body, + Host: r.Host, + Method: r.Method, + Proto: r.Proto, + ContentLength: r.ContentLength, + } + + *req.URL = *r.URL + for k, v := range r.Header { + for _, vv := range v { + req.Header.Add(k, vv) + } + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go new file mode 100644 index 0000000000..da6396d2d9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go @@ -0,0 +1,49 @@ +package request + +import ( + "io" + "sync" +) + +// offsetReader is a thread-safe io.ReadCloser to prevent racing +// with retrying requests +type offsetReader struct { + buf io.ReadSeeker + lock sync.RWMutex + closed bool +} + +func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader { + reader := &offsetReader{} + buf.Seek(offset, 0) + + reader.buf = buf + return reader +} + +// Close is a thread-safe close. Uses the write lock. +func (o *offsetReader) Close() error { + o.lock.Lock() + defer o.lock.Unlock() + o.closed = true + return nil +} + +// Read is a thread-safe read using a read lock. +func (o *offsetReader) Read(p []byte) (int, error) { + o.lock.RLock() + defer o.lock.RUnlock() + + if o.closed { + return 0, io.EOF + } + + return o.buf.Read(p) +} + +// CloseAndCopy will return a new offsetReader with a copy of the old buffer +// and close the old buffer. +func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader { + o.Close() + return newOffsetReader(o.buf, offset) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go new file mode 100644 index 0000000000..2832aaa436 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -0,0 +1,326 @@ +package request + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client/metadata" +) + +// A Request is the service request to be made. +type Request struct { + Config aws.Config + ClientInfo metadata.ClientInfo + Handlers Handlers + + Retryer + Time time.Time + ExpireTime time.Duration + Operation *Operation + HTTPRequest *http.Request + HTTPResponse *http.Response + Body io.ReadSeeker + BodyStart int64 // offset from beginning of Body that the request body starts + Params interface{} + Error error + Data interface{} + RequestID string + RetryCount int + Retryable *bool + RetryDelay time.Duration + NotHoist bool + SignedHeaderVals http.Header + LastSignedAt time.Time + + built bool +} + +// An Operation is the service API operation to be made. +type Operation struct { + Name string + HTTPMethod string + HTTPPath string + *Paginator +} + +// Paginator keeps track of pagination configuration for an API operation. +type Paginator struct { + InputTokens []string + OutputTokens []string + LimitToken string + TruncationToken string +} + +// New returns a new Request pointer for the service API +// operation and parameters. +// +// Params is any value of input parameters to be the request payload. +// Data is pointer value to an object which the request's response +// payload will be deserialized to. +func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, + retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request { + + method := operation.HTTPMethod + if method == "" { + method = "POST" + } + + httpReq, _ := http.NewRequest(method, "", nil) + + var err error + httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath) + if err != nil { + httpReq.URL = &url.URL{} + err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err) + } + + r := &Request{ + Config: cfg, + ClientInfo: clientInfo, + Handlers: handlers.Copy(), + + Retryer: retryer, + Time: time.Now(), + ExpireTime: 0, + Operation: operation, + HTTPRequest: httpReq, + Body: nil, + Params: params, + Error: err, + Data: data, + } + r.SetBufferBody([]byte{}) + + return r +} + +// WillRetry returns if the request's can be retried. +func (r *Request) WillRetry() bool { + return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() +} + +// ParamsFilled returns if the request's parameters have been populated +// and the parameters are valid. False is returned if no parameters are +// provided or invalid. +func (r *Request) ParamsFilled() bool { + return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid() +} + +// DataFilled returns true if the request's data for response deserialization +// target has been set and is a valid. False is returned if data is not +// set, or is invalid. +func (r *Request) DataFilled() bool { + return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid() +} + +// SetBufferBody will set the request's body bytes that will be sent to +// the service API. +func (r *Request) SetBufferBody(buf []byte) { + r.SetReaderBody(bytes.NewReader(buf)) +} + +// SetStringBody sets the body of the request to be backed by a string. +func (r *Request) SetStringBody(s string) { + r.SetReaderBody(strings.NewReader(s)) +} + +// SetReaderBody will set the request's body reader. +func (r *Request) SetReaderBody(reader io.ReadSeeker) { + r.HTTPRequest.Body = newOffsetReader(reader, 0) + r.Body = reader +} + +// Presign returns the request's signed URL. Error will be returned +// if the signing fails. +func (r *Request) Presign(expireTime time.Duration) (string, error) { + r.ExpireTime = expireTime + r.NotHoist = false + r.Sign() + if r.Error != nil { + return "", r.Error + } + return r.HTTPRequest.URL.String(), nil +} + +// PresignRequest behaves just like presign, but hoists all headers and signs them. +// Also returns the signed hash back to the user +func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) { + r.ExpireTime = expireTime + r.NotHoist = true + r.Sign() + if r.Error != nil { + return "", nil, r.Error + } + return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil +} + +func debugLogReqError(r *Request, stage string, retrying bool, err error) { + if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) { + return + } + + retryStr := "not retrying" + if retrying { + retryStr = "will retry" + } + + r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v", + stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err)) +} + +// Build will build the request's object so it can be signed and sent +// to the service. Build will also validate all the request's parameters. +// Anny additional build Handlers set on this request will be run +// in the order they were set. +// +// The request will only be built once. Multiple calls to build will have +// no effect. +// +// If any Validate or Build errors occur the build will stop and the error +// which occurred will be returned. +func (r *Request) Build() error { + if !r.built { + r.Handlers.Validate.Run(r) + if r.Error != nil { + debugLogReqError(r, "Validate Request", false, r.Error) + return r.Error + } + r.Handlers.Build.Run(r) + if r.Error != nil { + debugLogReqError(r, "Build Request", false, r.Error) + return r.Error + } + r.built = true + } + + return r.Error +} + +// Sign will sign the request returning error if errors are encountered. +// +// Send will build the request prior to signing. All Sign Handlers will +// be executed in the order they were set. +func (r *Request) Sign() error { + r.Build() + if r.Error != nil { + debugLogReqError(r, "Build Request", false, r.Error) + return r.Error + } + + r.Handlers.Sign.Run(r) + return r.Error +} + +// Send will send the request returning error if errors are encountered. +// +// Send will sign the request prior to sending. All Send Handlers will +// be executed in the order they were set. +// +// Canceling a request is non-deterministic. If a request has been canceled, +// then the transport will choose, randomly, one of the state channels during +// reads or getting the connection. +// +// readLoop() and getConn(req *Request, cm connectMethod) +// https://github.com/golang/go/blob/master/src/net/http/transport.go +func (r *Request) Send() error { + for { + if aws.BoolValue(r.Retryable) { + if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) { + r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d", + r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount)) + } + + var body io.ReadCloser + if reader, ok := r.HTTPRequest.Body.(*offsetReader); ok { + body = reader.CloseAndCopy(r.BodyStart) + } else { + if r.Config.Logger != nil { + r.Config.Logger.Log("Request body type has been overwritten. May cause race conditions") + } + r.Body.Seek(r.BodyStart, 0) + body = ioutil.NopCloser(r.Body) + } + + r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, body) + if r.HTTPResponse != nil && r.HTTPResponse.Body != nil { + // Closing response body. Since we are setting a new request to send off, this + // response will get squashed and leaked. + r.HTTPResponse.Body.Close() + } + } + + r.Sign() + if r.Error != nil { + return r.Error + } + + r.Retryable = nil + + r.Handlers.Send.Run(r) + if r.Error != nil { + if strings.Contains(r.Error.Error(), "net/http: request canceled") { + return r.Error + } + + err := r.Error + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + if r.Error != nil { + debugLogReqError(r, "Send Request", false, r.Error) + return r.Error + } + debugLogReqError(r, "Send Request", true, err) + continue + } + + r.Handlers.UnmarshalMeta.Run(r) + r.Handlers.ValidateResponse.Run(r) + if r.Error != nil { + err := r.Error + r.Handlers.UnmarshalError.Run(r) + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + if r.Error != nil { + debugLogReqError(r, "Validate Response", false, r.Error) + return r.Error + } + debugLogReqError(r, "Validate Response", true, err) + continue + } + + r.Handlers.Unmarshal.Run(r) + if r.Error != nil { + err := r.Error + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + if r.Error != nil { + debugLogReqError(r, "Unmarshal Response", false, r.Error) + return r.Error + } + debugLogReqError(r, "Unmarshal Response", true, err) + continue + } + + break + } + + return nil +} + +// AddToUserAgent adds the string to the end of the request's current user agent. +func AddToUserAgent(r *Request, s string) { + curUA := r.HTTPRequest.Header.Get("User-Agent") + if len(curUA) > 0 { + s = curUA + " " + s + } + r.HTTPRequest.Header.Set("User-Agent", s) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go new file mode 100644 index 0000000000..2939ec473f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go @@ -0,0 +1,104 @@ +package request + +import ( + "reflect" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" +) + +//type Paginater interface { +// HasNextPage() bool +// NextPage() *Request +// EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error +//} + +// HasNextPage returns true if this request has more pages of data available. +func (r *Request) HasNextPage() bool { + return len(r.nextPageTokens()) > 0 +} + +// nextPageTokens returns the tokens to use when asking for the next page of +// data. +func (r *Request) nextPageTokens() []interface{} { + if r.Operation.Paginator == nil { + return nil + } + + if r.Operation.TruncationToken != "" { + tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) + if len(tr) == 0 { + return nil + } + + switch v := tr[0].(type) { + case *bool: + if !aws.BoolValue(v) { + return nil + } + case bool: + if v == false { + return nil + } + } + } + + tokens := []interface{}{} + tokenAdded := false + for _, outToken := range r.Operation.OutputTokens { + v, _ := awsutil.ValuesAtPath(r.Data, outToken) + if len(v) > 0 { + tokens = append(tokens, v[0]) + tokenAdded = true + } else { + tokens = append(tokens, nil) + } + } + if !tokenAdded { + return nil + } + + return tokens +} + +// NextPage returns a new Request that can be executed to return the next +// page of result data. Call .Send() on this request to execute it. +func (r *Request) NextPage() *Request { + tokens := r.nextPageTokens() + if len(tokens) == 0 { + return nil + } + + data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface() + nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data) + for i, intok := range nr.Operation.InputTokens { + awsutil.SetValueAtPath(nr.Params, intok, tokens[i]) + } + return nr +} + +// EachPage iterates over each page of a paginated request object. The fn +// parameter should be a function with the following sample signature: +// +// func(page *T, lastPage bool) bool { +// return true // return false to stop iterating +// } +// +// Where "T" is the structure type matching the output structure of the given +// operation. For example, a request object generated by +// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput +// as the structure "T". The lastPage value represents whether the page is +// the last page of data or not. The return value of this function should +// return true to keep iterating or false to stop. +func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error { + for page := r; page != nil; page = page.NextPage() { + if err := page.Send(); err != nil { + return err + } + if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage { + return page.Error + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go new file mode 100644 index 0000000000..8cc8b015ae --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go @@ -0,0 +1,101 @@ +package request + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// Retryer is an interface to control retry logic for a given service. +// The default implementation used by most services is the service.DefaultRetryer +// structure, which contains basic retry logic using exponential backoff. +type Retryer interface { + RetryRules(*Request) time.Duration + ShouldRetry(*Request) bool + MaxRetries() int +} + +// WithRetryer sets a config Retryer value to the given Config returning it +// for chaining. +func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config { + cfg.Retryer = retryer + return cfg +} + +// retryableCodes is a collection of service response codes which are retry-able +// without any further action. +var retryableCodes = map[string]struct{}{ + "RequestError": {}, + "RequestTimeout": {}, +} + +var throttleCodes = map[string]struct{}{ + "ProvisionedThroughputExceededException": {}, + "Throttling": {}, + "ThrottlingException": {}, + "RequestLimitExceeded": {}, + "RequestThrottled": {}, + "LimitExceededException": {}, // Deleting 10+ DynamoDb tables at once + "TooManyRequestsException": {}, // Lambda functions +} + +// credsExpiredCodes is a collection of error codes which signify the credentials +// need to be refreshed. Expired tokens require refreshing of credentials, and +// resigning before the request can be retried. +var credsExpiredCodes = map[string]struct{}{ + "ExpiredToken": {}, + "ExpiredTokenException": {}, + "RequestExpired": {}, // EC2 Only +} + +func isCodeThrottle(code string) bool { + _, ok := throttleCodes[code] + return ok +} + +func isCodeRetryable(code string) bool { + if _, ok := retryableCodes[code]; ok { + return true + } + + return isCodeExpiredCreds(code) +} + +func isCodeExpiredCreds(code string) bool { + _, ok := credsExpiredCodes[code] + return ok +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if the request has no Error set. +func (r *Request) IsErrorRetryable() bool { + if r.Error != nil { + if err, ok := r.Error.(awserr.Error); ok { + return isCodeRetryable(err.Code()) + } + } + return false +} + +// IsErrorThrottle returns whether the error is to be throttled based on its code. +// Returns false if the request has no Error set +func (r *Request) IsErrorThrottle() bool { + if r.Error != nil { + if err, ok := r.Error.(awserr.Error); ok { + return isCodeThrottle(err.Code()) + } + } + return false +} + +// IsErrorExpired returns whether the error code is a credential expiry error. +// Returns false if the request has no Error set. +func (r *Request) IsErrorExpired() bool { + if r.Error != nil { + if err, ok := r.Error.(awserr.Error); ok { + return isCodeExpiredCreds(err.Code()) + } + } + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go new file mode 100644 index 0000000000..2520286b75 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go @@ -0,0 +1,234 @@ +package request + +import ( + "bytes" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +const ( + // InvalidParameterErrCode is the error code for invalid parameters errors + InvalidParameterErrCode = "InvalidParameter" + // ParamRequiredErrCode is the error code for required parameter errors + ParamRequiredErrCode = "ParamRequiredError" + // ParamMinValueErrCode is the error code for fields with too low of a + // number value. + ParamMinValueErrCode = "ParamMinValueError" + // ParamMinLenErrCode is the error code for fields without enough elements. + ParamMinLenErrCode = "ParamMinLenError" +) + +// Validator provides a way for types to perform validation logic on their +// input values that external code can use to determine if a type's values +// are valid. +type Validator interface { + Validate() error +} + +// An ErrInvalidParams provides wrapping of invalid parameter errors found when +// validating API operation input parameters. +type ErrInvalidParams struct { + // Context is the base context of the invalid parameter group. + Context string + errs []ErrInvalidParam +} + +// Add adds a new invalid parameter error to the collection of invalid +// parameters. The context of the invalid parameter will be updated to reflect +// this collection. +func (e *ErrInvalidParams) Add(err ErrInvalidParam) { + err.SetContext(e.Context) + e.errs = append(e.errs, err) +} + +// AddNested adds the invalid parameter errors from another ErrInvalidParams +// value into this collection. The nested errors will have their nested context +// updated and base context to reflect the merging. +// +// Use for nested validations errors. +func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) { + for _, err := range nested.errs { + err.SetContext(e.Context) + err.AddNestedContext(nestedCtx) + e.errs = append(e.errs, err) + } +} + +// Len returns the number of invalid parameter errors +func (e ErrInvalidParams) Len() int { + return len(e.errs) +} + +// Code returns the code of the error +func (e ErrInvalidParams) Code() string { + return InvalidParameterErrCode +} + +// Message returns the message of the error +func (e ErrInvalidParams) Message() string { + return fmt.Sprintf("%d validation error(s) found.", len(e.errs)) +} + +// Error returns the string formatted form of the invalid parameters. +func (e ErrInvalidParams) Error() string { + w := &bytes.Buffer{} + fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message()) + + for _, err := range e.errs { + fmt.Fprintf(w, "- %s\n", err.Message()) + } + + return w.String() +} + +// OrigErr returns the invalid parameters as a awserr.BatchedErrors value +func (e ErrInvalidParams) OrigErr() error { + return awserr.NewBatchError( + InvalidParameterErrCode, e.Message(), e.OrigErrs()) +} + +// OrigErrs returns a slice of the invalid parameters +func (e ErrInvalidParams) OrigErrs() []error { + errs := make([]error, len(e.errs)) + for i := 0; i < len(errs); i++ { + errs[i] = e.errs[i] + } + + return errs +} + +// An ErrInvalidParam represents an invalid parameter error type. +type ErrInvalidParam interface { + awserr.Error + + // Field name the error occurred on. + Field() string + + // SetContext updates the context of the error. + SetContext(string) + + // AddNestedContext updates the error's context to include a nested level. + AddNestedContext(string) +} + +type errInvalidParam struct { + context string + nestedContext string + field string + code string + msg string +} + +// Code returns the error code for the type of invalid parameter. +func (e *errInvalidParam) Code() string { + return e.code +} + +// Message returns the reason the parameter was invalid, and its context. +func (e *errInvalidParam) Message() string { + return fmt.Sprintf("%s, %s.", e.msg, e.Field()) +} + +// Error returns the string version of the invalid parameter error. +func (e *errInvalidParam) Error() string { + return fmt.Sprintf("%s: %s", e.code, e.Message()) +} + +// OrigErr returns nil, Implemented for awserr.Error interface. +func (e *errInvalidParam) OrigErr() error { + return nil +} + +// Field Returns the field and context the error occurred. +func (e *errInvalidParam) Field() string { + field := e.context + if len(field) > 0 { + field += "." + } + if len(e.nestedContext) > 0 { + field += fmt.Sprintf("%s.", e.nestedContext) + } + field += e.field + + return field +} + +// SetContext updates the base context of the error. +func (e *errInvalidParam) SetContext(ctx string) { + e.context = ctx +} + +// AddNestedContext prepends a context to the field's path. +func (e *errInvalidParam) AddNestedContext(ctx string) { + if len(e.nestedContext) == 0 { + e.nestedContext = ctx + } else { + e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext) + } + +} + +// An ErrParamRequired represents an required parameter error. +type ErrParamRequired struct { + errInvalidParam +} + +// NewErrParamRequired creates a new required parameter error. +func NewErrParamRequired(field string) *ErrParamRequired { + return &ErrParamRequired{ + errInvalidParam{ + code: ParamRequiredErrCode, + field: field, + msg: fmt.Sprintf("missing required field"), + }, + } +} + +// An ErrParamMinValue represents a minimum value parameter error. +type ErrParamMinValue struct { + errInvalidParam + min float64 +} + +// NewErrParamMinValue creates a new minimum value parameter error. +func NewErrParamMinValue(field string, min float64) *ErrParamMinValue { + return &ErrParamMinValue{ + errInvalidParam: errInvalidParam{ + code: ParamMinValueErrCode, + field: field, + msg: fmt.Sprintf("minimum field value of %v", min), + }, + min: min, + } +} + +// MinValue returns the field's require minimum value. +// +// float64 is returned for both int and float min values. +func (e *ErrParamMinValue) MinValue() float64 { + return e.min +} + +// An ErrParamMinLen represents a minimum length parameter error. +type ErrParamMinLen struct { + errInvalidParam + min int +} + +// NewErrParamMinLen creates a new minimum length parameter error. +func NewErrParamMinLen(field string, min int) *ErrParamMinLen { + return &ErrParamMinLen{ + errInvalidParam: errInvalidParam{ + code: ParamMinValueErrCode, + field: field, + msg: fmt.Sprintf("minimum field size of %v", min), + }, + min: min, + } +} + +// MinLen returns the field's required minimum length. +func (e *ErrParamMinLen) MinLen() int { + return e.min +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go new file mode 100644 index 0000000000..097d3237b3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go @@ -0,0 +1,223 @@ +/* +Package session provides configuration for the SDK's service clients. + +Sessions can be shared across all service clients that share the same base +configuration. The Session is built from the SDK's default configuration and +request handlers. + +Sessions should be cached when possible, because creating a new Session will +load all configuration values from the environment, and config files each time +the Session is created. Sharing the Session value across all of your service +clients will ensure the configuration is loaded the fewest number of times possible. + +Concurrency + +Sessions are safe to use concurrently as long as the Session is not being +modified. The SDK will not modify the Session once the Session has been created. +Creating service clients concurrently from a shared Session is safe. + +Sessions from Shared Config + +Sessions can be created using the method above that will only load the +additional config if the AWS_SDK_LOAD_CONFIG environment variable is set. +Alternatively you can explicitly create a Session with shared config enabled. +To do this you can use NewSessionWithOptions to configure how the Session will +be created. Using the NewSessionWithOptions with SharedConfigState set to +SharedConfigEnabled will create the session as if the AWS_SDK_LOAD_CONFIG +environment variable was set. + +Creating Sessions + +When creating Sessions optional aws.Config values can be passed in that will +override the default, or loaded config values the Session is being created +with. This allows you to provide additional, or case based, configuration +as needed. + +By default NewSession will only load credentials from the shared credentials +file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is +set to a truthy value the Session will be created from the configuration +values from the shared config (~/.aws/config) and shared credentials +(~/.aws/credentials) files. See the section Sessions from Shared Config for +more information. + +Create a Session with the default config and request handlers. With credentials +region, and profile loaded from the environment and shared config automatically. +Requires the AWS_PROFILE to be set, or "default" is used. + + // Create Session + sess, err := session.NewSession() + + // Create a Session with a custom region + sess, err := session.NewSession(&aws.Config{Region: aws.String("us-east-1")}) + + // Create a S3 client instance from a session + sess, err := session.NewSession() + if err != nil { + // Handle Session creation error + } + svc := s3.New(sess) + +Create Session With Option Overrides + +In addition to NewSession, Sessions can be created using NewSessionWithOptions. +This func allows you to control and override how the Session will be created +through code instead of being driven by environment variables only. + +Use NewSessionWithOptions when you want to provide the config profile, or +override the shared config state (AWS_SDK_LOAD_CONFIG). + + // Equivalent to session.New + sess, err := session.NewSessionWithOptions(session.Options{}) + + // Specify profile to load for the session's config + sess, err := session.NewSessionWithOptions(session.Options{ + Profile: "profile_name", + }) + + // Specify profile for config and region for requests + sess, err := session.NewSessionWithOptions(session.Options{ + Config: aws.Config{Region: aws.String("us-east-1")}, + Profile: "profile_name", + }) + + // Force enable Shared Config support + sess, err := session.NewSessionWithOptions(session.Options{ + SharedConfigState: SharedConfigEnable, + }) + +Adding Handlers + +You can add handlers to a session for processing HTTP requests. All service +clients that use the session inherit the handlers. For example, the following +handler logs every request and its payload made by a service client: + + // Create a session, and add additional handlers for all service + // clients created with the Session to inherit. Adds logging handler. + sess, err := session.NewSession() + sess.Handlers.Send.PushFront(func(r *request.Request) { + // Log every request made and its payload + logger.Println("Request: %s/%s, Payload: %s", + r.ClientInfo.ServiceName, r.Operation, r.Params) + }) + +Deprecated "New" function + +The New session function has been deprecated because it does not provide good +way to return errors that occur when loading the configuration files and values. +Because of this, NewSession was created so errors can be retrieved when +creating a session fails. + +Shared Config Fields + +By default the SDK will only load the shared credentials file's (~/.aws/credentials) +credentials values, and all other config is provided by the environment variables, +SDK defaults, and user provided aws.Config values. + +If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable +option is used to create the Session the full shared config values will be +loaded. This includes credentials, region, and support for assume role. In +addition the Session will load its configuration from both the shared config +file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both +files have the same format. + +If both config files are present the configuration from both files will be +read. The Session will be created from configuration values from the shared +credentials file (~/.aws/credentials) over those in the shared credentials +file (~/.aws/config). + +Credentials are the values the SDK should use for authenticating requests with +AWS Services. They arfrom a configuration file will need to include both +aws_access_key_id and aws_secret_access_key must be provided together in the +same file to be considered valid. The values will be ignored if not a complete +group. aws_session_token is an optional field that can be provided if both of +the other two fields are also provided. + + aws_access_key_id = AKID + aws_secret_access_key = SECRET + aws_session_token = TOKEN + +Assume Role values allow you to configure the SDK to assume an IAM role using +a set of credentials provided in a config file via the source_profile field. +Both "role_arn" and "source_profile" are required. The SDK does not support +assuming a role with MFA token Via the Session's constructor. You can use the +stscreds.AssumeRoleProvider credentials provider to specify custom +configuration and support for MFA. + + role_arn = arn:aws:iam:::role/ + source_profile = profile_with_creds + external_id = 1234 + mfa_serial = not supported! + role_session_name = session_name + +Region is the region the SDK should use for looking up AWS service endpoints +and signing requests. + + region = us-east-1 + +Environment Variables + +When a Session is created several environment variables can be set to adjust +how the SDK functions, and what configuration data it loads when creating +Sessions. All environment values are optional, but some values like credentials +require multiple of the values to set or the partial values will be ignored. +All environment variable values are strings unless otherwise noted. + +Environment configuration values. If set both Access Key ID and Secret Access +Key must be provided. Session Token and optionally also be provided, but is +not required. + + # Access Key ID + AWS_ACCESS_KEY_ID=AKID + AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + + # Secret Access Key + AWS_SECRET_ACCESS_KEY=SECRET + AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + + # Session Token + AWS_SESSION_TOKEN=TOKEN + +Region value will instruct the SDK where to make service API requests to. If is +not provided in the environment the region must be provided before a service +client request is made. + + AWS_REGION=us-east-1 + + # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_REGION is not also set. + AWS_DEFAULT_REGION=us-east-1 + +Profile name the SDK should load use when loading shared config from the +configuration files. If not provided "default" will be used as the profile name. + + AWS_PROFILE=my_profile + + # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_PROFILE is not also set. + AWS_DEFAULT_PROFILE=my_profile + +SDK load config instructs the SDK to load the shared config in addition to +shared credentials. This also expands the configuration loaded so the shared +credentials will have parity with the shared config file. This also enables +Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE +env values as well. + + AWS_SDK_LOAD_CONFIG=1 + +Shared credentials file path can be set to instruct the SDK to use an alternative +file for the shared credentials. If not set the file will be loaded from +$HOME/.aws/credentials on Linux/Unix based systems, and +%USERPROFILE%\.aws\credentials on Windows. + + AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + +Shared config file path can be set to instruct the SDK to use an alternative +file for the shared config. If not set the file will be loaded from +$HOME/.aws/config on Linux/Unix based systems, and +%USERPROFILE%\.aws\config on Windows. + + AWS_CONFIG_FILE=$HOME/my_shared_config + + +*/ +package session diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go new file mode 100644 index 0000000000..d2f0c84481 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -0,0 +1,188 @@ +package session + +import ( + "os" + "path/filepath" + "strconv" + + "github.com/aws/aws-sdk-go/aws/credentials" +) + +// envConfig is a collection of environment values the SDK will read +// setup config from. All environment values are optional. But some values +// such as credentials require multiple values to be complete or the values +// will be ignored. +type envConfig struct { + // Environment configuration values. If set both Access Key ID and Secret Access + // Key must be provided. Session Token and optionally also be provided, but is + // not required. + // + // # Access Key ID + // AWS_ACCESS_KEY_ID=AKID + // AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + // + // # Secret Access Key + // AWS_SECRET_ACCESS_KEY=SECRET + // AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + // + // # Session Token + // AWS_SESSION_TOKEN=TOKEN + Creds credentials.Value + + // Region value will instruct the SDK where to make service API requests to. If is + // not provided in the environment the region must be provided before a service + // client request is made. + // + // AWS_REGION=us-east-1 + // + // # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_REGION is not also set. + // AWS_DEFAULT_REGION=us-east-1 + Region string + + // Profile name the SDK should load use when loading shared configuration from the + // shared configuration files. If not provided "default" will be used as the + // profile name. + // + // AWS_PROFILE=my_profile + // + // # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_PROFILE is not also set. + // AWS_DEFAULT_PROFILE=my_profile + Profile string + + // SDK load config instructs the SDK to load the shared config in addition to + // shared credentials. This also expands the configuration loaded from the shared + // credentials to have parity with the shared config file. This also enables + // Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE + // env values as well. + // + // AWS_SDK_LOAD_CONFIG=1 + EnableSharedConfig bool + + // Shared credentials file path can be set to instruct the SDK to use an alternate + // file for the shared credentials. If not set the file will be loaded from + // $HOME/.aws/credentials on Linux/Unix based systems, and + // %USERPROFILE%\.aws\credentials on Windows. + // + // AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + SharedCredentialsFile string + + // Shared config file path can be set to instruct the SDK to use an alternate + // file for the shared config. If not set the file will be loaded from + // $HOME/.aws/config on Linux/Unix based systems, and + // %USERPROFILE%\.aws\config on Windows. + // + // AWS_CONFIG_FILE=$HOME/my_shared_config + SharedConfigFile string +} + +var ( + credAccessEnvKey = []string{ + "AWS_ACCESS_KEY_ID", + "AWS_ACCESS_KEY", + } + credSecretEnvKey = []string{ + "AWS_SECRET_ACCESS_KEY", + "AWS_SECRET_KEY", + } + credSessionEnvKey = []string{ + "AWS_SESSION_TOKEN", + } + + regionEnvKeys = []string{ + "AWS_REGION", + "AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set + } + profileEnvKeys = []string{ + "AWS_PROFILE", + "AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set + } +) + +// loadEnvConfig retrieves the SDK's environment configuration. +// See `envConfig` for the values that will be retrieved. +// +// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value +// the shared SDK config will be loaded in addition to the SDK's specific +// configuration values. +func loadEnvConfig() envConfig { + enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) + return envConfigLoad(enableSharedConfig) +} + +// loadEnvSharedConfig retrieves the SDK's environment configuration, and the +// SDK shared config. See `envConfig` for the values that will be retrieved. +// +// Loads the shared configuration in addition to the SDK's specific configuration. +// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` +// environment variable is set. +func loadSharedEnvConfig() envConfig { + return envConfigLoad(true) +} + +func envConfigLoad(enableSharedConfig bool) envConfig { + cfg := envConfig{} + + cfg.EnableSharedConfig = enableSharedConfig + + setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey) + setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey) + setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey) + + // Require logical grouping of credentials + if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 { + cfg.Creds = credentials.Value{} + } else { + cfg.Creds.ProviderName = "EnvConfigCredentials" + } + + regionKeys := regionEnvKeys + profileKeys := profileEnvKeys + if !cfg.EnableSharedConfig { + regionKeys = regionKeys[:1] + profileKeys = profileKeys[:1] + } + + setFromEnvVal(&cfg.Region, regionKeys) + setFromEnvVal(&cfg.Profile, profileKeys) + + cfg.SharedCredentialsFile = sharedCredentialsFilename() + cfg.SharedConfigFile = sharedConfigFilename() + + return cfg +} + +func setFromEnvVal(dst *string, keys []string) { + for _, k := range keys { + if v := os.Getenv(k); len(v) > 0 { + *dst = v + break + } + } +} + +func sharedCredentialsFilename() string { + if name := os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(name) > 0 { + return name + } + + return filepath.Join(userHomeDir(), ".aws", "credentials") +} + +func sharedConfigFilename() string { + if name := os.Getenv("AWS_CONFIG_FILE"); len(name) > 0 { + return name + } + + return filepath.Join(userHomeDir(), ".aws", "config") +} + +func userHomeDir() string { + homeDir := os.Getenv("HOME") // *nix + if len(homeDir) == 0 { // windows + homeDir = os.Getenv("USERPROFILE") + } + + return homeDir +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go new file mode 100644 index 0000000000..2374b1f273 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go @@ -0,0 +1,388 @@ +package session + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/endpoints" +) + +// A Session provides a central location to create service clients from and +// store configurations and request handlers for those services. +// +// Sessions are safe to create service clients concurrently, but it is not safe +// to mutate the Session concurrently. +// +// The Session satisfies the service client's client.ClientConfigProvider. +type Session struct { + Config *aws.Config + Handlers request.Handlers +} + +// New creates a new instance of the handlers merging in the provided configs +// on top of the SDK's default configurations. Once the Session is created it +// can be mutated to modify the Config or Handlers. The Session is safe to be +// read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New +// method could now encounter an error when loading the configuration. When +// The environment variable is set, and an error occurs, New will return a +// session that will fail all requests reporting the error that occured while +// loading the session. Use NewSession to get the error when creating the +// session. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded, in addition to +// the shared credentials file (~/.aws/config). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. +// +// Deprecated: Use NewSession functiions to create sessions instead. NewSession +// has the same functionality as New except an error can be returned when the +// func is called instead of waiting to receive an error until a request is made. +func New(cfgs ...*aws.Config) *Session { + // load initial config from environment + envCfg := loadEnvConfig() + + if envCfg.EnableSharedConfig { + s, err := newSession(envCfg, cfgs...) + if err != nil { + // Old session.New expected all errors to be discovered when + // a request is made, and would report the errors then. This + // needs to be replicated if an error occurs while creating + // the session. + msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " + + "Use session.NewSession to handle errors occuring during session creation." + + // Session creation failed, need to report the error and prevent + // any requests from succeeding. + s = &Session{Config: defaults.Config()} + s.Config.MergeIn(cfgs...) + s.Config.Logger.Log("ERROR:", msg, "Error:", err) + s.Handlers.Validate.PushBack(func(r *request.Request) { + r.Error = err + }) + } + return s + } + + return oldNewSession(cfgs...) +} + +// NewSession returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. Once the Session is created +// it can be mutated to modify the Config or Handlers. The Session is safe to +// be read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/config). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// See the NewSessionWithOptions func for information on how to override or +// control through code how the Session will be created. Such as specifing the +// config profile, and controlling if shared config is enabled or not. +func NewSession(cfgs ...*aws.Config) (*Session, error) { + envCfg := loadEnvConfig() + + return newSession(envCfg, cfgs...) +} + +// SharedConfigState provides the ability to optionally override the state +// of the session's creation based on the shared config being enabled or +// disabled. +type SharedConfigState int + +const ( + // SharedConfigStateFromEnv does not override any state of the + // AWS_SDK_LOAD_CONFIG env var. It is the default value of the + // SharedConfigState type. + SharedConfigStateFromEnv SharedConfigState = iota + + // SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value + // and disables the shared config functionality. + SharedConfigDisable + + // SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value + // and enables the shared config functionality. + SharedConfigEnable +) + +// Options provides the means to control how a Session is created and what +// configuration values will be loaded. +// +type Options struct { + // Provides config values for the SDK to use when creating service clients + // and making API requests to services. Any value set in with this field + // will override the associated value provided by the SDK defaults, + // environment or config files where relevent. + // + // If not set, configuration values from from SDK defaults, environment, + // config will be used. + Config aws.Config + + // Overrides the config profile the Session should be created from. If not + // set the value of the environment variable will be loaded (AWS_PROFILE, + // or AWS_DEFAULT_PROFILE if the Shared Config is enabled). + // + // If not set and environment variables are not set the "default" + // (DefaultSharedConfigProfile) will be used as the profile to load the + // session config from. + Profile string + + // Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG + // environment variable. By default a Session will be created using the + // value provided by the AWS_SDK_LOAD_CONFIG environment variable. + // + // Setting this value to SharedConfigEnable or SharedConfigDisable + // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable + // and enable or disable the shared config functionality. + SharedConfigState SharedConfigState +} + +// NewSessionWithOptions returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. This func uses the Options +// values to configure how the Session is created. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/config). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// // Equivalent to session.New +// sess, err := session.NewSessionWithOptions(session.Options{}) +// +// // Specify profile to load for the session's config +// sess, err := session.NewSessionWithOptions(session.Options{ +// Profile: "profile_name", +// }) +// +// // Specify profile for config and region for requests +// sess, err := session.NewSessionWithOptions(session.Options{ +// Config: aws.Config{Region: aws.String("us-east-1")}, +// Profile: "profile_name", +// }) +// +// // Force enable Shared Config support +// sess, err := session.NewSessionWithOptions(session.Options{ +// SharedConfigState: SharedConfigEnable, +// }) +func NewSessionWithOptions(opts Options) (*Session, error) { + envCfg := loadEnvConfig() + + if len(opts.Profile) > 0 { + envCfg.Profile = opts.Profile + } + + switch opts.SharedConfigState { + case SharedConfigDisable: + envCfg.EnableSharedConfig = false + case SharedConfigEnable: + envCfg.EnableSharedConfig = true + } + + return newSession(envCfg, &opts.Config) +} + +// Must is a helper function to ensure the Session is valid and there was no +// error when calling a NewSession function. +// +// This helper is intended to be used in variable initialization to load the +// Session and configuration at startup. Such as: +// +// var sess = session.Must(session.NewSession()) +func Must(sess *Session, err error) *Session { + if err != nil { + panic(err) + } + + return sess +} + +func oldNewSession(cfgs ...*aws.Config) *Session { + cfg := defaults.Config() + handlers := defaults.Handlers() + + // Apply the passed in configs so the configuration can be applied to the + // default credential chain + cfg.MergeIn(cfgs...) + cfg.Credentials = defaults.CredChain(cfg, handlers) + + // Reapply any passed in configs to override credentials if set + cfg.MergeIn(cfgs...) + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + + return s +} + +func newSession(envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { + cfg := defaults.Config() + handlers := defaults.Handlers() + + // Get a merged version of the user provided config to determine if + // credentials were. + userCfg := &aws.Config{} + userCfg.MergeIn(cfgs...) + + // Order config files will be loaded in with later files overwriting + // previous config file values. + cfgFiles := []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile} + if !envCfg.EnableSharedConfig { + // The shared config file (~/.aws/config) is only loaded if instructed + // to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG). + cfgFiles = cfgFiles[1:] + } + + // Load additional config from file(s) + sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles) + if err != nil { + return nil, err + } + + mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers) + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + + return s, nil +} + +func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers) { + // Merge in user provided configuration + cfg.MergeIn(userCfg) + + // Region if not already set by user + if len(aws.StringValue(cfg.Region)) == 0 { + if len(envCfg.Region) > 0 { + cfg.WithRegion(envCfg.Region) + } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 { + cfg.WithRegion(sharedCfg.Region) + } + } + + // Configure credentials if not already set + if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { + if len(envCfg.Creds.AccessKeyID) > 0 { + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + envCfg.Creds, + ) + } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil { + cfgCp := *cfg + cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( + sharedCfg.AssumeRoleSource.Creds, + ) + cfg.Credentials = stscreds.NewCredentials( + &Session{ + Config: &cfgCp, + Handlers: handlers.Copy(), + }, + sharedCfg.AssumeRole.RoleARN, + func(opt *stscreds.AssumeRoleProvider) { + opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName + + if len(sharedCfg.AssumeRole.ExternalID) > 0 { + opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) + } + + // MFA not supported + }, + ) + } else if len(sharedCfg.Creds.AccessKeyID) > 0 { + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + sharedCfg.Creds, + ) + } else { + // Fallback to default credentials provider, include mock errors + // for the credential chain so user can identify why credentials + // failed to be retrieved. + cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: []credentials.Provider{ + &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)}, + &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)}, + defaults.RemoteCredProvider(*cfg, handlers), + }, + }) + } + } +} + +type credProviderError struct { + Err error +} + +var emptyCreds = credentials.Value{} + +func (c credProviderError) Retrieve() (credentials.Value, error) { + return credentials.Value{}, c.Err +} +func (c credProviderError) IsExpired() bool { + return true +} + +func initHandlers(s *Session) { + // Add the Validate parameter handler if it is not disabled. + s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) + if !aws.BoolValue(s.Config.DisableParamValidation) { + s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler) + } +} + +// Copy creates and returns a copy of the current Session, coping the config +// and handlers. If any additional configs are provided they will be merged +// on top of the Session's copied config. +// +// // Create a copy of the current Session, configured for the us-west-2 region. +// sess.Copy(&aws.Config{Region: aws.String("us-west-2")}) +func (s *Session) Copy(cfgs ...*aws.Config) *Session { + newSession := &Session{ + Config: s.Config.Copy(cfgs...), + Handlers: s.Handlers.Copy(), + } + + initHandlers(newSession) + + return newSession +} + +// ClientConfig satisfies the client.ConfigProvider interface and is used to +// configure the service client instances. Passing the Session to the service +// client's constructor (New) will use this method to configure the client. +func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { + s = s.Copy(cfgs...) + endpoint, signingRegion := endpoints.NormalizeEndpoint( + aws.StringValue(s.Config.Endpoint), + serviceName, + aws.StringValue(s.Config.Region), + aws.BoolValue(s.Config.DisableSSL), + aws.BoolValue(s.Config.UseDualStack), + ) + + return client.Config{ + Config: s.Config, + Handlers: s.Handlers, + Endpoint: endpoint, + SigningRegion: signingRegion, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go new file mode 100644 index 0000000000..0147eedeb9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go @@ -0,0 +1,294 @@ +package session + +import ( + "fmt" + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/go-ini/ini" +) + +const ( + // Static Credentials group + accessKeyIDKey = `aws_access_key_id` // group required + secretAccessKey = `aws_secret_access_key` // group required + sessionTokenKey = `aws_session_token` // optional + + // Assume Role Credentials group + roleArnKey = `role_arn` // group required + sourceProfileKey = `source_profile` // group required + externalIDKey = `external_id` // optional + mfaSerialKey = `mfa_serial` // optional + roleSessionNameKey = `role_session_name` // optional + + // Additional Config fields + regionKey = `region` + + // DefaultSharedConfigProfile is the default profile to be used when + // loading configuration from the config files if another profile name + // is not provided. + DefaultSharedConfigProfile = `default` +) + +type assumeRoleConfig struct { + RoleARN string + SourceProfile string + ExternalID string + MFASerial string + RoleSessionName string +} + +// sharedConfig represents the configuration fields of the SDK config files. +type sharedConfig struct { + // Credentials values from the config file. Both aws_access_key_id + // and aws_secret_access_key must be provided together in the same file + // to be considered valid. The values will be ignored if not a complete group. + // aws_session_token is an optional field that can be provided if both of the + // other two fields are also provided. + // + // aws_access_key_id + // aws_secret_access_key + // aws_session_token + Creds credentials.Value + + AssumeRole assumeRoleConfig + AssumeRoleSource *sharedConfig + + // Region is the region the SDK should use for looking up AWS service endpoints + // and signing requests. + // + // region + Region string +} + +type sharedConfigFile struct { + Filename string + IniData *ini.File +} + +// loadSharedConfig retrieves the configuration from the list of files +// using the profile provided. The order the files are listed will determine +// precedence. Values in subsequent files will overwrite values defined in +// earlier files. +// +// For example, given two files A and B. Both define credentials. If the order +// of the files are A then B, B's credential values will be used instead of A's. +// +// See sharedConfig.setFromFile for information how the config files +// will be loaded. +func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) { + if len(profile) == 0 { + profile = DefaultSharedConfigProfile + } + + files, err := loadSharedConfigIniFiles(filenames) + if err != nil { + return sharedConfig{}, err + } + + cfg := sharedConfig{} + if err = cfg.setFromIniFiles(profile, files); err != nil { + return sharedConfig{}, err + } + + if len(cfg.AssumeRole.SourceProfile) > 0 { + if err := cfg.setAssumeRoleSource(profile, files); err != nil { + return sharedConfig{}, err + } + } + + return cfg, nil +} + +func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) { + files := make([]sharedConfigFile, 0, len(filenames)) + + for _, filename := range filenames { + if _, err := os.Stat(filename); os.IsNotExist(err) { + // Trim files from the list that don't exist. + continue + } + + f, err := ini.Load(filename) + if err != nil { + return nil, SharedConfigLoadError{Filename: filename} + } + + files = append(files, sharedConfigFile{ + Filename: filename, IniData: f, + }) + } + + return files, nil +} + +func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error { + var assumeRoleSrc sharedConfig + + // Multiple level assume role chains are not support + if cfg.AssumeRole.SourceProfile == origProfile { + assumeRoleSrc = *cfg + assumeRoleSrc.AssumeRole = assumeRoleConfig{} + } else { + err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files) + if err != nil { + return err + } + } + + if len(assumeRoleSrc.Creds.AccessKeyID) == 0 { + return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN} + } + + cfg.AssumeRoleSource = &assumeRoleSrc + + return nil +} + +func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error { + // Trim files from the list that don't exist. + for _, f := range files { + if err := cfg.setFromIniFile(profile, f); err != nil { + if _, ok := err.(SharedConfigProfileNotExistsError); ok { + // Ignore proviles missings + continue + } + return err + } + } + + return nil +} + +// setFromFile loads the configuration from the file using +// the profile provided. A sharedConfig pointer type value is used so that +// multiple config file loadings can be chained. +// +// Only loads complete logically grouped values, and will not set fields in cfg +// for incomplete grouped values in the config. Such as credentials. For example +// if a config file only includes aws_access_key_id but no aws_secret_access_key +// the aws_access_key_id will be ignored. +func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error { + section, err := file.IniData.GetSection(profile) + if err != nil { + // Fallback to to alternate profile name: profile + section, err = file.IniData.GetSection(fmt.Sprintf("profile %s", profile)) + if err != nil { + return SharedConfigProfileNotExistsError{Profile: profile, Err: err} + } + } + + // Shared Credentials + akid := section.Key(accessKeyIDKey).String() + secret := section.Key(secretAccessKey).String() + if len(akid) > 0 && len(secret) > 0 { + cfg.Creds = credentials.Value{ + AccessKeyID: akid, + SecretAccessKey: secret, + SessionToken: section.Key(sessionTokenKey).String(), + ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename), + } + } + + // Assume Role + roleArn := section.Key(roleArnKey).String() + srcProfile := section.Key(sourceProfileKey).String() + if len(roleArn) > 0 && len(srcProfile) > 0 { + cfg.AssumeRole = assumeRoleConfig{ + RoleARN: roleArn, + SourceProfile: srcProfile, + ExternalID: section.Key(externalIDKey).String(), + MFASerial: section.Key(mfaSerialKey).String(), + RoleSessionName: section.Key(roleSessionNameKey).String(), + } + } + + // Region + if v := section.Key(regionKey).String(); len(v) > 0 { + cfg.Region = v + } + + return nil +} + +// SharedConfigLoadError is an error for the shared config file failed to load. +type SharedConfigLoadError struct { + Filename string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigLoadError) Code() string { + return "SharedConfigLoadError" +} + +// Message is the description of the error +func (e SharedConfigLoadError) Message() string { + return fmt.Sprintf("failed to load config file, %s", e.Filename) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigLoadError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigLoadError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigProfileNotExistsError is an error for the shared config when +// the profile was not find in the config file. +type SharedConfigProfileNotExistsError struct { + Profile string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigProfileNotExistsError) Code() string { + return "SharedConfigProfileNotExistsError" +} + +// Message is the description of the error +func (e SharedConfigProfileNotExistsError) Message() string { + return fmt.Sprintf("failed to get profile, %s", e.Profile) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigProfileNotExistsError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigProfileNotExistsError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigAssumeRoleError is an error for the shared config when the +// profile contains assume role information, but that information is invalid +// or not complete. +type SharedConfigAssumeRoleError struct { + RoleARN string +} + +// Code is the short id of the error. +func (e SharedConfigAssumeRoleError) Code() string { + return "SharedConfigAssumeRoleError" +} + +// Message is the description of the error +func (e SharedConfigAssumeRoleError) Message() string { + return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials", + e.RoleARN) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigAssumeRoleError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e SharedConfigAssumeRoleError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go new file mode 100644 index 0000000000..244c86da05 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go @@ -0,0 +1,82 @@ +package v4 + +import ( + "net/http" + "strings" +) + +// validator houses a set of rule needed for validation of a +// string value +type rules []rule + +// rule interface allows for more flexible rules and just simply +// checks whether or not a value adheres to that rule +type rule interface { + IsValid(value string) bool +} + +// IsValid will iterate through all rules and see if any rules +// apply to the value and supports nested rules +func (r rules) IsValid(value string) bool { + for _, rule := range r { + if rule.IsValid(value) { + return true + } + } + return false +} + +// mapRule generic rule for maps +type mapRule map[string]struct{} + +// IsValid for the map rule satisfies whether it exists in the map +func (m mapRule) IsValid(value string) bool { + _, ok := m[value] + return ok +} + +// whitelist is a generic rule for whitelisting +type whitelist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (w whitelist) IsValid(value string) bool { + return w.rule.IsValid(value) +} + +// blacklist is a generic rule for blacklisting +type blacklist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (b blacklist) IsValid(value string) bool { + return !b.rule.IsValid(value) +} + +type patterns []string + +// IsValid for patterns checks each pattern and returns if a match has +// been found +func (p patterns) IsValid(value string) bool { + for _, pattern := range p { + if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) { + return true + } + } + return false +} + +// inclusiveRules rules allow for rules to depend on one another +type inclusiveRules []rule + +// IsValid will return true if all rules are true +func (r inclusiveRules) IsValid(value string) bool { + for _, rule := range r { + if !rule.IsValid(value) { + return false + } + } + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go new file mode 100644 index 0000000000..7d99f54d15 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -0,0 +1,644 @@ +// Package v4 implements signing for AWS V4 signer +// +// Provides request signing for request that need to be signed with +// AWS V4 Signatures. +package v4 + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +const ( + authHeaderPrefix = "AWS4-HMAC-SHA256" + timeFormat = "20060102T150405Z" + shortTimeFormat = "20060102" + + // emptyStringSHA256 is a SHA256 of an empty string + emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` +) + +var ignoredHeaders = rules{ + blacklist{ + mapRule{ + "Authorization": struct{}{}, + "User-Agent": struct{}{}, + }, + }, +} + +// requiredSignedHeaders is a whitelist for build canonical headers. +var requiredSignedHeaders = rules{ + whitelist{ + mapRule{ + "Cache-Control": struct{}{}, + "Content-Disposition": struct{}{}, + "Content-Encoding": struct{}{}, + "Content-Language": struct{}{}, + "Content-Md5": struct{}{}, + "Content-Type": struct{}{}, + "Expires": struct{}{}, + "If-Match": struct{}{}, + "If-Modified-Since": struct{}{}, + "If-None-Match": struct{}{}, + "If-Unmodified-Since": struct{}{}, + "Range": struct{}{}, + "X-Amz-Acl": struct{}{}, + "X-Amz-Copy-Source": struct{}{}, + "X-Amz-Copy-Source-If-Match": struct{}{}, + "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, + "X-Amz-Copy-Source-If-None-Match": struct{}{}, + "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, + "X-Amz-Copy-Source-Range": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Grant-Full-control": struct{}{}, + "X-Amz-Grant-Read": struct{}{}, + "X-Amz-Grant-Read-Acp": struct{}{}, + "X-Amz-Grant-Write": struct{}{}, + "X-Amz-Grant-Write-Acp": struct{}{}, + "X-Amz-Metadata-Directive": struct{}{}, + "X-Amz-Mfa": struct{}{}, + "X-Amz-Request-Payer": struct{}{}, + "X-Amz-Server-Side-Encryption": struct{}{}, + "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Storage-Class": struct{}{}, + "X-Amz-Website-Redirect-Location": struct{}{}, + }, + }, + patterns{"X-Amz-Meta-"}, +} + +// allowedHoisting is a whitelist for build query headers. The boolean value +// represents whether or not it is a pattern. +var allowedQueryHoisting = inclusiveRules{ + blacklist{requiredSignedHeaders}, + patterns{"X-Amz-"}, +} + +// Signer applies AWS v4 signing to given request. Use this to sign requests +// that need to be signed with AWS V4 Signatures. +type Signer struct { + // The authentication credentials the request will be signed against. + // This value must be set to sign requests. + Credentials *credentials.Credentials + + // Sets the log level the signer should use when reporting information to + // the logger. If the logger is nil nothing will be logged. See + // aws.LogLevelType for more information on available logging levels + // + // By default nothing will be logged. + Debug aws.LogLevelType + + // The logger loging information will be written to. If there the logger + // is nil, nothing will be logged. + Logger aws.Logger + + // Disables the Signer's moving HTTP header key/value pairs from the HTTP + // request header to the request's query string. This is most commonly used + // with pre-signed requests preventing headers from being added to the + // request's query string. + DisableHeaderHoisting bool + + // currentTimeFn returns the time value which represents the current time. + // This value should only be used for testing. If it is nil the default + // time.Now will be used. + currentTimeFn func() time.Time +} + +// NewSigner returns a Signer pointer configured with the credentials and optional +// option values provided. If not options are provided the Signer will use its +// default configuration. +func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer { + v4 := &Signer{ + Credentials: credentials, + } + + for _, option := range options { + option(v4) + } + + return v4 +} + +type signingCtx struct { + ServiceName string + Region string + Request *http.Request + Body io.ReadSeeker + Query url.Values + Time time.Time + ExpireTime time.Duration + SignedHeaderVals http.Header + + credValues credentials.Value + isPresign bool + formattedTime string + formattedShortTime string + + bodyDigest string + signedHeaders string + canonicalHeaders string + canonicalString string + credentialString string + stringToSign string + signature string + authorization string +} + +// Sign signs AWS v4 requests with the provided body, service name, region the +// request is made to, and time the request is signed at. The signTime allows +// you to specify that a request is signed for the future, and cannot be +// used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. Generally for signed requests this value +// is not needed as the full request context will be captured by the http.Request +// value. It is included for reference though. +// +// Sign differs from Presign in that it will sign the request using HTTP +// header values. This type of signing is intended for http.Request values that +// will not be shared, or are shared in a way the header values on the request +// will not be lost. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, 0, signTime) +} + +// Presign signs AWS v4 requests with the provided body, service name, region +// the request is made to, and time the request is signed at. The signTime +// allows you to specify that a request is signed for the future, and cannot +// be used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. For presigned requests these headers +// and their values must be included on the HTTP request when it is made. This +// is helpful to know what header values need to be shared with the party the +// presigned request will be distributed to. +// +// Presign differs from Sign in that it will sign the request using query string +// instead of header values. This allows you to share the Presigned Request's +// URL with third parties, or distribute it throughout your system with minimal +// dependencies. +// +// Presign also takes an exp value which is the duration the +// signed request will be valid after the signing time. This is allows you to +// set when the request will expire. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +// +// Presigning a S3 request will not compute the body's SHA256 hash by default. +// This is done due to the general use case for S3 presigned URLs is to share +// PUT/GET capabilities. If you would like to include the body's SHA256 in the +// presigned request's signature you can set the "X-Amz-Content-Sha256" +// HTTP header and that will be included in the request's signature. +func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, exp, signTime) +} + +func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + currentTimeFn := v4.currentTimeFn + if currentTimeFn == nil { + currentTimeFn = time.Now + } + + ctx := &signingCtx{ + Request: r, + Body: body, + Query: r.URL.Query(), + Time: signTime, + ExpireTime: exp, + isPresign: exp != 0, + ServiceName: service, + Region: region, + } + + if ctx.isRequestSigned() { + if !v4.Credentials.IsExpired() && currentTimeFn().Before(ctx.Time.Add(10*time.Minute)) { + // If the request is already signed, and the credentials have not + // expired, and the request is not too old ignore the signing request. + return ctx.SignedHeaderVals, nil + } + ctx.Time = currentTimeFn() + ctx.handlePresignRemoval() + } + + var err error + ctx.credValues, err = v4.Credentials.Get() + if err != nil { + return http.Header{}, err + } + + ctx.assignAmzQueryValues() + ctx.build(v4.DisableHeaderHoisting) + + if v4.Debug.Matches(aws.LogDebugWithSigning) { + v4.logSigningInfo(ctx) + } + + return ctx.SignedHeaderVals, nil +} + +func (ctx *signingCtx) handlePresignRemoval() { + if !ctx.isPresign { + return + } + + // The credentials have expired for this request. The current signing + // is invalid, and needs to be request because the request will fail. + ctx.removePresign() + + // Update the request's query string to ensure the values stays in + // sync in the case retrieving the new credentials fails. + ctx.Request.URL.RawQuery = ctx.Query.Encode() +} + +func (ctx *signingCtx) assignAmzQueryValues() { + if ctx.isPresign { + ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix) + if ctx.credValues.SessionToken != "" { + ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } else { + ctx.Query.Del("X-Amz-Security-Token") + } + + return + } + + if ctx.credValues.SessionToken != "" { + ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } +} + +// SignRequestHandler is a named request handler the SDK will use to sign +// service client request with using the V4 signature. +var SignRequestHandler = request.NamedHandler{ + Name: "v4.SignRequestHandler", Fn: SignSDKRequest, +} + +// SignSDKRequest signs an AWS request with the V4 signature. This +// request handler is bested used only with the SDK's built in service client's +// API operation requests. +// +// This function should not be used on its on its own, but in conjunction with +// an AWS service client's API operation call. To sign a standalone request +// not created by a service client's API operation method use the "Sign" or +// "Presign" functions of the "Signer" type. +// +// If the credentials of the request's config are set to +// credentials.AnonymousCredentials the request will not be signed. +func SignSDKRequest(req *request.Request) { + signSDKRequestWithCurrTime(req, time.Now) +} +func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time) { + // If the request does not need to be signed ignore the signing of the + // request if the AnonymousCredentials object is used. + if req.Config.Credentials == credentials.AnonymousCredentials { + return + } + + region := req.ClientInfo.SigningRegion + if region == "" { + region = aws.StringValue(req.Config.Region) + } + + name := req.ClientInfo.SigningName + if name == "" { + name = req.ClientInfo.ServiceName + } + + v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) { + v4.Debug = req.Config.LogLevel.Value() + v4.Logger = req.Config.Logger + v4.DisableHeaderHoisting = req.NotHoist + v4.currentTimeFn = curTimeFn + }) + + signingTime := req.Time + if !req.LastSignedAt.IsZero() { + signingTime = req.LastSignedAt + } + + signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.Body, name, region, req.ExpireTime, signingTime) + if err != nil { + req.Error = err + req.SignedHeaderVals = nil + return + } + + req.SignedHeaderVals = signedHeaders + req.LastSignedAt = curTimeFn() +} + +const logSignInfoMsg = `DEBUG: Request Signiture: +---[ CANONICAL STRING ]----------------------------- +%s +---[ STRING TO SIGN ]-------------------------------- +%s%s +-----------------------------------------------------` +const logSignedURLMsg = ` +---[ SIGNED URL ]------------------------------------ +%s` + +func (v4 *Signer) logSigningInfo(ctx *signingCtx) { + signedURLMsg := "" + if ctx.isPresign { + signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String()) + } + msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg) + v4.Logger.Log(msg) +} + +func (ctx *signingCtx) build(disableHeaderHoisting bool) { + ctx.buildTime() // no depends + ctx.buildCredentialString() // no depends + + unsignedHeaders := ctx.Request.Header + if ctx.isPresign { + if !disableHeaderHoisting { + urlValues := url.Values{} + urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends + for k := range urlValues { + ctx.Query[k] = urlValues[k] + } + } + } + + ctx.buildBodyDigest() + ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) + ctx.buildCanonicalString() // depends on canon headers / signed headers + ctx.buildStringToSign() // depends on canon string + ctx.buildSignature() // depends on string to sign + + if ctx.isPresign { + ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature + } else { + parts := []string{ + authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, + "SignedHeaders=" + ctx.signedHeaders, + "Signature=" + ctx.signature, + } + ctx.Request.Header.Set("Authorization", strings.Join(parts, ", ")) + } +} + +func (ctx *signingCtx) buildTime() { + ctx.formattedTime = ctx.Time.UTC().Format(timeFormat) + ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat) + + if ctx.isPresign { + duration := int64(ctx.ExpireTime / time.Second) + ctx.Query.Set("X-Amz-Date", ctx.formattedTime) + ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10)) + } else { + ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime) + } +} + +func (ctx *signingCtx) buildCredentialString() { + ctx.credentialString = strings.Join([]string{ + ctx.formattedShortTime, + ctx.Region, + ctx.ServiceName, + "aws4_request", + }, "/") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString) + } +} + +func buildQuery(r rule, header http.Header) (url.Values, http.Header) { + query := url.Values{} + unsignedHeaders := http.Header{} + for k, h := range header { + if r.IsValid(k) { + query[k] = h + } else { + unsignedHeaders[k] = h + } + } + + return query, unsignedHeaders +} +func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { + var headers []string + headers = append(headers, "host") + for k, v := range header { + canonicalKey := http.CanonicalHeaderKey(k) + if !r.IsValid(canonicalKey) { + continue // ignored header + } + if ctx.SignedHeaderVals == nil { + ctx.SignedHeaderVals = make(http.Header) + } + + lowerCaseKey := strings.ToLower(k) + if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok { + // include additional values + ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) + ctx.SignedHeaderVals[lowerCaseKey] = v + } + sort.Strings(headers) + + ctx.signedHeaders = strings.Join(headers, ";") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders) + } + + headerValues := make([]string, len(headers)) + for i, k := range headers { + if k == "host" { + headerValues[i] = "host:" + ctx.Request.URL.Host + } else { + headerValues[i] = k + ":" + + strings.Join(ctx.SignedHeaderVals[k], ",") + } + } + + ctx.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n") +} + +func (ctx *signingCtx) buildCanonicalString() { + ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) + uri := ctx.Request.URL.Opaque + if uri != "" { + uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/") + } else { + uri = ctx.Request.URL.Path + } + if uri == "" { + uri = "/" + } + + if ctx.ServiceName != "s3" { + uri = rest.EscapePath(uri, false) + } + + ctx.canonicalString = strings.Join([]string{ + ctx.Request.Method, + uri, + ctx.Request.URL.RawQuery, + ctx.canonicalHeaders + "\n", + ctx.signedHeaders, + ctx.bodyDigest, + }, "\n") +} + +func (ctx *signingCtx) buildStringToSign() { + ctx.stringToSign = strings.Join([]string{ + authHeaderPrefix, + ctx.formattedTime, + ctx.credentialString, + hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))), + }, "\n") +} + +func (ctx *signingCtx) buildSignature() { + secret := ctx.credValues.SecretAccessKey + date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime)) + region := makeHmac(date, []byte(ctx.Region)) + service := makeHmac(region, []byte(ctx.ServiceName)) + credentials := makeHmac(service, []byte("aws4_request")) + signature := makeHmac(credentials, []byte(ctx.stringToSign)) + ctx.signature = hex.EncodeToString(signature) +} + +func (ctx *signingCtx) buildBodyDigest() { + hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") + if hash == "" { + if ctx.isPresign && ctx.ServiceName == "s3" { + hash = "UNSIGNED-PAYLOAD" + } else if ctx.Body == nil { + hash = emptyStringSHA256 + } else { + hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) + } + if ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" { + ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) + } + } + ctx.bodyDigest = hash +} + +// isRequestSigned returns if the request is currently signed or presigned +func (ctx *signingCtx) isRequestSigned() bool { + if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" { + return true + } + if ctx.Request.Header.Get("Authorization") != "" { + return true + } + + return false +} + +// unsign removes signing flags for both signed and presigned requests. +func (ctx *signingCtx) removePresign() { + ctx.Query.Del("X-Amz-Algorithm") + ctx.Query.Del("X-Amz-Signature") + ctx.Query.Del("X-Amz-Security-Token") + ctx.Query.Del("X-Amz-Date") + ctx.Query.Del("X-Amz-Expires") + ctx.Query.Del("X-Amz-Credential") + ctx.Query.Del("X-Amz-SignedHeaders") +} + +func makeHmac(key []byte, data []byte) []byte { + hash := hmac.New(sha256.New, key) + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256(data []byte) []byte { + hash := sha256.New() + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256Reader(reader io.ReadSeeker) []byte { + hash := sha256.New() + start, _ := reader.Seek(0, 1) + defer reader.Seek(start, 0) + + io.Copy(hash, reader) + return hash.Sum(nil) +} + +const doubleSpaces = " " + +var doubleSpaceBytes = []byte(doubleSpaces) + +func stripExcessSpaces(headerVals []string) []string { + vals := make([]string, len(headerVals)) + for i, str := range headerVals { + // Trim leading and trailing spaces + trimmed := strings.TrimSpace(str) + + idx := strings.Index(trimmed, doubleSpaces) + var buf []byte + for idx > -1 { + // Multiple adjacent spaces found + if buf == nil { + // first time create the buffer + buf = []byte(trimmed) + } + + stripToIdx := -1 + for j := idx + 1; j < len(buf); j++ { + if buf[j] != ' ' { + buf = append(buf[:idx+1], buf[j:]...) + stripToIdx = j + break + } + } + + if stripToIdx >= 0 { + idx = bytes.Index(buf[stripToIdx:], doubleSpaceBytes) + if idx >= 0 { + idx += stripToIdx + } + } else { + idx = -1 + } + } + + if buf != nil { + vals[i] = string(buf) + } else { + vals[i] = trimmed + } + } + return vals +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/types.go b/vendor/github.com/aws/aws-sdk-go/aws/types.go new file mode 100644 index 0000000000..fa014b49e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/types.go @@ -0,0 +1,106 @@ +package aws + +import ( + "io" + "sync" +) + +// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser +func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { + return ReaderSeekerCloser{r} +} + +// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and +// io.Closer interfaces to the underlying object if they are available. +type ReaderSeekerCloser struct { + r io.Reader +} + +// Read reads from the reader up to size of p. The number of bytes read, and +// error if it occurred will be returned. +// +// If the reader is not an io.Reader zero bytes read, and nil error will be returned. +// +// Performs the same functionality as io.Reader Read +func (r ReaderSeekerCloser) Read(p []byte) (int, error) { + switch t := r.r.(type) { + case io.Reader: + return t.Read(p) + } + return 0, nil +} + +// Seek sets the offset for the next Read to offset, interpreted according to +// whence: 0 means relative to the origin of the file, 1 means relative to the +// current offset, and 2 means relative to the end. Seek returns the new offset +// and an error, if any. +// +// If the ReaderSeekerCloser is not an io.Seeker nothing will be done. +func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) { + switch t := r.r.(type) { + case io.Seeker: + return t.Seek(offset, whence) + } + return int64(0), nil +} + +// Close closes the ReaderSeekerCloser. +// +// If the ReaderSeekerCloser is not an io.Closer nothing will be done. +func (r ReaderSeekerCloser) Close() error { + switch t := r.r.(type) { + case io.Closer: + return t.Close() + } + return nil +} + +// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface +// Can be used with the s3manager.Downloader to download content to a buffer +// in memory. Safe to use concurrently. +type WriteAtBuffer struct { + buf []byte + m sync.Mutex + + // GrowthCoeff defines the growth rate of the internal buffer. By + // default, the growth rate is 1, where expanding the internal + // buffer will allocate only enough capacity to fit the new expected + // length. + GrowthCoeff float64 +} + +// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer +// provided by buf. +func NewWriteAtBuffer(buf []byte) *WriteAtBuffer { + return &WriteAtBuffer{buf: buf} +} + +// WriteAt writes a slice of bytes to a buffer starting at the position provided +// The number of bytes written will be returned, or error. Can overwrite previous +// written slices if the write ats overlap. +func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) { + pLen := len(p) + expLen := pos + int64(pLen) + b.m.Lock() + defer b.m.Unlock() + if int64(len(b.buf)) < expLen { + if int64(cap(b.buf)) < expLen { + if b.GrowthCoeff < 1 { + b.GrowthCoeff = 1 + } + newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen))) + copy(newBuf, b.buf) + b.buf = newBuf + } + b.buf = b.buf[:expLen] + } + copy(b.buf[pos:], p) + return pLen, nil +} + +// Bytes returns a slice of bytes written to the buffer. +func (b *WriteAtBuffer) Bytes() []byte { + b.m.Lock() + defer b.m.Unlock() + return b.buf[:len(b.buf):len(b.buf)] +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go new file mode 100644 index 0000000000..750a7f4756 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -0,0 +1,8 @@ +// Package aws provides core functionality for making requests to AWS services. +package aws + +// SDKName is the name of this AWS SDK +const SDKName = "aws-sdk-go" + +// SDKVersion is the version of this SDK +const SDKVersion = "1.4.10" diff --git a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go new file mode 100644 index 0000000000..b4ad7405c6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go @@ -0,0 +1,70 @@ +// Package endpoints validates regional endpoints for services. +package endpoints + +//go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go +//go:generate gofmt -s -w endpoints_map.go + +import ( + "fmt" + "regexp" + "strings" +) + +// NormalizeEndpoint takes and endpoint and service API information to return a +// normalized endpoint and signing region. If the endpoint is not an empty string +// the service name and region will be used to look up the service's API endpoint. +// If the endpoint is provided the scheme will be added if it is not present. +func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL, useDualStack bool) (normEndpoint, signingRegion string) { + if endpoint == "" { + return EndpointForRegion(serviceName, region, disableSSL, useDualStack) + } + + return AddScheme(endpoint, disableSSL), "" +} + +// EndpointForRegion returns an endpoint and its signing region for a service and region. +// if the service and region pair are not found endpoint and signingRegion will be empty. +func EndpointForRegion(svcName, region string, disableSSL, useDualStack bool) (endpoint, signingRegion string) { + dualStackField := "" + if useDualStack { + dualStackField = "/dualstack" + } + + derivedKeys := []string{ + region + "/" + svcName + dualStackField, + region + "/*" + dualStackField, + "*/" + svcName + dualStackField, + "*/*" + dualStackField, + } + + for _, key := range derivedKeys { + if val, ok := endpointsMap.Endpoints[key]; ok { + ep := val.Endpoint + ep = strings.Replace(ep, "{region}", region, -1) + ep = strings.Replace(ep, "{service}", svcName, -1) + + endpoint = ep + signingRegion = val.SigningRegion + break + } + } + + return AddScheme(endpoint, disableSSL), signingRegion +} + +// Regular expression to determine if the endpoint string is prefixed with a scheme. +var schemeRE = regexp.MustCompile("^([^:]+)://") + +// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no +// scheme. If disableSSL is true HTTP will be added instead of the default HTTPS. +func AddScheme(endpoint string, disableSSL bool) string { + if endpoint != "" && !schemeRE.MatchString(endpoint) { + scheme := "https" + if disableSSL { + scheme = "http" + } + endpoint = fmt.Sprintf("%s://%s", scheme, endpoint) + } + + return endpoint +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json new file mode 100644 index 0000000000..c5bf3c7c35 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json @@ -0,0 +1,78 @@ +{ + "version": 2, + "endpoints": { + "*/*": { + "endpoint": "{service}.{region}.amazonaws.com" + }, + "cn-north-1/*": { + "endpoint": "{service}.{region}.amazonaws.com.cn", + "signatureVersion": "v4" + }, + "cn-north-1/ec2metadata": { + "endpoint": "http://169.254.169.254/latest" + }, + "us-gov-west-1/iam": { + "endpoint": "iam.us-gov.amazonaws.com" + }, + "us-gov-west-1/sts": { + "endpoint": "sts.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1/s3": { + "endpoint": "s3-{region}.amazonaws.com" + }, + "us-gov-west-1/ec2metadata": { + "endpoint": "http://169.254.169.254/latest" + }, + "*/cloudfront": { + "endpoint": "cloudfront.amazonaws.com", + "signingRegion": "us-east-1" + }, + "*/cloudsearchdomain": { + "endpoint": "", + "signingRegion": "us-east-1" + }, + "*/data.iot": { + "endpoint": "", + "signingRegion": "us-east-1" + }, + "*/ec2metadata": { + "endpoint": "http://169.254.169.254/latest" + }, + "*/iam": { + "endpoint": "iam.amazonaws.com", + "signingRegion": "us-east-1" + }, + "*/importexport": { + "endpoint": "importexport.amazonaws.com", + "signingRegion": "us-east-1" + }, + "*/route53": { + "endpoint": "route53.amazonaws.com", + "signingRegion": "us-east-1" + }, + "*/sts": { + "endpoint": "sts.amazonaws.com", + "signingRegion": "us-east-1" + }, + "*/waf": { + "endpoint": "waf.amazonaws.com", + "signingRegion": "us-east-1" + }, + "us-east-1/sdb": { + "endpoint": "sdb.amazonaws.com", + "signingRegion": "us-east-1" + }, + "*/s3": { + "endpoint": "s3-{region}.amazonaws.com" + }, + "*/s3/dualstack": { + "endpoint": "s3.dualstack.{region}.amazonaws.com" + }, + "us-east-1/s3": { + "endpoint": "s3.amazonaws.com" + }, + "eu-central-1/s3": { + "endpoint": "{service}.{region}.amazonaws.com" + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go new file mode 100644 index 0000000000..a81d158c3d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go @@ -0,0 +1,91 @@ +package endpoints + +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +type endpointStruct struct { + Version int + Endpoints map[string]endpointEntry +} + +type endpointEntry struct { + Endpoint string + SigningRegion string +} + +var endpointsMap = endpointStruct{ + Version: 2, + Endpoints: map[string]endpointEntry{ + "*/*": { + Endpoint: "{service}.{region}.amazonaws.com", + }, + "*/cloudfront": { + Endpoint: "cloudfront.amazonaws.com", + SigningRegion: "us-east-1", + }, + "*/cloudsearchdomain": { + Endpoint: "", + SigningRegion: "us-east-1", + }, + "*/data.iot": { + Endpoint: "", + SigningRegion: "us-east-1", + }, + "*/ec2metadata": { + Endpoint: "http://169.254.169.254/latest", + }, + "*/iam": { + Endpoint: "iam.amazonaws.com", + SigningRegion: "us-east-1", + }, + "*/importexport": { + Endpoint: "importexport.amazonaws.com", + SigningRegion: "us-east-1", + }, + "*/route53": { + Endpoint: "route53.amazonaws.com", + SigningRegion: "us-east-1", + }, + "*/s3": { + Endpoint: "s3-{region}.amazonaws.com", + }, + "*/s3/dualstack": { + Endpoint: "s3.dualstack.{region}.amazonaws.com", + }, + "*/sts": { + Endpoint: "sts.amazonaws.com", + SigningRegion: "us-east-1", + }, + "*/waf": { + Endpoint: "waf.amazonaws.com", + SigningRegion: "us-east-1", + }, + "cn-north-1/*": { + Endpoint: "{service}.{region}.amazonaws.com.cn", + }, + "cn-north-1/ec2metadata": { + Endpoint: "http://169.254.169.254/latest", + }, + "eu-central-1/s3": { + Endpoint: "{service}.{region}.amazonaws.com", + }, + "us-east-1/s3": { + Endpoint: "s3.amazonaws.com", + }, + "us-east-1/sdb": { + Endpoint: "sdb.amazonaws.com", + SigningRegion: "us-east-1", + }, + "us-gov-west-1/ec2metadata": { + Endpoint: "http://169.254.169.254/latest", + }, + "us-gov-west-1/iam": { + Endpoint: "iam.us-gov.amazonaws.com", + }, + "us-gov-west-1/s3": { + Endpoint: "s3-{region}.amazonaws.com", + }, + "us-gov-west-1/sts": { + Endpoint: "sts.us-gov-west-1.amazonaws.com", + }, + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go new file mode 100644 index 0000000000..bb0dae97a9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go @@ -0,0 +1,35 @@ +// Package ec2query provides serialization of AWS EC2 requests and responses. +package ec2query + +//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/ec2.json build_test.go + +import ( + "net/url" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/query/queryutil" +) + +// BuildHandler is a named request handler for building ec2query protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.ec2query.Build", Fn: Build} + +// Build builds a request for the EC2 protocol. +func Build(r *request.Request) { + body := url.Values{ + "Action": {r.Operation.Name}, + "Version": {r.ClientInfo.APIVersion}, + } + if err := queryutil.Parse(body, r.Params, true); err != nil { + r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err) + } + + if r.ExpireTime == 0 { + r.HTTPRequest.Method = "POST" + r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + r.SetBufferBody([]byte(body.Encode())) + } else { // This is a pre-signed request + r.HTTPRequest.Method = "GET" + r.HTTPRequest.URL.RawQuery = body.Encode() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/unmarshal.go new file mode 100644 index 0000000000..631e63c0b5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/unmarshal.go @@ -0,0 +1,63 @@ +package ec2query + +//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/ec2.json unmarshal_test.go + +import ( + "encoding/xml" + "io" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// UnmarshalHandler is a named request handler for unmarshaling ec2query protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.ec2query.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling ec2query protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.ec2query.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling ec2query protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.ec2query.UnmarshalError", Fn: UnmarshalError} + +// Unmarshal unmarshals a response body for the EC2 protocol. +func Unmarshal(r *request.Request) { + defer r.HTTPResponse.Body.Close() + if r.DataFilled() { + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, "") + if err != nil { + r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err) + return + } + } +} + +// UnmarshalMeta unmarshals response headers for the EC2 protocol. +func UnmarshalMeta(r *request.Request) { + // TODO implement unmarshaling of request IDs +} + +type xmlErrorResponse struct { + XMLName xml.Name `xml:"Response"` + Code string `xml:"Errors>Error>Code"` + Message string `xml:"Errors>Error>Message"` + RequestID string `xml:"RequestID"` +} + +// UnmarshalError unmarshals a response error for the EC2 protocol. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + resp := &xmlErrorResponse{} + err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) + if err != nil && err != io.EOF { + r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err) + } else { + r.Error = awserr.NewRequestFailure( + awserr.New(resp.Code, resp.Message, nil), + r.HTTPResponse.StatusCode, + resp.RequestID, + ) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go new file mode 100644 index 0000000000..53831dff98 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "crypto/rand" + "fmt" + "reflect" +) + +// RandReader is the random reader the protocol package will use to read +// random bytes from. This is exported for testing, and should not be used. +var RandReader = rand.Reader + +const idempotencyTokenFillTag = `idempotencyToken` + +// CanSetIdempotencyToken returns true if the struct field should be +// automatically populated with a Idempotency token. +// +// Only *string and string type fields that are tagged with idempotencyToken +// which are not already set can be auto filled. +func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool { + switch u := v.Interface().(type) { + // To auto fill an Idempotency token the field must be a string, + // tagged for auto fill, and have a zero value. + case *string: + return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + case string: + return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + } + + return false +} + +// GetIdempotencyToken returns a randomly generated idempotency token. +func GetIdempotencyToken() string { + b := make([]byte, 16) + RandReader.Read(b) + + return UUIDVersion4(b) +} + +// SetIdempotencyToken will set the value provided with a Idempotency Token. +// Given that the value can be set. Will panic if value is not setable. +func SetIdempotencyToken(v reflect.Value) { + if v.Kind() == reflect.Ptr { + if v.IsNil() && v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = reflect.Indirect(v) + + if !v.CanSet() { + panic(fmt.Sprintf("unable to set idempotnecy token %v", v)) + } + + b := make([]byte, 16) + _, err := rand.Read(b) + if err != nil { + // TODO handle error + return + } + + v.Set(reflect.ValueOf(UUIDVersion4(b))) +} + +// UUIDVersion4 returns a Version 4 random UUID from the byte slice provided +func UUIDVersion4(u []byte) string { + // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 + // 13th character is "4" + u[6] = (u[6] | 0x40) & 0x4F + // 17th character is "8", "9", "a", or "b" + u[8] = (u[8] | 0x80) & 0xBF + + return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go new file mode 100644 index 0000000000..c705481c3c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go @@ -0,0 +1,36 @@ +// Package query provides serialization of AWS query requests, and responses. +package query + +//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go + +import ( + "net/url" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/query/queryutil" +) + +// BuildHandler is a named request handler for building query protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build} + +// Build builds a request for an AWS Query service. +func Build(r *request.Request) { + body := url.Values{ + "Action": {r.Operation.Name}, + "Version": {r.ClientInfo.APIVersion}, + } + if err := queryutil.Parse(body, r.Params, false); err != nil { + r.Error = awserr.New("SerializationError", "failed encoding Query request", err) + return + } + + if r.ExpireTime == 0 { + r.HTTPRequest.Method = "POST" + r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + r.SetBufferBody([]byte(body.Encode())) + } else { // This is a pre-signed request + r.HTTPRequest.Method = "GET" + r.HTTPRequest.URL.RawQuery = body.Encode() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go new file mode 100644 index 0000000000..60ea0bd1e5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go @@ -0,0 +1,230 @@ +package queryutil + +import ( + "encoding/base64" + "fmt" + "net/url" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/private/protocol" +) + +// Parse parses an object i and fills a url.Values object. The isEC2 flag +// indicates if this is the EC2 Query sub-protocol. +func Parse(body url.Values, i interface{}, isEC2 bool) error { + q := queryParser{isEC2: isEC2} + return q.parseValue(body, reflect.ValueOf(i), "", "") +} + +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +type queryParser struct { + isEC2 bool +} + +func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + value = elemOf(value) + + // no need to handle zero values + if !value.IsValid() { + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + return q.parseStruct(v, value, prefix) + case "list": + return q.parseList(v, value, prefix, tag) + case "map": + return q.parseMap(v, value, prefix, tag) + default: + return q.parseScalar(v, value, prefix, tag) + } +} + +func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error { + if !value.IsValid() { + return nil + } + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + elemValue := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + elemValue = reflect.ValueOf(token) + } + + var name string + if q.isEC2 { + name = field.Tag.Get("queryName") + } + if name == "" { + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + if name != "" && q.isEC2 { + name = strings.ToUpper(name[0:1]) + name[1:] + } + } + if name == "" { + name = field.Name + } + + if prefix != "" { + name = prefix + "." + name + } + + if err := q.parseValue(v, elemValue, name, field.Tag); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + prefix += ".member" + } + + for i := 0; i < value.Len(); i++ { + slicePrefix := prefix + if slicePrefix == "" { + slicePrefix = strconv.Itoa(i + 1) + } else { + slicePrefix = slicePrefix + "." + strconv.Itoa(i+1) + } + if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + prefix += ".entry" + } + + // sort keys for improved serialization consistency. + // this is not strictly necessary for protocol support. + mapKeyValues := value.MapKeys() + mapKeys := map[string]reflect.Value{} + mapKeyNames := make([]string, len(mapKeyValues)) + for i, mapKey := range mapKeyValues { + name := mapKey.String() + mapKeys[name] = mapKey + mapKeyNames[i] = name + } + sort.Strings(mapKeyNames) + + for i, mapKeyName := range mapKeyNames { + mapKey := mapKeys[mapKeyName] + mapValue := value.MapIndex(mapKey) + + kname := tag.Get("locationNameKey") + if kname == "" { + kname = "key" + } + vname := tag.Get("locationNameValue") + if vname == "" { + vname = "value" + } + + // serialize key + var keyName string + if prefix == "" { + keyName = strconv.Itoa(i+1) + "." + kname + } else { + keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname + } + + if err := q.parseValue(v, mapKey, keyName, ""); err != nil { + return err + } + + // serialize value + var valueName string + if prefix == "" { + valueName = strconv.Itoa(i+1) + "." + vname + } else { + valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname + } + + if err := q.parseValue(v, mapValue, valueName, ""); err != nil { + return err + } + } + + return nil +} + +func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error { + switch value := r.Interface().(type) { + case string: + v.Set(name, value) + case []byte: + if !r.IsNil() { + v.Set(name, base64.StdEncoding.EncodeToString(value)) + } + case bool: + v.Set(name, strconv.FormatBool(value)) + case int64: + v.Set(name, strconv.FormatInt(value, 10)) + case int: + v.Set(name, strconv.Itoa(value)) + case float64: + v.Set(name, strconv.FormatFloat(value, 'f', -1, 64)) + case float32: + v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32)) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + v.Set(name, value.UTC().Format(ISO8601UTC)) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go new file mode 100644 index 0000000000..a3ea40955d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go @@ -0,0 +1,35 @@ +package query + +//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go + +import ( + "encoding/xml" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// UnmarshalHandler is a named request handler for unmarshaling query protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals a response for an AWS Query service. +func Unmarshal(r *request.Request) { + defer r.HTTPResponse.Body.Close() + if r.DataFilled() { + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") + if err != nil { + r.Error = awserr.New("SerializationError", "failed decoding Query response", err) + return + } + } +} + +// UnmarshalMeta unmarshals header response values for an AWS Query service. +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go new file mode 100644 index 0000000000..f214296171 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go @@ -0,0 +1,66 @@ +package query + +import ( + "encoding/xml" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +type xmlErrorResponse struct { + XMLName xml.Name `xml:"ErrorResponse"` + Code string `xml:"Error>Code"` + Message string `xml:"Error>Message"` + RequestID string `xml:"RequestId"` +} + +type xmlServiceUnavailableResponse struct { + XMLName xml.Name `xml:"ServiceUnavailableException"` +} + +// UnmarshalErrorHandler is a name request handler to unmarshal request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError} + +// UnmarshalError unmarshals an error response for an AWS Query service. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err) + return + } + + // First check for specific error + resp := xmlErrorResponse{} + decodeErr := xml.Unmarshal(bodyBytes, &resp) + if decodeErr == nil { + reqID := resp.RequestID + if reqID == "" { + reqID = r.RequestID + } + r.Error = awserr.NewRequestFailure( + awserr.New(resp.Code, resp.Message, nil), + r.HTTPResponse.StatusCode, + reqID, + ) + return + } + + // Check for unhandled error + servUnavailResp := xmlServiceUnavailableResponse{} + unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp) + if unavailErr == nil { + r.Error = awserr.NewRequestFailure( + awserr.New("ServiceUnavailableException", "service is unavailable", nil), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + // Failed to retrieve any error message from the response body + r.Error = awserr.New("SerializationError", + "failed to decode query XML error response", decodeErr) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go new file mode 100644 index 0000000000..5f412516dc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go @@ -0,0 +1,256 @@ +// Package rest provides RESTful serialization of AWS requests and responses. +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/url" + "path" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// RFC822 returns an RFC822 formatted timestamp for AWS protocols +const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT" + +// Whether the byte value can be sent without escaping in AWS URLs +var noEscape [256]bool + +var errValueNotSet = fmt.Errorf("value not set") + +func init() { + for i := 0; i < len(noEscape); i++ { + // AWS expects every character except these to be escaped + noEscape[i] = (i >= 'A' && i <= 'Z') || + (i >= 'a' && i <= 'z') || + (i >= '0' && i <= '9') || + i == '-' || + i == '.' || + i == '_' || + i == '~' + } +} + +// BuildHandler is a named request handler for building rest protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build} + +// Build builds the REST component of a service request. +func Build(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v) + buildBody(r, v) + } +} + +func buildLocationElements(r *request.Request, v reflect.Value) { + query := r.HTTPRequest.URL.Query() + + for i := 0; i < v.NumField(); i++ { + m := v.Field(i) + if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + field := v.Type().Field(i) + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + if m.Kind() == reflect.Ptr { + m = m.Elem() + } + if !m.IsValid() { + continue + } + + var err error + switch field.Tag.Get("location") { + case "headers": // header maps + err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag.Get("locationName")) + case "header": + err = buildHeader(&r.HTTPRequest.Header, m, name) + case "uri": + err = buildURI(r.HTTPRequest.URL, m, name) + case "querystring": + err = buildQueryString(query, m, name) + } + r.Error = err + } + if r.Error != nil { + return + } + } + + r.HTTPRequest.URL.RawQuery = query.Encode() + updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path) +} + +func buildBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := reflect.Indirect(v.FieldByName(payloadName)) + if payload.IsValid() && payload.Interface() != nil { + switch reader := payload.Interface().(type) { + case io.ReadSeeker: + r.SetReaderBody(reader) + case []byte: + r.SetBufferBody(reader) + case string: + r.SetStringBody(reader) + default: + r.Error = awserr.New("SerializationError", + "failed to encode REST request", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } +} + +func buildHeader(header *http.Header, v reflect.Value, name string) error { + str, err := convertType(v) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + } + + header.Add(name, str) + + return nil +} + +func buildHeaderMap(header *http.Header, v reflect.Value, prefix string) error { + for _, key := range v.MapKeys() { + str, err := convertType(v.MapIndex(key)) + if err == errValueNotSet { + continue + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + + } + + header.Add(prefix+key.String(), str) + } + return nil +} + +func buildURI(u *url.URL, v reflect.Value, name string) error { + value, err := convertType(v) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + } + + uri := u.Path + uri = strings.Replace(uri, "{"+name+"}", EscapePath(value, true), -1) + uri = strings.Replace(uri, "{"+name+"+}", EscapePath(value, false), -1) + u.Path = uri + + return nil +} + +func buildQueryString(query url.Values, v reflect.Value, name string) error { + switch value := v.Interface().(type) { + case []*string: + for _, item := range value { + query.Add(name, *item) + } + case map[string]*string: + for key, item := range value { + query.Add(key, *item) + } + case map[string][]*string: + for key, items := range value { + for _, item := range items { + query.Add(key, *item) + } + } + default: + str, err := convertType(v) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + } + query.Set(name, str) + } + + return nil +} + +func updatePath(url *url.URL, urlPath string) { + scheme, query := url.Scheme, url.RawQuery + + hasSlash := strings.HasSuffix(urlPath, "/") + + // clean up path + urlPath = path.Clean(urlPath) + if hasSlash && !strings.HasSuffix(urlPath, "/") { + urlPath += "/" + } + + // get formatted URL minus scheme so we can build this into Opaque + url.Scheme, url.Path, url.RawQuery = "", "", "" + s := url.String() + url.Scheme = scheme + url.RawQuery = query + + // build opaque URI + url.Opaque = s + urlPath +} + +// EscapePath escapes part of a URL path in Amazon style +func EscapePath(path string, encodeSep bool) string { + var buf bytes.Buffer + for i := 0; i < len(path); i++ { + c := path[i] + if noEscape[c] || (c == '/' && !encodeSep) { + buf.WriteByte(c) + } else { + fmt.Fprintf(&buf, "%%%02X", c) + } + } + return buf.String() +} + +func convertType(v reflect.Value) (string, error) { + v = reflect.Indirect(v) + if !v.IsValid() { + return "", errValueNotSet + } + + var str string + switch value := v.Interface().(type) { + case string: + str = value + case []byte: + str = base64.StdEncoding.EncodeToString(value) + case bool: + str = strconv.FormatBool(value) + case int64: + str = strconv.FormatInt(value, 10) + case float64: + str = strconv.FormatFloat(value, 'f', -1, 64) + case time.Time: + str = value.UTC().Format(RFC822) + default: + err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + return "", err + } + return str, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go new file mode 100644 index 0000000000..4366de2e1e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go @@ -0,0 +1,45 @@ +package rest + +import "reflect" + +// PayloadMember returns the payload field member of i if there is one, or nil. +func PayloadMember(i interface{}) interface{} { + if i == nil { + return nil + } + + v := reflect.ValueOf(i).Elem() + if !v.IsValid() { + return nil + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + field, _ := v.Type().FieldByName(payloadName) + if field.Tag.Get("type") != "structure" { + return nil + } + + payload := v.FieldByName(payloadName) + if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { + return payload.Interface() + } + } + } + return nil +} + +// PayloadType returns the type of a payload field member of i if there is one, or "". +func PayloadType(i interface{}) string { + v := reflect.Indirect(reflect.ValueOf(i)) + if !v.IsValid() { + return "" + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + if member, ok := v.Type().FieldByName(payloadName); ok { + return member.Tag.Get("type") + } + } + } + return "" +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go new file mode 100644 index 0000000000..2cba1d9aa7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go @@ -0,0 +1,198 @@ +package rest + +import ( + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals the REST component of a response in a REST service. +func Unmarshal(r *request.Request) { + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalBody(r, v) + } +} + +// UnmarshalMeta unmarshals the REST metadata of a response in a REST service +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") + if r.RequestID == "" { + // Alternative version of request id in the header + r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") + } + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalLocationElements(r, v) + } +} + +func unmarshalBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := v.FieldByName(payloadName) + if payload.IsValid() { + switch payload.Interface().(type) { + case []byte: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + } else { + payload.Set(reflect.ValueOf(b)) + } + case *string: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + } else { + str := string(b) + payload.Set(reflect.ValueOf(&str)) + } + default: + switch payload.Type().String() { + case "io.ReadSeeker": + payload.Set(reflect.ValueOf(aws.ReadSeekCloser(r.HTTPResponse.Body))) + case "aws.ReadSeekCloser", "io.ReadCloser": + payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) + default: + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + defer r.HTTPResponse.Body.Close() + r.Error = awserr.New("SerializationError", + "failed to decode REST response", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } + } +} + +func unmarshalLocationElements(r *request.Request, v reflect.Value) { + for i := 0; i < v.NumField(); i++ { + m, field := v.Field(i), v.Type().Field(i) + if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + + switch field.Tag.Get("location") { + case "statusCode": + unmarshalStatusCode(m, r.HTTPResponse.StatusCode) + case "header": + err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name)) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + break + } + case "headers": + prefix := field.Tag.Get("locationName") + err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + break + } + } + } + if r.Error != nil { + return + } + } +} + +func unmarshalStatusCode(v reflect.Value, statusCode int) { + if !v.IsValid() { + return + } + + switch v.Interface().(type) { + case *int64: + s := int64(statusCode) + v.Set(reflect.ValueOf(&s)) + } +} + +func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error { + switch r.Interface().(type) { + case map[string]*string: // we only support string map value types + out := map[string]*string{} + for k, v := range headers { + k = http.CanonicalHeaderKey(k) + if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) { + out[k[len(prefix):]] = &v[0] + } + } + r.Set(reflect.ValueOf(out)) + } + return nil +} + +func unmarshalHeader(v reflect.Value, header string) error { + if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) { + return nil + } + + switch v.Interface().(type) { + case *string: + v.Set(reflect.ValueOf(&header)) + case []byte: + b, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *bool: + b, err := strconv.ParseBool(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *int64: + i, err := strconv.ParseInt(header, 10, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&i)) + case *float64: + f, err := strconv.ParseFloat(header, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&f)) + case *time.Time: + t, err := time.Parse(RFC822, header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&t)) + default: + err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go new file mode 100644 index 0000000000..da1a68111d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go @@ -0,0 +1,21 @@ +package protocol + +import ( + "io" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body +var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} + +// UnmarshalDiscardBody is a request handler to empty a response's body and closing it. +func UnmarshalDiscardBody(r *request.Request) { + if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { + return + } + + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + r.HTTPResponse.Body.Close() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go new file mode 100644 index 0000000000..221029baff --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go @@ -0,0 +1,293 @@ +// Package xmlutil provides XML serialization of AWS requests and responses. +package xmlutil + +import ( + "encoding/base64" + "encoding/xml" + "fmt" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/private/protocol" +) + +// BuildXML will serialize params into an xml.Encoder. +// Error will be returned if the serialization of any of the params or nested values fails. +func BuildXML(params interface{}, e *xml.Encoder) error { + b := xmlBuilder{encoder: e, namespaces: map[string]string{}} + root := NewXMLElement(xml.Name{}) + if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil { + return err + } + for _, c := range root.Children { + for _, v := range c { + return StructToXML(e, v, false) + } + } + return nil +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +// A xmlBuilder serializes values from Go code to XML +type xmlBuilder struct { + encoder *xml.Encoder + namespaces map[string]string +} + +// buildValue generic XMLNode builder for any type. Will build value for their specific type +// struct, list, map, scalar. +// +// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If +// type is not provided reflect will be used to determine the value's type. +func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + value = elemOf(value) + if !value.IsValid() { // no need to handle zero values + return nil + } else if tag.Get("location") != "" { // don't handle non-body location values + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := value.Type().FieldByName("_"); ok { + tag = tag + reflect.StructTag(" ") + field.Tag + } + return b.buildStruct(value, current, tag) + case "list": + return b.buildList(value, current, tag) + case "map": + return b.buildMap(value, current, tag) + default: + return b.buildScalar(value, current, tag) + } +} + +// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested +// types are converted to XMLNodes also. +func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + fieldAdded := false + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + child := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + + // there is an xmlNamespace associated with this struct + if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" { + ns := xml.Attr{ + Name: xml.Name{Local: "xmlns"}, + Value: uri, + } + if prefix != "" { + b.namespaces[prefix] = uri // register the namespace + ns.Name.Local = "xmlns:" + prefix + } + + child.Attr = append(child.Attr, ns) + } + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + member := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + + mTag := field.Tag + if mTag.Get("location") != "" { // skip non-body members + continue + } + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(token) + } + + memberName := mTag.Get("locationName") + if memberName == "" { + memberName = field.Name + mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`) + } + if err := b.buildValue(member, child, mTag); err != nil { + return err + } + + fieldAdded = true + } + + if fieldAdded { // only append this child if we have one ore more valid members + current.AddChild(child) + } + + return nil +} + +// buildList adds the value's list items to the current XMLNode as children nodes. All +// nested values in the list are converted to XMLNodes also. +func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted lists + return nil + } + + // check for unflattened list member + flattened := tag.Get("flattened") != "" + + xname := xml.Name{Local: tag.Get("locationName")} + if flattened { + for i := 0; i < value.Len(); i++ { + child := NewXMLElement(xname) + current.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } else { + list := NewXMLElement(xname) + current.AddChild(list) + + for i := 0; i < value.Len(); i++ { + iname := tag.Get("locationNameList") + if iname == "" { + iname = "member" + } + + child := NewXMLElement(xml.Name{Local: iname}) + list.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } + + return nil +} + +// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All +// nested values in the map are converted to XMLNodes also. +// +// Error will be returned if it is unable to build the map's values into XMLNodes +func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted maps + return nil + } + + maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + current.AddChild(maproot) + current = maproot + + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + // sorting is not required for compliance, but it makes testing easier + keys := make([]string, value.Len()) + for i, k := range value.MapKeys() { + keys[i] = k.String() + } + sort.Strings(keys) + + for _, k := range keys { + v := value.MapIndex(reflect.ValueOf(k)) + + mapcur := current + if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps + child := NewXMLElement(xml.Name{Local: "entry"}) + mapcur.AddChild(child) + mapcur = child + } + + kchild := NewXMLElement(xml.Name{Local: kname}) + kchild.Text = k + vchild := NewXMLElement(xml.Name{Local: vname}) + mapcur.AddChild(kchild) + mapcur.AddChild(vchild) + + if err := b.buildValue(v, vchild, ""); err != nil { + return err + } + } + + return nil +} + +// buildScalar will convert the value into a string and append it as a attribute or child +// of the current XMLNode. +// +// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value. +// +// Error will be returned if the value type is unsupported. +func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + var str string + switch converted := value.Interface().(type) { + case string: + str = converted + case []byte: + if !value.IsNil() { + str = base64.StdEncoding.EncodeToString(converted) + } + case bool: + str = strconv.FormatBool(converted) + case int64: + str = strconv.FormatInt(converted, 10) + case int: + str = strconv.Itoa(converted) + case float64: + str = strconv.FormatFloat(converted, 'f', -1, 64) + case float32: + str = strconv.FormatFloat(float64(converted), 'f', -1, 32) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + str = converted.UTC().Format(ISO8601UTC) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", + tag.Get("locationName"), value.Interface(), value.Type().Name()) + } + + xname := xml.Name{Local: tag.Get("locationName")} + if tag.Get("xmlAttribute") != "" { // put into current node's attribute list + attr := xml.Attr{Name: xname, Value: str} + current.Attr = append(current.Attr, attr) + } else { // regular text node + current.AddChild(&XMLNode{Name: xname, Text: str}) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go new file mode 100644 index 0000000000..49f291a857 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go @@ -0,0 +1,260 @@ +package xmlutil + +import ( + "encoding/base64" + "encoding/xml" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "time" +) + +// UnmarshalXML deserializes an xml.Decoder into the container v. V +// needs to match the shape of the XML expected to be decoded. +// If the shape doesn't match unmarshaling will fail. +func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { + n, _ := XMLToStruct(d, nil) + if n.Children != nil { + for _, root := range n.Children { + for _, c := range root { + if wrappedChild, ok := c.Children[wrapper]; ok { + c = wrappedChild[0] // pull out wrapped element + } + + err := parse(reflect.ValueOf(v), c, "") + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } + } + return nil + } + return nil +} + +// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect +// will be used to determine the type from r. +func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + rtype := r.Type() + if rtype.Kind() == reflect.Ptr { + rtype = rtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch rtype.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := rtype.FieldByName("_"); ok { + tag = field.Tag + } + return parseStruct(r, node, tag) + case "list": + return parseList(r, node, tag) + case "map": + return parseMap(r, node, tag) + default: + return parseScalar(r, node, tag) + } +} + +// parseStruct deserializes a structure and its fields from an XMLNode. Any nested +// types in the structure will also be deserialized. +func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + if r.Kind() == reflect.Ptr { + if r.IsNil() { // create the structure if it's nil + s := reflect.New(r.Type().Elem()) + r.Set(s) + r = s + } + + r = r.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return parseStruct(r.FieldByName(payload), node, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if c := field.Name[0:1]; strings.ToLower(c) == c { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + // try to find the field by name in elements + elems := node.Children[name] + + if elems == nil { // try to find the field in attributes + for _, a := range node.Attr { + if name == a.Name.Local { + // turn this into a text node for de-serializing + elems = []*XMLNode{{Text: a.Value}} + } + } + } + + member := r.FieldByName(field.Name) + for _, elem := range elems { + err := parse(member, elem, field.Tag) + if err != nil { + return err + } + } + } + return nil +} + +// parseList deserializes a list of values from an XML node. Each list entry +// will also be deserialized. +func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + + if tag.Get("flattened") == "" { // look at all item entries + mname := "member" + if name := tag.Get("locationNameList"); name != "" { + mname = name + } + + if Children, ok := node.Children[mname]; ok { + if r.IsNil() { + r.Set(reflect.MakeSlice(t, len(Children), len(Children))) + } + + for i, c := range Children { + err := parse(r.Index(i), c, "") + if err != nil { + return err + } + } + } + } else { // flattened list means this is a single element + if r.IsNil() { + r.Set(reflect.MakeSlice(t, 0, 0)) + } + + childR := reflect.Zero(t.Elem()) + r.Set(reflect.Append(r, childR)) + err := parse(r.Index(r.Len()-1), node, "") + if err != nil { + return err + } + } + + return nil +} + +// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode +// will also be deserialized as map entries. +func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + if r.IsNil() { + r.Set(reflect.MakeMap(r.Type())) + } + + if tag.Get("flattened") == "" { // look at all child entries + for _, entry := range node.Children["entry"] { + parseMapEntry(r, entry, tag) + } + } else { // this element is itself an entry + parseMapEntry(r, node, tag) + } + + return nil +} + +// parseMapEntry deserializes a map entry from a XML node. +func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + keys, ok := node.Children[kname] + values := node.Children[vname] + if ok { + for i, key := range keys { + keyR := reflect.ValueOf(key.Text) + value := values[i] + valueR := reflect.New(r.Type().Elem()).Elem() + + parse(valueR, value, "") + r.SetMapIndex(keyR, valueR) + } + } + return nil +} + +// parseScaller deserializes an XMLNode value into a concrete type based on the +// interface type of r. +// +// Error is returned if the deserialization fails due to invalid type conversion, +// or unsupported interface type. +func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + switch r.Interface().(type) { + case *string: + r.Set(reflect.ValueOf(&node.Text)) + return nil + case []byte: + b, err := base64.StdEncoding.DecodeString(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(b)) + case *bool: + v, err := strconv.ParseBool(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *int64: + v, err := strconv.ParseInt(node.Text, 10, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *float64: + v, err := strconv.ParseFloat(node.Text, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + t, err := time.Parse(ISO8601UTC, node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go new file mode 100644 index 0000000000..72c198a9d8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go @@ -0,0 +1,105 @@ +package xmlutil + +import ( + "encoding/xml" + "io" + "sort" +) + +// A XMLNode contains the values to be encoded or decoded. +type XMLNode struct { + Name xml.Name `json:",omitempty"` + Children map[string][]*XMLNode `json:",omitempty"` + Text string `json:",omitempty"` + Attr []xml.Attr `json:",omitempty"` +} + +// NewXMLElement returns a pointer to a new XMLNode initialized to default values. +func NewXMLElement(name xml.Name) *XMLNode { + return &XMLNode{ + Name: name, + Children: map[string][]*XMLNode{}, + Attr: []xml.Attr{}, + } +} + +// AddChild adds child to the XMLNode. +func (n *XMLNode) AddChild(child *XMLNode) { + if _, ok := n.Children[child.Name.Local]; !ok { + n.Children[child.Name.Local] = []*XMLNode{} + } + n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child) +} + +// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values. +func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) { + out := &XMLNode{} + for { + tok, err := d.Token() + if tok == nil || err == io.EOF { + break + } + if err != nil { + return out, err + } + + switch typed := tok.(type) { + case xml.CharData: + out.Text = string(typed.Copy()) + case xml.StartElement: + el := typed.Copy() + out.Attr = el.Attr + if out.Children == nil { + out.Children = map[string][]*XMLNode{} + } + + name := typed.Name.Local + slice := out.Children[name] + if slice == nil { + slice = []*XMLNode{} + } + node, e := XMLToStruct(d, &el) + if e != nil { + return out, e + } + node.Name = typed.Name + slice = append(slice, node) + out.Children[name] = slice + case xml.EndElement: + if s != nil && s.Name.Local == typed.Name.Local { // matching end token + return out, nil + } + } + } + return out, nil +} + +// StructToXML writes an XMLNode to a xml.Encoder as tokens. +func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error { + e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr}) + + if node.Text != "" { + e.EncodeToken(xml.CharData([]byte(node.Text))) + } else if sorted { + sortedNames := []string{} + for k := range node.Children { + sortedNames = append(sortedNames, k) + } + sort.Strings(sortedNames) + + for _, k := range sortedNames { + for _, v := range node.Children[k] { + StructToXML(e, v, sorted) + } + } + } else { + for _, c := range node.Children { + for _, v := range c { + StructToXML(e, v, sorted) + } + } + } + + e.EncodeToken(xml.EndElement{Name: node.Name}) + return e.Flush() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go b/vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go new file mode 100644 index 0000000000..b51e9449c1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go @@ -0,0 +1,134 @@ +package waiter + +import ( + "fmt" + "reflect" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" +) + +// A Config provides a collection of configuration values to setup a generated +// waiter code with. +type Config struct { + Name string + Delay int + MaxAttempts int + Operation string + Acceptors []WaitAcceptor +} + +// A WaitAcceptor provides the information needed to wait for an API operation +// to complete. +type WaitAcceptor struct { + Expected interface{} + Matcher string + State string + Argument string +} + +// A Waiter provides waiting for an operation to complete. +type Waiter struct { + Config + Client interface{} + Input interface{} +} + +// Wait waits for an operation to complete, expire max attempts, or fail. Error +// is returned if the operation fails. +func (w *Waiter) Wait() error { + client := reflect.ValueOf(w.Client) + in := reflect.ValueOf(w.Input) + method := client.MethodByName(w.Config.Operation + "Request") + + for i := 0; i < w.MaxAttempts; i++ { + res := method.Call([]reflect.Value{in}) + req := res[0].Interface().(*request.Request) + req.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Waiter")) + + err := req.Send() + for _, a := range w.Acceptors { + result := false + var vals []interface{} + switch a.Matcher { + case "pathAll", "path": + // Require all matches to be equal for result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + if len(vals) == 0 { + break + } + result = true + for _, val := range vals { + if !awsutil.DeepEqual(val, a.Expected) { + result = false + break + } + } + case "pathAny": + // Only a single match needs to equal for the result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + for _, val := range vals { + if awsutil.DeepEqual(val, a.Expected) { + result = true + break + } + } + case "status": + s := a.Expected.(int) + result = s == req.HTTPResponse.StatusCode + case "error": + if aerr, ok := err.(awserr.Error); ok { + result = aerr.Code() == a.Expected.(string) + } + case "pathList": + // ignored matcher + default: + logf(client, "WARNING: Waiter for %s encountered unexpected matcher: %s", + w.Config.Operation, a.Matcher) + } + + if !result { + // If there was no matching result found there is nothing more to do + // for this response, retry the request. + continue + } + + switch a.State { + case "success": + // waiter completed + return nil + case "failure": + // Waiter failure state triggered + return awserr.New("ResourceNotReady", + fmt.Sprintf("failed waiting for successful resource state"), err) + case "retry": + // clear the error and retry the operation + err = nil + default: + logf(client, "WARNING: Waiter for %s encountered unexpected state: %s", + w.Config.Operation, a.State) + } + } + if err != nil { + return err + } + + time.Sleep(time.Second * time.Duration(w.Delay)) + } + + return awserr.New("ResourceNotReady", + fmt.Sprintf("exceeded %d wait attempts", w.MaxAttempts), nil) +} + +func logf(client reflect.Value, msg string, args ...interface{}) { + cfgVal := client.FieldByName("Config") + if !cfgVal.IsValid() { + return + } + if cfg, ok := cfgVal.Interface().(*aws.Config); ok && cfg.Logger != nil { + cfg.Logger.Log(fmt.Sprintf(msg, args...)) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go new file mode 100644 index 0000000000..83787faa37 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -0,0 +1,33933 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +// Package ec2 provides a client for Amazon Elastic Compute Cloud. +package ec2 + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/ec2query" +) + +const opAcceptVpcPeeringConnection = "AcceptVpcPeeringConnection" + +// AcceptVpcPeeringConnectionRequest generates a "aws/request.Request" representing the +// client's request for the AcceptVpcPeeringConnection operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AcceptVpcPeeringConnection method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AcceptVpcPeeringConnectionRequest method. +// req, resp := client.AcceptVpcPeeringConnectionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AcceptVpcPeeringConnectionRequest(input *AcceptVpcPeeringConnectionInput) (req *request.Request, output *AcceptVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opAcceptVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AcceptVpcPeeringConnectionInput{} + } + + req = c.newRequest(op, input, output) + output = &AcceptVpcPeeringConnectionOutput{} + req.Data = output + return +} + +// Accept a VPC peering connection request. To accept a request, the VPC peering +// connection must be in the pending-acceptance state, and you must be the owner +// of the peer VPC. Use the DescribeVpcPeeringConnections request to view your +// outstanding VPC peering connection requests. +func (c *EC2) AcceptVpcPeeringConnection(input *AcceptVpcPeeringConnectionInput) (*AcceptVpcPeeringConnectionOutput, error) { + req, out := c.AcceptVpcPeeringConnectionRequest(input) + err := req.Send() + return out, err +} + +const opAllocateAddress = "AllocateAddress" + +// AllocateAddressRequest generates a "aws/request.Request" representing the +// client's request for the AllocateAddress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AllocateAddress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AllocateAddressRequest method. +// req, resp := client.AllocateAddressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AllocateAddressRequest(input *AllocateAddressInput) (req *request.Request, output *AllocateAddressOutput) { + op := &request.Operation{ + Name: opAllocateAddress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AllocateAddressInput{} + } + + req = c.newRequest(op, input, output) + output = &AllocateAddressOutput{} + req.Data = output + return +} + +// Acquires an Elastic IP address. +// +// An Elastic IP address is for use either in the EC2-Classic platform or in +// a VPC. For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) AllocateAddress(input *AllocateAddressInput) (*AllocateAddressOutput, error) { + req, out := c.AllocateAddressRequest(input) + err := req.Send() + return out, err +} + +const opAllocateHosts = "AllocateHosts" + +// AllocateHostsRequest generates a "aws/request.Request" representing the +// client's request for the AllocateHosts operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AllocateHosts method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AllocateHostsRequest method. +// req, resp := client.AllocateHostsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AllocateHostsRequest(input *AllocateHostsInput) (req *request.Request, output *AllocateHostsOutput) { + op := &request.Operation{ + Name: opAllocateHosts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AllocateHostsInput{} + } + + req = c.newRequest(op, input, output) + output = &AllocateHostsOutput{} + req.Data = output + return +} + +// Allocates a Dedicated Host to your account. At minimum you need to specify +// the instance size type, Availability Zone, and quantity of hosts you want +// to allocate. +func (c *EC2) AllocateHosts(input *AllocateHostsInput) (*AllocateHostsOutput, error) { + req, out := c.AllocateHostsRequest(input) + err := req.Send() + return out, err +} + +const opAssignPrivateIpAddresses = "AssignPrivateIpAddresses" + +// AssignPrivateIpAddressesRequest generates a "aws/request.Request" representing the +// client's request for the AssignPrivateIpAddresses operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssignPrivateIpAddresses method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssignPrivateIpAddressesRequest method. +// req, resp := client.AssignPrivateIpAddressesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AssignPrivateIpAddressesRequest(input *AssignPrivateIpAddressesInput) (req *request.Request, output *AssignPrivateIpAddressesOutput) { + op := &request.Operation{ + Name: opAssignPrivateIpAddresses, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssignPrivateIpAddressesInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &AssignPrivateIpAddressesOutput{} + req.Data = output + return +} + +// Assigns one or more secondary private IP addresses to the specified network +// interface. You can specify one or more specific secondary IP addresses, or +// you can specify the number of secondary IP addresses to be automatically +// assigned within the subnet's CIDR block range. The number of secondary IP +// addresses that you can assign to an instance varies by instance type. For +// information about instance types, see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) +// in the Amazon Elastic Compute Cloud User Guide. For more information about +// Elastic IP addresses, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// AssignPrivateIpAddresses is available only in EC2-VPC. +func (c *EC2) AssignPrivateIpAddresses(input *AssignPrivateIpAddressesInput) (*AssignPrivateIpAddressesOutput, error) { + req, out := c.AssignPrivateIpAddressesRequest(input) + err := req.Send() + return out, err +} + +const opAssociateAddress = "AssociateAddress" + +// AssociateAddressRequest generates a "aws/request.Request" representing the +// client's request for the AssociateAddress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssociateAddress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssociateAddressRequest method. +// req, resp := client.AssociateAddressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *request.Request, output *AssociateAddressOutput) { + op := &request.Operation{ + Name: opAssociateAddress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssociateAddressInput{} + } + + req = c.newRequest(op, input, output) + output = &AssociateAddressOutput{} + req.Data = output + return +} + +// Associates an Elastic IP address with an instance or a network interface. +// +// An Elastic IP address is for use in either the EC2-Classic platform or in +// a VPC. For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// [EC2-Classic, VPC in an EC2-VPC-only account] If the Elastic IP address +// is already associated with a different instance, it is disassociated from +// that instance and associated with the specified instance. +// +// [VPC in an EC2-Classic account] If you don't specify a private IP address, +// the Elastic IP address is associated with the primary IP address. If the +// Elastic IP address is already associated with a different instance or a network +// interface, you get an error unless you allow reassociation. +// +// This is an idempotent operation. If you perform the operation more than +// once, Amazon EC2 doesn't return an error, and you may be charged for each +// time the Elastic IP address is remapped to the same instance. For more information, +// see the Elastic IP Addresses section of Amazon EC2 Pricing (http://aws.amazon.com/ec2/pricing/). +func (c *EC2) AssociateAddress(input *AssociateAddressInput) (*AssociateAddressOutput, error) { + req, out := c.AssociateAddressRequest(input) + err := req.Send() + return out, err +} + +const opAssociateDhcpOptions = "AssociateDhcpOptions" + +// AssociateDhcpOptionsRequest generates a "aws/request.Request" representing the +// client's request for the AssociateDhcpOptions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssociateDhcpOptions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssociateDhcpOptionsRequest method. +// req, resp := client.AssociateDhcpOptionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AssociateDhcpOptionsRequest(input *AssociateDhcpOptionsInput) (req *request.Request, output *AssociateDhcpOptionsOutput) { + op := &request.Operation{ + Name: opAssociateDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssociateDhcpOptionsInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &AssociateDhcpOptionsOutput{} + req.Data = output + return +} + +// Associates a set of DHCP options (that you've previously created) with the +// specified VPC, or associates no DHCP options with the VPC. +// +// After you associate the options with the VPC, any existing instances and +// all new instances that you launch in that VPC use the options. You don't +// need to restart or relaunch the instances. They automatically pick up the +// changes within a few hours, depending on how frequently the instance renews +// its DHCP lease. You can explicitly renew the lease using the operating system +// on the instance. +// +// For more information, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) AssociateDhcpOptions(input *AssociateDhcpOptionsInput) (*AssociateDhcpOptionsOutput, error) { + req, out := c.AssociateDhcpOptionsRequest(input) + err := req.Send() + return out, err +} + +const opAssociateRouteTable = "AssociateRouteTable" + +// AssociateRouteTableRequest generates a "aws/request.Request" representing the +// client's request for the AssociateRouteTable operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssociateRouteTable method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssociateRouteTableRequest method. +// req, resp := client.AssociateRouteTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AssociateRouteTableRequest(input *AssociateRouteTableInput) (req *request.Request, output *AssociateRouteTableOutput) { + op := &request.Operation{ + Name: opAssociateRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssociateRouteTableInput{} + } + + req = c.newRequest(op, input, output) + output = &AssociateRouteTableOutput{} + req.Data = output + return +} + +// Associates a subnet with a route table. The subnet and route table must be +// in the same VPC. This association causes traffic originating from the subnet +// to be routed according to the routes in the route table. The action returns +// an association ID, which you need in order to disassociate the route table +// from the subnet later. A route table can be associated with multiple subnets. +// +// For more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) AssociateRouteTable(input *AssociateRouteTableInput) (*AssociateRouteTableOutput, error) { + req, out := c.AssociateRouteTableRequest(input) + err := req.Send() + return out, err +} + +const opAttachClassicLinkVpc = "AttachClassicLinkVpc" + +// AttachClassicLinkVpcRequest generates a "aws/request.Request" representing the +// client's request for the AttachClassicLinkVpc operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AttachClassicLinkVpc method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AttachClassicLinkVpcRequest method. +// req, resp := client.AttachClassicLinkVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AttachClassicLinkVpcRequest(input *AttachClassicLinkVpcInput) (req *request.Request, output *AttachClassicLinkVpcOutput) { + op := &request.Operation{ + Name: opAttachClassicLinkVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachClassicLinkVpcInput{} + } + + req = c.newRequest(op, input, output) + output = &AttachClassicLinkVpcOutput{} + req.Data = output + return +} + +// Links an EC2-Classic instance to a ClassicLink-enabled VPC through one or +// more of the VPC's security groups. You cannot link an EC2-Classic instance +// to more than one VPC at a time. You can only link an instance that's in the +// running state. An instance is automatically unlinked from a VPC when it's +// stopped - you can link it to the VPC again when you restart it. +// +// After you've linked an instance, you cannot change the VPC security groups +// that are associated with it. To change the security groups, you must first +// unlink the instance, and then link it again. +// +// Linking your instance to a VPC is sometimes referred to as attaching your +// instance. +func (c *EC2) AttachClassicLinkVpc(input *AttachClassicLinkVpcInput) (*AttachClassicLinkVpcOutput, error) { + req, out := c.AttachClassicLinkVpcRequest(input) + err := req.Send() + return out, err +} + +const opAttachInternetGateway = "AttachInternetGateway" + +// AttachInternetGatewayRequest generates a "aws/request.Request" representing the +// client's request for the AttachInternetGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AttachInternetGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AttachInternetGatewayRequest method. +// req, resp := client.AttachInternetGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AttachInternetGatewayRequest(input *AttachInternetGatewayInput) (req *request.Request, output *AttachInternetGatewayOutput) { + op := &request.Operation{ + Name: opAttachInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachInternetGatewayInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &AttachInternetGatewayOutput{} + req.Data = output + return +} + +// Attaches an Internet gateway to a VPC, enabling connectivity between the +// Internet and the VPC. For more information about your VPC and Internet gateway, +// see the Amazon Virtual Private Cloud User Guide (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/). +func (c *EC2) AttachInternetGateway(input *AttachInternetGatewayInput) (*AttachInternetGatewayOutput, error) { + req, out := c.AttachInternetGatewayRequest(input) + err := req.Send() + return out, err +} + +const opAttachNetworkInterface = "AttachNetworkInterface" + +// AttachNetworkInterfaceRequest generates a "aws/request.Request" representing the +// client's request for the AttachNetworkInterface operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AttachNetworkInterface method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AttachNetworkInterfaceRequest method. +// req, resp := client.AttachNetworkInterfaceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AttachNetworkInterfaceRequest(input *AttachNetworkInterfaceInput) (req *request.Request, output *AttachNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opAttachNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachNetworkInterfaceInput{} + } + + req = c.newRequest(op, input, output) + output = &AttachNetworkInterfaceOutput{} + req.Data = output + return +} + +// Attaches a network interface to an instance. +func (c *EC2) AttachNetworkInterface(input *AttachNetworkInterfaceInput) (*AttachNetworkInterfaceOutput, error) { + req, out := c.AttachNetworkInterfaceRequest(input) + err := req.Send() + return out, err +} + +const opAttachVolume = "AttachVolume" + +// AttachVolumeRequest generates a "aws/request.Request" representing the +// client's request for the AttachVolume operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AttachVolume method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AttachVolumeRequest method. +// req, resp := client.AttachVolumeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AttachVolumeRequest(input *AttachVolumeInput) (req *request.Request, output *VolumeAttachment) { + op := &request.Operation{ + Name: opAttachVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &VolumeAttachment{} + req.Data = output + return +} + +// Attaches an EBS volume to a running or stopped instance and exposes it to +// the instance with the specified device name. +// +// Encrypted EBS volumes may only be attached to instances that support Amazon +// EBS encryption. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// For a list of supported device names, see Attaching an EBS Volume to an +// Instance (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html). +// Any device names that aren't reserved for instance store volumes can be used +// for EBS volumes. For more information, see Amazon EC2 Instance Store (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// If a volume has an AWS Marketplace product code: +// +// The volume can be attached only to a stopped instance. +// +// AWS Marketplace product codes are copied from the volume to the instance. +// +// You must be subscribed to the product. +// +// The instance type and operating system of the instance must support the +// product. For example, you can't detach a volume from a Windows instance and +// attach it to a Linux instance. +// +// For an overview of the AWS Marketplace, see Introducing AWS Marketplace +// (https://aws.amazon.com/marketplace/help/200900000). +// +// For more information about EBS volumes, see Attaching Amazon EBS Volumes +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) AttachVolume(input *AttachVolumeInput) (*VolumeAttachment, error) { + req, out := c.AttachVolumeRequest(input) + err := req.Send() + return out, err +} + +const opAttachVpnGateway = "AttachVpnGateway" + +// AttachVpnGatewayRequest generates a "aws/request.Request" representing the +// client's request for the AttachVpnGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AttachVpnGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AttachVpnGatewayRequest method. +// req, resp := client.AttachVpnGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AttachVpnGatewayRequest(input *AttachVpnGatewayInput) (req *request.Request, output *AttachVpnGatewayOutput) { + op := &request.Operation{ + Name: opAttachVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachVpnGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &AttachVpnGatewayOutput{} + req.Data = output + return +} + +// Attaches a virtual private gateway to a VPC. For more information, see Adding +// a Hardware Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) AttachVpnGateway(input *AttachVpnGatewayInput) (*AttachVpnGatewayOutput, error) { + req, out := c.AttachVpnGatewayRequest(input) + err := req.Send() + return out, err +} + +const opAuthorizeSecurityGroupEgress = "AuthorizeSecurityGroupEgress" + +// AuthorizeSecurityGroupEgressRequest generates a "aws/request.Request" representing the +// client's request for the AuthorizeSecurityGroupEgress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AuthorizeSecurityGroupEgress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AuthorizeSecurityGroupEgressRequest method. +// req, resp := client.AuthorizeSecurityGroupEgressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AuthorizeSecurityGroupEgressRequest(input *AuthorizeSecurityGroupEgressInput) (req *request.Request, output *AuthorizeSecurityGroupEgressOutput) { + op := &request.Operation{ + Name: opAuthorizeSecurityGroupEgress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AuthorizeSecurityGroupEgressInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &AuthorizeSecurityGroupEgressOutput{} + req.Data = output + return +} + +// [EC2-VPC only] Adds one or more egress rules to a security group for use +// with a VPC. Specifically, this action permits instances to send traffic to +// one or more destination CIDR IP address ranges, or to one or more destination +// security groups for the same VPC. This action doesn't apply to security groups +// for use in EC2-Classic. For more information, see Security Groups for Your +// VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// You can have up to 50 rules per security group (covering both ingress and +// egress rules). +// +// Each rule consists of the protocol (for example, TCP), plus either a CIDR +// range or a source group. For the TCP and UDP protocols, you must also specify +// the destination port or port range. For the ICMP protocol, you must also +// specify the ICMP type and code. You can use -1 for the type or code to mean +// all types or all codes. +// +// Rule changes are propagated to affected instances as quickly as possible. +// However, a small delay might occur. +func (c *EC2) AuthorizeSecurityGroupEgress(input *AuthorizeSecurityGroupEgressInput) (*AuthorizeSecurityGroupEgressOutput, error) { + req, out := c.AuthorizeSecurityGroupEgressRequest(input) + err := req.Send() + return out, err +} + +const opAuthorizeSecurityGroupIngress = "AuthorizeSecurityGroupIngress" + +// AuthorizeSecurityGroupIngressRequest generates a "aws/request.Request" representing the +// client's request for the AuthorizeSecurityGroupIngress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AuthorizeSecurityGroupIngress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AuthorizeSecurityGroupIngressRequest method. +// req, resp := client.AuthorizeSecurityGroupIngressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) AuthorizeSecurityGroupIngressRequest(input *AuthorizeSecurityGroupIngressInput) (req *request.Request, output *AuthorizeSecurityGroupIngressOutput) { + op := &request.Operation{ + Name: opAuthorizeSecurityGroupIngress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AuthorizeSecurityGroupIngressInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &AuthorizeSecurityGroupIngressOutput{} + req.Data = output + return +} + +// Adds one or more ingress rules to a security group. +// +// EC2-Classic: You can have up to 100 rules per group. +// +// EC2-VPC: You can have up to 50 rules per group (covering both ingress and +// egress rules). +// +// Rule changes are propagated to instances within the security group as quickly +// as possible. However, a small delay might occur. +// +// [EC2-Classic] This action gives one or more CIDR IP address ranges permission +// to access a security group in your account, or gives one or more security +// groups (called the source groups) permission to access a security group for +// your account. A source group can be for your own AWS account, or another. +// +// [EC2-VPC] This action gives one or more CIDR IP address ranges permission +// to access a security group in your VPC, or gives one or more other security +// groups (called the source groups) permission to access a security group for +// your VPC. The security groups must all be for the same VPC. +func (c *EC2) AuthorizeSecurityGroupIngress(input *AuthorizeSecurityGroupIngressInput) (*AuthorizeSecurityGroupIngressOutput, error) { + req, out := c.AuthorizeSecurityGroupIngressRequest(input) + err := req.Send() + return out, err +} + +const opBundleInstance = "BundleInstance" + +// BundleInstanceRequest generates a "aws/request.Request" representing the +// client's request for the BundleInstance operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the BundleInstance method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the BundleInstanceRequest method. +// req, resp := client.BundleInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) BundleInstanceRequest(input *BundleInstanceInput) (req *request.Request, output *BundleInstanceOutput) { + op := &request.Operation{ + Name: opBundleInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &BundleInstanceInput{} + } + + req = c.newRequest(op, input, output) + output = &BundleInstanceOutput{} + req.Data = output + return +} + +// Bundles an Amazon instance store-backed Windows instance. +// +// During bundling, only the root device volume (C:\) is bundled. Data on other +// instance store volumes is not preserved. +// +// This action is not applicable for Linux/Unix instances or Windows instances +// that are backed by Amazon EBS. +// +// For more information, see Creating an Instance Store-Backed Windows AMI +// (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/Creating_InstanceStoreBacked_WinAMI.html). +func (c *EC2) BundleInstance(input *BundleInstanceInput) (*BundleInstanceOutput, error) { + req, out := c.BundleInstanceRequest(input) + err := req.Send() + return out, err +} + +const opCancelBundleTask = "CancelBundleTask" + +// CancelBundleTaskRequest generates a "aws/request.Request" representing the +// client's request for the CancelBundleTask operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelBundleTask method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelBundleTaskRequest method. +// req, resp := client.CancelBundleTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelBundleTaskRequest(input *CancelBundleTaskInput) (req *request.Request, output *CancelBundleTaskOutput) { + op := &request.Operation{ + Name: opCancelBundleTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelBundleTaskInput{} + } + + req = c.newRequest(op, input, output) + output = &CancelBundleTaskOutput{} + req.Data = output + return +} + +// Cancels a bundling operation for an instance store-backed Windows instance. +func (c *EC2) CancelBundleTask(input *CancelBundleTaskInput) (*CancelBundleTaskOutput, error) { + req, out := c.CancelBundleTaskRequest(input) + err := req.Send() + return out, err +} + +const opCancelConversionTask = "CancelConversionTask" + +// CancelConversionTaskRequest generates a "aws/request.Request" representing the +// client's request for the CancelConversionTask operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelConversionTask method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelConversionTaskRequest method. +// req, resp := client.CancelConversionTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelConversionTaskRequest(input *CancelConversionTaskInput) (req *request.Request, output *CancelConversionTaskOutput) { + op := &request.Operation{ + Name: opCancelConversionTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelConversionTaskInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &CancelConversionTaskOutput{} + req.Data = output + return +} + +// Cancels an active conversion task. The task can be the import of an instance +// or volume. The action removes all artifacts of the conversion, including +// a partially uploaded volume or instance. If the conversion is complete or +// is in the process of transferring the final disk image, the command fails +// and returns an exception. +// +// For more information, see Importing a Virtual Machine Using the Amazon EC2 +// CLI (http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ec2-cli-vmimport-export.html). +func (c *EC2) CancelConversionTask(input *CancelConversionTaskInput) (*CancelConversionTaskOutput, error) { + req, out := c.CancelConversionTaskRequest(input) + err := req.Send() + return out, err +} + +const opCancelExportTask = "CancelExportTask" + +// CancelExportTaskRequest generates a "aws/request.Request" representing the +// client's request for the CancelExportTask operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelExportTask method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelExportTaskRequest method. +// req, resp := client.CancelExportTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelExportTaskRequest(input *CancelExportTaskInput) (req *request.Request, output *CancelExportTaskOutput) { + op := &request.Operation{ + Name: opCancelExportTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelExportTaskInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &CancelExportTaskOutput{} + req.Data = output + return +} + +// Cancels an active export task. The request removes all artifacts of the export, +// including any partially-created Amazon S3 objects. If the export task is +// complete or is in the process of transferring the final disk image, the command +// fails and returns an error. +func (c *EC2) CancelExportTask(input *CancelExportTaskInput) (*CancelExportTaskOutput, error) { + req, out := c.CancelExportTaskRequest(input) + err := req.Send() + return out, err +} + +const opCancelImportTask = "CancelImportTask" + +// CancelImportTaskRequest generates a "aws/request.Request" representing the +// client's request for the CancelImportTask operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelImportTask method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelImportTaskRequest method. +// req, resp := client.CancelImportTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelImportTaskRequest(input *CancelImportTaskInput) (req *request.Request, output *CancelImportTaskOutput) { + op := &request.Operation{ + Name: opCancelImportTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelImportTaskInput{} + } + + req = c.newRequest(op, input, output) + output = &CancelImportTaskOutput{} + req.Data = output + return +} + +// Cancels an in-process import virtual machine or import snapshot task. +func (c *EC2) CancelImportTask(input *CancelImportTaskInput) (*CancelImportTaskOutput, error) { + req, out := c.CancelImportTaskRequest(input) + err := req.Send() + return out, err +} + +const opCancelReservedInstancesListing = "CancelReservedInstancesListing" + +// CancelReservedInstancesListingRequest generates a "aws/request.Request" representing the +// client's request for the CancelReservedInstancesListing operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelReservedInstancesListing method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelReservedInstancesListingRequest method. +// req, resp := client.CancelReservedInstancesListingRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelReservedInstancesListingRequest(input *CancelReservedInstancesListingInput) (req *request.Request, output *CancelReservedInstancesListingOutput) { + op := &request.Operation{ + Name: opCancelReservedInstancesListing, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelReservedInstancesListingInput{} + } + + req = c.newRequest(op, input, output) + output = &CancelReservedInstancesListingOutput{} + req.Data = output + return +} + +// Cancels the specified Reserved Instance listing in the Reserved Instance +// Marketplace. +// +// For more information, see Reserved Instance Marketplace (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CancelReservedInstancesListing(input *CancelReservedInstancesListingInput) (*CancelReservedInstancesListingOutput, error) { + req, out := c.CancelReservedInstancesListingRequest(input) + err := req.Send() + return out, err +} + +const opCancelSpotFleetRequests = "CancelSpotFleetRequests" + +// CancelSpotFleetRequestsRequest generates a "aws/request.Request" representing the +// client's request for the CancelSpotFleetRequests operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelSpotFleetRequests method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelSpotFleetRequestsRequest method. +// req, resp := client.CancelSpotFleetRequestsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelSpotFleetRequestsRequest(input *CancelSpotFleetRequestsInput) (req *request.Request, output *CancelSpotFleetRequestsOutput) { + op := &request.Operation{ + Name: opCancelSpotFleetRequests, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelSpotFleetRequestsInput{} + } + + req = c.newRequest(op, input, output) + output = &CancelSpotFleetRequestsOutput{} + req.Data = output + return +} + +// Cancels the specified Spot fleet requests. +// +// After you cancel a Spot fleet request, the Spot fleet launches no new Spot +// instances. You must specify whether the Spot fleet should also terminate +// its Spot instances. If you terminate the instances, the Spot fleet request +// enters the cancelled_terminating state. Otherwise, the Spot fleet request +// enters the cancelled_running state and the instances continue to run until +// they are interrupted or you terminate them manually. +func (c *EC2) CancelSpotFleetRequests(input *CancelSpotFleetRequestsInput) (*CancelSpotFleetRequestsOutput, error) { + req, out := c.CancelSpotFleetRequestsRequest(input) + err := req.Send() + return out, err +} + +const opCancelSpotInstanceRequests = "CancelSpotInstanceRequests" + +// CancelSpotInstanceRequestsRequest generates a "aws/request.Request" representing the +// client's request for the CancelSpotInstanceRequests operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CancelSpotInstanceRequests method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CancelSpotInstanceRequestsRequest method. +// req, resp := client.CancelSpotInstanceRequestsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CancelSpotInstanceRequestsRequest(input *CancelSpotInstanceRequestsInput) (req *request.Request, output *CancelSpotInstanceRequestsOutput) { + op := &request.Operation{ + Name: opCancelSpotInstanceRequests, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelSpotInstanceRequestsInput{} + } + + req = c.newRequest(op, input, output) + output = &CancelSpotInstanceRequestsOutput{} + req.Data = output + return +} + +// Cancels one or more Spot instance requests. Spot instances are instances +// that Amazon EC2 starts on your behalf when the bid price that you specify +// exceeds the current Spot price. Amazon EC2 periodically sets the Spot price +// based on available Spot instance capacity and current Spot instance requests. +// For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Canceling a Spot instance request does not terminate running Spot instances +// associated with the request. +func (c *EC2) CancelSpotInstanceRequests(input *CancelSpotInstanceRequestsInput) (*CancelSpotInstanceRequestsOutput, error) { + req, out := c.CancelSpotInstanceRequestsRequest(input) + err := req.Send() + return out, err +} + +const opConfirmProductInstance = "ConfirmProductInstance" + +// ConfirmProductInstanceRequest generates a "aws/request.Request" representing the +// client's request for the ConfirmProductInstance operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ConfirmProductInstance method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ConfirmProductInstanceRequest method. +// req, resp := client.ConfirmProductInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ConfirmProductInstanceRequest(input *ConfirmProductInstanceInput) (req *request.Request, output *ConfirmProductInstanceOutput) { + op := &request.Operation{ + Name: opConfirmProductInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ConfirmProductInstanceInput{} + } + + req = c.newRequest(op, input, output) + output = &ConfirmProductInstanceOutput{} + req.Data = output + return +} + +// Determines whether a product code is associated with an instance. This action +// can only be used by the owner of the product code. It is useful when a product +// code owner needs to verify whether another user's instance is eligible for +// support. +func (c *EC2) ConfirmProductInstance(input *ConfirmProductInstanceInput) (*ConfirmProductInstanceOutput, error) { + req, out := c.ConfirmProductInstanceRequest(input) + err := req.Send() + return out, err +} + +const opCopyImage = "CopyImage" + +// CopyImageRequest generates a "aws/request.Request" representing the +// client's request for the CopyImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CopyImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CopyImageRequest method. +// req, resp := client.CopyImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CopyImageRequest(input *CopyImageInput) (req *request.Request, output *CopyImageOutput) { + op := &request.Operation{ + Name: opCopyImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CopyImageInput{} + } + + req = c.newRequest(op, input, output) + output = &CopyImageOutput{} + req.Data = output + return +} + +// Initiates the copy of an AMI from the specified source region to the current +// region. You specify the destination region by using its endpoint when making +// the request. +// +// For more information, see Copying AMIs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/CopyingAMIs.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CopyImage(input *CopyImageInput) (*CopyImageOutput, error) { + req, out := c.CopyImageRequest(input) + err := req.Send() + return out, err +} + +const opCopySnapshot = "CopySnapshot" + +// CopySnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CopySnapshot operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CopySnapshot method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CopySnapshotRequest method. +// req, resp := client.CopySnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *request.Request, output *CopySnapshotOutput) { + op := &request.Operation{ + Name: opCopySnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CopySnapshotInput{} + } + + req = c.newRequest(op, input, output) + output = &CopySnapshotOutput{} + req.Data = output + return +} + +// Copies a point-in-time snapshot of an EBS volume and stores it in Amazon +// S3. You can copy the snapshot within the same region or from one region to +// another. You can use the snapshot to create EBS volumes or Amazon Machine +// Images (AMIs). The snapshot is copied to the regional endpoint that you send +// the HTTP request to. +// +// Copies of encrypted EBS snapshots remain encrypted. Copies of unencrypted +// snapshots remain unencrypted, unless the Encrypted flag is specified during +// the snapshot copy operation. By default, encrypted snapshot copies use the +// default AWS Key Management Service (AWS KMS) customer master key (CMK); however, +// you can specify a non-default CMK with the KmsKeyId parameter. +// +// To copy an encrypted snapshot that has been shared from another account, +// you must have permissions for the CMK used to encrypt the snapshot. +// +// Snapshots created by the CopySnapshot action have an arbitrary volume +// ID that should not be used for any purpose. +// +// For more information, see Copying an Amazon EBS Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-copy-snapshot.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CopySnapshot(input *CopySnapshotInput) (*CopySnapshotOutput, error) { + req, out := c.CopySnapshotRequest(input) + err := req.Send() + return out, err +} + +const opCreateCustomerGateway = "CreateCustomerGateway" + +// CreateCustomerGatewayRequest generates a "aws/request.Request" representing the +// client's request for the CreateCustomerGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateCustomerGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateCustomerGatewayRequest method. +// req, resp := client.CreateCustomerGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (req *request.Request, output *CreateCustomerGatewayOutput) { + op := &request.Operation{ + Name: opCreateCustomerGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateCustomerGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateCustomerGatewayOutput{} + req.Data = output + return +} + +// Provides information to AWS about your VPN customer gateway device. The customer +// gateway is the appliance at your end of the VPN connection. (The device on +// the AWS side of the VPN connection is the virtual private gateway.) You must +// provide the Internet-routable IP address of the customer gateway's external +// interface. The IP address must be static and may be behind a device performing +// network address translation (NAT). +// +// For devices that use Border Gateway Protocol (BGP), you can also provide +// the device's BGP Autonomous System Number (ASN). You can use an existing +// ASN assigned to your network. If you don't have an ASN already, you can use +// a private ASN (in the 64512 - 65534 range). +// +// Amazon EC2 supports all 2-byte ASN numbers in the range of 1 - 65534, with +// the exception of 7224, which is reserved in the us-east-1 region, and 9059, +// which is reserved in the eu-west-1 region. +// +// For more information about VPN customer gateways, see Adding a Hardware +// Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// You cannot create more than one customer gateway with the same VPN type, +// IP address, and BGP ASN parameter values. If you run an identical request +// more than one time, the first request creates the customer gateway, and subsequent +// requests return information about the existing customer gateway. The subsequent +// requests do not create new customer gateway resources. +func (c *EC2) CreateCustomerGateway(input *CreateCustomerGatewayInput) (*CreateCustomerGatewayOutput, error) { + req, out := c.CreateCustomerGatewayRequest(input) + err := req.Send() + return out, err +} + +const opCreateDhcpOptions = "CreateDhcpOptions" + +// CreateDhcpOptionsRequest generates a "aws/request.Request" representing the +// client's request for the CreateDhcpOptions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateDhcpOptions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateDhcpOptionsRequest method. +// req, resp := client.CreateDhcpOptionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *request.Request, output *CreateDhcpOptionsOutput) { + op := &request.Operation{ + Name: opCreateDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDhcpOptionsInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateDhcpOptionsOutput{} + req.Data = output + return +} + +// Creates a set of DHCP options for your VPC. After creating the set, you must +// associate it with the VPC, causing all existing and new instances that you +// launch in the VPC to use this set of DHCP options. The following are the +// individual DHCP options you can specify. For more information about the options, +// see RFC 2132 (http://www.ietf.org/rfc/rfc2132.txt). +// +// domain-name-servers - The IP addresses of up to four domain name servers, +// or AmazonProvidedDNS. The default DHCP option set specifies AmazonProvidedDNS. +// If specifying more than one domain name server, specify the IP addresses +// in a single parameter, separated by commas. If you want your instance to +// receive a custom DNS hostname as specified in domain-name, you must set domain-name-servers +// to a custom DNS server. +// +// domain-name - If you're using AmazonProvidedDNS in "us-east-1", specify +// "ec2.internal". If you're using AmazonProvidedDNS in another region, specify +// "region.compute.internal" (for example, "ap-northeast-1.compute.internal"). +// Otherwise, specify a domain name (for example, "MyCompany.com"). This value +// is used to complete unqualified DNS hostnames. Important: Some Linux operating +// systems accept multiple domain names separated by spaces. However, Windows +// and other Linux operating systems treat the value as a single domain, which +// results in unexpected behavior. If your DHCP options set is associated with +// a VPC that has instances with multiple operating systems, specify only one +// domain name. +// +// ntp-servers - The IP addresses of up to four Network Time Protocol (NTP) +// servers. +// +// netbios-name-servers - The IP addresses of up to four NetBIOS name servers. +// +// netbios-node-type - The NetBIOS node type (1, 2, 4, or 8). We recommend +// that you specify 2 (broadcast and multicast are not currently supported). +// For more information about these node types, see RFC 2132 (http://www.ietf.org/rfc/rfc2132.txt). +// +// Your VPC automatically starts out with a set of DHCP options that includes +// only a DNS server that we provide (AmazonProvidedDNS). If you create a set +// of options, and if your VPC has an Internet gateway, make sure to set the +// domain-name-servers option either to AmazonProvidedDNS or to a domain name +// server of your choice. For more information about DHCP options, see DHCP +// Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateDhcpOptions(input *CreateDhcpOptionsInput) (*CreateDhcpOptionsOutput, error) { + req, out := c.CreateDhcpOptionsRequest(input) + err := req.Send() + return out, err +} + +const opCreateFlowLogs = "CreateFlowLogs" + +// CreateFlowLogsRequest generates a "aws/request.Request" representing the +// client's request for the CreateFlowLogs operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateFlowLogs method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateFlowLogsRequest method. +// req, resp := client.CreateFlowLogsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateFlowLogsRequest(input *CreateFlowLogsInput) (req *request.Request, output *CreateFlowLogsOutput) { + op := &request.Operation{ + Name: opCreateFlowLogs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateFlowLogsInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateFlowLogsOutput{} + req.Data = output + return +} + +// Creates one or more flow logs to capture IP traffic for a specific network +// interface, subnet, or VPC. Flow logs are delivered to a specified log group +// in Amazon CloudWatch Logs. If you specify a VPC or subnet in the request, +// a log stream is created in CloudWatch Logs for each network interface in +// the subnet or VPC. Log streams can include information about accepted and +// rejected traffic to a network interface. You can view the data in your log +// streams using Amazon CloudWatch Logs. +// +// In your request, you must also specify an IAM role that has permission to +// publish logs to CloudWatch Logs. +func (c *EC2) CreateFlowLogs(input *CreateFlowLogsInput) (*CreateFlowLogsOutput, error) { + req, out := c.CreateFlowLogsRequest(input) + err := req.Send() + return out, err +} + +const opCreateImage = "CreateImage" + +// CreateImageRequest generates a "aws/request.Request" representing the +// client's request for the CreateImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateImageRequest method. +// req, resp := client.CreateImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateImageRequest(input *CreateImageInput) (req *request.Request, output *CreateImageOutput) { + op := &request.Operation{ + Name: opCreateImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateImageInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateImageOutput{} + req.Data = output + return +} + +// Creates an Amazon EBS-backed AMI from an Amazon EBS-backed instance that +// is either running or stopped. +// +// If you customized your instance with instance store volumes or EBS volumes +// in addition to the root device volume, the new AMI contains block device +// mapping information for those volumes. When you launch an instance from this +// new AMI, the instance automatically launches with those additional volumes. +// +// For more information, see Creating Amazon EBS-Backed Linux AMIs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateImage(input *CreateImageInput) (*CreateImageOutput, error) { + req, out := c.CreateImageRequest(input) + err := req.Send() + return out, err +} + +const opCreateInstanceExportTask = "CreateInstanceExportTask" + +// CreateInstanceExportTaskRequest generates a "aws/request.Request" representing the +// client's request for the CreateInstanceExportTask operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateInstanceExportTask method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateInstanceExportTaskRequest method. +// req, resp := client.CreateInstanceExportTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateInstanceExportTaskRequest(input *CreateInstanceExportTaskInput) (req *request.Request, output *CreateInstanceExportTaskOutput) { + op := &request.Operation{ + Name: opCreateInstanceExportTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateInstanceExportTaskInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateInstanceExportTaskOutput{} + req.Data = output + return +} + +// Exports a running or stopped instance to an S3 bucket. +// +// For information about the supported operating systems, image formats, and +// known limitations for the types of instances you can export, see Exporting +// an Instance as a VM Using VM Import/Export (http://docs.aws.amazon.com/vm-import/latest/userguide/vmexport.html) +// in the VM Import/Export User Guide. +func (c *EC2) CreateInstanceExportTask(input *CreateInstanceExportTaskInput) (*CreateInstanceExportTaskOutput, error) { + req, out := c.CreateInstanceExportTaskRequest(input) + err := req.Send() + return out, err +} + +const opCreateInternetGateway = "CreateInternetGateway" + +// CreateInternetGatewayRequest generates a "aws/request.Request" representing the +// client's request for the CreateInternetGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateInternetGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateInternetGatewayRequest method. +// req, resp := client.CreateInternetGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateInternetGatewayRequest(input *CreateInternetGatewayInput) (req *request.Request, output *CreateInternetGatewayOutput) { + op := &request.Operation{ + Name: opCreateInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateInternetGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateInternetGatewayOutput{} + req.Data = output + return +} + +// Creates an Internet gateway for use with a VPC. After creating the Internet +// gateway, you attach it to a VPC using AttachInternetGateway. +// +// For more information about your VPC and Internet gateway, see the Amazon +// Virtual Private Cloud User Guide (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/). +func (c *EC2) CreateInternetGateway(input *CreateInternetGatewayInput) (*CreateInternetGatewayOutput, error) { + req, out := c.CreateInternetGatewayRequest(input) + err := req.Send() + return out, err +} + +const opCreateKeyPair = "CreateKeyPair" + +// CreateKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the CreateKeyPair operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateKeyPair method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateKeyPairRequest method. +// req, resp := client.CreateKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateKeyPairRequest(input *CreateKeyPairInput) (req *request.Request, output *CreateKeyPairOutput) { + op := &request.Operation{ + Name: opCreateKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateKeyPairInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateKeyPairOutput{} + req.Data = output + return +} + +// Creates a 2048-bit RSA key pair with the specified name. Amazon EC2 stores +// the public key and displays the private key for you to save to a file. The +// private key is returned as an unencrypted PEM encoded PKCS#8 private key. +// If a key with the specified name already exists, Amazon EC2 returns an error. +// +// You can have up to five thousand key pairs per region. +// +// The key pair returned to you is available only in the region in which you +// create it. To create a key pair that is available in all regions, use ImportKeyPair. +// +// For more information about key pairs, see Key Pairs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateKeyPair(input *CreateKeyPairInput) (*CreateKeyPairOutput, error) { + req, out := c.CreateKeyPairRequest(input) + err := req.Send() + return out, err +} + +const opCreateNatGateway = "CreateNatGateway" + +// CreateNatGatewayRequest generates a "aws/request.Request" representing the +// client's request for the CreateNatGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateNatGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateNatGatewayRequest method. +// req, resp := client.CreateNatGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateNatGatewayRequest(input *CreateNatGatewayInput) (req *request.Request, output *CreateNatGatewayOutput) { + op := &request.Operation{ + Name: opCreateNatGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateNatGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateNatGatewayOutput{} + req.Data = output + return +} + +// Creates a NAT gateway in the specified subnet. A NAT gateway can be used +// to enable instances in a private subnet to connect to the Internet. This +// action creates a network interface in the specified subnet with a private +// IP address from the IP address range of the subnet. For more information, +// see NAT Gateways (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateNatGateway(input *CreateNatGatewayInput) (*CreateNatGatewayOutput, error) { + req, out := c.CreateNatGatewayRequest(input) + err := req.Send() + return out, err +} + +const opCreateNetworkAcl = "CreateNetworkAcl" + +// CreateNetworkAclRequest generates a "aws/request.Request" representing the +// client's request for the CreateNetworkAcl operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateNetworkAcl method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateNetworkAclRequest method. +// req, resp := client.CreateNetworkAclRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateNetworkAclRequest(input *CreateNetworkAclInput) (req *request.Request, output *CreateNetworkAclOutput) { + op := &request.Operation{ + Name: opCreateNetworkAcl, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateNetworkAclInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateNetworkAclOutput{} + req.Data = output + return +} + +// Creates a network ACL in a VPC. Network ACLs provide an optional layer of +// security (in addition to security groups) for the instances in your VPC. +// +// For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateNetworkAcl(input *CreateNetworkAclInput) (*CreateNetworkAclOutput, error) { + req, out := c.CreateNetworkAclRequest(input) + err := req.Send() + return out, err +} + +const opCreateNetworkAclEntry = "CreateNetworkAclEntry" + +// CreateNetworkAclEntryRequest generates a "aws/request.Request" representing the +// client's request for the CreateNetworkAclEntry operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateNetworkAclEntry method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateNetworkAclEntryRequest method. +// req, resp := client.CreateNetworkAclEntryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateNetworkAclEntryRequest(input *CreateNetworkAclEntryInput) (req *request.Request, output *CreateNetworkAclEntryOutput) { + op := &request.Operation{ + Name: opCreateNetworkAclEntry, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateNetworkAclEntryInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &CreateNetworkAclEntryOutput{} + req.Data = output + return +} + +// Creates an entry (a rule) in a network ACL with the specified rule number. +// Each network ACL has a set of numbered ingress rules and a separate set of +// numbered egress rules. When determining whether a packet should be allowed +// in or out of a subnet associated with the ACL, we process the entries in +// the ACL according to the rule numbers, in ascending order. Each network ACL +// has a set of ingress rules and a separate set of egress rules. +// +// We recommend that you leave room between the rule numbers (for example, +// 100, 110, 120, ...), and not number them one right after the other (for example, +// 101, 102, 103, ...). This makes it easier to add a rule between existing +// ones without having to renumber the rules. +// +// After you add an entry, you can't modify it; you must either replace it, +// or create an entry and delete the old one. +// +// For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateNetworkAclEntry(input *CreateNetworkAclEntryInput) (*CreateNetworkAclEntryOutput, error) { + req, out := c.CreateNetworkAclEntryRequest(input) + err := req.Send() + return out, err +} + +const opCreateNetworkInterface = "CreateNetworkInterface" + +// CreateNetworkInterfaceRequest generates a "aws/request.Request" representing the +// client's request for the CreateNetworkInterface operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateNetworkInterface method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateNetworkInterfaceRequest method. +// req, resp := client.CreateNetworkInterfaceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateNetworkInterfaceRequest(input *CreateNetworkInterfaceInput) (req *request.Request, output *CreateNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opCreateNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateNetworkInterfaceInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateNetworkInterfaceOutput{} + req.Data = output + return +} + +// Creates a network interface in the specified subnet. +// +// For more information about network interfaces, see Elastic Network Interfaces +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) in the +// Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateNetworkInterface(input *CreateNetworkInterfaceInput) (*CreateNetworkInterfaceOutput, error) { + req, out := c.CreateNetworkInterfaceRequest(input) + err := req.Send() + return out, err +} + +const opCreatePlacementGroup = "CreatePlacementGroup" + +// CreatePlacementGroupRequest generates a "aws/request.Request" representing the +// client's request for the CreatePlacementGroup operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreatePlacementGroup method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreatePlacementGroupRequest method. +// req, resp := client.CreatePlacementGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreatePlacementGroupRequest(input *CreatePlacementGroupInput) (req *request.Request, output *CreatePlacementGroupOutput) { + op := &request.Operation{ + Name: opCreatePlacementGroup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreatePlacementGroupInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &CreatePlacementGroupOutput{} + req.Data = output + return +} + +// Creates a placement group that you launch cluster instances into. You must +// give the group a name that's unique within the scope of your account. +// +// For more information about placement groups and cluster instances, see Cluster +// Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cluster_computing.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreatePlacementGroup(input *CreatePlacementGroupInput) (*CreatePlacementGroupOutput, error) { + req, out := c.CreatePlacementGroupRequest(input) + err := req.Send() + return out, err +} + +const opCreateReservedInstancesListing = "CreateReservedInstancesListing" + +// CreateReservedInstancesListingRequest generates a "aws/request.Request" representing the +// client's request for the CreateReservedInstancesListing operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateReservedInstancesListing method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateReservedInstancesListingRequest method. +// req, resp := client.CreateReservedInstancesListingRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstancesListingInput) (req *request.Request, output *CreateReservedInstancesListingOutput) { + op := &request.Operation{ + Name: opCreateReservedInstancesListing, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateReservedInstancesListingInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateReservedInstancesListingOutput{} + req.Data = output + return +} + +// Creates a listing for Amazon EC2 Reserved Instances to be sold in the Reserved +// Instance Marketplace. You can submit one Reserved Instance listing at a time. +// To get a list of your Reserved Instances, you can use the DescribeReservedInstances +// operation. +// +// The Reserved Instance Marketplace matches sellers who want to resell Reserved +// Instance capacity that they no longer need with buyers who want to purchase +// additional capacity. Reserved Instances bought and sold through the Reserved +// Instance Marketplace work like any other Reserved Instances. +// +// To sell your Reserved Instances, you must first register as a seller in +// the Reserved Instance Marketplace. After completing the registration process, +// you can create a Reserved Instance Marketplace listing of some or all of +// your Reserved Instances, and specify the upfront price to receive for them. +// Your Reserved Instance listings then become available for purchase. To view +// the details of your Reserved Instance listing, you can use the DescribeReservedInstancesListings +// operation. +// +// For more information, see Reserved Instance Marketplace (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateReservedInstancesListing(input *CreateReservedInstancesListingInput) (*CreateReservedInstancesListingOutput, error) { + req, out := c.CreateReservedInstancesListingRequest(input) + err := req.Send() + return out, err +} + +const opCreateRoute = "CreateRoute" + +// CreateRouteRequest generates a "aws/request.Request" representing the +// client's request for the CreateRoute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateRoute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateRouteRequest method. +// req, resp := client.CreateRouteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateRouteRequest(input *CreateRouteInput) (req *request.Request, output *CreateRouteOutput) { + op := &request.Operation{ + Name: opCreateRoute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateRouteInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateRouteOutput{} + req.Data = output + return +} + +// Creates a route in a route table within a VPC. +// +// You must specify one of the following targets: Internet gateway or virtual +// private gateway, NAT instance, NAT gateway, VPC peering connection, or network +// interface. +// +// When determining how to route traffic, we use the route with the most specific +// match. For example, let's say the traffic is destined for 192.0.2.3, and +// the route table includes the following two routes: +// +// 192.0.2.0/24 (goes to some target A) +// +// 192.0.2.0/28 (goes to some target B) +// +// Both routes apply to the traffic destined for 192.0.2.3. However, the +// second route in the list covers a smaller number of IP addresses and is therefore +// more specific, so we use that route to determine where to target the traffic. +// +// For more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateRoute(input *CreateRouteInput) (*CreateRouteOutput, error) { + req, out := c.CreateRouteRequest(input) + err := req.Send() + return out, err +} + +const opCreateRouteTable = "CreateRouteTable" + +// CreateRouteTableRequest generates a "aws/request.Request" representing the +// client's request for the CreateRouteTable operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateRouteTable method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateRouteTableRequest method. +// req, resp := client.CreateRouteTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateRouteTableRequest(input *CreateRouteTableInput) (req *request.Request, output *CreateRouteTableOutput) { + op := &request.Operation{ + Name: opCreateRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateRouteTableInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateRouteTableOutput{} + req.Data = output + return +} + +// Creates a route table for the specified VPC. After you create a route table, +// you can add routes and associate the table with a subnet. +// +// For more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateRouteTable(input *CreateRouteTableInput) (*CreateRouteTableOutput, error) { + req, out := c.CreateRouteTableRequest(input) + err := req.Send() + return out, err +} + +const opCreateSecurityGroup = "CreateSecurityGroup" + +// CreateSecurityGroupRequest generates a "aws/request.Request" representing the +// client's request for the CreateSecurityGroup operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateSecurityGroup method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateSecurityGroupRequest method. +// req, resp := client.CreateSecurityGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateSecurityGroupRequest(input *CreateSecurityGroupInput) (req *request.Request, output *CreateSecurityGroupOutput) { + op := &request.Operation{ + Name: opCreateSecurityGroup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateSecurityGroupInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateSecurityGroupOutput{} + req.Data = output + return +} + +// Creates a security group. +// +// A security group is for use with instances either in the EC2-Classic platform +// or in a specific VPC. For more information, see Amazon EC2 Security Groups +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) +// in the Amazon Elastic Compute Cloud User Guide and Security Groups for Your +// VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// EC2-Classic: You can have up to 500 security groups. +// +// EC2-VPC: You can create up to 500 security groups per VPC. +// +// When you create a security group, you specify a friendly name of your choice. +// You can have a security group for use in EC2-Classic with the same name as +// a security group for use in a VPC. However, you can't have two security groups +// for use in EC2-Classic with the same name or two security groups for use +// in a VPC with the same name. +// +// You have a default security group for use in EC2-Classic and a default security +// group for use in your VPC. If you don't specify a security group when you +// launch an instance, the instance is launched into the appropriate default +// security group. A default security group includes a default rule that grants +// instances unrestricted network access to each other. +// +// You can add or remove rules from your security groups using AuthorizeSecurityGroupIngress, +// AuthorizeSecurityGroupEgress, RevokeSecurityGroupIngress, and RevokeSecurityGroupEgress. +func (c *EC2) CreateSecurityGroup(input *CreateSecurityGroupInput) (*CreateSecurityGroupOutput, error) { + req, out := c.CreateSecurityGroupRequest(input) + err := req.Send() + return out, err +} + +const opCreateSnapshot = "CreateSnapshot" + +// CreateSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateSnapshot operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateSnapshot method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateSnapshotRequest method. +// req, resp := client.CreateSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateSnapshotRequest(input *CreateSnapshotInput) (req *request.Request, output *Snapshot) { + op := &request.Operation{ + Name: opCreateSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateSnapshotInput{} + } + + req = c.newRequest(op, input, output) + output = &Snapshot{} + req.Data = output + return +} + +// Creates a snapshot of an EBS volume and stores it in Amazon S3. You can use +// snapshots for backups, to make copies of EBS volumes, and to save data before +// shutting down an instance. +// +// When a snapshot is created, any AWS Marketplace product codes that are associated +// with the source volume are propagated to the snapshot. +// +// You can take a snapshot of an attached volume that is in use. However, snapshots +// only capture data that has been written to your EBS volume at the time the +// snapshot command is issued; this may exclude any data that has been cached +// by any applications or the operating system. If you can pause any file systems +// on the volume long enough to take a snapshot, your snapshot should be complete. +// However, if you cannot pause all file writes to the volume, you should unmount +// the volume from within the instance, issue the snapshot command, and then +// remount the volume to ensure a consistent and complete snapshot. You may +// remount and use your volume while the snapshot status is pending. +// +// To create a snapshot for EBS volumes that serve as root devices, you should +// stop the instance before taking the snapshot. +// +// Snapshots that are taken from encrypted volumes are automatically encrypted. +// Volumes that are created from encrypted snapshots are also automatically +// encrypted. Your encrypted volumes and any associated snapshots always remain +// protected. +// +// For more information, see Amazon Elastic Block Store (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html) +// and Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateSnapshot(input *CreateSnapshotInput) (*Snapshot, error) { + req, out := c.CreateSnapshotRequest(input) + err := req.Send() + return out, err +} + +const opCreateSpotDatafeedSubscription = "CreateSpotDatafeedSubscription" + +// CreateSpotDatafeedSubscriptionRequest generates a "aws/request.Request" representing the +// client's request for the CreateSpotDatafeedSubscription operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateSpotDatafeedSubscription method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateSpotDatafeedSubscriptionRequest method. +// req, resp := client.CreateSpotDatafeedSubscriptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateSpotDatafeedSubscriptionRequest(input *CreateSpotDatafeedSubscriptionInput) (req *request.Request, output *CreateSpotDatafeedSubscriptionOutput) { + op := &request.Operation{ + Name: opCreateSpotDatafeedSubscription, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateSpotDatafeedSubscriptionInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateSpotDatafeedSubscriptionOutput{} + req.Data = output + return +} + +// Creates a data feed for Spot instances, enabling you to view Spot instance +// usage logs. You can create one data feed per AWS account. For more information, +// see Spot Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateSpotDatafeedSubscription(input *CreateSpotDatafeedSubscriptionInput) (*CreateSpotDatafeedSubscriptionOutput, error) { + req, out := c.CreateSpotDatafeedSubscriptionRequest(input) + err := req.Send() + return out, err +} + +const opCreateSubnet = "CreateSubnet" + +// CreateSubnetRequest generates a "aws/request.Request" representing the +// client's request for the CreateSubnet operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateSubnet method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateSubnetRequest method. +// req, resp := client.CreateSubnetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Request, output *CreateSubnetOutput) { + op := &request.Operation{ + Name: opCreateSubnet, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateSubnetInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateSubnetOutput{} + req.Data = output + return +} + +// Creates a subnet in an existing VPC. +// +// When you create each subnet, you provide the VPC ID and the CIDR block you +// want for the subnet. After you create a subnet, you can't change its CIDR +// block. The subnet's CIDR block can be the same as the VPC's CIDR block (assuming +// you want only a single subnet in the VPC), or a subset of the VPC's CIDR +// block. If you create more than one subnet in a VPC, the subnets' CIDR blocks +// must not overlap. The smallest subnet (and VPC) you can create uses a /28 +// netmask (16 IP addresses), and the largest uses a /16 netmask (65,536 IP +// addresses). +// +// AWS reserves both the first four and the last IP address in each subnet's +// CIDR block. They're not available for use. +// +// If you add more than one subnet to a VPC, they're set up in a star topology +// with a logical router in the middle. +// +// If you launch an instance in a VPC using an Amazon EBS-backed AMI, the IP +// address doesn't change if you stop and restart the instance (unlike a similar +// instance launched outside a VPC, which gets a new IP address when restarted). +// It's therefore possible to have a subnet with no running instances (they're +// all stopped), but no remaining IP addresses available. +// +// For more information about subnets, see Your VPC and Subnets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateSubnet(input *CreateSubnetInput) (*CreateSubnetOutput, error) { + req, out := c.CreateSubnetRequest(input) + err := req.Send() + return out, err +} + +const opCreateTags = "CreateTags" + +// CreateTagsRequest generates a "aws/request.Request" representing the +// client's request for the CreateTags operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateTags method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateTagsRequest method. +// req, resp := client.CreateTagsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateTagsRequest(input *CreateTagsInput) (req *request.Request, output *CreateTagsOutput) { + op := &request.Operation{ + Name: opCreateTags, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateTagsInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &CreateTagsOutput{} + req.Data = output + return +} + +// Adds or overwrites one or more tags for the specified Amazon EC2 resource +// or resources. Each resource can have a maximum of 50 tags. Each tag consists +// of a key and optional value. Tag keys must be unique per resource. +// +// For more information about tags, see Tagging Your Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) +// in the Amazon Elastic Compute Cloud User Guide. For more information about +// creating IAM policies that control users' access to resources based on tags, +// see Supported Resource-Level Permissions for Amazon EC2 API Actions (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-supported-iam-actions-resources.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateTags(input *CreateTagsInput) (*CreateTagsOutput, error) { + req, out := c.CreateTagsRequest(input) + err := req.Send() + return out, err +} + +const opCreateVolume = "CreateVolume" + +// CreateVolumeRequest generates a "aws/request.Request" representing the +// client's request for the CreateVolume operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVolume method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVolumeRequest method. +// req, resp := client.CreateVolumeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVolumeRequest(input *CreateVolumeInput) (req *request.Request, output *Volume) { + op := &request.Operation{ + Name: opCreateVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &Volume{} + req.Data = output + return +} + +// Creates an EBS volume that can be attached to an instance in the same Availability +// Zone. The volume is created in the regional endpoint that you send the HTTP +// request to. For more information see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html). +// +// You can create a new empty volume or restore a volume from an EBS snapshot. +// Any AWS Marketplace product codes from the snapshot are propagated to the +// volume. +// +// You can create encrypted volumes with the Encrypted parameter. Encrypted +// volumes may only be attached to instances that support Amazon EBS encryption. +// Volumes that are created from encrypted snapshots are also automatically +// encrypted. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// For more information, see Creating or Restoring an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateVolume(input *CreateVolumeInput) (*Volume, error) { + req, out := c.CreateVolumeRequest(input) + err := req.Send() + return out, err +} + +const opCreateVpc = "CreateVpc" + +// CreateVpcRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpc operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVpc method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVpcRequest method. +// req, resp := client.CreateVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVpcRequest(input *CreateVpcInput) (req *request.Request, output *CreateVpcOutput) { + op := &request.Operation{ + Name: opCreateVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpcInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateVpcOutput{} + req.Data = output + return +} + +// Creates a VPC with the specified CIDR block. +// +// The smallest VPC you can create uses a /28 netmask (16 IP addresses), and +// the largest uses a /16 netmask (65,536 IP addresses). To help you decide +// how big to make your VPC, see Your VPC and Subnets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// By default, each instance you launch in the VPC has the default DHCP options, +// which includes only a default DNS server that we provide (AmazonProvidedDNS). +// For more information about DHCP options, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// You can specify the instance tenancy value for the VPC when you create it. +// You can't change this value for the VPC after you create it. For more information, +// see Dedicated Instances (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/dedicated-instance.html.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateVpc(input *CreateVpcInput) (*CreateVpcOutput, error) { + req, out := c.CreateVpcRequest(input) + err := req.Send() + return out, err +} + +const opCreateVpcEndpoint = "CreateVpcEndpoint" + +// CreateVpcEndpointRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpcEndpoint operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVpcEndpoint method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVpcEndpointRequest method. +// req, resp := client.CreateVpcEndpointRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVpcEndpointRequest(input *CreateVpcEndpointInput) (req *request.Request, output *CreateVpcEndpointOutput) { + op := &request.Operation{ + Name: opCreateVpcEndpoint, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpcEndpointInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateVpcEndpointOutput{} + req.Data = output + return +} + +// Creates a VPC endpoint for a specified AWS service. An endpoint enables you +// to create a private connection between your VPC and another AWS service in +// your account. You can specify an endpoint policy to attach to the endpoint +// that will control access to the service from your VPC. You can also specify +// the VPC route tables that use the endpoint. +// +// Currently, only endpoints to Amazon S3 are supported. +func (c *EC2) CreateVpcEndpoint(input *CreateVpcEndpointInput) (*CreateVpcEndpointOutput, error) { + req, out := c.CreateVpcEndpointRequest(input) + err := req.Send() + return out, err +} + +const opCreateVpcPeeringConnection = "CreateVpcPeeringConnection" + +// CreateVpcPeeringConnectionRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpcPeeringConnection operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVpcPeeringConnection method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVpcPeeringConnectionRequest method. +// req, resp := client.CreateVpcPeeringConnectionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectionInput) (req *request.Request, output *CreateVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opCreateVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpcPeeringConnectionInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateVpcPeeringConnectionOutput{} + req.Data = output + return +} + +// Requests a VPC peering connection between two VPCs: a requester VPC that +// you own and a peer VPC with which to create the connection. The peer VPC +// can belong to another AWS account. The requester VPC and peer VPC cannot +// have overlapping CIDR blocks. +// +// The owner of the peer VPC must accept the peering request to activate the +// peering connection. The VPC peering connection request expires after 7 days, +// after which it cannot be accepted or rejected. +// +// A CreateVpcPeeringConnection request between VPCs with overlapping CIDR +// blocks results in the VPC peering connection having a status of failed. +func (c *EC2) CreateVpcPeeringConnection(input *CreateVpcPeeringConnectionInput) (*CreateVpcPeeringConnectionOutput, error) { + req, out := c.CreateVpcPeeringConnectionRequest(input) + err := req.Send() + return out, err +} + +const opCreateVpnConnection = "CreateVpnConnection" + +// CreateVpnConnectionRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpnConnection operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVpnConnection method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVpnConnectionRequest method. +// req, resp := client.CreateVpnConnectionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVpnConnectionRequest(input *CreateVpnConnectionInput) (req *request.Request, output *CreateVpnConnectionOutput) { + op := &request.Operation{ + Name: opCreateVpnConnection, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpnConnectionInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateVpnConnectionOutput{} + req.Data = output + return +} + +// Creates a VPN connection between an existing virtual private gateway and +// a VPN customer gateway. The only supported connection type is ipsec.1. +// +// The response includes information that you need to give to your network +// administrator to configure your customer gateway. +// +// We strongly recommend that you use HTTPS when calling this operation because +// the response contains sensitive cryptographic information for configuring +// your customer gateway. +// +// If you decide to shut down your VPN connection for any reason and later +// create a new VPN connection, you must reconfigure your customer gateway with +// the new information returned from this call. +// +// This is an idempotent operation. If you perform the operation more than +// once, Amazon EC2 doesn't return an error. +// +// For more information about VPN connections, see Adding a Hardware Virtual +// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateVpnConnection(input *CreateVpnConnectionInput) (*CreateVpnConnectionOutput, error) { + req, out := c.CreateVpnConnectionRequest(input) + err := req.Send() + return out, err +} + +const opCreateVpnConnectionRoute = "CreateVpnConnectionRoute" + +// CreateVpnConnectionRouteRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpnConnectionRoute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVpnConnectionRoute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVpnConnectionRouteRequest method. +// req, resp := client.CreateVpnConnectionRouteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVpnConnectionRouteRequest(input *CreateVpnConnectionRouteInput) (req *request.Request, output *CreateVpnConnectionRouteOutput) { + op := &request.Operation{ + Name: opCreateVpnConnectionRoute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpnConnectionRouteInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &CreateVpnConnectionRouteOutput{} + req.Data = output + return +} + +// Creates a static route associated with a VPN connection between an existing +// virtual private gateway and a VPN customer gateway. The static route allows +// traffic to be routed from the virtual private gateway to the VPN customer +// gateway. +// +// For more information about VPN connections, see Adding a Hardware Virtual +// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateVpnConnectionRoute(input *CreateVpnConnectionRouteInput) (*CreateVpnConnectionRouteOutput, error) { + req, out := c.CreateVpnConnectionRouteRequest(input) + err := req.Send() + return out, err +} + +const opCreateVpnGateway = "CreateVpnGateway" + +// CreateVpnGatewayRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpnGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateVpnGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateVpnGatewayRequest method. +// req, resp := client.CreateVpnGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) CreateVpnGatewayRequest(input *CreateVpnGatewayInput) (req *request.Request, output *CreateVpnGatewayOutput) { + op := &request.Operation{ + Name: opCreateVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpnGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateVpnGatewayOutput{} + req.Data = output + return +} + +// Creates a virtual private gateway. A virtual private gateway is the endpoint +// on the VPC side of your VPN connection. You can create a virtual private +// gateway before creating the VPC itself. +// +// For more information about virtual private gateways, see Adding a Hardware +// Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) CreateVpnGateway(input *CreateVpnGatewayInput) (*CreateVpnGatewayOutput, error) { + req, out := c.CreateVpnGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDeleteCustomerGateway = "DeleteCustomerGateway" + +// DeleteCustomerGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DeleteCustomerGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteCustomerGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteCustomerGatewayRequest method. +// req, resp := client.DeleteCustomerGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteCustomerGatewayRequest(input *DeleteCustomerGatewayInput) (req *request.Request, output *DeleteCustomerGatewayOutput) { + op := &request.Operation{ + Name: opDeleteCustomerGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteCustomerGatewayInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteCustomerGatewayOutput{} + req.Data = output + return +} + +// Deletes the specified customer gateway. You must delete the VPN connection +// before you can delete the customer gateway. +func (c *EC2) DeleteCustomerGateway(input *DeleteCustomerGatewayInput) (*DeleteCustomerGatewayOutput, error) { + req, out := c.DeleteCustomerGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDeleteDhcpOptions = "DeleteDhcpOptions" + +// DeleteDhcpOptionsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDhcpOptions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteDhcpOptions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteDhcpOptionsRequest method. +// req, resp := client.DeleteDhcpOptionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteDhcpOptionsRequest(input *DeleteDhcpOptionsInput) (req *request.Request, output *DeleteDhcpOptionsOutput) { + op := &request.Operation{ + Name: opDeleteDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDhcpOptionsInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteDhcpOptionsOutput{} + req.Data = output + return +} + +// Deletes the specified set of DHCP options. You must disassociate the set +// of DHCP options before you can delete it. You can disassociate the set of +// DHCP options by associating either a new set of options or the default set +// of options with the VPC. +func (c *EC2) DeleteDhcpOptions(input *DeleteDhcpOptionsInput) (*DeleteDhcpOptionsOutput, error) { + req, out := c.DeleteDhcpOptionsRequest(input) + err := req.Send() + return out, err +} + +const opDeleteFlowLogs = "DeleteFlowLogs" + +// DeleteFlowLogsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteFlowLogs operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteFlowLogs method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteFlowLogsRequest method. +// req, resp := client.DeleteFlowLogsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteFlowLogsRequest(input *DeleteFlowLogsInput) (req *request.Request, output *DeleteFlowLogsOutput) { + op := &request.Operation{ + Name: opDeleteFlowLogs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteFlowLogsInput{} + } + + req = c.newRequest(op, input, output) + output = &DeleteFlowLogsOutput{} + req.Data = output + return +} + +// Deletes one or more flow logs. +func (c *EC2) DeleteFlowLogs(input *DeleteFlowLogsInput) (*DeleteFlowLogsOutput, error) { + req, out := c.DeleteFlowLogsRequest(input) + err := req.Send() + return out, err +} + +const opDeleteInternetGateway = "DeleteInternetGateway" + +// DeleteInternetGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DeleteInternetGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteInternetGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteInternetGatewayRequest method. +// req, resp := client.DeleteInternetGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteInternetGatewayRequest(input *DeleteInternetGatewayInput) (req *request.Request, output *DeleteInternetGatewayOutput) { + op := &request.Operation{ + Name: opDeleteInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteInternetGatewayInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteInternetGatewayOutput{} + req.Data = output + return +} + +// Deletes the specified Internet gateway. You must detach the Internet gateway +// from the VPC before you can delete it. +func (c *EC2) DeleteInternetGateway(input *DeleteInternetGatewayInput) (*DeleteInternetGatewayOutput, error) { + req, out := c.DeleteInternetGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDeleteKeyPair = "DeleteKeyPair" + +// DeleteKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the DeleteKeyPair operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteKeyPair method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteKeyPairRequest method. +// req, resp := client.DeleteKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteKeyPairRequest(input *DeleteKeyPairInput) (req *request.Request, output *DeleteKeyPairOutput) { + op := &request.Operation{ + Name: opDeleteKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteKeyPairInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteKeyPairOutput{} + req.Data = output + return +} + +// Deletes the specified key pair, by removing the public key from Amazon EC2. +func (c *EC2) DeleteKeyPair(input *DeleteKeyPairInput) (*DeleteKeyPairOutput, error) { + req, out := c.DeleteKeyPairRequest(input) + err := req.Send() + return out, err +} + +const opDeleteNatGateway = "DeleteNatGateway" + +// DeleteNatGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DeleteNatGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteNatGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteNatGatewayRequest method. +// req, resp := client.DeleteNatGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteNatGatewayRequest(input *DeleteNatGatewayInput) (req *request.Request, output *DeleteNatGatewayOutput) { + op := &request.Operation{ + Name: opDeleteNatGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteNatGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &DeleteNatGatewayOutput{} + req.Data = output + return +} + +// Deletes the specified NAT gateway. Deleting a NAT gateway disassociates its +// Elastic IP address, but does not release the address from your account. Deleting +// a NAT gateway does not delete any NAT gateway routes in your route tables. +func (c *EC2) DeleteNatGateway(input *DeleteNatGatewayInput) (*DeleteNatGatewayOutput, error) { + req, out := c.DeleteNatGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDeleteNetworkAcl = "DeleteNetworkAcl" + +// DeleteNetworkAclRequest generates a "aws/request.Request" representing the +// client's request for the DeleteNetworkAcl operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteNetworkAcl method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteNetworkAclRequest method. +// req, resp := client.DeleteNetworkAclRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteNetworkAclRequest(input *DeleteNetworkAclInput) (req *request.Request, output *DeleteNetworkAclOutput) { + op := &request.Operation{ + Name: opDeleteNetworkAcl, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteNetworkAclInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteNetworkAclOutput{} + req.Data = output + return +} + +// Deletes the specified network ACL. You can't delete the ACL if it's associated +// with any subnets. You can't delete the default network ACL. +func (c *EC2) DeleteNetworkAcl(input *DeleteNetworkAclInput) (*DeleteNetworkAclOutput, error) { + req, out := c.DeleteNetworkAclRequest(input) + err := req.Send() + return out, err +} + +const opDeleteNetworkAclEntry = "DeleteNetworkAclEntry" + +// DeleteNetworkAclEntryRequest generates a "aws/request.Request" representing the +// client's request for the DeleteNetworkAclEntry operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteNetworkAclEntry method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteNetworkAclEntryRequest method. +// req, resp := client.DeleteNetworkAclEntryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteNetworkAclEntryRequest(input *DeleteNetworkAclEntryInput) (req *request.Request, output *DeleteNetworkAclEntryOutput) { + op := &request.Operation{ + Name: opDeleteNetworkAclEntry, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteNetworkAclEntryInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteNetworkAclEntryOutput{} + req.Data = output + return +} + +// Deletes the specified ingress or egress entry (rule) from the specified network +// ACL. +func (c *EC2) DeleteNetworkAclEntry(input *DeleteNetworkAclEntryInput) (*DeleteNetworkAclEntryOutput, error) { + req, out := c.DeleteNetworkAclEntryRequest(input) + err := req.Send() + return out, err +} + +const opDeleteNetworkInterface = "DeleteNetworkInterface" + +// DeleteNetworkInterfaceRequest generates a "aws/request.Request" representing the +// client's request for the DeleteNetworkInterface operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteNetworkInterface method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteNetworkInterfaceRequest method. +// req, resp := client.DeleteNetworkInterfaceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteNetworkInterfaceRequest(input *DeleteNetworkInterfaceInput) (req *request.Request, output *DeleteNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opDeleteNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteNetworkInterfaceInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteNetworkInterfaceOutput{} + req.Data = output + return +} + +// Deletes the specified network interface. You must detach the network interface +// before you can delete it. +func (c *EC2) DeleteNetworkInterface(input *DeleteNetworkInterfaceInput) (*DeleteNetworkInterfaceOutput, error) { + req, out := c.DeleteNetworkInterfaceRequest(input) + err := req.Send() + return out, err +} + +const opDeletePlacementGroup = "DeletePlacementGroup" + +// DeletePlacementGroupRequest generates a "aws/request.Request" representing the +// client's request for the DeletePlacementGroup operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeletePlacementGroup method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeletePlacementGroupRequest method. +// req, resp := client.DeletePlacementGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeletePlacementGroupRequest(input *DeletePlacementGroupInput) (req *request.Request, output *DeletePlacementGroupOutput) { + op := &request.Operation{ + Name: opDeletePlacementGroup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeletePlacementGroupInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeletePlacementGroupOutput{} + req.Data = output + return +} + +// Deletes the specified placement group. You must terminate all instances in +// the placement group before you can delete the placement group. For more information +// about placement groups and cluster instances, see Cluster Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cluster_computing.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DeletePlacementGroup(input *DeletePlacementGroupInput) (*DeletePlacementGroupOutput, error) { + req, out := c.DeletePlacementGroupRequest(input) + err := req.Send() + return out, err +} + +const opDeleteRoute = "DeleteRoute" + +// DeleteRouteRequest generates a "aws/request.Request" representing the +// client's request for the DeleteRoute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteRoute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteRouteRequest method. +// req, resp := client.DeleteRouteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteRouteRequest(input *DeleteRouteInput) (req *request.Request, output *DeleteRouteOutput) { + op := &request.Operation{ + Name: opDeleteRoute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteRouteInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteRouteOutput{} + req.Data = output + return +} + +// Deletes the specified route from the specified route table. +func (c *EC2) DeleteRoute(input *DeleteRouteInput) (*DeleteRouteOutput, error) { + req, out := c.DeleteRouteRequest(input) + err := req.Send() + return out, err +} + +const opDeleteRouteTable = "DeleteRouteTable" + +// DeleteRouteTableRequest generates a "aws/request.Request" representing the +// client's request for the DeleteRouteTable operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteRouteTable method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteRouteTableRequest method. +// req, resp := client.DeleteRouteTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteRouteTableRequest(input *DeleteRouteTableInput) (req *request.Request, output *DeleteRouteTableOutput) { + op := &request.Operation{ + Name: opDeleteRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteRouteTableInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteRouteTableOutput{} + req.Data = output + return +} + +// Deletes the specified route table. You must disassociate the route table +// from any subnets before you can delete it. You can't delete the main route +// table. +func (c *EC2) DeleteRouteTable(input *DeleteRouteTableInput) (*DeleteRouteTableOutput, error) { + req, out := c.DeleteRouteTableRequest(input) + err := req.Send() + return out, err +} + +const opDeleteSecurityGroup = "DeleteSecurityGroup" + +// DeleteSecurityGroupRequest generates a "aws/request.Request" representing the +// client's request for the DeleteSecurityGroup operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteSecurityGroup method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteSecurityGroupRequest method. +// req, resp := client.DeleteSecurityGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteSecurityGroupRequest(input *DeleteSecurityGroupInput) (req *request.Request, output *DeleteSecurityGroupOutput) { + op := &request.Operation{ + Name: opDeleteSecurityGroup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteSecurityGroupInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteSecurityGroupOutput{} + req.Data = output + return +} + +// Deletes a security group. +// +// If you attempt to delete a security group that is associated with an instance, +// or is referenced by another security group, the operation fails with InvalidGroup.InUse +// in EC2-Classic or DependencyViolation in EC2-VPC. +func (c *EC2) DeleteSecurityGroup(input *DeleteSecurityGroupInput) (*DeleteSecurityGroupOutput, error) { + req, out := c.DeleteSecurityGroupRequest(input) + err := req.Send() + return out, err +} + +const opDeleteSnapshot = "DeleteSnapshot" + +// DeleteSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the DeleteSnapshot operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteSnapshot method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteSnapshotRequest method. +// req, resp := client.DeleteSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteSnapshotRequest(input *DeleteSnapshotInput) (req *request.Request, output *DeleteSnapshotOutput) { + op := &request.Operation{ + Name: opDeleteSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteSnapshotInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteSnapshotOutput{} + req.Data = output + return +} + +// Deletes the specified snapshot. +// +// When you make periodic snapshots of a volume, the snapshots are incremental, +// and only the blocks on the device that have changed since your last snapshot +// are saved in the new snapshot. When you delete a snapshot, only the data +// not needed for any other snapshot is removed. So regardless of which prior +// snapshots have been deleted, all active snapshots will have access to all +// the information needed to restore the volume. +// +// You cannot delete a snapshot of the root device of an EBS volume used by +// a registered AMI. You must first de-register the AMI before you can delete +// the snapshot. +// +// For more information, see Deleting an Amazon EBS Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-deleting-snapshot.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DeleteSnapshot(input *DeleteSnapshotInput) (*DeleteSnapshotOutput, error) { + req, out := c.DeleteSnapshotRequest(input) + err := req.Send() + return out, err +} + +const opDeleteSpotDatafeedSubscription = "DeleteSpotDatafeedSubscription" + +// DeleteSpotDatafeedSubscriptionRequest generates a "aws/request.Request" representing the +// client's request for the DeleteSpotDatafeedSubscription operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteSpotDatafeedSubscription method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteSpotDatafeedSubscriptionRequest method. +// req, resp := client.DeleteSpotDatafeedSubscriptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteSpotDatafeedSubscriptionRequest(input *DeleteSpotDatafeedSubscriptionInput) (req *request.Request, output *DeleteSpotDatafeedSubscriptionOutput) { + op := &request.Operation{ + Name: opDeleteSpotDatafeedSubscription, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteSpotDatafeedSubscriptionInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteSpotDatafeedSubscriptionOutput{} + req.Data = output + return +} + +// Deletes the data feed for Spot instances. +func (c *EC2) DeleteSpotDatafeedSubscription(input *DeleteSpotDatafeedSubscriptionInput) (*DeleteSpotDatafeedSubscriptionOutput, error) { + req, out := c.DeleteSpotDatafeedSubscriptionRequest(input) + err := req.Send() + return out, err +} + +const opDeleteSubnet = "DeleteSubnet" + +// DeleteSubnetRequest generates a "aws/request.Request" representing the +// client's request for the DeleteSubnet operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteSubnet method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteSubnetRequest method. +// req, resp := client.DeleteSubnetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteSubnetRequest(input *DeleteSubnetInput) (req *request.Request, output *DeleteSubnetOutput) { + op := &request.Operation{ + Name: opDeleteSubnet, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteSubnetInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteSubnetOutput{} + req.Data = output + return +} + +// Deletes the specified subnet. You must terminate all running instances in +// the subnet before you can delete the subnet. +func (c *EC2) DeleteSubnet(input *DeleteSubnetInput) (*DeleteSubnetOutput, error) { + req, out := c.DeleteSubnetRequest(input) + err := req.Send() + return out, err +} + +const opDeleteTags = "DeleteTags" + +// DeleteTagsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteTags operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteTags method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteTagsRequest method. +// req, resp := client.DeleteTagsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, output *DeleteTagsOutput) { + op := &request.Operation{ + Name: opDeleteTags, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteTagsInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteTagsOutput{} + req.Data = output + return +} + +// Deletes the specified set of tags from the specified set of resources. This +// call is designed to follow a DescribeTags request. +// +// For more information about tags, see Tagging Your Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DeleteTags(input *DeleteTagsInput) (*DeleteTagsOutput, error) { + req, out := c.DeleteTagsRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVolume = "DeleteVolume" + +// DeleteVolumeRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVolume operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVolume method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVolumeRequest method. +// req, resp := client.DeleteVolumeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVolumeRequest(input *DeleteVolumeInput) (req *request.Request, output *DeleteVolumeOutput) { + op := &request.Operation{ + Name: opDeleteVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVolumeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteVolumeOutput{} + req.Data = output + return +} + +// Deletes the specified EBS volume. The volume must be in the available state +// (not attached to an instance). +// +// The volume may remain in the deleting state for several minutes. +// +// For more information, see Deleting an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-deleting-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DeleteVolume(input *DeleteVolumeInput) (*DeleteVolumeOutput, error) { + req, out := c.DeleteVolumeRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVpc = "DeleteVpc" + +// DeleteVpcRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpc operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVpc method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVpcRequest method. +// req, resp := client.DeleteVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVpcRequest(input *DeleteVpcInput) (req *request.Request, output *DeleteVpcOutput) { + op := &request.Operation{ + Name: opDeleteVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpcInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteVpcOutput{} + req.Data = output + return +} + +// Deletes the specified VPC. You must detach or delete all gateways and resources +// that are associated with the VPC before you can delete it. For example, you +// must terminate all instances running in the VPC, delete all security groups +// associated with the VPC (except the default one), delete all route tables +// associated with the VPC (except the default one), and so on. +func (c *EC2) DeleteVpc(input *DeleteVpcInput) (*DeleteVpcOutput, error) { + req, out := c.DeleteVpcRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVpcEndpoints = "DeleteVpcEndpoints" + +// DeleteVpcEndpointsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpcEndpoints operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVpcEndpoints method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVpcEndpointsRequest method. +// req, resp := client.DeleteVpcEndpointsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVpcEndpointsRequest(input *DeleteVpcEndpointsInput) (req *request.Request, output *DeleteVpcEndpointsOutput) { + op := &request.Operation{ + Name: opDeleteVpcEndpoints, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpcEndpointsInput{} + } + + req = c.newRequest(op, input, output) + output = &DeleteVpcEndpointsOutput{} + req.Data = output + return +} + +// Deletes one or more specified VPC endpoints. Deleting the endpoint also deletes +// the endpoint routes in the route tables that were associated with the endpoint. +func (c *EC2) DeleteVpcEndpoints(input *DeleteVpcEndpointsInput) (*DeleteVpcEndpointsOutput, error) { + req, out := c.DeleteVpcEndpointsRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVpcPeeringConnection = "DeleteVpcPeeringConnection" + +// DeleteVpcPeeringConnectionRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpcPeeringConnection operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVpcPeeringConnection method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVpcPeeringConnectionRequest method. +// req, resp := client.DeleteVpcPeeringConnectionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVpcPeeringConnectionRequest(input *DeleteVpcPeeringConnectionInput) (req *request.Request, output *DeleteVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opDeleteVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpcPeeringConnectionInput{} + } + + req = c.newRequest(op, input, output) + output = &DeleteVpcPeeringConnectionOutput{} + req.Data = output + return +} + +// Deletes a VPC peering connection. Either the owner of the requester VPC or +// the owner of the peer VPC can delete the VPC peering connection if it's in +// the active state. The owner of the requester VPC can delete a VPC peering +// connection in the pending-acceptance state. +func (c *EC2) DeleteVpcPeeringConnection(input *DeleteVpcPeeringConnectionInput) (*DeleteVpcPeeringConnectionOutput, error) { + req, out := c.DeleteVpcPeeringConnectionRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVpnConnection = "DeleteVpnConnection" + +// DeleteVpnConnectionRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpnConnection operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVpnConnection method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVpnConnectionRequest method. +// req, resp := client.DeleteVpnConnectionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVpnConnectionRequest(input *DeleteVpnConnectionInput) (req *request.Request, output *DeleteVpnConnectionOutput) { + op := &request.Operation{ + Name: opDeleteVpnConnection, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpnConnectionInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteVpnConnectionOutput{} + req.Data = output + return +} + +// Deletes the specified VPN connection. +// +// If you're deleting the VPC and its associated components, we recommend that +// you detach the virtual private gateway from the VPC and delete the VPC before +// deleting the VPN connection. If you believe that the tunnel credentials for +// your VPN connection have been compromised, you can delete the VPN connection +// and create a new one that has new keys, without needing to delete the VPC +// or virtual private gateway. If you create a new VPN connection, you must +// reconfigure the customer gateway using the new configuration information +// returned with the new VPN connection ID. +func (c *EC2) DeleteVpnConnection(input *DeleteVpnConnectionInput) (*DeleteVpnConnectionOutput, error) { + req, out := c.DeleteVpnConnectionRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVpnConnectionRoute = "DeleteVpnConnectionRoute" + +// DeleteVpnConnectionRouteRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpnConnectionRoute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVpnConnectionRoute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVpnConnectionRouteRequest method. +// req, resp := client.DeleteVpnConnectionRouteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVpnConnectionRouteRequest(input *DeleteVpnConnectionRouteInput) (req *request.Request, output *DeleteVpnConnectionRouteOutput) { + op := &request.Operation{ + Name: opDeleteVpnConnectionRoute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpnConnectionRouteInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteVpnConnectionRouteOutput{} + req.Data = output + return +} + +// Deletes the specified static route associated with a VPN connection between +// an existing virtual private gateway and a VPN customer gateway. The static +// route allows traffic to be routed from the virtual private gateway to the +// VPN customer gateway. +func (c *EC2) DeleteVpnConnectionRoute(input *DeleteVpnConnectionRouteInput) (*DeleteVpnConnectionRouteOutput, error) { + req, out := c.DeleteVpnConnectionRouteRequest(input) + err := req.Send() + return out, err +} + +const opDeleteVpnGateway = "DeleteVpnGateway" + +// DeleteVpnGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpnGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteVpnGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteVpnGatewayRequest method. +// req, resp := client.DeleteVpnGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeleteVpnGatewayRequest(input *DeleteVpnGatewayInput) (req *request.Request, output *DeleteVpnGatewayOutput) { + op := &request.Operation{ + Name: opDeleteVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpnGatewayInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteVpnGatewayOutput{} + req.Data = output + return +} + +// Deletes the specified virtual private gateway. We recommend that before you +// delete a virtual private gateway, you detach it from the VPC and delete the +// VPN connection. Note that you don't need to delete the virtual private gateway +// if you plan to delete and recreate the VPN connection between your VPC and +// your network. +func (c *EC2) DeleteVpnGateway(input *DeleteVpnGatewayInput) (*DeleteVpnGatewayOutput, error) { + req, out := c.DeleteVpnGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDeregisterImage = "DeregisterImage" + +// DeregisterImageRequest generates a "aws/request.Request" representing the +// client's request for the DeregisterImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeregisterImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeregisterImageRequest method. +// req, resp := client.DeregisterImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DeregisterImageRequest(input *DeregisterImageInput) (req *request.Request, output *DeregisterImageOutput) { + op := &request.Operation{ + Name: opDeregisterImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeregisterImageInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeregisterImageOutput{} + req.Data = output + return +} + +// Deregisters the specified AMI. After you deregister an AMI, it can't be used +// to launch new instances. +// +// This command does not delete the AMI. +func (c *EC2) DeregisterImage(input *DeregisterImageInput) (*DeregisterImageOutput, error) { + req, out := c.DeregisterImageRequest(input) + err := req.Send() + return out, err +} + +const opDescribeAccountAttributes = "DescribeAccountAttributes" + +// DescribeAccountAttributesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeAccountAttributes operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeAccountAttributes method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeAccountAttributesRequest method. +// req, resp := client.DescribeAccountAttributesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeAccountAttributesRequest(input *DescribeAccountAttributesInput) (req *request.Request, output *DescribeAccountAttributesOutput) { + op := &request.Operation{ + Name: opDescribeAccountAttributes, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeAccountAttributesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeAccountAttributesOutput{} + req.Data = output + return +} + +// Describes attributes of your AWS account. The following are the supported +// account attributes: +// +// supported-platforms: Indicates whether your account can launch instances +// into EC2-Classic and EC2-VPC, or only into EC2-VPC. +// +// default-vpc: The ID of the default VPC for your account, or none. +// +// max-instances: The maximum number of On-Demand instances that you can +// run. +// +// vpc-max-security-groups-per-interface: The maximum number of security +// groups that you can assign to a network interface. +// +// max-elastic-ips: The maximum number of Elastic IP addresses that you +// can allocate for use with EC2-Classic. +// +// vpc-max-elastic-ips: The maximum number of Elastic IP addresses that +// you can allocate for use with EC2-VPC. +func (c *EC2) DescribeAccountAttributes(input *DescribeAccountAttributesInput) (*DescribeAccountAttributesOutput, error) { + req, out := c.DescribeAccountAttributesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeAddresses = "DescribeAddresses" + +// DescribeAddressesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeAddresses operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeAddresses method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeAddressesRequest method. +// req, resp := client.DescribeAddressesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeAddressesRequest(input *DescribeAddressesInput) (req *request.Request, output *DescribeAddressesOutput) { + op := &request.Operation{ + Name: opDescribeAddresses, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeAddressesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeAddressesOutput{} + req.Data = output + return +} + +// Describes one or more of your Elastic IP addresses. +// +// An Elastic IP address is for use in either the EC2-Classic platform or in +// a VPC. For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeAddresses(input *DescribeAddressesInput) (*DescribeAddressesOutput, error) { + req, out := c.DescribeAddressesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeAvailabilityZones = "DescribeAvailabilityZones" + +// DescribeAvailabilityZonesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeAvailabilityZones operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeAvailabilityZones method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeAvailabilityZonesRequest method. +// req, resp := client.DescribeAvailabilityZonesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeAvailabilityZonesRequest(input *DescribeAvailabilityZonesInput) (req *request.Request, output *DescribeAvailabilityZonesOutput) { + op := &request.Operation{ + Name: opDescribeAvailabilityZones, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeAvailabilityZonesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeAvailabilityZonesOutput{} + req.Data = output + return +} + +// Describes one or more of the Availability Zones that are available to you. +// The results include zones only for the region you're currently using. If +// there is an event impacting an Availability Zone, you can use this request +// to view the state and any provided message for that Availability Zone. +// +// For more information, see Regions and Availability Zones (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeAvailabilityZones(input *DescribeAvailabilityZonesInput) (*DescribeAvailabilityZonesOutput, error) { + req, out := c.DescribeAvailabilityZonesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeBundleTasks = "DescribeBundleTasks" + +// DescribeBundleTasksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeBundleTasks operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeBundleTasks method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeBundleTasksRequest method. +// req, resp := client.DescribeBundleTasksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeBundleTasksRequest(input *DescribeBundleTasksInput) (req *request.Request, output *DescribeBundleTasksOutput) { + op := &request.Operation{ + Name: opDescribeBundleTasks, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeBundleTasksInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeBundleTasksOutput{} + req.Data = output + return +} + +// Describes one or more of your bundling tasks. +// +// Completed bundle tasks are listed for only a limited time. If your bundle +// task is no longer in the list, you can still register an AMI from it. Just +// use RegisterImage with the Amazon S3 bucket name and image manifest name +// you provided to the bundle task. +func (c *EC2) DescribeBundleTasks(input *DescribeBundleTasksInput) (*DescribeBundleTasksOutput, error) { + req, out := c.DescribeBundleTasksRequest(input) + err := req.Send() + return out, err +} + +const opDescribeClassicLinkInstances = "DescribeClassicLinkInstances" + +// DescribeClassicLinkInstancesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeClassicLinkInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeClassicLinkInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeClassicLinkInstancesRequest method. +// req, resp := client.DescribeClassicLinkInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeClassicLinkInstancesRequest(input *DescribeClassicLinkInstancesInput) (req *request.Request, output *DescribeClassicLinkInstancesOutput) { + op := &request.Operation{ + Name: opDescribeClassicLinkInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeClassicLinkInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeClassicLinkInstancesOutput{} + req.Data = output + return +} + +// Describes one or more of your linked EC2-Classic instances. This request +// only returns information about EC2-Classic instances linked to a VPC through +// ClassicLink; you cannot use this request to return information about other +// instances. +func (c *EC2) DescribeClassicLinkInstances(input *DescribeClassicLinkInstancesInput) (*DescribeClassicLinkInstancesOutput, error) { + req, out := c.DescribeClassicLinkInstancesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeConversionTasks = "DescribeConversionTasks" + +// DescribeConversionTasksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeConversionTasks operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeConversionTasks method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeConversionTasksRequest method. +// req, resp := client.DescribeConversionTasksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeConversionTasksRequest(input *DescribeConversionTasksInput) (req *request.Request, output *DescribeConversionTasksOutput) { + op := &request.Operation{ + Name: opDescribeConversionTasks, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeConversionTasksInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeConversionTasksOutput{} + req.Data = output + return +} + +// Describes one or more of your conversion tasks. For more information, see +// the VM Import/Export User Guide (http://docs.aws.amazon.com/vm-import/latest/userguide/). +// +// For information about the import manifest referenced by this API action, +// see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). +func (c *EC2) DescribeConversionTasks(input *DescribeConversionTasksInput) (*DescribeConversionTasksOutput, error) { + req, out := c.DescribeConversionTasksRequest(input) + err := req.Send() + return out, err +} + +const opDescribeCustomerGateways = "DescribeCustomerGateways" + +// DescribeCustomerGatewaysRequest generates a "aws/request.Request" representing the +// client's request for the DescribeCustomerGateways operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeCustomerGateways method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeCustomerGatewaysRequest method. +// req, resp := client.DescribeCustomerGatewaysRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeCustomerGatewaysRequest(input *DescribeCustomerGatewaysInput) (req *request.Request, output *DescribeCustomerGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeCustomerGateways, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeCustomerGatewaysInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeCustomerGatewaysOutput{} + req.Data = output + return +} + +// Describes one or more of your VPN customer gateways. +// +// For more information about VPN customer gateways, see Adding a Hardware +// Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeCustomerGateways(input *DescribeCustomerGatewaysInput) (*DescribeCustomerGatewaysOutput, error) { + req, out := c.DescribeCustomerGatewaysRequest(input) + err := req.Send() + return out, err +} + +const opDescribeDhcpOptions = "DescribeDhcpOptions" + +// DescribeDhcpOptionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeDhcpOptions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeDhcpOptions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeDhcpOptionsRequest method. +// req, resp := client.DescribeDhcpOptionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeDhcpOptionsRequest(input *DescribeDhcpOptionsInput) (req *request.Request, output *DescribeDhcpOptionsOutput) { + op := &request.Operation{ + Name: opDescribeDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeDhcpOptionsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeDhcpOptionsOutput{} + req.Data = output + return +} + +// Describes one or more of your DHCP options sets. +// +// For more information about DHCP options sets, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeDhcpOptions(input *DescribeDhcpOptionsInput) (*DescribeDhcpOptionsOutput, error) { + req, out := c.DescribeDhcpOptionsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeExportTasks = "DescribeExportTasks" + +// DescribeExportTasksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeExportTasks operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeExportTasks method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeExportTasksRequest method. +// req, resp := client.DescribeExportTasksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *request.Request, output *DescribeExportTasksOutput) { + op := &request.Operation{ + Name: opDescribeExportTasks, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeExportTasksInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeExportTasksOutput{} + req.Data = output + return +} + +// Describes one or more of your export tasks. +func (c *EC2) DescribeExportTasks(input *DescribeExportTasksInput) (*DescribeExportTasksOutput, error) { + req, out := c.DescribeExportTasksRequest(input) + err := req.Send() + return out, err +} + +const opDescribeFlowLogs = "DescribeFlowLogs" + +// DescribeFlowLogsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeFlowLogs operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeFlowLogs method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeFlowLogsRequest method. +// req, resp := client.DescribeFlowLogsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeFlowLogsRequest(input *DescribeFlowLogsInput) (req *request.Request, output *DescribeFlowLogsOutput) { + op := &request.Operation{ + Name: opDescribeFlowLogs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeFlowLogsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeFlowLogsOutput{} + req.Data = output + return +} + +// Describes one or more flow logs. To view the information in your flow logs +// (the log streams for the network interfaces), you must use the CloudWatch +// Logs console or the CloudWatch Logs API. +func (c *EC2) DescribeFlowLogs(input *DescribeFlowLogsInput) (*DescribeFlowLogsOutput, error) { + req, out := c.DescribeFlowLogsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeHostReservationOfferings = "DescribeHostReservationOfferings" + +// DescribeHostReservationOfferingsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeHostReservationOfferings operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeHostReservationOfferings method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeHostReservationOfferingsRequest method. +// req, resp := client.DescribeHostReservationOfferingsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeHostReservationOfferingsRequest(input *DescribeHostReservationOfferingsInput) (req *request.Request, output *DescribeHostReservationOfferingsOutput) { + op := &request.Operation{ + Name: opDescribeHostReservationOfferings, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeHostReservationOfferingsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeHostReservationOfferingsOutput{} + req.Data = output + return +} + +// Describes the Dedicated Host Reservations that are available to purchase. +// +// The results describe all the Dedicated Host Reservation offerings, including +// offerings that may not match the instance family and region of your Dedicated +// Hosts. When purchasing an offering, ensure that the the instance family and +// region of the offering matches that of the Dedicated Host/s it will be associated +// with. For an overview of supported instance types, see Dedicated Hosts Overview +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-hosts-overview.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeHostReservationOfferings(input *DescribeHostReservationOfferingsInput) (*DescribeHostReservationOfferingsOutput, error) { + req, out := c.DescribeHostReservationOfferingsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeHostReservations = "DescribeHostReservations" + +// DescribeHostReservationsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeHostReservations operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeHostReservations method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeHostReservationsRequest method. +// req, resp := client.DescribeHostReservationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeHostReservationsRequest(input *DescribeHostReservationsInput) (req *request.Request, output *DescribeHostReservationsOutput) { + op := &request.Operation{ + Name: opDescribeHostReservations, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeHostReservationsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeHostReservationsOutput{} + req.Data = output + return +} + +// Describes Dedicated Host Reservations which are associated with Dedicated +// Hosts in your account. +func (c *EC2) DescribeHostReservations(input *DescribeHostReservationsInput) (*DescribeHostReservationsOutput, error) { + req, out := c.DescribeHostReservationsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeHosts = "DescribeHosts" + +// DescribeHostsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeHosts operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeHosts method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeHostsRequest method. +// req, resp := client.DescribeHostsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeHostsRequest(input *DescribeHostsInput) (req *request.Request, output *DescribeHostsOutput) { + op := &request.Operation{ + Name: opDescribeHosts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeHostsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeHostsOutput{} + req.Data = output + return +} + +// Describes one or more of your Dedicated Hosts. +// +// The results describe only the Dedicated Hosts in the region you're currently +// using. All listed instances consume capacity on your Dedicated Host. Dedicated +// Hosts that have recently been released will be listed with the state released. +func (c *EC2) DescribeHosts(input *DescribeHostsInput) (*DescribeHostsOutput, error) { + req, out := c.DescribeHostsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeIdFormat = "DescribeIdFormat" + +// DescribeIdFormatRequest generates a "aws/request.Request" representing the +// client's request for the DescribeIdFormat operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeIdFormat method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeIdFormatRequest method. +// req, resp := client.DescribeIdFormatRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeIdFormatRequest(input *DescribeIdFormatInput) (req *request.Request, output *DescribeIdFormatOutput) { + op := &request.Operation{ + Name: opDescribeIdFormat, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeIdFormatInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeIdFormatOutput{} + req.Data = output + return +} + +// Describes the ID format settings for your resources on a per-region basis, +// for example, to view which resource types are enabled for longer IDs. This +// request only returns information about resource types whose ID formats can +// be modified; it does not return information about other resource types. +// +// The following resource types support longer IDs: instance | reservation +// | snapshot | volume. +// +// These settings apply to the IAM user who makes the request; they do not +// apply to the entire AWS account. By default, an IAM user defaults to the +// same settings as the root user, unless they explicitly override the settings +// by running the ModifyIdFormat command. Resources created with longer IDs +// are visible to all IAM users, regardless of these settings and provided that +// they have permission to use the relevant Describe command for the resource +// type. +func (c *EC2) DescribeIdFormat(input *DescribeIdFormatInput) (*DescribeIdFormatOutput, error) { + req, out := c.DescribeIdFormatRequest(input) + err := req.Send() + return out, err +} + +const opDescribeIdentityIdFormat = "DescribeIdentityIdFormat" + +// DescribeIdentityIdFormatRequest generates a "aws/request.Request" representing the +// client's request for the DescribeIdentityIdFormat operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeIdentityIdFormat method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeIdentityIdFormatRequest method. +// req, resp := client.DescribeIdentityIdFormatRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeIdentityIdFormatRequest(input *DescribeIdentityIdFormatInput) (req *request.Request, output *DescribeIdentityIdFormatOutput) { + op := &request.Operation{ + Name: opDescribeIdentityIdFormat, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeIdentityIdFormatInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeIdentityIdFormatOutput{} + req.Data = output + return +} + +// Describes the ID format settings for resources for the specified IAM user, +// IAM role, or root user. For example, you can view the resource types that +// are enabled for longer IDs. This request only returns information about resource +// types whose ID formats can be modified; it does not return information about +// other resource types. For more information, see Resource IDs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/resource-ids.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// The following resource types support longer IDs: instance | reservation +// | snapshot | volume. +// +// These settings apply to the principal specified in the request. They do +// not apply to the principal that makes the request. +func (c *EC2) DescribeIdentityIdFormat(input *DescribeIdentityIdFormatInput) (*DescribeIdentityIdFormatOutput, error) { + req, out := c.DescribeIdentityIdFormatRequest(input) + err := req.Send() + return out, err +} + +const opDescribeImageAttribute = "DescribeImageAttribute" + +// DescribeImageAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeImageAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeImageAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeImageAttributeRequest method. +// req, resp := client.DescribeImageAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeImageAttributeRequest(input *DescribeImageAttributeInput) (req *request.Request, output *DescribeImageAttributeOutput) { + op := &request.Operation{ + Name: opDescribeImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeImageAttributeInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeImageAttributeOutput{} + req.Data = output + return +} + +// Describes the specified attribute of the specified AMI. You can specify only +// one attribute at a time. +func (c *EC2) DescribeImageAttribute(input *DescribeImageAttributeInput) (*DescribeImageAttributeOutput, error) { + req, out := c.DescribeImageAttributeRequest(input) + err := req.Send() + return out, err +} + +const opDescribeImages = "DescribeImages" + +// DescribeImagesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeImages operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeImages method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeImagesRequest method. +// req, resp := client.DescribeImagesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Request, output *DescribeImagesOutput) { + op := &request.Operation{ + Name: opDescribeImages, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeImagesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeImagesOutput{} + req.Data = output + return +} + +// Describes one or more of the images (AMIs, AKIs, and ARIs) available to you. +// Images available to you include public images, private images that you own, +// and private images owned by other AWS accounts but for which you have explicit +// launch permissions. +// +// Deregistered images are included in the returned results for an unspecified +// interval after deregistration. +func (c *EC2) DescribeImages(input *DescribeImagesInput) (*DescribeImagesOutput, error) { + req, out := c.DescribeImagesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeImportImageTasks = "DescribeImportImageTasks" + +// DescribeImportImageTasksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeImportImageTasks operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeImportImageTasks method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeImportImageTasksRequest method. +// req, resp := client.DescribeImportImageTasksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeImportImageTasksRequest(input *DescribeImportImageTasksInput) (req *request.Request, output *DescribeImportImageTasksOutput) { + op := &request.Operation{ + Name: opDescribeImportImageTasks, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeImportImageTasksInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeImportImageTasksOutput{} + req.Data = output + return +} + +// Displays details about an import virtual machine or import snapshot tasks +// that are already created. +func (c *EC2) DescribeImportImageTasks(input *DescribeImportImageTasksInput) (*DescribeImportImageTasksOutput, error) { + req, out := c.DescribeImportImageTasksRequest(input) + err := req.Send() + return out, err +} + +const opDescribeImportSnapshotTasks = "DescribeImportSnapshotTasks" + +// DescribeImportSnapshotTasksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeImportSnapshotTasks operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeImportSnapshotTasks method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeImportSnapshotTasksRequest method. +// req, resp := client.DescribeImportSnapshotTasksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeImportSnapshotTasksRequest(input *DescribeImportSnapshotTasksInput) (req *request.Request, output *DescribeImportSnapshotTasksOutput) { + op := &request.Operation{ + Name: opDescribeImportSnapshotTasks, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeImportSnapshotTasksInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeImportSnapshotTasksOutput{} + req.Data = output + return +} + +// Describes your import snapshot tasks. +func (c *EC2) DescribeImportSnapshotTasks(input *DescribeImportSnapshotTasksInput) (*DescribeImportSnapshotTasksOutput, error) { + req, out := c.DescribeImportSnapshotTasksRequest(input) + err := req.Send() + return out, err +} + +const opDescribeInstanceAttribute = "DescribeInstanceAttribute" + +// DescribeInstanceAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeInstanceAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeInstanceAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeInstanceAttributeRequest method. +// req, resp := client.DescribeInstanceAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeInstanceAttributeRequest(input *DescribeInstanceAttributeInput) (req *request.Request, output *DescribeInstanceAttributeOutput) { + op := &request.Operation{ + Name: opDescribeInstanceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeInstanceAttributeInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeInstanceAttributeOutput{} + req.Data = output + return +} + +// Describes the specified attribute of the specified instance. You can specify +// only one attribute at a time. Valid attribute values are: instanceType | +// kernel | ramdisk | userData | disableApiTermination | instanceInitiatedShutdownBehavior +// | rootDeviceName | blockDeviceMapping | productCodes | sourceDestCheck | +// groupSet | ebsOptimized | sriovNetSupport +func (c *EC2) DescribeInstanceAttribute(input *DescribeInstanceAttributeInput) (*DescribeInstanceAttributeOutput, error) { + req, out := c.DescribeInstanceAttributeRequest(input) + err := req.Send() + return out, err +} + +const opDescribeInstanceStatus = "DescribeInstanceStatus" + +// DescribeInstanceStatusRequest generates a "aws/request.Request" representing the +// client's request for the DescribeInstanceStatus operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeInstanceStatus method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeInstanceStatusRequest method. +// req, resp := client.DescribeInstanceStatusRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeInstanceStatusRequest(input *DescribeInstanceStatusInput) (req *request.Request, output *DescribeInstanceStatusOutput) { + op := &request.Operation{ + Name: opDescribeInstanceStatus, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeInstanceStatusInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeInstanceStatusOutput{} + req.Data = output + return +} + +// Describes the status of one or more instances. By default, only running instances +// are described, unless specified otherwise. +// +// Instance status includes the following components: +// +// Status checks - Amazon EC2 performs status checks on running EC2 instances +// to identify hardware and software issues. For more information, see Status +// Checks for Your Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-system-instance-status-check.html) +// and Troubleshooting Instances with Failed Status Checks (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstances.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Scheduled events - Amazon EC2 can schedule events (such as reboot, stop, +// or terminate) for your instances related to hardware issues, software updates, +// or system maintenance. For more information, see Scheduled Events for Your +// Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Instance state - You can manage your instances from the moment you launch +// them through their termination. For more information, see Instance Lifecycle +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeInstanceStatus(input *DescribeInstanceStatusInput) (*DescribeInstanceStatusOutput, error) { + req, out := c.DescribeInstanceStatusRequest(input) + err := req.Send() + return out, err +} + +// DescribeInstanceStatusPages iterates over the pages of a DescribeInstanceStatus operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeInstanceStatus method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeInstanceStatus operation. +// pageNum := 0 +// err := client.DescribeInstanceStatusPages(params, +// func(page *DescribeInstanceStatusOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeInstanceStatusPages(input *DescribeInstanceStatusInput, fn func(p *DescribeInstanceStatusOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeInstanceStatusRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeInstanceStatusOutput), lastPage) + }) +} + +const opDescribeInstances = "DescribeInstances" + +// DescribeInstancesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeInstancesRequest method. +// req, resp := client.DescribeInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeInstancesRequest(input *DescribeInstancesInput) (req *request.Request, output *DescribeInstancesOutput) { + op := &request.Operation{ + Name: opDescribeInstances, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeInstancesOutput{} + req.Data = output + return +} + +// Describes one or more of your instances. +// +// If you specify one or more instance IDs, Amazon EC2 returns information +// for those instances. If you do not specify instance IDs, Amazon EC2 returns +// information for all relevant instances. If you specify an instance ID that +// is not valid, an error is returned. If you specify an instance that you do +// not own, it is not included in the returned results. +// +// Recently terminated instances might appear in the returned results. This +// interval is usually less than one hour. +// +// If you describe instances in the rare case where an Availability Zone is +// experiencing a service disruption and you specify instance IDs that are in +// the affected zone, or do not specify any instance IDs at all, the call fails. +// If you describe instances and specify only instance IDs that are in an unaffected +// zone, the call works normally. +func (c *EC2) DescribeInstances(input *DescribeInstancesInput) (*DescribeInstancesOutput, error) { + req, out := c.DescribeInstancesRequest(input) + err := req.Send() + return out, err +} + +// DescribeInstancesPages iterates over the pages of a DescribeInstances operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeInstances method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeInstances operation. +// pageNum := 0 +// err := client.DescribeInstancesPages(params, +// func(page *DescribeInstancesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeInstancesPages(input *DescribeInstancesInput, fn func(p *DescribeInstancesOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeInstancesRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeInstancesOutput), lastPage) + }) +} + +const opDescribeInternetGateways = "DescribeInternetGateways" + +// DescribeInternetGatewaysRequest generates a "aws/request.Request" representing the +// client's request for the DescribeInternetGateways operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeInternetGateways method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeInternetGatewaysRequest method. +// req, resp := client.DescribeInternetGatewaysRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeInternetGatewaysRequest(input *DescribeInternetGatewaysInput) (req *request.Request, output *DescribeInternetGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeInternetGateways, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeInternetGatewaysInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeInternetGatewaysOutput{} + req.Data = output + return +} + +// Describes one or more of your Internet gateways. +func (c *EC2) DescribeInternetGateways(input *DescribeInternetGatewaysInput) (*DescribeInternetGatewaysOutput, error) { + req, out := c.DescribeInternetGatewaysRequest(input) + err := req.Send() + return out, err +} + +const opDescribeKeyPairs = "DescribeKeyPairs" + +// DescribeKeyPairsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeKeyPairs operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeKeyPairs method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeKeyPairsRequest method. +// req, resp := client.DescribeKeyPairsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeKeyPairsRequest(input *DescribeKeyPairsInput) (req *request.Request, output *DescribeKeyPairsOutput) { + op := &request.Operation{ + Name: opDescribeKeyPairs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeKeyPairsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeKeyPairsOutput{} + req.Data = output + return +} + +// Describes one or more of your key pairs. +// +// For more information about key pairs, see Key Pairs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeKeyPairs(input *DescribeKeyPairsInput) (*DescribeKeyPairsOutput, error) { + req, out := c.DescribeKeyPairsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeMovingAddresses = "DescribeMovingAddresses" + +// DescribeMovingAddressesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeMovingAddresses operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeMovingAddresses method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeMovingAddressesRequest method. +// req, resp := client.DescribeMovingAddressesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeMovingAddressesRequest(input *DescribeMovingAddressesInput) (req *request.Request, output *DescribeMovingAddressesOutput) { + op := &request.Operation{ + Name: opDescribeMovingAddresses, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeMovingAddressesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeMovingAddressesOutput{} + req.Data = output + return +} + +// Describes your Elastic IP addresses that are being moved to the EC2-VPC platform, +// or that are being restored to the EC2-Classic platform. This request does +// not return information about any other Elastic IP addresses in your account. +func (c *EC2) DescribeMovingAddresses(input *DescribeMovingAddressesInput) (*DescribeMovingAddressesOutput, error) { + req, out := c.DescribeMovingAddressesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeNatGateways = "DescribeNatGateways" + +// DescribeNatGatewaysRequest generates a "aws/request.Request" representing the +// client's request for the DescribeNatGateways operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeNatGateways method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeNatGatewaysRequest method. +// req, resp := client.DescribeNatGatewaysRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeNatGatewaysRequest(input *DescribeNatGatewaysInput) (req *request.Request, output *DescribeNatGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeNatGateways, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeNatGatewaysInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeNatGatewaysOutput{} + req.Data = output + return +} + +// Describes one or more of the your NAT gateways. +func (c *EC2) DescribeNatGateways(input *DescribeNatGatewaysInput) (*DescribeNatGatewaysOutput, error) { + req, out := c.DescribeNatGatewaysRequest(input) + err := req.Send() + return out, err +} + +const opDescribeNetworkAcls = "DescribeNetworkAcls" + +// DescribeNetworkAclsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeNetworkAcls operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeNetworkAcls method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeNetworkAclsRequest method. +// req, resp := client.DescribeNetworkAclsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeNetworkAclsRequest(input *DescribeNetworkAclsInput) (req *request.Request, output *DescribeNetworkAclsOutput) { + op := &request.Operation{ + Name: opDescribeNetworkAcls, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeNetworkAclsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeNetworkAclsOutput{} + req.Data = output + return +} + +// Describes one or more of your network ACLs. +// +// For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeNetworkAcls(input *DescribeNetworkAclsInput) (*DescribeNetworkAclsOutput, error) { + req, out := c.DescribeNetworkAclsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeNetworkInterfaceAttribute = "DescribeNetworkInterfaceAttribute" + +// DescribeNetworkInterfaceAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeNetworkInterfaceAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeNetworkInterfaceAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeNetworkInterfaceAttributeRequest method. +// req, resp := client.DescribeNetworkInterfaceAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeNetworkInterfaceAttributeRequest(input *DescribeNetworkInterfaceAttributeInput) (req *request.Request, output *DescribeNetworkInterfaceAttributeOutput) { + op := &request.Operation{ + Name: opDescribeNetworkInterfaceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeNetworkInterfaceAttributeInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeNetworkInterfaceAttributeOutput{} + req.Data = output + return +} + +// Describes a network interface attribute. You can specify only one attribute +// at a time. +func (c *EC2) DescribeNetworkInterfaceAttribute(input *DescribeNetworkInterfaceAttributeInput) (*DescribeNetworkInterfaceAttributeOutput, error) { + req, out := c.DescribeNetworkInterfaceAttributeRequest(input) + err := req.Send() + return out, err +} + +const opDescribeNetworkInterfaces = "DescribeNetworkInterfaces" + +// DescribeNetworkInterfacesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeNetworkInterfaces operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeNetworkInterfaces method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeNetworkInterfacesRequest method. +// req, resp := client.DescribeNetworkInterfacesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeNetworkInterfacesRequest(input *DescribeNetworkInterfacesInput) (req *request.Request, output *DescribeNetworkInterfacesOutput) { + op := &request.Operation{ + Name: opDescribeNetworkInterfaces, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeNetworkInterfacesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeNetworkInterfacesOutput{} + req.Data = output + return +} + +// Describes one or more of your network interfaces. +func (c *EC2) DescribeNetworkInterfaces(input *DescribeNetworkInterfacesInput) (*DescribeNetworkInterfacesOutput, error) { + req, out := c.DescribeNetworkInterfacesRequest(input) + err := req.Send() + return out, err +} + +const opDescribePlacementGroups = "DescribePlacementGroups" + +// DescribePlacementGroupsRequest generates a "aws/request.Request" representing the +// client's request for the DescribePlacementGroups operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribePlacementGroups method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribePlacementGroupsRequest method. +// req, resp := client.DescribePlacementGroupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribePlacementGroupsRequest(input *DescribePlacementGroupsInput) (req *request.Request, output *DescribePlacementGroupsOutput) { + op := &request.Operation{ + Name: opDescribePlacementGroups, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribePlacementGroupsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribePlacementGroupsOutput{} + req.Data = output + return +} + +// Describes one or more of your placement groups. For more information about +// placement groups and cluster instances, see Cluster Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cluster_computing.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribePlacementGroups(input *DescribePlacementGroupsInput) (*DescribePlacementGroupsOutput, error) { + req, out := c.DescribePlacementGroupsRequest(input) + err := req.Send() + return out, err +} + +const opDescribePrefixLists = "DescribePrefixLists" + +// DescribePrefixListsRequest generates a "aws/request.Request" representing the +// client's request for the DescribePrefixLists operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribePrefixLists method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribePrefixListsRequest method. +// req, resp := client.DescribePrefixListsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribePrefixListsRequest(input *DescribePrefixListsInput) (req *request.Request, output *DescribePrefixListsOutput) { + op := &request.Operation{ + Name: opDescribePrefixLists, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribePrefixListsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribePrefixListsOutput{} + req.Data = output + return +} + +// Describes available AWS services in a prefix list format, which includes +// the prefix list name and prefix list ID of the service and the IP address +// range for the service. A prefix list ID is required for creating an outbound +// security group rule that allows traffic from a VPC to access an AWS service +// through a VPC endpoint. +func (c *EC2) DescribePrefixLists(input *DescribePrefixListsInput) (*DescribePrefixListsOutput, error) { + req, out := c.DescribePrefixListsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeRegions = "DescribeRegions" + +// DescribeRegionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeRegions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeRegions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeRegionsRequest method. +// req, resp := client.DescribeRegionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeRegionsRequest(input *DescribeRegionsInput) (req *request.Request, output *DescribeRegionsOutput) { + op := &request.Operation{ + Name: opDescribeRegions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeRegionsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeRegionsOutput{} + req.Data = output + return +} + +// Describes one or more regions that are currently available to you. +// +// For a list of the regions supported by Amazon EC2, see Regions and Endpoints +// (http://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region). +func (c *EC2) DescribeRegions(input *DescribeRegionsInput) (*DescribeRegionsOutput, error) { + req, out := c.DescribeRegionsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeReservedInstances = "DescribeReservedInstances" + +// DescribeReservedInstancesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeReservedInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeReservedInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeReservedInstancesRequest method. +// req, resp := client.DescribeReservedInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeReservedInstancesRequest(input *DescribeReservedInstancesInput) (req *request.Request, output *DescribeReservedInstancesOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeReservedInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeReservedInstancesOutput{} + req.Data = output + return +} + +// Describes one or more of the Reserved Instances that you purchased. +// +// For more information about Reserved Instances, see Reserved Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts-on-demand-reserved-instances.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeReservedInstances(input *DescribeReservedInstancesInput) (*DescribeReservedInstancesOutput, error) { + req, out := c.DescribeReservedInstancesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeReservedInstancesListings = "DescribeReservedInstancesListings" + +// DescribeReservedInstancesListingsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeReservedInstancesListings operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeReservedInstancesListings method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeReservedInstancesListingsRequest method. +// req, resp := client.DescribeReservedInstancesListingsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeReservedInstancesListingsRequest(input *DescribeReservedInstancesListingsInput) (req *request.Request, output *DescribeReservedInstancesListingsOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstancesListings, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeReservedInstancesListingsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeReservedInstancesListingsOutput{} + req.Data = output + return +} + +// Describes your account's Reserved Instance listings in the Reserved Instance +// Marketplace. +// +// The Reserved Instance Marketplace matches sellers who want to resell Reserved +// Instance capacity that they no longer need with buyers who want to purchase +// additional capacity. Reserved Instances bought and sold through the Reserved +// Instance Marketplace work like any other Reserved Instances. +// +// As a seller, you choose to list some or all of your Reserved Instances, +// and you specify the upfront price to receive for them. Your Reserved Instances +// are then listed in the Reserved Instance Marketplace and are available for +// purchase. +// +// As a buyer, you specify the configuration of the Reserved Instance to purchase, +// and the Marketplace matches what you're searching for with what's available. +// The Marketplace first sells the lowest priced Reserved Instances to you, +// and continues to sell available Reserved Instance listings to you until your +// demand is met. You are charged based on the total price of all of the listings +// that you purchase. +// +// For more information, see Reserved Instance Marketplace (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeReservedInstancesListings(input *DescribeReservedInstancesListingsInput) (*DescribeReservedInstancesListingsOutput, error) { + req, out := c.DescribeReservedInstancesListingsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeReservedInstancesModifications = "DescribeReservedInstancesModifications" + +// DescribeReservedInstancesModificationsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeReservedInstancesModifications operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeReservedInstancesModifications method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeReservedInstancesModificationsRequest method. +// req, resp := client.DescribeReservedInstancesModificationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeReservedInstancesModificationsRequest(input *DescribeReservedInstancesModificationsInput) (req *request.Request, output *DescribeReservedInstancesModificationsOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstancesModifications, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeReservedInstancesModificationsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeReservedInstancesModificationsOutput{} + req.Data = output + return +} + +// Describes the modifications made to your Reserved Instances. If no parameter +// is specified, information about all your Reserved Instances modification +// requests is returned. If a modification ID is specified, only information +// about the specific modification is returned. +// +// For more information, see Modifying Reserved Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-modifying.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeReservedInstancesModifications(input *DescribeReservedInstancesModificationsInput) (*DescribeReservedInstancesModificationsOutput, error) { + req, out := c.DescribeReservedInstancesModificationsRequest(input) + err := req.Send() + return out, err +} + +// DescribeReservedInstancesModificationsPages iterates over the pages of a DescribeReservedInstancesModifications operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeReservedInstancesModifications method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeReservedInstancesModifications operation. +// pageNum := 0 +// err := client.DescribeReservedInstancesModificationsPages(params, +// func(page *DescribeReservedInstancesModificationsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeReservedInstancesModificationsPages(input *DescribeReservedInstancesModificationsInput, fn func(p *DescribeReservedInstancesModificationsOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeReservedInstancesModificationsRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeReservedInstancesModificationsOutput), lastPage) + }) +} + +const opDescribeReservedInstancesOfferings = "DescribeReservedInstancesOfferings" + +// DescribeReservedInstancesOfferingsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeReservedInstancesOfferings operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeReservedInstancesOfferings method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeReservedInstancesOfferingsRequest method. +// req, resp := client.DescribeReservedInstancesOfferingsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeReservedInstancesOfferingsRequest(input *DescribeReservedInstancesOfferingsInput) (req *request.Request, output *DescribeReservedInstancesOfferingsOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstancesOfferings, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeReservedInstancesOfferingsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeReservedInstancesOfferingsOutput{} + req.Data = output + return +} + +// Describes Reserved Instance offerings that are available for purchase. With +// Reserved Instances, you purchase the right to launch instances for a period +// of time. During that time period, you do not receive insufficient capacity +// errors, and you pay a lower usage rate than the rate charged for On-Demand +// instances for the actual time used. +// +// If you have listed your own Reserved Instances for sale in the Reserved +// Instance Marketplace, they will be excluded from these results. This is to +// ensure that you do not purchase your own Reserved Instances. +// +// For more information, see Reserved Instance Marketplace (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeReservedInstancesOfferings(input *DescribeReservedInstancesOfferingsInput) (*DescribeReservedInstancesOfferingsOutput, error) { + req, out := c.DescribeReservedInstancesOfferingsRequest(input) + err := req.Send() + return out, err +} + +// DescribeReservedInstancesOfferingsPages iterates over the pages of a DescribeReservedInstancesOfferings operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeReservedInstancesOfferings method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeReservedInstancesOfferings operation. +// pageNum := 0 +// err := client.DescribeReservedInstancesOfferingsPages(params, +// func(page *DescribeReservedInstancesOfferingsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeReservedInstancesOfferingsPages(input *DescribeReservedInstancesOfferingsInput, fn func(p *DescribeReservedInstancesOfferingsOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeReservedInstancesOfferingsRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeReservedInstancesOfferingsOutput), lastPage) + }) +} + +const opDescribeRouteTables = "DescribeRouteTables" + +// DescribeRouteTablesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeRouteTables operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeRouteTables method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeRouteTablesRequest method. +// req, resp := client.DescribeRouteTablesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeRouteTablesRequest(input *DescribeRouteTablesInput) (req *request.Request, output *DescribeRouteTablesOutput) { + op := &request.Operation{ + Name: opDescribeRouteTables, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeRouteTablesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeRouteTablesOutput{} + req.Data = output + return +} + +// Describes one or more of your route tables. +// +// Each subnet in your VPC must be associated with a route table. If a subnet +// is not explicitly associated with any route table, it is implicitly associated +// with the main route table. This command does not return the subnet ID for +// implicit associations. +// +// For more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeRouteTables(input *DescribeRouteTablesInput) (*DescribeRouteTablesOutput, error) { + req, out := c.DescribeRouteTablesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeScheduledInstanceAvailability = "DescribeScheduledInstanceAvailability" + +// DescribeScheduledInstanceAvailabilityRequest generates a "aws/request.Request" representing the +// client's request for the DescribeScheduledInstanceAvailability operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeScheduledInstanceAvailability method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeScheduledInstanceAvailabilityRequest method. +// req, resp := client.DescribeScheduledInstanceAvailabilityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeScheduledInstanceAvailabilityRequest(input *DescribeScheduledInstanceAvailabilityInput) (req *request.Request, output *DescribeScheduledInstanceAvailabilityOutput) { + op := &request.Operation{ + Name: opDescribeScheduledInstanceAvailability, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeScheduledInstanceAvailabilityInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeScheduledInstanceAvailabilityOutput{} + req.Data = output + return +} + +// Finds available schedules that meet the specified criteria. +// +// You can search for an available schedule no more than 3 months in advance. +// You must meet the minimum required duration of 1,200 hours per year. For +// example, the minimum daily schedule is 4 hours, the minimum weekly schedule +// is 24 hours, and the minimum monthly schedule is 100 hours. +// +// After you find a schedule that meets your needs, call PurchaseScheduledInstances +// to purchase Scheduled Instances with that schedule. +func (c *EC2) DescribeScheduledInstanceAvailability(input *DescribeScheduledInstanceAvailabilityInput) (*DescribeScheduledInstanceAvailabilityOutput, error) { + req, out := c.DescribeScheduledInstanceAvailabilityRequest(input) + err := req.Send() + return out, err +} + +const opDescribeScheduledInstances = "DescribeScheduledInstances" + +// DescribeScheduledInstancesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeScheduledInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeScheduledInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeScheduledInstancesRequest method. +// req, resp := client.DescribeScheduledInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeScheduledInstancesRequest(input *DescribeScheduledInstancesInput) (req *request.Request, output *DescribeScheduledInstancesOutput) { + op := &request.Operation{ + Name: opDescribeScheduledInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeScheduledInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeScheduledInstancesOutput{} + req.Data = output + return +} + +// Describes one or more of your Scheduled Instances. +func (c *EC2) DescribeScheduledInstances(input *DescribeScheduledInstancesInput) (*DescribeScheduledInstancesOutput, error) { + req, out := c.DescribeScheduledInstancesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSecurityGroupReferences = "DescribeSecurityGroupReferences" + +// DescribeSecurityGroupReferencesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSecurityGroupReferences operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSecurityGroupReferences method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSecurityGroupReferencesRequest method. +// req, resp := client.DescribeSecurityGroupReferencesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSecurityGroupReferencesRequest(input *DescribeSecurityGroupReferencesInput) (req *request.Request, output *DescribeSecurityGroupReferencesOutput) { + op := &request.Operation{ + Name: opDescribeSecurityGroupReferences, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSecurityGroupReferencesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSecurityGroupReferencesOutput{} + req.Data = output + return +} + +// [EC2-VPC only] Describes the VPCs on the other side of a VPC peering connection +// that are referencing the security groups you've specified in this request. +func (c *EC2) DescribeSecurityGroupReferences(input *DescribeSecurityGroupReferencesInput) (*DescribeSecurityGroupReferencesOutput, error) { + req, out := c.DescribeSecurityGroupReferencesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSecurityGroups = "DescribeSecurityGroups" + +// DescribeSecurityGroupsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSecurityGroups operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSecurityGroups method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSecurityGroupsRequest method. +// req, resp := client.DescribeSecurityGroupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSecurityGroupsRequest(input *DescribeSecurityGroupsInput) (req *request.Request, output *DescribeSecurityGroupsOutput) { + op := &request.Operation{ + Name: opDescribeSecurityGroups, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSecurityGroupsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSecurityGroupsOutput{} + req.Data = output + return +} + +// Describes one or more of your security groups. +// +// A security group is for use with instances either in the EC2-Classic platform +// or in a specific VPC. For more information, see Amazon EC2 Security Groups +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) +// in the Amazon Elastic Compute Cloud User Guide and Security Groups for Your +// VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeSecurityGroups(input *DescribeSecurityGroupsInput) (*DescribeSecurityGroupsOutput, error) { + req, out := c.DescribeSecurityGroupsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSnapshotAttribute = "DescribeSnapshotAttribute" + +// DescribeSnapshotAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSnapshotAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSnapshotAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSnapshotAttributeRequest method. +// req, resp := client.DescribeSnapshotAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSnapshotAttributeRequest(input *DescribeSnapshotAttributeInput) (req *request.Request, output *DescribeSnapshotAttributeOutput) { + op := &request.Operation{ + Name: opDescribeSnapshotAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSnapshotAttributeInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSnapshotAttributeOutput{} + req.Data = output + return +} + +// Describes the specified attribute of the specified snapshot. You can specify +// only one attribute at a time. +// +// For more information about EBS snapshots, see Amazon EBS Snapshots (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSSnapshots.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeSnapshotAttribute(input *DescribeSnapshotAttributeInput) (*DescribeSnapshotAttributeOutput, error) { + req, out := c.DescribeSnapshotAttributeRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSnapshots = "DescribeSnapshots" + +// DescribeSnapshotsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSnapshots operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSnapshots method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSnapshotsRequest method. +// req, resp := client.DescribeSnapshotsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *request.Request, output *DescribeSnapshotsOutput) { + op := &request.Operation{ + Name: opDescribeSnapshots, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeSnapshotsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSnapshotsOutput{} + req.Data = output + return +} + +// Describes one or more of the EBS snapshots available to you. Available snapshots +// include public snapshots available for any AWS account to launch, private +// snapshots that you own, and private snapshots owned by another AWS account +// but for which you've been given explicit create volume permissions. +// +// The create volume permissions fall into the following categories: +// +// public: The owner of the snapshot granted create volume permissions for +// the snapshot to the all group. All AWS accounts have create volume permissions +// for these snapshots. +// +// explicit: The owner of the snapshot granted create volume permissions +// to a specific AWS account. +// +// implicit: An AWS account has implicit create volume permissions for all +// snapshots it owns. +// +// The list of snapshots returned can be modified by specifying snapshot +// IDs, snapshot owners, or AWS accounts with create volume permissions. If +// no options are specified, Amazon EC2 returns all snapshots for which you +// have create volume permissions. +// +// If you specify one or more snapshot IDs, only snapshots that have the specified +// IDs are returned. If you specify an invalid snapshot ID, an error is returned. +// If you specify a snapshot ID for which you do not have access, it is not +// included in the returned results. +// +// If you specify one or more snapshot owners using the OwnerIds option, only +// snapshots from the specified owners and for which you have access are returned. +// The results can include the AWS account IDs of the specified owners, amazon +// for snapshots owned by Amazon, or self for snapshots that you own. +// +// If you specify a list of restorable users, only snapshots with create snapshot +// permissions for those users are returned. You can specify AWS account IDs +// (if you own the snapshots), self for snapshots for which you own or have +// explicit permissions, or all for public snapshots. +// +// If you are describing a long list of snapshots, you can paginate the output +// to make the list more manageable. The MaxResults parameter sets the maximum +// number of results returned in a single page. If the list of results exceeds +// your MaxResults value, then that number of results is returned along with +// a NextToken value that can be passed to a subsequent DescribeSnapshots request +// to retrieve the remaining results. +// +// For more information about EBS snapshots, see Amazon EBS Snapshots (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSSnapshots.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeSnapshots(input *DescribeSnapshotsInput) (*DescribeSnapshotsOutput, error) { + req, out := c.DescribeSnapshotsRequest(input) + err := req.Send() + return out, err +} + +// DescribeSnapshotsPages iterates over the pages of a DescribeSnapshots operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeSnapshots method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeSnapshots operation. +// pageNum := 0 +// err := client.DescribeSnapshotsPages(params, +// func(page *DescribeSnapshotsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeSnapshotsPages(input *DescribeSnapshotsInput, fn func(p *DescribeSnapshotsOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeSnapshotsRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeSnapshotsOutput), lastPage) + }) +} + +const opDescribeSpotDatafeedSubscription = "DescribeSpotDatafeedSubscription" + +// DescribeSpotDatafeedSubscriptionRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSpotDatafeedSubscription operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSpotDatafeedSubscription method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSpotDatafeedSubscriptionRequest method. +// req, resp := client.DescribeSpotDatafeedSubscriptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSpotDatafeedSubscriptionRequest(input *DescribeSpotDatafeedSubscriptionInput) (req *request.Request, output *DescribeSpotDatafeedSubscriptionOutput) { + op := &request.Operation{ + Name: opDescribeSpotDatafeedSubscription, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSpotDatafeedSubscriptionInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSpotDatafeedSubscriptionOutput{} + req.Data = output + return +} + +// Describes the data feed for Spot instances. For more information, see Spot +// Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeSpotDatafeedSubscription(input *DescribeSpotDatafeedSubscriptionInput) (*DescribeSpotDatafeedSubscriptionOutput, error) { + req, out := c.DescribeSpotDatafeedSubscriptionRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSpotFleetInstances = "DescribeSpotFleetInstances" + +// DescribeSpotFleetInstancesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSpotFleetInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSpotFleetInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSpotFleetInstancesRequest method. +// req, resp := client.DescribeSpotFleetInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSpotFleetInstancesRequest(input *DescribeSpotFleetInstancesInput) (req *request.Request, output *DescribeSpotFleetInstancesOutput) { + op := &request.Operation{ + Name: opDescribeSpotFleetInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSpotFleetInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSpotFleetInstancesOutput{} + req.Data = output + return +} + +// Describes the running instances for the specified Spot fleet. +func (c *EC2) DescribeSpotFleetInstances(input *DescribeSpotFleetInstancesInput) (*DescribeSpotFleetInstancesOutput, error) { + req, out := c.DescribeSpotFleetInstancesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSpotFleetRequestHistory = "DescribeSpotFleetRequestHistory" + +// DescribeSpotFleetRequestHistoryRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSpotFleetRequestHistory operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSpotFleetRequestHistory method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSpotFleetRequestHistoryRequest method. +// req, resp := client.DescribeSpotFleetRequestHistoryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSpotFleetRequestHistoryRequest(input *DescribeSpotFleetRequestHistoryInput) (req *request.Request, output *DescribeSpotFleetRequestHistoryOutput) { + op := &request.Operation{ + Name: opDescribeSpotFleetRequestHistory, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSpotFleetRequestHistoryInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSpotFleetRequestHistoryOutput{} + req.Data = output + return +} + +// Describes the events for the specified Spot fleet request during the specified +// time. +// +// Spot fleet events are delayed by up to 30 seconds before they can be described. +// This ensures that you can query by the last evaluated time and not miss a +// recorded event. +func (c *EC2) DescribeSpotFleetRequestHistory(input *DescribeSpotFleetRequestHistoryInput) (*DescribeSpotFleetRequestHistoryOutput, error) { + req, out := c.DescribeSpotFleetRequestHistoryRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSpotFleetRequests = "DescribeSpotFleetRequests" + +// DescribeSpotFleetRequestsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSpotFleetRequests operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSpotFleetRequests method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSpotFleetRequestsRequest method. +// req, resp := client.DescribeSpotFleetRequestsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsInput) (req *request.Request, output *DescribeSpotFleetRequestsOutput) { + op := &request.Operation{ + Name: opDescribeSpotFleetRequests, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeSpotFleetRequestsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSpotFleetRequestsOutput{} + req.Data = output + return +} + +// Describes your Spot fleet requests. +func (c *EC2) DescribeSpotFleetRequests(input *DescribeSpotFleetRequestsInput) (*DescribeSpotFleetRequestsOutput, error) { + req, out := c.DescribeSpotFleetRequestsRequest(input) + err := req.Send() + return out, err +} + +// DescribeSpotFleetRequestsPages iterates over the pages of a DescribeSpotFleetRequests operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeSpotFleetRequests method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeSpotFleetRequests operation. +// pageNum := 0 +// err := client.DescribeSpotFleetRequestsPages(params, +// func(page *DescribeSpotFleetRequestsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeSpotFleetRequestsPages(input *DescribeSpotFleetRequestsInput, fn func(p *DescribeSpotFleetRequestsOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeSpotFleetRequestsRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeSpotFleetRequestsOutput), lastPage) + }) +} + +const opDescribeSpotInstanceRequests = "DescribeSpotInstanceRequests" + +// DescribeSpotInstanceRequestsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSpotInstanceRequests operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSpotInstanceRequests method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSpotInstanceRequestsRequest method. +// req, resp := client.DescribeSpotInstanceRequestsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceRequestsInput) (req *request.Request, output *DescribeSpotInstanceRequestsOutput) { + op := &request.Operation{ + Name: opDescribeSpotInstanceRequests, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSpotInstanceRequestsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSpotInstanceRequestsOutput{} + req.Data = output + return +} + +// Describes the Spot instance requests that belong to your account. Spot instances +// are instances that Amazon EC2 launches when the bid price that you specify +// exceeds the current Spot price. Amazon EC2 periodically sets the Spot price +// based on available Spot instance capacity and current Spot instance requests. +// For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// You can use DescribeSpotInstanceRequests to find a running Spot instance +// by examining the response. If the status of the Spot instance is fulfilled, +// the instance ID appears in the response and contains the identifier of the +// instance. Alternatively, you can use DescribeInstances with a filter to look +// for instances where the instance lifecycle is spot. +func (c *EC2) DescribeSpotInstanceRequests(input *DescribeSpotInstanceRequestsInput) (*DescribeSpotInstanceRequestsOutput, error) { + req, out := c.DescribeSpotInstanceRequestsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSpotPriceHistory = "DescribeSpotPriceHistory" + +// DescribeSpotPriceHistoryRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSpotPriceHistory operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSpotPriceHistory method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSpotPriceHistoryRequest method. +// req, resp := client.DescribeSpotPriceHistoryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSpotPriceHistoryRequest(input *DescribeSpotPriceHistoryInput) (req *request.Request, output *DescribeSpotPriceHistoryOutput) { + op := &request.Operation{ + Name: opDescribeSpotPriceHistory, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeSpotPriceHistoryInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSpotPriceHistoryOutput{} + req.Data = output + return +} + +// Describes the Spot price history. The prices returned are listed in chronological +// order, from the oldest to the most recent, for up to the past 90 days. For +// more information, see Spot Instance Pricing History (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances-history.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// When you specify a start and end time, this operation returns the prices +// of the instance types within the time range that you specified and the time +// when the price changed. The price is valid within the time period that you +// specified; the response merely indicates the last time that the price changed. +func (c *EC2) DescribeSpotPriceHistory(input *DescribeSpotPriceHistoryInput) (*DescribeSpotPriceHistoryOutput, error) { + req, out := c.DescribeSpotPriceHistoryRequest(input) + err := req.Send() + return out, err +} + +// DescribeSpotPriceHistoryPages iterates over the pages of a DescribeSpotPriceHistory operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeSpotPriceHistory method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeSpotPriceHistory operation. +// pageNum := 0 +// err := client.DescribeSpotPriceHistoryPages(params, +// func(page *DescribeSpotPriceHistoryOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeSpotPriceHistoryPages(input *DescribeSpotPriceHistoryInput, fn func(p *DescribeSpotPriceHistoryOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeSpotPriceHistoryRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeSpotPriceHistoryOutput), lastPage) + }) +} + +const opDescribeStaleSecurityGroups = "DescribeStaleSecurityGroups" + +// DescribeStaleSecurityGroupsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeStaleSecurityGroups operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeStaleSecurityGroups method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeStaleSecurityGroupsRequest method. +// req, resp := client.DescribeStaleSecurityGroupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeStaleSecurityGroupsRequest(input *DescribeStaleSecurityGroupsInput) (req *request.Request, output *DescribeStaleSecurityGroupsOutput) { + op := &request.Operation{ + Name: opDescribeStaleSecurityGroups, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeStaleSecurityGroupsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeStaleSecurityGroupsOutput{} + req.Data = output + return +} + +// [EC2-VPC only] Describes the stale security group rules for security groups +// in a specified VPC. Rules are stale when they reference a deleted security +// group in a peer VPC, or a security group in a peer VPC for which the VPC +// peering connection has been deleted. +func (c *EC2) DescribeStaleSecurityGroups(input *DescribeStaleSecurityGroupsInput) (*DescribeStaleSecurityGroupsOutput, error) { + req, out := c.DescribeStaleSecurityGroupsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeSubnets = "DescribeSubnets" + +// DescribeSubnetsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeSubnets operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeSubnets method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeSubnetsRequest method. +// req, resp := client.DescribeSubnetsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeSubnetsRequest(input *DescribeSubnetsInput) (req *request.Request, output *DescribeSubnetsOutput) { + op := &request.Operation{ + Name: opDescribeSubnets, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeSubnetsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeSubnetsOutput{} + req.Data = output + return +} + +// Describes one or more of your subnets. +// +// For more information about subnets, see Your VPC and Subnets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeSubnets(input *DescribeSubnetsInput) (*DescribeSubnetsOutput, error) { + req, out := c.DescribeSubnetsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeTags = "DescribeTags" + +// DescribeTagsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeTags operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeTags method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeTagsRequest method. +// req, resp := client.DescribeTagsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) { + op := &request.Operation{ + Name: opDescribeTags, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeTagsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeTagsOutput{} + req.Data = output + return +} + +// Describes one or more of the tags for your EC2 resources. +// +// For more information about tags, see Tagging Your Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error) { + req, out := c.DescribeTagsRequest(input) + err := req.Send() + return out, err +} + +// DescribeTagsPages iterates over the pages of a DescribeTags operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeTags method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeTags operation. +// pageNum := 0 +// err := client.DescribeTagsPages(params, +// func(page *DescribeTagsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeTagsPages(input *DescribeTagsInput, fn func(p *DescribeTagsOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeTagsRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeTagsOutput), lastPage) + }) +} + +const opDescribeVolumeAttribute = "DescribeVolumeAttribute" + +// DescribeVolumeAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVolumeAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVolumeAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVolumeAttributeRequest method. +// req, resp := client.DescribeVolumeAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVolumeAttributeRequest(input *DescribeVolumeAttributeInput) (req *request.Request, output *DescribeVolumeAttributeOutput) { + op := &request.Operation{ + Name: opDescribeVolumeAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVolumeAttributeInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVolumeAttributeOutput{} + req.Data = output + return +} + +// Describes the specified attribute of the specified volume. You can specify +// only one attribute at a time. +// +// For more information about EBS volumes, see Amazon EBS Volumes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumes.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeVolumeAttribute(input *DescribeVolumeAttributeInput) (*DescribeVolumeAttributeOutput, error) { + req, out := c.DescribeVolumeAttributeRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVolumeStatus = "DescribeVolumeStatus" + +// DescribeVolumeStatusRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVolumeStatus operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVolumeStatus method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVolumeStatusRequest method. +// req, resp := client.DescribeVolumeStatusRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVolumeStatusRequest(input *DescribeVolumeStatusInput) (req *request.Request, output *DescribeVolumeStatusOutput) { + op := &request.Operation{ + Name: opDescribeVolumeStatus, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeVolumeStatusInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVolumeStatusOutput{} + req.Data = output + return +} + +// Describes the status of the specified volumes. Volume status provides the +// result of the checks performed on your volumes to determine events that can +// impair the performance of your volumes. The performance of a volume can be +// affected if an issue occurs on the volume's underlying host. If the volume's +// underlying host experiences a power outage or system issue, after the system +// is restored, there could be data inconsistencies on the volume. Volume events +// notify you if this occurs. Volume actions notify you if any action needs +// to be taken in response to the event. +// +// The DescribeVolumeStatus operation provides the following information about +// the specified volumes: +// +// Status: Reflects the current status of the volume. The possible values +// are ok, impaired , warning, or insufficient-data. If all checks pass, the +// overall status of the volume is ok. If the check fails, the overall status +// is impaired. If the status is insufficient-data, then the checks may still +// be taking place on your volume at the time. We recommend that you retry the +// request. For more information on volume status, see Monitoring the Status +// of Your Volumes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-volume-status.html). +// +// Events: Reflect the cause of a volume status and may require you to take +// action. For example, if your volume returns an impaired status, then the +// volume event might be potential-data-inconsistency. This means that your +// volume has been affected by an issue with the underlying host, has all I/O +// operations disabled, and may have inconsistent data. +// +// Actions: Reflect the actions you may have to take in response to an event. +// For example, if the status of the volume is impaired and the volume event +// shows potential-data-inconsistency, then the action shows enable-volume-io. +// This means that you may want to enable the I/O operations for the volume +// by calling the EnableVolumeIO action and then check the volume for data consistency. +// +// Volume status is based on the volume status checks, and does not reflect +// the volume state. Therefore, volume status does not indicate volumes in the +// error state (for example, when a volume is incapable of accepting I/O.) +func (c *EC2) DescribeVolumeStatus(input *DescribeVolumeStatusInput) (*DescribeVolumeStatusOutput, error) { + req, out := c.DescribeVolumeStatusRequest(input) + err := req.Send() + return out, err +} + +// DescribeVolumeStatusPages iterates over the pages of a DescribeVolumeStatus operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeVolumeStatus method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeVolumeStatus operation. +// pageNum := 0 +// err := client.DescribeVolumeStatusPages(params, +// func(page *DescribeVolumeStatusOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeVolumeStatusPages(input *DescribeVolumeStatusInput, fn func(p *DescribeVolumeStatusOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeVolumeStatusRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeVolumeStatusOutput), lastPage) + }) +} + +const opDescribeVolumes = "DescribeVolumes" + +// DescribeVolumesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVolumes operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVolumes method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVolumesRequest method. +// req, resp := client.DescribeVolumesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVolumesRequest(input *DescribeVolumesInput) (req *request.Request, output *DescribeVolumesOutput) { + op := &request.Operation{ + Name: opDescribeVolumes, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeVolumesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVolumesOutput{} + req.Data = output + return +} + +// Describes the specified EBS volumes. +// +// If you are describing a long list of volumes, you can paginate the output +// to make the list more manageable. The MaxResults parameter sets the maximum +// number of results returned in a single page. If the list of results exceeds +// your MaxResults value, then that number of results is returned along with +// a NextToken value that can be passed to a subsequent DescribeVolumes request +// to retrieve the remaining results. +// +// For more information about EBS volumes, see Amazon EBS Volumes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumes.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeVolumes(input *DescribeVolumesInput) (*DescribeVolumesOutput, error) { + req, out := c.DescribeVolumesRequest(input) + err := req.Send() + return out, err +} + +// DescribeVolumesPages iterates over the pages of a DescribeVolumes operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeVolumes method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeVolumes operation. +// pageNum := 0 +// err := client.DescribeVolumesPages(params, +// func(page *DescribeVolumesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *EC2) DescribeVolumesPages(input *DescribeVolumesInput, fn func(p *DescribeVolumesOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.DescribeVolumesRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*DescribeVolumesOutput), lastPage) + }) +} + +const opDescribeVpcAttribute = "DescribeVpcAttribute" + +// DescribeVpcAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcAttributeRequest method. +// req, resp := client.DescribeVpcAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcAttributeRequest(input *DescribeVpcAttributeInput) (req *request.Request, output *DescribeVpcAttributeOutput) { + op := &request.Operation{ + Name: opDescribeVpcAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcAttributeInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcAttributeOutput{} + req.Data = output + return +} + +// Describes the specified attribute of the specified VPC. You can specify only +// one attribute at a time. +func (c *EC2) DescribeVpcAttribute(input *DescribeVpcAttributeInput) (*DescribeVpcAttributeOutput, error) { + req, out := c.DescribeVpcAttributeRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpcClassicLink = "DescribeVpcClassicLink" + +// DescribeVpcClassicLinkRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcClassicLink operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcClassicLink method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcClassicLinkRequest method. +// req, resp := client.DescribeVpcClassicLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcClassicLinkRequest(input *DescribeVpcClassicLinkInput) (req *request.Request, output *DescribeVpcClassicLinkOutput) { + op := &request.Operation{ + Name: opDescribeVpcClassicLink, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcClassicLinkInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcClassicLinkOutput{} + req.Data = output + return +} + +// Describes the ClassicLink status of one or more VPCs. +func (c *EC2) DescribeVpcClassicLink(input *DescribeVpcClassicLinkInput) (*DescribeVpcClassicLinkOutput, error) { + req, out := c.DescribeVpcClassicLinkRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpcClassicLinkDnsSupport = "DescribeVpcClassicLinkDnsSupport" + +// DescribeVpcClassicLinkDnsSupportRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcClassicLinkDnsSupport operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcClassicLinkDnsSupport method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcClassicLinkDnsSupportRequest method. +// req, resp := client.DescribeVpcClassicLinkDnsSupportRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcClassicLinkDnsSupportRequest(input *DescribeVpcClassicLinkDnsSupportInput) (req *request.Request, output *DescribeVpcClassicLinkDnsSupportOutput) { + op := &request.Operation{ + Name: opDescribeVpcClassicLinkDnsSupport, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcClassicLinkDnsSupportInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcClassicLinkDnsSupportOutput{} + req.Data = output + return +} + +// Describes the ClassicLink DNS support status of one or more VPCs. If enabled, +// the DNS hostname of a linked EC2-Classic instance resolves to its private +// IP address when addressed from an instance in the VPC to which it's linked. +// Similarly, the DNS hostname of an instance in a VPC resolves to its private +// IP address when addressed from a linked EC2-Classic instance. For more information +// about ClassicLink, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeVpcClassicLinkDnsSupport(input *DescribeVpcClassicLinkDnsSupportInput) (*DescribeVpcClassicLinkDnsSupportOutput, error) { + req, out := c.DescribeVpcClassicLinkDnsSupportRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpcEndpointServices = "DescribeVpcEndpointServices" + +// DescribeVpcEndpointServicesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcEndpointServices operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcEndpointServices method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcEndpointServicesRequest method. +// req, resp := client.DescribeVpcEndpointServicesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcEndpointServicesRequest(input *DescribeVpcEndpointServicesInput) (req *request.Request, output *DescribeVpcEndpointServicesOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpointServices, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcEndpointServicesInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcEndpointServicesOutput{} + req.Data = output + return +} + +// Describes all supported AWS services that can be specified when creating +// a VPC endpoint. +func (c *EC2) DescribeVpcEndpointServices(input *DescribeVpcEndpointServicesInput) (*DescribeVpcEndpointServicesOutput, error) { + req, out := c.DescribeVpcEndpointServicesRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpcEndpoints = "DescribeVpcEndpoints" + +// DescribeVpcEndpointsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcEndpoints operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcEndpoints method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcEndpointsRequest method. +// req, resp := client.DescribeVpcEndpointsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcEndpointsRequest(input *DescribeVpcEndpointsInput) (req *request.Request, output *DescribeVpcEndpointsOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpoints, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcEndpointsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcEndpointsOutput{} + req.Data = output + return +} + +// Describes one or more of your VPC endpoints. +func (c *EC2) DescribeVpcEndpoints(input *DescribeVpcEndpointsInput) (*DescribeVpcEndpointsOutput, error) { + req, out := c.DescribeVpcEndpointsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpcPeeringConnections = "DescribeVpcPeeringConnections" + +// DescribeVpcPeeringConnectionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcPeeringConnections operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcPeeringConnections method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcPeeringConnectionsRequest method. +// req, resp := client.DescribeVpcPeeringConnectionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcPeeringConnectionsRequest(input *DescribeVpcPeeringConnectionsInput) (req *request.Request, output *DescribeVpcPeeringConnectionsOutput) { + op := &request.Operation{ + Name: opDescribeVpcPeeringConnections, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcPeeringConnectionsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcPeeringConnectionsOutput{} + req.Data = output + return +} + +// Describes one or more of your VPC peering connections. +func (c *EC2) DescribeVpcPeeringConnections(input *DescribeVpcPeeringConnectionsInput) (*DescribeVpcPeeringConnectionsOutput, error) { + req, out := c.DescribeVpcPeeringConnectionsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpcs = "DescribeVpcs" + +// DescribeVpcsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcs operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpcs method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpcsRequest method. +// req, resp := client.DescribeVpcsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpcsRequest(input *DescribeVpcsInput) (req *request.Request, output *DescribeVpcsOutput) { + op := &request.Operation{ + Name: opDescribeVpcs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpcsOutput{} + req.Data = output + return +} + +// Describes one or more of your VPCs. +func (c *EC2) DescribeVpcs(input *DescribeVpcsInput) (*DescribeVpcsOutput, error) { + req, out := c.DescribeVpcsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpnConnections = "DescribeVpnConnections" + +// DescribeVpnConnectionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpnConnections operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpnConnections method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpnConnectionsRequest method. +// req, resp := client.DescribeVpnConnectionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpnConnectionsRequest(input *DescribeVpnConnectionsInput) (req *request.Request, output *DescribeVpnConnectionsOutput) { + op := &request.Operation{ + Name: opDescribeVpnConnections, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpnConnectionsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpnConnectionsOutput{} + req.Data = output + return +} + +// Describes one or more of your VPN connections. +// +// For more information about VPN connections, see Adding a Hardware Virtual +// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeVpnConnections(input *DescribeVpnConnectionsInput) (*DescribeVpnConnectionsOutput, error) { + req, out := c.DescribeVpnConnectionsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeVpnGateways = "DescribeVpnGateways" + +// DescribeVpnGatewaysRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpnGateways operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeVpnGateways method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeVpnGatewaysRequest method. +// req, resp := client.DescribeVpnGatewaysRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeVpnGatewaysRequest(input *DescribeVpnGatewaysInput) (req *request.Request, output *DescribeVpnGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeVpnGateways, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpnGatewaysInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeVpnGatewaysOutput{} + req.Data = output + return +} + +// Describes one or more of your virtual private gateways. +// +// For more information about virtual private gateways, see Adding an IPsec +// Hardware VPN to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeVpnGateways(input *DescribeVpnGatewaysInput) (*DescribeVpnGatewaysOutput, error) { + req, out := c.DescribeVpnGatewaysRequest(input) + err := req.Send() + return out, err +} + +const opDetachClassicLinkVpc = "DetachClassicLinkVpc" + +// DetachClassicLinkVpcRequest generates a "aws/request.Request" representing the +// client's request for the DetachClassicLinkVpc operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DetachClassicLinkVpc method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DetachClassicLinkVpcRequest method. +// req, resp := client.DetachClassicLinkVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DetachClassicLinkVpcRequest(input *DetachClassicLinkVpcInput) (req *request.Request, output *DetachClassicLinkVpcOutput) { + op := &request.Operation{ + Name: opDetachClassicLinkVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachClassicLinkVpcInput{} + } + + req = c.newRequest(op, input, output) + output = &DetachClassicLinkVpcOutput{} + req.Data = output + return +} + +// Unlinks (detaches) a linked EC2-Classic instance from a VPC. After the instance +// has been unlinked, the VPC security groups are no longer associated with +// it. An instance is automatically unlinked from a VPC when it's stopped. +func (c *EC2) DetachClassicLinkVpc(input *DetachClassicLinkVpcInput) (*DetachClassicLinkVpcOutput, error) { + req, out := c.DetachClassicLinkVpcRequest(input) + err := req.Send() + return out, err +} + +const opDetachInternetGateway = "DetachInternetGateway" + +// DetachInternetGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DetachInternetGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DetachInternetGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DetachInternetGatewayRequest method. +// req, resp := client.DetachInternetGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (req *request.Request, output *DetachInternetGatewayOutput) { + op := &request.Operation{ + Name: opDetachInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachInternetGatewayInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DetachInternetGatewayOutput{} + req.Data = output + return +} + +// Detaches an Internet gateway from a VPC, disabling connectivity between the +// Internet and the VPC. The VPC must not contain any running instances with +// Elastic IP addresses. +func (c *EC2) DetachInternetGateway(input *DetachInternetGatewayInput) (*DetachInternetGatewayOutput, error) { + req, out := c.DetachInternetGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDetachNetworkInterface = "DetachNetworkInterface" + +// DetachNetworkInterfaceRequest generates a "aws/request.Request" representing the +// client's request for the DetachNetworkInterface operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DetachNetworkInterface method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DetachNetworkInterfaceRequest method. +// req, resp := client.DetachNetworkInterfaceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DetachNetworkInterfaceRequest(input *DetachNetworkInterfaceInput) (req *request.Request, output *DetachNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opDetachNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachNetworkInterfaceInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DetachNetworkInterfaceOutput{} + req.Data = output + return +} + +// Detaches a network interface from an instance. +func (c *EC2) DetachNetworkInterface(input *DetachNetworkInterfaceInput) (*DetachNetworkInterfaceOutput, error) { + req, out := c.DetachNetworkInterfaceRequest(input) + err := req.Send() + return out, err +} + +const opDetachVolume = "DetachVolume" + +// DetachVolumeRequest generates a "aws/request.Request" representing the +// client's request for the DetachVolume operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DetachVolume method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DetachVolumeRequest method. +// req, resp := client.DetachVolumeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DetachVolumeRequest(input *DetachVolumeInput) (req *request.Request, output *VolumeAttachment) { + op := &request.Operation{ + Name: opDetachVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &VolumeAttachment{} + req.Data = output + return +} + +// Detaches an EBS volume from an instance. Make sure to unmount any file systems +// on the device within your operating system before detaching the volume. Failure +// to do so can result in the volume becoming stuck in the busy state while +// detaching. If this happens, detachment can be delayed indefinitely until +// you unmount the volume, force detachment, reboot the instance, or all three. +// If an EBS volume is the root device of an instance, it can't be detached +// while the instance is running. To detach the root volume, stop the instance +// first. +// +// When a volume with an AWS Marketplace product code is detached from an instance, +// the product code is no longer associated with the instance. +// +// For more information, see Detaching an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-detaching-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DetachVolume(input *DetachVolumeInput) (*VolumeAttachment, error) { + req, out := c.DetachVolumeRequest(input) + err := req.Send() + return out, err +} + +const opDetachVpnGateway = "DetachVpnGateway" + +// DetachVpnGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DetachVpnGateway operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DetachVpnGateway method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DetachVpnGatewayRequest method. +// req, resp := client.DetachVpnGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DetachVpnGatewayRequest(input *DetachVpnGatewayInput) (req *request.Request, output *DetachVpnGatewayOutput) { + op := &request.Operation{ + Name: opDetachVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachVpnGatewayInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DetachVpnGatewayOutput{} + req.Data = output + return +} + +// Detaches a virtual private gateway from a VPC. You do this if you're planning +// to turn off the VPC and not use it anymore. You can confirm a virtual private +// gateway has been completely detached from a VPC by describing the virtual +// private gateway (any attachments to the virtual private gateway are also +// described). +// +// You must wait for the attachment's state to switch to detached before you +// can delete the VPC or attach a different VPC to the virtual private gateway. +func (c *EC2) DetachVpnGateway(input *DetachVpnGatewayInput) (*DetachVpnGatewayOutput, error) { + req, out := c.DetachVpnGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDisableVgwRoutePropagation = "DisableVgwRoutePropagation" + +// DisableVgwRoutePropagationRequest generates a "aws/request.Request" representing the +// client's request for the DisableVgwRoutePropagation operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DisableVgwRoutePropagation method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DisableVgwRoutePropagationRequest method. +// req, resp := client.DisableVgwRoutePropagationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DisableVgwRoutePropagationRequest(input *DisableVgwRoutePropagationInput) (req *request.Request, output *DisableVgwRoutePropagationOutput) { + op := &request.Operation{ + Name: opDisableVgwRoutePropagation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableVgwRoutePropagationInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DisableVgwRoutePropagationOutput{} + req.Data = output + return +} + +// Disables a virtual private gateway (VGW) from propagating routes to a specified +// route table of a VPC. +func (c *EC2) DisableVgwRoutePropagation(input *DisableVgwRoutePropagationInput) (*DisableVgwRoutePropagationOutput, error) { + req, out := c.DisableVgwRoutePropagationRequest(input) + err := req.Send() + return out, err +} + +const opDisableVpcClassicLink = "DisableVpcClassicLink" + +// DisableVpcClassicLinkRequest generates a "aws/request.Request" representing the +// client's request for the DisableVpcClassicLink operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DisableVpcClassicLink method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DisableVpcClassicLinkRequest method. +// req, resp := client.DisableVpcClassicLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DisableVpcClassicLinkRequest(input *DisableVpcClassicLinkInput) (req *request.Request, output *DisableVpcClassicLinkOutput) { + op := &request.Operation{ + Name: opDisableVpcClassicLink, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableVpcClassicLinkInput{} + } + + req = c.newRequest(op, input, output) + output = &DisableVpcClassicLinkOutput{} + req.Data = output + return +} + +// Disables ClassicLink for a VPC. You cannot disable ClassicLink for a VPC +// that has EC2-Classic instances linked to it. +func (c *EC2) DisableVpcClassicLink(input *DisableVpcClassicLinkInput) (*DisableVpcClassicLinkOutput, error) { + req, out := c.DisableVpcClassicLinkRequest(input) + err := req.Send() + return out, err +} + +const opDisableVpcClassicLinkDnsSupport = "DisableVpcClassicLinkDnsSupport" + +// DisableVpcClassicLinkDnsSupportRequest generates a "aws/request.Request" representing the +// client's request for the DisableVpcClassicLinkDnsSupport operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DisableVpcClassicLinkDnsSupport method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DisableVpcClassicLinkDnsSupportRequest method. +// req, resp := client.DisableVpcClassicLinkDnsSupportRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DisableVpcClassicLinkDnsSupportRequest(input *DisableVpcClassicLinkDnsSupportInput) (req *request.Request, output *DisableVpcClassicLinkDnsSupportOutput) { + op := &request.Operation{ + Name: opDisableVpcClassicLinkDnsSupport, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableVpcClassicLinkDnsSupportInput{} + } + + req = c.newRequest(op, input, output) + output = &DisableVpcClassicLinkDnsSupportOutput{} + req.Data = output + return +} + +// Disables ClassicLink DNS support for a VPC. If disabled, DNS hostnames resolve +// to public IP addresses when addressed between a linked EC2-Classic instance +// and instances in the VPC to which it's linked. For more information about +// ClassicLink, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DisableVpcClassicLinkDnsSupport(input *DisableVpcClassicLinkDnsSupportInput) (*DisableVpcClassicLinkDnsSupportOutput, error) { + req, out := c.DisableVpcClassicLinkDnsSupportRequest(input) + err := req.Send() + return out, err +} + +const opDisassociateAddress = "DisassociateAddress" + +// DisassociateAddressRequest generates a "aws/request.Request" representing the +// client's request for the DisassociateAddress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DisassociateAddress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DisassociateAddressRequest method. +// req, resp := client.DisassociateAddressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DisassociateAddressRequest(input *DisassociateAddressInput) (req *request.Request, output *DisassociateAddressOutput) { + op := &request.Operation{ + Name: opDisassociateAddress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisassociateAddressInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DisassociateAddressOutput{} + req.Data = output + return +} + +// Disassociates an Elastic IP address from the instance or network interface +// it's associated with. +// +// An Elastic IP address is for use in either the EC2-Classic platform or in +// a VPC. For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// This is an idempotent operation. If you perform the operation more than +// once, Amazon EC2 doesn't return an error. +func (c *EC2) DisassociateAddress(input *DisassociateAddressInput) (*DisassociateAddressOutput, error) { + req, out := c.DisassociateAddressRequest(input) + err := req.Send() + return out, err +} + +const opDisassociateRouteTable = "DisassociateRouteTable" + +// DisassociateRouteTableRequest generates a "aws/request.Request" representing the +// client's request for the DisassociateRouteTable operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DisassociateRouteTable method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DisassociateRouteTableRequest method. +// req, resp := client.DisassociateRouteTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DisassociateRouteTableRequest(input *DisassociateRouteTableInput) (req *request.Request, output *DisassociateRouteTableOutput) { + op := &request.Operation{ + Name: opDisassociateRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisassociateRouteTableInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DisassociateRouteTableOutput{} + req.Data = output + return +} + +// Disassociates a subnet from a route table. +// +// After you perform this action, the subnet no longer uses the routes in the +// route table. Instead, it uses the routes in the VPC's main route table. For +// more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DisassociateRouteTable(input *DisassociateRouteTableInput) (*DisassociateRouteTableOutput, error) { + req, out := c.DisassociateRouteTableRequest(input) + err := req.Send() + return out, err +} + +const opEnableVgwRoutePropagation = "EnableVgwRoutePropagation" + +// EnableVgwRoutePropagationRequest generates a "aws/request.Request" representing the +// client's request for the EnableVgwRoutePropagation operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the EnableVgwRoutePropagation method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the EnableVgwRoutePropagationRequest method. +// req, resp := client.EnableVgwRoutePropagationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) EnableVgwRoutePropagationRequest(input *EnableVgwRoutePropagationInput) (req *request.Request, output *EnableVgwRoutePropagationOutput) { + op := &request.Operation{ + Name: opEnableVgwRoutePropagation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableVgwRoutePropagationInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &EnableVgwRoutePropagationOutput{} + req.Data = output + return +} + +// Enables a virtual private gateway (VGW) to propagate routes to the specified +// route table of a VPC. +func (c *EC2) EnableVgwRoutePropagation(input *EnableVgwRoutePropagationInput) (*EnableVgwRoutePropagationOutput, error) { + req, out := c.EnableVgwRoutePropagationRequest(input) + err := req.Send() + return out, err +} + +const opEnableVolumeIO = "EnableVolumeIO" + +// EnableVolumeIORequest generates a "aws/request.Request" representing the +// client's request for the EnableVolumeIO operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the EnableVolumeIO method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the EnableVolumeIORequest method. +// req, resp := client.EnableVolumeIORequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) EnableVolumeIORequest(input *EnableVolumeIOInput) (req *request.Request, output *EnableVolumeIOOutput) { + op := &request.Operation{ + Name: opEnableVolumeIO, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableVolumeIOInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &EnableVolumeIOOutput{} + req.Data = output + return +} + +// Enables I/O operations for a volume that had I/O operations disabled because +// the data on the volume was potentially inconsistent. +func (c *EC2) EnableVolumeIO(input *EnableVolumeIOInput) (*EnableVolumeIOOutput, error) { + req, out := c.EnableVolumeIORequest(input) + err := req.Send() + return out, err +} + +const opEnableVpcClassicLink = "EnableVpcClassicLink" + +// EnableVpcClassicLinkRequest generates a "aws/request.Request" representing the +// client's request for the EnableVpcClassicLink operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the EnableVpcClassicLink method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the EnableVpcClassicLinkRequest method. +// req, resp := client.EnableVpcClassicLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) EnableVpcClassicLinkRequest(input *EnableVpcClassicLinkInput) (req *request.Request, output *EnableVpcClassicLinkOutput) { + op := &request.Operation{ + Name: opEnableVpcClassicLink, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableVpcClassicLinkInput{} + } + + req = c.newRequest(op, input, output) + output = &EnableVpcClassicLinkOutput{} + req.Data = output + return +} + +// Enables a VPC for ClassicLink. You can then link EC2-Classic instances to +// your ClassicLink-enabled VPC to allow communication over private IP addresses. +// You cannot enable your VPC for ClassicLink if any of your VPC's route tables +// have existing routes for address ranges within the 10.0.0.0/8 IP address +// range, excluding local routes for VPCs in the 10.0.0.0/16 and 10.1.0.0/16 +// IP address ranges. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) EnableVpcClassicLink(input *EnableVpcClassicLinkInput) (*EnableVpcClassicLinkOutput, error) { + req, out := c.EnableVpcClassicLinkRequest(input) + err := req.Send() + return out, err +} + +const opEnableVpcClassicLinkDnsSupport = "EnableVpcClassicLinkDnsSupport" + +// EnableVpcClassicLinkDnsSupportRequest generates a "aws/request.Request" representing the +// client's request for the EnableVpcClassicLinkDnsSupport operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the EnableVpcClassicLinkDnsSupport method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the EnableVpcClassicLinkDnsSupportRequest method. +// req, resp := client.EnableVpcClassicLinkDnsSupportRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) EnableVpcClassicLinkDnsSupportRequest(input *EnableVpcClassicLinkDnsSupportInput) (req *request.Request, output *EnableVpcClassicLinkDnsSupportOutput) { + op := &request.Operation{ + Name: opEnableVpcClassicLinkDnsSupport, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableVpcClassicLinkDnsSupportInput{} + } + + req = c.newRequest(op, input, output) + output = &EnableVpcClassicLinkDnsSupportOutput{} + req.Data = output + return +} + +// Enables a VPC to support DNS hostname resolution for ClassicLink. If enabled, +// the DNS hostname of a linked EC2-Classic instance resolves to its private +// IP address when addressed from an instance in the VPC to which it's linked. +// Similarly, the DNS hostname of an instance in a VPC resolves to its private +// IP address when addressed from a linked EC2-Classic instance. For more information +// about ClassicLink, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) EnableVpcClassicLinkDnsSupport(input *EnableVpcClassicLinkDnsSupportInput) (*EnableVpcClassicLinkDnsSupportOutput, error) { + req, out := c.EnableVpcClassicLinkDnsSupportRequest(input) + err := req.Send() + return out, err +} + +const opGetConsoleOutput = "GetConsoleOutput" + +// GetConsoleOutputRequest generates a "aws/request.Request" representing the +// client's request for the GetConsoleOutput operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetConsoleOutput method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetConsoleOutputRequest method. +// req, resp := client.GetConsoleOutputRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) GetConsoleOutputRequest(input *GetConsoleOutputInput) (req *request.Request, output *GetConsoleOutputOutput) { + op := &request.Operation{ + Name: opGetConsoleOutput, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetConsoleOutputInput{} + } + + req = c.newRequest(op, input, output) + output = &GetConsoleOutputOutput{} + req.Data = output + return +} + +// Gets the console output for the specified instance. +// +// Instances do not have a physical monitor through which you can view their +// console output. They also lack physical controls that allow you to power +// up, reboot, or shut them down. To allow these actions, we provide them through +// the Amazon EC2 API and command line interface. +// +// Instance console output is buffered and posted shortly after instance boot, +// reboot, and termination. Amazon EC2 preserves the most recent 64 KB output +// which is available for at least one hour after the most recent post. +// +// For Linux instances, the instance console output displays the exact console +// output that would normally be displayed on a physical monitor attached to +// a computer. This output is buffered because the instance produces it and +// then posts it to a store where the instance's owner can retrieve it. +// +// For Windows instances, the instance console output includes output from +// the EC2Config service. +func (c *EC2) GetConsoleOutput(input *GetConsoleOutputInput) (*GetConsoleOutputOutput, error) { + req, out := c.GetConsoleOutputRequest(input) + err := req.Send() + return out, err +} + +const opGetConsoleScreenshot = "GetConsoleScreenshot" + +// GetConsoleScreenshotRequest generates a "aws/request.Request" representing the +// client's request for the GetConsoleScreenshot operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetConsoleScreenshot method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetConsoleScreenshotRequest method. +// req, resp := client.GetConsoleScreenshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) GetConsoleScreenshotRequest(input *GetConsoleScreenshotInput) (req *request.Request, output *GetConsoleScreenshotOutput) { + op := &request.Operation{ + Name: opGetConsoleScreenshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetConsoleScreenshotInput{} + } + + req = c.newRequest(op, input, output) + output = &GetConsoleScreenshotOutput{} + req.Data = output + return +} + +// Retrieve a JPG-format screenshot of a running instance to help with troubleshooting. +// +// The returned content is Base64-encoded. +func (c *EC2) GetConsoleScreenshot(input *GetConsoleScreenshotInput) (*GetConsoleScreenshotOutput, error) { + req, out := c.GetConsoleScreenshotRequest(input) + err := req.Send() + return out, err +} + +const opGetHostReservationPurchasePreview = "GetHostReservationPurchasePreview" + +// GetHostReservationPurchasePreviewRequest generates a "aws/request.Request" representing the +// client's request for the GetHostReservationPurchasePreview operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetHostReservationPurchasePreview method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetHostReservationPurchasePreviewRequest method. +// req, resp := client.GetHostReservationPurchasePreviewRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) GetHostReservationPurchasePreviewRequest(input *GetHostReservationPurchasePreviewInput) (req *request.Request, output *GetHostReservationPurchasePreviewOutput) { + op := &request.Operation{ + Name: opGetHostReservationPurchasePreview, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetHostReservationPurchasePreviewInput{} + } + + req = c.newRequest(op, input, output) + output = &GetHostReservationPurchasePreviewOutput{} + req.Data = output + return +} + +// Preview a reservation purchase with configurations that match those of your +// Dedicated Host. You must have active Dedicated Hosts in your account before +// you purchase a reservation. +// +// This is a preview of the PurchaseHostReservation action and does not result +// in the offering being purchased. +func (c *EC2) GetHostReservationPurchasePreview(input *GetHostReservationPurchasePreviewInput) (*GetHostReservationPurchasePreviewOutput, error) { + req, out := c.GetHostReservationPurchasePreviewRequest(input) + err := req.Send() + return out, err +} + +const opGetPasswordData = "GetPasswordData" + +// GetPasswordDataRequest generates a "aws/request.Request" representing the +// client's request for the GetPasswordData operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetPasswordData method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetPasswordDataRequest method. +// req, resp := client.GetPasswordDataRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) GetPasswordDataRequest(input *GetPasswordDataInput) (req *request.Request, output *GetPasswordDataOutput) { + op := &request.Operation{ + Name: opGetPasswordData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetPasswordDataInput{} + } + + req = c.newRequest(op, input, output) + output = &GetPasswordDataOutput{} + req.Data = output + return +} + +// Retrieves the encrypted administrator password for an instance running Windows. +// +// The Windows password is generated at boot if the EC2Config service plugin, +// Ec2SetPassword, is enabled. This usually only happens the first time an AMI +// is launched, and then Ec2SetPassword is automatically disabled. The password +// is not generated for rebundled AMIs unless Ec2SetPassword is enabled before +// bundling. +// +// The password is encrypted using the key pair that you specified when you +// launched the instance. You must provide the corresponding key pair file. +// +// Password generation and encryption takes a few moments. We recommend that +// you wait up to 15 minutes after launching an instance before trying to retrieve +// the generated password. +func (c *EC2) GetPasswordData(input *GetPasswordDataInput) (*GetPasswordDataOutput, error) { + req, out := c.GetPasswordDataRequest(input) + err := req.Send() + return out, err +} + +const opImportImage = "ImportImage" + +// ImportImageRequest generates a "aws/request.Request" representing the +// client's request for the ImportImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportImageRequest method. +// req, resp := client.ImportImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ImportImageRequest(input *ImportImageInput) (req *request.Request, output *ImportImageOutput) { + op := &request.Operation{ + Name: opImportImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ImportImageInput{} + } + + req = c.newRequest(op, input, output) + output = &ImportImageOutput{} + req.Data = output + return +} + +// Import single or multi-volume disk images or EBS snapshots into an Amazon +// Machine Image (AMI). For more information, see Importing a VM as an Image +// Using VM Import/Export (http://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html) +// in the VM Import/Export User Guide. +func (c *EC2) ImportImage(input *ImportImageInput) (*ImportImageOutput, error) { + req, out := c.ImportImageRequest(input) + err := req.Send() + return out, err +} + +const opImportInstance = "ImportInstance" + +// ImportInstanceRequest generates a "aws/request.Request" representing the +// client's request for the ImportInstance operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportInstance method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportInstanceRequest method. +// req, resp := client.ImportInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ImportInstanceRequest(input *ImportInstanceInput) (req *request.Request, output *ImportInstanceOutput) { + op := &request.Operation{ + Name: opImportInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ImportInstanceInput{} + } + + req = c.newRequest(op, input, output) + output = &ImportInstanceOutput{} + req.Data = output + return +} + +// Creates an import instance task using metadata from the specified disk image. +// ImportInstance only supports single-volume VMs. To import multi-volume VMs, +// use ImportImage. For more information, see Importing a Virtual Machine Using +// the Amazon EC2 CLI (http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ec2-cli-vmimport-export.html). +// +// For information about the import manifest referenced by this API action, +// see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). +func (c *EC2) ImportInstance(input *ImportInstanceInput) (*ImportInstanceOutput, error) { + req, out := c.ImportInstanceRequest(input) + err := req.Send() + return out, err +} + +const opImportKeyPair = "ImportKeyPair" + +// ImportKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the ImportKeyPair operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportKeyPair method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportKeyPairRequest method. +// req, resp := client.ImportKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ImportKeyPairRequest(input *ImportKeyPairInput) (req *request.Request, output *ImportKeyPairOutput) { + op := &request.Operation{ + Name: opImportKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ImportKeyPairInput{} + } + + req = c.newRequest(op, input, output) + output = &ImportKeyPairOutput{} + req.Data = output + return +} + +// Imports the public key from an RSA key pair that you created with a third-party +// tool. Compare this with CreateKeyPair, in which AWS creates the key pair +// and gives the keys to you (AWS keeps a copy of the public key). With ImportKeyPair, +// you create the key pair and give AWS just the public key. The private key +// is never transferred between you and AWS. +// +// For more information about key pairs, see Key Pairs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) ImportKeyPair(input *ImportKeyPairInput) (*ImportKeyPairOutput, error) { + req, out := c.ImportKeyPairRequest(input) + err := req.Send() + return out, err +} + +const opImportSnapshot = "ImportSnapshot" + +// ImportSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the ImportSnapshot operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportSnapshot method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportSnapshotRequest method. +// req, resp := client.ImportSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ImportSnapshotRequest(input *ImportSnapshotInput) (req *request.Request, output *ImportSnapshotOutput) { + op := &request.Operation{ + Name: opImportSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ImportSnapshotInput{} + } + + req = c.newRequest(op, input, output) + output = &ImportSnapshotOutput{} + req.Data = output + return +} + +// Imports a disk into an EBS snapshot. +func (c *EC2) ImportSnapshot(input *ImportSnapshotInput) (*ImportSnapshotOutput, error) { + req, out := c.ImportSnapshotRequest(input) + err := req.Send() + return out, err +} + +const opImportVolume = "ImportVolume" + +// ImportVolumeRequest generates a "aws/request.Request" representing the +// client's request for the ImportVolume operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportVolume method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportVolumeRequest method. +// req, resp := client.ImportVolumeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ImportVolumeRequest(input *ImportVolumeInput) (req *request.Request, output *ImportVolumeOutput) { + op := &request.Operation{ + Name: opImportVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ImportVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &ImportVolumeOutput{} + req.Data = output + return +} + +// Creates an import volume task using metadata from the specified disk image.For +// more information, see Importing Disks to Amazon EBS (http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/importing-your-volumes-into-amazon-ebs.html). +// +// For information about the import manifest referenced by this API action, +// see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). +func (c *EC2) ImportVolume(input *ImportVolumeInput) (*ImportVolumeOutput, error) { + req, out := c.ImportVolumeRequest(input) + err := req.Send() + return out, err +} + +const opModifyHosts = "ModifyHosts" + +// ModifyHostsRequest generates a "aws/request.Request" representing the +// client's request for the ModifyHosts operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyHosts method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyHostsRequest method. +// req, resp := client.ModifyHostsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyHostsRequest(input *ModifyHostsInput) (req *request.Request, output *ModifyHostsOutput) { + op := &request.Operation{ + Name: opModifyHosts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyHostsInput{} + } + + req = c.newRequest(op, input, output) + output = &ModifyHostsOutput{} + req.Data = output + return +} + +// Modify the auto-placement setting of a Dedicated Host. When auto-placement +// is enabled, AWS will place instances that you launch with a tenancy of host, +// but without targeting a specific host ID, onto any available Dedicated Host +// in your account which has auto-placement enabled. When auto-placement is +// disabled, you need to provide a host ID if you want the instance to launch +// onto a specific host. If no host ID is provided, the instance will be launched +// onto a suitable host which has auto-placement enabled. +func (c *EC2) ModifyHosts(input *ModifyHostsInput) (*ModifyHostsOutput, error) { + req, out := c.ModifyHostsRequest(input) + err := req.Send() + return out, err +} + +const opModifyIdFormat = "ModifyIdFormat" + +// ModifyIdFormatRequest generates a "aws/request.Request" representing the +// client's request for the ModifyIdFormat operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyIdFormat method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyIdFormatRequest method. +// req, resp := client.ModifyIdFormatRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyIdFormatRequest(input *ModifyIdFormatInput) (req *request.Request, output *ModifyIdFormatOutput) { + op := &request.Operation{ + Name: opModifyIdFormat, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyIdFormatInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyIdFormatOutput{} + req.Data = output + return +} + +// Modifies the ID format for the specified resource on a per-region basis. +// You can specify that resources should receive longer IDs (17-character IDs) +// when they are created. The following resource types support longer IDs: instance +// | reservation | snapshot | volume. +// +// This setting applies to the IAM user who makes the request; it does not +// apply to the entire AWS account. By default, an IAM user defaults to the +// same settings as the root user. If you're using this action as the root user, +// then these settings apply to the entire account, unless an IAM user explicitly +// overrides these settings for themselves. For more information, see Resource +// IDs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/resource-ids.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Resources created with longer IDs are visible to all IAM roles and users, +// regardless of these settings and provided that they have permission to use +// the relevant Describe command for the resource type. +func (c *EC2) ModifyIdFormat(input *ModifyIdFormatInput) (*ModifyIdFormatOutput, error) { + req, out := c.ModifyIdFormatRequest(input) + err := req.Send() + return out, err +} + +const opModifyIdentityIdFormat = "ModifyIdentityIdFormat" + +// ModifyIdentityIdFormatRequest generates a "aws/request.Request" representing the +// client's request for the ModifyIdentityIdFormat operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyIdentityIdFormat method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyIdentityIdFormatRequest method. +// req, resp := client.ModifyIdentityIdFormatRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyIdentityIdFormatRequest(input *ModifyIdentityIdFormatInput) (req *request.Request, output *ModifyIdentityIdFormatOutput) { + op := &request.Operation{ + Name: opModifyIdentityIdFormat, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyIdentityIdFormatInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyIdentityIdFormatOutput{} + req.Data = output + return +} + +// Modifies the ID format of a resource for a specified IAM user, IAM role, +// or the root user for an account; or all IAM users, IAM roles, and the root +// user for an account. You can specify that resources should receive longer +// IDs (17-character IDs) when they are created. +// +// The following resource types support longer IDs: instance | reservation +// | snapshot | volume. For more information, see Resource IDs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/resource-ids.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// This setting applies to the principal specified in the request; it does +// not apply to the principal that makes the request. +// +// Resources created with longer IDs are visible to all IAM roles and users, +// regardless of these settings and provided that they have permission to use +// the relevant Describe command for the resource type. +func (c *EC2) ModifyIdentityIdFormat(input *ModifyIdentityIdFormatInput) (*ModifyIdentityIdFormatOutput, error) { + req, out := c.ModifyIdentityIdFormatRequest(input) + err := req.Send() + return out, err +} + +const opModifyImageAttribute = "ModifyImageAttribute" + +// ModifyImageAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifyImageAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyImageAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyImageAttributeRequest method. +// req, resp := client.ModifyImageAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req *request.Request, output *ModifyImageAttributeOutput) { + op := &request.Operation{ + Name: opModifyImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyImageAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyImageAttributeOutput{} + req.Data = output + return +} + +// Modifies the specified attribute of the specified AMI. You can specify only +// one attribute at a time. +// +// AWS Marketplace product codes cannot be modified. Images with an AWS Marketplace +// product code cannot be made public. +// +// The SriovNetSupport enhanced networking attribute cannot be changed using +// this command. Instead, enable SriovNetSupport on an instance and create an +// AMI from the instance. This will result in an image with SriovNetSupport +// enabled. +func (c *EC2) ModifyImageAttribute(input *ModifyImageAttributeInput) (*ModifyImageAttributeOutput, error) { + req, out := c.ModifyImageAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifyInstanceAttribute = "ModifyInstanceAttribute" + +// ModifyInstanceAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifyInstanceAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyInstanceAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyInstanceAttributeRequest method. +// req, resp := client.ModifyInstanceAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyInstanceAttributeRequest(input *ModifyInstanceAttributeInput) (req *request.Request, output *ModifyInstanceAttributeOutput) { + op := &request.Operation{ + Name: opModifyInstanceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyInstanceAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyInstanceAttributeOutput{} + req.Data = output + return +} + +// Modifies the specified attribute of the specified instance. You can specify +// only one attribute at a time. +// +// To modify some attributes, the instance must be stopped. For more information, +// see Modifying Attributes of a Stopped Instance (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_ChangingAttributesWhileInstanceStopped.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) ModifyInstanceAttribute(input *ModifyInstanceAttributeInput) (*ModifyInstanceAttributeOutput, error) { + req, out := c.ModifyInstanceAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifyInstancePlacement = "ModifyInstancePlacement" + +// ModifyInstancePlacementRequest generates a "aws/request.Request" representing the +// client's request for the ModifyInstancePlacement operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyInstancePlacement method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyInstancePlacementRequest method. +// req, resp := client.ModifyInstancePlacementRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyInstancePlacementRequest(input *ModifyInstancePlacementInput) (req *request.Request, output *ModifyInstancePlacementOutput) { + op := &request.Operation{ + Name: opModifyInstancePlacement, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyInstancePlacementInput{} + } + + req = c.newRequest(op, input, output) + output = &ModifyInstancePlacementOutput{} + req.Data = output + return +} + +// Set the instance affinity value for a specific stopped instance and modify +// the instance tenancy setting. +// +// Instance affinity is disabled by default. When instance affinity is host +// and it is not associated with a specific Dedicated Host, the next time it +// is launched it will automatically be associated with the host it lands on. +// This relationship will persist if the instance is stopped/started, or rebooted. +// +// You can modify the host ID associated with a stopped instance. If a stopped +// instance has a new host ID association, the instance will target that host +// when restarted. +// +// You can modify the tenancy of a stopped instance with a tenancy of host +// or dedicated. +// +// Affinity, hostID, and tenancy are not required parameters, but at least +// one of them must be specified in the request. Affinity and tenancy can be +// modified in the same request, but tenancy can only be modified on instances +// that are stopped. +func (c *EC2) ModifyInstancePlacement(input *ModifyInstancePlacementInput) (*ModifyInstancePlacementOutput, error) { + req, out := c.ModifyInstancePlacementRequest(input) + err := req.Send() + return out, err +} + +const opModifyNetworkInterfaceAttribute = "ModifyNetworkInterfaceAttribute" + +// ModifyNetworkInterfaceAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifyNetworkInterfaceAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyNetworkInterfaceAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyNetworkInterfaceAttributeRequest method. +// req, resp := client.ModifyNetworkInterfaceAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyNetworkInterfaceAttributeRequest(input *ModifyNetworkInterfaceAttributeInput) (req *request.Request, output *ModifyNetworkInterfaceAttributeOutput) { + op := &request.Operation{ + Name: opModifyNetworkInterfaceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyNetworkInterfaceAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyNetworkInterfaceAttributeOutput{} + req.Data = output + return +} + +// Modifies the specified network interface attribute. You can specify only +// one attribute at a time. +func (c *EC2) ModifyNetworkInterfaceAttribute(input *ModifyNetworkInterfaceAttributeInput) (*ModifyNetworkInterfaceAttributeOutput, error) { + req, out := c.ModifyNetworkInterfaceAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifyReservedInstances = "ModifyReservedInstances" + +// ModifyReservedInstancesRequest generates a "aws/request.Request" representing the +// client's request for the ModifyReservedInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyReservedInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyReservedInstancesRequest method. +// req, resp := client.ModifyReservedInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput) (req *request.Request, output *ModifyReservedInstancesOutput) { + op := &request.Operation{ + Name: opModifyReservedInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyReservedInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &ModifyReservedInstancesOutput{} + req.Data = output + return +} + +// Modifies the Availability Zone, instance count, instance type, or network +// platform (EC2-Classic or EC2-VPC) of your Reserved Instances. The Reserved +// Instances to be modified must be identical, except for Availability Zone, +// network platform, and instance type. +// +// For more information, see Modifying Reserved Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-modifying.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) ModifyReservedInstances(input *ModifyReservedInstancesInput) (*ModifyReservedInstancesOutput, error) { + req, out := c.ModifyReservedInstancesRequest(input) + err := req.Send() + return out, err +} + +const opModifySnapshotAttribute = "ModifySnapshotAttribute" + +// ModifySnapshotAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifySnapshotAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifySnapshotAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifySnapshotAttributeRequest method. +// req, resp := client.ModifySnapshotAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifySnapshotAttributeRequest(input *ModifySnapshotAttributeInput) (req *request.Request, output *ModifySnapshotAttributeOutput) { + op := &request.Operation{ + Name: opModifySnapshotAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifySnapshotAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifySnapshotAttributeOutput{} + req.Data = output + return +} + +// Adds or removes permission settings for the specified snapshot. You may add +// or remove specified AWS account IDs from a snapshot's list of create volume +// permissions, but you cannot do both in a single API call. If you need to +// both add and remove account IDs for a snapshot, you must use multiple API +// calls. +// +// Encrypted snapshots and snapshots with AWS Marketplace product codes cannot +// be made public. Snapshots encrypted with your default CMK cannot be shared +// with other accounts. +// +// For more information on modifying snapshot permissions, see Sharing Snapshots +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-modifying-snapshot-permissions.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) ModifySnapshotAttribute(input *ModifySnapshotAttributeInput) (*ModifySnapshotAttributeOutput, error) { + req, out := c.ModifySnapshotAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifySpotFleetRequest = "ModifySpotFleetRequest" + +// ModifySpotFleetRequestRequest generates a "aws/request.Request" representing the +// client's request for the ModifySpotFleetRequest operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifySpotFleetRequest method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifySpotFleetRequestRequest method. +// req, resp := client.ModifySpotFleetRequestRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifySpotFleetRequestRequest(input *ModifySpotFleetRequestInput) (req *request.Request, output *ModifySpotFleetRequestOutput) { + op := &request.Operation{ + Name: opModifySpotFleetRequest, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifySpotFleetRequestInput{} + } + + req = c.newRequest(op, input, output) + output = &ModifySpotFleetRequestOutput{} + req.Data = output + return +} + +// Modifies the specified Spot fleet request. +// +// While the Spot fleet request is being modified, it is in the modifying state. +// +// To scale up your Spot fleet, increase its target capacity. The Spot fleet +// launches the additional Spot instances according to the allocation strategy +// for the Spot fleet request. If the allocation strategy is lowestPrice, the +// Spot fleet launches instances using the Spot pool with the lowest price. +// If the allocation strategy is diversified, the Spot fleet distributes the +// instances across the Spot pools. +// +// To scale down your Spot fleet, decrease its target capacity. First, the +// Spot fleet cancels any open bids that exceed the new target capacity. You +// can request that the Spot fleet terminate Spot instances until the size of +// the fleet no longer exceeds the new target capacity. If the allocation strategy +// is lowestPrice, the Spot fleet terminates the instances with the highest +// price per unit. If the allocation strategy is diversified, the Spot fleet +// terminates instances across the Spot pools. Alternatively, you can request +// that the Spot fleet keep the fleet at its current size, but not replace any +// Spot instances that are interrupted or that you terminate manually. +func (c *EC2) ModifySpotFleetRequest(input *ModifySpotFleetRequestInput) (*ModifySpotFleetRequestOutput, error) { + req, out := c.ModifySpotFleetRequestRequest(input) + err := req.Send() + return out, err +} + +const opModifySubnetAttribute = "ModifySubnetAttribute" + +// ModifySubnetAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifySubnetAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifySubnetAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifySubnetAttributeRequest method. +// req, resp := client.ModifySubnetAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifySubnetAttributeRequest(input *ModifySubnetAttributeInput) (req *request.Request, output *ModifySubnetAttributeOutput) { + op := &request.Operation{ + Name: opModifySubnetAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifySubnetAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifySubnetAttributeOutput{} + req.Data = output + return +} + +// Modifies a subnet attribute. +func (c *EC2) ModifySubnetAttribute(input *ModifySubnetAttributeInput) (*ModifySubnetAttributeOutput, error) { + req, out := c.ModifySubnetAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifyVolumeAttribute = "ModifyVolumeAttribute" + +// ModifyVolumeAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVolumeAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyVolumeAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyVolumeAttributeRequest method. +// req, resp := client.ModifyVolumeAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyVolumeAttributeRequest(input *ModifyVolumeAttributeInput) (req *request.Request, output *ModifyVolumeAttributeOutput) { + op := &request.Operation{ + Name: opModifyVolumeAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVolumeAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyVolumeAttributeOutput{} + req.Data = output + return +} + +// Modifies a volume attribute. +// +// By default, all I/O operations for the volume are suspended when the data +// on the volume is determined to be potentially inconsistent, to prevent undetectable, +// latent data corruption. The I/O access to the volume can be resumed by first +// enabling I/O access and then checking the data consistency on your volume. +// +// You can change the default behavior to resume I/O operations. We recommend +// that you change this only for boot volumes or for volumes that are stateless +// or disposable. +func (c *EC2) ModifyVolumeAttribute(input *ModifyVolumeAttributeInput) (*ModifyVolumeAttributeOutput, error) { + req, out := c.ModifyVolumeAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifyVpcAttribute = "ModifyVpcAttribute" + +// ModifyVpcAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyVpcAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyVpcAttributeRequest method. +// req, resp := client.ModifyVpcAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyVpcAttributeRequest(input *ModifyVpcAttributeInput) (req *request.Request, output *ModifyVpcAttributeOutput) { + op := &request.Operation{ + Name: opModifyVpcAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ModifyVpcAttributeOutput{} + req.Data = output + return +} + +// Modifies the specified attribute of the specified VPC. +func (c *EC2) ModifyVpcAttribute(input *ModifyVpcAttributeInput) (*ModifyVpcAttributeOutput, error) { + req, out := c.ModifyVpcAttributeRequest(input) + err := req.Send() + return out, err +} + +const opModifyVpcEndpoint = "ModifyVpcEndpoint" + +// ModifyVpcEndpointRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcEndpoint operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyVpcEndpoint method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyVpcEndpointRequest method. +// req, resp := client.ModifyVpcEndpointRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyVpcEndpointRequest(input *ModifyVpcEndpointInput) (req *request.Request, output *ModifyVpcEndpointOutput) { + op := &request.Operation{ + Name: opModifyVpcEndpoint, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcEndpointInput{} + } + + req = c.newRequest(op, input, output) + output = &ModifyVpcEndpointOutput{} + req.Data = output + return +} + +// Modifies attributes of a specified VPC endpoint. You can modify the policy +// associated with the endpoint, and you can add and remove route tables associated +// with the endpoint. +func (c *EC2) ModifyVpcEndpoint(input *ModifyVpcEndpointInput) (*ModifyVpcEndpointOutput, error) { + req, out := c.ModifyVpcEndpointRequest(input) + err := req.Send() + return out, err +} + +const opModifyVpcPeeringConnectionOptions = "ModifyVpcPeeringConnectionOptions" + +// ModifyVpcPeeringConnectionOptionsRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcPeeringConnectionOptions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ModifyVpcPeeringConnectionOptions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ModifyVpcPeeringConnectionOptionsRequest method. +// req, resp := client.ModifyVpcPeeringConnectionOptionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ModifyVpcPeeringConnectionOptionsRequest(input *ModifyVpcPeeringConnectionOptionsInput) (req *request.Request, output *ModifyVpcPeeringConnectionOptionsOutput) { + op := &request.Operation{ + Name: opModifyVpcPeeringConnectionOptions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcPeeringConnectionOptionsInput{} + } + + req = c.newRequest(op, input, output) + output = &ModifyVpcPeeringConnectionOptionsOutput{} + req.Data = output + return +} + +// Modifies the VPC peering connection options on one side of a VPC peering +// connection. You can do the following: +// +// Enable/disable communication over the peering connection between an EC2-Classic +// instance that's linked to your VPC (using ClassicLink) and instances in the +// peer VPC. +// +// Enable/disable communication over the peering connection between instances +// in your VPC and an EC2-Classic instance that's linked to the peer VPC. +// +// Enable/disable a local VPC to resolve public DNS hostnames to private +// IP addresses when queried from instances in the peer VPC. +// +// If the peered VPCs are in different accounts, each owner must initiate +// a separate request to modify the peering connection options, depending on +// whether their VPC was the requester or accepter for the VPC peering connection. +// If the peered VPCs are in the same account, you can modify the requester +// and accepter options in the same request. To confirm which VPC is the accepter +// and requester for a VPC peering connection, use the DescribeVpcPeeringConnections +// command. +func (c *EC2) ModifyVpcPeeringConnectionOptions(input *ModifyVpcPeeringConnectionOptionsInput) (*ModifyVpcPeeringConnectionOptionsOutput, error) { + req, out := c.ModifyVpcPeeringConnectionOptionsRequest(input) + err := req.Send() + return out, err +} + +const opMonitorInstances = "MonitorInstances" + +// MonitorInstancesRequest generates a "aws/request.Request" representing the +// client's request for the MonitorInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the MonitorInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the MonitorInstancesRequest method. +// req, resp := client.MonitorInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) MonitorInstancesRequest(input *MonitorInstancesInput) (req *request.Request, output *MonitorInstancesOutput) { + op := &request.Operation{ + Name: opMonitorInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &MonitorInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &MonitorInstancesOutput{} + req.Data = output + return +} + +// Enables monitoring for a running instance. For more information about monitoring +// instances, see Monitoring Your Instances and Volumes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) MonitorInstances(input *MonitorInstancesInput) (*MonitorInstancesOutput, error) { + req, out := c.MonitorInstancesRequest(input) + err := req.Send() + return out, err +} + +const opMoveAddressToVpc = "MoveAddressToVpc" + +// MoveAddressToVpcRequest generates a "aws/request.Request" representing the +// client's request for the MoveAddressToVpc operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the MoveAddressToVpc method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the MoveAddressToVpcRequest method. +// req, resp := client.MoveAddressToVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) MoveAddressToVpcRequest(input *MoveAddressToVpcInput) (req *request.Request, output *MoveAddressToVpcOutput) { + op := &request.Operation{ + Name: opMoveAddressToVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &MoveAddressToVpcInput{} + } + + req = c.newRequest(op, input, output) + output = &MoveAddressToVpcOutput{} + req.Data = output + return +} + +// Moves an Elastic IP address from the EC2-Classic platform to the EC2-VPC +// platform. The Elastic IP address must be allocated to your account for more +// than 24 hours, and it must not be associated with an instance. After the +// Elastic IP address is moved, it is no longer available for use in the EC2-Classic +// platform, unless you move it back using the RestoreAddressToClassic request. +// You cannot move an Elastic IP address that was originally allocated for use +// in the EC2-VPC platform to the EC2-Classic platform. +func (c *EC2) MoveAddressToVpc(input *MoveAddressToVpcInput) (*MoveAddressToVpcOutput, error) { + req, out := c.MoveAddressToVpcRequest(input) + err := req.Send() + return out, err +} + +const opPurchaseHostReservation = "PurchaseHostReservation" + +// PurchaseHostReservationRequest generates a "aws/request.Request" representing the +// client's request for the PurchaseHostReservation operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PurchaseHostReservation method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PurchaseHostReservationRequest method. +// req, resp := client.PurchaseHostReservationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) PurchaseHostReservationRequest(input *PurchaseHostReservationInput) (req *request.Request, output *PurchaseHostReservationOutput) { + op := &request.Operation{ + Name: opPurchaseHostReservation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PurchaseHostReservationInput{} + } + + req = c.newRequest(op, input, output) + output = &PurchaseHostReservationOutput{} + req.Data = output + return +} + +// Purchase a reservation with configurations that match those of your Dedicated +// Host. You must have active Dedicated Hosts in your account before you purchase +// a reservation. This action results in the specified reservation being purchased +// and charged to your account. +func (c *EC2) PurchaseHostReservation(input *PurchaseHostReservationInput) (*PurchaseHostReservationOutput, error) { + req, out := c.PurchaseHostReservationRequest(input) + err := req.Send() + return out, err +} + +const opPurchaseReservedInstancesOffering = "PurchaseReservedInstancesOffering" + +// PurchaseReservedInstancesOfferingRequest generates a "aws/request.Request" representing the +// client's request for the PurchaseReservedInstancesOffering operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PurchaseReservedInstancesOffering method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PurchaseReservedInstancesOfferingRequest method. +// req, resp := client.PurchaseReservedInstancesOfferingRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedInstancesOfferingInput) (req *request.Request, output *PurchaseReservedInstancesOfferingOutput) { + op := &request.Operation{ + Name: opPurchaseReservedInstancesOffering, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PurchaseReservedInstancesOfferingInput{} + } + + req = c.newRequest(op, input, output) + output = &PurchaseReservedInstancesOfferingOutput{} + req.Data = output + return +} + +// Purchases a Reserved Instance for use with your account. With Reserved Instances, +// you obtain a capacity reservation for a certain instance configuration over +// a specified period of time and pay a lower hourly rate compared to On-Demand +// instance pricing. +// +// Use DescribeReservedInstancesOfferings to get a list of Reserved Instance +// offerings that match your specifications. After you've purchased a Reserved +// Instance, you can check for your new Reserved Instance with DescribeReservedInstances. +// +// For more information, see Reserved Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts-on-demand-reserved-instances.html) +// and Reserved Instance Marketplace (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) PurchaseReservedInstancesOffering(input *PurchaseReservedInstancesOfferingInput) (*PurchaseReservedInstancesOfferingOutput, error) { + req, out := c.PurchaseReservedInstancesOfferingRequest(input) + err := req.Send() + return out, err +} + +const opPurchaseScheduledInstances = "PurchaseScheduledInstances" + +// PurchaseScheduledInstancesRequest generates a "aws/request.Request" representing the +// client's request for the PurchaseScheduledInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PurchaseScheduledInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PurchaseScheduledInstancesRequest method. +// req, resp := client.PurchaseScheduledInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) PurchaseScheduledInstancesRequest(input *PurchaseScheduledInstancesInput) (req *request.Request, output *PurchaseScheduledInstancesOutput) { + op := &request.Operation{ + Name: opPurchaseScheduledInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PurchaseScheduledInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &PurchaseScheduledInstancesOutput{} + req.Data = output + return +} + +// Purchases one or more Scheduled Instances with the specified schedule. +// +// Scheduled Instances enable you to purchase Amazon EC2 compute capacity by +// the hour for a one-year term. Before you can purchase a Scheduled Instance, +// you must call DescribeScheduledInstanceAvailability to check for available +// schedules and obtain a purchase token. After you purchase a Scheduled Instance, +// you must call RunScheduledInstances during each scheduled time period. +// +// After you purchase a Scheduled Instance, you can't cancel, modify, or resell +// your purchase. +func (c *EC2) PurchaseScheduledInstances(input *PurchaseScheduledInstancesInput) (*PurchaseScheduledInstancesOutput, error) { + req, out := c.PurchaseScheduledInstancesRequest(input) + err := req.Send() + return out, err +} + +const opRebootInstances = "RebootInstances" + +// RebootInstancesRequest generates a "aws/request.Request" representing the +// client's request for the RebootInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RebootInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RebootInstancesRequest method. +// req, resp := client.RebootInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RebootInstancesRequest(input *RebootInstancesInput) (req *request.Request, output *RebootInstancesOutput) { + op := &request.Operation{ + Name: opRebootInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RebootInstancesInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &RebootInstancesOutput{} + req.Data = output + return +} + +// Requests a reboot of one or more instances. This operation is asynchronous; +// it only queues a request to reboot the specified instances. The operation +// succeeds if the instances are valid and belong to you. Requests to reboot +// terminated instances are ignored. +// +// If an instance does not cleanly shut down within four minutes, Amazon EC2 +// performs a hard reboot. +// +// For more information about troubleshooting, see Getting Console Output and +// Rebooting Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-console.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) RebootInstances(input *RebootInstancesInput) (*RebootInstancesOutput, error) { + req, out := c.RebootInstancesRequest(input) + err := req.Send() + return out, err +} + +const opRegisterImage = "RegisterImage" + +// RegisterImageRequest generates a "aws/request.Request" representing the +// client's request for the RegisterImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RegisterImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RegisterImageRequest method. +// req, resp := client.RegisterImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RegisterImageRequest(input *RegisterImageInput) (req *request.Request, output *RegisterImageOutput) { + op := &request.Operation{ + Name: opRegisterImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RegisterImageInput{} + } + + req = c.newRequest(op, input, output) + output = &RegisterImageOutput{} + req.Data = output + return +} + +// Registers an AMI. When you're creating an AMI, this is the final step you +// must complete before you can launch an instance from the AMI. For more information +// about creating AMIs, see Creating Your Own AMIs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// For Amazon EBS-backed instances, CreateImage creates and registers the +// AMI in a single request, so you don't have to register the AMI yourself. +// +// You can also use RegisterImage to create an Amazon EBS-backed Linux AMI +// from a snapshot of a root device volume. For more information, see Launching +// an Instance from a Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_LaunchingInstanceFromSnapshot.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Some Linux distributions, such as Red Hat Enterprise Linux (RHEL) and SUSE +// Linux Enterprise Server (SLES), use the EC2 billingProduct code associated +// with an AMI to verify subscription status for package updates. Creating an +// AMI from an EBS snapshot does not maintain this billing code, and subsequent +// instances launched from such an AMI will not be able to connect to package +// update infrastructure. +// +// Similarly, although you can create a Windows AMI from a snapshot, you can't +// successfully launch an instance from the AMI. +// +// To create Windows AMIs or to create AMIs for Linux operating systems that +// must retain AMI billing codes to work properly, see CreateImage. +// +// If needed, you can deregister an AMI at any time. Any modifications you +// make to an AMI backed by an instance store volume invalidates its registration. +// If you make changes to an image, deregister the previous image and register +// the new image. +// +// You can't register an image where a secondary (non-root) snapshot has AWS +// Marketplace product codes. +func (c *EC2) RegisterImage(input *RegisterImageInput) (*RegisterImageOutput, error) { + req, out := c.RegisterImageRequest(input) + err := req.Send() + return out, err +} + +const opRejectVpcPeeringConnection = "RejectVpcPeeringConnection" + +// RejectVpcPeeringConnectionRequest generates a "aws/request.Request" representing the +// client's request for the RejectVpcPeeringConnection operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RejectVpcPeeringConnection method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RejectVpcPeeringConnectionRequest method. +// req, resp := client.RejectVpcPeeringConnectionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RejectVpcPeeringConnectionRequest(input *RejectVpcPeeringConnectionInput) (req *request.Request, output *RejectVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opRejectVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RejectVpcPeeringConnectionInput{} + } + + req = c.newRequest(op, input, output) + output = &RejectVpcPeeringConnectionOutput{} + req.Data = output + return +} + +// Rejects a VPC peering connection request. The VPC peering connection must +// be in the pending-acceptance state. Use the DescribeVpcPeeringConnections +// request to view your outstanding VPC peering connection requests. To delete +// an active VPC peering connection, or to delete a VPC peering connection request +// that you initiated, use DeleteVpcPeeringConnection. +func (c *EC2) RejectVpcPeeringConnection(input *RejectVpcPeeringConnectionInput) (*RejectVpcPeeringConnectionOutput, error) { + req, out := c.RejectVpcPeeringConnectionRequest(input) + err := req.Send() + return out, err +} + +const opReleaseAddress = "ReleaseAddress" + +// ReleaseAddressRequest generates a "aws/request.Request" representing the +// client's request for the ReleaseAddress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReleaseAddress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReleaseAddressRequest method. +// req, resp := client.ReleaseAddressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReleaseAddressRequest(input *ReleaseAddressInput) (req *request.Request, output *ReleaseAddressOutput) { + op := &request.Operation{ + Name: opReleaseAddress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReleaseAddressInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ReleaseAddressOutput{} + req.Data = output + return +} + +// Releases the specified Elastic IP address. +// +// After releasing an Elastic IP address, it is released to the IP address +// pool and might be unavailable to you. Be sure to update your DNS records +// and any servers or devices that communicate with the address. If you attempt +// to release an Elastic IP address that you already released, you'll get an +// AuthFailure error if the address is already allocated to another AWS account. +// +// [EC2-Classic, default VPC] Releasing an Elastic IP address automatically +// disassociates it from any instance that it's associated with. To disassociate +// an Elastic IP address without releasing it, use DisassociateAddress. +// +// [Nondefault VPC] You must use DisassociateAddress to disassociate the Elastic +// IP address before you try to release it. Otherwise, Amazon EC2 returns an +// error (InvalidIPAddress.InUse). +func (c *EC2) ReleaseAddress(input *ReleaseAddressInput) (*ReleaseAddressOutput, error) { + req, out := c.ReleaseAddressRequest(input) + err := req.Send() + return out, err +} + +const opReleaseHosts = "ReleaseHosts" + +// ReleaseHostsRequest generates a "aws/request.Request" representing the +// client's request for the ReleaseHosts operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReleaseHosts method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReleaseHostsRequest method. +// req, resp := client.ReleaseHostsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReleaseHostsRequest(input *ReleaseHostsInput) (req *request.Request, output *ReleaseHostsOutput) { + op := &request.Operation{ + Name: opReleaseHosts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReleaseHostsInput{} + } + + req = c.newRequest(op, input, output) + output = &ReleaseHostsOutput{} + req.Data = output + return +} + +// When you no longer want to use an On-Demand Dedicated Host it can be released. +// On-Demand billing is stopped and the host goes into released state. The host +// ID of Dedicated Hosts that have been released can no longer be specified +// in another request, e.g., ModifyHosts. You must stop or terminate all instances +// on a host before it can be released. +// +// When Dedicated Hosts are released, it make take some time for them to stop +// counting toward your limit and you may receive capacity errors when trying +// to allocate new Dedicated hosts. Try waiting a few minutes, and then try +// again. +// +// Released hosts will still appear in a DescribeHosts response. +func (c *EC2) ReleaseHosts(input *ReleaseHostsInput) (*ReleaseHostsOutput, error) { + req, out := c.ReleaseHostsRequest(input) + err := req.Send() + return out, err +} + +const opReplaceNetworkAclAssociation = "ReplaceNetworkAclAssociation" + +// ReplaceNetworkAclAssociationRequest generates a "aws/request.Request" representing the +// client's request for the ReplaceNetworkAclAssociation operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReplaceNetworkAclAssociation method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReplaceNetworkAclAssociationRequest method. +// req, resp := client.ReplaceNetworkAclAssociationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReplaceNetworkAclAssociationRequest(input *ReplaceNetworkAclAssociationInput) (req *request.Request, output *ReplaceNetworkAclAssociationOutput) { + op := &request.Operation{ + Name: opReplaceNetworkAclAssociation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReplaceNetworkAclAssociationInput{} + } + + req = c.newRequest(op, input, output) + output = &ReplaceNetworkAclAssociationOutput{} + req.Data = output + return +} + +// Changes which network ACL a subnet is associated with. By default when you +// create a subnet, it's automatically associated with the default network ACL. +// For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) ReplaceNetworkAclAssociation(input *ReplaceNetworkAclAssociationInput) (*ReplaceNetworkAclAssociationOutput, error) { + req, out := c.ReplaceNetworkAclAssociationRequest(input) + err := req.Send() + return out, err +} + +const opReplaceNetworkAclEntry = "ReplaceNetworkAclEntry" + +// ReplaceNetworkAclEntryRequest generates a "aws/request.Request" representing the +// client's request for the ReplaceNetworkAclEntry operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReplaceNetworkAclEntry method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReplaceNetworkAclEntryRequest method. +// req, resp := client.ReplaceNetworkAclEntryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReplaceNetworkAclEntryRequest(input *ReplaceNetworkAclEntryInput) (req *request.Request, output *ReplaceNetworkAclEntryOutput) { + op := &request.Operation{ + Name: opReplaceNetworkAclEntry, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReplaceNetworkAclEntryInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ReplaceNetworkAclEntryOutput{} + req.Data = output + return +} + +// Replaces an entry (rule) in a network ACL. For more information about network +// ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) ReplaceNetworkAclEntry(input *ReplaceNetworkAclEntryInput) (*ReplaceNetworkAclEntryOutput, error) { + req, out := c.ReplaceNetworkAclEntryRequest(input) + err := req.Send() + return out, err +} + +const opReplaceRoute = "ReplaceRoute" + +// ReplaceRouteRequest generates a "aws/request.Request" representing the +// client's request for the ReplaceRoute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReplaceRoute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReplaceRouteRequest method. +// req, resp := client.ReplaceRouteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReplaceRouteRequest(input *ReplaceRouteInput) (req *request.Request, output *ReplaceRouteOutput) { + op := &request.Operation{ + Name: opReplaceRoute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReplaceRouteInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ReplaceRouteOutput{} + req.Data = output + return +} + +// Replaces an existing route within a route table in a VPC. You must provide +// only one of the following: Internet gateway or virtual private gateway, NAT +// instance, NAT gateway, VPC peering connection, or network interface. +// +// For more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) ReplaceRoute(input *ReplaceRouteInput) (*ReplaceRouteOutput, error) { + req, out := c.ReplaceRouteRequest(input) + err := req.Send() + return out, err +} + +const opReplaceRouteTableAssociation = "ReplaceRouteTableAssociation" + +// ReplaceRouteTableAssociationRequest generates a "aws/request.Request" representing the +// client's request for the ReplaceRouteTableAssociation operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReplaceRouteTableAssociation method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReplaceRouteTableAssociationRequest method. +// req, resp := client.ReplaceRouteTableAssociationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReplaceRouteTableAssociationRequest(input *ReplaceRouteTableAssociationInput) (req *request.Request, output *ReplaceRouteTableAssociationOutput) { + op := &request.Operation{ + Name: opReplaceRouteTableAssociation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReplaceRouteTableAssociationInput{} + } + + req = c.newRequest(op, input, output) + output = &ReplaceRouteTableAssociationOutput{} + req.Data = output + return +} + +// Changes the route table associated with a given subnet in a VPC. After the +// operation completes, the subnet uses the routes in the new route table it's +// associated with. For more information about route tables, see Route Tables +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// You can also use ReplaceRouteTableAssociation to change which table is the +// main route table in the VPC. You just specify the main route table's association +// ID and the route table to be the new main route table. +func (c *EC2) ReplaceRouteTableAssociation(input *ReplaceRouteTableAssociationInput) (*ReplaceRouteTableAssociationOutput, error) { + req, out := c.ReplaceRouteTableAssociationRequest(input) + err := req.Send() + return out, err +} + +const opReportInstanceStatus = "ReportInstanceStatus" + +// ReportInstanceStatusRequest generates a "aws/request.Request" representing the +// client's request for the ReportInstanceStatus operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ReportInstanceStatus method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ReportInstanceStatusRequest method. +// req, resp := client.ReportInstanceStatusRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ReportInstanceStatusRequest(input *ReportInstanceStatusInput) (req *request.Request, output *ReportInstanceStatusOutput) { + op := &request.Operation{ + Name: opReportInstanceStatus, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReportInstanceStatusInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ReportInstanceStatusOutput{} + req.Data = output + return +} + +// Submits feedback about the status of an instance. The instance must be in +// the running state. If your experience with the instance differs from the +// instance status returned by DescribeInstanceStatus, use ReportInstanceStatus +// to report your experience with the instance. Amazon EC2 collects this information +// to improve the accuracy of status checks. +// +// Use of this action does not change the value returned by DescribeInstanceStatus. +func (c *EC2) ReportInstanceStatus(input *ReportInstanceStatusInput) (*ReportInstanceStatusOutput, error) { + req, out := c.ReportInstanceStatusRequest(input) + err := req.Send() + return out, err +} + +const opRequestSpotFleet = "RequestSpotFleet" + +// RequestSpotFleetRequest generates a "aws/request.Request" representing the +// client's request for the RequestSpotFleet operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RequestSpotFleet method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RequestSpotFleetRequest method. +// req, resp := client.RequestSpotFleetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *request.Request, output *RequestSpotFleetOutput) { + op := &request.Operation{ + Name: opRequestSpotFleet, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RequestSpotFleetInput{} + } + + req = c.newRequest(op, input, output) + output = &RequestSpotFleetOutput{} + req.Data = output + return +} + +// Creates a Spot fleet request. +// +// You can submit a single request that includes multiple launch specifications +// that vary by instance type, AMI, Availability Zone, or subnet. +// +// By default, the Spot fleet requests Spot instances in the Spot pool where +// the price per unit is the lowest. Each launch specification can include its +// own instance weighting that reflects the value of the instance type to your +// application workload. +// +// Alternatively, you can specify that the Spot fleet distribute the target +// capacity across the Spot pools included in its launch specifications. By +// ensuring that the Spot instances in your Spot fleet are in different Spot +// pools, you can improve the availability of your fleet. +// +// For more information, see Spot Fleet Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet-requests.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) RequestSpotFleet(input *RequestSpotFleetInput) (*RequestSpotFleetOutput, error) { + req, out := c.RequestSpotFleetRequest(input) + err := req.Send() + return out, err +} + +const opRequestSpotInstances = "RequestSpotInstances" + +// RequestSpotInstancesRequest generates a "aws/request.Request" representing the +// client's request for the RequestSpotInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RequestSpotInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RequestSpotInstancesRequest method. +// req, resp := client.RequestSpotInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RequestSpotInstancesRequest(input *RequestSpotInstancesInput) (req *request.Request, output *RequestSpotInstancesOutput) { + op := &request.Operation{ + Name: opRequestSpotInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RequestSpotInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &RequestSpotInstancesOutput{} + req.Data = output + return +} + +// Creates a Spot instance request. Spot instances are instances that Amazon +// EC2 launches when the bid price that you specify exceeds the current Spot +// price. Amazon EC2 periodically sets the Spot price based on available Spot +// Instance capacity and current Spot instance requests. For more information, +// see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) RequestSpotInstances(input *RequestSpotInstancesInput) (*RequestSpotInstancesOutput, error) { + req, out := c.RequestSpotInstancesRequest(input) + err := req.Send() + return out, err +} + +const opResetImageAttribute = "ResetImageAttribute" + +// ResetImageAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ResetImageAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ResetImageAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ResetImageAttributeRequest method. +// req, resp := client.ResetImageAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ResetImageAttributeRequest(input *ResetImageAttributeInput) (req *request.Request, output *ResetImageAttributeOutput) { + op := &request.Operation{ + Name: opResetImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ResetImageAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ResetImageAttributeOutput{} + req.Data = output + return +} + +// Resets an attribute of an AMI to its default value. +// +// The productCodes attribute can't be reset. +func (c *EC2) ResetImageAttribute(input *ResetImageAttributeInput) (*ResetImageAttributeOutput, error) { + req, out := c.ResetImageAttributeRequest(input) + err := req.Send() + return out, err +} + +const opResetInstanceAttribute = "ResetInstanceAttribute" + +// ResetInstanceAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ResetInstanceAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ResetInstanceAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ResetInstanceAttributeRequest method. +// req, resp := client.ResetInstanceAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ResetInstanceAttributeRequest(input *ResetInstanceAttributeInput) (req *request.Request, output *ResetInstanceAttributeOutput) { + op := &request.Operation{ + Name: opResetInstanceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ResetInstanceAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ResetInstanceAttributeOutput{} + req.Data = output + return +} + +// Resets an attribute of an instance to its default value. To reset the kernel +// or ramdisk, the instance must be in a stopped state. To reset the sourceDestCheck, +// the instance can be either running or stopped. +// +// The sourceDestCheck attribute controls whether source/destination checking +// is enabled. The default value is true, which means checking is enabled. This +// value must be false for a NAT instance to perform NAT. For more information, +// see NAT Instances (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) ResetInstanceAttribute(input *ResetInstanceAttributeInput) (*ResetInstanceAttributeOutput, error) { + req, out := c.ResetInstanceAttributeRequest(input) + err := req.Send() + return out, err +} + +const opResetNetworkInterfaceAttribute = "ResetNetworkInterfaceAttribute" + +// ResetNetworkInterfaceAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ResetNetworkInterfaceAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ResetNetworkInterfaceAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ResetNetworkInterfaceAttributeRequest method. +// req, resp := client.ResetNetworkInterfaceAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ResetNetworkInterfaceAttributeRequest(input *ResetNetworkInterfaceAttributeInput) (req *request.Request, output *ResetNetworkInterfaceAttributeOutput) { + op := &request.Operation{ + Name: opResetNetworkInterfaceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ResetNetworkInterfaceAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ResetNetworkInterfaceAttributeOutput{} + req.Data = output + return +} + +// Resets a network interface attribute. You can specify only one attribute +// at a time. +func (c *EC2) ResetNetworkInterfaceAttribute(input *ResetNetworkInterfaceAttributeInput) (*ResetNetworkInterfaceAttributeOutput, error) { + req, out := c.ResetNetworkInterfaceAttributeRequest(input) + err := req.Send() + return out, err +} + +const opResetSnapshotAttribute = "ResetSnapshotAttribute" + +// ResetSnapshotAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ResetSnapshotAttribute operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ResetSnapshotAttribute method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ResetSnapshotAttributeRequest method. +// req, resp := client.ResetSnapshotAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) ResetSnapshotAttributeRequest(input *ResetSnapshotAttributeInput) (req *request.Request, output *ResetSnapshotAttributeOutput) { + op := &request.Operation{ + Name: opResetSnapshotAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ResetSnapshotAttributeInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &ResetSnapshotAttributeOutput{} + req.Data = output + return +} + +// Resets permission settings for the specified snapshot. +// +// For more information on modifying snapshot permissions, see Sharing Snapshots +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-modifying-snapshot-permissions.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) ResetSnapshotAttribute(input *ResetSnapshotAttributeInput) (*ResetSnapshotAttributeOutput, error) { + req, out := c.ResetSnapshotAttributeRequest(input) + err := req.Send() + return out, err +} + +const opRestoreAddressToClassic = "RestoreAddressToClassic" + +// RestoreAddressToClassicRequest generates a "aws/request.Request" representing the +// client's request for the RestoreAddressToClassic operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RestoreAddressToClassic method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RestoreAddressToClassicRequest method. +// req, resp := client.RestoreAddressToClassicRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RestoreAddressToClassicRequest(input *RestoreAddressToClassicInput) (req *request.Request, output *RestoreAddressToClassicOutput) { + op := &request.Operation{ + Name: opRestoreAddressToClassic, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RestoreAddressToClassicInput{} + } + + req = c.newRequest(op, input, output) + output = &RestoreAddressToClassicOutput{} + req.Data = output + return +} + +// Restores an Elastic IP address that was previously moved to the EC2-VPC platform +// back to the EC2-Classic platform. You cannot move an Elastic IP address that +// was originally allocated for use in EC2-VPC. The Elastic IP address must +// not be associated with an instance or network interface. +func (c *EC2) RestoreAddressToClassic(input *RestoreAddressToClassicInput) (*RestoreAddressToClassicOutput, error) { + req, out := c.RestoreAddressToClassicRequest(input) + err := req.Send() + return out, err +} + +const opRevokeSecurityGroupEgress = "RevokeSecurityGroupEgress" + +// RevokeSecurityGroupEgressRequest generates a "aws/request.Request" representing the +// client's request for the RevokeSecurityGroupEgress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RevokeSecurityGroupEgress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RevokeSecurityGroupEgressRequest method. +// req, resp := client.RevokeSecurityGroupEgressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RevokeSecurityGroupEgressRequest(input *RevokeSecurityGroupEgressInput) (req *request.Request, output *RevokeSecurityGroupEgressOutput) { + op := &request.Operation{ + Name: opRevokeSecurityGroupEgress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RevokeSecurityGroupEgressInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &RevokeSecurityGroupEgressOutput{} + req.Data = output + return +} + +// [EC2-VPC only] Removes one or more egress rules from a security group for +// EC2-VPC. This action doesn't apply to security groups for use in EC2-Classic. +// The values that you specify in the revoke request (for example, ports) must +// match the existing rule's values for the rule to be revoked. +// +// Each rule consists of the protocol and the CIDR range or source security +// group. For the TCP and UDP protocols, you must also specify the destination +// port or range of ports. For the ICMP protocol, you must also specify the +// ICMP type and code. +// +// Rule changes are propagated to instances within the security group as quickly +// as possible. However, a small delay might occur. +func (c *EC2) RevokeSecurityGroupEgress(input *RevokeSecurityGroupEgressInput) (*RevokeSecurityGroupEgressOutput, error) { + req, out := c.RevokeSecurityGroupEgressRequest(input) + err := req.Send() + return out, err +} + +const opRevokeSecurityGroupIngress = "RevokeSecurityGroupIngress" + +// RevokeSecurityGroupIngressRequest generates a "aws/request.Request" representing the +// client's request for the RevokeSecurityGroupIngress operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RevokeSecurityGroupIngress method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RevokeSecurityGroupIngressRequest method. +// req, resp := client.RevokeSecurityGroupIngressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RevokeSecurityGroupIngressRequest(input *RevokeSecurityGroupIngressInput) (req *request.Request, output *RevokeSecurityGroupIngressOutput) { + op := &request.Operation{ + Name: opRevokeSecurityGroupIngress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RevokeSecurityGroupIngressInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &RevokeSecurityGroupIngressOutput{} + req.Data = output + return +} + +// Removes one or more ingress rules from a security group. The values that +// you specify in the revoke request (for example, ports) must match the existing +// rule's values for the rule to be removed. +// +// Each rule consists of the protocol and the CIDR range or source security +// group. For the TCP and UDP protocols, you must also specify the destination +// port or range of ports. For the ICMP protocol, you must also specify the +// ICMP type and code. +// +// Rule changes are propagated to instances within the security group as quickly +// as possible. However, a small delay might occur. +func (c *EC2) RevokeSecurityGroupIngress(input *RevokeSecurityGroupIngressInput) (*RevokeSecurityGroupIngressOutput, error) { + req, out := c.RevokeSecurityGroupIngressRequest(input) + err := req.Send() + return out, err +} + +const opRunInstances = "RunInstances" + +// RunInstancesRequest generates a "aws/request.Request" representing the +// client's request for the RunInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RunInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RunInstancesRequest method. +// req, resp := client.RunInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *request.Request, output *Reservation) { + op := &request.Operation{ + Name: opRunInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RunInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &Reservation{} + req.Data = output + return +} + +// Launches the specified number of instances using an AMI for which you have +// permissions. +// +// When you launch an instance, it enters the pending state. After the instance +// is ready for you, it enters the running state. To check the state of your +// instance, call DescribeInstances. +// +// To ensure faster instance launches, break up large requests into smaller +// batches. For example, create five separate launch requests for 100 instances +// each instead of one launch request for 500 instances. +// +// To tag your instance, ensure that it is running as CreateTags requires a +// resource ID. For more information about tagging, see Tagging Your Amazon +// EC2 Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html). +// +// If you don't specify a security group when launching an instance, Amazon +// EC2 uses the default security group. For more information, see Security Groups +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// [EC2-VPC only accounts] If you don't specify a subnet in the request, we +// choose a default subnet from your default VPC for you. +// +// [EC2-Classic accounts] If you're launching into EC2-Classic and you don't +// specify an Availability Zone, we choose one for you. +// +// Linux instances have access to the public key of the key pair at boot. You +// can use this key to provide secure access to the instance. Amazon EC2 public +// images use this feature to provide secure access without passwords. For more +// information, see Key Pairs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// You can provide optional user data when launching an instance. For more +// information, see Instance Metadata (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// If any of the AMIs have a product code attached for which the user has not +// subscribed, RunInstances fails. +// +// Some instance types can only be launched into a VPC. If you do not have +// a default VPC, or if you do not specify a subnet ID in the request, RunInstances +// fails. For more information, see Instance Types Available Only in a VPC (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-vpc.html#vpc-only-instance-types). +// +// For more information about troubleshooting, see What To Do If An Instance +// Immediately Terminates (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_InstanceStraightToTerminated.html), +// and Troubleshooting Connecting to Your Instance (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) RunInstances(input *RunInstancesInput) (*Reservation, error) { + req, out := c.RunInstancesRequest(input) + err := req.Send() + return out, err +} + +const opRunScheduledInstances = "RunScheduledInstances" + +// RunScheduledInstancesRequest generates a "aws/request.Request" representing the +// client's request for the RunScheduledInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the RunScheduledInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the RunScheduledInstancesRequest method. +// req, resp := client.RunScheduledInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) RunScheduledInstancesRequest(input *RunScheduledInstancesInput) (req *request.Request, output *RunScheduledInstancesOutput) { + op := &request.Operation{ + Name: opRunScheduledInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RunScheduledInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &RunScheduledInstancesOutput{} + req.Data = output + return +} + +// Launches the specified Scheduled Instances. +// +// Before you can launch a Scheduled Instance, you must purchase it and obtain +// an identifier using PurchaseScheduledInstances. +// +// You must launch a Scheduled Instance during its scheduled time period. You +// can't stop or reboot a Scheduled Instance, but you can terminate it as needed. +// If you terminate a Scheduled Instance before the current scheduled time period +// ends, you can launch it again after a few minutes. For more information, +// see Scheduled Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-scheduled-instances.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) RunScheduledInstances(input *RunScheduledInstancesInput) (*RunScheduledInstancesOutput, error) { + req, out := c.RunScheduledInstancesRequest(input) + err := req.Send() + return out, err +} + +const opStartInstances = "StartInstances" + +// StartInstancesRequest generates a "aws/request.Request" representing the +// client's request for the StartInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the StartInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the StartInstancesRequest method. +// req, resp := client.StartInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) StartInstancesRequest(input *StartInstancesInput) (req *request.Request, output *StartInstancesOutput) { + op := &request.Operation{ + Name: opStartInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StartInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &StartInstancesOutput{} + req.Data = output + return +} + +// Starts an Amazon EBS-backed AMI that you've previously stopped. +// +// Instances that use Amazon EBS volumes as their root devices can be quickly +// stopped and started. When an instance is stopped, the compute resources are +// released and you are not billed for hourly instance usage. However, your +// root partition Amazon EBS volume remains, continues to persist your data, +// and you are charged for Amazon EBS volume usage. You can restart your instance +// at any time. Each time you transition an instance from stopped to started, +// Amazon EC2 charges a full instance hour, even if transitions happen multiple +// times within a single hour. +// +// Before stopping an instance, make sure it is in a state from which it can +// be restarted. Stopping an instance does not preserve data stored in RAM. +// +// Performing this operation on an instance that uses an instance store as +// its root device returns an error. +// +// For more information, see Stopping Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Stop_Start.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) StartInstances(input *StartInstancesInput) (*StartInstancesOutput, error) { + req, out := c.StartInstancesRequest(input) + err := req.Send() + return out, err +} + +const opStopInstances = "StopInstances" + +// StopInstancesRequest generates a "aws/request.Request" representing the +// client's request for the StopInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the StopInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the StopInstancesRequest method. +// req, resp := client.StopInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) StopInstancesRequest(input *StopInstancesInput) (req *request.Request, output *StopInstancesOutput) { + op := &request.Operation{ + Name: opStopInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StopInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &StopInstancesOutput{} + req.Data = output + return +} + +// Stops an Amazon EBS-backed instance. +// +// We don't charge hourly usage for a stopped instance, or data transfer fees; +// however, your root partition Amazon EBS volume remains, continues to persist +// your data, and you are charged for Amazon EBS volume usage. Each time you +// transition an instance from stopped to started, Amazon EC2 charges a full +// instance hour, even if transitions happen multiple times within a single +// hour. +// +// You can't start or stop Spot instances, and you can't stop instance store-backed +// instances. +// +// When you stop an instance, we shut it down. You can restart your instance +// at any time. Before stopping an instance, make sure it is in a state from +// which it can be restarted. Stopping an instance does not preserve data stored +// in RAM. +// +// Stopping an instance is different to rebooting or terminating it. For example, +// when you stop an instance, the root device and any other devices attached +// to the instance persist. When you terminate an instance, the root device +// and any other devices attached during the instance launch are automatically +// deleted. For more information about the differences between rebooting, stopping, +// and terminating instances, see Instance Lifecycle (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// When you stop an instance, we attempt to shut it down forcibly after a short +// while. If your instance appears stuck in the stopping state after a period +// of time, there may be an issue with the underlying host computer. For more +// information, see Troubleshooting Stopping Your Instance (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstancesStopping.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) StopInstances(input *StopInstancesInput) (*StopInstancesOutput, error) { + req, out := c.StopInstancesRequest(input) + err := req.Send() + return out, err +} + +const opTerminateInstances = "TerminateInstances" + +// TerminateInstancesRequest generates a "aws/request.Request" representing the +// client's request for the TerminateInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the TerminateInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the TerminateInstancesRequest method. +// req, resp := client.TerminateInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *request.Request, output *TerminateInstancesOutput) { + op := &request.Operation{ + Name: opTerminateInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TerminateInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &TerminateInstancesOutput{} + req.Data = output + return +} + +// Shuts down one or more instances. This operation is idempotent; if you terminate +// an instance more than once, each call succeeds. +// +// Terminated instances remain visible after termination (for approximately +// one hour). +// +// By default, Amazon EC2 deletes all EBS volumes that were attached when the +// instance launched. Volumes attached after instance launch continue running. +// +// You can stop, start, and terminate EBS-backed instances. You can only terminate +// instance store-backed instances. What happens to an instance differs if you +// stop it or terminate it. For example, when you stop an instance, the root +// device and any other devices attached to the instance persist. When you terminate +// an instance, any attached EBS volumes with the DeleteOnTermination block +// device mapping parameter set to true are automatically deleted. For more +// information about the differences between stopping and terminating instances, +// see Instance Lifecycle (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// For more information about troubleshooting, see Troubleshooting Terminating +// Your Instance (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstancesShuttingDown.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) TerminateInstances(input *TerminateInstancesInput) (*TerminateInstancesOutput, error) { + req, out := c.TerminateInstancesRequest(input) + err := req.Send() + return out, err +} + +const opUnassignPrivateIpAddresses = "UnassignPrivateIpAddresses" + +// UnassignPrivateIpAddressesRequest generates a "aws/request.Request" representing the +// client's request for the UnassignPrivateIpAddresses operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the UnassignPrivateIpAddresses method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the UnassignPrivateIpAddressesRequest method. +// req, resp := client.UnassignPrivateIpAddressesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) UnassignPrivateIpAddressesRequest(input *UnassignPrivateIpAddressesInput) (req *request.Request, output *UnassignPrivateIpAddressesOutput) { + op := &request.Operation{ + Name: opUnassignPrivateIpAddresses, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UnassignPrivateIpAddressesInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &UnassignPrivateIpAddressesOutput{} + req.Data = output + return +} + +// Unassigns one or more secondary private IP addresses from a network interface. +func (c *EC2) UnassignPrivateIpAddresses(input *UnassignPrivateIpAddressesInput) (*UnassignPrivateIpAddressesOutput, error) { + req, out := c.UnassignPrivateIpAddressesRequest(input) + err := req.Send() + return out, err +} + +const opUnmonitorInstances = "UnmonitorInstances" + +// UnmonitorInstancesRequest generates a "aws/request.Request" representing the +// client's request for the UnmonitorInstances operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the UnmonitorInstances method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the UnmonitorInstancesRequest method. +// req, resp := client.UnmonitorInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) UnmonitorInstancesRequest(input *UnmonitorInstancesInput) (req *request.Request, output *UnmonitorInstancesOutput) { + op := &request.Operation{ + Name: opUnmonitorInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UnmonitorInstancesInput{} + } + + req = c.newRequest(op, input, output) + output = &UnmonitorInstancesOutput{} + req.Data = output + return +} + +// Disables monitoring for a running instance. For more information about monitoring +// instances, see Monitoring Your Instances and Volumes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) UnmonitorInstances(input *UnmonitorInstancesInput) (*UnmonitorInstancesOutput, error) { + req, out := c.UnmonitorInstancesRequest(input) + err := req.Send() + return out, err +} + +// Contains the parameters for AcceptVpcPeeringConnection. +type AcceptVpcPeeringConnectionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s AcceptVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AcceptVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +// Contains the output of AcceptVpcPeeringConnection. +type AcceptVpcPeeringConnectionOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPC peering connection. + VpcPeeringConnection *VpcPeeringConnection `locationName:"vpcPeeringConnection" type:"structure"` +} + +// String returns the string representation +func (s AcceptVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AcceptVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + +// Describes an account attribute. +type AccountAttribute struct { + _ struct{} `type:"structure"` + + // The name of the account attribute. + AttributeName *string `locationName:"attributeName" type:"string"` + + // One or more values for the account attribute. + AttributeValues []*AccountAttributeValue `locationName:"attributeValueSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s AccountAttribute) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccountAttribute) GoString() string { + return s.String() +} + +// Describes a value of an account attribute. +type AccountAttributeValue struct { + _ struct{} `type:"structure"` + + // The value of the attribute. + AttributeValue *string `locationName:"attributeValue" type:"string"` +} + +// String returns the string representation +func (s AccountAttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccountAttributeValue) GoString() string { + return s.String() +} + +// Describes a running instance in a Spot fleet. +type ActiveInstance struct { + _ struct{} `type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string"` + + // The ID of the Spot instance request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` +} + +// String returns the string representation +func (s ActiveInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ActiveInstance) GoString() string { + return s.String() +} + +// Describes an Elastic IP address. +type Address struct { + _ struct{} `type:"structure"` + + // The ID representing the allocation of the address for use with EC2-VPC. + AllocationId *string `locationName:"allocationId" type:"string"` + + // The ID representing the association of the address with an instance in a + // VPC. + AssociationId *string `locationName:"associationId" type:"string"` + + // Indicates whether this Elastic IP address is for use with instances in EC2-Classic + // (standard) or instances in a VPC (vpc). + Domain *string `locationName:"domain" type:"string" enum:"DomainType"` + + // The ID of the instance that the address is associated with (if any). + InstanceId *string `locationName:"instanceId" type:"string"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The ID of the AWS account that owns the network interface. + NetworkInterfaceOwnerId *string `locationName:"networkInterfaceOwnerId" type:"string"` + + // The private IP address associated with the Elastic IP address. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The Elastic IP address. + PublicIp *string `locationName:"publicIp" type:"string"` +} + +// String returns the string representation +func (s Address) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Address) GoString() string { + return s.String() +} + +// Contains the parameters for AllocateAddress. +type AllocateAddressInput struct { + _ struct{} `type:"structure"` + + // Set to vpc to allocate the address for use with instances in a VPC. + // + // Default: The address is for use with instances in EC2-Classic. + Domain *string `type:"string" enum:"DomainType"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s AllocateAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateAddressInput) GoString() string { + return s.String() +} + +// Contains the output of AllocateAddress. +type AllocateAddressOutput struct { + _ struct{} `type:"structure"` + + // [EC2-VPC] The ID that AWS assigns to represent the allocation of the Elastic + // IP address for use with instances in a VPC. + AllocationId *string `locationName:"allocationId" type:"string"` + + // Indicates whether this Elastic IP address is for use with instances in EC2-Classic + // (standard) or instances in a VPC (vpc). + Domain *string `locationName:"domain" type:"string" enum:"DomainType"` + + // The Elastic IP address. + PublicIp *string `locationName:"publicIp" type:"string"` +} + +// String returns the string representation +func (s AllocateAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateAddressOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AllocateHosts. +type AllocateHostsInput struct { + _ struct{} `type:"structure"` + + // This is enabled by default. This property allows instances to be automatically + // placed onto available Dedicated Hosts, when you are launching instances without + // specifying a host ID. + // + // Default: Enabled + AutoPlacement *string `locationName:"autoPlacement" type:"string" enum:"AutoPlacement"` + + // The Availability Zone for the Dedicated Hosts. + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Specify the instance type that you want your Dedicated Hosts to be configured + // for. When you specify the instance type, that is the only instance type that + // you can launch onto that host. + InstanceType *string `locationName:"instanceType" type:"string" required:"true"` + + // The number of Dedicated Hosts you want to allocate to your account with these + // parameters. + Quantity *int64 `locationName:"quantity" type:"integer" required:"true"` +} + +// String returns the string representation +func (s AllocateHostsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateHostsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AllocateHostsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AllocateHostsInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.InstanceType == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceType")) + } + if s.Quantity == nil { + invalidParams.Add(request.NewErrParamRequired("Quantity")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of AllocateHosts. +type AllocateHostsOutput struct { + _ struct{} `type:"structure"` + + // The ID of the allocated Dedicated Host. This is used when you want to launch + // an instance onto a specific host. + HostIds []*string `locationName:"hostIdSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s AllocateHostsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateHostsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AssignPrivateIpAddresses. +type AssignPrivateIpAddressesInput struct { + _ struct{} `type:"structure"` + + // Indicates whether to allow an IP address that is already assigned to another + // network interface or instance to be reassigned to the specified network interface. + AllowReassignment *bool `locationName:"allowReassignment" type:"boolean"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` + + // One or more IP addresses to be assigned as a secondary private IP address + // to the network interface. You can't specify this parameter when also specifying + // a number of secondary IP addresses. + // + // If you don't specify an IP address, Amazon EC2 automatically selects an + // IP address within the subnet range. + PrivateIpAddresses []*string `locationName:"privateIpAddress" locationNameList:"PrivateIpAddress" type:"list"` + + // The number of secondary IP addresses to assign to the network interface. + // You can't specify this parameter when also specifying private IP addresses. + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` +} + +// String returns the string representation +func (s AssignPrivateIpAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssignPrivateIpAddressesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssignPrivateIpAddressesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssignPrivateIpAddressesInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type AssignPrivateIpAddressesOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s AssignPrivateIpAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssignPrivateIpAddressesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AssociateAddress. +type AssociateAddressInput struct { + _ struct{} `type:"structure"` + + // [EC2-VPC] The allocation ID. This is required for EC2-VPC. + AllocationId *string `type:"string"` + + // [EC2-VPC] For a VPC in an EC2-Classic account, specify true to allow an Elastic + // IP address that is already associated with an instance or network interface + // to be reassociated with the specified instance or network interface. Otherwise, + // the operation fails. In a VPC in an EC2-VPC-only account, reassociation is + // automatic, therefore you can specify false to ensure the operation fails + // if the Elastic IP address is already associated with another resource. + AllowReassociation *bool `locationName:"allowReassociation" type:"boolean"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. This is required for EC2-Classic. For EC2-VPC, you + // can specify either the instance ID or the network interface ID, but not both. + // The operation fails if you specify an instance ID unless exactly one network + // interface is attached. + InstanceId *string `type:"string"` + + // [EC2-VPC] The ID of the network interface. If the instance has more than + // one network interface, you must specify a network interface ID. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // [EC2-VPC] The primary or secondary private IP address to associate with the + // Elastic IP address. If no private IP address is specified, the Elastic IP + // address is associated with the primary private IP address. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The Elastic IP address. This is required for EC2-Classic. + PublicIp *string `type:"string"` +} + +// String returns the string representation +func (s AssociateAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateAddressInput) GoString() string { + return s.String() +} + +// Contains the output of AssociateAddress. +type AssociateAddressOutput struct { + _ struct{} `type:"structure"` + + // [EC2-VPC] The ID that represents the association of the Elastic IP address + // with an instance. + AssociationId *string `locationName:"associationId" type:"string"` +} + +// String returns the string representation +func (s AssociateAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateAddressOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AssociateDhcpOptions. +type AssociateDhcpOptionsInput struct { + _ struct{} `type:"structure"` + + // The ID of the DHCP options set, or default to associate no DHCP options with + // the VPC. + DhcpOptionsId *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s AssociateDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateDhcpOptionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssociateDhcpOptionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssociateDhcpOptionsInput"} + if s.DhcpOptionsId == nil { + invalidParams.Add(request.NewErrParamRequired("DhcpOptionsId")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type AssociateDhcpOptionsOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s AssociateDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateDhcpOptionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AssociateRouteTable. +type AssociateRouteTableInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the route table. + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` + + // The ID of the subnet. + SubnetId *string `locationName:"subnetId" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssociateRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateRouteTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssociateRouteTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssociateRouteTableInput"} + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + if s.SubnetId == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of AssociateRouteTable. +type AssociateRouteTableOutput struct { + _ struct{} `type:"structure"` + + // The route table association ID (needed to disassociate the route table). + AssociationId *string `locationName:"associationId" type:"string"` +} + +// String returns the string representation +func (s AssociateRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateRouteTableOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AttachClassicLinkVpc. +type AttachClassicLinkVpcInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of one or more of the VPC's security groups. You cannot specify security + // groups from a different VPC. + Groups []*string `locationName:"SecurityGroupId" locationNameList:"groupId" type:"list" required:"true"` + + // The ID of an EC2-Classic instance to link to the ClassicLink-enabled VPC. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // The ID of a ClassicLink-enabled VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachClassicLinkVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachClassicLinkVpcInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachClassicLinkVpcInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachClassicLinkVpcInput"} + if s.Groups == nil { + invalidParams.Add(request.NewErrParamRequired("Groups")) + } + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of AttachClassicLinkVpc. +type AttachClassicLinkVpcOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s AttachClassicLinkVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachClassicLinkVpcOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AttachInternetGateway. +type AttachInternetGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the Internet gateway. + InternetGatewayId *string `locationName:"internetGatewayId" type:"string" required:"true"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInternetGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachInternetGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachInternetGatewayInput"} + if s.InternetGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("InternetGatewayId")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type AttachInternetGatewayOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s AttachInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInternetGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AttachNetworkInterface. +type AttachNetworkInterfaceInput struct { + _ struct{} `type:"structure"` + + // The index of the device for the network interface attachment. + DeviceIndex *int64 `locationName:"deviceIndex" type:"integer" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachNetworkInterfaceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachNetworkInterfaceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachNetworkInterfaceInput"} + if s.DeviceIndex == nil { + invalidParams.Add(request.NewErrParamRequired("DeviceIndex")) + } + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of AttachNetworkInterface. +type AttachNetworkInterfaceOutput struct { + _ struct{} `type:"structure"` + + // The ID of the network interface attachment. + AttachmentId *string `locationName:"attachmentId" type:"string"` +} + +// String returns the string representation +func (s AttachNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachNetworkInterfaceOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AttachVolume. +type AttachVolumeInput struct { + _ struct{} `type:"structure"` + + // The device name to expose to the instance (for example, /dev/sdh or xvdh). + Device *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `type:"string" required:"true"` + + // The ID of the EBS volume. The volume and instance must be within the same + // Availability Zone. + VolumeId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachVolumeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachVolumeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachVolumeInput"} + if s.Device == nil { + invalidParams.Add(request.NewErrParamRequired("Device")) + } + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the parameters for AttachVpnGateway. +type AttachVpnGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` + + // The ID of the virtual private gateway. + VpnGatewayId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachVpnGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachVpnGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachVpnGatewayInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + if s.VpnGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of AttachVpnGateway. +type AttachVpnGatewayOutput struct { + _ struct{} `type:"structure"` + + // Information about the attachment. + VpcAttachment *VpcAttachment `locationName:"attachment" type:"structure"` +} + +// String returns the string representation +func (s AttachVpnGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachVpnGatewayOutput) GoString() string { + return s.String() +} + +// Describes a value for a resource attribute that is a Boolean value. +type AttributeBooleanValue struct { + _ struct{} `type:"structure"` + + // The attribute value. The valid values are true or false. + Value *bool `locationName:"value" type:"boolean"` +} + +// String returns the string representation +func (s AttributeBooleanValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttributeBooleanValue) GoString() string { + return s.String() +} + +// Describes a value for a resource attribute that is a String. +type AttributeValue struct { + _ struct{} `type:"structure"` + + // The attribute value. Note that the value is case-sensitive. + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s AttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttributeValue) GoString() string { + return s.String() +} + +// Contains the parameters for AuthorizeSecurityGroupEgress. +type AuthorizeSecurityGroupEgressInput struct { + _ struct{} `type:"structure"` + + // The CIDR IP address range. We recommend that you specify the CIDR range in + // a set of IP permissions instead. + CidrIp *string `locationName:"cidrIp" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The start of port range for the TCP and UDP protocols, or an ICMP type number. + // We recommend that you specify the port range in a set of IP permissions instead. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string" required:"true"` + + // A set of IP permissions. You can't specify a destination security group and + // a CIDR IP address range. + IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` + + // The IP protocol name or number. We recommend that you specify the protocol + // in a set of IP permissions instead. + IpProtocol *string `locationName:"ipProtocol" type:"string"` + + // The name of a destination security group. To authorize outbound access to + // a destination security group, we recommend that you use a set of IP permissions + // instead. + SourceSecurityGroupName *string `locationName:"sourceSecurityGroupName" type:"string"` + + // The AWS account number for a destination security group. To authorize outbound + // access to a destination security group, we recommend that you use a set of + // IP permissions instead. + SourceSecurityGroupOwnerId *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` + + // The end of port range for the TCP and UDP protocols, or an ICMP type number. + // We recommend that you specify the port range in a set of IP permissions instead. + ToPort *int64 `locationName:"toPort" type:"integer"` +} + +// String returns the string representation +func (s AuthorizeSecurityGroupEgressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupEgressInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AuthorizeSecurityGroupEgressInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AuthorizeSecurityGroupEgressInput"} + if s.GroupId == nil { + invalidParams.Add(request.NewErrParamRequired("GroupId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type AuthorizeSecurityGroupEgressOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s AuthorizeSecurityGroupEgressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupEgressOutput) GoString() string { + return s.String() +} + +// Contains the parameters for AuthorizeSecurityGroupIngress. +type AuthorizeSecurityGroupIngressInput struct { + _ struct{} `type:"structure"` + + // The CIDR IP address range. You can't specify this parameter when specifying + // a source security group. + CidrIp *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The start of port range for the TCP and UDP protocols, or an ICMP type number. + // For the ICMP type number, use -1 to specify all ICMP types. + FromPort *int64 `type:"integer"` + + // The ID of the security group. Required for a nondefault VPC. + GroupId *string `type:"string"` + + // [EC2-Classic, default VPC] The name of the security group. + GroupName *string `type:"string"` + + // A set of IP permissions. Can be used to specify multiple rules in a single + // command. + IpPermissions []*IpPermission `locationNameList:"item" type:"list"` + + // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). + // (VPC only) Use -1 to specify all traffic. If you specify -1, traffic on all + // ports is allowed, regardless of any ports you specify. + IpProtocol *string `type:"string"` + + // [EC2-Classic, default VPC] The name of the source security group. You can't + // specify this parameter in combination with the following parameters: the + // CIDR IP address range, the start of the port range, the IP protocol, and + // the end of the port range. Creates rules that grant full ICMP, UDP, and TCP + // access. To create a rule with a specific IP protocol and port range, use + // a set of IP permissions instead. For EC2-VPC, the source security group must + // be in the same VPC. + SourceSecurityGroupName *string `type:"string"` + + // [EC2-Classic] The AWS account number for the source security group, if the + // source security group is in a different account. You can't specify this parameter + // in combination with the following parameters: the CIDR IP address range, + // the IP protocol, the start of the port range, and the end of the port range. + // Creates rules that grant full ICMP, UDP, and TCP access. To create a rule + // with a specific IP protocol and port range, use a set of IP permissions instead. + SourceSecurityGroupOwnerId *string `type:"string"` + + // The end of port range for the TCP and UDP protocols, or an ICMP code number. + // For the ICMP code number, use -1 to specify all ICMP codes for the ICMP type. + ToPort *int64 `type:"integer"` +} + +// String returns the string representation +func (s AuthorizeSecurityGroupIngressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupIngressInput) GoString() string { + return s.String() +} + +type AuthorizeSecurityGroupIngressOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s AuthorizeSecurityGroupIngressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupIngressOutput) GoString() string { + return s.String() +} + +// Describes an Availability Zone. +type AvailabilityZone struct { + _ struct{} `type:"structure"` + + // Any messages about the Availability Zone. + Messages []*AvailabilityZoneMessage `locationName:"messageSet" locationNameList:"item" type:"list"` + + // The name of the region. + RegionName *string `locationName:"regionName" type:"string"` + + // The state of the Availability Zone. + State *string `locationName:"zoneState" type:"string" enum:"AvailabilityZoneState"` + + // The name of the Availability Zone. + ZoneName *string `locationName:"zoneName" type:"string"` +} + +// String returns the string representation +func (s AvailabilityZone) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailabilityZone) GoString() string { + return s.String() +} + +// Describes a message about an Availability Zone. +type AvailabilityZoneMessage struct { + _ struct{} `type:"structure"` + + // The message about the Availability Zone. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s AvailabilityZoneMessage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailabilityZoneMessage) GoString() string { + return s.String() +} + +// The capacity information for instances launched onto the Dedicated Host. +type AvailableCapacity struct { + _ struct{} `type:"structure"` + + // The total number of instances that the Dedicated Host supports. + AvailableInstanceCapacity []*InstanceCapacity `locationName:"availableInstanceCapacity" locationNameList:"item" type:"list"` + + // The number of vCPUs available on the Dedicated Host. + AvailableVCpus *int64 `locationName:"availableVCpus" type:"integer"` +} + +// String returns the string representation +func (s AvailableCapacity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailableCapacity) GoString() string { + return s.String() +} + +type BlobAttributeValue struct { + _ struct{} `type:"structure"` + + // Value is automatically base64 encoded/decoded by the SDK. + Value []byte `locationName:"value" type:"blob"` +} + +// String returns the string representation +func (s BlobAttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BlobAttributeValue) GoString() string { + return s.String() +} + +// Describes a block device mapping. +type BlockDeviceMapping struct { + _ struct{} `type:"structure"` + + // The device name exposed to the instance (for example, /dev/sdh or xvdh). + DeviceName *string `locationName:"deviceName" type:"string"` + + // Parameters used to automatically set up EBS volumes when the instance is + // launched. + Ebs *EbsBlockDevice `locationName:"ebs" type:"structure"` + + // Suppresses the specified device included in the block device mapping of the + // AMI. + NoDevice *string `locationName:"noDevice" type:"string"` + + // The virtual device name (ephemeralN). Instance store volumes are numbered + // starting from 0. An instance type with 2 available instance store volumes + // can specify mappings for ephemeral0 and ephemeral1.The number of available + // instance store volumes depends on the instance type. After you connect to + // the instance, you must mount the volume. + // + // Constraints: For M3 instances, you must specify instance store volumes in + // the block device mapping for the instance. When you launch an M3 instance, + // we ignore any instance store volumes specified in the block device mapping + // for the AMI. + VirtualName *string `locationName:"virtualName" type:"string"` +} + +// String returns the string representation +func (s BlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BlockDeviceMapping) GoString() string { + return s.String() +} + +// Contains the parameters for BundleInstance. +type BundleInstanceInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance to bundle. + // + // Type: String + // + // Default: None + // + // Required: Yes + InstanceId *string `type:"string" required:"true"` + + // The bucket in which to store the AMI. You can specify a bucket that you already + // own or a new bucket that Amazon EC2 creates on your behalf. If you specify + // a bucket that belongs to someone else, Amazon EC2 returns an error. + Storage *Storage `type:"structure" required:"true"` +} + +// String returns the string representation +func (s BundleInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *BundleInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "BundleInstanceInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.Storage == nil { + invalidParams.Add(request.NewErrParamRequired("Storage")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of BundleInstance. +type BundleInstanceOutput struct { + _ struct{} `type:"structure"` + + // Information about the bundle task. + BundleTask *BundleTask `locationName:"bundleInstanceTask" type:"structure"` +} + +// String returns the string representation +func (s BundleInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleInstanceOutput) GoString() string { + return s.String() +} + +// Describes a bundle task. +type BundleTask struct { + _ struct{} `type:"structure"` + + // The ID of the bundle task. + BundleId *string `locationName:"bundleId" type:"string"` + + // If the task fails, a description of the error. + BundleTaskError *BundleTaskError `locationName:"error" type:"structure"` + + // The ID of the instance associated with this bundle task. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The level of task completion, as a percent (for example, 20%). + Progress *string `locationName:"progress" type:"string"` + + // The time this task started. + StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` + + // The state of the task. + State *string `locationName:"state" type:"string" enum:"BundleTaskState"` + + // The Amazon S3 storage locations. + Storage *Storage `locationName:"storage" type:"structure"` + + // The time of the most recent update for the task. + UpdateTime *time.Time `locationName:"updateTime" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s BundleTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleTask) GoString() string { + return s.String() +} + +// Describes an error for BundleInstance. +type BundleTaskError struct { + _ struct{} `type:"structure"` + + // The error code. + Code *string `locationName:"code" type:"string"` + + // The error message. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s BundleTaskError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleTaskError) GoString() string { + return s.String() +} + +// Contains the parameters for CancelBundleTask. +type CancelBundleTaskInput struct { + _ struct{} `type:"structure"` + + // The ID of the bundle task. + BundleId *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s CancelBundleTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelBundleTaskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelBundleTaskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelBundleTaskInput"} + if s.BundleId == nil { + invalidParams.Add(request.NewErrParamRequired("BundleId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CancelBundleTask. +type CancelBundleTaskOutput struct { + _ struct{} `type:"structure"` + + // Information about the bundle task. + BundleTask *BundleTask `locationName:"bundleInstanceTask" type:"structure"` +} + +// String returns the string representation +func (s CancelBundleTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelBundleTaskOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CancelConversionTask. +type CancelConversionTaskInput struct { + _ struct{} `type:"structure"` + + // The ID of the conversion task. + ConversionTaskId *string `locationName:"conversionTaskId" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The reason for canceling the conversion task. + ReasonMessage *string `locationName:"reasonMessage" type:"string"` +} + +// String returns the string representation +func (s CancelConversionTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelConversionTaskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelConversionTaskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelConversionTaskInput"} + if s.ConversionTaskId == nil { + invalidParams.Add(request.NewErrParamRequired("ConversionTaskId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type CancelConversionTaskOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s CancelConversionTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelConversionTaskOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CancelExportTask. +type CancelExportTaskInput struct { + _ struct{} `type:"structure"` + + // The ID of the export task. This is the ID returned by CreateInstanceExportTask. + ExportTaskId *string `locationName:"exportTaskId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelExportTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelExportTaskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelExportTaskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelExportTaskInput"} + if s.ExportTaskId == nil { + invalidParams.Add(request.NewErrParamRequired("ExportTaskId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type CancelExportTaskOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s CancelExportTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelExportTaskOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CancelImportTask. +type CancelImportTaskInput struct { + _ struct{} `type:"structure"` + + // The reason for canceling the task. + CancelReason *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the import image or import snapshot task to be canceled. + ImportTaskId *string `type:"string"` +} + +// String returns the string representation +func (s CancelImportTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelImportTaskInput) GoString() string { + return s.String() +} + +// Contains the output for CancelImportTask. +type CancelImportTaskOutput struct { + _ struct{} `type:"structure"` + + // The ID of the task being canceled. + ImportTaskId *string `locationName:"importTaskId" type:"string"` + + // The current state of the task being canceled. + PreviousState *string `locationName:"previousState" type:"string"` + + // The current state of the task being canceled. + State *string `locationName:"state" type:"string"` +} + +// String returns the string representation +func (s CancelImportTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelImportTaskOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CancelReservedInstancesListing. +type CancelReservedInstancesListingInput struct { + _ struct{} `type:"structure"` + + // The ID of the Reserved Instance listing. + ReservedInstancesListingId *string `locationName:"reservedInstancesListingId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelReservedInstancesListingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelReservedInstancesListingInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelReservedInstancesListingInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelReservedInstancesListingInput"} + if s.ReservedInstancesListingId == nil { + invalidParams.Add(request.NewErrParamRequired("ReservedInstancesListingId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CancelReservedInstancesListing. +type CancelReservedInstancesListingOutput struct { + _ struct{} `type:"structure"` + + // The Reserved Instance listing. + ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s CancelReservedInstancesListingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelReservedInstancesListingOutput) GoString() string { + return s.String() +} + +// Describes a Spot fleet error. +type CancelSpotFleetRequestsError struct { + _ struct{} `type:"structure"` + + // The error code. + Code *string `locationName:"code" type:"string" required:"true" enum:"CancelBatchErrorCode"` + + // The description for the error code. + Message *string `locationName:"message" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelSpotFleetRequestsError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsError) GoString() string { + return s.String() +} + +// Describes a Spot fleet request that was not successfully canceled. +type CancelSpotFleetRequestsErrorItem struct { + _ struct{} `type:"structure"` + + // The error. + Error *CancelSpotFleetRequestsError `locationName:"error" type:"structure" required:"true"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelSpotFleetRequestsErrorItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsErrorItem) GoString() string { + return s.String() +} + +// Contains the parameters for CancelSpotFleetRequests. +type CancelSpotFleetRequestsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The IDs of the Spot fleet requests. + SpotFleetRequestIds []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list" required:"true"` + + // Indicates whether to terminate instances for a Spot fleet request if it is + // canceled successfully. + TerminateInstances *bool `locationName:"terminateInstances" type:"boolean" required:"true"` +} + +// String returns the string representation +func (s CancelSpotFleetRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelSpotFleetRequestsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelSpotFleetRequestsInput"} + if s.SpotFleetRequestIds == nil { + invalidParams.Add(request.NewErrParamRequired("SpotFleetRequestIds")) + } + if s.TerminateInstances == nil { + invalidParams.Add(request.NewErrParamRequired("TerminateInstances")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CancelSpotFleetRequests. +type CancelSpotFleetRequestsOutput struct { + _ struct{} `type:"structure"` + + // Information about the Spot fleet requests that are successfully canceled. + SuccessfulFleetRequests []*CancelSpotFleetRequestsSuccessItem `locationName:"successfulFleetRequestSet" locationNameList:"item" type:"list"` + + // Information about the Spot fleet requests that are not successfully canceled. + UnsuccessfulFleetRequests []*CancelSpotFleetRequestsErrorItem `locationName:"unsuccessfulFleetRequestSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s CancelSpotFleetRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsOutput) GoString() string { + return s.String() +} + +// Describes a Spot fleet request that was successfully canceled. +type CancelSpotFleetRequestsSuccessItem struct { + _ struct{} `type:"structure"` + + // The current state of the Spot fleet request. + CurrentSpotFleetRequestState *string `locationName:"currentSpotFleetRequestState" type:"string" required:"true" enum:"BatchState"` + + // The previous state of the Spot fleet request. + PreviousSpotFleetRequestState *string `locationName:"previousSpotFleetRequestState" type:"string" required:"true" enum:"BatchState"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelSpotFleetRequestsSuccessItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsSuccessItem) GoString() string { + return s.String() +} + +// Contains the parameters for CancelSpotInstanceRequests. +type CancelSpotInstanceRequestsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more Spot instance request IDs. + SpotInstanceRequestIds []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list" required:"true"` +} + +// String returns the string representation +func (s CancelSpotInstanceRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotInstanceRequestsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelSpotInstanceRequestsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelSpotInstanceRequestsInput"} + if s.SpotInstanceRequestIds == nil { + invalidParams.Add(request.NewErrParamRequired("SpotInstanceRequestIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CancelSpotInstanceRequests. +type CancelSpotInstanceRequestsOutput struct { + _ struct{} `type:"structure"` + + // One or more Spot instance requests. + CancelledSpotInstanceRequests []*CancelledSpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s CancelSpotInstanceRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotInstanceRequestsOutput) GoString() string { + return s.String() +} + +// Describes a request to cancel a Spot instance. +type CancelledSpotInstanceRequest struct { + _ struct{} `type:"structure"` + + // The ID of the Spot instance request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` + + // The state of the Spot instance request. + State *string `locationName:"state" type:"string" enum:"CancelSpotInstanceRequestState"` +} + +// String returns the string representation +func (s CancelledSpotInstanceRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelledSpotInstanceRequest) GoString() string { + return s.String() +} + +// Describes the ClassicLink DNS support status of a VPC. +type ClassicLinkDnsSupport struct { + _ struct{} `type:"structure"` + + // Indicates whether ClassicLink DNS support is enabled for the VPC. + ClassicLinkDnsSupported *bool `locationName:"classicLinkDnsSupported" type:"boolean"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s ClassicLinkDnsSupport) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClassicLinkDnsSupport) GoString() string { + return s.String() +} + +// Describes a linked EC2-Classic instance. +type ClassicLinkInstance struct { + _ struct{} `type:"structure"` + + // A list of security groups. + Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // Any tags assigned to the instance. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s ClassicLinkInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClassicLinkInstance) GoString() string { + return s.String() +} + +// Describes the client-specific data. +type ClientData struct { + _ struct{} `type:"structure"` + + // A user-defined comment about the disk upload. + Comment *string `type:"string"` + + // The time that the disk upload ends. + UploadEnd *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The size of the uploaded disk image, in GiB. + UploadSize *float64 `type:"double"` + + // The time that the disk upload starts. + UploadStart *time.Time `type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s ClientData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClientData) GoString() string { + return s.String() +} + +// Contains the parameters for ConfirmProductInstance. +type ConfirmProductInstanceInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `type:"string" required:"true"` + + // The product code. This must be a product code that you own. + ProductCode *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ConfirmProductInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConfirmProductInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ConfirmProductInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ConfirmProductInstanceInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.ProductCode == nil { + invalidParams.Add(request.NewErrParamRequired("ProductCode")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ConfirmProductInstance. +type ConfirmProductInstanceOutput struct { + _ struct{} `type:"structure"` + + // The AWS account ID of the instance owner. This is only present if the product + // code is attached to the instance. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The return value of the request. Returns true if the specified product code + // is owned by the requester and associated with the specified instance. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ConfirmProductInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConfirmProductInstanceOutput) GoString() string { + return s.String() +} + +// Describes a conversion task. +type ConversionTask struct { + _ struct{} `type:"structure"` + + // The ID of the conversion task. + ConversionTaskId *string `locationName:"conversionTaskId" type:"string" required:"true"` + + // The time when the task expires. If the upload isn't complete before the expiration + // time, we automatically cancel the task. + ExpirationTime *string `locationName:"expirationTime" type:"string"` + + // If the task is for importing an instance, this contains information about + // the import instance task. + ImportInstance *ImportInstanceTaskDetails `locationName:"importInstance" type:"structure"` + + // If the task is for importing a volume, this contains information about the + // import volume task. + ImportVolume *ImportVolumeTaskDetails `locationName:"importVolume" type:"structure"` + + // The state of the conversion task. + State *string `locationName:"state" type:"string" required:"true" enum:"ConversionTaskState"` + + // The status message related to the conversion task. + StatusMessage *string `locationName:"statusMessage" type:"string"` + + // Any tags assigned to the task. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s ConversionTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConversionTask) GoString() string { + return s.String() +} + +// Contains the parameters for CopyImage. +type CopyImageInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide. + ClientToken *string `type:"string"` + + // A description for the new AMI in the destination region. + Description *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Specifies whether the destination snapshots of the copied image should be + // encrypted. The default CMK for EBS is used unless a non-default AWS Key Management + // Service (AWS KMS) CMK is specified with KmsKeyId. For more information, see + // Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) + // in the Amazon Elastic Compute Cloud User Guide. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The full ARN of the AWS Key Management Service (AWS KMS) CMK to use when + // encrypting the snapshots of an image during a copy operation. This parameter + // is only required if you want to use a non-default CMK; if this parameter + // is not specified, the default CMK for EBS is used. The ARN contains the arn:aws:kms + // namespace, followed by the region of the CMK, the AWS account ID of the CMK + // owner, the key namespace, and then the CMK ID. For example, arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. + // The specified CMK must exist in the region that the snapshot is being copied + // to. If a KmsKeyId is specified, the Encrypted flag must also be set. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` + + // The name of the new AMI in the destination region. + Name *string `type:"string" required:"true"` + + // The ID of the AMI to copy. + SourceImageId *string `type:"string" required:"true"` + + // The name of the region that contains the AMI to copy. + SourceRegion *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CopyImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopyImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CopyImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CopyImageInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.SourceImageId == nil { + invalidParams.Add(request.NewErrParamRequired("SourceImageId")) + } + if s.SourceRegion == nil { + invalidParams.Add(request.NewErrParamRequired("SourceRegion")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CopyImage. +type CopyImageOutput struct { + _ struct{} `type:"structure"` + + // The ID of the new AMI. + ImageId *string `locationName:"imageId" type:"string"` +} + +// String returns the string representation +func (s CopyImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopyImageOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CopySnapshot. +type CopySnapshotInput struct { + _ struct{} `type:"structure"` + + // A description for the EBS snapshot. + Description *string `type:"string"` + + // The destination region to use in the PresignedUrl parameter of a snapshot + // copy operation. This parameter is only valid for specifying the destination + // region in a PresignedUrl parameter, where it is required. + // + // CopySnapshot sends the snapshot copy to the regional endpoint that you + // send the HTTP request to, such as ec2.us-east-1.amazonaws.com (in the AWS + // CLI, this is specified with the --region parameter or the default region + // in your AWS configuration file). + DestinationRegion *string `locationName:"destinationRegion" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Specifies whether the destination snapshot should be encrypted. You can encrypt + // a copy of an unencrypted snapshot using this flag, but you cannot use it + // to create an unencrypted copy from an encrypted snapshot. Your default CMK + // for EBS is used unless a non-default AWS Key Management Service (AWS KMS) + // CMK is specified with KmsKeyId. For more information, see Amazon EBS Encryption + // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) in + // the Amazon Elastic Compute Cloud User Guide. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The full ARN of the AWS Key Management Service (AWS KMS) CMK to use when + // creating the snapshot copy. This parameter is only required if you want to + // use a non-default CMK; if this parameter is not specified, the default CMK + // for EBS is used. The ARN contains the arn:aws:kms namespace, followed by + // the region of the CMK, the AWS account ID of the CMK owner, the key namespace, + // and then the CMK ID. For example, arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. + // The specified CMK must exist in the region that the snapshot is being copied + // to. If a KmsKeyId is specified, the Encrypted flag must also be set. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` + + // The pre-signed URL that facilitates copying an encrypted snapshot. This parameter + // is only required when copying an encrypted snapshot with the Amazon EC2 Query + // API; it is available as an optional parameter in all other cases. The PresignedUrl + // should use the snapshot source endpoint, the CopySnapshot action, and include + // the SourceRegion, SourceSnapshotId, and DestinationRegion parameters. The + // PresignedUrl must be signed using AWS Signature Version 4. Because EBS snapshots + // are stored in Amazon S3, the signing algorithm for this parameter uses the + // same logic that is described in Authenticating Requests by Using Query Parameters + // (AWS Signature Version 4) (http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html) + // in the Amazon Simple Storage Service API Reference. An invalid or improperly + // signed PresignedUrl will cause the copy operation to fail asynchronously, + // and the snapshot will move to an error state. + PresignedUrl *string `locationName:"presignedUrl" type:"string"` + + // The ID of the region that contains the snapshot to be copied. + SourceRegion *string `type:"string" required:"true"` + + // The ID of the EBS snapshot to copy. + SourceSnapshotId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CopySnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopySnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CopySnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CopySnapshotInput"} + if s.SourceRegion == nil { + invalidParams.Add(request.NewErrParamRequired("SourceRegion")) + } + if s.SourceSnapshotId == nil { + invalidParams.Add(request.NewErrParamRequired("SourceSnapshotId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CopySnapshot. +type CopySnapshotOutput struct { + _ struct{} `type:"structure"` + + // The ID of the new snapshot. + SnapshotId *string `locationName:"snapshotId" type:"string"` +} + +// String returns the string representation +func (s CopySnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopySnapshotOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateCustomerGateway. +type CreateCustomerGatewayInput struct { + _ struct{} `type:"structure"` + + // For devices that support BGP, the customer gateway's BGP ASN. + // + // Default: 65000 + BgpAsn *int64 `type:"integer" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The Internet-routable IP address for the customer gateway's outside interface. + // The address must be static. + PublicIp *string `locationName:"IpAddress" type:"string" required:"true"` + + // The type of VPN connection that this customer gateway supports (ipsec.1). + Type *string `type:"string" required:"true" enum:"GatewayType"` +} + +// String returns the string representation +func (s CreateCustomerGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCustomerGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateCustomerGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateCustomerGatewayInput"} + if s.BgpAsn == nil { + invalidParams.Add(request.NewErrParamRequired("BgpAsn")) + } + if s.PublicIp == nil { + invalidParams.Add(request.NewErrParamRequired("PublicIp")) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateCustomerGateway. +type CreateCustomerGatewayOutput struct { + _ struct{} `type:"structure"` + + // Information about the customer gateway. + CustomerGateway *CustomerGateway `locationName:"customerGateway" type:"structure"` +} + +// String returns the string representation +func (s CreateCustomerGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCustomerGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateDhcpOptions. +type CreateDhcpOptionsInput struct { + _ struct{} `type:"structure"` + + // A DHCP configuration option. + DhcpConfigurations []*NewDhcpConfiguration `locationName:"dhcpConfiguration" locationNameList:"item" type:"list" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s CreateDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDhcpOptionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDhcpOptionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDhcpOptionsInput"} + if s.DhcpConfigurations == nil { + invalidParams.Add(request.NewErrParamRequired("DhcpConfigurations")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateDhcpOptions. +type CreateDhcpOptionsOutput struct { + _ struct{} `type:"structure"` + + // A set of DHCP options. + DhcpOptions *DhcpOptions `locationName:"dhcpOptions" type:"structure"` +} + +// String returns the string representation +func (s CreateDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDhcpOptionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateFlowLogs. +type CreateFlowLogsInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // The ARN for the IAM role that's used to post flow logs to a CloudWatch Logs + // log group. + DeliverLogsPermissionArn *string `type:"string" required:"true"` + + // The name of the CloudWatch log group. + LogGroupName *string `type:"string" required:"true"` + + // One or more subnet, network interface, or VPC IDs. + // + // Constraints: Maximum of 1000 resources + ResourceIds []*string `locationName:"ResourceId" locationNameList:"item" type:"list" required:"true"` + + // The type of resource on which to create the flow log. + ResourceType *string `type:"string" required:"true" enum:"FlowLogsResourceType"` + + // The type of traffic to log. + TrafficType *string `type:"string" required:"true" enum:"TrafficType"` +} + +// String returns the string representation +func (s CreateFlowLogsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFlowLogsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFlowLogsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFlowLogsInput"} + if s.DeliverLogsPermissionArn == nil { + invalidParams.Add(request.NewErrParamRequired("DeliverLogsPermissionArn")) + } + if s.LogGroupName == nil { + invalidParams.Add(request.NewErrParamRequired("LogGroupName")) + } + if s.ResourceIds == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceIds")) + } + if s.ResourceType == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceType")) + } + if s.TrafficType == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficType")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateFlowLogs. +type CreateFlowLogsOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. + ClientToken *string `locationName:"clientToken" type:"string"` + + // The IDs of the flow logs. + FlowLogIds []*string `locationName:"flowLogIdSet" locationNameList:"item" type:"list"` + + // Information about the flow logs that could not be created successfully. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s CreateFlowLogsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFlowLogsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateImage. +type CreateImageInput struct { + _ struct{} `type:"structure"` + + // Information about one or more block device mappings. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` + + // A description for the new image. + Description *string `locationName:"description" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // A name for the new image. + // + // Constraints: 3-128 alphanumeric characters, parentheses (()), square brackets + // ([]), spaces ( ), periods (.), slashes (/), dashes (-), single quotes ('), + // at-signs (@), or underscores(_) + Name *string `locationName:"name" type:"string" required:"true"` + + // By default, Amazon EC2 attempts to shut down and reboot the instance before + // creating the image. If the 'No Reboot' option is set, Amazon EC2 doesn't + // shut down the instance before creating the image. When this option is used, + // file system integrity on the created image can't be guaranteed. + NoReboot *bool `locationName:"noReboot" type:"boolean"` +} + +// String returns the string representation +func (s CreateImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateImageInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateImage. +type CreateImageOutput struct { + _ struct{} `type:"structure"` + + // The ID of the new AMI. + ImageId *string `locationName:"imageId" type:"string"` +} + +// String returns the string representation +func (s CreateImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateImageOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateInstanceExportTask. +type CreateInstanceExportTaskInput struct { + _ struct{} `type:"structure"` + + // A description for the conversion task or the resource being exported. The + // maximum length is 255 bytes. + Description *string `locationName:"description" type:"string"` + + // The format and location for an instance export task. + ExportToS3Task *ExportToS3TaskSpecification `locationName:"exportToS3" type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // The target virtualization environment. + TargetEnvironment *string `locationName:"targetEnvironment" type:"string" enum:"ExportEnvironment"` +} + +// String returns the string representation +func (s CreateInstanceExportTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstanceExportTaskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateInstanceExportTaskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateInstanceExportTaskInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output for CreateInstanceExportTask. +type CreateInstanceExportTaskOutput struct { + _ struct{} `type:"structure"` + + // Information about the instance export task. + ExportTask *ExportTask `locationName:"exportTask" type:"structure"` +} + +// String returns the string representation +func (s CreateInstanceExportTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstanceExportTaskOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateInternetGateway. +type CreateInternetGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s CreateInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInternetGatewayInput) GoString() string { + return s.String() +} + +// Contains the output of CreateInternetGateway. +type CreateInternetGatewayOutput struct { + _ struct{} `type:"structure"` + + // Information about the Internet gateway. + InternetGateway *InternetGateway `locationName:"internetGateway" type:"structure"` +} + +// String returns the string representation +func (s CreateInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInternetGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateKeyPair. +type CreateKeyPairInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // A unique name for the key pair. + // + // Constraints: Up to 255 ASCII characters + KeyName *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateKeyPairInput"} + if s.KeyName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a key pair. +type CreateKeyPairOutput struct { + _ struct{} `type:"structure"` + + // The SHA-1 digest of the DER encoded private key. + KeyFingerprint *string `locationName:"keyFingerprint" type:"string"` + + // An unencrypted PEM encoded RSA private key. + KeyMaterial *string `locationName:"keyMaterial" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` +} + +// String returns the string representation +func (s CreateKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateKeyPairOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateNatGateway. +type CreateNatGatewayInput struct { + _ struct{} `type:"structure"` + + // The allocation ID of an Elastic IP address to associate with the NAT gateway. + // If the Elastic IP address is associated with another resource, you must first + // disassociate it. + AllocationId *string `type:"string" required:"true"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + // + // Constraint: Maximum 64 ASCII characters. + ClientToken *string `type:"string"` + + // The subnet in which to create the NAT gateway. + SubnetId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateNatGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNatGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateNatGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateNatGatewayInput"} + if s.AllocationId == nil { + invalidParams.Add(request.NewErrParamRequired("AllocationId")) + } + if s.SubnetId == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateNatGateway. +type CreateNatGatewayOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier to ensure the idempotency of the request. + // Only returned if a client token was provided in the request. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Information about the NAT gateway. + NatGateway *NatGateway `locationName:"natGateway" type:"structure"` +} + +// String returns the string representation +func (s CreateNatGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNatGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateNetworkAclEntry. +type CreateNetworkAclEntryInput struct { + _ struct{} `type:"structure"` + + // The network range to allow or deny, in CIDR notation (for example 172.16.0.0/24). + CidrBlock *string `locationName:"cidrBlock" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Indicates whether this is an egress rule (rule is applied to traffic leaving + // the subnet). + Egress *bool `locationName:"egress" type:"boolean" required:"true"` + + // ICMP protocol: The ICMP type and code. Required if specifying ICMP for the + // protocol. + IcmpTypeCode *IcmpTypeCode `locationName:"Icmp" type:"structure"` + + // The ID of the network ACL. + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` + + // TCP or UDP protocols: The range of ports the rule applies to. + PortRange *PortRange `locationName:"portRange" type:"structure"` + + // The protocol. A value of -1 means all protocols. + Protocol *string `locationName:"protocol" type:"string" required:"true"` + + // Indicates whether to allow or deny the traffic that matches the rule. + RuleAction *string `locationName:"ruleAction" type:"string" required:"true" enum:"RuleAction"` + + // The rule number for the entry (for example, 100). ACL entries are processed + // in ascending order by rule number. + // + // Constraints: Positive integer from 1 to 32766. The range 32767 to 65535 + // is reserved for internal use. + RuleNumber *int64 `locationName:"ruleNumber" type:"integer" required:"true"` +} + +// String returns the string representation +func (s CreateNetworkAclEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclEntryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateNetworkAclEntryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateNetworkAclEntryInput"} + if s.CidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("CidrBlock")) + } + if s.Egress == nil { + invalidParams.Add(request.NewErrParamRequired("Egress")) + } + if s.NetworkAclId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkAclId")) + } + if s.Protocol == nil { + invalidParams.Add(request.NewErrParamRequired("Protocol")) + } + if s.RuleAction == nil { + invalidParams.Add(request.NewErrParamRequired("RuleAction")) + } + if s.RuleNumber == nil { + invalidParams.Add(request.NewErrParamRequired("RuleNumber")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type CreateNetworkAclEntryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s CreateNetworkAclEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclEntryOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateNetworkAcl. +type CreateNetworkAclInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateNetworkAclInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateNetworkAclInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateNetworkAclInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateNetworkAcl. +type CreateNetworkAclOutput struct { + _ struct{} `type:"structure"` + + // Information about the network ACL. + NetworkAcl *NetworkAcl `locationName:"networkAcl" type:"structure"` +} + +// String returns the string representation +func (s CreateNetworkAclOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateNetworkInterface. +type CreateNetworkInterfaceInput struct { + _ struct{} `type:"structure"` + + // A description for the network interface. + Description *string `locationName:"description" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The IDs of one or more security groups. + Groups []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // The primary private IP address of the network interface. If you don't specify + // an IP address, Amazon EC2 selects one for you from the subnet range. If you + // specify an IP address, you cannot indicate any IP addresses specified in + // privateIpAddresses as primary (only one IP address can be designated as primary). + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // One or more private IP addresses. + PrivateIpAddresses []*PrivateIpAddressSpecification `locationName:"privateIpAddresses" locationNameList:"item" type:"list"` + + // The number of secondary private IP addresses to assign to a network interface. + // When you specify a number of secondary IP addresses, Amazon EC2 selects these + // IP addresses within the subnet range. You can't specify this option and specify + // more than one private IP address using privateIpAddresses. + // + // The number of IP addresses you can assign to a network interface varies + // by instance type. For more information, see Private IP Addresses Per ENI + // Per Instance Type (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI) + // in the Amazon Elastic Compute Cloud User Guide. + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` + + // The ID of the subnet to associate with the network interface. + SubnetId *string `locationName:"subnetId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkInterfaceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateNetworkInterfaceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateNetworkInterfaceInput"} + if s.SubnetId == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetId")) + } + if s.PrivateIpAddresses != nil { + for i, v := range s.PrivateIpAddresses { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PrivateIpAddresses", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateNetworkInterface. +type CreateNetworkInterfaceOutput struct { + _ struct{} `type:"structure"` + + // Information about the network interface. + NetworkInterface *NetworkInterface `locationName:"networkInterface" type:"structure"` +} + +// String returns the string representation +func (s CreateNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkInterfaceOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreatePlacementGroup. +type CreatePlacementGroupInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // A name for the placement group. + // + // Constraints: Up to 255 ASCII characters + GroupName *string `locationName:"groupName" type:"string" required:"true"` + + // The placement strategy. + Strategy *string `locationName:"strategy" type:"string" required:"true" enum:"PlacementStrategy"` +} + +// String returns the string representation +func (s CreatePlacementGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreatePlacementGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreatePlacementGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreatePlacementGroupInput"} + if s.GroupName == nil { + invalidParams.Add(request.NewErrParamRequired("GroupName")) + } + if s.Strategy == nil { + invalidParams.Add(request.NewErrParamRequired("Strategy")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type CreatePlacementGroupOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s CreatePlacementGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreatePlacementGroupOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateReservedInstancesListing. +type CreateReservedInstancesListingInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of your + // listings. This helps avoid duplicate listings. For more information, see + // Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `locationName:"clientToken" type:"string" required:"true"` + + // The number of instances that are a part of a Reserved Instance account to + // be listed in the Reserved Instance Marketplace. This number should be less + // than or equal to the instance count associated with the Reserved Instance + // ID specified in this call. + InstanceCount *int64 `locationName:"instanceCount" type:"integer" required:"true"` + + // A list specifying the price of the Reserved Instance for each month remaining + // in the Reserved Instance term. + PriceSchedules []*PriceScheduleSpecification `locationName:"priceSchedules" locationNameList:"item" type:"list" required:"true"` + + // The ID of the active Reserved Instance. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateReservedInstancesListingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateReservedInstancesListingInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateReservedInstancesListingInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateReservedInstancesListingInput"} + if s.ClientToken == nil { + invalidParams.Add(request.NewErrParamRequired("ClientToken")) + } + if s.InstanceCount == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceCount")) + } + if s.PriceSchedules == nil { + invalidParams.Add(request.NewErrParamRequired("PriceSchedules")) + } + if s.ReservedInstancesId == nil { + invalidParams.Add(request.NewErrParamRequired("ReservedInstancesId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateReservedInstancesListing. +type CreateReservedInstancesListingOutput struct { + _ struct{} `type:"structure"` + + // Information about the Reserved Instance listing. + ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s CreateReservedInstancesListingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateReservedInstancesListingOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateRoute. +type CreateRouteInput struct { + _ struct{} `type:"structure"` + + // The CIDR address block used for the destination match. Routing decisions + // are based on the most specific match. + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of an Internet gateway or virtual private gateway attached to your + // VPC. + GatewayId *string `locationName:"gatewayId" type:"string"` + + // The ID of a NAT instance in your VPC. The operation fails if you specify + // an instance ID unless exactly one network interface is attached. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The ID of a NAT gateway. + NatGatewayId *string `locationName:"natGatewayId" type:"string"` + + // The ID of a network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The ID of the route table for the route. + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` + + // The ID of a VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s CreateRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateRouteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateRouteInput"} + if s.DestinationCidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("DestinationCidrBlock")) + } + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateRoute. +type CreateRouteOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s CreateRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateRouteTable. +type CreateRouteTableInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateRouteTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateRouteTableInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateRouteTable. +type CreateRouteTableOutput struct { + _ struct{} `type:"structure"` + + // Information about the route table. + RouteTable *RouteTable `locationName:"routeTable" type:"structure"` +} + +// String returns the string representation +func (s CreateRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteTableOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateSecurityGroup. +type CreateSecurityGroupInput struct { + _ struct{} `type:"structure"` + + // A description for the security group. This is informational only. + // + // Constraints: Up to 255 characters in length + // + // Constraints for EC2-Classic: ASCII characters + // + // Constraints for EC2-VPC: a-z, A-Z, 0-9, spaces, and ._-:/()#,@[]+=&;{}!$* + Description *string `locationName:"GroupDescription" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The name of the security group. + // + // Constraints: Up to 255 characters in length + // + // Constraints for EC2-Classic: ASCII characters + // + // Constraints for EC2-VPC: a-z, A-Z, 0-9, spaces, and ._-:/()#,@[]+=&;{}!$* + GroupName *string `type:"string" required:"true"` + + // [EC2-VPC] The ID of the VPC. Required for EC2-VPC. + VpcId *string `type:"string"` +} + +// String returns the string representation +func (s CreateSecurityGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSecurityGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateSecurityGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateSecurityGroupInput"} + if s.Description == nil { + invalidParams.Add(request.NewErrParamRequired("Description")) + } + if s.GroupName == nil { + invalidParams.Add(request.NewErrParamRequired("GroupName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateSecurityGroup. +type CreateSecurityGroupOutput struct { + _ struct{} `type:"structure"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string"` +} + +// String returns the string representation +func (s CreateSecurityGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSecurityGroupOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateSnapshot. +type CreateSnapshotInput struct { + _ struct{} `type:"structure"` + + // A description for the snapshot. + Description *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the EBS volume. + VolumeId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateSnapshotInput"} + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the parameters for CreateSpotDatafeedSubscription. +type CreateSpotDatafeedSubscriptionInput struct { + _ struct{} `type:"structure"` + + // The Amazon S3 bucket in which to store the Spot instance data feed. + Bucket *string `locationName:"bucket" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // A prefix for the data feed file names. + Prefix *string `locationName:"prefix" type:"string"` +} + +// String returns the string representation +func (s CreateSpotDatafeedSubscriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSpotDatafeedSubscriptionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateSpotDatafeedSubscriptionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateSpotDatafeedSubscriptionInput"} + if s.Bucket == nil { + invalidParams.Add(request.NewErrParamRequired("Bucket")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateSpotDatafeedSubscription. +type CreateSpotDatafeedSubscriptionOutput struct { + _ struct{} `type:"structure"` + + // The Spot instance data feed subscription. + SpotDatafeedSubscription *SpotDatafeedSubscription `locationName:"spotDatafeedSubscription" type:"structure"` +} + +// String returns the string representation +func (s CreateSpotDatafeedSubscriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSpotDatafeedSubscriptionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateSubnet. +type CreateSubnetInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone for the subnet. + // + // Default: AWS selects one for you. If you create more than one subnet in + // your VPC, we may not necessarily select a different zone for each subnet. + AvailabilityZone *string `type:"string"` + + // The network range for the subnet, in CIDR notation. For example, 10.0.0.0/24. + CidrBlock *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateSubnetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSubnetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateSubnetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateSubnetInput"} + if s.CidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("CidrBlock")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateSubnet. +type CreateSubnetOutput struct { + _ struct{} `type:"structure"` + + // Information about the subnet. + Subnet *Subnet `locationName:"subnet" type:"structure"` +} + +// String returns the string representation +func (s CreateSubnetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSubnetOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateTags. +type CreateTagsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The IDs of one or more resources to tag. For example, ami-1a2b3c4d. + Resources []*string `locationName:"ResourceId" type:"list" required:"true"` + + // One or more tags. The value parameter is required, but if you don't want + // the tag to have a value, specify the parameter with no value, and we set + // the value to an empty string. + Tags []*Tag `locationName:"Tag" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s CreateTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTagsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateTagsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateTagsInput"} + if s.Resources == nil { + invalidParams.Add(request.NewErrParamRequired("Resources")) + } + if s.Tags == nil { + invalidParams.Add(request.NewErrParamRequired("Tags")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type CreateTagsOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s CreateTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTagsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVolume. +type CreateVolumeInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which to create the volume. Use DescribeAvailabilityZones + // to list the Availability Zones that are currently available to you. + AvailabilityZone *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Specifies whether the volume should be encrypted. Encrypted Amazon EBS volumes + // may only be attached to instances that support Amazon EBS encryption. Volumes + // that are created from encrypted snapshots are automatically encrypted. There + // is no way to create an encrypted volume from an unencrypted snapshot or vice + // versa. If your AMI uses encrypted volumes, you can only launch it on supported + // instance types. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) + // in the Amazon Elastic Compute Cloud User Guide. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // Only valid for Provisioned IOPS SSD volumes. The number of I/O operations + // per second (IOPS) to provision for the volume, with a maximum ratio of 30 + // IOPS/GiB. + // + // Constraint: Range is 100 to 20000 for Provisioned IOPS SSD volumes + Iops *int64 `type:"integer"` + + // The full ARN of the AWS Key Management Service (AWS KMS) customer master + // key (CMK) to use when creating the encrypted volume. This parameter is only + // required if you want to use a non-default CMK; if this parameter is not specified, + // the default CMK for EBS is used. The ARN contains the arn:aws:kms namespace, + // followed by the region of the CMK, the AWS account ID of the CMK owner, the + // key namespace, and then the CMK ID. For example, arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. + // If a KmsKeyId is specified, the Encrypted flag must also be set. + KmsKeyId *string `type:"string"` + + // The size of the volume, in GiBs. + // + // Constraints: 1-16384 for gp2, 4-16384 for io1, 500-16384 for st1, 500-16384 + // for sc1, and 1-1024 for standard. If you specify a snapshot, the volume size + // must be equal to or larger than the snapshot size. + // + // Default: If you're creating the volume from a snapshot and don't specify + // a volume size, the default is the snapshot size. + Size *int64 `type:"integer"` + + // The snapshot from which to create the volume. + SnapshotId *string `type:"string"` + + // The volume type. This can be gp2 for General Purpose SSD, io1 for Provisioned + // IOPS SSD, st1 for Throughput Optimized HDD, sc1 for Cold HDD, or standard + // for Magnetic volumes. + // + // Default: standard + VolumeType *string `type:"string" enum:"VolumeType"` +} + +// String returns the string representation +func (s CreateVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVolumeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVolumeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVolumeInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes the user or group to be added or removed from the permissions for +// a volume. +type CreateVolumePermission struct { + _ struct{} `type:"structure"` + + // The specific group that is to be added or removed from a volume's list of + // create volume permissions. + Group *string `locationName:"group" type:"string" enum:"PermissionGroup"` + + // The specific AWS account ID that is to be added or removed from a volume's + // list of create volume permissions. + UserId *string `locationName:"userId" type:"string"` +} + +// String returns the string representation +func (s CreateVolumePermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVolumePermission) GoString() string { + return s.String() +} + +// Describes modifications to the permissions for a volume. +type CreateVolumePermissionModifications struct { + _ struct{} `type:"structure"` + + // Adds a specific AWS account ID or group to a volume's list of create volume + // permissions. + Add []*CreateVolumePermission `locationNameList:"item" type:"list"` + + // Removes a specific AWS account ID or group from a volume's list of create + // volume permissions. + Remove []*CreateVolumePermission `locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s CreateVolumePermissionModifications) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVolumePermissionModifications) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVpcEndpoint. +type CreateVpcEndpointInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // A policy to attach to the endpoint that controls access to the service. The + // policy must be in valid JSON format. If this parameter is not specified, + // we attach a default policy that allows full access to the service. + PolicyDocument *string `type:"string"` + + // One or more route table IDs. + RouteTableIds []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` + + // The AWS service name, in the form com.amazonaws.region.service . To get a + // list of available services, use the DescribeVpcEndpointServices request. + ServiceName *string `type:"string" required:"true"` + + // The ID of the VPC in which the endpoint will be used. + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateVpcEndpointInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpcEndpointInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpcEndpointInput"} + if s.ServiceName == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceName")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateVpcEndpoint. +type CreateVpcEndpointOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Information about the endpoint. + VpcEndpoint *VpcEndpoint `locationName:"vpcEndpoint" type:"structure"` +} + +// String returns the string representation +func (s CreateVpcEndpointOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVpc. +type CreateVpcInput struct { + _ struct{} `type:"structure"` + + // The network range for the VPC, in CIDR notation. For example, 10.0.0.0/16. + CidrBlock *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The tenancy options for instances launched into the VPC. For default, instances + // are launched with shared tenancy by default. You can launch instances with + // any tenancy into a shared tenancy VPC. For dedicated, instances are launched + // as dedicated tenancy instances by default. You can only launch instances + // with a tenancy of dedicated or host into a dedicated tenancy VPC. + // + // Important: The host value cannot be used with this parameter. Use the default + // or dedicated values only. + // + // Default: default + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` +} + +// String returns the string representation +func (s CreateVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpcInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpcInput"} + if s.CidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("CidrBlock")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateVpc. +type CreateVpcOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPC. + Vpc *Vpc `locationName:"vpc" type:"structure"` +} + +// String returns the string representation +func (s CreateVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVpcPeeringConnection. +type CreateVpcPeeringConnectionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The AWS account ID of the owner of the peer VPC. + // + // Default: Your AWS account ID + PeerOwnerId *string `locationName:"peerOwnerId" type:"string"` + + // The ID of the VPC with which you are creating the VPC peering connection. + PeerVpcId *string `locationName:"peerVpcId" type:"string"` + + // The ID of the requester VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s CreateVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +// Contains the output of CreateVpcPeeringConnection. +type CreateVpcPeeringConnectionOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPC peering connection. + VpcPeeringConnection *VpcPeeringConnection `locationName:"vpcPeeringConnection" type:"structure"` +} + +// String returns the string representation +func (s CreateVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVpnConnection. +type CreateVpnConnectionInput struct { + _ struct{} `type:"structure"` + + // The ID of the customer gateway. + CustomerGatewayId *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Indicates whether the VPN connection requires static routes. If you are creating + // a VPN connection for a device that does not support BGP, you must specify + // true. + // + // Default: false + Options *VpnConnectionOptionsSpecification `locationName:"options" type:"structure"` + + // The type of VPN connection (ipsec.1). + Type *string `type:"string" required:"true"` + + // The ID of the virtual private gateway. + VpnGatewayId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateVpnConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnConnectionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpnConnectionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpnConnectionInput"} + if s.CustomerGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("CustomerGatewayId")) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.VpnGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateVpnConnection. +type CreateVpnConnectionOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPN connection. + VpnConnection *VpnConnection `locationName:"vpnConnection" type:"structure"` +} + +// String returns the string representation +func (s CreateVpnConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnConnectionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVpnConnectionRoute. +type CreateVpnConnectionRouteInput struct { + _ struct{} `type:"structure"` + + // The CIDR block associated with the local subnet of the customer network. + DestinationCidrBlock *string `type:"string" required:"true"` + + // The ID of the VPN connection. + VpnConnectionId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateVpnConnectionRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnConnectionRouteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpnConnectionRouteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpnConnectionRouteInput"} + if s.DestinationCidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("DestinationCidrBlock")) + } + if s.VpnConnectionId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnConnectionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type CreateVpnConnectionRouteOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s CreateVpnConnectionRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnConnectionRouteOutput) GoString() string { + return s.String() +} + +// Contains the parameters for CreateVpnGateway. +type CreateVpnGatewayInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone for the virtual private gateway. + AvailabilityZone *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The type of VPN connection this virtual private gateway supports. + Type *string `type:"string" required:"true" enum:"GatewayType"` +} + +// String returns the string representation +func (s CreateVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpnGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpnGatewayInput"} + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of CreateVpnGateway. +type CreateVpnGatewayOutput struct { + _ struct{} `type:"structure"` + + // Information about the virtual private gateway. + VpnGateway *VpnGateway `locationName:"vpnGateway" type:"structure"` +} + +// String returns the string representation +func (s CreateVpnGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnGatewayOutput) GoString() string { + return s.String() +} + +// Describes a customer gateway. +type CustomerGateway struct { + _ struct{} `type:"structure"` + + // The customer gateway's Border Gateway Protocol (BGP) Autonomous System Number + // (ASN). + BgpAsn *string `locationName:"bgpAsn" type:"string"` + + // The ID of the customer gateway. + CustomerGatewayId *string `locationName:"customerGatewayId" type:"string"` + + // The Internet-routable IP address of the customer gateway's outside interface. + IpAddress *string `locationName:"ipAddress" type:"string"` + + // The current state of the customer gateway (pending | available | deleting + // | deleted). + State *string `locationName:"state" type:"string"` + + // Any tags assigned to the customer gateway. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The type of VPN connection the customer gateway supports (ipsec.1). + Type *string `locationName:"type" type:"string"` +} + +// String returns the string representation +func (s CustomerGateway) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CustomerGateway) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteCustomerGateway. +type DeleteCustomerGatewayInput struct { + _ struct{} `type:"structure"` + + // The ID of the customer gateway. + CustomerGatewayId *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s DeleteCustomerGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteCustomerGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteCustomerGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteCustomerGatewayInput"} + if s.CustomerGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("CustomerGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteCustomerGatewayOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteCustomerGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteCustomerGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteDhcpOptions. +type DeleteDhcpOptionsInput struct { + _ struct{} `type:"structure"` + + // The ID of the DHCP options set. + DhcpOptionsId *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s DeleteDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDhcpOptionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDhcpOptionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteDhcpOptionsInput"} + if s.DhcpOptionsId == nil { + invalidParams.Add(request.NewErrParamRequired("DhcpOptionsId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteDhcpOptionsOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDhcpOptionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteFlowLogs. +type DeleteFlowLogsInput struct { + _ struct{} `type:"structure"` + + // One or more flow log IDs. + FlowLogIds []*string `locationName:"FlowLogId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s DeleteFlowLogsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFlowLogsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteFlowLogsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteFlowLogsInput"} + if s.FlowLogIds == nil { + invalidParams.Add(request.NewErrParamRequired("FlowLogIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DeleteFlowLogs. +type DeleteFlowLogsOutput struct { + _ struct{} `type:"structure"` + + // Information about the flow logs that could not be deleted successfully. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DeleteFlowLogsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFlowLogsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteInternetGateway. +type DeleteInternetGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the Internet gateway. + InternetGatewayId *string `locationName:"internetGatewayId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInternetGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteInternetGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteInternetGatewayInput"} + if s.InternetGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("InternetGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteInternetGatewayOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInternetGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteKeyPair. +type DeleteKeyPairInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The name of the key pair. + KeyName *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteKeyPairInput"} + if s.KeyName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteKeyPairOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKeyPairOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteNatGateway. +type DeleteNatGatewayInput struct { + _ struct{} `type:"structure"` + + // The ID of the NAT gateway. + NatGatewayId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteNatGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNatGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteNatGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteNatGatewayInput"} + if s.NatGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("NatGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DeleteNatGateway. +type DeleteNatGatewayOutput struct { + _ struct{} `type:"structure"` + + // The ID of the NAT gateway. + NatGatewayId *string `locationName:"natGatewayId" type:"string"` +} + +// String returns the string representation +func (s DeleteNatGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNatGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteNetworkAclEntry. +type DeleteNetworkAclEntryInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Indicates whether the rule is an egress rule. + Egress *bool `locationName:"egress" type:"boolean" required:"true"` + + // The ID of the network ACL. + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` + + // The rule number of the entry to delete. + RuleNumber *int64 `locationName:"ruleNumber" type:"integer" required:"true"` +} + +// String returns the string representation +func (s DeleteNetworkAclEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkAclEntryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteNetworkAclEntryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteNetworkAclEntryInput"} + if s.Egress == nil { + invalidParams.Add(request.NewErrParamRequired("Egress")) + } + if s.NetworkAclId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkAclId")) + } + if s.RuleNumber == nil { + invalidParams.Add(request.NewErrParamRequired("RuleNumber")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteNetworkAclEntryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteNetworkAclEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkAclEntryOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteNetworkAcl. +type DeleteNetworkAclInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the network ACL. + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteNetworkAclInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkAclInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteNetworkAclInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteNetworkAclInput"} + if s.NetworkAclId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkAclId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteNetworkAclOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteNetworkAclOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkAclOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteNetworkInterface. +type DeleteNetworkInterfaceInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkInterfaceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteNetworkInterfaceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteNetworkInterfaceInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteNetworkInterfaceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkInterfaceOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeletePlacementGroup. +type DeletePlacementGroupInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The name of the placement group. + GroupName *string `locationName:"groupName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeletePlacementGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeletePlacementGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeletePlacementGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeletePlacementGroupInput"} + if s.GroupName == nil { + invalidParams.Add(request.NewErrParamRequired("GroupName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeletePlacementGroupOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeletePlacementGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeletePlacementGroupOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteRoute. +type DeleteRouteInput struct { + _ struct{} `type:"structure"` + + // The CIDR range for the route. The value you specify must match the CIDR for + // the route exactly. + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the route table. + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteRouteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteRouteInput"} + if s.DestinationCidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("DestinationCidrBlock")) + } + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteRouteOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteRouteTable. +type DeleteRouteTableInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the route table. + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteRouteTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteRouteTableInput"} + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteRouteTableOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteTableOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteSecurityGroup. +type DeleteSecurityGroupInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the security group. Required for a nondefault VPC. + GroupId *string `type:"string"` + + // [EC2-Classic, default VPC] The name of the security group. You can specify + // either the security group name or the security group ID. + GroupName *string `type:"string"` +} + +// String returns the string representation +func (s DeleteSecurityGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSecurityGroupInput) GoString() string { + return s.String() +} + +type DeleteSecurityGroupOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteSecurityGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSecurityGroupOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteSnapshot. +type DeleteSnapshotInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the EBS snapshot. + SnapshotId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteSnapshotInput"} + if s.SnapshotId == nil { + invalidParams.Add(request.NewErrParamRequired("SnapshotId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteSnapshotOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSnapshotOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteSpotDatafeedSubscription. +type DeleteSpotDatafeedSubscriptionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s DeleteSpotDatafeedSubscriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSpotDatafeedSubscriptionInput) GoString() string { + return s.String() +} + +type DeleteSpotDatafeedSubscriptionOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteSpotDatafeedSubscriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSpotDatafeedSubscriptionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteSubnet. +type DeleteSubnetInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the subnet. + SubnetId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteSubnetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSubnetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteSubnetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteSubnetInput"} + if s.SubnetId == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteSubnetOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteSubnetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSubnetOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteTags. +type DeleteTagsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the resource. For example, ami-1a2b3c4d. You can specify more than + // one resource ID. + Resources []*string `locationName:"resourceId" type:"list" required:"true"` + + // One or more tags to delete. If you omit the value parameter, we delete the + // tag regardless of its value. If you specify this parameter with an empty + // string as the value, we delete the key only if its value is an empty string. + Tags []*Tag `locationName:"tag" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DeleteTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTagsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteTagsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteTagsInput"} + if s.Resources == nil { + invalidParams.Add(request.NewErrParamRequired("Resources")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteTagsOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTagsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVolume. +type DeleteVolumeInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVolumeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVolumeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVolumeInput"} + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteVolumeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteVolumeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVolumeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVpcEndpoints. +type DeleteVpcEndpointsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more endpoint IDs. + VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s DeleteVpcEndpointsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpcEndpointsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpcEndpointsInput"} + if s.VpcEndpointIds == nil { + invalidParams.Add(request.NewErrParamRequired("VpcEndpointIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DeleteVpcEndpoints. +type DeleteVpcEndpointsOutput struct { + _ struct{} `type:"structure"` + + // Information about the endpoints that were not successfully deleted. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DeleteVpcEndpointsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVpc. +type DeleteVpcInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpcInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpcInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteVpcOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVpcPeeringConnection. +type DeleteVpcPeeringConnectionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpcPeeringConnectionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpcPeeringConnectionInput"} + if s.VpcPeeringConnectionId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcPeeringConnectionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DeleteVpcPeeringConnection. +type DeleteVpcPeeringConnectionOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s DeleteVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVpnConnection. +type DeleteVpnConnectionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPN connection. + VpnConnectionId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteVpnConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnConnectionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpnConnectionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpnConnectionInput"} + if s.VpnConnectionId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnConnectionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteVpnConnectionOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteVpnConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnConnectionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVpnConnectionRoute. +type DeleteVpnConnectionRouteInput struct { + _ struct{} `type:"structure"` + + // The CIDR block associated with the local subnet of the customer network. + DestinationCidrBlock *string `type:"string" required:"true"` + + // The ID of the VPN connection. + VpnConnectionId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteVpnConnectionRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnConnectionRouteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpnConnectionRouteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpnConnectionRouteInput"} + if s.DestinationCidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("DestinationCidrBlock")) + } + if s.VpnConnectionId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnConnectionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteVpnConnectionRouteOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteVpnConnectionRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnConnectionRouteOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeleteVpnGateway. +type DeleteVpnGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the virtual private gateway. + VpnGatewayId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpnGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpnGatewayInput"} + if s.VpnGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteVpnGatewayOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteVpnGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DeregisterImage. +type DeregisterImageInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the AMI. + ImageId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeregisterImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeregisterImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeregisterImageInput"} + if s.ImageId == nil { + invalidParams.Add(request.NewErrParamRequired("ImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeregisterImageOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeregisterImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterImageOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeAccountAttributes. +type DescribeAccountAttributesInput struct { + _ struct{} `type:"structure"` + + // One or more account attribute names. + AttributeNames []*string `locationName:"attributeName" locationNameList:"attributeName" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s DescribeAccountAttributesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAccountAttributesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeAccountAttributes. +type DescribeAccountAttributesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more account attributes. + AccountAttributes []*AccountAttribute `locationName:"accountAttributeSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeAccountAttributesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAccountAttributesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeAddresses. +type DescribeAddressesInput struct { + _ struct{} `type:"structure"` + + // [EC2-VPC] One or more allocation IDs. + // + // Default: Describes all your Elastic IP addresses. + AllocationIds []*string `locationName:"AllocationId" locationNameList:"AllocationId" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. Filter names and values are case-sensitive. + // + // allocation-id - [EC2-VPC] The allocation ID for the address. + // + // association-id - [EC2-VPC] The association ID for the address. + // + // domain - Indicates whether the address is for use in EC2-Classic (standard) + // or in a VPC (vpc). + // + // instance-id - The ID of the instance the address is associated with, + // if any. + // + // network-interface-id - [EC2-VPC] The ID of the network interface that + // the address is associated with, if any. + // + // network-interface-owner-id - The AWS account ID of the owner. + // + // private-ip-address - [EC2-VPC] The private IP address associated with + // the Elastic IP address. + // + // public-ip - The Elastic IP address. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // [EC2-Classic] One or more Elastic IP addresses. + // + // Default: Describes all your Elastic IP addresses. + PublicIps []*string `locationName:"PublicIp" locationNameList:"PublicIp" type:"list"` +} + +// String returns the string representation +func (s DescribeAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAddressesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeAddresses. +type DescribeAddressesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more Elastic IP addresses. + Addresses []*Address `locationName:"addressesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAddressesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeAvailabilityZones. +type DescribeAvailabilityZonesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // message - Information about the Availability Zone. + // + // region-name - The name of the region for the Availability Zone (for example, + // us-east-1). + // + // state - The state of the Availability Zone (available | information | + // impaired | unavailable). + // + // zone-name - The name of the Availability Zone (for example, us-east-1a). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The names of one or more Availability Zones. + ZoneNames []*string `locationName:"ZoneName" locationNameList:"ZoneName" type:"list"` +} + +// String returns the string representation +func (s DescribeAvailabilityZonesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAvailabilityZonesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeAvailabiltyZones. +type DescribeAvailabilityZonesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more Availability Zones. + AvailabilityZones []*AvailabilityZone `locationName:"availabilityZoneInfo" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeAvailabilityZonesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAvailabilityZonesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeBundleTasks. +type DescribeBundleTasksInput struct { + _ struct{} `type:"structure"` + + // One or more bundle task IDs. + // + // Default: Describes all your bundle tasks. + BundleIds []*string `locationName:"BundleId" locationNameList:"BundleId" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // bundle-id - The ID of the bundle task. + // + // error-code - If the task failed, the error code returned. + // + // error-message - If the task failed, the error message returned. + // + // instance-id - The ID of the instance. + // + // progress - The level of task completion, as a percentage (for example, + // 20%). + // + // s3-bucket - The Amazon S3 bucket to store the AMI. + // + // s3-prefix - The beginning of the AMI name. + // + // start-time - The time the task started (for example, 2013-09-15T17:15:20.000Z). + // + // state - The state of the task (pending | waiting-for-shutdown | bundling + // | storing | cancelling | complete | failed). + // + // update-time - The time of the most recent update for the task. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` +} + +// String returns the string representation +func (s DescribeBundleTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeBundleTasksInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeBundleTasks. +type DescribeBundleTasksOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more bundle tasks. + BundleTasks []*BundleTask `locationName:"bundleInstanceTasksSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeBundleTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeBundleTasksOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeClassicLinkInstances. +type DescribeClassicLinkInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // group-id - The ID of a VPC security group that's associated with the + // instance. + // + // instance-id - The ID of the instance. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-id - The ID of the VPC that the instance is linked to. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more instance IDs. Must be instances linked to a VPC through ClassicLink. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results of the initial request can be seen by sending another + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. You cannot specify this parameter and the instance IDs parameter + // in the same request. + // + // Constraint: If the value is greater than 1000, we return only 1000 items. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeClassicLinkInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeClassicLinkInstancesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeClassicLinkInstances. +type DescribeClassicLinkInstancesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more linked EC2-Classic instances. + Instances []*ClassicLinkInstance `locationName:"instancesSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeClassicLinkInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeClassicLinkInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeConversionTasks. +type DescribeConversionTasksInput struct { + _ struct{} `type:"structure"` + + // One or more conversion task IDs. + ConversionTaskIds []*string `locationName:"conversionTaskId" locationNameList:"item" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + Filters []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"` +} + +// String returns the string representation +func (s DescribeConversionTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeConversionTasksInput) GoString() string { + return s.String() +} + +// Contains the output for DescribeConversionTasks. +type DescribeConversionTasksOutput struct { + _ struct{} `type:"structure"` + + // Information about the conversion tasks. + ConversionTasks []*ConversionTask `locationName:"conversionTasks" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeConversionTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeConversionTasksOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeCustomerGateways. +type DescribeCustomerGatewaysInput struct { + _ struct{} `type:"structure"` + + // One or more customer gateway IDs. + // + // Default: Describes all your customer gateways. + CustomerGatewayIds []*string `locationName:"CustomerGatewayId" locationNameList:"CustomerGatewayId" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // bgp-asn - The customer gateway's Border Gateway Protocol (BGP) Autonomous + // System Number (ASN). + // + // customer-gateway-id - The ID of the customer gateway. + // + // ip-address - The IP address of the customer gateway's Internet-routable + // external interface. + // + // state - The state of the customer gateway (pending | available | deleting + // | deleted). + // + // type - The type of customer gateway. Currently, the only supported type + // is ipsec.1. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` +} + +// String returns the string representation +func (s DescribeCustomerGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCustomerGatewaysInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeCustomerGateways. +type DescribeCustomerGatewaysOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more customer gateways. + CustomerGateways []*CustomerGateway `locationName:"customerGatewaySet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeCustomerGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCustomerGatewaysOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeDhcpOptions. +type DescribeDhcpOptionsInput struct { + _ struct{} `type:"structure"` + + // The IDs of one or more DHCP options sets. + // + // Default: Describes all your DHCP options sets. + DhcpOptionsIds []*string `locationName:"DhcpOptionsId" locationNameList:"DhcpOptionsId" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // dhcp-options-id - The ID of a set of DHCP options. + // + // key - The key for one of the options (for example, domain-name). + // + // value - The value for one of the options. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` +} + +// String returns the string representation +func (s DescribeDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeDhcpOptionsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeDhcpOptions. +type DescribeDhcpOptionsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more DHCP options sets. + DhcpOptions []*DhcpOptions `locationName:"dhcpOptionsSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeDhcpOptionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeExportTasks. +type DescribeExportTasksInput struct { + _ struct{} `type:"structure"` + + // One or more export task IDs. + ExportTaskIds []*string `locationName:"exportTaskId" locationNameList:"ExportTaskId" type:"list"` +} + +// String returns the string representation +func (s DescribeExportTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeExportTasksInput) GoString() string { + return s.String() +} + +// Contains the output for DescribeExportTasks. +type DescribeExportTasksOutput struct { + _ struct{} `type:"structure"` + + // Information about the export tasks. + ExportTasks []*ExportTask `locationName:"exportTaskSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeExportTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeExportTasksOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeFlowLogs. +type DescribeFlowLogsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // deliver-log-status - The status of the logs delivery (SUCCESS | FAILED). + // + // flow-log-id - The ID of the flow log. + // + // log-group-name - The name of the log group. + // + // resource-id - The ID of the VPC, subnet, or network interface. + // + // traffic-type - The type of traffic (ACCEPT | REJECT | ALL) + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // One or more flow log IDs. + FlowLogIds []*string `locationName:"FlowLogId" locationNameList:"item" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // NextToken value. This value can be between 5 and 1000; if MaxResults is given + // a value larger than 1000, only 1000 results are returned. You cannot specify + // this parameter and the flow log IDs parameter in the same request. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeFlowLogsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFlowLogsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeFlowLogs. +type DescribeFlowLogsOutput struct { + _ struct{} `type:"structure"` + + // Information about the flow logs. + FlowLogs []*FlowLog `locationName:"flowLogSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeFlowLogsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFlowLogsOutput) GoString() string { + return s.String() +} + +type DescribeHostReservationOfferingsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // instance-family - The instance family of the offering (e.g., m4). + // + // payment-option - The payment option (No Upfront | Partial Upfront | All + // Upfront). + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // This is the maximum duration of the reservation you'd like to purchase, specified + // in seconds. Reservations are available in one-year and three-year terms. + // The number of seconds specified must be the number of seconds in a year (365x24x60x60) + // times one of the supported durations (1 or 3). For example, specify 94608000 + // for three years. + MaxDuration *int64 `type:"integer"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // nextToken value. This value can be between 5 and 500; if maxResults is given + // a larger value than 500, you will receive an error. + MaxResults *int64 `type:"integer"` + + // This is the minimum duration of the reservation you'd like to purchase, specified + // in seconds. Reservations are available in one-year and three-year terms. + // The number of seconds specified must be the number of seconds in a year (365x24x60x60) + // times one of the supported durations (1 or 3). For example, specify 31536000 + // for one year. + MinDuration *int64 `type:"integer"` + + // The token to use to retrieve the next page of results. + NextToken *string `type:"string"` + + // The ID of the reservation offering. + OfferingId *string `type:"string"` +} + +// String returns the string representation +func (s DescribeHostReservationOfferingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationOfferingsInput) GoString() string { + return s.String() +} + +type DescribeHostReservationOfferingsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the offerings. + OfferingSet []*HostOffering `locationName:"offeringSet" type:"list"` +} + +// String returns the string representation +func (s DescribeHostReservationOfferingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationOfferingsOutput) GoString() string { + return s.String() +} + +type DescribeHostReservationsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // instance-family - The instance family (e.g., m4). + // + // payment-option - The payment option (No Upfront | Partial Upfront | All + // Upfront). + // + // state - The state of the reservation (payment-pending | payment-failed + // | active | retired). + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // One or more host reservation IDs. + HostReservationIdSet []*string `locationNameList:"item" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // nextToken value. This value can be between 5 and 500; if maxResults is given + // a larger value than 500, you will receive an error. + MaxResults *int64 `type:"integer"` + + // The token to use to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeHostReservationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationsInput) GoString() string { + return s.String() +} + +type DescribeHostReservationsOutput struct { + _ struct{} `type:"structure"` + + // Details about the reservation's configuration. + HostReservationSet []*HostReservation `locationName:"hostReservationSet" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeHostReservationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeHosts. +type DescribeHostsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // instance-type - The instance type size that the Dedicated Host is configured + // to support. + // + // auto-placement - Whether auto-placement is enabled or disabled (on | + // off). + // + // host-reservation-id - The ID of the reservation assigned to this host. + // + // client-token - The idempotency token you provided when you launched the + // instance + // + // state- The allocation state of the Dedicated Host (available | under-assessment + // | permanent-failure | released | released-permanent-failure). + // + // availability-zone - The Availability Zone of the host. + Filter []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"` + + // The IDs of the Dedicated Hosts. The IDs are used for targeted instance launches. + HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // nextToken value. This value can be between 5 and 500; if maxResults is given + // a larger value than 500, you will receive an error. You cannot specify this + // parameter and the host IDs parameter in the same request. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeHostsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeHosts. +type DescribeHostsOutput struct { + _ struct{} `type:"structure"` + + // Information about the Dedicated Hosts. + Hosts []*Host `locationName:"hostSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeHostsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeIdFormat. +type DescribeIdFormatInput struct { + _ struct{} `type:"structure"` + + // The type of resource: instance | reservation | snapshot | volume + Resource *string `type:"string"` +} + +// String returns the string representation +func (s DescribeIdFormatInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeIdFormatInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeIdFormat. +type DescribeIdFormatOutput struct { + _ struct{} `type:"structure"` + + // Information about the ID format for the resource. + Statuses []*IdFormat `locationName:"statusSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeIdFormatOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeIdFormatOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeIdentityIdFormat. +type DescribeIdentityIdFormatInput struct { + _ struct{} `type:"structure"` + + // The ARN of the principal, which can be an IAM role, IAM user, or the root + // user. + PrincipalArn *string `locationName:"principalArn" type:"string" required:"true"` + + // The type of resource: instance | reservation | snapshot | volume + Resource *string `locationName:"resource" type:"string"` +} + +// String returns the string representation +func (s DescribeIdentityIdFormatInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeIdentityIdFormatInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeIdentityIdFormatInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeIdentityIdFormatInput"} + if s.PrincipalArn == nil { + invalidParams.Add(request.NewErrParamRequired("PrincipalArn")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeIdentityIdFormat. +type DescribeIdentityIdFormatOutput struct { + _ struct{} `type:"structure"` + + // Information about the ID format for the resources. + Statuses []*IdFormat `locationName:"statusSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeIdentityIdFormatOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeIdentityIdFormatOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeImageAttribute. +type DescribeImageAttributeInput struct { + _ struct{} `type:"structure"` + + // The AMI attribute. + // + // Note: Depending on your account privileges, the blockDeviceMapping attribute + // may return a Client.AuthFailure error. If this happens, use DescribeImages + // to get information about the block device mapping for the AMI. + Attribute *string `type:"string" required:"true" enum:"ImageAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the AMI. + ImageId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImageAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeImageAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeImageAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.ImageId == nil { + invalidParams.Add(request.NewErrParamRequired("ImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes an image attribute. +type DescribeImageAttributeOutput struct { + _ struct{} `type:"structure"` + + // One or more block device mapping entries. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // A description for the AMI. + Description *AttributeValue `locationName:"description" type:"structure"` + + // The ID of the AMI. + ImageId *string `locationName:"imageId" type:"string"` + + // The kernel ID. + KernelId *AttributeValue `locationName:"kernel" type:"structure"` + + // One or more launch permissions. + LaunchPermissions []*LaunchPermission `locationName:"launchPermission" locationNameList:"item" type:"list"` + + // One or more product codes. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // The RAM disk ID. + RamdiskId *AttributeValue `locationName:"ramdisk" type:"structure"` + + // Indicates whether enhanced networking with the Intel 82599 Virtual Function + // interface is enabled. + SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` +} + +// String returns the string representation +func (s DescribeImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImageAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeImages. +type DescribeImagesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Scopes the images by users with explicit launch permissions. Specify an AWS + // account ID, self (the sender of the request), or all (public AMIs). + ExecutableUsers []*string `locationName:"ExecutableBy" locationNameList:"ExecutableBy" type:"list"` + + // One or more filters. + // + // architecture - The image architecture (i386 | x86_64). + // + // block-device-mapping.delete-on-termination - A Boolean value that indicates + // whether the Amazon EBS volume is deleted on instance termination. + // + // block-device-mapping.device-name - The device name for the EBS volume + // (for example, /dev/sdh). + // + // block-device-mapping.snapshot-id - The ID of the snapshot used for the + // EBS volume. + // + // block-device-mapping.volume-size - The volume size of the EBS volume, + // in GiB. + // + // block-device-mapping.volume-type - The volume type of the EBS volume + // (gp2 | io1 | st1 | sc1 | standard). + // + // description - The description of the image (provided during image creation). + // + // hypervisor - The hypervisor type (ovm | xen). + // + // image-id - The ID of the image. + // + // image-type - The image type (machine | kernel | ramdisk). + // + // is-public - A Boolean that indicates whether the image is public. + // + // kernel-id - The kernel ID. + // + // manifest-location - The location of the image manifest. + // + // name - The name of the AMI (provided during image creation). + // + // owner-alias - String value from an Amazon-maintained list (amazon | aws-marketplace + // | microsoft) of snapshot owners. Not to be confused with the user-configured + // AWS account alias, which is set from the IAM console. + // + // owner-id - The AWS account ID of the image owner. + // + // platform - The platform. To only list Windows-based AMIs, use windows. + // + // product-code - The product code. + // + // product-code.type - The type of the product code (devpay | marketplace). + // + // ramdisk-id - The RAM disk ID. + // + // root-device-name - The name of the root device volume (for example, /dev/sda1). + // + // root-device-type - The type of the root device volume (ebs | instance-store). + // + // state - The state of the image (available | pending | failed). + // + // state-reason-code - The reason code for the state change. + // + // state-reason-message - The message for the state change. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // virtualization-type - The virtualization type (paravirtual | hvm). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more image IDs. + // + // Default: Describes all images available to you. + ImageIds []*string `locationName:"ImageId" locationNameList:"ImageId" type:"list"` + + // Filters the images by the owner. Specify an AWS account ID, self (owner is + // the sender of the request), or an AWS owner alias (valid values are amazon + // | aws-marketplace | microsoft). Omitting this option returns all images for + // which you have launch permissions, regardless of ownership. + Owners []*string `locationName:"Owner" locationNameList:"Owner" type:"list"` +} + +// String returns the string representation +func (s DescribeImagesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImagesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeImages. +type DescribeImagesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more images. + Images []*Image `locationName:"imagesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeImagesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImagesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeImportImageTasks. +type DescribeImportImageTasksInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // Filter tasks using the task-state filter and one of the following values: + // active, completed, deleting, deleted. + Filters []*Filter `locationNameList:"Filter" type:"list"` + + // A list of import image task IDs. + ImportTaskIds []*string `locationName:"ImportTaskId" locationNameList:"ImportTaskId" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. + MaxResults *int64 `type:"integer"` + + // A token that indicates the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeImportImageTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportImageTasksInput) GoString() string { + return s.String() +} + +// Contains the output for DescribeImportImageTasks. +type DescribeImportImageTasksOutput struct { + _ struct{} `type:"structure"` + + // A list of zero or more import image tasks that are currently active or were + // completed or canceled in the previous 7 days. + ImportImageTasks []*ImportImageTask `locationName:"importImageTaskSet" locationNameList:"item" type:"list"` + + // The token to use to get the next page of results. This value is null when + // there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeImportImageTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportImageTasksOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeImportSnapshotTasks. +type DescribeImportSnapshotTasksInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + Filters []*Filter `locationNameList:"Filter" type:"list"` + + // A list of import snapshot task IDs. + ImportTaskIds []*string `locationName:"ImportTaskId" locationNameList:"ImportTaskId" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. + MaxResults *int64 `type:"integer"` + + // A token that indicates the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeImportSnapshotTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportSnapshotTasksInput) GoString() string { + return s.String() +} + +// Contains the output for DescribeImportSnapshotTasks. +type DescribeImportSnapshotTasksOutput struct { + _ struct{} `type:"structure"` + + // A list of zero or more import snapshot tasks that are currently active or + // were completed or canceled in the previous 7 days. + ImportSnapshotTasks []*ImportSnapshotTask `locationName:"importSnapshotTaskSet" locationNameList:"item" type:"list"` + + // The token to use to get the next page of results. This value is null when + // there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeImportSnapshotTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportSnapshotTasksOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeInstanceAttribute. +type DescribeInstanceAttributeInput struct { + _ struct{} `type:"structure"` + + // The instance attribute. + // + // Note: The enaSupport attribute is not supported at this time. + Attribute *string `locationName:"attribute" type:"string" required:"true" enum:"InstanceAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeInstanceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeInstanceAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeInstanceAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes an instance attribute. +type DescribeInstanceAttributeOutput struct { + _ struct{} `type:"structure"` + + // The block device mapping of the instance. + BlockDeviceMappings []*InstanceBlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // If the value is true, you can't terminate the instance through the Amazon + // EC2 console, CLI, or API; otherwise, you can. + DisableApiTermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` + + // Indicates whether the instance is optimized for EBS I/O. + EbsOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` + + // Indicates whether enhanced networking with ENA is enabled. + EnaSupport *AttributeBooleanValue `locationName:"enaSupport" type:"structure"` + + // The security groups associated with the instance. + Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // Indicates whether an instance stops or terminates when you initiate shutdown + // from the instance (using the operating system command for system shutdown). + InstanceInitiatedShutdownBehavior *AttributeValue `locationName:"instanceInitiatedShutdownBehavior" type:"structure"` + + // The instance type. + InstanceType *AttributeValue `locationName:"instanceType" type:"structure"` + + // The kernel ID. + KernelId *AttributeValue `locationName:"kernel" type:"structure"` + + // A list of product codes. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // The RAM disk ID. + RamdiskId *AttributeValue `locationName:"ramdisk" type:"structure"` + + // The name of the root device (for example, /dev/sda1 or /dev/xvda). + RootDeviceName *AttributeValue `locationName:"rootDeviceName" type:"structure"` + + // Indicates whether source/destination checking is enabled. A value of true + // means checking is enabled, and false means checking is disabled. This value + // must be false for a NAT instance to perform NAT. + SourceDestCheck *AttributeBooleanValue `locationName:"sourceDestCheck" type:"structure"` + + // Indicates whether enhanced networking with the Intel 82599 Virtual Function + // interface is enabled. + SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` + + // The user data. + UserData *AttributeValue `locationName:"userData" type:"structure"` +} + +// String returns the string representation +func (s DescribeInstanceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeInstanceStatus. +type DescribeInstanceStatusInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // availability-zone - The Availability Zone of the instance. + // + // event.code - The code for the scheduled event (instance-reboot | system-reboot + // | system-maintenance | instance-retirement | instance-stop). + // + // event.description - A description of the event. + // + // event.not-after - The latest end time for the scheduled event (for example, + // 2014-09-15T17:15:20.000Z). + // + // event.not-before - The earliest start time for the scheduled event (for + // example, 2014-09-15T17:15:20.000Z). + // + // instance-state-code - The code for the instance state, as a 16-bit unsigned + // integer. The high byte is an opaque internal value and should be ignored. + // The low byte is set based on the state represented. The valid values are + // 0 (pending), 16 (running), 32 (shutting-down), 48 (terminated), 64 (stopping), + // and 80 (stopped). + // + // instance-state-name - The state of the instance (pending | running | + // shutting-down | terminated | stopping | stopped). + // + // instance-status.reachability - Filters on instance status where the name + // is reachability (passed | failed | initializing | insufficient-data). + // + // instance-status.status - The status of the instance (ok | impaired | + // initializing | insufficient-data | not-applicable). + // + // system-status.reachability - Filters on system status where the name + // is reachability (passed | failed | initializing | insufficient-data). + // + // system-status.status - The system status of the instance (ok | impaired + // | initializing | insufficient-data | not-applicable). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // When true, includes the health status for all instances. When false, includes + // the health status for running instances only. + // + // Default: false + IncludeAllInstances *bool `locationName:"includeAllInstances" type:"boolean"` + + // One or more instance IDs. + // + // Default: Describes all your instances. + // + // Constraints: Maximum 100 explicitly specified instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. This + // value can be between 5 and 1000. You cannot specify this parameter and the + // instance IDs parameter in the same call. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeInstanceStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceStatusInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeInstanceStatus. +type DescribeInstanceStatusOutput struct { + _ struct{} `type:"structure"` + + // One or more instance status descriptions. + InstanceStatuses []*InstanceStatus `locationName:"instanceStatusSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeInstanceStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceStatusOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeInstances. +type DescribeInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // affinity - The affinity setting for an instance running on a Dedicated + // Host (default | host). + // + // architecture - The instance architecture (i386 | x86_64). + // + // availability-zone - The Availability Zone of the instance. + // + // block-device-mapping.attach-time - The attach time for an EBS volume + // mapped to the instance, for example, 2010-09-15T17:15:20.000Z. + // + // block-device-mapping.delete-on-termination - A Boolean that indicates + // whether the EBS volume is deleted on instance termination. + // + // block-device-mapping.device-name - The device name for the EBS volume + // (for example, /dev/sdh or xvdh). + // + // block-device-mapping.status - The status for the EBS volume (attaching + // | attached | detaching | detached). + // + // block-device-mapping.volume-id - The volume ID of the EBS volume. + // + // client-token - The idempotency token you provided when you launched the + // instance. + // + // dns-name - The public DNS name of the instance. + // + // group-id - The ID of the security group for the instance. EC2-Classic + // only. + // + // group-name - The name of the security group for the instance. EC2-Classic + // only. + // + // host-id - The ID of the Dedicated Host on which the instance is running, + // if applicable. + // + // hypervisor - The hypervisor type of the instance (ovm | xen). + // + // iam-instance-profile.arn - The instance profile associated with the instance. + // Specified as an ARN. + // + // image-id - The ID of the image used to launch the instance. + // + // instance-id - The ID of the instance. + // + // instance-lifecycle - Indicates whether this is a Spot Instance or a Scheduled + // Instance (spot | scheduled). + // + // instance-state-code - The state of the instance, as a 16-bit unsigned + // integer. The high byte is an opaque internal value and should be ignored. + // The low byte is set based on the state represented. The valid values are: + // 0 (pending), 16 (running), 32 (shutting-down), 48 (terminated), 64 (stopping), + // and 80 (stopped). + // + // instance-state-name - The state of the instance (pending | running | + // shutting-down | terminated | stopping | stopped). + // + // instance-type - The type of instance (for example, t2.micro). + // + // instance.group-id - The ID of the security group for the instance. + // + // instance.group-name - The name of the security group for the instance. + // + // ip-address - The public IP address of the instance. + // + // kernel-id - The kernel ID. + // + // key-name - The name of the key pair used when the instance was launched. + // + // launch-index - When launching multiple instances, this is the index for + // the instance in the launch group (for example, 0, 1, 2, and so on). + // + // launch-time - The time when the instance was launched. + // + // monitoring-state - Indicates whether monitoring is enabled for the instance + // (disabled | enabled). + // + // owner-id - The AWS account ID of the instance owner. + // + // placement-group-name - The name of the placement group for the instance. + // + // platform - The platform. Use windows if you have Windows instances; otherwise, + // leave blank. + // + // private-dns-name - The private DNS name of the instance. + // + // private-ip-address - The private IP address of the instance. + // + // product-code - The product code associated with the AMI used to launch + // the instance. + // + // product-code.type - The type of product code (devpay | marketplace). + // + // ramdisk-id - The RAM disk ID. + // + // reason - The reason for the current state of the instance (for example, + // shows "User Initiated [date]" when you stop or terminate the instance). Similar + // to the state-reason-code filter. + // + // requester-id - The ID of the entity that launched the instance on your + // behalf (for example, AWS Management Console, Auto Scaling, and so on). + // + // reservation-id - The ID of the instance's reservation. A reservation + // ID is created any time you launch an instance. A reservation ID has a one-to-one + // relationship with an instance launch request, but can be associated with + // more than one instance if you launch multiple instances using the same launch + // request. For example, if you launch one instance, you'll get one reservation + // ID. If you launch ten instances using the same launch request, you'll also + // get one reservation ID. + // + // root-device-name - The name of the root device for the instance (for + // example, /dev/sda1 or /dev/xvda). + // + // root-device-type - The type of root device that the instance uses (ebs + // | instance-store). + // + // source-dest-check - Indicates whether the instance performs source/destination + // checking. A value of true means that checking is enabled, and false means + // checking is disabled. The value must be false for the instance to perform + // network address translation (NAT) in your VPC. + // + // spot-instance-request-id - The ID of the Spot instance request. + // + // state-reason-code - The reason code for the state change. + // + // state-reason-message - A message that describes the state change. + // + // subnet-id - The ID of the subnet for the instance. + // + // tag:key=value - The key/value combination of a tag assigned to the resource, + // where tag:key is the tag's key. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // tenancy - The tenancy of an instance (dedicated | default | host). + // + // virtualization-type - The virtualization type of the instance (paravirtual + // | hvm). + // + // vpc-id - The ID of the VPC that the instance is running in. + // + // network-interface.description - The description of the network interface. + // + // network-interface.subnet-id - The ID of the subnet for the network interface. + // + // network-interface.vpc-id - The ID of the VPC for the network interface. + // + // network-interface.network-interface-id - The ID of the network interface. + // + // network-interface.owner-id - The ID of the owner of the network interface. + // + // network-interface.availability-zone - The Availability Zone for the network + // interface. + // + // network-interface.requester-id - The requester ID for the network interface. + // + // network-interface.requester-managed - Indicates whether the network interface + // is being managed by AWS. + // + // network-interface.status - The status of the network interface (available) + // | in-use). + // + // network-interface.mac-address - The MAC address of the network interface. + // + // network-interface.private-dns-name - The private DNS name of the network + // interface. + // + // network-interface.source-dest-check - Whether the network interface performs + // source/destination checking. A value of true means checking is enabled, and + // false means checking is disabled. The value must be false for the network + // interface to perform network address translation (NAT) in your VPC. + // + // network-interface.group-id - The ID of a security group associated with + // the network interface. + // + // network-interface.group-name - The name of a security group associated + // with the network interface. + // + // network-interface.attachment.attachment-id - The ID of the interface + // attachment. + // + // network-interface.attachment.instance-id - The ID of the instance to + // which the network interface is attached. + // + // network-interface.attachment.instance-owner-id - The owner ID of the + // instance to which the network interface is attached. + // + // network-interface.addresses.private-ip-address - The private IP address + // associated with the network interface. + // + // network-interface.attachment.device-index - The device index to which + // the network interface is attached. + // + // network-interface.attachment.status - The status of the attachment (attaching + // | attached | detaching | detached). + // + // network-interface.attachment.attach-time - The time that the network + // interface was attached to an instance. + // + // network-interface.attachment.delete-on-termination - Specifies whether + // the attachment is deleted when an instance is terminated. + // + // network-interface.addresses.primary - Specifies whether the IP address + // of the network interface is the primary private IP address. + // + // network-interface.addresses.association.public-ip - The ID of the association + // of an Elastic IP address with a network interface. + // + // network-interface.addresses.association.ip-owner-id - The owner ID of + // the private IP address associated with the network interface. + // + // association.public-ip - The address of the Elastic IP address bound to + // the network interface. + // + // association.ip-owner-id - The owner of the Elastic IP address associated + // with the network interface. + // + // association.allocation-id - The allocation ID returned when you allocated + // the Elastic IP address for your network interface. + // + // association.association-id - The association ID returned when the network + // interface was associated with an IP address. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more instance IDs. + // + // Default: Describes all your instances. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. This + // value can be between 5 and 1000. You cannot specify this parameter and the + // instance IDs parameter or tag filters in the same call. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token to request the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstancesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeInstances. +type DescribeInstancesOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Zero or more reservations. + Reservations []*Reservation `locationName:"reservationSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeInternetGateways. +type DescribeInternetGatewaysInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // attachment.state - The current state of the attachment between the gateway + // and the VPC (available). Present only if a VPC is attached. + // + // attachment.vpc-id - The ID of an attached VPC. + // + // internet-gateway-id - The ID of the Internet gateway. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more Internet gateway IDs. + // + // Default: Describes all your Internet gateways. + InternetGatewayIds []*string `locationName:"internetGatewayId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeInternetGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInternetGatewaysInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeInternetGateways. +type DescribeInternetGatewaysOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more Internet gateways. + InternetGateways []*InternetGateway `locationName:"internetGatewaySet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeInternetGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInternetGatewaysOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeKeyPairs. +type DescribeKeyPairsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // fingerprint - The fingerprint of the key pair. + // + // key-name - The name of the key pair. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more key pair names. + // + // Default: Describes all your key pairs. + KeyNames []*string `locationName:"KeyName" locationNameList:"KeyName" type:"list"` +} + +// String returns the string representation +func (s DescribeKeyPairsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeKeyPairsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeKeyPairs. +type DescribeKeyPairsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more key pairs. + KeyPairs []*KeyPairInfo `locationName:"keySet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeKeyPairsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeKeyPairsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeMovingAddresses. +type DescribeMovingAddressesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // moving-status - The status of the Elastic IP address (MovingToVpc | RestoringToClassic). + Filters []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results of the initial request can be seen by sending another + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value outside of this range, an error is returned. + // + // Default: If no value is provided, the default is 1000. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token to use to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // One or more Elastic IP addresses. + PublicIps []*string `locationName:"publicIp" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeMovingAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeMovingAddressesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeMovingAddresses. +type DescribeMovingAddressesOutput struct { + _ struct{} `type:"structure"` + + // The status for each Elastic IP address. + MovingAddressStatuses []*MovingAddressStatus `locationName:"movingAddressStatusSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeMovingAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeMovingAddressesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeNatGateways. +type DescribeNatGatewaysInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // nat-gateway-id - The ID of the NAT gateway. + // + // state - The state of the NAT gateway (pending | failed | available | + // deleting | deleted). + // + // subnet-id - The ID of the subnet in which the NAT gateway resides. + // + // vpc-id - The ID of the VPC in which the NAT gateway resides. + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + // + // Constraint: If the value specified is greater than 1000, we return only + // 1000 items. + MaxResults *int64 `type:"integer"` + + // One or more NAT gateway IDs. + NatGatewayIds []*string `locationName:"NatGatewayId" locationNameList:"item" type:"list"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeNatGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNatGatewaysInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeNatGateways. +type DescribeNatGatewaysOutput struct { + _ struct{} `type:"structure"` + + // Information about the NAT gateways. + NatGateways []*NatGateway `locationName:"natGatewaySet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeNatGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNatGatewaysOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeNetworkAcls. +type DescribeNetworkAclsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // association.association-id - The ID of an association ID for the ACL. + // + // association.network-acl-id - The ID of the network ACL involved in the + // association. + // + // association.subnet-id - The ID of the subnet involved in the association. + // + // default - Indicates whether the ACL is the default network ACL for the + // VPC. + // + // entry.cidr - The CIDR range specified in the entry. + // + // entry.egress - Indicates whether the entry applies to egress traffic. + // + // entry.icmp.code - The ICMP code specified in the entry, if any. + // + // entry.icmp.type - The ICMP type specified in the entry, if any. + // + // entry.port-range.from - The start of the port range specified in the + // entry. + // + // entry.port-range.to - The end of the port range specified in the entry. + // + // entry.protocol - The protocol specified in the entry (tcp | udp | icmp + // or a protocol number). + // + // entry.rule-action - Allows or denies the matching traffic (allow | deny). + // + // entry.rule-number - The number of an entry (in other words, rule) in + // the ACL's set of entries. + // + // network-acl-id - The ID of the network ACL. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-id - The ID of the VPC for the network ACL. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more network ACL IDs. + // + // Default: Describes all your network ACLs. + NetworkAclIds []*string `locationName:"NetworkAclId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeNetworkAclsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkAclsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeNetworkAcls. +type DescribeNetworkAclsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more network ACLs. + NetworkAcls []*NetworkAcl `locationName:"networkAclSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeNetworkAclsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkAclsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeNetworkInterfaceAttribute. +type DescribeNetworkInterfaceAttributeInput struct { + _ struct{} `type:"structure"` + + // The attribute of the network interface. + Attribute *string `locationName:"attribute" type:"string" enum:"NetworkInterfaceAttribute"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeNetworkInterfaceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfaceAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeNetworkInterfaceAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeNetworkInterfaceAttributeInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeNetworkInterfaceAttribute. +type DescribeNetworkInterfaceAttributeOutput struct { + _ struct{} `type:"structure"` + + // The attachment (if any) of the network interface. + Attachment *NetworkInterfaceAttachment `locationName:"attachment" type:"structure"` + + // The description of the network interface. + Description *AttributeValue `locationName:"description" type:"structure"` + + // The security groups associated with the network interface. + Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // Indicates whether source/destination checking is enabled. + SourceDestCheck *AttributeBooleanValue `locationName:"sourceDestCheck" type:"structure"` +} + +// String returns the string representation +func (s DescribeNetworkInterfaceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfaceAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeNetworkInterfaces. +type DescribeNetworkInterfacesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // addresses.private-ip-address - The private IP addresses associated with + // the network interface. + // + // addresses.primary - Whether the private IP address is the primary IP + // address associated with the network interface. + // + // addresses.association.public-ip - The association ID returned when the + // network interface was associated with the Elastic IP address. + // + // addresses.association.owner-id - The owner ID of the addresses associated + // with the network interface. + // + // association.association-id - The association ID returned when the network + // interface was associated with an IP address. + // + // association.allocation-id - The allocation ID returned when you allocated + // the Elastic IP address for your network interface. + // + // association.ip-owner-id - The owner of the Elastic IP address associated + // with the network interface. + // + // association.public-ip - The address of the Elastic IP address bound to + // the network interface. + // + // association.public-dns-name - The public DNS name for the network interface. + // + // attachment.attachment-id - The ID of the interface attachment. + // + // attachment.attach.time - The time that the network interface was attached + // to an instance. + // + // attachment.delete-on-termination - Indicates whether the attachment is + // deleted when an instance is terminated. + // + // attachment.device-index - The device index to which the network interface + // is attached. + // + // attachment.instance-id - The ID of the instance to which the network + // interface is attached. + // + // attachment.instance-owner-id - The owner ID of the instance to which + // the network interface is attached. + // + // attachment.nat-gateway-id - The ID of the NAT gateway to which the network + // interface is attached. + // + // attachment.status - The status of the attachment (attaching | attached + // | detaching | detached). + // + // availability-zone - The Availability Zone of the network interface. + // + // description - The description of the network interface. + // + // group-id - The ID of a security group associated with the network interface. + // + // group-name - The name of a security group associated with the network + // interface. + // + // mac-address - The MAC address of the network interface. + // + // network-interface-id - The ID of the network interface. + // + // owner-id - The AWS account ID of the network interface owner. + // + // private-ip-address - The private IP address or addresses of the network + // interface. + // + // private-dns-name - The private DNS name of the network interface. + // + // requester-id - The ID of the entity that launched the instance on your + // behalf (for example, AWS Management Console, Auto Scaling, and so on). + // + // requester-managed - Indicates whether the network interface is being + // managed by an AWS service (for example, AWS Management Console, Auto Scaling, + // and so on). + // + // source-desk-check - Indicates whether the network interface performs + // source/destination checking. A value of true means checking is enabled, and + // false means checking is disabled. The value must be false for the network + // interface to perform network address translation (NAT) in your VPC. + // + // status - The status of the network interface. If the network interface + // is not attached to an instance, the status is available; if a network interface + // is attached to an instance the status is in-use. + // + // subnet-id - The ID of the subnet for the network interface. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-id - The ID of the VPC for the network interface. + Filters []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"` + + // One or more network interface IDs. + // + // Default: Describes all your network interfaces. + NetworkInterfaceIds []*string `locationName:"NetworkInterfaceId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeNetworkInterfacesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfacesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeNetworkInterfaces. +type DescribeNetworkInterfacesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more network interfaces. + NetworkInterfaces []*NetworkInterface `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeNetworkInterfacesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfacesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribePlacementGroups. +type DescribePlacementGroupsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // group-name - The name of the placement group. + // + // state - The state of the placement group (pending | available | deleting + // | deleted). + // + // strategy - The strategy of the placement group (cluster). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more placement group names. + // + // Default: Describes all your placement groups, or only those otherwise specified. + GroupNames []*string `locationName:"groupName" type:"list"` +} + +// String returns the string representation +func (s DescribePlacementGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePlacementGroupsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribePlacementGroups. +type DescribePlacementGroupsOutput struct { + _ struct{} `type:"structure"` + + // One or more placement groups. + PlacementGroups []*PlacementGroup `locationName:"placementGroupSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribePlacementGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePlacementGroupsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribePrefixLists. +type DescribePrefixListsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // prefix-list-id: The ID of a prefix list. + // + // prefix-list-name: The name of a prefix list. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + // + // Constraint: If the value specified is greater than 1000, we return only + // 1000 items. + MaxResults *int64 `type:"integer"` + + // The token for the next set of items to return. (You received this token from + // a prior call.) + NextToken *string `type:"string"` + + // One or more prefix list IDs. + PrefixListIds []*string `locationName:"PrefixListId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribePrefixListsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePrefixListsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribePrefixLists. +type DescribePrefixListsOutput struct { + _ struct{} `type:"structure"` + + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. + NextToken *string `locationName:"nextToken" type:"string"` + + // All available prefix lists. + PrefixLists []*PrefixList `locationName:"prefixListSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribePrefixListsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePrefixListsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeRegions. +type DescribeRegionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // endpoint - The endpoint of the region (for example, ec2.us-east-1.amazonaws.com). + // + // region-name - The name of the region (for example, us-east-1). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The names of one or more regions. + RegionNames []*string `locationName:"RegionName" locationNameList:"RegionName" type:"list"` +} + +// String returns the string representation +func (s DescribeRegionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRegionsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeRegions. +type DescribeRegionsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more regions. + Regions []*Region `locationName:"regionInfo" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeRegionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRegionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeReservedInstances. +type DescribeReservedInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // availability-zone - The Availability Zone where the Reserved Instance + // can be used. + // + // duration - The duration of the Reserved Instance (one year or three years), + // in seconds (31536000 | 94608000). + // + // end - The time when the Reserved Instance expires (for example, 2015-08-07T11:54:42.000Z). + // + // fixed-price - The purchase price of the Reserved Instance (for example, + // 9800.0). + // + // instance-type - The instance type that is covered by the reservation. + // + // product-description - The Reserved Instance product platform description. + // Instances that include (Amazon VPC) in the product platform description will + // only be displayed to EC2-Classic account holders and are for use with Amazon + // VPC (Linux/UNIX | Linux/UNIX (Amazon VPC) | SUSE Linux | SUSE Linux (Amazon + // VPC) | Red Hat Enterprise Linux | Red Hat Enterprise Linux (Amazon VPC) | + // Windows | Windows (Amazon VPC) | Windows with SQL Server Standard | Windows + // with SQL Server Standard (Amazon VPC) | Windows with SQL Server Web | Windows + // with SQL Server Web (Amazon VPC) | Windows with SQL Server Enterprise | Windows + // with SQL Server Enterprise (Amazon VPC)). + // + // reserved-instances-id - The ID of the Reserved Instance. + // + // start - The time at which the Reserved Instance purchase request was + // placed (for example, 2014-08-07T11:54:42.000Z). + // + // state - The state of the Reserved Instance (payment-pending | active + // | payment-failed | retired). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // usage-price - The usage price of the Reserved Instance, per hour (for + // example, 0.84). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The Reserved Instance offering type. If you are using tools that predate + // the 2011-11-01 API version, you only have access to the Medium Utilization + // Reserved Instance offering type. + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` + + // One or more Reserved Instance IDs. + // + // Default: Describes all your Reserved Instances, or only those otherwise + // specified. + ReservedInstancesIds []*string `locationName:"ReservedInstancesId" locationNameList:"ReservedInstancesId" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesInput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeReservedInstancesListings. +type DescribeReservedInstancesListingsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // reserved-instances-id - The ID of the Reserved Instances. + // + // reserved-instances-listing-id - The ID of the Reserved Instances listing. + // + // status - The status of the Reserved Instance listing (pending | active + // | cancelled | closed). + // + // status-message - The reason for the status. + Filters []*Filter `locationName:"filters" locationNameList:"Filter" type:"list"` + + // One or more Reserved Instance IDs. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` + + // One or more Reserved Instance listing IDs. + ReservedInstancesListingId *string `locationName:"reservedInstancesListingId" type:"string"` +} + +// String returns the string representation +func (s DescribeReservedInstancesListingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesListingsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeReservedInstancesListings. +type DescribeReservedInstancesListingsOutput struct { + _ struct{} `type:"structure"` + + // Information about the Reserved Instance listing. + ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesListingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesListingsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeReservedInstancesModifications. +type DescribeReservedInstancesModificationsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // client-token - The idempotency token for the modification request. + // + // create-date - The time when the modification request was created. + // + // effective-date - The time when the modification becomes effective. + // + // modification-result.reserved-instances-id - The ID for the Reserved Instances + // created as part of the modification request. This ID is only available when + // the status of the modification is fulfilled. + // + // modification-result.target-configuration.availability-zone - The Availability + // Zone for the new Reserved Instances. + // + // modification-result.target-configuration.instance-count - The number + // of new Reserved Instances. + // + // modification-result.target-configuration.instance-type - The instance + // type of the new Reserved Instances. + // + // modification-result.target-configuration.platform - The network platform + // of the new Reserved Instances (EC2-Classic | EC2-VPC). + // + // reserved-instances-id - The ID of the Reserved Instances modified. + // + // reserved-instances-modification-id - The ID of the modification request. + // + // status - The status of the Reserved Instances modification request (processing + // | fulfilled | failed). + // + // status-message - The reason for the status. + // + // update-date - The time when the modification request was last updated. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The token to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // IDs for the submitted modification request. + ReservedInstancesModificationIds []*string `locationName:"ReservedInstancesModificationId" locationNameList:"ReservedInstancesModificationId" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesModificationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesModificationsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeReservedInstancesModifications. +type DescribeReservedInstancesModificationsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // The Reserved Instance modification information. + ReservedInstancesModifications []*ReservedInstancesModification `locationName:"reservedInstancesModificationsSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesModificationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesModificationsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeReservedInstancesOfferings. +type DescribeReservedInstancesOfferingsInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which the Reserved Instance can be used. + AvailabilityZone *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // availability-zone - The Availability Zone where the Reserved Instance + // can be used. + // + // duration - The duration of the Reserved Instance (for example, one year + // or three years), in seconds (31536000 | 94608000). + // + // fixed-price - The purchase price of the Reserved Instance (for example, + // 9800.0). + // + // instance-type - The instance type that is covered by the reservation. + // + // marketplace - Set to true to show only Reserved Instance Marketplace + // offerings. When this filter is not used, which is the default behavior, all + // offerings from both AWS and the Reserved Instance Marketplace are listed. + // + // product-description - The Reserved Instance product platform description. + // Instances that include (Amazon VPC) in the product platform description will + // only be displayed to EC2-Classic account holders and are for use with Amazon + // VPC. (Linux/UNIX | Linux/UNIX (Amazon VPC) | SUSE Linux | SUSE Linux (Amazon + // VPC) | Red Hat Enterprise Linux | Red Hat Enterprise Linux (Amazon VPC) | + // Windows | Windows (Amazon VPC) | Windows with SQL Server Standard | Windows + // with SQL Server Standard (Amazon VPC) | Windows with SQL Server Web | Windows + // with SQL Server Web (Amazon VPC) | Windows with SQL Server Enterprise | Windows + // with SQL Server Enterprise (Amazon VPC)) + // + // reserved-instances-offering-id - The Reserved Instances offering ID. + // + // usage-price - The usage price of the Reserved Instance, per hour (for + // example, 0.84). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // Include Reserved Instance Marketplace offerings in the response. + IncludeMarketplace *bool `type:"boolean"` + + // The tenancy of the instances covered by the reservation. A Reserved Instance + // with a tenancy of dedicated is applied to instances that run in a VPC on + // single-tenant hardware (i.e., Dedicated Instances). + // + // Default: default + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` + + // The instance type that the reservation will cover (for example, m1.small). + // For more information, see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) + // in the Amazon Elastic Compute Cloud User Guide. + InstanceType *string `type:"string" enum:"InstanceType"` + + // The maximum duration (in seconds) to filter when searching for offerings. + // + // Default: 94608000 (3 years) + MaxDuration *int64 `type:"long"` + + // The maximum number of instances to filter when searching for offerings. + // + // Default: 20 + MaxInstanceCount *int64 `type:"integer"` + + // The maximum number of results to return for the request in a single page. + // The remaining results of the initial request can be seen by sending another + // request with the returned NextToken value. The maximum is 100. + // + // Default: 100 + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The minimum duration (in seconds) to filter when searching for offerings. + // + // Default: 2592000 (1 month) + MinDuration *int64 `type:"long"` + + // The token to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // The Reserved Instance offering type. If you are using tools that predate + // the 2011-11-01 API version, you only have access to the Medium Utilization + // Reserved Instance offering type. + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` + + // The Reserved Instance product platform description. Instances that include + // (Amazon VPC) in the description are for use with Amazon VPC. + ProductDescription *string `type:"string" enum:"RIProductDescription"` + + // One or more Reserved Instances offering IDs. + ReservedInstancesOfferingIds []*string `locationName:"ReservedInstancesOfferingId" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesOfferingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesOfferingsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeReservedInstancesOfferings. +type DescribeReservedInstancesOfferingsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // A list of Reserved Instances offerings. + ReservedInstancesOfferings []*ReservedInstancesOffering `locationName:"reservedInstancesOfferingsSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesOfferingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesOfferingsOutput) GoString() string { + return s.String() +} + +// Contains the output for DescribeReservedInstances. +type DescribeReservedInstancesOutput struct { + _ struct{} `type:"structure"` + + // A list of Reserved Instances. + ReservedInstances []*ReservedInstances `locationName:"reservedInstancesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeReservedInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeRouteTables. +type DescribeRouteTablesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // association.route-table-association-id - The ID of an association ID + // for the route table. + // + // association.route-table-id - The ID of the route table involved in the + // association. + // + // association.subnet-id - The ID of the subnet involved in the association. + // + // association.main - Indicates whether the route table is the main route + // table for the VPC (true | false). + // + // route-table-id - The ID of the route table. + // + // route.destination-cidr-block - The CIDR range specified in a route in + // the table. + // + // route.destination-prefix-list-id - The ID (prefix) of the AWS service + // specified in a route in the table. + // + // route.gateway-id - The ID of a gateway specified in a route in the table. + // + // route.instance-id - The ID of an instance specified in a route in the + // table. + // + // route.nat-gateway-id - The ID of a NAT gateway. + // + // route.origin - Describes how the route was created. CreateRouteTable + // indicates that the route was automatically created when the route table was + // created; CreateRoute indicates that the route was manually added to the route + // table; EnableVgwRoutePropagation indicates that the route was propagated + // by route propagation. + // + // route.state - The state of a route in the route table (active | blackhole). + // The blackhole state indicates that the route's target isn't available (for + // example, the specified gateway isn't attached to the VPC, the specified NAT + // instance has been terminated, and so on). + // + // route.vpc-peering-connection-id - The ID of a VPC peering connection + // specified in a route in the table. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-id - The ID of the VPC for the route table. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more route table IDs. + // + // Default: Describes all your route tables. + RouteTableIds []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeRouteTablesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRouteTablesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeRouteTables. +type DescribeRouteTablesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more route tables. + RouteTables []*RouteTable `locationName:"routeTableSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeRouteTablesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRouteTablesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeScheduledInstanceAvailability. +type DescribeScheduledInstanceAvailabilityInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // availability-zone - The Availability Zone (for example, us-west-2a). + // + // instance-type - The instance type (for example, c4.large). + // + // network-platform - The network platform (EC2-Classic or EC2-VPC). + // + // platform - The platform (Linux/UNIX or Windows). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The time period for the first schedule to start. + FirstSlotStartTimeRange *SlotDateTimeRangeRequest `type:"structure" required:"true"` + + // The maximum number of results to return in a single call. This value can + // be between 5 and 300. The default value is 300. To retrieve the remaining + // results, make another call with the returned NextToken value. + MaxResults *int64 `type:"integer"` + + // The maximum available duration, in hours. This value must be greater than + // MinSlotDurationInHours and less than 1,720. + MaxSlotDurationInHours *int64 `type:"integer"` + + // The minimum available duration, in hours. The minimum required duration is + // 1,200 hours per year. For example, the minimum daily schedule is 4 hours, + // the minimum weekly schedule is 24 hours, and the minimum monthly schedule + // is 100 hours. + MinSlotDurationInHours *int64 `type:"integer"` + + // The token for the next set of results. + NextToken *string `type:"string"` + + // The schedule recurrence. + Recurrence *ScheduledInstanceRecurrenceRequest `type:"structure" required:"true"` +} + +// String returns the string representation +func (s DescribeScheduledInstanceAvailabilityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScheduledInstanceAvailabilityInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeScheduledInstanceAvailabilityInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeScheduledInstanceAvailabilityInput"} + if s.FirstSlotStartTimeRange == nil { + invalidParams.Add(request.NewErrParamRequired("FirstSlotStartTimeRange")) + } + if s.Recurrence == nil { + invalidParams.Add(request.NewErrParamRequired("Recurrence")) + } + if s.FirstSlotStartTimeRange != nil { + if err := s.FirstSlotStartTimeRange.Validate(); err != nil { + invalidParams.AddNested("FirstSlotStartTimeRange", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeScheduledInstanceAvailability. +type DescribeScheduledInstanceAvailabilityOutput struct { + _ struct{} `type:"structure"` + + // The token required to retrieve the next set of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the available Scheduled Instances. + ScheduledInstanceAvailabilitySet []*ScheduledInstanceAvailability `locationName:"scheduledInstanceAvailabilitySet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeScheduledInstanceAvailabilityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScheduledInstanceAvailabilityOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeScheduledInstances. +type DescribeScheduledInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // availability-zone - The Availability Zone (for example, us-west-2a). + // + // instance-type - The instance type (for example, c4.large). + // + // network-platform - The network platform (EC2-Classic or EC2-VPC). + // + // platform - The platform (Linux/UNIX or Windows). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return in a single call. This value can + // be between 5 and 300. The default value is 100. To retrieve the remaining + // results, make another call with the returned NextToken value. + MaxResults *int64 `type:"integer"` + + // The token for the next set of results. + NextToken *string `type:"string"` + + // One or more Scheduled Instance IDs. + ScheduledInstanceIds []*string `locationName:"ScheduledInstanceId" locationNameList:"ScheduledInstanceId" type:"list"` + + // The time period for the first schedule to start. + SlotStartTimeRange *SlotStartTimeRangeRequest `type:"structure"` +} + +// String returns the string representation +func (s DescribeScheduledInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScheduledInstancesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeScheduledInstances. +type DescribeScheduledInstancesOutput struct { + _ struct{} `type:"structure"` + + // The token required to retrieve the next set of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the Scheduled Instances. + ScheduledInstanceSet []*ScheduledInstance `locationName:"scheduledInstanceSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeScheduledInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScheduledInstancesOutput) GoString() string { + return s.String() +} + +type DescribeSecurityGroupReferencesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the operation, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more security group IDs in your account. + GroupId []*string `locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s DescribeSecurityGroupReferencesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSecurityGroupReferencesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeSecurityGroupReferencesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeSecurityGroupReferencesInput"} + if s.GroupId == nil { + invalidParams.Add(request.NewErrParamRequired("GroupId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DescribeSecurityGroupReferencesOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPCs with the referencing security groups. + SecurityGroupReferenceSet []*SecurityGroupReference `locationName:"securityGroupReferenceSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSecurityGroupReferencesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSecurityGroupReferencesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSecurityGroups. +type DescribeSecurityGroupsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. If using multiple filters for rules, the results include + // security groups for which any combination of rules - not necessarily a single + // rule - match all filters. + // + // description - The description of the security group. + // + // egress.ip-permission.prefix-list-id - The ID (prefix) of the AWS service + // to which the security group allows access. + // + // group-id - The ID of the security group. + // + // group-name - The name of the security group. + // + // ip-permission.cidr - A CIDR range that has been granted permission. + // + // ip-permission.from-port - The start of port range for the TCP and UDP + // protocols, or an ICMP type number. + // + // ip-permission.group-id - The ID of a security group that has been granted + // permission. + // + // ip-permission.group-name - The name of a security group that has been + // granted permission. + // + // ip-permission.protocol - The IP protocol for the permission (tcp | udp + // | icmp or a protocol number). + // + // ip-permission.to-port - The end of port range for the TCP and UDP protocols, + // or an ICMP code. + // + // ip-permission.user-id - The ID of an AWS account that has been granted + // permission. + // + // owner-id - The AWS account ID of the owner of the security group. + // + // tag-key - The key of a tag assigned to the security group. + // + // tag-value - The value of a tag assigned to the security group. + // + // vpc-id - The ID of the VPC specified when the security group was created. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more security group IDs. Required for security groups in a nondefault + // VPC. + // + // Default: Describes all your security groups. + GroupIds []*string `locationName:"GroupId" locationNameList:"groupId" type:"list"` + + // [EC2-Classic and default VPC only] One or more security group names. You + // can specify either the security group name or the security group ID. For + // security groups in a nondefault VPC, use the group-name filter to describe + // security groups by name. + // + // Default: Describes all your security groups. + GroupNames []*string `locationName:"GroupName" locationNameList:"GroupName" type:"list"` +} + +// String returns the string representation +func (s DescribeSecurityGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSecurityGroupsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSecurityGroups. +type DescribeSecurityGroupsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more security groups. + SecurityGroups []*SecurityGroup `locationName:"securityGroupInfo" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSecurityGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSecurityGroupsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSnapshotAttribute. +type DescribeSnapshotAttributeInput struct { + _ struct{} `type:"structure"` + + // The snapshot attribute you would like to view. + Attribute *string `type:"string" required:"true" enum:"SnapshotAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the EBS snapshot. + SnapshotId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeSnapshotAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeSnapshotAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeSnapshotAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.SnapshotId == nil { + invalidParams.Add(request.NewErrParamRequired("SnapshotId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeSnapshotAttribute. +type DescribeSnapshotAttributeOutput struct { + _ struct{} `type:"structure"` + + // A list of permissions for creating volumes from the snapshot. + CreateVolumePermissions []*CreateVolumePermission `locationName:"createVolumePermission" locationNameList:"item" type:"list"` + + // A list of product codes. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // The ID of the EBS snapshot. + SnapshotId *string `locationName:"snapshotId" type:"string"` +} + +// String returns the string representation +func (s DescribeSnapshotAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSnapshots. +type DescribeSnapshotsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // description - A description of the snapshot. + // + // owner-alias - Value from an Amazon-maintained list (amazon | aws-marketplace + // | microsoft) of snapshot owners. Not to be confused with the user-configured + // AWS account alias, which is set from the IAM consolew. + // + // owner-id - The ID of the AWS account that owns the snapshot. + // + // progress - The progress of the snapshot, as a percentage (for example, + // 80%). + // + // snapshot-id - The snapshot ID. + // + // start-time - The time stamp when the snapshot was initiated. + // + // status - The status of the snapshot (pending | completed | error). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // volume-id - The ID of the volume the snapshot is for. + // + // volume-size - The size of the volume, in GiB. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of snapshot results returned by DescribeSnapshots in paginated + // output. When this parameter is used, DescribeSnapshots only returns MaxResults + // results in a single page along with a NextToken response element. The remaining + // results of the initial request can be seen by sending another DescribeSnapshots + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. If this parameter is not used, then DescribeSnapshots returns + // all results. You cannot specify this parameter and the snapshot IDs parameter + // in the same request. + MaxResults *int64 `type:"integer"` + + // The NextToken value returned from a previous paginated DescribeSnapshots + // request where MaxResults was used and the results exceeded the value of that + // parameter. Pagination continues from the end of the previous results that + // returned the NextToken value. This value is null when there are no more results + // to return. + NextToken *string `type:"string"` + + // Returns the snapshots owned by the specified owner. Multiple owners can be + // specified. + OwnerIds []*string `locationName:"Owner" locationNameList:"Owner" type:"list"` + + // One or more AWS accounts IDs that can create volumes from the snapshot. + RestorableByUserIds []*string `locationName:"RestorableBy" type:"list"` + + // One or more snapshot IDs. + // + // Default: Describes snapshots for which you have launch permissions. + SnapshotIds []*string `locationName:"SnapshotId" locationNameList:"SnapshotId" type:"list"` +} + +// String returns the string representation +func (s DescribeSnapshotsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSnapshots. +type DescribeSnapshotsOutput struct { + _ struct{} `type:"structure"` + + // The NextToken value to include in a future DescribeSnapshots request. When + // the results of a DescribeSnapshots request exceed MaxResults, this value + // can be used to retrieve the next page of results. This value is null when + // there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the snapshots. + Snapshots []*Snapshot `locationName:"snapshotSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSnapshotsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSpotDatafeedSubscription. +type DescribeSpotDatafeedSubscriptionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s DescribeSpotDatafeedSubscriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotDatafeedSubscriptionInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSpotDatafeedSubscription. +type DescribeSpotDatafeedSubscriptionOutput struct { + _ struct{} `type:"structure"` + + // The Spot instance data feed subscription. + SpotDatafeedSubscription *SpotDatafeedSubscription `locationName:"spotDatafeedSubscription" type:"structure"` +} + +// String returns the string representation +func (s DescribeSpotDatafeedSubscriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotDatafeedSubscriptionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSpotFleetInstances. +type DescribeSpotFleetInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The maximum number of results to return in a single call. Specify a value + // between 1 and 1000. The default value is 1000. To retrieve the remaining + // results, make another call with the returned NextToken value. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token for the next set of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeSpotFleetInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeSpotFleetInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeSpotFleetInstancesInput"} + if s.SpotFleetRequestId == nil { + invalidParams.Add(request.NewErrParamRequired("SpotFleetRequestId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeSpotFleetInstances. +type DescribeSpotFleetInstancesOutput struct { + _ struct{} `type:"structure"` + + // The running instances. Note that this list is refreshed periodically and + // might be out of date. + ActiveInstances []*ActiveInstance `locationName:"activeInstanceSet" locationNameList:"item" type:"list" required:"true"` + + // The token required to retrieve the next set of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeSpotFleetInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSpotFleetRequestHistory. +type DescribeSpotFleetRequestHistoryInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The type of events to describe. By default, all events are described. + EventType *string `locationName:"eventType" type:"string" enum:"EventType"` + + // The maximum number of results to return in a single call. Specify a value + // between 1 and 1000. The default value is 1000. To retrieve the remaining + // results, make another call with the returned NextToken value. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token for the next set of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + + // The starting date and time for the events, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` +} + +// String returns the string representation +func (s DescribeSpotFleetRequestHistoryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestHistoryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeSpotFleetRequestHistoryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeSpotFleetRequestHistoryInput"} + if s.SpotFleetRequestId == nil { + invalidParams.Add(request.NewErrParamRequired("SpotFleetRequestId")) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeSpotFleetRequestHistory. +type DescribeSpotFleetRequestHistoryOutput struct { + _ struct{} `type:"structure"` + + // Information about the events in the history of the Spot fleet request. + HistoryRecords []*HistoryRecord `locationName:"historyRecordSet" locationNameList:"item" type:"list" required:"true"` + + // The last date and time for the events, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + // All records up to this time were retrieved. + // + // If nextToken indicates that there are more results, this value is not present. + LastEvaluatedTime *time.Time `locationName:"lastEvaluatedTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The token required to retrieve the next set of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + + // The starting date and time for the events, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` +} + +// String returns the string representation +func (s DescribeSpotFleetRequestHistoryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestHistoryOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSpotFleetRequests. +type DescribeSpotFleetRequestsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The maximum number of results to return in a single call. Specify a value + // between 1 and 1000. The default value is 1000. To retrieve the remaining + // results, make another call with the returned NextToken value. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token for the next set of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // The IDs of the Spot fleet requests. + SpotFleetRequestIds []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSpotFleetRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSpotFleetRequests. +type DescribeSpotFleetRequestsOutput struct { + _ struct{} `type:"structure"` + + // The token required to retrieve the next set of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the configuration of your Spot fleet. + SpotFleetRequestConfigs []*SpotFleetRequestConfig `locationName:"spotFleetRequestConfigSet" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s DescribeSpotFleetRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSpotInstanceRequests. +type DescribeSpotInstanceRequestsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // availability-zone-group - The Availability Zone group. + // + // create-time - The time stamp when the Spot instance request was created. + // + // fault-code - The fault code related to the request. + // + // fault-message - The fault message related to the request. + // + // instance-id - The ID of the instance that fulfilled the request. + // + // launch-group - The Spot instance launch group. + // + // launch.block-device-mapping.delete-on-termination - Indicates whether + // the Amazon EBS volume is deleted on instance termination. + // + // launch.block-device-mapping.device-name - The device name for the Amazon + // EBS volume (for example, /dev/sdh). + // + // launch.block-device-mapping.snapshot-id - The ID of the snapshot used + // for the Amazon EBS volume. + // + // launch.block-device-mapping.volume-size - The size of the Amazon EBS + // volume, in GiB. + // + // launch.block-device-mapping.volume-type - The type of the Amazon EBS + // volume: gp2 for General Purpose SSD, io1 for Provisioned IOPS SSD, st1 for + // Throughput Optimized HDD, sc1for Cold HDD, or standard for Magnetic. + // + // launch.group-id - The security group for the instance. + // + // launch.image-id - The ID of the AMI. + // + // launch.instance-type - The type of instance (for example, m3.medium). + // + // launch.kernel-id - The kernel ID. + // + // launch.key-name - The name of the key pair the instance launched with. + // + // launch.monitoring-enabled - Whether monitoring is enabled for the Spot + // instance. + // + // launch.ramdisk-id - The RAM disk ID. + // + // network-interface.network-interface-id - The ID of the network interface. + // + // network-interface.device-index - The index of the device for the network + // interface attachment on the instance. + // + // network-interface.subnet-id - The ID of the subnet for the instance. + // + // network-interface.description - A description of the network interface. + // + // network-interface.private-ip-address - The primary private IP address + // of the network interface. + // + // network-interface.delete-on-termination - Indicates whether the network + // interface is deleted when the instance is terminated. + // + // network-interface.group-id - The ID of the security group associated + // with the network interface. + // + // network-interface.group-name - The name of the security group associated + // with the network interface. + // + // network-interface.addresses.primary - Indicates whether the IP address + // is the primary private IP address. + // + // product-description - The product description associated with the instance + // (Linux/UNIX | Windows). + // + // spot-instance-request-id - The Spot instance request ID. + // + // spot-price - The maximum hourly price for any Spot instance launched + // to fulfill the request. + // + // state - The state of the Spot instance request (open | active | closed + // | cancelled | failed). Spot bid status information can help you track your + // Amazon EC2 Spot instance requests. For more information, see Spot Bid Status + // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // status-code - The short code describing the most recent evaluation of + // your Spot instance request. + // + // status-message - The message explaining the status of the Spot instance + // request. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // type - The type of Spot instance request (one-time | persistent). + // + // launched-availability-zone - The Availability Zone in which the bid is + // launched. + // + // valid-from - The start date of the request. + // + // valid-until - The end date of the request. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more Spot instance request IDs. + SpotInstanceRequestIds []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list"` +} + +// String returns the string representation +func (s DescribeSpotInstanceRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotInstanceRequestsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSpotInstanceRequests. +type DescribeSpotInstanceRequestsOutput struct { + _ struct{} `type:"structure"` + + // One or more Spot instance requests. + SpotInstanceRequests []*SpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSpotInstanceRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotInstanceRequestsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSpotPriceHistory. +type DescribeSpotPriceHistoryInput struct { + _ struct{} `type:"structure"` + + // Filters the results by the specified Availability Zone. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The date and time, up to the current date, from which to stop retrieving + // the price history data, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + EndTime *time.Time `locationName:"endTime" type:"timestamp" timestampFormat:"iso8601"` + + // One or more filters. + // + // availability-zone - The Availability Zone for which prices should be + // returned. + // + // instance-type - The type of instance (for example, m3.medium). + // + // product-description - The product description for the Spot price (Linux/UNIX + // | SUSE Linux | Windows | Linux/UNIX (Amazon VPC) | SUSE Linux (Amazon VPC) + // | Windows (Amazon VPC)). + // + // spot-price - The Spot price. The value must match exactly (or use wildcards; + // greater than or less than comparison is not supported). + // + // timestamp - The timestamp of the Spot price history, in UTC format (for + // example, YYYY-MM-DDTHH:MM:SSZ). You can use wildcards (* and ?). Greater + // than or less than comparison is not supported. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // Filters the results by the specified instance types. + InstanceTypes []*string `locationName:"InstanceType" type:"list"` + + // The maximum number of results to return in a single call. Specify a value + // between 1 and 1000. The default value is 1000. To retrieve the remaining + // results, make another call with the returned NextToken value. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token for the next set of results. + NextToken *string `locationName:"nextToken" type:"string"` + + // Filters the results by the specified basic product descriptions. + ProductDescriptions []*string `locationName:"ProductDescription" type:"list"` + + // The date and time, up to the past 90 days, from which to start retrieving + // the price history data, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s DescribeSpotPriceHistoryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotPriceHistoryInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSpotPriceHistory. +type DescribeSpotPriceHistoryOutput struct { + _ struct{} `type:"structure"` + + // The token required to retrieve the next set of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // The historical Spot prices. + SpotPriceHistory []*SpotPrice `locationName:"spotPriceHistorySet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSpotPriceHistoryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotPriceHistoryOutput) GoString() string { + return s.String() +} + +type DescribeStaleSecurityGroupsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the operation, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + MaxResults *int64 `min:"5" type:"integer"` + + // The token for the next set of items to return. (You received this token from + // a prior call.) + NextToken *string `min:"1" type:"string"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeStaleSecurityGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeStaleSecurityGroupsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeStaleSecurityGroupsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeStaleSecurityGroupsInput"} + if s.MaxResults != nil && *s.MaxResults < 5 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 5)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DescribeStaleSecurityGroupsOutput struct { + _ struct{} `type:"structure"` + + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the stale security groups. + StaleSecurityGroupSet []*StaleSecurityGroup `locationName:"staleSecurityGroupSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeStaleSecurityGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeStaleSecurityGroupsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeSubnets. +type DescribeSubnetsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // availabilityZone - The Availability Zone for the subnet. You can also + // use availability-zone as the filter name. + // + // available-ip-address-count - The number of IP addresses in the subnet + // that are available. + // + // cidrBlock - The CIDR block of the subnet. The CIDR block you specify + // must exactly match the subnet's CIDR block for information to be returned + // for the subnet. You can also use cidr or cidr-block as the filter names. + // + // defaultForAz - Indicates whether this is the default subnet for the Availability + // Zone. You can also use default-for-az as the filter name. + // + // state - The state of the subnet (pending | available). + // + // subnet-id - The ID of the subnet. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-id - The ID of the VPC for the subnet. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more subnet IDs. + // + // Default: Describes all your subnets. + SubnetIds []*string `locationName:"SubnetId" locationNameList:"SubnetId" type:"list"` +} + +// String returns the string representation +func (s DescribeSubnetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSubnetsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeSubnets. +type DescribeSubnetsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more subnets. + Subnets []*Subnet `locationName:"subnetSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeSubnetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSubnetsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeTags. +type DescribeTagsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // key - The tag key. + // + // resource-id - The resource ID. + // + // resource-type - The resource type (customer-gateway | dhcp-options | + // image | instance | internet-gateway | network-acl | network-interface | reserved-instances + // | route-table | security-group | snapshot | spot-instances-request | subnet + // | volume | vpc | vpn-connection | vpn-gateway). + // + // value - The tag value. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return in a single call. This value can + // be between 5 and 1000. To retrieve the remaining results, make another call + // with the returned NextToken value. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeTags. +type DescribeTagsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return.. + NextToken *string `locationName:"nextToken" type:"string"` + + // A list of tags. + Tags []*TagDescription `locationName:"tagSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVolumeAttribute. +type DescribeVolumeAttributeInput struct { + _ struct{} `type:"structure"` + + // The instance attribute. + Attribute *string `type:"string" enum:"VolumeAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeVolumeAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumeAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeVolumeAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeVolumeAttributeInput"} + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeVolumeAttribute. +type DescribeVolumeAttributeOutput struct { + _ struct{} `type:"structure"` + + // The state of autoEnableIO attribute. + AutoEnableIO *AttributeBooleanValue `locationName:"autoEnableIO" type:"structure"` + + // A list of product codes. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string"` +} + +// String returns the string representation +func (s DescribeVolumeAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumeAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVolumeStatus. +type DescribeVolumeStatusInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // action.code - The action code for the event (for example, enable-volume-io). + // + // action.description - A description of the action. + // + // action.event-id - The event ID associated with the action. + // + // availability-zone - The Availability Zone of the instance. + // + // event.description - A description of the event. + // + // event.event-id - The event ID. + // + // event.event-type - The event type (for io-enabled: passed | failed; for + // io-performance: io-performance:degraded | io-performance:severely-degraded + // | io-performance:stalled). + // + // event.not-after - The latest end time for the event. + // + // event.not-before - The earliest start time for the event. + // + // volume-status.details-name - The cause for volume-status.status (io-enabled + // | io-performance). + // + // volume-status.details-status - The status of volume-status.details-name + // (for io-enabled: passed | failed; for io-performance: normal | degraded | + // severely-degraded | stalled). + // + // volume-status.status - The status of the volume (ok | impaired | warning + // | insufficient-data). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of volume results returned by DescribeVolumeStatus in + // paginated output. When this parameter is used, the request only returns MaxResults + // results in a single page along with a NextToken response element. The remaining + // results of the initial request can be seen by sending another request with + // the returned NextToken value. This value can be between 5 and 1000; if MaxResults + // is given a value larger than 1000, only 1000 results are returned. If this + // parameter is not used, then DescribeVolumeStatus returns all results. You + // cannot specify this parameter and the volume IDs parameter in the same request. + MaxResults *int64 `type:"integer"` + + // The NextToken value to include in a future DescribeVolumeStatus request. + // When the results of the request exceed MaxResults, this value can be used + // to retrieve the next page of results. This value is null when there are no + // more results to return. + NextToken *string `type:"string"` + + // One or more volume IDs. + // + // Default: Describes all your volumes. + VolumeIds []*string `locationName:"VolumeId" locationNameList:"VolumeId" type:"list"` +} + +// String returns the string representation +func (s DescribeVolumeStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumeStatusInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVolumeStatus. +type DescribeVolumeStatusOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // A list of volumes. + VolumeStatuses []*VolumeStatusItem `locationName:"volumeStatusSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVolumeStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumeStatusOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVolumes. +type DescribeVolumesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // attachment.attach-time - The time stamp when the attachment initiated. + // + // attachment.delete-on-termination - Whether the volume is deleted on instance + // termination. + // + // attachment.device - The device name that is exposed to the instance (for + // example, /dev/sda1). + // + // attachment.instance-id - The ID of the instance the volume is attached + // to. + // + // attachment.status - The attachment state (attaching | attached | detaching + // | detached). + // + // availability-zone - The Availability Zone in which the volume was created. + // + // create-time - The time stamp when the volume was created. + // + // encrypted - The encryption status of the volume. + // + // size - The size of the volume, in GiB. + // + // snapshot-id - The snapshot from which the volume was created. + // + // status - The status of the volume (creating | available | in-use | deleting + // | deleted | error). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // volume-id - The volume ID. + // + // volume-type - The Amazon EBS volume type. This can be gp2 for General + // Purpose SSD, io1 for Provisioned IOPS SSD, st1 for Throughput Optimized HDD, + // sc1 for Cold HDD, or standard for Magnetic volumes. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of volume results returned by DescribeVolumes in paginated + // output. When this parameter is used, DescribeVolumes only returns MaxResults + // results in a single page along with a NextToken response element. The remaining + // results of the initial request can be seen by sending another DescribeVolumes + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. If this parameter is not used, then DescribeVolumes returns + // all results. You cannot specify this parameter and the volume IDs parameter + // in the same request. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The NextToken value returned from a previous paginated DescribeVolumes request + // where MaxResults was used and the results exceeded the value of that parameter. + // Pagination continues from the end of the previous results that returned the + // NextToken value. This value is null when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // One or more volume IDs. + VolumeIds []*string `locationName:"VolumeId" locationNameList:"VolumeId" type:"list"` +} + +// String returns the string representation +func (s DescribeVolumesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVolumes. +type DescribeVolumesOutput struct { + _ struct{} `type:"structure"` + + // The NextToken value to include in a future DescribeVolumes request. When + // the results of a DescribeVolumes request exceed MaxResults, this value can + // be used to retrieve the next page of results. This value is null when there + // are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the volumes. + Volumes []*Volume `locationName:"volumeSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVolumesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcAttribute. +type DescribeVpcAttributeInput struct { + _ struct{} `type:"structure"` + + // The VPC attribute. + Attribute *string `type:"string" required:"true" enum:"VpcAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeVpcAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeVpcAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeVpcAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeVpcAttribute. +type DescribeVpcAttributeOutput struct { + _ struct{} `type:"structure"` + + // Indicates whether the instances launched in the VPC get DNS hostnames. If + // this attribute is true, instances in the VPC get DNS hostnames; otherwise, + // they do not. + EnableDnsHostnames *AttributeBooleanValue `locationName:"enableDnsHostnames" type:"structure"` + + // Indicates whether DNS resolution is enabled for the VPC. If this attribute + // is true, the Amazon DNS server resolves DNS hostnames for your instances + // to their corresponding IP addresses; otherwise, it does not. + EnableDnsSupport *AttributeBooleanValue `locationName:"enableDnsSupport" type:"structure"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s DescribeVpcAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcClassicLinkDnsSupport. +type DescribeVpcClassicLinkDnsSupportInput struct { + _ struct{} `type:"structure"` + + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + MaxResults *int64 `locationName:"maxResults" min:"5" type:"integer"` + + // The token for the next set of items to return. (You received this token from + // a prior call.) + NextToken *string `locationName:"nextToken" min:"1" type:"string"` + + // One or more VPC IDs. + VpcIds []*string `locationNameList:"VpcId" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcClassicLinkDnsSupportInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcClassicLinkDnsSupportInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeVpcClassicLinkDnsSupportInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeVpcClassicLinkDnsSupportInput"} + if s.MaxResults != nil && *s.MaxResults < 5 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 5)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DescribeVpcClassicLinkDnsSupport. +type DescribeVpcClassicLinkDnsSupportOutput struct { + _ struct{} `type:"structure"` + + // The token to use when requesting the next set of items. + NextToken *string `locationName:"nextToken" min:"1" type:"string"` + + // Information about the ClassicLink DNS support status of the VPCs. + Vpcs []*ClassicLinkDnsSupport `locationName:"vpcs" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcClassicLinkDnsSupportOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcClassicLinkDnsSupportOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcClassicLink. +type DescribeVpcClassicLinkInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // is-classic-link-enabled - Whether the VPC is enabled for ClassicLink + // (true | false). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more VPCs for which you want to describe the ClassicLink status. + VpcIds []*string `locationName:"VpcId" locationNameList:"VpcId" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcClassicLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcClassicLinkInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpcClassicLink. +type DescribeVpcClassicLinkOutput struct { + _ struct{} `type:"structure"` + + // The ClassicLink status of one or more VPCs. + Vpcs []*VpcClassicLink `locationName:"vpcSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcClassicLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcClassicLinkOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcEndpointServices. +type DescribeVpcEndpointServicesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + // + // Constraint: If the value is greater than 1000, we return only 1000 items. + MaxResults *int64 `type:"integer"` + + // The token for the next set of items to return. (You received this token from + // a prior call.) + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeVpcEndpointServicesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServicesInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpcEndpointServices. +type DescribeVpcEndpointServicesOutput struct { + _ struct{} `type:"structure"` + + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. + NextToken *string `locationName:"nextToken" type:"string"` + + // A list of supported AWS services. + ServiceNames []*string `locationName:"serviceNameSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcEndpointServicesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServicesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcEndpoints. +type DescribeVpcEndpointsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // service-name: The name of the AWS service. + // + // vpc-id: The ID of the VPC in which the endpoint resides. + // + // vpc-endpoint-id: The ID of the endpoint. + // + // vpc-endpoint-state: The state of the endpoint. (pending | available | + // deleting | deleted) + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + // + // Constraint: If the value is greater than 1000, we return only 1000 items. + MaxResults *int64 `type:"integer"` + + // The token for the next set of items to return. (You received this token from + // a prior call.) + NextToken *string `type:"string"` + + // One or more endpoint IDs. + VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcEndpointsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpcEndpoints. +type DescribeVpcEndpointsOutput struct { + _ struct{} `type:"structure"` + + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the endpoints. + VpcEndpoints []*VpcEndpoint `locationName:"vpcEndpointSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcEndpointsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcPeeringConnections. +type DescribeVpcPeeringConnectionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // accepter-vpc-info.cidr-block - The CIDR block of the peer VPC. + // + // accepter-vpc-info.owner-id - The AWS account ID of the owner of the peer + // VPC. + // + // accepter-vpc-info.vpc-id - The ID of the peer VPC. + // + // expiration-time - The expiration date and time for the VPC peering connection. + // + // requester-vpc-info.cidr-block - The CIDR block of the requester's VPC. + // + // requester-vpc-info.owner-id - The AWS account ID of the owner of the + // requester VPC. + // + // requester-vpc-info.vpc-id - The ID of the requester VPC. + // + // status-code - The status of the VPC peering connection (pending-acceptance + // | failed | expired | provisioning | active | deleted | rejected). + // + // status-message - A message that provides more information about the status + // of the VPC peering connection, if applicable. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-peering-connection-id - The ID of the VPC peering connection. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more VPC peering connection IDs. + // + // Default: Describes all your VPC peering connections. + VpcPeeringConnectionIds []*string `locationName:"VpcPeeringConnectionId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcPeeringConnectionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcPeeringConnectionsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpcPeeringConnections. +type DescribeVpcPeeringConnectionsOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPC peering connections. + VpcPeeringConnections []*VpcPeeringConnection `locationName:"vpcPeeringConnectionSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcPeeringConnectionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcPeeringConnectionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpcs. +type DescribeVpcsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // cidr - The CIDR block of the VPC. The CIDR block you specify must exactly + // match the VPC's CIDR block for information to be returned for the VPC. Must + // contain the slash followed by one or two digits (for example, /28). + // + // dhcp-options-id - The ID of a set of DHCP options. + // + // isDefault - Indicates whether the VPC is the default VPC. + // + // state - The state of the VPC (pending | available). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // vpc-id - The ID of the VPC. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more VPC IDs. + // + // Default: Describes all your VPCs. + VpcIds []*string `locationName:"VpcId" locationNameList:"VpcId" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpcs. +type DescribeVpcsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more VPCs. + Vpcs []*Vpc `locationName:"vpcSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpnConnections. +type DescribeVpnConnectionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // customer-gateway-configuration - The configuration information for the + // customer gateway. + // + // customer-gateway-id - The ID of a customer gateway associated with the + // VPN connection. + // + // state - The state of the VPN connection (pending | available | deleting + // | deleted). + // + // option.static-routes-only - Indicates whether the connection has static + // routes only. Used for devices that do not support Border Gateway Protocol + // (BGP). + // + // route.destination-cidr-block - The destination CIDR block. This corresponds + // to the subnet used in a customer data center. + // + // bgp-asn - The BGP Autonomous System Number (ASN) associated with a BGP + // device. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // type - The type of VPN connection. Currently the only supported type + // is ipsec.1. + // + // vpn-connection-id - The ID of the VPN connection. + // + // vpn-gateway-id - The ID of a virtual private gateway associated with + // the VPN connection. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more VPN connection IDs. + // + // Default: Describes your VPN connections. + VpnConnectionIds []*string `locationName:"VpnConnectionId" locationNameList:"VpnConnectionId" type:"list"` +} + +// String returns the string representation +func (s DescribeVpnConnectionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpnConnectionsInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpnConnections. +type DescribeVpnConnectionsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more VPN connections. + VpnConnections []*VpnConnection `locationName:"vpnConnectionSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpnConnectionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpnConnectionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DescribeVpnGateways. +type DescribeVpnGatewaysInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more filters. + // + // attachment.state - The current state of the attachment between the gateway + // and the VPC (attaching | attached | detaching | detached). + // + // attachment.vpc-id - The ID of an attached VPC. + // + // availability-zone - The Availability Zone for the virtual private gateway + // (if applicable). + // + // state - The state of the virtual private gateway (pending | available + // | deleting | deleted). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // type - The type of virtual private gateway. Currently the only supported + // type is ipsec.1. + // + // vpn-gateway-id - The ID of the virtual private gateway. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more virtual private gateway IDs. + // + // Default: Describes all your virtual private gateways. + VpnGatewayIds []*string `locationName:"VpnGatewayId" locationNameList:"VpnGatewayId" type:"list"` +} + +// String returns the string representation +func (s DescribeVpnGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpnGatewaysInput) GoString() string { + return s.String() +} + +// Contains the output of DescribeVpnGateways. +type DescribeVpnGatewaysOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more virtual private gateways. + VpnGateways []*VpnGateway `locationName:"vpnGatewaySet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpnGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpnGatewaysOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DetachClassicLinkVpc. +type DetachClassicLinkVpcInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance to unlink from the VPC. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // The ID of the VPC to which the instance is linked. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachClassicLinkVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachClassicLinkVpcInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachClassicLinkVpcInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachClassicLinkVpcInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DetachClassicLinkVpc. +type DetachClassicLinkVpcOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s DetachClassicLinkVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachClassicLinkVpcOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DetachInternetGateway. +type DetachInternetGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the Internet gateway. + InternetGatewayId *string `locationName:"internetGatewayId" type:"string" required:"true"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInternetGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachInternetGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachInternetGatewayInput"} + if s.InternetGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("InternetGatewayId")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DetachInternetGatewayOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DetachInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInternetGatewayOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DetachNetworkInterface. +type DetachNetworkInterfaceInput struct { + _ struct{} `type:"structure"` + + // The ID of the attachment. + AttachmentId *string `locationName:"attachmentId" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Specifies whether to force a detachment. + Force *bool `locationName:"force" type:"boolean"` +} + +// String returns the string representation +func (s DetachNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachNetworkInterfaceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachNetworkInterfaceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachNetworkInterfaceInput"} + if s.AttachmentId == nil { + invalidParams.Add(request.NewErrParamRequired("AttachmentId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DetachNetworkInterfaceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DetachNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachNetworkInterfaceOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DetachVolume. +type DetachVolumeInput struct { + _ struct{} `type:"structure"` + + // The device name. + Device *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Forces detachment if the previous detachment attempt did not occur cleanly + // (for example, logging into an instance, unmounting the volume, and detaching + // normally). This option can lead to data loss or a corrupted file system. + // Use this option only as a last resort to detach a volume from a failed instance. + // The instance won't have an opportunity to flush file system caches or file + // system metadata. If you use this option, you must perform file system check + // and repair procedures. + Force *bool `type:"boolean"` + + // The ID of the instance. + InstanceId *string `type:"string"` + + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachVolumeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachVolumeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachVolumeInput"} + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the parameters for DetachVpnGateway. +type DetachVpnGatewayInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` + + // The ID of the virtual private gateway. + VpnGatewayId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachVpnGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachVpnGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachVpnGatewayInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + if s.VpnGatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("VpnGatewayId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DetachVpnGatewayOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DetachVpnGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachVpnGatewayOutput) GoString() string { + return s.String() +} + +// Describes a DHCP configuration option. +type DhcpConfiguration struct { + _ struct{} `type:"structure"` + + // The name of a DHCP option. + Key *string `locationName:"key" type:"string"` + + // One or more values for the DHCP option. + Values []*AttributeValue `locationName:"valueSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DhcpConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DhcpConfiguration) GoString() string { + return s.String() +} + +// Describes a set of DHCP options. +type DhcpOptions struct { + _ struct{} `type:"structure"` + + // One or more DHCP options in the set. + DhcpConfigurations []*DhcpConfiguration `locationName:"dhcpConfigurationSet" locationNameList:"item" type:"list"` + + // The ID of the set of DHCP options. + DhcpOptionsId *string `locationName:"dhcpOptionsId" type:"string"` + + // Any tags assigned to the DHCP options set. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DhcpOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DhcpOptions) GoString() string { + return s.String() +} + +// Contains the parameters for DisableVgwRoutePropagation. +type DisableVgwRoutePropagationInput struct { + _ struct{} `type:"structure"` + + // The ID of the virtual private gateway. + GatewayId *string `type:"string" required:"true"` + + // The ID of the route table. + RouteTableId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DisableVgwRoutePropagationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVgwRoutePropagationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisableVgwRoutePropagationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisableVgwRoutePropagationInput"} + if s.GatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("GatewayId")) + } + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DisableVgwRoutePropagationOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DisableVgwRoutePropagationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVgwRoutePropagationOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DisableVpcClassicLinkDnsSupport. +type DisableVpcClassicLinkDnsSupportInput struct { + _ struct{} `type:"structure"` + + // The ID of the VPC. + VpcId *string `type:"string"` +} + +// String returns the string representation +func (s DisableVpcClassicLinkDnsSupportInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVpcClassicLinkDnsSupportInput) GoString() string { + return s.String() +} + +// Contains the output of DisableVpcClassicLinkDnsSupport. +type DisableVpcClassicLinkDnsSupportOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s DisableVpcClassicLinkDnsSupportOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVpcClassicLinkDnsSupportOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DisableVpcClassicLink. +type DisableVpcClassicLinkInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DisableVpcClassicLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVpcClassicLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisableVpcClassicLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisableVpcClassicLinkInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of DisableVpcClassicLink. +type DisableVpcClassicLinkOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s DisableVpcClassicLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVpcClassicLinkOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DisassociateAddress. +type DisassociateAddressInput struct { + _ struct{} `type:"structure"` + + // [EC2-VPC] The association ID. Required for EC2-VPC. + AssociationId *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // [EC2-Classic] The Elastic IP address. Required for EC2-Classic. + PublicIp *string `type:"string"` +} + +// String returns the string representation +func (s DisassociateAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateAddressInput) GoString() string { + return s.String() +} + +type DisassociateAddressOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DisassociateAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateAddressOutput) GoString() string { + return s.String() +} + +// Contains the parameters for DisassociateRouteTable. +type DisassociateRouteTableInput struct { + _ struct{} `type:"structure"` + + // The association ID representing the current association between the route + // table and subnet. + AssociationId *string `locationName:"associationId" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` +} + +// String returns the string representation +func (s DisassociateRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateRouteTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisassociateRouteTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisassociateRouteTableInput"} + if s.AssociationId == nil { + invalidParams.Add(request.NewErrParamRequired("AssociationId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DisassociateRouteTableOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DisassociateRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateRouteTableOutput) GoString() string { + return s.String() +} + +// Describes a disk image. +type DiskImage struct { + _ struct{} `type:"structure"` + + // A description of the disk image. + Description *string `type:"string"` + + // Information about the disk image. + Image *DiskImageDetail `type:"structure"` + + // Information about the volume. + Volume *VolumeDetail `type:"structure"` +} + +// String returns the string representation +func (s DiskImage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImage) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DiskImage) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DiskImage"} + if s.Image != nil { + if err := s.Image.Validate(); err != nil { + invalidParams.AddNested("Image", err.(request.ErrInvalidParams)) + } + } + if s.Volume != nil { + if err := s.Volume.Validate(); err != nil { + invalidParams.AddNested("Volume", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a disk image. +type DiskImageDescription struct { + _ struct{} `type:"structure"` + + // The checksum computed for the disk image. + Checksum *string `locationName:"checksum" type:"string"` + + // The disk image format. + Format *string `locationName:"format" type:"string" required:"true" enum:"DiskImageFormat"` + + // A presigned URL for the import manifest stored in Amazon S3. For information + // about creating a presigned URL for an Amazon S3 object, read the "Query String + // Request Authentication Alternative" section of the Authenticating REST Requests + // (http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) + // topic in the Amazon Simple Storage Service Developer Guide. + // + // For information about the import manifest referenced by this API action, + // see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). + ImportManifestUrl *string `locationName:"importManifestUrl" type:"string" required:"true"` + + // The size of the disk image, in GiB. + Size *int64 `locationName:"size" type:"long" required:"true"` +} + +// String returns the string representation +func (s DiskImageDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImageDescription) GoString() string { + return s.String() +} + +// Describes a disk image. +type DiskImageDetail struct { + _ struct{} `type:"structure"` + + // The size of the disk image, in GiB. + Bytes *int64 `locationName:"bytes" type:"long" required:"true"` + + // The disk image format. + Format *string `locationName:"format" type:"string" required:"true" enum:"DiskImageFormat"` + + // A presigned URL for the import manifest stored in Amazon S3 and presented + // here as an Amazon S3 presigned URL. For information about creating a presigned + // URL for an Amazon S3 object, read the "Query String Request Authentication + // Alternative" section of the Authenticating REST Requests (http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) + // topic in the Amazon Simple Storage Service Developer Guide. + // + // For information about the import manifest referenced by this API action, + // see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). + ImportManifestUrl *string `locationName:"importManifestUrl" type:"string" required:"true"` +} + +// String returns the string representation +func (s DiskImageDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImageDetail) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DiskImageDetail) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DiskImageDetail"} + if s.Bytes == nil { + invalidParams.Add(request.NewErrParamRequired("Bytes")) + } + if s.Format == nil { + invalidParams.Add(request.NewErrParamRequired("Format")) + } + if s.ImportManifestUrl == nil { + invalidParams.Add(request.NewErrParamRequired("ImportManifestUrl")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a disk image volume. +type DiskImageVolumeDescription struct { + _ struct{} `type:"structure"` + + // The volume identifier. + Id *string `locationName:"id" type:"string" required:"true"` + + // The size of the volume, in GiB. + Size *int64 `locationName:"size" type:"long"` +} + +// String returns the string representation +func (s DiskImageVolumeDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImageVolumeDescription) GoString() string { + return s.String() +} + +// Describes a block device for an EBS volume. +type EbsBlockDevice struct { + _ struct{} `type:"structure"` + + // Indicates whether the EBS volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // Indicates whether the EBS volume is encrypted. Encrypted Amazon EBS volumes + // may only be attached to instances that support Amazon EBS encryption. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The number of I/O operations per second (IOPS) that the volume supports. + // For io1, this represents the number of IOPS that are provisioned for the + // volume. For gp2, this represents the baseline performance of the volume and + // the rate at which the volume accumulates I/O credits for bursting. For more + // information about General Purpose SSD baseline performance, I/O credits, + // and bursting, see Amazon EBS Volume Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // Constraint: Range is 100-20000 IOPS for io1 volumes and 100-10000 IOPS for + // gp2 volumes. + // + // Condition: This parameter is required for requests to create io1 volumes; + // it is not used in requests to create gp2, st1, sc1, or standard volumes. + Iops *int64 `locationName:"iops" type:"integer"` + + // The ID of the snapshot. + SnapshotId *string `locationName:"snapshotId" type:"string"` + + // The size of the volume, in GiB. + // + // Constraints: 1-16384 for General Purpose SSD (gp2), 4-16384 for Provisioned + // IOPS SSD (io1), 500-16384 for Throughput Optimized HDD (st1), 500-16384 for + // Cold HDD (sc1), and 1-1024 for Magnetic (standard) volumes. If you specify + // a snapshot, the volume size must be equal to or larger than the snapshot + // size. + // + // Default: If you're creating the volume from a snapshot and don't specify + // a volume size, the default is the snapshot size. + VolumeSize *int64 `locationName:"volumeSize" type:"integer"` + + // The volume type: gp2, io1, st1, sc1, or standard. + // + // Default: standard + VolumeType *string `locationName:"volumeType" type:"string" enum:"VolumeType"` +} + +// String returns the string representation +func (s EbsBlockDevice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EbsBlockDevice) GoString() string { + return s.String() +} + +// Describes a parameter used to set up an EBS volume in a block device mapping. +type EbsInstanceBlockDevice struct { + _ struct{} `type:"structure"` + + // The time stamp when the attachment initiated. + AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` + + // Indicates whether the volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // The attachment state. + Status *string `locationName:"status" type:"string" enum:"AttachmentStatus"` + + // The ID of the EBS volume. + VolumeId *string `locationName:"volumeId" type:"string"` +} + +// String returns the string representation +func (s EbsInstanceBlockDevice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EbsInstanceBlockDevice) GoString() string { + return s.String() +} + +// Describes information used to set up an EBS volume specified in a block device +// mapping. +type EbsInstanceBlockDeviceSpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether the volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // The ID of the EBS volume. + VolumeId *string `locationName:"volumeId" type:"string"` +} + +// String returns the string representation +func (s EbsInstanceBlockDeviceSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EbsInstanceBlockDeviceSpecification) GoString() string { + return s.String() +} + +// Contains the parameters for EnableVgwRoutePropagation. +type EnableVgwRoutePropagationInput struct { + _ struct{} `type:"structure"` + + // The ID of the virtual private gateway. + GatewayId *string `type:"string" required:"true"` + + // The ID of the route table. + RouteTableId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s EnableVgwRoutePropagationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVgwRoutePropagationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *EnableVgwRoutePropagationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "EnableVgwRoutePropagationInput"} + if s.GatewayId == nil { + invalidParams.Add(request.NewErrParamRequired("GatewayId")) + } + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type EnableVgwRoutePropagationOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s EnableVgwRoutePropagationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVgwRoutePropagationOutput) GoString() string { + return s.String() +} + +// Contains the parameters for EnableVolumeIO. +type EnableVolumeIOInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string" required:"true"` +} + +// String returns the string representation +func (s EnableVolumeIOInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVolumeIOInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *EnableVolumeIOInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "EnableVolumeIOInput"} + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type EnableVolumeIOOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s EnableVolumeIOOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVolumeIOOutput) GoString() string { + return s.String() +} + +// Contains the parameters for EnableVpcClassicLinkDnsSupport. +type EnableVpcClassicLinkDnsSupportInput struct { + _ struct{} `type:"structure"` + + // The ID of the VPC. + VpcId *string `type:"string"` +} + +// String returns the string representation +func (s EnableVpcClassicLinkDnsSupportInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVpcClassicLinkDnsSupportInput) GoString() string { + return s.String() +} + +// Contains the output of EnableVpcClassicLinkDnsSupport. +type EnableVpcClassicLinkDnsSupportOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s EnableVpcClassicLinkDnsSupportOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVpcClassicLinkDnsSupportOutput) GoString() string { + return s.String() +} + +// Contains the parameters for EnableVpcClassicLink. +type EnableVpcClassicLinkInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s EnableVpcClassicLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVpcClassicLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *EnableVpcClassicLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "EnableVpcClassicLinkInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of EnableVpcClassicLink. +type EnableVpcClassicLinkOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s EnableVpcClassicLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVpcClassicLinkOutput) GoString() string { + return s.String() +} + +// Describes a Spot fleet event. +type EventInformation struct { + _ struct{} `type:"structure"` + + // The description of the event. + EventDescription *string `locationName:"eventDescription" type:"string"` + + // The event. + // + // The following are the error events. + // + // iamFleetRoleInvalid - The Spot fleet did not have the required permissions + // either to launch or terminate an instance. + // + // launchSpecTemporarilyBlacklisted - The configuration is not valid and + // several attempts to launch instances have failed. For more information, see + // the description of the event. + // + // spotFleetRequestConfigurationInvalid - The configuration is not valid. + // For more information, see the description of the event. + // + // spotInstanceCountLimitExceeded - You've reached the limit on the number + // of Spot instances that you can launch. + // + // The following are the fleetRequestChange events. + // + // active - The Spot fleet has been validated and Amazon EC2 is attempting + // to maintain the target number of running Spot instances. + // + // cancelled - The Spot fleet is canceled and has no running Spot instances. + // The Spot fleet will be deleted two days after its instances were terminated. + // + // cancelled_running - The Spot fleet is canceled and will not launch additional + // Spot instances, but its existing Spot instances continue to run until they + // are interrupted or terminated. + // + // cancelled_terminating - The Spot fleet is canceled and its Spot instances + // are terminating. + // + // expired - The Spot fleet request has expired. A subsequent event indicates + // that the instances were terminated, if the request was created with TerminateInstancesWithExpiration + // set. + // + // modify_in_progress - A request to modify the Spot fleet request was accepted + // and is in progress. + // + // modify_successful - The Spot fleet request was modified. + // + // price_update - The bid price for a launch configuration was adjusted + // because it was too high. This change is permanent. + // + // submitted - The Spot fleet request is being evaluated and Amazon EC2 + // is preparing to launch the target number of Spot instances. + // + // The following are the instanceChange events. + // + // launched - A bid was fulfilled and a new instance was launched. + // + // terminated - An instance was terminated by the user. + EventSubType *string `locationName:"eventSubType" type:"string"` + + // The ID of the instance. This information is available only for instanceChange + // events. + InstanceId *string `locationName:"instanceId" type:"string"` +} + +// String returns the string representation +func (s EventInformation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EventInformation) GoString() string { + return s.String() +} + +// Describes an instance export task. +type ExportTask struct { + _ struct{} `type:"structure"` + + // A description of the resource being exported. + Description *string `locationName:"description" type:"string"` + + // The ID of the export task. + ExportTaskId *string `locationName:"exportTaskId" type:"string"` + + // Information about the export task. + ExportToS3Task *ExportToS3Task `locationName:"exportToS3" type:"structure"` + + // Information about the instance to export. + InstanceExportDetails *InstanceExportDetails `locationName:"instanceExport" type:"structure"` + + // The state of the export task. + State *string `locationName:"state" type:"string" enum:"ExportTaskState"` + + // The status message related to the export task. + StatusMessage *string `locationName:"statusMessage" type:"string"` +} + +// String returns the string representation +func (s ExportTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportTask) GoString() string { + return s.String() +} + +// Describes the format and location for an instance export task. +type ExportToS3Task struct { + _ struct{} `type:"structure"` + + // The container format used to combine disk images with metadata (such as OVF). + // If absent, only the disk image is exported. + ContainerFormat *string `locationName:"containerFormat" type:"string" enum:"ContainerFormat"` + + // The format for the exported image. + DiskImageFormat *string `locationName:"diskImageFormat" type:"string" enum:"DiskImageFormat"` + + // The S3 bucket for the destination image. The destination bucket must exist + // and grant WRITE and READ_ACP permissions to the AWS account vm-import-export@amazon.com. + S3Bucket *string `locationName:"s3Bucket" type:"string"` + + // The encryption key for your S3 bucket. + S3Key *string `locationName:"s3Key" type:"string"` +} + +// String returns the string representation +func (s ExportToS3Task) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportToS3Task) GoString() string { + return s.String() +} + +// Describes an instance export task. +type ExportToS3TaskSpecification struct { + _ struct{} `type:"structure"` + + // The container format used to combine disk images with metadata (such as OVF). + // If absent, only the disk image is exported. + ContainerFormat *string `locationName:"containerFormat" type:"string" enum:"ContainerFormat"` + + // The format for the exported image. + DiskImageFormat *string `locationName:"diskImageFormat" type:"string" enum:"DiskImageFormat"` + + // The S3 bucket for the destination image. The destination bucket must exist + // and grant WRITE and READ_ACP permissions to the AWS account vm-import-export@amazon.com. + S3Bucket *string `locationName:"s3Bucket" type:"string"` + + // The image is written to a single object in the S3 bucket at the S3 key s3prefix + // + exportTaskId + '.' + diskImageFormat. + S3Prefix *string `locationName:"s3Prefix" type:"string"` +} + +// String returns the string representation +func (s ExportToS3TaskSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportToS3TaskSpecification) GoString() string { + return s.String() +} + +// A filter name and value pair that is used to return a more specific list +// of results. Filters can be used to match a set of resources by various criteria, +// such as tags, attributes, or IDs. +type Filter struct { + _ struct{} `type:"structure"` + + // The name of the filter. Filter names are case-sensitive. + Name *string `type:"string"` + + // One or more filter values. Filter values are case-sensitive. + Values []*string `locationName:"Value" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s Filter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Filter) GoString() string { + return s.String() +} + +// Describes a flow log. +type FlowLog struct { + _ struct{} `type:"structure"` + + // The date and time the flow log was created. + CreationTime *time.Time `locationName:"creationTime" type:"timestamp" timestampFormat:"iso8601"` + + // Information about the error that occurred. Rate limited indicates that CloudWatch + // logs throttling has been applied for one or more network interfaces, or that + // you've reached the limit on the number of CloudWatch Logs log groups that + // you can create. Access error indicates that the IAM role associated with + // the flow log does not have sufficient permissions to publish to CloudWatch + // Logs. Unknown error indicates an internal error. + DeliverLogsErrorMessage *string `locationName:"deliverLogsErrorMessage" type:"string"` + + // The ARN of the IAM role that posts logs to CloudWatch Logs. + DeliverLogsPermissionArn *string `locationName:"deliverLogsPermissionArn" type:"string"` + + // The status of the logs delivery (SUCCESS | FAILED). + DeliverLogsStatus *string `locationName:"deliverLogsStatus" type:"string"` + + // The flow log ID. + FlowLogId *string `locationName:"flowLogId" type:"string"` + + // The status of the flow log (ACTIVE). + FlowLogStatus *string `locationName:"flowLogStatus" type:"string"` + + // The name of the flow log group. + LogGroupName *string `locationName:"logGroupName" type:"string"` + + // The ID of the resource on which the flow log was created. + ResourceId *string `locationName:"resourceId" type:"string"` + + // The type of traffic captured for the flow log. + TrafficType *string `locationName:"trafficType" type:"string" enum:"TrafficType"` +} + +// String returns the string representation +func (s FlowLog) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FlowLog) GoString() string { + return s.String() +} + +// Contains the parameters for GetConsoleOutput. +type GetConsoleOutputInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s GetConsoleOutputInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetConsoleOutputInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetConsoleOutputInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetConsoleOutputInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of GetConsoleOutput. +type GetConsoleOutputOutput struct { + _ struct{} `type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The console output, Base64-encoded. If using a command line tool, the tool + // decodes the output for you. + Output *string `locationName:"output" type:"string"` + + // The time the output was last updated. + Timestamp *time.Time `locationName:"timestamp" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s GetConsoleOutputOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetConsoleOutputOutput) GoString() string { + return s.String() +} + +// Contains the parameters for the request. +type GetConsoleScreenshotInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the instance. + InstanceId *string `type:"string" required:"true"` + + // When set to true, acts as keystroke input and wakes up an instance that's + // in standby or "sleep" mode. + WakeUp *bool `type:"boolean"` +} + +// String returns the string representation +func (s GetConsoleScreenshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetConsoleScreenshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetConsoleScreenshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetConsoleScreenshotInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of the request. +type GetConsoleScreenshotOutput struct { + _ struct{} `type:"structure"` + + // The data that comprises the image. + ImageData *string `locationName:"imageData" type:"string"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` +} + +// String returns the string representation +func (s GetConsoleScreenshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetConsoleScreenshotOutput) GoString() string { + return s.String() +} + +type GetHostReservationPurchasePreviewInput struct { + _ struct{} `type:"structure"` + + // The ID/s of the Dedicated Host/s that the reservation will be associated + // with. + HostIdSet []*string `locationNameList:"item" type:"list" required:"true"` + + // The offering ID of the reservation. + OfferingId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s GetHostReservationPurchasePreviewInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostReservationPurchasePreviewInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHostReservationPurchasePreviewInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHostReservationPurchasePreviewInput"} + if s.HostIdSet == nil { + invalidParams.Add(request.NewErrParamRequired("HostIdSet")) + } + if s.OfferingId == nil { + invalidParams.Add(request.NewErrParamRequired("OfferingId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type GetHostReservationPurchasePreviewOutput struct { + _ struct{} `type:"structure"` + + // The currency in which the totalUpfrontPrice and totalHourlyPrice amounts + // are specified. At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The purchase information of the Dedicated Host Reservation and the Dedicated + // Hosts associated with it. + Purchase []*Purchase `locationName:"purchase" type:"list"` + + // The potential total hourly price of the reservation per hour. + TotalHourlyPrice *string `locationName:"totalHourlyPrice" type:"string"` + + // The potential total upfront price. This is billed immediately. + TotalUpfrontPrice *string `locationName:"totalUpfrontPrice" type:"string"` +} + +// String returns the string representation +func (s GetHostReservationPurchasePreviewOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostReservationPurchasePreviewOutput) GoString() string { + return s.String() +} + +// Contains the parameters for GetPasswordData. +type GetPasswordDataInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the Windows instance. + InstanceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s GetPasswordDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetPasswordDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetPasswordDataInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetPasswordDataInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of GetPasswordData. +type GetPasswordDataOutput struct { + _ struct{} `type:"structure"` + + // The ID of the Windows instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The password of the instance. + PasswordData *string `locationName:"passwordData" type:"string"` + + // The time the data was last updated. + Timestamp *time.Time `locationName:"timestamp" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s GetPasswordDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetPasswordDataOutput) GoString() string { + return s.String() +} + +// Describes a security group. +type GroupIdentifier struct { + _ struct{} `type:"structure"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string"` + + // The name of the security group. + GroupName *string `locationName:"groupName" type:"string"` +} + +// String returns the string representation +func (s GroupIdentifier) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GroupIdentifier) GoString() string { + return s.String() +} + +// Describes an event in the history of the Spot fleet request. +type HistoryRecord struct { + _ struct{} `type:"structure"` + + // Information about the event. + EventInformation *EventInformation `locationName:"eventInformation" type:"structure" required:"true"` + + // The event type. + // + // error - Indicates an error with the Spot fleet request. + // + // fleetRequestChange - Indicates a change in the status or configuration + // of the Spot fleet request. + // + // instanceChange - Indicates that an instance was launched or terminated. + EventType *string `locationName:"eventType" type:"string" required:"true" enum:"EventType"` + + // The date and time of the event, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + Timestamp *time.Time `locationName:"timestamp" type:"timestamp" timestampFormat:"iso8601" required:"true"` +} + +// String returns the string representation +func (s HistoryRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HistoryRecord) GoString() string { + return s.String() +} + +// Describes the properties of the Dedicated Host. +type Host struct { + _ struct{} `type:"structure"` + + // Whether auto-placement is on or off. + AutoPlacement *string `locationName:"autoPlacement" type:"string" enum:"AutoPlacement"` + + // The Availability Zone of the Dedicated Host. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The number of new instances that can be launched onto the Dedicated Host. + AvailableCapacity *AvailableCapacity `locationName:"availableCapacity" type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide. + ClientToken *string `locationName:"clientToken" type:"string"` + + // The ID of the Dedicated Host. + HostId *string `locationName:"hostId" type:"string"` + + // The hardware specifications of the Dedicated Host. + HostProperties *HostProperties `locationName:"hostProperties" type:"structure"` + + // The reservation ID of the Dedicated Host. This returns a null response if + // the Dedicated Host doesn't have an associated reservation. + HostReservationId *string `locationName:"hostReservationId" type:"string"` + + // The IDs and instance type that are currently running on the Dedicated Host. + Instances []*HostInstance `locationName:"instances" locationNameList:"item" type:"list"` + + // The Dedicated Host's state. + State *string `locationName:"state" type:"string" enum:"AllocationState"` +} + +// String returns the string representation +func (s Host) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Host) GoString() string { + return s.String() +} + +// Describes an instance running on a Dedicated Host. +type HostInstance struct { + _ struct{} `type:"structure"` + + // the IDs of instances that are running on the Dedicated Host. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The instance type size (for example, m3.medium) of the running instance. + InstanceType *string `locationName:"instanceType" type:"string"` +} + +// String returns the string representation +func (s HostInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostInstance) GoString() string { + return s.String() +} + +// Details about the Dedicated Host Reservation offering. +type HostOffering struct { + _ struct{} `type:"structure"` + + // The currency of the offering. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The duration of the offering (in seconds). + Duration *int64 `locationName:"duration" type:"integer"` + + // The hourly price of the offering. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance family of the offering. + InstanceFamily *string `locationName:"instanceFamily" type:"string"` + + // The ID of the offering. + OfferingId *string `locationName:"offeringId" type:"string"` + + // The available payment option. + PaymentOption *string `locationName:"paymentOption" type:"string" enum:"PaymentOption"` + + // The upfront price of the offering. Does not apply to No Upfront offerings. + UpfrontPrice *string `locationName:"upfrontPrice" type:"string"` +} + +// String returns the string representation +func (s HostOffering) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostOffering) GoString() string { + return s.String() +} + +// Describes properties of a Dedicated Host. +type HostProperties struct { + _ struct{} `type:"structure"` + + // The number of cores on the Dedicated Host. + Cores *int64 `locationName:"cores" type:"integer"` + + // The instance type size that the Dedicated Host supports (for example, m3.medium). + InstanceType *string `locationName:"instanceType" type:"string"` + + // The number of sockets on the Dedicated Host. + Sockets *int64 `locationName:"sockets" type:"integer"` + + // The number of vCPUs on the Dedicated Host. + TotalVCpus *int64 `locationName:"totalVCpus" type:"integer"` +} + +// String returns the string representation +func (s HostProperties) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostProperties) GoString() string { + return s.String() +} + +// Details about the Dedicated Host Reservation and associated Dedicated Hosts. +type HostReservation struct { + _ struct{} `type:"structure"` + + // The number of Dedicated Hosts the reservation is associated with. + Count *int64 `locationName:"count" type:"integer"` + + // The currency in which the upfrontPrice and hourlyPrice amounts are specified. + // At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The length of the reservation's term, specified in seconds. Can be 31536000 + // (1 year) | 94608000 (3 years). + Duration *int64 `locationName:"duration" type:"integer"` + + // The date and time that the reservation ends. + End *time.Time `locationName:"end" type:"timestamp" timestampFormat:"iso8601"` + + // The IDs of the Dedicated Hosts associated with the reservation. + HostIdSet []*string `locationName:"hostIdSet" locationNameList:"item" type:"list"` + + // The ID of the reservation that specifies the associated Dedicated Hosts. + HostReservationId *string `locationName:"hostReservationId" type:"string"` + + // The hourly price of the reservation. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance family of the Dedicated Host Reservation. The instance family + // on the Dedicated Host must be the same in order for it to benefit from the + // reservation. + InstanceFamily *string `locationName:"instanceFamily" type:"string"` + + // The ID of the reservation. This remains the same regardless of which Dedicated + // Hosts are associated with it. + OfferingId *string `locationName:"offeringId" type:"string"` + + // The payment option selected for this reservation. + PaymentOption *string `locationName:"paymentOption" type:"string" enum:"PaymentOption"` + + // The date and time that the reservation started. + Start *time.Time `locationName:"start" type:"timestamp" timestampFormat:"iso8601"` + + // The state of the reservation. + State *string `locationName:"state" type:"string" enum:"ReservationState"` + + // The upfront price of the reservation. + UpfrontPrice *string `locationName:"upfrontPrice" type:"string"` +} + +// String returns the string representation +func (s HostReservation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostReservation) GoString() string { + return s.String() +} + +// Describes an IAM instance profile. +type IamInstanceProfile struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the instance profile. + Arn *string `locationName:"arn" type:"string"` + + // The ID of the instance profile. + Id *string `locationName:"id" type:"string"` +} + +// String returns the string representation +func (s IamInstanceProfile) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IamInstanceProfile) GoString() string { + return s.String() +} + +// Describes an IAM instance profile. +type IamInstanceProfileSpecification struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the instance profile. + Arn *string `locationName:"arn" type:"string"` + + // The name of the instance profile. + Name *string `locationName:"name" type:"string"` +} + +// String returns the string representation +func (s IamInstanceProfileSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IamInstanceProfileSpecification) GoString() string { + return s.String() +} + +// Describes the ICMP type and code. +type IcmpTypeCode struct { + _ struct{} `type:"structure"` + + // The ICMP type. A value of -1 means all types. + Code *int64 `locationName:"code" type:"integer"` + + // The ICMP code. A value of -1 means all codes for the specified ICMP type. + Type *int64 `locationName:"type" type:"integer"` +} + +// String returns the string representation +func (s IcmpTypeCode) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IcmpTypeCode) GoString() string { + return s.String() +} + +// Describes the ID format for a resource. +type IdFormat struct { + _ struct{} `type:"structure"` + + // The date in UTC at which you are permanently switched over to using longer + // IDs. If a deadline is not yet available for this resource type, this field + // is not returned. + Deadline *time.Time `locationName:"deadline" type:"timestamp" timestampFormat:"iso8601"` + + // The type of resource. + Resource *string `locationName:"resource" type:"string"` + + // Indicates whether longer IDs (17-character IDs) are enabled for the resource. + UseLongIds *bool `locationName:"useLongIds" type:"boolean"` +} + +// String returns the string representation +func (s IdFormat) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IdFormat) GoString() string { + return s.String() +} + +// Describes an image. +type Image struct { + _ struct{} `type:"structure"` + + // The architecture of the image. + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` + + // Any block device mapping entries. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // The date and time the image was created. + CreationDate *string `locationName:"creationDate" type:"string"` + + // The description of the AMI that was provided during image creation. + Description *string `locationName:"description" type:"string"` + + // Specifies whether enhanced networking with ENA is enabled. + EnaSupport *bool `locationName:"enaSupport" type:"boolean"` + + // The hypervisor type of the image. + Hypervisor *string `locationName:"hypervisor" type:"string" enum:"HypervisorType"` + + // The ID of the AMI. + ImageId *string `locationName:"imageId" type:"string"` + + // The location of the AMI. + ImageLocation *string `locationName:"imageLocation" type:"string"` + + // The AWS account alias (for example, amazon, self) or the AWS account ID of + // the AMI owner. + ImageOwnerAlias *string `locationName:"imageOwnerAlias" type:"string"` + + // The type of image. + ImageType *string `locationName:"imageType" type:"string" enum:"ImageTypeValues"` + + // The kernel associated with the image, if any. Only applicable for machine + // images. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the AMI that was provided during image creation. + Name *string `locationName:"name" type:"string"` + + // The AWS account ID of the image owner. + OwnerId *string `locationName:"imageOwnerId" type:"string"` + + // The value is Windows for Windows AMIs; otherwise blank. + Platform *string `locationName:"platform" type:"string" enum:"PlatformValues"` + + // Any product codes associated with the AMI. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // Indicates whether the image has public launch permissions. The value is true + // if this image has public launch permissions or false if it has only implicit + // and explicit launch permissions. + Public *bool `locationName:"isPublic" type:"boolean"` + + // The RAM disk associated with the image, if any. Only applicable for machine + // images. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + // The device name of the root device (for example, /dev/sda1 or /dev/xvda). + RootDeviceName *string `locationName:"rootDeviceName" type:"string"` + + // The type of root device used by the AMI. The AMI can use an EBS volume or + // an instance store volume. + RootDeviceType *string `locationName:"rootDeviceType" type:"string" enum:"DeviceType"` + + // Specifies whether enhanced networking with the Intel 82599 Virtual Function + // interface is enabled. + SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` + + // The current state of the AMI. If the state is available, the image is successfully + // registered and can be used to launch an instance. + State *string `locationName:"imageState" type:"string" enum:"ImageState"` + + // The reason for the state change. + StateReason *StateReason `locationName:"stateReason" type:"structure"` + + // Any tags assigned to the image. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The type of virtualization of the AMI. + VirtualizationType *string `locationName:"virtualizationType" type:"string" enum:"VirtualizationType"` +} + +// String returns the string representation +func (s Image) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Image) GoString() string { + return s.String() +} + +// Describes the disk container object for an import image task. +type ImageDiskContainer struct { + _ struct{} `type:"structure"` + + // The description of the disk image. + Description *string `type:"string"` + + // The block device mapping for the disk. + DeviceName *string `type:"string"` + + // The format of the disk image being imported. + // + // Valid values: RAW | VHD | VMDK | OVA + Format *string `type:"string"` + + // The ID of the EBS snapshot to be used for importing the snapshot. + SnapshotId *string `type:"string"` + + // The URL to the Amazon S3-based disk image being imported. The URL can either + // be a https URL (https://..) or an Amazon S3 URL (s3://..) + Url *string `type:"string"` + + // The S3 bucket for the disk image. + UserBucket *UserBucket `type:"structure"` +} + +// String returns the string representation +func (s ImageDiskContainer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImageDiskContainer) GoString() string { + return s.String() +} + +// Contains the parameters for ImportImage. +type ImportImageInput struct { + _ struct{} `type:"structure"` + + // The architecture of the virtual machine. + // + // Valid values: i386 | x86_64 + Architecture *string `type:"string"` + + // The client-specific data. + ClientData *ClientData `type:"structure"` + + // The token to enable idempotency for VM import requests. + ClientToken *string `type:"string"` + + // A description string for the import image task. + Description *string `type:"string"` + + // Information about the disk containers. + DiskContainers []*ImageDiskContainer `locationName:"DiskContainer" locationNameList:"item" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The target hypervisor platform. + // + // Valid values: xen + Hypervisor *string `type:"string"` + + // The license type to be used for the Amazon Machine Image (AMI) after importing. + // + // Note: You may only use BYOL if you have existing licenses with rights to + // use these licenses in a third party cloud like AWS. For more information, + // see Prerequisites (http://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html#prerequisites-image) + // in the VM Import/Export User Guide. + // + // Valid values: AWS | BYOL + LicenseType *string `type:"string"` + + // The operating system of the virtual machine. + // + // Valid values: Windows | Linux + Platform *string `type:"string"` + + // The name of the role to use when not using the default role, 'vmimport'. + RoleName *string `type:"string"` +} + +// String returns the string representation +func (s ImportImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportImageInput) GoString() string { + return s.String() +} + +// Contains the output for ImportImage. +type ImportImageOutput struct { + _ struct{} `type:"structure"` + + // The architecture of the virtual machine. + Architecture *string `locationName:"architecture" type:"string"` + + // A description of the import task. + Description *string `locationName:"description" type:"string"` + + // The target hypervisor of the import task. + Hypervisor *string `locationName:"hypervisor" type:"string"` + + // The ID of the Amazon Machine Image (AMI) created by the import task. + ImageId *string `locationName:"imageId" type:"string"` + + // The task ID of the import image task. + ImportTaskId *string `locationName:"importTaskId" type:"string"` + + // The license type of the virtual machine. + LicenseType *string `locationName:"licenseType" type:"string"` + + // The operating system of the virtual machine. + Platform *string `locationName:"platform" type:"string"` + + // The progress of the task. + Progress *string `locationName:"progress" type:"string"` + + // Information about the snapshots. + SnapshotDetails []*SnapshotDetail `locationName:"snapshotDetailSet" locationNameList:"item" type:"list"` + + // A brief status of the task. + Status *string `locationName:"status" type:"string"` + + // A detailed status message of the import task. + StatusMessage *string `locationName:"statusMessage" type:"string"` +} + +// String returns the string representation +func (s ImportImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportImageOutput) GoString() string { + return s.String() +} + +// Describes an import image task. +type ImportImageTask struct { + _ struct{} `type:"structure"` + + // The architecture of the virtual machine. + // + // Valid values: i386 | x86_64 + Architecture *string `locationName:"architecture" type:"string"` + + // A description of the import task. + Description *string `locationName:"description" type:"string"` + + // The target hypervisor for the import task. + // + // Valid values: xen + Hypervisor *string `locationName:"hypervisor" type:"string"` + + // The ID of the Amazon Machine Image (AMI) of the imported virtual machine. + ImageId *string `locationName:"imageId" type:"string"` + + // The ID of the import image task. + ImportTaskId *string `locationName:"importTaskId" type:"string"` + + // The license type of the virtual machine. + LicenseType *string `locationName:"licenseType" type:"string"` + + // The description string for the import image task. + Platform *string `locationName:"platform" type:"string"` + + // The percentage of progress of the import image task. + Progress *string `locationName:"progress" type:"string"` + + // Information about the snapshots. + SnapshotDetails []*SnapshotDetail `locationName:"snapshotDetailSet" locationNameList:"item" type:"list"` + + // A brief status for the import image task. + Status *string `locationName:"status" type:"string"` + + // A descriptive status message for the import image task. + StatusMessage *string `locationName:"statusMessage" type:"string"` +} + +// String returns the string representation +func (s ImportImageTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportImageTask) GoString() string { + return s.String() +} + +// Contains the parameters for ImportInstance. +type ImportInstanceInput struct { + _ struct{} `type:"structure"` + + // A description for the instance being imported. + Description *string `locationName:"description" type:"string"` + + // The disk image. + DiskImages []*DiskImage `locationName:"diskImage" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The launch specification. + LaunchSpecification *ImportInstanceLaunchSpecification `locationName:"launchSpecification" type:"structure"` + + // The instance operating system. + Platform *string `locationName:"platform" type:"string" required:"true" enum:"PlatformValues"` +} + +// String returns the string representation +func (s ImportInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ImportInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ImportInstanceInput"} + if s.Platform == nil { + invalidParams.Add(request.NewErrParamRequired("Platform")) + } + if s.DiskImages != nil { + for i, v := range s.DiskImages { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "DiskImages", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes the launch specification for VM import. +type ImportInstanceLaunchSpecification struct { + _ struct{} `type:"structure"` + + // Reserved. + AdditionalInfo *string `locationName:"additionalInfo" type:"string"` + + // The architecture of the instance. + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` + + // One or more security group IDs. + GroupIds []*string `locationName:"GroupId" locationNameList:"SecurityGroupId" type:"list"` + + // One or more security group names. + GroupNames []*string `locationName:"GroupName" locationNameList:"SecurityGroup" type:"list"` + + // Indicates whether an instance stops or terminates when you initiate shutdown + // from the instance (using the operating system command for system shutdown). + InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` + + // The instance type. For more information about the instance types that you + // can import, see Instance Types (http://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html#vmimport-instance-types) + // in the VM Import/Export User Guide. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // Indicates whether monitoring is enabled. + Monitoring *bool `locationName:"monitoring" type:"boolean"` + + // The placement information for the instance. + Placement *Placement `locationName:"placement" type:"structure"` + + // [EC2-VPC] An available IP address from the IP address range of the subnet. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // [EC2-VPC] The ID of the subnet in which to launch the instance. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The user data to make available to the instance. If you are using an AWS + // SDK or command line tool, Base64-encoding is performed for you, and you can + // load the text from a file. Otherwise, you must provide Base64-encoded text. + UserData *UserData `locationName:"userData" type:"structure"` +} + +// String returns the string representation +func (s ImportInstanceLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceLaunchSpecification) GoString() string { + return s.String() +} + +// Contains the output for ImportInstance. +type ImportInstanceOutput struct { + _ struct{} `type:"structure"` + + // Information about the conversion task. + ConversionTask *ConversionTask `locationName:"conversionTask" type:"structure"` +} + +// String returns the string representation +func (s ImportInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceOutput) GoString() string { + return s.String() +} + +// Describes an import instance task. +type ImportInstanceTaskDetails struct { + _ struct{} `type:"structure"` + + // A description of the task. + Description *string `locationName:"description" type:"string"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The instance operating system. + Platform *string `locationName:"platform" type:"string" enum:"PlatformValues"` + + // One or more volumes. + Volumes []*ImportInstanceVolumeDetailItem `locationName:"volumes" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s ImportInstanceTaskDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceTaskDetails) GoString() string { + return s.String() +} + +// Describes an import volume task. +type ImportInstanceVolumeDetailItem struct { + _ struct{} `type:"structure"` + + // The Availability Zone where the resulting instance will reside. + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The number of bytes converted so far. + BytesConverted *int64 `locationName:"bytesConverted" type:"long" required:"true"` + + // A description of the task. + Description *string `locationName:"description" type:"string"` + + // The image. + Image *DiskImageDescription `locationName:"image" type:"structure" required:"true"` + + // The status of the import of this particular disk image. + Status *string `locationName:"status" type:"string" required:"true"` + + // The status information or errors related to the disk image. + StatusMessage *string `locationName:"statusMessage" type:"string"` + + // The volume. + Volume *DiskImageVolumeDescription `locationName:"volume" type:"structure" required:"true"` +} + +// String returns the string representation +func (s ImportInstanceVolumeDetailItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceVolumeDetailItem) GoString() string { + return s.String() +} + +// Contains the parameters for ImportKeyPair. +type ImportKeyPairInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // A unique name for the key pair. + KeyName *string `locationName:"keyName" type:"string" required:"true"` + + // The public key. For API calls, the text must be base64-encoded. For command + // line tools, base64 encoding is performed for you. + // + // PublicKeyMaterial is automatically base64 encoded/decoded by the SDK. + PublicKeyMaterial []byte `locationName:"publicKeyMaterial" type:"blob" required:"true"` +} + +// String returns the string representation +func (s ImportKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ImportKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ImportKeyPairInput"} + if s.KeyName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyName")) + } + if s.PublicKeyMaterial == nil { + invalidParams.Add(request.NewErrParamRequired("PublicKeyMaterial")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ImportKeyPair. +type ImportKeyPairOutput struct { + _ struct{} `type:"structure"` + + // The MD5 public key fingerprint as specified in section 4 of RFC 4716. + KeyFingerprint *string `locationName:"keyFingerprint" type:"string"` + + // The key pair name you provided. + KeyName *string `locationName:"keyName" type:"string"` +} + +// String returns the string representation +func (s ImportKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportKeyPairOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ImportSnapshot. +type ImportSnapshotInput struct { + _ struct{} `type:"structure"` + + // The client-specific data. + ClientData *ClientData `type:"structure"` + + // Token to enable idempotency for VM import requests. + ClientToken *string `type:"string"` + + // The description string for the import snapshot task. + Description *string `type:"string"` + + // Information about the disk container. + DiskContainer *SnapshotDiskContainer `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The name of the role to use when not using the default role, 'vmimport'. + RoleName *string `type:"string"` +} + +// String returns the string representation +func (s ImportSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportSnapshotInput) GoString() string { + return s.String() +} + +// Contains the output for ImportSnapshot. +type ImportSnapshotOutput struct { + _ struct{} `type:"structure"` + + // A description of the import snapshot task. + Description *string `locationName:"description" type:"string"` + + // The ID of the import snapshot task. + ImportTaskId *string `locationName:"importTaskId" type:"string"` + + // Information about the import snapshot task. + SnapshotTaskDetail *SnapshotTaskDetail `locationName:"snapshotTaskDetail" type:"structure"` +} + +// String returns the string representation +func (s ImportSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportSnapshotOutput) GoString() string { + return s.String() +} + +// Describes an import snapshot task. +type ImportSnapshotTask struct { + _ struct{} `type:"structure"` + + // A description of the import snapshot task. + Description *string `locationName:"description" type:"string"` + + // The ID of the import snapshot task. + ImportTaskId *string `locationName:"importTaskId" type:"string"` + + // Describes an import snapshot task. + SnapshotTaskDetail *SnapshotTaskDetail `locationName:"snapshotTaskDetail" type:"structure"` +} + +// String returns the string representation +func (s ImportSnapshotTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportSnapshotTask) GoString() string { + return s.String() +} + +// Contains the parameters for ImportVolume. +type ImportVolumeInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone for the resulting EBS volume. + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // A description of the volume. + Description *string `locationName:"description" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The disk image. + Image *DiskImageDetail `locationName:"image" type:"structure" required:"true"` + + // The volume size. + Volume *VolumeDetail `locationName:"volume" type:"structure" required:"true"` +} + +// String returns the string representation +func (s ImportVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportVolumeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ImportVolumeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ImportVolumeInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.Image == nil { + invalidParams.Add(request.NewErrParamRequired("Image")) + } + if s.Volume == nil { + invalidParams.Add(request.NewErrParamRequired("Volume")) + } + if s.Image != nil { + if err := s.Image.Validate(); err != nil { + invalidParams.AddNested("Image", err.(request.ErrInvalidParams)) + } + } + if s.Volume != nil { + if err := s.Volume.Validate(); err != nil { + invalidParams.AddNested("Volume", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output for ImportVolume. +type ImportVolumeOutput struct { + _ struct{} `type:"structure"` + + // Information about the conversion task. + ConversionTask *ConversionTask `locationName:"conversionTask" type:"structure"` +} + +// String returns the string representation +func (s ImportVolumeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportVolumeOutput) GoString() string { + return s.String() +} + +// Describes an import volume task. +type ImportVolumeTaskDetails struct { + _ struct{} `type:"structure"` + + // The Availability Zone where the resulting volume will reside. + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The number of bytes converted so far. + BytesConverted *int64 `locationName:"bytesConverted" type:"long" required:"true"` + + // The description you provided when starting the import volume task. + Description *string `locationName:"description" type:"string"` + + // The image. + Image *DiskImageDescription `locationName:"image" type:"structure" required:"true"` + + // The volume. + Volume *DiskImageVolumeDescription `locationName:"volume" type:"structure" required:"true"` +} + +// String returns the string representation +func (s ImportVolumeTaskDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportVolumeTaskDetails) GoString() string { + return s.String() +} + +// Describes an instance. +type Instance struct { + _ struct{} `type:"structure"` + + // The AMI launch index, which can be used to find this instance in the launch + // group. + AmiLaunchIndex *int64 `locationName:"amiLaunchIndex" type:"integer"` + + // The architecture of the image. + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` + + // Any block device mapping entries for the instance. + BlockDeviceMappings []*InstanceBlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // The idempotency token you provided when you launched the instance, if applicable. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Indicates whether the instance is optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS + // Optimized instance. + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // Specifies whether enhanced networking with ENA is enabled. + EnaSupport *bool `locationName:"enaSupport" type:"boolean"` + + // The hypervisor type of the instance. + Hypervisor *string `locationName:"hypervisor" type:"string" enum:"HypervisorType"` + + // The IAM instance profile associated with the instance, if applicable. + IamInstanceProfile *IamInstanceProfile `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI used to launch the instance. + ImageId *string `locationName:"imageId" type:"string"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // Indicates whether this is a Spot instance or a Scheduled Instance. + InstanceLifecycle *string `locationName:"instanceLifecycle" type:"string" enum:"InstanceLifecycleType"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The kernel associated with this instance, if applicable. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the key pair, if this instance was launched with an associated + // key pair. + KeyName *string `locationName:"keyName" type:"string"` + + // The time the instance was launched. + LaunchTime *time.Time `locationName:"launchTime" type:"timestamp" timestampFormat:"iso8601"` + + // The monitoring information for the instance. + Monitoring *Monitoring `locationName:"monitoring" type:"structure"` + + // [EC2-VPC] One or more network interfaces for the instance. + NetworkInterfaces []*InstanceNetworkInterface `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` + + // The location where the instance launched, if applicable. + Placement *Placement `locationName:"placement" type:"structure"` + + // The value is Windows for Windows instances; otherwise blank. + Platform *string `locationName:"platform" type:"string" enum:"PlatformValues"` + + // The private DNS name assigned to the instance. This DNS name can only be + // used inside the Amazon EC2 network. This name is not available until the + // instance enters the running state. For EC2-VPC, this name is only available + // if you've enabled DNS hostnames for your VPC. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The private IP address assigned to the instance. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The product codes attached to this instance, if applicable. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // The public DNS name assigned to the instance. This name is not available + // until the instance enters the running state. For EC2-VPC, this name is only + // available if you've enabled DNS hostnames for your VPC. + PublicDnsName *string `locationName:"dnsName" type:"string"` + + // The public IP address assigned to the instance, if applicable. + PublicIpAddress *string `locationName:"ipAddress" type:"string"` + + // The RAM disk associated with this instance, if applicable. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + // The root device name (for example, /dev/sda1 or /dev/xvda). + RootDeviceName *string `locationName:"rootDeviceName" type:"string"` + + // The root device type used by the AMI. The AMI can use an EBS volume or an + // instance store volume. + RootDeviceType *string `locationName:"rootDeviceType" type:"string" enum:"DeviceType"` + + // One or more security groups for the instance. + SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // Specifies whether to enable an instance launched in a VPC to perform NAT. + // This controls whether source/destination checking is enabled on the instance. + // A value of true means checking is enabled, and false means checking is disabled. + // The value must be false for the instance to perform NAT. For more information, + // see NAT Instances (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html) + // in the Amazon Virtual Private Cloud User Guide. + SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` + + // If the request is a Spot instance request, the ID of the request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` + + // Specifies whether enhanced networking with the Intel 82599 Virtual Function + // interface is enabled. + SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` + + // The current state of the instance. + State *InstanceState `locationName:"instanceState" type:"structure"` + + // The reason for the most recent state transition. + StateReason *StateReason `locationName:"stateReason" type:"structure"` + + // The reason for the most recent state transition. This might be an empty string. + StateTransitionReason *string `locationName:"reason" type:"string"` + + // [EC2-VPC] The ID of the subnet in which the instance is running. + SubnetId *string `locationName:"subnetId" type:"string"` + + // Any tags assigned to the instance. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The virtualization type of the instance. + VirtualizationType *string `locationName:"virtualizationType" type:"string" enum:"VirtualizationType"` + + // [EC2-VPC] The ID of the VPC in which the instance is running. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s Instance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Instance) GoString() string { + return s.String() +} + +// Describes a block device mapping. +type InstanceBlockDeviceMapping struct { + _ struct{} `type:"structure"` + + // The device name exposed to the instance (for example, /dev/sdh or xvdh). + DeviceName *string `locationName:"deviceName" type:"string"` + + // Parameters used to automatically set up EBS volumes when the instance is + // launched. + Ebs *EbsInstanceBlockDevice `locationName:"ebs" type:"structure"` +} + +// String returns the string representation +func (s InstanceBlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceBlockDeviceMapping) GoString() string { + return s.String() +} + +// Describes a block device mapping entry. +type InstanceBlockDeviceMappingSpecification struct { + _ struct{} `type:"structure"` + + // The device name exposed to the instance (for example, /dev/sdh or xvdh). + DeviceName *string `locationName:"deviceName" type:"string"` + + // Parameters used to automatically set up EBS volumes when the instance is + // launched. + Ebs *EbsInstanceBlockDeviceSpecification `locationName:"ebs" type:"structure"` + + // suppress the specified device included in the block device mapping. + NoDevice *string `locationName:"noDevice" type:"string"` + + // The virtual device name. + VirtualName *string `locationName:"virtualName" type:"string"` +} + +// String returns the string representation +func (s InstanceBlockDeviceMappingSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceBlockDeviceMappingSpecification) GoString() string { + return s.String() +} + +// Information about the instance type that the Dedicated Host supports. +type InstanceCapacity struct { + _ struct{} `type:"structure"` + + // The number of instances that can still be launched onto the Dedicated Host. + AvailableCapacity *int64 `locationName:"availableCapacity" type:"integer"` + + // The instance type size supported by the Dedicated Host. + InstanceType *string `locationName:"instanceType" type:"string"` + + // The total number of instances that can be launched onto the Dedicated Host. + TotalCapacity *int64 `locationName:"totalCapacity" type:"integer"` +} + +// String returns the string representation +func (s InstanceCapacity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceCapacity) GoString() string { + return s.String() +} + +// Describes a Reserved Instance listing state. +type InstanceCount struct { + _ struct{} `type:"structure"` + + // The number of listed Reserved Instances in the state specified by the state. + InstanceCount *int64 `locationName:"instanceCount" type:"integer"` + + // The states of the listed Reserved Instances. + State *string `locationName:"state" type:"string" enum:"ListingState"` +} + +// String returns the string representation +func (s InstanceCount) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceCount) GoString() string { + return s.String() +} + +// Describes an instance to export. +type InstanceExportDetails struct { + _ struct{} `type:"structure"` + + // The ID of the resource being exported. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The target virtualization environment. + TargetEnvironment *string `locationName:"targetEnvironment" type:"string" enum:"ExportEnvironment"` +} + +// String returns the string representation +func (s InstanceExportDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceExportDetails) GoString() string { + return s.String() +} + +// Describes the monitoring information of the instance. +type InstanceMonitoring struct { + _ struct{} `type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The monitoring information. + Monitoring *Monitoring `locationName:"monitoring" type:"structure"` +} + +// String returns the string representation +func (s InstanceMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceMonitoring) GoString() string { + return s.String() +} + +// Describes a network interface. +type InstanceNetworkInterface struct { + _ struct{} `type:"structure"` + + // The association information for an Elastic IP associated with the network + // interface. + Association *InstanceNetworkInterfaceAssociation `locationName:"association" type:"structure"` + + // The network interface attachment. + Attachment *InstanceNetworkInterfaceAttachment `locationName:"attachment" type:"structure"` + + // The description. + Description *string `locationName:"description" type:"string"` + + // One or more security groups. + Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The MAC address. + MacAddress *string `locationName:"macAddress" type:"string"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The ID of the AWS account that created the network interface. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The private DNS name. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The IP address of the network interface within the subnet. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The private IP addresses associated with the network interface. + PrivateIpAddresses []*InstancePrivateIpAddress `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` + + // Indicates whether to validate network traffic to or from this network interface. + SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` + + // The status of the network interface. + Status *string `locationName:"status" type:"string" enum:"NetworkInterfaceStatus"` + + // The ID of the subnet. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s InstanceNetworkInterface) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterface) GoString() string { + return s.String() +} + +// Describes association information for an Elastic IP address. +type InstanceNetworkInterfaceAssociation struct { + _ struct{} `type:"structure"` + + // The ID of the owner of the Elastic IP address. + IpOwnerId *string `locationName:"ipOwnerId" type:"string"` + + // The public DNS name. + PublicDnsName *string `locationName:"publicDnsName" type:"string"` + + // The public IP address or Elastic IP address bound to the network interface. + PublicIp *string `locationName:"publicIp" type:"string"` +} + +// String returns the string representation +func (s InstanceNetworkInterfaceAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterfaceAssociation) GoString() string { + return s.String() +} + +// Describes a network interface attachment. +type InstanceNetworkInterfaceAttachment struct { + _ struct{} `type:"structure"` + + // The time stamp when the attachment initiated. + AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` + + // The ID of the network interface attachment. + AttachmentId *string `locationName:"attachmentId" type:"string"` + + // Indicates whether the network interface is deleted when the instance is terminated. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // The index of the device on the instance for the network interface attachment. + DeviceIndex *int64 `locationName:"deviceIndex" type:"integer"` + + // The attachment state. + Status *string `locationName:"status" type:"string" enum:"AttachmentStatus"` +} + +// String returns the string representation +func (s InstanceNetworkInterfaceAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterfaceAttachment) GoString() string { + return s.String() +} + +// Describes a network interface. +type InstanceNetworkInterfaceSpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether to assign a public IP address to an instance you launch + // in a VPC. The public IP address can only be assigned to a network interface + // for eth0, and can only be assigned to a new network interface, not an existing + // one. You cannot specify more than one network interface in the request. If + // launching into a default subnet, the default value is true. + AssociatePublicIpAddress *bool `locationName:"associatePublicIpAddress" type:"boolean"` + + // If set to true, the interface is deleted when the instance is terminated. + // You can specify true only if creating a new network interface when launching + // an instance. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // The description of the network interface. Applies only if creating a network + // interface when launching an instance. + Description *string `locationName:"description" type:"string"` + + // The index of the device on the instance for the network interface attachment. + // If you are specifying a network interface in a RunInstances request, you + // must provide the device index. + DeviceIndex *int64 `locationName:"deviceIndex" type:"integer"` + + // The IDs of the security groups for the network interface. Applies only if + // creating a network interface when launching an instance. + Groups []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The private IP address of the network interface. Applies only if creating + // a network interface when launching an instance. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // One or more private IP addresses to assign to the network interface. Only + // one private IP address can be designated as primary. + PrivateIpAddresses []*PrivateIpAddressSpecification `locationName:"privateIpAddressesSet" queryName:"PrivateIpAddresses" locationNameList:"item" type:"list"` + + // The number of secondary private IP addresses. You can't specify this option + // and specify more than one private IP address using the private IP addresses + // option. + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` + + // The ID of the subnet associated with the network string. Applies only if + // creating a network interface when launching an instance. + SubnetId *string `locationName:"subnetId" type:"string"` +} + +// String returns the string representation +func (s InstanceNetworkInterfaceSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterfaceSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *InstanceNetworkInterfaceSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "InstanceNetworkInterfaceSpecification"} + if s.PrivateIpAddresses != nil { + for i, v := range s.PrivateIpAddresses { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PrivateIpAddresses", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a private IP address. +type InstancePrivateIpAddress struct { + _ struct{} `type:"structure"` + + // The association information for an Elastic IP address for the network interface. + Association *InstanceNetworkInterfaceAssociation `locationName:"association" type:"structure"` + + // Indicates whether this IP address is the primary private IP address of the + // network interface. + Primary *bool `locationName:"primary" type:"boolean"` + + // The private DNS name. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The private IP address of the network interface. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` +} + +// String returns the string representation +func (s InstancePrivateIpAddress) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstancePrivateIpAddress) GoString() string { + return s.String() +} + +// Describes the current state of the instance. +type InstanceState struct { + _ struct{} `type:"structure"` + + // The low byte represents the state. The high byte is an opaque internal value + // and should be ignored. + // + // 0 : pending + // + // 16 : running + // + // 32 : shutting-down + // + // 48 : terminated + // + // 64 : stopping + // + // 80 : stopped + Code *int64 `locationName:"code" type:"integer"` + + // The current state of the instance. + Name *string `locationName:"name" type:"string" enum:"InstanceStateName"` +} + +// String returns the string representation +func (s InstanceState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceState) GoString() string { + return s.String() +} + +// Describes an instance state change. +type InstanceStateChange struct { + _ struct{} `type:"structure"` + + // The current state of the instance. + CurrentState *InstanceState `locationName:"currentState" type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The previous state of the instance. + PreviousState *InstanceState `locationName:"previousState" type:"structure"` +} + +// String returns the string representation +func (s InstanceStateChange) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStateChange) GoString() string { + return s.String() +} + +// Describes the status of an instance. +type InstanceStatus struct { + _ struct{} `type:"structure"` + + // The Availability Zone of the instance. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // Any scheduled events associated with the instance. + Events []*InstanceStatusEvent `locationName:"eventsSet" locationNameList:"item" type:"list"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The intended state of the instance. DescribeInstanceStatus requires that + // an instance be in the running state. + InstanceState *InstanceState `locationName:"instanceState" type:"structure"` + + // Reports impaired functionality that stems from issues internal to the instance, + // such as impaired reachability. + InstanceStatus *InstanceStatusSummary `locationName:"instanceStatus" type:"structure"` + + // Reports impaired functionality that stems from issues related to the systems + // that support an instance, such as hardware failures and network connectivity + // problems. + SystemStatus *InstanceStatusSummary `locationName:"systemStatus" type:"structure"` +} + +// String returns the string representation +func (s InstanceStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatus) GoString() string { + return s.String() +} + +// Describes the instance status. +type InstanceStatusDetails struct { + _ struct{} `type:"structure"` + + // The time when a status check failed. For an instance that was launched and + // impaired, this is the time when the instance was launched. + ImpairedSince *time.Time `locationName:"impairedSince" type:"timestamp" timestampFormat:"iso8601"` + + // The type of instance status. + Name *string `locationName:"name" type:"string" enum:"StatusName"` + + // The status. + Status *string `locationName:"status" type:"string" enum:"StatusType"` +} + +// String returns the string representation +func (s InstanceStatusDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatusDetails) GoString() string { + return s.String() +} + +// Describes a scheduled event for an instance. +type InstanceStatusEvent struct { + _ struct{} `type:"structure"` + + // The event code. + Code *string `locationName:"code" type:"string" enum:"EventCode"` + + // A description of the event. + // + // After a scheduled event is completed, it can still be described for up to + // a week. If the event has been completed, this description starts with the + // following text: [Completed]. + Description *string `locationName:"description" type:"string"` + + // The latest scheduled end time for the event. + NotAfter *time.Time `locationName:"notAfter" type:"timestamp" timestampFormat:"iso8601"` + + // The earliest scheduled start time for the event. + NotBefore *time.Time `locationName:"notBefore" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s InstanceStatusEvent) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatusEvent) GoString() string { + return s.String() +} + +// Describes the status of an instance. +type InstanceStatusSummary struct { + _ struct{} `type:"structure"` + + // The system instance health or application instance health. + Details []*InstanceStatusDetails `locationName:"details" locationNameList:"item" type:"list"` + + // The status. + Status *string `locationName:"status" type:"string" enum:"SummaryStatus"` +} + +// String returns the string representation +func (s InstanceStatusSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatusSummary) GoString() string { + return s.String() +} + +// Describes an Internet gateway. +type InternetGateway struct { + _ struct{} `type:"structure"` + + // Any VPCs attached to the Internet gateway. + Attachments []*InternetGatewayAttachment `locationName:"attachmentSet" locationNameList:"item" type:"list"` + + // The ID of the Internet gateway. + InternetGatewayId *string `locationName:"internetGatewayId" type:"string"` + + // Any tags assigned to the Internet gateway. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s InternetGateway) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InternetGateway) GoString() string { + return s.String() +} + +// Describes the attachment of a VPC to an Internet gateway. +type InternetGatewayAttachment struct { + _ struct{} `type:"structure"` + + // The current state of the attachment. + State *string `locationName:"state" type:"string" enum:"AttachmentStatus"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s InternetGatewayAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InternetGatewayAttachment) GoString() string { + return s.String() +} + +// Describes a security group rule. +type IpPermission struct { + _ struct{} `type:"structure"` + + // The start of port range for the TCP and UDP protocols, or an ICMP type number. + // A value of -1 indicates all ICMP types. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The IP protocol name (for tcp, udp, and icmp) or number (see Protocol Numbers + // (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). + // + // [EC2-VPC only] When you authorize or revoke security group rules, you can + // use -1 to specify all. + IpProtocol *string `locationName:"ipProtocol" type:"string"` + + // One or more IP ranges. + IpRanges []*IpRange `locationName:"ipRanges" locationNameList:"item" type:"list"` + + // (Valid for AuthorizeSecurityGroupEgress, RevokeSecurityGroupEgress and DescribeSecurityGroups + // only) One or more prefix list IDs for an AWS service. In an AuthorizeSecurityGroupEgress + // request, this is the AWS service that you want to access through a VPC endpoint + // from instances associated with the security group. + PrefixListIds []*PrefixListId `locationName:"prefixListIds" locationNameList:"item" type:"list"` + + // The end of port range for the TCP and UDP protocols, or an ICMP code. A value + // of -1 indicates all ICMP codes for the specified ICMP type. + ToPort *int64 `locationName:"toPort" type:"integer"` + + // One or more security group and AWS account ID pairs. + UserIdGroupPairs []*UserIdGroupPair `locationName:"groups" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s IpPermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IpPermission) GoString() string { + return s.String() +} + +// Describes an IP range. +type IpRange struct { + _ struct{} `type:"structure"` + + // The CIDR range. You can either specify a CIDR range or a source security + // group, not both. + CidrIp *string `locationName:"cidrIp" type:"string"` +} + +// String returns the string representation +func (s IpRange) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IpRange) GoString() string { + return s.String() +} + +// Describes a key pair. +type KeyPairInfo struct { + _ struct{} `type:"structure"` + + // If you used CreateKeyPair to create the key pair, this is the SHA-1 digest + // of the DER encoded private key. If you used ImportKeyPair to provide AWS + // the public key, this is the MD5 public key fingerprint as specified in section + // 4 of RFC4716. + KeyFingerprint *string `locationName:"keyFingerprint" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` +} + +// String returns the string representation +func (s KeyPairInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s KeyPairInfo) GoString() string { + return s.String() +} + +// Describes a launch permission. +type LaunchPermission struct { + _ struct{} `type:"structure"` + + // The name of the group. + Group *string `locationName:"group" type:"string" enum:"PermissionGroup"` + + // The AWS account ID. + UserId *string `locationName:"userId" type:"string"` +} + +// String returns the string representation +func (s LaunchPermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchPermission) GoString() string { + return s.String() +} + +// Describes a launch permission modification. +type LaunchPermissionModifications struct { + _ struct{} `type:"structure"` + + // The AWS account ID to add to the list of launch permissions for the AMI. + Add []*LaunchPermission `locationNameList:"item" type:"list"` + + // The AWS account ID to remove from the list of launch permissions for the + // AMI. + Remove []*LaunchPermission `locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s LaunchPermissionModifications) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchPermissionModifications) GoString() string { + return s.String() +} + +// Describes the launch specification for an instance. +type LaunchSpecification struct { + _ struct{} `type:"structure"` + + // Deprecated. + AddressingType *string `locationName:"addressingType" type:"string"` + + // One or more block device mapping entries. + // + // Although you can specify encrypted EBS volumes in this block device mapping + // for your Spot Instances, these volumes are not encrypted. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // Indicates whether the instance is optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS + // Optimized instance. + // + // Default: false + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // The IAM instance profile. + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI. + ImageId *string `locationName:"imageId" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The ID of the kernel. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` + + // Describes the monitoring for the instance. + Monitoring *RunInstancesMonitoringEnabled `locationName:"monitoring" type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*InstanceNetworkInterfaceSpecification `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` + + // The placement information for the instance. + Placement *SpotPlacement `locationName:"placement" type:"structure"` + + // The ID of the RAM disk. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + // One or more security groups. When requesting instances in a VPC, you must + // specify the IDs of the security groups. When requesting instances in EC2-Classic, + // you can specify the names or the IDs of the security groups. + SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The ID of the subnet in which to launch the instance. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The user data to make available to the instances. If you are using an AWS + // SDK or command line tool, Base64-encoding is performed for you, and you can + // load the text from a file. Otherwise, you must provide Base64-encoded text. + UserData *string `locationName:"userData" type:"string"` +} + +// String returns the string representation +func (s LaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchSpecification) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyHosts. +type ModifyHostsInput struct { + _ struct{} `type:"structure"` + + // Specify whether to enable or disable auto-placement. + AutoPlacement *string `locationName:"autoPlacement" type:"string" required:"true" enum:"AutoPlacement"` + + // The host IDs of the Dedicated Hosts you want to modify. + HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s ModifyHostsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyHostsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyHostsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyHostsInput"} + if s.AutoPlacement == nil { + invalidParams.Add(request.NewErrParamRequired("AutoPlacement")) + } + if s.HostIds == nil { + invalidParams.Add(request.NewErrParamRequired("HostIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ModifyHosts. +type ModifyHostsOutput struct { + _ struct{} `type:"structure"` + + // The IDs of the Dedicated Hosts that were successfully modified. + Successful []*string `locationName:"successful" locationNameList:"item" type:"list"` + + // The IDs of the Dedicated Hosts that could not be modified. Check whether + // the setting you requested can be used. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s ModifyHostsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyHostsOutput) GoString() string { + return s.String() +} + +// Contains the parameters of ModifyIdFormat. +type ModifyIdFormatInput struct { + _ struct{} `type:"structure"` + + // The type of resource: instance | reservation | snapshot | volume + Resource *string `type:"string" required:"true"` + + // Indicate whether the resource should use longer IDs (17-character IDs). + UseLongIds *bool `type:"boolean" required:"true"` +} + +// String returns the string representation +func (s ModifyIdFormatInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyIdFormatInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyIdFormatInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyIdFormatInput"} + if s.Resource == nil { + invalidParams.Add(request.NewErrParamRequired("Resource")) + } + if s.UseLongIds == nil { + invalidParams.Add(request.NewErrParamRequired("UseLongIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyIdFormatOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyIdFormatOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyIdFormatOutput) GoString() string { + return s.String() +} + +// Contains the parameters of ModifyIdentityIdFormat. +type ModifyIdentityIdFormatInput struct { + _ struct{} `type:"structure"` + + // The ARN of the principal, which can be an IAM user, IAM role, or the root + // user. Specify all to modify the ID format for all IAM users, IAM roles, and + // the root user of the account. + PrincipalArn *string `locationName:"principalArn" type:"string" required:"true"` + + // The type of resource: instance | reservation | snapshot | volume + Resource *string `locationName:"resource" type:"string" required:"true"` + + // Indicates whether the resource should use longer IDs (17-character IDs) + UseLongIds *bool `locationName:"useLongIds" type:"boolean" required:"true"` +} + +// String returns the string representation +func (s ModifyIdentityIdFormatInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyIdentityIdFormatInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyIdentityIdFormatInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyIdentityIdFormatInput"} + if s.PrincipalArn == nil { + invalidParams.Add(request.NewErrParamRequired("PrincipalArn")) + } + if s.Resource == nil { + invalidParams.Add(request.NewErrParamRequired("Resource")) + } + if s.UseLongIds == nil { + invalidParams.Add(request.NewErrParamRequired("UseLongIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyIdentityIdFormatOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyIdentityIdFormatOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyIdentityIdFormatOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyImageAttribute. +type ModifyImageAttributeInput struct { + _ struct{} `type:"structure"` + + // The name of the attribute to modify. + Attribute *string `type:"string"` + + // A description for the AMI. + Description *AttributeValue `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the AMI. + ImageId *string `type:"string" required:"true"` + + // A launch permission modification. + LaunchPermission *LaunchPermissionModifications `type:"structure"` + + // The operation type. + OperationType *string `type:"string" enum:"OperationType"` + + // One or more product codes. After you add a product code to an AMI, it can't + // be removed. This is only valid when modifying the productCodes attribute. + ProductCodes []*string `locationName:"ProductCode" locationNameList:"ProductCode" type:"list"` + + // One or more user groups. This is only valid when modifying the launchPermission + // attribute. + UserGroups []*string `locationName:"UserGroup" locationNameList:"UserGroup" type:"list"` + + // One or more AWS account IDs. This is only valid when modifying the launchPermission + // attribute. + UserIds []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` + + // The value of the attribute being modified. This is only valid when modifying + // the description attribute. + Value *string `type:"string"` +} + +// String returns the string representation +func (s ModifyImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyImageAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyImageAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyImageAttributeInput"} + if s.ImageId == nil { + invalidParams.Add(request.NewErrParamRequired("ImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyImageAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyImageAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyInstanceAttribute. +type ModifyInstanceAttributeInput struct { + _ struct{} `type:"structure"` + + // The name of the attribute. + Attribute *string `locationName:"attribute" type:"string" enum:"InstanceAttributeName"` + + // Modifies the DeleteOnTermination attribute for volumes that are currently + // attached. The volume must be owned by the caller. If no value is specified + // for DeleteOnTermination, the default is true and the volume is deleted when + // the instance is terminated. + // + // To add instance store volumes to an Amazon EBS-backed instance, you must + // add them when you launch the instance. For more information, see Updating + // the Block Device Mapping when Launching an Instance (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html#Using_OverridingAMIBDM) + // in the Amazon Elastic Compute Cloud User Guide. + BlockDeviceMappings []*InstanceBlockDeviceMappingSpecification `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // If the value is true, you can't terminate the instance using the Amazon EC2 + // console, CLI, or API; otherwise, you can. You cannot use this paramater for + // Spot Instances. + DisableApiTermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Specifies whether the instance is optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS + // Optimized instance. + EbsOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` + + // Set to true to enable enhanced networking with ENA for the instance. + // + // This option is supported only for HVM instances. Specifying this option + // with a PV instance can make it unreachable. + EnaSupport *AttributeBooleanValue `locationName:"enaSupport" type:"structure"` + + // [EC2-VPC] Changes the security groups of the instance. You must specify at + // least one security group, even if it's just the default security group for + // the VPC. You must specify the security group ID, not the security group name. + Groups []*string `locationName:"GroupId" locationNameList:"groupId" type:"list"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // Specifies whether an instance stops or terminates when you initiate shutdown + // from the instance (using the operating system command for system shutdown). + InstanceInitiatedShutdownBehavior *AttributeValue `locationName:"instanceInitiatedShutdownBehavior" type:"structure"` + + // Changes the instance type to the specified value. For more information, see + // Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html). + // If the instance type is not valid, the error returned is InvalidInstanceAttributeValue. + InstanceType *AttributeValue `locationName:"instanceType" type:"structure"` + + // Changes the instance's kernel to the specified value. We recommend that you + // use PV-GRUB instead of kernels and RAM disks. For more information, see PV-GRUB + // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedKernels.html). + Kernel *AttributeValue `locationName:"kernel" type:"structure"` + + // Changes the instance's RAM disk to the specified value. We recommend that + // you use PV-GRUB instead of kernels and RAM disks. For more information, see + // PV-GRUB (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedKernels.html). + Ramdisk *AttributeValue `locationName:"ramdisk" type:"structure"` + + // Specifies whether source/destination checking is enabled. A value of true + // means that checking is enabled, and false means checking is disabled. This + // value must be false for a NAT instance to perform NAT. + SourceDestCheck *AttributeBooleanValue `type:"structure"` + + // Set to simple to enable enhanced networking with the Intel 82599 Virtual + // Function interface for the instance. + // + // There is no way to disable enhanced networking with the Intel 82599 Virtual + // Function interface at this time. + // + // This option is supported only for HVM instances. Specifying this option + // with a PV instance can make it unreachable. + SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` + + // Changes the instance's user data to the specified value. If you are using + // an AWS SDK or command line tool, Base64-encoding is performed for you, and + // you can load the text from a file. Otherwise, you must provide Base64-encoded + // text. + UserData *BlobAttributeValue `locationName:"userData" type:"structure"` + + // A new value for the attribute. Use only with the kernel, ramdisk, userData, + // disableApiTermination, or instanceInitiatedShutdownBehavior attribute. + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s ModifyInstanceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstanceAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyInstanceAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyInstanceAttributeInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyInstanceAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyInstanceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstanceAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyInstancePlacement. +type ModifyInstancePlacementInput struct { + _ struct{} `type:"structure"` + + // The new affinity setting for the instance. + Affinity *string `locationName:"affinity" type:"string" enum:"Affinity"` + + // The ID of the Dedicated Host that the instance will have affinity with. + HostId *string `locationName:"hostId" type:"string"` + + // The ID of the instance that you are modifying. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // The tenancy of the instance that you are modifying. + Tenancy *string `locationName:"tenancy" type:"string" enum:"HostTenancy"` +} + +// String returns the string representation +func (s ModifyInstancePlacementInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstancePlacementInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyInstancePlacementInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyInstancePlacementInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ModifyInstancePlacement. +type ModifyInstancePlacementOutput struct { + _ struct{} `type:"structure"` + + // Is true if the request succeeds, and an error otherwise. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifyInstancePlacementOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstancePlacementOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyNetworkInterfaceAttribute. +type ModifyNetworkInterfaceAttributeInput struct { + _ struct{} `type:"structure"` + + // Information about the interface attachment. If modifying the 'delete on termination' + // attribute, you must specify the ID of the interface attachment. + Attachment *NetworkInterfaceAttachmentChanges `locationName:"attachment" type:"structure"` + + // A description for the network interface. + Description *AttributeValue `locationName:"description" type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Changes the security groups for the network interface. The new set of groups + // you specify replaces the current set. You must specify at least one group, + // even if it's just the default security group in the VPC. You must specify + // the ID of the security group, not the name. + Groups []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` + + // Indicates whether source/destination checking is enabled. A value of true + // means checking is enabled, and false means checking is disabled. This value + // must be false for a NAT instance to perform NAT. For more information, see + // NAT Instances (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html) + // in the Amazon Virtual Private Cloud User Guide. + SourceDestCheck *AttributeBooleanValue `locationName:"sourceDestCheck" type:"structure"` +} + +// String returns the string representation +func (s ModifyNetworkInterfaceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyNetworkInterfaceAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyNetworkInterfaceAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyNetworkInterfaceAttributeInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyNetworkInterfaceAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyNetworkInterfaceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyNetworkInterfaceAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyReservedInstances. +type ModifyReservedInstancesInput struct { + _ struct{} `type:"structure"` + + // A unique, case-sensitive token you provide to ensure idempotency of your + // modification request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `locationName:"clientToken" type:"string"` + + // The IDs of the Reserved Instances to modify. + ReservedInstancesIds []*string `locationName:"ReservedInstancesId" locationNameList:"ReservedInstancesId" type:"list" required:"true"` + + // The configuration settings for the Reserved Instances to modify. + TargetConfigurations []*ReservedInstancesConfiguration `locationName:"ReservedInstancesConfigurationSetItemType" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s ModifyReservedInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyReservedInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyReservedInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyReservedInstancesInput"} + if s.ReservedInstancesIds == nil { + invalidParams.Add(request.NewErrParamRequired("ReservedInstancesIds")) + } + if s.TargetConfigurations == nil { + invalidParams.Add(request.NewErrParamRequired("TargetConfigurations")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ModifyReservedInstances. +type ModifyReservedInstancesOutput struct { + _ struct{} `type:"structure"` + + // The ID for the modification. + ReservedInstancesModificationId *string `locationName:"reservedInstancesModificationId" type:"string"` +} + +// String returns the string representation +func (s ModifyReservedInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyReservedInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifySnapshotAttribute. +type ModifySnapshotAttributeInput struct { + _ struct{} `type:"structure"` + + // The snapshot attribute to modify. + // + // Only volume creation permissions may be modified at the customer level. + Attribute *string `type:"string" enum:"SnapshotAttributeName"` + + // A JSON representation of the snapshot attribute modification. + CreateVolumePermission *CreateVolumePermissionModifications `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The group to modify for the snapshot. + GroupNames []*string `locationName:"UserGroup" locationNameList:"GroupName" type:"list"` + + // The type of operation to perform to the attribute. + OperationType *string `type:"string" enum:"OperationType"` + + // The ID of the snapshot. + SnapshotId *string `type:"string" required:"true"` + + // The account ID to modify for the snapshot. + UserIds []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` +} + +// String returns the string representation +func (s ModifySnapshotAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySnapshotAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifySnapshotAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifySnapshotAttributeInput"} + if s.SnapshotId == nil { + invalidParams.Add(request.NewErrParamRequired("SnapshotId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifySnapshotAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifySnapshotAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySnapshotAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifySpotFleetRequest. +type ModifySpotFleetRequestInput struct { + _ struct{} `type:"structure"` + + // Indicates whether running Spot instances should be terminated if the target + // capacity of the Spot fleet request is decreased below the current size of + // the Spot fleet. + ExcessCapacityTerminationPolicy *string `locationName:"excessCapacityTerminationPolicy" type:"string" enum:"ExcessCapacityTerminationPolicy"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + + // The size of the fleet. + TargetCapacity *int64 `locationName:"targetCapacity" type:"integer"` +} + +// String returns the string representation +func (s ModifySpotFleetRequestInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySpotFleetRequestInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifySpotFleetRequestInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifySpotFleetRequestInput"} + if s.SpotFleetRequestId == nil { + invalidParams.Add(request.NewErrParamRequired("SpotFleetRequestId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ModifySpotFleetRequest. +type ModifySpotFleetRequestOutput struct { + _ struct{} `type:"structure"` + + // Is true if the request succeeds, and an error otherwise. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifySpotFleetRequestOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySpotFleetRequestOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifySubnetAttribute. +type ModifySubnetAttributeInput struct { + _ struct{} `type:"structure"` + + // Specify true to indicate that instances launched into the specified subnet + // should be assigned public IP address. + MapPublicIpOnLaunch *AttributeBooleanValue `type:"structure"` + + // The ID of the subnet. + SubnetId *string `locationName:"subnetId" type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifySubnetAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySubnetAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifySubnetAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifySubnetAttributeInput"} + if s.SubnetId == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifySubnetAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifySubnetAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySubnetAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyVolumeAttribute. +type ModifyVolumeAttributeInput struct { + _ struct{} `type:"structure"` + + // Indicates whether the volume should be auto-enabled for I/O operations. + AutoEnableIO *AttributeBooleanValue `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVolumeAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVolumeAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVolumeAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVolumeAttributeInput"} + if s.VolumeId == nil { + invalidParams.Add(request.NewErrParamRequired("VolumeId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyVolumeAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyVolumeAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVolumeAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyVpcAttribute. +type ModifyVpcAttributeInput struct { + _ struct{} `type:"structure"` + + // Indicates whether the instances launched in the VPC get DNS hostnames. If + // enabled, instances in the VPC get DNS hostnames; otherwise, they do not. + // + // You cannot modify the DNS resolution and DNS hostnames attributes in the + // same request. Use separate requests for each attribute. You can only enable + // DNS hostnames if you've enabled DNS support. + EnableDnsHostnames *AttributeBooleanValue `type:"structure"` + + // Indicates whether the DNS resolution is supported for the VPC. If enabled, + // queries to the Amazon provided DNS server at the 169.254.169.253 IP address, + // or the reserved IP address at the base of the VPC network range "plus two" + // will succeed. If disabled, the Amazon provided DNS service in the VPC that + // resolves public DNS hostnames to IP addresses is not enabled. + // + // You cannot modify the DNS resolution and DNS hostnames attributes in the + // same request. Use separate requests for each attribute. + EnableDnsSupport *AttributeBooleanValue `type:"structure"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVpcAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcAttributeInput"} + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyVpcAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ModifyVpcAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ModifyVpcEndpoint. +type ModifyVpcEndpointInput struct { + _ struct{} `type:"structure"` + + // One or more route tables IDs to associate with the endpoint. + AddRouteTableIds []*string `locationName:"AddRouteTableId" locationNameList:"item" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // A policy document to attach to the endpoint. The policy must be in valid + // JSON format. + PolicyDocument *string `type:"string"` + + // One or more route table IDs to disassociate from the endpoint. + RemoveRouteTableIds []*string `locationName:"RemoveRouteTableId" locationNameList:"item" type:"list"` + + // Specify true to reset the policy document to the default policy. The default + // policy allows access to the service. + ResetPolicy *bool `type:"boolean"` + + // The ID of the endpoint. + VpcEndpointId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVpcEndpointInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcEndpointInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcEndpointInput"} + if s.VpcEndpointId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcEndpointId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ModifyVpcEndpoint. +type ModifyVpcEndpointOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifyVpcEndpointOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointOutput) GoString() string { + return s.String() +} + +type ModifyVpcPeeringConnectionOptionsInput struct { + _ struct{} `type:"structure"` + + // The VPC peering connection options for the accepter VPC. + AccepterPeeringConnectionOptions *PeeringConnectionOptionsRequest `type:"structure"` + + // Checks whether you have the required permissions for the operation, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The VPC peering connection options for the requester VPC. + RequesterPeeringConnectionOptions *PeeringConnectionOptionsRequest `type:"structure"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVpcPeeringConnectionOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcPeeringConnectionOptionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcPeeringConnectionOptionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcPeeringConnectionOptionsInput"} + if s.VpcPeeringConnectionId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcPeeringConnectionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ModifyVpcPeeringConnectionOptionsOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPC peering connection options for the accepter VPC. + AccepterPeeringConnectionOptions *PeeringConnectionOptions `locationName:"accepterPeeringConnectionOptions" type:"structure"` + + // Information about the VPC peering connection options for the requester VPC. + RequesterPeeringConnectionOptions *PeeringConnectionOptions `locationName:"requesterPeeringConnectionOptions" type:"structure"` +} + +// String returns the string representation +func (s ModifyVpcPeeringConnectionOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcPeeringConnectionOptionsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for MonitorInstances. +type MonitorInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` +} + +// String returns the string representation +func (s MonitorInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MonitorInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *MonitorInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "MonitorInstancesInput"} + if s.InstanceIds == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of MonitorInstances. +type MonitorInstancesOutput struct { + _ struct{} `type:"structure"` + + // Monitoring information for one or more instances. + InstanceMonitorings []*InstanceMonitoring `locationName:"instancesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s MonitorInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MonitorInstancesOutput) GoString() string { + return s.String() +} + +// Describes the monitoring for the instance. +type Monitoring struct { + _ struct{} `type:"structure"` + + // Indicates whether monitoring is enabled for the instance. + State *string `locationName:"state" type:"string" enum:"MonitoringState"` +} + +// String returns the string representation +func (s Monitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Monitoring) GoString() string { + return s.String() +} + +// Contains the parameters for MoveAddressToVpc. +type MoveAddressToVpcInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The Elastic IP address. + PublicIp *string `locationName:"publicIp" type:"string" required:"true"` +} + +// String returns the string representation +func (s MoveAddressToVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MoveAddressToVpcInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *MoveAddressToVpcInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "MoveAddressToVpcInput"} + if s.PublicIp == nil { + invalidParams.Add(request.NewErrParamRequired("PublicIp")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of MoveAddressToVpc. +type MoveAddressToVpcOutput struct { + _ struct{} `type:"structure"` + + // The allocation ID for the Elastic IP address. + AllocationId *string `locationName:"allocationId" type:"string"` + + // The status of the move of the IP address. + Status *string `locationName:"status" type:"string" enum:"Status"` +} + +// String returns the string representation +func (s MoveAddressToVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MoveAddressToVpcOutput) GoString() string { + return s.String() +} + +// Describes the status of a moving Elastic IP address. +type MovingAddressStatus struct { + _ struct{} `type:"structure"` + + // The status of the Elastic IP address that's being moved to the EC2-VPC platform, + // or restored to the EC2-Classic platform. + MoveStatus *string `locationName:"moveStatus" type:"string" enum:"MoveStatus"` + + // The Elastic IP address. + PublicIp *string `locationName:"publicIp" type:"string"` +} + +// String returns the string representation +func (s MovingAddressStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MovingAddressStatus) GoString() string { + return s.String() +} + +// Describes a NAT gateway. +type NatGateway struct { + _ struct{} `type:"structure"` + + // The date and time the NAT gateway was created. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` + + // The date and time the NAT gateway was deleted, if applicable. + DeleteTime *time.Time `locationName:"deleteTime" type:"timestamp" timestampFormat:"iso8601"` + + // If the NAT gateway could not be created, specifies the error code for the + // failure. (InsufficientFreeAddressesInSubnet | Gateway.NotAttached | InvalidAllocationID.NotFound + // | Resource.AlreadyAssociated | InternalError | InvalidSubnetID.NotFound) + FailureCode *string `locationName:"failureCode" type:"string"` + + // If the NAT gateway could not be created, specifies the error message for + // the failure, that corresponds to the error code. + // + // For InsufficientFreeAddressesInSubnet: "Subnet has insufficient free addresses + // to create this NAT gateway" + // + // For Gateway.NotAttached: "Network vpc-xxxxxxxx has no Internet gateway + // attached" + // + // For InvalidAllocationID.NotFound: "Elastic IP address eipalloc-xxxxxxxx + // could not be associated with this NAT gateway" + // + // For Resource.AlreadyAssociated: "Elastic IP address eipalloc-xxxxxxxx + // is already associated" + // + // For InternalError: "Network interface eni-xxxxxxxx, created and used internally + // by this NAT gateway is in an invalid state. Please try again." + // + // For InvalidSubnetID.NotFound: "The specified subnet subnet-xxxxxxxx does + // not exist or could not be found." + FailureMessage *string `locationName:"failureMessage" type:"string"` + + // Information about the IP addresses and network interface associated with + // the NAT gateway. + NatGatewayAddresses []*NatGatewayAddress `locationName:"natGatewayAddressSet" locationNameList:"item" type:"list"` + + // The ID of the NAT gateway. + NatGatewayId *string `locationName:"natGatewayId" type:"string"` + + // Reserved. If you need to sustain traffic greater than the documented limits + // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), + // contact us through the Support Center (https://console.aws.amazon.com/support/home?). + ProvisionedBandwidth *ProvisionedBandwidth `locationName:"provisionedBandwidth" type:"structure"` + + // The state of the NAT gateway. + // + // pending: The NAT gateway is being created and is not ready to process + // traffic. + // + // failed: The NAT gateway could not be created. Check the failureCode and + // failureMessage fields for the reason. + // + // available: The NAT gateway is able to process traffic. This status remains + // until you delete the NAT gateway, and does not indicate the health of the + // NAT gateway. + // + // deleting: The NAT gateway is in the process of being terminated and may + // still be processing traffic. + // + // deleted: The NAT gateway has been terminated and is no longer processing + // traffic. + State *string `locationName:"state" type:"string" enum:"NatGatewayState"` + + // The ID of the subnet in which the NAT gateway is located. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The ID of the VPC in which the NAT gateway is located. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s NatGateway) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NatGateway) GoString() string { + return s.String() +} + +// Describes the IP addresses and network interface associated with a NAT gateway. +type NatGatewayAddress struct { + _ struct{} `type:"structure"` + + // The allocation ID of the Elastic IP address that's associated with the NAT + // gateway. + AllocationId *string `locationName:"allocationId" type:"string"` + + // The ID of the network interface associated with the NAT gateway. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The private IP address associated with the Elastic IP address. + PrivateIp *string `locationName:"privateIp" type:"string"` + + // The Elastic IP address associated with the NAT gateway. + PublicIp *string `locationName:"publicIp" type:"string"` +} + +// String returns the string representation +func (s NatGatewayAddress) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NatGatewayAddress) GoString() string { + return s.String() +} + +// Describes a network ACL. +type NetworkAcl struct { + _ struct{} `type:"structure"` + + // Any associations between the network ACL and one or more subnets + Associations []*NetworkAclAssociation `locationName:"associationSet" locationNameList:"item" type:"list"` + + // One or more entries (rules) in the network ACL. + Entries []*NetworkAclEntry `locationName:"entrySet" locationNameList:"item" type:"list"` + + // Indicates whether this is the default network ACL for the VPC. + IsDefault *bool `locationName:"default" type:"boolean"` + + // The ID of the network ACL. + NetworkAclId *string `locationName:"networkAclId" type:"string"` + + // Any tags assigned to the network ACL. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC for the network ACL. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s NetworkAcl) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkAcl) GoString() string { + return s.String() +} + +// Describes an association between a network ACL and a subnet. +type NetworkAclAssociation struct { + _ struct{} `type:"structure"` + + // The ID of the association between a network ACL and a subnet. + NetworkAclAssociationId *string `locationName:"networkAclAssociationId" type:"string"` + + // The ID of the network ACL. + NetworkAclId *string `locationName:"networkAclId" type:"string"` + + // The ID of the subnet. + SubnetId *string `locationName:"subnetId" type:"string"` +} + +// String returns the string representation +func (s NetworkAclAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkAclAssociation) GoString() string { + return s.String() +} + +// Describes an entry in a network ACL. +type NetworkAclEntry struct { + _ struct{} `type:"structure"` + + // The network range to allow or deny, in CIDR notation. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // Indicates whether the rule is an egress rule (applied to traffic leaving + // the subnet). + Egress *bool `locationName:"egress" type:"boolean"` + + // ICMP protocol: The ICMP type and code. + IcmpTypeCode *IcmpTypeCode `locationName:"icmpTypeCode" type:"structure"` + + // TCP or UDP protocols: The range of ports the rule applies to. + PortRange *PortRange `locationName:"portRange" type:"structure"` + + // The protocol. A value of -1 means all protocols. + Protocol *string `locationName:"protocol" type:"string"` + + // Indicates whether to allow or deny the traffic that matches the rule. + RuleAction *string `locationName:"ruleAction" type:"string" enum:"RuleAction"` + + // The rule number for the entry. ACL entries are processed in ascending order + // by rule number. + RuleNumber *int64 `locationName:"ruleNumber" type:"integer"` +} + +// String returns the string representation +func (s NetworkAclEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkAclEntry) GoString() string { + return s.String() +} + +// Describes a network interface. +type NetworkInterface struct { + _ struct{} `type:"structure"` + + // The association information for an Elastic IP associated with the network + // interface. + Association *NetworkInterfaceAssociation `locationName:"association" type:"structure"` + + // The network interface attachment. + Attachment *NetworkInterfaceAttachment `locationName:"attachment" type:"structure"` + + // The Availability Zone. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // A description. + Description *string `locationName:"description" type:"string"` + + // Any security groups for the network interface. + Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The type of interface. + InterfaceType *string `locationName:"interfaceType" type:"string" enum:"NetworkInterfaceType"` + + // The MAC address. + MacAddress *string `locationName:"macAddress" type:"string"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The AWS account ID of the owner of the network interface. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The private DNS name. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The IP address of the network interface within the subnet. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The private IP addresses associated with the network interface. + PrivateIpAddresses []*NetworkInterfacePrivateIpAddress `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` + + // The ID of the entity that launched the instance on your behalf (for example, + // AWS Management Console or Auto Scaling). + RequesterId *string `locationName:"requesterId" type:"string"` + + // Indicates whether the network interface is being managed by AWS. + RequesterManaged *bool `locationName:"requesterManaged" type:"boolean"` + + // Indicates whether traffic to or from the instance is validated. + SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` + + // The status of the network interface. + Status *string `locationName:"status" type:"string" enum:"NetworkInterfaceStatus"` + + // The ID of the subnet. + SubnetId *string `locationName:"subnetId" type:"string"` + + // Any tags assigned to the network interface. + TagSet []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s NetworkInterface) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterface) GoString() string { + return s.String() +} + +// Describes association information for an Elastic IP address. +type NetworkInterfaceAssociation struct { + _ struct{} `type:"structure"` + + // The allocation ID. + AllocationId *string `locationName:"allocationId" type:"string"` + + // The association ID. + AssociationId *string `locationName:"associationId" type:"string"` + + // The ID of the Elastic IP address owner. + IpOwnerId *string `locationName:"ipOwnerId" type:"string"` + + // The public DNS name. + PublicDnsName *string `locationName:"publicDnsName" type:"string"` + + // The address of the Elastic IP address bound to the network interface. + PublicIp *string `locationName:"publicIp" type:"string"` +} + +// String returns the string representation +func (s NetworkInterfaceAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfaceAssociation) GoString() string { + return s.String() +} + +// Describes a network interface attachment. +type NetworkInterfaceAttachment struct { + _ struct{} `type:"structure"` + + // The timestamp indicating when the attachment initiated. + AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` + + // The ID of the network interface attachment. + AttachmentId *string `locationName:"attachmentId" type:"string"` + + // Indicates whether the network interface is deleted when the instance is terminated. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // The device index of the network interface attachment on the instance. + DeviceIndex *int64 `locationName:"deviceIndex" type:"integer"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The AWS account ID of the owner of the instance. + InstanceOwnerId *string `locationName:"instanceOwnerId" type:"string"` + + // The attachment state. + Status *string `locationName:"status" type:"string" enum:"AttachmentStatus"` +} + +// String returns the string representation +func (s NetworkInterfaceAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfaceAttachment) GoString() string { + return s.String() +} + +// Describes an attachment change. +type NetworkInterfaceAttachmentChanges struct { + _ struct{} `type:"structure"` + + // The ID of the network interface attachment. + AttachmentId *string `locationName:"attachmentId" type:"string"` + + // Indicates whether the network interface is deleted when the instance is terminated. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` +} + +// String returns the string representation +func (s NetworkInterfaceAttachmentChanges) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfaceAttachmentChanges) GoString() string { + return s.String() +} + +// Describes the private IP address of a network interface. +type NetworkInterfacePrivateIpAddress struct { + _ struct{} `type:"structure"` + + // The association information for an Elastic IP address associated with the + // network interface. + Association *NetworkInterfaceAssociation `locationName:"association" type:"structure"` + + // Indicates whether this IP address is the primary private IP address of the + // network interface. + Primary *bool `locationName:"primary" type:"boolean"` + + // The private DNS name. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The private IP address. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` +} + +// String returns the string representation +func (s NetworkInterfacePrivateIpAddress) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfacePrivateIpAddress) GoString() string { + return s.String() +} + +type NewDhcpConfiguration struct { + _ struct{} `type:"structure"` + + Key *string `locationName:"key" type:"string"` + + Values []*string `locationName:"Value" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s NewDhcpConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NewDhcpConfiguration) GoString() string { + return s.String() +} + +// Describes the VPC peering connection options. +type PeeringConnectionOptions struct { + _ struct{} `type:"structure"` + + // If true, enables a local VPC to resolve public DNS hostnames to private IP + // addresses when queried from instances in the peer VPC. + AllowDnsResolutionFromRemoteVpc *bool `locationName:"allowDnsResolutionFromRemoteVpc" type:"boolean"` + + // If true, enables outbound communication from an EC2-Classic instance that's + // linked to a local VPC via ClassicLink to instances in a peer VPC. + AllowEgressFromLocalClassicLinkToRemoteVpc *bool `locationName:"allowEgressFromLocalClassicLinkToRemoteVpc" type:"boolean"` + + // If true, enables outbound communication from instances in a local VPC to + // an EC2-Classic instance that's linked to a peer VPC via ClassicLink. + AllowEgressFromLocalVpcToRemoteClassicLink *bool `locationName:"allowEgressFromLocalVpcToRemoteClassicLink" type:"boolean"` +} + +// String returns the string representation +func (s PeeringConnectionOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PeeringConnectionOptions) GoString() string { + return s.String() +} + +// The VPC peering connection options. +type PeeringConnectionOptionsRequest struct { + _ struct{} `type:"structure"` + + // If true, enables a local VPC to resolve public DNS hostnames to private IP + // addresses when queried from instances in the peer VPC. + AllowDnsResolutionFromRemoteVpc *bool `type:"boolean"` + + // If true, enables outbound communication from an EC2-Classic instance that's + // linked to a local VPC via ClassicLink to instances in a peer VPC. + AllowEgressFromLocalClassicLinkToRemoteVpc *bool `type:"boolean"` + + // If true, enables outbound communication from instances in a local VPC to + // an EC2-Classic instance that's linked to a peer VPC via ClassicLink. + AllowEgressFromLocalVpcToRemoteClassicLink *bool `type:"boolean"` +} + +// String returns the string representation +func (s PeeringConnectionOptionsRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PeeringConnectionOptionsRequest) GoString() string { + return s.String() +} + +// Describes the placement for the instance. +type Placement struct { + _ struct{} `type:"structure"` + + // The affinity setting for the instance on the Dedicated Host. This parameter + // is not supported for the ImportInstance command. + Affinity *string `locationName:"affinity" type:"string"` + + // The Availability Zone of the instance. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The name of the placement group the instance is in (for cluster compute instances). + GroupName *string `locationName:"groupName" type:"string"` + + // The ID of the Dedicted host on which the instance resides. This parameter + // is not support for the ImportInstance command. + HostId *string `locationName:"hostId" type:"string"` + + // The tenancy of the instance (if the instance is running in a VPC). An instance + // with a tenancy of dedicated runs on single-tenant hardware. The host tenancy + // is not supported for the ImportInstance command. + Tenancy *string `locationName:"tenancy" type:"string" enum:"Tenancy"` +} + +// String returns the string representation +func (s Placement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Placement) GoString() string { + return s.String() +} + +// Describes a placement group. +type PlacementGroup struct { + _ struct{} `type:"structure"` + + // The name of the placement group. + GroupName *string `locationName:"groupName" type:"string"` + + // The state of the placement group. + State *string `locationName:"state" type:"string" enum:"PlacementGroupState"` + + // The placement strategy. + Strategy *string `locationName:"strategy" type:"string" enum:"PlacementStrategy"` +} + +// String returns the string representation +func (s PlacementGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PlacementGroup) GoString() string { + return s.String() +} + +// Describes a range of ports. +type PortRange struct { + _ struct{} `type:"structure"` + + // The first port in the range. + From *int64 `locationName:"from" type:"integer"` + + // The last port in the range. + To *int64 `locationName:"to" type:"integer"` +} + +// String returns the string representation +func (s PortRange) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PortRange) GoString() string { + return s.String() +} + +// Describes prefixes for AWS services. +type PrefixList struct { + _ struct{} `type:"structure"` + + // The IP address range of the AWS service. + Cidrs []*string `locationName:"cidrSet" locationNameList:"item" type:"list"` + + // The ID of the prefix. + PrefixListId *string `locationName:"prefixListId" type:"string"` + + // The name of the prefix. + PrefixListName *string `locationName:"prefixListName" type:"string"` +} + +// String returns the string representation +func (s PrefixList) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PrefixList) GoString() string { + return s.String() +} + +// The ID of the prefix. +type PrefixListId struct { + _ struct{} `type:"structure"` + + // The ID of the prefix. + PrefixListId *string `locationName:"prefixListId" type:"string"` +} + +// String returns the string representation +func (s PrefixListId) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PrefixListId) GoString() string { + return s.String() +} + +// Describes the price for a Reserved Instance. +type PriceSchedule struct { + _ struct{} `type:"structure"` + + // The current price schedule, as determined by the term remaining for the Reserved + // Instance in the listing. + // + // A specific price schedule is always in effect, but only one price schedule + // can be active at any time. Take, for example, a Reserved Instance listing + // that has five months remaining in its term. When you specify price schedules + // for five months and two months, this means that schedule 1, covering the + // first three months of the remaining term, will be active during months 5, + // 4, and 3. Then schedule 2, covering the last two months of the term, will + // be active for months 2 and 1. + Active *bool `locationName:"active" type:"boolean"` + + // The currency for transacting the Reserved Instance resale. At this time, + // the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The fixed price for the term. + Price *float64 `locationName:"price" type:"double"` + + // The number of months remaining in the reservation. For example, 2 is the + // second to the last month before the capacity reservation expires. + Term *int64 `locationName:"term" type:"long"` +} + +// String returns the string representation +func (s PriceSchedule) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PriceSchedule) GoString() string { + return s.String() +} + +// Describes the price for a Reserved Instance. +type PriceScheduleSpecification struct { + _ struct{} `type:"structure"` + + // The currency for transacting the Reserved Instance resale. At this time, + // the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The fixed price for the term. + Price *float64 `locationName:"price" type:"double"` + + // The number of months remaining in the reservation. For example, 2 is the + // second to the last month before the capacity reservation expires. + Term *int64 `locationName:"term" type:"long"` +} + +// String returns the string representation +func (s PriceScheduleSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PriceScheduleSpecification) GoString() string { + return s.String() +} + +// Describes a Reserved Instance offering. +type PricingDetail struct { + _ struct{} `type:"structure"` + + // The number of reservations available for the price. + Count *int64 `locationName:"count" type:"integer"` + + // The price per instance. + Price *float64 `locationName:"price" type:"double"` +} + +// String returns the string representation +func (s PricingDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PricingDetail) GoString() string { + return s.String() +} + +// Describes a secondary private IP address for a network interface. +type PrivateIpAddressSpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether the private IP address is the primary private IP address. + // Only one IP address can be designated as primary. + Primary *bool `locationName:"primary" type:"boolean"` + + // The private IP addresses. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string" required:"true"` +} + +// String returns the string representation +func (s PrivateIpAddressSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PrivateIpAddressSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PrivateIpAddressSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PrivateIpAddressSpecification"} + if s.PrivateIpAddress == nil { + invalidParams.Add(request.NewErrParamRequired("PrivateIpAddress")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a product code. +type ProductCode struct { + _ struct{} `type:"structure"` + + // The product code. + ProductCodeId *string `locationName:"productCode" type:"string"` + + // The type of product code. + ProductCodeType *string `locationName:"type" type:"string" enum:"ProductCodeValues"` +} + +// String returns the string representation +func (s ProductCode) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ProductCode) GoString() string { + return s.String() +} + +// Describes a virtual private gateway propagating route. +type PropagatingVgw struct { + _ struct{} `type:"structure"` + + // The ID of the virtual private gateway (VGW). + GatewayId *string `locationName:"gatewayId" type:"string"` +} + +// String returns the string representation +func (s PropagatingVgw) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PropagatingVgw) GoString() string { + return s.String() +} + +// Reserved. If you need to sustain traffic greater than the documented limits +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), +// contact us through the Support Center (https://console.aws.amazon.com/support/home?). +type ProvisionedBandwidth struct { + _ struct{} `type:"structure"` + + // Reserved. If you need to sustain traffic greater than the documented limits + // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), + // contact us through the Support Center (https://console.aws.amazon.com/support/home?). + ProvisionTime *time.Time `locationName:"provisionTime" type:"timestamp" timestampFormat:"iso8601"` + + // Reserved. If you need to sustain traffic greater than the documented limits + // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), + // contact us through the Support Center (https://console.aws.amazon.com/support/home?). + Provisioned *string `locationName:"provisioned" type:"string"` + + // Reserved. If you need to sustain traffic greater than the documented limits + // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), + // contact us through the Support Center (https://console.aws.amazon.com/support/home?). + RequestTime *time.Time `locationName:"requestTime" type:"timestamp" timestampFormat:"iso8601"` + + // Reserved. If you need to sustain traffic greater than the documented limits + // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), + // contact us through the Support Center (https://console.aws.amazon.com/support/home?). + Requested *string `locationName:"requested" type:"string"` + + // Reserved. If you need to sustain traffic greater than the documented limits + // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), + // contact us through the Support Center (https://console.aws.amazon.com/support/home?). + Status *string `locationName:"status" type:"string"` +} + +// String returns the string representation +func (s ProvisionedBandwidth) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ProvisionedBandwidth) GoString() string { + return s.String() +} + +// Describes the result of the purchase. +type Purchase struct { + _ struct{} `type:"structure"` + + // The currency in which the UpfrontPrice and HourlyPrice amounts are specified. + // At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The duration of the reservation's term in seconds. + Duration *int64 `locationName:"duration" type:"integer"` + + // The IDs of the Dedicated Hosts associated with the reservation. + HostIdSet []*string `locationName:"hostIdSet" locationNameList:"item" type:"list"` + + // The ID of the reservation. + HostReservationId *string `locationName:"hostReservationId" type:"string"` + + // The hourly price of the reservation per hour. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance family on the Dedicated Host that the reservation can be associated + // with. + InstanceFamily *string `locationName:"instanceFamily" type:"string"` + + // The payment option for the reservation. + PaymentOption *string `locationName:"paymentOption" type:"string" enum:"PaymentOption"` + + // The upfront price of the reservation. + UpfrontPrice *string `locationName:"upfrontPrice" type:"string"` +} + +// String returns the string representation +func (s Purchase) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Purchase) GoString() string { + return s.String() +} + +type PurchaseHostReservationInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide. + ClientToken *string `type:"string"` + + // The currency in which the totalUpfrontPrice, LimitPrice, and totalHourlyPrice + // amounts are specified. At this time, the only supported currency is USD. + CurrencyCode *string `type:"string" enum:"CurrencyCodeValues"` + + // The ID/s of the Dedicated Host/s that the reservation will be associated + // with. + HostIdSet []*string `locationNameList:"item" type:"list" required:"true"` + + // The specified limit is checked against the total upfront cost of the reservation + // (calculated as the offering's upfront cost multiplied by the host count). + // If the total upfront cost is greater than the specified price limit, the + // request will fail. This is used to ensure that the purchase does not exceed + // the expected upfront cost of the purchase. At this time, the only supported + // currency is USD. For example, to indicate a limit price of USD 100, specify + // 100.00. + LimitPrice *string `type:"string"` + + // The ID of the offering. + OfferingId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s PurchaseHostReservationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseHostReservationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PurchaseHostReservationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PurchaseHostReservationInput"} + if s.HostIdSet == nil { + invalidParams.Add(request.NewErrParamRequired("HostIdSet")) + } + if s.OfferingId == nil { + invalidParams.Add(request.NewErrParamRequired("OfferingId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type PurchaseHostReservationOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide + ClientToken *string `locationName:"clientToken" type:"string"` + + // The currency in which the totalUpfrontPrice and totalHourlyPrice amounts + // are specified. At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // Describes the details of the purchase. + Purchase []*Purchase `locationName:"purchase" type:"list"` + + // The total hourly price of the reservation calculated per hour. + TotalHourlyPrice *string `locationName:"totalHourlyPrice" type:"string"` + + // The total amount that will be charged to your account when you purchase the + // reservation. + TotalUpfrontPrice *string `locationName:"totalUpfrontPrice" type:"string"` +} + +// String returns the string representation +func (s PurchaseHostReservationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseHostReservationOutput) GoString() string { + return s.String() +} + +// Describes a request to purchase Scheduled Instances. +type PurchaseRequest struct { + _ struct{} `type:"structure"` + + // The number of instances. + InstanceCount *int64 `type:"integer" required:"true"` + + // The purchase token. + PurchaseToken *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s PurchaseRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseRequest) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PurchaseRequest) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PurchaseRequest"} + if s.InstanceCount == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceCount")) + } + if s.PurchaseToken == nil { + invalidParams.Add(request.NewErrParamRequired("PurchaseToken")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the parameters for PurchaseReservedInstancesOffering. +type PurchaseReservedInstancesOfferingInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The number of Reserved Instances to purchase. + InstanceCount *int64 `type:"integer" required:"true"` + + // Specified for Reserved Instance Marketplace offerings to limit the total + // order and ensure that the Reserved Instances are not purchased at unexpected + // prices. + LimitPrice *ReservedInstanceLimitPrice `locationName:"limitPrice" type:"structure"` + + // The ID of the Reserved Instance offering to purchase. + ReservedInstancesOfferingId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s PurchaseReservedInstancesOfferingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseReservedInstancesOfferingInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PurchaseReservedInstancesOfferingInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PurchaseReservedInstancesOfferingInput"} + if s.InstanceCount == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceCount")) + } + if s.ReservedInstancesOfferingId == nil { + invalidParams.Add(request.NewErrParamRequired("ReservedInstancesOfferingId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of PurchaseReservedInstancesOffering. +type PurchaseReservedInstancesOfferingOutput struct { + _ struct{} `type:"structure"` + + // The IDs of the purchased Reserved Instances. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` +} + +// String returns the string representation +func (s PurchaseReservedInstancesOfferingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseReservedInstancesOfferingOutput) GoString() string { + return s.String() +} + +// Contains the parameters for PurchaseScheduledInstances. +type PurchaseScheduledInstancesInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier that ensures the idempotency of the request. + // For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string" idempotencyToken:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more purchase requests. + PurchaseRequests []*PurchaseRequest `locationName:"PurchaseRequest" locationNameList:"PurchaseRequest" min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s PurchaseScheduledInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseScheduledInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PurchaseScheduledInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PurchaseScheduledInstancesInput"} + if s.PurchaseRequests == nil { + invalidParams.Add(request.NewErrParamRequired("PurchaseRequests")) + } + if s.PurchaseRequests != nil && len(s.PurchaseRequests) < 1 { + invalidParams.Add(request.NewErrParamMinLen("PurchaseRequests", 1)) + } + if s.PurchaseRequests != nil { + for i, v := range s.PurchaseRequests { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PurchaseRequests", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of PurchaseScheduledInstances. +type PurchaseScheduledInstancesOutput struct { + _ struct{} `type:"structure"` + + // Information about the Scheduled Instances. + ScheduledInstanceSet []*ScheduledInstance `locationName:"scheduledInstanceSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s PurchaseScheduledInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseScheduledInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RebootInstances. +type RebootInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` +} + +// String returns the string representation +func (s RebootInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RebootInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RebootInstancesInput"} + if s.InstanceIds == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type RebootInstancesOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s RebootInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootInstancesOutput) GoString() string { + return s.String() +} + +// Describes a recurring charge. +type RecurringCharge struct { + _ struct{} `type:"structure"` + + // The amount of the recurring charge. + Amount *float64 `locationName:"amount" type:"double"` + + // The frequency of the recurring charge. + Frequency *string `locationName:"frequency" type:"string" enum:"RecurringChargeFrequency"` +} + +// String returns the string representation +func (s RecurringCharge) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RecurringCharge) GoString() string { + return s.String() +} + +// Describes a region. +type Region struct { + _ struct{} `type:"structure"` + + // The region service endpoint. + Endpoint *string `locationName:"regionEndpoint" type:"string"` + + // The name of the region. + RegionName *string `locationName:"regionName" type:"string"` +} + +// String returns the string representation +func (s Region) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Region) GoString() string { + return s.String() +} + +// Contains the parameters for RegisterImage. +type RegisterImageInput struct { + _ struct{} `type:"structure"` + + // The architecture of the AMI. + // + // Default: For Amazon EBS-backed AMIs, i386. For instance store-backed AMIs, + // the architecture specified in the manifest file. + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` + + // One or more block device mapping entries. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` + + // A description for your AMI. + Description *string `locationName:"description" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Set to true to enable enhanced networking with ENA for the AMI and any instances + // that you launch from the AMI. + // + // This option is supported only for HVM AMIs. Specifying this option with + // a PV AMI can make instances launched from the AMI unreachable. + EnaSupport *bool `locationName:"enaSupport" type:"boolean"` + + // The full path to your AMI manifest in Amazon S3 storage. + ImageLocation *string `type:"string"` + + // The ID of the kernel. + KernelId *string `locationName:"kernelId" type:"string"` + + // A name for your AMI. + // + // Constraints: 3-128 alphanumeric characters, parentheses (()), square brackets + // ([]), spaces ( ), periods (.), slashes (/), dashes (-), single quotes ('), + // at-signs (@), or underscores(_) + Name *string `locationName:"name" type:"string" required:"true"` + + // The ID of the RAM disk. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + // The name of the root device (for example, /dev/sda1, or /dev/xvda). + RootDeviceName *string `locationName:"rootDeviceName" type:"string"` + + // Set to simple to enable enhanced networking with the Intel 82599 Virtual + // Function interface for the AMI and any instances that you launch from the + // AMI. + // + // There is no way to disable sriovNetSupport at this time. + // + // This option is supported only for HVM AMIs. Specifying this option with + // a PV AMI can make instances launched from the AMI unreachable. + SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` + + // The type of virtualization. + // + // Default: paravirtual + VirtualizationType *string `locationName:"virtualizationType" type:"string"` +} + +// String returns the string representation +func (s RegisterImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RegisterImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RegisterImageInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of RegisterImage. +type RegisterImageOutput struct { + _ struct{} `type:"structure"` + + // The ID of the newly registered AMI. + ImageId *string `locationName:"imageId" type:"string"` +} + +// String returns the string representation +func (s RegisterImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterImageOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RejectVpcPeeringConnection. +type RejectVpcPeeringConnectionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string" required:"true"` +} + +// String returns the string representation +func (s RejectVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RejectVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RejectVpcPeeringConnectionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RejectVpcPeeringConnectionInput"} + if s.VpcPeeringConnectionId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcPeeringConnectionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of RejectVpcPeeringConnection. +type RejectVpcPeeringConnectionOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s RejectVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RejectVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReleaseAddress. +type ReleaseAddressInput struct { + _ struct{} `type:"structure"` + + // [EC2-VPC] The allocation ID. Required for EC2-VPC. + AllocationId *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // [EC2-Classic] The Elastic IP address. Required for EC2-Classic. + PublicIp *string `type:"string"` +} + +// String returns the string representation +func (s ReleaseAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseAddressInput) GoString() string { + return s.String() +} + +type ReleaseAddressOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ReleaseAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseAddressOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReleaseHosts. +type ReleaseHostsInput struct { + _ struct{} `type:"structure"` + + // The IDs of the Dedicated Hosts you want to release. + HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s ReleaseHostsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseHostsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReleaseHostsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReleaseHostsInput"} + if s.HostIds == nil { + invalidParams.Add(request.NewErrParamRequired("HostIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ReleaseHosts. +type ReleaseHostsOutput struct { + _ struct{} `type:"structure"` + + // The IDs of the Dedicated Hosts that were successfully released. + Successful []*string `locationName:"successful" locationNameList:"item" type:"list"` + + // The IDs of the Dedicated Hosts that could not be released, including an error + // message. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s ReleaseHostsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseHostsOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReplaceNetworkAclAssociation. +type ReplaceNetworkAclAssociationInput struct { + _ struct{} `type:"structure"` + + // The ID of the current association between the original network ACL and the + // subnet. + AssociationId *string `locationName:"associationId" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the new network ACL to associate with the subnet. + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` +} + +// String returns the string representation +func (s ReplaceNetworkAclAssociationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclAssociationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplaceNetworkAclAssociationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplaceNetworkAclAssociationInput"} + if s.AssociationId == nil { + invalidParams.Add(request.NewErrParamRequired("AssociationId")) + } + if s.NetworkAclId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkAclId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ReplaceNetworkAclAssociation. +type ReplaceNetworkAclAssociationOutput struct { + _ struct{} `type:"structure"` + + // The ID of the new association. + NewAssociationId *string `locationName:"newAssociationId" type:"string"` +} + +// String returns the string representation +func (s ReplaceNetworkAclAssociationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclAssociationOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReplaceNetworkAclEntry. +type ReplaceNetworkAclEntryInput struct { + _ struct{} `type:"structure"` + + // The network range to allow or deny, in CIDR notation. + CidrBlock *string `locationName:"cidrBlock" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Indicates whether to replace the egress rule. + // + // Default: If no value is specified, we replace the ingress rule. + Egress *bool `locationName:"egress" type:"boolean" required:"true"` + + // ICMP protocol: The ICMP type and code. Required if specifying 1 (ICMP) for + // the protocol. + IcmpTypeCode *IcmpTypeCode `locationName:"Icmp" type:"structure"` + + // The ID of the ACL. + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` + + // TCP or UDP protocols: The range of ports the rule applies to. Required if + // specifying 6 (TCP) or 17 (UDP) for the protocol. + PortRange *PortRange `locationName:"portRange" type:"structure"` + + // The IP protocol. You can specify all or -1 to mean all protocols. + Protocol *string `locationName:"protocol" type:"string" required:"true"` + + // Indicates whether to allow or deny the traffic that matches the rule. + RuleAction *string `locationName:"ruleAction" type:"string" required:"true" enum:"RuleAction"` + + // The rule number of the entry to replace. + RuleNumber *int64 `locationName:"ruleNumber" type:"integer" required:"true"` +} + +// String returns the string representation +func (s ReplaceNetworkAclEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclEntryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplaceNetworkAclEntryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplaceNetworkAclEntryInput"} + if s.CidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("CidrBlock")) + } + if s.Egress == nil { + invalidParams.Add(request.NewErrParamRequired("Egress")) + } + if s.NetworkAclId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkAclId")) + } + if s.Protocol == nil { + invalidParams.Add(request.NewErrParamRequired("Protocol")) + } + if s.RuleAction == nil { + invalidParams.Add(request.NewErrParamRequired("RuleAction")) + } + if s.RuleNumber == nil { + invalidParams.Add(request.NewErrParamRequired("RuleNumber")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ReplaceNetworkAclEntryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ReplaceNetworkAclEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclEntryOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReplaceRoute. +type ReplaceRouteInput struct { + _ struct{} `type:"structure"` + + // The CIDR address block used for the destination match. The value you provide + // must match the CIDR of an existing route in the table. + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of an Internet gateway or virtual private gateway. + GatewayId *string `locationName:"gatewayId" type:"string"` + + // The ID of a NAT instance in your VPC. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The ID of a NAT gateway. + NatGatewayId *string `locationName:"natGatewayId" type:"string"` + + // The ID of a network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The ID of the route table. + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` + + // The ID of a VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s ReplaceRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplaceRouteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplaceRouteInput"} + if s.DestinationCidrBlock == nil { + invalidParams.Add(request.NewErrParamRequired("DestinationCidrBlock")) + } + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ReplaceRouteOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ReplaceRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReplaceRouteTableAssociation. +type ReplaceRouteTableAssociationInput struct { + _ struct{} `type:"structure"` + + // The association ID. + AssociationId *string `locationName:"associationId" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the new route table to associate with the subnet. + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` +} + +// String returns the string representation +func (s ReplaceRouteTableAssociationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteTableAssociationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplaceRouteTableAssociationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplaceRouteTableAssociationInput"} + if s.AssociationId == nil { + invalidParams.Add(request.NewErrParamRequired("AssociationId")) + } + if s.RouteTableId == nil { + invalidParams.Add(request.NewErrParamRequired("RouteTableId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of ReplaceRouteTableAssociation. +type ReplaceRouteTableAssociationOutput struct { + _ struct{} `type:"structure"` + + // The ID of the new association. + NewAssociationId *string `locationName:"newAssociationId" type:"string"` +} + +// String returns the string representation +func (s ReplaceRouteTableAssociationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteTableAssociationOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ReportInstanceStatus. +type ReportInstanceStatusInput struct { + _ struct{} `type:"structure"` + + // Descriptive text about the health state of your instance. + Description *string `locationName:"description" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The time at which the reported instance health state ended. + EndTime *time.Time `locationName:"endTime" type:"timestamp" timestampFormat:"iso8601"` + + // One or more instances. + Instances []*string `locationName:"instanceId" locationNameList:"InstanceId" type:"list" required:"true"` + + // One or more reason codes that describes the health state of your instance. + // + // instance-stuck-in-state: My instance is stuck in a state. + // + // unresponsive: My instance is unresponsive. + // + // not-accepting-credentials: My instance is not accepting my credentials. + // + // password-not-available: A password is not available for my instance. + // + // performance-network: My instance is experiencing performance problems + // which I believe are network related. + // + // performance-instance-store: My instance is experiencing performance problems + // which I believe are related to the instance stores. + // + // performance-ebs-volume: My instance is experiencing performance problems + // which I believe are related to an EBS volume. + // + // performance-other: My instance is experiencing performance problems. + // + // other: [explain using the description parameter] + ReasonCodes []*string `locationName:"reasonCode" locationNameList:"item" type:"list" required:"true"` + + // The time at which the reported instance health state began. + StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` + + // The status of all instances listed. + Status *string `locationName:"status" type:"string" required:"true" enum:"ReportStatusType"` +} + +// String returns the string representation +func (s ReportInstanceStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReportInstanceStatusInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReportInstanceStatusInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReportInstanceStatusInput"} + if s.Instances == nil { + invalidParams.Add(request.NewErrParamRequired("Instances")) + } + if s.ReasonCodes == nil { + invalidParams.Add(request.NewErrParamRequired("ReasonCodes")) + } + if s.Status == nil { + invalidParams.Add(request.NewErrParamRequired("Status")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ReportInstanceStatusOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ReportInstanceStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReportInstanceStatusOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RequestSpotFleet. +type RequestSpotFleetInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The configuration for the Spot fleet request. + SpotFleetRequestConfig *SpotFleetRequestConfigData `locationName:"spotFleetRequestConfig" type:"structure" required:"true"` +} + +// String returns the string representation +func (s RequestSpotFleetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotFleetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RequestSpotFleetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RequestSpotFleetInput"} + if s.SpotFleetRequestConfig == nil { + invalidParams.Add(request.NewErrParamRequired("SpotFleetRequestConfig")) + } + if s.SpotFleetRequestConfig != nil { + if err := s.SpotFleetRequestConfig.Validate(); err != nil { + invalidParams.AddNested("SpotFleetRequestConfig", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of RequestSpotFleet. +type RequestSpotFleetOutput struct { + _ struct{} `type:"structure"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` +} + +// String returns the string representation +func (s RequestSpotFleetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotFleetOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RequestSpotInstances. +type RequestSpotInstancesInput struct { + _ struct{} `type:"structure"` + + // The user-specified name for a logical grouping of bids. + // + // When you specify an Availability Zone group in a Spot Instance request, + // all Spot instances in the request are launched in the same Availability Zone. + // Instance proximity is maintained with this parameter, but the choice of Availability + // Zone is not. The group applies only to bids for Spot Instances of the same + // instance type. Any additional Spot instance requests that are specified with + // the same Availability Zone group name are launched in that same Availability + // Zone, as long as at least one instance from the group is still active. + // + // If there is no active instance running in the Availability Zone group that + // you specify for a new Spot instance request (all instances are terminated, + // the bid is expired, or the bid falls below current market), then Amazon EC2 + // launches the instance in any Availability Zone where the constraint can be + // met. Consequently, the subsequent set of Spot instances could be placed in + // a different zone from the original request, even if you specified the same + // Availability Zone group. + // + // Default: Instances are launched in any available Availability Zone. + AvailabilityZoneGroup *string `locationName:"availabilityZoneGroup" type:"string"` + + // The required duration for the Spot instances (also known as Spot blocks), + // in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, + // or 360). + // + // The duration period starts as soon as your Spot instance receives its instance + // ID. At the end of the duration period, Amazon EC2 marks the Spot instance + // for termination and provides a Spot instance termination notice, which gives + // the instance a two-minute warning before it terminates. + // + // Note that you can't specify an Availability Zone group or a launch group + // if you specify a duration. + BlockDurationMinutes *int64 `locationName:"blockDurationMinutes" type:"integer"` + + // Unique, case-sensitive identifier that you provide to ensure the idempotency + // of the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The maximum number of Spot instances to launch. + // + // Default: 1 + InstanceCount *int64 `locationName:"instanceCount" type:"integer"` + + // The instance launch group. Launch groups are Spot instances that launch together + // and terminate together. + // + // Default: Instances are launched and terminated individually + LaunchGroup *string `locationName:"launchGroup" type:"string"` + + // Describes the launch specification for an instance. + LaunchSpecification *RequestSpotLaunchSpecification `type:"structure"` + + // The maximum hourly price (bid) for any Spot instance launched to fulfill + // the request. + SpotPrice *string `locationName:"spotPrice" type:"string" required:"true"` + + // The Spot instance request type. + // + // Default: one-time + Type *string `locationName:"type" type:"string" enum:"SpotInstanceType"` + + // The start date of the request. If this is a one-time request, the request + // becomes active at this date and time and remains active until all instances + // launch, the request expires, or the request is canceled. If the request is + // persistent, the request becomes active at this date and time and remains + // active until it expires or is canceled. + // + // Default: The request is effective indefinitely. + ValidFrom *time.Time `locationName:"validFrom" type:"timestamp" timestampFormat:"iso8601"` + + // The end date of the request. If this is a one-time request, the request remains + // active until all instances launch, the request is canceled, or this date + // is reached. If the request is persistent, it remains active until it is canceled + // or this date and time is reached. + // + // Default: The request is effective indefinitely. + ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s RequestSpotInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RequestSpotInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RequestSpotInstancesInput"} + if s.SpotPrice == nil { + invalidParams.Add(request.NewErrParamRequired("SpotPrice")) + } + if s.LaunchSpecification != nil { + if err := s.LaunchSpecification.Validate(); err != nil { + invalidParams.AddNested("LaunchSpecification", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of RequestSpotInstances. +type RequestSpotInstancesOutput struct { + _ struct{} `type:"structure"` + + // One or more Spot instance requests. + SpotInstanceRequests []*SpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s RequestSpotInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotInstancesOutput) GoString() string { + return s.String() +} + +// Describes the launch specification for an instance. +type RequestSpotLaunchSpecification struct { + _ struct{} `type:"structure"` + + // Deprecated. + AddressingType *string `locationName:"addressingType" type:"string"` + + // One or more block device mapping entries. + // + // Although you can specify encrypted EBS volumes in this block device mapping + // for your Spot Instances, these volumes are not encrypted. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // Indicates whether the instance is optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS + // Optimized instance. + // + // Default: false + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // The IAM instance profile. + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI. + ImageId *string `locationName:"imageId" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The ID of the kernel. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` + + // Describes the monitoring for the instance. + Monitoring *RunInstancesMonitoringEnabled `locationName:"monitoring" type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*InstanceNetworkInterfaceSpecification `locationName:"NetworkInterface" locationNameList:"item" type:"list"` + + // The placement information for the instance. + Placement *SpotPlacement `locationName:"placement" type:"structure"` + + // The ID of the RAM disk. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"item" type:"list"` + + SecurityGroups []*string `locationName:"SecurityGroup" locationNameList:"item" type:"list"` + + // The ID of the subnet in which to launch the instance. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The user data to make available to the instances. If you are using an AWS + // SDK or command line tool, Base64-encoding is performed for you, and you can + // load the text from a file. Otherwise, you must provide Base64-encoded text. + UserData *string `locationName:"userData" type:"string"` +} + +// String returns the string representation +func (s RequestSpotLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotLaunchSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RequestSpotLaunchSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RequestSpotLaunchSpecification"} + if s.Monitoring != nil { + if err := s.Monitoring.Validate(); err != nil { + invalidParams.AddNested("Monitoring", err.(request.ErrInvalidParams)) + } + } + if s.NetworkInterfaces != nil { + for i, v := range s.NetworkInterfaces { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "NetworkInterfaces", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a reservation. +type Reservation struct { + _ struct{} `type:"structure"` + + // [EC2-Classic only] One or more security groups. + Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // One or more instances. + Instances []*Instance `locationName:"instancesSet" locationNameList:"item" type:"list"` + + // The ID of the AWS account that owns the reservation. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The ID of the requester that launched the instances on your behalf (for example, + // AWS Management Console or Auto Scaling). + RequesterId *string `locationName:"requesterId" type:"string"` + + // The ID of the reservation. + ReservationId *string `locationName:"reservationId" type:"string"` +} + +// String returns the string representation +func (s Reservation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Reservation) GoString() string { + return s.String() +} + +// Describes the limit price of a Reserved Instance offering. +type ReservedInstanceLimitPrice struct { + _ struct{} `type:"structure"` + + // Used for Reserved Instance Marketplace offerings. Specifies the limit price + // on the total order (instanceCount * price). + Amount *float64 `locationName:"amount" type:"double"` + + // The currency in which the limitPrice amount is specified. At this time, the + // only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` +} + +// String returns the string representation +func (s ReservedInstanceLimitPrice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstanceLimitPrice) GoString() string { + return s.String() +} + +// Describes a Reserved Instance. +type ReservedInstances struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which the Reserved Instance can be used. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The currency of the Reserved Instance. It's specified using ISO 4217 standard + // currency codes. At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The duration of the Reserved Instance, in seconds. + Duration *int64 `locationName:"duration" type:"long"` + + // The time when the Reserved Instance expires. + End *time.Time `locationName:"end" type:"timestamp" timestampFormat:"iso8601"` + + // The purchase price of the Reserved Instance. + FixedPrice *float64 `locationName:"fixedPrice" type:"float"` + + // The number of reservations purchased. + InstanceCount *int64 `locationName:"instanceCount" type:"integer"` + + // The tenancy of the instance. + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` + + // The instance type on which the Reserved Instance can be used. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The Reserved Instance offering type. + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` + + // The Reserved Instance product platform description. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` + + // The recurring charge tag assigned to the resource. + RecurringCharges []*RecurringCharge `locationName:"recurringCharges" locationNameList:"item" type:"list"` + + // The ID of the Reserved Instance. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` + + // The date and time the Reserved Instance started. + Start *time.Time `locationName:"start" type:"timestamp" timestampFormat:"iso8601"` + + // The state of the Reserved Instance purchase. + State *string `locationName:"state" type:"string" enum:"ReservedInstanceState"` + + // Any tags assigned to the resource. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The usage price of the Reserved Instance, per hour. + UsagePrice *float64 `locationName:"usagePrice" type:"float"` +} + +// String returns the string representation +func (s ReservedInstances) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstances) GoString() string { + return s.String() +} + +// Describes the configuration settings for the modified Reserved Instances. +type ReservedInstancesConfiguration struct { + _ struct{} `type:"structure"` + + // The Availability Zone for the modified Reserved Instances. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The number of modified Reserved Instances. + InstanceCount *int64 `locationName:"instanceCount" type:"integer"` + + // The instance type for the modified Reserved Instances. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The network platform of the modified Reserved Instances, which is either + // EC2-Classic or EC2-VPC. + Platform *string `locationName:"platform" type:"string"` +} + +// String returns the string representation +func (s ReservedInstancesConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesConfiguration) GoString() string { + return s.String() +} + +// Describes the ID of a Reserved Instance. +type ReservedInstancesId struct { + _ struct{} `type:"structure"` + + // The ID of the Reserved Instance. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` +} + +// String returns the string representation +func (s ReservedInstancesId) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesId) GoString() string { + return s.String() +} + +// Describes a Reserved Instance listing. +type ReservedInstancesListing struct { + _ struct{} `type:"structure"` + + // A unique, case-sensitive key supplied by the client to ensure that the request + // is idempotent. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `locationName:"clientToken" type:"string"` + + // The time the listing was created. + CreateDate *time.Time `locationName:"createDate" type:"timestamp" timestampFormat:"iso8601"` + + // The number of instances in this state. + InstanceCounts []*InstanceCount `locationName:"instanceCounts" locationNameList:"item" type:"list"` + + // The price of the Reserved Instance listing. + PriceSchedules []*PriceSchedule `locationName:"priceSchedules" locationNameList:"item" type:"list"` + + // The ID of the Reserved Instance. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` + + // The ID of the Reserved Instance listing. + ReservedInstancesListingId *string `locationName:"reservedInstancesListingId" type:"string"` + + // The status of the Reserved Instance listing. + Status *string `locationName:"status" type:"string" enum:"ListingStatus"` + + // The reason for the current status of the Reserved Instance listing. The response + // can be blank. + StatusMessage *string `locationName:"statusMessage" type:"string"` + + // Any tags assigned to the resource. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The last modified timestamp of the listing. + UpdateDate *time.Time `locationName:"updateDate" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s ReservedInstancesListing) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesListing) GoString() string { + return s.String() +} + +// Describes a Reserved Instance modification. +type ReservedInstancesModification struct { + _ struct{} `type:"structure"` + + // A unique, case-sensitive key supplied by the client to ensure that the request + // is idempotent. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `locationName:"clientToken" type:"string"` + + // The time when the modification request was created. + CreateDate *time.Time `locationName:"createDate" type:"timestamp" timestampFormat:"iso8601"` + + // The time for the modification to become effective. + EffectiveDate *time.Time `locationName:"effectiveDate" type:"timestamp" timestampFormat:"iso8601"` + + // Contains target configurations along with their corresponding new Reserved + // Instance IDs. + ModificationResults []*ReservedInstancesModificationResult `locationName:"modificationResultSet" locationNameList:"item" type:"list"` + + // The IDs of one or more Reserved Instances. + ReservedInstancesIds []*ReservedInstancesId `locationName:"reservedInstancesSet" locationNameList:"item" type:"list"` + + // A unique ID for the Reserved Instance modification. + ReservedInstancesModificationId *string `locationName:"reservedInstancesModificationId" type:"string"` + + // The status of the Reserved Instances modification request. + Status *string `locationName:"status" type:"string"` + + // The reason for the status. + StatusMessage *string `locationName:"statusMessage" type:"string"` + + // The time when the modification request was last updated. + UpdateDate *time.Time `locationName:"updateDate" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s ReservedInstancesModification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesModification) GoString() string { + return s.String() +} + +// Describes the modification request/s. +type ReservedInstancesModificationResult struct { + _ struct{} `type:"structure"` + + // The ID for the Reserved Instances that were created as part of the modification + // request. This field is only available when the modification is fulfilled. + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` + + // The target Reserved Instances configurations supplied as part of the modification + // request. + TargetConfiguration *ReservedInstancesConfiguration `locationName:"targetConfiguration" type:"structure"` +} + +// String returns the string representation +func (s ReservedInstancesModificationResult) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesModificationResult) GoString() string { + return s.String() +} + +// Describes a Reserved Instance offering. +type ReservedInstancesOffering struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which the Reserved Instance can be used. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The currency of the Reserved Instance offering you are purchasing. It's specified + // using ISO 4217 standard currency codes. At this time, the only supported + // currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The duration of the Reserved Instance, in seconds. + Duration *int64 `locationName:"duration" type:"long"` + + // The purchase price of the Reserved Instance. + FixedPrice *float64 `locationName:"fixedPrice" type:"float"` + + // The tenancy of the instance. + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` + + // The instance type on which the Reserved Instance can be used. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // Indicates whether the offering is available through the Reserved Instance + // Marketplace (resale) or AWS. If it's a Reserved Instance Marketplace offering, + // this is true. + Marketplace *bool `locationName:"marketplace" type:"boolean"` + + // The Reserved Instance offering type. + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` + + // The pricing details of the Reserved Instance offering. + PricingDetails []*PricingDetail `locationName:"pricingDetailsSet" locationNameList:"item" type:"list"` + + // The Reserved Instance product platform description. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` + + // The recurring charge tag assigned to the resource. + RecurringCharges []*RecurringCharge `locationName:"recurringCharges" locationNameList:"item" type:"list"` + + // The ID of the Reserved Instance offering. + ReservedInstancesOfferingId *string `locationName:"reservedInstancesOfferingId" type:"string"` + + // The usage price of the Reserved Instance, per hour. + UsagePrice *float64 `locationName:"usagePrice" type:"float"` +} + +// String returns the string representation +func (s ReservedInstancesOffering) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesOffering) GoString() string { + return s.String() +} + +// Contains the parameters for ResetImageAttribute. +type ResetImageAttributeInput struct { + _ struct{} `type:"structure"` + + // The attribute to reset (currently you can only reset the launch permission + // attribute). + Attribute *string `type:"string" required:"true" enum:"ResetImageAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the AMI. + ImageId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ResetImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetImageAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResetImageAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResetImageAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.ImageId == nil { + invalidParams.Add(request.NewErrParamRequired("ImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ResetImageAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ResetImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetImageAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ResetInstanceAttribute. +type ResetInstanceAttributeInput struct { + _ struct{} `type:"structure"` + + // The attribute to reset. + // + // You can only reset the following attributes: kernel | ramdisk | sourceDestCheck. + // To change an instance attribute, use ModifyInstanceAttribute. + Attribute *string `locationName:"attribute" type:"string" required:"true" enum:"InstanceAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` +} + +// String returns the string representation +func (s ResetInstanceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetInstanceAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResetInstanceAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResetInstanceAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ResetInstanceAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ResetInstanceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetInstanceAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ResetNetworkInterfaceAttribute. +type ResetNetworkInterfaceAttributeInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` + + // The source/destination checking attribute. Resets the value to true. + SourceDestCheck *string `locationName:"sourceDestCheck" type:"string"` +} + +// String returns the string representation +func (s ResetNetworkInterfaceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetNetworkInterfaceAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResetNetworkInterfaceAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResetNetworkInterfaceAttributeInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ResetNetworkInterfaceAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ResetNetworkInterfaceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetNetworkInterfaceAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for ResetSnapshotAttribute. +type ResetSnapshotAttributeInput struct { + _ struct{} `type:"structure"` + + // The attribute to reset. Currently, only the attribute for permission to create + // volumes can be reset. + Attribute *string `type:"string" required:"true" enum:"SnapshotAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the snapshot. + SnapshotId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ResetSnapshotAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetSnapshotAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResetSnapshotAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResetSnapshotAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.SnapshotId == nil { + invalidParams.Add(request.NewErrParamRequired("SnapshotId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ResetSnapshotAttributeOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ResetSnapshotAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetSnapshotAttributeOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RestoreAddressToClassic. +type RestoreAddressToClassicInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The Elastic IP address. + PublicIp *string `locationName:"publicIp" type:"string" required:"true"` +} + +// String returns the string representation +func (s RestoreAddressToClassicInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RestoreAddressToClassicInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RestoreAddressToClassicInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RestoreAddressToClassicInput"} + if s.PublicIp == nil { + invalidParams.Add(request.NewErrParamRequired("PublicIp")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of RestoreAddressToClassic. +type RestoreAddressToClassicOutput struct { + _ struct{} `type:"structure"` + + // The Elastic IP address. + PublicIp *string `locationName:"publicIp" type:"string"` + + // The move status for the IP address. + Status *string `locationName:"status" type:"string" enum:"Status"` +} + +// String returns the string representation +func (s RestoreAddressToClassicOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RestoreAddressToClassicOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RevokeSecurityGroupEgress. +type RevokeSecurityGroupEgressInput struct { + _ struct{} `type:"structure"` + + // The CIDR IP address range. We recommend that you specify the CIDR range in + // a set of IP permissions instead. + CidrIp *string `locationName:"cidrIp" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The start of port range for the TCP and UDP protocols, or an ICMP type number. + // We recommend that you specify the port range in a set of IP permissions instead. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string" required:"true"` + + // A set of IP permissions. You can't specify a destination security group and + // a CIDR IP address range. + IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` + + // The IP protocol name or number. We recommend that you specify the protocol + // in a set of IP permissions instead. + IpProtocol *string `locationName:"ipProtocol" type:"string"` + + // The name of a destination security group. To revoke outbound access to a + // destination security group, we recommend that you use a set of IP permissions + // instead. + SourceSecurityGroupName *string `locationName:"sourceSecurityGroupName" type:"string"` + + // The AWS account number for a destination security group. To revoke outbound + // access to a destination security group, we recommend that you use a set of + // IP permissions instead. + SourceSecurityGroupOwnerId *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` + + // The end of port range for the TCP and UDP protocols, or an ICMP type number. + // We recommend that you specify the port range in a set of IP permissions instead. + ToPort *int64 `locationName:"toPort" type:"integer"` +} + +// String returns the string representation +func (s RevokeSecurityGroupEgressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupEgressInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RevokeSecurityGroupEgressInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RevokeSecurityGroupEgressInput"} + if s.GroupId == nil { + invalidParams.Add(request.NewErrParamRequired("GroupId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type RevokeSecurityGroupEgressOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s RevokeSecurityGroupEgressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupEgressOutput) GoString() string { + return s.String() +} + +// Contains the parameters for RevokeSecurityGroupIngress. +type RevokeSecurityGroupIngressInput struct { + _ struct{} `type:"structure"` + + // The CIDR IP address range. You can't specify this parameter when specifying + // a source security group. + CidrIp *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The start of port range for the TCP and UDP protocols, or an ICMP type number. + // For the ICMP type number, use -1 to specify all ICMP types. + FromPort *int64 `type:"integer"` + + // The ID of the security group. Required for a security group in a nondefault + // VPC. + GroupId *string `type:"string"` + + // [EC2-Classic, default VPC] The name of the security group. + GroupName *string `type:"string"` + + // A set of IP permissions. You can't specify a source security group and a + // CIDR IP address range. + IpPermissions []*IpPermission `locationNameList:"item" type:"list"` + + // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). + // Use -1 to specify all. + IpProtocol *string `type:"string"` + + // [EC2-Classic, default VPC] The name of the source security group. You can't + // specify this parameter in combination with the following parameters: the + // CIDR IP address range, the start of the port range, the IP protocol, and + // the end of the port range. For EC2-VPC, the source security group must be + // in the same VPC. To revoke a specific rule for an IP protocol and port range, + // use a set of IP permissions instead. + SourceSecurityGroupName *string `type:"string"` + + // [EC2-Classic] The AWS account ID of the source security group, if the source + // security group is in a different account. You can't specify this parameter + // in combination with the following parameters: the CIDR IP address range, + // the IP protocol, the start of the port range, and the end of the port range. + // To revoke a specific rule for an IP protocol and port range, use a set of + // IP permissions instead. + SourceSecurityGroupOwnerId *string `type:"string"` + + // The end of port range for the TCP and UDP protocols, or an ICMP code number. + // For the ICMP code number, use -1 to specify all ICMP codes for the ICMP type. + ToPort *int64 `type:"integer"` +} + +// String returns the string representation +func (s RevokeSecurityGroupIngressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupIngressInput) GoString() string { + return s.String() +} + +type RevokeSecurityGroupIngressOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s RevokeSecurityGroupIngressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupIngressOutput) GoString() string { + return s.String() +} + +// Describes a route in a route table. +type Route struct { + _ struct{} `type:"structure"` + + // The CIDR block used for the destination match. + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string"` + + // The prefix of the AWS service. + DestinationPrefixListId *string `locationName:"destinationPrefixListId" type:"string"` + + // The ID of a gateway attached to your VPC. + GatewayId *string `locationName:"gatewayId" type:"string"` + + // The ID of a NAT instance in your VPC. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The AWS account ID of the owner of the instance. + InstanceOwnerId *string `locationName:"instanceOwnerId" type:"string"` + + // The ID of a NAT gateway. + NatGatewayId *string `locationName:"natGatewayId" type:"string"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // Describes how the route was created. + // + // CreateRouteTable - The route was automatically created when the route + // table was created. + // + // CreateRoute - The route was manually added to the route table. + // + // EnableVgwRoutePropagation - The route was propagated by route propagation. + Origin *string `locationName:"origin" type:"string" enum:"RouteOrigin"` + + // The state of the route. The blackhole state indicates that the route's target + // isn't available (for example, the specified gateway isn't attached to the + // VPC, or the specified NAT instance has been terminated). + State *string `locationName:"state" type:"string" enum:"RouteState"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s Route) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Route) GoString() string { + return s.String() +} + +// Describes a route table. +type RouteTable struct { + _ struct{} `type:"structure"` + + // The associations between the route table and one or more subnets. + Associations []*RouteTableAssociation `locationName:"associationSet" locationNameList:"item" type:"list"` + + // Any virtual private gateway (VGW) propagating routes. + PropagatingVgws []*PropagatingVgw `locationName:"propagatingVgwSet" locationNameList:"item" type:"list"` + + // The ID of the route table. + RouteTableId *string `locationName:"routeTableId" type:"string"` + + // The routes in the route table. + Routes []*Route `locationName:"routeSet" locationNameList:"item" type:"list"` + + // Any tags assigned to the route table. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s RouteTable) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RouteTable) GoString() string { + return s.String() +} + +// Describes an association between a route table and a subnet. +type RouteTableAssociation struct { + _ struct{} `type:"structure"` + + // Indicates whether this is the main route table. + Main *bool `locationName:"main" type:"boolean"` + + // The ID of the association between a route table and a subnet. + RouteTableAssociationId *string `locationName:"routeTableAssociationId" type:"string"` + + // The ID of the route table. + RouteTableId *string `locationName:"routeTableId" type:"string"` + + // The ID of the subnet. A subnet ID is not returned for an implicit association. + SubnetId *string `locationName:"subnetId" type:"string"` +} + +// String returns the string representation +func (s RouteTableAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RouteTableAssociation) GoString() string { + return s.String() +} + +// Contains the parameters for RunInstances. +type RunInstancesInput struct { + _ struct{} `type:"structure"` + + // Reserved. + AdditionalInfo *string `locationName:"additionalInfo" type:"string"` + + // The block device mapping. + // + // Supplying both a snapshot ID and an encryption value as arguments for block-device + // mapping results in an error. This is because only blank volumes can be encrypted + // on start, and these are not created from a snapshot. If a snapshot is the + // basis for the volume, it contains data by definition and its encryption status + // cannot be changed using this action. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + // + // Constraints: Maximum 64 ASCII characters + ClientToken *string `locationName:"clientToken" type:"string"` + + // If you set this parameter to true, you can't terminate the instance using + // the Amazon EC2 console, CLI, or API; otherwise, you can. If you set this + // parameter to true and then later want to be able to terminate the instance, + // you must first change the value of the disableApiTermination attribute to + // false using ModifyInstanceAttribute. Alternatively, if you set InstanceInitiatedShutdownBehavior + // to terminate, you can terminate the instance by running the shutdown command + // from the instance. + // + // Default: false + DisableApiTermination *bool `locationName:"disableApiTermination" type:"boolean"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Indicates whether the instance is optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS-optimized + // instance. + // + // Default: false + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // The IAM instance profile. + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI, which you can get by calling DescribeImages. + ImageId *string `type:"string" required:"true"` + + // Indicates whether an instance stops or terminates when you initiate shutdown + // from the instance (using the operating system command for system shutdown). + // + // Default: stop + InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` + + // The instance type. For more information, see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // Default: m1.small + InstanceType *string `type:"string" enum:"InstanceType"` + + // The ID of the kernel. + // + // We recommend that you use PV-GRUB instead of kernels and RAM disks. For + // more information, see PV-GRUB (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) + // in the Amazon Elastic Compute Cloud User Guide. + KernelId *string `type:"string"` + + // The name of the key pair. You can create a key pair using CreateKeyPair or + // ImportKeyPair. + // + // If you do not specify a key pair, you can't connect to the instance unless + // you choose an AMI that is configured to allow users another way to log in. + KeyName *string `type:"string"` + + // The maximum number of instances to launch. If you specify more instances + // than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches + // the largest possible number of instances above MinCount. + // + // Constraints: Between 1 and the maximum number you're allowed for the specified + // instance type. For more information about the default limits, and how to + // request an increase, see How many instances can I run in Amazon EC2 (http://aws.amazon.com/ec2/faqs/#How_many_instances_can_I_run_in_Amazon_EC2) + // in the Amazon EC2 FAQ. + MaxCount *int64 `type:"integer" required:"true"` + + // The minimum number of instances to launch. If you specify a minimum that + // is more instances than Amazon EC2 can launch in the target Availability Zone, + // Amazon EC2 launches no instances. + // + // Constraints: Between 1 and the maximum number you're allowed for the specified + // instance type. For more information about the default limits, and how to + // request an increase, see How many instances can I run in Amazon EC2 (http://aws.amazon.com/ec2/faqs/#How_many_instances_can_I_run_in_Amazon_EC2) + // in the Amazon EC2 General FAQ. + MinCount *int64 `type:"integer" required:"true"` + + // The monitoring for the instance. + Monitoring *RunInstancesMonitoringEnabled `type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*InstanceNetworkInterfaceSpecification `locationName:"networkInterface" locationNameList:"item" type:"list"` + + // The placement for the instance. + Placement *Placement `type:"structure"` + + // [EC2-VPC] The primary IP address. You must specify a value from the IP address + // range of the subnet. + // + // Only one private IP address can be designated as primary. Therefore, you + // can't specify this parameter if PrivateIpAddresses.n.Primary is set to true + // and PrivateIpAddresses.n.PrivateIpAddress is set to an IP address. + // + // Default: We select an IP address from the IP address range of the subnet. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The ID of the RAM disk. + // + // We recommend that you use PV-GRUB instead of kernels and RAM disks. For + // more information, see PV-GRUB (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) + // in the Amazon Elastic Compute Cloud User Guide. + RamdiskId *string `type:"string"` + + // One or more security group IDs. You can create a security group using CreateSecurityGroup. + // + // Default: Amazon EC2 uses the default security group. + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // [EC2-Classic, default VPC] One or more security group names. For a nondefault + // VPC, you must use security group IDs instead. + // + // Default: Amazon EC2 uses the default security group. + SecurityGroups []*string `locationName:"SecurityGroup" locationNameList:"SecurityGroup" type:"list"` + + // [EC2-VPC] The ID of the subnet to launch the instance into. + SubnetId *string `type:"string"` + + // The user data to make available to the instance. For more information, see + // Running Commands on Your Linux Instance at Launch (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) + // (Linux) and Adding User Data (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-instance-metadata.html#instancedata-add-user-data) + // (Windows). If you are using an AWS SDK or command line tool, Base64-encoding + // is performed for you, and you can load the text from a file. Otherwise, you + // must provide Base64-encoded text. + UserData *string `type:"string"` +} + +// String returns the string representation +func (s RunInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RunInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RunInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RunInstancesInput"} + if s.ImageId == nil { + invalidParams.Add(request.NewErrParamRequired("ImageId")) + } + if s.MaxCount == nil { + invalidParams.Add(request.NewErrParamRequired("MaxCount")) + } + if s.MinCount == nil { + invalidParams.Add(request.NewErrParamRequired("MinCount")) + } + if s.Monitoring != nil { + if err := s.Monitoring.Validate(); err != nil { + invalidParams.AddNested("Monitoring", err.(request.ErrInvalidParams)) + } + } + if s.NetworkInterfaces != nil { + for i, v := range s.NetworkInterfaces { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "NetworkInterfaces", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes the monitoring for the instance. +type RunInstancesMonitoringEnabled struct { + _ struct{} `type:"structure"` + + // Indicates whether monitoring is enabled for the instance. + Enabled *bool `locationName:"enabled" type:"boolean" required:"true"` +} + +// String returns the string representation +func (s RunInstancesMonitoringEnabled) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RunInstancesMonitoringEnabled) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RunInstancesMonitoringEnabled) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RunInstancesMonitoringEnabled"} + if s.Enabled == nil { + invalidParams.Add(request.NewErrParamRequired("Enabled")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the parameters for RunScheduledInstances. +type RunScheduledInstancesInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier that ensures the idempotency of the request. + // For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string" idempotencyToken:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The number of instances. + // + // Default: 1 + InstanceCount *int64 `type:"integer"` + + // The launch specification. You must match the instance type, Availability + // Zone, network, and platform of the schedule that you purchased. + LaunchSpecification *ScheduledInstancesLaunchSpecification `type:"structure" required:"true"` + + // The Scheduled Instance ID. + ScheduledInstanceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s RunScheduledInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RunScheduledInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RunScheduledInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RunScheduledInstancesInput"} + if s.LaunchSpecification == nil { + invalidParams.Add(request.NewErrParamRequired("LaunchSpecification")) + } + if s.ScheduledInstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("ScheduledInstanceId")) + } + if s.LaunchSpecification != nil { + if err := s.LaunchSpecification.Validate(); err != nil { + invalidParams.AddNested("LaunchSpecification", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of RunScheduledInstances. +type RunScheduledInstancesOutput struct { + _ struct{} `type:"structure"` + + // The IDs of the newly launched instances. + InstanceIdSet []*string `locationName:"instanceIdSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s RunScheduledInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RunScheduledInstancesOutput) GoString() string { + return s.String() +} + +// Describes the storage parameters for S3 and S3 buckets for an instance store-backed +// AMI. +type S3Storage struct { + _ struct{} `type:"structure"` + + // The access key ID of the owner of the bucket. Before you specify a value + // for your access key ID, review and follow the guidance in Best Practices + // for Managing AWS Access Keys (http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html). + AWSAccessKeyId *string `type:"string"` + + // The bucket in which to store the AMI. You can specify a bucket that you already + // own or a new bucket that Amazon EC2 creates on your behalf. If you specify + // a bucket that belongs to someone else, Amazon EC2 returns an error. + Bucket *string `locationName:"bucket" type:"string"` + + // The beginning of the file name of the AMI. + Prefix *string `locationName:"prefix" type:"string"` + + // An Amazon S3 upload policy that gives Amazon EC2 permission to upload items + // into Amazon S3 on your behalf. + // + // UploadPolicy is automatically base64 encoded/decoded by the SDK. + UploadPolicy []byte `locationName:"uploadPolicy" type:"blob"` + + // The signature of the JSON document. + UploadPolicySignature *string `locationName:"uploadPolicySignature" type:"string"` +} + +// String returns the string representation +func (s S3Storage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s S3Storage) GoString() string { + return s.String() +} + +// Describes a Scheduled Instance. +type ScheduledInstance struct { + _ struct{} `type:"structure"` + + // The Availability Zone. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The date when the Scheduled Instance was purchased. + CreateDate *time.Time `locationName:"createDate" type:"timestamp" timestampFormat:"iso8601"` + + // The hourly price for a single instance. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The number of instances. + InstanceCount *int64 `locationName:"instanceCount" type:"integer"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string"` + + // The network platform (EC2-Classic or EC2-VPC). + NetworkPlatform *string `locationName:"networkPlatform" type:"string"` + + // The time for the next schedule to start. + NextSlotStartTime *time.Time `locationName:"nextSlotStartTime" type:"timestamp" timestampFormat:"iso8601"` + + // The platform (Linux/UNIX or Windows). + Platform *string `locationName:"platform" type:"string"` + + // The time that the previous schedule ended or will end. + PreviousSlotEndTime *time.Time `locationName:"previousSlotEndTime" type:"timestamp" timestampFormat:"iso8601"` + + // The schedule recurrence. + Recurrence *ScheduledInstanceRecurrence `locationName:"recurrence" type:"structure"` + + // The Scheduled Instance ID. + ScheduledInstanceId *string `locationName:"scheduledInstanceId" type:"string"` + + // The number of hours in the schedule. + SlotDurationInHours *int64 `locationName:"slotDurationInHours" type:"integer"` + + // The end date for the Scheduled Instance. + TermEndDate *time.Time `locationName:"termEndDate" type:"timestamp" timestampFormat:"iso8601"` + + // The start date for the Scheduled Instance. + TermStartDate *time.Time `locationName:"termStartDate" type:"timestamp" timestampFormat:"iso8601"` + + // The total number of hours for a single instance for the entire term. + TotalScheduledInstanceHours *int64 `locationName:"totalScheduledInstanceHours" type:"integer"` +} + +// String returns the string representation +func (s ScheduledInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstance) GoString() string { + return s.String() +} + +// Describes a schedule that is available for your Scheduled Instances. +type ScheduledInstanceAvailability struct { + _ struct{} `type:"structure"` + + // The Availability Zone. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The number of available instances. + AvailableInstanceCount *int64 `locationName:"availableInstanceCount" type:"integer"` + + // The time period for the first schedule to start. + FirstSlotStartTime *time.Time `locationName:"firstSlotStartTime" type:"timestamp" timestampFormat:"iso8601"` + + // The hourly price for a single instance. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance type. You can specify one of the C3, C4, M4, or R3 instance + // types. + InstanceType *string `locationName:"instanceType" type:"string"` + + // The maximum term. The only possible value is 365 days. + MaxTermDurationInDays *int64 `locationName:"maxTermDurationInDays" type:"integer"` + + // The minimum term. The only possible value is 365 days. + MinTermDurationInDays *int64 `locationName:"minTermDurationInDays" type:"integer"` + + // The network platform (EC2-Classic or EC2-VPC). + NetworkPlatform *string `locationName:"networkPlatform" type:"string"` + + // The platform (Linux/UNIX or Windows). + Platform *string `locationName:"platform" type:"string"` + + // The purchase token. This token expires in two hours. + PurchaseToken *string `locationName:"purchaseToken" type:"string"` + + // The schedule recurrence. + Recurrence *ScheduledInstanceRecurrence `locationName:"recurrence" type:"structure"` + + // The number of hours in the schedule. + SlotDurationInHours *int64 `locationName:"slotDurationInHours" type:"integer"` + + // The total number of hours for a single instance for the entire term. + TotalScheduledInstanceHours *int64 `locationName:"totalScheduledInstanceHours" type:"integer"` +} + +// String returns the string representation +func (s ScheduledInstanceAvailability) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstanceAvailability) GoString() string { + return s.String() +} + +// Describes the recurring schedule for a Scheduled Instance. +type ScheduledInstanceRecurrence struct { + _ struct{} `type:"structure"` + + // The frequency (Daily, Weekly, or Monthly). + Frequency *string `locationName:"frequency" type:"string"` + + // The interval quantity. The interval unit depends on the value of frequency. + // For example, every 2 weeks or every 2 months. + Interval *int64 `locationName:"interval" type:"integer"` + + // The days. For a monthly schedule, this is one or more days of the month (1-31). + // For a weekly schedule, this is one or more days of the week (1-7, where 1 + // is Sunday). + OccurrenceDaySet []*int64 `locationName:"occurrenceDaySet" locationNameList:"item" type:"list"` + + // Indicates whether the occurrence is relative to the end of the specified + // week or month. + OccurrenceRelativeToEnd *bool `locationName:"occurrenceRelativeToEnd" type:"boolean"` + + // The unit for occurrenceDaySet (DayOfWeek or DayOfMonth). + OccurrenceUnit *string `locationName:"occurrenceUnit" type:"string"` +} + +// String returns the string representation +func (s ScheduledInstanceRecurrence) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstanceRecurrence) GoString() string { + return s.String() +} + +// Describes the recurring schedule for a Scheduled Instance. +type ScheduledInstanceRecurrenceRequest struct { + _ struct{} `type:"structure"` + + // The frequency (Daily, Weekly, or Monthly). + Frequency *string `type:"string"` + + // The interval quantity. The interval unit depends on the value of Frequency. + // For example, every 2 weeks or every 2 months. + Interval *int64 `type:"integer"` + + // The days. For a monthly schedule, this is one or more days of the month (1-31). + // For a weekly schedule, this is one or more days of the week (1-7, where 1 + // is Sunday). You can't specify this value with a daily schedule. If the occurrence + // is relative to the end of the month, you can specify only a single day. + OccurrenceDays []*int64 `locationName:"OccurrenceDay" locationNameList:"OccurenceDay" type:"list"` + + // Indicates whether the occurrence is relative to the end of the specified + // week or month. You can't specify this value with a daily schedule. + OccurrenceRelativeToEnd *bool `type:"boolean"` + + // The unit for OccurrenceDays (DayOfWeek or DayOfMonth). This value is required + // for a monthly schedule. You can't specify DayOfWeek with a weekly schedule. + // You can't specify this value with a daily schedule. + OccurrenceUnit *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstanceRecurrenceRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstanceRecurrenceRequest) GoString() string { + return s.String() +} + +// Describes a block device mapping for a Scheduled Instance. +type ScheduledInstancesBlockDeviceMapping struct { + _ struct{} `type:"structure"` + + // The device name exposed to the instance (for example, /dev/sdh or xvdh). + DeviceName *string `type:"string"` + + // Parameters used to set up EBS volumes automatically when the instance is + // launched. + Ebs *ScheduledInstancesEbs `type:"structure"` + + // Suppresses the specified device included in the block device mapping of the + // AMI. + NoDevice *string `type:"string"` + + // The virtual device name (ephemeralN). Instance store volumes are numbered + // starting from 0. An instance type with two available instance store volumes + // can specify mappings for ephemeral0 and ephemeral1.The number of available + // instance store volumes depends on the instance type. After you connect to + // the instance, you must mount the volume. + // + // Constraints: For M3 instances, you must specify instance store volumes in + // the block device mapping for the instance. When you launch an M3 instance, + // we ignore any instance store volumes specified in the block device mapping + // for the AMI. + VirtualName *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesBlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesBlockDeviceMapping) GoString() string { + return s.String() +} + +// Describes an EBS volume for a Scheduled Instance. +type ScheduledInstancesEbs struct { + _ struct{} `type:"structure"` + + // Indicates whether the volume is deleted on instance termination. + DeleteOnTermination *bool `type:"boolean"` + + // Indicates whether the volume is encrypted. You can attached encrypted volumes + // only to instances that support them. + Encrypted *bool `type:"boolean"` + + // The number of I/O operations per second (IOPS) that the volume supports. + // For io1 volumes, this represents the number of IOPS that are provisioned + // for the volume. For gp2 volumes, this represents the baseline performance + // of the volume and the rate at which the volume accumulates I/O credits for + // bursting. For more information about gp2 baseline performance, I/O credits, + // and bursting, see Amazon EBS Volume Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // Constraint: Range is 100-20000 IOPS for io1 volumes and 100-10000 IOPS for + // gp2 volumes. + // + // Condition: This parameter is required for requests to create io1volumes; + // it is not used in requests to create gp2, st1, sc1, or standard volumes. + Iops *int64 `type:"integer"` + + // The ID of the snapshot. + SnapshotId *string `type:"string"` + + // The size of the volume, in GiB. + // + // Default: If you're creating the volume from a snapshot and don't specify + // a volume size, the default is the snapshot size. + VolumeSize *int64 `type:"integer"` + + // The volume type. gp2 for General Purpose SSD, io1 for Provisioned IOPS SSD, + // Throughput Optimized HDD for st1, Cold HDD for sc1, or standard for Magnetic. + // + // Default: standard + VolumeType *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesEbs) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesEbs) GoString() string { + return s.String() +} + +// Describes an IAM instance profile for a Scheduled Instance. +type ScheduledInstancesIamInstanceProfile struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN). + Arn *string `type:"string"` + + // The name. + Name *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesIamInstanceProfile) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesIamInstanceProfile) GoString() string { + return s.String() +} + +// Describes the launch specification for a Scheduled Instance. +// +// If you are launching the Scheduled Instance in EC2-VPC, you must specify +// the ID of the subnet. You can specify the subnet using either SubnetId or +// NetworkInterface. +type ScheduledInstancesLaunchSpecification struct { + _ struct{} `type:"structure"` + + // One or more block device mapping entries. + BlockDeviceMappings []*ScheduledInstancesBlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` + + // Indicates whether the instances are optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS-optimized + // instance. + // + // Default: false + EbsOptimized *bool `type:"boolean"` + + // The IAM instance profile. + IamInstanceProfile *ScheduledInstancesIamInstanceProfile `type:"structure"` + + // The ID of the Amazon Machine Image (AMI). + ImageId *string `type:"string" required:"true"` + + // The instance type. + InstanceType *string `type:"string"` + + // The ID of the kernel. + KernelId *string `type:"string"` + + // The name of the key pair. + KeyName *string `type:"string"` + + // Enable or disable monitoring for the instances. + Monitoring *ScheduledInstancesMonitoring `type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*ScheduledInstancesNetworkInterface `locationName:"NetworkInterface" locationNameList:"NetworkInterface" type:"list"` + + // The placement information. + Placement *ScheduledInstancesPlacement `type:"structure"` + + // The ID of the RAM disk. + RamdiskId *string `type:"string"` + + // The IDs of one or more security groups. + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // The ID of the subnet in which to launch the instances. + SubnetId *string `type:"string"` + + // The base64-encoded MIME user data. + UserData *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesLaunchSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ScheduledInstancesLaunchSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ScheduledInstancesLaunchSpecification"} + if s.ImageId == nil { + invalidParams.Add(request.NewErrParamRequired("ImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes whether monitoring is enabled for a Scheduled Instance. +type ScheduledInstancesMonitoring struct { + _ struct{} `type:"structure"` + + // Indicates whether monitoring is enabled. + Enabled *bool `type:"boolean"` +} + +// String returns the string representation +func (s ScheduledInstancesMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesMonitoring) GoString() string { + return s.String() +} + +// Describes a network interface for a Scheduled Instance. +type ScheduledInstancesNetworkInterface struct { + _ struct{} `type:"structure"` + + // Indicates whether to assign a public IP address to instances launched in + // a VPC. The public IP address can only be assigned to a network interface + // for eth0, and can only be assigned to a new network interface, not an existing + // one. You cannot specify more than one network interface in the request. If + // launching into a default subnet, the default value is true. + AssociatePublicIpAddress *bool `type:"boolean"` + + // Indicates whether to delete the interface when the instance is terminated. + DeleteOnTermination *bool `type:"boolean"` + + // The description. + Description *string `type:"string"` + + // The index of the device for the network interface attachment. + DeviceIndex *int64 `type:"integer"` + + // The IDs of one or more security groups. + Groups []*string `locationName:"Group" locationNameList:"SecurityGroupId" type:"list"` + + // The ID of the network interface. + NetworkInterfaceId *string `type:"string"` + + // The IP address of the network interface within the subnet. + PrivateIpAddress *string `type:"string"` + + // The private IP addresses. + PrivateIpAddressConfigs []*ScheduledInstancesPrivateIpAddressConfig `locationName:"PrivateIpAddressConfig" locationNameList:"PrivateIpAddressConfigSet" type:"list"` + + // The number of secondary private IP addresses. + SecondaryPrivateIpAddressCount *int64 `type:"integer"` + + // The ID of the subnet. + SubnetId *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesNetworkInterface) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesNetworkInterface) GoString() string { + return s.String() +} + +// Describes the placement for a Scheduled Instance. +type ScheduledInstancesPlacement struct { + _ struct{} `type:"structure"` + + // The Availability Zone. + AvailabilityZone *string `type:"string"` + + // The name of the placement group. + GroupName *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesPlacement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesPlacement) GoString() string { + return s.String() +} + +// Describes a private IP address for a Scheduled Instance. +type ScheduledInstancesPrivateIpAddressConfig struct { + _ struct{} `type:"structure"` + + // Indicates whether this is a primary IP address. Otherwise, this is a secondary + // IP address. + Primary *bool `type:"boolean"` + + // The IP address. + PrivateIpAddress *string `type:"string"` +} + +// String returns the string representation +func (s ScheduledInstancesPrivateIpAddressConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledInstancesPrivateIpAddressConfig) GoString() string { + return s.String() +} + +// Describes a security group +type SecurityGroup struct { + _ struct{} `type:"structure"` + + // A description of the security group. + Description *string `locationName:"groupDescription" type:"string"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string"` + + // The name of the security group. + GroupName *string `locationName:"groupName" type:"string"` + + // One or more inbound rules associated with the security group. + IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` + + // [EC2-VPC] One or more outbound rules associated with the security group. + IpPermissionsEgress []*IpPermission `locationName:"ipPermissionsEgress" locationNameList:"item" type:"list"` + + // The AWS account ID of the owner of the security group. + OwnerId *string `locationName:"ownerId" type:"string"` + + // Any tags assigned to the security group. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // [EC2-VPC] The ID of the VPC for the security group. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s SecurityGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SecurityGroup) GoString() string { + return s.String() +} + +// Describes a VPC with a security group that references your security group. +type SecurityGroupReference struct { + _ struct{} `type:"structure"` + + // The ID of your security group. + GroupId *string `locationName:"groupId" type:"string" required:"true"` + + // The ID of the VPC with the referencing security group. + ReferencingVpcId *string `locationName:"referencingVpcId" type:"string" required:"true"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s SecurityGroupReference) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SecurityGroupReference) GoString() string { + return s.String() +} + +// Describes the time period for a Scheduled Instance to start its first schedule. +// The time period must span less than one day. +type SlotDateTimeRangeRequest struct { + _ struct{} `type:"structure"` + + // The earliest date and time, in UTC, for the Scheduled Instance to start. + EarliestTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The latest date and time, in UTC, for the Scheduled Instance to start. This + // value must be later than or equal to the earliest date and at most three + // months in the future. + LatestTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` +} + +// String returns the string representation +func (s SlotDateTimeRangeRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SlotDateTimeRangeRequest) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SlotDateTimeRangeRequest) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SlotDateTimeRangeRequest"} + if s.EarliestTime == nil { + invalidParams.Add(request.NewErrParamRequired("EarliestTime")) + } + if s.LatestTime == nil { + invalidParams.Add(request.NewErrParamRequired("LatestTime")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes the time period for a Scheduled Instance to start its first schedule. +type SlotStartTimeRangeRequest struct { + _ struct{} `type:"structure"` + + // The earliest date and time, in UTC, for the Scheduled Instance to start. + EarliestTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The latest date and time, in UTC, for the Scheduled Instance to start. + LatestTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s SlotStartTimeRangeRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SlotStartTimeRangeRequest) GoString() string { + return s.String() +} + +// Describes a snapshot. +type Snapshot struct { + _ struct{} `type:"structure"` + + // The data encryption key identifier for the snapshot. This value is a unique + // identifier that corresponds to the data encryption key that was used to encrypt + // the original volume or snapshot copy. Because data encryption keys are inherited + // by volumes created from snapshots, and vice versa, if snapshots share the + // same data encryption key identifier, then they belong to the same volume/snapshot + // lineage. This parameter is only returned by the DescribeSnapshots API operation. + DataEncryptionKeyId *string `locationName:"dataEncryptionKeyId" type:"string"` + + // The description for the snapshot. + Description *string `locationName:"description" type:"string"` + + // Indicates whether the snapshot is encrypted. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The full ARN of the AWS Key Management Service (AWS KMS) customer master + // key (CMK) that was used to protect the volume encryption key for the parent + // volume. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` + + // Value from an Amazon-maintained list (amazon | aws-marketplace | microsoft) + // of snapshot owners. Not to be confused with the user-configured AWS account + // alias, which is set from the IAM console. + OwnerAlias *string `locationName:"ownerAlias" type:"string"` + + // The AWS account ID of the EBS snapshot owner. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The progress of the snapshot, as a percentage. + Progress *string `locationName:"progress" type:"string"` + + // The ID of the snapshot. Each snapshot receives a unique identifier when it + // is created. + SnapshotId *string `locationName:"snapshotId" type:"string"` + + // The time stamp when the snapshot was initiated. + StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` + + // The snapshot state. + State *string `locationName:"status" type:"string" enum:"SnapshotState"` + + // Encrypted Amazon EBS snapshots are copied asynchronously. If a snapshot copy + // operation fails (for example, if the proper AWS Key Management Service (AWS + // KMS) permissions are not obtained) this field displays error state details + // to help you diagnose why the error occurred. This parameter is only returned + // by the DescribeSnapshots API operation. + StateMessage *string `locationName:"statusMessage" type:"string"` + + // Any tags assigned to the snapshot. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the volume that was used to create the snapshot. Snapshots created + // by the CopySnapshot action have an arbitrary volume ID that should not be + // used for any purpose. + VolumeId *string `locationName:"volumeId" type:"string"` + + // The size of the volume, in GiB. + VolumeSize *int64 `locationName:"volumeSize" type:"integer"` +} + +// String returns the string representation +func (s Snapshot) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Snapshot) GoString() string { + return s.String() +} + +// Describes the snapshot created from the imported disk. +type SnapshotDetail struct { + _ struct{} `type:"structure"` + + // A description for the snapshot. + Description *string `locationName:"description" type:"string"` + + // The block device mapping for the snapshot. + DeviceName *string `locationName:"deviceName" type:"string"` + + // The size of the disk in the snapshot, in GiB. + DiskImageSize *float64 `locationName:"diskImageSize" type:"double"` + + // The format of the disk image from which the snapshot is created. + Format *string `locationName:"format" type:"string"` + + // The percentage of progress for the task. + Progress *string `locationName:"progress" type:"string"` + + // The snapshot ID of the disk being imported. + SnapshotId *string `locationName:"snapshotId" type:"string"` + + // A brief status of the snapshot creation. + Status *string `locationName:"status" type:"string"` + + // A detailed status message for the snapshot creation. + StatusMessage *string `locationName:"statusMessage" type:"string"` + + // The URL used to access the disk image. + Url *string `locationName:"url" type:"string"` + + // The S3 bucket for the disk image. + UserBucket *UserBucketDetails `locationName:"userBucket" type:"structure"` +} + +// String returns the string representation +func (s SnapshotDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SnapshotDetail) GoString() string { + return s.String() +} + +// The disk container object for the import snapshot request. +type SnapshotDiskContainer struct { + _ struct{} `type:"structure"` + + // The description of the disk image being imported. + Description *string `type:"string"` + + // The format of the disk image being imported. + // + // Valid values: RAW | VHD | VMDK | OVA + Format *string `type:"string"` + + // The URL to the Amazon S3-based disk image being imported. It can either be + // a https URL (https://..) or an Amazon S3 URL (s3://..). + Url *string `type:"string"` + + // The S3 bucket for the disk image. + UserBucket *UserBucket `type:"structure"` +} + +// String returns the string representation +func (s SnapshotDiskContainer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SnapshotDiskContainer) GoString() string { + return s.String() +} + +// Details about the import snapshot task. +type SnapshotTaskDetail struct { + _ struct{} `type:"structure"` + + // The description of the snapshot. + Description *string `locationName:"description" type:"string"` + + // The size of the disk in the snapshot, in GiB. + DiskImageSize *float64 `locationName:"diskImageSize" type:"double"` + + // The format of the disk image from which the snapshot is created. + Format *string `locationName:"format" type:"string"` + + // The percentage of completion for the import snapshot task. + Progress *string `locationName:"progress" type:"string"` + + // The snapshot ID of the disk being imported. + SnapshotId *string `locationName:"snapshotId" type:"string"` + + // A brief status for the import snapshot task. + Status *string `locationName:"status" type:"string"` + + // A detailed status message for the import snapshot task. + StatusMessage *string `locationName:"statusMessage" type:"string"` + + // The URL of the disk image from which the snapshot is created. + Url *string `locationName:"url" type:"string"` + + // The S3 bucket for the disk image. + UserBucket *UserBucketDetails `locationName:"userBucket" type:"structure"` +} + +// String returns the string representation +func (s SnapshotTaskDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SnapshotTaskDetail) GoString() string { + return s.String() +} + +// Describes the data feed for a Spot instance. +type SpotDatafeedSubscription struct { + _ struct{} `type:"structure"` + + // The Amazon S3 bucket where the Spot instance data feed is located. + Bucket *string `locationName:"bucket" type:"string"` + + // The fault codes for the Spot instance request, if any. + Fault *SpotInstanceStateFault `locationName:"fault" type:"structure"` + + // The AWS account ID of the account. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The prefix that is prepended to data feed files. + Prefix *string `locationName:"prefix" type:"string"` + + // The state of the Spot instance data feed subscription. + State *string `locationName:"state" type:"string" enum:"DatafeedSubscriptionState"` +} + +// String returns the string representation +func (s SpotDatafeedSubscription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotDatafeedSubscription) GoString() string { + return s.String() +} + +// Describes the launch specification for one or more Spot instances. +type SpotFleetLaunchSpecification struct { + _ struct{} `type:"structure"` + + // Deprecated. + AddressingType *string `locationName:"addressingType" type:"string"` + + // One or more block device mapping entries. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // Indicates whether the instances are optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS + // Optimized instance. + // + // Default: false + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // The IAM instance profile. + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI. + ImageId *string `locationName:"imageId" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The ID of the kernel. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` + + // Enable or disable monitoring for the instances. + Monitoring *SpotFleetMonitoring `locationName:"monitoring" type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*InstanceNetworkInterfaceSpecification `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` + + // The placement information. + Placement *SpotPlacement `locationName:"placement" type:"structure"` + + // The ID of the RAM disk. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + // One or more security groups. When requesting instances in a VPC, you must + // specify the IDs of the security groups. When requesting instances in EC2-Classic, + // you can specify the names or the IDs of the security groups. + SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The bid price per unit hour for the specified instance type. If this value + // is not specified, the default is the Spot bid price specified for the fleet. + // To determine the bid price per unit hour, divide the Spot bid price by the + // value of WeightedCapacity. + SpotPrice *string `locationName:"spotPrice" type:"string"` + + // The ID of the subnet in which to launch the instances. To specify multiple + // subnets, separate them using commas; for example, "subnet-a61dafcf, subnet-65ea5f08". + SubnetId *string `locationName:"subnetId" type:"string"` + + // The user data to make available to the instances. If you are using an AWS + // SDK or command line tool, Base64-encoding is performed for you, and you can + // load the text from a file. Otherwise, you must provide Base64-encoded text. + UserData *string `locationName:"userData" type:"string"` + + // The number of units provided by the specified instance type. These are the + // same units that you chose to set the target capacity in terms (instances + // or a performance characteristic such as vCPUs, memory, or I/O). + // + // If the target capacity divided by this value is not a whole number, we round + // the number of instances to the next whole number. If this value is not specified, + // the default is 1. + WeightedCapacity *float64 `locationName:"weightedCapacity" type:"double"` +} + +// String returns the string representation +func (s SpotFleetLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetLaunchSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SpotFleetLaunchSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SpotFleetLaunchSpecification"} + if s.NetworkInterfaces != nil { + for i, v := range s.NetworkInterfaces { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "NetworkInterfaces", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes whether monitoring is enabled. +type SpotFleetMonitoring struct { + _ struct{} `type:"structure"` + + // Enables monitoring for the instance. + // + // Default: false + Enabled *bool `locationName:"enabled" type:"boolean"` +} + +// String returns the string representation +func (s SpotFleetMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetMonitoring) GoString() string { + return s.String() +} + +// Describes a Spot fleet request. +type SpotFleetRequestConfig struct { + _ struct{} `type:"structure"` + + // The progress of the Spot fleet request. If there is an error, the status + // is error. After all bids are placed, the status is pending_fulfillment. If + // the size of the fleet is equal to or greater than its target capacity, the + // status is fulfilled. If the size of the fleet is decreased, the status is + // pending_termination while Spot instances are terminating. + ActivityStatus *string `locationName:"activityStatus" type:"string" enum:"ActivityStatus"` + + // The creation date and time of the request. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // Information about the configuration of the Spot fleet request. + SpotFleetRequestConfig *SpotFleetRequestConfigData `locationName:"spotFleetRequestConfig" type:"structure" required:"true"` + + // The ID of the Spot fleet request. + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + + // The state of the Spot fleet request. + SpotFleetRequestState *string `locationName:"spotFleetRequestState" type:"string" required:"true" enum:"BatchState"` +} + +// String returns the string representation +func (s SpotFleetRequestConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetRequestConfig) GoString() string { + return s.String() +} + +// Describes the configuration of a Spot fleet request. +type SpotFleetRequestConfigData struct { + _ struct{} `type:"structure"` + + // Indicates how to allocate the target capacity across the Spot pools specified + // by the Spot fleet request. The default is lowestPrice. + AllocationStrategy *string `locationName:"allocationStrategy" type:"string" enum:"AllocationStrategy"` + + // A unique, case-sensitive identifier you provide to ensure idempotency of + // your listings. This helps avoid duplicate listings. For more information, + // see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `locationName:"clientToken" type:"string"` + + // Indicates whether running Spot instances should be terminated if the target + // capacity of the Spot fleet request is decreased below the current size of + // the Spot fleet. + ExcessCapacityTerminationPolicy *string `locationName:"excessCapacityTerminationPolicy" type:"string" enum:"ExcessCapacityTerminationPolicy"` + + // The number of units fulfilled by this request compared to the set target + // capacity. + FulfilledCapacity *float64 `locationName:"fulfilledCapacity" type:"double"` + + // Grants the Spot fleet permission to terminate Spot instances on your behalf + // when you cancel its Spot fleet request using CancelSpotFleetRequests or when + // the Spot fleet request expires, if you set terminateInstancesWithExpiration. + IamFleetRole *string `locationName:"iamFleetRole" type:"string" required:"true"` + + // Information about the launch specifications for the Spot fleet request. + LaunchSpecifications []*SpotFleetLaunchSpecification `locationName:"launchSpecifications" locationNameList:"item" min:"1" type:"list" required:"true"` + + // The bid price per unit hour. + SpotPrice *string `locationName:"spotPrice" type:"string" required:"true"` + + // The number of units to request. You can choose to set the target capacity + // in terms of instances or a performance characteristic that is important to + // your application workload, such as vCPUs, memory, or I/O. + TargetCapacity *int64 `locationName:"targetCapacity" type:"integer" required:"true"` + + // Indicates whether running Spot instances should be terminated when the Spot + // fleet request expires. + TerminateInstancesWithExpiration *bool `locationName:"terminateInstancesWithExpiration" type:"boolean"` + + // The type of request. Indicates whether the fleet will only request the target + // capacity or also attempt to maintain it. When you request a certain target + // capacity, the fleet will only place the required bids. It will not attempt + // to replenish Spot instances if capacity is diminished, nor will it submit + // bids in alternative Spot pools if capacity is not available. When you want + // to maintain a certain target capacity, fleet will place the required bids + // to meet this target capacity. It will also automatically replenish any interrupted + // instances. Default: maintain. + Type *string `locationName:"type" type:"string" enum:"FleetType"` + + // The start date and time of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + // The default is to start fulfilling the request immediately. + ValidFrom *time.Time `locationName:"validFrom" type:"timestamp" timestampFormat:"iso8601"` + + // The end date and time of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + // At this point, no new Spot instance requests are placed or enabled to fulfill + // the request. + ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s SpotFleetRequestConfigData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetRequestConfigData) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SpotFleetRequestConfigData) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SpotFleetRequestConfigData"} + if s.IamFleetRole == nil { + invalidParams.Add(request.NewErrParamRequired("IamFleetRole")) + } + if s.LaunchSpecifications == nil { + invalidParams.Add(request.NewErrParamRequired("LaunchSpecifications")) + } + if s.LaunchSpecifications != nil && len(s.LaunchSpecifications) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LaunchSpecifications", 1)) + } + if s.SpotPrice == nil { + invalidParams.Add(request.NewErrParamRequired("SpotPrice")) + } + if s.TargetCapacity == nil { + invalidParams.Add(request.NewErrParamRequired("TargetCapacity")) + } + if s.LaunchSpecifications != nil { + for i, v := range s.LaunchSpecifications { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LaunchSpecifications", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a Spot instance request. +type SpotInstanceRequest struct { + _ struct{} `type:"structure"` + + // If you specified a duration and your Spot instance request was fulfilled, + // this is the fixed hourly price in effect for the Spot instance while it runs. + ActualBlockHourlyPrice *string `locationName:"actualBlockHourlyPrice" type:"string"` + + // The Availability Zone group. If you specify the same Availability Zone group + // for all Spot instance requests, all Spot instances are launched in the same + // Availability Zone. + AvailabilityZoneGroup *string `locationName:"availabilityZoneGroup" type:"string"` + + // The duration for the Spot instance, in minutes. + BlockDurationMinutes *int64 `locationName:"blockDurationMinutes" type:"integer"` + + // The date and time when the Spot instance request was created, in UTC format + // (for example, YYYY-MM-DDTHH:MM:SSZ). + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` + + // The fault codes for the Spot instance request, if any. + Fault *SpotInstanceStateFault `locationName:"fault" type:"structure"` + + // The instance ID, if an instance has been launched to fulfill the Spot instance + // request. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The instance launch group. Launch groups are Spot instances that launch together + // and terminate together. + LaunchGroup *string `locationName:"launchGroup" type:"string"` + + // Additional information for launching instances. + LaunchSpecification *LaunchSpecification `locationName:"launchSpecification" type:"structure"` + + // The Availability Zone in which the bid is launched. + LaunchedAvailabilityZone *string `locationName:"launchedAvailabilityZone" type:"string"` + + // The product description associated with the Spot instance. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` + + // The ID of the Spot instance request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` + + // The maximum hourly price (bid) for the Spot instance launched to fulfill + // the request. + SpotPrice *string `locationName:"spotPrice" type:"string"` + + // The state of the Spot instance request. Spot bid status information can help + // you track your Spot instance requests. For more information, see Spot Bid + // Status (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) + // in the Amazon Elastic Compute Cloud User Guide. + State *string `locationName:"state" type:"string" enum:"SpotInstanceState"` + + // The status code and status message describing the Spot instance request. + Status *SpotInstanceStatus `locationName:"status" type:"structure"` + + // Any tags assigned to the resource. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The Spot instance request type. + Type *string `locationName:"type" type:"string" enum:"SpotInstanceType"` + + // The start date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + // The request becomes active at this date and time. + ValidFrom *time.Time `locationName:"validFrom" type:"timestamp" timestampFormat:"iso8601"` + + // The end date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + // If this is a one-time request, it remains active until all instances launch, + // the request is canceled, or this date is reached. If the request is persistent, + // it remains active until it is canceled or this date is reached. + ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s SpotInstanceRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotInstanceRequest) GoString() string { + return s.String() +} + +// Describes a Spot instance state change. +type SpotInstanceStateFault struct { + _ struct{} `type:"structure"` + + // The reason code for the Spot instance state change. + Code *string `locationName:"code" type:"string"` + + // The message for the Spot instance state change. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s SpotInstanceStateFault) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotInstanceStateFault) GoString() string { + return s.String() +} + +// Describes the status of a Spot instance request. +type SpotInstanceStatus struct { + _ struct{} `type:"structure"` + + // The status code. For a list of status codes, see Spot Bid Status Codes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html#spot-instance-bid-status-understand) + // in the Amazon Elastic Compute Cloud User Guide. + Code *string `locationName:"code" type:"string"` + + // The description for the status code. + Message *string `locationName:"message" type:"string"` + + // The date and time of the most recent status update, in UTC format (for example, + // YYYY-MM-DDTHH:MM:SSZ). + UpdateTime *time.Time `locationName:"updateTime" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s SpotInstanceStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotInstanceStatus) GoString() string { + return s.String() +} + +// Describes Spot instance placement. +type SpotPlacement struct { + _ struct{} `type:"structure"` + + // The Availability Zone. + // + // [Spot fleet only] To specify multiple Availability Zones, separate them + // using commas; for example, "us-west-2a, us-west-2b". + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The name of the placement group (for cluster instances). + GroupName *string `locationName:"groupName" type:"string"` +} + +// String returns the string representation +func (s SpotPlacement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotPlacement) GoString() string { + return s.String() +} + +// Describes the maximum hourly price (bid) for any Spot instance launched to +// fulfill the request. +type SpotPrice struct { + _ struct{} `type:"structure"` + + // The Availability Zone. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // A general description of the AMI. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` + + // The maximum price (bid) that you are willing to pay for a Spot instance. + SpotPrice *string `locationName:"spotPrice" type:"string"` + + // The date and time the request was created, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). + Timestamp *time.Time `locationName:"timestamp" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s SpotPrice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotPrice) GoString() string { + return s.String() +} + +// Describes a stale rule in a security group. +type StaleIpPermission struct { + _ struct{} `type:"structure"` + + // The start of the port range for the TCP and UDP protocols, or an ICMP type + // number. A value of -1 indicates all ICMP types. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The IP protocol name (for tcp, udp, and icmp) or number (see Protocol Numbers) + // (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). + IpProtocol *string `locationName:"ipProtocol" type:"string"` + + // One or more IP ranges. Not applicable for stale security group rules. + IpRanges []*string `locationName:"ipRanges" locationNameList:"item" type:"list"` + + // One or more prefix list IDs for an AWS service. Not applicable for stale + // security group rules. + PrefixListIds []*string `locationName:"prefixListIds" locationNameList:"item" type:"list"` + + // The end of the port range for the TCP and UDP protocols, or an ICMP type + // number. A value of -1 indicates all ICMP types. + ToPort *int64 `locationName:"toPort" type:"integer"` + + // One or more security group pairs. Returns the ID of the referenced security + // group and VPC, and the ID and status of the VPC peering connection. + UserIdGroupPairs []*UserIdGroupPair `locationName:"groups" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s StaleIpPermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StaleIpPermission) GoString() string { + return s.String() +} + +// Describes a stale security group (a security group that contains stale rules). +type StaleSecurityGroup struct { + _ struct{} `type:"structure"` + + // The description of the security group. + Description *string `locationName:"description" type:"string"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string" required:"true"` + + // The name of the security group. + GroupName *string `locationName:"groupName" type:"string"` + + // Information about the stale inbound rules in the security group. + StaleIpPermissions []*StaleIpPermission `locationName:"staleIpPermissions" locationNameList:"item" type:"list"` + + // Information about the stale outbound rules in the security group. + StaleIpPermissionsEgress []*StaleIpPermission `locationName:"staleIpPermissionsEgress" locationNameList:"item" type:"list"` + + // The ID of the VPC for the security group. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s StaleSecurityGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StaleSecurityGroup) GoString() string { + return s.String() +} + +// Contains the parameters for StartInstances. +type StartInstancesInput struct { + _ struct{} `type:"structure"` + + // Reserved. + AdditionalInfo *string `locationName:"additionalInfo" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` +} + +// String returns the string representation +func (s StartInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StartInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StartInstancesInput"} + if s.InstanceIds == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of StartInstances. +type StartInstancesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more started instances. + StartingInstances []*InstanceStateChange `locationName:"instancesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s StartInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartInstancesOutput) GoString() string { + return s.String() +} + +// Describes a state change. +type StateReason struct { + _ struct{} `type:"structure"` + + // The reason code for the state change. + Code *string `locationName:"code" type:"string"` + + // The message for the state change. + // + // Server.SpotInstanceTermination: A Spot instance was terminated due to + // an increase in the market price. + // + // Server.InternalError: An internal error occurred during instance launch, + // resulting in termination. + // + // Server.InsufficientInstanceCapacity: There was insufficient instance + // capacity to satisfy the launch request. + // + // Client.InternalError: A client error caused the instance to terminate + // on launch. + // + // Client.InstanceInitiatedShutdown: The instance was shut down using the + // shutdown -h command from the instance. + // + // Client.UserInitiatedShutdown: The instance was shut down using the Amazon + // EC2 API. + // + // Client.VolumeLimitExceeded: The limit on the number of EBS volumes or + // total storage was exceeded. Decrease usage or request an increase in your + // limits. + // + // Client.InvalidSnapshot.NotFound: The specified snapshot was not found. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s StateReason) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StateReason) GoString() string { + return s.String() +} + +// Contains the parameters for StopInstances. +type StopInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Forces the instances to stop. The instances do not have an opportunity to + // flush file system caches or file system metadata. If you use this option, + // you must perform file system check and repair procedures. This option is + // not recommended for Windows instances. + // + // Default: false + Force *bool `locationName:"force" type:"boolean"` + + // One or more instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` +} + +// String returns the string representation +func (s StopInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StopInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StopInstancesInput"} + if s.InstanceIds == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of StopInstances. +type StopInstancesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more stopped instances. + StoppingInstances []*InstanceStateChange `locationName:"instancesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s StopInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopInstancesOutput) GoString() string { + return s.String() +} + +// Describes the storage location for an instance store-backed AMI. +type Storage struct { + _ struct{} `type:"structure"` + + // An Amazon S3 storage location. + S3 *S3Storage `type:"structure"` +} + +// String returns the string representation +func (s Storage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Storage) GoString() string { + return s.String() +} + +// Describes a subnet. +type Subnet struct { + _ struct{} `type:"structure"` + + // The Availability Zone of the subnet. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The number of unused IP addresses in the subnet. Note that the IP addresses + // for any stopped instances are considered unavailable. + AvailableIpAddressCount *int64 `locationName:"availableIpAddressCount" type:"integer"` + + // The CIDR block assigned to the subnet. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // Indicates whether this is the default subnet for the Availability Zone. + DefaultForAz *bool `locationName:"defaultForAz" type:"boolean"` + + // Indicates whether instances launched in this subnet receive a public IP address. + MapPublicIpOnLaunch *bool `locationName:"mapPublicIpOnLaunch" type:"boolean"` + + // The current state of the subnet. + State *string `locationName:"state" type:"string" enum:"SubnetState"` + + // The ID of the subnet. + SubnetId *string `locationName:"subnetId" type:"string"` + + // Any tags assigned to the subnet. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC the subnet is in. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s Subnet) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Subnet) GoString() string { + return s.String() +} + +// Describes a tag. +type Tag struct { + _ struct{} `type:"structure"` + + // The key of the tag. + // + // Constraints: Tag keys are case-sensitive and accept a maximum of 127 Unicode + // characters. May not begin with aws: + Key *string `locationName:"key" type:"string"` + + // The value of the tag. + // + // Constraints: Tag values are case-sensitive and accept a maximum of 255 Unicode + // characters. + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + +// Describes a tag. +type TagDescription struct { + _ struct{} `type:"structure"` + + // The tag key. + Key *string `locationName:"key" type:"string"` + + // The ID of the resource. For example, ami-1a2b3c4d. + ResourceId *string `locationName:"resourceId" type:"string"` + + // The resource type. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The tag value. + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s TagDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagDescription) GoString() string { + return s.String() +} + +// Contains the parameters for TerminateInstances. +type TerminateInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` +} + +// String returns the string representation +func (s TerminateInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TerminateInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TerminateInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TerminateInstancesInput"} + if s.InstanceIds == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of TerminateInstances. +type TerminateInstancesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more terminated instances. + TerminatingInstances []*InstanceStateChange `locationName:"instancesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s TerminateInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TerminateInstancesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for UnassignPrivateIpAddresses. +type UnassignPrivateIpAddressesInput struct { + _ struct{} `type:"structure"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` + + // The secondary private IP addresses to unassign from the network interface. + // You can specify this option multiple times to unassign more than one IP address. + PrivateIpAddresses []*string `locationName:"privateIpAddress" locationNameList:"PrivateIpAddress" type:"list" required:"true"` +} + +// String returns the string representation +func (s UnassignPrivateIpAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnassignPrivateIpAddressesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UnassignPrivateIpAddressesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UnassignPrivateIpAddressesInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + if s.PrivateIpAddresses == nil { + invalidParams.Add(request.NewErrParamRequired("PrivateIpAddresses")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type UnassignPrivateIpAddressesOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s UnassignPrivateIpAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnassignPrivateIpAddressesOutput) GoString() string { + return s.String() +} + +// Contains the parameters for UnmonitorInstances. +type UnmonitorInstancesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // One or more instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` +} + +// String returns the string representation +func (s UnmonitorInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnmonitorInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UnmonitorInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UnmonitorInstancesInput"} + if s.InstanceIds == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the output of UnmonitorInstances. +type UnmonitorInstancesOutput struct { + _ struct{} `type:"structure"` + + // Monitoring information for one or more instances. + InstanceMonitorings []*InstanceMonitoring `locationName:"instancesSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s UnmonitorInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnmonitorInstancesOutput) GoString() string { + return s.String() +} + +// Information about items that were not successfully processed in a batch call. +type UnsuccessfulItem struct { + _ struct{} `type:"structure"` + + // Information about the error. + Error *UnsuccessfulItemError `locationName:"error" type:"structure" required:"true"` + + // The ID of the resource. + ResourceId *string `locationName:"resourceId" type:"string"` +} + +// String returns the string representation +func (s UnsuccessfulItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnsuccessfulItem) GoString() string { + return s.String() +} + +// Information about the error that occurred. For more information about errors, +// see Error Codes (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html). +type UnsuccessfulItemError struct { + _ struct{} `type:"structure"` + + // The error code. + Code *string `locationName:"code" type:"string" required:"true"` + + // The error message accompanying the error code. + Message *string `locationName:"message" type:"string" required:"true"` +} + +// String returns the string representation +func (s UnsuccessfulItemError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnsuccessfulItemError) GoString() string { + return s.String() +} + +// Describes the S3 bucket for the disk image. +type UserBucket struct { + _ struct{} `type:"structure"` + + // The name of the S3 bucket where the disk image is located. + S3Bucket *string `type:"string"` + + // The file name of the disk image. + S3Key *string `type:"string"` +} + +// String returns the string representation +func (s UserBucket) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserBucket) GoString() string { + return s.String() +} + +// Describes the S3 bucket for the disk image. +type UserBucketDetails struct { + _ struct{} `type:"structure"` + + // The S3 bucket from which the disk image was created. + S3Bucket *string `locationName:"s3Bucket" type:"string"` + + // The file name of the disk image. + S3Key *string `locationName:"s3Key" type:"string"` +} + +// String returns the string representation +func (s UserBucketDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserBucketDetails) GoString() string { + return s.String() +} + +// Describes the user data for an instance. +type UserData struct { + _ struct{} `type:"structure"` + + // The user data. If you are using an AWS SDK or command line tool, Base64-encoding + // is performed for you, and you can load the text from a file. Otherwise, you + // must provide Base64-encoded text. + Data *string `locationName:"data" type:"string"` +} + +// String returns the string representation +func (s UserData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserData) GoString() string { + return s.String() +} + +// Describes a security group and AWS account ID pair. +type UserIdGroupPair struct { + _ struct{} `type:"structure"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string"` + + // The name of the security group. In a request, use this parameter for a security + // group in EC2-Classic or a default VPC only. For a security group in a nondefault + // VPC, use the security group ID. + GroupName *string `locationName:"groupName" type:"string"` + + // The status of a VPC peering connection, if applicable. + PeeringStatus *string `locationName:"peeringStatus" type:"string"` + + // The ID of an AWS account. For a referenced security group in another VPC, + // the account ID of the referenced security group is returned. + // + // [EC2-Classic] Required when adding or removing rules that reference a security + // group in another AWS account. + UserId *string `locationName:"userId" type:"string"` + + // The ID of the VPC for the referenced security group, if applicable. + VpcId *string `locationName:"vpcId" type:"string"` + + // The ID of the VPC peering connection, if applicable. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s UserIdGroupPair) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserIdGroupPair) GoString() string { + return s.String() +} + +// Describes telemetry for a VPN tunnel. +type VgwTelemetry struct { + _ struct{} `type:"structure"` + + // The number of accepted routes. + AcceptedRouteCount *int64 `locationName:"acceptedRouteCount" type:"integer"` + + // The date and time of the last change in status. + LastStatusChange *time.Time `locationName:"lastStatusChange" type:"timestamp" timestampFormat:"iso8601"` + + // The Internet-routable IP address of the virtual private gateway's outside + // interface. + OutsideIpAddress *string `locationName:"outsideIpAddress" type:"string"` + + // The status of the VPN tunnel. + Status *string `locationName:"status" type:"string" enum:"TelemetryStatus"` + + // If an error occurs, a description of the error. + StatusMessage *string `locationName:"statusMessage" type:"string"` +} + +// String returns the string representation +func (s VgwTelemetry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VgwTelemetry) GoString() string { + return s.String() +} + +// Describes a volume. +type Volume struct { + _ struct{} `type:"structure"` + + // Information about the volume attachments. + Attachments []*VolumeAttachment `locationName:"attachmentSet" locationNameList:"item" type:"list"` + + // The Availability Zone for the volume. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The time stamp when volume creation was initiated. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` + + // Indicates whether the volume will be encrypted. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The number of I/O operations per second (IOPS) that the volume supports. + // For Provisioned IOPS SSD volumes, this represents the number of IOPS that + // are provisioned for the volume. For General Purpose SSD volumes, this represents + // the baseline performance of the volume and the rate at which the volume accumulates + // I/O credits for bursting. For more information on General Purpose SSD baseline + // performance, I/O credits, and bursting, see Amazon EBS Volume Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // Constraint: Range is 100-20000 IOPS for io1 volumes and 100-10000 IOPS for + // gp2 volumes. + // + // Condition: This parameter is required for requests to create io1 volumes; + // it is not used in requests to create gp2, st1, sc1, or standard volumes. + Iops *int64 `locationName:"iops" type:"integer"` + + // The full ARN of the AWS Key Management Service (AWS KMS) customer master + // key (CMK) that was used to protect the volume encryption key for the volume. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` + + // The size of the volume, in GiBs. + Size *int64 `locationName:"size" type:"integer"` + + // The snapshot from which the volume was created, if applicable. + SnapshotId *string `locationName:"snapshotId" type:"string"` + + // The volume state. + State *string `locationName:"status" type:"string" enum:"VolumeState"` + + // Any tags assigned to the volume. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string"` + + // The volume type. This can be gp2 for General Purpose SSD, io1 for Provisioned + // IOPS SSD, st1 for Throughput Optimized HDD, sc1 for Cold HDD, or standard + // for Magnetic volumes. + VolumeType *string `locationName:"volumeType" type:"string" enum:"VolumeType"` +} + +// String returns the string representation +func (s Volume) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Volume) GoString() string { + return s.String() +} + +// Describes volume attachment details. +type VolumeAttachment struct { + _ struct{} `type:"structure"` + + // The time stamp when the attachment initiated. + AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` + + // Indicates whether the EBS volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // The device name. + Device *string `locationName:"device" type:"string"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` + + // The attachment state of the volume. + State *string `locationName:"status" type:"string" enum:"VolumeAttachmentState"` + + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string"` +} + +// String returns the string representation +func (s VolumeAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeAttachment) GoString() string { + return s.String() +} + +// Describes an EBS volume. +type VolumeDetail struct { + _ struct{} `type:"structure"` + + // The size of the volume, in GiB. + Size *int64 `locationName:"size" type:"long" required:"true"` +} + +// String returns the string representation +func (s VolumeDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeDetail) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *VolumeDetail) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "VolumeDetail"} + if s.Size == nil { + invalidParams.Add(request.NewErrParamRequired("Size")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Describes a volume status operation code. +type VolumeStatusAction struct { + _ struct{} `type:"structure"` + + // The code identifying the operation, for example, enable-volume-io. + Code *string `locationName:"code" type:"string"` + + // A description of the operation. + Description *string `locationName:"description" type:"string"` + + // The ID of the event associated with this operation. + EventId *string `locationName:"eventId" type:"string"` + + // The event type associated with this operation. + EventType *string `locationName:"eventType" type:"string"` +} + +// String returns the string representation +func (s VolumeStatusAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusAction) GoString() string { + return s.String() +} + +// Describes a volume status. +type VolumeStatusDetails struct { + _ struct{} `type:"structure"` + + // The name of the volume status. + Name *string `locationName:"name" type:"string" enum:"VolumeStatusName"` + + // The intended status of the volume status. + Status *string `locationName:"status" type:"string"` +} + +// String returns the string representation +func (s VolumeStatusDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusDetails) GoString() string { + return s.String() +} + +// Describes a volume status event. +type VolumeStatusEvent struct { + _ struct{} `type:"structure"` + + // A description of the event. + Description *string `locationName:"description" type:"string"` + + // The ID of this event. + EventId *string `locationName:"eventId" type:"string"` + + // The type of this event. + EventType *string `locationName:"eventType" type:"string"` + + // The latest end time of the event. + NotAfter *time.Time `locationName:"notAfter" type:"timestamp" timestampFormat:"iso8601"` + + // The earliest start time of the event. + NotBefore *time.Time `locationName:"notBefore" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s VolumeStatusEvent) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusEvent) GoString() string { + return s.String() +} + +// Describes the status of a volume. +type VolumeStatusInfo struct { + _ struct{} `type:"structure"` + + // The details of the volume status. + Details []*VolumeStatusDetails `locationName:"details" locationNameList:"item" type:"list"` + + // The status of the volume. + Status *string `locationName:"status" type:"string" enum:"VolumeStatusInfoStatus"` +} + +// String returns the string representation +func (s VolumeStatusInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusInfo) GoString() string { + return s.String() +} + +// Describes the volume status. +type VolumeStatusItem struct { + _ struct{} `type:"structure"` + + // The details of the operation. + Actions []*VolumeStatusAction `locationName:"actionsSet" locationNameList:"item" type:"list"` + + // The Availability Zone of the volume. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // A list of events associated with the volume. + Events []*VolumeStatusEvent `locationName:"eventsSet" locationNameList:"item" type:"list"` + + // The volume ID. + VolumeId *string `locationName:"volumeId" type:"string"` + + // The volume status. + VolumeStatus *VolumeStatusInfo `locationName:"volumeStatus" type:"structure"` +} + +// String returns the string representation +func (s VolumeStatusItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusItem) GoString() string { + return s.String() +} + +// Describes a VPC. +type Vpc struct { + _ struct{} `type:"structure"` + + // The CIDR block for the VPC. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // The ID of the set of DHCP options you've associated with the VPC (or default + // if the default options are associated with the VPC). + DhcpOptionsId *string `locationName:"dhcpOptionsId" type:"string"` + + // The allowed tenancy of instances launched into the VPC. + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` + + // Indicates whether the VPC is the default VPC. + IsDefault *bool `locationName:"isDefault" type:"boolean"` + + // The current state of the VPC. + State *string `locationName:"state" type:"string" enum:"VpcState"` + + // Any tags assigned to the VPC. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s Vpc) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Vpc) GoString() string { + return s.String() +} + +// Describes an attachment between a virtual private gateway and a VPC. +type VpcAttachment struct { + _ struct{} `type:"structure"` + + // The current state of the attachment. + State *string `locationName:"state" type:"string" enum:"AttachmentStatus"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s VpcAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcAttachment) GoString() string { + return s.String() +} + +// Describes whether a VPC is enabled for ClassicLink. +type VpcClassicLink struct { + _ struct{} `type:"structure"` + + // Indicates whether the VPC is enabled for ClassicLink. + ClassicLinkEnabled *bool `locationName:"classicLinkEnabled" type:"boolean"` + + // Any tags assigned to the VPC. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s VpcClassicLink) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcClassicLink) GoString() string { + return s.String() +} + +// Describes a VPC endpoint. +type VpcEndpoint struct { + _ struct{} `type:"structure"` + + // The date and time the VPC endpoint was created. + CreationTimestamp *time.Time `locationName:"creationTimestamp" type:"timestamp" timestampFormat:"iso8601"` + + // The policy document associated with the endpoint. + PolicyDocument *string `locationName:"policyDocument" type:"string"` + + // One or more route tables associated with the endpoint. + RouteTableIds []*string `locationName:"routeTableIdSet" locationNameList:"item" type:"list"` + + // The name of the AWS service to which the endpoint is associated. + ServiceName *string `locationName:"serviceName" type:"string"` + + // The state of the VPC endpoint. + State *string `locationName:"state" type:"string" enum:"State"` + + // The ID of the VPC endpoint. + VpcEndpointId *string `locationName:"vpcEndpointId" type:"string"` + + // The ID of the VPC to which the endpoint is associated. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s VpcEndpoint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcEndpoint) GoString() string { + return s.String() +} + +// Describes a VPC peering connection. +type VpcPeeringConnection struct { + _ struct{} `type:"structure"` + + // Information about the accepter VPC. CIDR block information is not returned + // when creating a VPC peering connection, or when describing a VPC peering + // connection that's in the initiating-request or pending-acceptance state. + AccepterVpcInfo *VpcPeeringConnectionVpcInfo `locationName:"accepterVpcInfo" type:"structure"` + + // The time that an unaccepted VPC peering connection will expire. + ExpirationTime *time.Time `locationName:"expirationTime" type:"timestamp" timestampFormat:"iso8601"` + + // Information about the requester VPC. + RequesterVpcInfo *VpcPeeringConnectionVpcInfo `locationName:"requesterVpcInfo" type:"structure"` + + // The status of the VPC peering connection. + Status *VpcPeeringConnectionStateReason `locationName:"status" type:"structure"` + + // Any tags assigned to the resource. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` +} + +// String returns the string representation +func (s VpcPeeringConnection) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnection) GoString() string { + return s.String() +} + +// Describes the VPC peering connection options. +type VpcPeeringConnectionOptionsDescription struct { + _ struct{} `type:"structure"` + + // Indicates whether a local VPC can resolve public DNS hostnames to private + // IP addresses when queried from instances in a peer VPC. + AllowDnsResolutionFromRemoteVpc *bool `locationName:"allowDnsResolutionFromRemoteVpc" type:"boolean"` + + // Indicates whether a local ClassicLink connection can communicate with the + // peer VPC over the VPC peering connection. + AllowEgressFromLocalClassicLinkToRemoteVpc *bool `locationName:"allowEgressFromLocalClassicLinkToRemoteVpc" type:"boolean"` + + // Indicates whether a local VPC can communicate with a ClassicLink connection + // in the peer VPC over the VPC peering connection. + AllowEgressFromLocalVpcToRemoteClassicLink *bool `locationName:"allowEgressFromLocalVpcToRemoteClassicLink" type:"boolean"` +} + +// String returns the string representation +func (s VpcPeeringConnectionOptionsDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnectionOptionsDescription) GoString() string { + return s.String() +} + +// Describes the status of a VPC peering connection. +type VpcPeeringConnectionStateReason struct { + _ struct{} `type:"structure"` + + // The status of the VPC peering connection. + Code *string `locationName:"code" type:"string" enum:"VpcPeeringConnectionStateReasonCode"` + + // A message that provides more information about the status, if applicable. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s VpcPeeringConnectionStateReason) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnectionStateReason) GoString() string { + return s.String() +} + +// Describes a VPC in a VPC peering connection. +type VpcPeeringConnectionVpcInfo struct { + _ struct{} `type:"structure"` + + // The CIDR block for the VPC. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // The AWS account ID of the VPC owner. + OwnerId *string `locationName:"ownerId" type:"string"` + + // Information about the VPC peering connection options for the accepter or + // requester VPC. + PeeringOptions *VpcPeeringConnectionOptionsDescription `locationName:"peeringOptions" type:"structure"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` +} + +// String returns the string representation +func (s VpcPeeringConnectionVpcInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnectionVpcInfo) GoString() string { + return s.String() +} + +// Describes a VPN connection. +type VpnConnection struct { + _ struct{} `type:"structure"` + + // The configuration information for the VPN connection's customer gateway (in + // the native XML format). This element is always present in the CreateVpnConnection + // response; however, it's present in the DescribeVpnConnections response only + // if the VPN connection is in the pending or available state. + CustomerGatewayConfiguration *string `locationName:"customerGatewayConfiguration" type:"string"` + + // The ID of the customer gateway at your end of the VPN connection. + CustomerGatewayId *string `locationName:"customerGatewayId" type:"string"` + + // The VPN connection options. + Options *VpnConnectionOptions `locationName:"options" type:"structure"` + + // The static routes associated with the VPN connection. + Routes []*VpnStaticRoute `locationName:"routes" locationNameList:"item" type:"list"` + + // The current state of the VPN connection. + State *string `locationName:"state" type:"string" enum:"VpnState"` + + // Any tags assigned to the VPN connection. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The type of VPN connection. + Type *string `locationName:"type" type:"string" enum:"GatewayType"` + + // Information about the VPN tunnel. + VgwTelemetry []*VgwTelemetry `locationName:"vgwTelemetry" locationNameList:"item" type:"list"` + + // The ID of the VPN connection. + VpnConnectionId *string `locationName:"vpnConnectionId" type:"string"` + + // The ID of the virtual private gateway at the AWS side of the VPN connection. + VpnGatewayId *string `locationName:"vpnGatewayId" type:"string"` +} + +// String returns the string representation +func (s VpnConnection) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnConnection) GoString() string { + return s.String() +} + +// Describes VPN connection options. +type VpnConnectionOptions struct { + _ struct{} `type:"structure"` + + // Indicates whether the VPN connection uses static routes only. Static routes + // must be used for devices that don't support BGP. + StaticRoutesOnly *bool `locationName:"staticRoutesOnly" type:"boolean"` +} + +// String returns the string representation +func (s VpnConnectionOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnConnectionOptions) GoString() string { + return s.String() +} + +// Describes VPN connection options. +type VpnConnectionOptionsSpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether the VPN connection uses static routes only. Static routes + // must be used for devices that don't support BGP. + StaticRoutesOnly *bool `locationName:"staticRoutesOnly" type:"boolean"` +} + +// String returns the string representation +func (s VpnConnectionOptionsSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnConnectionOptionsSpecification) GoString() string { + return s.String() +} + +// Describes a virtual private gateway. +type VpnGateway struct { + _ struct{} `type:"structure"` + + // The Availability Zone where the virtual private gateway was created, if applicable. + // This field may be empty or not returned. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The current state of the virtual private gateway. + State *string `locationName:"state" type:"string" enum:"VpnState"` + + // Any tags assigned to the virtual private gateway. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The type of VPN connection the virtual private gateway supports. + Type *string `locationName:"type" type:"string" enum:"GatewayType"` + + // Any VPCs attached to the virtual private gateway. + VpcAttachments []*VpcAttachment `locationName:"attachments" locationNameList:"item" type:"list"` + + // The ID of the virtual private gateway. + VpnGatewayId *string `locationName:"vpnGatewayId" type:"string"` +} + +// String returns the string representation +func (s VpnGateway) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnGateway) GoString() string { + return s.String() +} + +// Describes a static route for a VPN connection. +type VpnStaticRoute struct { + _ struct{} `type:"structure"` + + // The CIDR block associated with the local subnet of the customer data center. + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string"` + + // Indicates how the routes were provided. + Source *string `locationName:"source" type:"string" enum:"VpnStaticRouteSource"` + + // The current state of the static route. + State *string `locationName:"state" type:"string" enum:"VpnState"` +} + +// String returns the string representation +func (s VpnStaticRoute) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnStaticRoute) GoString() string { + return s.String() +} + +const ( + // @enum AccountAttributeName + AccountAttributeNameSupportedPlatforms = "supported-platforms" + // @enum AccountAttributeName + AccountAttributeNameDefaultVpc = "default-vpc" +) + +const ( + // @enum ActivityStatus + ActivityStatusError = "error" + // @enum ActivityStatus + ActivityStatusPendingFulfillment = "pending_fulfillment" + // @enum ActivityStatus + ActivityStatusPendingTermination = "pending_termination" + // @enum ActivityStatus + ActivityStatusFulfilled = "fulfilled" +) + +const ( + // @enum Affinity + AffinityDefault = "default" + // @enum Affinity + AffinityHost = "host" +) + +const ( + // @enum AllocationState + AllocationStateAvailable = "available" + // @enum AllocationState + AllocationStateUnderAssessment = "under-assessment" + // @enum AllocationState + AllocationStatePermanentFailure = "permanent-failure" + // @enum AllocationState + AllocationStateReleased = "released" + // @enum AllocationState + AllocationStateReleasedPermanentFailure = "released-permanent-failure" +) + +const ( + // @enum AllocationStrategy + AllocationStrategyLowestPrice = "lowestPrice" + // @enum AllocationStrategy + AllocationStrategyDiversified = "diversified" +) + +const ( + // @enum ArchitectureValues + ArchitectureValuesI386 = "i386" + // @enum ArchitectureValues + ArchitectureValuesX8664 = "x86_64" +) + +const ( + // @enum AttachmentStatus + AttachmentStatusAttaching = "attaching" + // @enum AttachmentStatus + AttachmentStatusAttached = "attached" + // @enum AttachmentStatus + AttachmentStatusDetaching = "detaching" + // @enum AttachmentStatus + AttachmentStatusDetached = "detached" +) + +const ( + // @enum AutoPlacement + AutoPlacementOn = "on" + // @enum AutoPlacement + AutoPlacementOff = "off" +) + +const ( + // @enum AvailabilityZoneState + AvailabilityZoneStateAvailable = "available" + // @enum AvailabilityZoneState + AvailabilityZoneStateInformation = "information" + // @enum AvailabilityZoneState + AvailabilityZoneStateImpaired = "impaired" + // @enum AvailabilityZoneState + AvailabilityZoneStateUnavailable = "unavailable" +) + +const ( + // @enum BatchState + BatchStateSubmitted = "submitted" + // @enum BatchState + BatchStateActive = "active" + // @enum BatchState + BatchStateCancelled = "cancelled" + // @enum BatchState + BatchStateFailed = "failed" + // @enum BatchState + BatchStateCancelledRunning = "cancelled_running" + // @enum BatchState + BatchStateCancelledTerminating = "cancelled_terminating" + // @enum BatchState + BatchStateModifying = "modifying" +) + +const ( + // @enum BundleTaskState + BundleTaskStatePending = "pending" + // @enum BundleTaskState + BundleTaskStateWaitingForShutdown = "waiting-for-shutdown" + // @enum BundleTaskState + BundleTaskStateBundling = "bundling" + // @enum BundleTaskState + BundleTaskStateStoring = "storing" + // @enum BundleTaskState + BundleTaskStateCancelling = "cancelling" + // @enum BundleTaskState + BundleTaskStateComplete = "complete" + // @enum BundleTaskState + BundleTaskStateFailed = "failed" +) + +const ( + // @enum CancelBatchErrorCode + CancelBatchErrorCodeFleetRequestIdDoesNotExist = "fleetRequestIdDoesNotExist" + // @enum CancelBatchErrorCode + CancelBatchErrorCodeFleetRequestIdMalformed = "fleetRequestIdMalformed" + // @enum CancelBatchErrorCode + CancelBatchErrorCodeFleetRequestNotInCancellableState = "fleetRequestNotInCancellableState" + // @enum CancelBatchErrorCode + CancelBatchErrorCodeUnexpectedError = "unexpectedError" +) + +const ( + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateActive = "active" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateOpen = "open" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateClosed = "closed" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateCancelled = "cancelled" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateCompleted = "completed" +) + +const ( + // @enum ContainerFormat + ContainerFormatOva = "ova" +) + +const ( + // @enum ConversionTaskState + ConversionTaskStateActive = "active" + // @enum ConversionTaskState + ConversionTaskStateCancelling = "cancelling" + // @enum ConversionTaskState + ConversionTaskStateCancelled = "cancelled" + // @enum ConversionTaskState + ConversionTaskStateCompleted = "completed" +) + +const ( + // @enum CurrencyCodeValues + CurrencyCodeValuesUsd = "USD" +) + +const ( + // @enum DatafeedSubscriptionState + DatafeedSubscriptionStateActive = "Active" + // @enum DatafeedSubscriptionState + DatafeedSubscriptionStateInactive = "Inactive" +) + +const ( + // @enum DeviceType + DeviceTypeEbs = "ebs" + // @enum DeviceType + DeviceTypeInstanceStore = "instance-store" +) + +const ( + // @enum DiskImageFormat + DiskImageFormatVmdk = "VMDK" + // @enum DiskImageFormat + DiskImageFormatRaw = "RAW" + // @enum DiskImageFormat + DiskImageFormatVhd = "VHD" +) + +const ( + // @enum DomainType + DomainTypeVpc = "vpc" + // @enum DomainType + DomainTypeStandard = "standard" +) + +const ( + // @enum EventCode + EventCodeInstanceReboot = "instance-reboot" + // @enum EventCode + EventCodeSystemReboot = "system-reboot" + // @enum EventCode + EventCodeSystemMaintenance = "system-maintenance" + // @enum EventCode + EventCodeInstanceRetirement = "instance-retirement" + // @enum EventCode + EventCodeInstanceStop = "instance-stop" +) + +const ( + // @enum EventType + EventTypeInstanceChange = "instanceChange" + // @enum EventType + EventTypeFleetRequestChange = "fleetRequestChange" + // @enum EventType + EventTypeError = "error" +) + +const ( + // @enum ExcessCapacityTerminationPolicy + ExcessCapacityTerminationPolicyNoTermination = "noTermination" + // @enum ExcessCapacityTerminationPolicy + ExcessCapacityTerminationPolicyDefault = "default" +) + +const ( + // @enum ExportEnvironment + ExportEnvironmentCitrix = "citrix" + // @enum ExportEnvironment + ExportEnvironmentVmware = "vmware" + // @enum ExportEnvironment + ExportEnvironmentMicrosoft = "microsoft" +) + +const ( + // @enum ExportTaskState + ExportTaskStateActive = "active" + // @enum ExportTaskState + ExportTaskStateCancelling = "cancelling" + // @enum ExportTaskState + ExportTaskStateCancelled = "cancelled" + // @enum ExportTaskState + ExportTaskStateCompleted = "completed" +) + +const ( + // @enum FleetType + FleetTypeRequest = "request" + // @enum FleetType + FleetTypeMaintain = "maintain" +) + +const ( + // @enum FlowLogsResourceType + FlowLogsResourceTypeVpc = "VPC" + // @enum FlowLogsResourceType + FlowLogsResourceTypeSubnet = "Subnet" + // @enum FlowLogsResourceType + FlowLogsResourceTypeNetworkInterface = "NetworkInterface" +) + +const ( + // @enum GatewayType + GatewayTypeIpsec1 = "ipsec.1" +) + +const ( + // @enum HostTenancy + HostTenancyDedicated = "dedicated" + // @enum HostTenancy + HostTenancyHost = "host" +) + +const ( + // @enum HypervisorType + HypervisorTypeOvm = "ovm" + // @enum HypervisorType + HypervisorTypeXen = "xen" +) + +const ( + // @enum ImageAttributeName + ImageAttributeNameDescription = "description" + // @enum ImageAttributeName + ImageAttributeNameKernel = "kernel" + // @enum ImageAttributeName + ImageAttributeNameRamdisk = "ramdisk" + // @enum ImageAttributeName + ImageAttributeNameLaunchPermission = "launchPermission" + // @enum ImageAttributeName + ImageAttributeNameProductCodes = "productCodes" + // @enum ImageAttributeName + ImageAttributeNameBlockDeviceMapping = "blockDeviceMapping" + // @enum ImageAttributeName + ImageAttributeNameSriovNetSupport = "sriovNetSupport" +) + +const ( + // @enum ImageState + ImageStatePending = "pending" + // @enum ImageState + ImageStateAvailable = "available" + // @enum ImageState + ImageStateInvalid = "invalid" + // @enum ImageState + ImageStateDeregistered = "deregistered" + // @enum ImageState + ImageStateTransient = "transient" + // @enum ImageState + ImageStateFailed = "failed" + // @enum ImageState + ImageStateError = "error" +) + +const ( + // @enum ImageTypeValues + ImageTypeValuesMachine = "machine" + // @enum ImageTypeValues + ImageTypeValuesKernel = "kernel" + // @enum ImageTypeValues + ImageTypeValuesRamdisk = "ramdisk" +) + +const ( + // @enum InstanceAttributeName + InstanceAttributeNameInstanceType = "instanceType" + // @enum InstanceAttributeName + InstanceAttributeNameKernel = "kernel" + // @enum InstanceAttributeName + InstanceAttributeNameRamdisk = "ramdisk" + // @enum InstanceAttributeName + InstanceAttributeNameUserData = "userData" + // @enum InstanceAttributeName + InstanceAttributeNameDisableApiTermination = "disableApiTermination" + // @enum InstanceAttributeName + InstanceAttributeNameInstanceInitiatedShutdownBehavior = "instanceInitiatedShutdownBehavior" + // @enum InstanceAttributeName + InstanceAttributeNameRootDeviceName = "rootDeviceName" + // @enum InstanceAttributeName + InstanceAttributeNameBlockDeviceMapping = "blockDeviceMapping" + // @enum InstanceAttributeName + InstanceAttributeNameProductCodes = "productCodes" + // @enum InstanceAttributeName + InstanceAttributeNameSourceDestCheck = "sourceDestCheck" + // @enum InstanceAttributeName + InstanceAttributeNameGroupSet = "groupSet" + // @enum InstanceAttributeName + InstanceAttributeNameEbsOptimized = "ebsOptimized" + // @enum InstanceAttributeName + InstanceAttributeNameSriovNetSupport = "sriovNetSupport" + // @enum InstanceAttributeName + InstanceAttributeNameEnaSupport = "enaSupport" +) + +const ( + // @enum InstanceLifecycleType + InstanceLifecycleTypeSpot = "spot" + // @enum InstanceLifecycleType + InstanceLifecycleTypeScheduled = "scheduled" +) + +const ( + // @enum InstanceStateName + InstanceStateNamePending = "pending" + // @enum InstanceStateName + InstanceStateNameRunning = "running" + // @enum InstanceStateName + InstanceStateNameShuttingDown = "shutting-down" + // @enum InstanceStateName + InstanceStateNameTerminated = "terminated" + // @enum InstanceStateName + InstanceStateNameStopping = "stopping" + // @enum InstanceStateName + InstanceStateNameStopped = "stopped" +) + +const ( + // @enum InstanceType + InstanceTypeT1Micro = "t1.micro" + // @enum InstanceType + InstanceTypeT2Nano = "t2.nano" + // @enum InstanceType + InstanceTypeT2Micro = "t2.micro" + // @enum InstanceType + InstanceTypeT2Small = "t2.small" + // @enum InstanceType + InstanceTypeT2Medium = "t2.medium" + // @enum InstanceType + InstanceTypeT2Large = "t2.large" + // @enum InstanceType + InstanceTypeM1Small = "m1.small" + // @enum InstanceType + InstanceTypeM1Medium = "m1.medium" + // @enum InstanceType + InstanceTypeM1Large = "m1.large" + // @enum InstanceType + InstanceTypeM1Xlarge = "m1.xlarge" + // @enum InstanceType + InstanceTypeM3Medium = "m3.medium" + // @enum InstanceType + InstanceTypeM3Large = "m3.large" + // @enum InstanceType + InstanceTypeM3Xlarge = "m3.xlarge" + // @enum InstanceType + InstanceTypeM32xlarge = "m3.2xlarge" + // @enum InstanceType + InstanceTypeM4Large = "m4.large" + // @enum InstanceType + InstanceTypeM4Xlarge = "m4.xlarge" + // @enum InstanceType + InstanceTypeM42xlarge = "m4.2xlarge" + // @enum InstanceType + InstanceTypeM44xlarge = "m4.4xlarge" + // @enum InstanceType + InstanceTypeM410xlarge = "m4.10xlarge" + // @enum InstanceType + InstanceTypeM2Xlarge = "m2.xlarge" + // @enum InstanceType + InstanceTypeM22xlarge = "m2.2xlarge" + // @enum InstanceType + InstanceTypeM24xlarge = "m2.4xlarge" + // @enum InstanceType + InstanceTypeCr18xlarge = "cr1.8xlarge" + // @enum InstanceType + InstanceTypeR3Large = "r3.large" + // @enum InstanceType + InstanceTypeR3Xlarge = "r3.xlarge" + // @enum InstanceType + InstanceTypeR32xlarge = "r3.2xlarge" + // @enum InstanceType + InstanceTypeR34xlarge = "r3.4xlarge" + // @enum InstanceType + InstanceTypeR38xlarge = "r3.8xlarge" + // @enum InstanceType + InstanceTypeX14xlarge = "x1.4xlarge" + // @enum InstanceType + InstanceTypeX18xlarge = "x1.8xlarge" + // @enum InstanceType + InstanceTypeX116xlarge = "x1.16xlarge" + // @enum InstanceType + InstanceTypeX132xlarge = "x1.32xlarge" + // @enum InstanceType + InstanceTypeI2Xlarge = "i2.xlarge" + // @enum InstanceType + InstanceTypeI22xlarge = "i2.2xlarge" + // @enum InstanceType + InstanceTypeI24xlarge = "i2.4xlarge" + // @enum InstanceType + InstanceTypeI28xlarge = "i2.8xlarge" + // @enum InstanceType + InstanceTypeHi14xlarge = "hi1.4xlarge" + // @enum InstanceType + InstanceTypeHs18xlarge = "hs1.8xlarge" + // @enum InstanceType + InstanceTypeC1Medium = "c1.medium" + // @enum InstanceType + InstanceTypeC1Xlarge = "c1.xlarge" + // @enum InstanceType + InstanceTypeC3Large = "c3.large" + // @enum InstanceType + InstanceTypeC3Xlarge = "c3.xlarge" + // @enum InstanceType + InstanceTypeC32xlarge = "c3.2xlarge" + // @enum InstanceType + InstanceTypeC34xlarge = "c3.4xlarge" + // @enum InstanceType + InstanceTypeC38xlarge = "c3.8xlarge" + // @enum InstanceType + InstanceTypeC4Large = "c4.large" + // @enum InstanceType + InstanceTypeC4Xlarge = "c4.xlarge" + // @enum InstanceType + InstanceTypeC42xlarge = "c4.2xlarge" + // @enum InstanceType + InstanceTypeC44xlarge = "c4.4xlarge" + // @enum InstanceType + InstanceTypeC48xlarge = "c4.8xlarge" + // @enum InstanceType + InstanceTypeCc14xlarge = "cc1.4xlarge" + // @enum InstanceType + InstanceTypeCc28xlarge = "cc2.8xlarge" + // @enum InstanceType + InstanceTypeG22xlarge = "g2.2xlarge" + // @enum InstanceType + InstanceTypeG28xlarge = "g2.8xlarge" + // @enum InstanceType + InstanceTypeCg14xlarge = "cg1.4xlarge" + // @enum InstanceType + InstanceTypeD2Xlarge = "d2.xlarge" + // @enum InstanceType + InstanceTypeD22xlarge = "d2.2xlarge" + // @enum InstanceType + InstanceTypeD24xlarge = "d2.4xlarge" + // @enum InstanceType + InstanceTypeD28xlarge = "d2.8xlarge" +) + +const ( + // @enum ListingState + ListingStateAvailable = "available" + // @enum ListingState + ListingStateSold = "sold" + // @enum ListingState + ListingStateCancelled = "cancelled" + // @enum ListingState + ListingStatePending = "pending" +) + +const ( + // @enum ListingStatus + ListingStatusActive = "active" + // @enum ListingStatus + ListingStatusPending = "pending" + // @enum ListingStatus + ListingStatusCancelled = "cancelled" + // @enum ListingStatus + ListingStatusClosed = "closed" +) + +const ( + // @enum MonitoringState + MonitoringStateDisabled = "disabled" + // @enum MonitoringState + MonitoringStateDisabling = "disabling" + // @enum MonitoringState + MonitoringStateEnabled = "enabled" + // @enum MonitoringState + MonitoringStatePending = "pending" +) + +const ( + // @enum MoveStatus + MoveStatusMovingToVpc = "movingToVpc" + // @enum MoveStatus + MoveStatusRestoringToClassic = "restoringToClassic" +) + +const ( + // @enum NatGatewayState + NatGatewayStatePending = "pending" + // @enum NatGatewayState + NatGatewayStateFailed = "failed" + // @enum NatGatewayState + NatGatewayStateAvailable = "available" + // @enum NatGatewayState + NatGatewayStateDeleting = "deleting" + // @enum NatGatewayState + NatGatewayStateDeleted = "deleted" +) + +const ( + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeDescription = "description" + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeGroupSet = "groupSet" + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeSourceDestCheck = "sourceDestCheck" + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeAttachment = "attachment" +) + +const ( + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusAvailable = "available" + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusAttaching = "attaching" + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusInUse = "in-use" + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusDetaching = "detaching" +) + +const ( + // @enum NetworkInterfaceType + NetworkInterfaceTypeInterface = "interface" + // @enum NetworkInterfaceType + NetworkInterfaceTypeNatGateway = "natGateway" +) + +const ( + // @enum OfferingTypeValues + OfferingTypeValuesHeavyUtilization = "Heavy Utilization" + // @enum OfferingTypeValues + OfferingTypeValuesMediumUtilization = "Medium Utilization" + // @enum OfferingTypeValues + OfferingTypeValuesLightUtilization = "Light Utilization" + // @enum OfferingTypeValues + OfferingTypeValuesNoUpfront = "No Upfront" + // @enum OfferingTypeValues + OfferingTypeValuesPartialUpfront = "Partial Upfront" + // @enum OfferingTypeValues + OfferingTypeValuesAllUpfront = "All Upfront" +) + +const ( + // @enum OperationType + OperationTypeAdd = "add" + // @enum OperationType + OperationTypeRemove = "remove" +) + +const ( + // @enum PaymentOption + PaymentOptionAllUpfront = "AllUpfront" + // @enum PaymentOption + PaymentOptionPartialUpfront = "PartialUpfront" + // @enum PaymentOption + PaymentOptionNoUpfront = "NoUpfront" +) + +const ( + // @enum PermissionGroup + PermissionGroupAll = "all" +) + +const ( + // @enum PlacementGroupState + PlacementGroupStatePending = "pending" + // @enum PlacementGroupState + PlacementGroupStateAvailable = "available" + // @enum PlacementGroupState + PlacementGroupStateDeleting = "deleting" + // @enum PlacementGroupState + PlacementGroupStateDeleted = "deleted" +) + +const ( + // @enum PlacementStrategy + PlacementStrategyCluster = "cluster" +) + +const ( + // @enum PlatformValues + PlatformValuesWindows = "Windows" +) + +const ( + // @enum ProductCodeValues + ProductCodeValuesDevpay = "devpay" + // @enum ProductCodeValues + ProductCodeValuesMarketplace = "marketplace" +) + +const ( + // @enum RIProductDescription + RIProductDescriptionLinuxUnix = "Linux/UNIX" + // @enum RIProductDescription + RIProductDescriptionLinuxUnixamazonVpc = "Linux/UNIX (Amazon VPC)" + // @enum RIProductDescription + RIProductDescriptionWindows = "Windows" + // @enum RIProductDescription + RIProductDescriptionWindowsAmazonVpc = "Windows (Amazon VPC)" +) + +const ( + // @enum RecurringChargeFrequency + RecurringChargeFrequencyHourly = "Hourly" +) + +const ( + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesInstanceStuckInState = "instance-stuck-in-state" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesUnresponsive = "unresponsive" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesNotAcceptingCredentials = "not-accepting-credentials" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPasswordNotAvailable = "password-not-available" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceNetwork = "performance-network" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceInstanceStore = "performance-instance-store" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceEbsVolume = "performance-ebs-volume" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceOther = "performance-other" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesOther = "other" +) + +const ( + // @enum ReportStatusType + ReportStatusTypeOk = "ok" + // @enum ReportStatusType + ReportStatusTypeImpaired = "impaired" +) + +const ( + // @enum ReservationState + ReservationStatePaymentPending = "payment-pending" + // @enum ReservationState + ReservationStatePaymentFailed = "payment-failed" + // @enum ReservationState + ReservationStateActive = "active" + // @enum ReservationState + ReservationStateRetired = "retired" +) + +const ( + // @enum ReservedInstanceState + ReservedInstanceStatePaymentPending = "payment-pending" + // @enum ReservedInstanceState + ReservedInstanceStateActive = "active" + // @enum ReservedInstanceState + ReservedInstanceStatePaymentFailed = "payment-failed" + // @enum ReservedInstanceState + ReservedInstanceStateRetired = "retired" +) + +const ( + // @enum ResetImageAttributeName + ResetImageAttributeNameLaunchPermission = "launchPermission" +) + +const ( + // @enum ResourceType + ResourceTypeCustomerGateway = "customer-gateway" + // @enum ResourceType + ResourceTypeDhcpOptions = "dhcp-options" + // @enum ResourceType + ResourceTypeImage = "image" + // @enum ResourceType + ResourceTypeInstance = "instance" + // @enum ResourceType + ResourceTypeInternetGateway = "internet-gateway" + // @enum ResourceType + ResourceTypeNetworkAcl = "network-acl" + // @enum ResourceType + ResourceTypeNetworkInterface = "network-interface" + // @enum ResourceType + ResourceTypeReservedInstances = "reserved-instances" + // @enum ResourceType + ResourceTypeRouteTable = "route-table" + // @enum ResourceType + ResourceTypeSnapshot = "snapshot" + // @enum ResourceType + ResourceTypeSpotInstancesRequest = "spot-instances-request" + // @enum ResourceType + ResourceTypeSubnet = "subnet" + // @enum ResourceType + ResourceTypeSecurityGroup = "security-group" + // @enum ResourceType + ResourceTypeVolume = "volume" + // @enum ResourceType + ResourceTypeVpc = "vpc" + // @enum ResourceType + ResourceTypeVpnConnection = "vpn-connection" + // @enum ResourceType + ResourceTypeVpnGateway = "vpn-gateway" +) + +const ( + // @enum RouteOrigin + RouteOriginCreateRouteTable = "CreateRouteTable" + // @enum RouteOrigin + RouteOriginCreateRoute = "CreateRoute" + // @enum RouteOrigin + RouteOriginEnableVgwRoutePropagation = "EnableVgwRoutePropagation" +) + +const ( + // @enum RouteState + RouteStateActive = "active" + // @enum RouteState + RouteStateBlackhole = "blackhole" +) + +const ( + // @enum RuleAction + RuleActionAllow = "allow" + // @enum RuleAction + RuleActionDeny = "deny" +) + +const ( + // @enum ShutdownBehavior + ShutdownBehaviorStop = "stop" + // @enum ShutdownBehavior + ShutdownBehaviorTerminate = "terminate" +) + +const ( + // @enum SnapshotAttributeName + SnapshotAttributeNameProductCodes = "productCodes" + // @enum SnapshotAttributeName + SnapshotAttributeNameCreateVolumePermission = "createVolumePermission" +) + +const ( + // @enum SnapshotState + SnapshotStatePending = "pending" + // @enum SnapshotState + SnapshotStateCompleted = "completed" + // @enum SnapshotState + SnapshotStateError = "error" +) + +const ( + // @enum SpotInstanceState + SpotInstanceStateOpen = "open" + // @enum SpotInstanceState + SpotInstanceStateActive = "active" + // @enum SpotInstanceState + SpotInstanceStateClosed = "closed" + // @enum SpotInstanceState + SpotInstanceStateCancelled = "cancelled" + // @enum SpotInstanceState + SpotInstanceStateFailed = "failed" +) + +const ( + // @enum SpotInstanceType + SpotInstanceTypeOneTime = "one-time" + // @enum SpotInstanceType + SpotInstanceTypePersistent = "persistent" +) + +const ( + // @enum State + StatePending = "Pending" + // @enum State + StateAvailable = "Available" + // @enum State + StateDeleting = "Deleting" + // @enum State + StateDeleted = "Deleted" +) + +const ( + // @enum Status + StatusMoveInProgress = "MoveInProgress" + // @enum Status + StatusInVpc = "InVpc" + // @enum Status + StatusInClassic = "InClassic" +) + +const ( + // @enum StatusName + StatusNameReachability = "reachability" +) + +const ( + // @enum StatusType + StatusTypePassed = "passed" + // @enum StatusType + StatusTypeFailed = "failed" + // @enum StatusType + StatusTypeInsufficientData = "insufficient-data" + // @enum StatusType + StatusTypeInitializing = "initializing" +) + +const ( + // @enum SubnetState + SubnetStatePending = "pending" + // @enum SubnetState + SubnetStateAvailable = "available" +) + +const ( + // @enum SummaryStatus + SummaryStatusOk = "ok" + // @enum SummaryStatus + SummaryStatusImpaired = "impaired" + // @enum SummaryStatus + SummaryStatusInsufficientData = "insufficient-data" + // @enum SummaryStatus + SummaryStatusNotApplicable = "not-applicable" + // @enum SummaryStatus + SummaryStatusInitializing = "initializing" +) + +const ( + // @enum TelemetryStatus + TelemetryStatusUp = "UP" + // @enum TelemetryStatus + TelemetryStatusDown = "DOWN" +) + +const ( + // @enum Tenancy + TenancyDefault = "default" + // @enum Tenancy + TenancyDedicated = "dedicated" + // @enum Tenancy + TenancyHost = "host" +) + +const ( + // @enum TrafficType + TrafficTypeAccept = "ACCEPT" + // @enum TrafficType + TrafficTypeReject = "REJECT" + // @enum TrafficType + TrafficTypeAll = "ALL" +) + +const ( + // @enum VirtualizationType + VirtualizationTypeHvm = "hvm" + // @enum VirtualizationType + VirtualizationTypeParavirtual = "paravirtual" +) + +const ( + // @enum VolumeAttachmentState + VolumeAttachmentStateAttaching = "attaching" + // @enum VolumeAttachmentState + VolumeAttachmentStateAttached = "attached" + // @enum VolumeAttachmentState + VolumeAttachmentStateDetaching = "detaching" + // @enum VolumeAttachmentState + VolumeAttachmentStateDetached = "detached" +) + +const ( + // @enum VolumeAttributeName + VolumeAttributeNameAutoEnableIo = "autoEnableIO" + // @enum VolumeAttributeName + VolumeAttributeNameProductCodes = "productCodes" +) + +const ( + // @enum VolumeState + VolumeStateCreating = "creating" + // @enum VolumeState + VolumeStateAvailable = "available" + // @enum VolumeState + VolumeStateInUse = "in-use" + // @enum VolumeState + VolumeStateDeleting = "deleting" + // @enum VolumeState + VolumeStateDeleted = "deleted" + // @enum VolumeState + VolumeStateError = "error" +) + +const ( + // @enum VolumeStatusInfoStatus + VolumeStatusInfoStatusOk = "ok" + // @enum VolumeStatusInfoStatus + VolumeStatusInfoStatusImpaired = "impaired" + // @enum VolumeStatusInfoStatus + VolumeStatusInfoStatusInsufficientData = "insufficient-data" +) + +const ( + // @enum VolumeStatusName + VolumeStatusNameIoEnabled = "io-enabled" + // @enum VolumeStatusName + VolumeStatusNameIoPerformance = "io-performance" +) + +const ( + // @enum VolumeType + VolumeTypeStandard = "standard" + // @enum VolumeType + VolumeTypeIo1 = "io1" + // @enum VolumeType + VolumeTypeGp2 = "gp2" + // @enum VolumeType + VolumeTypeSc1 = "sc1" + // @enum VolumeType + VolumeTypeSt1 = "st1" +) + +const ( + // @enum VpcAttributeName + VpcAttributeNameEnableDnsSupport = "enableDnsSupport" + // @enum VpcAttributeName + VpcAttributeNameEnableDnsHostnames = "enableDnsHostnames" +) + +const ( + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeInitiatingRequest = "initiating-request" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodePendingAcceptance = "pending-acceptance" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeActive = "active" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeDeleted = "deleted" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeRejected = "rejected" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeFailed = "failed" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeExpired = "expired" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeProvisioning = "provisioning" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeDeleting = "deleting" +) + +const ( + // @enum VpcState + VpcStatePending = "pending" + // @enum VpcState + VpcStateAvailable = "available" +) + +const ( + // @enum VpnState + VpnStatePending = "pending" + // @enum VpnState + VpnStateAvailable = "available" + // @enum VpnState + VpnStateDeleting = "deleting" + // @enum VpnState + VpnStateDeleted = "deleted" +) + +const ( + // @enum VpnStaticRouteSource + VpnStaticRouteSourceStatic = "Static" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go new file mode 100644 index 0000000000..36181d9914 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go @@ -0,0 +1,59 @@ +package ec2 + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/endpoints" +) + +func init() { + initRequest = func(r *request.Request) { + if r.Operation.Name == opCopySnapshot { // fill the PresignedURL parameter + r.Handlers.Build.PushFront(fillPresignedURL) + } + } +} + +func fillPresignedURL(r *request.Request) { + if !r.ParamsFilled() { + return + } + + origParams := r.Params.(*CopySnapshotInput) + + // Stop if PresignedURL/DestinationRegion is set + if origParams.PresignedUrl != nil || origParams.DestinationRegion != nil { + return + } + + origParams.DestinationRegion = r.Config.Region + newParams := awsutil.CopyOf(r.Params).(*CopySnapshotInput) + + // Create a new request based on the existing request. We will use this to + // presign the CopySnapshot request against the source region. + cfg := r.Config.Copy(aws.NewConfig(). + WithEndpoint(""). + WithRegion(aws.StringValue(origParams.SourceRegion))) + + clientInfo := r.ClientInfo + clientInfo.Endpoint, clientInfo.SigningRegion = endpoints.EndpointForRegion( + clientInfo.ServiceName, + aws.StringValue(cfg.Region), + aws.BoolValue(cfg.DisableSSL), + aws.BoolValue(cfg.UseDualStack), + ) + + // Presign a CopySnapshot request with modified params + req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data) + url, err := req.Presign(5 * time.Minute) // 5 minutes should be enough. + if err != nil { // bubble error back up to original request + r.Error = err + return + } + + // We have our URL, set it on params + origParams.PresignedUrl = &url +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go new file mode 100644 index 0000000000..4e6fa4cd78 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go @@ -0,0 +1,89 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +package ec2 + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/ec2query" +) + +// Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity +// in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your +// need to invest in hardware up front, so you can develop and deploy applications +// faster. +//The service client's operations are safe to be used concurrently. +// It is not safe to mutate any of the client's properties though. +type EC2 struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// A ServiceName is the name of the service the client will make API calls to. +const ServiceName = "ec2" + +// New creates a new instance of the EC2 client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a EC2 client from just a session. +// svc := ec2.New(mySession) +// +// // Create a EC2 client with additional configuration +// svc := ec2.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2 { + c := p.ClientConfig(ServiceName, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *EC2 { + svc := &EC2{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2016-04-01", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(ec2query.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(ec2query.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(ec2query.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(ec2query.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a EC2 operation and runs any +// custom request initialization. +func (c *EC2) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go new file mode 100644 index 0000000000..bee4a057ff --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go @@ -0,0 +1,907 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +package ec2 + +import ( + "github.com/aws/aws-sdk-go/private/waiter" +) + +func (c *EC2) WaitUntilBundleTaskComplete(input *DescribeBundleTasksInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeBundleTasks", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "BundleTasks[].State", + Expected: "complete", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "BundleTasks[].State", + Expected: "failed", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilConversionTaskCancelled(input *DescribeConversionTasksInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeConversionTasks", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "ConversionTasks[].State", + Expected: "cancelled", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilConversionTaskCompleted(input *DescribeConversionTasksInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeConversionTasks", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "ConversionTasks[].State", + Expected: "completed", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "ConversionTasks[].State", + Expected: "cancelled", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "ConversionTasks[].State", + Expected: "cancelling", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilConversionTaskDeleted(input *DescribeConversionTasksInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeConversionTasks", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "ConversionTasks[].State", + Expected: "deleted", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilCustomerGatewayAvailable(input *DescribeCustomerGatewaysInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeCustomerGateways", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "CustomerGateways[].State", + Expected: "available", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "CustomerGateways[].State", + Expected: "deleted", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "CustomerGateways[].State", + Expected: "deleting", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilExportTaskCancelled(input *DescribeExportTasksInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeExportTasks", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "ExportTasks[].State", + Expected: "cancelled", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilExportTaskCompleted(input *DescribeExportTasksInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeExportTasks", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "ExportTasks[].State", + Expected: "completed", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilImageAvailable(input *DescribeImagesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeImages", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Images[].State", + Expected: "available", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Images[].State", + Expected: "failed", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilImageExists(input *DescribeImagesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeImages", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "path", + Argument: "length(Images[]) > `0`", + Expected: true, + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidAMIID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilInstanceExists(input *DescribeInstancesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeInstances", + Delay: 5, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "path", + Argument: "length(Reservations[]) > `0`", + Expected: true, + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidInstanceID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilInstanceRunning(input *DescribeInstancesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeInstances", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Reservations[].Instances[].State.Name", + Expected: "running", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "shutting-down", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "terminated", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "stopping", + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidInstanceID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilInstanceStatusOk(input *DescribeInstanceStatusInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeInstanceStatus", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "InstanceStatuses[].InstanceStatus.Status", + Expected: "ok", + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidInstanceID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilInstanceStopped(input *DescribeInstancesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeInstances", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Reservations[].Instances[].State.Name", + Expected: "stopped", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "pending", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "terminated", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilInstanceTerminated(input *DescribeInstancesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeInstances", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Reservations[].Instances[].State.Name", + Expected: "terminated", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "pending", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Reservations[].Instances[].State.Name", + Expected: "stopping", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilKeyPairExists(input *DescribeKeyPairsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeKeyPairs", + Delay: 5, + MaxAttempts: 6, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "length(KeyPairs[].KeyName) > `0`", + Expected: true, + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidKeyPair.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilNatGatewayAvailable(input *DescribeNatGatewaysInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeNatGateways", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "NatGateways[].State", + Expected: "available", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "NatGateways[].State", + Expected: "failed", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "NatGateways[].State", + Expected: "deleting", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "NatGateways[].State", + Expected: "deleted", + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "NatGatewayNotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilNetworkInterfaceAvailable(input *DescribeNetworkInterfacesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeNetworkInterfaces", + Delay: 20, + MaxAttempts: 10, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "NetworkInterfaces[].Status", + Expected: "available", + }, + { + State: "failure", + Matcher: "error", + Argument: "", + Expected: "InvalidNetworkInterfaceID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilPasswordDataAvailable(input *GetPasswordDataInput) error { + waiterCfg := waiter.Config{ + Operation: "GetPasswordData", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "path", + Argument: "length(PasswordData) > `0`", + Expected: true, + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilSnapshotCompleted(input *DescribeSnapshotsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeSnapshots", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Snapshots[].State", + Expected: "completed", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilSpotInstanceRequestFulfilled(input *DescribeSpotInstanceRequestsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeSpotInstanceRequests", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "SpotInstanceRequests[].Status.Code", + Expected: "fulfilled", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "SpotInstanceRequests[].Status.Code", + Expected: "schedule-expired", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "SpotInstanceRequests[].Status.Code", + Expected: "canceled-before-fulfillment", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "SpotInstanceRequests[].Status.Code", + Expected: "bad-parameters", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "SpotInstanceRequests[].Status.Code", + Expected: "system-error", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilSubnetAvailable(input *DescribeSubnetsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeSubnets", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Subnets[].State", + Expected: "available", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilSystemStatusOk(input *DescribeInstanceStatusInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeInstanceStatus", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "InstanceStatuses[].SystemStatus.Status", + Expected: "ok", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVolumeAvailable(input *DescribeVolumesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVolumes", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Volumes[].State", + Expected: "available", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Volumes[].State", + Expected: "deleted", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVolumeDeleted(input *DescribeVolumesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVolumes", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Volumes[].State", + Expected: "deleted", + }, + { + State: "success", + Matcher: "error", + Argument: "", + Expected: "InvalidVolume.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVolumeInUse(input *DescribeVolumesInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVolumes", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Volumes[].State", + Expected: "in-use", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "Volumes[].State", + Expected: "deleted", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVpcAvailable(input *DescribeVpcsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVpcs", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "Vpcs[].State", + Expected: "available", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVpcExists(input *DescribeVpcsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVpcs", + Delay: 1, + MaxAttempts: 5, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "status", + Argument: "", + Expected: 200, + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidVpcID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVpcPeeringConnectionExists(input *DescribeVpcPeeringConnectionsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVpcPeeringConnections", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "status", + Argument: "", + Expected: 200, + }, + { + State: "retry", + Matcher: "error", + Argument: "", + Expected: "InvalidVpcPeeringConnectionID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVpnConnectionAvailable(input *DescribeVpnConnectionsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVpnConnections", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "VpnConnections[].State", + Expected: "available", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "VpnConnections[].State", + Expected: "deleting", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "VpnConnections[].State", + Expected: "deleted", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} + +func (c *EC2) WaitUntilVpnConnectionDeleted(input *DescribeVpnConnectionsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeVpnConnections", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "pathAll", + Argument: "VpnConnections[].State", + Expected: "deleted", + }, + { + State: "failure", + Matcher: "pathAny", + Argument: "VpnConnections[].State", + Expected: "pending", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go new file mode 100644 index 0000000000..f11e8675f2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -0,0 +1,1653 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +// Package sts provides a client for AWS Security Token Service. +package sts + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" +) + +const opAssumeRole = "AssumeRole" + +// AssumeRoleRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRole operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssumeRole method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssumeRoleRequest method. +// req, resp := client.AssumeRoleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) { + op := &request.Operation{ + Name: opAssumeRole, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleInput{} + } + + req = c.newRequest(op, input, output) + output = &AssumeRoleOutput{} + req.Data = output + return +} + +// Returns a set of temporary security credentials (consisting of an access +// key ID, a secret access key, and a security token) that you can use to access +// AWS resources that you might not normally have access to. Typically, you +// use AssumeRole for cross-account access or federation. For a comparison of +// AssumeRole with the other APIs that produce temporary credentials, see Requesting +// Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// Important: You cannot call AssumeRole by using AWS root account credentials; +// access is denied. You must use credentials for an IAM user or an IAM role +// to call AssumeRole. +// +// For cross-account access, imagine that you own multiple accounts and need +// to access resources in each account. You could create long-term credentials +// in each account to access those resources. However, managing all those credentials +// and remembering which one can access which account can be time consuming. +// Instead, you can create one set of long-term credentials in one account and +// then use temporary security credentials to access all the other accounts +// by assuming roles in those accounts. For more information about roles, see +// IAM Roles (Delegation and Federation) (http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html) +// in the IAM User Guide. +// +// For federation, you can, for example, grant single sign-on access to the +// AWS Management Console. If you already have an identity and authentication +// system in your corporate network, you don't have to recreate user identities +// in AWS in order to grant those user identities access to AWS. Instead, after +// a user has been authenticated, you call AssumeRole (and specify the role +// with the appropriate permissions) to get temporary security credentials for +// that user. With those temporary security credentials, you construct a sign-in +// URL that users can use to access the console. For more information, see Common +// Scenarios for Temporary Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html#sts-introduction) +// in the IAM User Guide. +// +// The temporary security credentials are valid for the duration that you specified +// when calling AssumeRole, which can be from 900 seconds (15 minutes) to a +// maximum of 3600 seconds (1 hour). The default is 1 hour. +// +// The temporary security credentials created by AssumeRole can be used to +// make API calls to any AWS service with the following exception: you cannot +// call the STS service's GetFederationToken or GetSessionToken APIs. +// +// Optionally, you can pass an IAM access policy to this operation. If you +// choose not to pass a policy, the temporary security credentials that are +// returned by the operation have the permissions that are defined in the access +// policy of the role that is being assumed. If you pass a policy to this operation, +// the temporary security credentials that are returned by the operation have +// the permissions that are allowed by both the access policy of the role that +// is being assumed, and the policy that you pass. This gives you a way to +// further restrict the permissions for the resulting temporary security credentials. +// You cannot use the passed policy to grant permissions that are in excess +// of those allowed by the access policy of the role that is being assumed. +// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, +// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) +// in the IAM User Guide. +// +// To assume a role, your AWS account must be trusted by the role. The trust +// relationship is defined in the role's trust policy when the role is created. +// That trust policy states which accounts are allowed to delegate access to +// this account's role. +// +// The user who wants to access the role must also have permissions delegated +// from the role's administrator. If the user is in a different account than +// the role, then the user's administrator must attach a policy that allows +// the user to call AssumeRole on the ARN of the role in the other account. +// If the user is in the same account as the role, then you can either attach +// a policy to the user (identical to the previous different account user), +// or you can add the user as a principal directly in the role's trust policy +// +// Using MFA with AssumeRole +// +// You can optionally include multi-factor authentication (MFA) information +// when you call AssumeRole. This is useful for cross-account scenarios in which +// you want to make sure that the user who is assuming the role has been authenticated +// using an AWS MFA device. In that scenario, the trust policy of the role being +// assumed includes a condition that tests for MFA authentication; if the caller +// does not include valid MFA information, the request to assume the role is +// denied. The condition in a trust policy that tests for MFA authentication +// might look like the following example. +// +// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}} +// +// For more information, see Configuring MFA-Protected API Access (http://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html) +// in the IAM User Guide guide. +// +// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode +// parameters. The SerialNumber value identifies the user's hardware or virtual +// MFA device. The TokenCode is the time-based one-time password (TOTP) that +// the MFA devices produces. +func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) { + req, out := c.AssumeRoleRequest(input) + err := req.Send() + return out, err +} + +const opAssumeRoleWithSAML = "AssumeRoleWithSAML" + +// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRoleWithSAML operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssumeRoleWithSAML method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssumeRoleWithSAMLRequest method. +// req, resp := client.AssumeRoleWithSAMLRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) { + op := &request.Operation{ + Name: opAssumeRoleWithSAML, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithSAMLInput{} + } + + req = c.newRequest(op, input, output) + output = &AssumeRoleWithSAMLOutput{} + req.Data = output + return +} + +// Returns a set of temporary security credentials for users who have been authenticated +// via a SAML authentication response. This operation provides a mechanism for +// tying an enterprise identity store or directory to role-based AWS access +// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML +// with the other APIs that produce temporary credentials, see Requesting Temporary +// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this operation consist of +// an access key ID, a secret access key, and a security token. Applications +// can use these temporary security credentials to sign calls to AWS services. +// +// The temporary security credentials are valid for the duration that you specified +// when calling AssumeRole, or until the time specified in the SAML authentication +// response's SessionNotOnOrAfter value, whichever is shorter. The duration +// can be from 900 seconds (15 minutes) to a maximum of 3600 seconds (1 hour). +// The default is 1 hour. +// +// The temporary security credentials created by AssumeRoleWithSAML can be +// used to make API calls to any AWS service with the following exception: you +// cannot call the STS service's GetFederationToken or GetSessionToken APIs. +// +// Optionally, you can pass an IAM access policy to this operation. If you +// choose not to pass a policy, the temporary security credentials that are +// returned by the operation have the permissions that are defined in the access +// policy of the role that is being assumed. If you pass a policy to this operation, +// the temporary security credentials that are returned by the operation have +// the permissions that are allowed by the intersection of both the access policy +// of the role that is being assumed, and the policy that you pass. This means +// that both policies must grant the permission for the action to be allowed. +// This gives you a way to further restrict the permissions for the resulting +// temporary security credentials. You cannot use the passed policy to grant +// permissions that are in excess of those allowed by the access policy of the +// role that is being assumed. For more information, see Permissions for AssumeRole, +// AssumeRoleWithSAML, and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithSAML, you must configure +// your SAML identity provider (IdP) to issue the claims required by AWS. Additionally, +// you must use AWS Identity and Access Management (IAM) to create a SAML provider +// entity in your AWS account that represents your identity provider, and create +// an IAM role that specifies this SAML provider in its trust policy. +// +// Calling AssumeRoleWithSAML does not require the use of AWS security credentials. +// The identity of the caller is validated by using keys in the metadata document +// that is uploaded for the SAML provider entity for your identity provider. +// +// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail +// logs. The entry includes the value in the NameID element of the SAML assertion. +// We recommend that you use a NameIDType that is not associated with any personally +// identifiable information (PII). For example, you could instead use the Persistent +// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent). +// +// For more information, see the following resources: +// +// About SAML 2.0-based Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) +// in the IAM User Guide. +// +// Creating SAML Identity Providers (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) +// in the IAM User Guide. +// +// Configuring a Relying Party and Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html) +// in the IAM User Guide. +// +// Creating a Role for SAML 2.0 Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html) +// in the IAM User Guide. +func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) { + req, out := c.AssumeRoleWithSAMLRequest(input) + err := req.Send() + return out, err +} + +const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity" + +// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRoleWithWebIdentity operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the AssumeRoleWithWebIdentity method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the AssumeRoleWithWebIdentityRequest method. +// req, resp := client.AssumeRoleWithWebIdentityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) { + op := &request.Operation{ + Name: opAssumeRoleWithWebIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithWebIdentityInput{} + } + + req = c.newRequest(op, input, output) + output = &AssumeRoleWithWebIdentityOutput{} + req.Data = output + return +} + +// Returns a set of temporary security credentials for users who have been authenticated +// in a mobile or web application with a web identity provider, such as Amazon +// Cognito, Login with Amazon, Facebook, Google, or any OpenID Connect-compatible +// identity provider. +// +// For mobile applications, we recommend that you use Amazon Cognito. You +// can use Amazon Cognito with the AWS SDK for iOS (http://aws.amazon.com/sdkforios/) +// and the AWS SDK for Android (http://aws.amazon.com/sdkforandroid/) to uniquely +// identify a user and supply the user with a consistent identity throughout +// the lifetime of an application. +// +// To learn more about Amazon Cognito, see Amazon Cognito Overview (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840) +// in the AWS SDK for Android Developer Guide guide and Amazon Cognito Overview +// (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664) +// in the AWS SDK for iOS Developer Guide. +// +// Calling AssumeRoleWithWebIdentity does not require the use of AWS security +// credentials. Therefore, you can distribute an application (for example, on +// mobile devices) that requests temporary security credentials without including +// long-term AWS credentials in the application, and without deploying server-based +// proxy services that use long-term AWS credentials. Instead, the identity +// of the caller is validated by using a token from the web identity provider. +// For a comparison of AssumeRoleWithWebIdentity with the other APIs that produce +// temporary credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this API consist of an access +// key ID, a secret access key, and a security token. Applications can use these +// temporary security credentials to sign calls to AWS service APIs. +// +// The credentials are valid for the duration that you specified when calling +// AssumeRoleWithWebIdentity, which can be from 900 seconds (15 minutes) to +// a maximum of 3600 seconds (1 hour). The default is 1 hour. +// +// The temporary security credentials created by AssumeRoleWithWebIdentity +// can be used to make API calls to any AWS service with the following exception: +// you cannot call the STS service's GetFederationToken or GetSessionToken APIs. +// +// Optionally, you can pass an IAM access policy to this operation. If you +// choose not to pass a policy, the temporary security credentials that are +// returned by the operation have the permissions that are defined in the access +// policy of the role that is being assumed. If you pass a policy to this operation, +// the temporary security credentials that are returned by the operation have +// the permissions that are allowed by both the access policy of the role that +// is being assumed, and the policy that you pass. This gives you a way to +// further restrict the permissions for the resulting temporary security credentials. +// You cannot use the passed policy to grant permissions that are in excess +// of those allowed by the access policy of the role that is being assumed. +// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, +// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithWebIdentity, you must have +// an identity token from a supported identity provider and create a role that +// the application can assume. The role that your application assumes must trust +// the identity provider that is associated with the identity token. In other +// words, the identity provider must be specified in the role's trust policy. +// +// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail +// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims) +// of the provided Web Identity Token. We recommend that you avoid using any +// personally identifiable information (PII) in this field. For example, you +// could instead use a GUID or a pairwise identifier, as suggested in the OIDC +// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes). +// +// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity +// API, see the following resources: +// +// Using Web Identity Federation APIs for Mobile Apps (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual) +// and Federation Through a Web-based Identity Provider (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html). +// This interactive website lets you walk through the process of authenticating +// via Login with Amazon, Facebook, or Google, getting temporary security credentials, +// and then using those credentials to make a request to AWS. +// +// AWS SDK for iOS (http://aws.amazon.com/sdkforios/) and AWS SDK for Android +// (http://aws.amazon.com/sdkforandroid/). These toolkits contain sample apps +// that show how to invoke the identity providers, and then how to use the information +// from these providers to get and use temporary security credentials. +// +// Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/4617974389850313). +// This article discusses web identity federation and shows an example of how +// to use web identity federation to get access to content in Amazon S3. +func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) { + req, out := c.AssumeRoleWithWebIdentityRequest(input) + err := req.Send() + return out, err +} + +const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage" + +// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the +// client's request for the DecodeAuthorizationMessage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DecodeAuthorizationMessage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DecodeAuthorizationMessageRequest method. +// req, resp := client.DecodeAuthorizationMessageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) { + op := &request.Operation{ + Name: opDecodeAuthorizationMessage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DecodeAuthorizationMessageInput{} + } + + req = c.newRequest(op, input, output) + output = &DecodeAuthorizationMessageOutput{} + req.Data = output + return +} + +// Decodes additional information about the authorization status of a request +// from an encoded message returned in response to an AWS request. +// +// For example, if a user is not authorized to perform an action that he or +// she has requested, the request returns a Client.UnauthorizedOperation response +// (an HTTP 403 response). Some AWS actions additionally return an encoded message +// that can provide details about this authorization failure. +// +// Only certain AWS actions return an encoded authorization message. The documentation +// for an individual action indicates whether that action returns an encoded +// message in addition to returning an HTTP code. +// +// The message is encoded because the details of the authorization status +// can constitute privileged information that the user who requested the action +// should not see. To decode an authorization status message, a user must be +// granted permissions via an IAM policy to request the DecodeAuthorizationMessage +// (sts:DecodeAuthorizationMessage) action. +// +// The decoded message includes the following type of information: +// +// Whether the request was denied due to an explicit deny or due to the absence +// of an explicit allow. For more information, see Determining Whether a Request +// is Allowed or Denied (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow) +// in the IAM User Guide. +// +// The principal who made the request. +// +// The requested action. +// +// The requested resource. +// +// The values of condition keys in the context of the user's request. +func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) { + req, out := c.DecodeAuthorizationMessageRequest(input) + err := req.Send() + return out, err +} + +const opGetCallerIdentity = "GetCallerIdentity" + +// GetCallerIdentityRequest generates a "aws/request.Request" representing the +// client's request for the GetCallerIdentity operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetCallerIdentity method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetCallerIdentityRequest method. +// req, resp := client.GetCallerIdentityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) { + op := &request.Operation{ + Name: opGetCallerIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetCallerIdentityInput{} + } + + req = c.newRequest(op, input, output) + output = &GetCallerIdentityOutput{} + req.Data = output + return +} + +// Returns details about the IAM identity whose credentials are used to call +// the API. +func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) { + req, out := c.GetCallerIdentityRequest(input) + err := req.Send() + return out, err +} + +const opGetFederationToken = "GetFederationToken" + +// GetFederationTokenRequest generates a "aws/request.Request" representing the +// client's request for the GetFederationToken operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetFederationToken method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetFederationTokenRequest method. +// req, resp := client.GetFederationTokenRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) { + op := &request.Operation{ + Name: opGetFederationToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetFederationTokenInput{} + } + + req = c.newRequest(op, input, output) + output = &GetFederationTokenOutput{} + req.Data = output + return +} + +// Returns a set of temporary security credentials (consisting of an access +// key ID, a secret access key, and a security token) for a federated user. +// A typical use is in a proxy application that gets temporary security credentials +// on behalf of distributed applications inside a corporate network. Because +// you must call the GetFederationToken action using the long-term security +// credentials of an IAM user, this call is appropriate in contexts where those +// credentials can be safely stored, usually in a server-based application. +// For a comparison of GetFederationToken with the other APIs that produce temporary +// credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// If you are creating a mobile-based or browser-based app that can authenticate +// users using a web identity provider like Login with Amazon, Facebook, Google, +// or an OpenID Connect-compatible identity provider, we recommend that you +// use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity. +// For more information, see Federation Through a Web-based Identity Provider +// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// The GetFederationToken action must be called by using the long-term AWS +// security credentials of an IAM user. You can also call GetFederationToken +// using the security credentials of an AWS root account, but we do not recommended +// it. Instead, we recommend that you create an IAM user for the purpose of +// the proxy application and then attach a policy to the IAM user that limits +// federated users to only the actions and resources that they need access to. +// For more information, see IAM Best Practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) +// in the IAM User Guide. +// +// The temporary security credentials that are obtained by using the long-term +// credentials of an IAM user are valid for the specified duration, from 900 +// seconds (15 minutes) up to a maximium of 129600 seconds (36 hours). The default +// is 43200 seconds (12 hours). Temporary credentials that are obtained by using +// AWS root account credentials have a maximum duration of 3600 seconds (1 hour). +// +// The temporary security credentials created by GetFederationToken can be +// used to make API calls to any AWS service with the following exceptions: +// +// You cannot use these credentials to call any IAM APIs. +// +// You cannot call any STS APIs. +// +// Permissions +// +// The permissions for the temporary security credentials returned by GetFederationToken +// are determined by a combination of the following: +// +// The policy or policies that are attached to the IAM user whose credentials +// are used to call GetFederationToken. +// +// The policy that is passed as a parameter in the call. +// +// The passed policy is attached to the temporary security credentials that +// result from the GetFederationToken API call--that is, to the federated user. +// When the federated user makes an AWS request, AWS evaluates the policy attached +// to the federated user in combination with the policy or policies attached +// to the IAM user whose credentials were used to call GetFederationToken. AWS +// allows the federated user's request only when both the federated user and +// the IAM user are explicitly allowed to perform the requested action. The +// passed policy cannot grant more permissions than those that are defined in +// the IAM user policy. +// +// A typical use case is that the permissions of the IAM user whose credentials +// are used to call GetFederationToken are designed to allow access to all the +// actions and resources that any federated user will need. Then, for individual +// users, you pass a policy to the operation that scopes down the permissions +// to a level that's appropriate to that individual user, using a policy that +// allows only a subset of permissions that are granted to the IAM user. +// +// If you do not pass a policy, the resulting temporary security credentials +// have no effective permissions. The only exception is when the temporary security +// credentials are used to access a resource that has a resource-based policy +// that specifically allows the federated user to access the resource. +// +// For more information about how permissions work, see Permissions for GetFederationToken +// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html). +// For information about using GetFederationToken to create temporary security +// credentials, see GetFederationToken—Federation Through a Custom Identity +// Broker (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken). +func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) { + req, out := c.GetFederationTokenRequest(input) + err := req.Send() + return out, err +} + +const opGetSessionToken = "GetSessionToken" + +// GetSessionTokenRequest generates a "aws/request.Request" representing the +// client's request for the GetSessionToken operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetSessionToken method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetSessionTokenRequest method. +// req, resp := client.GetSessionTokenRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) { + op := &request.Operation{ + Name: opGetSessionToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetSessionTokenInput{} + } + + req = c.newRequest(op, input, output) + output = &GetSessionTokenOutput{} + req.Data = output + return +} + +// Returns a set of temporary credentials for an AWS account or IAM user. The +// credentials consist of an access key ID, a secret access key, and a security +// token. Typically, you use GetSessionToken if you want to use MFA to protect +// programmatic calls to specific AWS APIs like Amazon EC2 StopInstances. MFA-enabled +// IAM users would need to call GetSessionToken and submit an MFA code that +// is associated with their MFA device. Using the temporary security credentials +// that are returned from the call, IAM users can then make programmatic calls +// to APIs that require MFA authentication. If you do not supply a correct MFA +// code, then the API returns an access denied error. For a comparison of GetSessionToken +// with the other APIs that produce temporary credentials, see Requesting Temporary +// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The GetSessionToken action must be called by using the long-term AWS security +// credentials of the AWS account or an IAM user. Credentials that are created +// by IAM users are valid for the duration that you specify, from 900 seconds +// (15 minutes) up to a maximum of 129600 seconds (36 hours), with a default +// of 43200 seconds (12 hours); credentials that are created by using account +// credentials can range from 900 seconds (15 minutes) up to a maximum of 3600 +// seconds (1 hour), with a default of 1 hour. +// +// The temporary security credentials created by GetSessionToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// You cannot call any IAM APIs unless MFA authentication information is +// included in the request. +// +// You cannot call any STS API except AssumeRole. +// +// We recommend that you do not call GetSessionToken with root account credentials. +// Instead, follow our best practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users) +// by creating one or more IAM users, giving them the necessary permissions, +// and using IAM users for everyday interaction with AWS. +// +// The permissions associated with the temporary security credentials returned +// by GetSessionToken are based on the permissions associated with account or +// IAM user whose credentials are used to call the action. If GetSessionToken +// is called using root account credentials, the temporary credentials have +// root account permissions. Similarly, if GetSessionToken is called using the +// credentials of an IAM user, the temporary credentials have the same permissions +// as the IAM user. +// +// For more information about using GetSessionToken to create temporary credentials, +// go to Temporary Credentials for Users in Untrusted Environments (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken) +// in the IAM User Guide. +func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) { + req, out := c.GetSessionTokenRequest(input) + err := req.Send() + return out, err +} + +type AssumeRoleInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set + // to 3600 seconds. + // + // This is separate from the duration of a console session that you might + // request using the returned credentials. The request to the federation endpoint + // for a console sign-in token takes a SessionDuration parameter that specifies + // the maximum length of the console session, separately from the DurationSeconds + // parameter on this API. For more information, see Creating a URL that Enables + // Federated Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // A unique identifier that is used by third parties when assuming roles in + // their customers' accounts. For each role that the third party can assume, + // they should instruct their customers to ensure the role's trust policy checks + // for the external ID that the third party generated. Each time the third party + // assumes the role, they should pass the customer's external ID. The external + // ID is useful in order to help third parties bind a role to the customer who + // created it. For more information about the external ID, see How to Use an + // External ID When Granting Access to Your AWS Resources to a Third Party (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) + // in the IAM User Guide. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters consisting of upper- and lower-case alphanumeric characters + // with no spaces. You can also include underscores or any of the following + // characters: =,.@:\/- + ExternalId *string `min:"2" type:"string"` + + // An IAM policy in JSON format. + // + // This parameter is optional. If you pass a policy, the temporary security + // credentials that are returned by the operation have the permissions that + // are allowed by both (the intersection of) the access policy of the role that + // is being assumed, and the policy that you pass. This gives you a way to further + // restrict the permissions for the resulting temporary security credentials. + // You cannot use the passed policy to grant permissions that are in excess + // of those allowed by the access policy of the role that is being assumed. + // For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, + // and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) + // in the IAM User Guide. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) of the role to assume. + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. + // + // Use the role session name to uniquely identify a session when the same role + // is assumed by different principals or for different reasons. In cross-account + // scenarios, the role session name is visible to, and can be logged by the + // account that owns the role. The role session name is also used in the ARN + // of the assumed role principal. This means that subsequent cross-account API + // requests using the temporary security credentials will expose the role session + // name to the external account in their CloudTrail logs. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters consisting of upper- and lower-case alphanumeric characters + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters consisting of upper- and lower-case alphanumeric characters + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- + SerialNumber *string `min:"9" type:"string"` + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.ExternalId != nil && len(*s.ExternalId) < 2 { + invalidParams.Add(request.NewErrParamMinLen("ExternalId", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.RoleSessionName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful AssumeRole request, including temporary +// AWS credentials that can be used to make AWS requests. +type AssumeRoleOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + // As of this writing, the typical size is less than 4096 bytes, but that can + // vary. Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s AssumeRoleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleOutput) GoString() string { + return s.String() +} + +type AssumeRoleWithSAMLInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set + // to 3600 seconds. An expiration can also be specified in the SAML authentication + // response's SessionNotOnOrAfter value. The actual expiration time is whichever + // value is shorter. + // + // This is separate from the duration of a console session that you might + // request using the returned credentials. The request to the federation endpoint + // for a console sign-in token takes a SessionDuration parameter that specifies + // the maximum length of the console session, separately from the DurationSeconds + // parameter on this API. For more information, see Enabling SAML 2.0 Federated + // Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // An IAM policy in JSON format. + // + // The policy parameter is optional. If you pass a policy, the temporary security + // credentials that are returned by the operation have the permissions that + // are allowed by both the access policy of the role that is being assumed, + // and the policy that you pass. This gives you a way to further restrict + // the permissions for the resulting temporary security credentials. You cannot + // use the passed policy to grant permissions that are in excess of those allowed + // by the access policy of the role that is being assumed. For more information, + // Permissions for AssumeRole, AssumeRoleWithSAML, and AssumeRoleWithWebIdentity + // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) + // in the IAM User Guide. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes + // the IdP. + PrincipalArn *string `min:"20" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + RoleArn *string `min:"20" type:"string" required:"true"` + + // The base-64 encoded SAML authentication response provided by the IdP. + // + // For more information, see Configuring a Relying Party and Adding Claims + // (http://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html) + // in the Using IAM guide. + SAMLAssertion *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithSAMLInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.PrincipalArn == nil { + invalidParams.Add(request.NewErrParamRequired("PrincipalArn")) + } + if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("PrincipalArn", 20)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.SAMLAssertion == nil { + invalidParams.Add(request.NewErrParamRequired("SAMLAssertion")) + } + if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 { + invalidParams.Add(request.NewErrParamMinLen("SAMLAssertion", 4)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful AssumeRoleWithSAML request, including +// temporary AWS credentials that can be used to make AWS requests. +type AssumeRoleWithSAMLOutput struct { + _ struct{} `type:"structure"` + + // The identifiers for the temporary security credentials that the operation + // returns. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The value of the Recipient attribute of the SubjectConfirmationData element + // of the SAML assertion. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + // As of this writing, the typical size is less than 4096 bytes, but that can + // vary. Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // The value of the Issuer element of the SAML assertion. + Issuer *string `type:"string"` + + // A hash value based on the concatenation of the Issuer response value, the + // AWS account ID, and the friendly name (the last part of the ARN) of the SAML + // provider in IAM. The combination of NameQualifier and Subject can be used + // to uniquely identify a federated user. + // + // The following pseudocode shows how the hash value is calculated: + // + // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP" + // ) ) + NameQualifier *string `type:"string"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The value of the NameID element in the Subject element of the SAML assertion. + Subject *string `type:"string"` + + // The format of the name ID, as defined by the Format attribute in the NameID + // element of the SAML assertion. Typical examples of the format are transient + // or persistent. + // + // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format, + // that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient + // is returned as transient. If the format includes any other prefix, the format + // is returned with no modifications. + SubjectType *string `type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLOutput) GoString() string { + return s.String() +} + +type AssumeRoleWithWebIdentityInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set + // to 3600 seconds. + // + // This is separate from the duration of a console session that you might + // request using the returned credentials. The request to the federation endpoint + // for a console sign-in token takes a SessionDuration parameter that specifies + // the maximum length of the console session, separately from the DurationSeconds + // parameter on this API. For more information, see Creating a URL that Enables + // Federated Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // An IAM policy in JSON format. + // + // The policy parameter is optional. If you pass a policy, the temporary security + // credentials that are returned by the operation have the permissions that + // are allowed by both the access policy of the role that is being assumed, + // and the policy that you pass. This gives you a way to further restrict + // the permissions for the resulting temporary security credentials. You cannot + // use the passed policy to grant permissions that are in excess of those allowed + // by the access policy of the role that is being assumed. For more information, + // see Permissions for AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) + // in the IAM User Guide. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string `min:"1" type:"string"` + + // The fully qualified host component of the domain name of the identity provider. + // + // Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com + // and graph.facebook.com are the only supported identity providers for OAuth + // 2.0 access tokens. Do not include URL schemes and port numbers. + // + // Do not specify this value for OpenID Connect ID tokens. + ProviderId *string `min:"4" type:"string"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. Typically, you pass the name + // or identifier that is associated with the user who is using your application. + // That way, the temporary security credentials that your application will use + // are associated with that user. This session name is included as part of the + // ARN and assumed role ID in the AssumedRoleUser response element. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters consisting of upper- and lower-case alphanumeric characters + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The OAuth 2.0 access token or OpenID Connect ID token that is provided by + // the identity provider. Your application must get this token by authenticating + // the user who is using your application with a web identity provider before + // the application makes an AssumeRoleWithWebIdentity call. + WebIdentityToken *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithWebIdentityInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.ProviderId != nil && len(*s.ProviderId) < 4 { + invalidParams.Add(request.NewErrParamMinLen("ProviderId", 4)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.RoleSessionName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.WebIdentityToken == nil { + invalidParams.Add(request.NewErrParamRequired("WebIdentityToken")) + } + if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 { + invalidParams.Add(request.NewErrParamMinLen("WebIdentityToken", 4)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful AssumeRoleWithWebIdentity request, +// including temporary AWS credentials that can be used to make AWS requests. +type AssumeRoleWithWebIdentityOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The intended audience (also known as client ID) of the web identity token. + // This is traditionally the client identifier issued to the application that + // requested the web identity token. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security token. + // + // Note: The size of the security token that STS APIs return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + // As of this writing, the typical size is less than 4096 bytes, but that can + // vary. Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The issuing authority of the web identity token presented. For OpenID Connect + // ID Tokens this contains the value of the iss field. For OAuth 2.0 access + // tokens, this contains the value of the ProviderId parameter that was passed + // in the AssumeRoleWithWebIdentity request. + Provider *string `type:"string"` + + // The unique user identifier that is returned by the identity provider. This + // identifier is associated with the WebIdentityToken that was submitted with + // the AssumeRoleWithWebIdentity call. The identifier is typically unique to + // the user and the application that acquired the WebIdentityToken (pairwise + // identifier). For OpenID Connect ID tokens, this field contains the value + // returned by the identity provider as the token's sub (Subject) claim. + SubjectFromWebIdentityToken *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityOutput) GoString() string { + return s.String() +} + +// The identifiers for the temporary security credentials that the operation +// returns. +type AssumedRoleUser struct { + _ struct{} `type:"structure"` + + // The ARN of the temporary security credentials that are returned from the + // AssumeRole action. For more information about ARNs and how to use them in + // policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + Arn *string `min:"20" type:"string" required:"true"` + + // A unique identifier that contains the role ID and the role session name of + // the role that is being assumed. The role ID is generated by AWS when the + // role is created. + AssumedRoleId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumedRoleUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumedRoleUser) GoString() string { + return s.String() +} + +// AWS credentials for API authentication. +type Credentials struct { + _ struct{} `type:"structure"` + + // The access key ID that identifies the temporary security credentials. + AccessKeyId *string `min:"16" type:"string" required:"true"` + + // The date on which the current credentials expire. + Expiration *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The secret access key that can be used to sign requests. + SecretAccessKey *string `type:"string" required:"true"` + + // The token that users must pass to the service API to use the temporary credentials. + SessionToken *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s Credentials) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Credentials) GoString() string { + return s.String() +} + +type DecodeAuthorizationMessageInput struct { + _ struct{} `type:"structure"` + + // The encoded message that was returned with the response. + EncodedMessage *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DecodeAuthorizationMessageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"} + if s.EncodedMessage == nil { + invalidParams.Add(request.NewErrParamRequired("EncodedMessage")) + } + if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 { + invalidParams.Add(request.NewErrParamMinLen("EncodedMessage", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// A document that contains additional information about the authorization status +// of a request from an encoded message that is returned in response to an AWS +// request. +type DecodeAuthorizationMessageOutput struct { + _ struct{} `type:"structure"` + + // An XML document that contains the decoded message. + DecodedMessage *string `type:"string"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageOutput) GoString() string { + return s.String() +} + +// Identifiers for the federated user that is associated with the credentials. +type FederatedUser struct { + _ struct{} `type:"structure"` + + // The ARN that specifies the federated user that is associated with the credentials. + // For more information about ARNs and how to use them in policies, see IAM + // Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + Arn *string `min:"20" type:"string" required:"true"` + + // The string that identifies the federated user associated with the credentials, + // similar to the unique ID of an IAM user. + FederatedUserId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s FederatedUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FederatedUser) GoString() string { + return s.String() +} + +type GetCallerIdentityInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetCallerIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityInput) GoString() string { + return s.String() +} + +// Contains the response to a successful GetCallerIdentity request, including +// information about the entity making the request. +type GetCallerIdentityOutput struct { + _ struct{} `type:"structure"` + + // The AWS account ID number of the account that owns or contains the calling + // entity. + Account *string `type:"string"` + + // The AWS ARN associated with the calling entity. + Arn *string `min:"20" type:"string"` + + // The unique identifier of the calling entity. The exact value depends on the + // type of entity making the call. The values returned are those listed in the + // aws:userid column in the Principal table (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable) + // found on the Policy Variables reference page in the IAM User Guide. + UserId *string `type:"string"` +} + +// String returns the string representation +func (s GetCallerIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityOutput) GoString() string { + return s.String() +} + +type GetFederationTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the session should last. Acceptable durations + // for federation sessions range from 900 seconds (15 minutes) to 129600 seconds + // (36 hours), with 43200 seconds (12 hours) as the default. Sessions obtained + // using AWS account (root) credentials are restricted to a maximum of 3600 + // seconds (one hour). If the specified duration is longer than one hour, the + // session obtained by using AWS account (root) credentials defaults to one + // hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The name of the federated user. The name is used as an identifier for the + // temporary security credentials (such as Bob). For example, you can reference + // the federated user name in a resource-based policy, such as in an Amazon + // S3 bucket policy. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters consisting of upper- and lower-case alphanumeric characters + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- + Name *string `min:"2" type:"string" required:"true"` + + // An IAM policy in JSON format that is passed with the GetFederationToken call + // and evaluated along with the policy or policies that are attached to the + // IAM user whose credentials are used to call GetFederationToken. The passed + // policy is used to scope down the permissions that are available to the IAM + // user, by allowing only a subset of the permissions that are granted to the + // IAM user. The passed policy cannot grant more permissions than those granted + // to the IAM user. The final permissions for the federated user are the most + // restrictive set based on the intersection of the passed policy and the IAM + // user policy. + // + // If you do not pass a policy, the resulting temporary security credentials + // have no effective permissions. The only exception is when the temporary security + // credentials are used to access a resource that has a resource-based policy + // that specifically allows the federated user to access the resource. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + // + // For more information about how permissions work, see Permissions for GetFederationToken + // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html). + Policy *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s GetFederationTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetFederationTokenInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetFederationTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 2 { + invalidParams.Add(request.NewErrParamMinLen("Name", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful GetFederationToken request, including +// temporary AWS credentials that can be used to make AWS requests. +type GetFederationTokenOutput struct { + _ struct{} `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + // As of this writing, the typical size is less than 4096 bytes, but that can + // vary. Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // Identifiers for the federated user associated with the credentials (such + // as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You + // can use the federated user's ARN in your resource-based policies, such as + // an Amazon S3 bucket policy. + FederatedUser *FederatedUser `type:"structure"` + + // A percentage value indicating the size of the policy in packed form. The + // service rejects policies for which the packed size is greater than 100 percent + // of the allowed value. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s GetFederationTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenOutput) GoString() string { + return s.String() +} + +type GetSessionTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the credentials should remain valid. Acceptable + // durations for IAM user sessions range from 900 seconds (15 minutes) to 129600 + // seconds (36 hours), with 43200 seconds (12 hours) as the default. Sessions + // for AWS account owners are restricted to a maximum of 3600 seconds (one hour). + // If the duration is longer than one hour, the session for AWS account owners + // defaults to one hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The identification number of the MFA device that is associated with the IAM + // user who is making the GetSessionToken call. Specify this value if the IAM + // user has a policy that requires MFA authentication. The value is either the + // serial number for a hardware device (such as GAHT12345678) or an Amazon Resource + // Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + // You can find the device for an IAM user by going to the AWS Management Console + // and viewing the user's security credentials. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters consisting of upper- and lower-case alphanumeric characters + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- + SerialNumber *string `min:"9" type:"string"` + + // The value provided by the MFA device, if MFA is required. If any policy requires + // the IAM user to submit an MFA code, specify this value. If MFA authentication + // is required, and the user does not provide a code when requesting a set of + // temporary security credentials, the user will receive an "access denied" + // response when requesting resources that require MFA authentication. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s GetSessionTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetSessionTokenInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetSessionTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful GetSessionToken request, including +// temporary AWS credentials that can be used to make AWS requests. +type GetSessionTokenOutput struct { + _ struct{} `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + // As of this writing, the typical size is less than 4096 bytes, but that can + // vary. Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` +} + +// String returns the string representation +func (s GetSessionTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenOutput) GoString() string { + return s.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go new file mode 100644 index 0000000000..4010cc7fa1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go @@ -0,0 +1,12 @@ +package sts + +import "github.com/aws/aws-sdk-go/aws/request" + +func init() { + initRequest = func(r *request.Request) { + switch r.Operation.Name { + case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity: + r.Handlers.Sign.Clear() // these operations are unsigned + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/service.go b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go new file mode 100644 index 0000000000..c938e6ca11 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go @@ -0,0 +1,130 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +package sts + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/query" +) + +// The AWS Security Token Service (STS) is a web service that enables you to +// request temporary, limited-privilege credentials for AWS Identity and Access +// Management (IAM) users or for users that you authenticate (federated users). +// This guide provides descriptions of the STS API. For more detailed information +// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). +// +// As an alternative to using the API, you can use one of the AWS SDKs, which +// consist of libraries and sample code for various programming languages and +// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient +// way to create programmatic access to STS. For example, the SDKs take care +// of cryptographically signing requests, managing errors, and retrying requests +// automatically. For information about the AWS SDKs, including how to download +// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/). +// +// For information about setting up signatures and authorization through the +// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) +// in the AWS General Reference. For general information about the Query API, +// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) +// in Using IAM. For information about using security tokens with other AWS +// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) +// in the IAM User Guide. +// +// If you're new to AWS and need additional technical information about a specific +// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ +// (http://aws.amazon.com/documentation/). +// +// Endpoints +// +// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com +// that maps to the US East (N. Virginia) region. Additional regions are available +// and are activated by default. For more information, see Activating and Deactivating +// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region) +// in the AWS General Reference. +// +// Recording API requests +// +// STS supports AWS CloudTrail, which is a service that records AWS calls for +// your AWS account and delivers log files to an Amazon S3 bucket. By using +// information collected by CloudTrail, you can determine what requests were +// successfully made to STS, who made the request, when it was made, and so +// on. To learn more about CloudTrail, including how to turn it on and find +// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). +//The service client's operations are safe to be used concurrently. +// It is not safe to mutate any of the client's properties though. +type STS struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// A ServiceName is the name of the service the client will make API calls to. +const ServiceName = "sts" + +// New creates a new instance of the STS client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a STS client from just a session. +// svc := sts.New(mySession) +// +// // Create a STS client with additional configuration +// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS { + c := p.ClientConfig(ServiceName, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *STS { + svc := &STS{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2011-06-15", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(query.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a STS operation and runs any +// custom request initialization. +func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/.travis.yml b/vendor/github.com/bugsnag/bugsnag-go/.travis.yml new file mode 100644 index 0000000000..0d567658c6 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/.travis.yml @@ -0,0 +1,11 @@ +sudo: false +language: go + +go: + - 1.3 + - 1.4 + - 1.5 + - tip + +script: + - make ci diff --git a/vendor/github.com/bugsnag/bugsnag-go/CHANGELOG.md b/vendor/github.com/bugsnag/bugsnag-go/CHANGELOG.md new file mode 100644 index 0000000000..79f736f00f --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/CHANGELOG.md @@ -0,0 +1,22 @@ +1.0.4 +----- + +- Fix appengine integration broken by 1.0.3 + +1.0.3 +----- + +- Allow any Logger with a Printf method. + +1.0.2 +----- + +- Use bugsnag copies of dependencies to avoid potential link rot + +1.0.1 +----- + +- gofmt/golint/govet docs improvements. + +1.0.0 +----- diff --git a/vendor/github.com/bugsnag/bugsnag-go/CONTRIBUTING.md b/vendor/github.com/bugsnag/bugsnag-go/CONTRIBUTING.md new file mode 100644 index 0000000000..a665b401e6 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/CONTRIBUTING.md @@ -0,0 +1,78 @@ +Contributing +============ + +- [Fork](https://help.github.com/articles/fork-a-repo) the [notifier on github](https://github.com/bugsnag/bugsnag-go) +- Build and test your changes +- Commit and push until you are happy with your contribution +- [Make a pull request](https://help.github.com/articles/using-pull-requests) +- Thanks! + + +Installing the go development environment +------------------------------------- + +1. Install homebrew + + ``` + ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)" + ``` + +1. Install go + + ``` + brew install go --cross-compile-all + ``` + +1. Configure `$GOPATH` in `~/.bashrc` + + ``` + export GOPATH="$HOME/go" + export PATH=$PATH:$GOPATH/bin + ``` + +Installing the appengine development environment +------------------------------------------------ + +1. Follow the [Google instructions](https://cloud.google.com/appengine/downloads). + +Downloading the code +-------------------- + +You can download the code and its dependencies using + +``` +go get -t github.com/bugsnag/bugsnag-go +``` + +It will be put into "$GOPATH/src/github.com/bugsnag/bugsnag-go" + +Then install depend + + +Running Tests +------------- + +You can run the tests with + +```shell +go test +``` + +If you've made significant changes, please also test the appengine integration with + +```shell +goapp test +``` + +Releasing a New Version +----------------------- + +If you are a project maintainer, you can build and release a new version of +`bugsnag-go` as follows: + +1. Commit all your changes. +2. Update the version number in `bugsnag.go`. +3. Add an entry to `CHANGELOG.md` and update the README if necessary. +4. commit tag and push + + git commit -mv1.0.x && git tag v1.0.x && git push origin v1.0.x diff --git a/vendor/github.com/bugsnag/bugsnag-go/LICENSE.txt b/vendor/github.com/bugsnag/bugsnag-go/LICENSE.txt new file mode 100644 index 0000000000..3cb0ec0fff --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2014 Bugsnag + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/bugsnag/bugsnag-go/Makefile b/vendor/github.com/bugsnag/bugsnag-go/Makefile new file mode 100644 index 0000000000..70ec732320 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/Makefile @@ -0,0 +1,30 @@ +TEST?=./... + +default: alldeps test + +deps: + go get -v -d ./... + +alldeps: + go get -v -d -t ./... + +updatedeps: + go get -v -d -u ./... + +test: alldeps + go test + @go vet 2>/dev/null ; if [ $$? -eq 3 ]; then \ + go get golang.org/x/tools/cmd/vet; \ + fi + @go vet $(TEST) ; if [ $$? -eq 1 ]; then \ + echo "go-vet: Issues running go vet ./..."; \ + exit 1; \ + fi + +ci: alldeps test + +bench: + go test --bench=.* + + +.PHONY: bin checkversion ci default deps generate releasebin test testacc testrace updatedeps diff --git a/vendor/github.com/bugsnag/bugsnag-go/README.md b/vendor/github.com/bugsnag/bugsnag-go/README.md new file mode 100644 index 0000000000..60ddc9976e --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/README.md @@ -0,0 +1,553 @@ +# Bugsnag Notifier for Golang +[![Latest Version](http://img.shields.io/github/release/bugsnag/bugsnag-go.svg?style=flat-square)](https://github.com/bugsnag/bugsnag-go/releases) +[![Build Status](https://travis-ci.org/bugsnag/bugsnag-go.svg)](https://travis-ci.org/bugsnag/bugsnag-go) +[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/bugsnag/bugsnag-go) + +The Bugsnag Notifier for Golang gives you instant notification of panics, or +unexpected errors, in your golang app. Any unhandled panics will trigger a +notification to be sent to your Bugsnag project. + +[Bugsnag](http://bugsnag.com) captures errors in real-time from your web, +mobile and desktop applications, helping you to understand and resolve them +as fast as possible. [Create a free account](http://bugsnag.com) to start +capturing exceptions from your applications. + +## How to Install + +1. Download the code + + ```shell + go get github.com/bugsnag/bugsnag-go + ``` + +### Using with net/http apps + +For a golang app based on [net/http](https://godoc.org/net/http), integrating +Bugsnag takes two steps. You should also use these instructions if you're using +the [gorilla toolkit](http://www.gorillatoolkit.org/), or the +[pat](https://github.com/bmizerany/pat/) muxer. + +1. Configure bugsnag at the start of your `main()` function: + + ```go + import "github.com/bugsnag/bugsnag-go" + + func main() { + bugsnag.Configure(bugsnag.Configuration{ + APIKey: "YOUR_API_KEY_HERE", + ReleaseStage: "production", + // more configuration options + }) + + // rest of your program. + } + ``` + +2. Wrap your server in a [bugsnag.Handler](https://godoc.org/github.com/bugsnag/bugsnag-go/#Handler) + + ```go + // a. If you're using the builtin http mux, you can just pass + // bugsnag.Handler(nil) to http.ListenAndServer + http.ListenAndServe(":8080", bugsnag.Handler(nil)) + + // b. If you're creating a server manually yourself, you can set + // its handlers the same way + srv := http.Server{ + Handler: bugsnag.Handler(nil) + } + + // c. If you're not using the builtin http mux, wrap your own handler + // (though make sure that it doesn't already catch panics) + http.ListenAndServe(":8080", bugsnag.Handler(handler)) + ``` + +### Using with Revel apps + +There are two steps to get panic handling in [revel](https://revel.github.io) apps. + +1. Add the `bugsnagrevel.Filter` immediately after the `revel.PanicFilter` in `app/init.go`: + + ```go + + import "github.com/bugsnag/bugsnag-go/revel" + + revel.Filters = []revel.Filter{ + revel.PanicFilter, + bugsnagrevel.Filter, + // ... + } + ``` + +2. Set bugsnag.apikey in the top section of `conf/app.conf`. + + ``` + module.static=github.com/revel/revel/modules/static + + bugsnag.apikey=YOUR_API_KEY_HERE + + [dev] + ``` + +### Using with martini apps + +1. Add `bugsnagmartini.AutoNotify` immediately after the `martini.Recovery` middleware in `main.go`. +This causes unhandled panics to notify bugsnag. + + ```go + + import "github.com/bugsnag/bugsnag-go/martini" + + func main() { + + m.Use(martini.Recover() + + m.Use(bugsnagmartini.AutoNotify(bugsnag.Configuration{ + APIKey: "YOUR_API_KEY_HERE", + })) + } + ``` + +2. Use `bugsnag` from the context injection if you need to notify about non-fatal errors. + + ``` + func MyHandler(r *http.Request, bugsnag *bugsnag.Notifier) string { + bugsnag.Notify(err); + } + ``` + +### Using with Google App Engine + +1. Configure bugsnag at the start of your `init()` function: + + ```go + import "github.com/bugsnag/bugsnag-go" + + func init() { + bugsnag.Configure(bugsnag.Configuration{ + APIKey: "YOUR_API_KEY_HERE", + }) + + // ... + } + ``` + +2. Wrap *every* http.Handler or http.HandlerFunc with Bugsnag: + + ```go + // a. If you're using HandlerFuncs + http.HandleFunc("/", bugsnag.HandlerFunc( + func (w http.ResponseWriter, r *http.Request) { + // ... + })) + + // b. If you're using Handlers + http.Handle("/", bugsnag.Handler(myHttpHandler)) + ``` + +3. In order to use Bugsnag, you must provide the current +[`appengine.Context`](https://developers.google.com/appengine/docs/go/reference#Context), or +current `*http.Request` as rawData (This is done automatically for `bugsnag.Handler` and `bugsnag.HandlerFunc`). +The easiest way to do this is to create a new instance of the notifier. + + ```go + c := appengine.NewContext(r) + notifier := bugsnag.New(c) + + if err != nil { + notifier.Notify(err) + } + + go func () { + defer notifier.Recover() + + // ... + }() + ``` + + +## Notifying Bugsnag manually + +Bugsnag will automatically handle any panics that crash your program and notify +you of them. If you've integrated with `revel` or `net/http`, then you'll also +be notified of any panics() that happen while processing a request. + +Sometimes however it's useful to manually notify Bugsnag of a problem. To do this, +call [`bugsnag.Notify()`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Notify) + +```go +if err != nil { + bugsnag.Notify(err) +} +``` + +### Manual panic handling + +To avoid a panic in a goroutine from crashing your entire app, you can use +[`bugsnag.Recover()`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Recover) +to stop a panic from unwinding the stack any further. When `Recover()` is hit, +it will send any current panic to Bugsnag and then stop panicking. This is +most useful at the start of a goroutine: + +```go +go func() { + defer bugsnag.Recover() + + // ... +}() +``` + +Alternatively you can use +[`bugsnag.AutoNotify()`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Recover) +to notify bugsnag of a panic while letting the program continue to panic. This +is useful if you're using a Framework that already has some handling of panics +and you are retrofitting bugsnag support. + +```go +defer bugsnag.AutoNotify() +``` + +## Sending Custom Data + +Most functions in the Bugsnag API, including `bugsnag.Notify()`, +`bugsnag.Recover()`, `bugsnag.AutoNotify()`, and `bugsnag.Handler()` let you +attach data to the notifications that they send. To do this you pass in rawData, +which can be any of the supported types listed here. To add support for more +types of rawData see [OnBeforeNotify](#custom-data-with-onbeforenotify). + +### Custom MetaData + +Custom metaData appears as tabs on Bugsnag.com. You can set it by passing +a [`bugsnag.MetaData`](https://godoc.org/github.com/bugsnag/bugsnag-go/#MetaData) +object as rawData. + +```go +bugsnag.Notify(err, + bugsnag.MetaData{ + "Account": { + "Name": Account.Name, + "Paying": Account.Plan.Premium, + }, + }) +``` + +### Request data + +Bugsnag can extract interesting data from +[`*http.Request`](https://godoc.org/net/http/#Request) objects, and +[`*revel.Controller`](https://godoc.org/github.com/revel/revel/#Controller) +objects. These are automatically passed in when handling panics, and you can +pass them yourself. + +```go +func (w http.ResponseWriter, r *http.Request) { + bugsnag.Notify(err, r) +} +``` + +### User data + +User data is searchable, and the `Id` powers the count of users affected. You +can set which user an error affects by passing a +[`bugsnag.User`](https://godoc.org/github.com/bugsnag/bugsnag-go/#User) object as +rawData. + +```go +bugsnag.Notify(err, + bugsnag.User{Id: "1234", Name: "Conrad", Email: "me@cirw.in"}) +``` + +### Error Class + +Errors in your Bugsnag dashboard are grouped by their "error class" and by line number. +You can override the error class by passing a +[`bugsnag.ErrorClass`](https://godoc.org/github.com/bugsnag/bugsnag-go/#ErrorClass) object as +rawData. + +```go +bugsnag.Notify(err, bugsnag.ErrorClass{"I/O Timeout"}) +``` + +### Context + +The context shows up prominently in the list view so that you can get an idea +of where a problem occurred. You can set it by passing a +[`bugsnag.Context`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Context) +object as rawData. + +```go +bugsnag.Notify(err, bugsnag.Context{"backgroundJob"}) +``` + +### Severity + +Bugsnag supports three severities, `SeverityError`, `SeverityWarning`, and `SeverityInfo`. +You can set the severity of an error by passing one of these objects as rawData. + +```go +bugsnag.Notify(err, bugsnag.SeverityInfo) +``` + +## Configuration + +You must call `bugsnag.Configure()` at the start of your program to use Bugsnag, you pass it +a [`bugsnag.Configuration`](https://godoc.org/github.com/bugsnag/bugsnag-go/#Configuration) object +containing any of the following values. + +### APIKey + +The Bugsnag API key can be found on your [Bugsnag dashboard](https://bugsnag.com) under "Settings". + +```go +bugsnag.Configure(bugsnag.Configuration{ + APIKey: "YOUR_API_KEY_HERE", +}) +``` + +### Endpoint + +The Bugsnag endpoint defaults to `https://notify.bugsnag.com/`. If you're using Bugsnag enterprise, +you should set this to the endpoint of your local instance. + +```go +bugsnag.Configure(bugsnag.Configuration{ + Endpoint: "http://bugsnag.internal:49000/", +}) +``` + +### ReleaseStage + +The ReleaseStage tracks where your app is deployed. You should set this to `production`, `staging`, +`development` or similar as appropriate. + +```go +bugsnag.Configure(bugsnag.Configuration{ + ReleaseStage: "development", +}) +``` + +### NotifyReleaseStages + +The list of ReleaseStages to notify in. By default Bugsnag will notify you in all release stages, but +you can use this to silence development errors. + +```go +bugsnag.Configure(bugsnag.Configuration{ + NotifyReleaseStages: []string{"production", "staging"}, +}) +``` + +### AppVersion + +If you use a versioning scheme for deploys of your app, Bugsnag can use the `AppVersion` to only +re-open errors if they occur in later version of the app. + +```go +bugsnag.Configure(bugsnag.Configuration{ + AppVersion: "1.2.3", +}) +``` + +### Hostname + +The hostname is used to track where exceptions are coming from in the Bugsnag dashboard. The +default value is obtained from `os.Hostname()` so you won't often need to change this. + +```go +bugsnag.Configure(bugsnag.Configuration{ + Hostname: "go1", +}) +``` + +### ProjectPackages + +In order to determine where a crash happens Bugsnag needs to know which packages you consider to +be part of your app (as opposed to a library). By default this is set to `[]string{"main*"}`. Strings +are matched to package names using [`filepath.Match`](http://godoc.org/path/filepath#Match). + +For matching subpackages within a package you may use the `**` notation. For example, `github.com/domain/package/**` will match all subpackages under `package/`. + +```go +bugsnag.Configure(bugsnag.Configuration{ + ProjectPackages: []string{"main", "github.com/domain/myapp/*"}, +} +``` + +### ParamsFilters + +Sometimes sensitive data is accidentally included in Bugsnag MetaData. You can remove it by +setting `ParamsFilters`. Any key in the `MetaData` that includes any string in the filters +will be redacted. The default is `[]string{"password", "secret"}`, which prevents fields like +`password`, `password_confirmation` and `secret_answer` from being sent. + +```go +bugsnag.Configure(bugsnag.Configuration{ + ParamsFilters: []string{"password", "secret"}, +} +``` + +### Logger + +The Logger to write to in case of an error inside Bugsnag. This defaults to the global logger. + +```go +bugsnag.Configure(bugsnag.Configuration{ + Logger: app.Logger, +} +``` + +### PanicHandler + +The first time Bugsnag is configured, it wraps the running program in a panic +handler using [panicwrap](http://godoc.org/github.com/ConradIrwin/panicwrap). This +forks a sub-process which monitors unhandled panics. To prevent this, set +`PanicHandler` to `func() {}` the first time you call +`bugsnag.Configure`. This will prevent bugsnag from being able to notify you about +unhandled panics. + +```go +bugsnag.Configure(bugsnag.Configuration{ + PanicHandler: func() {}, +}) +``` + +### Synchronous + +Bugsnag usually starts a new goroutine before sending notifications. This means +that notifications can be lost if you do a bugsnag.Notify and then immediately +os.Exit. To avoid this problem, set Bugsnag to Synchronous (or just `panic()` +instead ;). + +```go +bugsnag.Configure(bugsnag.Configuration{ + Synchronous: true +}) +``` + +Or just for one error: + +```go +bugsnag.Notify(err, bugsnag.Configuration{Synchronous: true}) +``` + +### Transport + +The transport configures how Bugsnag makes http requests. By default we use +[`http.DefaultTransport`](http://godoc.org/net/http#RoundTripper) which handles +HTTP proxies automatically using the `$HTTP_PROXY` environment variable. + +```go +bugsnag.Configure(bugsnag.Configuration{ + Transport: http.DefaultTransport, +}) +``` + +## Custom data with OnBeforeNotify + +While it's nice that you can pass `MetaData` directly into `bugsnag.Notify`, +`bugsnag.AutoNotify`, and `bugsnag.Recover`, this can be a bit cumbersome and +inefficient — you're constructing the meta-data whether or not it will actually +be used. A better idea is to pass raw data in to these functions, and add an +`OnBeforeNotify` filter that converts them into `MetaData`. + +For example, lets say our system processes jobs: + +```go +type Job struct{ + Retry bool + UserId string + UserEmail string + Name string + Params map[string]string +} +``` + +You can pass a job directly into Bugsnag.notify: + +```go +bugsnag.Notify(err, job) +``` + +And then add a filter to extract information from that job and attach it to the +Bugsnag event: + +```go +bugsnag.OnBeforeNotify( + func(event *bugsnag.Event, config *bugsnag.Configuration) error { + + // Search all the RawData for any *Job pointers that we're passed in + // to bugsnag.Notify() and friends. + for _, datum := range event.RawData { + if job, ok := datum.(*Job); ok { + // don't notify bugsnag about errors in retries + if job.Retry { + return fmt.Errorf("not notifying about retried jobs") + } + + // add the job as a tab on Bugsnag.com + event.MetaData.AddStruct("Job", job) + + // set the user correctly + event.User = &User{Id: job.UserId, Email: job.UserEmail} + } + } + + // continue notifying as normal + return nil + }) +``` + +## Advanced Usage + +If you want to have multiple different configurations around in one program, +you can use `bugsnag.New()` to create multiple independent instances of +Bugsnag. You can use these without calling `bugsnag.Configure()`, but bear in +mind that until you call `bugsnag.Configure()` unhandled panics will not be +sent to bugsnag. + +```go +notifier := bugsnag.New(bugsnag.Configuration{ + APIKey: "YOUR_OTHER_API_KEY", +}) +``` + +In fact any place that lets you pass in `rawData` also allows you to pass in +configuration. For example to send http errors to one bugsnag project, you +could do: + +```go +bugsnag.Handler(nil, bugsnag.Configuration{APIKey: "YOUR_OTHER_API_KEY"}) +``` + +### GroupingHash + +If you need to override Bugsnag's grouping algorithm, you can set the +`GroupingHash` in an `OnBeforeNotify`: + +```go +bugsnag.OnBeforeNotify( + func (event *bugsnag.Event, config *bugsnag.Configuration) error { + event.GroupingHash = calculateGroupingHash(event) + return nil + }) +``` + +### Skipping lines in stacktrace + +If you have your own logging wrapper all of your errors will appear to +originate from inside it. You can avoid this problem by constructing +an error with a stacktrace manually, and then passing that to Bugsnag.notify: + +```go +import ( + "github.com/bugsnag/bugsnag-go" + "github.com/bugsnag/bugsnag-go/errors" +) + +func LogError(e error) { + // 1 removes one line of stacktrace, so the caller of LogError + // will be at the top. + e = errors.New(e, 1) + bugsnag.Notify(e) +} +``` + diff --git a/vendor/github.com/bugsnag/bugsnag-go/appengine.go b/vendor/github.com/bugsnag/bugsnag-go/appengine.go new file mode 100644 index 0000000000..81e25069cb --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/appengine.go @@ -0,0 +1,81 @@ +// +build appengine + +package bugsnag + +import ( + "appengine" + "appengine/urlfetch" + "appengine/user" + "fmt" + "log" + "net/http" +) + +func defaultPanicHandler() {} + +func init() { + OnBeforeNotify(appengineMiddleware) +} + +func appengineMiddleware(event *Event, config *Configuration) (err error) { + var c appengine.Context + + for _, datum := range event.RawData { + if r, ok := datum.(*http.Request); ok { + c = appengine.NewContext(r) + break + } else if context, ok := datum.(appengine.Context); ok { + c = context + break + } + } + + if c == nil { + return fmt.Errorf("No appengine context given") + } + + // You can only use the builtin http library if you pay for appengine, + // so we use the appengine urlfetch service instead. + config.Transport = &urlfetch.Transport{ + Context: c, + } + + // Anything written to stderr/stdout is discarded, so lets log to the request. + + if configuredLogger, ok := config.Logger.(*log.Logger); ok { + config.Logger = log.New(appengineWriter{c}, configuredLogger.Prefix(), configuredLogger.Flags()) + } else { + config.Logger = log.New(appengineWriter{c}, log.Prefix(), log.Flags()) + } + + // Set the releaseStage appropriately + if config.ReleaseStage == "" { + if appengine.IsDevAppServer() { + config.ReleaseStage = "development" + } else { + config.ReleaseStage = "production" + } + } + + if event.User == nil { + u := user.Current(c) + if u != nil { + event.User = &User{ + Id: u.ID, + Email: u.Email, + } + } + } + + return nil +} + +// Convert an appengine.Context into an io.Writer so we can create a log.Logger. +type appengineWriter struct { + appengine.Context +} + +func (c appengineWriter) Write(b []byte) (int, error) { + c.Warningf(string(b)) + return len(b), nil +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/bugsnag.go b/vendor/github.com/bugsnag/bugsnag-go/bugsnag.go new file mode 100644 index 0000000000..e9bbf4656a --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/bugsnag.go @@ -0,0 +1,131 @@ +package bugsnag + +import ( + "github.com/bugsnag/bugsnag-go/errors" + "log" + "net/http" + "os" + "sync" + + // Fixes a bug with SHA-384 intermediate certs on some platforms. + // - https://github.com/bugsnag/bugsnag-go/issues/9 + _ "crypto/sha512" +) + +// The current version of bugsnag-go. +const VERSION = "1.0.3" + +var once sync.Once +var middleware middlewareStack + +// The configuration for the default bugsnag notifier. +var Config Configuration + +var defaultNotifier = Notifier{&Config, nil} + +// Configure Bugsnag. The only required setting is the APIKey, which can be +// obtained by clicking on "Settings" in your Bugsnag dashboard. This function +// is also responsible for installing the global panic handler, so it should be +// called as early as possible in your initialization process. +func Configure(config Configuration) { + Config.update(&config) + once.Do(Config.PanicHandler) +} + +// Notify sends an error to Bugsnag along with the current stack trace. The +// rawData is used to send extra information along with the error. For example +// you can pass the current http.Request to Bugsnag to see information about it +// in the dashboard, or set the severity of the notification. +func Notify(err error, rawData ...interface{}) error { + return defaultNotifier.Notify(errors.New(err, 1), rawData...) +} + +// AutoNotify logs a panic on a goroutine and then repanics. +// It should only be used in places that have existing panic handlers further +// up the stack. See bugsnag.Recover(). The rawData is used to send extra +// information along with any panics that are handled this way. +// Usage: defer bugsnag.AutoNotify() +func AutoNotify(rawData ...interface{}) { + if err := recover(); err != nil { + rawData = defaultNotifier.addDefaultSeverity(rawData, SeverityError) + defaultNotifier.Notify(errors.New(err, 2), rawData...) + panic(err) + } +} + +// Recover logs a panic on a goroutine and then recovers. +// The rawData is used to send extra information along with +// any panics that are handled this way +// Usage: defer bugsnag.Recover() +func Recover(rawData ...interface{}) { + if err := recover(); err != nil { + rawData = defaultNotifier.addDefaultSeverity(rawData, SeverityWarning) + defaultNotifier.Notify(errors.New(err, 2), rawData...) + } +} + +// OnBeforeNotify adds a callback to be run before a notification is sent to +// Bugsnag. It can be used to modify the event or its MetaData. Changes made +// to the configuration are local to notifying about this event. To prevent the +// event from being sent to Bugsnag return an error, this error will be +// returned from bugsnag.Notify() and the event will not be sent. +func OnBeforeNotify(callback func(event *Event, config *Configuration) error) { + middleware.OnBeforeNotify(callback) +} + +// Handler creates an http Handler that notifies Bugsnag any panics that +// happen. It then repanics so that the default http Server panic handler can +// handle the panic too. The rawData is used to send extra information along +// with any panics that are handled this way. +func Handler(h http.Handler, rawData ...interface{}) http.Handler { + notifier := New(rawData...) + if h == nil { + h = http.DefaultServeMux + } + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer notifier.AutoNotify(r) + h.ServeHTTP(w, r) + }) +} + +// HandlerFunc creates an http HandlerFunc that notifies Bugsnag about any +// panics that happen. It then repanics so that the default http Server panic +// handler can handle the panic too. The rawData is used to send extra +// information along with any panics that are handled this way. If you have +// already wrapped your http server using bugsnag.Handler() you don't also need +// to wrap each HandlerFunc. +func HandlerFunc(h http.HandlerFunc, rawData ...interface{}) http.HandlerFunc { + notifier := New(rawData...) + + return func(w http.ResponseWriter, r *http.Request) { + defer notifier.AutoNotify(r) + h(w, r) + } +} + +func init() { + // Set up builtin middlewarez + OnBeforeNotify(httpRequestMiddleware) + + // Default configuration + Config.update(&Configuration{ + APIKey: "", + Endpoint: "https://notify.bugsnag.com/", + Hostname: "", + AppVersion: "", + ReleaseStage: "", + ParamsFilters: []string{"password", "secret"}, + // * for app-engine + ProjectPackages: []string{"main*"}, + NotifyReleaseStages: nil, + Logger: log.New(os.Stdout, log.Prefix(), log.Flags()), + PanicHandler: defaultPanicHandler, + Transport: http.DefaultTransport, + }) + + hostname, err := os.Hostname() + if err == nil { + Config.Hostname = hostname + } +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/configuration.go b/vendor/github.com/bugsnag/bugsnag-go/configuration.go new file mode 100644 index 0000000000..ad1d42db9c --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/configuration.go @@ -0,0 +1,169 @@ +package bugsnag + +import ( + "log" + "net/http" + "path/filepath" + "strings" +) + +// Configuration sets up and customizes communication with the Bugsnag API. +type Configuration struct { + // Your Bugsnag API key, e.g. "c9d60ae4c7e70c4b6c4ebd3e8056d2b8". You can + // find this by clicking Settings on https://bugsnag.com/. + APIKey string + // The Endpoint to notify about crashes. This defaults to + // "https://notify.bugsnag.com/", if you're using Bugsnag Enterprise then + // set it to your internal Bugsnag endpoint. + Endpoint string + + // The current release stage. This defaults to "production" and is used to + // filter errors in the Bugsnag dashboard. + ReleaseStage string + // The currently running version of the app. This is used to filter errors + // in the Bugsnag dasboard. If you set this then Bugsnag will only re-open + // resolved errors if they happen in different app versions. + AppVersion string + // The hostname of the current server. This defaults to the return value of + // os.Hostname() and is graphed in the Bugsnag dashboard. + Hostname string + + // The Release stages to notify in. If you set this then bugsnag-go will + // only send notifications to Bugsnag if the ReleaseStage is listed here. + NotifyReleaseStages []string + + // packages that are part of your app. Bugsnag uses this to determine how + // to group errors and how to display them on your dashboard. You should + // include any packages that are part of your app, and exclude libraries + // and helpers. You can list wildcards here, and they'll be expanded using + // filepath.Glob. The default value is []string{"main*"} + ProjectPackages []string + + // Any meta-data that matches these filters will be marked as [REDACTED] + // before sending a Notification to Bugsnag. It defaults to + // []string{"password", "secret"} so that request parameters like password, + // password_confirmation and auth_secret will not be sent to Bugsnag. + ParamsFilters []string + + // The PanicHandler is used by Bugsnag to catch unhandled panics in your + // application. The default panicHandler uses mitchellh's panicwrap library, + // and you can disable this feature by passing an empty: func() {} + PanicHandler func() + + // The logger that Bugsnag should log to. Uses the same defaults as go's + // builtin logging package. bugsnag-go logs whenever it notifies Bugsnag + // of an error, and when any error occurs inside the library itself. + Logger interface { + Printf(format string, v ...interface{}) // limited to the functions used + } + // The http Transport to use, defaults to the default http Transport. This + // can be configured if you are in an environment like Google App Engine + // that has stringent conditions on making http requests. + Transport http.RoundTripper + // Whether bugsnag should notify synchronously. This defaults to false which + // causes bugsnag-go to spawn a new goroutine for each notification. + Synchronous bool + // TODO: remember to update the update() function when modifying this struct +} + +func (config *Configuration) update(other *Configuration) *Configuration { + if other.APIKey != "" { + config.APIKey = other.APIKey + } + if other.Endpoint != "" { + config.Endpoint = other.Endpoint + } + if other.Hostname != "" { + config.Hostname = other.Hostname + } + if other.AppVersion != "" { + config.AppVersion = other.AppVersion + } + if other.ReleaseStage != "" { + config.ReleaseStage = other.ReleaseStage + } + if other.ParamsFilters != nil { + config.ParamsFilters = other.ParamsFilters + } + if other.ProjectPackages != nil { + config.ProjectPackages = other.ProjectPackages + } + if other.Logger != nil { + config.Logger = other.Logger + } + if other.NotifyReleaseStages != nil { + config.NotifyReleaseStages = other.NotifyReleaseStages + } + if other.PanicHandler != nil { + config.PanicHandler = other.PanicHandler + } + if other.Transport != nil { + config.Transport = other.Transport + } + if other.Synchronous { + config.Synchronous = true + } + + return config +} + +func (config *Configuration) merge(other *Configuration) *Configuration { + return config.clone().update(other) +} + +func (config *Configuration) clone() *Configuration { + clone := *config + return &clone +} + +func (config *Configuration) isProjectPackage(pkg string) bool { + for _, p := range config.ProjectPackages { + if d, f := filepath.Split(p); f == "**" { + if strings.HasPrefix(pkg, d) { + return true + } + } + + if match, _ := filepath.Match(p, pkg); match { + return true + } + } + return false +} + +func (config *Configuration) stripProjectPackages(file string) string { + for _, p := range config.ProjectPackages { + if len(p) > 2 && p[len(p)-2] == '/' && p[len(p)-1] == '*' { + p = p[:len(p)-1] + } else if p[len(p)-1] == '*' && p[len(p)-2] == '*' { + p = p[:len(p)-2] + } else { + p = p + "/" + } + if strings.HasPrefix(file, p) { + return strings.TrimPrefix(file, p) + } + } + + return file +} + +func (config *Configuration) logf(fmt string, args ...interface{}) { + if config != nil && config.Logger != nil { + config.Logger.Printf(fmt, args...) + } else { + log.Printf(fmt, args...) + } +} + +func (config *Configuration) notifyInReleaseStage() bool { + if config.NotifyReleaseStages == nil { + return true + } + for _, r := range config.NotifyReleaseStages { + if r == config.ReleaseStage { + return true + } + } + return false +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/doc.go b/vendor/github.com/bugsnag/bugsnag-go/doc.go new file mode 100644 index 0000000000..827e03b8be --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/doc.go @@ -0,0 +1,69 @@ +/* +Package bugsnag captures errors in real-time and reports them to Bugsnag (http://bugsnag.com). + +Using bugsnag-go is a three-step process. + +1. As early as possible in your program configure the notifier with your APIKey. This sets up +handling of panics that would otherwise crash your app. + + func init() { + bugsnag.Configure(bugsnag.Configuration{ + APIKey: "YOUR_API_KEY_HERE", + }) + } + +2. Add bugsnag to places that already catch panics. For example you should add it to the HTTP server +when you call ListenAndServer: + + http.ListenAndServe(":8080", bugsnag.Handler(nil)) + +If that's not possible, for example because you're using Google App Engine, you can also wrap each +HTTP handler manually: + + http.HandleFunc("/" bugsnag.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { + ... + }) + +3. To notify Bugsnag of an error that is not a panic, pass it to bugsnag.Notify. This will also +log the error message using the configured Logger. + + if err != nil { + bugsnag.Notify(err) + } + +For detailed integration instructions see https://bugsnag.com/docs/notifiers/go. + +Configuration + +The only required configuration is the Bugsnag API key which can be obtained by clicking "Settings" +on the top of https://bugsnag.com/ after signing up. We also recommend you set the ReleaseStage +and AppVersion if these make sense for your deployment workflow. + +RawData + +If you need to attach extra data to Bugsnag notifications you can do that using +the rawData mechanism. Most of the functions that send errors to Bugsnag allow +you to pass in any number of interface{} values as rawData. The rawData can +consist of the Severity, Context, User or MetaData types listed below, and +there is also builtin support for *http.Requests. + + bugsnag.Notify(err, bugsnag.SeverityError) + +If you want to add custom tabs to your bugsnag dashboard you can pass any value in as rawData, +and then process it into the event's metadata using a bugsnag.OnBeforeNotify() hook. + + bugsnag.Notify(err, account) + + bugsnag.OnBeforeNotify(func (e *bugsnag.Event, c *bugsnag.Configuration) { + for datum := range e.RawData { + if account, ok := datum.(Account); ok { + e.MetaData.Add("account", "name", account.Name) + e.MetaData.Add("account", "url", account.URL) + } + } + }) + +If necessary you can pass Configuration in as rawData, or modify the Configuration object passed +into OnBeforeNotify hooks. Configuration passed in this way only affects the current notification. +*/ +package bugsnag diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/README.md b/vendor/github.com/bugsnag/bugsnag-go/errors/README.md new file mode 100644 index 0000000000..8d8e097aa7 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/errors/README.md @@ -0,0 +1,6 @@ +Adds stacktraces to errors in golang. + +This was made to help build the Bugsnag notifier but can be used standalone if +you like to have stacktraces on errors. + +See [Godoc](https://godoc.org/github.com/bugsnag/bugsnag-go/errors) for the API docs. diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/error.go b/vendor/github.com/bugsnag/bugsnag-go/errors/error.go new file mode 100644 index 0000000000..0081c0a80c --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/errors/error.go @@ -0,0 +1,90 @@ +// Package errors provides errors that have stack-traces. +package errors + +import ( + "bytes" + "fmt" + "reflect" + "runtime" +) + +// The maximum number of stackframes on any error. +var MaxStackDepth = 50 + +// Error is an error with an attached stacktrace. It can be used +// wherever the builtin error interface is expected. +type Error struct { + Err error + stack []uintptr + frames []StackFrame +} + +// New makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The skip parameter indicates how far up the stack +// to start the stacktrace. 0 is from the current call, 1 from its caller, etc. +func New(e interface{}, skip int) *Error { + var err error + + switch e := e.(type) { + case *Error: + return e + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2+skip, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// Errorf creates a new error with the given message. You can use it +// as a drop-in replacement for fmt.Errorf() to provide descriptive +// errors in return values. +func Errorf(format string, a ...interface{}) *Error { + return New(fmt.Errorf(format, a...), 1) +} + +// Error returns the underlying error's message. +func (err *Error) Error() string { + return err.Err.Error() +} + +// Stack returns the callstack formatted the same way that go does +// in runtime/debug.Stack() +func (err *Error) Stack() []byte { + buf := bytes.Buffer{} + + for _, frame := range err.StackFrames() { + buf.WriteString(frame.String()) + } + + return buf.Bytes() +} + +// StackFrames returns an array of frames containing information about the +// stack. +func (err *Error) StackFrames() []StackFrame { + if err.frames == nil { + err.frames = make([]StackFrame, len(err.stack)) + + for i, pc := range err.stack { + err.frames[i] = NewStackFrame(pc) + } + } + + return err.frames +} + +// TypeName returns the type this error. e.g. *errors.stringError. +func (err *Error) TypeName() string { + if _, ok := err.Err.(uncaughtPanic); ok { + return "panic" + } + return reflect.TypeOf(err.Err).String() +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/parse_panic.go b/vendor/github.com/bugsnag/bugsnag-go/errors/parse_panic.go new file mode 100644 index 0000000000..cc37052d78 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/errors/parse_panic.go @@ -0,0 +1,127 @@ +package errors + +import ( + "strconv" + "strings" +) + +type uncaughtPanic struct{ message string } + +func (p uncaughtPanic) Error() string { + return p.message +} + +// ParsePanic allows you to get an error object from the output of a go program +// that panicked. This is particularly useful with https://github.com/mitchellh/panicwrap. +func ParsePanic(text string) (*Error, error) { + lines := strings.Split(text, "\n") + + state := "start" + + var message string + var stack []StackFrame + + for i := 0; i < len(lines); i++ { + line := lines[i] + + if state == "start" { + if strings.HasPrefix(line, "panic: ") { + message = strings.TrimPrefix(line, "panic: ") + state = "seek" + } else { + return nil, Errorf("bugsnag.panicParser: Invalid line (no prefix): %s", line) + } + + } else if state == "seek" { + if strings.HasPrefix(line, "goroutine ") && strings.HasSuffix(line, "[running]:") { + state = "parsing" + } + + } else if state == "parsing" { + if line == "" { + state = "done" + break + } + createdBy := false + if strings.HasPrefix(line, "created by ") { + line = strings.TrimPrefix(line, "created by ") + createdBy = true + } + + i++ + + if i >= len(lines) { + return nil, Errorf("bugsnag.panicParser: Invalid line (unpaired): %s", line) + } + + frame, err := parsePanicFrame(line, lines[i], createdBy) + if err != nil { + return nil, err + } + + stack = append(stack, *frame) + if createdBy { + state = "done" + break + } + } + } + + if state == "done" || state == "parsing" { + return &Error{Err: uncaughtPanic{message}, frames: stack}, nil + } + return nil, Errorf("could not parse panic: %v", text) +} + +// The lines we're passing look like this: +// +// main.(*foo).destruct(0xc208067e98) +// /0/go/src/github.com/bugsnag/bugsnag-go/pan/main.go:22 +0x151 +func parsePanicFrame(name string, line string, createdBy bool) (*StackFrame, error) { + idx := strings.LastIndex(name, "(") + if idx == -1 && !createdBy { + return nil, Errorf("bugsnag.panicParser: Invalid line (no call): %s", name) + } + if idx != -1 { + name = name[:idx] + } + pkg := "" + + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + + if !strings.HasPrefix(line, "\t") { + return nil, Errorf("bugsnag.panicParser: Invalid line (no tab): %s", line) + } + + idx = strings.LastIndex(line, ":") + if idx == -1 { + return nil, Errorf("bugsnag.panicParser: Invalid line (no line number): %s", line) + } + file := line[1:idx] + + number := line[idx+1:] + if idx = strings.Index(number, " +"); idx > -1 { + number = number[:idx] + } + + lno, err := strconv.ParseInt(number, 10, 32) + if err != nil { + return nil, Errorf("bugsnag.panicParser: Invalid line (bad line number): %s", line) + } + + return &StackFrame{ + File: file, + LineNumber: int(lno), + Package: pkg, + Name: name, + }, nil +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/errors/stackframe.go b/vendor/github.com/bugsnag/bugsnag-go/errors/stackframe.go new file mode 100644 index 0000000000..4edadbc589 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/errors/stackframe.go @@ -0,0 +1,97 @@ +package errors + +import ( + "bytes" + "fmt" + "io/ioutil" + "runtime" + "strings" +) + +// A StackFrame contains all necessary information about to generate a line +// in a callstack. +type StackFrame struct { + File string + LineNumber int + Name string + Package string + ProgramCounter uintptr +} + +// NewStackFrame popoulates a stack frame object from the program counter. +func NewStackFrame(pc uintptr) (frame StackFrame) { + + frame = StackFrame{ProgramCounter: pc} + if frame.Func() == nil { + return + } + frame.Package, frame.Name = packageAndName(frame.Func()) + + // pc -1 because the program counters we use are usually return addresses, + // and we want to show the line that corresponds to the function call + frame.File, frame.LineNumber = frame.Func().FileLine(pc - 1) + return + +} + +// Func returns the function that this stackframe corresponds to +func (frame *StackFrame) Func() *runtime.Func { + if frame.ProgramCounter == 0 { + return nil + } + return runtime.FuncForPC(frame.ProgramCounter) +} + +// String returns the stackframe formatted in the same way as go does +// in runtime/debug.Stack() +func (frame *StackFrame) String() string { + str := fmt.Sprintf("%s:%d (0x%x)\n", frame.File, frame.LineNumber, frame.ProgramCounter) + + source, err := frame.SourceLine() + if err != nil { + return str + } + + return str + fmt.Sprintf("\t%s: %s\n", frame.Name, source) +} + +// SourceLine gets the line of code (from File and Line) of the original source if possible +func (frame *StackFrame) SourceLine() (string, error) { + data, err := ioutil.ReadFile(frame.File) + + if err != nil { + return "", err + } + + lines := bytes.Split(data, []byte{'\n'}) + if frame.LineNumber <= 0 || frame.LineNumber >= len(lines) { + return "???", nil + } + // -1 because line-numbers are 1 based, but our array is 0 based + return string(bytes.Trim(lines[frame.LineNumber-1], " \t")), nil +} + +func packageAndName(fn *runtime.Func) (string, string) { + name := fn.Name() + pkg := "" + + // The name includes the path name to the package, which is unnecessary + // since the file name is already included. Plus, it has center dots. + // That is, we see + // runtime/debug.*T·ptrmethod + // and want + // *T.ptrmethod + // Since the package path might contains dots (e.g. code.google.com/...), + // we first remove the path prefix if there is one. + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + return pkg, name +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/event.go b/vendor/github.com/bugsnag/bugsnag-go/event.go new file mode 100644 index 0000000000..320c6154c3 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/event.go @@ -0,0 +1,143 @@ +package bugsnag + +import ( + "strings" + + "github.com/bugsnag/bugsnag-go/errors" +) + +// Context is the context of the error in Bugsnag. +// This can be passed to Notify, Recover or AutoNotify as rawData. +type Context struct { + String string +} + +// User represents the searchable user-data on Bugsnag. The Id is also used +// to determine the number of users affected by a bug. This can be +// passed to Notify, Recover or AutoNotify as rawData. +type User struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Email string `json:"email,omitempty"` +} + +// ErrorClass overrides the error class in Bugsnag. +// This struct enables you to group errors as you like. +type ErrorClass struct { + Name string +} + +// Sets the severity of the error on Bugsnag. These values can be +// passed to Notify, Recover or AutoNotify as rawData. +var ( + SeverityError = severity{"error"} + SeverityWarning = severity{"warning"} + SeverityInfo = severity{"info"} +) + +// The severity tag type, private so that people can only use Error,Warning,Info +type severity struct { + String string +} + +// The form of stacktrace that Bugsnag expects +type stackFrame struct { + Method string `json:"method"` + File string `json:"file"` + LineNumber int `json:"lineNumber"` + InProject bool `json:"inProject,omitempty"` +} + +// Event represents a payload of data that gets sent to Bugsnag. +// This is passed to each OnBeforeNotify hook. +type Event struct { + + // The original error that caused this event, not sent to Bugsnag. + Error *errors.Error + + // The rawData affecting this error, not sent to Bugsnag. + RawData []interface{} + + // The error class to be sent to Bugsnag. This defaults to the type name of the Error, for + // example *error.String + ErrorClass string + // The error message to be sent to Bugsnag. This defaults to the return value of Error.Error() + Message string + // The stacktrrace of the error to be sent to Bugsnag. + Stacktrace []stackFrame + + // The context to be sent to Bugsnag. This should be set to the part of the app that was running, + // e.g. for http requests, set it to the path. + Context string + // The severity of the error. Can be SeverityError, SeverityWarning or SeverityInfo. + Severity severity + // The grouping hash is used to override Bugsnag's grouping. Set this if you'd like all errors with + // the same grouping hash to group together in the dashboard. + GroupingHash string + + // User data to send to Bugsnag. This is searchable on the dashboard. + User *User + // Other MetaData to send to Bugsnag. Appears as a set of tabbed tables in the dashboard. + MetaData MetaData +} + +func newEvent(err *errors.Error, rawData []interface{}, notifier *Notifier) (*Event, *Configuration) { + + config := notifier.Config + event := &Event{ + Error: err, + RawData: append(notifier.RawData, rawData...), + + ErrorClass: err.TypeName(), + Message: err.Error(), + Stacktrace: make([]stackFrame, len(err.StackFrames())), + + Severity: SeverityWarning, + + MetaData: make(MetaData), + } + + for _, datum := range event.RawData { + switch datum := datum.(type) { + case severity: + event.Severity = datum + + case Context: + event.Context = datum.String + + case Configuration: + config = config.merge(&datum) + + case MetaData: + event.MetaData.Update(datum) + + case User: + event.User = &datum + + case ErrorClass: + event.ErrorClass = datum.Name + } + } + + for i, frame := range err.StackFrames() { + file := frame.File + inProject := config.isProjectPackage(frame.Package) + + // remove $GOROOT and $GOHOME from other frames + if idx := strings.Index(file, frame.Package); idx > -1 { + file = file[idx:] + } + if inProject { + file = config.stripProjectPackages(file) + } + + event.Stacktrace[i] = stackFrame{ + Method: frame.Name, + File: file, + LineNumber: frame.LineNumber, + InProject: inProject, + } + } + + return event, config +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/json_tags.go b/vendor/github.com/bugsnag/bugsnag-go/json_tags.go new file mode 100644 index 0000000000..45be38fa9e --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/json_tags.go @@ -0,0 +1,43 @@ +// The code is stripped from: +// http://golang.org/src/pkg/encoding/json/tags.go?m=text + +package bugsnag + +import ( + "strings" +) + +// tagOptions is the string following a comma in a struct field's "json" +// tag, or the empty string. It does not include the leading comma. +type tagOptions string + +// parseTag splits a struct field's json tag into its name and +// comma-separated options. +func parseTag(tag string) (string, tagOptions) { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx], tagOptions(tag[idx+1:]) + } + return tag, tagOptions("") +} + +// Contains reports whether a comma-separated list of options +// contains a particular substr flag. substr must be surrounded by a +// string boundary or commas. +func (o tagOptions) Contains(optionName string) bool { + if len(o) == 0 { + return false + } + s := string(o) + for s != "" { + var next string + i := strings.Index(s, ",") + if i >= 0 { + s, next = s[:i], s[i+1:] + } + if s == optionName { + return true + } + s = next + } + return false +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/metadata.go b/vendor/github.com/bugsnag/bugsnag-go/metadata.go new file mode 100644 index 0000000000..20628117d2 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/metadata.go @@ -0,0 +1,189 @@ +package bugsnag + +import ( + "fmt" + "reflect" + "strings" +) + +// MetaData is added to the Bugsnag dashboard in tabs. Each tab is +// a map of strings -> values. You can pass MetaData to Notify, Recover +// and AutoNotify as rawData. +type MetaData map[string]map[string]interface{} + +// Update the meta-data with more information. Tabs are merged together such +// that unique keys from both sides are preserved, and duplicate keys end up +// with the provided values. +func (meta MetaData) Update(other MetaData) { + for name, tab := range other { + + if meta[name] == nil { + meta[name] = make(map[string]interface{}) + } + + for key, value := range tab { + meta[name][key] = value + } + } +} + +// Add creates a tab of Bugsnag meta-data. +// If the tab doesn't yet exist it will be created. +// If the key already exists, it will be overwritten. +func (meta MetaData) Add(tab string, key string, value interface{}) { + if meta[tab] == nil { + meta[tab] = make(map[string]interface{}) + } + + meta[tab][key] = value +} + +// AddStruct creates a tab of Bugsnag meta-data. +// The struct will be converted to an Object using the +// reflect library so any private fields will not be exported. +// As a safety measure, if you pass a non-struct the value will be +// sent to Bugsnag under the "Extra data" tab. +func (meta MetaData) AddStruct(tab string, obj interface{}) { + val := sanitizer{}.Sanitize(obj) + content, ok := val.(map[string]interface{}) + if ok { + meta[tab] = content + } else { + // Wasn't a struct + meta.Add("Extra data", tab, obj) + } + +} + +// Remove any values from meta-data that have keys matching the filters, +// and any that are recursive data-structures +func (meta MetaData) sanitize(filters []string) interface{} { + return sanitizer{ + Filters: filters, + Seen: make([]interface{}, 0), + }.Sanitize(meta) + +} + +// The sanitizer is used to remove filtered params and recursion from meta-data. +type sanitizer struct { + Filters []string + Seen []interface{} +} + +func (s sanitizer) Sanitize(data interface{}) interface{} { + for _, s := range s.Seen { + // TODO: we don't need deep equal here, just type-ignoring equality + if reflect.DeepEqual(data, s) { + return "[RECURSION]" + } + } + + // Sanitizers are passed by value, so we can modify s and it only affects + // s.Seen for nested calls. + s.Seen = append(s.Seen, data) + + t := reflect.TypeOf(data) + v := reflect.ValueOf(data) + + if t == nil { + return "" + } + + switch t.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64: + return data + + case reflect.String: + return data + + case reflect.Interface, reflect.Ptr: + return s.Sanitize(v.Elem().Interface()) + + case reflect.Array, reflect.Slice: + ret := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + ret[i] = s.Sanitize(v.Index(i).Interface()) + } + return ret + + case reflect.Map: + return s.sanitizeMap(v) + + case reflect.Struct: + return s.sanitizeStruct(v, t) + + // Things JSON can't serialize: + // case t.Chan, t.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer: + default: + return "[" + t.String() + "]" + + } + +} + +func (s sanitizer) sanitizeMap(v reflect.Value) interface{} { + ret := make(map[string]interface{}) + + for _, key := range v.MapKeys() { + val := s.Sanitize(v.MapIndex(key).Interface()) + newKey := fmt.Sprintf("%v", key.Interface()) + + if s.shouldRedact(newKey) { + val = "[REDACTED]" + } + + ret[newKey] = val + } + + return ret +} + +func (s sanitizer) sanitizeStruct(v reflect.Value, t reflect.Type) interface{} { + ret := make(map[string]interface{}) + + for i := 0; i < v.NumField(); i++ { + + val := v.Field(i) + // Don't export private fields + if !val.CanInterface() { + continue + } + + name := t.Field(i).Name + var opts tagOptions + + // Parse JSON tags. Supports name and "omitempty" + if jsonTag := t.Field(i).Tag.Get("json"); len(jsonTag) != 0 { + name, opts = parseTag(jsonTag) + } + + if s.shouldRedact(name) { + ret[name] = "[REDACTED]" + } else { + sanitized := s.Sanitize(val.Interface()) + if str, ok := sanitized.(string); ok { + if !(opts.Contains("omitempty") && len(str) == 0) { + ret[name] = str + } + } else { + ret[name] = sanitized + } + + } + } + + return ret +} + +func (s sanitizer) shouldRedact(key string) bool { + for _, filter := range s.Filters { + if strings.Contains(strings.ToLower(filter), strings.ToLower(key)) { + return true + } + } + return false +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/middleware.go b/vendor/github.com/bugsnag/bugsnag-go/middleware.go new file mode 100644 index 0000000000..c1c9f79db4 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/middleware.go @@ -0,0 +1,96 @@ +package bugsnag + +import ( + "net/http" + "strings" +) + +type ( + beforeFunc func(*Event, *Configuration) error + + // MiddlewareStacks keep middleware in the correct order. They are + // called in reverse order, so if you add a new middleware it will + // be called before all existing middleware. + middlewareStack struct { + before []beforeFunc + } +) + +// AddMiddleware adds a new middleware to the outside of the existing ones, +// when the middlewareStack is Run it will be run before all middleware that +// have been added before. +func (stack *middlewareStack) OnBeforeNotify(middleware beforeFunc) { + stack.before = append(stack.before, middleware) +} + +// Run causes all the middleware to be run. If they all permit it the next callback +// will be called with all the middleware on the stack. +func (stack *middlewareStack) Run(event *Event, config *Configuration, next func() error) error { + // run all the before filters in reverse order + for i := range stack.before { + before := stack.before[len(stack.before)-i-1] + + err := stack.runBeforeFilter(before, event, config) + if err != nil { + return err + } + } + + return next() +} + +func (stack *middlewareStack) runBeforeFilter(f beforeFunc, event *Event, config *Configuration) error { + defer func() { + if err := recover(); err != nil { + config.logf("bugsnag/middleware: unexpected panic: %v", err) + } + }() + + return f(event, config) +} + +// catchMiddlewarePanic is used to log any panics that happen inside Middleware, +// we wouldn't want to not notify Bugsnag in this case. +func catchMiddlewarePanic(event *Event, config *Configuration, next func() error) { +} + +// httpRequestMiddleware is added OnBeforeNotify by default. It takes information +// from an http.Request passed in as rawData, and adds it to the Event. You can +// use this as a template for writing your own Middleware. +func httpRequestMiddleware(event *Event, config *Configuration) error { + for _, datum := range event.RawData { + if request, ok := datum.(*http.Request); ok { + proto := "http://" + if request.TLS != nil { + proto = "https://" + } + + event.MetaData.Update(MetaData{ + "Request": { + "RemoteAddr": request.RemoteAddr, + "Method": request.Method, + "Url": proto + request.Host + request.RequestURI, + "Params": request.URL.Query(), + }, + }) + + // Add headers as a separate tab. + event.MetaData.AddStruct("Headers", request.Header) + + // Default context to Path + if event.Context == "" { + event.Context = request.URL.Path + } + + // Default user.id to IP so that users-affected works. + if event.User == nil { + ip := request.RemoteAddr + if idx := strings.LastIndex(ip, ":"); idx != -1 { + ip = ip[:idx] + } + event.User = &User{Id: ip} + } + } + } + return nil +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/notifier.go b/vendor/github.com/bugsnag/bugsnag-go/notifier.go new file mode 100644 index 0000000000..009ec63958 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/notifier.go @@ -0,0 +1,102 @@ +package bugsnag + +import ( + "fmt" + + "github.com/bugsnag/bugsnag-go/errors" +) + +// Notifier sends errors to Bugsnag. +type Notifier struct { + Config *Configuration + RawData []interface{} +} + +// New creates a new notifier. +// You can pass an instance of bugsnag.Configuration in rawData to change the configuration. +// Other values of rawData will be passed to Notify. +func New(rawData ...interface{}) *Notifier { + config := Config.clone() + for i, datum := range rawData { + if c, ok := datum.(Configuration); ok { + config.update(&c) + rawData[i] = nil + } + } + + return &Notifier{ + Config: config, + RawData: rawData, + } +} + +// Notify sends an error to Bugsnag. Any rawData you pass here will be sent to +// Bugsnag after being converted to JSON. e.g. bugsnag.SeverityError, bugsnag.Context, +// or bugsnag.MetaData. +func (notifier *Notifier) Notify(err error, rawData ...interface{}) (e error) { + event, config := newEvent(errors.New(err, 1), rawData, notifier) + + // Never block, start throwing away errors if we have too many. + e = middleware.Run(event, config, func() error { + config.logf("notifying bugsnag: %s", event.Message) + if config.notifyInReleaseStage() { + if config.Synchronous { + return (&payload{event, config}).deliver() + } + // Ensure that any errors are logged if they occur in a goroutine. + go func(event *Event, config *Configuration) { + err := (&payload{event, config}).deliver() + if err != nil { + config.logf("bugsnag.Notify: %v", err) + } + }(event, config) + + return nil + } + return fmt.Errorf("not notifying in %s", config.ReleaseStage) + }) + + if e != nil { + config.logf("bugsnag.Notify: %v", e) + } + return e +} + +// AutoNotify notifies Bugsnag of any panics, then repanics. +// It sends along any rawData that gets passed in. +// Usage: defer AutoNotify() +func (notifier *Notifier) AutoNotify(rawData ...interface{}) { + if err := recover(); err != nil { + rawData = notifier.addDefaultSeverity(rawData, SeverityError) + notifier.Notify(errors.New(err, 2), rawData...) + panic(err) + } +} + +// Recover logs any panics, then recovers. +// It sends along any rawData that gets passed in. +// Usage: defer Recover() +func (notifier *Notifier) Recover(rawData ...interface{}) { + if err := recover(); err != nil { + rawData = notifier.addDefaultSeverity(rawData, SeverityWarning) + notifier.Notify(errors.New(err, 2), rawData...) + } +} + +func (notifier *Notifier) dontPanic() { + if err := recover(); err != nil { + notifier.Config.logf("bugsnag/notifier.Notify: panic! %s", err) + } +} + +// Add a severity to raw data only if the default is not set. +func (notifier *Notifier) addDefaultSeverity(rawData []interface{}, s severity) []interface{} { + + for _, datum := range append(notifier.RawData, rawData...) { + if _, ok := datum.(severity); ok { + return rawData + } + } + + return append(rawData, s) +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/panicwrap.go b/vendor/github.com/bugsnag/bugsnag-go/panicwrap.go new file mode 100644 index 0000000000..d8bd60154d --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/panicwrap.go @@ -0,0 +1,27 @@ +// +build !appengine + +package bugsnag + +import ( + "github.com/bugsnag/bugsnag-go/errors" + "github.com/bugsnag/panicwrap" +) + +// NOTE: this function does not return when you call it, instead it +// re-exec()s the current process with panic monitoring. +func defaultPanicHandler() { + defer defaultNotifier.dontPanic() + + err := panicwrap.BasicMonitor(func(output string) { + toNotify, err := errors.ParsePanic(output) + + if err != nil { + defaultNotifier.Config.logf("bugsnag.handleUncaughtPanic: %v", err) + } + Notify(toNotify, SeverityError, Configuration{Synchronous: true}) + }) + + if err != nil { + defaultNotifier.Config.logf("bugsnag.handleUncaughtPanic: %v", err) + } +} diff --git a/vendor/github.com/bugsnag/bugsnag-go/payload.go b/vendor/github.com/bugsnag/bugsnag-go/payload.go new file mode 100644 index 0000000000..a516a5d2d6 --- /dev/null +++ b/vendor/github.com/bugsnag/bugsnag-go/payload.go @@ -0,0 +1,96 @@ +package bugsnag + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" +) + +type payload struct { + *Event + *Configuration +} + +type hash map[string]interface{} + +func (p *payload) deliver() error { + + if len(p.APIKey) != 32 { + return fmt.Errorf("bugsnag/payload.deliver: invalid api key") + } + + buf, err := json.Marshal(p) + + if err != nil { + return fmt.Errorf("bugsnag/payload.deliver: %v", err) + } + + client := http.Client{ + Transport: p.Transport, + } + + resp, err := client.Post(p.Endpoint, "application/json", bytes.NewBuffer(buf)) + + if err != nil { + return fmt.Errorf("bugsnag/payload.deliver: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("bugsnag/payload.deliver: Got HTTP %s\n", resp.Status) + } + + return nil +} + +func (p *payload) MarshalJSON() ([]byte, error) { + + data := hash{ + "apiKey": p.APIKey, + + "notifier": hash{ + "name": "Bugsnag Go", + "url": "https://github.com/bugsnag/bugsnag-go", + "version": VERSION, + }, + + "events": []hash{ + { + "payloadVersion": "2", + "exceptions": []hash{ + { + "errorClass": p.ErrorClass, + "message": p.Message, + "stacktrace": p.Stacktrace, + }, + }, + "severity": p.Severity.String, + "app": hash{ + "releaseStage": p.ReleaseStage, + }, + "user": p.User, + "metaData": p.MetaData.sanitize(p.ParamsFilters), + }, + }, + } + + event := data["events"].([]hash)[0] + + if p.Context != "" { + event["context"] = p.Context + } + if p.GroupingHash != "" { + event["groupingHash"] = p.GroupingHash + } + if p.Hostname != "" { + event["device"] = hash{ + "hostname": p.Hostname, + } + } + if p.AppVersion != "" { + event["app"].(hash)["version"] = p.AppVersion + } + return json.Marshal(data) + +} diff --git a/vendor/github.com/bugsnag/osext/LICENSE b/vendor/github.com/bugsnag/osext/LICENSE new file mode 100644 index 0000000000..18527a28fb --- /dev/null +++ b/vendor/github.com/bugsnag/osext/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2012 Daniel Theophanes + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. diff --git a/vendor/github.com/bugsnag/osext/osext.go b/vendor/github.com/bugsnag/osext/osext.go new file mode 100644 index 0000000000..37efbb2210 --- /dev/null +++ b/vendor/github.com/bugsnag/osext/osext.go @@ -0,0 +1,32 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Extensions to the standard "os" package. +package osext + +import "path/filepath" + +// Executable returns an absolute path that can be used to +// re-invoke the current program. +// It may not be valid after the current program exits. +func Executable() (string, error) { + p, err := executable() + return filepath.Clean(p), err +} + +// Returns same path as Executable, returns just the folder +// path. Excludes the executable name. +func ExecutableFolder() (string, error) { + p, err := Executable() + if err != nil { + return "", err + } + folder, _ := filepath.Split(p) + return folder, nil +} + +// Depricated. Same as Executable(). +func GetExePath() (exePath string, err error) { + return Executable() +} diff --git a/vendor/github.com/bugsnag/osext/osext_plan9.go b/vendor/github.com/bugsnag/osext/osext_plan9.go new file mode 100644 index 0000000000..e88c1e0933 --- /dev/null +++ b/vendor/github.com/bugsnag/osext/osext_plan9.go @@ -0,0 +1,16 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package osext + +import "syscall" + +func executable() (string, error) { + f, err := Open("/proc/" + itoa(Getpid()) + "/text") + if err != nil { + return "", err + } + defer f.Close() + return syscall.Fd2path(int(f.Fd())) +} diff --git a/vendor/github.com/bugsnag/osext/osext_procfs.go b/vendor/github.com/bugsnag/osext/osext_procfs.go new file mode 100644 index 0000000000..546fec9155 --- /dev/null +++ b/vendor/github.com/bugsnag/osext/osext_procfs.go @@ -0,0 +1,25 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux netbsd openbsd + +package osext + +import ( + "errors" + "os" + "runtime" +) + +func executable() (string, error) { + switch runtime.GOOS { + case "linux": + return os.Readlink("/proc/self/exe") + case "netbsd": + return os.Readlink("/proc/curproc/exe") + case "openbsd": + return os.Readlink("/proc/curproc/file") + } + return "", errors.New("ExecPath not implemented for " + runtime.GOOS) +} diff --git a/vendor/github.com/bugsnag/osext/osext_sysctl.go b/vendor/github.com/bugsnag/osext/osext_sysctl.go new file mode 100644 index 0000000000..d764646286 --- /dev/null +++ b/vendor/github.com/bugsnag/osext/osext_sysctl.go @@ -0,0 +1,64 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin freebsd + +package osext + +import ( + "os" + "runtime" + "syscall" + "unsafe" +) + +var startUpcwd, getwdError = os.Getwd() + +func executable() (string, error) { + var mib [4]int32 + switch runtime.GOOS { + case "freebsd": + mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1} + case "darwin": + mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1} + } + + n := uintptr(0) + // get length + _, _, err := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if err != 0 { + return "", err + } + if n == 0 { // shouldn't happen + return "", nil + } + buf := make([]byte, n) + _, _, err = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0) + if err != 0 { + return "", err + } + if n == 0 { // shouldn't happen + return "", nil + } + for i, v := range buf { + if v == 0 { + buf = buf[:i] + break + } + } + if buf[0] != '/' { + if getwdError != nil { + return string(buf), getwdError + } else { + if buf[0] == '.' { + buf = buf[1:] + } + if startUpcwd[len(startUpcwd)-1] != '/' { + return startUpcwd + "/" + string(buf), nil + } + return startUpcwd + string(buf), nil + } + } + return string(buf), nil +} diff --git a/vendor/github.com/bugsnag/osext/osext_windows.go b/vendor/github.com/bugsnag/osext/osext_windows.go new file mode 100644 index 0000000000..72d282cf8c --- /dev/null +++ b/vendor/github.com/bugsnag/osext/osext_windows.go @@ -0,0 +1,34 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package osext + +import ( + "syscall" + "unicode/utf16" + "unsafe" +) + +var ( + kernel = syscall.MustLoadDLL("kernel32.dll") + getModuleFileNameProc = kernel.MustFindProc("GetModuleFileNameW") +) + +// GetModuleFileName() with hModule = NULL +func executable() (exePath string, err error) { + return getModuleFileName() +} + +func getModuleFileName() (string, error) { + var n uint32 + b := make([]uint16, syscall.MAX_PATH) + size := uint32(len(b)) + + r0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size)) + n = uint32(r0) + if n == 0 { + return "", e1 + } + return string(utf16.Decode(b[0:n])), nil +} diff --git a/vendor/github.com/bugsnag/panicwrap/CHANGELOG.md b/vendor/github.com/bugsnag/panicwrap/CHANGELOG.md new file mode 100644 index 0000000000..8ad30baf54 --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/CHANGELOG.md @@ -0,0 +1,11 @@ +## 1.1.0 (2016-01-18) + +* Add ARM64 support + [liusdu](https://github.com/liusdu) + [#1](https://github.com/bugsnag/panicwrap/pull/1) + +## 1.0.0 (2014-11-10) + +### Enhancements + +* Add ability to monitor a process diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/bugsnag/panicwrap/LICENSE similarity index 100% rename from Godeps/_workspace/src/github.com/mitchellh/mapstructure/LICENSE rename to vendor/github.com/bugsnag/panicwrap/LICENSE diff --git a/vendor/github.com/bugsnag/panicwrap/README.md b/vendor/github.com/bugsnag/panicwrap/README.md new file mode 100644 index 0000000000..d0a5967539 --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/README.md @@ -0,0 +1,101 @@ +# panicwrap + +panicwrap is a Go library that re-executes a Go binary and monitors stderr +output from the binary for a panic. When it find a panic, it executes a +user-defined handler function. Stdout, stderr, stdin, signals, and exit +codes continue to work as normal, making the existence of panicwrap mostly +invisble to the end user until a panic actually occurs. + +Since a panic is truly a bug in the program meant to crash the runtime, +globally catching panics within Go applications is not supposed to be possible. +Despite this, it is often useful to have a way to know when panics occur. +panicwrap allows you to do something with these panics, such as writing them +to a file, so that you can track when panics occur. + +panicwrap is ***not a panic recovery system***. Panics indicate serious +problems with your application and _should_ crash the runtime. panicwrap +is just meant as a way to monitor for panics. If you still think this is +the worst idea ever, read the section below on why. + +## Features + +* **SIMPLE!** +* Works with all Go applications on all platforms Go supports +* Custom behavior when a panic occurs +* Stdout, stderr, stdin, exit codes, and signals continue to work as + expected. + +## Usage + +Using panicwrap is simple. It behaves a lot like `fork`, if you know +how that works. A basic example is shown below. + +Because it would be sad to panic while capturing a panic, it is recommended +that the handler functions for panicwrap remain relatively simple and well +tested. panicwrap itself contains many tests. + +```go +package main + +import ( + "fmt" + "github.com/mitchellh/panicwrap" + "os" +) + +func main() { + exitStatus, err := panicwrap.BasicWrap(panicHandler) + if err != nil { + // Something went wrong setting up the panic wrapper. Unlikely, + // but possible. + panic(err) + } + + // If exitStatus >= 0, then we're the parent process and the panicwrap + // re-executed ourselves and completed. Just exit with the proper status. + if exitStatus >= 0 { + os.Exit(exitStatus) + } + + // Otherwise, exitStatus < 0 means we're the child. Continue executing as + // normal... + + // Let's say we panic + panic("oh shucks") +} + +func panicHandler(output string) { + // output contains the full output (including stack traces) of the + // panic. Put it in a file or something. + fmt.Printf("The child panicked:\n\n%s\n", output) + os.Exit(1) +} +``` + +## How Does it Work? + +panicwrap works by re-executing the running program (retaining arguments, +environmental variables, etc.) and monitoring the stderr of the program. +Since Go always outputs panics in a predictable way with a predictable +exit code, panicwrap is able to reliably detect panics and allow the parent +process to handle them. + +## WHY?! Panics should CRASH! + +Yes, panics _should_ crash. They are 100% always indicative of bugs. +However, in some cases, such as user-facing programs (programs like +[Packer](http://github.com/mitchellh/packer) or +[Docker](http://github.com/dotcloud/docker)), it is up to the user to +report such panics. This is unreliable, at best, and it would be better if the +program could have a way to automatically report panics. panicwrap provides +a way to do this. + +For backend applications, it is easier to detect crashes (since the application +exits). However, it is still nice sometimes to more intelligently log +panics in some way. For example, at [HashiCorp](http://www.hashicorp.com), +we use panicwrap to log panics to timestamped files with some additional +data (configuration settings at the time, environmental variables, etc.) + +The goal of panicwrap is _not_ to hide panics. It is instead to provide +a clean mechanism for handling them before bubbling the up to the user +and ultimately crashing. diff --git a/vendor/github.com/bugsnag/panicwrap/dup2.go b/vendor/github.com/bugsnag/panicwrap/dup2.go new file mode 100644 index 0000000000..de523c83d5 --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/dup2.go @@ -0,0 +1,11 @@ +// +build darwin dragonfly freebsd linux,!arm64 netbsd openbsd + +package panicwrap + +import ( + "syscall" +) + +func dup2(oldfd, newfd int) error { + return syscall.Dup2(oldfd, newfd) +} diff --git a/vendor/github.com/bugsnag/panicwrap/dup3.go b/vendor/github.com/bugsnag/panicwrap/dup3.go new file mode 100644 index 0000000000..9721b36cc2 --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/dup3.go @@ -0,0 +1,11 @@ +// +build linux,arm64 + +package panicwrap + +import ( + "syscall" +) + +func dup2(oldfd, newfd int) error { + return syscall.Dup3(oldfd, newfd, 0) +} diff --git a/vendor/github.com/bugsnag/panicwrap/monitor.go b/vendor/github.com/bugsnag/panicwrap/monitor.go new file mode 100644 index 0000000000..72b418a27b --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/monitor.go @@ -0,0 +1,62 @@ +// +build !windows + +package panicwrap + +import ( + "github.com/bugsnag/osext" + "os" + "os/exec" +) + +func monitor(c *WrapConfig) (int, error) { + + // If we're the child process, absorb panics. + if Wrapped(c) { + panicCh := make(chan string) + + go trackPanic(os.Stdin, os.Stderr, c.DetectDuration, panicCh) + + // Wait on the panic data + panicTxt := <-panicCh + if panicTxt != "" { + if !c.HidePanic { + os.Stderr.Write([]byte(panicTxt)) + } + + c.Handler(panicTxt) + } + + os.Exit(0) + } + + exePath, err := osext.Executable() + if err != nil { + return -1, err + } + cmd := exec.Command(exePath, os.Args[1:]...) + + read, write, err := os.Pipe() + if err != nil { + return -1, err + } + + cmd.Stdin = read + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Env = append(os.Environ(), c.CookieKey+"="+c.CookieValue) + + if err != nil { + return -1, err + } + err = cmd.Start() + if err != nil { + return -1, err + } + + err = dup2(int(write.Fd()), int(os.Stderr.Fd())) + if err != nil { + return -1, err + } + + return -1, nil +} diff --git a/vendor/github.com/bugsnag/panicwrap/monitor_windows.go b/vendor/github.com/bugsnag/panicwrap/monitor_windows.go new file mode 100644 index 0000000000..d07a692189 --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/monitor_windows.go @@ -0,0 +1,7 @@ +package panicwrap + +import "fmt" + +func monitor(c *WrapConfig) (int, error) { + return -1, fmt.Errorf("Monitor is not supported on windows") +} diff --git a/vendor/github.com/bugsnag/panicwrap/panicwrap.go b/vendor/github.com/bugsnag/panicwrap/panicwrap.go new file mode 100644 index 0000000000..f9ea3e3e63 --- /dev/null +++ b/vendor/github.com/bugsnag/panicwrap/panicwrap.go @@ -0,0 +1,339 @@ +// The panicwrap package provides functions for capturing and handling +// panics in your application. It does this by re-executing the running +// application and monitoring stderr for any panics. At the same time, +// stdout/stderr/etc. are set to the same values so that data is shuttled +// through properly, making the existence of panicwrap mostly transparent. +// +// Panics are only detected when the subprocess exits with a non-zero +// exit status, since this is the only time panics are real. Otherwise, +// "panic-like" output is ignored. +package panicwrap + +import ( + "bytes" + "errors" + "github.com/bugsnag/osext" + "io" + "os" + "os/exec" + "os/signal" + "runtime" + "syscall" + "time" +) + +const ( + DEFAULT_COOKIE_KEY = "cccf35992f8f3cd8d1d28f0109dd953e26664531" + DEFAULT_COOKIE_VAL = "7c28215aca87789f95b406b8dd91aa5198406750" +) + +// HandlerFunc is the type called when a panic is detected. +type HandlerFunc func(string) + +// WrapConfig is the configuration for panicwrap when wrapping an existing +// binary. To get started, in general, you only need the BasicWrap function +// that will set this up for you. However, for more customizability, +// WrapConfig and Wrap can be used. +type WrapConfig struct { + // Handler is the function called when a panic occurs. + Handler HandlerFunc + + // The cookie key and value are used within environmental variables + // to tell the child process that it is already executing so that + // wrap doesn't re-wrap itself. + CookieKey string + CookieValue string + + // If true, the panic will not be mirrored to the configured writer + // and will instead ONLY go to the handler. This lets you effectively + // hide panics from the end user. This is not recommended because if + // your handler fails, the panic is effectively lost. + HidePanic bool + + // If true, panicwrap will boot a monitor sub-process and let the parent + // run the app. This mode is useful for processes run under supervisors + // like runit as signals get sent to the correct codebase. This is not + // supported when GOOS=windows, and ignores c.Stderr and c.Stdout. + Monitor bool + + // The amount of time that a process must exit within after detecting + // a panic header for panicwrap to assume it is a panic. Defaults to + // 300 milliseconds. + DetectDuration time.Duration + + // The writer to send the stderr to. If this is nil, then it defaults + // to os.Stderr. + Writer io.Writer + + // The writer to send stdout to. If this is nil, then it defaults to + // os.Stdout. + Stdout io.Writer +} + +// BasicWrap calls Wrap with the given handler function, using defaults +// for everything else. See Wrap and WrapConfig for more information on +// functionality and return values. +func BasicWrap(f HandlerFunc) (int, error) { + return Wrap(&WrapConfig{ + Handler: f, + }) +} + +// BasicMonitor calls Wrap with Monitor set to true on supported platforms. +// It forks your program and runs it again form the start. In one process +// BasicMonitor never returns, it just listens on stderr of the other process, +// and calls your handler when a panic is seen. In the other it either returns +// nil to indicate that the panic monitoring is enabled, or an error to indicate +// that something else went wrong. +func BasicMonitor(f HandlerFunc) error { + exitStatus, err := Wrap(&WrapConfig{ + Handler: f, + Monitor: runtime.GOOS != "windows", + }) + + if err != nil { + return err + } + + if exitStatus >= 0 { + os.Exit(exitStatus) + } + + return nil +} + +// Wrap wraps the current executable in a handler to catch panics. It +// returns an error if there was an error during the wrapping process. +// If the error is nil, then the int result indicates the exit status of the +// child process. If the exit status is -1, then this is the child process, +// and execution should continue as normal. Otherwise, this is the parent +// process and the child successfully ran already, and you should exit the +// process with the returned exit status. +// +// This function should be called very very early in your program's execution. +// Ideally, this runs as the first line of code of main. +// +// Once this is called, the given WrapConfig shouldn't be modified or used +// any further. +func Wrap(c *WrapConfig) (int, error) { + if c.Handler == nil { + return -1, errors.New("Handler must be set") + } + + if c.DetectDuration == 0 { + c.DetectDuration = 300 * time.Millisecond + } + + if c.Writer == nil { + c.Writer = os.Stderr + } + + if c.Monitor { + return monitor(c) + } else { + return wrap(c) + } +} + +func wrap(c *WrapConfig) (int, error) { + + // If we're already wrapped, exit out. + if Wrapped(c) { + return -1, nil + } + + // Get the path to our current executable + exePath, err := osext.Executable() + if err != nil { + return -1, err + } + + // Pipe the stderr so we can read all the data as we look for panics + stderr_r, stderr_w := io.Pipe() + + // doneCh is closed when we're done, signaling any other goroutines + // to end immediately. + doneCh := make(chan struct{}) + + // panicCh is the channel on which the panic text will actually be + // sent. + panicCh := make(chan string) + + // On close, make sure to finish off the copying of data to stderr + defer func() { + defer close(doneCh) + stderr_w.Close() + <-panicCh + }() + + // Start the goroutine that will watch stderr for any panics + go trackPanic(stderr_r, c.Writer, c.DetectDuration, panicCh) + + // Create the writer for stdout that we're going to use + var stdout_w io.Writer = os.Stdout + if c.Stdout != nil { + stdout_w = c.Stdout + } + + // Build a subcommand to re-execute ourselves. We make sure to + // set the environmental variable to include our cookie. We also + // set stdin/stdout to match the config. Finally, we pipe stderr + // through ourselves in order to watch for panics. + cmd := exec.Command(exePath, os.Args[1:]...) + cmd.Env = append(os.Environ(), c.CookieKey+"="+c.CookieValue) + cmd.Stdin = os.Stdin + cmd.Stdout = stdout_w + cmd.Stderr = stderr_w + if err := cmd.Start(); err != nil { + return 1, err + } + + // Listen to signals and capture them forever. We allow the child + // process to handle them in some way. + sigCh := make(chan os.Signal) + signal.Notify(sigCh, os.Interrupt) + go func() { + defer signal.Stop(sigCh) + for { + select { + case <-doneCh: + return + case <-sigCh: + } + } + }() + + if err := cmd.Wait(); err != nil { + exitErr, ok := err.(*exec.ExitError) + if !ok { + // This is some other kind of subprocessing error. + return 1, err + } + + exitStatus := 1 + if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { + exitStatus = status.ExitStatus() + } + + // Close the writer end so that the tracker goroutine ends at some point + stderr_w.Close() + + // Wait on the panic data + panicTxt := <-panicCh + if panicTxt != "" { + if !c.HidePanic { + c.Writer.Write([]byte(panicTxt)) + } + + c.Handler(panicTxt) + } + + return exitStatus, nil + } + + return 0, nil +} + +// Wrapped checks if we're already wrapped according to the configuration +// given. +// +// Wrapped is very cheap and can be used early to short-circuit some pre-wrap +// logic your application may have. +func Wrapped(c *WrapConfig) bool { + if c.CookieKey == "" { + c.CookieKey = DEFAULT_COOKIE_KEY + } + + if c.CookieValue == "" { + c.CookieValue = DEFAULT_COOKIE_VAL + } + + // If the cookie key/value match our environment, then we are the + // child, so just exit now and tell the caller that we're the child + return os.Getenv(c.CookieKey) == c.CookieValue +} + +// trackPanic monitors the given reader for a panic. If a panic is detected, +// it is outputted on the result channel. This will close the channel once +// it is complete. +func trackPanic(r io.Reader, w io.Writer, dur time.Duration, result chan<- string) { + defer close(result) + + var panicTimer <-chan time.Time + panicBuf := new(bytes.Buffer) + panicHeader := []byte("panic:") + + tempBuf := make([]byte, 2048) + for { + var buf []byte + var n int + + if panicTimer == nil && panicBuf.Len() > 0 { + // We're not tracking a panic but the buffer length is + // greater than 0. We need to clear out that buffer, but + // look for another panic along the way. + + // First, remove the previous panic header so we don't loop + w.Write(panicBuf.Next(len(panicHeader))) + + // Next, assume that this is our new buffer to inspect + n = panicBuf.Len() + buf = make([]byte, n) + copy(buf, panicBuf.Bytes()) + panicBuf.Reset() + } else { + var err error + buf = tempBuf + n, err = r.Read(buf) + if n <= 0 && err == io.EOF { + if panicBuf.Len() > 0 { + // We were tracking a panic, assume it was a panic + // and return that as the result. + result <- panicBuf.String() + } + + return + } + } + + if panicTimer != nil { + // We're tracking what we think is a panic right now. + // If the timer ended, then it is not a panic. + isPanic := true + select { + case <-panicTimer: + isPanic = false + default: + } + + // No matter what, buffer the text some more. + panicBuf.Write(buf[0:n]) + + if !isPanic { + // It isn't a panic, stop tracking. Clean-up will happen + // on the next iteration. + panicTimer = nil + } + + continue + } + + flushIdx := n + idx := bytes.Index(buf[0:n], panicHeader) + if idx >= 0 { + flushIdx = idx + } + + // Flush to stderr what isn't a panic + w.Write(buf[0:flushIdx]) + + if idx < 0 { + // Not a panic so just continue along + continue + } + + // We have a panic header. Write we assume is a panic os far. + panicBuf.Write(buf[idx:n]) + panicTimer = time.After(dur) + } +} diff --git a/vendor/github.com/cenkalti/backoff/.gitignore b/vendor/github.com/cenkalti/backoff/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/cenkalti/backoff/.travis.yml b/vendor/github.com/cenkalti/backoff/.travis.yml new file mode 100644 index 0000000000..ce9cb62333 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/.travis.yml @@ -0,0 +1,2 @@ +language: go +go: 1.3.3 diff --git a/vendor/github.com/cenkalti/backoff/LICENSE b/vendor/github.com/cenkalti/backoff/LICENSE new file mode 100644 index 0000000000..89b8179965 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cenkalti/backoff/README.md b/vendor/github.com/cenkalti/backoff/README.md new file mode 100644 index 0000000000..8e2612e639 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/README.md @@ -0,0 +1,69 @@ +# backoff + +[![GoDoc](https://godoc.org/github.com/cenkalti/backoff?status.png)](https://godoc.org/github.com/cenkalti/backoff) +[![Build Status](https://travis-ci.org/cenkalti/backoff.png)](https://travis-ci.org/cenkalti/backoff) + +This is a Go port of the exponential backoff algorithm from +[google-http-java-client](https://code.google.com/p/google-http-java-client/wiki/ExponentialBackoff). + +[Exponential backoff](http://en.wikipedia.org/wiki/Exponential_backoff) +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + + + + +## Install + +```bash +go get github.com/cenkalti/backoff +``` + +## Example + +Simple retry helper that uses exponential back-off algorithm: + +```go +operation := func() error { + // An operation that might fail +} + +err := backoff.Retry(operation, backoff.NewExponentialBackOff()) +if err != nil { + // handle error +} + +// operation is successfull +``` + +Ticker example: + +```go +operation := func() error { + // An operation that may fail +} + +b := backoff.NewExponentialBackOff() +ticker := backoff.NewTicker(b) + +var err error + +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +for t = range ticker.C { + if err = operation(); err != nil { + log.Println(err, "will retry...") + continue + } + + ticker.Stop() + break +} + +if err != nil { + // Operation has failed. +} + +// Operation is successfull. +``` diff --git a/vendor/github.com/cenkalti/backoff/backoff.go b/vendor/github.com/cenkalti/backoff/backoff.go new file mode 100644 index 0000000000..25870d2fc8 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/backoff.go @@ -0,0 +1,56 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Also has a Retry() helper for retrying operations that may fail. +package backoff + +import "time" + +// Back-off policy when retrying an operation. +type BackOff interface { + // Gets the duration to wait before retrying the operation or + // backoff.Stop to indicate that no retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff(); + // if (duration == backoff.Stop) { + // // do not retry operation + // } else { + // // sleep for duration and retry operation + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed back-off policy whose back-off time is always zero, +// meaning that the operation is retried immediately without waiting. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed back-off policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should not be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/vendor/github.com/cenkalti/backoff/exponential.go b/vendor/github.com/cenkalti/backoff/exponential.go new file mode 100644 index 0000000000..e81e9c67a9 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/exponential.go @@ -0,0 +1,141 @@ +package backoff + +import ( + "math/rand" + "time" +) + +/* +ExponentialBackOff is an implementation of BackOff that increases the back off +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized_interval = + retry_interval * (random value in range [1 - randomization_factor, 1 + randomization_factor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. For example, using 2 seconds as the base retry +interval and 0.5 as the randomization factor, the actual back off period used in the next retry +attempt will be between 1 and 3 seconds. + +Note: max_interval caps the retry_interval and not the randomized_interval. + +If the time elapsed since an ExponentialBackOff instance is created goes past the +max_elapsed_time then the method NextBackOff() starts returning backoff.Stop. +The elapsed time can be reset by calling Reset(). + +Example: The default retry_interval is .5 seconds, default randomization_factor is 0.5, default +multiplier is 1.5 and the default max_interval is 1 minute. For 10 tries the sequence will be +(values in seconds) and assuming we go over the max_elapsed_time on the 10th try: + + request# retry_interval randomized_interval + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + 10 19.210 backoff.Stop + +Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + // After MaxElapsedTime the ExponentialBackOff stops. + // It never stops if MaxElapsedTime == 0. + MaxElapsedTime time.Duration + Clock Clock + + currentInterval time.Duration + startTime time.Time +} + +// Clock is an interface that returns current time for BackOff. +type Clock interface { + Now() time.Time +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second + DefaultMaxElapsedTime = 15 * time.Minute +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + return &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + MaxElapsedTime: DefaultMaxElapsedTime, + Clock: SystemClock, + } +} + +type systemClock struct{} + +func (t systemClock) Now() time.Time { + return time.Now() +} + +// SystemClock implements Clock interface that uses time.Now(). +var SystemClock = systemClock{} + +// Reset the interval back to the initial retry interval and restarts the timer. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval + b.startTime = b.Clock.Now() +} + +// NextBackOff calculates the next back off interval using the formula: +// randomized_interval = retry_interval +/- (randomization_factor * retry_interval) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + // Make sure we have not gone over the maximum elapsed time. + if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime { + return Stop + } + defer b.incrementCurrentInterval() + return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) +} + +// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance +// is created and is reset when Reset() is called. +// +// The elapsed time is computed using time.Now().UnixNano(). +func (b *ExponentialBackOff) GetElapsedTime() time.Duration { + return b.Clock.Now().Sub(b.startTime) +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the interval: +// [randomizationFactor * currentInterval, randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/vendor/github.com/cenkalti/backoff/retry.go b/vendor/github.com/cenkalti/backoff/retry.go new file mode 100644 index 0000000000..80c5477678 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/retry.go @@ -0,0 +1,47 @@ +package backoff + +import "time" + +// Retry the function f until it does not return error or BackOff stops. +// f is guaranteed to be run at least once. +// It is the caller's responsibility to reset b after Retry returns. +// +// Retry sleeps the goroutine for the duration returned by BackOff after a +// failed operation returns. +// +// Usage: +// operation := func() error { +// // An operation that may fail +// } +// +// err := backoff.Retry(operation, backoff.NewExponentialBackOff()) +// if err != nil { +// // Operation has failed. +// } +// +// // Operation is successfull. +// +func Retry(f func() error, b BackOff) error { return RetryNotify(f, b, nil) } + +// RetryNotify calls notify function with the error and wait duration for each failed attempt before sleep. +func RetryNotify(f func() error, b BackOff, notify func(err error, wait time.Duration)) error { + var err error + var next time.Duration + + b.Reset() + for { + if err = f(); err == nil { + return nil + } + + if next = b.NextBackOff(); next == Stop { + return err + } + + if notify != nil { + notify(err, next) + } + + time.Sleep(next) + } +} diff --git a/vendor/github.com/cenkalti/backoff/ticker.go b/vendor/github.com/cenkalti/backoff/ticker.go new file mode 100644 index 0000000000..17ace56600 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/ticker.go @@ -0,0 +1,105 @@ +package backoff + +import ( + "runtime" + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +// +// Usage: +// operation := func() error { +// // An operation that may fail +// } +// +// b := backoff.NewExponentialBackOff() +// ticker := backoff.NewTicker(b) +// +// var err error +// for _ = range ticker.C { +// if err = operation(); err != nil { +// log.Println(err, "will retry...") +// continue +// } +// +// ticker.Stop() +// break +// } +// +// if err != nil { +// // Operation has failed. +// } +// +// // Operation is successfull. +// +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOff + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send the time at times +// specified by the BackOff argument. Ticker is guaranteed to tick at least once. +// The channel is closed when Stop method is called or BackOff stops. +func NewTicker(b BackOff) *Ticker { + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: b, + stop: make(chan struct{}), + } + go t.run() + runtime.SetFinalizer(t, (*Ticker).Stop) + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + t.b.Reset() + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + return time.After(next) +} diff --git a/vendor/github.com/codegangsta/cli/.travis.yml b/vendor/github.com/codegangsta/cli/.travis.yml new file mode 100644 index 0000000000..87ba52f98e --- /dev/null +++ b/vendor/github.com/codegangsta/cli/.travis.yml @@ -0,0 +1,19 @@ +language: go +sudo: false + +go: +- 1.0.3 +- 1.1.2 +- 1.2.2 +- 1.3.3 +- 1.4.2 +- 1.5.1 +- tip + +matrix: + allow_failures: + - go: tip + +script: +- go vet ./... +- go test -v ./... diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE b/vendor/github.com/codegangsta/cli/LICENSE similarity index 100% rename from Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE rename to vendor/github.com/codegangsta/cli/LICENSE diff --git a/vendor/github.com/codegangsta/cli/README.md b/vendor/github.com/codegangsta/cli/README.md new file mode 100644 index 0000000000..26a183865d --- /dev/null +++ b/vendor/github.com/codegangsta/cli/README.md @@ -0,0 +1,341 @@ +[![Coverage](http://gocover.io/_badge/github.com/codegangsta/cli?0)](http://gocover.io/github.com/codegangsta/cli) +[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli) +[![GoDoc](https://godoc.org/github.com/codegangsta/cli?status.svg)](https://godoc.org/github.com/codegangsta/cli) + +# cli.go +`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. + +## Overview +Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app. + +**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive! + +## Installation +Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html). + +To install `cli.go`, simply run: +``` +$ go get github.com/codegangsta/cli +``` + +Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used: +``` +export PATH=$PATH:$GOPATH/bin +``` + +## Getting Started +One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`. + +``` go +package main + +import ( + "os" + "github.com/codegangsta/cli" +) + +func main() { + cli.NewApp().Run(os.Args) +} +``` + +This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation: + +``` go +package main + +import ( + "os" + "github.com/codegangsta/cli" +) + +func main() { + app := cli.NewApp() + app.Name = "boom" + app.Usage = "make an explosive entrance" + app.Action = func(c *cli.Context) { + println("boom! I say!") + } + + app.Run(os.Args) +} +``` + +Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below. + +## Example + +Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness! + +Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it: + +``` go +package main + +import ( + "os" + "github.com/codegangsta/cli" +) + +func main() { + app := cli.NewApp() + app.Name = "greet" + app.Usage = "fight the loneliness!" + app.Action = func(c *cli.Context) { + println("Hello friend!") + } + + app.Run(os.Args) +} +``` + +Install our command to the `$GOPATH/bin` directory: + +``` +$ go install +``` + +Finally run our new command: + +``` +$ greet +Hello friend! +``` + +`cli.go` also generates neat help text: + +``` +$ greet help +NAME: + greet - fight the loneliness! + +USAGE: + greet [global options] command [command options] [arguments...] + +VERSION: + 0.0.0 + +COMMANDS: + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS + --version Shows version information +``` + +### Arguments +You can lookup arguments by calling the `Args` function on `cli.Context`. + +``` go +... +app.Action = func(c *cli.Context) { + println("Hello", c.Args()[0]) +} +... +``` + +### Flags +Setting and querying flags is simple. +``` go +... +app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang", + Value: "english", + Usage: "language for the greeting", + }, +} +app.Action = func(c *cli.Context) { + name := "someone" + if len(c.Args()) > 0 { + name = c.Args()[0] + } + if c.String("lang") == "spanish" { + println("Hola", name) + } else { + println("Hello", name) + } +} +... +``` + +You can also set a destination variable for a flag, to which the content will be scanned. +``` go +... +var language string +app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang", + Value: "english", + Usage: "language for the greeting", + Destination: &language, + }, +} +app.Action = func(c *cli.Context) { + name := "someone" + if len(c.Args()) > 0 { + name = c.Args()[0] + } + if language == "spanish" { + println("Hola", name) + } else { + println("Hello", name) + } +} +... +``` + +See full list of flags at http://godoc.org/github.com/codegangsta/cli + +#### Alternate Names + +You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g. + +``` go +app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang, l", + Value: "english", + Usage: "language for the greeting", + }, +} +``` + +That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error. + +#### Values from the Environment + +You can also have the default value set from the environment via `EnvVar`. e.g. + +``` go +app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang, l", + Value: "english", + Usage: "language for the greeting", + EnvVar: "APP_LANG", + }, +} +``` + +The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default. + +``` go +app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang, l", + Value: "english", + Usage: "language for the greeting", + EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG", + }, +} +``` + +### Subcommands + +Subcommands can be defined for a more git-like command line app. +```go +... +app.Commands = []cli.Command{ + { + Name: "add", + Aliases: []string{"a"}, + Usage: "add a task to the list", + Action: func(c *cli.Context) { + println("added task: ", c.Args().First()) + }, + }, + { + Name: "complete", + Aliases: []string{"c"}, + Usage: "complete a task on the list", + Action: func(c *cli.Context) { + println("completed task: ", c.Args().First()) + }, + }, + { + Name: "template", + Aliases: []string{"r"}, + Usage: "options for task templates", + Subcommands: []cli.Command{ + { + Name: "add", + Usage: "add a new template", + Action: func(c *cli.Context) { + println("new task template: ", c.Args().First()) + }, + }, + { + Name: "remove", + Usage: "remove an existing template", + Action: func(c *cli.Context) { + println("removed task template: ", c.Args().First()) + }, + }, + }, + }, +} +... +``` + +### Bash Completion + +You can enable completion commands by setting the `EnableBashCompletion` +flag on the `App` object. By default, this setting will only auto-complete to +show an app's subcommands, but you can write your own completion methods for +the App or its subcommands. +```go +... +var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"} +app := cli.NewApp() +app.EnableBashCompletion = true +app.Commands = []cli.Command{ + { + Name: "complete", + Aliases: []string{"c"}, + Usage: "complete a task on the list", + Action: func(c *cli.Context) { + println("completed task: ", c.Args().First()) + }, + BashComplete: func(c *cli.Context) { + // This will complete if no args are passed + if len(c.Args()) > 0 { + return + } + for _, t := range tasks { + fmt.Println(t) + } + }, + } +} +... +``` + +#### To Enable + +Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while +setting the `PROG` variable to the name of your program: + +`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` + +#### To Distribute + +Copy `autocomplete/bash_autocomplete` into `/etc/bash_completion.d/` and rename +it to the name of the program you wish to add autocomplete support for (or +automatically install it there if you are distributing a package). Don't forget +to source the file to make it active in the current shell. + +``` + sudo cp src/bash_autocomplete /etc/bash_completion.d/ + source /etc/bash_completion.d/ +``` + +Alternatively, you can just document that users should source the generic +`autocomplete/bash_autocomplete` in their bash configuration with `$PROG` set +to the name of their program (as above). + +## Contribution Guidelines +Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch. + +If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together. + +If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out. diff --git a/vendor/github.com/codegangsta/cli/app.go b/vendor/github.com/codegangsta/cli/app.go new file mode 100644 index 0000000000..9a15c0c038 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/app.go @@ -0,0 +1,333 @@ +package cli + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "time" +) + +// App is the main structure of a cli application. It is recomended that +// an app be created with the cli.NewApp() function +type App struct { + // The name of the program. Defaults to os.Args[0] + Name string + // Full name of command for help, defaults to Name + HelpName string + // Description of the program. + Usage string + // Description of the program argument format. + ArgsUsage string + // Version of the program + Version string + // List of commands to execute + Commands []Command + // List of flags to parse + Flags []Flag + // Boolean to enable bash completion commands + EnableBashCompletion bool + // Boolean to hide built-in help command + HideHelp bool + // Boolean to hide built-in version flag + HideVersion bool + // An action to execute when the bash-completion flag is set + BashComplete func(context *Context) + // An action to execute before any subcommands are run, but after the context is ready + // If a non-nil error is returned, no subcommands are run + Before func(context *Context) error + // An action to execute after any subcommands are run, but after the subcommand has finished + // It is run even if Action() panics + After func(context *Context) error + // The action to execute when no subcommands are specified + Action func(context *Context) + // Execute this function if the proper command cannot be found + CommandNotFound func(context *Context, command string) + // Compilation date + Compiled time.Time + // List of all authors who contributed + Authors []Author + // Copyright of the binary if any + Copyright string + // Name of Author (Note: Use App.Authors, this is deprecated) + Author string + // Email of Author (Note: Use App.Authors, this is deprecated) + Email string + // Writer writer to write output to + Writer io.Writer +} + +// Tries to find out when this binary was compiled. +// Returns the current time if it fails to find it. +func compileTime() time.Time { + info, err := os.Stat(os.Args[0]) + if err != nil { + return time.Now() + } + return info.ModTime() +} + +// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action. +func NewApp() *App { + return &App{ + Name: os.Args[0], + HelpName: os.Args[0], + Usage: "A new cli application", + Version: "0.0.0", + BashComplete: DefaultAppComplete, + Action: helpCommand.Action, + Compiled: compileTime(), + Writer: os.Stdout, + } +} + +// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination +func (a *App) Run(arguments []string) (err error) { + if a.Author != "" || a.Email != "" { + a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email}) + } + + newCmds := []Command{} + for _, c := range a.Commands { + if c.HelpName == "" { + c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) + } + newCmds = append(newCmds, c) + } + a.Commands = newCmds + + // append help to commands + if a.Command(helpCommand.Name) == nil && !a.HideHelp { + a.Commands = append(a.Commands, helpCommand) + if (HelpFlag != BoolFlag{}) { + a.appendFlag(HelpFlag) + } + } + + //append version/help flags + if a.EnableBashCompletion { + a.appendFlag(BashCompletionFlag) + } + + if !a.HideVersion { + a.appendFlag(VersionFlag) + } + + // parse flags + set := flagSet(a.Name, a.Flags) + set.SetOutput(ioutil.Discard) + err = set.Parse(arguments[1:]) + nerr := normalizeFlags(a.Flags, set) + if nerr != nil { + fmt.Fprintln(a.Writer, nerr) + context := NewContext(a, set, nil) + ShowAppHelp(context) + return nerr + } + context := NewContext(a, set, nil) + + if err != nil { + fmt.Fprintln(a.Writer, "Incorrect Usage.") + fmt.Fprintln(a.Writer) + ShowAppHelp(context) + return err + } + + if checkCompletions(context) { + return nil + } + + if !a.HideHelp && checkHelp(context) { + ShowAppHelp(context) + return nil + } + + if !a.HideVersion && checkVersion(context) { + ShowVersion(context) + return nil + } + + if a.After != nil { + defer func() { + afterErr := a.After(context) + if afterErr != nil { + if err != nil { + err = NewMultiError(err, afterErr) + } else { + err = afterErr + } + } + }() + } + + if a.Before != nil { + err := a.Before(context) + if err != nil { + return err + } + } + + args := context.Args() + if args.Present() { + name := args.First() + c := a.Command(name) + if c != nil { + return c.Run(context) + } + } + + // Run default Action + a.Action(context) + return nil +} + +// Another entry point to the cli app, takes care of passing arguments and error handling +func (a *App) RunAndExitOnError() { + if err := a.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags +func (a *App) RunAsSubcommand(ctx *Context) (err error) { + // append help to commands + if len(a.Commands) > 0 { + if a.Command(helpCommand.Name) == nil && !a.HideHelp { + a.Commands = append(a.Commands, helpCommand) + if (HelpFlag != BoolFlag{}) { + a.appendFlag(HelpFlag) + } + } + } + + newCmds := []Command{} + for _, c := range a.Commands { + if c.HelpName == "" { + c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) + } + newCmds = append(newCmds, c) + } + a.Commands = newCmds + + // append flags + if a.EnableBashCompletion { + a.appendFlag(BashCompletionFlag) + } + + // parse flags + set := flagSet(a.Name, a.Flags) + set.SetOutput(ioutil.Discard) + err = set.Parse(ctx.Args().Tail()) + nerr := normalizeFlags(a.Flags, set) + context := NewContext(a, set, ctx) + + if nerr != nil { + fmt.Fprintln(a.Writer, nerr) + fmt.Fprintln(a.Writer) + if len(a.Commands) > 0 { + ShowSubcommandHelp(context) + } else { + ShowCommandHelp(ctx, context.Args().First()) + } + return nerr + } + + if err != nil { + fmt.Fprintln(a.Writer, "Incorrect Usage.") + fmt.Fprintln(a.Writer) + ShowSubcommandHelp(context) + return err + } + + if checkCompletions(context) { + return nil + } + + if len(a.Commands) > 0 { + if checkSubcommandHelp(context) { + return nil + } + } else { + if checkCommandHelp(ctx, context.Args().First()) { + return nil + } + } + + if a.After != nil { + defer func() { + afterErr := a.After(context) + if afterErr != nil { + if err != nil { + err = NewMultiError(err, afterErr) + } else { + err = afterErr + } + } + }() + } + + if a.Before != nil { + err := a.Before(context) + if err != nil { + return err + } + } + + args := context.Args() + if args.Present() { + name := args.First() + c := a.Command(name) + if c != nil { + return c.Run(context) + } + } + + // Run default Action + a.Action(context) + + return nil +} + +// Returns the named command on App. Returns nil if the command does not exist +func (a *App) Command(name string) *Command { + for _, c := range a.Commands { + if c.HasName(name) { + return &c + } + } + + return nil +} + +func (a *App) hasFlag(flag Flag) bool { + for _, f := range a.Flags { + if flag == f { + return true + } + } + + return false +} + +func (a *App) appendFlag(flag Flag) { + if !a.hasFlag(flag) { + a.Flags = append(a.Flags, flag) + } +} + +// Author represents someone who has contributed to a cli project. +type Author struct { + Name string // The Authors name + Email string // The Authors email +} + +// String makes Author comply to the Stringer interface, to allow an easy print in the templating process +func (a Author) String() string { + e := "" + if a.Email != "" { + e = "<" + a.Email + "> " + } + + return fmt.Sprintf("%v %v", a.Name, e) +} diff --git a/vendor/github.com/codegangsta/cli/cli.go b/vendor/github.com/codegangsta/cli/cli.go new file mode 100644 index 0000000000..31dc9124d1 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/cli.go @@ -0,0 +1,40 @@ +// Package cli provides a minimal framework for creating and organizing command line +// Go applications. cli is designed to be easy to understand and write, the most simple +// cli application can be written as follows: +// func main() { +// cli.NewApp().Run(os.Args) +// } +// +// Of course this application does not do much, so let's make this an actual application: +// func main() { +// app := cli.NewApp() +// app.Name = "greet" +// app.Usage = "say a greeting" +// app.Action = func(c *cli.Context) { +// println("Greetings") +// } +// +// app.Run(os.Args) +// } +package cli + +import ( + "strings" +) + +type MultiError struct { + Errors []error +} + +func NewMultiError(err ...error) MultiError { + return MultiError{Errors: err} +} + +func (m MultiError) Error() string { + errs := make([]string, len(m.Errors)) + for i, err := range m.Errors { + errs[i] = err.Error() + } + + return strings.Join(errs, "\n") +} diff --git a/vendor/github.com/codegangsta/cli/command.go b/vendor/github.com/codegangsta/cli/command.go new file mode 100644 index 0000000000..824e77bae3 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/command.go @@ -0,0 +1,216 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "strings" +) + +// Command is a subcommand for a cli.App. +type Command struct { + // The name of the command + Name string + // short name of the command. Typically one character (deprecated, use `Aliases`) + ShortName string + // A list of aliases for the command + Aliases []string + // A short description of the usage of this command + Usage string + // A longer explanation of how the command works + Description string + // A short description of the arguments of this command + ArgsUsage string + // The function to call when checking for bash command completions + BashComplete func(context *Context) + // An action to execute before any sub-subcommands are run, but after the context is ready + // If a non-nil error is returned, no sub-subcommands are run + Before func(context *Context) error + // An action to execute after any subcommands are run, but after the subcommand has finished + // It is run even if Action() panics + After func(context *Context) error + // The function to call when this command is invoked + Action func(context *Context) + // List of child commands + Subcommands []Command + // List of flags to parse + Flags []Flag + // Treat all flags as normal arguments if true + SkipFlagParsing bool + // Boolean to hide built-in help command + HideHelp bool + + // Full name of command for help, defaults to full command name, including parent commands. + HelpName string + commandNamePath []string +} + +// Returns the full name of the command. +// For subcommands this ensures that parent commands are part of the command path +func (c Command) FullName() string { + if c.commandNamePath == nil { + return c.Name + } + return strings.Join(c.commandNamePath, " ") +} + +// Invokes the command given the context, parses ctx.Args() to generate command-specific flags +func (c Command) Run(ctx *Context) error { + if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil { + return c.startApp(ctx) + } + + if !c.HideHelp && (HelpFlag != BoolFlag{}) { + // append help to flags + c.Flags = append( + c.Flags, + HelpFlag, + ) + } + + if ctx.App.EnableBashCompletion { + c.Flags = append(c.Flags, BashCompletionFlag) + } + + set := flagSet(c.Name, c.Flags) + set.SetOutput(ioutil.Discard) + + var err error + if !c.SkipFlagParsing { + firstFlagIndex := -1 + terminatorIndex := -1 + for index, arg := range ctx.Args() { + if arg == "--" { + terminatorIndex = index + break + } else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 { + firstFlagIndex = index + } + } + + if firstFlagIndex > -1 { + args := ctx.Args() + regularArgs := make([]string, len(args[1:firstFlagIndex])) + copy(regularArgs, args[1:firstFlagIndex]) + + var flagArgs []string + if terminatorIndex > -1 { + flagArgs = args[firstFlagIndex:terminatorIndex] + regularArgs = append(regularArgs, args[terminatorIndex:]...) + } else { + flagArgs = args[firstFlagIndex:] + } + + err = set.Parse(append(flagArgs, regularArgs...)) + } else { + err = set.Parse(ctx.Args().Tail()) + } + } else { + if c.SkipFlagParsing { + err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...)) + } + } + + if err != nil { + fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.") + fmt.Fprintln(ctx.App.Writer) + ShowCommandHelp(ctx, c.Name) + return err + } + + nerr := normalizeFlags(c.Flags, set) + if nerr != nil { + fmt.Fprintln(ctx.App.Writer, nerr) + fmt.Fprintln(ctx.App.Writer) + ShowCommandHelp(ctx, c.Name) + return nerr + } + context := NewContext(ctx.App, set, ctx) + + if checkCommandCompletions(context, c.Name) { + return nil + } + + if checkCommandHelp(context, c.Name) { + return nil + } + context.Command = c + c.Action(context) + return nil +} + +func (c Command) Names() []string { + names := []string{c.Name} + + if c.ShortName != "" { + names = append(names, c.ShortName) + } + + return append(names, c.Aliases...) +} + +// Returns true if Command.Name or Command.ShortName matches given name +func (c Command) HasName(name string) bool { + for _, n := range c.Names() { + if n == name { + return true + } + } + return false +} + +func (c Command) startApp(ctx *Context) error { + app := NewApp() + + // set the name and usage + app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) + if c.HelpName == "" { + app.HelpName = c.HelpName + } else { + app.HelpName = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) + } + + if c.Description != "" { + app.Usage = c.Description + } else { + app.Usage = c.Usage + } + + // set CommandNotFound + app.CommandNotFound = ctx.App.CommandNotFound + + // set the flags and commands + app.Commands = c.Subcommands + app.Flags = c.Flags + app.HideHelp = c.HideHelp + + app.Version = ctx.App.Version + app.HideVersion = ctx.App.HideVersion + app.Compiled = ctx.App.Compiled + app.Author = ctx.App.Author + app.Email = ctx.App.Email + app.Writer = ctx.App.Writer + + // bash completion + app.EnableBashCompletion = ctx.App.EnableBashCompletion + if c.BashComplete != nil { + app.BashComplete = c.BashComplete + } + + // set the actions + app.Before = c.Before + app.After = c.After + if c.Action != nil { + app.Action = c.Action + } else { + app.Action = helpSubcommand.Action + } + + var newCmds []Command + for _, cc := range app.Commands { + cc.commandNamePath = []string{c.Name, cc.Name} + newCmds = append(newCmds, cc) + } + app.Commands = newCmds + + return app.RunAsSubcommand(ctx) +} diff --git a/vendor/github.com/codegangsta/cli/context.go b/vendor/github.com/codegangsta/cli/context.go new file mode 100644 index 0000000000..f541f41c3c --- /dev/null +++ b/vendor/github.com/codegangsta/cli/context.go @@ -0,0 +1,388 @@ +package cli + +import ( + "errors" + "flag" + "strconv" + "strings" + "time" +) + +// Context is a type that is passed through to +// each Handler action in a cli application. Context +// can be used to retrieve context-specific Args and +// parsed command-line options. +type Context struct { + App *App + Command Command + flagSet *flag.FlagSet + setFlags map[string]bool + globalSetFlags map[string]bool + parentContext *Context +} + +// Creates a new context. For use in when invoking an App or Command action. +func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { + return &Context{App: app, flagSet: set, parentContext: parentCtx} +} + +// Looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Int(name string) int { + return lookupInt(name, c.flagSet) +} + +// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists +func (c *Context) Duration(name string) time.Duration { + return lookupDuration(name, c.flagSet) +} + +// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists +func (c *Context) Float64(name string) float64 { + return lookupFloat64(name, c.flagSet) +} + +// Looks up the value of a local bool flag, returns false if no bool flag exists +func (c *Context) Bool(name string) bool { + return lookupBool(name, c.flagSet) +} + +// Looks up the value of a local boolT flag, returns false if no bool flag exists +func (c *Context) BoolT(name string) bool { + return lookupBoolT(name, c.flagSet) +} + +// Looks up the value of a local string flag, returns "" if no string flag exists +func (c *Context) String(name string) string { + return lookupString(name, c.flagSet) +} + +// Looks up the value of a local string slice flag, returns nil if no string slice flag exists +func (c *Context) StringSlice(name string) []string { + return lookupStringSlice(name, c.flagSet) +} + +// Looks up the value of a local int slice flag, returns nil if no int slice flag exists +func (c *Context) IntSlice(name string) []int { + return lookupIntSlice(name, c.flagSet) +} + +// Looks up the value of a local generic flag, returns nil if no generic flag exists +func (c *Context) Generic(name string) interface{} { + return lookupGeneric(name, c.flagSet) +} + +// Looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalInt(name string) int { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt(name, fs) + } + return 0 +} + +// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists +func (c *Context) GlobalDuration(name string) time.Duration { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupDuration(name, fs) + } + return 0 +} + +// Looks up the value of a global bool flag, returns false if no bool flag exists +func (c *Context) GlobalBool(name string) bool { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupBool(name, fs) + } + return false +} + +// Looks up the value of a global string flag, returns "" if no string flag exists +func (c *Context) GlobalString(name string) string { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupString(name, fs) + } + return "" +} + +// Looks up the value of a global string slice flag, returns nil if no string slice flag exists +func (c *Context) GlobalStringSlice(name string) []string { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupStringSlice(name, fs) + } + return nil +} + +// Looks up the value of a global int slice flag, returns nil if no int slice flag exists +func (c *Context) GlobalIntSlice(name string) []int { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupIntSlice(name, fs) + } + return nil +} + +// Looks up the value of a global generic flag, returns nil if no generic flag exists +func (c *Context) GlobalGeneric(name string) interface{} { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupGeneric(name, fs) + } + return nil +} + +// Returns the number of flags set +func (c *Context) NumFlags() int { + return c.flagSet.NFlag() +} + +// Determines if the flag was actually set +func (c *Context) IsSet(name string) bool { + if c.setFlags == nil { + c.setFlags = make(map[string]bool) + c.flagSet.Visit(func(f *flag.Flag) { + c.setFlags[f.Name] = true + }) + } + return c.setFlags[name] == true +} + +// Determines if the global flag was actually set +func (c *Context) GlobalIsSet(name string) bool { + if c.globalSetFlags == nil { + c.globalSetFlags = make(map[string]bool) + ctx := c + if ctx.parentContext != nil { + ctx = ctx.parentContext + } + for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext { + ctx.flagSet.Visit(func(f *flag.Flag) { + c.globalSetFlags[f.Name] = true + }) + } + } + return c.globalSetFlags[name] +} + +// Returns a slice of flag names used in this context. +func (c *Context) FlagNames() (names []string) { + for _, flag := range c.Command.Flags { + name := strings.Split(flag.getName(), ",")[0] + if name == "help" { + continue + } + names = append(names, name) + } + return +} + +// Returns a slice of global flag names used by the app. +func (c *Context) GlobalFlagNames() (names []string) { + for _, flag := range c.App.Flags { + name := strings.Split(flag.getName(), ",")[0] + if name == "help" || name == "version" { + continue + } + names = append(names, name) + } + return +} + +// Returns the parent context, if any +func (c *Context) Parent() *Context { + return c.parentContext +} + +type Args []string + +// Returns the command line arguments associated with the context. +func (c *Context) Args() Args { + args := Args(c.flagSet.Args()) + return args +} + +// Returns the nth argument, or else a blank string +func (a Args) Get(n int) string { + if len(a) > n { + return a[n] + } + return "" +} + +// Returns the first argument, or else a blank string +func (a Args) First() string { + return a.Get(0) +} + +// Return the rest of the arguments (not the first one) +// or else an empty string slice +func (a Args) Tail() []string { + if len(a) >= 2 { + return []string(a)[1:] + } + return []string{} +} + +// Checks if there are any arguments present +func (a Args) Present() bool { + return len(a) != 0 +} + +// Swaps arguments at the given indexes +func (a Args) Swap(from, to int) error { + if from >= len(a) || to >= len(a) { + return errors.New("index out of range") + } + a[from], a[to] = a[to], a[from] + return nil +} + +func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { + if ctx.parentContext != nil { + ctx = ctx.parentContext + } + for ; ctx != nil; ctx = ctx.parentContext { + if f := ctx.flagSet.Lookup(name); f != nil { + return ctx.flagSet + } + } + return nil +} + +func lookupInt(name string, set *flag.FlagSet) int { + f := set.Lookup(name) + if f != nil { + val, err := strconv.Atoi(f.Value.String()) + if err != nil { + return 0 + } + return val + } + + return 0 +} + +func lookupDuration(name string, set *flag.FlagSet) time.Duration { + f := set.Lookup(name) + if f != nil { + val, err := time.ParseDuration(f.Value.String()) + if err == nil { + return val + } + } + + return 0 +} + +func lookupFloat64(name string, set *flag.FlagSet) float64 { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseFloat(f.Value.String(), 64) + if err != nil { + return 0 + } + return val + } + + return 0 +} + +func lookupString(name string, set *flag.FlagSet) string { + f := set.Lookup(name) + if f != nil { + return f.Value.String() + } + + return "" +} + +func lookupStringSlice(name string, set *flag.FlagSet) []string { + f := set.Lookup(name) + if f != nil { + return (f.Value.(*StringSlice)).Value() + + } + + return nil +} + +func lookupIntSlice(name string, set *flag.FlagSet) []int { + f := set.Lookup(name) + if f != nil { + return (f.Value.(*IntSlice)).Value() + + } + + return nil +} + +func lookupGeneric(name string, set *flag.FlagSet) interface{} { + f := set.Lookup(name) + if f != nil { + return f.Value + } + return nil +} + +func lookupBool(name string, set *flag.FlagSet) bool { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseBool(f.Value.String()) + if err != nil { + return false + } + return val + } + + return false +} + +func lookupBoolT(name string, set *flag.FlagSet) bool { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseBool(f.Value.String()) + if err != nil { + return true + } + return val + } + + return false +} + +func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { + switch ff.Value.(type) { + case *StringSlice: + default: + set.Set(name, ff.Value.String()) + } +} + +func normalizeFlags(flags []Flag, set *flag.FlagSet) error { + visited := make(map[string]bool) + set.Visit(func(f *flag.Flag) { + visited[f.Name] = true + }) + for _, f := range flags { + parts := strings.Split(f.getName(), ",") + if len(parts) == 1 { + continue + } + var ff *flag.Flag + for _, name := range parts { + name = strings.Trim(name, " ") + if visited[name] { + if ff != nil { + return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name) + } + ff = set.Lookup(name) + } + } + if ff == nil { + continue + } + for _, name := range parts { + name = strings.Trim(name, " ") + if !visited[name] { + copyFlag(name, ff, set) + } + } + } + return nil +} diff --git a/vendor/github.com/codegangsta/cli/flag.go b/vendor/github.com/codegangsta/cli/flag.go new file mode 100644 index 0000000000..9b22d7f1f2 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/flag.go @@ -0,0 +1,527 @@ +package cli + +import ( + "flag" + "fmt" + "os" + "strconv" + "strings" + "time" +) + +// This flag enables bash-completion for all commands and subcommands +var BashCompletionFlag = BoolFlag{ + Name: "generate-bash-completion", +} + +// This flag prints the version for the application +var VersionFlag = BoolFlag{ + Name: "version, v", + Usage: "print the version", +} + +// This flag prints the help for all commands and subcommands +// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand +// unless HideHelp is set to true) +var HelpFlag = BoolFlag{ + Name: "help, h", + Usage: "show help", +} + +// Flag is a common interface related to parsing flags in cli. +// For more advanced flag parsing techniques, it is recomended that +// this interface be implemented. +type Flag interface { + fmt.Stringer + // Apply Flag settings to the given flag set + Apply(*flag.FlagSet) + getName() string +} + +func flagSet(name string, flags []Flag) *flag.FlagSet { + set := flag.NewFlagSet(name, flag.ContinueOnError) + + for _, f := range flags { + f.Apply(set) + } + return set +} + +func eachName(longName string, fn func(string)) { + parts := strings.Split(longName, ",") + for _, name := range parts { + name = strings.Trim(name, " ") + fn(name) + } +} + +// Generic is a generic parseable type identified by a specific flag +type Generic interface { + Set(value string) error + String() string +} + +// GenericFlag is the flag type for types implementing Generic +type GenericFlag struct { + Name string + Value Generic + Usage string + EnvVar string +} + +// String returns the string representation of the generic flag to display the +// help text to the user (uses the String() method of the generic flag to show +// the value) +func (f GenericFlag) String() string { + return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s \"%v\"\t%v", prefixFor(f.Name), f.Name, f.Value, f.Usage)) +} + +// Apply takes the flagset and calls Set on the generic flag with the value +// provided by the user for parsing by the flag +func (f GenericFlag) Apply(set *flag.FlagSet) { + val := f.Value + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + val.Set(envVal) + break + } + } + } + + eachName(f.Name, func(name string) { + set.Var(f.Value, name, f.Usage) + }) +} + +func (f GenericFlag) getName() string { + return f.Name +} + +// StringSlice is an opaque type for []string to satisfy flag.Value +type StringSlice []string + +// Set appends the string value to the list of values +func (f *StringSlice) Set(value string) error { + *f = append(*f, value) + return nil +} + +// String returns a readable representation of this value (for usage defaults) +func (f *StringSlice) String() string { + return fmt.Sprintf("%s", *f) +} + +// Value returns the slice of strings set by this flag +func (f *StringSlice) Value() []string { + return *f +} + +// StringSlice is a string flag that can be specified multiple times on the +// command-line +type StringSliceFlag struct { + Name string + Value *StringSlice + Usage string + EnvVar string +} + +// String returns the usage +func (f StringSliceFlag) String() string { + firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") + pref := prefixFor(firstName) + return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f StringSliceFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + newVal := &StringSlice{} + for _, s := range strings.Split(envVal, ",") { + s = strings.TrimSpace(s) + newVal.Set(s) + } + f.Value = newVal + break + } + } + } + + eachName(f.Name, func(name string) { + if f.Value == nil { + f.Value = &StringSlice{} + } + set.Var(f.Value, name, f.Usage) + }) +} + +func (f StringSliceFlag) getName() string { + return f.Name +} + +// StringSlice is an opaque type for []int to satisfy flag.Value +type IntSlice []int + +// Set parses the value into an integer and appends it to the list of values +func (f *IntSlice) Set(value string) error { + tmp, err := strconv.Atoi(value) + if err != nil { + return err + } else { + *f = append(*f, tmp) + } + return nil +} + +// String returns a readable representation of this value (for usage defaults) +func (f *IntSlice) String() string { + return fmt.Sprintf("%d", *f) +} + +// Value returns the slice of ints set by this flag +func (f *IntSlice) Value() []int { + return *f +} + +// IntSliceFlag is an int flag that can be specified multiple times on the +// command-line +type IntSliceFlag struct { + Name string + Value *IntSlice + Usage string + EnvVar string +} + +// String returns the usage +func (f IntSliceFlag) String() string { + firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") + pref := prefixFor(firstName) + return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f IntSliceFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + newVal := &IntSlice{} + for _, s := range strings.Split(envVal, ",") { + s = strings.TrimSpace(s) + err := newVal.Set(s) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + } + } + f.Value = newVal + break + } + } + } + + eachName(f.Name, func(name string) { + if f.Value == nil { + f.Value = &IntSlice{} + } + set.Var(f.Value, name, f.Usage) + }) +} + +func (f IntSliceFlag) getName() string { + return f.Name +} + +// BoolFlag is a switch that defaults to false +type BoolFlag struct { + Name string + Usage string + EnvVar string + Destination *bool +} + +// String returns a readable representation of this value (for usage defaults) +func (f BoolFlag) String() string { + return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f BoolFlag) Apply(set *flag.FlagSet) { + val := false + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValBool, err := strconv.ParseBool(envVal) + if err == nil { + val = envValBool + } + break + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.BoolVar(f.Destination, name, val, f.Usage) + return + } + set.Bool(name, val, f.Usage) + }) +} + +func (f BoolFlag) getName() string { + return f.Name +} + +// BoolTFlag this represents a boolean flag that is true by default, but can +// still be set to false by --some-flag=false +type BoolTFlag struct { + Name string + Usage string + EnvVar string + Destination *bool +} + +// String returns a readable representation of this value (for usage defaults) +func (f BoolTFlag) String() string { + return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f BoolTFlag) Apply(set *flag.FlagSet) { + val := true + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValBool, err := strconv.ParseBool(envVal) + if err == nil { + val = envValBool + break + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.BoolVar(f.Destination, name, val, f.Usage) + return + } + set.Bool(name, val, f.Usage) + }) +} + +func (f BoolTFlag) getName() string { + return f.Name +} + +// StringFlag represents a flag that takes as string value +type StringFlag struct { + Name string + Value string + Usage string + EnvVar string + Destination *string +} + +// String returns the usage +func (f StringFlag) String() string { + var fmtString string + fmtString = "%s %v\t%v" + + if len(f.Value) > 0 { + fmtString = "%s \"%v\"\t%v" + } else { + fmtString = "%s %v\t%v" + } + + return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f StringFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + f.Value = envVal + break + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.StringVar(f.Destination, name, f.Value, f.Usage) + return + } + set.String(name, f.Value, f.Usage) + }) +} + +func (f StringFlag) getName() string { + return f.Name +} + +// IntFlag is a flag that takes an integer +// Errors if the value provided cannot be parsed +type IntFlag struct { + Name string + Value int + Usage string + EnvVar string + Destination *int +} + +// String returns the usage +func (f IntFlag) String() string { + return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f IntFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseInt(envVal, 0, 64) + if err == nil { + f.Value = int(envValInt) + break + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.IntVar(f.Destination, name, f.Value, f.Usage) + return + } + set.Int(name, f.Value, f.Usage) + }) +} + +func (f IntFlag) getName() string { + return f.Name +} + +// DurationFlag is a flag that takes a duration specified in Go's duration +// format: https://golang.org/pkg/time/#ParseDuration +type DurationFlag struct { + Name string + Value time.Duration + Usage string + EnvVar string + Destination *time.Duration +} + +// String returns a readable representation of this value (for usage defaults) +func (f DurationFlag) String() string { + return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f DurationFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValDuration, err := time.ParseDuration(envVal) + if err == nil { + f.Value = envValDuration + break + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.DurationVar(f.Destination, name, f.Value, f.Usage) + return + } + set.Duration(name, f.Value, f.Usage) + }) +} + +func (f DurationFlag) getName() string { + return f.Name +} + +// Float64Flag is a flag that takes an float value +// Errors if the value provided cannot be parsed +type Float64Flag struct { + Name string + Value float64 + Usage string + EnvVar string + Destination *float64 +} + +// String returns the usage +func (f Float64Flag) String() string { + return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)) +} + +// Apply populates the flag given the flag set and environment +func (f Float64Flag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValFloat, err := strconv.ParseFloat(envVal, 10) + if err == nil { + f.Value = float64(envValFloat) + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.Float64Var(f.Destination, name, f.Value, f.Usage) + return + } + set.Float64(name, f.Value, f.Usage) + }) +} + +func (f Float64Flag) getName() string { + return f.Name +} + +func prefixFor(name string) (prefix string) { + if len(name) == 1 { + prefix = "-" + } else { + prefix = "--" + } + + return +} + +func prefixedNames(fullName string) (prefixed string) { + parts := strings.Split(fullName, ",") + for i, name := range parts { + name = strings.Trim(name, " ") + prefixed += prefixFor(name) + name + if i < len(parts)-1 { + prefixed += ", " + } + } + return +} + +func withEnvHint(envVar, str string) string { + envText := "" + if envVar != "" { + envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $")) + } + return str + envText +} diff --git a/vendor/github.com/codegangsta/cli/help.go b/vendor/github.com/codegangsta/cli/help.go new file mode 100644 index 0000000000..a246f63ac4 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/help.go @@ -0,0 +1,246 @@ +package cli + +import ( + "fmt" + "io" + "strings" + "text/tabwriter" + "text/template" +) + +// The text template for the Default help topic. +// cli.go uses text/template to render templates. You can +// render custom help text by setting this variable. +var AppHelpTemplate = `NAME: + {{.Name}} - {{.Usage}} + +USAGE: + {{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} + {{if .Version}} +VERSION: + {{.Version}} + {{end}}{{if len .Authors}} +AUTHOR(S): + {{range .Authors}}{{ . }}{{end}} + {{end}}{{if .Commands}} +COMMANDS: + {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} + {{end}}{{end}}{{if .Flags}} +GLOBAL OPTIONS: + {{range .Flags}}{{.}} + {{end}}{{end}}{{if .Copyright }} +COPYRIGHT: + {{.Copyright}} + {{end}} +` + +// The text template for the command help topic. +// cli.go uses text/template to render templates. You can +// render custom help text by setting this variable. +var CommandHelpTemplate = `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Description}} + +DESCRIPTION: + {{.Description}}{{end}}{{if .Flags}} + +OPTIONS: + {{range .Flags}}{{.}} + {{end}}{{ end }} +` + +// The text template for the subcommand help topic. +// cli.go uses text/template to render templates. You can +// render custom help text by setting this variable. +var SubcommandHelpTemplate = `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} + +COMMANDS: + {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} + {{end}}{{if .Flags}} +OPTIONS: + {{range .Flags}}{{.}} + {{end}}{{end}} +` + +var helpCommand = Command{ + Name: "help", + Aliases: []string{"h"}, + Usage: "Shows a list of commands or help for one command", + ArgsUsage: "[command]", + Action: func(c *Context) { + args := c.Args() + if args.Present() { + ShowCommandHelp(c, args.First()) + } else { + ShowAppHelp(c) + } + }, +} + +var helpSubcommand = Command{ + Name: "help", + Aliases: []string{"h"}, + Usage: "Shows a list of commands or help for one command", + ArgsUsage: "[command]", + Action: func(c *Context) { + args := c.Args() + if args.Present() { + ShowCommandHelp(c, args.First()) + } else { + ShowSubcommandHelp(c) + } + }, +} + +// Prints help for the App or Command +type helpPrinter func(w io.Writer, templ string, data interface{}) + +var HelpPrinter helpPrinter = printHelp + +// Prints version for the App +var VersionPrinter = printVersion + +func ShowAppHelp(c *Context) { + HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) +} + +// Prints the list of subcommands as the default app completion method +func DefaultAppComplete(c *Context) { + for _, command := range c.App.Commands { + for _, name := range command.Names() { + fmt.Fprintln(c.App.Writer, name) + } + } +} + +// Prints help for the given command +func ShowCommandHelp(ctx *Context, command string) { + // show the subcommand help for a command with subcommands + if command == "" { + HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App) + return + } + + for _, c := range ctx.App.Commands { + if c.HasName(command) { + HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c) + return + } + } + + if ctx.App.CommandNotFound != nil { + ctx.App.CommandNotFound(ctx, command) + } else { + fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command) + } +} + +// Prints help for the given subcommand +func ShowSubcommandHelp(c *Context) { + ShowCommandHelp(c, c.Command.Name) +} + +// Prints the version number of the App +func ShowVersion(c *Context) { + VersionPrinter(c) +} + +func printVersion(c *Context) { + fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) +} + +// Prints the lists of commands within a given context +func ShowCompletions(c *Context) { + a := c.App + if a != nil && a.BashComplete != nil { + a.BashComplete(c) + } +} + +// Prints the custom completions for a given command +func ShowCommandCompletions(ctx *Context, command string) { + c := ctx.App.Command(command) + if c != nil && c.BashComplete != nil { + c.BashComplete(ctx) + } +} + +func printHelp(out io.Writer, templ string, data interface{}) { + funcMap := template.FuncMap{ + "join": strings.Join, + } + + w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0) + t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) + err := t.Execute(w, data) + if err != nil { + panic(err) + } + w.Flush() +} + +func checkVersion(c *Context) bool { + found := false + if VersionFlag.Name != "" { + eachName(VersionFlag.Name, func(name string) { + if c.GlobalBool(name) || c.Bool(name) { + found = true + } + }) + } + return found +} + +func checkHelp(c *Context) bool { + found := false + if HelpFlag.Name != "" { + eachName(HelpFlag.Name, func(name string) { + if c.GlobalBool(name) || c.Bool(name) { + found = true + } + }) + } + return found +} + +func checkCommandHelp(c *Context, name string) bool { + if c.Bool("h") || c.Bool("help") { + ShowCommandHelp(c, name) + return true + } + + return false +} + +func checkSubcommandHelp(c *Context) bool { + if c.GlobalBool("h") || c.GlobalBool("help") { + ShowSubcommandHelp(c) + return true + } + + return false +} + +func checkCompletions(c *Context) bool { + if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion { + ShowCompletions(c) + return true + } + + return false +} + +func checkCommandCompletions(c *Context, name string) bool { + if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion { + ShowCommandCompletions(c, name) + return true + } + + return false +} diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE new file mode 100644 index 0000000000..2a7cfd2bf6 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2012-2013 Dave Collins + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go new file mode 100644 index 0000000000..565bf5899f --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go @@ -0,0 +1,151 @@ +// Copyright (c) 2015 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is not running on Google App Engine and "-tags disableunsafe" +// is not added to the go build command line. +// +build !appengine,!disableunsafe + +package spew + +import ( + "reflect" + "unsafe" +) + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = false + + // ptrSize is the size of a pointer on the current arch. + ptrSize = unsafe.Sizeof((*byte)(nil)) +) + +var ( + // offsetPtr, offsetScalar, and offsetFlag are the offsets for the + // internal reflect.Value fields. These values are valid before golang + // commit ecccf07e7f9d which changed the format. The are also valid + // after commit 82f48826c6c7 which changed the format again to mirror + // the original format. Code in the init function updates these offsets + // as necessary. + offsetPtr = uintptr(ptrSize) + offsetScalar = uintptr(0) + offsetFlag = uintptr(ptrSize * 2) + + // flagKindWidth and flagKindShift indicate various bits that the + // reflect package uses internally to track kind information. + // + // flagRO indicates whether or not the value field of a reflect.Value is + // read-only. + // + // flagIndir indicates whether the value field of a reflect.Value is + // the actual data or a pointer to the data. + // + // These values are valid before golang commit 90a7c3c86944 which + // changed their positions. Code in the init function updates these + // flags as necessary. + flagKindWidth = uintptr(5) + flagKindShift = uintptr(flagKindWidth - 1) + flagRO = uintptr(1 << 0) + flagIndir = uintptr(1 << 1) +) + +func init() { + // Older versions of reflect.Value stored small integers directly in the + // ptr field (which is named val in the older versions). Versions + // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named + // scalar for this purpose which unfortunately came before the flag + // field, so the offset of the flag field is different for those + // versions. + // + // This code constructs a new reflect.Value from a known small integer + // and checks if the size of the reflect.Value struct indicates it has + // the scalar field. When it does, the offsets are updated accordingly. + vv := reflect.ValueOf(0xf00) + if unsafe.Sizeof(vv) == (ptrSize * 4) { + offsetScalar = ptrSize * 2 + offsetFlag = ptrSize * 3 + } + + // Commit 90a7c3c86944 changed the flag positions such that the low + // order bits are the kind. This code extracts the kind from the flags + // field and ensures it's the correct type. When it's not, the flag + // order has been changed to the newer format, so the flags are updated + // accordingly. + upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) + upfv := *(*uintptr)(upf) + flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { + flagKindShift = 0 + flagRO = 1 << 5 + flagIndir = 1 << 6 + + // Commit adf9b30e5594 modified the flags to separate the + // flagRO flag into two bits which specifies whether or not the + // field is embedded. This causes flagIndir to move over a bit + // and means that flagRO is the combination of either of the + // original flagRO bit and the new bit. + // + // This code detects the change by extracting what used to be + // the indirect bit to ensure it's set. When it's not, the flag + // order has been changed to the newer format, so the flags are + // updated accordingly. + if upfv&flagIndir == 0 { + flagRO = 3 << 5 + flagIndir = 1 << 7 + } + } +} + +// unsafeReflectValue converts the passed reflect.Value into a one that bypasses +// the typical safety restrictions preventing access to unaddressable and +// unexported data. It works by digging the raw pointer to the underlying +// value out of the protected value and generating a new unprotected (unsafe) +// reflect.Value to it. +// +// This allows us to check for implementations of the Stringer and error +// interfaces to be used for pretty printing ordinarily unaddressable and +// inaccessible values such as unexported struct fields. +func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { + indirects := 1 + vt := v.Type() + upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) + rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) + if rvf&flagIndir != 0 { + vt = reflect.PtrTo(v.Type()) + indirects++ + } else if offsetScalar != 0 { + // The value is in the scalar field when it's not one of the + // reference types. + switch vt.Kind() { + case reflect.Uintptr: + case reflect.Chan: + case reflect.Func: + case reflect.Map: + case reflect.Ptr: + case reflect.UnsafePointer: + default: + upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + + offsetScalar) + } + } + + pv := reflect.NewAt(vt, upv) + rv = pv + for i := 0; i < indirects; i++ { + rv = rv.Elem() + } + return rv +} diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go new file mode 100644 index 0000000000..457e41235e --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go @@ -0,0 +1,37 @@ +// Copyright (c) 2015 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when either the code is running on Google App Engine or "-tags disableunsafe" +// is added to the go build command line. +// +build appengine disableunsafe + +package spew + +import "reflect" + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = true +) + +// unsafeReflectValue typically converts the passed reflect.Value into a one +// that bypasses the typical safety restrictions preventing access to +// unaddressable and unexported data. However, doing this relies on access to +// the unsafe package. This is a stub version which simply returns the passed +// reflect.Value when the unsafe package is not available. +func unsafeReflectValue(v reflect.Value) reflect.Value { + return v +} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go new file mode 100644 index 0000000000..14f02dc15b --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/common.go @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "reflect" + "sort" + "strconv" +) + +// Some constants in the form of bytes to avoid string overhead. This mirrors +// the technique used in the fmt package. +var ( + panicBytes = []byte("(PANIC=") + plusBytes = []byte("+") + iBytes = []byte("i") + trueBytes = []byte("true") + falseBytes = []byte("false") + interfaceBytes = []byte("(interface {})") + commaNewlineBytes = []byte(",\n") + newlineBytes = []byte("\n") + openBraceBytes = []byte("{") + openBraceNewlineBytes = []byte("{\n") + closeBraceBytes = []byte("}") + asteriskBytes = []byte("*") + colonBytes = []byte(":") + colonSpaceBytes = []byte(": ") + openParenBytes = []byte("(") + closeParenBytes = []byte(")") + spaceBytes = []byte(" ") + pointerChainBytes = []byte("->") + nilAngleBytes = []byte("") + maxNewlineBytes = []byte("\n") + maxShortBytes = []byte("") + circularBytes = []byte("") + circularShortBytes = []byte("") + invalidAngleBytes = []byte("") + openBracketBytes = []byte("[") + closeBracketBytes = []byte("]") + percentBytes = []byte("%") + precisionBytes = []byte(".") + openAngleBytes = []byte("<") + closeAngleBytes = []byte(">") + openMapBytes = []byte("map[") + closeMapBytes = []byte("]") + lenEqualsBytes = []byte("len=") + capEqualsBytes = []byte("cap=") +) + +// hexDigits is used to map a decimal value to a hex digit. +var hexDigits = "0123456789abcdef" + +// catchPanic handles any panics that might occur during the handleMethods +// calls. +func catchPanic(w io.Writer, v reflect.Value) { + if err := recover(); err != nil { + w.Write(panicBytes) + fmt.Fprintf(w, "%v", err) + w.Write(closeParenBytes) + } +} + +// handleMethods attempts to call the Error and String methods on the underlying +// type the passed reflect.Value represents and outputes the result to Writer w. +// +// It handles panics in any called methods by catching and displaying the error +// as the formatted value. +func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { + // We need an interface to check if the type implements the error or + // Stringer interface. However, the reflect package won't give us an + // interface on certain things like unexported struct fields in order + // to enforce visibility rules. We use unsafe, when it's available, + // to bypass these restrictions since this package does not mutate the + // values. + if !v.CanInterface() { + if UnsafeDisabled { + return false + } + + v = unsafeReflectValue(v) + } + + // Choose whether or not to do error and Stringer interface lookups against + // the base type or a pointer to the base type depending on settings. + // Technically calling one of these methods with a pointer receiver can + // mutate the value, however, types which choose to satisify an error or + // Stringer interface with a pointer receiver should not be mutating their + // state inside these interface methods. + if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { + v = unsafeReflectValue(v) + } + if v.CanAddr() { + v = v.Addr() + } + + // Is it an error or Stringer? + switch iface := v.Interface().(type) { + case error: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.Error())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + + w.Write([]byte(iface.Error())) + return true + + case fmt.Stringer: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.String())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + w.Write([]byte(iface.String())) + return true + } + return false +} + +// printBool outputs a boolean value as true or false to Writer w. +func printBool(w io.Writer, val bool) { + if val { + w.Write(trueBytes) + } else { + w.Write(falseBytes) + } +} + +// printInt outputs a signed integer value to Writer w. +func printInt(w io.Writer, val int64, base int) { + w.Write([]byte(strconv.FormatInt(val, base))) +} + +// printUint outputs an unsigned integer value to Writer w. +func printUint(w io.Writer, val uint64, base int) { + w.Write([]byte(strconv.FormatUint(val, base))) +} + +// printFloat outputs a floating point value using the specified precision, +// which is expected to be 32 or 64bit, to Writer w. +func printFloat(w io.Writer, val float64, precision int) { + w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) +} + +// printComplex outputs a complex value using the specified float precision +// for the real and imaginary parts to Writer w. +func printComplex(w io.Writer, c complex128, floatPrecision int) { + r := real(c) + w.Write(openParenBytes) + w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) + i := imag(c) + if i >= 0 { + w.Write(plusBytes) + } + w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) + w.Write(iBytes) + w.Write(closeParenBytes) +} + +// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x' +// prefix to Writer w. +func printHexPtr(w io.Writer, p uintptr) { + // Null pointer. + num := uint64(p) + if num == 0 { + w.Write(nilAngleBytes) + return + } + + // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix + buf := make([]byte, 18) + + // It's simpler to construct the hex string right to left. + base := uint64(16) + i := len(buf) - 1 + for num >= base { + buf[i] = hexDigits[num%base] + num /= base + i-- + } + buf[i] = hexDigits[num] + + // Add '0x' prefix. + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + + // Strip unused leading bytes. + buf = buf[i:] + w.Write(buf) +} + +// valuesSorter implements sort.Interface to allow a slice of reflect.Value +// elements to be sorted. +type valuesSorter struct { + values []reflect.Value + strings []string // either nil or same len and values + cs *ConfigState +} + +// newValuesSorter initializes a valuesSorter instance, which holds a set of +// surrogate keys on which the data should be sorted. It uses flags in +// ConfigState to decide if and how to populate those surrogate keys. +func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { + vs := &valuesSorter{values: values, cs: cs} + if canSortSimply(vs.values[0].Kind()) { + return vs + } + if !cs.DisableMethods { + vs.strings = make([]string, len(values)) + for i := range vs.values { + b := bytes.Buffer{} + if !handleMethods(cs, &b, vs.values[i]) { + vs.strings = nil + break + } + vs.strings[i] = b.String() + } + } + if vs.strings == nil && cs.SpewKeys { + vs.strings = make([]string, len(values)) + for i := range vs.values { + vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) + } + } + return vs +} + +// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted +// directly, or whether it should be considered for sorting by surrogate keys +// (if the ConfigState allows it). +func canSortSimply(kind reflect.Kind) bool { + // This switch parallels valueSortLess, except for the default case. + switch kind { + case reflect.Bool: + return true + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return true + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.String: + return true + case reflect.Uintptr: + return true + case reflect.Array: + return true + } + return false +} + +// Len returns the number of values in the slice. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Len() int { + return len(s.values) +} + +// Swap swaps the values at the passed indices. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Swap(i, j int) { + s.values[i], s.values[j] = s.values[j], s.values[i] + if s.strings != nil { + s.strings[i], s.strings[j] = s.strings[j], s.strings[i] + } +} + +// valueSortLess returns whether the first value should sort before the second +// value. It is used by valueSorter.Less as part of the sort.Interface +// implementation. +func valueSortLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Bool: + return !a.Bool() && b.Bool() + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return a.Int() < b.Int() + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return a.Uint() < b.Uint() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.String: + return a.String() < b.String() + case reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Array: + // Compare the contents of both arrays. + l := a.Len() + for i := 0; i < l; i++ { + av := a.Index(i) + bv := b.Index(i) + if av.Interface() == bv.Interface() { + continue + } + return valueSortLess(av, bv) + } + } + return a.String() < b.String() +} + +// Less returns whether the value at index i should sort before the +// value at index j. It is part of the sort.Interface implementation. +func (s *valuesSorter) Less(i, j int) bool { + if s.strings == nil { + return valueSortLess(s.values[i], s.values[j]) + } + return s.strings[i] < s.strings[j] +} + +// sortValues is a sort function that handles both native types and any type that +// can be converted to error or Stringer. Other inputs are sorted according to +// their Value.String() value to ensure display stability. +func sortValues(values []reflect.Value, cs *ConfigState) { + if len(values) == 0 { + return + } + sort.Sort(newValuesSorter(values, cs)) +} diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go new file mode 100644 index 0000000000..ee1ab07b3f --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/config.go @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "os" +) + +// ConfigState houses the configuration options used by spew to format and +// display values. There is a global instance, Config, that is used to control +// all top-level Formatter and Dump functionality. Each ConfigState instance +// provides methods equivalent to the top-level functions. +// +// The zero value for ConfigState provides no indentation. You would typically +// want to set it to a space or a tab. +// +// Alternatively, you can use NewDefaultConfig to get a ConfigState instance +// with default settings. See the documentation of NewDefaultConfig for default +// values. +type ConfigState struct { + // Indent specifies the string to use for each indentation level. The + // global config instance that all top-level functions use set this to a + // single space by default. If you would like more indentation, you might + // set this to a tab with "\t" or perhaps two spaces with " ". + Indent string + + // MaxDepth controls the maximum number of levels to descend into nested + // data structures. The default, 0, means there is no limit. + // + // NOTE: Circular data structures are properly detected, so it is not + // necessary to set this value unless you specifically want to limit deeply + // nested data structures. + MaxDepth int + + // DisableMethods specifies whether or not error and Stringer interfaces are + // invoked for types that implement them. + DisableMethods bool + + // DisablePointerMethods specifies whether or not to check for and invoke + // error and Stringer interfaces on types which only accept a pointer + // receiver when the current type is not a pointer. + // + // NOTE: This might be an unsafe action since calling one of these methods + // with a pointer receiver could technically mutate the value, however, + // in practice, types which choose to satisify an error or Stringer + // interface with a pointer receiver should not be mutating their state + // inside these interface methods. As a result, this option relies on + // access to the unsafe package, so it will not have any effect when + // running in environments without access to the unsafe package such as + // Google App Engine or with the "disableunsafe" build tag specified. + DisablePointerMethods bool + + // ContinueOnMethod specifies whether or not recursion should continue once + // a custom error or Stringer interface is invoked. The default, false, + // means it will print the results of invoking the custom error or Stringer + // interface and return immediately instead of continuing to recurse into + // the internals of the data type. + // + // NOTE: This flag does not have any effect if method invocation is disabled + // via the DisableMethods or DisablePointerMethods options. + ContinueOnMethod bool + + // SortKeys specifies map keys should be sorted before being printed. Use + // this to have a more deterministic, diffable output. Note that only + // native types (bool, int, uint, floats, uintptr and string) and types + // that support the error or Stringer interfaces (if methods are + // enabled) are supported, with other types sorted according to the + // reflect.Value.String() output which guarantees display stability. + SortKeys bool + + // SpewKeys specifies that, as a last resort attempt, map keys should + // be spewed to strings and sorted by those strings. This is only + // considered if SortKeys is true. + SpewKeys bool +} + +// Config is the active configuration of the top-level functions. +// The configuration can be changed by modifying the contents of spew.Config. +var Config = ConfigState{Indent: " "} + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the formatted string as a value that satisfies error. See NewFormatter +// for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, c.convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, c.convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, c.convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a Formatter interface returned by c.NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, c.convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Print(a ...interface{}) (n int, err error) { + return fmt.Print(c.convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, c.convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Println(a ...interface{}) (n int, err error) { + return fmt.Println(c.convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprint(a ...interface{}) string { + return fmt.Sprint(c.convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, c.convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a Formatter interface returned by c.NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintln(a ...interface{}) string { + return fmt.Sprintln(c.convertArgs(a)...) +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +c.Printf, c.Println, or c.Printf. +*/ +func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(c, v) +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { + fdump(c, w, a...) +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + * Pointers are dereferenced and followed + * Circular data structures are detected and handled properly + * Custom Stringer/error interfaces are optionally invoked, including + on unexported types + * Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + * Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by modifying the public members +of c. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func (c *ConfigState) Dump(a ...interface{}) { + fdump(c, os.Stdout, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func (c *ConfigState) Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(c, &buf, a...) + return buf.String() +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a spew Formatter interface using +// the ConfigState associated with s. +func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = newFormatter(c, arg) + } + return formatters +} + +// NewDefaultConfig returns a ConfigState with the following default settings. +// +// Indent: " " +// MaxDepth: 0 +// DisableMethods: false +// DisablePointerMethods: false +// ContinueOnMethod: false +// SortKeys: false +func NewDefaultConfig() *ConfigState { + return &ConfigState{Indent: " "} +} diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go new file mode 100644 index 0000000000..5be0c40609 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/doc.go @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +Package spew implements a deep pretty printer for Go data structures to aid in +debugging. + +A quick overview of the additional features spew provides over the built-in +printing facilities for Go data types are as follows: + + * Pointers are dereferenced and followed + * Circular data structures are detected and handled properly + * Custom Stringer/error interfaces are optionally invoked, including + on unexported types + * Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + * Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output (only when using + Dump style) + +There are two different approaches spew allows for dumping Go data structures: + + * Dump style which prints with newlines, customizable indentation, + and additional debug information such as types and all pointer addresses + used to indirect to the final value + * A custom Formatter interface that integrates cleanly with the standard fmt + package and replaces %v, %+v, %#v, and %#+v to provide inline printing + similar to the default %v while providing the additional functionality + outlined above and passing unsupported format verbs such as %x and %q + along to fmt + +Quick Start + +This section demonstrates how to quickly get started with spew. See the +sections below for further details on formatting and configuration options. + +To dump a variable with full newlines, indentation, type, and pointer +information use Dump, Fdump, or Sdump: + spew.Dump(myVar1, myVar2, ...) + spew.Fdump(someWriter, myVar1, myVar2, ...) + str := spew.Sdump(myVar1, myVar2, ...) + +Alternatively, if you would prefer to use format strings with a compacted inline +printing style, use the convenience wrappers Printf, Fprintf, etc with +%v (most compact), %+v (adds pointer addresses), %#v (adds types), or +%#+v (adds types and pointer addresses): + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +Configuration Options + +Configuration of spew is handled by fields in the ConfigState type. For +convenience, all of the top-level functions use a global state available +via the spew.Config global. + +It is also possible to create a ConfigState instance that provides methods +equivalent to the top-level functions. This allows concurrent configuration +options. See the ConfigState documentation for more details. + +The following configuration options are available: + * Indent + String to use for each indentation level for Dump functions. + It is a single space by default. A popular alternative is "\t". + + * MaxDepth + Maximum number of levels to descend into nested data structures. + There is no limit by default. + + * DisableMethods + Disables invocation of error and Stringer interface methods. + Method invocation is enabled by default. + + * DisablePointerMethods + Disables invocation of error and Stringer interface methods on types + which only accept pointer receivers from non-pointer variables. + Pointer method invocation is enabled by default. + + * ContinueOnMethod + Enables recursion into types after invoking error and Stringer interface + methods. Recursion after method invocation is disabled by default. + + * SortKeys + Specifies map keys should be sorted before being printed. Use + this to have a more deterministic, diffable output. Note that + only native types (bool, int, uint, floats, uintptr and string) + and types which implement error or Stringer interfaces are + supported with other types sorted according to the + reflect.Value.String() output which guarantees display + stability. Natural map order is used by default. + + * SpewKeys + Specifies that, as a last resort attempt, map keys should be + spewed to strings and sorted by those strings. This is only + considered if SortKeys is true. + +Dump Usage + +Simply call spew.Dump with a list of variables you want to dump: + + spew.Dump(myVar1, myVar2, ...) + +You may also call spew.Fdump if you would prefer to output to an arbitrary +io.Writer. For example, to dump to standard error: + + spew.Fdump(os.Stderr, myVar1, myVar2, ...) + +A third option is to call spew.Sdump to get the formatted output as a string: + + str := spew.Sdump(myVar1, myVar2, ...) + +Sample Dump Output + +See the Dump example for details on the setup of the types and variables being +shown here. + + (main.Foo) { + unexportedField: (*main.Bar)(0xf84002e210)({ + flag: (main.Flag) flagTwo, + data: (uintptr) + }), + ExportedField: (map[interface {}]interface {}) (len=1) { + (string) (len=3) "one": (bool) true + } + } + +Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C +command as shown. + ([]uint8) (len=32 cap=32) { + 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | + 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| + 00000020 31 32 |12| + } + +Custom Formatter + +Spew provides a custom formatter that implements the fmt.Formatter interface +so that it integrates cleanly with standard fmt package printing functions. The +formatter is useful for inline printing of smaller data types similar to the +standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Custom Formatter Usage + +The simplest way to make use of the spew custom formatter is to call one of the +convenience functions such as spew.Printf, spew.Println, or spew.Printf. The +functions have syntax you are most likely already familiar with: + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Println(myVar, myVar2) + spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +See the Index for the full list convenience functions. + +Sample Formatter Output + +Double pointer to a uint8: + %v: <**>5 + %+v: <**>(0xf8400420d0->0xf8400420c8)5 + %#v: (**uint8)5 + %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 + +Pointer to circular struct with a uint8 field and a pointer to itself: + %v: <*>{1 <*>} + %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} + %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} + %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} + +See the Printf example for details on the setup of variables being shown +here. + +Errors + +Since it is possible for custom Stringer/error interfaces to panic, spew +detects them and handles them internally by printing the panic information +inline with the output. Since spew is intended to provide deep pretty printing +capabilities on structures, it intentionally does not return any errors. +*/ +package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go new file mode 100644 index 0000000000..a0ff95e27e --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/dump.go @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "encoding/hex" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + // uint8Type is a reflect.Type representing a uint8. It is used to + // convert cgo types to uint8 slices for hexdumping. + uint8Type = reflect.TypeOf(uint8(0)) + + // cCharRE is a regular expression that matches a cgo char. + // It is used to detect character arrays to hexdump them. + cCharRE = regexp.MustCompile("^.*\\._Ctype_char$") + + // cUnsignedCharRE is a regular expression that matches a cgo unsigned + // char. It is used to detect unsigned character arrays to hexdump + // them. + cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$") + + // cUint8tCharRE is a regular expression that matches a cgo uint8_t. + // It is used to detect uint8_t arrays to hexdump them. + cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$") +) + +// dumpState contains information about the state of a dump operation. +type dumpState struct { + w io.Writer + depth int + pointers map[uintptr]int + ignoreNextType bool + ignoreNextIndent bool + cs *ConfigState +} + +// indent performs indentation according to the depth level and cs.Indent +// option. +func (d *dumpState) indent() { + if d.ignoreNextIndent { + d.ignoreNextIndent = false + return + } + d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) +} + +// unpackValue returns values inside of non-nil interfaces when possible. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface && !v.IsNil() { + v = v.Elem() + } + return v +} + +// dumpPtr handles formatting of pointers by indirecting them as necessary. +func (d *dumpState) dumpPtr(v reflect.Value) { + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range d.pointers { + if depth >= d.depth { + delete(d.pointers, k) + } + } + + // Keep list of all dereferenced pointers to show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by dereferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := d.pointers[addr]; ok && pd < d.depth { + cycleFound = true + indirects-- + break + } + d.pointers[addr] = d.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type information. + d.w.Write(openParenBytes) + d.w.Write(bytes.Repeat(asteriskBytes, indirects)) + d.w.Write([]byte(ve.Type().String())) + d.w.Write(closeParenBytes) + + // Display pointer information. + if len(pointerChain) > 0 { + d.w.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + d.w.Write(pointerChainBytes) + } + printHexPtr(d.w, addr) + } + d.w.Write(closeParenBytes) + } + + // Display dereferenced value. + d.w.Write(openParenBytes) + switch { + case nilFound == true: + d.w.Write(nilAngleBytes) + + case cycleFound == true: + d.w.Write(circularBytes) + + default: + d.ignoreNextType = true + d.dump(ve) + } + d.w.Write(closeParenBytes) +} + +// dumpSlice handles formatting of arrays and slices. Byte (uint8 under +// reflection) arrays and slices are dumped in hexdump -C fashion. +func (d *dumpState) dumpSlice(v reflect.Value) { + // Determine whether this type should be hex dumped or not. Also, + // for types which should be hexdumped, try to use the underlying data + // first, then fall back to trying to convert them to a uint8 slice. + var buf []uint8 + doConvert := false + doHexDump := false + numEntries := v.Len() + if numEntries > 0 { + vt := v.Index(0).Type() + vts := vt.String() + switch { + // C types that need to be converted. + case cCharRE.MatchString(vts): + fallthrough + case cUnsignedCharRE.MatchString(vts): + fallthrough + case cUint8tCharRE.MatchString(vts): + doConvert = true + + // Try to use existing uint8 slices and fall back to converting + // and copying if that fails. + case vt.Kind() == reflect.Uint8: + // We need an addressable interface to convert the type + // to a byte slice. However, the reflect package won't + // give us an interface on certain things like + // unexported struct fields in order to enforce + // visibility rules. We use unsafe, when available, to + // bypass these restrictions since this package does not + // mutate the values. + vs := v + if !vs.CanInterface() || !vs.CanAddr() { + vs = unsafeReflectValue(vs) + } + if !UnsafeDisabled { + vs = vs.Slice(0, numEntries) + + // Use the existing uint8 slice if it can be + // type asserted. + iface := vs.Interface() + if slice, ok := iface.([]uint8); ok { + buf = slice + doHexDump = true + break + } + } + + // The underlying data needs to be converted if it can't + // be type asserted to a uint8 slice. + doConvert = true + } + + // Copy and convert the underlying type if needed. + if doConvert && vt.ConvertibleTo(uint8Type) { + // Convert and copy each element into a uint8 byte + // slice. + buf = make([]uint8, numEntries) + for i := 0; i < numEntries; i++ { + vv := v.Index(i) + buf[i] = uint8(vv.Convert(uint8Type).Uint()) + } + doHexDump = true + } + } + + // Hexdump the entire slice as needed. + if doHexDump { + indent := strings.Repeat(d.cs.Indent, d.depth) + str := indent + hex.Dump(buf) + str = strings.Replace(str, "\n", "\n"+indent, -1) + str = strings.TrimRight(str, d.cs.Indent) + d.w.Write([]byte(str)) + return + } + + // Recursively call dump for each item. + for i := 0; i < numEntries; i++ { + d.dump(d.unpackValue(v.Index(i))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } +} + +// dump is the main workhorse for dumping a value. It uses the passed reflect +// value to figure out what kind of object we are dealing with and formats it +// appropriately. It is a recursive function, however circular data structures +// are detected and handled properly. +func (d *dumpState) dump(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + d.w.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + d.indent() + d.dumpPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !d.ignoreNextType { + d.indent() + d.w.Write(openParenBytes) + d.w.Write([]byte(v.Type().String())) + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + d.ignoreNextType = false + + // Display length and capacity if the built-in len and cap functions + // work with the value's kind and the len/cap itself is non-zero. + valueLen, valueCap := 0, 0 + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Chan: + valueLen, valueCap = v.Len(), v.Cap() + case reflect.Map, reflect.String: + valueLen = v.Len() + } + if valueLen != 0 || valueCap != 0 { + d.w.Write(openParenBytes) + if valueLen != 0 { + d.w.Write(lenEqualsBytes) + printInt(d.w, int64(valueLen), 10) + } + if valueCap != 0 { + if valueLen != 0 { + d.w.Write(spaceBytes) + } + d.w.Write(capEqualsBytes) + printInt(d.w, int64(valueCap), 10) + } + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + + // Call Stringer/error interfaces if they exist and the handle methods flag + // is enabled + if !d.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(d.cs, d.w, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(d.w, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(d.w, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(d.w, v.Uint(), 10) + + case reflect.Float32: + printFloat(d.w, v.Float(), 32) + + case reflect.Float64: + printFloat(d.w, v.Float(), 64) + + case reflect.Complex64: + printComplex(d.w, v.Complex(), 32) + + case reflect.Complex128: + printComplex(d.w, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + d.dumpSlice(v) + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.String: + d.w.Write([]byte(strconv.Quote(v.String()))) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + d.w.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + numEntries := v.Len() + keys := v.MapKeys() + if d.cs.SortKeys { + sortValues(keys, d.cs) + } + for i, key := range keys { + d.dump(d.unpackValue(key)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.MapIndex(key))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Struct: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + vt := v.Type() + numFields := v.NumField() + for i := 0; i < numFields; i++ { + d.indent() + vtf := vt.Field(i) + d.w.Write([]byte(vtf.Name)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.Field(i))) + if i < (numFields - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(d.w, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(d.w, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it in case any new + // types are added. + default: + if v.CanInterface() { + fmt.Fprintf(d.w, "%v", v.Interface()) + } else { + fmt.Fprintf(d.w, "%v", v.String()) + } + } +} + +// fdump is a helper function to consolidate the logic from the various public +// methods which take varying writers and config states. +func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { + for _, arg := range a { + if arg == nil { + w.Write(interfaceBytes) + w.Write(spaceBytes) + w.Write(nilAngleBytes) + w.Write(newlineBytes) + continue + } + + d := dumpState{w: w, cs: cs} + d.pointers = make(map[uintptr]int) + d.dump(reflect.ValueOf(arg)) + d.w.Write(newlineBytes) + } +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func Fdump(w io.Writer, a ...interface{}) { + fdump(&Config, w, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(&Config, &buf, a...) + return buf.String() +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + * Pointers are dereferenced and followed + * Circular data structures are detected and handled properly + * Custom Stringer/error interfaces are optionally invoked, including + on unexported types + * Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + * Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by an exported package global, +spew.Config. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func Dump(a ...interface{}) { + fdump(&Config, os.Stdout, a...) +} diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go new file mode 100644 index 0000000000..ecf3b80e24 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/format.go @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + "strings" +) + +// supportedFlags is a list of all the character flags supported by fmt package. +const supportedFlags = "0-+# " + +// formatState implements the fmt.Formatter interface and contains information +// about the state of a formatting operation. The NewFormatter function can +// be used to get a new Formatter which can be used directly as arguments +// in standard fmt package printing calls. +type formatState struct { + value interface{} + fs fmt.State + depth int + pointers map[uintptr]int + ignoreNextType bool + cs *ConfigState +} + +// buildDefaultFormat recreates the original format string without precision +// and width information to pass in to fmt.Sprintf in the case of an +// unrecognized type. Unless new types are added to the language, this +// function won't ever be called. +func (f *formatState) buildDefaultFormat() (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + buf.WriteRune('v') + + format = buf.String() + return format +} + +// constructOrigFormat recreates the original format string including precision +// and width information to pass along to the standard fmt package. This allows +// automatic deferral of all format strings this package doesn't support. +func (f *formatState) constructOrigFormat(verb rune) (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + if width, ok := f.fs.Width(); ok { + buf.WriteString(strconv.Itoa(width)) + } + + if precision, ok := f.fs.Precision(); ok { + buf.Write(precisionBytes) + buf.WriteString(strconv.Itoa(precision)) + } + + buf.WriteRune(verb) + + format = buf.String() + return format +} + +// unpackValue returns values inside of non-nil interfaces when possible and +// ensures that types for values which have been unpacked from an interface +// are displayed when the show types flag is also set. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (f *formatState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface { + f.ignoreNextType = false + if !v.IsNil() { + v = v.Elem() + } + } + return v +} + +// formatPtr handles formatting of pointers by indirecting them as necessary. +func (f *formatState) formatPtr(v reflect.Value) { + // Display nil if top level pointer is nil. + showTypes := f.fs.Flag('#') + if v.IsNil() && (!showTypes || f.ignoreNextType) { + f.fs.Write(nilAngleBytes) + return + } + + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range f.pointers { + if depth >= f.depth { + delete(f.pointers, k) + } + } + + // Keep list of all dereferenced pointers to possibly show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by derferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := f.pointers[addr]; ok && pd < f.depth { + cycleFound = true + indirects-- + break + } + f.pointers[addr] = f.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type or indirection level depending on flags. + if showTypes && !f.ignoreNextType { + f.fs.Write(openParenBytes) + f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) + f.fs.Write([]byte(ve.Type().String())) + f.fs.Write(closeParenBytes) + } else { + if nilFound || cycleFound { + indirects += strings.Count(ve.Type().String(), "*") + } + f.fs.Write(openAngleBytes) + f.fs.Write([]byte(strings.Repeat("*", indirects))) + f.fs.Write(closeAngleBytes) + } + + // Display pointer information depending on flags. + if f.fs.Flag('+') && (len(pointerChain) > 0) { + f.fs.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + f.fs.Write(pointerChainBytes) + } + printHexPtr(f.fs, addr) + } + f.fs.Write(closeParenBytes) + } + + // Display dereferenced value. + switch { + case nilFound == true: + f.fs.Write(nilAngleBytes) + + case cycleFound == true: + f.fs.Write(circularShortBytes) + + default: + f.ignoreNextType = true + f.format(ve) + } +} + +// format is the main workhorse for providing the Formatter interface. It +// uses the passed reflect value to figure out what kind of object we are +// dealing with and formats it appropriately. It is a recursive function, +// however circular data structures are detected and handled properly. +func (f *formatState) format(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + f.fs.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + f.formatPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !f.ignoreNextType && f.fs.Flag('#') { + f.fs.Write(openParenBytes) + f.fs.Write([]byte(v.Type().String())) + f.fs.Write(closeParenBytes) + } + f.ignoreNextType = false + + // Call Stringer/error interfaces if they exist and the handle methods + // flag is enabled. + if !f.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(f.cs, f.fs, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(f.fs, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(f.fs, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(f.fs, v.Uint(), 10) + + case reflect.Float32: + printFloat(f.fs, v.Float(), 32) + + case reflect.Float64: + printFloat(f.fs, v.Float(), 64) + + case reflect.Complex64: + printComplex(f.fs, v.Complex(), 32) + + case reflect.Complex128: + printComplex(f.fs, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + f.fs.Write(openBracketBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + numEntries := v.Len() + for i := 0; i < numEntries; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(v.Index(i))) + } + } + f.depth-- + f.fs.Write(closeBracketBytes) + + case reflect.String: + f.fs.Write([]byte(v.String())) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + f.fs.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + + f.fs.Write(openMapBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + keys := v.MapKeys() + if f.cs.SortKeys { + sortValues(keys, f.cs) + } + for i, key := range keys { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(key)) + f.fs.Write(colonBytes) + f.ignoreNextType = true + f.format(f.unpackValue(v.MapIndex(key))) + } + } + f.depth-- + f.fs.Write(closeMapBytes) + + case reflect.Struct: + numFields := v.NumField() + f.fs.Write(openBraceBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + vt := v.Type() + for i := 0; i < numFields; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + vtf := vt.Field(i) + if f.fs.Flag('+') || f.fs.Flag('#') { + f.fs.Write([]byte(vtf.Name)) + f.fs.Write(colonBytes) + } + f.format(f.unpackValue(v.Field(i))) + } + } + f.depth-- + f.fs.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(f.fs, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(f.fs, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it if any get added. + default: + format := f.buildDefaultFormat() + if v.CanInterface() { + fmt.Fprintf(f.fs, format, v.Interface()) + } else { + fmt.Fprintf(f.fs, format, v.String()) + } + } +} + +// Format satisfies the fmt.Formatter interface. See NewFormatter for usage +// details. +func (f *formatState) Format(fs fmt.State, verb rune) { + f.fs = fs + + // Use standard formatting for verbs that are not v. + if verb != 'v' { + format := f.constructOrigFormat(verb) + fmt.Fprintf(fs, format, f.value) + return + } + + if f.value == nil { + if fs.Flag('#') { + fs.Write(interfaceBytes) + } + fs.Write(nilAngleBytes) + return + } + + f.format(reflect.ValueOf(f.value)) +} + +// newFormatter is a helper function to consolidate the logic from the various +// public methods which take varying config states. +func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { + fs := &formatState{value: v, cs: cs} + fs.pointers = make(map[uintptr]int) + return fs +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +Printf, Println, or Fprintf. +*/ +func NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(&Config, v) +} diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go new file mode 100644 index 0000000000..d8233f542e --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/spew.go @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "fmt" + "io" +) + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the formatted string as a value that satisfies error. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a default Formatter interface returned by NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) +func Print(a ...interface{}) (n int, err error) { + return fmt.Print(convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) +func Println(a ...interface{}) (n int, err error) { + return fmt.Println(convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprint(a ...interface{}) string { + return fmt.Sprint(convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintln(a ...interface{}) string { + return fmt.Sprintln(convertArgs(a)...) +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a default spew Formatter interface. +func convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = NewFormatter(arg) + } + return formatters +} diff --git a/vendor/github.com/dgrijalva/jwt-go/.gitignore b/vendor/github.com/dgrijalva/jwt-go/.gitignore new file mode 100644 index 0000000000..80bed650ec --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bin + + diff --git a/vendor/github.com/dgrijalva/jwt-go/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/.travis.yml new file mode 100644 index 0000000000..bde823d8ab --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - tip diff --git a/vendor/github.com/dgrijalva/jwt-go/LICENSE b/vendor/github.com/dgrijalva/jwt-go/LICENSE new file mode 100644 index 0000000000..df83a9c2f0 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2012 Dave Grijalva + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md new file mode 100644 index 0000000000..7fc1f793cb --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md @@ -0,0 +1,97 @@ +## Migration Guide from v2 -> v3 + +Version 3 adds several new, frequently requested features. To do so, it introduces a few breaking changes. We've worked to keep these as minimal as possible. This guide explains the breaking changes and how you can quickly update your code. + +### `Token.Claims` is now an interface type + +The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`. We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`. + +`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior. It is the default claims type when using `Parse`. The usage is unchanged except you must type cast the claims property. + +The old example for parsing a token looked like this.. + +```go + if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { + fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"]) + } +``` + +is now directly mapped to... + +```go + if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { + claims := token.Claims.(jwt.MapClaims) + fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) + } +``` + +`StandardClaims` is designed to be embedded in your custom type. You can supply a custom claims type with the new `ParseWithClaims` function. Here's an example of using a custom claims type. + +```go + type MyCustomClaims struct { + User string + *StandardClaims + } + + if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil { + claims := token.Claims.(*MyCustomClaims) + fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt) + } +``` + +### `ParseFromRequest` has been moved + +To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`. The method signatues have also been augmented to receive a new argument: `Extractor`. + +`Extractors` do the work of picking the token string out of a request. The interface is simple and composable. + +This simple parsing example: + +```go + if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil { + fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"]) + } +``` + +is directly mapped to: + +```go + if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil { + claims := token.Claims.(jwt.MapClaims) + fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) + } +``` + +There are several concrete `Extractor` types provided for your convenience: + +* `HeaderExtractor` will search a list of headers until one contains content. +* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content. +* `MultiExtractor` will try a list of `Extractors` in order until one returns content. +* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token. +* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument +* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed. A simple example is stripping the `Bearer ` text from a header + + +### RSA signing methods no longer accept `[]byte` keys + +Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse. + +To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`. These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types. + +```go + func keyLookupFunc(*Token) (interface{}, error) { + // Don't forget to validate the alg is what you expect: + if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + + // Look up key + key, err := lookupPublicKey(token.Header["kid"]) + if err != nil { + return nil, err + } + + // Unpack key from PEM encoded PKCS8 + return jwt.ParseRSAPublicKeyFromPEM(key) + } +``` diff --git a/vendor/github.com/dgrijalva/jwt-go/README.md b/vendor/github.com/dgrijalva/jwt-go/README.md new file mode 100644 index 0000000000..f48365fafb --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/README.md @@ -0,0 +1,85 @@ +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) + +[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go) + +**BREAKING CHANGES:*** Version 3.0.0 is here. It includes _a lot_ of changes including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code. + +**NOTICE:** A vulnerability in JWT was [recently published](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). As this library doesn't force users to validate the `alg` is what they expected, it's possible your usage is effected. There will be an update soon to remedy this, and it will likey require backwards-incompatible changes to the API. In the short term, please make sure your implementation verifies the `alg` is what you expect. + + +## What the heck is a JWT? + +JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens. + +In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded. The last part is the signature, encoded the same way. + +The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used. + +The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own. + +## What's in the box? + +This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own. + +## Examples + +See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage: + +* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac) +* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac) +* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples) + +## Extensions + +This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`. + +Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go + +## Compliance + +This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences: + +* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. + +## Project Status & Versioning + +This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason). + +This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `master`. Periodically, versions will be tagged from `master`. You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases). + +While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v2`. It will do the right thing WRT semantic versioning. + +## Usage Tips + +### Signing vs Encryption + +A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data: + +* The author of the token was in the possession of the signing secret +* The data has not been modified since it was signed + +It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library. + +### Choosing a Signing Method + +There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric. + +Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation. + +Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification. + +### JWT and OAuth + +It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication. + +Without going too far down the rabbit hole, here's a description of the interaction of these technologies: + +* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth. +* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token. +* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL. + +## More + +Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go). + +The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in to documentation. diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md new file mode 100644 index 0000000000..b605b45093 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md @@ -0,0 +1,105 @@ +## `jwt-go` Version History + +#### 3.0.0 + +* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code + * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. + * `ParseFromRequest` has been moved to `request` subpackage and usage has changed + * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. +* Other Additions and Changes + * Added `Claims` interface type to allow users to decode the claims into a custom type + * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. + * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage + * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` + * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. + * Added several new, more specific, validation errors to error type bitmask + * Moved examples from README to executable example files + * Signing method registry is now thread safe + * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) + +#### 2.7.0 + +This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. + +* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying +* Error text for expired tokens includes how long it's been expired +* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` +* Documentation updates + +#### 2.6.0 + +* Exposed inner error within ValidationError +* Fixed validation errors when using UseJSONNumber flag +* Added several unit tests + +#### 2.5.0 + +* Added support for signing method none. You shouldn't use this. The API tries to make this clear. +* Updated/fixed some documentation +* Added more helpful error message when trying to parse tokens that begin with `BEARER ` + +#### 2.4.0 + +* Added new type, Parser, to allow for configuration of various parsing parameters + * You can now specify a list of valid signing methods. Anything outside this set will be rejected. + * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON +* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) +* Fixed some bugs with ECDSA parsing + +#### 2.3.0 + +* Added support for ECDSA signing methods +* Added support for RSA PSS signing methods (requires go v1.4) + +#### 2.2.0 + +* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. + +#### 2.1.0 + +Backwards compatible API change that was missed in 2.0.0. + +* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` + +#### 2.0.0 + +There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. + +The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. + +It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. + +* **Compatibility Breaking Changes** + * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` + * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` + * `KeyFunc` now returns `interface{}` instead of `[]byte` + * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key + * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key +* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodHS256` + * Added public package global `SigningMethodHS384` + * Added public package global `SigningMethodHS512` +* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodRS256` + * Added public package global `SigningMethodRS384` + * Added public package global `SigningMethodRS512` +* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. +* Refactored the RSA implementation to be easier to read +* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` + +#### 1.0.2 + +* Fixed bug in parsing public keys from certificates +* Added more tests around the parsing of keys for RS256 +* Code refactoring in RS256 implementation. No functional changes + +#### 1.0.1 + +* Fixed panic if RS256 signing method was passed an invalid key + +#### 1.0.0 + +* First versioned release +* API stabilized +* Supports creating, signing, parsing, and validating JWT tokens +* Supports RS256 and HS256 signing methods \ No newline at end of file diff --git a/vendor/github.com/dgrijalva/jwt-go/claims.go b/vendor/github.com/dgrijalva/jwt-go/claims.go new file mode 100644 index 0000000000..f0228f02e0 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/claims.go @@ -0,0 +1,134 @@ +package jwt + +import ( + "crypto/subtle" + "fmt" + "time" +) + +// For a type to be a Claims object, it must just have a Valid method that determines +// if the token is invalid for any supported reason +type Claims interface { + Valid() error +} + +// Structured version of Claims Section, as referenced at +// https://tools.ietf.org/html/rfc7519#section-4.1 +// See examples for how to use this with your own claim types +type StandardClaims struct { + Audience string `json:"aud,omitempty"` + ExpiresAt int64 `json:"exp,omitempty"` + Id string `json:"jti,omitempty"` + IssuedAt int64 `json:"iat,omitempty"` + Issuer string `json:"iss,omitempty"` + NotBefore int64 `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` +} + +// Validates time based claims "exp, iat, nbf". +// There is no accounting for clock skew. +// As well, if any of the above claims are not in the token, it will still +// be considered a valid claim. +func (c StandardClaims) Valid() error { + vErr := new(ValidationError) + now := TimeFunc().Unix() + + // The claims below are optional, by default, so if they are set to the + // default value in Go, let's not fail the verification for them. + if c.VerifyExpiresAt(now, false) == false { + delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0)) + vErr.Inner = fmt.Errorf("token is expired by %v", delta) + vErr.Errors |= ValidationErrorExpired + } + + if c.VerifyIssuedAt(now, false) == false { + vErr.Inner = fmt.Errorf("Token used before issued") + vErr.Errors |= ValidationErrorIssuedAt + } + + if c.VerifyNotBefore(now, false) == false { + vErr.Inner = fmt.Errorf("token is not valid yet") + vErr.Errors |= ValidationErrorNotValidYet + } + + if vErr.valid() { + return nil + } + + return vErr +} + +// Compares the aud claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool { + return verifyAud(c.Audience, cmp, req) +} + +// Compares the exp claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool { + return verifyExp(c.ExpiresAt, cmp, req) +} + +// Compares the iat claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool { + return verifyIat(c.IssuedAt, cmp, req) +} + +// Compares the iss claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool { + return verifyIss(c.Issuer, cmp, req) +} + +// Compares the nbf claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { + return verifyNbf(c.NotBefore, cmp, req) +} + +// ----- helpers + +func verifyAud(aud string, cmp string, required bool) bool { + if aud == "" { + return !required + } + if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 { + return true + } else { + return false + } +} + +func verifyExp(exp int64, now int64, required bool) bool { + if exp == 0 { + return !required + } + return now <= exp +} + +func verifyIat(iat int64, now int64, required bool) bool { + if iat == 0 { + return !required + } + return now >= iat +} + +func verifyIss(iss string, cmp string, required bool) bool { + if iss == "" { + return !required + } + if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 { + return true + } else { + return false + } +} + +func verifyNbf(nbf int64, now int64, required bool) bool { + if nbf == 0 { + return !required + } + return now >= nbf +} diff --git a/vendor/github.com/dgrijalva/jwt-go/doc.go b/vendor/github.com/dgrijalva/jwt-go/doc.go new file mode 100644 index 0000000000..a86dc1a3b3 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/doc.go @@ -0,0 +1,4 @@ +// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html +// +// See README.md for more info. +package jwt diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go new file mode 100644 index 0000000000..2f59a22236 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go @@ -0,0 +1,147 @@ +package jwt + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "errors" + "math/big" +) + +var ( + // Sadly this is missing from crypto/ecdsa compared to crypto/rsa + ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") +) + +// Implements the ECDSA family of signing methods signing methods +type SigningMethodECDSA struct { + Name string + Hash crypto.Hash + KeySize int + CurveBits int +} + +// Specific instances for EC256 and company +var ( + SigningMethodES256 *SigningMethodECDSA + SigningMethodES384 *SigningMethodECDSA + SigningMethodES512 *SigningMethodECDSA +) + +func init() { + // ES256 + SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} + RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { + return SigningMethodES256 + }) + + // ES384 + SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} + RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { + return SigningMethodES384 + }) + + // ES512 + SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} + RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { + return SigningMethodES512 + }) +} + +func (m *SigningMethodECDSA) Alg() string { + return m.Name +} + +// Implements the Verify method from SigningMethod +// For this verify method, key must be an ecdsa.PublicKey struct +func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + // Get the key + var ecdsaKey *ecdsa.PublicKey + switch k := key.(type) { + case *ecdsa.PublicKey: + ecdsaKey = k + default: + return ErrInvalidKeyType + } + + if len(sig) != 2*m.KeySize { + return ErrECDSAVerification + } + + r := big.NewInt(0).SetBytes(sig[:m.KeySize]) + s := big.NewInt(0).SetBytes(sig[m.KeySize:]) + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true { + return nil + } else { + return ErrECDSAVerification + } +} + +// Implements the Sign method from SigningMethod +// For this signing method, key must be an ecdsa.PrivateKey struct +func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) { + // Get the key + var ecdsaKey *ecdsa.PrivateKey + switch k := key.(type) { + case *ecdsa.PrivateKey: + ecdsaKey = k + default: + return "", ErrInvalidKeyType + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return r, s + if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { + curveBits := ecdsaKey.Curve.Params().BitSize + + if m.CurveBits != curveBits { + return "", ErrInvalidKey + } + + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes += 1 + } + + // We serialize the outpus (r and s) into big-endian byte arrays and pad + // them with zeros on the left to make sure the sizes work out. Both arrays + // must be keyBytes long, and the output must be 2*keyBytes long. + rBytes := r.Bytes() + rBytesPadded := make([]byte, keyBytes) + copy(rBytesPadded[keyBytes-len(rBytes):], rBytes) + + sBytes := s.Bytes() + sBytesPadded := make([]byte, keyBytes) + copy(sBytesPadded[keyBytes-len(sBytes):], sBytes) + + out := append(rBytesPadded, sBytesPadded...) + + return EncodeSegment(out), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go new file mode 100644 index 0000000000..d19624b726 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go @@ -0,0 +1,67 @@ +package jwt + +import ( + "crypto/ecdsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotECPublicKey = errors.New("Key is not a valid ECDSA public key") + ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key") +) + +// Parse PEM encoded Elliptic Curve Private Key Structure +func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { + return nil, err + } + + var pkey *ecdsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { + return nil, ErrNotECPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 public key +func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *ecdsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { + return nil, ErrNotECPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/errors.go b/vendor/github.com/dgrijalva/jwt-go/errors.go new file mode 100644 index 0000000000..662df19d4e --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/errors.go @@ -0,0 +1,63 @@ +package jwt + +import ( + "errors" +) + +// Error constants +var ( + ErrInvalidKey = errors.New("key is invalid") + ErrInvalidKeyType = errors.New("key is of invalid type") + ErrHashUnavailable = errors.New("the requested hash function is unavailable") +) + +// The errors that might occur when parsing and validating a token +const ( + ValidationErrorMalformed uint32 = 1 << iota // Token is malformed + ValidationErrorUnverifiable // Token could not be verified because of signing problems + ValidationErrorSignatureInvalid // Signature validation failed + + // Standard Claim validation errors + ValidationErrorAudience // AUD validation failed + ValidationErrorExpired // EXP validation failed + ValidationErrorIssuedAt // IAT validation failed + ValidationErrorIssuer // ISS validation failed + ValidationErrorNotValidYet // NBF validation failed + ValidationErrorId // JTI validation failed + ValidationErrorClaimsInvalid // Generic claims validation error +) + +// Helper for constructing a ValidationError with a string error message +func NewValidationError(errorText string, errorFlags uint32) *ValidationError { + return &ValidationError{ + text: errorText, + Errors: errorFlags, + } +} + +// The error from Parse if token is not valid +type ValidationError struct { + Inner error // stores the error returned by external dependencies, i.e.: KeyFunc + Errors uint32 // bitfield. see ValidationError... constants + text string // errors that do not have a valid error just have text +} + +// Validation error is an error type +func (e ValidationError) Error() string { + if e.Inner != nil { + return e.Inner.Error() + } else if e.text != "" { + return e.text + } else { + return "token is invalid" + } + return e.Inner.Error() +} + +// No errors +func (e *ValidationError) valid() bool { + if e.Errors > 0 { + return false + } + return true +} diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/dgrijalva/jwt-go/hmac.go new file mode 100644 index 0000000000..c229919254 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/hmac.go @@ -0,0 +1,94 @@ +package jwt + +import ( + "crypto" + "crypto/hmac" + "errors" +) + +// Implements the HMAC-SHA family of signing methods signing methods +type SigningMethodHMAC struct { + Name string + Hash crypto.Hash +} + +// Specific instances for HS256 and company +var ( + SigningMethodHS256 *SigningMethodHMAC + SigningMethodHS384 *SigningMethodHMAC + SigningMethodHS512 *SigningMethodHMAC + ErrSignatureInvalid = errors.New("signature is invalid") +) + +func init() { + // HS256 + SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { + return SigningMethodHS256 + }) + + // HS384 + SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { + return SigningMethodHS384 + }) + + // HS512 + SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { + return SigningMethodHS512 + }) +} + +func (m *SigningMethodHMAC) Alg() string { + return m.Name +} + +// Verify the signature of HSXXX tokens. Returns nil if the signature is valid. +func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error { + // Verify the key is the right type + keyBytes, ok := key.([]byte) + if !ok { + return ErrInvalidKeyType + } + + // Decode signature, for comparison + sig, err := DecodeSegment(signature) + if err != nil { + return err + } + + // Can we use the specified hashing method? + if !m.Hash.Available() { + return ErrHashUnavailable + } + + // This signing method is symmetric, so we validate the signature + // by reproducing the signature from the signing string and key, then + // comparing that against the provided signature. + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + if !hmac.Equal(sig, hasher.Sum(nil)) { + return ErrSignatureInvalid + } + + // No validation errors. Signature is good. + return nil +} + +// Implements the Sign method from SigningMethod for this signing method. +// Key must be []byte +func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) { + if keyBytes, ok := key.([]byte); ok { + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + + return EncodeSegment(hasher.Sum(nil)), nil + } + + return "", ErrInvalidKey +} diff --git a/vendor/github.com/dgrijalva/jwt-go/map_claims.go b/vendor/github.com/dgrijalva/jwt-go/map_claims.go new file mode 100644 index 0000000000..291213c460 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/map_claims.go @@ -0,0 +1,94 @@ +package jwt + +import ( + "encoding/json" + "errors" + // "fmt" +) + +// Claims type that uses the map[string]interface{} for JSON decoding +// This is the default claims type if you don't supply one +type MapClaims map[string]interface{} + +// Compares the aud claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyAudience(cmp string, req bool) bool { + aud, _ := m["aud"].(string) + return verifyAud(aud, cmp, req) +} + +// Compares the exp claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool { + switch exp := m["exp"].(type) { + case float64: + return verifyExp(int64(exp), cmp, req) + case json.Number: + v, _ := exp.Int64() + return verifyExp(v, cmp, req) + } + return req == false +} + +// Compares the iat claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool { + switch iat := m["iat"].(type) { + case float64: + return verifyIat(int64(iat), cmp, req) + case json.Number: + v, _ := iat.Int64() + return verifyIat(v, cmp, req) + } + return req == false +} + +// Compares the iss claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyIssuer(cmp string, req bool) bool { + iss, _ := m["iss"].(string) + return verifyIss(iss, cmp, req) +} + +// Compares the nbf claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool { + switch nbf := m["nbf"].(type) { + case float64: + return verifyNbf(int64(nbf), cmp, req) + case json.Number: + v, _ := nbf.Int64() + return verifyNbf(v, cmp, req) + } + return req == false +} + +// Validates time based claims "exp, iat, nbf". +// There is no accounting for clock skew. +// As well, if any of the above claims are not in the token, it will still +// be considered a valid claim. +func (m MapClaims) Valid() error { + vErr := new(ValidationError) + now := TimeFunc().Unix() + + if m.VerifyExpiresAt(now, false) == false { + vErr.Inner = errors.New("Token is expired") + vErr.Errors |= ValidationErrorExpired + } + + if m.VerifyIssuedAt(now, false) == false { + vErr.Inner = errors.New("Token used before issued") + vErr.Errors |= ValidationErrorIssuedAt + } + + if m.VerifyNotBefore(now, false) == false { + vErr.Inner = errors.New("Token is not valid yet") + vErr.Errors |= ValidationErrorNotValidYet + } + + if vErr.valid() { + return nil + } + + return vErr +} diff --git a/vendor/github.com/dgrijalva/jwt-go/none.go b/vendor/github.com/dgrijalva/jwt-go/none.go new file mode 100644 index 0000000000..f04d189d06 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/none.go @@ -0,0 +1,52 @@ +package jwt + +// Implements the none signing method. This is required by the spec +// but you probably should never use it. +var SigningMethodNone *signingMethodNone + +const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" + +var NoneSignatureTypeDisallowedError error + +type signingMethodNone struct{} +type unsafeNoneMagicConstant string + +func init() { + SigningMethodNone = &signingMethodNone{} + NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid) + + RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { + return SigningMethodNone + }) +} + +func (m *signingMethodNone) Alg() string { + return "none" +} + +// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) { + // Key must be UnsafeAllowNoneSignatureType to prevent accidentally + // accepting 'none' signing method + if _, ok := key.(unsafeNoneMagicConstant); !ok { + return NoneSignatureTypeDisallowedError + } + // If signing method is none, signature must be an empty string + if signature != "" { + return NewValidationError( + "'none' signing method with non-empty signature", + ValidationErrorSignatureInvalid, + ) + } + + // Accept 'none' signing method. + return nil +} + +// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) { + if _, ok := key.(unsafeNoneMagicConstant); ok { + return "", nil + } + return "", NoneSignatureTypeDisallowedError +} diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go new file mode 100644 index 0000000000..7bf1c4ea08 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/parser.go @@ -0,0 +1,131 @@ +package jwt + +import ( + "bytes" + "encoding/json" + "fmt" + "strings" +) + +type Parser struct { + ValidMethods []string // If populated, only these methods will be considered valid + UseJSONNumber bool // Use JSON Number format in JSON decoder + SkipClaimsValidation bool // Skip claims validation during token parsing +} + +// Parse, validate, and return a token. +// keyFunc will receive the parsed token and should return the key for validating. +// If everything is kosher, err will be nil +func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) +} + +func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + parts := strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) + } + + var err error + token := &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = DecodeSegment(parts[0]); err != nil { + if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { + return token, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) + } + return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // parse Claims + var claimBytes []byte + token.Claims = claims + + if claimBytes, err = DecodeSegment(parts[1]); err != nil { + return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + if p.UseJSONNumber { + dec.UseNumber() + } + // JSON Decode. Special case for map type to avoid weird pointer behavior + if c, ok := token.Claims.(MapClaims); ok { + err = dec.Decode(&c) + } else { + err = dec.Decode(&claims) + } + // Handle decode error + if err != nil { + return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) + } + } else { + return token, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + } + + // Verify signing method is in the required set + if p.ValidMethods != nil { + var signingMethodValid = false + var alg = token.Method.Alg() + for _, m := range p.ValidMethods { + if m == alg { + signingMethodValid = true + break + } + } + if !signingMethodValid { + // signing method is not in the listed set + return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid) + } + } + + // Lookup key + var key interface{} + if keyFunc == nil { + // keyFunc was not provided. short circuiting validation + return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable) + } + if key, err = keyFunc(token); err != nil { + // keyFunc returned an error + return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable} + } + + vErr := &ValidationError{} + + // Validate Claims + if !p.SkipClaimsValidation { + if err := token.Claims.Valid(); err != nil { + + // If the Claims Valid returned an error, check if it is a validation error, + // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set + if e, ok := err.(*ValidationError); !ok { + vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid} + } else { + vErr = e + } + } + } + + // Perform validation + token.Signature = parts[2] + if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil { + vErr.Inner = err + vErr.Errors |= ValidationErrorSignatureInvalid + } + + if vErr.valid() { + token.Valid = true + return token, nil + } + + return token, vErr +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/dgrijalva/jwt-go/rsa.go new file mode 100644 index 0000000000..0ae0b1984e --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa.go @@ -0,0 +1,100 @@ +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// Implements the RSA family of signing methods signing methods +type SigningMethodRSA struct { + Name string + Hash crypto.Hash +} + +// Specific instances for RS256 and company +var ( + SigningMethodRS256 *SigningMethodRSA + SigningMethodRS384 *SigningMethodRSA + SigningMethodRS512 *SigningMethodRSA +) + +func init() { + // RS256 + SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { + return SigningMethodRS256 + }) + + // RS384 + SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { + return SigningMethodRS384 + }) + + // RS512 + SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { + return SigningMethodRS512 + }) +} + +func (m *SigningMethodRSA) Alg() string { + return m.Name +} + +// Implements the Verify method from SigningMethod +// For this signing method, must be an rsa.PublicKey structure. +func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + var rsaKey *rsa.PublicKey + var ok bool + + if rsaKey, ok = key.(*rsa.PublicKey); !ok { + return ErrInvalidKeyType + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) +} + +// Implements the Sign method from SigningMethod +// For this signing method, must be an rsa.PrivateKey structure. +func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { + var rsaKey *rsa.PrivateKey + var ok bool + + // Validate type of key + if rsaKey, ok = key.(*rsa.PrivateKey); !ok { + return "", ErrInvalidKey + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go new file mode 100644 index 0000000000..10ee9db8a4 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go @@ -0,0 +1,126 @@ +// +build go1.4 + +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// Implements the RSAPSS family of signing methods signing methods +type SigningMethodRSAPSS struct { + *SigningMethodRSA + Options *rsa.PSSOptions +} + +// Specific instances for RS/PS and company +var ( + SigningMethodPS256 *SigningMethodRSAPSS + SigningMethodPS384 *SigningMethodRSAPSS + SigningMethodPS512 *SigningMethodRSAPSS +) + +func init() { + // PS256 + SigningMethodPS256 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS256", + Hash: crypto.SHA256, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA256, + }, + } + RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { + return SigningMethodPS256 + }) + + // PS384 + SigningMethodPS384 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS384", + Hash: crypto.SHA384, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA384, + }, + } + RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { + return SigningMethodPS384 + }) + + // PS512 + SigningMethodPS512 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS512", + Hash: crypto.SHA512, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA512, + }, + } + RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { + return SigningMethodPS512 + }) +} + +// Implements the Verify method from SigningMethod +// For this verify method, key must be an rsa.PublicKey struct +func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + var rsaKey *rsa.PublicKey + switch k := key.(type) { + case *rsa.PublicKey: + rsaKey = k + default: + return ErrInvalidKey + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options) +} + +// Implements the Sign method from SigningMethod +// For this signing method, key must be an rsa.PrivateKey struct +func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) { + var rsaKey *rsa.PrivateKey + + switch k := key.(type) { + case *rsa.PrivateKey: + rsaKey = k + default: + return "", ErrInvalidKeyType + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go new file mode 100644 index 0000000000..213a90dbbf --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go @@ -0,0 +1,69 @@ +package jwt + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key") + ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key") + ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key") +) + +// Parse PEM encoded PKCS1 or PKCS8 private key +func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 public key +func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *rsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { + return nil, ErrNotRSAPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/signing_method.go b/vendor/github.com/dgrijalva/jwt-go/signing_method.go new file mode 100644 index 0000000000..ed1f212b21 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/signing_method.go @@ -0,0 +1,35 @@ +package jwt + +import ( + "sync" +) + +var signingMethods = map[string]func() SigningMethod{} +var signingMethodLock = new(sync.RWMutex) + +// Implement SigningMethod to add new methods for signing or verifying tokens. +type SigningMethod interface { + Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid + Sign(signingString string, key interface{}) (string, error) // Returns encoded signature or error + Alg() string // returns the alg identifier for this method (example: 'HS256') +} + +// Register the "alg" name and a factory function for signing method. +// This is typically done during init() in the method's implementation +func RegisterSigningMethod(alg string, f func() SigningMethod) { + signingMethodLock.Lock() + defer signingMethodLock.Unlock() + + signingMethods[alg] = f +} + +// Get a signing method from an "alg" string +func GetSigningMethod(alg string) (method SigningMethod) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + if methodF, ok := signingMethods[alg]; ok { + method = methodF() + } + return +} diff --git a/vendor/github.com/dgrijalva/jwt-go/token.go b/vendor/github.com/dgrijalva/jwt-go/token.go new file mode 100644 index 0000000000..d637e0867c --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/token.go @@ -0,0 +1,108 @@ +package jwt + +import ( + "encoding/base64" + "encoding/json" + "strings" + "time" +) + +// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time). +// You can override it to use another time value. This is useful for testing or if your +// server uses a different time zone than your tokens. +var TimeFunc = time.Now + +// Parse methods use this callback function to supply +// the key for verification. The function receives the parsed, +// but unverified Token. This allows you to use properties in the +// Header of the token (such as `kid`) to identify which key to use. +type Keyfunc func(*Token) (interface{}, error) + +// A JWT Token. Different fields will be used depending on whether you're +// creating or parsing/verifying a token. +type Token struct { + Raw string // The raw token. Populated when you Parse a token + Method SigningMethod // The signing method used or to be used + Header map[string]interface{} // The first segment of the token + Claims Claims // The second segment of the token + Signature string // The third segment of the token. Populated when you Parse a token + Valid bool // Is the token valid? Populated when you Parse/Verify a token +} + +// Create a new Token. Takes a signing method +func New(method SigningMethod) *Token { + return NewWithClaims(method, MapClaims{}) +} + +func NewWithClaims(method SigningMethod, claims Claims) *Token { + return &Token{ + Header: map[string]interface{}{ + "typ": "JWT", + "alg": method.Alg(), + }, + Claims: claims, + Method: method, + } +} + +// Get the complete, signed token +func (t *Token) SignedString(key interface{}) (string, error) { + var sig, sstr string + var err error + if sstr, err = t.SigningString(); err != nil { + return "", err + } + if sig, err = t.Method.Sign(sstr, key); err != nil { + return "", err + } + return strings.Join([]string{sstr, sig}, "."), nil +} + +// Generate the signing string. This is the +// most expensive part of the whole deal. Unless you +// need this for something special, just go straight for +// the SignedString. +func (t *Token) SigningString() (string, error) { + var err error + parts := make([]string, 2) + for i, _ := range parts { + var jsonValue []byte + if i == 0 { + if jsonValue, err = json.Marshal(t.Header); err != nil { + return "", err + } + } else { + if jsonValue, err = json.Marshal(t.Claims); err != nil { + return "", err + } + } + + parts[i] = EncodeSegment(jsonValue) + } + return strings.Join(parts, "."), nil +} + +// Parse, validate, and return a token. +// keyFunc will receive the parsed token and should return the key for validating. +// If everything is kosher, err will be nil +func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return new(Parser).Parse(tokenString, keyFunc) +} + +func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + return new(Parser).ParseWithClaims(tokenString, claims, keyFunc) +} + +// Encode JWT specific base64url encoding with padding stripped +func EncodeSegment(seg []byte) string { + return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=") +} + +// Decode JWT specific base64url encoding with padding stripped +func DecodeSegment(seg string) ([]byte, error) { + if l := len(seg) % 4; l > 0 { + seg += strings.Repeat("=", 4-l) + } + + return base64.URLEncoding.DecodeString(seg) +} diff --git a/vendor/github.com/digitalocean/godo/.gitignore b/vendor/github.com/digitalocean/godo/.gitignore new file mode 100755 index 0000000000..48b8bf9072 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/vendor/github.com/digitalocean/godo/.travis.yml b/vendor/github.com/digitalocean/godo/.travis.yml new file mode 100644 index 0000000000..f918f8d761 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/.travis.yml @@ -0,0 +1,5 @@ +language: go + +go: + - 1.7 + - tip diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md new file mode 100644 index 0000000000..71886a3542 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +## [v1.0.0] - 2017-03-10 + +### Added +- #130 Add Convert to ImageActionsService. - @xmudrii +- #126 Add CertificatesService for managing certificates with the DigitalOcean API. - @viola +- #125 Add LoadBalancersService for managing load balancers with the DigitalOcean API. - @viola +- #122 Add GetVolumeByName to StorageService. - @protochron +- #113 Add context.Context to all calls. - @aybabtme diff --git a/vendor/github.com/digitalocean/godo/CONTRIBUTING.md b/vendor/github.com/digitalocean/godo/CONTRIBUTING.md new file mode 100644 index 0000000000..f27200a7a3 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +If you submit a pull request, please keep the following guidelines in mind: + +1. Code should be `go fmt` compliant. +2. Types, structs and funcs should be documented. +3. Tests pass. + +## Getting set up + +Assuming your `$GOPATH` is set up according to your desires, run: + +```sh +go get github.com/digitalocean/godo +``` + +## Running tests + +When working on code in this repository, tests can be run via: + +```sh +go test . +``` diff --git a/vendor/github.com/digitalocean/godo/LICENSE.txt b/vendor/github.com/digitalocean/godo/LICENSE.txt new file mode 100644 index 0000000000..43c5d2eee7 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/LICENSE.txt @@ -0,0 +1,55 @@ +Copyright (c) 2014-2016 The godo AUTHORS. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +====================== +Portions of the client are based on code at: +https://github.com/google/go-github/ + +Copyright (c) 2013 The go-github AUTHORS. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/github.com/digitalocean/godo/README.md b/vendor/github.com/digitalocean/godo/README.md new file mode 100644 index 0000000000..4d5cdf83eb --- /dev/null +++ b/vendor/github.com/digitalocean/godo/README.md @@ -0,0 +1,138 @@ +[![Build Status](https://travis-ci.org/digitalocean/godo.svg)](https://travis-ci.org/digitalocean/godo) + +# Godo + +Godo is a Go client library for accessing the DigitalOcean V2 API. + +You can view the client API docs here: [http://godoc.org/github.com/digitalocean/godo](http://godoc.org/github.com/digitalocean/godo) + +You can view DigitalOcean API docs here: [https://developers.digitalocean.com/documentation/v2/](https://developers.digitalocean.com/documentation/v2/) + + +## Usage + +```go +import "github.com/digitalocean/godo" +``` + +Create a new DigitalOcean client, then use the exposed services to +access different parts of the DigitalOcean API. + +### Authentication + +Currently, Personal Access Token (PAT) is the only method of +authenticating with the API. You can manage your tokens +at the DigitalOcean Control Panel [Applications Page](https://cloud.digitalocean.com/settings/applications). + +You can then use your token to create a new client: + +```go +import "golang.org/x/oauth2" + +pat := "mytoken" +type TokenSource struct { + AccessToken string +} + +func (t *TokenSource) Token() (*oauth2.Token, error) { + token := &oauth2.Token{ + AccessToken: t.AccessToken, + } + return token, nil +} + +tokenSource := &TokenSource{ + AccessToken: pat, +} +oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource) +client := godo.NewClient(oauthClient) +``` + +## Examples + + +To create a new Droplet: + +```go +dropletName := "super-cool-droplet" + +createRequest := &godo.DropletCreateRequest{ + Name: dropletName, + Region: "nyc3", + Size: "512mb", + Image: godo.DropletCreateImage{ + Slug: "ubuntu-14-04-x64", + }, +} + +ctx := context.TODO() + +newDroplet, _, err := client.Droplets.Create(ctx, createRequest) + +if err != nil { + fmt.Printf("Something bad happened: %s\n\n", err) + return err +} +``` + +### Pagination + +If a list of items is paginated by the API, you must request pages individually. For example, to fetch all Droplets: + +```go +func DropletList(ctx context.Context, client *godo.Client) ([]godo.Droplet, error) { + // create a list to hold our droplets + list := []godo.Droplet{} + + // create options. initially, these will be blank + opt := &godo.ListOptions{} + for { + droplets, resp, err := client.Droplets.List(ctx, opt) + if err != nil { + return nil, err + } + + // append the current page's droplets to our list + for _, d := range droplets { + list = append(list, d) + } + + // if we are at the last page, break out the for loop + if resp.Links == nil || resp.Links.IsLastPage() { + break + } + + page, err := resp.Links.CurrentPage() + if err != nil { + return nil, err + } + + // set the page we want for the next request + opt.Page = page + 1 + } + + return list, nil +} +``` + +## Versioning + +Each version of the client is tagged and the version is updated accordingly. + +Since Go does not have a built-in versioning, a package management tool is +recommended - a good one that works with git tags is +[gopkg.in](http://labix.org/gopkg.in). + +To see the list of past versions, run `git tag`. + + +## Documentation + +For a comprehensive list of examples, check out the [API documentation](https://developers.digitalocean.com/documentation/v2/). + +For details on all the functionality in this library, see the [GoDoc](http://godoc.org/github.com/digitalocean/godo) documentation. + + +## Contributing + +We love pull requests! Please see the [contribution guidelines](CONTRIBUTING.md). diff --git a/vendor/github.com/digitalocean/godo/account.go b/vendor/github.com/digitalocean/godo/account.go new file mode 100644 index 0000000000..18eed97125 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/account.go @@ -0,0 +1,56 @@ +package godo + +import "context" + +// AccountService is an interface for interfacing with the Account +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2/#account +type AccountService interface { + Get(context.Context) (*Account, *Response, error) +} + +// AccountServiceOp handles communication with the Account related methods of +// the DigitalOcean API. +type AccountServiceOp struct { + client *Client +} + +var _ AccountService = &AccountServiceOp{} + +// Account represents a DigitalOcean Account +type Account struct { + DropletLimit int `json:"droplet_limit,omitempty"` + FloatingIPLimit int `json:"floating_ip_limit,omitempty"` + Email string `json:"email,omitempty"` + UUID string `json:"uuid,omitempty"` + EmailVerified bool `json:"email_verified,omitempty"` + Status string `json:"status,omitempty"` + StatusMessage string `json:"status_message,omitempty"` +} + +type accountRoot struct { + Account *Account `json:"account"` +} + +func (r Account) String() string { + return Stringify(r) +} + +// Get DigitalOcean account info +func (s *AccountServiceOp) Get(ctx context.Context) (*Account, *Response, error) { + + path := "v2/account" + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(accountRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Account, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/action.go b/vendor/github.com/digitalocean/godo/action.go new file mode 100644 index 0000000000..9baef21473 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/action.go @@ -0,0 +1,103 @@ +package godo + +import ( + "context" + "fmt" +) + +const ( + actionsBasePath = "v2/actions" + + // ActionInProgress is an in progress action status + ActionInProgress = "in-progress" + + //ActionCompleted is a completed action status + ActionCompleted = "completed" +) + +// ActionsService handles communction with action related methods of the +// DigitalOcean API: https://developers.digitalocean.com/documentation/v2#actions +type ActionsService interface { + List(context.Context, *ListOptions) ([]Action, *Response, error) + Get(context.Context, int) (*Action, *Response, error) +} + +// ActionsServiceOp handles communition with the image action related methods of the +// DigitalOcean API. +type ActionsServiceOp struct { + client *Client +} + +var _ ActionsService = &ActionsServiceOp{} + +type actionsRoot struct { + Actions []Action `json:"actions"` + Links *Links `json:"links"` +} + +type actionRoot struct { + Event *Action `json:"action"` +} + +// Action represents a DigitalOcean Action +type Action struct { + ID int `json:"id"` + Status string `json:"status"` + Type string `json:"type"` + StartedAt *Timestamp `json:"started_at"` + CompletedAt *Timestamp `json:"completed_at"` + ResourceID int `json:"resource_id"` + ResourceType string `json:"resource_type"` + Region *Region `json:"region,omitempty"` + RegionSlug string `json:"region_slug,omitempty"` +} + +// List all actions +func (s *ActionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Action, *Response, error) { + path := actionsBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Actions, resp, err +} + +// Get an action by ID. +func (s *ActionsServiceOp) Get(ctx context.Context, id int) (*Action, *Response, error) { + if id < 1 { + return nil, nil, NewArgError("id", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", actionsBasePath, id) + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func (a Action) String() string { + return Stringify(a) +} diff --git a/vendor/github.com/digitalocean/godo/certificates.go b/vendor/github.com/digitalocean/godo/certificates.go new file mode 100644 index 0000000000..b48e80ec32 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/certificates.go @@ -0,0 +1,120 @@ +package godo + +import ( + "context" + "path" +) + +const certificatesBasePath = "/v2/certificates" + +// CertificatesService is an interface for managing certificates with the DigitalOcean API. +// See: https://developers.digitalocean.com/documentation/v2/#certificates +type CertificatesService interface { + Get(context.Context, string) (*Certificate, *Response, error) + List(context.Context, *ListOptions) ([]Certificate, *Response, error) + Create(context.Context, *CertificateRequest) (*Certificate, *Response, error) + Delete(context.Context, string) (*Response, error) +} + +// Certificate represents a DigitalOcean certificate configuration. +type Certificate struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + NotAfter string `json:"not_after,omitempty"` + SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"` + Created string `json:"created_at,omitempty"` +} + +// CertificateRequest represents configuration for a new certificate. +type CertificateRequest struct { + Name string `json:"name,omitempty"` + PrivateKey string `json:"private_key,omitempty"` + LeafCertificate string `json:"leaf_certificate,omitempty"` + CertificateChain string `json:"certificate_chain,omitempty"` +} + +type certificateRoot struct { + Certificate *Certificate `json:"certificate"` +} + +type certificatesRoot struct { + Certificates []Certificate `json:"certificates"` + Links *Links `json:"links"` +} + +// CertificatesServiceOp handles communication with certificates methods of the DigitalOcean API. +type CertificatesServiceOp struct { + client *Client +} + +var _ CertificatesService = &CertificatesServiceOp{} + +// Get an existing certificate by its identifier. +func (c *CertificatesServiceOp) Get(ctx context.Context, cID string) (*Certificate, *Response, error) { + urlStr := path.Join(certificatesBasePath, cID) + + req, err := c.client.NewRequest(ctx, "GET", urlStr, nil) + if err != nil { + return nil, nil, err + } + + root := new(certificateRoot) + resp, err := c.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Certificate, resp, nil +} + +// List all certificates. +func (c *CertificatesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Certificate, *Response, error) { + urlStr, err := addOptions(certificatesBasePath, opt) + if err != nil { + return nil, nil, err + } + + req, err := c.client.NewRequest(ctx, "GET", urlStr, nil) + if err != nil { + return nil, nil, err + } + + root := new(certificatesRoot) + resp, err := c.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Certificates, resp, nil +} + +// Create a new certificate with provided configuration. +func (c *CertificatesServiceOp) Create(ctx context.Context, cr *CertificateRequest) (*Certificate, *Response, error) { + req, err := c.client.NewRequest(ctx, "POST", certificatesBasePath, cr) + if err != nil { + return nil, nil, err + } + + root := new(certificateRoot) + resp, err := c.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Certificate, resp, nil +} + +// Delete a certificate by its identifier. +func (c *CertificatesServiceOp) Delete(ctx context.Context, cID string) (*Response, error) { + urlStr := path.Join(certificatesBasePath, cID) + + req, err := c.client.NewRequest(ctx, "DELETE", urlStr, nil) + if err != nil { + return nil, err + } + + return c.client.Do(req, nil) +} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/doc.go b/vendor/github.com/digitalocean/godo/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/digitalocean/godo/doc.go rename to vendor/github.com/digitalocean/godo/doc.go diff --git a/vendor/github.com/digitalocean/godo/domains.go b/vendor/github.com/digitalocean/godo/domains.go new file mode 100644 index 0000000000..fdc2a84c64 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/domains.go @@ -0,0 +1,326 @@ +package godo + +import ( + "context" + "fmt" +) + +const domainsBasePath = "v2/domains" + +// DomainsService is an interface for managing DNS with the DigitalOcean API. +// See: https://developers.digitalocean.com/documentation/v2#domains and +// https://developers.digitalocean.com/documentation/v2#domain-records +type DomainsService interface { + List(context.Context, *ListOptions) ([]Domain, *Response, error) + Get(context.Context, string) (*Domain, *Response, error) + Create(context.Context, *DomainCreateRequest) (*Domain, *Response, error) + Delete(context.Context, string) (*Response, error) + + Records(context.Context, string, *ListOptions) ([]DomainRecord, *Response, error) + Record(context.Context, string, int) (*DomainRecord, *Response, error) + DeleteRecord(context.Context, string, int) (*Response, error) + EditRecord(context.Context, string, int, *DomainRecordEditRequest) (*DomainRecord, *Response, error) + CreateRecord(context.Context, string, *DomainRecordEditRequest) (*DomainRecord, *Response, error) +} + +// DomainsServiceOp handles communication with the domain related methods of the +// DigitalOcean API. +type DomainsServiceOp struct { + client *Client +} + +var _ DomainsService = &DomainsServiceOp{} + +// Domain represents a DigitalOcean domain +type Domain struct { + Name string `json:"name"` + TTL int `json:"ttl"` + ZoneFile string `json:"zone_file"` +} + +// domainRoot represents a response from the DigitalOcean API +type domainRoot struct { + Domain *Domain `json:"domain"` +} + +type domainsRoot struct { + Domains []Domain `json:"domains"` + Links *Links `json:"links"` +} + +// DomainCreateRequest respresents a request to create a domain. +type DomainCreateRequest struct { + Name string `json:"name"` + IPAddress string `json:"ip_address"` +} + +// DomainRecordRoot is the root of an individual Domain Record response +type domainRecordRoot struct { + DomainRecord *DomainRecord `json:"domain_record"` +} + +// DomainRecordsRoot is the root of a group of Domain Record responses +type domainRecordsRoot struct { + DomainRecords []DomainRecord `json:"domain_records"` + Links *Links `json:"links"` +} + +// DomainRecord represents a DigitalOcean DomainRecord +type DomainRecord struct { + ID int `json:"id,float64,omitempty"` + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Data string `json:"data,omitempty"` + Priority int `json:"priority,omitempty"` + Port int `json:"port,omitempty"` + Weight int `json:"weight,omitempty"` +} + +// DomainRecordEditRequest represents a request to update a domain record. +type DomainRecordEditRequest struct { + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Data string `json:"data,omitempty"` + Priority int `json:"priority,omitempty"` + Port int `json:"port,omitempty"` + Weight int `json:"weight,omitempty"` +} + +func (d Domain) String() string { + return Stringify(d) +} + +// List all domains. +func (s DomainsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Domain, *Response, error) { + path := domainsBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(domainsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Domains, resp, err +} + +// Get individual domain. It requires a non-empty domain name. +func (s *DomainsServiceOp) Get(ctx context.Context, name string) (*Domain, *Response, error) { + if len(name) < 1 { + return nil, nil, NewArgError("name", "cannot be an empty string") + } + + path := fmt.Sprintf("%s/%s", domainsBasePath, name) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(domainRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Domain, resp, err +} + +// Create a new domain +func (s *DomainsServiceOp) Create(ctx context.Context, createRequest *DomainCreateRequest) (*Domain, *Response, error) { + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + path := domainsBasePath + + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(domainRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + return root.Domain, resp, err +} + +// Delete domain +func (s *DomainsServiceOp) Delete(ctx context.Context, name string) (*Response, error) { + if len(name) < 1 { + return nil, NewArgError("name", "cannot be an empty string") + } + + path := fmt.Sprintf("%s/%s", domainsBasePath, name) + + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// Converts a DomainRecord to a string. +func (d DomainRecord) String() string { + return Stringify(d) +} + +// Converts a DomainRecordEditRequest to a string. +func (d DomainRecordEditRequest) String() string { + return Stringify(d) +} + +// Records returns a slice of DomainRecords for a domain +func (s *DomainsServiceOp) Records(ctx context.Context, domain string, opt *ListOptions) ([]DomainRecord, *Response, error) { + if len(domain) < 1 { + return nil, nil, NewArgError("domain", "cannot be an empty string") + } + + path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(domainRecordsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.DomainRecords, resp, err +} + +// Record returns the record id from a domain +func (s *DomainsServiceOp) Record(ctx context.Context, domain string, id int) (*DomainRecord, *Response, error) { + if len(domain) < 1 { + return nil, nil, NewArgError("domain", "cannot be an empty string") + } + + if id < 1 { + return nil, nil, NewArgError("id", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + record := new(domainRecordRoot) + resp, err := s.client.Do(req, record) + if err != nil { + return nil, resp, err + } + + return record.DomainRecord, resp, err +} + +// DeleteRecord deletes a record from a domain identified by id +func (s *DomainsServiceOp) DeleteRecord(ctx context.Context, domain string, id int) (*Response, error) { + if len(domain) < 1 { + return nil, NewArgError("domain", "cannot be an empty string") + } + + if id < 1 { + return nil, NewArgError("id", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) + + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// EditRecord edits a record using a DomainRecordEditRequest +func (s *DomainsServiceOp) EditRecord(ctx context.Context, + domain string, + id int, + editRequest *DomainRecordEditRequest, +) (*DomainRecord, *Response, error) { + if len(domain) < 1 { + return nil, nil, NewArgError("domain", "cannot be an empty string") + } + + if id < 1 { + return nil, nil, NewArgError("id", "cannot be less than 1") + } + + if editRequest == nil { + return nil, nil, NewArgError("editRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) + + req, err := s.client.NewRequest(ctx, "PUT", path, editRequest) + if err != nil { + return nil, nil, err + } + + d := new(DomainRecord) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, err +} + +// CreateRecord creates a record using a DomainRecordEditRequest +func (s *DomainsServiceOp) CreateRecord(ctx context.Context, + domain string, + createRequest *DomainRecordEditRequest) (*DomainRecord, *Response, error) { + if len(domain) < 1 { + return nil, nil, NewArgError("domain", "cannot be empty string") + } + + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain) + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) + + if err != nil { + return nil, nil, err + } + + d := new(domainRecordRoot) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d.DomainRecord, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/droplet_actions.go b/vendor/github.com/digitalocean/godo/droplet_actions.go new file mode 100644 index 0000000000..cd8b94e2f9 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/droplet_actions.go @@ -0,0 +1,335 @@ +package godo + +import ( + "context" + "fmt" + "net/url" +) + +// ActionRequest reprents DigitalOcean Action Request +type ActionRequest map[string]interface{} + +// DropletActionsService is an interface for interfacing with the Droplet actions +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#droplet-actions +type DropletActionsService interface { + Shutdown(context.Context, int) (*Action, *Response, error) + ShutdownByTag(context.Context, string) (*Action, *Response, error) + PowerOff(context.Context, int) (*Action, *Response, error) + PowerOffByTag(context.Context, string) (*Action, *Response, error) + PowerOn(context.Context, int) (*Action, *Response, error) + PowerOnByTag(context.Context, string) (*Action, *Response, error) + PowerCycle(context.Context, int) (*Action, *Response, error) + PowerCycleByTag(context.Context, string) (*Action, *Response, error) + Reboot(context.Context, int) (*Action, *Response, error) + Restore(context.Context, int, int) (*Action, *Response, error) + Resize(context.Context, int, string, bool) (*Action, *Response, error) + Rename(context.Context, int, string) (*Action, *Response, error) + Snapshot(context.Context, int, string) (*Action, *Response, error) + SnapshotByTag(context.Context, string, string) (*Action, *Response, error) + EnableBackups(context.Context, int) (*Action, *Response, error) + EnableBackupsByTag(context.Context, string) (*Action, *Response, error) + DisableBackups(context.Context, int) (*Action, *Response, error) + DisableBackupsByTag(context.Context, string) (*Action, *Response, error) + PasswordReset(context.Context, int) (*Action, *Response, error) + RebuildByImageID(context.Context, int, int) (*Action, *Response, error) + RebuildByImageSlug(context.Context, int, string) (*Action, *Response, error) + ChangeKernel(context.Context, int, int) (*Action, *Response, error) + EnableIPv6(context.Context, int) (*Action, *Response, error) + EnableIPv6ByTag(context.Context, string) (*Action, *Response, error) + EnablePrivateNetworking(context.Context, int) (*Action, *Response, error) + EnablePrivateNetworkingByTag(context.Context, string) (*Action, *Response, error) + Upgrade(context.Context, int) (*Action, *Response, error) + Get(context.Context, int, int) (*Action, *Response, error) + GetByURI(context.Context, string) (*Action, *Response, error) +} + +// DropletActionsServiceOp handles communication with the Droplet action related +// methods of the DigitalOcean API. +type DropletActionsServiceOp struct { + client *Client +} + +var _ DropletActionsService = &DropletActionsServiceOp{} + +// Shutdown a Droplet +func (s *DropletActionsServiceOp) Shutdown(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "shutdown"} + return s.doAction(ctx, id, request) +} + +// ShutdownByTag shuts down Droplets matched by a Tag. +func (s *DropletActionsServiceOp) ShutdownByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "shutdown"} + return s.doActionByTag(ctx, tag, request) +} + +// PowerOff a Droplet +func (s *DropletActionsServiceOp) PowerOff(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "power_off"} + return s.doAction(ctx, id, request) +} + +// PowerOffByTag powers off Droplets matched by a Tag. +func (s *DropletActionsServiceOp) PowerOffByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "power_off"} + return s.doActionByTag(ctx, tag, request) +} + +// PowerOn a Droplet +func (s *DropletActionsServiceOp) PowerOn(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "power_on"} + return s.doAction(ctx, id, request) +} + +// PowerOnByTag powers on Droplets matched by a Tag. +func (s *DropletActionsServiceOp) PowerOnByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "power_on"} + return s.doActionByTag(ctx, tag, request) +} + +// PowerCycle a Droplet +func (s *DropletActionsServiceOp) PowerCycle(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "power_cycle"} + return s.doAction(ctx, id, request) +} + +// PowerCycleByTag power cycles Droplets matched by a Tag. +func (s *DropletActionsServiceOp) PowerCycleByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "power_cycle"} + return s.doActionByTag(ctx, tag, request) +} + +// Reboot a Droplet +func (s *DropletActionsServiceOp) Reboot(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "reboot"} + return s.doAction(ctx, id, request) +} + +// Restore an image to a Droplet +func (s *DropletActionsServiceOp) Restore(ctx context.Context, id, imageID int) (*Action, *Response, error) { + requestType := "restore" + request := &ActionRequest{ + "type": requestType, + "image": float64(imageID), + } + return s.doAction(ctx, id, request) +} + +// Resize a Droplet +func (s *DropletActionsServiceOp) Resize(ctx context.Context, id int, sizeSlug string, resizeDisk bool) (*Action, *Response, error) { + requestType := "resize" + request := &ActionRequest{ + "type": requestType, + "size": sizeSlug, + "disk": resizeDisk, + } + return s.doAction(ctx, id, request) +} + +// Rename a Droplet +func (s *DropletActionsServiceOp) Rename(ctx context.Context, id int, name string) (*Action, *Response, error) { + requestType := "rename" + request := &ActionRequest{ + "type": requestType, + "name": name, + } + return s.doAction(ctx, id, request) +} + +// Snapshot a Droplet. +func (s *DropletActionsServiceOp) Snapshot(ctx context.Context, id int, name string) (*Action, *Response, error) { + requestType := "snapshot" + request := &ActionRequest{ + "type": requestType, + "name": name, + } + return s.doAction(ctx, id, request) +} + +// SnapshotByTag snapshots Droplets matched by a Tag. +func (s *DropletActionsServiceOp) SnapshotByTag(ctx context.Context, tag string, name string) (*Action, *Response, error) { + requestType := "snapshot" + request := &ActionRequest{ + "type": requestType, + "name": name, + } + return s.doActionByTag(ctx, tag, request) +} + +// EnableBackups enables backups for a Droplet. +func (s *DropletActionsServiceOp) EnableBackups(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "enable_backups"} + return s.doAction(ctx, id, request) +} + +// EnableBackupsByTag enables backups for Droplets matched by a Tag. +func (s *DropletActionsServiceOp) EnableBackupsByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "enable_backups"} + return s.doActionByTag(ctx, tag, request) +} + +// DisableBackups disables backups for a Droplet. +func (s *DropletActionsServiceOp) DisableBackups(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "disable_backups"} + return s.doAction(ctx, id, request) +} + +// DisableBackupsByTag disables backups for Droplet matched by a Tag. +func (s *DropletActionsServiceOp) DisableBackupsByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "disable_backups"} + return s.doActionByTag(ctx, tag, request) +} + +// PasswordReset resets the password for a Droplet. +func (s *DropletActionsServiceOp) PasswordReset(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "password_reset"} + return s.doAction(ctx, id, request) +} + +// RebuildByImageID rebuilds a Droplet from an image with a given id. +func (s *DropletActionsServiceOp) RebuildByImageID(ctx context.Context, id, imageID int) (*Action, *Response, error) { + request := &ActionRequest{"type": "rebuild", "image": imageID} + return s.doAction(ctx, id, request) +} + +// RebuildByImageSlug rebuilds a Droplet from an Image matched by a given Slug. +func (s *DropletActionsServiceOp) RebuildByImageSlug(ctx context.Context, id int, slug string) (*Action, *Response, error) { + request := &ActionRequest{"type": "rebuild", "image": slug} + return s.doAction(ctx, id, request) +} + +// ChangeKernel changes the kernel for a Droplet. +func (s *DropletActionsServiceOp) ChangeKernel(ctx context.Context, id, kernelID int) (*Action, *Response, error) { + request := &ActionRequest{"type": "change_kernel", "kernel": kernelID} + return s.doAction(ctx, id, request) +} + +// EnableIPv6 enables IPv6 for a Droplet. +func (s *DropletActionsServiceOp) EnableIPv6(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "enable_ipv6"} + return s.doAction(ctx, id, request) +} + +// EnableIPv6ByTag enables IPv6 for Droplets matched by a Tag. +func (s *DropletActionsServiceOp) EnableIPv6ByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "enable_ipv6"} + return s.doActionByTag(ctx, tag, request) +} + +// EnablePrivateNetworking enables private networking for a Droplet. +func (s *DropletActionsServiceOp) EnablePrivateNetworking(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "enable_private_networking"} + return s.doAction(ctx, id, request) +} + +// EnablePrivateNetworkingByTag enables private networking for Droplets matched by a Tag. +func (s *DropletActionsServiceOp) EnablePrivateNetworkingByTag(ctx context.Context, tag string) (*Action, *Response, error) { + request := &ActionRequest{"type": "enable_private_networking"} + return s.doActionByTag(ctx, tag, request) +} + +// Upgrade a Droplet. +func (s *DropletActionsServiceOp) Upgrade(ctx context.Context, id int) (*Action, *Response, error) { + request := &ActionRequest{"type": "upgrade"} + return s.doAction(ctx, id, request) +} + +func (s *DropletActionsServiceOp) doAction(ctx context.Context, id int, request *ActionRequest) (*Action, *Response, error) { + if id < 1 { + return nil, nil, NewArgError("id", "cannot be less than 1") + } + + if request == nil { + return nil, nil, NewArgError("request", "request can't be nil") + } + + path := dropletActionPath(id) + + req, err := s.client.NewRequest(ctx, "POST", path, request) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func (s *DropletActionsServiceOp) doActionByTag(ctx context.Context, tag string, request *ActionRequest) (*Action, *Response, error) { + if tag == "" { + return nil, nil, NewArgError("tag", "cannot be empty") + } + + if request == nil { + return nil, nil, NewArgError("request", "request can't be nil") + } + + path := dropletActionPathByTag(tag) + + req, err := s.client.NewRequest(ctx, "POST", path, request) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +// Get an action for a particular Droplet by id. +func (s *DropletActionsServiceOp) Get(ctx context.Context, dropletID, actionID int) (*Action, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + if actionID < 1 { + return nil, nil, NewArgError("actionID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", dropletActionPath(dropletID), actionID) + return s.get(ctx, path) +} + +// GetByURI gets an action for a particular Droplet by id. +func (s *DropletActionsServiceOp) GetByURI(ctx context.Context, rawurl string) (*Action, *Response, error) { + u, err := url.Parse(rawurl) + if err != nil { + return nil, nil, err + } + + return s.get(ctx, u.Path) + +} + +func (s *DropletActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err + +} + +func dropletActionPath(dropletID int) string { + return fmt.Sprintf("v2/droplets/%d/actions", dropletID) +} + +func dropletActionPathByTag(tag string) string { + return fmt.Sprintf("v2/droplets/actions?tag_name=%s", tag) +} diff --git a/vendor/github.com/digitalocean/godo/droplets.go b/vendor/github.com/digitalocean/godo/droplets.go new file mode 100644 index 0000000000..b145d9805e --- /dev/null +++ b/vendor/github.com/digitalocean/godo/droplets.go @@ -0,0 +1,565 @@ +package godo + +import ( + "context" + "encoding/json" + "errors" + "fmt" +) + +const dropletBasePath = "v2/droplets" + +var errNoNetworks = errors.New("no networks have been defined") + +// DropletsService is an interface for interfacing with the Droplet +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#droplets +type DropletsService interface { + List(context.Context, *ListOptions) ([]Droplet, *Response, error) + ListByTag(context.Context, string, *ListOptions) ([]Droplet, *Response, error) + Get(context.Context, int) (*Droplet, *Response, error) + Create(context.Context, *DropletCreateRequest) (*Droplet, *Response, error) + CreateMultiple(context.Context, *DropletMultiCreateRequest) ([]Droplet, *Response, error) + Delete(context.Context, int) (*Response, error) + DeleteByTag(context.Context, string) (*Response, error) + Kernels(context.Context, int, *ListOptions) ([]Kernel, *Response, error) + Snapshots(context.Context, int, *ListOptions) ([]Image, *Response, error) + Backups(context.Context, int, *ListOptions) ([]Image, *Response, error) + Actions(context.Context, int, *ListOptions) ([]Action, *Response, error) + Neighbors(context.Context, int) ([]Droplet, *Response, error) +} + +// DropletsServiceOp handles communication with the Droplet related methods of the +// DigitalOcean API. +type DropletsServiceOp struct { + client *Client +} + +var _ DropletsService = &DropletsServiceOp{} + +// Droplet represents a DigitalOcean Droplet +type Droplet struct { + ID int `json:"id,float64,omitempty"` + Name string `json:"name,omitempty"` + Memory int `json:"memory,omitempty"` + Vcpus int `json:"vcpus,omitempty"` + Disk int `json:"disk,omitempty"` + Region *Region `json:"region,omitempty"` + Image *Image `json:"image,omitempty"` + Size *Size `json:"size,omitempty"` + SizeSlug string `json:"size_slug,omitempty"` + BackupIDs []int `json:"backup_ids,omitempty"` + NextBackupWindow *BackupWindow `json:"next_backup_window,omitempty"` + SnapshotIDs []int `json:"snapshot_ids,omitempty"` + Features []string `json:"features,omitempty"` + Locked bool `json:"locked,bool,omitempty"` + Status string `json:"status,omitempty"` + Networks *Networks `json:"networks,omitempty"` + Created string `json:"created_at,omitempty"` + Kernel *Kernel `json:"kernel,omitempty"` + Tags []string `json:"tags,omitempty"` + VolumeIDs []string `json:"volume_ids"` +} + +// PublicIPv4 returns the public IPv4 address for the Droplet. +func (d *Droplet) PublicIPv4() (string, error) { + if d.Networks == nil { + return "", errNoNetworks + } + + for _, v4 := range d.Networks.V4 { + if v4.Type == "public" { + return v4.IPAddress, nil + } + } + + return "", nil +} + +// PrivateIPv4 returns the private IPv4 address for the Droplet. +func (d *Droplet) PrivateIPv4() (string, error) { + if d.Networks == nil { + return "", errNoNetworks + } + + for _, v4 := range d.Networks.V4 { + if v4.Type == "private" { + return v4.IPAddress, nil + } + } + + return "", nil +} + +// PublicIPv6 returns the public IPv6 address for the Droplet. +func (d *Droplet) PublicIPv6() (string, error) { + if d.Networks == nil { + return "", errNoNetworks + } + + for _, v6 := range d.Networks.V6 { + if v6.Type == "public" { + return v6.IPAddress, nil + } + } + + return "", nil +} + +// Kernel object +type Kernel struct { + ID int `json:"id,float64,omitempty"` + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` +} + +// BackupWindow object +type BackupWindow struct { + Start *Timestamp `json:"start,omitempty"` + End *Timestamp `json:"end,omitempty"` +} + +// Convert Droplet to a string +func (d Droplet) String() string { + return Stringify(d) +} + +// DropletRoot represents a Droplet root +type dropletRoot struct { + Droplet *Droplet `json:"droplet"` + Links *Links `json:"links,omitempty"` +} + +type dropletsRoot struct { + Droplets []Droplet `json:"droplets"` + Links *Links `json:"links"` +} + +type kernelsRoot struct { + Kernels []Kernel `json:"kernels,omitempty"` + Links *Links `json:"links"` +} + +type dropletSnapshotsRoot struct { + Snapshots []Image `json:"snapshots,omitempty"` + Links *Links `json:"links"` +} + +type backupsRoot struct { + Backups []Image `json:"backups,omitempty"` + Links *Links `json:"links"` +} + +// DropletCreateImage identifies an image for the create request. It prefers slug over ID. +type DropletCreateImage struct { + ID int + Slug string +} + +// MarshalJSON returns either the slug or id of the image. It returns the id +// if the slug is empty. +func (d DropletCreateImage) MarshalJSON() ([]byte, error) { + if d.Slug != "" { + return json.Marshal(d.Slug) + } + + return json.Marshal(d.ID) +} + +// DropletCreateVolume identifies a volume to attach for the create request. It +// prefers Name over ID, +type DropletCreateVolume struct { + ID string + Name string +} + +// MarshalJSON returns an object with either the name or id of the volume. It +// returns the id if the name is empty. +func (d DropletCreateVolume) MarshalJSON() ([]byte, error) { + if d.Name != "" { + return json.Marshal(struct { + Name string `json:"name"` + }{Name: d.Name}) + } + + return json.Marshal(struct { + ID string `json:"id"` + }{ID: d.ID}) +} + +// DropletCreateSSHKey identifies a SSH Key for the create request. It prefers fingerprint over ID. +type DropletCreateSSHKey struct { + ID int + Fingerprint string +} + +// MarshalJSON returns either the fingerprint or id of the ssh key. It returns +// the id if the fingerprint is empty. +func (d DropletCreateSSHKey) MarshalJSON() ([]byte, error) { + if d.Fingerprint != "" { + return json.Marshal(d.Fingerprint) + } + + return json.Marshal(d.ID) +} + +// DropletCreateRequest represents a request to create a Droplet. +type DropletCreateRequest struct { + Name string `json:"name"` + Region string `json:"region"` + Size string `json:"size"` + Image DropletCreateImage `json:"image"` + SSHKeys []DropletCreateSSHKey `json:"ssh_keys"` + Backups bool `json:"backups"` + IPv6 bool `json:"ipv6"` + PrivateNetworking bool `json:"private_networking"` + Monitoring bool `json:"monitoring"` + UserData string `json:"user_data,omitempty"` + Volumes []DropletCreateVolume `json:"volumes,omitempty"` + Tags []string `json:"tags"` +} + +// DropletMultiCreateRequest is a request to create multiple Droplets. +type DropletMultiCreateRequest struct { + Names []string `json:"names"` + Region string `json:"region"` + Size string `json:"size"` + Image DropletCreateImage `json:"image"` + SSHKeys []DropletCreateSSHKey `json:"ssh_keys"` + Backups bool `json:"backups"` + IPv6 bool `json:"ipv6"` + PrivateNetworking bool `json:"private_networking"` + Monitoring bool `json:"monitoring"` + UserData string `json:"user_data,omitempty"` + Tags []string `json:"tags"` +} + +func (d DropletCreateRequest) String() string { + return Stringify(d) +} + +func (d DropletMultiCreateRequest) String() string { + return Stringify(d) +} + +// Networks represents the Droplet's Networks. +type Networks struct { + V4 []NetworkV4 `json:"v4,omitempty"` + V6 []NetworkV6 `json:"v6,omitempty"` +} + +// NetworkV4 represents a DigitalOcean IPv4 Network. +type NetworkV4 struct { + IPAddress string `json:"ip_address,omitempty"` + Netmask string `json:"netmask,omitempty"` + Gateway string `json:"gateway,omitempty"` + Type string `json:"type,omitempty"` +} + +func (n NetworkV4) String() string { + return Stringify(n) +} + +// NetworkV6 represents a DigitalOcean IPv6 network. +type NetworkV6 struct { + IPAddress string `json:"ip_address,omitempty"` + Netmask int `json:"netmask,omitempty"` + Gateway string `json:"gateway,omitempty"` + Type string `json:"type,omitempty"` +} + +func (n NetworkV6) String() string { + return Stringify(n) +} + +// Performs a list request given a path. +func (s *DropletsServiceOp) list(ctx context.Context, path string) ([]Droplet, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(dropletsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Droplets, resp, err +} + +// List all Droplets. +func (s *DropletsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Droplet, *Response, error) { + path := dropletBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + return s.list(ctx, path) +} + +// ListByTag lists all Droplets matched by a Tag. +func (s *DropletsServiceOp) ListByTag(ctx context.Context, tag string, opt *ListOptions) ([]Droplet, *Response, error) { + path := fmt.Sprintf("%s?tag_name=%s", dropletBasePath, tag) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + return s.list(ctx, path) +} + +// Get individual Droplet. +func (s *DropletsServiceOp) Get(ctx context.Context, dropletID int) (*Droplet, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(dropletRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Droplet, resp, err +} + +// Create Droplet +func (s *DropletsServiceOp) Create(ctx context.Context, createRequest *DropletCreateRequest) (*Droplet, *Response, error) { + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + path := dropletBasePath + + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(dropletRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Droplet, resp, err +} + +// CreateMultiple creates multiple Droplets. +func (s *DropletsServiceOp) CreateMultiple(ctx context.Context, createRequest *DropletMultiCreateRequest) ([]Droplet, *Response, error) { + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + path := dropletBasePath + + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(dropletsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Droplets, resp, err +} + +// Performs a delete request given a path +func (s *DropletsServiceOp) delete(ctx context.Context, path string) (*Response, error) { + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// Delete Droplet. +func (s *DropletsServiceOp) Delete(ctx context.Context, dropletID int) (*Response, error) { + if dropletID < 1 { + return nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID) + + return s.delete(ctx, path) +} + +// DeleteByTag deletes Droplets matched by a Tag. +func (s *DropletsServiceOp) DeleteByTag(ctx context.Context, tag string) (*Response, error) { + if tag == "" { + return nil, NewArgError("tag", "cannot be empty") + } + + path := fmt.Sprintf("%s?tag_name=%s", dropletBasePath, tag) + + return s.delete(ctx, path) +} + +// Kernels lists kernels available for a Droplet. +func (s *DropletsServiceOp) Kernels(ctx context.Context, dropletID int, opt *ListOptions) ([]Kernel, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d/kernels", dropletBasePath, dropletID) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(kernelsRoot) + resp, err := s.client.Do(req, root) + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Kernels, resp, err +} + +// Actions lists the actions for a Droplet. +func (s *DropletsServiceOp) Actions(ctx context.Context, dropletID int, opt *ListOptions) ([]Action, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d/actions", dropletBasePath, dropletID) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Actions, resp, err +} + +// Backups lists the backups for a Droplet. +func (s *DropletsServiceOp) Backups(ctx context.Context, dropletID int, opt *ListOptions) ([]Image, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d/backups", dropletBasePath, dropletID) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(backupsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Backups, resp, err +} + +// Snapshots lists the snapshots available for a Droplet. +func (s *DropletsServiceOp) Snapshots(ctx context.Context, dropletID int, opt *ListOptions) ([]Image, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d/snapshots", dropletBasePath, dropletID) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(dropletSnapshotsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Snapshots, resp, err +} + +// Neighbors lists the neighbors for a Droplet. +func (s *DropletsServiceOp) Neighbors(ctx context.Context, dropletID int) ([]Droplet, *Response, error) { + if dropletID < 1 { + return nil, nil, NewArgError("dropletID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d/neighbors", dropletBasePath, dropletID) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(dropletsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Droplets, resp, err +} + +func (s *DropletsServiceOp) dropletActionStatus(ctx context.Context, uri string) (string, error) { + action, _, err := s.client.DropletActions.GetByURI(ctx, uri) + + if err != nil { + return "", err + } + + return action.Status, nil +} diff --git a/vendor/github.com/digitalocean/godo/errors.go b/vendor/github.com/digitalocean/godo/errors.go new file mode 100644 index 0000000000..a65ebd76b6 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/errors.go @@ -0,0 +1,24 @@ +package godo + +import "fmt" + +// ArgError is an error that represents an error with an input to godo. It +// identifies the argument and the cause (if possible). +type ArgError struct { + arg string + reason string +} + +var _ error = &ArgError{} + +// NewArgError creates an InputError. +func NewArgError(arg, reason string) *ArgError { + return &ArgError{ + arg: arg, + reason: reason, + } +} + +func (e *ArgError) Error() string { + return fmt.Sprintf("%s is invalid because %s", e.arg, e.reason) +} diff --git a/vendor/github.com/digitalocean/godo/floating_ips.go b/vendor/github.com/digitalocean/godo/floating_ips.go new file mode 100644 index 0000000000..13e983261e --- /dev/null +++ b/vendor/github.com/digitalocean/godo/floating_ips.go @@ -0,0 +1,134 @@ +package godo + +import ( + "context" + "fmt" +) + +const floatingBasePath = "v2/floating_ips" + +// FloatingIPsService is an interface for interfacing with the floating IPs +// endpoints of the Digital Ocean API. +// See: https://developers.digitalocean.com/documentation/v2#floating-ips +type FloatingIPsService interface { + List(context.Context, *ListOptions) ([]FloatingIP, *Response, error) + Get(context.Context, string) (*FloatingIP, *Response, error) + Create(context.Context, *FloatingIPCreateRequest) (*FloatingIP, *Response, error) + Delete(context.Context, string) (*Response, error) +} + +// FloatingIPsServiceOp handles communication with the floating IPs related methods of the +// DigitalOcean API. +type FloatingIPsServiceOp struct { + client *Client +} + +var _ FloatingIPsService = &FloatingIPsServiceOp{} + +// FloatingIP represents a Digital Ocean floating IP. +type FloatingIP struct { + Region *Region `json:"region"` + Droplet *Droplet `json:"droplet"` + IP string `json:"ip"` +} + +func (f FloatingIP) String() string { + return Stringify(f) +} + +type floatingIPsRoot struct { + FloatingIPs []FloatingIP `json:"floating_ips"` + Links *Links `json:"links"` +} + +type floatingIPRoot struct { + FloatingIP *FloatingIP `json:"floating_ip"` + Links *Links `json:"links,omitempty"` +} + +// FloatingIPCreateRequest represents a request to create a floating IP. +// If DropletID is not empty, the floating IP will be assigned to the +// droplet. +type FloatingIPCreateRequest struct { + Region string `json:"region"` + DropletID int `json:"droplet_id,omitempty"` +} + +// List all floating IPs. +func (f *FloatingIPsServiceOp) List(ctx context.Context, opt *ListOptions) ([]FloatingIP, *Response, error) { + path := floatingBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := f.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(floatingIPsRoot) + resp, err := f.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.FloatingIPs, resp, err +} + +// Get an individual floating IP. +func (f *FloatingIPsServiceOp) Get(ctx context.Context, ip string) (*FloatingIP, *Response, error) { + path := fmt.Sprintf("%s/%s", floatingBasePath, ip) + + req, err := f.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(floatingIPRoot) + resp, err := f.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.FloatingIP, resp, err +} + +// Create a floating IP. If the DropletID field of the request is not empty, +// the floating IP will also be assigned to the droplet. +func (f *FloatingIPsServiceOp) Create(ctx context.Context, createRequest *FloatingIPCreateRequest) (*FloatingIP, *Response, error) { + path := floatingBasePath + + req, err := f.client.NewRequest(ctx, "POST", path, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(floatingIPRoot) + resp, err := f.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.FloatingIP, resp, err +} + +// Delete a floating IP. +func (f *FloatingIPsServiceOp) Delete(ctx context.Context, ip string) (*Response, error) { + path := fmt.Sprintf("%s/%s", floatingBasePath, ip) + + req, err := f.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := f.client.Do(req, nil) + + return resp, err +} diff --git a/vendor/github.com/digitalocean/godo/floating_ips_actions.go b/vendor/github.com/digitalocean/godo/floating_ips_actions.go new file mode 100644 index 0000000000..5afa051d74 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/floating_ips_actions.go @@ -0,0 +1,108 @@ +package godo + +import ( + "context" + "fmt" +) + +// FloatingIPActionsService is an interface for interfacing with the +// floating IPs actions endpoints of the Digital Ocean API. +// See: https://developers.digitalocean.com/documentation/v2#floating-ips-action +type FloatingIPActionsService interface { + Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) + Unassign(ctx context.Context, ip string) (*Action, *Response, error) + Get(ctx context.Context, ip string, actionID int) (*Action, *Response, error) + List(ctx context.Context, ip string, opt *ListOptions) ([]Action, *Response, error) +} + +// FloatingIPActionsServiceOp handles communication with the floating IPs +// action related methods of the DigitalOcean API. +type FloatingIPActionsServiceOp struct { + client *Client +} + +// Assign a floating IP to a droplet. +func (s *FloatingIPActionsServiceOp) Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) { + request := &ActionRequest{ + "type": "assign", + "droplet_id": dropletID, + } + return s.doAction(ctx, ip, request) +} + +// Unassign a floating IP from the droplet it is currently assigned to. +func (s *FloatingIPActionsServiceOp) Unassign(ctx context.Context, ip string) (*Action, *Response, error) { + request := &ActionRequest{"type": "unassign"} + return s.doAction(ctx, ip, request) +} + +// Get an action for a particular floating IP by id. +func (s *FloatingIPActionsServiceOp) Get(ctx context.Context, ip string, actionID int) (*Action, *Response, error) { + path := fmt.Sprintf("%s/%d", floatingIPActionPath(ip), actionID) + return s.get(ctx, path) +} + +// List the actions for a particular floating IP. +func (s *FloatingIPActionsServiceOp) List(ctx context.Context, ip string, opt *ListOptions) ([]Action, *Response, error) { + path := floatingIPActionPath(ip) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + return s.list(ctx, path) +} + +func (s *FloatingIPActionsServiceOp) doAction(ctx context.Context, ip string, request *ActionRequest) (*Action, *Response, error) { + path := floatingIPActionPath(ip) + + req, err := s.client.NewRequest(ctx, "POST", path, request) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func (s *FloatingIPActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func (s *FloatingIPActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Actions, resp, err +} + +func floatingIPActionPath(ip string) string { + return fmt.Sprintf("%s/%s/actions", floatingBasePath, ip) +} diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go new file mode 100644 index 0000000000..0f9d7a91b3 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/godo.go @@ -0,0 +1,398 @@ +package godo + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "strconv" + "time" + + "github.com/google/go-querystring/query" + headerLink "github.com/tent/http-link-go" +) + +const ( + libraryVersion = "1.0.0" + defaultBaseURL = "https://api.digitalocean.com/" + userAgent = "godo/" + libraryVersion + mediaType = "application/json" + + headerRateLimit = "RateLimit-Limit" + headerRateRemaining = "RateLimit-Remaining" + headerRateReset = "RateLimit-Reset" +) + +// Client manages communication with DigitalOcean V2 API. +type Client struct { + // HTTP client used to communicate with the DO API. + client *http.Client + + // Base URL for API requests. + BaseURL *url.URL + + // User agent for client + UserAgent string + + // Rate contains the current rate limit for the client as determined by the most recent + // API call. + Rate Rate + + // Services used for communicating with the API + Account AccountService + Actions ActionsService + Domains DomainsService + Droplets DropletsService + DropletActions DropletActionsService + Images ImagesService + ImageActions ImageActionsService + Keys KeysService + Regions RegionsService + Sizes SizesService + FloatingIPs FloatingIPsService + FloatingIPActions FloatingIPActionsService + Snapshots SnapshotsService + Storage StorageService + StorageActions StorageActionsService + Tags TagsService + LoadBalancers LoadBalancersService + Certificates CertificatesService + + // Optional function called after every successful request made to the DO APIs + onRequestCompleted RequestCompletionCallback +} + +// RequestCompletionCallback defines the type of the request callback function +type RequestCompletionCallback func(*http.Request, *http.Response) + +// ListOptions specifies the optional parameters to various List methods that +// support pagination. +type ListOptions struct { + // For paginated result sets, page of results to retrieve. + Page int `url:"page,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage int `url:"per_page,omitempty"` +} + +// Response is a DigitalOcean response. This wraps the standard http.Response returned from DigitalOcean. +type Response struct { + *http.Response + + // Links that were returned with the response. These are parsed from + // request body and not the header. + Links *Links + + // Monitoring URI + Monitor string + + Rate +} + +// An ErrorResponse reports the error caused by an API request +type ErrorResponse struct { + // HTTP response that caused this error + Response *http.Response + + // Error message + Message string `json:"message"` + + // RequestID returned from the API, useful to contact support. + RequestID string `json:"request_id"` +} + +// Rate contains the rate limit for the current client. +type Rate struct { + // The number of request per hour the client is currently limited to. + Limit int `json:"limit"` + + // The number of remaining requests the client can make this hour. + Remaining int `json:"remaining"` + + // The time at which the current rate limit will reset. + Reset Timestamp `json:"reset"` +} + +func addOptions(s string, opt interface{}) (string, error) { + v := reflect.ValueOf(opt) + + if v.Kind() == reflect.Ptr && v.IsNil() { + return s, nil + } + + origURL, err := url.Parse(s) + if err != nil { + return s, err + } + + origValues := origURL.Query() + + newValues, err := query.Values(opt) + if err != nil { + return s, err + } + + for k, v := range newValues { + origValues[k] = v + } + + origURL.RawQuery = origValues.Encode() + return origURL.String(), nil +} + +// NewClient returns a new DigitalOcean API client. +func NewClient(httpClient *http.Client) *Client { + if httpClient == nil { + httpClient = http.DefaultClient + } + + baseURL, _ := url.Parse(defaultBaseURL) + + c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent} + c.Account = &AccountServiceOp{client: c} + c.Actions = &ActionsServiceOp{client: c} + c.Domains = &DomainsServiceOp{client: c} + c.Droplets = &DropletsServiceOp{client: c} + c.DropletActions = &DropletActionsServiceOp{client: c} + c.FloatingIPs = &FloatingIPsServiceOp{client: c} + c.FloatingIPActions = &FloatingIPActionsServiceOp{client: c} + c.Images = &ImagesServiceOp{client: c} + c.ImageActions = &ImageActionsServiceOp{client: c} + c.Keys = &KeysServiceOp{client: c} + c.Regions = &RegionsServiceOp{client: c} + c.Snapshots = &SnapshotsServiceOp{client: c} + c.Sizes = &SizesServiceOp{client: c} + c.Storage = &StorageServiceOp{client: c} + c.StorageActions = &StorageActionsServiceOp{client: c} + c.Tags = &TagsServiceOp{client: c} + c.LoadBalancers = &LoadBalancersServiceOp{client: c} + c.Certificates = &CertificatesServiceOp{client: c} + + return c +} + +// ClientOpt are options for New. +type ClientOpt func(*Client) error + +// New returns a new DIgitalOcean API client instance. +func New(httpClient *http.Client, opts ...ClientOpt) (*Client, error) { + c := NewClient(httpClient) + for _, opt := range opts { + if err := opt(c); err != nil { + return nil, err + } + } + + return c, nil +} + +// SetBaseURL is a client option for setting the base URL. +func SetBaseURL(bu string) ClientOpt { + return func(c *Client) error { + u, err := url.Parse(bu) + if err != nil { + return err + } + + c.BaseURL = u + return nil + } +} + +// SetUserAgent is a client option for setting the user agent. +func SetUserAgent(ua string) ClientOpt { + return func(c *Client) error { + c.UserAgent = fmt.Sprintf("%s+%s", ua, c.UserAgent) + return nil + } +} + +// NewRequest creates an API request. A relative URL can be provided in urlStr, which will be resolved to the +// BaseURL of the Client. Relative URLS should always be specified without a preceding slash. If specified, the +// value pointed to by body is JSON encoded and included in as the request body. +func (c *Client) NewRequest(ctx context.Context, method, urlStr string, body interface{}) (*http.Request, error) { + rel, err := url.Parse(urlStr) + if err != nil { + return nil, err + } + + u := c.BaseURL.ResolveReference(rel) + + buf := new(bytes.Buffer) + if body != nil { + err = json.NewEncoder(buf).Encode(body) + if err != nil { + return nil, err + } + } + + req, err := http.NewRequest(method, u.String(), buf) + if err != nil { + return nil, err + } + + req = req.WithContext(ctx) + req.Header.Add("Content-Type", mediaType) + req.Header.Add("Accept", mediaType) + req.Header.Add("User-Agent", c.UserAgent) + return req, nil +} + +// OnRequestCompleted sets the DO API request completion callback +func (c *Client) OnRequestCompleted(rc RequestCompletionCallback) { + c.onRequestCompleted = rc +} + +// newResponse creates a new Response for the provided http.Response +func newResponse(r *http.Response) *Response { + response := Response{Response: r} + response.populateRate() + + return &response +} + +func (r *Response) links() (map[string]headerLink.Link, error) { + if linkText, ok := r.Response.Header["Link"]; ok { + links, err := headerLink.Parse(linkText[0]) + + if err != nil { + return nil, err + } + + linkMap := map[string]headerLink.Link{} + for _, link := range links { + linkMap[link.Rel] = link + } + + return linkMap, nil + } + + return map[string]headerLink.Link{}, nil +} + +// populateRate parses the rate related headers and populates the response Rate. +func (r *Response) populateRate() { + if limit := r.Header.Get(headerRateLimit); limit != "" { + r.Rate.Limit, _ = strconv.Atoi(limit) + } + if remaining := r.Header.Get(headerRateRemaining); remaining != "" { + r.Rate.Remaining, _ = strconv.Atoi(remaining) + } + if reset := r.Header.Get(headerRateReset); reset != "" { + if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 { + r.Rate.Reset = Timestamp{time.Unix(v, 0)} + } + } +} + +// Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value +// pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface, +// the raw response will be written to v, without attempting to decode it. +func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { + resp, err := c.client.Do(req) + if err != nil { + return nil, err + } + if c.onRequestCompleted != nil { + c.onRequestCompleted(req, resp) + } + + defer func() { + if rerr := resp.Body.Close(); err == nil { + err = rerr + } + }() + + response := newResponse(resp) + c.Rate = response.Rate + + err = CheckResponse(resp) + if err != nil { + return response, err + } + + if v != nil { + if w, ok := v.(io.Writer); ok { + _, err = io.Copy(w, resp.Body) + if err != nil { + return nil, err + } + } else { + err = json.NewDecoder(resp.Body).Decode(v) + if err != nil { + return nil, err + } + } + } + + return response, err +} +func (r *ErrorResponse) Error() string { + if r.RequestID != "" { + return fmt.Sprintf("%v %v: %d (request %q) %v", + r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.RequestID, r.Message) + } + return fmt.Sprintf("%v %v: %d %v", + r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message) +} + +// CheckResponse checks the API response for errors, and returns them if present. A response is considered an +// error if it has a status code outside the 200 range. API error responses are expected to have either no response +// body, or a JSON response body that maps to ErrorResponse. Any other response body will be silently ignored. +func CheckResponse(r *http.Response) error { + if c := r.StatusCode; c >= 200 && c <= 299 { + return nil + } + + errorResponse := &ErrorResponse{Response: r} + data, err := ioutil.ReadAll(r.Body) + if err == nil && len(data) > 0 { + err := json.Unmarshal(data, errorResponse) + if err != nil { + return err + } + } + + return errorResponse +} + +func (r Rate) String() string { + return Stringify(r) +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + p := new(string) + *p = v + return p +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int { + p := new(int) + *p = v + return p +} + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + p := new(bool) + *p = v + return p +} + +// StreamToString converts a reader to a string +func StreamToString(stream io.Reader) string { + buf := new(bytes.Buffer) + _, _ = buf.ReadFrom(stream) + return buf.String() +} diff --git a/vendor/github.com/digitalocean/godo/image_actions.go b/vendor/github.com/digitalocean/godo/image_actions.go new file mode 100644 index 0000000000..c4201c0deb --- /dev/null +++ b/vendor/github.com/digitalocean/godo/image_actions.go @@ -0,0 +1,101 @@ +package godo + +import ( + "context" + "fmt" +) + +// ImageActionsService is an interface for interfacing with the image actions +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#image-actions +type ImageActionsService interface { + Get(context.Context, int, int) (*Action, *Response, error) + Transfer(context.Context, int, *ActionRequest) (*Action, *Response, error) + Convert(context.Context, int) (*Action, *Response, error) +} + +// ImageActionsServiceOp handles communition with the image action related methods of the +// DigitalOcean API. +type ImageActionsServiceOp struct { + client *Client +} + +var _ ImageActionsService = &ImageActionsServiceOp{} + +// Transfer an image +func (i *ImageActionsServiceOp) Transfer(ctx context.Context, imageID int, transferRequest *ActionRequest) (*Action, *Response, error) { + if imageID < 1 { + return nil, nil, NewArgError("imageID", "cannot be less than 1") + } + + if transferRequest == nil { + return nil, nil, NewArgError("transferRequest", "cannot be nil") + } + + path := fmt.Sprintf("v2/images/%d/actions", imageID) + + req, err := i.client.NewRequest(ctx, "POST", path, transferRequest) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := i.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +// Convert an image to a snapshot +func (i *ImageActionsServiceOp) Convert(ctx context.Context, imageID int) (*Action, *Response, error) { + if imageID < 1 { + return nil, nil, NewArgError("imageID", "cannont be less than 1") + } + + path := fmt.Sprintf("v2/images/%d/actions", imageID) + + convertRequest := &ActionRequest{ + "type": "convert", + } + + req, err := i.client.NewRequest(ctx, "POST", path, convertRequest) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := i.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +// Get an action for a particular image by id. +func (i *ImageActionsServiceOp) Get(ctx context.Context, imageID, actionID int) (*Action, *Response, error) { + if imageID < 1 { + return nil, nil, NewArgError("imageID", "cannot be less than 1") + } + + if actionID < 1 { + return nil, nil, NewArgError("actionID", "cannot be less than 1") + } + + path := fmt.Sprintf("v2/images/%d/actions/%d", imageID, actionID) + + req, err := i.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := i.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/images.go b/vendor/github.com/digitalocean/godo/images.go new file mode 100644 index 0000000000..c808af6ec0 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/images.go @@ -0,0 +1,197 @@ +package godo + +import ( + "context" + "fmt" +) + +const imageBasePath = "v2/images" + +// ImagesService is an interface for interfacing with the images +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#images +type ImagesService interface { + List(context.Context, *ListOptions) ([]Image, *Response, error) + ListDistribution(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) + ListApplication(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) + ListUser(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) + GetByID(context.Context, int) (*Image, *Response, error) + GetBySlug(context.Context, string) (*Image, *Response, error) + Update(context.Context, int, *ImageUpdateRequest) (*Image, *Response, error) + Delete(context.Context, int) (*Response, error) +} + +// ImagesServiceOp handles communication with the image related methods of the +// DigitalOcean API. +type ImagesServiceOp struct { + client *Client +} + +var _ ImagesService = &ImagesServiceOp{} + +// Image represents a DigitalOcean Image +type Image struct { + ID int `json:"id,float64,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Distribution string `json:"distribution,omitempty"` + Slug string `json:"slug,omitempty"` + Public bool `json:"public,omitempty"` + Regions []string `json:"regions,omitempty"` + MinDiskSize int `json:"min_disk_size,omitempty"` + Created string `json:"created_at,omitempty"` +} + +// ImageUpdateRequest represents a request to update an image. +type ImageUpdateRequest struct { + Name string `json:"name"` +} + +type imageRoot struct { + Image *Image +} + +type imagesRoot struct { + Images []Image + Links *Links `json:"links"` +} + +type listImageOptions struct { + Private bool `url:"private,omitempty"` + Type string `url:"type,omitempty"` +} + +func (i Image) String() string { + return Stringify(i) +} + +// List lists all the images available. +func (s *ImagesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { + return s.list(ctx, opt, nil) +} + +// ListDistribution lists all the distribution images. +func (s *ImagesServiceOp) ListDistribution(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { + listOpt := listImageOptions{Type: "distribution"} + return s.list(ctx, opt, &listOpt) +} + +// ListApplication lists all the application images. +func (s *ImagesServiceOp) ListApplication(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { + listOpt := listImageOptions{Type: "application"} + return s.list(ctx, opt, &listOpt) +} + +// ListUser lists all the user images. +func (s *ImagesServiceOp) ListUser(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { + listOpt := listImageOptions{Private: true} + return s.list(ctx, opt, &listOpt) +} + +// GetByID retrieves an image by id. +func (s *ImagesServiceOp) GetByID(ctx context.Context, imageID int) (*Image, *Response, error) { + if imageID < 1 { + return nil, nil, NewArgError("imageID", "cannot be less than 1") + } + + return s.get(ctx, interface{}(imageID)) +} + +// GetBySlug retrieves an image by slug. +func (s *ImagesServiceOp) GetBySlug(ctx context.Context, slug string) (*Image, *Response, error) { + if len(slug) < 1 { + return nil, nil, NewArgError("slug", "cannot be blank") + } + + return s.get(ctx, interface{}(slug)) +} + +// Update an image name. +func (s *ImagesServiceOp) Update(ctx context.Context, imageID int, updateRequest *ImageUpdateRequest) (*Image, *Response, error) { + if imageID < 1 { + return nil, nil, NewArgError("imageID", "cannot be less than 1") + } + + if updateRequest == nil { + return nil, nil, NewArgError("updateRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%d", imageBasePath, imageID) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) + if err != nil { + return nil, nil, err + } + + root := new(imageRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Image, resp, err +} + +// Delete an image. +func (s *ImagesServiceOp) Delete(ctx context.Context, imageID int) (*Response, error) { + if imageID < 1 { + return nil, NewArgError("imageID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", imageBasePath, imageID) + + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// Helper method for getting an individual image +func (s *ImagesServiceOp) get(ctx context.Context, ID interface{}) (*Image, *Response, error) { + path := fmt.Sprintf("%s/%v", imageBasePath, ID) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(imageRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Image, resp, err +} + +// Helper method for listing images +func (s *ImagesServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listImageOptions) ([]Image, *Response, error) { + path := imageBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + path, err = addOptions(path, listOpt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(imagesRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Images, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/keys.go b/vendor/github.com/digitalocean/godo/keys.go new file mode 100644 index 0000000000..7b336c4ce6 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/keys.go @@ -0,0 +1,225 @@ +package godo + +import ( + "context" + "fmt" +) + +const keysBasePath = "v2/account/keys" + +// KeysService is an interface for interfacing with the keys +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#keys +type KeysService interface { + List(context.Context, *ListOptions) ([]Key, *Response, error) + GetByID(context.Context, int) (*Key, *Response, error) + GetByFingerprint(context.Context, string) (*Key, *Response, error) + Create(context.Context, *KeyCreateRequest) (*Key, *Response, error) + UpdateByID(context.Context, int, *KeyUpdateRequest) (*Key, *Response, error) + UpdateByFingerprint(context.Context, string, *KeyUpdateRequest) (*Key, *Response, error) + DeleteByID(context.Context, int) (*Response, error) + DeleteByFingerprint(context.Context, string) (*Response, error) +} + +// KeysServiceOp handles communication with key related method of the +// DigitalOcean API. +type KeysServiceOp struct { + client *Client +} + +var _ KeysService = &KeysServiceOp{} + +// Key represents a DigitalOcean Key. +type Key struct { + ID int `json:"id,float64,omitempty"` + Name string `json:"name,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` + PublicKey string `json:"public_key,omitempty"` +} + +// KeyUpdateRequest represents a request to update a DigitalOcean key. +type KeyUpdateRequest struct { + Name string `json:"name"` +} + +type keysRoot struct { + SSHKeys []Key `json:"ssh_keys"` + Links *Links `json:"links"` +} + +type keyRoot struct { + SSHKey *Key `json:"ssh_key"` +} + +func (s Key) String() string { + return Stringify(s) +} + +// KeyCreateRequest represents a request to create a new key. +type KeyCreateRequest struct { + Name string `json:"name"` + PublicKey string `json:"public_key"` +} + +// List all keys +func (s *KeysServiceOp) List(ctx context.Context, opt *ListOptions) ([]Key, *Response, error) { + path := keysBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(keysRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.SSHKeys, resp, err +} + +// Performs a get given a path +func (s *KeysServiceOp) get(ctx context.Context, path string) (*Key, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(keyRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.SSHKey, resp, err +} + +// GetByID gets a Key by id +func (s *KeysServiceOp) GetByID(ctx context.Context, keyID int) (*Key, *Response, error) { + if keyID < 1 { + return nil, nil, NewArgError("keyID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", keysBasePath, keyID) + return s.get(ctx, path) +} + +// GetByFingerprint gets a Key by by fingerprint +func (s *KeysServiceOp) GetByFingerprint(ctx context.Context, fingerprint string) (*Key, *Response, error) { + if len(fingerprint) < 1 { + return nil, nil, NewArgError("fingerprint", "cannot not be empty") + } + + path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) + return s.get(ctx, path) +} + +// Create a key using a KeyCreateRequest +func (s *KeysServiceOp) Create(ctx context.Context, createRequest *KeyCreateRequest) (*Key, *Response, error) { + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + req, err := s.client.NewRequest(ctx, "POST", keysBasePath, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(keyRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.SSHKey, resp, err +} + +// UpdateByID updates a key name by ID. +func (s *KeysServiceOp) UpdateByID(ctx context.Context, keyID int, updateRequest *KeyUpdateRequest) (*Key, *Response, error) { + if keyID < 1 { + return nil, nil, NewArgError("keyID", "cannot be less than 1") + } + + if updateRequest == nil { + return nil, nil, NewArgError("updateRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%d", keysBasePath, keyID) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) + if err != nil { + return nil, nil, err + } + + root := new(keyRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.SSHKey, resp, err +} + +// UpdateByFingerprint updates a key name by fingerprint. +func (s *KeysServiceOp) UpdateByFingerprint(ctx context.Context, fingerprint string, updateRequest *KeyUpdateRequest) (*Key, *Response, error) { + if len(fingerprint) < 1 { + return nil, nil, NewArgError("fingerprint", "cannot be empty") + } + + if updateRequest == nil { + return nil, nil, NewArgError("updateRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) + if err != nil { + return nil, nil, err + } + + root := new(keyRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.SSHKey, resp, err +} + +// Delete key using a path +func (s *KeysServiceOp) delete(ctx context.Context, path string) (*Response, error) { + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// DeleteByID deletes a key by its id +func (s *KeysServiceOp) DeleteByID(ctx context.Context, keyID int) (*Response, error) { + if keyID < 1 { + return nil, NewArgError("keyID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s/%d", keysBasePath, keyID) + return s.delete(ctx, path) +} + +// DeleteByFingerprint deletes a key by its fingerprint +func (s *KeysServiceOp) DeleteByFingerprint(ctx context.Context, fingerprint string) (*Response, error) { + if len(fingerprint) < 1 { + return nil, NewArgError("fingerprint", "cannot be empty") + } + + path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) + return s.delete(ctx, path) +} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/links.go b/vendor/github.com/digitalocean/godo/links.go similarity index 88% rename from Godeps/_workspace/src/github.com/digitalocean/godo/links.go rename to vendor/github.com/digitalocean/godo/links.go index 64db34cb70..2098441729 100644 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/links.go +++ b/vendor/github.com/digitalocean/godo/links.go @@ -1,6 +1,7 @@ package godo import ( + "context" "net/url" "strconv" ) @@ -58,11 +59,7 @@ func (l *Links) IsLastPage() bool { } func (p *Pages) isLast() bool { - if p.Last == "" { - return true - } - - return false + return p.Last == "" } func pageForURL(urlText string) (int, error) { @@ -80,6 +77,7 @@ func pageForURL(urlText string) (int, error) { return page, nil } -func (la *LinkAction) Get(client *Client) (*Action, *Response, error) { - return client.Actions.Get(la.ID) +// Get a link action by id. +func (la *LinkAction) Get(ctx context.Context, client *Client) (*Action, *Response, error) { + return client.Actions.Get(ctx, la.ID) } diff --git a/vendor/github.com/digitalocean/godo/load_balancers.go b/vendor/github.com/digitalocean/godo/load_balancers.go new file mode 100644 index 0000000000..48b9c26541 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/load_balancers.go @@ -0,0 +1,275 @@ +package godo + +import ( + "context" + "fmt" +) + +const loadBalancersBasePath = "/v2/load_balancers" +const forwardingRulesPath = "forwarding_rules" +const dropletsPath = "droplets" + +// LoadBalancersService is an interface for managing load balancers with the DigitalOcean API. +// See: https://developers.digitalocean.com/documentation/v2#load-balancers +type LoadBalancersService interface { + Get(context.Context, string) (*LoadBalancer, *Response, error) + List(context.Context, *ListOptions) ([]LoadBalancer, *Response, error) + Create(context.Context, *LoadBalancerRequest) (*LoadBalancer, *Response, error) + Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) + Delete(ctx context.Context, lbID string) (*Response, error) + AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) + RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) + AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) + RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) +} + +// LoadBalancer represents a DigitalOcean load balancer configuration. +type LoadBalancer struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + IP string `json:"ip,omitempty"` + Algorithm string `json:"algorithm,omitempty"` + Status string `json:"status,omitempty"` + Created string `json:"created_at,omitempty"` + ForwardingRules []ForwardingRule `json:"forwarding_rules,omitempty"` + HealthCheck *HealthCheck `json:"health_check,omitempty"` + StickySessions *StickySessions `json:"sticky_sessions,omitempty"` + Region *Region `json:"region,omitempty"` + DropletIDs []int `json:"droplet_ids,omitempty"` + Tag string `json:"tag,omitempty"` + RedirectHttpToHttps bool `json:"redirect_http_to_https,omitempty"` +} + +// String creates a human-readable description of a LoadBalancer. +func (l LoadBalancer) String() string { + return Stringify(l) +} + +// ForwardingRule represents load balancer forwarding rules. +type ForwardingRule struct { + EntryProtocol string `json:"entry_protocol,omitempty"` + EntryPort int `json:"entry_port,omitempty"` + TargetProtocol string `json:"target_protocol,omitempty"` + TargetPort int `json:"target_port,omitempty"` + CertificateID string `json:"certificate_id,omitempty"` + TlsPassthrough bool `json:"tls_passthrough,omitempty"` +} + +// String creates a human-readable description of a ForwardingRule. +func (f ForwardingRule) String() string { + return Stringify(f) +} + +// HealthCheck represents optional load balancer health check rules. +type HealthCheck struct { + Protocol string `json:"protocol,omitempty"` + Port int `json:"port,omitempty"` + Path string `json:"path,omitempty"` + CheckIntervalSeconds int `json:"check_interval_seconds,omitempty"` + ResponseTimeoutSeconds int `json:"response_timeout_seconds,omitempty"` + HealthyThreshold int `json:"healthy_threshold,omitempty"` + UnhealthyThreshold int `json:"unhealthy_threshold,omitempty"` +} + +// String creates a human-readable description of a HealthCheck. +func (h HealthCheck) String() string { + return Stringify(h) +} + +// StickySessions represents optional load balancer session affinity rules. +type StickySessions struct { + Type string `json:"type,omitempty"` + CookieName string `json:"cookie_name,omitempty"` + CookieTtlSeconds int `json:"cookie_ttl_seconds,omitempty"` +} + +// String creates a human-readable description of a StickySessions instance. +func (s StickySessions) String() string { + return Stringify(s) +} + +// LoadBalancerRequest represents the configuration to be applied to an existing or a new load balancer. +type LoadBalancerRequest struct { + Name string `json:"name,omitempty"` + Algorithm string `json:"algorithm,omitempty"` + Region string `json:"region,omitempty"` + ForwardingRules []ForwardingRule `json:"forwarding_rules,omitempty"` + HealthCheck *HealthCheck `json:"health_check,omitempty"` + StickySessions *StickySessions `json:"sticky_sessions,omitempty"` + DropletIDs []int `json:"droplet_ids,omitempty"` + Tag string `json:"tag,omitempty"` + RedirectHttpToHttps bool `json:"redirect_http_to_https,omitempty"` +} + +// String creates a human-readable description of a LoadBalancerRequest. +func (l LoadBalancerRequest) String() string { + return Stringify(l) +} + +type forwardingRulesRequest struct { + Rules []ForwardingRule `json:"forwarding_rules,omitempty"` +} + +func (l forwardingRulesRequest) String() string { + return Stringify(l) +} + +type dropletIDsRequest struct { + IDs []int `json:"droplet_ids,omitempty"` +} + +func (l dropletIDsRequest) String() string { + return Stringify(l) +} + +type loadBalancersRoot struct { + LoadBalancers []LoadBalancer `json:"load_balancers"` + Links *Links `json:"links"` +} + +type loadBalancerRoot struct { + LoadBalancer *LoadBalancer `json:"load_balancer"` +} + +// LoadBalancersServiceOp handles communication with load balancer-related methods of the DigitalOcean API. +type LoadBalancersServiceOp struct { + client *Client +} + +var _ LoadBalancersService = &LoadBalancersServiceOp{} + +// Get an existing load balancer by its identifier. +func (l *LoadBalancersServiceOp) Get(ctx context.Context, lbID string) (*LoadBalancer, *Response, error) { + path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID) + + req, err := l.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(loadBalancerRoot) + resp, err := l.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.LoadBalancer, resp, err +} + +// List load balancers, with optional pagination. +func (l *LoadBalancersServiceOp) List(ctx context.Context, opt *ListOptions) ([]LoadBalancer, *Response, error) { + path, err := addOptions(loadBalancersBasePath, opt) + if err != nil { + return nil, nil, err + } + + req, err := l.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(loadBalancersRoot) + resp, err := l.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.LoadBalancers, resp, err +} + +// Create a new load balancer with a given configuration. +func (l *LoadBalancersServiceOp) Create(ctx context.Context, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) { + req, err := l.client.NewRequest(ctx, "POST", loadBalancersBasePath, lbr) + if err != nil { + return nil, nil, err + } + + root := new(loadBalancerRoot) + resp, err := l.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.LoadBalancer, resp, err +} + +// Update an existing load balancer with new configuration. +func (l *LoadBalancersServiceOp) Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) { + path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID) + + req, err := l.client.NewRequest(ctx, "PUT", path, lbr) + if err != nil { + return nil, nil, err + } + + root := new(loadBalancerRoot) + resp, err := l.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.LoadBalancer, resp, err +} + +// Delete a load balancer by its identifier. +func (l *LoadBalancersServiceOp) Delete(ctx context.Context, ldID string) (*Response, error) { + path := fmt.Sprintf("%s/%s", loadBalancersBasePath, ldID) + + req, err := l.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + return l.client.Do(req, nil) +} + +// AddDroplets adds droplets to a load balancer. +func (l *LoadBalancersServiceOp) AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) { + path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath) + + req, err := l.client.NewRequest(ctx, "POST", path, &dropletIDsRequest{IDs: dropletIDs}) + if err != nil { + return nil, err + } + + return l.client.Do(req, nil) +} + +// RemoveDroplets removes droplets from a load balancer. +func (l *LoadBalancersServiceOp) RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) { + path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath) + + req, err := l.client.NewRequest(ctx, "DELETE", path, &dropletIDsRequest{IDs: dropletIDs}) + if err != nil { + return nil, err + } + + return l.client.Do(req, nil) +} + +// AddForwardingRules adds forwarding rules to a load balancer. +func (l *LoadBalancersServiceOp) AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) { + path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath) + + req, err := l.client.NewRequest(ctx, "POST", path, &forwardingRulesRequest{Rules: rules}) + if err != nil { + return nil, err + } + + return l.client.Do(req, nil) +} + +// RemoveForwardingRules removes forwarding rules from a load balancer. +func (l *LoadBalancersServiceOp) RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) { + path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath) + + req, err := l.client.NewRequest(ctx, "DELETE", path, &forwardingRulesRequest{Rules: rules}) + if err != nil { + return nil, err + } + + return l.client.Do(req, nil) +} diff --git a/vendor/github.com/digitalocean/godo/regions.go b/vendor/github.com/digitalocean/godo/regions.go new file mode 100644 index 0000000000..ccfe02926e --- /dev/null +++ b/vendor/github.com/digitalocean/godo/regions.go @@ -0,0 +1,61 @@ +package godo + +import "context" + +// RegionsService is an interface for interfacing with the regions +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#regions +type RegionsService interface { + List(context.Context, *ListOptions) ([]Region, *Response, error) +} + +// RegionsServiceOp handles communication with the region related methods of the +// DigitalOcean API. +type RegionsServiceOp struct { + client *Client +} + +var _ RegionsService = &RegionsServiceOp{} + +// Region represents a DigitalOcean Region +type Region struct { + Slug string `json:"slug,omitempty"` + Name string `json:"name,omitempty"` + Sizes []string `json:"sizes,omitempty"` + Available bool `json:"available,omitempty"` + Features []string `json:"features,omitempty"` +} + +type regionsRoot struct { + Regions []Region + Links *Links `json:"links"` +} + +func (r Region) String() string { + return Stringify(r) +} + +// List all regions +func (s *RegionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Region, *Response, error) { + path := "v2/regions" + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(regionsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Regions, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/sizes.go b/vendor/github.com/digitalocean/godo/sizes.go new file mode 100644 index 0000000000..b695792787 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/sizes.go @@ -0,0 +1,65 @@ +package godo + +import "context" + +// SizesService is an interface for interfacing with the size +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#sizes +type SizesService interface { + List(context.Context, *ListOptions) ([]Size, *Response, error) +} + +// SizesServiceOp handles communication with the size related methods of the +// DigitalOcean API. +type SizesServiceOp struct { + client *Client +} + +var _ SizesService = &SizesServiceOp{} + +// Size represents a DigitalOcean Size +type Size struct { + Slug string `json:"slug,omitempty"` + Memory int `json:"memory,omitempty"` + Vcpus int `json:"vcpus,omitempty"` + Disk int `json:"disk,omitempty"` + PriceMonthly float64 `json:"price_monthly,omitempty"` + PriceHourly float64 `json:"price_hourly,omitempty"` + Regions []string `json:"regions,omitempty"` + Available bool `json:"available,omitempty"` + Transfer float64 `json:"transfer,omitempty"` +} + +func (s Size) String() string { + return Stringify(s) +} + +type sizesRoot struct { + Sizes []Size + Links *Links `json:"links"` +} + +// List all images +func (s *SizesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Size, *Response, error) { + path := "v2/sizes" + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(sizesRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Sizes, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/snapshots.go b/vendor/github.com/digitalocean/godo/snapshots.go new file mode 100644 index 0000000000..5a9e5c5d80 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/snapshots.go @@ -0,0 +1,139 @@ +package godo + +import ( + "context" + "fmt" +) + +const snapshotBasePath = "v2/snapshots" + +// SnapshotsService is an interface for interfacing with the snapshots +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#snapshots +type SnapshotsService interface { + List(context.Context, *ListOptions) ([]Snapshot, *Response, error) + ListVolume(context.Context, *ListOptions) ([]Snapshot, *Response, error) + ListDroplet(context.Context, *ListOptions) ([]Snapshot, *Response, error) + Get(context.Context, string) (*Snapshot, *Response, error) + Delete(context.Context, string) (*Response, error) +} + +// SnapshotsServiceOp handles communication with the snapshot related methods of the +// DigitalOcean API. +type SnapshotsServiceOp struct { + client *Client +} + +var _ SnapshotsService = &SnapshotsServiceOp{} + +// Snapshot represents a DigitalOcean Snapshot +type Snapshot struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + ResourceID string `json:"resource_id,omitempty"` + ResourceType string `json:"resource_type,omitempty"` + Regions []string `json:"regions,omitempty"` + MinDiskSize int `json:"min_disk_size,omitempty"` + SizeGigaBytes float64 `json:"size_gigabytes,omitempty"` + Created string `json:"created_at,omitempty"` +} + +type snapshotRoot struct { + Snapshot *Snapshot `json:"snapshot"` +} + +type snapshotsRoot struct { + Snapshots []Snapshot `json:"snapshots"` + Links *Links `json:"links,omitempty"` +} + +type listSnapshotOptions struct { + ResourceType string `url:"resource_type,omitempty"` +} + +func (s Snapshot) String() string { + return Stringify(s) +} + +// List lists all the snapshots available. +func (s *SnapshotsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { + return s.list(ctx, opt, nil) +} + +// ListDroplet lists all the Droplet snapshots. +func (s *SnapshotsServiceOp) ListDroplet(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { + listOpt := listSnapshotOptions{ResourceType: "droplet"} + return s.list(ctx, opt, &listOpt) +} + +// ListVolume lists all the volume snapshots. +func (s *SnapshotsServiceOp) ListVolume(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { + listOpt := listSnapshotOptions{ResourceType: "volume"} + return s.list(ctx, opt, &listOpt) +} + +// Get retrieves an snapshot by id. +func (s *SnapshotsServiceOp) Get(ctx context.Context, snapshotID string) (*Snapshot, *Response, error) { + return s.get(ctx, snapshotID) +} + +// Delete an snapshot. +func (s *SnapshotsServiceOp) Delete(ctx context.Context, snapshotID string) (*Response, error) { + path := fmt.Sprintf("%s/%s", snapshotBasePath, snapshotID) + + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// Helper method for getting an individual snapshot +func (s *SnapshotsServiceOp) get(ctx context.Context, ID string) (*Snapshot, *Response, error) { + path := fmt.Sprintf("%s/%s", snapshotBasePath, ID) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(snapshotRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Snapshot, resp, err +} + +// Helper method for listing snapshots +func (s *SnapshotsServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listSnapshotOptions) ([]Snapshot, *Response, error) { + path := snapshotBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + path, err = addOptions(path, listOpt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(snapshotsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Snapshots, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/storage.go b/vendor/github.com/digitalocean/godo/storage.go new file mode 100644 index 0000000000..00d5157d69 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/storage.go @@ -0,0 +1,238 @@ +package godo + +import ( + "context" + "fmt" + "time" +) + +const ( + storageBasePath = "v2" + storageAllocPath = storageBasePath + "/volumes" + storageSnapPath = storageBasePath + "/snapshots" +) + +// StorageService is an interface for interfacing with the storage +// endpoints of the Digital Ocean API. +// See: https://developers.digitalocean.com/documentation/v2#storage +type StorageService interface { + ListVolumes(context.Context, *ListVolumeParams) ([]Volume, *Response, error) + GetVolume(context.Context, string) (*Volume, *Response, error) + CreateVolume(context.Context, *VolumeCreateRequest) (*Volume, *Response, error) + DeleteVolume(context.Context, string) (*Response, error) + ListSnapshots(ctx context.Context, volumeID string, opts *ListOptions) ([]Snapshot, *Response, error) + GetSnapshot(context.Context, string) (*Snapshot, *Response, error) + CreateSnapshot(context.Context, *SnapshotCreateRequest) (*Snapshot, *Response, error) + DeleteSnapshot(context.Context, string) (*Response, error) +} + +// StorageServiceOp handles communication with the storage volumes related methods of the +// DigitalOcean API. +type StorageServiceOp struct { + client *Client +} + +// ListVolumeParams stores the options you can set for a ListVolumeCall +type ListVolumeParams struct { + Region string `json:"region"` + Name string `json:"name"` + ListOptions *ListOptions `json:"list_options,omitempty"` +} + +var _ StorageService = &StorageServiceOp{} + +// Volume represents a Digital Ocean block store volume. +type Volume struct { + ID string `json:"id"` + Region *Region `json:"region"` + Name string `json:"name"` + SizeGigaBytes int64 `json:"size_gigabytes"` + Description string `json:"description"` + DropletIDs []int `json:"droplet_ids"` + CreatedAt time.Time `json:"created_at"` +} + +func (f Volume) String() string { + return Stringify(f) +} + +type storageVolumesRoot struct { + Volumes []Volume `json:"volumes"` + Links *Links `json:"links"` +} + +type storageVolumeRoot struct { + Volume *Volume `json:"volume"` + Links *Links `json:"links,omitempty"` +} + +// VolumeCreateRequest represents a request to create a block store +// volume. +type VolumeCreateRequest struct { + Region string `json:"region"` + Name string `json:"name"` + Description string `json:"description"` + SizeGigaBytes int64 `json:"size_gigabytes"` + SnapshotID string `json:"snapshot_id"` +} + +// ListVolumes lists all storage volumes. +func (svc *StorageServiceOp) ListVolumes(ctx context.Context, params *ListVolumeParams) ([]Volume, *Response, error) { + path := storageAllocPath + if params != nil { + if params.Region != "" && params.Name != "" { + path = fmt.Sprintf("%s?name=%s®ion=%s", path, params.Name, params.Region) + } + + if params.ListOptions != nil { + var err error + path, err = addOptions(path, params.ListOptions) + if err != nil { + return nil, nil, err + } + } + } + + req, err := svc.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(storageVolumesRoot) + resp, err := svc.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Volumes, resp, nil +} + +// CreateVolume creates a storage volume. The name must be unique. +func (svc *StorageServiceOp) CreateVolume(ctx context.Context, createRequest *VolumeCreateRequest) (*Volume, *Response, error) { + path := storageAllocPath + + req, err := svc.client.NewRequest(ctx, "POST", path, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(storageVolumeRoot) + resp, err := svc.client.Do(req, root) + if err != nil { + return nil, resp, err + } + return root.Volume, resp, nil +} + +// GetVolume retrieves an individual storage volume. +func (svc *StorageServiceOp) GetVolume(ctx context.Context, id string) (*Volume, *Response, error) { + path := fmt.Sprintf("%s/%s", storageAllocPath, id) + + req, err := svc.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(storageVolumeRoot) + resp, err := svc.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Volume, resp, nil +} + +// DeleteVolume deletes a storage volume. +func (svc *StorageServiceOp) DeleteVolume(ctx context.Context, id string) (*Response, error) { + path := fmt.Sprintf("%s/%s", storageAllocPath, id) + + req, err := svc.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + return svc.client.Do(req, nil) +} + +// SnapshotCreateRequest represents a request to create a block store +// volume. +type SnapshotCreateRequest struct { + VolumeID string `json:"volume_id"` + Name string `json:"name"` + Description string `json:"description"` +} + +// ListSnapshots lists all snapshots related to a storage volume. +func (svc *StorageServiceOp) ListSnapshots(ctx context.Context, volumeID string, opt *ListOptions) ([]Snapshot, *Response, error) { + path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, volumeID) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := svc.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(snapshotsRoot) + resp, err := svc.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Snapshots, resp, nil +} + +// CreateSnapshot creates a snapshot of a storage volume. +func (svc *StorageServiceOp) CreateSnapshot(ctx context.Context, createRequest *SnapshotCreateRequest) (*Snapshot, *Response, error) { + path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, createRequest.VolumeID) + + req, err := svc.client.NewRequest(ctx, "POST", path, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(snapshotRoot) + resp, err := svc.client.Do(req, root) + if err != nil { + return nil, resp, err + } + return root.Snapshot, resp, nil +} + +// GetSnapshot retrieves an individual snapshot. +func (svc *StorageServiceOp) GetSnapshot(ctx context.Context, id string) (*Snapshot, *Response, error) { + path := fmt.Sprintf("%s/%s", storageSnapPath, id) + + req, err := svc.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(snapshotRoot) + resp, err := svc.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Snapshot, resp, nil +} + +// DeleteSnapshot deletes a snapshot. +func (svc *StorageServiceOp) DeleteSnapshot(ctx context.Context, id string) (*Response, error) { + path := fmt.Sprintf("%s/%s", storageSnapPath, id) + + req, err := svc.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + return svc.client.Do(req, nil) +} diff --git a/vendor/github.com/digitalocean/godo/storage_actions.go b/vendor/github.com/digitalocean/godo/storage_actions.go new file mode 100644 index 0000000000..7988868536 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/storage_actions.go @@ -0,0 +1,137 @@ +package godo + +import ( + "context" + "fmt" +) + +// StorageActionsService is an interface for interfacing with the +// storage actions endpoints of the Digital Ocean API. +// See: https://developers.digitalocean.com/documentation/v2#storage-actions +type StorageActionsService interface { + Attach(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) + Detach(ctx context.Context, volumeID string) (*Action, *Response, error) + DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) + Get(ctx context.Context, volumeID string, actionID int) (*Action, *Response, error) + List(ctx context.Context, volumeID string, opt *ListOptions) ([]Action, *Response, error) + Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) +} + +// StorageActionsServiceOp handles communication with the storage volumes +// action related methods of the DigitalOcean API. +type StorageActionsServiceOp struct { + client *Client +} + +// StorageAttachment represents the attachement of a block storage +// volume to a specific Droplet under the device name. +type StorageAttachment struct { + DropletID int `json:"droplet_id"` +} + +// Attach a storage volume to a Droplet. +func (s *StorageActionsServiceOp) Attach(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) { + request := &ActionRequest{ + "type": "attach", + "droplet_id": dropletID, + } + return s.doAction(ctx, volumeID, request) +} + +// Detach a storage volume from a Droplet. +func (s *StorageActionsServiceOp) Detach(ctx context.Context, volumeID string) (*Action, *Response, error) { + request := &ActionRequest{ + "type": "detach", + } + return s.doAction(ctx, volumeID, request) +} + +// DetachByDropletID a storage volume from a Droplet by Droplet ID. +func (s *StorageActionsServiceOp) DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) { + request := &ActionRequest{ + "type": "detach", + "droplet_id": dropletID, + } + return s.doAction(ctx, volumeID, request) +} + +// Get an action for a particular storage volume by id. +func (s *StorageActionsServiceOp) Get(ctx context.Context, volumeID string, actionID int) (*Action, *Response, error) { + path := fmt.Sprintf("%s/%d", storageAllocationActionPath(volumeID), actionID) + return s.get(ctx, path) +} + +// List the actions for a particular storage volume. +func (s *StorageActionsServiceOp) List(ctx context.Context, volumeID string, opt *ListOptions) ([]Action, *Response, error) { + path := storageAllocationActionPath(volumeID) + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + return s.list(ctx, path) +} + +// Resize a storage volume. +func (s *StorageActionsServiceOp) Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) { + request := &ActionRequest{ + "type": "resize", + "size_gigabytes": sizeGigabytes, + "region": regionSlug, + } + return s.doAction(ctx, volumeID, request) +} + +func (s *StorageActionsServiceOp) doAction(ctx context.Context, volumeID string, request *ActionRequest) (*Action, *Response, error) { + path := storageAllocationActionPath(volumeID) + + req, err := s.client.NewRequest(ctx, "POST", path, request) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func (s *StorageActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func (s *StorageActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(actionsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Actions, resp, err +} + +func storageAllocationActionPath(volumeID string) string { + return fmt.Sprintf("%s/%s/actions", storageAllocPath, volumeID) +} diff --git a/vendor/github.com/digitalocean/godo/strings.go b/vendor/github.com/digitalocean/godo/strings.go new file mode 100644 index 0000000000..4a8bfb636c --- /dev/null +++ b/vendor/github.com/digitalocean/godo/strings.go @@ -0,0 +1,92 @@ +package godo + +import ( + "bytes" + "fmt" + "io" + "reflect" +) + +var timestampType = reflect.TypeOf(Timestamp{}) + +// Stringify attempts to create a string representation of DigitalOcean types +func Stringify(message interface{}) string { + var buf bytes.Buffer + v := reflect.ValueOf(message) + stringifyValue(&buf, v) + return buf.String() +} + +// stringifyValue was graciously cargoculted from the goprotubuf library +func stringifyValue(w io.Writer, val reflect.Value) { + if val.Kind() == reflect.Ptr && val.IsNil() { + _, _ = w.Write([]byte("")) + return + } + + v := reflect.Indirect(val) + + switch v.Kind() { + case reflect.String: + fmt.Fprintf(w, `"%s"`, v) + case reflect.Slice: + stringifySlice(w, v) + return + case reflect.Struct: + stringifyStruct(w, v) + default: + if v.CanInterface() { + fmt.Fprint(w, v.Interface()) + } + } +} + +func stringifySlice(w io.Writer, v reflect.Value) { + _, _ = w.Write([]byte{'['}) + for i := 0; i < v.Len(); i++ { + if i > 0 { + _, _ = w.Write([]byte{' '}) + } + + stringifyValue(w, v.Index(i)) + } + + _, _ = w.Write([]byte{']'}) +} + +func stringifyStruct(w io.Writer, v reflect.Value) { + if v.Type().Name() != "" { + _, _ = w.Write([]byte(v.Type().String())) + } + + // special handling of Timestamp values + if v.Type() == timestampType { + fmt.Fprintf(w, "{%s}", v.Interface()) + return + } + + _, _ = w.Write([]byte{'{'}) + + var sep bool + for i := 0; i < v.NumField(); i++ { + fv := v.Field(i) + if fv.Kind() == reflect.Ptr && fv.IsNil() { + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + continue + } + + if sep { + _, _ = w.Write([]byte(", ")) + } else { + sep = true + } + + _, _ = w.Write([]byte(v.Type().Field(i).Name)) + _, _ = w.Write([]byte{':'}) + stringifyValue(w, fv) + } + + _, _ = w.Write([]byte{'}'}) +} diff --git a/vendor/github.com/digitalocean/godo/tags.go b/vendor/github.com/digitalocean/godo/tags.go new file mode 100644 index 0000000000..709e96cd9d --- /dev/null +++ b/vendor/github.com/digitalocean/godo/tags.go @@ -0,0 +1,234 @@ +package godo + +import ( + "context" + "fmt" +) + +const tagsBasePath = "v2/tags" + +// TagsService is an interface for interfacing with the tags +// endpoints of the DigitalOcean API +// See: https://developers.digitalocean.com/documentation/v2#tags +type TagsService interface { + List(context.Context, *ListOptions) ([]Tag, *Response, error) + Get(context.Context, string) (*Tag, *Response, error) + Create(context.Context, *TagCreateRequest) (*Tag, *Response, error) + Update(context.Context, string, *TagUpdateRequest) (*Response, error) + Delete(context.Context, string) (*Response, error) + + TagResources(context.Context, string, *TagResourcesRequest) (*Response, error) + UntagResources(context.Context, string, *UntagResourcesRequest) (*Response, error) +} + +// TagsServiceOp handles communication with tag related method of the +// DigitalOcean API. +type TagsServiceOp struct { + client *Client +} + +var _ TagsService = &TagsServiceOp{} + +// ResourceType represents a class of resource, currently only droplet are supported +type ResourceType string + +const ( + //DropletResourceType holds the string representing our ResourceType of Droplet. + DropletResourceType ResourceType = "droplet" +) + +// Resource represent a single resource for associating/disassociating with tags +type Resource struct { + ID string `json:"resource_id,omit_empty"` + Type ResourceType `json:"resource_type,omit_empty"` +} + +// TaggedResources represent the set of resources a tag is attached to +type TaggedResources struct { + Droplets *TaggedDropletsResources `json:"droplets,omitempty"` +} + +// TaggedDropletsResources represent the droplet resources a tag is attached to +type TaggedDropletsResources struct { + Count int `json:"count,float64,omitempty"` + LastTagged *Droplet `json:"last_tagged,omitempty"` +} + +// Tag represent DigitalOcean tag +type Tag struct { + Name string `json:"name,omitempty"` + Resources *TaggedResources `json:"resources,omitempty"` +} + +//TagCreateRequest represents the JSON structure of a request of that type. +type TagCreateRequest struct { + Name string `json:"name"` +} + +//TagUpdateRequest represents the JSON structure of a request of that type. +type TagUpdateRequest struct { + Name string `json:"name"` +} + +// TagResourcesRequest represents the JSON structure of a request of that type. +type TagResourcesRequest struct { + Resources []Resource `json:"resources"` +} + +// UntagResourcesRequest represents the JSON structure of a request of that type. +type UntagResourcesRequest struct { + Resources []Resource `json:"resources"` +} + +type tagsRoot struct { + Tags []Tag `json:"tags"` + Links *Links `json:"links"` +} + +type tagRoot struct { + Tag *Tag `json:"tag"` +} + +// List all tags +func (s *TagsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Tag, *Response, error) { + path := tagsBasePath + path, err := addOptions(path, opt) + + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(tagsRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Tags, resp, err +} + +// Get a single tag +func (s *TagsServiceOp) Get(ctx context.Context, name string) (*Tag, *Response, error) { + path := fmt.Sprintf("%s/%s", tagsBasePath, name) + + req, err := s.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(tagRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Tag, resp, err +} + +// Create a new tag +func (s *TagsServiceOp) Create(ctx context.Context, createRequest *TagCreateRequest) (*Tag, *Response, error) { + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + req, err := s.client.NewRequest(ctx, "POST", tagsBasePath, createRequest) + if err != nil { + return nil, nil, err + } + + root := new(tagRoot) + resp, err := s.client.Do(req, root) + if err != nil { + return nil, resp, err + } + + return root.Tag, resp, err +} + +// Update an exsting tag +func (s *TagsServiceOp) Update(ctx context.Context, name string, updateRequest *TagUpdateRequest) (*Response, error) { + if name == "" { + return nil, NewArgError("name", "cannot be empty") + } + + if updateRequest == nil { + return nil, NewArgError("updateRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%s", tagsBasePath, name) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// Delete an existing tag +func (s *TagsServiceOp) Delete(ctx context.Context, name string) (*Response, error) { + if name == "" { + return nil, NewArgError("name", "cannot be empty") + } + + path := fmt.Sprintf("%s/%s", tagsBasePath, name) + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// TagResources associates resources with a given Tag. +func (s *TagsServiceOp) TagResources(ctx context.Context, name string, tagRequest *TagResourcesRequest) (*Response, error) { + if name == "" { + return nil, NewArgError("name", "cannot be empty") + } + + if tagRequest == nil { + return nil, NewArgError("tagRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name) + req, err := s.client.NewRequest(ctx, "POST", path, tagRequest) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} + +// UntagResources dissociates resources with a given Tag. +func (s *TagsServiceOp) UntagResources(ctx context.Context, name string, untagRequest *UntagResourcesRequest) (*Response, error) { + if name == "" { + return nil, NewArgError("name", "cannot be empty") + } + + if untagRequest == nil { + return nil, NewArgError("tagRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name) + req, err := s.client.NewRequest(ctx, "DELETE", path, untagRequest) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, nil) + + return resp, err +} diff --git a/Godeps/_workspace/src/github.com/digitalocean/godo/timestamp.go b/vendor/github.com/digitalocean/godo/timestamp.go similarity index 91% rename from Godeps/_workspace/src/github.com/digitalocean/godo/timestamp.go rename to vendor/github.com/digitalocean/godo/timestamp.go index 4df53639b0..37a28e5f2f 100644 --- a/Godeps/_workspace/src/github.com/digitalocean/godo/timestamp.go +++ b/vendor/github.com/digitalocean/godo/timestamp.go @@ -18,7 +18,7 @@ func (t Timestamp) String() string { // UnmarshalJSON implements the json.Unmarshaler interface. // Time is expected in RFC3339 or Unix format. -func (t *Timestamp) UnmarshalJSON(data []byte) (err error) { +func (t *Timestamp) UnmarshalJSON(data []byte) error { str := string(data) i, err := strconv.ParseInt(str, 10, 64) if err == nil { @@ -26,7 +26,7 @@ func (t *Timestamp) UnmarshalJSON(data []byte) (err error) { } else { t.Time, err = time.Parse(`"`+time.RFC3339+`"`, str) } - return + return err } // Equal reports whether t and u are equal based on time.Equal diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS new file mode 100644 index 0000000000..46102d7402 --- /dev/null +++ b/vendor/github.com/docker/docker/AUTHORS @@ -0,0 +1,1984 @@ +# This file lists all individuals having contributed content to the repository. +# For how it is generated, see `hack/generate-authors.sh`. + +Aanand Prasad +Aaron Davidson +Aaron Feng +Aaron Huslage +Aaron L. Xu +Aaron Lehmann +Aaron Welch +Aaron.L.Xu +Abel Muiño +Abhijeet Kasurde +Abhinandan Prativadi +Abhinav Ajgaonkar +Abhishek Chanda +Abhishek Sharma +Abin Shahab +Adam Avilla +Adam Eijdenberg +Adam Kunk +Adam Miller +Adam Mills +Adam Pointer +Adam Singer +Adam Walz +Addam Hardy +Aditi Rajagopal +Aditya +Adnan Khan +Adolfo Ochagavía +Adria Casas +Adrian Moisey +Adrian Mouat +Adrian Oprea +Adrien Folie +Adrien Gallouët +Ahmed Kamal +Ahmet Alp Balkan +Aidan Feldman +Aidan Hobson Sayers +AJ Bowen +Ajey Charantimath +ajneu +Akash Gupta +Akihiro Matsushima +Akihiro Suda +Akim Demaille +Akira Koyasu +Akshay Karle +Al Tobey +alambike +Alan Scherger +Alan Thompson +Albert Callarisa +Albert Zhang +Alejandro González Hevia +Aleksa Sarai +Aleksandrs Fadins +Alena Prokharchyk +Alessandro Boch +Alessio Biancalana +Alex Chan +Alex Chen +Alex Coventry +Alex Crawford +Alex Ellis +Alex Gaynor +Alex Goodman +Alex Olshansky +Alex Samorukov +Alex Warhawk +Alexander Artemenko +Alexander Boyd +Alexander Larsson +Alexander Midlash +Alexander Morozov +Alexander Shopov +Alexandre Beslic +Alexandre Garnier +Alexandre González +Alexandre Jomin +Alexandru Sfirlogea +Alexey Guskov +Alexey Kotlyarov +Alexey Shamrin +Alexis THOMAS +Alfred Landrum +Ali Dehghani +Alicia Lauerman +Alihan Demir +Allen Madsen +Allen Sun +almoehi +Alvaro Saurin +Alvin Deng +Alvin Richards +amangoel +Amen Belayneh +Amir Goldstein +Amit Bakshi +Amit Krishnan +Amit Shukla +Amr Gawish +Amy Lindburg +Anand Patil +AnandkumarPatel +Anatoly Borodin +Anchal Agrawal +Anda Xu +Anders Janmyr +Andre Dublin <81dublin@gmail.com> +Andre Granovsky +Andrea Luzzardi +Andrea Turli +Andreas Elvers +Andreas Köhler +Andreas Savvides +Andreas Tiefenthaler +Andrei Gherzan +Andrew C. Bodine +Andrew Clay Shafer +Andrew Duckworth +Andrew France +Andrew Gerrand +Andrew Guenther +Andrew He +Andrew Hsu +Andrew Kuklewicz +Andrew Macgregor +Andrew Macpherson +Andrew Martin +Andrew McDonnell +Andrew Munsell +Andrew Pennebaker +Andrew Po +Andrew Weiss +Andrew Williams +Andrews Medina +Andrey Petrov +Andrey Stolbovsky +André Martins +andy +Andy Chambers +andy diller +Andy Goldstein +Andy Kipp +Andy Rothfusz +Andy Smith +Andy Wilson +Anes Hasicic +Anil Belur +Anil Madhavapeddy +Ankush Agarwal +Anonmily +Anran Qiao +Anshul Pundir +Anthon van der Neut +Anthony Baire +Anthony Bishopric +Anthony Dahanne +Anthony Sottile +Anton Löfgren +Anton Nikitin +Anton Polonskiy +Anton Tiurin +Antonio Murdaca +Antonis Kalipetis +Antony Messerli +Anuj Bahuguna +Anusha Ragunathan +apocas +Arash Deshmeh +ArikaChen +Arnaud Lefebvre +Arnaud Porterie +Arthur Barr +Arthur Gautier +Artur Meyster +Arun Gupta +Asad Saeeduddin +Asbjørn Enge +averagehuman +Avi Das +Avi Miller +Avi Vaid +ayoshitake +Azat Khuyiyakhmetov +Bardia Keyoumarsi +Barnaby Gray +Barry Allard +Bartłomiej Piotrowski +Bastiaan Bakker +bdevloed +Ben Bonnefoy +Ben Firshman +Ben Golub +Ben Hall +Ben Sargent +Ben Severson +Ben Toews +Ben Wiklund +Benjamin Atkin +Benjamin Boudreau +Benjamin Yolken +Benoit Chesneau +Bernerd Schaefer +Bernhard M. Wiedemann +Bert Goethals +Bharath Thiruveedula +Bhiraj Butala +Bhumika Bayani +Bilal Amarni +Bill Wang +Bin Liu +Bingshen Wang +Blake Geno +Boaz Shuster +bobby abbott +Boris Pruessmann +Boshi Lian +Bouke Haarsma +Boyd Hemphill +boynux +Bradley Cicenas +Bradley Wright +Brandon Liu +Brandon Philips +Brandon Rhodes +Brendan Dixon +Brent Salisbury +Brett Higgins +Brett Kochendorfer +Brett Randall +Brian (bex) Exelbierd +Brian Bland +Brian DeHamer +Brian Dorsey +Brian Flad +Brian Goff +Brian McCallister +Brian Olsen +Brian Schwind +Brian Shumate +Brian Torres-Gil +Brian Trump +Brice Jaglin +Briehan Lombaard +Bruno Bigras +Bruno Binet +Bruno Gazzera +Bruno Renié +Bruno Tavares +Bryan Bess +Bryan Boreham +Bryan Matsuo +Bryan Murphy +Burke Libbey +Byung Kang +Caleb Spare +Calen Pennington +Cameron Boehmer +Cameron Spear +Campbell Allen +Candid Dauth +Cao Weiwei +Carl Henrik Lunde +Carl Loa Odin +Carl X. Su +Carlo Mion +Carlos Alexandro Becker +Carlos Sanchez +Carol Fager-Higgins +Cary +Casey Bisson +Catalin Pirvu +Ce Gao +Cedric Davies +Cezar Sa Espinola +Chad Swenson +Chance Zibolski +Chander Govindarajan +Chanhun Jeong +Chao Wang +Charles Chan +Charles Hooper +Charles Law +Charles Lindsay +Charles Merriam +Charles Sarrazin +Charles Smith +Charlie Drage +Charlie Lewis +Chase Bolt +ChaYoung You +Chen Chao +Chen Chuanliang +Chen Hanxiao +Chen Min +Chen Mingjie +Chen Qiu +Cheng-mean Liu +Chengguang Xu +chenyuzhu +Chetan Birajdar +Chewey +Chia-liang Kao +chli +Cholerae Hu +Chris Alfonso +Chris Armstrong +Chris Dias +Chris Dituri +Chris Fordham +Chris Gavin +Chris Gibson +Chris Khoo +Chris McKinnel +Chris McKinnel +Chris Seto +Chris Snow +Chris St. Pierre +Chris Stivers +Chris Swan +Chris Telfer +Chris Wahl +Chris Weyl +Christian Berendt +Christian Brauner +Christian Böhme +Christian Persson +Christian Rotzoll +Christian Simon +Christian Stefanescu +Christophe Mehay +Christophe Troestler +Christophe Vidal +Christopher Biscardi +Christopher Crone +Christopher Currie +Christopher Jones +Christopher Latham +Christopher Rigor +Christy Perez +Chun Chen +Ciro S. Costa +Clayton Coleman +Clinton Kitson +Cody Roseborough +Coenraad Loubser +Colin Dunklau +Colin Hebert +Colin Rice +Colin Walters +Collin Guarino +Colm Hally +companycy +Corbin Coleman +Corey Farrell +Cory Forsyth +cressie176 +CrimsonGlory +Cristian Staretu +cristiano balducci +Cruceru Calin-Cristian +CUI Wei +Cyprian Gracz +Cyril F +Daan van Berkel +Daehyeok Mun +Dafydd Crosby +dalanlan +Damian Smyth +Damien Nadé +Damien Nozay +Damjan Georgievski +Dan Anolik +Dan Buch +Dan Cotora +Dan Feldman +Dan Griffin +Dan Hirsch +Dan Keder +Dan Levy +Dan McPherson +Dan Stine +Dan Williams +Dani Louca +Daniel Antlinger +Daniel Dao +Daniel Exner +Daniel Farrell +Daniel Garcia +Daniel Gasienica +Daniel Grunwell +Daniel Hiltgen +Daniel J Walsh +Daniel Menet +Daniel Mizyrycki +Daniel Nephin +Daniel Norberg +Daniel Nordberg +Daniel Robinson +Daniel S +Daniel Von Fange +Daniel Watkins +Daniel X Moore +Daniel YC Lin +Daniel Zhang +Danny Berger +Danny Yates +Danyal Khaliq +Darren Coxall +Darren Shepherd +Darren Stahl +Dattatraya Kumbhar +Davanum Srinivas +Dave Barboza +Dave Goodchild +Dave Henderson +Dave MacDonald +Dave Tucker +David Anderson +David Calavera +David Chung +David Corking +David Cramer +David Currie +David Davis +David Dooling +David Gageot +David Gebler +David Glasser +David Lawrence +David Lechner +David M. Karr +David Mackey +David Mat +David Mcanulty +David McKay +David Pelaez +David R. Jenni +David Röthlisberger +David Sheets +David Sissitka +David Trott +David Williamson +David Xia +David Young +Davide Ceretti +Dawn Chen +dbdd +dcylabs +Deborah Gertrude Digges +deed02392 +Deng Guangxing +Deni Bertovic +Denis Defreyne +Denis Gladkikh +Denis Ollier +Dennis Chen +Dennis Chen +Dennis Docter +Derek +Derek +Derek Ch +Derek McGowan +Deric Crago +Deshi Xiao +devmeyster +Devvyn Murphy +Dharmit Shah +Dhawal Yogesh Bhanushali +Diego Romero +Diego Siqueira +Dieter Reuter +Dillon Dixon +Dima Stopel +Dimitri John Ledkov +Dimitris Rozakis +Dimitry Andric +Dinesh Subhraveti +Ding Fei +Diogo Monica +DiuDiugirl +Djibril Koné +dkumor +Dmitri Logvinenko +Dmitri Shuralyov +Dmitry Demeshchuk +Dmitry Gusev +Dmitry Kononenko +Dmitry Shyshkin +Dmitry Smirnov +Dmitry V. Krivenok +Dmitry Vorobev +Dolph Mathews +Dominik Dingel +Dominik Finkbeiner +Dominik Honnef +Don Kirkby +Don Kjer +Don Spaulding +Donald Huang +Dong Chen +Donovan Jones +Doron Podoleanu +Doug Davis +Doug MacEachern +Doug Tangren +Douglas Curtis +Dr Nic Williams +dragon788 +Dražen Lučanin +Drew Erny +Drew Hubl +Dustin Sallings +Ed Costello +Edmund Wagner +Eiichi Tsukata +Eike Herzbach +Eivin Giske Skaaren +Eivind Uggedal +Elan Ruusamäe +Elango Sivanandam +Elena Morozova +Eli Uriegas +Elias Faxö +Elias Probst +Elijah Zupancic +eluck +Elvir Kuric +Emil Davtyan +Emil Hernvall +Emily Maier +Emily Rose +Emir Ozer +Enguerran +Eohyung Lee +epeterso +Eric Barch +Eric Curtin +Eric G. Noriega +Eric Hanchrow +Eric Lee +Eric Myhre +Eric Paris +Eric Rafaloff +Eric Rosenberg +Eric Sage +Eric Soderstrom +Eric Yang +Eric-Olivier Lamey +Erica Windisch +Erik Bray +Erik Dubbelboer +Erik Hollensbe +Erik Inge Bolsø +Erik Kristensen +Erik St. Martin +Erik Weathers +Erno Hopearuoho +Erwin van der Koogh +Ethan Bell +Euan Kemp +Eugen Krizo +Eugene Yakubovich +Evan Allrich +Evan Carmi +Evan Hazlett +Evan Krall +Evan Phoenix +Evan Wies +Evelyn Xu +Everett Toews +Evgeny Shmarnev +Evgeny Vereshchagin +Ewa Czechowska +Eystein Måløy Stenberg +ezbercih +Ezra Silvera +Fabian Lauer +Fabiano Rosas +Fabio Falci +Fabio Kung +Fabio Rapposelli +Fabio Rehm +Fabrizio Regini +Fabrizio Soppelsa +Faiz Khan +falmp +Fangming Fang +Fangyuan Gao <21551127@zju.edu.cn> +Fareed Dudhia +Fathi Boudra +Federico Gimenez +Felipe Oliveira +Felix Abecassis +Felix Geisendörfer +Felix Hupfeld +Felix Rabe +Felix Ruess +Felix Schindler +Feng Yan +Fengtu Wang +Ferenc Szabo +Fernando +Fero Volar +Ferran Rodenas +Filipe Brandenburger +Filipe Oliveira +Flavio Castelli +Flavio Crisciani +Florian +Florian Klein +Florian Maier +Florian Noeding +Florian Weingarten +Florin Asavoaie +Florin Patan +fonglh +Foysal Iqbal +Francesc Campoy +Francis Chuang +Francisco Carriedo +Francisco Souza +Frank Groeneveld +Frank Herrmann +Frank Macreery +Frank Rosquin +Fred Lifton +Frederick F. Kautz IV +Frederik Loeffert +Frederik Nordahl Jul Sabroe +Freek Kalter +Frieder Bluemle +Félix Baylac-Jacqué +Félix Cantournet +Gabe Rosenhouse +Gabor Nagy +Gabriel Linder +Gabriel Monroy +Gabriel Nicolas Avellaneda +Gaetan de Villele +Galen Sampson +Gang Qiao +Gareth Rushgrove +Garrett Barboza +Gary Schaetz +Gaurav +gautam, prasanna +Gaël PORTAY +Genki Takiuchi +GennadySpb +Geoffrey Bachelet +George Kontridze +George MacRorie +George Xie +Georgi Hristozov +Gereon Frey +German DZ +Gert van Valkenhoef +Gerwim Feiken +Ghislain Bourgeois +Giampaolo Mancini +Gianluca Borello +Gildas Cuisinier +gissehel +Giuseppe Mazzotta +Gleb Fotengauer-Malinovskiy +Gleb M Borisov +Glyn Normington +GoBella +Goffert van Gool +Gopikannan Venugopalsamy +Gosuke Miyashita +Gou Rao +Govinda Fichtner +Grant Reaber +Graydon Hoare +Greg Fausak +Greg Pflaum +Greg Stephens +Greg Thornton +Grzegorz Jaśkiewicz +Guilhem Lettron +Guilherme Salgado +Guillaume Dufour +Guillaume J. Charmes +guoxiuyan +Guri +Gurjeet Singh +Guruprasad +Gustav Sinder +gwx296173 +Günter Zöchbauer +Hakan Özler +Hans Kristian Flaatten +Hans Rødtang +Hao Shu Wei +Hao Zhang <21521210@zju.edu.cn> +Harald Albers +Harley Laue +Harold Cooper +Harry Zhang +Harshal Patil +Harshal Patil +He Simei +He Xiaoxi +He Xin +heartlock <21521209@zju.edu.cn> +Hector Castro +Helen Xie +Henning Sprang +Hiroshi Hatake +Hobofan +Hollie Teal +Hong Xu +Hongbin Lu +hsinko <21551195@zju.edu.cn> +Hu Keping +Hu Tao +Huanzhong Zhang +Huayi Zhang +Hugo Duncan +Hugo Marisco <0x6875676f@gmail.com> +Hunter Blanks +huqun +Huu Nguyen +hyeongkyu.lee +Hyzhou Zhy +Iago López Galeiras +Ian Babrou +Ian Bishop +Ian Bull +Ian Calvert +Ian Campbell +Ian Lee +Ian Main +Ian Philpot +Ian Truslove +Iavael +Icaro Seara +Ignacio Capurro +Igor Dolzhikov +Igor Karpovich +Iliana Weller +Ilkka Laukkanen +Ilya Dmitrichenko +Ilya Gusev +Ilya Khlopotov +imre Fitos +inglesp +Ingo Gottwald +Isaac Dupree +Isabel Jimenez +Isao Jonas +Ivan Babrou +Ivan Fraixedes +Ivan Grcic +Ivan Markin +J Bruni +J. Nunn +Jack Danger Canty +Jack Laxson +Jacob Atzen +Jacob Edelman +Jacob Tomlinson +Jacob Vallejo +Jacob Wen +Jaivish Kothari +Jake Champlin +Jake Moshenko +Jake Sanders +jakedt +James Allen +James Carey +James Carr +James DeFelice +James Harrison Fisher +James Kyburz +James Kyle +James Lal +James Mills +James Nesbitt +James Nugent +James Turnbull +Jamie Hannaford +Jamshid Afshar +Jan Keromnes +Jan Koprowski +Jan Pazdziora +Jan Toebes +Jan-Gerd Tenberge +Jan-Jaap Driessen +Jana Radhakrishnan +Jannick Fahlbusch +Januar Wayong +Jared Biel +Jared Hocutt +Jaroslaw Zabiello +jaseg +Jasmine Hegman +Jason Divock +Jason Giedymin +Jason Green +Jason Hall +Jason Heiss +Jason Livesay +Jason McVetta +Jason Plum +Jason Shepherd +Jason Smith +Jason Sommer +Jason Stangroome +jaxgeller +Jay +Jay +Jay Kamat +Jean-Baptiste Barth +Jean-Baptiste Dalido +Jean-Christophe Berthon +Jean-Paul Calderone +Jean-Pierre Huynh +Jean-Tiare Le Bigot +Jeeva S. Chelladhurai +Jeff Anderson +Jeff Hajewski +Jeff Johnston +Jeff Lindsay +Jeff Mickey +Jeff Minard +Jeff Nickoloff +Jeff Silberman +Jeff Welch +Jeffrey Bolle +Jeffrey Morgan +Jeffrey van Gogh +Jenny Gebske +Jeremy Chambers +Jeremy Grosser +Jeremy Price +Jeremy Qian +Jeremy Unruh +Jeremy Yallop +Jeroen Franse +Jeroen Jacobs +Jesse Dearing +Jesse Dubay +Jessica Frazelle +Jezeniel Zapanta +Jhon Honce +Ji.Zhilong +Jian Zhang +Jie Luo +Jihyun Hwang +Jilles Oldenbeuving +Jim Alateras +Jim Galasyn +Jim Minter +Jim Perrin +Jimmy Cuadra +Jimmy Puckett +Jimmy Song +jimmyxian +Jinsoo Park +Jiri Popelka +Jiuyue Ma +Jiří Župka +jjy +jmzwcn +Joao Fernandes +Joe Beda +Joe Doliner +Joe Ferguson +Joe Gordon +Joe Shaw +Joe Van Dyk +Joel Friedly +Joel Handwell +Joel Hansson +Joel Wurtz +Joey Geiger +Joey Geiger +Joey Gibson +Joffrey F +Johan Euphrosine +Johan Rydberg +Johanan Lieberman +Johannes 'fish' Ziemke +John Costa +John Feminella +John Gardiner Myers +John Gossman +John Harris +John Howard (VM) +John Laswell +John Maguire +John Mulhausen +John OBrien III +John Starks +John Stephens +John Tims +John V. Martinez +John Warwick +John Willis +Jon Johnson +Jon Surrell +Jon Wedaman +Jonas Pfenniger +Jonathan A. Sternberg +Jonathan Boulle +Jonathan Camp +Jonathan Choy +Jonathan Dowland +Jonathan Lebon +Jonathan Lomas +Jonathan McCrohan +Jonathan Mueller +Jonathan Pares +Jonathan Rudenberg +Jonathan Stoppani +Jonh Wendell +Joni Sar +Joost Cassee +Jordan Arentsen +Jordan Jennings +Jordan Sissel +Jorge Marin +Jorit Kleine-Möllhoff +Jose Diaz-Gonzalez +Joseph Anthony Pasquale Holsten +Joseph Hager +Joseph Kern +Joseph Rothrock +Josh +Josh Bodah +Josh Bonczkowski +Josh Chorlton +Josh Eveleth +Josh Hawn +Josh Horwitz +Josh Poimboeuf +Josh Soref +Josh Wilson +Josiah Kiehl +José Tomás Albornoz +Joyce Jang +JP +Julian Taylor +Julien Barbier +Julien Bisconti +Julien Bordellier +Julien Dubois +Julien Kassar +Julien Maitrehenry +Julien Pervillé +Julio Montes +Jun-Ru Chang +Jussi Nummelin +Justas Brazauskas +Justin Cormack +Justin Force +Justin Menga +Justin Plock +Justin Simonelis +Justin Terry +Justyn Temme +Jyrki Puttonen +Jérôme Petazzoni +Jörg Thalheim +K. Heller +Kai Blin +Kai Qiang Wu (Kennan) +Kamil Domański +Kamjar Gerami +Kanstantsin Shautsou +Kara Alexandra +Karan Lyons +Kareem Khazem +kargakis +Karl Grzeszczak +Karol Duleba +Karthik Karanth +Karthik Nayak +Kate Heddleston +Katie McLaughlin +Kato Kazuyoshi +Katrina Owen +Kawsar Saiyeed +Kay Yan +kayrus +Ke Li +Ke Xu +Kei Ohmura +Keith Hudgins +Keli Hu +Ken Cochrane +Ken Herner +Ken ICHIKAWA +Kenfe-Mickaël Laventure +Kenjiro Nakayama +Kent Johnson +Kevin "qwazerty" Houdebert +Kevin Burke +Kevin Clark +Kevin Feyrer +Kevin J. Lynagh +Kevin Jing Qiu +Kevin Kern +Kevin Menard +Kevin Meredith +Kevin P. Kucharczyk +Kevin Richardson +Kevin Shi +Kevin Wallace +Kevin Yap +Keyvan Fatehi +kies +Kim BKC Carlbacker +Kim Eik +Kimbro Staken +Kir Kolyshkin +Kiran Gangadharan +Kirill SIbirev +knappe +Kohei Tsuruta +Koichi Shiraishi +Konrad Kleine +Konstantin Gribov +Konstantin L +Konstantin Pelykh +Krasi Georgiev +Krasimir Georgiev +Kris-Mikael Krister +Kristian Haugene +Kristina Zabunova +krrg +Kun Zhang +Kunal Kushwaha +Kyle Conroy +Kyle Linden +kyu +Lachlan Coote +Lai Jiangshan +Lajos Papp +Lakshan Perera +Lalatendu Mohanty +Lance Chen +Lance Kinley +Lars Butler +Lars Kellogg-Stedman +Lars R. Damerow +Lars-Magnus Skog +Laszlo Meszaros +Laura Frank +Laurent Erignoux +Laurie Voss +Leandro Siqueira +Lee Chao <932819864@qq.com> +Lee, Meng-Han +leeplay +Lei Jitang +Len Weincier +Lennie +Leo Gallucci +Leszek Kowalski +Levi Blackstone +Levi Gross +Lewis Daly +Lewis Marshall +Lewis Peckover +Li Yi +Liam Macgillavry +Liana Lo +Liang Mingqiang +Liang-Chi Hsieh +Liao Qingwei +Lily Guo +limsy +Lin Lu +LingFaKe +Linus Heckemann +Liran Tal +Liron Levin +Liu Bo +Liu Hua +liwenqi +lixiaobing10051267 +Liz Zhang +LIZAO LI +Lizzie Dixon <_@lizzie.io> +Lloyd Dewolf +Lokesh Mandvekar +longliqiang88 <394564827@qq.com> +Lorenz Leutgeb +Lorenzo Fontana +Louis Opter +Luca Favatella +Luca Marturana +Luca Orlandi +Luca-Bogdan Grigorescu +Lucas Chan +Lucas Chi +Lucas Molas +Luciano Mores +Luis Martínez de Bartolomé Izquierdo +Luiz Svoboda +Lukas Waslowski +lukaspustina +Lukasz Zajaczkowski +Luke Marsden +Lyn +Lynda O'Leary +Lénaïc Huard +Ma Müller +Ma Shimiao +Mabin +Madhan Raj Mookkandy +Madhav Puri +Madhu Venugopal +Mageee +Mahesh Tiyyagura +malnick +Malte Janduda +Manfred Touron +Manfred Zabarauskas +Manjunath A Kumatagi +Mansi Nahar +Manuel Meurer +Manuel Rüger +Manuel Woelker +mapk0y +Marc Abramowitz +Marc Kuo +Marc Tamsky +Marcel Edmund Franke +Marcelo Horacio Fortino +Marcelo Salazar +Marco Hennings +Marcus Cobden +Marcus Farkas +Marcus Linke +Marcus Martins +Marcus Ramberg +Marek Goldmann +Marian Marinov +Marianna Tessel +Mario Loriedo +Marius Gundersen +Marius Sturm +Marius Voila +Mark Allen +Mark McGranaghan +Mark McKinstry +Mark Milstein +Mark Oates +Mark Parker +Mark West +Markan Patel +Marko Mikulicic +Marko Tibold +Markus Fix +Markus Kortlang +Martijn Dwars +Martijn van Oosterhout +Martin Honermeyer +Martin Kelly +Martin Mosegaard Amdisen +Martin Redmond +Mary Anthony +Masahito Zembutsu +Masato Ohba +Masayuki Morita +Mason Malone +Mateusz Sulima +Mathias Monnerville +Mathieu Champlon +Mathieu Le Marec - Pasquet +Mathieu Parent +Matt Apperson +Matt Bachmann +Matt Bentley +Matt Haggard +Matt Hoyle +Matt McCormick +Matt Moore +Matt Richardson +Matt Rickard +Matt Robenolt +Matt Schurenko +Matt Williams +Matthew Heon +Matthew Lapworth +Matthew Mayer +Matthew Mosesohn +Matthew Mueller +Matthew Riley +Matthias Klumpp +Matthias Kühnle +Matthias Rampke +Matthieu Hauglustaine +Mauricio Garavaglia +mauriyouth +Max Shytikov +Maxim Fedchyshyn +Maxim Ivanov +Maxim Kulkin +Maxim Treskin +Maxime Petazzoni +Meaglith Ma +meejah +Megan Kostick +Mehul Kar +Mei ChunTao +Mengdi Gao +Mert Yazıcıoğlu +mgniu +Micah Zoltu +Michael A. Smith +Michael Bridgen +Michael Brown +Michael Chiang +Michael Crosby +Michael Currie +Michael Friis +Michael Gorsuch +Michael Grauer +Michael Holzheu +Michael Hudson-Doyle +Michael Huettermann +Michael Irwin +Michael Käufl +Michael Neale +Michael Nussbaum +Michael Prokop +Michael Scharf +Michael Spetsiotis +Michael Stapelberg +Michael Steinert +Michael Thies +Michael West +Michal Fojtik +Michal Gebauer +Michal Jemala +Michal Minář +Michal Wieczorek +Michaël Pailloncy +Michał Czeraszkiewicz +Michał Gryko +Michiel@unhosted +Mickaël FORTUNATO +Miguel Angel Fernández +Miguel Morales +Mihai Borobocea +Mihuleacc Sergiu +Mike Brown +Mike Casas +Mike Chelen +Mike Danese +Mike Dillon +Mike Dougherty +Mike Estes +Mike Gaffney +Mike Goelzer +Mike Leone +Mike Lundy +Mike MacCana +Mike Naberezny +Mike Snitzer +mikelinjie <294893458@qq.com> +Mikhail Sobolev +Miklos Szegedi +Milind Chawre +Miloslav Trmač +mingqing +Mingzhen Feng +Misty Stanley-Jones +Mitch Capper +Mizuki Urushida +mlarcher +Mohammad Banikazemi +Mohammed Aaqib Ansari +Mohit Soni +Moorthy RS +Morgan Bauer +Morgante Pell +Morgy93 +Morten Siebuhr +Morton Fox +Moysés Borges +mrfly +Mrunal Patel +Muayyad Alsadi +Mustafa Akın +Muthukumar R +Máximo Cuadros +Médi-Rémi Hashim +Nace Oroz +Nahum Shalman +Nakul Pathak +Nalin Dahyabhai +Nan Monnand Deng +Naoki Orii +Natalie Parker +Natanael Copa +Nate Brennand +Nate Eagleson +Nate Jones +Nathan Hsieh +Nathan Kleyn +Nathan LeClaire +Nathan McCauley +Nathan Williams +Naveed Jamil +Neal McBurnett +Neil Horman +Neil Peterson +Nelson Chen +Neyazul Haque +Nghia Tran +Niall O'Higgins +Nicholas E. Rabenau +Nick DeCoursin +Nick Irvine +Nick Neisen +Nick Parker +Nick Payne +Nick Russo +Nick Stenning +Nick Stinemates +NickrenREN +Nicola Kabar +Nicolas Borboën +Nicolas De Loof +Nicolas Dudebout +Nicolas Goy +Nicolas Kaiser +Nicolas Sterchele +Nicolás Hock Isaza +Nigel Poulton +Nik Nyby +Nikhil Chawla +NikolaMandic +Nikolas Garofil +Nikolay Milovanov +Nirmal Mehta +Nishant Totla +NIWA Hideyuki +Noah Meyerhans +Noah Treuhaft +NobodyOnSE +noducks +Nolan Darilek +nponeccop +Nuutti Kotivuori +nzwsch +O.S. Tezer +objectified +Oguz Bilgic +Oh Jinkyun +Ohad Schneider +ohmystack +Ole Reifschneider +Oliver Neal +Olivier Gambier +Olle Jonsson +Oriol Francès +Oskar Niburski +Otto Kekäläinen +Ouyang Liduo +Ovidio Mallo +Panagiotis Moustafellos +Paolo G. Giarrusso +Pascal +Pascal Borreli +Pascal Hartig +Patrick Böänziger +Patrick Devine +Patrick Hemmer +Patrick Stapleton +Patrik Cyvoct +pattichen +Paul +paul +Paul Annesley +Paul Bellamy +Paul Bowsher +Paul Furtado +Paul Hammond +Paul Jimenez +Paul Kehrer +Paul Lietar +Paul Liljenberg +Paul Morie +Paul Nasrat +Paul Weaver +Paulo Ribeiro +Pavel Lobashov +Pavel Pletenev +Pavel Pospisil +Pavel Sutyrin +Pavel Tikhomirov +Pavlos Ratis +Pavol Vargovcik +Pawel Konczalski +Peeyush Gupta +Peggy Li +Pei Su +Peng Tao +Penghan Wang +Per Weijnitz +perhapszzy@sina.com +Peter Bourgon +Peter Braden +Peter Bücker +Peter Choi +Peter Dave Hello +Peter Edge +Peter Ericson +Peter Esbensen +Peter Jaffe +Peter Malmgren +Peter Salvatore +Peter Volpe +Peter Waller +Petr Švihlík +Phil +Phil Estes +Phil Spitler +Philip Alexander Etling +Philip Monroe +Philipp Gillé +Philipp Wahala +Philipp Weissensteiner +Phillip Alexander +phineas +pidster +Piergiuliano Bossi +Pierre +Pierre Carrier +Pierre Dal-Pra +Pierre Wacrenier +Pierre-Alain RIVIERE +Piotr Bogdan +pixelistik +Porjo +Poul Kjeldager Sørensen +Pradeep Chhetri +Pradip Dhara +Prasanna Gautam +Pratik Karki +Prayag Verma +Priya Wadhwa +Przemek Hejman +Pure White +pysqz +Qiang Huang +Qinglan Peng +qudongfang +Quentin Brossard +Quentin Perez +Quentin Tayssier +r0n22 +Rafal Jeczalik +Rafe Colton +Raghavendra K T +Raghuram Devarakonda +Raja Sami +Rajat Pandit +Rajdeep Dua +Ralf Sippl +Ralle +Ralph Bean +Ramkumar Ramachandra +Ramon Brooker +Ramon van Alteren +Ray Tsang +ReadmeCritic +Recursive Madman +Reficul +Regan McCooey +Remi Rampin +Remy Suen +Renato Riccieri Santos Zannon +Renaud Gaubert +Rhys Hiltner +Ri Xu +Ricardo N Feliciano +Rich Moyse +Rich Seymour +Richard +Richard Burnison +Richard Harvey +Richard Mathie +Richard Metzler +Richard Scothern +Richo Healey +Rick Bradley +Rick van de Loo +Rick Wieman +Rik Nijessen +Riku Voipio +Riley Guerin +Ritesh H Shukla +Riyaz Faizullabhoy +Rob Vesse +Robert Bachmann +Robert Bittle +Robert Obryk +Robert Schneider +Robert Stern +Robert Terhaar +Robert Wallis +Roberto G. Hashioka +Roberto Muñoz Fernández +Robin Naundorf +Robin Schneider +Robin Speekenbrink +robpc +Rodolfo Carvalho +Rodrigo Vaz +Roel Van Nyen +Roger Peppe +Rohit Jnagal +Rohit Kadam +Rojin George +Roland Huß +Roland Kammerer +Roland Moriz +Roma Sokolov +Roman Dudin +Roman Strashkin +Ron Smits +Ron Williams +root +root +root +root +Rory Hunter +Rory McCune +Ross Boucher +Rovanion Luckey +Royce Remer +Rozhnov Alexandr +Rudolph Gottesheim +Rui Lopes +Runshen Zhu +Ryan Abrams +Ryan Anderson +Ryan Aslett +Ryan Belgrave +Ryan Detzel +Ryan Fowler +Ryan Liu +Ryan McLaughlin +Ryan O'Donnell +Ryan Seto +Ryan Simmen +Ryan Stelly +Ryan Thomas +Ryan Trauntvein +Ryan Wallner +Ryan Zhang +ryancooper7 +RyanDeng +Rémy Greinhofer +s. rannou +s00318865 +Sabin Basyal +Sachin Joshi +Sagar Hani +Sainath Grandhi +Sakeven Jiang +Sally O'Malley +Sam Abed +Sam Alba +Sam Bailey +Sam J Sharpe +Sam Neirinck +Sam Reis +Sam Rijs +Sambuddha Basu +Sami Wagiaalla +Samuel Andaya +Samuel Dion-Girardeau +Samuel Karp +Samuel PHAN +Sandeep Bansal +Sankar சங்கர் +Sanket Saurav +Santhosh Manohar +sapphiredev +Sargun Dhillon +Sascha Andres +Satnam Singh +Satoshi Amemiya +Satoshi Tagomori +Scott Bessler +Scott Collier +Scott Johnston +Scott Stamp +Scott Walls +sdreyesg +Sean Christopherson +Sean Cronin +Sean Lee +Sean McIntyre +Sean OMeara +Sean P. Kane +Sean Rodman +Sebastiaan van Steenis +Sebastiaan van Stijn +Senthil Kumar Selvaraj +Senthil Kumaran +SeongJae Park +Seongyeol Lim +Serge Hallyn +Sergey Alekseev +Sergey Evstifeev +Sergii Kabashniuk +Serhat Gülçiçek +Sevki Hasirci +Shane Canon +Shane da Silva +Shaun Kaasten +shaunol +Shawn Landden +Shawn Siefkas +shawnhe +Shayne Wang +Shekhar Gulati +Sheng Yang +Shengbo Song +Shev Yan +Shih-Yuan Lee +Shijiang Wei +Shijun Qin +Shishir Mahajan +Shoubhik Bose +Shourya Sarcar +shuai-z +Shukui Yang +Shuwei Hao +Sian Lerk Lau +Sidhartha Mani +sidharthamani +Silas Sewell +Silvan Jegen +Simei He +Simon Eskildsen +Simon Ferquel +Simon Leinen +Simon Menke +Simon Taranto +Simon Vikstrom +Sindhu S +Sjoerd Langkemper +Solganik Alexander +Solomon Hykes +Song Gao +Soshi Katsuta +Soulou +Spencer Brown +Spencer Smith +Sridatta Thatipamala +Sridhar Ratnakumar +Srini Brahmaroutu +Srinivasan Srivatsan +Stanislav Bondarenko +Steeve Morin +Stefan Berger +Stefan J. Wernli +Stefan Praszalowicz +Stefan S. +Stefan Scherer +Stefan Staudenmeyer +Stefan Weil +Stephan Spindler +Stephen Crosby +Stephen Day +Stephen Drake +Stephen Rust +Steve Desmond +Steve Dougherty +Steve Durrheimer +Steve Francia +Steve Koch +Steven Burgess +Steven Erenst +Steven Hartland +Steven Iveson +Steven Merrill +Steven Richards +Steven Taylor +Subhajit Ghosh +Sujith Haridasan +Sun Gengze <690388648@qq.com> +Sun Jianbo +Sunny Gogoi +Suryakumar Sudar +Sven Dowideit +Swapnil Daingade +Sylvain Baubeau +Sylvain Bellemare +Sébastien +Sébastien HOUZÉ +Sébastien Luttringer +Sébastien Stormacq +Tabakhase +Tadej Janež +TAGOMORI Satoshi +tang0th +Tangi Colin +Tatsuki Sugiura +Tatsushi Inagaki +Taylor Jones +tbonza +Ted M. Young +Tehmasp Chaudhri +Tejesh Mehta +terryding77 <550147740@qq.com> +tgic +Thatcher Peskens +theadactyl +Thell 'Bo' Fowler +Thermionix +Thijs Terlouw +Thomas Bikeev +Thomas Frössman +Thomas Gazagnaire +Thomas Grainger +Thomas Hansen +Thomas Leonard +Thomas Léveil +Thomas Orozco +Thomas Riccardi +Thomas Schroeter +Thomas Sjögren +Thomas Swift +Thomas Tanaka +Thomas Texier +Ti Zhou +Tianon Gravi +Tianyi Wang +Tibor Vass +Tiffany Jernigan +Tiffany Low +Tim Bart +Tim Bosse +Tim Dettrick +Tim Düsterhus +Tim Hockin +Tim Potter +Tim Ruffles +Tim Smith +Tim Terhorst +Tim Wang +Tim Waugh +Tim Wraight +Tim Zju <21651152@zju.edu.cn> +timfeirg +Timothy Hobbs +tjwebb123 +tobe +Tobias Bieniek +Tobias Bradtke +Tobias Gesellchen +Tobias Klauser +Tobias Munk +Tobias Schmidt +Tobias Schwab +Todd Crane +Todd Lunter +Todd Whiteman +Toli Kuznets +Tom Barlow +Tom Booth +Tom Denham +Tom Fotherby +Tom Howe +Tom Hulihan +Tom Maaswinkel +Tom Sweeney +Tom Wilkie +Tom X. Tobin +Tomas Tomecek +Tomasz Kopczynski +Tomasz Lipinski +Tomasz Nurkiewicz +Tommaso Visconti +Tomáš Hrčka +Tonny Xu +Tony Abboud +Tony Daws +Tony Miller +toogley +Torstein Husebø +Tõnis Tiigi +tpng +tracylihui <793912329@qq.com> +Trapier Marshall +Travis Cline +Travis Thieman +Trent Ogren +Trevor +Trevor Pounds +Trevor Sullivan +Trishna Guha +Tristan Carel +Troy Denton +Tycho Andersen +Tyler Brock +Tzu-Jung Lee +uhayate +Ulysse Carion +Umesh Yadav +Utz Bacher +vagrant +Vaidas Jablonskis +vanderliang +Veres Lajos +Victor Algaze +Victor Coisne +Victor Costan +Victor I. Wood +Victor Lyuboslavsky +Victor Marmol +Victor Palma +Victor Vieux +Victoria Bialas +Vijaya Kumar K +Viktor Stanchev +Viktor Vojnovski +VinayRaghavanKS +Vincent Batts +Vincent Bernat +Vincent Demeester +Vincent Giersch +Vincent Mayers +Vincent Woo +Vinod Kulkarni +Vishal Doshi +Vishnu Kannan +Vitaly Ostrosablin +Vitor Monteiro +Vivek Agarwal +Vivek Dasgupta +Vivek Goyal +Vladimir Bulyga +Vladimir Kirillov +Vladimir Pouzanov +Vladimir Rutsky +Vladimir Varankin +VladimirAus +Vlastimil Zeman +Vojtech Vitek (V-Teq) +waitingkuo +Walter Leibbrandt +Walter Stanish +Wang Chao +Wang Guoliang +Wang Jie +Wang Long +Wang Ping +Wang Xing +Wang Yuexiao +Ward Vandewege +WarheadsSE +Wassim Dhif +Wayne Chang +Wayne Song +Weerasak Chongnguluam +Wei Wu +Wei-Ting Kuo +weipeng +weiyan +Weiyang Zhu +Wen Cheng Ma +Wendel Fleming +Wenjun Tang +Wenkai Yin +Wentao Zhang +Wenxuan Zhao +Wenyu You <21551128@zju.edu.cn> +Wenzhi Liang +Wes Morgan +Wewang Xiaorenfine +Will Dietz +Will Rouesnel +Will Weaver +willhf +William Delanoue +William Henry +William Hubbs +William Martin +William Riancho +William Thurston +WiseTrem +Wolfgang Powisch +Wonjun Kim +xamyzhao +Xianglin Gao +Xianlu Bird +XiaoBing Jiang +Xiaoxu Chen +Xiaoyu Zhang +xiekeyang +Xinbo Weng +Xinzi Zhou +Xiuming Chen +Xuecong Liao +xuzhaokui +Yahya +YAMADA Tsuyoshi +Yamasaki Masahide +Yan Feng +Yang Bai +Yang Pengfei +yangchenliang +Yanqiang Miao +Yao Zaiyong +Yassine Tijani +Yasunori Mahata +Yazhong Liu +Yestin Sun +Yi EungJun +Yibai Zhang +Yihang Ho +Ying Li +Yohei Ueda +Yong Tang +Yongzhi Pan +Yosef Fertel +You-Sheng Yang (楊有勝) +Youcef YEKHLEF +Yu Changchun +Yu Chengxia +Yu Peng +Yu-Ju Hong +Yuan Sun +Yuanhong Peng +Yuhao Fang +Yunxiang Huang +Yurii Rashkovskii +Yves Junqueira +Zac Dover +Zach Borboa +Zachary Jaffee +Zain Memon +Zaiste! +Zane DeGraffenried +Zefan Li +Zen Lin(Zhinan Lin) +Zhang Kun +Zhang Wei +Zhang Wentao +ZhangHang +zhangxianwei +Zhenan Ye <21551168@zju.edu.cn> +zhenghenghuo +Zhenkun Bi +Zhou Hao +Zhu Guihua +Zhu Kunjia +Zhuoyun Wei +Zilin Du +zimbatm +Ziming Dong +ZJUshuaizhou <21551191@zju.edu.cn> +zmarouf +Zoltan Tombol +Zou Yu +zqh +Zuhayr Elahi +Zunayed Ali +Álex González +Álvaro Lázaro +Átila Camurça Alves +尹吉峰 +徐俊杰 +慕陶 +搏通 +黄艳红00139573 diff --git a/vendor/github.com/docker/docker/LICENSE b/vendor/github.com/docker/docker/LICENSE new file mode 100644 index 0000000000..9c8e20ab85 --- /dev/null +++ b/vendor/github.com/docker/docker/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2017 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/docker/docker/NOTICE b/vendor/github.com/docker/docker/NOTICE new file mode 100644 index 0000000000..0c74e15b05 --- /dev/null +++ b/vendor/github.com/docker/docker/NOTICE @@ -0,0 +1,19 @@ +Docker +Copyright 2012-2017 Docker, Inc. + +This product includes software developed at Docker, Inc. (https://www.docker.com). + +This product contains software (https://github.com/kr/pty) developed +by Keith Rarick, licensed under the MIT License. + +The following is courtesy of our legal counsel: + + +Use and transfer of Docker may be subject to certain restrictions by the +United States and other governments. +It is your responsibility to ensure that your use and/or transfer does not +violate applicable laws. + +For more information, please see https://www.bis.doc.gov + +See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. diff --git a/vendor/github.com/docker/docker/contrib/syntax/vim/LICENSE b/vendor/github.com/docker/docker/contrib/syntax/vim/LICENSE new file mode 100644 index 0000000000..e67cdabd22 --- /dev/null +++ b/vendor/github.com/docker/docker/contrib/syntax/vim/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 Honza Pokorny +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/docker/docker/docs/static_files/contributors.png b/vendor/github.com/docker/docker/docs/static_files/contributors.png new file mode 100644 index 0000000000..63c0a0c09b Binary files /dev/null and b/vendor/github.com/docker/docker/docs/static_files/contributors.png differ diff --git a/vendor/github.com/docker/docker/hack/generate-authors.sh b/vendor/github.com/docker/docker/hack/generate-authors.sh new file mode 100755 index 0000000000..680bdb7b3f --- /dev/null +++ b/vendor/github.com/docker/docker/hack/generate-authors.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e + +cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.." + +# see also ".mailmap" for how email addresses and names are deduplicated + +{ + cat <<-'EOH' + # This file lists all individuals having contributed content to the repository. + # For how it is generated, see `hack/generate-authors.sh`. + EOH + echo + git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf +} > AUTHORS diff --git a/vendor/github.com/docker/docker/integration-cli/fixtures/https/ca.pem b/vendor/github.com/docker/docker/integration-cli/fixtures/https/ca.pem new file mode 120000 index 0000000000..70a3e6ce54 --- /dev/null +++ b/vendor/github.com/docker/docker/integration-cli/fixtures/https/ca.pem @@ -0,0 +1 @@ +../../../integration/testdata/https/ca.pem \ No newline at end of file diff --git a/vendor/github.com/docker/docker/integration-cli/fixtures/https/client-cert.pem b/vendor/github.com/docker/docker/integration-cli/fixtures/https/client-cert.pem new file mode 120000 index 0000000000..458882026e --- /dev/null +++ b/vendor/github.com/docker/docker/integration-cli/fixtures/https/client-cert.pem @@ -0,0 +1 @@ +../../../integration/testdata/https/client-cert.pem \ No newline at end of file diff --git a/vendor/github.com/docker/docker/integration-cli/fixtures/https/client-key.pem b/vendor/github.com/docker/docker/integration-cli/fixtures/https/client-key.pem new file mode 120000 index 0000000000..d5f6bbee57 --- /dev/null +++ b/vendor/github.com/docker/docker/integration-cli/fixtures/https/client-key.pem @@ -0,0 +1 @@ +../../../integration/testdata/https/client-key.pem \ No newline at end of file diff --git a/vendor/github.com/docker/docker/integration-cli/fixtures/https/server-cert.pem b/vendor/github.com/docker/docker/integration-cli/fixtures/https/server-cert.pem new file mode 120000 index 0000000000..c18601067a --- /dev/null +++ b/vendor/github.com/docker/docker/integration-cli/fixtures/https/server-cert.pem @@ -0,0 +1 @@ +../../../integration/testdata/https/server-cert.pem \ No newline at end of file diff --git a/vendor/github.com/docker/docker/integration-cli/fixtures/https/server-key.pem b/vendor/github.com/docker/docker/integration-cli/fixtures/https/server-key.pem new file mode 120000 index 0000000000..48b9c2df65 --- /dev/null +++ b/vendor/github.com/docker/docker/integration-cli/fixtures/https/server-key.pem @@ -0,0 +1 @@ +../../../integration/testdata/https/server-key.pem \ No newline at end of file diff --git a/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE new file mode 100644 index 0000000000..b9fbf3c98f --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2014-2017 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD new file mode 100644 index 0000000000..4c056c5ed2 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD @@ -0,0 +1,27 @@ +Copyright (c) 2014-2017 The Docker & Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/docker/docker/pkg/term/ascii.go b/vendor/github.com/docker/docker/pkg/term/ascii.go new file mode 100644 index 0000000000..87bca8d4ac --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/ascii.go @@ -0,0 +1,66 @@ +package term // import "github.com/docker/docker/pkg/term" + +import ( + "fmt" + "strings" +) + +// ASCII list the possible supported ASCII key sequence +var ASCII = []string{ + "ctrl-@", + "ctrl-a", + "ctrl-b", + "ctrl-c", + "ctrl-d", + "ctrl-e", + "ctrl-f", + "ctrl-g", + "ctrl-h", + "ctrl-i", + "ctrl-j", + "ctrl-k", + "ctrl-l", + "ctrl-m", + "ctrl-n", + "ctrl-o", + "ctrl-p", + "ctrl-q", + "ctrl-r", + "ctrl-s", + "ctrl-t", + "ctrl-u", + "ctrl-v", + "ctrl-w", + "ctrl-x", + "ctrl-y", + "ctrl-z", + "ctrl-[", + "ctrl-\\", + "ctrl-]", + "ctrl-^", + "ctrl-_", +} + +// ToBytes converts a string representing a suite of key-sequence to the corresponding ASCII code. +func ToBytes(keys string) ([]byte, error) { + codes := []byte{} +next: + for _, key := range strings.Split(keys, ",") { + if len(key) != 1 { + for code, ctrl := range ASCII { + if ctrl == key { + codes = append(codes, byte(code)) + continue next + } + } + if key == "DEL" { + codes = append(codes, 127) + } else { + return nil, fmt.Errorf("Unknown character: '%s'", key) + } + } else { + codes = append(codes, key[0]) + } + } + return codes, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/proxy.go b/vendor/github.com/docker/docker/pkg/term/proxy.go new file mode 100644 index 0000000000..da733e5848 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/proxy.go @@ -0,0 +1,78 @@ +package term // import "github.com/docker/docker/pkg/term" + +import ( + "io" +) + +// EscapeError is special error which returned by a TTY proxy reader's Read() +// method in case its detach escape sequence is read. +type EscapeError struct{} + +func (EscapeError) Error() string { + return "read escape sequence" +} + +// escapeProxy is used only for attaches with a TTY. It is used to proxy +// stdin keypresses from the underlying reader and look for the passed in +// escape key sequence to signal a detach. +type escapeProxy struct { + escapeKeys []byte + escapeKeyPos int + r io.Reader +} + +// NewEscapeProxy returns a new TTY proxy reader which wraps the given reader +// and detects when the specified escape keys are read, in which case the Read +// method will return an error of type EscapeError. +func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader { + return &escapeProxy{ + escapeKeys: escapeKeys, + r: r, + } +} + +func (r *escapeProxy) Read(buf []byte) (int, error) { + nr, err := r.r.Read(buf) + + if len(r.escapeKeys) == 0 { + return nr, err + } + + preserve := func() { + // this preserves the original key presses in the passed in buffer + nr += r.escapeKeyPos + preserve := make([]byte, 0, r.escapeKeyPos+len(buf)) + preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...) + preserve = append(preserve, buf...) + r.escapeKeyPos = 0 + copy(buf[0:nr], preserve) + } + + if nr != 1 || err != nil { + if r.escapeKeyPos > 0 { + preserve() + } + return nr, err + } + + if buf[0] != r.escapeKeys[r.escapeKeyPos] { + if r.escapeKeyPos > 0 { + preserve() + } + return nr, nil + } + + if r.escapeKeyPos == len(r.escapeKeys)-1 { + return 0, EscapeError{} + } + + // Looks like we've got an escape key, but we need to match again on the next + // read. + // Store the current escape key we found so we can look for the next one on + // the next read. + // Since this is an escape key, make sure we don't let the caller read it + // If later on we find that this is not the escape sequence, we'll add the + // keys back + r.escapeKeyPos++ + return nr - r.escapeKeyPos, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/tc.go b/vendor/github.com/docker/docker/pkg/term/tc.go new file mode 100644 index 0000000000..01bcaa8abb --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/tc.go @@ -0,0 +1,20 @@ +// +build !windows + +package term // import "github.com/docker/docker/pkg/term" + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +func tcget(fd uintptr, p *Termios) syscall.Errno { + _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p))) + return err +} + +func tcset(fd uintptr, p *Termios) syscall.Errno { + _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p))) + return err +} diff --git a/vendor/github.com/docker/docker/pkg/term/term.go b/vendor/github.com/docker/docker/pkg/term/term.go new file mode 100644 index 0000000000..0589a95519 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/term.go @@ -0,0 +1,124 @@ +// +build !windows + +// Package term provides structures and helper functions to work with +// terminal (state, sizes). +package term // import "github.com/docker/docker/pkg/term" + +import ( + "errors" + "fmt" + "io" + "os" + "os/signal" + + "golang.org/x/sys/unix" +) + +var ( + // ErrInvalidState is returned if the state of the terminal is invalid. + ErrInvalidState = errors.New("Invalid terminal state") +) + +// State represents the state of the terminal. +type State struct { + termios Termios +} + +// Winsize represents the size of the terminal window. +type Winsize struct { + Height uint16 + Width uint16 + x uint16 + y uint16 +} + +// StdStreams returns the standard streams (stdin, stdout, stderr). +func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { + return os.Stdin, os.Stdout, os.Stderr +} + +// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal. +func GetFdInfo(in interface{}) (uintptr, bool) { + var inFd uintptr + var isTerminalIn bool + if file, ok := in.(*os.File); ok { + inFd = file.Fd() + isTerminalIn = IsTerminal(inFd) + } + return inFd, isTerminalIn +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd uintptr) bool { + var termios Termios + return tcget(fd, &termios) == 0 +} + +// RestoreTerminal restores the terminal connected to the given file descriptor +// to a previous state. +func RestoreTerminal(fd uintptr, state *State) error { + if state == nil { + return ErrInvalidState + } + if err := tcset(fd, &state.termios); err != 0 { + return err + } + return nil +} + +// SaveState saves the state of the terminal connected to the given file descriptor. +func SaveState(fd uintptr) (*State, error) { + var oldState State + if err := tcget(fd, &oldState.termios); err != 0 { + return nil, err + } + + return &oldState, nil +} + +// DisableEcho applies the specified state to the terminal connected to the file +// descriptor, with echo disabled. +func DisableEcho(fd uintptr, state *State) error { + newState := state.termios + newState.Lflag &^= unix.ECHO + + if err := tcset(fd, &newState); err != 0 { + return err + } + handleInterrupt(fd, state) + return nil +} + +// SetRawTerminal puts the terminal connected to the given file descriptor into +// raw mode and returns the previous state. On UNIX, this puts both the input +// and output into raw mode. On Windows, it only puts the input into raw mode. +func SetRawTerminal(fd uintptr) (*State, error) { + oldState, err := MakeRaw(fd) + if err != nil { + return nil, err + } + handleInterrupt(fd, oldState) + return oldState, err +} + +// SetRawTerminalOutput puts the output of terminal connected to the given file +// descriptor into raw mode. On UNIX, this does nothing and returns nil for the +// state. On Windows, it disables LF -> CRLF translation. +func SetRawTerminalOutput(fd uintptr) (*State, error) { + return nil, nil +} + +func handleInterrupt(fd uintptr, state *State) { + sigchan := make(chan os.Signal, 1) + signal.Notify(sigchan, os.Interrupt) + go func() { + for range sigchan { + // quit cleanly and the new terminal item is on a new line + fmt.Println() + signal.Stop(sigchan) + close(sigchan) + RestoreTerminal(fd, state) + os.Exit(1) + } + }() +} diff --git a/vendor/github.com/docker/docker/pkg/term/term_windows.go b/vendor/github.com/docker/docker/pkg/term/term_windows.go new file mode 100644 index 0000000000..64ead3c53b --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/term_windows.go @@ -0,0 +1,228 @@ +package term // import "github.com/docker/docker/pkg/term" + +import ( + "io" + "os" + "os/signal" + "syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE + + "github.com/Azure/go-ansiterm/winterm" + "github.com/docker/docker/pkg/term/windows" +) + +// State holds the console mode for the terminal. +type State struct { + mode uint32 +} + +// Winsize is used for window size. +type Winsize struct { + Height uint16 + Width uint16 +} + +// vtInputSupported is true if winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported by the console +var vtInputSupported bool + +// StdStreams returns the standard streams (stdin, stdout, stderr). +func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { + // Turn on VT handling on all std handles, if possible. This might + // fail, in which case we will fall back to terminal emulation. + var emulateStdin, emulateStdout, emulateStderr bool + fd := os.Stdin.Fd() + if mode, err := winterm.GetConsoleMode(fd); err == nil { + // Validate that winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it. + if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil { + emulateStdin = true + } else { + vtInputSupported = true + } + // Unconditionally set the console mode back even on failure because SetConsoleMode + // remembers invalid bits on input handles. + winterm.SetConsoleMode(fd, mode) + } + + fd = os.Stdout.Fd() + if mode, err := winterm.GetConsoleMode(fd); err == nil { + // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it. + if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil { + emulateStdout = true + } else { + winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING) + } + } + + fd = os.Stderr.Fd() + if mode, err := winterm.GetConsoleMode(fd); err == nil { + // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it. + if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil { + emulateStderr = true + } else { + winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING) + } + } + + if os.Getenv("ConEmuANSI") == "ON" || os.Getenv("ConsoleZVersion") != "" { + // The ConEmu and ConsoleZ terminals emulate ANSI on output streams well. + emulateStdin = true + emulateStdout = false + emulateStderr = false + } + + // Temporarily use STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and + // STD_ERROR_HANDLE from syscall rather than x/sys/windows as long as + // go-ansiterm hasn't switch to x/sys/windows. + // TODO: switch back to x/sys/windows once go-ansiterm has switched + if emulateStdin { + stdIn = windowsconsole.NewAnsiReader(syscall.STD_INPUT_HANDLE) + } else { + stdIn = os.Stdin + } + + if emulateStdout { + stdOut = windowsconsole.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE) + } else { + stdOut = os.Stdout + } + + if emulateStderr { + stdErr = windowsconsole.NewAnsiWriter(syscall.STD_ERROR_HANDLE) + } else { + stdErr = os.Stderr + } + + return +} + +// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal. +func GetFdInfo(in interface{}) (uintptr, bool) { + return windowsconsole.GetHandleInfo(in) +} + +// GetWinsize returns the window size based on the specified file descriptor. +func GetWinsize(fd uintptr) (*Winsize, error) { + info, err := winterm.GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil, err + } + + winsize := &Winsize{ + Width: uint16(info.Window.Right - info.Window.Left + 1), + Height: uint16(info.Window.Bottom - info.Window.Top + 1), + } + + return winsize, nil +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd uintptr) bool { + return windowsconsole.IsConsole(fd) +} + +// RestoreTerminal restores the terminal connected to the given file descriptor +// to a previous state. +func RestoreTerminal(fd uintptr, state *State) error { + return winterm.SetConsoleMode(fd, state.mode) +} + +// SaveState saves the state of the terminal connected to the given file descriptor. +func SaveState(fd uintptr) (*State, error) { + mode, e := winterm.GetConsoleMode(fd) + if e != nil { + return nil, e + } + + return &State{mode: mode}, nil +} + +// DisableEcho disables echo for the terminal connected to the given file descriptor. +// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx +func DisableEcho(fd uintptr, state *State) error { + mode := state.mode + mode &^= winterm.ENABLE_ECHO_INPUT + mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT + err := winterm.SetConsoleMode(fd, mode) + if err != nil { + return err + } + + // Register an interrupt handler to catch and restore prior state + restoreAtInterrupt(fd, state) + return nil +} + +// SetRawTerminal puts the terminal connected to the given file descriptor into +// raw mode and returns the previous state. On UNIX, this puts both the input +// and output into raw mode. On Windows, it only puts the input into raw mode. +func SetRawTerminal(fd uintptr) (*State, error) { + state, err := MakeRaw(fd) + if err != nil { + return nil, err + } + + // Register an interrupt handler to catch and restore prior state + restoreAtInterrupt(fd, state) + return state, err +} + +// SetRawTerminalOutput puts the output of terminal connected to the given file +// descriptor into raw mode. On UNIX, this does nothing and returns nil for the +// state. On Windows, it disables LF -> CRLF translation. +func SetRawTerminalOutput(fd uintptr) (*State, error) { + state, err := SaveState(fd) + if err != nil { + return nil, err + } + + // Ignore failures, since winterm.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this + // version of Windows. + winterm.SetConsoleMode(fd, state.mode|winterm.DISABLE_NEWLINE_AUTO_RETURN) + return state, err +} + +// MakeRaw puts the terminal (Windows Console) connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be restored. +func MakeRaw(fd uintptr) (*State, error) { + state, err := SaveState(fd) + if err != nil { + return nil, err + } + + mode := state.mode + + // See + // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx + + // Disable these modes + mode &^= winterm.ENABLE_ECHO_INPUT + mode &^= winterm.ENABLE_LINE_INPUT + mode &^= winterm.ENABLE_MOUSE_INPUT + mode &^= winterm.ENABLE_WINDOW_INPUT + mode &^= winterm.ENABLE_PROCESSED_INPUT + + // Enable these modes + mode |= winterm.ENABLE_EXTENDED_FLAGS + mode |= winterm.ENABLE_INSERT_MODE + mode |= winterm.ENABLE_QUICK_EDIT_MODE + if vtInputSupported { + mode |= winterm.ENABLE_VIRTUAL_TERMINAL_INPUT + } + + err = winterm.SetConsoleMode(fd, mode) + if err != nil { + return nil, err + } + return state, nil +} + +func restoreAtInterrupt(fd uintptr, state *State) { + sigchan := make(chan os.Signal, 1) + signal.Notify(sigchan, os.Interrupt) + + go func() { + _ = <-sigchan + RestoreTerminal(fd, state) + os.Exit(0) + }() +} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_bsd.go b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go new file mode 100644 index 0000000000..48b16f5203 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go @@ -0,0 +1,42 @@ +// +build darwin freebsd openbsd netbsd + +package term // import "github.com/docker/docker/pkg/term" + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +const ( + getTermios = unix.TIOCGETA + setTermios = unix.TIOCSETA +) + +// Termios is the Unix API for terminal I/O. +type Termios unix.Termios + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + var oldState State + if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { + return nil, err + } + + newState := oldState.termios + newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) + newState.Oflag &^= unix.OPOST + newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) + newState.Cflag &^= (unix.CSIZE | unix.PARENB) + newState.Cflag |= unix.CS8 + newState.Cc[unix.VMIN] = 1 + newState.Cc[unix.VTIME] = 0 + + if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { + return nil, err + } + + return &oldState, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_linux.go b/vendor/github.com/docker/docker/pkg/term/termios_linux.go new file mode 100644 index 0000000000..6d4c63fdb7 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/termios_linux.go @@ -0,0 +1,39 @@ +package term // import "github.com/docker/docker/pkg/term" + +import ( + "golang.org/x/sys/unix" +) + +const ( + getTermios = unix.TCGETS + setTermios = unix.TCSETS +) + +// Termios is the Unix API for terminal I/O. +type Termios unix.Termios + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + termios, err := unix.IoctlGetTermios(int(fd), getTermios) + if err != nil { + return nil, err + } + + var oldState State + oldState.termios = Termios(*termios) + + termios.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) + termios.Oflag &^= unix.OPOST + termios.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) + termios.Cflag &^= (unix.CSIZE | unix.PARENB) + termios.Cflag |= unix.CS8 + termios.Cc[unix.VMIN] = 1 + termios.Cc[unix.VTIME] = 0 + + if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil { + return nil, err + } + return &oldState, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go new file mode 100644 index 0000000000..1d7c452cc8 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go @@ -0,0 +1,263 @@ +// +build windows + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "bytes" + "errors" + "fmt" + "io" + "os" + "strings" + "unsafe" + + ansiterm "github.com/Azure/go-ansiterm" + "github.com/Azure/go-ansiterm/winterm" +) + +const ( + escapeSequence = ansiterm.KEY_ESC_CSI +) + +// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation. +type ansiReader struct { + file *os.File + fd uintptr + buffer []byte + cbBuffer int + command []byte +} + +// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a +// Windows console input handle. +func NewAnsiReader(nFile int) io.ReadCloser { + initLogger() + file, fd := winterm.GetStdFile(nFile) + return &ansiReader{ + file: file, + fd: fd, + command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), + buffer: make([]byte, 0), + } +} + +// Close closes the wrapped file. +func (ar *ansiReader) Close() (err error) { + return ar.file.Close() +} + +// Fd returns the file descriptor of the wrapped file. +func (ar *ansiReader) Fd() uintptr { + return ar.fd +} + +// Read reads up to len(p) bytes of translated input events into p. +func (ar *ansiReader) Read(p []byte) (int, error) { + if len(p) == 0 { + return 0, nil + } + + // Previously read bytes exist, read as much as we can and return + if len(ar.buffer) > 0 { + logger.Debugf("Reading previously cached bytes") + + originalLength := len(ar.buffer) + copiedLength := copy(p, ar.buffer) + + if copiedLength == originalLength { + ar.buffer = make([]byte, 0, len(p)) + } else { + ar.buffer = ar.buffer[copiedLength:] + } + + logger.Debugf("Read from cache p[%d]: % x", copiedLength, p) + return copiedLength, nil + } + + // Read and translate key events + events, err := readInputEvents(ar.fd, len(p)) + if err != nil { + return 0, err + } else if len(events) == 0 { + logger.Debug("No input events detected") + return 0, nil + } + + keyBytes := translateKeyEvents(events, []byte(escapeSequence)) + + // Save excess bytes and right-size keyBytes + if len(keyBytes) > len(p) { + logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p)) + ar.buffer = keyBytes[len(p):] + keyBytes = keyBytes[:len(p)] + } else if len(keyBytes) == 0 { + logger.Debug("No key bytes returned from the translator") + return 0, nil + } + + copiedLength := copy(p, keyBytes) + if copiedLength != len(keyBytes) { + return 0, errors.New("unexpected copy length encountered") + } + + logger.Debugf("Read p[%d]: % x", copiedLength, p) + logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes) + return copiedLength, nil +} + +// readInputEvents polls until at least one event is available. +func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) { + // Determine the maximum number of records to retrieve + // -- Cast around the type system to obtain the size of a single INPUT_RECORD. + // unsafe.Sizeof requires an expression vs. a type-reference; the casting + // tricks the type system into believing it has such an expression. + recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes))))) + countRecords := maxBytes / recordSize + if countRecords > ansiterm.MAX_INPUT_EVENTS { + countRecords = ansiterm.MAX_INPUT_EVENTS + } else if countRecords == 0 { + countRecords = 1 + } + logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize) + + // Wait for and read input events + events := make([]winterm.INPUT_RECORD, countRecords) + nEvents := uint32(0) + eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE) + if err != nil { + return nil, err + } + + if eventsExist { + err = winterm.ReadConsoleInput(fd, events, &nEvents) + if err != nil { + return nil, err + } + } + + // Return a slice restricted to the number of returned records + logger.Debugf("[windows] readInputEvents: Read %v events", nEvents) + return events[:nEvents], nil +} + +// KeyEvent Translation Helpers + +var arrowKeyMapPrefix = map[uint16]string{ + winterm.VK_UP: "%s%sA", + winterm.VK_DOWN: "%s%sB", + winterm.VK_RIGHT: "%s%sC", + winterm.VK_LEFT: "%s%sD", +} + +var keyMapPrefix = map[uint16]string{ + winterm.VK_UP: "\x1B[%sA", + winterm.VK_DOWN: "\x1B[%sB", + winterm.VK_RIGHT: "\x1B[%sC", + winterm.VK_LEFT: "\x1B[%sD", + winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1 + winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4 + winterm.VK_INSERT: "\x1B[2%s~", + winterm.VK_DELETE: "\x1B[3%s~", + winterm.VK_PRIOR: "\x1B[5%s~", + winterm.VK_NEXT: "\x1B[6%s~", + winterm.VK_F1: "", + winterm.VK_F2: "", + winterm.VK_F3: "\x1B[13%s~", + winterm.VK_F4: "\x1B[14%s~", + winterm.VK_F5: "\x1B[15%s~", + winterm.VK_F6: "\x1B[17%s~", + winterm.VK_F7: "\x1B[18%s~", + winterm.VK_F8: "\x1B[19%s~", + winterm.VK_F9: "\x1B[20%s~", + winterm.VK_F10: "\x1B[21%s~", + winterm.VK_F11: "\x1B[23%s~", + winterm.VK_F12: "\x1B[24%s~", +} + +// translateKeyEvents converts the input events into the appropriate ANSI string. +func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte { + var buffer bytes.Buffer + for _, event := range events { + if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 { + buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence)) + } + } + + return buffer.Bytes() +} + +// keyToString maps the given input event record to the corresponding string. +func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string { + if keyEvent.UnicodeChar == 0 { + return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence) + } + + _, alt, control := getControlKeys(keyEvent.ControlKeyState) + if control { + // TODO(azlinux): Implement following control sequences + // -D Signals the end of input from the keyboard; also exits current shell. + // -H Deletes the first character to the left of the cursor. Also called the ERASE key. + // -Q Restarts printing after it has been stopped with -s. + // -S Suspends printing on the screen (does not stop the program). + // -U Deletes all characters on the current line. Also called the KILL key. + // -E Quits current command and creates a core + + } + + // +Key generates ESC N Key + if !control && alt { + return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar)) + } + + return string(keyEvent.UnicodeChar) +} + +// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string. +func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) string { + shift, alt, control := getControlKeys(controlState) + modifier := getControlKeysModifier(shift, alt, control) + + if format, ok := arrowKeyMapPrefix[key]; ok { + return fmt.Sprintf(format, escapeSequence, modifier) + } + + if format, ok := keyMapPrefix[key]; ok { + return fmt.Sprintf(format, modifier) + } + + return "" +} + +// getControlKeys extracts the shift, alt, and ctrl key states. +func getControlKeys(controlState uint32) (shift, alt, control bool) { + shift = 0 != (controlState & winterm.SHIFT_PRESSED) + alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED)) + control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED)) + return shift, alt, control +} + +// getControlKeysModifier returns the ANSI modifier for the given combination of control keys. +func getControlKeysModifier(shift, alt, control bool) string { + if shift && alt && control { + return ansiterm.KEY_CONTROL_PARAM_8 + } + if alt && control { + return ansiterm.KEY_CONTROL_PARAM_7 + } + if shift && control { + return ansiterm.KEY_CONTROL_PARAM_6 + } + if control { + return ansiterm.KEY_CONTROL_PARAM_5 + } + if shift && alt { + return ansiterm.KEY_CONTROL_PARAM_4 + } + if alt { + return ansiterm.KEY_CONTROL_PARAM_3 + } + if shift { + return ansiterm.KEY_CONTROL_PARAM_2 + } + return "" +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go new file mode 100644 index 0000000000..7799a03fc5 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go @@ -0,0 +1,64 @@ +// +build windows + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "io" + "os" + + ansiterm "github.com/Azure/go-ansiterm" + "github.com/Azure/go-ansiterm/winterm" +) + +// ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation. +type ansiWriter struct { + file *os.File + fd uintptr + infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO + command []byte + escapeSequence []byte + inAnsiSequence bool + parser *ansiterm.AnsiParser +} + +// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a +// Windows console output handle. +func NewAnsiWriter(nFile int) io.Writer { + initLogger() + file, fd := winterm.GetStdFile(nFile) + info, err := winterm.GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil + } + + parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file)) + logger.Infof("newAnsiWriter: parser %p", parser) + + aw := &ansiWriter{ + file: file, + fd: fd, + infoReset: info, + command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), + escapeSequence: []byte(ansiterm.KEY_ESC_CSI), + parser: parser, + } + + logger.Infof("newAnsiWriter: aw.parser %p", aw.parser) + logger.Infof("newAnsiWriter: %v", aw) + return aw +} + +func (aw *ansiWriter) Fd() uintptr { + return aw.fd +} + +// Write writes len(p) bytes from p to the underlying data stream. +func (aw *ansiWriter) Write(p []byte) (total int, err error) { + if len(p) == 0 { + return 0, nil + } + + logger.Infof("Write: % x", p) + logger.Infof("Write: %s", string(p)) + return aw.parser.Parse(p) +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/console.go b/vendor/github.com/docker/docker/pkg/term/windows/console.go new file mode 100644 index 0000000000..5274019758 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/console.go @@ -0,0 +1,35 @@ +// +build windows + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "os" + + "github.com/Azure/go-ansiterm/winterm" +) + +// GetHandleInfo returns file descriptor and bool indicating whether the file is a console. +func GetHandleInfo(in interface{}) (uintptr, bool) { + switch t := in.(type) { + case *ansiReader: + return t.Fd(), true + case *ansiWriter: + return t.Fd(), true + } + + var inFd uintptr + var isTerminal bool + + if file, ok := in.(*os.File); ok { + inFd = file.Fd() + isTerminal = IsConsole(inFd) + } + return inFd, isTerminal +} + +// IsConsole returns true if the given file descriptor is a Windows Console. +// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console. +func IsConsole(fd uintptr) bool { + _, e := winterm.GetConsoleMode(fd) + return e == nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/windows.go b/vendor/github.com/docker/docker/pkg/term/windows/windows.go new file mode 100644 index 0000000000..3e5593ca6a --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/windows.go @@ -0,0 +1,33 @@ +// These files implement ANSI-aware input and output streams for use by the Docker Windows client. +// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create +// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls. + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "io/ioutil" + "os" + "sync" + + "github.com/Azure/go-ansiterm" + "github.com/sirupsen/logrus" +) + +var logger *logrus.Logger +var initOnce sync.Once + +func initLogger() { + initOnce.Do(func() { + logFile := ioutil.Discard + + if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { + logFile, _ = os.Create("ansiReaderWriter.log") + } + + logger = &logrus.Logger{ + Out: logFile, + Formatter: new(logrus.TextFormatter), + Level: logrus.DebugLevel, + } + }) +} diff --git a/vendor/github.com/docker/docker/pkg/term/winsize.go b/vendor/github.com/docker/docker/pkg/term/winsize.go new file mode 100644 index 0000000000..a19663ad83 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/winsize.go @@ -0,0 +1,20 @@ +// +build !windows + +package term // import "github.com/docker/docker/pkg/term" + +import ( + "golang.org/x/sys/unix" +) + +// GetWinsize returns the window size based on the specified file descriptor. +func GetWinsize(fd uintptr) (*Winsize, error) { + uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) + ws := &Winsize{Height: uws.Row, Width: uws.Col, x: uws.Xpixel, y: uws.Ypixel} + return ws, err +} + +// SetWinsize tries to set the specified window size for the specified file descriptor. +func SetWinsize(fd uintptr, ws *Winsize) error { + uws := &unix.Winsize{Row: ws.Height, Col: ws.Width, Xpixel: ws.x, Ypixel: ws.y} + return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, uws) +} diff --git a/vendor/github.com/docker/docker/project/CONTRIBUTING.md b/vendor/github.com/docker/docker/project/CONTRIBUTING.md new file mode 120000 index 0000000000..44fcc63439 --- /dev/null +++ b/vendor/github.com/docker/docker/project/CONTRIBUTING.md @@ -0,0 +1 @@ +../CONTRIBUTING.md \ No newline at end of file diff --git a/vendor/github.com/docker/go-units/CONTRIBUTING.md b/vendor/github.com/docker/go-units/CONTRIBUTING.md new file mode 100644 index 0000000000..9ea86d784e --- /dev/null +++ b/vendor/github.com/docker/go-units/CONTRIBUTING.md @@ -0,0 +1,67 @@ +# Contributing to go-units + +Want to hack on go-units? Awesome! Here are instructions to get you started. + +go-units is a part of the [Docker](https://www.docker.com) project, and follows +the same rules and principles. If you're already familiar with the way +Docker does things, you'll feel right at home. + +Otherwise, go read Docker's +[contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md), +[issue triaging](https://github.com/docker/docker/blob/master/project/ISSUE-TRIAGE.md), +[review process](https://github.com/docker/docker/blob/master/project/REVIEWING.md) and +[branches and tags](https://github.com/docker/docker/blob/master/project/BRANCHES-AND-TAGS.md). + +### Sign your work + +The sign-off is a simple line at the end of the explanation for the patch. Your +signature certifies that you wrote the patch or otherwise have the right to pass +it on as an open-source patch. The rules are pretty simple: if you can certify +the below (from [developercertificate.org](http://developercertificate.org/)): + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +Then you just add a line to every git commit message: + + Signed-off-by: Joe Smith + +Use your real name (sorry, no pseudonyms or anonymous contributions.) + +If you set your `user.name` and `user.email` git configs, you can sign your +commit automatically with `git commit -s`. diff --git a/vendor/github.com/docker/go-units/LICENSE.code b/vendor/github.com/docker/go-units/LICENSE.code new file mode 100644 index 0000000000..b55b37bc31 --- /dev/null +++ b/vendor/github.com/docker/go-units/LICENSE.code @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2015 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/docker/go-units/LICENSE.docs b/vendor/github.com/docker/go-units/LICENSE.docs new file mode 100644 index 0000000000..e26cd4fc8e --- /dev/null +++ b/vendor/github.com/docker/go-units/LICENSE.docs @@ -0,0 +1,425 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/vendor/github.com/docker/go-units/MAINTAINERS b/vendor/github.com/docker/go-units/MAINTAINERS new file mode 100644 index 0000000000..477be8b214 --- /dev/null +++ b/vendor/github.com/docker/go-units/MAINTAINERS @@ -0,0 +1,27 @@ +# go-connections maintainers file +# +# This file describes who runs the docker/go-connections project and how. +# This is a living document - if you see something out of date or missing, speak up! +# +# It is structured to be consumable by both humans and programs. +# To extract its contents programmatically, use any TOML-compliant parser. +# +# This file is compiled into the MAINTAINERS file in docker/opensource. +# +[Org] + [Org."Core maintainers"] + people = [ + "calavera", + ] + +[people] + +# A reference list of all people associated with the project. +# All other sections should refer to people by their canonical key +# in the people section. + + # ADD YOURSELF HERE IN ALPHABETICAL ORDER + [people.calavera] + Name = "David Calavera" + Email = "david.calavera@gmail.com" + GitHub = "calavera" diff --git a/vendor/github.com/docker/go-units/README.md b/vendor/github.com/docker/go-units/README.md new file mode 100644 index 0000000000..3ce4d79dac --- /dev/null +++ b/vendor/github.com/docker/go-units/README.md @@ -0,0 +1,18 @@ +[![GoDoc](https://godoc.org/github.com/docker/go-units?status.svg)](https://godoc.org/github.com/docker/go-units) + +# Introduction + +go-units is a library to transform human friendly measurements into machine friendly values. + +## Usage + +See the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation. + +## Copyright and license + +Copyright © 2015 Docker, Inc. All rights reserved, except as follows. Code +is released under the Apache 2.0 license. The README.md file, and files in the +"docs" folder are licensed under the Creative Commons Attribution 4.0 +International License under the terms and conditions set forth in the file +"LICENSE.docs". You may obtain a duplicate copy of the same license, titled +CC-BY-SA-4.0, at http://creativecommons.org/licenses/by/4.0/. diff --git a/vendor/github.com/docker/go-units/circle.yml b/vendor/github.com/docker/go-units/circle.yml new file mode 100644 index 0000000000..9043b35478 --- /dev/null +++ b/vendor/github.com/docker/go-units/circle.yml @@ -0,0 +1,11 @@ +dependencies: + post: + # install golint + - go get github.com/golang/lint/golint + +test: + pre: + # run analysis before tests + - go vet ./... + - test -z "$(golint ./... | tee /dev/stderr)" + - test -z "$(gofmt -s -l . | tee /dev/stderr)" diff --git a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go b/vendor/github.com/docker/go-units/duration.go similarity index 79% rename from Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go rename to vendor/github.com/docker/go-units/duration.go index cd33121496..c219a8a968 100644 --- a/Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go +++ b/vendor/github.com/docker/go-units/duration.go @@ -1,3 +1,5 @@ +// Package units provides helper function to parse and print size and time units +// in human-readable format. package units import ( @@ -6,7 +8,7 @@ import ( ) // HumanDuration returns a human-readable approximation of a duration -// (eg. "About a minute", "4 hours ago", etc.) +// (eg. "About a minute", "4 hours ago", etc.). func HumanDuration(d time.Duration) string { if seconds := int(d.Seconds()); seconds < 1 { return "Less than a second" @@ -27,5 +29,5 @@ func HumanDuration(d time.Duration) string { } else if hours < 24*365*2 { return fmt.Sprintf("%d months", hours/24/30) } - return fmt.Sprintf("%f years", d.Hours()/24/365) + return fmt.Sprintf("%d years", int(d.Hours())/24/365) } diff --git a/vendor/github.com/docker/go-units/size.go b/vendor/github.com/docker/go-units/size.go new file mode 100644 index 0000000000..3b59daff31 --- /dev/null +++ b/vendor/github.com/docker/go-units/size.go @@ -0,0 +1,95 @@ +package units + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +// See: http://en.wikipedia.org/wiki/Binary_prefix +const ( + // Decimal + + KB = 1000 + MB = 1000 * KB + GB = 1000 * MB + TB = 1000 * GB + PB = 1000 * TB + + // Binary + + KiB = 1024 + MiB = 1024 * KiB + GiB = 1024 * MiB + TiB = 1024 * GiB + PiB = 1024 * TiB +) + +type unitMap map[string]int64 + +var ( + decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} + binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} + sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`) +) + +var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} +var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} + +// CustomSize returns a human-readable approximation of a size +// using custom format. +func CustomSize(format string, size float64, base float64, _map []string) string { + i := 0 + for size >= base { + size = size / base + i++ + } + return fmt.Sprintf(format, size, _map[i]) +} + +// HumanSize returns a human-readable approximation of a size +// capped at 4 valid numbers (eg. "2.746 MB", "796 KB"). +func HumanSize(size float64) string { + return CustomSize("%.4g %s", size, 1000.0, decimapAbbrs) +} + +// BytesSize returns a human-readable size in bytes, kibibytes, +// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB"). +func BytesSize(size float64) string { + return CustomSize("%.4g %s", size, 1024.0, binaryAbbrs) +} + +// FromHumanSize returns an integer from a human-readable specification of a +// size using SI standard (eg. "44kB", "17MB"). +func FromHumanSize(size string) (int64, error) { + return parseSize(size, decimalMap) +} + +// RAMInBytes parses a human-readable string representing an amount of RAM +// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and +// returns the number of bytes, or -1 if the string is unparseable. +// Units are case-insensitive, and the 'b' suffix is optional. +func RAMInBytes(size string) (int64, error) { + return parseSize(size, binaryMap) +} + +// Parses the human-readable size string into the amount it represents. +func parseSize(sizeStr string, uMap unitMap) (int64, error) { + matches := sizeRegex.FindStringSubmatch(sizeStr) + if len(matches) != 3 { + return -1, fmt.Errorf("invalid size: '%s'", sizeStr) + } + + size, err := strconv.ParseInt(matches[1], 10, 0) + if err != nil { + return -1, err + } + + unitPrefix := strings.ToLower(matches[2]) + if mul, ok := uMap[unitPrefix]; ok { + size *= mul + } + + return size, nil +} diff --git a/vendor/github.com/docker/go-units/ulimit.go b/vendor/github.com/docker/go-units/ulimit.go new file mode 100644 index 0000000000..5ac7fd825f --- /dev/null +++ b/vendor/github.com/docker/go-units/ulimit.go @@ -0,0 +1,118 @@ +package units + +import ( + "fmt" + "strconv" + "strings" +) + +// Ulimit is a human friendly version of Rlimit. +type Ulimit struct { + Name string + Hard int64 + Soft int64 +} + +// Rlimit specifies the resource limits, such as max open files. +type Rlimit struct { + Type int `json:"type,omitempty"` + Hard uint64 `json:"hard,omitempty"` + Soft uint64 `json:"soft,omitempty"` +} + +const ( + // magic numbers for making the syscall + // some of these are defined in the syscall package, but not all. + // Also since Windows client doesn't get access to the syscall package, need to + // define these here + rlimitAs = 9 + rlimitCore = 4 + rlimitCPU = 0 + rlimitData = 2 + rlimitFsize = 1 + rlimitLocks = 10 + rlimitMemlock = 8 + rlimitMsgqueue = 12 + rlimitNice = 13 + rlimitNofile = 7 + rlimitNproc = 6 + rlimitRss = 5 + rlimitRtprio = 14 + rlimitRttime = 15 + rlimitSigpending = 11 + rlimitStack = 3 +) + +var ulimitNameMapping = map[string]int{ + //"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container. + "core": rlimitCore, + "cpu": rlimitCPU, + "data": rlimitData, + "fsize": rlimitFsize, + "locks": rlimitLocks, + "memlock": rlimitMemlock, + "msgqueue": rlimitMsgqueue, + "nice": rlimitNice, + "nofile": rlimitNofile, + "nproc": rlimitNproc, + "rss": rlimitRss, + "rtprio": rlimitRtprio, + "rttime": rlimitRttime, + "sigpending": rlimitSigpending, + "stack": rlimitStack, +} + +// ParseUlimit parses and returns a Ulimit from the specified string. +func ParseUlimit(val string) (*Ulimit, error) { + parts := strings.SplitN(val, "=", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("invalid ulimit argument: %s", val) + } + + if _, exists := ulimitNameMapping[parts[0]]; !exists { + return nil, fmt.Errorf("invalid ulimit type: %s", parts[0]) + } + + var ( + soft int64 + hard = &soft // default to soft in case no hard was set + temp int64 + err error + ) + switch limitVals := strings.Split(parts[1], ":"); len(limitVals) { + case 2: + temp, err = strconv.ParseInt(limitVals[1], 10, 64) + if err != nil { + return nil, err + } + hard = &temp + fallthrough + case 1: + soft, err = strconv.ParseInt(limitVals[0], 10, 64) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]) + } + + if soft > *hard { + return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard) + } + + return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil +} + +// GetRlimit returns the RLimit corresponding to Ulimit. +func (u *Ulimit) GetRlimit() (*Rlimit, error) { + t, exists := ulimitNameMapping[u.Name] + if !exists { + return nil, fmt.Errorf("invalid ulimit name %s", u.Name) + } + + return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil +} + +func (u *Ulimit) String() string { + return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard) +} diff --git a/vendor/github.com/exoscale/egoscale/.codeclimate.yml b/vendor/github.com/exoscale/egoscale/.codeclimate.yml new file mode 100644 index 0000000000..dc2b688a41 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.codeclimate.yml @@ -0,0 +1,31 @@ +version: "2" + +checks: + argument-count: + enabled: false + complex-logic: + enabled: false + file-lines: + enabled: false + method-complexity: + enabled: false + method-count: + enabled: false + method-lines: + enabled: false + nested-control-flow: + enabled: false + return-statements: + enabled: false + similar-code: + enabled: false + identical-code: + enabled: false + +plugins: + gofmt: + enabled: true + golint: + enabled: true + govet: + enabled: true diff --git a/vendor/github.com/exoscale/egoscale/.gitignore b/vendor/github.com/exoscale/egoscale/.gitignore new file mode 100644 index 0000000000..43a3cef8e6 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.gitignore @@ -0,0 +1,4 @@ +build/ +exo +vendor +.gopath diff --git a/vendor/github.com/exoscale/egoscale/.travis.yml b/vendor/github.com/exoscale/egoscale/.travis.yml new file mode 100644 index 0000000000..9dd0251b32 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.travis.yml @@ -0,0 +1,29 @@ +language: go + +dist: trusty + +go: +- 1.8 +- 1.9 +- "1.10" +- tip + +env: + - DEP_VERSION=0.4.1 + +cache: apt + +before_install: + - curl -L -s https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 -o $GOPATH/bin/dep + - chmod +x $GOPATH/bin/dep + - npm i -g codeclimate-test-reporter + +script: + - dep ensure + - go test -race -coverprofile=coverage.out -covermode=atomic . + +after_success: + - > + if [ "${TRAVIS_GO_VERSION}" = "1.10" ]; then + codeclimate-test-reporter < coverage.out; + fi diff --git a/vendor/github.com/exoscale/egoscale/AUTHORS b/vendor/github.com/exoscale/egoscale/AUTHORS new file mode 100644 index 0000000000..ae4d8f83b9 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/AUTHORS @@ -0,0 +1,8 @@ +Pierre-Yves Ritschard +Vincent Bernat +Chris Baumbauer +Marc-Aurèle Brothier +Sebastien Goasguen +Yoan Blanc +Stefano Marengo +Pierre-Emmanuel Jacquier diff --git a/vendor/github.com/exoscale/egoscale/CHANGELOG.md b/vendor/github.com/exoscale/egoscale/CHANGELOG.md new file mode 100644 index 0000000000..246ff34040 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/CHANGELOG.md @@ -0,0 +1,193 @@ +Changelog +========= + +0.9.23 +------ + +- feat: `booleanResponse` supports true booleans: https://github.com/apache/cloudstack/pull/2428 + +0.9.22 +------ + +- feat: `ListUsers`, `CreateUser`, `UpdateUser` +- feat: `ListResourceDetails` +- feat: `SecurityGroup` helper `RuleByID` +- feat: `Sign` signs the payload +- feat: `UpdateNetworkOffering` +- feat: `GetVirtualMachineUserData` +- feat: `EnableAccount` and `DisableAccount` (admin stuff) +- feat: `AsyncRequest` and `AsyncRequestWithContext` to examine the polling +- fix: `AuthorizeSecurityGroupIngress` support for ICMPv6 +- change: move `APIName()` into the `Client`, nice godoc +- change: `Payload` doesn't sign the request anymore +- change: `Client` exposes more of its underlying data +- change: requests are sent as GET unless it body size is too big + +0.9.21 +------ + +- feat: `Network` is `Listable` +- feat: `Zone` is `Gettable` +- feat: `Client.Payload` to help preview the HTTP parameters +- feat: generate command utility +- fix: `CreateSnapshot` was missing the `Name` attribute +- fix: `ListSnapshots` was missing the `IDs` attribute +- fix: `ListZones` was missing the `NetworkType` attribute +- fix: `ListAsyncJobs` was missing the `ListAll` attribute +- change: ICMP Type/Code are uint8 and TCP/UDP port are uint16 + +0.9.20 +------ + +- feat: `Template` is `Listable` +- feat: `IPAddress` is `Listable` +- change: `List` and `Paginate` return pointers +- fix: `Template` was missing `tags` + +0.9.19 +------ + +- feat: `SSHKeyPair` is `Listable` + +0.9.18 +------ + +- feat: `VirtualMachine` is `Listable` +- feat: new `Client.Paginate` and `Client.PaginateWithContext` +- change: the inner logic of `Listable` +- remove: not working `Client.AsyncList` + +0.9.17 +------ + +- fix: `AuthorizeSecurityGroup(In|E)gress` startport may be zero + +0.9.16 +------ + +- feat: new `Listable` interface +- feat: `Nic` is `Listable` +- feat: `Volume` is `Listable` +- feat: `Zone` is `Listable` +- feat: `AffinityGroup` is `Listable` +- remove: deprecated methods `ListNics`, `AddIPToNic`, and `RemoveIPFromNic` +- remove: deprecated method `GetRootVolumeForVirtualMachine` + +0.9.15 +------ + +- feat: `IPAddress` is `Gettable` and `Deletable` +- fix: serialization of *bool + +0.9.14 +------ + +- fix: `GetVMPassword` response +- remove: deprecated `GetTopology`, `GetImages`, and al + +0.9.13 +------ + +- feat: IP4 and IP6 flags to DeployVirtualMachine +- feat: add ActivateIP6 +- fix: error message was gobbled on 40x + +0.9.12 +------ + +- feat: add `BooleanRequestWithContext` +- feat: add `client.Get`, `client.GetWithContext` to fetch a resource +- feat: add `cleint.Delete`, `client.DeleteWithContext` to delete a resource +- feat: `SSHKeyPair` is `Gettable` and `Deletable` +- feat: `VirtualMachine` is `Gettable` and `Deletable` +- feat: `AffinityGroup` is `Gettable` and `Deletable` +- feat: `SecurityGroup` is `Gettable` and `Deletable` +- remove: deprecated methods `CreateAffinityGroup`, `DeleteAffinityGroup` +- remove: deprecated methods `CreateKeypair`, `DeleteKeypair`, `RegisterKeypair` +- remove: deprecated method `GetSecurityGroupID` + +0.9.11 +------ + +- feat: CloudStack API name is now public `APIName()` +- feat: enforce the mutual exclusivity of some fields +- feat: add `context.Context` to `RequestWithContext` +- change: `AsyncRequest` and `BooleanAsyncRequest` are gone, use `Request` and `BooleanRequest` instead. +- change: `AsyncInfo` is no more + +0.9.10 +------ + +- fix: typo made ListAll required in ListPublicIPAddresses +- fix: all bool are now *bool, respecting CS default value +- feat: (*VM).DefaultNic() to obtain the main Nic + +0.9.9 +----- + +- fix: affinity groups virtualmachineIds attribute +- fix: uuidList is not a list of strings + +0.9.8 +----- + +- feat: add RootDiskSize to RestoreVirtualMachine +- fix: monotonic polling using Context + +0.9.7 +----- + +- feat: add Taggable interface to expose ResourceType +- feat: add (Create|Update|Delete|List)InstanceGroup(s) +- feat: add RegisterUserKeys +- feat: add ListResourceLimits +- feat: add ListAccounts + +0.9.6 +----- + +- fix: update UpdateVirtualMachine userdata +- fix: Network's name/displaytext might be empty + +0.9.5 +----- + +- fix: serialization of slice + +0.9.4 +----- + +- fix: constants + +0.9.3 +----- + +- change: userdata expects a string +- change: no pointer in sub-struct's + +0.9.2 +----- + +- bug: createNetwork is a sync call +- bug: typo in listVirtualMachines' domainid +- bug: serialization of map[string], e.g. UpdateVirtualMachine +- change: IPAddress's use net.IP type +- feat: helpers VM.NicsByType, VM.NicByNetworkID, VM.NicByID +- feat: addition of CloudStack ApiErrorCode constants + +0.9.1 +----- + +- bug: sync calls returns succes as a string rather than a bool +- change: unexport BooleanResponse types +- feat: original CloudStack error response can be obtained + +0.9.0 +----- + +Big refactoring, addition of the documentation, compliance to golint. + +0.1.0 +----- + +Initial library diff --git a/vendor/github.com/exoscale/egoscale/Gopkg.lock b/vendor/github.com/exoscale/egoscale/Gopkg.lock new file mode 100644 index 0000000000..ba27dd9bb3 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/Gopkg.lock @@ -0,0 +1,225 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "cloud.google.com/go" + packages = [ + "compute/metadata", + "iam", + "internal", + "internal/optional", + "internal/trace", + "internal/version", + "storage" + ] + revision = "4b98a6370e36d7a85192e7bad08a4ebd82eac2a8" + version = "v0.20.0" + +[[projects]] + name = "github.com/golang/protobuf" + packages = [ + "proto", + "protoc-gen-go/descriptor", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "925541529c1fa6821df4e44ce2723319eb2be768" + version = "v1.0.0" + +[[projects]] + name = "github.com/googleapis/gax-go" + packages = ["."] + revision = "317e0006254c44a0ac427cc52a0e083ff0b9622f" + version = "v2.0.0" + +[[projects]] + branch = "master" + name = "github.com/jinzhu/copier" + packages = ["."] + revision = "7e38e58719c33e0d44d585c4ab477a30f8cb82dd" + +[[projects]] + name = "go.opencensus.io" + packages = [ + "exporter/stackdriver/propagation", + "internal", + "internal/tagencoding", + "plugin/ochttp", + "plugin/ochttp/propagation/b3", + "stats", + "stats/internal", + "stats/view", + "tag", + "trace", + "trace/propagation" + ] + revision = "076344b67ac19bcb8096c4b12440c3cf92ac3927" + version = "v0.7.0" + +[[projects]] + branch = "master" + name = "golang.org/x/build" + packages = ["autocertcache"] + revision = "943bea333176fcb634d5b9ce74c90a595a7ec9fa" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = [ + "acme", + "acme/autocert" + ] + revision = "b2aa35443fbc700ab74c586ae79b81c171851023" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "context/ctxhttp", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "lex/httplex", + "trace" + ] + revision = "b68f30494add4df6bd8ef5e82803f308e7f7c59c" + +[[projects]] + branch = "master" + name = "golang.org/x/oauth2" + packages = [ + ".", + "google", + "internal", + "jws", + "jwt" + ] + revision = "921ae394b9430ed4fb549668d7b087601bd60a81" + +[[projects]] + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable" + ] + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + branch = "master" + name = "golang.org/x/tools" + packages = [ + "go/ast/astutil", + "go/buildutil", + "go/gccgoexportdata", + "go/internal/gccgoimporter", + "go/loader", + "go/types/typeutil", + "refactor/importgraph", + "refactor/rename", + "refactor/satisfy" + ] + revision = "ac136b6c2db7c4d43955e4bc7174db36dc0539c0" + +[[projects]] + branch = "master" + name = "google.golang.org/api" + packages = [ + "gensupport", + "googleapi", + "googleapi/internal/uritemplates", + "googleapi/transport", + "internal", + "iterator", + "option", + "storage/v1", + "transport/http" + ] + revision = "3097bf831ede4a24e08a3316254e29ca726383e3" + +[[projects]] + name = "google.golang.org/appengine" + packages = [ + ".", + "datastore", + "internal", + "internal/app_identity", + "internal/base", + "internal/datastore", + "internal/log", + "internal/memcache", + "internal/modules", + "internal/remote_api", + "internal/urlfetch", + "internal/user", + "log", + "memcache", + "urlfetch", + "user" + ] + revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "google.golang.org/genproto" + packages = [ + "googleapis/api/annotations", + "googleapis/iam/v1", + "googleapis/rpc/code", + "googleapis/rpc/status" + ] + revision = "35de2414665fc36f56b72d982c5af480d86de5ab" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "balancer/base", + "balancer/roundrobin", + "codes", + "connectivity", + "credentials", + "encoding", + "encoding/proto", + "grpclb/grpc_lb_v1/messages", + "grpclog", + "internal", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "resolver/dns", + "resolver/passthrough", + "stats", + "status", + "tap", + "transport" + ] + revision = "1e2570b1b19ade82d8dbb31bba4e65e9f9ef5b34" + version = "v1.11.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "e8cec537f196899b1252944d23dac756bfc3462f9aad743526d2bcf01e03f5c7" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/exoscale/egoscale/Gopkg.toml b/vendor/github.com/exoscale/egoscale/Gopkg.toml new file mode 100644 index 0000000000..4c94bd4fc6 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/Gopkg.toml @@ -0,0 +1,8 @@ +[[constraint]] + name = "github.com/jinzhu/copier" + branch = "master" + +[prune] + non-go = true + go-tests = true + unused-packages = true diff --git a/vendor/github.com/exoscale/egoscale/LICENSE b/vendor/github.com/exoscale/egoscale/LICENSE new file mode 100644 index 0000000000..327ecb8235 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2014 exoscale(tm) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/exoscale/egoscale/Makefile b/vendor/github.com/exoscale/egoscale/Makefile new file mode 100644 index 0000000000..5032ca51c4 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/Makefile @@ -0,0 +1,27 @@ +PKG=github.com/exoscale/egoscale + +GOPATH=$(CURDIR)/.gopath +DEP=$(GOPATH)/bin/dep + +export GOPATH + +$(GOPATH)/src/$(PKG): + mkdir -p $(GOPATH) + go get -u github.com/golang/dep/cmd/dep + mkdir -p $(shell dirname $(GOPATH)/src/$(PKG)) + ln -sf ../../../.. $(GOPATH)/src/$(PKG) + +.PHONY: deps +deps: $(GOPATH)/src/$(PKG) + (cd $(GOPATH)/src/$(PKG) && \ + $(DEP) ensure) + +.PHONY: deps-update +deps-update: deps + (cd $(GOPATH)/src/$(PKG) && \ + $(DEP) ensure -update) + +.PHONY: clean +clean: + $(RM) -r $(DEST) + go clean diff --git a/vendor/github.com/exoscale/egoscale/README.md b/vendor/github.com/exoscale/egoscale/README.md new file mode 100644 index 0000000000..1be67a0934 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/README.md @@ -0,0 +1,19 @@ +egoscale: exoscale driver for golang +==================================== + + + +[![Build Status](https://travis-ci.org/exoscale/egoscale.svg?branch=master)](https://travis-ci.org/exoscale/egoscale) +[![Maintainability](https://api.codeclimate.com/v1/badges/fcab3b624b7d3ca96a9d/maintainability)](https://codeclimate.com/github/exoscale/egoscale/maintainability) +[![Test Coverage](https://api.codeclimate.com/v1/badges/fcab3b624b7d3ca96a9d/test_coverage)](https://codeclimate.com/github/exoscale/egoscale/test_coverage) +[![GoDoc](https://godoc.org/github.com/exoscale/egoscale?status.svg)](https://godoc.org/github.com/exoscale/egoscale) +[![Go Report Card](https://goreportcard.com/badge/github.com/exoscale/egoscale)](https://goreportcard.com/report/github.com/exoscale/egoscale) + +An API wrapper for the CloudStack based [Exoscale public cloud](https://www.exoscale.com). + +### License + +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 diff --git a/vendor/github.com/exoscale/egoscale/accounts.go b/vendor/github.com/exoscale/egoscale/accounts.go new file mode 100644 index 0000000000..dde0819e7e --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/accounts.go @@ -0,0 +1,25 @@ +package egoscale + +func (*ListAccounts) name() string { + return "listAccounts" +} + +func (*ListAccounts) response() interface{} { + return new(ListAccountsResponse) +} + +func (*EnableAccount) name() string { + return "enableAccount" +} + +func (*EnableAccount) response() interface{} { + return new(EnableAccountResponse) +} + +func (*DisableAccount) name() string { + return "disableAccount" +} + +func (*DisableAccount) asyncResponse() interface{} { + return new(DisableAccountResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/accounts_type.go b/vendor/github.com/exoscale/egoscale/accounts_type.go new file mode 100644 index 0000000000..ae8bed2153 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/accounts_type.go @@ -0,0 +1,123 @@ +package egoscale + +// AccountType represents the type of an Account +// +// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/4.8/accounts.html#accounts-users-and-domains +type AccountType int16 + +//go:generate stringer -type AccountType +const ( + // UserAccount represents a User + UserAccount AccountType = iota + // AdminAccount represents an Admin + AdminAccount + // DomainAdminAccount represents a Domain Admin + DomainAdminAccount +) + +// Account provides the detailed account information +type Account struct { + AccountDetails map[string]string `json:"accountdetails,omitempty" doc:"details for the account"` + AccountType AccountType `json:"accounttype,omitempty" doc:"account type (admin, domain-admin, user)"` + CPUAvailable string `json:"cpuavailable,omitempty" doc:"the total number of cpu cores available to be created for this account"` + CPULimit string `json:"cpulimit,omitempty" doc:"the total number of cpu cores the account can own"` + CPUTotal int64 `json:"cputotal,omitempty" doc:"the total number of cpu cores owned by account"` + DefaultZoneID string `json:"defaultzoneid,omitempty" doc:"the default zone of the account"` + Domain string `json:"domain,omitempty" doc:"name of the Domain the account belongs too"` + DomainID string `json:"domainid,omitempty" doc:"id of the Domain the account belongs too"` + EipLimit string `json:"eiplimit,omitempty" doc:"the total number of public elastic ip addresses this account can acquire"` + Groups []string `json:"groups,omitempty" doc:"the list of acl groups that account belongs to"` + ID string `json:"id,omitempty" doc:"the id of the account"` + IPAvailable string `json:"ipavailable,omitempty" doc:"the total number of public ip addresses available for this account to acquire"` + IPLimit string `json:"iplimit,omitempty" doc:"the total number of public ip addresses this account can acquire"` + IPTotal int64 `json:"iptotal,omitempty" doc:"the total number of public ip addresses allocated for this account"` + IsCleanupRequired bool `json:"iscleanuprequired,omitempty" doc:"true if the account requires cleanup"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if account is default, false otherwise"` + MemoryAvailable string `json:"memoryavailable,omitempty" doc:"the total memory (in MB) available to be created for this account"` + MemoryLimit string `json:"memorylimit,omitempty" doc:"the total memory (in MB) the account can own"` + MemoryTotal int64 `json:"memorytotal,omitempty" doc:"the total memory (in MB) owned by account"` + Name string `json:"name,omitempty" doc:"the name of the account"` + NetworkAvailable string `json:"networkavailable,omitempty" doc:"the total number of networks available to be created for this account"` + NetworkDomain string `json:"networkdomain,omitempty" doc:"the network domain"` + NetworkLimit string `json:"networklimit,omitempty" doc:"the total number of networks the account can own"` + NetworkTotal int64 `json:"networktotal,omitempty" doc:"the total number of networks owned by account"` + PrimaryStorageAvailable string `json:"primarystorageavailable,omitempty" doc:"the total primary storage space (in GiB) available to be used for this account"` + PrimaryStorageLimit string `json:"primarystoragelimit,omitempty" doc:"the total primary storage space (in GiB) the account can own"` + PrimaryStorageTotal int64 `json:"primarystoragetotal,omitempty" doc:"the total primary storage space (in GiB) owned by account"` + ProjectAvailable string `json:"projectavailable,omitempty" doc:"the total number of projects available for administration by this account"` + ProjectLimit string `json:"projectlimit,omitempty" doc:"the total number of projects the account can own"` + ProjectTotal int64 `json:"projecttotal,omitempty" doc:"the total number of projects being administrated by this account"` + SecondaryStorageAvailable string `json:"secondarystorageavailable,omitempty" doc:"the total secondary storage space (in GiB) available to be used for this account"` + SecondaryStorageLimit string `json:"secondarystoragelimit,omitempty" doc:"the total secondary storage space (in GiB) the account can own"` + SecondaryStorageTotal int64 `json:"secondarystoragetotal,omitempty" doc:"the total secondary storage space (in GiB) owned by account"` + SMTP bool `json:"smtp,omitempty" doc:"if SMTP outbound is allowed"` + SnapshotAvailable string `json:"snapshotavailable,omitempty" doc:"the total number of snapshots available for this account"` + SnapshotLimit string `json:"snapshotlimit,omitempty" doc:"the total number of snapshots which can be stored by this account"` + SnapshotTotal int64 `json:"snapshottotal,omitempty" doc:"the total number of snapshots stored by this account"` + State string `json:"state,omitempty" doc:"the state of the account"` + TemplateAvailable string `json:"templateavailable,omitempty" doc:"the total number of templates available to be created by this account"` + TemplateLimit string `json:"templatelimit,omitempty" doc:"the total number of templates which can be created by this account"` + TemplateTotal int64 `json:"templatetotal,omitempty" doc:"the total number of templates which have been created by this account"` + User []User `json:"user,omitempty" doc:"the list of users associated with account"` + VMAvailable string `json:"vmavailable,omitempty" doc:"the total number of virtual machines available for this account to acquire"` + VMLimit string `json:"vmlimit,omitempty" doc:"the total number of virtual machines that can be deployed by this account"` + VMRunning int `json:"vmrunning,omitempty" doc:"the total number of virtual machines running for this account"` + VMStopped int `json:"vmstopped,omitempty" doc:"the total number of virtual machines stopped for this account"` + VMTotal int64 `json:"vmtotal,omitempty" doc:"the total number of virtual machines deployed by this account"` + VolumeAvailable string `json:"volumeavailable,omitempty" doc:"the total volume available for this account"` + VolumeLimit string `json:"volumelimit,omitempty" doc:"the total volume which can be used by this account"` + VolumeTotal int64 `json:"volumetotal,omitempty" doc:"the total volume being used by this account"` + VpcAvailable string `json:"vpcavailable,omitempty" doc:"the total number of vpcs available to be created for this account"` + VpcLimit string `json:"vpclimit,omitempty" doc:"the total number of vpcs the account can own"` + VpcTotal int64 `json:"vpctotal,omitempty" doc:"the total number of vpcs owned by account"` +} + +// ListAccounts represents a query to display the accounts +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listAccounts.html +type ListAccounts struct { + AccountType AccountType `json:"accounttype,omitempty" doc:"list accounts by account type. Valid account types are 1 (admin), 2 (domain-admin), and 0 (user)."` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + ID string `json:"id,omitempty" doc:"list account by account ID"` + IsCleanUpRequired *bool `json:"iscleanuprequired,omitempty" doc:"list accounts by cleanuprequred attribute (values are true or false)"` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Name string `json:"name,omitempty" doc:"list account by account name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + State string `json:"state,omitempty" doc:"list accounts by state. Valid states are enabled, disabled, and locked."` +} + +// ListAccountsResponse represents a list of accounts +type ListAccountsResponse struct { + Count int `json:"count"` + Account []Account `json:"account"` +} + +// EnableAccount represents the activation of an account +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/enableAccount.html +type EnableAccount struct { + Account string `json:"account,omitempty" doc:"Enables specified account."` + DomainID string `json:"domainid,omitempty" doc:"Enables specified account in this domain."` + ID string `json:"id,omitempty" doc:"Account id"` +} + +// EnableAccountResponse represents the modified account +type EnableAccountResponse struct { + Account Account `json:"account"` +} + +// DisableAccount (Async) represents the deactivation of an account +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/disableAccount.html +type DisableAccount struct { + Lock *bool `json:"lock" doc:"If true, only lock the account; else disable the account"` + Account string `json:"account,omitempty" doc:"Disables specified account."` + DomainID string `json:"domainid,omitempty" doc:"Disables specified account in this domain."` + ID string `json:"id,omitempty" doc:"Account id"` +} + +// DisableAccountResponse represents the modified account +type DisableAccountResponse EnableAccountResponse diff --git a/vendor/github.com/exoscale/egoscale/accounttype_string.go b/vendor/github.com/exoscale/egoscale/accounttype_string.go new file mode 100644 index 0000000000..7d622a16c0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/accounttype_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type AccountType"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const _AccountType_name = "UserAccountAdminAccountDomainAdminAccount" + +var _AccountType_index = [...]uint8{0, 11, 23, 41} + +func (i AccountType) String() string { + if i < 0 || i >= AccountType(len(_AccountType_index)-1) { + return "AccountType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _AccountType_name[_AccountType_index[i]:_AccountType_index[i+1]] +} diff --git a/vendor/github.com/exoscale/egoscale/addresses.go b/vendor/github.com/exoscale/egoscale/addresses.go new file mode 100644 index 0000000000..5ce0b09df6 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/addresses.go @@ -0,0 +1,142 @@ +package egoscale + +import ( + "context" + "fmt" + + "github.com/jinzhu/copier" +) + +// Get fetches the resource +func (ipaddress *IPAddress) Get(ctx context.Context, client *Client) error { + if ipaddress.ID == "" && ipaddress.IPAddress == nil { + return fmt.Errorf("An IPAddress may only be searched using ID or IPAddress") + } + + req := &ListPublicIPAddresses{ + ID: ipaddress.ID, + IPAddress: ipaddress.IPAddress, + Account: ipaddress.Account, + DomainID: ipaddress.DomainID, + ProjectID: ipaddress.ProjectID, + ZoneID: ipaddress.ZoneID, + } + + if ipaddress.IsElastic { + req.IsElastic = &(ipaddress.IsElastic) + } + + resp, err := client.RequestWithContext(ctx, req) + if err != nil { + return err + } + + ips := resp.(*ListPublicIPAddressesResponse) + count := len(ips.PublicIPAddress) + if count == 0 { + return &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("PublicIPAddress not found. id: %s, ipaddress: %s", ipaddress.ID, ipaddress.IPAddress), + } + } else if count > 1 { + return fmt.Errorf("More than one PublicIPAddress was found") + } + + return copier.Copy(ipaddress, ips.PublicIPAddress[0]) +} + +// Delete removes the resource +func (ipaddress *IPAddress) Delete(ctx context.Context, client *Client) error { + if ipaddress.ID == "" { + return fmt.Errorf("An IPAddress may only be deleted using ID") + } + + return client.BooleanRequestWithContext(ctx, &DisassociateIPAddress{ + ID: ipaddress.ID, + }) +} + +// ResourceType returns the type of the resource +func (*IPAddress) ResourceType() string { + return "PublicIpAddress" +} + +// name returns the CloudStack API command name +func (*AssociateIPAddress) name() string { + return "associateIpAddress" +} + +func (*AssociateIPAddress) asyncResponse() interface{} { + return new(AssociateIPAddressResponse) +} + +// name returns the CloudStack API command name +func (*DisassociateIPAddress) name() string { + return "disassociateIpAddress" +} +func (*DisassociateIPAddress) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*UpdateIPAddress) name() string { + return "updateIpAddress" +} +func (*UpdateIPAddress) asyncResponse() interface{} { + return new(UpdateIPAddressResponse) +} + +// name returns the CloudStack API command name +func (*ListPublicIPAddresses) name() string { + return "listPublicIpAddresses" +} + +func (*ListPublicIPAddresses) response() interface{} { + return new(ListPublicIPAddressesResponse) +} + +// ListRequest builds the ListAdresses request +func (ipaddress *IPAddress) ListRequest() (ListCommand, error) { + req := &ListPublicIPAddresses{ + Account: ipaddress.Account, + AllocatedNetworkID: ipaddress.AssociatedNetworkID, + DomainID: ipaddress.DomainID, + ForDisplay: &ipaddress.ForDisplay, + //ForVirtualNetwork: ip.ForVirtualNetwork, change ForVirtualNetwork type for type bool + ID: ipaddress.ID, + IPAddress: ipaddress.IPAddress, + IsElastic: &ipaddress.IsElastic, + IsSourceNat: &ipaddress.IsSourceNat, + PhysicalNetworkID: ipaddress.PhysicalNetworkID, + ProjectID: ipaddress.ProjectID, + VlanID: ipaddress.VlanID, + VpcID: ipaddress.VpcID, + ZoneID: ipaddress.ZoneID, + } + + return req, nil +} + +// SetPage sets the current page +func (ls *ListPublicIPAddresses) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListPublicIPAddresses) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +func (*ListPublicIPAddresses) each(resp interface{}, callback IterateItemFunc) { + ips, ok := resp.(*ListPublicIPAddressesResponse) + if !ok { + callback(nil, fmt.Errorf("ListPublicIPAddressesResponse expected, got %t", resp)) + return + } + + for i := range ips.PublicIPAddress { + if !callback(&ips.PublicIPAddress[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/addresses_type.go b/vendor/github.com/exoscale/egoscale/addresses_type.go new file mode 100644 index 0000000000..0a4af86abf --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/addresses_type.go @@ -0,0 +1,115 @@ +package egoscale + +import ( + "net" +) + +// IPAddress represents an IP Address +type IPAddress struct { + ID string `json:"id"` + Account string `json:"account,omitempty"` + AllocatedAt string `json:"allocated,omitempty"` + AssociatedNetworkID string `json:"associatednetworkid,omitempty"` + AssociatedNetworkName string `json:"associatednetworkname,omitempty"` + DomainID string `json:"domainid,omitempty"` + DomainName string `json:"domainname,omitempty"` + ForDisplay bool `json:"fordisplay,omitempty"` + ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty"` + IPAddress net.IP `json:"ipaddress"` + IsElastic bool `json:"iselastic,omitempty"` + IsPortable bool `json:"isportable,omitempty"` + IsSourceNat bool `json:"issourcenat,omitempty"` + IsSystem bool `json:"issystem,omitempty"` + NetworkID string `json:"networkid,omitempty"` + PhysicalNetworkID string `json:"physicalnetworkid,omitempty"` + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Purpose string `json:"purpose,omitempty"` + State string `json:"state,omitempty"` + VirtualMachineDisplayName string `json:"virtualmachinedisplayname,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` + VirtualMachineName string `json:"virtualmachineName,omitempty"` + VlanID string `json:"vlanid,omitempty"` + VlanName string `json:"vlanname,omitempty"` + VMIPAddress net.IP `json:"vmipaddress,omitempty"` + VpcID string `json:"vpcid,omitempty"` + ZoneID string `json:"zoneid,omitempty"` + ZoneName string `json:"zonename,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + JobID string `json:"jobid,omitempty"` + JobStatus JobStatusType `json:"jobstatus,omitempty"` +} + +// AssociateIPAddress (Async) represents the IP creation +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/associateIpAddress.html +type AssociateIPAddress struct { + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + ForDisplay *bool `json:"fordisplay,omitempty"` + IsPortable *bool `json:"isportable,omitempty"` + NetworkdID string `json:"networkid,omitempty"` + ProjectID string `json:"projectid,omitempty"` + RegionID string `json:"regionid,omitempty"` + VpcID string `json:"vpcid,omitempty"` + ZoneID string `json:"zoneid,omitempty"` +} + +// AssociateIPAddressResponse represents the response to the creation of an IPAddress +type AssociateIPAddressResponse struct { + IPAddress IPAddress `json:"ipaddress"` +} + +// DisassociateIPAddress (Async) represents the IP deletion +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/disassociateIpAddress.html +type DisassociateIPAddress struct { + ID string `json:"id"` +} + +// UpdateIPAddress (Async) represents the IP modification +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/updateIpAddress.html +type UpdateIPAddress struct { + ID string `json:"id"` + CustomID string `json:"customid,omitempty"` // root only + ForDisplay *bool `json:"fordisplay,omitempty"` +} + +// UpdateIPAddressResponse represents the modified IP Address +type UpdateIPAddressResponse AssociateIPAddressResponse + +// ListPublicIPAddresses represents a search for public IP addresses +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listPublicIpAddresses.html +type ListPublicIPAddresses struct { + Account string `json:"account,omitempty"` // must be used with the DomainID + AllocatedOnly *bool `json:"allocatedonly,omitempty"` + AllocatedNetworkID string `json:"allocatednetworkid,omitempty"` + DomainID string `json:"domainid,omitempty"` + ForDisplay *bool `json:"fordisplay,omitempty"` + ForLoadBalancing *bool `json:"forloadbalancing,omitempty"` + ForVirtualNetwork string `json:"forvirtualnetwork,omitempty"` + ID string `json:"id,omitempty"` + IPAddress net.IP `json:"ipaddress,omitempty"` + IsElastic *bool `json:"iselastic,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + IsSourceNat *bool `json:"issourcenat,omitempty"` + IsStaticNat *bool `json:"isstaticnat,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + PhysicalNetworkID string `json:"physicalnetworkid,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + VlanID string `json:"vlanid,omitempty"` + VpcID string `json:"vpcid,omitempty"` + ZoneID string `json:"zoneid,omitempty"` +} + +// ListPublicIPAddressesResponse represents a list of public IP addresses +type ListPublicIPAddressesResponse struct { + Count int `json:"count"` + PublicIPAddress []IPAddress `json:"publicipaddress"` +} diff --git a/vendor/github.com/exoscale/egoscale/affinity_groups.go b/vendor/github.com/exoscale/egoscale/affinity_groups.go new file mode 100644 index 0000000000..5415911a06 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/affinity_groups.go @@ -0,0 +1,211 @@ +package egoscale + +import ( + "context" + "fmt" + "net/url" + + "github.com/jinzhu/copier" +) + +// AffinityGroup represents an (anti-)affinity group +// +// Affinity and Anti-Affinity groups provide a way to influence where VMs should run. +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#affinity-groups +type AffinityGroup struct { + ID string `json:"id,omitempty"` + Account string `json:"account,omitempty"` + Description string `json:"description,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Name string `json:"name,omitempty"` + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Type string `json:"type,omitempty"` + VirtualMachineIDs []string `json:"virtualmachineIds,omitempty"` // *I*ds is not a typo +} + +// AffinityGroupType represent an affinity group type +type AffinityGroupType struct { + Type string `json:"type"` +} + +// Get loads the given Affinity Group +func (ag *AffinityGroup) Get(ctx context.Context, client *Client) error { + if ag.ID == "" && ag.Name == "" { + return fmt.Errorf("An Affinity Group may only be searched using ID or Name") + } + + resp, err := client.RequestWithContext(ctx, &ListAffinityGroups{ + ID: ag.ID, + Name: ag.Name, + }) + + if err != nil { + return err + } + + ags := resp.(*ListAffinityGroupsResponse) + count := len(ags.AffinityGroup) + if count == 0 { + return &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("AffinityGroup not found id: %s, name: %s", ag.ID, ag.Name), + } + } else if count > 1 { + return fmt.Errorf("More than one Affinity Group was found. Query; id: %s, name: %s", ag.ID, ag.Name) + } + + return copier.Copy(ag, ags.AffinityGroup[0]) +} + +// Delete removes the given Affinity Group +func (ag *AffinityGroup) Delete(ctx context.Context, client *Client) error { + if ag.ID == "" && ag.Name == "" { + return fmt.Errorf("An Affinity Group may only be deleted using ID or Name") + } + + req := &DeleteAffinityGroup{ + Account: ag.Account, + DomainID: ag.DomainID, + ProjectID: ag.ProjectID, + } + + if ag.ID != "" { + req.ID = ag.ID + } else { + req.Name = ag.Name + } + + return client.BooleanRequestWithContext(ctx, req) +} + +// CreateAffinityGroup (Async) represents a new (anti-)affinity group +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createAffinityGroup.html +type CreateAffinityGroup struct { + Name string `json:"name"` + Type string `json:"type"` + Account string `json:"account,omitempty"` + Description string `json:"description,omitempty"` + DomainID string `json:"domainid,omitempty"` +} + +// name returns the CloudStack API command name +func (*CreateAffinityGroup) name() string { + return "createAffinityGroup" +} + +func (*CreateAffinityGroup) asyncResponse() interface{} { + return new(CreateAffinityGroupResponse) +} + +// CreateAffinityGroupResponse represents the response of the creation of an (anti-)affinity group +type CreateAffinityGroupResponse struct { + AffinityGroup AffinityGroup `json:"affinitygroup"` +} + +// UpdateVMAffinityGroup (Async) represents a modification of a (anti-)affinity group +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateVMAffinityGroup.html +type UpdateVMAffinityGroup struct { + ID string `json:"id"` + AffinityGroupIDs []string `json:"affinitygroupids,omitempty"` // mutually exclusive with names + AffinityGroupNames []string `json:"affinitygroupnames,omitempty"` // mutually exclusive with ids +} + +// name returns the CloudStack API command name +func (*UpdateVMAffinityGroup) name() string { + return "updateVMAffinityGroup" +} + +func (*UpdateVMAffinityGroup) asyncResponse() interface{} { + return new(UpdateVMAffinityGroupResponse) +} + +func (req *UpdateVMAffinityGroup) onBeforeSend(params *url.Values) error { + // Either AffinityGroupIDs or AffinityGroupNames must be set + if len(req.AffinityGroupIDs) == 0 && len(req.AffinityGroupNames) == 0 { + params.Set("affinitygroupids", "") + } + return nil +} + +// UpdateVMAffinityGroupResponse represents the new VM +type UpdateVMAffinityGroupResponse VirtualMachineResponse + +// DeleteAffinityGroup (Async) represents an (anti-)affinity group to be deleted +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteAffinityGroup.html +type DeleteAffinityGroup struct { + Account string `json:"account,omitempty"` // must be specified with DomainID + DomainID string `json:"domainid,omitempty"` + ID string `json:"id,omitempty"` // mutually exclusive with Name + Name string `json:"name,omitempty"` // mutually exclusive with ID + ProjectID string `json:"projectid,omitempty"` +} + +// name returns the CloudStack API command name +func (*DeleteAffinityGroup) name() string { + return "deleteAffinityGroup" +} + +func (*DeleteAffinityGroup) asyncResponse() interface{} { + return new(booleanResponse) +} + +// ListAffinityGroups represents an (anti-)affinity groups search +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listAffinityGroups.html +type ListAffinityGroups struct { + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Name string `json:"name,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + Type string `json:"type,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` +} + +// name returns the CloudStack API command name +func (*ListAffinityGroups) name() string { + return "listAffinityGroups" +} + +func (*ListAffinityGroups) response() interface{} { + return new(ListAffinityGroupsResponse) +} + +// ListAffinityGroupTypes represents an (anti-)affinity groups search +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listAffinityGroupTypes.html +type ListAffinityGroupTypes struct { + Keyword string `json:"keyword,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` +} + +// name returns the CloudStack API command name +func (*ListAffinityGroupTypes) name() string { + return "listAffinityGroupTypes" +} + +func (*ListAffinityGroupTypes) response() interface{} { + return new(ListAffinityGroupTypesResponse) +} + +// ListAffinityGroupsResponse represents a list of (anti-)affinity groups +type ListAffinityGroupsResponse struct { + Count int `json:"count"` + AffinityGroup []AffinityGroup `json:"affinitygroup"` +} + +// ListAffinityGroupTypesResponse represents a list of (anti-)affinity group types +type ListAffinityGroupTypesResponse struct { + Count int `json:"count"` + AffinityGroupType []AffinityGroupType `json:"affinitygrouptype"` +} diff --git a/vendor/github.com/exoscale/egoscale/apis.go b/vendor/github.com/exoscale/egoscale/apis.go new file mode 100644 index 0000000000..a6b099091a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/apis.go @@ -0,0 +1,9 @@ +package egoscale + +func (*ListAPIs) name() string { + return "listApis" +} + +func (*ListAPIs) response() interface{} { + return new(ListAPIsResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/apis_type.go b/vendor/github.com/exoscale/egoscale/apis_type.go new file mode 100644 index 0000000000..06b1b87248 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/apis_type.go @@ -0,0 +1,36 @@ +package egoscale + +// API represents an API service +type API struct { + Description string `json:"description,omitempty" doc:"description of the api"` + IsAsync bool `json:"isasync,omitempty" doc:"true if api is asynchronous"` + Name string `json:"name,omitempty" doc:"the name of the api command"` + Related string `json:"related,omitempty" doc:"comma separated related apis"` + Since string `json:"since,omitempty" doc:"version of CloudStack the api was introduced in"` + Type string `json:"type,omitempty" doc:"response field type"` + Params []APIParam `json:"params,omitempty" doc:"the list params the api accepts"` + Response []APIParam `json:"response,omitempty" doc:"api response fields"` +} + +// APIParam represents an API parameter field +type APIParam struct { + Description string `json:"description"` + Length int64 `json:"length"` + Name string `json:"name"` + Required bool `json:"required"` + Since string `json:"since"` + Type string `json:"type"` +} + +// ListAPIs represents a query to list the api +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listApis.html +type ListAPIs struct { + Name string `json:"name,omitempty" doc:"API name"` +} + +// ListAPIsResponse represents a list of API +type ListAPIsResponse struct { + Count int `json:"count"` + API []API `json:"api"` +} diff --git a/vendor/github.com/exoscale/egoscale/async_jobs.go b/vendor/github.com/exoscale/egoscale/async_jobs.go new file mode 100644 index 0000000000..2750c6a0af --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/async_jobs.go @@ -0,0 +1,49 @@ +package egoscale + +import "encoding/json" + +// QueryAsyncJobResult represents a query to fetch the status of async job +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/queryAsyncJobResult.html +type QueryAsyncJobResult struct { + JobID string `json:"jobid" doc:"the ID of the asychronous job"` +} + +// name returns the CloudStack API command name +func (*QueryAsyncJobResult) name() string { + return "queryAsyncJobResult" +} + +func (*QueryAsyncJobResult) response() interface{} { + return new(QueryAsyncJobResultResponse) +} + +// name returns the CloudStack API command name +func (*ListAsyncJobs) name() string { + return "listAsyncJobs" +} + +func (*ListAsyncJobs) response() interface{} { + return new(ListAsyncJobsResponse) +} + +//Response return response of AsyncJobResult from a given type +func (a *AsyncJobResult) Response(i interface{}) error { + if a.JobStatus == Failure { + return a.Error() + } + if a.JobStatus == Success { + if err := json.Unmarshal(*(a.JobResult), i); err != nil { + return err + } + } + return nil +} + +func (a *AsyncJobResult) Error() error { + r := new(ErrorResponse) + if e := json.Unmarshal(*a.JobResult, r); e != nil { + return e + } + return r +} diff --git a/vendor/github.com/exoscale/egoscale/async_jobs_type.go b/vendor/github.com/exoscale/egoscale/async_jobs_type.go new file mode 100644 index 0000000000..d241eae108 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/async_jobs_type.go @@ -0,0 +1,44 @@ +package egoscale + +import ( + "encoding/json" +) + +// AsyncJobResult represents an asynchronous job result +type AsyncJobResult struct { + AccountID string `json:"accountid"` + Cmd string `json:"cmd"` + Created string `json:"created"` + JobInstanceID string `json:"jobinstanceid,omitempty"` + JobInstanceType string `json:"jobinstancetype,omitempty"` + JobProcStatus int `json:"jobprocstatus"` + JobResult *json.RawMessage `json:"jobresult"` + JobResultCode int `json:"jobresultcode"` + JobResultType string `json:"jobresulttype"` + JobStatus JobStatusType `json:"jobstatus"` + UserID string `json:"userid"` + JobID string `json:"jobid"` +} + +// QueryAsyncJobResultResponse represents the current status of an asynchronous job +type QueryAsyncJobResultResponse AsyncJobResult + +// ListAsyncJobs list the asynchronous jobs +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listAsyncJobs.html +type ListAsyncJobs struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + StartDate string `json:"startdate,omitempty" doc:"the start date of the async job"` +} + +// ListAsyncJobsResponse represents a list of job results +type ListAsyncJobsResponse struct { + Count int `json:"count"` + AsyncJobs []AsyncJobResult `json:"asyncjobs"` +} diff --git a/vendor/github.com/exoscale/egoscale/client.go b/vendor/github.com/exoscale/egoscale/client.go new file mode 100644 index 0000000000..019f0d959a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/client.go @@ -0,0 +1,233 @@ +package egoscale + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + "time" +) + +// Get populates the given resource or fails +func (client *Client) Get(g Gettable) error { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.GetWithContext(ctx, g) +} + +// GetWithContext populates the given resource or fails +func (client *Client) GetWithContext(ctx context.Context, g Gettable) error { + return g.Get(ctx, client) +} + +// Delete removes the given resource of fails +func (client *Client) Delete(g Deletable) error { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.DeleteWithContext(ctx, g) +} + +// DeleteWithContext removes the given resource of fails +func (client *Client) DeleteWithContext(ctx context.Context, g Deletable) error { + return g.Delete(ctx, client) +} + +// List lists the given resource (and paginate till the end) +func (client *Client) List(g Listable) ([]interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.ListWithContext(ctx, g) +} + +// ListWithContext lists the given resources (and paginate till the end) +func (client *Client) ListWithContext(ctx context.Context, g Listable) ([]interface{}, error) { + s := make([]interface{}, 0) + + req, err := g.ListRequest() + if err != nil { + return s, err + } + + client.PaginateWithContext(ctx, req, func(item interface{}, e error) bool { + if item != nil { + s = append(s, item) + return true + } + err = e + return false + }) + + return s, err +} + +// AsyncListWithContext lists the given resources (and paginate till the end) +// +// +// // NB: goroutine may leak if not read until the end. Create a proper context! +// ctx, cancel := context.WithCancel(context.Background()) +// defer cancel() +// +// outChan, errChan := client.AsyncListWithContext(ctx, new(egoscale.VirtualMachine)) +// +// for { +// select { +// case i, ok := <- outChan: +// if ok { +// vm := i.(egoscale.VirtualMachine) +// // ... +// } else { +// outChan = nil +// } +// case err, ok := <- errChan: +// if ok { +// // do something +// } +// // Once an error has been received, you can expect the channels to be closed. +// errChan = nil +// } +// if errChan == nil && outChan == nil { +// break +// } +// } +// +func (client *Client) AsyncListWithContext(ctx context.Context, g Listable) (<-chan interface{}, <-chan error) { + outChan := make(chan interface{}, client.PageSize) + errChan := make(chan error) + + go func() { + defer close(outChan) + defer close(errChan) + + req, err := g.ListRequest() + if err != nil { + errChan <- err + return + } + + client.PaginateWithContext(ctx, req, func(item interface{}, e error) bool { + if item != nil { + outChan <- item + return true + } + errChan <- e + return false + }) + }() + + return outChan, errChan +} + +// Paginate runs the ListCommand and paginates +func (client *Client) Paginate(req ListCommand, callback IterateItemFunc) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + client.PaginateWithContext(ctx, req, callback) +} + +// PaginateWithContext runs the ListCommand as long as the ctx is valid +func (client *Client) PaginateWithContext(ctx context.Context, req ListCommand, callback IterateItemFunc) { + pageSize := client.PageSize + + page := 1 + + for { + req.SetPage(page) + req.SetPageSize(pageSize) + resp, err := client.RequestWithContext(ctx, req) + if err != nil { + callback(nil, err) + break + } + + size := 0 + didErr := false + req.each(resp, func(element interface{}, err error) bool { + // If the context was cancelled, kill it in flight + if e := ctx.Err(); e != nil { + element = nil + err = e + } + + if callback(element, err) { + size++ + return true + } + + didErr = true + return false + }) + + if size < pageSize || didErr { + break + } + + page++ + } +} + +// APIName returns the CloudStack name of the given command +func (client *Client) APIName(request Command) string { + return request.name() +} + +// Response returns the response structure of the given command +func (client *Client) Response(request Command) interface{} { + switch request.(type) { + case syncCommand: + return (request.(syncCommand)).response() + case AsyncCommand: + return (request.(AsyncCommand)).asyncResponse() + default: + panic(fmt.Errorf("The command %s is not a proper Sync or Async command", request.name())) + } +} + +// NewClientWithTimeout creates a CloudStack API client +// +// Timeout is set to both the HTTP client and the client itself. +func NewClientWithTimeout(endpoint, apiKey, apiSecret string, timeout time.Duration) *Client { + client := &http.Client{ + Timeout: timeout, + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: false, + }, + }, + } + + cs := &Client{ + HTTPClient: client, + Endpoint: endpoint, + APIKey: apiKey, + apiSecret: apiSecret, + PageSize: 50, + Timeout: timeout, + RetryStrategy: FibonacciRetryStrategy, + } + + return cs +} + +// NewClient creates a CloudStack API client with default timeout (60) +func NewClient(endpoint, apiKey, apiSecret string) *Client { + timeout := time.Duration(60 * time.Second) + return NewClientWithTimeout(endpoint, apiKey, apiSecret, timeout) +} + +// FibonacciRetryStrategy waits for an increasing amount of time following the Fibonacci sequence +func FibonacciRetryStrategy(iteration int64) time.Duration { + var a, b, i, tmp int64 + a = 0 + b = 1 + for i = 0; i < iteration; i++ { + tmp = a + b + a = b + b = tmp + } + return time.Duration(a) * time.Second +} diff --git a/vendor/github.com/exoscale/egoscale/client_type.go b/vendor/github.com/exoscale/egoscale/client_type.go new file mode 100644 index 0000000000..f80844e423 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/client_type.go @@ -0,0 +1,60 @@ +package egoscale + +import ( + "context" + "net/http" + "time" +) + +// Taggable represents a resource which can have tags attached +// +// This is a helper to fill the resourcetype of a CreateTags call +type Taggable interface { + // CloudStack resource type of the Taggable type + ResourceType() string +} + +// Gettable represents an Interface that can be "Get" by the client +type Gettable interface { + // Get populates the given resource or throws + Get(context context.Context, client *Client) error +} + +// Deletable represents an Interface that can be "Delete" by the client +type Deletable interface { + // Delete removes the given resource(s) or throws + Delete(context context.Context, client *Client) error +} + +// Listable represents an Interface that can be "List" by the client +type Listable interface { + // ListRequest builds the list command + ListRequest() (ListCommand, error) +} + +// Client represents the CloudStack API client +type Client struct { + // HTTPClient holds the HTTP client + HTTPClient *http.Client + // Endpoints is CloudStack API + Endpoint string + // APIKey is the API identifier + APIKey string + // apisecret is the API secret, hence non exposed + apiSecret string + // PageSize represents the default size for a paginated result + PageSize int + // Timeout represents the default timeout for the async requests + Timeout time.Duration + // RetryStrategy represents the waiting strategy for polling the async requests + RetryStrategy RetryStrategyFunc +} + +// RetryStrategyFunc represents a how much time to wait between two calls to CloudStack +type RetryStrategyFunc func(int64) time.Duration + +// IterateItemFunc represents the callback to iterate a list of results, if false stops +type IterateItemFunc func(interface{}, error) bool + +// WaitAsyncJobResultFunc represents the callback to wait a results of an async request, if false stops +type WaitAsyncJobResultFunc func(*AsyncJobResult, error) bool diff --git a/vendor/github.com/exoscale/egoscale/dns.go b/vendor/github.com/exoscale/egoscale/dns.go new file mode 100644 index 0000000000..852947b7c0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/dns.go @@ -0,0 +1,249 @@ +package egoscale + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" +) + +// DNSDomain represents a domain +type DNSDomain struct { + ID int64 `json:"id"` + AccountID int64 `json:"account_id,omitempty"` + UserID int64 `json:"user_id,omitempty"` + RegistrantID int64 `json:"registrant_id,omitempty"` + Name string `json:"name"` + UnicodeName string `json:"unicode_name"` + Token string `json:"token"` + State string `json:"state"` + Language string `json:"language,omitempty"` + Lockable bool `json:"lockable"` + AutoRenew bool `json:"auto_renew"` + WhoisProtected bool `json:"whois_protected"` + RecordCount int64 `json:"record_count"` + ServiceCount int64 `json:"service_count"` + ExpiresOn string `json:"expires_on,omitempty"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// DNSDomainResponse represents a domain creation response +type DNSDomainResponse struct { + Domain *DNSDomain `json:"domain"` +} + +// DNSRecord represents a DNS record +type DNSRecord struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + Name string `json:"name"` + TTL int `json:"ttl,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + Content string `json:"content"` + RecordType string `json:"record_type"` + Prio int `json:"prio,omitempty"` +} + +// DNSRecordResponse represents the creation of a DNS record +type DNSRecordResponse struct { + Record DNSRecord `json:"record"` +} + +// DNSErrorResponse represents an error in the API +type DNSErrorResponse struct { + Message string `json:"message,omitempty"` + Errors *DNSError `json:"errors"` +} + +// DNSError represents an error +type DNSError struct { + Name []string `json:"name"` +} + +// Error formats the DNSerror into a string +func (req *DNSErrorResponse) Error() error { + if req.Errors != nil { + return fmt.Errorf("DNS error: %s", strings.Join(req.Errors.Name, ", ")) + } + return fmt.Errorf("DNS error: %s", req.Message) +} + +// CreateDomain creates a DNS domain +func (exo *Client) CreateDomain(name string) (*DNSDomain, error) { + m, err := json.Marshal(DNSDomainResponse{ + Domain: &DNSDomain{ + Name: name, + }, + }) + if err != nil { + return nil, err + } + + resp, err := exo.dnsRequest("/v1/domains", string(m), "POST") + if err != nil { + return nil, err + } + + var d *DNSDomainResponse + if err := json.Unmarshal(resp, &d); err != nil { + return nil, err + } + + return d.Domain, nil +} + +// GetDomain gets a DNS domain +func (exo *Client) GetDomain(name string) (*DNSDomain, error) { + resp, err := exo.dnsRequest("/v1/domains/"+name, "", "GET") + if err != nil { + return nil, err + } + + var d *DNSDomainResponse + if err := json.Unmarshal(resp, &d); err != nil { + return nil, err + } + + return d.Domain, nil +} + +// DeleteDomain delets a DNS domain +func (exo *Client) DeleteDomain(name string) error { + _, err := exo.dnsRequest("/v1/domains/"+name, "", "DELETE") + if err != nil { + return err + } + + return nil +} + +// GetRecord returns a DNS record +func (exo *Client) GetRecord(domain string, recordID int64) (*DNSRecord, error) { + id := strconv.FormatInt(recordID, 10) + resp, err := exo.dnsRequest("/v1/domains/"+domain+"/records/"+id, "", "GET") + if err != nil { + return nil, err + } + + var r DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + return &(r.Record), nil +} + +// GetRecords returns the DNS records +func (exo *Client) GetRecords(name string) ([]DNSRecord, error) { + resp, err := exo.dnsRequest("/v1/domains/"+name+"/records", "", "GET") + if err != nil { + return nil, err + } + + var r []DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + records := make([]DNSRecord, 0, len(r)) + for _, rec := range r { + records = append(records, rec.Record) + } + + return records, nil +} + +// CreateRecord creates a DNS record +func (exo *Client) CreateRecord(name string, rec DNSRecord) (*DNSRecord, error) { + body, err := json.Marshal(DNSRecordResponse{ + Record: rec, + }) + if err != nil { + return nil, err + } + + resp, err := exo.dnsRequest("/v1/domains/"+name+"/records", string(body), "POST") + if err != nil { + return nil, err + } + + var r DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + return &(r.Record), nil +} + +// UpdateRecord updates a DNS record +func (exo *Client) UpdateRecord(name string, rec DNSRecord) (*DNSRecord, error) { + body, err := json.Marshal(DNSRecordResponse{ + Record: rec, + }) + if err != nil { + return nil, err + } + + id := strconv.FormatInt(rec.ID, 10) + resp, err := exo.dnsRequest("/v1/domains/"+name+"/records/"+id, string(body), "PUT") + if err != nil { + return nil, err + } + + var r DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + return &(r.Record), nil +} + +// DeleteRecord deletes a record +func (exo *Client) DeleteRecord(name string, recordID int64) error { + id := strconv.FormatInt(recordID, 10) + _, err := exo.dnsRequest("/v1/domains/"+name+"/records/"+id, "", "DELETE") + + return err +} + +func (exo *Client) dnsRequest(uri string, params string, method string) (json.RawMessage, error) { + url := exo.Endpoint + uri + req, err := http.NewRequest(method, url, strings.NewReader(params)) + if err != nil { + return nil, err + } + + var hdr = make(http.Header) + hdr.Add("X-DNS-TOKEN", exo.APIKey+":"+exo.apiSecret) + hdr.Add("User-Agent", fmt.Sprintf("exoscale/egoscale (%v)", Version)) + hdr.Add("Accept", "application/json") + if params != "" { + hdr.Add("Content-Type", "application/json") + } + req.Header = hdr + + response, err := exo.HTTPClient.Do(req) + if err != nil { + return nil, err + } + + defer response.Body.Close() + b, err := ioutil.ReadAll(response.Body) + if err != nil { + return nil, err + } + + if response.StatusCode >= 400 { + var e DNSErrorResponse + if err := json.Unmarshal(b, &e); err != nil { + return nil, err + } + return nil, e.Error() + } + + return b, nil +} diff --git a/vendor/github.com/exoscale/egoscale/doc.go b/vendor/github.com/exoscale/egoscale/doc.go new file mode 100644 index 0000000000..1bd8f0f703 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/doc.go @@ -0,0 +1,165 @@ +/* + +Package egoscale is a mapping for with the CloudStack API (http://cloudstack.apache.org/api.html) from Go. It has been designed against the Exoscale (https://www.exoscale.com/) infrastructure but should fit other CloudStack services. + +Requests and Responses + +To build a request, construct the adequate struct. This library expects a pointer for efficiency reasons only. The response is a struct corresponding to the request itself. E.g. DeployVirtualMachine gives DeployVirtualMachineResponse, as a pointer as well to avoid big copies. + +Then everything within the struct is not a pointer. Find below some examples of how egoscale may be used to interact with a CloudStack endpoint, especially Exoscale itself. If anything feels odd or unclear, please let us know: https://github.com/exoscale/egoscale/issues + + req := &egoscale.DeployVirtualMachine{ + Size: 10, + ServiceOfferingID: "...", + TemplateID: "...", + ZoneID: "...", + } + + fmt.Println("Deployment started") + resp, err := cs.Request(req) + if err != nil { + panic(err) + } + + vm := resp.(*egoscale.DeployVirtualMachineResponse).VirtualMachine + fmt.Printf("Virtual Machine ID: %s\n", vm.ID) + +This exemple deploys a virtual machine while controlling the job status as it goes. It enables a finer control over errors, e.g. HTTP timeout, and eventually a way to kill it of (from the client side). + + req := &egoscale.DeployVirtualMachine{ + Size: 10, + ServiceOfferingID: "...", + TemplateID: "...", + ZoneID: "...", + } + resp := &egoscale.DeployVirtualMachineResponse{} + + fmt.Println("Deployment started") + cs.AsyncRequest(req, func(jobResult *egoscale.AsyncJobResult, err error) bool { + if err != nil { + // any kind of error + panic(err) + } + + // Keep waiting + if jobResult.JobStatus == egoscale.Pending { + fmt.Println("wait...") + return true + } + + // Unmarshal the response into the response struct + if err := jobResult.Response(resp); err != nil { + // JSON unmarshaling error + panic(err) + } + + // Stop waiting + return false + }) + + fmt.Printf("Virtual Machine ID: %s\n", resp.VirtualMachine.ID) + + +APIs + +All the available APIs on the server and provided by the API Discovery plugin + + cs := egoscale.NewClient("https://api.exoscale.ch/compute", "EXO...", "...") + + resp, err := cs.Request(&egoscale.ListAPIs{}) + if err != nil { + panic(err) + } + + for _, api := range resp.(*egoscale.ListAPIsResponse).API { + fmt.Printf("%s %s\n", api.Name, api.Description) + } + // Output: + // listNetworks Lists all available networks + // ... + +Security Groups + +Security Groups provide a way to isolate traffic to VMs. Rules are added via the two Authorization commands. + + resp, err := cs.Request(&egoscale.CreateSecurityGroup{ + Name: "Load balancer", + Description: "Opens HTTP/HTTPS ports from the outside world", + }) + securityGroup := resp.(*egoscale.CreateSecurityGroupResponse).SecurityGroup + + resp, err = cs.Request(&egoscale.AuthorizeSecurityGroupIngress{ + Description: "SSH traffic", + SecurityGroupID: securityGroup.ID, + CidrList: []string{"0.0.0.0/0"}, + Protocol: "tcp", + StartPort: 22, + EndPort: 22, + }) + // The modified SecurityGroup is returned + securityGroup := resp.(*egoscale.AuthorizeSecurityGroupResponse).SecurityGroup + + // ... + err = client.BooleanRequest(&egoscale.DeleteSecurityGroup{ + ID: securityGroup.ID, + }) + // ... + +Security Group also implement the generic List, Get and Delete interfaces (Listable, Gettable and Deletable). + + // List all Security Groups + sgs, err := cs.List(new(egoscale.SecurityGroup)) + for _, s := range sgs { + sg := s.(egoscale.SecurityGroup) + // ... + } + + // Get a Security Group + sg := &egoscale.SecurityGroup{Name: "Load balancer"} + if err := cs.Get(sg); err != nil { + ... + } + // The SecurityGroup struct has been loaded with the SecurityGroup informations + + if err := cs.Delete(sg); err != nil { + ... + } + // The SecurityGroup has been deleted + +See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/networking_and_traffic.html#security-groups + +Zones + +A Zone corresponds to a Data Center. You may list them. Zone implements the Listable interface, which let you perform a list in two different ways. The first exposes the underlying CloudStack request while the second one hide them and you only manipulate the structs of your interest. + + // Using ListZones request + req := &egoscale.ListZones{} + resp, err := client.Request(req) + if err != nil { + panic(err) + } + + for _, zone := range resp.(*egoscale.ListZonesResponse) { + ... + } + + // Using client.List + zone := &egoscale.Zone{} + zones, err := client.List(zone) + if err != nil { + panic(err) + } + + for _, z := range zones { + zone := z.(egoscale.Zone) + ... + } + +Elastic IPs + +An Elastic IP is a way to attach an IP address to many Virtual Machines. The API side of the story configures the external environment, like the routing. Some work is required within the machine to properly configure the interfaces. + +See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html#about-elastic-ips + +*/ +package egoscale diff --git a/vendor/github.com/exoscale/egoscale/errorcode_string.go b/vendor/github.com/exoscale/egoscale/errorcode_string.go new file mode 100644 index 0000000000..19711257e5 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/errorcode_string.go @@ -0,0 +1,37 @@ +// Code generated by "stringer -type ErrorCode"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const ( + _ErrorCode_name_0 = "Unauthorized" + _ErrorCode_name_1 = "MethodNotAllowed" + _ErrorCode_name_2 = "UnsupportedActionError" + _ErrorCode_name_3 = "APILimitExceededMalformedParameterErrorParamError" + _ErrorCode_name_4 = "InternalErrorAccountErrorAccountResourceLimitErrorInsufficientCapacityErrorResourceUnavailableErrorResourceAllocationErrorResourceInUseErrorNetworkRuleConflictError" +) + +var ( + _ErrorCode_index_3 = [...]uint8{0, 16, 39, 49} + _ErrorCode_index_4 = [...]uint8{0, 13, 25, 50, 75, 99, 122, 140, 164} +) + +func (i ErrorCode) String() string { + switch { + case i == 401: + return _ErrorCode_name_0 + case i == 405: + return _ErrorCode_name_1 + case i == 422: + return _ErrorCode_name_2 + case 429 <= i && i <= 431: + i -= 429 + return _ErrorCode_name_3[_ErrorCode_index_3[i]:_ErrorCode_index_3[i+1]] + case 530 <= i && i <= 537: + i -= 530 + return _ErrorCode_name_4[_ErrorCode_index_4[i]:_ErrorCode_index_4[i+1]] + default: + return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/github.com/exoscale/egoscale/events.go b/vendor/github.com/exoscale/egoscale/events.go new file mode 100644 index 0000000000..eb92b1b092 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/events.go @@ -0,0 +1,79 @@ +package egoscale + +// Event represents an event in the system +type Event struct { + ID string `json:"id"` + Account string `json:"account"` + Created string `json:"created"` + Description string `json:"description,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Level string `json:"level"` // INFO, WARN, ERROR + ParentID string `json:"parentid,omitempty"` + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` + State string `json:"state,omitempty"` + Type string `json:"type"` + UserName string `json:"username,omitempty"` +} + +// EventType represent a type of event +type EventType struct { + Name string `json:"name"` +} + +// ListEvents list the events +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listEvents.html +type ListEvents struct { + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + Duration int `json:"duration,omitempty"` + EndDate string `json:"enddate,omitempty"` + EntryTime int `json:"entrytime,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + Level string `json:"level,omitempty"` // INFO, WARN, ERROR + ListAll *bool `json:"listall,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty"` + StartDate string `json:"startdate,omitempty"` + Type string `json:"type,omitempty"` +} + +// name returns the CloudStack API command name +func (*ListEvents) name() string { + return "listEvents" +} + +func (*ListEvents) response() interface{} { + return new(ListEventsResponse) +} + +// ListEventsResponse represents a response of a list query +type ListEventsResponse struct { + Count int `json:"count"` + Event []Event `json:"event"` +} + +// ListEventTypes list the event types +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listEventTypes.html +type ListEventTypes struct{} + +// name returns the CloudStack API command name +func (*ListEventTypes) name() string { + return "listEventTypes" +} + +func (*ListEventTypes) response() interface{} { + return new(ListEventTypesResponse) +} + +// ListEventTypesResponse represents a response of a list query +type ListEventTypesResponse struct { + Count int `json:"count"` + EventType []EventType `json:"eventtype"` +} diff --git a/vendor/github.com/exoscale/egoscale/gopher.png b/vendor/github.com/exoscale/egoscale/gopher.png new file mode 100644 index 0000000000..16420a6182 Binary files /dev/null and b/vendor/github.com/exoscale/egoscale/gopher.png differ diff --git a/vendor/github.com/exoscale/egoscale/jobstatustype_string.go b/vendor/github.com/exoscale/egoscale/jobstatustype_string.go new file mode 100644 index 0000000000..2985616084 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/jobstatustype_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type JobStatusType"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const _JobStatusType_name = "PendingSuccessFailure" + +var _JobStatusType_index = [...]uint8{0, 7, 14, 21} + +func (i JobStatusType) String() string { + if i < 0 || i >= JobStatusType(len(_JobStatusType_index)-1) { + return "JobStatusType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _JobStatusType_name[_JobStatusType_index[i]:_JobStatusType_index[i+1]] +} diff --git a/vendor/github.com/exoscale/egoscale/keypairs.go b/vendor/github.com/exoscale/egoscale/keypairs.go new file mode 100644 index 0000000000..1dad316b96 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/keypairs.go @@ -0,0 +1,124 @@ +package egoscale + +import ( + "context" + "fmt" + + "github.com/jinzhu/copier" +) + +// Get populates the given SSHKeyPair +func (ssh *SSHKeyPair) Get(ctx context.Context, client *Client) error { + sshs, err := client.ListWithContext(ctx, ssh) + if err != nil { + return err + } + + count := len(sshs) + if count == 0 { + return &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("SSHKeyPair not found"), + } + } else if count > 1 { + return fmt.Errorf("More than one SSHKeyPair was found") + } + + return copier.Copy(ssh, sshs[0]) +} + +// Delete removes the given SSH key, by Name +func (ssh *SSHKeyPair) Delete(ctx context.Context, client *Client) error { + if ssh.Name == "" { + return fmt.Errorf("An SSH Key Pair may only be deleted using Name") + } + + return client.BooleanRequestWithContext(ctx, &DeleteSSHKeyPair{ + Name: ssh.Name, + Account: ssh.Account, + DomainID: ssh.DomainID, + ProjectID: ssh.ProjectID, + }) +} + +// ListRequest builds the ListSSHKeyPairs request +func (ssh *SSHKeyPair) ListRequest() (ListCommand, error) { + req := &ListSSHKeyPairs{ + Account: ssh.Account, + DomainID: ssh.DomainID, + Fingerprint: ssh.Fingerprint, + Name: ssh.Name, + ProjectID: ssh.ProjectID, + } + + return req, nil +} + +// name returns the CloudStack API command name +func (*CreateSSHKeyPair) name() string { + return "createSSHKeyPair" +} + +func (*CreateSSHKeyPair) response() interface{} { + return new(CreateSSHKeyPairResponse) +} + +// name returns the CloudStack API command name +func (*DeleteSSHKeyPair) name() string { + return "deleteSSHKeyPair" +} + +func (*DeleteSSHKeyPair) response() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*RegisterSSHKeyPair) name() string { + return "registerSSHKeyPair" +} + +func (*RegisterSSHKeyPair) response() interface{} { + return new(RegisterSSHKeyPairResponse) +} + +// name returns the CloudStack API command name +func (*ListSSHKeyPairs) name() string { + return "listSSHKeyPairs" +} + +func (*ListSSHKeyPairs) response() interface{} { + return new(ListSSHKeyPairsResponse) +} + +func (*ListSSHKeyPairs) each(resp interface{}, callback IterateItemFunc) { + sshs, ok := resp.(*ListSSHKeyPairsResponse) + if !ok { + callback(nil, fmt.Errorf("ListSSHKeyPairsResponse expected, got %t", resp)) + return + } + + for i := range sshs.SSHKeyPair { + if !callback(&sshs.SSHKeyPair[i], nil) { + break + } + } +} + +// SetPage sets the current page +func (ls *ListSSHKeyPairs) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListSSHKeyPairs) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// name returns the CloudStack API command name +func (*ResetSSHKeyForVirtualMachine) name() string { + return "resetSSHKeyForVirtualMachine" +} + +func (*ResetSSHKeyForVirtualMachine) asyncResponse() interface{} { + return new(ResetSSHKeyForVirtualMachineResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/keypairs_type.go b/vendor/github.com/exoscale/egoscale/keypairs_type.go new file mode 100644 index 0000000000..9e39123a41 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/keypairs_type.go @@ -0,0 +1,90 @@ +package egoscale + +// SSHKeyPair represents an SSH key pair +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#creating-the-ssh-keypair +type SSHKeyPair struct { + Account string `json:"account,omitempty"` // must be used with a Domain ID + DomainID string `json:"domainid,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` + Name string `json:"name,omitempty"` + PrivateKey string `json:"privatekey,omitempty"` +} + +// CreateSSHKeyPair represents a new keypair to be created +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createSSHKeyPair.html +type CreateSSHKeyPair struct { + Name string `json:"name" doc:"Name of the keypair"` + Account string `json:"account,omitempty" doc:"an optional account for the ssh key. Must be used with domainId."` + DomainID string `json:"domainid,omitempty" doc:"an optional domainId for the ssh key. If the account parameter is used, domainId must also be used."` + ProjectID string `json:"projectid,omitempty" doc:"an optional project for the ssh key"` +} + +// CreateSSHKeyPairResponse represents the creation of an SSH Key Pair +type CreateSSHKeyPairResponse struct { + KeyPair SSHKeyPair `json:"keypair"` +} + +// DeleteSSHKeyPair represents a new keypair to be created +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteSSHKeyPair.html +type DeleteSSHKeyPair struct { + Name string `json:"name" doc:"Name of the keypair"` + Account string `json:"account,omitempty" doc:"the account associated with the keypair. Must be used with the domainId parameter."` + DomainID string `json:"domainid,omitempty" doc:"the domain ID associated with the keypair"` + ProjectID string `json:"projectid,omitempty" doc:"the project associated with keypair"` +} + +// RegisterSSHKeyPair represents a new registration of a public key in a keypair +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/registerSSHKeyPair.html +type RegisterSSHKeyPair struct { + Name string `json:"name" doc:"Name of the keypair"` + PublicKey string `json:"publickey" doc:"Public key material of the keypair"` + Account string `json:"account,omitempty" doc:"an optional account for the ssh key. Must be used with domainId."` + DomainID string `json:"domainid,omitempty" doc:"an optional domainId for the ssh key. If the account parameter is used, domainId must also be used."` + ProjectID string `json:"projectid,omitempty" doc:"an optional project for the ssh key"` +} + +// RegisterSSHKeyPairResponse represents the creation of an SSH Key Pair +type RegisterSSHKeyPairResponse struct { + KeyPair SSHKeyPair `json:"keypair"` +} + +// ListSSHKeyPairs represents a query for a list of SSH KeyPairs +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listSSHKeyPairs.html +type ListSSHKeyPairs struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + Fingerprint string `json:"fingerprint,omitempty" doc:"A public key fingerprint to look for"` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Name string `json:"name,omitempty" doc:"A key pair name to look for"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty" doc:"list objects by project"` +} + +// ListSSHKeyPairsResponse represents a list of SSH key pairs +type ListSSHKeyPairsResponse struct { + Count int `json:"count"` + SSHKeyPair []SSHKeyPair `json:"sshkeypair"` +} + +// ResetSSHKeyForVirtualMachine (Async) represents a change for the key pairs +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/resetSSHKeyForVirtualMachine.html +type ResetSSHKeyForVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` + KeyPair string `json:"keypair" doc:"name of the ssh key pair used to login to the virtual machine"` + Account string `json:"account,omitempty" doc:"an optional account for the ssh key. Must be used with domainId."` + DomainID string `json:"domainid,omitempty" doc:"an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used."` + ProjectID string `json:"projectid,omitempty" doc:"an optional project for the ssh key"` +} + +// ResetSSHKeyForVirtualMachineResponse represents the modified VirtualMachine +type ResetSSHKeyForVirtualMachineResponse VirtualMachineResponse diff --git a/vendor/github.com/exoscale/egoscale/limits.go b/vendor/github.com/exoscale/egoscale/limits.go new file mode 100644 index 0000000000..538d4874b1 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/limits.go @@ -0,0 +1,107 @@ +package egoscale + +// https://github.com/apache/cloudstack/blob/master/api/src/main/java/com/cloud/configuration/Resource.java + +// ResourceTypeName represents the name of a resource type (for limits) +type ResourceTypeName string + +const ( + // VirtualMachineTypeName is the resource type name of a VM + VirtualMachineTypeName ResourceTypeName = "user_vm" + // IPAddressTypeName is the resource type name of an IP address + IPAddressTypeName = "public_ip" + // VolumeTypeName is the resource type name of a volume + VolumeTypeName = "volume" + // SnapshotTypeName is the resource type name of a snapshot + SnapshotTypeName = "snapshot" + // TemplateTypeName is the resource type name of a template + TemplateTypeName = "template" + // ProjectTypeName is the resource type name of a project + ProjectTypeName = "project" + // NetworkTypeName is the resource type name of a network + NetworkTypeName = "network" + // VPCTypeName is the resource type name of a VPC + VPCTypeName = "vpc" + // CPUTypeName is the resource type name of a CPU + CPUTypeName = "cpu" + // MemoryTypeName is the resource type name of Memory + MemoryTypeName = "memory" + // PrimaryStorageTypeName is the resource type name of primary storage + PrimaryStorageTypeName = "primary_storage" + // SecondaryStorageTypeName is the resource type name of secondary storage + SecondaryStorageTypeName = "secondary_storage" +) + +// ResourceType represents the ID of a resource type (for limits) +type ResourceType int64 + +const ( + // VirtualMachineType is the resource type ID of a VM + VirtualMachineType ResourceType = iota + // IPAddressType is the resource type ID of an IP address + IPAddressType + // VolumeType is the resource type ID of a volume + VolumeType + // SnapshotType is the resource type ID of a snapshot + SnapshotType + // TemplateType is the resource type ID of a template + TemplateType + // ProjectType is the resource type ID of a project + ProjectType + // NetworkType is the resource type ID of a network + NetworkType + // VPCType is the resource type ID of a VPC + VPCType + // CPUType is the resource type ID of a CPU + CPUType + // MemoryType is the resource type ID of Memory + MemoryType + // PrimaryStorageType is the resource type ID of primary storage + PrimaryStorageType + // SecondaryStorageType is the resource type ID of secondary storage + SecondaryStorageType +) + +// ListResourceLimits lists the resource limits +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listResourceLimits.html +type ListResourceLimits struct { + Account string `json:"account,omittempty"` + DomainID string `json:"domainid,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty"` + ResourceType ResourceType `json:"resourcetype,omitempty"` + ResourceTypeName ResourceTypeName `json:"resourcetypename,omitempty"` +} + +// name returns the CloudStack API command name +func (*ListResourceLimits) name() string { + return "listResourceLimits" +} + +func (*ListResourceLimits) response() interface{} { + return new(ListResourceLimitsResponse) +} + +// ListResourceLimitsResponse represents a list of resource limits +type ListResourceLimitsResponse struct { + Count int `json:"count"` + ResourceLimit []ResourceLimit `json:"resourcelimit"` +} + +// ResourceLimit represents the limit on a particular resource +type ResourceLimit struct { + Account string `json:"account,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Max int64 `json:"max,omitempty"` // -1 means the sky is the limit + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` + ResourceType ResourceType `json:"resourcetype,omitempty"` + ResourceTypeName ResourceTypeName `json:"resourcetypename,omitempty"` +} diff --git a/vendor/github.com/exoscale/egoscale/network_offerings.go b/vendor/github.com/exoscale/egoscale/network_offerings.go new file mode 100644 index 0000000000..0777f09fa7 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/network_offerings.go @@ -0,0 +1,17 @@ +package egoscale + +func (*ListNetworkOfferings) name() string { + return "listNetworkOfferings" +} + +func (*ListNetworkOfferings) response() interface{} { + return new(ListNetworkOfferingsResponse) +} + +func (*UpdateNetworkOffering) name() string { + return "updateNetworkOffering" +} + +func (*UpdateNetworkOffering) response() interface{} { + return new(UpdateNetworkOfferingResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/network_offerings_type.go b/vendor/github.com/exoscale/egoscale/network_offerings_type.go new file mode 100644 index 0000000000..ff07de0a50 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/network_offerings_type.go @@ -0,0 +1,78 @@ +package egoscale + +// NetworkOffering corresponds to the Compute Offerings +type NetworkOffering struct { + Availability string `json:"availability,omitempty" doc:"availability of the network offering"` + ConserveMode bool `json:"conservemode,omitempty" doc:"true if network offering is ip conserve mode enabled"` + Created string `json:"created,omitempty" doc:"the date this network offering was created"` + Details map[string]string `json:"details,omitempty" doc:"additional key/value details tied with network offering"` + DisplayText string `json:"displaytext,omitempty" doc:"an alternate display text of the network offering."` + EgressDefaultPolicy bool `json:"egressdefaultpolicy,omitempty" doc:"true if guest network default egress policy is allow; false if default egress policy is deny"` + ForVPC bool `json:"forvpc,omitempty" doc:"true if network offering can be used by VPC networks only"` + GuestIPType string `json:"guestiptype,omitempty" doc:"guest type of the network offering, can be Shared or Isolated"` + ID string `json:"id,omitempty" doc:"the id of the network offering"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if network offering is default, false otherwise"` + IsPersistent bool `json:"ispersistent,omitempty" doc:"true if network offering supports persistent networks, false otherwise"` + MaxConnections int `json:"maxconnections,omitempty" doc:"maximum number of concurrents connections to be handled by lb"` + Name string `json:"name,omitempty" doc:"the name of the network offering"` + NetworkRate int `json:"networkrate,omitempty" doc:"data transfer rate in megabits per second allowed."` + Service []Service `json:"service,omitempty" doc:"the list of supported services"` + ServiceOfferingID string `json:"serviceofferingid,omitempty" doc:"the ID of the service offering used by virtual router provider"` + SpecifyIPRanges bool `json:"specifyipranges,omitempty" doc:"true if network offering supports specifying ip ranges, false otherwise"` + SpecifyVlan bool `json:"specifyvlan,omitempty" doc:"true if network offering supports vlans, false otherwise"` + State string `json:"state,omitempty" doc:"state of the network offering. Can be Disabled/Enabled/Inactive"` + SupportsStrechedL2Subnet bool `json:"supportsstrechedl2subnet,omitempty" doc:"true if network offering supports network that span multiple zones"` + Tags string `json:"tags,omitempty" doc:"the tags for the network offering"` + TrafficType string `json:"traffictype,omitempty" doc:"the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage."` +} + +// ListNetworkOfferings represents a query for network offerings +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listNetworkOfferings.html +type ListNetworkOfferings struct { + Availability string `json:"availability,omitempty" doc:"the availability of network offering. Default value is Required"` + DisplayText string `json:"displaytext,omitempty" doc:"list network offerings by display text"` + ForVPC *bool `json:"forvpc,omitempty" doc:"the network offering can be used only for network creation inside the VPC"` + GuestIPType string `json:"guestiptype,omitempty" doc:"list network offerings by guest type: Shared or Isolated"` + ID string `json:"id,omitempty" doc:"list network offerings by id"` + IsDefault *bool `json:"isdefault,omitempty" doc:"true if need to list only default network offerings. Default value is false"` + IsTagged *bool `json:"istagged,omitempty" doc:"true if offering has tags specified"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"list network offerings by name"` + NetworkID string `json:"networkid,omitempty" doc:"the ID of the network. Pass this in if you want to see the available network offering that a network can be changed to."` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + SourceNATSupported *bool `json:"sourcenatsupported,omitempty" doc:"true if need to list only netwok offerings where source nat is supported, false otherwise"` + SpecifyIPRanges *bool `json:"specifyipranges,omitempty" doc:"true if need to list only network offerings which support specifying ip ranges"` + SpecifyVlan *bool `json:"specifyvlan,omitempty" doc:"the tags for the network offering."` + State string `json:"state,omitempty" doc:"list network offerings by state"` + SupportedServices []Service `json:"supportedservices,omitempty" doc:"list network offerings supporting certain services"` + Tags string `json:"tags,omitempty" doc:"list network offerings by tags"` + TrafficType string `json:"traffictype,omitempty" doc:"list by traffic type"` + ZoneID string `json:"zoneid,omitempty" doc:"list netowrk offerings available for network creation in specific zone"` +} + +// ListNetworkOfferingsResponse represents a list of service offerings +type ListNetworkOfferingsResponse struct { + Count int `json:"count"` + NetworkOffering []NetworkOffering `json:"networkoffering"` +} + +// UpdateNetworkOffering represents a modification of a network offering +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/updateNetworkOffering.html +type UpdateNetworkOffering struct { + Availability string `json:"availability,omitempty" doc:"the availability of network offering. Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering"` + DisplayText string `json:"displaytext,omitempty" doc:"the display text of the network offering"` + ID string `json:"id,omitempty" doc:"the id of the network offering"` + KeepAliveEnabled *bool `json:"keepaliveenabled,omitempty" doc:"if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file."` + MaxConnections int `json:"maxconnections,omitempty" doc:"maximum number of concurrent connections supported by the network offering"` + Name string `json:"name,omitempty" doc:"the name of the network offering"` + SortKey int `json:"sortkey,omitempty" doc:"sort key of the network offering, integer"` + State string `json:"state,omitempty" doc:"update state for the network offering"` +} + +// UpdateNetworkOfferingResponse represents a newly modified network offering +type UpdateNetworkOfferingResponse struct { + NetworkOffering NetworkOffering `json:"networkoffering"` +} diff --git a/vendor/github.com/exoscale/egoscale/networks.go b/vendor/github.com/exoscale/egoscale/networks.go new file mode 100644 index 0000000000..13fd453ed8 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/networks.go @@ -0,0 +1,112 @@ +package egoscale + +import ( + "fmt" + "net/url" +) + +// ListRequest builds the ListNetworks request +func (network *Network) ListRequest() (ListCommand, error) { + //TODO add tags support + req := &ListNetworks{ + Account: network.Account, + ACLType: network.ACLType, + CanUseForDeploy: &network.CanUseForDeploy, + DomainID: network.DomainID, + ID: network.ID, + PhysicalNetworkID: network.PhysicalNetworkID, + ProjectID: network.ProjectID, + RestartRequired: &network.RestartRequired, + TrafficType: network.TrafficType, + Type: network.Type, + VpcID: network.VpcID, + ZoneID: network.ZoneID, + } + + return req, nil +} + +// ResourceType returns the type of the resource +func (*Network) ResourceType() string { + return "Network" +} + +// name returns the CloudStack API command name +func (*CreateNetwork) name() string { + return "createNetwork" +} + +func (*CreateNetwork) response() interface{} { + return new(CreateNetworkResponse) +} + +func (req *CreateNetwork) onBeforeSend(params *url.Values) error { + // Those fields are required but might be empty + if req.Name == "" { + params.Set("name", "") + } + if req.DisplayText == "" { + params.Set("displaytext", "") + } + return nil +} + +// name returns the CloudStack API command name +func (*UpdateNetwork) name() string { + return "updateNetwork" +} + +func (*UpdateNetwork) asyncResponse() interface{} { + return new(UpdateNetworkResponse) +} + +// name returns the CloudStack API command name +func (*RestartNetwork) name() string { + return "restartNetwork" +} + +func (*RestartNetwork) asyncResponse() interface{} { + return new(RestartNetworkResponse) +} + +// name returns the CloudStack API command name +func (*DeleteNetwork) name() string { + return "deleteNetwork" +} + +func (*DeleteNetwork) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*ListNetworks) name() string { + return "listNetworks" +} + +func (*ListNetworks) response() interface{} { + return new(ListNetworksResponse) +} + +// SetPage sets the current page +func (listNetwork *ListNetworks) SetPage(page int) { + listNetwork.Page = page +} + +// SetPageSize sets the page size +func (listNetwork *ListNetworks) SetPageSize(pageSize int) { + listNetwork.PageSize = pageSize +} + +func (*ListNetworks) each(resp interface{}, callback IterateItemFunc) { + networks, ok := resp.(*ListNetworksResponse) + if !ok { + callback(nil, fmt.Errorf("ListNetworksResponse expected, got %t", resp)) + return + } + + for i := range networks.Network { + if !callback(&networks.Network[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/networks_type.go b/vendor/github.com/exoscale/egoscale/networks_type.go new file mode 100644 index 0000000000..8338231008 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/networks_type.go @@ -0,0 +1,191 @@ +package egoscale + +import "net" + +// Network represents a network +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html +type Network struct { + Account string `json:"account,omitempty" doc:"the owner of the network"` + ACLID string `json:"aclid,omitempty" doc:"ACL Id associated with the VPC network"` + ACLType string `json:"acltype,omitempty" doc:"acl type - access type to the network"` + BroadcastDomainType string `json:"broadcastdomaintype,omitempty" doc:"Broadcast domain type of the network"` + BroadcastURI string `json:"broadcasturi,omitempty" doc:"broadcast uri of the network. This parameter is visible to ROOT admins only"` + CanUseForDeploy bool `json:"canusefordeploy,omitempty" doc:"list networks available for vm deployment"` + Cidr string `json:"cidr,omitempty" doc:"Cloudstack managed address space, all CloudStack managed VMs get IP address from CIDR"` + DisplayNetwork bool `json:"displaynetwork,omitempty" doc:"an optional field, whether to the display the network to the end user or not."` + DisplayText string `json:"displaytext,omitempty" doc:"the displaytext of the network"` + DNS1 net.IP `json:"dns1,omitempty" doc:"the first DNS for the network"` + DNS2 net.IP `json:"dns2,omitempty" doc:"the second DNS for the network"` + Domain string `json:"domain,omitempty" doc:"the domain name of the network owner"` + DomainID string `json:"domainid,omitempty" doc:"the domain id of the network owner"` + Gateway net.IP `json:"gateway,omitempty" doc:"the network's gateway"` + ID string `json:"id,omitempty" doc:"the id of the network"` + IP6Cidr string `json:"ip6cidr,omitempty" doc:"the cidr of IPv6 network"` + IP6Gateway net.IP `json:"ip6gateway,omitempty" doc:"the gateway of IPv6 network"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if network is default, false otherwise"` + IsPersistent bool `json:"ispersistent,omitempty" doc:"list networks that are persistent"` + IsSystem bool `json:"issystem,omitempty" doc:"true if network is system, false otherwise"` + Name string `json:"name,omitempty" doc:"the name of the network"` + Netmask net.IP `json:"netmask,omitempty" doc:"the network's netmask"` + NetworkCidr string `json:"networkcidr,omitempty" doc:"the network CIDR of the guest network configured with IP reservation. It is the summation of CIDR and RESERVED_IP_RANGE"` + NetworkDomain string `json:"networkdomain,omitempty" doc:"the network domain"` + NetworkOfferingAvailability string `json:"networkofferingavailability,omitempty" doc:"availability of the network offering the network is created from"` + NetworkOfferingConserveMode bool `json:"networkofferingconservemode,omitempty" doc:"true if network offering is ip conserve mode enabled"` + NetworkOfferingDisplayText string `json:"networkofferingdisplaytext,omitempty" doc:"display text of the network offering the network is created from"` + NetworkOfferingID string `json:"networkofferingid,omitempty" doc:"network offering id the network is created from"` + NetworkOfferingName string `json:"networkofferingname,omitempty" doc:"name of the network offering the network is created from"` + PhysicalNetworkID string `json:"physicalnetworkid,omitempty" doc:"the physical network id"` + Project string `json:"project,omitempty" doc:"the project name of the address"` + ProjectID string `json:"projectid,omitempty" doc:"the project id of the ipaddress"` + Related string `json:"related,omitempty" doc:"related to what other network configuration"` + ReservedIPRange string `json:"reservediprange,omitempty" doc:"the network's IP range not to be used by CloudStack guest VMs and can be used for non CloudStack purposes"` + RestartRequired bool `json:"restartrequired,omitempty" doc:"true network requires restart"` + Service []Service `json:"service,omitempty" doc:"the list of services"` + SpecifyIPRanges bool `json:"specifyipranges,omitempty" doc:"true if network supports specifying ip ranges, false otherwise"` + State string `json:"state,omitempty" doc:"state of the network"` + StrechedL2Subnet bool `json:"strechedl2subnet,omitempty" doc:"true if network can span multiple zones"` + SubdomainAccess bool `json:"subdomainaccess,omitempty" doc:"true if users from subdomains can access the domain level network"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with network"` + TrafficType string `json:"traffictype,omitempty" doc:"the traffic type of the network"` + Type string `json:"type,omitempty" doc:"the type of the network"` + Vlan string `json:"vlan,omitemtpy" doc:"The vlan of the network. This parameter is visible to ROOT admins only"` + VpcID string `json:"vpcid,omitempty" doc:"VPC the network belongs to"` + ZoneID string `json:"zoneid,omitempty" doc:"zone id of the network"` + ZoneName string `json:"zonename,omitempty" doc:"the name of the zone the network belongs to"` + ZonesNetworkSpans []Zone `json:"zonesnetworkspans,omitempty" doc:"If a network is enabled for 'streched l2 subnet' then represents zones on which network currently spans"` +} + +// Service is a feature of a network +type Service struct { + Capability []ServiceCapability `json:"capability,omitempty"` + Name string `json:"name"` + Provider []ServiceProvider `json:"provider,omitempty"` +} + +// ServiceCapability represents optional capability of a service +type ServiceCapability struct { + CanChooseServiceCapability bool `json:"canchooseservicecapability"` + Name string `json:"name"` + Value string `json:"value"` +} + +// ServiceProvider represents the provider of the service +type ServiceProvider struct { + CanEnableIndividualService bool `json:"canenableindividualservice"` + DestinationPhysicalNetworkID string `json:"destinationphysicalnetworkid"` + ID string `json:"id"` + Name string `json:"name"` + PhysicalNetworkID string `json:"physicalnetworkid"` + ServiceList []string `json:"servicelist,omitempty"` +} + +// NetworkResponse represents a network +type NetworkResponse struct { + Network Network `json:"network"` +} + +// CreateNetwork creates a network +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createNetwork.html +type CreateNetwork struct { + Account string `json:"account,omitempty" doc:"account who will own the network"` + ACLID string `json:"aclid,omitempty" doc:"Network ACL Id associated for the network"` + ACLType string `json:"acltype,omitempty" doc:"Access control type; supported values are account and domain. In 3.0 all shared networks should have aclType=Domain, and all Isolated networks - Account. Account means that only the account owner can use the network, domain - all accouns in the domain can use the network"` + DisplayNetwork *bool `json:"displaynetwork,omitempty" doc:"an optional field, whether to the display the network to the end user or not."` + DisplayText string `json:"displaytext" doc:"the display text of the network"` + DomainID string `json:"domainid,omitempty" doc:"domain ID of the account owning a network"` + EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. If not specified, will be defaulted to startIP"` + EndIpv6 net.IP `json:"endipv6,omitempty" doc:"the ending IPv6 address in the IPv6 network range"` + Gateway net.IP `json:"gateway,omitempty" doc:"the gateway of the network. Required for Shared networks and Isolated networks when it belongs to VPC"` + IP6Cidr string `json:"ip6cidr,omitempty" doc:"the CIDR of IPv6 network, must be at least /64"` + IP6Gateway net.IP `json:"ip6gateway,omitempty" doc:"the gateway of the IPv6 network. Required for Shared networks and Isolated networks when it belongs to VPC"` + IsolatedPVlan string `json:"isolatedpvlan,omitempty" doc:"the isolated private vlan for this network"` + Name string `json:"name" doc:"the name of the network"` + Netmask net.IP `json:"netmask,omitempty" doc:"the netmask of the network. Required for Shared networks and Isolated networks when it belongs to VPC"` + NetworkDomain string `json:"networkdomain,omitempty" doc:"network domain"` + NetworkOfferingID string `json:"networkofferingid" doc:"the network offering id"` + PhysicalNetworkID string `json:"physicalnetworkid,omitempty" doc:"the Physical Network ID the network belongs to"` + ProjectID string `json:"projectid,omitempty" doc:"an optional project for the ssh key"` + StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range"` + StartIpv6 net.IP `json:"startipv6,omitempty" doc:"the beginning IPv6 address in the IPv6 network range"` + SubdomainAccess *bool `json:"subdomainaccess,omitempty" doc:"Defines whether to allow subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to allow.subdomain.network.access global config if not specified"` + Vlan string `json:"vlan,omitempty" doc:"the ID or VID of the network"` + VpcID string `json:"vpcid,omitempty" doc:"the VPC network belongs to"` + ZoneID string `json:"zoneid" doc:"the Zone ID for the network"` +} + +// CreateNetworkResponse represents a freshly created network +type CreateNetworkResponse NetworkResponse + +// UpdateNetwork (Async) updates a network +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateNetwork.html +type UpdateNetwork struct { + ID string `json:"id" doc:"the ID of the network"` + ChangeCidr *bool `json:"changecidr,omitempty" doc:"Force update even if cidr type is different"` + CustomID string `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"` + DisplayNetwork *bool `json:"displaynetwork,omitempty" doc:"an optional field, whether to the display the network to the end user or not."` + DisplayText string `json:"displaytext,omitempty" doc:"the new display text for the network"` + GuestVMCidr string `json:"guestvmcidr,omitempty" doc:"CIDR for Guest VMs,Cloudstack allocates IPs to Guest VMs only from this CIDR"` + Name string `json:"name,omitempty" doc:"the new name for the network"` + NetworkDomain string `json:"networkdomain,omitempty" doc:"network domain"` + NetworkOfferingID string `json:"networkofferingid,omitempty" doc:"network offering ID"` +} + +// UpdateNetworkResponse represents a freshly created network +type UpdateNetworkResponse NetworkResponse + +// RestartNetwork (Async) updates a network +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/restartNetwork.html +type RestartNetwork struct { + ID string `json:"id" doc:"The id of the network to restart."` + Cleanup *bool `json:"cleanup,omitempty" doc:"If cleanup old network elements"` +} + +// RestartNetworkResponse represents a freshly created network +type RestartNetworkResponse NetworkResponse + +// DeleteNetwork deletes a network +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteNetwork.html +type DeleteNetwork struct { + ID string `json:"id" doc:"the ID of the network"` + Forced *bool `json:"forced,omitempty" doc:"Force delete a network. Network will be marked as 'Destroy' even when commands to shutdown and cleanup to the backend fails."` +} + +// ListNetworks represents a query to a network +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listNetworks.html +type ListNetworks struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + ACLType string `json:"acltype,omitempty" doc:"list networks by ACL (access control list) type. Supported values are Account and Domain"` + CanUseForDeploy *bool `json:"canusefordeploy,omitempty" doc:"list networks available for vm deployment"` + DisplayNetwork *bool `json:"displaynetwork,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + ForVpc *bool `json:"forvpc,omitempty" doc:"the network belongs to vpc"` + ID string `json:"id,omitempty" doc:"list networks by id"` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + IsSystem *bool `json:"issystem,omitempty" doc:"true if network is system, false otherwise"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + PhysicalNetworkID string `json:"physicalnetworkid,omitempty" doc:"list networks by physical network id"` + ProjectID string `json:"projectid,omitempty" doc:"list objects by project"` + RestartRequired *bool `json:"restartrequired,omitempty" doc:"list networks by restartRequired"` + SpecifyIPRanges *bool `json:"specifyipranges,omitempty" doc:"true if need to list only networks which support specifying ip ranges"` + SupportedServices []Service `json:"supportedservices,omitempty" doc:"list networks supporting certain services"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + TrafficType string `json:"traffictype,omitempty" doc:"type of the traffic"` + Type string `json:"type,omitempty" doc:"the type of the network. Supported values are: Isolated and Shared"` + VpcID string `json:"vpcid,omitempty" doc:"List networks by VPC"` + ZoneID string `json:"zoneid,omitempty" doc:"the Zone ID of the network"` +} + +// ListNetworksResponse represents the list of networks +type ListNetworksResponse struct { + Count int `json:"count"` + Network []Network `json:"network"` +} diff --git a/vendor/github.com/exoscale/egoscale/nics.go b/vendor/github.com/exoscale/egoscale/nics.go new file mode 100644 index 0000000000..c536ec22a1 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/nics.go @@ -0,0 +1,74 @@ +package egoscale + +import ( + "fmt" +) + +// ListRequest build a ListNics request from the given Nic +func (nic *Nic) ListRequest() (ListCommand, error) { + if nic.VirtualMachineID == "" { + return nil, fmt.Errorf("ListNics command requires the VirtualMachineID field to be set") + } + + req := &ListNics{ + VirtualMachineID: nic.VirtualMachineID, + NicID: nic.ID, + NetworkID: nic.NetworkID, + } + + return req, nil +} + +// name returns the CloudStack API command name +func (*ListNics) name() string { + return "listNics" +} + +func (*ListNics) response() interface{} { + return new(ListNicsResponse) +} + +// SetPage sets the current page +func (ls *ListNics) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListNics) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +func (*ListNics) each(resp interface{}, callback IterateItemFunc) { + nics := resp.(*ListNicsResponse) + for i := range nics.Nic { + if !callback(&(nics.Nic[i]), nil) { + break + } + } +} + +// name returns the CloudStack API command name: addIpToNic +func (*AddIPToNic) name() string { + return "addIpToNic" +} +func (*AddIPToNic) asyncResponse() interface{} { + return new(AddIPToNicResponse) +} + +// name returns the CloudStack API command name: removeIpFromNic +func (*RemoveIPFromNic) name() string { + return "removeIpFromNic" +} + +func (*RemoveIPFromNic) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name: activateIp6 +func (*ActivateIP6) name() string { + return "activateIp6" +} + +func (*ActivateIP6) asyncResponse() interface{} { + return new(ActivateIP6Response) +} diff --git a/vendor/github.com/exoscale/egoscale/nics_type.go b/vendor/github.com/exoscale/egoscale/nics_type.go new file mode 100644 index 0000000000..bcdbdf1916 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/nics_type.go @@ -0,0 +1,88 @@ +package egoscale + +import ( + "net" +) + +// Nic represents a Network Interface Controller (NIC) +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html#configuring-multiple-ip-addresses-on-a-single-nic +type Nic struct { + ID string `json:"id,omitempty"` + BroadcastURI string `json:"broadcasturi,omitempty"` + Gateway net.IP `json:"gateway,omitempty"` + IP6Address net.IP `json:"ip6address,omitempty"` + IP6Cidr string `json:"ip6cidr,omitempty"` + IP6Gateway net.IP `json:"ip6gateway,omitempty"` + IPAddress net.IP `json:"ipaddress,omitempty"` + IsDefault bool `json:"isdefault,omitempty"` + IsolationURI string `json:"isolationuri,omitempty"` + MacAddress string `json:"macaddress,omitempty"` + Netmask net.IP `json:"netmask,omitempty"` + NetworkID string `json:"networkid,omitempty"` + NetworkName string `json:"networkname,omitempty"` + SecondaryIP []NicSecondaryIP `json:"secondaryip,omitempty"` + TrafficType string `json:"traffictype,omitempty"` + Type string `json:"type,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` +} + +// NicSecondaryIP represents a link between NicID and IPAddress +type NicSecondaryIP struct { + ID string `json:"id"` + IPAddress net.IP `json:"ipaddress"` + NetworkID string `json:"networkid,omitempty"` + NicID string `json:"nicid,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` +} + +// ListNics represents the NIC search +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listNics.html +type ListNics struct { + VirtualMachineID string `json:"virtualmachineid"` + ForDisplay bool `json:"fordisplay,omitempty"` + Keyword string `json:"keyword,omitempty"` + NetworkID string `json:"networkid,omitempty"` + NicID string `json:"nicid,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` +} + +// ListNicsResponse represents a list of templates +type ListNicsResponse struct { + Count int `json:"count"` + Nic []Nic `json:"nic"` +} + +// AddIPToNic (Async) represents the assignation of a secondary IP +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/addIpToNic.html +type AddIPToNic struct { + NicID string `json:"nicid"` + IPAddress net.IP `json:"ipaddress"` +} + +// AddIPToNicResponse represents the addition of an IP to a NIC +type AddIPToNicResponse struct { + NicSecondaryIP NicSecondaryIP `json:"nicsecondaryip"` +} + +// RemoveIPFromNic (Async) represents a deletion request +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/removeIpFromNic.html +type RemoveIPFromNic struct { + ID string `json:"id"` +} + +// ActivateIP6 (Async) activates the IP6 on the given NIC +// +// Exoscale specific API: https://community.exoscale.ch/api/compute/#activateip6_GET +type ActivateIP6 struct { + NicID string `json:"nicid"` +} + +// ActivateIP6Response represents the modified NIC +type ActivateIP6Response struct { + Nic Nic `json:"nic"` +} diff --git a/vendor/github.com/exoscale/egoscale/request.go b/vendor/github.com/exoscale/egoscale/request.go new file mode 100644 index 0000000000..1a9fd1da03 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/request.go @@ -0,0 +1,352 @@ +package egoscale + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" +) + +// Error formats a CloudStack error into a standard error +func (e *ErrorResponse) Error() string { + return fmt.Sprintf("API error %s %d (%d): %s", e.ErrorCode, e.ErrorCode, e.CsErrorCode, e.ErrorText) +} + +// Success computes the values based on the RawMessage, either string or bool +func (e *booleanResponse) IsSuccess() (bool, error) { + if e.Success == nil { + return false, fmt.Errorf("Not a valid booleanResponse") + } + + str := "" + if err := json.Unmarshal(e.Success, &str); err != nil { + boolean := false + if e := json.Unmarshal(e.Success, &boolean); e != nil { + return false, e + } + return boolean, nil + } + return str == "true", nil +} + +// Error formats a CloudStack job response into a standard error +func (e *booleanResponse) Error() error { + success, err := e.IsSuccess() + + if err != nil { + return err + } + + if success { + return nil + } + + fmt.Printf("%#v", e) + return fmt.Errorf("API error: %s", e.DisplayText) +} + +func (exo *Client) parseResponse(resp *http.Response) (json.RawMessage, error) { + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + a, err := rawValues(b) + + if a == nil { + b, err = rawValue(b) + if err != nil { + return nil, err + } + } + + if resp.StatusCode >= 400 { + errorResponse := new(ErrorResponse) + if e := json.Unmarshal(b, errorResponse); e == nil && errorResponse.ErrorCode > 0 { + return nil, errorResponse + } + return nil, fmt.Errorf("%d %s", resp.StatusCode, b) + } + + return b, nil +} + +// asyncRequest perform an asynchronous job with a context +func (exo *Client) asyncRequest(ctx context.Context, request AsyncCommand) (interface{}, error) { + var err error + + res := request.asyncResponse() + exo.AsyncRequestWithContext(ctx, request, func(j *AsyncJobResult, er error) bool { + if er != nil { + err = er + return false + } + if j.JobStatus == Success { + if r := j.Response(res); err != nil { + err = r + } + return false + } + return true + }) + return res, err +} + +// syncRequest performs a sync request with a context +func (exo *Client) syncRequest(ctx context.Context, request syncCommand) (interface{}, error) { + body, err := exo.request(ctx, request) + if err != nil { + return nil, err + } + + response := request.response() + err = json.Unmarshal(body, response) + + // booleanResponse will alway be valid... + if err == nil { + if br, ok := response.(*booleanResponse); ok { + success, e := br.IsSuccess() + if e != nil { + return nil, e + } + if !success { + err = fmt.Errorf("Not a valid booleanResponse") + } + } + } + + if err != nil { + errResponse := new(ErrorResponse) + if e := json.Unmarshal(body, errResponse); e == nil && errResponse.ErrorCode > 0 { + return errResponse, nil + } + return nil, err + } + + return response, nil +} + +// BooleanRequest performs the given boolean command +func (exo *Client) BooleanRequest(req Command) error { + resp, err := exo.Request(req) + if err != nil { + return err + } + + if b, ok := resp.(*booleanResponse); ok { + return b.Error() + } + + panic(fmt.Errorf("The command %s is not a proper boolean response. %#v", req.name(), resp)) +} + +// BooleanRequestWithContext performs the given boolean command +func (exo *Client) BooleanRequestWithContext(ctx context.Context, req Command) error { + resp, err := exo.RequestWithContext(ctx, req) + if err != nil { + return err + } + + if b, ok := resp.(*booleanResponse); ok { + return b.Error() + } + + panic(fmt.Errorf("The command %s is not a proper boolean response. %#v", req.name(), resp)) +} + +// Request performs the given command +func (exo *Client) Request(request Command) (interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), exo.Timeout) + defer cancel() + + switch request.(type) { + case syncCommand: + return exo.syncRequest(ctx, request.(syncCommand)) + case AsyncCommand: + return exo.asyncRequest(ctx, request.(AsyncCommand)) + default: + panic(fmt.Errorf("The command %s is not a proper Sync or Async command", request.name())) + } +} + +// RequestWithContext preforms a request with a context +func (exo *Client) RequestWithContext(ctx context.Context, request Command) (interface{}, error) { + switch request.(type) { + case syncCommand: + return exo.syncRequest(ctx, request.(syncCommand)) + case AsyncCommand: + return exo.asyncRequest(ctx, request.(AsyncCommand)) + default: + panic(fmt.Errorf("The command %s is not a proper Sync or Async command", request.name())) + } +} + +// AsyncRequest performs the given command +func (exo *Client) AsyncRequest(request AsyncCommand, callback WaitAsyncJobResultFunc) { + ctx, cancel := context.WithTimeout(context.Background(), exo.Timeout) + defer cancel() + exo.AsyncRequestWithContext(ctx, request, callback) +} + +// AsyncRequestWithContext preforms a request with a context +func (exo *Client) AsyncRequestWithContext(ctx context.Context, request AsyncCommand, callback WaitAsyncJobResultFunc) { + body, err := exo.request(ctx, request) + if err != nil { + callback(nil, err) + return + } + + jobResult := new(AsyncJobResult) + if err := json.Unmarshal(body, jobResult); err != nil { + r := new(ErrorResponse) + if e := json.Unmarshal(body, r); e != nil && r.ErrorCode > 0 { + if !callback(nil, r) { + return + } + } + if !callback(nil, err) { + return + } + } + + // Successful response + if jobResult.JobID == "" || jobResult.JobStatus != Pending { + if !callback(jobResult, nil) { + return + } + } + + for iteration := 0; ; iteration++ { + time.Sleep(exo.RetryStrategy(int64(iteration))) + + req := &QueryAsyncJobResult{JobID: jobResult.JobID} + resp, err := exo.syncRequest(ctx, req) + if err != nil { + if !callback(nil, err) { + return + } + } + + result, ok := resp.(*QueryAsyncJobResultResponse) + if !ok { + if !callback(nil, fmt.Errorf("AsyncJobResult expected, got %t", resp)) { + return + } + } + + res := (*AsyncJobResult)(result) + + if res.JobStatus == Failure { + if !callback(nil, res.Error()) { + return + } + } else { + if !callback(res, nil) { + return + } + } + } +} + +// Payload builds the HTTP request from the given command +func (exo *Client) Payload(request Command) (string, error) { + params := url.Values{} + err := prepareValues("", ¶ms, request) + if err != nil { + return "", err + } + if hookReq, ok := request.(onBeforeHook); ok { + hookReq.onBeforeSend(¶ms) + } + params.Set("apikey", exo.APIKey) + params.Set("command", request.name()) + params.Set("response", "json") + + // This code is borrowed from net/url/url.go + // The way it's encoded by net/url doesn't match + // how CloudStack works. + var buf bytes.Buffer + keys := make([]string, 0, len(params)) + for k := range params { + keys = append(keys, k) + } + + sort.Strings(keys) + for _, k := range keys { + prefix := csEncode(k) + "=" + for _, v := range params[k] { + if buf.Len() > 0 { + buf.WriteByte('&') + } + buf.WriteString(prefix) + buf.WriteString(csEncode(v)) + } + } + + return buf.String(), nil +} + +// Sign signs the HTTP request and return it +func (exo *Client) Sign(query string) string { + mac := hmac.New(sha1.New, []byte(exo.apiSecret)) + mac.Write([]byte(strings.ToLower(query))) + signature := csEncode(base64.StdEncoding.EncodeToString(mac.Sum(nil))) + + return fmt.Sprintf("%s&signature=%s", csQuotePlus(query), signature) +} + +// request makes a Request while being close to the metal +func (exo *Client) request(ctx context.Context, req Command) (json.RawMessage, error) { + payload, err := exo.Payload(req) + if err != nil { + return nil, err + } + query := exo.Sign(payload) + + method := "GET" + url := fmt.Sprintf("%s?%s", exo.Endpoint, query) + + var body io.Reader + // respect Internet Explorer limit of 2048 + if len(url) > 1<<11 { + url = exo.Endpoint + method = "POST" + body = strings.NewReader(query) + } + + request, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + request = request.WithContext(ctx) + request.Header.Add("User-Agent", fmt.Sprintf("exoscale/egoscale (%v)", Version)) + + if method == "POST" { + request.Header.Add("Content-Type", "application/x-www-form-urlencoded") + request.Header.Add("Content-Length", strconv.Itoa(len(query))) + } + + resp, err := exo.HTTPClient.Do(request) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + text, err := exo.parseResponse(resp) + if err != nil { + return nil, err + } + + return text, nil +} diff --git a/vendor/github.com/exoscale/egoscale/request_type.go b/vendor/github.com/exoscale/egoscale/request_type.go new file mode 100644 index 0000000000..4b35247ff3 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/request_type.go @@ -0,0 +1,130 @@ +package egoscale + +import ( + "encoding/json" + "net/url" +) + +// Command represents a CloudStack request +type Command interface { + // CloudStack API command name + name() string +} + +// SyncCommand represents a CloudStack synchronous request +type syncCommand interface { + Command + // Response interface to Unmarshal the JSON into + response() interface{} +} + +// AsyncCommand represents a async CloudStack request +type AsyncCommand interface { + Command + // Response interface to Unmarshal the JSON into + asyncResponse() interface{} +} + +// ListCommand represents a CloudStack list request +type ListCommand interface { + Command + // SetPage defines the current pages + SetPage(int) + // SetPageSize defines the size of the page + SetPageSize(int) + // each reads the data from the response and feeds channels, and returns true if we are on the last page + each(interface{}, IterateItemFunc) +} + +// onBeforeHook represents an action to be done on the params before sending them +// +// This little took helps with issue of relying on JSON serialization logic only. +// `omitempty` may make sense in some cases but not all the time. +type onBeforeHook interface { + onBeforeSend(params *url.Values) error +} + +//go:generate stringer -type JobStatusType +const ( + // Pending represents a job in progress + Pending JobStatusType = iota + // Success represents a successfully completed job + Success + // Failure represents a job that has failed to complete + Failure +) + +// JobStatusType represents the status of a Job +type JobStatusType int + +//go:generate stringer -type ErrorCode +const ( + // Unauthorized represents ... (TODO) + Unauthorized ErrorCode = 401 + // MethodNotAllowed represents ... (TODO) + MethodNotAllowed ErrorCode = 405 + // UnsupportedActionError represents ... (TODO) + UnsupportedActionError ErrorCode = 422 + // APILimitExceeded represents ... (TODO) + APILimitExceeded ErrorCode = 429 + // MalformedParameterError represents ... (TODO) + MalformedParameterError ErrorCode = 430 + // ParamError represents ... (TODO) + ParamError ErrorCode = 431 + + // InternalError represents a server error + InternalError ErrorCode = 530 + // AccountError represents ... (TODO) + AccountError ErrorCode = 531 + // AccountResourceLimitError represents ... (TODO) + AccountResourceLimitError ErrorCode = 532 + // InsufficientCapacityError represents ... (TODO) + InsufficientCapacityError ErrorCode = 533 + // ResourceUnavailableError represents ... (TODO) + ResourceUnavailableError ErrorCode = 534 + // ResourceAllocationError represents ... (TODO) + ResourceAllocationError ErrorCode = 535 + // ResourceInUseError represents ... (TODO) + ResourceInUseError ErrorCode = 536 + // NetworkRuleConflictError represents ... (TODO) + NetworkRuleConflictError ErrorCode = 537 +) + +// ErrorCode represents the CloudStack ApiErrorCode enum +// +// See: https://github.com/apache/cloudstack/blob/master/api/src/org/apache/cloudstack/api/ApiErrorCode.java +type ErrorCode int + +// JobResultResponse represents a generic response to a job task +type JobResultResponse struct { + AccountID string `json:"accountid,omitempty"` + Cmd string `json:"cmd"` + Created string `json:"created"` + JobID string `json:"jobid"` + JobProcStatus int `json:"jobprocstatus"` + JobResult *json.RawMessage `json:"jobresult"` + JobStatus JobStatusType `json:"jobstatus"` + JobResultType string `json:"jobresulttype"` + UserID string `json:"userid,omitempty"` +} + +// ErrorResponse represents the standard error response from CloudStack +type ErrorResponse struct { + ErrorCode ErrorCode `json:"errorcode"` + CsErrorCode int `json:"cserrorcode"` + ErrorText string `json:"errortext"` + UUIDList []UUIDItem `json:"uuidList,omitempty"` // uuid*L*ist is not a typo +} + +// UUIDItem represents an item of the UUIDList part of an ErrorResponse +type UUIDItem struct { + Description string `json:"description,omitempty"` + SerialVersionUID int64 `json:"serialVersionUID,omitempty"` + UUID string `json:"uuid"` +} + +// booleanResponse represents a boolean response (usually after a deletion) +type booleanResponse struct { + Success json.RawMessage `json:"success"` + DisplayText string `json:"displaytext,omitempty"` +} diff --git a/vendor/github.com/exoscale/egoscale/resource_metadata.go b/vendor/github.com/exoscale/egoscale/resource_metadata.go new file mode 100644 index 0000000000..7b823adbff --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/resource_metadata.go @@ -0,0 +1,9 @@ +package egoscale + +func (*ListResourceDetails) name() string { + return "listResourceDetails" +} + +func (*ListResourceDetails) response() interface{} { + return new(ListResourceDetailsResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/resource_metadata_type.go b/vendor/github.com/exoscale/egoscale/resource_metadata_type.go new file mode 100644 index 0000000000..4b319916a9 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/resource_metadata_type.go @@ -0,0 +1,26 @@ +package egoscale + +// ListResourceDetails lists the resource tag(s) (but different from listTags...) +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listResourceDetails.html +type ListResourceDetails struct { + ResourceType string `json:"resourcetype" doc:"list by resource type"` + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + ForDisplay bool `json:"fordisplay,omitempty" doc:"if set to true, only details marked with display=true, are returned. False by default"` + Key string `json:"key,omitempty" doc:"list by key"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty" doc:"list objects by project"` + ResourceID string `json:"resourceid,omitempty" doc:"list by resource id"` + Value string `json:"value,omitempty" doc:"list by key, value. Needs to be passed only along with key"` + IsRecursive bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` +} + +// ListResourceDetailsResponse represents a list of resource details +type ListResourceDetailsResponse struct { + Count int `json:"count"` + ResourceDetail []ResourceTag `json:"resourcedetail"` +} diff --git a/vendor/github.com/exoscale/egoscale/security_groups.go b/vendor/github.com/exoscale/egoscale/security_groups.go new file mode 100644 index 0000000000..07c94ea040 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/security_groups.go @@ -0,0 +1,203 @@ +package egoscale + +import ( + "context" + "fmt" + "net/url" + "strconv" + "strings" + + "github.com/jinzhu/copier" +) + +// ResourceType returns the type of the resource +func (*SecurityGroup) ResourceType() string { + return "SecurityGroup" +} + +// Get loads the given Security Group +func (sg *SecurityGroup) Get(ctx context.Context, client *Client) error { + if sg.ID == "" && sg.Name == "" { + return fmt.Errorf("A SecurityGroup may only be searched using ID or Name") + } + + resp, err := client.List(&SecurityGroup{Name: sg.Name, ID: sg.ID}) + if err != nil { + return err + } + + listSize := len(resp) + + if listSize == 0 { + err := &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("SecurityGroup not found id: %s, name: %s", sg.ID, sg.Name), + } + return err + } else if listSize > 1 { + return fmt.Errorf("More than one SecurityGroup was found. Query: id: %s, name: %s", sg.ID, sg.Name) + } + + securGroup, ok := resp[0].(*SecurityGroup) + if !ok { + return fmt.Errorf("SecurityGroup expected, got %t", resp[0]) + } + + return copier.Copy(sg, securGroup) +} + +// ListRequest builds the ListSecurityGroups request +func (sg *SecurityGroup) ListRequest() (ListCommand, error) { + //TODO add tags + req := &ListSecurityGroups{ + Account: sg.Account, + DomainID: sg.DomainID, + ID: sg.ID, + ProjectID: sg.ProjectID, + SecurityGroupName: sg.Name, + } + + return req, nil +} + +// Delete deletes the given Security Group +func (sg *SecurityGroup) Delete(ctx context.Context, client *Client) error { + if sg.ID == "" && sg.Name == "" { + return fmt.Errorf("A SecurityGroup may only be deleted using ID or Name") + } + + req := &DeleteSecurityGroup{ + Account: sg.Account, + DomainID: sg.DomainID, + ProjectID: sg.ProjectID, + } + + if sg.ID != "" { + req.ID = sg.ID + } else { + req.Name = sg.Name + } + + return client.BooleanRequestWithContext(ctx, req) +} + +// RuleByID returns IngressRule or EgressRule by a rule ID +func (sg *SecurityGroup) RuleByID(ruleID string) (*IngressRule, *EgressRule) { + for i, in := range sg.IngressRule { + if ruleID == in.RuleID { + return &sg.IngressRule[i], nil + } + } + + for i, out := range sg.EgressRule { + if ruleID == out.RuleID { + return nil, &sg.EgressRule[i] + } + } + + return nil, nil +} + +// name returns the CloudStack API command name +func (*CreateSecurityGroup) name() string { + return "createSecurityGroup" +} + +func (*CreateSecurityGroup) response() interface{} { + return new(CreateSecurityGroupResponse) +} + +// name returns the CloudStack API command name +func (*DeleteSecurityGroup) name() string { + return "deleteSecurityGroup" +} + +func (*DeleteSecurityGroup) response() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*AuthorizeSecurityGroupIngress) name() string { + return "authorizeSecurityGroupIngress" +} + +func (*AuthorizeSecurityGroupIngress) asyncResponse() interface{} { + return new(AuthorizeSecurityGroupIngressResponse) +} + +func (req *AuthorizeSecurityGroupIngress) onBeforeSend(params *url.Values) error { + // ICMP code and type may be zero but can also be omitted... + if strings.HasPrefix(strings.ToLower(req.Protocol), "icmp") { + params.Set("icmpcode", strconv.FormatInt(int64(req.IcmpCode), 10)) + params.Set("icmptype", strconv.FormatInt(int64(req.IcmpType), 10)) + } + // StartPort may be zero but can also be omitted... + if req.EndPort != 0 && req.StartPort == 0 { + params.Set("startport", "0") + } + return nil +} + +// name returns the CloudStack API command name +func (*AuthorizeSecurityGroupEgress) name() string { + return "authorizeSecurityGroupEgress" +} + +func (*AuthorizeSecurityGroupEgress) asyncResponse() interface{} { + return new(AuthorizeSecurityGroupEgressResponse) +} + +func (req *AuthorizeSecurityGroupEgress) onBeforeSend(params *url.Values) error { + return (*AuthorizeSecurityGroupIngress)(req).onBeforeSend(params) +} + +// name returns the CloudStack API command name +func (*RevokeSecurityGroupIngress) name() string { + return "revokeSecurityGroupIngress" +} + +func (*RevokeSecurityGroupIngress) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*RevokeSecurityGroupEgress) name() string { + return "revokeSecurityGroupEgress" +} + +func (*RevokeSecurityGroupEgress) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*ListSecurityGroups) name() string { + return "listSecurityGroups" +} + +func (*ListSecurityGroups) response() interface{} { + return new(ListSecurityGroupsResponse) +} + +// SetPage sets the current page +func (lsg *ListSecurityGroups) SetPage(page int) { + lsg.Page = page +} + +// SetPageSize sets the page size +func (lsg *ListSecurityGroups) SetPageSize(pageSize int) { + lsg.PageSize = pageSize +} + +func (*ListSecurityGroups) each(resp interface{}, callback IterateItemFunc) { + sgs, ok := resp.(*ListSecurityGroupsResponse) + if !ok { + callback(nil, fmt.Errorf("ListSecurityGroupsResponse expected, got %t", resp)) + return + } + + for i := range sgs.SecurityGroup { + if !callback(&sgs.SecurityGroup[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/security_groups_type.go b/vendor/github.com/exoscale/egoscale/security_groups_type.go new file mode 100644 index 0000000000..7f3897b555 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/security_groups_type.go @@ -0,0 +1,146 @@ +package egoscale + +// SecurityGroup represent a firewalling set of rules +type SecurityGroup struct { + ID string `json:"id"` + Account string `json:"account,omitempty"` + Description string `json:"description,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Name string `json:"name"` + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` + VirtualMachineCount int `json:"virtualmachinecount,omitempty"` // CloudStack 4.6+ + VirtualMachineIDs []string `json:"virtualmachineids,omitempty"` // CloudStack 4.6+ + IngressRule []IngressRule `json:"ingressrule"` + EgressRule []EgressRule `json:"egressrule"` + Tags []ResourceTag `json:"tags,omitempty"` + JobID string `json:"jobid,omitempty"` + JobStatus JobStatusType `json:"jobstatus,omitempty"` +} + +// IngressRule represents the ingress rule +type IngressRule struct { + RuleID string `json:"ruleid"` + Account string `json:"account,omitempty"` + Cidr string `json:"cidr,omitempty"` + Description string `json:"description,omitempty"` + IcmpType uint8 `json:"icmptype,omitempty"` + IcmpCode uint8 `json:"icmpcode,omitempty"` + StartPort uint16 `json:"startport,omitempty"` + EndPort uint16 `json:"endport,omitempty"` + Protocol string `json:"protocol,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + SecurityGroupID string `json:"securitygroupid,omitempty"` + SecurityGroupName string `json:"securitygroupname,omitempty"` + UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"` + JobID string `json:"jobid,omitempty"` + JobStatus JobStatusType `json:"jobstatus,omitempty"` +} + +// EgressRule represents the ingress rule +type EgressRule IngressRule + +// UserSecurityGroup represents the traffic of another security group +type UserSecurityGroup struct { + Group string `json:"group,omitempty"` + Account string `json:"account,omitempty"` +} + +// SecurityGroupResponse represents a generic security group response +type SecurityGroupResponse struct { + SecurityGroup SecurityGroup `json:"securitygroup"` +} + +// CreateSecurityGroup represents a security group creation +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/createSecurityGroup.html +type CreateSecurityGroup struct { + Name string `json:"name"` + Description string `json:"description,omitempty"` +} + +// CreateSecurityGroupResponse represents a new security group +type CreateSecurityGroupResponse SecurityGroupResponse + +// DeleteSecurityGroup represents a security group deletion +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/deleteSecurityGroup.html +type DeleteSecurityGroup struct { + Account string `json:"account,omitempty"` // Must be specified with Domain ID + DomainID string `json:"domainid,omitempty"` // Must be specified with Account + ID string `json:"id,omitempty"` // Mutually exclusive with name + Name string `json:"name,omitempty"` // Mutually exclusive with id + ProjectID string `json:"project,omitempty"` +} + +// AuthorizeSecurityGroupIngress (Async) represents the ingress rule creation +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/authorizeSecurityGroupIngress.html +type AuthorizeSecurityGroupIngress struct { + Account string `json:"account,omitempty"` + CidrList []string `json:"cidrlist,omitempty"` + Description string `json:"description,omitempty"` + DomainID string `json:"domainid,omitempty"` + IcmpType uint8 `json:"icmptype,omitempty"` + IcmpCode uint8 `json:"icmpcode,omitempty"` + StartPort uint16 `json:"startport,omitempty"` + EndPort uint16 `json:"endport,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Protocol string `json:"protocol,omitempty"` + SecurityGroupID string `json:"securitygroupid,omitempty"` + SecurityGroupName string `json:"securitygroupname,omitempty"` + UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"` +} + +// AuthorizeSecurityGroupIngressResponse represents the new egress rule +// /!\ the Cloud Stack API document is not fully accurate. /!\ +type AuthorizeSecurityGroupIngressResponse SecurityGroupResponse + +// AuthorizeSecurityGroupEgress (Async) represents the egress rule creation +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/authorizeSecurityGroupEgress.html +type AuthorizeSecurityGroupEgress AuthorizeSecurityGroupIngress + +// AuthorizeSecurityGroupEgressResponse represents the new egress rule +// /!\ the Cloud Stack API document is not fully accurate. /!\ +type AuthorizeSecurityGroupEgressResponse CreateSecurityGroupResponse + +// RevokeSecurityGroupIngress (Async) represents the ingress/egress rule deletion +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/revokeSecurityGroupIngress.html +type RevokeSecurityGroupIngress struct { + ID string `json:"id"` +} + +// RevokeSecurityGroupEgress (Async) represents the ingress/egress rule deletion +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/revokeSecurityGroupEgress.html +type RevokeSecurityGroupEgress struct { + ID string `json:"id"` +} + +// ListSecurityGroups represents a search for security groups +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listSecurityGroups.html +type ListSecurityGroups struct { + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Type string `json:"type,omitempty"` + SecurityGroupName string `json:"securitygroupname,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` +} + +// ListSecurityGroupsResponse represents a list of security groups +type ListSecurityGroupsResponse struct { + Count int `json:"count"` + SecurityGroup []SecurityGroup `json:"securitygroup"` +} diff --git a/vendor/github.com/exoscale/egoscale/serialization.go b/vendor/github.com/exoscale/egoscale/serialization.go new file mode 100644 index 0000000000..039a863a98 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/serialization.go @@ -0,0 +1,254 @@ +package egoscale + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "log" + "net" + "net/url" + "reflect" + "strconv" + "strings" +) + +func csQuotePlus(s string) string { + s = strings.Replace(s, "+", "%20", -1) + s = strings.Replace(s, "%5B", "[", -1) + s = strings.Replace(s, "%5D", "]", -1) + return s +} + +func csEncode(s string) string { + return csQuotePlus(url.QueryEscape(s)) +} + +func rawValue(b json.RawMessage) (json.RawMessage, error) { + var m map[string]json.RawMessage + + if err := json.Unmarshal(b, &m); err != nil { + return nil, err + } + for _, v := range m { + return v, nil + } + return nil, nil +} + +func rawValues(b json.RawMessage) (json.RawMessage, error) { + var i []json.RawMessage + + if err := json.Unmarshal(b, &i); err != nil { + return nil, nil + } + + return i[0], nil +} + +// prepareValues uses a command to build a POST request +// +// command is not a Command so it's easier to Test +func prepareValues(prefix string, params *url.Values, command interface{}) error { + value := reflect.ValueOf(command) + typeof := reflect.TypeOf(command) + + // Going up the pointer chain to find the underlying struct + for typeof.Kind() == reflect.Ptr { + typeof = typeof.Elem() + value = value.Elem() + } + + for i := 0; i < typeof.NumField(); i++ { + field := typeof.Field(i) + val := value.Field(i) + tag := field.Tag + if json, ok := tag.Lookup("json"); ok { + n, required := extractJSONTag(field.Name, json) + name := prefix + n + + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v := val.Int() + if v == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), field.Name, val.Kind()) + } + } else { + (*params).Set(name, strconv.FormatInt(v, 10)) + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v := val.Uint() + if v == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), field.Name, val.Kind()) + } + } else { + (*params).Set(name, strconv.FormatUint(v, 10)) + } + case reflect.Float32, reflect.Float64: + v := val.Float() + if v == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), field.Name, val.Kind()) + } + } else { + (*params).Set(name, strconv.FormatFloat(v, 'f', -1, 64)) + } + case reflect.String: + v := val.String() + if v == "" { + if required { + return fmt.Errorf("%s.%s (%v) is required, got \"\"", typeof.Name(), field.Name, val.Kind()) + } + } else { + (*params).Set(name, v) + } + case reflect.Bool: + v := val.Bool() + if v == false { + if required { + params.Set(name, "false") + } + } else { + (*params).Set(name, "true") + } + case reflect.Ptr: + if val.IsNil() { + if required { + return fmt.Errorf("%s.%s (%v) is required, got tempty ptr", typeof.Name(), field.Name, val.Kind()) + } + } else { + switch field.Type.Elem().Kind() { + case reflect.Bool: + params.Set(name, strconv.FormatBool(val.Elem().Bool())) + default: + log.Printf("[SKIP] %s.%s (%v) not supported", typeof.Name(), field.Name, field.Type.Elem().Kind()) + } + } + case reflect.Slice: + switch field.Type.Elem().Kind() { + case reflect.Uint8: + switch field.Type { + case reflect.TypeOf(net.IPv4zero): + ip := (net.IP)(val.Bytes()) + if ip == nil || ip.Equal(net.IPv4zero) { + if required { + return fmt.Errorf("%s.%s (%v) is required, got zero IPv4 address", typeof.Name(), field.Name, val.Kind()) + } + } else { + (*params).Set(name, ip.String()) + } + default: + if val.Len() == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), field.Name, val.Kind()) + } + } else { + v := val.Bytes() + (*params).Set(name, base64.StdEncoding.EncodeToString(v)) + } + } + case reflect.String: + { + if val.Len() == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), field.Name, val.Kind()) + } + } else { + elems := make([]string, 0, val.Len()) + for i := 0; i < val.Len(); i++ { + // XXX what if the value contains a comma? Double encode? + s := val.Index(i).String() + elems = append(elems, s) + } + (*params).Set(name, strings.Join(elems, ",")) + } + } + default: + if val.Len() == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), field.Name, val.Kind()) + } + } else { + err := prepareList(name, params, val.Interface()) + if err != nil { + return err + } + } + } + case reflect.Map: + if val.Len() == 0 { + if required { + return fmt.Errorf("%s.%s (%v) is required, got empty map", typeof.Name(), field.Name, val.Kind()) + } + } else { + err := prepareMap(name, params, val.Interface()) + if err != nil { + return err + } + } + default: + if required { + return fmt.Errorf("Unsupported type %s.%s (%v)", typeof.Name(), field.Name, val.Kind()) + } + } + } else { + log.Printf("[SKIP] %s.%s no json label found", typeof.Name(), field.Name) + } + } + + return nil +} + +func prepareList(prefix string, params *url.Values, slice interface{}) error { + value := reflect.ValueOf(slice) + + for i := 0; i < value.Len(); i++ { + prepareValues(fmt.Sprintf("%s[%d].", prefix, i), params, value.Index(i).Interface()) + } + + return nil +} + +func prepareMap(prefix string, params *url.Values, m interface{}) error { + value := reflect.ValueOf(m) + + for i, key := range value.MapKeys() { + var keyName string + var keyValue string + + switch key.Kind() { + case reflect.String: + keyName = key.String() + default: + return fmt.Errorf("Only map[string]string are supported (XXX)") + } + + val := value.MapIndex(key) + switch val.Kind() { + case reflect.String: + keyValue = val.String() + default: + return fmt.Errorf("Only map[string]string are supported (XXX)") + } + params.Set(fmt.Sprintf("%s[%d].%s", prefix, i, keyName), keyValue) + } + return nil +} + +// extractJSONTag returns the variable name or defaultName as well as if the field is required (!omitempty) +func extractJSONTag(defaultName, jsonTag string) (string, bool) { + tags := strings.Split(jsonTag, ",") + name := tags[0] + required := true + for _, tag := range tags { + if tag == "omitempty" { + required = false + } + } + + if name == "" || name == "omitempty" { + name = defaultName + } + return name, required +} diff --git a/vendor/github.com/exoscale/egoscale/service_offerings.go b/vendor/github.com/exoscale/egoscale/service_offerings.go new file mode 100644 index 0000000000..78066cd121 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/service_offerings.go @@ -0,0 +1,16 @@ +package egoscale + +// name returns the CloudStack API command name +func (*ListServiceOfferings) name() string { + return "listServiceOfferings" +} + +func (*ListServiceOfferings) response() interface{} { + return new(ListServiceOfferingsResponse) +} + +// ListServiceOfferingsResponse represents a list of service offerings +type ListServiceOfferingsResponse struct { + Count int `json:"count"` + ServiceOffering []ServiceOffering `json:"serviceoffering"` +} diff --git a/vendor/github.com/exoscale/egoscale/service_offerings_type.go b/vendor/github.com/exoscale/egoscale/service_offerings_type.go new file mode 100644 index 0000000000..4e928439dd --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/service_offerings_type.go @@ -0,0 +1,57 @@ +package egoscale + +// ServiceOffering corresponds to the Compute Offerings +// +// A service offering correspond to some hardware features (CPU, RAM). +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/service_offerings.html +type ServiceOffering struct { + Authorized bool `json:"authorized,omitempty" doc:"is the account/domain authorized to use this service offering"` + CPUNumber int `json:"cpunumber,omitempty" doc:"the number of CPU"` + CPUSpeed int `json:"cpuspeed,omitempty" doc:"the clock rate CPU speed in Mhz"` + Created string `json:"created,omitempty" doc:"the date this service offering was created"` + DefaultUse bool `json:"defaultuse,omitempty" doc:"is this a default system vm offering"` + DeploymentPlanner string `json:"deploymentplanner,omitempty" doc:"deployment strategy used to deploy VM."` + DiskBytesReadRate int64 `json:"diskBytesReadRate,omitempty" doc:"bytes read rate of the service offering"` + DiskBytesWriteRate int64 `json:"diskBytesWriteRate,omitempty" doc:"bytes write rate of the service offering"` + DiskIopsReadRate int64 `json:"diskIopsReadRate,omitempty" doc:"io requests read rate of the service offering"` + DiskIopsWriteRate int64 `json:"diskIopsWriteRate,omitempty" doc:"io requests write rate of the service offering"` + Displaytext string `json:"displaytext,omitempty" doc:"an alternate display text of the service offering."` + Domain string `json:"domain,omitempty" doc:"Domain name for the offering"` + DomainID string `json:"domainid,omitempty" doc:"the domain id of the service offering"` + HostTags string `json:"hosttags,omitempty" doc:"the host tag for the service offering"` + HypervisorSnapshotReserve int `json:"hypervisorsnapshotreserve,omitempty" doc:"Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)"` + ID string `json:"id,omitempty" doc:"the id of the service offering"` + IsCustomized bool `json:"iscustomized,omitempty" doc:"is true if the offering is customized"` + IsCustomizedIops bool `json:"iscustomizediops,omitempty" doc:"true if disk offering uses custom iops, false otherwise"` + IsSystem bool `json:"issystem,omitempty" doc:"is this a system vm offering"` + IsVolatile bool `json:"isvolatile,omitempty" doc:"true if the vm needs to be volatile, i.e., on every reboot of vm from API root disk is discarded and creates a new root disk"` + LimitCPUUse bool `json:"limitcpuuse,omitempty" doc:"restrict the CPU usage to committed service offering"` + MaxIops int64 `json:"maxiops,omitempty" doc:"the max iops of the disk offering"` + Memory int `json:"memory,omitempty" doc:"the memory in MB"` + MinIops int64 `json:"miniops,omitempty" doc:"the min iops of the disk offering"` + Name string `json:"name,omitempty" doc:"the name of the service offering"` + NetworkRate int `json:"networkrate,omitempty" doc:"data transfer rate in megabits per second allowed."` + OfferHA bool `json:"offerha,omitempty" doc:"the ha support in the service offering"` + Restricted bool `json:"restricted,omitempty" doc:"is this offering restricted"` + ServiceOfferingDetails map[string]string `json:"serviceofferingdetails,omitempty" doc:"additional key/value details tied with this service offering"` + StorageType string `json:"storagetype,omitempty" doc:"the storage type for this service offering"` + SystemVMType string `json:"systemvmtype,omitempty" doc:"is this a the systemvm type for system vm offering"` + Tags string `json:"tags,omitempty" doc:"the tags for the service offering"` +} + +// ListServiceOfferings represents a query for service offerings +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listServiceOfferings.html +type ListServiceOfferings struct { + DomainID string `json:"domainid,omitempty" doc:"the ID of the domain associated with the service offering"` + ID string `json:"id,omitempty" doc:"ID of the service offering"` + IsSystem *bool `json:"issystem,omitempty" doc:"is this a system vm offering"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"name of the service offering"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + Restricted *bool `json:"restricted,omitempty" doc:"filter by the restriction flag: true to list only the restricted service offerings, false to list non-restricted service offerings, or nothing for all."` + SystemVMType string `json:"systemvmtype,omitempty" doc:"the system VM type. Possible types are \"consoleproxy\", \"secondarystoragevm\" or \"domainrouter\"."` + VirtualMachineID string `json:"virtualmachineid,omitempty" doc:"the ID of the virtual machine. Pass this in if you want to see the available service offering that a virtual machine can be changed to."` +} diff --git a/vendor/github.com/exoscale/egoscale/snapshots.go b/vendor/github.com/exoscale/egoscale/snapshots.go new file mode 100644 index 0000000000..457e1abfcb --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/snapshots.go @@ -0,0 +1,53 @@ +package egoscale + +// ResourceType returns the type of the resource +func (*Snapshot) ResourceType() string { + return "Snapshot" +} + +// name returns the CloudStack API command name +func (*CreateSnapshot) name() string { + return "createSnapshot" +} + +func (*CreateSnapshot) asyncResponse() interface{} { + return new(CreateSnapshotResponse) +} + +// CreateSnapshotResponse represents a freshly created snapshot +type CreateSnapshotResponse struct { + Snapshot Snapshot `json:"snapshot"` +} + +// name returns the CloudStack API command name +func (*ListSnapshots) name() string { + return "listSnapshots" +} + +func (*ListSnapshots) response() interface{} { + return new(ListSnapshotsResponse) +} + +// ListSnapshotsResponse represents a list of volume snapshots +type ListSnapshotsResponse struct { + Count int `json:"count"` + Snapshot []Snapshot `json:"snapshot"` +} + +// name returns the CloudStack API command name +func (*DeleteSnapshot) name() string { + return "deleteSnapshot" +} + +func (*DeleteSnapshot) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*RevertSnapshot) name() string { + return "revertSnapshot" +} + +func (*RevertSnapshot) asyncResponse() interface{} { + return new(booleanResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/snapshots_type.go b/vendor/github.com/exoscale/egoscale/snapshots_type.go new file mode 100644 index 0000000000..a2d7f3e0dd --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/snapshots_type.go @@ -0,0 +1,74 @@ +package egoscale + +// Snapshot represents a volume snapshot +type Snapshot struct { + ID string `json:"id"` + Account string `json:"account"` + Created string `json:"created,omitempty"` + Domain string `json:"domain"` + DomainID string `json:"domainid"` + IntervalType string `json:"intervaltype,omitempty"` // hourly, daily, weekly, monthly, ..., none + Name string `json:"name,omitempty"` + PhysicalSize int64 `json:"physicalsize"` + Project string `json:"project"` + ProjectID string `json:"projectid"` + Revertable bool `json:"revertable,omitempty"` + Size int64 `json:"size,omitempty"` + SnapshotType string `json:"snapshottype,omitempty"` + State string `json:"state"` // BackedUp, Creating, BackingUp, ... + VolumeID string `json:"volumeid"` + VolumeName string `json:"volumename,omitempty"` + VolumeType string `json:"volumetype,omitempty"` + ZoneID string `json:"zoneid"` + Tags []ResourceTag `json:"tags"` + JobID string `json:"jobid,omitempty"` + JobStatus JobStatusType `json:"jobstatus,omitempty"` +} + +// CreateSnapshot represents a request to create a volume snapshot +// +// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/createSnapshot.html +type CreateSnapshot struct { + VolumeID string `json:"volumeid" doc:"The ID of the disk volume"` + Account string `json:"account,omitempty" doc:"The account of the snapshot. The account parameter must be used with the domainId parameter."` + Name string `json:"name,omitempty" doc:"the name of the snapshot"` + DomainID string `json:"domainid,omitempty" doc:"The domain ID of the snapshot. If used with the account parameter, specifies a domain for the account associated with the disk volume."` + PolicyID string `json:"policyid,omitempty" doc:"policy id of the snapshot, if this is null, then use MANUAL_POLICY."` + QuiesceVM *bool `json:"quiescevm,omitempty" doc:"quiesce vm if true"` +} + +// ListSnapshots lists the volume snapshots +// +// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/listSnapshots.html +type ListSnapshots struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + ID string `json:"id,omitempty" doc:"lists snapshot by snapshot ID"` + IDs []string `json:"ids,omitempty" doc:"the IDs of the snapshots, mutually exclusive with id"` + IntervalType string `json:"intervaltype,omitempty" doc:"valid values are HOURLY, DAILY, WEEKLY, and MONTHLY."` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Name string `json:"name,omitempty" doc:"lists snapshot by snapshot name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty" doc:"list objects by project"` + SnapshotType string `json:"snapshottype,omitempty" doc:"valid values are MANUAL or RECURRING."` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + VolumeID string `json:"volumeid,omitempty" doc:"the ID of the disk volume"` + ZoneID string `json:"zoneid,omitempty" doc:"list snapshots by zone id"` +} + +// DeleteSnapshot represents the deletion of a volume snapshot +// +// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteSnapshot.html +type DeleteSnapshot struct { + ID string `json:"id" doc:"The ID of the snapshot"` +} + +// RevertSnapshot revert a volume snapshot +// +// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/revertSnapshot.html +type RevertSnapshot struct { + ID string `json:"id" doc:"The ID of the snapshot"` +} diff --git a/vendor/github.com/exoscale/egoscale/tags.go b/vendor/github.com/exoscale/egoscale/tags.go new file mode 100644 index 0000000000..0a41423f7d --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/tags.go @@ -0,0 +1,28 @@ +package egoscale + +// name returns the CloudStack API command name +func (*CreateTags) name() string { + return "createTags" +} + +func (*CreateTags) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*DeleteTags) name() string { + return "deleteTags" +} + +func (*DeleteTags) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*ListTags) name() string { + return "listTags" +} + +func (*ListTags) response() interface{} { + return new(ListTagsResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/tags_type.go b/vendor/github.com/exoscale/egoscale/tags_type.go new file mode 100644 index 0000000000..9bc85d795a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/tags_type.go @@ -0,0 +1,61 @@ +package egoscale + +// ResourceTag is a tag associated with a resource +// +// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/4.9/management.html +type ResourceTag struct { + Account string `json:"account,omitempty" doc:"the account associated with the tag"` + Customer string `json:"customer,omitempty" doc:"customer associated with the tag"` + Domain string `json:"domain,omitempty" doc:"the domain associated with the tag"` + DomainID string `json:"domainid,omitempty" doc:"the ID of the domain associated with the tag"` + Key string `json:"key,omitempty" doc:"tag key name"` + Project string `json:"project,omitempty" doc:"the project name where tag belongs to"` + ProjectID string `json:"projectid,omitempty" doc:"the project id the tag belongs to"` + ResourceID string `json:"resourceid,omitempty" doc:"id of the resource"` + ResourceType string `json:"resourcetype,omitempty" doc:"resource type"` + Value string `json:"value,omitempty" doc:"tag value"` +} + +// CreateTags (Async) creates resource tag(s) +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createTags.html +type CreateTags struct { + ResourceIDs []string `json:"resourceids" doc:"list of resources to create the tags for"` + ResourceType string `json:"resourcetype" doc:"type of the resource"` + Tags []ResourceTag `json:"tags" doc:"Map of tags (key/value pairs)"` + Customer string `json:"customer,omitempty" doc:"identifies client specific tag. When the value is not null, the tag can't be used by cloudStack code internally"` +} + +// DeleteTags (Async) deletes the resource tag(s) +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteTags.html +type DeleteTags struct { + ResourceIDs []string `json:"resourceids" doc:"Delete tags for resource id(s)"` + ResourceType string `json:"resourcetype" doc:"Delete tag by resource type"` + Tags []ResourceTag `json:"tags,omitempty" doc:"Delete tags matching key/value pairs"` +} + +// ListTags list resource tag(s) +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listTags.html +type ListTags struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + Customer string `json:"customer,omitempty" doc:"list by customer name"` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Key string `json:"key,omitempty" doc:"list by key"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty" doc:"list objects by project"` + ResourceID string `json:"resourceid,omitempty" doc:"list by resource id"` + ResourceType string `json:"resourcetype,omitempty" doc:"list by resource type"` + Value string `json:"value,omitempty" doc:"list by value"` +} + +// ListTagsResponse represents a list of resource tags +type ListTagsResponse struct { + Count int `json:"count"` + Tag []ResourceTag `json:"tag"` +} diff --git a/vendor/github.com/exoscale/egoscale/templates.go b/vendor/github.com/exoscale/egoscale/templates.go new file mode 100644 index 0000000000..0d1864d769 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/templates.go @@ -0,0 +1,63 @@ +package egoscale + +import "fmt" + +// ListRequest builds the ListTemplates request +func (temp *Template) ListRequest() (ListCommand, error) { + req := &ListTemplates{ + Name: temp.Name, + Account: temp.Account, + DomainID: temp.DomainID, + ID: temp.ID, + ProjectID: temp.ProjectID, + ZoneID: temp.ZoneID, + Hypervisor: temp.Hypervisor, + //TODO Tags + } + if temp.IsFeatured { + req.TemplateFilter = "featured" + } + if temp.Removed != "" { + *req.ShowRemoved = true + } + + return req, nil +} + +func (*ListTemplates) each(resp interface{}, callback IterateItemFunc) { + temps, ok := resp.(*ListTemplatesResponse) + if !ok { + callback(nil, fmt.Errorf("ListTemplatesResponse expected, got %t", resp)) + return + } + + for i := range temps.Template { + if !callback(&temps.Template[i], nil) { + break + } + } +} + +// SetPage sets the current page +func (ls *ListTemplates) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListTemplates) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// ResourceType returns the type of the resource +func (*Template) ResourceType() string { + return "Template" +} + +// name returns the CloudStack API command name +func (*ListTemplates) name() string { + return "listTemplates" +} + +func (*ListTemplates) response() interface{} { + return new(ListTemplatesResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/templates_type.go b/vendor/github.com/exoscale/egoscale/templates_type.go new file mode 100644 index 0000000000..38ce276995 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/templates_type.go @@ -0,0 +1,66 @@ +package egoscale + +// Template represents a machine to be deployed +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/templates.html +type Template struct { + Account string `json:"account,omitempty"` + AccountID string `json:"accountid,omitempty"` + Bootable bool `json:"bootable,omitempty"` + Checksum string `json:"checksum,omitempty"` + Created string `json:"created,omitempty"` + CrossZones bool `json:"crossZones,omitempty"` // not a typo + Details map[string]string `json:"details,omitempty"` + DisplayText string `json:"displaytext,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Format string `json:"format,omitempty"` + HostID string `json:"hostid,omitempty"` + HostName string `json:"hostname,omitempty"` + Hypervisor string `json:"hypervisor,omitempty"` + ID string `json:"id,omitempty"` + IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty"` + IsExtractable bool `json:"isextractable,omitempty"` + IsFeatured bool `json:"isfeatured,omitempty"` + IsPublic bool `json:"ispublic,omitempty"` + IsReady bool `json:"isready,omitempty"` + Name string `json:"name,omitempty"` + OsTypeID string `json:"ostypeid,omitempty"` + OsTypeName string `json:"ostypename,omitempty"` + PasswordEnabled bool `json:"passwordenabled,omitempty"` + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` + Removed string `json:"removed,omitempty"` + Size int64 `json:"size,omitempty"` + SourceTemplateID string `json:"sourcetemplateid,omitempty"` + SSHKeyEnabled bool `json:"sshkeyenabled,omitempty"` + Status string `json:"status,omitempty"` + ZoneID string `json:"zoneid,omitempty"` + ZoneName string `json:"zonename,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` +} + +// ListTemplates represents a template query filter +type ListTemplates struct { + TemplateFilter string `json:"templatefilter"` // featured, etc. + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + Hypervisor string `json:"hypervisor,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Name string `json:"name,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ProjectID string `json:"projectid,omitempty"` + ShowRemoved *bool `json:"showremoved,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + ZoneID string `json:"zoneid,omitempty"` +} + +// ListTemplatesResponse represents a list of templates +type ListTemplatesResponse struct { + Count int `json:"count"` + Template []Template `json:"template"` +} diff --git a/vendor/github.com/exoscale/egoscale/users.go b/vendor/github.com/exoscale/egoscale/users.go new file mode 100644 index 0000000000..434704d704 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/users.go @@ -0,0 +1,33 @@ +package egoscale + +func (*RegisterUserKeys) name() string { + return "registerUserKeys" +} + +func (*RegisterUserKeys) response() interface{} { + return new(RegisterUserKeysResponse) +} + +func (*CreateUser) name() string { + return "createUser" +} + +func (*CreateUser) response() interface{} { + return new(CreateUserResponse) +} + +func (*UpdateUser) name() string { + return "updateUser" +} + +func (*UpdateUser) response() interface{} { + return new(UpdateUserResponse) +} + +func (*ListUsers) name() string { + return "listUsers" +} + +func (*ListUsers) response() interface{} { + return new(ListUsersResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/users_type.go b/vendor/github.com/exoscale/egoscale/users_type.go new file mode 100644 index 0000000000..7c5e50f747 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/users_type.go @@ -0,0 +1,100 @@ +package egoscale + +// User represents a User +type User struct { + APIKey string `json:"apikey,omitempty" doc:"the api key of the user"` + Account string `json:"account,omitempty" doc:"the account name of the user"` + AccountID string `json:"accountid,omitempty" doc:"the account ID of the user"` + AccountType int16 `json:"accounttype,omitempty" doc:"the account type of the user"` + Created string `json:"created,omitempty" doc:"the date and time the user account was created"` + Domain string `json:"domain,omitempty" doc:"the domain name of the user"` + DomainID string `json:"domainid,omitempty" doc:"the domain ID of the user"` + Email string `json:"email,omitempty" doc:"the user email address"` + FirstName string `json:"firstname,omitempty" doc:"the user firstname"` + ID string `json:"id,omitempty" doc:"the user ID"` + IsCallerChildDomain bool `json:"iscallerchilddomain,omitempty" doc:"the boolean value representing if the updating target is in caller's child domain"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if user is default, false otherwise"` + LastName string `json:"lastname,omitempty" doc:"the user lastname"` + RoleID string `json:"roleid,omitempty" doc:"the ID of the role"` + RoleName string `json:"rolename,omitempty" doc:"the name of the role"` + RoleType string `json:"roletype,omitempty" doc:"the type of the role"` + SecretKey string `json:"secretkey,omitempty" doc:"the secret key of the user"` + State string `json:"state,omitempty" doc:"the user state"` + Timezone string `json:"timezone,omitempty" doc:"the timezone user was created in"` + UserName string `json:"username,omitempty" doc:"the user name"` +} + +// RegisterUserKeys registers a new set of key of the given user +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/registerUserKeys.html +type RegisterUserKeys struct { + ID string `json:"id" doc:"User id"` +} + +// RegisterUserKeysResponse represents a new set of UserKeys +// +// NB: only the APIKey and SecretKey will be filled, hence the different key name +type RegisterUserKeysResponse struct { + UserKeys User `json:"userkeys"` +} + +// CreateUser represents the creation of a User +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createUser.html +type CreateUser struct { + Account string `json:"account" doc:"Creates the user under the specified account. If no account is specified, the username will be used as the account name."` + Email string `json:"email" doc:"email"` + FirstName string `json:"firstname" doc:"firstname"` + LastName string `json:"lastname" doc:"lastname"` + Password string `json:"password" doc:"Clear text password (Default hashed to SHA256SALT). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter See Docs section."` + UserName string `json:"username" doc:"Unique username."` + DomainID string `json:"domainid,omitempty" doc:"Creates the user under the specified domain. Has to be accompanied with the account parameter"` + Timezone string `json:"timezone,omitempty" doc:"Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format."` + UserID string `json:"userid,omitempty" doc:"User UUID, required for adding account from external provisioning system"` +} + +// CreateUserResponse represents the freshly created User +type CreateUserResponse struct { + User User `json:"user"` +} + +// UpdateUser represents the modification of a User +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateUser.html +type UpdateUser struct { + ID string `json:"id" doc:"User uuid"` + Email string `json:"email,omitempty" doc:"email"` + FirstName string `json:"firstname,omitempty" doc:"first name"` + LastName string `json:"lastname,omitempty" doc:"last name"` + Password string `json:"password,omitempty" doc:"Clear text password (default hashed to SHA256SALT). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter. Can't be passed when command is executed via integration.api.port"` + Timezone string `json:"timezone,omitempty" doc:"Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format."` + UserAPIKey string `json:"userapikey,omitempty" doc:"The API key for the user. Must be specified with userSecretKey"` + UserName string `json:"username,omitempty" doc:"Unique username"` + UserSecretKey string `json:"usersecretkey,omitempty" doc:"The secret key for the user. Must be specified with userApiKey"` +} + +// UpdateUserResponse represents the freshly modified User +type UpdateUserResponse CreateUserResponse + +// ListUsers represents the search for Users +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listUsers.html +type ListUsers struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + AccountType int64 `json:"accounttype,omitempty" doc:"List users by account type. Valid types include admin, domain-admin, read-only-admin, or user."` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + ID string `json:"id,omitempty" doc:"List user by ID."` + IsRecursive bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + State string `json:"state,omitempty" doc:"List users by state of the user account."` + Username string `json:"username,omitempty" doc:"List user by the username"` +} + +// ListUsersResponse represents a list of users +type ListUsersResponse struct { + Count int `json:"count"` + User []User `json:"user"` +} diff --git a/vendor/github.com/exoscale/egoscale/version.go b/vendor/github.com/exoscale/egoscale/version.go new file mode 100644 index 0000000000..56f4453bbf --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/version.go @@ -0,0 +1,4 @@ +package egoscale + +// Version of the library +const Version = "0.9.23" diff --git a/vendor/github.com/exoscale/egoscale/virtual_machines.go b/vendor/github.com/exoscale/egoscale/virtual_machines.go new file mode 100644 index 0000000000..21cff4c2f1 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/virtual_machines.go @@ -0,0 +1,330 @@ +package egoscale + +import ( + "context" + "fmt" + "net" + "net/url" + + "github.com/jinzhu/copier" +) + +// ResourceType returns the type of the resource +func (*VirtualMachine) ResourceType() string { + return "UserVM" +} + +// Get fills the VM +func (vm *VirtualMachine) Get(ctx context.Context, client *Client) error { + if vm.ID == "" && vm.Name == "" && vm.DefaultNic() == nil { + return fmt.Errorf("A VirtualMachine may only be searched using ID, Name or IPAddress") + } + + vms, err := client.ListWithContext(ctx, vm) + if err != nil { + return err + } + + count := len(vms) + if count == 0 { + return &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("VirtualMachine not found. id: %s, name: %s", vm.ID, vm.Name), + } + } else if count > 1 { + return fmt.Errorf("More than one VirtualMachine was found. Query: id: %s, name: %s", vm.ID, vm.Name) + } + + return copier.Copy(vm, vms[0]) +} + +// Delete destroys the VM +func (vm *VirtualMachine) Delete(ctx context.Context, client *Client) error { + _, err := client.RequestWithContext(ctx, &DestroyVirtualMachine{ + ID: vm.ID, + }) + + return err +} + +// ListRequest builds the ListVirtualMachines request +func (vm *VirtualMachine) ListRequest() (ListCommand, error) { + // XXX: AffinityGroupID, SecurityGroupID, Tags + + req := &ListVirtualMachines{ + Account: vm.Account, + DomainID: vm.DomainID, + GroupID: vm.GroupID, + ID: vm.ID, + Name: vm.Name, + ProjectID: vm.ProjectID, + State: vm.State, + TemplateID: vm.TemplateID, + ZoneID: vm.ZoneID, + } + + nic := vm.DefaultNic() + if nic != nil { + req.IPAddress = nic.IPAddress + } + + return req, nil +} + +// DefaultNic returns the default nic +func (vm *VirtualMachine) DefaultNic() *Nic { + for _, nic := range vm.Nic { + if nic.IsDefault { + return &nic + } + } + + return nil +} + +// IP returns the default nic IP address +func (vm *VirtualMachine) IP() *net.IP { + nic := vm.DefaultNic() + if nic != nil { + ip := nic.IPAddress + return &ip + } + + return nil +} + +// NicsByType returns the corresponding interfaces base on the given type +func (vm *VirtualMachine) NicsByType(nicType string) []Nic { + nics := make([]Nic, 0) + for _, nic := range vm.Nic { + if nic.Type == nicType { + // XXX The CloudStack API forgets to specify it + nic.VirtualMachineID = vm.ID + nics = append(nics, nic) + } + } + return nics +} + +// NicByNetworkID returns the corresponding interface based on the given NetworkID +// +// A VM cannot be connected twice to a same network. +func (vm *VirtualMachine) NicByNetworkID(networkID string) *Nic { + for _, nic := range vm.Nic { + if nic.NetworkID == networkID { + nic.VirtualMachineID = vm.ID + return &nic + } + } + return nil +} + +// NicByID returns the corresponding interface base on its ID +func (vm *VirtualMachine) NicByID(nicID string) *Nic { + for _, nic := range vm.Nic { + if nic.ID == nicID { + nic.VirtualMachineID = vm.ID + return &nic + } + } + + return nil +} + +// name returns the CloudStack API command name +func (*DeployVirtualMachine) name() string { + return "deployVirtualMachine" +} + +func (req *DeployVirtualMachine) onBeforeSend(params *url.Values) error { + // Either AffinityGroupIDs or AffinityGroupNames must be set + if len(req.AffinityGroupIDs) > 0 && len(req.AffinityGroupNames) > 0 { + return fmt.Errorf("Either AffinityGroupIDs or AffinityGroupNames must be set") + } + + // Either SecurityGroupIDs or SecurityGroupNames must be set + if len(req.SecurityGroupIDs) > 0 && len(req.SecurityGroupNames) > 0 { + return fmt.Errorf("Either SecurityGroupIDs or SecurityGroupNames must be set") + } + + return nil +} + +func (*DeployVirtualMachine) asyncResponse() interface{} { + return new(DeployVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*StartVirtualMachine) name() string { + return "startVirtualMachine" +} +func (*StartVirtualMachine) asyncResponse() interface{} { + return new(StartVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*StopVirtualMachine) name() string { + return "stopVirtualMachine" +} + +func (*StopVirtualMachine) asyncResponse() interface{} { + return new(StopVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*RebootVirtualMachine) name() string { + return "rebootVirtualMachine" +} + +func (*RebootVirtualMachine) asyncResponse() interface{} { + return new(RebootVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*RestoreVirtualMachine) name() string { + return "restoreVirtualMachine" +} + +func (*RestoreVirtualMachine) asyncResponse() interface{} { + return new(RestoreVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*RecoverVirtualMachine) name() string { + return "recoverVirtualMachine" +} + +func (*RecoverVirtualMachine) response() interface{} { + return new(RecoverVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*DestroyVirtualMachine) name() string { + return "destroyVirtualMachine" +} + +func (*DestroyVirtualMachine) asyncResponse() interface{} { + return new(DestroyVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*UpdateVirtualMachine) name() string { + return "updateVirtualMachine" +} + +func (*UpdateVirtualMachine) response() interface{} { + return new(UpdateVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*ExpungeVirtualMachine) name() string { + return "expungeVirtualMachine" +} + +func (*ExpungeVirtualMachine) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*ScaleVirtualMachine) name() string { + return "scaleVirtualMachine" +} + +func (*ScaleVirtualMachine) asyncResponse() interface{} { + return new(booleanResponse) +} + +// name returns the CloudStack API command name +func (*ChangeServiceForVirtualMachine) name() string { + return "changeServiceForVirtualMachine" +} + +func (*ChangeServiceForVirtualMachine) response() interface{} { + return new(ChangeServiceForVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*ResetPasswordForVirtualMachine) name() string { + return "resetPasswordForVirtualMachine" +} + +func (*ResetPasswordForVirtualMachine) asyncResponse() interface{} { + return new(ResetPasswordForVirtualMachineResponse) +} + +func (*GetVirtualMachineUserData) name() string { + return "getVirtualMachineUserData" +} + +func (*GetVirtualMachineUserData) response() interface{} { + return new(GetVirtualMachineUserDataResponse) +} + +// name returns the CloudStack API command name +func (*GetVMPassword) name() string { + return "getVMPassword" +} + +func (*GetVMPassword) response() interface{} { + return new(GetVMPasswordResponse) +} + +// name returns the CloudStack API command name +func (*ListVirtualMachines) name() string { + return "listVirtualMachines" +} + +func (*ListVirtualMachines) response() interface{} { + return new(ListVirtualMachinesResponse) +} + +// SetPage sets the current page +func (ls *ListVirtualMachines) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListVirtualMachines) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +func (*ListVirtualMachines) each(resp interface{}, callback IterateItemFunc) { + vms, ok := resp.(*ListVirtualMachinesResponse) + if !ok { + callback(nil, fmt.Errorf("ListVirtualMachinesResponse expected, got %t", resp)) + return + } + + for i := range vms.VirtualMachine { + if !callback(&vms.VirtualMachine[i], nil) { + break + } + } +} + +// name returns the CloudStack API command name +func (*AddNicToVirtualMachine) name() string { + return "addNicToVirtualMachine" +} + +func (*AddNicToVirtualMachine) asyncResponse() interface{} { + return new(AddNicToVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*RemoveNicFromVirtualMachine) name() string { + return "removeNicFromVirtualMachine" +} + +func (*RemoveNicFromVirtualMachine) asyncResponse() interface{} { + return new(RemoveNicFromVirtualMachineResponse) +} + +// name returns the CloudStack API command name +func (*UpdateDefaultNicForVirtualMachine) name() string { + return "updateDefaultNicForVirtualMachine" +} + +func (*UpdateDefaultNicForVirtualMachine) asyncResponse() interface{} { + return new(UpdateDefaultNicForVirtualMachineResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/virtual_machines_type.go b/vendor/github.com/exoscale/egoscale/virtual_machines_type.go new file mode 100644 index 0000000000..ae87188682 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/virtual_machines_type.go @@ -0,0 +1,345 @@ +package egoscale + +import ( + "net" +) + +// VirtualMachine represents a virtual machine +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html +type VirtualMachine struct { + Account string `json:"account,omitempty" doc:"the account associated with the virtual machine"` + AffinityGroup []AffinityGroup `json:"affinitygroup,omitempty" doc:"list of affinity groups associated with the virtual machine"` + ClusterID string `json:"clusterid,omitempty" doc:"the ID of the vm's cluster"` + ClusterName string `json:"clustername,omitempty" doc:"the name of the vm's cluster"` + CPUNumber int `json:"cpunumber,omitempty" doc:"the number of cpu this virtual machine is running with"` + CPUSpeed int `json:"cpuspeed,omitempty" doc:"the speed of each cpu"` + CPUUsed string `json:"cpuused,omitempty" doc:"the amount of the vm's CPU currently used"` + Created string `json:"created,omitempty" doc:"the date when this virtual machine was created"` + Details map[string]string `json:"details,omitempty" doc:"Vm details in key/value pairs."` + DiskIoRead int64 `json:"diskioread,omitempty" doc:"the read (io) of disk on the vm"` + DiskIoWrite int64 `json:"diskiowrite,omitempty" doc:"the write (io) of disk on the vm"` + DiskKbsRead int64 `json:"diskkbsread,omitempty" doc:"the read (bytes) of disk on the vm"` + DiskKbsWrite int64 `json:"diskkbswrite,omitempty" doc:"the write (bytes) of disk on the vm"` + DiskOfferingID string `json:"diskofferingid,omitempty" doc:"the ID of the disk offering of the virtual machine"` + DiskOfferingName string `json:"diskofferingname,omitempty" doc:"the name of the disk offering of the virtual machine"` + DisplayName string `json:"displayname,omitempty" doc:"user generated name. The name of the virtual machine is returned if no displayname exists."` + DisplayVM bool `json:"displayvm,omitempty" doc:"an optional field whether to the display the vm to the end user or not."` + Domain string `json:"domain,omitempty" doc:"the name of the domain in which the virtual machine exists"` + DomainID string `json:"domainid,omitempty" doc:"the ID of the domain in which the virtual machine exists"` + ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the service offering"` + Group string `json:"group,omitempty" doc:"the group name of the virtual machine"` + GroupID string `json:"groupid,omitempty" doc:"the group ID of the virtual machine"` + HAEnable bool `json:"haenable,omitempty" doc:"true if high-availability is enabled, false otherwise"` + HostID string `json:"hostid,omitempty" doc:"the ID of the host for the virtual machine"` + HostName string `json:"hostname,omitempty" doc:"the name of the host for the virtual machine"` + Hypervisor string `json:"hypervisor,omitempty" doc:"the hypervisor on which the template runs"` + ID string `json:"id,omitempty" doc:"the ID of the virtual machine"` + InstanceName string `json:"instancename,omitempty" doc:"instance name of the user vm; this parameter is returned to the ROOT admin only"` + IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty" doc:"true if vm contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory."` + IsoDisplayText string `json:"isodisplaytext,omitempty" doc:"an alternate display text of the ISO attached to the virtual machine"` + IsoID string `json:"isoid,omitempty" doc:"the ID of the ISO attached to the virtual machine"` + IsoName string `json:"isoname,omitempty" doc:"the name of the ISO attached to the virtual machine"` + KeyPair string `json:"keypair,omitempty" doc:"ssh key-pair"` + Memory int `json:"memory,omitempty" doc:"the memory allocated for the virtual machine"` + Name string `json:"name,omitempty" doc:"the name of the virtual machine"` + NetworkKbsRead int64 `json:"networkkbsread,omitempty" doc:"the incoming network traffic on the vm"` + NetworkKbsWrite int64 `json:"networkkbswrite,omitempty" doc:"the outgoing network traffic on the host"` + Nic []Nic `json:"nic,omitempty" doc:"the list of nics associated with vm"` + OsCategoryID string `json:"oscategoryid,omitempty" doc:"Os category ID of the virtual machine"` + Password string `json:"password,omitempty" doc:"the password (if exists) of the virtual machine"` + PasswordEnabled bool `json:"passwordenabled,omitempty" doc:"true if the password rest feature is enabled, false otherwise"` + PCIDevices []string `json:"pcidevices,omitempty" doc:"list of PCI devices"` + PodID string `json:"podid,omitempty" doc:"the ID of the vm's pod"` + PodName string `json:"podname,omitempty" doc:"the name of the vm's pod"` + Project string `json:"project,omitempty" doc:"the project name of the vm"` + ProjectID string `json:"projectid,omitempty" doc:"the project id of the vm"` + PublicIP string `json:"publicip,omitempty" doc:"public IP address id associated with vm via Static nat rule"` + PublicIPID string `json:"publicipid,omitempty" doc:"public IP address id associated with vm via Static nat rule"` + RootDeviceID int64 `json:"rootdeviceid,omitempty" doc:"device ID of the root volume"` + RootDeviceType string `json:"rootdevicetype,omitempty" doc:"device type of the root volume"` + SecurityGroup []SecurityGroup `json:"securitygroup,omitempty" doc:"list of security groups associated with the virtual machine"` + ServiceOfferingID string `json:"serviceofferingid,omitempty" doc:"the ID of the service offering of the virtual machine"` + ServiceOfferingName string `json:"serviceofferingname,omitempty" doc:"the name of the service offering of the virtual machine"` + ServiceState string `json:"servicestate,omitempty" doc:"State of the Service from LB rule"` + State string `json:"state,omitempty" doc:"the state of the virtual machine"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with vm"` + TemplateDisplayText string `json:"templatedisplaytext,omitempty" doc:" an alternate display text of the template for the virtual machine"` + TemplateID string `json:"templateid,omitempty" doc:"the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file."` + TemplateName string `json:"templatename,omitempty" doc:"the name of the template for the virtual machine"` + ZoneID string `json:"zoneid,omitempty" doc:"the ID of the availablility zone for the virtual machine"` + ZoneName string `json:"zonename,omitempty" doc:"the name of the availability zone for the virtual machine"` +} + +// IPToNetwork represents a mapping between ip and networks +type IPToNetwork struct { + IP string `json:"ip,omitempty"` + Ipv6 string `json:"ipv6,omitempty"` + NetworkID string `json:"networkid,omitempty"` +} + +// Password represents an encrypted password +// +// TODO: method to decrypt it, https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=34014652 +type Password struct { + EncryptedPassword string `json:"encryptedpassword"` +} + +// VirtualMachineResponse represents a generic Virtual Machine response +type VirtualMachineResponse struct { + VirtualMachine VirtualMachine `json:"virtualmachine"` +} + +// DeployVirtualMachine (Async) represents the machine creation +// +// Regarding the UserData field, the client is responsible to base64 (and probably gzip) it. Doing it within this library would make the integration with other tools, e.g. Terraform harder. +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/deployVirtualMachine.html +type DeployVirtualMachine struct { + Account string `json:"account,omitempty" doc:"an optional account for the virtual machine. Must be used with domainId."` + AffinityGroupIDs []string `json:"affinitygroupids,omitempty" doc:"comma separated list of affinity groups id that are going to be applied to the virtual machine. Mutually exclusive with affinitygroupnames parameter"` + AffinityGroupNames []string `json:"affinitygroupnames,omitempty" doc:"comma separated list of affinity groups names that are going to be applied to the virtual machine.Mutually exclusive with affinitygroupids parameter"` + CustomID string `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"` + DeploymentPlanner string `json:"deploymentplanner,omitempty" doc:"Deployment planner to use for vm allocation. Available to ROOT admin only"` + Details map[string]string `json:"details,omitempty" doc:"used to specify the custom parameters."` + DiskOfferingID string `json:"diskofferingid,omitempty" doc:"the ID of the disk offering for the virtual machine. If the template is of ISO format, the diskOfferingId is for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk volume. If the templateId parameter passed is from a Template object, the diskOfferingId refers to a DATA Disk Volume created. If the templateId parameter passed is from an ISO object, the diskOfferingId refers to a ROOT Disk Volume created."` + DisplayName string `json:"displayname,omitempty" doc:"an optional user generated name for the virtual machine"` + DisplayVM *bool `json:"displayvm,omitempty" doc:"an optional field, whether to the display the vm to the end user or not."` + DomainID string `json:"domainid,omitempty" doc:"an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used."` + Group string `json:"group,omitempty" doc:"an optional group for the virtual machine"` + HostID string `json:"hostid,omitempty" doc:"destination Host ID to deploy the VM to - parameter available for root admin only"` + Hypervisor string `json:"hypervisor,omitempty" doc:"the hypervisor on which to deploy the virtual machine"` + IP4 *bool `json:"ip4,omitempty" doc:"True to set an IPv4 to the default interface"` + IP6 *bool `json:"ip6,omitempty" doc:"True to set an IPv6 to the default interface"` + IP6Address net.IP `json:"ip6address,omitempty" doc:"the ipv6 address for default vm's network"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"the ip address for default vm's network"` + IPToNetworkList []IPToNetwork `json:"iptonetworklist,omitempty" doc:"ip to network mapping. Can't be specified with networkIds parameter. Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid - requests to use ip 10.10.10.11 in network id=uuid"` + Keyboard string `json:"keyboard,omitempty" doc:"an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us"` + KeyPair string `json:"keypair,omitempty" doc:"name of the ssh key pair used to login to the virtual machine"` + Name string `json:"name,omitempty" doc:"host name for the virtual machine"` + NetworkIDs []string `json:"networkids,omitempty" doc:"list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter"` + ProjectID string `json:"projectid,omitempty" doc:"Deploy vm for the project"` + RootDiskSize int64 `json:"rootdisksize,omitempty" doc:"Optional field to resize root disk on deploy. Value is in GB. Only applies to template-based deployments. Analogous to details[0].rootdisksize, which takes precedence over this parameter if both are provided"` + SecurityGroupIDs []string `json:"securitygroupids,omitempty" doc:"comma separated list of security groups id that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupnames parameter"` + SecurityGroupNames []string `json:"securitygroupnames,omitempty" doc:"comma separated list of security groups names that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupids parameter"` + ServiceOfferingID string `json:"serviceofferingid" doc:"the ID of the service offering for the virtual machine"` + Size int64 `json:"size,omitempty" doc:"the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId"` + StartVM *bool `json:"startvm,omitempty" doc:"true if start vm after creating. Default value is true"` + TemplateID string `json:"templateid" doc:"the ID of the template for the virtual machine"` + UserData string `json:"userdata,omitempty" doc:"an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding."` + ZoneID string `json:"zoneid" doc:"availability zone for the virtual machine"` +} + +// DeployVirtualMachineResponse represents a deployed VM instance +type DeployVirtualMachineResponse VirtualMachineResponse + +// StartVirtualMachine (Async) represents the creation of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/startVirtualMachine.html +type StartVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` + DeploymentPlanner string `json:"deploymentplanner,omitempty" doc:"Deployment planner to use for vm allocation. Available to ROOT admin only"` + HostID string `json:"hostid,omitempty" doc:"destination Host ID to deploy the VM to - parameter available for root admin only"` +} + +// StartVirtualMachineResponse represents a started VM instance +type StartVirtualMachineResponse VirtualMachineResponse + +// StopVirtualMachine (Async) represents the stopping of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/stopVirtualMachine.html +type StopVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` + Forced *bool `json:"forced,omitempty" doc:"Force stop the VM (vm is marked as Stopped even when command fails to be send to the backend). The caller knows the VM is stopped."` +} + +// StopVirtualMachineResponse represents a stopped VM instance +type StopVirtualMachineResponse VirtualMachineResponse + +// RebootVirtualMachine (Async) represents the rebooting of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/rebootVirtualMachine.html +type RebootVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` +} + +// RebootVirtualMachineResponse represents a rebooted VM instance +type RebootVirtualMachineResponse VirtualMachineResponse + +// RestoreVirtualMachine (Async) represents the restoration of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/restoreVirtualMachine.html +type RestoreVirtualMachine struct { + VirtualMachineID string `json:"virtualmachineid" doc:"Virtual Machine ID"` + TemplateID string `json:"templateid,omitempty" doc:"an optional template Id to restore vm from the new template. This can be an ISO id in case of restore vm deployed using ISO"` + RootDiskSize int64 `json:"rootdisksize,omitempty" doc:"Optional field to resize root disk on restore. Value is in GB. Only applies to template-based deployments."` +} + +// RestoreVirtualMachineResponse represents a restored VM instance +type RestoreVirtualMachineResponse VirtualMachineResponse + +// RecoverVirtualMachine represents the restoration of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/recoverVirtualMachine.html +type RecoverVirtualMachine RebootVirtualMachine + +// RecoverVirtualMachineResponse represents a recovered VM instance +type RecoverVirtualMachineResponse VirtualMachineResponse + +// DestroyVirtualMachine (Async) represents the destruction of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/destroyVirtualMachine.html +type DestroyVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` + Expunge *bool `json:"expunge,omitempty" doc:"If true is passed, the vm is expunged immediately. False by default."` +} + +// DestroyVirtualMachineResponse represents a destroyed VM instance +type DestroyVirtualMachineResponse VirtualMachineResponse + +// UpdateVirtualMachine represents the update of the virtual machine +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/updateVirtualMachine.html +type UpdateVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` + CustomID string `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"` + Details map[string]string `json:"details,omitempty" doc:"Details in key/value pairs."` + DisplayName string `json:"displayname,omitempty" doc:"user generated name"` + DisplayVM *bool `json:"displayvm,omitempty" doc:"an optional field, whether to the display the vm to the end user or not."` + Group string `json:"group,omitempty" doc:"group of the virtual machine"` + HAEnable *bool `json:"haenable,omitempty" doc:"true if high-availability is enabled for the virtual machine, false otherwise"` + IsDynamicallyScalable *bool `json:"isdynamicallyscalable,omitempty" doc:"true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"` + Name string `json:"name,omitempty" doc:"new host name of the vm. The VM has to be stopped/started for this update to take affect"` + SecurityGroupIDs []string `json:"securitygroupids,omitempty" doc:"list of security group ids to be applied on the virtual machine."` + UserData string `json:"userdata,omitempty" doc:"an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding."` +} + +// UpdateVirtualMachineResponse represents an updated VM instance +type UpdateVirtualMachineResponse VirtualMachineResponse + +// ExpungeVirtualMachine represents the annihilation of a VM +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/expungeVirtualMachine.html +type ExpungeVirtualMachine RebootVirtualMachine + +// ScaleVirtualMachine (Async) represents the scaling of a VM +// +// ChangeServiceForVirtualMachine does the same thing but returns the +// new Virtual Machine which is more consistent with the rest of the API. +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/scaleVirtualMachine.html +type ScaleVirtualMachine struct { + ID string `json:"id" doc:"The ID of the virtual machine"` + ServiceOfferingID string `json:"serviceofferingid" doc:"the ID of the service offering for the virtual machine"` + Details map[string]string `json:"details,omitempty" doc:"name value pairs of custom parameters for cpu,memory and cpunumber. example details[i].name=value"` +} + +// ChangeServiceForVirtualMachine represents the scaling of a VM +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/changeServiceForVirtualMachine.html +type ChangeServiceForVirtualMachine ScaleVirtualMachine + +// ChangeServiceForVirtualMachineResponse represents an changed VM instance +type ChangeServiceForVirtualMachineResponse VirtualMachineResponse + +// ResetPasswordForVirtualMachine resets the password for virtual machine. The virtual machine must be in a "Stopped" state... +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/resetPasswordForVirtualMachine.html +type ResetPasswordForVirtualMachine RebootVirtualMachine + +// ResetPasswordForVirtualMachineResponse represents the updated vm +type ResetPasswordForVirtualMachineResponse VirtualMachineResponse + +// GetVMPassword asks for an encrypted password +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/getVMPassword.html +type GetVMPassword RebootVirtualMachine + +// GetVMPasswordResponse represents the encrypted password +type GetVMPasswordResponse struct { + // Base64 encrypted password for the VM + Password Password `json:"password"` +} + +// ListVirtualMachines represents a search for a VM +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listVirtualMachine.html +type ListVirtualMachines struct { + Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."` + AffinityGroupID string `json:"affinitygroupid,omitempty" doc:"list vms by affinity group"` + Details []string `json:"details,omitempty" doc:"comma separated list of host details requested, value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp]. If no parameter is passed in, the details will be defaulted to all"` + DisplayVM *bool `json:"displayvm,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"` + DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"` + ForVirtualNetwork *bool `json:"forvirtualnetwork,omitempty" doc:"list by network type; true if need to list vms using Virtual Network, false otherwise"` + GroupID string `json:"groupid,omitempty" doc:"the group ID"` + HostID string `json:"hostid,omitempty" doc:"the host ID"` + Hypervisor string `json:"hypervisor,omitempty" doc:"the target hypervisor for the template"` + ID string `json:"id,omitempty" doc:"the ID of the virtual machine"` + IDs []string `json:"ids,omitempty" doc:"the IDs of the virtual machines, mutually exclusive with id"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"an IP address to filter the result"` + IsoID string `json:"isoid,omitempty" doc:"list vms by iso"` + IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"` + Name string `json:"name,omitempty" doc:"name of the virtual machine"` + NetworkID string `json:"networkid,omitempty" doc:"list by network id"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + PodID string `json:"podid,omitempty" doc:"the pod ID"` + ProjectID string `json:"projectid,omitempty" doc:"list objects by project"` + ServiceOfferindID string `json:"serviceofferingid,omitempty" doc:"list by the service offering"` + State string `json:"state,omitempty" doc:"state of the virtual machine"` + StorageID string `json:"storageid,omitempty" doc:"the storage ID where vm's volumes belong to"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + TemplateID string `json:"templateid,omitempty" doc:"list vms by template"` + VpcID string `json:"vpcid,omitempty" doc:"list vms by vpc"` + ZoneID string `json:"zoneid,omitempty" doc:"the availability zone ID"` +} + +// ListVirtualMachinesResponse represents a list of virtual machines +type ListVirtualMachinesResponse struct { + Count int `json:"count"` + VirtualMachine []VirtualMachine `json:"virtualmachine"` +} + +// AddNicToVirtualMachine (Async) adds a NIC to a VM +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/addNicToVirtualMachine.html +type AddNicToVirtualMachine struct { + NetworkID string `json:"networkid" doc:"Network ID"` + VirtualMachineID string `json:"virtualmachineid" doc:"Virtual Machine ID"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"IP Address for the new network"` +} + +// AddNicToVirtualMachineResponse represents the modified VM +type AddNicToVirtualMachineResponse VirtualMachineResponse + +// RemoveNicFromVirtualMachine (Async) removes a NIC from a VM +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/removeNicFromVirtualMachine.html +type RemoveNicFromVirtualMachine struct { + NicID string `json:"nicid" doc:"NIC ID"` + VirtualMachineID string `json:"virtualmachineid" doc:"Virtual Machine ID"` +} + +// RemoveNicFromVirtualMachineResponse represents the modified VM +type RemoveNicFromVirtualMachineResponse VirtualMachineResponse + +// UpdateDefaultNicForVirtualMachine (Async) adds a NIC to a VM +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateDefaultNicForVirtualMachine.html +type UpdateDefaultNicForVirtualMachine RemoveNicFromVirtualMachine + +// UpdateDefaultNicForVirtualMachineResponse represents the modified VM +type UpdateDefaultNicForVirtualMachineResponse VirtualMachineResponse + +// GetVirtualMachineUserData returns the user-data of the given VM +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/getVirtualMachineUserData.html +type GetVirtualMachineUserData RebootVirtualMachine + +// GetVirtualMachineUserDataResponse represents the base64 encoded user-data +type GetVirtualMachineUserDataResponse struct { + UserData string `json:"userdata,omitempty" doc:"Base 64 encoded VM user data"` + VirtualMachineID string `json:"virtualmachineid,omitempty" doc:"the ID of the virtual machine"` +} diff --git a/vendor/github.com/exoscale/egoscale/vm_groups.go b/vendor/github.com/exoscale/egoscale/vm_groups.go new file mode 100644 index 0000000000..e7837dfe26 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/vm_groups.go @@ -0,0 +1,110 @@ +package egoscale + +// InstanceGroup represents a group of VM +type InstanceGroup struct { + ID string `json:"id"` + Account string `json:"account,omitempty"` + Created string `json:"created,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Name string `json:"name,omitempty"` + Project string `json:"project,omitempty"` + ProjectID string `json:"projectid,omitempty"` +} + +// InstanceGroupResponse represents a VM group +type InstanceGroupResponse struct { + InstanceGroup InstanceGroup `json:"instancegroup"` +} + +// CreateInstanceGroup creates a VM group +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createInstanceGroup.html +type CreateInstanceGroup struct { + Name string `json:"name"` + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + ProjectID string `json:"projectid,omitempty"` +} + +// name returns the CloudStack API command name +func (*CreateInstanceGroup) name() string { + return "createInstanceGroup" +} + +func (*CreateInstanceGroup) response() interface{} { + return new(CreateInstanceGroupResponse) +} + +// CreateInstanceGroupResponse represents a freshly created VM group +type CreateInstanceGroupResponse InstanceGroupResponse + +// UpdateInstanceGroup creates a VM group +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateInstanceGroup.html +type UpdateInstanceGroup struct { + ID string `json:"id"` + Name string `json:"name,omitempty"` +} + +// name returns the CloudStack API command name +func (*UpdateInstanceGroup) name() string { + return "updateInstanceGroup" +} + +func (*UpdateInstanceGroup) response() interface{} { + return new(UpdateInstanceGroupResponse) +} + +// UpdateInstanceGroupResponse represents an updated VM group +type UpdateInstanceGroupResponse InstanceGroupResponse + +// DeleteInstanceGroup creates a VM group +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteInstanceGroup.html +type DeleteInstanceGroup struct { + Name string `json:"name"` + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + ProjectID string `json:"projectid,omitempty"` +} + +// name returns the CloudStack API command name +func (*DeleteInstanceGroup) name() string { + return "deleteInstanceGroup" +} + +func (*DeleteInstanceGroup) response() interface{} { + return new(booleanResponse) +} + +// ListInstanceGroups lists VM groups +// +// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listInstanceGroups.html +type ListInstanceGroups struct { + Account string `json:"account,omitempty"` + DomainID string `json:"domainid,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + State string `json:"state,omitempty"` + ProjectID string `json:"projectid,omitempty"` +} + +// name returns the CloudStack API command name +func (*ListInstanceGroups) name() string { + return "listInstanceGroups" +} + +func (*ListInstanceGroups) response() interface{} { + return new(ListInstanceGroupsResponse) +} + +// ListInstanceGroupsResponse represents a list of instance groups +type ListInstanceGroupsResponse struct { + Count int `json:"count"` + InstanceGroup []InstanceGroup `json:"instancegroup"` +} diff --git a/vendor/github.com/exoscale/egoscale/volumes.go b/vendor/github.com/exoscale/egoscale/volumes.go new file mode 100644 index 0000000000..ba8ccf459a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/volumes.go @@ -0,0 +1,98 @@ +package egoscale + +import ( + "context" + "fmt" + + "github.com/jinzhu/copier" +) + +// ResourceType returns the type of the resource +func (*Volume) ResourceType() string { + return "Volume" +} + +// Get fetches the given volume by ID +func (vol *Volume) Get(ctx context.Context, client *Client) error { + if vol.ID == "" { + return fmt.Errorf("A Volume may only be get using ID") + } + + vols, err := client.ListWithContext(ctx, vol) + if err != nil { + return err + } + + count := len(vols) + if count == 0 { + return &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("Volume not found. id: %s", vol.ID), + } + } else if count > 1 { + return fmt.Errorf("More than one Volume was found. Query: id: %s", vol.ID) + } + + return copier.Copy(vol, vols[0]) +} + +// ListRequest builds the ListVolumes request +func (vol *Volume) ListRequest() (ListCommand, error) { + req := &ListVolumes{ + Account: vol.Account, + DomainID: vol.DomainID, + Name: vol.Name, + Type: vol.Type, + VirtualMachineID: vol.VirtualMachineID, + ZoneID: vol.ZoneID, + } + + return req, nil +} + +// name returns the CloudStack API command name +func (*ResizeVolume) name() string { + return "resizeVolume" +} + +func (*ResizeVolume) asyncResponse() interface{} { + return new(ResizeVolumeResponse) +} + +// ResizeVolumeResponse represents the new Volume +type ResizeVolumeResponse struct { + Volume Volume `json:"volume"` +} + +// name returns the CloudStack API command name +func (*ListVolumes) name() string { + return "listVolumes" +} + +func (*ListVolumes) response() interface{} { + return new(ListVolumesResponse) +} + +// SetPage sets the current page +func (ls *ListVolumes) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListVolumes) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +func (*ListVolumes) each(resp interface{}, callback IterateItemFunc) { + volumes, ok := resp.(*ListVolumesResponse) + if !ok { + callback(nil, fmt.Errorf("ListVolumesResponse expected, got %t", resp)) + return + } + + for i := range volumes.Volume { + if !callback(&volumes.Volume[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/volumes_type.go b/vendor/github.com/exoscale/egoscale/volumes_type.go new file mode 100644 index 0000000000..57f48eef67 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/volumes_type.go @@ -0,0 +1,71 @@ +package egoscale + +// Volume represents a volume linked to a VM +type Volume struct { + ID string `json:"id"` + Account string `json:"account,omitempty"` + Attached string `json:"attached,omitempty"` + ChainInfo string `json:"chaininfo,omitempty"` + Created string `json:"created,omitempty"` + Destroyed bool `json:"destroyed,omitempty"` + DisplayVolume bool `json:"displayvolume,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + Name string `json:"name,omitempty"` + QuiesceVM bool `json:"quiescevm,omitempty"` + ServiceOfferingDisplayText string `json:"serviceofferingdisplaytext,omitempty"` + ServiceOfferingID string `json:"serviceofferingid,omitempty"` + ServiceOfferingName string `json:"serviceofferingname,omitempty"` + Size uint64 `json:"size,omitempty"` + State string `json:"state,omitempty"` + Type string `json:"type,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` + VMName string `json:"vmname,omitempty"` + VMState string `json:"vmstate,omitempty"` + ZoneID string `json:"zoneid,omitempty"` + ZoneName string `json:"zonename,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + JobID string `json:"jobid,omitempty"` + JobStatus JobStatusType `json:"jobstatus,omitempty"` +} + +// ResizeVolume (Async) resizes a volume +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/resizeVolume.html +type ResizeVolume struct { + ID string `json:"id"` + DiskOfferingID string `json:"diskofferingid,omitempty"` + ShrinkOk *bool `json:"shrinkok,omitempty"` + Size int64 `json:"size,omitempty"` // in GiB +} + +// ListVolumes represents a query listing volumes +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listVolumes.html +type ListVolumes struct { + Account string `json:"account,omitempty"` + DiskOfferingID string `json:"diskoffering,omitempty"` + DisplayVolume string `json:"displayvolume,omitempty"` // root only + DomainID string `json:"domainid,omitempty"` + HostID string `json:"hostid,omitempty"` + ID string `json:"id,omitempty"` + IsRecursive *bool `json:"isrecursive,omitempty"` + Keyword string `json:"keyword,omitempty"` + ListAll *bool `json:"listall,omitempty"` + Name string `json:"name,omitempty"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + PodID string `json:"podid,omitempty"` + ProjectID string `json:"projectid,omitempty"` + StorageID string `json:"storageid,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` + Type string `json:"type,omitempty"` + VirtualMachineID string `json:"virtualmachineid,omitempty"` + ZoneID string `json:"zoneid,omitempty"` +} + +// ListVolumesResponse represents a list of volumes +type ListVolumesResponse struct { + Count int `json:"count"` + Volume []Volume `json:"volume"` +} diff --git a/vendor/github.com/exoscale/egoscale/zones.go b/vendor/github.com/exoscale/egoscale/zones.go new file mode 100644 index 0000000000..c02b3e4e05 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/zones.go @@ -0,0 +1,76 @@ +package egoscale + +import ( + "context" + "fmt" + + "github.com/jinzhu/copier" +) + +// Get fetches the given zone by ID or Name +func (zone *Zone) Get(ctx context.Context, client *Client) error { + if zone.ID == "" && zone.Name == "" { + return fmt.Errorf("A Zone may only be obtained using ID or Name") + } + + zones, err := client.ListWithContext(ctx, zone) + if err != nil { + return err + } + + count := len(zones) + if count == 0 { + return &ErrorResponse{ + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("Zone not found. id: %q, name: %q", zone.ID, zone.Name), + } + } else if count > 1 { + return fmt.Errorf("More than one Zone was found. Query: id: %s", zone.ID) + } + + return copier.Copy(zone, zones[0]) +} + +// ListRequest builds the ListZones request +func (zone *Zone) ListRequest() (ListCommand, error) { + req := &ListZones{ + DomainID: zone.DomainID, + ID: zone.ID, + Name: zone.Name, + } + + return req, nil +} + +// name returns the CloudStack API command name +func (*ListZones) name() string { + return "listZones" +} + +func (*ListZones) response() interface{} { + return new(ListZonesResponse) +} + +// SetPage sets the current page +func (ls *ListZones) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListZones) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +func (*ListZones) each(resp interface{}, callback IterateItemFunc) { + zones, ok := resp.(*ListZonesResponse) + if !ok { + callback(nil, fmt.Errorf("ListZonesResponse expected, got %t", resp)) + return + } + + for i := range zones.Zone { + if !callback(&zones.Zone[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/zones_type.go b/vendor/github.com/exoscale/egoscale/zones_type.go new file mode 100644 index 0000000000..f8102a1d90 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/zones_type.go @@ -0,0 +1,55 @@ +package egoscale + +import ( + "net" +) + +// Zone represents a data center +type Zone struct { + ID string `json:"id"` + AllocationState string `json:"allocationstate,omitempty"` + Capacity string `json:"capacity,omitempty"` + Description string `json:"description,omitempty"` + DhcpProvider string `json:"dhcpprovider,omitempty"` + DisplayText string `json:"displaytext,omitempty"` + DNS1 net.IP `json:"dns1,omitempty"` + DNS2 net.IP `json:"dns2,omitempty"` + Domain string `json:"domain,omitempty"` + DomainID string `json:"domainid,omitempty"` + DomainName string `json:"domainname,omitempty"` + GuestCidrAddress string `json:"guestcidraddress,omitempty"` + InternalDNS1 net.IP `json:"internaldns1,omitempty"` + InternalDNS2 net.IP `json:"internaldns2,omitempty"` + IP6DNS1 net.IP `json:"ip6dns1,omitempty"` + IP6DNS2 net.IP `json:"ip6dns2,omitempty"` + LocalStorageEnabled bool `json:"localstorageenabled,omitempty"` + Name string `json:"name,omitempty"` + NetworkType string `json:"networktype,omitempty"` + ResourceDetails map[string]string `json:"resourcedetails,omitempty"` + SecurityGroupsEnabled bool `json:"securitygroupsenabled,omitempty"` + Vlan string `json:"vlan,omitempty"` + ZoneToken string `json:"zonetoken,omitempty"` + Tags []ResourceTag `json:"tags,omitempty"` +} + +// ListZones represents a query for zones +// +// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listZones.html +type ListZones struct { + Available *bool `json:"available,omitempty" doc:"true if you want to retrieve all available Zones. False if you only want to return the Zones from which you have at least one VM. Default is false."` + DomainID string `json:"domainid,omitempty" doc:"the ID of the domain associated with the zone"` + ID string `json:"id,omitempty" doc:"the ID of the zone"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"the name of the zone"` + NetworkType string `json:"networktype,omitempty" doc:"the network type of the zone that the virtual machine belongs to"` + Page int `json:"page,omitempty" ` + PageSize int `json:"pagesize,omitempty"` + ShowCapacities *bool `json:"showcapacities,omitempty" doc:"flag to display the capacity of the zones"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List zones by resource tags (key/value pairs)"` +} + +// ListZonesResponse represents a list of zones +type ListZonesResponse struct { + Count int `json:"count"` + Zone []Zone `json:"zone"` +} diff --git a/vendor/github.com/go-ini/ini/.gitignore b/vendor/github.com/go-ini/ini/.gitignore new file mode 100644 index 0000000000..7adca9439c --- /dev/null +++ b/vendor/github.com/go-ini/ini/.gitignore @@ -0,0 +1,4 @@ +testdata/conf_out.ini +ini.sublime-project +ini.sublime-workspace +testdata/conf_reflect.ini diff --git a/vendor/github.com/go-ini/ini/LICENSE b/vendor/github.com/go-ini/ini/LICENSE new file mode 100644 index 0000000000..37ec93a14f --- /dev/null +++ b/vendor/github.com/go-ini/ini/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md new file mode 100644 index 0000000000..5d7f1c710a --- /dev/null +++ b/vendor/github.com/go-ini/ini/README.md @@ -0,0 +1,578 @@ +ini [![Build Status](https://drone.io/github.com/go-ini/ini/status.png)](https://drone.io/github.com/go-ini/ini/latest) [![](http://gocover.io/_badge/github.com/go-ini/ini)](http://gocover.io/github.com/go-ini/ini) +=== + +![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200) + +Package ini provides INI file read and write functionality in Go. + +[简体中文](README_ZH.md) + +## Feature + +- Load multiple data sources(`[]byte` or file) with overwrites. +- Read with recursion values. +- Read with parent-child sections. +- Read with auto-increment key names. +- Read with multiple-line values. +- Read with tons of helper methods. +- Read and convert values to Go types. +- Read and **WRITE** comments of sections and keys. +- Manipulate sections, keys and comments with ease. +- Keep sections and keys in order as you parse and save. + +## Installation + + go get gopkg.in/ini.v1 + +## Getting Started + +### Loading from data sources + +A **Data Source** is either raw data in type `[]byte` or a file name with type `string` and you can load **as many as** data sources you want. Passing other types will simply return an error. + +```go +cfg, err := ini.Load([]byte("raw data"), "filename") +``` + +Or start with an empty object: + +```go +cfg := ini.Empty() +``` + +When you cannot decide how many data sources to load at the beginning, you still able to **Append()** them later. + +```go +err := cfg.Append("other file", []byte("other raw data")) +``` + +### Working with sections + +To get a section, you would need to: + +```go +section, err := cfg.GetSection("section name") +``` + +For a shortcut for default section, just give an empty string as name: + +```go +section, err := cfg.GetSection("") +``` + +When you're pretty sure the section exists, following code could make your life easier: + +```go +section := cfg.Section("") +``` + +What happens when the section somehow does not exist? Don't panic, it automatically creates and returns a new section to you. + +To create a new section: + +```go +err := cfg.NewSection("new section") +``` + +To get a list of sections or section names: + +```go +sections := cfg.Sections() +names := cfg.SectionStrings() +``` + +### Working with keys + +To get a key under a section: + +```go +key, err := cfg.Section("").GetKey("key name") +``` + +Same rule applies to key operations: + +```go +key := cfg.Section("").Key("key name") +``` + +To check if a key exists: + +```go +yes := cfg.Section("").HasKey("key name") +``` + +To create a new key: + +```go +err := cfg.Section("").NewKey("name", "value") +``` + +To get a list of keys or key names: + +```go +keys := cfg.Section("").Keys() +names := cfg.Section("").KeyStrings() +``` + +To get a clone hash of keys and corresponding values: + +```go +hash := cfg.GetSection("").KeysHash() +``` + +### Working with values + +To get a string value: + +```go +val := cfg.Section("").Key("key name").String() +``` + +To validate key value on the fly: + +```go +val := cfg.Section("").Key("key name").Validate(func(in string) string { + if len(in) == 0 { + return "default" + } + return in +}) +``` + +If you do not want any auto-transformation (such as recursive read) for the values, you can get raw value directly (this way you get much better performance): + +```go +val := cfg.Section("").Key("key name").Value() +``` + +To check if raw value exists: + +```go +yes := cfg.Section("").HasValue("test value") +``` + +To get value with types: + +```go +// For boolean values: +// true when value is: 1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On +// false when value is: 0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off +v, err = cfg.Section("").Key("BOOL").Bool() +v, err = cfg.Section("").Key("FLOAT64").Float64() +v, err = cfg.Section("").Key("INT").Int() +v, err = cfg.Section("").Key("INT64").Int64() +v, err = cfg.Section("").Key("UINT").Uint() +v, err = cfg.Section("").Key("UINT64").Uint64() +v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339) +v, err = cfg.Section("").Key("TIME").Time() // RFC3339 + +v = cfg.Section("").Key("BOOL").MustBool() +v = cfg.Section("").Key("FLOAT64").MustFloat64() +v = cfg.Section("").Key("INT").MustInt() +v = cfg.Section("").Key("INT64").MustInt64() +v = cfg.Section("").Key("UINT").MustUint() +v = cfg.Section("").Key("UINT64").MustUint64() +v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339) +v = cfg.Section("").Key("TIME").MustTime() // RFC3339 + +// Methods start with Must also accept one argument for default value +// when key not found or fail to parse value to given type. +// Except method MustString, which you have to pass a default value. + +v = cfg.Section("").Key("String").MustString("default") +v = cfg.Section("").Key("BOOL").MustBool(true) +v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25) +v = cfg.Section("").Key("INT").MustInt(10) +v = cfg.Section("").Key("INT64").MustInt64(99) +v = cfg.Section("").Key("UINT").MustUint(3) +v = cfg.Section("").Key("UINT64").MustUint64(6) +v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now()) +v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339 +``` + +What if my value is three-line long? + +```ini +[advance] +ADDRESS = """404 road, +NotFound, State, 5000 +Earth""" +``` + +Not a problem! + +```go +cfg.Section("advance").Key("ADDRESS").String() + +/* --- start --- +404 road, +NotFound, State, 5000 +Earth +------ end --- */ +``` + +That's cool, how about continuation lines? + +```ini +[advance] +two_lines = how about \ + continuation lines? +lots_of_lines = 1 \ + 2 \ + 3 \ + 4 +``` + +Piece of cake! + +```go +cfg.Section("advance").Key("two_lines").String() // how about continuation lines? +cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4 +``` + +Note that single quotes around values will be stripped: + +```ini +foo = "some value" // foo: some value +bar = 'some value' // bar: some value +``` + +That's all? Hmm, no. + +#### Helper methods of working with values + +To get value with given candidates: + +```go +v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"}) +v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75}) +v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30}) +v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30}) +v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9}) +v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9}) +v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3}) +v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339 +``` + +Default value will be presented if value of key is not in candidates you given, and default value does not need be one of candidates. + +To validate value in a given range: + +```go +vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2) +vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20) +vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20) +vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9) +vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9) +vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime) +vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339 +``` + +To auto-split value into slice: + +```go +vals = cfg.Section("").Key("STRINGS").Strings(",") +vals = cfg.Section("").Key("FLOAT64S").Float64s(",") +vals = cfg.Section("").Key("INTS").Ints(",") +vals = cfg.Section("").Key("INT64S").Int64s(",") +vals = cfg.Section("").Key("UINTS").Uints(",") +vals = cfg.Section("").Key("UINT64S").Uint64s(",") +vals = cfg.Section("").Key("TIMES").Times(",") +``` + +### Save your configuration + +Finally, it's time to save your configuration to somewhere. + +A typical way to save configuration is writing it to a file: + +```go +// ... +err = cfg.SaveTo("my.ini") +err = cfg.SaveToIndent("my.ini", "\t") +``` + +Another way to save is writing to a `io.Writer` interface: + +```go +// ... +cfg.WriteTo(writer) +cfg.WriteToIndent(writer, "\t") +``` + +## Advanced Usage + +### Recursive Values + +For all value of keys, there is a special syntax `%()s`, where `` is the key name in same section or default section, and `%()s` will be replaced by corresponding value(empty string if key not found). You can use this syntax at most 99 level of recursions. + +```ini +NAME = ini + +[author] +NAME = Unknwon +GITHUB = https://github.com/%(NAME)s + +[package] +FULL_NAME = github.com/go-ini/%(NAME)s +``` + +```go +cfg.Section("author").Key("GITHUB").String() // https://github.com/Unknwon +cfg.Section("package").Key("FULL_NAME").String() // github.com/go-ini/ini +``` + +### Parent-child Sections + +You can use `.` in section name to indicate parent-child relationship between two or more sections. If the key not found in the child section, library will try again on its parent section until there is no parent section. + +```ini +NAME = ini +VERSION = v1 +IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s + +[package] +CLONE_URL = https://%(IMPORT_PATH)s + +[package.sub] +``` + +```go +cfg.Section("package.sub").Key("CLONE_URL").String() // https://gopkg.in/ini.v1 +``` + +### Auto-increment Key Names + +If key name is `-` in data source, then it would be seen as special syntax for auto-increment key name start from 1, and every section is independent on counter. + +```ini +[features] +-: Support read/write comments of keys and sections +-: Support auto-increment of key names +-: Support load multiple files to overwrite key values +``` + +```go +cfg.Section("features").KeyStrings() // []{"#1", "#2", "#3"} +``` + +### Map To Struct + +Want more objective way to play with INI? Cool. + +```ini +Name = Unknwon +age = 21 +Male = true +Born = 1993-01-01T20:17:05Z + +[Note] +Content = Hi is a good man! +Cities = HangZhou, Boston +``` + +```go +type Note struct { + Content string + Cities []string +} + +type Person struct { + Name string + Age int `ini:"age"` + Male bool + Born time.Time + Note + Created time.Time `ini:"-"` +} + +func main() { + cfg, err := ini.Load("path/to/ini") + // ... + p := new(Person) + err = cfg.MapTo(p) + // ... + + // Things can be simpler. + err = ini.MapTo(p, "path/to/ini") + // ... + + // Just map a section? Fine. + n := new(Note) + err = cfg.Section("Note").MapTo(n) + // ... +} +``` + +Can I have default value for field? Absolutely. + +Assign it before you map to struct. It will keep the value as it is if the key is not presented or got wrong type. + +```go +// ... +p := &Person{ + Name: "Joe", +} +// ... +``` + +It's really cool, but what's the point if you can't give me my file back from struct? + +### Reflect From Struct + +Why not? + +```go +type Embeded struct { + Dates []time.Time `delim:"|"` + Places []string + None []int +} + +type Author struct { + Name string `ini:"NAME"` + Male bool + Age int + GPA float64 + NeverMind string `ini:"-"` + *Embeded +} + +func main() { + a := &Author{"Unknwon", true, 21, 2.8, "", + &Embeded{ + []time.Time{time.Now(), time.Now()}, + []string{"HangZhou", "Boston"}, + []int{}, + }} + cfg := ini.Empty() + err = ini.ReflectFrom(cfg, a) + // ... +} +``` + +So, what do I get? + +```ini +NAME = Unknwon +Male = true +Age = 21 +GPA = 2.8 + +[Embeded] +Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00 +Places = HangZhou,Boston +None = +``` + +#### Name Mapper + +To save your time and make your code cleaner, this library supports [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) between struct field and actual section and key name. + +There are 2 built-in name mappers: + +- `AllCapsUnderscore`: it converts to format `ALL_CAPS_UNDERSCORE` then match section or key. +- `TitleUnderscore`: it converts to format `title_underscore` then match section or key. + +To use them: + +```go +type Info struct { + PackageName string +} + +func main() { + err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("package_name=ini")) + // ... + + cfg, err := ini.Load([]byte("PACKAGE_NAME=ini")) + // ... + info := new(Info) + cfg.NameMapper = ini.AllCapsUnderscore + err = cfg.MapTo(info) + // ... +} +``` + +Same rules of name mapper apply to `ini.ReflectFromWithMapper` function. + +#### Other Notes On Map/Reflect + +Any embedded struct is treated as a section by default, and there is no automatic parent-child relations in map/reflect feature: + +```go +type Child struct { + Age string +} + +type Parent struct { + Name string + Child +} + +type Config struct { + City string + Parent +} +``` + +Example configuration: + +```ini +City = Boston + +[Parent] +Name = Unknwon + +[Child] +Age = 21 +``` + +What if, yes, I'm paranoid, I want embedded struct to be in the same section. Well, all roads lead to Rome. + +```go +type Child struct { + Age string +} + +type Parent struct { + Name string + Child `ini:"Parent"` +} + +type Config struct { + City string + Parent +} +``` + +Example configuration: + +```ini +City = Boston + +[Parent] +Name = Unknwon +Age = 21 +``` + +## Getting Help + +- [API Documentation](https://gowalker.org/gopkg.in/ini.v1) +- [File An Issue](https://github.com/go-ini/ini/issues/new) + +## FAQs + +### What does `BlockMode` field do? + +By default, library lets you read and write values so we need a locker to make sure your data is safe. But in cases that you are very sure about only reading data through the library, you can set `cfg.BlockMode = false` to speed up read operations about **50-70%** faster. + +### Why another INI library? + +Many people are using my another INI library [goconfig](https://github.com/Unknwon/goconfig), so the reason for this one is I would like to make more Go style code. Also when you set `cfg.BlockMode = false`, this one is about **10-30%** faster. + +To make those changes I have to confirm API broken, so it's safer to keep it in another place and start using `gopkg.in` to version my package at this time.(PS: shorter import path) + +## License + +This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. diff --git a/vendor/github.com/go-ini/ini/README_ZH.md b/vendor/github.com/go-ini/ini/README_ZH.md new file mode 100644 index 0000000000..acda259be8 --- /dev/null +++ b/vendor/github.com/go-ini/ini/README_ZH.md @@ -0,0 +1,565 @@ +本包提供了 Go 语言中读写 INI 文件的功能。 + +## 功能特性 + +- 支持覆盖加载多个数据源(`[]byte` 或文件) +- 支持递归读取键值 +- 支持读取父子分区 +- 支持读取自增键名 +- 支持读取多行的键值 +- 支持大量辅助方法 +- 支持在读取时直接转换为 Go 语言类型 +- 支持读取和 **写入** 分区和键的注释 +- 轻松操作分区、键值和注释 +- 在保存文件时分区和键值会保持原有的顺序 + +## 下载安装 + + go get gopkg.in/ini.v1 + +## 开始使用 + +### 从数据源加载 + +一个 **数据源** 可以是 `[]byte` 类型的原始数据,或 `string` 类型的文件路径。您可以加载 **任意多个** 数据源。如果您传递其它类型的数据源,则会直接返回错误。 + +```go +cfg, err := ini.Load([]byte("raw data"), "filename") +``` + +或者从一个空白的文件开始: + +```go +cfg := ini.Empty() +``` + +当您在一开始无法决定需要加载哪些数据源时,仍可以使用 **Append()** 在需要的时候加载它们。 + +```go +err := cfg.Append("other file", []byte("other raw data")) +``` + +### 操作分区(Section) + +获取指定分区: + +```go +section, err := cfg.GetSection("section name") +``` + +如果您想要获取默认分区,则可以用空字符串代替分区名: + +```go +section, err := cfg.GetSection("") +``` + +当您非常确定某个分区是存在的,可以使用以下简便方法: + +```go +section := cfg.Section("") +``` + +如果不小心判断错了,要获取的分区其实是不存在的,那会发生什么呢?没事的,它会自动创建并返回一个对应的分区对象给您。 + +创建一个分区: + +```go +err := cfg.NewSection("new section") +``` + +获取所有分区对象或名称: + +```go +sections := cfg.Sections() +names := cfg.SectionStrings() +``` + +### 操作键(Key) + +获取某个分区下的键: + +```go +key, err := cfg.Section("").GetKey("key name") +``` + +和分区一样,您也可以直接获取键而忽略错误处理: + +```go +key := cfg.Section("").Key("key name") +``` + +判断某个键是否存在: + +```go +yes := cfg.Section("").HasKey("key name") +``` + +创建一个新的键: + +```go +err := cfg.Section("").NewKey("name", "value") +``` + +获取分区下的所有键或键名: + +```go +keys := cfg.Section("").Keys() +names := cfg.Section("").KeyStrings() +``` + +获取分区下的所有键值对的克隆: + +```go +hash := cfg.GetSection("").KeysHash() +``` + +### 操作键值(Value) + +获取一个类型为字符串(string)的值: + +```go +val := cfg.Section("").Key("key name").String() +``` + +获取值的同时通过自定义函数进行处理验证: + +```go +val := cfg.Section("").Key("key name").Validate(func(in string) string { + if len(in) == 0 { + return "default" + } + return in +}) +``` + +如果您不需要任何对值的自动转变功能(例如递归读取),可以直接获取原值(这种方式性能最佳): + +```go +val := cfg.Section("").Key("key name").Value() +``` + +判断某个原值是否存在: + +```go +yes := cfg.Section("").HasValue("test value") +``` + +获取其它类型的值: + +```go +// 布尔值的规则: +// true 当值为:1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On +// false 当值为:0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off +v, err = cfg.Section("").Key("BOOL").Bool() +v, err = cfg.Section("").Key("FLOAT64").Float64() +v, err = cfg.Section("").Key("INT").Int() +v, err = cfg.Section("").Key("INT64").Int64() +v, err = cfg.Section("").Key("UINT").Uint() +v, err = cfg.Section("").Key("UINT64").Uint64() +v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339) +v, err = cfg.Section("").Key("TIME").Time() // RFC3339 + +v = cfg.Section("").Key("BOOL").MustBool() +v = cfg.Section("").Key("FLOAT64").MustFloat64() +v = cfg.Section("").Key("INT").MustInt() +v = cfg.Section("").Key("INT64").MustInt64() +v = cfg.Section("").Key("UINT").MustUint() +v = cfg.Section("").Key("UINT64").MustUint64() +v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339) +v = cfg.Section("").Key("TIME").MustTime() // RFC3339 + +// 由 Must 开头的方法名允许接收一个相同类型的参数来作为默认值, +// 当键不存在或者转换失败时,则会直接返回该默认值。 +// 但是,MustString 方法必须传递一个默认值。 + +v = cfg.Seciont("").Key("String").MustString("default") +v = cfg.Section("").Key("BOOL").MustBool(true) +v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25) +v = cfg.Section("").Key("INT").MustInt(10) +v = cfg.Section("").Key("INT64").MustInt64(99) +v = cfg.Section("").Key("UINT").MustUint(3) +v = cfg.Section("").Key("UINT64").MustUint64(6) +v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now()) +v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339 +``` + +如果我的值有好多行怎么办? + +```ini +[advance] +ADDRESS = """404 road, +NotFound, State, 5000 +Earth""" +``` + +嗯哼?小 case! + +```go +cfg.Section("advance").Key("ADDRESS").String() + +/* --- start --- +404 road, +NotFound, State, 5000 +Earth +------ end --- */ +``` + +赞爆了!那要是我属于一行的内容写不下想要写到第二行怎么办? + +```ini +[advance] +two_lines = how about \ + continuation lines? +lots_of_lines = 1 \ + 2 \ + 3 \ + 4 +``` + +简直是小菜一碟! + +```go +cfg.Section("advance").Key("two_lines").String() // how about continuation lines? +cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4 +``` + +需要注意的是,值两侧的单引号会被自动剔除: + +```ini +foo = "some value" // foo: some value +bar = 'some value' // bar: some value +``` + +这就是全部了?哈哈,当然不是。 + +#### 操作键值的辅助方法 + +获取键值时设定候选值: + +```go +v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"}) +v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75}) +v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30}) +v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30}) +v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9}) +v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9}) +v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3}) +v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339 +``` + +如果获取到的值不是候选值的任意一个,则会返回默认值,而默认值不需要是候选值中的一员。 + +验证获取的值是否在指定范围内: + +```go +vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2) +vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20) +vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20) +vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9) +vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9) +vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime) +vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339 +``` + +自动分割键值为切片(slice): + +```go +vals = cfg.Section("").Key("STRINGS").Strings(",") +vals = cfg.Section("").Key("FLOAT64S").Float64s(",") +vals = cfg.Section("").Key("INTS").Ints(",") +vals = cfg.Section("").Key("INT64S").Int64s(",") +vals = cfg.Section("").Key("UINTS").Uints(",") +vals = cfg.Section("").Key("UINT64S").Uint64s(",") +vals = cfg.Section("").Key("TIMES").Times(",") +``` + +### 保存配置 + +终于到了这个时刻,是时候保存一下配置了。 + +比较原始的做法是输出配置到某个文件: + +```go +// ... +err = cfg.SaveTo("my.ini") +err = cfg.SaveToIndent("my.ini", "\t") +``` + +另一个比较高级的做法是写入到任何实现 `io.Writer` 接口的对象中: + +```go +// ... +cfg.WriteTo(writer) +cfg.WriteToIndent(writer, "\t") +``` + +### 高级用法 + +#### 递归读取键值 + +在获取所有键值的过程中,特殊语法 `%()s` 会被应用,其中 `` 可以是相同分区或者默认分区下的键名。字符串 `%()s` 会被相应的键值所替代,如果指定的键不存在,则会用空字符串替代。您可以最多使用 99 层的递归嵌套。 + +```ini +NAME = ini + +[author] +NAME = Unknwon +GITHUB = https://github.com/%(NAME)s + +[package] +FULL_NAME = github.com/go-ini/%(NAME)s +``` + +```go +cfg.Section("author").Key("GITHUB").String() // https://github.com/Unknwon +cfg.Section("package").Key("FULL_NAME").String() // github.com/go-ini/ini +``` + +#### 读取父子分区 + +您可以在分区名称中使用 `.` 来表示两个或多个分区之间的父子关系。如果某个键在子分区中不存在,则会去它的父分区中再次寻找,直到没有父分区为止。 + +```ini +NAME = ini +VERSION = v1 +IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s + +[package] +CLONE_URL = https://%(IMPORT_PATH)s + +[package.sub] +``` + +```go +cfg.Section("package.sub").Key("CLONE_URL").String() // https://gopkg.in/ini.v1 +``` + +#### 读取自增键名 + +如果数据源中的键名为 `-`,则认为该键使用了自增键名的特殊语法。计数器从 1 开始,并且分区之间是相互独立的。 + +```ini +[features] +-: Support read/write comments of keys and sections +-: Support auto-increment of key names +-: Support load multiple files to overwrite key values +``` + +```go +cfg.Section("features").KeyStrings() // []{"#1", "#2", "#3"} +``` + +### 映射到结构 + +想要使用更加面向对象的方式玩转 INI 吗?好主意。 + +```ini +Name = Unknwon +age = 21 +Male = true +Born = 1993-01-01T20:17:05Z + +[Note] +Content = Hi is a good man! +Cities = HangZhou, Boston +``` + +```go +type Note struct { + Content string + Cities []string +} + +type Person struct { + Name string + Age int `ini:"age"` + Male bool + Born time.Time + Note + Created time.Time `ini:"-"` +} + +func main() { + cfg, err := ini.Load("path/to/ini") + // ... + p := new(Person) + err = cfg.MapTo(p) + // ... + + // 一切竟可以如此的简单。 + err = ini.MapTo(p, "path/to/ini") + // ... + + // 嗯哼?只需要映射一个分区吗? + n := new(Note) + err = cfg.Section("Note").MapTo(n) + // ... +} +``` + +结构的字段怎么设置默认值呢?很简单,只要在映射之前对指定字段进行赋值就可以了。如果键未找到或者类型错误,该值不会发生改变。 + +```go +// ... +p := &Person{ + Name: "Joe", +} +// ... +``` + +这样玩 INI 真的好酷啊!然而,如果不能还给我原来的配置文件,有什么卵用? + +### 从结构反射 + +可是,我有说不能吗? + +```go +type Embeded struct { + Dates []time.Time `delim:"|"` + Places []string + None []int +} + +type Author struct { + Name string `ini:"NAME"` + Male bool + Age int + GPA float64 + NeverMind string `ini:"-"` + *Embeded +} + +func main() { + a := &Author{"Unknwon", true, 21, 2.8, "", + &Embeded{ + []time.Time{time.Now(), time.Now()}, + []string{"HangZhou", "Boston"}, + []int{}, + }} + cfg := ini.Empty() + err = ini.ReflectFrom(cfg, a) + // ... +} +``` + +瞧瞧,奇迹发生了。 + +```ini +NAME = Unknwon +Male = true +Age = 21 +GPA = 2.8 + +[Embeded] +Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00 +Places = HangZhou,Boston +None = +``` + +#### 名称映射器(Name Mapper) + +为了节省您的时间并简化代码,本库支持类型为 [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) 的名称映射器,该映射器负责结构字段名与分区名和键名之间的映射。 + +目前有 2 款内置的映射器: + +- `AllCapsUnderscore`:该映射器将字段名转换至格式 `ALL_CAPS_UNDERSCORE` 后再去匹配分区名和键名。 +- `TitleUnderscore`:该映射器将字段名转换至格式 `title_underscore` 后再去匹配分区名和键名。 + +使用方法: + +```go +type Info struct{ + PackageName string +} + +func main() { + err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("package_name=ini")) + // ... + + cfg, err := ini.Load([]byte("PACKAGE_NAME=ini")) + // ... + info := new(Info) + cfg.NameMapper = ini.AllCapsUnderscore + err = cfg.MapTo(info) + // ... +} +``` + +使用函数 `ini.ReflectFromWithMapper` 时也可应用相同的规则。 + +#### 映射/反射的其它说明 + +任何嵌入的结构都会被默认认作一个不同的分区,并且不会自动产生所谓的父子分区关联: + +```go +type Child struct { + Age string +} + +type Parent struct { + Name string + Child +} + +type Config struct { + City string + Parent +} +``` + +示例配置文件: + +```ini +City = Boston + +[Parent] +Name = Unknwon + +[Child] +Age = 21 +``` + +很好,但是,我就是要嵌入结构也在同一个分区。好吧,你爹是李刚! + +```go +type Child struct { + Age string +} + +type Parent struct { + Name string + Child `ini:"Parent"` +} + +type Config struct { + City string + Parent +} +``` + +示例配置文件: + +```ini +City = Boston + +[Parent] +Name = Unknwon +Age = 21 +``` + +## 获取帮助 + +- [API 文档](https://gowalker.org/gopkg.in/ini.v1) +- [创建工单](https://github.com/go-ini/ini/issues/new) + +## 常见问题 + +### 字段 `BlockMode` 是什么? + +默认情况下,本库会在您进行读写操作时采用锁机制来确保数据时间。但在某些情况下,您非常确定只进行读操作。此时,您可以通过设置 `cfg.BlockMode = false` 来将读操作提升大约 **50-70%** 的性能。 + +### 为什么要写另一个 INI 解析库? + +许多人都在使用我的 [goconfig](https://github.com/Unknwon/goconfig) 来完成对 INI 文件的操作,但我希望使用更加 Go 风格的代码。并且当您设置 `cfg.BlockMode = false` 时,会有大约 **10-30%** 的性能提升。 + +为了做出这些改变,我必须对 API 进行破坏,所以新开一个仓库是最安全的做法。除此之外,本库直接使用 `gopkg.in` 来进行版本化发布。(其实真相是导入路径更短了) diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go new file mode 100644 index 0000000000..a8d21739fb --- /dev/null +++ b/vendor/github.com/go-ini/ini/ini.go @@ -0,0 +1,1250 @@ +// Copyright 2014 Unknwon +// +// 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 ini provides INI file read and write functionality in Go. +package ini + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "os" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "time" +) + +const ( + DEFAULT_SECTION = "DEFAULT" + // Maximum allowed depth when recursively substituing variable names. + _DEPTH_VALUES = 99 + + _VERSION = "1.7.0" +) + +func Version() string { + return _VERSION +} + +var ( + LineBreak = "\n" + + // Variable regexp pattern: %(variable)s + varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`) + + // Write spaces around "=" to look better. + PrettyFormat = true +) + +func init() { + if runtime.GOOS == "windows" { + LineBreak = "\r\n" + } +} + +func inSlice(str string, s []string) bool { + for _, v := range s { + if str == v { + return true + } + } + return false +} + +// dataSource is a interface that returns file content. +type dataSource interface { + ReadCloser() (io.ReadCloser, error) +} + +type sourceFile struct { + name string +} + +func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) { + return os.Open(s.name) +} + +type bytesReadCloser struct { + reader io.Reader +} + +func (rc *bytesReadCloser) Read(p []byte) (n int, err error) { + return rc.reader.Read(p) +} + +func (rc *bytesReadCloser) Close() error { + return nil +} + +type sourceData struct { + data []byte +} + +func (s *sourceData) ReadCloser() (io.ReadCloser, error) { + return &bytesReadCloser{bytes.NewReader(s.data)}, nil +} + +// ____ __. +// | |/ _|____ ___.__. +// | <_/ __ < | | +// | | \ ___/\___ | +// |____|__ \___ > ____| +// \/ \/\/ + +// Key represents a key under a section. +type Key struct { + s *Section + Comment string + name string + value string + isAutoIncr bool +} + +// Name returns name of key. +func (k *Key) Name() string { + return k.name +} + +// Value returns raw value of key for performance purpose. +func (k *Key) Value() string { + return k.value +} + +// String returns string representation of value. +func (k *Key) String() string { + val := k.value + if strings.Index(val, "%") == -1 { + return val + } + + for i := 0; i < _DEPTH_VALUES; i++ { + vr := varPattern.FindString(val) + if len(vr) == 0 { + break + } + + // Take off leading '%(' and trailing ')s'. + noption := strings.TrimLeft(vr, "%(") + noption = strings.TrimRight(noption, ")s") + + // Search in the same section. + nk, err := k.s.GetKey(noption) + if err != nil { + // Search again in default section. + nk, _ = k.s.f.Section("").GetKey(noption) + } + + // Substitute by new value and take off leading '%(' and trailing ')s'. + val = strings.Replace(val, vr, nk.value, -1) + } + return val +} + +// Validate accepts a validate function which can +// return modifed result as key value. +func (k *Key) Validate(fn func(string) string) string { + return fn(k.String()) +} + +// parseBool returns the boolean value represented by the string. +// +// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On, +// 0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off. +// Any other value returns an error. +func parseBool(str string) (value bool, err error) { + switch str { + case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "ON", "on", "On": + return true, nil + case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "OFF", "off", "Off": + return false, nil + } + return false, fmt.Errorf("parsing \"%s\": invalid syntax", str) +} + +// Bool returns bool type value. +func (k *Key) Bool() (bool, error) { + return parseBool(k.String()) +} + +// Float64 returns float64 type value. +func (k *Key) Float64() (float64, error) { + return strconv.ParseFloat(k.String(), 64) +} + +// Int returns int type value. +func (k *Key) Int() (int, error) { + return strconv.Atoi(k.String()) +} + +// Int64 returns int64 type value. +func (k *Key) Int64() (int64, error) { + return strconv.ParseInt(k.String(), 10, 64) +} + +// Uint returns uint type valued. +func (k *Key) Uint() (uint, error) { + u, e := strconv.ParseUint(k.String(), 10, 64) + return uint(u), e +} + +// Uint64 returns uint64 type value. +func (k *Key) Uint64() (uint64, error) { + return strconv.ParseUint(k.String(), 10, 64) +} + +// Duration returns time.Duration type value. +func (k *Key) Duration() (time.Duration, error) { + return time.ParseDuration(k.String()) +} + +// TimeFormat parses with given format and returns time.Time type value. +func (k *Key) TimeFormat(format string) (time.Time, error) { + return time.Parse(format, k.String()) +} + +// Time parses with RFC3339 format and returns time.Time type value. +func (k *Key) Time() (time.Time, error) { + return k.TimeFormat(time.RFC3339) +} + +// MustString returns default value if key value is empty. +func (k *Key) MustString(defaultVal string) string { + val := k.String() + if len(val) == 0 { + return defaultVal + } + return val +} + +// MustBool always returns value without error, +// it returns false if error occurs. +func (k *Key) MustBool(defaultVal ...bool) bool { + val, err := k.Bool() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustFloat64 always returns value without error, +// it returns 0.0 if error occurs. +func (k *Key) MustFloat64(defaultVal ...float64) float64 { + val, err := k.Float64() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustInt always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustInt(defaultVal ...int) int { + val, err := k.Int() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustInt64 always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustInt64(defaultVal ...int64) int64 { + val, err := k.Int64() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustUint always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustUint(defaultVal ...uint) uint { + val, err := k.Uint() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustUint64 always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustUint64(defaultVal ...uint64) uint64 { + val, err := k.Uint64() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustDuration always returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration { + val, err := k.Duration() + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustTimeFormat always parses with given format and returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time { + val, err := k.TimeFormat(format) + if len(defaultVal) > 0 && err != nil { + return defaultVal[0] + } + return val +} + +// MustTime always parses with RFC3339 format and returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustTime(defaultVal ...time.Time) time.Time { + return k.MustTimeFormat(time.RFC3339, defaultVal...) +} + +// In always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) In(defaultVal string, candidates []string) string { + val := k.String() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InFloat64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 { + val := k.MustFloat64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InInt always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InInt(defaultVal int, candidates []int) int { + val := k.MustInt() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InInt64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 { + val := k.MustInt64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InUint always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InUint(defaultVal uint, candidates []uint) uint { + val := k.MustUint() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InUint64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 { + val := k.MustUint64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InTimeFormat always parses with given format and returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time { + val := k.MustTimeFormat(format) + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InTime always parses with RFC3339 format and returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time { + return k.InTimeFormat(time.RFC3339, defaultVal, candidates) +} + +// RangeFloat64 checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 { + val := k.MustFloat64() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeInt checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeInt(defaultVal, min, max int) int { + val := k.MustInt() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeInt64 checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeInt64(defaultVal, min, max int64) int64 { + val := k.MustInt64() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeTimeFormat checks if value with given format is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time { + val := k.MustTimeFormat(format) + if val.Unix() < min.Unix() || val.Unix() > max.Unix() { + return defaultVal + } + return val +} + +// RangeTime checks if value with RFC3339 format is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time { + return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max) +} + +// Strings returns list of string devide by given delimiter. +func (k *Key) Strings(delim string) []string { + str := k.String() + if len(str) == 0 { + return []string{} + } + + vals := strings.Split(str, delim) + for i := range vals { + vals[i] = strings.TrimSpace(vals[i]) + } + return vals +} + +// Float64s returns list of float64 devide by given delimiter. +func (k *Key) Float64s(delim string) []float64 { + strs := k.Strings(delim) + vals := make([]float64, len(strs)) + for i := range strs { + vals[i], _ = strconv.ParseFloat(strs[i], 64) + } + return vals +} + +// Ints returns list of int devide by given delimiter. +func (k *Key) Ints(delim string) []int { + strs := k.Strings(delim) + vals := make([]int, len(strs)) + for i := range strs { + vals[i], _ = strconv.Atoi(strs[i]) + } + return vals +} + +// Int64s returns list of int64 devide by given delimiter. +func (k *Key) Int64s(delim string) []int64 { + strs := k.Strings(delim) + vals := make([]int64, len(strs)) + for i := range strs { + vals[i], _ = strconv.ParseInt(strs[i], 10, 64) + } + return vals +} + +// Uints returns list of uint devide by given delimiter. +func (k *Key) Uints(delim string) []uint { + strs := k.Strings(delim) + vals := make([]uint, len(strs)) + for i := range strs { + u, _ := strconv.ParseUint(strs[i], 10, 64) + vals[i] = uint(u) + } + return vals +} + +// Uint64s returns list of uint64 devide by given delimiter. +func (k *Key) Uint64s(delim string) []uint64 { + strs := k.Strings(delim) + vals := make([]uint64, len(strs)) + for i := range strs { + vals[i], _ = strconv.ParseUint(strs[i], 10, 64) + } + return vals +} + +// TimesFormat parses with given format and returns list of time.Time devide by given delimiter. +func (k *Key) TimesFormat(format, delim string) []time.Time { + strs := k.Strings(delim) + vals := make([]time.Time, len(strs)) + for i := range strs { + vals[i], _ = time.Parse(format, strs[i]) + } + return vals +} + +// Times parses with RFC3339 format and returns list of time.Time devide by given delimiter. +func (k *Key) Times(delim string) []time.Time { + return k.TimesFormat(time.RFC3339, delim) +} + +// SetValue changes key value. +func (k *Key) SetValue(v string) { + k.value = v +} + +// _________ __ .__ +// / _____/ ____ _____/ |_|__| ____ ____ +// \_____ \_/ __ \_/ ___\ __\ |/ _ \ / \ +// / \ ___/\ \___| | | ( <_> ) | \ +// /_______ /\___ >\___ >__| |__|\____/|___| / +// \/ \/ \/ \/ + +// Section represents a config section. +type Section struct { + f *File + Comment string + name string + keys map[string]*Key + keyList []string + keysHash map[string]string +} + +func newSection(f *File, name string) *Section { + return &Section{f, "", name, make(map[string]*Key), make([]string, 0, 10), make(map[string]string)} +} + +// Name returns name of Section. +func (s *Section) Name() string { + return s.name +} + +// NewKey creates a new key to given section. +func (s *Section) NewKey(name, val string) (*Key, error) { + if len(name) == 0 { + return nil, errors.New("error creating new key: empty key name") + } + + if s.f.BlockMode { + s.f.lock.Lock() + defer s.f.lock.Unlock() + } + + if inSlice(name, s.keyList) { + s.keys[name].value = val + return s.keys[name], nil + } + + s.keyList = append(s.keyList, name) + s.keys[name] = &Key{s, "", name, val, false} + s.keysHash[name] = val + return s.keys[name], nil +} + +// GetKey returns key in section by given name. +func (s *Section) GetKey(name string) (*Key, error) { + // FIXME: change to section level lock? + if s.f.BlockMode { + s.f.lock.RLock() + } + key := s.keys[name] + if s.f.BlockMode { + s.f.lock.RUnlock() + } + + if key == nil { + // Check if it is a child-section. + sname := s.name + for { + if i := strings.LastIndex(sname, "."); i > -1 { + sname = sname[:i] + sec, err := s.f.GetSection(sname) + if err != nil { + continue + } + return sec.GetKey(name) + } else { + break + } + } + return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name) + } + return key, nil +} + +// HasKey returns true if section contains a key with given name. +func (s *Section) Haskey(name string) bool { + key, _ := s.GetKey(name) + return key != nil +} + +// HasKey returns true if section contains given raw value. +func (s *Section) HasValue(value string) bool { + if s.f.BlockMode { + s.f.lock.RLock() + defer s.f.lock.RUnlock() + } + + for _, k := range s.keys { + if value == k.value { + return true + } + } + return false +} + +// Key assumes named Key exists in section and returns a zero-value when not. +func (s *Section) Key(name string) *Key { + key, err := s.GetKey(name) + if err != nil { + // It's OK here because the only possible error is empty key name, + // but if it's empty, this piece of code won't be executed. + key, _ = s.NewKey(name, "") + return key + } + return key +} + +// Keys returns list of keys of section. +func (s *Section) Keys() []*Key { + keys := make([]*Key, len(s.keyList)) + for i := range s.keyList { + keys[i] = s.Key(s.keyList[i]) + } + return keys +} + +// KeyStrings returns list of key names of section. +func (s *Section) KeyStrings() []string { + list := make([]string, len(s.keyList)) + copy(list, s.keyList) + return list +} + +// KeysHash returns keys hash consisting of names and values. +func (s *Section) KeysHash() map[string]string { + if s.f.BlockMode { + s.f.lock.RLock() + defer s.f.lock.RUnlock() + } + + hash := map[string]string{} + for key, value := range s.keysHash { + hash[key] = value + } + return hash +} + +// DeleteKey deletes a key from section. +func (s *Section) DeleteKey(name string) { + if s.f.BlockMode { + s.f.lock.Lock() + defer s.f.lock.Unlock() + } + + for i, k := range s.keyList { + if k == name { + s.keyList = append(s.keyList[:i], s.keyList[i+1:]...) + delete(s.keys, name) + return + } + } +} + +// ___________.__.__ +// \_ _____/|__| | ____ +// | __) | | | _/ __ \ +// | \ | | |_\ ___/ +// \___ / |__|____/\___ > +// \/ \/ + +// File represents a combination of a or more INI file(s) in memory. +type File struct { + // Should make things safe, but sometimes doesn't matter. + BlockMode bool + // Make sure data is safe in multiple goroutines. + lock sync.RWMutex + + // Allow combination of multiple data sources. + dataSources []dataSource + // Actual data is stored here. + sections map[string]*Section + + // To keep data in order. + sectionList []string + + NameMapper +} + +// newFile initializes File object with given data sources. +func newFile(dataSources []dataSource) *File { + return &File{ + BlockMode: true, + dataSources: dataSources, + sections: make(map[string]*Section), + sectionList: make([]string, 0, 10), + } +} + +func parseDataSource(source interface{}) (dataSource, error) { + switch s := source.(type) { + case string: + return sourceFile{s}, nil + case []byte: + return &sourceData{s}, nil + default: + return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s) + } +} + +// Load loads and parses from INI data sources. +// Arguments can be mixed of file name with string type, or raw data in []byte. +func Load(source interface{}, others ...interface{}) (_ *File, err error) { + sources := make([]dataSource, len(others)+1) + sources[0], err = parseDataSource(source) + if err != nil { + return nil, err + } + for i := range others { + sources[i+1], err = parseDataSource(others[i]) + if err != nil { + return nil, err + } + } + f := newFile(sources) + if err = f.Reload(); err != nil { + return nil, err + } + return f, nil +} + +// Empty returns an empty file object. +func Empty() *File { + // Ignore error here, we sure our data is good. + f, _ := Load([]byte("")) + return f +} + +// NewSection creates a new section. +func (f *File) NewSection(name string) (*Section, error) { + if len(name) == 0 { + return nil, errors.New("error creating new section: empty section name") + } + + if f.BlockMode { + f.lock.Lock() + defer f.lock.Unlock() + } + + if inSlice(name, f.sectionList) { + return f.sections[name], nil + } + + f.sectionList = append(f.sectionList, name) + f.sections[name] = newSection(f, name) + return f.sections[name], nil +} + +// NewSections creates a list of sections. +func (f *File) NewSections(names ...string) (err error) { + for _, name := range names { + if _, err = f.NewSection(name); err != nil { + return err + } + } + return nil +} + +// GetSection returns section by given name. +func (f *File) GetSection(name string) (*Section, error) { + if len(name) == 0 { + name = DEFAULT_SECTION + } + + if f.BlockMode { + f.lock.RLock() + defer f.lock.RUnlock() + } + + sec := f.sections[name] + if sec == nil { + return nil, fmt.Errorf("error when getting section: section '%s' not exists", name) + } + return sec, nil +} + +// Section assumes named section exists and returns a zero-value when not. +func (f *File) Section(name string) *Section { + sec, err := f.GetSection(name) + if err != nil { + // Note: It's OK here because the only possible error is empty section name, + // but if it's empty, this piece of code won't be executed. + sec, _ = f.NewSection(name) + return sec + } + return sec +} + +// Section returns list of Section. +func (f *File) Sections() []*Section { + sections := make([]*Section, len(f.sectionList)) + for i := range f.sectionList { + sections[i] = f.Section(f.sectionList[i]) + } + return sections +} + +// SectionStrings returns list of section names. +func (f *File) SectionStrings() []string { + list := make([]string, len(f.sectionList)) + copy(list, f.sectionList) + return list +} + +// DeleteSection deletes a section. +func (f *File) DeleteSection(name string) { + if f.BlockMode { + f.lock.Lock() + defer f.lock.Unlock() + } + + if len(name) == 0 { + name = DEFAULT_SECTION + } + + for i, s := range f.sectionList { + if s == name { + f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...) + delete(f.sections, name) + return + } + } +} + +func cutComment(str string) string { + i := strings.Index(str, "#") + if i == -1 { + return str + } + return str[:i] +} + +func checkMultipleLines(buf *bufio.Reader, line, val, valQuote string) (string, error) { + isEnd := false + for { + next, err := buf.ReadString('\n') + if err != nil { + if err != io.EOF { + return "", err + } + isEnd = true + } + pos := strings.LastIndex(next, valQuote) + if pos > -1 { + val += next[:pos] + break + } + val += next + if isEnd { + return "", fmt.Errorf("error parsing line: missing closing key quote from '%s' to '%s'", line, next) + } + } + return val, nil +} + +func checkContinuationLines(buf *bufio.Reader, val string) (string, bool, error) { + isEnd := false + for { + valLen := len(val) + if valLen == 0 || val[valLen-1] != '\\' { + break + } + val = val[:valLen-1] + + next, err := buf.ReadString('\n') + if err != nil { + if err != io.EOF { + return "", isEnd, err + } + isEnd = true + } + + next = strings.TrimSpace(next) + if len(next) == 0 { + break + } + val += next + } + return val, isEnd, nil +} + +// parse parses data through an io.Reader. +func (f *File) parse(reader io.Reader) error { + buf := bufio.NewReader(reader) + + // Handle BOM-UTF8. + // http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding + mask, err := buf.Peek(3) + if err == nil && len(mask) >= 3 && mask[0] == 239 && mask[1] == 187 && mask[2] == 191 { + buf.Read(mask) + } + + count := 1 + comments := "" + isEnd := false + + section, err := f.NewSection(DEFAULT_SECTION) + if err != nil { + return err + } + + for { + line, err := buf.ReadString('\n') + line = strings.TrimSpace(line) + length := len(line) + + // Check error and ignore io.EOF just for a moment. + if err != nil { + if err != io.EOF { + return fmt.Errorf("error reading next line: %v", err) + } + // The last line of file could be an empty line. + if length == 0 { + break + } + isEnd = true + } + + // Skip empty lines. + if length == 0 { + continue + } + + switch { + case line[0] == '#' || line[0] == ';': // Comments. + if len(comments) == 0 { + comments = line + } else { + comments += LineBreak + line + } + continue + case line[0] == '[' && line[length-1] == ']': // New sction. + section, err = f.NewSection(strings.TrimSpace(line[1 : length-1])) + if err != nil { + return err + } + + if len(comments) > 0 { + section.Comment = comments + comments = "" + } + // Reset counter. + count = 1 + continue + } + + // Other possibilities. + var ( + i int + keyQuote string + kname string + valQuote string + val string + ) + + // Key name surrounded by quotes. + if line[0] == '"' { + if length > 6 && line[0:3] == `"""` { + keyQuote = `"""` + } else { + keyQuote = `"` + } + } else if line[0] == '`' { + keyQuote = "`" + } + if len(keyQuote) > 0 { + qLen := len(keyQuote) + pos := strings.Index(line[qLen:], keyQuote) + if pos == -1 { + return fmt.Errorf("error parsing line: missing closing key quote: %s", line) + } + pos = pos + qLen + i = strings.IndexAny(line[pos:], "=:") + if i < 0 { + return fmt.Errorf("error parsing line: key-value delimiter not found: %s", line) + } else if i == pos { + return fmt.Errorf("error parsing line: key is empty: %s", line) + } + i = i + pos + kname = line[qLen:pos] // Just keep spaces inside quotes. + } else { + i = strings.IndexAny(line, "=:") + if i < 0 { + return fmt.Errorf("error parsing line: key-value delimiter not found: %s", line) + } else if i == 0 { + return fmt.Errorf("error parsing line: key is empty: %s", line) + } + kname = strings.TrimSpace(line[0:i]) + } + + isAutoIncr := false + // Auto increment. + if kname == "-" { + isAutoIncr = true + kname = "#" + fmt.Sprint(count) + count++ + } + + lineRight := strings.TrimSpace(line[i+1:]) + lineRightLength := len(lineRight) + firstChar := "" + if lineRightLength >= 2 { + firstChar = lineRight[0:1] + } + if firstChar == "`" { + valQuote = "`" + } else if firstChar == `"` { + if lineRightLength >= 3 && lineRight[0:3] == `"""` { + valQuote = `"""` + } else { + valQuote = `"` + } + } else if firstChar == `'` { + valQuote = `'` + } + + if len(valQuote) > 0 { + qLen := len(valQuote) + pos := strings.LastIndex(lineRight[qLen:], valQuote) + // For multiple-line value check. + if pos == -1 { + if valQuote == `"` || valQuote == `'` { + return fmt.Errorf("error parsing line: single quote does not allow multiple-line value: %s", line) + } + + val = lineRight[qLen:] + "\n" + val, err = checkMultipleLines(buf, line, val, valQuote) + if err != nil { + return err + } + } else { + val = lineRight[qLen : pos+qLen] + } + } else { + val = strings.TrimSpace(cutComment(lineRight)) + val, isEnd, err = checkContinuationLines(buf, val) + if err != nil { + return err + } + } + + k, err := section.NewKey(kname, val) + if err != nil { + return err + } + k.isAutoIncr = isAutoIncr + if len(comments) > 0 { + k.Comment = comments + comments = "" + } + + if isEnd { + break + } + } + return nil +} + +func (f *File) reload(s dataSource) error { + r, err := s.ReadCloser() + if err != nil { + return err + } + defer r.Close() + + return f.parse(r) +} + +// Reload reloads and parses all data sources. +func (f *File) Reload() (err error) { + for _, s := range f.dataSources { + if err = f.reload(s); err != nil { + return err + } + } + return nil +} + +// Append appends one or more data sources and reloads automatically. +func (f *File) Append(source interface{}, others ...interface{}) error { + ds, err := parseDataSource(source) + if err != nil { + return err + } + f.dataSources = append(f.dataSources, ds) + for _, s := range others { + ds, err = parseDataSource(s) + if err != nil { + return err + } + f.dataSources = append(f.dataSources, ds) + } + return f.Reload() +} + +// WriteToIndent writes file content into io.Writer with given value indention. +func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) { + equalSign := "=" + if PrettyFormat { + equalSign = " = " + } + + // Use buffer to make sure target is safe until finish encoding. + buf := bytes.NewBuffer(nil) + for i, sname := range f.sectionList { + sec := f.Section(sname) + if len(sec.Comment) > 0 { + if sec.Comment[0] != '#' && sec.Comment[0] != ';' { + sec.Comment = "; " + sec.Comment + } + if _, err = buf.WriteString(sec.Comment + LineBreak); err != nil { + return 0, err + } + } + + if i > 0 { + if _, err = buf.WriteString("[" + sname + "]" + LineBreak); err != nil { + return 0, err + } + } else { + // Write nothing if default section is empty. + if len(sec.keyList) == 0 { + continue + } + } + + for _, kname := range sec.keyList { + key := sec.Key(kname) + if len(key.Comment) > 0 { + if len(indent) > 0 && sname != DEFAULT_SECTION { + buf.WriteString(indent) + } + if key.Comment[0] != '#' && key.Comment[0] != ';' { + key.Comment = "; " + key.Comment + } + if _, err = buf.WriteString(key.Comment + LineBreak); err != nil { + return 0, err + } + } + + if len(indent) > 0 && sname != DEFAULT_SECTION { + buf.WriteString(indent) + } + + switch { + case key.isAutoIncr: + kname = "-" + case strings.Contains(kname, "`") || strings.Contains(kname, `"`): + kname = `"""` + kname + `"""` + case strings.Contains(kname, `=`) || strings.Contains(kname, `:`): + kname = "`" + kname + "`" + } + + val := key.value + // In case key value contains "\n", "`" or "\"". + if strings.Contains(val, "\n") || strings.Contains(val, "`") || strings.Contains(val, `"`) || + strings.Contains(val, "#") { + val = `"""` + val + `"""` + } + if _, err = buf.WriteString(kname + equalSign + val + LineBreak); err != nil { + return 0, err + } + } + + // Put a line between sections. + if _, err = buf.WriteString(LineBreak); err != nil { + return 0, err + } + } + + return buf.WriteTo(w) +} + +// WriteTo writes file content into io.Writer. +func (f *File) WriteTo(w io.Writer) (int64, error) { + return f.WriteToIndent(w, "") +} + +// SaveToIndent writes content to file system with given value indention. +func (f *File) SaveToIndent(filename, indent string) error { + // Note: Because we are truncating with os.Create, + // so it's safer to save to a temporary file location and rename afte done. + tmpPath := filename + "." + strconv.Itoa(time.Now().Nanosecond()) + ".tmp" + defer os.Remove(tmpPath) + + fw, err := os.Create(tmpPath) + if err != nil { + return err + } + + if _, err = f.WriteToIndent(fw, indent); err != nil { + fw.Close() + return err + } + fw.Close() + + // Remove old file and rename the new one. + os.Remove(filename) + return os.Rename(tmpPath, filename) +} + +// SaveTo writes content to file system. +func (f *File) SaveTo(filename string) error { + return f.SaveToIndent(filename, "") +} diff --git a/vendor/github.com/go-ini/ini/struct.go b/vendor/github.com/go-ini/ini/struct.go new file mode 100644 index 0000000000..c118437101 --- /dev/null +++ b/vendor/github.com/go-ini/ini/struct.go @@ -0,0 +1,350 @@ +// Copyright 2014 Unknwon +// +// 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 ini + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "time" + "unicode" +) + +// NameMapper represents a ini tag name mapper. +type NameMapper func(string) string + +// Built-in name getters. +var ( + // AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE. + AllCapsUnderscore NameMapper = func(raw string) string { + newstr := make([]rune, 0, len(raw)) + for i, chr := range raw { + if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + } + newstr = append(newstr, unicode.ToUpper(chr)) + } + return string(newstr) + } + // TitleUnderscore converts to format title_underscore. + TitleUnderscore NameMapper = func(raw string) string { + newstr := make([]rune, 0, len(raw)) + for i, chr := range raw { + if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + chr -= ('A' - 'a') + } + newstr = append(newstr, chr) + } + return string(newstr) + } +) + +func (s *Section) parseFieldName(raw, actual string) string { + if len(actual) > 0 { + return actual + } + if s.f.NameMapper != nil { + return s.f.NameMapper(raw) + } + return raw +} + +func parseDelim(actual string) string { + if len(actual) > 0 { + return actual + } + return "," +} + +var reflectTime = reflect.TypeOf(time.Now()).Kind() + +// setWithProperType sets proper value to field based on its type, +// but it does not return error for failing parsing, +// because we want to use default value that is already assigned to strcut. +func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error { + switch t.Kind() { + case reflect.String: + if len(key.String()) == 0 { + return nil + } + field.SetString(key.String()) + case reflect.Bool: + boolVal, err := key.Bool() + if err != nil { + return nil + } + field.SetBool(boolVal) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + durationVal, err := key.Duration() + if err == nil { + field.Set(reflect.ValueOf(durationVal)) + return nil + } + + intVal, err := key.Int64() + if err != nil { + return nil + } + field.SetInt(intVal) + // byte is an alias for uint8, so supporting uint8 breaks support for byte + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + durationVal, err := key.Duration() + if err == nil { + field.Set(reflect.ValueOf(durationVal)) + return nil + } + + uintVal, err := key.Uint64() + if err != nil { + return nil + } + field.SetUint(uintVal) + + case reflect.Float64: + floatVal, err := key.Float64() + if err != nil { + return nil + } + field.SetFloat(floatVal) + case reflectTime: + timeVal, err := key.Time() + if err != nil { + return nil + } + field.Set(reflect.ValueOf(timeVal)) + case reflect.Slice: + vals := key.Strings(delim) + numVals := len(vals) + if numVals == 0 { + return nil + } + + sliceOf := field.Type().Elem().Kind() + + var times []time.Time + if sliceOf == reflectTime { + times = key.Times(delim) + } + + slice := reflect.MakeSlice(field.Type(), numVals, numVals) + for i := 0; i < numVals; i++ { + switch sliceOf { + case reflectTime: + slice.Index(i).Set(reflect.ValueOf(times[i])) + default: + slice.Index(i).Set(reflect.ValueOf(vals[i])) + } + } + field.Set(slice) + default: + return fmt.Errorf("unsupported type '%s'", t) + } + return nil +} + +func (s *Section) mapTo(val reflect.Value) error { + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + typ := val.Type() + + for i := 0; i < typ.NumField(); i++ { + field := val.Field(i) + tpField := typ.Field(i) + + tag := tpField.Tag.Get("ini") + if tag == "-" { + continue + } + + fieldName := s.parseFieldName(tpField.Name, tag) + if len(fieldName) == 0 || !field.CanSet() { + continue + } + + isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous + isStruct := tpField.Type.Kind() == reflect.Struct + if isAnonymous { + field.Set(reflect.New(tpField.Type.Elem())) + } + + if isAnonymous || isStruct { + if sec, err := s.f.GetSection(fieldName); err == nil { + if err = sec.mapTo(field); err != nil { + return fmt.Errorf("error mapping field(%s): %v", fieldName, err) + } + continue + } + } + + if key, err := s.GetKey(fieldName); err == nil { + if err = setWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil { + return fmt.Errorf("error mapping field(%s): %v", fieldName, err) + } + } + } + return nil +} + +// MapTo maps section to given struct. +func (s *Section) MapTo(v interface{}) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return errors.New("cannot map to non-pointer struct") + } + + return s.mapTo(val) +} + +// MapTo maps file to given struct. +func (f *File) MapTo(v interface{}) error { + return f.Section("").MapTo(v) +} + +// MapTo maps data sources to given struct with name mapper. +func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { + cfg, err := Load(source, others...) + if err != nil { + return err + } + cfg.NameMapper = mapper + return cfg.MapTo(v) +} + +// MapTo maps data sources to given struct. +func MapTo(v, source interface{}, others ...interface{}) error { + return MapToWithMapper(v, nil, source, others...) +} + +// reflectWithProperType does the opposite thing with setWithProperType. +func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error { + switch t.Kind() { + case reflect.String: + key.SetValue(field.String()) + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float64, + reflectTime: + key.SetValue(fmt.Sprint(field)) + case reflect.Slice: + vals := field.Slice(0, field.Len()) + if field.Len() == 0 { + return nil + } + + var buf bytes.Buffer + isTime := fmt.Sprint(field.Type()) == "[]time.Time" + for i := 0; i < field.Len(); i++ { + if isTime { + buf.WriteString(vals.Index(i).Interface().(time.Time).Format(time.RFC3339)) + } else { + buf.WriteString(fmt.Sprint(vals.Index(i))) + } + buf.WriteString(delim) + } + key.SetValue(buf.String()[:buf.Len()-1]) + default: + return fmt.Errorf("unsupported type '%s'", t) + } + return nil +} + +func (s *Section) reflectFrom(val reflect.Value) error { + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + typ := val.Type() + + for i := 0; i < typ.NumField(); i++ { + field := val.Field(i) + tpField := typ.Field(i) + + tag := tpField.Tag.Get("ini") + if tag == "-" { + continue + } + + fieldName := s.parseFieldName(tpField.Name, tag) + if len(fieldName) == 0 || !field.CanSet() { + continue + } + + if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) || + (tpField.Type.Kind() == reflect.Struct) { + // Note: The only error here is section doesn't exist. + sec, err := s.f.GetSection(fieldName) + if err != nil { + // Note: fieldName can never be empty here, ignore error. + sec, _ = s.f.NewSection(fieldName) + } + if err = sec.reflectFrom(field); err != nil { + return fmt.Errorf("error reflecting field(%s): %v", fieldName, err) + } + continue + } + + // Note: Same reason as secion. + key, err := s.GetKey(fieldName) + if err != nil { + key, _ = s.NewKey(fieldName, "") + } + if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil { + return fmt.Errorf("error reflecting field(%s): %v", fieldName, err) + } + + } + return nil +} + +// ReflectFrom reflects secion from given struct. +func (s *Section) ReflectFrom(v interface{}) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return errors.New("cannot reflect from non-pointer struct") + } + + return s.reflectFrom(val) +} + +// ReflectFrom reflects file from given struct. +func (f *File) ReflectFrom(v interface{}) error { + return f.Section("").ReflectFrom(v) +} + +// ReflectFrom reflects data sources from given struct with name mapper. +func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error { + cfg.NameMapper = mapper + return cfg.ReflectFrom(v) +} + +// ReflectFrom reflects data sources from given struct. +func ReflectFrom(cfg *File, v interface{}) error { + return ReflectFromWithMapper(cfg, v, nil) +} diff --git a/vendor/github.com/golang/protobuf/AUTHORS b/vendor/github.com/golang/protobuf/AUTHORS new file mode 100644 index 0000000000..15167cd746 --- /dev/null +++ b/vendor/github.com/golang/protobuf/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/github.com/golang/protobuf/CONTRIBUTORS b/vendor/github.com/golang/protobuf/CONTRIBUTORS new file mode 100644 index 0000000000..1c4577e968 --- /dev/null +++ b/vendor/github.com/golang/protobuf/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/github.com/golang/protobuf/LICENSE b/vendor/github.com/golang/protobuf/LICENSE new file mode 100644 index 0000000000..1b1b1921ef --- /dev/null +++ b/vendor/github.com/golang/protobuf/LICENSE @@ -0,0 +1,31 @@ +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/github.com/golang/protobuf/proto/Makefile b/vendor/github.com/golang/protobuf/proto/Makefile new file mode 100644 index 0000000000..f1f06564a1 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/Makefile @@ -0,0 +1,43 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +install: + go install + +test: install generate-test-pbs + go test + + +generate-test-pbs: + make install + make -C testdata + protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto + make diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go new file mode 100644 index 0000000000..e98ddec981 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/clone.go @@ -0,0 +1,223 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Protocol buffer deep copy and merge. +// TODO: RawMessage. + +package proto + +import ( + "log" + "reflect" + "strings" +) + +// Clone returns a deep copy of a protocol buffer. +func Clone(pb Message) Message { + in := reflect.ValueOf(pb) + if in.IsNil() { + return pb + } + + out := reflect.New(in.Type().Elem()) + // out is empty so a merge is a deep copy. + mergeStruct(out.Elem(), in.Elem()) + return out.Interface().(Message) +} + +// Merge merges src into dst. +// Required and optional fields that are set in src will be set to that value in dst. +// Elements of repeated fields will be appended. +// Merge panics if src and dst are not the same type, or if dst is nil. +func Merge(dst, src Message) { + in := reflect.ValueOf(src) + out := reflect.ValueOf(dst) + if out.IsNil() { + panic("proto: nil destination") + } + if in.Type() != out.Type() { + // Explicit test prior to mergeStruct so that mistyped nils will fail + panic("proto: type mismatch") + } + if in.IsNil() { + // Merging nil into non-nil is a quiet no-op + return + } + mergeStruct(out.Elem(), in.Elem()) +} + +func mergeStruct(out, in reflect.Value) { + sprop := GetProperties(in.Type()) + for i := 0; i < in.NumField(); i++ { + f := in.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) + } + + if emIn, ok := in.Addr().Interface().(extendableProto); ok { + emOut := out.Addr().Interface().(extendableProto) + mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) + } + + uf := in.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return + } + uin := uf.Bytes() + if len(uin) > 0 { + out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) + } +} + +// mergeAny performs a merge between two values of the same type. +// viaPtr indicates whether the values were indirected through a pointer (implying proto2). +// prop is set if this is a struct field (it may be nil). +func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { + if in.Type() == protoMessageType { + if !in.IsNil() { + if out.IsNil() { + out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) + } else { + Merge(out.Interface().(Message), in.Interface().(Message)) + } + } + return + } + switch in.Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + if !viaPtr && isProto3Zero(in) { + return + } + out.Set(in) + case reflect.Interface: + // Probably a oneof field; copy non-nil values. + if in.IsNil() { + return + } + // Allocate destination if it is not set, or set to a different type. + // Otherwise we will merge as normal. + if out.IsNil() || out.Elem().Type() != in.Elem().Type() { + out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) + } + mergeAny(out.Elem(), in.Elem(), false, nil) + case reflect.Map: + if in.Len() == 0 { + return + } + if out.IsNil() { + out.Set(reflect.MakeMap(in.Type())) + } + // For maps with value types of *T or []byte we need to deep copy each value. + elemKind := in.Type().Elem().Kind() + for _, key := range in.MapKeys() { + var val reflect.Value + switch elemKind { + case reflect.Ptr: + val = reflect.New(in.Type().Elem().Elem()) + mergeAny(val, in.MapIndex(key), false, nil) + case reflect.Slice: + val = in.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + default: + val = in.MapIndex(key) + } + out.SetMapIndex(key, val) + } + case reflect.Ptr: + if in.IsNil() { + return + } + if out.IsNil() { + out.Set(reflect.New(in.Elem().Type())) + } + mergeAny(out.Elem(), in.Elem(), true, nil) + case reflect.Slice: + if in.IsNil() { + return + } + if in.Type().Elem().Kind() == reflect.Uint8 { + // []byte is a scalar bytes field, not a repeated field. + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value, and should not + // be merged. + if prop != nil && prop.proto3 && in.Len() == 0 { + return + } + + // Make a deep copy. + // Append to []byte{} instead of []byte(nil) so that we never end up + // with a nil result. + out.SetBytes(append([]byte{}, in.Bytes()...)) + return + } + n := in.Len() + if out.IsNil() { + out.Set(reflect.MakeSlice(in.Type(), 0, n)) + } + switch in.Type().Elem().Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + out.Set(reflect.AppendSlice(out, in)) + default: + for i := 0; i < n; i++ { + x := reflect.Indirect(reflect.New(in.Type().Elem())) + mergeAny(x, in.Index(i), false, nil) + out.Set(reflect.Append(out, x)) + } + } + case reflect.Struct: + mergeStruct(out, in) + default: + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to copy %v", in) + } +} + +func mergeExtension(out, in map[int32]Extension) { + for extNum, eIn := range in { + eOut := Extension{desc: eIn.desc} + if eIn.value != nil { + v := reflect.New(reflect.TypeOf(eIn.value)).Elem() + mergeAny(v, reflect.ValueOf(eIn.value), false, nil) + eOut.value = v.Interface() + } + if eIn.enc != nil { + eOut.enc = make([]byte, len(eIn.enc)) + copy(eOut.enc, eIn.enc) + } + + out[extNum] = eOut + } +} diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go new file mode 100644 index 0000000000..5810782fd8 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -0,0 +1,867 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Routines for decoding protocol buffer data to construct in-memory representations. + */ + +import ( + "errors" + "fmt" + "io" + "os" + "reflect" +) + +// errOverflow is returned when an integer is too large to be represented. +var errOverflow = errors.New("proto: integer overflow") + +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + +// The fundamental decoders that interpret bytes on the wire. +// Those that take integer types all return uint64 and are +// therefore of type valueDecoder. + +// DecodeVarint reads a varint-encoded integer from the slice. +// It returns the integer and the number of bytes consumed, or +// zero if there is not enough. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func DecodeVarint(buf []byte) (x uint64, n int) { + // x, n already 0 + for shift := uint(0); shift < 64; shift += 7 { + if n >= len(buf) { + return 0, 0 + } + b := uint64(buf[n]) + n++ + x |= (b & 0x7F) << shift + if (b & 0x80) == 0 { + return x, n + } + } + + // The number is too large to represent in a 64-bit value. + return 0, 0 +} + +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + // x, err already 0 + + i := p.index + l := len(p.buf) + + for shift := uint(0); shift < 64; shift += 7 { + if i >= l { + err = io.ErrUnexpectedEOF + return + } + b := p.buf[i] + i++ + x |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + p.index = i + return + } + } + + // The number is too large to represent in a 64-bit value. + err = errOverflow + return +} + +// DecodeFixed64 reads a 64-bit integer from the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) DecodeFixed64() (x uint64, err error) { + // x, err already 0 + i := p.index + 8 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-8]) + x |= uint64(p.buf[i-7]) << 8 + x |= uint64(p.buf[i-6]) << 16 + x |= uint64(p.buf[i-5]) << 24 + x |= uint64(p.buf[i-4]) << 32 + x |= uint64(p.buf[i-3]) << 40 + x |= uint64(p.buf[i-2]) << 48 + x |= uint64(p.buf[i-1]) << 56 + return +} + +// DecodeFixed32 reads a 32-bit integer from the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) DecodeFixed32() (x uint64, err error) { + // x, err already 0 + i := p.index + 4 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-4]) + x |= uint64(p.buf[i-3]) << 8 + x |= uint64(p.buf[i-2]) << 16 + x |= uint64(p.buf[i-1]) << 24 + return +} + +// DecodeZigzag64 reads a zigzag-encoded 64-bit integer +// from the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) DecodeZigzag64() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) + return +} + +// DecodeZigzag32 reads a zigzag-encoded 32-bit integer +// from the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) DecodeZigzag32() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) + return +} + +// These are not ValueDecoders: they produce an array of bytes or a string. +// bytes, embedded messages + +// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { + n, err := p.DecodeVarint() + if err != nil { + return nil, err + } + + nb := int(n) + if nb < 0 { + return nil, fmt.Errorf("proto: bad byte length %d", nb) + } + end := p.index + nb + if end < p.index || end > len(p.buf) { + return nil, io.ErrUnexpectedEOF + } + + if !alloc { + // todo: check if can get more uses of alloc=false + buf = p.buf[p.index:end] + p.index += nb + return + } + + buf = make([]byte, nb) + copy(buf, p.buf[p.index:]) + p.index += nb + return +} + +// DecodeStringBytes reads an encoded string from the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) DecodeStringBytes() (s string, err error) { + buf, err := p.DecodeRawBytes(false) + if err != nil { + return + } + return string(buf), nil +} + +// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. +// If the protocol buffer has extensions, and the field matches, add it as an extension. +// Otherwise, if the XXX_unrecognized field exists, append the skipped data there. +func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error { + oi := o.index + + err := o.skip(t, tag, wire) + if err != nil { + return err + } + + if !unrecField.IsValid() { + return nil + } + + ptr := structPointer_Bytes(base, unrecField) + + // Add the skipped field to struct field + obuf := o.buf + + o.buf = *ptr + o.EncodeVarint(uint64(tag<<3 | wire)) + *ptr = append(o.buf, obuf[oi:o.index]...) + + o.buf = obuf + + return nil +} + +// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. +func (o *Buffer) skip(t reflect.Type, tag, wire int) error { + + var u uint64 + var err error + + switch wire { + case WireVarint: + _, err = o.DecodeVarint() + case WireFixed64: + _, err = o.DecodeFixed64() + case WireBytes: + _, err = o.DecodeRawBytes(false) + case WireFixed32: + _, err = o.DecodeFixed32() + case WireStartGroup: + for { + u, err = o.DecodeVarint() + if err != nil { + break + } + fwire := int(u & 0x7) + if fwire == WireEndGroup { + break + } + ftag := int(u >> 3) + err = o.skip(t, ftag, fwire) + if err != nil { + break + } + } + default: + err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t) + } + return err +} + +// Unmarshaler is the interface representing objects that can +// unmarshal themselves. The method should reset the receiver before +// decoding starts. The argument points to data that may be +// overwritten, so implementations should not keep references to the +// buffer. +type Unmarshaler interface { + Unmarshal([]byte) error +} + +// Unmarshal parses the protocol buffer representation in buf and places the +// decoded result in pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// Unmarshal resets pb before starting to unmarshal, so any +// existing data in pb is always removed. Use UnmarshalMerge +// to preserve and append to existing data. +func Unmarshal(buf []byte, pb Message) error { + pb.Reset() + return UnmarshalMerge(buf, pb) +} + +// UnmarshalMerge parses the protocol buffer representation in buf and +// writes the decoded result to pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// UnmarshalMerge merges into existing data in pb. +// Most code should use Unmarshal instead. +func UnmarshalMerge(buf []byte, pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(Unmarshaler); ok { + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +func (p *Buffer) DecodeGroup(pb Message) error { + typ, base, err := getbase(pb) + if err != nil { + return err + } + return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base) +} + +// Unmarshal parses the protocol buffer representation in the +// Buffer and places the decoded result in pb. If the struct +// underlying pb does not match the data in the buffer, the results can be +// unpredictable. +func (p *Buffer) Unmarshal(pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(Unmarshaler); ok { + err := u.Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + + typ, base, err := getbase(pb) + if err != nil { + return err + } + + err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base) + + if collectStats { + stats.Decode++ + } + + return err +} + +// unmarshalType does the work of unmarshaling a structure. +func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error { + var state errorState + required, reqFields := prop.reqCount, uint64(0) + + var err error + for err == nil && o.index < len(o.buf) { + oi := o.index + var u uint64 + u, err = o.DecodeVarint() + if err != nil { + break + } + wire := int(u & 0x7) + if wire == WireEndGroup { + if is_group { + return nil // input is satisfied + } + return fmt.Errorf("proto: %s: wiretype end group for non-group", st) + } + tag := int(u >> 3) + if tag <= 0 { + return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire) + } + fieldnum, ok := prop.decoderTags.get(tag) + if !ok { + // Maybe it's an extension? + if prop.extendable { + if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) { + if err = o.skip(st, tag, wire); err == nil { + ext := e.ExtensionMap()[int32(tag)] // may be missing + ext.enc = append(ext.enc, o.buf[oi:o.index]...) + e.ExtensionMap()[int32(tag)] = ext + } + continue + } + } + // Maybe it's a oneof? + if prop.oneofUnmarshaler != nil { + m := structPointer_Interface(base, st).(Message) + // First return value indicates whether tag is a oneof field. + ok, err = prop.oneofUnmarshaler(m, tag, wire, o) + if err == ErrInternalBadWireType { + // Map the error to something more descriptive. + // Do the formatting here to save generated code space. + err = fmt.Errorf("bad wiretype for oneof field in %T", m) + } + if ok { + continue + } + } + err = o.skipAndSave(st, tag, wire, base, prop.unrecField) + continue + } + p := prop.Prop[fieldnum] + + if p.dec == nil { + fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name) + continue + } + dec := p.dec + if wire != WireStartGroup && wire != p.WireType { + if wire == WireBytes && p.packedDec != nil { + // a packable field + dec = p.packedDec + } else { + err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType) + continue + } + } + decErr := dec(o, p, base) + if decErr != nil && !state.shouldContinue(decErr, p) { + err = decErr + } + if err == nil && p.Required { + // Successfully decoded a required field. + if tag <= 64 { + // use bitmap for fields 1-64 to catch field reuse. + var mask uint64 = 1 << uint64(tag-1) + if reqFields&mask == 0 { + // new required field + reqFields |= mask + required-- + } + } else { + // This is imprecise. It can be fooled by a required field + // with a tag > 64 that is encoded twice; that's very rare. + // A fully correct implementation would require allocating + // a data structure, which we would like to avoid. + required-- + } + } + } + if err == nil { + if is_group { + return io.ErrUnexpectedEOF + } + if state.err != nil { + return state.err + } + if required > 0 { + // Not enough information to determine the exact field. If we use extra + // CPU, we could determine the field only if the missing required field + // has a tag <= 64 and we check reqFields. + return &RequiredNotSetError{"{Unknown}"} + } + } + return err +} + +// Individual type decoders +// For each, +// u is the decoded value, +// v is a pointer to the field (pointer) in the struct + +// Sizes of the pools to allocate inside the Buffer. +// The goal is modest amortization and allocation +// on at least 16-byte boundaries. +const ( + boolPoolSize = 16 + uint32PoolSize = 8 + uint64PoolSize = 4 +) + +// Decode a bool. +func (o *Buffer) dec_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + if len(o.bools) == 0 { + o.bools = make([]bool, boolPoolSize) + } + o.bools[0] = u != 0 + *structPointer_Bool(base, p.field) = &o.bools[0] + o.bools = o.bools[1:] + return nil +} + +func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + *structPointer_BoolVal(base, p.field) = u != 0 + return nil +} + +// Decode an int32. +func (o *Buffer) dec_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word32_Set(structPointer_Word32(base, p.field), o, uint32(u)) + return nil +} + +func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u)) + return nil +} + +// Decode an int64. +func (o *Buffer) dec_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word64_Set(structPointer_Word64(base, p.field), o, u) + return nil +} + +func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word64Val_Set(structPointer_Word64Val(base, p.field), o, u) + return nil +} + +// Decode a string. +func (o *Buffer) dec_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + *structPointer_String(base, p.field) = &s + return nil +} + +func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + *structPointer_StringVal(base, p.field) = s + return nil +} + +// Decode a slice of bytes ([]byte). +func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error { + b, err := o.DecodeRawBytes(true) + if err != nil { + return err + } + *structPointer_Bytes(base, p.field) = b + return nil +} + +// Decode a slice of bools ([]bool). +func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + v := structPointer_BoolSlice(base, p.field) + *v = append(*v, u != 0) + return nil +} + +// Decode a slice of bools ([]bool) in packed format. +func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error { + v := structPointer_BoolSlice(base, p.field) + + nn, err := o.DecodeVarint() + if err != nil { + return err + } + nb := int(nn) // number of bytes of encoded bools + fin := o.index + nb + if fin < o.index { + return errOverflow + } + + y := *v + for o.index < fin { + u, err := p.valDec(o) + if err != nil { + return err + } + y = append(y, u != 0) + } + + *v = y + return nil +} + +// Decode a slice of int32s ([]int32). +func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + structPointer_Word32Slice(base, p.field).Append(uint32(u)) + return nil +} + +// Decode a slice of int32s ([]int32) in packed format. +func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error { + v := structPointer_Word32Slice(base, p.field) + + nn, err := o.DecodeVarint() + if err != nil { + return err + } + nb := int(nn) // number of bytes of encoded int32s + + fin := o.index + nb + if fin < o.index { + return errOverflow + } + for o.index < fin { + u, err := p.valDec(o) + if err != nil { + return err + } + v.Append(uint32(u)) + } + return nil +} + +// Decode a slice of int64s ([]int64). +func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + + structPointer_Word64Slice(base, p.field).Append(u) + return nil +} + +// Decode a slice of int64s ([]int64) in packed format. +func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error { + v := structPointer_Word64Slice(base, p.field) + + nn, err := o.DecodeVarint() + if err != nil { + return err + } + nb := int(nn) // number of bytes of encoded int64s + + fin := o.index + nb + if fin < o.index { + return errOverflow + } + for o.index < fin { + u, err := p.valDec(o) + if err != nil { + return err + } + v.Append(u) + } + return nil +} + +// Decode a slice of strings ([]string). +func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + v := structPointer_StringSlice(base, p.field) + *v = append(*v, s) + return nil +} + +// Decode a slice of slice of bytes ([][]byte). +func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error { + b, err := o.DecodeRawBytes(true) + if err != nil { + return err + } + v := structPointer_BytesSlice(base, p.field) + *v = append(*v, b) + return nil +} + +// Decode a map field. +func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { + raw, err := o.DecodeRawBytes(false) + if err != nil { + return err + } + oi := o.index // index at the end of this map entry + o.index -= len(raw) // move buffer back to start of map entry + + mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V + if mptr.Elem().IsNil() { + mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) + } + v := mptr.Elem() // map[K]V + + // Prepare addressable doubly-indirect placeholders for the key and value types. + // See enc_new_map for why. + keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K + keybase := toStructPointer(keyptr.Addr()) // **K + + var valbase structPointer + var valptr reflect.Value + switch p.mtype.Elem().Kind() { + case reflect.Slice: + // []byte + var dummy []byte + valptr = reflect.ValueOf(&dummy) // *[]byte + valbase = toStructPointer(valptr) // *[]byte + case reflect.Ptr: + // message; valptr is **Msg; need to allocate the intermediate pointer + valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V + valptr.Set(reflect.New(valptr.Type().Elem())) + valbase = toStructPointer(valptr) + default: + // everything else + valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V + valbase = toStructPointer(valptr.Addr()) // **V + } + + // Decode. + // This parses a restricted wire format, namely the encoding of a message + // with two fields. See enc_new_map for the format. + for o.index < oi { + // tagcode for key and value properties are always a single byte + // because they have tags 1 and 2. + tagcode := o.buf[o.index] + o.index++ + switch tagcode { + case p.mkeyprop.tagcode[0]: + if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil { + return err + } + case p.mvalprop.tagcode[0]: + if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil { + return err + } + default: + // TODO: Should we silently skip this instead? + return fmt.Errorf("proto: bad map data tag %d", raw[0]) + } + } + keyelem, valelem := keyptr.Elem(), valptr.Elem() + if !keyelem.IsValid() || !valelem.IsValid() { + // We did not decode the key or the value in the map entry. + // Either way, it's an invalid map entry. + return fmt.Errorf("proto: bad map data: missing key/val") + } + + v.SetMapIndex(keyelem, valelem) + return nil +} + +// Decode a group. +func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error { + bas := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(bas) { + // allocate new nested message + bas = toStructPointer(reflect.New(p.stype)) + structPointer_SetStructPointer(base, p.field, bas) + } + return o.unmarshalType(p.stype, p.sprop, true, bas) +} + +// Decode an embedded message. +func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) { + raw, e := o.DecodeRawBytes(false) + if e != nil { + return e + } + + bas := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(bas) { + // allocate new nested message + bas = toStructPointer(reflect.New(p.stype)) + structPointer_SetStructPointer(base, p.field, bas) + } + + // If the object can unmarshal itself, let it. + if p.isUnmarshaler { + iv := structPointer_Interface(bas, p.stype) + return iv.(Unmarshaler).Unmarshal(raw) + } + + obuf := o.buf + oi := o.index + o.buf = raw + o.index = 0 + + err = o.unmarshalType(p.stype, p.sprop, false, bas) + o.buf = obuf + o.index = oi + + return err +} + +// Decode a slice of embedded messages. +func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error { + return o.dec_slice_struct(p, false, base) +} + +// Decode a slice of embedded groups. +func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error { + return o.dec_slice_struct(p, true, base) +} + +// Decode a slice of structs ([]*struct). +func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error { + v := reflect.New(p.stype) + bas := toStructPointer(v) + structPointer_StructPointerSlice(base, p.field).Append(bas) + + if is_group { + err := o.unmarshalType(p.stype, p.sprop, is_group, bas) + return err + } + + raw, err := o.DecodeRawBytes(false) + if err != nil { + return err + } + + // If the object can unmarshal itself, let it. + if p.isUnmarshaler { + iv := v.Interface() + return iv.(Unmarshaler).Unmarshal(raw) + } + + obuf := o.buf + oi := o.index + o.buf = raw + o.index = 0 + + err = o.unmarshalType(p.stype, p.sprop, is_group, bas) + + o.buf = obuf + o.index = oi + + return err +} diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go new file mode 100644 index 0000000000..231b07401a --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/encode.go @@ -0,0 +1,1325 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "errors" + "fmt" + "reflect" + "sort" +) + +// RequiredNotSetError is the error returned if Marshal is called with +// a protocol buffer struct whose required fields have not +// all been initialized. It is also the error returned if Unmarshal is +// called with an encoded protocol buffer that does not include all the +// required fields. +// +// When printed, RequiredNotSetError reports the first unset required field in a +// message. If the field cannot be precisely determined, it is reported as +// "{Unknown}". +type RequiredNotSetError struct { + field string +} + +func (e *RequiredNotSetError) Error() string { + return fmt.Sprintf("proto: required field %q not set", e.field) +} + +var ( + // errRepeatedHasNil is the error returned if Marshal is called with + // a struct with a repeated field containing a nil element. + errRepeatedHasNil = errors.New("proto: repeated field has nil element") + + // ErrNil is the error returned if Marshal is called with nil. + ErrNil = errors.New("proto: Marshal called with nil") +) + +// The fundamental encoders that put bytes on the wire. +// Those that take integer types all accept uint64 and are +// therefore of type valueEncoder. + +const maxVarintBytes = 10 // maximum length of a varint + +// EncodeVarint returns the varint encoding of x. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +// Not used by the package itself, but helpful to clients +// wishing to use the same encoding. +func EncodeVarint(x uint64) []byte { + var buf [maxVarintBytes]byte + var n int + for n = 0; x > 127; n++ { + buf[n] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + buf[n] = uint8(x) + n++ + return buf[0:n] +} + +// EncodeVarint writes a varint-encoded integer to the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) EncodeVarint(x uint64) error { + for x >= 1<<7 { + p.buf = append(p.buf, uint8(x&0x7f|0x80)) + x >>= 7 + } + p.buf = append(p.buf, uint8(x)) + return nil +} + +// SizeVarint returns the varint encoding size of an integer. +func SizeVarint(x uint64) int { + return sizeVarint(x) +} + +func sizeVarint(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} + +// EncodeFixed64 writes a 64-bit integer to the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) EncodeFixed64(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24), + uint8(x>>32), + uint8(x>>40), + uint8(x>>48), + uint8(x>>56)) + return nil +} + +func sizeFixed64(x uint64) int { + return 8 +} + +// EncodeFixed32 writes a 32-bit integer to the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) EncodeFixed32(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24)) + return nil +} + +func sizeFixed32(x uint64) int { + return 4 +} + +// EncodeZigzag64 writes a zigzag-encoded 64-bit integer +// to the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) EncodeZigzag64(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func sizeZigzag64(x uint64) int { + return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +// EncodeZigzag32 writes a zigzag-encoded 32-bit integer +// to the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) EncodeZigzag32(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + +func sizeZigzag32(x uint64) int { + return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + +// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) EncodeRawBytes(b []byte) error { + p.EncodeVarint(uint64(len(b))) + p.buf = append(p.buf, b...) + return nil +} + +func sizeRawBytes(b []byte) int { + return sizeVarint(uint64(len(b))) + + len(b) +} + +// EncodeStringBytes writes an encoded string to the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) EncodeStringBytes(s string) error { + p.EncodeVarint(uint64(len(s))) + p.buf = append(p.buf, s...) + return nil +} + +func sizeStringBytes(s string) int { + return sizeVarint(uint64(len(s))) + + len(s) +} + +// Marshaler is the interface representing objects that can marshal themselves. +type Marshaler interface { + Marshal() ([]byte, error) +} + +// Marshal takes the protocol buffer +// and encodes it into the wire format, returning the data. +func Marshal(pb Message) ([]byte, error) { + // Can the object marshal itself? + if m, ok := pb.(Marshaler); ok { + return m.Marshal() + } + p := NewBuffer(nil) + err := p.Marshal(pb) + var state errorState + if err != nil && !state.shouldContinue(err, nil) { + return nil, err + } + if p.buf == nil && err == nil { + // Return a non-nil slice on success. + return []byte{}, nil + } + return p.buf, err +} + +// EncodeMessage writes the protocol buffer to the Buffer, +// prefixed by a varint-encoded length. +func (p *Buffer) EncodeMessage(pb Message) error { + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return ErrNil + } + if err == nil { + var state errorState + err = p.enc_len_struct(GetProperties(t.Elem()), base, &state) + } + return err +} + +// Marshal takes the protocol buffer +// and encodes it into the wire format, writing the result to the +// Buffer. +func (p *Buffer) Marshal(pb Message) error { + // Can the object marshal itself? + if m, ok := pb.(Marshaler); ok { + data, err := m.Marshal() + if err != nil { + return err + } + p.buf = append(p.buf, data...) + return nil + } + + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return ErrNil + } + if err == nil { + err = p.enc_struct(GetProperties(t.Elem()), base) + } + + if collectStats { + stats.Encode++ + } + + return err +} + +// Size returns the encoded size of a protocol buffer. +func Size(pb Message) (n int) { + // Can the object marshal itself? If so, Size is slow. + // TODO: add Size to Marshaler, or add a Sizer interface. + if m, ok := pb.(Marshaler); ok { + b, _ := m.Marshal() + return len(b) + } + + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return 0 + } + if err == nil { + n = size_struct(GetProperties(t.Elem()), base) + } + + if collectStats { + stats.Size++ + } + + return +} + +// Individual type encoders. + +// Encode a bool. +func (o *Buffer) enc_bool(p *Properties, base structPointer) error { + v := *structPointer_Bool(base, p.field) + if v == nil { + return ErrNil + } + x := 0 + if *v { + x = 1 + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error { + v := *structPointer_BoolVal(base, p.field) + if !v { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, 1) + return nil +} + +func size_bool(p *Properties, base structPointer) int { + v := *structPointer_Bool(base, p.field) + if v == nil { + return 0 + } + return len(p.tagcode) + 1 // each bool takes exactly one byte +} + +func size_proto3_bool(p *Properties, base structPointer) int { + v := *structPointer_BoolVal(base, p.field) + if !v && !p.oneof { + return 0 + } + return len(p.tagcode) + 1 // each bool takes exactly one byte +} + +// Encode an int32. +func (o *Buffer) enc_int32(p *Properties, base structPointer) error { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return ErrNil + } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error { + v := structPointer_Word32Val(base, p.field) + x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_int32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +func size_proto3_int32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32Val(base, p.field) + x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range + if x == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +// Encode a uint32. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return ErrNil + } + x := word32_Get(v) + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32Val(base, p.field) + x := word32Val_Get(v) + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } + x := word32_Get(v) + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +func size_proto3_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32Val(base, p.field) + x := word32Val_Get(v) + if x == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +// Encode an int64. +func (o *Buffer) enc_int64(p *Properties, base structPointer) error { + v := structPointer_Word64(base, p.field) + if word64_IsNil(v) { + return ErrNil + } + x := word64_Get(v) + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, x) + return nil +} + +func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error { + v := structPointer_Word64Val(base, p.field) + x := word64Val_Get(v) + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, x) + return nil +} + +func size_int64(p *Properties, base structPointer) (n int) { + v := structPointer_Word64(base, p.field) + if word64_IsNil(v) { + return 0 + } + x := word64_Get(v) + n += len(p.tagcode) + n += p.valSize(x) + return +} + +func size_proto3_int64(p *Properties, base structPointer) (n int) { + v := structPointer_Word64Val(base, p.field) + x := word64Val_Get(v) + if x == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += p.valSize(x) + return +} + +// Encode a string. +func (o *Buffer) enc_string(p *Properties, base structPointer) error { + v := *structPointer_String(base, p.field) + if v == nil { + return ErrNil + } + x := *v + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(x) + return nil +} + +func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error { + v := *structPointer_StringVal(base, p.field) + if v == "" { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(v) + return nil +} + +func size_string(p *Properties, base structPointer) (n int) { + v := *structPointer_String(base, p.field) + if v == nil { + return 0 + } + x := *v + n += len(p.tagcode) + n += sizeStringBytes(x) + return +} + +func size_proto3_string(p *Properties, base structPointer) (n int) { + v := *structPointer_StringVal(base, p.field) + if v == "" && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += sizeStringBytes(v) + return +} + +// All protocol buffer fields are nillable, but be careful. +func isNil(v reflect.Value) bool { + switch v.Kind() { + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + return false +} + +// Encode a message struct. +func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error { + var state errorState + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return ErrNil + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, err := m.Marshal() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + return state.err + } + + o.buf = append(o.buf, p.tagcode...) + return o.enc_len_struct(p.sprop, structp, &state) +} + +func size_struct_message(p *Properties, base structPointer) int { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return 0 + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, _ := m.Marshal() + n0 := len(p.tagcode) + n1 := sizeRawBytes(data) + return n0 + n1 + } + + n0 := len(p.tagcode) + n1 := size_struct(p.sprop, structp) + n2 := sizeVarint(uint64(n1)) // size of encoded length + return n0 + n1 + n2 +} + +// Encode a group struct. +func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error { + var state errorState + b := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(b) { + return ErrNil + } + + o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) + err := o.enc_struct(p.sprop, b) + if err != nil && !state.shouldContinue(err, nil) { + return err + } + o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) + return state.err +} + +func size_struct_group(p *Properties, base structPointer) (n int) { + b := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(b) { + return 0 + } + + n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup)) + n += size_struct(p.sprop, b) + n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup)) + return +} + +// Encode a slice of bools ([]bool). +func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return ErrNil + } + for _, x := range s { + o.buf = append(o.buf, p.tagcode...) + v := uint64(0) + if x { + v = 1 + } + p.valEnc(o, v) + } + return nil +} + +func size_slice_bool(p *Properties, base structPointer) int { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return 0 + } + return l * (len(p.tagcode) + 1) // each bool takes exactly one byte +} + +// Encode a slice of bools ([]bool) in packed format. +func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(l)) // each bool takes exactly one byte + for _, x := range s { + v := uint64(0) + if x { + v = 1 + } + p.valEnc(o, v) + } + return nil +} + +func size_slice_packed_bool(p *Properties, base structPointer) (n int) { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return 0 + } + n += len(p.tagcode) + n += sizeVarint(uint64(l)) + n += l // each bool takes exactly one byte + return +} + +// Encode a slice of bytes ([]byte). +func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error { + s := *structPointer_Bytes(base, p.field) + if s == nil { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(s) + return nil +} + +func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error { + s := *structPointer_Bytes(base, p.field) + if len(s) == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(s) + return nil +} + +func size_slice_byte(p *Properties, base structPointer) (n int) { + s := *structPointer_Bytes(base, p.field) + if s == nil && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += sizeRawBytes(s) + return +} + +func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { + s := *structPointer_Bytes(base, p.field) + if len(s) == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += sizeRawBytes(s) + return +} + +// Encode a slice of int32s ([]int32). +func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + p.valEnc(o, uint64(x)) + } + return nil +} + +func size_slice_int32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + n += p.valSize(uint64(x)) + } + return +} + +// Encode a slice of int32s ([]int32) in packed format. +func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + p.valEnc(buf, uint64(x)) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_int32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + bufSize += p.valSize(uint64(x)) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of uint32s ([]uint32). +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + x := s.Index(i) + p.valEnc(o, uint64(x)) + } + return nil +} + +func size_slice_uint32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + x := s.Index(i) + n += p.valSize(uint64(x)) + } + return +} + +// Encode a slice of uint32s ([]uint32) in packed format. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { + p.valEnc(buf, uint64(s.Index(i))) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_uint32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + bufSize += p.valSize(uint64(s.Index(i))) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of int64s ([]int64). +func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, s.Index(i)) + } + return nil +} + +func size_slice_int64(p *Properties, base structPointer) (n int) { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + n += p.valSize(s.Index(i)) + } + return +} + +// Encode a slice of int64s ([]int64) in packed format. +func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { + p.valEnc(buf, s.Index(i)) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_int64(p *Properties, base structPointer) (n int) { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + bufSize += p.valSize(s.Index(i)) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of slice of bytes ([][]byte). +func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error { + ss := *structPointer_BytesSlice(base, p.field) + l := len(ss) + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(ss[i]) + } + return nil +} + +func size_slice_slice_byte(p *Properties, base structPointer) (n int) { + ss := *structPointer_BytesSlice(base, p.field) + l := len(ss) + if l == 0 { + return 0 + } + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + n += sizeRawBytes(ss[i]) + } + return +} + +// Encode a slice of strings ([]string). +func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error { + ss := *structPointer_StringSlice(base, p.field) + l := len(ss) + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(ss[i]) + } + return nil +} + +func size_slice_string(p *Properties, base structPointer) (n int) { + ss := *structPointer_StringSlice(base, p.field) + l := len(ss) + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + n += sizeStringBytes(ss[i]) + } + return +} + +// Encode a slice of message structs ([]*struct). +func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error { + var state errorState + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + for i := 0; i < l; i++ { + structp := s.Index(i) + if structPointer_IsNil(structp) { + return errRepeatedHasNil + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, err := m.Marshal() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + continue + } + + o.buf = append(o.buf, p.tagcode...) + err := o.enc_len_struct(p.sprop, structp, &state) + if err != nil && !state.shouldContinue(err, nil) { + if err == ErrNil { + return errRepeatedHasNil + } + return err + } + } + return state.err +} + +func size_slice_struct_message(p *Properties, base structPointer) (n int) { + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + structp := s.Index(i) + if structPointer_IsNil(structp) { + return // return the size up to this point + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, _ := m.Marshal() + n += len(p.tagcode) + n += sizeRawBytes(data) + continue + } + + n0 := size_struct(p.sprop, structp) + n1 := sizeVarint(uint64(n0)) // size of encoded length + n += n0 + n1 + } + return +} + +// Encode a slice of group structs ([]*struct). +func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error { + var state errorState + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + for i := 0; i < l; i++ { + b := s.Index(i) + if structPointer_IsNil(b) { + return errRepeatedHasNil + } + + o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) + + err := o.enc_struct(p.sprop, b) + + if err != nil && !state.shouldContinue(err, nil) { + if err == ErrNil { + return errRepeatedHasNil + } + return err + } + + o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) + } + return state.err +} + +func size_slice_struct_group(p *Properties, base structPointer) (n int) { + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup)) + n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup)) + for i := 0; i < l; i++ { + b := s.Index(i) + if structPointer_IsNil(b) { + return // return size up to this point + } + + n += size_struct(p.sprop, b) + } + return +} + +// Encode an extension map. +func (o *Buffer) enc_map(p *Properties, base structPointer) error { + v := *structPointer_ExtMap(base, p.field) + if err := encodeExtensionMap(v); err != nil { + return err + } + // Fast-path for common cases: zero or one extensions. + if len(v) <= 1 { + for _, e := range v { + o.buf = append(o.buf, e.enc...) + } + return nil + } + + // Sort keys to provide a deterministic encoding. + keys := make([]int, 0, len(v)) + for k := range v { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, k := range keys { + o.buf = append(o.buf, v[int32(k)].enc...) + } + return nil +} + +func size_map(p *Properties, base structPointer) int { + v := *structPointer_ExtMap(base, p.field) + return sizeExtensionMap(v) +} + +// Encode a map field. +func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { + var state errorState // XXX: or do we need to plumb this through? + + /* + A map defined as + map map_field = N; + is encoded in the same way as + message MapFieldEntry { + key_type key = 1; + value_type value = 2; + } + repeated MapFieldEntry map_field = N; + */ + + v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V + if v.Len() == 0 { + return nil + } + + keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) + + enc := func() error { + if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil { + return err + } + if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil { + return err + } + return nil + } + + // Don't sort map keys. It is not required by the spec, and C++ doesn't do it. + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + + // The only illegal map entry values are nil message pointers. + if val.Kind() == reflect.Ptr && val.IsNil() { + return errors.New("proto: map has nil element") + } + + keycopy.Set(key) + valcopy.Set(val) + + o.buf = append(o.buf, p.tagcode...) + if err := o.enc_len_thing(enc, &state); err != nil { + return err + } + } + return nil +} + +func size_new_map(p *Properties, base structPointer) int { + v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V + + keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) + + n := 0 + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + keycopy.Set(key) + valcopy.Set(val) + + // Tag codes for key and val are the responsibility of the sub-sizer. + keysize := p.mkeyprop.size(p.mkeyprop, keybase) + valsize := p.mvalprop.size(p.mvalprop, valbase) + entry := keysize + valsize + // Add on tag code and length of map entry itself. + n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry + } + return n +} + +// mapEncodeScratch returns a new reflect.Value matching the map's value type, +// and a structPointer suitable for passing to an encoder or sizer. +func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) { + // Prepare addressable doubly-indirect placeholders for the key and value types. + // This is needed because the element-type encoders expect **T, but the map iteration produces T. + + keycopy = reflect.New(mapType.Key()).Elem() // addressable K + keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K + keyptr.Set(keycopy.Addr()) // + keybase = toStructPointer(keyptr.Addr()) // **K + + // Value types are more varied and require special handling. + switch mapType.Elem().Kind() { + case reflect.Slice: + // []byte + var dummy []byte + valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte + valbase = toStructPointer(valcopy.Addr()) + case reflect.Ptr: + // message; the generated field type is map[K]*Msg (so V is *Msg), + // so we only need one level of indirection. + valcopy = reflect.New(mapType.Elem()).Elem() // addressable V + valbase = toStructPointer(valcopy.Addr()) + default: + // everything else + valcopy = reflect.New(mapType.Elem()).Elem() // addressable V + valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V + valptr.Set(valcopy.Addr()) // + valbase = toStructPointer(valptr.Addr()) // **V + } + return +} + +// Encode a struct. +func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { + var state errorState + // Encode fields in tag order so that decoders may use optimizations + // that depend on the ordering. + // https://developers.google.com/protocol-buffers/docs/encoding#order + for _, i := range prop.order { + p := prop.Prop[i] + if p.enc != nil { + err := p.enc(o, p, base) + if err != nil { + if err == ErrNil { + if p.Required && state.err == nil { + state.err = &RequiredNotSetError{p.Name} + } + } else if err == errRepeatedHasNil { + // Give more context to nil values in repeated fields. + return errors.New("repeated field " + p.OrigName + " has nil element") + } else if !state.shouldContinue(err, p) { + return err + } + } + } + } + + // Do oneof fields. + if prop.oneofMarshaler != nil { + m := structPointer_Interface(base, prop.stype).(Message) + if err := prop.oneofMarshaler(m, o); err != nil { + return err + } + } + + // Add unrecognized fields at the end. + if prop.unrecField.IsValid() { + v := *structPointer_Bytes(base, prop.unrecField) + if len(v) > 0 { + o.buf = append(o.buf, v...) + } + } + + return state.err +} + +func size_struct(prop *StructProperties, base structPointer) (n int) { + for _, i := range prop.order { + p := prop.Prop[i] + if p.size != nil { + n += p.size(p, base) + } + } + + // Add unrecognized fields at the end. + if prop.unrecField.IsValid() { + v := *structPointer_Bytes(base, prop.unrecField) + n += len(v) + } + + // Factor in any oneof fields. + if prop.oneofSizer != nil { + m := structPointer_Interface(base, prop.stype).(Message) + n += prop.oneofSizer(m) + } + + return +} + +var zeroes [20]byte // longer than any conceivable sizeVarint + +// Encode a struct, preceded by its encoded length (as a varint). +func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error { + return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state) +} + +// Encode something, preceded by its encoded length (as a varint). +func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error { + iLen := len(o.buf) + o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length + iMsg := len(o.buf) + err := enc() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + lMsg := len(o.buf) - iMsg + lLen := sizeVarint(uint64(lMsg)) + switch x := lLen - (iMsg - iLen); { + case x > 0: // actual length is x bytes larger than the space we reserved + // Move msg x bytes right. + o.buf = append(o.buf, zeroes[:x]...) + copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) + case x < 0: // actual length is x bytes smaller than the space we reserved + // Move msg x bytes left. + copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) + o.buf = o.buf[:len(o.buf)+x] // x is negative + } + // Encode the length in the reserved space. + o.buf = o.buf[:iLen] + o.EncodeVarint(uint64(lMsg)) + o.buf = o.buf[:len(o.buf)+lMsg] + return state.err +} + +// errorState maintains the first error that occurs and updates that error +// with additional context. +type errorState struct { + err error +} + +// shouldContinue reports whether encoding should continue upon encountering the +// given error. If the error is RequiredNotSetError, shouldContinue returns true +// and, if this is the first appearance of that error, remembers it for future +// reporting. +// +// If prop is not nil, it may update any error with additional context about the +// field with the error. +func (s *errorState) shouldContinue(err error, prop *Properties) bool { + // Ignore unset required fields. + reqNotSet, ok := err.(*RequiredNotSetError) + if !ok { + return false + } + if s.err == nil { + if prop != nil { + err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field} + } + s.err = err + } + return true +} diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go new file mode 100644 index 0000000000..f5db1def3c --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -0,0 +1,276 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Protocol buffer comparison. + +package proto + +import ( + "bytes" + "log" + "reflect" + "strings" +) + +/* +Equal returns true iff protocol buffers a and b are equal. +The arguments must both be pointers to protocol buffer structs. + +Equality is defined in this way: + - Two messages are equal iff they are the same type, + corresponding fields are equal, unknown field sets + are equal, and extensions sets are equal. + - Two set scalar fields are equal iff their values are equal. + If the fields are of a floating-point type, remember that + NaN != x for all x, including NaN. If the message is defined + in a proto3 .proto file, fields are not "set"; specifically, + zero length proto3 "bytes" fields are equal (nil == {}). + - Two repeated fields are equal iff their lengths are the same, + and their corresponding elements are equal (a "bytes" field, + although represented by []byte, is not a repeated field) + - Two unset fields are equal. + - Two unknown field sets are equal if their current + encoded state is equal. + - Two extension sets are equal iff they have corresponding + elements that are pairwise equal. + - Every other combination of things are not equal. + +The return value is undefined if a and b are not protocol buffers. +*/ +func Equal(a, b Message) bool { + if a == nil || b == nil { + return a == b + } + v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) + if v1.Type() != v2.Type() { + return false + } + if v1.Kind() == reflect.Ptr { + if v1.IsNil() { + return v2.IsNil() + } + if v2.IsNil() { + return false + } + v1, v2 = v1.Elem(), v2.Elem() + } + if v1.Kind() != reflect.Struct { + return false + } + return equalStruct(v1, v2) +} + +// v1 and v2 are known to have the same type. +func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) + for i := 0; i < v1.NumField(); i++ { + f := v1.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + f1, f2 := v1.Field(i), v2.Field(i) + if f.Type.Kind() == reflect.Ptr { + if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { + // both unset + continue + } else if n1 != n2 { + // set/unset mismatch + return false + } + b1, ok := f1.Interface().(raw) + if ok { + b2 := f2.Interface().(raw) + // RawMessage + if !bytes.Equal(b1.Bytes(), b2.Bytes()) { + return false + } + continue + } + f1, f2 = f1.Elem(), f2.Elem() + } + if !equalAny(f1, f2, sprop.Prop[i]) { + return false + } + } + + if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_extensions") + if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { + return false + } + } + + uf := v1.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return true + } + + u1 := uf.Bytes() + u2 := v2.FieldByName("XXX_unrecognized").Bytes() + if !bytes.Equal(u1, u2) { + return false + } + + return true +} + +// v1 and v2 are known to have the same type. +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { + if v1.Type() == protoMessageType { + m1, _ := v1.Interface().(Message) + m2, _ := v2.Interface().(Message) + return Equal(m1, m2) + } + switch v1.Kind() { + case reflect.Bool: + return v1.Bool() == v2.Bool() + case reflect.Float32, reflect.Float64: + return v1.Float() == v2.Float() + case reflect.Int32, reflect.Int64: + return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2, nil) + case reflect.Map: + if v1.Len() != v2.Len() { + return false + } + for _, key := range v1.MapKeys() { + val2 := v2.MapIndex(key) + if !val2.IsValid() { + // This key was not found in the second map. + return false + } + if !equalAny(v1.MapIndex(key), val2, nil) { + return false + } + } + return true + case reflect.Ptr: + return equalAny(v1.Elem(), v2.Elem(), prop) + case reflect.Slice: + if v1.Type().Elem().Kind() == reflect.Uint8 { + // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) + } + + if v1.Len() != v2.Len() { + return false + } + for i := 0; i < v1.Len(); i++ { + if !equalAny(v1.Index(i), v2.Index(i), prop) { + return false + } + } + return true + case reflect.String: + return v1.Interface().(string) == v2.Interface().(string) + case reflect.Struct: + return equalStruct(v1, v2) + case reflect.Uint32, reflect.Uint64: + return v1.Uint() == v2.Uint() + } + + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to compare %v", v1) + return false +} + +// base is the struct type that the extensions are based on. +// em1 and em2 are extension maps. +func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { + if len(em1) != len(em2) { + return false + } + + for extNum, e1 := range em1 { + e2, ok := em2[extNum] + if !ok { + return false + } + + m1, m2 := e1.value, e2.value + + if m1 != nil && m2 != nil { + // Both are unencoded. + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + continue + } + + // At least one is encoded. To do a semantically correct comparison + // we need to unmarshal them first. + var desc *ExtensionDesc + if m := extensionMaps[base]; m != nil { + desc = m[extNum] + } + if desc == nil { + log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) + continue + } + var err error + if m1 == nil { + m1, err = decodeExtension(e1.enc, desc) + } + if m2 == nil && err == nil { + m2, err = decodeExtension(e2.enc, desc) + } + if err != nil { + // The encoded form is invalid. + log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) + return false + } + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + } + + return true +} diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go new file mode 100644 index 0000000000..054f4f1df7 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -0,0 +1,399 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Types and routines for supporting protocol buffer extensions. + */ + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "sync" +) + +// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. +var ErrMissingExtension = errors.New("proto: missing extension") + +// ExtensionRange represents a range of message extensions for a protocol buffer. +// Used in code generated by the protocol compiler. +type ExtensionRange struct { + Start, End int32 // both inclusive +} + +// extendableProto is an interface implemented by any protocol buffer that may be extended. +type extendableProto interface { + Message + ExtensionRangeArray() []ExtensionRange + ExtensionMap() map[int32]Extension +} + +var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() + +// ExtensionDesc represents an extension specification. +// Used in generated code from the protocol compiler. +type ExtensionDesc struct { + ExtendedType Message // nil pointer to the type that is being extended + ExtensionType interface{} // nil pointer to the extension type + Field int32 // field number + Name string // fully-qualified name of extension, for text formatting + Tag string // protobuf tag style +} + +func (ed *ExtensionDesc) repeated() bool { + t := reflect.TypeOf(ed.ExtensionType) + return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 +} + +// Extension represents an extension in a message. +type Extension struct { + // When an extension is stored in a message using SetExtension + // only desc and value are set. When the message is marshaled + // enc will be set to the encoded form of the message. + // + // When a message is unmarshaled and contains extensions, each + // extension will have only enc set. When such an extension is + // accessed using GetExtension (or GetExtensions) desc and value + // will be set. + desc *ExtensionDesc + value interface{} + enc []byte +} + +// SetRawExtension is for testing only. +func SetRawExtension(base extendableProto, id int32, b []byte) { + base.ExtensionMap()[id] = Extension{enc: b} +} + +// isExtensionField returns true iff the given field number is in an extension range. +func isExtensionField(pb extendableProto, field int32) bool { + for _, er := range pb.ExtensionRangeArray() { + if er.Start <= field && field <= er.End { + return true + } + } + return false +} + +// checkExtensionTypes checks that the given extension is valid for pb. +func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { + // Check the extended type. + if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { + return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) + } + // Check the range. + if !isExtensionField(pb, extension.Field) { + return errors.New("proto: bad extension number; not in declared ranges") + } + return nil +} + +// extPropKey is sufficient to uniquely identify an extension. +type extPropKey struct { + base reflect.Type + field int32 +} + +var extProp = struct { + sync.RWMutex + m map[extPropKey]*Properties +}{ + m: make(map[extPropKey]*Properties), +} + +func extensionProperties(ed *ExtensionDesc) *Properties { + key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} + + extProp.RLock() + if prop, ok := extProp.m[key]; ok { + extProp.RUnlock() + return prop + } + extProp.RUnlock() + + extProp.Lock() + defer extProp.Unlock() + // Check again. + if prop, ok := extProp.m[key]; ok { + return prop + } + + prop := new(Properties) + prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) + extProp.m[key] = prop + return prop +} + +// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m. +func encodeExtensionMap(m map[int32]Extension) error { + for k, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + p := NewBuffer(nil) + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + if err := props.enc(p, props, toStructPointer(x)); err != nil { + return err + } + e.enc = p.buf + m[k] = e + } + return nil +} + +func sizeExtensionMap(m map[int32]Extension) (n int) { + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + n += props.size(props, toStructPointer(x)) + } + return +} + +// HasExtension returns whether the given extension is present in pb. +func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { + // TODO: Check types, field numbers, etc.? + _, ok := pb.ExtensionMap()[extension.Field] + return ok +} + +// ClearExtension removes the given extension from pb. +func ClearExtension(pb extendableProto, extension *ExtensionDesc) { + // TODO: Check types, field numbers, etc.? + delete(pb.ExtensionMap(), extension.Field) +} + +// GetExtension parses and returns the given extension of pb. +// If the extension is not present and has no default value it returns ErrMissingExtension. +func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { + if err := checkExtensionTypes(pb, extension); err != nil { + return nil, err + } + + emap := pb.ExtensionMap() + e, ok := emap[extension.Field] + if !ok { + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) + } + + if e.value != nil { + // Already decoded. Check the descriptor, though. + if e.desc != extension { + // This shouldn't happen. If it does, it means that + // GetExtension was called twice with two different + // descriptors with the same field number. + return nil, errors.New("proto: descriptor conflict") + } + return e.value, nil + } + + v, err := decodeExtension(e.enc, extension) + if err != nil { + return nil, err + } + + // Remember the decoded version and drop the encoded version. + // That way it is safe to mutate what we return. + e.value = v + e.desc = extension + e.enc = nil + emap[extension.Field] = e + return e.value, nil +} + +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + +// decodeExtension decodes an extension encoded in b. +func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { + o := NewBuffer(b) + + t := reflect.TypeOf(extension.ExtensionType) + + props := extensionProperties(extension) + + // t is a pointer to a struct, pointer to basic type or a slice. + // Allocate a "field" to store the pointer/slice itself; the + // pointer/slice will be stored here. We pass + // the address of this field to props.dec. + // This passes a zero field and a *t and lets props.dec + // interpret it as a *struct{ x t }. + value := reflect.New(t).Elem() + + for { + // Discard wire type and field number varint. It isn't needed. + if _, err := o.DecodeVarint(); err != nil { + return nil, err + } + + if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil { + return nil, err + } + + if o.index >= len(o.buf) { + break + } + } + return value.Interface(), nil +} + +// GetExtensions returns a slice of the extensions present in pb that are also listed in es. +// The returned slice has the same length as es; missing extensions will appear as nil elements. +func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { + epb, ok := pb.(extendableProto) + if !ok { + err = errors.New("proto: not an extendable proto") + return + } + extensions = make([]interface{}, len(es)) + for i, e := range es { + extensions[i], err = GetExtension(epb, e) + if err == ErrMissingExtension { + err = nil + } + if err != nil { + return + } + } + return +} + +// SetExtension sets the specified extension of pb to the specified value. +func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { + if err := checkExtensionTypes(pb, extension); err != nil { + return err + } + typ := reflect.TypeOf(extension.ExtensionType) + if typ != reflect.TypeOf(value) { + return errors.New("proto: bad extension value type") + } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) + } + + pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} + return nil +} + +// A global registry of extensions. +// The generated code will register the generated descriptors by calling RegisterExtension. + +var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) + +// RegisterExtension is called from the generated code. +func RegisterExtension(desc *ExtensionDesc) { + st := reflect.TypeOf(desc.ExtendedType).Elem() + m := extensionMaps[st] + if m == nil { + m = make(map[int32]*ExtensionDesc) + extensionMaps[st] = m + } + if _, ok := m[desc.Field]; ok { + panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) + } + m[desc.Field] = desc +} + +// RegisteredExtensions returns a map of the registered extensions of a +// protocol buffer struct, indexed by the extension number. +// The argument pb should be a nil pointer to the struct type. +func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { + return extensionMaps[reflect.TypeOf(pb).Elem()] +} diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go new file mode 100644 index 0000000000..0de8f8dffd --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -0,0 +1,894 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* +Package proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Getters are only generated for message and oneof fields. + - Enum types do not get an Enum method. + +The simplest way to describe this is to see an example. +Given file test.proto, containing + + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + oneof union { + int32 number = 6; + string name = 7; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/golang/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err + } + *x = FOO(value) + return nil + } + + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} + + type isTest_Union interface { + isTest_Union() + } + + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } + + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union + } + return nil + } + const Default_Test_Type int32 = 77 + + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" + } + + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type + } + return Default_Test_Type + } + + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil + } + + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } + + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" + } + + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number + } + return 0 + } + + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name + } + return "" + } + + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } + +To create and play with a Test object: + + package main + + import ( + "log" + + "github.com/golang/protobuf/proto" + pb "./example.pb" + ) + + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + Union: &pb.Test_Name{"fred"}, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) + } + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. + } + // etc. + } +*/ +package proto + +import ( + "encoding/json" + "fmt" + "log" + "reflect" + "sort" + "strconv" + "sync" +) + +// Message is implemented by generated protocol buffer messages. +type Message interface { + Reset() + String() string + ProtoMessage() +} + +// Stats records allocation details about the protocol buffer encoders +// and decoders. Useful for tuning the library itself. +type Stats struct { + Emalloc uint64 // mallocs in encode + Dmalloc uint64 // mallocs in decode + Encode uint64 // number of encodes + Decode uint64 // number of decodes + Chit uint64 // number of cache hits + Cmiss uint64 // number of cache misses + Size uint64 // number of sizes +} + +// Set to true to enable stats collection. +const collectStats = false + +var stats Stats + +// GetStats returns a copy of the global Stats structure. +func GetStats() Stats { return stats } + +// A Buffer is a buffer manager for marshaling and unmarshaling +// protocol buffers. It may be reused between invocations to +// reduce memory usage. It is not necessary to use a Buffer; +// the global functions Marshal and Unmarshal create a +// temporary Buffer and are fine for most applications. +type Buffer struct { + buf []byte // encode/decode byte stream + index int // write point + + // pools of basic types to amortize allocation. + bools []bool + uint32s []uint32 + uint64s []uint64 + + // extra pools, only used with pointer_reflect.go + int32s []int32 + int64s []int64 + float32s []float32 + float64s []float64 +} + +// NewBuffer allocates a new Buffer and initializes its internal data to +// the contents of the argument slice. +func NewBuffer(e []byte) *Buffer { + return &Buffer{buf: e} +} + +// Reset resets the Buffer, ready for marshaling a new protocol buffer. +func (p *Buffer) Reset() { + p.buf = p.buf[0:0] // for reading/writing + p.index = 0 // for reading +} + +// SetBuf replaces the internal buffer with the slice, +// ready for unmarshaling the contents of the slice. +func (p *Buffer) SetBuf(s []byte) { + p.buf = s + p.index = 0 +} + +// Bytes returns the contents of the Buffer. +func (p *Buffer) Bytes() []byte { return p.buf } + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + return &v +} + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { + return &v +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int32 { + p := new(int32) + *p = int32(v) + return p +} + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { + return &v +} + +// Float32 is a helper routine that allocates a new float32 value +// to store v and returns a pointer to it. +func Float32(v float32) *float32 { + return &v +} + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { + return &v +} + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { + return &v +} + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { + return &v +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + return &v +} + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// UnmarshalJSONEnum is a helper function to simplify recovering enum int values +// from their JSON-encoded representation. Given a map from the enum's symbolic +// names to its int values, and a byte buffer containing the JSON-encoded +// value, it returns an int32 that can be cast to the enum type by the caller. +// +// The function can deal with both JSON representations, numeric and symbolic. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// DebugPrint dumps the encoded data in b in a debugging format with a header +// including the string s. Used in testing but made available for general debugging. +func (p *Buffer) DebugPrint(s string, b []byte) { + var u uint64 + + obuf := p.buf + index := p.index + p.buf = b + p.index = 0 + depth := 0 + + fmt.Printf("\n--- %s ---\n", s) + +out: + for { + for i := 0; i < depth; i++ { + fmt.Print(" ") + } + + index := p.index + if index == len(p.buf) { + break + } + + op, err := p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: fetching op err %v\n", index, err) + break out + } + tag := op >> 3 + wire := op & 7 + + switch wire { + default: + fmt.Printf("%3d: t=%3d unknown wire=%d\n", + index, tag, wire) + break out + + case WireBytes: + var r []byte + + r, err = p.DecodeRawBytes(false) + if err != nil { + break out + } + fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) + if len(r) <= 6 { + for i := 0; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } else { + for i := 0; i < 3; i++ { + fmt.Printf(" %.2x", r[i]) + } + fmt.Printf(" ..") + for i := len(r) - 3; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } + fmt.Printf("\n") + + case WireFixed32: + u, err = p.DecodeFixed32() + if err != nil { + fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) + + case WireFixed64: + u, err = p.DecodeFixed64() + if err != nil { + fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) + + case WireVarint: + u, err = p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) + + case WireStartGroup: + fmt.Printf("%3d: t=%3d start\n", index, tag) + depth++ + + case WireEndGroup: + depth-- + fmt.Printf("%3d: t=%3d end\n", index, tag) + } + } + + if depth != 0 { + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) + } + fmt.Printf("\n") + + p.buf = obuf + p.index = index +} + +// SetDefaults sets unset protocol buffer fields to their default values. +// It only modifies fields that are both unset and have defined defaults. +// It recursively sets default values in any non-nil sub-messages. +func SetDefaults(pb Message) { + setDefaults(reflect.ValueOf(pb), true, false) +} + +// v is a pointer to a struct. +func setDefaults(v reflect.Value, recur, zeros bool) { + v = v.Elem() + + defaultMu.RLock() + dm, ok := defaults[v.Type()] + defaultMu.RUnlock() + if !ok { + dm = buildDefaultMessage(v.Type()) + defaultMu.Lock() + defaults[v.Type()] = dm + defaultMu.Unlock() + } + + for _, sf := range dm.scalars { + f := v.Field(sf.index) + if !f.IsNil() { + // field already set + continue + } + dv := sf.value + if dv == nil && !zeros { + // no explicit default, and don't want to set zeros + continue + } + fptr := f.Addr().Interface() // **T + // TODO: Consider batching the allocations we do here. + switch sf.kind { + case reflect.Bool: + b := new(bool) + if dv != nil { + *b = dv.(bool) + } + *(fptr.(**bool)) = b + case reflect.Float32: + f := new(float32) + if dv != nil { + *f = dv.(float32) + } + *(fptr.(**float32)) = f + case reflect.Float64: + f := new(float64) + if dv != nil { + *f = dv.(float64) + } + *(fptr.(**float64)) = f + case reflect.Int32: + // might be an enum + if ft := f.Type(); ft != int32PtrType { + // enum + f.Set(reflect.New(ft.Elem())) + if dv != nil { + f.Elem().SetInt(int64(dv.(int32))) + } + } else { + // int32 field + i := new(int32) + if dv != nil { + *i = dv.(int32) + } + *(fptr.(**int32)) = i + } + case reflect.Int64: + i := new(int64) + if dv != nil { + *i = dv.(int64) + } + *(fptr.(**int64)) = i + case reflect.String: + s := new(string) + if dv != nil { + *s = dv.(string) + } + *(fptr.(**string)) = s + case reflect.Uint8: + // exceptional case: []byte + var b []byte + if dv != nil { + db := dv.([]byte) + b = make([]byte, len(db)) + copy(b, db) + } else { + b = []byte{} + } + *(fptr.(*[]byte)) = b + case reflect.Uint32: + u := new(uint32) + if dv != nil { + *u = dv.(uint32) + } + *(fptr.(**uint32)) = u + case reflect.Uint64: + u := new(uint64) + if dv != nil { + *u = dv.(uint64) + } + *(fptr.(**uint64)) = u + default: + log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) + } + } + + for _, ni := range dm.nested { + f := v.Field(ni) + // f is *T or []*T or map[T]*T + switch f.Kind() { + case reflect.Ptr: + if f.IsNil() { + continue + } + setDefaults(f, recur, zeros) + + case reflect.Slice: + for i := 0; i < f.Len(); i++ { + e := f.Index(i) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + } + } +} + +var ( + // defaults maps a protocol buffer struct type to a slice of the fields, + // with its scalar fields set to their proto-declared non-zero default values. + defaultMu sync.RWMutex + defaults = make(map[reflect.Type]defaultMessage) + + int32PtrType = reflect.TypeOf((*int32)(nil)) +) + +// defaultMessage represents information about the default values of a message. +type defaultMessage struct { + scalars []scalarField + nested []int // struct field index of nested messages +} + +type scalarField struct { + index int // struct field index + kind reflect.Kind // element type (the T in *T or []T) + value interface{} // the proto-declared default value, or nil +} + +// t is a struct type. +func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { + sprop := GetProperties(t) + for _, prop := range sprop.Prop { + fi, ok := sprop.decoderTags.get(prop.Tag) + if !ok { + // XXX_unrecognized + continue + } + ft := t.Field(fi).Type + + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: + dm.nested = append(dm.nested, fi) + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) + } + } + + return dm +} + +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field + } + + case reflect.Slice: + switch ft.Elem().Kind() { + case reflect.Ptr: + nestedMessage = true // repeated message + case reflect.Uint8: + canHaveDefault = true // bytes field + } + + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } + } + + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + +// Map fields may have key types of non-float scalars, strings and enums. +// The easiest way to sort them in some deterministic order is to use fmt. +// If this turns out to be inefficient we can always consider other options, +// such as doing a Schwartzian transform. + +func mapKeys(vs []reflect.Value) sort.Interface { + s := mapKeySorter{ + vs: vs, + // default Less function: textual comparison + less: func(a, b reflect.Value) bool { + return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface()) + }, + } + + // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps; + // numeric keys are sorted numerically. + if len(vs) == 0 { + return s + } + switch vs[0].Kind() { + case reflect.Int32, reflect.Int64: + s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } + case reflect.Uint32, reflect.Uint64: + s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } + } + + return s +} + +type mapKeySorter struct { + vs []reflect.Value + less func(a, b reflect.Value) bool +} + +func (s mapKeySorter) Len() int { return len(s.vs) } +func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } +func (s mapKeySorter) Less(i, j int) bool { + return s.less(s.vs[i], s.vs[j]) +} + +// isProto3Zero reports whether v is a zero proto3 value. +func isProto3Zero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return !v.Bool() + case reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint32, reflect.Uint64: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.String: + return v.String() == "" + } + return false +} + +// ProtoPackageIsVersion1 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const ProtoPackageIsVersion1 = true diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go new file mode 100644 index 0000000000..e25e01e637 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/message_set.go @@ -0,0 +1,280 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Support for message sets. + */ + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "reflect" + "sort" +) + +// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. +// A message type ID is required for storing a protocol buffer in a message set. +var errNoMessageTypeID = errors.New("proto does not have a message type ID") + +// The first two types (_MessageSet_Item and messageSet) +// model what the protocol compiler produces for the following protocol message: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } +// That is the MessageSet wire format. We can't use a proto to generate these +// because that would introduce a circular dependency between it and this package. + +type _MessageSet_Item struct { + TypeId *int32 `protobuf:"varint,2,req,name=type_id"` + Message []byte `protobuf:"bytes,3,req,name=message"` +} + +type messageSet struct { + Item []*_MessageSet_Item `protobuf:"group,1,rep"` + XXX_unrecognized []byte + // TODO: caching? +} + +// Make sure messageSet is a Message. +var _ Message = (*messageSet)(nil) + +// messageTypeIder is an interface satisfied by a protocol buffer type +// that may be stored in a MessageSet. +type messageTypeIder interface { + MessageTypeId() int32 +} + +func (ms *messageSet) find(pb Message) *_MessageSet_Item { + mti, ok := pb.(messageTypeIder) + if !ok { + return nil + } + id := mti.MessageTypeId() + for _, item := range ms.Item { + if *item.TypeId == id { + return item + } + } + return nil +} + +func (ms *messageSet) Has(pb Message) bool { + if ms.find(pb) != nil { + return true + } + return false +} + +func (ms *messageSet) Unmarshal(pb Message) error { + if item := ms.find(pb); item != nil { + return Unmarshal(item.Message, pb) + } + if _, ok := pb.(messageTypeIder); !ok { + return errNoMessageTypeID + } + return nil // TODO: return error instead? +} + +func (ms *messageSet) Marshal(pb Message) error { + msg, err := Marshal(pb) + if err != nil { + return err + } + if item := ms.find(pb); item != nil { + // reuse existing item + item.Message = msg + return nil + } + + mti, ok := pb.(messageTypeIder) + if !ok { + return errNoMessageTypeID + } + + mtid := mti.MessageTypeId() + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: &mtid, + Message: msg, + }) + return nil +} + +func (ms *messageSet) Reset() { *ms = messageSet{} } +func (ms *messageSet) String() string { return CompactTextString(ms) } +func (*messageSet) ProtoMessage() {} + +// Support for the message_set_wire_format message option. + +func skipVarint(buf []byte) []byte { + i := 0 + for ; buf[i]&0x80 != 0; i++ { + } + return buf[i+1:] +} + +// MarshalMessageSet encodes the extension map represented by m in the message set wire format. +// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { + if err := encodeExtensionMap(m); err != nil { + return nil, err + } + + // Sort extension IDs to provide a deterministic encoding. + // See also enc_map in encode.go. + ids := make([]int, 0, len(m)) + for id := range m { + ids = append(ids, int(id)) + } + sort.Ints(ids) + + ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))} + for _, id := range ids { + e := m[int32(id)] + // Remove the wire type and field number varint, as well as the length varint. + msg := skipVarint(skipVarint(e.enc)) + + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: Int32(int32(id)), + Message: msg, + }) + } + return Marshal(ms) +} + +// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { + ms := new(messageSet) + if err := Unmarshal(buf, ms); err != nil { + return err + } + for _, item := range ms.Item { + id := *item.TypeId + msg := item.Message + + // Restore wire type and field number varint, plus length varint. + // Be careful to preserve duplicate items. + b := EncodeVarint(uint64(id)<<3 | WireBytes) + if ext, ok := m[id]; ok { + // Existing data; rip off the tag and length varint + // so we join the new data correctly. + // We can assume that ext.enc is set because we are unmarshaling. + o := ext.enc[len(b):] // skip wire type and field number + _, n := DecodeVarint(o) // calculate length of length varint + o = o[n:] // skip length varint + msg = append(o, msg...) // join old data and new data + } + b = append(b, EncodeVarint(uint64(len(msg)))...) + b = append(b, msg...) + + m[id] = Extension{enc: b} + } + return nil +} + +// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. +// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) { + var b bytes.Buffer + b.WriteByte('{') + + // Process the map in key order for deterministic output. + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) // int32Slice defined in text.go + + for i, id := range ids { + ext := m[id] + if i > 0 { + b.WriteByte(',') + } + + msd, ok := messageSetMap[id] + if !ok { + // Unknown type; we can't render it, so skip it. + continue + } + fmt.Fprintf(&b, `"[%s]":`, msd.name) + + x := ext.value + if x == nil { + x = reflect.New(msd.t.Elem()).Interface() + if err := Unmarshal(ext.enc, x.(Message)); err != nil { + return nil, err + } + } + d, err := json.Marshal(x) + if err != nil { + return nil, err + } + b.Write(d) + } + b.WriteByte('}') + return b.Bytes(), nil +} + +// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. +// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error { + // Common-case fast path. + if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { + return nil + } + + // This is fairly tricky, and it's not clear that it is needed. + return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") +} + +// A global registry of types that can be used in a MessageSet. + +var messageSetMap = make(map[int32]messageSetDesc) + +type messageSetDesc struct { + t reflect.Type // pointer to struct + name string +} + +// RegisterMessageSetType is called from the generated code. +func RegisterMessageSetType(m Message, fieldNum int32, name string) { + messageSetMap[fieldNum] = messageSetDesc{ + t: reflect.TypeOf(m), + name: name, + } +} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go new file mode 100644 index 0000000000..749919d250 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go @@ -0,0 +1,479 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +build appengine + +// This file contains an implementation of proto field accesses using package reflect. +// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can +// be used on App Engine. + +package proto + +import ( + "math" + "reflect" +) + +// A structPointer is a pointer to a struct. +type structPointer struct { + v reflect.Value +} + +// toStructPointer returns a structPointer equivalent to the given reflect value. +// The reflect value must itself be a pointer to a struct. +func toStructPointer(v reflect.Value) structPointer { + return structPointer{v} +} + +// IsNil reports whether p is nil. +func structPointer_IsNil(p structPointer) bool { + return p.v.IsNil() +} + +// Interface returns the struct pointer as an interface value. +func structPointer_Interface(p structPointer, _ reflect.Type) interface{} { + return p.v.Interface() +} + +// A field identifies a field in a struct, accessible from a structPointer. +// In this implementation, a field is identified by the sequence of field indices +// passed to reflect's FieldByIndex. +type field []int + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return f.Index +} + +// invalidField is an invalid field identifier. +var invalidField = field(nil) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { return f != nil } + +// field returns the given field in the struct as a reflect value. +func structPointer_field(p structPointer, f field) reflect.Value { + // Special case: an extension map entry with a value of type T + // passes a *T to the struct-handling code with a zero field, + // expecting that it will be treated as equivalent to *struct{ X T }, + // which has the same memory layout. We have to handle that case + // specially, because reflect will panic if we call FieldByIndex on a + // non-struct. + if f == nil { + return p.v.Elem() + } + + return p.v.Elem().FieldByIndex(f) +} + +// ifield returns the given field in the struct as an interface value. +func structPointer_ifield(p structPointer, f field) interface{} { + return structPointer_field(p, f).Addr().Interface() +} + +// Bytes returns the address of a []byte field in the struct. +func structPointer_Bytes(p structPointer, f field) *[]byte { + return structPointer_ifield(p, f).(*[]byte) +} + +// BytesSlice returns the address of a [][]byte field in the struct. +func structPointer_BytesSlice(p structPointer, f field) *[][]byte { + return structPointer_ifield(p, f).(*[][]byte) +} + +// Bool returns the address of a *bool field in the struct. +func structPointer_Bool(p structPointer, f field) **bool { + return structPointer_ifield(p, f).(**bool) +} + +// BoolVal returns the address of a bool field in the struct. +func structPointer_BoolVal(p structPointer, f field) *bool { + return structPointer_ifield(p, f).(*bool) +} + +// BoolSlice returns the address of a []bool field in the struct. +func structPointer_BoolSlice(p structPointer, f field) *[]bool { + return structPointer_ifield(p, f).(*[]bool) +} + +// String returns the address of a *string field in the struct. +func structPointer_String(p structPointer, f field) **string { + return structPointer_ifield(p, f).(**string) +} + +// StringVal returns the address of a string field in the struct. +func structPointer_StringVal(p structPointer, f field) *string { + return structPointer_ifield(p, f).(*string) +} + +// StringSlice returns the address of a []string field in the struct. +func structPointer_StringSlice(p structPointer, f field) *[]string { + return structPointer_ifield(p, f).(*[]string) +} + +// ExtMap returns the address of an extension map field in the struct. +func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { + return structPointer_ifield(p, f).(*map[int32]Extension) +} + +// NewAt returns the reflect.Value for a pointer to a field in the struct. +func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { + return structPointer_field(p, f).Addr() +} + +// SetStructPointer writes a *struct field in the struct. +func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { + structPointer_field(p, f).Set(q.v) +} + +// GetStructPointer reads a *struct field in the struct. +func structPointer_GetStructPointer(p structPointer, f field) structPointer { + return structPointer{structPointer_field(p, f)} +} + +// StructPointerSlice the address of a []*struct field in the struct. +func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { + return structPointerSlice{structPointer_field(p, f)} +} + +// A structPointerSlice represents the address of a slice of pointers to structs +// (themselves messages or groups). That is, v.Type() is *[]*struct{...}. +type structPointerSlice struct { + v reflect.Value +} + +func (p structPointerSlice) Len() int { return p.v.Len() } +func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } +func (p structPointerSlice) Append(q structPointer) { + p.v.Set(reflect.Append(p.v, q.v)) +} + +var ( + int32Type = reflect.TypeOf(int32(0)) + uint32Type = reflect.TypeOf(uint32(0)) + float32Type = reflect.TypeOf(float32(0)) + int64Type = reflect.TypeOf(int64(0)) + uint64Type = reflect.TypeOf(uint64(0)) + float64Type = reflect.TypeOf(float64(0)) +) + +// A word32 represents a field of type *int32, *uint32, *float32, or *enum. +// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable. +type word32 struct { + v reflect.Value +} + +// IsNil reports whether p is nil. +func word32_IsNil(p word32) bool { + return p.v.IsNil() +} + +// Set sets p to point at a newly allocated word with bits set to x. +func word32_Set(p word32, o *Buffer, x uint32) { + t := p.v.Type().Elem() + switch t { + case int32Type: + if len(o.int32s) == 0 { + o.int32s = make([]int32, uint32PoolSize) + } + o.int32s[0] = int32(x) + p.v.Set(reflect.ValueOf(&o.int32s[0])) + o.int32s = o.int32s[1:] + return + case uint32Type: + if len(o.uint32s) == 0 { + o.uint32s = make([]uint32, uint32PoolSize) + } + o.uint32s[0] = x + p.v.Set(reflect.ValueOf(&o.uint32s[0])) + o.uint32s = o.uint32s[1:] + return + case float32Type: + if len(o.float32s) == 0 { + o.float32s = make([]float32, uint32PoolSize) + } + o.float32s[0] = math.Float32frombits(x) + p.v.Set(reflect.ValueOf(&o.float32s[0])) + o.float32s = o.float32s[1:] + return + } + + // must be enum + p.v.Set(reflect.New(t)) + p.v.Elem().SetInt(int64(int32(x))) +} + +// Get gets the bits pointed at by p, as a uint32. +func word32_Get(p word32) uint32 { + elem := p.v.Elem() + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32(p structPointer, f field) word32 { + return word32{structPointer_field(p, f)} +} + +// A word32Val represents a field of type int32, uint32, float32, or enum. +// That is, v.Type() is int32, uint32, float32, or enum and v is assignable. +type word32Val struct { + v reflect.Value +} + +// Set sets *p to x. +func word32Val_Set(p word32Val, x uint32) { + switch p.v.Type() { + case int32Type: + p.v.SetInt(int64(x)) + return + case uint32Type: + p.v.SetUint(uint64(x)) + return + case float32Type: + p.v.SetFloat(float64(math.Float32frombits(x))) + return + } + + // must be enum + p.v.SetInt(int64(int32(x))) +} + +// Get gets the bits pointed at by p, as a uint32. +func word32Val_Get(p word32Val) uint32 { + elem := p.v + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. +func structPointer_Word32Val(p structPointer, f field) word32Val { + return word32Val{structPointer_field(p, f)} +} + +// A word32Slice is a slice of 32-bit values. +// That is, v.Type() is []int32, []uint32, []float32, or []enum. +type word32Slice struct { + v reflect.Value +} + +func (p word32Slice) Append(x uint32) { + n, m := p.v.Len(), p.v.Cap() + if n < m { + p.v.SetLen(n + 1) + } else { + t := p.v.Type().Elem() + p.v.Set(reflect.Append(p.v, reflect.Zero(t))) + } + elem := p.v.Index(n) + switch elem.Kind() { + case reflect.Int32: + elem.SetInt(int64(int32(x))) + case reflect.Uint32: + elem.SetUint(uint64(x)) + case reflect.Float32: + elem.SetFloat(float64(math.Float32frombits(x))) + } +} + +func (p word32Slice) Len() int { + return p.v.Len() +} + +func (p word32Slice) Index(i int) uint32 { + elem := p.v.Index(i) + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct. +func structPointer_Word32Slice(p structPointer, f field) word32Slice { + return word32Slice{structPointer_field(p, f)} +} + +// word64 is like word32 but for 64-bit values. +type word64 struct { + v reflect.Value +} + +func word64_Set(p word64, o *Buffer, x uint64) { + t := p.v.Type().Elem() + switch t { + case int64Type: + if len(o.int64s) == 0 { + o.int64s = make([]int64, uint64PoolSize) + } + o.int64s[0] = int64(x) + p.v.Set(reflect.ValueOf(&o.int64s[0])) + o.int64s = o.int64s[1:] + return + case uint64Type: + if len(o.uint64s) == 0 { + o.uint64s = make([]uint64, uint64PoolSize) + } + o.uint64s[0] = x + p.v.Set(reflect.ValueOf(&o.uint64s[0])) + o.uint64s = o.uint64s[1:] + return + case float64Type: + if len(o.float64s) == 0 { + o.float64s = make([]float64, uint64PoolSize) + } + o.float64s[0] = math.Float64frombits(x) + p.v.Set(reflect.ValueOf(&o.float64s[0])) + o.float64s = o.float64s[1:] + return + } + panic("unreachable") +} + +func word64_IsNil(p word64) bool { + return p.v.IsNil() +} + +func word64_Get(p word64) uint64 { + elem := p.v.Elem() + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return elem.Uint() + case reflect.Float64: + return math.Float64bits(elem.Float()) + } + panic("unreachable") +} + +func structPointer_Word64(p structPointer, f field) word64 { + return word64{structPointer_field(p, f)} +} + +// word64Val is like word32Val but for 64-bit values. +type word64Val struct { + v reflect.Value +} + +func word64Val_Set(p word64Val, o *Buffer, x uint64) { + switch p.v.Type() { + case int64Type: + p.v.SetInt(int64(x)) + return + case uint64Type: + p.v.SetUint(x) + return + case float64Type: + p.v.SetFloat(math.Float64frombits(x)) + return + } + panic("unreachable") +} + +func word64Val_Get(p word64Val) uint64 { + elem := p.v + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return elem.Uint() + case reflect.Float64: + return math.Float64bits(elem.Float()) + } + panic("unreachable") +} + +func structPointer_Word64Val(p structPointer, f field) word64Val { + return word64Val{structPointer_field(p, f)} +} + +type word64Slice struct { + v reflect.Value +} + +func (p word64Slice) Append(x uint64) { + n, m := p.v.Len(), p.v.Cap() + if n < m { + p.v.SetLen(n + 1) + } else { + t := p.v.Type().Elem() + p.v.Set(reflect.Append(p.v, reflect.Zero(t))) + } + elem := p.v.Index(n) + switch elem.Kind() { + case reflect.Int64: + elem.SetInt(int64(int64(x))) + case reflect.Uint64: + elem.SetUint(uint64(x)) + case reflect.Float64: + elem.SetFloat(float64(math.Float64frombits(x))) + } +} + +func (p word64Slice) Len() int { + return p.v.Len() +} + +func (p word64Slice) Index(i int) uint64 { + elem := p.v.Index(i) + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return uint64(elem.Uint()) + case reflect.Float64: + return math.Float64bits(float64(elem.Float())) + } + panic("unreachable") +} + +func structPointer_Word64Slice(p structPointer, f field) word64Slice { + return word64Slice{structPointer_field(p, f)} +} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go new file mode 100644 index 0000000000..e9be0fe92e --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -0,0 +1,266 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +build !appengine + +// This file contains the implementation of the proto field accesses using package unsafe. + +package proto + +import ( + "reflect" + "unsafe" +) + +// NOTE: These type_Foo functions would more idiomatically be methods, +// but Go does not allow methods on pointer types, and we must preserve +// some pointer type for the garbage collector. We use these +// funcs with clunky names as our poor approximation to methods. +// +// An alternative would be +// type structPointer struct { p unsafe.Pointer } +// but that does not registerize as well. + +// A structPointer is a pointer to a struct. +type structPointer unsafe.Pointer + +// toStructPointer returns a structPointer equivalent to the given reflect value. +func toStructPointer(v reflect.Value) structPointer { + return structPointer(unsafe.Pointer(v.Pointer())) +} + +// IsNil reports whether p is nil. +func structPointer_IsNil(p structPointer) bool { + return p == nil +} + +// Interface returns the struct pointer, assumed to have element type t, +// as an interface value. +func structPointer_Interface(p structPointer, t reflect.Type) interface{} { + return reflect.NewAt(t, unsafe.Pointer(p)).Interface() +} + +// A field identifies a field in a struct, accessible from a structPointer. +// In this implementation, a field is identified by its byte offset from the start of the struct. +type field uintptr + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return field(f.Offset) +} + +// invalidField is an invalid field identifier. +const invalidField = ^field(0) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { + return f != ^field(0) +} + +// Bytes returns the address of a []byte field in the struct. +func structPointer_Bytes(p structPointer, f field) *[]byte { + return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// BytesSlice returns the address of a [][]byte field in the struct. +func structPointer_BytesSlice(p structPointer, f field) *[][]byte { + return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// Bool returns the address of a *bool field in the struct. +func structPointer_Bool(p structPointer, f field) **bool { + return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// BoolVal returns the address of a bool field in the struct. +func structPointer_BoolVal(p structPointer, f field) *bool { + return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// BoolSlice returns the address of a []bool field in the struct. +func structPointer_BoolSlice(p structPointer, f field) *[]bool { + return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// String returns the address of a *string field in the struct. +func structPointer_String(p structPointer, f field) **string { + return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// StringVal returns the address of a string field in the struct. +func structPointer_StringVal(p structPointer, f field) *string { + return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// StringSlice returns the address of a []string field in the struct. +func structPointer_StringSlice(p structPointer, f field) *[]string { + return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// ExtMap returns the address of an extension map field in the struct. +func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { + return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// NewAt returns the reflect.Value for a pointer to a field in the struct. +func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { + return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) +} + +// SetStructPointer writes a *struct field in the struct. +func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { + *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q +} + +// GetStructPointer reads a *struct field in the struct. +func structPointer_GetStructPointer(p structPointer, f field) structPointer { + return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// StructPointerSlice the address of a []*struct field in the struct. +func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice { + return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups). +type structPointerSlice []structPointer + +func (v *structPointerSlice) Len() int { return len(*v) } +func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] } +func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) } + +// A word32 is the address of a "pointer to 32-bit value" field. +type word32 **uint32 + +// IsNil reports whether *v is nil. +func word32_IsNil(p word32) bool { + return *p == nil +} + +// Set sets *v to point at a newly allocated word set to x. +func word32_Set(p word32, o *Buffer, x uint32) { + if len(o.uint32s) == 0 { + o.uint32s = make([]uint32, uint32PoolSize) + } + o.uint32s[0] = x + *p = &o.uint32s[0] + o.uint32s = o.uint32s[1:] +} + +// Get gets the value pointed at by *v. +func word32_Get(p word32) uint32 { + return **p +} + +// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32(p structPointer, f field) word32 { + return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// A word32Val is the address of a 32-bit value field. +type word32Val *uint32 + +// Set sets *p to x. +func word32Val_Set(p word32Val, x uint32) { + *p = x +} + +// Get gets the value pointed at by p. +func word32Val_Get(p word32Val) uint32 { + return *p +} + +// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32Val(p structPointer, f field) word32Val { + return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// A word32Slice is a slice of 32-bit values. +type word32Slice []uint32 + +func (v *word32Slice) Append(x uint32) { *v = append(*v, x) } +func (v *word32Slice) Len() int { return len(*v) } +func (v *word32Slice) Index(i int) uint32 { return (*v)[i] } + +// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct. +func structPointer_Word32Slice(p structPointer, f field) *word32Slice { + return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// word64 is like word32 but for 64-bit values. +type word64 **uint64 + +func word64_Set(p word64, o *Buffer, x uint64) { + if len(o.uint64s) == 0 { + o.uint64s = make([]uint64, uint64PoolSize) + } + o.uint64s[0] = x + *p = &o.uint64s[0] + o.uint64s = o.uint64s[1:] +} + +func word64_IsNil(p word64) bool { + return *p == nil +} + +func word64_Get(p word64) uint64 { + return **p +} + +func structPointer_Word64(p structPointer, f field) word64 { + return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// word64Val is like word32Val but for 64-bit values. +type word64Val *uint64 + +func word64Val_Set(p word64Val, o *Buffer, x uint64) { + *p = x +} + +func word64Val_Get(p word64Val) uint64 { + return *p +} + +func structPointer_Word64Val(p structPointer, f field) word64Val { + return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// word64Slice is like word32Slice but for 64-bit values. +type word64Slice []uint64 + +func (v *word64Slice) Append(x uint64) { *v = append(*v, x) } +func (v *word64Slice) Len() int { return len(*v) } +func (v *word64Slice) Index(i int) uint64 { return (*v)[i] } + +func structPointer_Word64Slice(p structPointer, f field) *word64Slice { + return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go new file mode 100644 index 0000000000..4fe2ec22e8 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -0,0 +1,846 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "fmt" + "log" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" +) + +const debug bool = false + +// Constants that identify the encoding of a value on the wire. +const ( + WireVarint = 0 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 + WireFixed32 = 5 +) + +const startSize = 10 // initial slice/string sizes + +// Encoders are defined in encode.go +// An encoder outputs the full representation of a field, including its +// tag and encoder type. +type encoder func(p *Buffer, prop *Properties, base structPointer) error + +// A valueEncoder encodes a single integer in a particular encoding. +type valueEncoder func(o *Buffer, x uint64) error + +// Sizers are defined in encode.go +// A sizer returns the encoded size of a field, including its tag and encoder +// type. +type sizer func(prop *Properties, base structPointer) int + +// A valueSizer returns the encoded size of a single integer in a particular +// encoding. +type valueSizer func(x uint64) int + +// Decoders are defined in decode.go +// A decoder creates a value from its wire representation. +// Unrecognized subelements are saved in unrec. +type decoder func(p *Buffer, prop *Properties, base structPointer) error + +// A valueDecoder decodes a single integer in a particular encoding. +type valueDecoder func(o *Buffer) (x uint64, err error) + +// A oneofMarshaler does the marshaling for all oneof fields in a message. +type oneofMarshaler func(Message, *Buffer) error + +// A oneofUnmarshaler does the unmarshaling for a oneof field in a message. +type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) + +// A oneofSizer does the sizing for all oneof fields in a message. +type oneofSizer func(Message) int + +// tagMap is an optimization over map[int]int for typical protocol buffer +// use-cases. Encoded protocol buffers are often in tag order with small tag +// numbers. +type tagMap struct { + fastTags []int + slowTags map[int]int +} + +// tagMapFastLimit is the upper bound on the tag number that will be stored in +// the tagMap slice rather than its map. +const tagMapFastLimit = 1024 + +func (p *tagMap) get(t int) (int, bool) { + if t > 0 && t < tagMapFastLimit { + if t >= len(p.fastTags) { + return 0, false + } + fi := p.fastTags[t] + return fi, fi >= 0 + } + fi, ok := p.slowTags[t] + return fi, ok +} + +func (p *tagMap) put(t int, fi int) { + if t > 0 && t < tagMapFastLimit { + for len(p.fastTags) < t+1 { + p.fastTags = append(p.fastTags, -1) + } + p.fastTags[t] = fi + return + } + if p.slowTags == nil { + p.slowTags = make(map[int]int) + } + p.slowTags[t] = fi +} + +// StructProperties represents properties for all the fields of a struct. +// decoderTags and decoderOrigNames should only be used by the decoder. +type StructProperties struct { + Prop []*Properties // properties for each field + reqCount int // required count + decoderTags tagMap // map from proto tag to struct field number + decoderOrigNames map[string]int // map from original name to struct field number + order []int // list of struct field numbers in tag order + unrecField field // field id of the XXX_unrecognized []byte field + extendable bool // is this an extendable proto + + oneofMarshaler oneofMarshaler + oneofUnmarshaler oneofUnmarshaler + oneofSizer oneofSizer + stype reflect.Type + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties +} + +// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. +// See encode.go, (*Buffer).enc_struct. + +func (sp *StructProperties) Len() int { return len(sp.order) } +func (sp *StructProperties) Less(i, j int) bool { + return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag +} +func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } + +// Properties represents the protocol-specific behavior of a single struct field. +type Properties struct { + Name string // name of the field, for error messages + OrigName string // original name before protocol compiler (always set) + JSONName string // name to use for JSON; determined by protoc + Wire string + WireType int + Tag int + Required bool + Optional bool + Repeated bool + Packed bool // relevant for repeated primitives only + Enum string // set for enum types only + proto3 bool // whether this is known to be a proto3 field; set for []byte only + oneof bool // whether this is a oneof field + + Default string // default value + HasDefault bool // whether an explicit default was provided + def_uint64 uint64 + + enc encoder + valEnc valueEncoder // set for bool and numeric types only + field field + tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType) + tagbuf [8]byte + stype reflect.Type // set for struct types only + sprop *StructProperties // set for struct types only + isMarshaler bool + isUnmarshaler bool + + mtype reflect.Type // set for map types only + mkeyprop *Properties // set for map types only + mvalprop *Properties // set for map types only + + size sizer + valSize valueSizer // set for bool and numeric types only + + dec decoder + valDec valueDecoder // set for bool and numeric types only + + // If this is a packable field, this will be the decoder for the packed version of the field. + packedDec decoder +} + +// String formats the properties in the protobuf struct field tag style. +func (p *Properties) String() string { + s := p.Wire + s = "," + s += strconv.Itoa(p.Tag) + if p.Required { + s += ",req" + } + if p.Optional { + s += ",opt" + } + if p.Repeated { + s += ",rep" + } + if p.Packed { + s += ",packed" + } + s += ",name=" + p.OrigName + if p.JSONName != p.OrigName { + s += ",json=" + p.JSONName + } + if p.proto3 { + s += ",proto3" + } + if p.oneof { + s += ",oneof" + } + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if p.HasDefault { + s += ",def=" + p.Default + } + return s +} + +// Parse populates p by parsing a string in the protobuf struct field tag style. +func (p *Properties) Parse(s string) { + // "bytes,49,opt,name=foo,def=hello!" + fields := strings.Split(s, ",") // breaks def=, but handled below. + if len(fields) < 2 { + fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) + return + } + + p.Wire = fields[0] + switch p.Wire { + case "varint": + p.WireType = WireVarint + p.valEnc = (*Buffer).EncodeVarint + p.valDec = (*Buffer).DecodeVarint + p.valSize = sizeVarint + case "fixed32": + p.WireType = WireFixed32 + p.valEnc = (*Buffer).EncodeFixed32 + p.valDec = (*Buffer).DecodeFixed32 + p.valSize = sizeFixed32 + case "fixed64": + p.WireType = WireFixed64 + p.valEnc = (*Buffer).EncodeFixed64 + p.valDec = (*Buffer).DecodeFixed64 + p.valSize = sizeFixed64 + case "zigzag32": + p.WireType = WireVarint + p.valEnc = (*Buffer).EncodeZigzag32 + p.valDec = (*Buffer).DecodeZigzag32 + p.valSize = sizeZigzag32 + case "zigzag64": + p.WireType = WireVarint + p.valEnc = (*Buffer).EncodeZigzag64 + p.valDec = (*Buffer).DecodeZigzag64 + p.valSize = sizeZigzag64 + case "bytes", "group": + p.WireType = WireBytes + // no numeric converter for non-numeric types + default: + fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) + return + } + + var err error + p.Tag, err = strconv.Atoi(fields[1]) + if err != nil { + return + } + + for i := 2; i < len(fields); i++ { + f := fields[i] + switch { + case f == "req": + p.Required = true + case f == "opt": + p.Optional = true + case f == "rep": + p.Repeated = true + case f == "packed": + p.Packed = true + case strings.HasPrefix(f, "name="): + p.OrigName = f[5:] + case strings.HasPrefix(f, "json="): + p.JSONName = f[5:] + case strings.HasPrefix(f, "enum="): + p.Enum = f[5:] + case f == "proto3": + p.proto3 = true + case f == "oneof": + p.oneof = true + case strings.HasPrefix(f, "def="): + p.HasDefault = true + p.Default = f[4:] // rest of string + if i+1 < len(fields) { + // Commas aren't escaped, and def is always last. + p.Default += "," + strings.Join(fields[i+1:], ",") + break + } + } + } +} + +func logNoSliceEnc(t1, t2 reflect.Type) { + fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2) +} + +var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() + +// Initialize the fields for encoding and decoding. +func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { + p.enc = nil + p.dec = nil + p.size = nil + + switch t1 := typ; t1.Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) + + // proto3 scalar types + + case reflect.Bool: + p.enc = (*Buffer).enc_proto3_bool + p.dec = (*Buffer).dec_proto3_bool + p.size = size_proto3_bool + case reflect.Int32: + p.enc = (*Buffer).enc_proto3_int32 + p.dec = (*Buffer).dec_proto3_int32 + p.size = size_proto3_int32 + case reflect.Uint32: + p.enc = (*Buffer).enc_proto3_uint32 + p.dec = (*Buffer).dec_proto3_int32 // can reuse + p.size = size_proto3_uint32 + case reflect.Int64, reflect.Uint64: + p.enc = (*Buffer).enc_proto3_int64 + p.dec = (*Buffer).dec_proto3_int64 + p.size = size_proto3_int64 + case reflect.Float32: + p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits + p.dec = (*Buffer).dec_proto3_int32 + p.size = size_proto3_uint32 + case reflect.Float64: + p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits + p.dec = (*Buffer).dec_proto3_int64 + p.size = size_proto3_int64 + case reflect.String: + p.enc = (*Buffer).enc_proto3_string + p.dec = (*Buffer).dec_proto3_string + p.size = size_proto3_string + + case reflect.Ptr: + switch t2 := t1.Elem(); t2.Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2) + break + case reflect.Bool: + p.enc = (*Buffer).enc_bool + p.dec = (*Buffer).dec_bool + p.size = size_bool + case reflect.Int32: + p.enc = (*Buffer).enc_int32 + p.dec = (*Buffer).dec_int32 + p.size = size_int32 + case reflect.Uint32: + p.enc = (*Buffer).enc_uint32 + p.dec = (*Buffer).dec_int32 // can reuse + p.size = size_uint32 + case reflect.Int64, reflect.Uint64: + p.enc = (*Buffer).enc_int64 + p.dec = (*Buffer).dec_int64 + p.size = size_int64 + case reflect.Float32: + p.enc = (*Buffer).enc_uint32 // can just treat them as bits + p.dec = (*Buffer).dec_int32 + p.size = size_uint32 + case reflect.Float64: + p.enc = (*Buffer).enc_int64 // can just treat them as bits + p.dec = (*Buffer).dec_int64 + p.size = size_int64 + case reflect.String: + p.enc = (*Buffer).enc_string + p.dec = (*Buffer).dec_string + p.size = size_string + case reflect.Struct: + p.stype = t1.Elem() + p.isMarshaler = isMarshaler(t1) + p.isUnmarshaler = isUnmarshaler(t1) + if p.Wire == "bytes" { + p.enc = (*Buffer).enc_struct_message + p.dec = (*Buffer).dec_struct_message + p.size = size_struct_message + } else { + p.enc = (*Buffer).enc_struct_group + p.dec = (*Buffer).dec_struct_group + p.size = size_struct_group + } + } + + case reflect.Slice: + switch t2 := t1.Elem(); t2.Kind() { + default: + logNoSliceEnc(t1, t2) + break + case reflect.Bool: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_bool + p.size = size_slice_packed_bool + } else { + p.enc = (*Buffer).enc_slice_bool + p.size = size_slice_bool + } + p.dec = (*Buffer).dec_slice_bool + p.packedDec = (*Buffer).dec_slice_packed_bool + case reflect.Int32: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int32 + p.size = size_slice_packed_int32 + } else { + p.enc = (*Buffer).enc_slice_int32 + p.size = size_slice_int32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case reflect.Uint32: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_uint32 + p.size = size_slice_packed_uint32 + } else { + p.enc = (*Buffer).enc_slice_uint32 + p.size = size_slice_uint32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case reflect.Int64, reflect.Uint64: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int64 + p.size = size_slice_packed_int64 + } else { + p.enc = (*Buffer).enc_slice_int64 + p.size = size_slice_int64 + } + p.dec = (*Buffer).dec_slice_int64 + p.packedDec = (*Buffer).dec_slice_packed_int64 + case reflect.Uint8: + p.enc = (*Buffer).enc_slice_byte + p.dec = (*Buffer).dec_slice_byte + p.size = size_slice_byte + // This is a []byte, which is either a bytes field, + // or the value of a map field. In the latter case, + // we always encode an empty []byte, so we should not + // use the proto3 enc/size funcs. + // f == nil iff this is the key/value of a map field. + if p.proto3 && f != nil { + p.enc = (*Buffer).enc_proto3_slice_byte + p.size = size_proto3_slice_byte + } + case reflect.Float32, reflect.Float64: + switch t2.Bits() { + case 32: + // can just treat them as bits + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_uint32 + p.size = size_slice_packed_uint32 + } else { + p.enc = (*Buffer).enc_slice_uint32 + p.size = size_slice_uint32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case 64: + // can just treat them as bits + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int64 + p.size = size_slice_packed_int64 + } else { + p.enc = (*Buffer).enc_slice_int64 + p.size = size_slice_int64 + } + p.dec = (*Buffer).dec_slice_int64 + p.packedDec = (*Buffer).dec_slice_packed_int64 + default: + logNoSliceEnc(t1, t2) + break + } + case reflect.String: + p.enc = (*Buffer).enc_slice_string + p.dec = (*Buffer).dec_slice_string + p.size = size_slice_string + case reflect.Ptr: + switch t3 := t2.Elem(); t3.Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3) + break + case reflect.Struct: + p.stype = t2.Elem() + p.isMarshaler = isMarshaler(t2) + p.isUnmarshaler = isUnmarshaler(t2) + if p.Wire == "bytes" { + p.enc = (*Buffer).enc_slice_struct_message + p.dec = (*Buffer).dec_slice_struct_message + p.size = size_slice_struct_message + } else { + p.enc = (*Buffer).enc_slice_struct_group + p.dec = (*Buffer).dec_slice_struct_group + p.size = size_slice_struct_group + } + } + case reflect.Slice: + switch t2.Elem().Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem()) + break + case reflect.Uint8: + p.enc = (*Buffer).enc_slice_slice_byte + p.dec = (*Buffer).dec_slice_slice_byte + p.size = size_slice_slice_byte + } + } + + case reflect.Map: + p.enc = (*Buffer).enc_new_map + p.dec = (*Buffer).dec_new_map + p.size = size_new_map + + p.mtype = t1 + p.mkeyprop = &Properties{} + p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.mvalprop = &Properties{} + vtype := p.mtype.Elem() + if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { + // The value type is not a message (*T) or bytes ([]byte), + // so we need encoders for the pointer to this type. + vtype = reflect.PtrTo(vtype) + } + p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) + } + + // precalculate tag code + wire := p.WireType + if p.Packed { + wire = WireBytes + } + x := uint32(p.Tag)<<3 | uint32(wire) + i := 0 + for i = 0; x > 127; i++ { + p.tagbuf[i] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + p.tagbuf[i] = uint8(x) + p.tagcode = p.tagbuf[0 : i+1] + + if p.stype != nil { + if lockGetProp { + p.sprop = GetProperties(p.stype) + } else { + p.sprop = getPropertiesLocked(p.stype) + } + } +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() +) + +// isMarshaler reports whether type t implements Marshaler. +func isMarshaler(t reflect.Type) bool { + // We're checking for (likely) pointer-receiver methods + // so if t is not a pointer, something is very wrong. + // The calls above only invoke isMarshaler on pointer types. + if t.Kind() != reflect.Ptr { + panic("proto: misuse of isMarshaler") + } + return t.Implements(marshalerType) +} + +// isUnmarshaler reports whether type t implements Unmarshaler. +func isUnmarshaler(t reflect.Type) bool { + // We're checking for (likely) pointer-receiver methods + // so if t is not a pointer, something is very wrong. + // The calls above only invoke isUnmarshaler on pointer types. + if t.Kind() != reflect.Ptr { + panic("proto: misuse of isUnmarshaler") + } + return t.Implements(unmarshalerType) +} + +// Init populates the properties from a protocol buffer struct tag. +func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { + p.init(typ, name, tag, f, true) +} + +func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { + // "bytes,49,opt,def=hello!" + p.Name = name + p.OrigName = name + if f != nil { + p.field = toField(f) + } + if tag == "" { + return + } + p.Parse(tag) + p.setEncAndDec(typ, f, lockGetProp) +} + +var ( + propertiesMu sync.RWMutex + propertiesMap = make(map[reflect.Type]*StructProperties) +) + +// GetProperties returns the list of properties for the type represented by t. +// t must represent a generated struct type of a protocol message. +func GetProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic("proto: type must have kind struct") + } + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + if collectStats { + stats.Chit++ + } + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() + return sprop +} + +// getPropertiesLocked requires that propertiesMu is held. +func getPropertiesLocked(t reflect.Type) *StructProperties { + if prop, ok := propertiesMap[t]; ok { + if collectStats { + stats.Chit++ + } + return prop + } + if collectStats { + stats.Cmiss++ + } + + prop := new(StructProperties) + // in case of recursive protos, fill this in now. + propertiesMap[t] = prop + + // build properties + prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) + prop.unrecField = invalidField + prop.Prop = make([]*Properties, t.NumField()) + prop.order = make([]int, t.NumField()) + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + p := new(Properties) + name := f.Name + p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) + + if f.Name == "XXX_extensions" { // special case + p.enc = (*Buffer).enc_map + p.dec = nil // not needed + p.size = size_map + } + if f.Name == "XXX_unrecognized" { // special case + prop.unrecField = toField(&f) + } + oneof := f.Tag.Get("protobuf_oneof") != "" // special case + prop.Prop[i] = p + prop.order[i] = i + if debug { + print(i, " ", f.Name, " ", t.String(), " ") + if p.Tag > 0 { + print(p.String()) + } + print("\n") + } + if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof { + fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") + } + } + + // Re-order prop.order. + sort.Sort(prop) + + type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + var oots []interface{} + prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs() + prop.stype = t + + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + + // build required counts + // build tags + reqCount := 0 + prop.decoderOrigNames = make(map[string]int) + for i, p := range prop.Prop { + if strings.HasPrefix(p.Name, "XXX_") { + // Internal fields should not appear in tags/origNames maps. + // They are handled specially when encoding and decoding. + continue + } + if p.Required { + reqCount++ + } + prop.decoderTags.put(p.Tag, i) + prop.decoderOrigNames[p.OrigName] = i + } + prop.reqCount = reqCount + + return prop +} + +// Return the Properties object for the x[0]'th field of the structure. +func propByIndex(t reflect.Type, x []int) *Properties { + if len(x) != 1 { + fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t) + return nil + } + prop := GetProperties(t) + return prop.Prop[x[0]] +} + +// Get the address and type of a pointer to a struct from an interface. +func getbase(pb Message) (t reflect.Type, b structPointer, err error) { + if pb == nil { + err = ErrNil + return + } + // get the reflect type of the pointer to the struct. + t = reflect.TypeOf(pb) + // get the address of the struct. + value := reflect.ValueOf(pb) + b = toStructPointer(value) + return +} + +// A global registry of enum types. +// The generated code will register the generated maps by calling RegisterEnum. + +var enumValueMaps = make(map[string]map[string]int32) + +// RegisterEnum is called from the generated code to install the enum descriptor +// maps into the global table to aid parsing text format protocol buffers. +func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { + if _, ok := enumValueMaps[typeName]; ok { + panic("proto: duplicate enum registered: " + typeName) + } + enumValueMaps[typeName] = valueMap +} + +// EnumValueMap returns the mapping from names to integers of the +// enum type enumType, or a nil if not found. +func EnumValueMap(enumType string) map[string]int32 { + return enumValueMaps[enumType] +} + +// A registry of all linked message types. +// The string is a fully-qualified proto name ("pkg.Message"). +var ( + protoTypes = make(map[string]reflect.Type) + revProtoTypes = make(map[reflect.Type]string) +) + +// RegisterType is called from generated code and maps from the fully qualified +// proto name to the type (pointer to struct) of the protocol buffer. +func RegisterType(x Message, name string) { + if _, ok := protoTypes[name]; ok { + // TODO: Some day, make this a panic. + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + protoTypes[name] = t + revProtoTypes[t] = name +} + +// MessageName returns the fully-qualified proto name for the given message type. +func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } + +// MessageType returns the message type (pointer to struct) for a named message. +func MessageType(name string) reflect.Type { return protoTypes[name] } diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go new file mode 100644 index 0000000000..1cbaf86d39 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/text.go @@ -0,0 +1,762 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +// Functions for writing the text protocol buffer format. + +import ( + "bufio" + "bytes" + "encoding" + "errors" + "fmt" + "io" + "log" + "math" + "reflect" + "sort" + "strings" +) + +var ( + newline = []byte("\n") + spaces = []byte(" ") + gtNewline = []byte(">\n") + endBraceNewline = []byte("}\n") + backslashN = []byte{'\\', 'n'} + backslashR = []byte{'\\', 'r'} + backslashT = []byte{'\\', 't'} + backslashDQ = []byte{'\\', '"'} + backslashBS = []byte{'\\', '\\'} + posInf = []byte("inf") + negInf = []byte("-inf") + nan = []byte("nan") +) + +type writer interface { + io.Writer + WriteByte(byte) error +} + +// textWriter is an io.Writer that tracks its indentation level. +type textWriter struct { + ind int + complete bool // if the current position is a complete line + compact bool // whether to write out as a one-liner + w writer +} + +func (w *textWriter) WriteString(s string) (n int, err error) { + if !strings.Contains(s, "\n") { + if !w.compact && w.complete { + w.writeIndent() + } + w.complete = false + return io.WriteString(w.w, s) + } + // WriteString is typically called without newlines, so this + // codepath and its copy are rare. We copy to avoid + // duplicating all of Write's logic here. + return w.Write([]byte(s)) +} + +func (w *textWriter) Write(p []byte) (n int, err error) { + newlines := bytes.Count(p, newline) + if newlines == 0 { + if !w.compact && w.complete { + w.writeIndent() + } + n, err = w.w.Write(p) + w.complete = false + return n, err + } + + frags := bytes.SplitN(p, newline, newlines+1) + if w.compact { + for i, frag := range frags { + if i > 0 { + if err := w.w.WriteByte(' '); err != nil { + return n, err + } + n++ + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + } + return n, nil + } + + for i, frag := range frags { + if w.complete { + w.writeIndent() + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + if i+1 < len(frags) { + if err := w.w.WriteByte('\n'); err != nil { + return n, err + } + n++ + } + } + w.complete = len(frags[len(frags)-1]) == 0 + return n, nil +} + +func (w *textWriter) WriteByte(c byte) error { + if w.compact && c == '\n' { + c = ' ' + } + if !w.compact && w.complete { + w.writeIndent() + } + err := w.w.WriteByte(c) + w.complete = c == '\n' + return err +} + +func (w *textWriter) indent() { w.ind++ } + +func (w *textWriter) unindent() { + if w.ind == 0 { + log.Printf("proto: textWriter unindented too far") + return + } + w.ind-- +} + +func writeName(w *textWriter, props *Properties) error { + if _, err := w.WriteString(props.OrigName); err != nil { + return err + } + if props.Wire != "group" { + return w.WriteByte(':') + } + return nil +} + +// raw is the interface satisfied by RawMessage. +type raw interface { + Bytes() []byte +} + +func writeStruct(w *textWriter, sv reflect.Value) error { + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < sv.NumField(); i++ { + fv := sv.Field(i) + props := sprops.Prop[i] + name := st.Field(i).Name + + if strings.HasPrefix(name, "XXX_") { + // There are two XXX_ fields: + // XXX_unrecognized []byte + // XXX_extensions map[int32]proto.Extension + // The first is handled here; + // the second is handled at the bottom of this function. + if name == "XXX_unrecognized" && !fv.IsNil() { + if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Field not filled in. This could be an optional field or + // a required field that wasn't filled in. Either way, there + // isn't anything we can show for it. + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + // Repeated field that is empty, or a bytes field that is unused. + continue + } + + if props.Repeated && fv.Kind() == reflect.Slice { + // Repeated field. + for j := 0; j < fv.Len(); j++ { + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + v := fv.Index(j) + if v.Kind() == reflect.Ptr && v.IsNil() { + // A nil message in a repeated field is not valid, + // but we can handle that more gracefully than panicking. + if _, err := w.Write([]byte("\n")); err != nil { + return err + } + continue + } + if err := writeAny(w, v, props); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Map { + // Map fields are rendered as a repeated struct with key/value fields. + keys := fv.MapKeys() + sort.Sort(mapKeys(keys)) + for _, key := range keys { + val := fv.MapIndex(key) + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + // open struct + if err := w.WriteByte('<'); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + // key + if _, err := w.WriteString("key:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, key, props.mkeyprop); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + // nil values aren't legal, but we can avoid panicking because of them. + if val.Kind() != reflect.Ptr || !val.IsNil() { + // value + if _, err := w.WriteString("value:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, val, props.mvalprop); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + // close struct + w.unindent() + if err := w.WriteByte('>'); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { + // empty bytes field + continue + } + if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { + // proto3 non-repeated scalar field; skip if zero value + if isProto3Zero(fv) { + continue + } + } + + if fv.Kind() == reflect.Interface { + // Check if it is a oneof. + if st.Field(i).Tag.Get("protobuf_oneof") != "" { + // fv is nil, or holds a pointer to generated struct. + // That generated struct has exactly one field, + // which has a protobuf struct tag. + if fv.IsNil() { + continue + } + inner := fv.Elem().Elem() // interface -> *T -> T + tag := inner.Type().Field(0).Tag.Get("protobuf") + props = new(Properties) // Overwrite the outer props var, but not its pointee. + props.Parse(tag) + // Write the value in the oneof, not the oneof itself. + fv = inner.Field(0) + + // Special case to cope with malformed messages gracefully: + // If the value in the oneof is a nil pointer, don't panic + // in writeAny. + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Use errors.New so writeAny won't render quotes. + msg := errors.New("/* nil */") + fv = reflect.ValueOf(&msg).Elem() + } + } + } + + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if b, ok := fv.Interface().(raw); ok { + if err := writeRaw(w, b.Bytes()); err != nil { + return err + } + continue + } + + // Enums have a String method, so writeAny will work fine. + if err := writeAny(w, fv, props); err != nil { + return err + } + + if err := w.WriteByte('\n'); err != nil { + return err + } + } + + // Extensions (the XXX_extensions field). + pv := sv.Addr() + if pv.Type().Implements(extendableProtoType) { + if err := writeExtensions(w, pv); err != nil { + return err + } + } + + return nil +} + +// writeRaw writes an uninterpreted raw message. +func writeRaw(w *textWriter, b []byte) error { + if err := w.WriteByte('<'); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + if err := writeUnknownStruct(w, b); err != nil { + return err + } + w.unindent() + if err := w.WriteByte('>'); err != nil { + return err + } + return nil +} + +// writeAny writes an arbitrary field. +func writeAny(w *textWriter, v reflect.Value, props *Properties) error { + v = reflect.Indirect(v) + + // Floats have special cases. + if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { + x := v.Float() + var b []byte + switch { + case math.IsInf(x, 1): + b = posInf + case math.IsInf(x, -1): + b = negInf + case math.IsNaN(x): + b = nan + } + if b != nil { + _, err := w.Write(b) + return err + } + // Other values are handled below. + } + + // We don't attempt to serialise every possible value type; only those + // that can occur in protocol buffers. + switch v.Kind() { + case reflect.Slice: + // Should only be a []byte; repeated fields are handled in writeStruct. + if err := writeString(w, string(v.Interface().([]byte))); err != nil { + return err + } + case reflect.String: + if err := writeString(w, v.String()); err != nil { + return err + } + case reflect.Struct: + // Required/optional group/message. + var bra, ket byte = '<', '>' + if props != nil && props.Wire == "group" { + bra, ket = '{', '}' + } + if err := w.WriteByte(bra); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + if tm, ok := v.Interface().(encoding.TextMarshaler); ok { + text, err := tm.MarshalText() + if err != nil { + return err + } + if _, err = w.Write(text); err != nil { + return err + } + } else if err := writeStruct(w, v); err != nil { + return err + } + w.unindent() + if err := w.WriteByte(ket); err != nil { + return err + } + default: + _, err := fmt.Fprint(w, v.Interface()) + return err + } + return nil +} + +// equivalent to C's isprint. +func isprint(c byte) bool { + return c >= 0x20 && c < 0x7f +} + +// writeString writes a string in the protocol buffer text format. +// It is similar to strconv.Quote except we don't use Go escape sequences, +// we treat the string as a byte sequence, and we use octal escapes. +// These differences are to maintain interoperability with the other +// languages' implementations of the text format. +func writeString(w *textWriter, s string) error { + // use WriteByte here to get any needed indent + if err := w.WriteByte('"'); err != nil { + return err + } + // Loop over the bytes, not the runes. + for i := 0; i < len(s); i++ { + var err error + // Divergence from C++: we don't escape apostrophes. + // There's no need to escape them, and the C++ parser + // copes with a naked apostrophe. + switch c := s[i]; c { + case '\n': + _, err = w.w.Write(backslashN) + case '\r': + _, err = w.w.Write(backslashR) + case '\t': + _, err = w.w.Write(backslashT) + case '"': + _, err = w.w.Write(backslashDQ) + case '\\': + _, err = w.w.Write(backslashBS) + default: + if isprint(c) { + err = w.w.WriteByte(c) + } else { + _, err = fmt.Fprintf(w.w, "\\%03o", c) + } + } + if err != nil { + return err + } + } + return w.WriteByte('"') +} + +func writeUnknownStruct(w *textWriter, data []byte) (err error) { + if !w.compact { + if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { + return err + } + } + b := NewBuffer(data) + for b.index < len(b.buf) { + x, err := b.DecodeVarint() + if err != nil { + _, err := fmt.Fprintf(w, "/* %v */\n", err) + return err + } + wire, tag := x&7, x>>3 + if wire == WireEndGroup { + w.unindent() + if _, err := w.Write(endBraceNewline); err != nil { + return err + } + continue + } + if _, err := fmt.Fprint(w, tag); err != nil { + return err + } + if wire != WireStartGroup { + if err := w.WriteByte(':'); err != nil { + return err + } + } + if !w.compact || wire == WireStartGroup { + if err := w.WriteByte(' '); err != nil { + return err + } + } + switch wire { + case WireBytes: + buf, e := b.DecodeRawBytes(false) + if e == nil { + _, err = fmt.Fprintf(w, "%q", buf) + } else { + _, err = fmt.Fprintf(w, "/* %v */", e) + } + case WireFixed32: + x, err = b.DecodeFixed32() + err = writeUnknownInt(w, x, err) + case WireFixed64: + x, err = b.DecodeFixed64() + err = writeUnknownInt(w, x, err) + case WireStartGroup: + err = w.WriteByte('{') + w.indent() + case WireVarint: + x, err = b.DecodeVarint() + err = writeUnknownInt(w, x, err) + default: + _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) + } + if err != nil { + return err + } + if err = w.WriteByte('\n'); err != nil { + return err + } + } + return nil +} + +func writeUnknownInt(w *textWriter, x uint64, err error) error { + if err == nil { + _, err = fmt.Fprint(w, x) + } else { + _, err = fmt.Fprintf(w, "/* %v */", err) + } + return err +} + +type int32Slice []int32 + +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// writeExtensions writes all the extensions in pv. +// pv is assumed to be a pointer to a protocol message struct that is extendable. +func writeExtensions(w *textWriter, pv reflect.Value) error { + emap := extensionMaps[pv.Type().Elem()] + ep := pv.Interface().(extendableProto) + + // Order the extensions by ID. + // This isn't strictly necessary, but it will give us + // canonical output, which will also make testing easier. + m := ep.ExtensionMap() + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + + for _, extNum := range ids { + ext := m[extNum] + var desc *ExtensionDesc + if emap != nil { + desc = emap[extNum] + } + if desc == nil { + // Unknown extension. + if err := writeUnknownStruct(w, ext.enc); err != nil { + return err + } + continue + } + + pb, err := GetExtension(ep, desc) + if err != nil { + return fmt.Errorf("failed getting extension: %v", err) + } + + // Repeated extensions will appear as a slice. + if !desc.repeated() { + if err := writeExtension(w, desc.Name, pb); err != nil { + return err + } + } else { + v := reflect.ValueOf(pb) + for i := 0; i < v.Len(); i++ { + if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { + return err + } + } + } + } + return nil +} + +func writeExtension(w *textWriter, name string, pb interface{}) error { + if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + return nil +} + +func (w *textWriter) writeIndent() { + if !w.complete { + return + } + remain := w.ind * 2 + for remain > 0 { + n := remain + if n > len(spaces) { + n = len(spaces) + } + w.w.Write(spaces[:n]) + remain -= n + } + w.complete = false +} + +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + Compact bool // use compact text format (one line). +} + +// Marshal writes a given protocol buffer in text format. +// The only errors returned are from w. +func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error { + val := reflect.ValueOf(pb) + if pb == nil || val.IsNil() { + w.Write([]byte("")) + return nil + } + var bw *bufio.Writer + ww, ok := w.(writer) + if !ok { + bw = bufio.NewWriter(w) + ww = bw + } + aw := &textWriter{ + w: ww, + complete: true, + compact: m.Compact, + } + + if tm, ok := pb.(encoding.TextMarshaler); ok { + text, err := tm.MarshalText() + if err != nil { + return err + } + if _, err = aw.Write(text); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil + } + // Dereference the received pointer so we don't have outer < and >. + v := reflect.Indirect(val) + if err := writeStruct(aw, v); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil +} + +// Text is the same as Marshal, but returns the string directly. +func (m *TextMarshaler) Text(pb Message) string { + var buf bytes.Buffer + m.Marshal(&buf, pb) + return buf.String() +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// TODO: consider removing some of the Marshal functions below. + +// MarshalText writes a given protocol buffer in text format. +// The only errors returned are from w. +func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } + +// MarshalTextString is the same as MarshalText, but returns the string directly. +func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } + +// CompactText writes a given protocol buffer in compact text format (one line). +func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } + +// CompactTextString is the same as CompactText, but returns the string directly. +func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go new file mode 100644 index 0000000000..451323262c --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -0,0 +1,806 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +// Functions for parsing the Text protocol buffer format. +// TODO: message sets. + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "unicode/utf8" +) + +type ParseError struct { + Message string + Line int // 1-based line number + Offset int // 0-based byte offset from start of input +} + +func (p *ParseError) Error() string { + if p.Line == 1 { + // show offset only for first line + return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) + } + return fmt.Sprintf("line %d: %v", p.Line, p.Message) +} + +type token struct { + value string + err *ParseError + line int // line number + offset int // byte number from start of input, not start of line + unquoted string // the unquoted version of value, if it was a quoted string +} + +func (t *token) String() string { + if t.err == nil { + return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) + } + return fmt.Sprintf("parse error: %v", t.err) +} + +type textParser struct { + s string // remaining input + done bool // whether the parsing is finished (success or error) + backed bool // whether back() was called + offset, line int + cur token +} + +func newTextParser(s string) *textParser { + p := new(textParser) + p.s = s + p.line = 1 + p.cur.line = 1 + return p +} + +func (p *textParser) errorf(format string, a ...interface{}) *ParseError { + pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} + p.cur.err = pe + p.done = true + return pe +} + +// Numbers and identifiers are matched by [-+._A-Za-z0-9] +func isIdentOrNumberChar(c byte) bool { + switch { + case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': + return true + case '0' <= c && c <= '9': + return true + } + switch c { + case '-', '+', '.', '_': + return true + } + return false +} + +func isWhitespace(c byte) bool { + switch c { + case ' ', '\t', '\n', '\r': + return true + } + return false +} + +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} + +func (p *textParser) skipWhitespace() { + i := 0 + for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { + if p.s[i] == '#' { + // comment; skip to end of line or input + for i < len(p.s) && p.s[i] != '\n' { + i++ + } + if i == len(p.s) { + break + } + } + if p.s[i] == '\n' { + p.line++ + } + i++ + } + p.offset += i + p.s = p.s[i:len(p.s)] + if len(p.s) == 0 { + p.done = true + } +} + +func (p *textParser) advance() { + // Skip whitespace + p.skipWhitespace() + if p.done { + return + } + + // Start of non-whitespace + p.cur.err = nil + p.cur.offset, p.cur.line = p.offset, p.line + p.cur.unquoted = "" + switch p.s[0] { + case '<', '>', '{', '}', ':', '[', ']', ';', ',': + // Single symbol + p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] + case '"', '\'': + // Quoted string + i := 1 + for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { + if p.s[i] == '\\' && i+1 < len(p.s) { + // skip escaped char + i++ + } + i++ + } + if i >= len(p.s) || p.s[i] != p.s[0] { + p.errorf("unmatched quote") + return + } + unq, err := unquoteC(p.s[1:i], rune(p.s[0])) + if err != nil { + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) + return + } + p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] + p.cur.unquoted = unq + default: + i := 0 + for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { + i++ + } + if i == 0 { + p.errorf("unexpected byte %#x", p.s[0]) + return + } + p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] + } + p.offset += len(p.cur.value) +} + +var ( + errBadUTF8 = errors.New("proto: bad UTF-8") + errBadHex = errors.New("proto: bad hexadecimal") +) + +func unquoteC(s string, quote rune) (string, error) { + // This is based on C++'s tokenizer.cc. + // Despite its name, this is *not* parsing C syntax. + // For instance, "\0" is an invalid quoted string. + + // Avoid allocation in trivial cases. + simple := true + for _, r := range s { + if r == '\\' || r == quote { + simple = false + break + } + } + if simple { + return s, nil + } + + buf := make([]byte, 0, 3*len(s)/2) + for len(s) > 0 { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", errBadUTF8 + } + s = s[n:] + if r != '\\' { + if r < utf8.RuneSelf { + buf = append(buf, byte(r)) + } else { + buf = append(buf, string(r)...) + } + continue + } + + ch, tail, err := unescape(s) + if err != nil { + return "", err + } + buf = append(buf, ch...) + s = tail + } + return string(buf), nil +} + +func unescape(s string) (ch string, tail string, err error) { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", "", errBadUTF8 + } + s = s[n:] + switch r { + case 'a': + return "\a", s, nil + case 'b': + return "\b", s, nil + case 'f': + return "\f", s, nil + case 'n': + return "\n", s, nil + case 'r': + return "\r", s, nil + case 't': + return "\t", s, nil + case 'v': + return "\v", s, nil + case '?': + return "?", s, nil // trigraph workaround + case '\'', '"', '\\': + return string(r), s, nil + case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X': + if len(s) < 2 { + return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) + } + base := 8 + ss := s[:2] + s = s[2:] + if r == 'x' || r == 'X' { + base = 16 + } else { + ss = string(r) + ss + } + i, err := strconv.ParseUint(ss, base, 8) + if err != nil { + return "", "", err + } + return string([]byte{byte(i)}), s, nil + case 'u', 'U': + n := 4 + if r == 'U' { + n = 8 + } + if len(s) < n { + return "", "", fmt.Errorf(`\%c requires %d digits`, r, n) + } + + bs := make([]byte, n/2) + for i := 0; i < n; i += 2 { + a, ok1 := unhex(s[i]) + b, ok2 := unhex(s[i+1]) + if !ok1 || !ok2 { + return "", "", errBadHex + } + bs[i/2] = a<<4 | b + } + s = s[n:] + return string(bs), s, nil + } + return "", "", fmt.Errorf(`unknown escape \%c`, r) +} + +// Adapted from src/pkg/strconv/quote.go. +func unhex(b byte) (v byte, ok bool) { + switch { + case '0' <= b && b <= '9': + return b - '0', true + case 'a' <= b && b <= 'f': + return b - 'a' + 10, true + case 'A' <= b && b <= 'F': + return b - 'A' + 10, true + } + return 0, false +} + +// Back off the parser by one token. Can only be done between calls to next(). +// It makes the next advance() a no-op. +func (p *textParser) back() { p.backed = true } + +// Advances the parser and returns the new current token. +func (p *textParser) next() *token { + if p.backed || p.done { + p.backed = false + return &p.cur + } + p.advance() + if p.done { + p.cur.value = "" + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { + // Look for multiple quoted strings separated by whitespace, + // and concatenate them. + cat := p.cur + for { + p.skipWhitespace() + if p.done || !isQuote(p.s[0]) { + break + } + p.advance() + if p.cur.err != nil { + return &p.cur + } + cat.value += " " + p.cur.value + cat.unquoted += p.cur.unquoted + } + p.done = false // parser may have seen EOF, but we want to return cat + p.cur = cat + } + return &p.cur +} + +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +// Return a RequiredNotSetError indicating which required field was not set. +func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < st.NumField(); i++ { + if !isNil(sv.Field(i)) { + continue + } + + props := sprops.Prop[i] + if props.Required { + return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} + } + } + return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen +} + +// Returns the index in the struct for the named field, as well as the parsed tag properties. +func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { + i, ok := sprops.decoderOrigNames[name] + if ok { + return i, sprops.Prop[i], true + } + return -1, nil, false +} + +// Consume a ':' from the input stream (if the next token is a colon), +// returning an error if a colon is needed but not present. +func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ":" { + // Colon is optional when the field is a group or message. + needColon := true + switch props.Wire { + case "group": + needColon = false + case "bytes": + // A "bytes" field is either a message, a string, or a repeated field; + // those three become *T, *string and []T respectively, so we can check for + // this field being a pointer to a non-string. + if typ.Kind() == reflect.Ptr { + // *T or *string + if typ.Elem().Kind() == reflect.String { + break + } + } else if typ.Kind() == reflect.Slice { + // []T or []*T + if typ.Elem().Kind() != reflect.Ptr { + break + } + } else if typ.Kind() == reflect.String { + // The proto3 exception is for a string field, + // which requires a colon. + break + } + needColon = false + } + if needColon { + return p.errorf("expected ':', found %q", tok.value) + } + p.back() + } + return nil +} + +func (p *textParser) readStruct(sv reflect.Value, terminator string) error { + st := sv.Type() + sprops := GetProperties(st) + reqCount := sprops.reqCount + var reqFieldErr error + fieldSet := make(map[string]bool) + // A struct is a sequence of "name: value", terminated by one of + // '>' or '}', or the end of the input. A name may also be + // "[extension]". + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + if tok.value == "[" { + // Looks like an extension. + // + // TODO: Check whether we need to handle + // namespace rooted names (e.g. ".something.Foo"). + tok = p.next() + if tok.err != nil { + return tok.err + } + var desc *ExtensionDesc + // This could be faster, but it's functional. + // TODO: Do something smarter than a linear scan. + for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { + if d.Name == tok.value { + desc = d + break + } + } + if desc == nil { + return p.errorf("unrecognized extension %q", tok.value) + } + // Check the extension terminator. + tok = p.next() + if tok.err != nil { + return tok.err + } + if tok.value != "]" { + return p.errorf("unrecognized extension terminator %q", tok.value) + } + + props := &Properties{} + props.Parse(desc.Tag) + + typ := reflect.TypeOf(desc.ExtensionType) + if err := p.checkForColon(props, typ); err != nil { + return err + } + + rep := desc.repeated() + + // Read the extension structure, and set it in + // the value we're constructing. + var ext reflect.Value + if !rep { + ext = reflect.New(typ).Elem() + } else { + ext = reflect.New(typ.Elem()).Elem() + } + if err := p.readAny(ext, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } + ep := sv.Addr().Interface().(extendableProto) + if !rep { + SetExtension(ep, desc, ext.Interface()) + } else { + old, err := GetExtension(ep, desc) + var sl reflect.Value + if err == nil { + sl = reflect.ValueOf(old) // existing slice + } else { + sl = reflect.MakeSlice(typ, 0, 1) + } + sl = reflect.Append(sl, ext) + SetExtension(ep, desc, sl.Interface()) + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + continue + } + + // This is a normal, non-extension field. + name := tok.value + var dst reflect.Value + fi, props, ok := structFieldByName(sprops, name) + if ok { + dst = sv.Field(fi) + } else if oop, ok := sprops.OneofTypes[name]; ok { + // It is a oneof. + props = oop.Prop + nv := reflect.New(oop.Type.Elem()) + dst = nv.Elem().Field(0) + sv.Field(oop.Field).Set(nv) + } + if !dst.IsValid() { + return p.errorf("unknown field name %q in %v", name, st) + } + + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) + } + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // Technically the "key" and "value" could come in any order, + // but in practice they won't. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + if err := p.consumeToken("key"); err != nil { + return err + } + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.mkeyprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken("value"); err != nil { + return err + } + if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.mvalprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken(terminator); err != nil { + return err + } + + dst.SetMapIndex(key, val) + continue + } + + // Check that it's not already set if it's not a repeated field. + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) + } + + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Parse into the field. + fieldSet[name] = true + if err := p.readAny(dst, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } else if props.Required { + reqCount-- + } + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + + } + + if reqCount > 0 { + return p.missingRequiredFieldError(sv) + } + return reqFieldErr +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in readStruct to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + +func (p *textParser) readAny(v reflect.Value, props *Properties) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "" { + return p.errorf("unexpected EOF") + } + + switch fv := v; fv.Kind() { + case reflect.Slice: + at := v.Type() + if at.Elem().Kind() == reflect.Uint8 { + // Special case for []byte + if tok.value[0] != '"' && tok.value[0] != '\'' { + // Deliberately written out here, as the error after + // this switch statement would write "invalid []byte: ...", + // which is not as user-friendly. + return p.errorf("invalid string: %v", tok.value) + } + bytes := []byte(tok.unquoted) + fv.Set(reflect.ValueOf(bytes)) + return nil + } + // Repeated field. + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + err := p.readAny(fv.Index(fv.Len()-1), props) + if err != nil { + return err + } + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "]" { + break + } + if tok.value != "," { + return p.errorf("Expected ']' or ',' found %q", tok.value) + } + } + return nil + } + // One value of the repeated field. + p.back() + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + return p.readAny(fv.Index(fv.Len()-1), props) + case reflect.Bool: + // Either "true", "false", 1 or 0. + switch tok.value { + case "true", "1": + fv.SetBool(true) + return nil + case "false", "0": + fv.SetBool(false) + return nil + } + case reflect.Float32, reflect.Float64: + v := tok.value + // Ignore 'f' for compatibility with output generated by C++, but don't + // remove 'f' when the value is "-inf" or "inf". + if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { + v = v[:len(v)-1] + } + if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { + fv.SetFloat(f) + return nil + } + case reflect.Int32: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + fv.SetInt(x) + return nil + } + + if len(props.Enum) == 0 { + break + } + m, ok := enumValueMaps[props.Enum] + if !ok { + break + } + x, ok := m[tok.value] + if !ok { + break + } + fv.SetInt(int64(x)) + return nil + case reflect.Int64: + if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { + fv.SetInt(x) + return nil + } + + case reflect.Ptr: + // A basic field (indirected through pointer), or a repeated message/group + p.back() + fv.Set(reflect.New(fv.Type().Elem())) + return p.readAny(fv.Elem(), props) + case reflect.String: + if tok.value[0] == '"' || tok.value[0] == '\'' { + fv.SetString(tok.unquoted) + return nil + } + case reflect.Struct: + var terminator string + switch tok.value { + case "{": + terminator = "}" + case "<": + terminator = ">" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + // TODO: Handle nested messages which implement encoding.TextUnmarshaler. + return p.readStruct(fv, terminator) + case reflect.Uint32: + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + fv.SetUint(uint64(x)) + return nil + } + case reflect.Uint64: + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + fv.SetUint(x) + return nil + } + } + return p.errorf("invalid %v: %v", v.Type(), tok.value) +} + +// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb +// before starting to unmarshal, so any existing data in pb is always removed. +// If a required field is not set and no other error occurs, +// UnmarshalText returns *RequiredNotSetError. +func UnmarshalText(s string, pb Message) error { + if um, ok := pb.(encoding.TextUnmarshaler); ok { + err := um.UnmarshalText([]byte(s)) + return err + } + pb.Reset() + v := reflect.ValueOf(pb) + if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { + return pe + } + return nil +} diff --git a/vendor/github.com/google/go-querystring/LICENSE b/vendor/github.com/google/go-querystring/LICENSE new file mode 100644 index 0000000000..ae121a1e46 --- /dev/null +++ b/vendor/github.com/google/go-querystring/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013 Google. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/google/go-querystring/query/encode.go b/vendor/github.com/google/go-querystring/query/encode.go similarity index 100% rename from Godeps/_workspace/src/github.com/google/go-querystring/query/encode.go rename to vendor/github.com/google/go-querystring/query/encode.go diff --git a/vendor/github.com/intel-go/cpuid/.gitignore b/vendor/github.com/intel-go/cpuid/.gitignore new file mode 100644 index 0000000000..b8bd0267bd --- /dev/null +++ b/vendor/github.com/intel-go/cpuid/.gitignore @@ -0,0 +1,28 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/vendor/github.com/intel-go/cpuid/LICENSE b/vendor/github.com/intel-go/cpuid/LICENSE new file mode 100644 index 0000000000..24b67017ab --- /dev/null +++ b/vendor/github.com/intel-go/cpuid/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015, Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/github.com/intel-go/cpuid/README.md b/vendor/github.com/intel-go/cpuid/README.md new file mode 100644 index 0000000000..7783f0fc50 --- /dev/null +++ b/vendor/github.com/intel-go/cpuid/README.md @@ -0,0 +1,244 @@ +# cpuid +### Intel CPUID library for Go Programming Language + +The cpuid package provides convenient and fast access to information from +the x86 CPUID instruction. +The package gathers all information during package initialization phase +so its public interface will not need to execute the CPUID instruction at runtime. +Frequent calls to the CPUID instruction can hurt performance, +so this package makes it easier to do CPU-specific optimizations. + +[![GoDoc](https://godoc.org/github.com/intel-go/cpuid?status.svg)](https://godoc.org/github.com/intel-go/cpuid) + +### You can get it with + +```shell +go get github.com/intel-go/cpuid +``` + +### Example: + +```go +package main + +import ( + "github.com/intel-go/cpuid" + "fmt" +) + +func main() { + fmt.Printf("VendorString: %s\n", cpuid.VendorIdentificatorString) + + fmt.Printf("Features: ") + for i := uint64(0); i < 64; i++ { + if cpuid.HasFeature(1 << i) { + fmt.Printf("%s ", cpuid.FeatureNames[1< **SSE3** Prescott New Instructions-SSE3 (PNI)
+ > **PCLMULQDQ** PCLMULQDQ support
+ > **DTES64** 64-bit debug store (edx bit 21)
+ > **MONITOR** MONITOR and MWAIT instructions (SSE3)
+ > **DSI_CPL** CPL qualified debug store
+ > **VMX** Virtual Machine eXtensions
+ > **SMX** Safer Mode Extensions (LaGrande)
+ > **EST** Enhanced SpeedStep
+ > **TM2** Thermal Monitor 2
+ > **SSSE3** Supplemental SSE3 instructions
+ > **CNXT_ID** L1 Context ID
+ > **SDBG** Silicon Debug interface
+ > **FMA** Fused multiply-add (FMA3)
+ > **CX16** CMPXCHG16B instruction
+ > **XTPR** Can disable sending task priority messages
+ > **PDCM** Perfmon & debug capability
+ > **PCID** Process context identifiers (CR4 bit 17)
+ > **DCA** Direct cache access for DMA writes[10][11]
+ > **SSE4_1** SSE4.1 instructions
+ > **SSE4_2** SSE4.2 instructions
+ > **X2APIC** x2APIC support
+ > **MOVBE** MOVBE instruction (big-endian)
+ > **POPCNT** POPCNT instruction
+ > **TSC_DEADLINE** line APIC supports one-shot operation using a TSC deadline value
+ > **AES** AES instruction set
+ > **XSAVE** XSAVE, XRESTOR, XSETBV, XGETBV
+ > **OSXSAVE** XSAVE enabled by OS
+ > **AVX** Advanced Vector Extensions
+ > **F16C** F16C (half-precision) FP support
+ > **RDRND** RDRAND (on-chip random number generator) support
+ > **HYPERVISOR** Running on a hypervisor (always 0 on a real CPU, but also with some hypervisors)
+ > **FPU** Onboard x87 FPU
+ > **VME** Virtual 8086 mode extensions (such as VIF, VIP, PIV)
+ > **DE** Debugging extensions (CR4 bit 3)
+ > **PSE** Page Size Extension
+ > **TSC** Time Stamp Counter
+ > **MSR** Model-specific registers
+ > **PAE** Physical Address Extension
+ > **MCE** Machine Check Exception
+ > **CX8** CMPXCHG8 (compare-and-swap) instruction
+ > **APIC** Onboard Advanced Programmable Interrupt Controller
+ > **SEP** SYSENTER and SYSEXIT instructions
+ > **MTRR** Memory Type Range Registers
+ > **PGE** Page Global Enable bit in CR4
+ > **MCA** Machine check architecture
+ > **CMOV** Conditional move and FCMOV instructions
+ > **PAT** Page Attribute Table
+ > **PSE_36** 36-bit page size extension
+ > **PSN** Processor Serial Number
+ > **CLFSH** CLFLUSH instruction (SSE2)
+ > **DS** Debug store: save trace of executed jumps
+ > **ACPI** Onboard thermal control MSRs for ACPI
+ > **MMX** MMX instructions
+ > **FXSR** FXSAVE, FXRESTOR instructions, CR4 bit 9
+ > **SSE** SSE instructions (a.k.a. Katmai New Instructions)
+ > **SSE2** SSE2 instructions
+ > **SS** CPU cache supports self-snoop
+ > **HTT** Hyper-threading
+ > **TM** Thermal monitor automatically limits temperature
+ > **IA64** IA64 processor emulating x86
+ > **PBE** Pending Break Enable (PBE# pin) wakeup support
+ +Usage example: + +```go +if EnabledAVX && HasFeature(AVX) { + fmt.Printf("We can use AVX\n") +} +``` + +* **func HasExtendedFeature(feature uint64) bool** to check for the following features: + > **FSGSBASE** Access to base of %fs and %gs
+ > **IA32_TSC_ADJUST** IA32_TSC_ADJUST MSR is supported if 1
+ > **BMI1** Bit Manipulation Instruction Set 1
+ > **HLE** Transactional Synchronization Extensions
+ > **AVX2** Advanced Vector Extensions 2
+ > **SMEP** Supervisor-Mode Execution Prevention
+ > **BMI2** Bit Manipulation Instruction Set 2
+ > **ERMS** Enhanced REP MOVSB/STOSB
+ > **INVPCID** INVPCID instruction
+ > **RTM** Transactional Synchronization Extensions
+ > **PQM** Supports Platform Quality of Service Monitoring (PQM) capability if 1
+ > **DFPUCDS** Deprecates FPU CS and FPU DS values if 1
+ > **MPX** Intel MPX (Memory Protection Extensions)
+ > **PQE** Supports Platform Quality of Service Enforcement (PQE) capability if 1
+ > **AVX512F** AVX-512 Foundation
+ > **AVX512DQ** AVX-512 Doubleword and Quadword Instructions
+ > **RDSEED** RDSEED instruction
+ > **ADX** Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
+ > **SMAP** Supervisor Mode Access Prevention
+ > **AVX512IFMA** AVX-512 Integer Fused Multiply-Add Instructions
+ > **PCOMMIT** PCOMMIT instruction
+ > **CLFLUSHOPT** CLFLUSHOPT instruction
+ > **CLWB** CLWB instruction
+ > **INTEL_PROCESSOR_TRACE** Intel Processor Trace
+ > **AVX512PF** AVX-512 Prefetch Instructions
+ > **AVX512ER** AVX-512 Exponential and Reciprocal Instructions
+ > **AVX512CD** AVX-512 Conflict Detection Instructions
+ > **SHA** Intel SHA extensions
+ > **AVX512BW** AVX-512 Byte and Word Instructions
+ > **AVX512VL** AVX-512 Vector Length Extensions
+ > **PREFETCHWT1** PREFETCHWT1 instruction
+ > **AVX512VBMI** AVX-512 Vector Bit Manipulation Instructions
+ +* **func HasExtraFeature(feature uint64) bool** + > **LAHF_LM** LahfSahf LAHF and SAHF instruction support in 64-bit mod
+ > **CMP_LEGACY** CmpLegacy Core multi-processing legacy mode.
+ > **SVM** SVM Secure virtual machine.
+ > **EXTAPIC** ExtApicSpace Extended APIC space.
+ > **CR8_LEGACY** AltMovCr8 LOCK MOV CR0 means MOV CR8.
+ > **ABM** ABM Advanced bit manipulation. LZCNT instruction support.
+ > **SSE4A** SSE4A EXTRQ, INSERTQ, MOVNTSS, and MOVNTSD instruction support.
+ > **MISALIGNSSE** Misaligned SSE mode.
+ > **PREFETCHW** PREFETCH and PREFETCHW instruction support.
+ > **OSVW** OSVW OS visible workaround. Indicates OS-visible workaround support.
+ > **IBS** IBS Instruction based sampling.
+ > **XOP** XOP Extended operation support.
+ > **SKINIT** SKINIT SKINIT and STGI are supported.
+ > **WDT** WDT Watchdog timer support.
+ > **LWP** LWP Lightweight profiling support.
+ > **FMA4** FMA4 Four-operand FMA instruction support.
+ > **TCE** Translation Cache Extension
+ > **NODEID_MSR** NodeID MSR
+ > **TBM** TBM Trailing bit manipulation instruction support.
+ > **TOPOEXT** TopologyExtensio Topology extensions support.
+ > **PERFCTR_CORE** PerfCtrExtCore Processor performance counter extensions support.
+ > **PERFCTR_NB** PerfCtrExtNB NB performance counter extensions support.
+ > **SPM** StreamPerfMon Streaming performance monitor architecture.
+ > **DBX** DataBreakpointEx Data access breakpoint extension.
+ > **PERFTSC** PerfTsc
+ > **PCX_L2I** L2I perf counter extensions
+ > **FPU_2** Onboard x87 FPU
+ > **VME_2** Virtual mode extensions (VIF)
+ > **DE_2** Debugging extensions (CR4 bit 3)
+ > **PSE_2** Page Size Extension
+ > **TSC_2** Time Stamp Counter
+ > **MSR_2** Model-specific register
+ > **PAE_2** Physical Address Extension
+ > **MCE_2** Machine Check Exception
+ > **CX8_2** CMPXCHG8 (compare-and-swap) instruction
+ > **APIC_2** Onboard Advanced Programmable Interrupt Controller
+ > **SYSCALL** SYSCALL and SYSRET instructions
+ > **MTRR_2** Memory Type Range Registers
+ > **PGE_2** Page Global Enable bit in CR4
+ > **MCA_2** Machine check architecture
+ > **CMOV_2** Conditional move and FCMOV instructions
+ > **PAT_2** Page Attribute Table
+ > **PSE36** 36-bit page size extension
+ > **MP** Multiprocessor Capable
+ > **NX** NX bit
+ > **MMXEXT** Extended MMX
+ > **MMX_2** MMX instructions
+ > **FXSR_2** FXSAVE, FXRSTOR instructions
+ > **FXSR_OPT** FXSAVE/FXRSTOR optimizations
+ > **PDPE1GB** Gibibyte pages
+ > **RDTSCP** RDTSCP instruction
+ > **LM** Long mode
+ > **_3DNOWEXT** Extended 3DNow!
+ > **_3DNOW** 3DNow!
diff --git a/vendor/github.com/intel-go/cpuid/cpuid.go b/vendor/github.com/intel-go/cpuid/cpuid.go new file mode 100644 index 0000000000..b768f98163 --- /dev/null +++ b/vendor/github.com/intel-go/cpuid/cpuid.go @@ -0,0 +1,537 @@ +// Copyright 2015 Intel Corporation. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cpuid provides access to the information available +// through the CPUID instruction. +// All information is gathered during package initialization phase +// so package's public interface doesn't call CPUID instruction. +package cpuid + +// VendorIdentificationString like "GenuineIntel" or "AuthenticAMD" +var VendorIdentificatorString string + +// ProcessorBrandString like "Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz" +var ProcessorBrandString string + +// SteppingId is Processor Stepping ID as described in +// Intel® 64 and IA-32 Architectures Software Developer’s Manual +var SteppingId uint32 + +// ProcessorType obtained from processor Version Information, according to +// Intel® 64 and IA-32 Architectures Software Developer’s Manual +var ProcessorType uint32 + +// DisplayFamily is Family of processors obtained from processor Version Information, according to +// Intel® 64 and IA-32 Architectures Software Developer’s Manual +var DisplayFamily uint32 + +// Display Model is Model of processor obtained from processor Version Information, according to +// Intel® 64 and IA-32 Architectures Software Developer’s Manual +var DisplayModel uint32 + +// Cache line size in bytes +var CacheLineSize uint32 + +// Maximum number of addressable IDs for logical processors in this physical package +var MaxLogocalCPUId uint32 + +// Initial APIC ID +var InitialAPICId uint32 + +// Cache descriptor's array +// You can iterate like there: +// for _, cacheDescription := range cpuid.CacheDescriptors { +// fmt.Printf("CacheDescriptor: %v\n", cacheDescription) +// } +// See CacheDescriptor type for more information +var CacheDescriptors []CacheDescriptor + +// Smallest monitor-line size in bytes (default is processor's monitor granularity) +var MonLineSizeMin uint32 + +// Largest monitor-line size in bytes (default is processor's monitor granularity) +var MonLineSizeMax uint32 + +// Enumeration of Monitor-Mwait extensions availability status +var MonitorEMX bool + +// Supports treating interrupts as break-event for MWAIT flag +var MonitorIBE bool + +// EnabledAVX flag allows to check if feature AVX is enabled by OS/BIOS +var EnabledAVX bool = false + +// EnabledAVX512 flag allows to check if features AVX512xxx are enabled by OS/BIOS +var EnabledAVX512 bool = false + +type CacheDescriptor struct { + Level int // Cache level + CacheType int // Cache type + CacheName string // Name + CacheSize int // in KBytes (of page size for TLB) + Ways int // Associativity, 0 undefined, 0xFF fully associate + LineSize int // Cache line size in bytes + Entries int // number of entries for TLB + Partioning int // partitioning +} + +// ThermalSensorInterruptThresholds is the number of interrupt thresholds in digital thermal sensor. +var ThermalSensorInterruptThresholds uint32 + +// HasFeature to check if features from FeatureNames map are available on the current processor +func HasFeature(feature uint64) bool { + return (featureFlags & feature) != 0 +} + +// HasExtendedFeature to check if features from ExtendedFeatureNames map are available on the current processor +func HasExtendedFeature(feature uint64) bool { + return (extendedFeatureFlags & feature) != 0 +} + +// HasExtraFeature to check if features from ExtraFeatureNames map are available on the current processor +func HasExtraFeature(feature uint64) bool { + return (extraFeatureFlags & feature) != 0 +} + +// HasThermalAndPowerFeature to check if features from ThermalAndPowerFeatureNames map are available on the current processor +func HasThermalAndPowerFeature(feature uint32) bool { + return (thermalAndPowerFeatureFlags & feature) != 0 +} + +var FeatureNames = map[uint64]string{ + SSE3: "SSE3", + PCLMULQDQ: "PCLMULQDQ", + DTES64: "DTES64", + MONITOR: "MONITOR", + DSI_CPL: "DSI_CPL", + VMX: "VMX", + SMX: "SMX", + EST: "EST", + TM2: "TM2", + SSSE3: "SSSE3", + CNXT_ID: "CNXT_ID", + SDBG: "SDBG", + FMA: "FMA", + CX16: "CX16", + XTPR: "XTPR", + PDCM: "PDCM", + PCID: "PCID", + DCA: "DCA", + SSE4_1: "SSE4_1", + SSE4_2: "SSE4_2", + X2APIC: "X2APIC", + MOVBE: "MOVBE", + POPCNT: "POPCNT", + TSC_DEADLINE: "TSC_DEADLINE", + AES: "AES", + XSAVE: "XSAVE", + OSXSAVE: "OSXSAVE", + AVX: "AVX", + F16C: "F16C", + RDRND: "RDRND", + HYPERVISOR: "HYPERVISOR", + FPU: "FPU", + VME: "VME", + DE: "DE", + PSE: "PSE", + TSC: "TSC", + MSR: "MSR", + PAE: "PAE", + MCE: "MCE", + CX8: "CX8", + APIC: "APIC", + SEP: "SEP", + MTRR: "MTRR", + PGE: "PGE", + MCA: "MCA", + CMOV: "CMOV", + PAT: "PAT", + PSE_36: "PSE_36", + PSN: "PSN", + CLFSH: "CLFSH", + DS: "DS", + ACPI: "ACPI", + MMX: "MMX", + FXSR: "FXSR", + SSE: "SSE", + SSE2: "SSE2", + SS: "SS", + HTT: "HTT", + TM: "TM", + IA64: "IA64", + PBE: "PBE", +} + +var ThermalAndPowerFeatureNames = map[uint32]string{ // From leaf06 + ARAT: "ARAT", + PLN: "PLN", + ECMD: "ECMD", + PTM: "PTM", + HDC: "HDC", + HCFC: "HCFC", + HWP: "HWP", + HWP_NOTIF: "HWP_NOTIF", + HWP_ACTIVITY_WINDOW: "HWP_ACTIVITY_WINDOW", + HWP_ENERGY_PERFORMANCE: "HWP_ENERGY_PERFORMANCE", + HWP_PACKAGE_LEVEL_REQUEST: "HWP_PACKAGE_LEVEL_REQUEST", + PERFORMANCE_ENERGY_BIAS: "PERFORMANCE_ENERGY_BIAS", + TEMPERATURE_SENSOR: "TEMPERATURE_SENSOR", + TURBO_BOOST: "TURBO_BOOST", + TURBO_BOOST_MAX: "TURBO_BOOST_MAX", +} + +var ExtendedFeatureNames = map[uint64]string{ // From leaf07 + FSGSBASE: "FSGSBASE", + IA32_TSC_ADJUST: "IA32_TSC_ADJUST", + BMI1: "BMI1", + HLE: "HLE", + AVX2: "AVX2", + SMEP: "SMEP", + BMI2: "BMI2", + ERMS: "ERMS", + INVPCID: "INVPCID", + RTM: "RTM", + PQM: "PQM", + DFPUCDS: "DFPUCDS", + MPX: "MPX", + PQE: "PQE", + AVX512F: "AVX512F", + AVX512DQ: "AVX512DQ", + RDSEED: "RDSEED", + ADX: "ADX", + SMAP: "SMAP", + AVX512IFMA: "AVX512IFMA", + PCOMMIT: "PCOMMIT", + CLFLUSHOPT: "CLFLUSHOPT", + CLWB: "CLWB", + INTEL_PROCESSOR_TRACE: "INTEL_PROCESSOR_TRACE", + AVX512PF: "AVX512PF", + AVX512ER: "AVX512ER", + AVX512CD: "AVX512CD", + SHA: "SHA", + AVX512BW: "AVX512BW", + AVX512VL: "AVX512VL", + PREFETCHWT1: "PREFETCHWT1", + AVX512VBMI: "AVX512VBMI", +} + +var ExtraFeatureNames = map[uint64]string{ // From leaf 8000 0001 + LAHF_LM: "LAHF_LM", + CMP_LEGACY: "CMP_LEGACY", + SVM: "SVM", + EXTAPIC: "EXTAPIC", + CR8_LEGACY: "CR8_LEGACY", + ABM: "ABM", + SSE4A: "SSE4A", + MISALIGNSSE: "MISALIGNSSE", + PREFETCHW: "PREFETCHW", + OSVW: "OSVW", + IBS: "IBS", + XOP: "XOP", + SKINIT: "SKINIT", + WDT: "WDT", + LWP: "LWP", + FMA4: "FMA4", + TCE: "TCE", + NODEID_MSR: "NODEID_MSR", + TBM: "TBM", + TOPOEXT: "TOPOEXT", + PERFCTR_CORE: "PERFCTR_CORE", + PERFCTR_NB: "PERFCTR_NB", + SPM: "SPM", + DBX: "DBX", + PERFTSC: "PERFTSC", + PCX_L2I: "PCX_L2I", + FPU_2: "FPU", + VME_2: "VME", + DE_2: "DE", + PSE_2: "PSE", + TSC_2: "TSC", + MSR_2: "MSR", + PAE_2: "PAE", + MCE_2: "MCE", + CX8_2: "CX8", + APIC_2: "APIC", + SYSCALL: "SYSCALL", + MTRR_2: "MTRR", + PGE_2: "PGE", + MCA_2: "MCA", + CMOV_2: "CMOV", + PAT_2: "PAT", + PSE36: "PSE36", + MP: "MP", + NX: "NX", + MMXEXT: "MMXEXT", + MMX_2: "MMX", + FXSR_2: "FXSR", + FXSR_OPT: "FXSR_OPT", + PDPE1GB: "PDPE1GB", + RDTSCP: "RDTSCP", + LM: "LM", + _3DNOWEXT: "3DNOWEXT", + _3DNOW: "3DNOW", +} + +var brandStrings = map[string]int{ + "AMDisbetter!": AMD, + "AuthenticAMD": AMD, + "CentaurHauls": CENTAUR, + "CyrixInstead": CYRIX, + "GenuineIntel": INTEL, + "TransmetaCPU": TRANSMETA, + "GenuineTMx86": TRANSMETA, + "Geode by NSC": NATIONALSEMICONDUCTOR, + "NexGenDriven": NEXGEN, + "RiseRiseRise": RISE, + "SiS SiS SiS ": SIS, + "UMC UMC UMC ": UMC, + "VIA VIA VIA ": VIA, + "Vortex86 SoC": VORTEX, + "KVMKVMKVM": KVM, + "Microsoft Hv": HYPERV, + "VMwareVMware": VMWARE, + "XenVMMXenVMM": XEN, +} + +var maxInputValue uint32 +var maxExtendedInputValue uint32 +var extendedModelId uint32 +var extendedFamilyId uint32 +var brandIndex uint32 +var brandId int +var featureFlags uint64 +var thermalAndPowerFeatureFlags uint32 +var extendedFeatureFlags uint64 +var extraFeatureFlags uint64 + +const ( + UKNOWN = iota + AMD + CENTAUR + CYRIX + INTEL + TRANSMETA + NATIONALSEMICONDUCTOR + NEXGEN + RISE + SIS + UMC + VIA + VORTEX + KVM + HYPERV + VMWARE + XEN +) + +const ( + SSE3 = uint64(1) << iota + PCLMULQDQ + DTES64 + MONITOR + DSI_CPL + VMX + SMX + EST + TM2 + SSSE3 + CNXT_ID + SDBG + FMA + CX16 + XTPR + PDCM + _ + PCID + DCA + SSE4_1 + SSE4_2 + X2APIC + MOVBE + POPCNT + TSC_DEADLINE + AES + XSAVE + OSXSAVE + AVX + F16C + RDRND + HYPERVISOR + FPU + VME + DE + PSE + TSC + MSR + PAE + MCE + CX8 + APIC + _ + SEP + MTRR + PGE + MCA + CMOV + PAT + PSE_36 + PSN + CLFSH + _ + DS + ACPI + MMX + FXSR + SSE + SSE2 + SS + HTT + TM + IA64 + PBE +) + +const ( + FSGSBASE = uint64(1) << iota + IA32_TSC_ADJUST + _ + BMI1 + HLE + AVX2 + _ + SMEP + BMI2 + ERMS + INVPCID + RTM + PQM + DFPUCDS + MPX + PQE + AVX512F + AVX512DQ + RDSEED + ADX + SMAP + AVX512IFMA + PCOMMIT + CLFLUSHOPT + CLWB + INTEL_PROCESSOR_TRACE + AVX512PF + AVX512ER + AVX512CD + SHA + AVX512BW + AVX512VL + // ECX's const from there + PREFETCHWT1 + AVX512VBMI +) + +const ( + LAHF_LM = uint64(1) << iota + CMP_LEGACY + SVM + EXTAPIC + CR8_LEGACY + ABM + SSE4A + MISALIGNSSE + PREFETCHW + OSVW + IBS + XOP + SKINIT + WDT + _ + LWP + FMA4 + TCE + _ + NODEID_MSR + _ + TBM + TOPOEXT + PERFCTR_CORE + PERFCTR_NB + SPM + DBX + PERFTSC + PCX_L2I + _ + _ + _ + // EDX features from there + FPU_2 + VME_2 + DE_2 + PSE_2 + TSC_2 + MSR_2 + PAE_2 + MCE_2 + CX8_2 + APIC_2 + _ + SYSCALL + MTRR_2 + PGE_2 + MCA_2 + CMOV_2 + PAT_2 + PSE36 + _ + MP + NX + _ + MMXEXT + MMX_2 + FXSR_2 + FXSR_OPT + PDPE1GB + RDTSCP + _ + LM + _3DNOWEXT + _3DNOW +) + +// Thermal and Power Management features +const ( + // EAX bits 0-15 + TEMPERATURE_SENSOR = uint32(1) << iota // Digital temperature sensor + TURBO_BOOST // Intel Turbo Boost Technology available + ARAT // APIC-Timer-always-running feature is supported if set. + _ // Reserved + PLN // Power limit notification controls + ECMD // Clock modulation duty cycle extension + PTM // Package thermal management + HWP // HWP base registers (IA32_PM_ENABLE[bit 0], IA32_HWP_CAPABILITIES, IA32_HWP_REQUEST, IA32_HWP_STATUS) + HWP_NOTIF // IA32_HWP_INTERRUPT MSR + HWP_ACTIVITY_WINDOW // IA32_HWP_REQUEST[bits 41:32] + HWP_ENERGY_PERFORMANCE // IA32_HWP_REQUEST[bits 31:24] + HWP_PACKAGE_LEVEL_REQUEST // IA32_HWP_REQUEST_PKG MSR + _ // Reserved (eax bit 12) + HDC // HDC base registers IA32_PKG_HDC_CTL, IA32_PM_CTL1, IA32_THREAD_STALL MSRs + TURBO_BOOST_MAX // Intel® Turbo Boost Max Technology + _ // Reserved (eax bit 15) + + // ECX bits 0-15 + HCFC // Hardware Coordination Feedback Capability + _ + _ + PERFORMANCE_ENERGY_BIAS // Processor supports performance-energy bias preference +) + +const ( + NULL = iota + DATA_CACHE + INSTRUCTION_CACHE + UNIFIED_CACHE + TLB + DTLB + STLB + PREFETCH +) diff --git a/vendor/github.com/intel-go/cpuid/cpuid_amd64.go b/vendor/github.com/intel-go/cpuid/cpuid_amd64.go new file mode 100644 index 0000000000..49f2716993 --- /dev/null +++ b/vendor/github.com/intel-go/cpuid/cpuid_amd64.go @@ -0,0 +1,595 @@ +// +build amd64 +// Copyright 2015 Intel Corporation. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cpuid provides access to the information available +// through the CPUID instruction. +// All information is gathered during package initialization phase +// so package's public interface doesn't call CPUID instruction. +package cpuid + +func cpuid_low(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32) // implemented in cpuidlow_amd64.s +func xgetbv_low(arg1 uint32) (eax, edx uint32) // implemented in cpuidlow_amd64.s + +func init() { + detectFeatures() +} + +func detectFeatures() { + leaf0() + leaf1() + leaf2() + leaf3() + leaf4() + leaf5() + leaf6() + leaf7() + leaf0x80000000() + leaf0x80000001() + leaf0x80000004() + leaf0x80000005() + leaf0x80000006() + + if HasFeature(OSXSAVE) { + eax, _ := xgetbv_low(0) + if (eax & 0x6) == 0x6 { + EnabledAVX = true + } + if (eax & 0xE0) == 0xE0 { + EnabledAVX512 = true + } + } +} + +var leaf02Names = [...]string{ + "NULL", + "DATA_CACHE", + "INSTRUCTION_CACHE", + "UNIFIED_CACHE", + "TLB", + "DTLB", + "STLB", + "PREFETCH", +} + +func leaf0() { + + eax, ebx, ecx, edx := cpuid_low(0, 0) + + maxInputValue = eax + + VendorIdentificatorString = string(int32sToBytes(ebx, edx, ecx)) + brandId = brandStrings[VendorIdentificatorString] +} + +func leaf1() { + + if maxInputValue < 1 { + return + } + + eax, ebx, ecx, edx := cpuid_low(1, 0) + // Parse EAX + SteppingId = (eax & 0xF) + modelId := (eax >> 4) & 0xF + familyId := (eax >> 8) & 0xF + ProcessorType = (eax >> 12) & 0x3 + ExtendedModelId := (eax >> 16) & 0xF + extendedFamilyId := (eax >> 20) & 0xFF + + DisplayFamily = familyId + DisplayModel = modelId + + if familyId == 0xF { + DisplayFamily = extendedFamilyId + familyId + } + + if familyId == 0x6 || familyId == 0xF { + DisplayModel = ExtendedModelId<<4 + modelId + } + + // Parse EBX + brandIndex = ebx & 0xFF + CacheLineSize = ((ebx >> 8) & 0xFF) << 3 + MaxLogocalCPUId = (ebx >> 16) & 0xFF + InitialAPICId = (ebx >> 24) + + // Parse ECX & EDX not needed. Ask through HasFeature function + featureFlags = (uint64(edx) << 32) | uint64(ecx) +} + +func leaf2() { + + if brandId != INTEL { + return + } + if maxInputValue < 2 { + return + } + + bytes := int32sToBytes(cpuid_low(2, 0)) + + for i := 0; i < len(bytes); i++ { + if (i%4 == 0) && (bytes[i+3]&(1<<7) != 0) { + i += 4 + continue + } + if bytes[i] == 0xFF { // it means that we should use leaf 4 for cache info + CacheDescriptors = CacheDescriptors[0:0] + break + } + CacheDescriptors = append(CacheDescriptors, leaf02Descriptors[int16(bytes[i])]) + } +} + +func leaf3() { + if brandId != INTEL { + return + } + + if maxInputValue < 3 { + return + } + // TODO SerialNumber for < Pentium 4 +} + +func leaf4() { + + if brandId != INTEL { + return + } + + if maxInputValue < 4 { + return + } + + cacheId := 0 + for { + eax, ebx, ecx, _ := cpuid_low(4, uint32(cacheId)) + cacheId++ + cacheType := eax & 0xF + + if cacheType == NULL { + break + } + + cacheLevel := (eax >> 5) & 0x7 + // selfInitializingCacheLevel := eax & (1<<8) + // fullyAssociativeCache := eax & (1<<9) + // maxNumLogicalCoresSharing := (eax >> 14) & 0x3FF + // maxNumPhisCores := (eax >> 26) & 0x3F + systemCoherencyLineSize := (ebx & 0xFFF) + 1 + physicalLinePartions := (ebx>>12)&0x3FF + 1 + waysOfAssiociativity := (ebx>>22)&0x3FF + 1 + numberOfSets := ecx + 1 + // writeBackInvalidate := edx & 1 + // cacheInclusiveness := edx & (1<<1) + // complexCacheIndexing := edx & (1<<2) + cacheSize := (waysOfAssiociativity * physicalLinePartions * + systemCoherencyLineSize * numberOfSets) >> 10 + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{int(cacheLevel), + int(cacheType), + "", + int(cacheSize), + int(waysOfAssiociativity), + int(systemCoherencyLineSize), + int(numberOfSets), + int(physicalLinePartions), + }) + } +} + +func leaf5() { + if maxInputValue < 5 { + return + } + + eax, ebx, ecx, _ := cpuid_low(4, 0) // TODO process EDX with C0-C7 C-states + MonLineSizeMax = eax & (0xFFFF) + MonLineSizeMax = ebx & (0xFFFF) + MonitorEMX = (ecx & (1 << 0)) != 0 + MonitorIBE = (ecx & (1 << 1)) != 0 + +} + +func leaf6() { + // Thermal and Power Management Features for Intel + if maxInputValue < 6 { + return + } + + eax, ebx, ecx, _ := cpuid_low(6, 0) + thermalAndPowerFeatureFlags = (eax & 0xFFFF) | (ecx << 16) + ThermalSensorInterruptThresholds = ebx & 7 +} + +func leaf7() { + _, ebx, ecx, _ := cpuid_low(7, 0) + extendedFeatureFlags = (uint64(ecx) << 32) | uint64(ebx) +} + +func leaf0x80000000() { + maxExtendedInputValue, _, _, _ = cpuid_low(0x80000000, 0) +} + +func leaf0x80000001() { + if maxExtendedInputValue < 0x80000001 { + return + } + _, _, ecx, edx := cpuid_low(0x80000001, 0) + //extendedProcessorSignatureAndFeatureBits := eax + extraFeatureFlags = (uint64(edx) << 32) | uint64(ecx) +} + +// leaf0x80000004 looks at the Processor Brand String in leaves 0x80000002 through 0x80000004 +func leaf0x80000004() { + if maxExtendedInputValue < 0x80000004 { + return + } + + ProcessorBrandString += string(int32sToBytes(cpuid_low(0x80000002, 0))) + ProcessorBrandString += string(int32sToBytes(cpuid_low(0x80000003, 0))) + ProcessorBrandString += string(int32sToBytes(cpuid_low(0x80000004, 0))) +} + +func leaf0x80000005() { + // AMD L1 Cache and TLB Information + if maxExtendedInputValue < 0x80000005 { + return + } + + if brandId != AMD { + return + } + + eax, ebx, ecx, edx := cpuid_low(0x80000005, 0) + + L1DTlb2and4MAssoc := (eax >> 24) & 0xFF + L1DTlb2and4MSize := (eax >> 16) & 0xFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{1, + DTLB, + "DTLB 2M/4M", + 2 * 1024, + int(L1DTlb2and4MAssoc), + -1, + int(L1DTlb2and4MSize), + 0, + }) + + L1ITlb2and4MAssoc := (eax >> 8) & 0xFF + L1ITlb2and4MSize := (eax) & 0xFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{1, + TLB, + "ITLB 2M/4M", + 2 * 1024, + int(L1ITlb2and4MAssoc), + -1, + int(L1ITlb2and4MSize), + 0, + }) + + L1DTlb4KAssoc := (ebx >> 24) & 0xFF + L1DTlb4KSize := (ebx >> 16) & 0xFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{1, + DTLB, + "DTLB 4K", + 4, + int(L1DTlb4KAssoc), + -1, + int(L1DTlb4KSize), + 0, + }) + + L1ITlb4KAssoc := (ebx >> 8) & 0xFF + L1ITlb4KSize := (ebx) & 0xFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{1, + TLB, + "ITLB 4K", + 4, + int(L1ITlb4KAssoc), + -1, + int(L1ITlb4KSize), + 0, + }) + + L1DcSize := (ecx >> 24) & 0xFF + L1DcAssoc := (ecx >> 16) & 0xFF + L1DcLinesPerTag := (ecx >> 8) & 0xFF + L1DcLineSize := (ecx >> 0) & 0xFF + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{1, + DATA_CACHE, + "L1 Data cache", + int(L1DcSize), + int(L1DcAssoc), + int(L1DcLineSize), + -1, + int(L1DcLinesPerTag), + }) + + L1IcSize := (edx >> 24) & 0xFF + L1IcAssoc := (edx >> 16) & 0xFF + L1IcLinesPerTag := (edx >> 8) & 0xFF + L1IcLineSize := (edx >> 0) & 0xFF + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{1, + INSTRUCTION_CACHE, + "L1 Instruction cache", + int(L1IcSize), + int(L1IcAssoc), + int(L1IcLineSize), + -1, + int(L1IcLinesPerTag), + }) +} + +func leaf0x80000006() { + + if maxExtendedInputValue < 0x80000006 { + return + } + + var associativityEncodings = map[uint]uint{ + 0x00: 0, + 0x01: 1, + 0x02: 2, + 0x04: 4, + 0x06: 8, + 0x08: 16, + 0x0A: 32, + 0x0B: 48, + 0x0C: 64, + 0x0D: 96, + 0x0E: 128, + 0x0F: 0xFF, // - Fully associative + } + + eax, ebx, ecx, edx := cpuid_low(0x80000006, 0) + + if brandId == INTEL { + + CacheLineSize := (ecx >> 0) & 0xFF + L2Associativity := uint((ecx >> 12) & 0xF) + CacheSize := (ecx >> 16) & 0xFFFF + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{2, + 0, + "Cache info from leaf 0x80000006 for Intel", + int(CacheSize), + int(associativityEncodings[L2Associativity]), + int(CacheLineSize), + -1, + 0, + }) + } + + if brandId == AMD { + + L2DTlb2and4MAssoc := uint((eax >> 28) & 0xF) + L2DTlb2and4MSize := (eax >> 16) & 0xFFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{2, + DTLB, + "DTLB 2M/4M", + 2 * 1024, + int(associativityEncodings[L2DTlb2and4MAssoc]), + -1, + int(L2DTlb2and4MSize), + 0, + }) + + L2ITlb2and4MAssoc := uint((eax >> 12) & 0xF) + L2ITlb2and4MSize := (eax) & 0xFFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{2, + TLB, + "ITLB 2M/4M", + 2 * 1024, + int(associativityEncodings[L2ITlb2and4MAssoc]), + -1, + int(L2ITlb2and4MSize), + 0, + }) + + L2DTlb4KAssoc := uint((ebx >> 28) & 0xF) + L2DTlb4KSize := (ebx >> 16) & 0xFFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{2, + DTLB, + "DTLB 4K", + 4, + int(associativityEncodings[L2DTlb4KAssoc]), + -1, + int(L2DTlb4KSize), + 0, + }) + + L2ITlb4KAssoc := uint((ebx >> 12) & 0xF) + L2ITlb4KSize := (ebx) & 0xFFF + + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{2, + TLB, + "ITLB 4K", + 4, + int(associativityEncodings[L2ITlb4KAssoc]), + -1, + int(L2ITlb4KSize), + 0, + }) + + L2Size := (ecx >> 16) & 0xFFFF + L2Assoc := uint((ecx >> 12) & 0xF) + L2LinesPerTag := (ecx >> 8) & 0xF + L2LineSize := (ecx >> 0) & 0xFF + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{2, + DATA_CACHE, + "L2 Data cache", + int(L2Size), + int(associativityEncodings[L2Assoc]), + int(L2LineSize), + -1, + int(L2LinesPerTag), + }) + + L3Size := ((edx >> 18) & 0xF) * 512 + L3Assoc := uint((edx >> 12) & 0xF) + L3LinesPerTag := (edx >> 8) & 0xF + L3LineSize := (edx >> 0) & 0xFF + CacheDescriptors = append(CacheDescriptors, + CacheDescriptor{3, + DATA_CACHE, + "L3 Data cache", + int(L3Size), + int(associativityEncodings[L3Assoc]), + int(L3LineSize), + -1, + int(L3LinesPerTag), + }) + } +} + +// TODO split fused descritops with bits in high key's byte like for 0x49 +var leaf02Descriptors = map[int16]CacheDescriptor{ + 0x01: {-1, TLB, "Instruction TLB", 4, 4, -1, 32, 0}, + 0x02: {-1, TLB, "Instruction TLB", 4 * 1024, 0xFF, -1, 2, 0}, + 0x03: {-1, TLB, "Data TLB", 4, 4, -1, 64, 0}, + 0x04: {-1, TLB, "Data TLB", 4 * 1024, 4, -1, 8, 0}, + 0x05: {-1, TLB, "Data TLB1", 4 * 1024, 4, -1, 32, 0}, + 0x06: {1, INSTRUCTION_CACHE, "1st-level instruction cache", 8, 4, 32, -1, 0}, + 0x08: {1, INSTRUCTION_CACHE, "1st-level instruction cache", 16, 4, 32, -1, 0}, + 0x09: {1, INSTRUCTION_CACHE, "1st-level instruction cache", 32, 4, 64, -1, 0}, + 0x0A: {1, DATA_CACHE, "1st-level data cache", 8, 2, 32, -1, 0}, + 0x0B: {-1, TLB, "Instruction TLB", 4 * 1024, 4, -1, 4, 0}, + 0x0C: {1, DATA_CACHE, "1st-level data cache", 16, 4, 32, -1, 0}, + 0x0D: {1, DATA_CACHE, "1st-level data cache", 16, 4, 64, -1, 0}, + 0x0E: {1, DATA_CACHE, "1st-level data cache", 24, 6, 64, -1, 0}, + 0x1D: {2, DATA_CACHE, "2nd-level cache", 128, 2, 64, -1, 0}, + 0x21: {2, DATA_CACHE, "2nd-level cache", 256, 8, 64, -1, 0}, + 0x22: {3, DATA_CACHE, "3nd-level cache", 512, 4, 64, -1, 2}, + 0x23: {3, DATA_CACHE, "3nd-level cache", 1 * 1024, 8, 64, -1, 2}, + 0x24: {2, DATA_CACHE, "2nd-level cache", 1 * 1024, 16, 64, -1, 0}, + 0x25: {3, DATA_CACHE, "3nd-level cache", 2 * 1024, 8, 64, -1, 2}, + 0x29: {3, DATA_CACHE, "2nd-level cache", 4 * 1024, 8, 64, -1, 2}, + 0x2C: {1, DATA_CACHE, "1st-level cache", 32, 8, 64, -1, 0}, + 0x30: {1, INSTRUCTION_CACHE, "1st-level instruction cache", 32, 8, 64, -1, 0}, + 0x40: {-1, DATA_CACHE, "No 2nd-level cache or, if processor contains a " + + "valid 2nd-level cache, no 3rd-level cache", -1, -1, -1, -1, 0}, + 0x41: {2, DATA_CACHE, "2nd-level cache", 128, 4, 32, -1, 0}, + 0x42: {2, DATA_CACHE, "2nd-level cache", 256, 4, 32, -1, 0}, + 0x43: {2, DATA_CACHE, "2nd-level cache", 512, 4, 32, -1, 0}, + 0x44: {2, DATA_CACHE, "2nd-level cache", 1 * 1024, 4, 32, -1, 0}, + 0x45: {2, DATA_CACHE, "2nd-level cache", 2 * 1024, 4, 32, -1, 0}, + 0x46: {3, DATA_CACHE, "3nd-level cache", 4 * 1024, 4, 64, -1, 0}, + 0x47: {3, DATA_CACHE, "3nd-level cache", 8 * 1024, 8, 64, -1, 0}, + 0x48: {2, DATA_CACHE, "2nd-level cache", 3 * 1024, 12, 64, -1, 0}, + 0x49: {2, DATA_CACHE, "2nd-level cache", 4 * 1024, 16, 64, -1, 0}, + // (Intel Xeon processor MP, Family 0FH, Model 06H) + (0x49 | (1 << 8)): {3, DATA_CACHE, "3nd-level cache", 4 * 1024, 16, 64, -1, 0}, + 0x4A: {3, DATA_CACHE, "3nd-level cache", 6 * 1024, 12, 64, -1, 0}, + 0x4B: {3, DATA_CACHE, "3nd-level cache", 8 * 1024, 16, 64, -1, 0}, + 0x4C: {3, DATA_CACHE, "3nd-level cache", 12 * 1024, 12, 64, -1, 0}, + 0x4D: {3, DATA_CACHE, "3nd-level cache", 16 * 1024, 16, 64, -1, 0}, + 0x4E: {2, DATA_CACHE, "3nd-level cache", 6 * 1024, 24, 64, -1, 0}, + 0x4F: {-1, TLB, "Instruction TLB", 4, -1, -1, 32, 0}, + 0x50: {-1, TLB, "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages", 4, -1, -1, 64, 0}, + 0x51: {-1, TLB, "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages", 4, -1, -1, 128, 0}, + 0x52: {-1, TLB, "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages", 4, -1, -1, 256, 0}, + 0x55: {-1, TLB, "Instruction TLB: 2-MByte or 4-MByte pages", 2 * 1024, 0xFF, -1, 7, 0}, + 0x56: {-1, TLB, "Data TLB0", 4 * 1024, 4, -1, 16, 0}, + 0x57: {-1, TLB, "Data TLB0", 4, 4, -1, 16, 0}, + 0x59: {-1, TLB, "Data TLB0", 4, 0xFF, -1, 16, 0}, + 0x5A: {-1, TLB, "Data TLB0 2-MByte or 4 MByte pages", 2 * 1024, 4, -1, 32, 0}, + 0x5B: {-1, TLB, "Data TLB 4 KByte and 4 MByte pages", 4, -1, -1, 64, 0}, + 0x5C: {-1, TLB, "Data TLB 4 KByte and 4 MByte pages", 4, -1, -1, 128, 0}, + 0x5D: {-1, TLB, "Data TLB 4 KByte and 4 MByte pages", 4, -1, -1, 256, 0}, + 0x60: {1, DATA_CACHE, "1st-level data cache", 16, 8, 64, -1, 0}, + 0x61: {-1, TLB, "Instruction TLB", 4, 0xFF, -1, 48, 0}, + 0x63: {-1, TLB, "Data TLB", 1 * 1024 * 1024, 4, -1, 4, 0}, + 0x66: {1, DATA_CACHE, "1st-level data cache", 8, 4, 64, -1, 0}, + 0x67: {1, DATA_CACHE, "1st-level data cache", 16, 4, 64, -1, 0}, + 0x68: {1, DATA_CACHE, "1st-level data cache", 32, 4, 64, -1, 0}, + 0x70: {1, INSTRUCTION_CACHE, "Trace cache (size in K of uop)", 12, 8, -1, -1, 0}, + 0x71: {1, INSTRUCTION_CACHE, "Trace cache (size in K of uop)", 16, 8, -1, -1, 0}, + 0x72: {1, INSTRUCTION_CACHE, "Trace cache (size in K of uop)", 32, 8, -1, -1, 0}, + 0x76: {-1, TLB, "Instruction TLB: 2M/4M pages", 2 * 1024, 0xFF, -1, 8, 0}, + 0x78: {2, DATA_CACHE, "2nd-level cache", 1 * 1024, 4, 64, -1, 0}, + 0x79: {2, DATA_CACHE, "2nd-level cache", 128, 8, 64, -1, 2}, + 0x7A: {2, DATA_CACHE, "2nd-level cache", 256, 8, 64, -1, 2}, + 0x7B: {2, DATA_CACHE, "2nd-level cache", 512, 8, 64, -1, 2}, + 0x7C: {2, DATA_CACHE, "2nd-level cache", 1 * 1024, 8, 64, -1, 2}, + 0x7D: {2, DATA_CACHE, "2nd-level cache", 2 * 1024, 8, 64, -1, 0}, + 0x7F: {2, DATA_CACHE, "2nd-level cache", 512, 2, 64, -1, 0}, + 0x80: {2, DATA_CACHE, "2nd-level cache", 512, 8, 64, -1, 0}, + 0x82: {2, DATA_CACHE, "2nd-level cache", 256, 8, 32, -1, 0}, + 0x83: {2, DATA_CACHE, "2nd-level cache", 512, 8, 32, -1, 0}, + 0x84: {2, DATA_CACHE, "2nd-level cache", 1 * 1024, 8, 32, -1, 0}, + 0x85: {2, DATA_CACHE, "2nd-level cache", 2 * 1024, 8, 32, -1, 0}, + 0x86: {2, DATA_CACHE, "2nd-level cache", 512, 4, 32, -1, 0}, + 0x87: {2, DATA_CACHE, "2nd-level cache", 1 * 1024, 8, 64, -1, 0}, + 0xA0: {-1, DTLB, "DTLB", 4, 0xFF, -1, 32, 0}, + 0xB0: {-1, TLB, "Instruction TLB", 4, 4, -1, 128, 0}, + 0xB1: {-1, TLB, "Instruction TLB 2M pages 4 way 8 entries or" + + "4M pages 4-way, 4 entries", 2 * 1024, 4, -1, 8, 0}, + 0xB2: {-1, TLB, "Instruction TLB", 4, 4, -1, 64, 0}, + 0xB3: {-1, TLB, "Data TLB", 4, 4, -1, 128, 0}, + 0xB4: {-1, TLB, "Data TLB1", 4, 4, -1, 256, 0}, + 0xB5: {-1, TLB, "Instruction TLB", 4, 8, -1, 64, 0}, + 0xB6: {-1, TLB, "Instruction TLB", 4, 8, -1, 128, 0}, + 0xBA: {-1, TLB, "Data TLB1", 4, 4, -1, 64, 0}, + 0xC0: {-1, TLB, "Data TLB: 4 KByte and 4 MByte pages", 4, 4, -1, 8, 0}, + 0xC1: {-1, STLB, "Shared 2nd-Level TLB: 4Kbyte and 2Mbyte pages", 4, 8, -1, 1024, 0}, + 0xC2: {-1, DTLB, "DTLB 4KByte/2 MByte pages", 4, 4, -1, 16, 0}, + 0xC3: {-1, STLB, "Shared 2nd-Level TLB: " + + "4 KByte /2 MByte pages, 6-way associative, 1536 entries." + + "Also 1GBbyte pages, 4-way,16 entries.", 4, 6, -1, 1536, 0}, + 0xCA: {-1, STLB, "Shared 2nd-Level TLB", 4, 4, -1, 512, 0}, + 0xD0: {3, DATA_CACHE, "3nd-level cache", 512, 4, 64, -1, 0}, + 0xD1: {3, DATA_CACHE, "3nd-level cache", 1 * 1024, 4, 64, -1, 0}, + 0xD2: {3, DATA_CACHE, "3nd-level cache", 2 * 1024, 4, 64, -1, 0}, + 0xD6: {3, DATA_CACHE, "3nd-level cache", 1 * 1024, 8, 64, -1, 0}, + 0xD7: {3, DATA_CACHE, "3nd-level cache", 2 * 1024, 8, 64, -1, 0}, + 0xD8: {3, DATA_CACHE, "3nd-level cache", 4 * 1024, 8, 64, -1, 0}, + 0xDC: {3, DATA_CACHE, "3nd-level cache", 1 * 1536, 12, 64, -1, 0}, + 0xDD: {3, DATA_CACHE, "3nd-level cache", 3 * 1024, 12, 64, -1, 0}, + 0xDE: {3, DATA_CACHE, "3nd-level cache", 6 * 1024, 12, 64, -1, 0}, + 0xE2: {3, DATA_CACHE, "3nd-level cache", 2 * 1024, 16, 64, -1, 0}, + 0xE3: {3, DATA_CACHE, "3nd-level cache", 4 * 1024, 16, 64, -1, 0}, + 0xE4: {3, DATA_CACHE, "3nd-level cache", 8 * 1024, 16, 64, -1, 0}, + 0xEA: {3, DATA_CACHE, "3nd-level cache", 12 * 1024, 24, 64, -1, 0}, + 0xEB: {3, DATA_CACHE, "3nd-level cache", 18 * 1024, 24, 64, -1, 0}, + 0xEC: {3, DATA_CACHE, "3nd-level cache", 24 * 1024, 24, 64, -1, 0}, + 0xF0: {-1, PREFETCH, "", 64, -1, -1, -1, 0}, + 0xF1: {-1, PREFETCH, "", 128, -1, -1, -1, 0}, + 0xFF: {-1, NULL, "CPUID leaf 2 does not report cache descriptor " + + "information, use CPUID leaf 4 to query cache parameters", + -1, -1, -1, -1, 0}, +} + +func int32sToBytes(args ...uint32) []byte { + var result []byte + + for _, arg := range args { + result = append(result, + byte((arg)&0xFF), + byte((arg>>8)&0xFF), + byte((arg>>16)&0xFF), + byte((arg>>24)&0xFF)) + } + + return result +} diff --git a/vendor/github.com/intel-go/cpuid/cpuidlow_amd64.s b/vendor/github.com/intel-go/cpuid/cpuidlow_amd64.s new file mode 100644 index 0000000000..20da845a6a --- /dev/null +++ b/vendor/github.com/intel-go/cpuid/cpuidlow_amd64.s @@ -0,0 +1,24 @@ +// Copyright 2017 Intel Corporation. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +#include "textflag.h" + +// func cpuid_low(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuid_low(SB),NOSPLIT,$0-24 + MOVL arg1+0(FP), AX + MOVL arg2+4(FP), CX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET +// func xgetbv_low(arg1 uint32) (eax, edx uint32) + TEXT ·xgetbv_low(SB),NOSPLIT,$0-16 + MOVL arg1+0(FP), CX + BYTE $0x0F + BYTE $0x01 + BYTE $0xD0 + MOVL AX,eax+8(FP) + MOVL DX,edx+12(FP) + RET diff --git a/vendor/github.com/jinzhu/copier/Guardfile b/vendor/github.com/jinzhu/copier/Guardfile new file mode 100644 index 0000000000..0b860b0653 --- /dev/null +++ b/vendor/github.com/jinzhu/copier/Guardfile @@ -0,0 +1,3 @@ +guard 'gotest' do + watch(%r{\.go$}) +end diff --git a/vendor/github.com/jinzhu/copier/License b/vendor/github.com/jinzhu/copier/License new file mode 100644 index 0000000000..e2dc5381e1 --- /dev/null +++ b/vendor/github.com/jinzhu/copier/License @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jinzhu + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/jinzhu/copier/README.md b/vendor/github.com/jinzhu/copier/README.md new file mode 100644 index 0000000000..f929b46793 --- /dev/null +++ b/vendor/github.com/jinzhu/copier/README.md @@ -0,0 +1,100 @@ +# Copier + + I am a copier, I copy everything from one to another + +[![wercker status](https://app.wercker.com/status/9d44ad2d4e6253929c8fb71359effc0b/s/master "wercker status")](https://app.wercker.com/project/byKey/9d44ad2d4e6253929c8fb71359effc0b) + +## Features + +* Copy from field to field with same name +* Copy from method to field with same name +* Copy from field to method with same name +* Copy from slice to slice +* Copy from struct to slice + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/jinzhu/copier" +) + +type User struct { + Name string + Role string + Age int32 +} + +func (user *User) DoubleAge() int32 { + return 2 * user.Age +} + +type Employee struct { + Name string + Age int32 + DoubleAge int32 + EmployeId int64 + SuperRule string +} + +func (employee *Employee) Role(role string) { + employee.SuperRule = "Super " + role +} + +func main() { + var ( + user = User{Name: "Jinzhu", Age: 18, Role: "Admin"} + users = []User{{Name: "Jinzhu", Age: 18, Role: "Admin"}, {Name: "jinzhu 2", Age: 30, Role: "Dev"}} + employee = Employee{} + employees = []Employee{} + ) + + copier.Copy(&employee, &user) + + fmt.Printf("%#v \n", employee) + // Employee{ + // Name: "Jinzhu", // Copy from field + // Age: 18, // Copy from field + // DoubleAge: 36, // Copy from method + // EmployeeId: 0, // Ignored + // SuperRule: "Super Admin", // Copy to method + // } + + // Copy struct to slice + copier.Copy(&employees, &user) + + fmt.Printf("%#v \n", employees) + // []Employee{ + // {Name: "Jinzhu", Age: 18, DoubleAge: 36, EmployeId: 0, SuperRule: "Super Admin"} + // } + + // Copy slice to slice + employees = []Employee{} + copier.Copy(&employees, &users) + + fmt.Printf("%#v \n", employees) + // []Employee{ + // {Name: "Jinzhu", Age: 18, DoubleAge: 36, EmployeId: 0, SuperRule: "Super Admin"}, + // {Name: "jinzhu 2", Age: 30, DoubleAge: 60, EmployeId: 0, SuperRule: "Super Dev"}, + // } +} +``` + +## Contributing + +You can help to make the project better, check out [http://gorm.io/contribute.html](http://gorm.io/contribute.html) for things you can do. + +# Author + +**jinzhu** + +* +* +* + +## License + +Released under the [MIT License](https://github.com/jinzhu/copier/blob/master/License). diff --git a/vendor/github.com/jinzhu/copier/copier.go b/vendor/github.com/jinzhu/copier/copier.go new file mode 100644 index 0000000000..ecbddffb0f --- /dev/null +++ b/vendor/github.com/jinzhu/copier/copier.go @@ -0,0 +1,185 @@ +package copier + +import ( + "database/sql" + "errors" + "reflect" +) + +// Copy copy things +func Copy(toValue interface{}, fromValue interface{}) (err error) { + var ( + isSlice bool + amount = 1 + from = indirect(reflect.ValueOf(fromValue)) + to = indirect(reflect.ValueOf(toValue)) + ) + + if !to.CanAddr() { + return errors.New("copy to value is unaddressable") + } + + // Return is from value is invalid + if !from.IsValid() { + return + } + + // Just set it if possible to assign + if from.Type().AssignableTo(to.Type()) { + to.Set(from) + return + } + + fromType := indirectType(from.Type()) + toType := indirectType(to.Type()) + + if fromType.Kind() != reflect.Struct || toType.Kind() != reflect.Struct { + return + } + + if to.Kind() == reflect.Slice { + isSlice = true + if from.Kind() == reflect.Slice { + amount = from.Len() + } + } + + for i := 0; i < amount; i++ { + var dest, source reflect.Value + + if isSlice { + // source + if from.Kind() == reflect.Slice { + source = indirect(from.Index(i)) + } else { + source = indirect(from) + } + + // dest + dest = indirect(reflect.New(toType).Elem()) + } else { + source = indirect(from) + dest = indirect(to) + } + + // Copy from field to field or method + for _, field := range deepFields(fromType) { + name := field.Name + + if fromField := source.FieldByName(name); fromField.IsValid() { + // has field + if toField := dest.FieldByName(name); toField.IsValid() { + if toField.CanSet() { + if !set(toField, fromField) { + if err := Copy(toField.Addr().Interface(), fromField.Interface()); err != nil { + return err + } + } + } + } else { + // try to set to method + var toMethod reflect.Value + if dest.CanAddr() { + toMethod = dest.Addr().MethodByName(name) + } else { + toMethod = dest.MethodByName(name) + } + + if toMethod.IsValid() && toMethod.Type().NumIn() == 1 && fromField.Type().AssignableTo(toMethod.Type().In(0)) { + toMethod.Call([]reflect.Value{fromField}) + } + } + } + } + + // Copy from method to field + for _, field := range deepFields(toType) { + name := field.Name + + var fromMethod reflect.Value + if source.CanAddr() { + fromMethod = source.Addr().MethodByName(name) + } else { + fromMethod = source.MethodByName(name) + } + + if fromMethod.IsValid() && fromMethod.Type().NumIn() == 0 && fromMethod.Type().NumOut() == 1 { + if toField := dest.FieldByName(name); toField.IsValid() && toField.CanSet() { + values := fromMethod.Call([]reflect.Value{}) + if len(values) >= 1 { + set(toField, values[0]) + } + } + } + } + + if isSlice { + if dest.Addr().Type().AssignableTo(to.Type().Elem()) { + to.Set(reflect.Append(to, dest.Addr())) + } else if dest.Type().AssignableTo(to.Type().Elem()) { + to.Set(reflect.Append(to, dest)) + } + } + } + return +} + +func deepFields(reflectType reflect.Type) []reflect.StructField { + var fields []reflect.StructField + + if reflectType = indirectType(reflectType); reflectType.Kind() == reflect.Struct { + for i := 0; i < reflectType.NumField(); i++ { + v := reflectType.Field(i) + if v.Anonymous { + fields = append(fields, deepFields(v.Type)...) + } else { + fields = append(fields, v) + } + } + } + + return fields +} + +func indirect(reflectValue reflect.Value) reflect.Value { + for reflectValue.Kind() == reflect.Ptr { + reflectValue = reflectValue.Elem() + } + return reflectValue +} + +func indirectType(reflectType reflect.Type) reflect.Type { + for reflectType.Kind() == reflect.Ptr || reflectType.Kind() == reflect.Slice { + reflectType = reflectType.Elem() + } + return reflectType +} + +func set(to, from reflect.Value) bool { + if from.IsValid() { + if to.Kind() == reflect.Ptr { + //set `to` to nil if from is nil + if from.Kind() == reflect.Ptr && from.IsNil() { + to.Set(reflect.Zero(to.Type())) + return true + } else if to.IsNil() { + to.Set(reflect.New(to.Type().Elem())) + } + to = to.Elem() + } + + if from.Type().ConvertibleTo(to.Type()) { + to.Set(from.Convert(to.Type())) + } else if scanner, ok := to.Addr().Interface().(sql.Scanner); ok { + err := scanner.Scan(from.Interface()) + if err != nil { + return false + } + } else if from.Kind() == reflect.Ptr { + return set(to, from.Elem()) + } else { + return false + } + } + return true +} diff --git a/vendor/github.com/jinzhu/copier/wercker.yml b/vendor/github.com/jinzhu/copier/wercker.yml new file mode 100644 index 0000000000..5e6ce981dc --- /dev/null +++ b/vendor/github.com/jinzhu/copier/wercker.yml @@ -0,0 +1,23 @@ +box: golang + +build: + steps: + - setup-go-workspace + + # Gets the dependencies + - script: + name: go get + code: | + go get + + # Build the project + - script: + name: go build + code: | + go build ./... + + # Test the project + - script: + name: go test + code: | + go test ./... diff --git a/vendor/github.com/jmespath/go-jmespath/.gitignore b/vendor/github.com/jmespath/go-jmespath/.gitignore new file mode 100644 index 0000000000..531fcc11c7 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/.gitignore @@ -0,0 +1,4 @@ +jpgo +jmespath-fuzz.zip +cpu.out +go-jmespath.test diff --git a/vendor/github.com/jmespath/go-jmespath/.travis.yml b/vendor/github.com/jmespath/go-jmespath/.travis.yml new file mode 100644 index 0000000000..1f98077570 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/.travis.yml @@ -0,0 +1,9 @@ +language: go + +sudo: false + +go: + - 1.4 + +install: go get -v -t ./... +script: make test diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/github.com/jmespath/go-jmespath/LICENSE new file mode 100644 index 0000000000..b03310a91f --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/LICENSE @@ -0,0 +1,13 @@ +Copyright 2015 James Saryerwinnie + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/github.com/jmespath/go-jmespath/Makefile b/vendor/github.com/jmespath/go-jmespath/Makefile new file mode 100644 index 0000000000..ad17bf0012 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/Makefile @@ -0,0 +1,44 @@ + +CMD = jpgo + +help: + @echo "Please use \`make ' where is one of" + @echo " test to run all the tests" + @echo " build to build the library and jp executable" + @echo " generate to run codegen" + + +generate: + go generate ./... + +build: + rm -f $(CMD) + go build ./... + rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./... + mv cmd/$(CMD)/$(CMD) . + +test: + go test -v ./... + +check: + go vet ./... + @echo "golint ./..." + @lint=`golint ./...`; \ + lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \ + echo "$$lint"; \ + if [ "$$lint" != "" ]; then exit 1; fi + +htmlc: + go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov + +buildfuzz: + go-fuzz-build github.com/jmespath/go-jmespath/fuzz + +fuzz: buildfuzz + go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/corpus + +bench: + go test -bench . -cpuprofile cpu.out + +pprof-cpu: + go tool pprof ./go-jmespath.test ./cpu.out diff --git a/vendor/github.com/jmespath/go-jmespath/README.md b/vendor/github.com/jmespath/go-jmespath/README.md new file mode 100644 index 0000000000..187ef676dc --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/README.md @@ -0,0 +1,7 @@ +# go-jmespath - A JMESPath implementation in Go + +[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath) + + + +See http://jmespath.org for more info. diff --git a/vendor/github.com/jmespath/go-jmespath/api.go b/vendor/github.com/jmespath/go-jmespath/api.go new file mode 100644 index 0000000000..67df3fc1c8 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/api.go @@ -0,0 +1,12 @@ +package jmespath + +// Search evaluates a JMESPath expression against input data and returns the result. +func Search(expression string, data interface{}) (interface{}, error) { + intr := newInterpreter() + parser := NewParser() + ast, err := parser.Parse(expression) + if err != nil { + return nil, err + } + return intr.Execute(ast, data) +} diff --git a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go new file mode 100644 index 0000000000..1cd2d239c9 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type astNodeType; DO NOT EDIT + +package jmespath + +import "fmt" + +const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection" + +var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307} + +func (i astNodeType) String() string { + if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) { + return fmt.Sprintf("astNodeType(%d)", i) + } + return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]] +} diff --git a/vendor/github.com/jmespath/go-jmespath/functions.go b/vendor/github.com/jmespath/go-jmespath/functions.go new file mode 100644 index 0000000000..8a3f2ef0dc --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/functions.go @@ -0,0 +1,840 @@ +package jmespath + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "sort" + "strconv" + "strings" + "unicode/utf8" +) + +type jpFunction func(arguments []interface{}) (interface{}, error) + +type jpType string + +const ( + jpUnknown jpType = "unknown" + jpNumber jpType = "number" + jpString jpType = "string" + jpArray jpType = "array" + jpObject jpType = "object" + jpArrayNumber jpType = "array[number]" + jpArrayString jpType = "array[string]" + jpExpref jpType = "expref" + jpAny jpType = "any" +) + +type functionEntry struct { + name string + arguments []argSpec + handler jpFunction + hasExpRef bool +} + +type argSpec struct { + types []jpType + variadic bool +} + +type byExprString struct { + intr *treeInterpreter + node ASTNode + items []interface{} + hasError bool +} + +func (a *byExprString) Len() int { + return len(a.items) +} +func (a *byExprString) Swap(i, j int) { + a.items[i], a.items[j] = a.items[j], a.items[i] +} +func (a *byExprString) Less(i, j int) bool { + first, err := a.intr.Execute(a.node, a.items[i]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + ith, ok := first.(string) + if !ok { + a.hasError = true + return true + } + second, err := a.intr.Execute(a.node, a.items[j]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + jth, ok := second.(string) + if !ok { + a.hasError = true + return true + } + return ith < jth +} + +type byExprFloat struct { + intr *treeInterpreter + node ASTNode + items []interface{} + hasError bool +} + +func (a *byExprFloat) Len() int { + return len(a.items) +} +func (a *byExprFloat) Swap(i, j int) { + a.items[i], a.items[j] = a.items[j], a.items[i] +} +func (a *byExprFloat) Less(i, j int) bool { + first, err := a.intr.Execute(a.node, a.items[i]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + ith, ok := first.(float64) + if !ok { + a.hasError = true + return true + } + second, err := a.intr.Execute(a.node, a.items[j]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + jth, ok := second.(float64) + if !ok { + a.hasError = true + return true + } + return ith < jth +} + +type functionCaller struct { + functionTable map[string]functionEntry +} + +func newFunctionCaller() *functionCaller { + caller := &functionCaller{} + caller.functionTable = map[string]functionEntry{ + "length": functionEntry{ + name: "length", + arguments: []argSpec{ + argSpec{types: []jpType{jpString, jpArray, jpObject}}, + }, + handler: jpfLength, + }, + "starts_with": functionEntry{ + name: "starts_with", + arguments: []argSpec{ + argSpec{types: []jpType{jpString}}, + argSpec{types: []jpType{jpString}}, + }, + handler: jpfStartsWith, + }, + "abs": functionEntry{ + name: "abs", + arguments: []argSpec{ + argSpec{types: []jpType{jpNumber}}, + }, + handler: jpfAbs, + }, + "avg": functionEntry{ + name: "avg", + arguments: []argSpec{ + argSpec{types: []jpType{jpArrayNumber}}, + }, + handler: jpfAvg, + }, + "ceil": functionEntry{ + name: "ceil", + arguments: []argSpec{ + argSpec{types: []jpType{jpNumber}}, + }, + handler: jpfCeil, + }, + "contains": functionEntry{ + name: "contains", + arguments: []argSpec{ + argSpec{types: []jpType{jpArray, jpString}}, + argSpec{types: []jpType{jpAny}}, + }, + handler: jpfContains, + }, + "ends_with": functionEntry{ + name: "ends_with", + arguments: []argSpec{ + argSpec{types: []jpType{jpString}}, + argSpec{types: []jpType{jpString}}, + }, + handler: jpfEndsWith, + }, + "floor": functionEntry{ + name: "floor", + arguments: []argSpec{ + argSpec{types: []jpType{jpNumber}}, + }, + handler: jpfFloor, + }, + "map": functionEntry{ + name: "amp", + arguments: []argSpec{ + argSpec{types: []jpType{jpExpref}}, + argSpec{types: []jpType{jpArray}}, + }, + handler: jpfMap, + hasExpRef: true, + }, + "max": functionEntry{ + name: "max", + arguments: []argSpec{ + argSpec{types: []jpType{jpArrayNumber, jpArrayString}}, + }, + handler: jpfMax, + }, + "merge": functionEntry{ + name: "merge", + arguments: []argSpec{ + argSpec{types: []jpType{jpObject}, variadic: true}, + }, + handler: jpfMerge, + }, + "max_by": functionEntry{ + name: "max_by", + arguments: []argSpec{ + argSpec{types: []jpType{jpArray}}, + argSpec{types: []jpType{jpExpref}}, + }, + handler: jpfMaxBy, + hasExpRef: true, + }, + "sum": functionEntry{ + name: "sum", + arguments: []argSpec{ + argSpec{types: []jpType{jpArrayNumber}}, + }, + handler: jpfSum, + }, + "min": functionEntry{ + name: "min", + arguments: []argSpec{ + argSpec{types: []jpType{jpArrayNumber, jpArrayString}}, + }, + handler: jpfMin, + }, + "min_by": functionEntry{ + name: "min_by", + arguments: []argSpec{ + argSpec{types: []jpType{jpArray}}, + argSpec{types: []jpType{jpExpref}}, + }, + handler: jpfMinBy, + hasExpRef: true, + }, + "type": functionEntry{ + name: "type", + arguments: []argSpec{ + argSpec{types: []jpType{jpAny}}, + }, + handler: jpfType, + }, + "keys": functionEntry{ + name: "keys", + arguments: []argSpec{ + argSpec{types: []jpType{jpObject}}, + }, + handler: jpfKeys, + }, + "values": functionEntry{ + name: "values", + arguments: []argSpec{ + argSpec{types: []jpType{jpObject}}, + }, + handler: jpfValues, + }, + "sort": functionEntry{ + name: "sort", + arguments: []argSpec{ + argSpec{types: []jpType{jpArrayString, jpArrayNumber}}, + }, + handler: jpfSort, + }, + "sort_by": functionEntry{ + name: "sort_by", + arguments: []argSpec{ + argSpec{types: []jpType{jpArray}}, + argSpec{types: []jpType{jpExpref}}, + }, + handler: jpfSortBy, + hasExpRef: true, + }, + "join": functionEntry{ + name: "join", + arguments: []argSpec{ + argSpec{types: []jpType{jpString}}, + argSpec{types: []jpType{jpArrayString}}, + }, + handler: jpfJoin, + }, + "reverse": functionEntry{ + name: "reverse", + arguments: []argSpec{ + argSpec{types: []jpType{jpArray, jpString}}, + }, + handler: jpfReverse, + }, + "to_array": functionEntry{ + name: "to_array", + arguments: []argSpec{ + argSpec{types: []jpType{jpAny}}, + }, + handler: jpfToArray, + }, + "to_string": functionEntry{ + name: "to_string", + arguments: []argSpec{ + argSpec{types: []jpType{jpAny}}, + }, + handler: jpfToString, + }, + "to_number": functionEntry{ + name: "to_number", + arguments: []argSpec{ + argSpec{types: []jpType{jpAny}}, + }, + handler: jpfToNumber, + }, + "not_null": functionEntry{ + name: "not_null", + arguments: []argSpec{ + argSpec{types: []jpType{jpAny}, variadic: true}, + }, + handler: jpfNotNull, + }, + } + return caller +} + +func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) { + if len(e.arguments) == 0 { + return arguments, nil + } + if !e.arguments[len(e.arguments)-1].variadic { + if len(e.arguments) != len(arguments) { + return nil, errors.New("incorrect number of args") + } + for i, spec := range e.arguments { + userArg := arguments[i] + err := spec.typeCheck(userArg) + if err != nil { + return nil, err + } + } + return arguments, nil + } + if len(arguments) < len(e.arguments) { + return nil, errors.New("Invalid arity.") + } + return arguments, nil +} + +func (a *argSpec) typeCheck(arg interface{}) error { + for _, t := range a.types { + switch t { + case jpNumber: + if _, ok := arg.(float64); ok { + return nil + } + case jpString: + if _, ok := arg.(string); ok { + return nil + } + case jpArray: + if _, ok := arg.([]interface{}); ok { + return nil + } + case jpObject: + if _, ok := arg.(map[string]interface{}); ok { + return nil + } + case jpArrayNumber: + if _, ok := toArrayNum(arg); ok { + return nil + } + case jpArrayString: + if _, ok := toArrayStr(arg); ok { + return nil + } + case jpAny: + return nil + case jpExpref: + if _, ok := arg.(expRef); ok { + return nil + } + } + } + return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types) +} + +func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) { + entry, ok := f.functionTable[name] + if !ok { + return nil, errors.New("unknown function: " + name) + } + resolvedArgs, err := entry.resolveArgs(arguments) + if err != nil { + return nil, err + } + if entry.hasExpRef { + var extra []interface{} + extra = append(extra, intr) + resolvedArgs = append(extra, resolvedArgs...) + } + return entry.handler(resolvedArgs) +} + +func jpfAbs(arguments []interface{}) (interface{}, error) { + num := arguments[0].(float64) + return math.Abs(num), nil +} + +func jpfLength(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if c, ok := arg.(string); ok { + return float64(utf8.RuneCountInString(c)), nil + } else if c, ok := arg.([]interface{}); ok { + return float64(len(c)), nil + } else if c, ok := arg.(map[string]interface{}); ok { + return float64(len(c)), nil + } + return nil, errors.New("could not compute length()") +} + +func jpfStartsWith(arguments []interface{}) (interface{}, error) { + search := arguments[0].(string) + prefix := arguments[1].(string) + return strings.HasPrefix(search, prefix), nil +} + +func jpfAvg(arguments []interface{}) (interface{}, error) { + // We've already type checked the value so we can safely use + // type assertions. + args := arguments[0].([]interface{}) + length := float64(len(args)) + numerator := 0.0 + for _, n := range args { + numerator += n.(float64) + } + return numerator / length, nil +} +func jpfCeil(arguments []interface{}) (interface{}, error) { + val := arguments[0].(float64) + return math.Ceil(val), nil +} +func jpfContains(arguments []interface{}) (interface{}, error) { + search := arguments[0] + el := arguments[1] + if searchStr, ok := search.(string); ok { + if elStr, ok := el.(string); ok { + return strings.Index(searchStr, elStr) != -1, nil + } + return false, nil + } + // Otherwise this is a generic contains for []interface{} + general := search.([]interface{}) + for _, item := range general { + if item == el { + return true, nil + } + } + return false, nil +} +func jpfEndsWith(arguments []interface{}) (interface{}, error) { + search := arguments[0].(string) + suffix := arguments[1].(string) + return strings.HasSuffix(search, suffix), nil +} +func jpfFloor(arguments []interface{}) (interface{}, error) { + val := arguments[0].(float64) + return math.Floor(val), nil +} +func jpfMap(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + exp := arguments[1].(expRef) + node := exp.ref + arr := arguments[2].([]interface{}) + mapped := make([]interface{}, 0, len(arr)) + for _, value := range arr { + current, err := intr.Execute(node, value) + if err != nil { + return nil, err + } + mapped = append(mapped, current) + } + return mapped, nil +} +func jpfMax(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item > best { + best = item + } + } + return best, nil + } + // Otherwise we're dealing with a max() of strings. + items, _ := toArrayStr(arguments[0]) + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item > best { + best = item + } + } + return best, nil +} +func jpfMerge(arguments []interface{}) (interface{}, error) { + final := make(map[string]interface{}) + for _, m := range arguments { + mapped := m.(map[string]interface{}) + for key, value := range mapped { + final[key] = value + } + } + return final, nil +} +func jpfMaxBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return nil, nil + } else if len(arr) == 1 { + return arr[0], nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + switch t := start.(type) { + case float64: + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(float64) + if !ok { + return nil, errors.New("invalid type, must be number") + } + if current > bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + case string: + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(string) + if !ok { + return nil, errors.New("invalid type, must be string") + } + if current > bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + default: + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfSum(arguments []interface{}) (interface{}, error) { + items, _ := toArrayNum(arguments[0]) + sum := 0.0 + for _, item := range items { + sum += item + } + return sum, nil +} + +func jpfMin(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item < best { + best = item + } + } + return best, nil + } + items, _ := toArrayStr(arguments[0]) + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item < best { + best = item + } + } + return best, nil +} + +func jpfMinBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return nil, nil + } else if len(arr) == 1 { + return arr[0], nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + if t, ok := start.(float64); ok { + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(float64) + if !ok { + return nil, errors.New("invalid type, must be number") + } + if current < bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + } else if t, ok := start.(string); ok { + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(string) + if !ok { + return nil, errors.New("invalid type, must be string") + } + if current < bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + } else { + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfType(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if _, ok := arg.(float64); ok { + return "number", nil + } + if _, ok := arg.(string); ok { + return "string", nil + } + if _, ok := arg.([]interface{}); ok { + return "array", nil + } + if _, ok := arg.(map[string]interface{}); ok { + return "object", nil + } + if arg == nil { + return "null", nil + } + if arg == true || arg == false { + return "boolean", nil + } + return nil, errors.New("unknown type") +} +func jpfKeys(arguments []interface{}) (interface{}, error) { + arg := arguments[0].(map[string]interface{}) + collected := make([]interface{}, 0, len(arg)) + for key := range arg { + collected = append(collected, key) + } + return collected, nil +} +func jpfValues(arguments []interface{}) (interface{}, error) { + arg := arguments[0].(map[string]interface{}) + collected := make([]interface{}, 0, len(arg)) + for _, value := range arg { + collected = append(collected, value) + } + return collected, nil +} +func jpfSort(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + d := sort.Float64Slice(items) + sort.Stable(d) + final := make([]interface{}, len(d)) + for i, val := range d { + final[i] = val + } + return final, nil + } + // Otherwise we're dealing with sort()'ing strings. + items, _ := toArrayStr(arguments[0]) + d := sort.StringSlice(items) + sort.Stable(d) + final := make([]interface{}, len(d)) + for i, val := range d { + final[i] = val + } + return final, nil +} +func jpfSortBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return arr, nil + } else if len(arr) == 1 { + return arr, nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + if _, ok := start.(float64); ok { + sortable := &byExprFloat{intr, node, arr, false} + sort.Stable(sortable) + if sortable.hasError { + return nil, errors.New("error in sort_by comparison") + } + return arr, nil + } else if _, ok := start.(string); ok { + sortable := &byExprString{intr, node, arr, false} + sort.Stable(sortable) + if sortable.hasError { + return nil, errors.New("error in sort_by comparison") + } + return arr, nil + } else { + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfJoin(arguments []interface{}) (interface{}, error) { + sep := arguments[0].(string) + // We can't just do arguments[1].([]string), we have to + // manually convert each item to a string. + arrayStr := []string{} + for _, item := range arguments[1].([]interface{}) { + arrayStr = append(arrayStr, item.(string)) + } + return strings.Join(arrayStr, sep), nil +} +func jpfReverse(arguments []interface{}) (interface{}, error) { + if s, ok := arguments[0].(string); ok { + r := []rune(s) + for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { + r[i], r[j] = r[j], r[i] + } + return string(r), nil + } + items := arguments[0].([]interface{}) + length := len(items) + reversed := make([]interface{}, length) + for i, item := range items { + reversed[length-(i+1)] = item + } + return reversed, nil +} +func jpfToArray(arguments []interface{}) (interface{}, error) { + if _, ok := arguments[0].([]interface{}); ok { + return arguments[0], nil + } + return arguments[:1:1], nil +} +func jpfToString(arguments []interface{}) (interface{}, error) { + if v, ok := arguments[0].(string); ok { + return v, nil + } + result, err := json.Marshal(arguments[0]) + if err != nil { + return nil, err + } + return string(result), nil +} +func jpfToNumber(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if v, ok := arg.(float64); ok { + return v, nil + } + if v, ok := arg.(string); ok { + conv, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil, nil + } + return conv, nil + } + if _, ok := arg.([]interface{}); ok { + return nil, nil + } + if _, ok := arg.(map[string]interface{}); ok { + return nil, nil + } + if arg == nil { + return nil, nil + } + if arg == true || arg == false { + return nil, nil + } + return nil, errors.New("unknown type") +} +func jpfNotNull(arguments []interface{}) (interface{}, error) { + for _, arg := range arguments { + if arg != nil { + return arg, nil + } + } + return nil, nil +} diff --git a/vendor/github.com/jmespath/go-jmespath/interpreter.go b/vendor/github.com/jmespath/go-jmespath/interpreter.go new file mode 100644 index 0000000000..13c74604c2 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/interpreter.go @@ -0,0 +1,418 @@ +package jmespath + +import ( + "errors" + "reflect" + "unicode" + "unicode/utf8" +) + +/* This is a tree based interpreter. It walks the AST and directly + interprets the AST to search through a JSON document. +*/ + +type treeInterpreter struct { + fCall *functionCaller +} + +func newInterpreter() *treeInterpreter { + interpreter := treeInterpreter{} + interpreter.fCall = newFunctionCaller() + return &interpreter +} + +type expRef struct { + ref ASTNode +} + +// Execute takes an ASTNode and input data and interprets the AST directly. +// It will produce the result of applying the JMESPath expression associated +// with the ASTNode to the input data "value". +func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) { + switch node.nodeType { + case ASTComparator: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + right, err := intr.Execute(node.children[1], value) + if err != nil { + return nil, err + } + switch node.value { + case tEQ: + return objsEqual(left, right), nil + case tNE: + return !objsEqual(left, right), nil + } + leftNum, ok := left.(float64) + if !ok { + return nil, nil + } + rightNum, ok := right.(float64) + if !ok { + return nil, nil + } + switch node.value { + case tGT: + return leftNum > rightNum, nil + case tGTE: + return leftNum >= rightNum, nil + case tLT: + return leftNum < rightNum, nil + case tLTE: + return leftNum <= rightNum, nil + } + case ASTExpRef: + return expRef{ref: node.children[0]}, nil + case ASTFunctionExpression: + resolvedArgs := []interface{}{} + for _, arg := range node.children { + current, err := intr.Execute(arg, value) + if err != nil { + return nil, err + } + resolvedArgs = append(resolvedArgs, current) + } + return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr) + case ASTField: + if m, ok := value.(map[string]interface{}); ok { + key := node.value.(string) + return m[key], nil + } + return intr.fieldFromStruct(node.value.(string), value) + case ASTFilterProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + sliceType, ok := left.([]interface{}) + if !ok { + if isSliceType(left) { + return intr.filterProjectionWithReflection(node, left) + } + return nil, nil + } + compareNode := node.children[2] + collected := []interface{}{} + for _, element := range sliceType { + result, err := intr.Execute(compareNode, element) + if err != nil { + return nil, err + } + if !isFalse(result) { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + } + return collected, nil + case ASTFlatten: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + sliceType, ok := left.([]interface{}) + if !ok { + // If we can't type convert to []interface{}, there's + // a chance this could still work via reflection if we're + // dealing with user provided types. + if isSliceType(left) { + return intr.flattenWithReflection(left) + } + return nil, nil + } + flattened := []interface{}{} + for _, element := range sliceType { + if elementSlice, ok := element.([]interface{}); ok { + flattened = append(flattened, elementSlice...) + } else if isSliceType(element) { + reflectFlat := []interface{}{} + v := reflect.ValueOf(element) + for i := 0; i < v.Len(); i++ { + reflectFlat = append(reflectFlat, v.Index(i).Interface()) + } + flattened = append(flattened, reflectFlat...) + } else { + flattened = append(flattened, element) + } + } + return flattened, nil + case ASTIdentity, ASTCurrentNode: + return value, nil + case ASTIndex: + if sliceType, ok := value.([]interface{}); ok { + index := node.value.(int) + if index < 0 { + index += len(sliceType) + } + if index < len(sliceType) && index >= 0 { + return sliceType[index], nil + } + return nil, nil + } + // Otherwise try via reflection. + rv := reflect.ValueOf(value) + if rv.Kind() == reflect.Slice { + index := node.value.(int) + if index < 0 { + index += rv.Len() + } + if index < rv.Len() && index >= 0 { + v := rv.Index(index) + return v.Interface(), nil + } + } + return nil, nil + case ASTKeyValPair: + return intr.Execute(node.children[0], value) + case ASTLiteral: + return node.value, nil + case ASTMultiSelectHash: + if value == nil { + return nil, nil + } + collected := make(map[string]interface{}) + for _, child := range node.children { + current, err := intr.Execute(child, value) + if err != nil { + return nil, err + } + key := child.value.(string) + collected[key] = current + } + return collected, nil + case ASTMultiSelectList: + if value == nil { + return nil, nil + } + collected := []interface{}{} + for _, child := range node.children { + current, err := intr.Execute(child, value) + if err != nil { + return nil, err + } + collected = append(collected, current) + } + return collected, nil + case ASTOrExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + matched, err = intr.Execute(node.children[1], value) + if err != nil { + return nil, err + } + } + return matched, nil + case ASTAndExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + return matched, nil + } + return intr.Execute(node.children[1], value) + case ASTNotExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + return true, nil + } + return false, nil + case ASTPipe: + result := value + var err error + for _, child := range node.children { + result, err = intr.Execute(child, result) + if err != nil { + return nil, err + } + } + return result, nil + case ASTProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + sliceType, ok := left.([]interface{}) + if !ok { + if isSliceType(left) { + return intr.projectWithReflection(node, left) + } + return nil, nil + } + collected := []interface{}{} + var current interface{} + for _, element := range sliceType { + current, err = intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + return collected, nil + case ASTSubexpression, ASTIndexExpression: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + return intr.Execute(node.children[1], left) + case ASTSlice: + sliceType, ok := value.([]interface{}) + if !ok { + if isSliceType(value) { + return intr.sliceWithReflection(node, value) + } + return nil, nil + } + parts := node.value.([]*int) + sliceParams := make([]sliceParam, 3) + for i, part := range parts { + if part != nil { + sliceParams[i].Specified = true + sliceParams[i].N = *part + } + } + return slice(sliceType, sliceParams) + case ASTValueProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + mapType, ok := left.(map[string]interface{}) + if !ok { + return nil, nil + } + values := make([]interface{}, len(mapType)) + for _, value := range mapType { + values = append(values, value) + } + collected := []interface{}{} + for _, element := range values { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + return collected, nil + } + return nil, errors.New("Unknown AST node: " + node.nodeType.String()) +} + +func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) { + rv := reflect.ValueOf(value) + first, n := utf8.DecodeRuneInString(key) + fieldName := string(unicode.ToUpper(first)) + key[n:] + if rv.Kind() == reflect.Struct { + v := rv.FieldByName(fieldName) + if !v.IsValid() { + return nil, nil + } + return v.Interface(), nil + } else if rv.Kind() == reflect.Ptr { + // Handle multiple levels of indirection? + if rv.IsNil() { + return nil, nil + } + rv = rv.Elem() + v := rv.FieldByName(fieldName) + if !v.IsValid() { + return nil, nil + } + return v.Interface(), nil + } + return nil, nil +} + +func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) { + v := reflect.ValueOf(value) + flattened := []interface{}{} + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + if reflect.TypeOf(element).Kind() == reflect.Slice { + // Then insert the contents of the element + // slice into the flattened slice, + // i.e flattened = append(flattened, mySlice...) + elementV := reflect.ValueOf(element) + for j := 0; j < elementV.Len(); j++ { + flattened = append( + flattened, elementV.Index(j).Interface()) + } + } else { + flattened = append(flattened, element) + } + } + return flattened, nil +} + +func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) { + v := reflect.ValueOf(value) + parts := node.value.([]*int) + sliceParams := make([]sliceParam, 3) + for i, part := range parts { + if part != nil { + sliceParams[i].Specified = true + sliceParams[i].N = *part + } + } + final := []interface{}{} + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + final = append(final, element) + } + return slice(final, sliceParams) +} + +func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) { + compareNode := node.children[2] + collected := []interface{}{} + v := reflect.ValueOf(value) + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + result, err := intr.Execute(compareNode, element) + if err != nil { + return nil, err + } + if !isFalse(result) { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + } + return collected, nil +} + +func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) { + collected := []interface{}{} + v := reflect.ValueOf(value) + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + result, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if result != nil { + collected = append(collected, result) + } + } + return collected, nil +} diff --git a/vendor/github.com/jmespath/go-jmespath/lexer.go b/vendor/github.com/jmespath/go-jmespath/lexer.go new file mode 100644 index 0000000000..817900c8f5 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/lexer.go @@ -0,0 +1,420 @@ +package jmespath + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "strings" + "unicode/utf8" +) + +type token struct { + tokenType tokType + value string + position int + length int +} + +type tokType int + +const eof = -1 + +// Lexer contains information about the expression being tokenized. +type Lexer struct { + expression string // The expression provided by the user. + currentPos int // The current position in the string. + lastWidth int // The width of the current rune. This + buf bytes.Buffer // Internal buffer used for building up values. +} + +// SyntaxError is the main error used whenever a lexing or parsing error occurs. +type SyntaxError struct { + msg string // Error message displayed to user + Expression string // Expression that generated a SyntaxError + Offset int // The location in the string where the error occurred +} + +func (e SyntaxError) Error() string { + // In the future, it would be good to underline the specific + // location where the error occurred. + return "SyntaxError: " + e.msg +} + +// HighlightLocation will show where the syntax error occurred. +// It will place a "^" character on a line below the expression +// at the point where the syntax error occurred. +func (e SyntaxError) HighlightLocation() string { + return e.Expression + "\n" + strings.Repeat(" ", e.Offset) + "^" +} + +//go:generate stringer -type=tokType +const ( + tUnknown tokType = iota + tStar + tDot + tFilter + tFlatten + tLparen + tRparen + tLbracket + tRbracket + tLbrace + tRbrace + tOr + tPipe + tNumber + tUnquotedIdentifier + tQuotedIdentifier + tComma + tColon + tLT + tLTE + tGT + tGTE + tEQ + tNE + tJSONLiteral + tStringLiteral + tCurrent + tExpref + tAnd + tNot + tEOF +) + +var basicTokens = map[rune]tokType{ + '.': tDot, + '*': tStar, + ',': tComma, + ':': tColon, + '{': tLbrace, + '}': tRbrace, + ']': tRbracket, // tLbracket not included because it could be "[]" + '(': tLparen, + ')': tRparen, + '@': tCurrent, +} + +// Bit mask for [a-zA-Z_] shifted down 64 bits to fit in a single uint64. +// When using this bitmask just be sure to shift the rune down 64 bits +// before checking against identifierStartBits. +const identifierStartBits uint64 = 576460745995190270 + +// Bit mask for [a-zA-Z0-9], 128 bits -> 2 uint64s. +var identifierTrailingBits = [2]uint64{287948901175001088, 576460745995190270} + +var whiteSpace = map[rune]bool{ + ' ': true, '\t': true, '\n': true, '\r': true, +} + +func (t token) String() string { + return fmt.Sprintf("Token{%+v, %s, %d, %d}", + t.tokenType, t.value, t.position, t.length) +} + +// NewLexer creates a new JMESPath lexer. +func NewLexer() *Lexer { + lexer := Lexer{} + return &lexer +} + +func (lexer *Lexer) next() rune { + if lexer.currentPos >= len(lexer.expression) { + lexer.lastWidth = 0 + return eof + } + r, w := utf8.DecodeRuneInString(lexer.expression[lexer.currentPos:]) + lexer.lastWidth = w + lexer.currentPos += w + return r +} + +func (lexer *Lexer) back() { + lexer.currentPos -= lexer.lastWidth +} + +func (lexer *Lexer) peek() rune { + t := lexer.next() + lexer.back() + return t +} + +// tokenize takes an expression and returns corresponding tokens. +func (lexer *Lexer) tokenize(expression string) ([]token, error) { + var tokens []token + lexer.expression = expression + lexer.currentPos = 0 + lexer.lastWidth = 0 +loop: + for { + r := lexer.next() + if identifierStartBits&(1<<(uint64(r)-64)) > 0 { + t := lexer.consumeUnquotedIdentifier() + tokens = append(tokens, t) + } else if val, ok := basicTokens[r]; ok { + // Basic single char token. + t := token{ + tokenType: val, + value: string(r), + position: lexer.currentPos - lexer.lastWidth, + length: 1, + } + tokens = append(tokens, t) + } else if r == '-' || (r >= '0' && r <= '9') { + t := lexer.consumeNumber() + tokens = append(tokens, t) + } else if r == '[' { + t := lexer.consumeLBracket() + tokens = append(tokens, t) + } else if r == '"' { + t, err := lexer.consumeQuotedIdentifier() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '\'' { + t, err := lexer.consumeRawStringLiteral() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '`' { + t, err := lexer.consumeLiteral() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '|' { + t := lexer.matchOrElse(r, '|', tOr, tPipe) + tokens = append(tokens, t) + } else if r == '<' { + t := lexer.matchOrElse(r, '=', tLTE, tLT) + tokens = append(tokens, t) + } else if r == '>' { + t := lexer.matchOrElse(r, '=', tGTE, tGT) + tokens = append(tokens, t) + } else if r == '!' { + t := lexer.matchOrElse(r, '=', tNE, tNot) + tokens = append(tokens, t) + } else if r == '=' { + t := lexer.matchOrElse(r, '=', tEQ, tUnknown) + tokens = append(tokens, t) + } else if r == '&' { + t := lexer.matchOrElse(r, '&', tAnd, tExpref) + tokens = append(tokens, t) + } else if r == eof { + break loop + } else if _, ok := whiteSpace[r]; ok { + // Ignore whitespace + } else { + return tokens, lexer.syntaxError(fmt.Sprintf("Unknown char: %s", strconv.QuoteRuneToASCII(r))) + } + } + tokens = append(tokens, token{tEOF, "", len(lexer.expression), 0}) + return tokens, nil +} + +// Consume characters until the ending rune "r" is reached. +// If the end of the expression is reached before seeing the +// terminating rune "r", then an error is returned. +// If no error occurs then the matching substring is returned. +// The returned string will not include the ending rune. +func (lexer *Lexer) consumeUntil(end rune) (string, error) { + start := lexer.currentPos + current := lexer.next() + for current != end && current != eof { + if current == '\\' && lexer.peek() != eof { + lexer.next() + } + current = lexer.next() + } + if lexer.lastWidth == 0 { + // Then we hit an EOF so we never reached the closing + // delimiter. + return "", SyntaxError{ + msg: "Unclosed delimiter: " + string(end), + Expression: lexer.expression, + Offset: len(lexer.expression), + } + } + return lexer.expression[start : lexer.currentPos-lexer.lastWidth], nil +} + +func (lexer *Lexer) consumeLiteral() (token, error) { + start := lexer.currentPos + value, err := lexer.consumeUntil('`') + if err != nil { + return token{}, err + } + value = strings.Replace(value, "\\`", "`", -1) + return token{ + tokenType: tJSONLiteral, + value: value, + position: start, + length: len(value), + }, nil +} + +func (lexer *Lexer) consumeRawStringLiteral() (token, error) { + start := lexer.currentPos + currentIndex := start + current := lexer.next() + for current != '\'' && lexer.peek() != eof { + if current == '\\' && lexer.peek() == '\'' { + chunk := lexer.expression[currentIndex : lexer.currentPos-1] + lexer.buf.WriteString(chunk) + lexer.buf.WriteString("'") + lexer.next() + currentIndex = lexer.currentPos + } + current = lexer.next() + } + if lexer.lastWidth == 0 { + // Then we hit an EOF so we never reached the closing + // delimiter. + return token{}, SyntaxError{ + msg: "Unclosed delimiter: '", + Expression: lexer.expression, + Offset: len(lexer.expression), + } + } + if currentIndex < lexer.currentPos { + lexer.buf.WriteString(lexer.expression[currentIndex : lexer.currentPos-1]) + } + value := lexer.buf.String() + // Reset the buffer so it can reused again. + lexer.buf.Reset() + return token{ + tokenType: tStringLiteral, + value: value, + position: start, + length: len(value), + }, nil +} + +func (lexer *Lexer) syntaxError(msg string) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: lexer.expression, + Offset: lexer.currentPos - 1, + } +} + +// Checks for a two char token, otherwise matches a single character +// token. This is used whenever a two char token overlaps a single +// char token, e.g. "||" -> tPipe, "|" -> tOr. +func (lexer *Lexer) matchOrElse(first rune, second rune, matchedType tokType, singleCharType tokType) token { + start := lexer.currentPos - lexer.lastWidth + nextRune := lexer.next() + var t token + if nextRune == second { + t = token{ + tokenType: matchedType, + value: string(first) + string(second), + position: start, + length: 2, + } + } else { + lexer.back() + t = token{ + tokenType: singleCharType, + value: string(first), + position: start, + length: 1, + } + } + return t +} + +func (lexer *Lexer) consumeLBracket() token { + // There's three options here: + // 1. A filter expression "[?" + // 2. A flatten operator "[]" + // 3. A bare rbracket "[" + start := lexer.currentPos - lexer.lastWidth + nextRune := lexer.next() + var t token + if nextRune == '?' { + t = token{ + tokenType: tFilter, + value: "[?", + position: start, + length: 2, + } + } else if nextRune == ']' { + t = token{ + tokenType: tFlatten, + value: "[]", + position: start, + length: 2, + } + } else { + t = token{ + tokenType: tLbracket, + value: "[", + position: start, + length: 1, + } + lexer.back() + } + return t +} + +func (lexer *Lexer) consumeQuotedIdentifier() (token, error) { + start := lexer.currentPos + value, err := lexer.consumeUntil('"') + if err != nil { + return token{}, err + } + var decoded string + asJSON := []byte("\"" + value + "\"") + if err := json.Unmarshal([]byte(asJSON), &decoded); err != nil { + return token{}, err + } + return token{ + tokenType: tQuotedIdentifier, + value: decoded, + position: start - 1, + length: len(decoded), + }, nil +} + +func (lexer *Lexer) consumeUnquotedIdentifier() token { + // Consume runes until we reach the end of an unquoted + // identifier. + start := lexer.currentPos - lexer.lastWidth + for { + r := lexer.next() + if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 { + lexer.back() + break + } + } + value := lexer.expression[start:lexer.currentPos] + return token{ + tokenType: tUnquotedIdentifier, + value: value, + position: start, + length: lexer.currentPos - start, + } +} + +func (lexer *Lexer) consumeNumber() token { + // Consume runes until we reach something that's not a number. + start := lexer.currentPos - lexer.lastWidth + for { + r := lexer.next() + if r < '0' || r > '9' { + lexer.back() + break + } + } + value := lexer.expression[start:lexer.currentPos] + return token{ + tokenType: tNumber, + value: value, + position: start, + length: lexer.currentPos - start, + } +} diff --git a/vendor/github.com/jmespath/go-jmespath/parser.go b/vendor/github.com/jmespath/go-jmespath/parser.go new file mode 100644 index 0000000000..c8f4bcebd8 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/parser.go @@ -0,0 +1,603 @@ +package jmespath + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" +) + +type astNodeType int + +//go:generate stringer -type astNodeType +const ( + ASTEmpty astNodeType = iota + ASTComparator + ASTCurrentNode + ASTExpRef + ASTFunctionExpression + ASTField + ASTFilterProjection + ASTFlatten + ASTIdentity + ASTIndex + ASTIndexExpression + ASTKeyValPair + ASTLiteral + ASTMultiSelectHash + ASTMultiSelectList + ASTOrExpression + ASTAndExpression + ASTNotExpression + ASTPipe + ASTProjection + ASTSubexpression + ASTSlice + ASTValueProjection +) + +// ASTNode represents the abstract syntax tree of a JMESPath expression. +type ASTNode struct { + nodeType astNodeType + value interface{} + children []ASTNode +} + +func (node ASTNode) String() string { + return node.PrettyPrint(0) +} + +// PrettyPrint will pretty print the parsed AST. +// The AST is an implementation detail and this pretty print +// function is provided as a convenience method to help with +// debugging. You should not rely on its output as the internal +// structure of the AST may change at any time. +func (node ASTNode) PrettyPrint(indent int) string { + spaces := strings.Repeat(" ", indent) + output := fmt.Sprintf("%s%s {\n", spaces, node.nodeType) + nextIndent := indent + 2 + if node.value != nil { + if converted, ok := node.value.(fmt.Stringer); ok { + // Account for things like comparator nodes + // that are enums with a String() method. + output += fmt.Sprintf("%svalue: %s\n", strings.Repeat(" ", nextIndent), converted.String()) + } else { + output += fmt.Sprintf("%svalue: %#v\n", strings.Repeat(" ", nextIndent), node.value) + } + } + lastIndex := len(node.children) + if lastIndex > 0 { + output += fmt.Sprintf("%schildren: {\n", strings.Repeat(" ", nextIndent)) + childIndent := nextIndent + 2 + for _, elem := range node.children { + output += elem.PrettyPrint(childIndent) + } + } + output += fmt.Sprintf("%s}\n", spaces) + return output +} + +var bindingPowers = map[tokType]int{ + tEOF: 0, + tUnquotedIdentifier: 0, + tQuotedIdentifier: 0, + tRbracket: 0, + tRparen: 0, + tComma: 0, + tRbrace: 0, + tNumber: 0, + tCurrent: 0, + tExpref: 0, + tColon: 0, + tPipe: 1, + tOr: 2, + tAnd: 3, + tEQ: 5, + tLT: 5, + tLTE: 5, + tGT: 5, + tGTE: 5, + tNE: 5, + tFlatten: 9, + tStar: 20, + tFilter: 21, + tDot: 40, + tNot: 45, + tLbrace: 50, + tLbracket: 55, + tLparen: 60, +} + +// Parser holds state about the current expression being parsed. +type Parser struct { + expression string + tokens []token + index int +} + +// NewParser creates a new JMESPath parser. +func NewParser() *Parser { + p := Parser{} + return &p +} + +// Parse will compile a JMESPath expression. +func (p *Parser) Parse(expression string) (ASTNode, error) { + lexer := NewLexer() + p.expression = expression + p.index = 0 + tokens, err := lexer.tokenize(expression) + if err != nil { + return ASTNode{}, err + } + p.tokens = tokens + parsed, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if p.current() != tEOF { + return ASTNode{}, p.syntaxError(fmt.Sprintf( + "Unexpected token at the end of the expresssion: %s", p.current())) + } + return parsed, nil +} + +func (p *Parser) parseExpression(bindingPower int) (ASTNode, error) { + var err error + leftToken := p.lookaheadToken(0) + p.advance() + leftNode, err := p.nud(leftToken) + if err != nil { + return ASTNode{}, err + } + currentToken := p.current() + for bindingPower < bindingPowers[currentToken] { + p.advance() + leftNode, err = p.led(currentToken, leftNode) + if err != nil { + return ASTNode{}, err + } + currentToken = p.current() + } + return leftNode, nil +} + +func (p *Parser) parseIndexExpression() (ASTNode, error) { + if p.lookahead(0) == tColon || p.lookahead(1) == tColon { + return p.parseSliceExpression() + } + indexStr := p.lookaheadToken(0).value + parsedInt, err := strconv.Atoi(indexStr) + if err != nil { + return ASTNode{}, err + } + indexNode := ASTNode{nodeType: ASTIndex, value: parsedInt} + p.advance() + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + return indexNode, nil +} + +func (p *Parser) parseSliceExpression() (ASTNode, error) { + parts := []*int{nil, nil, nil} + index := 0 + current := p.current() + for current != tRbracket && index < 3 { + if current == tColon { + index++ + p.advance() + } else if current == tNumber { + parsedInt, err := strconv.Atoi(p.lookaheadToken(0).value) + if err != nil { + return ASTNode{}, err + } + parts[index] = &parsedInt + p.advance() + } else { + return ASTNode{}, p.syntaxError( + "Expected tColon or tNumber" + ", received: " + p.current().String()) + } + current = p.current() + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTSlice, + value: parts, + }, nil +} + +func (p *Parser) match(tokenType tokType) error { + if p.current() == tokenType { + p.advance() + return nil + } + return p.syntaxError("Expected " + tokenType.String() + ", received: " + p.current().String()) +} + +func (p *Parser) led(tokenType tokType, node ASTNode) (ASTNode, error) { + switch tokenType { + case tDot: + if p.current() != tStar { + right, err := p.parseDotRHS(bindingPowers[tDot]) + return ASTNode{ + nodeType: ASTSubexpression, + children: []ASTNode{node, right}, + }, err + } + p.advance() + right, err := p.parseProjectionRHS(bindingPowers[tDot]) + return ASTNode{ + nodeType: ASTValueProjection, + children: []ASTNode{node, right}, + }, err + case tPipe: + right, err := p.parseExpression(bindingPowers[tPipe]) + return ASTNode{nodeType: ASTPipe, children: []ASTNode{node, right}}, err + case tOr: + right, err := p.parseExpression(bindingPowers[tOr]) + return ASTNode{nodeType: ASTOrExpression, children: []ASTNode{node, right}}, err + case tAnd: + right, err := p.parseExpression(bindingPowers[tAnd]) + return ASTNode{nodeType: ASTAndExpression, children: []ASTNode{node, right}}, err + case tLparen: + name := node.value + var args []ASTNode + for p.current() != tRparen { + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if p.current() == tComma { + if err := p.match(tComma); err != nil { + return ASTNode{}, err + } + } + args = append(args, expression) + } + if err := p.match(tRparen); err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTFunctionExpression, + value: name, + children: args, + }, nil + case tFilter: + return p.parseFilter(node) + case tFlatten: + left := ASTNode{nodeType: ASTFlatten, children: []ASTNode{node}} + right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{left, right}, + }, err + case tEQ, tNE, tGT, tGTE, tLT, tLTE: + right, err := p.parseExpression(bindingPowers[tokenType]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTComparator, + value: tokenType, + children: []ASTNode{node, right}, + }, nil + case tLbracket: + tokenType := p.current() + var right ASTNode + var err error + if tokenType == tNumber || tokenType == tColon { + right, err = p.parseIndexExpression() + if err != nil { + return ASTNode{}, err + } + return p.projectIfSlice(node, right) + } + // Otherwise this is a projection. + if err := p.match(tStar); err != nil { + return ASTNode{}, err + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + right, err = p.parseProjectionRHS(bindingPowers[tStar]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{node, right}, + }, nil + } + return ASTNode{}, p.syntaxError("Unexpected token: " + tokenType.String()) +} + +func (p *Parser) nud(token token) (ASTNode, error) { + switch token.tokenType { + case tJSONLiteral: + var parsed interface{} + err := json.Unmarshal([]byte(token.value), &parsed) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTLiteral, value: parsed}, nil + case tStringLiteral: + return ASTNode{nodeType: ASTLiteral, value: token.value}, nil + case tUnquotedIdentifier: + return ASTNode{ + nodeType: ASTField, + value: token.value, + }, nil + case tQuotedIdentifier: + node := ASTNode{nodeType: ASTField, value: token.value} + if p.current() == tLparen { + return ASTNode{}, p.syntaxErrorToken("Can't have quoted identifier as function name.", token) + } + return node, nil + case tStar: + left := ASTNode{nodeType: ASTIdentity} + var right ASTNode + var err error + if p.current() == tRbracket { + right = ASTNode{nodeType: ASTIdentity} + } else { + right, err = p.parseProjectionRHS(bindingPowers[tStar]) + } + return ASTNode{nodeType: ASTValueProjection, children: []ASTNode{left, right}}, err + case tFilter: + return p.parseFilter(ASTNode{nodeType: ASTIdentity}) + case tLbrace: + return p.parseMultiSelectHash() + case tFlatten: + left := ASTNode{ + nodeType: ASTFlatten, + children: []ASTNode{ASTNode{nodeType: ASTIdentity}}, + } + right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTProjection, children: []ASTNode{left, right}}, nil + case tLbracket: + tokenType := p.current() + //var right ASTNode + if tokenType == tNumber || tokenType == tColon { + right, err := p.parseIndexExpression() + if err != nil { + return ASTNode{}, nil + } + return p.projectIfSlice(ASTNode{nodeType: ASTIdentity}, right) + } else if tokenType == tStar && p.lookahead(1) == tRbracket { + p.advance() + p.advance() + right, err := p.parseProjectionRHS(bindingPowers[tStar]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{ASTNode{nodeType: ASTIdentity}, right}, + }, nil + } else { + return p.parseMultiSelectList() + } + case tCurrent: + return ASTNode{nodeType: ASTCurrentNode}, nil + case tExpref: + expression, err := p.parseExpression(bindingPowers[tExpref]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTExpRef, children: []ASTNode{expression}}, nil + case tNot: + expression, err := p.parseExpression(bindingPowers[tNot]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTNotExpression, children: []ASTNode{expression}}, nil + case tLparen: + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if err := p.match(tRparen); err != nil { + return ASTNode{}, err + } + return expression, nil + case tEOF: + return ASTNode{}, p.syntaxErrorToken("Incomplete expression", token) + } + + return ASTNode{}, p.syntaxErrorToken("Invalid token: "+token.tokenType.String(), token) +} + +func (p *Parser) parseMultiSelectList() (ASTNode, error) { + var expressions []ASTNode + for { + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + expressions = append(expressions, expression) + if p.current() == tRbracket { + break + } + err = p.match(tComma) + if err != nil { + return ASTNode{}, err + } + } + err := p.match(tRbracket) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTMultiSelectList, + children: expressions, + }, nil +} + +func (p *Parser) parseMultiSelectHash() (ASTNode, error) { + var children []ASTNode + for { + keyToken := p.lookaheadToken(0) + if err := p.match(tUnquotedIdentifier); err != nil { + if err := p.match(tQuotedIdentifier); err != nil { + return ASTNode{}, p.syntaxError("Expected tQuotedIdentifier or tUnquotedIdentifier") + } + } + keyName := keyToken.value + err := p.match(tColon) + if err != nil { + return ASTNode{}, err + } + value, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + node := ASTNode{ + nodeType: ASTKeyValPair, + value: keyName, + children: []ASTNode{value}, + } + children = append(children, node) + if p.current() == tComma { + err := p.match(tComma) + if err != nil { + return ASTNode{}, nil + } + } else if p.current() == tRbrace { + err := p.match(tRbrace) + if err != nil { + return ASTNode{}, nil + } + break + } + } + return ASTNode{ + nodeType: ASTMultiSelectHash, + children: children, + }, nil +} + +func (p *Parser) projectIfSlice(left ASTNode, right ASTNode) (ASTNode, error) { + indexExpr := ASTNode{ + nodeType: ASTIndexExpression, + children: []ASTNode{left, right}, + } + if right.nodeType == ASTSlice { + right, err := p.parseProjectionRHS(bindingPowers[tStar]) + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{indexExpr, right}, + }, err + } + return indexExpr, nil +} +func (p *Parser) parseFilter(node ASTNode) (ASTNode, error) { + var right, condition ASTNode + var err error + condition, err = p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + if p.current() == tFlatten { + right = ASTNode{nodeType: ASTIdentity} + } else { + right, err = p.parseProjectionRHS(bindingPowers[tFilter]) + if err != nil { + return ASTNode{}, err + } + } + + return ASTNode{ + nodeType: ASTFilterProjection, + children: []ASTNode{node, right, condition}, + }, nil +} + +func (p *Parser) parseDotRHS(bindingPower int) (ASTNode, error) { + lookahead := p.current() + if tokensOneOf([]tokType{tQuotedIdentifier, tUnquotedIdentifier, tStar}, lookahead) { + return p.parseExpression(bindingPower) + } else if lookahead == tLbracket { + if err := p.match(tLbracket); err != nil { + return ASTNode{}, err + } + return p.parseMultiSelectList() + } else if lookahead == tLbrace { + if err := p.match(tLbrace); err != nil { + return ASTNode{}, err + } + return p.parseMultiSelectHash() + } + return ASTNode{}, p.syntaxError("Expected identifier, lbracket, or lbrace") +} + +func (p *Parser) parseProjectionRHS(bindingPower int) (ASTNode, error) { + current := p.current() + if bindingPowers[current] < 10 { + return ASTNode{nodeType: ASTIdentity}, nil + } else if current == tLbracket { + return p.parseExpression(bindingPower) + } else if current == tFilter { + return p.parseExpression(bindingPower) + } else if current == tDot { + err := p.match(tDot) + if err != nil { + return ASTNode{}, err + } + return p.parseDotRHS(bindingPower) + } else { + return ASTNode{}, p.syntaxError("Error") + } +} + +func (p *Parser) lookahead(number int) tokType { + return p.lookaheadToken(number).tokenType +} + +func (p *Parser) current() tokType { + return p.lookahead(0) +} + +func (p *Parser) lookaheadToken(number int) token { + return p.tokens[p.index+number] +} + +func (p *Parser) advance() { + p.index++ +} + +func tokensOneOf(elements []tokType, token tokType) bool { + for _, elem := range elements { + if elem == token { + return true + } + } + return false +} + +func (p *Parser) syntaxError(msg string) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: p.expression, + Offset: p.lookaheadToken(0).position, + } +} + +// Create a SyntaxError based on the provided token. +// This differs from syntaxError() which creates a SyntaxError +// based on the current lookahead token. +func (p *Parser) syntaxErrorToken(msg string, t token) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: p.expression, + Offset: t.position, + } +} diff --git a/vendor/github.com/jmespath/go-jmespath/toktype_string.go b/vendor/github.com/jmespath/go-jmespath/toktype_string.go new file mode 100644 index 0000000000..dae79cbdf3 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/toktype_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type=tokType; DO NOT EDIT + +package jmespath + +import "fmt" + +const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF" + +var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214} + +func (i tokType) String() string { + if i < 0 || i >= tokType(len(_tokType_index)-1) { + return fmt.Sprintf("tokType(%d)", i) + } + return _tokType_name[_tokType_index[i]:_tokType_index[i+1]] +} diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go new file mode 100644 index 0000000000..ddc1b7d7d4 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/util.go @@ -0,0 +1,185 @@ +package jmespath + +import ( + "errors" + "reflect" +) + +// IsFalse determines if an object is false based on the JMESPath spec. +// JMESPath defines false values to be any of: +// - An empty string array, or hash. +// - The boolean value false. +// - nil +func isFalse(value interface{}) bool { + switch v := value.(type) { + case bool: + return !v + case []interface{}: + return len(v) == 0 + case map[string]interface{}: + return len(v) == 0 + case string: + return len(v) == 0 + case nil: + return true + } + // Try the reflection cases before returning false. + rv := reflect.ValueOf(value) + switch rv.Kind() { + case reflect.Struct: + // A struct type will never be false, even if + // all of its values are the zero type. + return false + case reflect.Slice, reflect.Map: + return rv.Len() == 0 + case reflect.Ptr: + if rv.IsNil() { + return true + } + // If it's a pointer type, we'll try to deref the pointer + // and evaluate the pointer value for isFalse. + element := rv.Elem() + return isFalse(element.Interface()) + } + return false +} + +// ObjsEqual is a generic object equality check. +// It will take two arbitrary objects and recursively determine +// if they are equal. +func objsEqual(left interface{}, right interface{}) bool { + return reflect.DeepEqual(left, right) +} + +// SliceParam refers to a single part of a slice. +// A slice consists of a start, a stop, and a step, similar to +// python slices. +type sliceParam struct { + N int + Specified bool +} + +// Slice supports [start:stop:step] style slicing that's supported in JMESPath. +func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) { + computed, err := computeSliceParams(len(slice), parts) + if err != nil { + return nil, err + } + start, stop, step := computed[0], computed[1], computed[2] + result := []interface{}{} + if step > 0 { + for i := start; i < stop; i += step { + result = append(result, slice[i]) + } + } else { + for i := start; i > stop; i += step { + result = append(result, slice[i]) + } + } + return result, nil +} + +func computeSliceParams(length int, parts []sliceParam) ([]int, error) { + var start, stop, step int + if !parts[2].Specified { + step = 1 + } else if parts[2].N == 0 { + return nil, errors.New("Invalid slice, step cannot be 0") + } else { + step = parts[2].N + } + var stepValueNegative bool + if step < 0 { + stepValueNegative = true + } else { + stepValueNegative = false + } + + if !parts[0].Specified { + if stepValueNegative { + start = length - 1 + } else { + start = 0 + } + } else { + start = capSlice(length, parts[0].N, step) + } + + if !parts[1].Specified { + if stepValueNegative { + stop = -1 + } else { + stop = length + } + } else { + stop = capSlice(length, parts[1].N, step) + } + return []int{start, stop, step}, nil +} + +func capSlice(length int, actual int, step int) int { + if actual < 0 { + actual += length + if actual < 0 { + if step < 0 { + actual = -1 + } else { + actual = 0 + } + } + } else if actual >= length { + if step < 0 { + actual = length - 1 + } else { + actual = length + } + } + return actual +} + +// ToArrayNum converts an empty interface type to a slice of float64. +// If any element in the array cannot be converted, then nil is returned +// along with a second value of false. +func toArrayNum(data interface{}) ([]float64, bool) { + // Is there a better way to do this with reflect? + if d, ok := data.([]interface{}); ok { + result := make([]float64, len(d)) + for i, el := range d { + item, ok := el.(float64) + if !ok { + return nil, false + } + result[i] = item + } + return result, true + } + return nil, false +} + +// ToArrayStr converts an empty interface type to a slice of strings. +// If any element in the array cannot be converted, then nil is returned +// along with a second value of false. If the input data could be entirely +// converted, then the converted data, along with a second value of true, +// will be returned. +func toArrayStr(data interface{}) ([]string, bool) { + // Is there a better way to do this with reflect? + if d, ok := data.([]interface{}); ok { + result := make([]string, len(d)) + for i, el := range d { + item, ok := el.(string) + if !ok { + return nil, false + } + result[i] = item + } + return result, true + } + return nil, false +} + +func isSliceType(v interface{}) bool { + if v == nil { + return false + } + return reflect.TypeOf(v).Kind() == reflect.Slice +} diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/mitchellh/mapstructure/LICENSE new file mode 100644 index 0000000000..f9c841a51e --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md similarity index 100% rename from Godeps/_workspace/src/github.com/mitchellh/mapstructure/README.md rename to vendor/github.com/mitchellh/mapstructure/README.md diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go similarity index 100% rename from Godeps/_workspace/src/github.com/mitchellh/mapstructure/decode_hooks.go rename to vendor/github.com/mitchellh/mapstructure/decode_hooks.go diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/error.go b/vendor/github.com/mitchellh/mapstructure/error.go similarity index 100% rename from Godeps/_workspace/src/github.com/mitchellh/mapstructure/error.go rename to vendor/github.com/mitchellh/mapstructure/error.go diff --git a/Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go similarity index 100% rename from Godeps/_workspace/src/github.com/mitchellh/mapstructure/mapstructure.go rename to vendor/github.com/mitchellh/mapstructure/mapstructure.go diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/pmezard/go-difflib/LICENSE new file mode 100644 index 0000000000..c67dad612a --- /dev/null +++ b/vendor/github.com/pmezard/go-difflib/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013, Patrick Mezard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go new file mode 100644 index 0000000000..003e99fadb --- /dev/null +++ b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go @@ -0,0 +1,772 @@ +// Package difflib is a partial port of Python difflib module. +// +// It provides tools to compare sequences of strings and generate textual diffs. +// +// The following class and functions have been ported: +// +// - SequenceMatcher +// +// - unified_diff +// +// - context_diff +// +// Getting unified diffs was the main goal of the port. Keep in mind this code +// is mostly suitable to output text differences in a human friendly way, there +// are no guarantees generated diffs are consumable by patch(1). +package difflib + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strings" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func calculateRatio(matches, length int) float64 { + if length > 0 { + return 2.0 * float64(matches) / float64(length) + } + return 1.0 +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool) *SequenceMatcher { + + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s, _ := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s, _ := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s, _ := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// and for all (i',j',k') meeting those conditions, +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n)}) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s] = m.fullBCount[s] + 1 + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches += 1 + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return string(w.Bytes()), err +} + +// Convert range to the "ed" format. +func formatRangeContext(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + if length <= 1 { + return fmt.Sprintf("%d", beginning) + } + return fmt.Sprintf("%d,%d", beginning, beginning+length-1) +} + +type ContextDiff UnifiedDiff + +// Compare two sequences of lines; generate the delta as a context diff. +// +// Context diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by diff.Context +// which defaults to three. +// +// By default, the diff control lines (those with *** or ---) are +// created with a trailing newline. +// +// For inputs that do not have trailing newlines, set the diff.Eol +// argument to "" so that the output will be uniformly newline free. +// +// The context diff format normally has a header for filenames and +// modification times. Any or all of these may be specified using +// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. +// The modification times are normally expressed in the ISO 8601 format. +// If not specified, the strings default to blanks. +func WriteContextDiff(writer io.Writer, diff ContextDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + var diffErr error + wf := func(format string, args ...interface{}) { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + if diffErr == nil && err != nil { + diffErr = err + } + } + ws := func(s string) { + _, err := buf.WriteString(s) + if diffErr == nil && err != nil { + diffErr = err + } + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + prefix := map[byte]string{ + 'i': "+ ", + 'd': "- ", + 'r': "! ", + 'e': " ", + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + } + } + + first, last := g[0], g[len(g)-1] + ws("***************" + diff.Eol) + + range1 := formatRangeContext(first.I1, last.I2) + wf("*** %s ****%s", range1, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'd' { + for _, cc := range g { + if cc.Tag == 'i' { + continue + } + for _, line := range diff.A[cc.I1:cc.I2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + + range2 := formatRangeContext(first.J1, last.J2) + wf("--- %s ----%s", range2, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'i' { + for _, cc := range g { + if cc.Tag == 'd' { + continue + } + for _, line := range diff.B[cc.J1:cc.J2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + } + return diffErr +} + +// Like WriteContextDiff but returns the diff a string. +func GetContextDiffString(diff ContextDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteContextDiff(w, diff) + return string(w.Bytes()), err +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} diff --git a/vendor/github.com/rackspace/gophercloud/.travis.yml b/vendor/github.com/rackspace/gophercloud/.travis.yml new file mode 100644 index 0000000000..946f98cb3d --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/.travis.yml @@ -0,0 +1,17 @@ +language: go +install: + - go get -v -tags 'fixtures acceptance' ./... +go: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - tip +script: script/cibuild +after_success: + - go get code.google.com/p/go.tools/cmd/cover + - go get github.com/axw/gocov/gocov + - go get github.com/mattn/goveralls + - export PATH=$PATH:$HOME/gopath/bin/ + - goveralls 2k7PTU3xa474Hymwgdj6XjqenNfGTNkO8 +sudo: false diff --git a/vendor/github.com/rackspace/gophercloud/CONTRIBUTING.md b/vendor/github.com/rackspace/gophercloud/CONTRIBUTING.md new file mode 100644 index 0000000000..9748c1ad2b --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/CONTRIBUTING.md @@ -0,0 +1,275 @@ +# Contributing to gophercloud + +- [Getting started](#getting-started) +- [Tests](#tests) +- [Style guide](#basic-style-guide) +- [5 ways to get involved](#5-ways-to-get-involved) + +## Setting up your git workspace + +As a contributor you will need to setup your workspace in a slightly different +way than just downloading it. Here are the basic installation instructions: + +1. Configure your `$GOPATH` and run `go get` as described in the main +[README](/README.md#how-to-install). + +2. Move into the directory that houses your local repository: + + ```bash + cd ${GOPATH}/src/github.com/rackspace/gophercloud + ``` + +3. Fork the `rackspace/gophercloud` repository and update your remote refs. You +will need to rename the `origin` remote branch to `upstream`, and add your +fork as `origin` instead: + + ```bash + git remote rename origin upstream + git remote add origin git@github.com//gophercloud + ``` + +4. Checkout the latest development branch ([click here](/branches) to see all +the branches): + + ```bash + git checkout release/v1.0.1 + ``` + +5. If you're working on something (discussed more in detail below), you will +need to checkout a new feature branch: + + ```bash + git checkout -b my-new-feature + ``` + +Another thing to bear in mind is that you will need to add a few extra +environment variables for acceptance tests - this is documented in our +[acceptance tests readme](/acceptance). + +## Tests + +When working on a new or existing feature, testing will be the backbone of your +work since it helps uncover and prevent regressions in the codebase. There are +two types of test we use in gophercloud: unit tests and acceptance tests, which +are both described below. + +### Unit tests + +Unit tests are the fine-grained tests that establish and ensure the behaviour +of individual units of functionality. We usually test on an +operation-by-operation basis (an operation typically being an API action) with +the use of mocking to set up explicit expectations. Each operation will set up +its HTTP response expectation, and then test how the system responds when fed +this controlled, pre-determined input. + +To make life easier, we've introduced a bunch of test helpers to simplify the +process of testing expectations with assertions: + +```go +import ( + "testing" + + "github.com/rackspace/gophercloud/testhelper" +) + +func TestSomething(t *testing.T) { + result, err := Operation() + + testhelper.AssertEquals(t, "foo", result.Bar) + testhelper.AssertNoErr(t, err) +} + +func TestSomethingElse(t *testing.T) { + testhelper.CheckEquals(t, "expected", "actual") +} +``` + +`AssertEquals` and `AssertNoErr` will throw a fatal error if a value does not +match an expected value or if an error has been declared, respectively. You can +also use `CheckEquals` and `CheckNoErr` for the same purpose; the only difference +being that `t.Errorf` is raised rather than `t.Fatalf`. + +Here is a truncated example of mocked HTTP responses: + +```go +import ( + "testing" + + th "github.com/rackspace/gophercloud/testhelper" + fake "github.com/rackspace/gophercloud/testhelper/client" +) + +func TestGet(t *testing.T) { + // Setup the HTTP request multiplexer and server + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { + // Test we're using the correct HTTP method + th.TestMethod(t, r, "GET") + + // Test we're setting the auth token + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + // Set the appropriate headers for our mocked response + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + // Set the HTTP body + fmt.Fprintf(w, ` +{ + "network": { + "status": "ACTIVE", + "name": "private-network", + "admin_state_up": true, + "tenant_id": "4fd44f30292945e481c7b8a0c8908869", + "shared": true, + "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" + } +} + `) + }) + + // Call our API operation + network, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() + + // Assert no errors and equality + th.AssertNoErr(t, err) + th.AssertEquals(t, n.Status, "ACTIVE") +} +``` + +### Acceptance tests + +As we've already mentioned, unit tests have a very narrow and confined focus - +they test small units of behaviour. Acceptance tests on the other hand have a +far larger scope: they are fully functional tests that test the entire API of a +service in one fell swoop. They don't care about unit isolation or mocking +expectations, they instead do a full run-through and consequently test how the +entire system _integrates_ together. When an API satisfies expectations, it +proves by default that the requirements for a contract have been met. + +Please be aware that acceptance tests will hit a live API - and may incur +service charges from your provider. Although most tests handle their own +teardown procedures, it is always worth manually checking that resources are +deleted after the test suite finishes. + +### Running tests + +To run all tests: + +```bash +go test ./... +``` + +To run all tests with verbose output: + +```bash +go test -v ./... +``` + +To run tests that match certain [build tags](): + +```bash +go test -tags "foo bar" ./... +``` + +To run tests for a particular sub-package: + +```bash +cd ./path/to/package && go test . +``` + +## Basic style guide + +We follow the standard formatting recommendations and language idioms set out +in the [Effective Go](https://golang.org/doc/effective_go.html) guide. It's +definitely worth reading - but the relevant sections are +[formatting](https://golang.org/doc/effective_go.html#formatting) +and [names](https://golang.org/doc/effective_go.html#names). + +## 5 ways to get involved + +There are five main ways you can get involved in our open-source project, and +each is described briefly below. Once you've made up your mind and decided on +your fix, you will need to follow the same basic steps that all submissions are +required to adhere to: + +1. [fork](https://help.github.com/articles/fork-a-repo/) the `rackspace/gophercloud` repository +2. checkout a [new branch](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches) +3. submit your branch as a [pull request](https://help.github.com/articles/creating-a-pull-request/) + +### 1. Providing feedback + +On of the easiest ways to get readily involved in our project is to let us know +about your experiences using our SDK. Feedback like this is incredibly useful +to us, because it allows us to refine and change features based on what our +users want and expect of us. There are a bunch of ways to get in contact! You +can [ping us](https://developer.rackspace.com/support/) via e-mail, talk to us on irc +(#rackspace-dev on freenode), [tweet us](https://twitter.com/rackspace), or +submit an issue on our [bug tracker](/issues). Things you might like to tell us +are: + +* how easy was it to start using our SDK? +* did it meet your expectations? If not, why not? +* did our documentation help or hinder you? +* what could we improve in general? + +### 2. Fixing bugs + +If you want to start fixing open bugs, we'd really appreciate that! Bug fixing +is central to any project. The best way to get started is by heading to our +[bug tracker](https://github.com/rackspace/gophercloud/issues) and finding open +bugs that you think nobody is working on. It might be useful to comment on the +thread to see the current state of the issue and if anybody has made any +breakthroughs on it so far. + +### 3. Improving documentation + +We have three forms of documentation: + +* short README documents that briefly introduce a topic +* reference documentation on [godoc.org](http://godoc.org) that is automatically +generated from source code comments +* user documentation on our [homepage](http://gophercloud.io) that includes +getting started guides, installation guides and code samples + +If you feel that a certain section could be improved - whether it's to clarify +ambiguity, correct a technical mistake, or to fix a grammatical error - please +feel entitled to do so! We welcome doc pull requests with the same childlike +enthusiasm as any other contribution! + +### 4. Optimizing existing features + +If you would like to improve or optimize an existing feature, please be aware +that we adhere to [semantic versioning](http://semver.org) - which means that +we cannot introduce breaking changes to the API without a major version change +(v1.x -> v2.x). Making that leap is a big step, so we encourage contributors to +refactor rather than rewrite. Running tests will prevent regression and avoid +the possibility of breaking somebody's current implementation. + +Another tip is to keep the focus of your work as small as possible - try not to +introduce a change that affects lots and lots of files because it introduces +added risk and increases the cognitive load on the reviewers checking your +work. Change-sets which are easily understood and will not negatively impact +users are more likely to be integrated quickly. + +Lastly, if you're seeking to optimize a particular operation, you should try to +demonstrate a negative performance impact - perhaps using go's inbuilt +[benchmark capabilities](http://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go). + +### 5. Working on a new feature + +If you've found something we've left out, definitely feel free to start work on +introducing that feature. It's always useful to open an issue or submit a pull +request early on to indicate your intent to a core contributor - this enables +quick/early feedback and can help steer you in the right direction by avoiding +known issues. It might also help you avoid losing time implementing something +that might not ever work. One tip is to prefix your Pull Request issue title +with [wip] - then people know it's a work in progress. + +You must ensure that all of your work is well tested - both in terms of unit +and acceptance tests. Untested code will not be merged because it introduces +too much of a risk to end-users. + +Happy hacking! diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTORS.md b/vendor/github.com/rackspace/gophercloud/CONTRIBUTORS.md similarity index 91% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTORS.md rename to vendor/github.com/rackspace/gophercloud/CONTRIBUTORS.md index eb97094b73..63beb30b20 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTORS.md +++ b/vendor/github.com/rackspace/gophercloud/CONTRIBUTORS.md @@ -10,3 +10,4 @@ Contributors | Ash Wilson | | Jamie Hannaford | | Don Schenck | don.schenck@rackspace.com> +| Joe Topjian | diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/LICENSE b/vendor/github.com/rackspace/gophercloud/LICENSE similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/LICENSE rename to vendor/github.com/rackspace/gophercloud/LICENSE diff --git a/vendor/github.com/rackspace/gophercloud/README.md b/vendor/github.com/rackspace/gophercloud/README.md new file mode 100644 index 0000000000..05453bfede --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/README.md @@ -0,0 +1,160 @@ +# Gophercloud: the OpenStack SDK for Go +[![Build Status](https://travis-ci.org/rackspace/gophercloud.svg?branch=master)](https://travis-ci.org/rackspace/gophercloud) + +Gophercloud is a flexible SDK that allows you to consume and work with OpenStack +clouds in a simple and idiomatic way using golang. Many services are supported, +including Compute, Block Storage, Object Storage, Networking, and Identity. +Each service API is backed with getting started guides, code samples, reference +documentation, unit tests and acceptance tests. + +## Useful links + +* [Gophercloud homepage](http://gophercloud.io) +* [Reference documentation](http://godoc.org/github.com/rackspace/gophercloud) +* [Getting started guides](http://gophercloud.io/docs) +* [Effective Go](https://golang.org/doc/effective_go.html) + +## How to install + +Before installing, you need to ensure that your [GOPATH environment variable](https://golang.org/doc/code.html#GOPATH) +is pointing to an appropriate directory where you want to install Gophercloud: + +```bash +mkdir $HOME/go +export GOPATH=$HOME/go +``` + +To protect yourself against changes in your dependencies, we highly recommend choosing a +[dependency management solution](https://code.google.com/p/go-wiki/wiki/PackageManagementTools) for +your projects, such as [godep](https://github.com/tools/godep). Once this is set up, you can install +Gophercloud as a dependency like so: + +```bash +go get github.com/rackspace/gophercloud + +# Edit your code to import relevant packages from "github.com/rackspace/gophercloud" + +godep save ./... +``` + +This will install all the source files you need into a `Godeps/_workspace` directory, which is +referenceable from your own source files when you use the `godep go` command. + +## Getting started + +### Credentials + +Because you'll be hitting an API, you will need to retrieve your OpenStack +credentials and either store them as environment variables or in your local Go +files. The first method is recommended because it decouples credential +information from source code, allowing you to push the latter to your version +control system without any security risk. + +You will need to retrieve the following: + +* username +* password +* tenant name or tenant ID +* a valid Keystone identity URL + +For users that have the OpenStack dashboard installed, there's a shortcut. If +you visit the `project/access_and_security` path in Horizon and click on the +"Download OpenStack RC File" button at the top right hand corner, you will +download a bash file that exports all of your access details to environment +variables. To execute the file, run `source admin-openrc.sh` and you will be +prompted for your password. + +### Authentication + +Once you have access to your credentials, you can begin plugging them into +Gophercloud. The next step is authentication, and this is handled by a base +"Provider" struct. To get one, you can either pass in your credentials +explicitly, or tell Gophercloud to use environment variables: + +```go +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/openstack" + "github.com/rackspace/gophercloud/openstack/utils" +) + +// Option 1: Pass in the values yourself +opts := gophercloud.AuthOptions{ + IdentityEndpoint: "https://my-openstack.com:5000/v2.0", + Username: "{username}", + Password: "{password}", + TenantID: "{tenant_id}", +} + +// Option 2: Use a utility function to retrieve all your environment variables +opts, err := openstack.AuthOptionsFromEnv() +``` + +Once you have the `opts` variable, you can pass it in and get back a +`ProviderClient` struct: + +```go +provider, err := openstack.AuthenticatedClient(opts) +``` + +The `ProviderClient` is the top-level client that all of your OpenStack services +derive from. The provider contains all of the authentication details that allow +your Go code to access the API - such as the base URL and token ID. + +### Provision a server + +Once we have a base Provider, we inject it as a dependency into each OpenStack +service. In order to work with the Compute API, we need a Compute service +client; which can be created like so: + +```go +client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ + Region: os.Getenv("OS_REGION_NAME"), +}) +``` + +We then use this `client` for any Compute API operation we want. In our case, +we want to provision a new server - so we invoke the `Create` method and pass +in the flavor ID (hardware specification) and image ID (operating system) we're +interested in: + +```go +import "github.com/rackspace/gophercloud/openstack/compute/v2/servers" + +server, err := servers.Create(client, servers.CreateOpts{ + Name: "My new server!", + FlavorRef: "flavor_id", + ImageRef: "image_id", +}).Extract() +``` + +If you are unsure about what images and flavors are, you can read our [Compute +Getting Started guide](http://gophercloud.io/docs/compute). The above code +sample creates a new server with the parameters, and embodies the new resource +in the `server` variable (a +[`servers.Server`](http://godoc.org/github.com/rackspace/gophercloud) struct). + +### Next steps + +Cool! You've handled authentication, got your `ProviderClient` and provisioned +a new server. You're now ready to use more OpenStack services. + +* [Getting started with Compute](http://gophercloud.io/docs/compute) +* [Getting started with Object Storage](http://gophercloud.io/docs/object-storage) +* [Getting started with Networking](http://gophercloud.io/docs/networking) +* [Getting started with Block Storage](http://gophercloud.io/docs/block-storage) +* [Getting started with Identity](http://gophercloud.io/docs/identity) + +## Contributing + +Engaging the community and lowering barriers for contributors is something we +care a lot about. For this reason, we've taken the time to write a [contributing +guide](./CONTRIBUTING.md) for folks interested in getting involved in our project. +If you're not sure how you can get involved, feel free to submit an issue or +[contact us](https://developer.rackspace.com/support/). You don't need to be a +Go expert - all members of the community are welcome! + +## Help and feedback + +If you're struggling with something or have spotted a potential bug, feel free +to submit an issue to our [bug tracker](/issues) or [contact us directly](https://developer.rackspace.com/support/). diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/UPGRADING.md b/vendor/github.com/rackspace/gophercloud/UPGRADING.md similarity index 99% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/UPGRADING.md rename to vendor/github.com/rackspace/gophercloud/UPGRADING.md index a702cfc509..76a94d5703 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/UPGRADING.md +++ b/vendor/github.com/rackspace/gophercloud/UPGRADING.md @@ -8,7 +8,7 @@ extensible, maintainable and easy-to-use. Below we've compiled upgrade instructions for the various services that existed before. If you have a specific issue that is not addressed below, please [submit an issue](/issues/new) or -[e-mail our support team](mailto:sdk-support@rackspace.com). +[e-mail our support team](https://developer.rackspace.com/support/). * [Authentication](#authentication) * [Servers](#servers) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go b/vendor/github.com/rackspace/gophercloud/auth_options.go similarity index 96% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go rename to vendor/github.com/rackspace/gophercloud/auth_options.go index 19ce5d4a99..9819e45f2d 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go +++ b/vendor/github.com/rackspace/gophercloud/auth_options.go @@ -42,7 +42,5 @@ type AuthOptions struct { // re-authenticate automatically if/when your token expires. If you set it to // false, it will not cache these settings, but re-authentication will not be // possible. This setting defaults to false. - // - // This setting is speculative and is currently not respected! AllowReauth bool } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_results.go b/vendor/github.com/rackspace/gophercloud/auth_results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_results.go rename to vendor/github.com/rackspace/gophercloud/auth_results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/doc.go b/vendor/github.com/rackspace/gophercloud/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/doc.go rename to vendor/github.com/rackspace/gophercloud/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/endpoint_search.go b/vendor/github.com/rackspace/gophercloud/endpoint_search.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/endpoint_search.go rename to vendor/github.com/rackspace/gophercloud/endpoint_search.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/auth_env.go b/vendor/github.com/rackspace/gophercloud/openstack/auth_env.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/auth_env.go rename to vendor/github.com/rackspace/gophercloud/openstack/auth_env.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/client.go b/vendor/github.com/rackspace/gophercloud/openstack/client.go new file mode 100644 index 0000000000..1193b19a7a --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/client.go @@ -0,0 +1,263 @@ +package openstack + +import ( + "fmt" + "net/url" + + "github.com/rackspace/gophercloud" + tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" + tokens3 "github.com/rackspace/gophercloud/openstack/identity/v3/tokens" + "github.com/rackspace/gophercloud/openstack/utils" +) + +const ( + v20 = "v2.0" + v30 = "v3.0" +) + +// NewClient prepares an unauthenticated ProviderClient instance. +// Most users will probably prefer using the AuthenticatedClient function instead. +// This is useful if you wish to explicitly control the version of the identity service that's used for authentication explicitly, +// for example. +func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { + u, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + hadPath := u.Path != "" + u.Path, u.RawQuery, u.Fragment = "", "", "" + base := u.String() + + endpoint = gophercloud.NormalizeURL(endpoint) + base = gophercloud.NormalizeURL(base) + + if hadPath { + return &gophercloud.ProviderClient{ + IdentityBase: base, + IdentityEndpoint: endpoint, + }, nil + } + + return &gophercloud.ProviderClient{ + IdentityBase: base, + IdentityEndpoint: "", + }, nil +} + +// AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint specified by options, acquires a token, and +// returns a Client instance that's ready to operate. +// It first queries the root identity endpoint to determine which versions of the identity service are supported, then chooses +// the most recent identity service available to proceed. +func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) { + client, err := NewClient(options.IdentityEndpoint) + if err != nil { + return nil, err + } + + err = Authenticate(client, options) + if err != nil { + return nil, err + } + return client, nil +} + +// Authenticate or re-authenticate against the most recent identity service supported at the provided endpoint. +func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { + versions := []*utils.Version{ + &utils.Version{ID: v20, Priority: 20, Suffix: "/v2.0/"}, + &utils.Version{ID: v30, Priority: 30, Suffix: "/v3/"}, + } + + chosen, endpoint, err := utils.ChooseVersion(client, versions) + if err != nil { + return err + } + + switch chosen.ID { + case v20: + return v2auth(client, endpoint, options) + case v30: + return v3auth(client, endpoint, options) + default: + // The switch statement must be out of date from the versions list. + return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) + } +} + +// AuthenticateV2 explicitly authenticates against the identity v2 endpoint. +func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { + return v2auth(client, "", options) +} + +func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error { + v2Client := NewIdentityV2(client) + if endpoint != "" { + v2Client.Endpoint = endpoint + } + + result := tokens2.Create(v2Client, tokens2.AuthOptions{AuthOptions: options}) + + token, err := result.ExtractToken() + if err != nil { + return err + } + + catalog, err := result.ExtractServiceCatalog() + if err != nil { + return err + } + + if options.AllowReauth { + client.ReauthFunc = func() error { + client.TokenID = "" + return AuthenticateV2(client, options) + } + } + client.TokenID = token.ID + client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { + return V2EndpointURL(catalog, opts) + } + + return nil +} + +// AuthenticateV3 explicitly authenticates against the identity v3 service. +func AuthenticateV3(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { + return v3auth(client, "", options) +} + +func v3auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error { + // Override the generated service endpoint with the one returned by the version endpoint. + v3Client := NewIdentityV3(client) + if endpoint != "" { + v3Client.Endpoint = endpoint + } + + var scope *tokens3.Scope + if options.TenantID != "" { + scope = &tokens3.Scope{ + ProjectID: options.TenantID, + } + options.TenantID = "" + options.TenantName = "" + } else { + if options.TenantName != "" { + scope = &tokens3.Scope{ + ProjectName: options.TenantName, + DomainID: options.DomainID, + DomainName: options.DomainName, + } + options.TenantName = "" + } + } + + result := tokens3.Create(v3Client, options, scope) + + token, err := result.ExtractToken() + if err != nil { + return err + } + + catalog, err := result.ExtractServiceCatalog() + if err != nil { + return err + } + + client.TokenID = token.ID + + if options.AllowReauth { + client.ReauthFunc = func() error { + return AuthenticateV3(client, options) + } + } + client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { + return V3EndpointURL(catalog, opts) + } + + return nil +} + +// NewIdentityV2 creates a ServiceClient that may be used to interact with the v2 identity service. +func NewIdentityV2(client *gophercloud.ProviderClient) *gophercloud.ServiceClient { + v2Endpoint := client.IdentityBase + "v2.0/" + + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: v2Endpoint, + } +} + +// NewIdentityV3 creates a ServiceClient that may be used to access the v3 identity service. +func NewIdentityV3(client *gophercloud.ProviderClient) *gophercloud.ServiceClient { + v3Endpoint := client.IdentityBase + "v3/" + + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: v3Endpoint, + } +} + +// NewObjectStorageV1 creates a ServiceClient that may be used with the v1 object storage package. +func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("object-store") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewComputeV2 creates a ServiceClient that may be used with the v2 compute package. +func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("compute") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewNetworkV2 creates a ServiceClient that may be used with the v2 network package. +func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("network") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: url, + ResourceBase: url + "v2.0/", + }, nil +} + +// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 block storage service. +func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("volume") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1 +// CDN service. +func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("cdn") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 orchestration service. +func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("orchestration") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/doc.go new file mode 100644 index 0000000000..f74f58ce83 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/doc.go @@ -0,0 +1,3 @@ +// Package floatingip provides the ability to manage floating ips through +// nova-network +package floatingip diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/fixtures.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/fixtures.go new file mode 100644 index 0000000000..26f32995fd --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/fixtures.go @@ -0,0 +1,174 @@ +// +build fixtures + +package floatingip + +import ( + "fmt" + "net/http" + "testing" + + th "github.com/rackspace/gophercloud/testhelper" + "github.com/rackspace/gophercloud/testhelper/client" +) + +// ListOutput is a sample response to a List call. +const ListOutput = ` +{ + "floating_ips": [ + { + "fixed_ip": null, + "id": 1, + "instance_id": null, + "ip": "10.10.10.1", + "pool": "nova" + }, + { + "fixed_ip": "166.78.185.201", + "id": 2, + "instance_id": "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + "ip": "10.10.10.2", + "pool": "nova" + } + ] +} +` + +// GetOutput is a sample response to a Get call. +const GetOutput = ` +{ + "floating_ip": { + "fixed_ip": "166.78.185.201", + "id": 2, + "instance_id": "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + "ip": "10.10.10.2", + "pool": "nova" + } +} +` + +// CreateOutput is a sample response to a Post call +const CreateOutput = ` +{ + "floating_ip": { + "fixed_ip": null, + "id": 1, + "instance_id": null, + "ip": "10.10.10.1", + "pool": "nova" + } +} +` + +// FirstFloatingIP is the first result in ListOutput. +var FirstFloatingIP = FloatingIP{ + ID: "1", + IP: "10.10.10.1", + Pool: "nova", +} + +// SecondFloatingIP is the first result in ListOutput. +var SecondFloatingIP = FloatingIP{ + FixedIP: "166.78.185.201", + ID: "2", + InstanceID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + IP: "10.10.10.2", + Pool: "nova", +} + +// ExpectedFloatingIPsSlice is the slice of results that should be parsed +// from ListOutput, in the expected order. +var ExpectedFloatingIPsSlice = []FloatingIP{FirstFloatingIP, SecondFloatingIP} + +// CreatedFloatingIP is the parsed result from CreateOutput. +var CreatedFloatingIP = FloatingIP{ + ID: "1", + IP: "10.10.10.1", + Pool: "nova", +} + +// HandleListSuccessfully configures the test server to respond to a List request. +func HandleListSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/os-floating-ips", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, ListOutput) + }) +} + +// HandleGetSuccessfully configures the test server to respond to a Get request +// for an existing floating ip +func HandleGetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/os-floating-ips/2", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, GetOutput) + }) +} + +// HandleCreateSuccessfully configures the test server to respond to a Create request +// for a new floating ip +func HandleCreateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/os-floating-ips", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, ` +{ + "pool": "nova" +} +`) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, CreateOutput) + }) +} + +// HandleDeleteSuccessfully configures the test server to respond to a Delete request for a +// an existing floating ip +func HandleDeleteSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/os-floating-ips/1", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusAccepted) + }) +} + +// HandleAssociateSuccessfully configures the test server to respond to a Post request +// to associate an allocated floating IP +func HandleAssociateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, ` +{ + "addFloatingIp": { + "address": "10.10.10.2" + } +} +`) + + w.WriteHeader(http.StatusAccepted) + }) +} + +// HandleDisassociateSuccessfully configures the test server to respond to a Post request +// to disassociate an allocated floating IP +func HandleDisassociateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, ` +{ + "removeFloatingIp": { + "address": "10.10.10.2" + } +} +`) + + w.WriteHeader(http.StatusAccepted) + }) +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/requests.go new file mode 100644 index 0000000000..8abb72dcde --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/requests.go @@ -0,0 +1,92 @@ +package floatingip + +import ( + "errors" + + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// List returns a Pager that allows you to iterate over a collection of FloatingIPs. +func List(client *gophercloud.ServiceClient) pagination.Pager { + return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { + return FloatingIPsPage{pagination.SinglePageBase(r)} + }) +} + +// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the +// CreateOpts struct in this package does. +type CreateOptsBuilder interface { + ToFloatingIPCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies a Floating IP allocation request +type CreateOpts struct { + // Pool is the pool of floating IPs to allocate one from + Pool string +} + +// ToFloatingIPCreateMap constructs a request body from CreateOpts. +func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) { + if opts.Pool == "" { + return nil, errors.New("Missing field required for floating IP creation: Pool") + } + + return map[string]interface{}{"pool": opts.Pool}, nil +} + +// Create requests the creation of a new floating IP +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { + var res CreateResult + + reqBody, err := opts.ToFloatingIPCreateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = client.Post(createURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return res +} + +// Get returns data about a previously created FloatingIP. +func Get(client *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = client.Get(getURL(client, id), &res.Body, nil) + return res +} + +// Delete requests the deletion of a previous allocated FloatingIP. +func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { + var res DeleteResult + _, res.Err = client.Delete(deleteURL(client, id), nil) + return res +} + +// association / disassociation + +// Associate pairs an allocated floating IP with an instance +func Associate(client *gophercloud.ServiceClient, serverId, fip string) AssociateResult { + var res AssociateResult + + addFloatingIp := make(map[string]interface{}) + addFloatingIp["address"] = fip + reqBody := map[string]interface{}{"addFloatingIp": addFloatingIp} + + _, res.Err = client.Post(associateURL(client, serverId), reqBody, nil, nil) + return res +} + +// Disassociate decouples an allocated floating IP from an instance +func Disassociate(client *gophercloud.ServiceClient, serverId, fip string) DisassociateResult { + var res DisassociateResult + + removeFloatingIp := make(map[string]interface{}) + removeFloatingIp["address"] = fip + reqBody := map[string]interface{}{"removeFloatingIp": removeFloatingIp} + + _, res.Err = client.Post(disassociateURL(client, serverId), reqBody, nil, nil) + return res +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/results.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/results.go new file mode 100644 index 0000000000..be77fa1792 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/results.go @@ -0,0 +1,99 @@ +package floatingip + +import ( + "github.com/mitchellh/mapstructure" + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// A FloatingIP is an IP that can be associated with an instance +type FloatingIP struct { + // ID is a unique ID of the Floating IP + ID string `mapstructure:"id"` + + // FixedIP is the IP of the instance related to the Floating IP + FixedIP string `mapstructure:"fixed_ip,omitempty"` + + // InstanceID is the ID of the instance that is using the Floating IP + InstanceID string `mapstructure:"instance_id"` + + // IP is the actual Floating IP + IP string `mapstructure:"ip"` + + // Pool is the pool of floating IPs that this floating IP belongs to + Pool string `mapstructure:"pool"` +} + +// FloatingIPsPage stores a single, only page of FloatingIPs +// results from a List call. +type FloatingIPsPage struct { + pagination.SinglePageBase +} + +// IsEmpty determines whether or not a FloatingIPsPage is empty. +func (page FloatingIPsPage) IsEmpty() (bool, error) { + va, err := ExtractFloatingIPs(page) + return len(va) == 0, err +} + +// ExtractFloatingIPs interprets a page of results as a slice of +// FloatingIPs. +func ExtractFloatingIPs(page pagination.Page) ([]FloatingIP, error) { + casted := page.(FloatingIPsPage).Body + var response struct { + FloatingIPs []FloatingIP `mapstructure:"floating_ips"` + } + + err := mapstructure.WeakDecode(casted, &response) + + return response.FloatingIPs, err +} + +type FloatingIPResult struct { + gophercloud.Result +} + +// Extract is a method that attempts to interpret any FloatingIP resource +// response as a FloatingIP struct. +func (r FloatingIPResult) Extract() (*FloatingIP, error) { + if r.Err != nil { + return nil, r.Err + } + + var res struct { + FloatingIP *FloatingIP `json:"floating_ip" mapstructure:"floating_ip"` + } + + err := mapstructure.WeakDecode(r.Body, &res) + return res.FloatingIP, err +} + +// CreateResult is the response from a Create operation. Call its Extract method to interpret it +// as a FloatingIP. +type CreateResult struct { + FloatingIPResult +} + +// GetResult is the response from a Get operation. Call its Extract method to interpret it +// as a FloatingIP. +type GetResult struct { + FloatingIPResult +} + +// DeleteResult is the response from a Delete operation. Call its Extract method to determine if +// the call succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// AssociateResult is the response from a Delete operation. Call its Extract method to determine if +// the call succeeded or failed. +type AssociateResult struct { + gophercloud.ErrResult +} + +// DisassociateResult is the response from a Delete operation. Call its Extract method to determine if +// the call succeeded or failed. +type DisassociateResult struct { + gophercloud.ErrResult +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/urls.go new file mode 100644 index 0000000000..54198f8529 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip/urls.go @@ -0,0 +1,37 @@ +package floatingip + +import "github.com/rackspace/gophercloud" + +const resourcePath = "os-floating-ips" + +func resourceURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(resourcePath) +} + +func listURL(c *gophercloud.ServiceClient) string { + return resourceURL(c) +} + +func createURL(c *gophercloud.ServiceClient) string { + return resourceURL(c) +} + +func getURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id) +} + +func deleteURL(c *gophercloud.ServiceClient, id string) string { + return getURL(c, id) +} + +func serverURL(c *gophercloud.ServiceClient, serverId string) string { + return c.ServiceURL("servers/" + serverId + "/action") +} + +func associateURL(c *gophercloud.ServiceClient, serverId string) string { + return serverURL(c, serverId) +} + +func disassociateURL(c *gophercloud.ServiceClient, serverId string) string { + return serverURL(c, serverId) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/fixtures.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/fixtures.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/fixtures.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/fixtures.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go new file mode 100644 index 0000000000..c56ee67ea2 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go @@ -0,0 +1,102 @@ +package keypairs + +import ( + "errors" + + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/openstack/compute/v2/servers" + "github.com/rackspace/gophercloud/pagination" +) + +// CreateOptsExt adds a KeyPair option to the base CreateOpts. +type CreateOptsExt struct { + servers.CreateOptsBuilder + KeyName string `json:"key_name,omitempty"` +} + +// ToServerCreateMap adds the key_name and, optionally, key_data options to +// the base server creation options. +func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { + base, err := opts.CreateOptsBuilder.ToServerCreateMap() + if err != nil { + return nil, err + } + + if opts.KeyName == "" { + return base, nil + } + + serverMap := base["server"].(map[string]interface{}) + serverMap["key_name"] = opts.KeyName + + return base, nil +} + +// List returns a Pager that allows you to iterate over a collection of KeyPairs. +func List(client *gophercloud.ServiceClient) pagination.Pager { + return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { + return KeyPairPage{pagination.SinglePageBase(r)} + }) +} + +// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the +// CreateOpts struct in this package does. +type CreateOptsBuilder interface { + ToKeyPairCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies keypair creation or import parameters. +type CreateOpts struct { + // Name [required] is a friendly name to refer to this KeyPair in other services. + Name string + + // PublicKey [optional] is a pregenerated OpenSSH-formatted public key. If provided, this key + // will be imported and no new key will be created. + PublicKey string +} + +// ToKeyPairCreateMap constructs a request body from CreateOpts. +func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) { + if opts.Name == "" { + return nil, errors.New("Missing field required for keypair creation: Name") + } + + keypair := make(map[string]interface{}) + keypair["name"] = opts.Name + if opts.PublicKey != "" { + keypair["public_key"] = opts.PublicKey + } + + return map[string]interface{}{"keypair": keypair}, nil +} + +// Create requests the creation of a new keypair on the server, or to import a pre-existing +// keypair. +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { + var res CreateResult + + reqBody, err := opts.ToKeyPairCreateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = client.Post(createURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return res +} + +// Get returns public data about a previously uploaded KeyPair. +func Get(client *gophercloud.ServiceClient, name string) GetResult { + var res GetResult + _, res.Err = client.Get(getURL(client, name), &res.Body, nil) + return res +} + +// Delete requests the deletion of a previous stored KeyPair from the server. +func Delete(client *gophercloud.ServiceClient, name string) DeleteResult { + var res DeleteResult + _, res.Err = client.Delete(deleteURL(client, name), nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/results.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/fixtures.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/fixtures.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/fixtures.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/fixtures.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests.go new file mode 100644 index 0000000000..0e090e69f2 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop/requests.go @@ -0,0 +1,23 @@ +package startstop + +import "github.com/rackspace/gophercloud" + +func actionURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("servers", id, "action") +} + +// Start is the operation responsible for starting a Compute server. +func Start(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { + var res gophercloud.ErrResult + reqBody := map[string]interface{}{"os-start": nil} + _, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil) + return res +} + +// Stop is the operation responsible for stopping a Compute server. +func Stop(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult { + var res gophercloud.ErrResult + reqBody := map[string]interface{}{"os-stop": nil} + _, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/doc.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go new file mode 100644 index 0000000000..586be67ac2 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go @@ -0,0 +1,68 @@ +package flavors + +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToFlavorListQuery() (string, error) +} + +// ListOpts helps control the results returned by the List() function. +// For example, a flavor with a minDisk field of 10 will not be returned if you specify MinDisk set to 20. +// Typically, software will use the last ID of the previous call to List to set the Marker for the current call. +type ListOpts struct { + + // ChangesSince, if provided, instructs List to return only those things which have changed since the timestamp provided. + ChangesSince string `q:"changes-since"` + + // MinDisk and MinRAM, if provided, elides flavors which do not meet your criteria. + MinDisk int `q:"minDisk"` + MinRAM int `q:"minRam"` + + // Marker and Limit control paging. + // Marker instructs List where to start listing from. + Marker string `q:"marker"` + + // Limit instructs List to refrain from sending excessively large lists of flavors. + Limit int `q:"limit"` +} + +// ToFlavorListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToFlavorListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// ListDetail instructs OpenStack to provide a list of flavors. +// You may provide criteria by which List curtails its results for easier processing. +// See ListOpts for more details. +func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(client) + if opts != nil { + query, err := opts.ToFlavorListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + createPage := func(r pagination.PageResult) pagination.Page { + return FlavorPage{pagination.LinkedPageBase{PageResult: r}} + } + + return pagination.NewPager(client, url, createPage) +} + +// Get instructs OpenStack to provide details on a single flavor, identified by its ID. +// Use ExtractFlavor to convert its result into a Flavor. +func Get(client *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = client.Get(getURL(client, id), &res.Body, nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/results.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/doc.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go new file mode 100644 index 0000000000..5eb19b5aa3 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go @@ -0,0 +1,65 @@ +package images + +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToImageListQuery() (string, error) +} + +// ListOpts contain options for limiting the number of Images returned from a call to ListDetail. +type ListOpts struct { + // When the image last changed status (in date-time format). + ChangesSince string `q:"changes-since"` + // The number of Images to return. + Limit int `q:"limit"` + // UUID of the Image at which to set a marker. + Marker string `q:"marker"` + // The name of the Image. + Name string `q:"name"` + // The name of the Server (in URL format). + Server string `q:"server"` + // The current status of the Image. + Status string `q:"status"` + // The value of the type of image (e.g. BASE, SERVER, ALL) + Type string `q:"type"` +} + +// ToImageListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToImageListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// ListDetail enumerates the available images. +func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listDetailURL(client) + if opts != nil { + query, err := opts.ToImageListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + createPage := func(r pagination.PageResult) pagination.Page { + return ImagePage{pagination.LinkedPageBase{PageResult: r}} + } + + return pagination.NewPager(client, url, createPage) +} + +// Get acquires additional detail about a specific image by ID. +// Use ExtractImage() to interpret the result as an openstack Image. +func Get(client *gophercloud.ServiceClient, id string) GetResult { + var result GetResult + _, result.Err = client.Get(getURL(client, id), &result.Body, nil) + return result +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/results.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/doc.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/fixtures.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/fixtures.go new file mode 100644 index 0000000000..e47bc0e8b0 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/fixtures.go @@ -0,0 +1,653 @@ +// +build fixtures + +package servers + +import ( + "fmt" + "net/http" + "testing" + + th "github.com/rackspace/gophercloud/testhelper" + "github.com/rackspace/gophercloud/testhelper/client" +) + +// ServerListBody contains the canned body of a servers.List response. +const ServerListBody = ` +{ + "servers": [ + { + "status": "ACTIVE", + "updated": "2014-09-25T13:10:10Z", + "hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", + "OS-EXT-SRV-ATTR:host": "devstack", + "addresses": { + "private": [ + { + "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b", + "version": 4, + "addr": "10.0.0.32", + "OS-EXT-IPS:type": "fixed" + } + ] + }, + "links": [ + { + "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", + "rel": "self" + }, + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", + "rel": "bookmark" + } + ], + "key_name": null, + "image": { + "id": "f90f6034-2570-4974-8351-6b49732ef2eb", + "links": [ + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", + "rel": "bookmark" + } + ] + }, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "OS-EXT-SRV-ATTR:instance_name": "instance-0000001e", + "OS-SRV-USG:launched_at": "2014-09-25T13:10:10.000000", + "OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack", + "flavor": { + "id": "1", + "links": [ + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", + "rel": "bookmark" + } + ] + }, + "id": "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", + "security_groups": [ + { + "name": "default" + } + ], + "OS-SRV-USG:terminated_at": null, + "OS-EXT-AZ:availability_zone": "nova", + "user_id": "9349aff8be7545ac9d2f1d00999a23cd", + "name": "herp", + "created": "2014-09-25T13:10:02Z", + "tenant_id": "fcad67a6189847c4aecfa3c81a05783b", + "OS-DCF:diskConfig": "MANUAL", + "os-extended-volumes:volumes_attached": [], + "accessIPv4": "", + "accessIPv6": "", + "progress": 0, + "OS-EXT-STS:power_state": 1, + "config_drive": "", + "metadata": {} + }, + { + "status": "ACTIVE", + "updated": "2014-09-25T13:04:49Z", + "hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", + "OS-EXT-SRV-ATTR:host": "devstack", + "addresses": { + "private": [ + { + "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be", + "version": 4, + "addr": "10.0.0.31", + "OS-EXT-IPS:type": "fixed" + } + ] + }, + "links": [ + { + "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "rel": "self" + }, + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "rel": "bookmark" + } + ], + "key_name": null, + "image": { + "id": "f90f6034-2570-4974-8351-6b49732ef2eb", + "links": [ + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", + "rel": "bookmark" + } + ] + }, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "OS-EXT-SRV-ATTR:instance_name": "instance-0000001d", + "OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000", + "OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack", + "flavor": { + "id": "1", + "links": [ + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", + "rel": "bookmark" + } + ] + }, + "id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "security_groups": [ + { + "name": "default" + } + ], + "OS-SRV-USG:terminated_at": null, + "OS-EXT-AZ:availability_zone": "nova", + "user_id": "9349aff8be7545ac9d2f1d00999a23cd", + "name": "derp", + "created": "2014-09-25T13:04:41Z", + "tenant_id": "fcad67a6189847c4aecfa3c81a05783b", + "OS-DCF:diskConfig": "MANUAL", + "os-extended-volumes:volumes_attached": [], + "accessIPv4": "", + "accessIPv6": "", + "progress": 0, + "OS-EXT-STS:power_state": 1, + "config_drive": "", + "metadata": {} + } + ] +} +` + +// SingleServerBody is the canned body of a Get request on an existing server. +const SingleServerBody = ` +{ + "server": { + "status": "ACTIVE", + "updated": "2014-09-25T13:04:49Z", + "hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", + "OS-EXT-SRV-ATTR:host": "devstack", + "addresses": { + "private": [ + { + "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be", + "version": 4, + "addr": "10.0.0.31", + "OS-EXT-IPS:type": "fixed" + } + ] + }, + "links": [ + { + "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "rel": "self" + }, + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "rel": "bookmark" + } + ], + "key_name": null, + "image": { + "id": "f90f6034-2570-4974-8351-6b49732ef2eb", + "links": [ + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", + "rel": "bookmark" + } + ] + }, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "OS-EXT-SRV-ATTR:instance_name": "instance-0000001d", + "OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000", + "OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack", + "flavor": { + "id": "1", + "links": [ + { + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", + "rel": "bookmark" + } + ] + }, + "id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "security_groups": [ + { + "name": "default" + } + ], + "OS-SRV-USG:terminated_at": null, + "OS-EXT-AZ:availability_zone": "nova", + "user_id": "9349aff8be7545ac9d2f1d00999a23cd", + "name": "derp", + "created": "2014-09-25T13:04:41Z", + "tenant_id": "fcad67a6189847c4aecfa3c81a05783b", + "OS-DCF:diskConfig": "MANUAL", + "os-extended-volumes:volumes_attached": [], + "accessIPv4": "", + "accessIPv6": "", + "progress": 0, + "OS-EXT-STS:power_state": 1, + "config_drive": "", + "metadata": {} + } +} +` + +var ( + // ServerHerp is a Server struct that should correspond to the first result in ServerListBody. + ServerHerp = Server{ + Status: "ACTIVE", + Updated: "2014-09-25T13:10:10Z", + HostID: "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", + Addresses: map[string]interface{}{ + "private": []interface{}{ + map[string]interface{}{ + "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b", + "version": float64(4), + "addr": "10.0.0.32", + "OS-EXT-IPS:type": "fixed", + }, + }, + }, + Links: []interface{}{ + map[string]interface{}{ + "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", + "rel": "self", + }, + map[string]interface{}{ + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", + "rel": "bookmark", + }, + }, + Image: map[string]interface{}{ + "id": "f90f6034-2570-4974-8351-6b49732ef2eb", + "links": []interface{}{ + map[string]interface{}{ + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", + "rel": "bookmark", + }, + }, + }, + Flavor: map[string]interface{}{ + "id": "1", + "links": []interface{}{ + map[string]interface{}{ + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", + "rel": "bookmark", + }, + }, + }, + ID: "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5", + UserID: "9349aff8be7545ac9d2f1d00999a23cd", + Name: "herp", + Created: "2014-09-25T13:10:02Z", + TenantID: "fcad67a6189847c4aecfa3c81a05783b", + Metadata: map[string]interface{}{}, + SecurityGroups: []map[string]interface{}{ + map[string]interface{}{ + "name": "default", + }, + }, + } + + // ServerDerp is a Server struct that should correspond to the second server in ServerListBody. + ServerDerp = Server{ + Status: "ACTIVE", + Updated: "2014-09-25T13:04:49Z", + HostID: "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362", + Addresses: map[string]interface{}{ + "private": []interface{}{ + map[string]interface{}{ + "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be", + "version": float64(4), + "addr": "10.0.0.31", + "OS-EXT-IPS:type": "fixed", + }, + }, + }, + Links: []interface{}{ + map[string]interface{}{ + "href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "rel": "self", + }, + map[string]interface{}{ + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba", + "rel": "bookmark", + }, + }, + Image: map[string]interface{}{ + "id": "f90f6034-2570-4974-8351-6b49732ef2eb", + "links": []interface{}{ + map[string]interface{}{ + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", + "rel": "bookmark", + }, + }, + }, + Flavor: map[string]interface{}{ + "id": "1", + "links": []interface{}{ + map[string]interface{}{ + "href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1", + "rel": "bookmark", + }, + }, + }, + ID: "9e5476bd-a4ec-4653-93d6-72c93aa682ba", + UserID: "9349aff8be7545ac9d2f1d00999a23cd", + Name: "derp", + Created: "2014-09-25T13:04:41Z", + TenantID: "fcad67a6189847c4aecfa3c81a05783b", + Metadata: map[string]interface{}{}, + SecurityGroups: []map[string]interface{}{ + map[string]interface{}{ + "name": "default", + }, + }, + } +) + +// HandleServerCreationSuccessfully sets up the test server to respond to a server creation request +// with a given response. +func HandleServerCreationSuccessfully(t *testing.T, response string) { + th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ + "server": { + "name": "derp", + "imageRef": "f90f6034-2570-4974-8351-6b49732ef2eb", + "flavorRef": "1" + } + }`) + + w.WriteHeader(http.StatusAccepted) + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, response) + }) +} + +// HandleServerListSuccessfully sets up the test server to respond to a server List request. +func HandleServerListSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + r.ParseForm() + marker := r.Form.Get("marker") + switch marker { + case "": + fmt.Fprintf(w, ServerListBody) + case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": + fmt.Fprintf(w, `{ "servers": [] }`) + default: + t.Fatalf("/servers/detail invoked with unexpected marker=[%s]", marker) + } + }) +} + +// HandleServerDeletionSuccessfully sets up the test server to respond to a server deletion request. +func HandleServerDeletionSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleServerGetSuccessfully sets up the test server to respond to a server Get request. +func HandleServerGetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + + fmt.Fprintf(w, SingleServerBody) + }) +} + +// HandleServerUpdateSuccessfully sets up the test server to respond to a server Update request. +func HandleServerUpdateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestJSONRequest(t, r, `{ "server": { "name": "new-name" } }`) + + fmt.Fprintf(w, SingleServerBody) + }) +} + +// HandleAdminPasswordChangeSuccessfully sets up the test server to respond to a server password +// change request. +func HandleAdminPasswordChangeSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ "changePassword": { "adminPass": "new-password" } }`) + + w.WriteHeader(http.StatusAccepted) + }) +} + +// HandleRebootSuccessfully sets up the test server to respond to a reboot request with success. +func HandleRebootSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ "reboot": { "type": "SOFT" } }`) + + w.WriteHeader(http.StatusAccepted) + }) +} + +// HandleRebuildSuccessfully sets up the test server to respond to a rebuild request with success. +func HandleRebuildSuccessfully(t *testing.T, response string) { + th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, ` + { + "rebuild": { + "name": "new-name", + "adminPass": "swordfish", + "imageRef": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb", + "accessIPv4": "1.2.3.4" + } + } + `) + + w.WriteHeader(http.StatusAccepted) + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, response) + }) +} + +// HandleServerRescueSuccessfully sets up the test server to respond to a server Rescue request. +func HandleServerRescueSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ "rescue": { "adminPass": "1234567890" } }`) + + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{ "adminPass": "1234567890" }`)) + }) +} + +// HandleMetadatumGetSuccessfully sets up the test server to respond to a metadatum Get request. +func HandleMetadatumGetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + w.Write([]byte(`{ "meta": {"foo":"bar"}}`)) + }) +} + +// HandleMetadatumCreateSuccessfully sets up the test server to respond to a metadatum Create request. +func HandleMetadatumCreateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ + "meta": { + "foo": "bar" + } + }`) + + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + w.Write([]byte(`{ "meta": {"foo":"bar"}}`)) + }) +} + +// HandleMetadatumDeleteSuccessfully sets up the test server to respond to a metadatum Delete request. +func HandleMetadatumDeleteSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.WriteHeader(http.StatusNoContent) + }) +} + +// HandleMetadataGetSuccessfully sets up the test server to respond to a metadata Get request. +func HandleMetadataGetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{ "metadata": {"foo":"bar", "this":"that"}}`)) + }) +} + +// HandleMetadataResetSuccessfully sets up the test server to respond to a metadata Create request. +func HandleMetadataResetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ + "metadata": { + "foo": "bar", + "this": "that" + } + }`) + + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + w.Write([]byte(`{ "metadata": {"foo":"bar", "this":"that"}}`)) + }) +} + +// HandleMetadataUpdateSuccessfully sets up the test server to respond to a metadata Update request. +func HandleMetadataUpdateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ + "metadata": { + "foo": "baz", + "this": "those" + } + }`) + + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + w.Write([]byte(`{ "metadata": {"foo":"baz", "this":"those"}}`)) + }) +} + +// ListAddressesExpected represents an expected repsonse from a ListAddresses request. +var ListAddressesExpected = map[string][]Address{ + "public": []Address{ + Address{ + Version: 4, + Address: "80.56.136.39", + }, + Address{ + Version: 6, + Address: "2001:4800:790e:510:be76:4eff:fe04:82a8", + }, + }, + "private": []Address{ + Address{ + Version: 4, + Address: "10.880.3.154", + }, + }, +} + +// HandleAddressListSuccessfully sets up the test server to respond to a ListAddresses request. +func HandleAddressListSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/asdfasdfasdf/ips", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, `{ + "addresses": { + "public": [ + { + "version": 4, + "addr": "50.56.176.35" + }, + { + "version": 6, + "addr": "2001:4800:780e:510:be76:4eff:fe04:84a8" + } + ], + "private": [ + { + "version": 4, + "addr": "10.180.3.155" + } + ] + } + }`) + }) +} + +// ListNetworkAddressesExpected represents an expected repsonse from a ListAddressesByNetwork request. +var ListNetworkAddressesExpected = []Address{ + Address{ + Version: 4, + Address: "50.56.176.35", + }, + Address{ + Version: 6, + Address: "2001:4800:780e:510:be76:4eff:fe04:84a8", + }, +} + +// HandleNetworkAddressListSuccessfully sets up the test server to respond to a ListAddressesByNetwork request. +func HandleNetworkAddressListSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/servers/asdfasdfasdf/ips/public", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, `{ + "public": [ + { + "version": 4, + "addr": "50.56.176.35" + }, + { + "version": 6, + "addr": "2001:4800:780e:510:be76:4eff:fe04:84a8" + } + ] + }`) + }) +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go new file mode 100644 index 0000000000..e0950e4e09 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go @@ -0,0 +1,703 @@ +package servers + +import ( + "encoding/base64" + "errors" + "fmt" + + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToServerListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the server attributes you want to see returned. Marker and Limit are used +// for pagination. +type ListOpts struct { + // A time/date stamp for when the server last changed status. + ChangesSince string `q:"changes-since"` + + // Name of the image in URL format. + Image string `q:"image"` + + // Name of the flavor in URL format. + Flavor string `q:"flavor"` + + // Name of the server as a string; can be queried with regular expressions. + // Realize that ?name=bob returns both bob and bobb. If you need to match bob + // only, you can use a regular expression matching the syntax of the + // underlying database server implemented for Compute. + Name string `q:"name"` + + // Value of the status of the server so that you can filter on "ACTIVE" for example. + Status string `q:"status"` + + // Name of the host as a string. + Host string `q:"host"` + + // UUID of the server at which you want to set a marker. + Marker string `q:"marker"` + + // Integer value for the limit of values to return. + Limit int `q:"limit"` +} + +// ToServerListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToServerListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// List makes a request against the API to list servers accessible to you. +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listDetailURL(client) + + if opts != nil { + query, err := opts.ToServerListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + createPageFn := func(r pagination.PageResult) pagination.Page { + return ServerPage{pagination.LinkedPageBase{PageResult: r}} + } + + return pagination.NewPager(client, url, createPageFn) +} + +// CreateOptsBuilder describes struct types that can be accepted by the Create call. +// The CreateOpts struct in this package does. +type CreateOptsBuilder interface { + ToServerCreateMap() (map[string]interface{}, error) +} + +// Network is used within CreateOpts to control a new server's network attachments. +type Network struct { + // UUID of a nova-network to attach to the newly provisioned server. + // Required unless Port is provided. + UUID string + + // Port of a neutron network to attach to the newly provisioned server. + // Required unless UUID is provided. + Port string + + // FixedIP [optional] specifies a fixed IPv4 address to be used on this network. + FixedIP string +} + +// CreateOpts specifies server creation parameters. +type CreateOpts struct { + // Name [required] is the name to assign to the newly launched server. + Name string + + // ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state. + // Optional if using the boot-from-volume extension. + ImageRef string + + // FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs. + FlavorRef string + + // SecurityGroups [optional] lists the names of the security groups to which this server should belong. + SecurityGroups []string + + // UserData [optional] contains configuration information or scripts to use upon launch. + // Create will base64-encode it for you. + UserData []byte + + // AvailabilityZone [optional] in which to launch the server. + AvailabilityZone string + + // Networks [optional] dictates how this server will be attached to available networks. + // By default, the server will be attached to all isolated networks for the tenant. + Networks []Network + + // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. + Metadata map[string]string + + // Personality [optional] includes the path and contents of a file to inject into the server at launch. + // The maximum size of the file is 255 bytes (decoded). + Personality []byte + + // ConfigDrive [optional] enables metadata injection through a configuration drive. + ConfigDrive bool + + // AdminPass [optional] sets the root user password. If not set, a randomly-generated + // password will be created and returned in the response. + AdminPass string + + // AccessIPv4 [optional] specifies an IPv4 address for the instance. + AccessIPv4 string + + // AccessIPv6 [optional] specifies an IPv6 address for the instance. + AccessIPv6 string +} + +// ToServerCreateMap assembles a request body based on the contents of a CreateOpts. +func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { + server := make(map[string]interface{}) + + server["name"] = opts.Name + server["imageRef"] = opts.ImageRef + server["flavorRef"] = opts.FlavorRef + + if opts.UserData != nil { + encoded := base64.StdEncoding.EncodeToString(opts.UserData) + server["user_data"] = &encoded + } + if opts.Personality != nil { + encoded := base64.StdEncoding.EncodeToString(opts.Personality) + server["personality"] = &encoded + } + if opts.ConfigDrive { + server["config_drive"] = "true" + } + if opts.AvailabilityZone != "" { + server["availability_zone"] = opts.AvailabilityZone + } + if opts.Metadata != nil { + server["metadata"] = opts.Metadata + } + if opts.AdminPass != "" { + server["adminPass"] = opts.AdminPass + } + if opts.AccessIPv4 != "" { + server["accessIPv4"] = opts.AccessIPv4 + } + if opts.AccessIPv6 != "" { + server["accessIPv6"] = opts.AccessIPv6 + } + + if len(opts.SecurityGroups) > 0 { + securityGroups := make([]map[string]interface{}, len(opts.SecurityGroups)) + for i, groupName := range opts.SecurityGroups { + securityGroups[i] = map[string]interface{}{"name": groupName} + } + server["security_groups"] = securityGroups + } + + if len(opts.Networks) > 0 { + networks := make([]map[string]interface{}, len(opts.Networks)) + for i, net := range opts.Networks { + networks[i] = make(map[string]interface{}) + if net.UUID != "" { + networks[i]["uuid"] = net.UUID + } + if net.Port != "" { + networks[i]["port"] = net.Port + } + if net.FixedIP != "" { + networks[i]["fixed_ip"] = net.FixedIP + } + } + server["networks"] = networks + } + + return map[string]interface{}{"server": server}, nil +} + +// Create requests a server to be provisioned to the user in the current tenant. +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { + var res CreateResult + + reqBody, err := opts.ToServerCreateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = client.Post(listURL(client), reqBody, &res.Body, nil) + return res +} + +// Delete requests that a server previously provisioned be removed from your account. +func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { + var res DeleteResult + _, res.Err = client.Delete(deleteURL(client, id), nil) + return res +} + +// Get requests details on a single server, by ID. +func Get(client *gophercloud.ServiceClient, id string) GetResult { + var result GetResult + _, result.Err = client.Get(getURL(client, id), &result.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 203}, + }) + return result +} + +// UpdateOptsBuilder allows extensions to add additional attributes to the Update request. +type UpdateOptsBuilder interface { + ToServerUpdateMap() map[string]interface{} +} + +// UpdateOpts specifies the base attributes that may be updated on an existing server. +type UpdateOpts struct { + // Name [optional] changes the displayed name of the server. + // The server host name will *not* change. + // Server names are not constrained to be unique, even within the same tenant. + Name string + + // AccessIPv4 [optional] provides a new IPv4 address for the instance. + AccessIPv4 string + + // AccessIPv6 [optional] provides a new IPv6 address for the instance. + AccessIPv6 string +} + +// ToServerUpdateMap formats an UpdateOpts structure into a request body. +func (opts UpdateOpts) ToServerUpdateMap() map[string]interface{} { + server := make(map[string]string) + if opts.Name != "" { + server["name"] = opts.Name + } + if opts.AccessIPv4 != "" { + server["accessIPv4"] = opts.AccessIPv4 + } + if opts.AccessIPv6 != "" { + server["accessIPv6"] = opts.AccessIPv6 + } + return map[string]interface{}{"server": server} +} + +// Update requests that various attributes of the indicated server be changed. +func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { + var result UpdateResult + reqBody := opts.ToServerUpdateMap() + _, result.Err = client.Put(updateURL(client, id), reqBody, &result.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return result +} + +// ChangeAdminPassword alters the administrator or root password for a specified server. +func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) ActionResult { + var req struct { + ChangePassword struct { + AdminPass string `json:"adminPass"` + } `json:"changePassword"` + } + + req.ChangePassword.AdminPass = newPassword + + var res ActionResult + _, res.Err = client.Post(actionURL(client, id), req, nil, nil) + return res +} + +// ErrArgument errors occur when an argument supplied to a package function +// fails to fall within acceptable values. For example, the Reboot() function +// expects the "how" parameter to be one of HardReboot or SoftReboot. These +// constants are (currently) strings, leading someone to wonder if they can pass +// other string values instead, perhaps in an effort to break the API of their +// provider. Reboot() returns this error in this situation. +// +// Function identifies which function was called/which function is generating +// the error. +// Argument identifies which formal argument was responsible for producing the +// error. +// Value provides the value as it was passed into the function. +type ErrArgument struct { + Function, Argument string + Value interface{} +} + +// Error yields a useful diagnostic for debugging purposes. +func (e *ErrArgument) Error() string { + return fmt.Sprintf("Bad argument in call to %s, formal parameter %s, value %#v", e.Function, e.Argument, e.Value) +} + +func (e *ErrArgument) String() string { + return e.Error() +} + +// RebootMethod describes the mechanisms by which a server reboot can be requested. +type RebootMethod string + +// These constants determine how a server should be rebooted. +// See the Reboot() function for further details. +const ( + SoftReboot RebootMethod = "SOFT" + HardReboot RebootMethod = "HARD" + OSReboot = SoftReboot + PowerCycle = HardReboot +) + +// Reboot requests that a given server reboot. +// Two methods exist for rebooting a server: +// +// HardReboot (aka PowerCycle) restarts the server instance by physically cutting power to the machine, or if a VM, +// terminating it at the hypervisor level. +// It's done. Caput. Full stop. +// Then, after a brief while, power is restored or the VM instance restarted. +// +// SoftReboot (aka OSReboot) simply tells the OS to restart under its own procedures. +// E.g., in Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to restart the machine. +func Reboot(client *gophercloud.ServiceClient, id string, how RebootMethod) ActionResult { + var res ActionResult + + if (how != SoftReboot) && (how != HardReboot) { + res.Err = &ErrArgument{ + Function: "Reboot", + Argument: "how", + Value: how, + } + return res + } + + reqBody := struct { + C map[string]string `json:"reboot"` + }{ + map[string]string{"type": string(how)}, + } + + _, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil) + return res +} + +// RebuildOptsBuilder is an interface that allows extensions to override the +// default behaviour of rebuild options +type RebuildOptsBuilder interface { + ToServerRebuildMap() (map[string]interface{}, error) +} + +// RebuildOpts represents the configuration options used in a server rebuild +// operation +type RebuildOpts struct { + // Required. The ID of the image you want your server to be provisioned on + ImageID string + + // Name to set the server to + Name string + + // Required. The server's admin password + AdminPass string + + // AccessIPv4 [optional] provides a new IPv4 address for the instance. + AccessIPv4 string + + // AccessIPv6 [optional] provides a new IPv6 address for the instance. + AccessIPv6 string + + // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. + Metadata map[string]string + + // Personality [optional] includes the path and contents of a file to inject into the server at launch. + // The maximum size of the file is 255 bytes (decoded). + Personality []byte +} + +// ToServerRebuildMap formats a RebuildOpts struct into a map for use in JSON +func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) { + var err error + server := make(map[string]interface{}) + + if opts.AdminPass == "" { + err = fmt.Errorf("AdminPass is required") + } + + if opts.ImageID == "" { + err = fmt.Errorf("ImageID is required") + } + + if err != nil { + return server, err + } + + server["name"] = opts.Name + server["adminPass"] = opts.AdminPass + server["imageRef"] = opts.ImageID + + if opts.AccessIPv4 != "" { + server["accessIPv4"] = opts.AccessIPv4 + } + + if opts.AccessIPv6 != "" { + server["accessIPv6"] = opts.AccessIPv6 + } + + if opts.Metadata != nil { + server["metadata"] = opts.Metadata + } + + if opts.Personality != nil { + encoded := base64.StdEncoding.EncodeToString(opts.Personality) + server["personality"] = &encoded + } + + return map[string]interface{}{"rebuild": server}, nil +} + +// Rebuild will reprovision the server according to the configuration options +// provided in the RebuildOpts struct. +func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuilder) RebuildResult { + var result RebuildResult + + if id == "" { + result.Err = fmt.Errorf("ID is required") + return result + } + + reqBody, err := opts.ToServerRebuildMap() + if err != nil { + result.Err = err + return result + } + + _, result.Err = client.Post(actionURL(client, id), reqBody, &result.Body, nil) + return result +} + +// ResizeOptsBuilder is an interface that allows extensions to override the default structure of +// a Resize request. +type ResizeOptsBuilder interface { + ToServerResizeMap() (map[string]interface{}, error) +} + +// ResizeOpts represents the configuration options used to control a Resize operation. +type ResizeOpts struct { + // FlavorRef is the ID of the flavor you wish your server to become. + FlavorRef string +} + +// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON request body for the +// Resize request. +func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) { + resize := map[string]interface{}{ + "flavorRef": opts.FlavorRef, + } + + return map[string]interface{}{"resize": resize}, nil +} + +// Resize instructs the provider to change the flavor of the server. +// Note that this implies rebuilding it. +// Unfortunately, one cannot pass rebuild parameters to the resize function. +// When the resize completes, the server will be in RESIZE_VERIFY state. +// While in this state, you can explore the use of the new server's configuration. +// If you like it, call ConfirmResize() to commit the resize permanently. +// Otherwise, call RevertResize() to restore the old configuration. +func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) ActionResult { + var res ActionResult + reqBody, err := opts.ToServerResizeMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil) + return res +} + +// ConfirmResize confirms a previous resize operation on a server. +// See Resize() for more details. +func ConfirmResize(client *gophercloud.ServiceClient, id string) ActionResult { + var res ActionResult + + reqBody := map[string]interface{}{"confirmResize": nil} + _, res.Err = client.Post(actionURL(client, id), reqBody, nil, &gophercloud.RequestOpts{ + OkCodes: []int{201, 202, 204}, + }) + return res +} + +// RevertResize cancels a previous resize operation on a server. +// See Resize() for more details. +func RevertResize(client *gophercloud.ServiceClient, id string) ActionResult { + var res ActionResult + reqBody := map[string]interface{}{"revertResize": nil} + _, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil) + return res +} + +// RescueOptsBuilder is an interface that allows extensions to override the +// default structure of a Rescue request. +type RescueOptsBuilder interface { + ToServerRescueMap() (map[string]interface{}, error) +} + +// RescueOpts represents the configuration options used to control a Rescue +// option. +type RescueOpts struct { + // AdminPass is the desired administrative password for the instance in + // RESCUE mode. If it's left blank, the server will generate a password. + AdminPass string +} + +// ToServerRescueMap formats a RescueOpts as a map that can be used as a JSON +// request body for the Rescue request. +func (opts RescueOpts) ToServerRescueMap() (map[string]interface{}, error) { + server := make(map[string]interface{}) + if opts.AdminPass != "" { + server["adminPass"] = opts.AdminPass + } + return map[string]interface{}{"rescue": server}, nil +} + +// Rescue instructs the provider to place the server into RESCUE mode. +func Rescue(client *gophercloud.ServiceClient, id string, opts RescueOptsBuilder) RescueResult { + var result RescueResult + + if id == "" { + result.Err = fmt.Errorf("ID is required") + return result + } + reqBody, err := opts.ToServerRescueMap() + if err != nil { + result.Err = err + return result + } + + _, result.Err = client.Post(actionURL(client, id), reqBody, &result.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + + return result +} + +// ResetMetadataOptsBuilder allows extensions to add additional parameters to the +// Reset request. +type ResetMetadataOptsBuilder interface { + ToMetadataResetMap() (map[string]interface{}, error) +} + +// MetadataOpts is a map that contains key-value pairs. +type MetadataOpts map[string]string + +// ToMetadataResetMap assembles a body for a Reset request based on the contents of a MetadataOpts. +func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) { + return map[string]interface{}{"metadata": opts}, nil +} + +// ToMetadataUpdateMap assembles a body for an Update request based on the contents of a MetadataOpts. +func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) { + return map[string]interface{}{"metadata": opts}, nil +} + +// ResetMetadata will create multiple new key-value pairs for the given server ID. +// Note: Using this operation will erase any already-existing metadata and create +// the new metadata provided. To keep any already-existing metadata, use the +// UpdateMetadatas or UpdateMetadata function. +func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) ResetMetadataResult { + var res ResetMetadataResult + metadata, err := opts.ToMetadataResetMap() + if err != nil { + res.Err = err + return res + } + _, res.Err = client.Put(metadataURL(client, id), metadata, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return res +} + +// Metadata requests all the metadata for the given server ID. +func Metadata(client *gophercloud.ServiceClient, id string) GetMetadataResult { + var res GetMetadataResult + _, res.Err = client.Get(metadataURL(client, id), &res.Body, nil) + return res +} + +// UpdateMetadataOptsBuilder allows extensions to add additional parameters to the +// Create request. +type UpdateMetadataOptsBuilder interface { + ToMetadataUpdateMap() (map[string]interface{}, error) +} + +// UpdateMetadata updates (or creates) all the metadata specified by opts for the given server ID. +// This operation does not affect already-existing metadata that is not specified +// by opts. +func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) UpdateMetadataResult { + var res UpdateMetadataResult + metadata, err := opts.ToMetadataUpdateMap() + if err != nil { + res.Err = err + return res + } + _, res.Err = client.Post(metadataURL(client, id), metadata, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return res +} + +// MetadatumOptsBuilder allows extensions to add additional parameters to the +// Create request. +type MetadatumOptsBuilder interface { + ToMetadatumCreateMap() (map[string]interface{}, string, error) +} + +// MetadatumOpts is a map of length one that contains a key-value pair. +type MetadatumOpts map[string]string + +// ToMetadatumCreateMap assembles a body for a Create request based on the contents of a MetadataumOpts. +func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) { + if len(opts) != 1 { + return nil, "", errors.New("CreateMetadatum operation must have 1 and only 1 key-value pair.") + } + metadatum := map[string]interface{}{"meta": opts} + var key string + for k := range metadatum["meta"].(MetadatumOpts) { + key = k + } + return metadatum, key, nil +} + +// CreateMetadatum will create or update the key-value pair with the given key for the given server ID. +func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts MetadatumOptsBuilder) CreateMetadatumResult { + var res CreateMetadatumResult + metadatum, key, err := opts.ToMetadatumCreateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = client.Put(metadatumURL(client, id, key), metadatum, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return res +} + +// Metadatum requests the key-value pair with the given key for the given server ID. +func Metadatum(client *gophercloud.ServiceClient, id, key string) GetMetadatumResult { + var res GetMetadatumResult + _, res.Err = client.Request("GET", metadatumURL(client, id, key), gophercloud.RequestOpts{ + JSONResponse: &res.Body, + }) + return res +} + +// DeleteMetadatum will delete the key-value pair with the given key for the given server ID. +func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) DeleteMetadatumResult { + var res DeleteMetadatumResult + _, res.Err = client.Delete(metadatumURL(client, id, key), &gophercloud.RequestOpts{ + JSONResponse: &res.Body, + }) + return res +} + +// ListAddresses makes a request against the API to list the servers IP addresses. +func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager { + createPageFn := func(r pagination.PageResult) pagination.Page { + return AddressPage{pagination.SinglePageBase(r)} + } + return pagination.NewPager(client, listAddressesURL(client, id), createPageFn) +} + +// ListAddressesByNetwork makes a request against the API to list the servers IP addresses +// for the given network. +func ListAddressesByNetwork(client *gophercloud.ServiceClient, id, network string) pagination.Pager { + createPageFn := func(r pagination.PageResult) pagination.Page { + return NetworkAddressPage{pagination.SinglePageBase(r)} + } + return pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), createPageFn) +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/results.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/results.go new file mode 100644 index 0000000000..e2be6baa78 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/results.go @@ -0,0 +1,347 @@ +package servers + +import ( + "reflect" + + "github.com/mitchellh/mapstructure" + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +type serverResult struct { + gophercloud.Result +} + +// Extract interprets any serverResult as a Server, if possible. +func (r serverResult) Extract() (*Server, error) { + if r.Err != nil { + return nil, r.Err + } + + var response struct { + Server Server `mapstructure:"server"` + } + + config := &mapstructure.DecoderConfig{ + DecodeHook: toMapFromString, + Result: &response, + } + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return nil, err + } + + err = decoder.Decode(r.Body) + if err != nil { + return nil, err + } + + return &response.Server, nil +} + +// CreateResult temporarily contains the response from a Create call. +type CreateResult struct { + serverResult +} + +// GetResult temporarily contains the response from a Get call. +type GetResult struct { + serverResult +} + +// UpdateResult temporarily contains the response from an Update call. +type UpdateResult struct { + serverResult +} + +// DeleteResult temporarily contains the response from a Delete call. +type DeleteResult struct { + gophercloud.ErrResult +} + +// RebuildResult temporarily contains the response from a Rebuild call. +type RebuildResult struct { + serverResult +} + +// ActionResult represents the result of server action operations, like reboot +type ActionResult struct { + gophercloud.ErrResult +} + +// RescueResult represents the result of a server rescue operation +type RescueResult struct { + ActionResult +} + +// Extract interprets any RescueResult as an AdminPass, if possible. +func (r RescueResult) Extract() (string, error) { + if r.Err != nil { + return "", r.Err + } + + var response struct { + AdminPass string `mapstructure:"adminPass"` + } + + err := mapstructure.Decode(r.Body, &response) + return response.AdminPass, err +} + +// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account. +type Server struct { + // ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant. + ID string + + // TenantID identifies the tenant owning this server resource. + TenantID string `mapstructure:"tenant_id"` + + // UserID uniquely identifies the user account owning the tenant. + UserID string `mapstructure:"user_id"` + + // Name contains the human-readable name for the server. + Name string + + // Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created. + Updated string + Created string + + HostID string + + // Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE. + Status string + + // Progress ranges from 0..100. + // A request made against the server completes only once Progress reaches 100. + Progress int + + // AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration. + AccessIPv4, AccessIPv6 string + + // Image refers to a JSON object, which itself indicates the OS image used to deploy the server. + Image map[string]interface{} + + // Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server. + Flavor map[string]interface{} + + // Addresses includes a list of all IP addresses assigned to the server, keyed by pool. + Addresses map[string]interface{} + + // Metadata includes a list of all user-specified key-value pairs attached to the server. + Metadata map[string]interface{} + + // Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference. + Links []interface{} + + // KeyName indicates which public key was injected into the server on launch. + KeyName string `json:"key_name" mapstructure:"key_name"` + + // AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place. + // Note that this is the ONLY time this field will be valid. + AdminPass string `json:"adminPass" mapstructure:"adminPass"` + + // SecurityGroups includes the security groups that this instance has applied to it + SecurityGroups []map[string]interface{} `json:"security_groups" mapstructure:"security_groups"` +} + +// ServerPage abstracts the raw results of making a List() request against the API. +// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the +// data provided through the ExtractServers call. +type ServerPage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if a page contains no Server results. +func (page ServerPage) IsEmpty() (bool, error) { + servers, err := ExtractServers(page) + if err != nil { + return true, err + } + return len(servers) == 0, nil +} + +// NextPageURL uses the response's embedded link reference to navigate to the next page of results. +func (page ServerPage) NextPageURL() (string, error) { + type resp struct { + Links []gophercloud.Link `mapstructure:"servers_links"` + } + + var r resp + err := mapstructure.Decode(page.Body, &r) + if err != nil { + return "", err + } + + return gophercloud.ExtractNextURL(r.Links) +} + +// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities. +func ExtractServers(page pagination.Page) ([]Server, error) { + casted := page.(ServerPage).Body + + var response struct { + Servers []Server `mapstructure:"servers"` + } + + config := &mapstructure.DecoderConfig{ + DecodeHook: toMapFromString, + Result: &response, + } + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return nil, err + } + + err = decoder.Decode(casted) + + return response.Servers, err +} + +// MetadataResult contains the result of a call for (potentially) multiple key-value pairs. +type MetadataResult struct { + gophercloud.Result +} + +// GetMetadataResult temporarily contains the response from a metadata Get call. +type GetMetadataResult struct { + MetadataResult +} + +// ResetMetadataResult temporarily contains the response from a metadata Reset call. +type ResetMetadataResult struct { + MetadataResult +} + +// UpdateMetadataResult temporarily contains the response from a metadata Update call. +type UpdateMetadataResult struct { + MetadataResult +} + +// MetadatumResult contains the result of a call for individual a single key-value pair. +type MetadatumResult struct { + gophercloud.Result +} + +// GetMetadatumResult temporarily contains the response from a metadatum Get call. +type GetMetadatumResult struct { + MetadatumResult +} + +// CreateMetadatumResult temporarily contains the response from a metadatum Create call. +type CreateMetadatumResult struct { + MetadatumResult +} + +// DeleteMetadatumResult temporarily contains the response from a metadatum Delete call. +type DeleteMetadatumResult struct { + gophercloud.ErrResult +} + +// Extract interprets any MetadataResult as a Metadata, if possible. +func (r MetadataResult) Extract() (map[string]string, error) { + if r.Err != nil { + return nil, r.Err + } + + var response struct { + Metadata map[string]string `mapstructure:"metadata"` + } + + err := mapstructure.Decode(r.Body, &response) + return response.Metadata, err +} + +// Extract interprets any MetadatumResult as a Metadatum, if possible. +func (r MetadatumResult) Extract() (map[string]string, error) { + if r.Err != nil { + return nil, r.Err + } + + var response struct { + Metadatum map[string]string `mapstructure:"meta"` + } + + err := mapstructure.Decode(r.Body, &response) + return response.Metadatum, err +} + +func toMapFromString(from reflect.Kind, to reflect.Kind, data interface{}) (interface{}, error) { + if (from == reflect.String) && (to == reflect.Map) { + return map[string]interface{}{}, nil + } + return data, nil +} + +// Address represents an IP address. +type Address struct { + Version int `mapstructure:"version"` + Address string `mapstructure:"addr"` +} + +// AddressPage abstracts the raw results of making a ListAddresses() request against the API. +// As OpenStack extensions may freely alter the response bodies of structures returned +// to the client, you may only safely access the data provided through the ExtractAddresses call. +type AddressPage struct { + pagination.SinglePageBase +} + +// IsEmpty returns true if an AddressPage contains no networks. +func (r AddressPage) IsEmpty() (bool, error) { + addresses, err := ExtractAddresses(r) + if err != nil { + return true, err + } + return len(addresses) == 0, nil +} + +// ExtractAddresses interprets the results of a single page from a ListAddresses() call, +// producing a map of addresses. +func ExtractAddresses(page pagination.Page) (map[string][]Address, error) { + casted := page.(AddressPage).Body + + var response struct { + Addresses map[string][]Address `mapstructure:"addresses"` + } + + err := mapstructure.Decode(casted, &response) + if err != nil { + return nil, err + } + + return response.Addresses, err +} + +// NetworkAddressPage abstracts the raw results of making a ListAddressesByNetwork() request against the API. +// As OpenStack extensions may freely alter the response bodies of structures returned +// to the client, you may only safely access the data provided through the ExtractAddresses call. +type NetworkAddressPage struct { + pagination.SinglePageBase +} + +// IsEmpty returns true if a NetworkAddressPage contains no addresses. +func (r NetworkAddressPage) IsEmpty() (bool, error) { + addresses, err := ExtractNetworkAddresses(r) + if err != nil { + return true, err + } + return len(addresses) == 0, nil +} + +// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call, +// producing a slice of addresses. +func ExtractNetworkAddresses(page pagination.Page) ([]Address, error) { + casted := page.(NetworkAddressPage).Body + + var response map[string][]Address + err := mapstructure.Decode(casted, &response) + if err != nil { + return nil, err + } + + var key string + for k := range response { + key = k + } + + return response[key], err +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls.go new file mode 100644 index 0000000000..8998354939 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/urls.go @@ -0,0 +1,47 @@ +package servers + +import "github.com/rackspace/gophercloud" + +func createURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("servers") +} + +func listURL(client *gophercloud.ServiceClient) string { + return createURL(client) +} + +func listDetailURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("servers", "detail") +} + +func deleteURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("servers", id) +} + +func getURL(client *gophercloud.ServiceClient, id string) string { + return deleteURL(client, id) +} + +func updateURL(client *gophercloud.ServiceClient, id string) string { + return deleteURL(client, id) +} + +func actionURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("servers", id, "action") +} + +func metadatumURL(client *gophercloud.ServiceClient, id, key string) string { + return client.ServiceURL("servers", id, "metadata", key) +} + +func metadataURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("servers", id, "metadata") +} + +func listAddressesURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("servers", id, "ips") +} + +func listAddressesByNetworkURL(client *gophercloud.ServiceClient, id, network string) string { + return client.ServiceURL("servers", id, "ips", network) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/util.go b/vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/util.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/util.go rename to vendor/github.com/rackspace/gophercloud/openstack/compute/v2/servers/util.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/endpoint_location.go b/vendor/github.com/rackspace/gophercloud/openstack/endpoint_location.go new file mode 100644 index 0000000000..29d02c43f9 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/endpoint_location.go @@ -0,0 +1,91 @@ +package openstack + +import ( + "fmt" + + "github.com/rackspace/gophercloud" + tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens" + tokens3 "github.com/rackspace/gophercloud/openstack/identity/v3/tokens" +) + +// V2EndpointURL discovers the endpoint URL for a specific service from a ServiceCatalog acquired +// during the v2 identity service. The specified EndpointOpts are used to identify a unique, +// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided +// criteria and when none do. The minimum that can be specified is a Type, but you will also often +// need to specify a Name and/or a Region depending on what's available on your OpenStack +// deployment. +func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. + var endpoints = make([]tokens2.Endpoint, 0, 1) + for _, entry := range catalog.Entries { + if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { + for _, endpoint := range entry.Endpoints { + if opts.Region == "" || endpoint.Region == opts.Region { + endpoints = append(endpoints, endpoint) + } + } + } + } + + // Report an error if the options were ambiguous. + if len(endpoints) > 1 { + return "", fmt.Errorf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints) + } + + // Extract the appropriate URL from the matching Endpoint. + for _, endpoint := range endpoints { + switch opts.Availability { + case gophercloud.AvailabilityPublic: + return gophercloud.NormalizeURL(endpoint.PublicURL), nil + case gophercloud.AvailabilityInternal: + return gophercloud.NormalizeURL(endpoint.InternalURL), nil + case gophercloud.AvailabilityAdmin: + return gophercloud.NormalizeURL(endpoint.AdminURL), nil + default: + return "", fmt.Errorf("Unexpected availability in endpoint query: %s", opts.Availability) + } + } + + // Report an error if there were no matching endpoints. + return "", gophercloud.ErrEndpointNotFound +} + +// V3EndpointURL discovers the endpoint URL for a specific service from a Catalog acquired +// during the v3 identity service. The specified EndpointOpts are used to identify a unique, +// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided +// criteria and when none do. The minimum that can be specified is a Type, but you will also often +// need to specify a Name and/or a Region depending on what's available on your OpenStack +// deployment. +func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + // Extract Endpoints from the catalog entries that match the requested Type, Interface, + // Name if provided, and Region if provided. + var endpoints = make([]tokens3.Endpoint, 0, 1) + for _, entry := range catalog.Entries { + if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { + for _, endpoint := range entry.Endpoints { + if opts.Availability != gophercloud.AvailabilityAdmin && + opts.Availability != gophercloud.AvailabilityPublic && + opts.Availability != gophercloud.AvailabilityInternal { + return "", fmt.Errorf("Unexpected availability in endpoint query: %s", opts.Availability) + } + if (opts.Availability == gophercloud.Availability(endpoint.Interface)) && + (opts.Region == "" || endpoint.Region == opts.Region) { + endpoints = append(endpoints, endpoint) + } + } + } + } + + // Report an error if the options were ambiguous. + if len(endpoints) > 1 { + return "", fmt.Errorf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints) + } + + // Extract the URL from the matching Endpoint. + for _, endpoint := range endpoints { + return gophercloud.NormalizeURL(endpoint.URL), nil + } + + // Report an error if there were no matching endpoints. + return "", gophercloud.ErrEndpointNotFound +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/fixtures.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/fixtures.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/fixtures.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/fixtures.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/results.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/fixtures.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/fixtures.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/fixtures.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/fixtures.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go new file mode 100644 index 0000000000..efa054fb39 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go @@ -0,0 +1,82 @@ +package tokens + +import "github.com/rackspace/gophercloud" + +// AuthOptionsBuilder describes any argument that may be passed to the Create call. +type AuthOptionsBuilder interface { + + // ToTokenCreateMap assembles the Create request body, returning an error if parameters are + // missing or inconsistent. + ToTokenCreateMap() (map[string]interface{}, error) +} + +// AuthOptions wraps a gophercloud AuthOptions in order to adhere to the AuthOptionsBuilder +// interface. +type AuthOptions struct { + gophercloud.AuthOptions +} + +// WrapOptions embeds a root AuthOptions struct in a package-specific one. +func WrapOptions(original gophercloud.AuthOptions) AuthOptions { + return AuthOptions{AuthOptions: original} +} + +// ToTokenCreateMap converts AuthOptions into nested maps that can be serialized into a JSON +// request. +func (auth AuthOptions) ToTokenCreateMap() (map[string]interface{}, error) { + // Error out if an unsupported auth option is present. + if auth.UserID != "" { + return nil, ErrUserIDProvided + } + if auth.APIKey != "" { + return nil, ErrAPIKeyProvided + } + if auth.DomainID != "" { + return nil, ErrDomainIDProvided + } + if auth.DomainName != "" { + return nil, ErrDomainNameProvided + } + + // Username and Password are always required. + if auth.Username == "" { + return nil, ErrUsernameRequired + } + if auth.Password == "" { + return nil, ErrPasswordRequired + } + + // Populate the request map. + authMap := make(map[string]interface{}) + + authMap["passwordCredentials"] = map[string]interface{}{ + "username": auth.Username, + "password": auth.Password, + } + + if auth.TenantID != "" { + authMap["tenantId"] = auth.TenantID + } + if auth.TenantName != "" { + authMap["tenantName"] = auth.TenantName + } + + return map[string]interface{}{"auth": authMap}, nil +} + +// Create authenticates to the identity service and attempts to acquire a Token. +// If successful, the CreateResult +// Generally, rather than interact with this call directly, end users should call openstack.AuthenticatedClient(), +// which abstracts all of the gory details about navigating service catalogs and such. +func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) CreateResult { + request, err := auth.ToTokenCreateMap() + if err != nil { + return CreateResult{gophercloud.Result{Err: err}} + } + + var result CreateResult + _, result.Err = client.Post(CreateURL(client), request, &result.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 203}, + }) + return result +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/results.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/errors.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/errors.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/errors.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/errors.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go new file mode 100644 index 0000000000..d449ca36e8 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go @@ -0,0 +1,281 @@ +package tokens + +import ( + "net/http" + + "github.com/rackspace/gophercloud" +) + +// Scope allows a created token to be limited to a specific domain or project. +type Scope struct { + ProjectID string + ProjectName string + DomainID string + DomainName string +} + +func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string { + h := c.AuthenticatedHeaders() + h["X-Subject-Token"] = subjectToken + return h +} + +// Create authenticates and either generates a new token, or changes the Scope of an existing token. +func Create(c *gophercloud.ServiceClient, options gophercloud.AuthOptions, scope *Scope) CreateResult { + type domainReq struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + } + + type projectReq struct { + Domain *domainReq `json:"domain,omitempty"` + Name *string `json:"name,omitempty"` + ID *string `json:"id,omitempty"` + } + + type userReq struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Password string `json:"password"` + Domain *domainReq `json:"domain,omitempty"` + } + + type passwordReq struct { + User userReq `json:"user"` + } + + type tokenReq struct { + ID string `json:"id"` + } + + type identityReq struct { + Methods []string `json:"methods"` + Password *passwordReq `json:"password,omitempty"` + Token *tokenReq `json:"token,omitempty"` + } + + type scopeReq struct { + Domain *domainReq `json:"domain,omitempty"` + Project *projectReq `json:"project,omitempty"` + } + + type authReq struct { + Identity identityReq `json:"identity"` + Scope *scopeReq `json:"scope,omitempty"` + } + + type request struct { + Auth authReq `json:"auth"` + } + + // Populate the request structure based on the provided arguments. Create and return an error + // if insufficient or incompatible information is present. + var req request + + // Test first for unrecognized arguments. + if options.APIKey != "" { + return createErr(ErrAPIKeyProvided) + } + if options.TenantID != "" { + return createErr(ErrTenantIDProvided) + } + if options.TenantName != "" { + return createErr(ErrTenantNameProvided) + } + + if options.Password == "" { + if c.TokenID != "" { + // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication + // parameters. + if options.Username != "" { + return createErr(ErrUsernameWithToken) + } + if options.UserID != "" { + return createErr(ErrUserIDWithToken) + } + if options.DomainID != "" { + return createErr(ErrDomainIDWithToken) + } + if options.DomainName != "" { + return createErr(ErrDomainNameWithToken) + } + + // Configure the request for Token authentication. + req.Auth.Identity.Methods = []string{"token"} + req.Auth.Identity.Token = &tokenReq{ + ID: c.TokenID, + } + } else { + // If no password or token ID are available, authentication can't continue. + return createErr(ErrMissingPassword) + } + } else { + // Password authentication. + req.Auth.Identity.Methods = []string{"password"} + + // At least one of Username and UserID must be specified. + if options.Username == "" && options.UserID == "" { + return createErr(ErrUsernameOrUserID) + } + + if options.Username != "" { + // If Username is provided, UserID may not be provided. + if options.UserID != "" { + return createErr(ErrUsernameOrUserID) + } + + // Either DomainID or DomainName must also be specified. + if options.DomainID == "" && options.DomainName == "" { + return createErr(ErrDomainIDOrDomainName) + } + + if options.DomainID != "" { + if options.DomainName != "" { + return createErr(ErrDomainIDOrDomainName) + } + + // Configure the request for Username and Password authentication with a DomainID. + req.Auth.Identity.Password = &passwordReq{ + User: userReq{ + Name: &options.Username, + Password: options.Password, + Domain: &domainReq{ID: &options.DomainID}, + }, + } + } + + if options.DomainName != "" { + // Configure the request for Username and Password authentication with a DomainName. + req.Auth.Identity.Password = &passwordReq{ + User: userReq{ + Name: &options.Username, + Password: options.Password, + Domain: &domainReq{Name: &options.DomainName}, + }, + } + } + } + + if options.UserID != "" { + // If UserID is specified, neither DomainID nor DomainName may be. + if options.DomainID != "" { + return createErr(ErrDomainIDWithUserID) + } + if options.DomainName != "" { + return createErr(ErrDomainNameWithUserID) + } + + // Configure the request for UserID and Password authentication. + req.Auth.Identity.Password = &passwordReq{ + User: userReq{ID: &options.UserID, Password: options.Password}, + } + } + } + + // Add a "scope" element if a Scope has been provided. + if scope != nil { + if scope.ProjectName != "" { + // ProjectName provided: either DomainID or DomainName must also be supplied. + // ProjectID may not be supplied. + if scope.DomainID == "" && scope.DomainName == "" { + return createErr(ErrScopeDomainIDOrDomainName) + } + if scope.ProjectID != "" { + return createErr(ErrScopeProjectIDOrProjectName) + } + + if scope.DomainID != "" { + // ProjectName + DomainID + req.Auth.Scope = &scopeReq{ + Project: &projectReq{ + Name: &scope.ProjectName, + Domain: &domainReq{ID: &scope.DomainID}, + }, + } + } + + if scope.DomainName != "" { + // ProjectName + DomainName + req.Auth.Scope = &scopeReq{ + Project: &projectReq{ + Name: &scope.ProjectName, + Domain: &domainReq{Name: &scope.DomainName}, + }, + } + } + } else if scope.ProjectID != "" { + // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. + if scope.DomainID != "" { + return createErr(ErrScopeProjectIDAlone) + } + if scope.DomainName != "" { + return createErr(ErrScopeProjectIDAlone) + } + + // ProjectID + req.Auth.Scope = &scopeReq{ + Project: &projectReq{ID: &scope.ProjectID}, + } + } else if scope.DomainID != "" { + // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. + if scope.DomainName != "" { + return createErr(ErrScopeDomainIDOrDomainName) + } + + // DomainID + req.Auth.Scope = &scopeReq{ + Domain: &domainReq{ID: &scope.DomainID}, + } + } else if scope.DomainName != "" { + return createErr(ErrScopeDomainName) + } else { + return createErr(ErrScopeEmpty) + } + } + + var result CreateResult + var response *http.Response + response, result.Err = c.Post(tokenURL(c), req, &result.Body, nil) + if result.Err != nil { + return result + } + result.Header = response.Header + return result +} + +// Get validates and retrieves information about another token. +func Get(c *gophercloud.ServiceClient, token string) GetResult { + var result GetResult + var response *http.Response + response, result.Err = c.Get(tokenURL(c), &result.Body, &gophercloud.RequestOpts{ + MoreHeaders: subjectTokenHeaders(c, token), + OkCodes: []int{200, 203}, + }) + if result.Err != nil { + return result + } + result.Header = response.Header + return result +} + +// Validate determines if a specified token is valid or not. +func Validate(c *gophercloud.ServiceClient, token string) (bool, error) { + response, err := c.Request("HEAD", tokenURL(c), gophercloud.RequestOpts{ + MoreHeaders: subjectTokenHeaders(c, token), + OkCodes: []int{204, 404}, + }) + if err != nil { + return false, err + } + + return response.StatusCode == 204, nil +} + +// Revoke immediately makes specified token invalid. +func Revoke(c *gophercloud.ServiceClient, token string) RevokeResult { + var res RevokeResult + _, res.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{ + MoreHeaders: subjectTokenHeaders(c, token), + }) + return res +} diff --git a/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go new file mode 100644 index 0000000000..d134f7d4d0 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go @@ -0,0 +1,139 @@ +package tokens + +import ( + "time" + + "github.com/mitchellh/mapstructure" + "github.com/rackspace/gophercloud" +) + +// Endpoint represents a single API endpoint offered by a service. +// It matches either a public, internal or admin URL. +// If supported, it contains a region specifier, again if provided. +// The significance of the Region field will depend upon your provider. +type Endpoint struct { + ID string `mapstructure:"id"` + Region string `mapstructure:"region"` + Interface string `mapstructure:"interface"` + URL string `mapstructure:"url"` +} + +// CatalogEntry provides a type-safe interface to an Identity API V3 service catalog listing. +// Each class of service, such as cloud DNS or block storage services, could have multiple +// CatalogEntry representing it (one by interface type, e.g public, admin or internal). +// +// Note: when looking for the desired service, try, whenever possible, to key off the type field. +// Otherwise, you'll tie the representation of the service to a specific provider. +type CatalogEntry struct { + + // Service ID + ID string `mapstructure:"id"` + + // Name will contain the provider-specified name for the service. + Name string `mapstructure:"name"` + + // Type will contain a type string if OpenStack defines a type for the service. + // Otherwise, for provider-specific services, the provider may assign their own type strings. + Type string `mapstructure:"type"` + + // Endpoints will let the caller iterate over all the different endpoints that may exist for + // the service. + Endpoints []Endpoint `mapstructure:"endpoints"` +} + +// ServiceCatalog provides a view into the service catalog from a previous, successful authentication. +type ServiceCatalog struct { + Entries []CatalogEntry +} + +// commonResult is the deferred result of a Create or a Get call. +type commonResult struct { + gophercloud.Result +} + +// Extract is a shortcut for ExtractToken. +// This function is deprecated and still present for backward compatibility. +func (r commonResult) Extract() (*Token, error) { + return r.ExtractToken() +} + +// ExtractToken interprets a commonResult as a Token. +func (r commonResult) ExtractToken() (*Token, error) { + if r.Err != nil { + return nil, r.Err + } + + var response struct { + Token struct { + ExpiresAt string `mapstructure:"expires_at"` + } `mapstructure:"token"` + } + + var token Token + + // Parse the token itself from the stored headers. + token.ID = r.Header.Get("X-Subject-Token") + + err := mapstructure.Decode(r.Body, &response) + if err != nil { + return nil, err + } + + // Attempt to parse the timestamp. + token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt) + + return &token, err +} + +// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token. +func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) { + if result.Err != nil { + return nil, result.Err + } + + var response struct { + Token struct { + Entries []CatalogEntry `mapstructure:"catalog"` + } `mapstructure:"token"` + } + + err := mapstructure.Decode(result.Body, &response) + if err != nil { + return nil, err + } + + return &ServiceCatalog{Entries: response.Token.Entries}, nil +} + +// CreateResult defers the interpretation of a created token. +// Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog. +type CreateResult struct { + commonResult +} + +// createErr quickly creates a CreateResult that reports an error. +func createErr(err error) CreateResult { + return CreateResult{ + commonResult: commonResult{Result: gophercloud.Result{Err: err}}, + } +} + +// GetResult is the deferred response from a Get call. +type GetResult struct { + commonResult +} + +// RevokeResult is the deferred response from a Revoke call. +type RevokeResult struct { + commonResult +} + +// Token is a string that grants a user access to a controlled set of services in an OpenStack provider. +// Each Token is valid for a set length of time. +type Token struct { + // ID is the issued token. + ID string + + // ExpiresAt is the timestamp at which this token will no longer be accepted. + ExpiresAt time.Time +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go new file mode 100644 index 0000000000..49d6f0b7a5 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go @@ -0,0 +1,167 @@ +package floatingips + +import ( + "fmt" + + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the floating IP attributes you want to see returned. SortKey allows you to +// sort by a particular network attribute. SortDir sets the direction, and is +// either `asc' or `desc'. Marker and Limit are used for pagination. +type ListOpts struct { + ID string `q:"id"` + FloatingNetworkID string `q:"floating_network_id"` + PortID string `q:"port_id"` + FixedIP string `q:"fixed_ip_address"` + FloatingIP string `q:"floating_ip_address"` + TenantID string `q:"tenant_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` +} + +// List returns a Pager which allows you to iterate over a collection of +// floating IP resources. It accepts a ListOpts struct, which allows you to +// filter and sort the returned collection for greater efficiency. +func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { + q, err := gophercloud.BuildQueryString(&opts) + if err != nil { + return pagination.Pager{Err: err} + } + u := rootURL(c) + q.String() + return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { + return FloatingIPPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// CreateOpts contains all the values needed to create a new floating IP +// resource. The only required fields are FloatingNetworkID and PortID which +// refer to the external network and internal port respectively. +type CreateOpts struct { + FloatingNetworkID string + FloatingIP string + PortID string + FixedIP string + TenantID string +} + +var ( + errFloatingNetworkIDRequired = fmt.Errorf("A NetworkID is required") +) + +// Create accepts a CreateOpts struct and uses the values provided to create a +// new floating IP resource. You can create floating IPs on external networks +// only. If you provide a FloatingNetworkID which refers to a network that is +// not external (i.e. its `router:external' attribute is False), the operation +// will fail and return a 400 error. +// +// If you do not specify a FloatingIP address value, the operation will +// automatically allocate an available address for the new resource. If you do +// choose to specify one, it must fall within the subnet range for the external +// network - otherwise the operation returns a 400 error. If the FloatingIP +// address is already in use, the operation returns a 409 error code. +// +// You can associate the new resource with an internal port by using the PortID +// field. If you specify a PortID that is not valid, the operation will fail and +// return 404 error code. +// +// You must also configure an IP address for the port associated with the PortID +// you have provided - this is what the FixedIP refers to: an IP fixed to a port. +// Because a port might be associated with multiple IP addresses, you can use +// the FixedIP field to associate a particular IP address rather than have the +// API assume for you. If you specify an IP address that is not valid, the +// operation will fail and return a 400 error code. If the PortID and FixedIP +// are already associated with another resource, the operation will fail and +// returns a 409 error code. +func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { + var res CreateResult + + // Validate + if opts.FloatingNetworkID == "" { + res.Err = errFloatingNetworkIDRequired + return res + } + + // Define structures + type floatingIP struct { + FloatingNetworkID string `json:"floating_network_id"` + FloatingIP string `json:"floating_ip_address,omitempty"` + PortID string `json:"port_id,omitempty"` + FixedIP string `json:"fixed_ip_address,omitempty"` + TenantID string `json:"tenant_id,omitempty"` + } + type request struct { + FloatingIP floatingIP `json:"floatingip"` + } + + // Populate request body + reqBody := request{FloatingIP: floatingIP{ + FloatingNetworkID: opts.FloatingNetworkID, + PortID: opts.PortID, + FixedIP: opts.FixedIP, + TenantID: opts.TenantID, + }} + + _, res.Err = c.Post(rootURL(c), reqBody, &res.Body, nil) + return res +} + +// Get retrieves a particular floating IP resource based on its unique ID. +func Get(c *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = c.Get(resourceURL(c, id), &res.Body, nil) + return res +} + +// UpdateOpts contains the values used when updating a floating IP resource. The +// only value that can be updated is which internal port the floating IP is +// linked to. To associate the floating IP with a new internal port, provide its +// ID. To disassociate the floating IP from all ports, provide an empty string. +type UpdateOpts struct { + PortID string +} + +// Update allows floating IP resources to be updated. Currently, the only way to +// "update" a floating IP is to associate it with a new internal port, or +// disassociated it from all ports. See UpdateOpts for instructions of how to +// do this. +func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { + type floatingIP struct { + PortID *string `json:"port_id"` + } + + type request struct { + FloatingIP floatingIP `json:"floatingip"` + } + + var portID *string + if opts.PortID == "" { + portID = nil + } else { + portID = &opts.PortID + } + + reqBody := request{FloatingIP: floatingIP{PortID: portID}} + + // Send request to API + var res UpdateResult + _, res.Err = c.Put(resourceURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + + return res +} + +// Delete will permanently delete a particular floating IP resource. Please +// ensure this is what you want - you can also disassociate the IP from existing +// internal ports. +func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { + var res DeleteResult + _, res.Err = c.Delete(resourceURL(c, id), nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/errors.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/errors.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/errors.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/errors.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go new file mode 100644 index 0000000000..7be3227400 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go @@ -0,0 +1,191 @@ +package networks + +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// AdminState gives users a solid type to work with for create and update +// operations. It is recommended that users use the `Up` and `Down` enums. +type AdminState *bool + +// Convenience vars for AdminStateUp values. +var ( + iTrue = true + iFalse = false + + Up AdminState = &iTrue + Down AdminState = &iFalse +) + +type networkOpts struct { + AdminStateUp *bool + Name string + Shared *bool + TenantID string +} + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToNetworkListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the network attributes you want to see returned. SortKey allows you to sort +// by a particular network attribute. SortDir sets the direction, and is either +// `asc' or `desc'. Marker and Limit are used for pagination. +type ListOpts struct { + Status string `q:"status"` + Name string `q:"name"` + AdminStateUp *bool `q:"admin_state_up"` + TenantID string `q:"tenant_id"` + Shared *bool `q:"shared"` + ID string `q:"id"` + Marker string `q:"marker"` + Limit int `q:"limit"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` +} + +// ToNetworkListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToNetworkListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// List returns a Pager which allows you to iterate over a collection of +// networks. It accepts a ListOpts struct, which allows you to filter and sort +// the returned collection for greater efficiency. +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(c) + if opts != nil { + query, err := opts.ToNetworkListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return NetworkPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get retrieves a specific network based on its unique ID. +func Get(c *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = c.Get(getURL(c, id), &res.Body, nil) + return res +} + +// CreateOptsBuilder is the interface options structs have to satisfy in order +// to be used in the main Create operation in this package. Since many +// extensions decorate or modify the common logic, it is useful for them to +// satisfy a basic interface in order for them to be used. +type CreateOptsBuilder interface { + ToNetworkCreateMap() (map[string]interface{}, error) +} + +// CreateOpts is the common options struct used in this package's Create +// operation. +type CreateOpts networkOpts + +// ToNetworkCreateMap casts a CreateOpts struct to a map. +func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { + n := make(map[string]interface{}) + + if opts.AdminStateUp != nil { + n["admin_state_up"] = &opts.AdminStateUp + } + if opts.Name != "" { + n["name"] = opts.Name + } + if opts.Shared != nil { + n["shared"] = &opts.Shared + } + if opts.TenantID != "" { + n["tenant_id"] = opts.TenantID + } + + return map[string]interface{}{"network": n}, nil +} + +// Create accepts a CreateOpts struct and creates a new network using the values +// provided. This operation does not actually require a request body, i.e. the +// CreateOpts struct argument can be empty. +// +// The tenant ID that is contained in the URI is the tenant that creates the +// network. An admin user, however, has the option of specifying another tenant +// ID in the CreateOpts struct. +func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { + var res CreateResult + + reqBody, err := opts.ToNetworkCreateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = c.Post(createURL(c), reqBody, &res.Body, nil) + return res +} + +// UpdateOptsBuilder is the interface options structs have to satisfy in order +// to be used in the main Update operation in this package. Since many +// extensions decorate or modify the common logic, it is useful for them to +// satisfy a basic interface in order for them to be used. +type UpdateOptsBuilder interface { + ToNetworkUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts is the common options struct used in this package's Update +// operation. +type UpdateOpts networkOpts + +// ToNetworkUpdateMap casts a UpdateOpts struct to a map. +func (opts UpdateOpts) ToNetworkUpdateMap() (map[string]interface{}, error) { + n := make(map[string]interface{}) + + if opts.AdminStateUp != nil { + n["admin_state_up"] = &opts.AdminStateUp + } + if opts.Name != "" { + n["name"] = opts.Name + } + if opts.Shared != nil { + n["shared"] = &opts.Shared + } + + return map[string]interface{}{"network": n}, nil +} + +// Update accepts a UpdateOpts struct and updates an existing network using the +// values provided. For more information, see the Create function. +func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOptsBuilder) UpdateResult { + var res UpdateResult + + reqBody, err := opts.ToNetworkUpdateMap() + if err != nil { + res.Err = err + return res + } + + // Send request to API + _, res.Err = c.Put(updateURL(c, networkID), reqBody, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201}, + }) + + return res +} + +// Delete accepts a unique ID and deletes the network associated with it. +func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult { + var res DeleteResult + _, res.Err = c.Delete(deleteURL(c, networkID), nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/results.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/networks/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/doc.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/doc.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/errors.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/errors.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/errors.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/errors.go diff --git a/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go new file mode 100644 index 0000000000..781a3c3e74 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go @@ -0,0 +1,225 @@ +package ports + +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// AdminState gives users a solid type to work with for create and update +// operations. It is recommended that users use the `Up` and `Down` enums. +type AdminState *bool + +// Convenience vars for AdminStateUp values. +var ( + iTrue = true + iFalse = false + + Up AdminState = &iTrue + Down AdminState = &iFalse +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToPortListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the port attributes you want to see returned. SortKey allows you to sort +// by a particular port attribute. SortDir sets the direction, and is either +// `asc' or `desc'. Marker and Limit are used for pagination. +type ListOpts struct { + Status string `q:"status"` + Name string `q:"name"` + AdminStateUp *bool `q:"admin_state_up"` + NetworkID string `q:"network_id"` + TenantID string `q:"tenant_id"` + DeviceOwner string `q:"device_owner"` + MACAddress string `q:"mac_address"` + ID string `q:"id"` + DeviceID string `q:"device_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` +} + +// ToPortListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToPortListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// List returns a Pager which allows you to iterate over a collection of +// ports. It accepts a ListOpts struct, which allows you to filter and sort +// the returned collection for greater efficiency. +// +// Default policy settings return only those ports that are owned by the tenant +// who submits the request, unless the request is submitted by a user with +// administrative rights. +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(c) + if opts != nil { + query, err := opts.ToPortListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return PortPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get retrieves a specific port based on its unique ID. +func Get(c *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = c.Get(getURL(c, id), &res.Body, nil) + return res +} + +// CreateOptsBuilder is the interface options structs have to satisfy in order +// to be used in the main Create operation in this package. Since many +// extensions decorate or modify the common logic, it is useful for them to +// satisfy a basic interface in order for them to be used. +type CreateOptsBuilder interface { + ToPortCreateMap() (map[string]interface{}, error) +} + +// CreateOpts represents the attributes used when creating a new port. +type CreateOpts struct { + NetworkID string + Name string + AdminStateUp *bool + MACAddress string + FixedIPs interface{} + DeviceID string + DeviceOwner string + TenantID string + SecurityGroups []string +} + +// ToPortCreateMap casts a CreateOpts struct to a map. +func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) { + p := make(map[string]interface{}) + + if opts.NetworkID == "" { + return nil, errNetworkIDRequired + } + p["network_id"] = opts.NetworkID + + if opts.DeviceID != "" { + p["device_id"] = opts.DeviceID + } + if opts.DeviceOwner != "" { + p["device_owner"] = opts.DeviceOwner + } + if opts.FixedIPs != nil { + p["fixed_ips"] = opts.FixedIPs + } + if opts.SecurityGroups != nil { + p["security_groups"] = opts.SecurityGroups + } + if opts.TenantID != "" { + p["tenant_id"] = opts.TenantID + } + if opts.AdminStateUp != nil { + p["admin_state_up"] = &opts.AdminStateUp + } + if opts.Name != "" { + p["name"] = opts.Name + } + if opts.MACAddress != "" { + p["mac_address"] = opts.MACAddress + } + + return map[string]interface{}{"port": p}, nil +} + +// Create accepts a CreateOpts struct and creates a new network using the values +// provided. You must remember to provide a NetworkID value. +func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { + var res CreateResult + + reqBody, err := opts.ToPortCreateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = c.Post(createURL(c), reqBody, &res.Body, nil) + return res +} + +// UpdateOptsBuilder is the interface options structs have to satisfy in order +// to be used in the main Update operation in this package. Since many +// extensions decorate or modify the common logic, it is useful for them to +// satisfy a basic interface in order for them to be used. +type UpdateOptsBuilder interface { + ToPortUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts represents the attributes used when updating an existing port. +type UpdateOpts struct { + Name string + AdminStateUp *bool + FixedIPs interface{} + DeviceID string + DeviceOwner string + SecurityGroups []string +} + +// ToPortUpdateMap casts an UpdateOpts struct to a map. +func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { + p := make(map[string]interface{}) + + if opts.DeviceID != "" { + p["device_id"] = opts.DeviceID + } + if opts.DeviceOwner != "" { + p["device_owner"] = opts.DeviceOwner + } + if opts.FixedIPs != nil { + p["fixed_ips"] = opts.FixedIPs + } + if opts.SecurityGroups != nil { + p["security_groups"] = opts.SecurityGroups + } + if opts.AdminStateUp != nil { + p["admin_state_up"] = &opts.AdminStateUp + } + if opts.Name != "" { + p["name"] = opts.Name + } + + return map[string]interface{}{"port": p}, nil +} + +// Update accepts a UpdateOpts struct and updates an existing port using the +// values provided. +func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { + var res UpdateResult + + reqBody, err := opts.ToPortUpdateMap() + if err != nil { + res.Err = err + return res + } + + _, res.Err = c.Put(updateURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201}, + }) + return res +} + +// Delete accepts a unique ID and deletes the port associated with it. +func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { + var res DeleteResult + _, res.Err = c.Delete(deleteURL(c, id), nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/results.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/results.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/results.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/results.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls.go b/vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls.go rename to vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/utils/choose_version.go b/vendor/github.com/rackspace/gophercloud/openstack/utils/choose_version.go similarity index 83% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/utils/choose_version.go rename to vendor/github.com/rackspace/gophercloud/openstack/utils/choose_version.go index a0d5b26468..b697ba8160 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/utils/choose_version.go +++ b/vendor/github.com/rackspace/gophercloud/openstack/utils/choose_version.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/racker/perigee" + "github.com/rackspace/gophercloud" ) // Version is a supported API version, corresponding to a vN package within the appropriate service. @@ -23,7 +23,7 @@ var goodStatus = map[string]bool{ // ChooseVersion queries the base endpoint of an API to choose the most recent non-experimental alternative from a service's // published versions. // It returns the highest-Priority Version among the alternatives that are provided, as well as its corresponding endpoint. -func ChooseVersion(identityBase string, identityEndpoint string, recognized []*Version) (*Version, string, error) { +func ChooseVersion(client *gophercloud.ProviderClient, recognized []*Version) (*Version, string, error) { type linkResp struct { Href string `json:"href"` Rel string `json:"rel"` @@ -49,7 +49,7 @@ func ChooseVersion(identityBase string, identityEndpoint string, recognized []*V } return endpoint } - identityEndpoint = normalize(identityEndpoint) + identityEndpoint := normalize(client.IdentityEndpoint) // If a full endpoint is specified, check version suffixes for a match first. for _, v := range recognized { @@ -59,9 +59,9 @@ func ChooseVersion(identityBase string, identityEndpoint string, recognized []*V } var resp response - _, err := perigee.Request("GET", identityBase, perigee.Options{ - Results: &resp, - OkCodes: []int{200, 300}, + _, err := client.Request("GET", client.IdentityBase, gophercloud.RequestOpts{ + JSONResponse: &resp, + OkCodes: []int{200, 300}, }) if err != nil { @@ -88,7 +88,7 @@ func ChooseVersion(identityBase string, identityEndpoint string, recognized []*V // Prefer a version that exactly matches the provided endpoint. if href == identityEndpoint { if href == "" { - return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, identityBase) + return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, client.IdentityBase) } return matching, href, nil } @@ -104,10 +104,10 @@ func ChooseVersion(identityBase string, identityEndpoint string, recognized []*V } if highest == nil { - return nil, "", fmt.Errorf("No supported version available from endpoint %s", identityBase) + return nil, "", fmt.Errorf("No supported version available from endpoint %s", client.IdentityBase) } if endpoint == "" { - return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", highest.ID, identityBase) + return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", highest.ID, client.IdentityBase) } return highest, endpoint, nil diff --git a/vendor/github.com/rackspace/gophercloud/pagination/http.go b/vendor/github.com/rackspace/gophercloud/pagination/http.go new file mode 100644 index 0000000000..cabcccd79f --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/pagination/http.go @@ -0,0 +1,54 @@ +package pagination + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "github.com/rackspace/gophercloud" +) + +// PageResult stores the HTTP response that returned the current page of results. +type PageResult struct { + gophercloud.Result + url.URL +} + +// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the +// results, interpreting it as JSON if the content type indicates. +func PageResultFrom(resp *http.Response) (PageResult, error) { + var parsedBody interface{} + + defer resp.Body.Close() + rawBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return PageResult{}, err + } + + if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { + err = json.Unmarshal(rawBody, &parsedBody) + if err != nil { + return PageResult{}, err + } + } else { + parsedBody = rawBody + } + + return PageResult{ + Result: gophercloud.Result{ + Body: parsedBody, + Header: resp.Header, + }, + URL: *resp.Request.URL, + }, err +} + +// Request performs an HTTP request and extracts the http.Response from the result. +func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) { + return client.Request("GET", url, gophercloud.RequestOpts{ + MoreHeaders: headers, + OkCodes: []int{200, 204}, + }) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/linked.go b/vendor/github.com/rackspace/gophercloud/pagination/linked.go similarity index 90% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/linked.go rename to vendor/github.com/rackspace/gophercloud/pagination/linked.go index 461fa499af..e9bd8dec97 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/linked.go +++ b/vendor/github.com/rackspace/gophercloud/pagination/linked.go @@ -59,3 +59,9 @@ func (current LinkedPageBase) NextPageURL() (string, error) { } } } + +// GetBody returns the linked page's body. This method is needed to satisfy the +// Page interface. +func (current LinkedPageBase) GetBody() interface{} { + return current.Body +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/marker.go b/vendor/github.com/rackspace/gophercloud/pagination/marker.go similarity index 83% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/marker.go rename to vendor/github.com/rackspace/gophercloud/pagination/marker.go index e7688c217b..f355afc54b 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/marker.go +++ b/vendor/github.com/rackspace/gophercloud/pagination/marker.go @@ -32,3 +32,9 @@ func (current MarkerPageBase) NextPageURL() (string, error) { return currentURL.String(), nil } + +// GetBody returns the linked page's body. This method is needed to satisfy the +// Page interface. +func (current MarkerPageBase) GetBody() interface{} { + return current.Body +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/null.go b/vendor/github.com/rackspace/gophercloud/pagination/null.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/null.go rename to vendor/github.com/rackspace/gophercloud/pagination/null.go diff --git a/vendor/github.com/rackspace/gophercloud/pagination/pager.go b/vendor/github.com/rackspace/gophercloud/pagination/pager.go new file mode 100644 index 0000000000..ea47c695dc --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/pagination/pager.go @@ -0,0 +1,224 @@ +package pagination + +import ( + "errors" + "fmt" + "net/http" + "reflect" + "strings" + + "github.com/rackspace/gophercloud" +) + +var ( + // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. + ErrPageNotAvailable = errors.New("The requested page does not exist.") +) + +// Page must be satisfied by the result type of any resource collection. +// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated. +// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs, +// instead. +// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type +// will need to implement. +type Page interface { + + // NextPageURL generates the URL for the page of data that follows this collection. + // Return "" if no such page exists. + NextPageURL() (string, error) + + // IsEmpty returns true if this Page has no items in it. + IsEmpty() (bool, error) + + // GetBody returns the Page Body. This is used in the `AllPages` method. + GetBody() interface{} +} + +// Pager knows how to advance through a specific resource collection, one page at a time. +type Pager struct { + client *gophercloud.ServiceClient + + initialURL string + + createPage func(r PageResult) Page + + Err error + + // Headers supplies additional HTTP headers to populate on each paged request. + Headers map[string]string +} + +// NewPager constructs a manually-configured pager. +// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page. +func NewPager(client *gophercloud.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager { + return Pager{ + client: client, + initialURL: initialURL, + createPage: createPage, + } +} + +// WithPageCreator returns a new Pager that substitutes a different page creation function. This is +// useful for overriding List functions in delegation. +func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager { + return Pager{ + client: p.client, + initialURL: p.initialURL, + createPage: createPage, + } +} + +func (p Pager) fetchNextPage(url string) (Page, error) { + resp, err := Request(p.client, p.Headers, url) + if err != nil { + return nil, err + } + + remembered, err := PageResultFrom(resp) + if err != nil { + return nil, err + } + + return p.createPage(remembered), nil +} + +// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function. +// Return "false" from the handler to prematurely stop iterating. +func (p Pager) EachPage(handler func(Page) (bool, error)) error { + if p.Err != nil { + return p.Err + } + currentURL := p.initialURL + for { + currentPage, err := p.fetchNextPage(currentURL) + if err != nil { + return err + } + + empty, err := currentPage.IsEmpty() + if err != nil { + return err + } + if empty { + return nil + } + + ok, err := handler(currentPage) + if err != nil { + return err + } + if !ok { + return nil + } + + currentURL, err = currentPage.NextPageURL() + if err != nil { + return err + } + if currentURL == "" { + return nil + } + } +} + +// AllPages returns all the pages from a `List` operation in a single page, +// allowing the user to retrieve all the pages at once. +func (p Pager) AllPages() (Page, error) { + // pagesSlice holds all the pages until they get converted into as Page Body. + var pagesSlice []interface{} + // body will contain the final concatenated Page body. + var body reflect.Value + + // Grab a test page to ascertain the page body type. + testPage, err := p.fetchNextPage(p.initialURL) + if err != nil { + return nil, err + } + // Store the page type so we can use reflection to create a new mega-page of + // that type. + pageType := reflect.TypeOf(testPage) + + // Switch on the page body type. Recognized types are `map[string]interface{}`, + // `[]byte`, and `[]interface{}`. + switch testPage.GetBody().(type) { + case map[string]interface{}: + // key is the map key for the page body if the body type is `map[string]interface{}`. + var key string + // Iterate over the pages to concatenate the bodies. + err := p.EachPage(func(page Page) (bool, error) { + b := page.GetBody().(map[string]interface{}) + for k := range b { + // If it's a linked page, we don't want the `links`, we want the other one. + if !strings.HasSuffix(k, "links") { + key = k + } + } + pagesSlice = append(pagesSlice, b[key].([]interface{})...) + return true, nil + }) + if err != nil { + return nil, err + } + // Set body to value of type `map[string]interface{}` + body = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(key), reflect.TypeOf(pagesSlice))) + body.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(pagesSlice)) + case []byte: + // Iterate over the pages to concatenate the bodies. + err := p.EachPage(func(page Page) (bool, error) { + b := page.GetBody().([]byte) + pagesSlice = append(pagesSlice, b) + // seperate pages with a comma + pagesSlice = append(pagesSlice, []byte{10}) + return true, nil + }) + if err != nil { + return nil, err + } + // Remove the trailing comma. + pagesSlice = pagesSlice[:len(pagesSlice)-1] + var b []byte + // Combine the slice of slices in to a single slice. + for _, slice := range pagesSlice { + b = append(b, slice.([]byte)...) + } + // Set body to value of type `bytes`. + body = reflect.New(reflect.TypeOf(b)).Elem() + body.SetBytes(b) + case []interface{}: + // Iterate over the pages to concatenate the bodies. + err := p.EachPage(func(page Page) (bool, error) { + b := page.GetBody().([]interface{}) + pagesSlice = append(pagesSlice, b...) + return true, nil + }) + if err != nil { + return nil, err + } + // Set body to value of type `[]interface{}` + body = reflect.MakeSlice(reflect.TypeOf(pagesSlice), len(pagesSlice), len(pagesSlice)) + for i, s := range pagesSlice { + body.Index(i).Set(reflect.ValueOf(s)) + } + default: + return nil, fmt.Errorf("Page body has unrecognized type.") + } + + // Each `Extract*` function is expecting a specific type of page coming back, + // otherwise the type assertion in those functions will fail. pageType is needed + // to create a type in this method that has the same type that the `Extract*` + // function is expecting and set the Body of that object to the concatenated + // pages. + page := reflect.New(pageType) + // Set the page body to be the concatenated pages. + page.Elem().FieldByName("Body").Set(body) + // Set any additional headers that were pass along. The `objectstorage` pacakge, + // for example, passes a Content-Type header. + h := make(http.Header) + for k, v := range p.Headers { + h.Add(k, v) + } + page.Elem().FieldByName("Header").Set(reflect.ValueOf(h)) + // Type assert the page to a Page interface so that the type assertion in the + // `Extract*` methods will work. + return page.Elem().Interface().(Page), err +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pkg.go b/vendor/github.com/rackspace/gophercloud/pagination/pkg.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pkg.go rename to vendor/github.com/rackspace/gophercloud/pagination/pkg.go diff --git a/vendor/github.com/rackspace/gophercloud/pagination/single.go b/vendor/github.com/rackspace/gophercloud/pagination/single.go new file mode 100644 index 0000000000..f78d4ab5d9 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/pagination/single.go @@ -0,0 +1,15 @@ +package pagination + +// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once. +type SinglePageBase PageResult + +// NextPageURL always returns "" to indicate that there are no more pages to return. +func (current SinglePageBase) NextPageURL() (string, error) { + return "", nil +} + +// GetBody returns the single page's body. This method is needed to satisfy the +// Page interface. +func (current SinglePageBase) GetBody() interface{} { + return current.Body +} diff --git a/vendor/github.com/rackspace/gophercloud/params.go b/vendor/github.com/rackspace/gophercloud/params.go new file mode 100644 index 0000000000..4d0f1e6e02 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/params.go @@ -0,0 +1,271 @@ +package gophercloud + +import ( + "fmt" + "net/url" + "reflect" + "strconv" + "strings" + "time" +) + +// EnabledState is a convenience type, mostly used in Create and Update +// operations. Because the zero value of a bool is FALSE, we need to use a +// pointer instead to indicate zero-ness. +type EnabledState *bool + +// Convenience vars for EnabledState values. +var ( + iTrue = true + iFalse = false + + Enabled EnabledState = &iTrue + Disabled EnabledState = &iFalse +) + +// IntToPointer is a function for converting integers into integer pointers. +// This is useful when passing in options to operations. +func IntToPointer(i int) *int { + return &i +} + +/* +MaybeString is an internal function to be used by request methods in individual +resource packages. + +It takes a string that might be a zero value and returns either a pointer to its +address or nil. This is useful for allowing users to conveniently omit values +from an options struct by leaving them zeroed, but still pass nil to the JSON +serializer so they'll be omitted from the request body. +*/ +func MaybeString(original string) *string { + if original != "" { + return &original + } + return nil +} + +/* +MaybeInt is an internal function to be used by request methods in individual +resource packages. + +Like MaybeString, it accepts an int that may or may not be a zero value, and +returns either a pointer to its address or nil. It's intended to hint that the +JSON serializer should omit its field. +*/ +func MaybeInt(original int) *int { + if original != 0 { + return &original + } + return nil +} + +var t time.Time + +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Func, reflect.Map, reflect.Slice: + return v.IsNil() + case reflect.Array: + z := true + for i := 0; i < v.Len(); i++ { + z = z && isZero(v.Index(i)) + } + return z + case reflect.Struct: + if v.Type() == reflect.TypeOf(t) { + if v.Interface().(time.Time).IsZero() { + return true + } + return false + } + z := true + for i := 0; i < v.NumField(); i++ { + z = z && isZero(v.Field(i)) + } + return z + } + // Compare other types directly: + z := reflect.Zero(v.Type()) + return v.Interface() == z.Interface() +} + +/* +BuildQueryString is an internal function to be used by request methods in +individual resource packages. + +It accepts a tagged structure and expands it into a URL struct. Field names are +converted into query parameters based on a "q" tag. For example: + + type struct Something { + Bar string `q:"x_bar"` + Baz int `q:"lorem_ipsum"` + } + + instance := Something{ + Bar: "AAA", + Baz: "BBB", + } + +will be converted into "?x_bar=AAA&lorem_ipsum=BBB". + +The struct's fields may be strings, integers, or boolean values. Fields left at +their type's zero value will be omitted from the query. +*/ +func BuildQueryString(opts interface{}) (*url.URL, error) { + optsValue := reflect.ValueOf(opts) + if optsValue.Kind() == reflect.Ptr { + optsValue = optsValue.Elem() + } + + optsType := reflect.TypeOf(opts) + if optsType.Kind() == reflect.Ptr { + optsType = optsType.Elem() + } + + params := url.Values{} + + if optsValue.Kind() == reflect.Struct { + for i := 0; i < optsValue.NumField(); i++ { + v := optsValue.Field(i) + f := optsType.Field(i) + qTag := f.Tag.Get("q") + + // if the field has a 'q' tag, it goes in the query string + if qTag != "" { + tags := strings.Split(qTag, ",") + + // if the field is set, add it to the slice of query pieces + if !isZero(v) { + switch v.Kind() { + case reflect.String: + params.Add(tags[0], v.String()) + case reflect.Int: + params.Add(tags[0], strconv.FormatInt(v.Int(), 10)) + case reflect.Bool: + params.Add(tags[0], strconv.FormatBool(v.Bool())) + case reflect.Slice: + switch v.Type().Elem() { + case reflect.TypeOf(0): + for i := 0; i < v.Len(); i++ { + params.Add(tags[0], strconv.FormatInt(v.Index(i).Int(), 10)) + } + default: + for i := 0; i < v.Len(); i++ { + params.Add(tags[0], v.Index(i).String()) + } + } + } + } else { + // Otherwise, the field is not set. + if len(tags) == 2 && tags[1] == "required" { + // And the field is required. Return an error. + return nil, fmt.Errorf("Required query parameter [%s] not set.", f.Name) + } + } + } + } + + return &url.URL{RawQuery: params.Encode()}, nil + } + // Return an error if the underlying type of 'opts' isn't a struct. + return nil, fmt.Errorf("Options type is not a struct.") +} + +/* +BuildHeaders is an internal function to be used by request methods in +individual resource packages. + +It accepts an arbitrary tagged structure and produces a string map that's +suitable for use as the HTTP headers of an outgoing request. Field names are +mapped to header names based in "h" tags. + + type struct Something { + Bar string `h:"x_bar"` + Baz int `h:"lorem_ipsum"` + } + + instance := Something{ + Bar: "AAA", + Baz: "BBB", + } + +will be converted into: + + map[string]string{ + "x_bar": "AAA", + "lorem_ipsum": "BBB", + } + +Untagged fields and fields left at their zero values are skipped. Integers, +booleans and string values are supported. +*/ +func BuildHeaders(opts interface{}) (map[string]string, error) { + optsValue := reflect.ValueOf(opts) + if optsValue.Kind() == reflect.Ptr { + optsValue = optsValue.Elem() + } + + optsType := reflect.TypeOf(opts) + if optsType.Kind() == reflect.Ptr { + optsType = optsType.Elem() + } + + optsMap := make(map[string]string) + if optsValue.Kind() == reflect.Struct { + for i := 0; i < optsValue.NumField(); i++ { + v := optsValue.Field(i) + f := optsType.Field(i) + hTag := f.Tag.Get("h") + + // if the field has a 'h' tag, it goes in the header + if hTag != "" { + tags := strings.Split(hTag, ",") + + // if the field is set, add it to the slice of query pieces + if !isZero(v) { + switch v.Kind() { + case reflect.String: + optsMap[tags[0]] = v.String() + case reflect.Int: + optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) + case reflect.Bool: + optsMap[tags[0]] = strconv.FormatBool(v.Bool()) + } + } else { + // Otherwise, the field is not set. + if len(tags) == 2 && tags[1] == "required" { + // And the field is required. Return an error. + return optsMap, fmt.Errorf("Required header not set.") + } + } + } + + } + return optsMap, nil + } + // Return an error if the underlying type of 'opts' isn't a struct. + return optsMap, fmt.Errorf("Options type is not a struct.") +} + +// IDSliceToQueryString takes a slice of elements and converts them into a query +// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the +// result would be `?name=20&name=40&name=60' +func IDSliceToQueryString(name string, ids []int) string { + str := "" + for k, v := range ids { + if k == 0 { + str += "?" + } else { + str += "&" + } + str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v)) + } + return str +} + +// IntWithinRange returns TRUE if an integer falls within a defined range, and +// FALSE if not. +func IntWithinRange(val, min, max int) bool { + return val > min && val < max +} diff --git a/vendor/github.com/rackspace/gophercloud/provider_client.go b/vendor/github.com/rackspace/gophercloud/provider_client.go new file mode 100644 index 0000000000..0dff2cfc30 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/provider_client.go @@ -0,0 +1,300 @@ +package gophercloud + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "strings" +) + +// DefaultUserAgent is the default User-Agent string set in the request header. +const DefaultUserAgent = "gophercloud/1.0.0" + +// UserAgent represents a User-Agent header. +type UserAgent struct { + // prepend is the slice of User-Agent strings to prepend to DefaultUserAgent. + // All the strings to prepend are accumulated and prepended in the Join method. + prepend []string +} + +// Prepend prepends a user-defined string to the default User-Agent string. Users +// may pass in one or more strings to prepend. +func (ua *UserAgent) Prepend(s ...string) { + ua.prepend = append(s, ua.prepend...) +} + +// Join concatenates all the user-defined User-Agend strings with the default +// Gophercloud User-Agent string. +func (ua *UserAgent) Join() string { + uaSlice := append(ua.prepend, DefaultUserAgent) + return strings.Join(uaSlice, " ") +} + +// ProviderClient stores details that are required to interact with any +// services within a specific provider's API. +// +// Generally, you acquire a ProviderClient by calling the NewClient method in +// the appropriate provider's child package, providing whatever authentication +// credentials are required. +type ProviderClient struct { + // IdentityBase is the base URL used for a particular provider's identity + // service - it will be used when issuing authenticatation requests. It + // should point to the root resource of the identity service, not a specific + // identity version. + IdentityBase string + + // IdentityEndpoint is the identity endpoint. This may be a specific version + // of the identity service. If this is the case, this endpoint is used rather + // than querying versions first. + IdentityEndpoint string + + // TokenID is the ID of the most recently issued valid token. + TokenID string + + // EndpointLocator describes how this provider discovers the endpoints for + // its constituent services. + EndpointLocator EndpointLocator + + // HTTPClient allows users to interject arbitrary http, https, or other transit behaviors. + HTTPClient http.Client + + // UserAgent represents the User-Agent header in the HTTP request. + UserAgent UserAgent + + // ReauthFunc is the function used to re-authenticate the user if the request + // fails with a 401 HTTP response code. This a needed because there may be multiple + // authentication functions for different Identity service versions. + ReauthFunc func() error +} + +// AuthenticatedHeaders returns a map of HTTP headers that are common for all +// authenticated service requests. +func (client *ProviderClient) AuthenticatedHeaders() map[string]string { + if client.TokenID == "" { + return map[string]string{} + } + return map[string]string{"X-Auth-Token": client.TokenID} +} + +// RequestOpts customizes the behavior of the provider.Request() method. +type RequestOpts struct { + // JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The + // content type of the request will default to "application/json" unless overridden by MoreHeaders. + // It's an error to specify both a JSONBody and a RawBody. + JSONBody interface{} + // RawBody contains an io.Reader that will be consumed by the request directly. No content-type + // will be set unless one is provided explicitly by MoreHeaders. + RawBody io.Reader + + // JSONResponse, if provided, will be populated with the contents of the response body parsed as + // JSON. + JSONResponse interface{} + // OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If + // the response has a different code, an error will be returned. + OkCodes []int + + // MoreHeaders specifies additional HTTP headers to be provide on the request. If a header is + // provided with a blank value (""), that header will be *omitted* instead: use this to suppress + // the default Accept header or an inferred Content-Type, for example. + MoreHeaders map[string]string +} + +// UnexpectedResponseCodeError is returned by the Request method when a response code other than +// those listed in OkCodes is encountered. +type UnexpectedResponseCodeError struct { + URL string + Method string + Expected []int + Actual int + Body []byte +} + +func (err *UnexpectedResponseCodeError) Error() string { + return fmt.Sprintf( + "Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s", + err.Expected, err.Method, err.URL, err.Actual, err.Body, + ) +} + +var applicationJSON = "application/json" + +// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication +// header will automatically be provided. +func (client *ProviderClient) Request(method, url string, options RequestOpts) (*http.Response, error) { + var body io.Reader + var contentType *string + + // Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided + // io.Reader as-is. Default the content-type to application/json. + if options.JSONBody != nil { + if options.RawBody != nil { + panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().") + } + + rendered, err := json.Marshal(options.JSONBody) + if err != nil { + return nil, err + } + + body = bytes.NewReader(rendered) + contentType = &applicationJSON + } + + if options.RawBody != nil { + body = options.RawBody + } + + // Construct the http.Request. + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + + // Populate the request headers. Apply options.MoreHeaders last, to give the caller the chance to + // modify or omit any header. + if contentType != nil { + req.Header.Set("Content-Type", *contentType) + } + req.Header.Set("Accept", applicationJSON) + + for k, v := range client.AuthenticatedHeaders() { + req.Header.Add(k, v) + } + + // Set the User-Agent header + req.Header.Set("User-Agent", client.UserAgent.Join()) + + if options.MoreHeaders != nil { + for k, v := range options.MoreHeaders { + if v != "" { + req.Header.Set(k, v) + } else { + req.Header.Del(k) + } + } + } + + // Issue the request. + resp, err := client.HTTPClient.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode == http.StatusUnauthorized { + if client.ReauthFunc != nil { + err = client.ReauthFunc() + if err != nil { + return nil, fmt.Errorf("Error trying to re-authenticate: %s", err) + } + resp, err = client.Request(method, url, options) + if err != nil { + return nil, fmt.Errorf("Successfully re-authenticated, but got error executing request: %s", err) + } + } + } + + // Allow default OkCodes if none explicitly set + if options.OkCodes == nil { + options.OkCodes = defaultOkCodes(method) + } + + // Validate the HTTP response status. + var ok bool + for _, code := range options.OkCodes { + if resp.StatusCode == code { + ok = true + break + } + } + if !ok { + body, _ := ioutil.ReadAll(resp.Body) + resp.Body.Close() + return resp, &UnexpectedResponseCodeError{ + URL: url, + Method: method, + Expected: options.OkCodes, + Actual: resp.StatusCode, + Body: body, + } + } + + // Parse the response body as JSON, if requested to do so. + if options.JSONResponse != nil { + defer resp.Body.Close() + json.NewDecoder(resp.Body).Decode(options.JSONResponse) + } + + return resp, nil +} + +func defaultOkCodes(method string) []int { + switch { + case method == "GET": + return []int{200} + case method == "POST": + return []int{201, 202} + case method == "PUT": + return []int{201, 202} + case method == "DELETE": + return []int{202, 204} + } + + return []int{} +} + +func (client *ProviderClient) Get(url string, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = &RequestOpts{} + } + if JSONResponse != nil { + opts.JSONResponse = JSONResponse + } + return client.Request("GET", url, *opts) +} + +func (client *ProviderClient) Post(url string, JSONBody interface{}, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = &RequestOpts{} + } + + if v, ok := (JSONBody).(io.Reader); ok { + opts.RawBody = v + } else if JSONBody != nil { + opts.JSONBody = JSONBody + } + + if JSONResponse != nil { + opts.JSONResponse = JSONResponse + } + + return client.Request("POST", url, *opts) +} + +func (client *ProviderClient) Put(url string, JSONBody interface{}, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = &RequestOpts{} + } + + if v, ok := (JSONBody).(io.Reader); ok { + opts.RawBody = v + } else if JSONBody != nil { + opts.JSONBody = JSONBody + } + + if JSONResponse != nil { + opts.JSONResponse = JSONResponse + } + + return client.Request("PUT", url, *opts) +} + +func (client *ProviderClient) Delete(url string, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = &RequestOpts{} + } + + return client.Request("DELETE", url, *opts) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/auth_env.go b/vendor/github.com/rackspace/gophercloud/rackspace/auth_env.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/auth_env.go rename to vendor/github.com/rackspace/gophercloud/rackspace/auth_env.go diff --git a/vendor/github.com/rackspace/gophercloud/rackspace/client.go b/vendor/github.com/rackspace/gophercloud/rackspace/client.go new file mode 100644 index 0000000000..db3f305b52 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/rackspace/client.go @@ -0,0 +1,214 @@ +package rackspace + +import ( + "fmt" + + "github.com/rackspace/gophercloud" + os "github.com/rackspace/gophercloud/openstack" + "github.com/rackspace/gophercloud/openstack/utils" + tokens2 "github.com/rackspace/gophercloud/rackspace/identity/v2/tokens" +) + +const ( + // RackspaceUSIdentity is an identity endpoint located in the United States. + RackspaceUSIdentity = "https://identity.api.rackspacecloud.com/v2.0/" + + // RackspaceUKIdentity is an identity endpoint located in the UK. + RackspaceUKIdentity = "https://lon.identity.api.rackspacecloud.com/v2.0/" +) + +const ( + v20 = "v2.0" +) + +// NewClient creates a client that's prepared to communicate with the Rackspace API, but is not +// yet authenticated. Most users will probably prefer using the AuthenticatedClient function +// instead. +// +// Provide the base URL of the identity endpoint you wish to authenticate against as "endpoint". +// Often, this will be either RackspaceUSIdentity or RackspaceUKIdentity. +func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { + if endpoint == "" { + return os.NewClient(RackspaceUSIdentity) + } + return os.NewClient(endpoint) +} + +// AuthenticatedClient logs in to Rackspace with the provided credentials and constructs a +// ProviderClient that's ready to operate. +// +// If the provided AuthOptions does not specify an explicit IdentityEndpoint, it will default to +// the canonical, production Rackspace US identity endpoint. +func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) { + client, err := NewClient(options.IdentityEndpoint) + if err != nil { + return nil, err + } + + err = Authenticate(client, options) + if err != nil { + return nil, err + } + return client, nil +} + +// Authenticate or re-authenticate against the most recent identity service supported at the +// provided endpoint. +func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { + versions := []*utils.Version{ + &utils.Version{ID: v20, Priority: 20, Suffix: "/v2.0/"}, + } + + chosen, endpoint, err := utils.ChooseVersion(client, versions) + if err != nil { + return err + } + + switch chosen.ID { + case v20: + return v2auth(client, endpoint, options) + default: + // The switch statement must be out of date from the versions list. + return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) + } +} + +// AuthenticateV2 explicitly authenticates with v2 of the identity service. +func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { + return v2auth(client, "", options) +} + +func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error { + v2Client := NewIdentityV2(client) + if endpoint != "" { + v2Client.Endpoint = endpoint + } + + result := tokens2.Create(v2Client, tokens2.WrapOptions(options)) + + token, err := result.ExtractToken() + if err != nil { + return err + } + + catalog, err := result.ExtractServiceCatalog() + if err != nil { + return err + } + + if options.AllowReauth { + client.ReauthFunc = func() error { + return AuthenticateV2(client, options) + } + } + client.TokenID = token.ID + client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { + return os.V2EndpointURL(catalog, opts) + } + + return nil +} + +// NewIdentityV2 creates a ServiceClient that may be used to access the v2 identity service. +func NewIdentityV2(client *gophercloud.ProviderClient) *gophercloud.ServiceClient { + v2Endpoint := client.IdentityBase + "v2.0/" + + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: v2Endpoint, + } +} + +// NewComputeV2 creates a ServiceClient that may be used to access the v2 compute service. +func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("compute") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: url, + }, nil +} + +// NewObjectCDNV1 creates a ServiceClient that may be used with the Rackspace v1 CDN. +func NewObjectCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("rax:object-cdn") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewObjectStorageV1 creates a ServiceClient that may be used with the Rackspace v1 object storage package. +func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return os.NewObjectStorageV1(client, eo) +} + +// NewBlockStorageV1 creates a ServiceClient that can be used to access the +// Rackspace Cloud Block Storage v1 API. +func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("volume") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewLBV1 creates a ServiceClient that can be used to access the Rackspace +// Cloud Load Balancer v1 API. +func NewLBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("rax:load-balancer") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewNetworkV2 creates a ServiceClient that can be used to access the Rackspace +// Networking v2 API. +func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("network") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewCDNV1 creates a ServiceClient that may be used to access the Rackspace v1 +// CDN service. +func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("rax:cdn") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 orchestration service. +func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("orchestration") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} + +// NewRackConnectV3 creates a ServiceClient that may be used to access the v3 RackConnect service. +func NewRackConnectV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + eo.ApplyDefaults("rax:rackconnect") + url, err := client.EndpointLocator(eo) + if err != nil { + return nil, err + } + return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate.go b/vendor/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate.go rename to vendor/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/delegate.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/doc.go b/vendor/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/doc.go rename to vendor/github.com/rackspace/gophercloud/rackspace/identity/v2/tokens/doc.go diff --git a/vendor/github.com/rackspace/gophercloud/results.go b/vendor/github.com/rackspace/gophercloud/results.go new file mode 100644 index 0000000000..7c86ce4623 --- /dev/null +++ b/vendor/github.com/rackspace/gophercloud/results.go @@ -0,0 +1,150 @@ +package gophercloud + +import ( + "encoding/json" + "net/http" + "reflect" + + "github.com/mitchellh/mapstructure" +) + +/* +Result is an internal type to be used by individual resource packages, but its +methods will be available on a wide variety of user-facing embedding types. + +It acts as a base struct that other Result types, returned from request +functions, can embed for convenience. All Results capture basic information +from the HTTP transaction that was performed, including the response body, +HTTP headers, and any errors that happened. + +Generally, each Result type will have an Extract method that can be used to +further interpret the result's payload in a specific context. Extensions or +providers can then provide additional extraction functions to pull out +provider- or extension-specific information as well. +*/ +type Result struct { + // Body is the payload of the HTTP response from the server. In most cases, + // this will be the deserialized JSON structure. + Body interface{} + + // Header contains the HTTP header structure from the original response. + Header http.Header + + // Err is an error that occurred during the operation. It's deferred until + // extraction to make it easier to chain the Extract call. + Err error +} + +// PrettyPrintJSON creates a string containing the full response body as +// pretty-printed JSON. It's useful for capturing test fixtures and for +// debugging extraction bugs. If you include its output in an issue related to +// a buggy extraction function, we will all love you forever. +func (r Result) PrettyPrintJSON() string { + pretty, err := json.MarshalIndent(r.Body, "", " ") + if err != nil { + panic(err.Error()) + } + return string(pretty) +} + +// ErrResult is an internal type to be used by individual resource packages, but +// its methods will be available on a wide variety of user-facing embedding +// types. +// +// It represents results that only contain a potential error and +// nothing else. Usually, if the operation executed successfully, the Err field +// will be nil; otherwise it will be stocked with a relevant error. Use the +// ExtractErr method +// to cleanly pull it out. +type ErrResult struct { + Result +} + +// ExtractErr is a function that extracts error information, or nil, from a result. +func (r ErrResult) ExtractErr() error { + return r.Err +} + +/* +HeaderResult is an internal type to be used by individual resource packages, but +its methods will be available on a wide variety of user-facing embedding types. + +It represents a result that only contains an error (possibly nil) and an +http.Header. This is used, for example, by the objectstorage packages in +openstack, because most of the operations don't return response bodies, but do +have relevant information in headers. +*/ +type HeaderResult struct { + Result +} + +// ExtractHeader will return the http.Header and error from the HeaderResult. +// +// header, err := objects.Create(client, "my_container", objects.CreateOpts{}).ExtractHeader() +func (hr HeaderResult) ExtractHeader() (http.Header, error) { + return hr.Header, hr.Err +} + +// DecodeHeader is a function that decodes a header (usually of type map[string]interface{}) to +// another type (usually a struct). This function is used by the objectstorage package to give +// users access to response headers without having to query a map. A DecodeHookFunction is used, +// because OpenStack-based clients return header values as arrays (Go slices). +func DecodeHeader(from, to interface{}) error { + config := &mapstructure.DecoderConfig{ + DecodeHook: func(from, to reflect.Kind, data interface{}) (interface{}, error) { + if from == reflect.Slice { + return data.([]string)[0], nil + } + return data, nil + }, + Result: to, + WeaklyTypedInput: true, + } + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + if err := decoder.Decode(from); err != nil { + return err + } + return nil +} + +// RFC3339Milli describes a common time format used by some API responses. +const RFC3339Milli = "2006-01-02T15:04:05.999999Z" + +/* +Link is an internal type to be used in packages of collection resources that are +paginated in a certain way. + +It's a response substructure common to many paginated collection results that is +used to point to related pages. Usually, the one we care about is the one with +Rel field set to "next". +*/ +type Link struct { + Href string `mapstructure:"href"` + Rel string `mapstructure:"rel"` +} + +/* +ExtractNextURL is an internal function useful for packages of collection +resources that are paginated in a certain way. + +It attempts attempts to extract the "next" URL from slice of Link structs, or +"" if no such URL is present. +*/ +func ExtractNextURL(links []Link) (string, error) { + var url string + + for _, l := range links { + if l.Rel == "next" { + url = l.Href + } + } + + if url == "" { + return "", nil + } + + return url, nil +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/service_client.go b/vendor/github.com/rackspace/gophercloud/service_client.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/service_client.go rename to vendor/github.com/rackspace/gophercloud/service_client.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/client/fake.go b/vendor/github.com/rackspace/gophercloud/testhelper/client/fake.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/client/fake.go rename to vendor/github.com/rackspace/gophercloud/testhelper/client/fake.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/convenience.go b/vendor/github.com/rackspace/gophercloud/testhelper/convenience.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/convenience.go rename to vendor/github.com/rackspace/gophercloud/testhelper/convenience.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/doc.go b/vendor/github.com/rackspace/gophercloud/testhelper/doc.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/doc.go rename to vendor/github.com/rackspace/gophercloud/testhelper/doc.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/http_responses.go b/vendor/github.com/rackspace/gophercloud/testhelper/http_responses.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/testhelper/http_responses.go rename to vendor/github.com/rackspace/gophercloud/testhelper/http_responses.go diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/util.go b/vendor/github.com/rackspace/gophercloud/util.go similarity index 100% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/util.go rename to vendor/github.com/rackspace/gophercloud/util.go diff --git a/vendor/github.com/samalba/dockerclient/.gitignore b/vendor/github.com/samalba/dockerclient/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/samalba/dockerclient/LICENSE b/vendor/github.com/samalba/dockerclient/LICENSE new file mode 100644 index 0000000000..00e1edb90f --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2014 Sam Alba + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/github.com/samalba/dockerclient/README.md b/vendor/github.com/samalba/dockerclient/README.md new file mode 100644 index 0000000000..6cad9bd318 --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/README.md @@ -0,0 +1,98 @@ +Docker client library in Go +=========================== +[![GoDoc](http://godoc.org/github.com/samalba/dockerclient?status.png)](http://godoc.org/github.com/samalba/dockerclient) + +Well maintained docker client library. + +# How to use it? + +Here is an example showing how to use it: + +```go +package main + +import ( + "github.com/samalba/dockerclient" + "log" + "time" + "os" +) + +// Callback used to listen to Docker's events +func eventCallback(event *dockerclient.Event, ec chan error, args ...interface{}) { + log.Printf("Received event: %#v\n", *event) +} + +func main() { + // Init the client + docker, _ := dockerclient.NewDockerClient("unix:///var/run/docker.sock", nil) + + // Get only running containers + containers, err := docker.ListContainers(false, false, "") + if err != nil { + log.Fatal(err) + } + for _, c := range containers { + log.Println(c.Id, c.Names) + } + + // Inspect the first container returned + if len(containers) > 0 { + id := containers[0].Id + info, _ := docker.InspectContainer(id) + log.Println(info) + } + + // Build a docker image + // some.tar contains the build context (Dockerfile any any files it needs to add/copy) + dockerBuildContext, err := os.Open("some.tar") + defer dockerBuildContext.Close() + buildImageConfig := &dockerclient.BuildImage{ + Context: dockerBuildContext, + RepoName: "your_image_name", + SuppressOutput: false, + } + reader, err := docker.BuildImage(buildImageConfig) + if err != nil { + log.Fatal(err) + } + + // Create a container + containerConfig := &dockerclient.ContainerConfig{ + Image: "ubuntu:14.04", + Cmd: []string{"bash"}, + AttachStdin: true, + Tty: true} + containerId, err := docker.CreateContainer(containerConfig, "foobar", nil) + if err != nil { + log.Fatal(err) + } + + // Start the container + hostConfig := &dockerclient.HostConfig{} + err = docker.StartContainer(containerId, hostConfig) + if err != nil { + log.Fatal(err) + } + + // Stop the container (with 5 seconds timeout) + docker.StopContainer(containerId, 5) + + // Listen to events + docker.StartMonitorEvents(eventCallback, nil) + + // Hold the execution to look at the events coming + time.Sleep(3600 * time.Second) +} +``` + +# Maintainers + +List of people you can ping for feedback on Pull Requests or any questions. + +- [Sam Alba](https://github.com/samalba) +- [Michael Crosby](https://github.com/crosbymichael) +- [Andrea Luzzardi](https://github.com/aluzzardi) +- [Victor Vieux](https://github.com/vieux) +- [Evan Hazlett](https://github.com/ehazlett) +- [Donald Huang](https://github.com/donhcd) diff --git a/vendor/github.com/samalba/dockerclient/auth.go b/vendor/github.com/samalba/dockerclient/auth.go new file mode 100644 index 0000000000..7c0a67f77e --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/auth.go @@ -0,0 +1,39 @@ +package dockerclient + +import ( + "bytes" + "encoding/base64" + "encoding/json" +) + +// AuthConfig hold parameters for authenticating with the docker registry +type AuthConfig struct { + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Email string `json:"email,omitempty"` + RegistryToken string `json:"registrytoken,omitempty"` +} + +// encode the auth configuration struct into base64 for the X-Registry-Auth header +func (c *AuthConfig) encode() (string, error) { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(c); err != nil { + return "", err + } + return base64.URLEncoding.EncodeToString(buf.Bytes()), nil +} + +// ConfigFile holds parameters for authenticating during a BuildImage request +type ConfigFile struct { + Configs map[string]AuthConfig `json:"configs,omitempty"` + rootPath string +} + +// encode the configuration struct into base64 for the X-Registry-Config header +func (c *ConfigFile) encode() (string, error) { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(c); err != nil { + return "", err + } + return base64.URLEncoding.EncodeToString(buf.Bytes()), nil +} diff --git a/vendor/github.com/samalba/dockerclient/dockerclient.go b/vendor/github.com/samalba/dockerclient/dockerclient.go new file mode 100644 index 0000000000..b52d52bf44 --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/dockerclient.go @@ -0,0 +1,937 @@ +package dockerclient + +import ( + "bytes" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + "sync/atomic" + "time" +) + +const ( + APIVersion = "v1.15" +) + +var ( + ErrImageNotFound = errors.New("Image not found") + ErrNotFound = errors.New("Not found") + ErrConnectionRefused = errors.New("Cannot connect to the docker engine endpoint") + + defaultTimeout = 30 * time.Second +) + +type DockerClient struct { + URL *url.URL + HTTPClient *http.Client + TLSConfig *tls.Config + monitorStats int32 + eventStopChan chan (struct{}) +} + +type Error struct { + StatusCode int + Status string + msg string +} + +func (e Error) Error() string { + return fmt.Sprintf("%s: %s", e.Status, e.msg) +} + +func NewDockerClient(daemonUrl string, tlsConfig *tls.Config) (*DockerClient, error) { + return NewDockerClientTimeout(daemonUrl, tlsConfig, time.Duration(defaultTimeout)) +} + +func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout time.Duration) (*DockerClient, error) { + u, err := url.Parse(daemonUrl) + if err != nil { + return nil, err + } + if u.Scheme == "" || u.Scheme == "tcp" { + if tlsConfig == nil { + u.Scheme = "http" + } else { + u.Scheme = "https" + } + } + httpClient := newHTTPClient(u, tlsConfig, timeout) + return &DockerClient{u, httpClient, tlsConfig, 0, nil}, nil +} + +func (client *DockerClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) { + b := bytes.NewBuffer(body) + + reader, err := client.doStreamRequest(method, path, b, headers) + if err != nil { + return nil, err + } + + defer reader.Close() + data, err := ioutil.ReadAll(reader) + if err != nil { + return nil, err + } + return data, nil +} + +func (client *DockerClient) doStreamRequest(method string, path string, in io.Reader, headers map[string]string) (io.ReadCloser, error) { + if (method == "POST" || method == "PUT") && in == nil { + in = bytes.NewReader(nil) + } + req, err := http.NewRequest(method, client.URL.String()+path, in) + if err != nil { + return nil, err + } + req.Header.Add("Content-Type", "application/json") + if headers != nil { + for header, value := range headers { + req.Header.Add(header, value) + } + } + resp, err := client.HTTPClient.Do(req) + if err != nil { + if !strings.Contains(err.Error(), "connection refused") && client.TLSConfig == nil { + return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err) + } + if strings.Contains(err.Error(), "connection refused") { + return nil, ErrConnectionRefused + } + return nil, err + } + if resp.StatusCode == 404 { + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, ErrNotFound + } + if len(data) > 0 { + // check if is image not found error + if strings.Index(string(data), "No such image") != -1 { + return nil, ErrImageNotFound + } + return nil, errors.New(string(data)) + } + return nil, ErrNotFound + } + if resp.StatusCode >= 400 { + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)} + } + + return resp.Body, nil +} + +func (client *DockerClient) Info() (*Info, error) { + uri := fmt.Sprintf("/%s/info", APIVersion) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + ret := &Info{} + err = json.Unmarshal(data, &ret) + if err != nil { + return nil, err + } + return ret, nil +} + +func (client *DockerClient) ListContainers(all bool, size bool, filters string) ([]Container, error) { + argAll := 0 + if all == true { + argAll = 1 + } + showSize := 0 + if size == true { + showSize = 1 + } + uri := fmt.Sprintf("/%s/containers/json?all=%d&size=%d", APIVersion, argAll, showSize) + + if filters != "" { + uri += "&filters=" + filters + } + + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + ret := []Container{} + err = json.Unmarshal(data, &ret) + if err != nil { + return nil, err + } + return ret, nil +} + +func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error) { + uri := fmt.Sprintf("/%s/containers/%s/json", APIVersion, id) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + info := &ContainerInfo{} + err = json.Unmarshal(data, info) + if err != nil { + return nil, err + } + return info, nil +} + +func (client *DockerClient) CreateContainer(config *ContainerConfig, name string, auth *AuthConfig) (string, error) { + data, err := json.Marshal(config) + if err != nil { + return "", err + } + uri := fmt.Sprintf("/%s/containers/create", APIVersion) + if name != "" { + v := url.Values{} + v.Set("name", name) + uri = fmt.Sprintf("%s?%s", uri, v.Encode()) + } + headers := map[string]string{} + if auth != nil { + encoded_auth, err := auth.encode() + if err != nil { + return "", err + } + headers["X-Registry-Auth"] = encoded_auth + } + data, err = client.doRequest("POST", uri, data, headers) + if err != nil { + return "", err + } + result := &RespContainersCreate{} + err = json.Unmarshal(data, result) + if err != nil { + return "", fmt.Errorf(string(data)) + } + return result.Id, nil +} + +func (client *DockerClient) ContainerLogs(id string, options *LogOptions) (io.ReadCloser, error) { + v := url.Values{} + v.Add("follow", strconv.FormatBool(options.Follow)) + v.Add("stdout", strconv.FormatBool(options.Stdout)) + v.Add("stderr", strconv.FormatBool(options.Stderr)) + v.Add("timestamps", strconv.FormatBool(options.Timestamps)) + if options.Tail > 0 { + v.Add("tail", strconv.FormatInt(options.Tail, 10)) + } + + uri := fmt.Sprintf("/%s/containers/%s/logs?%s", APIVersion, id, v.Encode()) + req, err := http.NewRequest("GET", client.URL.String()+uri, nil) + if err != nil { + return nil, err + } + req.Header.Add("Content-Type", "application/json") + resp, err := client.HTTPClient.Do(req) + if err != nil { + return nil, err + } + return resp.Body, nil +} + +func (client *DockerClient) ContainerChanges(id string) ([]*ContainerChanges, error) { + uri := fmt.Sprintf("/%s/containers/%s/changes", APIVersion, id) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + changes := []*ContainerChanges{} + err = json.Unmarshal(data, &changes) + if err != nil { + return nil, err + } + return changes, nil +} + +func (client *DockerClient) readJSONStream(stream io.ReadCloser, decode func(*json.Decoder) decodingResult, stopChan <-chan struct{}) <-chan decodingResult { + resultChan := make(chan decodingResult) + + go func() { + decodeChan := make(chan decodingResult) + + go func() { + decoder := json.NewDecoder(stream) + for { + decodeResult := decode(decoder) + decodeChan <- decodeResult + if decodeResult.err != nil { + close(decodeChan) + return + } + } + }() + + defer close(resultChan) + + for { + select { + case <-stopChan: + stream.Close() + for range decodeChan { + } + return + case decodeResult := <-decodeChan: + resultChan <- decodeResult + if decodeResult.err != nil { + stream.Close() + return + } + } + } + + }() + + return resultChan +} + +func (client *DockerClient) ExecCreate(config *ExecConfig) (string, error) { + data, err := json.Marshal(config) + if err != nil { + return "", err + } + uri := fmt.Sprintf("/%s/containers/%s/exec", APIVersion, config.Container) + resp, err := client.doRequest("POST", uri, data, nil) + if err != nil { + return "", err + } + var createExecResp struct { + Id string + } + if err = json.Unmarshal(resp, &createExecResp); err != nil { + return "", err + } + return createExecResp.Id, nil +} + +func (client *DockerClient) ExecStart(id string, config *ExecConfig) error { + data, err := json.Marshal(config) + if err != nil { + return err + } + + uri := fmt.Sprintf("/%s/exec/%s/start", APIVersion, id) + if _, err := client.doRequest("POST", uri, data, nil); err != nil { + return err + } + + return nil +} + +func (client *DockerClient) ExecResize(id string, width, height int) error { + v := url.Values{} + + w := strconv.Itoa(width) + h := strconv.Itoa(height) + + v.Set("w", w) + v.Set("h", h) + + uri := fmt.Sprintf("/%s/exec/%s/resize?%s", APIVersion, id, v.Encode()) + if _, err := client.doRequest("POST", client.URL.String()+uri, nil, nil); err != nil { + return err + } + + return nil +} + +func (client *DockerClient) AttachContainer(id string, options *AttachOptions) (io.ReadCloser, error) { + v := url.Values{} + if options != nil { + if options.Logs { + v.Set("logs", "1") + } + if options.Stream { + v.Set("stream", "1") + } + if options.Stdin { + v.Set("stdin", "1") + } + if options.Stdout { + v.Set("stdout", "1") + } + if options.Stderr { + v.Set("stderr", "1") + } + } + uri := fmt.Sprintf("/%s/containers/%s/attach?%s", APIVersion, id, v.Encode()) + return client.doStreamRequest("POST", uri, nil, nil) +} + +func (client *DockerClient) StartContainer(id string, config *HostConfig) error { + data, err := json.Marshal(config) + if err != nil { + return err + } + uri := fmt.Sprintf("/%s/containers/%s/start", APIVersion, id) + _, err = client.doRequest("POST", uri, data, nil) + if err != nil { + return err + } + return nil +} + +func (client *DockerClient) StopContainer(id string, timeout int) error { + uri := fmt.Sprintf("/%s/containers/%s/stop?t=%d", APIVersion, id, timeout) + _, err := client.doRequest("POST", uri, nil, nil) + if err != nil { + return err + } + return nil +} + +func (client *DockerClient) RestartContainer(id string, timeout int) error { + uri := fmt.Sprintf("/%s/containers/%s/restart?t=%d", APIVersion, id, timeout) + _, err := client.doRequest("POST", uri, nil, nil) + if err != nil { + return err + } + return nil +} + +func (client *DockerClient) KillContainer(id, signal string) error { + uri := fmt.Sprintf("/%s/containers/%s/kill?signal=%s", APIVersion, id, signal) + _, err := client.doRequest("POST", uri, nil, nil) + if err != nil { + return err + } + return nil +} + +func (client *DockerClient) Wait(id string) <-chan WaitResult { + ch := make(chan WaitResult) + uri := fmt.Sprintf("/%s/containers/%s/wait", APIVersion, id) + + go func() { + data, err := client.doRequest("POST", uri, nil, nil) + if err != nil { + ch <- WaitResult{ExitCode: -1, Error: err} + return + } + + var result struct { + StatusCode int `json:"StatusCode"` + } + err = json.Unmarshal(data, &result) + ch <- WaitResult{ExitCode: result.StatusCode, Error: err} + }() + return ch +} + +func (client *DockerClient) MonitorEvents(options *MonitorEventsOptions, stopChan <-chan struct{}) (<-chan EventOrError, error) { + v := url.Values{} + if options != nil { + if options.Since != 0 { + v.Add("since", strconv.Itoa(options.Since)) + } + if options.Until != 0 { + v.Add("until", strconv.Itoa(options.Until)) + } + if options.Filters != nil { + filterMap := make(map[string][]string) + if len(options.Filters.Event) > 0 { + filterMap["event"] = []string{options.Filters.Event} + } + if len(options.Filters.Image) > 0 { + filterMap["image"] = []string{options.Filters.Image} + } + if len(options.Filters.Container) > 0 { + filterMap["container"] = []string{options.Filters.Container} + } + if len(filterMap) > 0 { + filterJSONBytes, err := json.Marshal(filterMap) + if err != nil { + return nil, err + } + v.Add("filters", string(filterJSONBytes)) + } + } + } + uri := fmt.Sprintf("%s/%s/events?%s", client.URL.String(), APIVersion, v.Encode()) + resp, err := client.HTTPClient.Get(uri) + if err != nil { + return nil, err + } + + decode := func(decoder *json.Decoder) decodingResult { + var event Event + if err := decoder.Decode(&event); err != nil { + return decodingResult{err: err} + } else { + return decodingResult{result: event} + } + } + decodingResultChan := client.readJSONStream(resp.Body, decode, stopChan) + eventOrErrorChan := make(chan EventOrError) + go func() { + for decodingResult := range decodingResultChan { + event, _ := decodingResult.result.(Event) + eventOrErrorChan <- EventOrError{ + Event: event, + Error: decodingResult.err, + } + } + close(eventOrErrorChan) + }() + return eventOrErrorChan, nil +} + +func (client *DockerClient) StartMonitorEvents(cb Callback, ec chan error, args ...interface{}) { + client.eventStopChan = make(chan struct{}) + + go func() { + eventErrChan, err := client.MonitorEvents(nil, client.eventStopChan) + if err != nil { + if ec != nil { + ec <- err + } + return + } + + for e := range eventErrChan { + if e.Error != nil { + if ec != nil { + ec <- err + } + return + } + cb(&e.Event, ec, args...) + } + }() +} + +func (client *DockerClient) StopAllMonitorEvents() { + if client.eventStopChan == nil { + return + } + close(client.eventStopChan) +} + +func (client *DockerClient) StartMonitorStats(id string, cb StatCallback, ec chan error, args ...interface{}) { + atomic.StoreInt32(&client.monitorStats, 1) + go client.getStats(id, cb, ec, args...) +} + +func (client *DockerClient) getStats(id string, cb StatCallback, ec chan error, args ...interface{}) { + uri := fmt.Sprintf("%s/%s/containers/%s/stats", client.URL.String(), APIVersion, id) + resp, err := client.HTTPClient.Get(uri) + if err != nil { + ec <- err + return + } + defer resp.Body.Close() + + dec := json.NewDecoder(resp.Body) + for atomic.LoadInt32(&client.monitorStats) > 0 { + var stats *Stats + if err := dec.Decode(&stats); err != nil { + ec <- err + return + } + cb(id, stats, ec, args...) + } +} + +func (client *DockerClient) StopAllMonitorStats() { + atomic.StoreInt32(&client.monitorStats, 0) +} + +func (client *DockerClient) TagImage(nameOrID string, repo string, tag string, force bool) error { + v := url.Values{} + v.Set("repo", repo) + v.Set("tag", tag) + if force { + v.Set("force", "1") + } + uri := fmt.Sprintf("/%s/images/%s/tag?%s", APIVersion, nameOrID, v.Encode()) + if _, err := client.doRequest("POST", uri, nil, nil); err != nil { + return err + } + return nil +} + +func (client *DockerClient) Version() (*Version, error) { + uri := fmt.Sprintf("/%s/version", APIVersion) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + version := &Version{} + err = json.Unmarshal(data, version) + if err != nil { + return nil, err + } + return version, nil +} + +func (client *DockerClient) PushImage(name string, tag string, auth *AuthConfig) error { + v := url.Values{} + if tag != "" { + v.Set("tag", tag) + } + uri := fmt.Sprintf("/%s/images/%s/push?%s", APIVersion, url.QueryEscape(name), v.Encode()) + req, err := http.NewRequest("POST", client.URL.String()+uri, nil) + if auth != nil { + if encodedAuth, err := auth.encode(); err != nil { + return err + } else { + req.Header.Add("X-Registry-Auth", encodedAuth) + } + } + resp, err := client.HTTPClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + var finalObj map[string]interface{} + for decoder := json.NewDecoder(resp.Body); err == nil; err = decoder.Decode(&finalObj) { + } + if err != io.EOF { + return err + } + if err, ok := finalObj["error"]; ok { + return fmt.Errorf("%v", err) + } + return nil +} + +func (client *DockerClient) PullImage(name string, auth *AuthConfig) error { + v := url.Values{} + v.Set("fromImage", name) + uri := fmt.Sprintf("/%s/images/create?%s", APIVersion, v.Encode()) + req, err := http.NewRequest("POST", client.URL.String()+uri, nil) + if auth != nil { + encoded_auth, err := auth.encode() + if err != nil { + return err + } + req.Header.Add("X-Registry-Auth", encoded_auth) + } + resp, err := client.HTTPClient.Do(req) + if err != nil { + return err + } + + defer resp.Body.Close() + if resp.StatusCode == 404 { + return ErrNotFound + } + if resp.StatusCode >= 400 { + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + return fmt.Errorf("%s", string(data)) + } + + var finalObj map[string]interface{} + for decoder := json.NewDecoder(resp.Body); err == nil; err = decoder.Decode(&finalObj) { + } + if err != io.EOF { + return err + } + if err, ok := finalObj["error"]; ok { + return fmt.Errorf("%v", err) + } + return nil +} + +func (client *DockerClient) InspectImage(id string) (*ImageInfo, error) { + uri := fmt.Sprintf("/%s/images/%s/json", APIVersion, id) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + info := &ImageInfo{} + err = json.Unmarshal(data, info) + if err != nil { + return nil, err + } + return info, nil +} + +func (client *DockerClient) LoadImage(reader io.Reader) error { + uri := fmt.Sprintf("/%s/images/load", APIVersion) + _, err := client.doStreamRequest("POST", uri, reader, nil) + return err +} + +func (client *DockerClient) RemoveContainer(id string, force, volumes bool) error { + argForce := 0 + argVolumes := 0 + if force == true { + argForce = 1 + } + if volumes == true { + argVolumes = 1 + } + args := fmt.Sprintf("force=%d&v=%d", argForce, argVolumes) + uri := fmt.Sprintf("/%s/containers/%s?%s", APIVersion, id, args) + _, err := client.doRequest("DELETE", uri, nil, nil) + return err +} + +func (client *DockerClient) ListImages(all bool) ([]*Image, error) { + argAll := 0 + if all { + argAll = 1 + } + uri := fmt.Sprintf("/%s/images/json?all=%d", APIVersion, argAll) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + var images []*Image + if err := json.Unmarshal(data, &images); err != nil { + return nil, err + } + return images, nil +} + +func (client *DockerClient) RemoveImage(name string, force bool) ([]*ImageDelete, error) { + argForce := 0 + if force { + argForce = 1 + } + + args := fmt.Sprintf("force=%d", argForce) + uri := fmt.Sprintf("/%s/images/%s?%s", APIVersion, name, args) + data, err := client.doRequest("DELETE", uri, nil, nil) + if err != nil { + return nil, err + } + var imageDelete []*ImageDelete + if err := json.Unmarshal(data, &imageDelete); err != nil { + return nil, err + } + return imageDelete, nil +} + +func (client *DockerClient) PauseContainer(id string) error { + uri := fmt.Sprintf("/%s/containers/%s/pause", APIVersion, id) + _, err := client.doRequest("POST", uri, nil, nil) + if err != nil { + return err + } + return nil +} +func (client *DockerClient) UnpauseContainer(id string) error { + uri := fmt.Sprintf("/%s/containers/%s/unpause", APIVersion, id) + _, err := client.doRequest("POST", uri, nil, nil) + if err != nil { + return err + } + return nil +} + +func (client *DockerClient) RenameContainer(oldName string, newName string) error { + uri := fmt.Sprintf("/containers/%s/rename?name=%s", oldName, newName) + _, err := client.doRequest("POST", uri, nil, nil) + return err +} + +func (client *DockerClient) ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error) { + var fromSrc string + v := &url.Values{} + if source == "" { + fromSrc = "-" + } else { + fromSrc = source + } + + v.Set("fromSrc", fromSrc) + v.Set("repo", repository) + if tag != "" { + v.Set("tag", tag) + } + + var in io.Reader + if fromSrc == "-" { + in = tar + } + return client.doStreamRequest("POST", "/images/create?"+v.Encode(), in, nil) +} + +func (client *DockerClient) BuildImage(image *BuildImage) (io.ReadCloser, error) { + v := url.Values{} + + if image.DockerfileName != "" { + v.Set("dockerfile", image.DockerfileName) + } + if image.RepoName != "" { + v.Set("t", image.RepoName) + } + if image.RemoteURL != "" { + v.Set("remote", image.RemoteURL) + } + if image.NoCache { + v.Set("nocache", "1") + } + if image.Pull { + v.Set("pull", "1") + } + if image.Remove { + v.Set("rm", "1") + } else { + v.Set("rm", "0") + } + if image.ForceRemove { + v.Set("forcerm", "1") + } + if image.SuppressOutput { + v.Set("q", "1") + } + + v.Set("memory", strconv.FormatInt(image.Memory, 10)) + v.Set("memswap", strconv.FormatInt(image.MemorySwap, 10)) + v.Set("cpushares", strconv.FormatInt(image.CpuShares, 10)) + v.Set("cpuperiod", strconv.FormatInt(image.CpuPeriod, 10)) + v.Set("cpuquota", strconv.FormatInt(image.CpuQuota, 10)) + v.Set("cpusetcpus", image.CpuSetCpus) + v.Set("cpusetmems", image.CpuSetMems) + v.Set("cgroupparent", image.CgroupParent) + if image.BuildArgs != nil { + buildArgsJSON, err := json.Marshal(image.BuildArgs) + if err != nil { + return nil, err + } + v.Set("buildargs", string(buildArgsJSON)) + } + + headers := make(map[string]string) + if image.Config != nil { + encoded_config, err := image.Config.encode() + if err != nil { + return nil, err + } + headers["X-Registry-Config"] = encoded_config + } + if image.Context != nil { + headers["Content-Type"] = "application/tar" + } + + uri := fmt.Sprintf("/%s/build?%s", APIVersion, v.Encode()) + return client.doStreamRequest("POST", uri, image.Context, headers) +} + +func (client *DockerClient) ListVolumes() ([]*Volume, error) { + uri := fmt.Sprintf("/%s/volumes", APIVersion) + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + var volumesList VolumesListResponse + if err := json.Unmarshal(data, &volumesList); err != nil { + return nil, err + } + return volumesList.Volumes, nil +} + +func (client *DockerClient) RemoveVolume(name string) error { + uri := fmt.Sprintf("/%s/volumes/%s", APIVersion, name) + _, err := client.doRequest("DELETE", uri, nil, nil) + return err +} + +func (client *DockerClient) CreateVolume(request *VolumeCreateRequest) (*Volume, error) { + data, err := json.Marshal(request) + if err != nil { + return nil, err + } + uri := fmt.Sprintf("/%s/volumes/create", APIVersion) + data, err = client.doRequest("POST", uri, data, nil) + if err != nil { + return nil, err + } + volume := &Volume{} + err = json.Unmarshal(data, volume) + return volume, err +} + +func (client *DockerClient) ListNetworks(filters string) ([]*NetworkResource, error) { + uri := fmt.Sprintf("/%s/networks", APIVersion) + + if filters != "" { + uri += "&filters=" + filters + } + + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + ret := []*NetworkResource{} + err = json.Unmarshal(data, &ret) + if err != nil { + return nil, err + } + return ret, nil +} + +func (client *DockerClient) InspectNetwork(id string) (*NetworkResource, error) { + uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id) + + data, err := client.doRequest("GET", uri, nil, nil) + if err != nil { + return nil, err + } + ret := &NetworkResource{} + err = json.Unmarshal(data, ret) + if err != nil { + return nil, err + } + + return ret, nil +} + +func (client *DockerClient) CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error) { + data, err := json.Marshal(config) + if err != nil { + return nil, err + } + uri := fmt.Sprintf("/%s/networks/create", APIVersion) + data, err = client.doRequest("POST", uri, data, nil) + if err != nil { + return nil, err + } + ret := &NetworkCreateResponse{} + err = json.Unmarshal(data, ret) + return ret, nil +} + +func (client *DockerClient) ConnectNetwork(id, container string) error { + data, err := json.Marshal(NetworkConnect{Container: container}) + if err != nil { + return err + } + uri := fmt.Sprintf("/%s/networks/%s/connect", APIVersion, id) + _, err = client.doRequest("POST", uri, data, nil) + return err +} + +func (client *DockerClient) DisconnectNetwork(id, container string) error { + data, err := json.Marshal(NetworkDisconnect{Container: container}) + if err != nil { + return err + } + uri := fmt.Sprintf("/%s/networks/%s/disconnect", APIVersion, id) + _, err = client.doRequest("POST", uri, data, nil) + return err +} + +func (client *DockerClient) RemoveNetwork(id string) error { + uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id) + _, err := client.doRequest("DELETE", uri, nil, nil) + return err +} diff --git a/vendor/github.com/samalba/dockerclient/example_responses.go b/vendor/github.com/samalba/dockerclient/example_responses.go new file mode 100644 index 0000000000..670508c074 --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/example_responses.go @@ -0,0 +1,13 @@ +package dockerclient + +var haproxyPullOutput = `{"status":"The image you are pulling has been verified","id":"haproxy:1"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"66301eb54a7d"}{"status":"Already exists","progressDetail":{},"id":"e3990b07573f"}{"status":"Already exists","progressDetail":{},"id":"ecb4b23ca7ce"}{"status":"Already exists","progressDetail":{},"id":"f453e940c177"}{"status":"Already exists","progressDetail":{},"id":"fc5ea1bc05ab"}{"status":"Already exists","progressDetail":{},"id":"380557f8f7b3"}{"status":"The image you are pulling has been verified","id":"haproxy:1.4"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"63a1b9929e14"}{"status":"Already exists","progressDetail":{},"id":"af43bf7d176e"}{"status":"Already exists","progressDetail":{},"id":"851aac2d69aa"}{"status":"Already exists","progressDetail":{},"id":"345053a92c95"}{"status":"Already exists","progressDetail":{},"id":"b41231d429c9"}{"status":"The image you are pulling has been verified","id":"haproxy:1.4.25"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"63a1b9929e14"}{"status":"Already exists","progressDetail":{},"id":"af43bf7d176e"}{"status":"Already exists","progressDetail":{},"id":"851aac2d69aa"}{"status":"Already exists","progressDetail":{},"id":"345053a92c95"}{"status":"Already exists","progressDetail":{},"id":"b41231d429c9"}{"status":"The image you are pulling has been verified","id":"haproxy:1.5"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"66301eb54a7d"}{"status":"Already exists","progressDetail":{},"id":"e3990b07573f"}{"status":"Already exists","progressDetail":{},"id":"ecb4b23ca7ce"}{"status":"Already exists","progressDetail":{},"id":"f453e940c177"}{"status":"Already exists","progressDetail":{},"id":"fc5ea1bc05ab"}{"status":"Already exists","progressDetail":{},"id":"380557f8f7b3"}{"status":"The image you are pulling has been verified","id":"haproxy:1.5.10"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"66301eb54a7d"}{"status":"Already exists","progressDetail":{},"id":"e3990b07573f"}{"status":"Already exists","progressDetail":{},"id":"ecb4b23ca7ce"}{"status":"Already exists","progressDetail":{},"id":"f453e940c177"}{"status":"Already exists","progressDetail":{},"id":"fc5ea1bc05ab"}{"status":"Already exists","progressDetail":{},"id":"380557f8f7b3"}{"status":"The image you are pulling has been verified","id":"haproxy:1.5.9"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"66301eb54a7d"}{"status":"Already exists","progressDetail":{},"id":"e3990b07573f"}{"status":"Already exists","progressDetail":{},"id":"3d894e6f7e63"}{"status":"Already exists","progressDetail":{},"id":"4d949c40bc77"}{"status":"Already exists","progressDetail":{},"id":"55e031889365"}{"status":"Already exists","progressDetail":{},"id":"c7aa675e1876"}{"status":"The image you are pulling has been verified","id":"haproxy:latest"} +{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"66301eb54a7d"}{"status":"Already exists","progressDetail":{},"id":"e3990b07573f"}{"status":"Already exists","progressDetail":{},"id":"ecb4b23ca7ce"}{"status":"Already exists","progressDetail":{},"id":"f453e940c177"}{"status":"Already exists","progressDetail":{},"id":"fc5ea1bc05ab"}{"status":"Already exists","progressDetail":{},"id":"380557f8f7b3"}{"status":"Status: Image is up to date for haproxy"} +` + +var eventsResp = `{"status":"pull","id":"nginx:latest","time":1428620433}{"status":"create","id":"9b818c3b8291708fdcecd7c4086b75c222cb503be10a93d9c11040886032a48b","from":"nginx:latest","time":1428620433}{"status":"start","id":"9b818c3b8291708fdcecd7c4086b75c222cb503be10a93d9c11040886032a48b","from":"nginx:latest","time":1428620433}{"status":"die","id":"9b818c3b8291708fdcecd7c4086b75c222cb503be10a93d9c11040886032a48b","from":"nginx:latest","time":1428620442}{"status":"create","id":"352d0b412aae5a5d2b14ae9d88be59dc276602d9edb9dcc33e138e475b3e4720","from":"52.11.96.81/foobar/ubuntu:latest","time":1428620444}{"status":"start","id":"352d0b412aae5a5d2b14ae9d88be59dc276602d9edb9dcc33e138e475b3e4720","from":"52.11.96.81/foobar/ubuntu:latest","time":1428620444}{"status":"die","id":"352d0b412aae5a5d2b14ae9d88be59dc276602d9edb9dcc33e138e475b3e4720","from":"52.11.96.81/foobar/ubuntu:latest","time":1428620444}{"status":"pull","id":"debian:latest","time":1428620453}{"status":"create","id":"668887b5729946546b3072655dc6da08f0e3210111b68b704eb842adfce53f6c","from":"debian:latest","time":1428620453}{"status":"start","id":"668887b5729946546b3072655dc6da08f0e3210111b68b704eb842adfce53f6c","from":"debian:latest","time":1428620453}{"status":"die","id":"668887b5729946546b3072655dc6da08f0e3210111b68b704eb842adfce53f6c","from":"debian:latest","time":1428620453}{"status":"create","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620458}{"status":"start","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620458}{"status":"pause","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620462}{"status":"unpause","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620466}{"status":"die","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620469}` diff --git a/vendor/github.com/samalba/dockerclient/interface.go b/vendor/github.com/samalba/dockerclient/interface.go new file mode 100644 index 0000000000..0638e4b906 --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/interface.go @@ -0,0 +1,59 @@ +package dockerclient + +import ( + "io" +) + +type Callback func(*Event, chan error, ...interface{}) + +type StatCallback func(string, *Stats, chan error, ...interface{}) + +type Client interface { + Info() (*Info, error) + ListContainers(all, size bool, filters string) ([]Container, error) + InspectContainer(id string) (*ContainerInfo, error) + InspectImage(id string) (*ImageInfo, error) + CreateContainer(config *ContainerConfig, name string, authConfig *AuthConfig) (string, error) + ContainerLogs(id string, options *LogOptions) (io.ReadCloser, error) + ContainerChanges(id string) ([]*ContainerChanges, error) + ExecCreate(config *ExecConfig) (string, error) + ExecStart(id string, config *ExecConfig) error + ExecResize(id string, width, height int) error + StartContainer(id string, config *HostConfig) error + AttachContainer(id string, options *AttachOptions) (io.ReadCloser, error) + StopContainer(id string, timeout int) error + RestartContainer(id string, timeout int) error + KillContainer(id, signal string) error + Wait(id string) <-chan WaitResult + // MonitorEvents takes options and an optional stop channel, and returns + // an EventOrError channel. If an error is ever sent, then no more + // events will be sent. If a stop channel is provided, events will stop + // being monitored after the stop channel is closed. + MonitorEvents(options *MonitorEventsOptions, stopChan <-chan struct{}) (<-chan EventOrError, error) + StartMonitorEvents(cb Callback, ec chan error, args ...interface{}) + StopAllMonitorEvents() + StartMonitorStats(id string, cb StatCallback, ec chan error, args ...interface{}) + StopAllMonitorStats() + TagImage(nameOrID string, repo string, tag string, force bool) error + Version() (*Version, error) + PullImage(name string, auth *AuthConfig) error + PushImage(name string, tag string, auth *AuthConfig) error + LoadImage(reader io.Reader) error + RemoveContainer(id string, force, volumes bool) error + ListImages(all bool) ([]*Image, error) + RemoveImage(name string, force bool) ([]*ImageDelete, error) + PauseContainer(name string) error + UnpauseContainer(name string) error + RenameContainer(oldName string, newName string) error + ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error) + BuildImage(image *BuildImage) (io.ReadCloser, error) + ListVolumes() ([]*Volume, error) + RemoveVolume(name string) error + CreateVolume(request *VolumeCreateRequest) (*Volume, error) + ListNetworks(filters string) ([]*NetworkResource, error) + InspectNetwork(id string) (*NetworkResource, error) + CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error) + ConnectNetwork(id, container string) error + DisconnectNetwork(id, container string) error + RemoveNetwork(id string) error +} diff --git a/vendor/github.com/samalba/dockerclient/types.go b/vendor/github.com/samalba/dockerclient/types.go new file mode 100644 index 0000000000..65cf93e2db --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/types.go @@ -0,0 +1,554 @@ +package dockerclient + +import ( + "fmt" + "io" + "time" + + "github.com/docker/go-units" +) + +type ContainerConfig struct { + Hostname string + Domainname string + User string + AttachStdin bool + AttachStdout bool + AttachStderr bool + ExposedPorts map[string]struct{} + Tty bool + OpenStdin bool + StdinOnce bool + Env []string + Cmd []string + Image string + Volumes map[string]struct{} + WorkingDir string + Entrypoint []string + NetworkDisabled bool + MacAddress string + OnBuild []string + Labels map[string]string + StopSignal string + + // FIXME: VolumeDriver have been removed since docker 1.9 + VolumeDriver string + + // FIXME: The following fields have been removed since API v1.18 + Memory int64 + MemorySwap int64 + CpuShares int64 + Cpuset string + PortSpecs []string + + // This is used only by the create command + HostConfig HostConfig +} + +type HostConfig struct { + Binds []string + ContainerIDFile string + LxcConf []map[string]string + Memory int64 + MemoryReservation int64 + MemorySwap int64 + KernelMemory int64 + CpuShares int64 + CpuPeriod int64 + CpusetCpus string + CpusetMems string + CpuQuota int64 + BlkioWeight int64 + OomKillDisable bool + MemorySwappiness int64 + Privileged bool + PortBindings map[string][]PortBinding + Links []string + PublishAllPorts bool + Dns []string + DNSOptions []string + DnsSearch []string + ExtraHosts []string + VolumesFrom []string + Devices []DeviceMapping + NetworkMode string + IpcMode string + PidMode string + UTSMode string + CapAdd []string + CapDrop []string + GroupAdd []string + RestartPolicy RestartPolicy + SecurityOpt []string + ReadonlyRootfs bool + Ulimits []Ulimit + LogConfig LogConfig + CgroupParent string + ConsoleSize [2]int + VolumeDriver string +} + +type DeviceMapping struct { + PathOnHost string `json:"PathOnHost"` + PathInContainer string `json:"PathInContainer"` + CgroupPermissions string `json:"CgroupPermissions"` +} + +type ExecConfig struct { + AttachStdin bool + AttachStdout bool + AttachStderr bool + Tty bool + Cmd []string + Container string + Detach bool +} + +type LogOptions struct { + Follow bool + Stdout bool + Stderr bool + Timestamps bool + Tail int64 +} + +type AttachOptions struct { + Logs bool + Stream bool + Stdin bool + Stdout bool + Stderr bool +} + +type MonitorEventsFilters struct { + Event string `json:",omitempty"` + Image string `json:",omitempty"` + Container string `json:",omitempty"` +} + +type MonitorEventsOptions struct { + Since int + Until int + Filters *MonitorEventsFilters `json:",omitempty"` +} + +type RestartPolicy struct { + Name string + MaximumRetryCount int64 +} + +type PortBinding struct { + HostIp string + HostPort string +} + +type State struct { + Running bool + Paused bool + Restarting bool + OOMKilled bool + Dead bool + Pid int + ExitCode int + Error string // contains last known error when starting the container + StartedAt time.Time + FinishedAt time.Time + Ghost bool +} + +// String returns a human-readable description of the state +// Stoken from docker/docker/daemon/state.go +func (s *State) String() string { + if s.Running { + if s.Paused { + return fmt.Sprintf("Up %s (Paused)", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt))) + } + if s.Restarting { + return fmt.Sprintf("Restarting (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt))) + } + + return fmt.Sprintf("Up %s", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt))) + } + + if s.Dead { + return "Dead" + } + + if s.FinishedAt.IsZero() { + return "" + } + + return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt))) +} + +// StateString returns a single string to describe state +// Stoken from docker/docker/daemon/state.go +func (s *State) StateString() string { + if s.Running { + if s.Paused { + return "paused" + } + if s.Restarting { + return "restarting" + } + return "running" + } + + if s.Dead { + return "dead" + } + + return "exited" +} + +type ImageInfo struct { + Architecture string + Author string + Comment string + Config *ContainerConfig + Container string + ContainerConfig *ContainerConfig + Created time.Time + DockerVersion string + Id string + Os string + Parent string + Size int64 + VirtualSize int64 +} + +type ContainerInfo struct { + Id string + Created string + Path string + Name string + Args []string + ExecIDs []string + Config *ContainerConfig + State *State + Image string + NetworkSettings struct { + IPAddress string `json:"IpAddress"` + IPPrefixLen int `json:"IpPrefixLen"` + Gateway string + Bridge string + Ports map[string][]PortBinding + } + SysInitPath string + ResolvConfPath string + Volumes map[string]string + HostConfig *HostConfig +} + +type ContainerChanges struct { + Path string + Kind int +} + +type Port struct { + IP string + PrivatePort int + PublicPort int + Type string +} + +type EndpointSettings struct { + EndpointID string + Gateway string + IPAddress string + IPPrefixLen int + IPv6Gateway string + GlobalIPv6Address string + GlobalIPv6PrefixLen int + MacAddress string +} + +type Container struct { + Id string + Names []string + Image string + Command string + Created int64 + Status string + Ports []Port + SizeRw int64 + SizeRootFs int64 + Labels map[string]string + NetworkSettings struct { + Networks map[string]EndpointSettings + } +} + +type Event struct { + Id string + Status string + From string + Time int64 +} + +type Version struct { + ApiVersion string + Arch string + GitCommit string + GoVersion string + KernelVersion string + Os string + Version string +} + +type RespContainersCreate struct { + Id string + Warnings []string +} + +type Image struct { + Created int64 + Id string + Labels map[string]string + ParentId string + RepoDigests []string + RepoTags []string + Size int64 + VirtualSize int64 +} + +// Info is the struct returned by /info +// The API is currently in flux, so Debug, MemoryLimit, SwapLimit, and +// IPv4Forwarding are interfaces because in docker 1.6.1 they are 0 or 1 but in +// master they are bools. +type Info struct { + ID string + Containers int64 + Driver string + DriverStatus [][]string + ExecutionDriver string + Images int64 + KernelVersion string + OperatingSystem string + NCPU int64 + MemTotal int64 + Name string + Labels []string + Debug interface{} + NFd int64 + NGoroutines int64 + SystemTime string + NEventsListener int64 + InitPath string + InitSha1 string + IndexServerAddress string + MemoryLimit interface{} + SwapLimit interface{} + IPv4Forwarding interface{} + BridgeNfIptables bool + BridgeNfIp6tables bool + DockerRootDir string + HttpProxy string + HttpsProxy string + NoProxy string +} + +type ImageDelete struct { + Deleted string + Untagged string +} + +type EventOrError struct { + Event + Error error +} + +type WaitResult struct { + ExitCode int + Error error +} + +type decodingResult struct { + result interface{} + err error +} + +// The following are types for the API stats endpoint +type ThrottlingData struct { + // Number of periods with throttling active + Periods uint64 `json:"periods"` + // Number of periods when the container hit its throttling limit. + ThrottledPeriods uint64 `json:"throttled_periods"` + // Aggregate time the container was throttled for in nanoseconds. + ThrottledTime uint64 `json:"throttled_time"` +} + +type CpuUsage struct { + // Total CPU time consumed. + // Units: nanoseconds. + TotalUsage uint64 `json:"total_usage"` + // Total CPU time consumed per core. + // Units: nanoseconds. + PercpuUsage []uint64 `json:"percpu_usage"` + // Time spent by tasks of the cgroup in kernel mode. + // Units: nanoseconds. + UsageInKernelmode uint64 `json:"usage_in_kernelmode"` + // Time spent by tasks of the cgroup in user mode. + // Units: nanoseconds. + UsageInUsermode uint64 `json:"usage_in_usermode"` +} + +type CpuStats struct { + CpuUsage CpuUsage `json:"cpu_usage"` + SystemUsage uint64 `json:"system_cpu_usage"` + ThrottlingData ThrottlingData `json:"throttling_data,omitempty"` +} + +type NetworkStats struct { + RxBytes uint64 `json:"rx_bytes"` + RxPackets uint64 `json:"rx_packets"` + RxErrors uint64 `json:"rx_errors"` + RxDropped uint64 `json:"rx_dropped"` + TxBytes uint64 `json:"tx_bytes"` + TxPackets uint64 `json:"tx_packets"` + TxErrors uint64 `json:"tx_errors"` + TxDropped uint64 `json:"tx_dropped"` +} + +type MemoryStats struct { + Usage uint64 `json:"usage"` + MaxUsage uint64 `json:"max_usage"` + Stats map[string]uint64 `json:"stats"` + Failcnt uint64 `json:"failcnt"` + Limit uint64 `json:"limit"` +} + +type BlkioStatEntry struct { + Major uint64 `json:"major"` + Minor uint64 `json:"minor"` + Op string `json:"op"` + Value uint64 `json:"value"` +} + +type BlkioStats struct { + // number of bytes tranferred to and from the block device + IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"` + IoServicedRecursive []BlkioStatEntry `json:"io_serviced_recursive"` + IoQueuedRecursive []BlkioStatEntry `json:"io_queue_recursive"` + IoServiceTimeRecursive []BlkioStatEntry `json:"io_service_time_recursive"` + IoWaitTimeRecursive []BlkioStatEntry `json:"io_wait_time_recursive"` + IoMergedRecursive []BlkioStatEntry `json:"io_merged_recursive"` + IoTimeRecursive []BlkioStatEntry `json:"io_time_recursive"` + SectorsRecursive []BlkioStatEntry `json:"sectors_recursive"` +} + +type Stats struct { + Read time.Time `json:"read"` + NetworkStats NetworkStats `json:"network,omitempty"` + CpuStats CpuStats `json:"cpu_stats,omitempty"` + MemoryStats MemoryStats `json:"memory_stats,omitempty"` + BlkioStats BlkioStats `json:"blkio_stats,omitempty"` +} + +type Ulimit struct { + Name string `json:"name"` + Soft uint64 `json:"soft"` + Hard uint64 `json:"hard"` +} + +type LogConfig struct { + Type string `json:"type"` + Config map[string]string `json:"config"` +} + +type BuildImage struct { + Config *ConfigFile + DockerfileName string + Context io.Reader + RemoteURL string + RepoName string + SuppressOutput bool + NoCache bool + Remove bool + ForceRemove bool + Pull bool + Memory int64 + MemorySwap int64 + CpuShares int64 + CpuPeriod int64 + CpuQuota int64 + CpuSetCpus string + CpuSetMems string + CgroupParent string + BuildArgs map[string]string +} + +type Volume struct { + Name string // Name is the name of the volume + Driver string // Driver is the Driver name used to create the volume + Mountpoint string // Mountpoint is the location on disk of the volume +} + +type VolumesListResponse struct { + Volumes []*Volume // Volumes is the list of volumes being returned +} + +type VolumeCreateRequest struct { + Name string // Name is the requested name of the volume + Driver string // Driver is the name of the driver that should be used to create the volume + DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume. +} + +// IPAM represents IP Address Management +type IPAM struct { + Driver string + Config []IPAMConfig +} + +// IPAMConfig represents IPAM configurations +type IPAMConfig struct { + Subnet string `json:",omitempty"` + IPRange string `json:",omitempty"` + Gateway string `json:",omitempty"` + AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"` +} + +// NetworkResource is the body of the "get network" http response message +type NetworkResource struct { + Name string + ID string `json:"Id"` + Scope string + Driver string + IPAM IPAM + Containers map[string]EndpointResource + Options map[string]string +} + +// EndpointResource contains network resources allocated and used for a container in a network +type EndpointResource struct { + Name string + EndpointID string + MacAddress string + IPv4Address string + IPv6Address string +} + +// NetworkCreate is the expected body of the "create network" http request message +type NetworkCreate struct { + Name string + CheckDuplicate bool + Driver string + IPAM IPAM + Options map[string]string +} + +// NetworkCreateResponse is the response message sent by the server for network create call +type NetworkCreateResponse struct { + ID string `json:"Id"` + Warning string +} + +// NetworkConnect represents the data to be used to connect a container to the network +type NetworkConnect struct { + Container string +} + +// NetworkDisconnect represents the data to be used to disconnect a container from the network +type NetworkDisconnect struct { + Container string +} diff --git a/vendor/github.com/samalba/dockerclient/utils.go b/vendor/github.com/samalba/dockerclient/utils.go new file mode 100644 index 0000000000..806f1b3e6a --- /dev/null +++ b/vendor/github.com/samalba/dockerclient/utils.go @@ -0,0 +1,33 @@ +package dockerclient + +import ( + "crypto/tls" + "net" + "net/http" + "net/url" + "time" +) + +func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client { + httpTransport := &http.Transport{ + TLSClientConfig: tlsConfig, + } + + switch u.Scheme { + default: + httpTransport.Dial = func(proto, addr string) (net.Conn, error) { + return net.DialTimeout(proto, addr, timeout) + } + case "unix": + socketPath := u.Path + unixDial := func(proto, addr string) (net.Conn, error) { + return net.DialTimeout("unix", socketPath, timeout) + } + httpTransport.Dial = unixDial + // Override the main URL object so the HTTP lib won't complain + u.Scheme = "http" + u.Host = "unix.sock" + u.Path = "" + } + return &http.Client{Transport: httpTransport} +} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore b/vendor/github.com/sirupsen/logrus/.gitignore similarity index 100% rename from Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore rename to vendor/github.com/sirupsen/logrus/.gitignore diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml new file mode 100644 index 0000000000..a23296a53b --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/.travis.yml @@ -0,0 +1,15 @@ +language: go +go: + - 1.6.x + - 1.7.x + - 1.8.x + - tip +env: + - GOMAXPROCS=4 GORACE=halt_on_error=1 +install: + - go get github.com/stretchr/testify/assert + - go get gopkg.in/gemnasium/logrus-airbrake-hook.v2 + - go get golang.org/x/sys/unix + - go get golang.org/x/sys/windows +script: + - go test -race -v ./... diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md new file mode 100644 index 0000000000..cc58f6451f --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -0,0 +1,118 @@ +# 1.0.4 + +* Fix race when adding hooks (#612) +* Fix terminal check in AppEngine (#635) + +# 1.0.3 + +* Replace example files with testable examples + +# 1.0.2 + +* bug: quote non-string values in text formatter (#583) +* Make (*Logger) SetLevel a public method + +# 1.0.1 + +* bug: fix escaping in text formatter (#575) + +# 1.0.0 + +* Officially changed name to lower-case +* bug: colors on Windows 10 (#541) +* bug: fix race in accessing level (#512) + +# 0.11.5 + +* feature: add writer and writerlevel to entry (#372) + +# 0.11.4 + +* bug: fix undefined variable on solaris (#493) + +# 0.11.3 + +* formatter: configure quoting of empty values (#484) +* formatter: configure quoting character (default is `"`) (#484) +* bug: fix not importing io correctly in non-linux environments (#481) + +# 0.11.2 + +* bug: fix windows terminal detection (#476) + +# 0.11.1 + +* bug: fix tty detection with custom out (#471) + +# 0.11.0 + +* performance: Use bufferpool to allocate (#370) +* terminal: terminal detection for app-engine (#343) +* feature: exit handler (#375) + +# 0.10.0 + +* feature: Add a test hook (#180) +* feature: `ParseLevel` is now case-insensitive (#326) +* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) +* performance: avoid re-allocations on `WithFields` (#335) + +# 0.9.0 + +* logrus/text_formatter: don't emit empty msg +* logrus/hooks/airbrake: move out of main repository +* logrus/hooks/sentry: move out of main repository +* logrus/hooks/papertrail: move out of main repository +* logrus/hooks/bugsnag: move out of main repository +* logrus/core: run tests with `-race` +* logrus/core: detect TTY based on `stderr` +* logrus/core: support `WithError` on logger +* logrus/core: Solaris support + +# 0.8.7 + +* logrus/core: fix possible race (#216) +* logrus/doc: small typo fixes and doc improvements + + +# 0.8.6 + +* hooks/raven: allow passing an initialized client + +# 0.8.5 + +* logrus/core: revert #208 + +# 0.8.4 + +* formatter/text: fix data race (#218) + +# 0.8.3 + +* logrus/core: fix entry log level (#208) +* logrus/core: improve performance of text formatter by 40% +* logrus/core: expose `LevelHooks` type +* logrus/core: add support for DragonflyBSD and NetBSD +* formatter/text: print structs more verbosely + +# 0.8.2 + +* logrus: fix more Fatal family functions + +# 0.8.1 + +* logrus: fix not exiting on `Fatalf` and `Fatalln` + +# 0.8.0 + +* logrus: defaults to stderr instead of stdout +* hooks/sentry: add special field for `*http.Request` +* formatter/text: ignore Windows for colors + +# 0.7.3 + +* formatter/\*: allow configuration of timestamp layout + +# 0.7.2 + +* formatter/text: Add configuration option for time format (#158) diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE similarity index 100% rename from Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE rename to vendor/github.com/sirupsen/logrus/LICENSE diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md new file mode 100644 index 0000000000..08584b5fc2 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -0,0 +1,509 @@ +# Logrus :walrus: [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) + +Logrus is a structured logger for Go (golang), completely API compatible with +the standard library logger. + +**Seeing weird case-sensitive problems?** It's in the past been possible to +import Logrus as both upper- and lower-case. Due to the Go package environment, +this caused issues in the community and we needed a standard. Some environments +experienced problems with the upper-case variant, so the lower-case was decided. +Everything using `logrus` will need to use the lower-case: +`github.com/sirupsen/logrus`. Any package that isn't, should be changed. + +To fix Glide, see [these +comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). +For an in-depth explanation of the casing issue, see [this +comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). + +**Are you interested in assisting in maintaining Logrus?** Currently I have a +lot of obligations, and I am unable to provide Logrus with the maintainership it +needs. If you'd like to help, please reach out to me at `simon at author's +username dot com`. + +Nicely color-coded in development (when a TTY is attached, otherwise just +plain text): + +![Colored](http://i.imgur.com/PY7qMwd.png) + +With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash +or Splunk: + +```json +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the +ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} + +{"level":"warning","msg":"The group's number increased tremendously!", +"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"A giant walrus appears!", +"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", +"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} + +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, +"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +``` + +With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not +attached, the output is compatible with the +[logfmt](http://godoc.org/github.com/kr/logfmt) format: + +```text +time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 +time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 +time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true +time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 +time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 +time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true +exit status 1 +``` + +#### Case-sensitivity + +The organization's name was changed to lower-case--and this will not be changed +back. If you are getting import conflicts due to case sensitivity, please use +the lower-case import: `github.com/sirupsen/logrus`. + +#### Example + +The simplest way to use Logrus is simply the package-level exported logger: + +```go +package main + +import ( + log "github.com/sirupsen/logrus" +) + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + }).Info("A walrus appears") +} +``` + +Note that it's completely api-compatible with the stdlib logger, so you can +replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"` +and you'll now have the flexibility of Logrus. You can customize it all you +want: + +```go +package main + +import ( + "os" + log "github.com/sirupsen/logrus" +) + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&log.JSONFormatter{}) + + // Output to stdout instead of the default stderr + // Can be any io.Writer, see below for File example + log.SetOutput(os.Stdout) + + // Only log the warning severity or above. + log.SetLevel(log.WarnLevel) +} + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(log.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(log.Fields{ + "omg": true, + "number": 100, + }).Fatal("The ice breaks!") + + // A common pattern is to re-use fields between logging statements by re-using + // the logrus.Entry returned from WithFields() + contextLogger := log.WithFields(log.Fields{ + "common": "this is a common field", + "other": "I also should be logged always", + }) + + contextLogger.Info("I'll be logged with common and other field") + contextLogger.Info("Me too") +} +``` + +For more advanced usage such as logging to multiple locations from the same +application, you can also create an instance of the `logrus` Logger: + +```go +package main + +import ( + "os" + "github.com/sirupsen/logrus" +) + +// Create a new instance of the logger. You can have any number of instances. +var log = logrus.New() + +func main() { + // The API for setting attributes is a little different than the package level + // exported logger. See Godoc. + log.Out = os.Stdout + + // You could set this to any `io.Writer` such as a file + // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) + // if err == nil { + // log.Out = file + // } else { + // log.Info("Failed to log to file, using default stderr") + // } + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") +} +``` + +#### Fields + +Logrus encourages careful, structured logging through logging fields instead of +long, unparseable error messages. For example, instead of: `log.Fatalf("Failed +to send event %s to topic %s with key %d")`, you should log the much more +discoverable: + +```go +log.WithFields(log.Fields{ + "event": event, + "topic": topic, + "key": key, +}).Fatal("Failed to send event") +``` + +We've found this API forces you to think about logging in a way that produces +much more useful logging messages. We've been in countless situations where just +a single added field to a log statement that was already there would've saved us +hours. The `WithFields` call is optional. + +In general, with Logrus using any of the `printf`-family functions should be +seen as a hint you should add a field, however, you can still use the +`printf`-family functions with Logrus. + +#### Default Fields + +Often it's helpful to have fields _always_ attached to log statements in an +application or parts of one. For example, you may want to always log the +`request_id` and `user_ip` in the context of a request. Instead of writing +`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on +every line, you can create a `logrus.Entry` to pass around instead: + +```go +requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}) +requestLogger.Info("something happened on that request") # will log request_id and user_ip +requestLogger.Warn("something not great happened") +``` + +#### Hooks + +You can add hooks for logging levels. For example to send errors to an exception +tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to +multiple places simultaneously, e.g. syslog. + +Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in +`init`: + +```go +import ( + log "github.com/sirupsen/logrus" + "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake" + logrus_syslog "github.com/sirupsen/logrus/hooks/syslog" + "log/syslog" +) + +func init() { + + // Use the Airbrake hook to report errors that have Error severity or above to + // an exception tracker. You can create custom hooks, see the Hooks section. + log.AddHook(airbrake.NewHook(123, "xyz", "production")) + + hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") + if err != nil { + log.Error("Unable to connect to local syslog daemon") + } else { + log.AddHook(hook) + } +} +``` +Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). + +| Hook | Description | +| ----- | ----------- | +| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | +| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. | +| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) | +| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) | +| [AzureTableHook](https://github.com/kpfaulkner/azuretablehook/) | Hook for logging to Azure Table Storage| +| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | +| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic | +| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) | +| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch| +| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/) +| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | +| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) | +| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) | +| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | +| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | +| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb | +| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) | +| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | +| [KafkaLogrus](https://github.com/tracer0tong/kafkalogrus) | Hook for logging to Kafka | +| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | +| [Logbeat](https://github.com/macandmia/logbeat) | Hook for logging to [Opbeat](https://opbeat.com/) | +| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) | +| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) | +| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) | +| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | +| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) | +| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | +| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) | +| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | +| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) | +| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit | +| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. | +| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) | +| [Promrus](https://github.com/weaveworks/promrus) | Expose number of log messages as [Prometheus](https://prometheus.io/) metrics | +| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) | +| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | +| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) | +| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | +| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)| +| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. | +| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | +| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) | +| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)| +| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | +| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. | +| [Telegram](https://github.com/rossmcdonald/telegram_hook) | Hook for logging errors to [Telegram](https://telegram.org/) | +| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) | +| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) | +| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash | +| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) | + +#### Level logging + +Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. + +```go +log.Debug("Useful debugging information.") +log.Info("Something noteworthy happened!") +log.Warn("You should probably take a look at this.") +log.Error("Something failed but I'm not quitting.") +// Calls os.Exit(1) after logging +log.Fatal("Bye.") +// Calls panic() after logging +log.Panic("I'm bailing.") +``` + +You can set the logging level on a `Logger`, then it will only log entries with +that severity or anything above it: + +```go +// Will log anything that is info or above (warn, error, fatal, panic). Default. +log.SetLevel(log.InfoLevel) +``` + +It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose +environment if your application has that. + +#### Entries + +Besides the fields added with `WithField` or `WithFields` some fields are +automatically added to all logging events: + +1. `time`. The timestamp when the entry was created. +2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after + the `AddFields` call. E.g. `Failed to send event.` +3. `level`. The logging level. E.g. `info`. + +#### Environments + +Logrus has no notion of environment. + +If you wish for hooks and formatters to only be used in specific environments, +you should handle that yourself. For example, if your application has a global +variable `Environment`, which is a string representation of the environment you +could do: + +```go +import ( + log "github.com/sirupsen/logrus" +) + +init() { + // do something here to set environment depending on an environment variable + // or command-line flag + if Environment == "production" { + log.SetFormatter(&log.JSONFormatter{}) + } else { + // The TextFormatter is default, you don't actually have to do this. + log.SetFormatter(&log.TextFormatter{}) + } +} +``` + +This configuration is how `logrus` was intended to be used, but JSON in +production is mostly only useful if you do log aggregation with tools like +Splunk or Logstash. + +#### Formatters + +The built-in logging formatters are: + +* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise + without colors. + * *Note:* to force colored output when there is no TTY, set the `ForceColors` + field to `true`. To force no colored output even if there is a TTY set the + `DisableColors` field to `true`. For Windows, see + [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). + * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). +* `logrus.JSONFormatter`. Logs fields as JSON. + * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). + +Third party logging formatters: + +* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine. +* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events. +* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. +* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. + +You can define your formatter by implementing the `Formatter` interface, +requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a +`Fields` type (`map[string]interface{}`) with all your fields as well as the +default ones (see Entries section above): + +```go +type MyJSONFormatter struct { +} + +log.SetFormatter(new(MyJSONFormatter)) + +func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { + // Note this doesn't include Time, Level and Message which are available on + // the Entry. Consult `godoc` on information about those fields or read the + // source of the official loggers. + serialized, err := json.Marshal(entry.Data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} +``` + +#### Logger as an `io.Writer` + +Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. + +```go +w := logger.Writer() +defer w.Close() + +srv := http.Server{ + // create a stdlib log.Logger that writes to + // logrus.Logger. + ErrorLog: log.New(w, "", 0), +} +``` + +Each line written to that writer will be printed the usual way, using formatters +and hooks. The level for those entries is `info`. + +This means that we can override the standard library logger easily: + +```go +logger := logrus.New() +logger.Formatter = &logrus.JSONFormatter{} + +// Use logrus for standard log output +// Note that `log` here references stdlib's log +// Not logrus imported under the name `log`. +log.SetOutput(logger.Writer()) +``` + +#### Rotation + +Log rotation is not provided with Logrus. Log rotation should be done by an +external program (like `logrotate(8)`) that can compress and delete old log +entries. It should not be a feature of the application-level logger. + +#### Tools + +| Tool | Description | +| ---- | ----------- | +|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.| +|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | + +#### Testing + +Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: + +* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook +* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): + +```go +import( + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestSomething(t*testing.T){ + logger, hook := test.NewNullLogger() + logger.Error("Helloerror") + + assert.Equal(t, 1, len(hook.Entries)) + assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level) + assert.Equal(t, "Helloerror", hook.LastEntry().Message) + + hook.Reset() + assert.Nil(t, hook.LastEntry()) +} +``` + +#### Fatal handlers + +Logrus can register one or more functions that will be called when any `fatal` +level message is logged. The registered handlers will be executed before +logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need +to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. + +``` +... +handler := func() { + // gracefully shutdown something... +} +logrus.RegisterExitHandler(handler) +... +``` + +#### Thread safety + +By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs. +If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking. + +Situation when locking is not needed includes: + +* You have no hooks registered, or hooks calling is already thread-safe. + +* Writing to logger.Out is already thread-safe, for example: + + 1) logger.Out is protected by locks. + + 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing) + + (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go new file mode 100644 index 0000000000..8af90637a9 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/alt_exit.go @@ -0,0 +1,64 @@ +package logrus + +// The following code was sourced and modified from the +// https://github.com/tebeka/atexit package governed by the following license: +// +// Copyright (c) 2012 Miki Tebeka . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import ( + "fmt" + "os" +) + +var handlers = []func(){} + +func runHandler(handler func()) { + defer func() { + if err := recover(); err != nil { + fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) + } + }() + + handler() +} + +func runHandlers() { + for _, handler := range handlers { + runHandler(handler) + } +} + +// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) +func Exit(code int) { + runHandlers() + os.Exit(code) +} + +// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke +// all handlers. The handlers will also be invoked when any Fatal log entry is +// made. +// +// This method is useful when a caller wishes to use logrus to log a fatal +// message but also needs to gracefully shutdown. An example usecase could be +// closing database connections, or sending a alert that the application is +// closing. +func RegisterExitHandler(handler func()) { + handlers = append(handlers, handler) +} diff --git a/vendor/github.com/sirupsen/logrus/appveyor.yml b/vendor/github.com/sirupsen/logrus/appveyor.yml new file mode 100644 index 0000000000..96c2ce15f8 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/appveyor.yml @@ -0,0 +1,14 @@ +version: "{build}" +platform: x64 +clone_folder: c:\gopath\src\github.com\sirupsen\logrus +environment: + GOPATH: c:\gopath +branches: + only: + - master +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version +build_script: + - go get -t + - go test diff --git a/vendor/github.com/sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go new file mode 100644 index 0000000000..da67aba06d --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/doc.go @@ -0,0 +1,26 @@ +/* +Package logrus is a structured logger for Go, completely API compatible with the standard library logger. + + +The simplest way to use Logrus is simply the package-level exported logger: + + package main + + import ( + log "github.com/sirupsen/logrus" + ) + + func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "number": 1, + "size": 10, + }).Info("A walrus appears") + } + +Output: + time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 + +For a full guide visit https://github.com/sirupsen/logrus +*/ +package logrus diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go new file mode 100644 index 0000000000..1fad45e082 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -0,0 +1,279 @@ +package logrus + +import ( + "bytes" + "fmt" + "os" + "sync" + "time" +) + +var bufferPool *sync.Pool + +func init() { + bufferPool = &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + } +} + +// Defines the key when adding errors using WithError. +var ErrorKey = "error" + +// An entry is the final or intermediate Logrus logging entry. It contains all +// the fields passed with WithField{,s}. It's finally logged when Debug, Info, +// Warn, Error, Fatal or Panic is called on it. These objects can be reused and +// passed around as much as you wish to avoid field duplication. +type Entry struct { + Logger *Logger + + // Contains all the fields set by the user. + Data Fields + + // Time at which the log entry was created + Time time.Time + + // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic + // This field will be set on entry firing and the value will be equal to the one in Logger struct field. + Level Level + + // Message passed to Debug, Info, Warn, Error, Fatal or Panic + Message string + + // When formatter is called in entry.log(), an Buffer may be set to entry + Buffer *bytes.Buffer +} + +func NewEntry(logger *Logger) *Entry { + return &Entry{ + Logger: logger, + // Default is three fields, give a little extra room + Data: make(Fields, 5), + } +} + +// Returns the string representation from the reader and ultimately the +// formatter. +func (entry *Entry) String() (string, error) { + serialized, err := entry.Logger.Formatter.Format(entry) + if err != nil { + return "", err + } + str := string(serialized) + return str, nil +} + +// Add an error as single field (using the key defined in ErrorKey) to the Entry. +func (entry *Entry) WithError(err error) *Entry { + return entry.WithField(ErrorKey, err) +} + +// Add a single field to the Entry. +func (entry *Entry) WithField(key string, value interface{}) *Entry { + return entry.WithFields(Fields{key: value}) +} + +// Add a map of fields to the Entry. +func (entry *Entry) WithFields(fields Fields) *Entry { + data := make(Fields, len(entry.Data)+len(fields)) + for k, v := range entry.Data { + data[k] = v + } + for k, v := range fields { + data[k] = v + } + return &Entry{Logger: entry.Logger, Data: data} +} + +// This function is not declared with a pointer value because otherwise +// race conditions will occur when using multiple goroutines +func (entry Entry) log(level Level, msg string) { + var buffer *bytes.Buffer + entry.Time = time.Now() + entry.Level = level + entry.Message = msg + + entry.Logger.mu.Lock() + err := entry.Logger.Hooks.Fire(level, &entry) + entry.Logger.mu.Unlock() + if err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + entry.Logger.mu.Unlock() + } + buffer = bufferPool.Get().(*bytes.Buffer) + buffer.Reset() + defer bufferPool.Put(buffer) + entry.Buffer = buffer + serialized, err := entry.Logger.Formatter.Format(&entry) + entry.Buffer = nil + if err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + entry.Logger.mu.Unlock() + } else { + entry.Logger.mu.Lock() + _, err = entry.Logger.Out.Write(serialized) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } + entry.Logger.mu.Unlock() + } + + // To avoid Entry#log() returning a value that only would make sense for + // panic() to use in Entry#Panic(), we avoid the allocation by checking + // directly here. + if level <= PanicLevel { + panic(&entry) + } +} + +func (entry *Entry) Debug(args ...interface{}) { + if entry.Logger.level() >= DebugLevel { + entry.log(DebugLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Print(args ...interface{}) { + entry.Info(args...) +} + +func (entry *Entry) Info(args ...interface{}) { + if entry.Logger.level() >= InfoLevel { + entry.log(InfoLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warn(args ...interface{}) { + if entry.Logger.level() >= WarnLevel { + entry.log(WarnLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warning(args ...interface{}) { + entry.Warn(args...) +} + +func (entry *Entry) Error(args ...interface{}) { + if entry.Logger.level() >= ErrorLevel { + entry.log(ErrorLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Fatal(args ...interface{}) { + if entry.Logger.level() >= FatalLevel { + entry.log(FatalLevel, fmt.Sprint(args...)) + } + Exit(1) +} + +func (entry *Entry) Panic(args ...interface{}) { + if entry.Logger.level() >= PanicLevel { + entry.log(PanicLevel, fmt.Sprint(args...)) + } + panic(fmt.Sprint(args...)) +} + +// Entry Printf family functions + +func (entry *Entry) Debugf(format string, args ...interface{}) { + if entry.Logger.level() >= DebugLevel { + entry.Debug(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Infof(format string, args ...interface{}) { + if entry.Logger.level() >= InfoLevel { + entry.Info(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Printf(format string, args ...interface{}) { + entry.Infof(format, args...) +} + +func (entry *Entry) Warnf(format string, args ...interface{}) { + if entry.Logger.level() >= WarnLevel { + entry.Warn(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Warningf(format string, args ...interface{}) { + entry.Warnf(format, args...) +} + +func (entry *Entry) Errorf(format string, args ...interface{}) { + if entry.Logger.level() >= ErrorLevel { + entry.Error(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Fatalf(format string, args ...interface{}) { + if entry.Logger.level() >= FatalLevel { + entry.Fatal(fmt.Sprintf(format, args...)) + } + Exit(1) +} + +func (entry *Entry) Panicf(format string, args ...interface{}) { + if entry.Logger.level() >= PanicLevel { + entry.Panic(fmt.Sprintf(format, args...)) + } +} + +// Entry Println family functions + +func (entry *Entry) Debugln(args ...interface{}) { + if entry.Logger.level() >= DebugLevel { + entry.Debug(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Infoln(args ...interface{}) { + if entry.Logger.level() >= InfoLevel { + entry.Info(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Println(args ...interface{}) { + entry.Infoln(args...) +} + +func (entry *Entry) Warnln(args ...interface{}) { + if entry.Logger.level() >= WarnLevel { + entry.Warn(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Warningln(args ...interface{}) { + entry.Warnln(args...) +} + +func (entry *Entry) Errorln(args ...interface{}) { + if entry.Logger.level() >= ErrorLevel { + entry.Error(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Fatalln(args ...interface{}) { + if entry.Logger.level() >= FatalLevel { + entry.Fatal(entry.sprintlnn(args...)) + } + Exit(1) +} + +func (entry *Entry) Panicln(args ...interface{}) { + if entry.Logger.level() >= PanicLevel { + entry.Panic(entry.sprintlnn(args...)) + } +} + +// Sprintlnn => Sprint no newline. This is to get the behavior of how +// fmt.Sprintln where spaces are always added between operands, regardless of +// their type. Instead of vendoring the Sprintln implementation to spare a +// string allocation, we do the simplest thing. +func (entry *Entry) sprintlnn(args ...interface{}) string { + msg := fmt.Sprintln(args...) + return msg[:len(msg)-1] +} diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go similarity index 93% rename from Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go rename to vendor/github.com/sirupsen/logrus/exported.go index d087124481..013183edab 100644 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go +++ b/vendor/github.com/sirupsen/logrus/exported.go @@ -9,6 +9,10 @@ var ( std = New() ) +func StandardLogger() *Logger { + return std +} + // SetOutput sets the standard logger output. func SetOutput(out io.Writer) { std.mu.Lock() @@ -27,12 +31,14 @@ func SetFormatter(formatter Formatter) { func SetLevel(level Level) { std.mu.Lock() defer std.mu.Unlock() - std.Level = level + std.SetLevel(level) } // GetLevel returns the standard logger level. func GetLevel() Level { - return std.Level + std.mu.Lock() + defer std.mu.Unlock() + return std.level() } // AddHook adds a hook to the standard logger hooks. @@ -42,6 +48,11 @@ func AddHook(hook Hook) { std.Hooks.Add(hook) } +// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +func WithError(err error) *Entry { + return std.WithField(ErrorKey, err) +} + // WithField creates an entry from the standard logger and adds a field to // it. If you want multiple fields, use `WithFields`. // diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go similarity index 78% rename from Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go rename to vendor/github.com/sirupsen/logrus/formatter.go index 74c49a0e0e..b183ff5b1d 100644 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go +++ b/vendor/github.com/sirupsen/logrus/formatter.go @@ -1,5 +1,9 @@ package logrus +import "time" + +const defaultTimestampFormat = time.RFC3339 + // The Formatter interface is used to implement a custom Formatter. It takes an // `Entry`. It exposes all the fields, including the default ones: // @@ -26,19 +30,16 @@ type Formatter interface { // // It's not exported because it's still using Data in an opinionated way. It's to // avoid code duplication between the two default formatters. -func prefixFieldClashes(entry *Entry) { - _, ok := entry.Data["time"] - if ok { - entry.Data["fields.time"] = entry.Data["time"] +func prefixFieldClashes(data Fields) { + if t, ok := data["time"]; ok { + data["fields.time"] = t } - _, ok = entry.Data["msg"] - if ok { - entry.Data["fields.msg"] = entry.Data["msg"] + if m, ok := data["msg"]; ok { + data["fields.msg"] = m } - _, ok = entry.Data["level"] - if ok { - entry.Data["fields.level"] = entry.Data["level"] + if l, ok := data["level"]; ok { + data["fields.level"] = l } } diff --git a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go similarity index 87% rename from Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go rename to vendor/github.com/sirupsen/logrus/hooks.go index 0da2b3653f..3f151cdc39 100644 --- a/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go +++ b/vendor/github.com/sirupsen/logrus/hooks.go @@ -11,11 +11,11 @@ type Hook interface { } // Internal type for storing the hooks on a logger instance. -type levelHooks map[Level][]Hook +type LevelHooks map[Level][]Hook // Add a hook to an instance of logger. This is called with // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. -func (hooks levelHooks) Add(hook Hook) { +func (hooks LevelHooks) Add(hook Hook) { for _, level := range hook.Levels() { hooks[level] = append(hooks[level], hook) } @@ -23,7 +23,7 @@ func (hooks levelHooks) Add(hook Hook) { // Fire all the hooks for the passed level. Used by `entry.log` to fire // appropriate hooks for a log entry. -func (hooks levelHooks) Fire(level Level, entry *Entry) error { +func (hooks LevelHooks) Fire(level Level, entry *Entry) error { for _, hook := range hooks[level] { if err := hook.Fire(entry); err != nil { return err diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go new file mode 100644 index 0000000000..fb01c1b104 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/json_formatter.go @@ -0,0 +1,79 @@ +package logrus + +import ( + "encoding/json" + "fmt" +) + +type fieldKey string + +// FieldMap allows customization of the key names for default fields. +type FieldMap map[fieldKey]string + +// Default key names for the default fields +const ( + FieldKeyMsg = "msg" + FieldKeyLevel = "level" + FieldKeyTime = "time" +) + +func (f FieldMap) resolve(key fieldKey) string { + if k, ok := f[key]; ok { + return k + } + + return string(key) +} + +// JSONFormatter formats logs into parsable json +type JSONFormatter struct { + // TimestampFormat sets the format used for marshaling timestamps. + TimestampFormat string + + // DisableTimestamp allows disabling automatic timestamps in output + DisableTimestamp bool + + // FieldMap allows users to customize the names of keys for default fields. + // As an example: + // formatter := &JSONFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message", + // }, + // } + FieldMap FieldMap +} + +// Format renders a single log entry +func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { + data := make(Fields, len(entry.Data)+3) + for k, v := range entry.Data { + switch v := v.(type) { + case error: + // Otherwise errors are ignored by `encoding/json` + // https://github.com/sirupsen/logrus/issues/137 + data[k] = v.Error() + default: + data[k] = v + } + } + prefixFieldClashes(data) + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = defaultTimestampFormat + } + + if !f.DisableTimestamp { + data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) + } + data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message + data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() + + serialized, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go new file mode 100644 index 0000000000..fdaf8a6534 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -0,0 +1,323 @@ +package logrus + +import ( + "io" + "os" + "sync" + "sync/atomic" +) + +type Logger struct { + // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a + // file, or leave it default which is `os.Stderr`. You can also set this to + // something more adventorous, such as logging to Kafka. + Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging + // levels and log entries. For example, to send errors to an error tracking + // service, log to StatsD or dump the core on fatal errors. + Hooks LevelHooks + // All log entries pass through the formatter before logged to Out. The + // included formatters are `TextFormatter` and `JSONFormatter` for which + // TextFormatter is the default. In development (when a TTY is attached) it + // logs with colors, but to a file it wouldn't. You can easily implement your + // own that implements the `Formatter` interface, see the `README` or included + // formatters for examples. + Formatter Formatter + // The logging level the logger should log at. This is typically (and defaults + // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be + // logged. + Level Level + // Used to sync writing to the log. Locking is enabled by Default + mu MutexWrap + // Reusable empty entry + entryPool sync.Pool +} + +type MutexWrap struct { + lock sync.Mutex + disabled bool +} + +func (mw *MutexWrap) Lock() { + if !mw.disabled { + mw.lock.Lock() + } +} + +func (mw *MutexWrap) Unlock() { + if !mw.disabled { + mw.lock.Unlock() + } +} + +func (mw *MutexWrap) Disable() { + mw.disabled = true +} + +// Creates a new logger. Configuration should be set by changing `Formatter`, +// `Out` and `Hooks` directly on the default logger instance. You can also just +// instantiate your own: +// +// var log = &Logger{ +// Out: os.Stderr, +// Formatter: new(JSONFormatter), +// Hooks: make(LevelHooks), +// Level: logrus.DebugLevel, +// } +// +// It's recommended to make this a global instance called `log`. +func New() *Logger { + return &Logger{ + Out: os.Stderr, + Formatter: new(TextFormatter), + Hooks: make(LevelHooks), + Level: InfoLevel, + } +} + +func (logger *Logger) newEntry() *Entry { + entry, ok := logger.entryPool.Get().(*Entry) + if ok { + return entry + } + return NewEntry(logger) +} + +func (logger *Logger) releaseEntry(entry *Entry) { + logger.entryPool.Put(entry) +} + +// Adds a field to the log entry, note that it doesn't log until you call +// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. +// If you want multiple fields, use `WithFields`. +func (logger *Logger) WithField(key string, value interface{}) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithField(key, value) +} + +// Adds a struct of fields to the log entry. All it does is call `WithField` for +// each `Field`. +func (logger *Logger) WithFields(fields Fields) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithFields(fields) +} + +// Add an error as single field to the log entry. All it does is call +// `WithError` for the given `error`. +func (logger *Logger) WithError(err error) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithError(err) +} + +func (logger *Logger) Debugf(format string, args ...interface{}) { + if logger.level() >= DebugLevel { + entry := logger.newEntry() + entry.Debugf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Infof(format string, args ...interface{}) { + if logger.level() >= InfoLevel { + entry := logger.newEntry() + entry.Infof(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Printf(format string, args ...interface{}) { + entry := logger.newEntry() + entry.Printf(format, args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warnf(format string, args ...interface{}) { + if logger.level() >= WarnLevel { + entry := logger.newEntry() + entry.Warnf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Warningf(format string, args ...interface{}) { + if logger.level() >= WarnLevel { + entry := logger.newEntry() + entry.Warnf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Errorf(format string, args ...interface{}) { + if logger.level() >= ErrorLevel { + entry := logger.newEntry() + entry.Errorf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Fatalf(format string, args ...interface{}) { + if logger.level() >= FatalLevel { + entry := logger.newEntry() + entry.Fatalf(format, args...) + logger.releaseEntry(entry) + } + Exit(1) +} + +func (logger *Logger) Panicf(format string, args ...interface{}) { + if logger.level() >= PanicLevel { + entry := logger.newEntry() + entry.Panicf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Debug(args ...interface{}) { + if logger.level() >= DebugLevel { + entry := logger.newEntry() + entry.Debug(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Info(args ...interface{}) { + if logger.level() >= InfoLevel { + entry := logger.newEntry() + entry.Info(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Print(args ...interface{}) { + entry := logger.newEntry() + entry.Info(args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warn(args ...interface{}) { + if logger.level() >= WarnLevel { + entry := logger.newEntry() + entry.Warn(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Warning(args ...interface{}) { + if logger.level() >= WarnLevel { + entry := logger.newEntry() + entry.Warn(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Error(args ...interface{}) { + if logger.level() >= ErrorLevel { + entry := logger.newEntry() + entry.Error(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Fatal(args ...interface{}) { + if logger.level() >= FatalLevel { + entry := logger.newEntry() + entry.Fatal(args...) + logger.releaseEntry(entry) + } + Exit(1) +} + +func (logger *Logger) Panic(args ...interface{}) { + if logger.level() >= PanicLevel { + entry := logger.newEntry() + entry.Panic(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Debugln(args ...interface{}) { + if logger.level() >= DebugLevel { + entry := logger.newEntry() + entry.Debugln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Infoln(args ...interface{}) { + if logger.level() >= InfoLevel { + entry := logger.newEntry() + entry.Infoln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Println(args ...interface{}) { + entry := logger.newEntry() + entry.Println(args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warnln(args ...interface{}) { + if logger.level() >= WarnLevel { + entry := logger.newEntry() + entry.Warnln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Warningln(args ...interface{}) { + if logger.level() >= WarnLevel { + entry := logger.newEntry() + entry.Warnln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Errorln(args ...interface{}) { + if logger.level() >= ErrorLevel { + entry := logger.newEntry() + entry.Errorln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Fatalln(args ...interface{}) { + if logger.level() >= FatalLevel { + entry := logger.newEntry() + entry.Fatalln(args...) + logger.releaseEntry(entry) + } + Exit(1) +} + +func (logger *Logger) Panicln(args ...interface{}) { + if logger.level() >= PanicLevel { + entry := logger.newEntry() + entry.Panicln(args...) + logger.releaseEntry(entry) + } +} + +//When file is opened with appending mode, it's safe to +//write concurrently to a file (within 4k message on Linux). +//In these cases user can choose to disable the lock. +func (logger *Logger) SetNoLock() { + logger.mu.Disable() +} + +func (logger *Logger) level() Level { + return Level(atomic.LoadUint32((*uint32)(&logger.Level))) +} + +func (logger *Logger) SetLevel(level Level) { + atomic.StoreUint32((*uint32)(&logger.Level), uint32(level)) +} + +func (logger *Logger) AddHook(hook Hook) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Hooks.Add(hook) +} diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go new file mode 100644 index 0000000000..dd38999741 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/logrus.go @@ -0,0 +1,143 @@ +package logrus + +import ( + "fmt" + "log" + "strings" +) + +// Fields type, used to pass to `WithFields`. +type Fields map[string]interface{} + +// Level type +type Level uint32 + +// Convert the Level to a string. E.g. PanicLevel becomes "panic". +func (level Level) String() string { + switch level { + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarnLevel: + return "warning" + case ErrorLevel: + return "error" + case FatalLevel: + return "fatal" + case PanicLevel: + return "panic" + } + + return "unknown" +} + +// ParseLevel takes a string level and returns the Logrus log level constant. +func ParseLevel(lvl string) (Level, error) { + switch strings.ToLower(lvl) { + case "panic": + return PanicLevel, nil + case "fatal": + return FatalLevel, nil + case "error": + return ErrorLevel, nil + case "warn", "warning": + return WarnLevel, nil + case "info": + return InfoLevel, nil + case "debug": + return DebugLevel, nil + } + + var l Level + return l, fmt.Errorf("not a valid logrus Level: %q", lvl) +} + +// A constant exposing all logging levels +var AllLevels = []Level{ + PanicLevel, + FatalLevel, + ErrorLevel, + WarnLevel, + InfoLevel, + DebugLevel, +} + +// These are the different logging levels. You can set the logging level to log +// on your instance of logger, obtained with `logrus.New()`. +const ( + // PanicLevel level, highest level of severity. Logs and then calls panic with the + // message passed to Debug, Info, ... + PanicLevel Level = iota + // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the + // logging level is set to Panic. + FatalLevel + // ErrorLevel level. Logs. Used for errors that should definitely be noted. + // Commonly used for hooks to send errors to an error tracking service. + ErrorLevel + // WarnLevel level. Non-critical entries that deserve eyes. + WarnLevel + // InfoLevel level. General operational entries about what's going on inside the + // application. + InfoLevel + // DebugLevel level. Usually only enabled when debugging. Very verbose logging. + DebugLevel +) + +// Won't compile if StdLogger can't be realized by a log.Logger +var ( + _ StdLogger = &log.Logger{} + _ StdLogger = &Entry{} + _ StdLogger = &Logger{} +) + +// StdLogger is what your logrus-enabled library should take, that way +// it'll accept a stdlib logger and a logrus logger. There's no standard +// interface, this is the closest we get, unfortunately. +type StdLogger interface { + Print(...interface{}) + Printf(string, ...interface{}) + Println(...interface{}) + + Fatal(...interface{}) + Fatalf(string, ...interface{}) + Fatalln(...interface{}) + + Panic(...interface{}) + Panicf(string, ...interface{}) + Panicln(...interface{}) +} + +// The FieldLogger interface generalizes the Entry and Logger types +type FieldLogger interface { + WithField(key string, value interface{}) *Entry + WithFields(fields Fields) *Entry + WithError(err error) *Entry + + Debugf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Printf(format string, args ...interface{}) + Warnf(format string, args ...interface{}) + Warningf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) + Panicf(format string, args ...interface{}) + + Debug(args ...interface{}) + Info(args ...interface{}) + Print(args ...interface{}) + Warn(args ...interface{}) + Warning(args ...interface{}) + Error(args ...interface{}) + Fatal(args ...interface{}) + Panic(args ...interface{}) + + Debugln(args ...interface{}) + Infoln(args ...interface{}) + Println(args ...interface{}) + Warnln(args ...interface{}) + Warningln(args ...interface{}) + Errorln(args ...interface{}) + Fatalln(args ...interface{}) + Panicln(args ...interface{}) +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go new file mode 100644 index 0000000000..d7b3893f3f --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_bsd.go @@ -0,0 +1,10 @@ +// +build darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package logrus + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TIOCGETA + +type Termios unix.Termios diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go new file mode 100644 index 0000000000..2403de9819 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go @@ -0,0 +1,11 @@ +// +build appengine + +package logrus + +import ( + "io" +) + +func checkIfTerminal(w io.Writer) bool { + return true +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go new file mode 100644 index 0000000000..116bcb4e33 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go @@ -0,0 +1,19 @@ +// +build !appengine + +package logrus + +import ( + "io" + "os" + + "golang.org/x/crypto/ssh/terminal" +) + +func checkIfTerminal(w io.Writer) bool { + switch v := w.(type) { + case *os.File: + return terminal.IsTerminal(int(v.Fd())) + default: + return false + } +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go new file mode 100644 index 0000000000..88d7298e24 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_linux.go @@ -0,0 +1,14 @@ +// Based on ssh/terminal: +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !appengine + +package logrus + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS + +type Termios unix.Termios diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go new file mode 100644 index 0000000000..61b21caea4 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -0,0 +1,178 @@ +package logrus + +import ( + "bytes" + "fmt" + "sort" + "strings" + "sync" + "time" +) + +const ( + nocolor = 0 + red = 31 + green = 32 + yellow = 33 + blue = 36 + gray = 37 +) + +var ( + baseTimestamp time.Time +) + +func init() { + baseTimestamp = time.Now() +} + +// TextFormatter formats logs into text +type TextFormatter struct { + // Set to true to bypass checking for a TTY before outputting colors. + ForceColors bool + + // Force disabling colors. + DisableColors bool + + // Disable timestamp logging. useful when output is redirected to logging + // system that already adds timestamps. + DisableTimestamp bool + + // Enable logging the full timestamp when a TTY is attached instead of just + // the time passed since beginning of execution. + FullTimestamp bool + + // TimestampFormat to use for display when a full timestamp is printed + TimestampFormat string + + // The fields are sorted by default for a consistent output. For applications + // that log extremely frequently and don't use the JSON formatter this may not + // be desired. + DisableSorting bool + + // QuoteEmptyFields will wrap empty fields in quotes if true + QuoteEmptyFields bool + + // Whether the logger's out is to a terminal + isTerminal bool + + sync.Once +} + +func (f *TextFormatter) init(entry *Entry) { + if entry.Logger != nil { + f.isTerminal = checkIfTerminal(entry.Logger.Out) + } +} + +// Format renders a single log entry +func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { + var b *bytes.Buffer + keys := make([]string, 0, len(entry.Data)) + for k := range entry.Data { + keys = append(keys, k) + } + + if !f.DisableSorting { + sort.Strings(keys) + } + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + + prefixFieldClashes(entry.Data) + + f.Do(func() { f.init(entry) }) + + isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = defaultTimestampFormat + } + if isColored { + f.printColored(b, entry, keys, timestampFormat) + } else { + if !f.DisableTimestamp { + f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) + } + f.appendKeyValue(b, "level", entry.Level.String()) + if entry.Message != "" { + f.appendKeyValue(b, "msg", entry.Message) + } + for _, key := range keys { + f.appendKeyValue(b, key, entry.Data[key]) + } + } + + b.WriteByte('\n') + return b.Bytes(), nil +} + +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { + var levelColor int + switch entry.Level { + case DebugLevel: + levelColor = gray + case WarnLevel: + levelColor = yellow + case ErrorLevel, FatalLevel, PanicLevel: + levelColor = red + default: + levelColor = blue + } + + levelText := strings.ToUpper(entry.Level.String())[0:4] + + if f.DisableTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message) + } else if !f.FullTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message) + } else { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) + } + for _, k := range keys { + v := entry.Data[k] + fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) + f.appendValue(b, v) + } +} + +func (f *TextFormatter) needsQuoting(text string) bool { + if f.QuoteEmptyFields && len(text) == 0 { + return true + } + for _, ch := range text { + if !((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') { + return true + } + } + return false +} + +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { + if b.Len() > 0 { + b.WriteByte(' ') + } + b.WriteString(key) + b.WriteByte('=') + f.appendValue(b, value) +} + +func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { + stringVal, ok := value.(string) + if !ok { + stringVal = fmt.Sprint(value) + } + + if !f.needsQuoting(stringVal) { + b.WriteString(stringVal) + } else { + b.WriteString(fmt.Sprintf("%q", stringVal)) + } +} diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go new file mode 100644 index 0000000000..7bdebedc60 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/writer.go @@ -0,0 +1,62 @@ +package logrus + +import ( + "bufio" + "io" + "runtime" +) + +func (logger *Logger) Writer() *io.PipeWriter { + return logger.WriterLevel(InfoLevel) +} + +func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { + return NewEntry(logger).WriterLevel(level) +} + +func (entry *Entry) Writer() *io.PipeWriter { + return entry.WriterLevel(InfoLevel) +} + +func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { + reader, writer := io.Pipe() + + var printFunc func(args ...interface{}) + + switch level { + case DebugLevel: + printFunc = entry.Debug + case InfoLevel: + printFunc = entry.Info + case WarnLevel: + printFunc = entry.Warn + case ErrorLevel: + printFunc = entry.Error + case FatalLevel: + printFunc = entry.Fatal + case PanicLevel: + printFunc = entry.Panic + default: + printFunc = entry.Print + } + + go entry.writerScanner(reader, printFunc) + runtime.SetFinalizer(writer, writerFinalizer) + + return writer +} + +func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + printFunc(scanner.Text()) + } + if err := scanner.Err(); err != nil { + entry.Errorf("Error while reading from Writer: %s", err) + } + reader.Close() +} + +func writerFinalizer(writer *io.PipeWriter) { + writer.Close() +} diff --git a/vendor/github.com/skarademir/naturalsort/LICENSE.md b/vendor/github.com/skarademir/naturalsort/LICENSE.md new file mode 100644 index 0000000000..af513860b4 --- /dev/null +++ b/vendor/github.com/skarademir/naturalsort/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 skarademir + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/skarademir/naturalsort/README.md b/vendor/github.com/skarademir/naturalsort/README.md new file mode 100644 index 0000000000..60307fc049 --- /dev/null +++ b/vendor/github.com/skarademir/naturalsort/README.md @@ -0,0 +1,22 @@ +# naturalsort +A simple natural string sorter for Go. + +##Usage +Implements the `sort.Interface` + +called by `sort.Sort(NaturalSort([]string))` +###Example + +```go +SampleStringArray := []string{ + "z24", "z2", "z15", "z1", + "z3", "z20", "z5", "z11", + "z 21", "z22"} +sort.Sort(NaturalSort(SampleStringArray)) +``` + +##Needless Description +Inspired by [Jeff Atwood's seminal blog post](http://blog.codinghorror.com/sorting-for-humans-natural-sort-order/) and +structured similarly to [Ian Griffiths' C# implementation](http://www.interact-sw.co.uk/iangblog/2007/12/13/natural-sorting). +This uses a regex to split the numeric and non-numeric portions of the string into a chunky array. Next, the left and right sides' +chunks are compared either by string comparrison (if either chunk is a non-numeric), or by ~~integer (if both chunks are numeric)~~ a character-by-character iterative function that compares numerical strings diff --git a/vendor/github.com/skarademir/naturalsort/naturalsort.go b/vendor/github.com/skarademir/naturalsort/naturalsort.go new file mode 100644 index 0000000000..23dd16d163 --- /dev/null +++ b/vendor/github.com/skarademir/naturalsort/naturalsort.go @@ -0,0 +1,60 @@ +package naturalsort + +import ( + "regexp" + "strings" +) + +type NaturalSort []string + +var r = regexp.MustCompile(`[^0-9]+|[0-9]+`) + +func (s NaturalSort) Len() int { + return len(s) +} +func (s NaturalSort) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} +func (s NaturalSort) Less(i, j int) bool { + + spliti := r.FindAllString(strings.Replace(s[i], " ", "", -1), -1) + splitj := r.FindAllString(strings.Replace(s[j], " ", "", -1), -1) + + for index := 0; index < len(spliti) && index < len(splitj); index++ { + if spliti[index] != splitj[index] { + // Both slices are numbers + if isNumber(spliti[index][0]) && isNumber(splitj[index][0]) { + // Remove Leading Zeroes + stringi := strings.TrimLeft(spliti[index], "0") + stringj := strings.TrimLeft(splitj[index], "0") + if len(stringi) == len(stringj) { + for indexchar := 0; indexchar < len(stringi); indexchar++ { + if stringi[indexchar] != stringj[indexchar] { + return stringi[indexchar] < stringj[indexchar] + } + } + return len(spliti[index]) < len(splitj[index]) + } + return len(stringi) < len(stringj) + } + // One of the slices is a number (we give precedence to numbers regardless of ASCII table position) + if isNumber(spliti[index][0]) || isNumber(splitj[index][0]) { + return isNumber(spliti[index][0]) + } + // Both slices are not numbers + return spliti[index] < splitj[index] + } + + } + // Fall back for cases where space characters have been annihliated by the replacment call + // Here we iterate over the unmolsested string and prioritize numbers over + for index := 0; index < len(s[i]) && index < len(s[j]); index++ { + if isNumber(s[i][index]) || isNumber(s[j][index]) { + return isNumber(s[i][index]) + } + } + return s[i] < s[j] +} +func isNumber(input uint8) bool { + return input >= '0' && input <= '9' +} diff --git a/vendor/github.com/stretchr/objx/.gitignore b/vendor/github.com/stretchr/objx/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/stretchr/objx/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/stretchr/objx/LICENSE.md b/vendor/github.com/stretchr/objx/LICENSE.md new file mode 100644 index 0000000000..2199945813 --- /dev/null +++ b/vendor/github.com/stretchr/objx/LICENSE.md @@ -0,0 +1,23 @@ +objx - by Mat Ryer and Tyler Bunnell + +The MIT License (MIT) + +Copyright (c) 2014 Stretchr, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/stretchr/objx/README.md b/vendor/github.com/stretchr/objx/README.md new file mode 100644 index 0000000000..4aa180687a --- /dev/null +++ b/vendor/github.com/stretchr/objx/README.md @@ -0,0 +1,3 @@ +# objx + + * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx) diff --git a/vendor/github.com/stretchr/objx/accessors.go b/vendor/github.com/stretchr/objx/accessors.go new file mode 100644 index 0000000000..721bcac799 --- /dev/null +++ b/vendor/github.com/stretchr/objx/accessors.go @@ -0,0 +1,179 @@ +package objx + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +// arrayAccesRegexString is the regex used to extract the array number +// from the access path +const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$` + +// arrayAccesRegex is the compiled arrayAccesRegexString +var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString) + +// Get gets the value using the specified selector and +// returns it inside a new Obj object. +// +// If it cannot find the value, Get will return a nil +// value inside an instance of Obj. +// +// Get can only operate directly on map[string]interface{} and []interface. +// +// Example +// +// To access the title of the third chapter of the second book, do: +// +// o.Get("books[1].chapters[2].title") +func (m Map) Get(selector string) *Value { + rawObj := access(m, selector, nil, false, false) + return &Value{data: rawObj} +} + +// Set sets the value using the specified selector and +// returns the object on which Set was called. +// +// Set can only operate directly on map[string]interface{} and []interface +// +// Example +// +// To set the title of the third chapter of the second book, do: +// +// o.Set("books[1].chapters[2].title","Time to Go") +func (m Map) Set(selector string, value interface{}) Map { + access(m, selector, value, true, false) + return m +} + +// access accesses the object using the selector and performs the +// appropriate action. +func access(current, selector, value interface{}, isSet, panics bool) interface{} { + + switch selector.(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + + if array, ok := current.([]interface{}); ok { + index := intFromInterface(selector) + + if index >= len(array) { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) + } + return nil + } + + return array[index] + } + + return nil + + case string: + + selStr := selector.(string) + selSegs := strings.SplitN(selStr, PathSeparator, 2) + thisSel := selSegs[0] + index := -1 + var err error + + // https://github.com/stretchr/objx/issues/12 + if strings.Contains(thisSel, "[") { + + arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel) + + if len(arrayMatches) > 0 { + + // Get the key into the map + thisSel = arrayMatches[1] + + // Get the index into the array at the key + index, err = strconv.Atoi(arrayMatches[2]) + + if err != nil { + // This should never happen. If it does, something has gone + // seriously wrong. Panic. + panic("objx: Array index is not an integer. Must use array[int].") + } + + } + } + + if curMap, ok := current.(Map); ok { + current = map[string]interface{}(curMap) + } + + // get the object in question + switch current.(type) { + case map[string]interface{}: + curMSI := current.(map[string]interface{}) + if len(selSegs) <= 1 && isSet { + curMSI[thisSel] = value + return nil + } else { + current = curMSI[thisSel] + } + default: + current = nil + } + + if current == nil && panics { + panic(fmt.Sprintf("objx: '%v' invalid on object.", selector)) + } + + // do we need to access the item of an array? + if index > -1 { + if array, ok := current.([]interface{}); ok { + if index < len(array) { + current = array[index] + } else { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) + } + current = nil + } + } + } + + if len(selSegs) > 1 { + current = access(current, selSegs[1], value, isSet, panics) + } + + } + + return current + +} + +// intFromInterface converts an interface object to the largest +// representation of an unsigned integer using a type switch and +// assertions +func intFromInterface(selector interface{}) int { + var value int + switch selector.(type) { + case int: + value = selector.(int) + case int8: + value = int(selector.(int8)) + case int16: + value = int(selector.(int16)) + case int32: + value = int(selector.(int32)) + case int64: + value = int(selector.(int64)) + case uint: + value = int(selector.(uint)) + case uint8: + value = int(selector.(uint8)) + case uint16: + value = int(selector.(uint16)) + case uint32: + value = int(selector.(uint32)) + case uint64: + value = int(selector.(uint64)) + default: + panic("objx: array access argument is not an integer type (this should never happen)") + } + + return value +} diff --git a/vendor/github.com/stretchr/objx/constants.go b/vendor/github.com/stretchr/objx/constants.go new file mode 100644 index 0000000000..f9eb42a25e --- /dev/null +++ b/vendor/github.com/stretchr/objx/constants.go @@ -0,0 +1,13 @@ +package objx + +const ( + // PathSeparator is the character used to separate the elements + // of the keypath. + // + // For example, `location.address.city` + PathSeparator string = "." + + // SignatureSeparator is the character that is used to + // separate the Base64 string from the security signature. + SignatureSeparator = "_" +) diff --git a/vendor/github.com/stretchr/objx/conversions.go b/vendor/github.com/stretchr/objx/conversions.go new file mode 100644 index 0000000000..9cdfa9f9f6 --- /dev/null +++ b/vendor/github.com/stretchr/objx/conversions.go @@ -0,0 +1,117 @@ +package objx + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/url" +) + +// JSON converts the contained object to a JSON string +// representation +func (m Map) JSON() (string, error) { + + result, err := json.Marshal(m) + + if err != nil { + err = errors.New("objx: JSON encode failed with: " + err.Error()) + } + + return string(result), err + +} + +// MustJSON converts the contained object to a JSON string +// representation and panics if there is an error +func (m Map) MustJSON() string { + result, err := m.JSON() + if err != nil { + panic(err.Error()) + } + return result +} + +// Base64 converts the contained object to a Base64 string +// representation of the JSON string representation +func (m Map) Base64() (string, error) { + + var buf bytes.Buffer + + jsonData, err := m.JSON() + if err != nil { + return "", err + } + + encoder := base64.NewEncoder(base64.StdEncoding, &buf) + encoder.Write([]byte(jsonData)) + encoder.Close() + + return buf.String(), nil + +} + +// MustBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and panics +// if there is an error +func (m Map) MustBase64() string { + result, err := m.Base64() + if err != nil { + panic(err.Error()) + } + return result +} + +// SignedBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and signs it +// using the provided key. +func (m Map) SignedBase64(key string) (string, error) { + + base64, err := m.Base64() + if err != nil { + return "", err + } + + sig := HashWithKey(base64, key) + + return base64 + SignatureSeparator + sig, nil + +} + +// MustSignedBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and signs it +// using the provided key and panics if there is an error +func (m Map) MustSignedBase64(key string) string { + result, err := m.SignedBase64(key) + if err != nil { + panic(err.Error()) + } + return result +} + +/* + URL Query + ------------------------------------------------ +*/ + +// URLValues creates a url.Values object from an Obj. This +// function requires that the wrapped object be a map[string]interface{} +func (m Map) URLValues() url.Values { + + vals := make(url.Values) + + for k, v := range m { + //TODO: can this be done without sprintf? + vals.Set(k, fmt.Sprintf("%v", v)) + } + + return vals +} + +// URLQuery gets an encoded URL query representing the given +// Obj. This function requires that the wrapped object be a +// map[string]interface{} +func (m Map) URLQuery() (string, error) { + return m.URLValues().Encode(), nil +} diff --git a/vendor/github.com/stretchr/objx/doc.go b/vendor/github.com/stretchr/objx/doc.go new file mode 100644 index 0000000000..47bf85e463 --- /dev/null +++ b/vendor/github.com/stretchr/objx/doc.go @@ -0,0 +1,72 @@ +// objx - Go package for dealing with maps, slices, JSON and other data. +// +// Overview +// +// Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes +// a powerful `Get` method (among others) that allows you to easily and quickly get +// access to data within the map, without having to worry too much about type assertions, +// missing data, default values etc. +// +// Pattern +// +// Objx uses a preditable pattern to make access data from within `map[string]interface{}'s +// easy. +// +// Call one of the `objx.` functions to create your `objx.Map` to get going: +// +// m, err := objx.FromJSON(json) +// +// NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, +// the rest will be optimistic and try to figure things out without panicking. +// +// Use `Get` to access the value you're interested in. You can use dot and array +// notation too: +// +// m.Get("places[0].latlng") +// +// Once you have saught the `Value` you're interested in, you can use the `Is*` methods +// to determine its type. +// +// if m.Get("code").IsStr() { /* ... */ } +// +// Or you can just assume the type, and use one of the strong type methods to +// extract the real value: +// +// m.Get("code").Int() +// +// If there's no value there (or if it's the wrong type) then a default value +// will be returned, or you can be explicit about the default value. +// +// Get("code").Int(-1) +// +// If you're dealing with a slice of data as a value, Objx provides many useful +// methods for iterating, manipulating and selecting that data. You can find out more +// by exploring the index below. +// +// Reading data +// +// A simple example of how to use Objx: +// +// // use MustFromJSON to make an objx.Map from some JSON +// m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) +// +// // get the details +// name := m.Get("name").Str() +// age := m.Get("age").Int() +// +// // get their nickname (or use their name if they +// // don't have one) +// nickname := m.Get("nickname").Str(name) +// +// Ranging +// +// Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For +// example, to `range` the data, do what you would expect: +// +// m := objx.MustFromJSON(json) +// for key, value := range m { +// +// /* ... do your magic ... */ +// +// } +package objx diff --git a/vendor/github.com/stretchr/objx/map.go b/vendor/github.com/stretchr/objx/map.go new file mode 100644 index 0000000000..eb6ed8e285 --- /dev/null +++ b/vendor/github.com/stretchr/objx/map.go @@ -0,0 +1,222 @@ +package objx + +import ( + "encoding/base64" + "encoding/json" + "errors" + "io/ioutil" + "net/url" + "strings" +) + +// MSIConvertable is an interface that defines methods for converting your +// custom types to a map[string]interface{} representation. +type MSIConvertable interface { + // MSI gets a map[string]interface{} (msi) representing the + // object. + MSI() map[string]interface{} +} + +// Map provides extended functionality for working with +// untyped data, in particular map[string]interface (msi). +type Map map[string]interface{} + +// Value returns the internal value instance +func (m Map) Value() *Value { + return &Value{data: m} +} + +// Nil represents a nil Map. +var Nil Map = New(nil) + +// New creates a new Map containing the map[string]interface{} in the data argument. +// If the data argument is not a map[string]interface, New attempts to call the +// MSI() method on the MSIConvertable interface to create one. +func New(data interface{}) Map { + if _, ok := data.(map[string]interface{}); !ok { + if converter, ok := data.(MSIConvertable); ok { + data = converter.MSI() + } else { + return nil + } + } + return Map(data.(map[string]interface{})) +} + +// MSI creates a map[string]interface{} and puts it inside a new Map. +// +// The arguments follow a key, value pattern. +// +// Panics +// +// Panics if any key arugment is non-string or if there are an odd number of arguments. +// +// Example +// +// To easily create Maps: +// +// m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true)) +// +// // creates an Map equivalent to +// m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}}) +func MSI(keyAndValuePairs ...interface{}) Map { + + newMap := make(map[string]interface{}) + keyAndValuePairsLen := len(keyAndValuePairs) + + if keyAndValuePairsLen%2 != 0 { + panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.") + } + + for i := 0; i < keyAndValuePairsLen; i = i + 2 { + + key := keyAndValuePairs[i] + value := keyAndValuePairs[i+1] + + // make sure the key is a string + keyString, keyStringOK := key.(string) + if !keyStringOK { + panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.") + } + + newMap[keyString] = value + + } + + return New(newMap) +} + +// ****** Conversion Constructors + +// MustFromJSON creates a new Map containing the data specified in the +// jsonString. +// +// Panics if the JSON is invalid. +func MustFromJSON(jsonString string) Map { + o, err := FromJSON(jsonString) + + if err != nil { + panic("objx: MustFromJSON failed with error: " + err.Error()) + } + + return o +} + +// FromJSON creates a new Map containing the data specified in the +// jsonString. +// +// Returns an error if the JSON is invalid. +func FromJSON(jsonString string) (Map, error) { + + var data interface{} + err := json.Unmarshal([]byte(jsonString), &data) + + if err != nil { + return Nil, err + } + + return New(data), nil + +} + +// FromBase64 creates a new Obj containing the data specified +// in the Base64 string. +// +// The string is an encoded JSON string returned by Base64 +func FromBase64(base64String string) (Map, error) { + + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String)) + + decoded, err := ioutil.ReadAll(decoder) + if err != nil { + return nil, err + } + + return FromJSON(string(decoded)) +} + +// MustFromBase64 creates a new Obj containing the data specified +// in the Base64 string and panics if there is an error. +// +// The string is an encoded JSON string returned by Base64 +func MustFromBase64(base64String string) Map { + + result, err := FromBase64(base64String) + + if err != nil { + panic("objx: MustFromBase64 failed with error: " + err.Error()) + } + + return result +} + +// FromSignedBase64 creates a new Obj containing the data specified +// in the Base64 string. +// +// The string is an encoded JSON string returned by SignedBase64 +func FromSignedBase64(base64String, key string) (Map, error) { + parts := strings.Split(base64String, SignatureSeparator) + if len(parts) != 2 { + return nil, errors.New("objx: Signed base64 string is malformed.") + } + + sig := HashWithKey(parts[0], key) + if parts[1] != sig { + return nil, errors.New("objx: Signature for base64 data does not match.") + } + + return FromBase64(parts[0]) +} + +// MustFromSignedBase64 creates a new Obj containing the data specified +// in the Base64 string and panics if there is an error. +// +// The string is an encoded JSON string returned by Base64 +func MustFromSignedBase64(base64String, key string) Map { + + result, err := FromSignedBase64(base64String, key) + + if err != nil { + panic("objx: MustFromSignedBase64 failed with error: " + err.Error()) + } + + return result +} + +// FromURLQuery generates a new Obj by parsing the specified +// query. +// +// For queries with multiple values, the first value is selected. +func FromURLQuery(query string) (Map, error) { + + vals, err := url.ParseQuery(query) + + if err != nil { + return nil, err + } + + m := make(map[string]interface{}) + for k, vals := range vals { + m[k] = vals[0] + } + + return New(m), nil +} + +// MustFromURLQuery generates a new Obj by parsing the specified +// query. +// +// For queries with multiple values, the first value is selected. +// +// Panics if it encounters an error +func MustFromURLQuery(query string) Map { + + o, err := FromURLQuery(query) + + if err != nil { + panic("objx: MustFromURLQuery failed with error: " + err.Error()) + } + + return o + +} diff --git a/vendor/github.com/stretchr/objx/mutations.go b/vendor/github.com/stretchr/objx/mutations.go new file mode 100644 index 0000000000..b35c86392b --- /dev/null +++ b/vendor/github.com/stretchr/objx/mutations.go @@ -0,0 +1,81 @@ +package objx + +// Exclude returns a new Map with the keys in the specified []string +// excluded. +func (d Map) Exclude(exclude []string) Map { + + excluded := make(Map) + for k, v := range d { + var shouldInclude bool = true + for _, toExclude := range exclude { + if k == toExclude { + shouldInclude = false + break + } + } + if shouldInclude { + excluded[k] = v + } + } + + return excluded +} + +// Copy creates a shallow copy of the Obj. +func (m Map) Copy() Map { + copied := make(map[string]interface{}) + for k, v := range m { + copied[k] = v + } + return New(copied) +} + +// Merge blends the specified map with a copy of this map and returns the result. +// +// Keys that appear in both will be selected from the specified map. +// This method requires that the wrapped object be a map[string]interface{} +func (m Map) Merge(merge Map) Map { + return m.Copy().MergeHere(merge) +} + +// Merge blends the specified map with this map and returns the current map. +// +// Keys that appear in both will be selected from the specified map. The original map +// will be modified. This method requires that +// the wrapped object be a map[string]interface{} +func (m Map) MergeHere(merge Map) Map { + + for k, v := range merge { + m[k] = v + } + + return m + +} + +// Transform builds a new Obj giving the transformer a chance +// to change the keys and values as it goes. This method requires that +// the wrapped object be a map[string]interface{} +func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map { + newMap := make(map[string]interface{}) + for k, v := range m { + modifiedKey, modifiedVal := transformer(k, v) + newMap[modifiedKey] = modifiedVal + } + return New(newMap) +} + +// TransformKeys builds a new map using the specified key mapping. +// +// Unspecified keys will be unaltered. +// This method requires that the wrapped object be a map[string]interface{} +func (m Map) TransformKeys(mapping map[string]string) Map { + return m.Transform(func(key string, value interface{}) (string, interface{}) { + + if newKey, ok := mapping[key]; ok { + return newKey, value + } + + return key, value + }) +} diff --git a/vendor/github.com/stretchr/objx/security.go b/vendor/github.com/stretchr/objx/security.go new file mode 100644 index 0000000000..fdd6be9cfb --- /dev/null +++ b/vendor/github.com/stretchr/objx/security.go @@ -0,0 +1,14 @@ +package objx + +import ( + "crypto/sha1" + "encoding/hex" +) + +// HashWithKey hashes the specified string using the security +// key. +func HashWithKey(data, key string) string { + hash := sha1.New() + hash.Write([]byte(data + ":" + key)) + return hex.EncodeToString(hash.Sum(nil)) +} diff --git a/vendor/github.com/stretchr/objx/tests.go b/vendor/github.com/stretchr/objx/tests.go new file mode 100644 index 0000000000..d9e0b479a4 --- /dev/null +++ b/vendor/github.com/stretchr/objx/tests.go @@ -0,0 +1,17 @@ +package objx + +// Has gets whether there is something at the specified selector +// or not. +// +// If m is nil, Has will always return false. +func (m Map) Has(selector string) bool { + if m == nil { + return false + } + return !m.Get(selector).IsNil() +} + +// IsNil gets whether the data is nil or not. +func (v *Value) IsNil() bool { + return v == nil || v.data == nil +} diff --git a/vendor/github.com/stretchr/objx/type_specific_codegen.go b/vendor/github.com/stretchr/objx/type_specific_codegen.go new file mode 100644 index 0000000000..f3ecb29b95 --- /dev/null +++ b/vendor/github.com/stretchr/objx/type_specific_codegen.go @@ -0,0 +1,2881 @@ +package objx + +/* + Inter (interface{} and []interface{}) + -------------------------------------------------- +*/ + +// Inter gets the value as a interface{}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Inter(optionalDefault ...interface{}) interface{} { + if s, ok := v.data.(interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInter gets the value as a interface{}. +// +// Panics if the object is not a interface{}. +func (v *Value) MustInter() interface{} { + return v.data.(interface{}) +} + +// InterSlice gets the value as a []interface{}, returns the optionalDefault +// value or nil if the value is not a []interface{}. +func (v *Value) InterSlice(optionalDefault ...[]interface{}) []interface{} { + if s, ok := v.data.([]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInterSlice gets the value as a []interface{}. +// +// Panics if the object is not a []interface{}. +func (v *Value) MustInterSlice() []interface{} { + return v.data.([]interface{}) +} + +// IsInter gets whether the object contained is a interface{} or not. +func (v *Value) IsInter() bool { + _, ok := v.data.(interface{}) + return ok +} + +// IsInterSlice gets whether the object contained is a []interface{} or not. +func (v *Value) IsInterSlice() bool { + _, ok := v.data.([]interface{}) + return ok +} + +// EachInter calls the specified callback for each object +// in the []interface{}. +// +// Panics if the object is the wrong type. +func (v *Value) EachInter(callback func(int, interface{}) bool) *Value { + + for index, val := range v.MustInterSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInter uses the specified decider function to select items +// from the []interface{}. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInter(decider func(int, interface{}) bool) *Value { + + var selected []interface{} + + v.EachInter(func(index int, val interface{}) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInter uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]interface{}. +func (v *Value) GroupInter(grouper func(int, interface{}) string) *Value { + + groups := make(map[string][]interface{}) + + v.EachInter(func(index int, val interface{}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]interface{}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInter uses the specified function to replace each interface{}s +// by iterating each item. The data in the returned result will be a +// []interface{} containing the replaced items. +func (v *Value) ReplaceInter(replacer func(int, interface{}) interface{}) *Value { + + arr := v.MustInterSlice() + replaced := make([]interface{}, len(arr)) + + v.EachInter(func(index int, val interface{}) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInter uses the specified collector function to collect a value +// for each of the interface{}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInter(collector func(int, interface{}) interface{}) *Value { + + arr := v.MustInterSlice() + collected := make([]interface{}, len(arr)) + + v.EachInter(func(index int, val interface{}) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + MSI (map[string]interface{} and []map[string]interface{}) + -------------------------------------------------- +*/ + +// MSI gets the value as a map[string]interface{}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} { + if s, ok := v.data.(map[string]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustMSI gets the value as a map[string]interface{}. +// +// Panics if the object is not a map[string]interface{}. +func (v *Value) MustMSI() map[string]interface{} { + return v.data.(map[string]interface{}) +} + +// MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault +// value or nil if the value is not a []map[string]interface{}. +func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} { + if s, ok := v.data.([]map[string]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustMSISlice gets the value as a []map[string]interface{}. +// +// Panics if the object is not a []map[string]interface{}. +func (v *Value) MustMSISlice() []map[string]interface{} { + return v.data.([]map[string]interface{}) +} + +// IsMSI gets whether the object contained is a map[string]interface{} or not. +func (v *Value) IsMSI() bool { + _, ok := v.data.(map[string]interface{}) + return ok +} + +// IsMSISlice gets whether the object contained is a []map[string]interface{} or not. +func (v *Value) IsMSISlice() bool { + _, ok := v.data.([]map[string]interface{}) + return ok +} + +// EachMSI calls the specified callback for each object +// in the []map[string]interface{}. +// +// Panics if the object is the wrong type. +func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value { + + for index, val := range v.MustMSISlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereMSI uses the specified decider function to select items +// from the []map[string]interface{}. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value { + + var selected []map[string]interface{} + + v.EachMSI(func(index int, val map[string]interface{}) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupMSI uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]map[string]interface{}. +func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value { + + groups := make(map[string][]map[string]interface{}) + + v.EachMSI(func(index int, val map[string]interface{}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]map[string]interface{}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceMSI uses the specified function to replace each map[string]interface{}s +// by iterating each item. The data in the returned result will be a +// []map[string]interface{} containing the replaced items. +func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value { + + arr := v.MustMSISlice() + replaced := make([]map[string]interface{}, len(arr)) + + v.EachMSI(func(index int, val map[string]interface{}) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectMSI uses the specified collector function to collect a value +// for each of the map[string]interface{}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value { + + arr := v.MustMSISlice() + collected := make([]interface{}, len(arr)) + + v.EachMSI(func(index int, val map[string]interface{}) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + ObjxMap ((Map) and [](Map)) + -------------------------------------------------- +*/ + +// ObjxMap gets the value as a (Map), returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) ObjxMap(optionalDefault ...(Map)) Map { + if s, ok := v.data.((Map)); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return New(nil) +} + +// MustObjxMap gets the value as a (Map). +// +// Panics if the object is not a (Map). +func (v *Value) MustObjxMap() Map { + return v.data.((Map)) +} + +// ObjxMapSlice gets the value as a [](Map), returns the optionalDefault +// value or nil if the value is not a [](Map). +func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) { + if s, ok := v.data.([](Map)); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustObjxMapSlice gets the value as a [](Map). +// +// Panics if the object is not a [](Map). +func (v *Value) MustObjxMapSlice() [](Map) { + return v.data.([](Map)) +} + +// IsObjxMap gets whether the object contained is a (Map) or not. +func (v *Value) IsObjxMap() bool { + _, ok := v.data.((Map)) + return ok +} + +// IsObjxMapSlice gets whether the object contained is a [](Map) or not. +func (v *Value) IsObjxMapSlice() bool { + _, ok := v.data.([](Map)) + return ok +} + +// EachObjxMap calls the specified callback for each object +// in the [](Map). +// +// Panics if the object is the wrong type. +func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value { + + for index, val := range v.MustObjxMapSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereObjxMap uses the specified decider function to select items +// from the [](Map). The object contained in the result will contain +// only the selected items. +func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value { + + var selected [](Map) + + v.EachObjxMap(func(index int, val Map) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupObjxMap uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][](Map). +func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value { + + groups := make(map[string][](Map)) + + v.EachObjxMap(func(index int, val Map) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([](Map), 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceObjxMap uses the specified function to replace each (Map)s +// by iterating each item. The data in the returned result will be a +// [](Map) containing the replaced items. +func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value { + + arr := v.MustObjxMapSlice() + replaced := make([](Map), len(arr)) + + v.EachObjxMap(func(index int, val Map) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectObjxMap uses the specified collector function to collect a value +// for each of the (Map)s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value { + + arr := v.MustObjxMapSlice() + collected := make([]interface{}, len(arr)) + + v.EachObjxMap(func(index int, val Map) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Bool (bool and []bool) + -------------------------------------------------- +*/ + +// Bool gets the value as a bool, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Bool(optionalDefault ...bool) bool { + if s, ok := v.data.(bool); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return false +} + +// MustBool gets the value as a bool. +// +// Panics if the object is not a bool. +func (v *Value) MustBool() bool { + return v.data.(bool) +} + +// BoolSlice gets the value as a []bool, returns the optionalDefault +// value or nil if the value is not a []bool. +func (v *Value) BoolSlice(optionalDefault ...[]bool) []bool { + if s, ok := v.data.([]bool); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustBoolSlice gets the value as a []bool. +// +// Panics if the object is not a []bool. +func (v *Value) MustBoolSlice() []bool { + return v.data.([]bool) +} + +// IsBool gets whether the object contained is a bool or not. +func (v *Value) IsBool() bool { + _, ok := v.data.(bool) + return ok +} + +// IsBoolSlice gets whether the object contained is a []bool or not. +func (v *Value) IsBoolSlice() bool { + _, ok := v.data.([]bool) + return ok +} + +// EachBool calls the specified callback for each object +// in the []bool. +// +// Panics if the object is the wrong type. +func (v *Value) EachBool(callback func(int, bool) bool) *Value { + + for index, val := range v.MustBoolSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereBool uses the specified decider function to select items +// from the []bool. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereBool(decider func(int, bool) bool) *Value { + + var selected []bool + + v.EachBool(func(index int, val bool) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupBool uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]bool. +func (v *Value) GroupBool(grouper func(int, bool) string) *Value { + + groups := make(map[string][]bool) + + v.EachBool(func(index int, val bool) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]bool, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceBool uses the specified function to replace each bools +// by iterating each item. The data in the returned result will be a +// []bool containing the replaced items. +func (v *Value) ReplaceBool(replacer func(int, bool) bool) *Value { + + arr := v.MustBoolSlice() + replaced := make([]bool, len(arr)) + + v.EachBool(func(index int, val bool) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectBool uses the specified collector function to collect a value +// for each of the bools in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectBool(collector func(int, bool) interface{}) *Value { + + arr := v.MustBoolSlice() + collected := make([]interface{}, len(arr)) + + v.EachBool(func(index int, val bool) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Str (string and []string) + -------------------------------------------------- +*/ + +// Str gets the value as a string, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Str(optionalDefault ...string) string { + if s, ok := v.data.(string); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return "" +} + +// MustStr gets the value as a string. +// +// Panics if the object is not a string. +func (v *Value) MustStr() string { + return v.data.(string) +} + +// StrSlice gets the value as a []string, returns the optionalDefault +// value or nil if the value is not a []string. +func (v *Value) StrSlice(optionalDefault ...[]string) []string { + if s, ok := v.data.([]string); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustStrSlice gets the value as a []string. +// +// Panics if the object is not a []string. +func (v *Value) MustStrSlice() []string { + return v.data.([]string) +} + +// IsStr gets whether the object contained is a string or not. +func (v *Value) IsStr() bool { + _, ok := v.data.(string) + return ok +} + +// IsStrSlice gets whether the object contained is a []string or not. +func (v *Value) IsStrSlice() bool { + _, ok := v.data.([]string) + return ok +} + +// EachStr calls the specified callback for each object +// in the []string. +// +// Panics if the object is the wrong type. +func (v *Value) EachStr(callback func(int, string) bool) *Value { + + for index, val := range v.MustStrSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereStr uses the specified decider function to select items +// from the []string. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereStr(decider func(int, string) bool) *Value { + + var selected []string + + v.EachStr(func(index int, val string) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupStr uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]string. +func (v *Value) GroupStr(grouper func(int, string) string) *Value { + + groups := make(map[string][]string) + + v.EachStr(func(index int, val string) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]string, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceStr uses the specified function to replace each strings +// by iterating each item. The data in the returned result will be a +// []string containing the replaced items. +func (v *Value) ReplaceStr(replacer func(int, string) string) *Value { + + arr := v.MustStrSlice() + replaced := make([]string, len(arr)) + + v.EachStr(func(index int, val string) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectStr uses the specified collector function to collect a value +// for each of the strings in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectStr(collector func(int, string) interface{}) *Value { + + arr := v.MustStrSlice() + collected := make([]interface{}, len(arr)) + + v.EachStr(func(index int, val string) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int (int and []int) + -------------------------------------------------- +*/ + +// Int gets the value as a int, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int(optionalDefault ...int) int { + if s, ok := v.data.(int); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt gets the value as a int. +// +// Panics if the object is not a int. +func (v *Value) MustInt() int { + return v.data.(int) +} + +// IntSlice gets the value as a []int, returns the optionalDefault +// value or nil if the value is not a []int. +func (v *Value) IntSlice(optionalDefault ...[]int) []int { + if s, ok := v.data.([]int); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustIntSlice gets the value as a []int. +// +// Panics if the object is not a []int. +func (v *Value) MustIntSlice() []int { + return v.data.([]int) +} + +// IsInt gets whether the object contained is a int or not. +func (v *Value) IsInt() bool { + _, ok := v.data.(int) + return ok +} + +// IsIntSlice gets whether the object contained is a []int or not. +func (v *Value) IsIntSlice() bool { + _, ok := v.data.([]int) + return ok +} + +// EachInt calls the specified callback for each object +// in the []int. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt(callback func(int, int) bool) *Value { + + for index, val := range v.MustIntSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt uses the specified decider function to select items +// from the []int. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt(decider func(int, int) bool) *Value { + + var selected []int + + v.EachInt(func(index int, val int) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int. +func (v *Value) GroupInt(grouper func(int, int) string) *Value { + + groups := make(map[string][]int) + + v.EachInt(func(index int, val int) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt uses the specified function to replace each ints +// by iterating each item. The data in the returned result will be a +// []int containing the replaced items. +func (v *Value) ReplaceInt(replacer func(int, int) int) *Value { + + arr := v.MustIntSlice() + replaced := make([]int, len(arr)) + + v.EachInt(func(index int, val int) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt uses the specified collector function to collect a value +// for each of the ints in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt(collector func(int, int) interface{}) *Value { + + arr := v.MustIntSlice() + collected := make([]interface{}, len(arr)) + + v.EachInt(func(index int, val int) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int8 (int8 and []int8) + -------------------------------------------------- +*/ + +// Int8 gets the value as a int8, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int8(optionalDefault ...int8) int8 { + if s, ok := v.data.(int8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt8 gets the value as a int8. +// +// Panics if the object is not a int8. +func (v *Value) MustInt8() int8 { + return v.data.(int8) +} + +// Int8Slice gets the value as a []int8, returns the optionalDefault +// value or nil if the value is not a []int8. +func (v *Value) Int8Slice(optionalDefault ...[]int8) []int8 { + if s, ok := v.data.([]int8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt8Slice gets the value as a []int8. +// +// Panics if the object is not a []int8. +func (v *Value) MustInt8Slice() []int8 { + return v.data.([]int8) +} + +// IsInt8 gets whether the object contained is a int8 or not. +func (v *Value) IsInt8() bool { + _, ok := v.data.(int8) + return ok +} + +// IsInt8Slice gets whether the object contained is a []int8 or not. +func (v *Value) IsInt8Slice() bool { + _, ok := v.data.([]int8) + return ok +} + +// EachInt8 calls the specified callback for each object +// in the []int8. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt8(callback func(int, int8) bool) *Value { + + for index, val := range v.MustInt8Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt8 uses the specified decider function to select items +// from the []int8. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt8(decider func(int, int8) bool) *Value { + + var selected []int8 + + v.EachInt8(func(index int, val int8) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt8 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int8. +func (v *Value) GroupInt8(grouper func(int, int8) string) *Value { + + groups := make(map[string][]int8) + + v.EachInt8(func(index int, val int8) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int8, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt8 uses the specified function to replace each int8s +// by iterating each item. The data in the returned result will be a +// []int8 containing the replaced items. +func (v *Value) ReplaceInt8(replacer func(int, int8) int8) *Value { + + arr := v.MustInt8Slice() + replaced := make([]int8, len(arr)) + + v.EachInt8(func(index int, val int8) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt8 uses the specified collector function to collect a value +// for each of the int8s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt8(collector func(int, int8) interface{}) *Value { + + arr := v.MustInt8Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt8(func(index int, val int8) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int16 (int16 and []int16) + -------------------------------------------------- +*/ + +// Int16 gets the value as a int16, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int16(optionalDefault ...int16) int16 { + if s, ok := v.data.(int16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt16 gets the value as a int16. +// +// Panics if the object is not a int16. +func (v *Value) MustInt16() int16 { + return v.data.(int16) +} + +// Int16Slice gets the value as a []int16, returns the optionalDefault +// value or nil if the value is not a []int16. +func (v *Value) Int16Slice(optionalDefault ...[]int16) []int16 { + if s, ok := v.data.([]int16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt16Slice gets the value as a []int16. +// +// Panics if the object is not a []int16. +func (v *Value) MustInt16Slice() []int16 { + return v.data.([]int16) +} + +// IsInt16 gets whether the object contained is a int16 or not. +func (v *Value) IsInt16() bool { + _, ok := v.data.(int16) + return ok +} + +// IsInt16Slice gets whether the object contained is a []int16 or not. +func (v *Value) IsInt16Slice() bool { + _, ok := v.data.([]int16) + return ok +} + +// EachInt16 calls the specified callback for each object +// in the []int16. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt16(callback func(int, int16) bool) *Value { + + for index, val := range v.MustInt16Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt16 uses the specified decider function to select items +// from the []int16. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt16(decider func(int, int16) bool) *Value { + + var selected []int16 + + v.EachInt16(func(index int, val int16) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt16 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int16. +func (v *Value) GroupInt16(grouper func(int, int16) string) *Value { + + groups := make(map[string][]int16) + + v.EachInt16(func(index int, val int16) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int16, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt16 uses the specified function to replace each int16s +// by iterating each item. The data in the returned result will be a +// []int16 containing the replaced items. +func (v *Value) ReplaceInt16(replacer func(int, int16) int16) *Value { + + arr := v.MustInt16Slice() + replaced := make([]int16, len(arr)) + + v.EachInt16(func(index int, val int16) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt16 uses the specified collector function to collect a value +// for each of the int16s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt16(collector func(int, int16) interface{}) *Value { + + arr := v.MustInt16Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt16(func(index int, val int16) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int32 (int32 and []int32) + -------------------------------------------------- +*/ + +// Int32 gets the value as a int32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int32(optionalDefault ...int32) int32 { + if s, ok := v.data.(int32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt32 gets the value as a int32. +// +// Panics if the object is not a int32. +func (v *Value) MustInt32() int32 { + return v.data.(int32) +} + +// Int32Slice gets the value as a []int32, returns the optionalDefault +// value or nil if the value is not a []int32. +func (v *Value) Int32Slice(optionalDefault ...[]int32) []int32 { + if s, ok := v.data.([]int32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt32Slice gets the value as a []int32. +// +// Panics if the object is not a []int32. +func (v *Value) MustInt32Slice() []int32 { + return v.data.([]int32) +} + +// IsInt32 gets whether the object contained is a int32 or not. +func (v *Value) IsInt32() bool { + _, ok := v.data.(int32) + return ok +} + +// IsInt32Slice gets whether the object contained is a []int32 or not. +func (v *Value) IsInt32Slice() bool { + _, ok := v.data.([]int32) + return ok +} + +// EachInt32 calls the specified callback for each object +// in the []int32. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt32(callback func(int, int32) bool) *Value { + + for index, val := range v.MustInt32Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt32 uses the specified decider function to select items +// from the []int32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt32(decider func(int, int32) bool) *Value { + + var selected []int32 + + v.EachInt32(func(index int, val int32) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int32. +func (v *Value) GroupInt32(grouper func(int, int32) string) *Value { + + groups := make(map[string][]int32) + + v.EachInt32(func(index int, val int32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt32 uses the specified function to replace each int32s +// by iterating each item. The data in the returned result will be a +// []int32 containing the replaced items. +func (v *Value) ReplaceInt32(replacer func(int, int32) int32) *Value { + + arr := v.MustInt32Slice() + replaced := make([]int32, len(arr)) + + v.EachInt32(func(index int, val int32) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt32 uses the specified collector function to collect a value +// for each of the int32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt32(collector func(int, int32) interface{}) *Value { + + arr := v.MustInt32Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt32(func(index int, val int32) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Int64 (int64 and []int64) + -------------------------------------------------- +*/ + +// Int64 gets the value as a int64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int64(optionalDefault ...int64) int64 { + if s, ok := v.data.(int64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt64 gets the value as a int64. +// +// Panics if the object is not a int64. +func (v *Value) MustInt64() int64 { + return v.data.(int64) +} + +// Int64Slice gets the value as a []int64, returns the optionalDefault +// value or nil if the value is not a []int64. +func (v *Value) Int64Slice(optionalDefault ...[]int64) []int64 { + if s, ok := v.data.([]int64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt64Slice gets the value as a []int64. +// +// Panics if the object is not a []int64. +func (v *Value) MustInt64Slice() []int64 { + return v.data.([]int64) +} + +// IsInt64 gets whether the object contained is a int64 or not. +func (v *Value) IsInt64() bool { + _, ok := v.data.(int64) + return ok +} + +// IsInt64Slice gets whether the object contained is a []int64 or not. +func (v *Value) IsInt64Slice() bool { + _, ok := v.data.([]int64) + return ok +} + +// EachInt64 calls the specified callback for each object +// in the []int64. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt64(callback func(int, int64) bool) *Value { + + for index, val := range v.MustInt64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereInt64 uses the specified decider function to select items +// from the []int64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt64(decider func(int, int64) bool) *Value { + + var selected []int64 + + v.EachInt64(func(index int, val int64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupInt64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int64. +func (v *Value) GroupInt64(grouper func(int, int64) string) *Value { + + groups := make(map[string][]int64) + + v.EachInt64(func(index int, val int64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceInt64 uses the specified function to replace each int64s +// by iterating each item. The data in the returned result will be a +// []int64 containing the replaced items. +func (v *Value) ReplaceInt64(replacer func(int, int64) int64) *Value { + + arr := v.MustInt64Slice() + replaced := make([]int64, len(arr)) + + v.EachInt64(func(index int, val int64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectInt64 uses the specified collector function to collect a value +// for each of the int64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt64(collector func(int, int64) interface{}) *Value { + + arr := v.MustInt64Slice() + collected := make([]interface{}, len(arr)) + + v.EachInt64(func(index int, val int64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint (uint and []uint) + -------------------------------------------------- +*/ + +// Uint gets the value as a uint, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint(optionalDefault ...uint) uint { + if s, ok := v.data.(uint); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint gets the value as a uint. +// +// Panics if the object is not a uint. +func (v *Value) MustUint() uint { + return v.data.(uint) +} + +// UintSlice gets the value as a []uint, returns the optionalDefault +// value or nil if the value is not a []uint. +func (v *Value) UintSlice(optionalDefault ...[]uint) []uint { + if s, ok := v.data.([]uint); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUintSlice gets the value as a []uint. +// +// Panics if the object is not a []uint. +func (v *Value) MustUintSlice() []uint { + return v.data.([]uint) +} + +// IsUint gets whether the object contained is a uint or not. +func (v *Value) IsUint() bool { + _, ok := v.data.(uint) + return ok +} + +// IsUintSlice gets whether the object contained is a []uint or not. +func (v *Value) IsUintSlice() bool { + _, ok := v.data.([]uint) + return ok +} + +// EachUint calls the specified callback for each object +// in the []uint. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint(callback func(int, uint) bool) *Value { + + for index, val := range v.MustUintSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint uses the specified decider function to select items +// from the []uint. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint(decider func(int, uint) bool) *Value { + + var selected []uint + + v.EachUint(func(index int, val uint) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint. +func (v *Value) GroupUint(grouper func(int, uint) string) *Value { + + groups := make(map[string][]uint) + + v.EachUint(func(index int, val uint) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint uses the specified function to replace each uints +// by iterating each item. The data in the returned result will be a +// []uint containing the replaced items. +func (v *Value) ReplaceUint(replacer func(int, uint) uint) *Value { + + arr := v.MustUintSlice() + replaced := make([]uint, len(arr)) + + v.EachUint(func(index int, val uint) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint uses the specified collector function to collect a value +// for each of the uints in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint(collector func(int, uint) interface{}) *Value { + + arr := v.MustUintSlice() + collected := make([]interface{}, len(arr)) + + v.EachUint(func(index int, val uint) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint8 (uint8 and []uint8) + -------------------------------------------------- +*/ + +// Uint8 gets the value as a uint8, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint8(optionalDefault ...uint8) uint8 { + if s, ok := v.data.(uint8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint8 gets the value as a uint8. +// +// Panics if the object is not a uint8. +func (v *Value) MustUint8() uint8 { + return v.data.(uint8) +} + +// Uint8Slice gets the value as a []uint8, returns the optionalDefault +// value or nil if the value is not a []uint8. +func (v *Value) Uint8Slice(optionalDefault ...[]uint8) []uint8 { + if s, ok := v.data.([]uint8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint8Slice gets the value as a []uint8. +// +// Panics if the object is not a []uint8. +func (v *Value) MustUint8Slice() []uint8 { + return v.data.([]uint8) +} + +// IsUint8 gets whether the object contained is a uint8 or not. +func (v *Value) IsUint8() bool { + _, ok := v.data.(uint8) + return ok +} + +// IsUint8Slice gets whether the object contained is a []uint8 or not. +func (v *Value) IsUint8Slice() bool { + _, ok := v.data.([]uint8) + return ok +} + +// EachUint8 calls the specified callback for each object +// in the []uint8. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint8(callback func(int, uint8) bool) *Value { + + for index, val := range v.MustUint8Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint8 uses the specified decider function to select items +// from the []uint8. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint8(decider func(int, uint8) bool) *Value { + + var selected []uint8 + + v.EachUint8(func(index int, val uint8) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint8 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint8. +func (v *Value) GroupUint8(grouper func(int, uint8) string) *Value { + + groups := make(map[string][]uint8) + + v.EachUint8(func(index int, val uint8) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint8, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint8 uses the specified function to replace each uint8s +// by iterating each item. The data in the returned result will be a +// []uint8 containing the replaced items. +func (v *Value) ReplaceUint8(replacer func(int, uint8) uint8) *Value { + + arr := v.MustUint8Slice() + replaced := make([]uint8, len(arr)) + + v.EachUint8(func(index int, val uint8) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint8 uses the specified collector function to collect a value +// for each of the uint8s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint8(collector func(int, uint8) interface{}) *Value { + + arr := v.MustUint8Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint8(func(index int, val uint8) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint16 (uint16 and []uint16) + -------------------------------------------------- +*/ + +// Uint16 gets the value as a uint16, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint16(optionalDefault ...uint16) uint16 { + if s, ok := v.data.(uint16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint16 gets the value as a uint16. +// +// Panics if the object is not a uint16. +func (v *Value) MustUint16() uint16 { + return v.data.(uint16) +} + +// Uint16Slice gets the value as a []uint16, returns the optionalDefault +// value or nil if the value is not a []uint16. +func (v *Value) Uint16Slice(optionalDefault ...[]uint16) []uint16 { + if s, ok := v.data.([]uint16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint16Slice gets the value as a []uint16. +// +// Panics if the object is not a []uint16. +func (v *Value) MustUint16Slice() []uint16 { + return v.data.([]uint16) +} + +// IsUint16 gets whether the object contained is a uint16 or not. +func (v *Value) IsUint16() bool { + _, ok := v.data.(uint16) + return ok +} + +// IsUint16Slice gets whether the object contained is a []uint16 or not. +func (v *Value) IsUint16Slice() bool { + _, ok := v.data.([]uint16) + return ok +} + +// EachUint16 calls the specified callback for each object +// in the []uint16. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint16(callback func(int, uint16) bool) *Value { + + for index, val := range v.MustUint16Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint16 uses the specified decider function to select items +// from the []uint16. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint16(decider func(int, uint16) bool) *Value { + + var selected []uint16 + + v.EachUint16(func(index int, val uint16) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint16 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint16. +func (v *Value) GroupUint16(grouper func(int, uint16) string) *Value { + + groups := make(map[string][]uint16) + + v.EachUint16(func(index int, val uint16) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint16, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint16 uses the specified function to replace each uint16s +// by iterating each item. The data in the returned result will be a +// []uint16 containing the replaced items. +func (v *Value) ReplaceUint16(replacer func(int, uint16) uint16) *Value { + + arr := v.MustUint16Slice() + replaced := make([]uint16, len(arr)) + + v.EachUint16(func(index int, val uint16) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint16 uses the specified collector function to collect a value +// for each of the uint16s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint16(collector func(int, uint16) interface{}) *Value { + + arr := v.MustUint16Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint16(func(index int, val uint16) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint32 (uint32 and []uint32) + -------------------------------------------------- +*/ + +// Uint32 gets the value as a uint32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint32(optionalDefault ...uint32) uint32 { + if s, ok := v.data.(uint32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint32 gets the value as a uint32. +// +// Panics if the object is not a uint32. +func (v *Value) MustUint32() uint32 { + return v.data.(uint32) +} + +// Uint32Slice gets the value as a []uint32, returns the optionalDefault +// value or nil if the value is not a []uint32. +func (v *Value) Uint32Slice(optionalDefault ...[]uint32) []uint32 { + if s, ok := v.data.([]uint32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint32Slice gets the value as a []uint32. +// +// Panics if the object is not a []uint32. +func (v *Value) MustUint32Slice() []uint32 { + return v.data.([]uint32) +} + +// IsUint32 gets whether the object contained is a uint32 or not. +func (v *Value) IsUint32() bool { + _, ok := v.data.(uint32) + return ok +} + +// IsUint32Slice gets whether the object contained is a []uint32 or not. +func (v *Value) IsUint32Slice() bool { + _, ok := v.data.([]uint32) + return ok +} + +// EachUint32 calls the specified callback for each object +// in the []uint32. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint32(callback func(int, uint32) bool) *Value { + + for index, val := range v.MustUint32Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint32 uses the specified decider function to select items +// from the []uint32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint32(decider func(int, uint32) bool) *Value { + + var selected []uint32 + + v.EachUint32(func(index int, val uint32) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint32. +func (v *Value) GroupUint32(grouper func(int, uint32) string) *Value { + + groups := make(map[string][]uint32) + + v.EachUint32(func(index int, val uint32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint32 uses the specified function to replace each uint32s +// by iterating each item. The data in the returned result will be a +// []uint32 containing the replaced items. +func (v *Value) ReplaceUint32(replacer func(int, uint32) uint32) *Value { + + arr := v.MustUint32Slice() + replaced := make([]uint32, len(arr)) + + v.EachUint32(func(index int, val uint32) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint32 uses the specified collector function to collect a value +// for each of the uint32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint32(collector func(int, uint32) interface{}) *Value { + + arr := v.MustUint32Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint32(func(index int, val uint32) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uint64 (uint64 and []uint64) + -------------------------------------------------- +*/ + +// Uint64 gets the value as a uint64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint64(optionalDefault ...uint64) uint64 { + if s, ok := v.data.(uint64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint64 gets the value as a uint64. +// +// Panics if the object is not a uint64. +func (v *Value) MustUint64() uint64 { + return v.data.(uint64) +} + +// Uint64Slice gets the value as a []uint64, returns the optionalDefault +// value or nil if the value is not a []uint64. +func (v *Value) Uint64Slice(optionalDefault ...[]uint64) []uint64 { + if s, ok := v.data.([]uint64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint64Slice gets the value as a []uint64. +// +// Panics if the object is not a []uint64. +func (v *Value) MustUint64Slice() []uint64 { + return v.data.([]uint64) +} + +// IsUint64 gets whether the object contained is a uint64 or not. +func (v *Value) IsUint64() bool { + _, ok := v.data.(uint64) + return ok +} + +// IsUint64Slice gets whether the object contained is a []uint64 or not. +func (v *Value) IsUint64Slice() bool { + _, ok := v.data.([]uint64) + return ok +} + +// EachUint64 calls the specified callback for each object +// in the []uint64. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint64(callback func(int, uint64) bool) *Value { + + for index, val := range v.MustUint64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUint64 uses the specified decider function to select items +// from the []uint64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint64(decider func(int, uint64) bool) *Value { + + var selected []uint64 + + v.EachUint64(func(index int, val uint64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUint64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint64. +func (v *Value) GroupUint64(grouper func(int, uint64) string) *Value { + + groups := make(map[string][]uint64) + + v.EachUint64(func(index int, val uint64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUint64 uses the specified function to replace each uint64s +// by iterating each item. The data in the returned result will be a +// []uint64 containing the replaced items. +func (v *Value) ReplaceUint64(replacer func(int, uint64) uint64) *Value { + + arr := v.MustUint64Slice() + replaced := make([]uint64, len(arr)) + + v.EachUint64(func(index int, val uint64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUint64 uses the specified collector function to collect a value +// for each of the uint64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint64(collector func(int, uint64) interface{}) *Value { + + arr := v.MustUint64Slice() + collected := make([]interface{}, len(arr)) + + v.EachUint64(func(index int, val uint64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Uintptr (uintptr and []uintptr) + -------------------------------------------------- +*/ + +// Uintptr gets the value as a uintptr, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uintptr(optionalDefault ...uintptr) uintptr { + if s, ok := v.data.(uintptr); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUintptr gets the value as a uintptr. +// +// Panics if the object is not a uintptr. +func (v *Value) MustUintptr() uintptr { + return v.data.(uintptr) +} + +// UintptrSlice gets the value as a []uintptr, returns the optionalDefault +// value or nil if the value is not a []uintptr. +func (v *Value) UintptrSlice(optionalDefault ...[]uintptr) []uintptr { + if s, ok := v.data.([]uintptr); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUintptrSlice gets the value as a []uintptr. +// +// Panics if the object is not a []uintptr. +func (v *Value) MustUintptrSlice() []uintptr { + return v.data.([]uintptr) +} + +// IsUintptr gets whether the object contained is a uintptr or not. +func (v *Value) IsUintptr() bool { + _, ok := v.data.(uintptr) + return ok +} + +// IsUintptrSlice gets whether the object contained is a []uintptr or not. +func (v *Value) IsUintptrSlice() bool { + _, ok := v.data.([]uintptr) + return ok +} + +// EachUintptr calls the specified callback for each object +// in the []uintptr. +// +// Panics if the object is the wrong type. +func (v *Value) EachUintptr(callback func(int, uintptr) bool) *Value { + + for index, val := range v.MustUintptrSlice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereUintptr uses the specified decider function to select items +// from the []uintptr. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUintptr(decider func(int, uintptr) bool) *Value { + + var selected []uintptr + + v.EachUintptr(func(index int, val uintptr) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupUintptr uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uintptr. +func (v *Value) GroupUintptr(grouper func(int, uintptr) string) *Value { + + groups := make(map[string][]uintptr) + + v.EachUintptr(func(index int, val uintptr) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uintptr, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceUintptr uses the specified function to replace each uintptrs +// by iterating each item. The data in the returned result will be a +// []uintptr containing the replaced items. +func (v *Value) ReplaceUintptr(replacer func(int, uintptr) uintptr) *Value { + + arr := v.MustUintptrSlice() + replaced := make([]uintptr, len(arr)) + + v.EachUintptr(func(index int, val uintptr) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectUintptr uses the specified collector function to collect a value +// for each of the uintptrs in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUintptr(collector func(int, uintptr) interface{}) *Value { + + arr := v.MustUintptrSlice() + collected := make([]interface{}, len(arr)) + + v.EachUintptr(func(index int, val uintptr) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Float32 (float32 and []float32) + -------------------------------------------------- +*/ + +// Float32 gets the value as a float32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Float32(optionalDefault ...float32) float32 { + if s, ok := v.data.(float32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustFloat32 gets the value as a float32. +// +// Panics if the object is not a float32. +func (v *Value) MustFloat32() float32 { + return v.data.(float32) +} + +// Float32Slice gets the value as a []float32, returns the optionalDefault +// value or nil if the value is not a []float32. +func (v *Value) Float32Slice(optionalDefault ...[]float32) []float32 { + if s, ok := v.data.([]float32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustFloat32Slice gets the value as a []float32. +// +// Panics if the object is not a []float32. +func (v *Value) MustFloat32Slice() []float32 { + return v.data.([]float32) +} + +// IsFloat32 gets whether the object contained is a float32 or not. +func (v *Value) IsFloat32() bool { + _, ok := v.data.(float32) + return ok +} + +// IsFloat32Slice gets whether the object contained is a []float32 or not. +func (v *Value) IsFloat32Slice() bool { + _, ok := v.data.([]float32) + return ok +} + +// EachFloat32 calls the specified callback for each object +// in the []float32. +// +// Panics if the object is the wrong type. +func (v *Value) EachFloat32(callback func(int, float32) bool) *Value { + + for index, val := range v.MustFloat32Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereFloat32 uses the specified decider function to select items +// from the []float32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereFloat32(decider func(int, float32) bool) *Value { + + var selected []float32 + + v.EachFloat32(func(index int, val float32) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupFloat32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]float32. +func (v *Value) GroupFloat32(grouper func(int, float32) string) *Value { + + groups := make(map[string][]float32) + + v.EachFloat32(func(index int, val float32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]float32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceFloat32 uses the specified function to replace each float32s +// by iterating each item. The data in the returned result will be a +// []float32 containing the replaced items. +func (v *Value) ReplaceFloat32(replacer func(int, float32) float32) *Value { + + arr := v.MustFloat32Slice() + replaced := make([]float32, len(arr)) + + v.EachFloat32(func(index int, val float32) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectFloat32 uses the specified collector function to collect a value +// for each of the float32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectFloat32(collector func(int, float32) interface{}) *Value { + + arr := v.MustFloat32Slice() + collected := make([]interface{}, len(arr)) + + v.EachFloat32(func(index int, val float32) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Float64 (float64 and []float64) + -------------------------------------------------- +*/ + +// Float64 gets the value as a float64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Float64(optionalDefault ...float64) float64 { + if s, ok := v.data.(float64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustFloat64 gets the value as a float64. +// +// Panics if the object is not a float64. +func (v *Value) MustFloat64() float64 { + return v.data.(float64) +} + +// Float64Slice gets the value as a []float64, returns the optionalDefault +// value or nil if the value is not a []float64. +func (v *Value) Float64Slice(optionalDefault ...[]float64) []float64 { + if s, ok := v.data.([]float64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustFloat64Slice gets the value as a []float64. +// +// Panics if the object is not a []float64. +func (v *Value) MustFloat64Slice() []float64 { + return v.data.([]float64) +} + +// IsFloat64 gets whether the object contained is a float64 or not. +func (v *Value) IsFloat64() bool { + _, ok := v.data.(float64) + return ok +} + +// IsFloat64Slice gets whether the object contained is a []float64 or not. +func (v *Value) IsFloat64Slice() bool { + _, ok := v.data.([]float64) + return ok +} + +// EachFloat64 calls the specified callback for each object +// in the []float64. +// +// Panics if the object is the wrong type. +func (v *Value) EachFloat64(callback func(int, float64) bool) *Value { + + for index, val := range v.MustFloat64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereFloat64 uses the specified decider function to select items +// from the []float64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereFloat64(decider func(int, float64) bool) *Value { + + var selected []float64 + + v.EachFloat64(func(index int, val float64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupFloat64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]float64. +func (v *Value) GroupFloat64(grouper func(int, float64) string) *Value { + + groups := make(map[string][]float64) + + v.EachFloat64(func(index int, val float64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]float64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceFloat64 uses the specified function to replace each float64s +// by iterating each item. The data in the returned result will be a +// []float64 containing the replaced items. +func (v *Value) ReplaceFloat64(replacer func(int, float64) float64) *Value { + + arr := v.MustFloat64Slice() + replaced := make([]float64, len(arr)) + + v.EachFloat64(func(index int, val float64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectFloat64 uses the specified collector function to collect a value +// for each of the float64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectFloat64(collector func(int, float64) interface{}) *Value { + + arr := v.MustFloat64Slice() + collected := make([]interface{}, len(arr)) + + v.EachFloat64(func(index int, val float64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Complex64 (complex64 and []complex64) + -------------------------------------------------- +*/ + +// Complex64 gets the value as a complex64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Complex64(optionalDefault ...complex64) complex64 { + if s, ok := v.data.(complex64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustComplex64 gets the value as a complex64. +// +// Panics if the object is not a complex64. +func (v *Value) MustComplex64() complex64 { + return v.data.(complex64) +} + +// Complex64Slice gets the value as a []complex64, returns the optionalDefault +// value or nil if the value is not a []complex64. +func (v *Value) Complex64Slice(optionalDefault ...[]complex64) []complex64 { + if s, ok := v.data.([]complex64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustComplex64Slice gets the value as a []complex64. +// +// Panics if the object is not a []complex64. +func (v *Value) MustComplex64Slice() []complex64 { + return v.data.([]complex64) +} + +// IsComplex64 gets whether the object contained is a complex64 or not. +func (v *Value) IsComplex64() bool { + _, ok := v.data.(complex64) + return ok +} + +// IsComplex64Slice gets whether the object contained is a []complex64 or not. +func (v *Value) IsComplex64Slice() bool { + _, ok := v.data.([]complex64) + return ok +} + +// EachComplex64 calls the specified callback for each object +// in the []complex64. +// +// Panics if the object is the wrong type. +func (v *Value) EachComplex64(callback func(int, complex64) bool) *Value { + + for index, val := range v.MustComplex64Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereComplex64 uses the specified decider function to select items +// from the []complex64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereComplex64(decider func(int, complex64) bool) *Value { + + var selected []complex64 + + v.EachComplex64(func(index int, val complex64) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupComplex64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]complex64. +func (v *Value) GroupComplex64(grouper func(int, complex64) string) *Value { + + groups := make(map[string][]complex64) + + v.EachComplex64(func(index int, val complex64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]complex64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceComplex64 uses the specified function to replace each complex64s +// by iterating each item. The data in the returned result will be a +// []complex64 containing the replaced items. +func (v *Value) ReplaceComplex64(replacer func(int, complex64) complex64) *Value { + + arr := v.MustComplex64Slice() + replaced := make([]complex64, len(arr)) + + v.EachComplex64(func(index int, val complex64) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectComplex64 uses the specified collector function to collect a value +// for each of the complex64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectComplex64(collector func(int, complex64) interface{}) *Value { + + arr := v.MustComplex64Slice() + collected := make([]interface{}, len(arr)) + + v.EachComplex64(func(index int, val complex64) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} + +/* + Complex128 (complex128 and []complex128) + -------------------------------------------------- +*/ + +// Complex128 gets the value as a complex128, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Complex128(optionalDefault ...complex128) complex128 { + if s, ok := v.data.(complex128); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustComplex128 gets the value as a complex128. +// +// Panics if the object is not a complex128. +func (v *Value) MustComplex128() complex128 { + return v.data.(complex128) +} + +// Complex128Slice gets the value as a []complex128, returns the optionalDefault +// value or nil if the value is not a []complex128. +func (v *Value) Complex128Slice(optionalDefault ...[]complex128) []complex128 { + if s, ok := v.data.([]complex128); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustComplex128Slice gets the value as a []complex128. +// +// Panics if the object is not a []complex128. +func (v *Value) MustComplex128Slice() []complex128 { + return v.data.([]complex128) +} + +// IsComplex128 gets whether the object contained is a complex128 or not. +func (v *Value) IsComplex128() bool { + _, ok := v.data.(complex128) + return ok +} + +// IsComplex128Slice gets whether the object contained is a []complex128 or not. +func (v *Value) IsComplex128Slice() bool { + _, ok := v.data.([]complex128) + return ok +} + +// EachComplex128 calls the specified callback for each object +// in the []complex128. +// +// Panics if the object is the wrong type. +func (v *Value) EachComplex128(callback func(int, complex128) bool) *Value { + + for index, val := range v.MustComplex128Slice() { + carryon := callback(index, val) + if carryon == false { + break + } + } + + return v + +} + +// WhereComplex128 uses the specified decider function to select items +// from the []complex128. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereComplex128(decider func(int, complex128) bool) *Value { + + var selected []complex128 + + v.EachComplex128(func(index int, val complex128) bool { + shouldSelect := decider(index, val) + if shouldSelect == false { + selected = append(selected, val) + } + return true + }) + + return &Value{data: selected} + +} + +// GroupComplex128 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]complex128. +func (v *Value) GroupComplex128(grouper func(int, complex128) string) *Value { + + groups := make(map[string][]complex128) + + v.EachComplex128(func(index int, val complex128) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]complex128, 0) + } + groups[group] = append(groups[group], val) + return true + }) + + return &Value{data: groups} + +} + +// ReplaceComplex128 uses the specified function to replace each complex128s +// by iterating each item. The data in the returned result will be a +// []complex128 containing the replaced items. +func (v *Value) ReplaceComplex128(replacer func(int, complex128) complex128) *Value { + + arr := v.MustComplex128Slice() + replaced := make([]complex128, len(arr)) + + v.EachComplex128(func(index int, val complex128) bool { + replaced[index] = replacer(index, val) + return true + }) + + return &Value{data: replaced} + +} + +// CollectComplex128 uses the specified collector function to collect a value +// for each of the complex128s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectComplex128(collector func(int, complex128) interface{}) *Value { + + arr := v.MustComplex128Slice() + collected := make([]interface{}, len(arr)) + + v.EachComplex128(func(index int, val complex128) bool { + collected[index] = collector(index, val) + return true + }) + + return &Value{data: collected} +} diff --git a/vendor/github.com/stretchr/objx/value.go b/vendor/github.com/stretchr/objx/value.go new file mode 100644 index 0000000000..956a2211d4 --- /dev/null +++ b/vendor/github.com/stretchr/objx/value.go @@ -0,0 +1,56 @@ +package objx + +import ( + "fmt" + "strconv" +) + +// Value provides methods for extracting interface{} data in various +// types. +type Value struct { + // data contains the raw data being managed by this Value + data interface{} +} + +// Data returns the raw data contained by this Value +func (v *Value) Data() interface{} { + return v.data +} + +// String returns the value always as a string +func (v *Value) String() string { + switch { + case v.IsStr(): + return v.Str() + case v.IsBool(): + return strconv.FormatBool(v.Bool()) + case v.IsFloat32(): + return strconv.FormatFloat(float64(v.Float32()), 'f', -1, 32) + case v.IsFloat64(): + return strconv.FormatFloat(v.Float64(), 'f', -1, 64) + case v.IsInt(): + return strconv.FormatInt(int64(v.Int()), 10) + case v.IsInt(): + return strconv.FormatInt(int64(v.Int()), 10) + case v.IsInt8(): + return strconv.FormatInt(int64(v.Int8()), 10) + case v.IsInt16(): + return strconv.FormatInt(int64(v.Int16()), 10) + case v.IsInt32(): + return strconv.FormatInt(int64(v.Int32()), 10) + case v.IsInt64(): + return strconv.FormatInt(v.Int64(), 10) + case v.IsUint(): + return strconv.FormatUint(uint64(v.Uint()), 10) + case v.IsUint8(): + return strconv.FormatUint(uint64(v.Uint8()), 10) + case v.IsUint16(): + return strconv.FormatUint(uint64(v.Uint16()), 10) + case v.IsUint32(): + return strconv.FormatUint(uint64(v.Uint32()), 10) + case v.IsUint64(): + return strconv.FormatUint(v.Uint64(), 10) + } + + return fmt.Sprintf("%#v", v.Data()) +} diff --git a/vendor/github.com/stretchr/testify/LICENCE.txt b/vendor/github.com/stretchr/testify/LICENCE.txt new file mode 100644 index 0000000000..473b670a7c --- /dev/null +++ b/vendor/github.com/stretchr/testify/LICENCE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell + +Please consider promoting this project if you find it useful. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE new file mode 100644 index 0000000000..473b670a7c --- /dev/null +++ b/vendor/github.com/stretchr/testify/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell + +Please consider promoting this project if you find it useful. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go new file mode 100644 index 0000000000..e6a796046c --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -0,0 +1,387 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND +*/ + +package assert + +import ( + + http "net/http" + url "net/url" + time "time" +) + + +// Condition uses a Comparison to assert a complex condition. +func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { + return Condition(a.t, comp, msgAndArgs...) +} + + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") +// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + return Contains(a.t, s, contains, msgAndArgs...) +} + + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Empty(obj) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + return Empty(a.t, object, msgAndArgs...) +} + + +// Equal asserts that two objects are equal. +// +// a.Equal(123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return Equal(a.t, expected, actual, msgAndArgs...) +} + + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + return EqualError(a.t, theError, errString, msgAndArgs...) +} + + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return EqualValues(a.t, expected, actual, msgAndArgs...) +} + + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Error(err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { + return Error(a.t, err, msgAndArgs...) +} + + +// Exactly asserts that two objects are equal is value and type. +// +// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return Exactly(a.t, expected, actual, msgAndArgs...) +} + + +// Fail reports a failure through +func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + return Fail(a.t, failureMessage, msgAndArgs...) +} + + +// FailNow fails test +func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { + return FailNow(a.t, failureMessage, msgAndArgs...) +} + + +// False asserts that the specified value is false. +// +// a.False(myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { + return False(a.t, value, msgAndArgs...) +} + + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { + return HTTPBodyContains(a.t, handler, method, url, values, str) +} + + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { + return HTTPBodyNotContains(a.t, handler, method, url, values, str) +} + + +// HTTPError asserts that a specified handler returns an error status code. +// +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool { + return HTTPError(a.t, handler, method, url, values) +} + + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool { + return HTTPRedirect(a.t, handler, method, url, values) +} + + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool { + return HTTPSuccess(a.t, handler, method, url, values) +} + + +// Implements asserts that an object is implemented by the specified interface. +// +// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") +func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + return Implements(a.t, interfaceObject, object, msgAndArgs...) +} + + +// InDelta asserts that the two numerals are within delta of each other. +// +// a.InDelta(math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InDelta(a.t, expected, actual, delta, msgAndArgs...) +} + + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) +} + + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) +} + + +// InEpsilonSlice is the same as InEpsilon, except it compares two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InEpsilonSlice(a.t, expected, actual, delta, msgAndArgs...) +} + + +// IsType asserts that the specified objects are of the same type. +func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + return IsType(a.t, expectedType, object, msgAndArgs...) +} + + +// JSONEq asserts that two JSON strings are equivalent. +// +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { + return JSONEq(a.t, expected, actual, msgAndArgs...) +} + + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// a.Len(mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + return Len(a.t, object, length, msgAndArgs...) +} + + +// Nil asserts that the specified object is nil. +// +// a.Nil(err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + return Nil(a.t, object, msgAndArgs...) +} + + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { + return NoError(a.t, err, msgAndArgs...) +} + + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + return NotContains(a.t, s, contains, msgAndArgs...) +} + + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + return NotEmpty(a.t, object, msgAndArgs...) +} + + +// NotEqual asserts that the specified values are NOT equal. +// +// a.NotEqual(obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return NotEqual(a.t, expected, actual, msgAndArgs...) +} + + +// NotNil asserts that the specified object is not nil. +// +// a.NotNil(err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + return NotNil(a.t, object, msgAndArgs...) +} + + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanics(func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + return NotPanics(a.t, f, msgAndArgs...) +} + + +// NotRegexp asserts that a specified regexp does not match a string. +// +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + return NotRegexp(a.t, rx, str, msgAndArgs...) +} + + +// NotZero asserts that i is not the zero value for its type and returns the truth. +func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { + return NotZero(a.t, i, msgAndArgs...) +} + + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panics(func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + return Panics(a.t, f, msgAndArgs...) +} + + +// Regexp asserts that a specified regexp matches a string. +// +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + return Regexp(a.t, rx, str, msgAndArgs...) +} + + +// True asserts that the specified value is true. +// +// a.True(myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { + return True(a.t, value, msgAndArgs...) +} + + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) +} + + +// Zero asserts that i is the zero value for its type and returns the truth. +func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { + return Zero(a.t, i, msgAndArgs...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl new file mode 100644 index 0000000000..99f9acfbba --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl @@ -0,0 +1,4 @@ +{{.CommentWithoutT "a"}} +func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { + return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go new file mode 100644 index 0000000000..d7c16c5903 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -0,0 +1,1004 @@ +package assert + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "math" + "reflect" + "regexp" + "runtime" + "strings" + "time" + "unicode" + "unicode/utf8" + + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" +) + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +// Comparison a custom function that returns true on success and false on failure +type Comparison func() (success bool) + +/* + Helper functions +*/ + +// ObjectsAreEqual determines if two objects are considered equal. +// +// This function does no assertion of any kind. +func ObjectsAreEqual(expected, actual interface{}) bool { + + if expected == nil || actual == nil { + return expected == actual + } + + return reflect.DeepEqual(expected, actual) + +} + +// ObjectsAreEqualValues gets whether two objects are equal, or if their +// values are equal. +func ObjectsAreEqualValues(expected, actual interface{}) bool { + if ObjectsAreEqual(expected, actual) { + return true + } + + actualType := reflect.TypeOf(actual) + if actualType == nil { + return false + } + expectedValue := reflect.ValueOf(expected) + if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { + // Attempt comparison after type conversion + return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) + } + + return false +} + +/* CallerInfo is necessary because the assert functions use the testing object +internally, causing it to print the file:line of the assert method, rather than where +the problem actually occured in calling code.*/ + +// CallerInfo returns an array of strings containing the file and line number +// of each stack frame leading from the current test to the assert call that +// failed. +func CallerInfo() []string { + + pc := uintptr(0) + file := "" + line := 0 + ok := false + name := "" + + callers := []string{} + for i := 0; ; i++ { + pc, file, line, ok = runtime.Caller(i) + if !ok { + return nil + } + + // This is a huge edge case, but it will panic if this is the case, see #180 + if file == "" { + break + } + + parts := strings.Split(file, "/") + dir := parts[len(parts)-2] + file = parts[len(parts)-1] + if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { + callers = append(callers, fmt.Sprintf("%s:%d", file, line)) + } + + f := runtime.FuncForPC(pc) + if f == nil { + break + } + name = f.Name() + // Drop the package + segments := strings.Split(name, ".") + name = segments[len(segments)-1] + if isTest(name, "Test") || + isTest(name, "Benchmark") || + isTest(name, "Example") { + break + } + } + + return callers +} + +// Stolen from the `go test` tool. +// isTest tells whether name looks like a test (or benchmark, according to prefix). +// It is a Test (say) if there is a character after Test that is not a lower-case letter. +// We don't want TesticularCancer. +func isTest(name, prefix string) bool { + if !strings.HasPrefix(name, prefix) { + return false + } + if len(name) == len(prefix) { // "Test" is ok + return true + } + rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) + return !unicode.IsLower(rune) +} + +// getWhitespaceString returns a string that is long enough to overwrite the default +// output from the go testing framework. +func getWhitespaceString() string { + + _, file, line, ok := runtime.Caller(1) + if !ok { + return "" + } + parts := strings.Split(file, "/") + file = parts[len(parts)-1] + + return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) + +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + return msgAndArgs[0].(string) + } + if len(msgAndArgs) > 1 { + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) + } + return "" +} + +// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's +// test printing (see inner comment for specifics) +func indentMessageLines(message string, tabs int) string { + outBuf := new(bytes.Buffer) + + for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { + if i != 0 { + outBuf.WriteRune('\n') + } + for ii := 0; ii < tabs; ii++ { + outBuf.WriteRune('\t') + // Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter + // by 1 prematurely. + if ii == 0 && i > 0 { + ii++ + } + } + outBuf.WriteString(scanner.Text()) + } + + return outBuf.String() +} + +type failNower interface { + FailNow() +} + +// FailNow fails test +func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + Fail(t, failureMessage, msgAndArgs...) + + // We cannot extend TestingT with FailNow() and + // maintain backwards compatibility, so we fallback + // to panicking when FailNow is not available in + // TestingT. + // See issue #263 + + if t, ok := t.(failNower); ok { + t.FailNow() + } else { + panic("test failed and t is missing `FailNow()`") + } + return false +} + +// Fail reports a failure through +func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + + errorTrace := strings.Join(CallerInfo(), "\n\r\t\t\t") + if len(message) > 0 { + t.Errorf("\r%s\r\tError Trace:\t%s\n"+ + "\r\tError:%s\n"+ + "\r\tMessages:\t%s\n\r", + getWhitespaceString(), + errorTrace, + indentMessageLines(failureMessage, 2), + message) + } else { + t.Errorf("\r%s\r\tError Trace:\t%s\n"+ + "\r\tError:%s\n\r", + getWhitespaceString(), + errorTrace, + indentMessageLines(failureMessage, 2)) + } + + return false +} + +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") +func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + + interfaceType := reflect.TypeOf(interfaceObject).Elem() + + if !reflect.TypeOf(object).Implements(interfaceType) { + return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) + } + + return true + +} + +// IsType asserts that the specified objects are of the same type. +func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { + return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) + } + + return true +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqual(expected, actual) { + diff := diff(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)%s", expected, actual, diff), msgAndArgs...) + } + + return true + +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqualValues(expected, actual) { + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)", expected, actual), msgAndArgs...) + } + + return true + +} + +// Exactly asserts that two objects are equal is value and type. +// +// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...) + } + + return Equal(t, expected, actual, msgAndArgs...) + +} + +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(t, err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if !isNil(object) { + return true + } + return Fail(t, "Expected value not to be nil.", msgAndArgs...) +} + +// isNil checks if a specified object is nil or not, without Failing. +func isNil(object interface{}) bool { + if object == nil { + return true + } + + value := reflect.ValueOf(object) + kind := value.Kind() + if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + return true + } + + return false +} + +// Nil asserts that the specified object is nil. +// +// assert.Nil(t, err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if isNil(object) { + return true + } + return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) +} + +var numericZeros = []interface{}{ + int(0), + int8(0), + int16(0), + int32(0), + int64(0), + uint(0), + uint8(0), + uint16(0), + uint32(0), + uint64(0), + float32(0), + float64(0), +} + +// isEmpty gets whether the specified object is considered empty or not. +func isEmpty(object interface{}) bool { + + if object == nil { + return true + } else if object == "" { + return true + } else if object == false { + return true + } + + for _, v := range numericZeros { + if object == v { + return true + } + } + + objValue := reflect.ValueOf(object) + + switch objValue.Kind() { + case reflect.Map: + fallthrough + case reflect.Slice, reflect.Chan: + { + return (objValue.Len() == 0) + } + case reflect.Struct: + switch object.(type) { + case time.Time: + return object.(time.Time).IsZero() + } + case reflect.Ptr: + { + if objValue.IsNil() { + return true + } + switch object.(type) { + case *time.Time: + return object.(*time.Time).IsZero() + default: + return false + } + } + } + return false +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Empty(t, obj) +// +// Returns whether the assertion was successful (true) or not (false). +func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + pass := isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + pass := !isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// getLen try to get length of object. +// return (false, 0) if impossible. +func getLen(x interface{}) (ok bool, length int) { + v := reflect.ValueOf(x) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + return true, v.Len() +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(t, mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { + ok, l := getLen(object) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) + } + + if l != length { + return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + } + return true +} + +// True asserts that the specified value is true. +// +// assert.True(t, myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { + + if value != true { + return Fail(t, "Should be true", msgAndArgs...) + } + + return true + +} + +// False asserts that the specified value is false. +// +// assert.False(t, myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { + + if value != false { + return Fail(t, "Should be false", msgAndArgs...) + } + + return true + +} + +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if ObjectsAreEqual(expected, actual) { + return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + } + + return true + +} + +// containsElement try loop over the list check if the list includes the element. +// return (false, false) if impossible. +// return (true, false) if element was not found. +// return (true, true) if element was found. +func includeElement(list interface{}, element interface{}) (ok, found bool) { + + listValue := reflect.ValueOf(list) + elementValue := reflect.ValueOf(element) + defer func() { + if e := recover(); e != nil { + ok = false + found = false + } + }() + + if reflect.TypeOf(list).Kind() == reflect.String { + return true, strings.Contains(listValue.String(), elementValue.String()) + } + + if reflect.TypeOf(list).Kind() == reflect.Map { + mapKeys := listValue.MapKeys() + for i := 0; i < len(mapKeys); i++ { + if ObjectsAreEqual(mapKeys[i].Interface(), element) { + return true, true + } + } + return true, false + } + + for i := 0; i < listValue.Len(); i++ { + if ObjectsAreEqual(listValue.Index(i).Interface(), element) { + return true, true + } + } + return true, false + +} + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") +// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") +// +// Returns whether the assertion was successful (true) or not (false). +func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if found { + return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// Condition uses a Comparison to assert a complex condition. +func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { + result := comp() + if !result { + Fail(t, "Condition failed!", msgAndArgs...) + } + return result +} + +// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics +// methods, and represents a simple func that takes no arguments, and returns nothing. +type PanicTestFunc func() + +// didPanic returns true if the function passed to it panics. Otherwise, it returns false. +func didPanic(f PanicTestFunc) (bool, interface{}) { + + didPanic := false + var message interface{} + func() { + + defer func() { + if message = recover(); message != nil { + didPanic = true + } + }() + + // call the target function + f() + + }() + + return didPanic, message + +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(t, func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(t, func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + if funcDidPanic, panicValue := didPanic(f); funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + + dt := expected.Sub(actual) + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +func toFloat(x interface{}) (float64, bool) { + var xf float64 + xok := true + + switch xn := x.(type) { + case uint8: + xf = float64(xn) + case uint16: + xf = float64(xn) + case uint32: + xf = float64(xn) + case uint64: + xf = float64(xn) + case int: + xf = float64(xn) + case int8: + xf = float64(xn) + case int16: + xf = float64(xn) + case int32: + xf = float64(xn) + case int64: + xf = float64(xn) + case float32: + xf = float64(xn) + case float64: + xf = float64(xn) + default: + xok = false + } + + return xf, xok +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + + af, aok := toFloat(expected) + bf, bok := toFloat(actual) + + if !aok || !bok { + return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) + } + + if math.IsNaN(af) { + return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...) + } + + if math.IsNaN(bf) { + return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) + } + + dt := af - bf + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta) + if !result { + return result + } + } + + return true +} + +func calcRelativeError(expected, actual interface{}) (float64, error) { + af, aok := toFloat(expected) + if !aok { + return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) + } + if af == 0 { + return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") + } + bf, bok := toFloat(actual) + if !bok { + return 0, fmt.Errorf("expected value %q cannot be converted to float", actual) + } + + return math.Abs(af-bf) / math.Abs(af), nil +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + actualEpsilon, err := calcRelativeError(expected, actual) + if err != nil { + return Fail(t, err.Error(), msgAndArgs...) + } + if actualEpsilon > epsilon { + return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ + " < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...) + } + + return true +} + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) + if !result { + return result + } + } + + return true +} + +/* + Errors +*/ + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { + if isNil(err) { + return true + } + + return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...) +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + return NotNil(t, err, "An error is expected but got nil. %s", message) + +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + if !NotNil(t, theError, "An error is expected but got nil. %s", message) { + return false + } + s := "An error with value \"%s\" is expected but got \"%s\". %s" + return Equal(t, errString, theError.Error(), + s, errString, theError.Error(), message) +} + +// matchRegexp return true if a specified regexp matches a string. +func matchRegexp(rx interface{}, str interface{}) bool { + + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr + } else { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + + return (r.FindStringIndex(fmt.Sprint(str)) != nil) + +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + + match := matchRegexp(rx, str) + + if !match { + Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) + } + + return match +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + match := matchRegexp(rx, str) + + if match { + Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) + } + + return !match + +} + +// Zero asserts that i is the zero value for its type and returns the truth. +func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// NotZero asserts that i is not the zero value for its type and returns the truth. +func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// JSONEq asserts that two JSON strings are equivalent. +// +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Returns whether the assertion was successful (true) or not (false). +func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { + var expectedJSONAsInterface, actualJSONAsInterface interface{} + + if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) + } + + if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) + } + + return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) +} + +func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { + t := reflect.TypeOf(v) + k := t.Kind() + + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() + } + return t, k +} + +// diff returns a diff of both values as long as both are of the same type and +// are a struct, map, slice or array. Otherwise it returns an empty string. +func diff(expected interface{}, actual interface{}) string { + if expected == nil || actual == nil { + return "" + } + + et, ek := typeAndKind(expected) + at, _ := typeAndKind(actual) + + if et != at { + return "" + } + + if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array { + return "" + } + + spew.Config.SortKeys = true + e := spew.Sdump(expected) + a := spew.Sdump(actual) + + diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(e), + B: difflib.SplitLines(a), + FromFile: "Expected", + FromDate: "", + ToFile: "Actual", + ToDate: "", + Context: 1, + }) + + return "\n\nDiff:\n" + diff +} diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go new file mode 100644 index 0000000000..c9dccc4d6c --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -0,0 +1,45 @@ +// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. +// +// Example Usage +// +// The following is a complete example using assert in a standard test function: +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } +// +// if you assert many times, use the format below: +// +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// assert := assert.New(t) +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(a, b, "The two words should be the same.") +// } +// +// Assertions +// +// Assertions allow you to easily write test code, and are global funcs in the `assert` package. +// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// testing framework. This allows the assertion funcs to write the failings and other details to +// the correct place. +// +// Every assertion function also takes an optional string message as the final argument, +// allowing custom error messages to be appended to the message the assertion method outputs. +package assert diff --git a/vendor/github.com/stretchr/testify/assert/errors.go b/vendor/github.com/stretchr/testify/assert/errors.go new file mode 100644 index 0000000000..ac9dc9d1d6 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/errors.go @@ -0,0 +1,10 @@ +package assert + +import ( + "errors" +) + +// AnError is an error instance useful for testing. If the code does not care +// about error specifics, and only needs to return the error for example, this +// error should be used to make the test code more readable. +var AnError = errors.New("assert.AnError general error for testing") diff --git a/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/vendor/github.com/stretchr/testify/assert/forward_assertions.go new file mode 100644 index 0000000000..b867e95ea5 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/forward_assertions.go @@ -0,0 +1,16 @@ +package assert + +// Assertions provides assertion methods around the +// TestingT interface. +type Assertions struct { + t TestingT +} + +// New makes a new Assertions object for the specified TestingT. +func New(t TestingT) *Assertions { + return &Assertions{ + t: t, + } +} + +//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go new file mode 100644 index 0000000000..e1b9442b5a --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -0,0 +1,106 @@ +package assert + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" +) + +// httpCode is a helper that returns HTTP code of the response. It returns -1 +// if building a new request fails. +func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) + if err != nil { + return -1 + } + handler(w, req) + return w.Code +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { + code := httpCode(handler, method, url, values) + if code == -1 { + return false + } + return code >= http.StatusOK && code <= http.StatusPartialContent +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { + code := httpCode(handler, method, url, values) + if code == -1 { + return false + } + return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { + code := httpCode(handler, method, url, values) + if code == -1 { + return false + } + return code >= http.StatusBadRequest +} + +// HTTPBody is a helper that returns HTTP body of the response. It returns +// empty string if building a new request fails. +func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) + if err != nil { + return "" + } + handler(w, req) + return w.Body.String() +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if !contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return contains +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if contains { + Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) + } + + return !contains +} diff --git a/vendor/github.com/stretchr/testify/mock/doc.go b/vendor/github.com/stretchr/testify/mock/doc.go new file mode 100644 index 0000000000..7324128ef1 --- /dev/null +++ b/vendor/github.com/stretchr/testify/mock/doc.go @@ -0,0 +1,44 @@ +// Package mock provides a system by which it is possible to mock your objects +// and verify calls are happening as expected. +// +// Example Usage +// +// The mock package provides an object, Mock, that tracks activity on another object. It is usually +// embedded into a test object as shown below: +// +// type MyTestObject struct { +// // add a Mock object instance +// mock.Mock +// +// // other fields go here as normal +// } +// +// When implementing the methods of an interface, you wire your functions up +// to call the Mock.Called(args...) method, and return the appropriate values. +// +// For example, to mock a method that saves the name and age of a person and returns +// the year of their birth or an error, you might write this: +// +// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) { +// args := o.Called(firstname, lastname, age) +// return args.Int(0), args.Error(1) +// } +// +// The Int, Error and Bool methods are examples of strongly typed getters that take the argument +// index position. Given this argument list: +// +// (12, true, "Something") +// +// You could read them out strongly typed like this: +// +// args.Int(0) +// args.Bool(1) +// args.String(2) +// +// For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion: +// +// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine) +// +// This may cause a panic if the object you are getting is nil (the type assertion will fail), in those +// cases you should check for nil first. +package mock diff --git a/vendor/github.com/stretchr/testify/mock/mock.go b/vendor/github.com/stretchr/testify/mock/mock.go new file mode 100644 index 0000000000..03cc0f6bf3 --- /dev/null +++ b/vendor/github.com/stretchr/testify/mock/mock.go @@ -0,0 +1,683 @@ +package mock + +import ( + "fmt" + "reflect" + "regexp" + "runtime" + "strings" + "sync" + "time" + + "github.com/stretchr/objx" + "github.com/stretchr/testify/assert" +) + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Logf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) + FailNow() +} + +/* + Call +*/ + +// Call represents a method call and is used for setting expectations, +// as well as recording activity. +type Call struct { + Parent *Mock + + // The name of the method that was or will be called. + Method string + + // Holds the arguments of the method. + Arguments Arguments + + // Holds the arguments that should be returned when + // this method is called. + ReturnArguments Arguments + + // The number of times to return the return arguments when setting + // expectations. 0 means to always return the value. + Repeatability int + + // Holds a channel that will be used to block the Return until it either + // recieves a message or is closed. nil means it returns immediately. + WaitFor <-chan time.Time + + // Holds a handler used to manipulate arguments content that are passed by + // reference. It's useful when mocking methods such as unmarshalers or + // decoders. + RunFn func(Arguments) +} + +func newCall(parent *Mock, methodName string, methodArguments ...interface{}) *Call { + return &Call{ + Parent: parent, + Method: methodName, + Arguments: methodArguments, + ReturnArguments: make([]interface{}, 0), + Repeatability: 0, + WaitFor: nil, + RunFn: nil, + } +} + +func (c *Call) lock() { + c.Parent.mutex.Lock() +} + +func (c *Call) unlock() { + c.Parent.mutex.Unlock() +} + +// Return specifies the return arguments for the expectation. +// +// Mock.On("DoSomething").Return(errors.New("failed")) +func (c *Call) Return(returnArguments ...interface{}) *Call { + c.lock() + defer c.unlock() + + c.ReturnArguments = returnArguments + + return c +} + +// Once indicates that that the mock should only return the value once. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once() +func (c *Call) Once() *Call { + return c.Times(1) +} + +// Twice indicates that that the mock should only return the value twice. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice() +func (c *Call) Twice() *Call { + return c.Times(2) +} + +// Times indicates that that the mock should only return the indicated number +// of times. +// +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5) +func (c *Call) Times(i int) *Call { + c.lock() + defer c.unlock() + c.Repeatability = i + return c +} + +// WaitUntil sets the channel that will block the mock's return until its closed +// or a message is received. +// +// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second)) +func (c *Call) WaitUntil(w <-chan time.Time) *Call { + c.lock() + defer c.unlock() + c.WaitFor = w + return c +} + +// After sets how long to block until the call returns +// +// Mock.On("MyMethod", arg1, arg2).After(time.Second) +func (c *Call) After(d time.Duration) *Call { + return c.WaitUntil(time.After(d)) +} + +// Run sets a handler to be called before returning. It can be used when +// mocking a method such as unmarshalers that takes a pointer to a struct and +// sets properties in such struct +// +// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}").Return().Run(func(args Arguments) { +// arg := args.Get(0).(*map[string]interface{}) +// arg["foo"] = "bar" +// }) +func (c *Call) Run(fn func(Arguments)) *Call { + c.lock() + defer c.unlock() + c.RunFn = fn + return c +} + +// On chains a new expectation description onto the mocked interface. This +// allows syntax like. +// +// Mock. +// On("MyMethod", 1).Return(nil). +// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error")) +func (c *Call) On(methodName string, arguments ...interface{}) *Call { + return c.Parent.On(methodName, arguments...) +} + +// Mock is the workhorse used to track activity on another object. +// For an example of its usage, refer to the "Example Usage" section at the top +// of this document. +type Mock struct { + // Represents the calls that are expected of + // an object. + ExpectedCalls []*Call + + // Holds the calls that were made to this mocked object. + Calls []Call + + // TestData holds any data that might be useful for testing. Testify ignores + // this data completely allowing you to do whatever you like with it. + testData objx.Map + + mutex sync.Mutex +} + +// TestData holds any data that might be useful for testing. Testify ignores +// this data completely allowing you to do whatever you like with it. +func (m *Mock) TestData() objx.Map { + + if m.testData == nil { + m.testData = make(objx.Map) + } + + return m.testData +} + +/* + Setting expectations +*/ + +// On starts a description of an expectation of the specified method +// being called. +// +// Mock.On("MyMethod", arg1, arg2) +func (m *Mock) On(methodName string, arguments ...interface{}) *Call { + for _, arg := range arguments { + if v := reflect.ValueOf(arg); v.Kind() == reflect.Func { + panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg)) + } + } + + m.mutex.Lock() + defer m.mutex.Unlock() + c := newCall(m, methodName, arguments...) + m.ExpectedCalls = append(m.ExpectedCalls, c) + return c +} + +// /* +// Recording and responding to activity +// */ + +func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) { + m.mutex.Lock() + defer m.mutex.Unlock() + for i, call := range m.ExpectedCalls { + if call.Method == method && call.Repeatability > -1 { + + _, diffCount := call.Arguments.Diff(arguments) + if diffCount == 0 { + return i, call + } + + } + } + return -1, nil +} + +func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) { + diffCount := 0 + var closestCall *Call + + for _, call := range m.expectedCalls() { + if call.Method == method { + + _, tempDiffCount := call.Arguments.Diff(arguments) + if tempDiffCount < diffCount || diffCount == 0 { + diffCount = tempDiffCount + closestCall = call + } + + } + } + + if closestCall == nil { + return false, nil + } + + return true, closestCall +} + +func callString(method string, arguments Arguments, includeArgumentValues bool) string { + + var argValsString string + if includeArgumentValues { + var argVals []string + for argIndex, arg := range arguments { + argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg)) + } + argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t")) + } + + return fmt.Sprintf("%s(%s)%s", method, arguments.String(), argValsString) +} + +// Called tells the mock object that a method has been called, and gets an array +// of arguments to return. Panics if the call is unexpected (i.e. not preceeded by +// appropriate .On .Return() calls) +// If Call.WaitFor is set, blocks until the channel is closed or receives a message. +func (m *Mock) Called(arguments ...interface{}) Arguments { + // get the calling function's name + pc, _, _, ok := runtime.Caller(1) + if !ok { + panic("Couldn't get the caller information") + } + functionPath := runtime.FuncForPC(pc).Name() + //Next four lines are required to use GCCGO function naming conventions. + //For Ex: github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock + //uses inteface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree + //With GCCGO we need to remove interface information starting from pN

. + re := regexp.MustCompile("\\.pN\\d+_") + if re.MatchString(functionPath) { + functionPath = re.Split(functionPath, -1)[0] + } + parts := strings.Split(functionPath, ".") + functionName := parts[len(parts)-1] + + found, call := m.findExpectedCall(functionName, arguments...) + + if found < 0 { + // we have to fail here - because we don't know what to do + // as the return arguments. This is because: + // + // a) this is a totally unexpected call to this method, + // b) the arguments are not what was expected, or + // c) the developer has forgotten to add an accompanying On...Return pair. + + closestFound, closestCall := m.findClosestCall(functionName, arguments...) + + if closestFound { + panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n", callString(functionName, arguments, true), callString(functionName, closestCall.Arguments, true))) + } else { + panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", functionName, functionName, callString(functionName, arguments, true), assert.CallerInfo())) + } + } else { + m.mutex.Lock() + switch { + case call.Repeatability == 1: + call.Repeatability = -1 + + case call.Repeatability > 1: + call.Repeatability-- + } + m.mutex.Unlock() + } + + // add the call + m.mutex.Lock() + m.Calls = append(m.Calls, *newCall(m, functionName, arguments...)) + m.mutex.Unlock() + + // block if specified + if call.WaitFor != nil { + <-call.WaitFor + } + + if call.RunFn != nil { + call.RunFn(arguments) + } + + return call.ReturnArguments +} + +/* + Assertions +*/ + +// AssertExpectationsForObjects asserts that everything specified with On and Return +// of the specified objects was in fact called as expected. +// +// Calls may have occurred in any order. +func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { + var success = true + for _, obj := range testObjects { + mockObj := obj.(Mock) + success = success && mockObj.AssertExpectations(t) + } + return success +} + +// AssertExpectations asserts that everything specified with On and Return was +// in fact called as expected. Calls may have occurred in any order. +func (m *Mock) AssertExpectations(t TestingT) bool { + var somethingMissing bool + var failedExpectations int + + // iterate through each expectation + expectedCalls := m.expectedCalls() + for _, expectedCall := range expectedCalls { + if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) { + somethingMissing = true + failedExpectations++ + t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String()) + } else { + m.mutex.Lock() + if expectedCall.Repeatability > 0 { + somethingMissing = true + failedExpectations++ + } else { + t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String()) + } + m.mutex.Unlock() + } + } + + if somethingMissing { + t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(expectedCalls)-failedExpectations, len(expectedCalls), failedExpectations, assert.CallerInfo()) + } + + return !somethingMissing +} + +// AssertNumberOfCalls asserts that the method was called expectedCalls times. +func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool { + var actualCalls int + for _, call := range m.calls() { + if call.Method == methodName { + actualCalls++ + } + } + return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls)) +} + +// AssertCalled asserts that the method was called. +func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool { + if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) { + t.Logf("%v", m.expectedCalls()) + return false + } + return true +} + +// AssertNotCalled asserts that the method was not called. +func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool { + if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) { + t.Logf("%v", m.expectedCalls()) + return false + } + return true +} + +func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool { + for _, call := range m.calls() { + if call.Method == methodName { + + _, differences := Arguments(expected).Diff(call.Arguments) + + if differences == 0 { + // found the expected call + return true + } + + } + } + // we didn't find the expected call + return false +} + +func (m *Mock) expectedCalls() []*Call { + m.mutex.Lock() + defer m.mutex.Unlock() + return append([]*Call{}, m.ExpectedCalls...) +} + +func (m *Mock) calls() []Call { + m.mutex.Lock() + defer m.mutex.Unlock() + return append([]Call{}, m.Calls...) +} + +/* + Arguments +*/ + +// Arguments holds an array of method arguments or return values. +type Arguments []interface{} + +const ( + // Anything is used in Diff and Assert when the argument being tested + // shouldn't be taken into consideration. + Anything string = "mock.Anything" +) + +// AnythingOfTypeArgument is a string that contains the type of an argument +// for use when type checking. Used in Diff and Assert. +type AnythingOfTypeArgument string + +// AnythingOfType returns an AnythingOfTypeArgument object containing the +// name of the type to check for. Used in Diff and Assert. +// +// For example: +// Assert(t, AnythingOfType("string"), AnythingOfType("int")) +func AnythingOfType(t string) AnythingOfTypeArgument { + return AnythingOfTypeArgument(t) +} + +// argumentMatcher performs custom argument matching, returning whether or +// not the argument is matched by the expectation fixture function. +type argumentMatcher struct { + // fn is a function which accepts one argument, and returns a bool. + fn reflect.Value +} + +func (f argumentMatcher) Matches(argument interface{}) bool { + expectType := f.fn.Type().In(0) + + if reflect.TypeOf(argument).AssignableTo(expectType) { + result := f.fn.Call([]reflect.Value{reflect.ValueOf(argument)}) + return result[0].Bool() + } + return false +} + +func (f argumentMatcher) String() string { + return fmt.Sprintf("func(%s) bool", f.fn.Type().In(0).Name()) +} + +// MatchedBy can be used to match a mock call based on only certain properties +// from a complex struct or some calculation. It takes a function that will be +// evaluated with the called argument and will return true when there's a match +// and false otherwise. +// +// Example: +// m.On("Do", func(req *http.Request) bool { return req.Host == "example.com" }) +// +// |fn|, must be a function accepting a single argument (of the expected type) +// which returns a bool. If |fn| doesn't match the required signature, +// MathedBy() panics. +func MatchedBy(fn interface{}) argumentMatcher { + fnType := reflect.TypeOf(fn) + + if fnType.Kind() != reflect.Func { + panic(fmt.Sprintf("assert: arguments: %s is not a func", fn)) + } + if fnType.NumIn() != 1 { + panic(fmt.Sprintf("assert: arguments: %s does not take exactly one argument", fn)) + } + if fnType.NumOut() != 1 || fnType.Out(0).Kind() != reflect.Bool { + panic(fmt.Sprintf("assert: arguments: %s does not return a bool", fn)) + } + + return argumentMatcher{fn: reflect.ValueOf(fn)} +} + +// Get Returns the argument at the specified index. +func (args Arguments) Get(index int) interface{} { + if index+1 > len(args) { + panic(fmt.Sprintf("assert: arguments: Cannot call Get(%d) because there are %d argument(s).", index, len(args))) + } + return args[index] +} + +// Is gets whether the objects match the arguments specified. +func (args Arguments) Is(objects ...interface{}) bool { + for i, obj := range args { + if obj != objects[i] { + return false + } + } + return true +} + +// Diff gets a string describing the differences between the arguments +// and the specified objects. +// +// Returns the diff string and number of differences found. +func (args Arguments) Diff(objects []interface{}) (string, int) { + + var output = "\n" + var differences int + + var maxArgCount = len(args) + if len(objects) > maxArgCount { + maxArgCount = len(objects) + } + + for i := 0; i < maxArgCount; i++ { + var actual, expected interface{} + + if len(objects) <= i { + actual = "(Missing)" + } else { + actual = objects[i] + } + + if len(args) <= i { + expected = "(Missing)" + } else { + expected = args[i] + } + + if matcher, ok := expected.(argumentMatcher); ok { + if matcher.Matches(actual) { + output = fmt.Sprintf("%s\t%d: \u2705 %s matched by %s\n", output, i, actual, matcher) + } else { + differences++ + output = fmt.Sprintf("%s\t%d: \u2705 %s not matched by %s\n", output, i, actual, matcher) + } + } else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() { + + // type checking + if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) { + // not match + differences++ + output = fmt.Sprintf("%s\t%d: \u274C type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual) + } + + } else { + + // normal checking + + if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { + // match + output = fmt.Sprintf("%s\t%d: \u2705 %s == %s\n", output, i, actual, expected) + } else { + // not match + differences++ + output = fmt.Sprintf("%s\t%d: \u274C %s != %s\n", output, i, actual, expected) + } + } + + } + + if differences == 0 { + return "No differences.", differences + } + + return output, differences + +} + +// Assert compares the arguments with the specified objects and fails if +// they do not exactly match. +func (args Arguments) Assert(t TestingT, objects ...interface{}) bool { + + // get the differences + diff, diffCount := args.Diff(objects) + + if diffCount == 0 { + return true + } + + // there are differences... report them... + t.Logf(diff) + t.Errorf("%sArguments do not match.", assert.CallerInfo()) + + return false + +} + +// String gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +// +// If no index is provided, String() returns a complete string representation +// of the arguments. +func (args Arguments) String(indexOrNil ...int) string { + + if len(indexOrNil) == 0 { + // normal String() method - return a string representation of the args + var argsStr []string + for _, arg := range args { + argsStr = append(argsStr, fmt.Sprintf("%s", reflect.TypeOf(arg))) + } + return strings.Join(argsStr, ",") + } else if len(indexOrNil) == 1 { + // Index has been specified - get the argument at that index + var index = indexOrNil[0] + var s string + var ok bool + if s, ok = args.Get(index).(string); !ok { + panic(fmt.Sprintf("assert: arguments: String(%d) failed because object wasn't correct type: %s", index, args.Get(index))) + } + return s + } + + panic(fmt.Sprintf("assert: arguments: Wrong number of arguments passed to String. Must be 0 or 1, not %d", len(indexOrNil))) + +} + +// Int gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +func (args Arguments) Int(index int) int { + var s int + var ok bool + if s, ok = args.Get(index).(int); !ok { + panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + } + return s +} + +// Error gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +func (args Arguments) Error(index int) error { + obj := args.Get(index) + var s error + var ok bool + if obj == nil { + return nil + } + if s, ok = obj.(error); !ok { + panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + } + return s +} + +// Bool gets the argument at the specified index. Panics if there is no argument, or +// if the argument is of the wrong type. +func (args Arguments) Bool(index int) bool { + var s bool + var ok bool + if s, ok = args.Get(index).(bool); !ok { + panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + } + return s +} diff --git a/Godeps/_workspace/src/github.com/tent/http-link-go/.gitignore b/vendor/github.com/tent/http-link-go/.gitignore similarity index 100% rename from Godeps/_workspace/src/github.com/tent/http-link-go/.gitignore rename to vendor/github.com/tent/http-link-go/.gitignore diff --git a/Godeps/_workspace/src/github.com/tent/http-link-go/.travis.yml b/vendor/github.com/tent/http-link-go/.travis.yml similarity index 100% rename from Godeps/_workspace/src/github.com/tent/http-link-go/.travis.yml rename to vendor/github.com/tent/http-link-go/.travis.yml diff --git a/Godeps/_workspace/src/github.com/tent/http-link-go/LICENSE b/vendor/github.com/tent/http-link-go/LICENSE similarity index 100% rename from Godeps/_workspace/src/github.com/tent/http-link-go/LICENSE rename to vendor/github.com/tent/http-link-go/LICENSE diff --git a/Godeps/_workspace/src/github.com/tent/http-link-go/README.md b/vendor/github.com/tent/http-link-go/README.md similarity index 100% rename from Godeps/_workspace/src/github.com/tent/http-link-go/README.md rename to vendor/github.com/tent/http-link-go/README.md diff --git a/Godeps/_workspace/src/github.com/tent/http-link-go/link.go b/vendor/github.com/tent/http-link-go/link.go similarity index 100% rename from Godeps/_workspace/src/github.com/tent/http-link-go/link.go rename to vendor/github.com/tent/http-link-go/link.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/.gitignore b/vendor/github.com/vmware/govcloudair/.gitignore similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/.gitignore rename to vendor/github.com/vmware/govcloudair/.gitignore diff --git a/vendor/github.com/vmware/govcloudair/.travis.yml b/vendor/github.com/vmware/govcloudair/.travis.yml new file mode 100644 index 0000000000..a3bb17a026 --- /dev/null +++ b/vendor/github.com/vmware/govcloudair/.travis.yml @@ -0,0 +1,10 @@ +language: go + +install: + - go get -t ./... + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + +script: + - PATH="$HOME/gopath/bin:$PATH" + - script/coverage --coveralls \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/LICENSE b/vendor/github.com/vmware/govcloudair/LICENSE similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/LICENSE rename to vendor/github.com/vmware/govcloudair/LICENSE diff --git a/vendor/github.com/vmware/govcloudair/Readme.md b/vendor/github.com/vmware/govcloudair/Readme.md new file mode 100644 index 0000000000..8269c30811 --- /dev/null +++ b/vendor/github.com/vmware/govcloudair/Readme.md @@ -0,0 +1,7 @@ +## govcloudair [![Build Status](https://travis-ci.org/vmware/govcloudair.svg?branch=master)](https://travis-ci.org/frapposelli/govcloudair) [![Coverage Status](https://img.shields.io/coveralls/vmware/govcloudair.svg)](https://coveralls.io/r/vmware/govcloudair) [![GoDoc](https://godoc.org/github.com/vmware/govcloudair?status.svg)](http://godoc.org/github.com/vmware/govcloudair) + +This package provides the `govcloudair` package which offers an interface to the vCloud Air 5.6 API. + +It serves as a foundation for a project currently in development, there are plans to make it a general purpose API in the future. + +The API is currently under heavy development, its coverage is extremely limited at the moment. \ No newline at end of file diff --git a/vendor/github.com/vmware/govcloudair/api.go b/vendor/github.com/vmware/govcloudair/api.go new file mode 100644 index 0000000000..4b094249db --- /dev/null +++ b/vendor/github.com/vmware/govcloudair/api.go @@ -0,0 +1,423 @@ +/* + * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. + */ + +// Package govcloudair provides a simple binding for vCloud Air REST APIs. +package govcloudair + +import ( + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "time" + + "github.com/cenkalti/backoff" + types "github.com/vmware/govcloudair/types/v56" +) + +// Client provides a client to vCloud Air, values can be populated automatically using the Authenticate method. +type Client struct { + VAToken string // vCloud Air authorization token + VAEndpoint url.URL // vCloud Air API endpoint + Region string // Region where the compute resource lives. + VCDToken string // Access Token (authorization header) + VCDAuthHeader string // Authorization header + VCDVDCHREF url.URL // HREF of the backend VDC you're using + Http http.Client // HttpClient is the client to use. Default will be used if not provided. +} + +// VCHS API + +type services struct { + Service []struct { + Region string `xml:"region,attr"` + ServiceID string `xml:"serviceId,attr"` + ServiceType string `xml:"serviceType,attr"` + Type string `xml:"type,attr"` + HREF string `xml:"href,attr"` + } `xml:"Service"` +} + +type session struct { + Link []*types.Link `xml:"Link"` +} + +type computeResources struct { + VdcRef []struct { + Status string `xml:"status,attr"` + Name string `xml:"name,attr"` + Type string `xml:"type,attr"` + HREF string `xml:"href,attr"` + Link []*types.Link `xml:"Link"` + } `xml:"VdcRef"` +} + +type vCloudSession struct { + VdcLink []struct { + AuthorizationToken string `xml:"authorizationToken,attr"` + AuthorizationHeader string `xml:"authorizationHeader,attr"` + Name string `xml:"name,attr"` + HREF string `xml:"href,attr"` + } `xml:"VdcLink"` +} + +// + +func (c *Client) vaauthorize(user, pass string) (u url.URL, err error) { + + if user == "" { + user = os.Getenv("VCLOUDAIR_USERNAME") + } + + if pass == "" { + pass = os.Getenv("VCLOUDAIR_PASSWORD") + } + + s := c.VAEndpoint + s.Path += "/vchs/sessions" + + // No point in checking for errors here + req := c.NewRequest(map[string]string{}, "POST", s, nil) + + // Set Basic Authentication Header + req.SetBasicAuth(user, pass) + + // Add the Accept header for vCA + req.Header.Add("Accept", "application/xml;version=5.6") + + resp, err := checkResp(c.Http.Do(req)) + if err != nil { + return url.URL{}, err + } + defer resp.Body.Close() + + // Store the authentication header + c.VAToken = resp.Header.Get("X-Vchs-Authorization") + + session := new(session) + + if err = decodeBody(resp, session); err != nil { + return url.URL{}, fmt.Errorf("error decoding session response: %s", err) + } + + // Loop in the session struct to find right service and compute resource. + for _, s := range session.Link { + if s.Type == "application/xml;class=vnd.vmware.vchs.servicelist" && s.Rel == "down" { + u, err := url.ParseRequestURI(s.HREF) + return *u, err + } + } + return url.URL{}, fmt.Errorf("couldn't find a Service List in current session") +} + +func (c *Client) vaacquireservice(s url.URL, cid string) (u url.URL, err error) { + + if cid == "" { + cid = os.Getenv("VCLOUDAIR_COMPUTEID") + } + + req := c.NewRequest(map[string]string{}, "GET", s, nil) + + // Add the Accept header for vCA + req.Header.Add("Accept", "application/xml;version=5.6") + + // Set Authorization Header for vCA + req.Header.Add("x-vchs-authorization", c.VAToken) + + resp, err := checkResp(c.Http.Do(req)) + if err != nil { + return url.URL{}, fmt.Errorf("error processing compute action: %s", err) + } + + services := new(services) + + if err = decodeBody(resp, services); err != nil { + return url.URL{}, fmt.Errorf("error decoding services response: %s", err) + } + + // Loop in the Services struct to find right service and compute resource. + for _, s := range services.Service { + if s.ServiceID == cid { + c.Region = s.Region + u, err := url.ParseRequestURI(s.HREF) + return *u, err + } + } + return url.URL{}, fmt.Errorf("couldn't find a Compute Resource in current service list") +} + +func (c *Client) vaacquirecompute(s url.URL, vid string) (u url.URL, err error) { + + if vid == "" { + vid = os.Getenv("VCLOUDAIR_VDCID") + } + + req := c.NewRequest(map[string]string{}, "GET", s, nil) + + // Add the Accept header for vCA + req.Header.Add("Accept", "application/xml;version=5.6") + + // Set Authorization Header + req.Header.Add("x-vchs-authorization", c.VAToken) + + resp, err := checkResp(c.Http.Do(req)) + if err != nil { + return url.URL{}, fmt.Errorf("error processing compute action: %s", err) + } + + computeresources := new(computeResources) + + if err = decodeBody(resp, computeresources); err != nil { + return url.URL{}, fmt.Errorf("error decoding computeresources response: %s", err) + } + + // Iterate through the ComputeResources struct searching for the right + // backend server + for _, s := range computeresources.VdcRef { + if s.Name == vid { + for _, t := range s.Link { + if t.Name == vid { + u, err := url.ParseRequestURI(t.HREF) + return *u, err + } + } + } + } + return url.URL{}, fmt.Errorf("couldn't find a VDC Resource in current Compute list") +} + +func (c *Client) vagetbackendauth(s url.URL, cid string) error { + + if cid == "" { + cid = os.Getenv("VCLOUDAIR_COMPUTEID") + } + + req := c.NewRequest(map[string]string{}, "POST", s, nil) + + // Add the Accept header for vCA + req.Header.Add("Accept", "application/xml;version=5.6") + + // Set Authorization Header + req.Header.Add("x-vchs-authorization", c.VAToken) + + // Adding exponential backoff to retry + b := backoff.NewExponentialBackOff() + b.MaxElapsedTime = time.Duration(30 * time.Second) + + ticker := backoff.NewTicker(b) + + var err error + var resp *http.Response + + for t := range ticker.C { + resp, err = checkResp(c.Http.Do(req)) + if err != nil { + fmt.Println(err, "retrying...", t) + continue + } + ticker.Stop() + break + + } + + if err != nil { + return fmt.Errorf("error processing backend url action: %s", err) + } + + defer resp.Body.Close() + + vcloudsession := new(vCloudSession) + + if err = decodeBody(resp, vcloudsession); err != nil { + return fmt.Errorf("error decoding vcloudsession response: %s", err) + } + + // Get the backend session information + for _, s := range vcloudsession.VdcLink { + if s.Name == cid { + // Fetch the authorization token + c.VCDToken = s.AuthorizationToken + + // Fetch the authorization header + c.VCDAuthHeader = s.AuthorizationHeader + + u, err := url.ParseRequestURI(s.HREF) + if err != nil { + return fmt.Errorf("error decoding href: %s", err) + } + c.VCDVDCHREF = *u + return nil + } + } + return fmt.Errorf("error finding the right backend resource") +} + +// NewClient returns a new empty client to authenticate against the vCloud Air +// service, the vCloud Air endpoint can be overridden by setting the +// VCLOUDAIR_ENDPOINT environment variable. +func NewClient() (*Client, error) { + + var u *url.URL + var err error + + if os.Getenv("VCLOUDAIR_ENDPOINT") != "" { + u, err = url.ParseRequestURI(os.Getenv("VCLOUDAIR_ENDPOINT")) + if err != nil { + return &Client{}, fmt.Errorf("cannot parse endpoint coming from VCLOUDAIR_ENDPOINT") + } + } else { + // Implicitly trust this URL parse. + u, _ = url.ParseRequestURI("https://vchs.vmware.com/api") + } + + Client := Client{ + VAEndpoint: *u, + // Patching things up as we're hitting several TLS timeouts. + Http: http.Client{Transport: &http.Transport{TLSHandshakeTimeout: 120 * time.Second}}, + } + return &Client, nil +} + +// Authenticate is an helper function that performs a complete login in vCloud +// Air and in the backend vCloud Director instance. +func (c *Client) Authenticate(username, password, computeid, vdcid string) (Vdc, error) { + // Authorize + vaservicehref, err := c.vaauthorize(username, password) + if err != nil { + return Vdc{}, fmt.Errorf("error Authorizing: %s", err) + } + + // Get Service + vacomputehref, err := c.vaacquireservice(vaservicehref, computeid) + if err != nil { + return Vdc{}, fmt.Errorf("error Acquiring Service: %s", err) + } + + // Get Compute + vavdchref, err := c.vaacquirecompute(vacomputehref, vdcid) + if err != nil { + return Vdc{}, fmt.Errorf("error Acquiring Compute: %s", err) + } + + // Get Backend Authorization + if err = c.vagetbackendauth(vavdchref, computeid); err != nil { + return Vdc{}, fmt.Errorf("error Acquiring Backend Authorization: %s", err) + } + + v, err := c.retrieveVDC() + if err != nil { + return Vdc{}, fmt.Errorf("error Acquiring VDC: %s", err) + } + + return v, nil + +} + +// NewRequest creates a new HTTP request and applies necessary auth headers if +// set. +func (c *Client) NewRequest(params map[string]string, method string, u url.URL, body io.Reader) *http.Request { + + p := url.Values{} + + // Build up our request parameters + for k, v := range params { + p.Add(k, v) + } + + // Add the params to our URL + u.RawQuery = p.Encode() + + // Build the request, no point in checking for errors here as we're just + // passing a string version of an url.URL struct and http.NewRequest returns + // error only if can't process an url.ParseRequestURI(). + req, _ := http.NewRequest(method, u.String(), body) + + if c.VCDAuthHeader != "" && c.VCDToken != "" { + // Add the authorization header + req.Header.Add(c.VCDAuthHeader, c.VCDToken) + // Add the Accept header for VCD + req.Header.Add("Accept", "application/*+xml;version=5.6") + } + + return req + +} + +// Disconnect performs a disconnection from the vCloud Air API endpoint. +func (c *Client) Disconnect() error { + if c.VCDToken == "" && c.VCDAuthHeader == "" && c.VAToken == "" { + return fmt.Errorf("cannot disconnect, client is not authenticated") + } + + s := c.VAEndpoint + s.Path += "/vchs/session" + + req := c.NewRequest(map[string]string{}, "DELETE", s, nil) + + // Add the Accept header for vCA + req.Header.Add("Accept", "application/xml;version=5.6") + + // Set Authorization Header + req.Header.Add("x-vchs-authorization", c.VAToken) + + if _, err := checkResp(c.Http.Do(req)); err != nil { + return fmt.Errorf("error processing session delete for vchs: %s", err) + } + + return nil +} + +// parseErr takes an error XML resp and returns a single string for use in error messages. +func parseErr(resp *http.Response) error { + + errBody := new(types.Error) + + // if there was an error decoding the body, just return that + if err := decodeBody(resp, errBody); err != nil { + return fmt.Errorf("error parsing error body for non-200 request: %s", err) + } + + return fmt.Errorf("API Error: %d: %s", errBody.MajorErrorCode, errBody.Message) +} + +// decodeBody is used to XML decode a response body +func decodeBody(resp *http.Response, out interface{}) error { + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + // Unmarshal the XML. + if err = xml.Unmarshal(body, &out); err != nil { + return err + } + + return nil +} + +// checkResp wraps http.Client.Do() and verifies the request, if status code +// is 2XX it passes back the response, if it's a known invalid status code it +// parses the resultant XML error and returns a descriptive error, if the +// status code is not handled it returns a generic error with the status code. +func checkResp(resp *http.Response, err error) (*http.Response, error) { + if err != nil { + return resp, err + } + + switch i := resp.StatusCode; { + // Valid request, return the response. + case i == 200 || i == 201 || i == 202 || i == 204: + return resp, nil + // Invalid request, parse the XML error returned and return it. + case i == 400 || i == 401 || i == 403 || i == 404 || i == 405 || i == 406 || i == 409 || i == 415 || i == 500 || i == 503 || i == 504: + return nil, parseErr(resp) + // Unhandled response. + default: + return nil, fmt.Errorf("unhandled API response, please report this issue, status code: %s", resp.Status) + } +} diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/catalog.go b/vendor/github.com/vmware/govcloudair/catalog.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/catalog.go rename to vendor/github.com/vmware/govcloudair/catalog.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem.go b/vendor/github.com/vmware/govcloudair/catalogitem.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/catalogitem.go rename to vendor/github.com/vmware/govcloudair/catalogitem.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway.go b/vendor/github.com/vmware/govcloudair/edgegateway.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/edgegateway.go rename to vendor/github.com/vmware/govcloudair/edgegateway.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/org.go b/vendor/github.com/vmware/govcloudair/org.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/org.go rename to vendor/github.com/vmware/govcloudair/org.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork.go b/vendor/github.com/vmware/govcloudair/orgvdcnetwork.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/orgvdcnetwork.go rename to vendor/github.com/vmware/govcloudair/orgvdcnetwork.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/task.go b/vendor/github.com/vmware/govcloudair/task.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/task.go rename to vendor/github.com/vmware/govcloudair/task.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/types/v56/types.go b/vendor/github.com/vmware/govcloudair/types/v56/types.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/types/v56/types.go rename to vendor/github.com/vmware/govcloudair/types/v56/types.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/vapp.go b/vendor/github.com/vmware/govcloudair/vapp.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/vapp.go rename to vendor/github.com/vmware/govcloudair/vapp.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate.go b/vendor/github.com/vmware/govcloudair/vapptemplate.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/vapptemplate.go rename to vendor/github.com/vmware/govcloudair/vapptemplate.go diff --git a/Godeps/_workspace/src/github.com/vmware/govcloudair/vdc.go b/vendor/github.com/vmware/govcloudair/vdc.go similarity index 100% rename from Godeps/_workspace/src/github.com/vmware/govcloudair/vdc.go rename to vendor/github.com/vmware/govcloudair/vdc.go diff --git a/vendor/github.com/vmware/govmomi/.drone.sec b/vendor/github.com/vmware/govmomi/.drone.sec new file mode 100644 index 0000000000..ad52e59ac8 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/.drone.sec @@ -0,0 +1 @@ +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.kK6pryC8R-O1R0Gj9ydLvQuIZlcYLGze23WdW7xbpiEEKdz6nweJrMm7ysy8lgu1tM47JVo19p2_b26bNKSQshCUOETvd7Hb2UMZOjnyUnqdyAAyoi6UkIquXfUUbHTNS0iMxwSxxW9KMp2GXNq8-o6T8xQZTDirBJFKKd8ZNUasTaoa5j8U9IfdR1aCavTBuOhvk8IVs-jSbY5TVJMJiE0IOPXois7aRJ6uAiANQBk9VKLegEcZD_qAewecXHDsHi-u0jbmg3o3PPaJaK_Qv5dsPlR2M-E2kE3AGUn0-zn5zYRngoAZ8WZr2O4GvLdltJKq9i2z7jOrdOzzRcDRow.96qvwl_E1Hj15u7Q.hWs-jQ8FsqQFD7pE9N-UEP1BWQ9rsJIcCaPvQRIp8Fukm_vvlw9YEaEq0ERLrsUWsJWpd1ca8_h8x7xD6f_d5YppwRqRHIeGIsdBOTMhNs0lG8ikkQXLat-UroCpy8EC17nuUtDE2E2Kdxrk4Cdd6Bk-dKk0Ta4w3Ud0YBKa.P8zrO7xizgv0i98eVWWzEg \ No newline at end of file diff --git a/vendor/github.com/vmware/govmomi/.drone.yml b/vendor/github.com/vmware/govmomi/.drone.yml new file mode 100644 index 0000000000..c1febba3ca --- /dev/null +++ b/vendor/github.com/vmware/govmomi/.drone.yml @@ -0,0 +1,17 @@ +clone: + tags: true + path: github.com/vmware/govmomi +build: + image: golang:1.6 + pull: true + environment: + - GOVC_TEST_URL=$$GOVC_TEST_URL + - GOVC_INSECURE=1 + - VCA=1 + commands: + - make all install + - git clone https://github.com/sstephenson/bats.git /tmp/bats + - /tmp/bats/install.sh /usr/local + - apt-get -qq update && apt-get install -yqq uuid-runtime bsdmainutils jq + - govc/test/images/update.sh + - bats govc/test diff --git a/vendor/github.com/vmware/govmomi/.gitignore b/vendor/github.com/vmware/govmomi/.gitignore new file mode 100644 index 0000000000..769c244007 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/.gitignore @@ -0,0 +1 @@ +secrets.yml diff --git a/vendor/github.com/vmware/govmomi/.travis.yml b/vendor/github.com/vmware/govmomi/.travis.yml new file mode 100644 index 0000000000..3c12d87776 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/.travis.yml @@ -0,0 +1,12 @@ +sudo: false + +language: go + +go: + - 1.6 + +before_install: + - make vendor + +script: + - make check test diff --git a/vendor/github.com/vmware/govmomi/CHANGELOG.md b/vendor/github.com/vmware/govmomi/CHANGELOG.md new file mode 100644 index 0000000000..c695d4a1a1 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/CHANGELOG.md @@ -0,0 +1,118 @@ +# changelog + +### 0.6.2 (2016-05-11) + +* Get complete file details in Datastore.Stat + +* SOAP decoding fixes + +* Add VirtualMachine.RemoveAllSnapshot + +### 0.6.1 (2016-04-30) + +* Fix mo.Entity interface + +### 0.6.0 (2016-04-29) + +* Add Common.Rename method + +* Add mo.Entity interface + +* Add OptionManager + +* Add Finder.FolderList method + +* Add VirtualMachine.WaitForNetIP method + +* Add VirtualMachine.RevertToSnapshot method + +* Add Datastore.Download method + +### 0.5.0 (2016-03-30) + +Generated fields using xsd type 'int' change to Go type 'int32' + +VirtualDevice.UnitNumber field changed to pointer type + +### 0.4.0 (2016-02-26) + +* Add method to convert virtual device list to array with virtual device + changes that can be used in the VirtualMachineConfigSpec. + +* Make datastore cluster traversable in lister + +* Add finder.DatastoreCluster methods (also known as storage pods) + +* Add Drone CI check + +* Add object.Datastore Type and AttachedClusterHosts methods + +* Add finder.*OrDefault methods + +### 0.3.0 (2016-01-16) + +* Add object.VirtualNicManager wrapper + +* Add object.HostVsanSystem wrapper + +* Add object.HostSystem methods: EnterMaintenanceMode, ExitMaintenanceMode, Disconnect, Reconnect + +* Add finder.Folder method + +* Add object.Common.Destroy method + +* Add object.ComputeResource.Reconfigure method + +* Add license.AssignmentManager wrapper + +* Add object.HostFirewallSystem wrapper + +* Add object.DiagnosticManager wrapper + +* Add LoginExtensionByCertificate support + +* Add object.ExtensionManager + +... + +### 0.2.0 (2015-09-15) + +* Update to vim25/6.0 API + +* Stop returning children from `ManagedObjectList` + + Change the `ManagedObjectList` function in the `find` package to only + return the managed objects specified by the path argument and not their + children. The original behavior was used by govc's `ls` command and is + now available in the newly added function `ManagedObjectListChildren`. + +* Add retry functionality to vim25 package + +* Change finder functions to no longer take varargs + + The `find` package had functions to return a list of objects, given a + variable number of patterns. This makes it impossible to distinguish which + patterns produced results and which ones didn't. + + In particular for govc, where multiple arguments can be passed from the + command line, it is useful to let the user know which ones produce results + and which ones don't. + + To evaluate multiple patterns, the user should call the find functions + multiple times (either serially or in parallel). + +* Make optional boolean fields pointers (`vim25/types`). + + False is the zero value of a boolean field, which means they are not serialized + if the field is marked "omitempty". If the field is a pointer instead, the zero + value will be the nil pointer, and both true and false values are serialized. + +### 0.1.0 (2015-03-17) + +Prior to this version the API of this library was in flux. + +Notable changes w.r.t. the state of this library before March 2015 are: + +* All functions that may execute a request take a `context.Context` parameter. +* The `vim25` package contains a minimal client implementation. +* The property collector and its convenience functions live in the `property` package. diff --git a/vendor/github.com/vmware/govmomi/CONTRIBUTING.md b/vendor/github.com/vmware/govmomi/CONTRIBUTING.md new file mode 100644 index 0000000000..18c7be510f --- /dev/null +++ b/vendor/github.com/vmware/govmomi/CONTRIBUTING.md @@ -0,0 +1,92 @@ +# Contributing to govmomi + +## Getting started + +First, fork the repository on GitHub to your personal account. + +Note that _GOPATH_ can be any directory, the example below uses _$HOME/govmomi_. +Change _$USER_ below to your github username if they are not the same. + +``` shell +export GOPATH=$HOME/govmomi +mkdir -p $GOPATH/src/github.com/vmware +cd $GOPATH/src/github.com/vmware +git clone git@github.com:vmware/govmomi.git +cd govmomi +git config push.default nothing # anything to avoid pushing to vmware/govmomi by default +git remote rename origin vmware +git remote add $USER git@github.com:$USER/govmomi.git +git fetch $USER +``` + +## Contribution flow + +This is a rough outline of what a contributor's workflow looks like: + +- Create a topic branch from where you want to base your work. +- Make commits of logical units. +- Make sure your commit messages are in the proper format (see below). +- Push your changes to a topic branch in your fork of the repository. +- Submit a pull request to vmware/govmomi. + +Example: + +``` shell +git checkout -b my-new-feature vmware/master +git commit -a +git push $USER my-new-feature +``` + +### Stay in sync with upstream + +When your branch gets out of sync with the vmware/master branch, use the following to update: + +``` shell +git checkout my-new-feature +git fetch -a +git rebase vmware/master +git push --force-with-lease $USER my-new-feature +``` + +### Updating pull requests + +If your PR fails to pass CI or needs changes based on code review, you'll most likely want to squash these changes into +existing commits. + +If your pull request contains a single commit or your changes are related to the most recent commit, you can simply +amend the commit. + +``` shell +git add . +git commit --amend +git push --force-with-lease $USER my-new-feature +``` + +If you need to squash changes into an earlier commit, you can use: + +``` shell +git add . +git commit --fixup +git rebase -i --autosquash vmware/master +git push --force-with-lease $USER my-new-feature +``` + +Be sure to add a comment to the PR indicating your new changes are ready to review, as github does not generate a +notification when you git push. + +### Code style + +The coding style suggested by the Golang community is used in govmomi. See the +[style doc](https://github.com/golang/go/wiki/CodeReviewComments) for details. + +Try to limit column width to 120 characters for both code and markdown documents such as this one. + +### Format of the Commit Message + +We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/). + +Be sure to include any related GitHub issue references in the commit message. + +## Reporting Bugs and Creating Issues + +When opening a new issue, try to roughly follow the commit message format conventions above. diff --git a/vendor/github.com/vmware/govmomi/CONTRIBUTORS b/vendor/github.com/vmware/govmomi/CONTRIBUTORS new file mode 100644 index 0000000000..11b2194367 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/CONTRIBUTORS @@ -0,0 +1,39 @@ +# People who can (and typically have) contributed to this repository. +# +# Please keep the list sorted. +# + +Alvaro Miranda +Amit Bathla +Andrew Chin +Arran Walker +Austin Parker +Bob Killen +Bruce Downs +Clint Greenwood +Cédric Blomart +Danny Lockard +Dave Tucker +Doug MacEachern +Eloy Coto +Eric Yutao +Fabio Rapposelli +Faiyaz Ahmed +Gavin Gray +Gavrie Philipson +George Hicken +Gerrit Renker +gthombare +Isaac Rodman +Louie Jiang +Mevan Samaratunga +Pieter Noordhuis +runner.mei +S.Çağlar Onur +Sergey Ignatov +Takaaki Furukawa +Steve Purcell +Yang Yang +Yuya Kusakabe +Zach Tucker +Zee Yang diff --git a/Godeps/_workspace/src/github.com/racker/perigee/LICENSE b/vendor/github.com/vmware/govmomi/LICENSE.txt similarity index 100% rename from Godeps/_workspace/src/github.com/racker/perigee/LICENSE rename to vendor/github.com/vmware/govmomi/LICENSE.txt diff --git a/vendor/github.com/vmware/govmomi/Makefile b/vendor/github.com/vmware/govmomi/Makefile new file mode 100644 index 0000000000..af14896340 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/Makefile @@ -0,0 +1,24 @@ +.PHONY: test + +all: check test + +check: goimports govet + +vendor: + go get golang.org/x/tools/cmd/goimports + go get github.com/davecgh/go-spew/spew + go get golang.org/x/net/context + +goimports: vendor + @echo checking go imports... + @! goimports -d . 2>&1 | egrep -v '^$$' + +govet: + @echo checking go vet... + @go tool vet -structtags=false -methods=false . + +test: vendor + go test -v $(TEST_OPTS) ./... + +install: vendor + go install github.com/vmware/govmomi/govc diff --git a/vendor/github.com/vmware/govmomi/README.md b/vendor/github.com/vmware/govmomi/README.md new file mode 100644 index 0000000000..5a9513b69e --- /dev/null +++ b/vendor/github.com/vmware/govmomi/README.md @@ -0,0 +1,54 @@ +[![Build Status](https://travis-ci.org/vmware/govmomi.png?branch=master)](https://travis-ci.org/vmware/govmomi) +[![Build Status](https://ci.vmware.run/api/badges/vmware/govmomi/status.svg)](https://ci.vmware.run/vmware/govmomi) + +# govmomi + +A Go library for interacting with VMware vSphere APIs (ESXi and/or vCenter). + +For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) directory. + +## Compatibility + +This library is built for and tested against ESXi and vCenter 5.5 and 6.0. + +If you're able to use it against older versions of ESXi and/or vCenter, please +leave a note and we'll include it in this compatibility list. + +## Documentation + +The APIs exposed by this library very closely follow the API described in the [VMware vSphere API Reference Documentation][apiref]. +Refer to this document to become familiar with the upstream API. + +The code in the `govmomi` package is a wrapper for the code that is generated from the vSphere API description. +It primarily provides convenience functions for working with the vSphere API. +See [godoc.org][godoc] for documentation. + +[apiref]:http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html +[godoc]:http://godoc.org/github.com/vmware/govmomi +[drone]:https://drone.io +[dronesrc]:https://github.com/drone/drone +[dronecli]:http://readme.drone.io/devs/cli/ + +#### Building with CI +Merges to this repository will trigger builds in both Travis and [Drone][drone]. + +To build locally with Drone: +- Ensure that you have Docker 1.6 or higher installed. +- Install the [Drone command line tools][dronecli]. +- Run `drone exec` from within the root directory of the govmomi repository. + +## Status + +Changes to the API are subject to [semantic versioning](http://semver.org). + +Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes. + +## Projects using govmomi + +* [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere) + +* [Terraform](https://github.com/hashicorp/terraform/tree/master/builtin/providers/vsphere) + +## License + +govmomi is available under the [Apache 2 license](LICENSE). diff --git a/vendor/github.com/vmware/govmomi/client.go b/vendor/github.com/vmware/govmomi/client.go new file mode 100644 index 0000000000..6068e2db34 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/client.go @@ -0,0 +1,167 @@ +/* +Copyright (c) 2014-2016 VMware, 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. +*/ + +/* +This package is the root package of the govmomi library. + +The library is structured as follows: + +Package vim25 + +The minimal usable functionality is available through the vim25 package. +It contains subpackages that contain generated types, managed objects, and all +available methods. The vim25 package is entirely independent of the other +packages in the govmomi tree -- it has no dependencies on its peers. + +The vim25 package itself contains a client structure that is +passed around throughout the entire library. It abstracts a session and its +immutable state. See the vim25 package for more information. + +Package session + +The session package contains an abstraction for the session manager that allows +a user to login and logout. It also provides access to the current session +(i.e. to determine if the user is in fact logged in) + +Package object + +The object package contains wrappers for a selection of managed objects. The +constructors of these objects all take a *vim25.Client, which they pass along +to derived objects, if applicable. + +Package govc + +The govc package contains the govc CLI. The code in this tree is not intended +to be used as a library. Any functionality that govc contains that _could_ be +used as a library function but isn't, _should_ live in a root level package. + +Other packages + +Other packages, such as "event", "guest", or "license", provide wrappers for +the respective subsystems. They are typically not needed in normal workflows so +are kept outside the object package. +*/ +package govmomi + +import ( + "crypto/tls" + "net/url" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/session" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type Client struct { + *vim25.Client + + SessionManager *session.Manager +} + +// NewClient creates a new client from a URL. The client authenticates with the +// server with username/password before returning if the URL contains user information. +func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error) { + soapClient := soap.NewClient(u, insecure) + vimClient, err := vim25.NewClient(ctx, soapClient) + if err != nil { + return nil, err + } + + c := &Client{ + Client: vimClient, + SessionManager: session.NewManager(vimClient), + } + + // Only login if the URL contains user information. + if u.User != nil { + err = c.Login(ctx, u.User) + if err != nil { + return nil, err + } + } + + return c, nil +} + +// NewClientWithCertificate creates a new client from a URL. The client authenticates with the +// server with the certificate before returning if the URL contains user information. +func NewClientWithCertificate(ctx context.Context, u *url.URL, insecure bool, cert tls.Certificate) (*Client, error) { + soapClient := soap.NewClient(u, insecure) + soapClient.SetCertificate(cert) + vimClient, err := vim25.NewClient(ctx, soapClient) + if err != nil { + return nil, err + } + + c := &Client{ + Client: vimClient, + SessionManager: session.NewManager(vimClient), + } + + if u.User != nil { + err = c.LoginExtensionByCertificate(ctx, u.User.Username(), "") + if err != nil { + return nil, err + } + } + + return c, nil +} + +// Login dispatches to the SessionManager. +func (c *Client) Login(ctx context.Context, u *url.Userinfo) error { + return c.SessionManager.Login(ctx, u) +} + +// Login dispatches to the SessionManager. +func (c *Client) LoginExtensionByCertificate(ctx context.Context, key string, locale string) error { + return c.SessionManager.LoginExtensionByCertificate(ctx, key, locale) +} + +// Logout dispatches to the SessionManager. +func (c *Client) Logout(ctx context.Context) error { + // Close any idle connections after logging out. + defer c.Client.CloseIdleConnections() + return c.SessionManager.Logout(ctx) +} + +// PropertyCollector returns the session's default property collector. +func (c *Client) PropertyCollector() *property.Collector { + return property.DefaultCollector(c.Client) +} + +// RetrieveOne dispatches to the Retrieve function on the default property collector. +func (c *Client) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, p []string, dst interface{}) error { + return c.PropertyCollector().RetrieveOne(ctx, obj, p, dst) +} + +// Retrieve dispatches to the Retrieve function on the default property collector. +func (c *Client) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, p []string, dst interface{}) error { + return c.PropertyCollector().Retrieve(ctx, objs, p, dst) +} + +// Wait dispatches to property.Wait. +func (c *Client) Wait(ctx context.Context, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error { + return property.Wait(ctx, c.PropertyCollector(), obj, ps, f) +} + +// IsVC returns true if we are connected to a vCenter +func (c *Client) IsVC() bool { + return c.Client.IsVC() +} diff --git a/vendor/github.com/vmware/govmomi/find/error.go b/vendor/github.com/vmware/govmomi/find/error.go new file mode 100644 index 0000000000..684526dab7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/find/error.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2015 VMware, 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 find + +import "fmt" + +type NotFoundError struct { + kind string + path string +} + +func (e *NotFoundError) Error() string { + return fmt.Sprintf("%s '%s' not found", e.kind, e.path) +} + +type MultipleFoundError struct { + kind string + path string +} + +func (e *MultipleFoundError) Error() string { + return fmt.Sprintf("path '%s' resolves to multiple %ss", e.path, e.kind) +} + +type DefaultNotFoundError struct { + kind string +} + +func (e *DefaultNotFoundError) Error() string { + return fmt.Sprintf("no default %s found", e.kind) +} + +type DefaultMultipleFoundError struct { + kind string +} + +func (e DefaultMultipleFoundError) Error() string { + return fmt.Sprintf("default %s resolves to multiple instances, please specify", e.kind) +} + +func toDefaultError(err error) error { + switch e := err.(type) { + case *NotFoundError: + return &DefaultNotFoundError{e.kind} + case *MultipleFoundError: + return &DefaultMultipleFoundError{e.kind} + default: + return err + } +} diff --git a/vendor/github.com/vmware/govmomi/find/finder.go b/vendor/github.com/vmware/govmomi/find/finder.go new file mode 100644 index 0000000000..3e9c3acb35 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/find/finder.go @@ -0,0 +1,803 @@ +/* +Copyright (c) 2014-2016 VMware, 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 find + +import ( + "errors" + "path" + + "github.com/vmware/govmomi/list" + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/mo" + "golang.org/x/net/context" +) + +type Finder struct { + client *vim25.Client + recurser list.Recurser + + dc *object.Datacenter + folders *object.DatacenterFolders +} + +func NewFinder(client *vim25.Client, all bool) *Finder { + f := &Finder{ + client: client, + recurser: list.Recurser{ + Collector: property.DefaultCollector(client), + All: all, + }, + } + + return f +} + +func (f *Finder) SetDatacenter(dc *object.Datacenter) *Finder { + f.dc = dc + f.folders = nil + return f +} + +type findRelativeFunc func(ctx context.Context) (object.Reference, error) + +func (f *Finder) find(ctx context.Context, fn findRelativeFunc, tl bool, arg string) ([]list.Element, error) { + root := list.Element{ + Path: "/", + Object: object.NewRootFolder(f.client), + } + + parts := list.ToParts(arg) + + if len(parts) > 0 { + switch parts[0] { + case "..": // Not supported; many edge case, little value + return nil, errors.New("cannot traverse up a tree") + case ".": // Relative to whatever + pivot, err := fn(ctx) + if err != nil { + return nil, err + } + + mes, err := mo.Ancestors(ctx, f.client, f.client.ServiceContent.PropertyCollector, pivot.Reference()) + if err != nil { + return nil, err + } + + for _, me := range mes { + // Skip root entity in building inventory path. + if me.Parent == nil { + continue + } + root.Path = path.Join(root.Path, me.Name) + } + + root.Object = pivot + parts = parts[1:] + } + } + + f.recurser.TraverseLeafs = tl + es, err := f.recurser.Recurse(ctx, root, parts) + if err != nil { + return nil, err + } + + return es, nil +} + +func (f *Finder) datacenter() (*object.Datacenter, error) { + if f.dc == nil { + return nil, errors.New("please specify a datacenter") + } + + return f.dc, nil +} + +func (f *Finder) dcFolders(ctx context.Context) (*object.DatacenterFolders, error) { + if f.folders != nil { + return f.folders, nil + } + + dc, err := f.datacenter() + if err != nil { + return nil, err + } + + folders, err := dc.Folders(ctx) + if err != nil { + return nil, err + } + + f.folders = folders + + return f.folders, nil +} + +func (f *Finder) dcReference(_ context.Context) (object.Reference, error) { + dc, err := f.datacenter() + if err != nil { + return nil, err + } + + return dc, nil +} + +func (f *Finder) vmFolder(ctx context.Context) (object.Reference, error) { + folders, err := f.dcFolders(ctx) + if err != nil { + return nil, err + } + + return folders.VmFolder, nil +} + +func (f *Finder) hostFolder(ctx context.Context) (object.Reference, error) { + folders, err := f.dcFolders(ctx) + if err != nil { + return nil, err + } + + return folders.HostFolder, nil +} + +func (f *Finder) datastoreFolder(ctx context.Context) (object.Reference, error) { + folders, err := f.dcFolders(ctx) + if err != nil { + return nil, err + } + + return folders.DatastoreFolder, nil +} + +func (f *Finder) networkFolder(ctx context.Context) (object.Reference, error) { + folders, err := f.dcFolders(ctx) + if err != nil { + return nil, err + } + + return folders.NetworkFolder, nil +} + +func (f *Finder) rootFolder(_ context.Context) (object.Reference, error) { + return object.NewRootFolder(f.client), nil +} + +func (f *Finder) managedObjectList(ctx context.Context, path string, tl bool) ([]list.Element, error) { + fn := f.rootFolder + + if f.dc != nil { + fn = f.dcReference + } + + if len(path) == 0 { + path = "." + } + + return f.find(ctx, fn, tl, path) +} + +func (f *Finder) ManagedObjectList(ctx context.Context, path string) ([]list.Element, error) { + return f.managedObjectList(ctx, path, false) +} + +func (f *Finder) ManagedObjectListChildren(ctx context.Context, path string) ([]list.Element, error) { + return f.managedObjectList(ctx, path, true) +} + +func (f *Finder) DatacenterList(ctx context.Context, path string) ([]*object.Datacenter, error) { + es, err := f.find(ctx, f.rootFolder, false, path) + if err != nil { + return nil, err + } + + var dcs []*object.Datacenter + for _, e := range es { + ref := e.Object.Reference() + if ref.Type == "Datacenter" { + dcs = append(dcs, object.NewDatacenter(f.client, ref)) + } + } + + if len(dcs) == 0 { + return nil, &NotFoundError{"datacenter", path} + } + + return dcs, nil +} + +func (f *Finder) Datacenter(ctx context.Context, path string) (*object.Datacenter, error) { + dcs, err := f.DatacenterList(ctx, path) + if err != nil { + return nil, err + } + + if len(dcs) > 1 { + return nil, &MultipleFoundError{"datacenter", path} + } + + return dcs[0], nil +} + +func (f *Finder) DefaultDatacenter(ctx context.Context) (*object.Datacenter, error) { + dc, err := f.Datacenter(ctx, "*") + if err != nil { + return nil, toDefaultError(err) + } + + return dc, nil +} + +func (f *Finder) DatacenterOrDefault(ctx context.Context, path string) (*object.Datacenter, error) { + if path != "" { + dc, err := f.Datacenter(ctx, path) + if err != nil { + return nil, err + } + return dc, nil + } + + return f.DefaultDatacenter(ctx) +} + +func (f *Finder) DatastoreList(ctx context.Context, path string) ([]*object.Datastore, error) { + es, err := f.find(ctx, f.datastoreFolder, false, path) + if err != nil { + return nil, err + } + + var dss []*object.Datastore + for _, e := range es { + ref := e.Object.Reference() + if ref.Type == "Datastore" { + ds := object.NewDatastore(f.client, ref) + ds.InventoryPath = e.Path + + dss = append(dss, ds) + } + } + + if len(dss) == 0 { + return nil, &NotFoundError{"datastore", path} + } + + return dss, nil +} + +func (f *Finder) Datastore(ctx context.Context, path string) (*object.Datastore, error) { + dss, err := f.DatastoreList(ctx, path) + if err != nil { + return nil, err + } + + if len(dss) > 1 { + return nil, &MultipleFoundError{"datastore", path} + } + + return dss[0], nil +} + +func (f *Finder) DefaultDatastore(ctx context.Context) (*object.Datastore, error) { + ds, err := f.Datastore(ctx, "*") + if err != nil { + return nil, toDefaultError(err) + } + + return ds, nil +} + +func (f *Finder) DatastoreOrDefault(ctx context.Context, path string) (*object.Datastore, error) { + if path != "" { + ds, err := f.Datastore(ctx, path) + if err != nil { + return nil, err + } + return ds, nil + } + + return f.DefaultDatastore(ctx) +} + +func (f *Finder) DatastoreClusterList(ctx context.Context, path string) ([]*object.StoragePod, error) { + es, err := f.find(ctx, f.datastoreFolder, false, path) + if err != nil { + return nil, err + } + + var sps []*object.StoragePod + for _, e := range es { + ref := e.Object.Reference() + if ref.Type == "StoragePod" { + sp := object.NewStoragePod(f.client, ref) + sp.InventoryPath = e.Path + sps = append(sps, sp) + } + } + + if len(sps) == 0 { + return nil, &NotFoundError{"datastore cluster", path} + } + + return sps, nil +} + +func (f *Finder) DatastoreCluster(ctx context.Context, path string) (*object.StoragePod, error) { + sps, err := f.DatastoreClusterList(ctx, path) + if err != nil { + return nil, err + } + + if len(sps) > 1 { + return nil, &MultipleFoundError{"datastore cluster", path} + } + + return sps[0], nil +} + +func (f *Finder) DefaultDatastoreCluster(ctx context.Context) (*object.StoragePod, error) { + sp, err := f.DatastoreCluster(ctx, "*") + if err != nil { + return nil, toDefaultError(err) + } + + return sp, nil +} + +func (f *Finder) DatastoreClusterOrDefault(ctx context.Context, path string) (*object.StoragePod, error) { + if path != "" { + sp, err := f.DatastoreCluster(ctx, path) + if err != nil { + return nil, err + } + return sp, nil + } + + return f.DefaultDatastoreCluster(ctx) +} + +func (f *Finder) ComputeResourceList(ctx context.Context, path string) ([]*object.ComputeResource, error) { + es, err := f.find(ctx, f.hostFolder, false, path) + if err != nil { + return nil, err + } + + var crs []*object.ComputeResource + for _, e := range es { + var cr *object.ComputeResource + + switch o := e.Object.(type) { + case mo.ComputeResource, mo.ClusterComputeResource: + cr = object.NewComputeResource(f.client, o.Reference()) + default: + continue + } + + cr.InventoryPath = e.Path + crs = append(crs, cr) + } + + if len(crs) == 0 { + return nil, &NotFoundError{"compute resource", path} + } + + return crs, nil +} + +func (f *Finder) ComputeResource(ctx context.Context, path string) (*object.ComputeResource, error) { + crs, err := f.ComputeResourceList(ctx, path) + if err != nil { + return nil, err + } + + if len(crs) > 1 { + return nil, &MultipleFoundError{"compute resource", path} + } + + return crs[0], nil +} + +func (f *Finder) DefaultComputeResource(ctx context.Context) (*object.ComputeResource, error) { + cr, err := f.ComputeResource(ctx, "*") + if err != nil { + return nil, toDefaultError(err) + } + + return cr, nil +} + +func (f *Finder) ComputeResourceOrDefault(ctx context.Context, path string) (*object.ComputeResource, error) { + if path != "" { + cr, err := f.ComputeResource(ctx, path) + if err != nil { + return nil, err + } + return cr, nil + } + + return f.DefaultComputeResource(ctx) +} + +func (f *Finder) ClusterComputeResourceList(ctx context.Context, path string) ([]*object.ClusterComputeResource, error) { + es, err := f.find(ctx, f.hostFolder, false, path) + if err != nil { + return nil, err + } + + var ccrs []*object.ClusterComputeResource + for _, e := range es { + var ccr *object.ClusterComputeResource + + switch o := e.Object.(type) { + case mo.ClusterComputeResource: + ccr = object.NewClusterComputeResource(f.client, o.Reference()) + default: + continue + } + + ccr.InventoryPath = e.Path + ccrs = append(ccrs, ccr) + } + + if len(ccrs) == 0 { + return nil, &NotFoundError{"cluster", path} + } + + return ccrs, nil +} + +func (f *Finder) ClusterComputeResource(ctx context.Context, path string) (*object.ClusterComputeResource, error) { + ccrs, err := f.ClusterComputeResourceList(ctx, path) + if err != nil { + return nil, err + } + + if len(ccrs) > 1 { + return nil, &MultipleFoundError{"cluster", path} + } + + return ccrs[0], nil +} + +func (f *Finder) HostSystemList(ctx context.Context, path string) ([]*object.HostSystem, error) { + es, err := f.find(ctx, f.hostFolder, false, path) + if err != nil { + return nil, err + } + + var hss []*object.HostSystem + for _, e := range es { + var hs *object.HostSystem + + switch o := e.Object.(type) { + case mo.HostSystem: + hs = object.NewHostSystem(f.client, o.Reference()) + + hs.InventoryPath = e.Path + hss = append(hss, hs) + case mo.ComputeResource, mo.ClusterComputeResource: + cr := object.NewComputeResource(f.client, o.Reference()) + + cr.InventoryPath = e.Path + + hosts, err := cr.Hosts(ctx) + if err != nil { + return nil, err + } + + hss = append(hss, hosts...) + } + } + + if len(hss) == 0 { + return nil, &NotFoundError{"host", path} + } + + return hss, nil +} + +func (f *Finder) HostSystem(ctx context.Context, path string) (*object.HostSystem, error) { + hss, err := f.HostSystemList(ctx, path) + if err != nil { + return nil, err + } + + if len(hss) > 1 { + return nil, &MultipleFoundError{"host", path} + } + + return hss[0], nil +} + +func (f *Finder) DefaultHostSystem(ctx context.Context) (*object.HostSystem, error) { + hs, err := f.HostSystem(ctx, "*/*") + if err != nil { + return nil, toDefaultError(err) + } + + return hs, nil +} + +func (f *Finder) HostSystemOrDefault(ctx context.Context, path string) (*object.HostSystem, error) { + if path != "" { + hs, err := f.HostSystem(ctx, path) + if err != nil { + return nil, err + } + return hs, nil + } + + return f.DefaultHostSystem(ctx) +} + +func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.NetworkReference, error) { + es, err := f.find(ctx, f.networkFolder, false, path) + if err != nil { + return nil, err + } + + var ns []object.NetworkReference + for _, e := range es { + ref := e.Object.Reference() + switch ref.Type { + case "Network": + r := object.NewNetwork(f.client, ref) + r.InventoryPath = e.Path + ns = append(ns, r) + case "DistributedVirtualPortgroup": + r := object.NewDistributedVirtualPortgroup(f.client, ref) + r.InventoryPath = e.Path + ns = append(ns, r) + case "DistributedVirtualSwitch", "VmwareDistributedVirtualSwitch": + r := object.NewDistributedVirtualSwitch(f.client, ref) + r.InventoryPath = e.Path + ns = append(ns, r) + } + } + + if len(ns) == 0 { + return nil, &NotFoundError{"network", path} + } + + return ns, nil +} + +func (f *Finder) Network(ctx context.Context, path string) (object.NetworkReference, error) { + networks, err := f.NetworkList(ctx, path) + if err != nil { + return nil, err + } + + if len(networks) > 1 { + return nil, &MultipleFoundError{"network", path} + } + + return networks[0], nil +} + +func (f *Finder) DefaultNetwork(ctx context.Context) (object.NetworkReference, error) { + network, err := f.Network(ctx, "*") + if err != nil { + return nil, toDefaultError(err) + } + + return network, nil +} + +func (f *Finder) NetworkOrDefault(ctx context.Context, path string) (object.NetworkReference, error) { + if path != "" { + network, err := f.Network(ctx, path) + if err != nil { + return nil, err + } + return network, nil + } + + return f.DefaultNetwork(ctx) +} + +func (f *Finder) ResourcePoolList(ctx context.Context, path string) ([]*object.ResourcePool, error) { + es, err := f.find(ctx, f.hostFolder, true, path) + if err != nil { + return nil, err + } + + var rps []*object.ResourcePool + for _, e := range es { + var rp *object.ResourcePool + + switch o := e.Object.(type) { + case mo.ResourcePool: + rp = object.NewResourcePool(f.client, o.Reference()) + rp.InventoryPath = e.Path + rps = append(rps, rp) + } + } + + if len(rps) == 0 { + return nil, &NotFoundError{"resource pool", path} + } + + return rps, nil +} + +func (f *Finder) ResourcePool(ctx context.Context, path string) (*object.ResourcePool, error) { + rps, err := f.ResourcePoolList(ctx, path) + if err != nil { + return nil, err + } + + if len(rps) > 1 { + return nil, &MultipleFoundError{"resource pool", path} + } + + return rps[0], nil +} + +func (f *Finder) DefaultResourcePool(ctx context.Context) (*object.ResourcePool, error) { + rp, err := f.ResourcePool(ctx, "*/Resources") + if err != nil { + return nil, toDefaultError(err) + } + + return rp, nil +} + +func (f *Finder) ResourcePoolOrDefault(ctx context.Context, path string) (*object.ResourcePool, error) { + if path != "" { + rp, err := f.ResourcePool(ctx, path) + if err != nil { + return nil, err + } + return rp, nil + } + + return f.DefaultResourcePool(ctx) +} + +func (f *Finder) DefaultFolder(ctx context.Context) (*object.Folder, error) { + ref, err := f.vmFolder(ctx) + if err != nil { + return nil, toDefaultError(err) + } + folder := object.NewFolder(f.client, ref.Reference()) + + return folder, nil +} + +func (f *Finder) FolderOrDefault(ctx context.Context, path string) (*object.Folder, error) { + if path != "" { + folder, err := f.Folder(ctx, path) + if err != nil { + return nil, err + } + return folder, nil + } + return f.DefaultFolder(ctx) +} + +func (f *Finder) VirtualMachineList(ctx context.Context, path string) ([]*object.VirtualMachine, error) { + es, err := f.find(ctx, f.vmFolder, false, path) + if err != nil { + return nil, err + } + + var vms []*object.VirtualMachine + for _, e := range es { + switch o := e.Object.(type) { + case mo.VirtualMachine: + vm := object.NewVirtualMachine(f.client, o.Reference()) + vm.InventoryPath = e.Path + vms = append(vms, vm) + } + } + + if len(vms) == 0 { + return nil, &NotFoundError{"vm", path} + } + + return vms, nil +} + +func (f *Finder) VirtualMachine(ctx context.Context, path string) (*object.VirtualMachine, error) { + vms, err := f.VirtualMachineList(ctx, path) + if err != nil { + return nil, err + } + + if len(vms) > 1 { + return nil, &MultipleFoundError{"vm", path} + } + + return vms[0], nil +} + +func (f *Finder) VirtualAppList(ctx context.Context, path string) ([]*object.VirtualApp, error) { + es, err := f.find(ctx, f.vmFolder, false, path) + if err != nil { + return nil, err + } + + var apps []*object.VirtualApp + for _, e := range es { + switch o := e.Object.(type) { + case mo.VirtualApp: + app := object.NewVirtualApp(f.client, o.Reference()) + app.InventoryPath = e.Path + apps = append(apps, app) + } + } + + if len(apps) == 0 { + return nil, &NotFoundError{"app", path} + } + + return apps, nil +} + +func (f *Finder) VirtualApp(ctx context.Context, path string) (*object.VirtualApp, error) { + apps, err := f.VirtualAppList(ctx, path) + if err != nil { + return nil, err + } + + if len(apps) > 1 { + return nil, &MultipleFoundError{"app", path} + } + + return apps[0], nil +} + +func (f *Finder) FolderList(ctx context.Context, path string) ([]*object.Folder, error) { + es, err := f.ManagedObjectList(ctx, path) + if err != nil { + return nil, err + } + + var folders []*object.Folder + + for _, e := range es { + switch o := e.Object.(type) { + case mo.Folder: + folder := object.NewFolder(f.client, o.Reference()) + folder.InventoryPath = e.Path + folders = append(folders, folder) + case *object.Folder: + // RootFolder + folders = append(folders, o) + } + } + + if len(folders) == 0 { + return nil, &NotFoundError{"folder", path} + } + + return folders, nil +} + +func (f *Finder) Folder(ctx context.Context, path string) (*object.Folder, error) { + folders, err := f.FolderList(ctx, path) + if err != nil { + return nil, err + } + + if len(folders) > 1 { + return nil, &MultipleFoundError{"folder", path} + } + + return folders[0], nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/test/license.bats b/vendor/github.com/vmware/govmomi/govc/test/license.bats new file mode 100755 index 0000000000..e81a61c1ce --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/test/license.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load test_helper + +# These tests should only run against a server running an evaluation license. +verify_evaluation() { + if [ "$(govc license.list -json | jq -r .[0].EditionKey)" != "eval" ]; then + skip "requires evaluation license" + fi +} + +get_key() { + jq ".[] | select(.LicenseKey == \"$1\")" +} + +get_property() { + jq -r ".Properties[] | select(.Key == \"$1\") | .Value" +} + +@test "license.add" { + skip_if_vca + verify_evaluation + + run govc license.add -json 00000-00000-00000-00000-00001 00000-00000-00000-00000-00002 + assert_success + + # Expect to see an entry for both the first and the second key + assert_equal "License is not valid for this product" $(get_key 00000-00000-00000-00000-00001 <<<${output} | get_property diagnostic) + assert_equal "License is not valid for this product" $(get_key 00000-00000-00000-00000-00002 <<<${output} | get_property diagnostic) +} + +@test "license.remove" { + verify_evaluation + + run govc license.remove -json 00000-00000-00000-00000-00001 + assert_success +} + +@test "license.list" { + skip_if_vca + verify_evaluation + + run govc license.list -json + assert_success + + # Expect the test instance to run in evaluation mode + assert_equal "Evaluation Mode" $(get_key 00000-00000-00000-00000-00000 <<<$output | jq -r ".Name") +} + +@test "license.decode" { + verify_evaluation + + key=00000-00000-00000-00000-00000 + assert_equal "eval" $(govc license.decode $key | grep $key | awk '{print $2}') +} diff --git a/vendor/github.com/vmware/govmomi/guest/auth_manager.go b/vendor/github.com/vmware/govmomi/guest/auth_manager.go new file mode 100644 index 0000000000..c62f012ce5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/guest/auth_manager.go @@ -0,0 +1,79 @@ +/* +Copyright (c) 2015 VMware, 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 guest + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type AuthManager struct { + types.ManagedObjectReference + + vm types.ManagedObjectReference + + c *vim25.Client +} + +func (m AuthManager) Reference() types.ManagedObjectReference { + return m.ManagedObjectReference +} + +func (m AuthManager) AcquireCredentials(ctx context.Context, requestedAuth types.BaseGuestAuthentication, sessionID int64) (types.BaseGuestAuthentication, error) { + req := types.AcquireCredentialsInGuest{ + This: m.Reference(), + Vm: m.vm, + RequestedAuth: requestedAuth, + SessionID: sessionID, + } + + res, err := methods.AcquireCredentialsInGuest(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m AuthManager) ReleaseCredentials(ctx context.Context, auth types.BaseGuestAuthentication) error { + req := types.ReleaseCredentialsInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + } + + _, err := methods.ReleaseCredentialsInGuest(ctx, m.c, &req) + + return err +} + +func (m AuthManager) ValidateCredentials(ctx context.Context, auth types.BaseGuestAuthentication) error { + req := types.ValidateCredentialsInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + } + + _, err := methods.ValidateCredentialsInGuest(ctx, m.c, &req) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/guest/file_manager.go b/vendor/github.com/vmware/govmomi/guest/file_manager.go new file mode 100644 index 0000000000..3d2d9b62ee --- /dev/null +++ b/vendor/github.com/vmware/govmomi/guest/file_manager.go @@ -0,0 +1,202 @@ +/* +Copyright (c) 2015 VMware, 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 guest + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type FileManager struct { + types.ManagedObjectReference + + vm types.ManagedObjectReference + + c *vim25.Client +} + +func (m FileManager) Reference() types.ManagedObjectReference { + return m.ManagedObjectReference +} + +func (m FileManager) ChangeFileAttributes(ctx context.Context, auth types.BaseGuestAuthentication, guestFilePath string, fileAttributes types.BaseGuestFileAttributes) error { + req := types.ChangeFileAttributesInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + GuestFilePath: guestFilePath, + FileAttributes: fileAttributes, + } + + _, err := methods.ChangeFileAttributesInGuest(ctx, m.c, &req) + return err +} + +func (m FileManager) CreateTemporaryDirectory(ctx context.Context, auth types.BaseGuestAuthentication, prefix, suffix string) (string, error) { + req := types.CreateTemporaryDirectoryInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + Prefix: prefix, + Suffix: suffix, + } + + res, err := methods.CreateTemporaryDirectoryInGuest(ctx, m.c, &req) + if err != nil { + return "", err + } + + return res.Returnval, nil +} + +func (m FileManager) CreateTemporaryFile(ctx context.Context, auth types.BaseGuestAuthentication, prefix, suffix string) (string, error) { + req := types.CreateTemporaryFileInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + Prefix: prefix, + Suffix: suffix, + } + + res, err := methods.CreateTemporaryFileInGuest(ctx, m.c, &req) + if err != nil { + return "", err + } + + return res.Returnval, nil +} + +func (m FileManager) DeleteDirectory(ctx context.Context, auth types.BaseGuestAuthentication, directoryPath string, recursive bool) error { + req := types.DeleteDirectoryInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + DirectoryPath: directoryPath, + Recursive: recursive, + } + + _, err := methods.DeleteDirectoryInGuest(ctx, m.c, &req) + return err +} + +func (m FileManager) DeleteFile(ctx context.Context, auth types.BaseGuestAuthentication, filePath string) error { + req := types.DeleteFileInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + FilePath: filePath, + } + + _, err := methods.DeleteFileInGuest(ctx, m.c, &req) + return err +} + +func (m FileManager) InitiateFileTransferFromGuest(ctx context.Context, auth types.BaseGuestAuthentication, guestFilePath string) (*types.FileTransferInformation, error) { + req := types.InitiateFileTransferFromGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + GuestFilePath: guestFilePath, + } + + res, err := methods.InitiateFileTransferFromGuest(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (m FileManager) InitiateFileTransferToGuest(ctx context.Context, auth types.BaseGuestAuthentication, guestFilePath string, fileAttributes types.BaseGuestFileAttributes, fileSize int64, overwrite bool) (string, error) { + req := types.InitiateFileTransferToGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + GuestFilePath: guestFilePath, + FileAttributes: fileAttributes, + FileSize: fileSize, + Overwrite: overwrite, + } + + res, err := methods.InitiateFileTransferToGuest(ctx, m.c, &req) + if err != nil { + return "", err + } + + return res.Returnval, nil +} + +func (m FileManager) ListFiles(ctx context.Context, auth types.BaseGuestAuthentication, filePath string, index int32, maxResults int32, matchPattern string) (*types.GuestListFileInfo, error) { + req := types.ListFilesInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + FilePath: filePath, + Index: index, + MaxResults: maxResults, + MatchPattern: matchPattern, + } + + res, err := methods.ListFilesInGuest(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (m FileManager) MakeDirectory(ctx context.Context, auth types.BaseGuestAuthentication, directoryPath string, createParentDirectories bool) error { + req := types.MakeDirectoryInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + DirectoryPath: directoryPath, + CreateParentDirectories: createParentDirectories, + } + + _, err := methods.MakeDirectoryInGuest(ctx, m.c, &req) + return err +} + +func (m FileManager) MoveDirectory(ctx context.Context, auth types.BaseGuestAuthentication, srcDirectoryPath string, dstDirectoryPath string) error { + req := types.MoveDirectoryInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + SrcDirectoryPath: srcDirectoryPath, + DstDirectoryPath: dstDirectoryPath, + } + + _, err := methods.MoveDirectoryInGuest(ctx, m.c, &req) + return err +} + +func (m FileManager) MoveFile(ctx context.Context, auth types.BaseGuestAuthentication, srcFilePath string, dstFilePath string, overwrite bool) error { + req := types.MoveFileInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + SrcFilePath: srcFilePath, + DstFilePath: dstFilePath, + Overwrite: overwrite, + } + + _, err := methods.MoveFileInGuest(ctx, m.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/guest/operations_manager.go b/vendor/github.com/vmware/govmomi/guest/operations_manager.go new file mode 100644 index 0000000000..3c5394d9da --- /dev/null +++ b/vendor/github.com/vmware/govmomi/guest/operations_manager.go @@ -0,0 +1,72 @@ +/* +Copyright (c) 2015 VMware, 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 guest + +import ( + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type OperationsManager struct { + c *vim25.Client + vm types.ManagedObjectReference +} + +func NewOperationsManager(c *vim25.Client, vm types.ManagedObjectReference) *OperationsManager { + return &OperationsManager{c, vm} +} + +func (m OperationsManager) retrieveOne(ctx context.Context, p string, dst *mo.GuestOperationsManager) error { + pc := property.DefaultCollector(m.c) + return pc.RetrieveOne(ctx, *m.c.ServiceContent.GuestOperationsManager, []string{p}, dst) +} + +func (m OperationsManager) AuthManager(ctx context.Context) (*AuthManager, error) { + var g mo.GuestOperationsManager + + err := m.retrieveOne(ctx, "authManager", &g) + if err != nil { + return nil, err + } + + return &AuthManager{*g.AuthManager, m.vm, m.c}, nil +} + +func (m OperationsManager) FileManager(ctx context.Context) (*FileManager, error) { + var g mo.GuestOperationsManager + + err := m.retrieveOne(ctx, "fileManager", &g) + if err != nil { + return nil, err + } + + return &FileManager{*g.FileManager, m.vm, m.c}, nil +} + +func (m OperationsManager) ProcessManager(ctx context.Context) (*ProcessManager, error) { + var g mo.GuestOperationsManager + + err := m.retrieveOne(ctx, "processManager", &g) + if err != nil { + return nil, err + } + + return &ProcessManager{*g.ProcessManager, m.vm, m.c}, nil +} diff --git a/vendor/github.com/vmware/govmomi/guest/process_manager.go b/vendor/github.com/vmware/govmomi/guest/process_manager.go new file mode 100644 index 0000000000..159a571d71 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/guest/process_manager.go @@ -0,0 +1,96 @@ +/* +Copyright (c) 2015 VMware, 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 guest + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ProcessManager struct { + types.ManagedObjectReference + + vm types.ManagedObjectReference + + c *vim25.Client +} + +func (m ProcessManager) Reference() types.ManagedObjectReference { + return m.ManagedObjectReference +} + +func (m ProcessManager) ListProcesses(ctx context.Context, auth types.BaseGuestAuthentication, pids []int64) ([]types.GuestProcessInfo, error) { + req := types.ListProcessesInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + Pids: pids, + } + + res, err := methods.ListProcessesInGuest(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return res.Returnval, err +} + +func (m ProcessManager) ReadEnvironmentVariable(ctx context.Context, auth types.BaseGuestAuthentication, names []string) ([]string, error) { + req := types.ReadEnvironmentVariableInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + Names: names, + } + + res, err := methods.ReadEnvironmentVariableInGuest(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return res.Returnval, err +} + +func (m ProcessManager) StartProgram(ctx context.Context, auth types.BaseGuestAuthentication, spec types.BaseGuestProgramSpec) (int64, error) { + req := types.StartProgramInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + Spec: spec, + } + + res, err := methods.StartProgramInGuest(ctx, m.c, &req) + if err != nil { + return 0, err + } + + return res.Returnval, err +} + +func (m ProcessManager) TerminateProcess(ctx context.Context, auth types.BaseGuestAuthentication, pid int64) error { + req := types.TerminateProcessInGuest{ + This: m.Reference(), + Vm: m.vm, + Auth: auth, + Pid: pid, + } + + _, err := methods.TerminateProcessInGuest(ctx, m.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/list/lister.go b/vendor/github.com/vmware/govmomi/list/lister.go new file mode 100644 index 0000000000..355208f534 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/list/lister.go @@ -0,0 +1,572 @@ +/* +Copyright (c) 2014-2016 VMware, 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 list + +import ( + "fmt" + "path" + "reflect" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type Element struct { + Path string + Object mo.Reference +} + +func ToElement(r mo.Reference, prefix string) Element { + var name string + + // Comments about types to be expected in folders copied from the + // documentation of the Folder managed object: + // http://pubs.vmware.com/vsphere-55/topic/com.vmware.wssdk.apiref.doc/vim.Folder.html + switch m := r.(type) { + case mo.Folder: + name = m.Name + case mo.StoragePod: + name = m.Name + + // { "vim.Datacenter" } - Identifies the root folder and its descendant + // folders. Data center folders can contain child data center folders and + // Datacenter managed objects. Datacenter objects contain virtual machine, + // compute resource, network entity, and datastore folders. + case mo.Datacenter: + name = m.Name + + // { "vim.Virtualmachine", "vim.VirtualApp" } - Identifies a virtual machine + // folder. A virtual machine folder may contain child virtual machine + // folders. It also can contain VirtualMachine managed objects, templates, + // and VirtualApp managed objects. + case mo.VirtualMachine: + name = m.Name + case mo.VirtualApp: + name = m.Name + + // { "vim.ComputeResource" } - Identifies a compute resource + // folder, which contains child compute resource folders and ComputeResource + // hierarchies. + case mo.ComputeResource: + name = m.Name + case mo.ClusterComputeResource: + name = m.Name + case mo.HostSystem: + name = m.Name + case mo.ResourcePool: + name = m.Name + + // { "vim.Network" } - Identifies a network entity folder. + // Network entity folders on a vCenter Server can contain Network, + // DistributedVirtualSwitch, and DistributedVirtualPortgroup managed objects. + // Network entity folders on an ESXi host can contain only Network objects. + case mo.Network: + name = m.Name + case mo.DistributedVirtualSwitch: + name = m.Name + case mo.DistributedVirtualPortgroup: + name = m.Name + case mo.VmwareDistributedVirtualSwitch: + name = m.Name + + // { "vim.Datastore" } - Identifies a datastore folder. Datastore folders can + // contain child datastore folders and Datastore managed objects. + case mo.Datastore: + name = m.Name + + default: + panic("not implemented for type " + reflect.TypeOf(r).String()) + } + + e := Element{ + Path: path.Join(prefix, name), + Object: r, + } + + return e +} + +type Lister struct { + Collector *property.Collector + Reference types.ManagedObjectReference + Prefix string + All bool +} + +func traversable(ref types.ManagedObjectReference) bool { + switch ref.Type { + case "Folder": + case "Datacenter": + case "ComputeResource", "ClusterComputeResource": + // Treat ComputeResource and ClusterComputeResource as one and the same. + // It doesn't matter from the perspective of the lister. + case "HostSystem": + case "VirtualApp": + case "StoragePod": + default: + return false + } + + return true +} + +func (l Lister) retrieveProperties(ctx context.Context, req types.RetrieveProperties, dst *[]interface{}) error { + res, err := l.Collector.RetrieveProperties(ctx, req) + if err != nil { + return err + } + + // Instead of using mo.LoadRetrievePropertiesResponse, use a custom loop to + // iterate over the results and ignore entries that have properties that + // could not be retrieved (a non-empty `missingSet` property). Since the + // returned objects are enumerated by vSphere in the first place, any object + // that has a non-empty `missingSet` property is indicative of a race + // condition in vSphere where the object was enumerated initially, but was + // removed before its properties could be collected. + for _, p := range res.Returnval { + v, err := mo.ObjectContentToType(p) + if err != nil { + // Ignore fault if it is ManagedObjectNotFound + if soap.IsVimFault(err) { + switch soap.ToVimFault(err).(type) { + case *types.ManagedObjectNotFound: + continue + } + } + + return err + } + + *dst = append(*dst, v) + } + + return nil +} + +func (l Lister) List(ctx context.Context) ([]Element, error) { + switch l.Reference.Type { + case "Folder", "StoragePod": + return l.ListFolder(ctx) + case "Datacenter": + return l.ListDatacenter(ctx) + case "ComputeResource", "ClusterComputeResource": + // Treat ComputeResource and ClusterComputeResource as one and the same. + // It doesn't matter from the perspective of the lister. + return l.ListComputeResource(ctx) + case "ResourcePool": + return l.ListResourcePool(ctx) + case "HostSystem": + return l.ListHostSystem(ctx) + case "VirtualApp": + return l.ListVirtualApp(ctx) + default: + return nil, fmt.Errorf("cannot traverse type " + l.Reference.Type) + } +} + +func (l Lister) ListFolder(ctx context.Context) ([]Element, error) { + spec := types.PropertyFilterSpec{ + ObjectSet: []types.ObjectSpec{ + { + Obj: l.Reference, + SelectSet: []types.BaseSelectionSpec{ + &types.TraversalSpec{ + Path: "childEntity", + Skip: types.NewBool(false), + Type: "Folder", + }, + }, + Skip: types.NewBool(true), + }, + }, + } + + // Retrieve all objects that we can deal with + childTypes := []string{ + "Folder", + "Datacenter", + "VirtualApp", + "VirtualMachine", + "Network", + "ComputeResource", + "ClusterComputeResource", + "Datastore", + "DistributedVirtualSwitch", + } + + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + + // Additional basic properties. + switch t { + case "ComputeResource", "ClusterComputeResource": + // The ComputeResource and ClusterComputeResource are dereferenced in + // the ResourcePoolFlag. Make sure they always have their resourcePool + // field populated. + pspec.PathSet = append(pspec.PathSet, "resourcePool") + } + } + + spec.PropSet = append(spec.PropSet, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{spec}, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} + +func (l Lister) ListDatacenter(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + // Include every datastore folder in the select set + fields := []string{ + "vmFolder", + "hostFolder", + "datastoreFolder", + "networkFolder", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "Datacenter", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + pspec := types.PropertySpec{ + Type: "Folder", + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: []types.PropertySpec{pspec}, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} + +func (l Lister) ListComputeResource(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + fields := []string{ + "host", + "resourcePool", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "ComputeResource", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + childTypes := []string{ + "HostSystem", + "ResourcePool", + } + + var pspecs []types.PropertySpec + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + pspecs = append(pspecs, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: pspecs, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} + +func (l Lister) ListResourcePool(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + fields := []string{ + "resourcePool", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "ResourcePool", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + childTypes := []string{ + "ResourcePool", + } + + var pspecs []types.PropertySpec + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + pspecs = append(pspecs, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: pspecs, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} + +func (l Lister) ListHostSystem(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + fields := []string{ + "datastore", + "network", + "vm", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "HostSystem", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + childTypes := []string{ + "Datastore", + "Network", + "VirtualMachine", + } + + var pspecs []types.PropertySpec + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + pspecs = append(pspecs, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: pspecs, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} + +func (l Lister) ListVirtualApp(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + fields := []string{ + "resourcePool", + "vm", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "VirtualApp", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + childTypes := []string{ + "ResourcePool", + "VirtualMachine", + } + + var pspecs []types.PropertySpec + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + pspecs = append(pspecs, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: pspecs, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} diff --git a/vendor/github.com/vmware/govmomi/list/path.go b/vendor/github.com/vmware/govmomi/list/path.go new file mode 100644 index 0000000000..f3a1065201 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/list/path.go @@ -0,0 +1,44 @@ +/* +Copyright (c) 2014 VMware, 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 list + +import ( + "path" + "strings" +) + +func ToParts(p string) []string { + p = path.Clean(p) + if p == "/" { + return []string{} + } + + if len(p) > 0 { + // Prefix ./ if relative + if p[0] != '/' && p[0] != '.' { + p = "./" + p + } + } + + ps := strings.Split(p, "/") + if ps[0] == "" { + // Start at root + ps = ps[1:] + } + + return ps +} diff --git a/vendor/github.com/vmware/govmomi/list/recurser.go b/vendor/github.com/vmware/govmomi/list/recurser.go new file mode 100644 index 0000000000..4b78415b33 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/list/recurser.go @@ -0,0 +1,97 @@ +/* +Copyright (c) 2014-2015 VMware, 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 list + +import ( + "path" + "path/filepath" + + "github.com/vmware/govmomi/property" + "golang.org/x/net/context" +) + +type Recurser struct { + Collector *property.Collector + + // All configures the recurses to fetch complete objects for leaf nodes. + All bool + + // TraverseLeafs configures the Recurser to traverse traversable leaf nodes. + // This is typically set to true when used from the ls command, where listing + // a folder means listing its contents. This is typically set to false for + // commands that take managed entities that are not folders as input. + TraverseLeafs bool +} + +func (r Recurser) Recurse(ctx context.Context, root Element, parts []string) ([]Element, error) { + if len(parts) == 0 { + // Include non-traversable leaf elements in result. For example, consider + // the pattern "./vm/my-vm-*", where the pattern should match the VMs and + // not try to traverse them. + // + // Include traversable leaf elements in result, if the TraverseLeafs + // field is set to false. + // + if !traversable(root.Object.Reference()) || !r.TraverseLeafs { + return []Element{root}, nil + } + } + + k := Lister{ + Collector: r.Collector, + Reference: root.Object.Reference(), + Prefix: root.Path, + } + + if r.All && len(parts) < 2 { + k.All = true + } + + in, err := k.List(ctx) + if err != nil { + return nil, err + } + + // This folder is a leaf as far as the glob goes. + if len(parts) == 0 { + return in, nil + } + + pattern := parts[0] + parts = parts[1:] + + var out []Element + for _, e := range in { + matched, err := filepath.Match(pattern, path.Base(e.Path)) + if err != nil { + return nil, err + } + + if !matched { + continue + } + + nres, err := r.Recurse(ctx, e, parts) + if err != nil { + return nil, err + } + + out = append(out, nres...) + } + + return out, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/authorization_manager.go b/vendor/github.com/vmware/govmomi/object/authorization_manager.go new file mode 100644 index 0000000000..868db4f712 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/authorization_manager.go @@ -0,0 +1,108 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type AuthorizationManager struct { + Common +} + +func NewAuthorizationManager(c *vim25.Client) *AuthorizationManager { + m := AuthorizationManager{ + Common: NewCommon(c, *c.ServiceContent.AuthorizationManager), + } + + return &m +} + +type AuthorizationRoleList []types.AuthorizationRole + +func (l AuthorizationRoleList) ById(id int32) *types.AuthorizationRole { + for _, role := range l { + if role.RoleId == id { + return &role + } + } + + return nil +} + +func (l AuthorizationRoleList) ByName(name string) *types.AuthorizationRole { + for _, role := range l { + if role.Name == name { + return &role + } + } + + return nil +} + +func (m AuthorizationManager) RoleList(ctx context.Context) (AuthorizationRoleList, error) { + var am mo.AuthorizationManager + + err := m.Properties(ctx, m.Reference(), []string{"roleList"}, &am) + if err != nil { + return nil, err + } + + return AuthorizationRoleList(am.RoleList), nil +} + +func (m AuthorizationManager) RetrieveEntityPermissions(ctx context.Context, entity types.ManagedObjectReference, inherited bool) ([]types.Permission, error) { + req := types.RetrieveEntityPermissions{ + This: m.Reference(), + Entity: entity, + Inherited: inherited, + } + + res, err := methods.RetrieveEntityPermissions(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m AuthorizationManager) RemoveEntityPermission(ctx context.Context, entity types.ManagedObjectReference, user string, isGroup bool) error { + req := types.RemoveEntityPermission{ + This: m.Reference(), + Entity: entity, + User: user, + IsGroup: isGroup, + } + + _, err := methods.RemoveEntityPermission(ctx, m.Client(), &req) + return err +} + +func (m AuthorizationManager) SetEntityPermissions(ctx context.Context, entity types.ManagedObjectReference, permission []types.Permission) error { + req := types.SetEntityPermissions{ + This: m.Reference(), + Entity: entity, + Permission: permission, + } + + _, err := methods.SetEntityPermissions(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go new file mode 100644 index 0000000000..3cd52f705f --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ClusterComputeResource struct { + ComputeResource + + InventoryPath string +} + +func NewClusterComputeResource(c *vim25.Client, ref types.ManagedObjectReference) *ClusterComputeResource { + return &ClusterComputeResource{ + ComputeResource: *NewComputeResource(c, ref), + } +} + +func (c ClusterComputeResource) ReconfigureCluster(ctx context.Context, spec types.ClusterConfigSpec) (*Task, error) { + req := types.ReconfigureCluster_Task{ + This: c.Reference(), + Spec: spec, + Modify: true, + } + + res, err := methods.ReconfigureCluster_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} + +func (c ClusterComputeResource) AddHost(ctx context.Context, spec types.HostConnectSpec, asConnected bool, license *string, resourcePool *types.ManagedObjectReference) (*Task, error) { + req := types.AddHost_Task{ + This: c.Reference(), + Spec: spec, + AsConnected: asConnected, + } + + if license != nil { + req.License = *license + } + + if resourcePool != nil { + req.ResourcePool = resourcePool + } + + res, err := methods.AddHost_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} + +func (c ClusterComputeResource) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: c.Reference(), + } + + res, err := methods.Destroy_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/common.go b/vendor/github.com/vmware/govmomi/object/common.go new file mode 100644 index 0000000000..97972849f9 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/common.go @@ -0,0 +1,85 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + "fmt" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +var ( + ErrNotSupported = errors.New("not supported (vCenter only)") +) + +// Common contains the fields and functions common to all objects. +type Common struct { + c *vim25.Client + r types.ManagedObjectReference +} + +func (c Common) String() string { + return fmt.Sprintf("%v", c.Reference()) +} + +func NewCommon(c *vim25.Client, r types.ManagedObjectReference) Common { + return Common{c: c, r: r} +} + +func (c Common) Reference() types.ManagedObjectReference { + return c.r +} + +func (c Common) Client() *vim25.Client { + return c.c +} + +func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error { + return property.DefaultCollector(c.c).RetrieveOne(ctx, r, ps, dst) +} + +func (c Common) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: c.Reference(), + } + + res, err := methods.Destroy_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} + +func (c Common) Rename(ctx context.Context, name string) (*Task, error) { + req := types.Rename_Task{ + This: c.Reference(), + NewName: name, + } + + res, err := methods.Rename_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/compute_resource.go b/vendor/github.com/vmware/govmomi/object/compute_resource.go new file mode 100644 index 0000000000..328c2e07cb --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/compute_resource.go @@ -0,0 +1,126 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "path" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ComputeResource struct { + Common + + InventoryPath string +} + +func NewComputeResource(c *vim25.Client, ref types.ManagedObjectReference) *ComputeResource { + return &ComputeResource{ + Common: NewCommon(c, ref), + } +} + +func (c ComputeResource) Hosts(ctx context.Context) ([]*HostSystem, error) { + var cr mo.ComputeResource + + err := c.Properties(ctx, c.Reference(), []string{"host"}, &cr) + if err != nil { + return nil, err + } + + if len(cr.Host) == 0 { + return nil, nil + } + + var hs []mo.HostSystem + pc := property.DefaultCollector(c.Client()) + err = pc.Retrieve(ctx, cr.Host, []string{"name"}, &hs) + if err != nil { + return nil, err + } + + var hosts []*HostSystem + + for _, h := range hs { + host := NewHostSystem(c.Client(), h.Reference()) + host.InventoryPath = path.Join(c.InventoryPath, h.Name) + hosts = append(hosts, host) + } + + return hosts, nil +} + +func (c ComputeResource) Datastores(ctx context.Context) ([]*Datastore, error) { + var cr mo.ComputeResource + + err := c.Properties(ctx, c.Reference(), []string{"datastore"}, &cr) + if err != nil { + return nil, err + } + + var dss []*Datastore + for _, ref := range cr.Datastore { + ds := NewDatastore(c.c, ref) + dss = append(dss, ds) + } + + return dss, nil +} + +func (c ComputeResource) ResourcePool(ctx context.Context) (*ResourcePool, error) { + var cr mo.ComputeResource + + err := c.Properties(ctx, c.Reference(), []string{"resourcePool"}, &cr) + if err != nil { + return nil, err + } + + return NewResourcePool(c.c, *cr.ResourcePool), nil +} + +func (c ComputeResource) Reconfigure(ctx context.Context, spec types.BaseComputeResourceConfigSpec, modify bool) (*Task, error) { + req := types.ReconfigureComputeResource_Task{ + This: c.Reference(), + Spec: spec, + Modify: modify, + } + + res, err := methods.ReconfigureComputeResource_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} + +func (c ComputeResource) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: c.Reference(), + } + + res, err := methods.Destroy_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go b/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go new file mode 100644 index 0000000000..ce9abf0870 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go @@ -0,0 +1,135 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + "strconv" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +var ( + ErrKeyNameNotFound = errors.New("key name not found") +) + +type CustomFieldsManager struct { + Common +} + +// GetCustomFieldsManager wraps NewCustomFieldsManager, returning ErrNotSupported +// when the client is not connected to a vCenter instance. +func GetCustomFieldsManager(c *vim25.Client) (*CustomFieldsManager, error) { + if c.ServiceContent.CustomFieldsManager == nil { + return nil, ErrNotSupported + } + return NewCustomFieldsManager(c), nil +} + +func NewCustomFieldsManager(c *vim25.Client) *CustomFieldsManager { + m := CustomFieldsManager{ + Common: NewCommon(c, *c.ServiceContent.CustomFieldsManager), + } + + return &m +} + +func (m CustomFieldsManager) Add(ctx context.Context, name string, moType string, fieldDefPolicy *types.PrivilegePolicyDef, fieldPolicy *types.PrivilegePolicyDef) (*types.CustomFieldDef, error) { + req := types.AddCustomFieldDef{ + This: m.Reference(), + Name: name, + MoType: moType, + FieldDefPolicy: fieldDefPolicy, + FieldPolicy: fieldPolicy, + } + + res, err := methods.AddCustomFieldDef(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (m CustomFieldsManager) Remove(ctx context.Context, key int32) error { + req := types.RemoveCustomFieldDef{ + This: m.Reference(), + Key: key, + } + + _, err := methods.RemoveCustomFieldDef(ctx, m.c, &req) + return err +} + +func (m CustomFieldsManager) Rename(ctx context.Context, key int32, name string) error { + req := types.RenameCustomFieldDef{ + This: m.Reference(), + Key: key, + Name: name, + } + + _, err := methods.RenameCustomFieldDef(ctx, m.c, &req) + return err +} + +func (m CustomFieldsManager) Set(ctx context.Context, entity types.ManagedObjectReference, key int32, value string) error { + req := types.SetField{ + This: m.Reference(), + Entity: entity, + Key: key, + Value: value, + } + + _, err := methods.SetField(ctx, m.c, &req) + return err +} + +func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef, error) { + var fm mo.CustomFieldsManager + + err := m.Properties(ctx, m.Reference(), []string{"field"}, &fm) + if err != nil { + return nil, err + } + + return fm.Field, nil +} + +func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, error) { + field, err := m.Field(ctx) + if err != nil { + return -1, err + } + + for _, def := range field { + if def.Name == key { + return def.Key, nil + } + } + + k, err := strconv.Atoi(key) + if err == nil { + // assume literal int key + return int32(k), nil + } + + return -1, ErrKeyNameNotFound +} diff --git a/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go b/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go new file mode 100644 index 0000000000..aebe73e844 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go @@ -0,0 +1,165 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type CustomizationSpecManager struct { + Common +} + +func NewCustomizationSpecManager(c *vim25.Client) *CustomizationSpecManager { + cs := CustomizationSpecManager{ + Common: NewCommon(c, *c.ServiceContent.CustomizationSpecManager), + } + + return &cs +} + +func (cs CustomizationSpecManager) DoesCustomizationSpecExist(ctx context.Context, name string) (bool, error) { + req := types.DoesCustomizationSpecExist{ + This: cs.Reference(), + Name: name, + } + + res, err := methods.DoesCustomizationSpecExist(ctx, cs.c, &req) + + if err != nil { + return false, err + } + + return res.Returnval, nil +} + +func (cs CustomizationSpecManager) GetCustomizationSpec(ctx context.Context, name string) (*types.CustomizationSpecItem, error) { + req := types.GetCustomizationSpec{ + This: cs.Reference(), + Name: name, + } + + res, err := methods.GetCustomizationSpec(ctx, cs.c, &req) + + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (cs CustomizationSpecManager) CreateCustomizationSpec(ctx context.Context, item types.CustomizationSpecItem) error { + req := types.CreateCustomizationSpec{ + This: cs.Reference(), + Item: item, + } + + _, err := methods.CreateCustomizationSpec(ctx, cs.c, &req) + if err != nil { + return err + } + + return nil +} + +func (cs CustomizationSpecManager) OverwriteCustomizationSpec(ctx context.Context, item types.CustomizationSpecItem) error { + req := types.OverwriteCustomizationSpec{ + This: cs.Reference(), + Item: item, + } + + _, err := methods.OverwriteCustomizationSpec(ctx, cs.c, &req) + if err != nil { + return err + } + + return nil +} + +func (cs CustomizationSpecManager) DeleteCustomizationSpec(ctx context.Context, name string) error { + req := types.DeleteCustomizationSpec{ + This: cs.Reference(), + Name: name, + } + + _, err := methods.DeleteCustomizationSpec(ctx, cs.c, &req) + if err != nil { + return err + } + + return nil +} + +func (cs CustomizationSpecManager) DuplicateCustomizationSpec(ctx context.Context, name string, newName string) error { + req := types.DuplicateCustomizationSpec{ + This: cs.Reference(), + Name: name, + NewName: newName, + } + + _, err := methods.DuplicateCustomizationSpec(ctx, cs.c, &req) + if err != nil { + return err + } + + return nil +} + +func (cs CustomizationSpecManager) RenameCustomizationSpec(ctx context.Context, name string, newName string) error { + req := types.RenameCustomizationSpec{ + This: cs.Reference(), + Name: name, + NewName: newName, + } + + _, err := methods.RenameCustomizationSpec(ctx, cs.c, &req) + if err != nil { + return err + } + + return nil +} + +func (cs CustomizationSpecManager) CustomizationSpecItemToXml(ctx context.Context, item types.CustomizationSpecItem) (string, error) { + req := types.CustomizationSpecItemToXml{ + This: cs.Reference(), + Item: item, + } + + res, err := methods.CustomizationSpecItemToXml(ctx, cs.c, &req) + if err != nil { + return "", err + } + + return res.Returnval, nil +} + +func (cs CustomizationSpecManager) XmlToCustomizationSpecItem(ctx context.Context, xml string) (*types.CustomizationSpecItem, error) { + req := types.XmlToCustomizationSpecItem{ + This: cs.Reference(), + SpecItemXml: xml, + } + + res, err := methods.XmlToCustomizationSpecItem(ctx, cs.c, &req) + if err != nil { + return nil, err + } + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/datacenter.go b/vendor/github.com/vmware/govmomi/object/datacenter.go new file mode 100644 index 0000000000..fa522fb053 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/datacenter.go @@ -0,0 +1,90 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "fmt" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type DatacenterFolders struct { + VmFolder *Folder + HostFolder *Folder + DatastoreFolder *Folder + NetworkFolder *Folder +} + +type Datacenter struct { + Common +} + +func NewDatacenter(c *vim25.Client, ref types.ManagedObjectReference) *Datacenter { + return &Datacenter{ + Common: NewCommon(c, ref), + } +} + +func (d *Datacenter) Folders(ctx context.Context) (*DatacenterFolders, error) { + var md mo.Datacenter + + ps := []string{"name", "vmFolder", "hostFolder", "datastoreFolder", "networkFolder"} + err := d.Properties(ctx, d.Reference(), ps, &md) + if err != nil { + return nil, err + } + + df := &DatacenterFolders{ + VmFolder: NewFolder(d.c, md.VmFolder), + HostFolder: NewFolder(d.c, md.HostFolder), + DatastoreFolder: NewFolder(d.c, md.DatastoreFolder), + NetworkFolder: NewFolder(d.c, md.NetworkFolder), + } + + paths := []struct { + name string + path *string + }{ + {"vm", &df.VmFolder.InventoryPath}, + {"host", &df.HostFolder.InventoryPath}, + {"datastore", &df.DatastoreFolder.InventoryPath}, + {"network", &df.NetworkFolder.InventoryPath}, + } + + for _, p := range paths { + *p.path = fmt.Sprintf("/%s/%s", md.Name, p.name) + } + + return df, nil +} + +func (d Datacenter) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: d.Reference(), + } + + res, err := methods.Destroy_Task(ctx, d.c, &req) + if err != nil { + return nil, err + } + + return NewTask(d.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/datastore.go b/vendor/github.com/vmware/govmomi/object/datastore.go new file mode 100644 index 0000000000..123dde8a83 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/datastore.go @@ -0,0 +1,362 @@ +/* +Copyright (c) 2015-2016 VMware, 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 object + +import ( + "fmt" + "io" + "math/rand" + "path" + "strings" + + "net/http" + "net/url" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/session" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// DatastoreNoSuchDirectoryError is returned when a directory could not be found. +type DatastoreNoSuchDirectoryError struct { + verb string + subject string +} + +func (e DatastoreNoSuchDirectoryError) Error() string { + return fmt.Sprintf("cannot %s '%s': No such directory", e.verb, e.subject) +} + +// DatastoreNoSuchFileError is returned when a file could not be found. +type DatastoreNoSuchFileError struct { + verb string + subject string +} + +func (e DatastoreNoSuchFileError) Error() string { + return fmt.Sprintf("cannot %s '%s': No such file", e.verb, e.subject) +} + +type Datastore struct { + Common + + InventoryPath string +} + +func NewDatastore(c *vim25.Client, ref types.ManagedObjectReference) *Datastore { + return &Datastore{ + Common: NewCommon(c, ref), + } +} + +func (d Datastore) Name() string { + return path.Base(d.InventoryPath) +} + +func (d Datastore) Path(path string) string { + name := d.Name() + if name == "" { + panic("expected non-empty name") + } + + return fmt.Sprintf("[%s] %s", name, path) +} + +// URL for datastore access over HTTP +func (d Datastore) URL(ctx context.Context, dc *Datacenter, path string) (*url.URL, error) { + var mdc mo.Datacenter + if err := dc.Properties(ctx, dc.Reference(), []string{"name"}, &mdc); err != nil { + return nil, err + } + + var mds mo.Datastore + if err := d.Properties(ctx, d.Reference(), []string{"name"}, &mds); err != nil { + return nil, err + } + + u := d.c.URL() + + return &url.URL{ + Scheme: u.Scheme, + Host: u.Host, + Path: fmt.Sprintf("/folder/%s", path), + RawQuery: url.Values{ + "dcPath": []string{mdc.Name}, + "dsName": []string{mds.Name}, + }.Encode(), + }, nil +} + +func (d Datastore) Browser(ctx context.Context) (*HostDatastoreBrowser, error) { + var do mo.Datastore + + err := d.Properties(ctx, d.Reference(), []string{"browser"}, &do) + if err != nil { + return nil, err + } + + return NewHostDatastoreBrowser(d.c, do.Browser), nil +} + +// ServiceTicket obtains a ticket via AcquireGenericServiceTicket and returns it an http.Cookie with the url.URL +// that can be used along with the ticket cookie to access the given path. +func (d Datastore) ServiceTicket(ctx context.Context, path string, method string) (*url.URL, *http.Cookie, error) { + // We are uploading to an ESX host + u := &url.URL{ + Scheme: d.c.URL().Scheme, + Host: d.c.URL().Host, + Path: fmt.Sprintf("/folder/%s", path), + RawQuery: url.Values{ + "dsName": []string{d.Name()}, + }.Encode(), + } + + // If connected to VC, the ticket request must be for an ESX host. + if d.c.IsVC() { + hosts, err := d.AttachedHosts(ctx) + if err != nil { + return nil, nil, err + } + + if len(hosts) == 0 { + return nil, nil, fmt.Errorf("no hosts attached to datastore %#v", d.Reference()) + } + + // Pick a random attached host + host := hosts[rand.Intn(len(hosts))] + name, err := host.Name(ctx) + if err != nil { + return nil, nil, err + } + u.Host = name + } + + spec := types.SessionManagerHttpServiceRequestSpec{ + Url: u.String(), + // See SessionManagerHttpServiceRequestSpecMethod enum + Method: fmt.Sprintf("http%s%s", method[0:1], strings.ToLower(method[1:])), + } + + sm := session.NewManager(d.Client()) + + ticket, err := sm.AcquireGenericServiceTicket(ctx, &spec) + if err != nil { + return nil, nil, err + } + + cookie := &http.Cookie{ + Name: "vmware_cgi_ticket", + Value: ticket.Id, + } + + return u, cookie, nil +} + +func (d Datastore) uploadTicket(ctx context.Context, path string, param *soap.Upload) (*url.URL, *soap.Upload, error) { + p := soap.DefaultUpload + if param != nil { + p = *param // copy + } + + u, ticket, err := d.ServiceTicket(ctx, path, p.Method) + if err != nil { + return nil, nil, err + } + + p.Ticket = ticket + + return u, &p, nil +} + +func (d Datastore) downloadTicket(ctx context.Context, path string, param *soap.Download) (*url.URL, *soap.Download, error) { + p := soap.DefaultDownload + if param != nil { + p = *param // copy + } + + u, ticket, err := d.ServiceTicket(ctx, path, p.Method) + if err != nil { + return nil, nil, err + } + + p.Ticket = ticket + + return u, &p, nil +} + +// Upload via soap.Upload with an http service ticket +func (d Datastore) Upload(ctx context.Context, f io.Reader, path string, param *soap.Upload) error { + u, p, err := d.uploadTicket(ctx, path, param) + if err != nil { + return err + } + return d.Client().Upload(f, u, p) +} + +// UploadFile via soap.Upload with an http service ticket +func (d Datastore) UploadFile(ctx context.Context, file string, path string, param *soap.Upload) error { + u, p, err := d.uploadTicket(ctx, path, param) + if err != nil { + return err + } + return d.Client().UploadFile(file, u, p) +} + +// Download via soap.Download with an http service ticket +func (d Datastore) Download(ctx context.Context, path string, param *soap.Download) (io.ReadCloser, int64, error) { + u, p, err := d.downloadTicket(ctx, path, param) + if err != nil { + return nil, 0, err + } + return d.Client().Download(u, p) +} + +// DownloadFile via soap.Download with an http service ticket +func (d Datastore) DownloadFile(ctx context.Context, path string, file string, param *soap.Download) error { + u, p, err := d.downloadTicket(ctx, path, param) + if err != nil { + return err + } + return d.Client().DownloadFile(file, u, p) +} + +// AttachedHosts returns hosts that have this Datastore attached, accessible and writable. +func (d Datastore) AttachedHosts(ctx context.Context) ([]*HostSystem, error) { + var ds mo.Datastore + var hosts []*HostSystem + + pc := property.DefaultCollector(d.Client()) + err := pc.RetrieveOne(ctx, d.Reference(), []string{"host"}, &ds) + if err != nil { + return nil, err + } + + mounts := make(map[types.ManagedObjectReference]types.DatastoreHostMount) + var refs []types.ManagedObjectReference + for _, host := range ds.Host { + refs = append(refs, host.Key) + mounts[host.Key] = host + } + + var hs []mo.HostSystem + err = pc.Retrieve(ctx, refs, []string{"runtime.connectionState", "runtime.powerState"}, &hs) + if err != nil { + return nil, err + } + + for _, host := range hs { + if host.Runtime.ConnectionState == types.HostSystemConnectionStateConnected && + host.Runtime.PowerState == types.HostSystemPowerStatePoweredOn { + + mount := mounts[host.Reference()] + info := mount.MountInfo + + if *info.Mounted && *info.Accessible && info.AccessMode == string(types.HostMountModeReadWrite) { + hosts = append(hosts, NewHostSystem(d.Client(), mount.Key)) + } + } + } + + return hosts, nil +} + +// AttachedHosts returns hosts that have this Datastore attached, accessible and writable and are members of the given cluster. +func (d Datastore) AttachedClusterHosts(ctx context.Context, cluster *ComputeResource) ([]*HostSystem, error) { + var hosts []*HostSystem + + clusterHosts, err := cluster.Hosts(ctx) + if err != nil { + return nil, err + } + + attachedHosts, err := d.AttachedHosts(ctx) + if err != nil { + return nil, err + } + + refs := make(map[types.ManagedObjectReference]bool) + for _, host := range attachedHosts { + refs[host.Reference()] = true + } + + for _, host := range clusterHosts { + if refs[host.Reference()] { + hosts = append(hosts, host) + } + } + + return hosts, nil +} + +func (d Datastore) Stat(ctx context.Context, file string) (types.BaseFileInfo, error) { + b, err := d.Browser(ctx) + if err != nil { + return nil, err + } + + spec := types.HostDatastoreBrowserSearchSpec{ + Details: &types.FileQueryFlags{ + FileType: true, + FileSize: true, + Modification: true, + FileOwner: types.NewBool(true), + }, + MatchPattern: []string{path.Base(file)}, + } + + dsPath := d.Path(path.Dir(file)) + task, err := b.SearchDatastore(context.TODO(), dsPath, &spec) + if err != nil { + return nil, err + } + + info, err := task.WaitForResult(context.TODO(), nil) + if err != nil { + if info == nil || info.Error != nil { + _, ok := info.Error.Fault.(*types.FileNotFound) + if ok { + // FileNotFound means the base path doesn't exist. + return nil, DatastoreNoSuchDirectoryError{"stat", dsPath} + } + } + + return nil, err + } + + res := info.Result.(types.HostDatastoreBrowserSearchResults) + if len(res.File) == 0 { + // File doesn't exist + return nil, DatastoreNoSuchFileError{"stat", d.Path(file)} + } + + return res.File[0], nil + +} + +// Type returns the type of file system volume. +func (d Datastore) Type(ctx context.Context) (types.HostFileSystemVolumeFileSystemType, error) { + var mds mo.Datastore + + if err := d.Properties(ctx, d.Reference(), []string{"summary.type"}, &mds); err != nil { + return types.HostFileSystemVolumeFileSystemType(""), err + } + return types.HostFileSystemVolumeFileSystemType(mds.Summary.Type), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/diagnostic_manager.go b/vendor/github.com/vmware/govmomi/object/diagnostic_manager.go new file mode 100644 index 0000000000..2a4cf1b8ff --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/diagnostic_manager.go @@ -0,0 +1,95 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type DiagnosticManager struct { + Common +} + +func NewDiagnosticManager(c *vim25.Client) *DiagnosticManager { + m := DiagnosticManager{ + Common: NewCommon(c, *c.ServiceContent.DiagnosticManager), + } + + return &m +} + +func (m DiagnosticManager) BrowseLog(ctx context.Context, host *HostSystem, key string, start, lines int32) (*types.DiagnosticManagerLogHeader, error) { + req := types.BrowseDiagnosticLog{ + This: m.Reference(), + Key: key, + Start: start, + Lines: lines, + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.BrowseDiagnosticLog(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (m DiagnosticManager) GenerateLogBundles(ctx context.Context, includeDefault bool, host []*HostSystem) (*Task, error) { + req := types.GenerateLogBundles_Task{ + This: m.Reference(), + IncludeDefault: includeDefault, + } + + if host != nil { + for _, h := range host { + req.Host = append(req.Host, h.Reference()) + } + } + + res, err := methods.GenerateLogBundles_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} + +func (m DiagnosticManager) QueryDescriptions(ctx context.Context, host *HostSystem) ([]types.DiagnosticManagerLogDescriptor, error) { + req := types.QueryDescriptions{ + This: m.Reference(), + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.QueryDescriptions(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go new file mode 100644 index 0000000000..0dbd4b589f --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "path" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type DistributedVirtualPortgroup struct { + Common + + InventoryPath string +} + +func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectReference) *DistributedVirtualPortgroup { + return &DistributedVirtualPortgroup{ + Common: NewCommon(c, ref), + } +} +func (p DistributedVirtualPortgroup) Name() string { + return path.Base(p.InventoryPath) +} + +// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup +func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) { + var dvp mo.DistributedVirtualPortgroup + var dvs mo.VmwareDistributedVirtualSwitch // TODO: should be mo.BaseDistributedVirtualSwitch + + if err := p.Properties(ctx, p.Reference(), []string{"key", "config.distributedVirtualSwitch"}, &dvp); err != nil { + return nil, err + } + + if err := p.Properties(ctx, *dvp.Config.DistributedVirtualSwitch, []string{"uuid"}, &dvs); err != nil { + return nil, err + } + + backing := &types.VirtualEthernetCardDistributedVirtualPortBackingInfo{ + Port: types.DistributedVirtualSwitchPortConnection{ + PortgroupKey: dvp.Key, + SwitchUuid: dvs.Uuid, + }, + } + + return backing, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go new file mode 100644 index 0000000000..f2fb0abeef --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type DistributedVirtualSwitch struct { + Common + + InventoryPath string +} + +func NewDistributedVirtualSwitch(c *vim25.Client, ref types.ManagedObjectReference) *DistributedVirtualSwitch { + return &DistributedVirtualSwitch{ + Common: NewCommon(c, ref), + } +} + +func (s DistributedVirtualSwitch) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) { + return nil, ErrNotSupported // TODO: just to satisfy NetworkReference interface for the finder +} + +func (s DistributedVirtualSwitch) Reconfigure(ctx context.Context, spec types.BaseDVSConfigSpec) (*Task, error) { + req := types.ReconfigureDvs_Task{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.ReconfigureDvs_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} + +func (s DistributedVirtualSwitch) AddPortgroup(ctx context.Context, spec []types.DVPortgroupConfigSpec) (*Task, error) { + req := types.AddDVPortgroup_Task{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.AddDVPortgroup_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/extension_manager.go b/vendor/github.com/vmware/govmomi/object/extension_manager.go new file mode 100644 index 0000000000..b7ce77c5c5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/extension_manager.go @@ -0,0 +1,112 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ExtensionManager struct { + Common +} + +// GetExtensionManager wraps NewExtensionManager, returning ErrNotSupported +// when the client is not connected to a vCenter instance. +func GetExtensionManager(c *vim25.Client) (*ExtensionManager, error) { + if c.ServiceContent.ExtensionManager == nil { + return nil, ErrNotSupported + } + return NewExtensionManager(c), nil +} + +func NewExtensionManager(c *vim25.Client) *ExtensionManager { + o := ExtensionManager{ + Common: NewCommon(c, *c.ServiceContent.ExtensionManager), + } + + return &o +} + +func (m ExtensionManager) List(ctx context.Context) ([]types.Extension, error) { + var em mo.ExtensionManager + + err := m.Properties(ctx, m.Reference(), []string{"extensionList"}, &em) + if err != nil { + return nil, err + } + + return em.ExtensionList, nil +} + +func (m ExtensionManager) Find(ctx context.Context, key string) (*types.Extension, error) { + req := types.FindExtension{ + This: m.Reference(), + ExtensionKey: key, + } + + res, err := methods.FindExtension(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m ExtensionManager) Register(ctx context.Context, extension types.Extension) error { + req := types.RegisterExtension{ + This: m.Reference(), + Extension: extension, + } + + _, err := methods.RegisterExtension(ctx, m.c, &req) + return err +} + +func (m ExtensionManager) SetCertificate(ctx context.Context, key string, certificatePem string) error { + req := types.SetExtensionCertificate{ + This: m.Reference(), + ExtensionKey: key, + CertificatePem: certificatePem, + } + + _, err := methods.SetExtensionCertificate(ctx, m.c, &req) + return err +} + +func (m ExtensionManager) Unregister(ctx context.Context, key string) error { + req := types.UnregisterExtension{ + This: m.Reference(), + ExtensionKey: key, + } + + _, err := methods.UnregisterExtension(ctx, m.c, &req) + return err +} + +func (m ExtensionManager) Update(ctx context.Context, extension types.Extension) error { + req := types.UpdateExtension{ + This: m.Reference(), + Extension: extension, + } + + _, err := methods.UpdateExtension(ctx, m.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/file_manager.go b/vendor/github.com/vmware/govmomi/object/file_manager.go new file mode 100644 index 0000000000..7164728269 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/file_manager.go @@ -0,0 +1,125 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type FileManager struct { + Common +} + +func NewFileManager(c *vim25.Client) *FileManager { + f := FileManager{ + Common: NewCommon(c, *c.ServiceContent.FileManager), + } + + return &f +} + +func (f FileManager) CopyDatastoreFile(ctx context.Context, sourceName string, sourceDatacenter *Datacenter, destinationName string, destinationDatacenter *Datacenter, force bool) (*Task, error) { + req := types.CopyDatastoreFile_Task{ + This: f.Reference(), + SourceName: sourceName, + DestinationName: destinationName, + Force: types.NewBool(force), + } + + if sourceDatacenter != nil { + ref := sourceDatacenter.Reference() + req.SourceDatacenter = &ref + } + + if destinationDatacenter != nil { + ref := destinationDatacenter.Reference() + req.DestinationDatacenter = &ref + } + + res, err := methods.CopyDatastoreFile_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} + +// DeleteDatastoreFile deletes the specified file or folder from the datastore. +func (f FileManager) DeleteDatastoreFile(ctx context.Context, name string, dc *Datacenter) (*Task, error) { + req := types.DeleteDatastoreFile_Task{ + This: f.Reference(), + Name: name, + } + + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + res, err := methods.DeleteDatastoreFile_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} + +// MakeDirectory creates a folder using the specified name. +func (f FileManager) MakeDirectory(ctx context.Context, name string, dc *Datacenter, createParentDirectories bool) error { + req := types.MakeDirectory{ + This: f.Reference(), + Name: name, + CreateParentDirectories: types.NewBool(createParentDirectories), + } + + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + _, err := methods.MakeDirectory(ctx, f.c, &req) + return err +} + +func (f FileManager) MoveDatastoreFile(ctx context.Context, sourceName string, sourceDatacenter *Datacenter, destinationName string, destinationDatacenter *Datacenter, force bool) (*Task, error) { + req := types.MoveDatastoreFile_Task{ + This: f.Reference(), + SourceName: sourceName, + DestinationName: destinationName, + Force: types.NewBool(force), + } + + if sourceDatacenter != nil { + ref := sourceDatacenter.Reference() + req.SourceDatacenter = &ref + } + + if destinationDatacenter != nil { + ref := destinationDatacenter.Reference() + req.DestinationDatacenter = &ref + } + + res, err := methods.MoveDatastoreFile_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/folder.go b/vendor/github.com/vmware/govmomi/object/folder.go new file mode 100644 index 0000000000..97c793470a --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/folder.go @@ -0,0 +1,214 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type Folder struct { + Common + + InventoryPath string +} + +func NewFolder(c *vim25.Client, ref types.ManagedObjectReference) *Folder { + return &Folder{ + Common: NewCommon(c, ref), + } +} + +func NewRootFolder(c *vim25.Client) *Folder { + f := NewFolder(c, c.ServiceContent.RootFolder) + f.InventoryPath = "/" + return f +} + +func (f Folder) Children(ctx context.Context) ([]Reference, error) { + var mf mo.Folder + + err := f.Properties(ctx, f.Reference(), []string{"childEntity"}, &mf) + if err != nil { + return nil, err + } + + var rs []Reference + for _, e := range mf.ChildEntity { + if r := NewReference(f.c, e); r != nil { + rs = append(rs, r) + } + } + + return rs, nil +} + +func (f Folder) CreateDatacenter(ctx context.Context, datacenter string) (*Datacenter, error) { + req := types.CreateDatacenter{ + This: f.Reference(), + Name: datacenter, + } + + res, err := methods.CreateDatacenter(ctx, f.c, &req) + if err != nil { + return nil, err + } + + // Response will be nil if this is an ESX host that does not belong to a vCenter + if res == nil { + return nil, nil + } + + return NewDatacenter(f.c, res.Returnval), nil +} + +func (f Folder) CreateCluster(ctx context.Context, cluster string, spec types.ClusterConfigSpecEx) (*ClusterComputeResource, error) { + req := types.CreateClusterEx{ + This: f.Reference(), + Name: cluster, + Spec: spec, + } + + res, err := methods.CreateClusterEx(ctx, f.c, &req) + if err != nil { + return nil, err + } + + // Response will be nil if this is an ESX host that does not belong to a vCenter + if res == nil { + return nil, nil + } + + return NewClusterComputeResource(f.c, res.Returnval), nil +} + +func (f Folder) CreateFolder(ctx context.Context, name string) (*Folder, error) { + req := types.CreateFolder{ + This: f.Reference(), + Name: name, + } + + res, err := methods.CreateFolder(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewFolder(f.c, res.Returnval), err +} + +func (f Folder) AddStandaloneHost(ctx context.Context, spec types.HostConnectSpec, addConnected bool, license *string, compResSpec *types.BaseComputeResourceConfigSpec) (*Task, error) { + req := types.AddStandaloneHost_Task{ + This: f.Reference(), + Spec: spec, + AddConnected: addConnected, + } + + if license != nil { + req.License = *license + } + + if compResSpec != nil { + req.CompResSpec = *compResSpec + } + + res, err := methods.AddStandaloneHost_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} + +func (f Folder) CreateVM(ctx context.Context, config types.VirtualMachineConfigSpec, pool *ResourcePool, host *HostSystem) (*Task, error) { + req := types.CreateVM_Task{ + This: f.Reference(), + Config: config, + Pool: pool.Reference(), + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.CreateVM_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} + +func (f Folder) RegisterVM(ctx context.Context, path string, name string, asTemplate bool, pool *ResourcePool, host *HostSystem) (*Task, error) { + req := types.RegisterVM_Task{ + This: f.Reference(), + Path: path, + AsTemplate: asTemplate, + } + + if name != "" { + req.Name = name + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + if pool != nil { + ref := pool.Reference() + req.Pool = &ref + } + + res, err := methods.RegisterVM_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} + +func (f Folder) CreateDVS(ctx context.Context, spec types.DVSCreateSpec) (*Task, error) { + req := types.CreateDVS_Task{ + This: f.Reference(), + Spec: spec, + } + + res, err := methods.CreateDVS_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} + +func (f Folder) MoveInto(ctx context.Context, list []types.ManagedObjectReference) (*Task, error) { + req := types.MoveIntoFolder_Task{ + This: f.Reference(), + List: list, + } + + res, err := methods.MoveIntoFolder_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/history_collector.go b/vendor/github.com/vmware/govmomi/object/history_collector.go new file mode 100644 index 0000000000..9d9ef4c91b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/history_collector.go @@ -0,0 +1,71 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HistoryCollector struct { + Common +} + +func NewHistoryCollector(c *vim25.Client, ref types.ManagedObjectReference) *HistoryCollector { + return &HistoryCollector{ + Common: NewCommon(c, ref), + } +} + +func (h HistoryCollector) Destroy(ctx context.Context) error { + req := types.DestroyCollector{ + This: h.Reference(), + } + + _, err := methods.DestroyCollector(ctx, h.c, &req) + return err +} + +func (h HistoryCollector) Reset(ctx context.Context) error { + req := types.ResetCollector{ + This: h.Reference(), + } + + _, err := methods.ResetCollector(ctx, h.c, &req) + return err +} + +func (h HistoryCollector) Rewind(ctx context.Context) error { + req := types.RewindCollector{ + This: h.Reference(), + } + + _, err := methods.RewindCollector(ctx, h.c, &req) + return err +} + +func (h HistoryCollector) SetPageSize(ctx context.Context, maxCount int32) error { + req := types.SetCollectorPageSize{ + This: h.Reference(), + MaxCount: maxCount, + } + + _, err := methods.SetCollectorPageSize(ctx, h.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_account_manager.go b/vendor/github.com/vmware/govmomi/object/host_account_manager.go new file mode 100644 index 0000000000..9505f508c4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_account_manager.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2016 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostAccountManager struct { + Common +} + +func NewHostAccountManager(c *vim25.Client, ref types.ManagedObjectReference) *HostAccountManager { + return &HostAccountManager{ + Common: NewCommon(c, ref), + } +} + +func (m HostAccountManager) Create(ctx context.Context, user *types.HostAccountSpec) error { + req := types.CreateUser{ + This: m.Reference(), + User: user, + } + + _, err := methods.CreateUser(ctx, m.Client(), &req) + return err +} + +func (m HostAccountManager) Update(ctx context.Context, user *types.HostAccountSpec) error { + req := types.UpdateUser{ + This: m.Reference(), + User: user, + } + + _, err := methods.UpdateUser(ctx, m.Client(), &req) + return err +} + +func (m HostAccountManager) Remove(ctx context.Context, userName string) error { + req := types.RemoveUser{ + This: m.Reference(), + UserName: userName, + } + + _, err := methods.RemoveUser(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_config_manager.go b/vendor/github.com/vmware/govmomi/object/host_config_manager.go new file mode 100644 index 0000000000..12327ee0f0 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_config_manager.go @@ -0,0 +1,122 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostConfigManager struct { + Common +} + +func NewHostConfigManager(c *vim25.Client, ref types.ManagedObjectReference) *HostConfigManager { + return &HostConfigManager{ + Common: NewCommon(c, ref), + } +} + +func (m HostConfigManager) DatastoreSystem(ctx context.Context) (*HostDatastoreSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.datastoreSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostDatastoreSystem(m.c, *h.ConfigManager.DatastoreSystem), nil +} + +func (m HostConfigManager) NetworkSystem(ctx context.Context) (*HostNetworkSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.networkSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostNetworkSystem(m.c, *h.ConfigManager.NetworkSystem), nil +} + +func (m HostConfigManager) FirewallSystem(ctx context.Context) (*HostFirewallSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.firewallSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostFirewallSystem(m.c, *h.ConfigManager.FirewallSystem), nil +} + +func (m HostConfigManager) StorageSystem(ctx context.Context) (*HostStorageSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.storageSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostStorageSystem(m.c, *h.ConfigManager.StorageSystem), nil +} + +func (m HostConfigManager) VirtualNicManager(ctx context.Context) (*HostVirtualNicManager, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.virtualNicManager"}, &h) + if err != nil { + return nil, err + } + + return NewHostVirtualNicManager(m.c, *h.ConfigManager.VirtualNicManager, m.Reference()), nil +} + +func (m HostConfigManager) VsanSystem(ctx context.Context) (*HostVsanSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.vsanSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostVsanSystem(m.c, *h.ConfigManager.VsanSystem), nil +} + +func (m HostConfigManager) AccountManager(ctx context.Context) (*HostAccountManager, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.accountManager"}, &h) + if err != nil { + return nil, err + } + + return NewHostAccountManager(m.c, *h.ConfigManager.AccountManager), nil +} + +func (m HostConfigManager) OptionManager(ctx context.Context) (*OptionManager, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.advancedOption"}, &h) + if err != nil { + return nil, err + } + + return NewOptionManager(m.c, *h.ConfigManager.AdvancedOption), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go b/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go new file mode 100644 index 0000000000..a2e2056634 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostDatastoreBrowser struct { + Common +} + +func NewHostDatastoreBrowser(c *vim25.Client, ref types.ManagedObjectReference) *HostDatastoreBrowser { + return &HostDatastoreBrowser{ + Common: NewCommon(c, ref), + } +} + +func (b HostDatastoreBrowser) SearchDatastore(ctx context.Context, datastorePath string, searchSpec *types.HostDatastoreBrowserSearchSpec) (*Task, error) { + req := types.SearchDatastore_Task{ + This: b.Reference(), + DatastorePath: datastorePath, + SearchSpec: searchSpec, + } + + res, err := methods.SearchDatastore_Task(ctx, b.c, &req) + if err != nil { + return nil, err + } + + return NewTask(b.c, res.Returnval), nil +} + +func (b HostDatastoreBrowser) SearchDatastoreSubFolders(ctx context.Context, datastorePath string, searchSpec *types.HostDatastoreBrowserSearchSpec) (*Task, error) { + req := types.SearchDatastoreSubFolders_Task{ + This: b.Reference(), + DatastorePath: datastorePath, + SearchSpec: searchSpec, + } + + res, err := methods.SearchDatastoreSubFolders_Task(ctx, b.c, &req) + if err != nil { + return nil, err + } + + return NewTask(b.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_datastore_system.go b/vendor/github.com/vmware/govmomi/object/host_datastore_system.go new file mode 100644 index 0000000000..632b7d255b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_datastore_system.go @@ -0,0 +1,103 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostDatastoreSystem struct { + Common +} + +func NewHostDatastoreSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostDatastoreSystem { + return &HostDatastoreSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostDatastoreSystem) CreateNasDatastore(ctx context.Context, spec types.HostNasVolumeSpec) (*Datastore, error) { + req := types.CreateNasDatastore{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.CreateNasDatastore(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewDatastore(s.Client(), res.Returnval), nil +} + +func (s HostDatastoreSystem) CreateVmfsDatastore(ctx context.Context, spec types.VmfsDatastoreCreateSpec) (*Datastore, error) { + req := types.CreateVmfsDatastore{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.CreateVmfsDatastore(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewDatastore(s.Client(), res.Returnval), nil +} + +func (s HostDatastoreSystem) Remove(ctx context.Context, ds *Datastore) error { + req := types.RemoveDatastore{ + This: s.Reference(), + Datastore: ds.Reference(), + } + + _, err := methods.RemoveDatastore(ctx, s.Client(), &req) + if err != nil { + return err + } + + return nil +} + +func (s HostDatastoreSystem) QueryAvailableDisksForVmfs(ctx context.Context) ([]types.HostScsiDisk, error) { + req := types.QueryAvailableDisksForVmfs{ + This: s.Reference(), + } + + res, err := methods.QueryAvailableDisksForVmfs(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (s HostDatastoreSystem) QueryVmfsDatastoreCreateOptions(ctx context.Context, devicePath string) ([]types.VmfsDatastoreOption, error) { + req := types.QueryVmfsDatastoreCreateOptions{ + This: s.Reference(), + DevicePath: devicePath, + } + + res, err := methods.QueryVmfsDatastoreCreateOptions(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_firewall_system.go b/vendor/github.com/vmware/govmomi/object/host_firewall_system.go new file mode 100644 index 0000000000..143f0983de --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_firewall_system.go @@ -0,0 +1,181 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + "fmt" + "strings" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostFirewallSystem struct { + Common +} + +func NewHostFirewallSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostFirewallSystem { + return &HostFirewallSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostFirewallSystem) DisableRuleset(ctx context.Context, id string) error { + req := types.DisableRuleset{ + This: s.Reference(), + Id: id, + } + + _, err := methods.DisableRuleset(ctx, s.c, &req) + return err +} + +func (s HostFirewallSystem) EnableRuleset(ctx context.Context, id string) error { + req := types.EnableRuleset{ + This: s.Reference(), + Id: id, + } + + _, err := methods.EnableRuleset(ctx, s.c, &req) + return err +} + +func (s HostFirewallSystem) Refresh(ctx context.Context) error { + req := types.RefreshFirewall{ + This: s.Reference(), + } + + _, err := methods.RefreshFirewall(ctx, s.c, &req) + return err +} + +func (s HostFirewallSystem) Info(ctx context.Context) (*types.HostFirewallInfo, error) { + var fs mo.HostFirewallSystem + + err := s.Properties(ctx, s.Reference(), []string{"firewallInfo"}, &fs) + if err != nil { + return nil, err + } + + return fs.FirewallInfo, nil +} + +// HostFirewallRulesetList provides helpers for a slice of types.HostFirewallRuleset +type HostFirewallRulesetList []types.HostFirewallRuleset + +// ByRule returns a HostFirewallRulesetList where Direction, PortType and Protocol are equal and Port is within range +func (l HostFirewallRulesetList) ByRule(rule types.HostFirewallRule) HostFirewallRulesetList { + var matches HostFirewallRulesetList + + for _, rs := range l { + for _, r := range rs.Rule { + if r.PortType != rule.PortType || + r.Protocol != rule.Protocol || + r.Direction != rule.Direction { + continue + } + + if r.EndPort == 0 && rule.Port == r.Port || + rule.Port >= r.Port && rule.Port <= r.EndPort { + matches = append(matches, rs) + break + } + } + } + + return matches +} + +// EnabledByRule returns a HostFirewallRulesetList with Match(rule) applied and filtered via Enabled() +// if enabled param is true, otherwise filtered via Disabled(). +// An error is returned if the resulting list is empty. +func (l HostFirewallRulesetList) EnabledByRule(rule types.HostFirewallRule, enabled bool) (HostFirewallRulesetList, error) { + var matched, skipped HostFirewallRulesetList + var matchedKind, skippedKind string + + l = l.ByRule(rule) + + if enabled { + matched = l.Enabled() + matchedKind = "enabled" + + skipped = l.Disabled() + skippedKind = "disabled" + } else { + matched = l.Disabled() + matchedKind = "disabled" + + skipped = l.Enabled() + skippedKind = "enabled" + } + + if len(matched) == 0 { + msg := fmt.Sprintf("%d %s firewall rulesets match %s %s %s %d, %d %s rulesets match", + len(matched), matchedKind, + rule.Direction, rule.Protocol, rule.PortType, rule.Port, + len(skipped), skippedKind) + + if len(skipped) != 0 { + msg += fmt.Sprintf(": %s", strings.Join(skipped.Keys(), ", ")) + } + + return nil, errors.New(msg) + } + + return matched, nil +} + +// Enabled returns a HostFirewallRulesetList with enabled rules +func (l HostFirewallRulesetList) Enabled() HostFirewallRulesetList { + var matches HostFirewallRulesetList + + for _, rs := range l { + if rs.Enabled { + matches = append(matches, rs) + } + } + + return matches +} + +// Disabled returns a HostFirewallRulesetList with disabled rules +func (l HostFirewallRulesetList) Disabled() HostFirewallRulesetList { + var matches HostFirewallRulesetList + + for _, rs := range l { + if !rs.Enabled { + matches = append(matches, rs) + } + } + + return matches +} + +// Keys returns the HostFirewallRuleset.Key for each ruleset in the list +func (l HostFirewallRulesetList) Keys() []string { + var keys []string + + for _, rs := range l { + keys = append(keys, rs.Key) + } + + return keys +} diff --git a/vendor/github.com/vmware/govmomi/object/host_network_system.go b/vendor/github.com/vmware/govmomi/object/host_network_system.go new file mode 100644 index 0000000000..1418de42f4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_network_system.go @@ -0,0 +1,357 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostNetworkSystem struct { + Common +} + +func NewHostNetworkSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostNetworkSystem { + return &HostNetworkSystem{ + Common: NewCommon(c, ref), + } +} + +// AddPortGroup wraps methods.AddPortGroup +func (o HostNetworkSystem) AddPortGroup(ctx context.Context, portgrp types.HostPortGroupSpec) error { + req := types.AddPortGroup{ + This: o.Reference(), + Portgrp: portgrp, + } + + _, err := methods.AddPortGroup(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// AddServiceConsoleVirtualNic wraps methods.AddServiceConsoleVirtualNic +func (o HostNetworkSystem) AddServiceConsoleVirtualNic(ctx context.Context, portgroup string, nic types.HostVirtualNicSpec) (string, error) { + req := types.AddServiceConsoleVirtualNic{ + This: o.Reference(), + Portgroup: portgroup, + Nic: nic, + } + + res, err := methods.AddServiceConsoleVirtualNic(ctx, o.c, &req) + if err != nil { + return "", err + } + + return res.Returnval, nil +} + +// AddVirtualNic wraps methods.AddVirtualNic +func (o HostNetworkSystem) AddVirtualNic(ctx context.Context, portgroup string, nic types.HostVirtualNicSpec) (string, error) { + req := types.AddVirtualNic{ + This: o.Reference(), + Portgroup: portgroup, + Nic: nic, + } + + res, err := methods.AddVirtualNic(ctx, o.c, &req) + if err != nil { + return "", err + } + + return res.Returnval, nil +} + +// AddVirtualSwitch wraps methods.AddVirtualSwitch +func (o HostNetworkSystem) AddVirtualSwitch(ctx context.Context, vswitchName string, spec *types.HostVirtualSwitchSpec) error { + req := types.AddVirtualSwitch{ + This: o.Reference(), + VswitchName: vswitchName, + Spec: spec, + } + + _, err := methods.AddVirtualSwitch(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// QueryNetworkHint wraps methods.QueryNetworkHint +func (o HostNetworkSystem) QueryNetworkHint(ctx context.Context, device []string) error { + req := types.QueryNetworkHint{ + This: o.Reference(), + Device: device, + } + + _, err := methods.QueryNetworkHint(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// RefreshNetworkSystem wraps methods.RefreshNetworkSystem +func (o HostNetworkSystem) RefreshNetworkSystem(ctx context.Context) error { + req := types.RefreshNetworkSystem{ + This: o.Reference(), + } + + _, err := methods.RefreshNetworkSystem(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// RemovePortGroup wraps methods.RemovePortGroup +func (o HostNetworkSystem) RemovePortGroup(ctx context.Context, pgName string) error { + req := types.RemovePortGroup{ + This: o.Reference(), + PgName: pgName, + } + + _, err := methods.RemovePortGroup(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// RemoveServiceConsoleVirtualNic wraps methods.RemoveServiceConsoleVirtualNic +func (o HostNetworkSystem) RemoveServiceConsoleVirtualNic(ctx context.Context, device string) error { + req := types.RemoveServiceConsoleVirtualNic{ + This: o.Reference(), + Device: device, + } + + _, err := methods.RemoveServiceConsoleVirtualNic(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// RemoveVirtualNic wraps methods.RemoveVirtualNic +func (o HostNetworkSystem) RemoveVirtualNic(ctx context.Context, device string) error { + req := types.RemoveVirtualNic{ + This: o.Reference(), + Device: device, + } + + _, err := methods.RemoveVirtualNic(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// RemoveVirtualSwitch wraps methods.RemoveVirtualSwitch +func (o HostNetworkSystem) RemoveVirtualSwitch(ctx context.Context, vswitchName string) error { + req := types.RemoveVirtualSwitch{ + This: o.Reference(), + VswitchName: vswitchName, + } + + _, err := methods.RemoveVirtualSwitch(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// RestartServiceConsoleVirtualNic wraps methods.RestartServiceConsoleVirtualNic +func (o HostNetworkSystem) RestartServiceConsoleVirtualNic(ctx context.Context, device string) error { + req := types.RestartServiceConsoleVirtualNic{ + This: o.Reference(), + Device: device, + } + + _, err := methods.RestartServiceConsoleVirtualNic(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateConsoleIpRouteConfig wraps methods.UpdateConsoleIpRouteConfig +func (o HostNetworkSystem) UpdateConsoleIpRouteConfig(ctx context.Context, config types.BaseHostIpRouteConfig) error { + req := types.UpdateConsoleIpRouteConfig{ + This: o.Reference(), + Config: config, + } + + _, err := methods.UpdateConsoleIpRouteConfig(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateDnsConfig wraps methods.UpdateDnsConfig +func (o HostNetworkSystem) UpdateDnsConfig(ctx context.Context, config types.BaseHostDnsConfig) error { + req := types.UpdateDnsConfig{ + This: o.Reference(), + Config: config, + } + + _, err := methods.UpdateDnsConfig(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateIpRouteConfig wraps methods.UpdateIpRouteConfig +func (o HostNetworkSystem) UpdateIpRouteConfig(ctx context.Context, config types.BaseHostIpRouteConfig) error { + req := types.UpdateIpRouteConfig{ + This: o.Reference(), + Config: config, + } + + _, err := methods.UpdateIpRouteConfig(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateIpRouteTableConfig wraps methods.UpdateIpRouteTableConfig +func (o HostNetworkSystem) UpdateIpRouteTableConfig(ctx context.Context, config types.HostIpRouteTableConfig) error { + req := types.UpdateIpRouteTableConfig{ + This: o.Reference(), + Config: config, + } + + _, err := methods.UpdateIpRouteTableConfig(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateNetworkConfig wraps methods.UpdateNetworkConfig +func (o HostNetworkSystem) UpdateNetworkConfig(ctx context.Context, config types.HostNetworkConfig, changeMode string) (*types.HostNetworkConfigResult, error) { + req := types.UpdateNetworkConfig{ + This: o.Reference(), + Config: config, + ChangeMode: changeMode, + } + + res, err := methods.UpdateNetworkConfig(ctx, o.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +// UpdatePhysicalNicLinkSpeed wraps methods.UpdatePhysicalNicLinkSpeed +func (o HostNetworkSystem) UpdatePhysicalNicLinkSpeed(ctx context.Context, device string, linkSpeed *types.PhysicalNicLinkInfo) error { + req := types.UpdatePhysicalNicLinkSpeed{ + This: o.Reference(), + Device: device, + LinkSpeed: linkSpeed, + } + + _, err := methods.UpdatePhysicalNicLinkSpeed(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdatePortGroup wraps methods.UpdatePortGroup +func (o HostNetworkSystem) UpdatePortGroup(ctx context.Context, pgName string, portgrp types.HostPortGroupSpec) error { + req := types.UpdatePortGroup{ + This: o.Reference(), + PgName: pgName, + Portgrp: portgrp, + } + + _, err := methods.UpdatePortGroup(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateServiceConsoleVirtualNic wraps methods.UpdateServiceConsoleVirtualNic +func (o HostNetworkSystem) UpdateServiceConsoleVirtualNic(ctx context.Context, device string, nic types.HostVirtualNicSpec) error { + req := types.UpdateServiceConsoleVirtualNic{ + This: o.Reference(), + Device: device, + Nic: nic, + } + + _, err := methods.UpdateServiceConsoleVirtualNic(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateVirtualNic wraps methods.UpdateVirtualNic +func (o HostNetworkSystem) UpdateVirtualNic(ctx context.Context, device string, nic types.HostVirtualNicSpec) error { + req := types.UpdateVirtualNic{ + This: o.Reference(), + Device: device, + Nic: nic, + } + + _, err := methods.UpdateVirtualNic(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// UpdateVirtualSwitch wraps methods.UpdateVirtualSwitch +func (o HostNetworkSystem) UpdateVirtualSwitch(ctx context.Context, vswitchName string, spec types.HostVirtualSwitchSpec) error { + req := types.UpdateVirtualSwitch{ + This: o.Reference(), + VswitchName: vswitchName, + Spec: spec, + } + + _, err := methods.UpdateVirtualSwitch(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_storage_system.go b/vendor/github.com/vmware/govmomi/object/host_storage_system.go new file mode 100644 index 0000000000..36cd68e3ad --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_storage_system.go @@ -0,0 +1,80 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostStorageSystem struct { + Common +} + +func NewHostStorageSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostStorageSystem { + return &HostStorageSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostStorageSystem) RetrieveDiskPartitionInfo(ctx context.Context, devicePath string) (*types.HostDiskPartitionInfo, error) { + req := types.RetrieveDiskPartitionInfo{ + This: s.Reference(), + DevicePath: []string{devicePath}, + } + + res, err := methods.RetrieveDiskPartitionInfo(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil || len(res.Returnval) == 0 { + return nil, errors.New("no partition info") + } + + return &res.Returnval[0], nil +} + +func (s HostStorageSystem) ComputeDiskPartitionInfo(ctx context.Context, devicePath string, layout types.HostDiskPartitionLayout) (*types.HostDiskPartitionInfo, error) { + req := types.ComputeDiskPartitionInfo{ + This: s.Reference(), + DevicePath: devicePath, + Layout: layout, + } + + res, err := methods.ComputeDiskPartitionInfo(ctx, s.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (s HostStorageSystem) UpdateDiskPartitionInfo(ctx context.Context, devicePath string, spec types.HostDiskPartitionSpec) error { + req := types.UpdateDiskPartitions{ + This: s.Reference(), + DevicePath: devicePath, + Spec: spec, + } + + _, err := methods.UpdateDiskPartitions(ctx, s.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_system.go b/vendor/github.com/vmware/govmomi/object/host_system.go new file mode 100644 index 0000000000..0146d9ae50 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_system.go @@ -0,0 +1,173 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "fmt" + "net" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostSystem struct { + Common + + InventoryPath string +} + +func (h HostSystem) String() string { + if h.InventoryPath == "" { + return h.Common.String() + } + return fmt.Sprintf("%v @ %v", h.Common, h.InventoryPath) +} + +func NewHostSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostSystem { + return &HostSystem{ + Common: NewCommon(c, ref), + } +} + +func (h HostSystem) Name(ctx context.Context) (string, error) { + var mh mo.HostSystem + + err := h.Properties(ctx, h.Reference(), []string{"name"}, &mh) + if err != nil { + return "", err + } + + return mh.Name, nil +} + +func (h HostSystem) ConfigManager() *HostConfigManager { + return NewHostConfigManager(h.c, h.Reference()) +} + +func (h HostSystem) ResourcePool(ctx context.Context) (*ResourcePool, error) { + var mh mo.HostSystem + + err := h.Properties(ctx, h.Reference(), []string{"parent"}, &mh) + if err != nil { + return nil, err + } + + var mcr *mo.ComputeResource + var parent interface{} + + switch mh.Parent.Type { + case "ComputeResource": + mcr = new(mo.ComputeResource) + parent = mcr + case "ClusterComputeResource": + mcc := new(mo.ClusterComputeResource) + mcr = &mcc.ComputeResource + parent = mcc + default: + return nil, fmt.Errorf("unknown host parent type: %s", mh.Parent.Type) + } + + err = h.Properties(ctx, *mh.Parent, []string{"resourcePool"}, parent) + if err != nil { + return nil, err + } + + pool := NewResourcePool(h.c, *mcr.ResourcePool) + return pool, nil +} + +func (h HostSystem) ManagementIPs(ctx context.Context) ([]net.IP, error) { + var mh mo.HostSystem + + err := h.Properties(ctx, h.Reference(), []string{"config.virtualNicManagerInfo.netConfig"}, &mh) + if err != nil { + return nil, err + } + + var ips []net.IP + for _, nc := range mh.Config.VirtualNicManagerInfo.NetConfig { + if nc.NicType == "management" && len(nc.CandidateVnic) > 0 { + ip := net.ParseIP(nc.CandidateVnic[0].Spec.Ip.IpAddress) + if ip != nil { + ips = append(ips, ip) + } + } + } + + return ips, nil +} + +func (h HostSystem) Disconnect(ctx context.Context) (*Task, error) { + req := types.DisconnectHost_Task{ + This: h.Reference(), + } + + res, err := methods.DisconnectHost_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} + +func (h HostSystem) Reconnect(ctx context.Context, cnxSpec *types.HostConnectSpec, reconnectSpec *types.HostSystemReconnectSpec) (*Task, error) { + req := types.ReconnectHost_Task{ + This: h.Reference(), + CnxSpec: cnxSpec, + ReconnectSpec: reconnectSpec, + } + + res, err := methods.ReconnectHost_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} + +func (h HostSystem) EnterMaintenanceMode(ctx context.Context, timeout int32, evacuate bool, spec *types.HostMaintenanceSpec) (*Task, error) { + req := types.EnterMaintenanceMode_Task{ + This: h.Reference(), + Timeout: timeout, + EvacuatePoweredOffVms: types.NewBool(evacuate), + MaintenanceSpec: spec, + } + + res, err := methods.EnterMaintenanceMode_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} + +func (h HostSystem) ExitMaintenanceMode(ctx context.Context, timeout int32) (*Task, error) { + req := types.ExitMaintenanceMode_Task{ + This: h.Reference(), + Timeout: timeout, + } + + res, err := methods.ExitMaintenanceMode_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_virtual_nic_manager.go b/vendor/github.com/vmware/govmomi/object/host_virtual_nic_manager.go new file mode 100644 index 0000000000..05338b82e1 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_virtual_nic_manager.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostVirtualNicManager struct { + Common + Host *HostSystem +} + +func NewHostVirtualNicManager(c *vim25.Client, ref types.ManagedObjectReference, host types.ManagedObjectReference) *HostVirtualNicManager { + return &HostVirtualNicManager{ + Common: NewCommon(c, ref), + Host: NewHostSystem(c, host), + } +} + +func (m HostVirtualNicManager) Info(ctx context.Context) (*types.HostVirtualNicManagerInfo, error) { + var vnm mo.HostVirtualNicManager + + err := m.Properties(ctx, m.Reference(), []string{"info"}, &vnm) + if err != nil { + return nil, err + } + + return &vnm.Info, nil +} + +func (m HostVirtualNicManager) DeselectVnic(ctx context.Context, nicType string, device string) error { + if nicType == string(types.HostVirtualNicManagerNicTypeVsan) { + // Avoid fault.NotSupported: + // "Error deselecting device '$device': VSAN interfaces must be deselected using vim.host.VsanSystem" + s, err := m.Host.ConfigManager().VsanSystem(ctx) + if err != nil { + return err + } + + return s.updateVnic(ctx, device, false) + } + + req := types.DeselectVnicForNicType{ + This: m.Reference(), + NicType: nicType, + Device: device, + } + + _, err := methods.DeselectVnicForNicType(ctx, m.Client(), &req) + return err +} + +func (m HostVirtualNicManager) SelectVnic(ctx context.Context, nicType string, device string) error { + if nicType == string(types.HostVirtualNicManagerNicTypeVsan) { + // Avoid fault.NotSupported: + // "Error selecting device '$device': VSAN interfaces must be selected using vim.host.VsanSystem" + s, err := m.Host.ConfigManager().VsanSystem(ctx) + if err != nil { + return err + } + + return s.updateVnic(ctx, device, true) + } + + req := types.SelectVnicForNicType{ + This: m.Reference(), + NicType: nicType, + Device: device, + } + + _, err := methods.SelectVnicForNicType(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_vsan_system.go b/vendor/github.com/vmware/govmomi/object/host_vsan_system.go new file mode 100644 index 0000000000..8c571421d3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_vsan_system.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostVsanSystem struct { + Common +} + +func NewHostVsanSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostVsanSystem { + return &HostVsanSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostVsanSystem) Update(ctx context.Context, config types.VsanHostConfigInfo) (*Task, error) { + req := types.UpdateVsan_Task{ + This: s.Reference(), + Config: config, + } + + res, err := methods.UpdateVsan_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} + +// updateVnic in support of the HostVirtualNicManager.{SelectVnic,DeselectVnic} methods +func (s HostVsanSystem) updateVnic(ctx context.Context, device string, enable bool) error { + var vsan mo.HostVsanSystem + + err := s.Properties(ctx, s.Reference(), []string{"config.networkInfo.port"}, &vsan) + if err != nil { + return err + } + + info := vsan.Config + + var port []types.VsanHostConfigInfoNetworkInfoPortConfig + + for _, p := range info.NetworkInfo.Port { + if p.Device == device { + continue + } + + port = append(port, p) + } + + if enable { + port = append(port, types.VsanHostConfigInfoNetworkInfoPortConfig{ + Device: device, + }) + } + + info.NetworkInfo.Port = port + + task, err := s.Update(ctx, info) + if err != nil { + return err + } + + _, err = task.WaitForResult(ctx, nil) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go b/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go new file mode 100644 index 0000000000..3b06e3c3ab --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go @@ -0,0 +1,143 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + "fmt" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HttpNfcLease struct { + Common +} + +func NewHttpNfcLease(c *vim25.Client, ref types.ManagedObjectReference) *HttpNfcLease { + return &HttpNfcLease{ + Common: NewCommon(c, ref), + } +} + +// HttpNfcLeaseAbort wraps methods.HttpNfcLeaseAbort +func (o HttpNfcLease) HttpNfcLeaseAbort(ctx context.Context, fault *types.LocalizedMethodFault) error { + req := types.HttpNfcLeaseAbort{ + This: o.Reference(), + Fault: fault, + } + + _, err := methods.HttpNfcLeaseAbort(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// HttpNfcLeaseComplete wraps methods.HttpNfcLeaseComplete +func (o HttpNfcLease) HttpNfcLeaseComplete(ctx context.Context) error { + req := types.HttpNfcLeaseComplete{ + This: o.Reference(), + } + + _, err := methods.HttpNfcLeaseComplete(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// HttpNfcLeaseGetManifest wraps methods.HttpNfcLeaseGetManifest +func (o HttpNfcLease) HttpNfcLeaseGetManifest(ctx context.Context) error { + req := types.HttpNfcLeaseGetManifest{ + This: o.Reference(), + } + + _, err := methods.HttpNfcLeaseGetManifest(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +// HttpNfcLeaseProgress wraps methods.HttpNfcLeaseProgress +func (o HttpNfcLease) HttpNfcLeaseProgress(ctx context.Context, percent int32) error { + req := types.HttpNfcLeaseProgress{ + This: o.Reference(), + Percent: percent, + } + + _, err := methods.HttpNfcLeaseProgress(ctx, o.c, &req) + if err != nil { + return err + } + + return nil +} + +func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error) { + var lease mo.HttpNfcLease + + pc := property.DefaultCollector(o.c) + err := property.Wait(ctx, pc, o.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool { + done := false + + for _, c := range pc { + if c.Val == nil { + continue + } + + switch c.Name { + case "error": + val := c.Val.(types.LocalizedMethodFault) + lease.Error = &val + done = true + case "info": + val := c.Val.(types.HttpNfcLeaseInfo) + lease.Info = &val + case "state": + lease.State = c.Val.(types.HttpNfcLeaseState) + if lease.State != types.HttpNfcLeaseStateInitializing { + done = true + } + } + } + + return done + }) + + if err != nil { + return nil, err + } + + if lease.State == types.HttpNfcLeaseStateReady { + return lease.Info, nil + } + + if lease.Error != nil { + return nil, errors.New(lease.Error.LocalizedMessage) + } + + return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State) +} diff --git a/vendor/github.com/vmware/govmomi/object/list_view.go b/vendor/github.com/vmware/govmomi/object/list_view.go new file mode 100644 index 0000000000..a79d33bc3d --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/list_view.go @@ -0,0 +1,43 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ListView struct { + Common +} + +func NewListView(c *vim25.Client, ref types.ManagedObjectReference) *ListView { + return &ListView{ + Common: NewCommon(c, ref), + } +} + +func (v ListView) Destroy(ctx context.Context) error { + req := types.DestroyView{ + This: v.Reference(), + } + + _, err := methods.DestroyView(ctx, v.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/network.go b/vendor/github.com/vmware/govmomi/object/network.go new file mode 100644 index 0000000000..9963744aa7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/network.go @@ -0,0 +1,54 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "path" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type Network struct { + Common + + InventoryPath string +} + +func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network { + return &Network{ + Common: NewCommon(c, ref), + } +} + +func (n Network) Name() string { + return path.Base(n.InventoryPath) +} + +// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network +func (n Network) EthernetCardBackingInfo(_ context.Context) (types.BaseVirtualDeviceBackingInfo, error) { + name := n.Name() + + backing := &types.VirtualEthernetCardNetworkBackingInfo{ + VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{ + DeviceName: name, + }, + } + + return backing, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/network_reference.go b/vendor/github.com/vmware/govmomi/object/network_reference.go new file mode 100644 index 0000000000..98dd538130 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/network_reference.go @@ -0,0 +1,30 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// The NetworkReference interface is implemented by managed objects +// which can be used as the backing for a VirtualEthernetCard. +type NetworkReference interface { + Reference + + EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) +} diff --git a/vendor/github.com/vmware/govmomi/object/option_manager.go b/vendor/github.com/vmware/govmomi/object/option_manager.go new file mode 100644 index 0000000000..eae1223ccc --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/option_manager.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2016 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type OptionManager struct { + Common +} + +func NewOptionManager(c *vim25.Client, ref types.ManagedObjectReference) *OptionManager { + return &OptionManager{ + Common: NewCommon(c, ref), + } +} + +func (m OptionManager) Query(ctx context.Context, name string) ([]types.BaseOptionValue, error) { + req := types.QueryOptions{ + This: m.Reference(), + Name: name, + } + + res, err := methods.QueryOptions(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m OptionManager) Update(ctx context.Context, value []types.BaseOptionValue) error { + req := types.UpdateOptions{ + This: m.Reference(), + ChangedValue: value, + } + + _, err := methods.UpdateOptions(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/ovf_manager.go b/vendor/github.com/vmware/govmomi/object/ovf_manager.go new file mode 100644 index 0000000000..e7912d0fd0 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/ovf_manager.go @@ -0,0 +1,103 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type OvfManager struct { + Common +} + +func NewOvfManager(c *vim25.Client) *OvfManager { + o := OvfManager{ + Common: NewCommon(c, *c.ServiceContent.OvfManager), + } + + return &o +} + +// CreateDescriptor wraps methods.CreateDescriptor +func (o OvfManager) CreateDescriptor(ctx context.Context, obj Reference, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) { + req := types.CreateDescriptor{ + This: o.Reference(), + Obj: obj.Reference(), + Cdp: cdp, + } + + res, err := methods.CreateDescriptor(ctx, o.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +// CreateImportSpec wraps methods.CreateImportSpec +func (o OvfManager) CreateImportSpec(ctx context.Context, ovfDescriptor string, resourcePool Reference, datastore Reference, cisp types.OvfCreateImportSpecParams) (*types.OvfCreateImportSpecResult, error) { + req := types.CreateImportSpec{ + This: o.Reference(), + OvfDescriptor: ovfDescriptor, + ResourcePool: resourcePool.Reference(), + Datastore: datastore.Reference(), + Cisp: cisp, + } + + res, err := methods.CreateImportSpec(ctx, o.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +// ParseDescriptor wraps methods.ParseDescriptor +func (o OvfManager) ParseDescriptor(ctx context.Context, ovfDescriptor string, pdp types.OvfParseDescriptorParams) (*types.OvfParseDescriptorResult, error) { + req := types.ParseDescriptor{ + This: o.Reference(), + OvfDescriptor: ovfDescriptor, + Pdp: pdp, + } + + res, err := methods.ParseDescriptor(ctx, o.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +// ValidateHost wraps methods.ValidateHost +func (o OvfManager) ValidateHost(ctx context.Context, ovfDescriptor string, host Reference, vhp types.OvfValidateHostParams) (*types.OvfValidateHostResult, error) { + req := types.ValidateHost{ + This: o.Reference(), + OvfDescriptor: ovfDescriptor, + Host: host.Reference(), + Vhp: vhp, + } + + res, err := methods.ValidateHost(ctx, o.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/resource_pool.go b/vendor/github.com/vmware/govmomi/object/resource_pool.go new file mode 100644 index 0000000000..e03460854e --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/resource_pool.go @@ -0,0 +1,159 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "fmt" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ResourcePool struct { + Common + + InventoryPath string +} + +func (p ResourcePool) String() string { + if p.InventoryPath == "" { + return p.Common.String() + } + return fmt.Sprintf("%v @ %v", p.Common, p.InventoryPath) +} + +func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *ResourcePool { + return &ResourcePool{ + Common: NewCommon(c, ref), + } +} + +func (p ResourcePool) Name(ctx context.Context) (string, error) { + var o mo.ResourcePool + + err := p.Properties(ctx, p.Reference(), []string{"name"}, &o) + if err != nil { + return "", err + } + + return o.Name, nil +} + +func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*HttpNfcLease, error) { + req := types.ImportVApp{ + This: p.Reference(), + Spec: spec, + } + + if folder != nil { + ref := folder.Reference() + req.Folder = &ref + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.ImportVApp(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewHttpNfcLease(p.c, res.Returnval), nil +} + +func (p ResourcePool) Create(ctx context.Context, name string, spec types.ResourceConfigSpec) (*ResourcePool, error) { + req := types.CreateResourcePool{ + This: p.Reference(), + Name: name, + Spec: spec, + } + + res, err := methods.CreateResourcePool(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewResourcePool(p.c, res.Returnval), nil +} + +func (p ResourcePool) CreateVApp(ctx context.Context, name string, resSpec types.ResourceConfigSpec, configSpec types.VAppConfigSpec, folder *Folder) (*VirtualApp, error) { + req := types.CreateVApp{ + This: p.Reference(), + Name: name, + ResSpec: resSpec, + ConfigSpec: configSpec, + } + + if folder != nil { + ref := folder.Reference() + req.VmFolder = &ref + } + + res, err := methods.CreateVApp(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewVirtualApp(p.c, res.Returnval), nil +} + +func (p ResourcePool) UpdateConfig(ctx context.Context, name string, config *types.ResourceConfigSpec) error { + req := types.UpdateConfig{ + This: p.Reference(), + Name: name, + Config: config, + } + + if config != nil && config.Entity == nil { + ref := p.Reference() + + // Create copy of config so changes won't leak back to the caller + newConfig := *config + newConfig.Entity = &ref + req.Config = &newConfig + } + + _, err := methods.UpdateConfig(ctx, p.c, &req) + return err +} + +func (p ResourcePool) DestroyChildren(ctx context.Context) error { + req := types.DestroyChildren{ + This: p.Reference(), + } + + _, err := methods.DestroyChildren(ctx, p.c, &req) + return err +} + +func (p ResourcePool) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: p.Reference(), + } + + res, err := methods.Destroy_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/search_index.go b/vendor/github.com/vmware/govmomi/object/search_index.go new file mode 100644 index 0000000000..638c8de2a5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/search_index.go @@ -0,0 +1,162 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type SearchIndex struct { + Common +} + +func NewSearchIndex(c *vim25.Client) *SearchIndex { + s := SearchIndex{ + Common: NewCommon(c, *c.ServiceContent.SearchIndex), + } + + return &s +} + +// FindByDatastorePath finds a virtual machine by its location on a datastore. +func (s SearchIndex) FindByDatastorePath(ctx context.Context, dc *Datacenter, path string) (Reference, error) { + req := types.FindByDatastorePath{ + This: s.Reference(), + Datacenter: dc.Reference(), + Path: path, + } + + res, err := methods.FindByDatastorePath(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil { + return nil, nil + } + return NewReference(s.c, *res.Returnval), nil +} + +// FindByDnsName finds a virtual machine or host by DNS name. +func (s SearchIndex) FindByDnsName(ctx context.Context, dc *Datacenter, dnsName string, vmSearch bool) (Reference, error) { + req := types.FindByDnsName{ + This: s.Reference(), + DnsName: dnsName, + VmSearch: vmSearch, + } + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + res, err := methods.FindByDnsName(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil { + return nil, nil + } + return NewReference(s.c, *res.Returnval), nil +} + +// FindByInventoryPath finds a managed entity based on its location in the inventory. +func (s SearchIndex) FindByInventoryPath(ctx context.Context, path string) (Reference, error) { + req := types.FindByInventoryPath{ + This: s.Reference(), + InventoryPath: path, + } + + res, err := methods.FindByInventoryPath(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil { + return nil, nil + } + return NewReference(s.c, *res.Returnval), nil +} + +// FindByIp finds a virtual machine or host by IP address. +func (s SearchIndex) FindByIp(ctx context.Context, dc *Datacenter, ip string, vmSearch bool) (Reference, error) { + req := types.FindByIp{ + This: s.Reference(), + Ip: ip, + VmSearch: vmSearch, + } + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + res, err := methods.FindByIp(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil { + return nil, nil + } + return NewReference(s.c, *res.Returnval), nil +} + +// FindByUuid finds a virtual machine or host by UUID. +func (s SearchIndex) FindByUuid(ctx context.Context, dc *Datacenter, uuid string, vmSearch bool, instanceUuid *bool) (Reference, error) { + req := types.FindByUuid{ + This: s.Reference(), + Uuid: uuid, + VmSearch: vmSearch, + InstanceUuid: instanceUuid, + } + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + res, err := methods.FindByUuid(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil { + return nil, nil + } + return NewReference(s.c, *res.Returnval), nil +} + +// FindChild finds a particular child based on a managed entity name. +func (s SearchIndex) FindChild(ctx context.Context, entity Reference, name string) (Reference, error) { + req := types.FindChild{ + This: s.Reference(), + Entity: entity.Reference(), + Name: name, + } + + res, err := methods.FindChild(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil { + return nil, nil + } + return NewReference(s.c, *res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/storage_pod.go b/vendor/github.com/vmware/govmomi/object/storage_pod.go new file mode 100644 index 0000000000..188b91a002 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/storage_pod.go @@ -0,0 +1,34 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/types" +) + +type StoragePod struct { + *Folder +} + +func NewStoragePod(c *vim25.Client, ref types.ManagedObjectReference) *StoragePod { + return &StoragePod{ + Folder: &Folder{ + Common: NewCommon(c, ref), + }, + } +} diff --git a/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go b/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go new file mode 100644 index 0000000000..54fd0d9e1c --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go @@ -0,0 +1,178 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type StorageResourceManager struct { + Common +} + +func NewStorageResourceManager(c *vim25.Client) *StorageResourceManager { + sr := StorageResourceManager{ + Common: NewCommon(c, *c.ServiceContent.StorageResourceManager), + } + + return &sr +} + +func (sr StorageResourceManager) ApplyStorageDrsRecommendation(ctx context.Context, key []string) (*Task, error) { + req := types.ApplyStorageDrsRecommendation_Task{ + This: sr.Reference(), + Key: key, + } + + res, err := methods.ApplyStorageDrsRecommendation_Task(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return NewTask(sr.c, res.Returnval), nil +} + +func (sr StorageResourceManager) ApplyStorageDrsRecommendationToPod(ctx context.Context, pod *StoragePod, key string) (*Task, error) { + req := types.ApplyStorageDrsRecommendationToPod_Task{ + This: sr.Reference(), + Key: key, + } + + if pod != nil { + req.Pod = pod.Reference() + } + + res, err := methods.ApplyStorageDrsRecommendationToPod_Task(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return NewTask(sr.c, res.Returnval), nil +} + +func (sr StorageResourceManager) CancelStorageDrsRecommendation(ctx context.Context, key []string) error { + req := types.CancelStorageDrsRecommendation{ + This: sr.Reference(), + Key: key, + } + + _, err := methods.CancelStorageDrsRecommendation(ctx, sr.c, &req) + + return err +} + +func (sr StorageResourceManager) ConfigureDatastoreIORM(ctx context.Context, datastore *Datastore, spec types.StorageIORMConfigSpec, key string) (*Task, error) { + req := types.ConfigureDatastoreIORM_Task{ + This: sr.Reference(), + Spec: spec, + } + + if datastore != nil { + req.Datastore = datastore.Reference() + } + + res, err := methods.ConfigureDatastoreIORM_Task(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return NewTask(sr.c, res.Returnval), nil +} + +func (sr StorageResourceManager) ConfigureStorageDrsForPod(ctx context.Context, pod *StoragePod, spec types.StorageDrsConfigSpec, modify bool) (*Task, error) { + req := types.ConfigureStorageDrsForPod_Task{ + This: sr.Reference(), + Spec: spec, + Modify: modify, + } + + if pod != nil { + req.Pod = pod.Reference() + } + + res, err := methods.ConfigureStorageDrsForPod_Task(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return NewTask(sr.c, res.Returnval), nil +} + +func (sr StorageResourceManager) QueryDatastorePerformanceSummary(ctx context.Context, datastore *Datastore) ([]types.StoragePerformanceSummary, error) { + req := types.QueryDatastorePerformanceSummary{ + This: sr.Reference(), + } + + if datastore != nil { + req.Datastore = datastore.Reference() + } + + res, err := methods.QueryDatastorePerformanceSummary(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (sr StorageResourceManager) QueryIORMConfigOption(ctx context.Context, host *HostSystem) (*types.StorageIORMConfigOption, error) { + req := types.QueryIORMConfigOption{ + This: sr.Reference(), + } + + if host != nil { + req.Host = host.Reference() + } + + res, err := methods.QueryIORMConfigOption(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (sr StorageResourceManager) RecommendDatastores(ctx context.Context, storageSpec types.StoragePlacementSpec) (*types.StoragePlacementResult, error) { + req := types.RecommendDatastores{ + This: sr.Reference(), + StorageSpec: storageSpec, + } + + res, err := methods.RecommendDatastores(ctx, sr.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (sr StorageResourceManager) RefreshStorageDrsRecommendation(ctx context.Context, pod *StoragePod) error { + req := types.RefreshStorageDrsRecommendation{ + This: sr.Reference(), + } + + if pod != nil { + req.Pod = pod.Reference() + } + + _, err := methods.RefreshStorageDrsRecommendation(ctx, sr.c, &req) + + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/task.go b/vendor/github.com/vmware/govmomi/object/task.go new file mode 100644 index 0000000000..d70a417be1 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/task.go @@ -0,0 +1,52 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/task" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/progress" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// Task is a convenience wrapper around task.Task that keeps a reference to +// the client that was used to create it. This allows users to call the Wait() +// function with only a context parameter, instead of a context parameter, a +// soap.RoundTripper, and reference to the root property collector. +type Task struct { + Common +} + +func NewTask(c *vim25.Client, ref types.ManagedObjectReference) *Task { + t := Task{ + Common: NewCommon(c, ref), + } + + return &t +} + +func (t *Task) Wait(ctx context.Context) error { + _, err := t.WaitForResult(ctx, nil) + return err +} + +func (t *Task) WaitForResult(ctx context.Context, s progress.Sinker) (*types.TaskInfo, error) { + p := property.DefaultCollector(t.c) + return task.Wait(ctx, t.Reference(), p, s) +} diff --git a/vendor/github.com/vmware/govmomi/object/types.go b/vendor/github.com/vmware/govmomi/object/types.go new file mode 100644 index 0000000000..f61aa362c4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/types.go @@ -0,0 +1,65 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/types" +) + +type Reference interface { + Reference() types.ManagedObjectReference +} + +func NewReference(c *vim25.Client, e types.ManagedObjectReference) Reference { + switch e.Type { + case "Folder": + return NewFolder(c, e) + case "StoragePod": + return &StoragePod{ + NewFolder(c, e), + } + case "Datacenter": + return NewDatacenter(c, e) + case "VirtualMachine": + return NewVirtualMachine(c, e) + case "VirtualApp": + return &VirtualApp{ + NewResourcePool(c, e), + } + case "ComputeResource": + return NewComputeResource(c, e) + case "ClusterComputeResource": + return NewClusterComputeResource(c, e) + case "HostSystem": + return NewHostSystem(c, e) + case "Network": + return NewNetwork(c, e) + case "ResourcePool": + return NewResourcePool(c, e) + case "DistributedVirtualSwitch": + return NewDistributedVirtualSwitch(c, e) + case "VmwareDistributedVirtualSwitch": + return &VmwareDistributedVirtualSwitch{*NewDistributedVirtualSwitch(c, e)} + case "DistributedVirtualPortgroup": + return NewDistributedVirtualPortgroup(c, e) + case "Datastore": + return NewDatastore(c, e) + default: + panic("Unknown managed entity: " + e.Type) + } +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_app.go b/vendor/github.com/vmware/govmomi/object/virtual_app.go new file mode 100644 index 0000000000..5b93f618f7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/virtual_app.go @@ -0,0 +1,126 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "fmt" + + "golang.org/x/net/context" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" +) + +type VirtualApp struct { + *ResourcePool +} + +func NewVirtualApp(c *vim25.Client, ref types.ManagedObjectReference) *VirtualApp { + return &VirtualApp{ + ResourcePool: NewResourcePool(c, ref), + } +} + +func (p VirtualApp) String() string { + if p.InventoryPath == "" { + return p.Common.String() + } + return fmt.Sprintf("%v @ %v", p.Common, p.InventoryPath) +} + +func (p VirtualApp) Name(ctx context.Context) (string, error) { + var o mo.VirtualApp + + err := p.Properties(ctx, p.Reference(), []string{"name"}, &o) + if err != nil { + return "", err + } + + return o.Name, nil +} + +func (p VirtualApp) CreateChildVM_Task(ctx context.Context, config types.VirtualMachineConfigSpec, host *HostSystem) (*Task, error) { + req := types.CreateChildVM_Task{ + This: p.Reference(), + Config: config, + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.CreateChildVM_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil +} + +func (p VirtualApp) UpdateVAppConfig(ctx context.Context, spec types.VAppConfigSpec) error { + req := types.UpdateVAppConfig{ + This: p.Reference(), + Spec: spec, + } + + _, err := methods.UpdateVAppConfig(ctx, p.c, &req) + return err +} + +func (p VirtualApp) PowerOnVApp_Task(ctx context.Context) (*Task, error) { + req := types.PowerOnVApp_Task{ + This: p.Reference(), + } + + res, err := methods.PowerOnVApp_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil +} + +func (p VirtualApp) PowerOffVApp_Task(ctx context.Context, force bool) (*Task, error) { + req := types.PowerOffVApp_Task{ + This: p.Reference(), + Force: force, + } + + res, err := methods.PowerOffVApp_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil + +} + +func (p VirtualApp) SuspendVApp_Task(ctx context.Context) (*Task, error) { + req := types.SuspendVApp_Task{ + This: p.Reference(), + } + + res, err := methods.SuspendVApp_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go new file mode 100644 index 0000000000..327b5d27ab --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go @@ -0,0 +1,827 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + "fmt" + "path/filepath" + "reflect" + "regexp" + "sort" + "strings" + + "github.com/vmware/govmomi/vim25/types" +) + +// Type values for use in BootOrder +const ( + DeviceTypeCdrom = "cdrom" + DeviceTypeDisk = "disk" + DeviceTypeEthernet = "ethernet" + DeviceTypeFloppy = "floppy" +) + +// VirtualDeviceList provides helper methods for working with a list of virtual devices. +type VirtualDeviceList []types.BaseVirtualDevice + +// SCSIControllerTypes are used for adding a new SCSI controller to a VM. +func SCSIControllerTypes() VirtualDeviceList { + // Return a mutable list of SCSI controller types, initialized with defaults. + return VirtualDeviceList([]types.BaseVirtualDevice{ + &types.VirtualLsiLogicController{}, + &types.VirtualBusLogicController{}, + &types.ParaVirtualSCSIController{}, + &types.VirtualLsiLogicSASController{}, + }).Select(func(device types.BaseVirtualDevice) bool { + c := device.(types.BaseVirtualSCSIController).GetVirtualSCSIController() + c.SharedBus = types.VirtualSCSISharingNoSharing + c.BusNumber = -1 + return true + }) +} + +// EthernetCardTypes are used for adding a new ethernet card to a VM. +func EthernetCardTypes() VirtualDeviceList { + return VirtualDeviceList([]types.BaseVirtualDevice{ + &types.VirtualE1000{}, + &types.VirtualE1000e{}, + &types.VirtualVmxnet3{}, + }).Select(func(device types.BaseVirtualDevice) bool { + c := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard() + c.GetVirtualDevice().Key = -1 + return true + }) +} + +// Select returns a new list containing all elements of the list for which the given func returns true. +func (l VirtualDeviceList) Select(f func(device types.BaseVirtualDevice) bool) VirtualDeviceList { + var found VirtualDeviceList + + for _, device := range l { + if f(device) { + found = append(found, device) + } + } + + return found +} + +// SelectByType returns a new list with devices that are equal to or extend the given type. +func (l VirtualDeviceList) SelectByType(deviceType types.BaseVirtualDevice) VirtualDeviceList { + dtype := reflect.TypeOf(deviceType) + dname := dtype.Elem().Name() + + return l.Select(func(device types.BaseVirtualDevice) bool { + t := reflect.TypeOf(device) + + if t == dtype { + return true + } + + _, ok := t.Elem().FieldByName(dname) + + return ok + }) +} + +// SelectByBackingInfo returns a new list with devices matching the given backing info. +// If the value of backing is nil, any device with a backing of the same type will be returned. +func (l VirtualDeviceList) SelectByBackingInfo(backing types.BaseVirtualDeviceBackingInfo) VirtualDeviceList { + t := reflect.TypeOf(backing) + + return l.Select(func(device types.BaseVirtualDevice) bool { + db := device.GetVirtualDevice().Backing + if db == nil { + return false + } + + if reflect.TypeOf(db) != t { + return false + } + + if reflect.ValueOf(backing).IsNil() { + // selecting by backing type + return true + } + + switch a := db.(type) { + case *types.VirtualEthernetCardNetworkBackingInfo: + b := backing.(*types.VirtualEthernetCardNetworkBackingInfo) + return a.DeviceName == b.DeviceName + case *types.VirtualEthernetCardDistributedVirtualPortBackingInfo: + b := backing.(*types.VirtualEthernetCardDistributedVirtualPortBackingInfo) + return a.Port.SwitchUuid == b.Port.SwitchUuid && + a.Port.PortgroupKey == b.Port.PortgroupKey + case *types.VirtualDiskFlatVer2BackingInfo: + b := backing.(*types.VirtualDiskFlatVer2BackingInfo) + if a.Parent != nil && b.Parent != nil { + return a.Parent.FileName == b.Parent.FileName + } + return a.FileName == b.FileName + case *types.VirtualSerialPortURIBackingInfo: + b := backing.(*types.VirtualSerialPortURIBackingInfo) + return a.ServiceURI == b.ServiceURI + case types.BaseVirtualDeviceFileBackingInfo: + b := backing.(types.BaseVirtualDeviceFileBackingInfo) + return a.GetVirtualDeviceFileBackingInfo().FileName == b.GetVirtualDeviceFileBackingInfo().FileName + default: + return false + } + }) +} + +// Find returns the device matching the given name. +func (l VirtualDeviceList) Find(name string) types.BaseVirtualDevice { + for _, device := range l { + if l.Name(device) == name { + return device + } + } + return nil +} + +// FindByKey returns the device matching the given key. +func (l VirtualDeviceList) FindByKey(key int32) types.BaseVirtualDevice { + for _, device := range l { + if device.GetVirtualDevice().Key == key { + return device + } + } + return nil +} + +// FindIDEController will find the named IDE controller if given, otherwise will pick an available controller. +// An error is returned if the named controller is not found or not an IDE controller. Or, if name is not +// given and no available controller can be found. +func (l VirtualDeviceList) FindIDEController(name string) (*types.VirtualIDEController, error) { + if name != "" { + d := l.Find(name) + if d == nil { + return nil, fmt.Errorf("device '%s' not found", name) + } + if c, ok := d.(*types.VirtualIDEController); ok { + return c, nil + } + return nil, fmt.Errorf("%s is not an IDE controller", name) + } + + c := l.PickController((*types.VirtualIDEController)(nil)) + if c == nil { + return nil, errors.New("no available IDE controller") + } + + return c.(*types.VirtualIDEController), nil +} + +// CreateIDEController creates a new IDE controller. +func (l VirtualDeviceList) CreateIDEController() (types.BaseVirtualDevice, error) { + ide := &types.VirtualIDEController{} + ide.Key = l.NewKey() + return ide, nil +} + +// FindSCSIController will find the named SCSI controller if given, otherwise will pick an available controller. +// An error is returned if the named controller is not found or not an SCSI controller. Or, if name is not +// given and no available controller can be found. +func (l VirtualDeviceList) FindSCSIController(name string) (*types.VirtualSCSIController, error) { + if name != "" { + d := l.Find(name) + if d == nil { + return nil, fmt.Errorf("device '%s' not found", name) + } + if c, ok := d.(types.BaseVirtualSCSIController); ok { + return c.GetVirtualSCSIController(), nil + } + return nil, fmt.Errorf("%s is not an SCSI controller", name) + } + + c := l.PickController((*types.VirtualSCSIController)(nil)) + if c == nil { + return nil, errors.New("no available SCSI controller") + } + + return c.(types.BaseVirtualSCSIController).GetVirtualSCSIController(), nil +} + +// CreateSCSIController creates a new SCSI controller of type name if given, otherwise defaults to lsilogic. +func (l VirtualDeviceList) CreateSCSIController(name string) (types.BaseVirtualDevice, error) { + ctypes := SCSIControllerTypes() + + if name == "scsi" || name == "" { + name = ctypes.Type(ctypes[0]) + } + + found := ctypes.Select(func(device types.BaseVirtualDevice) bool { + return l.Type(device) == name + }) + + if len(found) == 0 { + return nil, fmt.Errorf("unknown SCSI controller type '%s'", name) + } + + c, ok := found[0].(types.BaseVirtualSCSIController) + if !ok { + return nil, fmt.Errorf("invalid SCSI controller type '%s'", name) + } + + scsi := c.GetVirtualSCSIController() + scsi.BusNumber = l.newSCSIBusNumber() + scsi.Key = l.NewKey() + return c.(types.BaseVirtualDevice), nil +} + +var scsiBusNumbers = []int{0, 1, 2, 3} + +// newSCSIBusNumber returns the bus number to use for adding a new SCSI bus device. +// -1 is returned if there are no bus numbers available. +func (l VirtualDeviceList) newSCSIBusNumber() int32 { + var used []int + + for _, d := range l.SelectByType((*types.VirtualSCSIController)(nil)) { + num := d.(types.BaseVirtualSCSIController).GetVirtualSCSIController().BusNumber + if num >= 0 { + used = append(used, int(num)) + } // else caller is creating a new vm using SCSIControllerTypes + } + + sort.Ints(used) + + for i, n := range scsiBusNumbers { + if i == len(used) || n != used[i] { + return int32(n) + } + } + + return -1 +} + +// FindDiskController will find an existing ide or scsi disk controller. +func (l VirtualDeviceList) FindDiskController(name string) (types.BaseVirtualController, error) { + switch { + case name == "ide": + return l.FindIDEController("") + case name == "scsi" || name == "": + return l.FindSCSIController("") + default: + if c, ok := l.Find(name).(types.BaseVirtualController); ok { + return c, nil + } + return nil, fmt.Errorf("%s is not a valid controller", name) + } +} + +// PickController returns a controller of the given type(s). +// If no controllers are found or have no available slots, then nil is returned. +func (l VirtualDeviceList) PickController(kind types.BaseVirtualController) types.BaseVirtualController { + l = l.SelectByType(kind.(types.BaseVirtualDevice)).Select(func(device types.BaseVirtualDevice) bool { + num := len(device.(types.BaseVirtualController).GetVirtualController().Device) + + switch device.(type) { + case types.BaseVirtualSCSIController: + return num < 15 + case *types.VirtualIDEController: + return num < 2 + default: + return true + } + }) + + if len(l) == 0 { + return nil + } + + return l[0].(types.BaseVirtualController) +} + +// newUnitNumber returns the unit number to use for attaching a new device to the given controller. +func (l VirtualDeviceList) newUnitNumber(c types.BaseVirtualController) int32 { + key := c.GetVirtualController().Key + var max int32 = -1 + + for _, device := range l { + d := device.GetVirtualDevice() + + if d.ControllerKey == key { + if d.UnitNumber != nil && *d.UnitNumber > max { + max = *d.UnitNumber + } + } + } + + return max + 1 +} + +// NewKey returns the key to use for adding a new device to the device list. +// The device list we're working with here may not be complete (e.g. when +// we're only adding new devices), so any positive keys could conflict with device keys +// that are already in use. To avoid this type of conflict, we can use negative keys +// here, which will be resolved to positive keys by vSphere as the reconfiguration is done. +func (l VirtualDeviceList) NewKey() int32 { + var key int32 = -200 + + for _, device := range l { + d := device.GetVirtualDevice() + if d.Key < key { + key = d.Key + } + } + + return key - 1 +} + +// AssignController assigns a device to a controller. +func (l VirtualDeviceList) AssignController(device types.BaseVirtualDevice, c types.BaseVirtualController) { + d := device.GetVirtualDevice() + d.ControllerKey = c.GetVirtualController().Key + d.UnitNumber = new(int32) + *d.UnitNumber = l.newUnitNumber(c) + if d.Key == 0 { + d.Key = -1 + } +} + +// CreateDisk creates a new VirtualDisk device which can be added to a VM. +func (l VirtualDeviceList) CreateDisk(c types.BaseVirtualController, ds types.ManagedObjectReference, name string) *types.VirtualDisk { + // If name is not specified, one will be chosen for you. + // But if when given, make sure it ends in .vmdk, otherwise it will be treated as a directory. + if len(name) > 0 && filepath.Ext(name) != ".vmdk" { + name += ".vmdk" + } + + device := &types.VirtualDisk{ + VirtualDevice: types.VirtualDevice{ + Backing: &types.VirtualDiskFlatVer2BackingInfo{ + DiskMode: string(types.VirtualDiskModePersistent), + ThinProvisioned: types.NewBool(true), + VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ + FileName: name, + Datastore: &ds, + }, + }, + }, + } + + l.AssignController(device, c) + return device +} + +// ChildDisk creates a new VirtualDisk device, linked to the given parent disk, which can be added to a VM. +func (l VirtualDeviceList) ChildDisk(parent *types.VirtualDisk) *types.VirtualDisk { + disk := *parent + backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo) + ds := strings.SplitN(backing.FileName[1:], "]", 2) + + // Use specified disk as parent backing to a new disk. + disk.Backing = &types.VirtualDiskFlatVer2BackingInfo{ + VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ + FileName: fmt.Sprintf("[%s]", ds[0]), + Datastore: backing.Datastore, + }, + Parent: backing, + DiskMode: backing.DiskMode, + ThinProvisioned: backing.ThinProvisioned, + } + + return &disk +} + +func (l VirtualDeviceList) connectivity(device types.BaseVirtualDevice, v bool) error { + c := device.GetVirtualDevice().Connectable + if c == nil { + return fmt.Errorf("%s is not connectable", l.Name(device)) + } + + c.Connected = v + c.StartConnected = v + + return nil +} + +// Connect changes the device to connected, returns an error if the device is not connectable. +func (l VirtualDeviceList) Connect(device types.BaseVirtualDevice) error { + return l.connectivity(device, true) +} + +// Disconnect changes the device to disconnected, returns an error if the device is not connectable. +func (l VirtualDeviceList) Disconnect(device types.BaseVirtualDevice) error { + return l.connectivity(device, false) +} + +// FindCdrom finds a cdrom device with the given name, defaulting to the first cdrom device if any. +func (l VirtualDeviceList) FindCdrom(name string) (*types.VirtualCdrom, error) { + if name != "" { + d := l.Find(name) + if d == nil { + return nil, fmt.Errorf("device '%s' not found", name) + } + if c, ok := d.(*types.VirtualCdrom); ok { + return c, nil + } + return nil, fmt.Errorf("%s is not a cdrom device", name) + } + + c := l.SelectByType((*types.VirtualCdrom)(nil)) + if len(c) == 0 { + return nil, errors.New("no cdrom device found") + } + + return c[0].(*types.VirtualCdrom), nil +} + +// CreateCdrom creates a new VirtualCdrom device which can be added to a VM. +func (l VirtualDeviceList) CreateCdrom(c *types.VirtualIDEController) (*types.VirtualCdrom, error) { + device := &types.VirtualCdrom{} + + l.AssignController(device, c) + + l.setDefaultCdromBacking(device) + + device.Connectable = &types.VirtualDeviceConnectInfo{ + AllowGuestControl: true, + Connected: true, + StartConnected: true, + } + + return device, nil +} + +// InsertIso changes the cdrom device backing to use the given iso file. +func (l VirtualDeviceList) InsertIso(device *types.VirtualCdrom, iso string) *types.VirtualCdrom { + device.Backing = &types.VirtualCdromIsoBackingInfo{ + VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ + FileName: iso, + }, + } + + return device +} + +// EjectIso removes the iso file based backing and replaces with the default cdrom backing. +func (l VirtualDeviceList) EjectIso(device *types.VirtualCdrom) *types.VirtualCdrom { + l.setDefaultCdromBacking(device) + return device +} + +func (l VirtualDeviceList) setDefaultCdromBacking(device *types.VirtualCdrom) { + device.Backing = &types.VirtualCdromAtapiBackingInfo{ + VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{ + DeviceName: fmt.Sprintf("%s-%d-%d", DeviceTypeCdrom, device.ControllerKey, device.UnitNumber), + UseAutoDetect: types.NewBool(false), + }, + } +} + +// FindFloppy finds a floppy device with the given name, defaulting to the first floppy device if any. +func (l VirtualDeviceList) FindFloppy(name string) (*types.VirtualFloppy, error) { + if name != "" { + d := l.Find(name) + if d == nil { + return nil, fmt.Errorf("device '%s' not found", name) + } + if c, ok := d.(*types.VirtualFloppy); ok { + return c, nil + } + return nil, fmt.Errorf("%s is not a floppy device", name) + } + + c := l.SelectByType((*types.VirtualFloppy)(nil)) + if len(c) == 0 { + return nil, errors.New("no floppy device found") + } + + return c[0].(*types.VirtualFloppy), nil +} + +// CreateFloppy creates a new VirtualFloppy device which can be added to a VM. +func (l VirtualDeviceList) CreateFloppy() (*types.VirtualFloppy, error) { + device := &types.VirtualFloppy{} + + c := l.PickController((*types.VirtualSIOController)(nil)) + if c == nil { + return nil, errors.New("no available SIO controller") + } + + l.AssignController(device, c) + + l.setDefaultFloppyBacking(device) + + device.Connectable = &types.VirtualDeviceConnectInfo{ + AllowGuestControl: true, + Connected: true, + StartConnected: true, + } + + return device, nil +} + +// InsertImg changes the floppy device backing to use the given img file. +func (l VirtualDeviceList) InsertImg(device *types.VirtualFloppy, img string) *types.VirtualFloppy { + device.Backing = &types.VirtualFloppyImageBackingInfo{ + VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ + FileName: img, + }, + } + + return device +} + +// EjectImg removes the img file based backing and replaces with the default floppy backing. +func (l VirtualDeviceList) EjectImg(device *types.VirtualFloppy) *types.VirtualFloppy { + l.setDefaultFloppyBacking(device) + return device +} + +func (l VirtualDeviceList) setDefaultFloppyBacking(device *types.VirtualFloppy) { + device.Backing = &types.VirtualFloppyDeviceBackingInfo{ + VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{ + DeviceName: fmt.Sprintf("%s-%d", DeviceTypeFloppy, device.UnitNumber), + UseAutoDetect: types.NewBool(false), + }, + } +} + +// FindSerialPort finds a serial port device with the given name, defaulting to the first serial port device if any. +func (l VirtualDeviceList) FindSerialPort(name string) (*types.VirtualSerialPort, error) { + if name != "" { + d := l.Find(name) + if d == nil { + return nil, fmt.Errorf("device '%s' not found", name) + } + if c, ok := d.(*types.VirtualSerialPort); ok { + return c, nil + } + return nil, fmt.Errorf("%s is not a serial port device", name) + } + + c := l.SelectByType((*types.VirtualSerialPort)(nil)) + if len(c) == 0 { + return nil, errors.New("no serial port device found") + } + + return c[0].(*types.VirtualSerialPort), nil +} + +// CreateSerialPort creates a new VirtualSerialPort device which can be added to a VM. +func (l VirtualDeviceList) CreateSerialPort() (*types.VirtualSerialPort, error) { + device := &types.VirtualSerialPort{ + YieldOnPoll: true, + } + + c := l.PickController((*types.VirtualSIOController)(nil)) + if c == nil { + return nil, errors.New("no available SIO controller") + } + + l.AssignController(device, c) + + l.setDefaultSerialPortBacking(device) + + return device, nil +} + +// ConnectSerialPort connects a serial port to a server or client uri. +func (l VirtualDeviceList) ConnectSerialPort(device *types.VirtualSerialPort, uri string, client bool) *types.VirtualSerialPort { + direction := types.VirtualDeviceURIBackingOptionDirectionServer + if client { + direction = types.VirtualDeviceURIBackingOptionDirectionClient + } + + device.Backing = &types.VirtualSerialPortURIBackingInfo{ + VirtualDeviceURIBackingInfo: types.VirtualDeviceURIBackingInfo{ + Direction: string(direction), + ServiceURI: uri, + }, + } + + return device +} + +// DisconnectSerialPort disconnects the serial port backing. +func (l VirtualDeviceList) DisconnectSerialPort(device *types.VirtualSerialPort) *types.VirtualSerialPort { + l.setDefaultSerialPortBacking(device) + return device +} + +func (l VirtualDeviceList) setDefaultSerialPortBacking(device *types.VirtualSerialPort) { + device.Backing = &types.VirtualSerialPortURIBackingInfo{ + VirtualDeviceURIBackingInfo: types.VirtualDeviceURIBackingInfo{ + Direction: "client", + ServiceURI: "localhost:0", + }, + } +} + +// CreateEthernetCard creates a new VirtualEthernetCard of the given name name and initialized with the given backing. +func (l VirtualDeviceList) CreateEthernetCard(name string, backing types.BaseVirtualDeviceBackingInfo) (types.BaseVirtualDevice, error) { + ctypes := EthernetCardTypes() + + if name == "" { + name = ctypes.deviceName(ctypes[0]) + } + + found := ctypes.Select(func(device types.BaseVirtualDevice) bool { + return l.deviceName(device) == name + }) + + if len(found) == 0 { + return nil, fmt.Errorf("unknown ethernet card type '%s'", name) + } + + c, ok := found[0].(types.BaseVirtualEthernetCard) + if !ok { + return nil, fmt.Errorf("invalid ethernet card type '%s'", name) + } + + c.GetVirtualEthernetCard().Backing = backing + + return c.(types.BaseVirtualDevice), nil +} + +// PrimaryMacAddress returns the MacAddress field of the primary VirtualEthernetCard +func (l VirtualDeviceList) PrimaryMacAddress() string { + eth0 := l.Find("ethernet-0") + + if eth0 == nil { + return "" + } + + return eth0.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard().MacAddress +} + +// convert a BaseVirtualDevice to a BaseVirtualMachineBootOptionsBootableDevice +var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice{ + DeviceTypeCdrom: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice { + return &types.VirtualMachineBootOptionsBootableCdromDevice{} + }, + DeviceTypeDisk: func(d types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice { + return &types.VirtualMachineBootOptionsBootableDiskDevice{ + DeviceKey: d.GetVirtualDevice().Key, + } + }, + DeviceTypeEthernet: func(d types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice { + return &types.VirtualMachineBootOptionsBootableEthernetDevice{ + DeviceKey: d.GetVirtualDevice().Key, + } + }, + DeviceTypeFloppy: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice { + return &types.VirtualMachineBootOptionsBootableFloppyDevice{} + }, +} + +// BootOrder returns a list of devices which can be used to set boot order via VirtualMachine.SetBootOptions. +// The order can any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name. +func (l VirtualDeviceList) BootOrder(order []string) []types.BaseVirtualMachineBootOptionsBootableDevice { + var devices []types.BaseVirtualMachineBootOptionsBootableDevice + + for _, name := range order { + if kind, ok := bootableDevices[name]; ok { + for _, device := range l { + if l.Type(device) == name { + devices = append(devices, kind(device)) + } + + } + continue + } + + if d := l.Find(name); d != nil { + if kind, ok := bootableDevices[l.Type(d)]; ok { + devices = append(devices, kind(d)) + } + } + } + + return devices +} + +// SelectBootOrder returns an ordered list of devices matching the given bootable device order +func (l VirtualDeviceList) SelectBootOrder(order []types.BaseVirtualMachineBootOptionsBootableDevice) VirtualDeviceList { + var devices VirtualDeviceList + + for _, bd := range order { + for _, device := range l { + if kind, ok := bootableDevices[l.Type(device)]; ok { + if reflect.DeepEqual(kind(device), bd) { + devices = append(devices, device) + } + } + } + } + + return devices +} + +// TypeName returns the vmodl type name of the device +func (l VirtualDeviceList) TypeName(device types.BaseVirtualDevice) string { + return reflect.TypeOf(device).Elem().Name() +} + +var deviceNameRegexp = regexp.MustCompile(`(?:Virtual)?(?:Machine)?(\w+?)(?:Card|Device|Controller)?$`) + +func (l VirtualDeviceList) deviceName(device types.BaseVirtualDevice) string { + name := "device" + typeName := l.TypeName(device) + + m := deviceNameRegexp.FindStringSubmatch(typeName) + if len(m) == 2 { + name = strings.ToLower(m[1]) + } + + return name +} + +// Type returns a human-readable name for the given device +func (l VirtualDeviceList) Type(device types.BaseVirtualDevice) string { + switch device.(type) { + case types.BaseVirtualEthernetCard: + return DeviceTypeEthernet + case *types.ParaVirtualSCSIController: + return "pvscsi" + case *types.VirtualLsiLogicSASController: + return "lsilogic-sas" + default: + return l.deviceName(device) + } +} + +// Name returns a stable, human-readable name for the given device +func (l VirtualDeviceList) Name(device types.BaseVirtualDevice) string { + var key string + var UnitNumber int32 + d := device.GetVirtualDevice() + if d.UnitNumber != nil { + UnitNumber = *d.UnitNumber + } + + dtype := l.Type(device) + switch dtype { + case DeviceTypeEthernet: + key = fmt.Sprintf("%d", UnitNumber-7) + case DeviceTypeDisk: + key = fmt.Sprintf("%d-%d", d.ControllerKey, UnitNumber) + default: + key = fmt.Sprintf("%d", d.Key) + } + + return fmt.Sprintf("%s-%s", dtype, key) +} + +// ConfigSpec creates a virtual machine configuration spec for +// the specified operation, for the list of devices in the device list. +func (l VirtualDeviceList) ConfigSpec(op types.VirtualDeviceConfigSpecOperation) ([]types.BaseVirtualDeviceConfigSpec, error) { + var fop types.VirtualDeviceConfigSpecFileOperation + switch op { + case types.VirtualDeviceConfigSpecOperationAdd: + fop = types.VirtualDeviceConfigSpecFileOperationCreate + case types.VirtualDeviceConfigSpecOperationEdit: + fop = types.VirtualDeviceConfigSpecFileOperationReplace + case types.VirtualDeviceConfigSpecOperationRemove: + fop = types.VirtualDeviceConfigSpecFileOperationDestroy + default: + panic("unknown op") + } + + var res []types.BaseVirtualDeviceConfigSpec + for _, device := range l { + config := &types.VirtualDeviceConfigSpec{ + Device: device, + Operation: op, + } + + if disk, ok := device.(*types.VirtualDisk); ok { + config.FileOperation = fop + + // Special case to attach an existing disk + if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 { + childDisk := false + if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { + childDisk = b.Parent != nil + } + + if !childDisk { + // Existing disk, clear file operation + config.FileOperation = "" + } + } + } + + res = append(res, config) + } + + return res, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go new file mode 100644 index 0000000000..800cfa0766 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go @@ -0,0 +1,145 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type VirtualDiskManager struct { + Common +} + +func NewVirtualDiskManager(c *vim25.Client) *VirtualDiskManager { + m := VirtualDiskManager{ + Common: NewCommon(c, *c.ServiceContent.VirtualDiskManager), + } + + return &m +} + +// CopyVirtualDisk copies a virtual disk, performing conversions as specified in the spec. +func (m VirtualDiskManager) CopyVirtualDisk( + ctx context.Context, + sourceName string, sourceDatacenter *Datacenter, + destName string, destDatacenter *Datacenter, + destSpec *types.VirtualDiskSpec, force bool) (*Task, error) { + + req := types.CopyVirtualDisk_Task{ + This: m.Reference(), + SourceName: sourceName, + DestName: destName, + DestSpec: destSpec, + Force: types.NewBool(force), + } + + if sourceDatacenter != nil { + ref := sourceDatacenter.Reference() + req.SourceDatacenter = &ref + } + + if destDatacenter != nil { + ref := destDatacenter.Reference() + req.DestDatacenter = &ref + } + + res, err := methods.CopyVirtualDisk_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} + +// CreateVirtualDisk creates a new virtual disk. +func (m VirtualDiskManager) CreateVirtualDisk( + ctx context.Context, + name string, datacenter *Datacenter, + spec types.BaseVirtualDiskSpec) (*Task, error) { + + req := types.CreateVirtualDisk_Task{ + This: m.Reference(), + Name: name, + Spec: spec, + } + + if datacenter != nil { + ref := datacenter.Reference() + req.Datacenter = &ref + } + + res, err := methods.CreateVirtualDisk_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} + +// MoveVirtualDisk moves a virtual disk. +func (m VirtualDiskManager) MoveVirtualDisk( + ctx context.Context, + sourceName string, sourceDatacenter *Datacenter, + destName string, destDatacenter *Datacenter, + force bool) (*Task, error) { + req := types.MoveVirtualDisk_Task{ + This: m.Reference(), + SourceName: sourceName, + DestName: destName, + Force: types.NewBool(force), + } + + if sourceDatacenter != nil { + ref := sourceDatacenter.Reference() + req.SourceDatacenter = &ref + } + + if destDatacenter != nil { + ref := destDatacenter.Reference() + req.DestDatacenter = &ref + } + + res, err := methods.MoveVirtualDisk_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} + +// DeleteVirtualDisk deletes a virtual disk. +func (m VirtualDiskManager) DeleteVirtualDisk(ctx context.Context, name string, dc *Datacenter) (*Task, error) { + req := types.DeleteVirtualDisk_Task{ + This: m.Reference(), + Name: name, + } + + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + res, err := methods.DeleteVirtualDisk_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_machine.go b/vendor/github.com/vmware/govmomi/object/virtual_machine.go new file mode 100644 index 0000000000..4faeae75e3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/virtual_machine.go @@ -0,0 +1,614 @@ +/* +Copyright (c) 2015 VMware, 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 object + +import ( + "errors" + "fmt" + "net" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +const ( + PropRuntimePowerState = "summary.runtime.powerState" +) + +type VirtualMachine struct { + Common + + InventoryPath string +} + +func (v VirtualMachine) String() string { + if v.InventoryPath == "" { + return v.Common.String() + } + return fmt.Sprintf("%v @ %v", v.Common, v.InventoryPath) +} + +func NewVirtualMachine(c *vim25.Client, ref types.ManagedObjectReference) *VirtualMachine { + return &VirtualMachine{ + Common: NewCommon(c, ref), + } +} + +func (v VirtualMachine) Name(ctx context.Context) (string, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"name"}, &o) + if err != nil { + return "", err + } + + return o.Name, nil +} + +func (v VirtualMachine) PowerState(ctx context.Context) (types.VirtualMachinePowerState, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{PropRuntimePowerState}, &o) + if err != nil { + return "", err + } + + return o.Summary.Runtime.PowerState, nil +} + +func (v VirtualMachine) PowerOn(ctx context.Context) (*Task, error) { + req := types.PowerOnVM_Task{ + This: v.Reference(), + } + + res, err := methods.PowerOnVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) PowerOff(ctx context.Context) (*Task, error) { + req := types.PowerOffVM_Task{ + This: v.Reference(), + } + + res, err := methods.PowerOffVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) Reset(ctx context.Context) (*Task, error) { + req := types.ResetVM_Task{ + This: v.Reference(), + } + + res, err := methods.ResetVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) Suspend(ctx context.Context) (*Task, error) { + req := types.SuspendVM_Task{ + This: v.Reference(), + } + + res, err := methods.SuspendVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) ShutdownGuest(ctx context.Context) error { + req := types.ShutdownGuest{ + This: v.Reference(), + } + + _, err := methods.ShutdownGuest(ctx, v.c, &req) + return err +} + +func (v VirtualMachine) RebootGuest(ctx context.Context) error { + req := types.RebootGuest{ + This: v.Reference(), + } + + _, err := methods.RebootGuest(ctx, v.c, &req) + return err +} + +func (v VirtualMachine) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: v.Reference(), + } + + res, err := methods.Destroy_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) Clone(ctx context.Context, folder *Folder, name string, config types.VirtualMachineCloneSpec) (*Task, error) { + req := types.CloneVM_Task{ + This: v.Reference(), + Folder: folder.Reference(), + Name: name, + Spec: config, + } + + res, err := methods.CloneVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) Customize(ctx context.Context, spec types.CustomizationSpec) (*Task, error) { + req := types.CustomizeVM_Task{ + This: v.Reference(), + Spec: spec, + } + + res, err := methods.CustomizeVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) Relocate(ctx context.Context, config types.VirtualMachineRelocateSpec, priority types.VirtualMachineMovePriority) (*Task, error) { + req := types.RelocateVM_Task{ + This: v.Reference(), + Spec: config, + Priority: priority, + } + + res, err := methods.RelocateVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) Reconfigure(ctx context.Context, config types.VirtualMachineConfigSpec) (*Task, error) { + req := types.ReconfigVM_Task{ + This: v.Reference(), + Spec: config, + } + + res, err := methods.ReconfigVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) { + var ip string + + p := property.DefaultCollector(v.c) + err := property.Wait(ctx, p, v.Reference(), []string{"guest.ipAddress"}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Name != "guest.ipAddress" { + continue + } + if c.Op != types.PropertyChangeOpAssign { + continue + } + if c.Val == nil { + continue + } + + ip = c.Val.(string) + return true + } + + return false + }) + + if err != nil { + return "", err + } + + return ip, nil +} + +// WaitForNetIP waits for the VM guest.net property to report an IP address for all VM NICs. +// Only consider IPv4 addresses if the v4 param is true. +// Returns a map with MAC address as the key and IP address list as the value. +func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][]string, error) { + macs := make(map[string][]string) + + p := property.DefaultCollector(v.c) + + // Wait for all NICs to have a MacAddress, which may not be generated yet. + err := property.Wait(ctx, p, v.Reference(), []string{"config.hardware.device"}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Op != types.PropertyChangeOpAssign { + continue + } + + devices := c.Val.(types.ArrayOfVirtualDevice).VirtualDevice + for _, device := range devices { + if nic, ok := device.(types.BaseVirtualEthernetCard); ok { + mac := nic.GetVirtualEthernetCard().MacAddress + if mac == "" { + return false + } + macs[mac] = nil + } + } + } + + return true + }) + + err = property.Wait(ctx, p, v.Reference(), []string{"guest.net"}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Op != types.PropertyChangeOpAssign { + continue + } + + nics := c.Val.(types.ArrayOfGuestNicInfo).GuestNicInfo + for _, nic := range nics { + mac := nic.MacAddress + if mac == "" || nic.IpConfig == nil { + continue + } + + for _, ip := range nic.IpConfig.IpAddress { + if _, ok := macs[mac]; !ok { + continue // Ignore any that don't correspond to a VM device + } + if v4 && net.ParseIP(ip.IpAddress).To4() == nil { + continue // Ignore non IPv4 address + } + macs[mac] = append(macs[mac], ip.IpAddress) + } + } + } + + for _, ips := range macs { + if len(ips) == 0 { + return false + } + } + + return true + }) + + if err != nil { + return nil, err + } + + return macs, nil +} + +// Device returns the VirtualMachine's config.hardware.device property. +func (v VirtualMachine) Device(ctx context.Context) (VirtualDeviceList, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"config.hardware.device"}, &o) + if err != nil { + return nil, err + } + + return VirtualDeviceList(o.Config.Hardware.Device), nil +} + +func (v VirtualMachine) HostSystem(ctx context.Context) (*HostSystem, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"summary"}, &o) + if err != nil { + return nil, err + } + + host := o.Summary.Runtime.Host + if host == nil { + return nil, errors.New("VM doesn't have a HostSystem") + } + + return NewHostSystem(v.c, *host), nil +} + +func (v VirtualMachine) ResourcePool(ctx context.Context) (*ResourcePool, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"resourcePool"}, &o) + if err != nil { + return nil, err + } + + rp := o.ResourcePool + if rp == nil { + return nil, errors.New("VM doesn't have a resourcePool") + } + + return NewResourcePool(v.c, *rp), nil +} + +func (v VirtualMachine) configureDevice(ctx context.Context, op types.VirtualDeviceConfigSpecOperation, fop types.VirtualDeviceConfigSpecFileOperation, devices ...types.BaseVirtualDevice) error { + spec := types.VirtualMachineConfigSpec{} + + for _, device := range devices { + config := &types.VirtualDeviceConfigSpec{ + Device: device, + Operation: op, + } + + if disk, ok := device.(*types.VirtualDisk); ok { + config.FileOperation = fop + + // Special case to attach an existing disk + if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 { + childDisk := false + if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { + childDisk = b.Parent != nil + } + + if !childDisk { + config.FileOperation = "" // existing disk + } + } + } + + spec.DeviceChange = append(spec.DeviceChange, config) + } + + task, err := v.Reconfigure(ctx, spec) + if err != nil { + return err + } + + return task.Wait(ctx) +} + +// AddDevice adds the given devices to the VirtualMachine +func (v VirtualMachine) AddDevice(ctx context.Context, device ...types.BaseVirtualDevice) error { + return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationAdd, types.VirtualDeviceConfigSpecFileOperationCreate, device...) +} + +// EditDevice edits the given (existing) devices on the VirtualMachine +func (v VirtualMachine) EditDevice(ctx context.Context, device ...types.BaseVirtualDevice) error { + return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationEdit, types.VirtualDeviceConfigSpecFileOperationReplace, device...) +} + +// RemoveDevice removes the given devices on the VirtualMachine +func (v VirtualMachine) RemoveDevice(ctx context.Context, keepFiles bool, device ...types.BaseVirtualDevice) error { + fop := types.VirtualDeviceConfigSpecFileOperationDestroy + if keepFiles { + fop = "" + } + return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationRemove, fop, device...) +} + +// BootOptions returns the VirtualMachine's config.bootOptions property. +func (v VirtualMachine) BootOptions(ctx context.Context) (*types.VirtualMachineBootOptions, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"config.bootOptions"}, &o) + if err != nil { + return nil, err + } + + return o.Config.BootOptions, nil +} + +// SetBootOptions reconfigures the VirtualMachine with the given options. +func (v VirtualMachine) SetBootOptions(ctx context.Context, options *types.VirtualMachineBootOptions) error { + spec := types.VirtualMachineConfigSpec{} + + spec.BootOptions = options + + task, err := v.Reconfigure(ctx, spec) + if err != nil { + return err + } + + return task.Wait(ctx) +} + +// Answer answers a pending question. +func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error { + req := types.AnswerVM{ + This: v.Reference(), + QuestionId: id, + AnswerChoice: answer, + } + + _, err := methods.AnswerVM(ctx, v.c, &req) + if err != nil { + return err + } + + return nil +} + +// CreateSnapshot creates a new snapshot of a virtual machine. +func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, description string, memory bool, quiesce bool) (*Task, error) { + req := types.CreateSnapshot_Task{ + This: v.Reference(), + Name: name, + Description: description, + Memory: memory, + Quiesce: quiesce, + } + + res, err := methods.CreateSnapshot_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +// RemoveAllSnapshot removes all snapshots of a virtual machine +func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool) (*Task, error) { + req := types.RemoveAllSnapshots_Task{ + This: v.Reference(), + Consolidate: consolidate, + } + + res, err := methods.RemoveAllSnapshots_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +// RevertToSnapshot reverts to a named snapshot +func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o) + + snapshotTree := o.Snapshot.RootSnapshotList + if len(snapshotTree) < 1 { + return nil, errors.New("No snapshots for this VM") + } + + snapshot, err := traverseSnapshotInTree(snapshotTree, name) + if err != nil { + return nil, err + } + + req := types.RevertToSnapshot_Task{ + This: snapshot, + SuppressPowerOn: types.NewBool(suppressPowerOn), + } + + res, err := methods.RevertToSnapshot_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +// traverseSnapshotInTree is a recursive function that will traverse a snapshot tree to find a given snapshot +func traverseSnapshotInTree(tree []types.VirtualMachineSnapshotTree, name string) (types.ManagedObjectReference, error) { + var o types.ManagedObjectReference + if tree == nil { + return o, errors.New("Snapshot tree is empty") + } + for _, s := range tree { + if s.Name == name { + o = s.Snapshot + break + } else { + childTree := s.ChildSnapshotList + var err error + o, err = traverseSnapshotInTree(childTree, name) + if err != nil { + return o, err + } + } + } + if o.Value == "" { + return o, errors.New("Snapshot not found") + } + + return o, nil +} + +// IsToolsRunning returns true if VMware Tools is currently running in the guest OS, and false otherwise. +func (v VirtualMachine) IsToolsRunning(ctx context.Context) (bool, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"guest.toolsRunningStatus"}, &o) + if err != nil { + return false, err + } + + return o.Guest.ToolsRunningStatus == string(types.VirtualMachineToolsRunningStatusGuestToolsRunning), nil +} + +// Wait for the VirtualMachine to change to the desired power state. +func (v VirtualMachine) WaitForPowerState(ctx context.Context, state types.VirtualMachinePowerState) error { + p := property.DefaultCollector(v.c) + err := property.Wait(ctx, p, v.Reference(), []string{PropRuntimePowerState}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Name != PropRuntimePowerState { + continue + } + if c.Val == nil { + continue + } + + ps := c.Val.(types.VirtualMachinePowerState) + if ps == state { + return true + } + } + return false + }) + + return err +} + +func (v VirtualMachine) MarkAsTemplate(ctx context.Context) error { + req := types.MarkAsTemplate{ + This: v.Reference(), + } + + _, err := methods.MarkAsTemplate(ctx, v.c, &req) + if err != nil { + return err + } + + return nil +} + +func (v VirtualMachine) MarkAsVirtualMachine(ctx context.Context, pool ResourcePool, host *HostSystem) error { + req := types.MarkAsVirtualMachine{ + This: v.Reference(), + Pool: pool.Reference(), + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + _, err := methods.MarkAsVirtualMachine(ctx, v.c, &req) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go b/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go new file mode 100644 index 0000000000..f6caf98708 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go @@ -0,0 +1,21 @@ +/* +Copyright (c) 2015 VMware, 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 object + +type VmwareDistributedVirtualSwitch struct { + DistributedVirtualSwitch +} diff --git a/vendor/github.com/vmware/govmomi/property/collector.go b/vendor/github.com/vmware/govmomi/property/collector.go new file mode 100644 index 0000000000..50ea8d8814 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/property/collector.go @@ -0,0 +1,174 @@ +/* +Copyright (c) 2015 VMware, 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 property + +import ( + "errors" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// Collector models the PropertyCollector managed object. +// +// For more information, see: +// http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vmodl.query.PropertyCollector.html +// +type Collector struct { + roundTripper soap.RoundTripper + reference types.ManagedObjectReference +} + +// DefaultCollector returns the session's default property collector. +func DefaultCollector(c *vim25.Client) *Collector { + p := Collector{ + roundTripper: c, + reference: c.ServiceContent.PropertyCollector, + } + + return &p +} + +func (p Collector) Reference() types.ManagedObjectReference { + return p.reference +} + +// Create creates a new session-specific Collector that can be used to +// retrieve property updates independent of any other Collector. +func (p *Collector) Create(ctx context.Context) (*Collector, error) { + req := types.CreatePropertyCollector{ + This: p.Reference(), + } + + res, err := methods.CreatePropertyCollector(ctx, p.roundTripper, &req) + if err != nil { + return nil, err + } + + newp := Collector{ + roundTripper: p.roundTripper, + reference: res.Returnval, + } + + return &newp, nil +} + +// Destroy destroys this Collector. +func (p *Collector) Destroy(ctx context.Context) error { + req := types.DestroyPropertyCollector{ + This: p.Reference(), + } + + _, err := methods.DestroyPropertyCollector(ctx, p.roundTripper, &req) + if err != nil { + return err + } + + p.reference = types.ManagedObjectReference{} + return nil +} + +func (p *Collector) CreateFilter(ctx context.Context, req types.CreateFilter) error { + req.This = p.Reference() + + _, err := methods.CreateFilter(ctx, p.roundTripper, &req) + if err != nil { + return err + } + + return nil +} + +func (p *Collector) WaitForUpdates(ctx context.Context, v string) (*types.UpdateSet, error) { + req := types.WaitForUpdatesEx{ + This: p.Reference(), + Version: v, + } + + res, err := methods.WaitForUpdatesEx(ctx, p.roundTripper, &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (p *Collector) RetrieveProperties(ctx context.Context, req types.RetrieveProperties) (*types.RetrievePropertiesResponse, error) { + req.This = p.Reference() + return methods.RetrieveProperties(ctx, p.roundTripper, &req) +} + +// Retrieve loads properties for a slice of managed objects. The dst argument +// must be a pointer to a []interface{}, which is populated with the instances +// of the specified managed objects, with the relevant properties filled in. If +// the properties slice is nil, all properties are loaded. +func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, ps []string, dst interface{}) error { + var propSpec *types.PropertySpec + var objectSet []types.ObjectSpec + + for _, obj := range objs { + // Ensure that all object reference types are the same + if propSpec == nil { + propSpec = &types.PropertySpec{ + Type: obj.Type, + } + + if ps == nil { + propSpec.All = types.NewBool(true) + } else { + propSpec.PathSet = ps + } + } else { + if obj.Type != propSpec.Type { + return errors.New("object references must have the same type") + } + } + + objectSpec := types.ObjectSpec{ + Obj: obj, + Skip: types.NewBool(false), + } + + objectSet = append(objectSet, objectSpec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: objectSet, + PropSet: []types.PropertySpec{*propSpec}, + }, + }, + } + + res, err := p.RetrieveProperties(ctx, req) + if err != nil { + return err + } + + return mo.LoadRetrievePropertiesResponse(res, dst) +} + +// RetrieveOne calls Retrieve with a single managed object reference. +func (p *Collector) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, ps []string, dst interface{}) error { + var objs = []types.ManagedObjectReference{obj} + return p.Retrieve(ctx, objs, ps, dst) +} diff --git a/vendor/github.com/vmware/govmomi/property/wait.go b/vendor/github.com/vmware/govmomi/property/wait.go new file mode 100644 index 0000000000..930cad7701 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/property/wait.go @@ -0,0 +1,147 @@ +/* +Copyright (c) 2015 VMware, 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 property + +import ( + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// Wait waits for any of the specified properties of the specified managed +// object to change. It calls the specified function for every update it +// receives. If this function returns false, it continues waiting for +// subsequent updates. If this function returns true, it stops waiting and +// returns. +// +// To only receive updates for the specified managed object, the function +// creates a new property collector and calls CreateFilter. A new property +// collector is required because filters can only be added, not removed. +// +// The newly created collector is destroyed before this function returns (both +// in case of success or error). +// +func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error { + p, err := c.Create(ctx) + if err != nil { + return err + } + + // Attempt to destroy the collector using the background context, as the + // specified context may have timed out or have been cancelled. + defer p.Destroy(context.Background()) + + req := types.CreateFilter{ + Spec: types.PropertyFilterSpec{ + ObjectSet: []types.ObjectSpec{ + { + Obj: obj, + }, + }, + PropSet: []types.PropertySpec{ + { + PathSet: ps, + Type: obj.Type, + }, + }, + }, + } + + err = p.CreateFilter(ctx, req) + if err != nil { + return err + } + return waitLoop(ctx, p, f) +} + +// WaitForView waits for any of the specified properties of the managed +// objects in the View to change. It calls the specified function for every update it +// receives. If this function returns false, it continues waiting for +// subsequent updates. If this function returns true, it stops waiting and +// returns. +// +// To only receive updates for the View's specified managed objects, the function +// creates a new property collector and calls CreateFilter. A new property +// collector is required because filters can only be added, not removed. +// +// The newly created collector is destroyed before this function returns (both +// in case of success or error). +// +// The code assumes that all objects in the View are the same type +func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectReference, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error { + p, err := c.Create(ctx) + if err != nil { + return err + } + + // Attempt to destroy the collector using the background context, as the + // specified context may have timed out or have been cancelled. + defer p.Destroy(context.Background()) + + req := types.CreateFilter{ + + Spec: types.PropertyFilterSpec{ + ObjectSet: []types.ObjectSpec{ + { + Obj: view, + SelectSet: []types.BaseSelectionSpec{ + &types.TraversalSpec{ + SelectionSpec: types.SelectionSpec{ + Name: "traverseEntities", + }, + Path: "view", + Type: view.Type}}, + }, + }, + PropSet: []types.PropertySpec{ + types.PropertySpec{ + Type: obj.Type, + PathSet: ps, + }, + }, + }} + + err = p.CreateFilter(ctx, req) + if err != nil { + return err + } + return waitLoop(ctx, p, f) +} + +func waitLoop(ctx context.Context, c *Collector, f func([]types.PropertyChange) bool) error { + for version := ""; ; { + res, err := c.WaitForUpdates(ctx, version) + if err != nil { + return err + } + + // Retry if the result came back empty + if res == nil { + continue + } + + version = res.Version + + for _, fs := range res.FilterSet { + for _, os := range fs.ObjectSet { + if f(os.ChangeSet) { + return nil + } + } + } + } + +} diff --git a/vendor/github.com/vmware/govmomi/scripts/contributors.sh b/vendor/github.com/vmware/govmomi/scripts/contributors.sh new file mode 100755 index 0000000000..6098738426 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/contributors.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +outfile="CONTRIBUTORS" +tmpfile="CONTRIBUTORS.tmp" +cp "${outfile}" "${tmpfile}" + +# Make sure the email address of every contributor is listed +git shortlog -sne | while read line; do + name=$(perl -pe 's/\d+\s+//' <<<"${line}") + email=$(grep -Po '(?<=<).*(?=>)' <<<"${name}") + if ! grep -q "${email}" "${outfile}"; then + echo "${name}" >> "${tmpfile}" + fi +done + +# Sort entries +( + sed -ne '1,5p' "${tmpfile}" + sed -ne '1,5!p' "${tmpfile}" | sort +) > "${outfile}" + +rm -f "${tmpfile}" diff --git a/vendor/github.com/vmware/govmomi/scripts/license.sh b/vendor/github.com/vmware/govmomi/scripts/license.sh new file mode 100755 index 0000000000..d47cad02c9 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/license.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -e + +header_dir=$(dirname $0)/headers + +tmpfile=$(mktemp) +trap "rm -f ${tmpfile}" EXIT + +git ls-files | while read file; do + years=( $(git log --format='%ai' $file | cut -d- -f1 | sort -u) ) + num_years=${#years[@]} + + if [ "${num_years}" == 0 ]; then + export YEARS="$(date +%Y)" + else + yearA=${years[0]} + yearB=${years[$((${num_years}-1))]} + + if [ ${yearA} == ${yearB} ]; then + export YEARS="${yearA}" + else + export YEARS="${yearA}-${yearB}" + fi + fi + + case "$file" in + vim25/xml/*) + # Ignore + ;; + *.go) + sed -e "s/\${YEARS}/${YEARS}/" ${header_dir}/go.txt > ${tmpfile} + last_header_line=$(grep -n '\*/' ${file} | head -1 | cut -d: -f1) + tail -n +$((${last_header_line} + 1)) ${file} >> ${tmpfile} + mv ${tmpfile} ${file} + ;; + *.rb) + sed -e "s/\${YEARS}/${YEARS}/" ${header_dir}/rb.txt > ${tmpfile} + last_header_line=$(grep -n '^$' ${file} | head -1 | cut -d: -f1) + tail -n +$((${last_header_line})) ${file} >> ${tmpfile} + mv ${tmpfile} ${file} + ;; + *) + echo "Unhandled file: $file" + ;; + esac +done + diff --git a/vendor/github.com/vmware/govmomi/session/keep_alive.go b/vendor/github.com/vmware/govmomi/session/keep_alive.go new file mode 100644 index 0000000000..f157b7f6d3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/session/keep_alive.go @@ -0,0 +1,127 @@ +/* +Copyright (c) 2015 VMware, 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 session + +import ( + "sync" + "time" + + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/soap" + "golang.org/x/net/context" +) + +type keepAlive struct { + sync.Mutex + + roundTripper soap.RoundTripper + idleTime time.Duration + notifyRequest chan struct{} + notifyStop chan struct{} + notifyWaitGroup sync.WaitGroup + + // keepAlive executes a request in the background with the purpose of + // keeping the session active. The response for this request is discarded. + keepAlive func(soap.RoundTripper) error +} + +func defaultKeepAlive(roundTripper soap.RoundTripper) error { + _, _ = methods.GetCurrentTime(context.Background(), roundTripper) + return nil +} + +// KeepAlive wraps the specified soap.RoundTripper and executes a meaningless +// API request in the background after the RoundTripper has been idle for the +// specified amount of idle time. The keep alive process only starts once a +// user logs in and runs until the user logs out again. +func KeepAlive(roundTripper soap.RoundTripper, idleTime time.Duration) soap.RoundTripper { + return KeepAliveHandler(roundTripper, idleTime, defaultKeepAlive) +} + +// KeepAliveHandler works as KeepAlive() does, but the handler param can decide how to handle errors. +// For example, if connectivity to ESX/VC is down long enough for a session to expire, a handler can choose to +// Login() on a types.NotAuthenticated error. If handler returns non-nil, the keep alive go routine will be stopped. +func KeepAliveHandler(roundTripper soap.RoundTripper, idleTime time.Duration, handler func(soap.RoundTripper) error) soap.RoundTripper { + k := &keepAlive{ + roundTripper: roundTripper, + idleTime: idleTime, + notifyRequest: make(chan struct{}), + } + + k.keepAlive = handler + + return k +} + +func (k *keepAlive) start() { + k.Lock() + defer k.Unlock() + + if k.notifyStop != nil { + return + } + + // This channel must be closed to terminate idle timer. + k.notifyStop = make(chan struct{}) + k.notifyWaitGroup.Add(1) + + go func() { + defer k.notifyWaitGroup.Done() + + for t := time.NewTimer(k.idleTime); ; { + select { + case <-k.notifyStop: + return + case <-k.notifyRequest: + t.Reset(k.idleTime) + case <-t.C: + if err := k.keepAlive(k.roundTripper); err != nil { + k.stop() + } + t = time.NewTimer(k.idleTime) + } + } + }() +} + +func (k *keepAlive) stop() { + k.Lock() + defer k.Unlock() + + if k.notifyStop != nil { + close(k.notifyStop) + k.notifyWaitGroup.Wait() + k.notifyStop = nil + } +} + +func (k *keepAlive) RoundTrip(ctx context.Context, req, res soap.HasFault) error { + err := k.roundTripper.RoundTrip(ctx, req, res) + if err != nil { + return err + } + + // Start ticker on login, stop ticker on logout. + switch req.(type) { + case *methods.LoginBody, *methods.LoginExtensionByCertificateBody: + k.start() + case *methods.LogoutBody: + k.stop() + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/session/manager.go b/vendor/github.com/vmware/govmomi/session/manager.go new file mode 100644 index 0000000000..5df6ebfc4b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/session/manager.go @@ -0,0 +1,163 @@ +/* +Copyright (c) 2015 VMware, 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 session + +import ( + "net/url" + + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type Manager struct { + client *vim25.Client + userSession *types.UserSession +} + +func NewManager(client *vim25.Client) *Manager { + m := Manager{ + client: client, + } + + return &m +} + +func (sm Manager) Reference() types.ManagedObjectReference { + return *sm.client.ServiceContent.SessionManager +} + +func (sm *Manager) Login(ctx context.Context, u *url.Userinfo) error { + req := types.Login{ + This: sm.Reference(), + } + + if u != nil { + req.UserName = u.Username() + if pw, ok := u.Password(); ok { + req.Password = pw + } + } + + login, err := methods.Login(ctx, sm.client, &req) + if err != nil { + return err + } + + sm.userSession = &login.Returnval + return nil +} + +func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string, locale string) error { + req := types.LoginExtensionByCertificate{ + This: sm.Reference(), + ExtensionKey: key, + Locale: locale, + } + + login, err := methods.LoginExtensionByCertificate(ctx, sm.client, &req) + if err != nil { + return err + } + + sm.userSession = &login.Returnval + return nil +} + +func (sm *Manager) Logout(ctx context.Context) error { + req := types.Logout{ + This: sm.Reference(), + } + + _, err := methods.Logout(ctx, sm.client, &req) + if err != nil { + return err + } + + sm.userSession = nil + return nil +} + +// UserSession retrieves and returns the SessionManager's CurrentSession field. +// Nil is returned if the session is not authenticated. +func (sm *Manager) UserSession(ctx context.Context) (*types.UserSession, error) { + var mgr mo.SessionManager + + pc := property.DefaultCollector(sm.client) + err := pc.RetrieveOne(ctx, sm.Reference(), []string{"currentSession"}, &mgr) + if err != nil { + // It's OK if we can't retrieve properties because we're not authenticated + if f, ok := err.(types.HasFault); ok { + switch f.Fault().(type) { + case *types.NotAuthenticated: + return nil, nil + } + } + + return nil, err + } + + return mgr.CurrentSession, nil +} + +func (sm *Manager) TerminateSession(ctx context.Context, sessionId []string) error { + req := types.TerminateSession{ + This: sm.Reference(), + SessionId: sessionId, + } + + _, err := methods.TerminateSession(ctx, sm.client, &req) + return err +} + +// SessionIsActive checks whether the session that was created at login is +// still valid. This function only works against vCenter. +func (sm *Manager) SessionIsActive(ctx context.Context) (bool, error) { + if sm.userSession == nil { + return false, nil + } + + req := types.SessionIsActive{ + This: sm.Reference(), + SessionID: sm.userSession.Key, + UserName: sm.userSession.UserName, + } + + active, err := methods.SessionIsActive(ctx, sm.client, &req) + if err != nil { + return false, err + } + + return active.Returnval, err +} + +func (sm *Manager) AcquireGenericServiceTicket(ctx context.Context, spec types.BaseSessionManagerServiceRequestSpec) (*types.SessionManagerGenericServiceTicket, error) { + req := types.AcquireGenericServiceTicket{ + This: sm.Reference(), + Spec: spec, + } + + res, err := methods.AcquireGenericServiceTicket(ctx, sm.client, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/task/error.go b/vendor/github.com/vmware/govmomi/task/error.go new file mode 100644 index 0000000000..5f6b8503f5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/task/error.go @@ -0,0 +1,32 @@ +/* +Copyright (c) 2015 VMware, 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 task + +import "github.com/vmware/govmomi/vim25/types" + +type Error struct { + *types.LocalizedMethodFault +} + +// Error returns the task's localized fault message. +func (e Error) Error() string { + return e.LocalizedMethodFault.LocalizedMessage +} + +func (e Error) Fault() types.BaseMethodFault { + return e.LocalizedMethodFault.Fault +} diff --git a/vendor/github.com/vmware/govmomi/task/wait.go b/vendor/github.com/vmware/govmomi/task/wait.go new file mode 100644 index 0000000000..9432ee7346 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/task/wait.go @@ -0,0 +1,126 @@ +/* +Copyright (c) 2015 VMware, 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 task + +import ( + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25/progress" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type taskProgress struct { + info *types.TaskInfo +} + +func (t taskProgress) Percentage() float32 { + return float32(t.info.Progress) +} + +func (t taskProgress) Detail() string { + return "" +} + +func (t taskProgress) Error() error { + if t.info.Error != nil { + return Error{t.info.Error} + } + + return nil +} + +type taskCallback struct { + ch chan<- progress.Report + info *types.TaskInfo + err error +} + +func (t *taskCallback) fn(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Name != "info" { + continue + } + + if c.Op != types.PropertyChangeOpAssign { + continue + } + + if c.Val == nil { + continue + } + + ti := c.Val.(types.TaskInfo) + t.info = &ti + } + + pr := taskProgress{t.info} + + // Store copy of error, so Wait() can return it as well. + t.err = pr.Error() + + switch t.info.State { + case types.TaskInfoStateQueued, types.TaskInfoStateRunning: + if t.ch != nil { + // Don't care if this is dropped + select { + case t.ch <- pr: + default: + } + } + return false + case types.TaskInfoStateSuccess, types.TaskInfoStateError: + if t.ch != nil { + // Last one must always be delivered + t.ch <- pr + } + return true + default: + panic("unknown state: " + t.info.State) + } +} + +// Wait waits for a task to finish with either success or failure. It does so +// by waiting for the "info" property of task managed object to change. The +// function returns when it finds the task in the "success" or "error" state. +// In the former case, the return value is nil. In the latter case the return +// value is an instance of this package's Error struct. +// +// Any error returned while waiting for property changes causes the function to +// return immediately and propagate the error. +// +// If the progress.Sinker argument is specified, any progress updates for the +// task are sent here. The completion percentage is passed through directly. +// The detail for the progress update is set to an empty string. If the task +// finishes in the error state, the error instance is passed through as well. +// Note that this error is the same error that is returned by this function. +// +func Wait(ctx context.Context, ref types.ManagedObjectReference, pc *property.Collector, s progress.Sinker) (*types.TaskInfo, error) { + cb := &taskCallback{} + + // Include progress sink if specified + if s != nil { + cb.ch = s.Sink() + defer close(cb.ch) + } + + err := property.Wait(ctx, pc, ref, []string{"info"}, cb.fn) + if err != nil { + return nil, err + } + + return cb.info, cb.err +} diff --git a/vendor/github.com/vmware/govmomi/vim25/client.go b/vendor/github.com/vmware/govmomi/vim25/client.go new file mode 100644 index 0000000000..210bf6bffc --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/client.go @@ -0,0 +1,123 @@ +/* +Copyright (c) 2015-2016 VMware, 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 vim25 + +import ( + "encoding/json" + + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// Client is a tiny wrapper around the vim25/soap Client that stores session +// specific state (i.e. state that only needs to be retrieved once after the +// client has been created). This means the client can be reused after +// serialization without performing additional requests for initialization. +type Client struct { + *soap.Client + + ServiceContent types.ServiceContent + + // RoundTripper is a separate field such that the client's implementation of + // the RoundTripper interface can be wrapped by separate implementations for + // extra functionality (for example, reauthentication on session timeout). + RoundTripper soap.RoundTripper +} + +// NewClient creates and returns a new client wirh the ServiceContent field +// filled in. +func NewClient(ctx context.Context, rt soap.RoundTripper) (*Client, error) { + serviceContent, err := methods.GetServiceContent(ctx, rt) + if err != nil { + return nil, err + } + + c := Client{ + ServiceContent: serviceContent, + RoundTripper: rt, + } + + // Set client if it happens to be a soap.Client + if sc, ok := rt.(*soap.Client); ok { + c.Client = sc + } + + return &c, nil +} + +// RoundTrip dispatches to the RoundTripper field. +func (c *Client) RoundTrip(ctx context.Context, req, res soap.HasFault) error { + return c.RoundTripper.RoundTrip(ctx, req, res) +} + +type marshaledClient struct { + SoapClient *soap.Client + ServiceContent types.ServiceContent +} + +func (c *Client) MarshalJSON() ([]byte, error) { + m := marshaledClient{ + SoapClient: c.Client, + ServiceContent: c.ServiceContent, + } + + return json.Marshal(m) +} + +func (c *Client) UnmarshalJSON(b []byte) error { + var m marshaledClient + + err := json.Unmarshal(b, &m) + if err != nil { + return err + } + + *c = Client{ + Client: m.SoapClient, + ServiceContent: m.ServiceContent, + RoundTripper: m.SoapClient, + } + + return nil +} + +// Valid returns whether or not the client is valid and ready for use. +// This should be called after unmarshalling the client. +func (c *Client) Valid() bool { + if c == nil { + return false + } + + if c.Client == nil { + return false + } + + // Use arbitrary pointer field in the service content. + // Doesn't matter which one, as long as it is populated by default. + if c.ServiceContent.SessionManager == nil { + return false + } + + return true +} + +// IsVC returns true if we are connected to a vCenter +func (c *Client) IsVC() bool { + return c.ServiceContent.About.ApiType == "VirtualCenter" +} diff --git a/vendor/github.com/vmware/govmomi/vim25/debug/debug.go b/vendor/github.com/vmware/govmomi/vim25/debug/debug.go new file mode 100644 index 0000000000..22d5471784 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/debug/debug.go @@ -0,0 +1,81 @@ +/* +Copyright (c) 2014 VMware, 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 debug + +import ( + "io" + "os" + "path" +) + +// Provider specified the interface types must implement to be used as a +// debugging sink. Having multiple such sink implementations allows it to be +// changed externally (for example when running tests). +type Provider interface { + NewFile(s string) io.WriteCloser + Flush() +} + +var currentProvider Provider = nil + +func SetProvider(p Provider) { + if currentProvider != nil { + currentProvider.Flush() + } + currentProvider = p +} + +// Enabled returns whether debugging is enabled or not. +func Enabled() bool { + return currentProvider != nil +} + +// NewFile dispatches to the current provider's NewFile function. +func NewFile(s string) io.WriteCloser { + return currentProvider.NewFile(s) +} + +// Flush dispatches to the current provider's Flush function. +func Flush() { + currentProvider.Flush() +} + +// FileProvider implements a debugging provider that creates a real file for +// every call to NewFile. It maintains a list of all files that it creates, +// such that it can close them when its Flush function is called. +type FileProvider struct { + Path string + + files []*os.File +} + +func (fp *FileProvider) NewFile(p string) io.WriteCloser { + f, err := os.Create(path.Join(fp.Path, p)) + if err != nil { + panic(err) + } + + fp.files = append(fp.files, f) + + return f +} + +func (fp *FileProvider) Flush() { + for _, f := range fp.files { + f.Close() + } +} diff --git a/vendor/github.com/vmware/govmomi/vim25/doc.go b/vendor/github.com/vmware/govmomi/vim25/doc.go new file mode 100644 index 0000000000..acb2c9f64d --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/doc.go @@ -0,0 +1,29 @@ +/* +Copyright (c) 2015 VMware, 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 vim25 provides a minimal client implementation to use with other +packages in the vim25 tree. The code in this package intentionally does not +take any dependendies outside the vim25 tree. + +The client implementation in this package embeds the soap.Client structure. +Additionally, it stores the value of the session's ServiceContent object. This +object stores references to a variety of subsystems, such as the root property +collector, the session manager, and the search index. The client is fully +functional after serialization and deserialization, without the need for +additional requests for initialization. +*/ +package vim25 diff --git a/vendor/github.com/vmware/govmomi/vim25/methods/internal.go b/vendor/github.com/vmware/govmomi/vim25/methods/internal.go new file mode 100644 index 0000000000..e2fb2a22bf --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/methods/internal.go @@ -0,0 +1,123 @@ +/* +Copyright (c) 2014-2015 VMware, 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 methods + +import ( + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type RetrieveDynamicTypeManagerBody struct { + Req *types.RetrieveDynamicTypeManager `xml:"urn:vim25 RetrieveDynamicTypeManager"` + Res *types.RetrieveDynamicTypeManagerResponse `xml:"urn:vim25 RetrieveDynamicTypeManagerResponse"` + Fault_ *soap.Fault +} + +func (b *RetrieveDynamicTypeManagerBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveDynamicTypeManager(ctx context.Context, r soap.RoundTripper, req *types.RetrieveDynamicTypeManager) (*types.RetrieveDynamicTypeManagerResponse, error) { + var reqBody, resBody RetrieveDynamicTypeManagerBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveManagedMethodExecuterBody struct { + Req *types.RetrieveManagedMethodExecuter `xml:"urn:vim25 RetrieveManagedMethodExecuter"` + Res *types.RetrieveManagedMethodExecuterResponse `xml:"urn:vim25 RetrieveManagedMethodExecuterResponse"` + Fault_ *soap.Fault +} + +func (b *RetrieveManagedMethodExecuterBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveManagedMethodExecuter(ctx context.Context, r soap.RoundTripper, req *types.RetrieveManagedMethodExecuter) (*types.RetrieveManagedMethodExecuterResponse, error) { + var reqBody, resBody RetrieveManagedMethodExecuterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DynamicTypeMgrQueryMoInstancesBody struct { + Req *types.DynamicTypeMgrQueryMoInstances `xml:"urn:vim25 DynamicTypeMgrQueryMoInstances"` + Res *types.DynamicTypeMgrQueryMoInstancesResponse `xml:"urn:vim25 DynamicTypeMgrQueryMoInstancesResponse"` + Fault_ *soap.Fault +} + +func (b *DynamicTypeMgrQueryMoInstancesBody) Fault() *soap.Fault { return b.Fault_ } + +func DynamicTypeMgrQueryMoInstances(ctx context.Context, r soap.RoundTripper, req *types.DynamicTypeMgrQueryMoInstances) (*types.DynamicTypeMgrQueryMoInstancesResponse, error) { + var reqBody, resBody DynamicTypeMgrQueryMoInstancesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DynamicTypeMgrQueryTypeInfoBody struct { + Req *types.DynamicTypeMgrQueryTypeInfo `xml:"urn:vim25 DynamicTypeMgrQueryTypeInfo"` + Res *types.DynamicTypeMgrQueryTypeInfoResponse `xml:"urn:vim25 DynamicTypeMgrQueryTypeInfoResponse"` + Fault_ *soap.Fault +} + +func (b *DynamicTypeMgrQueryTypeInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func DynamicTypeMgrQueryTypeInfo(ctx context.Context, r soap.RoundTripper, req *types.DynamicTypeMgrQueryTypeInfo) (*types.DynamicTypeMgrQueryTypeInfoResponse, error) { + var reqBody, resBody DynamicTypeMgrQueryTypeInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExecuteSoapBody struct { + Req *types.ExecuteSoap `xml:"urn:vim25 ExecuteSoap"` + Res *types.ExecuteSoapResponse `xml:"urn:vim25 ExecuteSoapResponse"` + Fault_ *soap.Fault +} + +func (b *ExecuteSoapBody) Fault() *soap.Fault { return b.Fault_ } + +func ExecuteSoap(ctx context.Context, r soap.RoundTripper, req *types.ExecuteSoap) (*types.ExecuteSoapResponse, error) { + var reqBody, resBody ExecuteSoapBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/methods/methods.go b/vendor/github.com/vmware/govmomi/vim25/methods/methods.go new file mode 100644 index 0000000000..ccc1b38c82 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/methods/methods.go @@ -0,0 +1,14103 @@ +/* +Copyright (c) 2014-2016 VMware, 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 methods + +import ( + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type AbdicateDomOwnershipBody struct { + Req *types.AbdicateDomOwnership `xml:"urn:vim25 AbdicateDomOwnership,omitempty"` + Res *types.AbdicateDomOwnershipResponse `xml:"urn:vim25 AbdicateDomOwnershipResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AbdicateDomOwnershipBody) Fault() *soap.Fault { return b.Fault_ } + +func AbdicateDomOwnership(ctx context.Context, r soap.RoundTripper, req *types.AbdicateDomOwnership) (*types.AbdicateDomOwnershipResponse, error) { + var reqBody, resBody AbdicateDomOwnershipBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcknowledgeAlarmBody struct { + Req *types.AcknowledgeAlarm `xml:"urn:vim25 AcknowledgeAlarm,omitempty"` + Res *types.AcknowledgeAlarmResponse `xml:"urn:vim25 AcknowledgeAlarmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcknowledgeAlarmBody) Fault() *soap.Fault { return b.Fault_ } + +func AcknowledgeAlarm(ctx context.Context, r soap.RoundTripper, req *types.AcknowledgeAlarm) (*types.AcknowledgeAlarmResponse, error) { + var reqBody, resBody AcknowledgeAlarmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireCimServicesTicketBody struct { + Req *types.AcquireCimServicesTicket `xml:"urn:vim25 AcquireCimServicesTicket,omitempty"` + Res *types.AcquireCimServicesTicketResponse `xml:"urn:vim25 AcquireCimServicesTicketResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireCimServicesTicketBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireCimServicesTicket(ctx context.Context, r soap.RoundTripper, req *types.AcquireCimServicesTicket) (*types.AcquireCimServicesTicketResponse, error) { + var reqBody, resBody AcquireCimServicesTicketBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireCloneTicketBody struct { + Req *types.AcquireCloneTicket `xml:"urn:vim25 AcquireCloneTicket,omitempty"` + Res *types.AcquireCloneTicketResponse `xml:"urn:vim25 AcquireCloneTicketResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireCloneTicketBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireCloneTicket(ctx context.Context, r soap.RoundTripper, req *types.AcquireCloneTicket) (*types.AcquireCloneTicketResponse, error) { + var reqBody, resBody AcquireCloneTicketBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireCredentialsInGuestBody struct { + Req *types.AcquireCredentialsInGuest `xml:"urn:vim25 AcquireCredentialsInGuest,omitempty"` + Res *types.AcquireCredentialsInGuestResponse `xml:"urn:vim25 AcquireCredentialsInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireCredentialsInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireCredentialsInGuest(ctx context.Context, r soap.RoundTripper, req *types.AcquireCredentialsInGuest) (*types.AcquireCredentialsInGuestResponse, error) { + var reqBody, resBody AcquireCredentialsInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireGenericServiceTicketBody struct { + Req *types.AcquireGenericServiceTicket `xml:"urn:vim25 AcquireGenericServiceTicket,omitempty"` + Res *types.AcquireGenericServiceTicketResponse `xml:"urn:vim25 AcquireGenericServiceTicketResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireGenericServiceTicketBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireGenericServiceTicket(ctx context.Context, r soap.RoundTripper, req *types.AcquireGenericServiceTicket) (*types.AcquireGenericServiceTicketResponse, error) { + var reqBody, resBody AcquireGenericServiceTicketBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireLocalTicketBody struct { + Req *types.AcquireLocalTicket `xml:"urn:vim25 AcquireLocalTicket,omitempty"` + Res *types.AcquireLocalTicketResponse `xml:"urn:vim25 AcquireLocalTicketResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireLocalTicketBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireLocalTicket(ctx context.Context, r soap.RoundTripper, req *types.AcquireLocalTicket) (*types.AcquireLocalTicketResponse, error) { + var reqBody, resBody AcquireLocalTicketBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireMksTicketBody struct { + Req *types.AcquireMksTicket `xml:"urn:vim25 AcquireMksTicket,omitempty"` + Res *types.AcquireMksTicketResponse `xml:"urn:vim25 AcquireMksTicketResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireMksTicketBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireMksTicket(ctx context.Context, r soap.RoundTripper, req *types.AcquireMksTicket) (*types.AcquireMksTicketResponse, error) { + var reqBody, resBody AcquireMksTicketBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AcquireTicketBody struct { + Req *types.AcquireTicket `xml:"urn:vim25 AcquireTicket,omitempty"` + Res *types.AcquireTicketResponse `xml:"urn:vim25 AcquireTicketResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AcquireTicketBody) Fault() *soap.Fault { return b.Fault_ } + +func AcquireTicket(ctx context.Context, r soap.RoundTripper, req *types.AcquireTicket) (*types.AcquireTicketResponse, error) { + var reqBody, resBody AcquireTicketBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddAuthorizationRoleBody struct { + Req *types.AddAuthorizationRole `xml:"urn:vim25 AddAuthorizationRole,omitempty"` + Res *types.AddAuthorizationRoleResponse `xml:"urn:vim25 AddAuthorizationRoleResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddAuthorizationRoleBody) Fault() *soap.Fault { return b.Fault_ } + +func AddAuthorizationRole(ctx context.Context, r soap.RoundTripper, req *types.AddAuthorizationRole) (*types.AddAuthorizationRoleResponse, error) { + var reqBody, resBody AddAuthorizationRoleBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddCustomFieldDefBody struct { + Req *types.AddCustomFieldDef `xml:"urn:vim25 AddCustomFieldDef,omitempty"` + Res *types.AddCustomFieldDefResponse `xml:"urn:vim25 AddCustomFieldDefResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddCustomFieldDefBody) Fault() *soap.Fault { return b.Fault_ } + +func AddCustomFieldDef(ctx context.Context, r soap.RoundTripper, req *types.AddCustomFieldDef) (*types.AddCustomFieldDefResponse, error) { + var reqBody, resBody AddCustomFieldDefBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddDVPortgroup_TaskBody struct { + Req *types.AddDVPortgroup_Task `xml:"urn:vim25 AddDVPortgroup_Task,omitempty"` + Res *types.AddDVPortgroup_TaskResponse `xml:"urn:vim25 AddDVPortgroup_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddDVPortgroup_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func AddDVPortgroup_Task(ctx context.Context, r soap.RoundTripper, req *types.AddDVPortgroup_Task) (*types.AddDVPortgroup_TaskResponse, error) { + var reqBody, resBody AddDVPortgroup_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddDisks_TaskBody struct { + Req *types.AddDisks_Task `xml:"urn:vim25 AddDisks_Task,omitempty"` + Res *types.AddDisks_TaskResponse `xml:"urn:vim25 AddDisks_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddDisks_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func AddDisks_Task(ctx context.Context, r soap.RoundTripper, req *types.AddDisks_Task) (*types.AddDisks_TaskResponse, error) { + var reqBody, resBody AddDisks_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddGuestAliasBody struct { + Req *types.AddGuestAlias `xml:"urn:vim25 AddGuestAlias,omitempty"` + Res *types.AddGuestAliasResponse `xml:"urn:vim25 AddGuestAliasResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddGuestAliasBody) Fault() *soap.Fault { return b.Fault_ } + +func AddGuestAlias(ctx context.Context, r soap.RoundTripper, req *types.AddGuestAlias) (*types.AddGuestAliasResponse, error) { + var reqBody, resBody AddGuestAliasBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddHost_TaskBody struct { + Req *types.AddHost_Task `xml:"urn:vim25 AddHost_Task,omitempty"` + Res *types.AddHost_TaskResponse `xml:"urn:vim25 AddHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func AddHost_Task(ctx context.Context, r soap.RoundTripper, req *types.AddHost_Task) (*types.AddHost_TaskResponse, error) { + var reqBody, resBody AddHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddInternetScsiSendTargetsBody struct { + Req *types.AddInternetScsiSendTargets `xml:"urn:vim25 AddInternetScsiSendTargets,omitempty"` + Res *types.AddInternetScsiSendTargetsResponse `xml:"urn:vim25 AddInternetScsiSendTargetsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddInternetScsiSendTargetsBody) Fault() *soap.Fault { return b.Fault_ } + +func AddInternetScsiSendTargets(ctx context.Context, r soap.RoundTripper, req *types.AddInternetScsiSendTargets) (*types.AddInternetScsiSendTargetsResponse, error) { + var reqBody, resBody AddInternetScsiSendTargetsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddInternetScsiStaticTargetsBody struct { + Req *types.AddInternetScsiStaticTargets `xml:"urn:vim25 AddInternetScsiStaticTargets,omitempty"` + Res *types.AddInternetScsiStaticTargetsResponse `xml:"urn:vim25 AddInternetScsiStaticTargetsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddInternetScsiStaticTargetsBody) Fault() *soap.Fault { return b.Fault_ } + +func AddInternetScsiStaticTargets(ctx context.Context, r soap.RoundTripper, req *types.AddInternetScsiStaticTargets) (*types.AddInternetScsiStaticTargetsResponse, error) { + var reqBody, resBody AddInternetScsiStaticTargetsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddLicenseBody struct { + Req *types.AddLicense `xml:"urn:vim25 AddLicense,omitempty"` + Res *types.AddLicenseResponse `xml:"urn:vim25 AddLicenseResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddLicenseBody) Fault() *soap.Fault { return b.Fault_ } + +func AddLicense(ctx context.Context, r soap.RoundTripper, req *types.AddLicense) (*types.AddLicenseResponse, error) { + var reqBody, resBody AddLicenseBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddNetworkResourcePoolBody struct { + Req *types.AddNetworkResourcePool `xml:"urn:vim25 AddNetworkResourcePool,omitempty"` + Res *types.AddNetworkResourcePoolResponse `xml:"urn:vim25 AddNetworkResourcePoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddNetworkResourcePoolBody) Fault() *soap.Fault { return b.Fault_ } + +func AddNetworkResourcePool(ctx context.Context, r soap.RoundTripper, req *types.AddNetworkResourcePool) (*types.AddNetworkResourcePoolResponse, error) { + var reqBody, resBody AddNetworkResourcePoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddPortGroupBody struct { + Req *types.AddPortGroup `xml:"urn:vim25 AddPortGroup,omitempty"` + Res *types.AddPortGroupResponse `xml:"urn:vim25 AddPortGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddPortGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func AddPortGroup(ctx context.Context, r soap.RoundTripper, req *types.AddPortGroup) (*types.AddPortGroupResponse, error) { + var reqBody, resBody AddPortGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddServiceConsoleVirtualNicBody struct { + Req *types.AddServiceConsoleVirtualNic `xml:"urn:vim25 AddServiceConsoleVirtualNic,omitempty"` + Res *types.AddServiceConsoleVirtualNicResponse `xml:"urn:vim25 AddServiceConsoleVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddServiceConsoleVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func AddServiceConsoleVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.AddServiceConsoleVirtualNic) (*types.AddServiceConsoleVirtualNicResponse, error) { + var reqBody, resBody AddServiceConsoleVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddStandaloneHost_TaskBody struct { + Req *types.AddStandaloneHost_Task `xml:"urn:vim25 AddStandaloneHost_Task,omitempty"` + Res *types.AddStandaloneHost_TaskResponse `xml:"urn:vim25 AddStandaloneHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddStandaloneHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func AddStandaloneHost_Task(ctx context.Context, r soap.RoundTripper, req *types.AddStandaloneHost_Task) (*types.AddStandaloneHost_TaskResponse, error) { + var reqBody, resBody AddStandaloneHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddVirtualNicBody struct { + Req *types.AddVirtualNic `xml:"urn:vim25 AddVirtualNic,omitempty"` + Res *types.AddVirtualNicResponse `xml:"urn:vim25 AddVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func AddVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.AddVirtualNic) (*types.AddVirtualNicResponse, error) { + var reqBody, resBody AddVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AddVirtualSwitchBody struct { + Req *types.AddVirtualSwitch `xml:"urn:vim25 AddVirtualSwitch,omitempty"` + Res *types.AddVirtualSwitchResponse `xml:"urn:vim25 AddVirtualSwitchResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AddVirtualSwitchBody) Fault() *soap.Fault { return b.Fault_ } + +func AddVirtualSwitch(ctx context.Context, r soap.RoundTripper, req *types.AddVirtualSwitch) (*types.AddVirtualSwitchResponse, error) { + var reqBody, resBody AddVirtualSwitchBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AllocateIpv4AddressBody struct { + Req *types.AllocateIpv4Address `xml:"urn:vim25 AllocateIpv4Address,omitempty"` + Res *types.AllocateIpv4AddressResponse `xml:"urn:vim25 AllocateIpv4AddressResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AllocateIpv4AddressBody) Fault() *soap.Fault { return b.Fault_ } + +func AllocateIpv4Address(ctx context.Context, r soap.RoundTripper, req *types.AllocateIpv4Address) (*types.AllocateIpv4AddressResponse, error) { + var reqBody, resBody AllocateIpv4AddressBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AllocateIpv6AddressBody struct { + Req *types.AllocateIpv6Address `xml:"urn:vim25 AllocateIpv6Address,omitempty"` + Res *types.AllocateIpv6AddressResponse `xml:"urn:vim25 AllocateIpv6AddressResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AllocateIpv6AddressBody) Fault() *soap.Fault { return b.Fault_ } + +func AllocateIpv6Address(ctx context.Context, r soap.RoundTripper, req *types.AllocateIpv6Address) (*types.AllocateIpv6AddressResponse, error) { + var reqBody, resBody AllocateIpv6AddressBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AnswerVMBody struct { + Req *types.AnswerVM `xml:"urn:vim25 AnswerVM,omitempty"` + Res *types.AnswerVMResponse `xml:"urn:vim25 AnswerVMResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AnswerVMBody) Fault() *soap.Fault { return b.Fault_ } + +func AnswerVM(ctx context.Context, r soap.RoundTripper, req *types.AnswerVM) (*types.AnswerVMResponse, error) { + var reqBody, resBody AnswerVMBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ApplyHostConfig_TaskBody struct { + Req *types.ApplyHostConfig_Task `xml:"urn:vim25 ApplyHostConfig_Task,omitempty"` + Res *types.ApplyHostConfig_TaskResponse `xml:"urn:vim25 ApplyHostConfig_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ApplyHostConfig_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ApplyHostConfig_Task(ctx context.Context, r soap.RoundTripper, req *types.ApplyHostConfig_Task) (*types.ApplyHostConfig_TaskResponse, error) { + var reqBody, resBody ApplyHostConfig_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ApplyRecommendationBody struct { + Req *types.ApplyRecommendation `xml:"urn:vim25 ApplyRecommendation,omitempty"` + Res *types.ApplyRecommendationResponse `xml:"urn:vim25 ApplyRecommendationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ApplyRecommendationBody) Fault() *soap.Fault { return b.Fault_ } + +func ApplyRecommendation(ctx context.Context, r soap.RoundTripper, req *types.ApplyRecommendation) (*types.ApplyRecommendationResponse, error) { + var reqBody, resBody ApplyRecommendationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ApplyStorageDrsRecommendationToPod_TaskBody struct { + Req *types.ApplyStorageDrsRecommendationToPod_Task `xml:"urn:vim25 ApplyStorageDrsRecommendationToPod_Task,omitempty"` + Res *types.ApplyStorageDrsRecommendationToPod_TaskResponse `xml:"urn:vim25 ApplyStorageDrsRecommendationToPod_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ApplyStorageDrsRecommendationToPod_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ApplyStorageDrsRecommendationToPod_Task(ctx context.Context, r soap.RoundTripper, req *types.ApplyStorageDrsRecommendationToPod_Task) (*types.ApplyStorageDrsRecommendationToPod_TaskResponse, error) { + var reqBody, resBody ApplyStorageDrsRecommendationToPod_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ApplyStorageDrsRecommendation_TaskBody struct { + Req *types.ApplyStorageDrsRecommendation_Task `xml:"urn:vim25 ApplyStorageDrsRecommendation_Task,omitempty"` + Res *types.ApplyStorageDrsRecommendation_TaskResponse `xml:"urn:vim25 ApplyStorageDrsRecommendation_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ApplyStorageDrsRecommendation_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ApplyStorageDrsRecommendation_Task(ctx context.Context, r soap.RoundTripper, req *types.ApplyStorageDrsRecommendation_Task) (*types.ApplyStorageDrsRecommendation_TaskResponse, error) { + var reqBody, resBody ApplyStorageDrsRecommendation_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AreAlarmActionsEnabledBody struct { + Req *types.AreAlarmActionsEnabled `xml:"urn:vim25 AreAlarmActionsEnabled,omitempty"` + Res *types.AreAlarmActionsEnabledResponse `xml:"urn:vim25 AreAlarmActionsEnabledResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AreAlarmActionsEnabledBody) Fault() *soap.Fault { return b.Fault_ } + +func AreAlarmActionsEnabled(ctx context.Context, r soap.RoundTripper, req *types.AreAlarmActionsEnabled) (*types.AreAlarmActionsEnabledResponse, error) { + var reqBody, resBody AreAlarmActionsEnabledBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AssignUserToGroupBody struct { + Req *types.AssignUserToGroup `xml:"urn:vim25 AssignUserToGroup,omitempty"` + Res *types.AssignUserToGroupResponse `xml:"urn:vim25 AssignUserToGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AssignUserToGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func AssignUserToGroup(ctx context.Context, r soap.RoundTripper, req *types.AssignUserToGroup) (*types.AssignUserToGroupResponse, error) { + var reqBody, resBody AssignUserToGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AssociateProfileBody struct { + Req *types.AssociateProfile `xml:"urn:vim25 AssociateProfile,omitempty"` + Res *types.AssociateProfileResponse `xml:"urn:vim25 AssociateProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AssociateProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func AssociateProfile(ctx context.Context, r soap.RoundTripper, req *types.AssociateProfile) (*types.AssociateProfileResponse, error) { + var reqBody, resBody AssociateProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AttachScsiLunBody struct { + Req *types.AttachScsiLun `xml:"urn:vim25 AttachScsiLun,omitempty"` + Res *types.AttachScsiLunResponse `xml:"urn:vim25 AttachScsiLunResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AttachScsiLunBody) Fault() *soap.Fault { return b.Fault_ } + +func AttachScsiLun(ctx context.Context, r soap.RoundTripper, req *types.AttachScsiLun) (*types.AttachScsiLunResponse, error) { + var reqBody, resBody AttachScsiLunBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AttachScsiLunEx_TaskBody struct { + Req *types.AttachScsiLunEx_Task `xml:"urn:vim25 AttachScsiLunEx_Task,omitempty"` + Res *types.AttachScsiLunEx_TaskResponse `xml:"urn:vim25 AttachScsiLunEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AttachScsiLunEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func AttachScsiLunEx_Task(ctx context.Context, r soap.RoundTripper, req *types.AttachScsiLunEx_Task) (*types.AttachScsiLunEx_TaskResponse, error) { + var reqBody, resBody AttachScsiLunEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AttachVmfsExtentBody struct { + Req *types.AttachVmfsExtent `xml:"urn:vim25 AttachVmfsExtent,omitempty"` + Res *types.AttachVmfsExtentResponse `xml:"urn:vim25 AttachVmfsExtentResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AttachVmfsExtentBody) Fault() *soap.Fault { return b.Fault_ } + +func AttachVmfsExtent(ctx context.Context, r soap.RoundTripper, req *types.AttachVmfsExtent) (*types.AttachVmfsExtentResponse, error) { + var reqBody, resBody AttachVmfsExtentBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AutoStartPowerOffBody struct { + Req *types.AutoStartPowerOff `xml:"urn:vim25 AutoStartPowerOff,omitempty"` + Res *types.AutoStartPowerOffResponse `xml:"urn:vim25 AutoStartPowerOffResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AutoStartPowerOffBody) Fault() *soap.Fault { return b.Fault_ } + +func AutoStartPowerOff(ctx context.Context, r soap.RoundTripper, req *types.AutoStartPowerOff) (*types.AutoStartPowerOffResponse, error) { + var reqBody, resBody AutoStartPowerOffBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type AutoStartPowerOnBody struct { + Req *types.AutoStartPowerOn `xml:"urn:vim25 AutoStartPowerOn,omitempty"` + Res *types.AutoStartPowerOnResponse `xml:"urn:vim25 AutoStartPowerOnResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *AutoStartPowerOnBody) Fault() *soap.Fault { return b.Fault_ } + +func AutoStartPowerOn(ctx context.Context, r soap.RoundTripper, req *types.AutoStartPowerOn) (*types.AutoStartPowerOnResponse, error) { + var reqBody, resBody AutoStartPowerOnBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type BackupFirmwareConfigurationBody struct { + Req *types.BackupFirmwareConfiguration `xml:"urn:vim25 BackupFirmwareConfiguration,omitempty"` + Res *types.BackupFirmwareConfigurationResponse `xml:"urn:vim25 BackupFirmwareConfigurationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *BackupFirmwareConfigurationBody) Fault() *soap.Fault { return b.Fault_ } + +func BackupFirmwareConfiguration(ctx context.Context, r soap.RoundTripper, req *types.BackupFirmwareConfiguration) (*types.BackupFirmwareConfigurationResponse, error) { + var reqBody, resBody BackupFirmwareConfigurationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type BindVnicBody struct { + Req *types.BindVnic `xml:"urn:vim25 BindVnic,omitempty"` + Res *types.BindVnicResponse `xml:"urn:vim25 BindVnicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *BindVnicBody) Fault() *soap.Fault { return b.Fault_ } + +func BindVnic(ctx context.Context, r soap.RoundTripper, req *types.BindVnic) (*types.BindVnicResponse, error) { + var reqBody, resBody BindVnicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type BrowseDiagnosticLogBody struct { + Req *types.BrowseDiagnosticLog `xml:"urn:vim25 BrowseDiagnosticLog,omitempty"` + Res *types.BrowseDiagnosticLogResponse `xml:"urn:vim25 BrowseDiagnosticLogResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *BrowseDiagnosticLogBody) Fault() *soap.Fault { return b.Fault_ } + +func BrowseDiagnosticLog(ctx context.Context, r soap.RoundTripper, req *types.BrowseDiagnosticLog) (*types.BrowseDiagnosticLogResponse, error) { + var reqBody, resBody BrowseDiagnosticLogBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CanProvisionObjectsBody struct { + Req *types.CanProvisionObjects `xml:"urn:vim25 CanProvisionObjects,omitempty"` + Res *types.CanProvisionObjectsResponse `xml:"urn:vim25 CanProvisionObjectsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CanProvisionObjectsBody) Fault() *soap.Fault { return b.Fault_ } + +func CanProvisionObjects(ctx context.Context, r soap.RoundTripper, req *types.CanProvisionObjects) (*types.CanProvisionObjectsResponse, error) { + var reqBody, resBody CanProvisionObjectsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CancelRecommendationBody struct { + Req *types.CancelRecommendation `xml:"urn:vim25 CancelRecommendation,omitempty"` + Res *types.CancelRecommendationResponse `xml:"urn:vim25 CancelRecommendationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CancelRecommendationBody) Fault() *soap.Fault { return b.Fault_ } + +func CancelRecommendation(ctx context.Context, r soap.RoundTripper, req *types.CancelRecommendation) (*types.CancelRecommendationResponse, error) { + var reqBody, resBody CancelRecommendationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CancelRetrievePropertiesExBody struct { + Req *types.CancelRetrievePropertiesEx `xml:"urn:vim25 CancelRetrievePropertiesEx,omitempty"` + Res *types.CancelRetrievePropertiesExResponse `xml:"urn:vim25 CancelRetrievePropertiesExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CancelRetrievePropertiesExBody) Fault() *soap.Fault { return b.Fault_ } + +func CancelRetrievePropertiesEx(ctx context.Context, r soap.RoundTripper, req *types.CancelRetrievePropertiesEx) (*types.CancelRetrievePropertiesExResponse, error) { + var reqBody, resBody CancelRetrievePropertiesExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CancelStorageDrsRecommendationBody struct { + Req *types.CancelStorageDrsRecommendation `xml:"urn:vim25 CancelStorageDrsRecommendation,omitempty"` + Res *types.CancelStorageDrsRecommendationResponse `xml:"urn:vim25 CancelStorageDrsRecommendationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CancelStorageDrsRecommendationBody) Fault() *soap.Fault { return b.Fault_ } + +func CancelStorageDrsRecommendation(ctx context.Context, r soap.RoundTripper, req *types.CancelStorageDrsRecommendation) (*types.CancelStorageDrsRecommendationResponse, error) { + var reqBody, resBody CancelStorageDrsRecommendationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CancelTaskBody struct { + Req *types.CancelTask `xml:"urn:vim25 CancelTask,omitempty"` + Res *types.CancelTaskResponse `xml:"urn:vim25 CancelTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CancelTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CancelTask(ctx context.Context, r soap.RoundTripper, req *types.CancelTask) (*types.CancelTaskResponse, error) { + var reqBody, resBody CancelTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CancelWaitForUpdatesBody struct { + Req *types.CancelWaitForUpdates `xml:"urn:vim25 CancelWaitForUpdates,omitempty"` + Res *types.CancelWaitForUpdatesResponse `xml:"urn:vim25 CancelWaitForUpdatesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CancelWaitForUpdatesBody) Fault() *soap.Fault { return b.Fault_ } + +func CancelWaitForUpdates(ctx context.Context, r soap.RoundTripper, req *types.CancelWaitForUpdates) (*types.CancelWaitForUpdatesResponse, error) { + var reqBody, resBody CancelWaitForUpdatesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CertMgrRefreshCACertificatesAndCRLs_TaskBody struct { + Req *types.CertMgrRefreshCACertificatesAndCRLs_Task `xml:"urn:vim25 CertMgrRefreshCACertificatesAndCRLs_Task,omitempty"` + Res *types.CertMgrRefreshCACertificatesAndCRLs_TaskResponse `xml:"urn:vim25 CertMgrRefreshCACertificatesAndCRLs_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CertMgrRefreshCACertificatesAndCRLs_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CertMgrRefreshCACertificatesAndCRLs_Task(ctx context.Context, r soap.RoundTripper, req *types.CertMgrRefreshCACertificatesAndCRLs_Task) (*types.CertMgrRefreshCACertificatesAndCRLs_TaskResponse, error) { + var reqBody, resBody CertMgrRefreshCACertificatesAndCRLs_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CertMgrRefreshCertificates_TaskBody struct { + Req *types.CertMgrRefreshCertificates_Task `xml:"urn:vim25 CertMgrRefreshCertificates_Task,omitempty"` + Res *types.CertMgrRefreshCertificates_TaskResponse `xml:"urn:vim25 CertMgrRefreshCertificates_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CertMgrRefreshCertificates_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CertMgrRefreshCertificates_Task(ctx context.Context, r soap.RoundTripper, req *types.CertMgrRefreshCertificates_Task) (*types.CertMgrRefreshCertificates_TaskResponse, error) { + var reqBody, resBody CertMgrRefreshCertificates_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CertMgrRevokeCertificates_TaskBody struct { + Req *types.CertMgrRevokeCertificates_Task `xml:"urn:vim25 CertMgrRevokeCertificates_Task,omitempty"` + Res *types.CertMgrRevokeCertificates_TaskResponse `xml:"urn:vim25 CertMgrRevokeCertificates_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CertMgrRevokeCertificates_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CertMgrRevokeCertificates_Task(ctx context.Context, r soap.RoundTripper, req *types.CertMgrRevokeCertificates_Task) (*types.CertMgrRevokeCertificates_TaskResponse, error) { + var reqBody, resBody CertMgrRevokeCertificates_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ChangeAccessModeBody struct { + Req *types.ChangeAccessMode `xml:"urn:vim25 ChangeAccessMode,omitempty"` + Res *types.ChangeAccessModeResponse `xml:"urn:vim25 ChangeAccessModeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ChangeAccessModeBody) Fault() *soap.Fault { return b.Fault_ } + +func ChangeAccessMode(ctx context.Context, r soap.RoundTripper, req *types.ChangeAccessMode) (*types.ChangeAccessModeResponse, error) { + var reqBody, resBody ChangeAccessModeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ChangeFileAttributesInGuestBody struct { + Req *types.ChangeFileAttributesInGuest `xml:"urn:vim25 ChangeFileAttributesInGuest,omitempty"` + Res *types.ChangeFileAttributesInGuestResponse `xml:"urn:vim25 ChangeFileAttributesInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ChangeFileAttributesInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ChangeFileAttributesInGuest(ctx context.Context, r soap.RoundTripper, req *types.ChangeFileAttributesInGuest) (*types.ChangeFileAttributesInGuestResponse, error) { + var reqBody, resBody ChangeFileAttributesInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ChangeLockdownModeBody struct { + Req *types.ChangeLockdownMode `xml:"urn:vim25 ChangeLockdownMode,omitempty"` + Res *types.ChangeLockdownModeResponse `xml:"urn:vim25 ChangeLockdownModeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ChangeLockdownModeBody) Fault() *soap.Fault { return b.Fault_ } + +func ChangeLockdownMode(ctx context.Context, r soap.RoundTripper, req *types.ChangeLockdownMode) (*types.ChangeLockdownModeResponse, error) { + var reqBody, resBody ChangeLockdownModeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ChangeNFSUserPasswordBody struct { + Req *types.ChangeNFSUserPassword `xml:"urn:vim25 ChangeNFSUserPassword,omitempty"` + Res *types.ChangeNFSUserPasswordResponse `xml:"urn:vim25 ChangeNFSUserPasswordResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ChangeNFSUserPasswordBody) Fault() *soap.Fault { return b.Fault_ } + +func ChangeNFSUserPassword(ctx context.Context, r soap.RoundTripper, req *types.ChangeNFSUserPassword) (*types.ChangeNFSUserPasswordResponse, error) { + var reqBody, resBody ChangeNFSUserPasswordBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ChangeOwnerBody struct { + Req *types.ChangeOwner `xml:"urn:vim25 ChangeOwner,omitempty"` + Res *types.ChangeOwnerResponse `xml:"urn:vim25 ChangeOwnerResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ChangeOwnerBody) Fault() *soap.Fault { return b.Fault_ } + +func ChangeOwner(ctx context.Context, r soap.RoundTripper, req *types.ChangeOwner) (*types.ChangeOwnerResponse, error) { + var reqBody, resBody ChangeOwnerBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckAddHostEvc_TaskBody struct { + Req *types.CheckAddHostEvc_Task `xml:"urn:vim25 CheckAddHostEvc_Task,omitempty"` + Res *types.CheckAddHostEvc_TaskResponse `xml:"urn:vim25 CheckAddHostEvc_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckAddHostEvc_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckAddHostEvc_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckAddHostEvc_Task) (*types.CheckAddHostEvc_TaskResponse, error) { + var reqBody, resBody CheckAddHostEvc_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckAnswerFileStatus_TaskBody struct { + Req *types.CheckAnswerFileStatus_Task `xml:"urn:vim25 CheckAnswerFileStatus_Task,omitempty"` + Res *types.CheckAnswerFileStatus_TaskResponse `xml:"urn:vim25 CheckAnswerFileStatus_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckAnswerFileStatus_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckAnswerFileStatus_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckAnswerFileStatus_Task) (*types.CheckAnswerFileStatus_TaskResponse, error) { + var reqBody, resBody CheckAnswerFileStatus_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckCompatibility_TaskBody struct { + Req *types.CheckCompatibility_Task `xml:"urn:vim25 CheckCompatibility_Task,omitempty"` + Res *types.CheckCompatibility_TaskResponse `xml:"urn:vim25 CheckCompatibility_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckCompatibility_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckCompatibility_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckCompatibility_Task) (*types.CheckCompatibility_TaskResponse, error) { + var reqBody, resBody CheckCompatibility_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckCompliance_TaskBody struct { + Req *types.CheckCompliance_Task `xml:"urn:vim25 CheckCompliance_Task,omitempty"` + Res *types.CheckCompliance_TaskResponse `xml:"urn:vim25 CheckCompliance_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckCompliance_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckCompliance_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckCompliance_Task) (*types.CheckCompliance_TaskResponse, error) { + var reqBody, resBody CheckCompliance_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckConfigureEvcMode_TaskBody struct { + Req *types.CheckConfigureEvcMode_Task `xml:"urn:vim25 CheckConfigureEvcMode_Task,omitempty"` + Res *types.CheckConfigureEvcMode_TaskResponse `xml:"urn:vim25 CheckConfigureEvcMode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckConfigureEvcMode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckConfigureEvcMode_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckConfigureEvcMode_Task) (*types.CheckConfigureEvcMode_TaskResponse, error) { + var reqBody, resBody CheckConfigureEvcMode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckCustomizationResourcesBody struct { + Req *types.CheckCustomizationResources `xml:"urn:vim25 CheckCustomizationResources,omitempty"` + Res *types.CheckCustomizationResourcesResponse `xml:"urn:vim25 CheckCustomizationResourcesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckCustomizationResourcesBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckCustomizationResources(ctx context.Context, r soap.RoundTripper, req *types.CheckCustomizationResources) (*types.CheckCustomizationResourcesResponse, error) { + var reqBody, resBody CheckCustomizationResourcesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckCustomizationSpecBody struct { + Req *types.CheckCustomizationSpec `xml:"urn:vim25 CheckCustomizationSpec,omitempty"` + Res *types.CheckCustomizationSpecResponse `xml:"urn:vim25 CheckCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.CheckCustomizationSpec) (*types.CheckCustomizationSpecResponse, error) { + var reqBody, resBody CheckCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckForUpdatesBody struct { + Req *types.CheckForUpdates `xml:"urn:vim25 CheckForUpdates,omitempty"` + Res *types.CheckForUpdatesResponse `xml:"urn:vim25 CheckForUpdatesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckForUpdatesBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckForUpdates(ctx context.Context, r soap.RoundTripper, req *types.CheckForUpdates) (*types.CheckForUpdatesResponse, error) { + var reqBody, resBody CheckForUpdatesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckHostPatch_TaskBody struct { + Req *types.CheckHostPatch_Task `xml:"urn:vim25 CheckHostPatch_Task,omitempty"` + Res *types.CheckHostPatch_TaskResponse `xml:"urn:vim25 CheckHostPatch_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckHostPatch_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckHostPatch_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckHostPatch_Task) (*types.CheckHostPatch_TaskResponse, error) { + var reqBody, resBody CheckHostPatch_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckLicenseFeatureBody struct { + Req *types.CheckLicenseFeature `xml:"urn:vim25 CheckLicenseFeature,omitempty"` + Res *types.CheckLicenseFeatureResponse `xml:"urn:vim25 CheckLicenseFeatureResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckLicenseFeatureBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckLicenseFeature(ctx context.Context, r soap.RoundTripper, req *types.CheckLicenseFeature) (*types.CheckLicenseFeatureResponse, error) { + var reqBody, resBody CheckLicenseFeatureBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckMigrate_TaskBody struct { + Req *types.CheckMigrate_Task `xml:"urn:vim25 CheckMigrate_Task,omitempty"` + Res *types.CheckMigrate_TaskResponse `xml:"urn:vim25 CheckMigrate_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckMigrate_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckMigrate_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckMigrate_Task) (*types.CheckMigrate_TaskResponse, error) { + var reqBody, resBody CheckMigrate_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckProfileCompliance_TaskBody struct { + Req *types.CheckProfileCompliance_Task `xml:"urn:vim25 CheckProfileCompliance_Task,omitempty"` + Res *types.CheckProfileCompliance_TaskResponse `xml:"urn:vim25 CheckProfileCompliance_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckProfileCompliance_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckProfileCompliance_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckProfileCompliance_Task) (*types.CheckProfileCompliance_TaskResponse, error) { + var reqBody, resBody CheckProfileCompliance_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CheckRelocate_TaskBody struct { + Req *types.CheckRelocate_Task `xml:"urn:vim25 CheckRelocate_Task,omitempty"` + Res *types.CheckRelocate_TaskResponse `xml:"urn:vim25 CheckRelocate_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CheckRelocate_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CheckRelocate_Task(ctx context.Context, r soap.RoundTripper, req *types.CheckRelocate_Task) (*types.CheckRelocate_TaskResponse, error) { + var reqBody, resBody CheckRelocate_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ClearComplianceStatusBody struct { + Req *types.ClearComplianceStatus `xml:"urn:vim25 ClearComplianceStatus,omitempty"` + Res *types.ClearComplianceStatusResponse `xml:"urn:vim25 ClearComplianceStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ClearComplianceStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func ClearComplianceStatus(ctx context.Context, r soap.RoundTripper, req *types.ClearComplianceStatus) (*types.ClearComplianceStatusResponse, error) { + var reqBody, resBody ClearComplianceStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ClearNFSUserBody struct { + Req *types.ClearNFSUser `xml:"urn:vim25 ClearNFSUser,omitempty"` + Res *types.ClearNFSUserResponse `xml:"urn:vim25 ClearNFSUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ClearNFSUserBody) Fault() *soap.Fault { return b.Fault_ } + +func ClearNFSUser(ctx context.Context, r soap.RoundTripper, req *types.ClearNFSUser) (*types.ClearNFSUserResponse, error) { + var reqBody, resBody ClearNFSUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CloneSessionBody struct { + Req *types.CloneSession `xml:"urn:vim25 CloneSession,omitempty"` + Res *types.CloneSessionResponse `xml:"urn:vim25 CloneSessionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CloneSessionBody) Fault() *soap.Fault { return b.Fault_ } + +func CloneSession(ctx context.Context, r soap.RoundTripper, req *types.CloneSession) (*types.CloneSessionResponse, error) { + var reqBody, resBody CloneSessionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CloneVApp_TaskBody struct { + Req *types.CloneVApp_Task `xml:"urn:vim25 CloneVApp_Task,omitempty"` + Res *types.CloneVApp_TaskResponse `xml:"urn:vim25 CloneVApp_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CloneVApp_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CloneVApp_Task(ctx context.Context, r soap.RoundTripper, req *types.CloneVApp_Task) (*types.CloneVApp_TaskResponse, error) { + var reqBody, resBody CloneVApp_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CloneVM_TaskBody struct { + Req *types.CloneVM_Task `xml:"urn:vim25 CloneVM_Task,omitempty"` + Res *types.CloneVM_TaskResponse `xml:"urn:vim25 CloneVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CloneVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CloneVM_Task(ctx context.Context, r soap.RoundTripper, req *types.CloneVM_Task) (*types.CloneVM_TaskResponse, error) { + var reqBody, resBody CloneVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CloseInventoryViewFolderBody struct { + Req *types.CloseInventoryViewFolder `xml:"urn:vim25 CloseInventoryViewFolder,omitempty"` + Res *types.CloseInventoryViewFolderResponse `xml:"urn:vim25 CloseInventoryViewFolderResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CloseInventoryViewFolderBody) Fault() *soap.Fault { return b.Fault_ } + +func CloseInventoryViewFolder(ctx context.Context, r soap.RoundTripper, req *types.CloseInventoryViewFolder) (*types.CloseInventoryViewFolderResponse, error) { + var reqBody, resBody CloseInventoryViewFolderBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ClusterEnterMaintenanceModeBody struct { + Req *types.ClusterEnterMaintenanceMode `xml:"urn:vim25 ClusterEnterMaintenanceMode,omitempty"` + Res *types.ClusterEnterMaintenanceModeResponse `xml:"urn:vim25 ClusterEnterMaintenanceModeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ClusterEnterMaintenanceModeBody) Fault() *soap.Fault { return b.Fault_ } + +func ClusterEnterMaintenanceMode(ctx context.Context, r soap.RoundTripper, req *types.ClusterEnterMaintenanceMode) (*types.ClusterEnterMaintenanceModeResponse, error) { + var reqBody, resBody ClusterEnterMaintenanceModeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ComputeDiskPartitionInfoBody struct { + Req *types.ComputeDiskPartitionInfo `xml:"urn:vim25 ComputeDiskPartitionInfo,omitempty"` + Res *types.ComputeDiskPartitionInfoResponse `xml:"urn:vim25 ComputeDiskPartitionInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ComputeDiskPartitionInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func ComputeDiskPartitionInfo(ctx context.Context, r soap.RoundTripper, req *types.ComputeDiskPartitionInfo) (*types.ComputeDiskPartitionInfoResponse, error) { + var reqBody, resBody ComputeDiskPartitionInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ComputeDiskPartitionInfoForResizeBody struct { + Req *types.ComputeDiskPartitionInfoForResize `xml:"urn:vim25 ComputeDiskPartitionInfoForResize,omitempty"` + Res *types.ComputeDiskPartitionInfoForResizeResponse `xml:"urn:vim25 ComputeDiskPartitionInfoForResizeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ComputeDiskPartitionInfoForResizeBody) Fault() *soap.Fault { return b.Fault_ } + +func ComputeDiskPartitionInfoForResize(ctx context.Context, r soap.RoundTripper, req *types.ComputeDiskPartitionInfoForResize) (*types.ComputeDiskPartitionInfoForResizeResponse, error) { + var reqBody, resBody ComputeDiskPartitionInfoForResizeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureDatastoreIORM_TaskBody struct { + Req *types.ConfigureDatastoreIORM_Task `xml:"urn:vim25 ConfigureDatastoreIORM_Task,omitempty"` + Res *types.ConfigureDatastoreIORM_TaskResponse `xml:"urn:vim25 ConfigureDatastoreIORM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureDatastoreIORM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureDatastoreIORM_Task(ctx context.Context, r soap.RoundTripper, req *types.ConfigureDatastoreIORM_Task) (*types.ConfigureDatastoreIORM_TaskResponse, error) { + var reqBody, resBody ConfigureDatastoreIORM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureDatastorePrincipalBody struct { + Req *types.ConfigureDatastorePrincipal `xml:"urn:vim25 ConfigureDatastorePrincipal,omitempty"` + Res *types.ConfigureDatastorePrincipalResponse `xml:"urn:vim25 ConfigureDatastorePrincipalResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureDatastorePrincipalBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureDatastorePrincipal(ctx context.Context, r soap.RoundTripper, req *types.ConfigureDatastorePrincipal) (*types.ConfigureDatastorePrincipalResponse, error) { + var reqBody, resBody ConfigureDatastorePrincipalBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureEvcMode_TaskBody struct { + Req *types.ConfigureEvcMode_Task `xml:"urn:vim25 ConfigureEvcMode_Task,omitempty"` + Res *types.ConfigureEvcMode_TaskResponse `xml:"urn:vim25 ConfigureEvcMode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureEvcMode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureEvcMode_Task(ctx context.Context, r soap.RoundTripper, req *types.ConfigureEvcMode_Task) (*types.ConfigureEvcMode_TaskResponse, error) { + var reqBody, resBody ConfigureEvcMode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureHostCache_TaskBody struct { + Req *types.ConfigureHostCache_Task `xml:"urn:vim25 ConfigureHostCache_Task,omitempty"` + Res *types.ConfigureHostCache_TaskResponse `xml:"urn:vim25 ConfigureHostCache_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureHostCache_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureHostCache_Task(ctx context.Context, r soap.RoundTripper, req *types.ConfigureHostCache_Task) (*types.ConfigureHostCache_TaskResponse, error) { + var reqBody, resBody ConfigureHostCache_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureLicenseSourceBody struct { + Req *types.ConfigureLicenseSource `xml:"urn:vim25 ConfigureLicenseSource,omitempty"` + Res *types.ConfigureLicenseSourceResponse `xml:"urn:vim25 ConfigureLicenseSourceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureLicenseSourceBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureLicenseSource(ctx context.Context, r soap.RoundTripper, req *types.ConfigureLicenseSource) (*types.ConfigureLicenseSourceResponse, error) { + var reqBody, resBody ConfigureLicenseSourceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigurePowerPolicyBody struct { + Req *types.ConfigurePowerPolicy `xml:"urn:vim25 ConfigurePowerPolicy,omitempty"` + Res *types.ConfigurePowerPolicyResponse `xml:"urn:vim25 ConfigurePowerPolicyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigurePowerPolicyBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigurePowerPolicy(ctx context.Context, r soap.RoundTripper, req *types.ConfigurePowerPolicy) (*types.ConfigurePowerPolicyResponse, error) { + var reqBody, resBody ConfigurePowerPolicyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureStorageDrsForPod_TaskBody struct { + Req *types.ConfigureStorageDrsForPod_Task `xml:"urn:vim25 ConfigureStorageDrsForPod_Task,omitempty"` + Res *types.ConfigureStorageDrsForPod_TaskResponse `xml:"urn:vim25 ConfigureStorageDrsForPod_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureStorageDrsForPod_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureStorageDrsForPod_Task(ctx context.Context, r soap.RoundTripper, req *types.ConfigureStorageDrsForPod_Task) (*types.ConfigureStorageDrsForPod_TaskResponse, error) { + var reqBody, resBody ConfigureStorageDrsForPod_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConfigureVFlashResourceEx_TaskBody struct { + Req *types.ConfigureVFlashResourceEx_Task `xml:"urn:vim25 ConfigureVFlashResourceEx_Task,omitempty"` + Res *types.ConfigureVFlashResourceEx_TaskResponse `xml:"urn:vim25 ConfigureVFlashResourceEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConfigureVFlashResourceEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ConfigureVFlashResourceEx_Task(ctx context.Context, r soap.RoundTripper, req *types.ConfigureVFlashResourceEx_Task) (*types.ConfigureVFlashResourceEx_TaskResponse, error) { + var reqBody, resBody ConfigureVFlashResourceEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ConsolidateVMDisks_TaskBody struct { + Req *types.ConsolidateVMDisks_Task `xml:"urn:vim25 ConsolidateVMDisks_Task,omitempty"` + Res *types.ConsolidateVMDisks_TaskResponse `xml:"urn:vim25 ConsolidateVMDisks_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ConsolidateVMDisks_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ConsolidateVMDisks_Task(ctx context.Context, r soap.RoundTripper, req *types.ConsolidateVMDisks_Task) (*types.ConsolidateVMDisks_TaskResponse, error) { + var reqBody, resBody ConsolidateVMDisks_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ContinueRetrievePropertiesExBody struct { + Req *types.ContinueRetrievePropertiesEx `xml:"urn:vim25 ContinueRetrievePropertiesEx,omitempty"` + Res *types.ContinueRetrievePropertiesExResponse `xml:"urn:vim25 ContinueRetrievePropertiesExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ContinueRetrievePropertiesExBody) Fault() *soap.Fault { return b.Fault_ } + +func ContinueRetrievePropertiesEx(ctx context.Context, r soap.RoundTripper, req *types.ContinueRetrievePropertiesEx) (*types.ContinueRetrievePropertiesExResponse, error) { + var reqBody, resBody ContinueRetrievePropertiesExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CopyDatastoreFile_TaskBody struct { + Req *types.CopyDatastoreFile_Task `xml:"urn:vim25 CopyDatastoreFile_Task,omitempty"` + Res *types.CopyDatastoreFile_TaskResponse `xml:"urn:vim25 CopyDatastoreFile_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CopyDatastoreFile_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CopyDatastoreFile_Task(ctx context.Context, r soap.RoundTripper, req *types.CopyDatastoreFile_Task) (*types.CopyDatastoreFile_TaskResponse, error) { + var reqBody, resBody CopyDatastoreFile_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CopyVirtualDisk_TaskBody struct { + Req *types.CopyVirtualDisk_Task `xml:"urn:vim25 CopyVirtualDisk_Task,omitempty"` + Res *types.CopyVirtualDisk_TaskResponse `xml:"urn:vim25 CopyVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CopyVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CopyVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.CopyVirtualDisk_Task) (*types.CopyVirtualDisk_TaskResponse, error) { + var reqBody, resBody CopyVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateAlarmBody struct { + Req *types.CreateAlarm `xml:"urn:vim25 CreateAlarm,omitempty"` + Res *types.CreateAlarmResponse `xml:"urn:vim25 CreateAlarmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateAlarmBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateAlarm(ctx context.Context, r soap.RoundTripper, req *types.CreateAlarm) (*types.CreateAlarmResponse, error) { + var reqBody, resBody CreateAlarmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateChildVM_TaskBody struct { + Req *types.CreateChildVM_Task `xml:"urn:vim25 CreateChildVM_Task,omitempty"` + Res *types.CreateChildVM_TaskResponse `xml:"urn:vim25 CreateChildVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateChildVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateChildVM_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateChildVM_Task) (*types.CreateChildVM_TaskResponse, error) { + var reqBody, resBody CreateChildVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateClusterBody struct { + Req *types.CreateCluster `xml:"urn:vim25 CreateCluster,omitempty"` + Res *types.CreateClusterResponse `xml:"urn:vim25 CreateClusterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateClusterBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateCluster(ctx context.Context, r soap.RoundTripper, req *types.CreateCluster) (*types.CreateClusterResponse, error) { + var reqBody, resBody CreateClusterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateClusterExBody struct { + Req *types.CreateClusterEx `xml:"urn:vim25 CreateClusterEx,omitempty"` + Res *types.CreateClusterExResponse `xml:"urn:vim25 CreateClusterExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateClusterExBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateClusterEx(ctx context.Context, r soap.RoundTripper, req *types.CreateClusterEx) (*types.CreateClusterExResponse, error) { + var reqBody, resBody CreateClusterExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateCollectorForEventsBody struct { + Req *types.CreateCollectorForEvents `xml:"urn:vim25 CreateCollectorForEvents,omitempty"` + Res *types.CreateCollectorForEventsResponse `xml:"urn:vim25 CreateCollectorForEventsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateCollectorForEventsBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateCollectorForEvents(ctx context.Context, r soap.RoundTripper, req *types.CreateCollectorForEvents) (*types.CreateCollectorForEventsResponse, error) { + var reqBody, resBody CreateCollectorForEventsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateCollectorForTasksBody struct { + Req *types.CreateCollectorForTasks `xml:"urn:vim25 CreateCollectorForTasks,omitempty"` + Res *types.CreateCollectorForTasksResponse `xml:"urn:vim25 CreateCollectorForTasksResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateCollectorForTasksBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateCollectorForTasks(ctx context.Context, r soap.RoundTripper, req *types.CreateCollectorForTasks) (*types.CreateCollectorForTasksResponse, error) { + var reqBody, resBody CreateCollectorForTasksBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateContainerViewBody struct { + Req *types.CreateContainerView `xml:"urn:vim25 CreateContainerView,omitempty"` + Res *types.CreateContainerViewResponse `xml:"urn:vim25 CreateContainerViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateContainerViewBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateContainerView(ctx context.Context, r soap.RoundTripper, req *types.CreateContainerView) (*types.CreateContainerViewResponse, error) { + var reqBody, resBody CreateContainerViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateCustomizationSpecBody struct { + Req *types.CreateCustomizationSpec `xml:"urn:vim25 CreateCustomizationSpec,omitempty"` + Res *types.CreateCustomizationSpecResponse `xml:"urn:vim25 CreateCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.CreateCustomizationSpec) (*types.CreateCustomizationSpecResponse, error) { + var reqBody, resBody CreateCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDVPortgroup_TaskBody struct { + Req *types.CreateDVPortgroup_Task `xml:"urn:vim25 CreateDVPortgroup_Task,omitempty"` + Res *types.CreateDVPortgroup_TaskResponse `xml:"urn:vim25 CreateDVPortgroup_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDVPortgroup_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDVPortgroup_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateDVPortgroup_Task) (*types.CreateDVPortgroup_TaskResponse, error) { + var reqBody, resBody CreateDVPortgroup_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDVS_TaskBody struct { + Req *types.CreateDVS_Task `xml:"urn:vim25 CreateDVS_Task,omitempty"` + Res *types.CreateDVS_TaskResponse `xml:"urn:vim25 CreateDVS_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDVS_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDVS_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateDVS_Task) (*types.CreateDVS_TaskResponse, error) { + var reqBody, resBody CreateDVS_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDatacenterBody struct { + Req *types.CreateDatacenter `xml:"urn:vim25 CreateDatacenter,omitempty"` + Res *types.CreateDatacenterResponse `xml:"urn:vim25 CreateDatacenterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDatacenterBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDatacenter(ctx context.Context, r soap.RoundTripper, req *types.CreateDatacenter) (*types.CreateDatacenterResponse, error) { + var reqBody, resBody CreateDatacenterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDefaultProfileBody struct { + Req *types.CreateDefaultProfile `xml:"urn:vim25 CreateDefaultProfile,omitempty"` + Res *types.CreateDefaultProfileResponse `xml:"urn:vim25 CreateDefaultProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDefaultProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDefaultProfile(ctx context.Context, r soap.RoundTripper, req *types.CreateDefaultProfile) (*types.CreateDefaultProfileResponse, error) { + var reqBody, resBody CreateDefaultProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDescriptorBody struct { + Req *types.CreateDescriptor `xml:"urn:vim25 CreateDescriptor,omitempty"` + Res *types.CreateDescriptorResponse `xml:"urn:vim25 CreateDescriptorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDescriptorBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDescriptor(ctx context.Context, r soap.RoundTripper, req *types.CreateDescriptor) (*types.CreateDescriptorResponse, error) { + var reqBody, resBody CreateDescriptorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDiagnosticPartitionBody struct { + Req *types.CreateDiagnosticPartition `xml:"urn:vim25 CreateDiagnosticPartition,omitempty"` + Res *types.CreateDiagnosticPartitionResponse `xml:"urn:vim25 CreateDiagnosticPartitionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDiagnosticPartitionBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDiagnosticPartition(ctx context.Context, r soap.RoundTripper, req *types.CreateDiagnosticPartition) (*types.CreateDiagnosticPartitionResponse, error) { + var reqBody, resBody CreateDiagnosticPartitionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateDirectoryBody struct { + Req *types.CreateDirectory `xml:"urn:vim25 CreateDirectory,omitempty"` + Res *types.CreateDirectoryResponse `xml:"urn:vim25 CreateDirectoryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateDirectoryBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateDirectory(ctx context.Context, r soap.RoundTripper, req *types.CreateDirectory) (*types.CreateDirectoryResponse, error) { + var reqBody, resBody CreateDirectoryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateFilterBody struct { + Req *types.CreateFilter `xml:"urn:vim25 CreateFilter,omitempty"` + Res *types.CreateFilterResponse `xml:"urn:vim25 CreateFilterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateFilterBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateFilter(ctx context.Context, r soap.RoundTripper, req *types.CreateFilter) (*types.CreateFilterResponse, error) { + var reqBody, resBody CreateFilterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateFolderBody struct { + Req *types.CreateFolder `xml:"urn:vim25 CreateFolder,omitempty"` + Res *types.CreateFolderResponse `xml:"urn:vim25 CreateFolderResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateFolderBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateFolder(ctx context.Context, r soap.RoundTripper, req *types.CreateFolder) (*types.CreateFolderResponse, error) { + var reqBody, resBody CreateFolderBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateGroupBody struct { + Req *types.CreateGroup `xml:"urn:vim25 CreateGroup,omitempty"` + Res *types.CreateGroupResponse `xml:"urn:vim25 CreateGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateGroup(ctx context.Context, r soap.RoundTripper, req *types.CreateGroup) (*types.CreateGroupResponse, error) { + var reqBody, resBody CreateGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateImportSpecBody struct { + Req *types.CreateImportSpec `xml:"urn:vim25 CreateImportSpec,omitempty"` + Res *types.CreateImportSpecResponse `xml:"urn:vim25 CreateImportSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateImportSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateImportSpec(ctx context.Context, r soap.RoundTripper, req *types.CreateImportSpec) (*types.CreateImportSpecResponse, error) { + var reqBody, resBody CreateImportSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateInventoryViewBody struct { + Req *types.CreateInventoryView `xml:"urn:vim25 CreateInventoryView,omitempty"` + Res *types.CreateInventoryViewResponse `xml:"urn:vim25 CreateInventoryViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateInventoryViewBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateInventoryView(ctx context.Context, r soap.RoundTripper, req *types.CreateInventoryView) (*types.CreateInventoryViewResponse, error) { + var reqBody, resBody CreateInventoryViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateIpPoolBody struct { + Req *types.CreateIpPool `xml:"urn:vim25 CreateIpPool,omitempty"` + Res *types.CreateIpPoolResponse `xml:"urn:vim25 CreateIpPoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateIpPoolBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateIpPool(ctx context.Context, r soap.RoundTripper, req *types.CreateIpPool) (*types.CreateIpPoolResponse, error) { + var reqBody, resBody CreateIpPoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateListViewBody struct { + Req *types.CreateListView `xml:"urn:vim25 CreateListView,omitempty"` + Res *types.CreateListViewResponse `xml:"urn:vim25 CreateListViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateListViewBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateListView(ctx context.Context, r soap.RoundTripper, req *types.CreateListView) (*types.CreateListViewResponse, error) { + var reqBody, resBody CreateListViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateListViewFromViewBody struct { + Req *types.CreateListViewFromView `xml:"urn:vim25 CreateListViewFromView,omitempty"` + Res *types.CreateListViewFromViewResponse `xml:"urn:vim25 CreateListViewFromViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateListViewFromViewBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateListViewFromView(ctx context.Context, r soap.RoundTripper, req *types.CreateListViewFromView) (*types.CreateListViewFromViewResponse, error) { + var reqBody, resBody CreateListViewFromViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateLocalDatastoreBody struct { + Req *types.CreateLocalDatastore `xml:"urn:vim25 CreateLocalDatastore,omitempty"` + Res *types.CreateLocalDatastoreResponse `xml:"urn:vim25 CreateLocalDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateLocalDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateLocalDatastore(ctx context.Context, r soap.RoundTripper, req *types.CreateLocalDatastore) (*types.CreateLocalDatastoreResponse, error) { + var reqBody, resBody CreateLocalDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateNasDatastoreBody struct { + Req *types.CreateNasDatastore `xml:"urn:vim25 CreateNasDatastore,omitempty"` + Res *types.CreateNasDatastoreResponse `xml:"urn:vim25 CreateNasDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateNasDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateNasDatastore(ctx context.Context, r soap.RoundTripper, req *types.CreateNasDatastore) (*types.CreateNasDatastoreResponse, error) { + var reqBody, resBody CreateNasDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateObjectScheduledTaskBody struct { + Req *types.CreateObjectScheduledTask `xml:"urn:vim25 CreateObjectScheduledTask,omitempty"` + Res *types.CreateObjectScheduledTaskResponse `xml:"urn:vim25 CreateObjectScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateObjectScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateObjectScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.CreateObjectScheduledTask) (*types.CreateObjectScheduledTaskResponse, error) { + var reqBody, resBody CreateObjectScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreatePerfIntervalBody struct { + Req *types.CreatePerfInterval `xml:"urn:vim25 CreatePerfInterval,omitempty"` + Res *types.CreatePerfIntervalResponse `xml:"urn:vim25 CreatePerfIntervalResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreatePerfIntervalBody) Fault() *soap.Fault { return b.Fault_ } + +func CreatePerfInterval(ctx context.Context, r soap.RoundTripper, req *types.CreatePerfInterval) (*types.CreatePerfIntervalResponse, error) { + var reqBody, resBody CreatePerfIntervalBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateProfileBody struct { + Req *types.CreateProfile `xml:"urn:vim25 CreateProfile,omitempty"` + Res *types.CreateProfileResponse `xml:"urn:vim25 CreateProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateProfile(ctx context.Context, r soap.RoundTripper, req *types.CreateProfile) (*types.CreateProfileResponse, error) { + var reqBody, resBody CreateProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreatePropertyCollectorBody struct { + Req *types.CreatePropertyCollector `xml:"urn:vim25 CreatePropertyCollector,omitempty"` + Res *types.CreatePropertyCollectorResponse `xml:"urn:vim25 CreatePropertyCollectorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreatePropertyCollectorBody) Fault() *soap.Fault { return b.Fault_ } + +func CreatePropertyCollector(ctx context.Context, r soap.RoundTripper, req *types.CreatePropertyCollector) (*types.CreatePropertyCollectorResponse, error) { + var reqBody, resBody CreatePropertyCollectorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateRegistryKeyInGuestBody struct { + Req *types.CreateRegistryKeyInGuest `xml:"urn:vim25 CreateRegistryKeyInGuest,omitempty"` + Res *types.CreateRegistryKeyInGuestResponse `xml:"urn:vim25 CreateRegistryKeyInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateRegistryKeyInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateRegistryKeyInGuest(ctx context.Context, r soap.RoundTripper, req *types.CreateRegistryKeyInGuest) (*types.CreateRegistryKeyInGuestResponse, error) { + var reqBody, resBody CreateRegistryKeyInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateResourcePoolBody struct { + Req *types.CreateResourcePool `xml:"urn:vim25 CreateResourcePool,omitempty"` + Res *types.CreateResourcePoolResponse `xml:"urn:vim25 CreateResourcePoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateResourcePoolBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateResourcePool(ctx context.Context, r soap.RoundTripper, req *types.CreateResourcePool) (*types.CreateResourcePoolResponse, error) { + var reqBody, resBody CreateResourcePoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateScheduledTaskBody struct { + Req *types.CreateScheduledTask `xml:"urn:vim25 CreateScheduledTask,omitempty"` + Res *types.CreateScheduledTaskResponse `xml:"urn:vim25 CreateScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.CreateScheduledTask) (*types.CreateScheduledTaskResponse, error) { + var reqBody, resBody CreateScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateScreenshot_TaskBody struct { + Req *types.CreateScreenshot_Task `xml:"urn:vim25 CreateScreenshot_Task,omitempty"` + Res *types.CreateScreenshot_TaskResponse `xml:"urn:vim25 CreateScreenshot_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateScreenshot_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateScreenshot_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateScreenshot_Task) (*types.CreateScreenshot_TaskResponse, error) { + var reqBody, resBody CreateScreenshot_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateSecondaryVMEx_TaskBody struct { + Req *types.CreateSecondaryVMEx_Task `xml:"urn:vim25 CreateSecondaryVMEx_Task,omitempty"` + Res *types.CreateSecondaryVMEx_TaskResponse `xml:"urn:vim25 CreateSecondaryVMEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateSecondaryVMEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateSecondaryVMEx_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateSecondaryVMEx_Task) (*types.CreateSecondaryVMEx_TaskResponse, error) { + var reqBody, resBody CreateSecondaryVMEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateSecondaryVM_TaskBody struct { + Req *types.CreateSecondaryVM_Task `xml:"urn:vim25 CreateSecondaryVM_Task,omitempty"` + Res *types.CreateSecondaryVM_TaskResponse `xml:"urn:vim25 CreateSecondaryVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateSecondaryVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateSecondaryVM_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateSecondaryVM_Task) (*types.CreateSecondaryVM_TaskResponse, error) { + var reqBody, resBody CreateSecondaryVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateSnapshot_TaskBody struct { + Req *types.CreateSnapshot_Task `xml:"urn:vim25 CreateSnapshot_Task,omitempty"` + Res *types.CreateSnapshot_TaskResponse `xml:"urn:vim25 CreateSnapshot_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateSnapshot_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateSnapshot_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateSnapshot_Task) (*types.CreateSnapshot_TaskResponse, error) { + var reqBody, resBody CreateSnapshot_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateStoragePodBody struct { + Req *types.CreateStoragePod `xml:"urn:vim25 CreateStoragePod,omitempty"` + Res *types.CreateStoragePodResponse `xml:"urn:vim25 CreateStoragePodResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateStoragePodBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateStoragePod(ctx context.Context, r soap.RoundTripper, req *types.CreateStoragePod) (*types.CreateStoragePodResponse, error) { + var reqBody, resBody CreateStoragePodBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateTaskBody struct { + Req *types.CreateTask `xml:"urn:vim25 CreateTask,omitempty"` + Res *types.CreateTaskResponse `xml:"urn:vim25 CreateTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateTask(ctx context.Context, r soap.RoundTripper, req *types.CreateTask) (*types.CreateTaskResponse, error) { + var reqBody, resBody CreateTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateTemporaryDirectoryInGuestBody struct { + Req *types.CreateTemporaryDirectoryInGuest `xml:"urn:vim25 CreateTemporaryDirectoryInGuest,omitempty"` + Res *types.CreateTemporaryDirectoryInGuestResponse `xml:"urn:vim25 CreateTemporaryDirectoryInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateTemporaryDirectoryInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateTemporaryDirectoryInGuest(ctx context.Context, r soap.RoundTripper, req *types.CreateTemporaryDirectoryInGuest) (*types.CreateTemporaryDirectoryInGuestResponse, error) { + var reqBody, resBody CreateTemporaryDirectoryInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateTemporaryFileInGuestBody struct { + Req *types.CreateTemporaryFileInGuest `xml:"urn:vim25 CreateTemporaryFileInGuest,omitempty"` + Res *types.CreateTemporaryFileInGuestResponse `xml:"urn:vim25 CreateTemporaryFileInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateTemporaryFileInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateTemporaryFileInGuest(ctx context.Context, r soap.RoundTripper, req *types.CreateTemporaryFileInGuest) (*types.CreateTemporaryFileInGuestResponse, error) { + var reqBody, resBody CreateTemporaryFileInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateUserBody struct { + Req *types.CreateUser `xml:"urn:vim25 CreateUser,omitempty"` + Res *types.CreateUserResponse `xml:"urn:vim25 CreateUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateUserBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateUser(ctx context.Context, r soap.RoundTripper, req *types.CreateUser) (*types.CreateUserResponse, error) { + var reqBody, resBody CreateUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateVAppBody struct { + Req *types.CreateVApp `xml:"urn:vim25 CreateVApp,omitempty"` + Res *types.CreateVAppResponse `xml:"urn:vim25 CreateVAppResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateVAppBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateVApp(ctx context.Context, r soap.RoundTripper, req *types.CreateVApp) (*types.CreateVAppResponse, error) { + var reqBody, resBody CreateVAppBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateVM_TaskBody struct { + Req *types.CreateVM_Task `xml:"urn:vim25 CreateVM_Task,omitempty"` + Res *types.CreateVM_TaskResponse `xml:"urn:vim25 CreateVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateVM_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateVM_Task) (*types.CreateVM_TaskResponse, error) { + var reqBody, resBody CreateVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateVirtualDisk_TaskBody struct { + Req *types.CreateVirtualDisk_Task `xml:"urn:vim25 CreateVirtualDisk_Task,omitempty"` + Res *types.CreateVirtualDisk_TaskResponse `xml:"urn:vim25 CreateVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.CreateVirtualDisk_Task) (*types.CreateVirtualDisk_TaskResponse, error) { + var reqBody, resBody CreateVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateVmfsDatastoreBody struct { + Req *types.CreateVmfsDatastore `xml:"urn:vim25 CreateVmfsDatastore,omitempty"` + Res *types.CreateVmfsDatastoreResponse `xml:"urn:vim25 CreateVmfsDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateVmfsDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateVmfsDatastore(ctx context.Context, r soap.RoundTripper, req *types.CreateVmfsDatastore) (*types.CreateVmfsDatastoreResponse, error) { + var reqBody, resBody CreateVmfsDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CreateVvolDatastoreBody struct { + Req *types.CreateVvolDatastore `xml:"urn:vim25 CreateVvolDatastore,omitempty"` + Res *types.CreateVvolDatastoreResponse `xml:"urn:vim25 CreateVvolDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CreateVvolDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func CreateVvolDatastore(ctx context.Context, r soap.RoundTripper, req *types.CreateVvolDatastore) (*types.CreateVvolDatastoreResponse, error) { + var reqBody, resBody CreateVvolDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CurrentTimeBody struct { + Req *types.CurrentTime `xml:"urn:vim25 CurrentTime,omitempty"` + Res *types.CurrentTimeResponse `xml:"urn:vim25 CurrentTimeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CurrentTimeBody) Fault() *soap.Fault { return b.Fault_ } + +func CurrentTime(ctx context.Context, r soap.RoundTripper, req *types.CurrentTime) (*types.CurrentTimeResponse, error) { + var reqBody, resBody CurrentTimeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CustomizationSpecItemToXmlBody struct { + Req *types.CustomizationSpecItemToXml `xml:"urn:vim25 CustomizationSpecItemToXml,omitempty"` + Res *types.CustomizationSpecItemToXmlResponse `xml:"urn:vim25 CustomizationSpecItemToXmlResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CustomizationSpecItemToXmlBody) Fault() *soap.Fault { return b.Fault_ } + +func CustomizationSpecItemToXml(ctx context.Context, r soap.RoundTripper, req *types.CustomizationSpecItemToXml) (*types.CustomizationSpecItemToXmlResponse, error) { + var reqBody, resBody CustomizationSpecItemToXmlBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type CustomizeVM_TaskBody struct { + Req *types.CustomizeVM_Task `xml:"urn:vim25 CustomizeVM_Task,omitempty"` + Res *types.CustomizeVM_TaskResponse `xml:"urn:vim25 CustomizeVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *CustomizeVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func CustomizeVM_Task(ctx context.Context, r soap.RoundTripper, req *types.CustomizeVM_Task) (*types.CustomizeVM_TaskResponse, error) { + var reqBody, resBody CustomizeVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DVPortgroupRollback_TaskBody struct { + Req *types.DVPortgroupRollback_Task `xml:"urn:vim25 DVPortgroupRollback_Task,omitempty"` + Res *types.DVPortgroupRollback_TaskResponse `xml:"urn:vim25 DVPortgroupRollback_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DVPortgroupRollback_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DVPortgroupRollback_Task(ctx context.Context, r soap.RoundTripper, req *types.DVPortgroupRollback_Task) (*types.DVPortgroupRollback_TaskResponse, error) { + var reqBody, resBody DVPortgroupRollback_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DVSManagerExportEntity_TaskBody struct { + Req *types.DVSManagerExportEntity_Task `xml:"urn:vim25 DVSManagerExportEntity_Task,omitempty"` + Res *types.DVSManagerExportEntity_TaskResponse `xml:"urn:vim25 DVSManagerExportEntity_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DVSManagerExportEntity_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DVSManagerExportEntity_Task(ctx context.Context, r soap.RoundTripper, req *types.DVSManagerExportEntity_Task) (*types.DVSManagerExportEntity_TaskResponse, error) { + var reqBody, resBody DVSManagerExportEntity_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DVSManagerImportEntity_TaskBody struct { + Req *types.DVSManagerImportEntity_Task `xml:"urn:vim25 DVSManagerImportEntity_Task,omitempty"` + Res *types.DVSManagerImportEntity_TaskResponse `xml:"urn:vim25 DVSManagerImportEntity_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DVSManagerImportEntity_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DVSManagerImportEntity_Task(ctx context.Context, r soap.RoundTripper, req *types.DVSManagerImportEntity_Task) (*types.DVSManagerImportEntity_TaskResponse, error) { + var reqBody, resBody DVSManagerImportEntity_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DVSManagerLookupDvPortGroupBody struct { + Req *types.DVSManagerLookupDvPortGroup `xml:"urn:vim25 DVSManagerLookupDvPortGroup,omitempty"` + Res *types.DVSManagerLookupDvPortGroupResponse `xml:"urn:vim25 DVSManagerLookupDvPortGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DVSManagerLookupDvPortGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func DVSManagerLookupDvPortGroup(ctx context.Context, r soap.RoundTripper, req *types.DVSManagerLookupDvPortGroup) (*types.DVSManagerLookupDvPortGroupResponse, error) { + var reqBody, resBody DVSManagerLookupDvPortGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DVSRollback_TaskBody struct { + Req *types.DVSRollback_Task `xml:"urn:vim25 DVSRollback_Task,omitempty"` + Res *types.DVSRollback_TaskResponse `xml:"urn:vim25 DVSRollback_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DVSRollback_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DVSRollback_Task(ctx context.Context, r soap.RoundTripper, req *types.DVSRollback_Task) (*types.DVSRollback_TaskResponse, error) { + var reqBody, resBody DVSRollback_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DatastoreEnterMaintenanceModeBody struct { + Req *types.DatastoreEnterMaintenanceMode `xml:"urn:vim25 DatastoreEnterMaintenanceMode,omitempty"` + Res *types.DatastoreEnterMaintenanceModeResponse `xml:"urn:vim25 DatastoreEnterMaintenanceModeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DatastoreEnterMaintenanceModeBody) Fault() *soap.Fault { return b.Fault_ } + +func DatastoreEnterMaintenanceMode(ctx context.Context, r soap.RoundTripper, req *types.DatastoreEnterMaintenanceMode) (*types.DatastoreEnterMaintenanceModeResponse, error) { + var reqBody, resBody DatastoreEnterMaintenanceModeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DatastoreExitMaintenanceMode_TaskBody struct { + Req *types.DatastoreExitMaintenanceMode_Task `xml:"urn:vim25 DatastoreExitMaintenanceMode_Task,omitempty"` + Res *types.DatastoreExitMaintenanceMode_TaskResponse `xml:"urn:vim25 DatastoreExitMaintenanceMode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DatastoreExitMaintenanceMode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DatastoreExitMaintenanceMode_Task(ctx context.Context, r soap.RoundTripper, req *types.DatastoreExitMaintenanceMode_Task) (*types.DatastoreExitMaintenanceMode_TaskResponse, error) { + var reqBody, resBody DatastoreExitMaintenanceMode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DecodeLicenseBody struct { + Req *types.DecodeLicense `xml:"urn:vim25 DecodeLicense,omitempty"` + Res *types.DecodeLicenseResponse `xml:"urn:vim25 DecodeLicenseResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DecodeLicenseBody) Fault() *soap.Fault { return b.Fault_ } + +func DecodeLicense(ctx context.Context, r soap.RoundTripper, req *types.DecodeLicense) (*types.DecodeLicenseResponse, error) { + var reqBody, resBody DecodeLicenseBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DefragmentAllDisksBody struct { + Req *types.DefragmentAllDisks `xml:"urn:vim25 DefragmentAllDisks,omitempty"` + Res *types.DefragmentAllDisksResponse `xml:"urn:vim25 DefragmentAllDisksResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DefragmentAllDisksBody) Fault() *soap.Fault { return b.Fault_ } + +func DefragmentAllDisks(ctx context.Context, r soap.RoundTripper, req *types.DefragmentAllDisks) (*types.DefragmentAllDisksResponse, error) { + var reqBody, resBody DefragmentAllDisksBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DefragmentVirtualDisk_TaskBody struct { + Req *types.DefragmentVirtualDisk_Task `xml:"urn:vim25 DefragmentVirtualDisk_Task,omitempty"` + Res *types.DefragmentVirtualDisk_TaskResponse `xml:"urn:vim25 DefragmentVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DefragmentVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DefragmentVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.DefragmentVirtualDisk_Task) (*types.DefragmentVirtualDisk_TaskResponse, error) { + var reqBody, resBody DefragmentVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteCustomizationSpecBody struct { + Req *types.DeleteCustomizationSpec `xml:"urn:vim25 DeleteCustomizationSpec,omitempty"` + Res *types.DeleteCustomizationSpecResponse `xml:"urn:vim25 DeleteCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.DeleteCustomizationSpec) (*types.DeleteCustomizationSpecResponse, error) { + var reqBody, resBody DeleteCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteDatastoreFile_TaskBody struct { + Req *types.DeleteDatastoreFile_Task `xml:"urn:vim25 DeleteDatastoreFile_Task,omitempty"` + Res *types.DeleteDatastoreFile_TaskResponse `xml:"urn:vim25 DeleteDatastoreFile_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteDatastoreFile_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteDatastoreFile_Task(ctx context.Context, r soap.RoundTripper, req *types.DeleteDatastoreFile_Task) (*types.DeleteDatastoreFile_TaskResponse, error) { + var reqBody, resBody DeleteDatastoreFile_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteDirectoryBody struct { + Req *types.DeleteDirectory `xml:"urn:vim25 DeleteDirectory,omitempty"` + Res *types.DeleteDirectoryResponse `xml:"urn:vim25 DeleteDirectoryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteDirectoryBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteDirectory(ctx context.Context, r soap.RoundTripper, req *types.DeleteDirectory) (*types.DeleteDirectoryResponse, error) { + var reqBody, resBody DeleteDirectoryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteDirectoryInGuestBody struct { + Req *types.DeleteDirectoryInGuest `xml:"urn:vim25 DeleteDirectoryInGuest,omitempty"` + Res *types.DeleteDirectoryInGuestResponse `xml:"urn:vim25 DeleteDirectoryInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteDirectoryInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteDirectoryInGuest(ctx context.Context, r soap.RoundTripper, req *types.DeleteDirectoryInGuest) (*types.DeleteDirectoryInGuestResponse, error) { + var reqBody, resBody DeleteDirectoryInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteFileBody struct { + Req *types.DeleteFile `xml:"urn:vim25 DeleteFile,omitempty"` + Res *types.DeleteFileResponse `xml:"urn:vim25 DeleteFileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteFileBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteFile(ctx context.Context, r soap.RoundTripper, req *types.DeleteFile) (*types.DeleteFileResponse, error) { + var reqBody, resBody DeleteFileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteFileInGuestBody struct { + Req *types.DeleteFileInGuest `xml:"urn:vim25 DeleteFileInGuest,omitempty"` + Res *types.DeleteFileInGuestResponse `xml:"urn:vim25 DeleteFileInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteFileInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteFileInGuest(ctx context.Context, r soap.RoundTripper, req *types.DeleteFileInGuest) (*types.DeleteFileInGuestResponse, error) { + var reqBody, resBody DeleteFileInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteRegistryKeyInGuestBody struct { + Req *types.DeleteRegistryKeyInGuest `xml:"urn:vim25 DeleteRegistryKeyInGuest,omitempty"` + Res *types.DeleteRegistryKeyInGuestResponse `xml:"urn:vim25 DeleteRegistryKeyInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteRegistryKeyInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteRegistryKeyInGuest(ctx context.Context, r soap.RoundTripper, req *types.DeleteRegistryKeyInGuest) (*types.DeleteRegistryKeyInGuestResponse, error) { + var reqBody, resBody DeleteRegistryKeyInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteRegistryValueInGuestBody struct { + Req *types.DeleteRegistryValueInGuest `xml:"urn:vim25 DeleteRegistryValueInGuest,omitempty"` + Res *types.DeleteRegistryValueInGuestResponse `xml:"urn:vim25 DeleteRegistryValueInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteRegistryValueInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteRegistryValueInGuest(ctx context.Context, r soap.RoundTripper, req *types.DeleteRegistryValueInGuest) (*types.DeleteRegistryValueInGuestResponse, error) { + var reqBody, resBody DeleteRegistryValueInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteScsiLunStateBody struct { + Req *types.DeleteScsiLunState `xml:"urn:vim25 DeleteScsiLunState,omitempty"` + Res *types.DeleteScsiLunStateResponse `xml:"urn:vim25 DeleteScsiLunStateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteScsiLunStateBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteScsiLunState(ctx context.Context, r soap.RoundTripper, req *types.DeleteScsiLunState) (*types.DeleteScsiLunStateResponse, error) { + var reqBody, resBody DeleteScsiLunStateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteVffsVolumeStateBody struct { + Req *types.DeleteVffsVolumeState `xml:"urn:vim25 DeleteVffsVolumeState,omitempty"` + Res *types.DeleteVffsVolumeStateResponse `xml:"urn:vim25 DeleteVffsVolumeStateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteVffsVolumeStateBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteVffsVolumeState(ctx context.Context, r soap.RoundTripper, req *types.DeleteVffsVolumeState) (*types.DeleteVffsVolumeStateResponse, error) { + var reqBody, resBody DeleteVffsVolumeStateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteVirtualDisk_TaskBody struct { + Req *types.DeleteVirtualDisk_Task `xml:"urn:vim25 DeleteVirtualDisk_Task,omitempty"` + Res *types.DeleteVirtualDisk_TaskResponse `xml:"urn:vim25 DeleteVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.DeleteVirtualDisk_Task) (*types.DeleteVirtualDisk_TaskResponse, error) { + var reqBody, resBody DeleteVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteVmfsVolumeStateBody struct { + Req *types.DeleteVmfsVolumeState `xml:"urn:vim25 DeleteVmfsVolumeState,omitempty"` + Res *types.DeleteVmfsVolumeStateResponse `xml:"urn:vim25 DeleteVmfsVolumeStateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteVmfsVolumeStateBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteVmfsVolumeState(ctx context.Context, r soap.RoundTripper, req *types.DeleteVmfsVolumeState) (*types.DeleteVmfsVolumeStateResponse, error) { + var reqBody, resBody DeleteVmfsVolumeStateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeleteVsanObjectsBody struct { + Req *types.DeleteVsanObjects `xml:"urn:vim25 DeleteVsanObjects,omitempty"` + Res *types.DeleteVsanObjectsResponse `xml:"urn:vim25 DeleteVsanObjectsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeleteVsanObjectsBody) Fault() *soap.Fault { return b.Fault_ } + +func DeleteVsanObjects(ctx context.Context, r soap.RoundTripper, req *types.DeleteVsanObjects) (*types.DeleteVsanObjectsResponse, error) { + var reqBody, resBody DeleteVsanObjectsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeselectVnicBody struct { + Req *types.DeselectVnic `xml:"urn:vim25 DeselectVnic,omitempty"` + Res *types.DeselectVnicResponse `xml:"urn:vim25 DeselectVnicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeselectVnicBody) Fault() *soap.Fault { return b.Fault_ } + +func DeselectVnic(ctx context.Context, r soap.RoundTripper, req *types.DeselectVnic) (*types.DeselectVnicResponse, error) { + var reqBody, resBody DeselectVnicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DeselectVnicForNicTypeBody struct { + Req *types.DeselectVnicForNicType `xml:"urn:vim25 DeselectVnicForNicType,omitempty"` + Res *types.DeselectVnicForNicTypeResponse `xml:"urn:vim25 DeselectVnicForNicTypeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DeselectVnicForNicTypeBody) Fault() *soap.Fault { return b.Fault_ } + +func DeselectVnicForNicType(ctx context.Context, r soap.RoundTripper, req *types.DeselectVnicForNicType) (*types.DeselectVnicForNicTypeResponse, error) { + var reqBody, resBody DeselectVnicForNicTypeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyChildrenBody struct { + Req *types.DestroyChildren `xml:"urn:vim25 DestroyChildren,omitempty"` + Res *types.DestroyChildrenResponse `xml:"urn:vim25 DestroyChildrenResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyChildrenBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyChildren(ctx context.Context, r soap.RoundTripper, req *types.DestroyChildren) (*types.DestroyChildrenResponse, error) { + var reqBody, resBody DestroyChildrenBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyCollectorBody struct { + Req *types.DestroyCollector `xml:"urn:vim25 DestroyCollector,omitempty"` + Res *types.DestroyCollectorResponse `xml:"urn:vim25 DestroyCollectorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyCollectorBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyCollector(ctx context.Context, r soap.RoundTripper, req *types.DestroyCollector) (*types.DestroyCollectorResponse, error) { + var reqBody, resBody DestroyCollectorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyDatastoreBody struct { + Req *types.DestroyDatastore `xml:"urn:vim25 DestroyDatastore,omitempty"` + Res *types.DestroyDatastoreResponse `xml:"urn:vim25 DestroyDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyDatastore(ctx context.Context, r soap.RoundTripper, req *types.DestroyDatastore) (*types.DestroyDatastoreResponse, error) { + var reqBody, resBody DestroyDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyIpPoolBody struct { + Req *types.DestroyIpPool `xml:"urn:vim25 DestroyIpPool,omitempty"` + Res *types.DestroyIpPoolResponse `xml:"urn:vim25 DestroyIpPoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyIpPoolBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyIpPool(ctx context.Context, r soap.RoundTripper, req *types.DestroyIpPool) (*types.DestroyIpPoolResponse, error) { + var reqBody, resBody DestroyIpPoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyNetworkBody struct { + Req *types.DestroyNetwork `xml:"urn:vim25 DestroyNetwork,omitempty"` + Res *types.DestroyNetworkResponse `xml:"urn:vim25 DestroyNetworkResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyNetworkBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyNetwork(ctx context.Context, r soap.RoundTripper, req *types.DestroyNetwork) (*types.DestroyNetworkResponse, error) { + var reqBody, resBody DestroyNetworkBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyProfileBody struct { + Req *types.DestroyProfile `xml:"urn:vim25 DestroyProfile,omitempty"` + Res *types.DestroyProfileResponse `xml:"urn:vim25 DestroyProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyProfile(ctx context.Context, r soap.RoundTripper, req *types.DestroyProfile) (*types.DestroyProfileResponse, error) { + var reqBody, resBody DestroyProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyPropertyCollectorBody struct { + Req *types.DestroyPropertyCollector `xml:"urn:vim25 DestroyPropertyCollector,omitempty"` + Res *types.DestroyPropertyCollectorResponse `xml:"urn:vim25 DestroyPropertyCollectorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyPropertyCollectorBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyPropertyCollector(ctx context.Context, r soap.RoundTripper, req *types.DestroyPropertyCollector) (*types.DestroyPropertyCollectorResponse, error) { + var reqBody, resBody DestroyPropertyCollectorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyPropertyFilterBody struct { + Req *types.DestroyPropertyFilter `xml:"urn:vim25 DestroyPropertyFilter,omitempty"` + Res *types.DestroyPropertyFilterResponse `xml:"urn:vim25 DestroyPropertyFilterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyPropertyFilterBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyPropertyFilter(ctx context.Context, r soap.RoundTripper, req *types.DestroyPropertyFilter) (*types.DestroyPropertyFilterResponse, error) { + var reqBody, resBody DestroyPropertyFilterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyVffsBody struct { + Req *types.DestroyVffs `xml:"urn:vim25 DestroyVffs,omitempty"` + Res *types.DestroyVffsResponse `xml:"urn:vim25 DestroyVffsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyVffsBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyVffs(ctx context.Context, r soap.RoundTripper, req *types.DestroyVffs) (*types.DestroyVffsResponse, error) { + var reqBody, resBody DestroyVffsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DestroyViewBody struct { + Req *types.DestroyView `xml:"urn:vim25 DestroyView,omitempty"` + Res *types.DestroyViewResponse `xml:"urn:vim25 DestroyViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DestroyViewBody) Fault() *soap.Fault { return b.Fault_ } + +func DestroyView(ctx context.Context, r soap.RoundTripper, req *types.DestroyView) (*types.DestroyViewResponse, error) { + var reqBody, resBody DestroyViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type Destroy_TaskBody struct { + Req *types.Destroy_Task `xml:"urn:vim25 Destroy_Task,omitempty"` + Res *types.Destroy_TaskResponse `xml:"urn:vim25 Destroy_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *Destroy_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func Destroy_Task(ctx context.Context, r soap.RoundTripper, req *types.Destroy_Task) (*types.Destroy_TaskResponse, error) { + var reqBody, resBody Destroy_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DetachScsiLunBody struct { + Req *types.DetachScsiLun `xml:"urn:vim25 DetachScsiLun,omitempty"` + Res *types.DetachScsiLunResponse `xml:"urn:vim25 DetachScsiLunResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DetachScsiLunBody) Fault() *soap.Fault { return b.Fault_ } + +func DetachScsiLun(ctx context.Context, r soap.RoundTripper, req *types.DetachScsiLun) (*types.DetachScsiLunResponse, error) { + var reqBody, resBody DetachScsiLunBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DetachScsiLunEx_TaskBody struct { + Req *types.DetachScsiLunEx_Task `xml:"urn:vim25 DetachScsiLunEx_Task,omitempty"` + Res *types.DetachScsiLunEx_TaskResponse `xml:"urn:vim25 DetachScsiLunEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DetachScsiLunEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DetachScsiLunEx_Task(ctx context.Context, r soap.RoundTripper, req *types.DetachScsiLunEx_Task) (*types.DetachScsiLunEx_TaskResponse, error) { + var reqBody, resBody DetachScsiLunEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableEvcMode_TaskBody struct { + Req *types.DisableEvcMode_Task `xml:"urn:vim25 DisableEvcMode_Task,omitempty"` + Res *types.DisableEvcMode_TaskResponse `xml:"urn:vim25 DisableEvcMode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableEvcMode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableEvcMode_Task(ctx context.Context, r soap.RoundTripper, req *types.DisableEvcMode_Task) (*types.DisableEvcMode_TaskResponse, error) { + var reqBody, resBody DisableEvcMode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableFeatureBody struct { + Req *types.DisableFeature `xml:"urn:vim25 DisableFeature,omitempty"` + Res *types.DisableFeatureResponse `xml:"urn:vim25 DisableFeatureResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableFeatureBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableFeature(ctx context.Context, r soap.RoundTripper, req *types.DisableFeature) (*types.DisableFeatureResponse, error) { + var reqBody, resBody DisableFeatureBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableHyperThreadingBody struct { + Req *types.DisableHyperThreading `xml:"urn:vim25 DisableHyperThreading,omitempty"` + Res *types.DisableHyperThreadingResponse `xml:"urn:vim25 DisableHyperThreadingResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableHyperThreadingBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableHyperThreading(ctx context.Context, r soap.RoundTripper, req *types.DisableHyperThreading) (*types.DisableHyperThreadingResponse, error) { + var reqBody, resBody DisableHyperThreadingBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableMultipathPathBody struct { + Req *types.DisableMultipathPath `xml:"urn:vim25 DisableMultipathPath,omitempty"` + Res *types.DisableMultipathPathResponse `xml:"urn:vim25 DisableMultipathPathResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableMultipathPathBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableMultipathPath(ctx context.Context, r soap.RoundTripper, req *types.DisableMultipathPath) (*types.DisableMultipathPathResponse, error) { + var reqBody, resBody DisableMultipathPathBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableRulesetBody struct { + Req *types.DisableRuleset `xml:"urn:vim25 DisableRuleset,omitempty"` + Res *types.DisableRulesetResponse `xml:"urn:vim25 DisableRulesetResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableRulesetBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableRuleset(ctx context.Context, r soap.RoundTripper, req *types.DisableRuleset) (*types.DisableRulesetResponse, error) { + var reqBody, resBody DisableRulesetBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableSecondaryVM_TaskBody struct { + Req *types.DisableSecondaryVM_Task `xml:"urn:vim25 DisableSecondaryVM_Task,omitempty"` + Res *types.DisableSecondaryVM_TaskResponse `xml:"urn:vim25 DisableSecondaryVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableSecondaryVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableSecondaryVM_Task(ctx context.Context, r soap.RoundTripper, req *types.DisableSecondaryVM_Task) (*types.DisableSecondaryVM_TaskResponse, error) { + var reqBody, resBody DisableSecondaryVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisableSmartCardAuthenticationBody struct { + Req *types.DisableSmartCardAuthentication `xml:"urn:vim25 DisableSmartCardAuthentication,omitempty"` + Res *types.DisableSmartCardAuthenticationResponse `xml:"urn:vim25 DisableSmartCardAuthenticationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisableSmartCardAuthenticationBody) Fault() *soap.Fault { return b.Fault_ } + +func DisableSmartCardAuthentication(ctx context.Context, r soap.RoundTripper, req *types.DisableSmartCardAuthentication) (*types.DisableSmartCardAuthenticationResponse, error) { + var reqBody, resBody DisableSmartCardAuthenticationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DisconnectHost_TaskBody struct { + Req *types.DisconnectHost_Task `xml:"urn:vim25 DisconnectHost_Task,omitempty"` + Res *types.DisconnectHost_TaskResponse `xml:"urn:vim25 DisconnectHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DisconnectHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DisconnectHost_Task(ctx context.Context, r soap.RoundTripper, req *types.DisconnectHost_Task) (*types.DisconnectHost_TaskResponse, error) { + var reqBody, resBody DisconnectHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DiscoverFcoeHbasBody struct { + Req *types.DiscoverFcoeHbas `xml:"urn:vim25 DiscoverFcoeHbas,omitempty"` + Res *types.DiscoverFcoeHbasResponse `xml:"urn:vim25 DiscoverFcoeHbasResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DiscoverFcoeHbasBody) Fault() *soap.Fault { return b.Fault_ } + +func DiscoverFcoeHbas(ctx context.Context, r soap.RoundTripper, req *types.DiscoverFcoeHbas) (*types.DiscoverFcoeHbasResponse, error) { + var reqBody, resBody DiscoverFcoeHbasBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DissociateProfileBody struct { + Req *types.DissociateProfile `xml:"urn:vim25 DissociateProfile,omitempty"` + Res *types.DissociateProfileResponse `xml:"urn:vim25 DissociateProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DissociateProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func DissociateProfile(ctx context.Context, r soap.RoundTripper, req *types.DissociateProfile) (*types.DissociateProfileResponse, error) { + var reqBody, resBody DissociateProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DoesCustomizationSpecExistBody struct { + Req *types.DoesCustomizationSpecExist `xml:"urn:vim25 DoesCustomizationSpecExist,omitempty"` + Res *types.DoesCustomizationSpecExistResponse `xml:"urn:vim25 DoesCustomizationSpecExistResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DoesCustomizationSpecExistBody) Fault() *soap.Fault { return b.Fault_ } + +func DoesCustomizationSpecExist(ctx context.Context, r soap.RoundTripper, req *types.DoesCustomizationSpecExist) (*types.DoesCustomizationSpecExistResponse, error) { + var reqBody, resBody DoesCustomizationSpecExistBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DuplicateCustomizationSpecBody struct { + Req *types.DuplicateCustomizationSpec `xml:"urn:vim25 DuplicateCustomizationSpec,omitempty"` + Res *types.DuplicateCustomizationSpecResponse `xml:"urn:vim25 DuplicateCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DuplicateCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func DuplicateCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.DuplicateCustomizationSpec) (*types.DuplicateCustomizationSpecResponse, error) { + var reqBody, resBody DuplicateCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type DvsReconfigureVmVnicNetworkResourcePool_TaskBody struct { + Req *types.DvsReconfigureVmVnicNetworkResourcePool_Task `xml:"urn:vim25 DvsReconfigureVmVnicNetworkResourcePool_Task,omitempty"` + Res *types.DvsReconfigureVmVnicNetworkResourcePool_TaskResponse `xml:"urn:vim25 DvsReconfigureVmVnicNetworkResourcePool_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *DvsReconfigureVmVnicNetworkResourcePool_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func DvsReconfigureVmVnicNetworkResourcePool_Task(ctx context.Context, r soap.RoundTripper, req *types.DvsReconfigureVmVnicNetworkResourcePool_Task) (*types.DvsReconfigureVmVnicNetworkResourcePool_TaskResponse, error) { + var reqBody, resBody DvsReconfigureVmVnicNetworkResourcePool_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EagerZeroVirtualDisk_TaskBody struct { + Req *types.EagerZeroVirtualDisk_Task `xml:"urn:vim25 EagerZeroVirtualDisk_Task,omitempty"` + Res *types.EagerZeroVirtualDisk_TaskResponse `xml:"urn:vim25 EagerZeroVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EagerZeroVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func EagerZeroVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.EagerZeroVirtualDisk_Task) (*types.EagerZeroVirtualDisk_TaskResponse, error) { + var reqBody, resBody EagerZeroVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableAlarmActionsBody struct { + Req *types.EnableAlarmActions `xml:"urn:vim25 EnableAlarmActions,omitempty"` + Res *types.EnableAlarmActionsResponse `xml:"urn:vim25 EnableAlarmActionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableAlarmActionsBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableAlarmActions(ctx context.Context, r soap.RoundTripper, req *types.EnableAlarmActions) (*types.EnableAlarmActionsResponse, error) { + var reqBody, resBody EnableAlarmActionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableFeatureBody struct { + Req *types.EnableFeature `xml:"urn:vim25 EnableFeature,omitempty"` + Res *types.EnableFeatureResponse `xml:"urn:vim25 EnableFeatureResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableFeatureBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableFeature(ctx context.Context, r soap.RoundTripper, req *types.EnableFeature) (*types.EnableFeatureResponse, error) { + var reqBody, resBody EnableFeatureBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableHyperThreadingBody struct { + Req *types.EnableHyperThreading `xml:"urn:vim25 EnableHyperThreading,omitempty"` + Res *types.EnableHyperThreadingResponse `xml:"urn:vim25 EnableHyperThreadingResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableHyperThreadingBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableHyperThreading(ctx context.Context, r soap.RoundTripper, req *types.EnableHyperThreading) (*types.EnableHyperThreadingResponse, error) { + var reqBody, resBody EnableHyperThreadingBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableMultipathPathBody struct { + Req *types.EnableMultipathPath `xml:"urn:vim25 EnableMultipathPath,omitempty"` + Res *types.EnableMultipathPathResponse `xml:"urn:vim25 EnableMultipathPathResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableMultipathPathBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableMultipathPath(ctx context.Context, r soap.RoundTripper, req *types.EnableMultipathPath) (*types.EnableMultipathPathResponse, error) { + var reqBody, resBody EnableMultipathPathBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableNetworkResourceManagementBody struct { + Req *types.EnableNetworkResourceManagement `xml:"urn:vim25 EnableNetworkResourceManagement,omitempty"` + Res *types.EnableNetworkResourceManagementResponse `xml:"urn:vim25 EnableNetworkResourceManagementResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableNetworkResourceManagementBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableNetworkResourceManagement(ctx context.Context, r soap.RoundTripper, req *types.EnableNetworkResourceManagement) (*types.EnableNetworkResourceManagementResponse, error) { + var reqBody, resBody EnableNetworkResourceManagementBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableRulesetBody struct { + Req *types.EnableRuleset `xml:"urn:vim25 EnableRuleset,omitempty"` + Res *types.EnableRulesetResponse `xml:"urn:vim25 EnableRulesetResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableRulesetBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableRuleset(ctx context.Context, r soap.RoundTripper, req *types.EnableRuleset) (*types.EnableRulesetResponse, error) { + var reqBody, resBody EnableRulesetBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableSecondaryVM_TaskBody struct { + Req *types.EnableSecondaryVM_Task `xml:"urn:vim25 EnableSecondaryVM_Task,omitempty"` + Res *types.EnableSecondaryVM_TaskResponse `xml:"urn:vim25 EnableSecondaryVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableSecondaryVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableSecondaryVM_Task(ctx context.Context, r soap.RoundTripper, req *types.EnableSecondaryVM_Task) (*types.EnableSecondaryVM_TaskResponse, error) { + var reqBody, resBody EnableSecondaryVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnableSmartCardAuthenticationBody struct { + Req *types.EnableSmartCardAuthentication `xml:"urn:vim25 EnableSmartCardAuthentication,omitempty"` + Res *types.EnableSmartCardAuthenticationResponse `xml:"urn:vim25 EnableSmartCardAuthenticationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnableSmartCardAuthenticationBody) Fault() *soap.Fault { return b.Fault_ } + +func EnableSmartCardAuthentication(ctx context.Context, r soap.RoundTripper, req *types.EnableSmartCardAuthentication) (*types.EnableSmartCardAuthenticationResponse, error) { + var reqBody, resBody EnableSmartCardAuthenticationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnterLockdownModeBody struct { + Req *types.EnterLockdownMode `xml:"urn:vim25 EnterLockdownMode,omitempty"` + Res *types.EnterLockdownModeResponse `xml:"urn:vim25 EnterLockdownModeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnterLockdownModeBody) Fault() *soap.Fault { return b.Fault_ } + +func EnterLockdownMode(ctx context.Context, r soap.RoundTripper, req *types.EnterLockdownMode) (*types.EnterLockdownModeResponse, error) { + var reqBody, resBody EnterLockdownModeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EnterMaintenanceMode_TaskBody struct { + Req *types.EnterMaintenanceMode_Task `xml:"urn:vim25 EnterMaintenanceMode_Task,omitempty"` + Res *types.EnterMaintenanceMode_TaskResponse `xml:"urn:vim25 EnterMaintenanceMode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EnterMaintenanceMode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func EnterMaintenanceMode_Task(ctx context.Context, r soap.RoundTripper, req *types.EnterMaintenanceMode_Task) (*types.EnterMaintenanceMode_TaskResponse, error) { + var reqBody, resBody EnterMaintenanceMode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EstimateDatabaseSizeBody struct { + Req *types.EstimateDatabaseSize `xml:"urn:vim25 EstimateDatabaseSize,omitempty"` + Res *types.EstimateDatabaseSizeResponse `xml:"urn:vim25 EstimateDatabaseSizeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EstimateDatabaseSizeBody) Fault() *soap.Fault { return b.Fault_ } + +func EstimateDatabaseSize(ctx context.Context, r soap.RoundTripper, req *types.EstimateDatabaseSize) (*types.EstimateDatabaseSizeResponse, error) { + var reqBody, resBody EstimateDatabaseSizeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EstimateStorageForConsolidateSnapshots_TaskBody struct { + Req *types.EstimateStorageForConsolidateSnapshots_Task `xml:"urn:vim25 EstimateStorageForConsolidateSnapshots_Task,omitempty"` + Res *types.EstimateStorageForConsolidateSnapshots_TaskResponse `xml:"urn:vim25 EstimateStorageForConsolidateSnapshots_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EstimateStorageForConsolidateSnapshots_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func EstimateStorageForConsolidateSnapshots_Task(ctx context.Context, r soap.RoundTripper, req *types.EstimateStorageForConsolidateSnapshots_Task) (*types.EstimateStorageForConsolidateSnapshots_TaskResponse, error) { + var reqBody, resBody EstimateStorageForConsolidateSnapshots_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EsxAgentHostManagerUpdateConfigBody struct { + Req *types.EsxAgentHostManagerUpdateConfig `xml:"urn:vim25 EsxAgentHostManagerUpdateConfig,omitempty"` + Res *types.EsxAgentHostManagerUpdateConfigResponse `xml:"urn:vim25 EsxAgentHostManagerUpdateConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EsxAgentHostManagerUpdateConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func EsxAgentHostManagerUpdateConfig(ctx context.Context, r soap.RoundTripper, req *types.EsxAgentHostManagerUpdateConfig) (*types.EsxAgentHostManagerUpdateConfigResponse, error) { + var reqBody, resBody EsxAgentHostManagerUpdateConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EvacuateVsanNode_TaskBody struct { + Req *types.EvacuateVsanNode_Task `xml:"urn:vim25 EvacuateVsanNode_Task,omitempty"` + Res *types.EvacuateVsanNode_TaskResponse `xml:"urn:vim25 EvacuateVsanNode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EvacuateVsanNode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func EvacuateVsanNode_Task(ctx context.Context, r soap.RoundTripper, req *types.EvacuateVsanNode_Task) (*types.EvacuateVsanNode_TaskResponse, error) { + var reqBody, resBody EvacuateVsanNode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type EvcManagerBody struct { + Req *types.EvcManager `xml:"urn:vim25 EvcManager,omitempty"` + Res *types.EvcManagerResponse `xml:"urn:vim25 EvcManagerResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *EvcManagerBody) Fault() *soap.Fault { return b.Fault_ } + +func EvcManager(ctx context.Context, r soap.RoundTripper, req *types.EvcManager) (*types.EvcManagerResponse, error) { + var reqBody, resBody EvcManagerBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExecuteHostProfileBody struct { + Req *types.ExecuteHostProfile `xml:"urn:vim25 ExecuteHostProfile,omitempty"` + Res *types.ExecuteHostProfileResponse `xml:"urn:vim25 ExecuteHostProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExecuteHostProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func ExecuteHostProfile(ctx context.Context, r soap.RoundTripper, req *types.ExecuteHostProfile) (*types.ExecuteHostProfileResponse, error) { + var reqBody, resBody ExecuteHostProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExecuteSimpleCommandBody struct { + Req *types.ExecuteSimpleCommand `xml:"urn:vim25 ExecuteSimpleCommand,omitempty"` + Res *types.ExecuteSimpleCommandResponse `xml:"urn:vim25 ExecuteSimpleCommandResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExecuteSimpleCommandBody) Fault() *soap.Fault { return b.Fault_ } + +func ExecuteSimpleCommand(ctx context.Context, r soap.RoundTripper, req *types.ExecuteSimpleCommand) (*types.ExecuteSimpleCommandResponse, error) { + var reqBody, resBody ExecuteSimpleCommandBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExitLockdownModeBody struct { + Req *types.ExitLockdownMode `xml:"urn:vim25 ExitLockdownMode,omitempty"` + Res *types.ExitLockdownModeResponse `xml:"urn:vim25 ExitLockdownModeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExitLockdownModeBody) Fault() *soap.Fault { return b.Fault_ } + +func ExitLockdownMode(ctx context.Context, r soap.RoundTripper, req *types.ExitLockdownMode) (*types.ExitLockdownModeResponse, error) { + var reqBody, resBody ExitLockdownModeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExitMaintenanceMode_TaskBody struct { + Req *types.ExitMaintenanceMode_Task `xml:"urn:vim25 ExitMaintenanceMode_Task,omitempty"` + Res *types.ExitMaintenanceMode_TaskResponse `xml:"urn:vim25 ExitMaintenanceMode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExitMaintenanceMode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ExitMaintenanceMode_Task(ctx context.Context, r soap.RoundTripper, req *types.ExitMaintenanceMode_Task) (*types.ExitMaintenanceMode_TaskResponse, error) { + var reqBody, resBody ExitMaintenanceMode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExpandVmfsDatastoreBody struct { + Req *types.ExpandVmfsDatastore `xml:"urn:vim25 ExpandVmfsDatastore,omitempty"` + Res *types.ExpandVmfsDatastoreResponse `xml:"urn:vim25 ExpandVmfsDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExpandVmfsDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func ExpandVmfsDatastore(ctx context.Context, r soap.RoundTripper, req *types.ExpandVmfsDatastore) (*types.ExpandVmfsDatastoreResponse, error) { + var reqBody, resBody ExpandVmfsDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExpandVmfsExtentBody struct { + Req *types.ExpandVmfsExtent `xml:"urn:vim25 ExpandVmfsExtent,omitempty"` + Res *types.ExpandVmfsExtentResponse `xml:"urn:vim25 ExpandVmfsExtentResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExpandVmfsExtentBody) Fault() *soap.Fault { return b.Fault_ } + +func ExpandVmfsExtent(ctx context.Context, r soap.RoundTripper, req *types.ExpandVmfsExtent) (*types.ExpandVmfsExtentResponse, error) { + var reqBody, resBody ExpandVmfsExtentBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExportAnswerFile_TaskBody struct { + Req *types.ExportAnswerFile_Task `xml:"urn:vim25 ExportAnswerFile_Task,omitempty"` + Res *types.ExportAnswerFile_TaskResponse `xml:"urn:vim25 ExportAnswerFile_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExportAnswerFile_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ExportAnswerFile_Task(ctx context.Context, r soap.RoundTripper, req *types.ExportAnswerFile_Task) (*types.ExportAnswerFile_TaskResponse, error) { + var reqBody, resBody ExportAnswerFile_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExportProfileBody struct { + Req *types.ExportProfile `xml:"urn:vim25 ExportProfile,omitempty"` + Res *types.ExportProfileResponse `xml:"urn:vim25 ExportProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExportProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func ExportProfile(ctx context.Context, r soap.RoundTripper, req *types.ExportProfile) (*types.ExportProfileResponse, error) { + var reqBody, resBody ExportProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExportSnapshotBody struct { + Req *types.ExportSnapshot `xml:"urn:vim25 ExportSnapshot,omitempty"` + Res *types.ExportSnapshotResponse `xml:"urn:vim25 ExportSnapshotResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExportSnapshotBody) Fault() *soap.Fault { return b.Fault_ } + +func ExportSnapshot(ctx context.Context, r soap.RoundTripper, req *types.ExportSnapshot) (*types.ExportSnapshotResponse, error) { + var reqBody, resBody ExportSnapshotBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExportVAppBody struct { + Req *types.ExportVApp `xml:"urn:vim25 ExportVApp,omitempty"` + Res *types.ExportVAppResponse `xml:"urn:vim25 ExportVAppResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExportVAppBody) Fault() *soap.Fault { return b.Fault_ } + +func ExportVApp(ctx context.Context, r soap.RoundTripper, req *types.ExportVApp) (*types.ExportVAppResponse, error) { + var reqBody, resBody ExportVAppBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExportVmBody struct { + Req *types.ExportVm `xml:"urn:vim25 ExportVm,omitempty"` + Res *types.ExportVmResponse `xml:"urn:vim25 ExportVmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExportVmBody) Fault() *soap.Fault { return b.Fault_ } + +func ExportVm(ctx context.Context, r soap.RoundTripper, req *types.ExportVm) (*types.ExportVmResponse, error) { + var reqBody, resBody ExportVmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExtendVffsBody struct { + Req *types.ExtendVffs `xml:"urn:vim25 ExtendVffs,omitempty"` + Res *types.ExtendVffsResponse `xml:"urn:vim25 ExtendVffsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExtendVffsBody) Fault() *soap.Fault { return b.Fault_ } + +func ExtendVffs(ctx context.Context, r soap.RoundTripper, req *types.ExtendVffs) (*types.ExtendVffsResponse, error) { + var reqBody, resBody ExtendVffsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExtendVirtualDisk_TaskBody struct { + Req *types.ExtendVirtualDisk_Task `xml:"urn:vim25 ExtendVirtualDisk_Task,omitempty"` + Res *types.ExtendVirtualDisk_TaskResponse `xml:"urn:vim25 ExtendVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExtendVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ExtendVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.ExtendVirtualDisk_Task) (*types.ExtendVirtualDisk_TaskResponse, error) { + var reqBody, resBody ExtendVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExtendVmfsDatastoreBody struct { + Req *types.ExtendVmfsDatastore `xml:"urn:vim25 ExtendVmfsDatastore,omitempty"` + Res *types.ExtendVmfsDatastoreResponse `xml:"urn:vim25 ExtendVmfsDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExtendVmfsDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func ExtendVmfsDatastore(ctx context.Context, r soap.RoundTripper, req *types.ExtendVmfsDatastore) (*types.ExtendVmfsDatastoreResponse, error) { + var reqBody, resBody ExtendVmfsDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ExtractOvfEnvironmentBody struct { + Req *types.ExtractOvfEnvironment `xml:"urn:vim25 ExtractOvfEnvironment,omitempty"` + Res *types.ExtractOvfEnvironmentResponse `xml:"urn:vim25 ExtractOvfEnvironmentResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ExtractOvfEnvironmentBody) Fault() *soap.Fault { return b.Fault_ } + +func ExtractOvfEnvironment(ctx context.Context, r soap.RoundTripper, req *types.ExtractOvfEnvironment) (*types.ExtractOvfEnvironmentResponse, error) { + var reqBody, resBody ExtractOvfEnvironmentBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FetchDVPortKeysBody struct { + Req *types.FetchDVPortKeys `xml:"urn:vim25 FetchDVPortKeys,omitempty"` + Res *types.FetchDVPortKeysResponse `xml:"urn:vim25 FetchDVPortKeysResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FetchDVPortKeysBody) Fault() *soap.Fault { return b.Fault_ } + +func FetchDVPortKeys(ctx context.Context, r soap.RoundTripper, req *types.FetchDVPortKeys) (*types.FetchDVPortKeysResponse, error) { + var reqBody, resBody FetchDVPortKeysBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FetchDVPortsBody struct { + Req *types.FetchDVPorts `xml:"urn:vim25 FetchDVPorts,omitempty"` + Res *types.FetchDVPortsResponse `xml:"urn:vim25 FetchDVPortsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FetchDVPortsBody) Fault() *soap.Fault { return b.Fault_ } + +func FetchDVPorts(ctx context.Context, r soap.RoundTripper, req *types.FetchDVPorts) (*types.FetchDVPortsResponse, error) { + var reqBody, resBody FetchDVPortsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindAllByDnsNameBody struct { + Req *types.FindAllByDnsName `xml:"urn:vim25 FindAllByDnsName,omitempty"` + Res *types.FindAllByDnsNameResponse `xml:"urn:vim25 FindAllByDnsNameResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindAllByDnsNameBody) Fault() *soap.Fault { return b.Fault_ } + +func FindAllByDnsName(ctx context.Context, r soap.RoundTripper, req *types.FindAllByDnsName) (*types.FindAllByDnsNameResponse, error) { + var reqBody, resBody FindAllByDnsNameBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindAllByIpBody struct { + Req *types.FindAllByIp `xml:"urn:vim25 FindAllByIp,omitempty"` + Res *types.FindAllByIpResponse `xml:"urn:vim25 FindAllByIpResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindAllByIpBody) Fault() *soap.Fault { return b.Fault_ } + +func FindAllByIp(ctx context.Context, r soap.RoundTripper, req *types.FindAllByIp) (*types.FindAllByIpResponse, error) { + var reqBody, resBody FindAllByIpBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindAllByUuidBody struct { + Req *types.FindAllByUuid `xml:"urn:vim25 FindAllByUuid,omitempty"` + Res *types.FindAllByUuidResponse `xml:"urn:vim25 FindAllByUuidResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindAllByUuidBody) Fault() *soap.Fault { return b.Fault_ } + +func FindAllByUuid(ctx context.Context, r soap.RoundTripper, req *types.FindAllByUuid) (*types.FindAllByUuidResponse, error) { + var reqBody, resBody FindAllByUuidBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindAssociatedProfileBody struct { + Req *types.FindAssociatedProfile `xml:"urn:vim25 FindAssociatedProfile,omitempty"` + Res *types.FindAssociatedProfileResponse `xml:"urn:vim25 FindAssociatedProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindAssociatedProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func FindAssociatedProfile(ctx context.Context, r soap.RoundTripper, req *types.FindAssociatedProfile) (*types.FindAssociatedProfileResponse, error) { + var reqBody, resBody FindAssociatedProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindByDatastorePathBody struct { + Req *types.FindByDatastorePath `xml:"urn:vim25 FindByDatastorePath,omitempty"` + Res *types.FindByDatastorePathResponse `xml:"urn:vim25 FindByDatastorePathResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindByDatastorePathBody) Fault() *soap.Fault { return b.Fault_ } + +func FindByDatastorePath(ctx context.Context, r soap.RoundTripper, req *types.FindByDatastorePath) (*types.FindByDatastorePathResponse, error) { + var reqBody, resBody FindByDatastorePathBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindByDnsNameBody struct { + Req *types.FindByDnsName `xml:"urn:vim25 FindByDnsName,omitempty"` + Res *types.FindByDnsNameResponse `xml:"urn:vim25 FindByDnsNameResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindByDnsNameBody) Fault() *soap.Fault { return b.Fault_ } + +func FindByDnsName(ctx context.Context, r soap.RoundTripper, req *types.FindByDnsName) (*types.FindByDnsNameResponse, error) { + var reqBody, resBody FindByDnsNameBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindByInventoryPathBody struct { + Req *types.FindByInventoryPath `xml:"urn:vim25 FindByInventoryPath,omitempty"` + Res *types.FindByInventoryPathResponse `xml:"urn:vim25 FindByInventoryPathResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindByInventoryPathBody) Fault() *soap.Fault { return b.Fault_ } + +func FindByInventoryPath(ctx context.Context, r soap.RoundTripper, req *types.FindByInventoryPath) (*types.FindByInventoryPathResponse, error) { + var reqBody, resBody FindByInventoryPathBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindByIpBody struct { + Req *types.FindByIp `xml:"urn:vim25 FindByIp,omitempty"` + Res *types.FindByIpResponse `xml:"urn:vim25 FindByIpResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindByIpBody) Fault() *soap.Fault { return b.Fault_ } + +func FindByIp(ctx context.Context, r soap.RoundTripper, req *types.FindByIp) (*types.FindByIpResponse, error) { + var reqBody, resBody FindByIpBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindByUuidBody struct { + Req *types.FindByUuid `xml:"urn:vim25 FindByUuid,omitempty"` + Res *types.FindByUuidResponse `xml:"urn:vim25 FindByUuidResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindByUuidBody) Fault() *soap.Fault { return b.Fault_ } + +func FindByUuid(ctx context.Context, r soap.RoundTripper, req *types.FindByUuid) (*types.FindByUuidResponse, error) { + var reqBody, resBody FindByUuidBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindChildBody struct { + Req *types.FindChild `xml:"urn:vim25 FindChild,omitempty"` + Res *types.FindChildResponse `xml:"urn:vim25 FindChildResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindChildBody) Fault() *soap.Fault { return b.Fault_ } + +func FindChild(ctx context.Context, r soap.RoundTripper, req *types.FindChild) (*types.FindChildResponse, error) { + var reqBody, resBody FindChildBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindExtensionBody struct { + Req *types.FindExtension `xml:"urn:vim25 FindExtension,omitempty"` + Res *types.FindExtensionResponse `xml:"urn:vim25 FindExtensionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindExtensionBody) Fault() *soap.Fault { return b.Fault_ } + +func FindExtension(ctx context.Context, r soap.RoundTripper, req *types.FindExtension) (*types.FindExtensionResponse, error) { + var reqBody, resBody FindExtensionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FindRulesForVmBody struct { + Req *types.FindRulesForVm `xml:"urn:vim25 FindRulesForVm,omitempty"` + Res *types.FindRulesForVmResponse `xml:"urn:vim25 FindRulesForVmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FindRulesForVmBody) Fault() *soap.Fault { return b.Fault_ } + +func FindRulesForVm(ctx context.Context, r soap.RoundTripper, req *types.FindRulesForVm) (*types.FindRulesForVmResponse, error) { + var reqBody, resBody FindRulesForVmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FormatVffsBody struct { + Req *types.FormatVffs `xml:"urn:vim25 FormatVffs,omitempty"` + Res *types.FormatVffsResponse `xml:"urn:vim25 FormatVffsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FormatVffsBody) Fault() *soap.Fault { return b.Fault_ } + +func FormatVffs(ctx context.Context, r soap.RoundTripper, req *types.FormatVffs) (*types.FormatVffsResponse, error) { + var reqBody, resBody FormatVffsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type FormatVmfsBody struct { + Req *types.FormatVmfs `xml:"urn:vim25 FormatVmfs,omitempty"` + Res *types.FormatVmfsResponse `xml:"urn:vim25 FormatVmfsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *FormatVmfsBody) Fault() *soap.Fault { return b.Fault_ } + +func FormatVmfs(ctx context.Context, r soap.RoundTripper, req *types.FormatVmfs) (*types.FormatVmfsResponse, error) { + var reqBody, resBody FormatVmfsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GenerateCertificateSigningRequestBody struct { + Req *types.GenerateCertificateSigningRequest `xml:"urn:vim25 GenerateCertificateSigningRequest,omitempty"` + Res *types.GenerateCertificateSigningRequestResponse `xml:"urn:vim25 GenerateCertificateSigningRequestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GenerateCertificateSigningRequestBody) Fault() *soap.Fault { return b.Fault_ } + +func GenerateCertificateSigningRequest(ctx context.Context, r soap.RoundTripper, req *types.GenerateCertificateSigningRequest) (*types.GenerateCertificateSigningRequestResponse, error) { + var reqBody, resBody GenerateCertificateSigningRequestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GenerateCertificateSigningRequestByDnBody struct { + Req *types.GenerateCertificateSigningRequestByDn `xml:"urn:vim25 GenerateCertificateSigningRequestByDn,omitempty"` + Res *types.GenerateCertificateSigningRequestByDnResponse `xml:"urn:vim25 GenerateCertificateSigningRequestByDnResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GenerateCertificateSigningRequestByDnBody) Fault() *soap.Fault { return b.Fault_ } + +func GenerateCertificateSigningRequestByDn(ctx context.Context, r soap.RoundTripper, req *types.GenerateCertificateSigningRequestByDn) (*types.GenerateCertificateSigningRequestByDnResponse, error) { + var reqBody, resBody GenerateCertificateSigningRequestByDnBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GenerateConfigTaskListBody struct { + Req *types.GenerateConfigTaskList `xml:"urn:vim25 GenerateConfigTaskList,omitempty"` + Res *types.GenerateConfigTaskListResponse `xml:"urn:vim25 GenerateConfigTaskListResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GenerateConfigTaskListBody) Fault() *soap.Fault { return b.Fault_ } + +func GenerateConfigTaskList(ctx context.Context, r soap.RoundTripper, req *types.GenerateConfigTaskList) (*types.GenerateConfigTaskListResponse, error) { + var reqBody, resBody GenerateConfigTaskListBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GenerateHostProfileTaskList_TaskBody struct { + Req *types.GenerateHostProfileTaskList_Task `xml:"urn:vim25 GenerateHostProfileTaskList_Task,omitempty"` + Res *types.GenerateHostProfileTaskList_TaskResponse `xml:"urn:vim25 GenerateHostProfileTaskList_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GenerateHostProfileTaskList_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func GenerateHostProfileTaskList_Task(ctx context.Context, r soap.RoundTripper, req *types.GenerateHostProfileTaskList_Task) (*types.GenerateHostProfileTaskList_TaskResponse, error) { + var reqBody, resBody GenerateHostProfileTaskList_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GenerateLogBundles_TaskBody struct { + Req *types.GenerateLogBundles_Task `xml:"urn:vim25 GenerateLogBundles_Task,omitempty"` + Res *types.GenerateLogBundles_TaskResponse `xml:"urn:vim25 GenerateLogBundles_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GenerateLogBundles_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func GenerateLogBundles_Task(ctx context.Context, r soap.RoundTripper, req *types.GenerateLogBundles_Task) (*types.GenerateLogBundles_TaskResponse, error) { + var reqBody, resBody GenerateLogBundles_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GetAlarmBody struct { + Req *types.GetAlarm `xml:"urn:vim25 GetAlarm,omitempty"` + Res *types.GetAlarmResponse `xml:"urn:vim25 GetAlarmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GetAlarmBody) Fault() *soap.Fault { return b.Fault_ } + +func GetAlarm(ctx context.Context, r soap.RoundTripper, req *types.GetAlarm) (*types.GetAlarmResponse, error) { + var reqBody, resBody GetAlarmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GetAlarmStateBody struct { + Req *types.GetAlarmState `xml:"urn:vim25 GetAlarmState,omitempty"` + Res *types.GetAlarmStateResponse `xml:"urn:vim25 GetAlarmStateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GetAlarmStateBody) Fault() *soap.Fault { return b.Fault_ } + +func GetAlarmState(ctx context.Context, r soap.RoundTripper, req *types.GetAlarmState) (*types.GetAlarmStateResponse, error) { + var reqBody, resBody GetAlarmStateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GetCustomizationSpecBody struct { + Req *types.GetCustomizationSpec `xml:"urn:vim25 GetCustomizationSpec,omitempty"` + Res *types.GetCustomizationSpecResponse `xml:"urn:vim25 GetCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GetCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func GetCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.GetCustomizationSpec) (*types.GetCustomizationSpecResponse, error) { + var reqBody, resBody GetCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GetPublicKeyBody struct { + Req *types.GetPublicKey `xml:"urn:vim25 GetPublicKey,omitempty"` + Res *types.GetPublicKeyResponse `xml:"urn:vim25 GetPublicKeyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GetPublicKeyBody) Fault() *soap.Fault { return b.Fault_ } + +func GetPublicKey(ctx context.Context, r soap.RoundTripper, req *types.GetPublicKey) (*types.GetPublicKeyResponse, error) { + var reqBody, resBody GetPublicKeyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GetResourceUsageBody struct { + Req *types.GetResourceUsage `xml:"urn:vim25 GetResourceUsage,omitempty"` + Res *types.GetResourceUsageResponse `xml:"urn:vim25 GetResourceUsageResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GetResourceUsageBody) Fault() *soap.Fault { return b.Fault_ } + +func GetResourceUsage(ctx context.Context, r soap.RoundTripper, req *types.GetResourceUsage) (*types.GetResourceUsageResponse, error) { + var reqBody, resBody GetResourceUsageBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type GetVsanObjExtAttrsBody struct { + Req *types.GetVsanObjExtAttrs `xml:"urn:vim25 GetVsanObjExtAttrs,omitempty"` + Res *types.GetVsanObjExtAttrsResponse `xml:"urn:vim25 GetVsanObjExtAttrsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *GetVsanObjExtAttrsBody) Fault() *soap.Fault { return b.Fault_ } + +func GetVsanObjExtAttrs(ctx context.Context, r soap.RoundTripper, req *types.GetVsanObjExtAttrs) (*types.GetVsanObjExtAttrsResponse, error) { + var reqBody, resBody GetVsanObjExtAttrsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HasPrivilegeOnEntitiesBody struct { + Req *types.HasPrivilegeOnEntities `xml:"urn:vim25 HasPrivilegeOnEntities,omitempty"` + Res *types.HasPrivilegeOnEntitiesResponse `xml:"urn:vim25 HasPrivilegeOnEntitiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HasPrivilegeOnEntitiesBody) Fault() *soap.Fault { return b.Fault_ } + +func HasPrivilegeOnEntities(ctx context.Context, r soap.RoundTripper, req *types.HasPrivilegeOnEntities) (*types.HasPrivilegeOnEntitiesResponse, error) { + var reqBody, resBody HasPrivilegeOnEntitiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HasPrivilegeOnEntityBody struct { + Req *types.HasPrivilegeOnEntity `xml:"urn:vim25 HasPrivilegeOnEntity,omitempty"` + Res *types.HasPrivilegeOnEntityResponse `xml:"urn:vim25 HasPrivilegeOnEntityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HasPrivilegeOnEntityBody) Fault() *soap.Fault { return b.Fault_ } + +func HasPrivilegeOnEntity(ctx context.Context, r soap.RoundTripper, req *types.HasPrivilegeOnEntity) (*types.HasPrivilegeOnEntityResponse, error) { + var reqBody, resBody HasPrivilegeOnEntityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HostConfigVFlashCacheBody struct { + Req *types.HostConfigVFlashCache `xml:"urn:vim25 HostConfigVFlashCache,omitempty"` + Res *types.HostConfigVFlashCacheResponse `xml:"urn:vim25 HostConfigVFlashCacheResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HostConfigVFlashCacheBody) Fault() *soap.Fault { return b.Fault_ } + +func HostConfigVFlashCache(ctx context.Context, r soap.RoundTripper, req *types.HostConfigVFlashCache) (*types.HostConfigVFlashCacheResponse, error) { + var reqBody, resBody HostConfigVFlashCacheBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HostConfigureVFlashResourceBody struct { + Req *types.HostConfigureVFlashResource `xml:"urn:vim25 HostConfigureVFlashResource,omitempty"` + Res *types.HostConfigureVFlashResourceResponse `xml:"urn:vim25 HostConfigureVFlashResourceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HostConfigureVFlashResourceBody) Fault() *soap.Fault { return b.Fault_ } + +func HostConfigureVFlashResource(ctx context.Context, r soap.RoundTripper, req *types.HostConfigureVFlashResource) (*types.HostConfigureVFlashResourceResponse, error) { + var reqBody, resBody HostConfigureVFlashResourceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HostGetVFlashModuleDefaultConfigBody struct { + Req *types.HostGetVFlashModuleDefaultConfig `xml:"urn:vim25 HostGetVFlashModuleDefaultConfig,omitempty"` + Res *types.HostGetVFlashModuleDefaultConfigResponse `xml:"urn:vim25 HostGetVFlashModuleDefaultConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HostGetVFlashModuleDefaultConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func HostGetVFlashModuleDefaultConfig(ctx context.Context, r soap.RoundTripper, req *types.HostGetVFlashModuleDefaultConfig) (*types.HostGetVFlashModuleDefaultConfigResponse, error) { + var reqBody, resBody HostGetVFlashModuleDefaultConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HostImageConfigGetAcceptanceBody struct { + Req *types.HostImageConfigGetAcceptance `xml:"urn:vim25 HostImageConfigGetAcceptance,omitempty"` + Res *types.HostImageConfigGetAcceptanceResponse `xml:"urn:vim25 HostImageConfigGetAcceptanceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HostImageConfigGetAcceptanceBody) Fault() *soap.Fault { return b.Fault_ } + +func HostImageConfigGetAcceptance(ctx context.Context, r soap.RoundTripper, req *types.HostImageConfigGetAcceptance) (*types.HostImageConfigGetAcceptanceResponse, error) { + var reqBody, resBody HostImageConfigGetAcceptanceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HostImageConfigGetProfileBody struct { + Req *types.HostImageConfigGetProfile `xml:"urn:vim25 HostImageConfigGetProfile,omitempty"` + Res *types.HostImageConfigGetProfileResponse `xml:"urn:vim25 HostImageConfigGetProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HostImageConfigGetProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func HostImageConfigGetProfile(ctx context.Context, r soap.RoundTripper, req *types.HostImageConfigGetProfile) (*types.HostImageConfigGetProfileResponse, error) { + var reqBody, resBody HostImageConfigGetProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HostRemoveVFlashResourceBody struct { + Req *types.HostRemoveVFlashResource `xml:"urn:vim25 HostRemoveVFlashResource,omitempty"` + Res *types.HostRemoveVFlashResourceResponse `xml:"urn:vim25 HostRemoveVFlashResourceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HostRemoveVFlashResourceBody) Fault() *soap.Fault { return b.Fault_ } + +func HostRemoveVFlashResource(ctx context.Context, r soap.RoundTripper, req *types.HostRemoveVFlashResource) (*types.HostRemoveVFlashResourceResponse, error) { + var reqBody, resBody HostRemoveVFlashResourceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HttpNfcLeaseAbortBody struct { + Req *types.HttpNfcLeaseAbort `xml:"urn:vim25 HttpNfcLeaseAbort,omitempty"` + Res *types.HttpNfcLeaseAbortResponse `xml:"urn:vim25 HttpNfcLeaseAbortResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HttpNfcLeaseAbortBody) Fault() *soap.Fault { return b.Fault_ } + +func HttpNfcLeaseAbort(ctx context.Context, r soap.RoundTripper, req *types.HttpNfcLeaseAbort) (*types.HttpNfcLeaseAbortResponse, error) { + var reqBody, resBody HttpNfcLeaseAbortBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HttpNfcLeaseCompleteBody struct { + Req *types.HttpNfcLeaseComplete `xml:"urn:vim25 HttpNfcLeaseComplete,omitempty"` + Res *types.HttpNfcLeaseCompleteResponse `xml:"urn:vim25 HttpNfcLeaseCompleteResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HttpNfcLeaseCompleteBody) Fault() *soap.Fault { return b.Fault_ } + +func HttpNfcLeaseComplete(ctx context.Context, r soap.RoundTripper, req *types.HttpNfcLeaseComplete) (*types.HttpNfcLeaseCompleteResponse, error) { + var reqBody, resBody HttpNfcLeaseCompleteBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HttpNfcLeaseGetManifestBody struct { + Req *types.HttpNfcLeaseGetManifest `xml:"urn:vim25 HttpNfcLeaseGetManifest,omitempty"` + Res *types.HttpNfcLeaseGetManifestResponse `xml:"urn:vim25 HttpNfcLeaseGetManifestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HttpNfcLeaseGetManifestBody) Fault() *soap.Fault { return b.Fault_ } + +func HttpNfcLeaseGetManifest(ctx context.Context, r soap.RoundTripper, req *types.HttpNfcLeaseGetManifest) (*types.HttpNfcLeaseGetManifestResponse, error) { + var reqBody, resBody HttpNfcLeaseGetManifestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type HttpNfcLeaseProgressBody struct { + Req *types.HttpNfcLeaseProgress `xml:"urn:vim25 HttpNfcLeaseProgress,omitempty"` + Res *types.HttpNfcLeaseProgressResponse `xml:"urn:vim25 HttpNfcLeaseProgressResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *HttpNfcLeaseProgressBody) Fault() *soap.Fault { return b.Fault_ } + +func HttpNfcLeaseProgress(ctx context.Context, r soap.RoundTripper, req *types.HttpNfcLeaseProgress) (*types.HttpNfcLeaseProgressResponse, error) { + var reqBody, resBody HttpNfcLeaseProgressBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ImpersonateUserBody struct { + Req *types.ImpersonateUser `xml:"urn:vim25 ImpersonateUser,omitempty"` + Res *types.ImpersonateUserResponse `xml:"urn:vim25 ImpersonateUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ImpersonateUserBody) Fault() *soap.Fault { return b.Fault_ } + +func ImpersonateUser(ctx context.Context, r soap.RoundTripper, req *types.ImpersonateUser) (*types.ImpersonateUserResponse, error) { + var reqBody, resBody ImpersonateUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ImportCertificateForCAM_TaskBody struct { + Req *types.ImportCertificateForCAM_Task `xml:"urn:vim25 ImportCertificateForCAM_Task,omitempty"` + Res *types.ImportCertificateForCAM_TaskResponse `xml:"urn:vim25 ImportCertificateForCAM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ImportCertificateForCAM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ImportCertificateForCAM_Task(ctx context.Context, r soap.RoundTripper, req *types.ImportCertificateForCAM_Task) (*types.ImportCertificateForCAM_TaskResponse, error) { + var reqBody, resBody ImportCertificateForCAM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ImportUnmanagedSnapshotBody struct { + Req *types.ImportUnmanagedSnapshot `xml:"urn:vim25 ImportUnmanagedSnapshot,omitempty"` + Res *types.ImportUnmanagedSnapshotResponse `xml:"urn:vim25 ImportUnmanagedSnapshotResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ImportUnmanagedSnapshotBody) Fault() *soap.Fault { return b.Fault_ } + +func ImportUnmanagedSnapshot(ctx context.Context, r soap.RoundTripper, req *types.ImportUnmanagedSnapshot) (*types.ImportUnmanagedSnapshotResponse, error) { + var reqBody, resBody ImportUnmanagedSnapshotBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ImportVAppBody struct { + Req *types.ImportVApp `xml:"urn:vim25 ImportVApp,omitempty"` + Res *types.ImportVAppResponse `xml:"urn:vim25 ImportVAppResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ImportVAppBody) Fault() *soap.Fault { return b.Fault_ } + +func ImportVApp(ctx context.Context, r soap.RoundTripper, req *types.ImportVApp) (*types.ImportVAppResponse, error) { + var reqBody, resBody ImportVAppBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InflateVirtualDisk_TaskBody struct { + Req *types.InflateVirtualDisk_Task `xml:"urn:vim25 InflateVirtualDisk_Task,omitempty"` + Res *types.InflateVirtualDisk_TaskResponse `xml:"urn:vim25 InflateVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InflateVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func InflateVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.InflateVirtualDisk_Task) (*types.InflateVirtualDisk_TaskResponse, error) { + var reqBody, resBody InflateVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InitializeDisks_TaskBody struct { + Req *types.InitializeDisks_Task `xml:"urn:vim25 InitializeDisks_Task,omitempty"` + Res *types.InitializeDisks_TaskResponse `xml:"urn:vim25 InitializeDisks_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InitializeDisks_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func InitializeDisks_Task(ctx context.Context, r soap.RoundTripper, req *types.InitializeDisks_Task) (*types.InitializeDisks_TaskResponse, error) { + var reqBody, resBody InitializeDisks_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InitiateFileTransferFromGuestBody struct { + Req *types.InitiateFileTransferFromGuest `xml:"urn:vim25 InitiateFileTransferFromGuest,omitempty"` + Res *types.InitiateFileTransferFromGuestResponse `xml:"urn:vim25 InitiateFileTransferFromGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InitiateFileTransferFromGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func InitiateFileTransferFromGuest(ctx context.Context, r soap.RoundTripper, req *types.InitiateFileTransferFromGuest) (*types.InitiateFileTransferFromGuestResponse, error) { + var reqBody, resBody InitiateFileTransferFromGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InitiateFileTransferToGuestBody struct { + Req *types.InitiateFileTransferToGuest `xml:"urn:vim25 InitiateFileTransferToGuest,omitempty"` + Res *types.InitiateFileTransferToGuestResponse `xml:"urn:vim25 InitiateFileTransferToGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InitiateFileTransferToGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func InitiateFileTransferToGuest(ctx context.Context, r soap.RoundTripper, req *types.InitiateFileTransferToGuest) (*types.InitiateFileTransferToGuestResponse, error) { + var reqBody, resBody InitiateFileTransferToGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InstallHostPatchV2_TaskBody struct { + Req *types.InstallHostPatchV2_Task `xml:"urn:vim25 InstallHostPatchV2_Task,omitempty"` + Res *types.InstallHostPatchV2_TaskResponse `xml:"urn:vim25 InstallHostPatchV2_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InstallHostPatchV2_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func InstallHostPatchV2_Task(ctx context.Context, r soap.RoundTripper, req *types.InstallHostPatchV2_Task) (*types.InstallHostPatchV2_TaskResponse, error) { + var reqBody, resBody InstallHostPatchV2_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InstallHostPatch_TaskBody struct { + Req *types.InstallHostPatch_Task `xml:"urn:vim25 InstallHostPatch_Task,omitempty"` + Res *types.InstallHostPatch_TaskResponse `xml:"urn:vim25 InstallHostPatch_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InstallHostPatch_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func InstallHostPatch_Task(ctx context.Context, r soap.RoundTripper, req *types.InstallHostPatch_Task) (*types.InstallHostPatch_TaskResponse, error) { + var reqBody, resBody InstallHostPatch_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InstallIoFilter_TaskBody struct { + Req *types.InstallIoFilter_Task `xml:"urn:vim25 InstallIoFilter_Task,omitempty"` + Res *types.InstallIoFilter_TaskResponse `xml:"urn:vim25 InstallIoFilter_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InstallIoFilter_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func InstallIoFilter_Task(ctx context.Context, r soap.RoundTripper, req *types.InstallIoFilter_Task) (*types.InstallIoFilter_TaskResponse, error) { + var reqBody, resBody InstallIoFilter_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InstallServerCertificateBody struct { + Req *types.InstallServerCertificate `xml:"urn:vim25 InstallServerCertificate,omitempty"` + Res *types.InstallServerCertificateResponse `xml:"urn:vim25 InstallServerCertificateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InstallServerCertificateBody) Fault() *soap.Fault { return b.Fault_ } + +func InstallServerCertificate(ctx context.Context, r soap.RoundTripper, req *types.InstallServerCertificate) (*types.InstallServerCertificateResponse, error) { + var reqBody, resBody InstallServerCertificateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type InstallSmartCardTrustAnchorBody struct { + Req *types.InstallSmartCardTrustAnchor `xml:"urn:vim25 InstallSmartCardTrustAnchor,omitempty"` + Res *types.InstallSmartCardTrustAnchorResponse `xml:"urn:vim25 InstallSmartCardTrustAnchorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *InstallSmartCardTrustAnchorBody) Fault() *soap.Fault { return b.Fault_ } + +func InstallSmartCardTrustAnchor(ctx context.Context, r soap.RoundTripper, req *types.InstallSmartCardTrustAnchor) (*types.InstallSmartCardTrustAnchorResponse, error) { + var reqBody, resBody InstallSmartCardTrustAnchorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type IsSharedGraphicsActiveBody struct { + Req *types.IsSharedGraphicsActive `xml:"urn:vim25 IsSharedGraphicsActive,omitempty"` + Res *types.IsSharedGraphicsActiveResponse `xml:"urn:vim25 IsSharedGraphicsActiveResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *IsSharedGraphicsActiveBody) Fault() *soap.Fault { return b.Fault_ } + +func IsSharedGraphicsActive(ctx context.Context, r soap.RoundTripper, req *types.IsSharedGraphicsActive) (*types.IsSharedGraphicsActiveResponse, error) { + var reqBody, resBody IsSharedGraphicsActiveBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type JoinDomainWithCAM_TaskBody struct { + Req *types.JoinDomainWithCAM_Task `xml:"urn:vim25 JoinDomainWithCAM_Task,omitempty"` + Res *types.JoinDomainWithCAM_TaskResponse `xml:"urn:vim25 JoinDomainWithCAM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *JoinDomainWithCAM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func JoinDomainWithCAM_Task(ctx context.Context, r soap.RoundTripper, req *types.JoinDomainWithCAM_Task) (*types.JoinDomainWithCAM_TaskResponse, error) { + var reqBody, resBody JoinDomainWithCAM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type JoinDomain_TaskBody struct { + Req *types.JoinDomain_Task `xml:"urn:vim25 JoinDomain_Task,omitempty"` + Res *types.JoinDomain_TaskResponse `xml:"urn:vim25 JoinDomain_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *JoinDomain_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func JoinDomain_Task(ctx context.Context, r soap.RoundTripper, req *types.JoinDomain_Task) (*types.JoinDomain_TaskResponse, error) { + var reqBody, resBody JoinDomain_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LeaveCurrentDomain_TaskBody struct { + Req *types.LeaveCurrentDomain_Task `xml:"urn:vim25 LeaveCurrentDomain_Task,omitempty"` + Res *types.LeaveCurrentDomain_TaskResponse `xml:"urn:vim25 LeaveCurrentDomain_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LeaveCurrentDomain_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func LeaveCurrentDomain_Task(ctx context.Context, r soap.RoundTripper, req *types.LeaveCurrentDomain_Task) (*types.LeaveCurrentDomain_TaskResponse, error) { + var reqBody, resBody LeaveCurrentDomain_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListCACertificateRevocationListsBody struct { + Req *types.ListCACertificateRevocationLists `xml:"urn:vim25 ListCACertificateRevocationLists,omitempty"` + Res *types.ListCACertificateRevocationListsResponse `xml:"urn:vim25 ListCACertificateRevocationListsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListCACertificateRevocationListsBody) Fault() *soap.Fault { return b.Fault_ } + +func ListCACertificateRevocationLists(ctx context.Context, r soap.RoundTripper, req *types.ListCACertificateRevocationLists) (*types.ListCACertificateRevocationListsResponse, error) { + var reqBody, resBody ListCACertificateRevocationListsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListCACertificatesBody struct { + Req *types.ListCACertificates `xml:"urn:vim25 ListCACertificates,omitempty"` + Res *types.ListCACertificatesResponse `xml:"urn:vim25 ListCACertificatesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListCACertificatesBody) Fault() *soap.Fault { return b.Fault_ } + +func ListCACertificates(ctx context.Context, r soap.RoundTripper, req *types.ListCACertificates) (*types.ListCACertificatesResponse, error) { + var reqBody, resBody ListCACertificatesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListFilesInGuestBody struct { + Req *types.ListFilesInGuest `xml:"urn:vim25 ListFilesInGuest,omitempty"` + Res *types.ListFilesInGuestResponse `xml:"urn:vim25 ListFilesInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListFilesInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ListFilesInGuest(ctx context.Context, r soap.RoundTripper, req *types.ListFilesInGuest) (*types.ListFilesInGuestResponse, error) { + var reqBody, resBody ListFilesInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListGuestAliasesBody struct { + Req *types.ListGuestAliases `xml:"urn:vim25 ListGuestAliases,omitempty"` + Res *types.ListGuestAliasesResponse `xml:"urn:vim25 ListGuestAliasesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListGuestAliasesBody) Fault() *soap.Fault { return b.Fault_ } + +func ListGuestAliases(ctx context.Context, r soap.RoundTripper, req *types.ListGuestAliases) (*types.ListGuestAliasesResponse, error) { + var reqBody, resBody ListGuestAliasesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListGuestMappedAliasesBody struct { + Req *types.ListGuestMappedAliases `xml:"urn:vim25 ListGuestMappedAliases,omitempty"` + Res *types.ListGuestMappedAliasesResponse `xml:"urn:vim25 ListGuestMappedAliasesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListGuestMappedAliasesBody) Fault() *soap.Fault { return b.Fault_ } + +func ListGuestMappedAliases(ctx context.Context, r soap.RoundTripper, req *types.ListGuestMappedAliases) (*types.ListGuestMappedAliasesResponse, error) { + var reqBody, resBody ListGuestMappedAliasesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListProcessesInGuestBody struct { + Req *types.ListProcessesInGuest `xml:"urn:vim25 ListProcessesInGuest,omitempty"` + Res *types.ListProcessesInGuestResponse `xml:"urn:vim25 ListProcessesInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListProcessesInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ListProcessesInGuest(ctx context.Context, r soap.RoundTripper, req *types.ListProcessesInGuest) (*types.ListProcessesInGuestResponse, error) { + var reqBody, resBody ListProcessesInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListRegistryKeysInGuestBody struct { + Req *types.ListRegistryKeysInGuest `xml:"urn:vim25 ListRegistryKeysInGuest,omitempty"` + Res *types.ListRegistryKeysInGuestResponse `xml:"urn:vim25 ListRegistryKeysInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListRegistryKeysInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ListRegistryKeysInGuest(ctx context.Context, r soap.RoundTripper, req *types.ListRegistryKeysInGuest) (*types.ListRegistryKeysInGuestResponse, error) { + var reqBody, resBody ListRegistryKeysInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListRegistryValuesInGuestBody struct { + Req *types.ListRegistryValuesInGuest `xml:"urn:vim25 ListRegistryValuesInGuest,omitempty"` + Res *types.ListRegistryValuesInGuestResponse `xml:"urn:vim25 ListRegistryValuesInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListRegistryValuesInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ListRegistryValuesInGuest(ctx context.Context, r soap.RoundTripper, req *types.ListRegistryValuesInGuest) (*types.ListRegistryValuesInGuestResponse, error) { + var reqBody, resBody ListRegistryValuesInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ListSmartCardTrustAnchorsBody struct { + Req *types.ListSmartCardTrustAnchors `xml:"urn:vim25 ListSmartCardTrustAnchors,omitempty"` + Res *types.ListSmartCardTrustAnchorsResponse `xml:"urn:vim25 ListSmartCardTrustAnchorsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ListSmartCardTrustAnchorsBody) Fault() *soap.Fault { return b.Fault_ } + +func ListSmartCardTrustAnchors(ctx context.Context, r soap.RoundTripper, req *types.ListSmartCardTrustAnchors) (*types.ListSmartCardTrustAnchorsResponse, error) { + var reqBody, resBody ListSmartCardTrustAnchorsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LogUserEventBody struct { + Req *types.LogUserEvent `xml:"urn:vim25 LogUserEvent,omitempty"` + Res *types.LogUserEventResponse `xml:"urn:vim25 LogUserEventResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LogUserEventBody) Fault() *soap.Fault { return b.Fault_ } + +func LogUserEvent(ctx context.Context, r soap.RoundTripper, req *types.LogUserEvent) (*types.LogUserEventResponse, error) { + var reqBody, resBody LogUserEventBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LoginBody struct { + Req *types.Login `xml:"urn:vim25 Login,omitempty"` + Res *types.LoginResponse `xml:"urn:vim25 LoginResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LoginBody) Fault() *soap.Fault { return b.Fault_ } + +func Login(ctx context.Context, r soap.RoundTripper, req *types.Login) (*types.LoginResponse, error) { + var reqBody, resBody LoginBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LoginBySSPIBody struct { + Req *types.LoginBySSPI `xml:"urn:vim25 LoginBySSPI,omitempty"` + Res *types.LoginBySSPIResponse `xml:"urn:vim25 LoginBySSPIResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LoginBySSPIBody) Fault() *soap.Fault { return b.Fault_ } + +func LoginBySSPI(ctx context.Context, r soap.RoundTripper, req *types.LoginBySSPI) (*types.LoginBySSPIResponse, error) { + var reqBody, resBody LoginBySSPIBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LoginByTokenBody struct { + Req *types.LoginByToken `xml:"urn:vim25 LoginByToken,omitempty"` + Res *types.LoginByTokenResponse `xml:"urn:vim25 LoginByTokenResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LoginByTokenBody) Fault() *soap.Fault { return b.Fault_ } + +func LoginByToken(ctx context.Context, r soap.RoundTripper, req *types.LoginByToken) (*types.LoginByTokenResponse, error) { + var reqBody, resBody LoginByTokenBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LoginExtensionByCertificateBody struct { + Req *types.LoginExtensionByCertificate `xml:"urn:vim25 LoginExtensionByCertificate,omitempty"` + Res *types.LoginExtensionByCertificateResponse `xml:"urn:vim25 LoginExtensionByCertificateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LoginExtensionByCertificateBody) Fault() *soap.Fault { return b.Fault_ } + +func LoginExtensionByCertificate(ctx context.Context, r soap.RoundTripper, req *types.LoginExtensionByCertificate) (*types.LoginExtensionByCertificateResponse, error) { + var reqBody, resBody LoginExtensionByCertificateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LoginExtensionBySubjectNameBody struct { + Req *types.LoginExtensionBySubjectName `xml:"urn:vim25 LoginExtensionBySubjectName,omitempty"` + Res *types.LoginExtensionBySubjectNameResponse `xml:"urn:vim25 LoginExtensionBySubjectNameResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LoginExtensionBySubjectNameBody) Fault() *soap.Fault { return b.Fault_ } + +func LoginExtensionBySubjectName(ctx context.Context, r soap.RoundTripper, req *types.LoginExtensionBySubjectName) (*types.LoginExtensionBySubjectNameResponse, error) { + var reqBody, resBody LoginExtensionBySubjectNameBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LogoutBody struct { + Req *types.Logout `xml:"urn:vim25 Logout,omitempty"` + Res *types.LogoutResponse `xml:"urn:vim25 LogoutResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LogoutBody) Fault() *soap.Fault { return b.Fault_ } + +func Logout(ctx context.Context, r soap.RoundTripper, req *types.Logout) (*types.LogoutResponse, error) { + var reqBody, resBody LogoutBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LookupDvPortGroupBody struct { + Req *types.LookupDvPortGroup `xml:"urn:vim25 LookupDvPortGroup,omitempty"` + Res *types.LookupDvPortGroupResponse `xml:"urn:vim25 LookupDvPortGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LookupDvPortGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func LookupDvPortGroup(ctx context.Context, r soap.RoundTripper, req *types.LookupDvPortGroup) (*types.LookupDvPortGroupResponse, error) { + var reqBody, resBody LookupDvPortGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type LookupVmOverheadMemoryBody struct { + Req *types.LookupVmOverheadMemory `xml:"urn:vim25 LookupVmOverheadMemory,omitempty"` + Res *types.LookupVmOverheadMemoryResponse `xml:"urn:vim25 LookupVmOverheadMemoryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *LookupVmOverheadMemoryBody) Fault() *soap.Fault { return b.Fault_ } + +func LookupVmOverheadMemory(ctx context.Context, r soap.RoundTripper, req *types.LookupVmOverheadMemory) (*types.LookupVmOverheadMemoryResponse, error) { + var reqBody, resBody LookupVmOverheadMemoryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MakeDirectoryBody struct { + Req *types.MakeDirectory `xml:"urn:vim25 MakeDirectory,omitempty"` + Res *types.MakeDirectoryResponse `xml:"urn:vim25 MakeDirectoryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MakeDirectoryBody) Fault() *soap.Fault { return b.Fault_ } + +func MakeDirectory(ctx context.Context, r soap.RoundTripper, req *types.MakeDirectory) (*types.MakeDirectoryResponse, error) { + var reqBody, resBody MakeDirectoryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MakeDirectoryInGuestBody struct { + Req *types.MakeDirectoryInGuest `xml:"urn:vim25 MakeDirectoryInGuest,omitempty"` + Res *types.MakeDirectoryInGuestResponse `xml:"urn:vim25 MakeDirectoryInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MakeDirectoryInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func MakeDirectoryInGuest(ctx context.Context, r soap.RoundTripper, req *types.MakeDirectoryInGuest) (*types.MakeDirectoryInGuestResponse, error) { + var reqBody, resBody MakeDirectoryInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MakePrimaryVM_TaskBody struct { + Req *types.MakePrimaryVM_Task `xml:"urn:vim25 MakePrimaryVM_Task,omitempty"` + Res *types.MakePrimaryVM_TaskResponse `xml:"urn:vim25 MakePrimaryVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MakePrimaryVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MakePrimaryVM_Task(ctx context.Context, r soap.RoundTripper, req *types.MakePrimaryVM_Task) (*types.MakePrimaryVM_TaskResponse, error) { + var reqBody, resBody MakePrimaryVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkAsLocal_TaskBody struct { + Req *types.MarkAsLocal_Task `xml:"urn:vim25 MarkAsLocal_Task,omitempty"` + Res *types.MarkAsLocal_TaskResponse `xml:"urn:vim25 MarkAsLocal_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkAsLocal_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkAsLocal_Task(ctx context.Context, r soap.RoundTripper, req *types.MarkAsLocal_Task) (*types.MarkAsLocal_TaskResponse, error) { + var reqBody, resBody MarkAsLocal_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkAsNonLocal_TaskBody struct { + Req *types.MarkAsNonLocal_Task `xml:"urn:vim25 MarkAsNonLocal_Task,omitempty"` + Res *types.MarkAsNonLocal_TaskResponse `xml:"urn:vim25 MarkAsNonLocal_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkAsNonLocal_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkAsNonLocal_Task(ctx context.Context, r soap.RoundTripper, req *types.MarkAsNonLocal_Task) (*types.MarkAsNonLocal_TaskResponse, error) { + var reqBody, resBody MarkAsNonLocal_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkAsNonSsd_TaskBody struct { + Req *types.MarkAsNonSsd_Task `xml:"urn:vim25 MarkAsNonSsd_Task,omitempty"` + Res *types.MarkAsNonSsd_TaskResponse `xml:"urn:vim25 MarkAsNonSsd_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkAsNonSsd_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkAsNonSsd_Task(ctx context.Context, r soap.RoundTripper, req *types.MarkAsNonSsd_Task) (*types.MarkAsNonSsd_TaskResponse, error) { + var reqBody, resBody MarkAsNonSsd_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkAsSsd_TaskBody struct { + Req *types.MarkAsSsd_Task `xml:"urn:vim25 MarkAsSsd_Task,omitempty"` + Res *types.MarkAsSsd_TaskResponse `xml:"urn:vim25 MarkAsSsd_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkAsSsd_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkAsSsd_Task(ctx context.Context, r soap.RoundTripper, req *types.MarkAsSsd_Task) (*types.MarkAsSsd_TaskResponse, error) { + var reqBody, resBody MarkAsSsd_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkAsTemplateBody struct { + Req *types.MarkAsTemplate `xml:"urn:vim25 MarkAsTemplate,omitempty"` + Res *types.MarkAsTemplateResponse `xml:"urn:vim25 MarkAsTemplateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkAsTemplateBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkAsTemplate(ctx context.Context, r soap.RoundTripper, req *types.MarkAsTemplate) (*types.MarkAsTemplateResponse, error) { + var reqBody, resBody MarkAsTemplateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkAsVirtualMachineBody struct { + Req *types.MarkAsVirtualMachine `xml:"urn:vim25 MarkAsVirtualMachine,omitempty"` + Res *types.MarkAsVirtualMachineResponse `xml:"urn:vim25 MarkAsVirtualMachineResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkAsVirtualMachineBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkAsVirtualMachine(ctx context.Context, r soap.RoundTripper, req *types.MarkAsVirtualMachine) (*types.MarkAsVirtualMachineResponse, error) { + var reqBody, resBody MarkAsVirtualMachineBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MarkForRemovalBody struct { + Req *types.MarkForRemoval `xml:"urn:vim25 MarkForRemoval,omitempty"` + Res *types.MarkForRemovalResponse `xml:"urn:vim25 MarkForRemovalResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MarkForRemovalBody) Fault() *soap.Fault { return b.Fault_ } + +func MarkForRemoval(ctx context.Context, r soap.RoundTripper, req *types.MarkForRemoval) (*types.MarkForRemovalResponse, error) { + var reqBody, resBody MarkForRemovalBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MergeDvs_TaskBody struct { + Req *types.MergeDvs_Task `xml:"urn:vim25 MergeDvs_Task,omitempty"` + Res *types.MergeDvs_TaskResponse `xml:"urn:vim25 MergeDvs_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MergeDvs_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MergeDvs_Task(ctx context.Context, r soap.RoundTripper, req *types.MergeDvs_Task) (*types.MergeDvs_TaskResponse, error) { + var reqBody, resBody MergeDvs_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MergePermissionsBody struct { + Req *types.MergePermissions `xml:"urn:vim25 MergePermissions,omitempty"` + Res *types.MergePermissionsResponse `xml:"urn:vim25 MergePermissionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MergePermissionsBody) Fault() *soap.Fault { return b.Fault_ } + +func MergePermissions(ctx context.Context, r soap.RoundTripper, req *types.MergePermissions) (*types.MergePermissionsResponse, error) { + var reqBody, resBody MergePermissionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MigrateVM_TaskBody struct { + Req *types.MigrateVM_Task `xml:"urn:vim25 MigrateVM_Task,omitempty"` + Res *types.MigrateVM_TaskResponse `xml:"urn:vim25 MigrateVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MigrateVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MigrateVM_Task(ctx context.Context, r soap.RoundTripper, req *types.MigrateVM_Task) (*types.MigrateVM_TaskResponse, error) { + var reqBody, resBody MigrateVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ModifyListViewBody struct { + Req *types.ModifyListView `xml:"urn:vim25 ModifyListView,omitempty"` + Res *types.ModifyListViewResponse `xml:"urn:vim25 ModifyListViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ModifyListViewBody) Fault() *soap.Fault { return b.Fault_ } + +func ModifyListView(ctx context.Context, r soap.RoundTripper, req *types.ModifyListView) (*types.ModifyListViewResponse, error) { + var reqBody, resBody ModifyListViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MountToolsInstallerBody struct { + Req *types.MountToolsInstaller `xml:"urn:vim25 MountToolsInstaller,omitempty"` + Res *types.MountToolsInstallerResponse `xml:"urn:vim25 MountToolsInstallerResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MountToolsInstallerBody) Fault() *soap.Fault { return b.Fault_ } + +func MountToolsInstaller(ctx context.Context, r soap.RoundTripper, req *types.MountToolsInstaller) (*types.MountToolsInstallerResponse, error) { + var reqBody, resBody MountToolsInstallerBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MountVffsVolumeBody struct { + Req *types.MountVffsVolume `xml:"urn:vim25 MountVffsVolume,omitempty"` + Res *types.MountVffsVolumeResponse `xml:"urn:vim25 MountVffsVolumeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MountVffsVolumeBody) Fault() *soap.Fault { return b.Fault_ } + +func MountVffsVolume(ctx context.Context, r soap.RoundTripper, req *types.MountVffsVolume) (*types.MountVffsVolumeResponse, error) { + var reqBody, resBody MountVffsVolumeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MountVmfsVolumeBody struct { + Req *types.MountVmfsVolume `xml:"urn:vim25 MountVmfsVolume,omitempty"` + Res *types.MountVmfsVolumeResponse `xml:"urn:vim25 MountVmfsVolumeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MountVmfsVolumeBody) Fault() *soap.Fault { return b.Fault_ } + +func MountVmfsVolume(ctx context.Context, r soap.RoundTripper, req *types.MountVmfsVolume) (*types.MountVmfsVolumeResponse, error) { + var reqBody, resBody MountVmfsVolumeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MountVmfsVolumeEx_TaskBody struct { + Req *types.MountVmfsVolumeEx_Task `xml:"urn:vim25 MountVmfsVolumeEx_Task,omitempty"` + Res *types.MountVmfsVolumeEx_TaskResponse `xml:"urn:vim25 MountVmfsVolumeEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MountVmfsVolumeEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MountVmfsVolumeEx_Task(ctx context.Context, r soap.RoundTripper, req *types.MountVmfsVolumeEx_Task) (*types.MountVmfsVolumeEx_TaskResponse, error) { + var reqBody, resBody MountVmfsVolumeEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveDVPort_TaskBody struct { + Req *types.MoveDVPort_Task `xml:"urn:vim25 MoveDVPort_Task,omitempty"` + Res *types.MoveDVPort_TaskResponse `xml:"urn:vim25 MoveDVPort_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveDVPort_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveDVPort_Task(ctx context.Context, r soap.RoundTripper, req *types.MoveDVPort_Task) (*types.MoveDVPort_TaskResponse, error) { + var reqBody, resBody MoveDVPort_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveDatastoreFile_TaskBody struct { + Req *types.MoveDatastoreFile_Task `xml:"urn:vim25 MoveDatastoreFile_Task,omitempty"` + Res *types.MoveDatastoreFile_TaskResponse `xml:"urn:vim25 MoveDatastoreFile_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveDatastoreFile_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveDatastoreFile_Task(ctx context.Context, r soap.RoundTripper, req *types.MoveDatastoreFile_Task) (*types.MoveDatastoreFile_TaskResponse, error) { + var reqBody, resBody MoveDatastoreFile_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveDirectoryInGuestBody struct { + Req *types.MoveDirectoryInGuest `xml:"urn:vim25 MoveDirectoryInGuest,omitempty"` + Res *types.MoveDirectoryInGuestResponse `xml:"urn:vim25 MoveDirectoryInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveDirectoryInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveDirectoryInGuest(ctx context.Context, r soap.RoundTripper, req *types.MoveDirectoryInGuest) (*types.MoveDirectoryInGuestResponse, error) { + var reqBody, resBody MoveDirectoryInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveFileInGuestBody struct { + Req *types.MoveFileInGuest `xml:"urn:vim25 MoveFileInGuest,omitempty"` + Res *types.MoveFileInGuestResponse `xml:"urn:vim25 MoveFileInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveFileInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveFileInGuest(ctx context.Context, r soap.RoundTripper, req *types.MoveFileInGuest) (*types.MoveFileInGuestResponse, error) { + var reqBody, resBody MoveFileInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveHostInto_TaskBody struct { + Req *types.MoveHostInto_Task `xml:"urn:vim25 MoveHostInto_Task,omitempty"` + Res *types.MoveHostInto_TaskResponse `xml:"urn:vim25 MoveHostInto_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveHostInto_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveHostInto_Task(ctx context.Context, r soap.RoundTripper, req *types.MoveHostInto_Task) (*types.MoveHostInto_TaskResponse, error) { + var reqBody, resBody MoveHostInto_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveIntoFolder_TaskBody struct { + Req *types.MoveIntoFolder_Task `xml:"urn:vim25 MoveIntoFolder_Task,omitempty"` + Res *types.MoveIntoFolder_TaskResponse `xml:"urn:vim25 MoveIntoFolder_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveIntoFolder_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveIntoFolder_Task(ctx context.Context, r soap.RoundTripper, req *types.MoveIntoFolder_Task) (*types.MoveIntoFolder_TaskResponse, error) { + var reqBody, resBody MoveIntoFolder_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveIntoResourcePoolBody struct { + Req *types.MoveIntoResourcePool `xml:"urn:vim25 MoveIntoResourcePool,omitempty"` + Res *types.MoveIntoResourcePoolResponse `xml:"urn:vim25 MoveIntoResourcePoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveIntoResourcePoolBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveIntoResourcePool(ctx context.Context, r soap.RoundTripper, req *types.MoveIntoResourcePool) (*types.MoveIntoResourcePoolResponse, error) { + var reqBody, resBody MoveIntoResourcePoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveInto_TaskBody struct { + Req *types.MoveInto_Task `xml:"urn:vim25 MoveInto_Task,omitempty"` + Res *types.MoveInto_TaskResponse `xml:"urn:vim25 MoveInto_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveInto_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveInto_Task(ctx context.Context, r soap.RoundTripper, req *types.MoveInto_Task) (*types.MoveInto_TaskResponse, error) { + var reqBody, resBody MoveInto_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type MoveVirtualDisk_TaskBody struct { + Req *types.MoveVirtualDisk_Task `xml:"urn:vim25 MoveVirtualDisk_Task,omitempty"` + Res *types.MoveVirtualDisk_TaskResponse `xml:"urn:vim25 MoveVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *MoveVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func MoveVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.MoveVirtualDisk_Task) (*types.MoveVirtualDisk_TaskResponse, error) { + var reqBody, resBody MoveVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type OpenInventoryViewFolderBody struct { + Req *types.OpenInventoryViewFolder `xml:"urn:vim25 OpenInventoryViewFolder,omitempty"` + Res *types.OpenInventoryViewFolderResponse `xml:"urn:vim25 OpenInventoryViewFolderResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *OpenInventoryViewFolderBody) Fault() *soap.Fault { return b.Fault_ } + +func OpenInventoryViewFolder(ctx context.Context, r soap.RoundTripper, req *types.OpenInventoryViewFolder) (*types.OpenInventoryViewFolderResponse, error) { + var reqBody, resBody OpenInventoryViewFolderBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type OverwriteCustomizationSpecBody struct { + Req *types.OverwriteCustomizationSpec `xml:"urn:vim25 OverwriteCustomizationSpec,omitempty"` + Res *types.OverwriteCustomizationSpecResponse `xml:"urn:vim25 OverwriteCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *OverwriteCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func OverwriteCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.OverwriteCustomizationSpec) (*types.OverwriteCustomizationSpecResponse, error) { + var reqBody, resBody OverwriteCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ParseDescriptorBody struct { + Req *types.ParseDescriptor `xml:"urn:vim25 ParseDescriptor,omitempty"` + Res *types.ParseDescriptorResponse `xml:"urn:vim25 ParseDescriptorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ParseDescriptorBody) Fault() *soap.Fault { return b.Fault_ } + +func ParseDescriptor(ctx context.Context, r soap.RoundTripper, req *types.ParseDescriptor) (*types.ParseDescriptorResponse, error) { + var reqBody, resBody ParseDescriptorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PerformDvsProductSpecOperation_TaskBody struct { + Req *types.PerformDvsProductSpecOperation_Task `xml:"urn:vim25 PerformDvsProductSpecOperation_Task,omitempty"` + Res *types.PerformDvsProductSpecOperation_TaskResponse `xml:"urn:vim25 PerformDvsProductSpecOperation_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PerformDvsProductSpecOperation_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PerformDvsProductSpecOperation_Task(ctx context.Context, r soap.RoundTripper, req *types.PerformDvsProductSpecOperation_Task) (*types.PerformDvsProductSpecOperation_TaskResponse, error) { + var reqBody, resBody PerformDvsProductSpecOperation_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PerformVsanUpgradePreflightCheckBody struct { + Req *types.PerformVsanUpgradePreflightCheck `xml:"urn:vim25 PerformVsanUpgradePreflightCheck,omitempty"` + Res *types.PerformVsanUpgradePreflightCheckResponse `xml:"urn:vim25 PerformVsanUpgradePreflightCheckResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PerformVsanUpgradePreflightCheckBody) Fault() *soap.Fault { return b.Fault_ } + +func PerformVsanUpgradePreflightCheck(ctx context.Context, r soap.RoundTripper, req *types.PerformVsanUpgradePreflightCheck) (*types.PerformVsanUpgradePreflightCheckResponse, error) { + var reqBody, resBody PerformVsanUpgradePreflightCheckBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PerformVsanUpgrade_TaskBody struct { + Req *types.PerformVsanUpgrade_Task `xml:"urn:vim25 PerformVsanUpgrade_Task,omitempty"` + Res *types.PerformVsanUpgrade_TaskResponse `xml:"urn:vim25 PerformVsanUpgrade_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PerformVsanUpgrade_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PerformVsanUpgrade_Task(ctx context.Context, r soap.RoundTripper, req *types.PerformVsanUpgrade_Task) (*types.PerformVsanUpgrade_TaskResponse, error) { + var reqBody, resBody PerformVsanUpgrade_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PlaceVmBody struct { + Req *types.PlaceVm `xml:"urn:vim25 PlaceVm,omitempty"` + Res *types.PlaceVmResponse `xml:"urn:vim25 PlaceVmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PlaceVmBody) Fault() *soap.Fault { return b.Fault_ } + +func PlaceVm(ctx context.Context, r soap.RoundTripper, req *types.PlaceVm) (*types.PlaceVmResponse, error) { + var reqBody, resBody PlaceVmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PostEventBody struct { + Req *types.PostEvent `xml:"urn:vim25 PostEvent,omitempty"` + Res *types.PostEventResponse `xml:"urn:vim25 PostEventResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PostEventBody) Fault() *soap.Fault { return b.Fault_ } + +func PostEvent(ctx context.Context, r soap.RoundTripper, req *types.PostEvent) (*types.PostEventResponse, error) { + var reqBody, resBody PostEventBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerDownHostToStandBy_TaskBody struct { + Req *types.PowerDownHostToStandBy_Task `xml:"urn:vim25 PowerDownHostToStandBy_Task,omitempty"` + Res *types.PowerDownHostToStandBy_TaskResponse `xml:"urn:vim25 PowerDownHostToStandBy_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerDownHostToStandBy_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerDownHostToStandBy_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerDownHostToStandBy_Task) (*types.PowerDownHostToStandBy_TaskResponse, error) { + var reqBody, resBody PowerDownHostToStandBy_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerOffVApp_TaskBody struct { + Req *types.PowerOffVApp_Task `xml:"urn:vim25 PowerOffVApp_Task,omitempty"` + Res *types.PowerOffVApp_TaskResponse `xml:"urn:vim25 PowerOffVApp_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerOffVApp_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerOffVApp_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerOffVApp_Task) (*types.PowerOffVApp_TaskResponse, error) { + var reqBody, resBody PowerOffVApp_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerOffVM_TaskBody struct { + Req *types.PowerOffVM_Task `xml:"urn:vim25 PowerOffVM_Task,omitempty"` + Res *types.PowerOffVM_TaskResponse `xml:"urn:vim25 PowerOffVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerOffVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerOffVM_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerOffVM_Task) (*types.PowerOffVM_TaskResponse, error) { + var reqBody, resBody PowerOffVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerOnMultiVM_TaskBody struct { + Req *types.PowerOnMultiVM_Task `xml:"urn:vim25 PowerOnMultiVM_Task,omitempty"` + Res *types.PowerOnMultiVM_TaskResponse `xml:"urn:vim25 PowerOnMultiVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerOnMultiVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerOnMultiVM_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerOnMultiVM_Task) (*types.PowerOnMultiVM_TaskResponse, error) { + var reqBody, resBody PowerOnMultiVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerOnVApp_TaskBody struct { + Req *types.PowerOnVApp_Task `xml:"urn:vim25 PowerOnVApp_Task,omitempty"` + Res *types.PowerOnVApp_TaskResponse `xml:"urn:vim25 PowerOnVApp_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerOnVApp_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerOnVApp_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerOnVApp_Task) (*types.PowerOnVApp_TaskResponse, error) { + var reqBody, resBody PowerOnVApp_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerOnVM_TaskBody struct { + Req *types.PowerOnVM_Task `xml:"urn:vim25 PowerOnVM_Task,omitempty"` + Res *types.PowerOnVM_TaskResponse `xml:"urn:vim25 PowerOnVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerOnVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerOnVM_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerOnVM_Task) (*types.PowerOnVM_TaskResponse, error) { + var reqBody, resBody PowerOnVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PowerUpHostFromStandBy_TaskBody struct { + Req *types.PowerUpHostFromStandBy_Task `xml:"urn:vim25 PowerUpHostFromStandBy_Task,omitempty"` + Res *types.PowerUpHostFromStandBy_TaskResponse `xml:"urn:vim25 PowerUpHostFromStandBy_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PowerUpHostFromStandBy_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PowerUpHostFromStandBy_Task(ctx context.Context, r soap.RoundTripper, req *types.PowerUpHostFromStandBy_Task) (*types.PowerUpHostFromStandBy_TaskResponse, error) { + var reqBody, resBody PowerUpHostFromStandBy_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type PromoteDisks_TaskBody struct { + Req *types.PromoteDisks_Task `xml:"urn:vim25 PromoteDisks_Task,omitempty"` + Res *types.PromoteDisks_TaskResponse `xml:"urn:vim25 PromoteDisks_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *PromoteDisks_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func PromoteDisks_Task(ctx context.Context, r soap.RoundTripper, req *types.PromoteDisks_Task) (*types.PromoteDisks_TaskResponse, error) { + var reqBody, resBody PromoteDisks_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAnswerFileStatusBody struct { + Req *types.QueryAnswerFileStatus `xml:"urn:vim25 QueryAnswerFileStatus,omitempty"` + Res *types.QueryAnswerFileStatusResponse `xml:"urn:vim25 QueryAnswerFileStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAnswerFileStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAnswerFileStatus(ctx context.Context, r soap.RoundTripper, req *types.QueryAnswerFileStatus) (*types.QueryAnswerFileStatusResponse, error) { + var reqBody, resBody QueryAnswerFileStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAssignedLicensesBody struct { + Req *types.QueryAssignedLicenses `xml:"urn:vim25 QueryAssignedLicenses,omitempty"` + Res *types.QueryAssignedLicensesResponse `xml:"urn:vim25 QueryAssignedLicensesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAssignedLicensesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAssignedLicenses(ctx context.Context, r soap.RoundTripper, req *types.QueryAssignedLicenses) (*types.QueryAssignedLicensesResponse, error) { + var reqBody, resBody QueryAssignedLicensesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAvailableDisksForVmfsBody struct { + Req *types.QueryAvailableDisksForVmfs `xml:"urn:vim25 QueryAvailableDisksForVmfs,omitempty"` + Res *types.QueryAvailableDisksForVmfsResponse `xml:"urn:vim25 QueryAvailableDisksForVmfsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAvailableDisksForVmfsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAvailableDisksForVmfs(ctx context.Context, r soap.RoundTripper, req *types.QueryAvailableDisksForVmfs) (*types.QueryAvailableDisksForVmfsResponse, error) { + var reqBody, resBody QueryAvailableDisksForVmfsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAvailableDvsSpecBody struct { + Req *types.QueryAvailableDvsSpec `xml:"urn:vim25 QueryAvailableDvsSpec,omitempty"` + Res *types.QueryAvailableDvsSpecResponse `xml:"urn:vim25 QueryAvailableDvsSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAvailableDvsSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAvailableDvsSpec(ctx context.Context, r soap.RoundTripper, req *types.QueryAvailableDvsSpec) (*types.QueryAvailableDvsSpecResponse, error) { + var reqBody, resBody QueryAvailableDvsSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAvailablePartitionBody struct { + Req *types.QueryAvailablePartition `xml:"urn:vim25 QueryAvailablePartition,omitempty"` + Res *types.QueryAvailablePartitionResponse `xml:"urn:vim25 QueryAvailablePartitionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAvailablePartitionBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAvailablePartition(ctx context.Context, r soap.RoundTripper, req *types.QueryAvailablePartition) (*types.QueryAvailablePartitionResponse, error) { + var reqBody, resBody QueryAvailablePartitionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAvailablePerfMetricBody struct { + Req *types.QueryAvailablePerfMetric `xml:"urn:vim25 QueryAvailablePerfMetric,omitempty"` + Res *types.QueryAvailablePerfMetricResponse `xml:"urn:vim25 QueryAvailablePerfMetricResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAvailablePerfMetricBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAvailablePerfMetric(ctx context.Context, r soap.RoundTripper, req *types.QueryAvailablePerfMetric) (*types.QueryAvailablePerfMetricResponse, error) { + var reqBody, resBody QueryAvailablePerfMetricBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAvailableSsdsBody struct { + Req *types.QueryAvailableSsds `xml:"urn:vim25 QueryAvailableSsds,omitempty"` + Res *types.QueryAvailableSsdsResponse `xml:"urn:vim25 QueryAvailableSsdsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAvailableSsdsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAvailableSsds(ctx context.Context, r soap.RoundTripper, req *types.QueryAvailableSsds) (*types.QueryAvailableSsdsResponse, error) { + var reqBody, resBody QueryAvailableSsdsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryAvailableTimeZonesBody struct { + Req *types.QueryAvailableTimeZones `xml:"urn:vim25 QueryAvailableTimeZones,omitempty"` + Res *types.QueryAvailableTimeZonesResponse `xml:"urn:vim25 QueryAvailableTimeZonesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryAvailableTimeZonesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryAvailableTimeZones(ctx context.Context, r soap.RoundTripper, req *types.QueryAvailableTimeZones) (*types.QueryAvailableTimeZonesResponse, error) { + var reqBody, resBody QueryAvailableTimeZonesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryBootDevicesBody struct { + Req *types.QueryBootDevices `xml:"urn:vim25 QueryBootDevices,omitempty"` + Res *types.QueryBootDevicesResponse `xml:"urn:vim25 QueryBootDevicesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryBootDevicesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryBootDevices(ctx context.Context, r soap.RoundTripper, req *types.QueryBootDevices) (*types.QueryBootDevicesResponse, error) { + var reqBody, resBody QueryBootDevicesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryBoundVnicsBody struct { + Req *types.QueryBoundVnics `xml:"urn:vim25 QueryBoundVnics,omitempty"` + Res *types.QueryBoundVnicsResponse `xml:"urn:vim25 QueryBoundVnicsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryBoundVnicsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryBoundVnics(ctx context.Context, r soap.RoundTripper, req *types.QueryBoundVnics) (*types.QueryBoundVnicsResponse, error) { + var reqBody, resBody QueryBoundVnicsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryCandidateNicsBody struct { + Req *types.QueryCandidateNics `xml:"urn:vim25 QueryCandidateNics,omitempty"` + Res *types.QueryCandidateNicsResponse `xml:"urn:vim25 QueryCandidateNicsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryCandidateNicsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryCandidateNics(ctx context.Context, r soap.RoundTripper, req *types.QueryCandidateNics) (*types.QueryCandidateNicsResponse, error) { + var reqBody, resBody QueryCandidateNicsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryChangedDiskAreasBody struct { + Req *types.QueryChangedDiskAreas `xml:"urn:vim25 QueryChangedDiskAreas,omitempty"` + Res *types.QueryChangedDiskAreasResponse `xml:"urn:vim25 QueryChangedDiskAreasResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryChangedDiskAreasBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryChangedDiskAreas(ctx context.Context, r soap.RoundTripper, req *types.QueryChangedDiskAreas) (*types.QueryChangedDiskAreasResponse, error) { + var reqBody, resBody QueryChangedDiskAreasBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryCmmdsBody struct { + Req *types.QueryCmmds `xml:"urn:vim25 QueryCmmds,omitempty"` + Res *types.QueryCmmdsResponse `xml:"urn:vim25 QueryCmmdsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryCmmdsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryCmmds(ctx context.Context, r soap.RoundTripper, req *types.QueryCmmds) (*types.QueryCmmdsResponse, error) { + var reqBody, resBody QueryCmmdsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryCompatibleHostForExistingDvsBody struct { + Req *types.QueryCompatibleHostForExistingDvs `xml:"urn:vim25 QueryCompatibleHostForExistingDvs,omitempty"` + Res *types.QueryCompatibleHostForExistingDvsResponse `xml:"urn:vim25 QueryCompatibleHostForExistingDvsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryCompatibleHostForExistingDvsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryCompatibleHostForExistingDvs(ctx context.Context, r soap.RoundTripper, req *types.QueryCompatibleHostForExistingDvs) (*types.QueryCompatibleHostForExistingDvsResponse, error) { + var reqBody, resBody QueryCompatibleHostForExistingDvsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryCompatibleHostForNewDvsBody struct { + Req *types.QueryCompatibleHostForNewDvs `xml:"urn:vim25 QueryCompatibleHostForNewDvs,omitempty"` + Res *types.QueryCompatibleHostForNewDvsResponse `xml:"urn:vim25 QueryCompatibleHostForNewDvsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryCompatibleHostForNewDvsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryCompatibleHostForNewDvs(ctx context.Context, r soap.RoundTripper, req *types.QueryCompatibleHostForNewDvs) (*types.QueryCompatibleHostForNewDvsResponse, error) { + var reqBody, resBody QueryCompatibleHostForNewDvsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryComplianceStatusBody struct { + Req *types.QueryComplianceStatus `xml:"urn:vim25 QueryComplianceStatus,omitempty"` + Res *types.QueryComplianceStatusResponse `xml:"urn:vim25 QueryComplianceStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryComplianceStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryComplianceStatus(ctx context.Context, r soap.RoundTripper, req *types.QueryComplianceStatus) (*types.QueryComplianceStatusResponse, error) { + var reqBody, resBody QueryComplianceStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConfigOptionBody struct { + Req *types.QueryConfigOption `xml:"urn:vim25 QueryConfigOption,omitempty"` + Res *types.QueryConfigOptionResponse `xml:"urn:vim25 QueryConfigOptionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConfigOptionBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConfigOption(ctx context.Context, r soap.RoundTripper, req *types.QueryConfigOption) (*types.QueryConfigOptionResponse, error) { + var reqBody, resBody QueryConfigOptionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConfigOptionDescriptorBody struct { + Req *types.QueryConfigOptionDescriptor `xml:"urn:vim25 QueryConfigOptionDescriptor,omitempty"` + Res *types.QueryConfigOptionDescriptorResponse `xml:"urn:vim25 QueryConfigOptionDescriptorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConfigOptionDescriptorBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConfigOptionDescriptor(ctx context.Context, r soap.RoundTripper, req *types.QueryConfigOptionDescriptor) (*types.QueryConfigOptionDescriptorResponse, error) { + var reqBody, resBody QueryConfigOptionDescriptorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConfigOptionExBody struct { + Req *types.QueryConfigOptionEx `xml:"urn:vim25 QueryConfigOptionEx,omitempty"` + Res *types.QueryConfigOptionExResponse `xml:"urn:vim25 QueryConfigOptionExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConfigOptionExBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConfigOptionEx(ctx context.Context, r soap.RoundTripper, req *types.QueryConfigOptionEx) (*types.QueryConfigOptionExResponse, error) { + var reqBody, resBody QueryConfigOptionExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConfigTargetBody struct { + Req *types.QueryConfigTarget `xml:"urn:vim25 QueryConfigTarget,omitempty"` + Res *types.QueryConfigTargetResponse `xml:"urn:vim25 QueryConfigTargetResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConfigTargetBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConfigTarget(ctx context.Context, r soap.RoundTripper, req *types.QueryConfigTarget) (*types.QueryConfigTargetResponse, error) { + var reqBody, resBody QueryConfigTargetBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConfiguredModuleOptionStringBody struct { + Req *types.QueryConfiguredModuleOptionString `xml:"urn:vim25 QueryConfiguredModuleOptionString,omitempty"` + Res *types.QueryConfiguredModuleOptionStringResponse `xml:"urn:vim25 QueryConfiguredModuleOptionStringResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConfiguredModuleOptionStringBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConfiguredModuleOptionString(ctx context.Context, r soap.RoundTripper, req *types.QueryConfiguredModuleOptionString) (*types.QueryConfiguredModuleOptionStringResponse, error) { + var reqBody, resBody QueryConfiguredModuleOptionStringBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConnectionInfoBody struct { + Req *types.QueryConnectionInfo `xml:"urn:vim25 QueryConnectionInfo,omitempty"` + Res *types.QueryConnectionInfoResponse `xml:"urn:vim25 QueryConnectionInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConnectionInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConnectionInfo(ctx context.Context, r soap.RoundTripper, req *types.QueryConnectionInfo) (*types.QueryConnectionInfoResponse, error) { + var reqBody, resBody QueryConnectionInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryConnectionInfoViaSpecBody struct { + Req *types.QueryConnectionInfoViaSpec `xml:"urn:vim25 QueryConnectionInfoViaSpec,omitempty"` + Res *types.QueryConnectionInfoViaSpecResponse `xml:"urn:vim25 QueryConnectionInfoViaSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryConnectionInfoViaSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryConnectionInfoViaSpec(ctx context.Context, r soap.RoundTripper, req *types.QueryConnectionInfoViaSpec) (*types.QueryConnectionInfoViaSpecResponse, error) { + var reqBody, resBody QueryConnectionInfoViaSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDatastorePerformanceSummaryBody struct { + Req *types.QueryDatastorePerformanceSummary `xml:"urn:vim25 QueryDatastorePerformanceSummary,omitempty"` + Res *types.QueryDatastorePerformanceSummaryResponse `xml:"urn:vim25 QueryDatastorePerformanceSummaryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDatastorePerformanceSummaryBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDatastorePerformanceSummary(ctx context.Context, r soap.RoundTripper, req *types.QueryDatastorePerformanceSummary) (*types.QueryDatastorePerformanceSummaryResponse, error) { + var reqBody, resBody QueryDatastorePerformanceSummaryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDateTimeBody struct { + Req *types.QueryDateTime `xml:"urn:vim25 QueryDateTime,omitempty"` + Res *types.QueryDateTimeResponse `xml:"urn:vim25 QueryDateTimeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDateTimeBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDateTime(ctx context.Context, r soap.RoundTripper, req *types.QueryDateTime) (*types.QueryDateTimeResponse, error) { + var reqBody, resBody QueryDateTimeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDescriptionsBody struct { + Req *types.QueryDescriptions `xml:"urn:vim25 QueryDescriptions,omitempty"` + Res *types.QueryDescriptionsResponse `xml:"urn:vim25 QueryDescriptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDescriptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDescriptions(ctx context.Context, r soap.RoundTripper, req *types.QueryDescriptions) (*types.QueryDescriptionsResponse, error) { + var reqBody, resBody QueryDescriptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDisksForVsanBody struct { + Req *types.QueryDisksForVsan `xml:"urn:vim25 QueryDisksForVsan,omitempty"` + Res *types.QueryDisksForVsanResponse `xml:"urn:vim25 QueryDisksForVsanResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDisksForVsanBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDisksForVsan(ctx context.Context, r soap.RoundTripper, req *types.QueryDisksForVsan) (*types.QueryDisksForVsanResponse, error) { + var reqBody, resBody QueryDisksForVsanBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDisksUsingFilterBody struct { + Req *types.QueryDisksUsingFilter `xml:"urn:vim25 QueryDisksUsingFilter,omitempty"` + Res *types.QueryDisksUsingFilterResponse `xml:"urn:vim25 QueryDisksUsingFilterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDisksUsingFilterBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDisksUsingFilter(ctx context.Context, r soap.RoundTripper, req *types.QueryDisksUsingFilter) (*types.QueryDisksUsingFilterResponse, error) { + var reqBody, resBody QueryDisksUsingFilterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDvsByUuidBody struct { + Req *types.QueryDvsByUuid `xml:"urn:vim25 QueryDvsByUuid,omitempty"` + Res *types.QueryDvsByUuidResponse `xml:"urn:vim25 QueryDvsByUuidResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDvsByUuidBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDvsByUuid(ctx context.Context, r soap.RoundTripper, req *types.QueryDvsByUuid) (*types.QueryDvsByUuidResponse, error) { + var reqBody, resBody QueryDvsByUuidBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDvsCheckCompatibilityBody struct { + Req *types.QueryDvsCheckCompatibility `xml:"urn:vim25 QueryDvsCheckCompatibility,omitempty"` + Res *types.QueryDvsCheckCompatibilityResponse `xml:"urn:vim25 QueryDvsCheckCompatibilityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDvsCheckCompatibilityBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDvsCheckCompatibility(ctx context.Context, r soap.RoundTripper, req *types.QueryDvsCheckCompatibility) (*types.QueryDvsCheckCompatibilityResponse, error) { + var reqBody, resBody QueryDvsCheckCompatibilityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDvsCompatibleHostSpecBody struct { + Req *types.QueryDvsCompatibleHostSpec `xml:"urn:vim25 QueryDvsCompatibleHostSpec,omitempty"` + Res *types.QueryDvsCompatibleHostSpecResponse `xml:"urn:vim25 QueryDvsCompatibleHostSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDvsCompatibleHostSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDvsCompatibleHostSpec(ctx context.Context, r soap.RoundTripper, req *types.QueryDvsCompatibleHostSpec) (*types.QueryDvsCompatibleHostSpecResponse, error) { + var reqBody, resBody QueryDvsCompatibleHostSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDvsConfigTargetBody struct { + Req *types.QueryDvsConfigTarget `xml:"urn:vim25 QueryDvsConfigTarget,omitempty"` + Res *types.QueryDvsConfigTargetResponse `xml:"urn:vim25 QueryDvsConfigTargetResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDvsConfigTargetBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDvsConfigTarget(ctx context.Context, r soap.RoundTripper, req *types.QueryDvsConfigTarget) (*types.QueryDvsConfigTargetResponse, error) { + var reqBody, resBody QueryDvsConfigTargetBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryDvsFeatureCapabilityBody struct { + Req *types.QueryDvsFeatureCapability `xml:"urn:vim25 QueryDvsFeatureCapability,omitempty"` + Res *types.QueryDvsFeatureCapabilityResponse `xml:"urn:vim25 QueryDvsFeatureCapabilityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryDvsFeatureCapabilityBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryDvsFeatureCapability(ctx context.Context, r soap.RoundTripper, req *types.QueryDvsFeatureCapability) (*types.QueryDvsFeatureCapabilityResponse, error) { + var reqBody, resBody QueryDvsFeatureCapabilityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryEventsBody struct { + Req *types.QueryEvents `xml:"urn:vim25 QueryEvents,omitempty"` + Res *types.QueryEventsResponse `xml:"urn:vim25 QueryEventsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryEventsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryEvents(ctx context.Context, r soap.RoundTripper, req *types.QueryEvents) (*types.QueryEventsResponse, error) { + var reqBody, resBody QueryEventsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryExpressionMetadataBody struct { + Req *types.QueryExpressionMetadata `xml:"urn:vim25 QueryExpressionMetadata,omitempty"` + Res *types.QueryExpressionMetadataResponse `xml:"urn:vim25 QueryExpressionMetadataResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryExpressionMetadataBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryExpressionMetadata(ctx context.Context, r soap.RoundTripper, req *types.QueryExpressionMetadata) (*types.QueryExpressionMetadataResponse, error) { + var reqBody, resBody QueryExpressionMetadataBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryExtensionIpAllocationUsageBody struct { + Req *types.QueryExtensionIpAllocationUsage `xml:"urn:vim25 QueryExtensionIpAllocationUsage,omitempty"` + Res *types.QueryExtensionIpAllocationUsageResponse `xml:"urn:vim25 QueryExtensionIpAllocationUsageResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryExtensionIpAllocationUsageBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryExtensionIpAllocationUsage(ctx context.Context, r soap.RoundTripper, req *types.QueryExtensionIpAllocationUsage) (*types.QueryExtensionIpAllocationUsageResponse, error) { + var reqBody, resBody QueryExtensionIpAllocationUsageBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryFaultToleranceCompatibilityBody struct { + Req *types.QueryFaultToleranceCompatibility `xml:"urn:vim25 QueryFaultToleranceCompatibility,omitempty"` + Res *types.QueryFaultToleranceCompatibilityResponse `xml:"urn:vim25 QueryFaultToleranceCompatibilityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryFaultToleranceCompatibilityBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryFaultToleranceCompatibility(ctx context.Context, r soap.RoundTripper, req *types.QueryFaultToleranceCompatibility) (*types.QueryFaultToleranceCompatibilityResponse, error) { + var reqBody, resBody QueryFaultToleranceCompatibilityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryFaultToleranceCompatibilityExBody struct { + Req *types.QueryFaultToleranceCompatibilityEx `xml:"urn:vim25 QueryFaultToleranceCompatibilityEx,omitempty"` + Res *types.QueryFaultToleranceCompatibilityExResponse `xml:"urn:vim25 QueryFaultToleranceCompatibilityExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryFaultToleranceCompatibilityExBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryFaultToleranceCompatibilityEx(ctx context.Context, r soap.RoundTripper, req *types.QueryFaultToleranceCompatibilityEx) (*types.QueryFaultToleranceCompatibilityExResponse, error) { + var reqBody, resBody QueryFaultToleranceCompatibilityExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryFirmwareConfigUploadURLBody struct { + Req *types.QueryFirmwareConfigUploadURL `xml:"urn:vim25 QueryFirmwareConfigUploadURL,omitempty"` + Res *types.QueryFirmwareConfigUploadURLResponse `xml:"urn:vim25 QueryFirmwareConfigUploadURLResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryFirmwareConfigUploadURLBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryFirmwareConfigUploadURL(ctx context.Context, r soap.RoundTripper, req *types.QueryFirmwareConfigUploadURL) (*types.QueryFirmwareConfigUploadURLResponse, error) { + var reqBody, resBody QueryFirmwareConfigUploadURLBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryHostConnectionInfoBody struct { + Req *types.QueryHostConnectionInfo `xml:"urn:vim25 QueryHostConnectionInfo,omitempty"` + Res *types.QueryHostConnectionInfoResponse `xml:"urn:vim25 QueryHostConnectionInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryHostConnectionInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryHostConnectionInfo(ctx context.Context, r soap.RoundTripper, req *types.QueryHostConnectionInfo) (*types.QueryHostConnectionInfoResponse, error) { + var reqBody, resBody QueryHostConnectionInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryHostPatch_TaskBody struct { + Req *types.QueryHostPatch_Task `xml:"urn:vim25 QueryHostPatch_Task,omitempty"` + Res *types.QueryHostPatch_TaskResponse `xml:"urn:vim25 QueryHostPatch_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryHostPatch_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryHostPatch_Task(ctx context.Context, r soap.RoundTripper, req *types.QueryHostPatch_Task) (*types.QueryHostPatch_TaskResponse, error) { + var reqBody, resBody QueryHostPatch_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryHostProfileMetadataBody struct { + Req *types.QueryHostProfileMetadata `xml:"urn:vim25 QueryHostProfileMetadata,omitempty"` + Res *types.QueryHostProfileMetadataResponse `xml:"urn:vim25 QueryHostProfileMetadataResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryHostProfileMetadataBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryHostProfileMetadata(ctx context.Context, r soap.RoundTripper, req *types.QueryHostProfileMetadata) (*types.QueryHostProfileMetadataResponse, error) { + var reqBody, resBody QueryHostProfileMetadataBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryHostStatusBody struct { + Req *types.QueryHostStatus `xml:"urn:vim25 QueryHostStatus,omitempty"` + Res *types.QueryHostStatusResponse `xml:"urn:vim25 QueryHostStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryHostStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryHostStatus(ctx context.Context, r soap.RoundTripper, req *types.QueryHostStatus) (*types.QueryHostStatusResponse, error) { + var reqBody, resBody QueryHostStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryIORMConfigOptionBody struct { + Req *types.QueryIORMConfigOption `xml:"urn:vim25 QueryIORMConfigOption,omitempty"` + Res *types.QueryIORMConfigOptionResponse `xml:"urn:vim25 QueryIORMConfigOptionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryIORMConfigOptionBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryIORMConfigOption(ctx context.Context, r soap.RoundTripper, req *types.QueryIORMConfigOption) (*types.QueryIORMConfigOptionResponse, error) { + var reqBody, resBody QueryIORMConfigOptionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryIPAllocationsBody struct { + Req *types.QueryIPAllocations `xml:"urn:vim25 QueryIPAllocations,omitempty"` + Res *types.QueryIPAllocationsResponse `xml:"urn:vim25 QueryIPAllocationsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryIPAllocationsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryIPAllocations(ctx context.Context, r soap.RoundTripper, req *types.QueryIPAllocations) (*types.QueryIPAllocationsResponse, error) { + var reqBody, resBody QueryIPAllocationsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryIoFilterInfoBody struct { + Req *types.QueryIoFilterInfo `xml:"urn:vim25 QueryIoFilterInfo,omitempty"` + Res *types.QueryIoFilterInfoResponse `xml:"urn:vim25 QueryIoFilterInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryIoFilterInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryIoFilterInfo(ctx context.Context, r soap.RoundTripper, req *types.QueryIoFilterInfo) (*types.QueryIoFilterInfoResponse, error) { + var reqBody, resBody QueryIoFilterInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryIoFilterIssuesBody struct { + Req *types.QueryIoFilterIssues `xml:"urn:vim25 QueryIoFilterIssues,omitempty"` + Res *types.QueryIoFilterIssuesResponse `xml:"urn:vim25 QueryIoFilterIssuesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryIoFilterIssuesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryIoFilterIssues(ctx context.Context, r soap.RoundTripper, req *types.QueryIoFilterIssues) (*types.QueryIoFilterIssuesResponse, error) { + var reqBody, resBody QueryIoFilterIssuesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryIpPoolsBody struct { + Req *types.QueryIpPools `xml:"urn:vim25 QueryIpPools,omitempty"` + Res *types.QueryIpPoolsResponse `xml:"urn:vim25 QueryIpPoolsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryIpPoolsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryIpPools(ctx context.Context, r soap.RoundTripper, req *types.QueryIpPools) (*types.QueryIpPoolsResponse, error) { + var reqBody, resBody QueryIpPoolsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryLicenseSourceAvailabilityBody struct { + Req *types.QueryLicenseSourceAvailability `xml:"urn:vim25 QueryLicenseSourceAvailability,omitempty"` + Res *types.QueryLicenseSourceAvailabilityResponse `xml:"urn:vim25 QueryLicenseSourceAvailabilityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryLicenseSourceAvailabilityBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryLicenseSourceAvailability(ctx context.Context, r soap.RoundTripper, req *types.QueryLicenseSourceAvailability) (*types.QueryLicenseSourceAvailabilityResponse, error) { + var reqBody, resBody QueryLicenseSourceAvailabilityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryLicenseUsageBody struct { + Req *types.QueryLicenseUsage `xml:"urn:vim25 QueryLicenseUsage,omitempty"` + Res *types.QueryLicenseUsageResponse `xml:"urn:vim25 QueryLicenseUsageResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryLicenseUsageBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryLicenseUsage(ctx context.Context, r soap.RoundTripper, req *types.QueryLicenseUsage) (*types.QueryLicenseUsageResponse, error) { + var reqBody, resBody QueryLicenseUsageBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryLockdownExceptionsBody struct { + Req *types.QueryLockdownExceptions `xml:"urn:vim25 QueryLockdownExceptions,omitempty"` + Res *types.QueryLockdownExceptionsResponse `xml:"urn:vim25 QueryLockdownExceptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryLockdownExceptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryLockdownExceptions(ctx context.Context, r soap.RoundTripper, req *types.QueryLockdownExceptions) (*types.QueryLockdownExceptionsResponse, error) { + var reqBody, resBody QueryLockdownExceptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryManagedByBody struct { + Req *types.QueryManagedBy `xml:"urn:vim25 QueryManagedBy,omitempty"` + Res *types.QueryManagedByResponse `xml:"urn:vim25 QueryManagedByResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryManagedByBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryManagedBy(ctx context.Context, r soap.RoundTripper, req *types.QueryManagedBy) (*types.QueryManagedByResponse, error) { + var reqBody, resBody QueryManagedByBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryMemoryOverheadBody struct { + Req *types.QueryMemoryOverhead `xml:"urn:vim25 QueryMemoryOverhead,omitempty"` + Res *types.QueryMemoryOverheadResponse `xml:"urn:vim25 QueryMemoryOverheadResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryMemoryOverheadBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryMemoryOverhead(ctx context.Context, r soap.RoundTripper, req *types.QueryMemoryOverhead) (*types.QueryMemoryOverheadResponse, error) { + var reqBody, resBody QueryMemoryOverheadBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryMemoryOverheadExBody struct { + Req *types.QueryMemoryOverheadEx `xml:"urn:vim25 QueryMemoryOverheadEx,omitempty"` + Res *types.QueryMemoryOverheadExResponse `xml:"urn:vim25 QueryMemoryOverheadExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryMemoryOverheadExBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryMemoryOverheadEx(ctx context.Context, r soap.RoundTripper, req *types.QueryMemoryOverheadEx) (*types.QueryMemoryOverheadExResponse, error) { + var reqBody, resBody QueryMemoryOverheadExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryMigrationDependenciesBody struct { + Req *types.QueryMigrationDependencies `xml:"urn:vim25 QueryMigrationDependencies,omitempty"` + Res *types.QueryMigrationDependenciesResponse `xml:"urn:vim25 QueryMigrationDependenciesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryMigrationDependenciesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryMigrationDependencies(ctx context.Context, r soap.RoundTripper, req *types.QueryMigrationDependencies) (*types.QueryMigrationDependenciesResponse, error) { + var reqBody, resBody QueryMigrationDependenciesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryModulesBody struct { + Req *types.QueryModules `xml:"urn:vim25 QueryModules,omitempty"` + Res *types.QueryModulesResponse `xml:"urn:vim25 QueryModulesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryModulesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryModules(ctx context.Context, r soap.RoundTripper, req *types.QueryModules) (*types.QueryModulesResponse, error) { + var reqBody, resBody QueryModulesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryNFSUserBody struct { + Req *types.QueryNFSUser `xml:"urn:vim25 QueryNFSUser,omitempty"` + Res *types.QueryNFSUserResponse `xml:"urn:vim25 QueryNFSUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryNFSUserBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryNFSUser(ctx context.Context, r soap.RoundTripper, req *types.QueryNFSUser) (*types.QueryNFSUserResponse, error) { + var reqBody, resBody QueryNFSUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryNetConfigBody struct { + Req *types.QueryNetConfig `xml:"urn:vim25 QueryNetConfig,omitempty"` + Res *types.QueryNetConfigResponse `xml:"urn:vim25 QueryNetConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryNetConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryNetConfig(ctx context.Context, r soap.RoundTripper, req *types.QueryNetConfig) (*types.QueryNetConfigResponse, error) { + var reqBody, resBody QueryNetConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryNetworkHintBody struct { + Req *types.QueryNetworkHint `xml:"urn:vim25 QueryNetworkHint,omitempty"` + Res *types.QueryNetworkHintResponse `xml:"urn:vim25 QueryNetworkHintResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryNetworkHintBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryNetworkHint(ctx context.Context, r soap.RoundTripper, req *types.QueryNetworkHint) (*types.QueryNetworkHintResponse, error) { + var reqBody, resBody QueryNetworkHintBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryObjectsOnPhysicalVsanDiskBody struct { + Req *types.QueryObjectsOnPhysicalVsanDisk `xml:"urn:vim25 QueryObjectsOnPhysicalVsanDisk,omitempty"` + Res *types.QueryObjectsOnPhysicalVsanDiskResponse `xml:"urn:vim25 QueryObjectsOnPhysicalVsanDiskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryObjectsOnPhysicalVsanDiskBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryObjectsOnPhysicalVsanDisk(ctx context.Context, r soap.RoundTripper, req *types.QueryObjectsOnPhysicalVsanDisk) (*types.QueryObjectsOnPhysicalVsanDiskResponse, error) { + var reqBody, resBody QueryObjectsOnPhysicalVsanDiskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryOptionsBody struct { + Req *types.QueryOptions `xml:"urn:vim25 QueryOptions,omitempty"` + Res *types.QueryOptionsResponse `xml:"urn:vim25 QueryOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryOptions) (*types.QueryOptionsResponse, error) { + var reqBody, resBody QueryOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPartitionCreateDescBody struct { + Req *types.QueryPartitionCreateDesc `xml:"urn:vim25 QueryPartitionCreateDesc,omitempty"` + Res *types.QueryPartitionCreateDescResponse `xml:"urn:vim25 QueryPartitionCreateDescResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPartitionCreateDescBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPartitionCreateDesc(ctx context.Context, r soap.RoundTripper, req *types.QueryPartitionCreateDesc) (*types.QueryPartitionCreateDescResponse, error) { + var reqBody, resBody QueryPartitionCreateDescBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPartitionCreateOptionsBody struct { + Req *types.QueryPartitionCreateOptions `xml:"urn:vim25 QueryPartitionCreateOptions,omitempty"` + Res *types.QueryPartitionCreateOptionsResponse `xml:"urn:vim25 QueryPartitionCreateOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPartitionCreateOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPartitionCreateOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryPartitionCreateOptions) (*types.QueryPartitionCreateOptionsResponse, error) { + var reqBody, resBody QueryPartitionCreateOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPathSelectionPolicyOptionsBody struct { + Req *types.QueryPathSelectionPolicyOptions `xml:"urn:vim25 QueryPathSelectionPolicyOptions,omitempty"` + Res *types.QueryPathSelectionPolicyOptionsResponse `xml:"urn:vim25 QueryPathSelectionPolicyOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPathSelectionPolicyOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPathSelectionPolicyOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryPathSelectionPolicyOptions) (*types.QueryPathSelectionPolicyOptionsResponse, error) { + var reqBody, resBody QueryPathSelectionPolicyOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPerfBody struct { + Req *types.QueryPerf `xml:"urn:vim25 QueryPerf,omitempty"` + Res *types.QueryPerfResponse `xml:"urn:vim25 QueryPerfResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPerfBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPerf(ctx context.Context, r soap.RoundTripper, req *types.QueryPerf) (*types.QueryPerfResponse, error) { + var reqBody, resBody QueryPerfBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPerfCompositeBody struct { + Req *types.QueryPerfComposite `xml:"urn:vim25 QueryPerfComposite,omitempty"` + Res *types.QueryPerfCompositeResponse `xml:"urn:vim25 QueryPerfCompositeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPerfCompositeBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPerfComposite(ctx context.Context, r soap.RoundTripper, req *types.QueryPerfComposite) (*types.QueryPerfCompositeResponse, error) { + var reqBody, resBody QueryPerfCompositeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPerfCounterBody struct { + Req *types.QueryPerfCounter `xml:"urn:vim25 QueryPerfCounter,omitempty"` + Res *types.QueryPerfCounterResponse `xml:"urn:vim25 QueryPerfCounterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPerfCounterBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPerfCounter(ctx context.Context, r soap.RoundTripper, req *types.QueryPerfCounter) (*types.QueryPerfCounterResponse, error) { + var reqBody, resBody QueryPerfCounterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPerfCounterByLevelBody struct { + Req *types.QueryPerfCounterByLevel `xml:"urn:vim25 QueryPerfCounterByLevel,omitempty"` + Res *types.QueryPerfCounterByLevelResponse `xml:"urn:vim25 QueryPerfCounterByLevelResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPerfCounterByLevelBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPerfCounterByLevel(ctx context.Context, r soap.RoundTripper, req *types.QueryPerfCounterByLevel) (*types.QueryPerfCounterByLevelResponse, error) { + var reqBody, resBody QueryPerfCounterByLevelBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPerfProviderSummaryBody struct { + Req *types.QueryPerfProviderSummary `xml:"urn:vim25 QueryPerfProviderSummary,omitempty"` + Res *types.QueryPerfProviderSummaryResponse `xml:"urn:vim25 QueryPerfProviderSummaryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPerfProviderSummaryBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPerfProviderSummary(ctx context.Context, r soap.RoundTripper, req *types.QueryPerfProviderSummary) (*types.QueryPerfProviderSummaryResponse, error) { + var reqBody, resBody QueryPerfProviderSummaryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPhysicalVsanDisksBody struct { + Req *types.QueryPhysicalVsanDisks `xml:"urn:vim25 QueryPhysicalVsanDisks,omitempty"` + Res *types.QueryPhysicalVsanDisksResponse `xml:"urn:vim25 QueryPhysicalVsanDisksResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPhysicalVsanDisksBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPhysicalVsanDisks(ctx context.Context, r soap.RoundTripper, req *types.QueryPhysicalVsanDisks) (*types.QueryPhysicalVsanDisksResponse, error) { + var reqBody, resBody QueryPhysicalVsanDisksBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPnicStatusBody struct { + Req *types.QueryPnicStatus `xml:"urn:vim25 QueryPnicStatus,omitempty"` + Res *types.QueryPnicStatusResponse `xml:"urn:vim25 QueryPnicStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPnicStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPnicStatus(ctx context.Context, r soap.RoundTripper, req *types.QueryPnicStatus) (*types.QueryPnicStatusResponse, error) { + var reqBody, resBody QueryPnicStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryPolicyMetadataBody struct { + Req *types.QueryPolicyMetadata `xml:"urn:vim25 QueryPolicyMetadata,omitempty"` + Res *types.QueryPolicyMetadataResponse `xml:"urn:vim25 QueryPolicyMetadataResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryPolicyMetadataBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryPolicyMetadata(ctx context.Context, r soap.RoundTripper, req *types.QueryPolicyMetadata) (*types.QueryPolicyMetadataResponse, error) { + var reqBody, resBody QueryPolicyMetadataBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryProfileStructureBody struct { + Req *types.QueryProfileStructure `xml:"urn:vim25 QueryProfileStructure,omitempty"` + Res *types.QueryProfileStructureResponse `xml:"urn:vim25 QueryProfileStructureResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryProfileStructureBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryProfileStructure(ctx context.Context, r soap.RoundTripper, req *types.QueryProfileStructure) (*types.QueryProfileStructureResponse, error) { + var reqBody, resBody QueryProfileStructureBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryResourceConfigOptionBody struct { + Req *types.QueryResourceConfigOption `xml:"urn:vim25 QueryResourceConfigOption,omitempty"` + Res *types.QueryResourceConfigOptionResponse `xml:"urn:vim25 QueryResourceConfigOptionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryResourceConfigOptionBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryResourceConfigOption(ctx context.Context, r soap.RoundTripper, req *types.QueryResourceConfigOption) (*types.QueryResourceConfigOptionResponse, error) { + var reqBody, resBody QueryResourceConfigOptionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryServiceListBody struct { + Req *types.QueryServiceList `xml:"urn:vim25 QueryServiceList,omitempty"` + Res *types.QueryServiceListResponse `xml:"urn:vim25 QueryServiceListResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryServiceListBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryServiceList(ctx context.Context, r soap.RoundTripper, req *types.QueryServiceList) (*types.QueryServiceListResponse, error) { + var reqBody, resBody QueryServiceListBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryStorageArrayTypePolicyOptionsBody struct { + Req *types.QueryStorageArrayTypePolicyOptions `xml:"urn:vim25 QueryStorageArrayTypePolicyOptions,omitempty"` + Res *types.QueryStorageArrayTypePolicyOptionsResponse `xml:"urn:vim25 QueryStorageArrayTypePolicyOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryStorageArrayTypePolicyOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryStorageArrayTypePolicyOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryStorageArrayTypePolicyOptions) (*types.QueryStorageArrayTypePolicyOptionsResponse, error) { + var reqBody, resBody QueryStorageArrayTypePolicyOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QuerySupportedFeaturesBody struct { + Req *types.QuerySupportedFeatures `xml:"urn:vim25 QuerySupportedFeatures,omitempty"` + Res *types.QuerySupportedFeaturesResponse `xml:"urn:vim25 QuerySupportedFeaturesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QuerySupportedFeaturesBody) Fault() *soap.Fault { return b.Fault_ } + +func QuerySupportedFeatures(ctx context.Context, r soap.RoundTripper, req *types.QuerySupportedFeatures) (*types.QuerySupportedFeaturesResponse, error) { + var reqBody, resBody QuerySupportedFeaturesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QuerySyncingVsanObjectsBody struct { + Req *types.QuerySyncingVsanObjects `xml:"urn:vim25 QuerySyncingVsanObjects,omitempty"` + Res *types.QuerySyncingVsanObjectsResponse `xml:"urn:vim25 QuerySyncingVsanObjectsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QuerySyncingVsanObjectsBody) Fault() *soap.Fault { return b.Fault_ } + +func QuerySyncingVsanObjects(ctx context.Context, r soap.RoundTripper, req *types.QuerySyncingVsanObjects) (*types.QuerySyncingVsanObjectsResponse, error) { + var reqBody, resBody QuerySyncingVsanObjectsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QuerySystemUsersBody struct { + Req *types.QuerySystemUsers `xml:"urn:vim25 QuerySystemUsers,omitempty"` + Res *types.QuerySystemUsersResponse `xml:"urn:vim25 QuerySystemUsersResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QuerySystemUsersBody) Fault() *soap.Fault { return b.Fault_ } + +func QuerySystemUsers(ctx context.Context, r soap.RoundTripper, req *types.QuerySystemUsers) (*types.QuerySystemUsersResponse, error) { + var reqBody, resBody QuerySystemUsersBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryTargetCapabilitiesBody struct { + Req *types.QueryTargetCapabilities `xml:"urn:vim25 QueryTargetCapabilities,omitempty"` + Res *types.QueryTargetCapabilitiesResponse `xml:"urn:vim25 QueryTargetCapabilitiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryTargetCapabilitiesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryTargetCapabilities(ctx context.Context, r soap.RoundTripper, req *types.QueryTargetCapabilities) (*types.QueryTargetCapabilitiesResponse, error) { + var reqBody, resBody QueryTargetCapabilitiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryTpmAttestationReportBody struct { + Req *types.QueryTpmAttestationReport `xml:"urn:vim25 QueryTpmAttestationReport,omitempty"` + Res *types.QueryTpmAttestationReportResponse `xml:"urn:vim25 QueryTpmAttestationReportResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryTpmAttestationReportBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryTpmAttestationReport(ctx context.Context, r soap.RoundTripper, req *types.QueryTpmAttestationReport) (*types.QueryTpmAttestationReportResponse, error) { + var reqBody, resBody QueryTpmAttestationReportBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryUnownedFilesBody struct { + Req *types.QueryUnownedFiles `xml:"urn:vim25 QueryUnownedFiles,omitempty"` + Res *types.QueryUnownedFilesResponse `xml:"urn:vim25 QueryUnownedFilesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryUnownedFilesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryUnownedFiles(ctx context.Context, r soap.RoundTripper, req *types.QueryUnownedFiles) (*types.QueryUnownedFilesResponse, error) { + var reqBody, resBody QueryUnownedFilesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryUnresolvedVmfsVolumeBody struct { + Req *types.QueryUnresolvedVmfsVolume `xml:"urn:vim25 QueryUnresolvedVmfsVolume,omitempty"` + Res *types.QueryUnresolvedVmfsVolumeResponse `xml:"urn:vim25 QueryUnresolvedVmfsVolumeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryUnresolvedVmfsVolumeBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryUnresolvedVmfsVolume(ctx context.Context, r soap.RoundTripper, req *types.QueryUnresolvedVmfsVolume) (*types.QueryUnresolvedVmfsVolumeResponse, error) { + var reqBody, resBody QueryUnresolvedVmfsVolumeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryUnresolvedVmfsVolumesBody struct { + Req *types.QueryUnresolvedVmfsVolumes `xml:"urn:vim25 QueryUnresolvedVmfsVolumes,omitempty"` + Res *types.QueryUnresolvedVmfsVolumesResponse `xml:"urn:vim25 QueryUnresolvedVmfsVolumesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryUnresolvedVmfsVolumesBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryUnresolvedVmfsVolumes(ctx context.Context, r soap.RoundTripper, req *types.QueryUnresolvedVmfsVolumes) (*types.QueryUnresolvedVmfsVolumesResponse, error) { + var reqBody, resBody QueryUnresolvedVmfsVolumesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryUsedVlanIdInDvsBody struct { + Req *types.QueryUsedVlanIdInDvs `xml:"urn:vim25 QueryUsedVlanIdInDvs,omitempty"` + Res *types.QueryUsedVlanIdInDvsResponse `xml:"urn:vim25 QueryUsedVlanIdInDvsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryUsedVlanIdInDvsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryUsedVlanIdInDvs(ctx context.Context, r soap.RoundTripper, req *types.QueryUsedVlanIdInDvs) (*types.QueryUsedVlanIdInDvsResponse, error) { + var reqBody, resBody QueryUsedVlanIdInDvsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVMotionCompatibilityBody struct { + Req *types.QueryVMotionCompatibility `xml:"urn:vim25 QueryVMotionCompatibility,omitempty"` + Res *types.QueryVMotionCompatibilityResponse `xml:"urn:vim25 QueryVMotionCompatibilityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVMotionCompatibilityBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVMotionCompatibility(ctx context.Context, r soap.RoundTripper, req *types.QueryVMotionCompatibility) (*types.QueryVMotionCompatibilityResponse, error) { + var reqBody, resBody QueryVMotionCompatibilityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVMotionCompatibilityEx_TaskBody struct { + Req *types.QueryVMotionCompatibilityEx_Task `xml:"urn:vim25 QueryVMotionCompatibilityEx_Task,omitempty"` + Res *types.QueryVMotionCompatibilityEx_TaskResponse `xml:"urn:vim25 QueryVMotionCompatibilityEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVMotionCompatibilityEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVMotionCompatibilityEx_Task(ctx context.Context, r soap.RoundTripper, req *types.QueryVMotionCompatibilityEx_Task) (*types.QueryVMotionCompatibilityEx_TaskResponse, error) { + var reqBody, resBody QueryVMotionCompatibilityEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVirtualDiskFragmentationBody struct { + Req *types.QueryVirtualDiskFragmentation `xml:"urn:vim25 QueryVirtualDiskFragmentation,omitempty"` + Res *types.QueryVirtualDiskFragmentationResponse `xml:"urn:vim25 QueryVirtualDiskFragmentationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVirtualDiskFragmentationBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVirtualDiskFragmentation(ctx context.Context, r soap.RoundTripper, req *types.QueryVirtualDiskFragmentation) (*types.QueryVirtualDiskFragmentationResponse, error) { + var reqBody, resBody QueryVirtualDiskFragmentationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVirtualDiskGeometryBody struct { + Req *types.QueryVirtualDiskGeometry `xml:"urn:vim25 QueryVirtualDiskGeometry,omitempty"` + Res *types.QueryVirtualDiskGeometryResponse `xml:"urn:vim25 QueryVirtualDiskGeometryResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVirtualDiskGeometryBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVirtualDiskGeometry(ctx context.Context, r soap.RoundTripper, req *types.QueryVirtualDiskGeometry) (*types.QueryVirtualDiskGeometryResponse, error) { + var reqBody, resBody QueryVirtualDiskGeometryBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVirtualDiskUuidBody struct { + Req *types.QueryVirtualDiskUuid `xml:"urn:vim25 QueryVirtualDiskUuid,omitempty"` + Res *types.QueryVirtualDiskUuidResponse `xml:"urn:vim25 QueryVirtualDiskUuidResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVirtualDiskUuidBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVirtualDiskUuid(ctx context.Context, r soap.RoundTripper, req *types.QueryVirtualDiskUuid) (*types.QueryVirtualDiskUuidResponse, error) { + var reqBody, resBody QueryVirtualDiskUuidBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVmfsDatastoreCreateOptionsBody struct { + Req *types.QueryVmfsDatastoreCreateOptions `xml:"urn:vim25 QueryVmfsDatastoreCreateOptions,omitempty"` + Res *types.QueryVmfsDatastoreCreateOptionsResponse `xml:"urn:vim25 QueryVmfsDatastoreCreateOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVmfsDatastoreCreateOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVmfsDatastoreCreateOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryVmfsDatastoreCreateOptions) (*types.QueryVmfsDatastoreCreateOptionsResponse, error) { + var reqBody, resBody QueryVmfsDatastoreCreateOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVmfsDatastoreExpandOptionsBody struct { + Req *types.QueryVmfsDatastoreExpandOptions `xml:"urn:vim25 QueryVmfsDatastoreExpandOptions,omitempty"` + Res *types.QueryVmfsDatastoreExpandOptionsResponse `xml:"urn:vim25 QueryVmfsDatastoreExpandOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVmfsDatastoreExpandOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVmfsDatastoreExpandOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryVmfsDatastoreExpandOptions) (*types.QueryVmfsDatastoreExpandOptionsResponse, error) { + var reqBody, resBody QueryVmfsDatastoreExpandOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVmfsDatastoreExtendOptionsBody struct { + Req *types.QueryVmfsDatastoreExtendOptions `xml:"urn:vim25 QueryVmfsDatastoreExtendOptions,omitempty"` + Res *types.QueryVmfsDatastoreExtendOptionsResponse `xml:"urn:vim25 QueryVmfsDatastoreExtendOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVmfsDatastoreExtendOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVmfsDatastoreExtendOptions(ctx context.Context, r soap.RoundTripper, req *types.QueryVmfsDatastoreExtendOptions) (*types.QueryVmfsDatastoreExtendOptionsResponse, error) { + var reqBody, resBody QueryVmfsDatastoreExtendOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVnicStatusBody struct { + Req *types.QueryVnicStatus `xml:"urn:vim25 QueryVnicStatus,omitempty"` + Res *types.QueryVnicStatusResponse `xml:"urn:vim25 QueryVnicStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVnicStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVnicStatus(ctx context.Context, r soap.RoundTripper, req *types.QueryVnicStatus) (*types.QueryVnicStatusResponse, error) { + var reqBody, resBody QueryVnicStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVsanObjectUuidsByFilterBody struct { + Req *types.QueryVsanObjectUuidsByFilter `xml:"urn:vim25 QueryVsanObjectUuidsByFilter,omitempty"` + Res *types.QueryVsanObjectUuidsByFilterResponse `xml:"urn:vim25 QueryVsanObjectUuidsByFilterResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVsanObjectUuidsByFilterBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVsanObjectUuidsByFilter(ctx context.Context, r soap.RoundTripper, req *types.QueryVsanObjectUuidsByFilter) (*types.QueryVsanObjectUuidsByFilterResponse, error) { + var reqBody, resBody QueryVsanObjectUuidsByFilterBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVsanObjectsBody struct { + Req *types.QueryVsanObjects `xml:"urn:vim25 QueryVsanObjects,omitempty"` + Res *types.QueryVsanObjectsResponse `xml:"urn:vim25 QueryVsanObjectsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVsanObjectsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVsanObjects(ctx context.Context, r soap.RoundTripper, req *types.QueryVsanObjects) (*types.QueryVsanObjectsResponse, error) { + var reqBody, resBody QueryVsanObjectsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVsanStatisticsBody struct { + Req *types.QueryVsanStatistics `xml:"urn:vim25 QueryVsanStatistics,omitempty"` + Res *types.QueryVsanStatisticsResponse `xml:"urn:vim25 QueryVsanStatisticsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVsanStatisticsBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVsanStatistics(ctx context.Context, r soap.RoundTripper, req *types.QueryVsanStatistics) (*types.QueryVsanStatisticsResponse, error) { + var reqBody, resBody QueryVsanStatisticsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type QueryVsanUpgradeStatusBody struct { + Req *types.QueryVsanUpgradeStatus `xml:"urn:vim25 QueryVsanUpgradeStatus,omitempty"` + Res *types.QueryVsanUpgradeStatusResponse `xml:"urn:vim25 QueryVsanUpgradeStatusResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *QueryVsanUpgradeStatusBody) Fault() *soap.Fault { return b.Fault_ } + +func QueryVsanUpgradeStatus(ctx context.Context, r soap.RoundTripper, req *types.QueryVsanUpgradeStatus) (*types.QueryVsanUpgradeStatusResponse, error) { + var reqBody, resBody QueryVsanUpgradeStatusBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReadEnvironmentVariableInGuestBody struct { + Req *types.ReadEnvironmentVariableInGuest `xml:"urn:vim25 ReadEnvironmentVariableInGuest,omitempty"` + Res *types.ReadEnvironmentVariableInGuestResponse `xml:"urn:vim25 ReadEnvironmentVariableInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReadEnvironmentVariableInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ReadEnvironmentVariableInGuest(ctx context.Context, r soap.RoundTripper, req *types.ReadEnvironmentVariableInGuest) (*types.ReadEnvironmentVariableInGuestResponse, error) { + var reqBody, resBody ReadEnvironmentVariableInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReadNextEventsBody struct { + Req *types.ReadNextEvents `xml:"urn:vim25 ReadNextEvents,omitempty"` + Res *types.ReadNextEventsResponse `xml:"urn:vim25 ReadNextEventsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReadNextEventsBody) Fault() *soap.Fault { return b.Fault_ } + +func ReadNextEvents(ctx context.Context, r soap.RoundTripper, req *types.ReadNextEvents) (*types.ReadNextEventsResponse, error) { + var reqBody, resBody ReadNextEventsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReadNextTasksBody struct { + Req *types.ReadNextTasks `xml:"urn:vim25 ReadNextTasks,omitempty"` + Res *types.ReadNextTasksResponse `xml:"urn:vim25 ReadNextTasksResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReadNextTasksBody) Fault() *soap.Fault { return b.Fault_ } + +func ReadNextTasks(ctx context.Context, r soap.RoundTripper, req *types.ReadNextTasks) (*types.ReadNextTasksResponse, error) { + var reqBody, resBody ReadNextTasksBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReadPreviousEventsBody struct { + Req *types.ReadPreviousEvents `xml:"urn:vim25 ReadPreviousEvents,omitempty"` + Res *types.ReadPreviousEventsResponse `xml:"urn:vim25 ReadPreviousEventsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReadPreviousEventsBody) Fault() *soap.Fault { return b.Fault_ } + +func ReadPreviousEvents(ctx context.Context, r soap.RoundTripper, req *types.ReadPreviousEvents) (*types.ReadPreviousEventsResponse, error) { + var reqBody, resBody ReadPreviousEventsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReadPreviousTasksBody struct { + Req *types.ReadPreviousTasks `xml:"urn:vim25 ReadPreviousTasks,omitempty"` + Res *types.ReadPreviousTasksResponse `xml:"urn:vim25 ReadPreviousTasksResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReadPreviousTasksBody) Fault() *soap.Fault { return b.Fault_ } + +func ReadPreviousTasks(ctx context.Context, r soap.RoundTripper, req *types.ReadPreviousTasks) (*types.ReadPreviousTasksResponse, error) { + var reqBody, resBody ReadPreviousTasksBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RebootGuestBody struct { + Req *types.RebootGuest `xml:"urn:vim25 RebootGuest,omitempty"` + Res *types.RebootGuestResponse `xml:"urn:vim25 RebootGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RebootGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func RebootGuest(ctx context.Context, r soap.RoundTripper, req *types.RebootGuest) (*types.RebootGuestResponse, error) { + var reqBody, resBody RebootGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RebootHost_TaskBody struct { + Req *types.RebootHost_Task `xml:"urn:vim25 RebootHost_Task,omitempty"` + Res *types.RebootHost_TaskResponse `xml:"urn:vim25 RebootHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RebootHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RebootHost_Task(ctx context.Context, r soap.RoundTripper, req *types.RebootHost_Task) (*types.RebootHost_TaskResponse, error) { + var reqBody, resBody RebootHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RecommendDatastoresBody struct { + Req *types.RecommendDatastores `xml:"urn:vim25 RecommendDatastores,omitempty"` + Res *types.RecommendDatastoresResponse `xml:"urn:vim25 RecommendDatastoresResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RecommendDatastoresBody) Fault() *soap.Fault { return b.Fault_ } + +func RecommendDatastores(ctx context.Context, r soap.RoundTripper, req *types.RecommendDatastores) (*types.RecommendDatastoresResponse, error) { + var reqBody, resBody RecommendDatastoresBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RecommendHostsForVmBody struct { + Req *types.RecommendHostsForVm `xml:"urn:vim25 RecommendHostsForVm,omitempty"` + Res *types.RecommendHostsForVmResponse `xml:"urn:vim25 RecommendHostsForVmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RecommendHostsForVmBody) Fault() *soap.Fault { return b.Fault_ } + +func RecommendHostsForVm(ctx context.Context, r soap.RoundTripper, req *types.RecommendHostsForVm) (*types.RecommendHostsForVmResponse, error) { + var reqBody, resBody RecommendHostsForVmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RecommissionVsanNode_TaskBody struct { + Req *types.RecommissionVsanNode_Task `xml:"urn:vim25 RecommissionVsanNode_Task,omitempty"` + Res *types.RecommissionVsanNode_TaskResponse `xml:"urn:vim25 RecommissionVsanNode_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RecommissionVsanNode_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RecommissionVsanNode_Task(ctx context.Context, r soap.RoundTripper, req *types.RecommissionVsanNode_Task) (*types.RecommissionVsanNode_TaskResponse, error) { + var reqBody, resBody RecommissionVsanNode_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigVM_TaskBody struct { + Req *types.ReconfigVM_Task `xml:"urn:vim25 ReconfigVM_Task,omitempty"` + Res *types.ReconfigVM_TaskResponse `xml:"urn:vim25 ReconfigVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigVM_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigVM_Task) (*types.ReconfigVM_TaskResponse, error) { + var reqBody, resBody ReconfigVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigurationSatisfiableBody struct { + Req *types.ReconfigurationSatisfiable `xml:"urn:vim25 ReconfigurationSatisfiable,omitempty"` + Res *types.ReconfigurationSatisfiableResponse `xml:"urn:vim25 ReconfigurationSatisfiableResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigurationSatisfiableBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigurationSatisfiable(ctx context.Context, r soap.RoundTripper, req *types.ReconfigurationSatisfiable) (*types.ReconfigurationSatisfiableResponse, error) { + var reqBody, resBody ReconfigurationSatisfiableBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureAlarmBody struct { + Req *types.ReconfigureAlarm `xml:"urn:vim25 ReconfigureAlarm,omitempty"` + Res *types.ReconfigureAlarmResponse `xml:"urn:vim25 ReconfigureAlarmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureAlarmBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureAlarm(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureAlarm) (*types.ReconfigureAlarmResponse, error) { + var reqBody, resBody ReconfigureAlarmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureAutostartBody struct { + Req *types.ReconfigureAutostart `xml:"urn:vim25 ReconfigureAutostart,omitempty"` + Res *types.ReconfigureAutostartResponse `xml:"urn:vim25 ReconfigureAutostartResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureAutostartBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureAutostart(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureAutostart) (*types.ReconfigureAutostartResponse, error) { + var reqBody, resBody ReconfigureAutostartBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureCluster_TaskBody struct { + Req *types.ReconfigureCluster_Task `xml:"urn:vim25 ReconfigureCluster_Task,omitempty"` + Res *types.ReconfigureCluster_TaskResponse `xml:"urn:vim25 ReconfigureCluster_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureCluster_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureCluster_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureCluster_Task) (*types.ReconfigureCluster_TaskResponse, error) { + var reqBody, resBody ReconfigureCluster_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureComputeResource_TaskBody struct { + Req *types.ReconfigureComputeResource_Task `xml:"urn:vim25 ReconfigureComputeResource_Task,omitempty"` + Res *types.ReconfigureComputeResource_TaskResponse `xml:"urn:vim25 ReconfigureComputeResource_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureComputeResource_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureComputeResource_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureComputeResource_Task) (*types.ReconfigureComputeResource_TaskResponse, error) { + var reqBody, resBody ReconfigureComputeResource_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureDVPort_TaskBody struct { + Req *types.ReconfigureDVPort_Task `xml:"urn:vim25 ReconfigureDVPort_Task,omitempty"` + Res *types.ReconfigureDVPort_TaskResponse `xml:"urn:vim25 ReconfigureDVPort_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureDVPort_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureDVPort_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureDVPort_Task) (*types.ReconfigureDVPort_TaskResponse, error) { + var reqBody, resBody ReconfigureDVPort_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureDVPortgroup_TaskBody struct { + Req *types.ReconfigureDVPortgroup_Task `xml:"urn:vim25 ReconfigureDVPortgroup_Task,omitempty"` + Res *types.ReconfigureDVPortgroup_TaskResponse `xml:"urn:vim25 ReconfigureDVPortgroup_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureDVPortgroup_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureDVPortgroup_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureDVPortgroup_Task) (*types.ReconfigureDVPortgroup_TaskResponse, error) { + var reqBody, resBody ReconfigureDVPortgroup_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureDatacenter_TaskBody struct { + Req *types.ReconfigureDatacenter_Task `xml:"urn:vim25 ReconfigureDatacenter_Task,omitempty"` + Res *types.ReconfigureDatacenter_TaskResponse `xml:"urn:vim25 ReconfigureDatacenter_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureDatacenter_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureDatacenter_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureDatacenter_Task) (*types.ReconfigureDatacenter_TaskResponse, error) { + var reqBody, resBody ReconfigureDatacenter_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureDomObjectBody struct { + Req *types.ReconfigureDomObject `xml:"urn:vim25 ReconfigureDomObject,omitempty"` + Res *types.ReconfigureDomObjectResponse `xml:"urn:vim25 ReconfigureDomObjectResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureDomObjectBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureDomObject(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureDomObject) (*types.ReconfigureDomObjectResponse, error) { + var reqBody, resBody ReconfigureDomObjectBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureDvs_TaskBody struct { + Req *types.ReconfigureDvs_Task `xml:"urn:vim25 ReconfigureDvs_Task,omitempty"` + Res *types.ReconfigureDvs_TaskResponse `xml:"urn:vim25 ReconfigureDvs_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureDvs_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureDvs_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureDvs_Task) (*types.ReconfigureDvs_TaskResponse, error) { + var reqBody, resBody ReconfigureDvs_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureHostForDAS_TaskBody struct { + Req *types.ReconfigureHostForDAS_Task `xml:"urn:vim25 ReconfigureHostForDAS_Task,omitempty"` + Res *types.ReconfigureHostForDAS_TaskResponse `xml:"urn:vim25 ReconfigureHostForDAS_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureHostForDAS_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureHostForDAS_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureHostForDAS_Task) (*types.ReconfigureHostForDAS_TaskResponse, error) { + var reqBody, resBody ReconfigureHostForDAS_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureScheduledTaskBody struct { + Req *types.ReconfigureScheduledTask `xml:"urn:vim25 ReconfigureScheduledTask,omitempty"` + Res *types.ReconfigureScheduledTaskResponse `xml:"urn:vim25 ReconfigureScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureScheduledTask) (*types.ReconfigureScheduledTaskResponse, error) { + var reqBody, resBody ReconfigureScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureServiceConsoleReservationBody struct { + Req *types.ReconfigureServiceConsoleReservation `xml:"urn:vim25 ReconfigureServiceConsoleReservation,omitempty"` + Res *types.ReconfigureServiceConsoleReservationResponse `xml:"urn:vim25 ReconfigureServiceConsoleReservationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureServiceConsoleReservationBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureServiceConsoleReservation(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureServiceConsoleReservation) (*types.ReconfigureServiceConsoleReservationResponse, error) { + var reqBody, resBody ReconfigureServiceConsoleReservationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureSnmpAgentBody struct { + Req *types.ReconfigureSnmpAgent `xml:"urn:vim25 ReconfigureSnmpAgent,omitempty"` + Res *types.ReconfigureSnmpAgentResponse `xml:"urn:vim25 ReconfigureSnmpAgentResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureSnmpAgentBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureSnmpAgent(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureSnmpAgent) (*types.ReconfigureSnmpAgentResponse, error) { + var reqBody, resBody ReconfigureSnmpAgentBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconfigureVirtualMachineReservationBody struct { + Req *types.ReconfigureVirtualMachineReservation `xml:"urn:vim25 ReconfigureVirtualMachineReservation,omitempty"` + Res *types.ReconfigureVirtualMachineReservationResponse `xml:"urn:vim25 ReconfigureVirtualMachineReservationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconfigureVirtualMachineReservationBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconfigureVirtualMachineReservation(ctx context.Context, r soap.RoundTripper, req *types.ReconfigureVirtualMachineReservation) (*types.ReconfigureVirtualMachineReservationResponse, error) { + var reqBody, resBody ReconfigureVirtualMachineReservationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReconnectHost_TaskBody struct { + Req *types.ReconnectHost_Task `xml:"urn:vim25 ReconnectHost_Task,omitempty"` + Res *types.ReconnectHost_TaskResponse `xml:"urn:vim25 ReconnectHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReconnectHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ReconnectHost_Task(ctx context.Context, r soap.RoundTripper, req *types.ReconnectHost_Task) (*types.ReconnectHost_TaskResponse, error) { + var reqBody, resBody ReconnectHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RectifyDvsHost_TaskBody struct { + Req *types.RectifyDvsHost_Task `xml:"urn:vim25 RectifyDvsHost_Task,omitempty"` + Res *types.RectifyDvsHost_TaskResponse `xml:"urn:vim25 RectifyDvsHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RectifyDvsHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RectifyDvsHost_Task(ctx context.Context, r soap.RoundTripper, req *types.RectifyDvsHost_Task) (*types.RectifyDvsHost_TaskResponse, error) { + var reqBody, resBody RectifyDvsHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RectifyDvsOnHost_TaskBody struct { + Req *types.RectifyDvsOnHost_Task `xml:"urn:vim25 RectifyDvsOnHost_Task,omitempty"` + Res *types.RectifyDvsOnHost_TaskResponse `xml:"urn:vim25 RectifyDvsOnHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RectifyDvsOnHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RectifyDvsOnHost_Task(ctx context.Context, r soap.RoundTripper, req *types.RectifyDvsOnHost_Task) (*types.RectifyDvsOnHost_TaskResponse, error) { + var reqBody, resBody RectifyDvsOnHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshBody struct { + Req *types.Refresh `xml:"urn:vim25 Refresh,omitempty"` + Res *types.RefreshResponse `xml:"urn:vim25 RefreshResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshBody) Fault() *soap.Fault { return b.Fault_ } + +func Refresh(ctx context.Context, r soap.RoundTripper, req *types.Refresh) (*types.RefreshResponse, error) { + var reqBody, resBody RefreshBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshDVPortStateBody struct { + Req *types.RefreshDVPortState `xml:"urn:vim25 RefreshDVPortState,omitempty"` + Res *types.RefreshDVPortStateResponse `xml:"urn:vim25 RefreshDVPortStateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshDVPortStateBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshDVPortState(ctx context.Context, r soap.RoundTripper, req *types.RefreshDVPortState) (*types.RefreshDVPortStateResponse, error) { + var reqBody, resBody RefreshDVPortStateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshDatastoreBody struct { + Req *types.RefreshDatastore `xml:"urn:vim25 RefreshDatastore,omitempty"` + Res *types.RefreshDatastoreResponse `xml:"urn:vim25 RefreshDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshDatastore(ctx context.Context, r soap.RoundTripper, req *types.RefreshDatastore) (*types.RefreshDatastoreResponse, error) { + var reqBody, resBody RefreshDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshDatastoreStorageInfoBody struct { + Req *types.RefreshDatastoreStorageInfo `xml:"urn:vim25 RefreshDatastoreStorageInfo,omitempty"` + Res *types.RefreshDatastoreStorageInfoResponse `xml:"urn:vim25 RefreshDatastoreStorageInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshDatastoreStorageInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshDatastoreStorageInfo(ctx context.Context, r soap.RoundTripper, req *types.RefreshDatastoreStorageInfo) (*types.RefreshDatastoreStorageInfoResponse, error) { + var reqBody, resBody RefreshDatastoreStorageInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshDateTimeSystemBody struct { + Req *types.RefreshDateTimeSystem `xml:"urn:vim25 RefreshDateTimeSystem,omitempty"` + Res *types.RefreshDateTimeSystemResponse `xml:"urn:vim25 RefreshDateTimeSystemResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshDateTimeSystemBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshDateTimeSystem(ctx context.Context, r soap.RoundTripper, req *types.RefreshDateTimeSystem) (*types.RefreshDateTimeSystemResponse, error) { + var reqBody, resBody RefreshDateTimeSystemBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshFirewallBody struct { + Req *types.RefreshFirewall `xml:"urn:vim25 RefreshFirewall,omitempty"` + Res *types.RefreshFirewallResponse `xml:"urn:vim25 RefreshFirewallResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshFirewallBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshFirewall(ctx context.Context, r soap.RoundTripper, req *types.RefreshFirewall) (*types.RefreshFirewallResponse, error) { + var reqBody, resBody RefreshFirewallBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshGraphicsManagerBody struct { + Req *types.RefreshGraphicsManager `xml:"urn:vim25 RefreshGraphicsManager,omitempty"` + Res *types.RefreshGraphicsManagerResponse `xml:"urn:vim25 RefreshGraphicsManagerResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshGraphicsManagerBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshGraphicsManager(ctx context.Context, r soap.RoundTripper, req *types.RefreshGraphicsManager) (*types.RefreshGraphicsManagerResponse, error) { + var reqBody, resBody RefreshGraphicsManagerBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshHealthStatusSystemBody struct { + Req *types.RefreshHealthStatusSystem `xml:"urn:vim25 RefreshHealthStatusSystem,omitempty"` + Res *types.RefreshHealthStatusSystemResponse `xml:"urn:vim25 RefreshHealthStatusSystemResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshHealthStatusSystemBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshHealthStatusSystem(ctx context.Context, r soap.RoundTripper, req *types.RefreshHealthStatusSystem) (*types.RefreshHealthStatusSystemResponse, error) { + var reqBody, resBody RefreshHealthStatusSystemBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshNetworkSystemBody struct { + Req *types.RefreshNetworkSystem `xml:"urn:vim25 RefreshNetworkSystem,omitempty"` + Res *types.RefreshNetworkSystemResponse `xml:"urn:vim25 RefreshNetworkSystemResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshNetworkSystemBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshNetworkSystem(ctx context.Context, r soap.RoundTripper, req *types.RefreshNetworkSystem) (*types.RefreshNetworkSystemResponse, error) { + var reqBody, resBody RefreshNetworkSystemBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshRecommendationBody struct { + Req *types.RefreshRecommendation `xml:"urn:vim25 RefreshRecommendation,omitempty"` + Res *types.RefreshRecommendationResponse `xml:"urn:vim25 RefreshRecommendationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshRecommendationBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshRecommendation(ctx context.Context, r soap.RoundTripper, req *types.RefreshRecommendation) (*types.RefreshRecommendationResponse, error) { + var reqBody, resBody RefreshRecommendationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshRuntimeBody struct { + Req *types.RefreshRuntime `xml:"urn:vim25 RefreshRuntime,omitempty"` + Res *types.RefreshRuntimeResponse `xml:"urn:vim25 RefreshRuntimeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshRuntimeBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshRuntime(ctx context.Context, r soap.RoundTripper, req *types.RefreshRuntime) (*types.RefreshRuntimeResponse, error) { + var reqBody, resBody RefreshRuntimeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshServicesBody struct { + Req *types.RefreshServices `xml:"urn:vim25 RefreshServices,omitempty"` + Res *types.RefreshServicesResponse `xml:"urn:vim25 RefreshServicesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshServicesBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshServices(ctx context.Context, r soap.RoundTripper, req *types.RefreshServices) (*types.RefreshServicesResponse, error) { + var reqBody, resBody RefreshServicesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshStorageDrsRecommendationBody struct { + Req *types.RefreshStorageDrsRecommendation `xml:"urn:vim25 RefreshStorageDrsRecommendation,omitempty"` + Res *types.RefreshStorageDrsRecommendationResponse `xml:"urn:vim25 RefreshStorageDrsRecommendationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshStorageDrsRecommendationBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshStorageDrsRecommendation(ctx context.Context, r soap.RoundTripper, req *types.RefreshStorageDrsRecommendation) (*types.RefreshStorageDrsRecommendationResponse, error) { + var reqBody, resBody RefreshStorageDrsRecommendationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshStorageInfoBody struct { + Req *types.RefreshStorageInfo `xml:"urn:vim25 RefreshStorageInfo,omitempty"` + Res *types.RefreshStorageInfoResponse `xml:"urn:vim25 RefreshStorageInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshStorageInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshStorageInfo(ctx context.Context, r soap.RoundTripper, req *types.RefreshStorageInfo) (*types.RefreshStorageInfoResponse, error) { + var reqBody, resBody RefreshStorageInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RefreshStorageSystemBody struct { + Req *types.RefreshStorageSystem `xml:"urn:vim25 RefreshStorageSystem,omitempty"` + Res *types.RefreshStorageSystemResponse `xml:"urn:vim25 RefreshStorageSystemResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RefreshStorageSystemBody) Fault() *soap.Fault { return b.Fault_ } + +func RefreshStorageSystem(ctx context.Context, r soap.RoundTripper, req *types.RefreshStorageSystem) (*types.RefreshStorageSystemResponse, error) { + var reqBody, resBody RefreshStorageSystemBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RegisterChildVM_TaskBody struct { + Req *types.RegisterChildVM_Task `xml:"urn:vim25 RegisterChildVM_Task,omitempty"` + Res *types.RegisterChildVM_TaskResponse `xml:"urn:vim25 RegisterChildVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RegisterChildVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RegisterChildVM_Task(ctx context.Context, r soap.RoundTripper, req *types.RegisterChildVM_Task) (*types.RegisterChildVM_TaskResponse, error) { + var reqBody, resBody RegisterChildVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RegisterExtensionBody struct { + Req *types.RegisterExtension `xml:"urn:vim25 RegisterExtension,omitempty"` + Res *types.RegisterExtensionResponse `xml:"urn:vim25 RegisterExtensionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RegisterExtensionBody) Fault() *soap.Fault { return b.Fault_ } + +func RegisterExtension(ctx context.Context, r soap.RoundTripper, req *types.RegisterExtension) (*types.RegisterExtensionResponse, error) { + var reqBody, resBody RegisterExtensionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RegisterVM_TaskBody struct { + Req *types.RegisterVM_Task `xml:"urn:vim25 RegisterVM_Task,omitempty"` + Res *types.RegisterVM_TaskResponse `xml:"urn:vim25 RegisterVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RegisterVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RegisterVM_Task(ctx context.Context, r soap.RoundTripper, req *types.RegisterVM_Task) (*types.RegisterVM_TaskResponse, error) { + var reqBody, resBody RegisterVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReleaseCredentialsInGuestBody struct { + Req *types.ReleaseCredentialsInGuest `xml:"urn:vim25 ReleaseCredentialsInGuest,omitempty"` + Res *types.ReleaseCredentialsInGuestResponse `xml:"urn:vim25 ReleaseCredentialsInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReleaseCredentialsInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ReleaseCredentialsInGuest(ctx context.Context, r soap.RoundTripper, req *types.ReleaseCredentialsInGuest) (*types.ReleaseCredentialsInGuestResponse, error) { + var reqBody, resBody ReleaseCredentialsInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReleaseIpAllocationBody struct { + Req *types.ReleaseIpAllocation `xml:"urn:vim25 ReleaseIpAllocation,omitempty"` + Res *types.ReleaseIpAllocationResponse `xml:"urn:vim25 ReleaseIpAllocationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReleaseIpAllocationBody) Fault() *soap.Fault { return b.Fault_ } + +func ReleaseIpAllocation(ctx context.Context, r soap.RoundTripper, req *types.ReleaseIpAllocation) (*types.ReleaseIpAllocationResponse, error) { + var reqBody, resBody ReleaseIpAllocationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReloadBody struct { + Req *types.Reload `xml:"urn:vim25 Reload,omitempty"` + Res *types.ReloadResponse `xml:"urn:vim25 ReloadResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReloadBody) Fault() *soap.Fault { return b.Fault_ } + +func Reload(ctx context.Context, r soap.RoundTripper, req *types.Reload) (*types.ReloadResponse, error) { + var reqBody, resBody ReloadBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RelocateVM_TaskBody struct { + Req *types.RelocateVM_Task `xml:"urn:vim25 RelocateVM_Task,omitempty"` + Res *types.RelocateVM_TaskResponse `xml:"urn:vim25 RelocateVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RelocateVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RelocateVM_Task(ctx context.Context, r soap.RoundTripper, req *types.RelocateVM_Task) (*types.RelocateVM_TaskResponse, error) { + var reqBody, resBody RelocateVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveAlarmBody struct { + Req *types.RemoveAlarm `xml:"urn:vim25 RemoveAlarm,omitempty"` + Res *types.RemoveAlarmResponse `xml:"urn:vim25 RemoveAlarmResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveAlarmBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveAlarm(ctx context.Context, r soap.RoundTripper, req *types.RemoveAlarm) (*types.RemoveAlarmResponse, error) { + var reqBody, resBody RemoveAlarmBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveAllSnapshots_TaskBody struct { + Req *types.RemoveAllSnapshots_Task `xml:"urn:vim25 RemoveAllSnapshots_Task,omitempty"` + Res *types.RemoveAllSnapshots_TaskResponse `xml:"urn:vim25 RemoveAllSnapshots_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveAllSnapshots_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveAllSnapshots_Task(ctx context.Context, r soap.RoundTripper, req *types.RemoveAllSnapshots_Task) (*types.RemoveAllSnapshots_TaskResponse, error) { + var reqBody, resBody RemoveAllSnapshots_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveAssignedLicenseBody struct { + Req *types.RemoveAssignedLicense `xml:"urn:vim25 RemoveAssignedLicense,omitempty"` + Res *types.RemoveAssignedLicenseResponse `xml:"urn:vim25 RemoveAssignedLicenseResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveAssignedLicenseBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveAssignedLicense(ctx context.Context, r soap.RoundTripper, req *types.RemoveAssignedLicense) (*types.RemoveAssignedLicenseResponse, error) { + var reqBody, resBody RemoveAssignedLicenseBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveAuthorizationRoleBody struct { + Req *types.RemoveAuthorizationRole `xml:"urn:vim25 RemoveAuthorizationRole,omitempty"` + Res *types.RemoveAuthorizationRoleResponse `xml:"urn:vim25 RemoveAuthorizationRoleResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveAuthorizationRoleBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveAuthorizationRole(ctx context.Context, r soap.RoundTripper, req *types.RemoveAuthorizationRole) (*types.RemoveAuthorizationRoleResponse, error) { + var reqBody, resBody RemoveAuthorizationRoleBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveCustomFieldDefBody struct { + Req *types.RemoveCustomFieldDef `xml:"urn:vim25 RemoveCustomFieldDef,omitempty"` + Res *types.RemoveCustomFieldDefResponse `xml:"urn:vim25 RemoveCustomFieldDefResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveCustomFieldDefBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveCustomFieldDef(ctx context.Context, r soap.RoundTripper, req *types.RemoveCustomFieldDef) (*types.RemoveCustomFieldDefResponse, error) { + var reqBody, resBody RemoveCustomFieldDefBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveDatastoreBody struct { + Req *types.RemoveDatastore `xml:"urn:vim25 RemoveDatastore,omitempty"` + Res *types.RemoveDatastoreResponse `xml:"urn:vim25 RemoveDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveDatastore(ctx context.Context, r soap.RoundTripper, req *types.RemoveDatastore) (*types.RemoveDatastoreResponse, error) { + var reqBody, resBody RemoveDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveDatastoreEx_TaskBody struct { + Req *types.RemoveDatastoreEx_Task `xml:"urn:vim25 RemoveDatastoreEx_Task,omitempty"` + Res *types.RemoveDatastoreEx_TaskResponse `xml:"urn:vim25 RemoveDatastoreEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveDatastoreEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveDatastoreEx_Task(ctx context.Context, r soap.RoundTripper, req *types.RemoveDatastoreEx_Task) (*types.RemoveDatastoreEx_TaskResponse, error) { + var reqBody, resBody RemoveDatastoreEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveDiskMapping_TaskBody struct { + Req *types.RemoveDiskMapping_Task `xml:"urn:vim25 RemoveDiskMapping_Task,omitempty"` + Res *types.RemoveDiskMapping_TaskResponse `xml:"urn:vim25 RemoveDiskMapping_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveDiskMapping_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveDiskMapping_Task(ctx context.Context, r soap.RoundTripper, req *types.RemoveDiskMapping_Task) (*types.RemoveDiskMapping_TaskResponse, error) { + var reqBody, resBody RemoveDiskMapping_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveDisk_TaskBody struct { + Req *types.RemoveDisk_Task `xml:"urn:vim25 RemoveDisk_Task,omitempty"` + Res *types.RemoveDisk_TaskResponse `xml:"urn:vim25 RemoveDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.RemoveDisk_Task) (*types.RemoveDisk_TaskResponse, error) { + var reqBody, resBody RemoveDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveEntityPermissionBody struct { + Req *types.RemoveEntityPermission `xml:"urn:vim25 RemoveEntityPermission,omitempty"` + Res *types.RemoveEntityPermissionResponse `xml:"urn:vim25 RemoveEntityPermissionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveEntityPermissionBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveEntityPermission(ctx context.Context, r soap.RoundTripper, req *types.RemoveEntityPermission) (*types.RemoveEntityPermissionResponse, error) { + var reqBody, resBody RemoveEntityPermissionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveGroupBody struct { + Req *types.RemoveGroup `xml:"urn:vim25 RemoveGroup,omitempty"` + Res *types.RemoveGroupResponse `xml:"urn:vim25 RemoveGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveGroup(ctx context.Context, r soap.RoundTripper, req *types.RemoveGroup) (*types.RemoveGroupResponse, error) { + var reqBody, resBody RemoveGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveGuestAliasBody struct { + Req *types.RemoveGuestAlias `xml:"urn:vim25 RemoveGuestAlias,omitempty"` + Res *types.RemoveGuestAliasResponse `xml:"urn:vim25 RemoveGuestAliasResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveGuestAliasBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveGuestAlias(ctx context.Context, r soap.RoundTripper, req *types.RemoveGuestAlias) (*types.RemoveGuestAliasResponse, error) { + var reqBody, resBody RemoveGuestAliasBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveGuestAliasByCertBody struct { + Req *types.RemoveGuestAliasByCert `xml:"urn:vim25 RemoveGuestAliasByCert,omitempty"` + Res *types.RemoveGuestAliasByCertResponse `xml:"urn:vim25 RemoveGuestAliasByCertResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveGuestAliasByCertBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveGuestAliasByCert(ctx context.Context, r soap.RoundTripper, req *types.RemoveGuestAliasByCert) (*types.RemoveGuestAliasByCertResponse, error) { + var reqBody, resBody RemoveGuestAliasByCertBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveInternetScsiSendTargetsBody struct { + Req *types.RemoveInternetScsiSendTargets `xml:"urn:vim25 RemoveInternetScsiSendTargets,omitempty"` + Res *types.RemoveInternetScsiSendTargetsResponse `xml:"urn:vim25 RemoveInternetScsiSendTargetsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveInternetScsiSendTargetsBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveInternetScsiSendTargets(ctx context.Context, r soap.RoundTripper, req *types.RemoveInternetScsiSendTargets) (*types.RemoveInternetScsiSendTargetsResponse, error) { + var reqBody, resBody RemoveInternetScsiSendTargetsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveInternetScsiStaticTargetsBody struct { + Req *types.RemoveInternetScsiStaticTargets `xml:"urn:vim25 RemoveInternetScsiStaticTargets,omitempty"` + Res *types.RemoveInternetScsiStaticTargetsResponse `xml:"urn:vim25 RemoveInternetScsiStaticTargetsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveInternetScsiStaticTargetsBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveInternetScsiStaticTargets(ctx context.Context, r soap.RoundTripper, req *types.RemoveInternetScsiStaticTargets) (*types.RemoveInternetScsiStaticTargetsResponse, error) { + var reqBody, resBody RemoveInternetScsiStaticTargetsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveLicenseBody struct { + Req *types.RemoveLicense `xml:"urn:vim25 RemoveLicense,omitempty"` + Res *types.RemoveLicenseResponse `xml:"urn:vim25 RemoveLicenseResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveLicenseBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveLicense(ctx context.Context, r soap.RoundTripper, req *types.RemoveLicense) (*types.RemoveLicenseResponse, error) { + var reqBody, resBody RemoveLicenseBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveLicenseLabelBody struct { + Req *types.RemoveLicenseLabel `xml:"urn:vim25 RemoveLicenseLabel,omitempty"` + Res *types.RemoveLicenseLabelResponse `xml:"urn:vim25 RemoveLicenseLabelResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveLicenseLabelBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveLicenseLabel(ctx context.Context, r soap.RoundTripper, req *types.RemoveLicenseLabel) (*types.RemoveLicenseLabelResponse, error) { + var reqBody, resBody RemoveLicenseLabelBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveNetworkResourcePoolBody struct { + Req *types.RemoveNetworkResourcePool `xml:"urn:vim25 RemoveNetworkResourcePool,omitempty"` + Res *types.RemoveNetworkResourcePoolResponse `xml:"urn:vim25 RemoveNetworkResourcePoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveNetworkResourcePoolBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveNetworkResourcePool(ctx context.Context, r soap.RoundTripper, req *types.RemoveNetworkResourcePool) (*types.RemoveNetworkResourcePoolResponse, error) { + var reqBody, resBody RemoveNetworkResourcePoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemovePerfIntervalBody struct { + Req *types.RemovePerfInterval `xml:"urn:vim25 RemovePerfInterval,omitempty"` + Res *types.RemovePerfIntervalResponse `xml:"urn:vim25 RemovePerfIntervalResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemovePerfIntervalBody) Fault() *soap.Fault { return b.Fault_ } + +func RemovePerfInterval(ctx context.Context, r soap.RoundTripper, req *types.RemovePerfInterval) (*types.RemovePerfIntervalResponse, error) { + var reqBody, resBody RemovePerfIntervalBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemovePortGroupBody struct { + Req *types.RemovePortGroup `xml:"urn:vim25 RemovePortGroup,omitempty"` + Res *types.RemovePortGroupResponse `xml:"urn:vim25 RemovePortGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemovePortGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func RemovePortGroup(ctx context.Context, r soap.RoundTripper, req *types.RemovePortGroup) (*types.RemovePortGroupResponse, error) { + var reqBody, resBody RemovePortGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveScheduledTaskBody struct { + Req *types.RemoveScheduledTask `xml:"urn:vim25 RemoveScheduledTask,omitempty"` + Res *types.RemoveScheduledTaskResponse `xml:"urn:vim25 RemoveScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.RemoveScheduledTask) (*types.RemoveScheduledTaskResponse, error) { + var reqBody, resBody RemoveScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveServiceConsoleVirtualNicBody struct { + Req *types.RemoveServiceConsoleVirtualNic `xml:"urn:vim25 RemoveServiceConsoleVirtualNic,omitempty"` + Res *types.RemoveServiceConsoleVirtualNicResponse `xml:"urn:vim25 RemoveServiceConsoleVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveServiceConsoleVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveServiceConsoleVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.RemoveServiceConsoleVirtualNic) (*types.RemoveServiceConsoleVirtualNicResponse, error) { + var reqBody, resBody RemoveServiceConsoleVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveSmartCardTrustAnchorBody struct { + Req *types.RemoveSmartCardTrustAnchor `xml:"urn:vim25 RemoveSmartCardTrustAnchor,omitempty"` + Res *types.RemoveSmartCardTrustAnchorResponse `xml:"urn:vim25 RemoveSmartCardTrustAnchorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveSmartCardTrustAnchorBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveSmartCardTrustAnchor(ctx context.Context, r soap.RoundTripper, req *types.RemoveSmartCardTrustAnchor) (*types.RemoveSmartCardTrustAnchorResponse, error) { + var reqBody, resBody RemoveSmartCardTrustAnchorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveSmartCardTrustAnchorByFingerprintBody struct { + Req *types.RemoveSmartCardTrustAnchorByFingerprint `xml:"urn:vim25 RemoveSmartCardTrustAnchorByFingerprint,omitempty"` + Res *types.RemoveSmartCardTrustAnchorByFingerprintResponse `xml:"urn:vim25 RemoveSmartCardTrustAnchorByFingerprintResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveSmartCardTrustAnchorByFingerprintBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveSmartCardTrustAnchorByFingerprint(ctx context.Context, r soap.RoundTripper, req *types.RemoveSmartCardTrustAnchorByFingerprint) (*types.RemoveSmartCardTrustAnchorByFingerprintResponse, error) { + var reqBody, resBody RemoveSmartCardTrustAnchorByFingerprintBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveSnapshot_TaskBody struct { + Req *types.RemoveSnapshot_Task `xml:"urn:vim25 RemoveSnapshot_Task,omitempty"` + Res *types.RemoveSnapshot_TaskResponse `xml:"urn:vim25 RemoveSnapshot_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveSnapshot_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveSnapshot_Task(ctx context.Context, r soap.RoundTripper, req *types.RemoveSnapshot_Task) (*types.RemoveSnapshot_TaskResponse, error) { + var reqBody, resBody RemoveSnapshot_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveUserBody struct { + Req *types.RemoveUser `xml:"urn:vim25 RemoveUser,omitempty"` + Res *types.RemoveUserResponse `xml:"urn:vim25 RemoveUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveUserBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveUser(ctx context.Context, r soap.RoundTripper, req *types.RemoveUser) (*types.RemoveUserResponse, error) { + var reqBody, resBody RemoveUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveVirtualNicBody struct { + Req *types.RemoveVirtualNic `xml:"urn:vim25 RemoveVirtualNic,omitempty"` + Res *types.RemoveVirtualNicResponse `xml:"urn:vim25 RemoveVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.RemoveVirtualNic) (*types.RemoveVirtualNicResponse, error) { + var reqBody, resBody RemoveVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RemoveVirtualSwitchBody struct { + Req *types.RemoveVirtualSwitch `xml:"urn:vim25 RemoveVirtualSwitch,omitempty"` + Res *types.RemoveVirtualSwitchResponse `xml:"urn:vim25 RemoveVirtualSwitchResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RemoveVirtualSwitchBody) Fault() *soap.Fault { return b.Fault_ } + +func RemoveVirtualSwitch(ctx context.Context, r soap.RoundTripper, req *types.RemoveVirtualSwitch) (*types.RemoveVirtualSwitchResponse, error) { + var reqBody, resBody RemoveVirtualSwitchBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RenameCustomFieldDefBody struct { + Req *types.RenameCustomFieldDef `xml:"urn:vim25 RenameCustomFieldDef,omitempty"` + Res *types.RenameCustomFieldDefResponse `xml:"urn:vim25 RenameCustomFieldDefResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RenameCustomFieldDefBody) Fault() *soap.Fault { return b.Fault_ } + +func RenameCustomFieldDef(ctx context.Context, r soap.RoundTripper, req *types.RenameCustomFieldDef) (*types.RenameCustomFieldDefResponse, error) { + var reqBody, resBody RenameCustomFieldDefBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RenameCustomizationSpecBody struct { + Req *types.RenameCustomizationSpec `xml:"urn:vim25 RenameCustomizationSpec,omitempty"` + Res *types.RenameCustomizationSpecResponse `xml:"urn:vim25 RenameCustomizationSpecResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RenameCustomizationSpecBody) Fault() *soap.Fault { return b.Fault_ } + +func RenameCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.RenameCustomizationSpec) (*types.RenameCustomizationSpecResponse, error) { + var reqBody, resBody RenameCustomizationSpecBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RenameDatastoreBody struct { + Req *types.RenameDatastore `xml:"urn:vim25 RenameDatastore,omitempty"` + Res *types.RenameDatastoreResponse `xml:"urn:vim25 RenameDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RenameDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func RenameDatastore(ctx context.Context, r soap.RoundTripper, req *types.RenameDatastore) (*types.RenameDatastoreResponse, error) { + var reqBody, resBody RenameDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RenameSnapshotBody struct { + Req *types.RenameSnapshot `xml:"urn:vim25 RenameSnapshot,omitempty"` + Res *types.RenameSnapshotResponse `xml:"urn:vim25 RenameSnapshotResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RenameSnapshotBody) Fault() *soap.Fault { return b.Fault_ } + +func RenameSnapshot(ctx context.Context, r soap.RoundTripper, req *types.RenameSnapshot) (*types.RenameSnapshotResponse, error) { + var reqBody, resBody RenameSnapshotBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type Rename_TaskBody struct { + Req *types.Rename_Task `xml:"urn:vim25 Rename_Task,omitempty"` + Res *types.Rename_TaskResponse `xml:"urn:vim25 Rename_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *Rename_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func Rename_Task(ctx context.Context, r soap.RoundTripper, req *types.Rename_Task) (*types.Rename_TaskResponse, error) { + var reqBody, resBody Rename_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReplaceCACertificatesAndCRLsBody struct { + Req *types.ReplaceCACertificatesAndCRLs `xml:"urn:vim25 ReplaceCACertificatesAndCRLs,omitempty"` + Res *types.ReplaceCACertificatesAndCRLsResponse `xml:"urn:vim25 ReplaceCACertificatesAndCRLsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReplaceCACertificatesAndCRLsBody) Fault() *soap.Fault { return b.Fault_ } + +func ReplaceCACertificatesAndCRLs(ctx context.Context, r soap.RoundTripper, req *types.ReplaceCACertificatesAndCRLs) (*types.ReplaceCACertificatesAndCRLsResponse, error) { + var reqBody, resBody ReplaceCACertificatesAndCRLsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ReplaceSmartCardTrustAnchorsBody struct { + Req *types.ReplaceSmartCardTrustAnchors `xml:"urn:vim25 ReplaceSmartCardTrustAnchors,omitempty"` + Res *types.ReplaceSmartCardTrustAnchorsResponse `xml:"urn:vim25 ReplaceSmartCardTrustAnchorsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ReplaceSmartCardTrustAnchorsBody) Fault() *soap.Fault { return b.Fault_ } + +func ReplaceSmartCardTrustAnchors(ctx context.Context, r soap.RoundTripper, req *types.ReplaceSmartCardTrustAnchors) (*types.ReplaceSmartCardTrustAnchorsResponse, error) { + var reqBody, resBody ReplaceSmartCardTrustAnchorsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RescanAllHbaBody struct { + Req *types.RescanAllHba `xml:"urn:vim25 RescanAllHba,omitempty"` + Res *types.RescanAllHbaResponse `xml:"urn:vim25 RescanAllHbaResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RescanAllHbaBody) Fault() *soap.Fault { return b.Fault_ } + +func RescanAllHba(ctx context.Context, r soap.RoundTripper, req *types.RescanAllHba) (*types.RescanAllHbaResponse, error) { + var reqBody, resBody RescanAllHbaBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RescanHbaBody struct { + Req *types.RescanHba `xml:"urn:vim25 RescanHba,omitempty"` + Res *types.RescanHbaResponse `xml:"urn:vim25 RescanHbaResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RescanHbaBody) Fault() *soap.Fault { return b.Fault_ } + +func RescanHba(ctx context.Context, r soap.RoundTripper, req *types.RescanHba) (*types.RescanHbaResponse, error) { + var reqBody, resBody RescanHbaBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RescanVffsBody struct { + Req *types.RescanVffs `xml:"urn:vim25 RescanVffs,omitempty"` + Res *types.RescanVffsResponse `xml:"urn:vim25 RescanVffsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RescanVffsBody) Fault() *soap.Fault { return b.Fault_ } + +func RescanVffs(ctx context.Context, r soap.RoundTripper, req *types.RescanVffs) (*types.RescanVffsResponse, error) { + var reqBody, resBody RescanVffsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RescanVmfsBody struct { + Req *types.RescanVmfs `xml:"urn:vim25 RescanVmfs,omitempty"` + Res *types.RescanVmfsResponse `xml:"urn:vim25 RescanVmfsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RescanVmfsBody) Fault() *soap.Fault { return b.Fault_ } + +func RescanVmfs(ctx context.Context, r soap.RoundTripper, req *types.RescanVmfs) (*types.RescanVmfsResponse, error) { + var reqBody, resBody RescanVmfsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetCollectorBody struct { + Req *types.ResetCollector `xml:"urn:vim25 ResetCollector,omitempty"` + Res *types.ResetCollectorResponse `xml:"urn:vim25 ResetCollectorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetCollectorBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetCollector(ctx context.Context, r soap.RoundTripper, req *types.ResetCollector) (*types.ResetCollectorResponse, error) { + var reqBody, resBody ResetCollectorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetCounterLevelMappingBody struct { + Req *types.ResetCounterLevelMapping `xml:"urn:vim25 ResetCounterLevelMapping,omitempty"` + Res *types.ResetCounterLevelMappingResponse `xml:"urn:vim25 ResetCounterLevelMappingResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetCounterLevelMappingBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetCounterLevelMapping(ctx context.Context, r soap.RoundTripper, req *types.ResetCounterLevelMapping) (*types.ResetCounterLevelMappingResponse, error) { + var reqBody, resBody ResetCounterLevelMappingBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetEntityPermissionsBody struct { + Req *types.ResetEntityPermissions `xml:"urn:vim25 ResetEntityPermissions,omitempty"` + Res *types.ResetEntityPermissionsResponse `xml:"urn:vim25 ResetEntityPermissionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetEntityPermissionsBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetEntityPermissions(ctx context.Context, r soap.RoundTripper, req *types.ResetEntityPermissions) (*types.ResetEntityPermissionsResponse, error) { + var reqBody, resBody ResetEntityPermissionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetFirmwareToFactoryDefaultsBody struct { + Req *types.ResetFirmwareToFactoryDefaults `xml:"urn:vim25 ResetFirmwareToFactoryDefaults,omitempty"` + Res *types.ResetFirmwareToFactoryDefaultsResponse `xml:"urn:vim25 ResetFirmwareToFactoryDefaultsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetFirmwareToFactoryDefaultsBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetFirmwareToFactoryDefaults(ctx context.Context, r soap.RoundTripper, req *types.ResetFirmwareToFactoryDefaults) (*types.ResetFirmwareToFactoryDefaultsResponse, error) { + var reqBody, resBody ResetFirmwareToFactoryDefaultsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetGuestInformationBody struct { + Req *types.ResetGuestInformation `xml:"urn:vim25 ResetGuestInformation,omitempty"` + Res *types.ResetGuestInformationResponse `xml:"urn:vim25 ResetGuestInformationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetGuestInformationBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetGuestInformation(ctx context.Context, r soap.RoundTripper, req *types.ResetGuestInformation) (*types.ResetGuestInformationResponse, error) { + var reqBody, resBody ResetGuestInformationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetListViewBody struct { + Req *types.ResetListView `xml:"urn:vim25 ResetListView,omitempty"` + Res *types.ResetListViewResponse `xml:"urn:vim25 ResetListViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetListViewBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetListView(ctx context.Context, r soap.RoundTripper, req *types.ResetListView) (*types.ResetListViewResponse, error) { + var reqBody, resBody ResetListViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetListViewFromViewBody struct { + Req *types.ResetListViewFromView `xml:"urn:vim25 ResetListViewFromView,omitempty"` + Res *types.ResetListViewFromViewResponse `xml:"urn:vim25 ResetListViewFromViewResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetListViewFromViewBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetListViewFromView(ctx context.Context, r soap.RoundTripper, req *types.ResetListViewFromView) (*types.ResetListViewFromViewResponse, error) { + var reqBody, resBody ResetListViewFromViewBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetSystemHealthInfoBody struct { + Req *types.ResetSystemHealthInfo `xml:"urn:vim25 ResetSystemHealthInfo,omitempty"` + Res *types.ResetSystemHealthInfoResponse `xml:"urn:vim25 ResetSystemHealthInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetSystemHealthInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetSystemHealthInfo(ctx context.Context, r soap.RoundTripper, req *types.ResetSystemHealthInfo) (*types.ResetSystemHealthInfoResponse, error) { + var reqBody, resBody ResetSystemHealthInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResetVM_TaskBody struct { + Req *types.ResetVM_Task `xml:"urn:vim25 ResetVM_Task,omitempty"` + Res *types.ResetVM_TaskResponse `xml:"urn:vim25 ResetVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResetVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ResetVM_Task(ctx context.Context, r soap.RoundTripper, req *types.ResetVM_Task) (*types.ResetVM_TaskResponse, error) { + var reqBody, resBody ResetVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResignatureUnresolvedVmfsVolume_TaskBody struct { + Req *types.ResignatureUnresolvedVmfsVolume_Task `xml:"urn:vim25 ResignatureUnresolvedVmfsVolume_Task,omitempty"` + Res *types.ResignatureUnresolvedVmfsVolume_TaskResponse `xml:"urn:vim25 ResignatureUnresolvedVmfsVolume_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResignatureUnresolvedVmfsVolume_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ResignatureUnresolvedVmfsVolume_Task(ctx context.Context, r soap.RoundTripper, req *types.ResignatureUnresolvedVmfsVolume_Task) (*types.ResignatureUnresolvedVmfsVolume_TaskResponse, error) { + var reqBody, resBody ResignatureUnresolvedVmfsVolume_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResolveInstallationErrorsOnCluster_TaskBody struct { + Req *types.ResolveInstallationErrorsOnCluster_Task `xml:"urn:vim25 ResolveInstallationErrorsOnCluster_Task,omitempty"` + Res *types.ResolveInstallationErrorsOnCluster_TaskResponse `xml:"urn:vim25 ResolveInstallationErrorsOnCluster_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResolveInstallationErrorsOnCluster_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ResolveInstallationErrorsOnCluster_Task(ctx context.Context, r soap.RoundTripper, req *types.ResolveInstallationErrorsOnCluster_Task) (*types.ResolveInstallationErrorsOnCluster_TaskResponse, error) { + var reqBody, resBody ResolveInstallationErrorsOnCluster_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResolveInstallationErrorsOnHost_TaskBody struct { + Req *types.ResolveInstallationErrorsOnHost_Task `xml:"urn:vim25 ResolveInstallationErrorsOnHost_Task,omitempty"` + Res *types.ResolveInstallationErrorsOnHost_TaskResponse `xml:"urn:vim25 ResolveInstallationErrorsOnHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResolveInstallationErrorsOnHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ResolveInstallationErrorsOnHost_Task(ctx context.Context, r soap.RoundTripper, req *types.ResolveInstallationErrorsOnHost_Task) (*types.ResolveInstallationErrorsOnHost_TaskResponse, error) { + var reqBody, resBody ResolveInstallationErrorsOnHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResolveMultipleUnresolvedVmfsVolumesBody struct { + Req *types.ResolveMultipleUnresolvedVmfsVolumes `xml:"urn:vim25 ResolveMultipleUnresolvedVmfsVolumes,omitempty"` + Res *types.ResolveMultipleUnresolvedVmfsVolumesResponse `xml:"urn:vim25 ResolveMultipleUnresolvedVmfsVolumesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResolveMultipleUnresolvedVmfsVolumesBody) Fault() *soap.Fault { return b.Fault_ } + +func ResolveMultipleUnresolvedVmfsVolumes(ctx context.Context, r soap.RoundTripper, req *types.ResolveMultipleUnresolvedVmfsVolumes) (*types.ResolveMultipleUnresolvedVmfsVolumesResponse, error) { + var reqBody, resBody ResolveMultipleUnresolvedVmfsVolumesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ResolveMultipleUnresolvedVmfsVolumesEx_TaskBody struct { + Req *types.ResolveMultipleUnresolvedVmfsVolumesEx_Task `xml:"urn:vim25 ResolveMultipleUnresolvedVmfsVolumesEx_Task,omitempty"` + Res *types.ResolveMultipleUnresolvedVmfsVolumesEx_TaskResponse `xml:"urn:vim25 ResolveMultipleUnresolvedVmfsVolumesEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ResolveMultipleUnresolvedVmfsVolumesEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ResolveMultipleUnresolvedVmfsVolumesEx_Task(ctx context.Context, r soap.RoundTripper, req *types.ResolveMultipleUnresolvedVmfsVolumesEx_Task) (*types.ResolveMultipleUnresolvedVmfsVolumesEx_TaskResponse, error) { + var reqBody, resBody ResolveMultipleUnresolvedVmfsVolumesEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RestartServiceBody struct { + Req *types.RestartService `xml:"urn:vim25 RestartService,omitempty"` + Res *types.RestartServiceResponse `xml:"urn:vim25 RestartServiceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RestartServiceBody) Fault() *soap.Fault { return b.Fault_ } + +func RestartService(ctx context.Context, r soap.RoundTripper, req *types.RestartService) (*types.RestartServiceResponse, error) { + var reqBody, resBody RestartServiceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RestartServiceConsoleVirtualNicBody struct { + Req *types.RestartServiceConsoleVirtualNic `xml:"urn:vim25 RestartServiceConsoleVirtualNic,omitempty"` + Res *types.RestartServiceConsoleVirtualNicResponse `xml:"urn:vim25 RestartServiceConsoleVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RestartServiceConsoleVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func RestartServiceConsoleVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.RestartServiceConsoleVirtualNic) (*types.RestartServiceConsoleVirtualNicResponse, error) { + var reqBody, resBody RestartServiceConsoleVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RestoreFirmwareConfigurationBody struct { + Req *types.RestoreFirmwareConfiguration `xml:"urn:vim25 RestoreFirmwareConfiguration,omitempty"` + Res *types.RestoreFirmwareConfigurationResponse `xml:"urn:vim25 RestoreFirmwareConfigurationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RestoreFirmwareConfigurationBody) Fault() *soap.Fault { return b.Fault_ } + +func RestoreFirmwareConfiguration(ctx context.Context, r soap.RoundTripper, req *types.RestoreFirmwareConfiguration) (*types.RestoreFirmwareConfigurationResponse, error) { + var reqBody, resBody RestoreFirmwareConfigurationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveAllPermissionsBody struct { + Req *types.RetrieveAllPermissions `xml:"urn:vim25 RetrieveAllPermissions,omitempty"` + Res *types.RetrieveAllPermissionsResponse `xml:"urn:vim25 RetrieveAllPermissionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveAllPermissionsBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveAllPermissions(ctx context.Context, r soap.RoundTripper, req *types.RetrieveAllPermissions) (*types.RetrieveAllPermissionsResponse, error) { + var reqBody, resBody RetrieveAllPermissionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveAnswerFileBody struct { + Req *types.RetrieveAnswerFile `xml:"urn:vim25 RetrieveAnswerFile,omitempty"` + Res *types.RetrieveAnswerFileResponse `xml:"urn:vim25 RetrieveAnswerFileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveAnswerFileBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveAnswerFile(ctx context.Context, r soap.RoundTripper, req *types.RetrieveAnswerFile) (*types.RetrieveAnswerFileResponse, error) { + var reqBody, resBody RetrieveAnswerFileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveAnswerFileForProfileBody struct { + Req *types.RetrieveAnswerFileForProfile `xml:"urn:vim25 RetrieveAnswerFileForProfile,omitempty"` + Res *types.RetrieveAnswerFileForProfileResponse `xml:"urn:vim25 RetrieveAnswerFileForProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveAnswerFileForProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveAnswerFileForProfile(ctx context.Context, r soap.RoundTripper, req *types.RetrieveAnswerFileForProfile) (*types.RetrieveAnswerFileForProfileResponse, error) { + var reqBody, resBody RetrieveAnswerFileForProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveArgumentDescriptionBody struct { + Req *types.RetrieveArgumentDescription `xml:"urn:vim25 RetrieveArgumentDescription,omitempty"` + Res *types.RetrieveArgumentDescriptionResponse `xml:"urn:vim25 RetrieveArgumentDescriptionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveArgumentDescriptionBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveArgumentDescription(ctx context.Context, r soap.RoundTripper, req *types.RetrieveArgumentDescription) (*types.RetrieveArgumentDescriptionResponse, error) { + var reqBody, resBody RetrieveArgumentDescriptionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveDasAdvancedRuntimeInfoBody struct { + Req *types.RetrieveDasAdvancedRuntimeInfo `xml:"urn:vim25 RetrieveDasAdvancedRuntimeInfo,omitempty"` + Res *types.RetrieveDasAdvancedRuntimeInfoResponse `xml:"urn:vim25 RetrieveDasAdvancedRuntimeInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveDasAdvancedRuntimeInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveDasAdvancedRuntimeInfo(ctx context.Context, r soap.RoundTripper, req *types.RetrieveDasAdvancedRuntimeInfo) (*types.RetrieveDasAdvancedRuntimeInfoResponse, error) { + var reqBody, resBody RetrieveDasAdvancedRuntimeInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveDescriptionBody struct { + Req *types.RetrieveDescription `xml:"urn:vim25 RetrieveDescription,omitempty"` + Res *types.RetrieveDescriptionResponse `xml:"urn:vim25 RetrieveDescriptionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveDescriptionBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveDescription(ctx context.Context, r soap.RoundTripper, req *types.RetrieveDescription) (*types.RetrieveDescriptionResponse, error) { + var reqBody, resBody RetrieveDescriptionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveDiskPartitionInfoBody struct { + Req *types.RetrieveDiskPartitionInfo `xml:"urn:vim25 RetrieveDiskPartitionInfo,omitempty"` + Res *types.RetrieveDiskPartitionInfoResponse `xml:"urn:vim25 RetrieveDiskPartitionInfoResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveDiskPartitionInfoBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveDiskPartitionInfo(ctx context.Context, r soap.RoundTripper, req *types.RetrieveDiskPartitionInfo) (*types.RetrieveDiskPartitionInfoResponse, error) { + var reqBody, resBody RetrieveDiskPartitionInfoBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveEntityPermissionsBody struct { + Req *types.RetrieveEntityPermissions `xml:"urn:vim25 RetrieveEntityPermissions,omitempty"` + Res *types.RetrieveEntityPermissionsResponse `xml:"urn:vim25 RetrieveEntityPermissionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveEntityPermissionsBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveEntityPermissions(ctx context.Context, r soap.RoundTripper, req *types.RetrieveEntityPermissions) (*types.RetrieveEntityPermissionsResponse, error) { + var reqBody, resBody RetrieveEntityPermissionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveEntityScheduledTaskBody struct { + Req *types.RetrieveEntityScheduledTask `xml:"urn:vim25 RetrieveEntityScheduledTask,omitempty"` + Res *types.RetrieveEntityScheduledTaskResponse `xml:"urn:vim25 RetrieveEntityScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveEntityScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveEntityScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.RetrieveEntityScheduledTask) (*types.RetrieveEntityScheduledTaskResponse, error) { + var reqBody, resBody RetrieveEntityScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveHardwareUptimeBody struct { + Req *types.RetrieveHardwareUptime `xml:"urn:vim25 RetrieveHardwareUptime,omitempty"` + Res *types.RetrieveHardwareUptimeResponse `xml:"urn:vim25 RetrieveHardwareUptimeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveHardwareUptimeBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveHardwareUptime(ctx context.Context, r soap.RoundTripper, req *types.RetrieveHardwareUptime) (*types.RetrieveHardwareUptimeResponse, error) { + var reqBody, resBody RetrieveHardwareUptimeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveHostAccessControlEntriesBody struct { + Req *types.RetrieveHostAccessControlEntries `xml:"urn:vim25 RetrieveHostAccessControlEntries,omitempty"` + Res *types.RetrieveHostAccessControlEntriesResponse `xml:"urn:vim25 RetrieveHostAccessControlEntriesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveHostAccessControlEntriesBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveHostAccessControlEntries(ctx context.Context, r soap.RoundTripper, req *types.RetrieveHostAccessControlEntries) (*types.RetrieveHostAccessControlEntriesResponse, error) { + var reqBody, resBody RetrieveHostAccessControlEntriesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveObjectScheduledTaskBody struct { + Req *types.RetrieveObjectScheduledTask `xml:"urn:vim25 RetrieveObjectScheduledTask,omitempty"` + Res *types.RetrieveObjectScheduledTaskResponse `xml:"urn:vim25 RetrieveObjectScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveObjectScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveObjectScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.RetrieveObjectScheduledTask) (*types.RetrieveObjectScheduledTaskResponse, error) { + var reqBody, resBody RetrieveObjectScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveProductComponentsBody struct { + Req *types.RetrieveProductComponents `xml:"urn:vim25 RetrieveProductComponents,omitempty"` + Res *types.RetrieveProductComponentsResponse `xml:"urn:vim25 RetrieveProductComponentsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveProductComponentsBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveProductComponents(ctx context.Context, r soap.RoundTripper, req *types.RetrieveProductComponents) (*types.RetrieveProductComponentsResponse, error) { + var reqBody, resBody RetrieveProductComponentsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrievePropertiesBody struct { + Req *types.RetrieveProperties `xml:"urn:vim25 RetrieveProperties,omitempty"` + Res *types.RetrievePropertiesResponse `xml:"urn:vim25 RetrievePropertiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrievePropertiesBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveProperties(ctx context.Context, r soap.RoundTripper, req *types.RetrieveProperties) (*types.RetrievePropertiesResponse, error) { + var reqBody, resBody RetrievePropertiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrievePropertiesExBody struct { + Req *types.RetrievePropertiesEx `xml:"urn:vim25 RetrievePropertiesEx,omitempty"` + Res *types.RetrievePropertiesExResponse `xml:"urn:vim25 RetrievePropertiesExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrievePropertiesExBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrievePropertiesEx(ctx context.Context, r soap.RoundTripper, req *types.RetrievePropertiesEx) (*types.RetrievePropertiesExResponse, error) { + var reqBody, resBody RetrievePropertiesExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveRolePermissionsBody struct { + Req *types.RetrieveRolePermissions `xml:"urn:vim25 RetrieveRolePermissions,omitempty"` + Res *types.RetrieveRolePermissionsResponse `xml:"urn:vim25 RetrieveRolePermissionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveRolePermissionsBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveRolePermissions(ctx context.Context, r soap.RoundTripper, req *types.RetrieveRolePermissions) (*types.RetrieveRolePermissionsResponse, error) { + var reqBody, resBody RetrieveRolePermissionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveServiceContentBody struct { + Req *types.RetrieveServiceContent `xml:"urn:vim25 RetrieveServiceContent,omitempty"` + Res *types.RetrieveServiceContentResponse `xml:"urn:vim25 RetrieveServiceContentResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveServiceContentBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveServiceContent(ctx context.Context, r soap.RoundTripper, req *types.RetrieveServiceContent) (*types.RetrieveServiceContentResponse, error) { + var reqBody, resBody RetrieveServiceContentBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RetrieveUserGroupsBody struct { + Req *types.RetrieveUserGroups `xml:"urn:vim25 RetrieveUserGroups,omitempty"` + Res *types.RetrieveUserGroupsResponse `xml:"urn:vim25 RetrieveUserGroupsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RetrieveUserGroupsBody) Fault() *soap.Fault { return b.Fault_ } + +func RetrieveUserGroups(ctx context.Context, r soap.RoundTripper, req *types.RetrieveUserGroups) (*types.RetrieveUserGroupsResponse, error) { + var reqBody, resBody RetrieveUserGroupsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RevertToCurrentSnapshot_TaskBody struct { + Req *types.RevertToCurrentSnapshot_Task `xml:"urn:vim25 RevertToCurrentSnapshot_Task,omitempty"` + Res *types.RevertToCurrentSnapshot_TaskResponse `xml:"urn:vim25 RevertToCurrentSnapshot_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RevertToCurrentSnapshot_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RevertToCurrentSnapshot_Task(ctx context.Context, r soap.RoundTripper, req *types.RevertToCurrentSnapshot_Task) (*types.RevertToCurrentSnapshot_TaskResponse, error) { + var reqBody, resBody RevertToCurrentSnapshot_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RevertToSnapshot_TaskBody struct { + Req *types.RevertToSnapshot_Task `xml:"urn:vim25 RevertToSnapshot_Task,omitempty"` + Res *types.RevertToSnapshot_TaskResponse `xml:"urn:vim25 RevertToSnapshot_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RevertToSnapshot_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RevertToSnapshot_Task(ctx context.Context, r soap.RoundTripper, req *types.RevertToSnapshot_Task) (*types.RevertToSnapshot_TaskResponse, error) { + var reqBody, resBody RevertToSnapshot_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RewindCollectorBody struct { + Req *types.RewindCollector `xml:"urn:vim25 RewindCollector,omitempty"` + Res *types.RewindCollectorResponse `xml:"urn:vim25 RewindCollectorResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RewindCollectorBody) Fault() *soap.Fault { return b.Fault_ } + +func RewindCollector(ctx context.Context, r soap.RoundTripper, req *types.RewindCollector) (*types.RewindCollectorResponse, error) { + var reqBody, resBody RewindCollectorBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RunScheduledTaskBody struct { + Req *types.RunScheduledTask `xml:"urn:vim25 RunScheduledTask,omitempty"` + Res *types.RunScheduledTaskResponse `xml:"urn:vim25 RunScheduledTaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RunScheduledTaskBody) Fault() *soap.Fault { return b.Fault_ } + +func RunScheduledTask(ctx context.Context, r soap.RoundTripper, req *types.RunScheduledTask) (*types.RunScheduledTaskResponse, error) { + var reqBody, resBody RunScheduledTaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type RunVsanPhysicalDiskDiagnosticsBody struct { + Req *types.RunVsanPhysicalDiskDiagnostics `xml:"urn:vim25 RunVsanPhysicalDiskDiagnostics,omitempty"` + Res *types.RunVsanPhysicalDiskDiagnosticsResponse `xml:"urn:vim25 RunVsanPhysicalDiskDiagnosticsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *RunVsanPhysicalDiskDiagnosticsBody) Fault() *soap.Fault { return b.Fault_ } + +func RunVsanPhysicalDiskDiagnostics(ctx context.Context, r soap.RoundTripper, req *types.RunVsanPhysicalDiskDiagnostics) (*types.RunVsanPhysicalDiskDiagnosticsResponse, error) { + var reqBody, resBody RunVsanPhysicalDiskDiagnosticsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ScanHostPatchV2_TaskBody struct { + Req *types.ScanHostPatchV2_Task `xml:"urn:vim25 ScanHostPatchV2_Task,omitempty"` + Res *types.ScanHostPatchV2_TaskResponse `xml:"urn:vim25 ScanHostPatchV2_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ScanHostPatchV2_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ScanHostPatchV2_Task(ctx context.Context, r soap.RoundTripper, req *types.ScanHostPatchV2_Task) (*types.ScanHostPatchV2_TaskResponse, error) { + var reqBody, resBody ScanHostPatchV2_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ScanHostPatch_TaskBody struct { + Req *types.ScanHostPatch_Task `xml:"urn:vim25 ScanHostPatch_Task,omitempty"` + Res *types.ScanHostPatch_TaskResponse `xml:"urn:vim25 ScanHostPatch_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ScanHostPatch_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ScanHostPatch_Task(ctx context.Context, r soap.RoundTripper, req *types.ScanHostPatch_Task) (*types.ScanHostPatch_TaskResponse, error) { + var reqBody, resBody ScanHostPatch_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SearchDatastoreSubFolders_TaskBody struct { + Req *types.SearchDatastoreSubFolders_Task `xml:"urn:vim25 SearchDatastoreSubFolders_Task,omitempty"` + Res *types.SearchDatastoreSubFolders_TaskResponse `xml:"urn:vim25 SearchDatastoreSubFolders_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SearchDatastoreSubFolders_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func SearchDatastoreSubFolders_Task(ctx context.Context, r soap.RoundTripper, req *types.SearchDatastoreSubFolders_Task) (*types.SearchDatastoreSubFolders_TaskResponse, error) { + var reqBody, resBody SearchDatastoreSubFolders_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SearchDatastore_TaskBody struct { + Req *types.SearchDatastore_Task `xml:"urn:vim25 SearchDatastore_Task,omitempty"` + Res *types.SearchDatastore_TaskResponse `xml:"urn:vim25 SearchDatastore_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SearchDatastore_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func SearchDatastore_Task(ctx context.Context, r soap.RoundTripper, req *types.SearchDatastore_Task) (*types.SearchDatastore_TaskResponse, error) { + var reqBody, resBody SearchDatastore_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SelectActivePartitionBody struct { + Req *types.SelectActivePartition `xml:"urn:vim25 SelectActivePartition,omitempty"` + Res *types.SelectActivePartitionResponse `xml:"urn:vim25 SelectActivePartitionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SelectActivePartitionBody) Fault() *soap.Fault { return b.Fault_ } + +func SelectActivePartition(ctx context.Context, r soap.RoundTripper, req *types.SelectActivePartition) (*types.SelectActivePartitionResponse, error) { + var reqBody, resBody SelectActivePartitionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SelectVnicBody struct { + Req *types.SelectVnic `xml:"urn:vim25 SelectVnic,omitempty"` + Res *types.SelectVnicResponse `xml:"urn:vim25 SelectVnicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SelectVnicBody) Fault() *soap.Fault { return b.Fault_ } + +func SelectVnic(ctx context.Context, r soap.RoundTripper, req *types.SelectVnic) (*types.SelectVnicResponse, error) { + var reqBody, resBody SelectVnicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SelectVnicForNicTypeBody struct { + Req *types.SelectVnicForNicType `xml:"urn:vim25 SelectVnicForNicType,omitempty"` + Res *types.SelectVnicForNicTypeResponse `xml:"urn:vim25 SelectVnicForNicTypeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SelectVnicForNicTypeBody) Fault() *soap.Fault { return b.Fault_ } + +func SelectVnicForNicType(ctx context.Context, r soap.RoundTripper, req *types.SelectVnicForNicType) (*types.SelectVnicForNicTypeResponse, error) { + var reqBody, resBody SelectVnicForNicTypeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SendNMIBody struct { + Req *types.SendNMI `xml:"urn:vim25 SendNMI,omitempty"` + Res *types.SendNMIResponse `xml:"urn:vim25 SendNMIResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SendNMIBody) Fault() *soap.Fault { return b.Fault_ } + +func SendNMI(ctx context.Context, r soap.RoundTripper, req *types.SendNMI) (*types.SendNMIResponse, error) { + var reqBody, resBody SendNMIBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SendTestNotificationBody struct { + Req *types.SendTestNotification `xml:"urn:vim25 SendTestNotification,omitempty"` + Res *types.SendTestNotificationResponse `xml:"urn:vim25 SendTestNotificationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SendTestNotificationBody) Fault() *soap.Fault { return b.Fault_ } + +func SendTestNotification(ctx context.Context, r soap.RoundTripper, req *types.SendTestNotification) (*types.SendTestNotificationResponse, error) { + var reqBody, resBody SendTestNotificationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SessionIsActiveBody struct { + Req *types.SessionIsActive `xml:"urn:vim25 SessionIsActive,omitempty"` + Res *types.SessionIsActiveResponse `xml:"urn:vim25 SessionIsActiveResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SessionIsActiveBody) Fault() *soap.Fault { return b.Fault_ } + +func SessionIsActive(ctx context.Context, r soap.RoundTripper, req *types.SessionIsActive) (*types.SessionIsActiveResponse, error) { + var reqBody, resBody SessionIsActiveBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetCollectorPageSizeBody struct { + Req *types.SetCollectorPageSize `xml:"urn:vim25 SetCollectorPageSize,omitempty"` + Res *types.SetCollectorPageSizeResponse `xml:"urn:vim25 SetCollectorPageSizeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetCollectorPageSizeBody) Fault() *soap.Fault { return b.Fault_ } + +func SetCollectorPageSize(ctx context.Context, r soap.RoundTripper, req *types.SetCollectorPageSize) (*types.SetCollectorPageSizeResponse, error) { + var reqBody, resBody SetCollectorPageSizeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetDisplayTopologyBody struct { + Req *types.SetDisplayTopology `xml:"urn:vim25 SetDisplayTopology,omitempty"` + Res *types.SetDisplayTopologyResponse `xml:"urn:vim25 SetDisplayTopologyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetDisplayTopologyBody) Fault() *soap.Fault { return b.Fault_ } + +func SetDisplayTopology(ctx context.Context, r soap.RoundTripper, req *types.SetDisplayTopology) (*types.SetDisplayTopologyResponse, error) { + var reqBody, resBody SetDisplayTopologyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetEntityPermissionsBody struct { + Req *types.SetEntityPermissions `xml:"urn:vim25 SetEntityPermissions,omitempty"` + Res *types.SetEntityPermissionsResponse `xml:"urn:vim25 SetEntityPermissionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetEntityPermissionsBody) Fault() *soap.Fault { return b.Fault_ } + +func SetEntityPermissions(ctx context.Context, r soap.RoundTripper, req *types.SetEntityPermissions) (*types.SetEntityPermissionsResponse, error) { + var reqBody, resBody SetEntityPermissionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetExtensionCertificateBody struct { + Req *types.SetExtensionCertificate `xml:"urn:vim25 SetExtensionCertificate,omitempty"` + Res *types.SetExtensionCertificateResponse `xml:"urn:vim25 SetExtensionCertificateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetExtensionCertificateBody) Fault() *soap.Fault { return b.Fault_ } + +func SetExtensionCertificate(ctx context.Context, r soap.RoundTripper, req *types.SetExtensionCertificate) (*types.SetExtensionCertificateResponse, error) { + var reqBody, resBody SetExtensionCertificateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetFieldBody struct { + Req *types.SetField `xml:"urn:vim25 SetField,omitempty"` + Res *types.SetFieldResponse `xml:"urn:vim25 SetFieldResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetFieldBody) Fault() *soap.Fault { return b.Fault_ } + +func SetField(ctx context.Context, r soap.RoundTripper, req *types.SetField) (*types.SetFieldResponse, error) { + var reqBody, resBody SetFieldBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetLicenseEditionBody struct { + Req *types.SetLicenseEdition `xml:"urn:vim25 SetLicenseEdition,omitempty"` + Res *types.SetLicenseEditionResponse `xml:"urn:vim25 SetLicenseEditionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetLicenseEditionBody) Fault() *soap.Fault { return b.Fault_ } + +func SetLicenseEdition(ctx context.Context, r soap.RoundTripper, req *types.SetLicenseEdition) (*types.SetLicenseEditionResponse, error) { + var reqBody, resBody SetLicenseEditionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetLocaleBody struct { + Req *types.SetLocale `xml:"urn:vim25 SetLocale,omitempty"` + Res *types.SetLocaleResponse `xml:"urn:vim25 SetLocaleResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetLocaleBody) Fault() *soap.Fault { return b.Fault_ } + +func SetLocale(ctx context.Context, r soap.RoundTripper, req *types.SetLocale) (*types.SetLocaleResponse, error) { + var reqBody, resBody SetLocaleBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetMultipathLunPolicyBody struct { + Req *types.SetMultipathLunPolicy `xml:"urn:vim25 SetMultipathLunPolicy,omitempty"` + Res *types.SetMultipathLunPolicyResponse `xml:"urn:vim25 SetMultipathLunPolicyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetMultipathLunPolicyBody) Fault() *soap.Fault { return b.Fault_ } + +func SetMultipathLunPolicy(ctx context.Context, r soap.RoundTripper, req *types.SetMultipathLunPolicy) (*types.SetMultipathLunPolicyResponse, error) { + var reqBody, resBody SetMultipathLunPolicyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetNFSUserBody struct { + Req *types.SetNFSUser `xml:"urn:vim25 SetNFSUser,omitempty"` + Res *types.SetNFSUserResponse `xml:"urn:vim25 SetNFSUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetNFSUserBody) Fault() *soap.Fault { return b.Fault_ } + +func SetNFSUser(ctx context.Context, r soap.RoundTripper, req *types.SetNFSUser) (*types.SetNFSUserResponse, error) { + var reqBody, resBody SetNFSUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetPublicKeyBody struct { + Req *types.SetPublicKey `xml:"urn:vim25 SetPublicKey,omitempty"` + Res *types.SetPublicKeyResponse `xml:"urn:vim25 SetPublicKeyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetPublicKeyBody) Fault() *soap.Fault { return b.Fault_ } + +func SetPublicKey(ctx context.Context, r soap.RoundTripper, req *types.SetPublicKey) (*types.SetPublicKeyResponse, error) { + var reqBody, resBody SetPublicKeyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetRegistryValueInGuestBody struct { + Req *types.SetRegistryValueInGuest `xml:"urn:vim25 SetRegistryValueInGuest,omitempty"` + Res *types.SetRegistryValueInGuestResponse `xml:"urn:vim25 SetRegistryValueInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetRegistryValueInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func SetRegistryValueInGuest(ctx context.Context, r soap.RoundTripper, req *types.SetRegistryValueInGuest) (*types.SetRegistryValueInGuestResponse, error) { + var reqBody, resBody SetRegistryValueInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetScreenResolutionBody struct { + Req *types.SetScreenResolution `xml:"urn:vim25 SetScreenResolution,omitempty"` + Res *types.SetScreenResolutionResponse `xml:"urn:vim25 SetScreenResolutionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetScreenResolutionBody) Fault() *soap.Fault { return b.Fault_ } + +func SetScreenResolution(ctx context.Context, r soap.RoundTripper, req *types.SetScreenResolution) (*types.SetScreenResolutionResponse, error) { + var reqBody, resBody SetScreenResolutionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetTaskDescriptionBody struct { + Req *types.SetTaskDescription `xml:"urn:vim25 SetTaskDescription,omitempty"` + Res *types.SetTaskDescriptionResponse `xml:"urn:vim25 SetTaskDescriptionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetTaskDescriptionBody) Fault() *soap.Fault { return b.Fault_ } + +func SetTaskDescription(ctx context.Context, r soap.RoundTripper, req *types.SetTaskDescription) (*types.SetTaskDescriptionResponse, error) { + var reqBody, resBody SetTaskDescriptionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetTaskStateBody struct { + Req *types.SetTaskState `xml:"urn:vim25 SetTaskState,omitempty"` + Res *types.SetTaskStateResponse `xml:"urn:vim25 SetTaskStateResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetTaskStateBody) Fault() *soap.Fault { return b.Fault_ } + +func SetTaskState(ctx context.Context, r soap.RoundTripper, req *types.SetTaskState) (*types.SetTaskStateResponse, error) { + var reqBody, resBody SetTaskStateBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SetVirtualDiskUuidBody struct { + Req *types.SetVirtualDiskUuid `xml:"urn:vim25 SetVirtualDiskUuid,omitempty"` + Res *types.SetVirtualDiskUuidResponse `xml:"urn:vim25 SetVirtualDiskUuidResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SetVirtualDiskUuidBody) Fault() *soap.Fault { return b.Fault_ } + +func SetVirtualDiskUuid(ctx context.Context, r soap.RoundTripper, req *types.SetVirtualDiskUuid) (*types.SetVirtualDiskUuidResponse, error) { + var reqBody, resBody SetVirtualDiskUuidBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ShrinkVirtualDisk_TaskBody struct { + Req *types.ShrinkVirtualDisk_Task `xml:"urn:vim25 ShrinkVirtualDisk_Task,omitempty"` + Res *types.ShrinkVirtualDisk_TaskResponse `xml:"urn:vim25 ShrinkVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ShrinkVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ShrinkVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.ShrinkVirtualDisk_Task) (*types.ShrinkVirtualDisk_TaskResponse, error) { + var reqBody, resBody ShrinkVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ShutdownGuestBody struct { + Req *types.ShutdownGuest `xml:"urn:vim25 ShutdownGuest,omitempty"` + Res *types.ShutdownGuestResponse `xml:"urn:vim25 ShutdownGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ShutdownGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ShutdownGuest(ctx context.Context, r soap.RoundTripper, req *types.ShutdownGuest) (*types.ShutdownGuestResponse, error) { + var reqBody, resBody ShutdownGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ShutdownHost_TaskBody struct { + Req *types.ShutdownHost_Task `xml:"urn:vim25 ShutdownHost_Task,omitempty"` + Res *types.ShutdownHost_TaskResponse `xml:"urn:vim25 ShutdownHost_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ShutdownHost_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ShutdownHost_Task(ctx context.Context, r soap.RoundTripper, req *types.ShutdownHost_Task) (*types.ShutdownHost_TaskResponse, error) { + var reqBody, resBody ShutdownHost_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StageHostPatch_TaskBody struct { + Req *types.StageHostPatch_Task `xml:"urn:vim25 StageHostPatch_Task,omitempty"` + Res *types.StageHostPatch_TaskResponse `xml:"urn:vim25 StageHostPatch_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StageHostPatch_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func StageHostPatch_Task(ctx context.Context, r soap.RoundTripper, req *types.StageHostPatch_Task) (*types.StageHostPatch_TaskResponse, error) { + var reqBody, resBody StageHostPatch_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StampAllRulesWithUuid_TaskBody struct { + Req *types.StampAllRulesWithUuid_Task `xml:"urn:vim25 StampAllRulesWithUuid_Task,omitempty"` + Res *types.StampAllRulesWithUuid_TaskResponse `xml:"urn:vim25 StampAllRulesWithUuid_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StampAllRulesWithUuid_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func StampAllRulesWithUuid_Task(ctx context.Context, r soap.RoundTripper, req *types.StampAllRulesWithUuid_Task) (*types.StampAllRulesWithUuid_TaskResponse, error) { + var reqBody, resBody StampAllRulesWithUuid_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StandbyGuestBody struct { + Req *types.StandbyGuest `xml:"urn:vim25 StandbyGuest,omitempty"` + Res *types.StandbyGuestResponse `xml:"urn:vim25 StandbyGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StandbyGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func StandbyGuest(ctx context.Context, r soap.RoundTripper, req *types.StandbyGuest) (*types.StandbyGuestResponse, error) { + var reqBody, resBody StandbyGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StartProgramInGuestBody struct { + Req *types.StartProgramInGuest `xml:"urn:vim25 StartProgramInGuest,omitempty"` + Res *types.StartProgramInGuestResponse `xml:"urn:vim25 StartProgramInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StartProgramInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func StartProgramInGuest(ctx context.Context, r soap.RoundTripper, req *types.StartProgramInGuest) (*types.StartProgramInGuestResponse, error) { + var reqBody, resBody StartProgramInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StartRecording_TaskBody struct { + Req *types.StartRecording_Task `xml:"urn:vim25 StartRecording_Task,omitempty"` + Res *types.StartRecording_TaskResponse `xml:"urn:vim25 StartRecording_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StartRecording_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func StartRecording_Task(ctx context.Context, r soap.RoundTripper, req *types.StartRecording_Task) (*types.StartRecording_TaskResponse, error) { + var reqBody, resBody StartRecording_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StartReplaying_TaskBody struct { + Req *types.StartReplaying_Task `xml:"urn:vim25 StartReplaying_Task,omitempty"` + Res *types.StartReplaying_TaskResponse `xml:"urn:vim25 StartReplaying_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StartReplaying_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func StartReplaying_Task(ctx context.Context, r soap.RoundTripper, req *types.StartReplaying_Task) (*types.StartReplaying_TaskResponse, error) { + var reqBody, resBody StartReplaying_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StartServiceBody struct { + Req *types.StartService `xml:"urn:vim25 StartService,omitempty"` + Res *types.StartServiceResponse `xml:"urn:vim25 StartServiceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StartServiceBody) Fault() *soap.Fault { return b.Fault_ } + +func StartService(ctx context.Context, r soap.RoundTripper, req *types.StartService) (*types.StartServiceResponse, error) { + var reqBody, resBody StartServiceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StopRecording_TaskBody struct { + Req *types.StopRecording_Task `xml:"urn:vim25 StopRecording_Task,omitempty"` + Res *types.StopRecording_TaskResponse `xml:"urn:vim25 StopRecording_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StopRecording_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func StopRecording_Task(ctx context.Context, r soap.RoundTripper, req *types.StopRecording_Task) (*types.StopRecording_TaskResponse, error) { + var reqBody, resBody StopRecording_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StopReplaying_TaskBody struct { + Req *types.StopReplaying_Task `xml:"urn:vim25 StopReplaying_Task,omitempty"` + Res *types.StopReplaying_TaskResponse `xml:"urn:vim25 StopReplaying_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StopReplaying_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func StopReplaying_Task(ctx context.Context, r soap.RoundTripper, req *types.StopReplaying_Task) (*types.StopReplaying_TaskResponse, error) { + var reqBody, resBody StopReplaying_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type StopServiceBody struct { + Req *types.StopService `xml:"urn:vim25 StopService,omitempty"` + Res *types.StopServiceResponse `xml:"urn:vim25 StopServiceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *StopServiceBody) Fault() *soap.Fault { return b.Fault_ } + +func StopService(ctx context.Context, r soap.RoundTripper, req *types.StopService) (*types.StopServiceResponse, error) { + var reqBody, resBody StopServiceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SuspendVApp_TaskBody struct { + Req *types.SuspendVApp_Task `xml:"urn:vim25 SuspendVApp_Task,omitempty"` + Res *types.SuspendVApp_TaskResponse `xml:"urn:vim25 SuspendVApp_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SuspendVApp_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func SuspendVApp_Task(ctx context.Context, r soap.RoundTripper, req *types.SuspendVApp_Task) (*types.SuspendVApp_TaskResponse, error) { + var reqBody, resBody SuspendVApp_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type SuspendVM_TaskBody struct { + Req *types.SuspendVM_Task `xml:"urn:vim25 SuspendVM_Task,omitempty"` + Res *types.SuspendVM_TaskResponse `xml:"urn:vim25 SuspendVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *SuspendVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func SuspendVM_Task(ctx context.Context, r soap.RoundTripper, req *types.SuspendVM_Task) (*types.SuspendVM_TaskResponse, error) { + var reqBody, resBody SuspendVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TerminateFaultTolerantVM_TaskBody struct { + Req *types.TerminateFaultTolerantVM_Task `xml:"urn:vim25 TerminateFaultTolerantVM_Task,omitempty"` + Res *types.TerminateFaultTolerantVM_TaskResponse `xml:"urn:vim25 TerminateFaultTolerantVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TerminateFaultTolerantVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func TerminateFaultTolerantVM_Task(ctx context.Context, r soap.RoundTripper, req *types.TerminateFaultTolerantVM_Task) (*types.TerminateFaultTolerantVM_TaskResponse, error) { + var reqBody, resBody TerminateFaultTolerantVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TerminateProcessInGuestBody struct { + Req *types.TerminateProcessInGuest `xml:"urn:vim25 TerminateProcessInGuest,omitempty"` + Res *types.TerminateProcessInGuestResponse `xml:"urn:vim25 TerminateProcessInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TerminateProcessInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func TerminateProcessInGuest(ctx context.Context, r soap.RoundTripper, req *types.TerminateProcessInGuest) (*types.TerminateProcessInGuestResponse, error) { + var reqBody, resBody TerminateProcessInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TerminateSessionBody struct { + Req *types.TerminateSession `xml:"urn:vim25 TerminateSession,omitempty"` + Res *types.TerminateSessionResponse `xml:"urn:vim25 TerminateSessionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TerminateSessionBody) Fault() *soap.Fault { return b.Fault_ } + +func TerminateSession(ctx context.Context, r soap.RoundTripper, req *types.TerminateSession) (*types.TerminateSessionResponse, error) { + var reqBody, resBody TerminateSessionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TerminateVMBody struct { + Req *types.TerminateVM `xml:"urn:vim25 TerminateVM,omitempty"` + Res *types.TerminateVMResponse `xml:"urn:vim25 TerminateVMResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TerminateVMBody) Fault() *soap.Fault { return b.Fault_ } + +func TerminateVM(ctx context.Context, r soap.RoundTripper, req *types.TerminateVM) (*types.TerminateVMResponse, error) { + var reqBody, resBody TerminateVMBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TurnDiskLocatorLedOff_TaskBody struct { + Req *types.TurnDiskLocatorLedOff_Task `xml:"urn:vim25 TurnDiskLocatorLedOff_Task,omitempty"` + Res *types.TurnDiskLocatorLedOff_TaskResponse `xml:"urn:vim25 TurnDiskLocatorLedOff_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TurnDiskLocatorLedOff_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func TurnDiskLocatorLedOff_Task(ctx context.Context, r soap.RoundTripper, req *types.TurnDiskLocatorLedOff_Task) (*types.TurnDiskLocatorLedOff_TaskResponse, error) { + var reqBody, resBody TurnDiskLocatorLedOff_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TurnDiskLocatorLedOn_TaskBody struct { + Req *types.TurnDiskLocatorLedOn_Task `xml:"urn:vim25 TurnDiskLocatorLedOn_Task,omitempty"` + Res *types.TurnDiskLocatorLedOn_TaskResponse `xml:"urn:vim25 TurnDiskLocatorLedOn_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TurnDiskLocatorLedOn_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func TurnDiskLocatorLedOn_Task(ctx context.Context, r soap.RoundTripper, req *types.TurnDiskLocatorLedOn_Task) (*types.TurnDiskLocatorLedOn_TaskResponse, error) { + var reqBody, resBody TurnDiskLocatorLedOn_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type TurnOffFaultToleranceForVM_TaskBody struct { + Req *types.TurnOffFaultToleranceForVM_Task `xml:"urn:vim25 TurnOffFaultToleranceForVM_Task,omitempty"` + Res *types.TurnOffFaultToleranceForVM_TaskResponse `xml:"urn:vim25 TurnOffFaultToleranceForVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *TurnOffFaultToleranceForVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func TurnOffFaultToleranceForVM_Task(ctx context.Context, r soap.RoundTripper, req *types.TurnOffFaultToleranceForVM_Task) (*types.TurnOffFaultToleranceForVM_TaskResponse, error) { + var reqBody, resBody TurnOffFaultToleranceForVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnassignUserFromGroupBody struct { + Req *types.UnassignUserFromGroup `xml:"urn:vim25 UnassignUserFromGroup,omitempty"` + Res *types.UnassignUserFromGroupResponse `xml:"urn:vim25 UnassignUserFromGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnassignUserFromGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func UnassignUserFromGroup(ctx context.Context, r soap.RoundTripper, req *types.UnassignUserFromGroup) (*types.UnassignUserFromGroupResponse, error) { + var reqBody, resBody UnassignUserFromGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnbindVnicBody struct { + Req *types.UnbindVnic `xml:"urn:vim25 UnbindVnic,omitempty"` + Res *types.UnbindVnicResponse `xml:"urn:vim25 UnbindVnicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnbindVnicBody) Fault() *soap.Fault { return b.Fault_ } + +func UnbindVnic(ctx context.Context, r soap.RoundTripper, req *types.UnbindVnic) (*types.UnbindVnicResponse, error) { + var reqBody, resBody UnbindVnicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UninstallHostPatch_TaskBody struct { + Req *types.UninstallHostPatch_Task `xml:"urn:vim25 UninstallHostPatch_Task,omitempty"` + Res *types.UninstallHostPatch_TaskResponse `xml:"urn:vim25 UninstallHostPatch_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UninstallHostPatch_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UninstallHostPatch_Task(ctx context.Context, r soap.RoundTripper, req *types.UninstallHostPatch_Task) (*types.UninstallHostPatch_TaskResponse, error) { + var reqBody, resBody UninstallHostPatch_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UninstallIoFilter_TaskBody struct { + Req *types.UninstallIoFilter_Task `xml:"urn:vim25 UninstallIoFilter_Task,omitempty"` + Res *types.UninstallIoFilter_TaskResponse `xml:"urn:vim25 UninstallIoFilter_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UninstallIoFilter_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UninstallIoFilter_Task(ctx context.Context, r soap.RoundTripper, req *types.UninstallIoFilter_Task) (*types.UninstallIoFilter_TaskResponse, error) { + var reqBody, resBody UninstallIoFilter_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UninstallServiceBody struct { + Req *types.UninstallService `xml:"urn:vim25 UninstallService,omitempty"` + Res *types.UninstallServiceResponse `xml:"urn:vim25 UninstallServiceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UninstallServiceBody) Fault() *soap.Fault { return b.Fault_ } + +func UninstallService(ctx context.Context, r soap.RoundTripper, req *types.UninstallService) (*types.UninstallServiceResponse, error) { + var reqBody, resBody UninstallServiceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmapVmfsVolumeEx_TaskBody struct { + Req *types.UnmapVmfsVolumeEx_Task `xml:"urn:vim25 UnmapVmfsVolumeEx_Task,omitempty"` + Res *types.UnmapVmfsVolumeEx_TaskResponse `xml:"urn:vim25 UnmapVmfsVolumeEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmapVmfsVolumeEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmapVmfsVolumeEx_Task(ctx context.Context, r soap.RoundTripper, req *types.UnmapVmfsVolumeEx_Task) (*types.UnmapVmfsVolumeEx_TaskResponse, error) { + var reqBody, resBody UnmapVmfsVolumeEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmountDiskMapping_TaskBody struct { + Req *types.UnmountDiskMapping_Task `xml:"urn:vim25 UnmountDiskMapping_Task,omitempty"` + Res *types.UnmountDiskMapping_TaskResponse `xml:"urn:vim25 UnmountDiskMapping_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmountDiskMapping_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmountDiskMapping_Task(ctx context.Context, r soap.RoundTripper, req *types.UnmountDiskMapping_Task) (*types.UnmountDiskMapping_TaskResponse, error) { + var reqBody, resBody UnmountDiskMapping_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmountForceMountedVmfsVolumeBody struct { + Req *types.UnmountForceMountedVmfsVolume `xml:"urn:vim25 UnmountForceMountedVmfsVolume,omitempty"` + Res *types.UnmountForceMountedVmfsVolumeResponse `xml:"urn:vim25 UnmountForceMountedVmfsVolumeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmountForceMountedVmfsVolumeBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmountForceMountedVmfsVolume(ctx context.Context, r soap.RoundTripper, req *types.UnmountForceMountedVmfsVolume) (*types.UnmountForceMountedVmfsVolumeResponse, error) { + var reqBody, resBody UnmountForceMountedVmfsVolumeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmountToolsInstallerBody struct { + Req *types.UnmountToolsInstaller `xml:"urn:vim25 UnmountToolsInstaller,omitempty"` + Res *types.UnmountToolsInstallerResponse `xml:"urn:vim25 UnmountToolsInstallerResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmountToolsInstallerBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmountToolsInstaller(ctx context.Context, r soap.RoundTripper, req *types.UnmountToolsInstaller) (*types.UnmountToolsInstallerResponse, error) { + var reqBody, resBody UnmountToolsInstallerBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmountVffsVolumeBody struct { + Req *types.UnmountVffsVolume `xml:"urn:vim25 UnmountVffsVolume,omitempty"` + Res *types.UnmountVffsVolumeResponse `xml:"urn:vim25 UnmountVffsVolumeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmountVffsVolumeBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmountVffsVolume(ctx context.Context, r soap.RoundTripper, req *types.UnmountVffsVolume) (*types.UnmountVffsVolumeResponse, error) { + var reqBody, resBody UnmountVffsVolumeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmountVmfsVolumeBody struct { + Req *types.UnmountVmfsVolume `xml:"urn:vim25 UnmountVmfsVolume,omitempty"` + Res *types.UnmountVmfsVolumeResponse `xml:"urn:vim25 UnmountVmfsVolumeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmountVmfsVolumeBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmountVmfsVolume(ctx context.Context, r soap.RoundTripper, req *types.UnmountVmfsVolume) (*types.UnmountVmfsVolumeResponse, error) { + var reqBody, resBody UnmountVmfsVolumeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnmountVmfsVolumeEx_TaskBody struct { + Req *types.UnmountVmfsVolumeEx_Task `xml:"urn:vim25 UnmountVmfsVolumeEx_Task,omitempty"` + Res *types.UnmountVmfsVolumeEx_TaskResponse `xml:"urn:vim25 UnmountVmfsVolumeEx_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnmountVmfsVolumeEx_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UnmountVmfsVolumeEx_Task(ctx context.Context, r soap.RoundTripper, req *types.UnmountVmfsVolumeEx_Task) (*types.UnmountVmfsVolumeEx_TaskResponse, error) { + var reqBody, resBody UnmountVmfsVolumeEx_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnregisterAndDestroy_TaskBody struct { + Req *types.UnregisterAndDestroy_Task `xml:"urn:vim25 UnregisterAndDestroy_Task,omitempty"` + Res *types.UnregisterAndDestroy_TaskResponse `xml:"urn:vim25 UnregisterAndDestroy_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnregisterAndDestroy_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UnregisterAndDestroy_Task(ctx context.Context, r soap.RoundTripper, req *types.UnregisterAndDestroy_Task) (*types.UnregisterAndDestroy_TaskResponse, error) { + var reqBody, resBody UnregisterAndDestroy_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnregisterExtensionBody struct { + Req *types.UnregisterExtension `xml:"urn:vim25 UnregisterExtension,omitempty"` + Res *types.UnregisterExtensionResponse `xml:"urn:vim25 UnregisterExtensionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnregisterExtensionBody) Fault() *soap.Fault { return b.Fault_ } + +func UnregisterExtension(ctx context.Context, r soap.RoundTripper, req *types.UnregisterExtension) (*types.UnregisterExtensionResponse, error) { + var reqBody, resBody UnregisterExtensionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UnregisterVMBody struct { + Req *types.UnregisterVM `xml:"urn:vim25 UnregisterVM,omitempty"` + Res *types.UnregisterVMResponse `xml:"urn:vim25 UnregisterVMResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UnregisterVMBody) Fault() *soap.Fault { return b.Fault_ } + +func UnregisterVM(ctx context.Context, r soap.RoundTripper, req *types.UnregisterVM) (*types.UnregisterVMResponse, error) { + var reqBody, resBody UnregisterVMBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateAnswerFile_TaskBody struct { + Req *types.UpdateAnswerFile_Task `xml:"urn:vim25 UpdateAnswerFile_Task,omitempty"` + Res *types.UpdateAnswerFile_TaskResponse `xml:"urn:vim25 UpdateAnswerFile_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateAnswerFile_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateAnswerFile_Task(ctx context.Context, r soap.RoundTripper, req *types.UpdateAnswerFile_Task) (*types.UpdateAnswerFile_TaskResponse, error) { + var reqBody, resBody UpdateAnswerFile_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateAssignedLicenseBody struct { + Req *types.UpdateAssignedLicense `xml:"urn:vim25 UpdateAssignedLicense,omitempty"` + Res *types.UpdateAssignedLicenseResponse `xml:"urn:vim25 UpdateAssignedLicenseResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateAssignedLicenseBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateAssignedLicense(ctx context.Context, r soap.RoundTripper, req *types.UpdateAssignedLicense) (*types.UpdateAssignedLicenseResponse, error) { + var reqBody, resBody UpdateAssignedLicenseBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateAuthorizationRoleBody struct { + Req *types.UpdateAuthorizationRole `xml:"urn:vim25 UpdateAuthorizationRole,omitempty"` + Res *types.UpdateAuthorizationRoleResponse `xml:"urn:vim25 UpdateAuthorizationRoleResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateAuthorizationRoleBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateAuthorizationRole(ctx context.Context, r soap.RoundTripper, req *types.UpdateAuthorizationRole) (*types.UpdateAuthorizationRoleResponse, error) { + var reqBody, resBody UpdateAuthorizationRoleBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateBootDeviceBody struct { + Req *types.UpdateBootDevice `xml:"urn:vim25 UpdateBootDevice,omitempty"` + Res *types.UpdateBootDeviceResponse `xml:"urn:vim25 UpdateBootDeviceResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateBootDeviceBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateBootDevice(ctx context.Context, r soap.RoundTripper, req *types.UpdateBootDevice) (*types.UpdateBootDeviceResponse, error) { + var reqBody, resBody UpdateBootDeviceBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateChildResourceConfigurationBody struct { + Req *types.UpdateChildResourceConfiguration `xml:"urn:vim25 UpdateChildResourceConfiguration,omitempty"` + Res *types.UpdateChildResourceConfigurationResponse `xml:"urn:vim25 UpdateChildResourceConfigurationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateChildResourceConfigurationBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateChildResourceConfiguration(ctx context.Context, r soap.RoundTripper, req *types.UpdateChildResourceConfiguration) (*types.UpdateChildResourceConfigurationResponse, error) { + var reqBody, resBody UpdateChildResourceConfigurationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateClusterProfileBody struct { + Req *types.UpdateClusterProfile `xml:"urn:vim25 UpdateClusterProfile,omitempty"` + Res *types.UpdateClusterProfileResponse `xml:"urn:vim25 UpdateClusterProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateClusterProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateClusterProfile(ctx context.Context, r soap.RoundTripper, req *types.UpdateClusterProfile) (*types.UpdateClusterProfileResponse, error) { + var reqBody, resBody UpdateClusterProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateConfigBody struct { + Req *types.UpdateConfig `xml:"urn:vim25 UpdateConfig,omitempty"` + Res *types.UpdateConfigResponse `xml:"urn:vim25 UpdateConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateConfig) (*types.UpdateConfigResponse, error) { + var reqBody, resBody UpdateConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateConsoleIpRouteConfigBody struct { + Req *types.UpdateConsoleIpRouteConfig `xml:"urn:vim25 UpdateConsoleIpRouteConfig,omitempty"` + Res *types.UpdateConsoleIpRouteConfigResponse `xml:"urn:vim25 UpdateConsoleIpRouteConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateConsoleIpRouteConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateConsoleIpRouteConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateConsoleIpRouteConfig) (*types.UpdateConsoleIpRouteConfigResponse, error) { + var reqBody, resBody UpdateConsoleIpRouteConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateCounterLevelMappingBody struct { + Req *types.UpdateCounterLevelMapping `xml:"urn:vim25 UpdateCounterLevelMapping,omitempty"` + Res *types.UpdateCounterLevelMappingResponse `xml:"urn:vim25 UpdateCounterLevelMappingResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateCounterLevelMappingBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateCounterLevelMapping(ctx context.Context, r soap.RoundTripper, req *types.UpdateCounterLevelMapping) (*types.UpdateCounterLevelMappingResponse, error) { + var reqBody, resBody UpdateCounterLevelMappingBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDVSHealthCheckConfig_TaskBody struct { + Req *types.UpdateDVSHealthCheckConfig_Task `xml:"urn:vim25 UpdateDVSHealthCheckConfig_Task,omitempty"` + Res *types.UpdateDVSHealthCheckConfig_TaskResponse `xml:"urn:vim25 UpdateDVSHealthCheckConfig_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDVSHealthCheckConfig_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDVSHealthCheckConfig_Task(ctx context.Context, r soap.RoundTripper, req *types.UpdateDVSHealthCheckConfig_Task) (*types.UpdateDVSHealthCheckConfig_TaskResponse, error) { + var reqBody, resBody UpdateDVSHealthCheckConfig_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDVSLacpGroupConfig_TaskBody struct { + Req *types.UpdateDVSLacpGroupConfig_Task `xml:"urn:vim25 UpdateDVSLacpGroupConfig_Task,omitempty"` + Res *types.UpdateDVSLacpGroupConfig_TaskResponse `xml:"urn:vim25 UpdateDVSLacpGroupConfig_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDVSLacpGroupConfig_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDVSLacpGroupConfig_Task(ctx context.Context, r soap.RoundTripper, req *types.UpdateDVSLacpGroupConfig_Task) (*types.UpdateDVSLacpGroupConfig_TaskResponse, error) { + var reqBody, resBody UpdateDVSLacpGroupConfig_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDateTimeBody struct { + Req *types.UpdateDateTime `xml:"urn:vim25 UpdateDateTime,omitempty"` + Res *types.UpdateDateTimeResponse `xml:"urn:vim25 UpdateDateTimeResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDateTimeBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDateTime(ctx context.Context, r soap.RoundTripper, req *types.UpdateDateTime) (*types.UpdateDateTimeResponse, error) { + var reqBody, resBody UpdateDateTimeBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDateTimeConfigBody struct { + Req *types.UpdateDateTimeConfig `xml:"urn:vim25 UpdateDateTimeConfig,omitempty"` + Res *types.UpdateDateTimeConfigResponse `xml:"urn:vim25 UpdateDateTimeConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDateTimeConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDateTimeConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateDateTimeConfig) (*types.UpdateDateTimeConfigResponse, error) { + var reqBody, resBody UpdateDateTimeConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDefaultPolicyBody struct { + Req *types.UpdateDefaultPolicy `xml:"urn:vim25 UpdateDefaultPolicy,omitempty"` + Res *types.UpdateDefaultPolicyResponse `xml:"urn:vim25 UpdateDefaultPolicyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDefaultPolicyBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDefaultPolicy(ctx context.Context, r soap.RoundTripper, req *types.UpdateDefaultPolicy) (*types.UpdateDefaultPolicyResponse, error) { + var reqBody, resBody UpdateDefaultPolicyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDiskPartitionsBody struct { + Req *types.UpdateDiskPartitions `xml:"urn:vim25 UpdateDiskPartitions,omitempty"` + Res *types.UpdateDiskPartitionsResponse `xml:"urn:vim25 UpdateDiskPartitionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDiskPartitionsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDiskPartitions(ctx context.Context, r soap.RoundTripper, req *types.UpdateDiskPartitions) (*types.UpdateDiskPartitionsResponse, error) { + var reqBody, resBody UpdateDiskPartitionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDnsConfigBody struct { + Req *types.UpdateDnsConfig `xml:"urn:vim25 UpdateDnsConfig,omitempty"` + Res *types.UpdateDnsConfigResponse `xml:"urn:vim25 UpdateDnsConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDnsConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDnsConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateDnsConfig) (*types.UpdateDnsConfigResponse, error) { + var reqBody, resBody UpdateDnsConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateDvsCapabilityBody struct { + Req *types.UpdateDvsCapability `xml:"urn:vim25 UpdateDvsCapability,omitempty"` + Res *types.UpdateDvsCapabilityResponse `xml:"urn:vim25 UpdateDvsCapabilityResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateDvsCapabilityBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateDvsCapability(ctx context.Context, r soap.RoundTripper, req *types.UpdateDvsCapability) (*types.UpdateDvsCapabilityResponse, error) { + var reqBody, resBody UpdateDvsCapabilityBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateExtensionBody struct { + Req *types.UpdateExtension `xml:"urn:vim25 UpdateExtension,omitempty"` + Res *types.UpdateExtensionResponse `xml:"urn:vim25 UpdateExtensionResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateExtensionBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateExtension(ctx context.Context, r soap.RoundTripper, req *types.UpdateExtension) (*types.UpdateExtensionResponse, error) { + var reqBody, resBody UpdateExtensionBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateFlagsBody struct { + Req *types.UpdateFlags `xml:"urn:vim25 UpdateFlags,omitempty"` + Res *types.UpdateFlagsResponse `xml:"urn:vim25 UpdateFlagsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateFlagsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateFlags(ctx context.Context, r soap.RoundTripper, req *types.UpdateFlags) (*types.UpdateFlagsResponse, error) { + var reqBody, resBody UpdateFlagsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateHostImageAcceptanceLevelBody struct { + Req *types.UpdateHostImageAcceptanceLevel `xml:"urn:vim25 UpdateHostImageAcceptanceLevel,omitempty"` + Res *types.UpdateHostImageAcceptanceLevelResponse `xml:"urn:vim25 UpdateHostImageAcceptanceLevelResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateHostImageAcceptanceLevelBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateHostImageAcceptanceLevel(ctx context.Context, r soap.RoundTripper, req *types.UpdateHostImageAcceptanceLevel) (*types.UpdateHostImageAcceptanceLevelResponse, error) { + var reqBody, resBody UpdateHostImageAcceptanceLevelBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateHostProfileBody struct { + Req *types.UpdateHostProfile `xml:"urn:vim25 UpdateHostProfile,omitempty"` + Res *types.UpdateHostProfileResponse `xml:"urn:vim25 UpdateHostProfileResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateHostProfileBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateHostProfile(ctx context.Context, r soap.RoundTripper, req *types.UpdateHostProfile) (*types.UpdateHostProfileResponse, error) { + var reqBody, resBody UpdateHostProfileBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiAdvancedOptionsBody struct { + Req *types.UpdateInternetScsiAdvancedOptions `xml:"urn:vim25 UpdateInternetScsiAdvancedOptions,omitempty"` + Res *types.UpdateInternetScsiAdvancedOptionsResponse `xml:"urn:vim25 UpdateInternetScsiAdvancedOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiAdvancedOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiAdvancedOptions(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiAdvancedOptions) (*types.UpdateInternetScsiAdvancedOptionsResponse, error) { + var reqBody, resBody UpdateInternetScsiAdvancedOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiAliasBody struct { + Req *types.UpdateInternetScsiAlias `xml:"urn:vim25 UpdateInternetScsiAlias,omitempty"` + Res *types.UpdateInternetScsiAliasResponse `xml:"urn:vim25 UpdateInternetScsiAliasResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiAliasBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiAlias(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiAlias) (*types.UpdateInternetScsiAliasResponse, error) { + var reqBody, resBody UpdateInternetScsiAliasBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiAuthenticationPropertiesBody struct { + Req *types.UpdateInternetScsiAuthenticationProperties `xml:"urn:vim25 UpdateInternetScsiAuthenticationProperties,omitempty"` + Res *types.UpdateInternetScsiAuthenticationPropertiesResponse `xml:"urn:vim25 UpdateInternetScsiAuthenticationPropertiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiAuthenticationPropertiesBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiAuthenticationProperties(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiAuthenticationProperties) (*types.UpdateInternetScsiAuthenticationPropertiesResponse, error) { + var reqBody, resBody UpdateInternetScsiAuthenticationPropertiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiDigestPropertiesBody struct { + Req *types.UpdateInternetScsiDigestProperties `xml:"urn:vim25 UpdateInternetScsiDigestProperties,omitempty"` + Res *types.UpdateInternetScsiDigestPropertiesResponse `xml:"urn:vim25 UpdateInternetScsiDigestPropertiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiDigestPropertiesBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiDigestProperties(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiDigestProperties) (*types.UpdateInternetScsiDigestPropertiesResponse, error) { + var reqBody, resBody UpdateInternetScsiDigestPropertiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiDiscoveryPropertiesBody struct { + Req *types.UpdateInternetScsiDiscoveryProperties `xml:"urn:vim25 UpdateInternetScsiDiscoveryProperties,omitempty"` + Res *types.UpdateInternetScsiDiscoveryPropertiesResponse `xml:"urn:vim25 UpdateInternetScsiDiscoveryPropertiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiDiscoveryPropertiesBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiDiscoveryProperties(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiDiscoveryProperties) (*types.UpdateInternetScsiDiscoveryPropertiesResponse, error) { + var reqBody, resBody UpdateInternetScsiDiscoveryPropertiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiIPPropertiesBody struct { + Req *types.UpdateInternetScsiIPProperties `xml:"urn:vim25 UpdateInternetScsiIPProperties,omitempty"` + Res *types.UpdateInternetScsiIPPropertiesResponse `xml:"urn:vim25 UpdateInternetScsiIPPropertiesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiIPPropertiesBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiIPProperties(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiIPProperties) (*types.UpdateInternetScsiIPPropertiesResponse, error) { + var reqBody, resBody UpdateInternetScsiIPPropertiesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateInternetScsiNameBody struct { + Req *types.UpdateInternetScsiName `xml:"urn:vim25 UpdateInternetScsiName,omitempty"` + Res *types.UpdateInternetScsiNameResponse `xml:"urn:vim25 UpdateInternetScsiNameResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateInternetScsiNameBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateInternetScsiName(ctx context.Context, r soap.RoundTripper, req *types.UpdateInternetScsiName) (*types.UpdateInternetScsiNameResponse, error) { + var reqBody, resBody UpdateInternetScsiNameBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateIpConfigBody struct { + Req *types.UpdateIpConfig `xml:"urn:vim25 UpdateIpConfig,omitempty"` + Res *types.UpdateIpConfigResponse `xml:"urn:vim25 UpdateIpConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateIpConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateIpConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateIpConfig) (*types.UpdateIpConfigResponse, error) { + var reqBody, resBody UpdateIpConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateIpPoolBody struct { + Req *types.UpdateIpPool `xml:"urn:vim25 UpdateIpPool,omitempty"` + Res *types.UpdateIpPoolResponse `xml:"urn:vim25 UpdateIpPoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateIpPoolBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateIpPool(ctx context.Context, r soap.RoundTripper, req *types.UpdateIpPool) (*types.UpdateIpPoolResponse, error) { + var reqBody, resBody UpdateIpPoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateIpRouteConfigBody struct { + Req *types.UpdateIpRouteConfig `xml:"urn:vim25 UpdateIpRouteConfig,omitempty"` + Res *types.UpdateIpRouteConfigResponse `xml:"urn:vim25 UpdateIpRouteConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateIpRouteConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateIpRouteConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateIpRouteConfig) (*types.UpdateIpRouteConfigResponse, error) { + var reqBody, resBody UpdateIpRouteConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateIpRouteTableConfigBody struct { + Req *types.UpdateIpRouteTableConfig `xml:"urn:vim25 UpdateIpRouteTableConfig,omitempty"` + Res *types.UpdateIpRouteTableConfigResponse `xml:"urn:vim25 UpdateIpRouteTableConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateIpRouteTableConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateIpRouteTableConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateIpRouteTableConfig) (*types.UpdateIpRouteTableConfigResponse, error) { + var reqBody, resBody UpdateIpRouteTableConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateIpmiBody struct { + Req *types.UpdateIpmi `xml:"urn:vim25 UpdateIpmi,omitempty"` + Res *types.UpdateIpmiResponse `xml:"urn:vim25 UpdateIpmiResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateIpmiBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateIpmi(ctx context.Context, r soap.RoundTripper, req *types.UpdateIpmi) (*types.UpdateIpmiResponse, error) { + var reqBody, resBody UpdateIpmiBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateLicenseBody struct { + Req *types.UpdateLicense `xml:"urn:vim25 UpdateLicense,omitempty"` + Res *types.UpdateLicenseResponse `xml:"urn:vim25 UpdateLicenseResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateLicenseBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateLicense(ctx context.Context, r soap.RoundTripper, req *types.UpdateLicense) (*types.UpdateLicenseResponse, error) { + var reqBody, resBody UpdateLicenseBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateLicenseLabelBody struct { + Req *types.UpdateLicenseLabel `xml:"urn:vim25 UpdateLicenseLabel,omitempty"` + Res *types.UpdateLicenseLabelResponse `xml:"urn:vim25 UpdateLicenseLabelResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateLicenseLabelBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateLicenseLabel(ctx context.Context, r soap.RoundTripper, req *types.UpdateLicenseLabel) (*types.UpdateLicenseLabelResponse, error) { + var reqBody, resBody UpdateLicenseLabelBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateLinkedChildrenBody struct { + Req *types.UpdateLinkedChildren `xml:"urn:vim25 UpdateLinkedChildren,omitempty"` + Res *types.UpdateLinkedChildrenResponse `xml:"urn:vim25 UpdateLinkedChildrenResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateLinkedChildrenBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateLinkedChildren(ctx context.Context, r soap.RoundTripper, req *types.UpdateLinkedChildren) (*types.UpdateLinkedChildrenResponse, error) { + var reqBody, resBody UpdateLinkedChildrenBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateLocalSwapDatastoreBody struct { + Req *types.UpdateLocalSwapDatastore `xml:"urn:vim25 UpdateLocalSwapDatastore,omitempty"` + Res *types.UpdateLocalSwapDatastoreResponse `xml:"urn:vim25 UpdateLocalSwapDatastoreResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateLocalSwapDatastoreBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateLocalSwapDatastore(ctx context.Context, r soap.RoundTripper, req *types.UpdateLocalSwapDatastore) (*types.UpdateLocalSwapDatastoreResponse, error) { + var reqBody, resBody UpdateLocalSwapDatastoreBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateLockdownExceptionsBody struct { + Req *types.UpdateLockdownExceptions `xml:"urn:vim25 UpdateLockdownExceptions,omitempty"` + Res *types.UpdateLockdownExceptionsResponse `xml:"urn:vim25 UpdateLockdownExceptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateLockdownExceptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateLockdownExceptions(ctx context.Context, r soap.RoundTripper, req *types.UpdateLockdownExceptions) (*types.UpdateLockdownExceptionsResponse, error) { + var reqBody, resBody UpdateLockdownExceptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateModuleOptionStringBody struct { + Req *types.UpdateModuleOptionString `xml:"urn:vim25 UpdateModuleOptionString,omitempty"` + Res *types.UpdateModuleOptionStringResponse `xml:"urn:vim25 UpdateModuleOptionStringResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateModuleOptionStringBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateModuleOptionString(ctx context.Context, r soap.RoundTripper, req *types.UpdateModuleOptionString) (*types.UpdateModuleOptionStringResponse, error) { + var reqBody, resBody UpdateModuleOptionStringBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateNetworkConfigBody struct { + Req *types.UpdateNetworkConfig `xml:"urn:vim25 UpdateNetworkConfig,omitempty"` + Res *types.UpdateNetworkConfigResponse `xml:"urn:vim25 UpdateNetworkConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateNetworkConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateNetworkConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateNetworkConfig) (*types.UpdateNetworkConfigResponse, error) { + var reqBody, resBody UpdateNetworkConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateNetworkResourcePoolBody struct { + Req *types.UpdateNetworkResourcePool `xml:"urn:vim25 UpdateNetworkResourcePool,omitempty"` + Res *types.UpdateNetworkResourcePoolResponse `xml:"urn:vim25 UpdateNetworkResourcePoolResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateNetworkResourcePoolBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateNetworkResourcePool(ctx context.Context, r soap.RoundTripper, req *types.UpdateNetworkResourcePool) (*types.UpdateNetworkResourcePoolResponse, error) { + var reqBody, resBody UpdateNetworkResourcePoolBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateOptionsBody struct { + Req *types.UpdateOptions `xml:"urn:vim25 UpdateOptions,omitempty"` + Res *types.UpdateOptionsResponse `xml:"urn:vim25 UpdateOptionsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateOptionsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateOptions(ctx context.Context, r soap.RoundTripper, req *types.UpdateOptions) (*types.UpdateOptionsResponse, error) { + var reqBody, resBody UpdateOptionsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdatePassthruConfigBody struct { + Req *types.UpdatePassthruConfig `xml:"urn:vim25 UpdatePassthruConfig,omitempty"` + Res *types.UpdatePassthruConfigResponse `xml:"urn:vim25 UpdatePassthruConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdatePassthruConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdatePassthruConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdatePassthruConfig) (*types.UpdatePassthruConfigResponse, error) { + var reqBody, resBody UpdatePassthruConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdatePerfIntervalBody struct { + Req *types.UpdatePerfInterval `xml:"urn:vim25 UpdatePerfInterval,omitempty"` + Res *types.UpdatePerfIntervalResponse `xml:"urn:vim25 UpdatePerfIntervalResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdatePerfIntervalBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdatePerfInterval(ctx context.Context, r soap.RoundTripper, req *types.UpdatePerfInterval) (*types.UpdatePerfIntervalResponse, error) { + var reqBody, resBody UpdatePerfIntervalBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdatePhysicalNicLinkSpeedBody struct { + Req *types.UpdatePhysicalNicLinkSpeed `xml:"urn:vim25 UpdatePhysicalNicLinkSpeed,omitempty"` + Res *types.UpdatePhysicalNicLinkSpeedResponse `xml:"urn:vim25 UpdatePhysicalNicLinkSpeedResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdatePhysicalNicLinkSpeedBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdatePhysicalNicLinkSpeed(ctx context.Context, r soap.RoundTripper, req *types.UpdatePhysicalNicLinkSpeed) (*types.UpdatePhysicalNicLinkSpeedResponse, error) { + var reqBody, resBody UpdatePhysicalNicLinkSpeedBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdatePortGroupBody struct { + Req *types.UpdatePortGroup `xml:"urn:vim25 UpdatePortGroup,omitempty"` + Res *types.UpdatePortGroupResponse `xml:"urn:vim25 UpdatePortGroupResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdatePortGroupBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdatePortGroup(ctx context.Context, r soap.RoundTripper, req *types.UpdatePortGroup) (*types.UpdatePortGroupResponse, error) { + var reqBody, resBody UpdatePortGroupBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateProgressBody struct { + Req *types.UpdateProgress `xml:"urn:vim25 UpdateProgress,omitempty"` + Res *types.UpdateProgressResponse `xml:"urn:vim25 UpdateProgressResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateProgressBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateProgress(ctx context.Context, r soap.RoundTripper, req *types.UpdateProgress) (*types.UpdateProgressResponse, error) { + var reqBody, resBody UpdateProgressBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateReferenceHostBody struct { + Req *types.UpdateReferenceHost `xml:"urn:vim25 UpdateReferenceHost,omitempty"` + Res *types.UpdateReferenceHostResponse `xml:"urn:vim25 UpdateReferenceHostResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateReferenceHostBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateReferenceHost(ctx context.Context, r soap.RoundTripper, req *types.UpdateReferenceHost) (*types.UpdateReferenceHostResponse, error) { + var reqBody, resBody UpdateReferenceHostBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateRulesetBody struct { + Req *types.UpdateRuleset `xml:"urn:vim25 UpdateRuleset,omitempty"` + Res *types.UpdateRulesetResponse `xml:"urn:vim25 UpdateRulesetResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateRulesetBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateRuleset(ctx context.Context, r soap.RoundTripper, req *types.UpdateRuleset) (*types.UpdateRulesetResponse, error) { + var reqBody, resBody UpdateRulesetBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateScsiLunDisplayNameBody struct { + Req *types.UpdateScsiLunDisplayName `xml:"urn:vim25 UpdateScsiLunDisplayName,omitempty"` + Res *types.UpdateScsiLunDisplayNameResponse `xml:"urn:vim25 UpdateScsiLunDisplayNameResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateScsiLunDisplayNameBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateScsiLunDisplayName(ctx context.Context, r soap.RoundTripper, req *types.UpdateScsiLunDisplayName) (*types.UpdateScsiLunDisplayNameResponse, error) { + var reqBody, resBody UpdateScsiLunDisplayNameBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateServiceConsoleVirtualNicBody struct { + Req *types.UpdateServiceConsoleVirtualNic `xml:"urn:vim25 UpdateServiceConsoleVirtualNic,omitempty"` + Res *types.UpdateServiceConsoleVirtualNicResponse `xml:"urn:vim25 UpdateServiceConsoleVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateServiceConsoleVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateServiceConsoleVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.UpdateServiceConsoleVirtualNic) (*types.UpdateServiceConsoleVirtualNicResponse, error) { + var reqBody, resBody UpdateServiceConsoleVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateServiceMessageBody struct { + Req *types.UpdateServiceMessage `xml:"urn:vim25 UpdateServiceMessage,omitempty"` + Res *types.UpdateServiceMessageResponse `xml:"urn:vim25 UpdateServiceMessageResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateServiceMessageBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateServiceMessage(ctx context.Context, r soap.RoundTripper, req *types.UpdateServiceMessage) (*types.UpdateServiceMessageResponse, error) { + var reqBody, resBody UpdateServiceMessageBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateServicePolicyBody struct { + Req *types.UpdateServicePolicy `xml:"urn:vim25 UpdateServicePolicy,omitempty"` + Res *types.UpdateServicePolicyResponse `xml:"urn:vim25 UpdateServicePolicyResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateServicePolicyBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateServicePolicy(ctx context.Context, r soap.RoundTripper, req *types.UpdateServicePolicy) (*types.UpdateServicePolicyResponse, error) { + var reqBody, resBody UpdateServicePolicyBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateSoftwareInternetScsiEnabledBody struct { + Req *types.UpdateSoftwareInternetScsiEnabled `xml:"urn:vim25 UpdateSoftwareInternetScsiEnabled,omitempty"` + Res *types.UpdateSoftwareInternetScsiEnabledResponse `xml:"urn:vim25 UpdateSoftwareInternetScsiEnabledResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateSoftwareInternetScsiEnabledBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateSoftwareInternetScsiEnabled(ctx context.Context, r soap.RoundTripper, req *types.UpdateSoftwareInternetScsiEnabled) (*types.UpdateSoftwareInternetScsiEnabledResponse, error) { + var reqBody, resBody UpdateSoftwareInternetScsiEnabledBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateSystemResourcesBody struct { + Req *types.UpdateSystemResources `xml:"urn:vim25 UpdateSystemResources,omitempty"` + Res *types.UpdateSystemResourcesResponse `xml:"urn:vim25 UpdateSystemResourcesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateSystemResourcesBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateSystemResources(ctx context.Context, r soap.RoundTripper, req *types.UpdateSystemResources) (*types.UpdateSystemResourcesResponse, error) { + var reqBody, resBody UpdateSystemResourcesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateSystemSwapConfigurationBody struct { + Req *types.UpdateSystemSwapConfiguration `xml:"urn:vim25 UpdateSystemSwapConfiguration,omitempty"` + Res *types.UpdateSystemSwapConfigurationResponse `xml:"urn:vim25 UpdateSystemSwapConfigurationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateSystemSwapConfigurationBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateSystemSwapConfiguration(ctx context.Context, r soap.RoundTripper, req *types.UpdateSystemSwapConfiguration) (*types.UpdateSystemSwapConfigurationResponse, error) { + var reqBody, resBody UpdateSystemSwapConfigurationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateSystemUsersBody struct { + Req *types.UpdateSystemUsers `xml:"urn:vim25 UpdateSystemUsers,omitempty"` + Res *types.UpdateSystemUsersResponse `xml:"urn:vim25 UpdateSystemUsersResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateSystemUsersBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateSystemUsers(ctx context.Context, r soap.RoundTripper, req *types.UpdateSystemUsers) (*types.UpdateSystemUsersResponse, error) { + var reqBody, resBody UpdateSystemUsersBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateUserBody struct { + Req *types.UpdateUser `xml:"urn:vim25 UpdateUser,omitempty"` + Res *types.UpdateUserResponse `xml:"urn:vim25 UpdateUserResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateUserBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateUser(ctx context.Context, r soap.RoundTripper, req *types.UpdateUser) (*types.UpdateUserResponse, error) { + var reqBody, resBody UpdateUserBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateVAppConfigBody struct { + Req *types.UpdateVAppConfig `xml:"urn:vim25 UpdateVAppConfig,omitempty"` + Res *types.UpdateVAppConfigResponse `xml:"urn:vim25 UpdateVAppConfigResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateVAppConfigBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateVAppConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateVAppConfig) (*types.UpdateVAppConfigResponse, error) { + var reqBody, resBody UpdateVAppConfigBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateVirtualMachineFiles_TaskBody struct { + Req *types.UpdateVirtualMachineFiles_Task `xml:"urn:vim25 UpdateVirtualMachineFiles_Task,omitempty"` + Res *types.UpdateVirtualMachineFiles_TaskResponse `xml:"urn:vim25 UpdateVirtualMachineFiles_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateVirtualMachineFiles_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateVirtualMachineFiles_Task(ctx context.Context, r soap.RoundTripper, req *types.UpdateVirtualMachineFiles_Task) (*types.UpdateVirtualMachineFiles_TaskResponse, error) { + var reqBody, resBody UpdateVirtualMachineFiles_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateVirtualNicBody struct { + Req *types.UpdateVirtualNic `xml:"urn:vim25 UpdateVirtualNic,omitempty"` + Res *types.UpdateVirtualNicResponse `xml:"urn:vim25 UpdateVirtualNicResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateVirtualNicBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateVirtualNic(ctx context.Context, r soap.RoundTripper, req *types.UpdateVirtualNic) (*types.UpdateVirtualNicResponse, error) { + var reqBody, resBody UpdateVirtualNicBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateVirtualSwitchBody struct { + Req *types.UpdateVirtualSwitch `xml:"urn:vim25 UpdateVirtualSwitch,omitempty"` + Res *types.UpdateVirtualSwitchResponse `xml:"urn:vim25 UpdateVirtualSwitchResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateVirtualSwitchBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateVirtualSwitch(ctx context.Context, r soap.RoundTripper, req *types.UpdateVirtualSwitch) (*types.UpdateVirtualSwitchResponse, error) { + var reqBody, resBody UpdateVirtualSwitchBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpdateVsan_TaskBody struct { + Req *types.UpdateVsan_Task `xml:"urn:vim25 UpdateVsan_Task,omitempty"` + Res *types.UpdateVsan_TaskResponse `xml:"urn:vim25 UpdateVsan_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpdateVsan_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpdateVsan_Task(ctx context.Context, r soap.RoundTripper, req *types.UpdateVsan_Task) (*types.UpdateVsan_TaskResponse, error) { + var reqBody, resBody UpdateVsan_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpgradeIoFilter_TaskBody struct { + Req *types.UpgradeIoFilter_Task `xml:"urn:vim25 UpgradeIoFilter_Task,omitempty"` + Res *types.UpgradeIoFilter_TaskResponse `xml:"urn:vim25 UpgradeIoFilter_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpgradeIoFilter_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpgradeIoFilter_Task(ctx context.Context, r soap.RoundTripper, req *types.UpgradeIoFilter_Task) (*types.UpgradeIoFilter_TaskResponse, error) { + var reqBody, resBody UpgradeIoFilter_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpgradeTools_TaskBody struct { + Req *types.UpgradeTools_Task `xml:"urn:vim25 UpgradeTools_Task,omitempty"` + Res *types.UpgradeTools_TaskResponse `xml:"urn:vim25 UpgradeTools_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpgradeTools_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpgradeTools_Task(ctx context.Context, r soap.RoundTripper, req *types.UpgradeTools_Task) (*types.UpgradeTools_TaskResponse, error) { + var reqBody, resBody UpgradeTools_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpgradeVM_TaskBody struct { + Req *types.UpgradeVM_Task `xml:"urn:vim25 UpgradeVM_Task,omitempty"` + Res *types.UpgradeVM_TaskResponse `xml:"urn:vim25 UpgradeVM_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpgradeVM_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func UpgradeVM_Task(ctx context.Context, r soap.RoundTripper, req *types.UpgradeVM_Task) (*types.UpgradeVM_TaskResponse, error) { + var reqBody, resBody UpgradeVM_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpgradeVmLayoutBody struct { + Req *types.UpgradeVmLayout `xml:"urn:vim25 UpgradeVmLayout,omitempty"` + Res *types.UpgradeVmLayoutResponse `xml:"urn:vim25 UpgradeVmLayoutResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpgradeVmLayoutBody) Fault() *soap.Fault { return b.Fault_ } + +func UpgradeVmLayout(ctx context.Context, r soap.RoundTripper, req *types.UpgradeVmLayout) (*types.UpgradeVmLayoutResponse, error) { + var reqBody, resBody UpgradeVmLayoutBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpgradeVmfsBody struct { + Req *types.UpgradeVmfs `xml:"urn:vim25 UpgradeVmfs,omitempty"` + Res *types.UpgradeVmfsResponse `xml:"urn:vim25 UpgradeVmfsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpgradeVmfsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpgradeVmfs(ctx context.Context, r soap.RoundTripper, req *types.UpgradeVmfs) (*types.UpgradeVmfsResponse, error) { + var reqBody, resBody UpgradeVmfsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type UpgradeVsanObjectsBody struct { + Req *types.UpgradeVsanObjects `xml:"urn:vim25 UpgradeVsanObjects,omitempty"` + Res *types.UpgradeVsanObjectsResponse `xml:"urn:vim25 UpgradeVsanObjectsResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *UpgradeVsanObjectsBody) Fault() *soap.Fault { return b.Fault_ } + +func UpgradeVsanObjects(ctx context.Context, r soap.RoundTripper, req *types.UpgradeVsanObjects) (*types.UpgradeVsanObjectsResponse, error) { + var reqBody, resBody UpgradeVsanObjectsBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ValidateCredentialsInGuestBody struct { + Req *types.ValidateCredentialsInGuest `xml:"urn:vim25 ValidateCredentialsInGuest,omitempty"` + Res *types.ValidateCredentialsInGuestResponse `xml:"urn:vim25 ValidateCredentialsInGuestResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ValidateCredentialsInGuestBody) Fault() *soap.Fault { return b.Fault_ } + +func ValidateCredentialsInGuest(ctx context.Context, r soap.RoundTripper, req *types.ValidateCredentialsInGuest) (*types.ValidateCredentialsInGuestResponse, error) { + var reqBody, resBody ValidateCredentialsInGuestBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ValidateHostBody struct { + Req *types.ValidateHost `xml:"urn:vim25 ValidateHost,omitempty"` + Res *types.ValidateHostResponse `xml:"urn:vim25 ValidateHostResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ValidateHostBody) Fault() *soap.Fault { return b.Fault_ } + +func ValidateHost(ctx context.Context, r soap.RoundTripper, req *types.ValidateHost) (*types.ValidateHostResponse, error) { + var reqBody, resBody ValidateHostBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ValidateMigrationBody struct { + Req *types.ValidateMigration `xml:"urn:vim25 ValidateMigration,omitempty"` + Res *types.ValidateMigrationResponse `xml:"urn:vim25 ValidateMigrationResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ValidateMigrationBody) Fault() *soap.Fault { return b.Fault_ } + +func ValidateMigration(ctx context.Context, r soap.RoundTripper, req *types.ValidateMigration) (*types.ValidateMigrationResponse, error) { + var reqBody, resBody ValidateMigrationBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type WaitForUpdatesBody struct { + Req *types.WaitForUpdates `xml:"urn:vim25 WaitForUpdates,omitempty"` + Res *types.WaitForUpdatesResponse `xml:"urn:vim25 WaitForUpdatesResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *WaitForUpdatesBody) Fault() *soap.Fault { return b.Fault_ } + +func WaitForUpdates(ctx context.Context, r soap.RoundTripper, req *types.WaitForUpdates) (*types.WaitForUpdatesResponse, error) { + var reqBody, resBody WaitForUpdatesBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type WaitForUpdatesExBody struct { + Req *types.WaitForUpdatesEx `xml:"urn:vim25 WaitForUpdatesEx,omitempty"` + Res *types.WaitForUpdatesExResponse `xml:"urn:vim25 WaitForUpdatesExResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *WaitForUpdatesExBody) Fault() *soap.Fault { return b.Fault_ } + +func WaitForUpdatesEx(ctx context.Context, r soap.RoundTripper, req *types.WaitForUpdatesEx) (*types.WaitForUpdatesExResponse, error) { + var reqBody, resBody WaitForUpdatesExBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type XmlToCustomizationSpecItemBody struct { + Req *types.XmlToCustomizationSpecItem `xml:"urn:vim25 XmlToCustomizationSpecItem,omitempty"` + Res *types.XmlToCustomizationSpecItemResponse `xml:"urn:vim25 XmlToCustomizationSpecItemResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *XmlToCustomizationSpecItemBody) Fault() *soap.Fault { return b.Fault_ } + +func XmlToCustomizationSpecItem(ctx context.Context, r soap.RoundTripper, req *types.XmlToCustomizationSpecItem) (*types.XmlToCustomizationSpecItemResponse, error) { + var reqBody, resBody XmlToCustomizationSpecItemBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} + +type ZeroFillVirtualDisk_TaskBody struct { + Req *types.ZeroFillVirtualDisk_Task `xml:"urn:vim25 ZeroFillVirtualDisk_Task,omitempty"` + Res *types.ZeroFillVirtualDisk_TaskResponse `xml:"urn:vim25 ZeroFillVirtualDisk_TaskResponse,omitempty"` + Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` +} + +func (b *ZeroFillVirtualDisk_TaskBody) Fault() *soap.Fault { return b.Fault_ } + +func ZeroFillVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *types.ZeroFillVirtualDisk_Task) (*types.ZeroFillVirtualDisk_TaskResponse, error) { + var reqBody, resBody ZeroFillVirtualDisk_TaskBody + + reqBody.Req = req + + if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil { + return nil, err + } + + return resBody.Res, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go b/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go new file mode 100644 index 0000000000..f685fdc2eb --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go @@ -0,0 +1,56 @@ +/* +Copyright (c) 2015 VMware, 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 methods + +import ( + "time" + + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +var serviceInstance = types.ManagedObjectReference{ + Type: "ServiceInstance", + Value: "ServiceInstance", +} + +func GetServiceContent(ctx context.Context, r soap.RoundTripper) (types.ServiceContent, error) { + req := types.RetrieveServiceContent{ + This: serviceInstance, + } + + res, err := RetrieveServiceContent(ctx, r, &req) + if err != nil { + return types.ServiceContent{}, err + } + + return res.Returnval, nil +} + +func GetCurrentTime(ctx context.Context, r soap.RoundTripper) (*time.Time, error) { + req := types.CurrentTime{ + This: serviceInstance, + } + + res, err := CurrentTime(ctx, r, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go b/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go new file mode 100644 index 0000000000..4bea1552c5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2015 VMware, 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 mo + +import ( + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +// Ancestors returns the entire ancestry tree of a specified managed object. +// The return value includes the root node and the specified object itself. +func Ancestors(ctx context.Context, rt soap.RoundTripper, pc, obj types.ManagedObjectReference) ([]ManagedEntity, error) { + ospec := types.ObjectSpec{ + Obj: obj, + SelectSet: []types.BaseSelectionSpec{ + &types.TraversalSpec{ + SelectionSpec: types.SelectionSpec{Name: "traverseParent"}, + Type: "ManagedEntity", + Path: "parent", + Skip: types.NewBool(false), + SelectSet: []types.BaseSelectionSpec{ + &types.SelectionSpec{Name: "traverseParent"}, + }, + }, + }, + Skip: types.NewBool(false), + } + + pspec := types.PropertySpec{ + Type: "ManagedEntity", + PathSet: []string{"name", "parent"}, + } + + req := types.RetrieveProperties{ + This: pc, + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: []types.PropertySpec{pspec}, + }, + }, + } + + var ifaces []interface{} + + err := RetrievePropertiesForRequest(ctx, rt, req, &ifaces) + if err != nil { + return nil, err + } + + var out []ManagedEntity + + // Build ancestry tree by iteratively finding a new child. + for len(out) < len(ifaces) { + var find types.ManagedObjectReference + + if len(out) > 0 { + find = out[len(out)-1].Self + } + + // Find entity we're looking for given the last entity in the current tree. + for _, iface := range ifaces { + me := iface.(IsManagedEntity).GetManagedEntity() + if me.Parent == nil { + out = append(out, me) + break + } + + if *me.Parent == find { + out = append(out, me) + break + } + } + } + + return out, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/entity.go b/vendor/github.com/vmware/govmomi/vim25/mo/entity.go new file mode 100644 index 0000000000..193e6f71ea --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/entity.go @@ -0,0 +1,24 @@ +/* +Copyright (c) 2016 VMware, 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 mo + +// Entity is the interface that is implemented by all managed objects +// that extend ManagedEntity. +type Entity interface { + Reference + Entity() *ManagedEntity +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/extra.go b/vendor/github.com/vmware/govmomi/vim25/mo/extra.go new file mode 100644 index 0000000000..36ed5ff0f8 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/extra.go @@ -0,0 +1,57 @@ +/* +Copyright (c) 2014 VMware, 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 mo + +type IsManagedEntity interface { + GetManagedEntity() ManagedEntity +} + +func (m ComputeResource) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m Datacenter) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m Datastore) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m DistributedVirtualSwitch) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m Folder) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m HostSystem) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m Network) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m ResourcePool) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + +func (m VirtualMachine) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/mo.go b/vendor/github.com/vmware/govmomi/vim25/mo/mo.go new file mode 100644 index 0000000000..f68b890a5d --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/mo.go @@ -0,0 +1,1660 @@ +/* +Copyright (c) 2014-2016 VMware, 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 mo + +import ( + "reflect" + "time" + + "github.com/vmware/govmomi/vim25/types" +) + +type Alarm struct { + ExtensibleManagedObject + + Info types.AlarmInfo `mo:"info"` +} + +func init() { + t["Alarm"] = reflect.TypeOf((*Alarm)(nil)).Elem() +} + +type AlarmManager struct { + Self types.ManagedObjectReference + + DefaultExpression []types.BaseAlarmExpression `mo:"defaultExpression"` + Description types.AlarmDescription `mo:"description"` +} + +func (m AlarmManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["AlarmManager"] = reflect.TypeOf((*AlarmManager)(nil)).Elem() +} + +type AuthorizationManager struct { + Self types.ManagedObjectReference + + PrivilegeList []types.AuthorizationPrivilege `mo:"privilegeList"` + RoleList []types.AuthorizationRole `mo:"roleList"` + Description types.AuthorizationDescription `mo:"description"` +} + +func (m AuthorizationManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["AuthorizationManager"] = reflect.TypeOf((*AuthorizationManager)(nil)).Elem() +} + +type CertificateManager struct { + Self types.ManagedObjectReference +} + +func (m CertificateManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["CertificateManager"] = reflect.TypeOf((*CertificateManager)(nil)).Elem() +} + +type ClusterComputeResource struct { + ComputeResource + + Configuration types.ClusterConfigInfo `mo:"configuration"` + Recommendation []types.ClusterRecommendation `mo:"recommendation"` + DrsRecommendation []types.ClusterDrsRecommendation `mo:"drsRecommendation"` + MigrationHistory []types.ClusterDrsMigration `mo:"migrationHistory"` + ActionHistory []types.ClusterActionHistory `mo:"actionHistory"` + DrsFault []types.ClusterDrsFaults `mo:"drsFault"` +} + +func init() { + t["ClusterComputeResource"] = reflect.TypeOf((*ClusterComputeResource)(nil)).Elem() +} + +type ClusterEVCManager struct { + ExtensibleManagedObject + + ManagedCluster types.ManagedObjectReference `mo:"managedCluster"` + EvcState types.ClusterEVCManagerEVCState `mo:"evcState"` +} + +func init() { + t["ClusterEVCManager"] = reflect.TypeOf((*ClusterEVCManager)(nil)).Elem() +} + +type ClusterProfile struct { + Profile +} + +func init() { + t["ClusterProfile"] = reflect.TypeOf((*ClusterProfile)(nil)).Elem() +} + +type ClusterProfileManager struct { + ProfileManager +} + +func init() { + t["ClusterProfileManager"] = reflect.TypeOf((*ClusterProfileManager)(nil)).Elem() +} + +type ComputeResource struct { + ManagedEntity + + ResourcePool *types.ManagedObjectReference `mo:"resourcePool"` + Host []types.ManagedObjectReference `mo:"host"` + Datastore []types.ManagedObjectReference `mo:"datastore"` + Network []types.ManagedObjectReference `mo:"network"` + Summary types.BaseComputeResourceSummary `mo:"summary"` + EnvironmentBrowser *types.ManagedObjectReference `mo:"environmentBrowser"` + ConfigurationEx types.BaseComputeResourceConfigInfo `mo:"configurationEx"` +} + +func (m *ComputeResource) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["ComputeResource"] = reflect.TypeOf((*ComputeResource)(nil)).Elem() +} + +type ContainerView struct { + ManagedObjectView + + Container types.ManagedObjectReference `mo:"container"` + Type []string `mo:"type"` + Recursive bool `mo:"recursive"` +} + +func init() { + t["ContainerView"] = reflect.TypeOf((*ContainerView)(nil)).Elem() +} + +type CustomFieldsManager struct { + Self types.ManagedObjectReference + + Field []types.CustomFieldDef `mo:"field"` +} + +func (m CustomFieldsManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["CustomFieldsManager"] = reflect.TypeOf((*CustomFieldsManager)(nil)).Elem() +} + +type CustomizationSpecManager struct { + Self types.ManagedObjectReference + + Info []types.CustomizationSpecInfo `mo:"info"` + EncryptionKey []byte `mo:"encryptionKey"` +} + +func (m CustomizationSpecManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["CustomizationSpecManager"] = reflect.TypeOf((*CustomizationSpecManager)(nil)).Elem() +} + +type Datacenter struct { + ManagedEntity + + VmFolder types.ManagedObjectReference `mo:"vmFolder"` + HostFolder types.ManagedObjectReference `mo:"hostFolder"` + DatastoreFolder types.ManagedObjectReference `mo:"datastoreFolder"` + NetworkFolder types.ManagedObjectReference `mo:"networkFolder"` + Datastore []types.ManagedObjectReference `mo:"datastore"` + Network []types.ManagedObjectReference `mo:"network"` + Configuration types.DatacenterConfigInfo `mo:"configuration"` +} + +func (m *Datacenter) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["Datacenter"] = reflect.TypeOf((*Datacenter)(nil)).Elem() +} + +type Datastore struct { + ManagedEntity + + Info types.BaseDatastoreInfo `mo:"info"` + Summary types.DatastoreSummary `mo:"summary"` + Host []types.DatastoreHostMount `mo:"host"` + Vm []types.ManagedObjectReference `mo:"vm"` + Browser types.ManagedObjectReference `mo:"browser"` + Capability types.DatastoreCapability `mo:"capability"` + IormConfiguration *types.StorageIORMInfo `mo:"iormConfiguration"` +} + +func (m *Datastore) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["Datastore"] = reflect.TypeOf((*Datastore)(nil)).Elem() +} + +type DatastoreNamespaceManager struct { + Self types.ManagedObjectReference +} + +func (m DatastoreNamespaceManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["DatastoreNamespaceManager"] = reflect.TypeOf((*DatastoreNamespaceManager)(nil)).Elem() +} + +type DiagnosticManager struct { + Self types.ManagedObjectReference +} + +func (m DiagnosticManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["DiagnosticManager"] = reflect.TypeOf((*DiagnosticManager)(nil)).Elem() +} + +type DistributedVirtualPortgroup struct { + Network + + Key string `mo:"key"` + Config types.DVPortgroupConfigInfo `mo:"config"` + PortKeys []string `mo:"portKeys"` +} + +func init() { + t["DistributedVirtualPortgroup"] = reflect.TypeOf((*DistributedVirtualPortgroup)(nil)).Elem() +} + +type DistributedVirtualSwitch struct { + ManagedEntity + + Uuid string `mo:"uuid"` + Capability types.DVSCapability `mo:"capability"` + Summary types.DVSSummary `mo:"summary"` + Config types.BaseDVSConfigInfo `mo:"config"` + NetworkResourcePool []types.DVSNetworkResourcePool `mo:"networkResourcePool"` + Portgroup []types.ManagedObjectReference `mo:"portgroup"` + Runtime *types.DVSRuntimeInfo `mo:"runtime"` +} + +func (m *DistributedVirtualSwitch) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["DistributedVirtualSwitch"] = reflect.TypeOf((*DistributedVirtualSwitch)(nil)).Elem() +} + +type DistributedVirtualSwitchManager struct { + Self types.ManagedObjectReference +} + +func (m DistributedVirtualSwitchManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["DistributedVirtualSwitchManager"] = reflect.TypeOf((*DistributedVirtualSwitchManager)(nil)).Elem() +} + +type EnvironmentBrowser struct { + Self types.ManagedObjectReference + + DatastoreBrowser *types.ManagedObjectReference `mo:"datastoreBrowser"` +} + +func (m EnvironmentBrowser) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["EnvironmentBrowser"] = reflect.TypeOf((*EnvironmentBrowser)(nil)).Elem() +} + +type EventHistoryCollector struct { + HistoryCollector + + LatestPage []types.BaseEvent `mo:"latestPage"` +} + +func init() { + t["EventHistoryCollector"] = reflect.TypeOf((*EventHistoryCollector)(nil)).Elem() +} + +type EventManager struct { + Self types.ManagedObjectReference + + Description types.EventDescription `mo:"description"` + LatestEvent types.BaseEvent `mo:"latestEvent"` + MaxCollector int32 `mo:"maxCollector"` +} + +func (m EventManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["EventManager"] = reflect.TypeOf((*EventManager)(nil)).Elem() +} + +type ExtensibleManagedObject struct { + Self types.ManagedObjectReference + + Value []types.BaseCustomFieldValue `mo:"value"` + AvailableField []types.CustomFieldDef `mo:"availableField"` +} + +func (m ExtensibleManagedObject) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ExtensibleManagedObject"] = reflect.TypeOf((*ExtensibleManagedObject)(nil)).Elem() +} + +type ExtensionManager struct { + Self types.ManagedObjectReference + + ExtensionList []types.Extension `mo:"extensionList"` +} + +func (m ExtensionManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ExtensionManager"] = reflect.TypeOf((*ExtensionManager)(nil)).Elem() +} + +type FileManager struct { + Self types.ManagedObjectReference +} + +func (m FileManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["FileManager"] = reflect.TypeOf((*FileManager)(nil)).Elem() +} + +type Folder struct { + ManagedEntity + + ChildType []string `mo:"childType"` + ChildEntity []types.ManagedObjectReference `mo:"childEntity"` +} + +func (m *Folder) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["Folder"] = reflect.TypeOf((*Folder)(nil)).Elem() +} + +type GuestAliasManager struct { + Self types.ManagedObjectReference +} + +func (m GuestAliasManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["GuestAliasManager"] = reflect.TypeOf((*GuestAliasManager)(nil)).Elem() +} + +type GuestAuthManager struct { + Self types.ManagedObjectReference +} + +func (m GuestAuthManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["GuestAuthManager"] = reflect.TypeOf((*GuestAuthManager)(nil)).Elem() +} + +type GuestFileManager struct { + Self types.ManagedObjectReference +} + +func (m GuestFileManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["GuestFileManager"] = reflect.TypeOf((*GuestFileManager)(nil)).Elem() +} + +type GuestOperationsManager struct { + Self types.ManagedObjectReference + + AuthManager *types.ManagedObjectReference `mo:"authManager"` + FileManager *types.ManagedObjectReference `mo:"fileManager"` + ProcessManager *types.ManagedObjectReference `mo:"processManager"` + GuestWindowsRegistryManager *types.ManagedObjectReference `mo:"guestWindowsRegistryManager"` + AliasManager *types.ManagedObjectReference `mo:"aliasManager"` +} + +func (m GuestOperationsManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["GuestOperationsManager"] = reflect.TypeOf((*GuestOperationsManager)(nil)).Elem() +} + +type GuestProcessManager struct { + Self types.ManagedObjectReference +} + +func (m GuestProcessManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["GuestProcessManager"] = reflect.TypeOf((*GuestProcessManager)(nil)).Elem() +} + +type GuestWindowsRegistryManager struct { + Self types.ManagedObjectReference +} + +func (m GuestWindowsRegistryManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["GuestWindowsRegistryManager"] = reflect.TypeOf((*GuestWindowsRegistryManager)(nil)).Elem() +} + +type HistoryCollector struct { + Self types.ManagedObjectReference + + Filter types.AnyType `mo:"filter"` +} + +func (m HistoryCollector) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HistoryCollector"] = reflect.TypeOf((*HistoryCollector)(nil)).Elem() +} + +type HostAccessManager struct { + Self types.ManagedObjectReference + + LockdownMode types.HostLockdownMode `mo:"lockdownMode"` +} + +func (m HostAccessManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostAccessManager"] = reflect.TypeOf((*HostAccessManager)(nil)).Elem() +} + +type HostActiveDirectoryAuthentication struct { + HostDirectoryStore +} + +func init() { + t["HostActiveDirectoryAuthentication"] = reflect.TypeOf((*HostActiveDirectoryAuthentication)(nil)).Elem() +} + +type HostAuthenticationManager struct { + Self types.ManagedObjectReference + + Info types.HostAuthenticationManagerInfo `mo:"info"` + SupportedStore []types.ManagedObjectReference `mo:"supportedStore"` +} + +func (m HostAuthenticationManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostAuthenticationManager"] = reflect.TypeOf((*HostAuthenticationManager)(nil)).Elem() +} + +type HostAuthenticationStore struct { + Self types.ManagedObjectReference + + Info types.BaseHostAuthenticationStoreInfo `mo:"info"` +} + +func (m HostAuthenticationStore) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostAuthenticationStore"] = reflect.TypeOf((*HostAuthenticationStore)(nil)).Elem() +} + +type HostAutoStartManager struct { + Self types.ManagedObjectReference + + Config types.HostAutoStartManagerConfig `mo:"config"` +} + +func (m HostAutoStartManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostAutoStartManager"] = reflect.TypeOf((*HostAutoStartManager)(nil)).Elem() +} + +type HostBootDeviceSystem struct { + Self types.ManagedObjectReference +} + +func (m HostBootDeviceSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostBootDeviceSystem"] = reflect.TypeOf((*HostBootDeviceSystem)(nil)).Elem() +} + +type HostCacheConfigurationManager struct { + Self types.ManagedObjectReference + + CacheConfigurationInfo []types.HostCacheConfigurationInfo `mo:"cacheConfigurationInfo"` +} + +func (m HostCacheConfigurationManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostCacheConfigurationManager"] = reflect.TypeOf((*HostCacheConfigurationManager)(nil)).Elem() +} + +type HostCertificateManager struct { + Self types.ManagedObjectReference + + CertificateInfo types.HostCertificateManagerCertificateInfo `mo:"certificateInfo"` +} + +func (m HostCertificateManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostCertificateManager"] = reflect.TypeOf((*HostCertificateManager)(nil)).Elem() +} + +type HostCpuSchedulerSystem struct { + ExtensibleManagedObject + + HyperthreadInfo *types.HostHyperThreadScheduleInfo `mo:"hyperthreadInfo"` +} + +func init() { + t["HostCpuSchedulerSystem"] = reflect.TypeOf((*HostCpuSchedulerSystem)(nil)).Elem() +} + +type HostDatastoreBrowser struct { + Self types.ManagedObjectReference + + Datastore []types.ManagedObjectReference `mo:"datastore"` + SupportedType []types.BaseFileQuery `mo:"supportedType"` +} + +func (m HostDatastoreBrowser) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostDatastoreBrowser"] = reflect.TypeOf((*HostDatastoreBrowser)(nil)).Elem() +} + +type HostDatastoreSystem struct { + Self types.ManagedObjectReference + + Datastore []types.ManagedObjectReference `mo:"datastore"` + Capabilities types.HostDatastoreSystemCapabilities `mo:"capabilities"` +} + +func (m HostDatastoreSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostDatastoreSystem"] = reflect.TypeOf((*HostDatastoreSystem)(nil)).Elem() +} + +type HostDateTimeSystem struct { + Self types.ManagedObjectReference + + DateTimeInfo types.HostDateTimeInfo `mo:"dateTimeInfo"` +} + +func (m HostDateTimeSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostDateTimeSystem"] = reflect.TypeOf((*HostDateTimeSystem)(nil)).Elem() +} + +type HostDiagnosticSystem struct { + Self types.ManagedObjectReference + + ActivePartition *types.HostDiagnosticPartition `mo:"activePartition"` +} + +func (m HostDiagnosticSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostDiagnosticSystem"] = reflect.TypeOf((*HostDiagnosticSystem)(nil)).Elem() +} + +type HostDirectoryStore struct { + HostAuthenticationStore +} + +func init() { + t["HostDirectoryStore"] = reflect.TypeOf((*HostDirectoryStore)(nil)).Elem() +} + +type HostEsxAgentHostManager struct { + Self types.ManagedObjectReference + + ConfigInfo types.HostEsxAgentHostManagerConfigInfo `mo:"configInfo"` +} + +func (m HostEsxAgentHostManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostEsxAgentHostManager"] = reflect.TypeOf((*HostEsxAgentHostManager)(nil)).Elem() +} + +type HostFirewallSystem struct { + ExtensibleManagedObject + + FirewallInfo *types.HostFirewallInfo `mo:"firewallInfo"` +} + +func init() { + t["HostFirewallSystem"] = reflect.TypeOf((*HostFirewallSystem)(nil)).Elem() +} + +type HostFirmwareSystem struct { + Self types.ManagedObjectReference +} + +func (m HostFirmwareSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostFirmwareSystem"] = reflect.TypeOf((*HostFirmwareSystem)(nil)).Elem() +} + +type HostGraphicsManager struct { + ExtensibleManagedObject + + GraphicsInfo []types.HostGraphicsInfo `mo:"graphicsInfo"` + SharedPassthruGpuTypes []string `mo:"sharedPassthruGpuTypes"` +} + +func init() { + t["HostGraphicsManager"] = reflect.TypeOf((*HostGraphicsManager)(nil)).Elem() +} + +type HostHealthStatusSystem struct { + Self types.ManagedObjectReference + + Runtime types.HealthSystemRuntime `mo:"runtime"` +} + +func (m HostHealthStatusSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostHealthStatusSystem"] = reflect.TypeOf((*HostHealthStatusSystem)(nil)).Elem() +} + +type HostImageConfigManager struct { + Self types.ManagedObjectReference +} + +func (m HostImageConfigManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostImageConfigManager"] = reflect.TypeOf((*HostImageConfigManager)(nil)).Elem() +} + +type HostKernelModuleSystem struct { + Self types.ManagedObjectReference +} + +func (m HostKernelModuleSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostKernelModuleSystem"] = reflect.TypeOf((*HostKernelModuleSystem)(nil)).Elem() +} + +type HostLocalAccountManager struct { + Self types.ManagedObjectReference +} + +func (m HostLocalAccountManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostLocalAccountManager"] = reflect.TypeOf((*HostLocalAccountManager)(nil)).Elem() +} + +type HostLocalAuthentication struct { + HostAuthenticationStore +} + +func init() { + t["HostLocalAuthentication"] = reflect.TypeOf((*HostLocalAuthentication)(nil)).Elem() +} + +type HostMemorySystem struct { + ExtensibleManagedObject + + ConsoleReservationInfo *types.ServiceConsoleReservationInfo `mo:"consoleReservationInfo"` + VirtualMachineReservationInfo *types.VirtualMachineMemoryReservationInfo `mo:"virtualMachineReservationInfo"` +} + +func init() { + t["HostMemorySystem"] = reflect.TypeOf((*HostMemorySystem)(nil)).Elem() +} + +type HostNetworkSystem struct { + ExtensibleManagedObject + + Capabilities *types.HostNetCapabilities `mo:"capabilities"` + NetworkInfo *types.HostNetworkInfo `mo:"networkInfo"` + OffloadCapabilities *types.HostNetOffloadCapabilities `mo:"offloadCapabilities"` + NetworkConfig *types.HostNetworkConfig `mo:"networkConfig"` + DnsConfig types.BaseHostDnsConfig `mo:"dnsConfig"` + IpRouteConfig types.BaseHostIpRouteConfig `mo:"ipRouteConfig"` + ConsoleIpRouteConfig types.BaseHostIpRouteConfig `mo:"consoleIpRouteConfig"` +} + +func init() { + t["HostNetworkSystem"] = reflect.TypeOf((*HostNetworkSystem)(nil)).Elem() +} + +type HostPatchManager struct { + Self types.ManagedObjectReference +} + +func (m HostPatchManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostPatchManager"] = reflect.TypeOf((*HostPatchManager)(nil)).Elem() +} + +type HostPciPassthruSystem struct { + ExtensibleManagedObject + + PciPassthruInfo []types.BaseHostPciPassthruInfo `mo:"pciPassthruInfo"` +} + +func init() { + t["HostPciPassthruSystem"] = reflect.TypeOf((*HostPciPassthruSystem)(nil)).Elem() +} + +type HostPowerSystem struct { + Self types.ManagedObjectReference + + Capability types.PowerSystemCapability `mo:"capability"` + Info types.PowerSystemInfo `mo:"info"` +} + +func (m HostPowerSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostPowerSystem"] = reflect.TypeOf((*HostPowerSystem)(nil)).Elem() +} + +type HostProfile struct { + Profile + + ReferenceHost *types.ManagedObjectReference `mo:"referenceHost"` +} + +func init() { + t["HostProfile"] = reflect.TypeOf((*HostProfile)(nil)).Elem() +} + +type HostProfileManager struct { + ProfileManager +} + +func init() { + t["HostProfileManager"] = reflect.TypeOf((*HostProfileManager)(nil)).Elem() +} + +type HostServiceSystem struct { + ExtensibleManagedObject + + ServiceInfo types.HostServiceInfo `mo:"serviceInfo"` +} + +func init() { + t["HostServiceSystem"] = reflect.TypeOf((*HostServiceSystem)(nil)).Elem() +} + +type HostSnmpSystem struct { + Self types.ManagedObjectReference + + Configuration types.HostSnmpConfigSpec `mo:"configuration"` + Limits types.HostSnmpSystemAgentLimits `mo:"limits"` +} + +func (m HostSnmpSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostSnmpSystem"] = reflect.TypeOf((*HostSnmpSystem)(nil)).Elem() +} + +type HostStorageSystem struct { + ExtensibleManagedObject + + StorageDeviceInfo *types.HostStorageDeviceInfo `mo:"storageDeviceInfo"` + FileSystemVolumeInfo types.HostFileSystemVolumeInfo `mo:"fileSystemVolumeInfo"` + SystemFile []string `mo:"systemFile"` + MultipathStateInfo *types.HostMultipathStateInfo `mo:"multipathStateInfo"` +} + +func init() { + t["HostStorageSystem"] = reflect.TypeOf((*HostStorageSystem)(nil)).Elem() +} + +type HostSystem struct { + ManagedEntity + + Runtime types.HostRuntimeInfo `mo:"runtime"` + Summary types.HostListSummary `mo:"summary"` + Hardware *types.HostHardwareInfo `mo:"hardware"` + Capability *types.HostCapability `mo:"capability"` + LicensableResource types.HostLicensableResourceInfo `mo:"licensableResource"` + ConfigManager types.HostConfigManager `mo:"configManager"` + Config *types.HostConfigInfo `mo:"config"` + Vm []types.ManagedObjectReference `mo:"vm"` + Datastore []types.ManagedObjectReference `mo:"datastore"` + Network []types.ManagedObjectReference `mo:"network"` + DatastoreBrowser types.ManagedObjectReference `mo:"datastoreBrowser"` + SystemResources *types.HostSystemResourceInfo `mo:"systemResources"` +} + +func (m *HostSystem) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["HostSystem"] = reflect.TypeOf((*HostSystem)(nil)).Elem() +} + +type HostVFlashManager struct { + Self types.ManagedObjectReference + + VFlashConfigInfo *types.HostVFlashManagerVFlashConfigInfo `mo:"vFlashConfigInfo"` +} + +func (m HostVFlashManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostVFlashManager"] = reflect.TypeOf((*HostVFlashManager)(nil)).Elem() +} + +type HostVMotionSystem struct { + ExtensibleManagedObject + + NetConfig *types.HostVMotionNetConfig `mo:"netConfig"` + IpConfig *types.HostIpConfig `mo:"ipConfig"` +} + +func init() { + t["HostVMotionSystem"] = reflect.TypeOf((*HostVMotionSystem)(nil)).Elem() +} + +type HostVirtualNicManager struct { + ExtensibleManagedObject + + Info types.HostVirtualNicManagerInfo `mo:"info"` +} + +func init() { + t["HostVirtualNicManager"] = reflect.TypeOf((*HostVirtualNicManager)(nil)).Elem() +} + +type HostVsanInternalSystem struct { + Self types.ManagedObjectReference +} + +func (m HostVsanInternalSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostVsanInternalSystem"] = reflect.TypeOf((*HostVsanInternalSystem)(nil)).Elem() +} + +type HostVsanSystem struct { + Self types.ManagedObjectReference + + Config types.VsanHostConfigInfo `mo:"config"` +} + +func (m HostVsanSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HostVsanSystem"] = reflect.TypeOf((*HostVsanSystem)(nil)).Elem() +} + +type HttpNfcLease struct { + Self types.ManagedObjectReference + + InitializeProgress int32 `mo:"initializeProgress"` + Info *types.HttpNfcLeaseInfo `mo:"info"` + State types.HttpNfcLeaseState `mo:"state"` + Error *types.LocalizedMethodFault `mo:"error"` +} + +func (m HttpNfcLease) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["HttpNfcLease"] = reflect.TypeOf((*HttpNfcLease)(nil)).Elem() +} + +type InventoryView struct { + ManagedObjectView +} + +func init() { + t["InventoryView"] = reflect.TypeOf((*InventoryView)(nil)).Elem() +} + +type IoFilterManager struct { + Self types.ManagedObjectReference +} + +func (m IoFilterManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["IoFilterManager"] = reflect.TypeOf((*IoFilterManager)(nil)).Elem() +} + +type IpPoolManager struct { + Self types.ManagedObjectReference +} + +func (m IpPoolManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["IpPoolManager"] = reflect.TypeOf((*IpPoolManager)(nil)).Elem() +} + +type IscsiManager struct { + Self types.ManagedObjectReference +} + +func (m IscsiManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["IscsiManager"] = reflect.TypeOf((*IscsiManager)(nil)).Elem() +} + +type LicenseAssignmentManager struct { + Self types.ManagedObjectReference +} + +func (m LicenseAssignmentManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["LicenseAssignmentManager"] = reflect.TypeOf((*LicenseAssignmentManager)(nil)).Elem() +} + +type LicenseManager struct { + Self types.ManagedObjectReference + + Source types.BaseLicenseSource `mo:"source"` + SourceAvailable bool `mo:"sourceAvailable"` + Diagnostics *types.LicenseDiagnostics `mo:"diagnostics"` + FeatureInfo []types.LicenseFeatureInfo `mo:"featureInfo"` + LicensedEdition string `mo:"licensedEdition"` + Licenses []types.LicenseManagerLicenseInfo `mo:"licenses"` + LicenseAssignmentManager *types.ManagedObjectReference `mo:"licenseAssignmentManager"` + Evaluation types.LicenseManagerEvaluationInfo `mo:"evaluation"` +} + +func (m LicenseManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["LicenseManager"] = reflect.TypeOf((*LicenseManager)(nil)).Elem() +} + +type ListView struct { + ManagedObjectView +} + +func init() { + t["ListView"] = reflect.TypeOf((*ListView)(nil)).Elem() +} + +type LocalizationManager struct { + Self types.ManagedObjectReference + + Catalog []types.LocalizationManagerMessageCatalog `mo:"catalog"` +} + +func (m LocalizationManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["LocalizationManager"] = reflect.TypeOf((*LocalizationManager)(nil)).Elem() +} + +type ManagedEntity struct { + ExtensibleManagedObject + + Parent *types.ManagedObjectReference `mo:"parent"` + CustomValue []types.BaseCustomFieldValue `mo:"customValue"` + OverallStatus types.ManagedEntityStatus `mo:"overallStatus"` + ConfigStatus types.ManagedEntityStatus `mo:"configStatus"` + ConfigIssue []types.BaseEvent `mo:"configIssue"` + EffectiveRole []int32 `mo:"effectiveRole"` + Permission []types.Permission `mo:"permission"` + Name string `mo:"name"` + DisabledMethod []string `mo:"disabledMethod"` + RecentTask []types.ManagedObjectReference `mo:"recentTask"` + DeclaredAlarmState []types.AlarmState `mo:"declaredAlarmState"` + TriggeredAlarmState []types.AlarmState `mo:"triggeredAlarmState"` + AlarmActionsEnabled *bool `mo:"alarmActionsEnabled"` + Tag []types.Tag `mo:"tag"` +} + +func init() { + t["ManagedEntity"] = reflect.TypeOf((*ManagedEntity)(nil)).Elem() +} + +type ManagedObjectView struct { + Self types.ManagedObjectReference + + View []types.ManagedObjectReference `mo:"view"` +} + +func (m ManagedObjectView) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ManagedObjectView"] = reflect.TypeOf((*ManagedObjectView)(nil)).Elem() +} + +type MessageBusProxy struct { + Self types.ManagedObjectReference +} + +func (m MessageBusProxy) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["MessageBusProxy"] = reflect.TypeOf((*MessageBusProxy)(nil)).Elem() +} + +type Network struct { + ManagedEntity + + Name string `mo:"name"` + Summary types.BaseNetworkSummary `mo:"summary"` + Host []types.ManagedObjectReference `mo:"host"` + Vm []types.ManagedObjectReference `mo:"vm"` +} + +func (m *Network) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["Network"] = reflect.TypeOf((*Network)(nil)).Elem() +} + +type OpaqueNetwork struct { + Network +} + +func init() { + t["OpaqueNetwork"] = reflect.TypeOf((*OpaqueNetwork)(nil)).Elem() +} + +type OptionManager struct { + Self types.ManagedObjectReference + + SupportedOption []types.OptionDef `mo:"supportedOption"` + Setting []types.BaseOptionValue `mo:"setting"` +} + +func (m OptionManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["OptionManager"] = reflect.TypeOf((*OptionManager)(nil)).Elem() +} + +type OverheadMemoryManager struct { + Self types.ManagedObjectReference +} + +func (m OverheadMemoryManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["OverheadMemoryManager"] = reflect.TypeOf((*OverheadMemoryManager)(nil)).Elem() +} + +type OvfManager struct { + Self types.ManagedObjectReference + + OvfImportOption []types.OvfOptionInfo `mo:"ovfImportOption"` + OvfExportOption []types.OvfOptionInfo `mo:"ovfExportOption"` +} + +func (m OvfManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["OvfManager"] = reflect.TypeOf((*OvfManager)(nil)).Elem() +} + +type PerformanceManager struct { + Self types.ManagedObjectReference + + Description types.PerformanceDescription `mo:"description"` + HistoricalInterval []types.PerfInterval `mo:"historicalInterval"` + PerfCounter []types.PerfCounterInfo `mo:"perfCounter"` +} + +func (m PerformanceManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["PerformanceManager"] = reflect.TypeOf((*PerformanceManager)(nil)).Elem() +} + +type Profile struct { + Self types.ManagedObjectReference + + Config types.BaseProfileConfigInfo `mo:"config"` + Description *types.ProfileDescription `mo:"description"` + Name string `mo:"name"` + CreatedTime time.Time `mo:"createdTime"` + ModifiedTime time.Time `mo:"modifiedTime"` + Entity []types.ManagedObjectReference `mo:"entity"` + ComplianceStatus string `mo:"complianceStatus"` +} + +func (m Profile) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["Profile"] = reflect.TypeOf((*Profile)(nil)).Elem() +} + +type ProfileComplianceManager struct { + Self types.ManagedObjectReference +} + +func (m ProfileComplianceManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ProfileComplianceManager"] = reflect.TypeOf((*ProfileComplianceManager)(nil)).Elem() +} + +type ProfileManager struct { + Self types.ManagedObjectReference + + Profile []types.ManagedObjectReference `mo:"profile"` +} + +func (m ProfileManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ProfileManager"] = reflect.TypeOf((*ProfileManager)(nil)).Elem() +} + +type PropertyCollector struct { + Self types.ManagedObjectReference + + Filter []types.ManagedObjectReference `mo:"filter"` +} + +func (m PropertyCollector) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["PropertyCollector"] = reflect.TypeOf((*PropertyCollector)(nil)).Elem() +} + +type PropertyFilter struct { + Self types.ManagedObjectReference + + Spec types.PropertyFilterSpec `mo:"spec"` + PartialUpdates bool `mo:"partialUpdates"` +} + +func (m PropertyFilter) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["PropertyFilter"] = reflect.TypeOf((*PropertyFilter)(nil)).Elem() +} + +type ResourcePlanningManager struct { + Self types.ManagedObjectReference +} + +func (m ResourcePlanningManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ResourcePlanningManager"] = reflect.TypeOf((*ResourcePlanningManager)(nil)).Elem() +} + +type ResourcePool struct { + ManagedEntity + + Summary types.BaseResourcePoolSummary `mo:"summary"` + Runtime types.ResourcePoolRuntimeInfo `mo:"runtime"` + Owner types.ManagedObjectReference `mo:"owner"` + ResourcePool []types.ManagedObjectReference `mo:"resourcePool"` + Vm []types.ManagedObjectReference `mo:"vm"` + Config types.ResourceConfigSpec `mo:"config"` + ChildConfiguration []types.ResourceConfigSpec `mo:"childConfiguration"` +} + +func (m *ResourcePool) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["ResourcePool"] = reflect.TypeOf((*ResourcePool)(nil)).Elem() +} + +type ScheduledTask struct { + ExtensibleManagedObject + + Info types.ScheduledTaskInfo `mo:"info"` +} + +func init() { + t["ScheduledTask"] = reflect.TypeOf((*ScheduledTask)(nil)).Elem() +} + +type ScheduledTaskManager struct { + Self types.ManagedObjectReference + + ScheduledTask []types.ManagedObjectReference `mo:"scheduledTask"` + Description types.ScheduledTaskDescription `mo:"description"` +} + +func (m ScheduledTaskManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ScheduledTaskManager"] = reflect.TypeOf((*ScheduledTaskManager)(nil)).Elem() +} + +type SearchIndex struct { + Self types.ManagedObjectReference +} + +func (m SearchIndex) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["SearchIndex"] = reflect.TypeOf((*SearchIndex)(nil)).Elem() +} + +type ServiceInstance struct { + Self types.ManagedObjectReference + + ServerClock time.Time `mo:"serverClock"` + Capability types.Capability `mo:"capability"` + Content types.ServiceContent `mo:"content"` +} + +func (m ServiceInstance) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ServiceInstance"] = reflect.TypeOf((*ServiceInstance)(nil)).Elem() +} + +type ServiceManager struct { + Self types.ManagedObjectReference + + Service []types.ServiceManagerServiceInfo `mo:"service"` +} + +func (m ServiceManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ServiceManager"] = reflect.TypeOf((*ServiceManager)(nil)).Elem() +} + +type SessionManager struct { + Self types.ManagedObjectReference + + SessionList []types.UserSession `mo:"sessionList"` + CurrentSession *types.UserSession `mo:"currentSession"` + Message *string `mo:"message"` + MessageLocaleList []string `mo:"messageLocaleList"` + SupportedLocaleList []string `mo:"supportedLocaleList"` + DefaultLocale string `mo:"defaultLocale"` +} + +func (m SessionManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["SessionManager"] = reflect.TypeOf((*SessionManager)(nil)).Elem() +} + +type SimpleCommand struct { + Self types.ManagedObjectReference + + EncodingType types.SimpleCommandEncoding `mo:"encodingType"` + Entity types.ServiceManagerServiceInfo `mo:"entity"` +} + +func (m SimpleCommand) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["SimpleCommand"] = reflect.TypeOf((*SimpleCommand)(nil)).Elem() +} + +type StoragePod struct { + Folder + + Summary *types.StoragePodSummary `mo:"summary"` + PodStorageDrsEntry *types.PodStorageDrsEntry `mo:"podStorageDrsEntry"` +} + +func init() { + t["StoragePod"] = reflect.TypeOf((*StoragePod)(nil)).Elem() +} + +type StorageResourceManager struct { + Self types.ManagedObjectReference +} + +func (m StorageResourceManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["StorageResourceManager"] = reflect.TypeOf((*StorageResourceManager)(nil)).Elem() +} + +type Task struct { + ExtensibleManagedObject + + Info types.TaskInfo `mo:"info"` +} + +func init() { + t["Task"] = reflect.TypeOf((*Task)(nil)).Elem() +} + +type TaskHistoryCollector struct { + HistoryCollector + + LatestPage []types.TaskInfo `mo:"latestPage"` +} + +func init() { + t["TaskHistoryCollector"] = reflect.TypeOf((*TaskHistoryCollector)(nil)).Elem() +} + +type TaskManager struct { + Self types.ManagedObjectReference + + RecentTask []types.ManagedObjectReference `mo:"recentTask"` + Description types.TaskDescription `mo:"description"` + MaxCollector int32 `mo:"maxCollector"` +} + +func (m TaskManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["TaskManager"] = reflect.TypeOf((*TaskManager)(nil)).Elem() +} + +type UserDirectory struct { + Self types.ManagedObjectReference + + DomainList []string `mo:"domainList"` +} + +func (m UserDirectory) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["UserDirectory"] = reflect.TypeOf((*UserDirectory)(nil)).Elem() +} + +type VRPResourceManager struct { + Self types.ManagedObjectReference +} + +func (m VRPResourceManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["VRPResourceManager"] = reflect.TypeOf((*VRPResourceManager)(nil)).Elem() +} + +type View struct { + Self types.ManagedObjectReference +} + +func (m View) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["View"] = reflect.TypeOf((*View)(nil)).Elem() +} + +type ViewManager struct { + Self types.ManagedObjectReference + + ViewList []types.ManagedObjectReference `mo:"viewList"` +} + +func (m ViewManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["ViewManager"] = reflect.TypeOf((*ViewManager)(nil)).Elem() +} + +type VirtualApp struct { + ResourcePool + + ParentFolder *types.ManagedObjectReference `mo:"parentFolder"` + Datastore []types.ManagedObjectReference `mo:"datastore"` + Network []types.ManagedObjectReference `mo:"network"` + VAppConfig *types.VAppConfigInfo `mo:"vAppConfig"` + ParentVApp *types.ManagedObjectReference `mo:"parentVApp"` + ChildLink []types.VirtualAppLinkInfo `mo:"childLink"` +} + +func init() { + t["VirtualApp"] = reflect.TypeOf((*VirtualApp)(nil)).Elem() +} + +type VirtualDiskManager struct { + Self types.ManagedObjectReference +} + +func (m VirtualDiskManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["VirtualDiskManager"] = reflect.TypeOf((*VirtualDiskManager)(nil)).Elem() +} + +type VirtualMachine struct { + ManagedEntity + + Capability types.VirtualMachineCapability `mo:"capability"` + Config *types.VirtualMachineConfigInfo `mo:"config"` + Layout *types.VirtualMachineFileLayout `mo:"layout"` + LayoutEx *types.VirtualMachineFileLayoutEx `mo:"layoutEx"` + Storage *types.VirtualMachineStorageInfo `mo:"storage"` + EnvironmentBrowser types.ManagedObjectReference `mo:"environmentBrowser"` + ResourcePool *types.ManagedObjectReference `mo:"resourcePool"` + ParentVApp *types.ManagedObjectReference `mo:"parentVApp"` + ResourceConfig *types.ResourceConfigSpec `mo:"resourceConfig"` + Runtime types.VirtualMachineRuntimeInfo `mo:"runtime"` + Guest *types.GuestInfo `mo:"guest"` + Summary types.VirtualMachineSummary `mo:"summary"` + Datastore []types.ManagedObjectReference `mo:"datastore"` + Network []types.ManagedObjectReference `mo:"network"` + Snapshot *types.VirtualMachineSnapshotInfo `mo:"snapshot"` + RootSnapshot []types.ManagedObjectReference `mo:"rootSnapshot"` + GuestHeartbeatStatus types.ManagedEntityStatus `mo:"guestHeartbeatStatus"` +} + +func (m *VirtualMachine) Entity() *ManagedEntity { + return &m.ManagedEntity +} + +func init() { + t["VirtualMachine"] = reflect.TypeOf((*VirtualMachine)(nil)).Elem() +} + +type VirtualMachineCompatibilityChecker struct { + Self types.ManagedObjectReference +} + +func (m VirtualMachineCompatibilityChecker) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["VirtualMachineCompatibilityChecker"] = reflect.TypeOf((*VirtualMachineCompatibilityChecker)(nil)).Elem() +} + +type VirtualMachineProvisioningChecker struct { + Self types.ManagedObjectReference +} + +func (m VirtualMachineProvisioningChecker) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["VirtualMachineProvisioningChecker"] = reflect.TypeOf((*VirtualMachineProvisioningChecker)(nil)).Elem() +} + +type VirtualMachineSnapshot struct { + ExtensibleManagedObject + + Config types.VirtualMachineConfigInfo `mo:"config"` + ChildSnapshot []types.ManagedObjectReference `mo:"childSnapshot"` + Vm types.ManagedObjectReference `mo:"vm"` +} + +func init() { + t["VirtualMachineSnapshot"] = reflect.TypeOf((*VirtualMachineSnapshot)(nil)).Elem() +} + +type VirtualizationManager struct { + Self types.ManagedObjectReference +} + +func (m VirtualizationManager) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["VirtualizationManager"] = reflect.TypeOf((*VirtualizationManager)(nil)).Elem() +} + +type VmwareDistributedVirtualSwitch struct { + DistributedVirtualSwitch +} + +func init() { + t["VmwareDistributedVirtualSwitch"] = reflect.TypeOf((*VmwareDistributedVirtualSwitch)(nil)).Elem() +} + +type VsanUpgradeSystem struct { + Self types.ManagedObjectReference +} + +func (m VsanUpgradeSystem) Reference() types.ManagedObjectReference { + return m.Self +} + +func init() { + t["VsanUpgradeSystem"] = reflect.TypeOf((*VsanUpgradeSystem)(nil)).Elem() +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/reference.go b/vendor/github.com/vmware/govmomi/vim25/mo/reference.go new file mode 100644 index 0000000000..465edbe807 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/reference.go @@ -0,0 +1,26 @@ +/* +Copyright (c) 2015 VMware, 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 mo + +import "github.com/vmware/govmomi/vim25/types" + +// Reference is the interface that is implemented by all the managed objects +// defined in this package. It specifies that these managed objects have a +// function that returns the managed object reference to themselves. +type Reference interface { + Reference() types.ManagedObjectReference +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/registry.go b/vendor/github.com/vmware/govmomi/vim25/mo/registry.go new file mode 100644 index 0000000000..deacf508bb --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/registry.go @@ -0,0 +1,21 @@ +/* +Copyright (c) 2014 VMware, 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 mo + +import "reflect" + +var t = map[string]reflect.Type{} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go b/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go new file mode 100644 index 0000000000..32fc374b49 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go @@ -0,0 +1,174 @@ +/* +Copyright (c) 2014-2015 VMware, 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 mo + +import ( + "reflect" + + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +func ignoreMissingProperty(ref types.ManagedObjectReference, p types.MissingProperty) bool { + switch ref.Type { + case "VirtualMachine": + switch p.Path { + case "environmentBrowser": + // See https://github.com/vmware/govmomi/pull/242 + return true + case "alarmActionsEnabled": + // Seen with vApp child VM + return true + } + } + + return false +} + +// ObjectContentToType loads an ObjectContent value into the value it +// represents. If the ObjectContent value has a non-empty 'MissingSet' field, +// it returns the first fault it finds there as error. If the 'MissingSet' +// field is empty, it returns a pointer to a reflect.Value. It handles contain +// nested properties, such as 'guest.ipAddress' or 'config.hardware'. +func ObjectContentToType(o types.ObjectContent) (interface{}, error) { + // Expect no properties in the missing set + for _, p := range o.MissingSet { + if ignoreMissingProperty(o.Obj, p) { + continue + } + + return nil, soap.WrapVimFault(p.Fault.Fault) + } + + ti := typeInfoForType(o.Obj.Type) + v, err := ti.LoadFromObjectContent(o) + if err != nil { + return nil, err + } + + return v.Elem().Interface(), nil +} + +// LoadRetrievePropertiesResponse converts the response of a call to +// RetrieveProperties to one or more managed objects. +func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst interface{}) error { + rt := reflect.TypeOf(dst) + if rt == nil || rt.Kind() != reflect.Ptr { + panic("need pointer") + } + + rv := reflect.ValueOf(dst).Elem() + if !rv.CanSet() { + panic("cannot set dst") + } + + isSlice := false + switch rt.Elem().Kind() { + case reflect.Struct: + case reflect.Slice: + isSlice = true + default: + panic("unexpected type") + } + + if isSlice { + for _, p := range res.Returnval { + v, err := ObjectContentToType(p) + if err != nil { + return err + } + + vt := reflect.TypeOf(v) + + if !rv.Type().AssignableTo(vt) { + // For example: dst is []ManagedEntity, res is []HostSystem + if field, ok := vt.FieldByName(rt.Elem().Elem().Name()); ok && field.Anonymous { + rv.Set(reflect.Append(rv, reflect.ValueOf(v).FieldByIndex(field.Index))) + continue + } + } + + rv.Set(reflect.Append(rv, reflect.ValueOf(v))) + } + } else { + switch len(res.Returnval) { + case 0: + case 1: + v, err := ObjectContentToType(res.Returnval[0]) + if err != nil { + return err + } + + vt := reflect.TypeOf(v) + + if !rv.Type().AssignableTo(vt) { + // For example: dst is ComputeResource, res is ClusterComputeResource + if field, ok := vt.FieldByName(rt.Elem().Name()); ok && field.Anonymous { + rv.Set(reflect.ValueOf(v).FieldByIndex(field.Index)) + return nil + } + } + + rv.Set(reflect.ValueOf(v)) + default: + // If dst is not a slice, expect to receive 0 or 1 results + panic("more than 1 result") + } + } + + return nil +} + +// RetrievePropertiesForRequest calls the RetrieveProperties method with the +// specified request and decodes the response struct into the value pointed to +// by dst. +func RetrievePropertiesForRequest(ctx context.Context, r soap.RoundTripper, req types.RetrieveProperties, dst interface{}) error { + res, err := methods.RetrieveProperties(ctx, r, &req) + if err != nil { + return err + } + + return LoadRetrievePropertiesResponse(res, dst) +} + +// RetrieveProperties retrieves the properties of the managed object specified +// as obj and decodes the response struct into the value pointed to by dst. +func RetrieveProperties(ctx context.Context, r soap.RoundTripper, pc, obj types.ManagedObjectReference, dst interface{}) error { + req := types.RetrieveProperties{ + This: pc, + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ + { + Obj: obj, + Skip: types.NewBool(false), + }, + }, + PropSet: []types.PropertySpec{ + { + All: types.NewBool(true), + Type: obj.Type, + }, + }, + }, + }, + } + + return RetrievePropertiesForRequest(ctx, r, req, dst) +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go b/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go new file mode 100644 index 0000000000..0c9e5b0348 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go @@ -0,0 +1,247 @@ +/* +Copyright (c) 2014 VMware, 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 mo + +import ( + "fmt" + "reflect" + "regexp" + "strings" + "sync" + + "github.com/vmware/govmomi/vim25/types" +) + +type typeInfo struct { + typ reflect.Type + + // Field indices of "Self" field. + self []int + + // Map property names to field indices. + props map[string][]int +} + +var typeInfoLock sync.RWMutex +var typeInfoMap = make(map[string]*typeInfo) + +func typeInfoForType(tname string) *typeInfo { + typeInfoLock.RLock() + ti, ok := typeInfoMap[tname] + typeInfoLock.RUnlock() + + if ok { + return ti + } + + // Create new typeInfo for type. + if typ, ok := t[tname]; !ok { + panic("unknown type: " + tname) + } else { + // Multiple routines may race to set it, but the result is the same. + typeInfoLock.Lock() + ti = newTypeInfo(typ) + typeInfoMap[tname] = ti + typeInfoLock.Unlock() + } + + return ti +} + +func newTypeInfo(typ reflect.Type) *typeInfo { + t := typeInfo{ + typ: typ, + props: make(map[string][]int), + } + + t.build(typ, "", []int{}) + + return &t +} + +var managedObjectRefType = reflect.TypeOf((*types.ManagedObjectReference)(nil)).Elem() + +func buildName(fn string, f reflect.StructField) string { + if fn != "" { + fn += "." + } + + motag := f.Tag.Get("mo") + if motag != "" { + return fn + motag + } + + xmltag := f.Tag.Get("xml") + if xmltag != "" { + tokens := strings.Split(xmltag, ",") + if tokens[0] != "" { + return fn + tokens[0] + } + } + + return "" +} + +func (t *typeInfo) build(typ reflect.Type, fn string, fi []int) { + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + + if typ.Kind() != reflect.Struct { + panic("need struct") + } + + for i := 0; i < typ.NumField(); i++ { + f := typ.Field(i) + ftyp := f.Type + + // Copy field indices so they can be passed along. + fic := make([]int, len(fi)+1) + copy(fic, fi) + fic[len(fi)] = i + + // Recurse into embedded field. + if f.Anonymous { + t.build(ftyp, fn, fic) + continue + } + + // Top level type has a "Self" field. + if f.Name == "Self" && ftyp == managedObjectRefType { + t.self = fic + continue + } + + fnc := buildName(fn, f) + if fnc == "" { + continue + } + + t.props[fnc] = fic + + // Dereference pointer. + if ftyp.Kind() == reflect.Ptr { + ftyp = ftyp.Elem() + } + + // Slices are not addressable by `foo.bar.qux`. + if ftyp.Kind() == reflect.Slice { + continue + } + + // Skip the managed reference type. + if ftyp == managedObjectRefType { + continue + } + + // Recurse into structs. + if ftyp.Kind() == reflect.Struct { + t.build(ftyp, fnc, fic) + } + } +} + +// assignValue assignes a value 'pv' to the struct pointed to by 'val', given a +// slice of field indices. It recurses into the struct until it finds the field +// specified by the indices. It creates new values for pointer types where +// needed. +func assignValue(val reflect.Value, fi []int, pv reflect.Value) { + // Create new value if necessary. + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + + val = val.Elem() + } + + rv := val.Field(fi[0]) + fi = fi[1:] + if len(fi) == 0 { + rt := rv.Type() + pt := pv.Type() + + // If type is a pointer, create new instance of type. + if rt.Kind() == reflect.Ptr { + rv.Set(reflect.New(rt.Elem())) + rv = rv.Elem() + rt = rv.Type() + } + + // If type is an interface, check if pv implements it. + if rt.Kind() == reflect.Interface && !pt.Implements(rt) { + // Check if pointer to pv implements it. + if reflect.PtrTo(pt).Implements(rt) { + npv := reflect.New(pt) + npv.Elem().Set(pv) + pv = npv + pt = pv.Type() + } else { + panic(fmt.Sprintf("type %s doesn't implement %s", pt.Name(), rt.Name())) + } + } + + if pt.AssignableTo(rt) { + rv.Set(pv) + } else if rt.ConvertibleTo(pt) { + rv.Set(pv.Convert(rt)) + } else { + panic(fmt.Sprintf("cannot assign %s (%s) to %s (%s)", rt.Name(), rt.Kind(), pt.Name(), pt.Kind())) + } + + return + } + + assignValue(rv, fi, pv) +} + +var arrayOfRegexp = regexp.MustCompile("ArrayOf(.*)$") + +func anyTypeToValue(t interface{}) reflect.Value { + rt := reflect.TypeOf(t) + rv := reflect.ValueOf(t) + + // Dereference if ArrayOfXYZ type + m := arrayOfRegexp.FindStringSubmatch(rt.Name()) + if len(m) > 0 { + // ArrayOfXYZ type has single field named XYZ + rv = rv.FieldByName(m[1]) + if !rv.IsValid() { + panic(fmt.Sprintf("expected %s type to have field %s", m[0], m[1])) + } + } + + return rv +} + +// LoadObjectFromContent loads properties from the 'PropSet' field in the +// specified ObjectContent value into the value it represents, which is +// returned as a reflect.Value. +func (t *typeInfo) LoadFromObjectContent(o types.ObjectContent) (reflect.Value, error) { + v := reflect.New(t.typ) + assignValue(v, t.self, reflect.ValueOf(o.Obj)) + + for _, p := range o.PropSet { + rv, ok := t.props[p.Name] + if !ok { + continue + } + assignValue(v, rv, anyTypeToValue(p.Val)) + } + + return v, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/aggregator.go b/vendor/github.com/vmware/govmomi/vim25/progress/aggregator.go new file mode 100644 index 0000000000..24cb3d59a9 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/aggregator.go @@ -0,0 +1,73 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +import "sync" + +type Aggregator struct { + downstream Sinker + upstream chan (<-chan Report) + + done chan struct{} + w sync.WaitGroup +} + +func NewAggregator(s Sinker) *Aggregator { + a := &Aggregator{ + downstream: s, + upstream: make(chan (<-chan Report)), + + done: make(chan struct{}), + } + + a.w.Add(1) + go a.loop() + + return a +} + +func (a *Aggregator) loop() { + defer a.w.Done() + + dch := a.downstream.Sink() + defer close(dch) + + for { + select { + case uch := <-a.upstream: + // Drain upstream channel + for e := range uch { + dch <- e + } + case <-a.done: + return + } + } +} + +func (a *Aggregator) Sink() chan<- Report { + ch := make(chan Report) + a.upstream <- ch + return ch +} + +// Done marks the aggregator as done. No more calls to Sink() may be made and +// the downstream progress report channel will be closed when Done() returns. +func (a *Aggregator) Done() { + close(a.done) + a.w.Wait() +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/doc.go b/vendor/github.com/vmware/govmomi/vim25/progress/doc.go new file mode 100644 index 0000000000..a0458dd5cc --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/doc.go @@ -0,0 +1,32 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +/* +The progress package contains functionality to deal with progress reporting. +The functionality is built to serve progress reporting for infrastructure +operations when talking the vSphere API, but is generic enough to be used +elsewhere. + +At the core of this progress reporting API lies the Sinker interface. This +interface is implemented by any object that can act as a sink for progress +reports. Callers of the Sink() function receives a send-only channel for +progress reports. They are responsible for closing the channel when done. +This semantic makes it easy to keep track of multiple progress report channels; +they are only created when Sink() is called and assumed closed when any +function that receives a Sinker parameter returns. +*/ diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/prefix.go b/vendor/github.com/vmware/govmomi/vim25/progress/prefix.go new file mode 100644 index 0000000000..4f842ad951 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/prefix.go @@ -0,0 +1,54 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +import "fmt" + +type prefixedReport struct { + Report + prefix string +} + +func (r prefixedReport) Detail() string { + if d := r.Report.Detail(); d != "" { + return fmt.Sprintf("%s: %s", r.prefix, d) + } + + return r.prefix +} + +func prefixLoop(upstream <-chan Report, downstream chan<- Report, prefix string) { + defer close(downstream) + + for r := range upstream { + downstream <- prefixedReport{ + Report: r, + prefix: prefix, + } + } +} + +func Prefix(s Sinker, prefix string) Sinker { + fn := func() chan<- Report { + upstream := make(chan Report) + downstream := s.Sink() + go prefixLoop(upstream, downstream, prefix) + return upstream + } + + return SinkFunc(fn) +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/reader.go b/vendor/github.com/vmware/govmomi/vim25/progress/reader.go new file mode 100644 index 0000000000..a981cb4e15 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/reader.go @@ -0,0 +1,177 @@ +/* +Copyright (c) 2014-2015 VMware, 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 progress + +import ( + "container/list" + "fmt" + "io" + "sync/atomic" + "time" +) + +type readerReport struct { + t time.Time + + pos int64 + size int64 + bps *uint64 + + err error +} + +func (r readerReport) Percentage() float32 { + return 100.0 * float32(r.pos) / float32(r.size) +} + +func (r readerReport) Detail() string { + const ( + KiB = 1024 + MiB = 1024 * KiB + GiB = 1024 * MiB + ) + + // Use the reader's bps field, so this report returns an up-to-date number. + // + // For example: if there hasn't been progress for the last 5 seconds, the + // most recent report should return "0B/s". + // + bps := atomic.LoadUint64(r.bps) + + switch { + case bps >= GiB: + return fmt.Sprintf("%.1fGiB/s", float32(bps)/float32(GiB)) + case bps >= MiB: + return fmt.Sprintf("%.1fMiB/s", float32(bps)/float32(MiB)) + case bps >= KiB: + return fmt.Sprintf("%.1fKiB/s", float32(bps)/float32(KiB)) + default: + return fmt.Sprintf("%dB/s", bps) + } +} + +func (p readerReport) Error() error { + return p.err +} + +// reader wraps an io.Reader and sends a progress report over a channel for +// every read it handles. +type reader struct { + r io.Reader + + pos int64 + size int64 + + bps uint64 + + ch chan<- Report +} + +func NewReader(s Sinker, r io.Reader, size int64) *reader { + pr := reader{ + r: r, + + size: size, + } + + // Reports must be sent downstream and to the bps computation loop. + pr.ch = Tee(s, newBpsLoop(&pr.bps)).Sink() + + return &pr +} + +// Read calls the Read function on the underlying io.Reader. Additionally, +// every read causes a progress report to be sent to the progress reader's +// underlying channel. +func (r *reader) Read(b []byte) (int, error) { + n, err := r.r.Read(b) + if err != nil { + return n, err + } + + r.pos += int64(n) + q := readerReport{ + t: time.Now(), + pos: r.pos, + size: r.size, + bps: &r.bps, + } + + r.ch <- q + + return n, err +} + +// Done marks the progress reader as done, optionally including an error in the +// progress report. After sending it, the underlying channel is closed. +func (r *reader) Done(err error) { + q := readerReport{ + t: time.Now(), + pos: r.pos, + size: r.size, + bps: &r.bps, + err: err, + } + + r.ch <- q + close(r.ch) +} + +// newBpsLoop returns a sink that monitors and stores throughput. +func newBpsLoop(dst *uint64) SinkFunc { + fn := func() chan<- Report { + sink := make(chan Report) + go bpsLoop(sink, dst) + return sink + } + + return fn +} + +func bpsLoop(ch <-chan Report, dst *uint64) { + l := list.New() + + for { + var tch <-chan time.Time + + // Setup timer for front of list to become stale. + if e := l.Front(); e != nil { + dt := time.Second - time.Now().Sub(e.Value.(readerReport).t) + tch = time.After(dt) + } + + select { + case q, ok := <-ch: + if !ok { + return + } + + l.PushBack(q) + case <-tch: + l.Remove(l.Front()) + } + + // Compute new bps + if l.Len() == 0 { + atomic.StoreUint64(dst, 0) + } else { + f := l.Front().Value.(readerReport) + b := l.Back().Value.(readerReport) + atomic.StoreUint64(dst, uint64(b.pos-f.pos)) + } + } +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/report.go b/vendor/github.com/vmware/govmomi/vim25/progress/report.go new file mode 100644 index 0000000000..bf80263ff5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/report.go @@ -0,0 +1,26 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +// Report defines the interface for types that can deliver progress reports. +// Examples include uploads/downloads in the http client and the task info +// field in the task managed object. +type Report interface { + Percentage() float32 + Detail() string + Error() error +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/scale.go b/vendor/github.com/vmware/govmomi/vim25/progress/scale.go new file mode 100644 index 0000000000..9880839206 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/scale.go @@ -0,0 +1,76 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +type scaledReport struct { + Report + n int + i int +} + +func (r scaledReport) Percentage() float32 { + b := 100 * float32(r.i) / float32(r.n) + return b + (r.Report.Percentage() / float32(r.n)) +} + +type scaleOne struct { + s Sinker + n int + i int +} + +func (s scaleOne) Sink() chan<- Report { + upstream := make(chan Report) + downstream := s.s.Sink() + go s.loop(upstream, downstream) + return upstream +} + +func (s scaleOne) loop(upstream <-chan Report, downstream chan<- Report) { + defer close(downstream) + + for r := range upstream { + downstream <- scaledReport{ + Report: r, + n: s.n, + i: s.i, + } + } +} + +type scaleMany struct { + s Sinker + n int + i int +} + +func Scale(s Sinker, n int) Sinker { + return &scaleMany{ + s: s, + n: n, + } +} + +func (s *scaleMany) Sink() chan<- Report { + if s.i == s.n { + s.n++ + } + + ch := scaleOne{s: s.s, n: s.n, i: s.i}.Sink() + s.i++ + return ch +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/sinker.go b/vendor/github.com/vmware/govmomi/vim25/progress/sinker.go new file mode 100644 index 0000000000..0bd35a47f7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/sinker.go @@ -0,0 +1,33 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +// Sinker defines what is expected of a type that can act as a sink for +// progress reports. The semantics are as follows. If you call Sink(), you are +// responsible for closing the returned channel. Closing this channel means +// that the related task is done, or resulted in error. +type Sinker interface { + Sink() chan<- Report +} + +// SinkFunc defines a function that returns a progress report channel. +type SinkFunc func() chan<- Report + +// Sink makes the SinkFunc implement the Sinker interface. +func (fn SinkFunc) Sink() chan<- Report { + return fn() +} diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/tee.go b/vendor/github.com/vmware/govmomi/vim25/progress/tee.go new file mode 100644 index 0000000000..ab4607842b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/progress/tee.go @@ -0,0 +1,41 @@ +/* +Copyright (c) 2014 VMware, 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 progress + +// Tee works like Unix tee; it forwards all progress reports it receives to the +// specified sinks +func Tee(s1, s2 Sinker) Sinker { + fn := func() chan<- Report { + d1 := s1.Sink() + d2 := s2.Sink() + u := make(chan Report) + go tee(u, d1, d2) + return u + } + + return SinkFunc(fn) +} + +func tee(u <-chan Report, d1, d2 chan<- Report) { + defer close(d1) + defer close(d2) + + for r := range u { + d1 <- r + d2 <- r + } +} diff --git a/vendor/github.com/vmware/govmomi/vim25/retry.go b/vendor/github.com/vmware/govmomi/vim25/retry.go new file mode 100644 index 0000000000..b5868e1792 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/retry.go @@ -0,0 +1,105 @@ +/* +Copyright (c) 2015 VMware, 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 vim25 + +import ( + "net" + "net/url" + "time" + + "github.com/vmware/govmomi/vim25/soap" + "golang.org/x/net/context" +) + +type RetryFunc func(err error) (retry bool, delay time.Duration) + +// TemporaryNetworkError returns a RetryFunc that retries up to a maximum of n +// times, only if the error returned by the RoundTrip function is a temporary +// network error (for example: a connect timeout). +func TemporaryNetworkError(n int) RetryFunc { + return func(err error) (retry bool, delay time.Duration) { + var nerr net.Error + var ok bool + + // Never retry if this is not a network error. + switch rerr := err.(type) { + case *url.Error: + if nerr, ok = rerr.Err.(net.Error); !ok { + return false, 0 + } + case net.Error: + nerr = rerr + default: + return false, 0 + } + + if !nerr.Temporary() { + return false, 0 + } + + // Don't retry if we're out of tries. + if n--; n <= 0 { + return false, 0 + } + + return true, 0 + } +} + +type retry struct { + roundTripper soap.RoundTripper + + // fn is a custom function that is called when an error occurs. + // It returns whether or not to retry, and if so, how long to + // delay before retrying. + fn RetryFunc +} + +// Retry wraps the specified soap.RoundTripper and invokes the +// specified RetryFunc. The RetryFunc returns whether or not to +// retry the call, and if so, how long to wait before retrying. If +// the result of this function is to not retry, the original error +// is returned from the RoundTrip function. +func Retry(roundTripper soap.RoundTripper, fn RetryFunc) soap.RoundTripper { + r := &retry{ + roundTripper: roundTripper, + fn: fn, + } + + return r +} + +func (r *retry) RoundTrip(ctx context.Context, req, res soap.HasFault) error { + var err error + + for { + err = r.roundTripper.RoundTrip(ctx, req, res) + if err == nil { + break + } + + // Invoke retry function to see if another attempt should be made. + if retry, delay := r.fn(err); retry { + time.Sleep(delay) + continue + } + + break + } + + return err +} diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/client.go b/vendor/github.com/vmware/govmomi/vim25/soap/client.go new file mode 100644 index 0000000000..4f65afb63f --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/soap/client.go @@ -0,0 +1,507 @@ +/* +Copyright (c) 2014-2015 VMware, 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 soap + +import ( + "bytes" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "net/http" + "net/http/cookiejar" + "net/url" + "os" + "regexp" + "strings" + "time" + + "github.com/vmware/govmomi/vim25/progress" + "github.com/vmware/govmomi/vim25/types" + "github.com/vmware/govmomi/vim25/xml" + "golang.org/x/net/context" +) + +type HasFault interface { + Fault() *Fault +} + +type RoundTripper interface { + RoundTrip(ctx context.Context, req, res HasFault) error +} + +var DefaultVimNamespace = "urn:vim25" +var DefaultVimVersion = "6.0" + +type Client struct { + http.Client + + u *url.URL + k bool // Named after curl's -k flag + d *debugContainer + t *http.Transport + p *url.URL + + Namespace string // Vim namespace + Version string // Vim version +} + +var schemeMatch = regexp.MustCompile(`^\w+://`) + +// ParseURL is wrapper around url.Parse, where Scheme defaults to "https" and Path defaults to "/sdk" +func ParseURL(s string) (*url.URL, error) { + var err error + var u *url.URL + + if s != "" { + // Default the scheme to https + if !schemeMatch.MatchString(s) { + s = "https://" + s + } + + u, err = url.Parse(s) + if err != nil { + return nil, err + } + + // Default the path to /sdk + if u.Path == "" { + u.Path = "/sdk" + } + + if u.User == nil { + u.User = url.UserPassword("", "") + } + } + + return u, nil +} + +func NewClient(u *url.URL, insecure bool) *Client { + c := Client{ + u: u, + k: insecure, + d: newDebug(), + } + + // Initialize http.RoundTripper on client, so we can customize it below + c.t = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + } + + if c.u.Scheme == "https" { + c.t.TLSClientConfig = &tls.Config{InsecureSkipVerify: c.k} + c.t.TLSHandshakeTimeout = 10 * time.Second + } + + c.Client.Transport = c.t + c.Client.Jar, _ = cookiejar.New(nil) + + // Remove user information from a copy of the URL + c.u = c.URL() + c.u.User = nil + + c.Namespace = DefaultVimNamespace + c.Version = DefaultVimVersion + + return &c +} + +// splitHostPort is similar to net.SplitHostPort, +// but rather than return error if there isn't a ':port', +// return an empty string for the port. +func splitHostPort(host string) (string, string) { + ix := strings.LastIndex(host, ":") + + if ix <= strings.LastIndex(host, "]") { + return host, "" + } + + name := host[:ix] + port := host[ix+1:] + + return name, port +} + +const sdkTunnel = "sdkTunnel:8089" + +func (c *Client) SetCertificate(cert tls.Certificate) { + t := c.Client.Transport.(*http.Transport) + + // Extension certificate + t.TLSClientConfig.Certificates = []tls.Certificate{cert} + + // Proxy to vCenter host on port 80 + host, _ := splitHostPort(c.u.Host) + + // Should be no reason to change the default port other than testing + port := os.Getenv("GOVC_TUNNEL_PROXY_PORT") + if port != "" { + host += ":" + port + } + + c.p = &url.URL{ + Scheme: "http", + Host: host, + } + t.Proxy = func(r *http.Request) (*url.URL, error) { + // Only sdk requests should be proxied + if r.URL.Path == "/sdk" { + return c.p, nil + } + return http.ProxyFromEnvironment(r) + } + + // Rewrite url Host to use the sdk tunnel, required for a certificate request. + c.u.Host = sdkTunnel +} + +func (c *Client) URL() *url.URL { + urlCopy := *c.u + return &urlCopy +} + +type marshaledClient struct { + Cookies []*http.Cookie + URL *url.URL + Insecure bool +} + +func (c *Client) MarshalJSON() ([]byte, error) { + m := marshaledClient{ + Cookies: c.Jar.Cookies(c.u), + URL: c.u, + Insecure: c.k, + } + + return json.Marshal(m) +} + +func (c *Client) UnmarshalJSON(b []byte) error { + var m marshaledClient + + err := json.Unmarshal(b, &m) + if err != nil { + return err + } + + *c = *NewClient(m.URL, m.Insecure) + c.Jar.SetCookies(m.URL, m.Cookies) + + return nil +} + +func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) { + if nil == ctx || nil == ctx.Done() { // ctx.Done() is for context.TODO() + return c.Client.Do(req) + } + + var resc = make(chan *http.Response, 1) + var errc = make(chan error, 1) + + // Perform request from separate routine. + go func() { + res, err := c.Client.Do(req) + if err != nil { + errc <- err + } else { + resc <- res + } + }() + + // Wait for request completion of context expiry. + select { + case <-ctx.Done(): + c.t.CancelRequest(req) + return nil, ctx.Err() + case err := <-errc: + return nil, err + case res := <-resc: + return res, nil + } +} + +func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error { + var err error + + reqEnv := Envelope{Body: reqBody} + resEnv := Envelope{Body: resBody} + + // Create debugging context for this round trip + d := c.d.newRoundTrip() + if d.enabled() { + defer d.done() + } + + b, err := xml.Marshal(reqEnv) + if err != nil { + panic(err) + } + + rawReqBody := io.MultiReader(strings.NewReader(xml.Header), bytes.NewReader(b)) + req, err := http.NewRequest("POST", c.u.String(), rawReqBody) + if err != nil { + panic(err) + } + + req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`) + soapAction := fmt.Sprintf("%s/%s", c.Namespace, c.Version) + req.Header.Set(`SOAPAction`, soapAction) + + if d.enabled() { + d.debugRequest(req) + } + + tstart := time.Now() + res, err := c.do(ctx, req) + tstop := time.Now() + + if d.enabled() { + d.logf("%6dms (%T)", tstop.Sub(tstart)/time.Millisecond, resBody) + } + + if err != nil { + return err + } + + if d.enabled() { + d.debugResponse(res) + } + + // Close response regardless of what happens next + defer res.Body.Close() + + switch res.StatusCode { + case http.StatusOK: + // OK + case http.StatusInternalServerError: + // Error, but typically includes a body explaining the error + default: + return errors.New(res.Status) + } + + dec := xml.NewDecoder(res.Body) + dec.TypeFunc = types.TypeFunc() + err = dec.Decode(&resEnv) + if err != nil { + return err + } + + if f := resBody.Fault(); f != nil { + return WrapSoapFault(f) + } + + return err +} + +func (c *Client) CloseIdleConnections() { + c.t.CloseIdleConnections() +} + +// ParseURL wraps url.Parse to rewrite the URL.Host field +// In the case of VM guest uploads or NFC lease URLs, a Host +// field with a value of "*" is rewritten to the Client's URL.Host. +func (c *Client) ParseURL(urlStr string) (*url.URL, error) { + u, err := url.Parse(urlStr) + if err != nil { + return nil, err + } + + host, _ := splitHostPort(u.Host) + if host == "*" { + // Also use Client's port, to support port forwarding + u.Host = c.URL().Host + } + + return u, nil +} + +type Upload struct { + Type string + Method string + ContentLength int64 + Headers map[string]string + Ticket *http.Cookie + Progress progress.Sinker +} + +var DefaultUpload = Upload{ + Type: "application/octet-stream", + Method: "PUT", +} + +// Upload PUTs the local file to the given URL +func (c *Client) Upload(f io.Reader, u *url.URL, param *Upload) error { + var err error + + if param.Progress != nil { + pr := progress.NewReader(param.Progress, f, param.ContentLength) + f = pr + + // Mark progress reader as done when returning from this function. + defer func() { + pr.Done(err) + }() + } + + req, err := http.NewRequest(param.Method, u.String(), f) + if err != nil { + return err + } + + req.ContentLength = param.ContentLength + req.Header.Set("Content-Type", param.Type) + + for k, v := range param.Headers { + req.Header.Add(k, v) + } + + if param.Ticket != nil { + req.AddCookie(param.Ticket) + } + + res, err := c.Client.Do(req) + if err != nil { + return err + } + + switch res.StatusCode { + case http.StatusOK: + case http.StatusCreated: + default: + err = errors.New(res.Status) + } + + return err +} + +// UploadFile PUTs the local file to the given URL +func (c *Client) UploadFile(file string, u *url.URL, param *Upload) error { + if param == nil { + p := DefaultUpload // Copy since we set ContentLength + param = &p + } + + s, err := os.Stat(file) + if err != nil { + return err + } + + f, err := os.Open(file) + if err != nil { + return err + } + defer f.Close() + + param.ContentLength = s.Size() + + return c.Upload(f, u, param) +} + +type Download struct { + Method string + Ticket *http.Cookie + Progress progress.Sinker +} + +var DefaultDownload = Download{ + Method: "GET", +} + +// Download GETs the remote file from the given URL +func (c *Client) Download(u *url.URL, param *Download) (io.ReadCloser, int64, error) { + + req, err := http.NewRequest(param.Method, u.String(), nil) + if err != nil { + return nil, 0, err + } + + if param.Ticket != nil { + req.AddCookie(param.Ticket) + } + + res, err := c.Client.Do(req) + if err != nil { + return nil, 0, err + } + + switch res.StatusCode { + case http.StatusOK: + default: + err = errors.New(res.Status) + } + + if err != nil { + return nil, 0, err + } + + var r io.ReadCloser = res.Body + + return r, res.ContentLength, nil +} + +// DownloadFile GETs the given URL to a local file +func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error { + var err error + if param == nil { + param = &DefaultDownload + } + + rc, contentLength, err := c.Download(u, param) + if err != nil { + return err + } + defer rc.Close() + + var r io.Reader = rc + + fh, err := os.Create(file) + if err != nil { + return err + } + defer fh.Close() + + if param.Progress != nil { + pr := progress.NewReader(param.Progress, r, contentLength) + r = pr + + // Mark progress reader as done when returning from this function. + defer func() { + pr.Done(err) + }() + } + + _, err = io.Copy(fh, r) + if err != nil { + return err + } + + // Assign error before returning so that it gets picked up by the deferred + // function marking the progress reader as done. + err = fh.Close() + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/debug.go b/vendor/github.com/vmware/govmomi/vim25/soap/debug.go new file mode 100644 index 0000000000..63518abca3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/soap/debug.go @@ -0,0 +1,149 @@ +/* +Copyright (c) 2015 VMware, 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 soap + +import ( + "fmt" + "io" + "net/http" + "net/http/httputil" + "sync/atomic" + "time" + + "github.com/vmware/govmomi/vim25/debug" +) + +// teeReader wraps io.TeeReader and patches through the Close() function. +type teeReader struct { + io.Reader + io.Closer +} + +func newTeeReader(rc io.ReadCloser, w io.Writer) io.ReadCloser { + return teeReader{ + Reader: io.TeeReader(rc, w), + Closer: rc, + } +} + +// debugRoundTrip contains state and logic needed to debug a single round trip. +type debugRoundTrip struct { + cn uint64 // Client number + rn uint64 // Request number + log io.WriteCloser // Request log + cs []io.Closer // Files that need closing when done +} + +func (d *debugRoundTrip) logf(format string, a ...interface{}) { + now := time.Now().Format("2006-01-02T15-04-05.000000000") + fmt.Fprintf(d.log, "%s - %04d: ", now, d.rn) + fmt.Fprintf(d.log, format, a...) + fmt.Fprintf(d.log, "\n") +} + +func (d *debugRoundTrip) enabled() bool { + return d != nil +} + +func (d *debugRoundTrip) done() { + for _, c := range d.cs { + c.Close() + } +} + +func (d *debugRoundTrip) newFile(suffix string) io.WriteCloser { + return debug.NewFile(fmt.Sprintf("%d-%04d.%s", d.cn, d.rn, suffix)) +} + +func (d *debugRoundTrip) debugRequest(req *http.Request) { + if d == nil { + return + } + + var wc io.WriteCloser + + // Capture headers + wc = d.newFile("req.headers") + b, _ := httputil.DumpRequest(req, false) + wc.Write(b) + wc.Close() + + // Capture body + wc = d.newFile("req.xml") + req.Body = newTeeReader(req.Body, wc) + + // Delay closing until marked done + d.cs = append(d.cs, wc) +} + +func (d *debugRoundTrip) debugResponse(res *http.Response) { + if d == nil { + return + } + + var wc io.WriteCloser + + // Capture headers + wc = d.newFile("res.headers") + b, _ := httputil.DumpResponse(res, false) + wc.Write(b) + wc.Close() + + // Capture body + wc = d.newFile("res.xml") + res.Body = newTeeReader(res.Body, wc) + + // Delay closing until marked done + d.cs = append(d.cs, wc) +} + +var cn uint64 // Client counter + +// debugContainer wraps the debugging state for a single client. +type debugContainer struct { + cn uint64 // Client number + rn uint64 // Request counter + log io.WriteCloser // Request log +} + +func newDebug() *debugContainer { + d := debugContainer{ + cn: atomic.AddUint64(&cn, 1), + rn: 0, + } + + if !debug.Enabled() { + return nil + } + + d.log = debug.NewFile(fmt.Sprintf("%d-client.log", d.cn)) + return &d +} + +func (d *debugContainer) newRoundTrip() *debugRoundTrip { + if d == nil { + return nil + } + + drt := debugRoundTrip{ + cn: d.cn, + rn: atomic.AddUint64(&d.rn, 1), + log: d.log, + } + + return &drt +} diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/error.go b/vendor/github.com/vmware/govmomi/vim25/soap/error.go new file mode 100644 index 0000000000..0408e7bf0d --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/soap/error.go @@ -0,0 +1,109 @@ +/* +Copyright (c) 2014 VMware, 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 soap + +import ( + "fmt" + "reflect" + + "github.com/vmware/govmomi/vim25/types" +) + +type regularError struct { + err error +} + +func (r regularError) Error() string { + return r.err.Error() +} + +type soapFaultError struct { + fault *Fault +} + +func (s soapFaultError) Error() string { + return fmt.Sprintf("%s: %s", s.fault.Code, s.fault.String) +} + +type vimFaultError struct { + fault types.BaseMethodFault +} + +func (v vimFaultError) Error() string { + typ := reflect.TypeOf(v.fault) + for typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + + return typ.Name() +} + +func (v vimFaultError) Fault() types.BaseMethodFault { + return v.fault +} + +func Wrap(err error) error { + switch err.(type) { + case regularError: + return err + case soapFaultError: + return err + case vimFaultError: + return err + } + + return WrapRegularError(err) +} + +func WrapRegularError(err error) error { + return regularError{err} +} + +func IsRegularError(err error) bool { + _, ok := err.(regularError) + return ok +} + +func ToRegularError(err error) error { + return err.(regularError).err +} + +func WrapSoapFault(f *Fault) error { + return soapFaultError{f} +} + +func IsSoapFault(err error) bool { + _, ok := err.(soapFaultError) + return ok +} + +func ToSoapFault(err error) *Fault { + return err.(soapFaultError).fault +} + +func WrapVimFault(v types.BaseMethodFault) error { + return vimFaultError{v} +} + +func IsVimFault(err error) bool { + _, ok := err.(vimFaultError) + return ok +} + +func ToVimFault(err error) types.BaseMethodFault { + return err.(vimFaultError).fault +} diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/soap.go b/vendor/github.com/vmware/govmomi/vim25/soap/soap.go new file mode 100644 index 0000000000..e3b1a97dc4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/soap/soap.go @@ -0,0 +1,45 @@ +/* +Copyright (c) 2014 VMware, 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 soap + +import ( + "github.com/vmware/govmomi/vim25/types" + "github.com/vmware/govmomi/vim25/xml" +) + +type Envelope struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header *Header `xml:",omitempty"` + Body interface{} +} + +type Header struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` +} + +type Fault struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"` + Code string `xml:"faultcode"` + String string `xml:"faultstring"` + Detail struct { + Fault types.AnyType `xml:",any"` + } `xml:"detail"` +} + +func (f *Fault) VimFault() types.AnyType { + return f.Detail.Fault +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/base.go b/vendor/github.com/vmware/govmomi/vim25/types/base.go new file mode 100644 index 0000000000..3bb12b7412 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/base.go @@ -0,0 +1,19 @@ +/* +Copyright (c) 2014 VMware, 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 types + +type AnyType interface{} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/enum.go b/vendor/github.com/vmware/govmomi/vim25/types/enum.go new file mode 100644 index 0000000000..07076e3a55 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/enum.go @@ -0,0 +1,4098 @@ +/* +Copyright (c) 2014-2016 VMware, 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 types + +import "reflect" + +type ActionParameter string + +const ( + ActionParameterTargetName = ActionParameter("targetName") + ActionParameterAlarmName = ActionParameter("alarmName") + ActionParameterOldStatus = ActionParameter("oldStatus") + ActionParameterNewStatus = ActionParameter("newStatus") + ActionParameterTriggeringSummary = ActionParameter("triggeringSummary") + ActionParameterDeclaringSummary = ActionParameter("declaringSummary") + ActionParameterEventDescription = ActionParameter("eventDescription") + ActionParameterTarget = ActionParameter("target") + ActionParameterAlarm = ActionParameter("alarm") +) + +func init() { + t["ActionParameter"] = reflect.TypeOf((*ActionParameter)(nil)).Elem() +} + +type ActionType string + +const ( + ActionTypeMigrationV1 = ActionType("MigrationV1") + ActionTypeVmPowerV1 = ActionType("VmPowerV1") + ActionTypeHostPowerV1 = ActionType("HostPowerV1") + ActionTypeHostMaintenanceV1 = ActionType("HostMaintenanceV1") + ActionTypeStorageMigrationV1 = ActionType("StorageMigrationV1") + ActionTypeStoragePlacementV1 = ActionType("StoragePlacementV1") + ActionTypePlacementV1 = ActionType("PlacementV1") +) + +func init() { + t["ActionType"] = reflect.TypeOf((*ActionType)(nil)).Elem() +} + +type AffinityType string + +const ( + AffinityTypeMemory = AffinityType("memory") + AffinityTypeCpu = AffinityType("cpu") +) + +func init() { + t["AffinityType"] = reflect.TypeOf((*AffinityType)(nil)).Elem() +} + +type AgentInstallFailedReason string + +const ( + AgentInstallFailedReasonNotEnoughSpaceOnDevice = AgentInstallFailedReason("NotEnoughSpaceOnDevice") + AgentInstallFailedReasonPrepareToUpgradeFailed = AgentInstallFailedReason("PrepareToUpgradeFailed") + AgentInstallFailedReasonAgentNotRunning = AgentInstallFailedReason("AgentNotRunning") + AgentInstallFailedReasonAgentNotReachable = AgentInstallFailedReason("AgentNotReachable") + AgentInstallFailedReasonInstallTimedout = AgentInstallFailedReason("InstallTimedout") + AgentInstallFailedReasonSignatureVerificationFailed = AgentInstallFailedReason("SignatureVerificationFailed") + AgentInstallFailedReasonAgentUploadFailed = AgentInstallFailedReason("AgentUploadFailed") + AgentInstallFailedReasonAgentUploadTimedout = AgentInstallFailedReason("AgentUploadTimedout") + AgentInstallFailedReasonUnknownInstallerError = AgentInstallFailedReason("UnknownInstallerError") +) + +func init() { + t["AgentInstallFailedReason"] = reflect.TypeOf((*AgentInstallFailedReason)(nil)).Elem() +} + +type ArrayUpdateOperation string + +const ( + ArrayUpdateOperationAdd = ArrayUpdateOperation("add") + ArrayUpdateOperationRemove = ArrayUpdateOperation("remove") + ArrayUpdateOperationEdit = ArrayUpdateOperation("edit") +) + +func init() { + t["ArrayUpdateOperation"] = reflect.TypeOf((*ArrayUpdateOperation)(nil)).Elem() +} + +type AutoStartAction string + +const ( + AutoStartActionNone = AutoStartAction("none") + AutoStartActionSystemDefault = AutoStartAction("systemDefault") + AutoStartActionPowerOn = AutoStartAction("powerOn") + AutoStartActionPowerOff = AutoStartAction("powerOff") + AutoStartActionGuestShutdown = AutoStartAction("guestShutdown") + AutoStartActionSuspend = AutoStartAction("suspend") +) + +func init() { + t["AutoStartAction"] = reflect.TypeOf((*AutoStartAction)(nil)).Elem() +} + +type AutoStartWaitHeartbeatSetting string + +const ( + AutoStartWaitHeartbeatSettingYes = AutoStartWaitHeartbeatSetting("yes") + AutoStartWaitHeartbeatSettingNo = AutoStartWaitHeartbeatSetting("no") + AutoStartWaitHeartbeatSettingSystemDefault = AutoStartWaitHeartbeatSetting("systemDefault") +) + +func init() { + t["AutoStartWaitHeartbeatSetting"] = reflect.TypeOf((*AutoStartWaitHeartbeatSetting)(nil)).Elem() +} + +type BatchResultResult string + +const ( + BatchResultResultSuccess = BatchResultResult("success") + BatchResultResultFail = BatchResultResult("fail") +) + +func init() { + t["BatchResultResult"] = reflect.TypeOf((*BatchResultResult)(nil)).Elem() +} + +type CannotEnableVmcpForClusterReason string + +const ( + CannotEnableVmcpForClusterReasonAPDTimeoutDisabled = CannotEnableVmcpForClusterReason("APDTimeoutDisabled") + CannotEnableVmcpForClusterReasonIncompatibleHostVersion = CannotEnableVmcpForClusterReason("IncompatibleHostVersion") +) + +func init() { + t["CannotEnableVmcpForClusterReason"] = reflect.TypeOf((*CannotEnableVmcpForClusterReason)(nil)).Elem() +} + +type CannotMoveFaultToleranceVmMoveType string + +const ( + CannotMoveFaultToleranceVmMoveTypeResourcePool = CannotMoveFaultToleranceVmMoveType("resourcePool") + CannotMoveFaultToleranceVmMoveTypeCluster = CannotMoveFaultToleranceVmMoveType("cluster") +) + +func init() { + t["CannotMoveFaultToleranceVmMoveType"] = reflect.TypeOf((*CannotMoveFaultToleranceVmMoveType)(nil)).Elem() +} + +type CannotPowerOffVmInClusterOperation string + +const ( + CannotPowerOffVmInClusterOperationSuspend = CannotPowerOffVmInClusterOperation("suspend") + CannotPowerOffVmInClusterOperationPowerOff = CannotPowerOffVmInClusterOperation("powerOff") + CannotPowerOffVmInClusterOperationGuestShutdown = CannotPowerOffVmInClusterOperation("guestShutdown") + CannotPowerOffVmInClusterOperationGuestSuspend = CannotPowerOffVmInClusterOperation("guestSuspend") +) + +func init() { + t["CannotPowerOffVmInClusterOperation"] = reflect.TypeOf((*CannotPowerOffVmInClusterOperation)(nil)).Elem() +} + +type CannotUseNetworkReason string + +const ( + CannotUseNetworkReasonNetworkReservationNotSupported = CannotUseNetworkReason("NetworkReservationNotSupported") + CannotUseNetworkReasonMismatchedNetworkPolicies = CannotUseNetworkReason("MismatchedNetworkPolicies") + CannotUseNetworkReasonMismatchedDvsVersionOrVendor = CannotUseNetworkReason("MismatchedDvsVersionOrVendor") + CannotUseNetworkReasonVMotionToUnsupportedNetworkType = CannotUseNetworkReason("VMotionToUnsupportedNetworkType") +) + +func init() { + t["CannotUseNetworkReason"] = reflect.TypeOf((*CannotUseNetworkReason)(nil)).Elem() +} + +type CheckTestType string + +const ( + CheckTestTypeSourceTests = CheckTestType("sourceTests") + CheckTestTypeHostTests = CheckTestType("hostTests") + CheckTestTypeResourcePoolTests = CheckTestType("resourcePoolTests") + CheckTestTypeDatastoreTests = CheckTestType("datastoreTests") + CheckTestTypeNetworkTests = CheckTestType("networkTests") +) + +func init() { + t["CheckTestType"] = reflect.TypeOf((*CheckTestType)(nil)).Elem() +} + +type ClusterDasAamNodeStateDasState string + +const ( + ClusterDasAamNodeStateDasStateUninitialized = ClusterDasAamNodeStateDasState("uninitialized") + ClusterDasAamNodeStateDasStateInitialized = ClusterDasAamNodeStateDasState("initialized") + ClusterDasAamNodeStateDasStateConfiguring = ClusterDasAamNodeStateDasState("configuring") + ClusterDasAamNodeStateDasStateUnconfiguring = ClusterDasAamNodeStateDasState("unconfiguring") + ClusterDasAamNodeStateDasStateRunning = ClusterDasAamNodeStateDasState("running") + ClusterDasAamNodeStateDasStateError = ClusterDasAamNodeStateDasState("error") + ClusterDasAamNodeStateDasStateAgentShutdown = ClusterDasAamNodeStateDasState("agentShutdown") + ClusterDasAamNodeStateDasStateNodeFailed = ClusterDasAamNodeStateDasState("nodeFailed") +) + +func init() { + t["ClusterDasAamNodeStateDasState"] = reflect.TypeOf((*ClusterDasAamNodeStateDasState)(nil)).Elem() +} + +type ClusterDasConfigInfoHBDatastoreCandidate string + +const ( + ClusterDasConfigInfoHBDatastoreCandidateUserSelectedDs = ClusterDasConfigInfoHBDatastoreCandidate("userSelectedDs") + ClusterDasConfigInfoHBDatastoreCandidateAllFeasibleDs = ClusterDasConfigInfoHBDatastoreCandidate("allFeasibleDs") + ClusterDasConfigInfoHBDatastoreCandidateAllFeasibleDsWithUserPreference = ClusterDasConfigInfoHBDatastoreCandidate("allFeasibleDsWithUserPreference") +) + +func init() { + t["ClusterDasConfigInfoHBDatastoreCandidate"] = reflect.TypeOf((*ClusterDasConfigInfoHBDatastoreCandidate)(nil)).Elem() +} + +type ClusterDasConfigInfoServiceState string + +const ( + ClusterDasConfigInfoServiceStateDisabled = ClusterDasConfigInfoServiceState("disabled") + ClusterDasConfigInfoServiceStateEnabled = ClusterDasConfigInfoServiceState("enabled") +) + +func init() { + t["ClusterDasConfigInfoServiceState"] = reflect.TypeOf((*ClusterDasConfigInfoServiceState)(nil)).Elem() +} + +type ClusterDasConfigInfoVmMonitoringState string + +const ( + ClusterDasConfigInfoVmMonitoringStateVmMonitoringDisabled = ClusterDasConfigInfoVmMonitoringState("vmMonitoringDisabled") + ClusterDasConfigInfoVmMonitoringStateVmMonitoringOnly = ClusterDasConfigInfoVmMonitoringState("vmMonitoringOnly") + ClusterDasConfigInfoVmMonitoringStateVmAndAppMonitoring = ClusterDasConfigInfoVmMonitoringState("vmAndAppMonitoring") +) + +func init() { + t["ClusterDasConfigInfoVmMonitoringState"] = reflect.TypeOf((*ClusterDasConfigInfoVmMonitoringState)(nil)).Elem() +} + +type ClusterDasFdmAvailabilityState string + +const ( + ClusterDasFdmAvailabilityStateUninitialized = ClusterDasFdmAvailabilityState("uninitialized") + ClusterDasFdmAvailabilityStateElection = ClusterDasFdmAvailabilityState("election") + ClusterDasFdmAvailabilityStateMaster = ClusterDasFdmAvailabilityState("master") + ClusterDasFdmAvailabilityStateConnectedToMaster = ClusterDasFdmAvailabilityState("connectedToMaster") + ClusterDasFdmAvailabilityStateNetworkPartitionedFromMaster = ClusterDasFdmAvailabilityState("networkPartitionedFromMaster") + ClusterDasFdmAvailabilityStateNetworkIsolated = ClusterDasFdmAvailabilityState("networkIsolated") + ClusterDasFdmAvailabilityStateHostDown = ClusterDasFdmAvailabilityState("hostDown") + ClusterDasFdmAvailabilityStateInitializationError = ClusterDasFdmAvailabilityState("initializationError") + ClusterDasFdmAvailabilityStateUninitializationError = ClusterDasFdmAvailabilityState("uninitializationError") + ClusterDasFdmAvailabilityStateFdmUnreachable = ClusterDasFdmAvailabilityState("fdmUnreachable") +) + +func init() { + t["ClusterDasFdmAvailabilityState"] = reflect.TypeOf((*ClusterDasFdmAvailabilityState)(nil)).Elem() +} + +type ClusterDasVmSettingsIsolationResponse string + +const ( + ClusterDasVmSettingsIsolationResponseNone = ClusterDasVmSettingsIsolationResponse("none") + ClusterDasVmSettingsIsolationResponsePowerOff = ClusterDasVmSettingsIsolationResponse("powerOff") + ClusterDasVmSettingsIsolationResponseShutdown = ClusterDasVmSettingsIsolationResponse("shutdown") + ClusterDasVmSettingsIsolationResponseClusterIsolationResponse = ClusterDasVmSettingsIsolationResponse("clusterIsolationResponse") +) + +func init() { + t["ClusterDasVmSettingsIsolationResponse"] = reflect.TypeOf((*ClusterDasVmSettingsIsolationResponse)(nil)).Elem() +} + +type ClusterDasVmSettingsRestartPriority string + +const ( + ClusterDasVmSettingsRestartPriorityDisabled = ClusterDasVmSettingsRestartPriority("disabled") + ClusterDasVmSettingsRestartPriorityLow = ClusterDasVmSettingsRestartPriority("low") + ClusterDasVmSettingsRestartPriorityMedium = ClusterDasVmSettingsRestartPriority("medium") + ClusterDasVmSettingsRestartPriorityHigh = ClusterDasVmSettingsRestartPriority("high") + ClusterDasVmSettingsRestartPriorityClusterRestartPriority = ClusterDasVmSettingsRestartPriority("clusterRestartPriority") +) + +func init() { + t["ClusterDasVmSettingsRestartPriority"] = reflect.TypeOf((*ClusterDasVmSettingsRestartPriority)(nil)).Elem() +} + +type ClusterPowerOnVmOption string + +const ( + ClusterPowerOnVmOptionOverrideAutomationLevel = ClusterPowerOnVmOption("OverrideAutomationLevel") + ClusterPowerOnVmOptionReserveResources = ClusterPowerOnVmOption("ReserveResources") +) + +func init() { + t["ClusterPowerOnVmOption"] = reflect.TypeOf((*ClusterPowerOnVmOption)(nil)).Elem() +} + +type ClusterProfileServiceType string + +const ( + ClusterProfileServiceTypeDRS = ClusterProfileServiceType("DRS") + ClusterProfileServiceTypeHA = ClusterProfileServiceType("HA") + ClusterProfileServiceTypeDPM = ClusterProfileServiceType("DPM") + ClusterProfileServiceTypeFT = ClusterProfileServiceType("FT") +) + +func init() { + t["ClusterProfileServiceType"] = reflect.TypeOf((*ClusterProfileServiceType)(nil)).Elem() +} + +type ClusterVmComponentProtectionSettingsStorageVmReaction string + +const ( + ClusterVmComponentProtectionSettingsStorageVmReactionDisabled = ClusterVmComponentProtectionSettingsStorageVmReaction("disabled") + ClusterVmComponentProtectionSettingsStorageVmReactionWarning = ClusterVmComponentProtectionSettingsStorageVmReaction("warning") + ClusterVmComponentProtectionSettingsStorageVmReactionRestartConservative = ClusterVmComponentProtectionSettingsStorageVmReaction("restartConservative") + ClusterVmComponentProtectionSettingsStorageVmReactionRestartAggressive = ClusterVmComponentProtectionSettingsStorageVmReaction("restartAggressive") + ClusterVmComponentProtectionSettingsStorageVmReactionClusterDefault = ClusterVmComponentProtectionSettingsStorageVmReaction("clusterDefault") +) + +func init() { + t["ClusterVmComponentProtectionSettingsStorageVmReaction"] = reflect.TypeOf((*ClusterVmComponentProtectionSettingsStorageVmReaction)(nil)).Elem() +} + +type ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared string + +const ( + ClusterVmComponentProtectionSettingsVmReactionOnAPDClearedNone = ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared("none") + ClusterVmComponentProtectionSettingsVmReactionOnAPDClearedReset = ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared("reset") + ClusterVmComponentProtectionSettingsVmReactionOnAPDClearedUseClusterDefault = ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared("useClusterDefault") +) + +func init() { + t["ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared"] = reflect.TypeOf((*ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared)(nil)).Elem() +} + +type ComplianceResultStatus string + +const ( + ComplianceResultStatusCompliant = ComplianceResultStatus("compliant") + ComplianceResultStatusNonCompliant = ComplianceResultStatus("nonCompliant") + ComplianceResultStatusUnknown = ComplianceResultStatus("unknown") +) + +func init() { + t["ComplianceResultStatus"] = reflect.TypeOf((*ComplianceResultStatus)(nil)).Elem() +} + +type ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState string + +const ( + ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseStateLicensed = ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState("licensed") + ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseStateUnlicensed = ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState("unlicensed") + ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseStateUnknown = ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState("unknown") +) + +func init() { + t["ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState"] = reflect.TypeOf((*ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState)(nil)).Elem() +} + +type ConfigSpecOperation string + +const ( + ConfigSpecOperationAdd = ConfigSpecOperation("add") + ConfigSpecOperationEdit = ConfigSpecOperation("edit") + ConfigSpecOperationRemove = ConfigSpecOperation("remove") +) + +func init() { + t["ConfigSpecOperation"] = reflect.TypeOf((*ConfigSpecOperation)(nil)).Elem() +} + +type CustomizationLicenseDataMode string + +const ( + CustomizationLicenseDataModePerServer = CustomizationLicenseDataMode("perServer") + CustomizationLicenseDataModePerSeat = CustomizationLicenseDataMode("perSeat") +) + +func init() { + t["CustomizationLicenseDataMode"] = reflect.TypeOf((*CustomizationLicenseDataMode)(nil)).Elem() +} + +type CustomizationNetBIOSMode string + +const ( + CustomizationNetBIOSModeEnableNetBIOSViaDhcp = CustomizationNetBIOSMode("enableNetBIOSViaDhcp") + CustomizationNetBIOSModeEnableNetBIOS = CustomizationNetBIOSMode("enableNetBIOS") + CustomizationNetBIOSModeDisableNetBIOS = CustomizationNetBIOSMode("disableNetBIOS") +) + +func init() { + t["CustomizationNetBIOSMode"] = reflect.TypeOf((*CustomizationNetBIOSMode)(nil)).Elem() +} + +type CustomizationSysprepRebootOption string + +const ( + CustomizationSysprepRebootOptionReboot = CustomizationSysprepRebootOption("reboot") + CustomizationSysprepRebootOptionNoreboot = CustomizationSysprepRebootOption("noreboot") + CustomizationSysprepRebootOptionShutdown = CustomizationSysprepRebootOption("shutdown") +) + +func init() { + t["CustomizationSysprepRebootOption"] = reflect.TypeOf((*CustomizationSysprepRebootOption)(nil)).Elem() +} + +type DVPortStatusVmDirectPathGen2InactiveReasonNetwork string + +const ( + DVPortStatusVmDirectPathGen2InactiveReasonNetworkPortNptIncompatibleDvs = DVPortStatusVmDirectPathGen2InactiveReasonNetwork("portNptIncompatibleDvs") + DVPortStatusVmDirectPathGen2InactiveReasonNetworkPortNptNoCompatibleNics = DVPortStatusVmDirectPathGen2InactiveReasonNetwork("portNptNoCompatibleNics") + DVPortStatusVmDirectPathGen2InactiveReasonNetworkPortNptNoVirtualFunctionsAvailable = DVPortStatusVmDirectPathGen2InactiveReasonNetwork("portNptNoVirtualFunctionsAvailable") + DVPortStatusVmDirectPathGen2InactiveReasonNetworkPortNptDisabledForPort = DVPortStatusVmDirectPathGen2InactiveReasonNetwork("portNptDisabledForPort") +) + +func init() { + t["DVPortStatusVmDirectPathGen2InactiveReasonNetwork"] = reflect.TypeOf((*DVPortStatusVmDirectPathGen2InactiveReasonNetwork)(nil)).Elem() +} + +type DVPortStatusVmDirectPathGen2InactiveReasonOther string + +const ( + DVPortStatusVmDirectPathGen2InactiveReasonOtherPortNptIncompatibleHost = DVPortStatusVmDirectPathGen2InactiveReasonOther("portNptIncompatibleHost") + DVPortStatusVmDirectPathGen2InactiveReasonOtherPortNptIncompatibleConnectee = DVPortStatusVmDirectPathGen2InactiveReasonOther("portNptIncompatibleConnectee") +) + +func init() { + t["DVPortStatusVmDirectPathGen2InactiveReasonOther"] = reflect.TypeOf((*DVPortStatusVmDirectPathGen2InactiveReasonOther)(nil)).Elem() +} + +type DasConfigFaultDasConfigFaultReason string + +const ( + DasConfigFaultDasConfigFaultReasonHostNetworkMisconfiguration = DasConfigFaultDasConfigFaultReason("HostNetworkMisconfiguration") + DasConfigFaultDasConfigFaultReasonHostMisconfiguration = DasConfigFaultDasConfigFaultReason("HostMisconfiguration") + DasConfigFaultDasConfigFaultReasonInsufficientPrivileges = DasConfigFaultDasConfigFaultReason("InsufficientPrivileges") + DasConfigFaultDasConfigFaultReasonNoPrimaryAgentAvailable = DasConfigFaultDasConfigFaultReason("NoPrimaryAgentAvailable") + DasConfigFaultDasConfigFaultReasonOther = DasConfigFaultDasConfigFaultReason("Other") + DasConfigFaultDasConfigFaultReasonNoDatastoresConfigured = DasConfigFaultDasConfigFaultReason("NoDatastoresConfigured") + DasConfigFaultDasConfigFaultReasonCreateConfigVvolFailed = DasConfigFaultDasConfigFaultReason("CreateConfigVvolFailed") + DasConfigFaultDasConfigFaultReasonVSanNotSupportedOnHost = DasConfigFaultDasConfigFaultReason("VSanNotSupportedOnHost") + DasConfigFaultDasConfigFaultReasonDasNetworkMisconfiguration = DasConfigFaultDasConfigFaultReason("DasNetworkMisconfiguration") +) + +func init() { + t["DasConfigFaultDasConfigFaultReason"] = reflect.TypeOf((*DasConfigFaultDasConfigFaultReason)(nil)).Elem() +} + +type DasVmPriority string + +const ( + DasVmPriorityDisabled = DasVmPriority("disabled") + DasVmPriorityLow = DasVmPriority("low") + DasVmPriorityMedium = DasVmPriority("medium") + DasVmPriorityHigh = DasVmPriority("high") +) + +func init() { + t["DasVmPriority"] = reflect.TypeOf((*DasVmPriority)(nil)).Elem() +} + +type DatastoreAccessible string + +const ( + DatastoreAccessibleTrue = DatastoreAccessible("True") + DatastoreAccessibleFalse = DatastoreAccessible("False") +) + +func init() { + t["DatastoreAccessible"] = reflect.TypeOf((*DatastoreAccessible)(nil)).Elem() +} + +type DatastoreSummaryMaintenanceModeState string + +const ( + DatastoreSummaryMaintenanceModeStateNormal = DatastoreSummaryMaintenanceModeState("normal") + DatastoreSummaryMaintenanceModeStateEnteringMaintenance = DatastoreSummaryMaintenanceModeState("enteringMaintenance") + DatastoreSummaryMaintenanceModeStateInMaintenance = DatastoreSummaryMaintenanceModeState("inMaintenance") +) + +func init() { + t["DatastoreSummaryMaintenanceModeState"] = reflect.TypeOf((*DatastoreSummaryMaintenanceModeState)(nil)).Elem() +} + +type DayOfWeek string + +const ( + DayOfWeekSunday = DayOfWeek("sunday") + DayOfWeekMonday = DayOfWeek("monday") + DayOfWeekTuesday = DayOfWeek("tuesday") + DayOfWeekWednesday = DayOfWeek("wednesday") + DayOfWeekThursday = DayOfWeek("thursday") + DayOfWeekFriday = DayOfWeek("friday") + DayOfWeekSaturday = DayOfWeek("saturday") +) + +func init() { + t["DayOfWeek"] = reflect.TypeOf((*DayOfWeek)(nil)).Elem() +} + +type DeviceNotSupportedReason string + +const ( + DeviceNotSupportedReasonHost = DeviceNotSupportedReason("host") + DeviceNotSupportedReasonGuest = DeviceNotSupportedReason("guest") +) + +func init() { + t["DeviceNotSupportedReason"] = reflect.TypeOf((*DeviceNotSupportedReason)(nil)).Elem() +} + +type DiagnosticManagerLogCreator string + +const ( + DiagnosticManagerLogCreatorVpxd = DiagnosticManagerLogCreator("vpxd") + DiagnosticManagerLogCreatorVpxa = DiagnosticManagerLogCreator("vpxa") + DiagnosticManagerLogCreatorHostd = DiagnosticManagerLogCreator("hostd") + DiagnosticManagerLogCreatorServerd = DiagnosticManagerLogCreator("serverd") + DiagnosticManagerLogCreatorInstall = DiagnosticManagerLogCreator("install") + DiagnosticManagerLogCreatorVpxClient = DiagnosticManagerLogCreator("vpxClient") + DiagnosticManagerLogCreatorRecordLog = DiagnosticManagerLogCreator("recordLog") +) + +func init() { + t["DiagnosticManagerLogCreator"] = reflect.TypeOf((*DiagnosticManagerLogCreator)(nil)).Elem() +} + +type DiagnosticManagerLogFormat string + +const ( + DiagnosticManagerLogFormatPlain = DiagnosticManagerLogFormat("plain") +) + +func init() { + t["DiagnosticManagerLogFormat"] = reflect.TypeOf((*DiagnosticManagerLogFormat)(nil)).Elem() +} + +type DiagnosticPartitionStorageType string + +const ( + DiagnosticPartitionStorageTypeDirectAttached = DiagnosticPartitionStorageType("directAttached") + DiagnosticPartitionStorageTypeNetworkAttached = DiagnosticPartitionStorageType("networkAttached") +) + +func init() { + t["DiagnosticPartitionStorageType"] = reflect.TypeOf((*DiagnosticPartitionStorageType)(nil)).Elem() +} + +type DiagnosticPartitionType string + +const ( + DiagnosticPartitionTypeSingleHost = DiagnosticPartitionType("singleHost") + DiagnosticPartitionTypeMultiHost = DiagnosticPartitionType("multiHost") +) + +func init() { + t["DiagnosticPartitionType"] = reflect.TypeOf((*DiagnosticPartitionType)(nil)).Elem() +} + +type DisallowedChangeByServiceDisallowedChange string + +const ( + DisallowedChangeByServiceDisallowedChangeHotExtendDisk = DisallowedChangeByServiceDisallowedChange("hotExtendDisk") +) + +func init() { + t["DisallowedChangeByServiceDisallowedChange"] = reflect.TypeOf((*DisallowedChangeByServiceDisallowedChange)(nil)).Elem() +} + +type DistributedVirtualPortgroupMetaTagName string + +const ( + DistributedVirtualPortgroupMetaTagNameDvsName = DistributedVirtualPortgroupMetaTagName("dvsName") + DistributedVirtualPortgroupMetaTagNamePortgroupName = DistributedVirtualPortgroupMetaTagName("portgroupName") + DistributedVirtualPortgroupMetaTagNamePortIndex = DistributedVirtualPortgroupMetaTagName("portIndex") +) + +func init() { + t["DistributedVirtualPortgroupMetaTagName"] = reflect.TypeOf((*DistributedVirtualPortgroupMetaTagName)(nil)).Elem() +} + +type DistributedVirtualPortgroupPortgroupType string + +const ( + DistributedVirtualPortgroupPortgroupTypeEarlyBinding = DistributedVirtualPortgroupPortgroupType("earlyBinding") + DistributedVirtualPortgroupPortgroupTypeLateBinding = DistributedVirtualPortgroupPortgroupType("lateBinding") + DistributedVirtualPortgroupPortgroupTypeEphemeral = DistributedVirtualPortgroupPortgroupType("ephemeral") +) + +func init() { + t["DistributedVirtualPortgroupPortgroupType"] = reflect.TypeOf((*DistributedVirtualPortgroupPortgroupType)(nil)).Elem() +} + +type DistributedVirtualSwitchHostInfrastructureTrafficClass string + +const ( + DistributedVirtualSwitchHostInfrastructureTrafficClassManagement = DistributedVirtualSwitchHostInfrastructureTrafficClass("management") + DistributedVirtualSwitchHostInfrastructureTrafficClassFaultTolerance = DistributedVirtualSwitchHostInfrastructureTrafficClass("faultTolerance") + DistributedVirtualSwitchHostInfrastructureTrafficClassVmotion = DistributedVirtualSwitchHostInfrastructureTrafficClass("vmotion") + DistributedVirtualSwitchHostInfrastructureTrafficClassVirtualMachine = DistributedVirtualSwitchHostInfrastructureTrafficClass("virtualMachine") + DistributedVirtualSwitchHostInfrastructureTrafficClassISCSI = DistributedVirtualSwitchHostInfrastructureTrafficClass("iSCSI") + DistributedVirtualSwitchHostInfrastructureTrafficClassNfs = DistributedVirtualSwitchHostInfrastructureTrafficClass("nfs") + DistributedVirtualSwitchHostInfrastructureTrafficClassHbr = DistributedVirtualSwitchHostInfrastructureTrafficClass("hbr") + DistributedVirtualSwitchHostInfrastructureTrafficClassVsan = DistributedVirtualSwitchHostInfrastructureTrafficClass("vsan") + DistributedVirtualSwitchHostInfrastructureTrafficClassVdp = DistributedVirtualSwitchHostInfrastructureTrafficClass("vdp") +) + +func init() { + t["DistributedVirtualSwitchHostInfrastructureTrafficClass"] = reflect.TypeOf((*DistributedVirtualSwitchHostInfrastructureTrafficClass)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberHostComponentState string + +const ( + DistributedVirtualSwitchHostMemberHostComponentStateUp = DistributedVirtualSwitchHostMemberHostComponentState("up") + DistributedVirtualSwitchHostMemberHostComponentStatePending = DistributedVirtualSwitchHostMemberHostComponentState("pending") + DistributedVirtualSwitchHostMemberHostComponentStateOutOfSync = DistributedVirtualSwitchHostMemberHostComponentState("outOfSync") + DistributedVirtualSwitchHostMemberHostComponentStateWarning = DistributedVirtualSwitchHostMemberHostComponentState("warning") + DistributedVirtualSwitchHostMemberHostComponentStateDisconnected = DistributedVirtualSwitchHostMemberHostComponentState("disconnected") + DistributedVirtualSwitchHostMemberHostComponentStateDown = DistributedVirtualSwitchHostMemberHostComponentState("down") +) + +func init() { + t["DistributedVirtualSwitchHostMemberHostComponentState"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberHostComponentState)(nil)).Elem() +} + +type DistributedVirtualSwitchNetworkResourceControlVersion string + +const ( + DistributedVirtualSwitchNetworkResourceControlVersionVersion2 = DistributedVirtualSwitchNetworkResourceControlVersion("version2") + DistributedVirtualSwitchNetworkResourceControlVersionVersion3 = DistributedVirtualSwitchNetworkResourceControlVersion("version3") +) + +func init() { + t["DistributedVirtualSwitchNetworkResourceControlVersion"] = reflect.TypeOf((*DistributedVirtualSwitchNetworkResourceControlVersion)(nil)).Elem() +} + +type DistributedVirtualSwitchNicTeamingPolicyMode string + +const ( + DistributedVirtualSwitchNicTeamingPolicyModeLoadbalance_ip = DistributedVirtualSwitchNicTeamingPolicyMode("loadbalance_ip") + DistributedVirtualSwitchNicTeamingPolicyModeLoadbalance_srcmac = DistributedVirtualSwitchNicTeamingPolicyMode("loadbalance_srcmac") + DistributedVirtualSwitchNicTeamingPolicyModeLoadbalance_srcid = DistributedVirtualSwitchNicTeamingPolicyMode("loadbalance_srcid") + DistributedVirtualSwitchNicTeamingPolicyModeFailover_explicit = DistributedVirtualSwitchNicTeamingPolicyMode("failover_explicit") + DistributedVirtualSwitchNicTeamingPolicyModeLoadbalance_loadbased = DistributedVirtualSwitchNicTeamingPolicyMode("loadbalance_loadbased") +) + +func init() { + t["DistributedVirtualSwitchNicTeamingPolicyMode"] = reflect.TypeOf((*DistributedVirtualSwitchNicTeamingPolicyMode)(nil)).Elem() +} + +type DistributedVirtualSwitchPortConnecteeConnecteeType string + +const ( + DistributedVirtualSwitchPortConnecteeConnecteeTypePnic = DistributedVirtualSwitchPortConnecteeConnecteeType("pnic") + DistributedVirtualSwitchPortConnecteeConnecteeTypeVmVnic = DistributedVirtualSwitchPortConnecteeConnecteeType("vmVnic") + DistributedVirtualSwitchPortConnecteeConnecteeTypeHostConsoleVnic = DistributedVirtualSwitchPortConnecteeConnecteeType("hostConsoleVnic") + DistributedVirtualSwitchPortConnecteeConnecteeTypeHostVmkVnic = DistributedVirtualSwitchPortConnecteeConnecteeType("hostVmkVnic") +) + +func init() { + t["DistributedVirtualSwitchPortConnecteeConnecteeType"] = reflect.TypeOf((*DistributedVirtualSwitchPortConnecteeConnecteeType)(nil)).Elem() +} + +type DistributedVirtualSwitchProductSpecOperationType string + +const ( + DistributedVirtualSwitchProductSpecOperationTypePreInstall = DistributedVirtualSwitchProductSpecOperationType("preInstall") + DistributedVirtualSwitchProductSpecOperationTypeUpgrade = DistributedVirtualSwitchProductSpecOperationType("upgrade") + DistributedVirtualSwitchProductSpecOperationTypeNotifyAvailableUpgrade = DistributedVirtualSwitchProductSpecOperationType("notifyAvailableUpgrade") + DistributedVirtualSwitchProductSpecOperationTypeProceedWithUpgrade = DistributedVirtualSwitchProductSpecOperationType("proceedWithUpgrade") + DistributedVirtualSwitchProductSpecOperationTypeUpdateBundleInfo = DistributedVirtualSwitchProductSpecOperationType("updateBundleInfo") +) + +func init() { + t["DistributedVirtualSwitchProductSpecOperationType"] = reflect.TypeOf((*DistributedVirtualSwitchProductSpecOperationType)(nil)).Elem() +} + +type DpmBehavior string + +const ( + DpmBehaviorManual = DpmBehavior("manual") + DpmBehaviorAutomated = DpmBehavior("automated") +) + +func init() { + t["DpmBehavior"] = reflect.TypeOf((*DpmBehavior)(nil)).Elem() +} + +type DrsBehavior string + +const ( + DrsBehaviorManual = DrsBehavior("manual") + DrsBehaviorPartiallyAutomated = DrsBehavior("partiallyAutomated") + DrsBehaviorFullyAutomated = DrsBehavior("fullyAutomated") +) + +func init() { + t["DrsBehavior"] = reflect.TypeOf((*DrsBehavior)(nil)).Elem() +} + +type DrsInjectorWorkloadCorrelationState string + +const ( + DrsInjectorWorkloadCorrelationStateCorrelated = DrsInjectorWorkloadCorrelationState("Correlated") + DrsInjectorWorkloadCorrelationStateUncorrelated = DrsInjectorWorkloadCorrelationState("Uncorrelated") +) + +func init() { + t["DrsInjectorWorkloadCorrelationState"] = reflect.TypeOf((*DrsInjectorWorkloadCorrelationState)(nil)).Elem() +} + +type DrsRecommendationReasonCode string + +const ( + DrsRecommendationReasonCodeFairnessCpuAvg = DrsRecommendationReasonCode("fairnessCpuAvg") + DrsRecommendationReasonCodeFairnessMemAvg = DrsRecommendationReasonCode("fairnessMemAvg") + DrsRecommendationReasonCodeJointAffin = DrsRecommendationReasonCode("jointAffin") + DrsRecommendationReasonCodeAntiAffin = DrsRecommendationReasonCode("antiAffin") + DrsRecommendationReasonCodeHostMaint = DrsRecommendationReasonCode("hostMaint") +) + +func init() { + t["DrsRecommendationReasonCode"] = reflect.TypeOf((*DrsRecommendationReasonCode)(nil)).Elem() +} + +type DvsFilterOnFailure string + +const ( + DvsFilterOnFailureFailOpen = DvsFilterOnFailure("failOpen") + DvsFilterOnFailureFailClosed = DvsFilterOnFailure("failClosed") +) + +func init() { + t["DvsFilterOnFailure"] = reflect.TypeOf((*DvsFilterOnFailure)(nil)).Elem() +} + +type DvsNetworkRuleDirectionType string + +const ( + DvsNetworkRuleDirectionTypeIncomingPackets = DvsNetworkRuleDirectionType("incomingPackets") + DvsNetworkRuleDirectionTypeOutgoingPackets = DvsNetworkRuleDirectionType("outgoingPackets") + DvsNetworkRuleDirectionTypeBoth = DvsNetworkRuleDirectionType("both") +) + +func init() { + t["DvsNetworkRuleDirectionType"] = reflect.TypeOf((*DvsNetworkRuleDirectionType)(nil)).Elem() +} + +type EntityImportType string + +const ( + EntityImportTypeCreateEntityWithNewIdentifier = EntityImportType("createEntityWithNewIdentifier") + EntityImportTypeCreateEntityWithOriginalIdentifier = EntityImportType("createEntityWithOriginalIdentifier") + EntityImportTypeApplyToEntitySpecified = EntityImportType("applyToEntitySpecified") +) + +func init() { + t["EntityImportType"] = reflect.TypeOf((*EntityImportType)(nil)).Elem() +} + +type EntityType string + +const ( + EntityTypeDistributedVirtualSwitch = EntityType("distributedVirtualSwitch") + EntityTypeDistributedVirtualPortgroup = EntityType("distributedVirtualPortgroup") +) + +func init() { + t["EntityType"] = reflect.TypeOf((*EntityType)(nil)).Elem() +} + +type EventAlarmExpressionComparisonOperator string + +const ( + EventAlarmExpressionComparisonOperatorEquals = EventAlarmExpressionComparisonOperator("equals") + EventAlarmExpressionComparisonOperatorNotEqualTo = EventAlarmExpressionComparisonOperator("notEqualTo") + EventAlarmExpressionComparisonOperatorStartsWith = EventAlarmExpressionComparisonOperator("startsWith") + EventAlarmExpressionComparisonOperatorDoesNotStartWith = EventAlarmExpressionComparisonOperator("doesNotStartWith") + EventAlarmExpressionComparisonOperatorEndsWith = EventAlarmExpressionComparisonOperator("endsWith") + EventAlarmExpressionComparisonOperatorDoesNotEndWith = EventAlarmExpressionComparisonOperator("doesNotEndWith") +) + +func init() { + t["EventAlarmExpressionComparisonOperator"] = reflect.TypeOf((*EventAlarmExpressionComparisonOperator)(nil)).Elem() +} + +type EventCategory string + +const ( + EventCategoryInfo = EventCategory("info") + EventCategoryWarning = EventCategory("warning") + EventCategoryError = EventCategory("error") + EventCategoryUser = EventCategory("user") +) + +func init() { + t["EventCategory"] = reflect.TypeOf((*EventCategory)(nil)).Elem() +} + +type EventEventSeverity string + +const ( + EventEventSeverityError = EventEventSeverity("error") + EventEventSeverityWarning = EventEventSeverity("warning") + EventEventSeverityInfo = EventEventSeverity("info") + EventEventSeverityUser = EventEventSeverity("user") +) + +func init() { + t["EventEventSeverity"] = reflect.TypeOf((*EventEventSeverity)(nil)).Elem() +} + +type EventFilterSpecRecursionOption string + +const ( + EventFilterSpecRecursionOptionSelf = EventFilterSpecRecursionOption("self") + EventFilterSpecRecursionOptionChildren = EventFilterSpecRecursionOption("children") + EventFilterSpecRecursionOptionAll = EventFilterSpecRecursionOption("all") +) + +func init() { + t["EventFilterSpecRecursionOption"] = reflect.TypeOf((*EventFilterSpecRecursionOption)(nil)).Elem() +} + +type FibreChannelPortType string + +const ( + FibreChannelPortTypeFabric = FibreChannelPortType("fabric") + FibreChannelPortTypeLoop = FibreChannelPortType("loop") + FibreChannelPortTypePointToPoint = FibreChannelPortType("pointToPoint") + FibreChannelPortTypeUnknown = FibreChannelPortType("unknown") +) + +func init() { + t["FibreChannelPortType"] = reflect.TypeOf((*FibreChannelPortType)(nil)).Elem() +} + +type FileSystemMountInfoVStorageSupportStatus string + +const ( + FileSystemMountInfoVStorageSupportStatusVStorageSupported = FileSystemMountInfoVStorageSupportStatus("vStorageSupported") + FileSystemMountInfoVStorageSupportStatusVStorageUnsupported = FileSystemMountInfoVStorageSupportStatus("vStorageUnsupported") + FileSystemMountInfoVStorageSupportStatusVStorageUnknown = FileSystemMountInfoVStorageSupportStatus("vStorageUnknown") +) + +func init() { + t["FileSystemMountInfoVStorageSupportStatus"] = reflect.TypeOf((*FileSystemMountInfoVStorageSupportStatus)(nil)).Elem() +} + +type FtIssuesOnHostHostSelectionType string + +const ( + FtIssuesOnHostHostSelectionTypeUser = FtIssuesOnHostHostSelectionType("user") + FtIssuesOnHostHostSelectionTypeVc = FtIssuesOnHostHostSelectionType("vc") + FtIssuesOnHostHostSelectionTypeDrs = FtIssuesOnHostHostSelectionType("drs") +) + +func init() { + t["FtIssuesOnHostHostSelectionType"] = reflect.TypeOf((*FtIssuesOnHostHostSelectionType)(nil)).Elem() +} + +type GuestFileType string + +const ( + GuestFileTypeFile = GuestFileType("file") + GuestFileTypeDirectory = GuestFileType("directory") + GuestFileTypeSymlink = GuestFileType("symlink") +) + +func init() { + t["GuestFileType"] = reflect.TypeOf((*GuestFileType)(nil)).Elem() +} + +type GuestInfoAppStateType string + +const ( + GuestInfoAppStateTypeNone = GuestInfoAppStateType("none") + GuestInfoAppStateTypeAppStateOk = GuestInfoAppStateType("appStateOk") + GuestInfoAppStateTypeAppStateNeedReset = GuestInfoAppStateType("appStateNeedReset") +) + +func init() { + t["GuestInfoAppStateType"] = reflect.TypeOf((*GuestInfoAppStateType)(nil)).Elem() +} + +type GuestOsDescriptorFirmwareType string + +const ( + GuestOsDescriptorFirmwareTypeBios = GuestOsDescriptorFirmwareType("bios") + GuestOsDescriptorFirmwareTypeEfi = GuestOsDescriptorFirmwareType("efi") +) + +func init() { + t["GuestOsDescriptorFirmwareType"] = reflect.TypeOf((*GuestOsDescriptorFirmwareType)(nil)).Elem() +} + +type GuestOsDescriptorSupportLevel string + +const ( + GuestOsDescriptorSupportLevelExperimental = GuestOsDescriptorSupportLevel("experimental") + GuestOsDescriptorSupportLevelLegacy = GuestOsDescriptorSupportLevel("legacy") + GuestOsDescriptorSupportLevelTerminated = GuestOsDescriptorSupportLevel("terminated") + GuestOsDescriptorSupportLevelSupported = GuestOsDescriptorSupportLevel("supported") + GuestOsDescriptorSupportLevelUnsupported = GuestOsDescriptorSupportLevel("unsupported") + GuestOsDescriptorSupportLevelDeprecated = GuestOsDescriptorSupportLevel("deprecated") + GuestOsDescriptorSupportLevelTechPreview = GuestOsDescriptorSupportLevel("techPreview") +) + +func init() { + t["GuestOsDescriptorSupportLevel"] = reflect.TypeOf((*GuestOsDescriptorSupportLevel)(nil)).Elem() +} + +type GuestRegKeyWowSpec string + +const ( + GuestRegKeyWowSpecWOWNative = GuestRegKeyWowSpec("WOWNative") + GuestRegKeyWowSpecWOW32 = GuestRegKeyWowSpec("WOW32") + GuestRegKeyWowSpecWOW64 = GuestRegKeyWowSpec("WOW64") +) + +func init() { + t["GuestRegKeyWowSpec"] = reflect.TypeOf((*GuestRegKeyWowSpec)(nil)).Elem() +} + +type HostAccessMode string + +const ( + HostAccessModeAccessNone = HostAccessMode("accessNone") + HostAccessModeAccessAdmin = HostAccessMode("accessAdmin") + HostAccessModeAccessNoAccess = HostAccessMode("accessNoAccess") + HostAccessModeAccessReadOnly = HostAccessMode("accessReadOnly") + HostAccessModeAccessOther = HostAccessMode("accessOther") +) + +func init() { + t["HostAccessMode"] = reflect.TypeOf((*HostAccessMode)(nil)).Elem() +} + +type HostActiveDirectoryAuthenticationCertificateDigest string + +const ( + HostActiveDirectoryAuthenticationCertificateDigestSHA1 = HostActiveDirectoryAuthenticationCertificateDigest("SHA1") +) + +func init() { + t["HostActiveDirectoryAuthenticationCertificateDigest"] = reflect.TypeOf((*HostActiveDirectoryAuthenticationCertificateDigest)(nil)).Elem() +} + +type HostActiveDirectoryInfoDomainMembershipStatus string + +const ( + HostActiveDirectoryInfoDomainMembershipStatusUnknown = HostActiveDirectoryInfoDomainMembershipStatus("unknown") + HostActiveDirectoryInfoDomainMembershipStatusOk = HostActiveDirectoryInfoDomainMembershipStatus("ok") + HostActiveDirectoryInfoDomainMembershipStatusNoServers = HostActiveDirectoryInfoDomainMembershipStatus("noServers") + HostActiveDirectoryInfoDomainMembershipStatusClientTrustBroken = HostActiveDirectoryInfoDomainMembershipStatus("clientTrustBroken") + HostActiveDirectoryInfoDomainMembershipStatusServerTrustBroken = HostActiveDirectoryInfoDomainMembershipStatus("serverTrustBroken") + HostActiveDirectoryInfoDomainMembershipStatusInconsistentTrust = HostActiveDirectoryInfoDomainMembershipStatus("inconsistentTrust") + HostActiveDirectoryInfoDomainMembershipStatusOtherProblem = HostActiveDirectoryInfoDomainMembershipStatus("otherProblem") +) + +func init() { + t["HostActiveDirectoryInfoDomainMembershipStatus"] = reflect.TypeOf((*HostActiveDirectoryInfoDomainMembershipStatus)(nil)).Elem() +} + +type HostCapabilityFtUnsupportedReason string + +const ( + HostCapabilityFtUnsupportedReasonVMotionNotLicensed = HostCapabilityFtUnsupportedReason("vMotionNotLicensed") + HostCapabilityFtUnsupportedReasonMissingVMotionNic = HostCapabilityFtUnsupportedReason("missingVMotionNic") + HostCapabilityFtUnsupportedReasonMissingFTLoggingNic = HostCapabilityFtUnsupportedReason("missingFTLoggingNic") + HostCapabilityFtUnsupportedReasonFtNotLicensed = HostCapabilityFtUnsupportedReason("ftNotLicensed") + HostCapabilityFtUnsupportedReasonHaAgentIssue = HostCapabilityFtUnsupportedReason("haAgentIssue") + HostCapabilityFtUnsupportedReasonUnsupportedProduct = HostCapabilityFtUnsupportedReason("unsupportedProduct") + HostCapabilityFtUnsupportedReasonCpuHvUnsupported = HostCapabilityFtUnsupportedReason("cpuHvUnsupported") + HostCapabilityFtUnsupportedReasonCpuHwmmuUnsupported = HostCapabilityFtUnsupportedReason("cpuHwmmuUnsupported") + HostCapabilityFtUnsupportedReasonCpuHvDisabled = HostCapabilityFtUnsupportedReason("cpuHvDisabled") +) + +func init() { + t["HostCapabilityFtUnsupportedReason"] = reflect.TypeOf((*HostCapabilityFtUnsupportedReason)(nil)).Elem() +} + +type HostCapabilityVmDirectPathGen2UnsupportedReason string + +const ( + HostCapabilityVmDirectPathGen2UnsupportedReasonHostNptIncompatibleProduct = HostCapabilityVmDirectPathGen2UnsupportedReason("hostNptIncompatibleProduct") + HostCapabilityVmDirectPathGen2UnsupportedReasonHostNptIncompatibleHardware = HostCapabilityVmDirectPathGen2UnsupportedReason("hostNptIncompatibleHardware") + HostCapabilityVmDirectPathGen2UnsupportedReasonHostNptDisabled = HostCapabilityVmDirectPathGen2UnsupportedReason("hostNptDisabled") +) + +func init() { + t["HostCapabilityVmDirectPathGen2UnsupportedReason"] = reflect.TypeOf((*HostCapabilityVmDirectPathGen2UnsupportedReason)(nil)).Elem() +} + +type HostCertificateManagerCertificateInfoCertificateStatus string + +const ( + HostCertificateManagerCertificateInfoCertificateStatusUnknown = HostCertificateManagerCertificateInfoCertificateStatus("unknown") + HostCertificateManagerCertificateInfoCertificateStatusExpired = HostCertificateManagerCertificateInfoCertificateStatus("expired") + HostCertificateManagerCertificateInfoCertificateStatusExpiring = HostCertificateManagerCertificateInfoCertificateStatus("expiring") + HostCertificateManagerCertificateInfoCertificateStatusExpiringShortly = HostCertificateManagerCertificateInfoCertificateStatus("expiringShortly") + HostCertificateManagerCertificateInfoCertificateStatusExpirationImminent = HostCertificateManagerCertificateInfoCertificateStatus("expirationImminent") + HostCertificateManagerCertificateInfoCertificateStatusGood = HostCertificateManagerCertificateInfoCertificateStatus("good") +) + +func init() { + t["HostCertificateManagerCertificateInfoCertificateStatus"] = reflect.TypeOf((*HostCertificateManagerCertificateInfoCertificateStatus)(nil)).Elem() +} + +type HostConfigChangeMode string + +const ( + HostConfigChangeModeModify = HostConfigChangeMode("modify") + HostConfigChangeModeReplace = HostConfigChangeMode("replace") +) + +func init() { + t["HostConfigChangeMode"] = reflect.TypeOf((*HostConfigChangeMode)(nil)).Elem() +} + +type HostConfigChangeOperation string + +const ( + HostConfigChangeOperationAdd = HostConfigChangeOperation("add") + HostConfigChangeOperationRemove = HostConfigChangeOperation("remove") + HostConfigChangeOperationEdit = HostConfigChangeOperation("edit") + HostConfigChangeOperationIgnore = HostConfigChangeOperation("ignore") +) + +func init() { + t["HostConfigChangeOperation"] = reflect.TypeOf((*HostConfigChangeOperation)(nil)).Elem() +} + +type HostCpuPackageVendor string + +const ( + HostCpuPackageVendorUnknown = HostCpuPackageVendor("unknown") + HostCpuPackageVendorIntel = HostCpuPackageVendor("intel") + HostCpuPackageVendorAmd = HostCpuPackageVendor("amd") +) + +func init() { + t["HostCpuPackageVendor"] = reflect.TypeOf((*HostCpuPackageVendor)(nil)).Elem() +} + +type HostCpuPowerManagementInfoPolicyType string + +const ( + HostCpuPowerManagementInfoPolicyTypeOff = HostCpuPowerManagementInfoPolicyType("off") + HostCpuPowerManagementInfoPolicyTypeStaticPolicy = HostCpuPowerManagementInfoPolicyType("staticPolicy") + HostCpuPowerManagementInfoPolicyTypeDynamicPolicy = HostCpuPowerManagementInfoPolicyType("dynamicPolicy") +) + +func init() { + t["HostCpuPowerManagementInfoPolicyType"] = reflect.TypeOf((*HostCpuPowerManagementInfoPolicyType)(nil)).Elem() +} + +type HostDasErrorEventHostDasErrorReason string + +const ( + HostDasErrorEventHostDasErrorReasonConfigFailed = HostDasErrorEventHostDasErrorReason("configFailed") + HostDasErrorEventHostDasErrorReasonTimeout = HostDasErrorEventHostDasErrorReason("timeout") + HostDasErrorEventHostDasErrorReasonCommunicationInitFailed = HostDasErrorEventHostDasErrorReason("communicationInitFailed") + HostDasErrorEventHostDasErrorReasonHealthCheckScriptFailed = HostDasErrorEventHostDasErrorReason("healthCheckScriptFailed") + HostDasErrorEventHostDasErrorReasonAgentFailed = HostDasErrorEventHostDasErrorReason("agentFailed") + HostDasErrorEventHostDasErrorReasonAgentShutdown = HostDasErrorEventHostDasErrorReason("agentShutdown") + HostDasErrorEventHostDasErrorReasonIsolationAddressUnpingable = HostDasErrorEventHostDasErrorReason("isolationAddressUnpingable") + HostDasErrorEventHostDasErrorReasonOther = HostDasErrorEventHostDasErrorReason("other") +) + +func init() { + t["HostDasErrorEventHostDasErrorReason"] = reflect.TypeOf((*HostDasErrorEventHostDasErrorReason)(nil)).Elem() +} + +type HostDigestInfoDigestMethodType string + +const ( + HostDigestInfoDigestMethodTypeSHA1 = HostDigestInfoDigestMethodType("SHA1") + HostDigestInfoDigestMethodTypeMD5 = HostDigestInfoDigestMethodType("MD5") +) + +func init() { + t["HostDigestInfoDigestMethodType"] = reflect.TypeOf((*HostDigestInfoDigestMethodType)(nil)).Elem() +} + +type HostDisconnectedEventReasonCode string + +const ( + HostDisconnectedEventReasonCodeSslThumbprintVerifyFailed = HostDisconnectedEventReasonCode("sslThumbprintVerifyFailed") + HostDisconnectedEventReasonCodeLicenseExpired = HostDisconnectedEventReasonCode("licenseExpired") + HostDisconnectedEventReasonCodeAgentUpgrade = HostDisconnectedEventReasonCode("agentUpgrade") + HostDisconnectedEventReasonCodeUserRequest = HostDisconnectedEventReasonCode("userRequest") + HostDisconnectedEventReasonCodeInsufficientLicenses = HostDisconnectedEventReasonCode("insufficientLicenses") + HostDisconnectedEventReasonCodeAgentOutOfDate = HostDisconnectedEventReasonCode("agentOutOfDate") + HostDisconnectedEventReasonCodePasswordDecryptFailure = HostDisconnectedEventReasonCode("passwordDecryptFailure") + HostDisconnectedEventReasonCodeUnknown = HostDisconnectedEventReasonCode("unknown") + HostDisconnectedEventReasonCodeVcVRAMCapacityExceeded = HostDisconnectedEventReasonCode("vcVRAMCapacityExceeded") +) + +func init() { + t["HostDisconnectedEventReasonCode"] = reflect.TypeOf((*HostDisconnectedEventReasonCode)(nil)).Elem() +} + +type HostDiskPartitionInfoPartitionFormat string + +const ( + HostDiskPartitionInfoPartitionFormatGpt = HostDiskPartitionInfoPartitionFormat("gpt") + HostDiskPartitionInfoPartitionFormatMbr = HostDiskPartitionInfoPartitionFormat("mbr") + HostDiskPartitionInfoPartitionFormatUnknown = HostDiskPartitionInfoPartitionFormat("unknown") +) + +func init() { + t["HostDiskPartitionInfoPartitionFormat"] = reflect.TypeOf((*HostDiskPartitionInfoPartitionFormat)(nil)).Elem() +} + +type HostDiskPartitionInfoType string + +const ( + HostDiskPartitionInfoTypeNone = HostDiskPartitionInfoType("none") + HostDiskPartitionInfoTypeVmfs = HostDiskPartitionInfoType("vmfs") + HostDiskPartitionInfoTypeLinuxNative = HostDiskPartitionInfoType("linuxNative") + HostDiskPartitionInfoTypeLinuxSwap = HostDiskPartitionInfoType("linuxSwap") + HostDiskPartitionInfoTypeExtended = HostDiskPartitionInfoType("extended") + HostDiskPartitionInfoTypeNtfs = HostDiskPartitionInfoType("ntfs") + HostDiskPartitionInfoTypeVmkDiagnostic = HostDiskPartitionInfoType("vmkDiagnostic") + HostDiskPartitionInfoTypeVffs = HostDiskPartitionInfoType("vffs") +) + +func init() { + t["HostDiskPartitionInfoType"] = reflect.TypeOf((*HostDiskPartitionInfoType)(nil)).Elem() +} + +type HostFeatureVersionKey string + +const ( + HostFeatureVersionKeyFaultTolerance = HostFeatureVersionKey("faultTolerance") +) + +func init() { + t["HostFeatureVersionKey"] = reflect.TypeOf((*HostFeatureVersionKey)(nil)).Elem() +} + +type HostFileSystemVolumeFileSystemType string + +const ( + HostFileSystemVolumeFileSystemTypeVMFS = HostFileSystemVolumeFileSystemType("VMFS") + HostFileSystemVolumeFileSystemTypeNFS = HostFileSystemVolumeFileSystemType("NFS") + HostFileSystemVolumeFileSystemTypeNFS41 = HostFileSystemVolumeFileSystemType("NFS41") + HostFileSystemVolumeFileSystemTypeCIFS = HostFileSystemVolumeFileSystemType("CIFS") + HostFileSystemVolumeFileSystemTypeVsan = HostFileSystemVolumeFileSystemType("vsan") + HostFileSystemVolumeFileSystemTypeVFFS = HostFileSystemVolumeFileSystemType("VFFS") + HostFileSystemVolumeFileSystemTypeVVOL = HostFileSystemVolumeFileSystemType("VVOL") + HostFileSystemVolumeFileSystemTypeOTHER = HostFileSystemVolumeFileSystemType("OTHER") +) + +func init() { + t["HostFileSystemVolumeFileSystemType"] = reflect.TypeOf((*HostFileSystemVolumeFileSystemType)(nil)).Elem() +} + +type HostFirewallRuleDirection string + +const ( + HostFirewallRuleDirectionInbound = HostFirewallRuleDirection("inbound") + HostFirewallRuleDirectionOutbound = HostFirewallRuleDirection("outbound") +) + +func init() { + t["HostFirewallRuleDirection"] = reflect.TypeOf((*HostFirewallRuleDirection)(nil)).Elem() +} + +type HostFirewallRulePortType string + +const ( + HostFirewallRulePortTypeSrc = HostFirewallRulePortType("src") + HostFirewallRulePortTypeDst = HostFirewallRulePortType("dst") +) + +func init() { + t["HostFirewallRulePortType"] = reflect.TypeOf((*HostFirewallRulePortType)(nil)).Elem() +} + +type HostFirewallRuleProtocol string + +const ( + HostFirewallRuleProtocolTcp = HostFirewallRuleProtocol("tcp") + HostFirewallRuleProtocolUdp = HostFirewallRuleProtocol("udp") +) + +func init() { + t["HostFirewallRuleProtocol"] = reflect.TypeOf((*HostFirewallRuleProtocol)(nil)).Elem() +} + +type HostGraphicsInfoGraphicsType string + +const ( + HostGraphicsInfoGraphicsTypeBasic = HostGraphicsInfoGraphicsType("basic") + HostGraphicsInfoGraphicsTypeShared = HostGraphicsInfoGraphicsType("shared") + HostGraphicsInfoGraphicsTypeDirect = HostGraphicsInfoGraphicsType("direct") +) + +func init() { + t["HostGraphicsInfoGraphicsType"] = reflect.TypeOf((*HostGraphicsInfoGraphicsType)(nil)).Elem() +} + +type HostHardwareElementStatus string + +const ( + HostHardwareElementStatusUnknown = HostHardwareElementStatus("Unknown") + HostHardwareElementStatusGreen = HostHardwareElementStatus("Green") + HostHardwareElementStatusYellow = HostHardwareElementStatus("Yellow") + HostHardwareElementStatusRed = HostHardwareElementStatus("Red") +) + +func init() { + t["HostHardwareElementStatus"] = reflect.TypeOf((*HostHardwareElementStatus)(nil)).Elem() +} + +type HostHasComponentFailureHostComponentType string + +const ( + HostHasComponentFailureHostComponentTypeDatastore = HostHasComponentFailureHostComponentType("Datastore") +) + +func init() { + t["HostHasComponentFailureHostComponentType"] = reflect.TypeOf((*HostHasComponentFailureHostComponentType)(nil)).Elem() +} + +type HostImageAcceptanceLevel string + +const ( + HostImageAcceptanceLevelVmware_certified = HostImageAcceptanceLevel("vmware_certified") + HostImageAcceptanceLevelVmware_accepted = HostImageAcceptanceLevel("vmware_accepted") + HostImageAcceptanceLevelPartner = HostImageAcceptanceLevel("partner") + HostImageAcceptanceLevelCommunity = HostImageAcceptanceLevel("community") +) + +func init() { + t["HostImageAcceptanceLevel"] = reflect.TypeOf((*HostImageAcceptanceLevel)(nil)).Elem() +} + +type HostIncompatibleForFaultToleranceReason string + +const ( + HostIncompatibleForFaultToleranceReasonProduct = HostIncompatibleForFaultToleranceReason("product") + HostIncompatibleForFaultToleranceReasonProcessor = HostIncompatibleForFaultToleranceReason("processor") +) + +func init() { + t["HostIncompatibleForFaultToleranceReason"] = reflect.TypeOf((*HostIncompatibleForFaultToleranceReason)(nil)).Elem() +} + +type HostIncompatibleForRecordReplayReason string + +const ( + HostIncompatibleForRecordReplayReasonProduct = HostIncompatibleForRecordReplayReason("product") + HostIncompatibleForRecordReplayReasonProcessor = HostIncompatibleForRecordReplayReason("processor") +) + +func init() { + t["HostIncompatibleForRecordReplayReason"] = reflect.TypeOf((*HostIncompatibleForRecordReplayReason)(nil)).Elem() +} + +type HostInternetScsiHbaChapAuthenticationType string + +const ( + HostInternetScsiHbaChapAuthenticationTypeChapProhibited = HostInternetScsiHbaChapAuthenticationType("chapProhibited") + HostInternetScsiHbaChapAuthenticationTypeChapDiscouraged = HostInternetScsiHbaChapAuthenticationType("chapDiscouraged") + HostInternetScsiHbaChapAuthenticationTypeChapPreferred = HostInternetScsiHbaChapAuthenticationType("chapPreferred") + HostInternetScsiHbaChapAuthenticationTypeChapRequired = HostInternetScsiHbaChapAuthenticationType("chapRequired") +) + +func init() { + t["HostInternetScsiHbaChapAuthenticationType"] = reflect.TypeOf((*HostInternetScsiHbaChapAuthenticationType)(nil)).Elem() +} + +type HostInternetScsiHbaDigestType string + +const ( + HostInternetScsiHbaDigestTypeDigestProhibited = HostInternetScsiHbaDigestType("digestProhibited") + HostInternetScsiHbaDigestTypeDigestDiscouraged = HostInternetScsiHbaDigestType("digestDiscouraged") + HostInternetScsiHbaDigestTypeDigestPreferred = HostInternetScsiHbaDigestType("digestPreferred") + HostInternetScsiHbaDigestTypeDigestRequired = HostInternetScsiHbaDigestType("digestRequired") +) + +func init() { + t["HostInternetScsiHbaDigestType"] = reflect.TypeOf((*HostInternetScsiHbaDigestType)(nil)).Elem() +} + +type HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType string + +const ( + HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationTypeDHCP = HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType("DHCP") + HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationTypeAutoConfigured = HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType("AutoConfigured") + HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationTypeStatic = HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType("Static") + HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationTypeOther = HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType("Other") +) + +func init() { + t["HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType"] = reflect.TypeOf((*HostInternetScsiHbaIscsiIpv6AddressAddressConfigurationType)(nil)).Elem() +} + +type HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperation string + +const ( + HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperationAdd = HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperation("add") + HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperationRemove = HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperation("remove") +) + +func init() { + t["HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperation"] = reflect.TypeOf((*HostInternetScsiHbaIscsiIpv6AddressIPv6AddressOperation)(nil)).Elem() +} + +type HostInternetScsiHbaNetworkBindingSupportType string + +const ( + HostInternetScsiHbaNetworkBindingSupportTypeNotsupported = HostInternetScsiHbaNetworkBindingSupportType("notsupported") + HostInternetScsiHbaNetworkBindingSupportTypeOptional = HostInternetScsiHbaNetworkBindingSupportType("optional") + HostInternetScsiHbaNetworkBindingSupportTypeRequired = HostInternetScsiHbaNetworkBindingSupportType("required") +) + +func init() { + t["HostInternetScsiHbaNetworkBindingSupportType"] = reflect.TypeOf((*HostInternetScsiHbaNetworkBindingSupportType)(nil)).Elem() +} + +type HostInternetScsiHbaStaticTargetTargetDiscoveryMethod string + +const ( + HostInternetScsiHbaStaticTargetTargetDiscoveryMethodStaticMethod = HostInternetScsiHbaStaticTargetTargetDiscoveryMethod("staticMethod") + HostInternetScsiHbaStaticTargetTargetDiscoveryMethodSendTargetMethod = HostInternetScsiHbaStaticTargetTargetDiscoveryMethod("sendTargetMethod") + HostInternetScsiHbaStaticTargetTargetDiscoveryMethodSlpMethod = HostInternetScsiHbaStaticTargetTargetDiscoveryMethod("slpMethod") + HostInternetScsiHbaStaticTargetTargetDiscoveryMethodIsnsMethod = HostInternetScsiHbaStaticTargetTargetDiscoveryMethod("isnsMethod") + HostInternetScsiHbaStaticTargetTargetDiscoveryMethodUnknownMethod = HostInternetScsiHbaStaticTargetTargetDiscoveryMethod("unknownMethod") +) + +func init() { + t["HostInternetScsiHbaStaticTargetTargetDiscoveryMethod"] = reflect.TypeOf((*HostInternetScsiHbaStaticTargetTargetDiscoveryMethod)(nil)).Elem() +} + +type HostIpConfigIpV6AddressConfigType string + +const ( + HostIpConfigIpV6AddressConfigTypeOther = HostIpConfigIpV6AddressConfigType("other") + HostIpConfigIpV6AddressConfigTypeManual = HostIpConfigIpV6AddressConfigType("manual") + HostIpConfigIpV6AddressConfigTypeDhcp = HostIpConfigIpV6AddressConfigType("dhcp") + HostIpConfigIpV6AddressConfigTypeLinklayer = HostIpConfigIpV6AddressConfigType("linklayer") + HostIpConfigIpV6AddressConfigTypeRandom = HostIpConfigIpV6AddressConfigType("random") +) + +func init() { + t["HostIpConfigIpV6AddressConfigType"] = reflect.TypeOf((*HostIpConfigIpV6AddressConfigType)(nil)).Elem() +} + +type HostIpConfigIpV6AddressStatus string + +const ( + HostIpConfigIpV6AddressStatusPreferred = HostIpConfigIpV6AddressStatus("preferred") + HostIpConfigIpV6AddressStatusDeprecated = HostIpConfigIpV6AddressStatus("deprecated") + HostIpConfigIpV6AddressStatusInvalid = HostIpConfigIpV6AddressStatus("invalid") + HostIpConfigIpV6AddressStatusInaccessible = HostIpConfigIpV6AddressStatus("inaccessible") + HostIpConfigIpV6AddressStatusUnknown = HostIpConfigIpV6AddressStatus("unknown") + HostIpConfigIpV6AddressStatusTentative = HostIpConfigIpV6AddressStatus("tentative") + HostIpConfigIpV6AddressStatusDuplicate = HostIpConfigIpV6AddressStatus("duplicate") +) + +func init() { + t["HostIpConfigIpV6AddressStatus"] = reflect.TypeOf((*HostIpConfigIpV6AddressStatus)(nil)).Elem() +} + +type HostLicensableResourceKey string + +const ( + HostLicensableResourceKeyNumCpuPackages = HostLicensableResourceKey("numCpuPackages") + HostLicensableResourceKeyNumCpuCores = HostLicensableResourceKey("numCpuCores") + HostLicensableResourceKeyMemorySize = HostLicensableResourceKey("memorySize") + HostLicensableResourceKeyMemoryForVms = HostLicensableResourceKey("memoryForVms") + HostLicensableResourceKeyNumVmsStarted = HostLicensableResourceKey("numVmsStarted") + HostLicensableResourceKeyNumVmsStarting = HostLicensableResourceKey("numVmsStarting") +) + +func init() { + t["HostLicensableResourceKey"] = reflect.TypeOf((*HostLicensableResourceKey)(nil)).Elem() +} + +type HostLockdownMode string + +const ( + HostLockdownModeLockdownDisabled = HostLockdownMode("lockdownDisabled") + HostLockdownModeLockdownNormal = HostLockdownMode("lockdownNormal") + HostLockdownModeLockdownStrict = HostLockdownMode("lockdownStrict") +) + +func init() { + t["HostLockdownMode"] = reflect.TypeOf((*HostLockdownMode)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerFileType string + +const ( + HostLowLevelProvisioningManagerFileTypeFile = HostLowLevelProvisioningManagerFileType("File") + HostLowLevelProvisioningManagerFileTypeVirtualDisk = HostLowLevelProvisioningManagerFileType("VirtualDisk") + HostLowLevelProvisioningManagerFileTypeDirectory = HostLowLevelProvisioningManagerFileType("Directory") +) + +func init() { + t["HostLowLevelProvisioningManagerFileType"] = reflect.TypeOf((*HostLowLevelProvisioningManagerFileType)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerReloadTarget string + +const ( + HostLowLevelProvisioningManagerReloadTargetCurrentConfig = HostLowLevelProvisioningManagerReloadTarget("currentConfig") + HostLowLevelProvisioningManagerReloadTargetSnapshotConfig = HostLowLevelProvisioningManagerReloadTarget("snapshotConfig") +) + +func init() { + t["HostLowLevelProvisioningManagerReloadTarget"] = reflect.TypeOf((*HostLowLevelProvisioningManagerReloadTarget)(nil)).Elem() +} + +type HostMountInfoInaccessibleReason string + +const ( + HostMountInfoInaccessibleReasonAllPathsDown_Start = HostMountInfoInaccessibleReason("AllPathsDown_Start") + HostMountInfoInaccessibleReasonAllPathsDown_Timeout = HostMountInfoInaccessibleReason("AllPathsDown_Timeout") + HostMountInfoInaccessibleReasonPermanentDeviceLoss = HostMountInfoInaccessibleReason("PermanentDeviceLoss") +) + +func init() { + t["HostMountInfoInaccessibleReason"] = reflect.TypeOf((*HostMountInfoInaccessibleReason)(nil)).Elem() +} + +type HostMountMode string + +const ( + HostMountModeReadWrite = HostMountMode("readWrite") + HostMountModeReadOnly = HostMountMode("readOnly") +) + +func init() { + t["HostMountMode"] = reflect.TypeOf((*HostMountMode)(nil)).Elem() +} + +type HostNasVolumeSecurityType string + +const ( + HostNasVolumeSecurityTypeAUTH_SYS = HostNasVolumeSecurityType("AUTH_SYS") + HostNasVolumeSecurityTypeSEC_KRB5 = HostNasVolumeSecurityType("SEC_KRB5") +) + +func init() { + t["HostNasVolumeSecurityType"] = reflect.TypeOf((*HostNasVolumeSecurityType)(nil)).Elem() +} + +type HostNetStackInstanceCongestionControlAlgorithmType string + +const ( + HostNetStackInstanceCongestionControlAlgorithmTypeNewreno = HostNetStackInstanceCongestionControlAlgorithmType("newreno") + HostNetStackInstanceCongestionControlAlgorithmTypeCubic = HostNetStackInstanceCongestionControlAlgorithmType("cubic") +) + +func init() { + t["HostNetStackInstanceCongestionControlAlgorithmType"] = reflect.TypeOf((*HostNetStackInstanceCongestionControlAlgorithmType)(nil)).Elem() +} + +type HostNetStackInstanceSystemStackKey string + +const ( + HostNetStackInstanceSystemStackKeyDefaultTcpipStack = HostNetStackInstanceSystemStackKey("defaultTcpipStack") + HostNetStackInstanceSystemStackKeyVmotion = HostNetStackInstanceSystemStackKey("vmotion") + HostNetStackInstanceSystemStackKeyVSphereProvisioning = HostNetStackInstanceSystemStackKey("vSphereProvisioning") +) + +func init() { + t["HostNetStackInstanceSystemStackKey"] = reflect.TypeOf((*HostNetStackInstanceSystemStackKey)(nil)).Elem() +} + +type HostNumericSensorHealthState string + +const ( + HostNumericSensorHealthStateUnknown = HostNumericSensorHealthState("unknown") + HostNumericSensorHealthStateGreen = HostNumericSensorHealthState("green") + HostNumericSensorHealthStateYellow = HostNumericSensorHealthState("yellow") + HostNumericSensorHealthStateRed = HostNumericSensorHealthState("red") +) + +func init() { + t["HostNumericSensorHealthState"] = reflect.TypeOf((*HostNumericSensorHealthState)(nil)).Elem() +} + +type HostNumericSensorType string + +const ( + HostNumericSensorTypeFan = HostNumericSensorType("fan") + HostNumericSensorTypePower = HostNumericSensorType("power") + HostNumericSensorTypeTemperature = HostNumericSensorType("temperature") + HostNumericSensorTypeVoltage = HostNumericSensorType("voltage") + HostNumericSensorTypeOther = HostNumericSensorType("other") +) + +func init() { + t["HostNumericSensorType"] = reflect.TypeOf((*HostNumericSensorType)(nil)).Elem() +} + +type HostOpaqueSwitchOpaqueSwitchState string + +const ( + HostOpaqueSwitchOpaqueSwitchStateUp = HostOpaqueSwitchOpaqueSwitchState("up") + HostOpaqueSwitchOpaqueSwitchStateWarning = HostOpaqueSwitchOpaqueSwitchState("warning") + HostOpaqueSwitchOpaqueSwitchStateDown = HostOpaqueSwitchOpaqueSwitchState("down") +) + +func init() { + t["HostOpaqueSwitchOpaqueSwitchState"] = reflect.TypeOf((*HostOpaqueSwitchOpaqueSwitchState)(nil)).Elem() +} + +type HostPatchManagerInstallState string + +const ( + HostPatchManagerInstallStateHostRestarted = HostPatchManagerInstallState("hostRestarted") + HostPatchManagerInstallStateImageActive = HostPatchManagerInstallState("imageActive") +) + +func init() { + t["HostPatchManagerInstallState"] = reflect.TypeOf((*HostPatchManagerInstallState)(nil)).Elem() +} + +type HostPatchManagerIntegrityStatus string + +const ( + HostPatchManagerIntegrityStatusValidated = HostPatchManagerIntegrityStatus("validated") + HostPatchManagerIntegrityStatusKeyNotFound = HostPatchManagerIntegrityStatus("keyNotFound") + HostPatchManagerIntegrityStatusKeyRevoked = HostPatchManagerIntegrityStatus("keyRevoked") + HostPatchManagerIntegrityStatusKeyExpired = HostPatchManagerIntegrityStatus("keyExpired") + HostPatchManagerIntegrityStatusDigestMismatch = HostPatchManagerIntegrityStatus("digestMismatch") + HostPatchManagerIntegrityStatusNotEnoughSignatures = HostPatchManagerIntegrityStatus("notEnoughSignatures") + HostPatchManagerIntegrityStatusValidationError = HostPatchManagerIntegrityStatus("validationError") +) + +func init() { + t["HostPatchManagerIntegrityStatus"] = reflect.TypeOf((*HostPatchManagerIntegrityStatus)(nil)).Elem() +} + +type HostPatchManagerReason string + +const ( + HostPatchManagerReasonObsoleted = HostPatchManagerReason("obsoleted") + HostPatchManagerReasonMissingPatch = HostPatchManagerReason("missingPatch") + HostPatchManagerReasonMissingLib = HostPatchManagerReason("missingLib") + HostPatchManagerReasonHasDependentPatch = HostPatchManagerReason("hasDependentPatch") + HostPatchManagerReasonConflictPatch = HostPatchManagerReason("conflictPatch") + HostPatchManagerReasonConflictLib = HostPatchManagerReason("conflictLib") +) + +func init() { + t["HostPatchManagerReason"] = reflect.TypeOf((*HostPatchManagerReason)(nil)).Elem() +} + +type HostPowerOperationType string + +const ( + HostPowerOperationTypePowerOn = HostPowerOperationType("powerOn") + HostPowerOperationTypePowerOff = HostPowerOperationType("powerOff") +) + +func init() { + t["HostPowerOperationType"] = reflect.TypeOf((*HostPowerOperationType)(nil)).Elem() +} + +type HostProfileManagerAnswerFileStatus string + +const ( + HostProfileManagerAnswerFileStatusValid = HostProfileManagerAnswerFileStatus("valid") + HostProfileManagerAnswerFileStatusInvalid = HostProfileManagerAnswerFileStatus("invalid") + HostProfileManagerAnswerFileStatusUnknown = HostProfileManagerAnswerFileStatus("unknown") +) + +func init() { + t["HostProfileManagerAnswerFileStatus"] = reflect.TypeOf((*HostProfileManagerAnswerFileStatus)(nil)).Elem() +} + +type HostProfileManagerTaskListRequirement string + +const ( + HostProfileManagerTaskListRequirementMaintenanceModeRequired = HostProfileManagerTaskListRequirement("maintenanceModeRequired") + HostProfileManagerTaskListRequirementRebootRequired = HostProfileManagerTaskListRequirement("rebootRequired") +) + +func init() { + t["HostProfileManagerTaskListRequirement"] = reflect.TypeOf((*HostProfileManagerTaskListRequirement)(nil)).Elem() +} + +type HostProtocolEndpointPEType string + +const ( + HostProtocolEndpointPETypeBlock = HostProtocolEndpointPEType("block") + HostProtocolEndpointPETypeNas = HostProtocolEndpointPEType("nas") +) + +func init() { + t["HostProtocolEndpointPEType"] = reflect.TypeOf((*HostProtocolEndpointPEType)(nil)).Elem() +} + +type HostReplayUnsupportedReason string + +const ( + HostReplayUnsupportedReasonIncompatibleProduct = HostReplayUnsupportedReason("incompatibleProduct") + HostReplayUnsupportedReasonIncompatibleCpu = HostReplayUnsupportedReason("incompatibleCpu") + HostReplayUnsupportedReasonHvDisabled = HostReplayUnsupportedReason("hvDisabled") + HostReplayUnsupportedReasonCpuidLimitSet = HostReplayUnsupportedReason("cpuidLimitSet") + HostReplayUnsupportedReasonOldBIOS = HostReplayUnsupportedReason("oldBIOS") + HostReplayUnsupportedReasonUnknown = HostReplayUnsupportedReason("unknown") +) + +func init() { + t["HostReplayUnsupportedReason"] = reflect.TypeOf((*HostReplayUnsupportedReason)(nil)).Elem() +} + +type HostRuntimeInfoNetStackInstanceRuntimeInfoState string + +const ( + HostRuntimeInfoNetStackInstanceRuntimeInfoStateInactive = HostRuntimeInfoNetStackInstanceRuntimeInfoState("inactive") + HostRuntimeInfoNetStackInstanceRuntimeInfoStateActive = HostRuntimeInfoNetStackInstanceRuntimeInfoState("active") + HostRuntimeInfoNetStackInstanceRuntimeInfoStateDeactivating = HostRuntimeInfoNetStackInstanceRuntimeInfoState("deactivating") + HostRuntimeInfoNetStackInstanceRuntimeInfoStateActivating = HostRuntimeInfoNetStackInstanceRuntimeInfoState("activating") +) + +func init() { + t["HostRuntimeInfoNetStackInstanceRuntimeInfoState"] = reflect.TypeOf((*HostRuntimeInfoNetStackInstanceRuntimeInfoState)(nil)).Elem() +} + +type HostServicePolicy string + +const ( + HostServicePolicyOn = HostServicePolicy("on") + HostServicePolicyAutomatic = HostServicePolicy("automatic") + HostServicePolicyOff = HostServicePolicy("off") +) + +func init() { + t["HostServicePolicy"] = reflect.TypeOf((*HostServicePolicy)(nil)).Elem() +} + +type HostSnmpAgentCapability string + +const ( + HostSnmpAgentCapabilityCOMPLETE = HostSnmpAgentCapability("COMPLETE") + HostSnmpAgentCapabilityDIAGNOSTICS = HostSnmpAgentCapability("DIAGNOSTICS") + HostSnmpAgentCapabilityCONFIGURATION = HostSnmpAgentCapability("CONFIGURATION") +) + +func init() { + t["HostSnmpAgentCapability"] = reflect.TypeOf((*HostSnmpAgentCapability)(nil)).Elem() +} + +type HostStandbyMode string + +const ( + HostStandbyModeEntering = HostStandbyMode("entering") + HostStandbyModeExiting = HostStandbyMode("exiting") + HostStandbyModeIn = HostStandbyMode("in") + HostStandbyModeNone = HostStandbyMode("none") +) + +func init() { + t["HostStandbyMode"] = reflect.TypeOf((*HostStandbyMode)(nil)).Elem() +} + +type HostSystemConnectionState string + +const ( + HostSystemConnectionStateConnected = HostSystemConnectionState("connected") + HostSystemConnectionStateNotResponding = HostSystemConnectionState("notResponding") + HostSystemConnectionStateDisconnected = HostSystemConnectionState("disconnected") +) + +func init() { + t["HostSystemConnectionState"] = reflect.TypeOf((*HostSystemConnectionState)(nil)).Elem() +} + +type HostSystemIdentificationInfoIdentifier string + +const ( + HostSystemIdentificationInfoIdentifierAssetTag = HostSystemIdentificationInfoIdentifier("AssetTag") + HostSystemIdentificationInfoIdentifierServiceTag = HostSystemIdentificationInfoIdentifier("ServiceTag") + HostSystemIdentificationInfoIdentifierOemSpecificString = HostSystemIdentificationInfoIdentifier("OemSpecificString") +) + +func init() { + t["HostSystemIdentificationInfoIdentifier"] = reflect.TypeOf((*HostSystemIdentificationInfoIdentifier)(nil)).Elem() +} + +type HostSystemPowerState string + +const ( + HostSystemPowerStatePoweredOn = HostSystemPowerState("poweredOn") + HostSystemPowerStatePoweredOff = HostSystemPowerState("poweredOff") + HostSystemPowerStateStandBy = HostSystemPowerState("standBy") + HostSystemPowerStateUnknown = HostSystemPowerState("unknown") +) + +func init() { + t["HostSystemPowerState"] = reflect.TypeOf((*HostSystemPowerState)(nil)).Elem() +} + +type HostUnresolvedVmfsExtentUnresolvedReason string + +const ( + HostUnresolvedVmfsExtentUnresolvedReasonDiskIdMismatch = HostUnresolvedVmfsExtentUnresolvedReason("diskIdMismatch") + HostUnresolvedVmfsExtentUnresolvedReasonUuidConflict = HostUnresolvedVmfsExtentUnresolvedReason("uuidConflict") +) + +func init() { + t["HostUnresolvedVmfsExtentUnresolvedReason"] = reflect.TypeOf((*HostUnresolvedVmfsExtentUnresolvedReason)(nil)).Elem() +} + +type HostUnresolvedVmfsResolutionSpecVmfsUuidResolution string + +const ( + HostUnresolvedVmfsResolutionSpecVmfsUuidResolutionResignature = HostUnresolvedVmfsResolutionSpecVmfsUuidResolution("resignature") + HostUnresolvedVmfsResolutionSpecVmfsUuidResolutionForceMount = HostUnresolvedVmfsResolutionSpecVmfsUuidResolution("forceMount") +) + +func init() { + t["HostUnresolvedVmfsResolutionSpecVmfsUuidResolution"] = reflect.TypeOf((*HostUnresolvedVmfsResolutionSpecVmfsUuidResolution)(nil)).Elem() +} + +type HostVirtualNicManagerNicType string + +const ( + HostVirtualNicManagerNicTypeVmotion = HostVirtualNicManagerNicType("vmotion") + HostVirtualNicManagerNicTypeFaultToleranceLogging = HostVirtualNicManagerNicType("faultToleranceLogging") + HostVirtualNicManagerNicTypeVSphereReplication = HostVirtualNicManagerNicType("vSphereReplication") + HostVirtualNicManagerNicTypeVSphereReplicationNFC = HostVirtualNicManagerNicType("vSphereReplicationNFC") + HostVirtualNicManagerNicTypeManagement = HostVirtualNicManagerNicType("management") + HostVirtualNicManagerNicTypeVsan = HostVirtualNicManagerNicType("vsan") + HostVirtualNicManagerNicTypeVSphereProvisioning = HostVirtualNicManagerNicType("vSphereProvisioning") +) + +func init() { + t["HostVirtualNicManagerNicType"] = reflect.TypeOf((*HostVirtualNicManagerNicType)(nil)).Elem() +} + +type HostVmciAccessManagerMode string + +const ( + HostVmciAccessManagerModeGrant = HostVmciAccessManagerMode("grant") + HostVmciAccessManagerModeReplace = HostVmciAccessManagerMode("replace") + HostVmciAccessManagerModeRevoke = HostVmciAccessManagerMode("revoke") +) + +func init() { + t["HostVmciAccessManagerMode"] = reflect.TypeOf((*HostVmciAccessManagerMode)(nil)).Elem() +} + +type HttpNfcLeaseState string + +const ( + HttpNfcLeaseStateInitializing = HttpNfcLeaseState("initializing") + HttpNfcLeaseStateReady = HttpNfcLeaseState("ready") + HttpNfcLeaseStateDone = HttpNfcLeaseState("done") + HttpNfcLeaseStateError = HttpNfcLeaseState("error") +) + +func init() { + t["HttpNfcLeaseState"] = reflect.TypeOf((*HttpNfcLeaseState)(nil)).Elem() +} + +type IncompatibleHostForVmReplicationIncompatibleReason string + +const ( + IncompatibleHostForVmReplicationIncompatibleReasonRpo = IncompatibleHostForVmReplicationIncompatibleReason("rpo") + IncompatibleHostForVmReplicationIncompatibleReasonNetCompression = IncompatibleHostForVmReplicationIncompatibleReason("netCompression") +) + +func init() { + t["IncompatibleHostForVmReplicationIncompatibleReason"] = reflect.TypeOf((*IncompatibleHostForVmReplicationIncompatibleReason)(nil)).Elem() +} + +type InternetScsiSnsDiscoveryMethod string + +const ( + InternetScsiSnsDiscoveryMethodIsnsStatic = InternetScsiSnsDiscoveryMethod("isnsStatic") + InternetScsiSnsDiscoveryMethodIsnsDhcp = InternetScsiSnsDiscoveryMethod("isnsDhcp") + InternetScsiSnsDiscoveryMethodIsnsSlp = InternetScsiSnsDiscoveryMethod("isnsSlp") +) + +func init() { + t["InternetScsiSnsDiscoveryMethod"] = reflect.TypeOf((*InternetScsiSnsDiscoveryMethod)(nil)).Elem() +} + +type InvalidDasConfigArgumentEntryForInvalidArgument string + +const ( + InvalidDasConfigArgumentEntryForInvalidArgumentAdmissionControl = InvalidDasConfigArgumentEntryForInvalidArgument("admissionControl") + InvalidDasConfigArgumentEntryForInvalidArgumentUserHeartbeatDs = InvalidDasConfigArgumentEntryForInvalidArgument("userHeartbeatDs") + InvalidDasConfigArgumentEntryForInvalidArgumentVmConfig = InvalidDasConfigArgumentEntryForInvalidArgument("vmConfig") +) + +func init() { + t["InvalidDasConfigArgumentEntryForInvalidArgument"] = reflect.TypeOf((*InvalidDasConfigArgumentEntryForInvalidArgument)(nil)).Elem() +} + +type InvalidProfileReferenceHostReason string + +const ( + InvalidProfileReferenceHostReasonIncompatibleVersion = InvalidProfileReferenceHostReason("incompatibleVersion") + InvalidProfileReferenceHostReasonMissingReferenceHost = InvalidProfileReferenceHostReason("missingReferenceHost") +) + +func init() { + t["InvalidProfileReferenceHostReason"] = reflect.TypeOf((*InvalidProfileReferenceHostReason)(nil)).Elem() +} + +type IoFilterOperation string + +const ( + IoFilterOperationInstall = IoFilterOperation("install") + IoFilterOperationUninstall = IoFilterOperation("uninstall") + IoFilterOperationUpgrade = IoFilterOperation("upgrade") +) + +func init() { + t["IoFilterOperation"] = reflect.TypeOf((*IoFilterOperation)(nil)).Elem() +} + +type IscsiPortInfoPathStatus string + +const ( + IscsiPortInfoPathStatusNotUsed = IscsiPortInfoPathStatus("notUsed") + IscsiPortInfoPathStatusActive = IscsiPortInfoPathStatus("active") + IscsiPortInfoPathStatusStandBy = IscsiPortInfoPathStatus("standBy") + IscsiPortInfoPathStatusLastActive = IscsiPortInfoPathStatus("lastActive") +) + +func init() { + t["IscsiPortInfoPathStatus"] = reflect.TypeOf((*IscsiPortInfoPathStatus)(nil)).Elem() +} + +type LatencySensitivitySensitivityLevel string + +const ( + LatencySensitivitySensitivityLevelLow = LatencySensitivitySensitivityLevel("low") + LatencySensitivitySensitivityLevelNormal = LatencySensitivitySensitivityLevel("normal") + LatencySensitivitySensitivityLevelMedium = LatencySensitivitySensitivityLevel("medium") + LatencySensitivitySensitivityLevelHigh = LatencySensitivitySensitivityLevel("high") + LatencySensitivitySensitivityLevelCustom = LatencySensitivitySensitivityLevel("custom") +) + +func init() { + t["LatencySensitivitySensitivityLevel"] = reflect.TypeOf((*LatencySensitivitySensitivityLevel)(nil)).Elem() +} + +type LicenseAssignmentFailedReason string + +const ( + LicenseAssignmentFailedReasonKeyEntityMismatch = LicenseAssignmentFailedReason("keyEntityMismatch") + LicenseAssignmentFailedReasonDowngradeDisallowed = LicenseAssignmentFailedReason("downgradeDisallowed") + LicenseAssignmentFailedReasonInventoryNotManageableByVirtualCenter = LicenseAssignmentFailedReason("inventoryNotManageableByVirtualCenter") + LicenseAssignmentFailedReasonHostsUnmanageableByVirtualCenterWithoutLicenseServer = LicenseAssignmentFailedReason("hostsUnmanageableByVirtualCenterWithoutLicenseServer") +) + +func init() { + t["LicenseAssignmentFailedReason"] = reflect.TypeOf((*LicenseAssignmentFailedReason)(nil)).Elem() +} + +type LicenseFeatureInfoSourceRestriction string + +const ( + LicenseFeatureInfoSourceRestrictionUnrestricted = LicenseFeatureInfoSourceRestriction("unrestricted") + LicenseFeatureInfoSourceRestrictionServed = LicenseFeatureInfoSourceRestriction("served") + LicenseFeatureInfoSourceRestrictionFile = LicenseFeatureInfoSourceRestriction("file") +) + +func init() { + t["LicenseFeatureInfoSourceRestriction"] = reflect.TypeOf((*LicenseFeatureInfoSourceRestriction)(nil)).Elem() +} + +type LicenseFeatureInfoState string + +const ( + LicenseFeatureInfoStateEnabled = LicenseFeatureInfoState("enabled") + LicenseFeatureInfoStateDisabled = LicenseFeatureInfoState("disabled") + LicenseFeatureInfoStateOptional = LicenseFeatureInfoState("optional") +) + +func init() { + t["LicenseFeatureInfoState"] = reflect.TypeOf((*LicenseFeatureInfoState)(nil)).Elem() +} + +type LicenseFeatureInfoUnit string + +const ( + LicenseFeatureInfoUnitHost = LicenseFeatureInfoUnit("host") + LicenseFeatureInfoUnitCpuCore = LicenseFeatureInfoUnit("cpuCore") + LicenseFeatureInfoUnitCpuPackage = LicenseFeatureInfoUnit("cpuPackage") + LicenseFeatureInfoUnitServer = LicenseFeatureInfoUnit("server") + LicenseFeatureInfoUnitVm = LicenseFeatureInfoUnit("vm") +) + +func init() { + t["LicenseFeatureInfoUnit"] = reflect.TypeOf((*LicenseFeatureInfoUnit)(nil)).Elem() +} + +type LicenseManagerLicenseKey string + +const ( + LicenseManagerLicenseKeyEsxFull = LicenseManagerLicenseKey("esxFull") + LicenseManagerLicenseKeyEsxVmtn = LicenseManagerLicenseKey("esxVmtn") + LicenseManagerLicenseKeyEsxExpress = LicenseManagerLicenseKey("esxExpress") + LicenseManagerLicenseKeySan = LicenseManagerLicenseKey("san") + LicenseManagerLicenseKeyIscsi = LicenseManagerLicenseKey("iscsi") + LicenseManagerLicenseKeyNas = LicenseManagerLicenseKey("nas") + LicenseManagerLicenseKeyVsmp = LicenseManagerLicenseKey("vsmp") + LicenseManagerLicenseKeyBackup = LicenseManagerLicenseKey("backup") + LicenseManagerLicenseKeyVc = LicenseManagerLicenseKey("vc") + LicenseManagerLicenseKeyVcExpress = LicenseManagerLicenseKey("vcExpress") + LicenseManagerLicenseKeyEsxHost = LicenseManagerLicenseKey("esxHost") + LicenseManagerLicenseKeyGsxHost = LicenseManagerLicenseKey("gsxHost") + LicenseManagerLicenseKeyServerHost = LicenseManagerLicenseKey("serverHost") + LicenseManagerLicenseKeyDrsPower = LicenseManagerLicenseKey("drsPower") + LicenseManagerLicenseKeyVmotion = LicenseManagerLicenseKey("vmotion") + LicenseManagerLicenseKeyDrs = LicenseManagerLicenseKey("drs") + LicenseManagerLicenseKeyDas = LicenseManagerLicenseKey("das") +) + +func init() { + t["LicenseManagerLicenseKey"] = reflect.TypeOf((*LicenseManagerLicenseKey)(nil)).Elem() +} + +type LicenseManagerState string + +const ( + LicenseManagerStateInitializing = LicenseManagerState("initializing") + LicenseManagerStateNormal = LicenseManagerState("normal") + LicenseManagerStateMarginal = LicenseManagerState("marginal") + LicenseManagerStateFault = LicenseManagerState("fault") +) + +func init() { + t["LicenseManagerState"] = reflect.TypeOf((*LicenseManagerState)(nil)).Elem() +} + +type LicenseReservationInfoState string + +const ( + LicenseReservationInfoStateNotUsed = LicenseReservationInfoState("notUsed") + LicenseReservationInfoStateNoLicense = LicenseReservationInfoState("noLicense") + LicenseReservationInfoStateUnlicensedUse = LicenseReservationInfoState("unlicensedUse") + LicenseReservationInfoStateLicensed = LicenseReservationInfoState("licensed") +) + +func init() { + t["LicenseReservationInfoState"] = reflect.TypeOf((*LicenseReservationInfoState)(nil)).Elem() +} + +type LinkDiscoveryProtocolConfigOperationType string + +const ( + LinkDiscoveryProtocolConfigOperationTypeNone = LinkDiscoveryProtocolConfigOperationType("none") + LinkDiscoveryProtocolConfigOperationTypeListen = LinkDiscoveryProtocolConfigOperationType("listen") + LinkDiscoveryProtocolConfigOperationTypeAdvertise = LinkDiscoveryProtocolConfigOperationType("advertise") + LinkDiscoveryProtocolConfigOperationTypeBoth = LinkDiscoveryProtocolConfigOperationType("both") +) + +func init() { + t["LinkDiscoveryProtocolConfigOperationType"] = reflect.TypeOf((*LinkDiscoveryProtocolConfigOperationType)(nil)).Elem() +} + +type LinkDiscoveryProtocolConfigProtocolType string + +const ( + LinkDiscoveryProtocolConfigProtocolTypeCdp = LinkDiscoveryProtocolConfigProtocolType("cdp") + LinkDiscoveryProtocolConfigProtocolTypeLldp = LinkDiscoveryProtocolConfigProtocolType("lldp") +) + +func init() { + t["LinkDiscoveryProtocolConfigProtocolType"] = reflect.TypeOf((*LinkDiscoveryProtocolConfigProtocolType)(nil)).Elem() +} + +type ManagedEntityStatus string + +const ( + ManagedEntityStatusGray = ManagedEntityStatus("gray") + ManagedEntityStatusGreen = ManagedEntityStatus("green") + ManagedEntityStatusYellow = ManagedEntityStatus("yellow") + ManagedEntityStatusRed = ManagedEntityStatus("red") +) + +func init() { + t["ManagedEntityStatus"] = reflect.TypeOf((*ManagedEntityStatus)(nil)).Elem() +} + +type MetricAlarmOperator string + +const ( + MetricAlarmOperatorIsAbove = MetricAlarmOperator("isAbove") + MetricAlarmOperatorIsBelow = MetricAlarmOperator("isBelow") +) + +func init() { + t["MetricAlarmOperator"] = reflect.TypeOf((*MetricAlarmOperator)(nil)).Elem() +} + +type MultipathState string + +const ( + MultipathStateStandby = MultipathState("standby") + MultipathStateActive = MultipathState("active") + MultipathStateDisabled = MultipathState("disabled") + MultipathStateDead = MultipathState("dead") + MultipathStateUnknown = MultipathState("unknown") +) + +func init() { + t["MultipathState"] = reflect.TypeOf((*MultipathState)(nil)).Elem() +} + +type NetBIOSConfigInfoMode string + +const ( + NetBIOSConfigInfoModeUnknown = NetBIOSConfigInfoMode("unknown") + NetBIOSConfigInfoModeEnabled = NetBIOSConfigInfoMode("enabled") + NetBIOSConfigInfoModeDisabled = NetBIOSConfigInfoMode("disabled") + NetBIOSConfigInfoModeEnabledViaDHCP = NetBIOSConfigInfoMode("enabledViaDHCP") +) + +func init() { + t["NetBIOSConfigInfoMode"] = reflect.TypeOf((*NetBIOSConfigInfoMode)(nil)).Elem() +} + +type NetIpConfigInfoIpAddressOrigin string + +const ( + NetIpConfigInfoIpAddressOriginOther = NetIpConfigInfoIpAddressOrigin("other") + NetIpConfigInfoIpAddressOriginManual = NetIpConfigInfoIpAddressOrigin("manual") + NetIpConfigInfoIpAddressOriginDhcp = NetIpConfigInfoIpAddressOrigin("dhcp") + NetIpConfigInfoIpAddressOriginLinklayer = NetIpConfigInfoIpAddressOrigin("linklayer") + NetIpConfigInfoIpAddressOriginRandom = NetIpConfigInfoIpAddressOrigin("random") +) + +func init() { + t["NetIpConfigInfoIpAddressOrigin"] = reflect.TypeOf((*NetIpConfigInfoIpAddressOrigin)(nil)).Elem() +} + +type NetIpConfigInfoIpAddressStatus string + +const ( + NetIpConfigInfoIpAddressStatusPreferred = NetIpConfigInfoIpAddressStatus("preferred") + NetIpConfigInfoIpAddressStatusDeprecated = NetIpConfigInfoIpAddressStatus("deprecated") + NetIpConfigInfoIpAddressStatusInvalid = NetIpConfigInfoIpAddressStatus("invalid") + NetIpConfigInfoIpAddressStatusInaccessible = NetIpConfigInfoIpAddressStatus("inaccessible") + NetIpConfigInfoIpAddressStatusUnknown = NetIpConfigInfoIpAddressStatus("unknown") + NetIpConfigInfoIpAddressStatusTentative = NetIpConfigInfoIpAddressStatus("tentative") + NetIpConfigInfoIpAddressStatusDuplicate = NetIpConfigInfoIpAddressStatus("duplicate") +) + +func init() { + t["NetIpConfigInfoIpAddressStatus"] = reflect.TypeOf((*NetIpConfigInfoIpAddressStatus)(nil)).Elem() +} + +type NetIpStackInfoEntryType string + +const ( + NetIpStackInfoEntryTypeOther = NetIpStackInfoEntryType("other") + NetIpStackInfoEntryTypeInvalid = NetIpStackInfoEntryType("invalid") + NetIpStackInfoEntryTypeDynamic = NetIpStackInfoEntryType("dynamic") + NetIpStackInfoEntryTypeManual = NetIpStackInfoEntryType("manual") +) + +func init() { + t["NetIpStackInfoEntryType"] = reflect.TypeOf((*NetIpStackInfoEntryType)(nil)).Elem() +} + +type NetIpStackInfoPreference string + +const ( + NetIpStackInfoPreferenceReserved = NetIpStackInfoPreference("reserved") + NetIpStackInfoPreferenceLow = NetIpStackInfoPreference("low") + NetIpStackInfoPreferenceMedium = NetIpStackInfoPreference("medium") + NetIpStackInfoPreferenceHigh = NetIpStackInfoPreference("high") +) + +func init() { + t["NetIpStackInfoPreference"] = reflect.TypeOf((*NetIpStackInfoPreference)(nil)).Elem() +} + +type NotSupportedDeviceForFTDeviceType string + +const ( + NotSupportedDeviceForFTDeviceTypeVirtualVmxnet3 = NotSupportedDeviceForFTDeviceType("virtualVmxnet3") + NotSupportedDeviceForFTDeviceTypeParaVirtualSCSIController = NotSupportedDeviceForFTDeviceType("paraVirtualSCSIController") +) + +func init() { + t["NotSupportedDeviceForFTDeviceType"] = reflect.TypeOf((*NotSupportedDeviceForFTDeviceType)(nil)).Elem() +} + +type NumVirtualCpusIncompatibleReason string + +const ( + NumVirtualCpusIncompatibleReasonRecordReplay = NumVirtualCpusIncompatibleReason("recordReplay") + NumVirtualCpusIncompatibleReasonFaultTolerance = NumVirtualCpusIncompatibleReason("faultTolerance") +) + +func init() { + t["NumVirtualCpusIncompatibleReason"] = reflect.TypeOf((*NumVirtualCpusIncompatibleReason)(nil)).Elem() +} + +type ObjectUpdateKind string + +const ( + ObjectUpdateKindModify = ObjectUpdateKind("modify") + ObjectUpdateKindEnter = ObjectUpdateKind("enter") + ObjectUpdateKindLeave = ObjectUpdateKind("leave") +) + +func init() { + t["ObjectUpdateKind"] = reflect.TypeOf((*ObjectUpdateKind)(nil)).Elem() +} + +type OvfConsumerOstNodeType string + +const ( + OvfConsumerOstNodeTypeEnvelope = OvfConsumerOstNodeType("envelope") + OvfConsumerOstNodeTypeVirtualSystem = OvfConsumerOstNodeType("virtualSystem") + OvfConsumerOstNodeTypeVirtualSystemCollection = OvfConsumerOstNodeType("virtualSystemCollection") +) + +func init() { + t["OvfConsumerOstNodeType"] = reflect.TypeOf((*OvfConsumerOstNodeType)(nil)).Elem() +} + +type OvfCreateImportSpecParamsDiskProvisioningType string + +const ( + OvfCreateImportSpecParamsDiskProvisioningTypeMonolithicSparse = OvfCreateImportSpecParamsDiskProvisioningType("monolithicSparse") + OvfCreateImportSpecParamsDiskProvisioningTypeMonolithicFlat = OvfCreateImportSpecParamsDiskProvisioningType("monolithicFlat") + OvfCreateImportSpecParamsDiskProvisioningTypeTwoGbMaxExtentSparse = OvfCreateImportSpecParamsDiskProvisioningType("twoGbMaxExtentSparse") + OvfCreateImportSpecParamsDiskProvisioningTypeTwoGbMaxExtentFlat = OvfCreateImportSpecParamsDiskProvisioningType("twoGbMaxExtentFlat") + OvfCreateImportSpecParamsDiskProvisioningTypeThin = OvfCreateImportSpecParamsDiskProvisioningType("thin") + OvfCreateImportSpecParamsDiskProvisioningTypeThick = OvfCreateImportSpecParamsDiskProvisioningType("thick") + OvfCreateImportSpecParamsDiskProvisioningTypeSeSparse = OvfCreateImportSpecParamsDiskProvisioningType("seSparse") + OvfCreateImportSpecParamsDiskProvisioningTypeEagerZeroedThick = OvfCreateImportSpecParamsDiskProvisioningType("eagerZeroedThick") + OvfCreateImportSpecParamsDiskProvisioningTypeSparse = OvfCreateImportSpecParamsDiskProvisioningType("sparse") + OvfCreateImportSpecParamsDiskProvisioningTypeFlat = OvfCreateImportSpecParamsDiskProvisioningType("flat") +) + +func init() { + t["OvfCreateImportSpecParamsDiskProvisioningType"] = reflect.TypeOf((*OvfCreateImportSpecParamsDiskProvisioningType)(nil)).Elem() +} + +type PerfFormat string + +const ( + PerfFormatNormal = PerfFormat("normal") + PerfFormatCsv = PerfFormat("csv") +) + +func init() { + t["PerfFormat"] = reflect.TypeOf((*PerfFormat)(nil)).Elem() +} + +type PerfStatsType string + +const ( + PerfStatsTypeAbsolute = PerfStatsType("absolute") + PerfStatsTypeDelta = PerfStatsType("delta") + PerfStatsTypeRate = PerfStatsType("rate") +) + +func init() { + t["PerfStatsType"] = reflect.TypeOf((*PerfStatsType)(nil)).Elem() +} + +type PerfSummaryType string + +const ( + PerfSummaryTypeAverage = PerfSummaryType("average") + PerfSummaryTypeMaximum = PerfSummaryType("maximum") + PerfSummaryTypeMinimum = PerfSummaryType("minimum") + PerfSummaryTypeLatest = PerfSummaryType("latest") + PerfSummaryTypeSummation = PerfSummaryType("summation") + PerfSummaryTypeNone = PerfSummaryType("none") +) + +func init() { + t["PerfSummaryType"] = reflect.TypeOf((*PerfSummaryType)(nil)).Elem() +} + +type PerformanceManagerUnit string + +const ( + PerformanceManagerUnitPercent = PerformanceManagerUnit("percent") + PerformanceManagerUnitKiloBytes = PerformanceManagerUnit("kiloBytes") + PerformanceManagerUnitMegaBytes = PerformanceManagerUnit("megaBytes") + PerformanceManagerUnitMegaHertz = PerformanceManagerUnit("megaHertz") + PerformanceManagerUnitNumber = PerformanceManagerUnit("number") + PerformanceManagerUnitMicrosecond = PerformanceManagerUnit("microsecond") + PerformanceManagerUnitMillisecond = PerformanceManagerUnit("millisecond") + PerformanceManagerUnitSecond = PerformanceManagerUnit("second") + PerformanceManagerUnitKiloBytesPerSecond = PerformanceManagerUnit("kiloBytesPerSecond") + PerformanceManagerUnitMegaBytesPerSecond = PerformanceManagerUnit("megaBytesPerSecond") + PerformanceManagerUnitWatt = PerformanceManagerUnit("watt") + PerformanceManagerUnitJoule = PerformanceManagerUnit("joule") + PerformanceManagerUnitTeraBytes = PerformanceManagerUnit("teraBytes") +) + +func init() { + t["PerformanceManagerUnit"] = reflect.TypeOf((*PerformanceManagerUnit)(nil)).Elem() +} + +type PhysicalNicResourcePoolSchedulerDisallowedReason string + +const ( + PhysicalNicResourcePoolSchedulerDisallowedReasonUserOptOut = PhysicalNicResourcePoolSchedulerDisallowedReason("userOptOut") + PhysicalNicResourcePoolSchedulerDisallowedReasonHardwareUnsupported = PhysicalNicResourcePoolSchedulerDisallowedReason("hardwareUnsupported") +) + +func init() { + t["PhysicalNicResourcePoolSchedulerDisallowedReason"] = reflect.TypeOf((*PhysicalNicResourcePoolSchedulerDisallowedReason)(nil)).Elem() +} + +type PhysicalNicVmDirectPathGen2SupportedMode string + +const ( + PhysicalNicVmDirectPathGen2SupportedModeUpt = PhysicalNicVmDirectPathGen2SupportedMode("upt") +) + +func init() { + t["PhysicalNicVmDirectPathGen2SupportedMode"] = reflect.TypeOf((*PhysicalNicVmDirectPathGen2SupportedMode)(nil)).Elem() +} + +type PlacementAffinityRuleRuleScope string + +const ( + PlacementAffinityRuleRuleScopeCluster = PlacementAffinityRuleRuleScope("cluster") + PlacementAffinityRuleRuleScopeHost = PlacementAffinityRuleRuleScope("host") + PlacementAffinityRuleRuleScopeStoragePod = PlacementAffinityRuleRuleScope("storagePod") + PlacementAffinityRuleRuleScopeDatastore = PlacementAffinityRuleRuleScope("datastore") +) + +func init() { + t["PlacementAffinityRuleRuleScope"] = reflect.TypeOf((*PlacementAffinityRuleRuleScope)(nil)).Elem() +} + +type PlacementAffinityRuleRuleType string + +const ( + PlacementAffinityRuleRuleTypeAffinity = PlacementAffinityRuleRuleType("affinity") + PlacementAffinityRuleRuleTypeAntiAffinity = PlacementAffinityRuleRuleType("antiAffinity") + PlacementAffinityRuleRuleTypeSoftAffinity = PlacementAffinityRuleRuleType("softAffinity") + PlacementAffinityRuleRuleTypeSoftAntiAffinity = PlacementAffinityRuleRuleType("softAntiAffinity") +) + +func init() { + t["PlacementAffinityRuleRuleType"] = reflect.TypeOf((*PlacementAffinityRuleRuleType)(nil)).Elem() +} + +type PlacementSpecPlacementType string + +const ( + PlacementSpecPlacementTypeCreate = PlacementSpecPlacementType("create") + PlacementSpecPlacementTypeReconfigure = PlacementSpecPlacementType("reconfigure") + PlacementSpecPlacementTypeRelocate = PlacementSpecPlacementType("relocate") + PlacementSpecPlacementTypeClone = PlacementSpecPlacementType("clone") +) + +func init() { + t["PlacementSpecPlacementType"] = reflect.TypeOf((*PlacementSpecPlacementType)(nil)).Elem() +} + +type PortGroupConnecteeType string + +const ( + PortGroupConnecteeTypeVirtualMachine = PortGroupConnecteeType("virtualMachine") + PortGroupConnecteeTypeSystemManagement = PortGroupConnecteeType("systemManagement") + PortGroupConnecteeTypeHost = PortGroupConnecteeType("host") + PortGroupConnecteeTypeUnknown = PortGroupConnecteeType("unknown") +) + +func init() { + t["PortGroupConnecteeType"] = reflect.TypeOf((*PortGroupConnecteeType)(nil)).Elem() +} + +type ProfileExecuteResultStatus string + +const ( + ProfileExecuteResultStatusSuccess = ProfileExecuteResultStatus("success") + ProfileExecuteResultStatusNeedInput = ProfileExecuteResultStatus("needInput") + ProfileExecuteResultStatusError = ProfileExecuteResultStatus("error") +) + +func init() { + t["ProfileExecuteResultStatus"] = reflect.TypeOf((*ProfileExecuteResultStatus)(nil)).Elem() +} + +type ProfileNumericComparator string + +const ( + ProfileNumericComparatorLessThan = ProfileNumericComparator("lessThan") + ProfileNumericComparatorLessThanEqual = ProfileNumericComparator("lessThanEqual") + ProfileNumericComparatorEqual = ProfileNumericComparator("equal") + ProfileNumericComparatorNotEqual = ProfileNumericComparator("notEqual") + ProfileNumericComparatorGreaterThanEqual = ProfileNumericComparator("greaterThanEqual") + ProfileNumericComparatorGreaterThan = ProfileNumericComparator("greaterThan") +) + +func init() { + t["ProfileNumericComparator"] = reflect.TypeOf((*ProfileNumericComparator)(nil)).Elem() +} + +type PropertyChangeOp string + +const ( + PropertyChangeOpAdd = PropertyChangeOp("add") + PropertyChangeOpRemove = PropertyChangeOp("remove") + PropertyChangeOpAssign = PropertyChangeOp("assign") + PropertyChangeOpIndirectRemove = PropertyChangeOp("indirectRemove") +) + +func init() { + t["PropertyChangeOp"] = reflect.TypeOf((*PropertyChangeOp)(nil)).Elem() +} + +type QuiesceMode string + +const ( + QuiesceModeApplication = QuiesceMode("application") + QuiesceModeFilesystem = QuiesceMode("filesystem") + QuiesceModeNone = QuiesceMode("none") +) + +func init() { + t["QuiesceMode"] = reflect.TypeOf((*QuiesceMode)(nil)).Elem() +} + +type RecommendationReasonCode string + +const ( + RecommendationReasonCodeFairnessCpuAvg = RecommendationReasonCode("fairnessCpuAvg") + RecommendationReasonCodeFairnessMemAvg = RecommendationReasonCode("fairnessMemAvg") + RecommendationReasonCodeJointAffin = RecommendationReasonCode("jointAffin") + RecommendationReasonCodeAntiAffin = RecommendationReasonCode("antiAffin") + RecommendationReasonCodeHostMaint = RecommendationReasonCode("hostMaint") + RecommendationReasonCodeEnterStandby = RecommendationReasonCode("enterStandby") + RecommendationReasonCodeReservationCpu = RecommendationReasonCode("reservationCpu") + RecommendationReasonCodeReservationMem = RecommendationReasonCode("reservationMem") + RecommendationReasonCodePowerOnVm = RecommendationReasonCode("powerOnVm") + RecommendationReasonCodePowerSaving = RecommendationReasonCode("powerSaving") + RecommendationReasonCodeIncreaseCapacity = RecommendationReasonCode("increaseCapacity") + RecommendationReasonCodeCheckResource = RecommendationReasonCode("checkResource") + RecommendationReasonCodeUnreservedCapacity = RecommendationReasonCode("unreservedCapacity") + RecommendationReasonCodeVmHostHardAffinity = RecommendationReasonCode("vmHostHardAffinity") + RecommendationReasonCodeVmHostSoftAffinity = RecommendationReasonCode("vmHostSoftAffinity") + RecommendationReasonCodeBalanceDatastoreSpaceUsage = RecommendationReasonCode("balanceDatastoreSpaceUsage") + RecommendationReasonCodeBalanceDatastoreIOLoad = RecommendationReasonCode("balanceDatastoreIOLoad") + RecommendationReasonCodeBalanceDatastoreIOPSReservation = RecommendationReasonCode("balanceDatastoreIOPSReservation") + RecommendationReasonCodeDatastoreMaint = RecommendationReasonCode("datastoreMaint") + RecommendationReasonCodeVirtualDiskJointAffin = RecommendationReasonCode("virtualDiskJointAffin") + RecommendationReasonCodeVirtualDiskAntiAffin = RecommendationReasonCode("virtualDiskAntiAffin") + RecommendationReasonCodeDatastoreSpaceOutage = RecommendationReasonCode("datastoreSpaceOutage") + RecommendationReasonCodeStoragePlacement = RecommendationReasonCode("storagePlacement") + RecommendationReasonCodeIolbDisabledInternal = RecommendationReasonCode("iolbDisabledInternal") + RecommendationReasonCodeXvmotionPlacement = RecommendationReasonCode("xvmotionPlacement") + RecommendationReasonCodeNetworkBandwidthReservation = RecommendationReasonCode("networkBandwidthReservation") +) + +func init() { + t["RecommendationReasonCode"] = reflect.TypeOf((*RecommendationReasonCode)(nil)).Elem() +} + +type RecommendationType string + +const ( + RecommendationTypeV1 = RecommendationType("V1") +) + +func init() { + t["RecommendationType"] = reflect.TypeOf((*RecommendationType)(nil)).Elem() +} + +type ReplicationDiskConfigFaultReasonForFault string + +const ( + ReplicationDiskConfigFaultReasonForFaultDiskNotFound = ReplicationDiskConfigFaultReasonForFault("diskNotFound") + ReplicationDiskConfigFaultReasonForFaultDiskTypeNotSupported = ReplicationDiskConfigFaultReasonForFault("diskTypeNotSupported") + ReplicationDiskConfigFaultReasonForFaultInvalidDiskKey = ReplicationDiskConfigFaultReasonForFault("invalidDiskKey") + ReplicationDiskConfigFaultReasonForFaultInvalidDiskReplicationId = ReplicationDiskConfigFaultReasonForFault("invalidDiskReplicationId") + ReplicationDiskConfigFaultReasonForFaultDuplicateDiskReplicationId = ReplicationDiskConfigFaultReasonForFault("duplicateDiskReplicationId") + ReplicationDiskConfigFaultReasonForFaultInvalidPersistentFilePath = ReplicationDiskConfigFaultReasonForFault("invalidPersistentFilePath") + ReplicationDiskConfigFaultReasonForFaultReconfigureDiskReplicationIdNotAllowed = ReplicationDiskConfigFaultReasonForFault("reconfigureDiskReplicationIdNotAllowed") +) + +func init() { + t["ReplicationDiskConfigFaultReasonForFault"] = reflect.TypeOf((*ReplicationDiskConfigFaultReasonForFault)(nil)).Elem() +} + +type ReplicationVmConfigFaultReasonForFault string + +const ( + ReplicationVmConfigFaultReasonForFaultIncompatibleHwVersion = ReplicationVmConfigFaultReasonForFault("incompatibleHwVersion") + ReplicationVmConfigFaultReasonForFaultInvalidVmReplicationId = ReplicationVmConfigFaultReasonForFault("invalidVmReplicationId") + ReplicationVmConfigFaultReasonForFaultInvalidGenerationNumber = ReplicationVmConfigFaultReasonForFault("invalidGenerationNumber") + ReplicationVmConfigFaultReasonForFaultOutOfBoundsRpoValue = ReplicationVmConfigFaultReasonForFault("outOfBoundsRpoValue") + ReplicationVmConfigFaultReasonForFaultInvalidDestinationIpAddress = ReplicationVmConfigFaultReasonForFault("invalidDestinationIpAddress") + ReplicationVmConfigFaultReasonForFaultInvalidDestinationPort = ReplicationVmConfigFaultReasonForFault("invalidDestinationPort") + ReplicationVmConfigFaultReasonForFaultInvalidExtraVmOptions = ReplicationVmConfigFaultReasonForFault("invalidExtraVmOptions") + ReplicationVmConfigFaultReasonForFaultStaleGenerationNumber = ReplicationVmConfigFaultReasonForFault("staleGenerationNumber") + ReplicationVmConfigFaultReasonForFaultReconfigureVmReplicationIdNotAllowed = ReplicationVmConfigFaultReasonForFault("reconfigureVmReplicationIdNotAllowed") + ReplicationVmConfigFaultReasonForFaultCannotRetrieveVmReplicationConfiguration = ReplicationVmConfigFaultReasonForFault("cannotRetrieveVmReplicationConfiguration") + ReplicationVmConfigFaultReasonForFaultReplicationAlreadyEnabled = ReplicationVmConfigFaultReasonForFault("replicationAlreadyEnabled") + ReplicationVmConfigFaultReasonForFaultInvalidPriorConfiguration = ReplicationVmConfigFaultReasonForFault("invalidPriorConfiguration") + ReplicationVmConfigFaultReasonForFaultReplicationNotEnabled = ReplicationVmConfigFaultReasonForFault("replicationNotEnabled") + ReplicationVmConfigFaultReasonForFaultReplicationConfigurationFailed = ReplicationVmConfigFaultReasonForFault("replicationConfigurationFailed") +) + +func init() { + t["ReplicationVmConfigFaultReasonForFault"] = reflect.TypeOf((*ReplicationVmConfigFaultReasonForFault)(nil)).Elem() +} + +type ReplicationVmFaultReasonForFault string + +const ( + ReplicationVmFaultReasonForFaultNotConfigured = ReplicationVmFaultReasonForFault("notConfigured") + ReplicationVmFaultReasonForFaultPoweredOff = ReplicationVmFaultReasonForFault("poweredOff") + ReplicationVmFaultReasonForFaultSuspended = ReplicationVmFaultReasonForFault("suspended") + ReplicationVmFaultReasonForFaultPoweredOn = ReplicationVmFaultReasonForFault("poweredOn") + ReplicationVmFaultReasonForFaultOfflineReplicating = ReplicationVmFaultReasonForFault("offlineReplicating") + ReplicationVmFaultReasonForFaultInvalidState = ReplicationVmFaultReasonForFault("invalidState") + ReplicationVmFaultReasonForFaultInvalidInstanceId = ReplicationVmFaultReasonForFault("invalidInstanceId") +) + +func init() { + t["ReplicationVmFaultReasonForFault"] = reflect.TypeOf((*ReplicationVmFaultReasonForFault)(nil)).Elem() +} + +type ReplicationVmInProgressFaultActivity string + +const ( + ReplicationVmInProgressFaultActivityFullSync = ReplicationVmInProgressFaultActivity("fullSync") + ReplicationVmInProgressFaultActivityDelta = ReplicationVmInProgressFaultActivity("delta") +) + +func init() { + t["ReplicationVmInProgressFaultActivity"] = reflect.TypeOf((*ReplicationVmInProgressFaultActivity)(nil)).Elem() +} + +type ReplicationVmState string + +const ( + ReplicationVmStateNone = ReplicationVmState("none") + ReplicationVmStatePaused = ReplicationVmState("paused") + ReplicationVmStateSyncing = ReplicationVmState("syncing") + ReplicationVmStateIdle = ReplicationVmState("idle") + ReplicationVmStateActive = ReplicationVmState("active") + ReplicationVmStateError = ReplicationVmState("error") +) + +func init() { + t["ReplicationVmState"] = reflect.TypeOf((*ReplicationVmState)(nil)).Elem() +} + +type ScheduledHardwareUpgradeInfoHardwareUpgradePolicy string + +const ( + ScheduledHardwareUpgradeInfoHardwareUpgradePolicyNever = ScheduledHardwareUpgradeInfoHardwareUpgradePolicy("never") + ScheduledHardwareUpgradeInfoHardwareUpgradePolicyOnSoftPowerOff = ScheduledHardwareUpgradeInfoHardwareUpgradePolicy("onSoftPowerOff") + ScheduledHardwareUpgradeInfoHardwareUpgradePolicyAlways = ScheduledHardwareUpgradeInfoHardwareUpgradePolicy("always") +) + +func init() { + t["ScheduledHardwareUpgradeInfoHardwareUpgradePolicy"] = reflect.TypeOf((*ScheduledHardwareUpgradeInfoHardwareUpgradePolicy)(nil)).Elem() +} + +type ScheduledHardwareUpgradeInfoHardwareUpgradeStatus string + +const ( + ScheduledHardwareUpgradeInfoHardwareUpgradeStatusNone = ScheduledHardwareUpgradeInfoHardwareUpgradeStatus("none") + ScheduledHardwareUpgradeInfoHardwareUpgradeStatusPending = ScheduledHardwareUpgradeInfoHardwareUpgradeStatus("pending") + ScheduledHardwareUpgradeInfoHardwareUpgradeStatusSuccess = ScheduledHardwareUpgradeInfoHardwareUpgradeStatus("success") + ScheduledHardwareUpgradeInfoHardwareUpgradeStatusFailed = ScheduledHardwareUpgradeInfoHardwareUpgradeStatus("failed") +) + +func init() { + t["ScheduledHardwareUpgradeInfoHardwareUpgradeStatus"] = reflect.TypeOf((*ScheduledHardwareUpgradeInfoHardwareUpgradeStatus)(nil)).Elem() +} + +type ScsiLunDescriptorQuality string + +const ( + ScsiLunDescriptorQualityHighQuality = ScsiLunDescriptorQuality("highQuality") + ScsiLunDescriptorQualityMediumQuality = ScsiLunDescriptorQuality("mediumQuality") + ScsiLunDescriptorQualityLowQuality = ScsiLunDescriptorQuality("lowQuality") + ScsiLunDescriptorQualityUnknownQuality = ScsiLunDescriptorQuality("unknownQuality") +) + +func init() { + t["ScsiLunDescriptorQuality"] = reflect.TypeOf((*ScsiLunDescriptorQuality)(nil)).Elem() +} + +type ScsiLunState string + +const ( + ScsiLunStateUnknownState = ScsiLunState("unknownState") + ScsiLunStateOk = ScsiLunState("ok") + ScsiLunStateError = ScsiLunState("error") + ScsiLunStateOff = ScsiLunState("off") + ScsiLunStateQuiesced = ScsiLunState("quiesced") + ScsiLunStateDegraded = ScsiLunState("degraded") + ScsiLunStateLostCommunication = ScsiLunState("lostCommunication") + ScsiLunStateTimeout = ScsiLunState("timeout") +) + +func init() { + t["ScsiLunState"] = reflect.TypeOf((*ScsiLunState)(nil)).Elem() +} + +type ScsiLunType string + +const ( + ScsiLunTypeDisk = ScsiLunType("disk") + ScsiLunTypeTape = ScsiLunType("tape") + ScsiLunTypePrinter = ScsiLunType("printer") + ScsiLunTypeProcessor = ScsiLunType("processor") + ScsiLunTypeWorm = ScsiLunType("worm") + ScsiLunTypeCdrom = ScsiLunType("cdrom") + ScsiLunTypeScanner = ScsiLunType("scanner") + ScsiLunTypeOpticalDevice = ScsiLunType("opticalDevice") + ScsiLunTypeMediaChanger = ScsiLunType("mediaChanger") + ScsiLunTypeCommunications = ScsiLunType("communications") + ScsiLunTypeStorageArrayController = ScsiLunType("storageArrayController") + ScsiLunTypeEnclosure = ScsiLunType("enclosure") + ScsiLunTypeUnknown = ScsiLunType("unknown") +) + +func init() { + t["ScsiLunType"] = reflect.TypeOf((*ScsiLunType)(nil)).Elem() +} + +type ScsiLunVStorageSupportStatus string + +const ( + ScsiLunVStorageSupportStatusVStorageSupported = ScsiLunVStorageSupportStatus("vStorageSupported") + ScsiLunVStorageSupportStatusVStorageUnsupported = ScsiLunVStorageSupportStatus("vStorageUnsupported") + ScsiLunVStorageSupportStatusVStorageUnknown = ScsiLunVStorageSupportStatus("vStorageUnknown") +) + +func init() { + t["ScsiLunVStorageSupportStatus"] = reflect.TypeOf((*ScsiLunVStorageSupportStatus)(nil)).Elem() +} + +type SessionManagerHttpServiceRequestSpecMethod string + +const ( + SessionManagerHttpServiceRequestSpecMethodHttpOptions = SessionManagerHttpServiceRequestSpecMethod("httpOptions") + SessionManagerHttpServiceRequestSpecMethodHttpGet = SessionManagerHttpServiceRequestSpecMethod("httpGet") + SessionManagerHttpServiceRequestSpecMethodHttpHead = SessionManagerHttpServiceRequestSpecMethod("httpHead") + SessionManagerHttpServiceRequestSpecMethodHttpPost = SessionManagerHttpServiceRequestSpecMethod("httpPost") + SessionManagerHttpServiceRequestSpecMethodHttpPut = SessionManagerHttpServiceRequestSpecMethod("httpPut") + SessionManagerHttpServiceRequestSpecMethodHttpDelete = SessionManagerHttpServiceRequestSpecMethod("httpDelete") + SessionManagerHttpServiceRequestSpecMethodHttpTrace = SessionManagerHttpServiceRequestSpecMethod("httpTrace") + SessionManagerHttpServiceRequestSpecMethodHttpConnect = SessionManagerHttpServiceRequestSpecMethod("httpConnect") +) + +func init() { + t["SessionManagerHttpServiceRequestSpecMethod"] = reflect.TypeOf((*SessionManagerHttpServiceRequestSpecMethod)(nil)).Elem() +} + +type SharesLevel string + +const ( + SharesLevelLow = SharesLevel("low") + SharesLevelNormal = SharesLevel("normal") + SharesLevelHigh = SharesLevel("high") + SharesLevelCustom = SharesLevel("custom") +) + +func init() { + t["SharesLevel"] = reflect.TypeOf((*SharesLevel)(nil)).Elem() +} + +type SimpleCommandEncoding string + +const ( + SimpleCommandEncodingCSV = SimpleCommandEncoding("CSV") + SimpleCommandEncodingHEX = SimpleCommandEncoding("HEX") + SimpleCommandEncodingSTRING = SimpleCommandEncoding("STRING") +) + +func init() { + t["SimpleCommandEncoding"] = reflect.TypeOf((*SimpleCommandEncoding)(nil)).Elem() +} + +type SlpDiscoveryMethod string + +const ( + SlpDiscoveryMethodSlpDhcp = SlpDiscoveryMethod("slpDhcp") + SlpDiscoveryMethodSlpAutoUnicast = SlpDiscoveryMethod("slpAutoUnicast") + SlpDiscoveryMethodSlpAutoMulticast = SlpDiscoveryMethod("slpAutoMulticast") + SlpDiscoveryMethodSlpManual = SlpDiscoveryMethod("slpManual") +) + +func init() { + t["SlpDiscoveryMethod"] = reflect.TypeOf((*SlpDiscoveryMethod)(nil)).Elem() +} + +type StateAlarmOperator string + +const ( + StateAlarmOperatorIsEqual = StateAlarmOperator("isEqual") + StateAlarmOperatorIsUnequal = StateAlarmOperator("isUnequal") +) + +func init() { + t["StateAlarmOperator"] = reflect.TypeOf((*StateAlarmOperator)(nil)).Elem() +} + +type StorageDrsPodConfigInfoBehavior string + +const ( + StorageDrsPodConfigInfoBehaviorManual = StorageDrsPodConfigInfoBehavior("manual") + StorageDrsPodConfigInfoBehaviorAutomated = StorageDrsPodConfigInfoBehavior("automated") +) + +func init() { + t["StorageDrsPodConfigInfoBehavior"] = reflect.TypeOf((*StorageDrsPodConfigInfoBehavior)(nil)).Elem() +} + +type StorageDrsSpaceLoadBalanceConfigSpaceThresholdMode string + +const ( + StorageDrsSpaceLoadBalanceConfigSpaceThresholdModeUtilization = StorageDrsSpaceLoadBalanceConfigSpaceThresholdMode("utilization") + StorageDrsSpaceLoadBalanceConfigSpaceThresholdModeFreeSpace = StorageDrsSpaceLoadBalanceConfigSpaceThresholdMode("freeSpace") +) + +func init() { + t["StorageDrsSpaceLoadBalanceConfigSpaceThresholdMode"] = reflect.TypeOf((*StorageDrsSpaceLoadBalanceConfigSpaceThresholdMode)(nil)).Elem() +} + +type StorageIORMThresholdMode string + +const ( + StorageIORMThresholdModeAutomatic = StorageIORMThresholdMode("automatic") + StorageIORMThresholdModeManual = StorageIORMThresholdMode("manual") +) + +func init() { + t["StorageIORMThresholdMode"] = reflect.TypeOf((*StorageIORMThresholdMode)(nil)).Elem() +} + +type StoragePlacementSpecPlacementType string + +const ( + StoragePlacementSpecPlacementTypeCreate = StoragePlacementSpecPlacementType("create") + StoragePlacementSpecPlacementTypeReconfigure = StoragePlacementSpecPlacementType("reconfigure") + StoragePlacementSpecPlacementTypeRelocate = StoragePlacementSpecPlacementType("relocate") + StoragePlacementSpecPlacementTypeClone = StoragePlacementSpecPlacementType("clone") +) + +func init() { + t["StoragePlacementSpecPlacementType"] = reflect.TypeOf((*StoragePlacementSpecPlacementType)(nil)).Elem() +} + +type TaskFilterSpecRecursionOption string + +const ( + TaskFilterSpecRecursionOptionSelf = TaskFilterSpecRecursionOption("self") + TaskFilterSpecRecursionOptionChildren = TaskFilterSpecRecursionOption("children") + TaskFilterSpecRecursionOptionAll = TaskFilterSpecRecursionOption("all") +) + +func init() { + t["TaskFilterSpecRecursionOption"] = reflect.TypeOf((*TaskFilterSpecRecursionOption)(nil)).Elem() +} + +type TaskFilterSpecTimeOption string + +const ( + TaskFilterSpecTimeOptionQueuedTime = TaskFilterSpecTimeOption("queuedTime") + TaskFilterSpecTimeOptionStartedTime = TaskFilterSpecTimeOption("startedTime") + TaskFilterSpecTimeOptionCompletedTime = TaskFilterSpecTimeOption("completedTime") +) + +func init() { + t["TaskFilterSpecTimeOption"] = reflect.TypeOf((*TaskFilterSpecTimeOption)(nil)).Elem() +} + +type TaskInfoState string + +const ( + TaskInfoStateQueued = TaskInfoState("queued") + TaskInfoStateRunning = TaskInfoState("running") + TaskInfoStateSuccess = TaskInfoState("success") + TaskInfoStateError = TaskInfoState("error") +) + +func init() { + t["TaskInfoState"] = reflect.TypeOf((*TaskInfoState)(nil)).Elem() +} + +type ThirdPartyLicenseAssignmentFailedReason string + +const ( + ThirdPartyLicenseAssignmentFailedReasonLicenseAssignmentFailed = ThirdPartyLicenseAssignmentFailedReason("licenseAssignmentFailed") + ThirdPartyLicenseAssignmentFailedReasonModuleNotInstalled = ThirdPartyLicenseAssignmentFailedReason("moduleNotInstalled") +) + +func init() { + t["ThirdPartyLicenseAssignmentFailedReason"] = reflect.TypeOf((*ThirdPartyLicenseAssignmentFailedReason)(nil)).Elem() +} + +type UpgradePolicy string + +const ( + UpgradePolicyManual = UpgradePolicy("manual") + UpgradePolicyUpgradeAtPowerCycle = UpgradePolicy("upgradeAtPowerCycle") +) + +func init() { + t["UpgradePolicy"] = reflect.TypeOf((*UpgradePolicy)(nil)).Elem() +} + +type VAppAutoStartAction string + +const ( + VAppAutoStartActionNone = VAppAutoStartAction("none") + VAppAutoStartActionPowerOn = VAppAutoStartAction("powerOn") + VAppAutoStartActionPowerOff = VAppAutoStartAction("powerOff") + VAppAutoStartActionGuestShutdown = VAppAutoStartAction("guestShutdown") + VAppAutoStartActionSuspend = VAppAutoStartAction("suspend") +) + +func init() { + t["VAppAutoStartAction"] = reflect.TypeOf((*VAppAutoStartAction)(nil)).Elem() +} + +type VAppCloneSpecProvisioningType string + +const ( + VAppCloneSpecProvisioningTypeSameAsSource = VAppCloneSpecProvisioningType("sameAsSource") + VAppCloneSpecProvisioningTypeThin = VAppCloneSpecProvisioningType("thin") + VAppCloneSpecProvisioningTypeThick = VAppCloneSpecProvisioningType("thick") +) + +func init() { + t["VAppCloneSpecProvisioningType"] = reflect.TypeOf((*VAppCloneSpecProvisioningType)(nil)).Elem() +} + +type VAppIPAssignmentInfoAllocationSchemes string + +const ( + VAppIPAssignmentInfoAllocationSchemesDhcp = VAppIPAssignmentInfoAllocationSchemes("dhcp") + VAppIPAssignmentInfoAllocationSchemesOvfenv = VAppIPAssignmentInfoAllocationSchemes("ovfenv") +) + +func init() { + t["VAppIPAssignmentInfoAllocationSchemes"] = reflect.TypeOf((*VAppIPAssignmentInfoAllocationSchemes)(nil)).Elem() +} + +type VAppIPAssignmentInfoIpAllocationPolicy string + +const ( + VAppIPAssignmentInfoIpAllocationPolicyDhcpPolicy = VAppIPAssignmentInfoIpAllocationPolicy("dhcpPolicy") + VAppIPAssignmentInfoIpAllocationPolicyTransientPolicy = VAppIPAssignmentInfoIpAllocationPolicy("transientPolicy") + VAppIPAssignmentInfoIpAllocationPolicyFixedPolicy = VAppIPAssignmentInfoIpAllocationPolicy("fixedPolicy") + VAppIPAssignmentInfoIpAllocationPolicyFixedAllocatedPolicy = VAppIPAssignmentInfoIpAllocationPolicy("fixedAllocatedPolicy") +) + +func init() { + t["VAppIPAssignmentInfoIpAllocationPolicy"] = reflect.TypeOf((*VAppIPAssignmentInfoIpAllocationPolicy)(nil)).Elem() +} + +type VAppIPAssignmentInfoProtocols string + +const ( + VAppIPAssignmentInfoProtocolsIPv4 = VAppIPAssignmentInfoProtocols("IPv4") + VAppIPAssignmentInfoProtocolsIPv6 = VAppIPAssignmentInfoProtocols("IPv6") +) + +func init() { + t["VAppIPAssignmentInfoProtocols"] = reflect.TypeOf((*VAppIPAssignmentInfoProtocols)(nil)).Elem() +} + +type VFlashModuleNotSupportedReason string + +const ( + VFlashModuleNotSupportedReasonCacheModeNotSupported = VFlashModuleNotSupportedReason("CacheModeNotSupported") + VFlashModuleNotSupportedReasonCacheConsistencyTypeNotSupported = VFlashModuleNotSupportedReason("CacheConsistencyTypeNotSupported") + VFlashModuleNotSupportedReasonCacheBlockSizeNotSupported = VFlashModuleNotSupportedReason("CacheBlockSizeNotSupported") + VFlashModuleNotSupportedReasonCacheReservationNotSupported = VFlashModuleNotSupportedReason("CacheReservationNotSupported") + VFlashModuleNotSupportedReasonDiskSizeNotSupported = VFlashModuleNotSupportedReason("DiskSizeNotSupported") +) + +func init() { + t["VFlashModuleNotSupportedReason"] = reflect.TypeOf((*VFlashModuleNotSupportedReason)(nil)).Elem() +} + +type VMotionCompatibilityType string + +const ( + VMotionCompatibilityTypeCpu = VMotionCompatibilityType("cpu") + VMotionCompatibilityTypeSoftware = VMotionCompatibilityType("software") +) + +func init() { + t["VMotionCompatibilityType"] = reflect.TypeOf((*VMotionCompatibilityType)(nil)).Elem() +} + +type VMwareDVSTeamingMatchStatus string + +const ( + VMwareDVSTeamingMatchStatusIphashMatch = VMwareDVSTeamingMatchStatus("iphashMatch") + VMwareDVSTeamingMatchStatusNonIphashMatch = VMwareDVSTeamingMatchStatus("nonIphashMatch") + VMwareDVSTeamingMatchStatusIphashMismatch = VMwareDVSTeamingMatchStatus("iphashMismatch") + VMwareDVSTeamingMatchStatusNonIphashMismatch = VMwareDVSTeamingMatchStatus("nonIphashMismatch") +) + +func init() { + t["VMwareDVSTeamingMatchStatus"] = reflect.TypeOf((*VMwareDVSTeamingMatchStatus)(nil)).Elem() +} + +type VMwareDVSVspanSessionType string + +const ( + VMwareDVSVspanSessionTypeMixedDestMirror = VMwareDVSVspanSessionType("mixedDestMirror") + VMwareDVSVspanSessionTypeDvPortMirror = VMwareDVSVspanSessionType("dvPortMirror") + VMwareDVSVspanSessionTypeRemoteMirrorSource = VMwareDVSVspanSessionType("remoteMirrorSource") + VMwareDVSVspanSessionTypeRemoteMirrorDest = VMwareDVSVspanSessionType("remoteMirrorDest") + VMwareDVSVspanSessionTypeEncapsulatedRemoteMirrorSource = VMwareDVSVspanSessionType("encapsulatedRemoteMirrorSource") +) + +func init() { + t["VMwareDVSVspanSessionType"] = reflect.TypeOf((*VMwareDVSVspanSessionType)(nil)).Elem() +} + +type VMwareDvsLacpApiVersion string + +const ( + VMwareDvsLacpApiVersionSingleLag = VMwareDvsLacpApiVersion("singleLag") + VMwareDvsLacpApiVersionMultipleLag = VMwareDvsLacpApiVersion("multipleLag") +) + +func init() { + t["VMwareDvsLacpApiVersion"] = reflect.TypeOf((*VMwareDvsLacpApiVersion)(nil)).Elem() +} + +type VMwareDvsLacpLoadBalanceAlgorithm string + +const ( + VMwareDvsLacpLoadBalanceAlgorithmSrcMac = VMwareDvsLacpLoadBalanceAlgorithm("srcMac") + VMwareDvsLacpLoadBalanceAlgorithmDestMac = VMwareDvsLacpLoadBalanceAlgorithm("destMac") + VMwareDvsLacpLoadBalanceAlgorithmSrcDestMac = VMwareDvsLacpLoadBalanceAlgorithm("srcDestMac") + VMwareDvsLacpLoadBalanceAlgorithmDestIpVlan = VMwareDvsLacpLoadBalanceAlgorithm("destIpVlan") + VMwareDvsLacpLoadBalanceAlgorithmSrcIpVlan = VMwareDvsLacpLoadBalanceAlgorithm("srcIpVlan") + VMwareDvsLacpLoadBalanceAlgorithmSrcDestIpVlan = VMwareDvsLacpLoadBalanceAlgorithm("srcDestIpVlan") + VMwareDvsLacpLoadBalanceAlgorithmDestTcpUdpPort = VMwareDvsLacpLoadBalanceAlgorithm("destTcpUdpPort") + VMwareDvsLacpLoadBalanceAlgorithmSrcTcpUdpPort = VMwareDvsLacpLoadBalanceAlgorithm("srcTcpUdpPort") + VMwareDvsLacpLoadBalanceAlgorithmSrcDestTcpUdpPort = VMwareDvsLacpLoadBalanceAlgorithm("srcDestTcpUdpPort") + VMwareDvsLacpLoadBalanceAlgorithmDestIpTcpUdpPort = VMwareDvsLacpLoadBalanceAlgorithm("destIpTcpUdpPort") + VMwareDvsLacpLoadBalanceAlgorithmSrcIpTcpUdpPort = VMwareDvsLacpLoadBalanceAlgorithm("srcIpTcpUdpPort") + VMwareDvsLacpLoadBalanceAlgorithmSrcDestIpTcpUdpPort = VMwareDvsLacpLoadBalanceAlgorithm("srcDestIpTcpUdpPort") + VMwareDvsLacpLoadBalanceAlgorithmDestIpTcpUdpPortVlan = VMwareDvsLacpLoadBalanceAlgorithm("destIpTcpUdpPortVlan") + VMwareDvsLacpLoadBalanceAlgorithmSrcIpTcpUdpPortVlan = VMwareDvsLacpLoadBalanceAlgorithm("srcIpTcpUdpPortVlan") + VMwareDvsLacpLoadBalanceAlgorithmSrcDestIpTcpUdpPortVlan = VMwareDvsLacpLoadBalanceAlgorithm("srcDestIpTcpUdpPortVlan") + VMwareDvsLacpLoadBalanceAlgorithmDestIp = VMwareDvsLacpLoadBalanceAlgorithm("destIp") + VMwareDvsLacpLoadBalanceAlgorithmSrcIp = VMwareDvsLacpLoadBalanceAlgorithm("srcIp") + VMwareDvsLacpLoadBalanceAlgorithmSrcDestIp = VMwareDvsLacpLoadBalanceAlgorithm("srcDestIp") + VMwareDvsLacpLoadBalanceAlgorithmVlan = VMwareDvsLacpLoadBalanceAlgorithm("vlan") + VMwareDvsLacpLoadBalanceAlgorithmSrcPortId = VMwareDvsLacpLoadBalanceAlgorithm("srcPortId") +) + +func init() { + t["VMwareDvsLacpLoadBalanceAlgorithm"] = reflect.TypeOf((*VMwareDvsLacpLoadBalanceAlgorithm)(nil)).Elem() +} + +type VMwareDvsMulticastFilteringMode string + +const ( + VMwareDvsMulticastFilteringModeLegacyFiltering = VMwareDvsMulticastFilteringMode("legacyFiltering") + VMwareDvsMulticastFilteringModeSnooping = VMwareDvsMulticastFilteringMode("snooping") +) + +func init() { + t["VMwareDvsMulticastFilteringMode"] = reflect.TypeOf((*VMwareDvsMulticastFilteringMode)(nil)).Elem() +} + +type VMwareUplinkLacpMode string + +const ( + VMwareUplinkLacpModeActive = VMwareUplinkLacpMode("active") + VMwareUplinkLacpModePassive = VMwareUplinkLacpMode("passive") +) + +func init() { + t["VMwareUplinkLacpMode"] = reflect.TypeOf((*VMwareUplinkLacpMode)(nil)).Elem() +} + +type ValidateMigrationTestType string + +const ( + ValidateMigrationTestTypeSourceTests = ValidateMigrationTestType("sourceTests") + ValidateMigrationTestTypeCompatibilityTests = ValidateMigrationTestType("compatibilityTests") + ValidateMigrationTestTypeDiskAccessibilityTests = ValidateMigrationTestType("diskAccessibilityTests") + ValidateMigrationTestTypeResourceTests = ValidateMigrationTestType("resourceTests") +) + +func init() { + t["ValidateMigrationTestType"] = reflect.TypeOf((*ValidateMigrationTestType)(nil)).Elem() +} + +type VirtualAppVAppState string + +const ( + VirtualAppVAppStateStarted = VirtualAppVAppState("started") + VirtualAppVAppStateStopped = VirtualAppVAppState("stopped") + VirtualAppVAppStateStarting = VirtualAppVAppState("starting") + VirtualAppVAppStateStopping = VirtualAppVAppState("stopping") +) + +func init() { + t["VirtualAppVAppState"] = reflect.TypeOf((*VirtualAppVAppState)(nil)).Elem() +} + +type VirtualDeviceConfigSpecFileOperation string + +const ( + VirtualDeviceConfigSpecFileOperationCreate = VirtualDeviceConfigSpecFileOperation("create") + VirtualDeviceConfigSpecFileOperationDestroy = VirtualDeviceConfigSpecFileOperation("destroy") + VirtualDeviceConfigSpecFileOperationReplace = VirtualDeviceConfigSpecFileOperation("replace") +) + +func init() { + t["VirtualDeviceConfigSpecFileOperation"] = reflect.TypeOf((*VirtualDeviceConfigSpecFileOperation)(nil)).Elem() +} + +type VirtualDeviceConfigSpecOperation string + +const ( + VirtualDeviceConfigSpecOperationAdd = VirtualDeviceConfigSpecOperation("add") + VirtualDeviceConfigSpecOperationRemove = VirtualDeviceConfigSpecOperation("remove") + VirtualDeviceConfigSpecOperationEdit = VirtualDeviceConfigSpecOperation("edit") +) + +func init() { + t["VirtualDeviceConfigSpecOperation"] = reflect.TypeOf((*VirtualDeviceConfigSpecOperation)(nil)).Elem() +} + +type VirtualDeviceConnectInfoStatus string + +const ( + VirtualDeviceConnectInfoStatusOk = VirtualDeviceConnectInfoStatus("ok") + VirtualDeviceConnectInfoStatusRecoverableError = VirtualDeviceConnectInfoStatus("recoverableError") + VirtualDeviceConnectInfoStatusUnrecoverableError = VirtualDeviceConnectInfoStatus("unrecoverableError") + VirtualDeviceConnectInfoStatusUntried = VirtualDeviceConnectInfoStatus("untried") +) + +func init() { + t["VirtualDeviceConnectInfoStatus"] = reflect.TypeOf((*VirtualDeviceConnectInfoStatus)(nil)).Elem() +} + +type VirtualDeviceFileExtension string + +const ( + VirtualDeviceFileExtensionIso = VirtualDeviceFileExtension("iso") + VirtualDeviceFileExtensionFlp = VirtualDeviceFileExtension("flp") + VirtualDeviceFileExtensionVmdk = VirtualDeviceFileExtension("vmdk") + VirtualDeviceFileExtensionDsk = VirtualDeviceFileExtension("dsk") + VirtualDeviceFileExtensionRdm = VirtualDeviceFileExtension("rdm") +) + +func init() { + t["VirtualDeviceFileExtension"] = reflect.TypeOf((*VirtualDeviceFileExtension)(nil)).Elem() +} + +type VirtualDeviceURIBackingOptionDirection string + +const ( + VirtualDeviceURIBackingOptionDirectionServer = VirtualDeviceURIBackingOptionDirection("server") + VirtualDeviceURIBackingOptionDirectionClient = VirtualDeviceURIBackingOptionDirection("client") +) + +func init() { + t["VirtualDeviceURIBackingOptionDirection"] = reflect.TypeOf((*VirtualDeviceURIBackingOptionDirection)(nil)).Elem() +} + +type VirtualDiskAdapterType string + +const ( + VirtualDiskAdapterTypeIde = VirtualDiskAdapterType("ide") + VirtualDiskAdapterTypeBusLogic = VirtualDiskAdapterType("busLogic") + VirtualDiskAdapterTypeLsiLogic = VirtualDiskAdapterType("lsiLogic") +) + +func init() { + t["VirtualDiskAdapterType"] = reflect.TypeOf((*VirtualDiskAdapterType)(nil)).Elem() +} + +type VirtualDiskCompatibilityMode string + +const ( + VirtualDiskCompatibilityModeVirtualMode = VirtualDiskCompatibilityMode("virtualMode") + VirtualDiskCompatibilityModePhysicalMode = VirtualDiskCompatibilityMode("physicalMode") +) + +func init() { + t["VirtualDiskCompatibilityMode"] = reflect.TypeOf((*VirtualDiskCompatibilityMode)(nil)).Elem() +} + +type VirtualDiskDeltaDiskFormat string + +const ( + VirtualDiskDeltaDiskFormatRedoLogFormat = VirtualDiskDeltaDiskFormat("redoLogFormat") + VirtualDiskDeltaDiskFormatNativeFormat = VirtualDiskDeltaDiskFormat("nativeFormat") + VirtualDiskDeltaDiskFormatSeSparseFormat = VirtualDiskDeltaDiskFormat("seSparseFormat") +) + +func init() { + t["VirtualDiskDeltaDiskFormat"] = reflect.TypeOf((*VirtualDiskDeltaDiskFormat)(nil)).Elem() +} + +type VirtualDiskDeltaDiskFormatVariant string + +const ( + VirtualDiskDeltaDiskFormatVariantVmfsSparseVariant = VirtualDiskDeltaDiskFormatVariant("vmfsSparseVariant") + VirtualDiskDeltaDiskFormatVariantVsanSparseVariant = VirtualDiskDeltaDiskFormatVariant("vsanSparseVariant") +) + +func init() { + t["VirtualDiskDeltaDiskFormatVariant"] = reflect.TypeOf((*VirtualDiskDeltaDiskFormatVariant)(nil)).Elem() +} + +type VirtualDiskMode string + +const ( + VirtualDiskModePersistent = VirtualDiskMode("persistent") + VirtualDiskModeNonpersistent = VirtualDiskMode("nonpersistent") + VirtualDiskModeUndoable = VirtualDiskMode("undoable") + VirtualDiskModeIndependent_persistent = VirtualDiskMode("independent_persistent") + VirtualDiskModeIndependent_nonpersistent = VirtualDiskMode("independent_nonpersistent") + VirtualDiskModeAppend = VirtualDiskMode("append") +) + +func init() { + t["VirtualDiskMode"] = reflect.TypeOf((*VirtualDiskMode)(nil)).Elem() +} + +type VirtualDiskSharing string + +const ( + VirtualDiskSharingSharingNone = VirtualDiskSharing("sharingNone") + VirtualDiskSharingSharingMultiWriter = VirtualDiskSharing("sharingMultiWriter") +) + +func init() { + t["VirtualDiskSharing"] = reflect.TypeOf((*VirtualDiskSharing)(nil)).Elem() +} + +type VirtualDiskType string + +const ( + VirtualDiskTypePreallocated = VirtualDiskType("preallocated") + VirtualDiskTypeThin = VirtualDiskType("thin") + VirtualDiskTypeSeSparse = VirtualDiskType("seSparse") + VirtualDiskTypeRdm = VirtualDiskType("rdm") + VirtualDiskTypeRdmp = VirtualDiskType("rdmp") + VirtualDiskTypeRaw = VirtualDiskType("raw") + VirtualDiskTypeDelta = VirtualDiskType("delta") + VirtualDiskTypeSparse2Gb = VirtualDiskType("sparse2Gb") + VirtualDiskTypeThick2Gb = VirtualDiskType("thick2Gb") + VirtualDiskTypeEagerZeroedThick = VirtualDiskType("eagerZeroedThick") + VirtualDiskTypeSparseMonolithic = VirtualDiskType("sparseMonolithic") + VirtualDiskTypeFlatMonolithic = VirtualDiskType("flatMonolithic") + VirtualDiskTypeThick = VirtualDiskType("thick") +) + +func init() { + t["VirtualDiskType"] = reflect.TypeOf((*VirtualDiskType)(nil)).Elem() +} + +type VirtualDiskVFlashCacheConfigInfoCacheConsistencyType string + +const ( + VirtualDiskVFlashCacheConfigInfoCacheConsistencyTypeStrong = VirtualDiskVFlashCacheConfigInfoCacheConsistencyType("strong") + VirtualDiskVFlashCacheConfigInfoCacheConsistencyTypeWeak = VirtualDiskVFlashCacheConfigInfoCacheConsistencyType("weak") +) + +func init() { + t["VirtualDiskVFlashCacheConfigInfoCacheConsistencyType"] = reflect.TypeOf((*VirtualDiskVFlashCacheConfigInfoCacheConsistencyType)(nil)).Elem() +} + +type VirtualDiskVFlashCacheConfigInfoCacheMode string + +const ( + VirtualDiskVFlashCacheConfigInfoCacheModeWrite_thru = VirtualDiskVFlashCacheConfigInfoCacheMode("write_thru") + VirtualDiskVFlashCacheConfigInfoCacheModeWrite_back = VirtualDiskVFlashCacheConfigInfoCacheMode("write_back") +) + +func init() { + t["VirtualDiskVFlashCacheConfigInfoCacheMode"] = reflect.TypeOf((*VirtualDiskVFlashCacheConfigInfoCacheMode)(nil)).Elem() +} + +type VirtualEthernetCardLegacyNetworkDeviceName string + +const ( + VirtualEthernetCardLegacyNetworkDeviceNameBridged = VirtualEthernetCardLegacyNetworkDeviceName("bridged") + VirtualEthernetCardLegacyNetworkDeviceNameNat = VirtualEthernetCardLegacyNetworkDeviceName("nat") + VirtualEthernetCardLegacyNetworkDeviceNameHostonly = VirtualEthernetCardLegacyNetworkDeviceName("hostonly") +) + +func init() { + t["VirtualEthernetCardLegacyNetworkDeviceName"] = reflect.TypeOf((*VirtualEthernetCardLegacyNetworkDeviceName)(nil)).Elem() +} + +type VirtualEthernetCardMacType string + +const ( + VirtualEthernetCardMacTypeManual = VirtualEthernetCardMacType("manual") + VirtualEthernetCardMacTypeGenerated = VirtualEthernetCardMacType("generated") + VirtualEthernetCardMacTypeAssigned = VirtualEthernetCardMacType("assigned") +) + +func init() { + t["VirtualEthernetCardMacType"] = reflect.TypeOf((*VirtualEthernetCardMacType)(nil)).Elem() +} + +type VirtualMachineAppHeartbeatStatusType string + +const ( + VirtualMachineAppHeartbeatStatusTypeAppStatusGray = VirtualMachineAppHeartbeatStatusType("appStatusGray") + VirtualMachineAppHeartbeatStatusTypeAppStatusGreen = VirtualMachineAppHeartbeatStatusType("appStatusGreen") + VirtualMachineAppHeartbeatStatusTypeAppStatusRed = VirtualMachineAppHeartbeatStatusType("appStatusRed") +) + +func init() { + t["VirtualMachineAppHeartbeatStatusType"] = reflect.TypeOf((*VirtualMachineAppHeartbeatStatusType)(nil)).Elem() +} + +type VirtualMachineBootOptionsNetworkBootProtocolType string + +const ( + VirtualMachineBootOptionsNetworkBootProtocolTypeIpv4 = VirtualMachineBootOptionsNetworkBootProtocolType("ipv4") + VirtualMachineBootOptionsNetworkBootProtocolTypeIpv6 = VirtualMachineBootOptionsNetworkBootProtocolType("ipv6") +) + +func init() { + t["VirtualMachineBootOptionsNetworkBootProtocolType"] = reflect.TypeOf((*VirtualMachineBootOptionsNetworkBootProtocolType)(nil)).Elem() +} + +type VirtualMachineConfigInfoNpivWwnType string + +const ( + VirtualMachineConfigInfoNpivWwnTypeVc = VirtualMachineConfigInfoNpivWwnType("vc") + VirtualMachineConfigInfoNpivWwnTypeHost = VirtualMachineConfigInfoNpivWwnType("host") + VirtualMachineConfigInfoNpivWwnTypeExternal = VirtualMachineConfigInfoNpivWwnType("external") +) + +func init() { + t["VirtualMachineConfigInfoNpivWwnType"] = reflect.TypeOf((*VirtualMachineConfigInfoNpivWwnType)(nil)).Elem() +} + +type VirtualMachineConfigInfoSwapPlacementType string + +const ( + VirtualMachineConfigInfoSwapPlacementTypeInherit = VirtualMachineConfigInfoSwapPlacementType("inherit") + VirtualMachineConfigInfoSwapPlacementTypeVmDirectory = VirtualMachineConfigInfoSwapPlacementType("vmDirectory") + VirtualMachineConfigInfoSwapPlacementTypeHostLocal = VirtualMachineConfigInfoSwapPlacementType("hostLocal") +) + +func init() { + t["VirtualMachineConfigInfoSwapPlacementType"] = reflect.TypeOf((*VirtualMachineConfigInfoSwapPlacementType)(nil)).Elem() +} + +type VirtualMachineConfigSpecNpivWwnOp string + +const ( + VirtualMachineConfigSpecNpivWwnOpGenerate = VirtualMachineConfigSpecNpivWwnOp("generate") + VirtualMachineConfigSpecNpivWwnOpSet = VirtualMachineConfigSpecNpivWwnOp("set") + VirtualMachineConfigSpecNpivWwnOpRemove = VirtualMachineConfigSpecNpivWwnOp("remove") + VirtualMachineConfigSpecNpivWwnOpExtend = VirtualMachineConfigSpecNpivWwnOp("extend") +) + +func init() { + t["VirtualMachineConfigSpecNpivWwnOp"] = reflect.TypeOf((*VirtualMachineConfigSpecNpivWwnOp)(nil)).Elem() +} + +type VirtualMachineConnectionState string + +const ( + VirtualMachineConnectionStateConnected = VirtualMachineConnectionState("connected") + VirtualMachineConnectionStateDisconnected = VirtualMachineConnectionState("disconnected") + VirtualMachineConnectionStateOrphaned = VirtualMachineConnectionState("orphaned") + VirtualMachineConnectionStateInaccessible = VirtualMachineConnectionState("inaccessible") + VirtualMachineConnectionStateInvalid = VirtualMachineConnectionState("invalid") +) + +func init() { + t["VirtualMachineConnectionState"] = reflect.TypeOf((*VirtualMachineConnectionState)(nil)).Elem() +} + +type VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOther string + +const ( + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOtherVmNptIncompatibleHost = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOther("vmNptIncompatibleHost") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOtherVmNptIncompatibleNetwork = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOther("vmNptIncompatibleNetwork") +) + +func init() { + t["VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOther"] = reflect.TypeOf((*VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonOther)(nil)).Elem() +} + +type VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm string + +const ( + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptIncompatibleGuest = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptIncompatibleGuest") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptIncompatibleGuestDriver = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptIncompatibleGuestDriver") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptIncompatibleAdapterType = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptIncompatibleAdapterType") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptDisabledOrDisconnectedAdapter = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptDisabledOrDisconnectedAdapter") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptIncompatibleAdapterFeatures = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptIncompatibleAdapterFeatures") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptIncompatibleBackingType = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptIncompatibleBackingType") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptInsufficientMemoryReservation = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptInsufficientMemoryReservation") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptFaultToleranceOrRecordReplayConfigured = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptFaultToleranceOrRecordReplayConfigured") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptConflictingIOChainConfigured = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptConflictingIOChainConfigured") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptMonitorBlocks = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptMonitorBlocks") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptConflictingOperationInProgress = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptConflictingOperationInProgress") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptRuntimeError = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptRuntimeError") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptOutOfIntrVector = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptOutOfIntrVector") + VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVmVmNptVMCIActive = VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm("vmNptVMCIActive") +) + +func init() { + t["VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm"] = reflect.TypeOf((*VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeStateVmDirectPathGen2InactiveReasonVm)(nil)).Elem() +} + +type VirtualMachineFaultToleranceState string + +const ( + VirtualMachineFaultToleranceStateNotConfigured = VirtualMachineFaultToleranceState("notConfigured") + VirtualMachineFaultToleranceStateDisabled = VirtualMachineFaultToleranceState("disabled") + VirtualMachineFaultToleranceStateEnabled = VirtualMachineFaultToleranceState("enabled") + VirtualMachineFaultToleranceStateNeedSecondary = VirtualMachineFaultToleranceState("needSecondary") + VirtualMachineFaultToleranceStateStarting = VirtualMachineFaultToleranceState("starting") + VirtualMachineFaultToleranceStateRunning = VirtualMachineFaultToleranceState("running") +) + +func init() { + t["VirtualMachineFaultToleranceState"] = reflect.TypeOf((*VirtualMachineFaultToleranceState)(nil)).Elem() +} + +type VirtualMachineFaultToleranceType string + +const ( + VirtualMachineFaultToleranceTypeUnset = VirtualMachineFaultToleranceType("unset") + VirtualMachineFaultToleranceTypeRecordReplay = VirtualMachineFaultToleranceType("recordReplay") + VirtualMachineFaultToleranceTypeCheckpointing = VirtualMachineFaultToleranceType("checkpointing") +) + +func init() { + t["VirtualMachineFaultToleranceType"] = reflect.TypeOf((*VirtualMachineFaultToleranceType)(nil)).Elem() +} + +type VirtualMachineFileLayoutExFileType string + +const ( + VirtualMachineFileLayoutExFileTypeConfig = VirtualMachineFileLayoutExFileType("config") + VirtualMachineFileLayoutExFileTypeExtendedConfig = VirtualMachineFileLayoutExFileType("extendedConfig") + VirtualMachineFileLayoutExFileTypeDiskDescriptor = VirtualMachineFileLayoutExFileType("diskDescriptor") + VirtualMachineFileLayoutExFileTypeDiskExtent = VirtualMachineFileLayoutExFileType("diskExtent") + VirtualMachineFileLayoutExFileTypeDigestDescriptor = VirtualMachineFileLayoutExFileType("digestDescriptor") + VirtualMachineFileLayoutExFileTypeDigestExtent = VirtualMachineFileLayoutExFileType("digestExtent") + VirtualMachineFileLayoutExFileTypeDiskReplicationState = VirtualMachineFileLayoutExFileType("diskReplicationState") + VirtualMachineFileLayoutExFileTypeLog = VirtualMachineFileLayoutExFileType("log") + VirtualMachineFileLayoutExFileTypeStat = VirtualMachineFileLayoutExFileType("stat") + VirtualMachineFileLayoutExFileTypeNamespaceData = VirtualMachineFileLayoutExFileType("namespaceData") + VirtualMachineFileLayoutExFileTypeNvram = VirtualMachineFileLayoutExFileType("nvram") + VirtualMachineFileLayoutExFileTypeSnapshotData = VirtualMachineFileLayoutExFileType("snapshotData") + VirtualMachineFileLayoutExFileTypeSnapshotMemory = VirtualMachineFileLayoutExFileType("snapshotMemory") + VirtualMachineFileLayoutExFileTypeSnapshotList = VirtualMachineFileLayoutExFileType("snapshotList") + VirtualMachineFileLayoutExFileTypeSnapshotManifestList = VirtualMachineFileLayoutExFileType("snapshotManifestList") + VirtualMachineFileLayoutExFileTypeSuspend = VirtualMachineFileLayoutExFileType("suspend") + VirtualMachineFileLayoutExFileTypeSuspendMemory = VirtualMachineFileLayoutExFileType("suspendMemory") + VirtualMachineFileLayoutExFileTypeSwap = VirtualMachineFileLayoutExFileType("swap") + VirtualMachineFileLayoutExFileTypeUwswap = VirtualMachineFileLayoutExFileType("uwswap") + VirtualMachineFileLayoutExFileTypeCore = VirtualMachineFileLayoutExFileType("core") + VirtualMachineFileLayoutExFileTypeScreenshot = VirtualMachineFileLayoutExFileType("screenshot") + VirtualMachineFileLayoutExFileTypeFtMetadata = VirtualMachineFileLayoutExFileType("ftMetadata") + VirtualMachineFileLayoutExFileTypeGuestCustomization = VirtualMachineFileLayoutExFileType("guestCustomization") +) + +func init() { + t["VirtualMachineFileLayoutExFileType"] = reflect.TypeOf((*VirtualMachineFileLayoutExFileType)(nil)).Elem() +} + +type VirtualMachineFlagInfoMonitorType string + +const ( + VirtualMachineFlagInfoMonitorTypeRelease = VirtualMachineFlagInfoMonitorType("release") + VirtualMachineFlagInfoMonitorTypeDebug = VirtualMachineFlagInfoMonitorType("debug") + VirtualMachineFlagInfoMonitorTypeStats = VirtualMachineFlagInfoMonitorType("stats") +) + +func init() { + t["VirtualMachineFlagInfoMonitorType"] = reflect.TypeOf((*VirtualMachineFlagInfoMonitorType)(nil)).Elem() +} + +type VirtualMachineFlagInfoVirtualExecUsage string + +const ( + VirtualMachineFlagInfoVirtualExecUsageHvAuto = VirtualMachineFlagInfoVirtualExecUsage("hvAuto") + VirtualMachineFlagInfoVirtualExecUsageHvOn = VirtualMachineFlagInfoVirtualExecUsage("hvOn") + VirtualMachineFlagInfoVirtualExecUsageHvOff = VirtualMachineFlagInfoVirtualExecUsage("hvOff") +) + +func init() { + t["VirtualMachineFlagInfoVirtualExecUsage"] = reflect.TypeOf((*VirtualMachineFlagInfoVirtualExecUsage)(nil)).Elem() +} + +type VirtualMachineFlagInfoVirtualMmuUsage string + +const ( + VirtualMachineFlagInfoVirtualMmuUsageAutomatic = VirtualMachineFlagInfoVirtualMmuUsage("automatic") + VirtualMachineFlagInfoVirtualMmuUsageOn = VirtualMachineFlagInfoVirtualMmuUsage("on") + VirtualMachineFlagInfoVirtualMmuUsageOff = VirtualMachineFlagInfoVirtualMmuUsage("off") +) + +func init() { + t["VirtualMachineFlagInfoVirtualMmuUsage"] = reflect.TypeOf((*VirtualMachineFlagInfoVirtualMmuUsage)(nil)).Elem() +} + +type VirtualMachineForkConfigInfoChildType string + +const ( + VirtualMachineForkConfigInfoChildTypeNone = VirtualMachineForkConfigInfoChildType("none") + VirtualMachineForkConfigInfoChildTypePersistent = VirtualMachineForkConfigInfoChildType("persistent") + VirtualMachineForkConfigInfoChildTypeNonpersistent = VirtualMachineForkConfigInfoChildType("nonpersistent") +) + +func init() { + t["VirtualMachineForkConfigInfoChildType"] = reflect.TypeOf((*VirtualMachineForkConfigInfoChildType)(nil)).Elem() +} + +type VirtualMachineGuestOsFamily string + +const ( + VirtualMachineGuestOsFamilyWindowsGuest = VirtualMachineGuestOsFamily("windowsGuest") + VirtualMachineGuestOsFamilyLinuxGuest = VirtualMachineGuestOsFamily("linuxGuest") + VirtualMachineGuestOsFamilyNetwareGuest = VirtualMachineGuestOsFamily("netwareGuest") + VirtualMachineGuestOsFamilySolarisGuest = VirtualMachineGuestOsFamily("solarisGuest") + VirtualMachineGuestOsFamilyDarwinGuestFamily = VirtualMachineGuestOsFamily("darwinGuestFamily") + VirtualMachineGuestOsFamilyOtherGuestFamily = VirtualMachineGuestOsFamily("otherGuestFamily") +) + +func init() { + t["VirtualMachineGuestOsFamily"] = reflect.TypeOf((*VirtualMachineGuestOsFamily)(nil)).Elem() +} + +type VirtualMachineGuestOsIdentifier string + +const ( + VirtualMachineGuestOsIdentifierDosGuest = VirtualMachineGuestOsIdentifier("dosGuest") + VirtualMachineGuestOsIdentifierWin31Guest = VirtualMachineGuestOsIdentifier("win31Guest") + VirtualMachineGuestOsIdentifierWin95Guest = VirtualMachineGuestOsIdentifier("win95Guest") + VirtualMachineGuestOsIdentifierWin98Guest = VirtualMachineGuestOsIdentifier("win98Guest") + VirtualMachineGuestOsIdentifierWinMeGuest = VirtualMachineGuestOsIdentifier("winMeGuest") + VirtualMachineGuestOsIdentifierWinNTGuest = VirtualMachineGuestOsIdentifier("winNTGuest") + VirtualMachineGuestOsIdentifierWin2000ProGuest = VirtualMachineGuestOsIdentifier("win2000ProGuest") + VirtualMachineGuestOsIdentifierWin2000ServGuest = VirtualMachineGuestOsIdentifier("win2000ServGuest") + VirtualMachineGuestOsIdentifierWin2000AdvServGuest = VirtualMachineGuestOsIdentifier("win2000AdvServGuest") + VirtualMachineGuestOsIdentifierWinXPHomeGuest = VirtualMachineGuestOsIdentifier("winXPHomeGuest") + VirtualMachineGuestOsIdentifierWinXPProGuest = VirtualMachineGuestOsIdentifier("winXPProGuest") + VirtualMachineGuestOsIdentifierWinXPPro64Guest = VirtualMachineGuestOsIdentifier("winXPPro64Guest") + VirtualMachineGuestOsIdentifierWinNetWebGuest = VirtualMachineGuestOsIdentifier("winNetWebGuest") + VirtualMachineGuestOsIdentifierWinNetStandardGuest = VirtualMachineGuestOsIdentifier("winNetStandardGuest") + VirtualMachineGuestOsIdentifierWinNetEnterpriseGuest = VirtualMachineGuestOsIdentifier("winNetEnterpriseGuest") + VirtualMachineGuestOsIdentifierWinNetDatacenterGuest = VirtualMachineGuestOsIdentifier("winNetDatacenterGuest") + VirtualMachineGuestOsIdentifierWinNetBusinessGuest = VirtualMachineGuestOsIdentifier("winNetBusinessGuest") + VirtualMachineGuestOsIdentifierWinNetStandard64Guest = VirtualMachineGuestOsIdentifier("winNetStandard64Guest") + VirtualMachineGuestOsIdentifierWinNetEnterprise64Guest = VirtualMachineGuestOsIdentifier("winNetEnterprise64Guest") + VirtualMachineGuestOsIdentifierWinLonghornGuest = VirtualMachineGuestOsIdentifier("winLonghornGuest") + VirtualMachineGuestOsIdentifierWinLonghorn64Guest = VirtualMachineGuestOsIdentifier("winLonghorn64Guest") + VirtualMachineGuestOsIdentifierWinNetDatacenter64Guest = VirtualMachineGuestOsIdentifier("winNetDatacenter64Guest") + VirtualMachineGuestOsIdentifierWinVistaGuest = VirtualMachineGuestOsIdentifier("winVistaGuest") + VirtualMachineGuestOsIdentifierWinVista64Guest = VirtualMachineGuestOsIdentifier("winVista64Guest") + VirtualMachineGuestOsIdentifierWindows7Guest = VirtualMachineGuestOsIdentifier("windows7Guest") + VirtualMachineGuestOsIdentifierWindows7_64Guest = VirtualMachineGuestOsIdentifier("windows7_64Guest") + VirtualMachineGuestOsIdentifierWindows7Server64Guest = VirtualMachineGuestOsIdentifier("windows7Server64Guest") + VirtualMachineGuestOsIdentifierWindows8Guest = VirtualMachineGuestOsIdentifier("windows8Guest") + VirtualMachineGuestOsIdentifierWindows8_64Guest = VirtualMachineGuestOsIdentifier("windows8_64Guest") + VirtualMachineGuestOsIdentifierWindows8Server64Guest = VirtualMachineGuestOsIdentifier("windows8Server64Guest") + VirtualMachineGuestOsIdentifierWindows9Guest = VirtualMachineGuestOsIdentifier("windows9Guest") + VirtualMachineGuestOsIdentifierWindows9_64Guest = VirtualMachineGuestOsIdentifier("windows9_64Guest") + VirtualMachineGuestOsIdentifierWindows9Server64Guest = VirtualMachineGuestOsIdentifier("windows9Server64Guest") + VirtualMachineGuestOsIdentifierWindowsHyperVGuest = VirtualMachineGuestOsIdentifier("windowsHyperVGuest") + VirtualMachineGuestOsIdentifierFreebsdGuest = VirtualMachineGuestOsIdentifier("freebsdGuest") + VirtualMachineGuestOsIdentifierFreebsd64Guest = VirtualMachineGuestOsIdentifier("freebsd64Guest") + VirtualMachineGuestOsIdentifierRedhatGuest = VirtualMachineGuestOsIdentifier("redhatGuest") + VirtualMachineGuestOsIdentifierRhel2Guest = VirtualMachineGuestOsIdentifier("rhel2Guest") + VirtualMachineGuestOsIdentifierRhel3Guest = VirtualMachineGuestOsIdentifier("rhel3Guest") + VirtualMachineGuestOsIdentifierRhel3_64Guest = VirtualMachineGuestOsIdentifier("rhel3_64Guest") + VirtualMachineGuestOsIdentifierRhel4Guest = VirtualMachineGuestOsIdentifier("rhel4Guest") + VirtualMachineGuestOsIdentifierRhel4_64Guest = VirtualMachineGuestOsIdentifier("rhel4_64Guest") + VirtualMachineGuestOsIdentifierRhel5Guest = VirtualMachineGuestOsIdentifier("rhel5Guest") + VirtualMachineGuestOsIdentifierRhel5_64Guest = VirtualMachineGuestOsIdentifier("rhel5_64Guest") + VirtualMachineGuestOsIdentifierRhel6Guest = VirtualMachineGuestOsIdentifier("rhel6Guest") + VirtualMachineGuestOsIdentifierRhel6_64Guest = VirtualMachineGuestOsIdentifier("rhel6_64Guest") + VirtualMachineGuestOsIdentifierRhel7Guest = VirtualMachineGuestOsIdentifier("rhel7Guest") + VirtualMachineGuestOsIdentifierRhel7_64Guest = VirtualMachineGuestOsIdentifier("rhel7_64Guest") + VirtualMachineGuestOsIdentifierCentosGuest = VirtualMachineGuestOsIdentifier("centosGuest") + VirtualMachineGuestOsIdentifierCentos64Guest = VirtualMachineGuestOsIdentifier("centos64Guest") + VirtualMachineGuestOsIdentifierOracleLinuxGuest = VirtualMachineGuestOsIdentifier("oracleLinuxGuest") + VirtualMachineGuestOsIdentifierOracleLinux64Guest = VirtualMachineGuestOsIdentifier("oracleLinux64Guest") + VirtualMachineGuestOsIdentifierSuseGuest = VirtualMachineGuestOsIdentifier("suseGuest") + VirtualMachineGuestOsIdentifierSuse64Guest = VirtualMachineGuestOsIdentifier("suse64Guest") + VirtualMachineGuestOsIdentifierSlesGuest = VirtualMachineGuestOsIdentifier("slesGuest") + VirtualMachineGuestOsIdentifierSles64Guest = VirtualMachineGuestOsIdentifier("sles64Guest") + VirtualMachineGuestOsIdentifierSles10Guest = VirtualMachineGuestOsIdentifier("sles10Guest") + VirtualMachineGuestOsIdentifierSles10_64Guest = VirtualMachineGuestOsIdentifier("sles10_64Guest") + VirtualMachineGuestOsIdentifierSles11Guest = VirtualMachineGuestOsIdentifier("sles11Guest") + VirtualMachineGuestOsIdentifierSles11_64Guest = VirtualMachineGuestOsIdentifier("sles11_64Guest") + VirtualMachineGuestOsIdentifierSles12Guest = VirtualMachineGuestOsIdentifier("sles12Guest") + VirtualMachineGuestOsIdentifierSles12_64Guest = VirtualMachineGuestOsIdentifier("sles12_64Guest") + VirtualMachineGuestOsIdentifierNld9Guest = VirtualMachineGuestOsIdentifier("nld9Guest") + VirtualMachineGuestOsIdentifierOesGuest = VirtualMachineGuestOsIdentifier("oesGuest") + VirtualMachineGuestOsIdentifierSjdsGuest = VirtualMachineGuestOsIdentifier("sjdsGuest") + VirtualMachineGuestOsIdentifierMandrakeGuest = VirtualMachineGuestOsIdentifier("mandrakeGuest") + VirtualMachineGuestOsIdentifierMandrivaGuest = VirtualMachineGuestOsIdentifier("mandrivaGuest") + VirtualMachineGuestOsIdentifierMandriva64Guest = VirtualMachineGuestOsIdentifier("mandriva64Guest") + VirtualMachineGuestOsIdentifierTurboLinuxGuest = VirtualMachineGuestOsIdentifier("turboLinuxGuest") + VirtualMachineGuestOsIdentifierTurboLinux64Guest = VirtualMachineGuestOsIdentifier("turboLinux64Guest") + VirtualMachineGuestOsIdentifierUbuntuGuest = VirtualMachineGuestOsIdentifier("ubuntuGuest") + VirtualMachineGuestOsIdentifierUbuntu64Guest = VirtualMachineGuestOsIdentifier("ubuntu64Guest") + VirtualMachineGuestOsIdentifierDebian4Guest = VirtualMachineGuestOsIdentifier("debian4Guest") + VirtualMachineGuestOsIdentifierDebian4_64Guest = VirtualMachineGuestOsIdentifier("debian4_64Guest") + VirtualMachineGuestOsIdentifierDebian5Guest = VirtualMachineGuestOsIdentifier("debian5Guest") + VirtualMachineGuestOsIdentifierDebian5_64Guest = VirtualMachineGuestOsIdentifier("debian5_64Guest") + VirtualMachineGuestOsIdentifierDebian6Guest = VirtualMachineGuestOsIdentifier("debian6Guest") + VirtualMachineGuestOsIdentifierDebian6_64Guest = VirtualMachineGuestOsIdentifier("debian6_64Guest") + VirtualMachineGuestOsIdentifierDebian7Guest = VirtualMachineGuestOsIdentifier("debian7Guest") + VirtualMachineGuestOsIdentifierDebian7_64Guest = VirtualMachineGuestOsIdentifier("debian7_64Guest") + VirtualMachineGuestOsIdentifierDebian8Guest = VirtualMachineGuestOsIdentifier("debian8Guest") + VirtualMachineGuestOsIdentifierDebian8_64Guest = VirtualMachineGuestOsIdentifier("debian8_64Guest") + VirtualMachineGuestOsIdentifierAsianux3Guest = VirtualMachineGuestOsIdentifier("asianux3Guest") + VirtualMachineGuestOsIdentifierAsianux3_64Guest = VirtualMachineGuestOsIdentifier("asianux3_64Guest") + VirtualMachineGuestOsIdentifierAsianux4Guest = VirtualMachineGuestOsIdentifier("asianux4Guest") + VirtualMachineGuestOsIdentifierAsianux4_64Guest = VirtualMachineGuestOsIdentifier("asianux4_64Guest") + VirtualMachineGuestOsIdentifierAsianux5_64Guest = VirtualMachineGuestOsIdentifier("asianux5_64Guest") + VirtualMachineGuestOsIdentifierOpensuseGuest = VirtualMachineGuestOsIdentifier("opensuseGuest") + VirtualMachineGuestOsIdentifierOpensuse64Guest = VirtualMachineGuestOsIdentifier("opensuse64Guest") + VirtualMachineGuestOsIdentifierFedoraGuest = VirtualMachineGuestOsIdentifier("fedoraGuest") + VirtualMachineGuestOsIdentifierFedora64Guest = VirtualMachineGuestOsIdentifier("fedora64Guest") + VirtualMachineGuestOsIdentifierCoreos64Guest = VirtualMachineGuestOsIdentifier("coreos64Guest") + VirtualMachineGuestOsIdentifierOther24xLinuxGuest = VirtualMachineGuestOsIdentifier("other24xLinuxGuest") + VirtualMachineGuestOsIdentifierOther26xLinuxGuest = VirtualMachineGuestOsIdentifier("other26xLinuxGuest") + VirtualMachineGuestOsIdentifierOtherLinuxGuest = VirtualMachineGuestOsIdentifier("otherLinuxGuest") + VirtualMachineGuestOsIdentifierOther3xLinuxGuest = VirtualMachineGuestOsIdentifier("other3xLinuxGuest") + VirtualMachineGuestOsIdentifierGenericLinuxGuest = VirtualMachineGuestOsIdentifier("genericLinuxGuest") + VirtualMachineGuestOsIdentifierOther24xLinux64Guest = VirtualMachineGuestOsIdentifier("other24xLinux64Guest") + VirtualMachineGuestOsIdentifierOther26xLinux64Guest = VirtualMachineGuestOsIdentifier("other26xLinux64Guest") + VirtualMachineGuestOsIdentifierOther3xLinux64Guest = VirtualMachineGuestOsIdentifier("other3xLinux64Guest") + VirtualMachineGuestOsIdentifierOtherLinux64Guest = VirtualMachineGuestOsIdentifier("otherLinux64Guest") + VirtualMachineGuestOsIdentifierSolaris6Guest = VirtualMachineGuestOsIdentifier("solaris6Guest") + VirtualMachineGuestOsIdentifierSolaris7Guest = VirtualMachineGuestOsIdentifier("solaris7Guest") + VirtualMachineGuestOsIdentifierSolaris8Guest = VirtualMachineGuestOsIdentifier("solaris8Guest") + VirtualMachineGuestOsIdentifierSolaris9Guest = VirtualMachineGuestOsIdentifier("solaris9Guest") + VirtualMachineGuestOsIdentifierSolaris10Guest = VirtualMachineGuestOsIdentifier("solaris10Guest") + VirtualMachineGuestOsIdentifierSolaris10_64Guest = VirtualMachineGuestOsIdentifier("solaris10_64Guest") + VirtualMachineGuestOsIdentifierSolaris11_64Guest = VirtualMachineGuestOsIdentifier("solaris11_64Guest") + VirtualMachineGuestOsIdentifierOs2Guest = VirtualMachineGuestOsIdentifier("os2Guest") + VirtualMachineGuestOsIdentifierEComStationGuest = VirtualMachineGuestOsIdentifier("eComStationGuest") + VirtualMachineGuestOsIdentifierEComStation2Guest = VirtualMachineGuestOsIdentifier("eComStation2Guest") + VirtualMachineGuestOsIdentifierNetware4Guest = VirtualMachineGuestOsIdentifier("netware4Guest") + VirtualMachineGuestOsIdentifierNetware5Guest = VirtualMachineGuestOsIdentifier("netware5Guest") + VirtualMachineGuestOsIdentifierNetware6Guest = VirtualMachineGuestOsIdentifier("netware6Guest") + VirtualMachineGuestOsIdentifierOpenServer5Guest = VirtualMachineGuestOsIdentifier("openServer5Guest") + VirtualMachineGuestOsIdentifierOpenServer6Guest = VirtualMachineGuestOsIdentifier("openServer6Guest") + VirtualMachineGuestOsIdentifierUnixWare7Guest = VirtualMachineGuestOsIdentifier("unixWare7Guest") + VirtualMachineGuestOsIdentifierDarwinGuest = VirtualMachineGuestOsIdentifier("darwinGuest") + VirtualMachineGuestOsIdentifierDarwin64Guest = VirtualMachineGuestOsIdentifier("darwin64Guest") + VirtualMachineGuestOsIdentifierDarwin10Guest = VirtualMachineGuestOsIdentifier("darwin10Guest") + VirtualMachineGuestOsIdentifierDarwin10_64Guest = VirtualMachineGuestOsIdentifier("darwin10_64Guest") + VirtualMachineGuestOsIdentifierDarwin11Guest = VirtualMachineGuestOsIdentifier("darwin11Guest") + VirtualMachineGuestOsIdentifierDarwin11_64Guest = VirtualMachineGuestOsIdentifier("darwin11_64Guest") + VirtualMachineGuestOsIdentifierDarwin12_64Guest = VirtualMachineGuestOsIdentifier("darwin12_64Guest") + VirtualMachineGuestOsIdentifierDarwin13_64Guest = VirtualMachineGuestOsIdentifier("darwin13_64Guest") + VirtualMachineGuestOsIdentifierDarwin14_64Guest = VirtualMachineGuestOsIdentifier("darwin14_64Guest") + VirtualMachineGuestOsIdentifierVmkernelGuest = VirtualMachineGuestOsIdentifier("vmkernelGuest") + VirtualMachineGuestOsIdentifierVmkernel5Guest = VirtualMachineGuestOsIdentifier("vmkernel5Guest") + VirtualMachineGuestOsIdentifierVmkernel6Guest = VirtualMachineGuestOsIdentifier("vmkernel6Guest") + VirtualMachineGuestOsIdentifierOtherGuest = VirtualMachineGuestOsIdentifier("otherGuest") + VirtualMachineGuestOsIdentifierOtherGuest64 = VirtualMachineGuestOsIdentifier("otherGuest64") +) + +func init() { + t["VirtualMachineGuestOsIdentifier"] = reflect.TypeOf((*VirtualMachineGuestOsIdentifier)(nil)).Elem() +} + +type VirtualMachineGuestState string + +const ( + VirtualMachineGuestStateRunning = VirtualMachineGuestState("running") + VirtualMachineGuestStateShuttingDown = VirtualMachineGuestState("shuttingDown") + VirtualMachineGuestStateResetting = VirtualMachineGuestState("resetting") + VirtualMachineGuestStateStandby = VirtualMachineGuestState("standby") + VirtualMachineGuestStateNotRunning = VirtualMachineGuestState("notRunning") + VirtualMachineGuestStateUnknown = VirtualMachineGuestState("unknown") +) + +func init() { + t["VirtualMachineGuestState"] = reflect.TypeOf((*VirtualMachineGuestState)(nil)).Elem() +} + +type VirtualMachineHtSharing string + +const ( + VirtualMachineHtSharingAny = VirtualMachineHtSharing("any") + VirtualMachineHtSharingNone = VirtualMachineHtSharing("none") + VirtualMachineHtSharingInternal = VirtualMachineHtSharing("internal") +) + +func init() { + t["VirtualMachineHtSharing"] = reflect.TypeOf((*VirtualMachineHtSharing)(nil)).Elem() +} + +type VirtualMachineMemoryAllocationPolicy string + +const ( + VirtualMachineMemoryAllocationPolicySwapNone = VirtualMachineMemoryAllocationPolicy("swapNone") + VirtualMachineMemoryAllocationPolicySwapSome = VirtualMachineMemoryAllocationPolicy("swapSome") + VirtualMachineMemoryAllocationPolicySwapMost = VirtualMachineMemoryAllocationPolicy("swapMost") +) + +func init() { + t["VirtualMachineMemoryAllocationPolicy"] = reflect.TypeOf((*VirtualMachineMemoryAllocationPolicy)(nil)).Elem() +} + +type VirtualMachineMetadataManagerVmMetadataOp string + +const ( + VirtualMachineMetadataManagerVmMetadataOpUpdate = VirtualMachineMetadataManagerVmMetadataOp("Update") + VirtualMachineMetadataManagerVmMetadataOpRemove = VirtualMachineMetadataManagerVmMetadataOp("Remove") +) + +func init() { + t["VirtualMachineMetadataManagerVmMetadataOp"] = reflect.TypeOf((*VirtualMachineMetadataManagerVmMetadataOp)(nil)).Elem() +} + +type VirtualMachineMetadataManagerVmMetadataOwnerOwner string + +const ( + VirtualMachineMetadataManagerVmMetadataOwnerOwnerComVmwareVsphereHA = VirtualMachineMetadataManagerVmMetadataOwnerOwner("ComVmwareVsphereHA") +) + +func init() { + t["VirtualMachineMetadataManagerVmMetadataOwnerOwner"] = reflect.TypeOf((*VirtualMachineMetadataManagerVmMetadataOwnerOwner)(nil)).Elem() +} + +type VirtualMachineMovePriority string + +const ( + VirtualMachineMovePriorityLowPriority = VirtualMachineMovePriority("lowPriority") + VirtualMachineMovePriorityHighPriority = VirtualMachineMovePriority("highPriority") + VirtualMachineMovePriorityDefaultPriority = VirtualMachineMovePriority("defaultPriority") +) + +func init() { + t["VirtualMachineMovePriority"] = reflect.TypeOf((*VirtualMachineMovePriority)(nil)).Elem() +} + +type VirtualMachineNeedSecondaryReason string + +const ( + VirtualMachineNeedSecondaryReasonInitializing = VirtualMachineNeedSecondaryReason("initializing") + VirtualMachineNeedSecondaryReasonDivergence = VirtualMachineNeedSecondaryReason("divergence") + VirtualMachineNeedSecondaryReasonLostConnection = VirtualMachineNeedSecondaryReason("lostConnection") + VirtualMachineNeedSecondaryReasonPartialHardwareFailure = VirtualMachineNeedSecondaryReason("partialHardwareFailure") + VirtualMachineNeedSecondaryReasonUserAction = VirtualMachineNeedSecondaryReason("userAction") + VirtualMachineNeedSecondaryReasonCheckpointError = VirtualMachineNeedSecondaryReason("checkpointError") + VirtualMachineNeedSecondaryReasonOther = VirtualMachineNeedSecondaryReason("other") +) + +func init() { + t["VirtualMachineNeedSecondaryReason"] = reflect.TypeOf((*VirtualMachineNeedSecondaryReason)(nil)).Elem() +} + +type VirtualMachinePowerOffBehavior string + +const ( + VirtualMachinePowerOffBehaviorPowerOff = VirtualMachinePowerOffBehavior("powerOff") + VirtualMachinePowerOffBehaviorRevert = VirtualMachinePowerOffBehavior("revert") + VirtualMachinePowerOffBehaviorPrompt = VirtualMachinePowerOffBehavior("prompt") + VirtualMachinePowerOffBehaviorTake = VirtualMachinePowerOffBehavior("take") +) + +func init() { + t["VirtualMachinePowerOffBehavior"] = reflect.TypeOf((*VirtualMachinePowerOffBehavior)(nil)).Elem() +} + +type VirtualMachinePowerOpType string + +const ( + VirtualMachinePowerOpTypeSoft = VirtualMachinePowerOpType("soft") + VirtualMachinePowerOpTypeHard = VirtualMachinePowerOpType("hard") + VirtualMachinePowerOpTypePreset = VirtualMachinePowerOpType("preset") +) + +func init() { + t["VirtualMachinePowerOpType"] = reflect.TypeOf((*VirtualMachinePowerOpType)(nil)).Elem() +} + +type VirtualMachinePowerState string + +const ( + VirtualMachinePowerStatePoweredOff = VirtualMachinePowerState("poweredOff") + VirtualMachinePowerStatePoweredOn = VirtualMachinePowerState("poweredOn") + VirtualMachinePowerStateSuspended = VirtualMachinePowerState("suspended") +) + +func init() { + t["VirtualMachinePowerState"] = reflect.TypeOf((*VirtualMachinePowerState)(nil)).Elem() +} + +type VirtualMachineRecordReplayState string + +const ( + VirtualMachineRecordReplayStateRecording = VirtualMachineRecordReplayState("recording") + VirtualMachineRecordReplayStateReplaying = VirtualMachineRecordReplayState("replaying") + VirtualMachineRecordReplayStateInactive = VirtualMachineRecordReplayState("inactive") +) + +func init() { + t["VirtualMachineRecordReplayState"] = reflect.TypeOf((*VirtualMachineRecordReplayState)(nil)).Elem() +} + +type VirtualMachineRelocateDiskMoveOptions string + +const ( + VirtualMachineRelocateDiskMoveOptionsMoveAllDiskBackingsAndAllowSharing = VirtualMachineRelocateDiskMoveOptions("moveAllDiskBackingsAndAllowSharing") + VirtualMachineRelocateDiskMoveOptionsMoveAllDiskBackingsAndDisallowSharing = VirtualMachineRelocateDiskMoveOptions("moveAllDiskBackingsAndDisallowSharing") + VirtualMachineRelocateDiskMoveOptionsMoveChildMostDiskBacking = VirtualMachineRelocateDiskMoveOptions("moveChildMostDiskBacking") + VirtualMachineRelocateDiskMoveOptionsCreateNewChildDiskBacking = VirtualMachineRelocateDiskMoveOptions("createNewChildDiskBacking") + VirtualMachineRelocateDiskMoveOptionsMoveAllDiskBackingsAndConsolidate = VirtualMachineRelocateDiskMoveOptions("moveAllDiskBackingsAndConsolidate") +) + +func init() { + t["VirtualMachineRelocateDiskMoveOptions"] = reflect.TypeOf((*VirtualMachineRelocateDiskMoveOptions)(nil)).Elem() +} + +type VirtualMachineRelocateTransformation string + +const ( + VirtualMachineRelocateTransformationFlat = VirtualMachineRelocateTransformation("flat") + VirtualMachineRelocateTransformationSparse = VirtualMachineRelocateTransformation("sparse") +) + +func init() { + t["VirtualMachineRelocateTransformation"] = reflect.TypeOf((*VirtualMachineRelocateTransformation)(nil)).Elem() +} + +type VirtualMachineScsiPassthroughType string + +const ( + VirtualMachineScsiPassthroughTypeDisk = VirtualMachineScsiPassthroughType("disk") + VirtualMachineScsiPassthroughTypeTape = VirtualMachineScsiPassthroughType("tape") + VirtualMachineScsiPassthroughTypePrinter = VirtualMachineScsiPassthroughType("printer") + VirtualMachineScsiPassthroughTypeProcessor = VirtualMachineScsiPassthroughType("processor") + VirtualMachineScsiPassthroughTypeWorm = VirtualMachineScsiPassthroughType("worm") + VirtualMachineScsiPassthroughTypeCdrom = VirtualMachineScsiPassthroughType("cdrom") + VirtualMachineScsiPassthroughTypeScanner = VirtualMachineScsiPassthroughType("scanner") + VirtualMachineScsiPassthroughTypeOptical = VirtualMachineScsiPassthroughType("optical") + VirtualMachineScsiPassthroughTypeMedia = VirtualMachineScsiPassthroughType("media") + VirtualMachineScsiPassthroughTypeCom = VirtualMachineScsiPassthroughType("com") + VirtualMachineScsiPassthroughTypeRaid = VirtualMachineScsiPassthroughType("raid") + VirtualMachineScsiPassthroughTypeUnknown = VirtualMachineScsiPassthroughType("unknown") +) + +func init() { + t["VirtualMachineScsiPassthroughType"] = reflect.TypeOf((*VirtualMachineScsiPassthroughType)(nil)).Elem() +} + +type VirtualMachineStandbyActionType string + +const ( + VirtualMachineStandbyActionTypeCheckpoint = VirtualMachineStandbyActionType("checkpoint") + VirtualMachineStandbyActionTypePowerOnSuspend = VirtualMachineStandbyActionType("powerOnSuspend") +) + +func init() { + t["VirtualMachineStandbyActionType"] = reflect.TypeOf((*VirtualMachineStandbyActionType)(nil)).Elem() +} + +type VirtualMachineTargetInfoConfigurationTag string + +const ( + VirtualMachineTargetInfoConfigurationTagCompliant = VirtualMachineTargetInfoConfigurationTag("compliant") + VirtualMachineTargetInfoConfigurationTagClusterWide = VirtualMachineTargetInfoConfigurationTag("clusterWide") +) + +func init() { + t["VirtualMachineTargetInfoConfigurationTag"] = reflect.TypeOf((*VirtualMachineTargetInfoConfigurationTag)(nil)).Elem() +} + +type VirtualMachineTicketType string + +const ( + VirtualMachineTicketTypeMks = VirtualMachineTicketType("mks") + VirtualMachineTicketTypeDevice = VirtualMachineTicketType("device") + VirtualMachineTicketTypeGuestControl = VirtualMachineTicketType("guestControl") + VirtualMachineTicketTypeWebmks = VirtualMachineTicketType("webmks") +) + +func init() { + t["VirtualMachineTicketType"] = reflect.TypeOf((*VirtualMachineTicketType)(nil)).Elem() +} + +type VirtualMachineToolsRunningStatus string + +const ( + VirtualMachineToolsRunningStatusGuestToolsNotRunning = VirtualMachineToolsRunningStatus("guestToolsNotRunning") + VirtualMachineToolsRunningStatusGuestToolsRunning = VirtualMachineToolsRunningStatus("guestToolsRunning") + VirtualMachineToolsRunningStatusGuestToolsExecutingScripts = VirtualMachineToolsRunningStatus("guestToolsExecutingScripts") +) + +func init() { + t["VirtualMachineToolsRunningStatus"] = reflect.TypeOf((*VirtualMachineToolsRunningStatus)(nil)).Elem() +} + +type VirtualMachineToolsStatus string + +const ( + VirtualMachineToolsStatusToolsNotInstalled = VirtualMachineToolsStatus("toolsNotInstalled") + VirtualMachineToolsStatusToolsNotRunning = VirtualMachineToolsStatus("toolsNotRunning") + VirtualMachineToolsStatusToolsOld = VirtualMachineToolsStatus("toolsOld") + VirtualMachineToolsStatusToolsOk = VirtualMachineToolsStatus("toolsOk") +) + +func init() { + t["VirtualMachineToolsStatus"] = reflect.TypeOf((*VirtualMachineToolsStatus)(nil)).Elem() +} + +type VirtualMachineToolsVersionStatus string + +const ( + VirtualMachineToolsVersionStatusGuestToolsNotInstalled = VirtualMachineToolsVersionStatus("guestToolsNotInstalled") + VirtualMachineToolsVersionStatusGuestToolsNeedUpgrade = VirtualMachineToolsVersionStatus("guestToolsNeedUpgrade") + VirtualMachineToolsVersionStatusGuestToolsCurrent = VirtualMachineToolsVersionStatus("guestToolsCurrent") + VirtualMachineToolsVersionStatusGuestToolsUnmanaged = VirtualMachineToolsVersionStatus("guestToolsUnmanaged") + VirtualMachineToolsVersionStatusGuestToolsTooOld = VirtualMachineToolsVersionStatus("guestToolsTooOld") + VirtualMachineToolsVersionStatusGuestToolsSupportedOld = VirtualMachineToolsVersionStatus("guestToolsSupportedOld") + VirtualMachineToolsVersionStatusGuestToolsSupportedNew = VirtualMachineToolsVersionStatus("guestToolsSupportedNew") + VirtualMachineToolsVersionStatusGuestToolsTooNew = VirtualMachineToolsVersionStatus("guestToolsTooNew") + VirtualMachineToolsVersionStatusGuestToolsBlacklisted = VirtualMachineToolsVersionStatus("guestToolsBlacklisted") +) + +func init() { + t["VirtualMachineToolsVersionStatus"] = reflect.TypeOf((*VirtualMachineToolsVersionStatus)(nil)).Elem() +} + +type VirtualMachineUsbInfoFamily string + +const ( + VirtualMachineUsbInfoFamilyAudio = VirtualMachineUsbInfoFamily("audio") + VirtualMachineUsbInfoFamilyHid = VirtualMachineUsbInfoFamily("hid") + VirtualMachineUsbInfoFamilyHid_bootable = VirtualMachineUsbInfoFamily("hid_bootable") + VirtualMachineUsbInfoFamilyPhysical = VirtualMachineUsbInfoFamily("physical") + VirtualMachineUsbInfoFamilyCommunication = VirtualMachineUsbInfoFamily("communication") + VirtualMachineUsbInfoFamilyImaging = VirtualMachineUsbInfoFamily("imaging") + VirtualMachineUsbInfoFamilyPrinter = VirtualMachineUsbInfoFamily("printer") + VirtualMachineUsbInfoFamilyStorage = VirtualMachineUsbInfoFamily("storage") + VirtualMachineUsbInfoFamilyHub = VirtualMachineUsbInfoFamily("hub") + VirtualMachineUsbInfoFamilySmart_card = VirtualMachineUsbInfoFamily("smart_card") + VirtualMachineUsbInfoFamilySecurity = VirtualMachineUsbInfoFamily("security") + VirtualMachineUsbInfoFamilyVideo = VirtualMachineUsbInfoFamily("video") + VirtualMachineUsbInfoFamilyWireless = VirtualMachineUsbInfoFamily("wireless") + VirtualMachineUsbInfoFamilyBluetooth = VirtualMachineUsbInfoFamily("bluetooth") + VirtualMachineUsbInfoFamilyWusb = VirtualMachineUsbInfoFamily("wusb") + VirtualMachineUsbInfoFamilyPda = VirtualMachineUsbInfoFamily("pda") + VirtualMachineUsbInfoFamilyVendor_specific = VirtualMachineUsbInfoFamily("vendor_specific") + VirtualMachineUsbInfoFamilyOther = VirtualMachineUsbInfoFamily("other") + VirtualMachineUsbInfoFamilyUnknownFamily = VirtualMachineUsbInfoFamily("unknownFamily") +) + +func init() { + t["VirtualMachineUsbInfoFamily"] = reflect.TypeOf((*VirtualMachineUsbInfoFamily)(nil)).Elem() +} + +type VirtualMachineUsbInfoSpeed string + +const ( + VirtualMachineUsbInfoSpeedLow = VirtualMachineUsbInfoSpeed("low") + VirtualMachineUsbInfoSpeedFull = VirtualMachineUsbInfoSpeed("full") + VirtualMachineUsbInfoSpeedHigh = VirtualMachineUsbInfoSpeed("high") + VirtualMachineUsbInfoSpeedSuperSpeed = VirtualMachineUsbInfoSpeed("superSpeed") + VirtualMachineUsbInfoSpeedUnknownSpeed = VirtualMachineUsbInfoSpeed("unknownSpeed") +) + +func init() { + t["VirtualMachineUsbInfoSpeed"] = reflect.TypeOf((*VirtualMachineUsbInfoSpeed)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceAction string + +const ( + VirtualMachineVMCIDeviceActionAllow = VirtualMachineVMCIDeviceAction("allow") + VirtualMachineVMCIDeviceActionDeny = VirtualMachineVMCIDeviceAction("deny") +) + +func init() { + t["VirtualMachineVMCIDeviceAction"] = reflect.TypeOf((*VirtualMachineVMCIDeviceAction)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceDirection string + +const ( + VirtualMachineVMCIDeviceDirectionGuest = VirtualMachineVMCIDeviceDirection("guest") + VirtualMachineVMCIDeviceDirectionHost = VirtualMachineVMCIDeviceDirection("host") + VirtualMachineVMCIDeviceDirectionAnyDirection = VirtualMachineVMCIDeviceDirection("anyDirection") +) + +func init() { + t["VirtualMachineVMCIDeviceDirection"] = reflect.TypeOf((*VirtualMachineVMCIDeviceDirection)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceProtocol string + +const ( + VirtualMachineVMCIDeviceProtocolHypervisor = VirtualMachineVMCIDeviceProtocol("hypervisor") + VirtualMachineVMCIDeviceProtocolDoorbell = VirtualMachineVMCIDeviceProtocol("doorbell") + VirtualMachineVMCIDeviceProtocolQueuepair = VirtualMachineVMCIDeviceProtocol("queuepair") + VirtualMachineVMCIDeviceProtocolDatagram = VirtualMachineVMCIDeviceProtocol("datagram") + VirtualMachineVMCIDeviceProtocolStream = VirtualMachineVMCIDeviceProtocol("stream") + VirtualMachineVMCIDeviceProtocolAnyProtocol = VirtualMachineVMCIDeviceProtocol("anyProtocol") +) + +func init() { + t["VirtualMachineVMCIDeviceProtocol"] = reflect.TypeOf((*VirtualMachineVMCIDeviceProtocol)(nil)).Elem() +} + +type VirtualMachineVideoCardUse3dRenderer string + +const ( + VirtualMachineVideoCardUse3dRendererAutomatic = VirtualMachineVideoCardUse3dRenderer("automatic") + VirtualMachineVideoCardUse3dRendererSoftware = VirtualMachineVideoCardUse3dRenderer("software") + VirtualMachineVideoCardUse3dRendererHardware = VirtualMachineVideoCardUse3dRenderer("hardware") +) + +func init() { + t["VirtualMachineVideoCardUse3dRenderer"] = reflect.TypeOf((*VirtualMachineVideoCardUse3dRenderer)(nil)).Elem() +} + +type VirtualPointingDeviceHostChoice string + +const ( + VirtualPointingDeviceHostChoiceAutodetect = VirtualPointingDeviceHostChoice("autodetect") + VirtualPointingDeviceHostChoiceIntellimouseExplorer = VirtualPointingDeviceHostChoice("intellimouseExplorer") + VirtualPointingDeviceHostChoiceIntellimousePs2 = VirtualPointingDeviceHostChoice("intellimousePs2") + VirtualPointingDeviceHostChoiceLogitechMouseman = VirtualPointingDeviceHostChoice("logitechMouseman") + VirtualPointingDeviceHostChoiceMicrosoft_serial = VirtualPointingDeviceHostChoice("microsoft_serial") + VirtualPointingDeviceHostChoiceMouseSystems = VirtualPointingDeviceHostChoice("mouseSystems") + VirtualPointingDeviceHostChoiceMousemanSerial = VirtualPointingDeviceHostChoice("mousemanSerial") + VirtualPointingDeviceHostChoicePs2 = VirtualPointingDeviceHostChoice("ps2") +) + +func init() { + t["VirtualPointingDeviceHostChoice"] = reflect.TypeOf((*VirtualPointingDeviceHostChoice)(nil)).Elem() +} + +type VirtualSCSISharing string + +const ( + VirtualSCSISharingNoSharing = VirtualSCSISharing("noSharing") + VirtualSCSISharingVirtualSharing = VirtualSCSISharing("virtualSharing") + VirtualSCSISharingPhysicalSharing = VirtualSCSISharing("physicalSharing") +) + +func init() { + t["VirtualSCSISharing"] = reflect.TypeOf((*VirtualSCSISharing)(nil)).Elem() +} + +type VirtualSerialPortEndPoint string + +const ( + VirtualSerialPortEndPointClient = VirtualSerialPortEndPoint("client") + VirtualSerialPortEndPointServer = VirtualSerialPortEndPoint("server") +) + +func init() { + t["VirtualSerialPortEndPoint"] = reflect.TypeOf((*VirtualSerialPortEndPoint)(nil)).Elem() +} + +type VmDasBeingResetEventReasonCode string + +const ( + VmDasBeingResetEventReasonCodeVmtoolsHeartbeatFailure = VmDasBeingResetEventReasonCode("vmtoolsHeartbeatFailure") + VmDasBeingResetEventReasonCodeAppHeartbeatFailure = VmDasBeingResetEventReasonCode("appHeartbeatFailure") + VmDasBeingResetEventReasonCodeAppImmediateResetRequest = VmDasBeingResetEventReasonCode("appImmediateResetRequest") + VmDasBeingResetEventReasonCodeVmcpResetApdCleared = VmDasBeingResetEventReasonCode("vmcpResetApdCleared") +) + +func init() { + t["VmDasBeingResetEventReasonCode"] = reflect.TypeOf((*VmDasBeingResetEventReasonCode)(nil)).Elem() +} + +type VmFailedStartingSecondaryEventFailureReason string + +const ( + VmFailedStartingSecondaryEventFailureReasonIncompatibleHost = VmFailedStartingSecondaryEventFailureReason("incompatibleHost") + VmFailedStartingSecondaryEventFailureReasonLoginFailed = VmFailedStartingSecondaryEventFailureReason("loginFailed") + VmFailedStartingSecondaryEventFailureReasonRegisterVmFailed = VmFailedStartingSecondaryEventFailureReason("registerVmFailed") + VmFailedStartingSecondaryEventFailureReasonMigrateFailed = VmFailedStartingSecondaryEventFailureReason("migrateFailed") +) + +func init() { + t["VmFailedStartingSecondaryEventFailureReason"] = reflect.TypeOf((*VmFailedStartingSecondaryEventFailureReason)(nil)).Elem() +} + +type VmFaultToleranceConfigIssueReasonForIssue string + +const ( + VmFaultToleranceConfigIssueReasonForIssueHaNotEnabled = VmFaultToleranceConfigIssueReasonForIssue("haNotEnabled") + VmFaultToleranceConfigIssueReasonForIssueMoreThanOneSecondary = VmFaultToleranceConfigIssueReasonForIssue("moreThanOneSecondary") + VmFaultToleranceConfigIssueReasonForIssueRecordReplayNotSupported = VmFaultToleranceConfigIssueReasonForIssue("recordReplayNotSupported") + VmFaultToleranceConfigIssueReasonForIssueReplayNotSupported = VmFaultToleranceConfigIssueReasonForIssue("replayNotSupported") + VmFaultToleranceConfigIssueReasonForIssueTemplateVm = VmFaultToleranceConfigIssueReasonForIssue("templateVm") + VmFaultToleranceConfigIssueReasonForIssueMultipleVCPU = VmFaultToleranceConfigIssueReasonForIssue("multipleVCPU") + VmFaultToleranceConfigIssueReasonForIssueHostInactive = VmFaultToleranceConfigIssueReasonForIssue("hostInactive") + VmFaultToleranceConfigIssueReasonForIssueFtUnsupportedHardware = VmFaultToleranceConfigIssueReasonForIssue("ftUnsupportedHardware") + VmFaultToleranceConfigIssueReasonForIssueFtUnsupportedProduct = VmFaultToleranceConfigIssueReasonForIssue("ftUnsupportedProduct") + VmFaultToleranceConfigIssueReasonForIssueMissingVMotionNic = VmFaultToleranceConfigIssueReasonForIssue("missingVMotionNic") + VmFaultToleranceConfigIssueReasonForIssueMissingFTLoggingNic = VmFaultToleranceConfigIssueReasonForIssue("missingFTLoggingNic") + VmFaultToleranceConfigIssueReasonForIssueThinDisk = VmFaultToleranceConfigIssueReasonForIssue("thinDisk") + VmFaultToleranceConfigIssueReasonForIssueVerifySSLCertificateFlagNotSet = VmFaultToleranceConfigIssueReasonForIssue("verifySSLCertificateFlagNotSet") + VmFaultToleranceConfigIssueReasonForIssueHasSnapshots = VmFaultToleranceConfigIssueReasonForIssue("hasSnapshots") + VmFaultToleranceConfigIssueReasonForIssueNoConfig = VmFaultToleranceConfigIssueReasonForIssue("noConfig") + VmFaultToleranceConfigIssueReasonForIssueFtSecondaryVm = VmFaultToleranceConfigIssueReasonForIssue("ftSecondaryVm") + VmFaultToleranceConfigIssueReasonForIssueHasLocalDisk = VmFaultToleranceConfigIssueReasonForIssue("hasLocalDisk") + VmFaultToleranceConfigIssueReasonForIssueEsxAgentVm = VmFaultToleranceConfigIssueReasonForIssue("esxAgentVm") + VmFaultToleranceConfigIssueReasonForIssueVideo3dEnabled = VmFaultToleranceConfigIssueReasonForIssue("video3dEnabled") + VmFaultToleranceConfigIssueReasonForIssueHasUnsupportedDisk = VmFaultToleranceConfigIssueReasonForIssue("hasUnsupportedDisk") + VmFaultToleranceConfigIssueReasonForIssueInsufficientBandwidth = VmFaultToleranceConfigIssueReasonForIssue("insufficientBandwidth") + VmFaultToleranceConfigIssueReasonForIssueHasNestedHVConfiguration = VmFaultToleranceConfigIssueReasonForIssue("hasNestedHVConfiguration") + VmFaultToleranceConfigIssueReasonForIssueHasVFlashConfiguration = VmFaultToleranceConfigIssueReasonForIssue("hasVFlashConfiguration") + VmFaultToleranceConfigIssueReasonForIssueUnsupportedProduct = VmFaultToleranceConfigIssueReasonForIssue("unsupportedProduct") + VmFaultToleranceConfigIssueReasonForIssueCpuHvUnsupported = VmFaultToleranceConfigIssueReasonForIssue("cpuHvUnsupported") + VmFaultToleranceConfigIssueReasonForIssueCpuHwmmuUnsupported = VmFaultToleranceConfigIssueReasonForIssue("cpuHwmmuUnsupported") + VmFaultToleranceConfigIssueReasonForIssueCpuHvDisabled = VmFaultToleranceConfigIssueReasonForIssue("cpuHvDisabled") + VmFaultToleranceConfigIssueReasonForIssueHasEFIFirmware = VmFaultToleranceConfigIssueReasonForIssue("hasEFIFirmware") +) + +func init() { + t["VmFaultToleranceConfigIssueReasonForIssue"] = reflect.TypeOf((*VmFaultToleranceConfigIssueReasonForIssue)(nil)).Elem() +} + +type VmFaultToleranceInvalidFileBackingDeviceType string + +const ( + VmFaultToleranceInvalidFileBackingDeviceTypeVirtualFloppy = VmFaultToleranceInvalidFileBackingDeviceType("virtualFloppy") + VmFaultToleranceInvalidFileBackingDeviceTypeVirtualCdrom = VmFaultToleranceInvalidFileBackingDeviceType("virtualCdrom") + VmFaultToleranceInvalidFileBackingDeviceTypeVirtualSerialPort = VmFaultToleranceInvalidFileBackingDeviceType("virtualSerialPort") + VmFaultToleranceInvalidFileBackingDeviceTypeVirtualParallelPort = VmFaultToleranceInvalidFileBackingDeviceType("virtualParallelPort") + VmFaultToleranceInvalidFileBackingDeviceTypeVirtualDisk = VmFaultToleranceInvalidFileBackingDeviceType("virtualDisk") +) + +func init() { + t["VmFaultToleranceInvalidFileBackingDeviceType"] = reflect.TypeOf((*VmFaultToleranceInvalidFileBackingDeviceType)(nil)).Elem() +} + +type VmShutdownOnIsolationEventOperation string + +const ( + VmShutdownOnIsolationEventOperationShutdown = VmShutdownOnIsolationEventOperation("shutdown") + VmShutdownOnIsolationEventOperationPoweredOff = VmShutdownOnIsolationEventOperation("poweredOff") +) + +func init() { + t["VmShutdownOnIsolationEventOperation"] = reflect.TypeOf((*VmShutdownOnIsolationEventOperation)(nil)).Elem() +} + +type VmwareDistributedVirtualSwitchPvlanPortType string + +const ( + VmwareDistributedVirtualSwitchPvlanPortTypePromiscuous = VmwareDistributedVirtualSwitchPvlanPortType("promiscuous") + VmwareDistributedVirtualSwitchPvlanPortTypeIsolated = VmwareDistributedVirtualSwitchPvlanPortType("isolated") + VmwareDistributedVirtualSwitchPvlanPortTypeCommunity = VmwareDistributedVirtualSwitchPvlanPortType("community") +) + +func init() { + t["VmwareDistributedVirtualSwitchPvlanPortType"] = reflect.TypeOf((*VmwareDistributedVirtualSwitchPvlanPortType)(nil)).Elem() +} + +type VsanDiskIssueType string + +const ( + VsanDiskIssueTypeNonExist = VsanDiskIssueType("nonExist") + VsanDiskIssueTypeStampMismatch = VsanDiskIssueType("stampMismatch") + VsanDiskIssueTypeUnknown = VsanDiskIssueType("unknown") +) + +func init() { + t["VsanDiskIssueType"] = reflect.TypeOf((*VsanDiskIssueType)(nil)).Elem() +} + +type VsanHostDecommissionModeObjectAction string + +const ( + VsanHostDecommissionModeObjectActionNoAction = VsanHostDecommissionModeObjectAction("noAction") + VsanHostDecommissionModeObjectActionEnsureObjectAccessibility = VsanHostDecommissionModeObjectAction("ensureObjectAccessibility") + VsanHostDecommissionModeObjectActionEvacuateAllData = VsanHostDecommissionModeObjectAction("evacuateAllData") +) + +func init() { + t["VsanHostDecommissionModeObjectAction"] = reflect.TypeOf((*VsanHostDecommissionModeObjectAction)(nil)).Elem() +} + +type VsanHostDiskResultState string + +const ( + VsanHostDiskResultStateInUse = VsanHostDiskResultState("inUse") + VsanHostDiskResultStateEligible = VsanHostDiskResultState("eligible") + VsanHostDiskResultStateIneligible = VsanHostDiskResultState("ineligible") +) + +func init() { + t["VsanHostDiskResultState"] = reflect.TypeOf((*VsanHostDiskResultState)(nil)).Elem() +} + +type VsanHostHealthState string + +const ( + VsanHostHealthStateUnknown = VsanHostHealthState("unknown") + VsanHostHealthStateHealthy = VsanHostHealthState("healthy") + VsanHostHealthStateUnhealthy = VsanHostHealthState("unhealthy") +) + +func init() { + t["VsanHostHealthState"] = reflect.TypeOf((*VsanHostHealthState)(nil)).Elem() +} + +type VsanHostNodeState string + +const ( + VsanHostNodeStateError = VsanHostNodeState("error") + VsanHostNodeStateDisabled = VsanHostNodeState("disabled") + VsanHostNodeStateAgent = VsanHostNodeState("agent") + VsanHostNodeStateMaster = VsanHostNodeState("master") + VsanHostNodeStateBackup = VsanHostNodeState("backup") + VsanHostNodeStateStarting = VsanHostNodeState("starting") + VsanHostNodeStateStopping = VsanHostNodeState("stopping") + VsanHostNodeStateEnteringMaintenanceMode = VsanHostNodeState("enteringMaintenanceMode") + VsanHostNodeStateExitingMaintenanceMode = VsanHostNodeState("exitingMaintenanceMode") + VsanHostNodeStateDecommissioning = VsanHostNodeState("decommissioning") +) + +func init() { + t["VsanHostNodeState"] = reflect.TypeOf((*VsanHostNodeState)(nil)).Elem() +} + +type VsanUpgradeSystemUpgradeHistoryDiskGroupOpType string + +const ( + VsanUpgradeSystemUpgradeHistoryDiskGroupOpTypeAdd = VsanUpgradeSystemUpgradeHistoryDiskGroupOpType("add") + VsanUpgradeSystemUpgradeHistoryDiskGroupOpTypeRemove = VsanUpgradeSystemUpgradeHistoryDiskGroupOpType("remove") +) + +func init() { + t["VsanUpgradeSystemUpgradeHistoryDiskGroupOpType"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeHistoryDiskGroupOpType)(nil)).Elem() +} + +type WeekOfMonth string + +const ( + WeekOfMonthFirst = WeekOfMonth("first") + WeekOfMonthSecond = WeekOfMonth("second") + WeekOfMonthThird = WeekOfMonth("third") + WeekOfMonthFourth = WeekOfMonth("fourth") + WeekOfMonthLast = WeekOfMonth("last") +) + +func init() { + t["WeekOfMonth"] = reflect.TypeOf((*WeekOfMonth)(nil)).Elem() +} + +type WillLoseHAProtectionResolution string + +const ( + WillLoseHAProtectionResolutionSvmotion = WillLoseHAProtectionResolution("svmotion") + WillLoseHAProtectionResolutionRelocate = WillLoseHAProtectionResolution("relocate") +) + +func init() { + t["WillLoseHAProtectionResolution"] = reflect.TypeOf((*WillLoseHAProtectionResolution)(nil)).Elem() +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/fault.go b/vendor/github.com/vmware/govmomi/vim25/types/fault.go new file mode 100644 index 0000000000..c2503fa5cb --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/fault.go @@ -0,0 +1,32 @@ +/* +Copyright (c) 2015 VMware, 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 types + +type HasFault interface { + Fault() BaseMethodFault +} + +func IsFileNotFound(err error) bool { + if f, ok := err.(HasFault); ok { + switch f.Fault().(type) { + case *FileNotFound: + return true + } + } + + return false +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/helpers.go b/vendor/github.com/vmware/govmomi/vim25/types/helpers.go new file mode 100644 index 0000000000..75c82cab3f --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/helpers.go @@ -0,0 +1,25 @@ +/* +Copyright (c) 2015 VMware, 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 types + +func NewBool(v bool) *bool { + return &v +} + +func NewReference(r ManagedObjectReference) *ManagedObjectReference { + return &r +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/if.go b/vendor/github.com/vmware/govmomi/vim25/types/if.go new file mode 100644 index 0000000000..5894e90698 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/if.go @@ -0,0 +1,3287 @@ +/* +Copyright (c) 2014-2016 VMware, 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 types + +import "reflect" + +func (b *Action) GetAction() *Action { return b } + +type BaseAction interface { + GetAction() *Action +} + +func init() { + t["BaseAction"] = reflect.TypeOf((*Action)(nil)).Elem() +} + +func (b *ActiveDirectoryFault) GetActiveDirectoryFault() *ActiveDirectoryFault { return b } + +type BaseActiveDirectoryFault interface { + GetActiveDirectoryFault() *ActiveDirectoryFault +} + +func init() { + t["BaseActiveDirectoryFault"] = reflect.TypeOf((*ActiveDirectoryFault)(nil)).Elem() +} + +func (b *AlarmAction) GetAlarmAction() *AlarmAction { return b } + +type BaseAlarmAction interface { + GetAlarmAction() *AlarmAction +} + +func init() { + t["BaseAlarmAction"] = reflect.TypeOf((*AlarmAction)(nil)).Elem() +} + +func (b *AlarmEvent) GetAlarmEvent() *AlarmEvent { return b } + +type BaseAlarmEvent interface { + GetAlarmEvent() *AlarmEvent +} + +func init() { + t["BaseAlarmEvent"] = reflect.TypeOf((*AlarmEvent)(nil)).Elem() +} + +func (b *AlarmExpression) GetAlarmExpression() *AlarmExpression { return b } + +type BaseAlarmExpression interface { + GetAlarmExpression() *AlarmExpression +} + +func init() { + t["BaseAlarmExpression"] = reflect.TypeOf((*AlarmExpression)(nil)).Elem() +} + +func (b *AlarmSpec) GetAlarmSpec() *AlarmSpec { return b } + +type BaseAlarmSpec interface { + GetAlarmSpec() *AlarmSpec +} + +func init() { + t["BaseAlarmSpec"] = reflect.TypeOf((*AlarmSpec)(nil)).Elem() +} + +func (b *AnswerFileCreateSpec) GetAnswerFileCreateSpec() *AnswerFileCreateSpec { return b } + +type BaseAnswerFileCreateSpec interface { + GetAnswerFileCreateSpec() *AnswerFileCreateSpec +} + +func init() { + t["BaseAnswerFileCreateSpec"] = reflect.TypeOf((*AnswerFileCreateSpec)(nil)).Elem() +} + +func (b *ApplyProfile) GetApplyProfile() *ApplyProfile { return b } + +type BaseApplyProfile interface { + GetApplyProfile() *ApplyProfile +} + +func init() { + t["BaseApplyProfile"] = reflect.TypeOf((*ApplyProfile)(nil)).Elem() +} + +func (b *ArrayUpdateSpec) GetArrayUpdateSpec() *ArrayUpdateSpec { return b } + +type BaseArrayUpdateSpec interface { + GetArrayUpdateSpec() *ArrayUpdateSpec +} + +func init() { + t["BaseArrayUpdateSpec"] = reflect.TypeOf((*ArrayUpdateSpec)(nil)).Elem() +} + +func (b *AuthorizationEvent) GetAuthorizationEvent() *AuthorizationEvent { return b } + +type BaseAuthorizationEvent interface { + GetAuthorizationEvent() *AuthorizationEvent +} + +func init() { + t["BaseAuthorizationEvent"] = reflect.TypeOf((*AuthorizationEvent)(nil)).Elem() +} + +func (b *CannotAccessNetwork) GetCannotAccessNetwork() *CannotAccessNetwork { return b } + +type BaseCannotAccessNetwork interface { + GetCannotAccessNetwork() *CannotAccessNetwork +} + +func init() { + t["BaseCannotAccessNetwork"] = reflect.TypeOf((*CannotAccessNetwork)(nil)).Elem() +} + +func (b *CannotAccessVmComponent) GetCannotAccessVmComponent() *CannotAccessVmComponent { return b } + +type BaseCannotAccessVmComponent interface { + GetCannotAccessVmComponent() *CannotAccessVmComponent +} + +func init() { + t["BaseCannotAccessVmComponent"] = reflect.TypeOf((*CannotAccessVmComponent)(nil)).Elem() +} + +func (b *CannotAccessVmDevice) GetCannotAccessVmDevice() *CannotAccessVmDevice { return b } + +type BaseCannotAccessVmDevice interface { + GetCannotAccessVmDevice() *CannotAccessVmDevice +} + +func init() { + t["BaseCannotAccessVmDevice"] = reflect.TypeOf((*CannotAccessVmDevice)(nil)).Elem() +} + +func (b *CannotAccessVmDisk) GetCannotAccessVmDisk() *CannotAccessVmDisk { return b } + +type BaseCannotAccessVmDisk interface { + GetCannotAccessVmDisk() *CannotAccessVmDisk +} + +func init() { + t["BaseCannotAccessVmDisk"] = reflect.TypeOf((*CannotAccessVmDisk)(nil)).Elem() +} + +func (b *CannotMoveVsanEnabledHost) GetCannotMoveVsanEnabledHost() *CannotMoveVsanEnabledHost { + return b +} + +type BaseCannotMoveVsanEnabledHost interface { + GetCannotMoveVsanEnabledHost() *CannotMoveVsanEnabledHost +} + +func init() { + t["BaseCannotMoveVsanEnabledHost"] = reflect.TypeOf((*CannotMoveVsanEnabledHost)(nil)).Elem() +} + +func (b *ClusterAction) GetClusterAction() *ClusterAction { return b } + +type BaseClusterAction interface { + GetClusterAction() *ClusterAction +} + +func init() { + t["BaseClusterAction"] = reflect.TypeOf((*ClusterAction)(nil)).Elem() +} + +func (b *ClusterDasAdmissionControlInfo) GetClusterDasAdmissionControlInfo() *ClusterDasAdmissionControlInfo { + return b +} + +type BaseClusterDasAdmissionControlInfo interface { + GetClusterDasAdmissionControlInfo() *ClusterDasAdmissionControlInfo +} + +func init() { + t["BaseClusterDasAdmissionControlInfo"] = reflect.TypeOf((*ClusterDasAdmissionControlInfo)(nil)).Elem() +} + +func (b *ClusterDasAdmissionControlPolicy) GetClusterDasAdmissionControlPolicy() *ClusterDasAdmissionControlPolicy { + return b +} + +type BaseClusterDasAdmissionControlPolicy interface { + GetClusterDasAdmissionControlPolicy() *ClusterDasAdmissionControlPolicy +} + +func init() { + t["BaseClusterDasAdmissionControlPolicy"] = reflect.TypeOf((*ClusterDasAdmissionControlPolicy)(nil)).Elem() +} + +func (b *ClusterDasAdvancedRuntimeInfo) GetClusterDasAdvancedRuntimeInfo() *ClusterDasAdvancedRuntimeInfo { + return b +} + +type BaseClusterDasAdvancedRuntimeInfo interface { + GetClusterDasAdvancedRuntimeInfo() *ClusterDasAdvancedRuntimeInfo +} + +func init() { + t["BaseClusterDasAdvancedRuntimeInfo"] = reflect.TypeOf((*ClusterDasAdvancedRuntimeInfo)(nil)).Elem() +} + +func (b *ClusterDasData) GetClusterDasData() *ClusterDasData { return b } + +type BaseClusterDasData interface { + GetClusterDasData() *ClusterDasData +} + +func init() { + t["BaseClusterDasData"] = reflect.TypeOf((*ClusterDasData)(nil)).Elem() +} + +func (b *ClusterDasHostInfo) GetClusterDasHostInfo() *ClusterDasHostInfo { return b } + +type BaseClusterDasHostInfo interface { + GetClusterDasHostInfo() *ClusterDasHostInfo +} + +func init() { + t["BaseClusterDasHostInfo"] = reflect.TypeOf((*ClusterDasHostInfo)(nil)).Elem() +} + +func (b *ClusterDrsFaultsFaultsByVm) GetClusterDrsFaultsFaultsByVm() *ClusterDrsFaultsFaultsByVm { + return b +} + +type BaseClusterDrsFaultsFaultsByVm interface { + GetClusterDrsFaultsFaultsByVm() *ClusterDrsFaultsFaultsByVm +} + +func init() { + t["BaseClusterDrsFaultsFaultsByVm"] = reflect.TypeOf((*ClusterDrsFaultsFaultsByVm)(nil)).Elem() +} + +func (b *ClusterEvent) GetClusterEvent() *ClusterEvent { return b } + +type BaseClusterEvent interface { + GetClusterEvent() *ClusterEvent +} + +func init() { + t["BaseClusterEvent"] = reflect.TypeOf((*ClusterEvent)(nil)).Elem() +} + +func (b *ClusterGroupInfo) GetClusterGroupInfo() *ClusterGroupInfo { return b } + +type BaseClusterGroupInfo interface { + GetClusterGroupInfo() *ClusterGroupInfo +} + +func init() { + t["BaseClusterGroupInfo"] = reflect.TypeOf((*ClusterGroupInfo)(nil)).Elem() +} + +func (b *ClusterOvercommittedEvent) GetClusterOvercommittedEvent() *ClusterOvercommittedEvent { + return b +} + +type BaseClusterOvercommittedEvent interface { + GetClusterOvercommittedEvent() *ClusterOvercommittedEvent +} + +func init() { + t["BaseClusterOvercommittedEvent"] = reflect.TypeOf((*ClusterOvercommittedEvent)(nil)).Elem() +} + +func (b *ClusterProfileConfigSpec) GetClusterProfileConfigSpec() *ClusterProfileConfigSpec { return b } + +type BaseClusterProfileConfigSpec interface { + GetClusterProfileConfigSpec() *ClusterProfileConfigSpec +} + +func init() { + t["BaseClusterProfileConfigSpec"] = reflect.TypeOf((*ClusterProfileConfigSpec)(nil)).Elem() +} + +func (b *ClusterProfileCreateSpec) GetClusterProfileCreateSpec() *ClusterProfileCreateSpec { return b } + +type BaseClusterProfileCreateSpec interface { + GetClusterProfileCreateSpec() *ClusterProfileCreateSpec +} + +func init() { + t["BaseClusterProfileCreateSpec"] = reflect.TypeOf((*ClusterProfileCreateSpec)(nil)).Elem() +} + +func (b *ClusterRuleInfo) GetClusterRuleInfo() *ClusterRuleInfo { return b } + +type BaseClusterRuleInfo interface { + GetClusterRuleInfo() *ClusterRuleInfo +} + +func init() { + t["BaseClusterRuleInfo"] = reflect.TypeOf((*ClusterRuleInfo)(nil)).Elem() +} + +func (b *ClusterSlotPolicy) GetClusterSlotPolicy() *ClusterSlotPolicy { return b } + +type BaseClusterSlotPolicy interface { + GetClusterSlotPolicy() *ClusterSlotPolicy +} + +func init() { + t["BaseClusterSlotPolicy"] = reflect.TypeOf((*ClusterSlotPolicy)(nil)).Elem() +} + +func (b *ClusterStatusChangedEvent) GetClusterStatusChangedEvent() *ClusterStatusChangedEvent { + return b +} + +type BaseClusterStatusChangedEvent interface { + GetClusterStatusChangedEvent() *ClusterStatusChangedEvent +} + +func init() { + t["BaseClusterStatusChangedEvent"] = reflect.TypeOf((*ClusterStatusChangedEvent)(nil)).Elem() +} + +func (b *ComputeResourceConfigInfo) GetComputeResourceConfigInfo() *ComputeResourceConfigInfo { + return b +} + +type BaseComputeResourceConfigInfo interface { + GetComputeResourceConfigInfo() *ComputeResourceConfigInfo +} + +func init() { + t["BaseComputeResourceConfigInfo"] = reflect.TypeOf((*ComputeResourceConfigInfo)(nil)).Elem() +} + +func (b *ComputeResourceConfigSpec) GetComputeResourceConfigSpec() *ComputeResourceConfigSpec { + return b +} + +type BaseComputeResourceConfigSpec interface { + GetComputeResourceConfigSpec() *ComputeResourceConfigSpec +} + +func init() { + t["BaseComputeResourceConfigSpec"] = reflect.TypeOf((*ComputeResourceConfigSpec)(nil)).Elem() +} + +func (b *ComputeResourceSummary) GetComputeResourceSummary() *ComputeResourceSummary { return b } + +type BaseComputeResourceSummary interface { + GetComputeResourceSummary() *ComputeResourceSummary +} + +func init() { + t["BaseComputeResourceSummary"] = reflect.TypeOf((*ComputeResourceSummary)(nil)).Elem() +} + +func (b *CpuIncompatible) GetCpuIncompatible() *CpuIncompatible { return b } + +type BaseCpuIncompatible interface { + GetCpuIncompatible() *CpuIncompatible +} + +func init() { + t["BaseCpuIncompatible"] = reflect.TypeOf((*CpuIncompatible)(nil)).Elem() +} + +func (b *CustomFieldDefEvent) GetCustomFieldDefEvent() *CustomFieldDefEvent { return b } + +type BaseCustomFieldDefEvent interface { + GetCustomFieldDefEvent() *CustomFieldDefEvent +} + +func init() { + t["BaseCustomFieldDefEvent"] = reflect.TypeOf((*CustomFieldDefEvent)(nil)).Elem() +} + +func (b *CustomFieldEvent) GetCustomFieldEvent() *CustomFieldEvent { return b } + +type BaseCustomFieldEvent interface { + GetCustomFieldEvent() *CustomFieldEvent +} + +func init() { + t["BaseCustomFieldEvent"] = reflect.TypeOf((*CustomFieldEvent)(nil)).Elem() +} + +func (b *CustomFieldValue) GetCustomFieldValue() *CustomFieldValue { return b } + +type BaseCustomFieldValue interface { + GetCustomFieldValue() *CustomFieldValue +} + +func init() { + t["BaseCustomFieldValue"] = reflect.TypeOf((*CustomFieldValue)(nil)).Elem() +} + +func (b *CustomizationEvent) GetCustomizationEvent() *CustomizationEvent { return b } + +type BaseCustomizationEvent interface { + GetCustomizationEvent() *CustomizationEvent +} + +func init() { + t["BaseCustomizationEvent"] = reflect.TypeOf((*CustomizationEvent)(nil)).Elem() +} + +func (b *CustomizationFailed) GetCustomizationFailed() *CustomizationFailed { return b } + +type BaseCustomizationFailed interface { + GetCustomizationFailed() *CustomizationFailed +} + +func init() { + t["BaseCustomizationFailed"] = reflect.TypeOf((*CustomizationFailed)(nil)).Elem() +} + +func (b *CustomizationFault) GetCustomizationFault() *CustomizationFault { return b } + +type BaseCustomizationFault interface { + GetCustomizationFault() *CustomizationFault +} + +func init() { + t["BaseCustomizationFault"] = reflect.TypeOf((*CustomizationFault)(nil)).Elem() +} + +func (b *CustomizationIdentitySettings) GetCustomizationIdentitySettings() *CustomizationIdentitySettings { + return b +} + +type BaseCustomizationIdentitySettings interface { + GetCustomizationIdentitySettings() *CustomizationIdentitySettings +} + +func init() { + t["BaseCustomizationIdentitySettings"] = reflect.TypeOf((*CustomizationIdentitySettings)(nil)).Elem() +} + +func (b *CustomizationIpGenerator) GetCustomizationIpGenerator() *CustomizationIpGenerator { return b } + +type BaseCustomizationIpGenerator interface { + GetCustomizationIpGenerator() *CustomizationIpGenerator +} + +func init() { + t["BaseCustomizationIpGenerator"] = reflect.TypeOf((*CustomizationIpGenerator)(nil)).Elem() +} + +func (b *CustomizationIpV6Generator) GetCustomizationIpV6Generator() *CustomizationIpV6Generator { + return b +} + +type BaseCustomizationIpV6Generator interface { + GetCustomizationIpV6Generator() *CustomizationIpV6Generator +} + +func init() { + t["BaseCustomizationIpV6Generator"] = reflect.TypeOf((*CustomizationIpV6Generator)(nil)).Elem() +} + +func (b *CustomizationName) GetCustomizationName() *CustomizationName { return b } + +type BaseCustomizationName interface { + GetCustomizationName() *CustomizationName +} + +func init() { + t["BaseCustomizationName"] = reflect.TypeOf((*CustomizationName)(nil)).Elem() +} + +func (b *CustomizationOptions) GetCustomizationOptions() *CustomizationOptions { return b } + +type BaseCustomizationOptions interface { + GetCustomizationOptions() *CustomizationOptions +} + +func init() { + t["BaseCustomizationOptions"] = reflect.TypeOf((*CustomizationOptions)(nil)).Elem() +} + +func (b *DVPortSetting) GetDVPortSetting() *DVPortSetting { return b } + +type BaseDVPortSetting interface { + GetDVPortSetting() *DVPortSetting +} + +func init() { + t["BaseDVPortSetting"] = reflect.TypeOf((*DVPortSetting)(nil)).Elem() +} + +func (b *DVPortgroupEvent) GetDVPortgroupEvent() *DVPortgroupEvent { return b } + +type BaseDVPortgroupEvent interface { + GetDVPortgroupEvent() *DVPortgroupEvent +} + +func init() { + t["BaseDVPortgroupEvent"] = reflect.TypeOf((*DVPortgroupEvent)(nil)).Elem() +} + +func (b *DVPortgroupPolicy) GetDVPortgroupPolicy() *DVPortgroupPolicy { return b } + +type BaseDVPortgroupPolicy interface { + GetDVPortgroupPolicy() *DVPortgroupPolicy +} + +func init() { + t["BaseDVPortgroupPolicy"] = reflect.TypeOf((*DVPortgroupPolicy)(nil)).Elem() +} + +func (b *DVSConfigInfo) GetDVSConfigInfo() *DVSConfigInfo { return b } + +type BaseDVSConfigInfo interface { + GetDVSConfigInfo() *DVSConfigInfo +} + +func init() { + t["BaseDVSConfigInfo"] = reflect.TypeOf((*DVSConfigInfo)(nil)).Elem() +} + +func (b *DVSConfigSpec) GetDVSConfigSpec() *DVSConfigSpec { return b } + +type BaseDVSConfigSpec interface { + GetDVSConfigSpec() *DVSConfigSpec +} + +func init() { + t["BaseDVSConfigSpec"] = reflect.TypeOf((*DVSConfigSpec)(nil)).Elem() +} + +func (b *DVSFeatureCapability) GetDVSFeatureCapability() *DVSFeatureCapability { return b } + +type BaseDVSFeatureCapability interface { + GetDVSFeatureCapability() *DVSFeatureCapability +} + +func init() { + t["BaseDVSFeatureCapability"] = reflect.TypeOf((*DVSFeatureCapability)(nil)).Elem() +} + +func (b *DVSHealthCheckCapability) GetDVSHealthCheckCapability() *DVSHealthCheckCapability { return b } + +type BaseDVSHealthCheckCapability interface { + GetDVSHealthCheckCapability() *DVSHealthCheckCapability +} + +func init() { + t["BaseDVSHealthCheckCapability"] = reflect.TypeOf((*DVSHealthCheckCapability)(nil)).Elem() +} + +func (b *DVSHealthCheckConfig) GetDVSHealthCheckConfig() *DVSHealthCheckConfig { return b } + +type BaseDVSHealthCheckConfig interface { + GetDVSHealthCheckConfig() *DVSHealthCheckConfig +} + +func init() { + t["BaseDVSHealthCheckConfig"] = reflect.TypeOf((*DVSHealthCheckConfig)(nil)).Elem() +} + +func (b *DVSUplinkPortPolicy) GetDVSUplinkPortPolicy() *DVSUplinkPortPolicy { return b } + +type BaseDVSUplinkPortPolicy interface { + GetDVSUplinkPortPolicy() *DVSUplinkPortPolicy +} + +func init() { + t["BaseDVSUplinkPortPolicy"] = reflect.TypeOf((*DVSUplinkPortPolicy)(nil)).Elem() +} + +func (b *DailyTaskScheduler) GetDailyTaskScheduler() *DailyTaskScheduler { return b } + +type BaseDailyTaskScheduler interface { + GetDailyTaskScheduler() *DailyTaskScheduler +} + +func init() { + t["BaseDailyTaskScheduler"] = reflect.TypeOf((*DailyTaskScheduler)(nil)).Elem() +} + +func (b *DatacenterEvent) GetDatacenterEvent() *DatacenterEvent { return b } + +type BaseDatacenterEvent interface { + GetDatacenterEvent() *DatacenterEvent +} + +func init() { + t["BaseDatacenterEvent"] = reflect.TypeOf((*DatacenterEvent)(nil)).Elem() +} + +func (b *DatastoreEvent) GetDatastoreEvent() *DatastoreEvent { return b } + +type BaseDatastoreEvent interface { + GetDatastoreEvent() *DatastoreEvent +} + +func init() { + t["BaseDatastoreEvent"] = reflect.TypeOf((*DatastoreEvent)(nil)).Elem() +} + +func (b *DatastoreFileEvent) GetDatastoreFileEvent() *DatastoreFileEvent { return b } + +type BaseDatastoreFileEvent interface { + GetDatastoreFileEvent() *DatastoreFileEvent +} + +func init() { + t["BaseDatastoreFileEvent"] = reflect.TypeOf((*DatastoreFileEvent)(nil)).Elem() +} + +func (b *DatastoreInfo) GetDatastoreInfo() *DatastoreInfo { return b } + +type BaseDatastoreInfo interface { + GetDatastoreInfo() *DatastoreInfo +} + +func init() { + t["BaseDatastoreInfo"] = reflect.TypeOf((*DatastoreInfo)(nil)).Elem() +} + +func (b *DatastoreNotWritableOnHost) GetDatastoreNotWritableOnHost() *DatastoreNotWritableOnHost { + return b +} + +type BaseDatastoreNotWritableOnHost interface { + GetDatastoreNotWritableOnHost() *DatastoreNotWritableOnHost +} + +func init() { + t["BaseDatastoreNotWritableOnHost"] = reflect.TypeOf((*DatastoreNotWritableOnHost)(nil)).Elem() +} + +func (b *Description) GetDescription() *Description { return b } + +type BaseDescription interface { + GetDescription() *Description +} + +func init() { + t["BaseDescription"] = reflect.TypeOf((*Description)(nil)).Elem() +} + +func (b *DeviceBackingNotSupported) GetDeviceBackingNotSupported() *DeviceBackingNotSupported { + return b +} + +type BaseDeviceBackingNotSupported interface { + GetDeviceBackingNotSupported() *DeviceBackingNotSupported +} + +func init() { + t["BaseDeviceBackingNotSupported"] = reflect.TypeOf((*DeviceBackingNotSupported)(nil)).Elem() +} + +func (b *DeviceNotSupported) GetDeviceNotSupported() *DeviceNotSupported { return b } + +type BaseDeviceNotSupported interface { + GetDeviceNotSupported() *DeviceNotSupported +} + +func init() { + t["BaseDeviceNotSupported"] = reflect.TypeOf((*DeviceNotSupported)(nil)).Elem() +} + +func (b *DiskNotSupported) GetDiskNotSupported() *DiskNotSupported { return b } + +type BaseDiskNotSupported interface { + GetDiskNotSupported() *DiskNotSupported +} + +func init() { + t["BaseDiskNotSupported"] = reflect.TypeOf((*DiskNotSupported)(nil)).Elem() +} + +func (b *DistributedVirtualSwitchHostMemberBacking) GetDistributedVirtualSwitchHostMemberBacking() *DistributedVirtualSwitchHostMemberBacking { + return b +} + +type BaseDistributedVirtualSwitchHostMemberBacking interface { + GetDistributedVirtualSwitchHostMemberBacking() *DistributedVirtualSwitchHostMemberBacking +} + +func init() { + t["BaseDistributedVirtualSwitchHostMemberBacking"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberBacking)(nil)).Elem() +} + +func (b *DistributedVirtualSwitchManagerHostDvsFilterSpec) GetDistributedVirtualSwitchManagerHostDvsFilterSpec() *DistributedVirtualSwitchManagerHostDvsFilterSpec { + return b +} + +type BaseDistributedVirtualSwitchManagerHostDvsFilterSpec interface { + GetDistributedVirtualSwitchManagerHostDvsFilterSpec() *DistributedVirtualSwitchManagerHostDvsFilterSpec +} + +func init() { + t["BaseDistributedVirtualSwitchManagerHostDvsFilterSpec"] = reflect.TypeOf((*DistributedVirtualSwitchManagerHostDvsFilterSpec)(nil)).Elem() +} + +func (b *DvsEvent) GetDvsEvent() *DvsEvent { return b } + +type BaseDvsEvent interface { + GetDvsEvent() *DvsEvent +} + +func init() { + t["BaseDvsEvent"] = reflect.TypeOf((*DvsEvent)(nil)).Elem() +} + +func (b *DvsFault) GetDvsFault() *DvsFault { return b } + +type BaseDvsFault interface { + GetDvsFault() *DvsFault +} + +func init() { + t["BaseDvsFault"] = reflect.TypeOf((*DvsFault)(nil)).Elem() +} + +func (b *DvsFilterConfig) GetDvsFilterConfig() *DvsFilterConfig { return b } + +type BaseDvsFilterConfig interface { + GetDvsFilterConfig() *DvsFilterConfig +} + +func init() { + t["BaseDvsFilterConfig"] = reflect.TypeOf((*DvsFilterConfig)(nil)).Elem() +} + +func (b *DvsHealthStatusChangeEvent) GetDvsHealthStatusChangeEvent() *DvsHealthStatusChangeEvent { + return b +} + +type BaseDvsHealthStatusChangeEvent interface { + GetDvsHealthStatusChangeEvent() *DvsHealthStatusChangeEvent +} + +func init() { + t["BaseDvsHealthStatusChangeEvent"] = reflect.TypeOf((*DvsHealthStatusChangeEvent)(nil)).Elem() +} + +func (b *DvsIpPort) GetDvsIpPort() *DvsIpPort { return b } + +type BaseDvsIpPort interface { + GetDvsIpPort() *DvsIpPort +} + +func init() { + t["BaseDvsIpPort"] = reflect.TypeOf((*DvsIpPort)(nil)).Elem() +} + +func (b *DvsNetworkRuleAction) GetDvsNetworkRuleAction() *DvsNetworkRuleAction { return b } + +type BaseDvsNetworkRuleAction interface { + GetDvsNetworkRuleAction() *DvsNetworkRuleAction +} + +func init() { + t["BaseDvsNetworkRuleAction"] = reflect.TypeOf((*DvsNetworkRuleAction)(nil)).Elem() +} + +func (b *DvsNetworkRuleQualifier) GetDvsNetworkRuleQualifier() *DvsNetworkRuleQualifier { return b } + +type BaseDvsNetworkRuleQualifier interface { + GetDvsNetworkRuleQualifier() *DvsNetworkRuleQualifier +} + +func init() { + t["BaseDvsNetworkRuleQualifier"] = reflect.TypeOf((*DvsNetworkRuleQualifier)(nil)).Elem() +} + +func (b *DvsTrafficFilterConfig) GetDvsTrafficFilterConfig() *DvsTrafficFilterConfig { return b } + +type BaseDvsTrafficFilterConfig interface { + GetDvsTrafficFilterConfig() *DvsTrafficFilterConfig +} + +func init() { + t["BaseDvsTrafficFilterConfig"] = reflect.TypeOf((*DvsTrafficFilterConfig)(nil)).Elem() +} + +func (b *DvsVNicProfile) GetDvsVNicProfile() *DvsVNicProfile { return b } + +type BaseDvsVNicProfile interface { + GetDvsVNicProfile() *DvsVNicProfile +} + +func init() { + t["BaseDvsVNicProfile"] = reflect.TypeOf((*DvsVNicProfile)(nil)).Elem() +} + +func (b *DynamicData) GetDynamicData() *DynamicData { return b } + +type BaseDynamicData interface { + GetDynamicData() *DynamicData +} + +func init() { + t["BaseDynamicData"] = reflect.TypeOf((*DynamicData)(nil)).Elem() +} + +func (b *EVCAdmissionFailed) GetEVCAdmissionFailed() *EVCAdmissionFailed { return b } + +type BaseEVCAdmissionFailed interface { + GetEVCAdmissionFailed() *EVCAdmissionFailed +} + +func init() { + t["BaseEVCAdmissionFailed"] = reflect.TypeOf((*EVCAdmissionFailed)(nil)).Elem() +} + +func (b *EVCConfigFault) GetEVCConfigFault() *EVCConfigFault { return b } + +type BaseEVCConfigFault interface { + GetEVCConfigFault() *EVCConfigFault +} + +func init() { + t["BaseEVCConfigFault"] = reflect.TypeOf((*EVCConfigFault)(nil)).Elem() +} + +func (b *ElementDescription) GetElementDescription() *ElementDescription { return b } + +type BaseElementDescription interface { + GetElementDescription() *ElementDescription +} + +func init() { + t["BaseElementDescription"] = reflect.TypeOf((*ElementDescription)(nil)).Elem() +} + +func (b *EnteredStandbyModeEvent) GetEnteredStandbyModeEvent() *EnteredStandbyModeEvent { return b } + +type BaseEnteredStandbyModeEvent interface { + GetEnteredStandbyModeEvent() *EnteredStandbyModeEvent +} + +func init() { + t["BaseEnteredStandbyModeEvent"] = reflect.TypeOf((*EnteredStandbyModeEvent)(nil)).Elem() +} + +func (b *EnteringStandbyModeEvent) GetEnteringStandbyModeEvent() *EnteringStandbyModeEvent { return b } + +type BaseEnteringStandbyModeEvent interface { + GetEnteringStandbyModeEvent() *EnteringStandbyModeEvent +} + +func init() { + t["BaseEnteringStandbyModeEvent"] = reflect.TypeOf((*EnteringStandbyModeEvent)(nil)).Elem() +} + +func (b *EntityEventArgument) GetEntityEventArgument() *EntityEventArgument { return b } + +type BaseEntityEventArgument interface { + GetEntityEventArgument() *EntityEventArgument +} + +func init() { + t["BaseEntityEventArgument"] = reflect.TypeOf((*EntityEventArgument)(nil)).Elem() +} + +func (b *Event) GetEvent() *Event { return b } + +type BaseEvent interface { + GetEvent() *Event +} + +func init() { + t["BaseEvent"] = reflect.TypeOf((*Event)(nil)).Elem() +} + +func (b *EventArgument) GetEventArgument() *EventArgument { return b } + +type BaseEventArgument interface { + GetEventArgument() *EventArgument +} + +func init() { + t["BaseEventArgument"] = reflect.TypeOf((*EventArgument)(nil)).Elem() +} + +func (b *ExitStandbyModeFailedEvent) GetExitStandbyModeFailedEvent() *ExitStandbyModeFailedEvent { + return b +} + +type BaseExitStandbyModeFailedEvent interface { + GetExitStandbyModeFailedEvent() *ExitStandbyModeFailedEvent +} + +func init() { + t["BaseExitStandbyModeFailedEvent"] = reflect.TypeOf((*ExitStandbyModeFailedEvent)(nil)).Elem() +} + +func (b *ExitedStandbyModeEvent) GetExitedStandbyModeEvent() *ExitedStandbyModeEvent { return b } + +type BaseExitedStandbyModeEvent interface { + GetExitedStandbyModeEvent() *ExitedStandbyModeEvent +} + +func init() { + t["BaseExitedStandbyModeEvent"] = reflect.TypeOf((*ExitedStandbyModeEvent)(nil)).Elem() +} + +func (b *ExitingStandbyModeEvent) GetExitingStandbyModeEvent() *ExitingStandbyModeEvent { return b } + +type BaseExitingStandbyModeEvent interface { + GetExitingStandbyModeEvent() *ExitingStandbyModeEvent +} + +func init() { + t["BaseExitingStandbyModeEvent"] = reflect.TypeOf((*ExitingStandbyModeEvent)(nil)).Elem() +} + +func (b *ExpiredFeatureLicense) GetExpiredFeatureLicense() *ExpiredFeatureLicense { return b } + +type BaseExpiredFeatureLicense interface { + GetExpiredFeatureLicense() *ExpiredFeatureLicense +} + +func init() { + t["BaseExpiredFeatureLicense"] = reflect.TypeOf((*ExpiredFeatureLicense)(nil)).Elem() +} + +func (b *FaultToleranceConfigInfo) GetFaultToleranceConfigInfo() *FaultToleranceConfigInfo { return b } + +type BaseFaultToleranceConfigInfo interface { + GetFaultToleranceConfigInfo() *FaultToleranceConfigInfo +} + +func init() { + t["BaseFaultToleranceConfigInfo"] = reflect.TypeOf((*FaultToleranceConfigInfo)(nil)).Elem() +} + +func (b *FcoeFault) GetFcoeFault() *FcoeFault { return b } + +type BaseFcoeFault interface { + GetFcoeFault() *FcoeFault +} + +func init() { + t["BaseFcoeFault"] = reflect.TypeOf((*FcoeFault)(nil)).Elem() +} + +func (b *FileBackedVirtualDiskSpec) GetFileBackedVirtualDiskSpec() *FileBackedVirtualDiskSpec { + return b +} + +type BaseFileBackedVirtualDiskSpec interface { + GetFileBackedVirtualDiskSpec() *FileBackedVirtualDiskSpec +} + +func init() { + t["BaseFileBackedVirtualDiskSpec"] = reflect.TypeOf((*FileBackedVirtualDiskSpec)(nil)).Elem() +} + +func (b *FileFault) GetFileFault() *FileFault { return b } + +type BaseFileFault interface { + GetFileFault() *FileFault +} + +func init() { + t["BaseFileFault"] = reflect.TypeOf((*FileFault)(nil)).Elem() +} + +func (b *FileInfo) GetFileInfo() *FileInfo { return b } + +type BaseFileInfo interface { + GetFileInfo() *FileInfo +} + +func init() { + t["BaseFileInfo"] = reflect.TypeOf((*FileInfo)(nil)).Elem() +} + +func (b *FileQuery) GetFileQuery() *FileQuery { return b } + +type BaseFileQuery interface { + GetFileQuery() *FileQuery +} + +func init() { + t["BaseFileQuery"] = reflect.TypeOf((*FileQuery)(nil)).Elem() +} + +func (b *GatewayConnectFault) GetGatewayConnectFault() *GatewayConnectFault { return b } + +type BaseGatewayConnectFault interface { + GetGatewayConnectFault() *GatewayConnectFault +} + +func init() { + t["BaseGatewayConnectFault"] = reflect.TypeOf((*GatewayConnectFault)(nil)).Elem() +} + +func (b *GatewayToHostConnectFault) GetGatewayToHostConnectFault() *GatewayToHostConnectFault { + return b +} + +type BaseGatewayToHostConnectFault interface { + GetGatewayToHostConnectFault() *GatewayToHostConnectFault +} + +func init() { + t["BaseGatewayToHostConnectFault"] = reflect.TypeOf((*GatewayToHostConnectFault)(nil)).Elem() +} + +func (b *GeneralEvent) GetGeneralEvent() *GeneralEvent { return b } + +type BaseGeneralEvent interface { + GetGeneralEvent() *GeneralEvent +} + +func init() { + t["BaseGeneralEvent"] = reflect.TypeOf((*GeneralEvent)(nil)).Elem() +} + +func (b *GuestAuthSubject) GetGuestAuthSubject() *GuestAuthSubject { return b } + +type BaseGuestAuthSubject interface { + GetGuestAuthSubject() *GuestAuthSubject +} + +func init() { + t["BaseGuestAuthSubject"] = reflect.TypeOf((*GuestAuthSubject)(nil)).Elem() +} + +func (b *GuestAuthentication) GetGuestAuthentication() *GuestAuthentication { return b } + +type BaseGuestAuthentication interface { + GetGuestAuthentication() *GuestAuthentication +} + +func init() { + t["BaseGuestAuthentication"] = reflect.TypeOf((*GuestAuthentication)(nil)).Elem() +} + +func (b *GuestFileAttributes) GetGuestFileAttributes() *GuestFileAttributes { return b } + +type BaseGuestFileAttributes interface { + GetGuestFileAttributes() *GuestFileAttributes +} + +func init() { + t["BaseGuestFileAttributes"] = reflect.TypeOf((*GuestFileAttributes)(nil)).Elem() +} + +func (b *GuestOperationsFault) GetGuestOperationsFault() *GuestOperationsFault { return b } + +type BaseGuestOperationsFault interface { + GetGuestOperationsFault() *GuestOperationsFault +} + +func init() { + t["BaseGuestOperationsFault"] = reflect.TypeOf((*GuestOperationsFault)(nil)).Elem() +} + +func (b *GuestProgramSpec) GetGuestProgramSpec() *GuestProgramSpec { return b } + +type BaseGuestProgramSpec interface { + GetGuestProgramSpec() *GuestProgramSpec +} + +func init() { + t["BaseGuestProgramSpec"] = reflect.TypeOf((*GuestProgramSpec)(nil)).Elem() +} + +func (b *GuestRegValueDataSpec) GetGuestRegValueDataSpec() *GuestRegValueDataSpec { return b } + +type BaseGuestRegValueDataSpec interface { + GetGuestRegValueDataSpec() *GuestRegValueDataSpec +} + +func init() { + t["BaseGuestRegValueDataSpec"] = reflect.TypeOf((*GuestRegValueDataSpec)(nil)).Elem() +} + +func (b *GuestRegistryFault) GetGuestRegistryFault() *GuestRegistryFault { return b } + +type BaseGuestRegistryFault interface { + GetGuestRegistryFault() *GuestRegistryFault +} + +func init() { + t["BaseGuestRegistryFault"] = reflect.TypeOf((*GuestRegistryFault)(nil)).Elem() +} + +func (b *GuestRegistryKeyFault) GetGuestRegistryKeyFault() *GuestRegistryKeyFault { return b } + +type BaseGuestRegistryKeyFault interface { + GetGuestRegistryKeyFault() *GuestRegistryKeyFault +} + +func init() { + t["BaseGuestRegistryKeyFault"] = reflect.TypeOf((*GuestRegistryKeyFault)(nil)).Elem() +} + +func (b *GuestRegistryValueFault) GetGuestRegistryValueFault() *GuestRegistryValueFault { return b } + +type BaseGuestRegistryValueFault interface { + GetGuestRegistryValueFault() *GuestRegistryValueFault +} + +func init() { + t["BaseGuestRegistryValueFault"] = reflect.TypeOf((*GuestRegistryValueFault)(nil)).Elem() +} + +func (b *HostAccountSpec) GetHostAccountSpec() *HostAccountSpec { return b } + +type BaseHostAccountSpec interface { + GetHostAccountSpec() *HostAccountSpec +} + +func init() { + t["BaseHostAccountSpec"] = reflect.TypeOf((*HostAccountSpec)(nil)).Elem() +} + +func (b *HostAuthenticationStoreInfo) GetHostAuthenticationStoreInfo() *HostAuthenticationStoreInfo { + return b +} + +type BaseHostAuthenticationStoreInfo interface { + GetHostAuthenticationStoreInfo() *HostAuthenticationStoreInfo +} + +func init() { + t["BaseHostAuthenticationStoreInfo"] = reflect.TypeOf((*HostAuthenticationStoreInfo)(nil)).Elem() +} + +func (b *HostCommunication) GetHostCommunication() *HostCommunication { return b } + +type BaseHostCommunication interface { + GetHostCommunication() *HostCommunication +} + +func init() { + t["BaseHostCommunication"] = reflect.TypeOf((*HostCommunication)(nil)).Elem() +} + +func (b *HostConfigFault) GetHostConfigFault() *HostConfigFault { return b } + +type BaseHostConfigFault interface { + GetHostConfigFault() *HostConfigFault +} + +func init() { + t["BaseHostConfigFault"] = reflect.TypeOf((*HostConfigFault)(nil)).Elem() +} + +func (b *HostConnectFault) GetHostConnectFault() *HostConnectFault { return b } + +type BaseHostConnectFault interface { + GetHostConnectFault() *HostConnectFault +} + +func init() { + t["BaseHostConnectFault"] = reflect.TypeOf((*HostConnectFault)(nil)).Elem() +} + +func (b *HostConnectInfoNetworkInfo) GetHostConnectInfoNetworkInfo() *HostConnectInfoNetworkInfo { + return b +} + +type BaseHostConnectInfoNetworkInfo interface { + GetHostConnectInfoNetworkInfo() *HostConnectInfoNetworkInfo +} + +func init() { + t["BaseHostConnectInfoNetworkInfo"] = reflect.TypeOf((*HostConnectInfoNetworkInfo)(nil)).Elem() +} + +func (b *HostDasEvent) GetHostDasEvent() *HostDasEvent { return b } + +type BaseHostDasEvent interface { + GetHostDasEvent() *HostDasEvent +} + +func init() { + t["BaseHostDasEvent"] = reflect.TypeOf((*HostDasEvent)(nil)).Elem() +} + +func (b *HostDatastoreConnectInfo) GetHostDatastoreConnectInfo() *HostDatastoreConnectInfo { return b } + +type BaseHostDatastoreConnectInfo interface { + GetHostDatastoreConnectInfo() *HostDatastoreConnectInfo +} + +func init() { + t["BaseHostDatastoreConnectInfo"] = reflect.TypeOf((*HostDatastoreConnectInfo)(nil)).Elem() +} + +func (b *HostDevice) GetHostDevice() *HostDevice { return b } + +type BaseHostDevice interface { + GetHostDevice() *HostDevice +} + +func init() { + t["BaseHostDevice"] = reflect.TypeOf((*HostDevice)(nil)).Elem() +} + +func (b *HostDigestInfo) GetHostDigestInfo() *HostDigestInfo { return b } + +type BaseHostDigestInfo interface { + GetHostDigestInfo() *HostDigestInfo +} + +func init() { + t["BaseHostDigestInfo"] = reflect.TypeOf((*HostDigestInfo)(nil)).Elem() +} + +func (b *HostDirectoryStoreInfo) GetHostDirectoryStoreInfo() *HostDirectoryStoreInfo { return b } + +type BaseHostDirectoryStoreInfo interface { + GetHostDirectoryStoreInfo() *HostDirectoryStoreInfo +} + +func init() { + t["BaseHostDirectoryStoreInfo"] = reflect.TypeOf((*HostDirectoryStoreInfo)(nil)).Elem() +} + +func (b *HostDnsConfig) GetHostDnsConfig() *HostDnsConfig { return b } + +type BaseHostDnsConfig interface { + GetHostDnsConfig() *HostDnsConfig +} + +func init() { + t["BaseHostDnsConfig"] = reflect.TypeOf((*HostDnsConfig)(nil)).Elem() +} + +func (b *HostEvent) GetHostEvent() *HostEvent { return b } + +type BaseHostEvent interface { + GetHostEvent() *HostEvent +} + +func init() { + t["BaseHostEvent"] = reflect.TypeOf((*HostEvent)(nil)).Elem() +} + +func (b *HostFibreChannelHba) GetHostFibreChannelHba() *HostFibreChannelHba { return b } + +type BaseHostFibreChannelHba interface { + GetHostFibreChannelHba() *HostFibreChannelHba +} + +func init() { + t["BaseHostFibreChannelHba"] = reflect.TypeOf((*HostFibreChannelHba)(nil)).Elem() +} + +func (b *HostFibreChannelTargetTransport) GetHostFibreChannelTargetTransport() *HostFibreChannelTargetTransport { + return b +} + +type BaseHostFibreChannelTargetTransport interface { + GetHostFibreChannelTargetTransport() *HostFibreChannelTargetTransport +} + +func init() { + t["BaseHostFibreChannelTargetTransport"] = reflect.TypeOf((*HostFibreChannelTargetTransport)(nil)).Elem() +} + +func (b *HostFileSystemVolume) GetHostFileSystemVolume() *HostFileSystemVolume { return b } + +type BaseHostFileSystemVolume interface { + GetHostFileSystemVolume() *HostFileSystemVolume +} + +func init() { + t["BaseHostFileSystemVolume"] = reflect.TypeOf((*HostFileSystemVolume)(nil)).Elem() +} + +func (b *HostHardwareElementInfo) GetHostHardwareElementInfo() *HostHardwareElementInfo { return b } + +type BaseHostHardwareElementInfo interface { + GetHostHardwareElementInfo() *HostHardwareElementInfo +} + +func init() { + t["BaseHostHardwareElementInfo"] = reflect.TypeOf((*HostHardwareElementInfo)(nil)).Elem() +} + +func (b *HostHostBusAdapter) GetHostHostBusAdapter() *HostHostBusAdapter { return b } + +type BaseHostHostBusAdapter interface { + GetHostHostBusAdapter() *HostHostBusAdapter +} + +func init() { + t["BaseHostHostBusAdapter"] = reflect.TypeOf((*HostHostBusAdapter)(nil)).Elem() +} + +func (b *HostIpRouteConfig) GetHostIpRouteConfig() *HostIpRouteConfig { return b } + +type BaseHostIpRouteConfig interface { + GetHostIpRouteConfig() *HostIpRouteConfig +} + +func init() { + t["BaseHostIpRouteConfig"] = reflect.TypeOf((*HostIpRouteConfig)(nil)).Elem() +} + +func (b *HostMemberHealthCheckResult) GetHostMemberHealthCheckResult() *HostMemberHealthCheckResult { + return b +} + +type BaseHostMemberHealthCheckResult interface { + GetHostMemberHealthCheckResult() *HostMemberHealthCheckResult +} + +func init() { + t["BaseHostMemberHealthCheckResult"] = reflect.TypeOf((*HostMemberHealthCheckResult)(nil)).Elem() +} + +func (b *HostMemberUplinkHealthCheckResult) GetHostMemberUplinkHealthCheckResult() *HostMemberUplinkHealthCheckResult { + return b +} + +type BaseHostMemberUplinkHealthCheckResult interface { + GetHostMemberUplinkHealthCheckResult() *HostMemberUplinkHealthCheckResult +} + +func init() { + t["BaseHostMemberUplinkHealthCheckResult"] = reflect.TypeOf((*HostMemberUplinkHealthCheckResult)(nil)).Elem() +} + +func (b *HostMultipathInfoLogicalUnitPolicy) GetHostMultipathInfoLogicalUnitPolicy() *HostMultipathInfoLogicalUnitPolicy { + return b +} + +type BaseHostMultipathInfoLogicalUnitPolicy interface { + GetHostMultipathInfoLogicalUnitPolicy() *HostMultipathInfoLogicalUnitPolicy +} + +func init() { + t["BaseHostMultipathInfoLogicalUnitPolicy"] = reflect.TypeOf((*HostMultipathInfoLogicalUnitPolicy)(nil)).Elem() +} + +func (b *HostPciPassthruConfig) GetHostPciPassthruConfig() *HostPciPassthruConfig { return b } + +type BaseHostPciPassthruConfig interface { + GetHostPciPassthruConfig() *HostPciPassthruConfig +} + +func init() { + t["BaseHostPciPassthruConfig"] = reflect.TypeOf((*HostPciPassthruConfig)(nil)).Elem() +} + +func (b *HostPciPassthruInfo) GetHostPciPassthruInfo() *HostPciPassthruInfo { return b } + +type BaseHostPciPassthruInfo interface { + GetHostPciPassthruInfo() *HostPciPassthruInfo +} + +func init() { + t["BaseHostPciPassthruInfo"] = reflect.TypeOf((*HostPciPassthruInfo)(nil)).Elem() +} + +func (b *HostPowerOpFailed) GetHostPowerOpFailed() *HostPowerOpFailed { return b } + +type BaseHostPowerOpFailed interface { + GetHostPowerOpFailed() *HostPowerOpFailed +} + +func init() { + t["BaseHostPowerOpFailed"] = reflect.TypeOf((*HostPowerOpFailed)(nil)).Elem() +} + +func (b *HostProfileConfigSpec) GetHostProfileConfigSpec() *HostProfileConfigSpec { return b } + +type BaseHostProfileConfigSpec interface { + GetHostProfileConfigSpec() *HostProfileConfigSpec +} + +func init() { + t["BaseHostProfileConfigSpec"] = reflect.TypeOf((*HostProfileConfigSpec)(nil)).Elem() +} + +func (b *HostSystemSwapConfigurationSystemSwapOption) GetHostSystemSwapConfigurationSystemSwapOption() *HostSystemSwapConfigurationSystemSwapOption { + return b +} + +type BaseHostSystemSwapConfigurationSystemSwapOption interface { + GetHostSystemSwapConfigurationSystemSwapOption() *HostSystemSwapConfigurationSystemSwapOption +} + +func init() { + t["BaseHostSystemSwapConfigurationSystemSwapOption"] = reflect.TypeOf((*HostSystemSwapConfigurationSystemSwapOption)(nil)).Elem() +} + +func (b *HostTargetTransport) GetHostTargetTransport() *HostTargetTransport { return b } + +type BaseHostTargetTransport interface { + GetHostTargetTransport() *HostTargetTransport +} + +func init() { + t["BaseHostTargetTransport"] = reflect.TypeOf((*HostTargetTransport)(nil)).Elem() +} + +func (b *HostTpmEventDetails) GetHostTpmEventDetails() *HostTpmEventDetails { return b } + +type BaseHostTpmEventDetails interface { + GetHostTpmEventDetails() *HostTpmEventDetails +} + +func init() { + t["BaseHostTpmEventDetails"] = reflect.TypeOf((*HostTpmEventDetails)(nil)).Elem() +} + +func (b *HostVirtualSwitchBridge) GetHostVirtualSwitchBridge() *HostVirtualSwitchBridge { return b } + +type BaseHostVirtualSwitchBridge interface { + GetHostVirtualSwitchBridge() *HostVirtualSwitchBridge +} + +func init() { + t["BaseHostVirtualSwitchBridge"] = reflect.TypeOf((*HostVirtualSwitchBridge)(nil)).Elem() +} + +func (b *HourlyTaskScheduler) GetHourlyTaskScheduler() *HourlyTaskScheduler { return b } + +type BaseHourlyTaskScheduler interface { + GetHourlyTaskScheduler() *HourlyTaskScheduler +} + +func init() { + t["BaseHourlyTaskScheduler"] = reflect.TypeOf((*HourlyTaskScheduler)(nil)).Elem() +} + +func (b *ImportSpec) GetImportSpec() *ImportSpec { return b } + +type BaseImportSpec interface { + GetImportSpec() *ImportSpec +} + +func init() { + t["BaseImportSpec"] = reflect.TypeOf((*ImportSpec)(nil)).Elem() +} + +func (b *InaccessibleDatastore) GetInaccessibleDatastore() *InaccessibleDatastore { return b } + +type BaseInaccessibleDatastore interface { + GetInaccessibleDatastore() *InaccessibleDatastore +} + +func init() { + t["BaseInaccessibleDatastore"] = reflect.TypeOf((*InaccessibleDatastore)(nil)).Elem() +} + +func (b *InheritablePolicy) GetInheritablePolicy() *InheritablePolicy { return b } + +type BaseInheritablePolicy interface { + GetInheritablePolicy() *InheritablePolicy +} + +func init() { + t["BaseInheritablePolicy"] = reflect.TypeOf((*InheritablePolicy)(nil)).Elem() +} + +func (b *InsufficientHostCapacityFault) GetInsufficientHostCapacityFault() *InsufficientHostCapacityFault { + return b +} + +type BaseInsufficientHostCapacityFault interface { + GetInsufficientHostCapacityFault() *InsufficientHostCapacityFault +} + +func init() { + t["BaseInsufficientHostCapacityFault"] = reflect.TypeOf((*InsufficientHostCapacityFault)(nil)).Elem() +} + +func (b *InsufficientResourcesFault) GetInsufficientResourcesFault() *InsufficientResourcesFault { + return b +} + +type BaseInsufficientResourcesFault interface { + GetInsufficientResourcesFault() *InsufficientResourcesFault +} + +func init() { + t["BaseInsufficientResourcesFault"] = reflect.TypeOf((*InsufficientResourcesFault)(nil)).Elem() +} + +func (b *InsufficientStandbyResource) GetInsufficientStandbyResource() *InsufficientStandbyResource { + return b +} + +type BaseInsufficientStandbyResource interface { + GetInsufficientStandbyResource() *InsufficientStandbyResource +} + +func init() { + t["BaseInsufficientStandbyResource"] = reflect.TypeOf((*InsufficientStandbyResource)(nil)).Elem() +} + +func (b *InvalidArgument) GetInvalidArgument() *InvalidArgument { return b } + +type BaseInvalidArgument interface { + GetInvalidArgument() *InvalidArgument +} + +func init() { + t["BaseInvalidArgument"] = reflect.TypeOf((*InvalidArgument)(nil)).Elem() +} + +func (b *InvalidCAMServer) GetInvalidCAMServer() *InvalidCAMServer { return b } + +type BaseInvalidCAMServer interface { + GetInvalidCAMServer() *InvalidCAMServer +} + +func init() { + t["BaseInvalidCAMServer"] = reflect.TypeOf((*InvalidCAMServer)(nil)).Elem() +} + +func (b *InvalidDatastore) GetInvalidDatastore() *InvalidDatastore { return b } + +type BaseInvalidDatastore interface { + GetInvalidDatastore() *InvalidDatastore +} + +func init() { + t["BaseInvalidDatastore"] = reflect.TypeOf((*InvalidDatastore)(nil)).Elem() +} + +func (b *InvalidDeviceSpec) GetInvalidDeviceSpec() *InvalidDeviceSpec { return b } + +type BaseInvalidDeviceSpec interface { + GetInvalidDeviceSpec() *InvalidDeviceSpec +} + +func init() { + t["BaseInvalidDeviceSpec"] = reflect.TypeOf((*InvalidDeviceSpec)(nil)).Elem() +} + +func (b *InvalidFolder) GetInvalidFolder() *InvalidFolder { return b } + +type BaseInvalidFolder interface { + GetInvalidFolder() *InvalidFolder +} + +func init() { + t["BaseInvalidFolder"] = reflect.TypeOf((*InvalidFolder)(nil)).Elem() +} + +func (b *InvalidFormat) GetInvalidFormat() *InvalidFormat { return b } + +type BaseInvalidFormat interface { + GetInvalidFormat() *InvalidFormat +} + +func init() { + t["BaseInvalidFormat"] = reflect.TypeOf((*InvalidFormat)(nil)).Elem() +} + +func (b *InvalidHostState) GetInvalidHostState() *InvalidHostState { return b } + +type BaseInvalidHostState interface { + GetInvalidHostState() *InvalidHostState +} + +func init() { + t["BaseInvalidHostState"] = reflect.TypeOf((*InvalidHostState)(nil)).Elem() +} + +func (b *InvalidLogin) GetInvalidLogin() *InvalidLogin { return b } + +type BaseInvalidLogin interface { + GetInvalidLogin() *InvalidLogin +} + +func init() { + t["BaseInvalidLogin"] = reflect.TypeOf((*InvalidLogin)(nil)).Elem() +} + +func (b *InvalidPropertyValue) GetInvalidPropertyValue() *InvalidPropertyValue { return b } + +type BaseInvalidPropertyValue interface { + GetInvalidPropertyValue() *InvalidPropertyValue +} + +func init() { + t["BaseInvalidPropertyValue"] = reflect.TypeOf((*InvalidPropertyValue)(nil)).Elem() +} + +func (b *InvalidRequest) GetInvalidRequest() *InvalidRequest { return b } + +type BaseInvalidRequest interface { + GetInvalidRequest() *InvalidRequest +} + +func init() { + t["BaseInvalidRequest"] = reflect.TypeOf((*InvalidRequest)(nil)).Elem() +} + +func (b *InvalidState) GetInvalidState() *InvalidState { return b } + +type BaseInvalidState interface { + GetInvalidState() *InvalidState +} + +func init() { + t["BaseInvalidState"] = reflect.TypeOf((*InvalidState)(nil)).Elem() +} + +func (b *InvalidVmConfig) GetInvalidVmConfig() *InvalidVmConfig { return b } + +type BaseInvalidVmConfig interface { + GetInvalidVmConfig() *InvalidVmConfig +} + +func init() { + t["BaseInvalidVmConfig"] = reflect.TypeOf((*InvalidVmConfig)(nil)).Elem() +} + +func (b *IoFilterInfo) GetIoFilterInfo() *IoFilterInfo { return b } + +type BaseIoFilterInfo interface { + GetIoFilterInfo() *IoFilterInfo +} + +func init() { + t["BaseIoFilterInfo"] = reflect.TypeOf((*IoFilterInfo)(nil)).Elem() +} + +func (b *IpAddress) GetIpAddress() *IpAddress { return b } + +type BaseIpAddress interface { + GetIpAddress() *IpAddress +} + +func init() { + t["BaseIpAddress"] = reflect.TypeOf((*IpAddress)(nil)).Elem() +} + +func (b *IscsiFault) GetIscsiFault() *IscsiFault { return b } + +type BaseIscsiFault interface { + GetIscsiFault() *IscsiFault +} + +func init() { + t["BaseIscsiFault"] = reflect.TypeOf((*IscsiFault)(nil)).Elem() +} + +func (b *LicenseEvent) GetLicenseEvent() *LicenseEvent { return b } + +type BaseLicenseEvent interface { + GetLicenseEvent() *LicenseEvent +} + +func init() { + t["BaseLicenseEvent"] = reflect.TypeOf((*LicenseEvent)(nil)).Elem() +} + +func (b *LicenseSource) GetLicenseSource() *LicenseSource { return b } + +type BaseLicenseSource interface { + GetLicenseSource() *LicenseSource +} + +func init() { + t["BaseLicenseSource"] = reflect.TypeOf((*LicenseSource)(nil)).Elem() +} + +func (b *MacAddress) GetMacAddress() *MacAddress { return b } + +type BaseMacAddress interface { + GetMacAddress() *MacAddress +} + +func init() { + t["BaseMacAddress"] = reflect.TypeOf((*MacAddress)(nil)).Elem() +} + +func (b *MethodFault) GetMethodFault() *MethodFault { return b } + +type BaseMethodFault interface { + GetMethodFault() *MethodFault +} + +func init() { + t["BaseMethodFault"] = reflect.TypeOf((*MethodFault)(nil)).Elem() +} + +func (b *MigrationEvent) GetMigrationEvent() *MigrationEvent { return b } + +type BaseMigrationEvent interface { + GetMigrationEvent() *MigrationEvent +} + +func init() { + t["BaseMigrationEvent"] = reflect.TypeOf((*MigrationEvent)(nil)).Elem() +} + +func (b *MigrationFault) GetMigrationFault() *MigrationFault { return b } + +type BaseMigrationFault interface { + GetMigrationFault() *MigrationFault +} + +func init() { + t["BaseMigrationFault"] = reflect.TypeOf((*MigrationFault)(nil)).Elem() +} + +func (b *MigrationFeatureNotSupported) GetMigrationFeatureNotSupported() *MigrationFeatureNotSupported { + return b +} + +type BaseMigrationFeatureNotSupported interface { + GetMigrationFeatureNotSupported() *MigrationFeatureNotSupported +} + +func init() { + t["BaseMigrationFeatureNotSupported"] = reflect.TypeOf((*MigrationFeatureNotSupported)(nil)).Elem() +} + +func (b *MonthlyTaskScheduler) GetMonthlyTaskScheduler() *MonthlyTaskScheduler { return b } + +type BaseMonthlyTaskScheduler interface { + GetMonthlyTaskScheduler() *MonthlyTaskScheduler +} + +func init() { + t["BaseMonthlyTaskScheduler"] = reflect.TypeOf((*MonthlyTaskScheduler)(nil)).Elem() +} + +func (b *NasConfigFault) GetNasConfigFault() *NasConfigFault { return b } + +type BaseNasConfigFault interface { + GetNasConfigFault() *NasConfigFault +} + +func init() { + t["BaseNasConfigFault"] = reflect.TypeOf((*NasConfigFault)(nil)).Elem() +} + +func (b *NegatableExpression) GetNegatableExpression() *NegatableExpression { return b } + +type BaseNegatableExpression interface { + GetNegatableExpression() *NegatableExpression +} + +func init() { + t["BaseNegatableExpression"] = reflect.TypeOf((*NegatableExpression)(nil)).Elem() +} + +func (b *NetBIOSConfigInfo) GetNetBIOSConfigInfo() *NetBIOSConfigInfo { return b } + +type BaseNetBIOSConfigInfo interface { + GetNetBIOSConfigInfo() *NetBIOSConfigInfo +} + +func init() { + t["BaseNetBIOSConfigInfo"] = reflect.TypeOf((*NetBIOSConfigInfo)(nil)).Elem() +} + +func (b *NetworkSummary) GetNetworkSummary() *NetworkSummary { return b } + +type BaseNetworkSummary interface { + GetNetworkSummary() *NetworkSummary +} + +func init() { + t["BaseNetworkSummary"] = reflect.TypeOf((*NetworkSummary)(nil)).Elem() +} + +func (b *NoCompatibleHost) GetNoCompatibleHost() *NoCompatibleHost { return b } + +type BaseNoCompatibleHost interface { + GetNoCompatibleHost() *NoCompatibleHost +} + +func init() { + t["BaseNoCompatibleHost"] = reflect.TypeOf((*NoCompatibleHost)(nil)).Elem() +} + +func (b *NoPermission) GetNoPermission() *NoPermission { return b } + +type BaseNoPermission interface { + GetNoPermission() *NoPermission +} + +func init() { + t["BaseNoPermission"] = reflect.TypeOf((*NoPermission)(nil)).Elem() +} + +func (b *NotEnoughCpus) GetNotEnoughCpus() *NotEnoughCpus { return b } + +type BaseNotEnoughCpus interface { + GetNotEnoughCpus() *NotEnoughCpus +} + +func init() { + t["BaseNotEnoughCpus"] = reflect.TypeOf((*NotEnoughCpus)(nil)).Elem() +} + +func (b *NotEnoughLicenses) GetNotEnoughLicenses() *NotEnoughLicenses { return b } + +type BaseNotEnoughLicenses interface { + GetNotEnoughLicenses() *NotEnoughLicenses +} + +func init() { + t["BaseNotEnoughLicenses"] = reflect.TypeOf((*NotEnoughLicenses)(nil)).Elem() +} + +func (b *NotSupported) GetNotSupported() *NotSupported { return b } + +type BaseNotSupported interface { + GetNotSupported() *NotSupported +} + +func init() { + t["BaseNotSupported"] = reflect.TypeOf((*NotSupported)(nil)).Elem() +} + +func (b *NotSupportedHost) GetNotSupportedHost() *NotSupportedHost { return b } + +type BaseNotSupportedHost interface { + GetNotSupportedHost() *NotSupportedHost +} + +func init() { + t["BaseNotSupportedHost"] = reflect.TypeOf((*NotSupportedHost)(nil)).Elem() +} + +func (b *NotSupportedHostInCluster) GetNotSupportedHostInCluster() *NotSupportedHostInCluster { + return b +} + +type BaseNotSupportedHostInCluster interface { + GetNotSupportedHostInCluster() *NotSupportedHostInCluster +} + +func init() { + t["BaseNotSupportedHostInCluster"] = reflect.TypeOf((*NotSupportedHostInCluster)(nil)).Elem() +} + +func (b *OptionType) GetOptionType() *OptionType { return b } + +type BaseOptionType interface { + GetOptionType() *OptionType +} + +func init() { + t["BaseOptionType"] = reflect.TypeOf((*OptionType)(nil)).Elem() +} + +func (b *OptionValue) GetOptionValue() *OptionValue { return b } + +type BaseOptionValue interface { + GetOptionValue() *OptionValue +} + +func init() { + t["BaseOptionValue"] = reflect.TypeOf((*OptionValue)(nil)).Elem() +} + +func (b *OvfAttribute) GetOvfAttribute() *OvfAttribute { return b } + +type BaseOvfAttribute interface { + GetOvfAttribute() *OvfAttribute +} + +func init() { + t["BaseOvfAttribute"] = reflect.TypeOf((*OvfAttribute)(nil)).Elem() +} + +func (b *OvfConnectedDevice) GetOvfConnectedDevice() *OvfConnectedDevice { return b } + +type BaseOvfConnectedDevice interface { + GetOvfConnectedDevice() *OvfConnectedDevice +} + +func init() { + t["BaseOvfConnectedDevice"] = reflect.TypeOf((*OvfConnectedDevice)(nil)).Elem() +} + +func (b *OvfConstraint) GetOvfConstraint() *OvfConstraint { return b } + +type BaseOvfConstraint interface { + GetOvfConstraint() *OvfConstraint +} + +func init() { + t["BaseOvfConstraint"] = reflect.TypeOf((*OvfConstraint)(nil)).Elem() +} + +func (b *OvfConsumerCallbackFault) GetOvfConsumerCallbackFault() *OvfConsumerCallbackFault { return b } + +type BaseOvfConsumerCallbackFault interface { + GetOvfConsumerCallbackFault() *OvfConsumerCallbackFault +} + +func init() { + t["BaseOvfConsumerCallbackFault"] = reflect.TypeOf((*OvfConsumerCallbackFault)(nil)).Elem() +} + +func (b *OvfElement) GetOvfElement() *OvfElement { return b } + +type BaseOvfElement interface { + GetOvfElement() *OvfElement +} + +func init() { + t["BaseOvfElement"] = reflect.TypeOf((*OvfElement)(nil)).Elem() +} + +func (b *OvfExport) GetOvfExport() *OvfExport { return b } + +type BaseOvfExport interface { + GetOvfExport() *OvfExport +} + +func init() { + t["BaseOvfExport"] = reflect.TypeOf((*OvfExport)(nil)).Elem() +} + +func (b *OvfFault) GetOvfFault() *OvfFault { return b } + +type BaseOvfFault interface { + GetOvfFault() *OvfFault +} + +func init() { + t["BaseOvfFault"] = reflect.TypeOf((*OvfFault)(nil)).Elem() +} + +func (b *OvfHardwareExport) GetOvfHardwareExport() *OvfHardwareExport { return b } + +type BaseOvfHardwareExport interface { + GetOvfHardwareExport() *OvfHardwareExport +} + +func init() { + t["BaseOvfHardwareExport"] = reflect.TypeOf((*OvfHardwareExport)(nil)).Elem() +} + +func (b *OvfImport) GetOvfImport() *OvfImport { return b } + +type BaseOvfImport interface { + GetOvfImport() *OvfImport +} + +func init() { + t["BaseOvfImport"] = reflect.TypeOf((*OvfImport)(nil)).Elem() +} + +func (b *OvfInvalidPackage) GetOvfInvalidPackage() *OvfInvalidPackage { return b } + +type BaseOvfInvalidPackage interface { + GetOvfInvalidPackage() *OvfInvalidPackage +} + +func init() { + t["BaseOvfInvalidPackage"] = reflect.TypeOf((*OvfInvalidPackage)(nil)).Elem() +} + +func (b *OvfInvalidValue) GetOvfInvalidValue() *OvfInvalidValue { return b } + +type BaseOvfInvalidValue interface { + GetOvfInvalidValue() *OvfInvalidValue +} + +func init() { + t["BaseOvfInvalidValue"] = reflect.TypeOf((*OvfInvalidValue)(nil)).Elem() +} + +func (b *OvfManagerCommonParams) GetOvfManagerCommonParams() *OvfManagerCommonParams { return b } + +type BaseOvfManagerCommonParams interface { + GetOvfManagerCommonParams() *OvfManagerCommonParams +} + +func init() { + t["BaseOvfManagerCommonParams"] = reflect.TypeOf((*OvfManagerCommonParams)(nil)).Elem() +} + +func (b *OvfMissingElement) GetOvfMissingElement() *OvfMissingElement { return b } + +type BaseOvfMissingElement interface { + GetOvfMissingElement() *OvfMissingElement +} + +func init() { + t["BaseOvfMissingElement"] = reflect.TypeOf((*OvfMissingElement)(nil)).Elem() +} + +func (b *OvfProperty) GetOvfProperty() *OvfProperty { return b } + +type BaseOvfProperty interface { + GetOvfProperty() *OvfProperty +} + +func init() { + t["BaseOvfProperty"] = reflect.TypeOf((*OvfProperty)(nil)).Elem() +} + +func (b *OvfSystemFault) GetOvfSystemFault() *OvfSystemFault { return b } + +type BaseOvfSystemFault interface { + GetOvfSystemFault() *OvfSystemFault +} + +func init() { + t["BaseOvfSystemFault"] = reflect.TypeOf((*OvfSystemFault)(nil)).Elem() +} + +func (b *OvfUnsupportedAttribute) GetOvfUnsupportedAttribute() *OvfUnsupportedAttribute { return b } + +type BaseOvfUnsupportedAttribute interface { + GetOvfUnsupportedAttribute() *OvfUnsupportedAttribute +} + +func init() { + t["BaseOvfUnsupportedAttribute"] = reflect.TypeOf((*OvfUnsupportedAttribute)(nil)).Elem() +} + +func (b *OvfUnsupportedElement) GetOvfUnsupportedElement() *OvfUnsupportedElement { return b } + +type BaseOvfUnsupportedElement interface { + GetOvfUnsupportedElement() *OvfUnsupportedElement +} + +func init() { + t["BaseOvfUnsupportedElement"] = reflect.TypeOf((*OvfUnsupportedElement)(nil)).Elem() +} + +func (b *OvfUnsupportedPackage) GetOvfUnsupportedPackage() *OvfUnsupportedPackage { return b } + +type BaseOvfUnsupportedPackage interface { + GetOvfUnsupportedPackage() *OvfUnsupportedPackage +} + +func init() { + t["BaseOvfUnsupportedPackage"] = reflect.TypeOf((*OvfUnsupportedPackage)(nil)).Elem() +} + +func (b *PatchMetadataInvalid) GetPatchMetadataInvalid() *PatchMetadataInvalid { return b } + +type BasePatchMetadataInvalid interface { + GetPatchMetadataInvalid() *PatchMetadataInvalid +} + +func init() { + t["BasePatchMetadataInvalid"] = reflect.TypeOf((*PatchMetadataInvalid)(nil)).Elem() +} + +func (b *PatchNotApplicable) GetPatchNotApplicable() *PatchNotApplicable { return b } + +type BasePatchNotApplicable interface { + GetPatchNotApplicable() *PatchNotApplicable +} + +func init() { + t["BasePatchNotApplicable"] = reflect.TypeOf((*PatchNotApplicable)(nil)).Elem() +} + +func (b *PerfEntityMetricBase) GetPerfEntityMetricBase() *PerfEntityMetricBase { return b } + +type BasePerfEntityMetricBase interface { + GetPerfEntityMetricBase() *PerfEntityMetricBase +} + +func init() { + t["BasePerfEntityMetricBase"] = reflect.TypeOf((*PerfEntityMetricBase)(nil)).Elem() +} + +func (b *PerfMetricSeries) GetPerfMetricSeries() *PerfMetricSeries { return b } + +type BasePerfMetricSeries interface { + GetPerfMetricSeries() *PerfMetricSeries +} + +func init() { + t["BasePerfMetricSeries"] = reflect.TypeOf((*PerfMetricSeries)(nil)).Elem() +} + +func (b *PermissionEvent) GetPermissionEvent() *PermissionEvent { return b } + +type BasePermissionEvent interface { + GetPermissionEvent() *PermissionEvent +} + +func init() { + t["BasePermissionEvent"] = reflect.TypeOf((*PermissionEvent)(nil)).Elem() +} + +func (b *PhysicalNicHint) GetPhysicalNicHint() *PhysicalNicHint { return b } + +type BasePhysicalNicHint interface { + GetPhysicalNicHint() *PhysicalNicHint +} + +func init() { + t["BasePhysicalNicHint"] = reflect.TypeOf((*PhysicalNicHint)(nil)).Elem() +} + +func (b *PlatformConfigFault) GetPlatformConfigFault() *PlatformConfigFault { return b } + +type BasePlatformConfigFault interface { + GetPlatformConfigFault() *PlatformConfigFault +} + +func init() { + t["BasePlatformConfigFault"] = reflect.TypeOf((*PlatformConfigFault)(nil)).Elem() +} + +func (b *PolicyOption) GetPolicyOption() *PolicyOption { return b } + +type BasePolicyOption interface { + GetPolicyOption() *PolicyOption +} + +func init() { + t["BasePolicyOption"] = reflect.TypeOf((*PolicyOption)(nil)).Elem() +} + +func (b *PortGroupProfile) GetPortGroupProfile() *PortGroupProfile { return b } + +type BasePortGroupProfile interface { + GetPortGroupProfile() *PortGroupProfile +} + +func init() { + t["BasePortGroupProfile"] = reflect.TypeOf((*PortGroupProfile)(nil)).Elem() +} + +func (b *ProfileConfigInfo) GetProfileConfigInfo() *ProfileConfigInfo { return b } + +type BaseProfileConfigInfo interface { + GetProfileConfigInfo() *ProfileConfigInfo +} + +func init() { + t["BaseProfileConfigInfo"] = reflect.TypeOf((*ProfileConfigInfo)(nil)).Elem() +} + +func (b *ProfileCreateSpec) GetProfileCreateSpec() *ProfileCreateSpec { return b } + +type BaseProfileCreateSpec interface { + GetProfileCreateSpec() *ProfileCreateSpec +} + +func init() { + t["BaseProfileCreateSpec"] = reflect.TypeOf((*ProfileCreateSpec)(nil)).Elem() +} + +func (b *ProfileEvent) GetProfileEvent() *ProfileEvent { return b } + +type BaseProfileEvent interface { + GetProfileEvent() *ProfileEvent +} + +func init() { + t["BaseProfileEvent"] = reflect.TypeOf((*ProfileEvent)(nil)).Elem() +} + +func (b *ProfileExpression) GetProfileExpression() *ProfileExpression { return b } + +type BaseProfileExpression interface { + GetProfileExpression() *ProfileExpression +} + +func init() { + t["BaseProfileExpression"] = reflect.TypeOf((*ProfileExpression)(nil)).Elem() +} + +func (b *ProfilePolicyOptionMetadata) GetProfilePolicyOptionMetadata() *ProfilePolicyOptionMetadata { + return b +} + +type BaseProfilePolicyOptionMetadata interface { + GetProfilePolicyOptionMetadata() *ProfilePolicyOptionMetadata +} + +func init() { + t["BaseProfilePolicyOptionMetadata"] = reflect.TypeOf((*ProfilePolicyOptionMetadata)(nil)).Elem() +} + +func (b *ProfileSerializedCreateSpec) GetProfileSerializedCreateSpec() *ProfileSerializedCreateSpec { + return b +} + +type BaseProfileSerializedCreateSpec interface { + GetProfileSerializedCreateSpec() *ProfileSerializedCreateSpec +} + +func init() { + t["BaseProfileSerializedCreateSpec"] = reflect.TypeOf((*ProfileSerializedCreateSpec)(nil)).Elem() +} + +func (b *RDMNotSupported) GetRDMNotSupported() *RDMNotSupported { return b } + +type BaseRDMNotSupported interface { + GetRDMNotSupported() *RDMNotSupported +} + +func init() { + t["BaseRDMNotSupported"] = reflect.TypeOf((*RDMNotSupported)(nil)).Elem() +} + +func (b *RecurrentTaskScheduler) GetRecurrentTaskScheduler() *RecurrentTaskScheduler { return b } + +type BaseRecurrentTaskScheduler interface { + GetRecurrentTaskScheduler() *RecurrentTaskScheduler +} + +func init() { + t["BaseRecurrentTaskScheduler"] = reflect.TypeOf((*RecurrentTaskScheduler)(nil)).Elem() +} + +func (b *ReplicationConfigFault) GetReplicationConfigFault() *ReplicationConfigFault { return b } + +type BaseReplicationConfigFault interface { + GetReplicationConfigFault() *ReplicationConfigFault +} + +func init() { + t["BaseReplicationConfigFault"] = reflect.TypeOf((*ReplicationConfigFault)(nil)).Elem() +} + +func (b *ReplicationFault) GetReplicationFault() *ReplicationFault { return b } + +type BaseReplicationFault interface { + GetReplicationFault() *ReplicationFault +} + +func init() { + t["BaseReplicationFault"] = reflect.TypeOf((*ReplicationFault)(nil)).Elem() +} + +func (b *ReplicationVmFault) GetReplicationVmFault() *ReplicationVmFault { return b } + +type BaseReplicationVmFault interface { + GetReplicationVmFault() *ReplicationVmFault +} + +func init() { + t["BaseReplicationVmFault"] = reflect.TypeOf((*ReplicationVmFault)(nil)).Elem() +} + +func (b *ResourceAllocationInfo) GetResourceAllocationInfo() *ResourceAllocationInfo { return b } + +type BaseResourceAllocationInfo interface { + GetResourceAllocationInfo() *ResourceAllocationInfo +} + +func init() { + t["BaseResourceAllocationInfo"] = reflect.TypeOf((*ResourceAllocationInfo)(nil)).Elem() +} + +func (b *ResourceInUse) GetResourceInUse() *ResourceInUse { return b } + +type BaseResourceInUse interface { + GetResourceInUse() *ResourceInUse +} + +func init() { + t["BaseResourceInUse"] = reflect.TypeOf((*ResourceInUse)(nil)).Elem() +} + +func (b *ResourcePoolEvent) GetResourcePoolEvent() *ResourcePoolEvent { return b } + +type BaseResourcePoolEvent interface { + GetResourcePoolEvent() *ResourcePoolEvent +} + +func init() { + t["BaseResourcePoolEvent"] = reflect.TypeOf((*ResourcePoolEvent)(nil)).Elem() +} + +func (b *ResourcePoolSummary) GetResourcePoolSummary() *ResourcePoolSummary { return b } + +type BaseResourcePoolSummary interface { + GetResourcePoolSummary() *ResourcePoolSummary +} + +func init() { + t["BaseResourcePoolSummary"] = reflect.TypeOf((*ResourcePoolSummary)(nil)).Elem() +} + +func (b *RoleEvent) GetRoleEvent() *RoleEvent { return b } + +type BaseRoleEvent interface { + GetRoleEvent() *RoleEvent +} + +func init() { + t["BaseRoleEvent"] = reflect.TypeOf((*RoleEvent)(nil)).Elem() +} + +func (b *RuntimeFault) GetRuntimeFault() *RuntimeFault { return b } + +type BaseRuntimeFault interface { + GetRuntimeFault() *RuntimeFault +} + +func init() { + t["BaseRuntimeFault"] = reflect.TypeOf((*RuntimeFault)(nil)).Elem() +} + +func (b *ScheduledTaskEvent) GetScheduledTaskEvent() *ScheduledTaskEvent { return b } + +type BaseScheduledTaskEvent interface { + GetScheduledTaskEvent() *ScheduledTaskEvent +} + +func init() { + t["BaseScheduledTaskEvent"] = reflect.TypeOf((*ScheduledTaskEvent)(nil)).Elem() +} + +func (b *ScheduledTaskSpec) GetScheduledTaskSpec() *ScheduledTaskSpec { return b } + +type BaseScheduledTaskSpec interface { + GetScheduledTaskSpec() *ScheduledTaskSpec +} + +func init() { + t["BaseScheduledTaskSpec"] = reflect.TypeOf((*ScheduledTaskSpec)(nil)).Elem() +} + +func (b *ScsiLun) GetScsiLun() *ScsiLun { return b } + +type BaseScsiLun interface { + GetScsiLun() *ScsiLun +} + +func init() { + t["BaseScsiLun"] = reflect.TypeOf((*ScsiLun)(nil)).Elem() +} + +func (b *SecurityError) GetSecurityError() *SecurityError { return b } + +type BaseSecurityError interface { + GetSecurityError() *SecurityError +} + +func init() { + t["BaseSecurityError"] = reflect.TypeOf((*SecurityError)(nil)).Elem() +} + +func (b *SelectionSet) GetSelectionSet() *SelectionSet { return b } + +type BaseSelectionSet interface { + GetSelectionSet() *SelectionSet +} + +func init() { + t["BaseSelectionSet"] = reflect.TypeOf((*SelectionSet)(nil)).Elem() +} + +func (b *SelectionSpec) GetSelectionSpec() *SelectionSpec { return b } + +type BaseSelectionSpec interface { + GetSelectionSpec() *SelectionSpec +} + +func init() { + t["BaseSelectionSpec"] = reflect.TypeOf((*SelectionSpec)(nil)).Elem() +} + +func (b *ServiceLocatorCredential) GetServiceLocatorCredential() *ServiceLocatorCredential { return b } + +type BaseServiceLocatorCredential interface { + GetServiceLocatorCredential() *ServiceLocatorCredential +} + +func init() { + t["BaseServiceLocatorCredential"] = reflect.TypeOf((*ServiceLocatorCredential)(nil)).Elem() +} + +func (b *SessionEvent) GetSessionEvent() *SessionEvent { return b } + +type BaseSessionEvent interface { + GetSessionEvent() *SessionEvent +} + +func init() { + t["BaseSessionEvent"] = reflect.TypeOf((*SessionEvent)(nil)).Elem() +} + +func (b *SessionManagerServiceRequestSpec) GetSessionManagerServiceRequestSpec() *SessionManagerServiceRequestSpec { + return b +} + +type BaseSessionManagerServiceRequestSpec interface { + GetSessionManagerServiceRequestSpec() *SessionManagerServiceRequestSpec +} + +func init() { + t["BaseSessionManagerServiceRequestSpec"] = reflect.TypeOf((*SessionManagerServiceRequestSpec)(nil)).Elem() +} + +func (b *SnapshotCopyNotSupported) GetSnapshotCopyNotSupported() *SnapshotCopyNotSupported { return b } + +type BaseSnapshotCopyNotSupported interface { + GetSnapshotCopyNotSupported() *SnapshotCopyNotSupported +} + +func init() { + t["BaseSnapshotCopyNotSupported"] = reflect.TypeOf((*SnapshotCopyNotSupported)(nil)).Elem() +} + +func (b *SnapshotFault) GetSnapshotFault() *SnapshotFault { return b } + +type BaseSnapshotFault interface { + GetSnapshotFault() *SnapshotFault +} + +func init() { + t["BaseSnapshotFault"] = reflect.TypeOf((*SnapshotFault)(nil)).Elem() +} + +func (b *TaskEvent) GetTaskEvent() *TaskEvent { return b } + +type BaseTaskEvent interface { + GetTaskEvent() *TaskEvent +} + +func init() { + t["BaseTaskEvent"] = reflect.TypeOf((*TaskEvent)(nil)).Elem() +} + +func (b *TaskInProgress) GetTaskInProgress() *TaskInProgress { return b } + +type BaseTaskInProgress interface { + GetTaskInProgress() *TaskInProgress +} + +func init() { + t["BaseTaskInProgress"] = reflect.TypeOf((*TaskInProgress)(nil)).Elem() +} + +func (b *TaskReason) GetTaskReason() *TaskReason { return b } + +type BaseTaskReason interface { + GetTaskReason() *TaskReason +} + +func init() { + t["BaseTaskReason"] = reflect.TypeOf((*TaskReason)(nil)).Elem() +} + +func (b *TaskScheduler) GetTaskScheduler() *TaskScheduler { return b } + +type BaseTaskScheduler interface { + GetTaskScheduler() *TaskScheduler +} + +func init() { + t["BaseTaskScheduler"] = reflect.TypeOf((*TaskScheduler)(nil)).Elem() +} + +func (b *TemplateUpgradeEvent) GetTemplateUpgradeEvent() *TemplateUpgradeEvent { return b } + +type BaseTemplateUpgradeEvent interface { + GetTemplateUpgradeEvent() *TemplateUpgradeEvent +} + +func init() { + t["BaseTemplateUpgradeEvent"] = reflect.TypeOf((*TemplateUpgradeEvent)(nil)).Elem() +} + +func (b *Timedout) GetTimedout() *Timedout { return b } + +type BaseTimedout interface { + GetTimedout() *Timedout +} + +func init() { + t["BaseTimedout"] = reflect.TypeOf((*Timedout)(nil)).Elem() +} + +func (b *TypeDescription) GetTypeDescription() *TypeDescription { return b } + +type BaseTypeDescription interface { + GetTypeDescription() *TypeDescription +} + +func init() { + t["BaseTypeDescription"] = reflect.TypeOf((*TypeDescription)(nil)).Elem() +} + +func (b *UnsupportedDatastore) GetUnsupportedDatastore() *UnsupportedDatastore { return b } + +type BaseUnsupportedDatastore interface { + GetUnsupportedDatastore() *UnsupportedDatastore +} + +func init() { + t["BaseUnsupportedDatastore"] = reflect.TypeOf((*UnsupportedDatastore)(nil)).Elem() +} + +func (b *UpgradeEvent) GetUpgradeEvent() *UpgradeEvent { return b } + +type BaseUpgradeEvent interface { + GetUpgradeEvent() *UpgradeEvent +} + +func init() { + t["BaseUpgradeEvent"] = reflect.TypeOf((*UpgradeEvent)(nil)).Elem() +} + +func (b *UserSearchResult) GetUserSearchResult() *UserSearchResult { return b } + +type BaseUserSearchResult interface { + GetUserSearchResult() *UserSearchResult +} + +func init() { + t["BaseUserSearchResult"] = reflect.TypeOf((*UserSearchResult)(nil)).Elem() +} + +func (b *VAppConfigFault) GetVAppConfigFault() *VAppConfigFault { return b } + +type BaseVAppConfigFault interface { + GetVAppConfigFault() *VAppConfigFault +} + +func init() { + t["BaseVAppConfigFault"] = reflect.TypeOf((*VAppConfigFault)(nil)).Elem() +} + +func (b *VAppPropertyFault) GetVAppPropertyFault() *VAppPropertyFault { return b } + +type BaseVAppPropertyFault interface { + GetVAppPropertyFault() *VAppPropertyFault +} + +func init() { + t["BaseVAppPropertyFault"] = reflect.TypeOf((*VAppPropertyFault)(nil)).Elem() +} + +func (b *VMotionInterfaceIssue) GetVMotionInterfaceIssue() *VMotionInterfaceIssue { return b } + +type BaseVMotionInterfaceIssue interface { + GetVMotionInterfaceIssue() *VMotionInterfaceIssue +} + +func init() { + t["BaseVMotionInterfaceIssue"] = reflect.TypeOf((*VMotionInterfaceIssue)(nil)).Elem() +} + +func (b *VMwareDVSHealthCheckConfig) GetVMwareDVSHealthCheckConfig() *VMwareDVSHealthCheckConfig { + return b +} + +type BaseVMwareDVSHealthCheckConfig interface { + GetVMwareDVSHealthCheckConfig() *VMwareDVSHealthCheckConfig +} + +func init() { + t["BaseVMwareDVSHealthCheckConfig"] = reflect.TypeOf((*VMwareDVSHealthCheckConfig)(nil)).Elem() +} + +func (b *VimFault) GetVimFault() *VimFault { return b } + +type BaseVimFault interface { + GetVimFault() *VimFault +} + +func init() { + t["BaseVimFault"] = reflect.TypeOf((*VimFault)(nil)).Elem() +} + +func (b *VirtualController) GetVirtualController() *VirtualController { return b } + +type BaseVirtualController interface { + GetVirtualController() *VirtualController +} + +func init() { + t["BaseVirtualController"] = reflect.TypeOf((*VirtualController)(nil)).Elem() +} + +func (b *VirtualControllerOption) GetVirtualControllerOption() *VirtualControllerOption { return b } + +type BaseVirtualControllerOption interface { + GetVirtualControllerOption() *VirtualControllerOption +} + +func init() { + t["BaseVirtualControllerOption"] = reflect.TypeOf((*VirtualControllerOption)(nil)).Elem() +} + +func (b *VirtualDevice) GetVirtualDevice() *VirtualDevice { return b } + +type BaseVirtualDevice interface { + GetVirtualDevice() *VirtualDevice +} + +func init() { + t["BaseVirtualDevice"] = reflect.TypeOf((*VirtualDevice)(nil)).Elem() +} + +func (b *VirtualDeviceBackingInfo) GetVirtualDeviceBackingInfo() *VirtualDeviceBackingInfo { return b } + +type BaseVirtualDeviceBackingInfo interface { + GetVirtualDeviceBackingInfo() *VirtualDeviceBackingInfo +} + +func init() { + t["BaseVirtualDeviceBackingInfo"] = reflect.TypeOf((*VirtualDeviceBackingInfo)(nil)).Elem() +} + +func (b *VirtualDeviceBackingOption) GetVirtualDeviceBackingOption() *VirtualDeviceBackingOption { + return b +} + +type BaseVirtualDeviceBackingOption interface { + GetVirtualDeviceBackingOption() *VirtualDeviceBackingOption +} + +func init() { + t["BaseVirtualDeviceBackingOption"] = reflect.TypeOf((*VirtualDeviceBackingOption)(nil)).Elem() +} + +func (b *VirtualDeviceBusSlotInfo) GetVirtualDeviceBusSlotInfo() *VirtualDeviceBusSlotInfo { return b } + +type BaseVirtualDeviceBusSlotInfo interface { + GetVirtualDeviceBusSlotInfo() *VirtualDeviceBusSlotInfo +} + +func init() { + t["BaseVirtualDeviceBusSlotInfo"] = reflect.TypeOf((*VirtualDeviceBusSlotInfo)(nil)).Elem() +} + +func (b *VirtualDeviceConfigSpec) GetVirtualDeviceConfigSpec() *VirtualDeviceConfigSpec { return b } + +type BaseVirtualDeviceConfigSpec interface { + GetVirtualDeviceConfigSpec() *VirtualDeviceConfigSpec +} + +func init() { + t["BaseVirtualDeviceConfigSpec"] = reflect.TypeOf((*VirtualDeviceConfigSpec)(nil)).Elem() +} + +func (b *VirtualDeviceDeviceBackingInfo) GetVirtualDeviceDeviceBackingInfo() *VirtualDeviceDeviceBackingInfo { + return b +} + +type BaseVirtualDeviceDeviceBackingInfo interface { + GetVirtualDeviceDeviceBackingInfo() *VirtualDeviceDeviceBackingInfo +} + +func init() { + t["BaseVirtualDeviceDeviceBackingInfo"] = reflect.TypeOf((*VirtualDeviceDeviceBackingInfo)(nil)).Elem() +} + +func (b *VirtualDeviceDeviceBackingOption) GetVirtualDeviceDeviceBackingOption() *VirtualDeviceDeviceBackingOption { + return b +} + +type BaseVirtualDeviceDeviceBackingOption interface { + GetVirtualDeviceDeviceBackingOption() *VirtualDeviceDeviceBackingOption +} + +func init() { + t["BaseVirtualDeviceDeviceBackingOption"] = reflect.TypeOf((*VirtualDeviceDeviceBackingOption)(nil)).Elem() +} + +func (b *VirtualDeviceFileBackingInfo) GetVirtualDeviceFileBackingInfo() *VirtualDeviceFileBackingInfo { + return b +} + +type BaseVirtualDeviceFileBackingInfo interface { + GetVirtualDeviceFileBackingInfo() *VirtualDeviceFileBackingInfo +} + +func init() { + t["BaseVirtualDeviceFileBackingInfo"] = reflect.TypeOf((*VirtualDeviceFileBackingInfo)(nil)).Elem() +} + +func (b *VirtualDeviceFileBackingOption) GetVirtualDeviceFileBackingOption() *VirtualDeviceFileBackingOption { + return b +} + +type BaseVirtualDeviceFileBackingOption interface { + GetVirtualDeviceFileBackingOption() *VirtualDeviceFileBackingOption +} + +func init() { + t["BaseVirtualDeviceFileBackingOption"] = reflect.TypeOf((*VirtualDeviceFileBackingOption)(nil)).Elem() +} + +func (b *VirtualDeviceOption) GetVirtualDeviceOption() *VirtualDeviceOption { return b } + +type BaseVirtualDeviceOption interface { + GetVirtualDeviceOption() *VirtualDeviceOption +} + +func init() { + t["BaseVirtualDeviceOption"] = reflect.TypeOf((*VirtualDeviceOption)(nil)).Elem() +} + +func (b *VirtualDevicePciBusSlotInfo) GetVirtualDevicePciBusSlotInfo() *VirtualDevicePciBusSlotInfo { + return b +} + +type BaseVirtualDevicePciBusSlotInfo interface { + GetVirtualDevicePciBusSlotInfo() *VirtualDevicePciBusSlotInfo +} + +func init() { + t["BaseVirtualDevicePciBusSlotInfo"] = reflect.TypeOf((*VirtualDevicePciBusSlotInfo)(nil)).Elem() +} + +func (b *VirtualDevicePipeBackingInfo) GetVirtualDevicePipeBackingInfo() *VirtualDevicePipeBackingInfo { + return b +} + +type BaseVirtualDevicePipeBackingInfo interface { + GetVirtualDevicePipeBackingInfo() *VirtualDevicePipeBackingInfo +} + +func init() { + t["BaseVirtualDevicePipeBackingInfo"] = reflect.TypeOf((*VirtualDevicePipeBackingInfo)(nil)).Elem() +} + +func (b *VirtualDevicePipeBackingOption) GetVirtualDevicePipeBackingOption() *VirtualDevicePipeBackingOption { + return b +} + +type BaseVirtualDevicePipeBackingOption interface { + GetVirtualDevicePipeBackingOption() *VirtualDevicePipeBackingOption +} + +func init() { + t["BaseVirtualDevicePipeBackingOption"] = reflect.TypeOf((*VirtualDevicePipeBackingOption)(nil)).Elem() +} + +func (b *VirtualDeviceRemoteDeviceBackingInfo) GetVirtualDeviceRemoteDeviceBackingInfo() *VirtualDeviceRemoteDeviceBackingInfo { + return b +} + +type BaseVirtualDeviceRemoteDeviceBackingInfo interface { + GetVirtualDeviceRemoteDeviceBackingInfo() *VirtualDeviceRemoteDeviceBackingInfo +} + +func init() { + t["BaseVirtualDeviceRemoteDeviceBackingInfo"] = reflect.TypeOf((*VirtualDeviceRemoteDeviceBackingInfo)(nil)).Elem() +} + +func (b *VirtualDeviceRemoteDeviceBackingOption) GetVirtualDeviceRemoteDeviceBackingOption() *VirtualDeviceRemoteDeviceBackingOption { + return b +} + +type BaseVirtualDeviceRemoteDeviceBackingOption interface { + GetVirtualDeviceRemoteDeviceBackingOption() *VirtualDeviceRemoteDeviceBackingOption +} + +func init() { + t["BaseVirtualDeviceRemoteDeviceBackingOption"] = reflect.TypeOf((*VirtualDeviceRemoteDeviceBackingOption)(nil)).Elem() +} + +func (b *VirtualDeviceURIBackingInfo) GetVirtualDeviceURIBackingInfo() *VirtualDeviceURIBackingInfo { + return b +} + +type BaseVirtualDeviceURIBackingInfo interface { + GetVirtualDeviceURIBackingInfo() *VirtualDeviceURIBackingInfo +} + +func init() { + t["BaseVirtualDeviceURIBackingInfo"] = reflect.TypeOf((*VirtualDeviceURIBackingInfo)(nil)).Elem() +} + +func (b *VirtualDeviceURIBackingOption) GetVirtualDeviceURIBackingOption() *VirtualDeviceURIBackingOption { + return b +} + +type BaseVirtualDeviceURIBackingOption interface { + GetVirtualDeviceURIBackingOption() *VirtualDeviceURIBackingOption +} + +func init() { + t["BaseVirtualDeviceURIBackingOption"] = reflect.TypeOf((*VirtualDeviceURIBackingOption)(nil)).Elem() +} + +func (b *VirtualDiskRawDiskVer2BackingInfo) GetVirtualDiskRawDiskVer2BackingInfo() *VirtualDiskRawDiskVer2BackingInfo { + return b +} + +type BaseVirtualDiskRawDiskVer2BackingInfo interface { + GetVirtualDiskRawDiskVer2BackingInfo() *VirtualDiskRawDiskVer2BackingInfo +} + +func init() { + t["BaseVirtualDiskRawDiskVer2BackingInfo"] = reflect.TypeOf((*VirtualDiskRawDiskVer2BackingInfo)(nil)).Elem() +} + +func (b *VirtualDiskRawDiskVer2BackingOption) GetVirtualDiskRawDiskVer2BackingOption() *VirtualDiskRawDiskVer2BackingOption { + return b +} + +type BaseVirtualDiskRawDiskVer2BackingOption interface { + GetVirtualDiskRawDiskVer2BackingOption() *VirtualDiskRawDiskVer2BackingOption +} + +func init() { + t["BaseVirtualDiskRawDiskVer2BackingOption"] = reflect.TypeOf((*VirtualDiskRawDiskVer2BackingOption)(nil)).Elem() +} + +func (b *VirtualDiskSpec) GetVirtualDiskSpec() *VirtualDiskSpec { return b } + +type BaseVirtualDiskSpec interface { + GetVirtualDiskSpec() *VirtualDiskSpec +} + +func init() { + t["BaseVirtualDiskSpec"] = reflect.TypeOf((*VirtualDiskSpec)(nil)).Elem() +} + +func (b *VirtualEthernetCard) GetVirtualEthernetCard() *VirtualEthernetCard { return b } + +type BaseVirtualEthernetCard interface { + GetVirtualEthernetCard() *VirtualEthernetCard +} + +func init() { + t["BaseVirtualEthernetCard"] = reflect.TypeOf((*VirtualEthernetCard)(nil)).Elem() +} + +func (b *VirtualEthernetCardOption) GetVirtualEthernetCardOption() *VirtualEthernetCardOption { + return b +} + +type BaseVirtualEthernetCardOption interface { + GetVirtualEthernetCardOption() *VirtualEthernetCardOption +} + +func init() { + t["BaseVirtualEthernetCardOption"] = reflect.TypeOf((*VirtualEthernetCardOption)(nil)).Elem() +} + +func (b *VirtualHardwareCompatibilityIssue) GetVirtualHardwareCompatibilityIssue() *VirtualHardwareCompatibilityIssue { + return b +} + +type BaseVirtualHardwareCompatibilityIssue interface { + GetVirtualHardwareCompatibilityIssue() *VirtualHardwareCompatibilityIssue +} + +func init() { + t["BaseVirtualHardwareCompatibilityIssue"] = reflect.TypeOf((*VirtualHardwareCompatibilityIssue)(nil)).Elem() +} + +func (b *VirtualMachineBootOptionsBootableDevice) GetVirtualMachineBootOptionsBootableDevice() *VirtualMachineBootOptionsBootableDevice { + return b +} + +type BaseVirtualMachineBootOptionsBootableDevice interface { + GetVirtualMachineBootOptionsBootableDevice() *VirtualMachineBootOptionsBootableDevice +} + +func init() { + t["BaseVirtualMachineBootOptionsBootableDevice"] = reflect.TypeOf((*VirtualMachineBootOptionsBootableDevice)(nil)).Elem() +} + +func (b *VirtualMachineDeviceRuntimeInfoDeviceRuntimeState) GetVirtualMachineDeviceRuntimeInfoDeviceRuntimeState() *VirtualMachineDeviceRuntimeInfoDeviceRuntimeState { + return b +} + +type BaseVirtualMachineDeviceRuntimeInfoDeviceRuntimeState interface { + GetVirtualMachineDeviceRuntimeInfoDeviceRuntimeState() *VirtualMachineDeviceRuntimeInfoDeviceRuntimeState +} + +func init() { + t["BaseVirtualMachineDeviceRuntimeInfoDeviceRuntimeState"] = reflect.TypeOf((*VirtualMachineDeviceRuntimeInfoDeviceRuntimeState)(nil)).Elem() +} + +func (b *VirtualMachineDiskDeviceInfo) GetVirtualMachineDiskDeviceInfo() *VirtualMachineDiskDeviceInfo { + return b +} + +type BaseVirtualMachineDiskDeviceInfo interface { + GetVirtualMachineDiskDeviceInfo() *VirtualMachineDiskDeviceInfo +} + +func init() { + t["BaseVirtualMachineDiskDeviceInfo"] = reflect.TypeOf((*VirtualMachineDiskDeviceInfo)(nil)).Elem() +} + +func (b *VirtualMachinePciPassthroughInfo) GetVirtualMachinePciPassthroughInfo() *VirtualMachinePciPassthroughInfo { + return b +} + +type BaseVirtualMachinePciPassthroughInfo interface { + GetVirtualMachinePciPassthroughInfo() *VirtualMachinePciPassthroughInfo +} + +func init() { + t["BaseVirtualMachinePciPassthroughInfo"] = reflect.TypeOf((*VirtualMachinePciPassthroughInfo)(nil)).Elem() +} + +func (b *VirtualMachineProfileSpec) GetVirtualMachineProfileSpec() *VirtualMachineProfileSpec { + return b +} + +type BaseVirtualMachineProfileSpec interface { + GetVirtualMachineProfileSpec() *VirtualMachineProfileSpec +} + +func init() { + t["BaseVirtualMachineProfileSpec"] = reflect.TypeOf((*VirtualMachineProfileSpec)(nil)).Elem() +} + +func (b *VirtualMachineTargetInfo) GetVirtualMachineTargetInfo() *VirtualMachineTargetInfo { return b } + +type BaseVirtualMachineTargetInfo interface { + GetVirtualMachineTargetInfo() *VirtualMachineTargetInfo +} + +func init() { + t["BaseVirtualMachineTargetInfo"] = reflect.TypeOf((*VirtualMachineTargetInfo)(nil)).Elem() +} + +func (b *VirtualPCIPassthroughPluginBackingInfo) GetVirtualPCIPassthroughPluginBackingInfo() *VirtualPCIPassthroughPluginBackingInfo { + return b +} + +type BaseVirtualPCIPassthroughPluginBackingInfo interface { + GetVirtualPCIPassthroughPluginBackingInfo() *VirtualPCIPassthroughPluginBackingInfo +} + +func init() { + t["BaseVirtualPCIPassthroughPluginBackingInfo"] = reflect.TypeOf((*VirtualPCIPassthroughPluginBackingInfo)(nil)).Elem() +} + +func (b *VirtualPCIPassthroughPluginBackingOption) GetVirtualPCIPassthroughPluginBackingOption() *VirtualPCIPassthroughPluginBackingOption { + return b +} + +type BaseVirtualPCIPassthroughPluginBackingOption interface { + GetVirtualPCIPassthroughPluginBackingOption() *VirtualPCIPassthroughPluginBackingOption +} + +func init() { + t["BaseVirtualPCIPassthroughPluginBackingOption"] = reflect.TypeOf((*VirtualPCIPassthroughPluginBackingOption)(nil)).Elem() +} + +func (b *VirtualSATAController) GetVirtualSATAController() *VirtualSATAController { return b } + +type BaseVirtualSATAController interface { + GetVirtualSATAController() *VirtualSATAController +} + +func init() { + t["BaseVirtualSATAController"] = reflect.TypeOf((*VirtualSATAController)(nil)).Elem() +} + +func (b *VirtualSATAControllerOption) GetVirtualSATAControllerOption() *VirtualSATAControllerOption { + return b +} + +type BaseVirtualSATAControllerOption interface { + GetVirtualSATAControllerOption() *VirtualSATAControllerOption +} + +func init() { + t["BaseVirtualSATAControllerOption"] = reflect.TypeOf((*VirtualSATAControllerOption)(nil)).Elem() +} + +func (b *VirtualSCSIController) GetVirtualSCSIController() *VirtualSCSIController { return b } + +type BaseVirtualSCSIController interface { + GetVirtualSCSIController() *VirtualSCSIController +} + +func init() { + t["BaseVirtualSCSIController"] = reflect.TypeOf((*VirtualSCSIController)(nil)).Elem() +} + +func (b *VirtualSCSIControllerOption) GetVirtualSCSIControllerOption() *VirtualSCSIControllerOption { + return b +} + +type BaseVirtualSCSIControllerOption interface { + GetVirtualSCSIControllerOption() *VirtualSCSIControllerOption +} + +func init() { + t["BaseVirtualSCSIControllerOption"] = reflect.TypeOf((*VirtualSCSIControllerOption)(nil)).Elem() +} + +func (b *VirtualSoundCard) GetVirtualSoundCard() *VirtualSoundCard { return b } + +type BaseVirtualSoundCard interface { + GetVirtualSoundCard() *VirtualSoundCard +} + +func init() { + t["BaseVirtualSoundCard"] = reflect.TypeOf((*VirtualSoundCard)(nil)).Elem() +} + +func (b *VirtualSoundCardOption) GetVirtualSoundCardOption() *VirtualSoundCardOption { return b } + +type BaseVirtualSoundCardOption interface { + GetVirtualSoundCardOption() *VirtualSoundCardOption +} + +func init() { + t["BaseVirtualSoundCardOption"] = reflect.TypeOf((*VirtualSoundCardOption)(nil)).Elem() +} + +func (b *VirtualVmxnet) GetVirtualVmxnet() *VirtualVmxnet { return b } + +type BaseVirtualVmxnet interface { + GetVirtualVmxnet() *VirtualVmxnet +} + +func init() { + t["BaseVirtualVmxnet"] = reflect.TypeOf((*VirtualVmxnet)(nil)).Elem() +} + +func (b *VirtualVmxnetOption) GetVirtualVmxnetOption() *VirtualVmxnetOption { return b } + +type BaseVirtualVmxnetOption interface { + GetVirtualVmxnetOption() *VirtualVmxnetOption +} + +func init() { + t["BaseVirtualVmxnetOption"] = reflect.TypeOf((*VirtualVmxnetOption)(nil)).Elem() +} + +func (b *VmCloneEvent) GetVmCloneEvent() *VmCloneEvent { return b } + +type BaseVmCloneEvent interface { + GetVmCloneEvent() *VmCloneEvent +} + +func init() { + t["BaseVmCloneEvent"] = reflect.TypeOf((*VmCloneEvent)(nil)).Elem() +} + +func (b *VmConfigFault) GetVmConfigFault() *VmConfigFault { return b } + +type BaseVmConfigFault interface { + GetVmConfigFault() *VmConfigFault +} + +func init() { + t["BaseVmConfigFault"] = reflect.TypeOf((*VmConfigFault)(nil)).Elem() +} + +func (b *VmConfigFileInfo) GetVmConfigFileInfo() *VmConfigFileInfo { return b } + +type BaseVmConfigFileInfo interface { + GetVmConfigFileInfo() *VmConfigFileInfo +} + +func init() { + t["BaseVmConfigFileInfo"] = reflect.TypeOf((*VmConfigFileInfo)(nil)).Elem() +} + +func (b *VmConfigFileQuery) GetVmConfigFileQuery() *VmConfigFileQuery { return b } + +type BaseVmConfigFileQuery interface { + GetVmConfigFileQuery() *VmConfigFileQuery +} + +func init() { + t["BaseVmConfigFileQuery"] = reflect.TypeOf((*VmConfigFileQuery)(nil)).Elem() +} + +func (b *VmConfigInfo) GetVmConfigInfo() *VmConfigInfo { return b } + +type BaseVmConfigInfo interface { + GetVmConfigInfo() *VmConfigInfo +} + +func init() { + t["BaseVmConfigInfo"] = reflect.TypeOf((*VmConfigInfo)(nil)).Elem() +} + +func (b *VmConfigSpec) GetVmConfigSpec() *VmConfigSpec { return b } + +type BaseVmConfigSpec interface { + GetVmConfigSpec() *VmConfigSpec +} + +func init() { + t["BaseVmConfigSpec"] = reflect.TypeOf((*VmConfigSpec)(nil)).Elem() +} + +func (b *VmDasBeingResetEvent) GetVmDasBeingResetEvent() *VmDasBeingResetEvent { return b } + +type BaseVmDasBeingResetEvent interface { + GetVmDasBeingResetEvent() *VmDasBeingResetEvent +} + +func init() { + t["BaseVmDasBeingResetEvent"] = reflect.TypeOf((*VmDasBeingResetEvent)(nil)).Elem() +} + +func (b *VmEvent) GetVmEvent() *VmEvent { return b } + +type BaseVmEvent interface { + GetVmEvent() *VmEvent +} + +func init() { + t["BaseVmEvent"] = reflect.TypeOf((*VmEvent)(nil)).Elem() +} + +func (b *VmFaultToleranceIssue) GetVmFaultToleranceIssue() *VmFaultToleranceIssue { return b } + +type BaseVmFaultToleranceIssue interface { + GetVmFaultToleranceIssue() *VmFaultToleranceIssue +} + +func init() { + t["BaseVmFaultToleranceIssue"] = reflect.TypeOf((*VmFaultToleranceIssue)(nil)).Elem() +} + +func (b *VmMigratedEvent) GetVmMigratedEvent() *VmMigratedEvent { return b } + +type BaseVmMigratedEvent interface { + GetVmMigratedEvent() *VmMigratedEvent +} + +func init() { + t["BaseVmMigratedEvent"] = reflect.TypeOf((*VmMigratedEvent)(nil)).Elem() +} + +func (b *VmPoweredOffEvent) GetVmPoweredOffEvent() *VmPoweredOffEvent { return b } + +type BaseVmPoweredOffEvent interface { + GetVmPoweredOffEvent() *VmPoweredOffEvent +} + +func init() { + t["BaseVmPoweredOffEvent"] = reflect.TypeOf((*VmPoweredOffEvent)(nil)).Elem() +} + +func (b *VmPoweredOnEvent) GetVmPoweredOnEvent() *VmPoweredOnEvent { return b } + +type BaseVmPoweredOnEvent interface { + GetVmPoweredOnEvent() *VmPoweredOnEvent +} + +func init() { + t["BaseVmPoweredOnEvent"] = reflect.TypeOf((*VmPoweredOnEvent)(nil)).Elem() +} + +func (b *VmRelocateSpecEvent) GetVmRelocateSpecEvent() *VmRelocateSpecEvent { return b } + +type BaseVmRelocateSpecEvent interface { + GetVmRelocateSpecEvent() *VmRelocateSpecEvent +} + +func init() { + t["BaseVmRelocateSpecEvent"] = reflect.TypeOf((*VmRelocateSpecEvent)(nil)).Elem() +} + +func (b *VmStartingEvent) GetVmStartingEvent() *VmStartingEvent { return b } + +type BaseVmStartingEvent interface { + GetVmStartingEvent() *VmStartingEvent +} + +func init() { + t["BaseVmStartingEvent"] = reflect.TypeOf((*VmStartingEvent)(nil)).Elem() +} + +func (b *VmToolsUpgradeFault) GetVmToolsUpgradeFault() *VmToolsUpgradeFault { return b } + +type BaseVmToolsUpgradeFault interface { + GetVmToolsUpgradeFault() *VmToolsUpgradeFault +} + +func init() { + t["BaseVmToolsUpgradeFault"] = reflect.TypeOf((*VmToolsUpgradeFault)(nil)).Elem() +} + +func (b *VmfsDatastoreBaseOption) GetVmfsDatastoreBaseOption() *VmfsDatastoreBaseOption { return b } + +type BaseVmfsDatastoreBaseOption interface { + GetVmfsDatastoreBaseOption() *VmfsDatastoreBaseOption +} + +func init() { + t["BaseVmfsDatastoreBaseOption"] = reflect.TypeOf((*VmfsDatastoreBaseOption)(nil)).Elem() +} + +func (b *VmfsDatastoreSingleExtentOption) GetVmfsDatastoreSingleExtentOption() *VmfsDatastoreSingleExtentOption { + return b +} + +type BaseVmfsDatastoreSingleExtentOption interface { + GetVmfsDatastoreSingleExtentOption() *VmfsDatastoreSingleExtentOption +} + +func init() { + t["BaseVmfsDatastoreSingleExtentOption"] = reflect.TypeOf((*VmfsDatastoreSingleExtentOption)(nil)).Elem() +} + +func (b *VmfsDatastoreSpec) GetVmfsDatastoreSpec() *VmfsDatastoreSpec { return b } + +type BaseVmfsDatastoreSpec interface { + GetVmfsDatastoreSpec() *VmfsDatastoreSpec +} + +func init() { + t["BaseVmfsDatastoreSpec"] = reflect.TypeOf((*VmfsDatastoreSpec)(nil)).Elem() +} + +func (b *VmfsMountFault) GetVmfsMountFault() *VmfsMountFault { return b } + +type BaseVmfsMountFault interface { + GetVmfsMountFault() *VmfsMountFault +} + +func init() { + t["BaseVmfsMountFault"] = reflect.TypeOf((*VmfsMountFault)(nil)).Elem() +} + +func (b *VmwareDistributedVirtualSwitchVlanSpec) GetVmwareDistributedVirtualSwitchVlanSpec() *VmwareDistributedVirtualSwitchVlanSpec { + return b +} + +type BaseVmwareDistributedVirtualSwitchVlanSpec interface { + GetVmwareDistributedVirtualSwitchVlanSpec() *VmwareDistributedVirtualSwitchVlanSpec +} + +func init() { + t["BaseVmwareDistributedVirtualSwitchVlanSpec"] = reflect.TypeOf((*VmwareDistributedVirtualSwitchVlanSpec)(nil)).Elem() +} + +func (b *VsanDiskFault) GetVsanDiskFault() *VsanDiskFault { return b } + +type BaseVsanDiskFault interface { + GetVsanDiskFault() *VsanDiskFault +} + +func init() { + t["BaseVsanDiskFault"] = reflect.TypeOf((*VsanDiskFault)(nil)).Elem() +} + +func (b *VsanFault) GetVsanFault() *VsanFault { return b } + +type BaseVsanFault interface { + GetVsanFault() *VsanFault +} + +func init() { + t["BaseVsanFault"] = reflect.TypeOf((*VsanFault)(nil)).Elem() +} + +func (b *VsanUpgradeSystemPreflightCheckIssue) GetVsanUpgradeSystemPreflightCheckIssue() *VsanUpgradeSystemPreflightCheckIssue { + return b +} + +type BaseVsanUpgradeSystemPreflightCheckIssue interface { + GetVsanUpgradeSystemPreflightCheckIssue() *VsanUpgradeSystemPreflightCheckIssue +} + +func init() { + t["BaseVsanUpgradeSystemPreflightCheckIssue"] = reflect.TypeOf((*VsanUpgradeSystemPreflightCheckIssue)(nil)).Elem() +} + +func (b *VsanUpgradeSystemUpgradeHistoryItem) GetVsanUpgradeSystemUpgradeHistoryItem() *VsanUpgradeSystemUpgradeHistoryItem { + return b +} + +type BaseVsanUpgradeSystemUpgradeHistoryItem interface { + GetVsanUpgradeSystemUpgradeHistoryItem() *VsanUpgradeSystemUpgradeHistoryItem +} + +func init() { + t["BaseVsanUpgradeSystemUpgradeHistoryItem"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeHistoryItem)(nil)).Elem() +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/internal.go b/vendor/github.com/vmware/govmomi/vim25/types/internal.go new file mode 100644 index 0000000000..5a9e6c63ee --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/internal.go @@ -0,0 +1,262 @@ +/* +Copyright (c) 2014 VMware, 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 types + +import "reflect" + +type DynamicTypeMgrQueryMoInstances struct { + This ManagedObjectReference `xml:"_this"` + FilterSpec BaseDynamicTypeMgrFilterSpec `xml:"filterSpec,omitempty,typeattr"` +} + +type DynamicTypeMgrQueryMoInstancesResponse struct { + Returnval []DynamicTypeMgrMoInstance `xml:"urn:vim25 returnval"` +} + +type DynamicTypeEnumTypeInfo struct { + DynamicData + + Name string `xml:"name"` + WsdlName string `xml:"wsdlName"` + Version string `xml:"version"` + Value []string `xml:"value,omitempty"` + Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"` +} + +func init() { + t["DynamicTypeEnumTypeInfo"] = reflect.TypeOf((*DynamicTypeEnumTypeInfo)(nil)).Elem() +} + +type DynamicTypeMgrAllTypeInfo struct { + DynamicData + + ManagedTypeInfo []DynamicTypeMgrManagedTypeInfo `xml:"managedTypeInfo,omitempty"` + EnumTypeInfo []DynamicTypeEnumTypeInfo `xml:"enumTypeInfo,omitempty"` + DataTypeInfo []DynamicTypeMgrDataTypeInfo `xml:"dataTypeInfo,omitempty"` +} + +func init() { + t["DynamicTypeMgrAllTypeInfo"] = reflect.TypeOf((*DynamicTypeMgrAllTypeInfo)(nil)).Elem() +} + +type DynamicTypeMgrAnnotation struct { + DynamicData + + Name string `xml:"name"` + Parameter []string `xml:"parameter,omitempty"` +} + +func init() { + t["DynamicTypeMgrAnnotation"] = reflect.TypeOf((*DynamicTypeMgrAnnotation)(nil)).Elem() +} + +type DynamicTypeMgrDataTypeInfo struct { + DynamicData + + Name string `xml:"name"` + WsdlName string `xml:"wsdlName"` + Version string `xml:"version"` + Base []string `xml:"base,omitempty"` + Property []DynamicTypeMgrPropertyTypeInfo `xml:"property,omitempty"` + Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"` +} + +func init() { + t["DynamicTypeMgrDataTypeInfo"] = reflect.TypeOf((*DynamicTypeMgrDataTypeInfo)(nil)).Elem() +} + +func (b *DynamicTypeMgrFilterSpec) GetDynamicTypeMgrFilterSpec() *DynamicTypeMgrFilterSpec { return b } + +type BaseDynamicTypeMgrFilterSpec interface { + GetDynamicTypeMgrFilterSpec() *DynamicTypeMgrFilterSpec +} + +type DynamicTypeMgrFilterSpec struct { + DynamicData +} + +func init() { + t["DynamicTypeMgrFilterSpec"] = reflect.TypeOf((*DynamicTypeMgrFilterSpec)(nil)).Elem() +} + +type DynamicTypeMgrManagedTypeInfo struct { + DynamicData + + Name string `xml:"name"` + WsdlName string `xml:"wsdlName"` + Version string `xml:"version"` + Base []string `xml:"base,omitempty"` + Property []DynamicTypeMgrPropertyTypeInfo `xml:"property,omitempty"` + Method []DynamicTypeMgrMethodTypeInfo `xml:"method,omitempty"` + Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"` +} + +func init() { + t["DynamicTypeMgrManagedTypeInfo"] = reflect.TypeOf((*DynamicTypeMgrManagedTypeInfo)(nil)).Elem() +} + +type DynamicTypeMgrMethodTypeInfo struct { + DynamicData + + Name string `xml:"name"` + WsdlName string `xml:"wsdlName"` + Version string `xml:"version"` + ParamTypeInfo []DynamicTypeMgrParamTypeInfo `xml:"paramTypeInfo,omitempty"` + ReturnTypeInfo *DynamicTypeMgrParamTypeInfo `xml:"returnTypeInfo,omitempty"` + Fault []string `xml:"fault,omitempty"` + PrivId string `xml:"privId,omitempty"` + Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"` +} + +func init() { + t["DynamicTypeMgrMethodTypeInfo"] = reflect.TypeOf((*DynamicTypeMgrMethodTypeInfo)(nil)).Elem() +} + +type DynamicTypeMgrMoFilterSpec struct { + DynamicTypeMgrFilterSpec + + Id string `xml:"id,omitempty"` + TypeSubstr string `xml:"typeSubstr,omitempty"` +} + +func init() { + t["DynamicTypeMgrMoFilterSpec"] = reflect.TypeOf((*DynamicTypeMgrMoFilterSpec)(nil)).Elem() +} + +type DynamicTypeMgrMoInstance struct { + DynamicData + + Id string `xml:"id"` + MoType string `xml:"moType"` +} + +func init() { + t["DynamicTypeMgrMoInstance"] = reflect.TypeOf((*DynamicTypeMgrMoInstance)(nil)).Elem() +} + +type DynamicTypeMgrParamTypeInfo struct { + DynamicData + + Name string `xml:"name"` + Version string `xml:"version"` + Type string `xml:"type"` + PrivId string `xml:"privId,omitempty"` + Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"` +} + +func init() { + t["DynamicTypeMgrParamTypeInfo"] = reflect.TypeOf((*DynamicTypeMgrParamTypeInfo)(nil)).Elem() +} + +type DynamicTypeMgrPropertyTypeInfo struct { + DynamicData + + Name string `xml:"name"` + Version string `xml:"version"` + Type string `xml:"type"` + PrivId string `xml:"privId,omitempty"` + MsgIdFormat string `xml:"msgIdFormat,omitempty"` + Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"` +} + +type DynamicTypeMgrQueryTypeInfo struct { + This ManagedObjectReference `xml:"_this"` + FilterSpec BaseDynamicTypeMgrFilterSpec `xml:"filterSpec,omitempty,typeattr"` +} + +type DynamicTypeMgrQueryTypeInfoResponse struct { + Returnval DynamicTypeMgrAllTypeInfo `xml:"urn:vim25 returnval"` +} + +func init() { + t["DynamicTypeMgrPropertyTypeInfo"] = reflect.TypeOf((*DynamicTypeMgrPropertyTypeInfo)(nil)).Elem() +} + +type DynamicTypeMgrTypeFilterSpec struct { + DynamicTypeMgrFilterSpec + + TypeSubstr string `xml:"typeSubstr,omitempty"` +} + +func init() { + t["DynamicTypeMgrTypeFilterSpec"] = reflect.TypeOf((*DynamicTypeMgrTypeFilterSpec)(nil)).Elem() +} + +type ReflectManagedMethodExecuterSoapArgument struct { + DynamicData + + Name string `xml:"name"` + Val string `xml:"val"` +} + +func init() { + t["ReflectManagedMethodExecuterSoapArgument"] = reflect.TypeOf((*ReflectManagedMethodExecuterSoapArgument)(nil)).Elem() +} + +type ReflectManagedMethodExecuterSoapFault struct { + DynamicData + + FaultMsg string `xml:"faultMsg"` + FaultDetail string `xml:"faultDetail,omitempty"` +} + +func init() { + t["ReflectManagedMethodExecuterSoapFault"] = reflect.TypeOf((*ReflectManagedMethodExecuterSoapFault)(nil)).Elem() +} + +type ReflectManagedMethodExecuterSoapResult struct { + DynamicData + + Response string `xml:"response,omitempty"` + Fault *ReflectManagedMethodExecuterSoapFault `xml:"fault,omitempty"` +} + +type RetrieveDynamicTypeManager struct { + This ManagedObjectReference `xml:"_this"` +} + +type RetrieveDynamicTypeManagerResponse struct { + Returnval *InternalDynamicTypeManager `xml:"urn:vim25 returnval"` +} + +type RetrieveManagedMethodExecuter struct { + This ManagedObjectReference `xml:"_this"` +} + +type RetrieveManagedMethodExecuterResponse struct { + Returnval *ReflectManagedMethodExecuter `xml:"urn:vim25 returnval"` +} + +type InternalDynamicTypeManager struct { + ManagedObjectReference +} + +type ReflectManagedMethodExecuter struct { + ManagedObjectReference +} + +type ExecuteSoap struct { + This ManagedObjectReference `xml:"_this"` + Moid string `xml:"moid"` + Version string `xml:"version"` + Method string `xml:"method"` + Argument []ReflectManagedMethodExecuterSoapArgument `xml:"argument,omitempty"` +} + +type ExecuteSoapResponse struct { + Returnval *ReflectManagedMethodExecuterSoapResult `xml:"urn:vim25 returnval"` +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/registry.go b/vendor/github.com/vmware/govmomi/vim25/types/registry.go new file mode 100644 index 0000000000..8f238088db --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/registry.go @@ -0,0 +1,30 @@ +/* +Copyright (c) 2014 VMware, 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 types + +import "reflect" + +var t = map[string]reflect.Type{} + +type Func func(string) (reflect.Type, bool) + +func TypeFunc() Func { + return func(name string) (reflect.Type, bool) { + typ, ok := t[name] + return typ, ok + } +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/types.go b/vendor/github.com/vmware/govmomi/vim25/types/types.go new file mode 100644 index 0000000000..03b976c2bc --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/types/types.go @@ -0,0 +1,49702 @@ +/* +Copyright (c) 2014-2016 VMware, 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 types + +import ( + "net/url" + "reflect" + "time" +) + +type AbdicateDomOwnership AbdicateDomOwnershipRequestType + +func init() { + t["AbdicateDomOwnership"] = reflect.TypeOf((*AbdicateDomOwnership)(nil)).Elem() +} + +type AbdicateDomOwnershipRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids"` +} + +func init() { + t["AbdicateDomOwnershipRequestType"] = reflect.TypeOf((*AbdicateDomOwnershipRequestType)(nil)).Elem() +} + +type AbdicateDomOwnershipResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type AboutInfo struct { + DynamicData + + Name string `xml:"name"` + FullName string `xml:"fullName"` + Vendor string `xml:"vendor"` + Version string `xml:"version"` + Build string `xml:"build"` + LocaleVersion string `xml:"localeVersion,omitempty"` + LocaleBuild string `xml:"localeBuild,omitempty"` + OsType string `xml:"osType"` + ProductLineId string `xml:"productLineId"` + ApiType string `xml:"apiType"` + ApiVersion string `xml:"apiVersion"` + InstanceUuid string `xml:"instanceUuid,omitempty"` + LicenseProductName string `xml:"licenseProductName,omitempty"` + LicenseProductVersion string `xml:"licenseProductVersion,omitempty"` +} + +func init() { + t["AboutInfo"] = reflect.TypeOf((*AboutInfo)(nil)).Elem() +} + +type AccountCreatedEvent struct { + HostEvent + + Spec BaseHostAccountSpec `xml:"spec,typeattr"` + Group bool `xml:"group"` +} + +func init() { + t["AccountCreatedEvent"] = reflect.TypeOf((*AccountCreatedEvent)(nil)).Elem() +} + +type AccountRemovedEvent struct { + HostEvent + + Account string `xml:"account"` + Group bool `xml:"group"` +} + +func init() { + t["AccountRemovedEvent"] = reflect.TypeOf((*AccountRemovedEvent)(nil)).Elem() +} + +type AccountUpdatedEvent struct { + HostEvent + + Spec BaseHostAccountSpec `xml:"spec,typeattr"` + Group bool `xml:"group"` +} + +func init() { + t["AccountUpdatedEvent"] = reflect.TypeOf((*AccountUpdatedEvent)(nil)).Elem() +} + +type AcknowledgeAlarm AcknowledgeAlarmRequestType + +func init() { + t["AcknowledgeAlarm"] = reflect.TypeOf((*AcknowledgeAlarm)(nil)).Elem() +} + +type AcknowledgeAlarmRequestType struct { + This ManagedObjectReference `xml:"_this"` + Alarm ManagedObjectReference `xml:"alarm"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["AcknowledgeAlarmRequestType"] = reflect.TypeOf((*AcknowledgeAlarmRequestType)(nil)).Elem() +} + +type AcknowledgeAlarmResponse struct { +} + +type AcquireCimServicesTicket AcquireCimServicesTicketRequestType + +func init() { + t["AcquireCimServicesTicket"] = reflect.TypeOf((*AcquireCimServicesTicket)(nil)).Elem() +} + +type AcquireCimServicesTicketRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["AcquireCimServicesTicketRequestType"] = reflect.TypeOf((*AcquireCimServicesTicketRequestType)(nil)).Elem() +} + +type AcquireCimServicesTicketResponse struct { + Returnval HostServiceTicket `xml:"returnval"` +} + +type AcquireCloneTicket AcquireCloneTicketRequestType + +func init() { + t["AcquireCloneTicket"] = reflect.TypeOf((*AcquireCloneTicket)(nil)).Elem() +} + +type AcquireCloneTicketRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["AcquireCloneTicketRequestType"] = reflect.TypeOf((*AcquireCloneTicketRequestType)(nil)).Elem() +} + +type AcquireCloneTicketResponse struct { + Returnval string `xml:"returnval"` +} + +type AcquireCredentialsInGuest AcquireCredentialsInGuestRequestType + +func init() { + t["AcquireCredentialsInGuest"] = reflect.TypeOf((*AcquireCredentialsInGuest)(nil)).Elem() +} + +type AcquireCredentialsInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + RequestedAuth BaseGuestAuthentication `xml:"requestedAuth,typeattr"` + SessionID int64 `xml:"sessionID,omitempty"` +} + +func init() { + t["AcquireCredentialsInGuestRequestType"] = reflect.TypeOf((*AcquireCredentialsInGuestRequestType)(nil)).Elem() +} + +type AcquireCredentialsInGuestResponse struct { + Returnval BaseGuestAuthentication `xml:"returnval,typeattr"` +} + +type AcquireGenericServiceTicket AcquireGenericServiceTicketRequestType + +func init() { + t["AcquireGenericServiceTicket"] = reflect.TypeOf((*AcquireGenericServiceTicket)(nil)).Elem() +} + +type AcquireGenericServiceTicketRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec BaseSessionManagerServiceRequestSpec `xml:"spec,typeattr"` +} + +func init() { + t["AcquireGenericServiceTicketRequestType"] = reflect.TypeOf((*AcquireGenericServiceTicketRequestType)(nil)).Elem() +} + +type AcquireGenericServiceTicketResponse struct { + Returnval SessionManagerGenericServiceTicket `xml:"returnval"` +} + +type AcquireLocalTicket AcquireLocalTicketRequestType + +func init() { + t["AcquireLocalTicket"] = reflect.TypeOf((*AcquireLocalTicket)(nil)).Elem() +} + +type AcquireLocalTicketRequestType struct { + This ManagedObjectReference `xml:"_this"` + UserName string `xml:"userName"` +} + +func init() { + t["AcquireLocalTicketRequestType"] = reflect.TypeOf((*AcquireLocalTicketRequestType)(nil)).Elem() +} + +type AcquireLocalTicketResponse struct { + Returnval SessionManagerLocalTicket `xml:"returnval"` +} + +type AcquireMksTicket AcquireMksTicketRequestType + +func init() { + t["AcquireMksTicket"] = reflect.TypeOf((*AcquireMksTicket)(nil)).Elem() +} + +type AcquireMksTicketRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["AcquireMksTicketRequestType"] = reflect.TypeOf((*AcquireMksTicketRequestType)(nil)).Elem() +} + +type AcquireMksTicketResponse struct { + Returnval VirtualMachineMksTicket `xml:"returnval"` +} + +type AcquireTicket AcquireTicketRequestType + +func init() { + t["AcquireTicket"] = reflect.TypeOf((*AcquireTicket)(nil)).Elem() +} + +type AcquireTicketRequestType struct { + This ManagedObjectReference `xml:"_this"` + TicketType string `xml:"ticketType"` +} + +func init() { + t["AcquireTicketRequestType"] = reflect.TypeOf((*AcquireTicketRequestType)(nil)).Elem() +} + +type AcquireTicketResponse struct { + Returnval VirtualMachineTicket `xml:"returnval"` +} + +type Action struct { + DynamicData +} + +func init() { + t["Action"] = reflect.TypeOf((*Action)(nil)).Elem() +} + +type ActiveDirectoryFault struct { + VimFault + + ErrorCode int32 `xml:"errorCode,omitempty"` +} + +func init() { + t["ActiveDirectoryFault"] = reflect.TypeOf((*ActiveDirectoryFault)(nil)).Elem() +} + +type ActiveDirectoryFaultFault BaseActiveDirectoryFault + +func init() { + t["ActiveDirectoryFaultFault"] = reflect.TypeOf((*ActiveDirectoryFaultFault)(nil)).Elem() +} + +type ActiveDirectoryProfile struct { + ApplyProfile +} + +func init() { + t["ActiveDirectoryProfile"] = reflect.TypeOf((*ActiveDirectoryProfile)(nil)).Elem() +} + +type ActiveVMsBlockingEVC struct { + EVCConfigFault + + EvcMode string `xml:"evcMode,omitempty"` + Host []ManagedObjectReference `xml:"host,omitempty"` + HostName []string `xml:"hostName,omitempty"` +} + +func init() { + t["ActiveVMsBlockingEVC"] = reflect.TypeOf((*ActiveVMsBlockingEVC)(nil)).Elem() +} + +type ActiveVMsBlockingEVCFault ActiveVMsBlockingEVC + +func init() { + t["ActiveVMsBlockingEVCFault"] = reflect.TypeOf((*ActiveVMsBlockingEVCFault)(nil)).Elem() +} + +type AddAuthorizationRole AddAuthorizationRoleRequestType + +func init() { + t["AddAuthorizationRole"] = reflect.TypeOf((*AddAuthorizationRole)(nil)).Elem() +} + +type AddAuthorizationRoleRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + PrivIds []string `xml:"privIds,omitempty"` +} + +func init() { + t["AddAuthorizationRoleRequestType"] = reflect.TypeOf((*AddAuthorizationRoleRequestType)(nil)).Elem() +} + +type AddAuthorizationRoleResponse struct { + Returnval int32 `xml:"returnval"` +} + +type AddCustomFieldDef AddCustomFieldDefRequestType + +func init() { + t["AddCustomFieldDef"] = reflect.TypeOf((*AddCustomFieldDef)(nil)).Elem() +} + +type AddCustomFieldDefRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + MoType string `xml:"moType,omitempty"` + FieldDefPolicy *PrivilegePolicyDef `xml:"fieldDefPolicy,omitempty"` + FieldPolicy *PrivilegePolicyDef `xml:"fieldPolicy,omitempty"` +} + +func init() { + t["AddCustomFieldDefRequestType"] = reflect.TypeOf((*AddCustomFieldDefRequestType)(nil)).Elem() +} + +type AddCustomFieldDefResponse struct { + Returnval CustomFieldDef `xml:"returnval"` +} + +type AddDVPortgroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec []DVPortgroupConfigSpec `xml:"spec"` +} + +func init() { + t["AddDVPortgroupRequestType"] = reflect.TypeOf((*AddDVPortgroupRequestType)(nil)).Elem() +} + +type AddDVPortgroup_Task AddDVPortgroupRequestType + +func init() { + t["AddDVPortgroup_Task"] = reflect.TypeOf((*AddDVPortgroup_Task)(nil)).Elem() +} + +type AddDVPortgroup_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type AddDisksRequestType struct { + This ManagedObjectReference `xml:"_this"` + Disk []HostScsiDisk `xml:"disk"` +} + +func init() { + t["AddDisksRequestType"] = reflect.TypeOf((*AddDisksRequestType)(nil)).Elem() +} + +type AddDisks_Task AddDisksRequestType + +func init() { + t["AddDisks_Task"] = reflect.TypeOf((*AddDisks_Task)(nil)).Elem() +} + +type AddDisks_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type AddGuestAlias AddGuestAliasRequestType + +func init() { + t["AddGuestAlias"] = reflect.TypeOf((*AddGuestAlias)(nil)).Elem() +} + +type AddGuestAliasRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Username string `xml:"username"` + MapCert bool `xml:"mapCert"` + Base64Cert string `xml:"base64Cert"` + AliasInfo GuestAuthAliasInfo `xml:"aliasInfo"` +} + +func init() { + t["AddGuestAliasRequestType"] = reflect.TypeOf((*AddGuestAliasRequestType)(nil)).Elem() +} + +type AddGuestAliasResponse struct { +} + +type AddHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostConnectSpec `xml:"spec"` + AsConnected bool `xml:"asConnected"` + ResourcePool *ManagedObjectReference `xml:"resourcePool,omitempty"` + License string `xml:"license,omitempty"` +} + +func init() { + t["AddHostRequestType"] = reflect.TypeOf((*AddHostRequestType)(nil)).Elem() +} + +type AddHost_Task AddHostRequestType + +func init() { + t["AddHost_Task"] = reflect.TypeOf((*AddHost_Task)(nil)).Elem() +} + +type AddHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type AddInternetScsiSendTargets AddInternetScsiSendTargetsRequestType + +func init() { + t["AddInternetScsiSendTargets"] = reflect.TypeOf((*AddInternetScsiSendTargets)(nil)).Elem() +} + +type AddInternetScsiSendTargetsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + Targets []HostInternetScsiHbaSendTarget `xml:"targets"` +} + +func init() { + t["AddInternetScsiSendTargetsRequestType"] = reflect.TypeOf((*AddInternetScsiSendTargetsRequestType)(nil)).Elem() +} + +type AddInternetScsiSendTargetsResponse struct { +} + +type AddInternetScsiStaticTargets AddInternetScsiStaticTargetsRequestType + +func init() { + t["AddInternetScsiStaticTargets"] = reflect.TypeOf((*AddInternetScsiStaticTargets)(nil)).Elem() +} + +type AddInternetScsiStaticTargetsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + Targets []HostInternetScsiHbaStaticTarget `xml:"targets"` +} + +func init() { + t["AddInternetScsiStaticTargetsRequestType"] = reflect.TypeOf((*AddInternetScsiStaticTargetsRequestType)(nil)).Elem() +} + +type AddInternetScsiStaticTargetsResponse struct { +} + +type AddLicense AddLicenseRequestType + +func init() { + t["AddLicense"] = reflect.TypeOf((*AddLicense)(nil)).Elem() +} + +type AddLicenseRequestType struct { + This ManagedObjectReference `xml:"_this"` + LicenseKey string `xml:"licenseKey"` + Labels []KeyValue `xml:"labels,omitempty"` +} + +func init() { + t["AddLicenseRequestType"] = reflect.TypeOf((*AddLicenseRequestType)(nil)).Elem() +} + +type AddLicenseResponse struct { + Returnval LicenseManagerLicenseInfo `xml:"returnval"` +} + +type AddNetworkResourcePool AddNetworkResourcePoolRequestType + +func init() { + t["AddNetworkResourcePool"] = reflect.TypeOf((*AddNetworkResourcePool)(nil)).Elem() +} + +type AddNetworkResourcePoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + ConfigSpec []DVSNetworkResourcePoolConfigSpec `xml:"configSpec"` +} + +func init() { + t["AddNetworkResourcePoolRequestType"] = reflect.TypeOf((*AddNetworkResourcePoolRequestType)(nil)).Elem() +} + +type AddNetworkResourcePoolResponse struct { +} + +type AddPortGroup AddPortGroupRequestType + +func init() { + t["AddPortGroup"] = reflect.TypeOf((*AddPortGroup)(nil)).Elem() +} + +type AddPortGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + Portgrp HostPortGroupSpec `xml:"portgrp"` +} + +func init() { + t["AddPortGroupRequestType"] = reflect.TypeOf((*AddPortGroupRequestType)(nil)).Elem() +} + +type AddPortGroupResponse struct { +} + +type AddServiceConsoleVirtualNic AddServiceConsoleVirtualNicRequestType + +func init() { + t["AddServiceConsoleVirtualNic"] = reflect.TypeOf((*AddServiceConsoleVirtualNic)(nil)).Elem() +} + +type AddServiceConsoleVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Portgroup string `xml:"portgroup"` + Nic HostVirtualNicSpec `xml:"nic"` +} + +func init() { + t["AddServiceConsoleVirtualNicRequestType"] = reflect.TypeOf((*AddServiceConsoleVirtualNicRequestType)(nil)).Elem() +} + +type AddServiceConsoleVirtualNicResponse struct { + Returnval string `xml:"returnval"` +} + +type AddStandaloneHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostConnectSpec `xml:"spec"` + CompResSpec BaseComputeResourceConfigSpec `xml:"compResSpec,omitempty,typeattr"` + AddConnected bool `xml:"addConnected"` + License string `xml:"license,omitempty"` +} + +func init() { + t["AddStandaloneHostRequestType"] = reflect.TypeOf((*AddStandaloneHostRequestType)(nil)).Elem() +} + +type AddStandaloneHost_Task AddStandaloneHostRequestType + +func init() { + t["AddStandaloneHost_Task"] = reflect.TypeOf((*AddStandaloneHost_Task)(nil)).Elem() +} + +type AddStandaloneHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type AddVirtualNic AddVirtualNicRequestType + +func init() { + t["AddVirtualNic"] = reflect.TypeOf((*AddVirtualNic)(nil)).Elem() +} + +type AddVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Portgroup string `xml:"portgroup"` + Nic HostVirtualNicSpec `xml:"nic"` +} + +func init() { + t["AddVirtualNicRequestType"] = reflect.TypeOf((*AddVirtualNicRequestType)(nil)).Elem() +} + +type AddVirtualNicResponse struct { + Returnval string `xml:"returnval"` +} + +type AddVirtualSwitch AddVirtualSwitchRequestType + +func init() { + t["AddVirtualSwitch"] = reflect.TypeOf((*AddVirtualSwitch)(nil)).Elem() +} + +type AddVirtualSwitchRequestType struct { + This ManagedObjectReference `xml:"_this"` + VswitchName string `xml:"vswitchName"` + Spec *HostVirtualSwitchSpec `xml:"spec,omitempty"` +} + +func init() { + t["AddVirtualSwitchRequestType"] = reflect.TypeOf((*AddVirtualSwitchRequestType)(nil)).Elem() +} + +type AddVirtualSwitchResponse struct { +} + +type AdminDisabled struct { + HostConfigFault +} + +func init() { + t["AdminDisabled"] = reflect.TypeOf((*AdminDisabled)(nil)).Elem() +} + +type AdminDisabledFault AdminDisabled + +func init() { + t["AdminDisabledFault"] = reflect.TypeOf((*AdminDisabledFault)(nil)).Elem() +} + +type AdminNotDisabled struct { + HostConfigFault +} + +func init() { + t["AdminNotDisabled"] = reflect.TypeOf((*AdminNotDisabled)(nil)).Elem() +} + +type AdminNotDisabledFault AdminNotDisabled + +func init() { + t["AdminNotDisabledFault"] = reflect.TypeOf((*AdminNotDisabledFault)(nil)).Elem() +} + +type AdminPasswordNotChangedEvent struct { + HostEvent +} + +func init() { + t["AdminPasswordNotChangedEvent"] = reflect.TypeOf((*AdminPasswordNotChangedEvent)(nil)).Elem() +} + +type AffinityConfigured struct { + MigrationFault + + ConfiguredAffinity []string `xml:"configuredAffinity"` +} + +func init() { + t["AffinityConfigured"] = reflect.TypeOf((*AffinityConfigured)(nil)).Elem() +} + +type AffinityConfiguredFault AffinityConfigured + +func init() { + t["AffinityConfiguredFault"] = reflect.TypeOf((*AffinityConfiguredFault)(nil)).Elem() +} + +type AfterStartupTaskScheduler struct { + TaskScheduler + + Minute int32 `xml:"minute"` +} + +func init() { + t["AfterStartupTaskScheduler"] = reflect.TypeOf((*AfterStartupTaskScheduler)(nil)).Elem() +} + +type AgentInstallFailed struct { + HostConnectFault + + Reason string `xml:"reason,omitempty"` + StatusCode int32 `xml:"statusCode,omitempty"` + InstallerOutput string `xml:"installerOutput,omitempty"` +} + +func init() { + t["AgentInstallFailed"] = reflect.TypeOf((*AgentInstallFailed)(nil)).Elem() +} + +type AgentInstallFailedFault AgentInstallFailed + +func init() { + t["AgentInstallFailedFault"] = reflect.TypeOf((*AgentInstallFailedFault)(nil)).Elem() +} + +type AlarmAcknowledgedEvent struct { + AlarmEvent + + Source ManagedEntityEventArgument `xml:"source"` + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["AlarmAcknowledgedEvent"] = reflect.TypeOf((*AlarmAcknowledgedEvent)(nil)).Elem() +} + +type AlarmAction struct { + DynamicData +} + +func init() { + t["AlarmAction"] = reflect.TypeOf((*AlarmAction)(nil)).Elem() +} + +type AlarmActionTriggeredEvent struct { + AlarmEvent + + Source ManagedEntityEventArgument `xml:"source"` + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["AlarmActionTriggeredEvent"] = reflect.TypeOf((*AlarmActionTriggeredEvent)(nil)).Elem() +} + +type AlarmClearedEvent struct { + AlarmEvent + + Source ManagedEntityEventArgument `xml:"source"` + Entity ManagedEntityEventArgument `xml:"entity"` + From string `xml:"from"` +} + +func init() { + t["AlarmClearedEvent"] = reflect.TypeOf((*AlarmClearedEvent)(nil)).Elem() +} + +type AlarmCreatedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["AlarmCreatedEvent"] = reflect.TypeOf((*AlarmCreatedEvent)(nil)).Elem() +} + +type AlarmDescription struct { + DynamicData + + Expr []BaseTypeDescription `xml:"expr,typeattr"` + StateOperator []BaseElementDescription `xml:"stateOperator,typeattr"` + MetricOperator []BaseElementDescription `xml:"metricOperator,typeattr"` + HostSystemConnectionState []BaseElementDescription `xml:"hostSystemConnectionState,typeattr"` + VirtualMachinePowerState []BaseElementDescription `xml:"virtualMachinePowerState,typeattr"` + DatastoreConnectionState []BaseElementDescription `xml:"datastoreConnectionState,omitempty,typeattr"` + HostSystemPowerState []BaseElementDescription `xml:"hostSystemPowerState,omitempty,typeattr"` + VirtualMachineGuestHeartbeatStatus []BaseElementDescription `xml:"virtualMachineGuestHeartbeatStatus,omitempty,typeattr"` + EntityStatus []BaseElementDescription `xml:"entityStatus,typeattr"` + Action []BaseTypeDescription `xml:"action,typeattr"` +} + +func init() { + t["AlarmDescription"] = reflect.TypeOf((*AlarmDescription)(nil)).Elem() +} + +type AlarmEmailCompletedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + To string `xml:"to"` +} + +func init() { + t["AlarmEmailCompletedEvent"] = reflect.TypeOf((*AlarmEmailCompletedEvent)(nil)).Elem() +} + +type AlarmEmailFailedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + To string `xml:"to"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["AlarmEmailFailedEvent"] = reflect.TypeOf((*AlarmEmailFailedEvent)(nil)).Elem() +} + +type AlarmEvent struct { + Event + + Alarm AlarmEventArgument `xml:"alarm"` +} + +func init() { + t["AlarmEvent"] = reflect.TypeOf((*AlarmEvent)(nil)).Elem() +} + +type AlarmEventArgument struct { + EntityEventArgument + + Alarm ManagedObjectReference `xml:"alarm"` +} + +func init() { + t["AlarmEventArgument"] = reflect.TypeOf((*AlarmEventArgument)(nil)).Elem() +} + +type AlarmExpression struct { + DynamicData +} + +func init() { + t["AlarmExpression"] = reflect.TypeOf((*AlarmExpression)(nil)).Elem() +} + +type AlarmInfo struct { + AlarmSpec + + Key string `xml:"key"` + Alarm ManagedObjectReference `xml:"alarm"` + Entity ManagedObjectReference `xml:"entity"` + LastModifiedTime time.Time `xml:"lastModifiedTime"` + LastModifiedUser string `xml:"lastModifiedUser"` + CreationEventId int32 `xml:"creationEventId"` +} + +func init() { + t["AlarmInfo"] = reflect.TypeOf((*AlarmInfo)(nil)).Elem() +} + +type AlarmReconfiguredEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["AlarmReconfiguredEvent"] = reflect.TypeOf((*AlarmReconfiguredEvent)(nil)).Elem() +} + +type AlarmRemovedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["AlarmRemovedEvent"] = reflect.TypeOf((*AlarmRemovedEvent)(nil)).Elem() +} + +type AlarmScriptCompleteEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + Script string `xml:"script"` +} + +func init() { + t["AlarmScriptCompleteEvent"] = reflect.TypeOf((*AlarmScriptCompleteEvent)(nil)).Elem() +} + +type AlarmScriptFailedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + Script string `xml:"script"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["AlarmScriptFailedEvent"] = reflect.TypeOf((*AlarmScriptFailedEvent)(nil)).Elem() +} + +type AlarmSetting struct { + DynamicData + + ToleranceRange int32 `xml:"toleranceRange"` + ReportingFrequency int32 `xml:"reportingFrequency"` +} + +func init() { + t["AlarmSetting"] = reflect.TypeOf((*AlarmSetting)(nil)).Elem() +} + +type AlarmSnmpCompletedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["AlarmSnmpCompletedEvent"] = reflect.TypeOf((*AlarmSnmpCompletedEvent)(nil)).Elem() +} + +type AlarmSnmpFailedEvent struct { + AlarmEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["AlarmSnmpFailedEvent"] = reflect.TypeOf((*AlarmSnmpFailedEvent)(nil)).Elem() +} + +type AlarmSpec struct { + DynamicData + + Name string `xml:"name"` + SystemName string `xml:"systemName,omitempty"` + Description string `xml:"description"` + Enabled bool `xml:"enabled"` + Expression BaseAlarmExpression `xml:"expression,typeattr"` + Action BaseAlarmAction `xml:"action,omitempty,typeattr"` + ActionFrequency int32 `xml:"actionFrequency,omitempty"` + Setting *AlarmSetting `xml:"setting,omitempty"` +} + +func init() { + t["AlarmSpec"] = reflect.TypeOf((*AlarmSpec)(nil)).Elem() +} + +type AlarmState struct { + DynamicData + + Key string `xml:"key"` + Entity ManagedObjectReference `xml:"entity"` + Alarm ManagedObjectReference `xml:"alarm"` + OverallStatus ManagedEntityStatus `xml:"overallStatus"` + Time time.Time `xml:"time"` + Acknowledged *bool `xml:"acknowledged"` + AcknowledgedByUser string `xml:"acknowledgedByUser,omitempty"` + AcknowledgedTime *time.Time `xml:"acknowledgedTime"` + EventKey int32 `xml:"eventKey,omitempty"` +} + +func init() { + t["AlarmState"] = reflect.TypeOf((*AlarmState)(nil)).Elem() +} + +type AlarmStatusChangedEvent struct { + AlarmEvent + + Source ManagedEntityEventArgument `xml:"source"` + Entity ManagedEntityEventArgument `xml:"entity"` + From string `xml:"from"` + To string `xml:"to"` +} + +func init() { + t["AlarmStatusChangedEvent"] = reflect.TypeOf((*AlarmStatusChangedEvent)(nil)).Elem() +} + +type AlarmTriggeringAction struct { + AlarmAction + + Action BaseAction `xml:"action,typeattr"` + TransitionSpecs []AlarmTriggeringActionTransitionSpec `xml:"transitionSpecs,omitempty"` + Green2yellow bool `xml:"green2yellow"` + Yellow2red bool `xml:"yellow2red"` + Red2yellow bool `xml:"red2yellow"` + Yellow2green bool `xml:"yellow2green"` +} + +func init() { + t["AlarmTriggeringAction"] = reflect.TypeOf((*AlarmTriggeringAction)(nil)).Elem() +} + +type AlarmTriggeringActionTransitionSpec struct { + DynamicData + + StartState ManagedEntityStatus `xml:"startState"` + FinalState ManagedEntityStatus `xml:"finalState"` + Repeats bool `xml:"repeats"` +} + +func init() { + t["AlarmTriggeringActionTransitionSpec"] = reflect.TypeOf((*AlarmTriggeringActionTransitionSpec)(nil)).Elem() +} + +type AllVirtualMachinesLicensedEvent struct { + LicenseEvent +} + +func init() { + t["AllVirtualMachinesLicensedEvent"] = reflect.TypeOf((*AllVirtualMachinesLicensedEvent)(nil)).Elem() +} + +type AllocateIpv4Address AllocateIpv4AddressRequestType + +func init() { + t["AllocateIpv4Address"] = reflect.TypeOf((*AllocateIpv4Address)(nil)).Elem() +} + +type AllocateIpv4AddressRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + PoolId int32 `xml:"poolId"` + AllocationId string `xml:"allocationId"` +} + +func init() { + t["AllocateIpv4AddressRequestType"] = reflect.TypeOf((*AllocateIpv4AddressRequestType)(nil)).Elem() +} + +type AllocateIpv4AddressResponse struct { + Returnval string `xml:"returnval"` +} + +type AllocateIpv6Address AllocateIpv6AddressRequestType + +func init() { + t["AllocateIpv6Address"] = reflect.TypeOf((*AllocateIpv6Address)(nil)).Elem() +} + +type AllocateIpv6AddressRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + PoolId int32 `xml:"poolId"` + AllocationId string `xml:"allocationId"` +} + +func init() { + t["AllocateIpv6AddressRequestType"] = reflect.TypeOf((*AllocateIpv6AddressRequestType)(nil)).Elem() +} + +type AllocateIpv6AddressResponse struct { + Returnval string `xml:"returnval"` +} + +type AlreadyAuthenticatedSessionEvent struct { + SessionEvent +} + +func init() { + t["AlreadyAuthenticatedSessionEvent"] = reflect.TypeOf((*AlreadyAuthenticatedSessionEvent)(nil)).Elem() +} + +type AlreadyBeingManaged struct { + HostConnectFault + + IpAddress string `xml:"ipAddress"` +} + +func init() { + t["AlreadyBeingManaged"] = reflect.TypeOf((*AlreadyBeingManaged)(nil)).Elem() +} + +type AlreadyBeingManagedFault AlreadyBeingManaged + +func init() { + t["AlreadyBeingManagedFault"] = reflect.TypeOf((*AlreadyBeingManagedFault)(nil)).Elem() +} + +type AlreadyConnected struct { + HostConnectFault + + Name string `xml:"name"` +} + +func init() { + t["AlreadyConnected"] = reflect.TypeOf((*AlreadyConnected)(nil)).Elem() +} + +type AlreadyConnectedFault AlreadyConnected + +func init() { + t["AlreadyConnectedFault"] = reflect.TypeOf((*AlreadyConnectedFault)(nil)).Elem() +} + +type AlreadyExists struct { + VimFault + + Name string `xml:"name,omitempty"` +} + +func init() { + t["AlreadyExists"] = reflect.TypeOf((*AlreadyExists)(nil)).Elem() +} + +type AlreadyExistsFault AlreadyExists + +func init() { + t["AlreadyExistsFault"] = reflect.TypeOf((*AlreadyExistsFault)(nil)).Elem() +} + +type AlreadyUpgraded struct { + VimFault +} + +func init() { + t["AlreadyUpgraded"] = reflect.TypeOf((*AlreadyUpgraded)(nil)).Elem() +} + +type AlreadyUpgradedFault AlreadyUpgraded + +func init() { + t["AlreadyUpgradedFault"] = reflect.TypeOf((*AlreadyUpgradedFault)(nil)).Elem() +} + +type AndAlarmExpression struct { + AlarmExpression + + Expression []BaseAlarmExpression `xml:"expression,typeattr"` +} + +func init() { + t["AndAlarmExpression"] = reflect.TypeOf((*AndAlarmExpression)(nil)).Elem() +} + +type AnswerFile struct { + DynamicData + + UserInput []ProfileDeferredPolicyOptionParameter `xml:"userInput,omitempty"` + CreatedTime time.Time `xml:"createdTime"` + ModifiedTime time.Time `xml:"modifiedTime"` +} + +func init() { + t["AnswerFile"] = reflect.TypeOf((*AnswerFile)(nil)).Elem() +} + +type AnswerFileCreateSpec struct { + DynamicData + + Validating *bool `xml:"validating"` +} + +func init() { + t["AnswerFileCreateSpec"] = reflect.TypeOf((*AnswerFileCreateSpec)(nil)).Elem() +} + +type AnswerFileOptionsCreateSpec struct { + AnswerFileCreateSpec + + UserInput []ProfileDeferredPolicyOptionParameter `xml:"userInput,omitempty"` +} + +func init() { + t["AnswerFileOptionsCreateSpec"] = reflect.TypeOf((*AnswerFileOptionsCreateSpec)(nil)).Elem() +} + +type AnswerFileSerializedCreateSpec struct { + AnswerFileCreateSpec + + AnswerFileConfigString string `xml:"answerFileConfigString"` +} + +func init() { + t["AnswerFileSerializedCreateSpec"] = reflect.TypeOf((*AnswerFileSerializedCreateSpec)(nil)).Elem() +} + +type AnswerFileStatusError struct { + DynamicData + + UserInputPath ProfilePropertyPath `xml:"userInputPath"` + ErrMsg LocalizableMessage `xml:"errMsg"` +} + +func init() { + t["AnswerFileStatusError"] = reflect.TypeOf((*AnswerFileStatusError)(nil)).Elem() +} + +type AnswerFileStatusResult struct { + DynamicData + + CheckedTime time.Time `xml:"checkedTime"` + Host ManagedObjectReference `xml:"host"` + Status string `xml:"status"` + Error []AnswerFileStatusError `xml:"error,omitempty"` +} + +func init() { + t["AnswerFileStatusResult"] = reflect.TypeOf((*AnswerFileStatusResult)(nil)).Elem() +} + +type AnswerFileUpdateFailed struct { + VimFault + + Failure []AnswerFileUpdateFailure `xml:"failure"` +} + +func init() { + t["AnswerFileUpdateFailed"] = reflect.TypeOf((*AnswerFileUpdateFailed)(nil)).Elem() +} + +type AnswerFileUpdateFailedFault AnswerFileUpdateFailed + +func init() { + t["AnswerFileUpdateFailedFault"] = reflect.TypeOf((*AnswerFileUpdateFailedFault)(nil)).Elem() +} + +type AnswerFileUpdateFailure struct { + DynamicData + + UserInputPath ProfilePropertyPath `xml:"userInputPath"` + ErrMsg LocalizableMessage `xml:"errMsg"` +} + +func init() { + t["AnswerFileUpdateFailure"] = reflect.TypeOf((*AnswerFileUpdateFailure)(nil)).Elem() +} + +type AnswerVM AnswerVMRequestType + +func init() { + t["AnswerVM"] = reflect.TypeOf((*AnswerVM)(nil)).Elem() +} + +type AnswerVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + QuestionId string `xml:"questionId"` + AnswerChoice string `xml:"answerChoice"` +} + +func init() { + t["AnswerVMRequestType"] = reflect.TypeOf((*AnswerVMRequestType)(nil)).Elem() +} + +type AnswerVMResponse struct { +} + +type ApplicationQuiesceFault struct { + SnapshotFault +} + +func init() { + t["ApplicationQuiesceFault"] = reflect.TypeOf((*ApplicationQuiesceFault)(nil)).Elem() +} + +type ApplicationQuiesceFaultFault ApplicationQuiesceFault + +func init() { + t["ApplicationQuiesceFaultFault"] = reflect.TypeOf((*ApplicationQuiesceFaultFault)(nil)).Elem() +} + +type ApplyHostConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` + ConfigSpec HostConfigSpec `xml:"configSpec"` + UserInput []ProfileDeferredPolicyOptionParameter `xml:"userInput,omitempty"` +} + +func init() { + t["ApplyHostConfigRequestType"] = reflect.TypeOf((*ApplyHostConfigRequestType)(nil)).Elem() +} + +type ApplyHostConfig_Task ApplyHostConfigRequestType + +func init() { + t["ApplyHostConfig_Task"] = reflect.TypeOf((*ApplyHostConfig_Task)(nil)).Elem() +} + +type ApplyHostConfig_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ApplyProfile struct { + DynamicData + + Enabled bool `xml:"enabled"` + Policy []ProfilePolicy `xml:"policy,omitempty"` + ProfileTypeName string `xml:"profileTypeName,omitempty"` + ProfileVersion string `xml:"profileVersion,omitempty"` + Property []ProfileApplyProfileProperty `xml:"property,omitempty"` +} + +func init() { + t["ApplyProfile"] = reflect.TypeOf((*ApplyProfile)(nil)).Elem() +} + +type ApplyRecommendation ApplyRecommendationRequestType + +func init() { + t["ApplyRecommendation"] = reflect.TypeOf((*ApplyRecommendation)(nil)).Elem() +} + +type ApplyRecommendationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key string `xml:"key"` +} + +func init() { + t["ApplyRecommendationRequestType"] = reflect.TypeOf((*ApplyRecommendationRequestType)(nil)).Elem() +} + +type ApplyRecommendationResponse struct { +} + +type ApplyStorageDrsRecommendationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key []string `xml:"key"` +} + +func init() { + t["ApplyStorageDrsRecommendationRequestType"] = reflect.TypeOf((*ApplyStorageDrsRecommendationRequestType)(nil)).Elem() +} + +type ApplyStorageDrsRecommendationToPodRequestType struct { + This ManagedObjectReference `xml:"_this"` + Pod ManagedObjectReference `xml:"pod"` + Key string `xml:"key"` +} + +func init() { + t["ApplyStorageDrsRecommendationToPodRequestType"] = reflect.TypeOf((*ApplyStorageDrsRecommendationToPodRequestType)(nil)).Elem() +} + +type ApplyStorageDrsRecommendationToPod_Task ApplyStorageDrsRecommendationToPodRequestType + +func init() { + t["ApplyStorageDrsRecommendationToPod_Task"] = reflect.TypeOf((*ApplyStorageDrsRecommendationToPod_Task)(nil)).Elem() +} + +type ApplyStorageDrsRecommendationToPod_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ApplyStorageDrsRecommendation_Task ApplyStorageDrsRecommendationRequestType + +func init() { + t["ApplyStorageDrsRecommendation_Task"] = reflect.TypeOf((*ApplyStorageDrsRecommendation_Task)(nil)).Elem() +} + +type ApplyStorageDrsRecommendation_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ApplyStorageRecommendationResult struct { + DynamicData + + Vm *ManagedObjectReference `xml:"vm,omitempty"` +} + +func init() { + t["ApplyStorageRecommendationResult"] = reflect.TypeOf((*ApplyStorageRecommendationResult)(nil)).Elem() +} + +type AreAlarmActionsEnabled AreAlarmActionsEnabledRequestType + +func init() { + t["AreAlarmActionsEnabled"] = reflect.TypeOf((*AreAlarmActionsEnabled)(nil)).Elem() +} + +type AreAlarmActionsEnabledRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["AreAlarmActionsEnabledRequestType"] = reflect.TypeOf((*AreAlarmActionsEnabledRequestType)(nil)).Elem() +} + +type AreAlarmActionsEnabledResponse struct { + Returnval bool `xml:"returnval"` +} + +type ArrayOfAlarmAction struct { + AlarmAction []BaseAlarmAction `xml:"AlarmAction,omitempty,typeattr"` +} + +func init() { + t["ArrayOfAlarmAction"] = reflect.TypeOf((*ArrayOfAlarmAction)(nil)).Elem() +} + +type ArrayOfAlarmExpression struct { + AlarmExpression []BaseAlarmExpression `xml:"AlarmExpression,omitempty,typeattr"` +} + +func init() { + t["ArrayOfAlarmExpression"] = reflect.TypeOf((*ArrayOfAlarmExpression)(nil)).Elem() +} + +type ArrayOfAlarmState struct { + AlarmState []AlarmState `xml:"AlarmState,omitempty"` +} + +func init() { + t["ArrayOfAlarmState"] = reflect.TypeOf((*ArrayOfAlarmState)(nil)).Elem() +} + +type ArrayOfAlarmTriggeringActionTransitionSpec struct { + AlarmTriggeringActionTransitionSpec []AlarmTriggeringActionTransitionSpec `xml:"AlarmTriggeringActionTransitionSpec,omitempty"` +} + +func init() { + t["ArrayOfAlarmTriggeringActionTransitionSpec"] = reflect.TypeOf((*ArrayOfAlarmTriggeringActionTransitionSpec)(nil)).Elem() +} + +type ArrayOfAnswerFileStatusError struct { + AnswerFileStatusError []AnswerFileStatusError `xml:"AnswerFileStatusError,omitempty"` +} + +func init() { + t["ArrayOfAnswerFileStatusError"] = reflect.TypeOf((*ArrayOfAnswerFileStatusError)(nil)).Elem() +} + +type ArrayOfAnswerFileStatusResult struct { + AnswerFileStatusResult []AnswerFileStatusResult `xml:"AnswerFileStatusResult,omitempty"` +} + +func init() { + t["ArrayOfAnswerFileStatusResult"] = reflect.TypeOf((*ArrayOfAnswerFileStatusResult)(nil)).Elem() +} + +type ArrayOfAnswerFileUpdateFailure struct { + AnswerFileUpdateFailure []AnswerFileUpdateFailure `xml:"AnswerFileUpdateFailure,omitempty"` +} + +func init() { + t["ArrayOfAnswerFileUpdateFailure"] = reflect.TypeOf((*ArrayOfAnswerFileUpdateFailure)(nil)).Elem() +} + +type ArrayOfAnyType struct { + AnyType []AnyType `xml:"anyType,omitempty,typeattr"` +} + +func init() { + t["ArrayOfAnyType"] = reflect.TypeOf((*ArrayOfAnyType)(nil)).Elem() +} + +type ArrayOfAnyURI struct { + AnyURI []url.URL `xml:"anyURI,omitempty"` +} + +func init() { + t["ArrayOfAnyURI"] = reflect.TypeOf((*ArrayOfAnyURI)(nil)).Elem() +} + +type ArrayOfApplyProfile struct { + ApplyProfile []BaseApplyProfile `xml:"ApplyProfile,omitempty,typeattr"` +} + +func init() { + t["ArrayOfApplyProfile"] = reflect.TypeOf((*ArrayOfApplyProfile)(nil)).Elem() +} + +type ArrayOfAuthorizationPrivilege struct { + AuthorizationPrivilege []AuthorizationPrivilege `xml:"AuthorizationPrivilege,omitempty"` +} + +func init() { + t["ArrayOfAuthorizationPrivilege"] = reflect.TypeOf((*ArrayOfAuthorizationPrivilege)(nil)).Elem() +} + +type ArrayOfAuthorizationRole struct { + AuthorizationRole []AuthorizationRole `xml:"AuthorizationRole,omitempty"` +} + +func init() { + t["ArrayOfAuthorizationRole"] = reflect.TypeOf((*ArrayOfAuthorizationRole)(nil)).Elem() +} + +type ArrayOfAutoStartPowerInfo struct { + AutoStartPowerInfo []AutoStartPowerInfo `xml:"AutoStartPowerInfo,omitempty"` +} + +func init() { + t["ArrayOfAutoStartPowerInfo"] = reflect.TypeOf((*ArrayOfAutoStartPowerInfo)(nil)).Elem() +} + +type ArrayOfBoolean struct { + Boolean []bool `xml:"boolean,omitempty"` +} + +func init() { + t["ArrayOfBoolean"] = reflect.TypeOf((*ArrayOfBoolean)(nil)).Elem() +} + +type ArrayOfByte struct { + Byte []byte `xml:"byte,omitempty"` +} + +func init() { + t["ArrayOfByte"] = reflect.TypeOf((*ArrayOfByte)(nil)).Elem() +} + +type ArrayOfCheckResult struct { + CheckResult []CheckResult `xml:"CheckResult,omitempty"` +} + +func init() { + t["ArrayOfCheckResult"] = reflect.TypeOf((*ArrayOfCheckResult)(nil)).Elem() +} + +type ArrayOfClusterAction struct { + ClusterAction []BaseClusterAction `xml:"ClusterAction,omitempty,typeattr"` +} + +func init() { + t["ArrayOfClusterAction"] = reflect.TypeOf((*ArrayOfClusterAction)(nil)).Elem() +} + +type ArrayOfClusterActionHistory struct { + ClusterActionHistory []ClusterActionHistory `xml:"ClusterActionHistory,omitempty"` +} + +func init() { + t["ArrayOfClusterActionHistory"] = reflect.TypeOf((*ArrayOfClusterActionHistory)(nil)).Elem() +} + +type ArrayOfClusterAttemptedVmInfo struct { + ClusterAttemptedVmInfo []ClusterAttemptedVmInfo `xml:"ClusterAttemptedVmInfo,omitempty"` +} + +func init() { + t["ArrayOfClusterAttemptedVmInfo"] = reflect.TypeOf((*ArrayOfClusterAttemptedVmInfo)(nil)).Elem() +} + +type ArrayOfClusterDasAamNodeState struct { + ClusterDasAamNodeState []ClusterDasAamNodeState `xml:"ClusterDasAamNodeState,omitempty"` +} + +func init() { + t["ArrayOfClusterDasAamNodeState"] = reflect.TypeOf((*ArrayOfClusterDasAamNodeState)(nil)).Elem() +} + +type ArrayOfClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots struct { + ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots []ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots `xml:"ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots,omitempty"` +} + +func init() { + t["ArrayOfClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots"] = reflect.TypeOf((*ArrayOfClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots)(nil)).Elem() +} + +type ArrayOfClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots struct { + ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots []ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots `xml:"ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots,omitempty"` +} + +func init() { + t["ArrayOfClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots"] = reflect.TypeOf((*ArrayOfClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots)(nil)).Elem() +} + +type ArrayOfClusterDasVmConfigInfo struct { + ClusterDasVmConfigInfo []ClusterDasVmConfigInfo `xml:"ClusterDasVmConfigInfo,omitempty"` +} + +func init() { + t["ArrayOfClusterDasVmConfigInfo"] = reflect.TypeOf((*ArrayOfClusterDasVmConfigInfo)(nil)).Elem() +} + +type ArrayOfClusterDasVmConfigSpec struct { + ClusterDasVmConfigSpec []ClusterDasVmConfigSpec `xml:"ClusterDasVmConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfClusterDasVmConfigSpec"] = reflect.TypeOf((*ArrayOfClusterDasVmConfigSpec)(nil)).Elem() +} + +type ArrayOfClusterDpmHostConfigInfo struct { + ClusterDpmHostConfigInfo []ClusterDpmHostConfigInfo `xml:"ClusterDpmHostConfigInfo,omitempty"` +} + +func init() { + t["ArrayOfClusterDpmHostConfigInfo"] = reflect.TypeOf((*ArrayOfClusterDpmHostConfigInfo)(nil)).Elem() +} + +type ArrayOfClusterDpmHostConfigSpec struct { + ClusterDpmHostConfigSpec []ClusterDpmHostConfigSpec `xml:"ClusterDpmHostConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfClusterDpmHostConfigSpec"] = reflect.TypeOf((*ArrayOfClusterDpmHostConfigSpec)(nil)).Elem() +} + +type ArrayOfClusterDrsFaults struct { + ClusterDrsFaults []ClusterDrsFaults `xml:"ClusterDrsFaults,omitempty"` +} + +func init() { + t["ArrayOfClusterDrsFaults"] = reflect.TypeOf((*ArrayOfClusterDrsFaults)(nil)).Elem() +} + +type ArrayOfClusterDrsFaultsFaultsByVm struct { + ClusterDrsFaultsFaultsByVm []BaseClusterDrsFaultsFaultsByVm `xml:"ClusterDrsFaultsFaultsByVm,omitempty,typeattr"` +} + +func init() { + t["ArrayOfClusterDrsFaultsFaultsByVm"] = reflect.TypeOf((*ArrayOfClusterDrsFaultsFaultsByVm)(nil)).Elem() +} + +type ArrayOfClusterDrsMigration struct { + ClusterDrsMigration []ClusterDrsMigration `xml:"ClusterDrsMigration,omitempty"` +} + +func init() { + t["ArrayOfClusterDrsMigration"] = reflect.TypeOf((*ArrayOfClusterDrsMigration)(nil)).Elem() +} + +type ArrayOfClusterDrsRecommendation struct { + ClusterDrsRecommendation []ClusterDrsRecommendation `xml:"ClusterDrsRecommendation,omitempty"` +} + +func init() { + t["ArrayOfClusterDrsRecommendation"] = reflect.TypeOf((*ArrayOfClusterDrsRecommendation)(nil)).Elem() +} + +type ArrayOfClusterDrsVmConfigInfo struct { + ClusterDrsVmConfigInfo []ClusterDrsVmConfigInfo `xml:"ClusterDrsVmConfigInfo,omitempty"` +} + +func init() { + t["ArrayOfClusterDrsVmConfigInfo"] = reflect.TypeOf((*ArrayOfClusterDrsVmConfigInfo)(nil)).Elem() +} + +type ArrayOfClusterDrsVmConfigSpec struct { + ClusterDrsVmConfigSpec []ClusterDrsVmConfigSpec `xml:"ClusterDrsVmConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfClusterDrsVmConfigSpec"] = reflect.TypeOf((*ArrayOfClusterDrsVmConfigSpec)(nil)).Elem() +} + +type ArrayOfClusterEVCManagerCheckResult struct { + ClusterEVCManagerCheckResult []ClusterEVCManagerCheckResult `xml:"ClusterEVCManagerCheckResult,omitempty"` +} + +func init() { + t["ArrayOfClusterEVCManagerCheckResult"] = reflect.TypeOf((*ArrayOfClusterEVCManagerCheckResult)(nil)).Elem() +} + +type ArrayOfClusterFailoverHostAdmissionControlInfoHostStatus struct { + ClusterFailoverHostAdmissionControlInfoHostStatus []ClusterFailoverHostAdmissionControlInfoHostStatus `xml:"ClusterFailoverHostAdmissionControlInfoHostStatus,omitempty"` +} + +func init() { + t["ArrayOfClusterFailoverHostAdmissionControlInfoHostStatus"] = reflect.TypeOf((*ArrayOfClusterFailoverHostAdmissionControlInfoHostStatus)(nil)).Elem() +} + +type ArrayOfClusterGroupInfo struct { + ClusterGroupInfo []BaseClusterGroupInfo `xml:"ClusterGroupInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfClusterGroupInfo"] = reflect.TypeOf((*ArrayOfClusterGroupInfo)(nil)).Elem() +} + +type ArrayOfClusterGroupSpec struct { + ClusterGroupSpec []ClusterGroupSpec `xml:"ClusterGroupSpec,omitempty"` +} + +func init() { + t["ArrayOfClusterGroupSpec"] = reflect.TypeOf((*ArrayOfClusterGroupSpec)(nil)).Elem() +} + +type ArrayOfClusterHostRecommendation struct { + ClusterHostRecommendation []ClusterHostRecommendation `xml:"ClusterHostRecommendation,omitempty"` +} + +func init() { + t["ArrayOfClusterHostRecommendation"] = reflect.TypeOf((*ArrayOfClusterHostRecommendation)(nil)).Elem() +} + +type ArrayOfClusterIoFilterInfo struct { + ClusterIoFilterInfo []ClusterIoFilterInfo `xml:"ClusterIoFilterInfo,omitempty"` +} + +func init() { + t["ArrayOfClusterIoFilterInfo"] = reflect.TypeOf((*ArrayOfClusterIoFilterInfo)(nil)).Elem() +} + +type ArrayOfClusterNotAttemptedVmInfo struct { + ClusterNotAttemptedVmInfo []ClusterNotAttemptedVmInfo `xml:"ClusterNotAttemptedVmInfo,omitempty"` +} + +func init() { + t["ArrayOfClusterNotAttemptedVmInfo"] = reflect.TypeOf((*ArrayOfClusterNotAttemptedVmInfo)(nil)).Elem() +} + +type ArrayOfClusterRecommendation struct { + ClusterRecommendation []ClusterRecommendation `xml:"ClusterRecommendation,omitempty"` +} + +func init() { + t["ArrayOfClusterRecommendation"] = reflect.TypeOf((*ArrayOfClusterRecommendation)(nil)).Elem() +} + +type ArrayOfClusterRuleInfo struct { + ClusterRuleInfo []BaseClusterRuleInfo `xml:"ClusterRuleInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfClusterRuleInfo"] = reflect.TypeOf((*ArrayOfClusterRuleInfo)(nil)).Elem() +} + +type ArrayOfClusterRuleSpec struct { + ClusterRuleSpec []ClusterRuleSpec `xml:"ClusterRuleSpec,omitempty"` +} + +func init() { + t["ArrayOfClusterRuleSpec"] = reflect.TypeOf((*ArrayOfClusterRuleSpec)(nil)).Elem() +} + +type ArrayOfComplianceFailure struct { + ComplianceFailure []ComplianceFailure `xml:"ComplianceFailure,omitempty"` +} + +func init() { + t["ArrayOfComplianceFailure"] = reflect.TypeOf((*ArrayOfComplianceFailure)(nil)).Elem() +} + +type ArrayOfComplianceLocator struct { + ComplianceLocator []ComplianceLocator `xml:"ComplianceLocator,omitempty"` +} + +func init() { + t["ArrayOfComplianceLocator"] = reflect.TypeOf((*ArrayOfComplianceLocator)(nil)).Elem() +} + +type ArrayOfComplianceResult struct { + ComplianceResult []ComplianceResult `xml:"ComplianceResult,omitempty"` +} + +func init() { + t["ArrayOfComplianceResult"] = reflect.TypeOf((*ArrayOfComplianceResult)(nil)).Elem() +} + +type ArrayOfComputeResourceHostSPBMLicenseInfo struct { + ComputeResourceHostSPBMLicenseInfo []ComputeResourceHostSPBMLicenseInfo `xml:"ComputeResourceHostSPBMLicenseInfo,omitempty"` +} + +func init() { + t["ArrayOfComputeResourceHostSPBMLicenseInfo"] = reflect.TypeOf((*ArrayOfComputeResourceHostSPBMLicenseInfo)(nil)).Elem() +} + +type ArrayOfConflictingConfigurationConfig struct { + ConflictingConfigurationConfig []ConflictingConfigurationConfig `xml:"ConflictingConfigurationConfig,omitempty"` +} + +func init() { + t["ArrayOfConflictingConfigurationConfig"] = reflect.TypeOf((*ArrayOfConflictingConfigurationConfig)(nil)).Elem() +} + +type ArrayOfCustomFieldDef struct { + CustomFieldDef []CustomFieldDef `xml:"CustomFieldDef,omitempty"` +} + +func init() { + t["ArrayOfCustomFieldDef"] = reflect.TypeOf((*ArrayOfCustomFieldDef)(nil)).Elem() +} + +type ArrayOfCustomFieldValue struct { + CustomFieldValue []BaseCustomFieldValue `xml:"CustomFieldValue,omitempty,typeattr"` +} + +func init() { + t["ArrayOfCustomFieldValue"] = reflect.TypeOf((*ArrayOfCustomFieldValue)(nil)).Elem() +} + +type ArrayOfCustomizationAdapterMapping struct { + CustomizationAdapterMapping []CustomizationAdapterMapping `xml:"CustomizationAdapterMapping,omitempty"` +} + +func init() { + t["ArrayOfCustomizationAdapterMapping"] = reflect.TypeOf((*ArrayOfCustomizationAdapterMapping)(nil)).Elem() +} + +type ArrayOfCustomizationIpV6Generator struct { + CustomizationIpV6Generator []BaseCustomizationIpV6Generator `xml:"CustomizationIpV6Generator,omitempty,typeattr"` +} + +func init() { + t["ArrayOfCustomizationIpV6Generator"] = reflect.TypeOf((*ArrayOfCustomizationIpV6Generator)(nil)).Elem() +} + +type ArrayOfCustomizationSpecInfo struct { + CustomizationSpecInfo []CustomizationSpecInfo `xml:"CustomizationSpecInfo,omitempty"` +} + +func init() { + t["ArrayOfCustomizationSpecInfo"] = reflect.TypeOf((*ArrayOfCustomizationSpecInfo)(nil)).Elem() +} + +type ArrayOfDVPortConfigSpec struct { + DVPortConfigSpec []DVPortConfigSpec `xml:"DVPortConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfDVPortConfigSpec"] = reflect.TypeOf((*ArrayOfDVPortConfigSpec)(nil)).Elem() +} + +type ArrayOfDVPortgroupConfigSpec struct { + DVPortgroupConfigSpec []DVPortgroupConfigSpec `xml:"DVPortgroupConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfDVPortgroupConfigSpec"] = reflect.TypeOf((*ArrayOfDVPortgroupConfigSpec)(nil)).Elem() +} + +type ArrayOfDVSHealthCheckConfig struct { + DVSHealthCheckConfig []BaseDVSHealthCheckConfig `xml:"DVSHealthCheckConfig,omitempty,typeattr"` +} + +func init() { + t["ArrayOfDVSHealthCheckConfig"] = reflect.TypeOf((*ArrayOfDVSHealthCheckConfig)(nil)).Elem() +} + +type ArrayOfDVSNetworkResourcePool struct { + DVSNetworkResourcePool []DVSNetworkResourcePool `xml:"DVSNetworkResourcePool,omitempty"` +} + +func init() { + t["ArrayOfDVSNetworkResourcePool"] = reflect.TypeOf((*ArrayOfDVSNetworkResourcePool)(nil)).Elem() +} + +type ArrayOfDVSNetworkResourcePoolConfigSpec struct { + DVSNetworkResourcePoolConfigSpec []DVSNetworkResourcePoolConfigSpec `xml:"DVSNetworkResourcePoolConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfDVSNetworkResourcePoolConfigSpec"] = reflect.TypeOf((*ArrayOfDVSNetworkResourcePoolConfigSpec)(nil)).Elem() +} + +type ArrayOfDVSVmVnicNetworkResourcePool struct { + DVSVmVnicNetworkResourcePool []DVSVmVnicNetworkResourcePool `xml:"DVSVmVnicNetworkResourcePool,omitempty"` +} + +func init() { + t["ArrayOfDVSVmVnicNetworkResourcePool"] = reflect.TypeOf((*ArrayOfDVSVmVnicNetworkResourcePool)(nil)).Elem() +} + +type ArrayOfDasHeartbeatDatastoreInfo struct { + DasHeartbeatDatastoreInfo []DasHeartbeatDatastoreInfo `xml:"DasHeartbeatDatastoreInfo,omitempty"` +} + +func init() { + t["ArrayOfDasHeartbeatDatastoreInfo"] = reflect.TypeOf((*ArrayOfDasHeartbeatDatastoreInfo)(nil)).Elem() +} + +type ArrayOfDatacenterMismatchArgument struct { + DatacenterMismatchArgument []DatacenterMismatchArgument `xml:"DatacenterMismatchArgument,omitempty"` +} + +func init() { + t["ArrayOfDatacenterMismatchArgument"] = reflect.TypeOf((*ArrayOfDatacenterMismatchArgument)(nil)).Elem() +} + +type ArrayOfDatastoreHostMount struct { + DatastoreHostMount []DatastoreHostMount `xml:"DatastoreHostMount,omitempty"` +} + +func init() { + t["ArrayOfDatastoreHostMount"] = reflect.TypeOf((*ArrayOfDatastoreHostMount)(nil)).Elem() +} + +type ArrayOfDatastoreMountPathDatastorePair struct { + DatastoreMountPathDatastorePair []DatastoreMountPathDatastorePair `xml:"DatastoreMountPathDatastorePair,omitempty"` +} + +func init() { + t["ArrayOfDatastoreMountPathDatastorePair"] = reflect.TypeOf((*ArrayOfDatastoreMountPathDatastorePair)(nil)).Elem() +} + +type ArrayOfDiagnosticManagerBundleInfo struct { + DiagnosticManagerBundleInfo []DiagnosticManagerBundleInfo `xml:"DiagnosticManagerBundleInfo,omitempty"` +} + +func init() { + t["ArrayOfDiagnosticManagerBundleInfo"] = reflect.TypeOf((*ArrayOfDiagnosticManagerBundleInfo)(nil)).Elem() +} + +type ArrayOfDiagnosticManagerLogDescriptor struct { + DiagnosticManagerLogDescriptor []DiagnosticManagerLogDescriptor `xml:"DiagnosticManagerLogDescriptor,omitempty"` +} + +func init() { + t["ArrayOfDiagnosticManagerLogDescriptor"] = reflect.TypeOf((*ArrayOfDiagnosticManagerLogDescriptor)(nil)).Elem() +} + +type ArrayOfDiskChangeExtent struct { + DiskChangeExtent []DiskChangeExtent `xml:"DiskChangeExtent,omitempty"` +} + +func init() { + t["ArrayOfDiskChangeExtent"] = reflect.TypeOf((*ArrayOfDiskChangeExtent)(nil)).Elem() +} + +type ArrayOfDistributedVirtualPort struct { + DistributedVirtualPort []DistributedVirtualPort `xml:"DistributedVirtualPort,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualPort"] = reflect.TypeOf((*ArrayOfDistributedVirtualPort)(nil)).Elem() +} + +type ArrayOfDistributedVirtualPortgroupInfo struct { + DistributedVirtualPortgroupInfo []DistributedVirtualPortgroupInfo `xml:"DistributedVirtualPortgroupInfo,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualPortgroupInfo"] = reflect.TypeOf((*ArrayOfDistributedVirtualPortgroupInfo)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchHostMember struct { + DistributedVirtualSwitchHostMember []DistributedVirtualSwitchHostMember `xml:"DistributedVirtualSwitchHostMember,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchHostMember"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchHostMember)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchHostMemberConfigSpec struct { + DistributedVirtualSwitchHostMemberConfigSpec []DistributedVirtualSwitchHostMemberConfigSpec `xml:"DistributedVirtualSwitchHostMemberConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchHostMemberConfigSpec"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchHostMemberConfigSpec)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchHostMemberPnicSpec struct { + DistributedVirtualSwitchHostMemberPnicSpec []DistributedVirtualSwitchHostMemberPnicSpec `xml:"DistributedVirtualSwitchHostMemberPnicSpec,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchHostMemberPnicSpec"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchHostMemberPnicSpec)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchHostProductSpec struct { + DistributedVirtualSwitchHostProductSpec []DistributedVirtualSwitchHostProductSpec `xml:"DistributedVirtualSwitchHostProductSpec,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchHostProductSpec"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchHostProductSpec)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchInfo struct { + DistributedVirtualSwitchInfo []DistributedVirtualSwitchInfo `xml:"DistributedVirtualSwitchInfo,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchInfo"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchInfo)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchKeyedOpaqueBlob struct { + DistributedVirtualSwitchKeyedOpaqueBlob []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"DistributedVirtualSwitchKeyedOpaqueBlob,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchKeyedOpaqueBlob"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchKeyedOpaqueBlob)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchManagerCompatibilityResult struct { + DistributedVirtualSwitchManagerCompatibilityResult []DistributedVirtualSwitchManagerCompatibilityResult `xml:"DistributedVirtualSwitchManagerCompatibilityResult,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchManagerCompatibilityResult"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchManagerCompatibilityResult)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchManagerHostDvsFilterSpec struct { + DistributedVirtualSwitchManagerHostDvsFilterSpec []BaseDistributedVirtualSwitchManagerHostDvsFilterSpec `xml:"DistributedVirtualSwitchManagerHostDvsFilterSpec,omitempty,typeattr"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchManagerHostDvsFilterSpec"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchManagerHostDvsFilterSpec)(nil)).Elem() +} + +type ArrayOfDistributedVirtualSwitchProductSpec struct { + DistributedVirtualSwitchProductSpec []DistributedVirtualSwitchProductSpec `xml:"DistributedVirtualSwitchProductSpec,omitempty"` +} + +func init() { + t["ArrayOfDistributedVirtualSwitchProductSpec"] = reflect.TypeOf((*ArrayOfDistributedVirtualSwitchProductSpec)(nil)).Elem() +} + +type ArrayOfDouble struct { + Double []float64 `xml:"double,omitempty"` +} + +func init() { + t["ArrayOfDouble"] = reflect.TypeOf((*ArrayOfDouble)(nil)).Elem() +} + +type ArrayOfDvsApplyOperationFaultFaultOnObject struct { + DvsApplyOperationFaultFaultOnObject []DvsApplyOperationFaultFaultOnObject `xml:"DvsApplyOperationFaultFaultOnObject,omitempty"` +} + +func init() { + t["ArrayOfDvsApplyOperationFaultFaultOnObject"] = reflect.TypeOf((*ArrayOfDvsApplyOperationFaultFaultOnObject)(nil)).Elem() +} + +type ArrayOfDvsFilterConfig struct { + DvsFilterConfig []BaseDvsFilterConfig `xml:"DvsFilterConfig,omitempty,typeattr"` +} + +func init() { + t["ArrayOfDvsFilterConfig"] = reflect.TypeOf((*ArrayOfDvsFilterConfig)(nil)).Elem() +} + +type ArrayOfDvsHostInfrastructureTrafficResource struct { + DvsHostInfrastructureTrafficResource []DvsHostInfrastructureTrafficResource `xml:"DvsHostInfrastructureTrafficResource,omitempty"` +} + +func init() { + t["ArrayOfDvsHostInfrastructureTrafficResource"] = reflect.TypeOf((*ArrayOfDvsHostInfrastructureTrafficResource)(nil)).Elem() +} + +type ArrayOfDvsHostVNicProfile struct { + DvsHostVNicProfile []DvsHostVNicProfile `xml:"DvsHostVNicProfile,omitempty"` +} + +func init() { + t["ArrayOfDvsHostVNicProfile"] = reflect.TypeOf((*ArrayOfDvsHostVNicProfile)(nil)).Elem() +} + +type ArrayOfDvsNetworkRuleQualifier struct { + DvsNetworkRuleQualifier []BaseDvsNetworkRuleQualifier `xml:"DvsNetworkRuleQualifier,omitempty,typeattr"` +} + +func init() { + t["ArrayOfDvsNetworkRuleQualifier"] = reflect.TypeOf((*ArrayOfDvsNetworkRuleQualifier)(nil)).Elem() +} + +type ArrayOfDvsOperationBulkFaultFaultOnHost struct { + DvsOperationBulkFaultFaultOnHost []DvsOperationBulkFaultFaultOnHost `xml:"DvsOperationBulkFaultFaultOnHost,omitempty"` +} + +func init() { + t["ArrayOfDvsOperationBulkFaultFaultOnHost"] = reflect.TypeOf((*ArrayOfDvsOperationBulkFaultFaultOnHost)(nil)).Elem() +} + +type ArrayOfDvsOutOfSyncHostArgument struct { + DvsOutOfSyncHostArgument []DvsOutOfSyncHostArgument `xml:"DvsOutOfSyncHostArgument,omitempty"` +} + +func init() { + t["ArrayOfDvsOutOfSyncHostArgument"] = reflect.TypeOf((*ArrayOfDvsOutOfSyncHostArgument)(nil)).Elem() +} + +type ArrayOfDvsProfile struct { + DvsProfile []DvsProfile `xml:"DvsProfile,omitempty"` +} + +func init() { + t["ArrayOfDvsProfile"] = reflect.TypeOf((*ArrayOfDvsProfile)(nil)).Elem() +} + +type ArrayOfDvsServiceConsoleVNicProfile struct { + DvsServiceConsoleVNicProfile []DvsServiceConsoleVNicProfile `xml:"DvsServiceConsoleVNicProfile,omitempty"` +} + +func init() { + t["ArrayOfDvsServiceConsoleVNicProfile"] = reflect.TypeOf((*ArrayOfDvsServiceConsoleVNicProfile)(nil)).Elem() +} + +type ArrayOfDvsTrafficRule struct { + DvsTrafficRule []DvsTrafficRule `xml:"DvsTrafficRule,omitempty"` +} + +func init() { + t["ArrayOfDvsTrafficRule"] = reflect.TypeOf((*ArrayOfDvsTrafficRule)(nil)).Elem() +} + +type ArrayOfDvsVmVnicNetworkResourcePoolRuntimeInfo struct { + DvsVmVnicNetworkResourcePoolRuntimeInfo []DvsVmVnicNetworkResourcePoolRuntimeInfo `xml:"DvsVmVnicNetworkResourcePoolRuntimeInfo,omitempty"` +} + +func init() { + t["ArrayOfDvsVmVnicNetworkResourcePoolRuntimeInfo"] = reflect.TypeOf((*ArrayOfDvsVmVnicNetworkResourcePoolRuntimeInfo)(nil)).Elem() +} + +type ArrayOfDvsVmVnicResourcePoolConfigSpec struct { + DvsVmVnicResourcePoolConfigSpec []DvsVmVnicResourcePoolConfigSpec `xml:"DvsVmVnicResourcePoolConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfDvsVmVnicResourcePoolConfigSpec"] = reflect.TypeOf((*ArrayOfDvsVmVnicResourcePoolConfigSpec)(nil)).Elem() +} + +type ArrayOfDvsVnicAllocatedResource struct { + DvsVnicAllocatedResource []DvsVnicAllocatedResource `xml:"DvsVnicAllocatedResource,omitempty"` +} + +func init() { + t["ArrayOfDvsVnicAllocatedResource"] = reflect.TypeOf((*ArrayOfDvsVnicAllocatedResource)(nil)).Elem() +} + +type ArrayOfDynamicProperty struct { + DynamicProperty []DynamicProperty `xml:"DynamicProperty,omitempty"` +} + +func init() { + t["ArrayOfDynamicProperty"] = reflect.TypeOf((*ArrayOfDynamicProperty)(nil)).Elem() +} + +type ArrayOfEVCMode struct { + EVCMode []EVCMode `xml:"EVCMode,omitempty"` +} + +func init() { + t["ArrayOfEVCMode"] = reflect.TypeOf((*ArrayOfEVCMode)(nil)).Elem() +} + +type ArrayOfElementDescription struct { + ElementDescription []BaseElementDescription `xml:"ElementDescription,omitempty,typeattr"` +} + +func init() { + t["ArrayOfElementDescription"] = reflect.TypeOf((*ArrayOfElementDescription)(nil)).Elem() +} + +type ArrayOfEntityBackupConfig struct { + EntityBackupConfig []EntityBackupConfig `xml:"EntityBackupConfig,omitempty"` +} + +func init() { + t["ArrayOfEntityBackupConfig"] = reflect.TypeOf((*ArrayOfEntityBackupConfig)(nil)).Elem() +} + +type ArrayOfEntityPrivilege struct { + EntityPrivilege []EntityPrivilege `xml:"EntityPrivilege,omitempty"` +} + +func init() { + t["ArrayOfEntityPrivilege"] = reflect.TypeOf((*ArrayOfEntityPrivilege)(nil)).Elem() +} + +type ArrayOfEnumDescription struct { + EnumDescription []EnumDescription `xml:"EnumDescription,omitempty"` +} + +func init() { + t["ArrayOfEnumDescription"] = reflect.TypeOf((*ArrayOfEnumDescription)(nil)).Elem() +} + +type ArrayOfEvent struct { + Event []BaseEvent `xml:"Event,omitempty,typeattr"` +} + +func init() { + t["ArrayOfEvent"] = reflect.TypeOf((*ArrayOfEvent)(nil)).Elem() +} + +type ArrayOfEventAlarmExpressionComparison struct { + EventAlarmExpressionComparison []EventAlarmExpressionComparison `xml:"EventAlarmExpressionComparison,omitempty"` +} + +func init() { + t["ArrayOfEventAlarmExpressionComparison"] = reflect.TypeOf((*ArrayOfEventAlarmExpressionComparison)(nil)).Elem() +} + +type ArrayOfEventArgDesc struct { + EventArgDesc []EventArgDesc `xml:"EventArgDesc,omitempty"` +} + +func init() { + t["ArrayOfEventArgDesc"] = reflect.TypeOf((*ArrayOfEventArgDesc)(nil)).Elem() +} + +type ArrayOfEventDescriptionEventDetail struct { + EventDescriptionEventDetail []EventDescriptionEventDetail `xml:"EventDescriptionEventDetail,omitempty"` +} + +func init() { + t["ArrayOfEventDescriptionEventDetail"] = reflect.TypeOf((*ArrayOfEventDescriptionEventDetail)(nil)).Elem() +} + +type ArrayOfExtManagedEntityInfo struct { + ExtManagedEntityInfo []ExtManagedEntityInfo `xml:"ExtManagedEntityInfo,omitempty"` +} + +func init() { + t["ArrayOfExtManagedEntityInfo"] = reflect.TypeOf((*ArrayOfExtManagedEntityInfo)(nil)).Elem() +} + +type ArrayOfExtSolutionManagerInfoTabInfo struct { + ExtSolutionManagerInfoTabInfo []ExtSolutionManagerInfoTabInfo `xml:"ExtSolutionManagerInfoTabInfo,omitempty"` +} + +func init() { + t["ArrayOfExtSolutionManagerInfoTabInfo"] = reflect.TypeOf((*ArrayOfExtSolutionManagerInfoTabInfo)(nil)).Elem() +} + +type ArrayOfExtendedEventPair struct { + ExtendedEventPair []ExtendedEventPair `xml:"ExtendedEventPair,omitempty"` +} + +func init() { + t["ArrayOfExtendedEventPair"] = reflect.TypeOf((*ArrayOfExtendedEventPair)(nil)).Elem() +} + +type ArrayOfExtension struct { + Extension []Extension `xml:"Extension,omitempty"` +} + +func init() { + t["ArrayOfExtension"] = reflect.TypeOf((*ArrayOfExtension)(nil)).Elem() +} + +type ArrayOfExtensionClientInfo struct { + ExtensionClientInfo []ExtensionClientInfo `xml:"ExtensionClientInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionClientInfo"] = reflect.TypeOf((*ArrayOfExtensionClientInfo)(nil)).Elem() +} + +type ArrayOfExtensionEventTypeInfo struct { + ExtensionEventTypeInfo []ExtensionEventTypeInfo `xml:"ExtensionEventTypeInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionEventTypeInfo"] = reflect.TypeOf((*ArrayOfExtensionEventTypeInfo)(nil)).Elem() +} + +type ArrayOfExtensionFaultTypeInfo struct { + ExtensionFaultTypeInfo []ExtensionFaultTypeInfo `xml:"ExtensionFaultTypeInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionFaultTypeInfo"] = reflect.TypeOf((*ArrayOfExtensionFaultTypeInfo)(nil)).Elem() +} + +type ArrayOfExtensionManagerIpAllocationUsage struct { + ExtensionManagerIpAllocationUsage []ExtensionManagerIpAllocationUsage `xml:"ExtensionManagerIpAllocationUsage,omitempty"` +} + +func init() { + t["ArrayOfExtensionManagerIpAllocationUsage"] = reflect.TypeOf((*ArrayOfExtensionManagerIpAllocationUsage)(nil)).Elem() +} + +type ArrayOfExtensionPrivilegeInfo struct { + ExtensionPrivilegeInfo []ExtensionPrivilegeInfo `xml:"ExtensionPrivilegeInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionPrivilegeInfo"] = reflect.TypeOf((*ArrayOfExtensionPrivilegeInfo)(nil)).Elem() +} + +type ArrayOfExtensionResourceInfo struct { + ExtensionResourceInfo []ExtensionResourceInfo `xml:"ExtensionResourceInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionResourceInfo"] = reflect.TypeOf((*ArrayOfExtensionResourceInfo)(nil)).Elem() +} + +type ArrayOfExtensionServerInfo struct { + ExtensionServerInfo []ExtensionServerInfo `xml:"ExtensionServerInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionServerInfo"] = reflect.TypeOf((*ArrayOfExtensionServerInfo)(nil)).Elem() +} + +type ArrayOfExtensionTaskTypeInfo struct { + ExtensionTaskTypeInfo []ExtensionTaskTypeInfo `xml:"ExtensionTaskTypeInfo,omitempty"` +} + +func init() { + t["ArrayOfExtensionTaskTypeInfo"] = reflect.TypeOf((*ArrayOfExtensionTaskTypeInfo)(nil)).Elem() +} + +type ArrayOfFaultToleranceDiskSpec struct { + FaultToleranceDiskSpec []FaultToleranceDiskSpec `xml:"FaultToleranceDiskSpec,omitempty"` +} + +func init() { + t["ArrayOfFaultToleranceDiskSpec"] = reflect.TypeOf((*ArrayOfFaultToleranceDiskSpec)(nil)).Elem() +} + +type ArrayOfFcoeConfigVlanRange struct { + FcoeConfigVlanRange []FcoeConfigVlanRange `xml:"FcoeConfigVlanRange,omitempty"` +} + +func init() { + t["ArrayOfFcoeConfigVlanRange"] = reflect.TypeOf((*ArrayOfFcoeConfigVlanRange)(nil)).Elem() +} + +type ArrayOfFileInfo struct { + FileInfo []BaseFileInfo `xml:"FileInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfFileInfo"] = reflect.TypeOf((*ArrayOfFileInfo)(nil)).Elem() +} + +type ArrayOfFileQuery struct { + FileQuery []BaseFileQuery `xml:"FileQuery,omitempty,typeattr"` +} + +func init() { + t["ArrayOfFileQuery"] = reflect.TypeOf((*ArrayOfFileQuery)(nil)).Elem() +} + +type ArrayOfFirewallProfileRulesetProfile struct { + FirewallProfileRulesetProfile []FirewallProfileRulesetProfile `xml:"FirewallProfileRulesetProfile,omitempty"` +} + +func init() { + t["ArrayOfFirewallProfileRulesetProfile"] = reflect.TypeOf((*ArrayOfFirewallProfileRulesetProfile)(nil)).Elem() +} + +type ArrayOfGuestAliases struct { + GuestAliases []GuestAliases `xml:"GuestAliases,omitempty"` +} + +func init() { + t["ArrayOfGuestAliases"] = reflect.TypeOf((*ArrayOfGuestAliases)(nil)).Elem() +} + +type ArrayOfGuestAuthAliasInfo struct { + GuestAuthAliasInfo []GuestAuthAliasInfo `xml:"GuestAuthAliasInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestAuthAliasInfo"] = reflect.TypeOf((*ArrayOfGuestAuthAliasInfo)(nil)).Elem() +} + +type ArrayOfGuestAuthSubject struct { + GuestAuthSubject []BaseGuestAuthSubject `xml:"GuestAuthSubject,omitempty,typeattr"` +} + +func init() { + t["ArrayOfGuestAuthSubject"] = reflect.TypeOf((*ArrayOfGuestAuthSubject)(nil)).Elem() +} + +type ArrayOfGuestDiskInfo struct { + GuestDiskInfo []GuestDiskInfo `xml:"GuestDiskInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestDiskInfo"] = reflect.TypeOf((*ArrayOfGuestDiskInfo)(nil)).Elem() +} + +type ArrayOfGuestFileInfo struct { + GuestFileInfo []GuestFileInfo `xml:"GuestFileInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestFileInfo"] = reflect.TypeOf((*ArrayOfGuestFileInfo)(nil)).Elem() +} + +type ArrayOfGuestInfoNamespaceGenerationInfo struct { + GuestInfoNamespaceGenerationInfo []GuestInfoNamespaceGenerationInfo `xml:"GuestInfoNamespaceGenerationInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestInfoNamespaceGenerationInfo"] = reflect.TypeOf((*ArrayOfGuestInfoNamespaceGenerationInfo)(nil)).Elem() +} + +type ArrayOfGuestMappedAliases struct { + GuestMappedAliases []GuestMappedAliases `xml:"GuestMappedAliases,omitempty"` +} + +func init() { + t["ArrayOfGuestMappedAliases"] = reflect.TypeOf((*ArrayOfGuestMappedAliases)(nil)).Elem() +} + +type ArrayOfGuestNicInfo struct { + GuestNicInfo []GuestNicInfo `xml:"GuestNicInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestNicInfo"] = reflect.TypeOf((*ArrayOfGuestNicInfo)(nil)).Elem() +} + +type ArrayOfGuestOsDescriptor struct { + GuestOsDescriptor []GuestOsDescriptor `xml:"GuestOsDescriptor,omitempty"` +} + +func init() { + t["ArrayOfGuestOsDescriptor"] = reflect.TypeOf((*ArrayOfGuestOsDescriptor)(nil)).Elem() +} + +type ArrayOfGuestProcessInfo struct { + GuestProcessInfo []GuestProcessInfo `xml:"GuestProcessInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestProcessInfo"] = reflect.TypeOf((*ArrayOfGuestProcessInfo)(nil)).Elem() +} + +type ArrayOfGuestRegKeyRecordSpec struct { + GuestRegKeyRecordSpec []GuestRegKeyRecordSpec `xml:"GuestRegKeyRecordSpec,omitempty"` +} + +func init() { + t["ArrayOfGuestRegKeyRecordSpec"] = reflect.TypeOf((*ArrayOfGuestRegKeyRecordSpec)(nil)).Elem() +} + +type ArrayOfGuestRegValueSpec struct { + GuestRegValueSpec []GuestRegValueSpec `xml:"GuestRegValueSpec,omitempty"` +} + +func init() { + t["ArrayOfGuestRegValueSpec"] = reflect.TypeOf((*ArrayOfGuestRegValueSpec)(nil)).Elem() +} + +type ArrayOfGuestStackInfo struct { + GuestStackInfo []GuestStackInfo `xml:"GuestStackInfo,omitempty"` +} + +func init() { + t["ArrayOfGuestStackInfo"] = reflect.TypeOf((*ArrayOfGuestStackInfo)(nil)).Elem() +} + +type ArrayOfHbrManagerVmReplicationCapability struct { + HbrManagerVmReplicationCapability []HbrManagerVmReplicationCapability `xml:"HbrManagerVmReplicationCapability,omitempty"` +} + +func init() { + t["ArrayOfHbrManagerVmReplicationCapability"] = reflect.TypeOf((*ArrayOfHbrManagerVmReplicationCapability)(nil)).Elem() +} + +type ArrayOfHostAccessControlEntry struct { + HostAccessControlEntry []HostAccessControlEntry `xml:"HostAccessControlEntry,omitempty"` +} + +func init() { + t["ArrayOfHostAccessControlEntry"] = reflect.TypeOf((*ArrayOfHostAccessControlEntry)(nil)).Elem() +} + +type ArrayOfHostAccountSpec struct { + HostAccountSpec []BaseHostAccountSpec `xml:"HostAccountSpec,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostAccountSpec"] = reflect.TypeOf((*ArrayOfHostAccountSpec)(nil)).Elem() +} + +type ArrayOfHostActiveDirectory struct { + HostActiveDirectory []HostActiveDirectory `xml:"HostActiveDirectory,omitempty"` +} + +func init() { + t["ArrayOfHostActiveDirectory"] = reflect.TypeOf((*ArrayOfHostActiveDirectory)(nil)).Elem() +} + +type ArrayOfHostAuthenticationStoreInfo struct { + HostAuthenticationStoreInfo []BaseHostAuthenticationStoreInfo `xml:"HostAuthenticationStoreInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostAuthenticationStoreInfo"] = reflect.TypeOf((*ArrayOfHostAuthenticationStoreInfo)(nil)).Elem() +} + +type ArrayOfHostBootDevice struct { + HostBootDevice []HostBootDevice `xml:"HostBootDevice,omitempty"` +} + +func init() { + t["ArrayOfHostBootDevice"] = reflect.TypeOf((*ArrayOfHostBootDevice)(nil)).Elem() +} + +type ArrayOfHostCacheConfigurationInfo struct { + HostCacheConfigurationInfo []HostCacheConfigurationInfo `xml:"HostCacheConfigurationInfo,omitempty"` +} + +func init() { + t["ArrayOfHostCacheConfigurationInfo"] = reflect.TypeOf((*ArrayOfHostCacheConfigurationInfo)(nil)).Elem() +} + +type ArrayOfHostConnectInfoNetworkInfo struct { + HostConnectInfoNetworkInfo []BaseHostConnectInfoNetworkInfo `xml:"HostConnectInfoNetworkInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostConnectInfoNetworkInfo"] = reflect.TypeOf((*ArrayOfHostConnectInfoNetworkInfo)(nil)).Elem() +} + +type ArrayOfHostCpuIdInfo struct { + HostCpuIdInfo []HostCpuIdInfo `xml:"HostCpuIdInfo,omitempty"` +} + +func init() { + t["ArrayOfHostCpuIdInfo"] = reflect.TypeOf((*ArrayOfHostCpuIdInfo)(nil)).Elem() +} + +type ArrayOfHostCpuPackage struct { + HostCpuPackage []HostCpuPackage `xml:"HostCpuPackage,omitempty"` +} + +func init() { + t["ArrayOfHostCpuPackage"] = reflect.TypeOf((*ArrayOfHostCpuPackage)(nil)).Elem() +} + +type ArrayOfHostDatastoreBrowserSearchResults struct { + HostDatastoreBrowserSearchResults []HostDatastoreBrowserSearchResults `xml:"HostDatastoreBrowserSearchResults,omitempty"` +} + +func init() { + t["ArrayOfHostDatastoreBrowserSearchResults"] = reflect.TypeOf((*ArrayOfHostDatastoreBrowserSearchResults)(nil)).Elem() +} + +type ArrayOfHostDatastoreConnectInfo struct { + HostDatastoreConnectInfo []BaseHostDatastoreConnectInfo `xml:"HostDatastoreConnectInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostDatastoreConnectInfo"] = reflect.TypeOf((*ArrayOfHostDatastoreConnectInfo)(nil)).Elem() +} + +type ArrayOfHostDatastoreSystemDatastoreResult struct { + HostDatastoreSystemDatastoreResult []HostDatastoreSystemDatastoreResult `xml:"HostDatastoreSystemDatastoreResult,omitempty"` +} + +func init() { + t["ArrayOfHostDatastoreSystemDatastoreResult"] = reflect.TypeOf((*ArrayOfHostDatastoreSystemDatastoreResult)(nil)).Elem() +} + +type ArrayOfHostDateTimeSystemTimeZone struct { + HostDateTimeSystemTimeZone []HostDateTimeSystemTimeZone `xml:"HostDateTimeSystemTimeZone,omitempty"` +} + +func init() { + t["ArrayOfHostDateTimeSystemTimeZone"] = reflect.TypeOf((*ArrayOfHostDateTimeSystemTimeZone)(nil)).Elem() +} + +type ArrayOfHostDhcpService struct { + HostDhcpService []HostDhcpService `xml:"HostDhcpService,omitempty"` +} + +func init() { + t["ArrayOfHostDhcpService"] = reflect.TypeOf((*ArrayOfHostDhcpService)(nil)).Elem() +} + +type ArrayOfHostDhcpServiceConfig struct { + HostDhcpServiceConfig []HostDhcpServiceConfig `xml:"HostDhcpServiceConfig,omitempty"` +} + +func init() { + t["ArrayOfHostDhcpServiceConfig"] = reflect.TypeOf((*ArrayOfHostDhcpServiceConfig)(nil)).Elem() +} + +type ArrayOfHostDiagnosticPartition struct { + HostDiagnosticPartition []HostDiagnosticPartition `xml:"HostDiagnosticPartition,omitempty"` +} + +func init() { + t["ArrayOfHostDiagnosticPartition"] = reflect.TypeOf((*ArrayOfHostDiagnosticPartition)(nil)).Elem() +} + +type ArrayOfHostDiagnosticPartitionCreateOption struct { + HostDiagnosticPartitionCreateOption []HostDiagnosticPartitionCreateOption `xml:"HostDiagnosticPartitionCreateOption,omitempty"` +} + +func init() { + t["ArrayOfHostDiagnosticPartitionCreateOption"] = reflect.TypeOf((*ArrayOfHostDiagnosticPartitionCreateOption)(nil)).Elem() +} + +type ArrayOfHostDiskConfigurationResult struct { + HostDiskConfigurationResult []HostDiskConfigurationResult `xml:"HostDiskConfigurationResult,omitempty"` +} + +func init() { + t["ArrayOfHostDiskConfigurationResult"] = reflect.TypeOf((*ArrayOfHostDiskConfigurationResult)(nil)).Elem() +} + +type ArrayOfHostDiskMappingPartitionOption struct { + HostDiskMappingPartitionOption []HostDiskMappingPartitionOption `xml:"HostDiskMappingPartitionOption,omitempty"` +} + +func init() { + t["ArrayOfHostDiskMappingPartitionOption"] = reflect.TypeOf((*ArrayOfHostDiskMappingPartitionOption)(nil)).Elem() +} + +type ArrayOfHostDiskPartitionAttributes struct { + HostDiskPartitionAttributes []HostDiskPartitionAttributes `xml:"HostDiskPartitionAttributes,omitempty"` +} + +func init() { + t["ArrayOfHostDiskPartitionAttributes"] = reflect.TypeOf((*ArrayOfHostDiskPartitionAttributes)(nil)).Elem() +} + +type ArrayOfHostDiskPartitionBlockRange struct { + HostDiskPartitionBlockRange []HostDiskPartitionBlockRange `xml:"HostDiskPartitionBlockRange,omitempty"` +} + +func init() { + t["ArrayOfHostDiskPartitionBlockRange"] = reflect.TypeOf((*ArrayOfHostDiskPartitionBlockRange)(nil)).Elem() +} + +type ArrayOfHostDiskPartitionInfo struct { + HostDiskPartitionInfo []HostDiskPartitionInfo `xml:"HostDiskPartitionInfo,omitempty"` +} + +func init() { + t["ArrayOfHostDiskPartitionInfo"] = reflect.TypeOf((*ArrayOfHostDiskPartitionInfo)(nil)).Elem() +} + +type ArrayOfHostEventArgument struct { + HostEventArgument []HostEventArgument `xml:"HostEventArgument,omitempty"` +} + +func init() { + t["ArrayOfHostEventArgument"] = reflect.TypeOf((*ArrayOfHostEventArgument)(nil)).Elem() +} + +type ArrayOfHostFeatureCapability struct { + HostFeatureCapability []HostFeatureCapability `xml:"HostFeatureCapability,omitempty"` +} + +func init() { + t["ArrayOfHostFeatureCapability"] = reflect.TypeOf((*ArrayOfHostFeatureCapability)(nil)).Elem() +} + +type ArrayOfHostFeatureMask struct { + HostFeatureMask []HostFeatureMask `xml:"HostFeatureMask,omitempty"` +} + +func init() { + t["ArrayOfHostFeatureMask"] = reflect.TypeOf((*ArrayOfHostFeatureMask)(nil)).Elem() +} + +type ArrayOfHostFeatureVersionInfo struct { + HostFeatureVersionInfo []HostFeatureVersionInfo `xml:"HostFeatureVersionInfo,omitempty"` +} + +func init() { + t["ArrayOfHostFeatureVersionInfo"] = reflect.TypeOf((*ArrayOfHostFeatureVersionInfo)(nil)).Elem() +} + +type ArrayOfHostFileSystemMountInfo struct { + HostFileSystemMountInfo []HostFileSystemMountInfo `xml:"HostFileSystemMountInfo,omitempty"` +} + +func init() { + t["ArrayOfHostFileSystemMountInfo"] = reflect.TypeOf((*ArrayOfHostFileSystemMountInfo)(nil)).Elem() +} + +type ArrayOfHostFirewallConfigRuleSetConfig struct { + HostFirewallConfigRuleSetConfig []HostFirewallConfigRuleSetConfig `xml:"HostFirewallConfigRuleSetConfig,omitempty"` +} + +func init() { + t["ArrayOfHostFirewallConfigRuleSetConfig"] = reflect.TypeOf((*ArrayOfHostFirewallConfigRuleSetConfig)(nil)).Elem() +} + +type ArrayOfHostFirewallRule struct { + HostFirewallRule []HostFirewallRule `xml:"HostFirewallRule,omitempty"` +} + +func init() { + t["ArrayOfHostFirewallRule"] = reflect.TypeOf((*ArrayOfHostFirewallRule)(nil)).Elem() +} + +type ArrayOfHostFirewallRuleset struct { + HostFirewallRuleset []HostFirewallRuleset `xml:"HostFirewallRuleset,omitempty"` +} + +func init() { + t["ArrayOfHostFirewallRuleset"] = reflect.TypeOf((*ArrayOfHostFirewallRuleset)(nil)).Elem() +} + +type ArrayOfHostFirewallRulesetIpNetwork struct { + HostFirewallRulesetIpNetwork []HostFirewallRulesetIpNetwork `xml:"HostFirewallRulesetIpNetwork,omitempty"` +} + +func init() { + t["ArrayOfHostFirewallRulesetIpNetwork"] = reflect.TypeOf((*ArrayOfHostFirewallRulesetIpNetwork)(nil)).Elem() +} + +type ArrayOfHostGraphicsInfo struct { + HostGraphicsInfo []HostGraphicsInfo `xml:"HostGraphicsInfo,omitempty"` +} + +func init() { + t["ArrayOfHostGraphicsInfo"] = reflect.TypeOf((*ArrayOfHostGraphicsInfo)(nil)).Elem() +} + +type ArrayOfHostHardwareElementInfo struct { + HostHardwareElementInfo []BaseHostHardwareElementInfo `xml:"HostHardwareElementInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostHardwareElementInfo"] = reflect.TypeOf((*ArrayOfHostHardwareElementInfo)(nil)).Elem() +} + +type ArrayOfHostHostBusAdapter struct { + HostHostBusAdapter []BaseHostHostBusAdapter `xml:"HostHostBusAdapter,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostHostBusAdapter"] = reflect.TypeOf((*ArrayOfHostHostBusAdapter)(nil)).Elem() +} + +type ArrayOfHostInternetScsiHbaIscsiIpv6Address struct { + HostInternetScsiHbaIscsiIpv6Address []HostInternetScsiHbaIscsiIpv6Address `xml:"HostInternetScsiHbaIscsiIpv6Address,omitempty"` +} + +func init() { + t["ArrayOfHostInternetScsiHbaIscsiIpv6Address"] = reflect.TypeOf((*ArrayOfHostInternetScsiHbaIscsiIpv6Address)(nil)).Elem() +} + +type ArrayOfHostInternetScsiHbaParamValue struct { + HostInternetScsiHbaParamValue []HostInternetScsiHbaParamValue `xml:"HostInternetScsiHbaParamValue,omitempty"` +} + +func init() { + t["ArrayOfHostInternetScsiHbaParamValue"] = reflect.TypeOf((*ArrayOfHostInternetScsiHbaParamValue)(nil)).Elem() +} + +type ArrayOfHostInternetScsiHbaSendTarget struct { + HostInternetScsiHbaSendTarget []HostInternetScsiHbaSendTarget `xml:"HostInternetScsiHbaSendTarget,omitempty"` +} + +func init() { + t["ArrayOfHostInternetScsiHbaSendTarget"] = reflect.TypeOf((*ArrayOfHostInternetScsiHbaSendTarget)(nil)).Elem() +} + +type ArrayOfHostInternetScsiHbaStaticTarget struct { + HostInternetScsiHbaStaticTarget []HostInternetScsiHbaStaticTarget `xml:"HostInternetScsiHbaStaticTarget,omitempty"` +} + +func init() { + t["ArrayOfHostInternetScsiHbaStaticTarget"] = reflect.TypeOf((*ArrayOfHostInternetScsiHbaStaticTarget)(nil)).Elem() +} + +type ArrayOfHostIoFilterInfo struct { + HostIoFilterInfo []HostIoFilterInfo `xml:"HostIoFilterInfo,omitempty"` +} + +func init() { + t["ArrayOfHostIoFilterInfo"] = reflect.TypeOf((*ArrayOfHostIoFilterInfo)(nil)).Elem() +} + +type ArrayOfHostIpConfigIpV6Address struct { + HostIpConfigIpV6Address []HostIpConfigIpV6Address `xml:"HostIpConfigIpV6Address,omitempty"` +} + +func init() { + t["ArrayOfHostIpConfigIpV6Address"] = reflect.TypeOf((*ArrayOfHostIpConfigIpV6Address)(nil)).Elem() +} + +type ArrayOfHostIpRouteEntry struct { + HostIpRouteEntry []HostIpRouteEntry `xml:"HostIpRouteEntry,omitempty"` +} + +func init() { + t["ArrayOfHostIpRouteEntry"] = reflect.TypeOf((*ArrayOfHostIpRouteEntry)(nil)).Elem() +} + +type ArrayOfHostIpRouteOp struct { + HostIpRouteOp []HostIpRouteOp `xml:"HostIpRouteOp,omitempty"` +} + +func init() { + t["ArrayOfHostIpRouteOp"] = reflect.TypeOf((*ArrayOfHostIpRouteOp)(nil)).Elem() +} + +type ArrayOfHostLowLevelProvisioningManagerDiskLayoutSpec struct { + HostLowLevelProvisioningManagerDiskLayoutSpec []HostLowLevelProvisioningManagerDiskLayoutSpec `xml:"HostLowLevelProvisioningManagerDiskLayoutSpec,omitempty"` +} + +func init() { + t["ArrayOfHostLowLevelProvisioningManagerDiskLayoutSpec"] = reflect.TypeOf((*ArrayOfHostLowLevelProvisioningManagerDiskLayoutSpec)(nil)).Elem() +} + +type ArrayOfHostLowLevelProvisioningManagerFileDeleteResult struct { + HostLowLevelProvisioningManagerFileDeleteResult []HostLowLevelProvisioningManagerFileDeleteResult `xml:"HostLowLevelProvisioningManagerFileDeleteResult,omitempty"` +} + +func init() { + t["ArrayOfHostLowLevelProvisioningManagerFileDeleteResult"] = reflect.TypeOf((*ArrayOfHostLowLevelProvisioningManagerFileDeleteResult)(nil)).Elem() +} + +type ArrayOfHostLowLevelProvisioningManagerFileDeleteSpec struct { + HostLowLevelProvisioningManagerFileDeleteSpec []HostLowLevelProvisioningManagerFileDeleteSpec `xml:"HostLowLevelProvisioningManagerFileDeleteSpec,omitempty"` +} + +func init() { + t["ArrayOfHostLowLevelProvisioningManagerFileDeleteSpec"] = reflect.TypeOf((*ArrayOfHostLowLevelProvisioningManagerFileDeleteSpec)(nil)).Elem() +} + +type ArrayOfHostLowLevelProvisioningManagerFileReserveResult struct { + HostLowLevelProvisioningManagerFileReserveResult []HostLowLevelProvisioningManagerFileReserveResult `xml:"HostLowLevelProvisioningManagerFileReserveResult,omitempty"` +} + +func init() { + t["ArrayOfHostLowLevelProvisioningManagerFileReserveResult"] = reflect.TypeOf((*ArrayOfHostLowLevelProvisioningManagerFileReserveResult)(nil)).Elem() +} + +type ArrayOfHostLowLevelProvisioningManagerFileReserveSpec struct { + HostLowLevelProvisioningManagerFileReserveSpec []HostLowLevelProvisioningManagerFileReserveSpec `xml:"HostLowLevelProvisioningManagerFileReserveSpec,omitempty"` +} + +func init() { + t["ArrayOfHostLowLevelProvisioningManagerFileReserveSpec"] = reflect.TypeOf((*ArrayOfHostLowLevelProvisioningManagerFileReserveSpec)(nil)).Elem() +} + +type ArrayOfHostLowLevelProvisioningManagerSnapshotLayoutSpec struct { + HostLowLevelProvisioningManagerSnapshotLayoutSpec []HostLowLevelProvisioningManagerSnapshotLayoutSpec `xml:"HostLowLevelProvisioningManagerSnapshotLayoutSpec,omitempty"` +} + +func init() { + t["ArrayOfHostLowLevelProvisioningManagerSnapshotLayoutSpec"] = reflect.TypeOf((*ArrayOfHostLowLevelProvisioningManagerSnapshotLayoutSpec)(nil)).Elem() +} + +type ArrayOfHostMemberHealthCheckResult struct { + HostMemberHealthCheckResult []BaseHostMemberHealthCheckResult `xml:"HostMemberHealthCheckResult,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostMemberHealthCheckResult"] = reflect.TypeOf((*ArrayOfHostMemberHealthCheckResult)(nil)).Elem() +} + +type ArrayOfHostMemberRuntimeInfo struct { + HostMemberRuntimeInfo []HostMemberRuntimeInfo `xml:"HostMemberRuntimeInfo,omitempty"` +} + +func init() { + t["ArrayOfHostMemberRuntimeInfo"] = reflect.TypeOf((*ArrayOfHostMemberRuntimeInfo)(nil)).Elem() +} + +type ArrayOfHostMultipathInfoLogicalUnit struct { + HostMultipathInfoLogicalUnit []HostMultipathInfoLogicalUnit `xml:"HostMultipathInfoLogicalUnit,omitempty"` +} + +func init() { + t["ArrayOfHostMultipathInfoLogicalUnit"] = reflect.TypeOf((*ArrayOfHostMultipathInfoLogicalUnit)(nil)).Elem() +} + +type ArrayOfHostMultipathInfoPath struct { + HostMultipathInfoPath []HostMultipathInfoPath `xml:"HostMultipathInfoPath,omitempty"` +} + +func init() { + t["ArrayOfHostMultipathInfoPath"] = reflect.TypeOf((*ArrayOfHostMultipathInfoPath)(nil)).Elem() +} + +type ArrayOfHostMultipathStateInfoPath struct { + HostMultipathStateInfoPath []HostMultipathStateInfoPath `xml:"HostMultipathStateInfoPath,omitempty"` +} + +func init() { + t["ArrayOfHostMultipathStateInfoPath"] = reflect.TypeOf((*ArrayOfHostMultipathStateInfoPath)(nil)).Elem() +} + +type ArrayOfHostNasVolumeConfig struct { + HostNasVolumeConfig []HostNasVolumeConfig `xml:"HostNasVolumeConfig,omitempty"` +} + +func init() { + t["ArrayOfHostNasVolumeConfig"] = reflect.TypeOf((*ArrayOfHostNasVolumeConfig)(nil)).Elem() +} + +type ArrayOfHostNatService struct { + HostNatService []HostNatService `xml:"HostNatService,omitempty"` +} + +func init() { + t["ArrayOfHostNatService"] = reflect.TypeOf((*ArrayOfHostNatService)(nil)).Elem() +} + +type ArrayOfHostNatServiceConfig struct { + HostNatServiceConfig []HostNatServiceConfig `xml:"HostNatServiceConfig,omitempty"` +} + +func init() { + t["ArrayOfHostNatServiceConfig"] = reflect.TypeOf((*ArrayOfHostNatServiceConfig)(nil)).Elem() +} + +type ArrayOfHostNatServicePortForwardSpec struct { + HostNatServicePortForwardSpec []HostNatServicePortForwardSpec `xml:"HostNatServicePortForwardSpec,omitempty"` +} + +func init() { + t["ArrayOfHostNatServicePortForwardSpec"] = reflect.TypeOf((*ArrayOfHostNatServicePortForwardSpec)(nil)).Elem() +} + +type ArrayOfHostNetStackInstance struct { + HostNetStackInstance []HostNetStackInstance `xml:"HostNetStackInstance,omitempty"` +} + +func init() { + t["ArrayOfHostNetStackInstance"] = reflect.TypeOf((*ArrayOfHostNetStackInstance)(nil)).Elem() +} + +type ArrayOfHostNetworkConfigNetStackSpec struct { + HostNetworkConfigNetStackSpec []HostNetworkConfigNetStackSpec `xml:"HostNetworkConfigNetStackSpec,omitempty"` +} + +func init() { + t["ArrayOfHostNetworkConfigNetStackSpec"] = reflect.TypeOf((*ArrayOfHostNetworkConfigNetStackSpec)(nil)).Elem() +} + +type ArrayOfHostNumaNode struct { + HostNumaNode []HostNumaNode `xml:"HostNumaNode,omitempty"` +} + +func init() { + t["ArrayOfHostNumaNode"] = reflect.TypeOf((*ArrayOfHostNumaNode)(nil)).Elem() +} + +type ArrayOfHostNumericSensorInfo struct { + HostNumericSensorInfo []HostNumericSensorInfo `xml:"HostNumericSensorInfo,omitempty"` +} + +func init() { + t["ArrayOfHostNumericSensorInfo"] = reflect.TypeOf((*ArrayOfHostNumericSensorInfo)(nil)).Elem() +} + +type ArrayOfHostOpaqueNetworkInfo struct { + HostOpaqueNetworkInfo []HostOpaqueNetworkInfo `xml:"HostOpaqueNetworkInfo,omitempty"` +} + +func init() { + t["ArrayOfHostOpaqueNetworkInfo"] = reflect.TypeOf((*ArrayOfHostOpaqueNetworkInfo)(nil)).Elem() +} + +type ArrayOfHostOpaqueSwitch struct { + HostOpaqueSwitch []HostOpaqueSwitch `xml:"HostOpaqueSwitch,omitempty"` +} + +func init() { + t["ArrayOfHostOpaqueSwitch"] = reflect.TypeOf((*ArrayOfHostOpaqueSwitch)(nil)).Elem() +} + +type ArrayOfHostOpaqueSwitchPhysicalNicZone struct { + HostOpaqueSwitchPhysicalNicZone []HostOpaqueSwitchPhysicalNicZone `xml:"HostOpaqueSwitchPhysicalNicZone,omitempty"` +} + +func init() { + t["ArrayOfHostOpaqueSwitchPhysicalNicZone"] = reflect.TypeOf((*ArrayOfHostOpaqueSwitchPhysicalNicZone)(nil)).Elem() +} + +type ArrayOfHostPatchManagerStatus struct { + HostPatchManagerStatus []HostPatchManagerStatus `xml:"HostPatchManagerStatus,omitempty"` +} + +func init() { + t["ArrayOfHostPatchManagerStatus"] = reflect.TypeOf((*ArrayOfHostPatchManagerStatus)(nil)).Elem() +} + +type ArrayOfHostPatchManagerStatusPrerequisitePatch struct { + HostPatchManagerStatusPrerequisitePatch []HostPatchManagerStatusPrerequisitePatch `xml:"HostPatchManagerStatusPrerequisitePatch,omitempty"` +} + +func init() { + t["ArrayOfHostPatchManagerStatusPrerequisitePatch"] = reflect.TypeOf((*ArrayOfHostPatchManagerStatusPrerequisitePatch)(nil)).Elem() +} + +type ArrayOfHostPathSelectionPolicyOption struct { + HostPathSelectionPolicyOption []HostPathSelectionPolicyOption `xml:"HostPathSelectionPolicyOption,omitempty"` +} + +func init() { + t["ArrayOfHostPathSelectionPolicyOption"] = reflect.TypeOf((*ArrayOfHostPathSelectionPolicyOption)(nil)).Elem() +} + +type ArrayOfHostPciDevice struct { + HostPciDevice []HostPciDevice `xml:"HostPciDevice,omitempty"` +} + +func init() { + t["ArrayOfHostPciDevice"] = reflect.TypeOf((*ArrayOfHostPciDevice)(nil)).Elem() +} + +type ArrayOfHostPciPassthruConfig struct { + HostPciPassthruConfig []BaseHostPciPassthruConfig `xml:"HostPciPassthruConfig,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostPciPassthruConfig"] = reflect.TypeOf((*ArrayOfHostPciPassthruConfig)(nil)).Elem() +} + +type ArrayOfHostPciPassthruInfo struct { + HostPciPassthruInfo []BaseHostPciPassthruInfo `xml:"HostPciPassthruInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostPciPassthruInfo"] = reflect.TypeOf((*ArrayOfHostPciPassthruInfo)(nil)).Elem() +} + +type ArrayOfHostPlacedVirtualNicIdentifier struct { + HostPlacedVirtualNicIdentifier []HostPlacedVirtualNicIdentifier `xml:"HostPlacedVirtualNicIdentifier,omitempty"` +} + +func init() { + t["ArrayOfHostPlacedVirtualNicIdentifier"] = reflect.TypeOf((*ArrayOfHostPlacedVirtualNicIdentifier)(nil)).Elem() +} + +type ArrayOfHostPlugStoreTopologyAdapter struct { + HostPlugStoreTopologyAdapter []HostPlugStoreTopologyAdapter `xml:"HostPlugStoreTopologyAdapter,omitempty"` +} + +func init() { + t["ArrayOfHostPlugStoreTopologyAdapter"] = reflect.TypeOf((*ArrayOfHostPlugStoreTopologyAdapter)(nil)).Elem() +} + +type ArrayOfHostPlugStoreTopologyDevice struct { + HostPlugStoreTopologyDevice []HostPlugStoreTopologyDevice `xml:"HostPlugStoreTopologyDevice,omitempty"` +} + +func init() { + t["ArrayOfHostPlugStoreTopologyDevice"] = reflect.TypeOf((*ArrayOfHostPlugStoreTopologyDevice)(nil)).Elem() +} + +type ArrayOfHostPlugStoreTopologyPath struct { + HostPlugStoreTopologyPath []HostPlugStoreTopologyPath `xml:"HostPlugStoreTopologyPath,omitempty"` +} + +func init() { + t["ArrayOfHostPlugStoreTopologyPath"] = reflect.TypeOf((*ArrayOfHostPlugStoreTopologyPath)(nil)).Elem() +} + +type ArrayOfHostPlugStoreTopologyPlugin struct { + HostPlugStoreTopologyPlugin []HostPlugStoreTopologyPlugin `xml:"HostPlugStoreTopologyPlugin,omitempty"` +} + +func init() { + t["ArrayOfHostPlugStoreTopologyPlugin"] = reflect.TypeOf((*ArrayOfHostPlugStoreTopologyPlugin)(nil)).Elem() +} + +type ArrayOfHostPlugStoreTopologyTarget struct { + HostPlugStoreTopologyTarget []HostPlugStoreTopologyTarget `xml:"HostPlugStoreTopologyTarget,omitempty"` +} + +func init() { + t["ArrayOfHostPlugStoreTopologyTarget"] = reflect.TypeOf((*ArrayOfHostPlugStoreTopologyTarget)(nil)).Elem() +} + +type ArrayOfHostPnicNetworkResourceInfo struct { + HostPnicNetworkResourceInfo []HostPnicNetworkResourceInfo `xml:"HostPnicNetworkResourceInfo,omitempty"` +} + +func init() { + t["ArrayOfHostPnicNetworkResourceInfo"] = reflect.TypeOf((*ArrayOfHostPnicNetworkResourceInfo)(nil)).Elem() +} + +type ArrayOfHostPortGroup struct { + HostPortGroup []HostPortGroup `xml:"HostPortGroup,omitempty"` +} + +func init() { + t["ArrayOfHostPortGroup"] = reflect.TypeOf((*ArrayOfHostPortGroup)(nil)).Elem() +} + +type ArrayOfHostPortGroupConfig struct { + HostPortGroupConfig []HostPortGroupConfig `xml:"HostPortGroupConfig,omitempty"` +} + +func init() { + t["ArrayOfHostPortGroupConfig"] = reflect.TypeOf((*ArrayOfHostPortGroupConfig)(nil)).Elem() +} + +type ArrayOfHostPortGroupPort struct { + HostPortGroupPort []HostPortGroupPort `xml:"HostPortGroupPort,omitempty"` +} + +func init() { + t["ArrayOfHostPortGroupPort"] = reflect.TypeOf((*ArrayOfHostPortGroupPort)(nil)).Elem() +} + +type ArrayOfHostPortGroupProfile struct { + HostPortGroupProfile []HostPortGroupProfile `xml:"HostPortGroupProfile,omitempty"` +} + +func init() { + t["ArrayOfHostPortGroupProfile"] = reflect.TypeOf((*ArrayOfHostPortGroupProfile)(nil)).Elem() +} + +type ArrayOfHostPowerPolicy struct { + HostPowerPolicy []HostPowerPolicy `xml:"HostPowerPolicy,omitempty"` +} + +func init() { + t["ArrayOfHostPowerPolicy"] = reflect.TypeOf((*ArrayOfHostPowerPolicy)(nil)).Elem() +} + +type ArrayOfHostProtocolEndpoint struct { + HostProtocolEndpoint []HostProtocolEndpoint `xml:"HostProtocolEndpoint,omitempty"` +} + +func init() { + t["ArrayOfHostProtocolEndpoint"] = reflect.TypeOf((*ArrayOfHostProtocolEndpoint)(nil)).Elem() +} + +type ArrayOfHostProxySwitch struct { + HostProxySwitch []HostProxySwitch `xml:"HostProxySwitch,omitempty"` +} + +func init() { + t["ArrayOfHostProxySwitch"] = reflect.TypeOf((*ArrayOfHostProxySwitch)(nil)).Elem() +} + +type ArrayOfHostProxySwitchConfig struct { + HostProxySwitchConfig []HostProxySwitchConfig `xml:"HostProxySwitchConfig,omitempty"` +} + +func init() { + t["ArrayOfHostProxySwitchConfig"] = reflect.TypeOf((*ArrayOfHostProxySwitchConfig)(nil)).Elem() +} + +type ArrayOfHostProxySwitchHostLagConfig struct { + HostProxySwitchHostLagConfig []HostProxySwitchHostLagConfig `xml:"HostProxySwitchHostLagConfig,omitempty"` +} + +func init() { + t["ArrayOfHostProxySwitchHostLagConfig"] = reflect.TypeOf((*ArrayOfHostProxySwitchHostLagConfig)(nil)).Elem() +} + +type ArrayOfHostRuntimeInfoNetStackInstanceRuntimeInfo struct { + HostRuntimeInfoNetStackInstanceRuntimeInfo []HostRuntimeInfoNetStackInstanceRuntimeInfo `xml:"HostRuntimeInfoNetStackInstanceRuntimeInfo,omitempty"` +} + +func init() { + t["ArrayOfHostRuntimeInfoNetStackInstanceRuntimeInfo"] = reflect.TypeOf((*ArrayOfHostRuntimeInfoNetStackInstanceRuntimeInfo)(nil)).Elem() +} + +type ArrayOfHostScsiDisk struct { + HostScsiDisk []HostScsiDisk `xml:"HostScsiDisk,omitempty"` +} + +func init() { + t["ArrayOfHostScsiDisk"] = reflect.TypeOf((*ArrayOfHostScsiDisk)(nil)).Elem() +} + +type ArrayOfHostScsiDiskPartition struct { + HostScsiDiskPartition []HostScsiDiskPartition `xml:"HostScsiDiskPartition,omitempty"` +} + +func init() { + t["ArrayOfHostScsiDiskPartition"] = reflect.TypeOf((*ArrayOfHostScsiDiskPartition)(nil)).Elem() +} + +type ArrayOfHostScsiTopologyInterface struct { + HostScsiTopologyInterface []HostScsiTopologyInterface `xml:"HostScsiTopologyInterface,omitempty"` +} + +func init() { + t["ArrayOfHostScsiTopologyInterface"] = reflect.TypeOf((*ArrayOfHostScsiTopologyInterface)(nil)).Elem() +} + +type ArrayOfHostScsiTopologyLun struct { + HostScsiTopologyLun []HostScsiTopologyLun `xml:"HostScsiTopologyLun,omitempty"` +} + +func init() { + t["ArrayOfHostScsiTopologyLun"] = reflect.TypeOf((*ArrayOfHostScsiTopologyLun)(nil)).Elem() +} + +type ArrayOfHostScsiTopologyTarget struct { + HostScsiTopologyTarget []HostScsiTopologyTarget `xml:"HostScsiTopologyTarget,omitempty"` +} + +func init() { + t["ArrayOfHostScsiTopologyTarget"] = reflect.TypeOf((*ArrayOfHostScsiTopologyTarget)(nil)).Elem() +} + +type ArrayOfHostService struct { + HostService []HostService `xml:"HostService,omitempty"` +} + +func init() { + t["ArrayOfHostService"] = reflect.TypeOf((*ArrayOfHostService)(nil)).Elem() +} + +type ArrayOfHostServiceConfig struct { + HostServiceConfig []HostServiceConfig `xml:"HostServiceConfig,omitempty"` +} + +func init() { + t["ArrayOfHostServiceConfig"] = reflect.TypeOf((*ArrayOfHostServiceConfig)(nil)).Elem() +} + +type ArrayOfHostSnmpDestination struct { + HostSnmpDestination []HostSnmpDestination `xml:"HostSnmpDestination,omitempty"` +} + +func init() { + t["ArrayOfHostSnmpDestination"] = reflect.TypeOf((*ArrayOfHostSnmpDestination)(nil)).Elem() +} + +type ArrayOfHostSslThumbprintInfo struct { + HostSslThumbprintInfo []HostSslThumbprintInfo `xml:"HostSslThumbprintInfo,omitempty"` +} + +func init() { + t["ArrayOfHostSslThumbprintInfo"] = reflect.TypeOf((*ArrayOfHostSslThumbprintInfo)(nil)).Elem() +} + +type ArrayOfHostStorageArrayTypePolicyOption struct { + HostStorageArrayTypePolicyOption []HostStorageArrayTypePolicyOption `xml:"HostStorageArrayTypePolicyOption,omitempty"` +} + +func init() { + t["ArrayOfHostStorageArrayTypePolicyOption"] = reflect.TypeOf((*ArrayOfHostStorageArrayTypePolicyOption)(nil)).Elem() +} + +type ArrayOfHostStorageElementInfo struct { + HostStorageElementInfo []HostStorageElementInfo `xml:"HostStorageElementInfo,omitempty"` +} + +func init() { + t["ArrayOfHostStorageElementInfo"] = reflect.TypeOf((*ArrayOfHostStorageElementInfo)(nil)).Elem() +} + +type ArrayOfHostStorageOperationalInfo struct { + HostStorageOperationalInfo []HostStorageOperationalInfo `xml:"HostStorageOperationalInfo,omitempty"` +} + +func init() { + t["ArrayOfHostStorageOperationalInfo"] = reflect.TypeOf((*ArrayOfHostStorageOperationalInfo)(nil)).Elem() +} + +type ArrayOfHostStorageSystemDiskLocatorLedResult struct { + HostStorageSystemDiskLocatorLedResult []HostStorageSystemDiskLocatorLedResult `xml:"HostStorageSystemDiskLocatorLedResult,omitempty"` +} + +func init() { + t["ArrayOfHostStorageSystemDiskLocatorLedResult"] = reflect.TypeOf((*ArrayOfHostStorageSystemDiskLocatorLedResult)(nil)).Elem() +} + +type ArrayOfHostStorageSystemScsiLunResult struct { + HostStorageSystemScsiLunResult []HostStorageSystemScsiLunResult `xml:"HostStorageSystemScsiLunResult,omitempty"` +} + +func init() { + t["ArrayOfHostStorageSystemScsiLunResult"] = reflect.TypeOf((*ArrayOfHostStorageSystemScsiLunResult)(nil)).Elem() +} + +type ArrayOfHostStorageSystemVmfsVolumeResult struct { + HostStorageSystemVmfsVolumeResult []HostStorageSystemVmfsVolumeResult `xml:"HostStorageSystemVmfsVolumeResult,omitempty"` +} + +func init() { + t["ArrayOfHostStorageSystemVmfsVolumeResult"] = reflect.TypeOf((*ArrayOfHostStorageSystemVmfsVolumeResult)(nil)).Elem() +} + +type ArrayOfHostSystemIdentificationInfo struct { + HostSystemIdentificationInfo []HostSystemIdentificationInfo `xml:"HostSystemIdentificationInfo,omitempty"` +} + +func init() { + t["ArrayOfHostSystemIdentificationInfo"] = reflect.TypeOf((*ArrayOfHostSystemIdentificationInfo)(nil)).Elem() +} + +type ArrayOfHostSystemResourceInfo struct { + HostSystemResourceInfo []HostSystemResourceInfo `xml:"HostSystemResourceInfo,omitempty"` +} + +func init() { + t["ArrayOfHostSystemResourceInfo"] = reflect.TypeOf((*ArrayOfHostSystemResourceInfo)(nil)).Elem() +} + +type ArrayOfHostSystemSwapConfigurationSystemSwapOption struct { + HostSystemSwapConfigurationSystemSwapOption []BaseHostSystemSwapConfigurationSystemSwapOption `xml:"HostSystemSwapConfigurationSystemSwapOption,omitempty,typeattr"` +} + +func init() { + t["ArrayOfHostSystemSwapConfigurationSystemSwapOption"] = reflect.TypeOf((*ArrayOfHostSystemSwapConfigurationSystemSwapOption)(nil)).Elem() +} + +type ArrayOfHostTpmDigestInfo struct { + HostTpmDigestInfo []HostTpmDigestInfo `xml:"HostTpmDigestInfo,omitempty"` +} + +func init() { + t["ArrayOfHostTpmDigestInfo"] = reflect.TypeOf((*ArrayOfHostTpmDigestInfo)(nil)).Elem() +} + +type ArrayOfHostTpmEventLogEntry struct { + HostTpmEventLogEntry []HostTpmEventLogEntry `xml:"HostTpmEventLogEntry,omitempty"` +} + +func init() { + t["ArrayOfHostTpmEventLogEntry"] = reflect.TypeOf((*ArrayOfHostTpmEventLogEntry)(nil)).Elem() +} + +type ArrayOfHostUnresolvedVmfsExtent struct { + HostUnresolvedVmfsExtent []HostUnresolvedVmfsExtent `xml:"HostUnresolvedVmfsExtent,omitempty"` +} + +func init() { + t["ArrayOfHostUnresolvedVmfsExtent"] = reflect.TypeOf((*ArrayOfHostUnresolvedVmfsExtent)(nil)).Elem() +} + +type ArrayOfHostUnresolvedVmfsResolutionResult struct { + HostUnresolvedVmfsResolutionResult []HostUnresolvedVmfsResolutionResult `xml:"HostUnresolvedVmfsResolutionResult,omitempty"` +} + +func init() { + t["ArrayOfHostUnresolvedVmfsResolutionResult"] = reflect.TypeOf((*ArrayOfHostUnresolvedVmfsResolutionResult)(nil)).Elem() +} + +type ArrayOfHostUnresolvedVmfsResolutionSpec struct { + HostUnresolvedVmfsResolutionSpec []HostUnresolvedVmfsResolutionSpec `xml:"HostUnresolvedVmfsResolutionSpec,omitempty"` +} + +func init() { + t["ArrayOfHostUnresolvedVmfsResolutionSpec"] = reflect.TypeOf((*ArrayOfHostUnresolvedVmfsResolutionSpec)(nil)).Elem() +} + +type ArrayOfHostUnresolvedVmfsVolume struct { + HostUnresolvedVmfsVolume []HostUnresolvedVmfsVolume `xml:"HostUnresolvedVmfsVolume,omitempty"` +} + +func init() { + t["ArrayOfHostUnresolvedVmfsVolume"] = reflect.TypeOf((*ArrayOfHostUnresolvedVmfsVolume)(nil)).Elem() +} + +type ArrayOfHostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption struct { + HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption []HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption `xml:"HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption,omitempty"` +} + +func init() { + t["ArrayOfHostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption"] = reflect.TypeOf((*ArrayOfHostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption)(nil)).Elem() +} + +type ArrayOfHostVMotionCompatibility struct { + HostVMotionCompatibility []HostVMotionCompatibility `xml:"HostVMotionCompatibility,omitempty"` +} + +func init() { + t["ArrayOfHostVMotionCompatibility"] = reflect.TypeOf((*ArrayOfHostVMotionCompatibility)(nil)).Elem() +} + +type ArrayOfHostVirtualNic struct { + HostVirtualNic []HostVirtualNic `xml:"HostVirtualNic,omitempty"` +} + +func init() { + t["ArrayOfHostVirtualNic"] = reflect.TypeOf((*ArrayOfHostVirtualNic)(nil)).Elem() +} + +type ArrayOfHostVirtualNicConfig struct { + HostVirtualNicConfig []HostVirtualNicConfig `xml:"HostVirtualNicConfig,omitempty"` +} + +func init() { + t["ArrayOfHostVirtualNicConfig"] = reflect.TypeOf((*ArrayOfHostVirtualNicConfig)(nil)).Elem() +} + +type ArrayOfHostVirtualNicManagerNicTypeSelection struct { + HostVirtualNicManagerNicTypeSelection []HostVirtualNicManagerNicTypeSelection `xml:"HostVirtualNicManagerNicTypeSelection,omitempty"` +} + +func init() { + t["ArrayOfHostVirtualNicManagerNicTypeSelection"] = reflect.TypeOf((*ArrayOfHostVirtualNicManagerNicTypeSelection)(nil)).Elem() +} + +type ArrayOfHostVirtualSwitch struct { + HostVirtualSwitch []HostVirtualSwitch `xml:"HostVirtualSwitch,omitempty"` +} + +func init() { + t["ArrayOfHostVirtualSwitch"] = reflect.TypeOf((*ArrayOfHostVirtualSwitch)(nil)).Elem() +} + +type ArrayOfHostVirtualSwitchConfig struct { + HostVirtualSwitchConfig []HostVirtualSwitchConfig `xml:"HostVirtualSwitchConfig,omitempty"` +} + +func init() { + t["ArrayOfHostVirtualSwitchConfig"] = reflect.TypeOf((*ArrayOfHostVirtualSwitchConfig)(nil)).Elem() +} + +type ArrayOfHostVmciAccessManagerAccessSpec struct { + HostVmciAccessManagerAccessSpec []HostVmciAccessManagerAccessSpec `xml:"HostVmciAccessManagerAccessSpec,omitempty"` +} + +func init() { + t["ArrayOfHostVmciAccessManagerAccessSpec"] = reflect.TypeOf((*ArrayOfHostVmciAccessManagerAccessSpec)(nil)).Elem() +} + +type ArrayOfHostVmfsRescanResult struct { + HostVmfsRescanResult []HostVmfsRescanResult `xml:"HostVmfsRescanResult,omitempty"` +} + +func init() { + t["ArrayOfHostVmfsRescanResult"] = reflect.TypeOf((*ArrayOfHostVmfsRescanResult)(nil)).Elem() +} + +type ArrayOfHostVsanInternalSystemCmmdsQuery struct { + HostVsanInternalSystemCmmdsQuery []HostVsanInternalSystemCmmdsQuery `xml:"HostVsanInternalSystemCmmdsQuery,omitempty"` +} + +func init() { + t["ArrayOfHostVsanInternalSystemCmmdsQuery"] = reflect.TypeOf((*ArrayOfHostVsanInternalSystemCmmdsQuery)(nil)).Elem() +} + +type ArrayOfHostVsanInternalSystemDeleteVsanObjectsResult struct { + HostVsanInternalSystemDeleteVsanObjectsResult []HostVsanInternalSystemDeleteVsanObjectsResult `xml:"HostVsanInternalSystemDeleteVsanObjectsResult,omitempty"` +} + +func init() { + t["ArrayOfHostVsanInternalSystemDeleteVsanObjectsResult"] = reflect.TypeOf((*ArrayOfHostVsanInternalSystemDeleteVsanObjectsResult)(nil)).Elem() +} + +type ArrayOfHostVsanInternalSystemVsanObjectOperationResult struct { + HostVsanInternalSystemVsanObjectOperationResult []HostVsanInternalSystemVsanObjectOperationResult `xml:"HostVsanInternalSystemVsanObjectOperationResult,omitempty"` +} + +func init() { + t["ArrayOfHostVsanInternalSystemVsanObjectOperationResult"] = reflect.TypeOf((*ArrayOfHostVsanInternalSystemVsanObjectOperationResult)(nil)).Elem() +} + +type ArrayOfHostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult struct { + HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult []HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult `xml:"HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult,omitempty"` +} + +func init() { + t["ArrayOfHostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult"] = reflect.TypeOf((*ArrayOfHostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult)(nil)).Elem() +} + +type ArrayOfHttpNfcLeaseDatastoreLeaseInfo struct { + HttpNfcLeaseDatastoreLeaseInfo []HttpNfcLeaseDatastoreLeaseInfo `xml:"HttpNfcLeaseDatastoreLeaseInfo,omitempty"` +} + +func init() { + t["ArrayOfHttpNfcLeaseDatastoreLeaseInfo"] = reflect.TypeOf((*ArrayOfHttpNfcLeaseDatastoreLeaseInfo)(nil)).Elem() +} + +type ArrayOfHttpNfcLeaseDeviceUrl struct { + HttpNfcLeaseDeviceUrl []HttpNfcLeaseDeviceUrl `xml:"HttpNfcLeaseDeviceUrl,omitempty"` +} + +func init() { + t["ArrayOfHttpNfcLeaseDeviceUrl"] = reflect.TypeOf((*ArrayOfHttpNfcLeaseDeviceUrl)(nil)).Elem() +} + +type ArrayOfHttpNfcLeaseHostInfo struct { + HttpNfcLeaseHostInfo []HttpNfcLeaseHostInfo `xml:"HttpNfcLeaseHostInfo,omitempty"` +} + +func init() { + t["ArrayOfHttpNfcLeaseHostInfo"] = reflect.TypeOf((*ArrayOfHttpNfcLeaseHostInfo)(nil)).Elem() +} + +type ArrayOfHttpNfcLeaseManifestEntry struct { + HttpNfcLeaseManifestEntry []HttpNfcLeaseManifestEntry `xml:"HttpNfcLeaseManifestEntry,omitempty"` +} + +func init() { + t["ArrayOfHttpNfcLeaseManifestEntry"] = reflect.TypeOf((*ArrayOfHttpNfcLeaseManifestEntry)(nil)).Elem() +} + +type ArrayOfImportOperationBulkFaultFaultOnImport struct { + ImportOperationBulkFaultFaultOnImport []ImportOperationBulkFaultFaultOnImport `xml:"ImportOperationBulkFaultFaultOnImport,omitempty"` +} + +func init() { + t["ArrayOfImportOperationBulkFaultFaultOnImport"] = reflect.TypeOf((*ArrayOfImportOperationBulkFaultFaultOnImport)(nil)).Elem() +} + +type ArrayOfImportSpec struct { + ImportSpec []BaseImportSpec `xml:"ImportSpec,omitempty,typeattr"` +} + +func init() { + t["ArrayOfImportSpec"] = reflect.TypeOf((*ArrayOfImportSpec)(nil)).Elem() +} + +type ArrayOfInt struct { + Int []int32 `xml:"int,omitempty"` +} + +func init() { + t["ArrayOfInt"] = reflect.TypeOf((*ArrayOfInt)(nil)).Elem() +} + +type ArrayOfIoFilterHostIssue struct { + IoFilterHostIssue []IoFilterHostIssue `xml:"IoFilterHostIssue,omitempty"` +} + +func init() { + t["ArrayOfIoFilterHostIssue"] = reflect.TypeOf((*ArrayOfIoFilterHostIssue)(nil)).Elem() +} + +type ArrayOfIpPool struct { + IpPool []IpPool `xml:"IpPool,omitempty"` +} + +func init() { + t["ArrayOfIpPool"] = reflect.TypeOf((*ArrayOfIpPool)(nil)).Elem() +} + +type ArrayOfIpPoolAssociation struct { + IpPoolAssociation []IpPoolAssociation `xml:"IpPoolAssociation,omitempty"` +} + +func init() { + t["ArrayOfIpPoolAssociation"] = reflect.TypeOf((*ArrayOfIpPoolAssociation)(nil)).Elem() +} + +type ArrayOfIpPoolManagerIpAllocation struct { + IpPoolManagerIpAllocation []IpPoolManagerIpAllocation `xml:"IpPoolManagerIpAllocation,omitempty"` +} + +func init() { + t["ArrayOfIpPoolManagerIpAllocation"] = reflect.TypeOf((*ArrayOfIpPoolManagerIpAllocation)(nil)).Elem() +} + +type ArrayOfIscsiDependencyEntity struct { + IscsiDependencyEntity []IscsiDependencyEntity `xml:"IscsiDependencyEntity,omitempty"` +} + +func init() { + t["ArrayOfIscsiDependencyEntity"] = reflect.TypeOf((*ArrayOfIscsiDependencyEntity)(nil)).Elem() +} + +type ArrayOfIscsiPortInfo struct { + IscsiPortInfo []IscsiPortInfo `xml:"IscsiPortInfo,omitempty"` +} + +func init() { + t["ArrayOfIscsiPortInfo"] = reflect.TypeOf((*ArrayOfIscsiPortInfo)(nil)).Elem() +} + +type ArrayOfKernelModuleInfo struct { + KernelModuleInfo []KernelModuleInfo `xml:"KernelModuleInfo,omitempty"` +} + +func init() { + t["ArrayOfKernelModuleInfo"] = reflect.TypeOf((*ArrayOfKernelModuleInfo)(nil)).Elem() +} + +type ArrayOfKeyAnyValue struct { + KeyAnyValue []KeyAnyValue `xml:"KeyAnyValue,omitempty"` +} + +func init() { + t["ArrayOfKeyAnyValue"] = reflect.TypeOf((*ArrayOfKeyAnyValue)(nil)).Elem() +} + +type ArrayOfKeyValue struct { + KeyValue []KeyValue `xml:"KeyValue,omitempty"` +} + +func init() { + t["ArrayOfKeyValue"] = reflect.TypeOf((*ArrayOfKeyValue)(nil)).Elem() +} + +type ArrayOfLicenseAssignmentManagerLicenseAssignment struct { + LicenseAssignmentManagerLicenseAssignment []LicenseAssignmentManagerLicenseAssignment `xml:"LicenseAssignmentManagerLicenseAssignment,omitempty"` +} + +func init() { + t["ArrayOfLicenseAssignmentManagerLicenseAssignment"] = reflect.TypeOf((*ArrayOfLicenseAssignmentManagerLicenseAssignment)(nil)).Elem() +} + +type ArrayOfLicenseAvailabilityInfo struct { + LicenseAvailabilityInfo []LicenseAvailabilityInfo `xml:"LicenseAvailabilityInfo,omitempty"` +} + +func init() { + t["ArrayOfLicenseAvailabilityInfo"] = reflect.TypeOf((*ArrayOfLicenseAvailabilityInfo)(nil)).Elem() +} + +type ArrayOfLicenseFeatureInfo struct { + LicenseFeatureInfo []LicenseFeatureInfo `xml:"LicenseFeatureInfo,omitempty"` +} + +func init() { + t["ArrayOfLicenseFeatureInfo"] = reflect.TypeOf((*ArrayOfLicenseFeatureInfo)(nil)).Elem() +} + +type ArrayOfLicenseManagerLicenseInfo struct { + LicenseManagerLicenseInfo []LicenseManagerLicenseInfo `xml:"LicenseManagerLicenseInfo,omitempty"` +} + +func init() { + t["ArrayOfLicenseManagerLicenseInfo"] = reflect.TypeOf((*ArrayOfLicenseManagerLicenseInfo)(nil)).Elem() +} + +type ArrayOfLicenseReservationInfo struct { + LicenseReservationInfo []LicenseReservationInfo `xml:"LicenseReservationInfo,omitempty"` +} + +func init() { + t["ArrayOfLicenseReservationInfo"] = reflect.TypeOf((*ArrayOfLicenseReservationInfo)(nil)).Elem() +} + +type ArrayOfLocalizableMessage struct { + LocalizableMessage []LocalizableMessage `xml:"LocalizableMessage,omitempty"` +} + +func init() { + t["ArrayOfLocalizableMessage"] = reflect.TypeOf((*ArrayOfLocalizableMessage)(nil)).Elem() +} + +type ArrayOfLocalizationManagerMessageCatalog struct { + LocalizationManagerMessageCatalog []LocalizationManagerMessageCatalog `xml:"LocalizationManagerMessageCatalog,omitempty"` +} + +func init() { + t["ArrayOfLocalizationManagerMessageCatalog"] = reflect.TypeOf((*ArrayOfLocalizationManagerMessageCatalog)(nil)).Elem() +} + +type ArrayOfLong struct { + Long []int64 `xml:"long,omitempty"` +} + +func init() { + t["ArrayOfLong"] = reflect.TypeOf((*ArrayOfLong)(nil)).Elem() +} + +type ArrayOfManagedObjectReference struct { + ManagedObjectReference []ManagedObjectReference `xml:"ManagedObjectReference,omitempty"` +} + +func init() { + t["ArrayOfManagedObjectReference"] = reflect.TypeOf((*ArrayOfManagedObjectReference)(nil)).Elem() +} + +type ArrayOfMethodActionArgument struct { + MethodActionArgument []MethodActionArgument `xml:"MethodActionArgument,omitempty"` +} + +func init() { + t["ArrayOfMethodActionArgument"] = reflect.TypeOf((*ArrayOfMethodActionArgument)(nil)).Elem() +} + +type ArrayOfMethodFault struct { + MethodFault []BaseMethodFault `xml:"MethodFault,omitempty,typeattr"` +} + +func init() { + t["ArrayOfMethodFault"] = reflect.TypeOf((*ArrayOfMethodFault)(nil)).Elem() +} + +type ArrayOfMissingObject struct { + MissingObject []MissingObject `xml:"MissingObject,omitempty"` +} + +func init() { + t["ArrayOfMissingObject"] = reflect.TypeOf((*ArrayOfMissingObject)(nil)).Elem() +} + +type ArrayOfMissingProperty struct { + MissingProperty []MissingProperty `xml:"MissingProperty,omitempty"` +} + +func init() { + t["ArrayOfMissingProperty"] = reflect.TypeOf((*ArrayOfMissingProperty)(nil)).Elem() +} + +type ArrayOfMultipleCertificatesVerifyFaultThumbprintData struct { + MultipleCertificatesVerifyFaultThumbprintData []MultipleCertificatesVerifyFaultThumbprintData `xml:"MultipleCertificatesVerifyFaultThumbprintData,omitempty"` +} + +func init() { + t["ArrayOfMultipleCertificatesVerifyFaultThumbprintData"] = reflect.TypeOf((*ArrayOfMultipleCertificatesVerifyFaultThumbprintData)(nil)).Elem() +} + +type ArrayOfNasStorageProfile struct { + NasStorageProfile []NasStorageProfile `xml:"NasStorageProfile,omitempty"` +} + +func init() { + t["ArrayOfNasStorageProfile"] = reflect.TypeOf((*ArrayOfNasStorageProfile)(nil)).Elem() +} + +type ArrayOfNetIpConfigInfoIpAddress struct { + NetIpConfigInfoIpAddress []NetIpConfigInfoIpAddress `xml:"NetIpConfigInfoIpAddress,omitempty"` +} + +func init() { + t["ArrayOfNetIpConfigInfoIpAddress"] = reflect.TypeOf((*ArrayOfNetIpConfigInfoIpAddress)(nil)).Elem() +} + +type ArrayOfNetIpConfigSpecIpAddressSpec struct { + NetIpConfigSpecIpAddressSpec []NetIpConfigSpecIpAddressSpec `xml:"NetIpConfigSpecIpAddressSpec,omitempty"` +} + +func init() { + t["ArrayOfNetIpConfigSpecIpAddressSpec"] = reflect.TypeOf((*ArrayOfNetIpConfigSpecIpAddressSpec)(nil)).Elem() +} + +type ArrayOfNetIpRouteConfigInfoIpRoute struct { + NetIpRouteConfigInfoIpRoute []NetIpRouteConfigInfoIpRoute `xml:"NetIpRouteConfigInfoIpRoute,omitempty"` +} + +func init() { + t["ArrayOfNetIpRouteConfigInfoIpRoute"] = reflect.TypeOf((*ArrayOfNetIpRouteConfigInfoIpRoute)(nil)).Elem() +} + +type ArrayOfNetIpRouteConfigSpecIpRouteSpec struct { + NetIpRouteConfigSpecIpRouteSpec []NetIpRouteConfigSpecIpRouteSpec `xml:"NetIpRouteConfigSpecIpRouteSpec,omitempty"` +} + +func init() { + t["ArrayOfNetIpRouteConfigSpecIpRouteSpec"] = reflect.TypeOf((*ArrayOfNetIpRouteConfigSpecIpRouteSpec)(nil)).Elem() +} + +type ArrayOfNetIpStackInfoDefaultRouter struct { + NetIpStackInfoDefaultRouter []NetIpStackInfoDefaultRouter `xml:"NetIpStackInfoDefaultRouter,omitempty"` +} + +func init() { + t["ArrayOfNetIpStackInfoDefaultRouter"] = reflect.TypeOf((*ArrayOfNetIpStackInfoDefaultRouter)(nil)).Elem() +} + +type ArrayOfNetIpStackInfoNetToMedia struct { + NetIpStackInfoNetToMedia []NetIpStackInfoNetToMedia `xml:"NetIpStackInfoNetToMedia,omitempty"` +} + +func init() { + t["ArrayOfNetIpStackInfoNetToMedia"] = reflect.TypeOf((*ArrayOfNetIpStackInfoNetToMedia)(nil)).Elem() +} + +type ArrayOfNetStackInstanceProfile struct { + NetStackInstanceProfile []NetStackInstanceProfile `xml:"NetStackInstanceProfile,omitempty"` +} + +func init() { + t["ArrayOfNetStackInstanceProfile"] = reflect.TypeOf((*ArrayOfNetStackInstanceProfile)(nil)).Elem() +} + +type ArrayOfNumericRange struct { + NumericRange []NumericRange `xml:"NumericRange,omitempty"` +} + +func init() { + t["ArrayOfNumericRange"] = reflect.TypeOf((*ArrayOfNumericRange)(nil)).Elem() +} + +type ArrayOfObjectContent struct { + ObjectContent []ObjectContent `xml:"ObjectContent,omitempty"` +} + +func init() { + t["ArrayOfObjectContent"] = reflect.TypeOf((*ArrayOfObjectContent)(nil)).Elem() +} + +type ArrayOfObjectSpec struct { + ObjectSpec []ObjectSpec `xml:"ObjectSpec,omitempty"` +} + +func init() { + t["ArrayOfObjectSpec"] = reflect.TypeOf((*ArrayOfObjectSpec)(nil)).Elem() +} + +type ArrayOfObjectUpdate struct { + ObjectUpdate []ObjectUpdate `xml:"ObjectUpdate,omitempty"` +} + +func init() { + t["ArrayOfObjectUpdate"] = reflect.TypeOf((*ArrayOfObjectUpdate)(nil)).Elem() +} + +type ArrayOfOpaqueNetworkTargetInfo struct { + OpaqueNetworkTargetInfo []OpaqueNetworkTargetInfo `xml:"OpaqueNetworkTargetInfo,omitempty"` +} + +func init() { + t["ArrayOfOpaqueNetworkTargetInfo"] = reflect.TypeOf((*ArrayOfOpaqueNetworkTargetInfo)(nil)).Elem() +} + +type ArrayOfOptionDef struct { + OptionDef []OptionDef `xml:"OptionDef,omitempty"` +} + +func init() { + t["ArrayOfOptionDef"] = reflect.TypeOf((*ArrayOfOptionDef)(nil)).Elem() +} + +type ArrayOfOptionProfile struct { + OptionProfile []OptionProfile `xml:"OptionProfile,omitempty"` +} + +func init() { + t["ArrayOfOptionProfile"] = reflect.TypeOf((*ArrayOfOptionProfile)(nil)).Elem() +} + +type ArrayOfOptionValue struct { + OptionValue []BaseOptionValue `xml:"OptionValue,omitempty,typeattr"` +} + +func init() { + t["ArrayOfOptionValue"] = reflect.TypeOf((*ArrayOfOptionValue)(nil)).Elem() +} + +type ArrayOfOvfConsumerOstNode struct { + OvfConsumerOstNode []OvfConsumerOstNode `xml:"OvfConsumerOstNode,omitempty"` +} + +func init() { + t["ArrayOfOvfConsumerOstNode"] = reflect.TypeOf((*ArrayOfOvfConsumerOstNode)(nil)).Elem() +} + +type ArrayOfOvfConsumerOvfSection struct { + OvfConsumerOvfSection []OvfConsumerOvfSection `xml:"OvfConsumerOvfSection,omitempty"` +} + +func init() { + t["ArrayOfOvfConsumerOvfSection"] = reflect.TypeOf((*ArrayOfOvfConsumerOvfSection)(nil)).Elem() +} + +type ArrayOfOvfDeploymentOption struct { + OvfDeploymentOption []OvfDeploymentOption `xml:"OvfDeploymentOption,omitempty"` +} + +func init() { + t["ArrayOfOvfDeploymentOption"] = reflect.TypeOf((*ArrayOfOvfDeploymentOption)(nil)).Elem() +} + +type ArrayOfOvfFile struct { + OvfFile []OvfFile `xml:"OvfFile,omitempty"` +} + +func init() { + t["ArrayOfOvfFile"] = reflect.TypeOf((*ArrayOfOvfFile)(nil)).Elem() +} + +type ArrayOfOvfFileItem struct { + OvfFileItem []OvfFileItem `xml:"OvfFileItem,omitempty"` +} + +func init() { + t["ArrayOfOvfFileItem"] = reflect.TypeOf((*ArrayOfOvfFileItem)(nil)).Elem() +} + +type ArrayOfOvfNetworkInfo struct { + OvfNetworkInfo []OvfNetworkInfo `xml:"OvfNetworkInfo,omitempty"` +} + +func init() { + t["ArrayOfOvfNetworkInfo"] = reflect.TypeOf((*ArrayOfOvfNetworkInfo)(nil)).Elem() +} + +type ArrayOfOvfNetworkMapping struct { + OvfNetworkMapping []OvfNetworkMapping `xml:"OvfNetworkMapping,omitempty"` +} + +func init() { + t["ArrayOfOvfNetworkMapping"] = reflect.TypeOf((*ArrayOfOvfNetworkMapping)(nil)).Elem() +} + +type ArrayOfOvfOptionInfo struct { + OvfOptionInfo []OvfOptionInfo `xml:"OvfOptionInfo,omitempty"` +} + +func init() { + t["ArrayOfOvfOptionInfo"] = reflect.TypeOf((*ArrayOfOvfOptionInfo)(nil)).Elem() +} + +type ArrayOfOvfResourceMap struct { + OvfResourceMap []OvfResourceMap `xml:"OvfResourceMap,omitempty"` +} + +func init() { + t["ArrayOfOvfResourceMap"] = reflect.TypeOf((*ArrayOfOvfResourceMap)(nil)).Elem() +} + +type ArrayOfPerfCounterInfo struct { + PerfCounterInfo []PerfCounterInfo `xml:"PerfCounterInfo,omitempty"` +} + +func init() { + t["ArrayOfPerfCounterInfo"] = reflect.TypeOf((*ArrayOfPerfCounterInfo)(nil)).Elem() +} + +type ArrayOfPerfEntityMetricBase struct { + PerfEntityMetricBase []BasePerfEntityMetricBase `xml:"PerfEntityMetricBase,omitempty,typeattr"` +} + +func init() { + t["ArrayOfPerfEntityMetricBase"] = reflect.TypeOf((*ArrayOfPerfEntityMetricBase)(nil)).Elem() +} + +type ArrayOfPerfInterval struct { + PerfInterval []PerfInterval `xml:"PerfInterval,omitempty"` +} + +func init() { + t["ArrayOfPerfInterval"] = reflect.TypeOf((*ArrayOfPerfInterval)(nil)).Elem() +} + +type ArrayOfPerfMetricId struct { + PerfMetricId []PerfMetricId `xml:"PerfMetricId,omitempty"` +} + +func init() { + t["ArrayOfPerfMetricId"] = reflect.TypeOf((*ArrayOfPerfMetricId)(nil)).Elem() +} + +type ArrayOfPerfMetricSeries struct { + PerfMetricSeries []BasePerfMetricSeries `xml:"PerfMetricSeries,omitempty,typeattr"` +} + +func init() { + t["ArrayOfPerfMetricSeries"] = reflect.TypeOf((*ArrayOfPerfMetricSeries)(nil)).Elem() +} + +type ArrayOfPerfMetricSeriesCSV struct { + PerfMetricSeriesCSV []PerfMetricSeriesCSV `xml:"PerfMetricSeriesCSV,omitempty"` +} + +func init() { + t["ArrayOfPerfMetricSeriesCSV"] = reflect.TypeOf((*ArrayOfPerfMetricSeriesCSV)(nil)).Elem() +} + +type ArrayOfPerfQuerySpec struct { + PerfQuerySpec []PerfQuerySpec `xml:"PerfQuerySpec,omitempty"` +} + +func init() { + t["ArrayOfPerfQuerySpec"] = reflect.TypeOf((*ArrayOfPerfQuerySpec)(nil)).Elem() +} + +type ArrayOfPerfSampleInfo struct { + PerfSampleInfo []PerfSampleInfo `xml:"PerfSampleInfo,omitempty"` +} + +func init() { + t["ArrayOfPerfSampleInfo"] = reflect.TypeOf((*ArrayOfPerfSampleInfo)(nil)).Elem() +} + +type ArrayOfPerformanceManagerCounterLevelMapping struct { + PerformanceManagerCounterLevelMapping []PerformanceManagerCounterLevelMapping `xml:"PerformanceManagerCounterLevelMapping,omitempty"` +} + +func init() { + t["ArrayOfPerformanceManagerCounterLevelMapping"] = reflect.TypeOf((*ArrayOfPerformanceManagerCounterLevelMapping)(nil)).Elem() +} + +type ArrayOfPermission struct { + Permission []Permission `xml:"Permission,omitempty"` +} + +func init() { + t["ArrayOfPermission"] = reflect.TypeOf((*ArrayOfPermission)(nil)).Elem() +} + +type ArrayOfPermissionProfile struct { + PermissionProfile []PermissionProfile `xml:"PermissionProfile,omitempty"` +} + +func init() { + t["ArrayOfPermissionProfile"] = reflect.TypeOf((*ArrayOfPermissionProfile)(nil)).Elem() +} + +type ArrayOfPhysicalNic struct { + PhysicalNic []PhysicalNic `xml:"PhysicalNic,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNic"] = reflect.TypeOf((*ArrayOfPhysicalNic)(nil)).Elem() +} + +type ArrayOfPhysicalNicConfig struct { + PhysicalNicConfig []PhysicalNicConfig `xml:"PhysicalNicConfig,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNicConfig"] = reflect.TypeOf((*ArrayOfPhysicalNicConfig)(nil)).Elem() +} + +type ArrayOfPhysicalNicHintInfo struct { + PhysicalNicHintInfo []PhysicalNicHintInfo `xml:"PhysicalNicHintInfo,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNicHintInfo"] = reflect.TypeOf((*ArrayOfPhysicalNicHintInfo)(nil)).Elem() +} + +type ArrayOfPhysicalNicIpHint struct { + PhysicalNicIpHint []PhysicalNicIpHint `xml:"PhysicalNicIpHint,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNicIpHint"] = reflect.TypeOf((*ArrayOfPhysicalNicIpHint)(nil)).Elem() +} + +type ArrayOfPhysicalNicLinkInfo struct { + PhysicalNicLinkInfo []PhysicalNicLinkInfo `xml:"PhysicalNicLinkInfo,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNicLinkInfo"] = reflect.TypeOf((*ArrayOfPhysicalNicLinkInfo)(nil)).Elem() +} + +type ArrayOfPhysicalNicNameHint struct { + PhysicalNicNameHint []PhysicalNicNameHint `xml:"PhysicalNicNameHint,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNicNameHint"] = reflect.TypeOf((*ArrayOfPhysicalNicNameHint)(nil)).Elem() +} + +type ArrayOfPhysicalNicProfile struct { + PhysicalNicProfile []PhysicalNicProfile `xml:"PhysicalNicProfile,omitempty"` +} + +func init() { + t["ArrayOfPhysicalNicProfile"] = reflect.TypeOf((*ArrayOfPhysicalNicProfile)(nil)).Elem() +} + +type ArrayOfPlacementAffinityRule struct { + PlacementAffinityRule []PlacementAffinityRule `xml:"PlacementAffinityRule,omitempty"` +} + +func init() { + t["ArrayOfPlacementAffinityRule"] = reflect.TypeOf((*ArrayOfPlacementAffinityRule)(nil)).Elem() +} + +type ArrayOfPlacementSpec struct { + PlacementSpec []PlacementSpec `xml:"PlacementSpec,omitempty"` +} + +func init() { + t["ArrayOfPlacementSpec"] = reflect.TypeOf((*ArrayOfPlacementSpec)(nil)).Elem() +} + +type ArrayOfPnicUplinkProfile struct { + PnicUplinkProfile []PnicUplinkProfile `xml:"PnicUplinkProfile,omitempty"` +} + +func init() { + t["ArrayOfPnicUplinkProfile"] = reflect.TypeOf((*ArrayOfPnicUplinkProfile)(nil)).Elem() +} + +type ArrayOfPodDiskLocator struct { + PodDiskLocator []PodDiskLocator `xml:"PodDiskLocator,omitempty"` +} + +func init() { + t["ArrayOfPodDiskLocator"] = reflect.TypeOf((*ArrayOfPodDiskLocator)(nil)).Elem() +} + +type ArrayOfPolicyOption struct { + PolicyOption []BasePolicyOption `xml:"PolicyOption,omitempty,typeattr"` +} + +func init() { + t["ArrayOfPolicyOption"] = reflect.TypeOf((*ArrayOfPolicyOption)(nil)).Elem() +} + +type ArrayOfPrivilegeAvailability struct { + PrivilegeAvailability []PrivilegeAvailability `xml:"PrivilegeAvailability,omitempty"` +} + +func init() { + t["ArrayOfPrivilegeAvailability"] = reflect.TypeOf((*ArrayOfPrivilegeAvailability)(nil)).Elem() +} + +type ArrayOfProductComponentInfo struct { + ProductComponentInfo []ProductComponentInfo `xml:"ProductComponentInfo,omitempty"` +} + +func init() { + t["ArrayOfProductComponentInfo"] = reflect.TypeOf((*ArrayOfProductComponentInfo)(nil)).Elem() +} + +type ArrayOfProfileApplyProfileProperty struct { + ProfileApplyProfileProperty []ProfileApplyProfileProperty `xml:"ProfileApplyProfileProperty,omitempty"` +} + +func init() { + t["ArrayOfProfileApplyProfileProperty"] = reflect.TypeOf((*ArrayOfProfileApplyProfileProperty)(nil)).Elem() +} + +type ArrayOfProfileDeferredPolicyOptionParameter struct { + ProfileDeferredPolicyOptionParameter []ProfileDeferredPolicyOptionParameter `xml:"ProfileDeferredPolicyOptionParameter,omitempty"` +} + +func init() { + t["ArrayOfProfileDeferredPolicyOptionParameter"] = reflect.TypeOf((*ArrayOfProfileDeferredPolicyOptionParameter)(nil)).Elem() +} + +type ArrayOfProfileDescriptionSection struct { + ProfileDescriptionSection []ProfileDescriptionSection `xml:"ProfileDescriptionSection,omitempty"` +} + +func init() { + t["ArrayOfProfileDescriptionSection"] = reflect.TypeOf((*ArrayOfProfileDescriptionSection)(nil)).Elem() +} + +type ArrayOfProfileExecuteError struct { + ProfileExecuteError []ProfileExecuteError `xml:"ProfileExecuteError,omitempty"` +} + +func init() { + t["ArrayOfProfileExecuteError"] = reflect.TypeOf((*ArrayOfProfileExecuteError)(nil)).Elem() +} + +type ArrayOfProfileExpression struct { + ProfileExpression []BaseProfileExpression `xml:"ProfileExpression,omitempty,typeattr"` +} + +func init() { + t["ArrayOfProfileExpression"] = reflect.TypeOf((*ArrayOfProfileExpression)(nil)).Elem() +} + +type ArrayOfProfileExpressionMetadata struct { + ProfileExpressionMetadata []ProfileExpressionMetadata `xml:"ProfileExpressionMetadata,omitempty"` +} + +func init() { + t["ArrayOfProfileExpressionMetadata"] = reflect.TypeOf((*ArrayOfProfileExpressionMetadata)(nil)).Elem() +} + +type ArrayOfProfileMetadata struct { + ProfileMetadata []ProfileMetadata `xml:"ProfileMetadata,omitempty"` +} + +func init() { + t["ArrayOfProfileMetadata"] = reflect.TypeOf((*ArrayOfProfileMetadata)(nil)).Elem() +} + +type ArrayOfProfileMetadataProfileSortSpec struct { + ProfileMetadataProfileSortSpec []ProfileMetadataProfileSortSpec `xml:"ProfileMetadataProfileSortSpec,omitempty"` +} + +func init() { + t["ArrayOfProfileMetadataProfileSortSpec"] = reflect.TypeOf((*ArrayOfProfileMetadataProfileSortSpec)(nil)).Elem() +} + +type ArrayOfProfileParameterMetadata struct { + ProfileParameterMetadata []ProfileParameterMetadata `xml:"ProfileParameterMetadata,omitempty"` +} + +func init() { + t["ArrayOfProfileParameterMetadata"] = reflect.TypeOf((*ArrayOfProfileParameterMetadata)(nil)).Elem() +} + +type ArrayOfProfilePolicy struct { + ProfilePolicy []ProfilePolicy `xml:"ProfilePolicy,omitempty"` +} + +func init() { + t["ArrayOfProfilePolicy"] = reflect.TypeOf((*ArrayOfProfilePolicy)(nil)).Elem() +} + +type ArrayOfProfilePolicyMetadata struct { + ProfilePolicyMetadata []ProfilePolicyMetadata `xml:"ProfilePolicyMetadata,omitempty"` +} + +func init() { + t["ArrayOfProfilePolicyMetadata"] = reflect.TypeOf((*ArrayOfProfilePolicyMetadata)(nil)).Elem() +} + +type ArrayOfProfilePolicyOptionMetadata struct { + ProfilePolicyOptionMetadata []BaseProfilePolicyOptionMetadata `xml:"ProfilePolicyOptionMetadata,omitempty,typeattr"` +} + +func init() { + t["ArrayOfProfilePolicyOptionMetadata"] = reflect.TypeOf((*ArrayOfProfilePolicyOptionMetadata)(nil)).Elem() +} + +type ArrayOfProfileProfileStructureProperty struct { + ProfileProfileStructureProperty []ProfileProfileStructureProperty `xml:"ProfileProfileStructureProperty,omitempty"` +} + +func init() { + t["ArrayOfProfileProfileStructureProperty"] = reflect.TypeOf((*ArrayOfProfileProfileStructureProperty)(nil)).Elem() +} + +type ArrayOfProfilePropertyPath struct { + ProfilePropertyPath []ProfilePropertyPath `xml:"ProfilePropertyPath,omitempty"` +} + +func init() { + t["ArrayOfProfilePropertyPath"] = reflect.TypeOf((*ArrayOfProfilePropertyPath)(nil)).Elem() +} + +type ArrayOfProfileUpdateFailedUpdateFailure struct { + ProfileUpdateFailedUpdateFailure []ProfileUpdateFailedUpdateFailure `xml:"ProfileUpdateFailedUpdateFailure,omitempty"` +} + +func init() { + t["ArrayOfProfileUpdateFailedUpdateFailure"] = reflect.TypeOf((*ArrayOfProfileUpdateFailedUpdateFailure)(nil)).Elem() +} + +type ArrayOfPropertyChange struct { + PropertyChange []PropertyChange `xml:"PropertyChange,omitempty"` +} + +func init() { + t["ArrayOfPropertyChange"] = reflect.TypeOf((*ArrayOfPropertyChange)(nil)).Elem() +} + +type ArrayOfPropertyFilterSpec struct { + PropertyFilterSpec []PropertyFilterSpec `xml:"PropertyFilterSpec,omitempty"` +} + +func init() { + t["ArrayOfPropertyFilterSpec"] = reflect.TypeOf((*ArrayOfPropertyFilterSpec)(nil)).Elem() +} + +type ArrayOfPropertyFilterUpdate struct { + PropertyFilterUpdate []PropertyFilterUpdate `xml:"PropertyFilterUpdate,omitempty"` +} + +func init() { + t["ArrayOfPropertyFilterUpdate"] = reflect.TypeOf((*ArrayOfPropertyFilterUpdate)(nil)).Elem() +} + +type ArrayOfPropertySpec struct { + PropertySpec []PropertySpec `xml:"PropertySpec,omitempty"` +} + +func init() { + t["ArrayOfPropertySpec"] = reflect.TypeOf((*ArrayOfPropertySpec)(nil)).Elem() +} + +type ArrayOfReplicationInfoDiskSettings struct { + ReplicationInfoDiskSettings []ReplicationInfoDiskSettings `xml:"ReplicationInfoDiskSettings,omitempty"` +} + +func init() { + t["ArrayOfReplicationInfoDiskSettings"] = reflect.TypeOf((*ArrayOfReplicationInfoDiskSettings)(nil)).Elem() +} + +type ArrayOfResourceConfigSpec struct { + ResourceConfigSpec []ResourceConfigSpec `xml:"ResourceConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfResourceConfigSpec"] = reflect.TypeOf((*ArrayOfResourceConfigSpec)(nil)).Elem() +} + +type ArrayOfScheduledTaskDetail struct { + ScheduledTaskDetail []ScheduledTaskDetail `xml:"ScheduledTaskDetail,omitempty"` +} + +func init() { + t["ArrayOfScheduledTaskDetail"] = reflect.TypeOf((*ArrayOfScheduledTaskDetail)(nil)).Elem() +} + +type ArrayOfScsiLun struct { + ScsiLun []BaseScsiLun `xml:"ScsiLun,omitempty,typeattr"` +} + +func init() { + t["ArrayOfScsiLun"] = reflect.TypeOf((*ArrayOfScsiLun)(nil)).Elem() +} + +type ArrayOfScsiLunDescriptor struct { + ScsiLunDescriptor []ScsiLunDescriptor `xml:"ScsiLunDescriptor,omitempty"` +} + +func init() { + t["ArrayOfScsiLunDescriptor"] = reflect.TypeOf((*ArrayOfScsiLunDescriptor)(nil)).Elem() +} + +type ArrayOfScsiLunDurableName struct { + ScsiLunDurableName []ScsiLunDurableName `xml:"ScsiLunDurableName,omitempty"` +} + +func init() { + t["ArrayOfScsiLunDurableName"] = reflect.TypeOf((*ArrayOfScsiLunDurableName)(nil)).Elem() +} + +type ArrayOfSelectionSet struct { + SelectionSet []BaseSelectionSet `xml:"SelectionSet,omitempty,typeattr"` +} + +func init() { + t["ArrayOfSelectionSet"] = reflect.TypeOf((*ArrayOfSelectionSet)(nil)).Elem() +} + +type ArrayOfSelectionSpec struct { + SelectionSpec []BaseSelectionSpec `xml:"SelectionSpec,omitempty,typeattr"` +} + +func init() { + t["ArrayOfSelectionSpec"] = reflect.TypeOf((*ArrayOfSelectionSpec)(nil)).Elem() +} + +type ArrayOfServiceConsolePortGroupProfile struct { + ServiceConsolePortGroupProfile []ServiceConsolePortGroupProfile `xml:"ServiceConsolePortGroupProfile,omitempty"` +} + +func init() { + t["ArrayOfServiceConsolePortGroupProfile"] = reflect.TypeOf((*ArrayOfServiceConsolePortGroupProfile)(nil)).Elem() +} + +type ArrayOfServiceLocator struct { + ServiceLocator []ServiceLocator `xml:"ServiceLocator,omitempty"` +} + +func init() { + t["ArrayOfServiceLocator"] = reflect.TypeOf((*ArrayOfServiceLocator)(nil)).Elem() +} + +type ArrayOfServiceManagerServiceInfo struct { + ServiceManagerServiceInfo []ServiceManagerServiceInfo `xml:"ServiceManagerServiceInfo,omitempty"` +} + +func init() { + t["ArrayOfServiceManagerServiceInfo"] = reflect.TypeOf((*ArrayOfServiceManagerServiceInfo)(nil)).Elem() +} + +type ArrayOfServiceProfile struct { + ServiceProfile []ServiceProfile `xml:"ServiceProfile,omitempty"` +} + +func init() { + t["ArrayOfServiceProfile"] = reflect.TypeOf((*ArrayOfServiceProfile)(nil)).Elem() +} + +type ArrayOfShort struct { + Short []int16 `xml:"short,omitempty"` +} + +func init() { + t["ArrayOfShort"] = reflect.TypeOf((*ArrayOfShort)(nil)).Elem() +} + +type ArrayOfStaticRouteProfile struct { + StaticRouteProfile []StaticRouteProfile `xml:"StaticRouteProfile,omitempty"` +} + +func init() { + t["ArrayOfStaticRouteProfile"] = reflect.TypeOf((*ArrayOfStaticRouteProfile)(nil)).Elem() +} + +type ArrayOfStorageDrsOptionSpec struct { + StorageDrsOptionSpec []StorageDrsOptionSpec `xml:"StorageDrsOptionSpec,omitempty"` +} + +func init() { + t["ArrayOfStorageDrsOptionSpec"] = reflect.TypeOf((*ArrayOfStorageDrsOptionSpec)(nil)).Elem() +} + +type ArrayOfStorageDrsPlacementRankVmSpec struct { + StorageDrsPlacementRankVmSpec []StorageDrsPlacementRankVmSpec `xml:"StorageDrsPlacementRankVmSpec,omitempty"` +} + +func init() { + t["ArrayOfStorageDrsPlacementRankVmSpec"] = reflect.TypeOf((*ArrayOfStorageDrsPlacementRankVmSpec)(nil)).Elem() +} + +type ArrayOfStorageDrsVmConfigInfo struct { + StorageDrsVmConfigInfo []StorageDrsVmConfigInfo `xml:"StorageDrsVmConfigInfo,omitempty"` +} + +func init() { + t["ArrayOfStorageDrsVmConfigInfo"] = reflect.TypeOf((*ArrayOfStorageDrsVmConfigInfo)(nil)).Elem() +} + +type ArrayOfStorageDrsVmConfigSpec struct { + StorageDrsVmConfigSpec []StorageDrsVmConfigSpec `xml:"StorageDrsVmConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfStorageDrsVmConfigSpec"] = reflect.TypeOf((*ArrayOfStorageDrsVmConfigSpec)(nil)).Elem() +} + +type ArrayOfStoragePerformanceSummary struct { + StoragePerformanceSummary []StoragePerformanceSummary `xml:"StoragePerformanceSummary,omitempty"` +} + +func init() { + t["ArrayOfStoragePerformanceSummary"] = reflect.TypeOf((*ArrayOfStoragePerformanceSummary)(nil)).Elem() +} + +type ArrayOfStorageRequirement struct { + StorageRequirement []StorageRequirement `xml:"StorageRequirement,omitempty"` +} + +func init() { + t["ArrayOfStorageRequirement"] = reflect.TypeOf((*ArrayOfStorageRequirement)(nil)).Elem() +} + +type ArrayOfString struct { + String []string `xml:"string,omitempty"` +} + +func init() { + t["ArrayOfString"] = reflect.TypeOf((*ArrayOfString)(nil)).Elem() +} + +type ArrayOfTag struct { + Tag []Tag `xml:"Tag,omitempty"` +} + +func init() { + t["ArrayOfTag"] = reflect.TypeOf((*ArrayOfTag)(nil)).Elem() +} + +type ArrayOfTaskInfo struct { + TaskInfo []TaskInfo `xml:"TaskInfo,omitempty"` +} + +func init() { + t["ArrayOfTaskInfo"] = reflect.TypeOf((*ArrayOfTaskInfo)(nil)).Elem() +} + +type ArrayOfTaskInfoState struct { + TaskInfoState []TaskInfoState `xml:"TaskInfoState,omitempty"` +} + +func init() { + t["ArrayOfTaskInfoState"] = reflect.TypeOf((*ArrayOfTaskInfoState)(nil)).Elem() +} + +type ArrayOfTypeDescription struct { + TypeDescription []BaseTypeDescription `xml:"TypeDescription,omitempty,typeattr"` +} + +func init() { + t["ArrayOfTypeDescription"] = reflect.TypeOf((*ArrayOfTypeDescription)(nil)).Elem() +} + +type ArrayOfUpdateVirtualMachineFilesResultFailedVmFileInfo struct { + UpdateVirtualMachineFilesResultFailedVmFileInfo []UpdateVirtualMachineFilesResultFailedVmFileInfo `xml:"UpdateVirtualMachineFilesResultFailedVmFileInfo,omitempty"` +} + +func init() { + t["ArrayOfUpdateVirtualMachineFilesResultFailedVmFileInfo"] = reflect.TypeOf((*ArrayOfUpdateVirtualMachineFilesResultFailedVmFileInfo)(nil)).Elem() +} + +type ArrayOfUserGroupProfile struct { + UserGroupProfile []UserGroupProfile `xml:"UserGroupProfile,omitempty"` +} + +func init() { + t["ArrayOfUserGroupProfile"] = reflect.TypeOf((*ArrayOfUserGroupProfile)(nil)).Elem() +} + +type ArrayOfUserProfile struct { + UserProfile []UserProfile `xml:"UserProfile,omitempty"` +} + +func init() { + t["ArrayOfUserProfile"] = reflect.TypeOf((*ArrayOfUserProfile)(nil)).Elem() +} + +type ArrayOfUserSearchResult struct { + UserSearchResult []BaseUserSearchResult `xml:"UserSearchResult,omitempty,typeattr"` +} + +func init() { + t["ArrayOfUserSearchResult"] = reflect.TypeOf((*ArrayOfUserSearchResult)(nil)).Elem() +} + +type ArrayOfUserSession struct { + UserSession []UserSession `xml:"UserSession,omitempty"` +} + +func init() { + t["ArrayOfUserSession"] = reflect.TypeOf((*ArrayOfUserSession)(nil)).Elem() +} + +type ArrayOfVASAStorageArray struct { + VASAStorageArray []VASAStorageArray `xml:"VASAStorageArray,omitempty"` +} + +func init() { + t["ArrayOfVASAStorageArray"] = reflect.TypeOf((*ArrayOfVASAStorageArray)(nil)).Elem() +} + +type ArrayOfVAppCloneSpecNetworkMappingPair struct { + VAppCloneSpecNetworkMappingPair []VAppCloneSpecNetworkMappingPair `xml:"VAppCloneSpecNetworkMappingPair,omitempty"` +} + +func init() { + t["ArrayOfVAppCloneSpecNetworkMappingPair"] = reflect.TypeOf((*ArrayOfVAppCloneSpecNetworkMappingPair)(nil)).Elem() +} + +type ArrayOfVAppCloneSpecResourceMap struct { + VAppCloneSpecResourceMap []VAppCloneSpecResourceMap `xml:"VAppCloneSpecResourceMap,omitempty"` +} + +func init() { + t["ArrayOfVAppCloneSpecResourceMap"] = reflect.TypeOf((*ArrayOfVAppCloneSpecResourceMap)(nil)).Elem() +} + +type ArrayOfVAppEntityConfigInfo struct { + VAppEntityConfigInfo []VAppEntityConfigInfo `xml:"VAppEntityConfigInfo,omitempty"` +} + +func init() { + t["ArrayOfVAppEntityConfigInfo"] = reflect.TypeOf((*ArrayOfVAppEntityConfigInfo)(nil)).Elem() +} + +type ArrayOfVAppOvfSectionInfo struct { + VAppOvfSectionInfo []VAppOvfSectionInfo `xml:"VAppOvfSectionInfo,omitempty"` +} + +func init() { + t["ArrayOfVAppOvfSectionInfo"] = reflect.TypeOf((*ArrayOfVAppOvfSectionInfo)(nil)).Elem() +} + +type ArrayOfVAppOvfSectionSpec struct { + VAppOvfSectionSpec []VAppOvfSectionSpec `xml:"VAppOvfSectionSpec,omitempty"` +} + +func init() { + t["ArrayOfVAppOvfSectionSpec"] = reflect.TypeOf((*ArrayOfVAppOvfSectionSpec)(nil)).Elem() +} + +type ArrayOfVAppProductInfo struct { + VAppProductInfo []VAppProductInfo `xml:"VAppProductInfo,omitempty"` +} + +func init() { + t["ArrayOfVAppProductInfo"] = reflect.TypeOf((*ArrayOfVAppProductInfo)(nil)).Elem() +} + +type ArrayOfVAppProductSpec struct { + VAppProductSpec []VAppProductSpec `xml:"VAppProductSpec,omitempty"` +} + +func init() { + t["ArrayOfVAppProductSpec"] = reflect.TypeOf((*ArrayOfVAppProductSpec)(nil)).Elem() +} + +type ArrayOfVAppPropertyInfo struct { + VAppPropertyInfo []VAppPropertyInfo `xml:"VAppPropertyInfo,omitempty"` +} + +func init() { + t["ArrayOfVAppPropertyInfo"] = reflect.TypeOf((*ArrayOfVAppPropertyInfo)(nil)).Elem() +} + +type ArrayOfVAppPropertySpec struct { + VAppPropertySpec []VAppPropertySpec `xml:"VAppPropertySpec,omitempty"` +} + +func init() { + t["ArrayOfVAppPropertySpec"] = reflect.TypeOf((*ArrayOfVAppPropertySpec)(nil)).Elem() +} + +type ArrayOfVMwareDVSPvlanConfigSpec struct { + VMwareDVSPvlanConfigSpec []VMwareDVSPvlanConfigSpec `xml:"VMwareDVSPvlanConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfVMwareDVSPvlanConfigSpec"] = reflect.TypeOf((*ArrayOfVMwareDVSPvlanConfigSpec)(nil)).Elem() +} + +type ArrayOfVMwareDVSPvlanMapEntry struct { + VMwareDVSPvlanMapEntry []VMwareDVSPvlanMapEntry `xml:"VMwareDVSPvlanMapEntry,omitempty"` +} + +func init() { + t["ArrayOfVMwareDVSPvlanMapEntry"] = reflect.TypeOf((*ArrayOfVMwareDVSPvlanMapEntry)(nil)).Elem() +} + +type ArrayOfVMwareDVSVspanConfigSpec struct { + VMwareDVSVspanConfigSpec []VMwareDVSVspanConfigSpec `xml:"VMwareDVSVspanConfigSpec,omitempty"` +} + +func init() { + t["ArrayOfVMwareDVSVspanConfigSpec"] = reflect.TypeOf((*ArrayOfVMwareDVSVspanConfigSpec)(nil)).Elem() +} + +type ArrayOfVMwareDvsLacpGroupConfig struct { + VMwareDvsLacpGroupConfig []VMwareDvsLacpGroupConfig `xml:"VMwareDvsLacpGroupConfig,omitempty"` +} + +func init() { + t["ArrayOfVMwareDvsLacpGroupConfig"] = reflect.TypeOf((*ArrayOfVMwareDvsLacpGroupConfig)(nil)).Elem() +} + +type ArrayOfVMwareDvsLacpGroupSpec struct { + VMwareDvsLacpGroupSpec []VMwareDvsLacpGroupSpec `xml:"VMwareDvsLacpGroupSpec,omitempty"` +} + +func init() { + t["ArrayOfVMwareDvsLacpGroupSpec"] = reflect.TypeOf((*ArrayOfVMwareDvsLacpGroupSpec)(nil)).Elem() +} + +type ArrayOfVMwareVspanSession struct { + VMwareVspanSession []VMwareVspanSession `xml:"VMwareVspanSession,omitempty"` +} + +func init() { + t["ArrayOfVMwareVspanSession"] = reflect.TypeOf((*ArrayOfVMwareVspanSession)(nil)).Elem() +} + +type ArrayOfVVolHostPE struct { + VVolHostPE []VVolHostPE `xml:"VVolHostPE,omitempty"` +} + +func init() { + t["ArrayOfVVolHostPE"] = reflect.TypeOf((*ArrayOfVVolHostPE)(nil)).Elem() +} + +type ArrayOfVimVasaProviderInfo struct { + VimVasaProviderInfo []VimVasaProviderInfo `xml:"VimVasaProviderInfo,omitempty"` +} + +func init() { + t["ArrayOfVimVasaProviderInfo"] = reflect.TypeOf((*ArrayOfVimVasaProviderInfo)(nil)).Elem() +} + +type ArrayOfVimVasaProviderStatePerArray struct { + VimVasaProviderStatePerArray []VimVasaProviderStatePerArray `xml:"VimVasaProviderStatePerArray,omitempty"` +} + +func init() { + t["ArrayOfVimVasaProviderStatePerArray"] = reflect.TypeOf((*ArrayOfVimVasaProviderStatePerArray)(nil)).Elem() +} + +type ArrayOfVirtualAppLinkInfo struct { + VirtualAppLinkInfo []VirtualAppLinkInfo `xml:"VirtualAppLinkInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualAppLinkInfo"] = reflect.TypeOf((*ArrayOfVirtualAppLinkInfo)(nil)).Elem() +} + +type ArrayOfVirtualDevice struct { + VirtualDevice []BaseVirtualDevice `xml:"VirtualDevice,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualDevice"] = reflect.TypeOf((*ArrayOfVirtualDevice)(nil)).Elem() +} + +type ArrayOfVirtualDeviceBackingOption struct { + VirtualDeviceBackingOption []BaseVirtualDeviceBackingOption `xml:"VirtualDeviceBackingOption,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualDeviceBackingOption"] = reflect.TypeOf((*ArrayOfVirtualDeviceBackingOption)(nil)).Elem() +} + +type ArrayOfVirtualDeviceConfigSpec struct { + VirtualDeviceConfigSpec []BaseVirtualDeviceConfigSpec `xml:"VirtualDeviceConfigSpec,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualDeviceConfigSpec"] = reflect.TypeOf((*ArrayOfVirtualDeviceConfigSpec)(nil)).Elem() +} + +type ArrayOfVirtualDeviceOption struct { + VirtualDeviceOption []BaseVirtualDeviceOption `xml:"VirtualDeviceOption,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualDeviceOption"] = reflect.TypeOf((*ArrayOfVirtualDeviceOption)(nil)).Elem() +} + +type ArrayOfVirtualDisk struct { + VirtualDisk []VirtualDisk `xml:"VirtualDisk,omitempty"` +} + +func init() { + t["ArrayOfVirtualDisk"] = reflect.TypeOf((*ArrayOfVirtualDisk)(nil)).Elem() +} + +type ArrayOfVirtualDiskDeltaDiskFormatsSupported struct { + VirtualDiskDeltaDiskFormatsSupported []VirtualDiskDeltaDiskFormatsSupported `xml:"VirtualDiskDeltaDiskFormatsSupported,omitempty"` +} + +func init() { + t["ArrayOfVirtualDiskDeltaDiskFormatsSupported"] = reflect.TypeOf((*ArrayOfVirtualDiskDeltaDiskFormatsSupported)(nil)).Elem() +} + +type ArrayOfVirtualDiskId struct { + VirtualDiskId []VirtualDiskId `xml:"VirtualDiskId,omitempty"` +} + +func init() { + t["ArrayOfVirtualDiskId"] = reflect.TypeOf((*ArrayOfVirtualDiskId)(nil)).Elem() +} + +type ArrayOfVirtualMachineBootOptionsBootableDevice struct { + VirtualMachineBootOptionsBootableDevice []BaseVirtualMachineBootOptionsBootableDevice `xml:"VirtualMachineBootOptionsBootableDevice,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualMachineBootOptionsBootableDevice"] = reflect.TypeOf((*ArrayOfVirtualMachineBootOptionsBootableDevice)(nil)).Elem() +} + +type ArrayOfVirtualMachineCdromInfo struct { + VirtualMachineCdromInfo []VirtualMachineCdromInfo `xml:"VirtualMachineCdromInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineCdromInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineCdromInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineConfigInfoDatastoreUrlPair struct { + VirtualMachineConfigInfoDatastoreUrlPair []VirtualMachineConfigInfoDatastoreUrlPair `xml:"VirtualMachineConfigInfoDatastoreUrlPair,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineConfigInfoDatastoreUrlPair"] = reflect.TypeOf((*ArrayOfVirtualMachineConfigInfoDatastoreUrlPair)(nil)).Elem() +} + +type ArrayOfVirtualMachineConfigOptionDescriptor struct { + VirtualMachineConfigOptionDescriptor []VirtualMachineConfigOptionDescriptor `xml:"VirtualMachineConfigOptionDescriptor,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineConfigOptionDescriptor"] = reflect.TypeOf((*ArrayOfVirtualMachineConfigOptionDescriptor)(nil)).Elem() +} + +type ArrayOfVirtualMachineCpuIdInfoSpec struct { + VirtualMachineCpuIdInfoSpec []VirtualMachineCpuIdInfoSpec `xml:"VirtualMachineCpuIdInfoSpec,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineCpuIdInfoSpec"] = reflect.TypeOf((*ArrayOfVirtualMachineCpuIdInfoSpec)(nil)).Elem() +} + +type ArrayOfVirtualMachineDatastoreInfo struct { + VirtualMachineDatastoreInfo []VirtualMachineDatastoreInfo `xml:"VirtualMachineDatastoreInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineDatastoreInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineDatastoreInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineDatastoreVolumeOption struct { + VirtualMachineDatastoreVolumeOption []VirtualMachineDatastoreVolumeOption `xml:"VirtualMachineDatastoreVolumeOption,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineDatastoreVolumeOption"] = reflect.TypeOf((*ArrayOfVirtualMachineDatastoreVolumeOption)(nil)).Elem() +} + +type ArrayOfVirtualMachineDeviceRuntimeInfo struct { + VirtualMachineDeviceRuntimeInfo []VirtualMachineDeviceRuntimeInfo `xml:"VirtualMachineDeviceRuntimeInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineDeviceRuntimeInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineDeviceRuntimeInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineDisplayTopology struct { + VirtualMachineDisplayTopology []VirtualMachineDisplayTopology `xml:"VirtualMachineDisplayTopology,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineDisplayTopology"] = reflect.TypeOf((*ArrayOfVirtualMachineDisplayTopology)(nil)).Elem() +} + +type ArrayOfVirtualMachineFeatureRequirement struct { + VirtualMachineFeatureRequirement []VirtualMachineFeatureRequirement `xml:"VirtualMachineFeatureRequirement,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFeatureRequirement"] = reflect.TypeOf((*ArrayOfVirtualMachineFeatureRequirement)(nil)).Elem() +} + +type ArrayOfVirtualMachineFileLayoutDiskLayout struct { + VirtualMachineFileLayoutDiskLayout []VirtualMachineFileLayoutDiskLayout `xml:"VirtualMachineFileLayoutDiskLayout,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFileLayoutDiskLayout"] = reflect.TypeOf((*ArrayOfVirtualMachineFileLayoutDiskLayout)(nil)).Elem() +} + +type ArrayOfVirtualMachineFileLayoutExDiskLayout struct { + VirtualMachineFileLayoutExDiskLayout []VirtualMachineFileLayoutExDiskLayout `xml:"VirtualMachineFileLayoutExDiskLayout,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFileLayoutExDiskLayout"] = reflect.TypeOf((*ArrayOfVirtualMachineFileLayoutExDiskLayout)(nil)).Elem() +} + +type ArrayOfVirtualMachineFileLayoutExDiskUnit struct { + VirtualMachineFileLayoutExDiskUnit []VirtualMachineFileLayoutExDiskUnit `xml:"VirtualMachineFileLayoutExDiskUnit,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFileLayoutExDiskUnit"] = reflect.TypeOf((*ArrayOfVirtualMachineFileLayoutExDiskUnit)(nil)).Elem() +} + +type ArrayOfVirtualMachineFileLayoutExFileInfo struct { + VirtualMachineFileLayoutExFileInfo []VirtualMachineFileLayoutExFileInfo `xml:"VirtualMachineFileLayoutExFileInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFileLayoutExFileInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineFileLayoutExFileInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineFileLayoutExSnapshotLayout struct { + VirtualMachineFileLayoutExSnapshotLayout []VirtualMachineFileLayoutExSnapshotLayout `xml:"VirtualMachineFileLayoutExSnapshotLayout,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFileLayoutExSnapshotLayout"] = reflect.TypeOf((*ArrayOfVirtualMachineFileLayoutExSnapshotLayout)(nil)).Elem() +} + +type ArrayOfVirtualMachineFileLayoutSnapshotLayout struct { + VirtualMachineFileLayoutSnapshotLayout []VirtualMachineFileLayoutSnapshotLayout `xml:"VirtualMachineFileLayoutSnapshotLayout,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFileLayoutSnapshotLayout"] = reflect.TypeOf((*ArrayOfVirtualMachineFileLayoutSnapshotLayout)(nil)).Elem() +} + +type ArrayOfVirtualMachineFloppyInfo struct { + VirtualMachineFloppyInfo []VirtualMachineFloppyInfo `xml:"VirtualMachineFloppyInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineFloppyInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineFloppyInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineIdeDiskDeviceInfo struct { + VirtualMachineIdeDiskDeviceInfo []VirtualMachineIdeDiskDeviceInfo `xml:"VirtualMachineIdeDiskDeviceInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineIdeDiskDeviceInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineIdeDiskDeviceInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineIdeDiskDevicePartitionInfo struct { + VirtualMachineIdeDiskDevicePartitionInfo []VirtualMachineIdeDiskDevicePartitionInfo `xml:"VirtualMachineIdeDiskDevicePartitionInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineIdeDiskDevicePartitionInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineIdeDiskDevicePartitionInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineLegacyNetworkSwitchInfo struct { + VirtualMachineLegacyNetworkSwitchInfo []VirtualMachineLegacyNetworkSwitchInfo `xml:"VirtualMachineLegacyNetworkSwitchInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineLegacyNetworkSwitchInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineLegacyNetworkSwitchInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineMessage struct { + VirtualMachineMessage []VirtualMachineMessage `xml:"VirtualMachineMessage,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineMessage"] = reflect.TypeOf((*ArrayOfVirtualMachineMessage)(nil)).Elem() +} + +type ArrayOfVirtualMachineMetadataManagerVmMetadataInput struct { + VirtualMachineMetadataManagerVmMetadataInput []VirtualMachineMetadataManagerVmMetadataInput `xml:"VirtualMachineMetadataManagerVmMetadataInput,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineMetadataManagerVmMetadataInput"] = reflect.TypeOf((*ArrayOfVirtualMachineMetadataManagerVmMetadataInput)(nil)).Elem() +} + +type ArrayOfVirtualMachineMetadataManagerVmMetadataResult struct { + VirtualMachineMetadataManagerVmMetadataResult []VirtualMachineMetadataManagerVmMetadataResult `xml:"VirtualMachineMetadataManagerVmMetadataResult,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineMetadataManagerVmMetadataResult"] = reflect.TypeOf((*ArrayOfVirtualMachineMetadataManagerVmMetadataResult)(nil)).Elem() +} + +type ArrayOfVirtualMachineNetworkInfo struct { + VirtualMachineNetworkInfo []VirtualMachineNetworkInfo `xml:"VirtualMachineNetworkInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineNetworkInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineNetworkInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineParallelInfo struct { + VirtualMachineParallelInfo []VirtualMachineParallelInfo `xml:"VirtualMachineParallelInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineParallelInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineParallelInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachinePciPassthroughInfo struct { + VirtualMachinePciPassthroughInfo []BaseVirtualMachinePciPassthroughInfo `xml:"VirtualMachinePciPassthroughInfo,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualMachinePciPassthroughInfo"] = reflect.TypeOf((*ArrayOfVirtualMachinePciPassthroughInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachinePciSharedGpuPassthroughInfo struct { + VirtualMachinePciSharedGpuPassthroughInfo []VirtualMachinePciSharedGpuPassthroughInfo `xml:"VirtualMachinePciSharedGpuPassthroughInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachinePciSharedGpuPassthroughInfo"] = reflect.TypeOf((*ArrayOfVirtualMachinePciSharedGpuPassthroughInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineProfileSpec struct { + VirtualMachineProfileSpec []BaseVirtualMachineProfileSpec `xml:"VirtualMachineProfileSpec,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVirtualMachineProfileSpec"] = reflect.TypeOf((*ArrayOfVirtualMachineProfileSpec)(nil)).Elem() +} + +type ArrayOfVirtualMachineRelocateSpecDiskLocator struct { + VirtualMachineRelocateSpecDiskLocator []VirtualMachineRelocateSpecDiskLocator `xml:"VirtualMachineRelocateSpecDiskLocator,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineRelocateSpecDiskLocator"] = reflect.TypeOf((*ArrayOfVirtualMachineRelocateSpecDiskLocator)(nil)).Elem() +} + +type ArrayOfVirtualMachineScsiDiskDeviceInfo struct { + VirtualMachineScsiDiskDeviceInfo []VirtualMachineScsiDiskDeviceInfo `xml:"VirtualMachineScsiDiskDeviceInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineScsiDiskDeviceInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineScsiDiskDeviceInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineScsiPassthroughInfo struct { + VirtualMachineScsiPassthroughInfo []VirtualMachineScsiPassthroughInfo `xml:"VirtualMachineScsiPassthroughInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineScsiPassthroughInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineScsiPassthroughInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineSerialInfo struct { + VirtualMachineSerialInfo []VirtualMachineSerialInfo `xml:"VirtualMachineSerialInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineSerialInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineSerialInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineSnapshotTree struct { + VirtualMachineSnapshotTree []VirtualMachineSnapshotTree `xml:"VirtualMachineSnapshotTree,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineSnapshotTree"] = reflect.TypeOf((*ArrayOfVirtualMachineSnapshotTree)(nil)).Elem() +} + +type ArrayOfVirtualMachineSoundInfo struct { + VirtualMachineSoundInfo []VirtualMachineSoundInfo `xml:"VirtualMachineSoundInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineSoundInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineSoundInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineSriovInfo struct { + VirtualMachineSriovInfo []VirtualMachineSriovInfo `xml:"VirtualMachineSriovInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineSriovInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineSriovInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineSummary struct { + VirtualMachineSummary []VirtualMachineSummary `xml:"VirtualMachineSummary,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineSummary"] = reflect.TypeOf((*ArrayOfVirtualMachineSummary)(nil)).Elem() +} + +type ArrayOfVirtualMachineUsageOnDatastore struct { + VirtualMachineUsageOnDatastore []VirtualMachineUsageOnDatastore `xml:"VirtualMachineUsageOnDatastore,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineUsageOnDatastore"] = reflect.TypeOf((*ArrayOfVirtualMachineUsageOnDatastore)(nil)).Elem() +} + +type ArrayOfVirtualMachineUsbInfo struct { + VirtualMachineUsbInfo []VirtualMachineUsbInfo `xml:"VirtualMachineUsbInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineUsbInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineUsbInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineVFlashModuleInfo struct { + VirtualMachineVFlashModuleInfo []VirtualMachineVFlashModuleInfo `xml:"VirtualMachineVFlashModuleInfo,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineVFlashModuleInfo"] = reflect.TypeOf((*ArrayOfVirtualMachineVFlashModuleInfo)(nil)).Elem() +} + +type ArrayOfVirtualMachineVMCIDeviceFilterSpec struct { + VirtualMachineVMCIDeviceFilterSpec []VirtualMachineVMCIDeviceFilterSpec `xml:"VirtualMachineVMCIDeviceFilterSpec,omitempty"` +} + +func init() { + t["ArrayOfVirtualMachineVMCIDeviceFilterSpec"] = reflect.TypeOf((*ArrayOfVirtualMachineVMCIDeviceFilterSpec)(nil)).Elem() +} + +type ArrayOfVirtualNicManagerNetConfig struct { + VirtualNicManagerNetConfig []VirtualNicManagerNetConfig `xml:"VirtualNicManagerNetConfig,omitempty"` +} + +func init() { + t["ArrayOfVirtualNicManagerNetConfig"] = reflect.TypeOf((*ArrayOfVirtualNicManagerNetConfig)(nil)).Elem() +} + +type ArrayOfVirtualSCSISharing struct { + VirtualSCSISharing []VirtualSCSISharing `xml:"VirtualSCSISharing,omitempty"` +} + +func init() { + t["ArrayOfVirtualSCSISharing"] = reflect.TypeOf((*ArrayOfVirtualSCSISharing)(nil)).Elem() +} + +type ArrayOfVirtualSwitchProfile struct { + VirtualSwitchProfile []VirtualSwitchProfile `xml:"VirtualSwitchProfile,omitempty"` +} + +func init() { + t["ArrayOfVirtualSwitchProfile"] = reflect.TypeOf((*ArrayOfVirtualSwitchProfile)(nil)).Elem() +} + +type ArrayOfVmEventArgument struct { + VmEventArgument []VmEventArgument `xml:"VmEventArgument,omitempty"` +} + +func init() { + t["ArrayOfVmEventArgument"] = reflect.TypeOf((*ArrayOfVmEventArgument)(nil)).Elem() +} + +type ArrayOfVmPodConfigForPlacement struct { + VmPodConfigForPlacement []VmPodConfigForPlacement `xml:"VmPodConfigForPlacement,omitempty"` +} + +func init() { + t["ArrayOfVmPodConfigForPlacement"] = reflect.TypeOf((*ArrayOfVmPodConfigForPlacement)(nil)).Elem() +} + +type ArrayOfVmPortGroupProfile struct { + VmPortGroupProfile []VmPortGroupProfile `xml:"VmPortGroupProfile,omitempty"` +} + +func init() { + t["ArrayOfVmPortGroupProfile"] = reflect.TypeOf((*ArrayOfVmPortGroupProfile)(nil)).Elem() +} + +type ArrayOfVmfsDatastoreOption struct { + VmfsDatastoreOption []VmfsDatastoreOption `xml:"VmfsDatastoreOption,omitempty"` +} + +func init() { + t["ArrayOfVmfsDatastoreOption"] = reflect.TypeOf((*ArrayOfVmfsDatastoreOption)(nil)).Elem() +} + +type ArrayOfVnicPortArgument struct { + VnicPortArgument []VnicPortArgument `xml:"VnicPortArgument,omitempty"` +} + +func init() { + t["ArrayOfVnicPortArgument"] = reflect.TypeOf((*ArrayOfVnicPortArgument)(nil)).Elem() +} + +type ArrayOfVsanHostConfigInfo struct { + VsanHostConfigInfo []VsanHostConfigInfo `xml:"VsanHostConfigInfo,omitempty"` +} + +func init() { + t["ArrayOfVsanHostConfigInfo"] = reflect.TypeOf((*ArrayOfVsanHostConfigInfo)(nil)).Elem() +} + +type ArrayOfVsanHostConfigInfoNetworkInfoPortConfig struct { + VsanHostConfigInfoNetworkInfoPortConfig []VsanHostConfigInfoNetworkInfoPortConfig `xml:"VsanHostConfigInfoNetworkInfoPortConfig,omitempty"` +} + +func init() { + t["ArrayOfVsanHostConfigInfoNetworkInfoPortConfig"] = reflect.TypeOf((*ArrayOfVsanHostConfigInfoNetworkInfoPortConfig)(nil)).Elem() +} + +type ArrayOfVsanHostDiskMapInfo struct { + VsanHostDiskMapInfo []VsanHostDiskMapInfo `xml:"VsanHostDiskMapInfo,omitempty"` +} + +func init() { + t["ArrayOfVsanHostDiskMapInfo"] = reflect.TypeOf((*ArrayOfVsanHostDiskMapInfo)(nil)).Elem() +} + +type ArrayOfVsanHostDiskMapResult struct { + VsanHostDiskMapResult []VsanHostDiskMapResult `xml:"VsanHostDiskMapResult,omitempty"` +} + +func init() { + t["ArrayOfVsanHostDiskMapResult"] = reflect.TypeOf((*ArrayOfVsanHostDiskMapResult)(nil)).Elem() +} + +type ArrayOfVsanHostDiskMapping struct { + VsanHostDiskMapping []VsanHostDiskMapping `xml:"VsanHostDiskMapping,omitempty"` +} + +func init() { + t["ArrayOfVsanHostDiskMapping"] = reflect.TypeOf((*ArrayOfVsanHostDiskMapping)(nil)).Elem() +} + +type ArrayOfVsanHostDiskResult struct { + VsanHostDiskResult []VsanHostDiskResult `xml:"VsanHostDiskResult,omitempty"` +} + +func init() { + t["ArrayOfVsanHostDiskResult"] = reflect.TypeOf((*ArrayOfVsanHostDiskResult)(nil)).Elem() +} + +type ArrayOfVsanHostMembershipInfo struct { + VsanHostMembershipInfo []VsanHostMembershipInfo `xml:"VsanHostMembershipInfo,omitempty"` +} + +func init() { + t["ArrayOfVsanHostMembershipInfo"] = reflect.TypeOf((*ArrayOfVsanHostMembershipInfo)(nil)).Elem() +} + +type ArrayOfVsanHostRuntimeInfoDiskIssue struct { + VsanHostRuntimeInfoDiskIssue []VsanHostRuntimeInfoDiskIssue `xml:"VsanHostRuntimeInfoDiskIssue,omitempty"` +} + +func init() { + t["ArrayOfVsanHostRuntimeInfoDiskIssue"] = reflect.TypeOf((*ArrayOfVsanHostRuntimeInfoDiskIssue)(nil)).Elem() +} + +type ArrayOfVsanNewPolicyBatch struct { + VsanNewPolicyBatch []VsanNewPolicyBatch `xml:"VsanNewPolicyBatch,omitempty"` +} + +func init() { + t["ArrayOfVsanNewPolicyBatch"] = reflect.TypeOf((*ArrayOfVsanNewPolicyBatch)(nil)).Elem() +} + +type ArrayOfVsanPolicyChangeBatch struct { + VsanPolicyChangeBatch []VsanPolicyChangeBatch `xml:"VsanPolicyChangeBatch,omitempty"` +} + +func init() { + t["ArrayOfVsanPolicyChangeBatch"] = reflect.TypeOf((*ArrayOfVsanPolicyChangeBatch)(nil)).Elem() +} + +type ArrayOfVsanPolicySatisfiability struct { + VsanPolicySatisfiability []VsanPolicySatisfiability `xml:"VsanPolicySatisfiability,omitempty"` +} + +func init() { + t["ArrayOfVsanPolicySatisfiability"] = reflect.TypeOf((*ArrayOfVsanPolicySatisfiability)(nil)).Elem() +} + +type ArrayOfVsanUpgradeSystemNetworkPartitionInfo struct { + VsanUpgradeSystemNetworkPartitionInfo []VsanUpgradeSystemNetworkPartitionInfo `xml:"VsanUpgradeSystemNetworkPartitionInfo,omitempty"` +} + +func init() { + t["ArrayOfVsanUpgradeSystemNetworkPartitionInfo"] = reflect.TypeOf((*ArrayOfVsanUpgradeSystemNetworkPartitionInfo)(nil)).Elem() +} + +type ArrayOfVsanUpgradeSystemPreflightCheckIssue struct { + VsanUpgradeSystemPreflightCheckIssue []BaseVsanUpgradeSystemPreflightCheckIssue `xml:"VsanUpgradeSystemPreflightCheckIssue,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVsanUpgradeSystemPreflightCheckIssue"] = reflect.TypeOf((*ArrayOfVsanUpgradeSystemPreflightCheckIssue)(nil)).Elem() +} + +type ArrayOfVsanUpgradeSystemUpgradeHistoryItem struct { + VsanUpgradeSystemUpgradeHistoryItem []BaseVsanUpgradeSystemUpgradeHistoryItem `xml:"VsanUpgradeSystemUpgradeHistoryItem,omitempty,typeattr"` +} + +func init() { + t["ArrayOfVsanUpgradeSystemUpgradeHistoryItem"] = reflect.TypeOf((*ArrayOfVsanUpgradeSystemUpgradeHistoryItem)(nil)).Elem() +} + +type ArrayUpdateSpec struct { + DynamicData + + Operation ArrayUpdateOperation `xml:"operation"` + RemoveKey AnyType `xml:"removeKey,omitempty,typeattr"` +} + +func init() { + t["ArrayUpdateSpec"] = reflect.TypeOf((*ArrayUpdateSpec)(nil)).Elem() +} + +type AssignUserToGroup AssignUserToGroupRequestType + +func init() { + t["AssignUserToGroup"] = reflect.TypeOf((*AssignUserToGroup)(nil)).Elem() +} + +type AssignUserToGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + User string `xml:"user"` + Group string `xml:"group"` +} + +func init() { + t["AssignUserToGroupRequestType"] = reflect.TypeOf((*AssignUserToGroupRequestType)(nil)).Elem() +} + +type AssignUserToGroupResponse struct { +} + +type AssociateProfile AssociateProfileRequestType + +func init() { + t["AssociateProfile"] = reflect.TypeOf((*AssociateProfile)(nil)).Elem() +} + +type AssociateProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity []ManagedObjectReference `xml:"entity"` +} + +func init() { + t["AssociateProfileRequestType"] = reflect.TypeOf((*AssociateProfileRequestType)(nil)).Elem() +} + +type AssociateProfileResponse struct { +} + +type AttachScsiLun AttachScsiLunRequestType + +func init() { + t["AttachScsiLun"] = reflect.TypeOf((*AttachScsiLun)(nil)).Elem() +} + +type AttachScsiLunExRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunUuid []string `xml:"lunUuid"` +} + +func init() { + t["AttachScsiLunExRequestType"] = reflect.TypeOf((*AttachScsiLunExRequestType)(nil)).Elem() +} + +type AttachScsiLunEx_Task AttachScsiLunExRequestType + +func init() { + t["AttachScsiLunEx_Task"] = reflect.TypeOf((*AttachScsiLunEx_Task)(nil)).Elem() +} + +type AttachScsiLunEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type AttachScsiLunRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunUuid string `xml:"lunUuid"` +} + +func init() { + t["AttachScsiLunRequestType"] = reflect.TypeOf((*AttachScsiLunRequestType)(nil)).Elem() +} + +type AttachScsiLunResponse struct { +} + +type AttachVmfsExtent AttachVmfsExtentRequestType + +func init() { + t["AttachVmfsExtent"] = reflect.TypeOf((*AttachVmfsExtent)(nil)).Elem() +} + +type AttachVmfsExtentRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsPath string `xml:"vmfsPath"` + Extent HostScsiDiskPartition `xml:"extent"` +} + +func init() { + t["AttachVmfsExtentRequestType"] = reflect.TypeOf((*AttachVmfsExtentRequestType)(nil)).Elem() +} + +type AttachVmfsExtentResponse struct { +} + +type AuthMinimumAdminPermission struct { + VimFault +} + +func init() { + t["AuthMinimumAdminPermission"] = reflect.TypeOf((*AuthMinimumAdminPermission)(nil)).Elem() +} + +type AuthMinimumAdminPermissionFault AuthMinimumAdminPermission + +func init() { + t["AuthMinimumAdminPermissionFault"] = reflect.TypeOf((*AuthMinimumAdminPermissionFault)(nil)).Elem() +} + +type AuthenticationProfile struct { + ApplyProfile + + ActiveDirectory *ActiveDirectoryProfile `xml:"activeDirectory,omitempty"` +} + +func init() { + t["AuthenticationProfile"] = reflect.TypeOf((*AuthenticationProfile)(nil)).Elem() +} + +type AuthorizationDescription struct { + DynamicData + + Privilege []BaseElementDescription `xml:"privilege,typeattr"` + PrivilegeGroup []BaseElementDescription `xml:"privilegeGroup,typeattr"` +} + +func init() { + t["AuthorizationDescription"] = reflect.TypeOf((*AuthorizationDescription)(nil)).Elem() +} + +type AuthorizationEvent struct { + Event +} + +func init() { + t["AuthorizationEvent"] = reflect.TypeOf((*AuthorizationEvent)(nil)).Elem() +} + +type AuthorizationPrivilege struct { + DynamicData + + PrivId string `xml:"privId"` + OnParent bool `xml:"onParent"` + Name string `xml:"name"` + PrivGroupName string `xml:"privGroupName"` +} + +func init() { + t["AuthorizationPrivilege"] = reflect.TypeOf((*AuthorizationPrivilege)(nil)).Elem() +} + +type AuthorizationRole struct { + DynamicData + + RoleId int32 `xml:"roleId"` + System bool `xml:"system"` + Name string `xml:"name"` + Info BaseDescription `xml:"info,typeattr"` + Privilege []string `xml:"privilege,omitempty"` +} + +func init() { + t["AuthorizationRole"] = reflect.TypeOf((*AuthorizationRole)(nil)).Elem() +} + +type AutoStartDefaults struct { + DynamicData + + Enabled *bool `xml:"enabled"` + StartDelay int32 `xml:"startDelay,omitempty"` + StopDelay int32 `xml:"stopDelay,omitempty"` + WaitForHeartbeat *bool `xml:"waitForHeartbeat"` + StopAction string `xml:"stopAction,omitempty"` +} + +func init() { + t["AutoStartDefaults"] = reflect.TypeOf((*AutoStartDefaults)(nil)).Elem() +} + +type AutoStartPowerInfo struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + StartOrder int32 `xml:"startOrder"` + StartDelay int32 `xml:"startDelay"` + WaitForHeartbeat AutoStartWaitHeartbeatSetting `xml:"waitForHeartbeat"` + StartAction string `xml:"startAction"` + StopDelay int32 `xml:"stopDelay"` + StopAction string `xml:"stopAction"` +} + +func init() { + t["AutoStartPowerInfo"] = reflect.TypeOf((*AutoStartPowerInfo)(nil)).Elem() +} + +type AutoStartPowerOff AutoStartPowerOffRequestType + +func init() { + t["AutoStartPowerOff"] = reflect.TypeOf((*AutoStartPowerOff)(nil)).Elem() +} + +type AutoStartPowerOffRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["AutoStartPowerOffRequestType"] = reflect.TypeOf((*AutoStartPowerOffRequestType)(nil)).Elem() +} + +type AutoStartPowerOffResponse struct { +} + +type AutoStartPowerOn AutoStartPowerOnRequestType + +func init() { + t["AutoStartPowerOn"] = reflect.TypeOf((*AutoStartPowerOn)(nil)).Elem() +} + +type AutoStartPowerOnRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["AutoStartPowerOnRequestType"] = reflect.TypeOf((*AutoStartPowerOnRequestType)(nil)).Elem() +} + +type AutoStartPowerOnResponse struct { +} + +type BackupBlobReadFailure struct { + DvsFault + + EntityName string `xml:"entityName"` + EntityType string `xml:"entityType"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["BackupBlobReadFailure"] = reflect.TypeOf((*BackupBlobReadFailure)(nil)).Elem() +} + +type BackupBlobReadFailureFault BackupBlobReadFailure + +func init() { + t["BackupBlobReadFailureFault"] = reflect.TypeOf((*BackupBlobReadFailureFault)(nil)).Elem() +} + +type BackupBlobWriteFailure struct { + DvsFault + + EntityName string `xml:"entityName"` + EntityType string `xml:"entityType"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["BackupBlobWriteFailure"] = reflect.TypeOf((*BackupBlobWriteFailure)(nil)).Elem() +} + +type BackupBlobWriteFailureFault BackupBlobWriteFailure + +func init() { + t["BackupBlobWriteFailureFault"] = reflect.TypeOf((*BackupBlobWriteFailureFault)(nil)).Elem() +} + +type BackupFirmwareConfiguration BackupFirmwareConfigurationRequestType + +func init() { + t["BackupFirmwareConfiguration"] = reflect.TypeOf((*BackupFirmwareConfiguration)(nil)).Elem() +} + +type BackupFirmwareConfigurationRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["BackupFirmwareConfigurationRequestType"] = reflect.TypeOf((*BackupFirmwareConfigurationRequestType)(nil)).Elem() +} + +type BackupFirmwareConfigurationResponse struct { + Returnval string `xml:"returnval"` +} + +type BadUsernameSessionEvent struct { + SessionEvent + + IpAddress string `xml:"ipAddress"` +} + +func init() { + t["BadUsernameSessionEvent"] = reflect.TypeOf((*BadUsernameSessionEvent)(nil)).Elem() +} + +type BatchResult struct { + DynamicData + + Result string `xml:"result"` + HostKey string `xml:"hostKey"` + Ds *ManagedObjectReference `xml:"ds,omitempty"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["BatchResult"] = reflect.TypeOf((*BatchResult)(nil)).Elem() +} + +type BindVnic BindVnicRequestType + +func init() { + t["BindVnic"] = reflect.TypeOf((*BindVnic)(nil)).Elem() +} + +type BindVnicRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaName string `xml:"iScsiHbaName"` + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["BindVnicRequestType"] = reflect.TypeOf((*BindVnicRequestType)(nil)).Elem() +} + +type BindVnicResponse struct { +} + +type BlockedByFirewall struct { + HostConfigFault +} + +func init() { + t["BlockedByFirewall"] = reflect.TypeOf((*BlockedByFirewall)(nil)).Elem() +} + +type BlockedByFirewallFault BlockedByFirewall + +func init() { + t["BlockedByFirewallFault"] = reflect.TypeOf((*BlockedByFirewallFault)(nil)).Elem() +} + +type BoolOption struct { + OptionType + + Supported bool `xml:"supported"` + DefaultValue bool `xml:"defaultValue"` +} + +func init() { + t["BoolOption"] = reflect.TypeOf((*BoolOption)(nil)).Elem() +} + +type BoolPolicy struct { + InheritablePolicy + + Value *bool `xml:"value"` +} + +func init() { + t["BoolPolicy"] = reflect.TypeOf((*BoolPolicy)(nil)).Elem() +} + +type BrowseDiagnosticLog BrowseDiagnosticLogRequestType + +func init() { + t["BrowseDiagnosticLog"] = reflect.TypeOf((*BrowseDiagnosticLog)(nil)).Elem() +} + +type BrowseDiagnosticLogRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Key string `xml:"key"` + Start int32 `xml:"start,omitempty"` + Lines int32 `xml:"lines,omitempty"` +} + +func init() { + t["BrowseDiagnosticLogRequestType"] = reflect.TypeOf((*BrowseDiagnosticLogRequestType)(nil)).Elem() +} + +type BrowseDiagnosticLogResponse struct { + Returnval DiagnosticManagerLogHeader `xml:"returnval"` +} + +type CAMServerRefusedConnection struct { + InvalidCAMServer +} + +func init() { + t["CAMServerRefusedConnection"] = reflect.TypeOf((*CAMServerRefusedConnection)(nil)).Elem() +} + +type CAMServerRefusedConnectionFault CAMServerRefusedConnection + +func init() { + t["CAMServerRefusedConnectionFault"] = reflect.TypeOf((*CAMServerRefusedConnectionFault)(nil)).Elem() +} + +type CanProvisionObjects CanProvisionObjectsRequestType + +func init() { + t["CanProvisionObjects"] = reflect.TypeOf((*CanProvisionObjects)(nil)).Elem() +} + +type CanProvisionObjectsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Npbs []VsanNewPolicyBatch `xml:"npbs"` + IgnoreSatisfiability *bool `xml:"ignoreSatisfiability"` +} + +func init() { + t["CanProvisionObjectsRequestType"] = reflect.TypeOf((*CanProvisionObjectsRequestType)(nil)).Elem() +} + +type CanProvisionObjectsResponse struct { + Returnval []VsanPolicySatisfiability `xml:"returnval"` +} + +type CancelRecommendation CancelRecommendationRequestType + +func init() { + t["CancelRecommendation"] = reflect.TypeOf((*CancelRecommendation)(nil)).Elem() +} + +type CancelRecommendationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key string `xml:"key"` +} + +func init() { + t["CancelRecommendationRequestType"] = reflect.TypeOf((*CancelRecommendationRequestType)(nil)).Elem() +} + +type CancelRecommendationResponse struct { +} + +type CancelRetrievePropertiesEx CancelRetrievePropertiesExRequestType + +func init() { + t["CancelRetrievePropertiesEx"] = reflect.TypeOf((*CancelRetrievePropertiesEx)(nil)).Elem() +} + +type CancelRetrievePropertiesExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Token string `xml:"token"` +} + +func init() { + t["CancelRetrievePropertiesExRequestType"] = reflect.TypeOf((*CancelRetrievePropertiesExRequestType)(nil)).Elem() +} + +type CancelRetrievePropertiesExResponse struct { +} + +type CancelStorageDrsRecommendation CancelStorageDrsRecommendationRequestType + +func init() { + t["CancelStorageDrsRecommendation"] = reflect.TypeOf((*CancelStorageDrsRecommendation)(nil)).Elem() +} + +type CancelStorageDrsRecommendationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key []string `xml:"key"` +} + +func init() { + t["CancelStorageDrsRecommendationRequestType"] = reflect.TypeOf((*CancelStorageDrsRecommendationRequestType)(nil)).Elem() +} + +type CancelStorageDrsRecommendationResponse struct { +} + +type CancelTask CancelTaskRequestType + +func init() { + t["CancelTask"] = reflect.TypeOf((*CancelTask)(nil)).Elem() +} + +type CancelTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["CancelTaskRequestType"] = reflect.TypeOf((*CancelTaskRequestType)(nil)).Elem() +} + +type CancelTaskResponse struct { +} + +type CancelWaitForUpdates CancelWaitForUpdatesRequestType + +func init() { + t["CancelWaitForUpdates"] = reflect.TypeOf((*CancelWaitForUpdates)(nil)).Elem() +} + +type CancelWaitForUpdatesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["CancelWaitForUpdatesRequestType"] = reflect.TypeOf((*CancelWaitForUpdatesRequestType)(nil)).Elem() +} + +type CancelWaitForUpdatesResponse struct { +} + +type CanceledHostOperationEvent struct { + HostEvent +} + +func init() { + t["CanceledHostOperationEvent"] = reflect.TypeOf((*CanceledHostOperationEvent)(nil)).Elem() +} + +type CannotAccessFile struct { + FileFault +} + +func init() { + t["CannotAccessFile"] = reflect.TypeOf((*CannotAccessFile)(nil)).Elem() +} + +type CannotAccessFileFault CannotAccessFile + +func init() { + t["CannotAccessFileFault"] = reflect.TypeOf((*CannotAccessFileFault)(nil)).Elem() +} + +type CannotAccessLocalSource struct { + VimFault +} + +func init() { + t["CannotAccessLocalSource"] = reflect.TypeOf((*CannotAccessLocalSource)(nil)).Elem() +} + +type CannotAccessLocalSourceFault CannotAccessLocalSource + +func init() { + t["CannotAccessLocalSourceFault"] = reflect.TypeOf((*CannotAccessLocalSourceFault)(nil)).Elem() +} + +type CannotAccessNetwork struct { + CannotAccessVmDevice + + Network *ManagedObjectReference `xml:"network,omitempty"` +} + +func init() { + t["CannotAccessNetwork"] = reflect.TypeOf((*CannotAccessNetwork)(nil)).Elem() +} + +type CannotAccessNetworkFault BaseCannotAccessNetwork + +func init() { + t["CannotAccessNetworkFault"] = reflect.TypeOf((*CannotAccessNetworkFault)(nil)).Elem() +} + +type CannotAccessVmComponent struct { + VmConfigFault +} + +func init() { + t["CannotAccessVmComponent"] = reflect.TypeOf((*CannotAccessVmComponent)(nil)).Elem() +} + +type CannotAccessVmComponentFault BaseCannotAccessVmComponent + +func init() { + t["CannotAccessVmComponentFault"] = reflect.TypeOf((*CannotAccessVmComponentFault)(nil)).Elem() +} + +type CannotAccessVmConfig struct { + CannotAccessVmComponent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["CannotAccessVmConfig"] = reflect.TypeOf((*CannotAccessVmConfig)(nil)).Elem() +} + +type CannotAccessVmConfigFault CannotAccessVmConfig + +func init() { + t["CannotAccessVmConfigFault"] = reflect.TypeOf((*CannotAccessVmConfigFault)(nil)).Elem() +} + +type CannotAccessVmDevice struct { + CannotAccessVmComponent + + Device string `xml:"device"` + Backing string `xml:"backing"` + Connected bool `xml:"connected"` +} + +func init() { + t["CannotAccessVmDevice"] = reflect.TypeOf((*CannotAccessVmDevice)(nil)).Elem() +} + +type CannotAccessVmDeviceFault BaseCannotAccessVmDevice + +func init() { + t["CannotAccessVmDeviceFault"] = reflect.TypeOf((*CannotAccessVmDeviceFault)(nil)).Elem() +} + +type CannotAccessVmDisk struct { + CannotAccessVmDevice + + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["CannotAccessVmDisk"] = reflect.TypeOf((*CannotAccessVmDisk)(nil)).Elem() +} + +type CannotAccessVmDiskFault BaseCannotAccessVmDisk + +func init() { + t["CannotAccessVmDiskFault"] = reflect.TypeOf((*CannotAccessVmDiskFault)(nil)).Elem() +} + +type CannotAddHostWithFTVmAsStandalone struct { + HostConnectFault +} + +func init() { + t["CannotAddHostWithFTVmAsStandalone"] = reflect.TypeOf((*CannotAddHostWithFTVmAsStandalone)(nil)).Elem() +} + +type CannotAddHostWithFTVmAsStandaloneFault CannotAddHostWithFTVmAsStandalone + +func init() { + t["CannotAddHostWithFTVmAsStandaloneFault"] = reflect.TypeOf((*CannotAddHostWithFTVmAsStandaloneFault)(nil)).Elem() +} + +type CannotAddHostWithFTVmToDifferentCluster struct { + HostConnectFault +} + +func init() { + t["CannotAddHostWithFTVmToDifferentCluster"] = reflect.TypeOf((*CannotAddHostWithFTVmToDifferentCluster)(nil)).Elem() +} + +type CannotAddHostWithFTVmToDifferentClusterFault CannotAddHostWithFTVmToDifferentCluster + +func init() { + t["CannotAddHostWithFTVmToDifferentClusterFault"] = reflect.TypeOf((*CannotAddHostWithFTVmToDifferentClusterFault)(nil)).Elem() +} + +type CannotAddHostWithFTVmToNonHACluster struct { + HostConnectFault +} + +func init() { + t["CannotAddHostWithFTVmToNonHACluster"] = reflect.TypeOf((*CannotAddHostWithFTVmToNonHACluster)(nil)).Elem() +} + +type CannotAddHostWithFTVmToNonHAClusterFault CannotAddHostWithFTVmToNonHACluster + +func init() { + t["CannotAddHostWithFTVmToNonHAClusterFault"] = reflect.TypeOf((*CannotAddHostWithFTVmToNonHAClusterFault)(nil)).Elem() +} + +type CannotChangeDrsBehaviorForFtSecondary struct { + VmFaultToleranceIssue + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["CannotChangeDrsBehaviorForFtSecondary"] = reflect.TypeOf((*CannotChangeDrsBehaviorForFtSecondary)(nil)).Elem() +} + +type CannotChangeDrsBehaviorForFtSecondaryFault CannotChangeDrsBehaviorForFtSecondary + +func init() { + t["CannotChangeDrsBehaviorForFtSecondaryFault"] = reflect.TypeOf((*CannotChangeDrsBehaviorForFtSecondaryFault)(nil)).Elem() +} + +type CannotChangeHaSettingsForFtSecondary struct { + VmFaultToleranceIssue + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["CannotChangeHaSettingsForFtSecondary"] = reflect.TypeOf((*CannotChangeHaSettingsForFtSecondary)(nil)).Elem() +} + +type CannotChangeHaSettingsForFtSecondaryFault CannotChangeHaSettingsForFtSecondary + +func init() { + t["CannotChangeHaSettingsForFtSecondaryFault"] = reflect.TypeOf((*CannotChangeHaSettingsForFtSecondaryFault)(nil)).Elem() +} + +type CannotChangeVsanClusterUuid struct { + VsanFault +} + +func init() { + t["CannotChangeVsanClusterUuid"] = reflect.TypeOf((*CannotChangeVsanClusterUuid)(nil)).Elem() +} + +type CannotChangeVsanClusterUuidFault CannotChangeVsanClusterUuid + +func init() { + t["CannotChangeVsanClusterUuidFault"] = reflect.TypeOf((*CannotChangeVsanClusterUuidFault)(nil)).Elem() +} + +type CannotChangeVsanNodeUuid struct { + VsanFault +} + +func init() { + t["CannotChangeVsanNodeUuid"] = reflect.TypeOf((*CannotChangeVsanNodeUuid)(nil)).Elem() +} + +type CannotChangeVsanNodeUuidFault CannotChangeVsanNodeUuid + +func init() { + t["CannotChangeVsanNodeUuidFault"] = reflect.TypeOf((*CannotChangeVsanNodeUuidFault)(nil)).Elem() +} + +type CannotComputeFTCompatibleHosts struct { + VmFaultToleranceIssue + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["CannotComputeFTCompatibleHosts"] = reflect.TypeOf((*CannotComputeFTCompatibleHosts)(nil)).Elem() +} + +type CannotComputeFTCompatibleHostsFault CannotComputeFTCompatibleHosts + +func init() { + t["CannotComputeFTCompatibleHostsFault"] = reflect.TypeOf((*CannotComputeFTCompatibleHostsFault)(nil)).Elem() +} + +type CannotCreateFile struct { + FileFault +} + +func init() { + t["CannotCreateFile"] = reflect.TypeOf((*CannotCreateFile)(nil)).Elem() +} + +type CannotCreateFileFault CannotCreateFile + +func init() { + t["CannotCreateFileFault"] = reflect.TypeOf((*CannotCreateFileFault)(nil)).Elem() +} + +type CannotDecryptPasswords struct { + CustomizationFault +} + +func init() { + t["CannotDecryptPasswords"] = reflect.TypeOf((*CannotDecryptPasswords)(nil)).Elem() +} + +type CannotDecryptPasswordsFault CannotDecryptPasswords + +func init() { + t["CannotDecryptPasswordsFault"] = reflect.TypeOf((*CannotDecryptPasswordsFault)(nil)).Elem() +} + +type CannotDeleteFile struct { + FileFault +} + +func init() { + t["CannotDeleteFile"] = reflect.TypeOf((*CannotDeleteFile)(nil)).Elem() +} + +type CannotDeleteFileFault CannotDeleteFile + +func init() { + t["CannotDeleteFileFault"] = reflect.TypeOf((*CannotDeleteFileFault)(nil)).Elem() +} + +type CannotDisableDrsOnClusterManagedByVDC struct { + RuntimeFault +} + +func init() { + t["CannotDisableDrsOnClusterManagedByVDC"] = reflect.TypeOf((*CannotDisableDrsOnClusterManagedByVDC)(nil)).Elem() +} + +type CannotDisableDrsOnClusterManagedByVDCFault CannotDisableDrsOnClusterManagedByVDC + +func init() { + t["CannotDisableDrsOnClusterManagedByVDCFault"] = reflect.TypeOf((*CannotDisableDrsOnClusterManagedByVDCFault)(nil)).Elem() +} + +type CannotDisableDrsOnClustersWithVApps struct { + RuntimeFault +} + +func init() { + t["CannotDisableDrsOnClustersWithVApps"] = reflect.TypeOf((*CannotDisableDrsOnClustersWithVApps)(nil)).Elem() +} + +type CannotDisableDrsOnClustersWithVAppsFault CannotDisableDrsOnClustersWithVApps + +func init() { + t["CannotDisableDrsOnClustersWithVAppsFault"] = reflect.TypeOf((*CannotDisableDrsOnClustersWithVAppsFault)(nil)).Elem() +} + +type CannotDisableSnapshot struct { + VmConfigFault +} + +func init() { + t["CannotDisableSnapshot"] = reflect.TypeOf((*CannotDisableSnapshot)(nil)).Elem() +} + +type CannotDisableSnapshotFault CannotDisableSnapshot + +func init() { + t["CannotDisableSnapshotFault"] = reflect.TypeOf((*CannotDisableSnapshotFault)(nil)).Elem() +} + +type CannotDisconnectHostWithFaultToleranceVm struct { + VimFault + + HostName string `xml:"hostName"` +} + +func init() { + t["CannotDisconnectHostWithFaultToleranceVm"] = reflect.TypeOf((*CannotDisconnectHostWithFaultToleranceVm)(nil)).Elem() +} + +type CannotDisconnectHostWithFaultToleranceVmFault CannotDisconnectHostWithFaultToleranceVm + +func init() { + t["CannotDisconnectHostWithFaultToleranceVmFault"] = reflect.TypeOf((*CannotDisconnectHostWithFaultToleranceVmFault)(nil)).Elem() +} + +type CannotEnableVmcpForCluster struct { + VimFault + + Host *ManagedObjectReference `xml:"host,omitempty"` + HostName string `xml:"hostName,omitempty"` + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["CannotEnableVmcpForCluster"] = reflect.TypeOf((*CannotEnableVmcpForCluster)(nil)).Elem() +} + +type CannotEnableVmcpForClusterFault CannotEnableVmcpForCluster + +func init() { + t["CannotEnableVmcpForClusterFault"] = reflect.TypeOf((*CannotEnableVmcpForClusterFault)(nil)).Elem() +} + +type CannotModifyConfigCpuRequirements struct { + MigrationFault +} + +func init() { + t["CannotModifyConfigCpuRequirements"] = reflect.TypeOf((*CannotModifyConfigCpuRequirements)(nil)).Elem() +} + +type CannotModifyConfigCpuRequirementsFault CannotModifyConfigCpuRequirements + +func init() { + t["CannotModifyConfigCpuRequirementsFault"] = reflect.TypeOf((*CannotModifyConfigCpuRequirementsFault)(nil)).Elem() +} + +type CannotMoveFaultToleranceVm struct { + VimFault + + MoveType string `xml:"moveType"` + VmName string `xml:"vmName"` +} + +func init() { + t["CannotMoveFaultToleranceVm"] = reflect.TypeOf((*CannotMoveFaultToleranceVm)(nil)).Elem() +} + +type CannotMoveFaultToleranceVmFault CannotMoveFaultToleranceVm + +func init() { + t["CannotMoveFaultToleranceVmFault"] = reflect.TypeOf((*CannotMoveFaultToleranceVmFault)(nil)).Elem() +} + +type CannotMoveHostWithFaultToleranceVm struct { + VimFault +} + +func init() { + t["CannotMoveHostWithFaultToleranceVm"] = reflect.TypeOf((*CannotMoveHostWithFaultToleranceVm)(nil)).Elem() +} + +type CannotMoveHostWithFaultToleranceVmFault CannotMoveHostWithFaultToleranceVm + +func init() { + t["CannotMoveHostWithFaultToleranceVmFault"] = reflect.TypeOf((*CannotMoveHostWithFaultToleranceVmFault)(nil)).Elem() +} + +type CannotMoveVmWithDeltaDisk struct { + MigrationFault + + Device string `xml:"device"` +} + +func init() { + t["CannotMoveVmWithDeltaDisk"] = reflect.TypeOf((*CannotMoveVmWithDeltaDisk)(nil)).Elem() +} + +type CannotMoveVmWithDeltaDiskFault CannotMoveVmWithDeltaDisk + +func init() { + t["CannotMoveVmWithDeltaDiskFault"] = reflect.TypeOf((*CannotMoveVmWithDeltaDiskFault)(nil)).Elem() +} + +type CannotMoveVmWithNativeDeltaDisk struct { + MigrationFault +} + +func init() { + t["CannotMoveVmWithNativeDeltaDisk"] = reflect.TypeOf((*CannotMoveVmWithNativeDeltaDisk)(nil)).Elem() +} + +type CannotMoveVmWithNativeDeltaDiskFault CannotMoveVmWithNativeDeltaDisk + +func init() { + t["CannotMoveVmWithNativeDeltaDiskFault"] = reflect.TypeOf((*CannotMoveVmWithNativeDeltaDiskFault)(nil)).Elem() +} + +type CannotMoveVsanEnabledHost struct { + VsanFault +} + +func init() { + t["CannotMoveVsanEnabledHost"] = reflect.TypeOf((*CannotMoveVsanEnabledHost)(nil)).Elem() +} + +type CannotMoveVsanEnabledHostFault BaseCannotMoveVsanEnabledHost + +func init() { + t["CannotMoveVsanEnabledHostFault"] = reflect.TypeOf((*CannotMoveVsanEnabledHostFault)(nil)).Elem() +} + +type CannotPlaceWithoutPrerequisiteMoves struct { + VimFault +} + +func init() { + t["CannotPlaceWithoutPrerequisiteMoves"] = reflect.TypeOf((*CannotPlaceWithoutPrerequisiteMoves)(nil)).Elem() +} + +type CannotPlaceWithoutPrerequisiteMovesFault CannotPlaceWithoutPrerequisiteMoves + +func init() { + t["CannotPlaceWithoutPrerequisiteMovesFault"] = reflect.TypeOf((*CannotPlaceWithoutPrerequisiteMovesFault)(nil)).Elem() +} + +type CannotPowerOffVmInCluster struct { + InvalidState + + Operation string `xml:"operation"` + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["CannotPowerOffVmInCluster"] = reflect.TypeOf((*CannotPowerOffVmInCluster)(nil)).Elem() +} + +type CannotPowerOffVmInClusterFault CannotPowerOffVmInCluster + +func init() { + t["CannotPowerOffVmInClusterFault"] = reflect.TypeOf((*CannotPowerOffVmInClusterFault)(nil)).Elem() +} + +type CannotReconfigureVsanWhenHaEnabled struct { + VsanFault +} + +func init() { + t["CannotReconfigureVsanWhenHaEnabled"] = reflect.TypeOf((*CannotReconfigureVsanWhenHaEnabled)(nil)).Elem() +} + +type CannotReconfigureVsanWhenHaEnabledFault CannotReconfigureVsanWhenHaEnabled + +func init() { + t["CannotReconfigureVsanWhenHaEnabledFault"] = reflect.TypeOf((*CannotReconfigureVsanWhenHaEnabledFault)(nil)).Elem() +} + +type CannotUseNetwork struct { + VmConfigFault + + Device string `xml:"device"` + Backing string `xml:"backing"` + Connected bool `xml:"connected"` + Reason string `xml:"reason"` + Network *ManagedObjectReference `xml:"network,omitempty"` +} + +func init() { + t["CannotUseNetwork"] = reflect.TypeOf((*CannotUseNetwork)(nil)).Elem() +} + +type CannotUseNetworkFault CannotUseNetwork + +func init() { + t["CannotUseNetworkFault"] = reflect.TypeOf((*CannotUseNetworkFault)(nil)).Elem() +} + +type Capability struct { + DynamicData + + ProvisioningSupported bool `xml:"provisioningSupported"` + MultiHostSupported bool `xml:"multiHostSupported"` + UserShellAccessSupported bool `xml:"userShellAccessSupported"` + SupportedEVCMode []EVCMode `xml:"supportedEVCMode,omitempty"` + NetworkBackupAndRestoreSupported *bool `xml:"networkBackupAndRestoreSupported"` +} + +func init() { + t["Capability"] = reflect.TypeOf((*Capability)(nil)).Elem() +} + +type CertMgrRefreshCACertificatesAndCRLsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["CertMgrRefreshCACertificatesAndCRLsRequestType"] = reflect.TypeOf((*CertMgrRefreshCACertificatesAndCRLsRequestType)(nil)).Elem() +} + +type CertMgrRefreshCACertificatesAndCRLs_Task CertMgrRefreshCACertificatesAndCRLsRequestType + +func init() { + t["CertMgrRefreshCACertificatesAndCRLs_Task"] = reflect.TypeOf((*CertMgrRefreshCACertificatesAndCRLs_Task)(nil)).Elem() +} + +type CertMgrRefreshCACertificatesAndCRLs_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CertMgrRefreshCertificatesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["CertMgrRefreshCertificatesRequestType"] = reflect.TypeOf((*CertMgrRefreshCertificatesRequestType)(nil)).Elem() +} + +type CertMgrRefreshCertificates_Task CertMgrRefreshCertificatesRequestType + +func init() { + t["CertMgrRefreshCertificates_Task"] = reflect.TypeOf((*CertMgrRefreshCertificates_Task)(nil)).Elem() +} + +type CertMgrRefreshCertificates_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CertMgrRevokeCertificatesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["CertMgrRevokeCertificatesRequestType"] = reflect.TypeOf((*CertMgrRevokeCertificatesRequestType)(nil)).Elem() +} + +type CertMgrRevokeCertificates_Task CertMgrRevokeCertificatesRequestType + +func init() { + t["CertMgrRevokeCertificates_Task"] = reflect.TypeOf((*CertMgrRevokeCertificates_Task)(nil)).Elem() +} + +type CertMgrRevokeCertificates_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ChangeAccessMode ChangeAccessModeRequestType + +func init() { + t["ChangeAccessMode"] = reflect.TypeOf((*ChangeAccessMode)(nil)).Elem() +} + +type ChangeAccessModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Principal string `xml:"principal"` + IsGroup bool `xml:"isGroup"` + AccessMode HostAccessMode `xml:"accessMode"` +} + +func init() { + t["ChangeAccessModeRequestType"] = reflect.TypeOf((*ChangeAccessModeRequestType)(nil)).Elem() +} + +type ChangeAccessModeResponse struct { +} + +type ChangeFileAttributesInGuest ChangeFileAttributesInGuestRequestType + +func init() { + t["ChangeFileAttributesInGuest"] = reflect.TypeOf((*ChangeFileAttributesInGuest)(nil)).Elem() +} + +type ChangeFileAttributesInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + GuestFilePath string `xml:"guestFilePath"` + FileAttributes BaseGuestFileAttributes `xml:"fileAttributes,typeattr"` +} + +func init() { + t["ChangeFileAttributesInGuestRequestType"] = reflect.TypeOf((*ChangeFileAttributesInGuestRequestType)(nil)).Elem() +} + +type ChangeFileAttributesInGuestResponse struct { +} + +type ChangeLockdownMode ChangeLockdownModeRequestType + +func init() { + t["ChangeLockdownMode"] = reflect.TypeOf((*ChangeLockdownMode)(nil)).Elem() +} + +type ChangeLockdownModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Mode HostLockdownMode `xml:"mode"` +} + +func init() { + t["ChangeLockdownModeRequestType"] = reflect.TypeOf((*ChangeLockdownModeRequestType)(nil)).Elem() +} + +type ChangeLockdownModeResponse struct { +} + +type ChangeNFSUserPassword ChangeNFSUserPasswordRequestType + +func init() { + t["ChangeNFSUserPassword"] = reflect.TypeOf((*ChangeNFSUserPassword)(nil)).Elem() +} + +type ChangeNFSUserPasswordRequestType struct { + This ManagedObjectReference `xml:"_this"` + Password string `xml:"password"` +} + +func init() { + t["ChangeNFSUserPasswordRequestType"] = reflect.TypeOf((*ChangeNFSUserPasswordRequestType)(nil)).Elem() +} + +type ChangeNFSUserPasswordResponse struct { +} + +type ChangeOwner ChangeOwnerRequestType + +func init() { + t["ChangeOwner"] = reflect.TypeOf((*ChangeOwner)(nil)).Elem() +} + +type ChangeOwnerRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Owner string `xml:"owner"` +} + +func init() { + t["ChangeOwnerRequestType"] = reflect.TypeOf((*ChangeOwnerRequestType)(nil)).Elem() +} + +type ChangeOwnerResponse struct { +} + +type CheckAddHostEvcRequestType struct { + This ManagedObjectReference `xml:"_this"` + CnxSpec HostConnectSpec `xml:"cnxSpec"` +} + +func init() { + t["CheckAddHostEvcRequestType"] = reflect.TypeOf((*CheckAddHostEvcRequestType)(nil)).Elem() +} + +type CheckAddHostEvc_Task CheckAddHostEvcRequestType + +func init() { + t["CheckAddHostEvc_Task"] = reflect.TypeOf((*CheckAddHostEvc_Task)(nil)).Elem() +} + +type CheckAddHostEvc_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckAnswerFileStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["CheckAnswerFileStatusRequestType"] = reflect.TypeOf((*CheckAnswerFileStatusRequestType)(nil)).Elem() +} + +type CheckAnswerFileStatus_Task CheckAnswerFileStatusRequestType + +func init() { + t["CheckAnswerFileStatus_Task"] = reflect.TypeOf((*CheckAnswerFileStatus_Task)(nil)).Elem() +} + +type CheckAnswerFileStatus_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckCompatibilityRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` + TestType []string `xml:"testType,omitempty"` +} + +func init() { + t["CheckCompatibilityRequestType"] = reflect.TypeOf((*CheckCompatibilityRequestType)(nil)).Elem() +} + +type CheckCompatibility_Task CheckCompatibilityRequestType + +func init() { + t["CheckCompatibility_Task"] = reflect.TypeOf((*CheckCompatibility_Task)(nil)).Elem() +} + +type CheckCompatibility_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckComplianceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Profile []ManagedObjectReference `xml:"profile,omitempty"` + Entity []ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["CheckComplianceRequestType"] = reflect.TypeOf((*CheckComplianceRequestType)(nil)).Elem() +} + +type CheckCompliance_Task CheckComplianceRequestType + +func init() { + t["CheckCompliance_Task"] = reflect.TypeOf((*CheckCompliance_Task)(nil)).Elem() +} + +type CheckCompliance_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckConfigureEvcModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + EvcModeKey string `xml:"evcModeKey"` +} + +func init() { + t["CheckConfigureEvcModeRequestType"] = reflect.TypeOf((*CheckConfigureEvcModeRequestType)(nil)).Elem() +} + +type CheckConfigureEvcMode_Task CheckConfigureEvcModeRequestType + +func init() { + t["CheckConfigureEvcMode_Task"] = reflect.TypeOf((*CheckConfigureEvcMode_Task)(nil)).Elem() +} + +type CheckConfigureEvcMode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckCustomizationResources CheckCustomizationResourcesRequestType + +func init() { + t["CheckCustomizationResources"] = reflect.TypeOf((*CheckCustomizationResources)(nil)).Elem() +} + +type CheckCustomizationResourcesRequestType struct { + This ManagedObjectReference `xml:"_this"` + GuestOs string `xml:"guestOs"` +} + +func init() { + t["CheckCustomizationResourcesRequestType"] = reflect.TypeOf((*CheckCustomizationResourcesRequestType)(nil)).Elem() +} + +type CheckCustomizationResourcesResponse struct { +} + +type CheckCustomizationSpec CheckCustomizationSpecRequestType + +func init() { + t["CheckCustomizationSpec"] = reflect.TypeOf((*CheckCustomizationSpec)(nil)).Elem() +} + +type CheckCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec CustomizationSpec `xml:"spec"` +} + +func init() { + t["CheckCustomizationSpecRequestType"] = reflect.TypeOf((*CheckCustomizationSpecRequestType)(nil)).Elem() +} + +type CheckCustomizationSpecResponse struct { +} + +type CheckForUpdates CheckForUpdatesRequestType + +func init() { + t["CheckForUpdates"] = reflect.TypeOf((*CheckForUpdates)(nil)).Elem() +} + +type CheckForUpdatesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Version string `xml:"version,omitempty"` +} + +func init() { + t["CheckForUpdatesRequestType"] = reflect.TypeOf((*CheckForUpdatesRequestType)(nil)).Elem() +} + +type CheckForUpdatesResponse struct { + Returnval *UpdateSet `xml:"returnval,omitempty"` +} + +type CheckHostPatchRequestType struct { + This ManagedObjectReference `xml:"_this"` + MetaUrls []string `xml:"metaUrls,omitempty"` + BundleUrls []string `xml:"bundleUrls,omitempty"` + Spec *HostPatchManagerPatchManagerOperationSpec `xml:"spec,omitempty"` +} + +func init() { + t["CheckHostPatchRequestType"] = reflect.TypeOf((*CheckHostPatchRequestType)(nil)).Elem() +} + +type CheckHostPatch_Task CheckHostPatchRequestType + +func init() { + t["CheckHostPatch_Task"] = reflect.TypeOf((*CheckHostPatch_Task)(nil)).Elem() +} + +type CheckHostPatch_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckLicenseFeature CheckLicenseFeatureRequestType + +func init() { + t["CheckLicenseFeature"] = reflect.TypeOf((*CheckLicenseFeature)(nil)).Elem() +} + +type CheckLicenseFeatureRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + FeatureKey string `xml:"featureKey"` +} + +func init() { + t["CheckLicenseFeatureRequestType"] = reflect.TypeOf((*CheckLicenseFeatureRequestType)(nil)).Elem() +} + +type CheckLicenseFeatureResponse struct { + Returnval bool `xml:"returnval"` +} + +type CheckMigrateRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` + State VirtualMachinePowerState `xml:"state,omitempty"` + TestType []string `xml:"testType,omitempty"` +} + +func init() { + t["CheckMigrateRequestType"] = reflect.TypeOf((*CheckMigrateRequestType)(nil)).Elem() +} + +type CheckMigrate_Task CheckMigrateRequestType + +func init() { + t["CheckMigrate_Task"] = reflect.TypeOf((*CheckMigrate_Task)(nil)).Elem() +} + +type CheckMigrate_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckProfileComplianceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity []ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["CheckProfileComplianceRequestType"] = reflect.TypeOf((*CheckProfileComplianceRequestType)(nil)).Elem() +} + +type CheckProfileCompliance_Task CheckProfileComplianceRequestType + +func init() { + t["CheckProfileCompliance_Task"] = reflect.TypeOf((*CheckProfileCompliance_Task)(nil)).Elem() +} + +type CheckProfileCompliance_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckRelocateRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Spec VirtualMachineRelocateSpec `xml:"spec"` + TestType []string `xml:"testType,omitempty"` +} + +func init() { + t["CheckRelocateRequestType"] = reflect.TypeOf((*CheckRelocateRequestType)(nil)).Elem() +} + +type CheckRelocate_Task CheckRelocateRequestType + +func init() { + t["CheckRelocate_Task"] = reflect.TypeOf((*CheckRelocate_Task)(nil)).Elem() +} + +type CheckRelocate_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CheckResult struct { + DynamicData + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Warning []LocalizedMethodFault `xml:"warning,omitempty"` + Error []LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["CheckResult"] = reflect.TypeOf((*CheckResult)(nil)).Elem() +} + +type ChoiceOption struct { + OptionType + + ChoiceInfo []BaseElementDescription `xml:"choiceInfo,typeattr"` + DefaultIndex int32 `xml:"defaultIndex,omitempty"` +} + +func init() { + t["ChoiceOption"] = reflect.TypeOf((*ChoiceOption)(nil)).Elem() +} + +type ClearComplianceStatus ClearComplianceStatusRequestType + +func init() { + t["ClearComplianceStatus"] = reflect.TypeOf((*ClearComplianceStatus)(nil)).Elem() +} + +type ClearComplianceStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + Profile []ManagedObjectReference `xml:"profile,omitempty"` + Entity []ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["ClearComplianceStatusRequestType"] = reflect.TypeOf((*ClearComplianceStatusRequestType)(nil)).Elem() +} + +type ClearComplianceStatusResponse struct { +} + +type ClearNFSUser ClearNFSUserRequestType + +func init() { + t["ClearNFSUser"] = reflect.TypeOf((*ClearNFSUser)(nil)).Elem() +} + +type ClearNFSUserRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ClearNFSUserRequestType"] = reflect.TypeOf((*ClearNFSUserRequestType)(nil)).Elem() +} + +type ClearNFSUserResponse struct { +} + +type ClockSkew struct { + HostConfigFault +} + +func init() { + t["ClockSkew"] = reflect.TypeOf((*ClockSkew)(nil)).Elem() +} + +type ClockSkewFault ClockSkew + +func init() { + t["ClockSkewFault"] = reflect.TypeOf((*ClockSkewFault)(nil)).Elem() +} + +type CloneFromSnapshotNotSupported struct { + MigrationFault +} + +func init() { + t["CloneFromSnapshotNotSupported"] = reflect.TypeOf((*CloneFromSnapshotNotSupported)(nil)).Elem() +} + +type CloneFromSnapshotNotSupportedFault CloneFromSnapshotNotSupported + +func init() { + t["CloneFromSnapshotNotSupportedFault"] = reflect.TypeOf((*CloneFromSnapshotNotSupportedFault)(nil)).Elem() +} + +type CloneSession CloneSessionRequestType + +func init() { + t["CloneSession"] = reflect.TypeOf((*CloneSession)(nil)).Elem() +} + +type CloneSessionRequestType struct { + This ManagedObjectReference `xml:"_this"` + CloneTicket string `xml:"cloneTicket"` +} + +func init() { + t["CloneSessionRequestType"] = reflect.TypeOf((*CloneSessionRequestType)(nil)).Elem() +} + +type CloneSessionResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type CloneVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Target ManagedObjectReference `xml:"target"` + Spec VAppCloneSpec `xml:"spec"` +} + +func init() { + t["CloneVAppRequestType"] = reflect.TypeOf((*CloneVAppRequestType)(nil)).Elem() +} + +type CloneVApp_Task CloneVAppRequestType + +func init() { + t["CloneVApp_Task"] = reflect.TypeOf((*CloneVApp_Task)(nil)).Elem() +} + +type CloneVApp_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CloneVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Folder ManagedObjectReference `xml:"folder"` + Name string `xml:"name"` + Spec VirtualMachineCloneSpec `xml:"spec"` +} + +func init() { + t["CloneVMRequestType"] = reflect.TypeOf((*CloneVMRequestType)(nil)).Elem() +} + +type CloneVM_Task CloneVMRequestType + +func init() { + t["CloneVM_Task"] = reflect.TypeOf((*CloneVM_Task)(nil)).Elem() +} + +type CloneVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CloseInventoryViewFolder CloseInventoryViewFolderRequestType + +func init() { + t["CloseInventoryViewFolder"] = reflect.TypeOf((*CloseInventoryViewFolder)(nil)).Elem() +} + +type CloseInventoryViewFolderRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity []ManagedObjectReference `xml:"entity"` +} + +func init() { + t["CloseInventoryViewFolderRequestType"] = reflect.TypeOf((*CloseInventoryViewFolderRequestType)(nil)).Elem() +} + +type CloseInventoryViewFolderResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type ClusterAction struct { + DynamicData + + Type string `xml:"type"` + Target *ManagedObjectReference `xml:"target,omitempty"` +} + +func init() { + t["ClusterAction"] = reflect.TypeOf((*ClusterAction)(nil)).Elem() +} + +type ClusterActionHistory struct { + DynamicData + + Action BaseClusterAction `xml:"action,typeattr"` + Time time.Time `xml:"time"` +} + +func init() { + t["ClusterActionHistory"] = reflect.TypeOf((*ClusterActionHistory)(nil)).Elem() +} + +type ClusterAffinityRuleSpec struct { + ClusterRuleInfo + + Vm []ManagedObjectReference `xml:"vm"` +} + +func init() { + t["ClusterAffinityRuleSpec"] = reflect.TypeOf((*ClusterAffinityRuleSpec)(nil)).Elem() +} + +type ClusterAntiAffinityRuleSpec struct { + ClusterRuleInfo + + Vm []ManagedObjectReference `xml:"vm"` +} + +func init() { + t["ClusterAntiAffinityRuleSpec"] = reflect.TypeOf((*ClusterAntiAffinityRuleSpec)(nil)).Elem() +} + +type ClusterAttemptedVmInfo struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + Task *ManagedObjectReference `xml:"task,omitempty"` +} + +func init() { + t["ClusterAttemptedVmInfo"] = reflect.TypeOf((*ClusterAttemptedVmInfo)(nil)).Elem() +} + +type ClusterComplianceCheckedEvent struct { + ClusterEvent + + Profile ProfileEventArgument `xml:"profile"` +} + +func init() { + t["ClusterComplianceCheckedEvent"] = reflect.TypeOf((*ClusterComplianceCheckedEvent)(nil)).Elem() +} + +type ClusterComputeResourceSummary struct { + ComputeResourceSummary + + CurrentFailoverLevel int32 `xml:"currentFailoverLevel"` + AdmissionControlInfo BaseClusterDasAdmissionControlInfo `xml:"admissionControlInfo,omitempty,typeattr"` + NumVmotions int32 `xml:"numVmotions"` + TargetBalance int32 `xml:"targetBalance,omitempty"` + CurrentBalance int32 `xml:"currentBalance,omitempty"` + UsageSummary *ClusterUsageSummary `xml:"usageSummary,omitempty"` + CurrentEVCModeKey string `xml:"currentEVCModeKey,omitempty"` + DasData BaseClusterDasData `xml:"dasData,omitempty,typeattr"` +} + +func init() { + t["ClusterComputeResourceSummary"] = reflect.TypeOf((*ClusterComputeResourceSummary)(nil)).Elem() +} + +type ClusterConfigInfo struct { + DynamicData + + DasConfig ClusterDasConfigInfo `xml:"dasConfig"` + DasVmConfig []ClusterDasVmConfigInfo `xml:"dasVmConfig,omitempty"` + DrsConfig ClusterDrsConfigInfo `xml:"drsConfig"` + DrsVmConfig []ClusterDrsVmConfigInfo `xml:"drsVmConfig,omitempty"` + Rule []BaseClusterRuleInfo `xml:"rule,omitempty,typeattr"` +} + +func init() { + t["ClusterConfigInfo"] = reflect.TypeOf((*ClusterConfigInfo)(nil)).Elem() +} + +type ClusterConfigInfoEx struct { + ComputeResourceConfigInfo + + DasConfig ClusterDasConfigInfo `xml:"dasConfig"` + DasVmConfig []ClusterDasVmConfigInfo `xml:"dasVmConfig,omitempty"` + DrsConfig ClusterDrsConfigInfo `xml:"drsConfig"` + DrsVmConfig []ClusterDrsVmConfigInfo `xml:"drsVmConfig,omitempty"` + Rule []BaseClusterRuleInfo `xml:"rule,omitempty,typeattr"` + DpmConfigInfo *ClusterDpmConfigInfo `xml:"dpmConfigInfo,omitempty"` + DpmHostConfig []ClusterDpmHostConfigInfo `xml:"dpmHostConfig,omitempty"` + VsanConfigInfo *VsanClusterConfigInfo `xml:"vsanConfigInfo,omitempty"` + VsanHostConfig []VsanHostConfigInfo `xml:"vsanHostConfig,omitempty"` + Group []BaseClusterGroupInfo `xml:"group,omitempty,typeattr"` +} + +func init() { + t["ClusterConfigInfoEx"] = reflect.TypeOf((*ClusterConfigInfoEx)(nil)).Elem() +} + +type ClusterConfigSpec struct { + DynamicData + + DasConfig *ClusterDasConfigInfo `xml:"dasConfig,omitempty"` + DasVmConfigSpec []ClusterDasVmConfigSpec `xml:"dasVmConfigSpec,omitempty"` + DrsConfig *ClusterDrsConfigInfo `xml:"drsConfig,omitempty"` + DrsVmConfigSpec []ClusterDrsVmConfigSpec `xml:"drsVmConfigSpec,omitempty"` + RulesSpec []ClusterRuleSpec `xml:"rulesSpec,omitempty"` +} + +func init() { + t["ClusterConfigSpec"] = reflect.TypeOf((*ClusterConfigSpec)(nil)).Elem() +} + +type ClusterConfigSpecEx struct { + ComputeResourceConfigSpec + + DasConfig *ClusterDasConfigInfo `xml:"dasConfig,omitempty"` + DasVmConfigSpec []ClusterDasVmConfigSpec `xml:"dasVmConfigSpec,omitempty"` + DrsConfig *ClusterDrsConfigInfo `xml:"drsConfig,omitempty"` + DrsVmConfigSpec []ClusterDrsVmConfigSpec `xml:"drsVmConfigSpec,omitempty"` + RulesSpec []ClusterRuleSpec `xml:"rulesSpec,omitempty"` + DpmConfig *ClusterDpmConfigInfo `xml:"dpmConfig,omitempty"` + DpmHostConfigSpec []ClusterDpmHostConfigSpec `xml:"dpmHostConfigSpec,omitempty"` + VsanConfig *VsanClusterConfigInfo `xml:"vsanConfig,omitempty"` + VsanHostConfigSpec []VsanHostConfigInfo `xml:"vsanHostConfigSpec,omitempty"` + GroupSpec []ClusterGroupSpec `xml:"groupSpec,omitempty"` +} + +func init() { + t["ClusterConfigSpecEx"] = reflect.TypeOf((*ClusterConfigSpecEx)(nil)).Elem() +} + +type ClusterCreatedEvent struct { + ClusterEvent + + Parent FolderEventArgument `xml:"parent"` +} + +func init() { + t["ClusterCreatedEvent"] = reflect.TypeOf((*ClusterCreatedEvent)(nil)).Elem() +} + +type ClusterDasAamHostInfo struct { + ClusterDasHostInfo + + HostDasState []ClusterDasAamNodeState `xml:"hostDasState,omitempty"` + PrimaryHosts []string `xml:"primaryHosts,omitempty"` +} + +func init() { + t["ClusterDasAamHostInfo"] = reflect.TypeOf((*ClusterDasAamHostInfo)(nil)).Elem() +} + +type ClusterDasAamNodeState struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Name string `xml:"name"` + ConfigState string `xml:"configState"` + RuntimeState string `xml:"runtimeState"` +} + +func init() { + t["ClusterDasAamNodeState"] = reflect.TypeOf((*ClusterDasAamNodeState)(nil)).Elem() +} + +type ClusterDasAdmissionControlInfo struct { + DynamicData +} + +func init() { + t["ClusterDasAdmissionControlInfo"] = reflect.TypeOf((*ClusterDasAdmissionControlInfo)(nil)).Elem() +} + +type ClusterDasAdmissionControlPolicy struct { + DynamicData +} + +func init() { + t["ClusterDasAdmissionControlPolicy"] = reflect.TypeOf((*ClusterDasAdmissionControlPolicy)(nil)).Elem() +} + +type ClusterDasAdvancedRuntimeInfo struct { + DynamicData + + DasHostInfo BaseClusterDasHostInfo `xml:"dasHostInfo,omitempty,typeattr"` + VmcpSupported *ClusterDasAdvancedRuntimeInfoVmcpCapabilityInfo `xml:"vmcpSupported,omitempty"` + HeartbeatDatastoreInfo []DasHeartbeatDatastoreInfo `xml:"heartbeatDatastoreInfo,omitempty"` +} + +func init() { + t["ClusterDasAdvancedRuntimeInfo"] = reflect.TypeOf((*ClusterDasAdvancedRuntimeInfo)(nil)).Elem() +} + +type ClusterDasAdvancedRuntimeInfoVmcpCapabilityInfo struct { + DynamicData + + StorageAPDSupported bool `xml:"storageAPDSupported"` + StoragePDLSupported bool `xml:"storagePDLSupported"` +} + +func init() { + t["ClusterDasAdvancedRuntimeInfoVmcpCapabilityInfo"] = reflect.TypeOf((*ClusterDasAdvancedRuntimeInfoVmcpCapabilityInfo)(nil)).Elem() +} + +type ClusterDasConfigInfo struct { + DynamicData + + Enabled *bool `xml:"enabled"` + VmMonitoring string `xml:"vmMonitoring,omitempty"` + HostMonitoring string `xml:"hostMonitoring,omitempty"` + VmComponentProtecting string `xml:"vmComponentProtecting,omitempty"` + FailoverLevel int32 `xml:"failoverLevel,omitempty"` + AdmissionControlPolicy BaseClusterDasAdmissionControlPolicy `xml:"admissionControlPolicy,omitempty,typeattr"` + AdmissionControlEnabled *bool `xml:"admissionControlEnabled"` + DefaultVmSettings *ClusterDasVmSettings `xml:"defaultVmSettings,omitempty"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` + HeartbeatDatastore []ManagedObjectReference `xml:"heartbeatDatastore,omitempty"` + HBDatastoreCandidatePolicy string `xml:"hBDatastoreCandidatePolicy,omitempty"` +} + +func init() { + t["ClusterDasConfigInfo"] = reflect.TypeOf((*ClusterDasConfigInfo)(nil)).Elem() +} + +type ClusterDasData struct { + DynamicData +} + +func init() { + t["ClusterDasData"] = reflect.TypeOf((*ClusterDasData)(nil)).Elem() +} + +type ClusterDasDataSummary struct { + ClusterDasData + + HostListVersion int64 `xml:"hostListVersion"` + ClusterConfigVersion int64 `xml:"clusterConfigVersion"` + CompatListVersion int64 `xml:"compatListVersion"` +} + +func init() { + t["ClusterDasDataSummary"] = reflect.TypeOf((*ClusterDasDataSummary)(nil)).Elem() +} + +type ClusterDasFailoverLevelAdvancedRuntimeInfo struct { + ClusterDasAdvancedRuntimeInfo + + SlotInfo ClusterDasFailoverLevelAdvancedRuntimeInfoSlotInfo `xml:"slotInfo"` + TotalSlots int32 `xml:"totalSlots"` + UsedSlots int32 `xml:"usedSlots"` + UnreservedSlots int32 `xml:"unreservedSlots"` + TotalVms int32 `xml:"totalVms"` + TotalHosts int32 `xml:"totalHosts"` + TotalGoodHosts int32 `xml:"totalGoodHosts"` + HostSlots []ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots `xml:"hostSlots,omitempty"` + VmsRequiringMultipleSlots []ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots `xml:"vmsRequiringMultipleSlots,omitempty"` +} + +func init() { + t["ClusterDasFailoverLevelAdvancedRuntimeInfo"] = reflect.TypeOf((*ClusterDasFailoverLevelAdvancedRuntimeInfo)(nil)).Elem() +} + +type ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Slots int32 `xml:"slots"` +} + +func init() { + t["ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots"] = reflect.TypeOf((*ClusterDasFailoverLevelAdvancedRuntimeInfoHostSlots)(nil)).Elem() +} + +type ClusterDasFailoverLevelAdvancedRuntimeInfoSlotInfo struct { + DynamicData + + NumVcpus int32 `xml:"numVcpus"` + CpuMHz int32 `xml:"cpuMHz"` + MemoryMB int32 `xml:"memoryMB"` +} + +func init() { + t["ClusterDasFailoverLevelAdvancedRuntimeInfoSlotInfo"] = reflect.TypeOf((*ClusterDasFailoverLevelAdvancedRuntimeInfoSlotInfo)(nil)).Elem() +} + +type ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + Slots int32 `xml:"slots"` +} + +func init() { + t["ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots"] = reflect.TypeOf((*ClusterDasFailoverLevelAdvancedRuntimeInfoVmSlots)(nil)).Elem() +} + +type ClusterDasFdmHostState struct { + DynamicData + + State string `xml:"state"` + StateReporter *ManagedObjectReference `xml:"stateReporter,omitempty"` +} + +func init() { + t["ClusterDasFdmHostState"] = reflect.TypeOf((*ClusterDasFdmHostState)(nil)).Elem() +} + +type ClusterDasHostInfo struct { + DynamicData +} + +func init() { + t["ClusterDasHostInfo"] = reflect.TypeOf((*ClusterDasHostInfo)(nil)).Elem() +} + +type ClusterDasHostRecommendation struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + DrsRating int32 `xml:"drsRating,omitempty"` +} + +func init() { + t["ClusterDasHostRecommendation"] = reflect.TypeOf((*ClusterDasHostRecommendation)(nil)).Elem() +} + +type ClusterDasVmConfigInfo struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + RestartPriority DasVmPriority `xml:"restartPriority,omitempty"` + PowerOffOnIsolation *bool `xml:"powerOffOnIsolation"` + DasSettings *ClusterDasVmSettings `xml:"dasSettings,omitempty"` +} + +func init() { + t["ClusterDasVmConfigInfo"] = reflect.TypeOf((*ClusterDasVmConfigInfo)(nil)).Elem() +} + +type ClusterDasVmConfigSpec struct { + ArrayUpdateSpec + + Info *ClusterDasVmConfigInfo `xml:"info,omitempty"` +} + +func init() { + t["ClusterDasVmConfigSpec"] = reflect.TypeOf((*ClusterDasVmConfigSpec)(nil)).Elem() +} + +type ClusterDasVmSettings struct { + DynamicData + + RestartPriority string `xml:"restartPriority,omitempty"` + IsolationResponse string `xml:"isolationResponse,omitempty"` + VmToolsMonitoringSettings *ClusterVmToolsMonitoringSettings `xml:"vmToolsMonitoringSettings,omitempty"` + VmComponentProtectionSettings *ClusterVmComponentProtectionSettings `xml:"vmComponentProtectionSettings,omitempty"` +} + +func init() { + t["ClusterDasVmSettings"] = reflect.TypeOf((*ClusterDasVmSettings)(nil)).Elem() +} + +type ClusterDestroyedEvent struct { + ClusterEvent +} + +func init() { + t["ClusterDestroyedEvent"] = reflect.TypeOf((*ClusterDestroyedEvent)(nil)).Elem() +} + +type ClusterDpmConfigInfo struct { + DynamicData + + Enabled *bool `xml:"enabled"` + DefaultDpmBehavior DpmBehavior `xml:"defaultDpmBehavior,omitempty"` + HostPowerActionRate int32 `xml:"hostPowerActionRate,omitempty"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` +} + +func init() { + t["ClusterDpmConfigInfo"] = reflect.TypeOf((*ClusterDpmConfigInfo)(nil)).Elem() +} + +type ClusterDpmHostConfigInfo struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + Enabled *bool `xml:"enabled"` + Behavior DpmBehavior `xml:"behavior,omitempty"` +} + +func init() { + t["ClusterDpmHostConfigInfo"] = reflect.TypeOf((*ClusterDpmHostConfigInfo)(nil)).Elem() +} + +type ClusterDpmHostConfigSpec struct { + ArrayUpdateSpec + + Info *ClusterDpmHostConfigInfo `xml:"info,omitempty"` +} + +func init() { + t["ClusterDpmHostConfigSpec"] = reflect.TypeOf((*ClusterDpmHostConfigSpec)(nil)).Elem() +} + +type ClusterDrsConfigInfo struct { + DynamicData + + Enabled *bool `xml:"enabled"` + EnableVmBehaviorOverrides *bool `xml:"enableVmBehaviorOverrides"` + DefaultVmBehavior DrsBehavior `xml:"defaultVmBehavior,omitempty"` + VmotionRate int32 `xml:"vmotionRate,omitempty"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` +} + +func init() { + t["ClusterDrsConfigInfo"] = reflect.TypeOf((*ClusterDrsConfigInfo)(nil)).Elem() +} + +type ClusterDrsFaults struct { + DynamicData + + Reason string `xml:"reason"` + FaultsByVm []BaseClusterDrsFaultsFaultsByVm `xml:"faultsByVm,typeattr"` +} + +func init() { + t["ClusterDrsFaults"] = reflect.TypeOf((*ClusterDrsFaults)(nil)).Elem() +} + +type ClusterDrsFaultsFaultsByVirtualDisk struct { + ClusterDrsFaultsFaultsByVm + + Disk *VirtualDiskId `xml:"disk,omitempty"` +} + +func init() { + t["ClusterDrsFaultsFaultsByVirtualDisk"] = reflect.TypeOf((*ClusterDrsFaultsFaultsByVirtualDisk)(nil)).Elem() +} + +type ClusterDrsFaultsFaultsByVm struct { + DynamicData + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + Fault []LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["ClusterDrsFaultsFaultsByVm"] = reflect.TypeOf((*ClusterDrsFaultsFaultsByVm)(nil)).Elem() +} + +type ClusterDrsMigration struct { + DynamicData + + Key string `xml:"key"` + Time time.Time `xml:"time"` + Vm ManagedObjectReference `xml:"vm"` + CpuLoad int32 `xml:"cpuLoad,omitempty"` + MemoryLoad int64 `xml:"memoryLoad,omitempty"` + Source ManagedObjectReference `xml:"source"` + SourceCpuLoad int32 `xml:"sourceCpuLoad,omitempty"` + SourceMemoryLoad int64 `xml:"sourceMemoryLoad,omitempty"` + Destination ManagedObjectReference `xml:"destination"` + DestinationCpuLoad int32 `xml:"destinationCpuLoad,omitempty"` + DestinationMemoryLoad int64 `xml:"destinationMemoryLoad,omitempty"` +} + +func init() { + t["ClusterDrsMigration"] = reflect.TypeOf((*ClusterDrsMigration)(nil)).Elem() +} + +type ClusterDrsRecommendation struct { + DynamicData + + Key string `xml:"key"` + Rating int32 `xml:"rating"` + Reason string `xml:"reason"` + ReasonText string `xml:"reasonText"` + MigrationList []ClusterDrsMigration `xml:"migrationList"` +} + +func init() { + t["ClusterDrsRecommendation"] = reflect.TypeOf((*ClusterDrsRecommendation)(nil)).Elem() +} + +type ClusterDrsVmConfigInfo struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + Enabled *bool `xml:"enabled"` + Behavior DrsBehavior `xml:"behavior,omitempty"` +} + +func init() { + t["ClusterDrsVmConfigInfo"] = reflect.TypeOf((*ClusterDrsVmConfigInfo)(nil)).Elem() +} + +type ClusterDrsVmConfigSpec struct { + ArrayUpdateSpec + + Info *ClusterDrsVmConfigInfo `xml:"info,omitempty"` +} + +func init() { + t["ClusterDrsVmConfigSpec"] = reflect.TypeOf((*ClusterDrsVmConfigSpec)(nil)).Elem() +} + +type ClusterEVCManagerCheckResult struct { + DynamicData + + EvcModeKey string `xml:"evcModeKey"` + Error LocalizedMethodFault `xml:"error"` + Host []ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["ClusterEVCManagerCheckResult"] = reflect.TypeOf((*ClusterEVCManagerCheckResult)(nil)).Elem() +} + +type ClusterEVCManagerEVCState struct { + DynamicData + + SupportedEVCMode []EVCMode `xml:"supportedEVCMode"` + CurrentEVCModeKey string `xml:"currentEVCModeKey,omitempty"` + GuaranteedCPUFeatures []HostCpuIdInfo `xml:"guaranteedCPUFeatures,omitempty"` + FeatureCapability []HostFeatureCapability `xml:"featureCapability,omitempty"` + FeatureMask []HostFeatureMask `xml:"featureMask,omitempty"` + FeatureRequirement []VirtualMachineFeatureRequirement `xml:"featureRequirement,omitempty"` +} + +func init() { + t["ClusterEVCManagerEVCState"] = reflect.TypeOf((*ClusterEVCManagerEVCState)(nil)).Elem() +} + +type ClusterEnterMaintenanceMode ClusterEnterMaintenanceModeRequestType + +func init() { + t["ClusterEnterMaintenanceMode"] = reflect.TypeOf((*ClusterEnterMaintenanceMode)(nil)).Elem() +} + +type ClusterEnterMaintenanceModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` +} + +func init() { + t["ClusterEnterMaintenanceModeRequestType"] = reflect.TypeOf((*ClusterEnterMaintenanceModeRequestType)(nil)).Elem() +} + +type ClusterEnterMaintenanceModeResponse struct { + Returnval ClusterEnterMaintenanceResult `xml:"returnval"` +} + +type ClusterEnterMaintenanceResult struct { + DynamicData + + Recommendations []ClusterRecommendation `xml:"recommendations,omitempty"` + Fault *ClusterDrsFaults `xml:"fault,omitempty"` +} + +func init() { + t["ClusterEnterMaintenanceResult"] = reflect.TypeOf((*ClusterEnterMaintenanceResult)(nil)).Elem() +} + +type ClusterEvent struct { + Event +} + +func init() { + t["ClusterEvent"] = reflect.TypeOf((*ClusterEvent)(nil)).Elem() +} + +type ClusterFailoverHostAdmissionControlInfo struct { + ClusterDasAdmissionControlInfo + + HostStatus []ClusterFailoverHostAdmissionControlInfoHostStatus `xml:"hostStatus,omitempty"` +} + +func init() { + t["ClusterFailoverHostAdmissionControlInfo"] = reflect.TypeOf((*ClusterFailoverHostAdmissionControlInfo)(nil)).Elem() +} + +type ClusterFailoverHostAdmissionControlInfoHostStatus struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Status ManagedEntityStatus `xml:"status"` +} + +func init() { + t["ClusterFailoverHostAdmissionControlInfoHostStatus"] = reflect.TypeOf((*ClusterFailoverHostAdmissionControlInfoHostStatus)(nil)).Elem() +} + +type ClusterFailoverHostAdmissionControlPolicy struct { + ClusterDasAdmissionControlPolicy + + FailoverHosts []ManagedObjectReference `xml:"failoverHosts,omitempty"` +} + +func init() { + t["ClusterFailoverHostAdmissionControlPolicy"] = reflect.TypeOf((*ClusterFailoverHostAdmissionControlPolicy)(nil)).Elem() +} + +type ClusterFailoverLevelAdmissionControlInfo struct { + ClusterDasAdmissionControlInfo + + CurrentFailoverLevel int32 `xml:"currentFailoverLevel"` +} + +func init() { + t["ClusterFailoverLevelAdmissionControlInfo"] = reflect.TypeOf((*ClusterFailoverLevelAdmissionControlInfo)(nil)).Elem() +} + +type ClusterFailoverLevelAdmissionControlPolicy struct { + ClusterDasAdmissionControlPolicy + + FailoverLevel int32 `xml:"failoverLevel"` + SlotPolicy BaseClusterSlotPolicy `xml:"slotPolicy,omitempty,typeattr"` +} + +func init() { + t["ClusterFailoverLevelAdmissionControlPolicy"] = reflect.TypeOf((*ClusterFailoverLevelAdmissionControlPolicy)(nil)).Elem() +} + +type ClusterFailoverResourcesAdmissionControlInfo struct { + ClusterDasAdmissionControlInfo + + CurrentCpuFailoverResourcesPercent int32 `xml:"currentCpuFailoverResourcesPercent"` + CurrentMemoryFailoverResourcesPercent int32 `xml:"currentMemoryFailoverResourcesPercent"` +} + +func init() { + t["ClusterFailoverResourcesAdmissionControlInfo"] = reflect.TypeOf((*ClusterFailoverResourcesAdmissionControlInfo)(nil)).Elem() +} + +type ClusterFailoverResourcesAdmissionControlPolicy struct { + ClusterDasAdmissionControlPolicy + + CpuFailoverResourcesPercent int32 `xml:"cpuFailoverResourcesPercent"` + MemoryFailoverResourcesPercent int32 `xml:"memoryFailoverResourcesPercent"` +} + +func init() { + t["ClusterFailoverResourcesAdmissionControlPolicy"] = reflect.TypeOf((*ClusterFailoverResourcesAdmissionControlPolicy)(nil)).Elem() +} + +type ClusterFixedSizeSlotPolicy struct { + ClusterSlotPolicy + + Cpu int32 `xml:"cpu"` + Memory int32 `xml:"memory"` +} + +func init() { + t["ClusterFixedSizeSlotPolicy"] = reflect.TypeOf((*ClusterFixedSizeSlotPolicy)(nil)).Elem() +} + +type ClusterGroupInfo struct { + DynamicData + + Name string `xml:"name"` + UserCreated *bool `xml:"userCreated"` + UniqueID string `xml:"uniqueID,omitempty"` +} + +func init() { + t["ClusterGroupInfo"] = reflect.TypeOf((*ClusterGroupInfo)(nil)).Elem() +} + +type ClusterGroupSpec struct { + ArrayUpdateSpec + + Info BaseClusterGroupInfo `xml:"info,omitempty,typeattr"` +} + +func init() { + t["ClusterGroupSpec"] = reflect.TypeOf((*ClusterGroupSpec)(nil)).Elem() +} + +type ClusterHostGroup struct { + ClusterGroupInfo + + Host []ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["ClusterHostGroup"] = reflect.TypeOf((*ClusterHostGroup)(nil)).Elem() +} + +type ClusterHostPowerAction struct { + ClusterAction + + OperationType HostPowerOperationType `xml:"operationType"` + PowerConsumptionWatt int32 `xml:"powerConsumptionWatt,omitempty"` + CpuCapacityMHz int32 `xml:"cpuCapacityMHz,omitempty"` + MemCapacityMB int32 `xml:"memCapacityMB,omitempty"` +} + +func init() { + t["ClusterHostPowerAction"] = reflect.TypeOf((*ClusterHostPowerAction)(nil)).Elem() +} + +type ClusterHostRecommendation struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Rating int32 `xml:"rating"` +} + +func init() { + t["ClusterHostRecommendation"] = reflect.TypeOf((*ClusterHostRecommendation)(nil)).Elem() +} + +type ClusterInitialPlacementAction struct { + ClusterAction + + TargetHost ManagedObjectReference `xml:"targetHost"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` +} + +func init() { + t["ClusterInitialPlacementAction"] = reflect.TypeOf((*ClusterInitialPlacementAction)(nil)).Elem() +} + +type ClusterIoFilterInfo struct { + IoFilterInfo + + OpType string `xml:"opType"` +} + +func init() { + t["ClusterIoFilterInfo"] = reflect.TypeOf((*ClusterIoFilterInfo)(nil)).Elem() +} + +type ClusterMigrationAction struct { + ClusterAction + + DrsMigration *ClusterDrsMigration `xml:"drsMigration,omitempty"` +} + +func init() { + t["ClusterMigrationAction"] = reflect.TypeOf((*ClusterMigrationAction)(nil)).Elem() +} + +type ClusterNotAttemptedVmInfo struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["ClusterNotAttemptedVmInfo"] = reflect.TypeOf((*ClusterNotAttemptedVmInfo)(nil)).Elem() +} + +type ClusterOvercommittedEvent struct { + ClusterEvent +} + +func init() { + t["ClusterOvercommittedEvent"] = reflect.TypeOf((*ClusterOvercommittedEvent)(nil)).Elem() +} + +type ClusterPowerOnVmResult struct { + DynamicData + + Attempted []ClusterAttemptedVmInfo `xml:"attempted,omitempty"` + NotAttempted []ClusterNotAttemptedVmInfo `xml:"notAttempted,omitempty"` + Recommendations []ClusterRecommendation `xml:"recommendations,omitempty"` +} + +func init() { + t["ClusterPowerOnVmResult"] = reflect.TypeOf((*ClusterPowerOnVmResult)(nil)).Elem() +} + +type ClusterProfileCompleteConfigSpec struct { + ClusterProfileConfigSpec + + ComplyProfile *ComplianceProfile `xml:"complyProfile,omitempty"` +} + +func init() { + t["ClusterProfileCompleteConfigSpec"] = reflect.TypeOf((*ClusterProfileCompleteConfigSpec)(nil)).Elem() +} + +type ClusterProfileConfigInfo struct { + ProfileConfigInfo + + ComplyProfile *ComplianceProfile `xml:"complyProfile,omitempty"` +} + +func init() { + t["ClusterProfileConfigInfo"] = reflect.TypeOf((*ClusterProfileConfigInfo)(nil)).Elem() +} + +type ClusterProfileConfigServiceCreateSpec struct { + ClusterProfileConfigSpec + + ServiceType []string `xml:"serviceType,omitempty"` +} + +func init() { + t["ClusterProfileConfigServiceCreateSpec"] = reflect.TypeOf((*ClusterProfileConfigServiceCreateSpec)(nil)).Elem() +} + +type ClusterProfileConfigSpec struct { + ClusterProfileCreateSpec +} + +func init() { + t["ClusterProfileConfigSpec"] = reflect.TypeOf((*ClusterProfileConfigSpec)(nil)).Elem() +} + +type ClusterProfileCreateSpec struct { + ProfileCreateSpec +} + +func init() { + t["ClusterProfileCreateSpec"] = reflect.TypeOf((*ClusterProfileCreateSpec)(nil)).Elem() +} + +type ClusterRecommendation struct { + DynamicData + + Key string `xml:"key"` + Type string `xml:"type"` + Time time.Time `xml:"time"` + Rating int32 `xml:"rating"` + Reason string `xml:"reason"` + ReasonText string `xml:"reasonText"` + WarningText string `xml:"warningText,omitempty"` + WarningDetails *LocalizableMessage `xml:"warningDetails,omitempty"` + Prerequisite []string `xml:"prerequisite,omitempty"` + Action []BaseClusterAction `xml:"action,omitempty,typeattr"` + Target *ManagedObjectReference `xml:"target,omitempty"` +} + +func init() { + t["ClusterRecommendation"] = reflect.TypeOf((*ClusterRecommendation)(nil)).Elem() +} + +type ClusterReconfiguredEvent struct { + ClusterEvent +} + +func init() { + t["ClusterReconfiguredEvent"] = reflect.TypeOf((*ClusterReconfiguredEvent)(nil)).Elem() +} + +type ClusterResourceUsageSummary struct { + DynamicData + + CpuUsedMHz int32 `xml:"cpuUsedMHz"` + CpuCapacityMHz int32 `xml:"cpuCapacityMHz"` + MemUsedMB int32 `xml:"memUsedMB"` + MemCapacityMB int32 `xml:"memCapacityMB"` + StorageUsedMB int64 `xml:"storageUsedMB"` + StorageCapacityMB int64 `xml:"storageCapacityMB"` +} + +func init() { + t["ClusterResourceUsageSummary"] = reflect.TypeOf((*ClusterResourceUsageSummary)(nil)).Elem() +} + +type ClusterRuleInfo struct { + DynamicData + + Key int32 `xml:"key,omitempty"` + Status ManagedEntityStatus `xml:"status,omitempty"` + Enabled *bool `xml:"enabled"` + Name string `xml:"name,omitempty"` + Mandatory *bool `xml:"mandatory"` + UserCreated *bool `xml:"userCreated"` + InCompliance *bool `xml:"inCompliance"` + RuleUuid string `xml:"ruleUuid,omitempty"` +} + +func init() { + t["ClusterRuleInfo"] = reflect.TypeOf((*ClusterRuleInfo)(nil)).Elem() +} + +type ClusterRuleSpec struct { + ArrayUpdateSpec + + Info BaseClusterRuleInfo `xml:"info,omitempty,typeattr"` +} + +func init() { + t["ClusterRuleSpec"] = reflect.TypeOf((*ClusterRuleSpec)(nil)).Elem() +} + +type ClusterSlotPolicy struct { + DynamicData +} + +func init() { + t["ClusterSlotPolicy"] = reflect.TypeOf((*ClusterSlotPolicy)(nil)).Elem() +} + +type ClusterStatusChangedEvent struct { + ClusterEvent + + OldStatus string `xml:"oldStatus"` + NewStatus string `xml:"newStatus"` +} + +func init() { + t["ClusterStatusChangedEvent"] = reflect.TypeOf((*ClusterStatusChangedEvent)(nil)).Elem() +} + +type ClusterUsageSummary struct { + DynamicData + + TotalCpuCapacityMhz int32 `xml:"totalCpuCapacityMhz"` + TotalMemCapacityMB int32 `xml:"totalMemCapacityMB"` + CpuReservationMhz int32 `xml:"cpuReservationMhz"` + MemReservationMB int32 `xml:"memReservationMB"` + PoweredOffCpuReservationMhz int32 `xml:"poweredOffCpuReservationMhz,omitempty"` + PoweredOffMemReservationMB int32 `xml:"poweredOffMemReservationMB,omitempty"` + CpuDemandMhz int32 `xml:"cpuDemandMhz"` + MemDemandMB int32 `xml:"memDemandMB"` + StatsGenNumber int64 `xml:"statsGenNumber"` + CpuEntitledMhz int32 `xml:"cpuEntitledMhz"` + MemEntitledMB int32 `xml:"memEntitledMB"` + PoweredOffVmCount int32 `xml:"poweredOffVmCount"` + TotalVmCount int32 `xml:"totalVmCount"` +} + +func init() { + t["ClusterUsageSummary"] = reflect.TypeOf((*ClusterUsageSummary)(nil)).Elem() +} + +type ClusterVmComponentProtectionSettings struct { + DynamicData + + VmStorageProtectionForAPD string `xml:"vmStorageProtectionForAPD,omitempty"` + EnableAPDTimeoutForHosts *bool `xml:"enableAPDTimeoutForHosts"` + VmTerminateDelayForAPDSec int32 `xml:"vmTerminateDelayForAPDSec,omitempty"` + VmReactionOnAPDCleared string `xml:"vmReactionOnAPDCleared,omitempty"` + VmStorageProtectionForPDL string `xml:"vmStorageProtectionForPDL,omitempty"` +} + +func init() { + t["ClusterVmComponentProtectionSettings"] = reflect.TypeOf((*ClusterVmComponentProtectionSettings)(nil)).Elem() +} + +type ClusterVmGroup struct { + ClusterGroupInfo + + Vm []ManagedObjectReference `xml:"vm,omitempty"` +} + +func init() { + t["ClusterVmGroup"] = reflect.TypeOf((*ClusterVmGroup)(nil)).Elem() +} + +type ClusterVmHostRuleInfo struct { + ClusterRuleInfo + + VmGroupName string `xml:"vmGroupName,omitempty"` + AffineHostGroupName string `xml:"affineHostGroupName,omitempty"` + AntiAffineHostGroupName string `xml:"antiAffineHostGroupName,omitempty"` +} + +func init() { + t["ClusterVmHostRuleInfo"] = reflect.TypeOf((*ClusterVmHostRuleInfo)(nil)).Elem() +} + +type ClusterVmToolsMonitoringSettings struct { + DynamicData + + Enabled *bool `xml:"enabled"` + VmMonitoring string `xml:"vmMonitoring,omitempty"` + ClusterSettings *bool `xml:"clusterSettings"` + FailureInterval int32 `xml:"failureInterval,omitempty"` + MinUpTime int32 `xml:"minUpTime,omitempty"` + MaxFailures int32 `xml:"maxFailures,omitempty"` + MaxFailureWindow int32 `xml:"maxFailureWindow,omitempty"` +} + +func init() { + t["ClusterVmToolsMonitoringSettings"] = reflect.TypeOf((*ClusterVmToolsMonitoringSettings)(nil)).Elem() +} + +type CollectorAddressUnset struct { + DvsFault +} + +func init() { + t["CollectorAddressUnset"] = reflect.TypeOf((*CollectorAddressUnset)(nil)).Elem() +} + +type CollectorAddressUnsetFault CollectorAddressUnset + +func init() { + t["CollectorAddressUnsetFault"] = reflect.TypeOf((*CollectorAddressUnsetFault)(nil)).Elem() +} + +type ComplianceFailure struct { + DynamicData + + FailureType string `xml:"failureType"` + Message LocalizableMessage `xml:"message"` + ExpressionName string `xml:"expressionName,omitempty"` +} + +func init() { + t["ComplianceFailure"] = reflect.TypeOf((*ComplianceFailure)(nil)).Elem() +} + +type ComplianceLocator struct { + DynamicData + + ExpressionName string `xml:"expressionName"` + ApplyPath ProfilePropertyPath `xml:"applyPath"` +} + +func init() { + t["ComplianceLocator"] = reflect.TypeOf((*ComplianceLocator)(nil)).Elem() +} + +type ComplianceProfile struct { + DynamicData + + Expression []BaseProfileExpression `xml:"expression,typeattr"` + RootExpression string `xml:"rootExpression"` +} + +func init() { + t["ComplianceProfile"] = reflect.TypeOf((*ComplianceProfile)(nil)).Elem() +} + +type ComplianceResult struct { + DynamicData + + Profile *ManagedObjectReference `xml:"profile,omitempty"` + ComplianceStatus string `xml:"complianceStatus"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` + CheckTime *time.Time `xml:"checkTime"` + Failure []ComplianceFailure `xml:"failure,omitempty"` +} + +func init() { + t["ComplianceResult"] = reflect.TypeOf((*ComplianceResult)(nil)).Elem() +} + +type CompositePolicyOption struct { + PolicyOption + + Option []BasePolicyOption `xml:"option,omitempty,typeattr"` +} + +func init() { + t["CompositePolicyOption"] = reflect.TypeOf((*CompositePolicyOption)(nil)).Elem() +} + +type ComputeDiskPartitionInfo ComputeDiskPartitionInfoRequestType + +func init() { + t["ComputeDiskPartitionInfo"] = reflect.TypeOf((*ComputeDiskPartitionInfo)(nil)).Elem() +} + +type ComputeDiskPartitionInfoForResize ComputeDiskPartitionInfoForResizeRequestType + +func init() { + t["ComputeDiskPartitionInfoForResize"] = reflect.TypeOf((*ComputeDiskPartitionInfoForResize)(nil)).Elem() +} + +type ComputeDiskPartitionInfoForResizeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Partition HostScsiDiskPartition `xml:"partition"` + BlockRange HostDiskPartitionBlockRange `xml:"blockRange"` + PartitionFormat string `xml:"partitionFormat,omitempty"` +} + +func init() { + t["ComputeDiskPartitionInfoForResizeRequestType"] = reflect.TypeOf((*ComputeDiskPartitionInfoForResizeRequestType)(nil)).Elem() +} + +type ComputeDiskPartitionInfoForResizeResponse struct { + Returnval HostDiskPartitionInfo `xml:"returnval"` +} + +type ComputeDiskPartitionInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` + DevicePath string `xml:"devicePath"` + Layout HostDiskPartitionLayout `xml:"layout"` + PartitionFormat string `xml:"partitionFormat,omitempty"` +} + +func init() { + t["ComputeDiskPartitionInfoRequestType"] = reflect.TypeOf((*ComputeDiskPartitionInfoRequestType)(nil)).Elem() +} + +type ComputeDiskPartitionInfoResponse struct { + Returnval HostDiskPartitionInfo `xml:"returnval"` +} + +type ComputeResourceConfigInfo struct { + DynamicData + + VmSwapPlacement string `xml:"vmSwapPlacement"` + SpbmEnabled *bool `xml:"spbmEnabled"` + DefaultHardwareVersionKey string `xml:"defaultHardwareVersionKey,omitempty"` +} + +func init() { + t["ComputeResourceConfigInfo"] = reflect.TypeOf((*ComputeResourceConfigInfo)(nil)).Elem() +} + +type ComputeResourceConfigSpec struct { + DynamicData + + VmSwapPlacement string `xml:"vmSwapPlacement,omitempty"` + SpbmEnabled *bool `xml:"spbmEnabled"` + DefaultHardwareVersionKey string `xml:"defaultHardwareVersionKey,omitempty"` +} + +func init() { + t["ComputeResourceConfigSpec"] = reflect.TypeOf((*ComputeResourceConfigSpec)(nil)).Elem() +} + +type ComputeResourceEventArgument struct { + EntityEventArgument + + ComputeResource ManagedObjectReference `xml:"computeResource"` +} + +func init() { + t["ComputeResourceEventArgument"] = reflect.TypeOf((*ComputeResourceEventArgument)(nil)).Elem() +} + +type ComputeResourceHostSPBMLicenseInfo struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + LicenseState ComputeResourceHostSPBMLicenseInfoHostSPBMLicenseState `xml:"licenseState"` +} + +func init() { + t["ComputeResourceHostSPBMLicenseInfo"] = reflect.TypeOf((*ComputeResourceHostSPBMLicenseInfo)(nil)).Elem() +} + +type ComputeResourceSummary struct { + DynamicData + + TotalCpu int32 `xml:"totalCpu"` + TotalMemory int64 `xml:"totalMemory"` + NumCpuCores int16 `xml:"numCpuCores"` + NumCpuThreads int16 `xml:"numCpuThreads"` + EffectiveCpu int32 `xml:"effectiveCpu"` + EffectiveMemory int64 `xml:"effectiveMemory"` + NumHosts int32 `xml:"numHosts"` + NumEffectiveHosts int32 `xml:"numEffectiveHosts"` + OverallStatus ManagedEntityStatus `xml:"overallStatus"` +} + +func init() { + t["ComputeResourceSummary"] = reflect.TypeOf((*ComputeResourceSummary)(nil)).Elem() +} + +type ConcurrentAccess struct { + VimFault +} + +func init() { + t["ConcurrentAccess"] = reflect.TypeOf((*ConcurrentAccess)(nil)).Elem() +} + +type ConcurrentAccessFault ConcurrentAccess + +func init() { + t["ConcurrentAccessFault"] = reflect.TypeOf((*ConcurrentAccessFault)(nil)).Elem() +} + +type ConfigTarget struct { + DynamicData + + NumCpus int32 `xml:"numCpus"` + NumCpuCores int32 `xml:"numCpuCores"` + NumNumaNodes int32 `xml:"numNumaNodes"` + SmcPresent *bool `xml:"smcPresent"` + Datastore []VirtualMachineDatastoreInfo `xml:"datastore,omitempty"` + Network []VirtualMachineNetworkInfo `xml:"network,omitempty"` + OpaqueNetwork []OpaqueNetworkTargetInfo `xml:"opaqueNetwork,omitempty"` + DistributedVirtualPortgroup []DistributedVirtualPortgroupInfo `xml:"distributedVirtualPortgroup,omitempty"` + DistributedVirtualSwitch []DistributedVirtualSwitchInfo `xml:"distributedVirtualSwitch,omitempty"` + CdRom []VirtualMachineCdromInfo `xml:"cdRom,omitempty"` + Serial []VirtualMachineSerialInfo `xml:"serial,omitempty"` + Parallel []VirtualMachineParallelInfo `xml:"parallel,omitempty"` + Sound []VirtualMachineSoundInfo `xml:"sound,omitempty"` + Usb []VirtualMachineUsbInfo `xml:"usb,omitempty"` + Floppy []VirtualMachineFloppyInfo `xml:"floppy,omitempty"` + LegacyNetworkInfo []VirtualMachineLegacyNetworkSwitchInfo `xml:"legacyNetworkInfo,omitempty"` + ScsiPassthrough []VirtualMachineScsiPassthroughInfo `xml:"scsiPassthrough,omitempty"` + ScsiDisk []VirtualMachineScsiDiskDeviceInfo `xml:"scsiDisk,omitempty"` + IdeDisk []VirtualMachineIdeDiskDeviceInfo `xml:"ideDisk,omitempty"` + MaxMemMBOptimalPerf int32 `xml:"maxMemMBOptimalPerf"` + ResourcePool *ResourcePoolRuntimeInfo `xml:"resourcePool,omitempty"` + AutoVmotion *bool `xml:"autoVmotion"` + PciPassthrough []BaseVirtualMachinePciPassthroughInfo `xml:"pciPassthrough,omitempty,typeattr"` + Sriov []VirtualMachineSriovInfo `xml:"sriov,omitempty"` + VFlashModule []VirtualMachineVFlashModuleInfo `xml:"vFlashModule,omitempty"` + SharedGpuPassthroughTypes []VirtualMachinePciSharedGpuPassthroughInfo `xml:"sharedGpuPassthroughTypes,omitempty"` +} + +func init() { + t["ConfigTarget"] = reflect.TypeOf((*ConfigTarget)(nil)).Elem() +} + +type ConfigureDatastoreIORMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` + Spec StorageIORMConfigSpec `xml:"spec"` +} + +func init() { + t["ConfigureDatastoreIORMRequestType"] = reflect.TypeOf((*ConfigureDatastoreIORMRequestType)(nil)).Elem() +} + +type ConfigureDatastoreIORM_Task ConfigureDatastoreIORMRequestType + +func init() { + t["ConfigureDatastoreIORM_Task"] = reflect.TypeOf((*ConfigureDatastoreIORM_Task)(nil)).Elem() +} + +type ConfigureDatastoreIORM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ConfigureDatastorePrincipal ConfigureDatastorePrincipalRequestType + +func init() { + t["ConfigureDatastorePrincipal"] = reflect.TypeOf((*ConfigureDatastorePrincipal)(nil)).Elem() +} + +type ConfigureDatastorePrincipalRequestType struct { + This ManagedObjectReference `xml:"_this"` + UserName string `xml:"userName"` + Password string `xml:"password,omitempty"` +} + +func init() { + t["ConfigureDatastorePrincipalRequestType"] = reflect.TypeOf((*ConfigureDatastorePrincipalRequestType)(nil)).Elem() +} + +type ConfigureDatastorePrincipalResponse struct { +} + +type ConfigureEvcModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + EvcModeKey string `xml:"evcModeKey"` +} + +func init() { + t["ConfigureEvcModeRequestType"] = reflect.TypeOf((*ConfigureEvcModeRequestType)(nil)).Elem() +} + +type ConfigureEvcMode_Task ConfigureEvcModeRequestType + +func init() { + t["ConfigureEvcMode_Task"] = reflect.TypeOf((*ConfigureEvcMode_Task)(nil)).Elem() +} + +type ConfigureEvcMode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ConfigureHostCacheRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostCacheConfigurationSpec `xml:"spec"` +} + +func init() { + t["ConfigureHostCacheRequestType"] = reflect.TypeOf((*ConfigureHostCacheRequestType)(nil)).Elem() +} + +type ConfigureHostCache_Task ConfigureHostCacheRequestType + +func init() { + t["ConfigureHostCache_Task"] = reflect.TypeOf((*ConfigureHostCache_Task)(nil)).Elem() +} + +type ConfigureHostCache_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ConfigureLicenseSource ConfigureLicenseSourceRequestType + +func init() { + t["ConfigureLicenseSource"] = reflect.TypeOf((*ConfigureLicenseSource)(nil)).Elem() +} + +type ConfigureLicenseSourceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + LicenseSource BaseLicenseSource `xml:"licenseSource,typeattr"` +} + +func init() { + t["ConfigureLicenseSourceRequestType"] = reflect.TypeOf((*ConfigureLicenseSourceRequestType)(nil)).Elem() +} + +type ConfigureLicenseSourceResponse struct { +} + +type ConfigurePowerPolicy ConfigurePowerPolicyRequestType + +func init() { + t["ConfigurePowerPolicy"] = reflect.TypeOf((*ConfigurePowerPolicy)(nil)).Elem() +} + +type ConfigurePowerPolicyRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key int32 `xml:"key"` +} + +func init() { + t["ConfigurePowerPolicyRequestType"] = reflect.TypeOf((*ConfigurePowerPolicyRequestType)(nil)).Elem() +} + +type ConfigurePowerPolicyResponse struct { +} + +type ConfigureStorageDrsForPodRequestType struct { + This ManagedObjectReference `xml:"_this"` + Pod ManagedObjectReference `xml:"pod"` + Spec StorageDrsConfigSpec `xml:"spec"` + Modify bool `xml:"modify"` +} + +func init() { + t["ConfigureStorageDrsForPodRequestType"] = reflect.TypeOf((*ConfigureStorageDrsForPodRequestType)(nil)).Elem() +} + +type ConfigureStorageDrsForPod_Task ConfigureStorageDrsForPodRequestType + +func init() { + t["ConfigureStorageDrsForPod_Task"] = reflect.TypeOf((*ConfigureStorageDrsForPod_Task)(nil)).Elem() +} + +type ConfigureStorageDrsForPod_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ConfigureVFlashResourceExRequestType struct { + This ManagedObjectReference `xml:"_this"` + DevicePath []string `xml:"devicePath,omitempty"` +} + +func init() { + t["ConfigureVFlashResourceExRequestType"] = reflect.TypeOf((*ConfigureVFlashResourceExRequestType)(nil)).Elem() +} + +type ConfigureVFlashResourceEx_Task ConfigureVFlashResourceExRequestType + +func init() { + t["ConfigureVFlashResourceEx_Task"] = reflect.TypeOf((*ConfigureVFlashResourceEx_Task)(nil)).Elem() +} + +type ConfigureVFlashResourceEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ConflictingConfiguration struct { + DvsFault + + ConfigInConflict []ConflictingConfigurationConfig `xml:"configInConflict"` +} + +func init() { + t["ConflictingConfiguration"] = reflect.TypeOf((*ConflictingConfiguration)(nil)).Elem() +} + +type ConflictingConfigurationConfig struct { + DynamicData + + Entity *ManagedObjectReference `xml:"entity,omitempty"` + PropertyPath string `xml:"propertyPath"` +} + +func init() { + t["ConflictingConfigurationConfig"] = reflect.TypeOf((*ConflictingConfigurationConfig)(nil)).Elem() +} + +type ConflictingConfigurationFault ConflictingConfiguration + +func init() { + t["ConflictingConfigurationFault"] = reflect.TypeOf((*ConflictingConfigurationFault)(nil)).Elem() +} + +type ConflictingDatastoreFound struct { + RuntimeFault + + Name string `xml:"name"` + Url string `xml:"url"` +} + +func init() { + t["ConflictingDatastoreFound"] = reflect.TypeOf((*ConflictingDatastoreFound)(nil)).Elem() +} + +type ConflictingDatastoreFoundFault ConflictingDatastoreFound + +func init() { + t["ConflictingDatastoreFoundFault"] = reflect.TypeOf((*ConflictingDatastoreFoundFault)(nil)).Elem() +} + +type ConnectedIso struct { + OvfExport + + Cdrom VirtualCdrom `xml:"cdrom"` + Filename string `xml:"filename"` +} + +func init() { + t["ConnectedIso"] = reflect.TypeOf((*ConnectedIso)(nil)).Elem() +} + +type ConnectedIsoFault ConnectedIso + +func init() { + t["ConnectedIsoFault"] = reflect.TypeOf((*ConnectedIsoFault)(nil)).Elem() +} + +type ConsolidateVMDisksRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ConsolidateVMDisksRequestType"] = reflect.TypeOf((*ConsolidateVMDisksRequestType)(nil)).Elem() +} + +type ConsolidateVMDisks_Task ConsolidateVMDisksRequestType + +func init() { + t["ConsolidateVMDisks_Task"] = reflect.TypeOf((*ConsolidateVMDisks_Task)(nil)).Elem() +} + +type ConsolidateVMDisks_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ContinueRetrievePropertiesEx ContinueRetrievePropertiesExRequestType + +func init() { + t["ContinueRetrievePropertiesEx"] = reflect.TypeOf((*ContinueRetrievePropertiesEx)(nil)).Elem() +} + +type ContinueRetrievePropertiesExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Token string `xml:"token"` +} + +func init() { + t["ContinueRetrievePropertiesExRequestType"] = reflect.TypeOf((*ContinueRetrievePropertiesExRequestType)(nil)).Elem() +} + +type ContinueRetrievePropertiesExResponse struct { + Returnval RetrieveResult `xml:"returnval"` +} + +type CopyDatastoreFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + SourceName string `xml:"sourceName"` + SourceDatacenter *ManagedObjectReference `xml:"sourceDatacenter,omitempty"` + DestinationName string `xml:"destinationName"` + DestinationDatacenter *ManagedObjectReference `xml:"destinationDatacenter,omitempty"` + Force *bool `xml:"force"` +} + +func init() { + t["CopyDatastoreFileRequestType"] = reflect.TypeOf((*CopyDatastoreFileRequestType)(nil)).Elem() +} + +type CopyDatastoreFile_Task CopyDatastoreFileRequestType + +func init() { + t["CopyDatastoreFile_Task"] = reflect.TypeOf((*CopyDatastoreFile_Task)(nil)).Elem() +} + +type CopyDatastoreFile_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CopyVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + SourceName string `xml:"sourceName"` + SourceDatacenter *ManagedObjectReference `xml:"sourceDatacenter,omitempty"` + DestName string `xml:"destName"` + DestDatacenter *ManagedObjectReference `xml:"destDatacenter,omitempty"` + DestSpec BaseVirtualDiskSpec `xml:"destSpec,omitempty,typeattr"` + Force *bool `xml:"force"` +} + +func init() { + t["CopyVirtualDiskRequestType"] = reflect.TypeOf((*CopyVirtualDiskRequestType)(nil)).Elem() +} + +type CopyVirtualDisk_Task CopyVirtualDiskRequestType + +func init() { + t["CopyVirtualDisk_Task"] = reflect.TypeOf((*CopyVirtualDisk_Task)(nil)).Elem() +} + +type CopyVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CpuCompatibilityUnknown struct { + CpuIncompatible +} + +func init() { + t["CpuCompatibilityUnknown"] = reflect.TypeOf((*CpuCompatibilityUnknown)(nil)).Elem() +} + +type CpuCompatibilityUnknownFault CpuCompatibilityUnknown + +func init() { + t["CpuCompatibilityUnknownFault"] = reflect.TypeOf((*CpuCompatibilityUnknownFault)(nil)).Elem() +} + +type CpuHotPlugNotSupported struct { + VmConfigFault +} + +func init() { + t["CpuHotPlugNotSupported"] = reflect.TypeOf((*CpuHotPlugNotSupported)(nil)).Elem() +} + +type CpuHotPlugNotSupportedFault CpuHotPlugNotSupported + +func init() { + t["CpuHotPlugNotSupportedFault"] = reflect.TypeOf((*CpuHotPlugNotSupportedFault)(nil)).Elem() +} + +type CpuIncompatible struct { + VirtualHardwareCompatibilityIssue + + Level int32 `xml:"level"` + RegisterName string `xml:"registerName"` + RegisterBits string `xml:"registerBits,omitempty"` + DesiredBits string `xml:"desiredBits,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["CpuIncompatible"] = reflect.TypeOf((*CpuIncompatible)(nil)).Elem() +} + +type CpuIncompatible1ECX struct { + CpuIncompatible + + Sse3 bool `xml:"sse3"` + Pclmulqdq *bool `xml:"pclmulqdq"` + Ssse3 bool `xml:"ssse3"` + Sse41 bool `xml:"sse41"` + Sse42 bool `xml:"sse42"` + Aes *bool `xml:"aes"` + Other bool `xml:"other"` + OtherOnly bool `xml:"otherOnly"` +} + +func init() { + t["CpuIncompatible1ECX"] = reflect.TypeOf((*CpuIncompatible1ECX)(nil)).Elem() +} + +type CpuIncompatible1ECXFault CpuIncompatible1ECX + +func init() { + t["CpuIncompatible1ECXFault"] = reflect.TypeOf((*CpuIncompatible1ECXFault)(nil)).Elem() +} + +type CpuIncompatible81EDX struct { + CpuIncompatible + + Nx bool `xml:"nx"` + Ffxsr bool `xml:"ffxsr"` + Rdtscp bool `xml:"rdtscp"` + Lm bool `xml:"lm"` + Other bool `xml:"other"` + OtherOnly bool `xml:"otherOnly"` +} + +func init() { + t["CpuIncompatible81EDX"] = reflect.TypeOf((*CpuIncompatible81EDX)(nil)).Elem() +} + +type CpuIncompatible81EDXFault CpuIncompatible81EDX + +func init() { + t["CpuIncompatible81EDXFault"] = reflect.TypeOf((*CpuIncompatible81EDXFault)(nil)).Elem() +} + +type CpuIncompatibleFault BaseCpuIncompatible + +func init() { + t["CpuIncompatibleFault"] = reflect.TypeOf((*CpuIncompatibleFault)(nil)).Elem() +} + +type CreateAlarm CreateAlarmRequestType + +func init() { + t["CreateAlarm"] = reflect.TypeOf((*CreateAlarm)(nil)).Elem() +} + +type CreateAlarmRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Spec BaseAlarmSpec `xml:"spec,typeattr"` +} + +func init() { + t["CreateAlarmRequestType"] = reflect.TypeOf((*CreateAlarmRequestType)(nil)).Elem() +} + +type CreateAlarmResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateChildVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config VirtualMachineConfigSpec `xml:"config"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["CreateChildVMRequestType"] = reflect.TypeOf((*CreateChildVMRequestType)(nil)).Elem() +} + +type CreateChildVM_Task CreateChildVMRequestType + +func init() { + t["CreateChildVM_Task"] = reflect.TypeOf((*CreateChildVM_Task)(nil)).Elem() +} + +type CreateChildVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateCluster CreateClusterRequestType + +func init() { + t["CreateCluster"] = reflect.TypeOf((*CreateCluster)(nil)).Elem() +} + +type CreateClusterEx CreateClusterExRequestType + +func init() { + t["CreateClusterEx"] = reflect.TypeOf((*CreateClusterEx)(nil)).Elem() +} + +type CreateClusterExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Spec ClusterConfigSpecEx `xml:"spec"` +} + +func init() { + t["CreateClusterExRequestType"] = reflect.TypeOf((*CreateClusterExRequestType)(nil)).Elem() +} + +type CreateClusterExResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateClusterRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Spec ClusterConfigSpec `xml:"spec"` +} + +func init() { + t["CreateClusterRequestType"] = reflect.TypeOf((*CreateClusterRequestType)(nil)).Elem() +} + +type CreateClusterResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateCollectorForEvents CreateCollectorForEventsRequestType + +func init() { + t["CreateCollectorForEvents"] = reflect.TypeOf((*CreateCollectorForEvents)(nil)).Elem() +} + +type CreateCollectorForEventsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Filter EventFilterSpec `xml:"filter"` +} + +func init() { + t["CreateCollectorForEventsRequestType"] = reflect.TypeOf((*CreateCollectorForEventsRequestType)(nil)).Elem() +} + +type CreateCollectorForEventsResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateCollectorForTasks CreateCollectorForTasksRequestType + +func init() { + t["CreateCollectorForTasks"] = reflect.TypeOf((*CreateCollectorForTasks)(nil)).Elem() +} + +type CreateCollectorForTasksRequestType struct { + This ManagedObjectReference `xml:"_this"` + Filter TaskFilterSpec `xml:"filter"` +} + +func init() { + t["CreateCollectorForTasksRequestType"] = reflect.TypeOf((*CreateCollectorForTasksRequestType)(nil)).Elem() +} + +type CreateCollectorForTasksResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateContainerView CreateContainerViewRequestType + +func init() { + t["CreateContainerView"] = reflect.TypeOf((*CreateContainerView)(nil)).Elem() +} + +type CreateContainerViewRequestType struct { + This ManagedObjectReference `xml:"_this"` + Container ManagedObjectReference `xml:"container"` + Type []string `xml:"type,omitempty"` + Recursive bool `xml:"recursive"` +} + +func init() { + t["CreateContainerViewRequestType"] = reflect.TypeOf((*CreateContainerViewRequestType)(nil)).Elem() +} + +type CreateContainerViewResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateCustomizationSpec CreateCustomizationSpecRequestType + +func init() { + t["CreateCustomizationSpec"] = reflect.TypeOf((*CreateCustomizationSpec)(nil)).Elem() +} + +type CreateCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Item CustomizationSpecItem `xml:"item"` +} + +func init() { + t["CreateCustomizationSpecRequestType"] = reflect.TypeOf((*CreateCustomizationSpecRequestType)(nil)).Elem() +} + +type CreateCustomizationSpecResponse struct { +} + +type CreateDVPortgroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec DVPortgroupConfigSpec `xml:"spec"` +} + +func init() { + t["CreateDVPortgroupRequestType"] = reflect.TypeOf((*CreateDVPortgroupRequestType)(nil)).Elem() +} + +type CreateDVPortgroup_Task CreateDVPortgroupRequestType + +func init() { + t["CreateDVPortgroup_Task"] = reflect.TypeOf((*CreateDVPortgroup_Task)(nil)).Elem() +} + +type CreateDVPortgroup_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateDVSRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec DVSCreateSpec `xml:"spec"` +} + +func init() { + t["CreateDVSRequestType"] = reflect.TypeOf((*CreateDVSRequestType)(nil)).Elem() +} + +type CreateDVS_Task CreateDVSRequestType + +func init() { + t["CreateDVS_Task"] = reflect.TypeOf((*CreateDVS_Task)(nil)).Elem() +} + +type CreateDVS_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateDatacenter CreateDatacenterRequestType + +func init() { + t["CreateDatacenter"] = reflect.TypeOf((*CreateDatacenter)(nil)).Elem() +} + +type CreateDatacenterRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["CreateDatacenterRequestType"] = reflect.TypeOf((*CreateDatacenterRequestType)(nil)).Elem() +} + +type CreateDatacenterResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateDefaultProfile CreateDefaultProfileRequestType + +func init() { + t["CreateDefaultProfile"] = reflect.TypeOf((*CreateDefaultProfile)(nil)).Elem() +} + +type CreateDefaultProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + ProfileType string `xml:"profileType"` + ProfileTypeName string `xml:"profileTypeName,omitempty"` + Profile *ManagedObjectReference `xml:"profile,omitempty"` +} + +func init() { + t["CreateDefaultProfileRequestType"] = reflect.TypeOf((*CreateDefaultProfileRequestType)(nil)).Elem() +} + +type CreateDefaultProfileResponse struct { + Returnval BaseApplyProfile `xml:"returnval,typeattr"` +} + +type CreateDescriptor CreateDescriptorRequestType + +func init() { + t["CreateDescriptor"] = reflect.TypeOf((*CreateDescriptor)(nil)).Elem() +} + +type CreateDescriptorRequestType struct { + This ManagedObjectReference `xml:"_this"` + Obj ManagedObjectReference `xml:"obj"` + Cdp OvfCreateDescriptorParams `xml:"cdp"` +} + +func init() { + t["CreateDescriptorRequestType"] = reflect.TypeOf((*CreateDescriptorRequestType)(nil)).Elem() +} + +type CreateDescriptorResponse struct { + Returnval OvfCreateDescriptorResult `xml:"returnval"` +} + +type CreateDiagnosticPartition CreateDiagnosticPartitionRequestType + +func init() { + t["CreateDiagnosticPartition"] = reflect.TypeOf((*CreateDiagnosticPartition)(nil)).Elem() +} + +type CreateDiagnosticPartitionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostDiagnosticPartitionCreateSpec `xml:"spec"` +} + +func init() { + t["CreateDiagnosticPartitionRequestType"] = reflect.TypeOf((*CreateDiagnosticPartitionRequestType)(nil)).Elem() +} + +type CreateDiagnosticPartitionResponse struct { +} + +type CreateDirectory CreateDirectoryRequestType + +func init() { + t["CreateDirectory"] = reflect.TypeOf((*CreateDirectory)(nil)).Elem() +} + +type CreateDirectoryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` + DisplayName string `xml:"displayName,omitempty"` + Policy string `xml:"policy,omitempty"` +} + +func init() { + t["CreateDirectoryRequestType"] = reflect.TypeOf((*CreateDirectoryRequestType)(nil)).Elem() +} + +type CreateDirectoryResponse struct { + Returnval string `xml:"returnval"` +} + +type CreateFilter CreateFilterRequestType + +func init() { + t["CreateFilter"] = reflect.TypeOf((*CreateFilter)(nil)).Elem() +} + +type CreateFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec PropertyFilterSpec `xml:"spec"` + PartialUpdates bool `xml:"partialUpdates"` +} + +func init() { + t["CreateFilterRequestType"] = reflect.TypeOf((*CreateFilterRequestType)(nil)).Elem() +} + +type CreateFilterResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateFolder CreateFolderRequestType + +func init() { + t["CreateFolder"] = reflect.TypeOf((*CreateFolder)(nil)).Elem() +} + +type CreateFolderRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["CreateFolderRequestType"] = reflect.TypeOf((*CreateFolderRequestType)(nil)).Elem() +} + +type CreateFolderResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateGroup CreateGroupRequestType + +func init() { + t["CreateGroup"] = reflect.TypeOf((*CreateGroup)(nil)).Elem() +} + +type CreateGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + Group BaseHostAccountSpec `xml:"group,typeattr"` +} + +func init() { + t["CreateGroupRequestType"] = reflect.TypeOf((*CreateGroupRequestType)(nil)).Elem() +} + +type CreateGroupResponse struct { +} + +type CreateImportSpec CreateImportSpecRequestType + +func init() { + t["CreateImportSpec"] = reflect.TypeOf((*CreateImportSpec)(nil)).Elem() +} + +type CreateImportSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + OvfDescriptor string `xml:"ovfDescriptor"` + ResourcePool ManagedObjectReference `xml:"resourcePool"` + Datastore ManagedObjectReference `xml:"datastore"` + Cisp OvfCreateImportSpecParams `xml:"cisp"` +} + +func init() { + t["CreateImportSpecRequestType"] = reflect.TypeOf((*CreateImportSpecRequestType)(nil)).Elem() +} + +type CreateImportSpecResponse struct { + Returnval OvfCreateImportSpecResult `xml:"returnval"` +} + +type CreateInventoryView CreateInventoryViewRequestType + +func init() { + t["CreateInventoryView"] = reflect.TypeOf((*CreateInventoryView)(nil)).Elem() +} + +type CreateInventoryViewRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["CreateInventoryViewRequestType"] = reflect.TypeOf((*CreateInventoryViewRequestType)(nil)).Elem() +} + +type CreateInventoryViewResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateIpPool CreateIpPoolRequestType + +func init() { + t["CreateIpPool"] = reflect.TypeOf((*CreateIpPool)(nil)).Elem() +} + +type CreateIpPoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + Pool IpPool `xml:"pool"` +} + +func init() { + t["CreateIpPoolRequestType"] = reflect.TypeOf((*CreateIpPoolRequestType)(nil)).Elem() +} + +type CreateIpPoolResponse struct { + Returnval int32 `xml:"returnval"` +} + +type CreateListView CreateListViewRequestType + +func init() { + t["CreateListView"] = reflect.TypeOf((*CreateListView)(nil)).Elem() +} + +type CreateListViewFromView CreateListViewFromViewRequestType + +func init() { + t["CreateListViewFromView"] = reflect.TypeOf((*CreateListViewFromView)(nil)).Elem() +} + +type CreateListViewFromViewRequestType struct { + This ManagedObjectReference `xml:"_this"` + View ManagedObjectReference `xml:"view"` +} + +func init() { + t["CreateListViewFromViewRequestType"] = reflect.TypeOf((*CreateListViewFromViewRequestType)(nil)).Elem() +} + +type CreateListViewFromViewResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateListViewRequestType struct { + This ManagedObjectReference `xml:"_this"` + Obj []ManagedObjectReference `xml:"obj,omitempty"` +} + +func init() { + t["CreateListViewRequestType"] = reflect.TypeOf((*CreateListViewRequestType)(nil)).Elem() +} + +type CreateListViewResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateLocalDatastore CreateLocalDatastoreRequestType + +func init() { + t["CreateLocalDatastore"] = reflect.TypeOf((*CreateLocalDatastore)(nil)).Elem() +} + +type CreateLocalDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Path string `xml:"path"` +} + +func init() { + t["CreateLocalDatastoreRequestType"] = reflect.TypeOf((*CreateLocalDatastoreRequestType)(nil)).Elem() +} + +type CreateLocalDatastoreResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateNasDatastore CreateNasDatastoreRequestType + +func init() { + t["CreateNasDatastore"] = reflect.TypeOf((*CreateNasDatastore)(nil)).Elem() +} + +type CreateNasDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostNasVolumeSpec `xml:"spec"` +} + +func init() { + t["CreateNasDatastoreRequestType"] = reflect.TypeOf((*CreateNasDatastoreRequestType)(nil)).Elem() +} + +type CreateNasDatastoreResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateObjectScheduledTask CreateObjectScheduledTaskRequestType + +func init() { + t["CreateObjectScheduledTask"] = reflect.TypeOf((*CreateObjectScheduledTask)(nil)).Elem() +} + +type CreateObjectScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Obj ManagedObjectReference `xml:"obj"` + Spec BaseScheduledTaskSpec `xml:"spec,typeattr"` +} + +func init() { + t["CreateObjectScheduledTaskRequestType"] = reflect.TypeOf((*CreateObjectScheduledTaskRequestType)(nil)).Elem() +} + +type CreateObjectScheduledTaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreatePerfInterval CreatePerfIntervalRequestType + +func init() { + t["CreatePerfInterval"] = reflect.TypeOf((*CreatePerfInterval)(nil)).Elem() +} + +type CreatePerfIntervalRequestType struct { + This ManagedObjectReference `xml:"_this"` + IntervalId PerfInterval `xml:"intervalId"` +} + +func init() { + t["CreatePerfIntervalRequestType"] = reflect.TypeOf((*CreatePerfIntervalRequestType)(nil)).Elem() +} + +type CreatePerfIntervalResponse struct { +} + +type CreateProfile CreateProfileRequestType + +func init() { + t["CreateProfile"] = reflect.TypeOf((*CreateProfile)(nil)).Elem() +} + +type CreateProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + CreateSpec BaseProfileCreateSpec `xml:"createSpec,typeattr"` +} + +func init() { + t["CreateProfileRequestType"] = reflect.TypeOf((*CreateProfileRequestType)(nil)).Elem() +} + +type CreateProfileResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreatePropertyCollector CreatePropertyCollectorRequestType + +func init() { + t["CreatePropertyCollector"] = reflect.TypeOf((*CreatePropertyCollector)(nil)).Elem() +} + +type CreatePropertyCollectorRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["CreatePropertyCollectorRequestType"] = reflect.TypeOf((*CreatePropertyCollectorRequestType)(nil)).Elem() +} + +type CreatePropertyCollectorResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateRegistryKeyInGuest CreateRegistryKeyInGuestRequestType + +func init() { + t["CreateRegistryKeyInGuest"] = reflect.TypeOf((*CreateRegistryKeyInGuest)(nil)).Elem() +} + +type CreateRegistryKeyInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + KeyName GuestRegKeyNameSpec `xml:"keyName"` + IsVolatile bool `xml:"isVolatile"` + ClassType string `xml:"classType,omitempty"` +} + +func init() { + t["CreateRegistryKeyInGuestRequestType"] = reflect.TypeOf((*CreateRegistryKeyInGuestRequestType)(nil)).Elem() +} + +type CreateRegistryKeyInGuestResponse struct { +} + +type CreateResourcePool CreateResourcePoolRequestType + +func init() { + t["CreateResourcePool"] = reflect.TypeOf((*CreateResourcePool)(nil)).Elem() +} + +type CreateResourcePoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Spec ResourceConfigSpec `xml:"spec"` +} + +func init() { + t["CreateResourcePoolRequestType"] = reflect.TypeOf((*CreateResourcePoolRequestType)(nil)).Elem() +} + +type CreateResourcePoolResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateScheduledTask CreateScheduledTaskRequestType + +func init() { + t["CreateScheduledTask"] = reflect.TypeOf((*CreateScheduledTask)(nil)).Elem() +} + +type CreateScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Spec BaseScheduledTaskSpec `xml:"spec,typeattr"` +} + +func init() { + t["CreateScheduledTaskRequestType"] = reflect.TypeOf((*CreateScheduledTaskRequestType)(nil)).Elem() +} + +type CreateScheduledTaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateScreenshotRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["CreateScreenshotRequestType"] = reflect.TypeOf((*CreateScreenshotRequestType)(nil)).Elem() +} + +type CreateScreenshot_Task CreateScreenshotRequestType + +func init() { + t["CreateScreenshot_Task"] = reflect.TypeOf((*CreateScreenshot_Task)(nil)).Elem() +} + +type CreateScreenshot_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateSecondaryVMExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Spec *FaultToleranceConfigSpec `xml:"spec,omitempty"` +} + +func init() { + t["CreateSecondaryVMExRequestType"] = reflect.TypeOf((*CreateSecondaryVMExRequestType)(nil)).Elem() +} + +type CreateSecondaryVMEx_Task CreateSecondaryVMExRequestType + +func init() { + t["CreateSecondaryVMEx_Task"] = reflect.TypeOf((*CreateSecondaryVMEx_Task)(nil)).Elem() +} + +type CreateSecondaryVMEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateSecondaryVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["CreateSecondaryVMRequestType"] = reflect.TypeOf((*CreateSecondaryVMRequestType)(nil)).Elem() +} + +type CreateSecondaryVM_Task CreateSecondaryVMRequestType + +func init() { + t["CreateSecondaryVM_Task"] = reflect.TypeOf((*CreateSecondaryVM_Task)(nil)).Elem() +} + +type CreateSecondaryVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Description string `xml:"description,omitempty"` + Memory bool `xml:"memory"` + Quiesce bool `xml:"quiesce"` +} + +func init() { + t["CreateSnapshotRequestType"] = reflect.TypeOf((*CreateSnapshotRequestType)(nil)).Elem() +} + +type CreateSnapshot_Task CreateSnapshotRequestType + +func init() { + t["CreateSnapshot_Task"] = reflect.TypeOf((*CreateSnapshot_Task)(nil)).Elem() +} + +type CreateSnapshot_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateStoragePod CreateStoragePodRequestType + +func init() { + t["CreateStoragePod"] = reflect.TypeOf((*CreateStoragePod)(nil)).Elem() +} + +type CreateStoragePodRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["CreateStoragePodRequestType"] = reflect.TypeOf((*CreateStoragePodRequestType)(nil)).Elem() +} + +type CreateStoragePodResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateTask CreateTaskRequestType + +func init() { + t["CreateTask"] = reflect.TypeOf((*CreateTask)(nil)).Elem() +} + +type CreateTaskAction struct { + Action + + TaskTypeId string `xml:"taskTypeId"` + Cancelable bool `xml:"cancelable"` +} + +func init() { + t["CreateTaskAction"] = reflect.TypeOf((*CreateTaskAction)(nil)).Elem() +} + +type CreateTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Obj ManagedObjectReference `xml:"obj"` + TaskTypeId string `xml:"taskTypeId"` + InitiatedBy string `xml:"initiatedBy,omitempty"` + Cancelable bool `xml:"cancelable"` + ParentTaskKey string `xml:"parentTaskKey,omitempty"` + ActivationId string `xml:"activationId,omitempty"` +} + +func init() { + t["CreateTaskRequestType"] = reflect.TypeOf((*CreateTaskRequestType)(nil)).Elem() +} + +type CreateTaskResponse struct { + Returnval TaskInfo `xml:"returnval"` +} + +type CreateTemporaryDirectoryInGuest CreateTemporaryDirectoryInGuestRequestType + +func init() { + t["CreateTemporaryDirectoryInGuest"] = reflect.TypeOf((*CreateTemporaryDirectoryInGuest)(nil)).Elem() +} + +type CreateTemporaryDirectoryInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Prefix string `xml:"prefix"` + Suffix string `xml:"suffix"` + DirectoryPath string `xml:"directoryPath,omitempty"` +} + +func init() { + t["CreateTemporaryDirectoryInGuestRequestType"] = reflect.TypeOf((*CreateTemporaryDirectoryInGuestRequestType)(nil)).Elem() +} + +type CreateTemporaryDirectoryInGuestResponse struct { + Returnval string `xml:"returnval"` +} + +type CreateTemporaryFileInGuest CreateTemporaryFileInGuestRequestType + +func init() { + t["CreateTemporaryFileInGuest"] = reflect.TypeOf((*CreateTemporaryFileInGuest)(nil)).Elem() +} + +type CreateTemporaryFileInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Prefix string `xml:"prefix"` + Suffix string `xml:"suffix"` + DirectoryPath string `xml:"directoryPath,omitempty"` +} + +func init() { + t["CreateTemporaryFileInGuestRequestType"] = reflect.TypeOf((*CreateTemporaryFileInGuestRequestType)(nil)).Elem() +} + +type CreateTemporaryFileInGuestResponse struct { + Returnval string `xml:"returnval"` +} + +type CreateUser CreateUserRequestType + +func init() { + t["CreateUser"] = reflect.TypeOf((*CreateUser)(nil)).Elem() +} + +type CreateUserRequestType struct { + This ManagedObjectReference `xml:"_this"` + User BaseHostAccountSpec `xml:"user,typeattr"` +} + +func init() { + t["CreateUserRequestType"] = reflect.TypeOf((*CreateUserRequestType)(nil)).Elem() +} + +type CreateUserResponse struct { +} + +type CreateVApp CreateVAppRequestType + +func init() { + t["CreateVApp"] = reflect.TypeOf((*CreateVApp)(nil)).Elem() +} + +type CreateVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + ResSpec ResourceConfigSpec `xml:"resSpec"` + ConfigSpec VAppConfigSpec `xml:"configSpec"` + VmFolder *ManagedObjectReference `xml:"vmFolder,omitempty"` +} + +func init() { + t["CreateVAppRequestType"] = reflect.TypeOf((*CreateVAppRequestType)(nil)).Elem() +} + +type CreateVAppResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config VirtualMachineConfigSpec `xml:"config"` + Pool ManagedObjectReference `xml:"pool"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["CreateVMRequestType"] = reflect.TypeOf((*CreateVMRequestType)(nil)).Elem() +} + +type CreateVM_Task CreateVMRequestType + +func init() { + t["CreateVM_Task"] = reflect.TypeOf((*CreateVM_Task)(nil)).Elem() +} + +type CreateVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Spec BaseVirtualDiskSpec `xml:"spec,typeattr"` +} + +func init() { + t["CreateVirtualDiskRequestType"] = reflect.TypeOf((*CreateVirtualDiskRequestType)(nil)).Elem() +} + +type CreateVirtualDisk_Task CreateVirtualDiskRequestType + +func init() { + t["CreateVirtualDisk_Task"] = reflect.TypeOf((*CreateVirtualDisk_Task)(nil)).Elem() +} + +type CreateVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateVmfsDatastore CreateVmfsDatastoreRequestType + +func init() { + t["CreateVmfsDatastore"] = reflect.TypeOf((*CreateVmfsDatastore)(nil)).Elem() +} + +type CreateVmfsDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec VmfsDatastoreCreateSpec `xml:"spec"` +} + +func init() { + t["CreateVmfsDatastoreRequestType"] = reflect.TypeOf((*CreateVmfsDatastoreRequestType)(nil)).Elem() +} + +type CreateVmfsDatastoreResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CreateVvolDatastore CreateVvolDatastoreRequestType + +func init() { + t["CreateVvolDatastore"] = reflect.TypeOf((*CreateVvolDatastore)(nil)).Elem() +} + +type CreateVvolDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostDatastoreSystemVvolDatastoreSpec `xml:"spec"` +} + +func init() { + t["CreateVvolDatastoreRequestType"] = reflect.TypeOf((*CreateVvolDatastoreRequestType)(nil)).Elem() +} + +type CreateVvolDatastoreResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type CurrentTime CurrentTimeRequestType + +func init() { + t["CurrentTime"] = reflect.TypeOf((*CurrentTime)(nil)).Elem() +} + +type CurrentTimeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["CurrentTimeRequestType"] = reflect.TypeOf((*CurrentTimeRequestType)(nil)).Elem() +} + +type CurrentTimeResponse struct { + Returnval time.Time `xml:"returnval"` +} + +type CustomFieldDef struct { + DynamicData + + Key int32 `xml:"key"` + Name string `xml:"name"` + Type string `xml:"type"` + ManagedObjectType string `xml:"managedObjectType,omitempty"` + FieldDefPrivileges *PrivilegePolicyDef `xml:"fieldDefPrivileges,omitempty"` + FieldInstancePrivileges *PrivilegePolicyDef `xml:"fieldInstancePrivileges,omitempty"` +} + +func init() { + t["CustomFieldDef"] = reflect.TypeOf((*CustomFieldDef)(nil)).Elem() +} + +type CustomFieldDefAddedEvent struct { + CustomFieldDefEvent +} + +func init() { + t["CustomFieldDefAddedEvent"] = reflect.TypeOf((*CustomFieldDefAddedEvent)(nil)).Elem() +} + +type CustomFieldDefEvent struct { + CustomFieldEvent + + FieldKey int32 `xml:"fieldKey"` + Name string `xml:"name"` +} + +func init() { + t["CustomFieldDefEvent"] = reflect.TypeOf((*CustomFieldDefEvent)(nil)).Elem() +} + +type CustomFieldDefRemovedEvent struct { + CustomFieldDefEvent +} + +func init() { + t["CustomFieldDefRemovedEvent"] = reflect.TypeOf((*CustomFieldDefRemovedEvent)(nil)).Elem() +} + +type CustomFieldDefRenamedEvent struct { + CustomFieldDefEvent + + NewName string `xml:"newName"` +} + +func init() { + t["CustomFieldDefRenamedEvent"] = reflect.TypeOf((*CustomFieldDefRenamedEvent)(nil)).Elem() +} + +type CustomFieldEvent struct { + Event +} + +func init() { + t["CustomFieldEvent"] = reflect.TypeOf((*CustomFieldEvent)(nil)).Elem() +} + +type CustomFieldStringValue struct { + CustomFieldValue + + Value string `xml:"value"` +} + +func init() { + t["CustomFieldStringValue"] = reflect.TypeOf((*CustomFieldStringValue)(nil)).Elem() +} + +type CustomFieldValue struct { + DynamicData + + Key int32 `xml:"key"` +} + +func init() { + t["CustomFieldValue"] = reflect.TypeOf((*CustomFieldValue)(nil)).Elem() +} + +type CustomFieldValueChangedEvent struct { + CustomFieldEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + FieldKey int32 `xml:"fieldKey"` + Name string `xml:"name"` + Value string `xml:"value"` +} + +func init() { + t["CustomFieldValueChangedEvent"] = reflect.TypeOf((*CustomFieldValueChangedEvent)(nil)).Elem() +} + +type CustomizationAdapterMapping struct { + DynamicData + + MacAddress string `xml:"macAddress,omitempty"` + Adapter CustomizationIPSettings `xml:"adapter"` +} + +func init() { + t["CustomizationAdapterMapping"] = reflect.TypeOf((*CustomizationAdapterMapping)(nil)).Elem() +} + +type CustomizationAutoIpV6Generator struct { + CustomizationIpV6Generator +} + +func init() { + t["CustomizationAutoIpV6Generator"] = reflect.TypeOf((*CustomizationAutoIpV6Generator)(nil)).Elem() +} + +type CustomizationCustomIpGenerator struct { + CustomizationIpGenerator + + Argument string `xml:"argument,omitempty"` +} + +func init() { + t["CustomizationCustomIpGenerator"] = reflect.TypeOf((*CustomizationCustomIpGenerator)(nil)).Elem() +} + +type CustomizationCustomIpV6Generator struct { + CustomizationIpV6Generator + + Argument string `xml:"argument,omitempty"` +} + +func init() { + t["CustomizationCustomIpV6Generator"] = reflect.TypeOf((*CustomizationCustomIpV6Generator)(nil)).Elem() +} + +type CustomizationCustomName struct { + CustomizationName + + Argument string `xml:"argument,omitempty"` +} + +func init() { + t["CustomizationCustomName"] = reflect.TypeOf((*CustomizationCustomName)(nil)).Elem() +} + +type CustomizationDhcpIpGenerator struct { + CustomizationIpGenerator +} + +func init() { + t["CustomizationDhcpIpGenerator"] = reflect.TypeOf((*CustomizationDhcpIpGenerator)(nil)).Elem() +} + +type CustomizationDhcpIpV6Generator struct { + CustomizationIpV6Generator +} + +func init() { + t["CustomizationDhcpIpV6Generator"] = reflect.TypeOf((*CustomizationDhcpIpV6Generator)(nil)).Elem() +} + +type CustomizationEvent struct { + VmEvent + + LogLocation string `xml:"logLocation,omitempty"` +} + +func init() { + t["CustomizationEvent"] = reflect.TypeOf((*CustomizationEvent)(nil)).Elem() +} + +type CustomizationFailed struct { + CustomizationEvent +} + +func init() { + t["CustomizationFailed"] = reflect.TypeOf((*CustomizationFailed)(nil)).Elem() +} + +type CustomizationFault struct { + VimFault +} + +func init() { + t["CustomizationFault"] = reflect.TypeOf((*CustomizationFault)(nil)).Elem() +} + +type CustomizationFaultFault BaseCustomizationFault + +func init() { + t["CustomizationFaultFault"] = reflect.TypeOf((*CustomizationFaultFault)(nil)).Elem() +} + +type CustomizationFixedIp struct { + CustomizationIpGenerator + + IpAddress string `xml:"ipAddress"` +} + +func init() { + t["CustomizationFixedIp"] = reflect.TypeOf((*CustomizationFixedIp)(nil)).Elem() +} + +type CustomizationFixedIpV6 struct { + CustomizationIpV6Generator + + IpAddress string `xml:"ipAddress"` + SubnetMask int32 `xml:"subnetMask"` +} + +func init() { + t["CustomizationFixedIpV6"] = reflect.TypeOf((*CustomizationFixedIpV6)(nil)).Elem() +} + +type CustomizationFixedName struct { + CustomizationName + + Name string `xml:"name"` +} + +func init() { + t["CustomizationFixedName"] = reflect.TypeOf((*CustomizationFixedName)(nil)).Elem() +} + +type CustomizationGlobalIPSettings struct { + DynamicData + + DnsSuffixList []string `xml:"dnsSuffixList,omitempty"` + DnsServerList []string `xml:"dnsServerList,omitempty"` +} + +func init() { + t["CustomizationGlobalIPSettings"] = reflect.TypeOf((*CustomizationGlobalIPSettings)(nil)).Elem() +} + +type CustomizationGuiRunOnce struct { + DynamicData + + CommandList []string `xml:"commandList"` +} + +func init() { + t["CustomizationGuiRunOnce"] = reflect.TypeOf((*CustomizationGuiRunOnce)(nil)).Elem() +} + +type CustomizationGuiUnattended struct { + DynamicData + + Password *CustomizationPassword `xml:"password,omitempty"` + TimeZone int32 `xml:"timeZone"` + AutoLogon bool `xml:"autoLogon"` + AutoLogonCount int32 `xml:"autoLogonCount"` +} + +func init() { + t["CustomizationGuiUnattended"] = reflect.TypeOf((*CustomizationGuiUnattended)(nil)).Elem() +} + +type CustomizationIPSettings struct { + DynamicData + + Ip BaseCustomizationIpGenerator `xml:"ip,typeattr"` + SubnetMask string `xml:"subnetMask,omitempty"` + Gateway []string `xml:"gateway,omitempty"` + IpV6Spec *CustomizationIPSettingsIpV6AddressSpec `xml:"ipV6Spec,omitempty"` + DnsServerList []string `xml:"dnsServerList,omitempty"` + DnsDomain string `xml:"dnsDomain,omitempty"` + PrimaryWINS string `xml:"primaryWINS,omitempty"` + SecondaryWINS string `xml:"secondaryWINS,omitempty"` + NetBIOS CustomizationNetBIOSMode `xml:"netBIOS,omitempty"` +} + +func init() { + t["CustomizationIPSettings"] = reflect.TypeOf((*CustomizationIPSettings)(nil)).Elem() +} + +type CustomizationIPSettingsIpV6AddressSpec struct { + DynamicData + + Ip []BaseCustomizationIpV6Generator `xml:"ip,typeattr"` + Gateway []string `xml:"gateway,omitempty"` +} + +func init() { + t["CustomizationIPSettingsIpV6AddressSpec"] = reflect.TypeOf((*CustomizationIPSettingsIpV6AddressSpec)(nil)).Elem() +} + +type CustomizationIdentification struct { + DynamicData + + JoinWorkgroup string `xml:"joinWorkgroup,omitempty"` + JoinDomain string `xml:"joinDomain,omitempty"` + DomainAdmin string `xml:"domainAdmin,omitempty"` + DomainAdminPassword *CustomizationPassword `xml:"domainAdminPassword,omitempty"` +} + +func init() { + t["CustomizationIdentification"] = reflect.TypeOf((*CustomizationIdentification)(nil)).Elem() +} + +type CustomizationIdentitySettings struct { + DynamicData +} + +func init() { + t["CustomizationIdentitySettings"] = reflect.TypeOf((*CustomizationIdentitySettings)(nil)).Elem() +} + +type CustomizationIpGenerator struct { + DynamicData +} + +func init() { + t["CustomizationIpGenerator"] = reflect.TypeOf((*CustomizationIpGenerator)(nil)).Elem() +} + +type CustomizationIpV6Generator struct { + DynamicData +} + +func init() { + t["CustomizationIpV6Generator"] = reflect.TypeOf((*CustomizationIpV6Generator)(nil)).Elem() +} + +type CustomizationLicenseFilePrintData struct { + DynamicData + + AutoMode CustomizationLicenseDataMode `xml:"autoMode"` + AutoUsers int32 `xml:"autoUsers,omitempty"` +} + +func init() { + t["CustomizationLicenseFilePrintData"] = reflect.TypeOf((*CustomizationLicenseFilePrintData)(nil)).Elem() +} + +type CustomizationLinuxIdentityFailed struct { + CustomizationFailed +} + +func init() { + t["CustomizationLinuxIdentityFailed"] = reflect.TypeOf((*CustomizationLinuxIdentityFailed)(nil)).Elem() +} + +type CustomizationLinuxOptions struct { + CustomizationOptions +} + +func init() { + t["CustomizationLinuxOptions"] = reflect.TypeOf((*CustomizationLinuxOptions)(nil)).Elem() +} + +type CustomizationLinuxPrep struct { + CustomizationIdentitySettings + + HostName BaseCustomizationName `xml:"hostName,typeattr"` + Domain string `xml:"domain"` + TimeZone string `xml:"timeZone,omitempty"` + HwClockUTC *bool `xml:"hwClockUTC"` +} + +func init() { + t["CustomizationLinuxPrep"] = reflect.TypeOf((*CustomizationLinuxPrep)(nil)).Elem() +} + +type CustomizationName struct { + DynamicData +} + +func init() { + t["CustomizationName"] = reflect.TypeOf((*CustomizationName)(nil)).Elem() +} + +type CustomizationNetworkSetupFailed struct { + CustomizationFailed +} + +func init() { + t["CustomizationNetworkSetupFailed"] = reflect.TypeOf((*CustomizationNetworkSetupFailed)(nil)).Elem() +} + +type CustomizationOptions struct { + DynamicData +} + +func init() { + t["CustomizationOptions"] = reflect.TypeOf((*CustomizationOptions)(nil)).Elem() +} + +type CustomizationPassword struct { + DynamicData + + Value string `xml:"value"` + PlainText bool `xml:"plainText"` +} + +func init() { + t["CustomizationPassword"] = reflect.TypeOf((*CustomizationPassword)(nil)).Elem() +} + +type CustomizationPending struct { + CustomizationFault +} + +func init() { + t["CustomizationPending"] = reflect.TypeOf((*CustomizationPending)(nil)).Elem() +} + +type CustomizationPendingFault CustomizationPending + +func init() { + t["CustomizationPendingFault"] = reflect.TypeOf((*CustomizationPendingFault)(nil)).Elem() +} + +type CustomizationPrefixName struct { + CustomizationName + + Base string `xml:"base"` +} + +func init() { + t["CustomizationPrefixName"] = reflect.TypeOf((*CustomizationPrefixName)(nil)).Elem() +} + +type CustomizationSpec struct { + DynamicData + + Options BaseCustomizationOptions `xml:"options,omitempty,typeattr"` + Identity BaseCustomizationIdentitySettings `xml:"identity,typeattr"` + GlobalIPSettings CustomizationGlobalIPSettings `xml:"globalIPSettings"` + NicSettingMap []CustomizationAdapterMapping `xml:"nicSettingMap,omitempty"` + EncryptionKey []byte `xml:"encryptionKey,omitempty"` +} + +func init() { + t["CustomizationSpec"] = reflect.TypeOf((*CustomizationSpec)(nil)).Elem() +} + +type CustomizationSpecInfo struct { + DynamicData + + Name string `xml:"name"` + Description string `xml:"description"` + Type string `xml:"type"` + ChangeVersion string `xml:"changeVersion,omitempty"` + LastUpdateTime *time.Time `xml:"lastUpdateTime"` +} + +func init() { + t["CustomizationSpecInfo"] = reflect.TypeOf((*CustomizationSpecInfo)(nil)).Elem() +} + +type CustomizationSpecItem struct { + DynamicData + + Info CustomizationSpecInfo `xml:"info"` + Spec CustomizationSpec `xml:"spec"` +} + +func init() { + t["CustomizationSpecItem"] = reflect.TypeOf((*CustomizationSpecItem)(nil)).Elem() +} + +type CustomizationSpecItemToXml CustomizationSpecItemToXmlRequestType + +func init() { + t["CustomizationSpecItemToXml"] = reflect.TypeOf((*CustomizationSpecItemToXml)(nil)).Elem() +} + +type CustomizationSpecItemToXmlRequestType struct { + This ManagedObjectReference `xml:"_this"` + Item CustomizationSpecItem `xml:"item"` +} + +func init() { + t["CustomizationSpecItemToXmlRequestType"] = reflect.TypeOf((*CustomizationSpecItemToXmlRequestType)(nil)).Elem() +} + +type CustomizationSpecItemToXmlResponse struct { + Returnval string `xml:"returnval"` +} + +type CustomizationStartedEvent struct { + CustomizationEvent +} + +func init() { + t["CustomizationStartedEvent"] = reflect.TypeOf((*CustomizationStartedEvent)(nil)).Elem() +} + +type CustomizationStatelessIpV6Generator struct { + CustomizationIpV6Generator +} + +func init() { + t["CustomizationStatelessIpV6Generator"] = reflect.TypeOf((*CustomizationStatelessIpV6Generator)(nil)).Elem() +} + +type CustomizationSucceeded struct { + CustomizationEvent +} + +func init() { + t["CustomizationSucceeded"] = reflect.TypeOf((*CustomizationSucceeded)(nil)).Elem() +} + +type CustomizationSysprep struct { + CustomizationIdentitySettings + + GuiUnattended CustomizationGuiUnattended `xml:"guiUnattended"` + UserData CustomizationUserData `xml:"userData"` + GuiRunOnce *CustomizationGuiRunOnce `xml:"guiRunOnce,omitempty"` + Identification CustomizationIdentification `xml:"identification"` + LicenseFilePrintData *CustomizationLicenseFilePrintData `xml:"licenseFilePrintData,omitempty"` +} + +func init() { + t["CustomizationSysprep"] = reflect.TypeOf((*CustomizationSysprep)(nil)).Elem() +} + +type CustomizationSysprepFailed struct { + CustomizationFailed + + SysprepVersion string `xml:"sysprepVersion"` + SystemVersion string `xml:"systemVersion"` +} + +func init() { + t["CustomizationSysprepFailed"] = reflect.TypeOf((*CustomizationSysprepFailed)(nil)).Elem() +} + +type CustomizationSysprepText struct { + CustomizationIdentitySettings + + Value string `xml:"value"` +} + +func init() { + t["CustomizationSysprepText"] = reflect.TypeOf((*CustomizationSysprepText)(nil)).Elem() +} + +type CustomizationUnknownFailure struct { + CustomizationFailed +} + +func init() { + t["CustomizationUnknownFailure"] = reflect.TypeOf((*CustomizationUnknownFailure)(nil)).Elem() +} + +type CustomizationUnknownIpGenerator struct { + CustomizationIpGenerator +} + +func init() { + t["CustomizationUnknownIpGenerator"] = reflect.TypeOf((*CustomizationUnknownIpGenerator)(nil)).Elem() +} + +type CustomizationUnknownIpV6Generator struct { + CustomizationIpV6Generator +} + +func init() { + t["CustomizationUnknownIpV6Generator"] = reflect.TypeOf((*CustomizationUnknownIpV6Generator)(nil)).Elem() +} + +type CustomizationUnknownName struct { + CustomizationName +} + +func init() { + t["CustomizationUnknownName"] = reflect.TypeOf((*CustomizationUnknownName)(nil)).Elem() +} + +type CustomizationUserData struct { + DynamicData + + FullName string `xml:"fullName"` + OrgName string `xml:"orgName"` + ComputerName BaseCustomizationName `xml:"computerName,typeattr"` + ProductId string `xml:"productId"` +} + +func init() { + t["CustomizationUserData"] = reflect.TypeOf((*CustomizationUserData)(nil)).Elem() +} + +type CustomizationVirtualMachineName struct { + CustomizationName +} + +func init() { + t["CustomizationVirtualMachineName"] = reflect.TypeOf((*CustomizationVirtualMachineName)(nil)).Elem() +} + +type CustomizationWinOptions struct { + CustomizationOptions + + ChangeSID bool `xml:"changeSID"` + DeleteAccounts bool `xml:"deleteAccounts"` + Reboot CustomizationSysprepRebootOption `xml:"reboot,omitempty"` +} + +func init() { + t["CustomizationWinOptions"] = reflect.TypeOf((*CustomizationWinOptions)(nil)).Elem() +} + +type CustomizeVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec CustomizationSpec `xml:"spec"` +} + +func init() { + t["CustomizeVMRequestType"] = reflect.TypeOf((*CustomizeVMRequestType)(nil)).Elem() +} + +type CustomizeVM_Task CustomizeVMRequestType + +func init() { + t["CustomizeVM_Task"] = reflect.TypeOf((*CustomizeVM_Task)(nil)).Elem() +} + +type CustomizeVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DVPortConfigInfo struct { + DynamicData + + Name string `xml:"name,omitempty"` + Scope []ManagedObjectReference `xml:"scope,omitempty"` + Description string `xml:"description,omitempty"` + Setting BaseDVPortSetting `xml:"setting,omitempty,typeattr"` + ConfigVersion string `xml:"configVersion"` +} + +func init() { + t["DVPortConfigInfo"] = reflect.TypeOf((*DVPortConfigInfo)(nil)).Elem() +} + +type DVPortConfigSpec struct { + DynamicData + + Operation string `xml:"operation"` + Key string `xml:"key,omitempty"` + Name string `xml:"name,omitempty"` + Scope []ManagedObjectReference `xml:"scope,omitempty"` + Description string `xml:"description,omitempty"` + Setting BaseDVPortSetting `xml:"setting,omitempty,typeattr"` + ConfigVersion string `xml:"configVersion,omitempty"` +} + +func init() { + t["DVPortConfigSpec"] = reflect.TypeOf((*DVPortConfigSpec)(nil)).Elem() +} + +type DVPortNotSupported struct { + DeviceBackingNotSupported +} + +func init() { + t["DVPortNotSupported"] = reflect.TypeOf((*DVPortNotSupported)(nil)).Elem() +} + +type DVPortNotSupportedFault DVPortNotSupported + +func init() { + t["DVPortNotSupportedFault"] = reflect.TypeOf((*DVPortNotSupportedFault)(nil)).Elem() +} + +type DVPortSetting struct { + DynamicData + + Blocked *BoolPolicy `xml:"blocked,omitempty"` + VmDirectPathGen2Allowed *BoolPolicy `xml:"vmDirectPathGen2Allowed,omitempty"` + InShapingPolicy *DVSTrafficShapingPolicy `xml:"inShapingPolicy,omitempty"` + OutShapingPolicy *DVSTrafficShapingPolicy `xml:"outShapingPolicy,omitempty"` + VendorSpecificConfig *DVSVendorSpecificConfig `xml:"vendorSpecificConfig,omitempty"` + NetworkResourcePoolKey *StringPolicy `xml:"networkResourcePoolKey,omitempty"` + FilterPolicy *DvsFilterPolicy `xml:"filterPolicy,omitempty"` +} + +func init() { + t["DVPortSetting"] = reflect.TypeOf((*DVPortSetting)(nil)).Elem() +} + +type DVPortState struct { + DynamicData + + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` + Stats DistributedVirtualSwitchPortStatistics `xml:"stats"` + VendorSpecificState []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificState,omitempty"` +} + +func init() { + t["DVPortState"] = reflect.TypeOf((*DVPortState)(nil)).Elem() +} + +type DVPortStatus struct { + DynamicData + + LinkUp bool `xml:"linkUp"` + Blocked bool `xml:"blocked"` + VlanIds []NumericRange `xml:"vlanIds,omitempty"` + TrunkingMode *bool `xml:"trunkingMode"` + Mtu int32 `xml:"mtu,omitempty"` + LinkPeer string `xml:"linkPeer,omitempty"` + MacAddress string `xml:"macAddress,omitempty"` + StatusDetail string `xml:"statusDetail,omitempty"` + VmDirectPathGen2Active *bool `xml:"vmDirectPathGen2Active"` + VmDirectPathGen2InactiveReasonNetwork []string `xml:"vmDirectPathGen2InactiveReasonNetwork,omitempty"` + VmDirectPathGen2InactiveReasonOther []string `xml:"vmDirectPathGen2InactiveReasonOther,omitempty"` + VmDirectPathGen2InactiveReasonExtended string `xml:"vmDirectPathGen2InactiveReasonExtended,omitempty"` +} + +func init() { + t["DVPortStatus"] = reflect.TypeOf((*DVPortStatus)(nil)).Elem() +} + +type DVPortgroupConfigInfo struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name"` + NumPorts int32 `xml:"numPorts"` + DistributedVirtualSwitch *ManagedObjectReference `xml:"distributedVirtualSwitch,omitempty"` + DefaultPortConfig BaseDVPortSetting `xml:"defaultPortConfig,omitempty,typeattr"` + Description string `xml:"description,omitempty"` + Type string `xml:"type"` + Policy BaseDVPortgroupPolicy `xml:"policy,typeattr"` + PortNameFormat string `xml:"portNameFormat,omitempty"` + Scope []ManagedObjectReference `xml:"scope,omitempty"` + VendorSpecificConfig []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificConfig,omitempty"` + ConfigVersion string `xml:"configVersion,omitempty"` + AutoExpand *bool `xml:"autoExpand"` + VmVnicNetworkResourcePoolKey string `xml:"vmVnicNetworkResourcePoolKey,omitempty"` +} + +func init() { + t["DVPortgroupConfigInfo"] = reflect.TypeOf((*DVPortgroupConfigInfo)(nil)).Elem() +} + +type DVPortgroupConfigSpec struct { + DynamicData + + ConfigVersion string `xml:"configVersion,omitempty"` + Name string `xml:"name,omitempty"` + NumPorts int32 `xml:"numPorts,omitempty"` + PortNameFormat string `xml:"portNameFormat,omitempty"` + DefaultPortConfig BaseDVPortSetting `xml:"defaultPortConfig,omitempty,typeattr"` + Description string `xml:"description,omitempty"` + Type string `xml:"type,omitempty"` + Scope []ManagedObjectReference `xml:"scope,omitempty"` + Policy BaseDVPortgroupPolicy `xml:"policy,omitempty,typeattr"` + VendorSpecificConfig []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificConfig,omitempty"` + AutoExpand *bool `xml:"autoExpand"` + VmVnicNetworkResourcePoolKey string `xml:"vmVnicNetworkResourcePoolKey,omitempty"` +} + +func init() { + t["DVPortgroupConfigSpec"] = reflect.TypeOf((*DVPortgroupConfigSpec)(nil)).Elem() +} + +type DVPortgroupCreatedEvent struct { + DVPortgroupEvent +} + +func init() { + t["DVPortgroupCreatedEvent"] = reflect.TypeOf((*DVPortgroupCreatedEvent)(nil)).Elem() +} + +type DVPortgroupDestroyedEvent struct { + DVPortgroupEvent +} + +func init() { + t["DVPortgroupDestroyedEvent"] = reflect.TypeOf((*DVPortgroupDestroyedEvent)(nil)).Elem() +} + +type DVPortgroupEvent struct { + Event +} + +func init() { + t["DVPortgroupEvent"] = reflect.TypeOf((*DVPortgroupEvent)(nil)).Elem() +} + +type DVPortgroupPolicy struct { + DynamicData + + BlockOverrideAllowed bool `xml:"blockOverrideAllowed"` + ShapingOverrideAllowed bool `xml:"shapingOverrideAllowed"` + VendorConfigOverrideAllowed bool `xml:"vendorConfigOverrideAllowed"` + LivePortMovingAllowed bool `xml:"livePortMovingAllowed"` + PortConfigResetAtDisconnect bool `xml:"portConfigResetAtDisconnect"` + NetworkResourcePoolOverrideAllowed *bool `xml:"networkResourcePoolOverrideAllowed"` + TrafficFilterOverrideAllowed *bool `xml:"trafficFilterOverrideAllowed"` +} + +func init() { + t["DVPortgroupPolicy"] = reflect.TypeOf((*DVPortgroupPolicy)(nil)).Elem() +} + +type DVPortgroupReconfiguredEvent struct { + DVPortgroupEvent + + ConfigSpec DVPortgroupConfigSpec `xml:"configSpec"` +} + +func init() { + t["DVPortgroupReconfiguredEvent"] = reflect.TypeOf((*DVPortgroupReconfiguredEvent)(nil)).Elem() +} + +type DVPortgroupRenamedEvent struct { + DVPortgroupEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["DVPortgroupRenamedEvent"] = reflect.TypeOf((*DVPortgroupRenamedEvent)(nil)).Elem() +} + +type DVPortgroupRollbackRequestType struct { + This ManagedObjectReference `xml:"_this"` + EntityBackup *EntityBackupConfig `xml:"entityBackup,omitempty"` +} + +func init() { + t["DVPortgroupRollbackRequestType"] = reflect.TypeOf((*DVPortgroupRollbackRequestType)(nil)).Elem() +} + +type DVPortgroupRollback_Task DVPortgroupRollbackRequestType + +func init() { + t["DVPortgroupRollback_Task"] = reflect.TypeOf((*DVPortgroupRollback_Task)(nil)).Elem() +} + +type DVPortgroupRollback_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DVPortgroupSelection struct { + SelectionSet + + DvsUuid string `xml:"dvsUuid"` + PortgroupKey []string `xml:"portgroupKey"` +} + +func init() { + t["DVPortgroupSelection"] = reflect.TypeOf((*DVPortgroupSelection)(nil)).Elem() +} + +type DVSBackupRestoreCapability struct { + DynamicData + + BackupRestoreSupported bool `xml:"backupRestoreSupported"` +} + +func init() { + t["DVSBackupRestoreCapability"] = reflect.TypeOf((*DVSBackupRestoreCapability)(nil)).Elem() +} + +type DVSCapability struct { + DynamicData + + DvsOperationSupported *bool `xml:"dvsOperationSupported"` + DvPortGroupOperationSupported *bool `xml:"dvPortGroupOperationSupported"` + DvPortOperationSupported *bool `xml:"dvPortOperationSupported"` + CompatibleHostComponentProductInfo []DistributedVirtualSwitchHostProductSpec `xml:"compatibleHostComponentProductInfo,omitempty"` + FeaturesSupported BaseDVSFeatureCapability `xml:"featuresSupported,omitempty,typeattr"` +} + +func init() { + t["DVSCapability"] = reflect.TypeOf((*DVSCapability)(nil)).Elem() +} + +type DVSConfigInfo struct { + DynamicData + + Uuid string `xml:"uuid"` + Name string `xml:"name"` + NumStandalonePorts int32 `xml:"numStandalonePorts"` + NumPorts int32 `xml:"numPorts"` + MaxPorts int32 `xml:"maxPorts"` + UplinkPortPolicy BaseDVSUplinkPortPolicy `xml:"uplinkPortPolicy,typeattr"` + UplinkPortgroup []ManagedObjectReference `xml:"uplinkPortgroup,omitempty"` + DefaultPortConfig BaseDVPortSetting `xml:"defaultPortConfig,typeattr"` + Host []DistributedVirtualSwitchHostMember `xml:"host,omitempty"` + ProductInfo DistributedVirtualSwitchProductSpec `xml:"productInfo"` + TargetInfo *DistributedVirtualSwitchProductSpec `xml:"targetInfo,omitempty"` + ExtensionKey string `xml:"extensionKey,omitempty"` + VendorSpecificConfig []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificConfig,omitempty"` + Policy *DVSPolicy `xml:"policy,omitempty"` + Description string `xml:"description,omitempty"` + ConfigVersion string `xml:"configVersion"` + Contact DVSContactInfo `xml:"contact"` + SwitchIpAddress string `xml:"switchIpAddress,omitempty"` + CreateTime time.Time `xml:"createTime"` + NetworkResourceManagementEnabled *bool `xml:"networkResourceManagementEnabled"` + DefaultProxySwitchMaxNumPorts int32 `xml:"defaultProxySwitchMaxNumPorts,omitempty"` + HealthCheckConfig []BaseDVSHealthCheckConfig `xml:"healthCheckConfig,omitempty,typeattr"` + InfrastructureTrafficResourceConfig []DvsHostInfrastructureTrafficResource `xml:"infrastructureTrafficResourceConfig,omitempty"` + NetworkResourceControlVersion string `xml:"networkResourceControlVersion,omitempty"` + VmVnicNetworkResourcePool []DVSVmVnicNetworkResourcePool `xml:"vmVnicNetworkResourcePool,omitempty"` + PnicCapacityRatioForReservation int32 `xml:"pnicCapacityRatioForReservation,omitempty"` +} + +func init() { + t["DVSConfigInfo"] = reflect.TypeOf((*DVSConfigInfo)(nil)).Elem() +} + +type DVSConfigSpec struct { + DynamicData + + ConfigVersion string `xml:"configVersion,omitempty"` + Name string `xml:"name,omitempty"` + NumStandalonePorts int32 `xml:"numStandalonePorts,omitempty"` + MaxPorts int32 `xml:"maxPorts,omitempty"` + UplinkPortPolicy BaseDVSUplinkPortPolicy `xml:"uplinkPortPolicy,omitempty,typeattr"` + UplinkPortgroup []ManagedObjectReference `xml:"uplinkPortgroup,omitempty"` + DefaultPortConfig BaseDVPortSetting `xml:"defaultPortConfig,omitempty,typeattr"` + Host []DistributedVirtualSwitchHostMemberConfigSpec `xml:"host,omitempty"` + ExtensionKey string `xml:"extensionKey,omitempty"` + Description string `xml:"description,omitempty"` + Policy *DVSPolicy `xml:"policy,omitempty"` + VendorSpecificConfig []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificConfig,omitempty"` + Contact *DVSContactInfo `xml:"contact,omitempty"` + SwitchIpAddress string `xml:"switchIpAddress,omitempty"` + DefaultProxySwitchMaxNumPorts int32 `xml:"defaultProxySwitchMaxNumPorts,omitempty"` + InfrastructureTrafficResourceConfig []DvsHostInfrastructureTrafficResource `xml:"infrastructureTrafficResourceConfig,omitempty"` + NetworkResourceControlVersion string `xml:"networkResourceControlVersion,omitempty"` +} + +func init() { + t["DVSConfigSpec"] = reflect.TypeOf((*DVSConfigSpec)(nil)).Elem() +} + +type DVSContactInfo struct { + DynamicData + + Name string `xml:"name,omitempty"` + Contact string `xml:"contact,omitempty"` +} + +func init() { + t["DVSContactInfo"] = reflect.TypeOf((*DVSContactInfo)(nil)).Elem() +} + +type DVSCreateSpec struct { + DynamicData + + ConfigSpec BaseDVSConfigSpec `xml:"configSpec,typeattr"` + ProductInfo *DistributedVirtualSwitchProductSpec `xml:"productInfo,omitempty"` + Capability *DVSCapability `xml:"capability,omitempty"` +} + +func init() { + t["DVSCreateSpec"] = reflect.TypeOf((*DVSCreateSpec)(nil)).Elem() +} + +type DVSFailureCriteria struct { + InheritablePolicy + + CheckSpeed *StringPolicy `xml:"checkSpeed,omitempty"` + Speed *IntPolicy `xml:"speed,omitempty"` + CheckDuplex *BoolPolicy `xml:"checkDuplex,omitempty"` + FullDuplex *BoolPolicy `xml:"fullDuplex,omitempty"` + CheckErrorPercent *BoolPolicy `xml:"checkErrorPercent,omitempty"` + Percentage *IntPolicy `xml:"percentage,omitempty"` + CheckBeacon *BoolPolicy `xml:"checkBeacon,omitempty"` +} + +func init() { + t["DVSFailureCriteria"] = reflect.TypeOf((*DVSFailureCriteria)(nil)).Elem() +} + +type DVSFeatureCapability struct { + DynamicData + + NetworkResourceManagementSupported bool `xml:"networkResourceManagementSupported"` + VmDirectPathGen2Supported bool `xml:"vmDirectPathGen2Supported"` + NicTeamingPolicy []string `xml:"nicTeamingPolicy,omitempty"` + NetworkResourcePoolHighShareValue int32 `xml:"networkResourcePoolHighShareValue,omitempty"` + NetworkResourceManagementCapability *DVSNetworkResourceManagementCapability `xml:"networkResourceManagementCapability,omitempty"` + HealthCheckCapability BaseDVSHealthCheckCapability `xml:"healthCheckCapability,omitempty,typeattr"` + RollbackCapability *DVSRollbackCapability `xml:"rollbackCapability,omitempty"` + BackupRestoreCapability *DVSBackupRestoreCapability `xml:"backupRestoreCapability,omitempty"` + NetworkFilterSupported *bool `xml:"networkFilterSupported"` +} + +func init() { + t["DVSFeatureCapability"] = reflect.TypeOf((*DVSFeatureCapability)(nil)).Elem() +} + +type DVSHealthCheckCapability struct { + DynamicData +} + +func init() { + t["DVSHealthCheckCapability"] = reflect.TypeOf((*DVSHealthCheckCapability)(nil)).Elem() +} + +type DVSHealthCheckConfig struct { + DynamicData + + Enable *bool `xml:"enable"` + Interval int32 `xml:"interval,omitempty"` +} + +func init() { + t["DVSHealthCheckConfig"] = reflect.TypeOf((*DVSHealthCheckConfig)(nil)).Elem() +} + +type DVSHostLocalPortInfo struct { + DynamicData + + SwitchUuid string `xml:"switchUuid"` + PortKey string `xml:"portKey"` + Setting BaseDVPortSetting `xml:"setting,typeattr"` + Vnic string `xml:"vnic"` +} + +func init() { + t["DVSHostLocalPortInfo"] = reflect.TypeOf((*DVSHostLocalPortInfo)(nil)).Elem() +} + +type DVSManagerDvsConfigTarget struct { + DynamicData + + DistributedVirtualPortgroup []DistributedVirtualPortgroupInfo `xml:"distributedVirtualPortgroup,omitempty"` + DistributedVirtualSwitch []DistributedVirtualSwitchInfo `xml:"distributedVirtualSwitch,omitempty"` +} + +func init() { + t["DVSManagerDvsConfigTarget"] = reflect.TypeOf((*DVSManagerDvsConfigTarget)(nil)).Elem() +} + +type DVSManagerExportEntityRequestType struct { + This ManagedObjectReference `xml:"_this"` + SelectionSet []BaseSelectionSet `xml:"selectionSet,typeattr"` +} + +func init() { + t["DVSManagerExportEntityRequestType"] = reflect.TypeOf((*DVSManagerExportEntityRequestType)(nil)).Elem() +} + +type DVSManagerExportEntity_Task DVSManagerExportEntityRequestType + +func init() { + t["DVSManagerExportEntity_Task"] = reflect.TypeOf((*DVSManagerExportEntity_Task)(nil)).Elem() +} + +type DVSManagerExportEntity_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DVSManagerImportEntityRequestType struct { + This ManagedObjectReference `xml:"_this"` + EntityBackup []EntityBackupConfig `xml:"entityBackup"` + ImportType string `xml:"importType"` +} + +func init() { + t["DVSManagerImportEntityRequestType"] = reflect.TypeOf((*DVSManagerImportEntityRequestType)(nil)).Elem() +} + +type DVSManagerImportEntity_Task DVSManagerImportEntityRequestType + +func init() { + t["DVSManagerImportEntity_Task"] = reflect.TypeOf((*DVSManagerImportEntity_Task)(nil)).Elem() +} + +type DVSManagerImportEntity_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DVSManagerLookupDvPortGroup DVSManagerLookupDvPortGroupRequestType + +func init() { + t["DVSManagerLookupDvPortGroup"] = reflect.TypeOf((*DVSManagerLookupDvPortGroup)(nil)).Elem() +} + +type DVSManagerLookupDvPortGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + SwitchUuid string `xml:"switchUuid"` + PortgroupKey string `xml:"portgroupKey"` +} + +func init() { + t["DVSManagerLookupDvPortGroupRequestType"] = reflect.TypeOf((*DVSManagerLookupDvPortGroupRequestType)(nil)).Elem() +} + +type DVSManagerLookupDvPortGroupResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type DVSNameArrayUplinkPortPolicy struct { + DVSUplinkPortPolicy + + UplinkPortName []string `xml:"uplinkPortName"` +} + +func init() { + t["DVSNameArrayUplinkPortPolicy"] = reflect.TypeOf((*DVSNameArrayUplinkPortPolicy)(nil)).Elem() +} + +type DVSNetworkResourceManagementCapability struct { + DynamicData + + NetworkResourceManagementSupported bool `xml:"networkResourceManagementSupported"` + NetworkResourcePoolHighShareValue int32 `xml:"networkResourcePoolHighShareValue"` + QosSupported bool `xml:"qosSupported"` + UserDefinedNetworkResourcePoolsSupported bool `xml:"userDefinedNetworkResourcePoolsSupported"` + NetworkResourceControlVersion3Supported *bool `xml:"networkResourceControlVersion3Supported"` +} + +func init() { + t["DVSNetworkResourceManagementCapability"] = reflect.TypeOf((*DVSNetworkResourceManagementCapability)(nil)).Elem() +} + +type DVSNetworkResourcePool struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` + ConfigVersion string `xml:"configVersion"` + AllocationInfo DVSNetworkResourcePoolAllocationInfo `xml:"allocationInfo"` +} + +func init() { + t["DVSNetworkResourcePool"] = reflect.TypeOf((*DVSNetworkResourcePool)(nil)).Elem() +} + +type DVSNetworkResourcePoolAllocationInfo struct { + DynamicData + + Limit int64 `xml:"limit,omitempty"` + Shares *SharesInfo `xml:"shares,omitempty"` + PriorityTag int32 `xml:"priorityTag,omitempty"` +} + +func init() { + t["DVSNetworkResourcePoolAllocationInfo"] = reflect.TypeOf((*DVSNetworkResourcePoolAllocationInfo)(nil)).Elem() +} + +type DVSNetworkResourcePoolConfigSpec struct { + DynamicData + + Key string `xml:"key"` + ConfigVersion string `xml:"configVersion,omitempty"` + AllocationInfo *DVSNetworkResourcePoolAllocationInfo `xml:"allocationInfo,omitempty"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["DVSNetworkResourcePoolConfigSpec"] = reflect.TypeOf((*DVSNetworkResourcePoolConfigSpec)(nil)).Elem() +} + +type DVSPolicy struct { + DynamicData + + AutoPreInstallAllowed *bool `xml:"autoPreInstallAllowed"` + AutoUpgradeAllowed *bool `xml:"autoUpgradeAllowed"` + PartialUpgradeAllowed *bool `xml:"partialUpgradeAllowed"` +} + +func init() { + t["DVSPolicy"] = reflect.TypeOf((*DVSPolicy)(nil)).Elem() +} + +type DVSRollbackCapability struct { + DynamicData + + RollbackSupported bool `xml:"rollbackSupported"` +} + +func init() { + t["DVSRollbackCapability"] = reflect.TypeOf((*DVSRollbackCapability)(nil)).Elem() +} + +type DVSRollbackRequestType struct { + This ManagedObjectReference `xml:"_this"` + EntityBackup *EntityBackupConfig `xml:"entityBackup,omitempty"` +} + +func init() { + t["DVSRollbackRequestType"] = reflect.TypeOf((*DVSRollbackRequestType)(nil)).Elem() +} + +type DVSRollback_Task DVSRollbackRequestType + +func init() { + t["DVSRollback_Task"] = reflect.TypeOf((*DVSRollback_Task)(nil)).Elem() +} + +type DVSRollback_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DVSRuntimeInfo struct { + DynamicData + + HostMemberRuntime []HostMemberRuntimeInfo `xml:"hostMemberRuntime,omitempty"` + ResourceRuntimeInfo *DvsResourceRuntimeInfo `xml:"resourceRuntimeInfo,omitempty"` +} + +func init() { + t["DVSRuntimeInfo"] = reflect.TypeOf((*DVSRuntimeInfo)(nil)).Elem() +} + +type DVSSecurityPolicy struct { + InheritablePolicy + + AllowPromiscuous *BoolPolicy `xml:"allowPromiscuous,omitempty"` + MacChanges *BoolPolicy `xml:"macChanges,omitempty"` + ForgedTransmits *BoolPolicy `xml:"forgedTransmits,omitempty"` +} + +func init() { + t["DVSSecurityPolicy"] = reflect.TypeOf((*DVSSecurityPolicy)(nil)).Elem() +} + +type DVSSelection struct { + SelectionSet + + DvsUuid string `xml:"dvsUuid"` +} + +func init() { + t["DVSSelection"] = reflect.TypeOf((*DVSSelection)(nil)).Elem() +} + +type DVSSummary struct { + DynamicData + + Name string `xml:"name"` + Uuid string `xml:"uuid"` + NumPorts int32 `xml:"numPorts"` + ProductInfo *DistributedVirtualSwitchProductSpec `xml:"productInfo,omitempty"` + HostMember []ManagedObjectReference `xml:"hostMember,omitempty"` + Vm []ManagedObjectReference `xml:"vm,omitempty"` + Host []ManagedObjectReference `xml:"host,omitempty"` + PortgroupName []string `xml:"portgroupName,omitempty"` + Description string `xml:"description,omitempty"` + Contact *DVSContactInfo `xml:"contact,omitempty"` + NumHosts int32 `xml:"numHosts,omitempty"` +} + +func init() { + t["DVSSummary"] = reflect.TypeOf((*DVSSummary)(nil)).Elem() +} + +type DVSTrafficShapingPolicy struct { + InheritablePolicy + + Enabled *BoolPolicy `xml:"enabled,omitempty"` + AverageBandwidth *LongPolicy `xml:"averageBandwidth,omitempty"` + PeakBandwidth *LongPolicy `xml:"peakBandwidth,omitempty"` + BurstSize *LongPolicy `xml:"burstSize,omitempty"` +} + +func init() { + t["DVSTrafficShapingPolicy"] = reflect.TypeOf((*DVSTrafficShapingPolicy)(nil)).Elem() +} + +type DVSUplinkPortPolicy struct { + DynamicData +} + +func init() { + t["DVSUplinkPortPolicy"] = reflect.TypeOf((*DVSUplinkPortPolicy)(nil)).Elem() +} + +type DVSVendorSpecificConfig struct { + InheritablePolicy + + KeyValue []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"keyValue,omitempty"` +} + +func init() { + t["DVSVendorSpecificConfig"] = reflect.TypeOf((*DVSVendorSpecificConfig)(nil)).Elem() +} + +type DVSVmVnicNetworkResourcePool struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` + ConfigVersion string `xml:"configVersion"` + AllocationInfo *DvsVmVnicResourceAllocation `xml:"allocationInfo,omitempty"` +} + +func init() { + t["DVSVmVnicNetworkResourcePool"] = reflect.TypeOf((*DVSVmVnicNetworkResourcePool)(nil)).Elem() +} + +type DailyTaskScheduler struct { + HourlyTaskScheduler + + Hour int32 `xml:"hour"` +} + +func init() { + t["DailyTaskScheduler"] = reflect.TypeOf((*DailyTaskScheduler)(nil)).Elem() +} + +type DasAdmissionControlDisabledEvent struct { + ClusterEvent +} + +func init() { + t["DasAdmissionControlDisabledEvent"] = reflect.TypeOf((*DasAdmissionControlDisabledEvent)(nil)).Elem() +} + +type DasAdmissionControlEnabledEvent struct { + ClusterEvent +} + +func init() { + t["DasAdmissionControlEnabledEvent"] = reflect.TypeOf((*DasAdmissionControlEnabledEvent)(nil)).Elem() +} + +type DasAgentFoundEvent struct { + ClusterEvent +} + +func init() { + t["DasAgentFoundEvent"] = reflect.TypeOf((*DasAgentFoundEvent)(nil)).Elem() +} + +type DasAgentUnavailableEvent struct { + ClusterEvent +} + +func init() { + t["DasAgentUnavailableEvent"] = reflect.TypeOf((*DasAgentUnavailableEvent)(nil)).Elem() +} + +type DasClusterIsolatedEvent struct { + ClusterEvent +} + +func init() { + t["DasClusterIsolatedEvent"] = reflect.TypeOf((*DasClusterIsolatedEvent)(nil)).Elem() +} + +type DasConfigFault struct { + VimFault + + Reason string `xml:"reason,omitempty"` + Output string `xml:"output,omitempty"` + Event []BaseEvent `xml:"event,omitempty,typeattr"` +} + +func init() { + t["DasConfigFault"] = reflect.TypeOf((*DasConfigFault)(nil)).Elem() +} + +type DasConfigFaultFault DasConfigFault + +func init() { + t["DasConfigFaultFault"] = reflect.TypeOf((*DasConfigFaultFault)(nil)).Elem() +} + +type DasDisabledEvent struct { + ClusterEvent +} + +func init() { + t["DasDisabledEvent"] = reflect.TypeOf((*DasDisabledEvent)(nil)).Elem() +} + +type DasEnabledEvent struct { + ClusterEvent +} + +func init() { + t["DasEnabledEvent"] = reflect.TypeOf((*DasEnabledEvent)(nil)).Elem() +} + +type DasHeartbeatDatastoreInfo struct { + DynamicData + + Datastore ManagedObjectReference `xml:"datastore"` + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["DasHeartbeatDatastoreInfo"] = reflect.TypeOf((*DasHeartbeatDatastoreInfo)(nil)).Elem() +} + +type DasHostFailedEvent struct { + ClusterEvent + + FailedHost HostEventArgument `xml:"failedHost"` +} + +func init() { + t["DasHostFailedEvent"] = reflect.TypeOf((*DasHostFailedEvent)(nil)).Elem() +} + +type DasHostIsolatedEvent struct { + ClusterEvent + + IsolatedHost HostEventArgument `xml:"isolatedHost"` +} + +func init() { + t["DasHostIsolatedEvent"] = reflect.TypeOf((*DasHostIsolatedEvent)(nil)).Elem() +} + +type DatabaseError struct { + RuntimeFault +} + +func init() { + t["DatabaseError"] = reflect.TypeOf((*DatabaseError)(nil)).Elem() +} + +type DatabaseErrorFault DatabaseError + +func init() { + t["DatabaseErrorFault"] = reflect.TypeOf((*DatabaseErrorFault)(nil)).Elem() +} + +type DatabaseSizeEstimate struct { + DynamicData + + Size int64 `xml:"size"` +} + +func init() { + t["DatabaseSizeEstimate"] = reflect.TypeOf((*DatabaseSizeEstimate)(nil)).Elem() +} + +type DatabaseSizeParam struct { + DynamicData + + InventoryDesc InventoryDescription `xml:"inventoryDesc"` + PerfStatsDesc *PerformanceStatisticsDescription `xml:"perfStatsDesc,omitempty"` +} + +func init() { + t["DatabaseSizeParam"] = reflect.TypeOf((*DatabaseSizeParam)(nil)).Elem() +} + +type DatacenterConfigInfo struct { + DynamicData + + DefaultHardwareVersionKey string `xml:"defaultHardwareVersionKey,omitempty"` +} + +func init() { + t["DatacenterConfigInfo"] = reflect.TypeOf((*DatacenterConfigInfo)(nil)).Elem() +} + +type DatacenterConfigSpec struct { + DynamicData + + DefaultHardwareVersionKey string `xml:"defaultHardwareVersionKey,omitempty"` +} + +func init() { + t["DatacenterConfigSpec"] = reflect.TypeOf((*DatacenterConfigSpec)(nil)).Elem() +} + +type DatacenterCreatedEvent struct { + DatacenterEvent + + Parent FolderEventArgument `xml:"parent"` +} + +func init() { + t["DatacenterCreatedEvent"] = reflect.TypeOf((*DatacenterCreatedEvent)(nil)).Elem() +} + +type DatacenterEvent struct { + Event +} + +func init() { + t["DatacenterEvent"] = reflect.TypeOf((*DatacenterEvent)(nil)).Elem() +} + +type DatacenterEventArgument struct { + EntityEventArgument + + Datacenter ManagedObjectReference `xml:"datacenter"` +} + +func init() { + t["DatacenterEventArgument"] = reflect.TypeOf((*DatacenterEventArgument)(nil)).Elem() +} + +type DatacenterMismatch struct { + MigrationFault + + InvalidArgument []DatacenterMismatchArgument `xml:"invalidArgument"` + ExpectedDatacenter ManagedObjectReference `xml:"expectedDatacenter"` +} + +func init() { + t["DatacenterMismatch"] = reflect.TypeOf((*DatacenterMismatch)(nil)).Elem() +} + +type DatacenterMismatchArgument struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` + InputDatacenter *ManagedObjectReference `xml:"inputDatacenter,omitempty"` +} + +func init() { + t["DatacenterMismatchArgument"] = reflect.TypeOf((*DatacenterMismatchArgument)(nil)).Elem() +} + +type DatacenterMismatchFault DatacenterMismatch + +func init() { + t["DatacenterMismatchFault"] = reflect.TypeOf((*DatacenterMismatchFault)(nil)).Elem() +} + +type DatacenterRenamedEvent struct { + DatacenterEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["DatacenterRenamedEvent"] = reflect.TypeOf((*DatacenterRenamedEvent)(nil)).Elem() +} + +type DatastoreCapability struct { + DynamicData + + DirectoryHierarchySupported bool `xml:"directoryHierarchySupported"` + RawDiskMappingsSupported bool `xml:"rawDiskMappingsSupported"` + PerFileThinProvisioningSupported bool `xml:"perFileThinProvisioningSupported"` + StorageIORMSupported *bool `xml:"storageIORMSupported"` + NativeSnapshotSupported *bool `xml:"nativeSnapshotSupported"` + TopLevelDirectoryCreateSupported *bool `xml:"topLevelDirectoryCreateSupported"` + SeSparseSupported *bool `xml:"seSparseSupported"` +} + +func init() { + t["DatastoreCapability"] = reflect.TypeOf((*DatastoreCapability)(nil)).Elem() +} + +type DatastoreCapacityIncreasedEvent struct { + DatastoreEvent + + OldCapacity int64 `xml:"oldCapacity"` + NewCapacity int64 `xml:"newCapacity"` +} + +func init() { + t["DatastoreCapacityIncreasedEvent"] = reflect.TypeOf((*DatastoreCapacityIncreasedEvent)(nil)).Elem() +} + +type DatastoreDestroyedEvent struct { + DatastoreEvent +} + +func init() { + t["DatastoreDestroyedEvent"] = reflect.TypeOf((*DatastoreDestroyedEvent)(nil)).Elem() +} + +type DatastoreDiscoveredEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["DatastoreDiscoveredEvent"] = reflect.TypeOf((*DatastoreDiscoveredEvent)(nil)).Elem() +} + +type DatastoreDuplicatedEvent struct { + DatastoreEvent +} + +func init() { + t["DatastoreDuplicatedEvent"] = reflect.TypeOf((*DatastoreDuplicatedEvent)(nil)).Elem() +} + +type DatastoreEnterMaintenanceMode DatastoreEnterMaintenanceModeRequestType + +func init() { + t["DatastoreEnterMaintenanceMode"] = reflect.TypeOf((*DatastoreEnterMaintenanceMode)(nil)).Elem() +} + +type DatastoreEnterMaintenanceModeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DatastoreEnterMaintenanceModeRequestType"] = reflect.TypeOf((*DatastoreEnterMaintenanceModeRequestType)(nil)).Elem() +} + +type DatastoreEnterMaintenanceModeResponse struct { + Returnval StoragePlacementResult `xml:"returnval"` +} + +type DatastoreEvent struct { + Event + + Datastore *DatastoreEventArgument `xml:"datastore,omitempty"` +} + +func init() { + t["DatastoreEvent"] = reflect.TypeOf((*DatastoreEvent)(nil)).Elem() +} + +type DatastoreEventArgument struct { + EntityEventArgument + + Datastore ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["DatastoreEventArgument"] = reflect.TypeOf((*DatastoreEventArgument)(nil)).Elem() +} + +type DatastoreExitMaintenanceModeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DatastoreExitMaintenanceModeRequestType"] = reflect.TypeOf((*DatastoreExitMaintenanceModeRequestType)(nil)).Elem() +} + +type DatastoreExitMaintenanceMode_Task DatastoreExitMaintenanceModeRequestType + +func init() { + t["DatastoreExitMaintenanceMode_Task"] = reflect.TypeOf((*DatastoreExitMaintenanceMode_Task)(nil)).Elem() +} + +type DatastoreExitMaintenanceMode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DatastoreFileCopiedEvent struct { + DatastoreFileEvent + + SourceDatastore DatastoreEventArgument `xml:"sourceDatastore"` + SourceFile string `xml:"sourceFile"` +} + +func init() { + t["DatastoreFileCopiedEvent"] = reflect.TypeOf((*DatastoreFileCopiedEvent)(nil)).Elem() +} + +type DatastoreFileDeletedEvent struct { + DatastoreFileEvent +} + +func init() { + t["DatastoreFileDeletedEvent"] = reflect.TypeOf((*DatastoreFileDeletedEvent)(nil)).Elem() +} + +type DatastoreFileEvent struct { + DatastoreEvent + + TargetFile string `xml:"targetFile"` +} + +func init() { + t["DatastoreFileEvent"] = reflect.TypeOf((*DatastoreFileEvent)(nil)).Elem() +} + +type DatastoreFileMovedEvent struct { + DatastoreFileEvent + + SourceDatastore DatastoreEventArgument `xml:"sourceDatastore"` + SourceFile string `xml:"sourceFile"` +} + +func init() { + t["DatastoreFileMovedEvent"] = reflect.TypeOf((*DatastoreFileMovedEvent)(nil)).Elem() +} + +type DatastoreHostMount struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + MountInfo HostMountInfo `xml:"mountInfo"` +} + +func init() { + t["DatastoreHostMount"] = reflect.TypeOf((*DatastoreHostMount)(nil)).Elem() +} + +type DatastoreIORMReconfiguredEvent struct { + DatastoreEvent +} + +func init() { + t["DatastoreIORMReconfiguredEvent"] = reflect.TypeOf((*DatastoreIORMReconfiguredEvent)(nil)).Elem() +} + +type DatastoreInfo struct { + DynamicData + + Name string `xml:"name"` + Url string `xml:"url"` + FreeSpace int64 `xml:"freeSpace"` + MaxFileSize int64 `xml:"maxFileSize"` + MaxVirtualDiskCapacity int64 `xml:"maxVirtualDiskCapacity,omitempty"` + MaxMemoryFileSize int64 `xml:"maxMemoryFileSize,omitempty"` + Timestamp *time.Time `xml:"timestamp"` + ContainerId string `xml:"containerId,omitempty"` +} + +func init() { + t["DatastoreInfo"] = reflect.TypeOf((*DatastoreInfo)(nil)).Elem() +} + +type DatastoreMountPathDatastorePair struct { + DynamicData + + OldMountPath string `xml:"oldMountPath"` + Datastore ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["DatastoreMountPathDatastorePair"] = reflect.TypeOf((*DatastoreMountPathDatastorePair)(nil)).Elem() +} + +type DatastoreNotWritableOnHost struct { + InvalidDatastore + + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["DatastoreNotWritableOnHost"] = reflect.TypeOf((*DatastoreNotWritableOnHost)(nil)).Elem() +} + +type DatastoreNotWritableOnHostFault BaseDatastoreNotWritableOnHost + +func init() { + t["DatastoreNotWritableOnHostFault"] = reflect.TypeOf((*DatastoreNotWritableOnHostFault)(nil)).Elem() +} + +type DatastoreOption struct { + DynamicData + + UnsupportedVolumes []VirtualMachineDatastoreVolumeOption `xml:"unsupportedVolumes,omitempty"` +} + +func init() { + t["DatastoreOption"] = reflect.TypeOf((*DatastoreOption)(nil)).Elem() +} + +type DatastorePrincipalConfigured struct { + HostEvent + + DatastorePrincipal string `xml:"datastorePrincipal"` +} + +func init() { + t["DatastorePrincipalConfigured"] = reflect.TypeOf((*DatastorePrincipalConfigured)(nil)).Elem() +} + +type DatastoreRemovedOnHostEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["DatastoreRemovedOnHostEvent"] = reflect.TypeOf((*DatastoreRemovedOnHostEvent)(nil)).Elem() +} + +type DatastoreRenamedEvent struct { + DatastoreEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["DatastoreRenamedEvent"] = reflect.TypeOf((*DatastoreRenamedEvent)(nil)).Elem() +} + +type DatastoreRenamedOnHostEvent struct { + HostEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["DatastoreRenamedOnHostEvent"] = reflect.TypeOf((*DatastoreRenamedOnHostEvent)(nil)).Elem() +} + +type DatastoreSummary struct { + DynamicData + + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` + Name string `xml:"name"` + Url string `xml:"url"` + Capacity int64 `xml:"capacity"` + FreeSpace int64 `xml:"freeSpace"` + Uncommitted int64 `xml:"uncommitted,omitempty"` + Accessible bool `xml:"accessible"` + MultipleHostAccess *bool `xml:"multipleHostAccess"` + Type string `xml:"type"` + MaintenanceMode string `xml:"maintenanceMode,omitempty"` +} + +func init() { + t["DatastoreSummary"] = reflect.TypeOf((*DatastoreSummary)(nil)).Elem() +} + +type DateTimeProfile struct { + ApplyProfile +} + +func init() { + t["DateTimeProfile"] = reflect.TypeOf((*DateTimeProfile)(nil)).Elem() +} + +type DecodeLicense DecodeLicenseRequestType + +func init() { + t["DecodeLicense"] = reflect.TypeOf((*DecodeLicense)(nil)).Elem() +} + +type DecodeLicenseRequestType struct { + This ManagedObjectReference `xml:"_this"` + LicenseKey string `xml:"licenseKey"` +} + +func init() { + t["DecodeLicenseRequestType"] = reflect.TypeOf((*DecodeLicenseRequestType)(nil)).Elem() +} + +type DecodeLicenseResponse struct { + Returnval LicenseManagerLicenseInfo `xml:"returnval"` +} + +type DefragmentAllDisks DefragmentAllDisksRequestType + +func init() { + t["DefragmentAllDisks"] = reflect.TypeOf((*DefragmentAllDisks)(nil)).Elem() +} + +type DefragmentAllDisksRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DefragmentAllDisksRequestType"] = reflect.TypeOf((*DefragmentAllDisksRequestType)(nil)).Elem() +} + +type DefragmentAllDisksResponse struct { +} + +type DefragmentVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["DefragmentVirtualDiskRequestType"] = reflect.TypeOf((*DefragmentVirtualDiskRequestType)(nil)).Elem() +} + +type DefragmentVirtualDisk_Task DefragmentVirtualDiskRequestType + +func init() { + t["DefragmentVirtualDisk_Task"] = reflect.TypeOf((*DefragmentVirtualDisk_Task)(nil)).Elem() +} + +type DefragmentVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DeleteCustomizationSpec DeleteCustomizationSpecRequestType + +func init() { + t["DeleteCustomizationSpec"] = reflect.TypeOf((*DeleteCustomizationSpec)(nil)).Elem() +} + +type DeleteCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["DeleteCustomizationSpecRequestType"] = reflect.TypeOf((*DeleteCustomizationSpecRequestType)(nil)).Elem() +} + +type DeleteCustomizationSpecResponse struct { +} + +type DeleteDatastoreFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["DeleteDatastoreFileRequestType"] = reflect.TypeOf((*DeleteDatastoreFileRequestType)(nil)).Elem() +} + +type DeleteDatastoreFile_Task DeleteDatastoreFileRequestType + +func init() { + t["DeleteDatastoreFile_Task"] = reflect.TypeOf((*DeleteDatastoreFile_Task)(nil)).Elem() +} + +type DeleteDatastoreFile_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DeleteDirectory DeleteDirectoryRequestType + +func init() { + t["DeleteDirectory"] = reflect.TypeOf((*DeleteDirectory)(nil)).Elem() +} + +type DeleteDirectoryInGuest DeleteDirectoryInGuestRequestType + +func init() { + t["DeleteDirectoryInGuest"] = reflect.TypeOf((*DeleteDirectoryInGuest)(nil)).Elem() +} + +type DeleteDirectoryInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + DirectoryPath string `xml:"directoryPath"` + Recursive bool `xml:"recursive"` +} + +func init() { + t["DeleteDirectoryInGuestRequestType"] = reflect.TypeOf((*DeleteDirectoryInGuestRequestType)(nil)).Elem() +} + +type DeleteDirectoryInGuestResponse struct { +} + +type DeleteDirectoryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + DatastorePath string `xml:"datastorePath"` +} + +func init() { + t["DeleteDirectoryRequestType"] = reflect.TypeOf((*DeleteDirectoryRequestType)(nil)).Elem() +} + +type DeleteDirectoryResponse struct { +} + +type DeleteFile DeleteFileRequestType + +func init() { + t["DeleteFile"] = reflect.TypeOf((*DeleteFile)(nil)).Elem() +} + +type DeleteFileInGuest DeleteFileInGuestRequestType + +func init() { + t["DeleteFileInGuest"] = reflect.TypeOf((*DeleteFileInGuest)(nil)).Elem() +} + +type DeleteFileInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + FilePath string `xml:"filePath"` +} + +func init() { + t["DeleteFileInGuestRequestType"] = reflect.TypeOf((*DeleteFileInGuestRequestType)(nil)).Elem() +} + +type DeleteFileInGuestResponse struct { +} + +type DeleteFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + DatastorePath string `xml:"datastorePath"` +} + +func init() { + t["DeleteFileRequestType"] = reflect.TypeOf((*DeleteFileRequestType)(nil)).Elem() +} + +type DeleteFileResponse struct { +} + +type DeleteRegistryKeyInGuest DeleteRegistryKeyInGuestRequestType + +func init() { + t["DeleteRegistryKeyInGuest"] = reflect.TypeOf((*DeleteRegistryKeyInGuest)(nil)).Elem() +} + +type DeleteRegistryKeyInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + KeyName GuestRegKeyNameSpec `xml:"keyName"` + Recursive bool `xml:"recursive"` +} + +func init() { + t["DeleteRegistryKeyInGuestRequestType"] = reflect.TypeOf((*DeleteRegistryKeyInGuestRequestType)(nil)).Elem() +} + +type DeleteRegistryKeyInGuestResponse struct { +} + +type DeleteRegistryValueInGuest DeleteRegistryValueInGuestRequestType + +func init() { + t["DeleteRegistryValueInGuest"] = reflect.TypeOf((*DeleteRegistryValueInGuest)(nil)).Elem() +} + +type DeleteRegistryValueInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + ValueName GuestRegValueNameSpec `xml:"valueName"` +} + +func init() { + t["DeleteRegistryValueInGuestRequestType"] = reflect.TypeOf((*DeleteRegistryValueInGuestRequestType)(nil)).Elem() +} + +type DeleteRegistryValueInGuestResponse struct { +} + +type DeleteScsiLunState DeleteScsiLunStateRequestType + +func init() { + t["DeleteScsiLunState"] = reflect.TypeOf((*DeleteScsiLunState)(nil)).Elem() +} + +type DeleteScsiLunStateRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunCanonicalName string `xml:"lunCanonicalName"` +} + +func init() { + t["DeleteScsiLunStateRequestType"] = reflect.TypeOf((*DeleteScsiLunStateRequestType)(nil)).Elem() +} + +type DeleteScsiLunStateResponse struct { +} + +type DeleteVffsVolumeState DeleteVffsVolumeStateRequestType + +func init() { + t["DeleteVffsVolumeState"] = reflect.TypeOf((*DeleteVffsVolumeState)(nil)).Elem() +} + +type DeleteVffsVolumeStateRequestType struct { + This ManagedObjectReference `xml:"_this"` + VffsUuid string `xml:"vffsUuid"` +} + +func init() { + t["DeleteVffsVolumeStateRequestType"] = reflect.TypeOf((*DeleteVffsVolumeStateRequestType)(nil)).Elem() +} + +type DeleteVffsVolumeStateResponse struct { +} + +type DeleteVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["DeleteVirtualDiskRequestType"] = reflect.TypeOf((*DeleteVirtualDiskRequestType)(nil)).Elem() +} + +type DeleteVirtualDisk_Task DeleteVirtualDiskRequestType + +func init() { + t["DeleteVirtualDisk_Task"] = reflect.TypeOf((*DeleteVirtualDisk_Task)(nil)).Elem() +} + +type DeleteVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DeleteVmfsVolumeState DeleteVmfsVolumeStateRequestType + +func init() { + t["DeleteVmfsVolumeState"] = reflect.TypeOf((*DeleteVmfsVolumeState)(nil)).Elem() +} + +type DeleteVmfsVolumeStateRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid string `xml:"vmfsUuid"` +} + +func init() { + t["DeleteVmfsVolumeStateRequestType"] = reflect.TypeOf((*DeleteVmfsVolumeStateRequestType)(nil)).Elem() +} + +type DeleteVmfsVolumeStateResponse struct { +} + +type DeleteVsanObjects DeleteVsanObjectsRequestType + +func init() { + t["DeleteVsanObjects"] = reflect.TypeOf((*DeleteVsanObjects)(nil)).Elem() +} + +type DeleteVsanObjectsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids"` + Force *bool `xml:"force"` +} + +func init() { + t["DeleteVsanObjectsRequestType"] = reflect.TypeOf((*DeleteVsanObjectsRequestType)(nil)).Elem() +} + +type DeleteVsanObjectsResponse struct { + Returnval []HostVsanInternalSystemDeleteVsanObjectsResult `xml:"returnval"` +} + +type DeltaDiskFormatNotSupported struct { + VmConfigFault + + Datastore []ManagedObjectReference `xml:"datastore,omitempty"` + DeltaDiskFormat string `xml:"deltaDiskFormat"` +} + +func init() { + t["DeltaDiskFormatNotSupported"] = reflect.TypeOf((*DeltaDiskFormatNotSupported)(nil)).Elem() +} + +type DeltaDiskFormatNotSupportedFault DeltaDiskFormatNotSupported + +func init() { + t["DeltaDiskFormatNotSupportedFault"] = reflect.TypeOf((*DeltaDiskFormatNotSupportedFault)(nil)).Elem() +} + +type Description struct { + DynamicData + + Label string `xml:"label"` + Summary string `xml:"summary"` +} + +func init() { + t["Description"] = reflect.TypeOf((*Description)(nil)).Elem() +} + +type DeselectVnic DeselectVnicRequestType + +func init() { + t["DeselectVnic"] = reflect.TypeOf((*DeselectVnic)(nil)).Elem() +} + +type DeselectVnicForNicType DeselectVnicForNicTypeRequestType + +func init() { + t["DeselectVnicForNicType"] = reflect.TypeOf((*DeselectVnicForNicType)(nil)).Elem() +} + +type DeselectVnicForNicTypeRequestType struct { + This ManagedObjectReference `xml:"_this"` + NicType string `xml:"nicType"` + Device string `xml:"device"` +} + +func init() { + t["DeselectVnicForNicTypeRequestType"] = reflect.TypeOf((*DeselectVnicForNicTypeRequestType)(nil)).Elem() +} + +type DeselectVnicForNicTypeResponse struct { +} + +type DeselectVnicRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DeselectVnicRequestType"] = reflect.TypeOf((*DeselectVnicRequestType)(nil)).Elem() +} + +type DeselectVnicResponse struct { +} + +type DestinationSwitchFull struct { + CannotAccessNetwork +} + +func init() { + t["DestinationSwitchFull"] = reflect.TypeOf((*DestinationSwitchFull)(nil)).Elem() +} + +type DestinationSwitchFullFault DestinationSwitchFull + +func init() { + t["DestinationSwitchFullFault"] = reflect.TypeOf((*DestinationSwitchFullFault)(nil)).Elem() +} + +type DestinationVsanDisabled struct { + CannotMoveVsanEnabledHost + + DestinationCluster string `xml:"destinationCluster"` +} + +func init() { + t["DestinationVsanDisabled"] = reflect.TypeOf((*DestinationVsanDisabled)(nil)).Elem() +} + +type DestinationVsanDisabledFault DestinationVsanDisabled + +func init() { + t["DestinationVsanDisabledFault"] = reflect.TypeOf((*DestinationVsanDisabledFault)(nil)).Elem() +} + +type DestroyChildren DestroyChildrenRequestType + +func init() { + t["DestroyChildren"] = reflect.TypeOf((*DestroyChildren)(nil)).Elem() +} + +type DestroyChildrenRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyChildrenRequestType"] = reflect.TypeOf((*DestroyChildrenRequestType)(nil)).Elem() +} + +type DestroyChildrenResponse struct { +} + +type DestroyCollector DestroyCollectorRequestType + +func init() { + t["DestroyCollector"] = reflect.TypeOf((*DestroyCollector)(nil)).Elem() +} + +type DestroyCollectorRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyCollectorRequestType"] = reflect.TypeOf((*DestroyCollectorRequestType)(nil)).Elem() +} + +type DestroyCollectorResponse struct { +} + +type DestroyDatastore DestroyDatastoreRequestType + +func init() { + t["DestroyDatastore"] = reflect.TypeOf((*DestroyDatastore)(nil)).Elem() +} + +type DestroyDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyDatastoreRequestType"] = reflect.TypeOf((*DestroyDatastoreRequestType)(nil)).Elem() +} + +type DestroyDatastoreResponse struct { +} + +type DestroyIpPool DestroyIpPoolRequestType + +func init() { + t["DestroyIpPool"] = reflect.TypeOf((*DestroyIpPool)(nil)).Elem() +} + +type DestroyIpPoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + Id int32 `xml:"id"` + Force bool `xml:"force"` +} + +func init() { + t["DestroyIpPoolRequestType"] = reflect.TypeOf((*DestroyIpPoolRequestType)(nil)).Elem() +} + +type DestroyIpPoolResponse struct { +} + +type DestroyNetwork DestroyNetworkRequestType + +func init() { + t["DestroyNetwork"] = reflect.TypeOf((*DestroyNetwork)(nil)).Elem() +} + +type DestroyNetworkRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyNetworkRequestType"] = reflect.TypeOf((*DestroyNetworkRequestType)(nil)).Elem() +} + +type DestroyNetworkResponse struct { +} + +type DestroyProfile DestroyProfileRequestType + +func init() { + t["DestroyProfile"] = reflect.TypeOf((*DestroyProfile)(nil)).Elem() +} + +type DestroyProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyProfileRequestType"] = reflect.TypeOf((*DestroyProfileRequestType)(nil)).Elem() +} + +type DestroyProfileResponse struct { +} + +type DestroyPropertyCollector DestroyPropertyCollectorRequestType + +func init() { + t["DestroyPropertyCollector"] = reflect.TypeOf((*DestroyPropertyCollector)(nil)).Elem() +} + +type DestroyPropertyCollectorRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyPropertyCollectorRequestType"] = reflect.TypeOf((*DestroyPropertyCollectorRequestType)(nil)).Elem() +} + +type DestroyPropertyCollectorResponse struct { +} + +type DestroyPropertyFilter DestroyPropertyFilterRequestType + +func init() { + t["DestroyPropertyFilter"] = reflect.TypeOf((*DestroyPropertyFilter)(nil)).Elem() +} + +type DestroyPropertyFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyPropertyFilterRequestType"] = reflect.TypeOf((*DestroyPropertyFilterRequestType)(nil)).Elem() +} + +type DestroyPropertyFilterResponse struct { +} + +type DestroyRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyRequestType"] = reflect.TypeOf((*DestroyRequestType)(nil)).Elem() +} + +type DestroyVffs DestroyVffsRequestType + +func init() { + t["DestroyVffs"] = reflect.TypeOf((*DestroyVffs)(nil)).Elem() +} + +type DestroyVffsRequestType struct { + This ManagedObjectReference `xml:"_this"` + VffsPath string `xml:"vffsPath"` +} + +func init() { + t["DestroyVffsRequestType"] = reflect.TypeOf((*DestroyVffsRequestType)(nil)).Elem() +} + +type DestroyVffsResponse struct { +} + +type DestroyView DestroyViewRequestType + +func init() { + t["DestroyView"] = reflect.TypeOf((*DestroyView)(nil)).Elem() +} + +type DestroyViewRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DestroyViewRequestType"] = reflect.TypeOf((*DestroyViewRequestType)(nil)).Elem() +} + +type DestroyViewResponse struct { +} + +type Destroy_Task DestroyRequestType + +func init() { + t["Destroy_Task"] = reflect.TypeOf((*Destroy_Task)(nil)).Elem() +} + +type Destroy_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DetachScsiLun DetachScsiLunRequestType + +func init() { + t["DetachScsiLun"] = reflect.TypeOf((*DetachScsiLun)(nil)).Elem() +} + +type DetachScsiLunExRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunUuid []string `xml:"lunUuid"` +} + +func init() { + t["DetachScsiLunExRequestType"] = reflect.TypeOf((*DetachScsiLunExRequestType)(nil)).Elem() +} + +type DetachScsiLunEx_Task DetachScsiLunExRequestType + +func init() { + t["DetachScsiLunEx_Task"] = reflect.TypeOf((*DetachScsiLunEx_Task)(nil)).Elem() +} + +type DetachScsiLunEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DetachScsiLunRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunUuid string `xml:"lunUuid"` +} + +func init() { + t["DetachScsiLunRequestType"] = reflect.TypeOf((*DetachScsiLunRequestType)(nil)).Elem() +} + +type DetachScsiLunResponse struct { +} + +type DeviceBackedVirtualDiskSpec struct { + VirtualDiskSpec + + Device string `xml:"device"` +} + +func init() { + t["DeviceBackedVirtualDiskSpec"] = reflect.TypeOf((*DeviceBackedVirtualDiskSpec)(nil)).Elem() +} + +type DeviceBackingNotSupported struct { + DeviceNotSupported + + Backing string `xml:"backing"` +} + +func init() { + t["DeviceBackingNotSupported"] = reflect.TypeOf((*DeviceBackingNotSupported)(nil)).Elem() +} + +type DeviceBackingNotSupportedFault BaseDeviceBackingNotSupported + +func init() { + t["DeviceBackingNotSupportedFault"] = reflect.TypeOf((*DeviceBackingNotSupportedFault)(nil)).Elem() +} + +type DeviceControllerNotSupported struct { + DeviceNotSupported + + Controller string `xml:"controller"` +} + +func init() { + t["DeviceControllerNotSupported"] = reflect.TypeOf((*DeviceControllerNotSupported)(nil)).Elem() +} + +type DeviceControllerNotSupportedFault DeviceControllerNotSupported + +func init() { + t["DeviceControllerNotSupportedFault"] = reflect.TypeOf((*DeviceControllerNotSupportedFault)(nil)).Elem() +} + +type DeviceHotPlugNotSupported struct { + InvalidDeviceSpec +} + +func init() { + t["DeviceHotPlugNotSupported"] = reflect.TypeOf((*DeviceHotPlugNotSupported)(nil)).Elem() +} + +type DeviceHotPlugNotSupportedFault DeviceHotPlugNotSupported + +func init() { + t["DeviceHotPlugNotSupportedFault"] = reflect.TypeOf((*DeviceHotPlugNotSupportedFault)(nil)).Elem() +} + +type DeviceNotFound struct { + InvalidDeviceSpec +} + +func init() { + t["DeviceNotFound"] = reflect.TypeOf((*DeviceNotFound)(nil)).Elem() +} + +type DeviceNotFoundFault DeviceNotFound + +func init() { + t["DeviceNotFoundFault"] = reflect.TypeOf((*DeviceNotFoundFault)(nil)).Elem() +} + +type DeviceNotSupported struct { + VirtualHardwareCompatibilityIssue + + Device string `xml:"device"` + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["DeviceNotSupported"] = reflect.TypeOf((*DeviceNotSupported)(nil)).Elem() +} + +type DeviceNotSupportedFault BaseDeviceNotSupported + +func init() { + t["DeviceNotSupportedFault"] = reflect.TypeOf((*DeviceNotSupportedFault)(nil)).Elem() +} + +type DeviceUnsupportedForVmPlatform struct { + InvalidDeviceSpec +} + +func init() { + t["DeviceUnsupportedForVmPlatform"] = reflect.TypeOf((*DeviceUnsupportedForVmPlatform)(nil)).Elem() +} + +type DeviceUnsupportedForVmPlatformFault DeviceUnsupportedForVmPlatform + +func init() { + t["DeviceUnsupportedForVmPlatformFault"] = reflect.TypeOf((*DeviceUnsupportedForVmPlatformFault)(nil)).Elem() +} + +type DeviceUnsupportedForVmVersion struct { + InvalidDeviceSpec + + CurrentVersion string `xml:"currentVersion"` + ExpectedVersion string `xml:"expectedVersion"` +} + +func init() { + t["DeviceUnsupportedForVmVersion"] = reflect.TypeOf((*DeviceUnsupportedForVmVersion)(nil)).Elem() +} + +type DeviceUnsupportedForVmVersionFault DeviceUnsupportedForVmVersion + +func init() { + t["DeviceUnsupportedForVmVersionFault"] = reflect.TypeOf((*DeviceUnsupportedForVmVersionFault)(nil)).Elem() +} + +type DiagnosticManagerBundleInfo struct { + DynamicData + + System *ManagedObjectReference `xml:"system,omitempty"` + Url string `xml:"url"` +} + +func init() { + t["DiagnosticManagerBundleInfo"] = reflect.TypeOf((*DiagnosticManagerBundleInfo)(nil)).Elem() +} + +type DiagnosticManagerLogDescriptor struct { + DynamicData + + Key string `xml:"key"` + FileName string `xml:"fileName"` + Creator string `xml:"creator"` + Format string `xml:"format"` + MimeType string `xml:"mimeType"` + Info BaseDescription `xml:"info,typeattr"` +} + +func init() { + t["DiagnosticManagerLogDescriptor"] = reflect.TypeOf((*DiagnosticManagerLogDescriptor)(nil)).Elem() +} + +type DiagnosticManagerLogHeader struct { + DynamicData + + LineStart int32 `xml:"lineStart"` + LineEnd int32 `xml:"lineEnd"` + LineText []string `xml:"lineText,omitempty"` +} + +func init() { + t["DiagnosticManagerLogHeader"] = reflect.TypeOf((*DiagnosticManagerLogHeader)(nil)).Elem() +} + +type DigestNotSupported struct { + DeviceNotSupported +} + +func init() { + t["DigestNotSupported"] = reflect.TypeOf((*DigestNotSupported)(nil)).Elem() +} + +type DigestNotSupportedFault DigestNotSupported + +func init() { + t["DigestNotSupportedFault"] = reflect.TypeOf((*DigestNotSupportedFault)(nil)).Elem() +} + +type DirectoryNotEmpty struct { + FileFault +} + +func init() { + t["DirectoryNotEmpty"] = reflect.TypeOf((*DirectoryNotEmpty)(nil)).Elem() +} + +type DirectoryNotEmptyFault DirectoryNotEmpty + +func init() { + t["DirectoryNotEmptyFault"] = reflect.TypeOf((*DirectoryNotEmptyFault)(nil)).Elem() +} + +type DisableAdminNotSupported struct { + HostConfigFault +} + +func init() { + t["DisableAdminNotSupported"] = reflect.TypeOf((*DisableAdminNotSupported)(nil)).Elem() +} + +type DisableAdminNotSupportedFault DisableAdminNotSupported + +func init() { + t["DisableAdminNotSupportedFault"] = reflect.TypeOf((*DisableAdminNotSupportedFault)(nil)).Elem() +} + +type DisableEvcModeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DisableEvcModeRequestType"] = reflect.TypeOf((*DisableEvcModeRequestType)(nil)).Elem() +} + +type DisableEvcMode_Task DisableEvcModeRequestType + +func init() { + t["DisableEvcMode_Task"] = reflect.TypeOf((*DisableEvcMode_Task)(nil)).Elem() +} + +type DisableEvcMode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DisableFeature DisableFeatureRequestType + +func init() { + t["DisableFeature"] = reflect.TypeOf((*DisableFeature)(nil)).Elem() +} + +type DisableFeatureRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + FeatureKey string `xml:"featureKey"` +} + +func init() { + t["DisableFeatureRequestType"] = reflect.TypeOf((*DisableFeatureRequestType)(nil)).Elem() +} + +type DisableFeatureResponse struct { + Returnval bool `xml:"returnval"` +} + +type DisableHyperThreading DisableHyperThreadingRequestType + +func init() { + t["DisableHyperThreading"] = reflect.TypeOf((*DisableHyperThreading)(nil)).Elem() +} + +type DisableHyperThreadingRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DisableHyperThreadingRequestType"] = reflect.TypeOf((*DisableHyperThreadingRequestType)(nil)).Elem() +} + +type DisableHyperThreadingResponse struct { +} + +type DisableMultipathPath DisableMultipathPathRequestType + +func init() { + t["DisableMultipathPath"] = reflect.TypeOf((*DisableMultipathPath)(nil)).Elem() +} + +type DisableMultipathPathRequestType struct { + This ManagedObjectReference `xml:"_this"` + PathName string `xml:"pathName"` +} + +func init() { + t["DisableMultipathPathRequestType"] = reflect.TypeOf((*DisableMultipathPathRequestType)(nil)).Elem() +} + +type DisableMultipathPathResponse struct { +} + +type DisableRuleset DisableRulesetRequestType + +func init() { + t["DisableRuleset"] = reflect.TypeOf((*DisableRuleset)(nil)).Elem() +} + +type DisableRulesetRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` +} + +func init() { + t["DisableRulesetRequestType"] = reflect.TypeOf((*DisableRulesetRequestType)(nil)).Elem() +} + +type DisableRulesetResponse struct { +} + +type DisableSecondaryVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` +} + +func init() { + t["DisableSecondaryVMRequestType"] = reflect.TypeOf((*DisableSecondaryVMRequestType)(nil)).Elem() +} + +type DisableSecondaryVM_Task DisableSecondaryVMRequestType + +func init() { + t["DisableSecondaryVM_Task"] = reflect.TypeOf((*DisableSecondaryVM_Task)(nil)).Elem() +} + +type DisableSecondaryVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DisableSmartCardAuthentication DisableSmartCardAuthenticationRequestType + +func init() { + t["DisableSmartCardAuthentication"] = reflect.TypeOf((*DisableSmartCardAuthentication)(nil)).Elem() +} + +type DisableSmartCardAuthenticationRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DisableSmartCardAuthenticationRequestType"] = reflect.TypeOf((*DisableSmartCardAuthenticationRequestType)(nil)).Elem() +} + +type DisableSmartCardAuthenticationResponse struct { +} + +type DisallowedChangeByService struct { + RuntimeFault + + ServiceName string `xml:"serviceName"` + DisallowedChange string `xml:"disallowedChange,omitempty"` +} + +func init() { + t["DisallowedChangeByService"] = reflect.TypeOf((*DisallowedChangeByService)(nil)).Elem() +} + +type DisallowedChangeByServiceFault DisallowedChangeByService + +func init() { + t["DisallowedChangeByServiceFault"] = reflect.TypeOf((*DisallowedChangeByServiceFault)(nil)).Elem() +} + +type DisallowedDiskModeChange struct { + InvalidDeviceSpec +} + +func init() { + t["DisallowedDiskModeChange"] = reflect.TypeOf((*DisallowedDiskModeChange)(nil)).Elem() +} + +type DisallowedDiskModeChangeFault DisallowedDiskModeChange + +func init() { + t["DisallowedDiskModeChangeFault"] = reflect.TypeOf((*DisallowedDiskModeChangeFault)(nil)).Elem() +} + +type DisallowedMigrationDeviceAttached struct { + MigrationFault + + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["DisallowedMigrationDeviceAttached"] = reflect.TypeOf((*DisallowedMigrationDeviceAttached)(nil)).Elem() +} + +type DisallowedMigrationDeviceAttachedFault DisallowedMigrationDeviceAttached + +func init() { + t["DisallowedMigrationDeviceAttachedFault"] = reflect.TypeOf((*DisallowedMigrationDeviceAttachedFault)(nil)).Elem() +} + +type DisallowedOperationOnFailoverHost struct { + RuntimeFault + + Host ManagedObjectReference `xml:"host"` + Hostname string `xml:"hostname"` +} + +func init() { + t["DisallowedOperationOnFailoverHost"] = reflect.TypeOf((*DisallowedOperationOnFailoverHost)(nil)).Elem() +} + +type DisallowedOperationOnFailoverHostFault DisallowedOperationOnFailoverHost + +func init() { + t["DisallowedOperationOnFailoverHostFault"] = reflect.TypeOf((*DisallowedOperationOnFailoverHostFault)(nil)).Elem() +} + +type DisconnectHostRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["DisconnectHostRequestType"] = reflect.TypeOf((*DisconnectHostRequestType)(nil)).Elem() +} + +type DisconnectHost_Task DisconnectHostRequestType + +func init() { + t["DisconnectHost_Task"] = reflect.TypeOf((*DisconnectHost_Task)(nil)).Elem() +} + +type DisconnectHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DisconnectedHostsBlockingEVC struct { + EVCConfigFault +} + +func init() { + t["DisconnectedHostsBlockingEVC"] = reflect.TypeOf((*DisconnectedHostsBlockingEVC)(nil)).Elem() +} + +type DisconnectedHostsBlockingEVCFault DisconnectedHostsBlockingEVC + +func init() { + t["DisconnectedHostsBlockingEVCFault"] = reflect.TypeOf((*DisconnectedHostsBlockingEVCFault)(nil)).Elem() +} + +type DiscoverFcoeHbas DiscoverFcoeHbasRequestType + +func init() { + t["DiscoverFcoeHbas"] = reflect.TypeOf((*DiscoverFcoeHbas)(nil)).Elem() +} + +type DiscoverFcoeHbasRequestType struct { + This ManagedObjectReference `xml:"_this"` + FcoeSpec FcoeConfigFcoeSpecification `xml:"fcoeSpec"` +} + +func init() { + t["DiscoverFcoeHbasRequestType"] = reflect.TypeOf((*DiscoverFcoeHbasRequestType)(nil)).Elem() +} + +type DiscoverFcoeHbasResponse struct { +} + +type DiskChangeExtent struct { + DynamicData + + Start int64 `xml:"start"` + Length int64 `xml:"length"` +} + +func init() { + t["DiskChangeExtent"] = reflect.TypeOf((*DiskChangeExtent)(nil)).Elem() +} + +type DiskChangeInfo struct { + DynamicData + + StartOffset int64 `xml:"startOffset"` + Length int64 `xml:"length"` + ChangedArea []DiskChangeExtent `xml:"changedArea,omitempty"` +} + +func init() { + t["DiskChangeInfo"] = reflect.TypeOf((*DiskChangeInfo)(nil)).Elem() +} + +type DiskHasPartitions struct { + VsanDiskFault +} + +func init() { + t["DiskHasPartitions"] = reflect.TypeOf((*DiskHasPartitions)(nil)).Elem() +} + +type DiskHasPartitionsFault DiskHasPartitions + +func init() { + t["DiskHasPartitionsFault"] = reflect.TypeOf((*DiskHasPartitionsFault)(nil)).Elem() +} + +type DiskIsLastRemainingNonSSD struct { + VsanDiskFault +} + +func init() { + t["DiskIsLastRemainingNonSSD"] = reflect.TypeOf((*DiskIsLastRemainingNonSSD)(nil)).Elem() +} + +type DiskIsLastRemainingNonSSDFault DiskIsLastRemainingNonSSD + +func init() { + t["DiskIsLastRemainingNonSSDFault"] = reflect.TypeOf((*DiskIsLastRemainingNonSSDFault)(nil)).Elem() +} + +type DiskIsNonLocal struct { + VsanDiskFault +} + +func init() { + t["DiskIsNonLocal"] = reflect.TypeOf((*DiskIsNonLocal)(nil)).Elem() +} + +type DiskIsNonLocalFault DiskIsNonLocal + +func init() { + t["DiskIsNonLocalFault"] = reflect.TypeOf((*DiskIsNonLocalFault)(nil)).Elem() +} + +type DiskIsUSB struct { + VsanDiskFault +} + +func init() { + t["DiskIsUSB"] = reflect.TypeOf((*DiskIsUSB)(nil)).Elem() +} + +type DiskIsUSBFault DiskIsUSB + +func init() { + t["DiskIsUSBFault"] = reflect.TypeOf((*DiskIsUSBFault)(nil)).Elem() +} + +type DiskMoveTypeNotSupported struct { + MigrationFault +} + +func init() { + t["DiskMoveTypeNotSupported"] = reflect.TypeOf((*DiskMoveTypeNotSupported)(nil)).Elem() +} + +type DiskMoveTypeNotSupportedFault DiskMoveTypeNotSupported + +func init() { + t["DiskMoveTypeNotSupportedFault"] = reflect.TypeOf((*DiskMoveTypeNotSupportedFault)(nil)).Elem() +} + +type DiskNotSupported struct { + VirtualHardwareCompatibilityIssue + + Disk int32 `xml:"disk"` +} + +func init() { + t["DiskNotSupported"] = reflect.TypeOf((*DiskNotSupported)(nil)).Elem() +} + +type DiskNotSupportedFault BaseDiskNotSupported + +func init() { + t["DiskNotSupportedFault"] = reflect.TypeOf((*DiskNotSupportedFault)(nil)).Elem() +} + +type DiskTooSmall struct { + VsanDiskFault +} + +func init() { + t["DiskTooSmall"] = reflect.TypeOf((*DiskTooSmall)(nil)).Elem() +} + +type DiskTooSmallFault DiskTooSmall + +func init() { + t["DiskTooSmallFault"] = reflect.TypeOf((*DiskTooSmallFault)(nil)).Elem() +} + +type DissociateProfile DissociateProfileRequestType + +func init() { + t["DissociateProfile"] = reflect.TypeOf((*DissociateProfile)(nil)).Elem() +} + +type DissociateProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity []ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["DissociateProfileRequestType"] = reflect.TypeOf((*DissociateProfileRequestType)(nil)).Elem() +} + +type DissociateProfileResponse struct { +} + +type DistributedVirtualPort struct { + DynamicData + + Key string `xml:"key"` + Config DVPortConfigInfo `xml:"config"` + DvsUuid string `xml:"dvsUuid"` + PortgroupKey string `xml:"portgroupKey,omitempty"` + ProxyHost *ManagedObjectReference `xml:"proxyHost,omitempty"` + Connectee *DistributedVirtualSwitchPortConnectee `xml:"connectee,omitempty"` + Conflict bool `xml:"conflict"` + ConflictPortKey string `xml:"conflictPortKey,omitempty"` + State *DVPortState `xml:"state,omitempty"` + ConnectionCookie int32 `xml:"connectionCookie,omitempty"` + LastStatusChange time.Time `xml:"lastStatusChange"` + HostLocalPort *bool `xml:"hostLocalPort"` +} + +func init() { + t["DistributedVirtualPort"] = reflect.TypeOf((*DistributedVirtualPort)(nil)).Elem() +} + +type DistributedVirtualPortgroupInfo struct { + DynamicData + + SwitchName string `xml:"switchName"` + SwitchUuid string `xml:"switchUuid"` + PortgroupName string `xml:"portgroupName"` + PortgroupKey string `xml:"portgroupKey"` + PortgroupType string `xml:"portgroupType"` + UplinkPortgroup bool `xml:"uplinkPortgroup"` + Portgroup ManagedObjectReference `xml:"portgroup"` + NetworkReservationSupported *bool `xml:"networkReservationSupported"` +} + +func init() { + t["DistributedVirtualPortgroupInfo"] = reflect.TypeOf((*DistributedVirtualPortgroupInfo)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMember struct { + DynamicData + + RuntimeState *DistributedVirtualSwitchHostMemberRuntimeState `xml:"runtimeState,omitempty"` + Config DistributedVirtualSwitchHostMemberConfigInfo `xml:"config"` + ProductInfo *DistributedVirtualSwitchProductSpec `xml:"productInfo,omitempty"` + UplinkPortKey []string `xml:"uplinkPortKey,omitempty"` + Status string `xml:"status"` + StatusDetail string `xml:"statusDetail,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchHostMember"] = reflect.TypeOf((*DistributedVirtualSwitchHostMember)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberBacking struct { + DynamicData +} + +func init() { + t["DistributedVirtualSwitchHostMemberBacking"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberBacking)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberConfigInfo struct { + DynamicData + + Host *ManagedObjectReference `xml:"host,omitempty"` + MaxProxySwitchPorts int32 `xml:"maxProxySwitchPorts"` + VendorSpecificConfig []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificConfig,omitempty"` + Backing BaseDistributedVirtualSwitchHostMemberBacking `xml:"backing,typeattr"` +} + +func init() { + t["DistributedVirtualSwitchHostMemberConfigInfo"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberConfigInfo)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberConfigSpec struct { + DynamicData + + Operation string `xml:"operation"` + Host ManagedObjectReference `xml:"host"` + Backing BaseDistributedVirtualSwitchHostMemberBacking `xml:"backing,omitempty,typeattr"` + MaxProxySwitchPorts int32 `xml:"maxProxySwitchPorts,omitempty"` + VendorSpecificConfig []DistributedVirtualSwitchKeyedOpaqueBlob `xml:"vendorSpecificConfig,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchHostMemberConfigSpec"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberConfigSpec)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberPnicBacking struct { + DistributedVirtualSwitchHostMemberBacking + + PnicSpec []DistributedVirtualSwitchHostMemberPnicSpec `xml:"pnicSpec,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchHostMemberPnicBacking"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberPnicBacking)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberPnicSpec struct { + DynamicData + + PnicDevice string `xml:"pnicDevice"` + UplinkPortKey string `xml:"uplinkPortKey,omitempty"` + UplinkPortgroupKey string `xml:"uplinkPortgroupKey,omitempty"` + ConnectionCookie int32 `xml:"connectionCookie,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchHostMemberPnicSpec"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberPnicSpec)(nil)).Elem() +} + +type DistributedVirtualSwitchHostMemberRuntimeState struct { + DynamicData + + CurrentMaxProxySwitchPorts int32 `xml:"currentMaxProxySwitchPorts"` +} + +func init() { + t["DistributedVirtualSwitchHostMemberRuntimeState"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberRuntimeState)(nil)).Elem() +} + +type DistributedVirtualSwitchHostProductSpec struct { + DynamicData + + ProductLineId string `xml:"productLineId,omitempty"` + Version string `xml:"version,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchHostProductSpec"] = reflect.TypeOf((*DistributedVirtualSwitchHostProductSpec)(nil)).Elem() +} + +type DistributedVirtualSwitchInfo struct { + DynamicData + + SwitchName string `xml:"switchName"` + SwitchUuid string `xml:"switchUuid"` + DistributedVirtualSwitch ManagedObjectReference `xml:"distributedVirtualSwitch"` + NetworkReservationSupported *bool `xml:"networkReservationSupported"` +} + +func init() { + t["DistributedVirtualSwitchInfo"] = reflect.TypeOf((*DistributedVirtualSwitchInfo)(nil)).Elem() +} + +type DistributedVirtualSwitchKeyedOpaqueBlob struct { + DynamicData + + Key string `xml:"key"` + OpaqueData string `xml:"opaqueData"` +} + +func init() { + t["DistributedVirtualSwitchKeyedOpaqueBlob"] = reflect.TypeOf((*DistributedVirtualSwitchKeyedOpaqueBlob)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerCompatibilityResult struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Error []LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchManagerCompatibilityResult"] = reflect.TypeOf((*DistributedVirtualSwitchManagerCompatibilityResult)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerDvsProductSpec struct { + DynamicData + + NewSwitchProductSpec *DistributedVirtualSwitchProductSpec `xml:"newSwitchProductSpec,omitempty"` + DistributedVirtualSwitch *ManagedObjectReference `xml:"distributedVirtualSwitch,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchManagerDvsProductSpec"] = reflect.TypeOf((*DistributedVirtualSwitchManagerDvsProductSpec)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerHostArrayFilter struct { + DistributedVirtualSwitchManagerHostDvsFilterSpec + + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["DistributedVirtualSwitchManagerHostArrayFilter"] = reflect.TypeOf((*DistributedVirtualSwitchManagerHostArrayFilter)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerHostContainer struct { + DynamicData + + Container ManagedObjectReference `xml:"container"` + Recursive bool `xml:"recursive"` +} + +func init() { + t["DistributedVirtualSwitchManagerHostContainer"] = reflect.TypeOf((*DistributedVirtualSwitchManagerHostContainer)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerHostContainerFilter struct { + DistributedVirtualSwitchManagerHostDvsFilterSpec + + HostContainer DistributedVirtualSwitchManagerHostContainer `xml:"hostContainer"` +} + +func init() { + t["DistributedVirtualSwitchManagerHostContainerFilter"] = reflect.TypeOf((*DistributedVirtualSwitchManagerHostContainerFilter)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerHostDvsFilterSpec struct { + DynamicData + + Inclusive bool `xml:"inclusive"` +} + +func init() { + t["DistributedVirtualSwitchManagerHostDvsFilterSpec"] = reflect.TypeOf((*DistributedVirtualSwitchManagerHostDvsFilterSpec)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerHostDvsMembershipFilter struct { + DistributedVirtualSwitchManagerHostDvsFilterSpec + + DistributedVirtualSwitch ManagedObjectReference `xml:"distributedVirtualSwitch"` +} + +func init() { + t["DistributedVirtualSwitchManagerHostDvsMembershipFilter"] = reflect.TypeOf((*DistributedVirtualSwitchManagerHostDvsMembershipFilter)(nil)).Elem() +} + +type DistributedVirtualSwitchManagerImportResult struct { + DynamicData + + DistributedVirtualSwitch []ManagedObjectReference `xml:"distributedVirtualSwitch,omitempty"` + DistributedVirtualPortgroup []ManagedObjectReference `xml:"distributedVirtualPortgroup,omitempty"` + ImportFault []ImportOperationBulkFaultFaultOnImport `xml:"importFault,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchManagerImportResult"] = reflect.TypeOf((*DistributedVirtualSwitchManagerImportResult)(nil)).Elem() +} + +type DistributedVirtualSwitchPortConnectee struct { + DynamicData + + ConnectedEntity *ManagedObjectReference `xml:"connectedEntity,omitempty"` + NicKey string `xml:"nicKey,omitempty"` + Type string `xml:"type,omitempty"` + AddressHint string `xml:"addressHint,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchPortConnectee"] = reflect.TypeOf((*DistributedVirtualSwitchPortConnectee)(nil)).Elem() +} + +type DistributedVirtualSwitchPortConnection struct { + DynamicData + + SwitchUuid string `xml:"switchUuid"` + PortgroupKey string `xml:"portgroupKey,omitempty"` + PortKey string `xml:"portKey,omitempty"` + ConnectionCookie int32 `xml:"connectionCookie,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchPortConnection"] = reflect.TypeOf((*DistributedVirtualSwitchPortConnection)(nil)).Elem() +} + +type DistributedVirtualSwitchPortCriteria struct { + DynamicData + + Connected *bool `xml:"connected"` + Active *bool `xml:"active"` + UplinkPort *bool `xml:"uplinkPort"` + Scope *ManagedObjectReference `xml:"scope,omitempty"` + PortgroupKey []string `xml:"portgroupKey,omitempty"` + Inside *bool `xml:"inside"` + PortKey []string `xml:"portKey,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchPortCriteria"] = reflect.TypeOf((*DistributedVirtualSwitchPortCriteria)(nil)).Elem() +} + +type DistributedVirtualSwitchPortStatistics struct { + DynamicData + + PacketsInMulticast int64 `xml:"packetsInMulticast"` + PacketsOutMulticast int64 `xml:"packetsOutMulticast"` + BytesInMulticast int64 `xml:"bytesInMulticast"` + BytesOutMulticast int64 `xml:"bytesOutMulticast"` + PacketsInUnicast int64 `xml:"packetsInUnicast"` + PacketsOutUnicast int64 `xml:"packetsOutUnicast"` + BytesInUnicast int64 `xml:"bytesInUnicast"` + BytesOutUnicast int64 `xml:"bytesOutUnicast"` + PacketsInBroadcast int64 `xml:"packetsInBroadcast"` + PacketsOutBroadcast int64 `xml:"packetsOutBroadcast"` + BytesInBroadcast int64 `xml:"bytesInBroadcast"` + BytesOutBroadcast int64 `xml:"bytesOutBroadcast"` + PacketsInDropped int64 `xml:"packetsInDropped"` + PacketsOutDropped int64 `xml:"packetsOutDropped"` + PacketsInException int64 `xml:"packetsInException"` + PacketsOutException int64 `xml:"packetsOutException"` +} + +func init() { + t["DistributedVirtualSwitchPortStatistics"] = reflect.TypeOf((*DistributedVirtualSwitchPortStatistics)(nil)).Elem() +} + +type DistributedVirtualSwitchProductSpec struct { + DynamicData + + Name string `xml:"name,omitempty"` + Vendor string `xml:"vendor,omitempty"` + Version string `xml:"version,omitempty"` + Build string `xml:"build,omitempty"` + ForwardingClass string `xml:"forwardingClass,omitempty"` + BundleId string `xml:"bundleId,omitempty"` + BundleUrl string `xml:"bundleUrl,omitempty"` +} + +func init() { + t["DistributedVirtualSwitchProductSpec"] = reflect.TypeOf((*DistributedVirtualSwitchProductSpec)(nil)).Elem() +} + +type DoesCustomizationSpecExist DoesCustomizationSpecExistRequestType + +func init() { + t["DoesCustomizationSpecExist"] = reflect.TypeOf((*DoesCustomizationSpecExist)(nil)).Elem() +} + +type DoesCustomizationSpecExistRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["DoesCustomizationSpecExistRequestType"] = reflect.TypeOf((*DoesCustomizationSpecExistRequestType)(nil)).Elem() +} + +type DoesCustomizationSpecExistResponse struct { + Returnval bool `xml:"returnval"` +} + +type DomainNotFound struct { + ActiveDirectoryFault + + DomainName string `xml:"domainName"` +} + +func init() { + t["DomainNotFound"] = reflect.TypeOf((*DomainNotFound)(nil)).Elem() +} + +type DomainNotFoundFault DomainNotFound + +func init() { + t["DomainNotFoundFault"] = reflect.TypeOf((*DomainNotFoundFault)(nil)).Elem() +} + +type DrsDisabledEvent struct { + ClusterEvent +} + +func init() { + t["DrsDisabledEvent"] = reflect.TypeOf((*DrsDisabledEvent)(nil)).Elem() +} + +type DrsDisabledOnVm struct { + VimFault +} + +func init() { + t["DrsDisabledOnVm"] = reflect.TypeOf((*DrsDisabledOnVm)(nil)).Elem() +} + +type DrsDisabledOnVmFault DrsDisabledOnVm + +func init() { + t["DrsDisabledOnVmFault"] = reflect.TypeOf((*DrsDisabledOnVmFault)(nil)).Elem() +} + +type DrsEnabledEvent struct { + ClusterEvent + + Behavior string `xml:"behavior"` +} + +func init() { + t["DrsEnabledEvent"] = reflect.TypeOf((*DrsEnabledEvent)(nil)).Elem() +} + +type DrsEnteredStandbyModeEvent struct { + EnteredStandbyModeEvent +} + +func init() { + t["DrsEnteredStandbyModeEvent"] = reflect.TypeOf((*DrsEnteredStandbyModeEvent)(nil)).Elem() +} + +type DrsEnteringStandbyModeEvent struct { + EnteringStandbyModeEvent +} + +func init() { + t["DrsEnteringStandbyModeEvent"] = reflect.TypeOf((*DrsEnteringStandbyModeEvent)(nil)).Elem() +} + +type DrsExitStandbyModeFailedEvent struct { + ExitStandbyModeFailedEvent +} + +func init() { + t["DrsExitStandbyModeFailedEvent"] = reflect.TypeOf((*DrsExitStandbyModeFailedEvent)(nil)).Elem() +} + +type DrsExitedStandbyModeEvent struct { + ExitedStandbyModeEvent +} + +func init() { + t["DrsExitedStandbyModeEvent"] = reflect.TypeOf((*DrsExitedStandbyModeEvent)(nil)).Elem() +} + +type DrsExitingStandbyModeEvent struct { + ExitingStandbyModeEvent +} + +func init() { + t["DrsExitingStandbyModeEvent"] = reflect.TypeOf((*DrsExitingStandbyModeEvent)(nil)).Elem() +} + +type DrsInvocationFailedEvent struct { + ClusterEvent +} + +func init() { + t["DrsInvocationFailedEvent"] = reflect.TypeOf((*DrsInvocationFailedEvent)(nil)).Elem() +} + +type DrsRecoveredFromFailureEvent struct { + ClusterEvent +} + +func init() { + t["DrsRecoveredFromFailureEvent"] = reflect.TypeOf((*DrsRecoveredFromFailureEvent)(nil)).Elem() +} + +type DrsResourceConfigureFailedEvent struct { + HostEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["DrsResourceConfigureFailedEvent"] = reflect.TypeOf((*DrsResourceConfigureFailedEvent)(nil)).Elem() +} + +type DrsResourceConfigureSyncedEvent struct { + HostEvent +} + +func init() { + t["DrsResourceConfigureSyncedEvent"] = reflect.TypeOf((*DrsResourceConfigureSyncedEvent)(nil)).Elem() +} + +type DrsRuleComplianceEvent struct { + VmEvent +} + +func init() { + t["DrsRuleComplianceEvent"] = reflect.TypeOf((*DrsRuleComplianceEvent)(nil)).Elem() +} + +type DrsRuleViolationEvent struct { + VmEvent +} + +func init() { + t["DrsRuleViolationEvent"] = reflect.TypeOf((*DrsRuleViolationEvent)(nil)).Elem() +} + +type DrsSoftRuleViolationEvent struct { + VmEvent +} + +func init() { + t["DrsSoftRuleViolationEvent"] = reflect.TypeOf((*DrsSoftRuleViolationEvent)(nil)).Elem() +} + +type DrsVmMigratedEvent struct { + VmMigratedEvent +} + +func init() { + t["DrsVmMigratedEvent"] = reflect.TypeOf((*DrsVmMigratedEvent)(nil)).Elem() +} + +type DrsVmPoweredOnEvent struct { + VmPoweredOnEvent +} + +func init() { + t["DrsVmPoweredOnEvent"] = reflect.TypeOf((*DrsVmPoweredOnEvent)(nil)).Elem() +} + +type DrsVmotionIncompatibleFault struct { + VirtualHardwareCompatibilityIssue + + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["DrsVmotionIncompatibleFault"] = reflect.TypeOf((*DrsVmotionIncompatibleFault)(nil)).Elem() +} + +type DrsVmotionIncompatibleFaultFault DrsVmotionIncompatibleFault + +func init() { + t["DrsVmotionIncompatibleFaultFault"] = reflect.TypeOf((*DrsVmotionIncompatibleFaultFault)(nil)).Elem() +} + +type DuplicateCustomizationSpec DuplicateCustomizationSpecRequestType + +func init() { + t["DuplicateCustomizationSpec"] = reflect.TypeOf((*DuplicateCustomizationSpec)(nil)).Elem() +} + +type DuplicateCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + NewName string `xml:"newName"` +} + +func init() { + t["DuplicateCustomizationSpecRequestType"] = reflect.TypeOf((*DuplicateCustomizationSpecRequestType)(nil)).Elem() +} + +type DuplicateCustomizationSpecResponse struct { +} + +type DuplicateDisks struct { + VsanDiskFault +} + +func init() { + t["DuplicateDisks"] = reflect.TypeOf((*DuplicateDisks)(nil)).Elem() +} + +type DuplicateDisksFault DuplicateDisks + +func init() { + t["DuplicateDisksFault"] = reflect.TypeOf((*DuplicateDisksFault)(nil)).Elem() +} + +type DuplicateIpDetectedEvent struct { + HostEvent + + DuplicateIP string `xml:"duplicateIP"` + MacAddress string `xml:"macAddress"` +} + +func init() { + t["DuplicateIpDetectedEvent"] = reflect.TypeOf((*DuplicateIpDetectedEvent)(nil)).Elem() +} + +type DuplicateName struct { + VimFault + + Name string `xml:"name"` + Object ManagedObjectReference `xml:"object"` +} + +func init() { + t["DuplicateName"] = reflect.TypeOf((*DuplicateName)(nil)).Elem() +} + +type DuplicateNameFault DuplicateName + +func init() { + t["DuplicateNameFault"] = reflect.TypeOf((*DuplicateNameFault)(nil)).Elem() +} + +type DuplicateVsanNetworkInterface struct { + VsanFault + + Device string `xml:"device"` +} + +func init() { + t["DuplicateVsanNetworkInterface"] = reflect.TypeOf((*DuplicateVsanNetworkInterface)(nil)).Elem() +} + +type DuplicateVsanNetworkInterfaceFault DuplicateVsanNetworkInterface + +func init() { + t["DuplicateVsanNetworkInterfaceFault"] = reflect.TypeOf((*DuplicateVsanNetworkInterfaceFault)(nil)).Elem() +} + +type DvpgImportEvent struct { + DVPortgroupEvent + + ImportType string `xml:"importType"` +} + +func init() { + t["DvpgImportEvent"] = reflect.TypeOf((*DvpgImportEvent)(nil)).Elem() +} + +type DvpgRestoreEvent struct { + DVPortgroupEvent +} + +func init() { + t["DvpgRestoreEvent"] = reflect.TypeOf((*DvpgRestoreEvent)(nil)).Elem() +} + +type DvsAcceptNetworkRuleAction struct { + DvsNetworkRuleAction +} + +func init() { + t["DvsAcceptNetworkRuleAction"] = reflect.TypeOf((*DvsAcceptNetworkRuleAction)(nil)).Elem() +} + +type DvsApplyOperationFault struct { + DvsFault + + ObjectFault []DvsApplyOperationFaultFaultOnObject `xml:"objectFault"` +} + +func init() { + t["DvsApplyOperationFault"] = reflect.TypeOf((*DvsApplyOperationFault)(nil)).Elem() +} + +type DvsApplyOperationFaultFault DvsApplyOperationFault + +func init() { + t["DvsApplyOperationFaultFault"] = reflect.TypeOf((*DvsApplyOperationFaultFault)(nil)).Elem() +} + +type DvsApplyOperationFaultFaultOnObject struct { + DynamicData + + ObjectId string `xml:"objectId"` + Type string `xml:"type"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["DvsApplyOperationFaultFaultOnObject"] = reflect.TypeOf((*DvsApplyOperationFaultFaultOnObject)(nil)).Elem() +} + +type DvsCopyNetworkRuleAction struct { + DvsNetworkRuleAction +} + +func init() { + t["DvsCopyNetworkRuleAction"] = reflect.TypeOf((*DvsCopyNetworkRuleAction)(nil)).Elem() +} + +type DvsCreatedEvent struct { + DvsEvent + + Parent FolderEventArgument `xml:"parent"` +} + +func init() { + t["DvsCreatedEvent"] = reflect.TypeOf((*DvsCreatedEvent)(nil)).Elem() +} + +type DvsDestroyedEvent struct { + DvsEvent +} + +func init() { + t["DvsDestroyedEvent"] = reflect.TypeOf((*DvsDestroyedEvent)(nil)).Elem() +} + +type DvsDropNetworkRuleAction struct { + DvsNetworkRuleAction +} + +func init() { + t["DvsDropNetworkRuleAction"] = reflect.TypeOf((*DvsDropNetworkRuleAction)(nil)).Elem() +} + +type DvsEvent struct { + Event +} + +func init() { + t["DvsEvent"] = reflect.TypeOf((*DvsEvent)(nil)).Elem() +} + +type DvsEventArgument struct { + EntityEventArgument + + Dvs ManagedObjectReference `xml:"dvs"` +} + +func init() { + t["DvsEventArgument"] = reflect.TypeOf((*DvsEventArgument)(nil)).Elem() +} + +type DvsFault struct { + VimFault +} + +func init() { + t["DvsFault"] = reflect.TypeOf((*DvsFault)(nil)).Elem() +} + +type DvsFaultFault BaseDvsFault + +func init() { + t["DvsFaultFault"] = reflect.TypeOf((*DvsFaultFault)(nil)).Elem() +} + +type DvsFilterConfig struct { + InheritablePolicy + + Key string `xml:"key,omitempty"` + AgentName string `xml:"agentName,omitempty"` + SlotNumber string `xml:"slotNumber,omitempty"` + Parameters *DvsFilterParameter `xml:"parameters,omitempty"` + OnFailure string `xml:"onFailure,omitempty"` +} + +func init() { + t["DvsFilterConfig"] = reflect.TypeOf((*DvsFilterConfig)(nil)).Elem() +} + +type DvsFilterConfigSpec struct { + DvsFilterConfig + + Operation string `xml:"operation"` +} + +func init() { + t["DvsFilterConfigSpec"] = reflect.TypeOf((*DvsFilterConfigSpec)(nil)).Elem() +} + +type DvsFilterParameter struct { + DynamicData + + Parameters []string `xml:"parameters,omitempty"` +} + +func init() { + t["DvsFilterParameter"] = reflect.TypeOf((*DvsFilterParameter)(nil)).Elem() +} + +type DvsFilterPolicy struct { + InheritablePolicy + + FilterConfig []BaseDvsFilterConfig `xml:"filterConfig,omitempty,typeattr"` +} + +func init() { + t["DvsFilterPolicy"] = reflect.TypeOf((*DvsFilterPolicy)(nil)).Elem() +} + +type DvsGreEncapNetworkRuleAction struct { + DvsNetworkRuleAction + + EncapsulationIp SingleIp `xml:"encapsulationIp"` +} + +func init() { + t["DvsGreEncapNetworkRuleAction"] = reflect.TypeOf((*DvsGreEncapNetworkRuleAction)(nil)).Elem() +} + +type DvsHealthStatusChangeEvent struct { + HostEvent + + SwitchUuid string `xml:"switchUuid"` + HealthResult BaseHostMemberHealthCheckResult `xml:"healthResult,omitempty,typeattr"` +} + +func init() { + t["DvsHealthStatusChangeEvent"] = reflect.TypeOf((*DvsHealthStatusChangeEvent)(nil)).Elem() +} + +type DvsHostBackInSyncEvent struct { + DvsEvent + + HostBackInSync HostEventArgument `xml:"hostBackInSync"` +} + +func init() { + t["DvsHostBackInSyncEvent"] = reflect.TypeOf((*DvsHostBackInSyncEvent)(nil)).Elem() +} + +type DvsHostInfrastructureTrafficResource struct { + DynamicData + + Key string `xml:"key"` + Description string `xml:"description,omitempty"` + AllocationInfo DvsHostInfrastructureTrafficResourceAllocation `xml:"allocationInfo"` +} + +func init() { + t["DvsHostInfrastructureTrafficResource"] = reflect.TypeOf((*DvsHostInfrastructureTrafficResource)(nil)).Elem() +} + +type DvsHostInfrastructureTrafficResourceAllocation struct { + DynamicData + + Limit int64 `xml:"limit,omitempty"` + Shares *SharesInfo `xml:"shares,omitempty"` + Reservation int64 `xml:"reservation,omitempty"` +} + +func init() { + t["DvsHostInfrastructureTrafficResourceAllocation"] = reflect.TypeOf((*DvsHostInfrastructureTrafficResourceAllocation)(nil)).Elem() +} + +type DvsHostJoinedEvent struct { + DvsEvent + + HostJoined HostEventArgument `xml:"hostJoined"` +} + +func init() { + t["DvsHostJoinedEvent"] = reflect.TypeOf((*DvsHostJoinedEvent)(nil)).Elem() +} + +type DvsHostLeftEvent struct { + DvsEvent + + HostLeft HostEventArgument `xml:"hostLeft"` +} + +func init() { + t["DvsHostLeftEvent"] = reflect.TypeOf((*DvsHostLeftEvent)(nil)).Elem() +} + +type DvsHostStatusUpdated struct { + DvsEvent + + HostMember HostEventArgument `xml:"hostMember"` + OldStatus string `xml:"oldStatus,omitempty"` + NewStatus string `xml:"newStatus,omitempty"` + OldStatusDetail string `xml:"oldStatusDetail,omitempty"` + NewStatusDetail string `xml:"newStatusDetail,omitempty"` +} + +func init() { + t["DvsHostStatusUpdated"] = reflect.TypeOf((*DvsHostStatusUpdated)(nil)).Elem() +} + +type DvsHostVNicProfile struct { + DvsVNicProfile +} + +func init() { + t["DvsHostVNicProfile"] = reflect.TypeOf((*DvsHostVNicProfile)(nil)).Elem() +} + +type DvsHostWentOutOfSyncEvent struct { + DvsEvent + + HostOutOfSync DvsOutOfSyncHostArgument `xml:"hostOutOfSync"` +} + +func init() { + t["DvsHostWentOutOfSyncEvent"] = reflect.TypeOf((*DvsHostWentOutOfSyncEvent)(nil)).Elem() +} + +type DvsImportEvent struct { + DvsEvent + + ImportType string `xml:"importType"` +} + +func init() { + t["DvsImportEvent"] = reflect.TypeOf((*DvsImportEvent)(nil)).Elem() +} + +type DvsIpNetworkRuleQualifier struct { + DvsNetworkRuleQualifier + + SourceAddress BaseIpAddress `xml:"sourceAddress,omitempty,typeattr"` + DestinationAddress BaseIpAddress `xml:"destinationAddress,omitempty,typeattr"` + Protocol *IntExpression `xml:"protocol,omitempty"` + SourceIpPort BaseDvsIpPort `xml:"sourceIpPort,omitempty,typeattr"` + DestinationIpPort BaseDvsIpPort `xml:"destinationIpPort,omitempty,typeattr"` + TcpFlags *IntExpression `xml:"tcpFlags,omitempty"` +} + +func init() { + t["DvsIpNetworkRuleQualifier"] = reflect.TypeOf((*DvsIpNetworkRuleQualifier)(nil)).Elem() +} + +type DvsIpPort struct { + NegatableExpression +} + +func init() { + t["DvsIpPort"] = reflect.TypeOf((*DvsIpPort)(nil)).Elem() +} + +type DvsIpPortRange struct { + DvsIpPort + + StartPortNumber int32 `xml:"startPortNumber"` + EndPortNumber int32 `xml:"endPortNumber"` +} + +func init() { + t["DvsIpPortRange"] = reflect.TypeOf((*DvsIpPortRange)(nil)).Elem() +} + +type DvsLogNetworkRuleAction struct { + DvsNetworkRuleAction +} + +func init() { + t["DvsLogNetworkRuleAction"] = reflect.TypeOf((*DvsLogNetworkRuleAction)(nil)).Elem() +} + +type DvsMacNetworkRuleQualifier struct { + DvsNetworkRuleQualifier + + SourceAddress BaseMacAddress `xml:"sourceAddress,omitempty,typeattr"` + DestinationAddress BaseMacAddress `xml:"destinationAddress,omitempty,typeattr"` + Protocol *IntExpression `xml:"protocol,omitempty"` + VlanId *IntExpression `xml:"vlanId,omitempty"` +} + +func init() { + t["DvsMacNetworkRuleQualifier"] = reflect.TypeOf((*DvsMacNetworkRuleQualifier)(nil)).Elem() +} + +type DvsMacRewriteNetworkRuleAction struct { + DvsNetworkRuleAction + + RewriteMac string `xml:"rewriteMac"` +} + +func init() { + t["DvsMacRewriteNetworkRuleAction"] = reflect.TypeOf((*DvsMacRewriteNetworkRuleAction)(nil)).Elem() +} + +type DvsMergedEvent struct { + DvsEvent + + SourceDvs DvsEventArgument `xml:"sourceDvs"` + DestinationDvs DvsEventArgument `xml:"destinationDvs"` +} + +func init() { + t["DvsMergedEvent"] = reflect.TypeOf((*DvsMergedEvent)(nil)).Elem() +} + +type DvsNetworkRuleAction struct { + DynamicData +} + +func init() { + t["DvsNetworkRuleAction"] = reflect.TypeOf((*DvsNetworkRuleAction)(nil)).Elem() +} + +type DvsNetworkRuleQualifier struct { + DynamicData + + Key string `xml:"key,omitempty"` +} + +func init() { + t["DvsNetworkRuleQualifier"] = reflect.TypeOf((*DvsNetworkRuleQualifier)(nil)).Elem() +} + +type DvsNotAuthorized struct { + DvsFault + + SessionExtensionKey string `xml:"sessionExtensionKey,omitempty"` + DvsExtensionKey string `xml:"dvsExtensionKey,omitempty"` +} + +func init() { + t["DvsNotAuthorized"] = reflect.TypeOf((*DvsNotAuthorized)(nil)).Elem() +} + +type DvsNotAuthorizedFault DvsNotAuthorized + +func init() { + t["DvsNotAuthorizedFault"] = reflect.TypeOf((*DvsNotAuthorizedFault)(nil)).Elem() +} + +type DvsOperationBulkFault struct { + DvsFault + + HostFault []DvsOperationBulkFaultFaultOnHost `xml:"hostFault"` +} + +func init() { + t["DvsOperationBulkFault"] = reflect.TypeOf((*DvsOperationBulkFault)(nil)).Elem() +} + +type DvsOperationBulkFaultFault DvsOperationBulkFault + +func init() { + t["DvsOperationBulkFaultFault"] = reflect.TypeOf((*DvsOperationBulkFaultFault)(nil)).Elem() +} + +type DvsOperationBulkFaultFaultOnHost struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["DvsOperationBulkFaultFaultOnHost"] = reflect.TypeOf((*DvsOperationBulkFaultFaultOnHost)(nil)).Elem() +} + +type DvsOutOfSyncHostArgument struct { + DynamicData + + OutOfSyncHost HostEventArgument `xml:"outOfSyncHost"` + ConfigParamters []string `xml:"configParamters"` +} + +func init() { + t["DvsOutOfSyncHostArgument"] = reflect.TypeOf((*DvsOutOfSyncHostArgument)(nil)).Elem() +} + +type DvsPortBlockedEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + StatusDetail string `xml:"statusDetail,omitempty"` + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` +} + +func init() { + t["DvsPortBlockedEvent"] = reflect.TypeOf((*DvsPortBlockedEvent)(nil)).Elem() +} + +type DvsPortConnectedEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + Connectee *DistributedVirtualSwitchPortConnectee `xml:"connectee,omitempty"` +} + +func init() { + t["DvsPortConnectedEvent"] = reflect.TypeOf((*DvsPortConnectedEvent)(nil)).Elem() +} + +type DvsPortCreatedEvent struct { + DvsEvent + + PortKey []string `xml:"portKey"` +} + +func init() { + t["DvsPortCreatedEvent"] = reflect.TypeOf((*DvsPortCreatedEvent)(nil)).Elem() +} + +type DvsPortDeletedEvent struct { + DvsEvent + + PortKey []string `xml:"portKey"` +} + +func init() { + t["DvsPortDeletedEvent"] = reflect.TypeOf((*DvsPortDeletedEvent)(nil)).Elem() +} + +type DvsPortDisconnectedEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + Connectee *DistributedVirtualSwitchPortConnectee `xml:"connectee,omitempty"` +} + +func init() { + t["DvsPortDisconnectedEvent"] = reflect.TypeOf((*DvsPortDisconnectedEvent)(nil)).Elem() +} + +type DvsPortEnteredPassthruEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` +} + +func init() { + t["DvsPortEnteredPassthruEvent"] = reflect.TypeOf((*DvsPortEnteredPassthruEvent)(nil)).Elem() +} + +type DvsPortExitedPassthruEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` +} + +func init() { + t["DvsPortExitedPassthruEvent"] = reflect.TypeOf((*DvsPortExitedPassthruEvent)(nil)).Elem() +} + +type DvsPortJoinPortgroupEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + PortgroupKey string `xml:"portgroupKey"` + PortgroupName string `xml:"portgroupName"` +} + +func init() { + t["DvsPortJoinPortgroupEvent"] = reflect.TypeOf((*DvsPortJoinPortgroupEvent)(nil)).Elem() +} + +type DvsPortLeavePortgroupEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + PortgroupKey string `xml:"portgroupKey"` + PortgroupName string `xml:"portgroupName"` +} + +func init() { + t["DvsPortLeavePortgroupEvent"] = reflect.TypeOf((*DvsPortLeavePortgroupEvent)(nil)).Elem() +} + +type DvsPortLinkDownEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` +} + +func init() { + t["DvsPortLinkDownEvent"] = reflect.TypeOf((*DvsPortLinkDownEvent)(nil)).Elem() +} + +type DvsPortLinkUpEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` +} + +func init() { + t["DvsPortLinkUpEvent"] = reflect.TypeOf((*DvsPortLinkUpEvent)(nil)).Elem() +} + +type DvsPortReconfiguredEvent struct { + DvsEvent + + PortKey []string `xml:"portKey"` +} + +func init() { + t["DvsPortReconfiguredEvent"] = reflect.TypeOf((*DvsPortReconfiguredEvent)(nil)).Elem() +} + +type DvsPortRuntimeChangeEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + RuntimeInfo DVPortStatus `xml:"runtimeInfo"` +} + +func init() { + t["DvsPortRuntimeChangeEvent"] = reflect.TypeOf((*DvsPortRuntimeChangeEvent)(nil)).Elem() +} + +type DvsPortUnblockedEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` + RuntimeInfo *DVPortStatus `xml:"runtimeInfo,omitempty"` +} + +func init() { + t["DvsPortUnblockedEvent"] = reflect.TypeOf((*DvsPortUnblockedEvent)(nil)).Elem() +} + +type DvsPortVendorSpecificStateChangeEvent struct { + DvsEvent + + PortKey string `xml:"portKey"` +} + +func init() { + t["DvsPortVendorSpecificStateChangeEvent"] = reflect.TypeOf((*DvsPortVendorSpecificStateChangeEvent)(nil)).Elem() +} + +type DvsProfile struct { + ApplyProfile + + Key string `xml:"key"` + Name string `xml:"name"` + Uplink []PnicUplinkProfile `xml:"uplink,omitempty"` +} + +func init() { + t["DvsProfile"] = reflect.TypeOf((*DvsProfile)(nil)).Elem() +} + +type DvsPuntNetworkRuleAction struct { + DvsNetworkRuleAction +} + +func init() { + t["DvsPuntNetworkRuleAction"] = reflect.TypeOf((*DvsPuntNetworkRuleAction)(nil)).Elem() +} + +type DvsRateLimitNetworkRuleAction struct { + DvsNetworkRuleAction + + PacketsPerSecond int32 `xml:"packetsPerSecond"` +} + +func init() { + t["DvsRateLimitNetworkRuleAction"] = reflect.TypeOf((*DvsRateLimitNetworkRuleAction)(nil)).Elem() +} + +type DvsReconfigureVmVnicNetworkResourcePoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + ConfigSpec []DvsVmVnicResourcePoolConfigSpec `xml:"configSpec"` +} + +func init() { + t["DvsReconfigureVmVnicNetworkResourcePoolRequestType"] = reflect.TypeOf((*DvsReconfigureVmVnicNetworkResourcePoolRequestType)(nil)).Elem() +} + +type DvsReconfigureVmVnicNetworkResourcePool_Task DvsReconfigureVmVnicNetworkResourcePoolRequestType + +func init() { + t["DvsReconfigureVmVnicNetworkResourcePool_Task"] = reflect.TypeOf((*DvsReconfigureVmVnicNetworkResourcePool_Task)(nil)).Elem() +} + +type DvsReconfigureVmVnicNetworkResourcePool_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type DvsReconfiguredEvent struct { + DvsEvent + + ConfigSpec BaseDVSConfigSpec `xml:"configSpec,typeattr"` +} + +func init() { + t["DvsReconfiguredEvent"] = reflect.TypeOf((*DvsReconfiguredEvent)(nil)).Elem() +} + +type DvsRenamedEvent struct { + DvsEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["DvsRenamedEvent"] = reflect.TypeOf((*DvsRenamedEvent)(nil)).Elem() +} + +type DvsResourceRuntimeInfo struct { + DynamicData + + Capacity int32 `xml:"capacity,omitempty"` + Usage int32 `xml:"usage,omitempty"` + Available int32 `xml:"available,omitempty"` + AllocatedResource []DvsVnicAllocatedResource `xml:"allocatedResource,omitempty"` + VmVnicNetworkResourcePoolRuntime []DvsVmVnicNetworkResourcePoolRuntimeInfo `xml:"vmVnicNetworkResourcePoolRuntime,omitempty"` +} + +func init() { + t["DvsResourceRuntimeInfo"] = reflect.TypeOf((*DvsResourceRuntimeInfo)(nil)).Elem() +} + +type DvsRestoreEvent struct { + DvsEvent +} + +func init() { + t["DvsRestoreEvent"] = reflect.TypeOf((*DvsRestoreEvent)(nil)).Elem() +} + +type DvsScopeViolated struct { + DvsFault + + Scope []ManagedObjectReference `xml:"scope"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["DvsScopeViolated"] = reflect.TypeOf((*DvsScopeViolated)(nil)).Elem() +} + +type DvsScopeViolatedFault DvsScopeViolated + +func init() { + t["DvsScopeViolatedFault"] = reflect.TypeOf((*DvsScopeViolatedFault)(nil)).Elem() +} + +type DvsServiceConsoleVNicProfile struct { + DvsVNicProfile +} + +func init() { + t["DvsServiceConsoleVNicProfile"] = reflect.TypeOf((*DvsServiceConsoleVNicProfile)(nil)).Elem() +} + +type DvsSingleIpPort struct { + DvsIpPort + + PortNumber int32 `xml:"portNumber"` +} + +func init() { + t["DvsSingleIpPort"] = reflect.TypeOf((*DvsSingleIpPort)(nil)).Elem() +} + +type DvsSystemTrafficNetworkRuleQualifier struct { + DvsNetworkRuleQualifier + + TypeOfSystemTraffic *StringExpression `xml:"typeOfSystemTraffic,omitempty"` +} + +func init() { + t["DvsSystemTrafficNetworkRuleQualifier"] = reflect.TypeOf((*DvsSystemTrafficNetworkRuleQualifier)(nil)).Elem() +} + +type DvsTrafficFilterConfig struct { + DvsFilterConfig + + TrafficRuleset *DvsTrafficRuleset `xml:"trafficRuleset,omitempty"` +} + +func init() { + t["DvsTrafficFilterConfig"] = reflect.TypeOf((*DvsTrafficFilterConfig)(nil)).Elem() +} + +type DvsTrafficFilterConfigSpec struct { + DvsTrafficFilterConfig + + Operation string `xml:"operation"` +} + +func init() { + t["DvsTrafficFilterConfigSpec"] = reflect.TypeOf((*DvsTrafficFilterConfigSpec)(nil)).Elem() +} + +type DvsTrafficRule struct { + DynamicData + + Key string `xml:"key,omitempty"` + Description string `xml:"description,omitempty"` + Sequence int32 `xml:"sequence,omitempty"` + Qualifier []BaseDvsNetworkRuleQualifier `xml:"qualifier,omitempty,typeattr"` + Action BaseDvsNetworkRuleAction `xml:"action,omitempty,typeattr"` + Direction string `xml:"direction,omitempty"` +} + +func init() { + t["DvsTrafficRule"] = reflect.TypeOf((*DvsTrafficRule)(nil)).Elem() +} + +type DvsTrafficRuleset struct { + DynamicData + + Key string `xml:"key,omitempty"` + Enabled *bool `xml:"enabled"` + Precedence int32 `xml:"precedence,omitempty"` + Rules []DvsTrafficRule `xml:"rules,omitempty"` +} + +func init() { + t["DvsTrafficRuleset"] = reflect.TypeOf((*DvsTrafficRuleset)(nil)).Elem() +} + +type DvsUpdateTagNetworkRuleAction struct { + DvsNetworkRuleAction + + QosTag int32 `xml:"qosTag,omitempty"` + DscpTag int32 `xml:"dscpTag,omitempty"` +} + +func init() { + t["DvsUpdateTagNetworkRuleAction"] = reflect.TypeOf((*DvsUpdateTagNetworkRuleAction)(nil)).Elem() +} + +type DvsUpgradeAvailableEvent struct { + DvsEvent + + ProductInfo DistributedVirtualSwitchProductSpec `xml:"productInfo"` +} + +func init() { + t["DvsUpgradeAvailableEvent"] = reflect.TypeOf((*DvsUpgradeAvailableEvent)(nil)).Elem() +} + +type DvsUpgradeInProgressEvent struct { + DvsEvent + + ProductInfo DistributedVirtualSwitchProductSpec `xml:"productInfo"` +} + +func init() { + t["DvsUpgradeInProgressEvent"] = reflect.TypeOf((*DvsUpgradeInProgressEvent)(nil)).Elem() +} + +type DvsUpgradeRejectedEvent struct { + DvsEvent + + ProductInfo DistributedVirtualSwitchProductSpec `xml:"productInfo"` +} + +func init() { + t["DvsUpgradeRejectedEvent"] = reflect.TypeOf((*DvsUpgradeRejectedEvent)(nil)).Elem() +} + +type DvsUpgradedEvent struct { + DvsEvent + + ProductInfo DistributedVirtualSwitchProductSpec `xml:"productInfo"` +} + +func init() { + t["DvsUpgradedEvent"] = reflect.TypeOf((*DvsUpgradedEvent)(nil)).Elem() +} + +type DvsVNicProfile struct { + ApplyProfile + + Key string `xml:"key"` + IpConfig IpAddressProfile `xml:"ipConfig"` +} + +func init() { + t["DvsVNicProfile"] = reflect.TypeOf((*DvsVNicProfile)(nil)).Elem() +} + +type DvsVmVnicNetworkResourcePoolRuntimeInfo struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name,omitempty"` + Capacity int32 `xml:"capacity,omitempty"` + Usage int32 `xml:"usage,omitempty"` + Available int32 `xml:"available,omitempty"` + Status string `xml:"status"` + AllocatedResource []DvsVnicAllocatedResource `xml:"allocatedResource,omitempty"` +} + +func init() { + t["DvsVmVnicNetworkResourcePoolRuntimeInfo"] = reflect.TypeOf((*DvsVmVnicNetworkResourcePoolRuntimeInfo)(nil)).Elem() +} + +type DvsVmVnicResourceAllocation struct { + DynamicData + + ReservationQuota int64 `xml:"reservationQuota,omitempty"` +} + +func init() { + t["DvsVmVnicResourceAllocation"] = reflect.TypeOf((*DvsVmVnicResourceAllocation)(nil)).Elem() +} + +type DvsVmVnicResourcePoolConfigSpec struct { + DynamicData + + Operation string `xml:"operation"` + Key string `xml:"key,omitempty"` + ConfigVersion string `xml:"configVersion,omitempty"` + AllocationInfo *DvsVmVnicResourceAllocation `xml:"allocationInfo,omitempty"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["DvsVmVnicResourcePoolConfigSpec"] = reflect.TypeOf((*DvsVmVnicResourcePoolConfigSpec)(nil)).Elem() +} + +type DvsVnicAllocatedResource struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + VnicKey string `xml:"vnicKey"` + Reservation int64 `xml:"reservation,omitempty"` +} + +func init() { + t["DvsVnicAllocatedResource"] = reflect.TypeOf((*DvsVnicAllocatedResource)(nil)).Elem() +} + +type DynamicArray struct { + Val []AnyType `xml:"val,typeattr"` +} + +func init() { + t["DynamicArray"] = reflect.TypeOf((*DynamicArray)(nil)).Elem() +} + +type DynamicData struct { +} + +func init() { + t["DynamicData"] = reflect.TypeOf((*DynamicData)(nil)).Elem() +} + +type DynamicProperty struct { + Name string `xml:"name"` + Val AnyType `xml:"val,typeattr"` +} + +func init() { + t["DynamicProperty"] = reflect.TypeOf((*DynamicProperty)(nil)).Elem() +} + +type EVCAdmissionFailed struct { + NotSupportedHostInCluster + + Faults []LocalizedMethodFault `xml:"faults,omitempty"` +} + +func init() { + t["EVCAdmissionFailed"] = reflect.TypeOf((*EVCAdmissionFailed)(nil)).Elem() +} + +type EVCAdmissionFailedCPUFeaturesForMode struct { + EVCAdmissionFailed + + CurrentEVCModeKey string `xml:"currentEVCModeKey"` +} + +func init() { + t["EVCAdmissionFailedCPUFeaturesForMode"] = reflect.TypeOf((*EVCAdmissionFailedCPUFeaturesForMode)(nil)).Elem() +} + +type EVCAdmissionFailedCPUFeaturesForModeFault EVCAdmissionFailedCPUFeaturesForMode + +func init() { + t["EVCAdmissionFailedCPUFeaturesForModeFault"] = reflect.TypeOf((*EVCAdmissionFailedCPUFeaturesForModeFault)(nil)).Elem() +} + +type EVCAdmissionFailedCPUModel struct { + EVCAdmissionFailed +} + +func init() { + t["EVCAdmissionFailedCPUModel"] = reflect.TypeOf((*EVCAdmissionFailedCPUModel)(nil)).Elem() +} + +type EVCAdmissionFailedCPUModelFault EVCAdmissionFailedCPUModel + +func init() { + t["EVCAdmissionFailedCPUModelFault"] = reflect.TypeOf((*EVCAdmissionFailedCPUModelFault)(nil)).Elem() +} + +type EVCAdmissionFailedCPUModelForMode struct { + EVCAdmissionFailed + + CurrentEVCModeKey string `xml:"currentEVCModeKey"` +} + +func init() { + t["EVCAdmissionFailedCPUModelForMode"] = reflect.TypeOf((*EVCAdmissionFailedCPUModelForMode)(nil)).Elem() +} + +type EVCAdmissionFailedCPUModelForModeFault EVCAdmissionFailedCPUModelForMode + +func init() { + t["EVCAdmissionFailedCPUModelForModeFault"] = reflect.TypeOf((*EVCAdmissionFailedCPUModelForModeFault)(nil)).Elem() +} + +type EVCAdmissionFailedCPUVendor struct { + EVCAdmissionFailed + + ClusterCPUVendor string `xml:"clusterCPUVendor"` + HostCPUVendor string `xml:"hostCPUVendor"` +} + +func init() { + t["EVCAdmissionFailedCPUVendor"] = reflect.TypeOf((*EVCAdmissionFailedCPUVendor)(nil)).Elem() +} + +type EVCAdmissionFailedCPUVendorFault EVCAdmissionFailedCPUVendor + +func init() { + t["EVCAdmissionFailedCPUVendorFault"] = reflect.TypeOf((*EVCAdmissionFailedCPUVendorFault)(nil)).Elem() +} + +type EVCAdmissionFailedCPUVendorUnknown struct { + EVCAdmissionFailed +} + +func init() { + t["EVCAdmissionFailedCPUVendorUnknown"] = reflect.TypeOf((*EVCAdmissionFailedCPUVendorUnknown)(nil)).Elem() +} + +type EVCAdmissionFailedCPUVendorUnknownFault EVCAdmissionFailedCPUVendorUnknown + +func init() { + t["EVCAdmissionFailedCPUVendorUnknownFault"] = reflect.TypeOf((*EVCAdmissionFailedCPUVendorUnknownFault)(nil)).Elem() +} + +type EVCAdmissionFailedFault BaseEVCAdmissionFailed + +func init() { + t["EVCAdmissionFailedFault"] = reflect.TypeOf((*EVCAdmissionFailedFault)(nil)).Elem() +} + +type EVCAdmissionFailedHostDisconnected struct { + EVCAdmissionFailed +} + +func init() { + t["EVCAdmissionFailedHostDisconnected"] = reflect.TypeOf((*EVCAdmissionFailedHostDisconnected)(nil)).Elem() +} + +type EVCAdmissionFailedHostDisconnectedFault EVCAdmissionFailedHostDisconnected + +func init() { + t["EVCAdmissionFailedHostDisconnectedFault"] = reflect.TypeOf((*EVCAdmissionFailedHostDisconnectedFault)(nil)).Elem() +} + +type EVCAdmissionFailedHostSoftware struct { + EVCAdmissionFailed +} + +func init() { + t["EVCAdmissionFailedHostSoftware"] = reflect.TypeOf((*EVCAdmissionFailedHostSoftware)(nil)).Elem() +} + +type EVCAdmissionFailedHostSoftwareFault EVCAdmissionFailedHostSoftware + +func init() { + t["EVCAdmissionFailedHostSoftwareFault"] = reflect.TypeOf((*EVCAdmissionFailedHostSoftwareFault)(nil)).Elem() +} + +type EVCAdmissionFailedHostSoftwareForMode struct { + EVCAdmissionFailed +} + +func init() { + t["EVCAdmissionFailedHostSoftwareForMode"] = reflect.TypeOf((*EVCAdmissionFailedHostSoftwareForMode)(nil)).Elem() +} + +type EVCAdmissionFailedHostSoftwareForModeFault EVCAdmissionFailedHostSoftwareForMode + +func init() { + t["EVCAdmissionFailedHostSoftwareForModeFault"] = reflect.TypeOf((*EVCAdmissionFailedHostSoftwareForModeFault)(nil)).Elem() +} + +type EVCAdmissionFailedVmActive struct { + EVCAdmissionFailed +} + +func init() { + t["EVCAdmissionFailedVmActive"] = reflect.TypeOf((*EVCAdmissionFailedVmActive)(nil)).Elem() +} + +type EVCAdmissionFailedVmActiveFault EVCAdmissionFailedVmActive + +func init() { + t["EVCAdmissionFailedVmActiveFault"] = reflect.TypeOf((*EVCAdmissionFailedVmActiveFault)(nil)).Elem() +} + +type EVCConfigFault struct { + VimFault + + Faults []LocalizedMethodFault `xml:"faults,omitempty"` +} + +func init() { + t["EVCConfigFault"] = reflect.TypeOf((*EVCConfigFault)(nil)).Elem() +} + +type EVCConfigFaultFault BaseEVCConfigFault + +func init() { + t["EVCConfigFaultFault"] = reflect.TypeOf((*EVCConfigFaultFault)(nil)).Elem() +} + +type EVCMode struct { + ElementDescription + + GuaranteedCPUFeatures []HostCpuIdInfo `xml:"guaranteedCPUFeatures,omitempty"` + FeatureCapability []HostFeatureCapability `xml:"featureCapability,omitempty"` + FeatureMask []HostFeatureMask `xml:"featureMask,omitempty"` + FeatureRequirement []VirtualMachineFeatureRequirement `xml:"featureRequirement,omitempty"` + Vendor string `xml:"vendor"` + Track []string `xml:"track,omitempty"` + VendorTier int32 `xml:"vendorTier"` +} + +func init() { + t["EVCMode"] = reflect.TypeOf((*EVCMode)(nil)).Elem() +} + +type EVCModeIllegalByVendor struct { + EVCConfigFault + + ClusterCPUVendor string `xml:"clusterCPUVendor"` + ModeCPUVendor string `xml:"modeCPUVendor"` +} + +func init() { + t["EVCModeIllegalByVendor"] = reflect.TypeOf((*EVCModeIllegalByVendor)(nil)).Elem() +} + +type EVCModeIllegalByVendorFault EVCModeIllegalByVendor + +func init() { + t["EVCModeIllegalByVendorFault"] = reflect.TypeOf((*EVCModeIllegalByVendorFault)(nil)).Elem() +} + +type EVCModeUnsupportedByHosts struct { + EVCConfigFault + + EvcMode string `xml:"evcMode,omitempty"` + Host []ManagedObjectReference `xml:"host,omitempty"` + HostName []string `xml:"hostName,omitempty"` +} + +func init() { + t["EVCModeUnsupportedByHosts"] = reflect.TypeOf((*EVCModeUnsupportedByHosts)(nil)).Elem() +} + +type EVCModeUnsupportedByHostsFault EVCModeUnsupportedByHosts + +func init() { + t["EVCModeUnsupportedByHostsFault"] = reflect.TypeOf((*EVCModeUnsupportedByHostsFault)(nil)).Elem() +} + +type EVCUnsupportedByHostHardware struct { + EVCConfigFault + + Host []ManagedObjectReference `xml:"host"` + HostName []string `xml:"hostName"` +} + +func init() { + t["EVCUnsupportedByHostHardware"] = reflect.TypeOf((*EVCUnsupportedByHostHardware)(nil)).Elem() +} + +type EVCUnsupportedByHostHardwareFault EVCUnsupportedByHostHardware + +func init() { + t["EVCUnsupportedByHostHardwareFault"] = reflect.TypeOf((*EVCUnsupportedByHostHardwareFault)(nil)).Elem() +} + +type EVCUnsupportedByHostSoftware struct { + EVCConfigFault + + Host []ManagedObjectReference `xml:"host"` + HostName []string `xml:"hostName"` +} + +func init() { + t["EVCUnsupportedByHostSoftware"] = reflect.TypeOf((*EVCUnsupportedByHostSoftware)(nil)).Elem() +} + +type EVCUnsupportedByHostSoftwareFault EVCUnsupportedByHostSoftware + +func init() { + t["EVCUnsupportedByHostSoftwareFault"] = reflect.TypeOf((*EVCUnsupportedByHostSoftwareFault)(nil)).Elem() +} + +type EagerZeroVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["EagerZeroVirtualDiskRequestType"] = reflect.TypeOf((*EagerZeroVirtualDiskRequestType)(nil)).Elem() +} + +type EagerZeroVirtualDisk_Task EagerZeroVirtualDiskRequestType + +func init() { + t["EagerZeroVirtualDisk_Task"] = reflect.TypeOf((*EagerZeroVirtualDisk_Task)(nil)).Elem() +} + +type EagerZeroVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type EightHostLimitViolated struct { + VmConfigFault +} + +func init() { + t["EightHostLimitViolated"] = reflect.TypeOf((*EightHostLimitViolated)(nil)).Elem() +} + +type EightHostLimitViolatedFault EightHostLimitViolated + +func init() { + t["EightHostLimitViolatedFault"] = reflect.TypeOf((*EightHostLimitViolatedFault)(nil)).Elem() +} + +type ElementDescription struct { + Description + + Key string `xml:"key"` +} + +func init() { + t["ElementDescription"] = reflect.TypeOf((*ElementDescription)(nil)).Elem() +} + +type EnableAlarmActions EnableAlarmActionsRequestType + +func init() { + t["EnableAlarmActions"] = reflect.TypeOf((*EnableAlarmActions)(nil)).Elem() +} + +type EnableAlarmActionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Enabled bool `xml:"enabled"` +} + +func init() { + t["EnableAlarmActionsRequestType"] = reflect.TypeOf((*EnableAlarmActionsRequestType)(nil)).Elem() +} + +type EnableAlarmActionsResponse struct { +} + +type EnableFeature EnableFeatureRequestType + +func init() { + t["EnableFeature"] = reflect.TypeOf((*EnableFeature)(nil)).Elem() +} + +type EnableFeatureRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + FeatureKey string `xml:"featureKey"` +} + +func init() { + t["EnableFeatureRequestType"] = reflect.TypeOf((*EnableFeatureRequestType)(nil)).Elem() +} + +type EnableFeatureResponse struct { + Returnval bool `xml:"returnval"` +} + +type EnableHyperThreading EnableHyperThreadingRequestType + +func init() { + t["EnableHyperThreading"] = reflect.TypeOf((*EnableHyperThreading)(nil)).Elem() +} + +type EnableHyperThreadingRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["EnableHyperThreadingRequestType"] = reflect.TypeOf((*EnableHyperThreadingRequestType)(nil)).Elem() +} + +type EnableHyperThreadingResponse struct { +} + +type EnableMultipathPath EnableMultipathPathRequestType + +func init() { + t["EnableMultipathPath"] = reflect.TypeOf((*EnableMultipathPath)(nil)).Elem() +} + +type EnableMultipathPathRequestType struct { + This ManagedObjectReference `xml:"_this"` + PathName string `xml:"pathName"` +} + +func init() { + t["EnableMultipathPathRequestType"] = reflect.TypeOf((*EnableMultipathPathRequestType)(nil)).Elem() +} + +type EnableMultipathPathResponse struct { +} + +type EnableNetworkResourceManagement EnableNetworkResourceManagementRequestType + +func init() { + t["EnableNetworkResourceManagement"] = reflect.TypeOf((*EnableNetworkResourceManagement)(nil)).Elem() +} + +type EnableNetworkResourceManagementRequestType struct { + This ManagedObjectReference `xml:"_this"` + Enable bool `xml:"enable"` +} + +func init() { + t["EnableNetworkResourceManagementRequestType"] = reflect.TypeOf((*EnableNetworkResourceManagementRequestType)(nil)).Elem() +} + +type EnableNetworkResourceManagementResponse struct { +} + +type EnableRuleset EnableRulesetRequestType + +func init() { + t["EnableRuleset"] = reflect.TypeOf((*EnableRuleset)(nil)).Elem() +} + +type EnableRulesetRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` +} + +func init() { + t["EnableRulesetRequestType"] = reflect.TypeOf((*EnableRulesetRequestType)(nil)).Elem() +} + +type EnableRulesetResponse struct { +} + +type EnableSecondaryVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["EnableSecondaryVMRequestType"] = reflect.TypeOf((*EnableSecondaryVMRequestType)(nil)).Elem() +} + +type EnableSecondaryVM_Task EnableSecondaryVMRequestType + +func init() { + t["EnableSecondaryVM_Task"] = reflect.TypeOf((*EnableSecondaryVM_Task)(nil)).Elem() +} + +type EnableSecondaryVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type EnableSmartCardAuthentication EnableSmartCardAuthenticationRequestType + +func init() { + t["EnableSmartCardAuthentication"] = reflect.TypeOf((*EnableSmartCardAuthentication)(nil)).Elem() +} + +type EnableSmartCardAuthenticationRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["EnableSmartCardAuthenticationRequestType"] = reflect.TypeOf((*EnableSmartCardAuthenticationRequestType)(nil)).Elem() +} + +type EnableSmartCardAuthenticationResponse struct { +} + +type EnterLockdownMode EnterLockdownModeRequestType + +func init() { + t["EnterLockdownMode"] = reflect.TypeOf((*EnterLockdownMode)(nil)).Elem() +} + +type EnterLockdownModeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["EnterLockdownModeRequestType"] = reflect.TypeOf((*EnterLockdownModeRequestType)(nil)).Elem() +} + +type EnterLockdownModeResponse struct { +} + +type EnterMaintenanceModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Timeout int32 `xml:"timeout"` + EvacuatePoweredOffVms *bool `xml:"evacuatePoweredOffVms"` + MaintenanceSpec *HostMaintenanceSpec `xml:"maintenanceSpec,omitempty"` +} + +func init() { + t["EnterMaintenanceModeRequestType"] = reflect.TypeOf((*EnterMaintenanceModeRequestType)(nil)).Elem() +} + +type EnterMaintenanceMode_Task EnterMaintenanceModeRequestType + +func init() { + t["EnterMaintenanceMode_Task"] = reflect.TypeOf((*EnterMaintenanceMode_Task)(nil)).Elem() +} + +type EnterMaintenanceMode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type EnteredMaintenanceModeEvent struct { + HostEvent +} + +func init() { + t["EnteredMaintenanceModeEvent"] = reflect.TypeOf((*EnteredMaintenanceModeEvent)(nil)).Elem() +} + +type EnteredStandbyModeEvent struct { + HostEvent +} + +func init() { + t["EnteredStandbyModeEvent"] = reflect.TypeOf((*EnteredStandbyModeEvent)(nil)).Elem() +} + +type EnteringMaintenanceModeEvent struct { + HostEvent +} + +func init() { + t["EnteringMaintenanceModeEvent"] = reflect.TypeOf((*EnteringMaintenanceModeEvent)(nil)).Elem() +} + +type EnteringStandbyModeEvent struct { + HostEvent +} + +func init() { + t["EnteringStandbyModeEvent"] = reflect.TypeOf((*EnteringStandbyModeEvent)(nil)).Elem() +} + +type EntityBackup struct { + DynamicData +} + +func init() { + t["EntityBackup"] = reflect.TypeOf((*EntityBackup)(nil)).Elem() +} + +type EntityBackupConfig struct { + DynamicData + + EntityType string `xml:"entityType"` + ConfigBlob []byte `xml:"configBlob"` + Key string `xml:"key,omitempty"` + Name string `xml:"name,omitempty"` + Container *ManagedObjectReference `xml:"container,omitempty"` + ConfigVersion string `xml:"configVersion,omitempty"` +} + +func init() { + t["EntityBackupConfig"] = reflect.TypeOf((*EntityBackupConfig)(nil)).Elem() +} + +type EntityEventArgument struct { + EventArgument + + Name string `xml:"name"` +} + +func init() { + t["EntityEventArgument"] = reflect.TypeOf((*EntityEventArgument)(nil)).Elem() +} + +type EntityPrivilege struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` + PrivAvailability []PrivilegeAvailability `xml:"privAvailability"` +} + +func init() { + t["EntityPrivilege"] = reflect.TypeOf((*EntityPrivilege)(nil)).Elem() +} + +type EnumDescription struct { + DynamicData + + Key string `xml:"key"` + Tags []BaseElementDescription `xml:"tags,typeattr"` +} + +func init() { + t["EnumDescription"] = reflect.TypeOf((*EnumDescription)(nil)).Elem() +} + +type EnvironmentBrowserConfigOptionQuerySpec struct { + DynamicData + + Key string `xml:"key,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + GuestId []string `xml:"guestId,omitempty"` +} + +func init() { + t["EnvironmentBrowserConfigOptionQuerySpec"] = reflect.TypeOf((*EnvironmentBrowserConfigOptionQuerySpec)(nil)).Elem() +} + +type ErrorUpgradeEvent struct { + UpgradeEvent +} + +func init() { + t["ErrorUpgradeEvent"] = reflect.TypeOf((*ErrorUpgradeEvent)(nil)).Elem() +} + +type EstimateDatabaseSize EstimateDatabaseSizeRequestType + +func init() { + t["EstimateDatabaseSize"] = reflect.TypeOf((*EstimateDatabaseSize)(nil)).Elem() +} + +type EstimateDatabaseSizeRequestType struct { + This ManagedObjectReference `xml:"_this"` + DbSizeParam DatabaseSizeParam `xml:"dbSizeParam"` +} + +func init() { + t["EstimateDatabaseSizeRequestType"] = reflect.TypeOf((*EstimateDatabaseSizeRequestType)(nil)).Elem() +} + +type EstimateDatabaseSizeResponse struct { + Returnval DatabaseSizeEstimate `xml:"returnval"` +} + +type EstimateStorageForConsolidateSnapshotsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["EstimateStorageForConsolidateSnapshotsRequestType"] = reflect.TypeOf((*EstimateStorageForConsolidateSnapshotsRequestType)(nil)).Elem() +} + +type EstimateStorageForConsolidateSnapshots_Task EstimateStorageForConsolidateSnapshotsRequestType + +func init() { + t["EstimateStorageForConsolidateSnapshots_Task"] = reflect.TypeOf((*EstimateStorageForConsolidateSnapshots_Task)(nil)).Elem() +} + +type EstimateStorageForConsolidateSnapshots_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type EsxAgentHostManagerUpdateConfig EsxAgentHostManagerUpdateConfigRequestType + +func init() { + t["EsxAgentHostManagerUpdateConfig"] = reflect.TypeOf((*EsxAgentHostManagerUpdateConfig)(nil)).Elem() +} + +type EsxAgentHostManagerUpdateConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + ConfigInfo HostEsxAgentHostManagerConfigInfo `xml:"configInfo"` +} + +func init() { + t["EsxAgentHostManagerUpdateConfigRequestType"] = reflect.TypeOf((*EsxAgentHostManagerUpdateConfigRequestType)(nil)).Elem() +} + +type EsxAgentHostManagerUpdateConfigResponse struct { +} + +type EvacuateVsanNodeRequestType struct { + This ManagedObjectReference `xml:"_this"` + MaintenanceSpec HostMaintenanceSpec `xml:"maintenanceSpec"` + Timeout int32 `xml:"timeout"` +} + +func init() { + t["EvacuateVsanNodeRequestType"] = reflect.TypeOf((*EvacuateVsanNodeRequestType)(nil)).Elem() +} + +type EvacuateVsanNode_Task EvacuateVsanNodeRequestType + +func init() { + t["EvacuateVsanNode_Task"] = reflect.TypeOf((*EvacuateVsanNode_Task)(nil)).Elem() +} + +type EvacuateVsanNode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type EvaluationLicenseSource struct { + LicenseSource + + RemainingHours int64 `xml:"remainingHours,omitempty"` +} + +func init() { + t["EvaluationLicenseSource"] = reflect.TypeOf((*EvaluationLicenseSource)(nil)).Elem() +} + +type EvcManager EvcManagerRequestType + +func init() { + t["EvcManager"] = reflect.TypeOf((*EvcManager)(nil)).Elem() +} + +type EvcManagerRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["EvcManagerRequestType"] = reflect.TypeOf((*EvcManagerRequestType)(nil)).Elem() +} + +type EvcManagerResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type Event struct { + DynamicData + + Key int32 `xml:"key"` + ChainId int32 `xml:"chainId"` + CreatedTime time.Time `xml:"createdTime"` + UserName string `xml:"userName"` + Datacenter *DatacenterEventArgument `xml:"datacenter,omitempty"` + ComputeResource *ComputeResourceEventArgument `xml:"computeResource,omitempty"` + Host *HostEventArgument `xml:"host,omitempty"` + Vm *VmEventArgument `xml:"vm,omitempty"` + Ds *DatastoreEventArgument `xml:"ds,omitempty"` + Net *NetworkEventArgument `xml:"net,omitempty"` + Dvs *DvsEventArgument `xml:"dvs,omitempty"` + FullFormattedMessage string `xml:"fullFormattedMessage,omitempty"` + ChangeTag string `xml:"changeTag,omitempty"` +} + +func init() { + t["Event"] = reflect.TypeOf((*Event)(nil)).Elem() +} + +type EventAlarmExpression struct { + AlarmExpression + + Comparisons []EventAlarmExpressionComparison `xml:"comparisons,omitempty"` + EventType string `xml:"eventType"` + EventTypeId string `xml:"eventTypeId,omitempty"` + ObjectType string `xml:"objectType,omitempty"` + Status ManagedEntityStatus `xml:"status,omitempty"` +} + +func init() { + t["EventAlarmExpression"] = reflect.TypeOf((*EventAlarmExpression)(nil)).Elem() +} + +type EventAlarmExpressionComparison struct { + DynamicData + + AttributeName string `xml:"attributeName"` + Operator string `xml:"operator"` + Value string `xml:"value"` +} + +func init() { + t["EventAlarmExpressionComparison"] = reflect.TypeOf((*EventAlarmExpressionComparison)(nil)).Elem() +} + +type EventArgDesc struct { + DynamicData + + Name string `xml:"name"` + Type string `xml:"type"` + Description BaseElementDescription `xml:"description,omitempty,typeattr"` +} + +func init() { + t["EventArgDesc"] = reflect.TypeOf((*EventArgDesc)(nil)).Elem() +} + +type EventArgument struct { + DynamicData +} + +func init() { + t["EventArgument"] = reflect.TypeOf((*EventArgument)(nil)).Elem() +} + +type EventDescription struct { + DynamicData + + Category []BaseElementDescription `xml:"category,typeattr"` + EventInfo []EventDescriptionEventDetail `xml:"eventInfo"` + EnumeratedTypes []EnumDescription `xml:"enumeratedTypes,omitempty"` +} + +func init() { + t["EventDescription"] = reflect.TypeOf((*EventDescription)(nil)).Elem() +} + +type EventDescriptionEventDetail struct { + DynamicData + + Key string `xml:"key"` + Description string `xml:"description,omitempty"` + Category string `xml:"category"` + FormatOnDatacenter string `xml:"formatOnDatacenter"` + FormatOnComputeResource string `xml:"formatOnComputeResource"` + FormatOnHost string `xml:"formatOnHost"` + FormatOnVm string `xml:"formatOnVm"` + FullFormat string `xml:"fullFormat"` + LongDescription string `xml:"longDescription,omitempty"` +} + +func init() { + t["EventDescriptionEventDetail"] = reflect.TypeOf((*EventDescriptionEventDetail)(nil)).Elem() +} + +type EventEx struct { + Event + + EventTypeId string `xml:"eventTypeId"` + Severity string `xml:"severity,omitempty"` + Message string `xml:"message,omitempty"` + Arguments []KeyAnyValue `xml:"arguments,omitempty"` + ObjectId string `xml:"objectId,omitempty"` + ObjectType string `xml:"objectType,omitempty"` + ObjectName string `xml:"objectName,omitempty"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["EventEx"] = reflect.TypeOf((*EventEx)(nil)).Elem() +} + +type EventFilterSpec struct { + DynamicData + + Entity *EventFilterSpecByEntity `xml:"entity,omitempty"` + Time *EventFilterSpecByTime `xml:"time,omitempty"` + UserName *EventFilterSpecByUsername `xml:"userName,omitempty"` + EventChainId int32 `xml:"eventChainId,omitempty"` + Alarm *ManagedObjectReference `xml:"alarm,omitempty"` + ScheduledTask *ManagedObjectReference `xml:"scheduledTask,omitempty"` + DisableFullMessage *bool `xml:"disableFullMessage"` + Category []string `xml:"category,omitempty"` + Type []string `xml:"type,omitempty"` + Tag []string `xml:"tag,omitempty"` + EventTypeId []string `xml:"eventTypeId,omitempty"` +} + +func init() { + t["EventFilterSpec"] = reflect.TypeOf((*EventFilterSpec)(nil)).Elem() +} + +type EventFilterSpecByEntity struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` + Recursion EventFilterSpecRecursionOption `xml:"recursion"` +} + +func init() { + t["EventFilterSpecByEntity"] = reflect.TypeOf((*EventFilterSpecByEntity)(nil)).Elem() +} + +type EventFilterSpecByTime struct { + DynamicData + + BeginTime *time.Time `xml:"beginTime"` + EndTime *time.Time `xml:"endTime"` +} + +func init() { + t["EventFilterSpecByTime"] = reflect.TypeOf((*EventFilterSpecByTime)(nil)).Elem() +} + +type EventFilterSpecByUsername struct { + DynamicData + + SystemUser bool `xml:"systemUser"` + UserList []string `xml:"userList,omitempty"` +} + +func init() { + t["EventFilterSpecByUsername"] = reflect.TypeOf((*EventFilterSpecByUsername)(nil)).Elem() +} + +type ExecuteHostProfile ExecuteHostProfileRequestType + +func init() { + t["ExecuteHostProfile"] = reflect.TypeOf((*ExecuteHostProfile)(nil)).Elem() +} + +type ExecuteHostProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` + DeferredParam []ProfileDeferredPolicyOptionParameter `xml:"deferredParam,omitempty"` +} + +func init() { + t["ExecuteHostProfileRequestType"] = reflect.TypeOf((*ExecuteHostProfileRequestType)(nil)).Elem() +} + +type ExecuteHostProfileResponse struct { + Returnval ProfileExecuteResult `xml:"returnval"` +} + +type ExecuteSimpleCommand ExecuteSimpleCommandRequestType + +func init() { + t["ExecuteSimpleCommand"] = reflect.TypeOf((*ExecuteSimpleCommand)(nil)).Elem() +} + +type ExecuteSimpleCommandRequestType struct { + This ManagedObjectReference `xml:"_this"` + Arguments []string `xml:"arguments,omitempty"` +} + +func init() { + t["ExecuteSimpleCommandRequestType"] = reflect.TypeOf((*ExecuteSimpleCommandRequestType)(nil)).Elem() +} + +type ExecuteSimpleCommandResponse struct { + Returnval string `xml:"returnval"` +} + +type ExitLockdownMode ExitLockdownModeRequestType + +func init() { + t["ExitLockdownMode"] = reflect.TypeOf((*ExitLockdownMode)(nil)).Elem() +} + +type ExitLockdownModeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ExitLockdownModeRequestType"] = reflect.TypeOf((*ExitLockdownModeRequestType)(nil)).Elem() +} + +type ExitLockdownModeResponse struct { +} + +type ExitMaintenanceModeEvent struct { + HostEvent +} + +func init() { + t["ExitMaintenanceModeEvent"] = reflect.TypeOf((*ExitMaintenanceModeEvent)(nil)).Elem() +} + +type ExitMaintenanceModeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Timeout int32 `xml:"timeout"` +} + +func init() { + t["ExitMaintenanceModeRequestType"] = reflect.TypeOf((*ExitMaintenanceModeRequestType)(nil)).Elem() +} + +type ExitMaintenanceMode_Task ExitMaintenanceModeRequestType + +func init() { + t["ExitMaintenanceMode_Task"] = reflect.TypeOf((*ExitMaintenanceMode_Task)(nil)).Elem() +} + +type ExitMaintenanceMode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExitStandbyModeFailedEvent struct { + HostEvent +} + +func init() { + t["ExitStandbyModeFailedEvent"] = reflect.TypeOf((*ExitStandbyModeFailedEvent)(nil)).Elem() +} + +type ExitedStandbyModeEvent struct { + HostEvent +} + +func init() { + t["ExitedStandbyModeEvent"] = reflect.TypeOf((*ExitedStandbyModeEvent)(nil)).Elem() +} + +type ExitingStandbyModeEvent struct { + HostEvent +} + +func init() { + t["ExitingStandbyModeEvent"] = reflect.TypeOf((*ExitingStandbyModeEvent)(nil)).Elem() +} + +type ExpandVmfsDatastore ExpandVmfsDatastoreRequestType + +func init() { + t["ExpandVmfsDatastore"] = reflect.TypeOf((*ExpandVmfsDatastore)(nil)).Elem() +} + +type ExpandVmfsDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` + Spec VmfsDatastoreExpandSpec `xml:"spec"` +} + +func init() { + t["ExpandVmfsDatastoreRequestType"] = reflect.TypeOf((*ExpandVmfsDatastoreRequestType)(nil)).Elem() +} + +type ExpandVmfsDatastoreResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExpandVmfsExtent ExpandVmfsExtentRequestType + +func init() { + t["ExpandVmfsExtent"] = reflect.TypeOf((*ExpandVmfsExtent)(nil)).Elem() +} + +type ExpandVmfsExtentRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsPath string `xml:"vmfsPath"` + Extent HostScsiDiskPartition `xml:"extent"` +} + +func init() { + t["ExpandVmfsExtentRequestType"] = reflect.TypeOf((*ExpandVmfsExtentRequestType)(nil)).Elem() +} + +type ExpandVmfsExtentResponse struct { +} + +type ExpiredAddonLicense struct { + ExpiredFeatureLicense +} + +func init() { + t["ExpiredAddonLicense"] = reflect.TypeOf((*ExpiredAddonLicense)(nil)).Elem() +} + +type ExpiredAddonLicenseFault ExpiredAddonLicense + +func init() { + t["ExpiredAddonLicenseFault"] = reflect.TypeOf((*ExpiredAddonLicenseFault)(nil)).Elem() +} + +type ExpiredEditionLicense struct { + ExpiredFeatureLicense +} + +func init() { + t["ExpiredEditionLicense"] = reflect.TypeOf((*ExpiredEditionLicense)(nil)).Elem() +} + +type ExpiredEditionLicenseFault ExpiredEditionLicense + +func init() { + t["ExpiredEditionLicenseFault"] = reflect.TypeOf((*ExpiredEditionLicenseFault)(nil)).Elem() +} + +type ExpiredFeatureLicense struct { + NotEnoughLicenses + + Feature string `xml:"feature"` + Count int32 `xml:"count"` + ExpirationDate time.Time `xml:"expirationDate"` +} + +func init() { + t["ExpiredFeatureLicense"] = reflect.TypeOf((*ExpiredFeatureLicense)(nil)).Elem() +} + +type ExpiredFeatureLicenseFault BaseExpiredFeatureLicense + +func init() { + t["ExpiredFeatureLicenseFault"] = reflect.TypeOf((*ExpiredFeatureLicenseFault)(nil)).Elem() +} + +type ExportAnswerFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["ExportAnswerFileRequestType"] = reflect.TypeOf((*ExportAnswerFileRequestType)(nil)).Elem() +} + +type ExportAnswerFile_Task ExportAnswerFileRequestType + +func init() { + t["ExportAnswerFile_Task"] = reflect.TypeOf((*ExportAnswerFile_Task)(nil)).Elem() +} + +type ExportAnswerFile_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExportProfile ExportProfileRequestType + +func init() { + t["ExportProfile"] = reflect.TypeOf((*ExportProfile)(nil)).Elem() +} + +type ExportProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ExportProfileRequestType"] = reflect.TypeOf((*ExportProfileRequestType)(nil)).Elem() +} + +type ExportProfileResponse struct { + Returnval string `xml:"returnval"` +} + +type ExportSnapshot ExportSnapshotRequestType + +func init() { + t["ExportSnapshot"] = reflect.TypeOf((*ExportSnapshot)(nil)).Elem() +} + +type ExportSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ExportSnapshotRequestType"] = reflect.TypeOf((*ExportSnapshotRequestType)(nil)).Elem() +} + +type ExportSnapshotResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExportVApp ExportVAppRequestType + +func init() { + t["ExportVApp"] = reflect.TypeOf((*ExportVApp)(nil)).Elem() +} + +type ExportVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ExportVAppRequestType"] = reflect.TypeOf((*ExportVAppRequestType)(nil)).Elem() +} + +type ExportVAppResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExportVm ExportVmRequestType + +func init() { + t["ExportVm"] = reflect.TypeOf((*ExportVm)(nil)).Elem() +} + +type ExportVmRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ExportVmRequestType"] = reflect.TypeOf((*ExportVmRequestType)(nil)).Elem() +} + +type ExportVmResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExtExtendedProductInfo struct { + DynamicData + + CompanyUrl string `xml:"companyUrl,omitempty"` + ProductUrl string `xml:"productUrl,omitempty"` + ManagementUrl string `xml:"managementUrl,omitempty"` + Self *ManagedObjectReference `xml:"self,omitempty"` +} + +func init() { + t["ExtExtendedProductInfo"] = reflect.TypeOf((*ExtExtendedProductInfo)(nil)).Elem() +} + +type ExtManagedEntityInfo struct { + DynamicData + + Type string `xml:"type"` + SmallIconUrl string `xml:"smallIconUrl,omitempty"` + IconUrl string `xml:"iconUrl,omitempty"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["ExtManagedEntityInfo"] = reflect.TypeOf((*ExtManagedEntityInfo)(nil)).Elem() +} + +type ExtSolutionManagerInfo struct { + DynamicData + + Tab []ExtSolutionManagerInfoTabInfo `xml:"tab,omitempty"` + SmallIconUrl string `xml:"smallIconUrl,omitempty"` +} + +func init() { + t["ExtSolutionManagerInfo"] = reflect.TypeOf((*ExtSolutionManagerInfo)(nil)).Elem() +} + +type ExtSolutionManagerInfoTabInfo struct { + DynamicData + + Label string `xml:"label"` + Url string `xml:"url"` +} + +func init() { + t["ExtSolutionManagerInfoTabInfo"] = reflect.TypeOf((*ExtSolutionManagerInfoTabInfo)(nil)).Elem() +} + +type ExtendVffs ExtendVffsRequestType + +func init() { + t["ExtendVffs"] = reflect.TypeOf((*ExtendVffs)(nil)).Elem() +} + +type ExtendVffsRequestType struct { + This ManagedObjectReference `xml:"_this"` + VffsPath string `xml:"vffsPath"` + DevicePath string `xml:"devicePath"` + Spec *HostDiskPartitionSpec `xml:"spec,omitempty"` +} + +func init() { + t["ExtendVffsRequestType"] = reflect.TypeOf((*ExtendVffsRequestType)(nil)).Elem() +} + +type ExtendVffsResponse struct { +} + +type ExtendVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + NewCapacityKb int64 `xml:"newCapacityKb"` + EagerZero *bool `xml:"eagerZero"` +} + +func init() { + t["ExtendVirtualDiskRequestType"] = reflect.TypeOf((*ExtendVirtualDiskRequestType)(nil)).Elem() +} + +type ExtendVirtualDisk_Task ExtendVirtualDiskRequestType + +func init() { + t["ExtendVirtualDisk_Task"] = reflect.TypeOf((*ExtendVirtualDisk_Task)(nil)).Elem() +} + +type ExtendVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExtendVmfsDatastore ExtendVmfsDatastoreRequestType + +func init() { + t["ExtendVmfsDatastore"] = reflect.TypeOf((*ExtendVmfsDatastore)(nil)).Elem() +} + +type ExtendVmfsDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` + Spec VmfsDatastoreExtendSpec `xml:"spec"` +} + +func init() { + t["ExtendVmfsDatastoreRequestType"] = reflect.TypeOf((*ExtendVmfsDatastoreRequestType)(nil)).Elem() +} + +type ExtendVmfsDatastoreResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ExtendedDescription struct { + Description + + MessageCatalogKeyPrefix string `xml:"messageCatalogKeyPrefix"` + MessageArg []KeyAnyValue `xml:"messageArg,omitempty"` +} + +func init() { + t["ExtendedDescription"] = reflect.TypeOf((*ExtendedDescription)(nil)).Elem() +} + +type ExtendedElementDescription struct { + ElementDescription + + MessageCatalogKeyPrefix string `xml:"messageCatalogKeyPrefix"` + MessageArg []KeyAnyValue `xml:"messageArg,omitempty"` +} + +func init() { + t["ExtendedElementDescription"] = reflect.TypeOf((*ExtendedElementDescription)(nil)).Elem() +} + +type ExtendedEvent struct { + GeneralEvent + + EventTypeId string `xml:"eventTypeId"` + ManagedObject ManagedObjectReference `xml:"managedObject"` + Data []ExtendedEventPair `xml:"data,omitempty"` +} + +func init() { + t["ExtendedEvent"] = reflect.TypeOf((*ExtendedEvent)(nil)).Elem() +} + +type ExtendedEventPair struct { + DynamicData + + Key string `xml:"key"` + Value string `xml:"value"` +} + +func init() { + t["ExtendedEventPair"] = reflect.TypeOf((*ExtendedEventPair)(nil)).Elem() +} + +type ExtendedFault struct { + VimFault + + FaultTypeId string `xml:"faultTypeId"` + Data []KeyValue `xml:"data,omitempty"` +} + +func init() { + t["ExtendedFault"] = reflect.TypeOf((*ExtendedFault)(nil)).Elem() +} + +type ExtendedFaultFault ExtendedFault + +func init() { + t["ExtendedFaultFault"] = reflect.TypeOf((*ExtendedFaultFault)(nil)).Elem() +} + +type Extension struct { + DynamicData + + Description BaseDescription `xml:"description,typeattr"` + Key string `xml:"key"` + Company string `xml:"company,omitempty"` + Type string `xml:"type,omitempty"` + Version string `xml:"version"` + SubjectName string `xml:"subjectName,omitempty"` + Server []ExtensionServerInfo `xml:"server,omitempty"` + Client []ExtensionClientInfo `xml:"client,omitempty"` + TaskList []ExtensionTaskTypeInfo `xml:"taskList,omitempty"` + EventList []ExtensionEventTypeInfo `xml:"eventList,omitempty"` + FaultList []ExtensionFaultTypeInfo `xml:"faultList,omitempty"` + PrivilegeList []ExtensionPrivilegeInfo `xml:"privilegeList,omitempty"` + ResourceList []ExtensionResourceInfo `xml:"resourceList,omitempty"` + LastHeartbeatTime time.Time `xml:"lastHeartbeatTime"` + HealthInfo *ExtensionHealthInfo `xml:"healthInfo,omitempty"` + OvfConsumerInfo *ExtensionOvfConsumerInfo `xml:"ovfConsumerInfo,omitempty"` + ExtendedProductInfo *ExtExtendedProductInfo `xml:"extendedProductInfo,omitempty"` + ManagedEntityInfo []ExtManagedEntityInfo `xml:"managedEntityInfo,omitempty"` + ShownInSolutionManager *bool `xml:"shownInSolutionManager"` + SolutionManagerInfo *ExtSolutionManagerInfo `xml:"solutionManagerInfo,omitempty"` +} + +func init() { + t["Extension"] = reflect.TypeOf((*Extension)(nil)).Elem() +} + +type ExtensionClientInfo struct { + DynamicData + + Version string `xml:"version"` + Description BaseDescription `xml:"description,typeattr"` + Company string `xml:"company"` + Type string `xml:"type"` + Url string `xml:"url"` +} + +func init() { + t["ExtensionClientInfo"] = reflect.TypeOf((*ExtensionClientInfo)(nil)).Elem() +} + +type ExtensionEventTypeInfo struct { + DynamicData + + EventID string `xml:"eventID"` + EventTypeSchema string `xml:"eventTypeSchema,omitempty"` +} + +func init() { + t["ExtensionEventTypeInfo"] = reflect.TypeOf((*ExtensionEventTypeInfo)(nil)).Elem() +} + +type ExtensionFaultTypeInfo struct { + DynamicData + + FaultID string `xml:"faultID"` +} + +func init() { + t["ExtensionFaultTypeInfo"] = reflect.TypeOf((*ExtensionFaultTypeInfo)(nil)).Elem() +} + +type ExtensionHealthInfo struct { + DynamicData + + Url string `xml:"url"` +} + +func init() { + t["ExtensionHealthInfo"] = reflect.TypeOf((*ExtensionHealthInfo)(nil)).Elem() +} + +type ExtensionManagerIpAllocationUsage struct { + DynamicData + + ExtensionKey string `xml:"extensionKey"` + NumAddresses int32 `xml:"numAddresses"` +} + +func init() { + t["ExtensionManagerIpAllocationUsage"] = reflect.TypeOf((*ExtensionManagerIpAllocationUsage)(nil)).Elem() +} + +type ExtensionOvfConsumerInfo struct { + DynamicData + + CallbackUrl string `xml:"callbackUrl"` + SectionType []string `xml:"sectionType"` +} + +func init() { + t["ExtensionOvfConsumerInfo"] = reflect.TypeOf((*ExtensionOvfConsumerInfo)(nil)).Elem() +} + +type ExtensionPrivilegeInfo struct { + DynamicData + + PrivID string `xml:"privID"` + PrivGroupName string `xml:"privGroupName"` +} + +func init() { + t["ExtensionPrivilegeInfo"] = reflect.TypeOf((*ExtensionPrivilegeInfo)(nil)).Elem() +} + +type ExtensionResourceInfo struct { + DynamicData + + Locale string `xml:"locale"` + Module string `xml:"module"` + Data []KeyValue `xml:"data"` +} + +func init() { + t["ExtensionResourceInfo"] = reflect.TypeOf((*ExtensionResourceInfo)(nil)).Elem() +} + +type ExtensionServerInfo struct { + DynamicData + + Url string `xml:"url"` + Description BaseDescription `xml:"description,typeattr"` + Company string `xml:"company"` + Type string `xml:"type"` + AdminEmail []string `xml:"adminEmail"` + ServerThumbprint string `xml:"serverThumbprint,omitempty"` +} + +func init() { + t["ExtensionServerInfo"] = reflect.TypeOf((*ExtensionServerInfo)(nil)).Elem() +} + +type ExtensionTaskTypeInfo struct { + DynamicData + + TaskID string `xml:"taskID"` +} + +func init() { + t["ExtensionTaskTypeInfo"] = reflect.TypeOf((*ExtensionTaskTypeInfo)(nil)).Elem() +} + +type ExtractOvfEnvironment ExtractOvfEnvironmentRequestType + +func init() { + t["ExtractOvfEnvironment"] = reflect.TypeOf((*ExtractOvfEnvironment)(nil)).Elem() +} + +type ExtractOvfEnvironmentRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ExtractOvfEnvironmentRequestType"] = reflect.TypeOf((*ExtractOvfEnvironmentRequestType)(nil)).Elem() +} + +type ExtractOvfEnvironmentResponse struct { + Returnval string `xml:"returnval"` +} + +type FailToEnableSPBM struct { + NotEnoughLicenses + + Cs ManagedObjectReference `xml:"cs"` + CsName string `xml:"csName"` + HostLicenseStates []ComputeResourceHostSPBMLicenseInfo `xml:"hostLicenseStates"` +} + +func init() { + t["FailToEnableSPBM"] = reflect.TypeOf((*FailToEnableSPBM)(nil)).Elem() +} + +type FailToEnableSPBMFault FailToEnableSPBM + +func init() { + t["FailToEnableSPBMFault"] = reflect.TypeOf((*FailToEnableSPBMFault)(nil)).Elem() +} + +type FailToLockFaultToleranceVMs struct { + RuntimeFault + + VmName string `xml:"vmName"` + Vm ManagedObjectReference `xml:"vm"` + AlreadyLockedVm ManagedObjectReference `xml:"alreadyLockedVm"` +} + +func init() { + t["FailToLockFaultToleranceVMs"] = reflect.TypeOf((*FailToLockFaultToleranceVMs)(nil)).Elem() +} + +type FailToLockFaultToleranceVMsFault FailToLockFaultToleranceVMs + +func init() { + t["FailToLockFaultToleranceVMsFault"] = reflect.TypeOf((*FailToLockFaultToleranceVMsFault)(nil)).Elem() +} + +type FailoverLevelRestored struct { + ClusterEvent +} + +func init() { + t["FailoverLevelRestored"] = reflect.TypeOf((*FailoverLevelRestored)(nil)).Elem() +} + +type FaultToleranceAntiAffinityViolated struct { + MigrationFault + + HostName string `xml:"hostName"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["FaultToleranceAntiAffinityViolated"] = reflect.TypeOf((*FaultToleranceAntiAffinityViolated)(nil)).Elem() +} + +type FaultToleranceAntiAffinityViolatedFault FaultToleranceAntiAffinityViolated + +func init() { + t["FaultToleranceAntiAffinityViolatedFault"] = reflect.TypeOf((*FaultToleranceAntiAffinityViolatedFault)(nil)).Elem() +} + +type FaultToleranceCannotEditMem struct { + VmConfigFault + + VmName string `xml:"vmName"` + Vm ManagedObjectReference `xml:"vm"` +} + +func init() { + t["FaultToleranceCannotEditMem"] = reflect.TypeOf((*FaultToleranceCannotEditMem)(nil)).Elem() +} + +type FaultToleranceCannotEditMemFault FaultToleranceCannotEditMem + +func init() { + t["FaultToleranceCannotEditMemFault"] = reflect.TypeOf((*FaultToleranceCannotEditMemFault)(nil)).Elem() +} + +type FaultToleranceConfigInfo struct { + DynamicData + + Role int32 `xml:"role"` + InstanceUuids []string `xml:"instanceUuids"` + ConfigPaths []string `xml:"configPaths"` + Orphaned *bool `xml:"orphaned"` +} + +func init() { + t["FaultToleranceConfigInfo"] = reflect.TypeOf((*FaultToleranceConfigInfo)(nil)).Elem() +} + +type FaultToleranceConfigSpec struct { + DynamicData + + MetaDataPath *FaultToleranceMetaSpec `xml:"metaDataPath,omitempty"` + SecondaryVmSpec *FaultToleranceVMConfigSpec `xml:"secondaryVmSpec,omitempty"` +} + +func init() { + t["FaultToleranceConfigSpec"] = reflect.TypeOf((*FaultToleranceConfigSpec)(nil)).Elem() +} + +type FaultToleranceCpuIncompatible struct { + CpuIncompatible + + Model bool `xml:"model"` + Family bool `xml:"family"` + Stepping bool `xml:"stepping"` +} + +func init() { + t["FaultToleranceCpuIncompatible"] = reflect.TypeOf((*FaultToleranceCpuIncompatible)(nil)).Elem() +} + +type FaultToleranceCpuIncompatibleFault FaultToleranceCpuIncompatible + +func init() { + t["FaultToleranceCpuIncompatibleFault"] = reflect.TypeOf((*FaultToleranceCpuIncompatibleFault)(nil)).Elem() +} + +type FaultToleranceDiskSpec struct { + DynamicData + + Disk BaseVirtualDevice `xml:"disk,typeattr"` + Datastore ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["FaultToleranceDiskSpec"] = reflect.TypeOf((*FaultToleranceDiskSpec)(nil)).Elem() +} + +type FaultToleranceMetaSpec struct { + DynamicData + + MetaDataDatastore ManagedObjectReference `xml:"metaDataDatastore"` +} + +func init() { + t["FaultToleranceMetaSpec"] = reflect.TypeOf((*FaultToleranceMetaSpec)(nil)).Elem() +} + +type FaultToleranceNeedsThickDisk struct { + MigrationFault + + VmName string `xml:"vmName"` +} + +func init() { + t["FaultToleranceNeedsThickDisk"] = reflect.TypeOf((*FaultToleranceNeedsThickDisk)(nil)).Elem() +} + +type FaultToleranceNeedsThickDiskFault FaultToleranceNeedsThickDisk + +func init() { + t["FaultToleranceNeedsThickDiskFault"] = reflect.TypeOf((*FaultToleranceNeedsThickDiskFault)(nil)).Elem() +} + +type FaultToleranceNotLicensed struct { + VmFaultToleranceIssue + + HostName string `xml:"hostName,omitempty"` +} + +func init() { + t["FaultToleranceNotLicensed"] = reflect.TypeOf((*FaultToleranceNotLicensed)(nil)).Elem() +} + +type FaultToleranceNotLicensedFault FaultToleranceNotLicensed + +func init() { + t["FaultToleranceNotLicensedFault"] = reflect.TypeOf((*FaultToleranceNotLicensedFault)(nil)).Elem() +} + +type FaultToleranceNotSameBuild struct { + MigrationFault + + Build string `xml:"build"` +} + +func init() { + t["FaultToleranceNotSameBuild"] = reflect.TypeOf((*FaultToleranceNotSameBuild)(nil)).Elem() +} + +type FaultToleranceNotSameBuildFault FaultToleranceNotSameBuild + +func init() { + t["FaultToleranceNotSameBuildFault"] = reflect.TypeOf((*FaultToleranceNotSameBuildFault)(nil)).Elem() +} + +type FaultTolerancePrimaryConfigInfo struct { + FaultToleranceConfigInfo + + Secondaries []ManagedObjectReference `xml:"secondaries"` +} + +func init() { + t["FaultTolerancePrimaryConfigInfo"] = reflect.TypeOf((*FaultTolerancePrimaryConfigInfo)(nil)).Elem() +} + +type FaultTolerancePrimaryPowerOnNotAttempted struct { + VmFaultToleranceIssue + + SecondaryVm ManagedObjectReference `xml:"secondaryVm"` + PrimaryVm ManagedObjectReference `xml:"primaryVm"` +} + +func init() { + t["FaultTolerancePrimaryPowerOnNotAttempted"] = reflect.TypeOf((*FaultTolerancePrimaryPowerOnNotAttempted)(nil)).Elem() +} + +type FaultTolerancePrimaryPowerOnNotAttemptedFault FaultTolerancePrimaryPowerOnNotAttempted + +func init() { + t["FaultTolerancePrimaryPowerOnNotAttemptedFault"] = reflect.TypeOf((*FaultTolerancePrimaryPowerOnNotAttemptedFault)(nil)).Elem() +} + +type FaultToleranceSecondaryConfigInfo struct { + FaultToleranceConfigInfo + + PrimaryVM ManagedObjectReference `xml:"primaryVM"` +} + +func init() { + t["FaultToleranceSecondaryConfigInfo"] = reflect.TypeOf((*FaultToleranceSecondaryConfigInfo)(nil)).Elem() +} + +type FaultToleranceSecondaryOpResult struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + PowerOnAttempted bool `xml:"powerOnAttempted"` + PowerOnResult *ClusterPowerOnVmResult `xml:"powerOnResult,omitempty"` +} + +func init() { + t["FaultToleranceSecondaryOpResult"] = reflect.TypeOf((*FaultToleranceSecondaryOpResult)(nil)).Elem() +} + +type FaultToleranceVMConfigSpec struct { + DynamicData + + VmConfig *ManagedObjectReference `xml:"vmConfig,omitempty"` + Disks []FaultToleranceDiskSpec `xml:"disks,omitempty"` +} + +func init() { + t["FaultToleranceVMConfigSpec"] = reflect.TypeOf((*FaultToleranceVMConfigSpec)(nil)).Elem() +} + +type FaultToleranceVmNotDasProtected struct { + VimFault + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["FaultToleranceVmNotDasProtected"] = reflect.TypeOf((*FaultToleranceVmNotDasProtected)(nil)).Elem() +} + +type FaultToleranceVmNotDasProtectedFault FaultToleranceVmNotDasProtected + +func init() { + t["FaultToleranceVmNotDasProtectedFault"] = reflect.TypeOf((*FaultToleranceVmNotDasProtectedFault)(nil)).Elem() +} + +type FcoeConfig struct { + DynamicData + + PriorityClass int32 `xml:"priorityClass"` + SourceMac string `xml:"sourceMac"` + VlanRange []FcoeConfigVlanRange `xml:"vlanRange"` + Capabilities FcoeConfigFcoeCapabilities `xml:"capabilities"` + FcoeActive bool `xml:"fcoeActive"` +} + +func init() { + t["FcoeConfig"] = reflect.TypeOf((*FcoeConfig)(nil)).Elem() +} + +type FcoeConfigFcoeCapabilities struct { + DynamicData + + PriorityClass bool `xml:"priorityClass"` + SourceMacAddress bool `xml:"sourceMacAddress"` + VlanRange bool `xml:"vlanRange"` +} + +func init() { + t["FcoeConfigFcoeCapabilities"] = reflect.TypeOf((*FcoeConfigFcoeCapabilities)(nil)).Elem() +} + +type FcoeConfigFcoeSpecification struct { + DynamicData + + UnderlyingPnic string `xml:"underlyingPnic"` + PriorityClass int32 `xml:"priorityClass,omitempty"` + SourceMac string `xml:"sourceMac,omitempty"` + VlanRange []FcoeConfigVlanRange `xml:"vlanRange,omitempty"` +} + +func init() { + t["FcoeConfigFcoeSpecification"] = reflect.TypeOf((*FcoeConfigFcoeSpecification)(nil)).Elem() +} + +type FcoeConfigVlanRange struct { + DynamicData + + VlanLow int32 `xml:"vlanLow"` + VlanHigh int32 `xml:"vlanHigh"` +} + +func init() { + t["FcoeConfigVlanRange"] = reflect.TypeOf((*FcoeConfigVlanRange)(nil)).Elem() +} + +type FcoeFault struct { + VimFault +} + +func init() { + t["FcoeFault"] = reflect.TypeOf((*FcoeFault)(nil)).Elem() +} + +type FcoeFaultFault BaseFcoeFault + +func init() { + t["FcoeFaultFault"] = reflect.TypeOf((*FcoeFaultFault)(nil)).Elem() +} + +type FcoeFaultPnicHasNoPortSet struct { + FcoeFault + + NicDevice string `xml:"nicDevice"` +} + +func init() { + t["FcoeFaultPnicHasNoPortSet"] = reflect.TypeOf((*FcoeFaultPnicHasNoPortSet)(nil)).Elem() +} + +type FcoeFaultPnicHasNoPortSetFault FcoeFaultPnicHasNoPortSet + +func init() { + t["FcoeFaultPnicHasNoPortSetFault"] = reflect.TypeOf((*FcoeFaultPnicHasNoPortSetFault)(nil)).Elem() +} + +type FeatureRequirementsNotMet struct { + VirtualHardwareCompatibilityIssue + + FeatureRequirement []VirtualMachineFeatureRequirement `xml:"featureRequirement,omitempty"` + Vm *ManagedObjectReference `xml:"vm,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["FeatureRequirementsNotMet"] = reflect.TypeOf((*FeatureRequirementsNotMet)(nil)).Elem() +} + +type FeatureRequirementsNotMetFault FeatureRequirementsNotMet + +func init() { + t["FeatureRequirementsNotMetFault"] = reflect.TypeOf((*FeatureRequirementsNotMetFault)(nil)).Elem() +} + +type FetchDVPortKeys FetchDVPortKeysRequestType + +func init() { + t["FetchDVPortKeys"] = reflect.TypeOf((*FetchDVPortKeys)(nil)).Elem() +} + +type FetchDVPortKeysRequestType struct { + This ManagedObjectReference `xml:"_this"` + Criteria *DistributedVirtualSwitchPortCriteria `xml:"criteria,omitempty"` +} + +func init() { + t["FetchDVPortKeysRequestType"] = reflect.TypeOf((*FetchDVPortKeysRequestType)(nil)).Elem() +} + +type FetchDVPortKeysResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type FetchDVPorts FetchDVPortsRequestType + +func init() { + t["FetchDVPorts"] = reflect.TypeOf((*FetchDVPorts)(nil)).Elem() +} + +type FetchDVPortsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Criteria *DistributedVirtualSwitchPortCriteria `xml:"criteria,omitempty"` +} + +func init() { + t["FetchDVPortsRequestType"] = reflect.TypeOf((*FetchDVPortsRequestType)(nil)).Elem() +} + +type FetchDVPortsResponse struct { + Returnval []DistributedVirtualPort `xml:"returnval,omitempty"` +} + +type FileAlreadyExists struct { + FileFault +} + +func init() { + t["FileAlreadyExists"] = reflect.TypeOf((*FileAlreadyExists)(nil)).Elem() +} + +type FileAlreadyExistsFault FileAlreadyExists + +func init() { + t["FileAlreadyExistsFault"] = reflect.TypeOf((*FileAlreadyExistsFault)(nil)).Elem() +} + +type FileBackedPortNotSupported struct { + DeviceNotSupported +} + +func init() { + t["FileBackedPortNotSupported"] = reflect.TypeOf((*FileBackedPortNotSupported)(nil)).Elem() +} + +type FileBackedPortNotSupportedFault FileBackedPortNotSupported + +func init() { + t["FileBackedPortNotSupportedFault"] = reflect.TypeOf((*FileBackedPortNotSupportedFault)(nil)).Elem() +} + +type FileBackedVirtualDiskSpec struct { + VirtualDiskSpec + + CapacityKb int64 `xml:"capacityKb"` + Profile []BaseVirtualMachineProfileSpec `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["FileBackedVirtualDiskSpec"] = reflect.TypeOf((*FileBackedVirtualDiskSpec)(nil)).Elem() +} + +type FileFault struct { + VimFault + + File string `xml:"file"` +} + +func init() { + t["FileFault"] = reflect.TypeOf((*FileFault)(nil)).Elem() +} + +type FileFaultFault BaseFileFault + +func init() { + t["FileFaultFault"] = reflect.TypeOf((*FileFaultFault)(nil)).Elem() +} + +type FileInfo struct { + DynamicData + + Path string `xml:"path"` + FileSize int64 `xml:"fileSize,omitempty"` + Modification *time.Time `xml:"modification"` + Owner string `xml:"owner,omitempty"` +} + +func init() { + t["FileInfo"] = reflect.TypeOf((*FileInfo)(nil)).Elem() +} + +type FileLocked struct { + FileFault +} + +func init() { + t["FileLocked"] = reflect.TypeOf((*FileLocked)(nil)).Elem() +} + +type FileLockedFault FileLocked + +func init() { + t["FileLockedFault"] = reflect.TypeOf((*FileLockedFault)(nil)).Elem() +} + +type FileNameTooLong struct { + FileFault +} + +func init() { + t["FileNameTooLong"] = reflect.TypeOf((*FileNameTooLong)(nil)).Elem() +} + +type FileNameTooLongFault FileNameTooLong + +func init() { + t["FileNameTooLongFault"] = reflect.TypeOf((*FileNameTooLongFault)(nil)).Elem() +} + +type FileNotFound struct { + FileFault +} + +func init() { + t["FileNotFound"] = reflect.TypeOf((*FileNotFound)(nil)).Elem() +} + +type FileNotFoundFault FileNotFound + +func init() { + t["FileNotFoundFault"] = reflect.TypeOf((*FileNotFoundFault)(nil)).Elem() +} + +type FileNotWritable struct { + FileFault +} + +func init() { + t["FileNotWritable"] = reflect.TypeOf((*FileNotWritable)(nil)).Elem() +} + +type FileNotWritableFault FileNotWritable + +func init() { + t["FileNotWritableFault"] = reflect.TypeOf((*FileNotWritableFault)(nil)).Elem() +} + +type FileQuery struct { + DynamicData +} + +func init() { + t["FileQuery"] = reflect.TypeOf((*FileQuery)(nil)).Elem() +} + +type FileQueryFlags struct { + DynamicData + + FileType bool `xml:"fileType"` + FileSize bool `xml:"fileSize"` + Modification bool `xml:"modification"` + FileOwner *bool `xml:"fileOwner"` +} + +func init() { + t["FileQueryFlags"] = reflect.TypeOf((*FileQueryFlags)(nil)).Elem() +} + +type FileTooLarge struct { + FileFault + + Datastore string `xml:"datastore"` + FileSize int64 `xml:"fileSize"` + MaxFileSize int64 `xml:"maxFileSize,omitempty"` +} + +func init() { + t["FileTooLarge"] = reflect.TypeOf((*FileTooLarge)(nil)).Elem() +} + +type FileTooLargeFault FileTooLarge + +func init() { + t["FileTooLargeFault"] = reflect.TypeOf((*FileTooLargeFault)(nil)).Elem() +} + +type FileTransferInformation struct { + DynamicData + + Attributes BaseGuestFileAttributes `xml:"attributes,typeattr"` + Size int64 `xml:"size"` + Url string `xml:"url"` +} + +func init() { + t["FileTransferInformation"] = reflect.TypeOf((*FileTransferInformation)(nil)).Elem() +} + +type FilesystemQuiesceFault struct { + SnapshotFault +} + +func init() { + t["FilesystemQuiesceFault"] = reflect.TypeOf((*FilesystemQuiesceFault)(nil)).Elem() +} + +type FilesystemQuiesceFaultFault FilesystemQuiesceFault + +func init() { + t["FilesystemQuiesceFaultFault"] = reflect.TypeOf((*FilesystemQuiesceFaultFault)(nil)).Elem() +} + +type FilterInUse struct { + ResourceInUse + + Disk []VirtualDiskId `xml:"disk,omitempty"` +} + +func init() { + t["FilterInUse"] = reflect.TypeOf((*FilterInUse)(nil)).Elem() +} + +type FilterInUseFault FilterInUse + +func init() { + t["FilterInUseFault"] = reflect.TypeOf((*FilterInUseFault)(nil)).Elem() +} + +type FindAllByDnsName FindAllByDnsNameRequestType + +func init() { + t["FindAllByDnsName"] = reflect.TypeOf((*FindAllByDnsName)(nil)).Elem() +} + +type FindAllByDnsNameRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + DnsName string `xml:"dnsName"` + VmSearch bool `xml:"vmSearch"` +} + +func init() { + t["FindAllByDnsNameRequestType"] = reflect.TypeOf((*FindAllByDnsNameRequestType)(nil)).Elem() +} + +type FindAllByDnsNameResponse struct { + Returnval []ManagedObjectReference `xml:"returnval"` +} + +type FindAllByIp FindAllByIpRequestType + +func init() { + t["FindAllByIp"] = reflect.TypeOf((*FindAllByIp)(nil)).Elem() +} + +type FindAllByIpRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Ip string `xml:"ip"` + VmSearch bool `xml:"vmSearch"` +} + +func init() { + t["FindAllByIpRequestType"] = reflect.TypeOf((*FindAllByIpRequestType)(nil)).Elem() +} + +type FindAllByIpResponse struct { + Returnval []ManagedObjectReference `xml:"returnval"` +} + +type FindAllByUuid FindAllByUuidRequestType + +func init() { + t["FindAllByUuid"] = reflect.TypeOf((*FindAllByUuid)(nil)).Elem() +} + +type FindAllByUuidRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Uuid string `xml:"uuid"` + VmSearch bool `xml:"vmSearch"` + InstanceUuid *bool `xml:"instanceUuid"` +} + +func init() { + t["FindAllByUuidRequestType"] = reflect.TypeOf((*FindAllByUuidRequestType)(nil)).Elem() +} + +type FindAllByUuidResponse struct { + Returnval []ManagedObjectReference `xml:"returnval"` +} + +type FindAssociatedProfile FindAssociatedProfileRequestType + +func init() { + t["FindAssociatedProfile"] = reflect.TypeOf((*FindAssociatedProfile)(nil)).Elem() +} + +type FindAssociatedProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["FindAssociatedProfileRequestType"] = reflect.TypeOf((*FindAssociatedProfileRequestType)(nil)).Elem() +} + +type FindAssociatedProfileResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindByDatastorePath FindByDatastorePathRequestType + +func init() { + t["FindByDatastorePath"] = reflect.TypeOf((*FindByDatastorePath)(nil)).Elem() +} + +type FindByDatastorePathRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter ManagedObjectReference `xml:"datacenter"` + Path string `xml:"path"` +} + +func init() { + t["FindByDatastorePathRequestType"] = reflect.TypeOf((*FindByDatastorePathRequestType)(nil)).Elem() +} + +type FindByDatastorePathResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindByDnsName FindByDnsNameRequestType + +func init() { + t["FindByDnsName"] = reflect.TypeOf((*FindByDnsName)(nil)).Elem() +} + +type FindByDnsNameRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + DnsName string `xml:"dnsName"` + VmSearch bool `xml:"vmSearch"` +} + +func init() { + t["FindByDnsNameRequestType"] = reflect.TypeOf((*FindByDnsNameRequestType)(nil)).Elem() +} + +type FindByDnsNameResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindByInventoryPath FindByInventoryPathRequestType + +func init() { + t["FindByInventoryPath"] = reflect.TypeOf((*FindByInventoryPath)(nil)).Elem() +} + +type FindByInventoryPathRequestType struct { + This ManagedObjectReference `xml:"_this"` + InventoryPath string `xml:"inventoryPath"` +} + +func init() { + t["FindByInventoryPathRequestType"] = reflect.TypeOf((*FindByInventoryPathRequestType)(nil)).Elem() +} + +type FindByInventoryPathResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindByIp FindByIpRequestType + +func init() { + t["FindByIp"] = reflect.TypeOf((*FindByIp)(nil)).Elem() +} + +type FindByIpRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Ip string `xml:"ip"` + VmSearch bool `xml:"vmSearch"` +} + +func init() { + t["FindByIpRequestType"] = reflect.TypeOf((*FindByIpRequestType)(nil)).Elem() +} + +type FindByIpResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindByUuid FindByUuidRequestType + +func init() { + t["FindByUuid"] = reflect.TypeOf((*FindByUuid)(nil)).Elem() +} + +type FindByUuidRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Uuid string `xml:"uuid"` + VmSearch bool `xml:"vmSearch"` + InstanceUuid *bool `xml:"instanceUuid"` +} + +func init() { + t["FindByUuidRequestType"] = reflect.TypeOf((*FindByUuidRequestType)(nil)).Elem() +} + +type FindByUuidResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindChild FindChildRequestType + +func init() { + t["FindChild"] = reflect.TypeOf((*FindChild)(nil)).Elem() +} + +type FindChildRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Name string `xml:"name"` +} + +func init() { + t["FindChildRequestType"] = reflect.TypeOf((*FindChildRequestType)(nil)).Elem() +} + +type FindChildResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type FindExtension FindExtensionRequestType + +func init() { + t["FindExtension"] = reflect.TypeOf((*FindExtension)(nil)).Elem() +} + +type FindExtensionRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` +} + +func init() { + t["FindExtensionRequestType"] = reflect.TypeOf((*FindExtensionRequestType)(nil)).Elem() +} + +type FindExtensionResponse struct { + Returnval *Extension `xml:"returnval,omitempty"` +} + +type FindRulesForVm FindRulesForVmRequestType + +func init() { + t["FindRulesForVm"] = reflect.TypeOf((*FindRulesForVm)(nil)).Elem() +} + +type FindRulesForVmRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` +} + +func init() { + t["FindRulesForVmRequestType"] = reflect.TypeOf((*FindRulesForVmRequestType)(nil)).Elem() +} + +type FindRulesForVmResponse struct { + Returnval []BaseClusterRuleInfo `xml:"returnval,omitempty,typeattr"` +} + +type FirewallProfile struct { + ApplyProfile + + Ruleset []FirewallProfileRulesetProfile `xml:"ruleset,omitempty"` +} + +func init() { + t["FirewallProfile"] = reflect.TypeOf((*FirewallProfile)(nil)).Elem() +} + +type FirewallProfileRulesetProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["FirewallProfileRulesetProfile"] = reflect.TypeOf((*FirewallProfileRulesetProfile)(nil)).Elem() +} + +type FloatOption struct { + OptionType + + Min float32 `xml:"min"` + Max float32 `xml:"max"` + DefaultValue float32 `xml:"defaultValue"` +} + +func init() { + t["FloatOption"] = reflect.TypeOf((*FloatOption)(nil)).Elem() +} + +type FloppyImageFileInfo struct { + FileInfo +} + +func init() { + t["FloppyImageFileInfo"] = reflect.TypeOf((*FloppyImageFileInfo)(nil)).Elem() +} + +type FloppyImageFileQuery struct { + FileQuery +} + +func init() { + t["FloppyImageFileQuery"] = reflect.TypeOf((*FloppyImageFileQuery)(nil)).Elem() +} + +type FolderEventArgument struct { + EntityEventArgument + + Folder ManagedObjectReference `xml:"folder"` +} + +func init() { + t["FolderEventArgument"] = reflect.TypeOf((*FolderEventArgument)(nil)).Elem() +} + +type FolderFileInfo struct { + FileInfo +} + +func init() { + t["FolderFileInfo"] = reflect.TypeOf((*FolderFileInfo)(nil)).Elem() +} + +type FolderFileQuery struct { + FileQuery +} + +func init() { + t["FolderFileQuery"] = reflect.TypeOf((*FolderFileQuery)(nil)).Elem() +} + +type FormatVffs FormatVffsRequestType + +func init() { + t["FormatVffs"] = reflect.TypeOf((*FormatVffs)(nil)).Elem() +} + +type FormatVffsRequestType struct { + This ManagedObjectReference `xml:"_this"` + CreateSpec HostVffsSpec `xml:"createSpec"` +} + +func init() { + t["FormatVffsRequestType"] = reflect.TypeOf((*FormatVffsRequestType)(nil)).Elem() +} + +type FormatVffsResponse struct { + Returnval HostVffsVolume `xml:"returnval"` +} + +type FormatVmfs FormatVmfsRequestType + +func init() { + t["FormatVmfs"] = reflect.TypeOf((*FormatVmfs)(nil)).Elem() +} + +type FormatVmfsRequestType struct { + This ManagedObjectReference `xml:"_this"` + CreateSpec HostVmfsSpec `xml:"createSpec"` +} + +func init() { + t["FormatVmfsRequestType"] = reflect.TypeOf((*FormatVmfsRequestType)(nil)).Elem() +} + +type FormatVmfsResponse struct { + Returnval HostVmfsVolume `xml:"returnval"` +} + +type FtIssuesOnHost struct { + VmFaultToleranceIssue + + Host ManagedObjectReference `xml:"host"` + HostName string `xml:"hostName"` + Errors []LocalizedMethodFault `xml:"errors,omitempty"` +} + +func init() { + t["FtIssuesOnHost"] = reflect.TypeOf((*FtIssuesOnHost)(nil)).Elem() +} + +type FtIssuesOnHostFault FtIssuesOnHost + +func init() { + t["FtIssuesOnHostFault"] = reflect.TypeOf((*FtIssuesOnHostFault)(nil)).Elem() +} + +type FullStorageVMotionNotSupported struct { + MigrationFeatureNotSupported +} + +func init() { + t["FullStorageVMotionNotSupported"] = reflect.TypeOf((*FullStorageVMotionNotSupported)(nil)).Elem() +} + +type FullStorageVMotionNotSupportedFault FullStorageVMotionNotSupported + +func init() { + t["FullStorageVMotionNotSupportedFault"] = reflect.TypeOf((*FullStorageVMotionNotSupportedFault)(nil)).Elem() +} + +type GatewayConnectFault struct { + HostConnectFault + + GatewayType string `xml:"gatewayType"` + GatewayId string `xml:"gatewayId"` + GatewayInfo string `xml:"gatewayInfo"` + Details *LocalizableMessage `xml:"details,omitempty"` +} + +func init() { + t["GatewayConnectFault"] = reflect.TypeOf((*GatewayConnectFault)(nil)).Elem() +} + +type GatewayConnectFaultFault BaseGatewayConnectFault + +func init() { + t["GatewayConnectFaultFault"] = reflect.TypeOf((*GatewayConnectFaultFault)(nil)).Elem() +} + +type GatewayHostNotReachable struct { + GatewayToHostConnectFault +} + +func init() { + t["GatewayHostNotReachable"] = reflect.TypeOf((*GatewayHostNotReachable)(nil)).Elem() +} + +type GatewayHostNotReachableFault GatewayHostNotReachable + +func init() { + t["GatewayHostNotReachableFault"] = reflect.TypeOf((*GatewayHostNotReachableFault)(nil)).Elem() +} + +type GatewayNotFound struct { + GatewayConnectFault +} + +func init() { + t["GatewayNotFound"] = reflect.TypeOf((*GatewayNotFound)(nil)).Elem() +} + +type GatewayNotFoundFault GatewayNotFound + +func init() { + t["GatewayNotFoundFault"] = reflect.TypeOf((*GatewayNotFoundFault)(nil)).Elem() +} + +type GatewayNotReachable struct { + GatewayConnectFault +} + +func init() { + t["GatewayNotReachable"] = reflect.TypeOf((*GatewayNotReachable)(nil)).Elem() +} + +type GatewayNotReachableFault GatewayNotReachable + +func init() { + t["GatewayNotReachableFault"] = reflect.TypeOf((*GatewayNotReachableFault)(nil)).Elem() +} + +type GatewayOperationRefused struct { + GatewayConnectFault +} + +func init() { + t["GatewayOperationRefused"] = reflect.TypeOf((*GatewayOperationRefused)(nil)).Elem() +} + +type GatewayOperationRefusedFault GatewayOperationRefused + +func init() { + t["GatewayOperationRefusedFault"] = reflect.TypeOf((*GatewayOperationRefusedFault)(nil)).Elem() +} + +type GatewayToHostAuthFault struct { + GatewayToHostConnectFault + + InvalidProperties []string `xml:"invalidProperties"` + MissingProperties []string `xml:"missingProperties"` +} + +func init() { + t["GatewayToHostAuthFault"] = reflect.TypeOf((*GatewayToHostAuthFault)(nil)).Elem() +} + +type GatewayToHostAuthFaultFault GatewayToHostAuthFault + +func init() { + t["GatewayToHostAuthFaultFault"] = reflect.TypeOf((*GatewayToHostAuthFaultFault)(nil)).Elem() +} + +type GatewayToHostConnectFault struct { + GatewayConnectFault + + Hostname string `xml:"hostname"` + Port int32 `xml:"port,omitempty"` +} + +func init() { + t["GatewayToHostConnectFault"] = reflect.TypeOf((*GatewayToHostConnectFault)(nil)).Elem() +} + +type GatewayToHostConnectFaultFault BaseGatewayToHostConnectFault + +func init() { + t["GatewayToHostConnectFaultFault"] = reflect.TypeOf((*GatewayToHostConnectFaultFault)(nil)).Elem() +} + +type GatewayToHostTrustVerifyFault struct { + GatewayToHostConnectFault + + VerificationToken string `xml:"verificationToken"` + PropertiesToVerify []KeyValue `xml:"propertiesToVerify"` +} + +func init() { + t["GatewayToHostTrustVerifyFault"] = reflect.TypeOf((*GatewayToHostTrustVerifyFault)(nil)).Elem() +} + +type GatewayToHostTrustVerifyFaultFault GatewayToHostTrustVerifyFault + +func init() { + t["GatewayToHostTrustVerifyFaultFault"] = reflect.TypeOf((*GatewayToHostTrustVerifyFaultFault)(nil)).Elem() +} + +type GeneralEvent struct { + Event + + Message string `xml:"message"` +} + +func init() { + t["GeneralEvent"] = reflect.TypeOf((*GeneralEvent)(nil)).Elem() +} + +type GeneralHostErrorEvent struct { + GeneralEvent +} + +func init() { + t["GeneralHostErrorEvent"] = reflect.TypeOf((*GeneralHostErrorEvent)(nil)).Elem() +} + +type GeneralHostInfoEvent struct { + GeneralEvent +} + +func init() { + t["GeneralHostInfoEvent"] = reflect.TypeOf((*GeneralHostInfoEvent)(nil)).Elem() +} + +type GeneralHostWarningEvent struct { + GeneralEvent +} + +func init() { + t["GeneralHostWarningEvent"] = reflect.TypeOf((*GeneralHostWarningEvent)(nil)).Elem() +} + +type GeneralUserEvent struct { + GeneralEvent + + Entity *ManagedEntityEventArgument `xml:"entity,omitempty"` +} + +func init() { + t["GeneralUserEvent"] = reflect.TypeOf((*GeneralUserEvent)(nil)).Elem() +} + +type GeneralVmErrorEvent struct { + GeneralEvent +} + +func init() { + t["GeneralVmErrorEvent"] = reflect.TypeOf((*GeneralVmErrorEvent)(nil)).Elem() +} + +type GeneralVmInfoEvent struct { + GeneralEvent +} + +func init() { + t["GeneralVmInfoEvent"] = reflect.TypeOf((*GeneralVmInfoEvent)(nil)).Elem() +} + +type GeneralVmWarningEvent struct { + GeneralEvent +} + +func init() { + t["GeneralVmWarningEvent"] = reflect.TypeOf((*GeneralVmWarningEvent)(nil)).Elem() +} + +type GenerateCertificateSigningRequest GenerateCertificateSigningRequestRequestType + +func init() { + t["GenerateCertificateSigningRequest"] = reflect.TypeOf((*GenerateCertificateSigningRequest)(nil)).Elem() +} + +type GenerateCertificateSigningRequestByDn GenerateCertificateSigningRequestByDnRequestType + +func init() { + t["GenerateCertificateSigningRequestByDn"] = reflect.TypeOf((*GenerateCertificateSigningRequestByDn)(nil)).Elem() +} + +type GenerateCertificateSigningRequestByDnRequestType struct { + This ManagedObjectReference `xml:"_this"` + DistinguishedName string `xml:"distinguishedName"` +} + +func init() { + t["GenerateCertificateSigningRequestByDnRequestType"] = reflect.TypeOf((*GenerateCertificateSigningRequestByDnRequestType)(nil)).Elem() +} + +type GenerateCertificateSigningRequestByDnResponse struct { + Returnval string `xml:"returnval"` +} + +type GenerateCertificateSigningRequestRequestType struct { + This ManagedObjectReference `xml:"_this"` + UseIpAddressAsCommonName bool `xml:"useIpAddressAsCommonName"` +} + +func init() { + t["GenerateCertificateSigningRequestRequestType"] = reflect.TypeOf((*GenerateCertificateSigningRequestRequestType)(nil)).Elem() +} + +type GenerateCertificateSigningRequestResponse struct { + Returnval string `xml:"returnval"` +} + +type GenerateConfigTaskList GenerateConfigTaskListRequestType + +func init() { + t["GenerateConfigTaskList"] = reflect.TypeOf((*GenerateConfigTaskList)(nil)).Elem() +} + +type GenerateConfigTaskListRequestType struct { + This ManagedObjectReference `xml:"_this"` + ConfigSpec HostConfigSpec `xml:"configSpec"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["GenerateConfigTaskListRequestType"] = reflect.TypeOf((*GenerateConfigTaskListRequestType)(nil)).Elem() +} + +type GenerateConfigTaskListResponse struct { + Returnval HostProfileManagerConfigTaskList `xml:"returnval"` +} + +type GenerateHostProfileTaskListRequestType struct { + This ManagedObjectReference `xml:"_this"` + ConfigSpec HostConfigSpec `xml:"configSpec"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["GenerateHostProfileTaskListRequestType"] = reflect.TypeOf((*GenerateHostProfileTaskListRequestType)(nil)).Elem() +} + +type GenerateHostProfileTaskList_Task GenerateHostProfileTaskListRequestType + +func init() { + t["GenerateHostProfileTaskList_Task"] = reflect.TypeOf((*GenerateHostProfileTaskList_Task)(nil)).Elem() +} + +type GenerateHostProfileTaskList_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type GenerateLogBundlesRequestType struct { + This ManagedObjectReference `xml:"_this"` + IncludeDefault bool `xml:"includeDefault"` + Host []ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["GenerateLogBundlesRequestType"] = reflect.TypeOf((*GenerateLogBundlesRequestType)(nil)).Elem() +} + +type GenerateLogBundles_Task GenerateLogBundlesRequestType + +func init() { + t["GenerateLogBundles_Task"] = reflect.TypeOf((*GenerateLogBundles_Task)(nil)).Elem() +} + +type GenerateLogBundles_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type GenericDrsFault struct { + VimFault + + HostFaults []LocalizedMethodFault `xml:"hostFaults,omitempty"` +} + +func init() { + t["GenericDrsFault"] = reflect.TypeOf((*GenericDrsFault)(nil)).Elem() +} + +type GenericDrsFaultFault GenericDrsFault + +func init() { + t["GenericDrsFaultFault"] = reflect.TypeOf((*GenericDrsFaultFault)(nil)).Elem() +} + +type GenericVmConfigFault struct { + VmConfigFault + + Reason string `xml:"reason"` +} + +func init() { + t["GenericVmConfigFault"] = reflect.TypeOf((*GenericVmConfigFault)(nil)).Elem() +} + +type GenericVmConfigFaultFault GenericVmConfigFault + +func init() { + t["GenericVmConfigFaultFault"] = reflect.TypeOf((*GenericVmConfigFaultFault)(nil)).Elem() +} + +type GetAlarm GetAlarmRequestType + +func init() { + t["GetAlarm"] = reflect.TypeOf((*GetAlarm)(nil)).Elem() +} + +type GetAlarmRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["GetAlarmRequestType"] = reflect.TypeOf((*GetAlarmRequestType)(nil)).Elem() +} + +type GetAlarmResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type GetAlarmState GetAlarmStateRequestType + +func init() { + t["GetAlarmState"] = reflect.TypeOf((*GetAlarmState)(nil)).Elem() +} + +type GetAlarmStateRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["GetAlarmStateRequestType"] = reflect.TypeOf((*GetAlarmStateRequestType)(nil)).Elem() +} + +type GetAlarmStateResponse struct { + Returnval []AlarmState `xml:"returnval,omitempty"` +} + +type GetCustomizationSpec GetCustomizationSpecRequestType + +func init() { + t["GetCustomizationSpec"] = reflect.TypeOf((*GetCustomizationSpec)(nil)).Elem() +} + +type GetCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["GetCustomizationSpecRequestType"] = reflect.TypeOf((*GetCustomizationSpecRequestType)(nil)).Elem() +} + +type GetCustomizationSpecResponse struct { + Returnval CustomizationSpecItem `xml:"returnval"` +} + +type GetPublicKey GetPublicKeyRequestType + +func init() { + t["GetPublicKey"] = reflect.TypeOf((*GetPublicKey)(nil)).Elem() +} + +type GetPublicKeyRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["GetPublicKeyRequestType"] = reflect.TypeOf((*GetPublicKeyRequestType)(nil)).Elem() +} + +type GetPublicKeyResponse struct { + Returnval string `xml:"returnval"` +} + +type GetResourceUsage GetResourceUsageRequestType + +func init() { + t["GetResourceUsage"] = reflect.TypeOf((*GetResourceUsage)(nil)).Elem() +} + +type GetResourceUsageRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["GetResourceUsageRequestType"] = reflect.TypeOf((*GetResourceUsageRequestType)(nil)).Elem() +} + +type GetResourceUsageResponse struct { + Returnval ClusterResourceUsageSummary `xml:"returnval"` +} + +type GetVsanObjExtAttrs GetVsanObjExtAttrsRequestType + +func init() { + t["GetVsanObjExtAttrs"] = reflect.TypeOf((*GetVsanObjExtAttrs)(nil)).Elem() +} + +type GetVsanObjExtAttrsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids"` +} + +func init() { + t["GetVsanObjExtAttrsRequestType"] = reflect.TypeOf((*GetVsanObjExtAttrsRequestType)(nil)).Elem() +} + +type GetVsanObjExtAttrsResponse struct { + Returnval string `xml:"returnval"` +} + +type GhostDvsProxySwitchDetectedEvent struct { + HostEvent + + SwitchUuid []string `xml:"switchUuid"` +} + +func init() { + t["GhostDvsProxySwitchDetectedEvent"] = reflect.TypeOf((*GhostDvsProxySwitchDetectedEvent)(nil)).Elem() +} + +type GhostDvsProxySwitchRemovedEvent struct { + HostEvent + + SwitchUuid []string `xml:"switchUuid"` +} + +func init() { + t["GhostDvsProxySwitchRemovedEvent"] = reflect.TypeOf((*GhostDvsProxySwitchRemovedEvent)(nil)).Elem() +} + +type GlobalMessageChangedEvent struct { + SessionEvent + + Message string `xml:"message"` +} + +func init() { + t["GlobalMessageChangedEvent"] = reflect.TypeOf((*GlobalMessageChangedEvent)(nil)).Elem() +} + +type GroupAlarmAction struct { + AlarmAction + + Action []BaseAlarmAction `xml:"action,typeattr"` +} + +func init() { + t["GroupAlarmAction"] = reflect.TypeOf((*GroupAlarmAction)(nil)).Elem() +} + +type GuestAliases struct { + DynamicData + + Base64Cert string `xml:"base64Cert"` + Aliases []GuestAuthAliasInfo `xml:"aliases"` +} + +func init() { + t["GuestAliases"] = reflect.TypeOf((*GuestAliases)(nil)).Elem() +} + +type GuestAuthAliasInfo struct { + DynamicData + + Subject BaseGuestAuthSubject `xml:"subject,typeattr"` + Comment string `xml:"comment"` +} + +func init() { + t["GuestAuthAliasInfo"] = reflect.TypeOf((*GuestAuthAliasInfo)(nil)).Elem() +} + +type GuestAuthAnySubject struct { + GuestAuthSubject +} + +func init() { + t["GuestAuthAnySubject"] = reflect.TypeOf((*GuestAuthAnySubject)(nil)).Elem() +} + +type GuestAuthNamedSubject struct { + GuestAuthSubject + + Name string `xml:"name"` +} + +func init() { + t["GuestAuthNamedSubject"] = reflect.TypeOf((*GuestAuthNamedSubject)(nil)).Elem() +} + +type GuestAuthSubject struct { + DynamicData +} + +func init() { + t["GuestAuthSubject"] = reflect.TypeOf((*GuestAuthSubject)(nil)).Elem() +} + +type GuestAuthentication struct { + DynamicData + + InteractiveSession bool `xml:"interactiveSession"` +} + +func init() { + t["GuestAuthentication"] = reflect.TypeOf((*GuestAuthentication)(nil)).Elem() +} + +type GuestAuthenticationChallenge struct { + GuestOperationsFault + + ServerChallenge BaseGuestAuthentication `xml:"serverChallenge,typeattr"` + SessionID int64 `xml:"sessionID"` +} + +func init() { + t["GuestAuthenticationChallenge"] = reflect.TypeOf((*GuestAuthenticationChallenge)(nil)).Elem() +} + +type GuestAuthenticationChallengeFault GuestAuthenticationChallenge + +func init() { + t["GuestAuthenticationChallengeFault"] = reflect.TypeOf((*GuestAuthenticationChallengeFault)(nil)).Elem() +} + +type GuestComponentsOutOfDate struct { + GuestOperationsFault +} + +func init() { + t["GuestComponentsOutOfDate"] = reflect.TypeOf((*GuestComponentsOutOfDate)(nil)).Elem() +} + +type GuestComponentsOutOfDateFault GuestComponentsOutOfDate + +func init() { + t["GuestComponentsOutOfDateFault"] = reflect.TypeOf((*GuestComponentsOutOfDateFault)(nil)).Elem() +} + +type GuestDiskInfo struct { + DynamicData + + DiskPath string `xml:"diskPath,omitempty"` + Capacity int64 `xml:"capacity,omitempty"` + FreeSpace int64 `xml:"freeSpace,omitempty"` +} + +func init() { + t["GuestDiskInfo"] = reflect.TypeOf((*GuestDiskInfo)(nil)).Elem() +} + +type GuestFileAttributes struct { + DynamicData + + ModificationTime *time.Time `xml:"modificationTime"` + AccessTime *time.Time `xml:"accessTime"` + SymlinkTarget string `xml:"symlinkTarget,omitempty"` +} + +func init() { + t["GuestFileAttributes"] = reflect.TypeOf((*GuestFileAttributes)(nil)).Elem() +} + +type GuestFileInfo struct { + DynamicData + + Path string `xml:"path"` + Type string `xml:"type"` + Size int64 `xml:"size"` + Attributes BaseGuestFileAttributes `xml:"attributes,typeattr"` +} + +func init() { + t["GuestFileInfo"] = reflect.TypeOf((*GuestFileInfo)(nil)).Elem() +} + +type GuestInfo struct { + DynamicData + + ToolsStatus VirtualMachineToolsStatus `xml:"toolsStatus,omitempty"` + ToolsVersionStatus string `xml:"toolsVersionStatus,omitempty"` + ToolsVersionStatus2 string `xml:"toolsVersionStatus2,omitempty"` + ToolsRunningStatus string `xml:"toolsRunningStatus,omitempty"` + ToolsVersion string `xml:"toolsVersion,omitempty"` + GuestId string `xml:"guestId,omitempty"` + GuestFamily string `xml:"guestFamily,omitempty"` + GuestFullName string `xml:"guestFullName,omitempty"` + HostName string `xml:"hostName,omitempty"` + IpAddress string `xml:"ipAddress,omitempty"` + Net []GuestNicInfo `xml:"net,omitempty"` + IpStack []GuestStackInfo `xml:"ipStack,omitempty"` + Disk []GuestDiskInfo `xml:"disk,omitempty"` + Screen *GuestScreenInfo `xml:"screen,omitempty"` + GuestState string `xml:"guestState"` + AppHeartbeatStatus string `xml:"appHeartbeatStatus,omitempty"` + GuestKernelCrashed *bool `xml:"guestKernelCrashed"` + AppState string `xml:"appState,omitempty"` + GuestOperationsReady *bool `xml:"guestOperationsReady"` + InteractiveGuestOperationsReady *bool `xml:"interactiveGuestOperationsReady"` + GuestStateChangeSupported *bool `xml:"guestStateChangeSupported"` + GenerationInfo []GuestInfoNamespaceGenerationInfo `xml:"generationInfo,omitempty"` +} + +func init() { + t["GuestInfo"] = reflect.TypeOf((*GuestInfo)(nil)).Elem() +} + +type GuestInfoNamespaceGenerationInfo struct { + DynamicData + + Key string `xml:"key"` + GenerationNo int32 `xml:"generationNo"` +} + +func init() { + t["GuestInfoNamespaceGenerationInfo"] = reflect.TypeOf((*GuestInfoNamespaceGenerationInfo)(nil)).Elem() +} + +type GuestListFileInfo struct { + DynamicData + + Files []GuestFileInfo `xml:"files,omitempty"` + Remaining int32 `xml:"remaining"` +} + +func init() { + t["GuestListFileInfo"] = reflect.TypeOf((*GuestListFileInfo)(nil)).Elem() +} + +type GuestMappedAliases struct { + DynamicData + + Base64Cert string `xml:"base64Cert"` + Username string `xml:"username"` + Subjects []BaseGuestAuthSubject `xml:"subjects,typeattr"` +} + +func init() { + t["GuestMappedAliases"] = reflect.TypeOf((*GuestMappedAliases)(nil)).Elem() +} + +type GuestMultipleMappings struct { + GuestOperationsFault +} + +func init() { + t["GuestMultipleMappings"] = reflect.TypeOf((*GuestMultipleMappings)(nil)).Elem() +} + +type GuestMultipleMappingsFault GuestMultipleMappings + +func init() { + t["GuestMultipleMappingsFault"] = reflect.TypeOf((*GuestMultipleMappingsFault)(nil)).Elem() +} + +type GuestNicInfo struct { + DynamicData + + Network string `xml:"network,omitempty"` + IpAddress []string `xml:"ipAddress,omitempty"` + MacAddress string `xml:"macAddress,omitempty"` + Connected bool `xml:"connected"` + DeviceConfigId int32 `xml:"deviceConfigId"` + DnsConfig *NetDnsConfigInfo `xml:"dnsConfig,omitempty"` + IpConfig *NetIpConfigInfo `xml:"ipConfig,omitempty"` + NetBIOSConfig BaseNetBIOSConfigInfo `xml:"netBIOSConfig,omitempty,typeattr"` +} + +func init() { + t["GuestNicInfo"] = reflect.TypeOf((*GuestNicInfo)(nil)).Elem() +} + +type GuestOperationsFault struct { + VimFault +} + +func init() { + t["GuestOperationsFault"] = reflect.TypeOf((*GuestOperationsFault)(nil)).Elem() +} + +type GuestOperationsFaultFault BaseGuestOperationsFault + +func init() { + t["GuestOperationsFaultFault"] = reflect.TypeOf((*GuestOperationsFaultFault)(nil)).Elem() +} + +type GuestOperationsUnavailable struct { + GuestOperationsFault +} + +func init() { + t["GuestOperationsUnavailable"] = reflect.TypeOf((*GuestOperationsUnavailable)(nil)).Elem() +} + +type GuestOperationsUnavailableFault GuestOperationsUnavailable + +func init() { + t["GuestOperationsUnavailableFault"] = reflect.TypeOf((*GuestOperationsUnavailableFault)(nil)).Elem() +} + +type GuestOsDescriptor struct { + DynamicData + + Id string `xml:"id"` + Family string `xml:"family"` + FullName string `xml:"fullName"` + SupportedMaxCPUs int32 `xml:"supportedMaxCPUs"` + NumSupportedPhysicalSockets int32 `xml:"numSupportedPhysicalSockets,omitempty"` + NumSupportedCoresPerSocket int32 `xml:"numSupportedCoresPerSocket,omitempty"` + SupportedMinMemMB int32 `xml:"supportedMinMemMB"` + SupportedMaxMemMB int32 `xml:"supportedMaxMemMB"` + RecommendedMemMB int32 `xml:"recommendedMemMB"` + RecommendedColorDepth int32 `xml:"recommendedColorDepth"` + SupportedDiskControllerList []string `xml:"supportedDiskControllerList"` + RecommendedSCSIController string `xml:"recommendedSCSIController,omitempty"` + RecommendedDiskController string `xml:"recommendedDiskController"` + SupportedNumDisks int32 `xml:"supportedNumDisks"` + RecommendedDiskSizeMB int32 `xml:"recommendedDiskSizeMB"` + RecommendedCdromController string `xml:"recommendedCdromController,omitempty"` + SupportedEthernetCard []string `xml:"supportedEthernetCard"` + RecommendedEthernetCard string `xml:"recommendedEthernetCard,omitempty"` + SupportsSlaveDisk *bool `xml:"supportsSlaveDisk"` + CpuFeatureMask []HostCpuIdInfo `xml:"cpuFeatureMask,omitempty"` + SmcRequired *bool `xml:"smcRequired"` + SupportsWakeOnLan bool `xml:"supportsWakeOnLan"` + SupportsVMI *bool `xml:"supportsVMI"` + SupportsMemoryHotAdd *bool `xml:"supportsMemoryHotAdd"` + SupportsCpuHotAdd *bool `xml:"supportsCpuHotAdd"` + SupportsCpuHotRemove *bool `xml:"supportsCpuHotRemove"` + SupportedFirmware []string `xml:"supportedFirmware,omitempty"` + RecommendedFirmware string `xml:"recommendedFirmware,omitempty"` + SupportedUSBControllerList []string `xml:"supportedUSBControllerList,omitempty"` + RecommendedUSBController string `xml:"recommendedUSBController,omitempty"` + Supports3D *bool `xml:"supports3D"` + Recommended3D *bool `xml:"recommended3D"` + SmcRecommended *bool `xml:"smcRecommended"` + Ich7mRecommended *bool `xml:"ich7mRecommended"` + UsbRecommended *bool `xml:"usbRecommended"` + SupportLevel string `xml:"supportLevel,omitempty"` + SupportedForCreate *bool `xml:"supportedForCreate"` + VRAMSizeInKB *IntOption `xml:"vRAMSizeInKB,omitempty"` + NumSupportedFloppyDevices int32 `xml:"numSupportedFloppyDevices,omitempty"` + WakeOnLanEthernetCard []string `xml:"wakeOnLanEthernetCard,omitempty"` + SupportsPvscsiControllerForBoot *bool `xml:"supportsPvscsiControllerForBoot"` + DiskUuidEnabled *bool `xml:"diskUuidEnabled"` + SupportsHotPlugPCI *bool `xml:"supportsHotPlugPCI"` +} + +func init() { + t["GuestOsDescriptor"] = reflect.TypeOf((*GuestOsDescriptor)(nil)).Elem() +} + +type GuestPermissionDenied struct { + GuestOperationsFault +} + +func init() { + t["GuestPermissionDenied"] = reflect.TypeOf((*GuestPermissionDenied)(nil)).Elem() +} + +type GuestPermissionDeniedFault GuestPermissionDenied + +func init() { + t["GuestPermissionDeniedFault"] = reflect.TypeOf((*GuestPermissionDeniedFault)(nil)).Elem() +} + +type GuestPosixFileAttributes struct { + GuestFileAttributes + + OwnerId int32 `xml:"ownerId,omitempty"` + GroupId int32 `xml:"groupId,omitempty"` + Permissions int64 `xml:"permissions,omitempty"` +} + +func init() { + t["GuestPosixFileAttributes"] = reflect.TypeOf((*GuestPosixFileAttributes)(nil)).Elem() +} + +type GuestProcessInfo struct { + DynamicData + + Name string `xml:"name"` + Pid int64 `xml:"pid"` + Owner string `xml:"owner"` + CmdLine string `xml:"cmdLine"` + StartTime time.Time `xml:"startTime"` + EndTime *time.Time `xml:"endTime"` + ExitCode int32 `xml:"exitCode,omitempty"` +} + +func init() { + t["GuestProcessInfo"] = reflect.TypeOf((*GuestProcessInfo)(nil)).Elem() +} + +type GuestProcessNotFound struct { + GuestOperationsFault + + Pid int64 `xml:"pid"` +} + +func init() { + t["GuestProcessNotFound"] = reflect.TypeOf((*GuestProcessNotFound)(nil)).Elem() +} + +type GuestProcessNotFoundFault GuestProcessNotFound + +func init() { + t["GuestProcessNotFoundFault"] = reflect.TypeOf((*GuestProcessNotFoundFault)(nil)).Elem() +} + +type GuestProgramSpec struct { + DynamicData + + ProgramPath string `xml:"programPath"` + Arguments string `xml:"arguments"` + WorkingDirectory string `xml:"workingDirectory,omitempty"` + EnvVariables []string `xml:"envVariables,omitempty"` +} + +func init() { + t["GuestProgramSpec"] = reflect.TypeOf((*GuestProgramSpec)(nil)).Elem() +} + +type GuestRegKeyNameSpec struct { + DynamicData + + RegistryPath string `xml:"registryPath"` + WowBitness string `xml:"wowBitness"` +} + +func init() { + t["GuestRegKeyNameSpec"] = reflect.TypeOf((*GuestRegKeyNameSpec)(nil)).Elem() +} + +type GuestRegKeyRecordSpec struct { + DynamicData + + Key GuestRegKeySpec `xml:"key"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["GuestRegKeyRecordSpec"] = reflect.TypeOf((*GuestRegKeyRecordSpec)(nil)).Elem() +} + +type GuestRegKeySpec struct { + DynamicData + + KeyName GuestRegKeyNameSpec `xml:"keyName"` + ClassType string `xml:"classType"` + LastWritten time.Time `xml:"lastWritten"` +} + +func init() { + t["GuestRegKeySpec"] = reflect.TypeOf((*GuestRegKeySpec)(nil)).Elem() +} + +type GuestRegValueBinarySpec struct { + GuestRegValueDataSpec + + Value []byte `xml:"value,omitempty"` +} + +func init() { + t["GuestRegValueBinarySpec"] = reflect.TypeOf((*GuestRegValueBinarySpec)(nil)).Elem() +} + +type GuestRegValueDataSpec struct { + DynamicData +} + +func init() { + t["GuestRegValueDataSpec"] = reflect.TypeOf((*GuestRegValueDataSpec)(nil)).Elem() +} + +type GuestRegValueDwordSpec struct { + GuestRegValueDataSpec + + Value int32 `xml:"value"` +} + +func init() { + t["GuestRegValueDwordSpec"] = reflect.TypeOf((*GuestRegValueDwordSpec)(nil)).Elem() +} + +type GuestRegValueExpandStringSpec struct { + GuestRegValueDataSpec + + Value string `xml:"value,omitempty"` +} + +func init() { + t["GuestRegValueExpandStringSpec"] = reflect.TypeOf((*GuestRegValueExpandStringSpec)(nil)).Elem() +} + +type GuestRegValueMultiStringSpec struct { + GuestRegValueDataSpec + + Value []string `xml:"value,omitempty"` +} + +func init() { + t["GuestRegValueMultiStringSpec"] = reflect.TypeOf((*GuestRegValueMultiStringSpec)(nil)).Elem() +} + +type GuestRegValueNameSpec struct { + DynamicData + + KeyName GuestRegKeyNameSpec `xml:"keyName"` + Name string `xml:"name"` +} + +func init() { + t["GuestRegValueNameSpec"] = reflect.TypeOf((*GuestRegValueNameSpec)(nil)).Elem() +} + +type GuestRegValueQwordSpec struct { + GuestRegValueDataSpec + + Value int64 `xml:"value"` +} + +func init() { + t["GuestRegValueQwordSpec"] = reflect.TypeOf((*GuestRegValueQwordSpec)(nil)).Elem() +} + +type GuestRegValueSpec struct { + DynamicData + + Name GuestRegValueNameSpec `xml:"name"` + Data BaseGuestRegValueDataSpec `xml:"data,typeattr"` +} + +func init() { + t["GuestRegValueSpec"] = reflect.TypeOf((*GuestRegValueSpec)(nil)).Elem() +} + +type GuestRegValueStringSpec struct { + GuestRegValueDataSpec + + Value string `xml:"value,omitempty"` +} + +func init() { + t["GuestRegValueStringSpec"] = reflect.TypeOf((*GuestRegValueStringSpec)(nil)).Elem() +} + +type GuestRegistryFault struct { + GuestOperationsFault + + WindowsSystemErrorCode int64 `xml:"windowsSystemErrorCode"` +} + +func init() { + t["GuestRegistryFault"] = reflect.TypeOf((*GuestRegistryFault)(nil)).Elem() +} + +type GuestRegistryFaultFault BaseGuestRegistryFault + +func init() { + t["GuestRegistryFaultFault"] = reflect.TypeOf((*GuestRegistryFaultFault)(nil)).Elem() +} + +type GuestRegistryKeyAlreadyExists struct { + GuestRegistryKeyFault +} + +func init() { + t["GuestRegistryKeyAlreadyExists"] = reflect.TypeOf((*GuestRegistryKeyAlreadyExists)(nil)).Elem() +} + +type GuestRegistryKeyAlreadyExistsFault GuestRegistryKeyAlreadyExists + +func init() { + t["GuestRegistryKeyAlreadyExistsFault"] = reflect.TypeOf((*GuestRegistryKeyAlreadyExistsFault)(nil)).Elem() +} + +type GuestRegistryKeyFault struct { + GuestRegistryFault + + KeyName string `xml:"keyName"` +} + +func init() { + t["GuestRegistryKeyFault"] = reflect.TypeOf((*GuestRegistryKeyFault)(nil)).Elem() +} + +type GuestRegistryKeyFaultFault BaseGuestRegistryKeyFault + +func init() { + t["GuestRegistryKeyFaultFault"] = reflect.TypeOf((*GuestRegistryKeyFaultFault)(nil)).Elem() +} + +type GuestRegistryKeyHasSubkeys struct { + GuestRegistryKeyFault +} + +func init() { + t["GuestRegistryKeyHasSubkeys"] = reflect.TypeOf((*GuestRegistryKeyHasSubkeys)(nil)).Elem() +} + +type GuestRegistryKeyHasSubkeysFault GuestRegistryKeyHasSubkeys + +func init() { + t["GuestRegistryKeyHasSubkeysFault"] = reflect.TypeOf((*GuestRegistryKeyHasSubkeysFault)(nil)).Elem() +} + +type GuestRegistryKeyInvalid struct { + GuestRegistryKeyFault +} + +func init() { + t["GuestRegistryKeyInvalid"] = reflect.TypeOf((*GuestRegistryKeyInvalid)(nil)).Elem() +} + +type GuestRegistryKeyInvalidFault GuestRegistryKeyInvalid + +func init() { + t["GuestRegistryKeyInvalidFault"] = reflect.TypeOf((*GuestRegistryKeyInvalidFault)(nil)).Elem() +} + +type GuestRegistryKeyParentVolatile struct { + GuestRegistryKeyFault +} + +func init() { + t["GuestRegistryKeyParentVolatile"] = reflect.TypeOf((*GuestRegistryKeyParentVolatile)(nil)).Elem() +} + +type GuestRegistryKeyParentVolatileFault GuestRegistryKeyParentVolatile + +func init() { + t["GuestRegistryKeyParentVolatileFault"] = reflect.TypeOf((*GuestRegistryKeyParentVolatileFault)(nil)).Elem() +} + +type GuestRegistryValueFault struct { + GuestRegistryFault + + KeyName string `xml:"keyName"` + ValueName string `xml:"valueName"` +} + +func init() { + t["GuestRegistryValueFault"] = reflect.TypeOf((*GuestRegistryValueFault)(nil)).Elem() +} + +type GuestRegistryValueFaultFault BaseGuestRegistryValueFault + +func init() { + t["GuestRegistryValueFaultFault"] = reflect.TypeOf((*GuestRegistryValueFaultFault)(nil)).Elem() +} + +type GuestRegistryValueNotFound struct { + GuestRegistryValueFault +} + +func init() { + t["GuestRegistryValueNotFound"] = reflect.TypeOf((*GuestRegistryValueNotFound)(nil)).Elem() +} + +type GuestRegistryValueNotFoundFault GuestRegistryValueNotFound + +func init() { + t["GuestRegistryValueNotFoundFault"] = reflect.TypeOf((*GuestRegistryValueNotFoundFault)(nil)).Elem() +} + +type GuestScreenInfo struct { + DynamicData + + Width int32 `xml:"width"` + Height int32 `xml:"height"` +} + +func init() { + t["GuestScreenInfo"] = reflect.TypeOf((*GuestScreenInfo)(nil)).Elem() +} + +type GuestStackInfo struct { + DynamicData + + DnsConfig *NetDnsConfigInfo `xml:"dnsConfig,omitempty"` + IpRouteConfig *NetIpRouteConfigInfo `xml:"ipRouteConfig,omitempty"` + IpStackConfig []KeyValue `xml:"ipStackConfig,omitempty"` + DhcpConfig *NetDhcpConfigInfo `xml:"dhcpConfig,omitempty"` +} + +func init() { + t["GuestStackInfo"] = reflect.TypeOf((*GuestStackInfo)(nil)).Elem() +} + +type GuestWindowsFileAttributes struct { + GuestFileAttributes + + Hidden *bool `xml:"hidden"` + ReadOnly *bool `xml:"readOnly"` + CreateTime *time.Time `xml:"createTime"` +} + +func init() { + t["GuestWindowsFileAttributes"] = reflect.TypeOf((*GuestWindowsFileAttributes)(nil)).Elem() +} + +type GuestWindowsProgramSpec struct { + GuestProgramSpec + + StartMinimized bool `xml:"startMinimized"` +} + +func init() { + t["GuestWindowsProgramSpec"] = reflect.TypeOf((*GuestWindowsProgramSpec)(nil)).Elem() +} + +type HAErrorsAtDest struct { + MigrationFault +} + +func init() { + t["HAErrorsAtDest"] = reflect.TypeOf((*HAErrorsAtDest)(nil)).Elem() +} + +type HAErrorsAtDestFault HAErrorsAtDest + +func init() { + t["HAErrorsAtDestFault"] = reflect.TypeOf((*HAErrorsAtDestFault)(nil)).Elem() +} + +type HasPrivilegeOnEntities HasPrivilegeOnEntitiesRequestType + +func init() { + t["HasPrivilegeOnEntities"] = reflect.TypeOf((*HasPrivilegeOnEntities)(nil)).Elem() +} + +type HasPrivilegeOnEntitiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity []ManagedObjectReference `xml:"entity"` + SessionId string `xml:"sessionId"` + PrivId []string `xml:"privId,omitempty"` +} + +func init() { + t["HasPrivilegeOnEntitiesRequestType"] = reflect.TypeOf((*HasPrivilegeOnEntitiesRequestType)(nil)).Elem() +} + +type HasPrivilegeOnEntitiesResponse struct { + Returnval []EntityPrivilege `xml:"returnval,omitempty"` +} + +type HasPrivilegeOnEntity HasPrivilegeOnEntityRequestType + +func init() { + t["HasPrivilegeOnEntity"] = reflect.TypeOf((*HasPrivilegeOnEntity)(nil)).Elem() +} + +type HasPrivilegeOnEntityRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + SessionId string `xml:"sessionId"` + PrivId []string `xml:"privId,omitempty"` +} + +func init() { + t["HasPrivilegeOnEntityRequestType"] = reflect.TypeOf((*HasPrivilegeOnEntityRequestType)(nil)).Elem() +} + +type HasPrivilegeOnEntityResponse struct { + Returnval []bool `xml:"returnval,omitempty"` +} + +type HbrDiskMigrationAction struct { + ClusterAction + + CollectionId string `xml:"collectionId"` + CollectionName string `xml:"collectionName"` + DiskIds []string `xml:"diskIds"` + Source ManagedObjectReference `xml:"source"` + Destination ManagedObjectReference `xml:"destination"` + SizeTransferred int64 `xml:"sizeTransferred"` + SpaceUtilSrcBefore float32 `xml:"spaceUtilSrcBefore,omitempty"` + SpaceUtilDstBefore float32 `xml:"spaceUtilDstBefore,omitempty"` + SpaceUtilSrcAfter float32 `xml:"spaceUtilSrcAfter,omitempty"` + SpaceUtilDstAfter float32 `xml:"spaceUtilDstAfter,omitempty"` + IoLatencySrcBefore float32 `xml:"ioLatencySrcBefore,omitempty"` + IoLatencyDstBefore float32 `xml:"ioLatencyDstBefore,omitempty"` +} + +func init() { + t["HbrDiskMigrationAction"] = reflect.TypeOf((*HbrDiskMigrationAction)(nil)).Elem() +} + +type HbrManagerReplicationVmInfo struct { + DynamicData + + State string `xml:"state"` + ProgressInfo *ReplicationVmProgressInfo `xml:"progressInfo,omitempty"` + ImageId string `xml:"imageId,omitempty"` + LastError *LocalizedMethodFault `xml:"lastError,omitempty"` +} + +func init() { + t["HbrManagerReplicationVmInfo"] = reflect.TypeOf((*HbrManagerReplicationVmInfo)(nil)).Elem() +} + +type HbrManagerVmReplicationCapability struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + SupportedQuiesceMode string `xml:"supportedQuiesceMode"` + CompressionSupported bool `xml:"compressionSupported"` + MaxSupportedSourceDiskCapacity int64 `xml:"maxSupportedSourceDiskCapacity"` + MinRpo int64 `xml:"minRpo,omitempty"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HbrManagerVmReplicationCapability"] = reflect.TypeOf((*HbrManagerVmReplicationCapability)(nil)).Elem() +} + +type HealthStatusChangedEvent struct { + Event + + ComponentId string `xml:"componentId"` + OldStatus string `xml:"oldStatus"` + NewStatus string `xml:"newStatus"` + ComponentName string `xml:"componentName"` + ServiceId string `xml:"serviceId,omitempty"` +} + +func init() { + t["HealthStatusChangedEvent"] = reflect.TypeOf((*HealthStatusChangedEvent)(nil)).Elem() +} + +type HealthSystemRuntime struct { + DynamicData + + SystemHealthInfo *HostSystemHealthInfo `xml:"systemHealthInfo,omitempty"` + HardwareStatusInfo *HostHardwareStatusInfo `xml:"hardwareStatusInfo,omitempty"` +} + +func init() { + t["HealthSystemRuntime"] = reflect.TypeOf((*HealthSystemRuntime)(nil)).Elem() +} + +type HeterogenousHostsBlockingEVC struct { + EVCConfigFault +} + +func init() { + t["HeterogenousHostsBlockingEVC"] = reflect.TypeOf((*HeterogenousHostsBlockingEVC)(nil)).Elem() +} + +type HeterogenousHostsBlockingEVCFault HeterogenousHostsBlockingEVC + +func init() { + t["HeterogenousHostsBlockingEVCFault"] = reflect.TypeOf((*HeterogenousHostsBlockingEVCFault)(nil)).Elem() +} + +type HostAccessControlEntry struct { + DynamicData + + Principal string `xml:"principal"` + Group bool `xml:"group"` + AccessMode HostAccessMode `xml:"accessMode"` +} + +func init() { + t["HostAccessControlEntry"] = reflect.TypeOf((*HostAccessControlEntry)(nil)).Elem() +} + +type HostAccessRestrictedToManagementServer struct { + NotSupported + + ManagementServer string `xml:"managementServer"` +} + +func init() { + t["HostAccessRestrictedToManagementServer"] = reflect.TypeOf((*HostAccessRestrictedToManagementServer)(nil)).Elem() +} + +type HostAccessRestrictedToManagementServerFault HostAccessRestrictedToManagementServer + +func init() { + t["HostAccessRestrictedToManagementServerFault"] = reflect.TypeOf((*HostAccessRestrictedToManagementServerFault)(nil)).Elem() +} + +type HostAccountSpec struct { + DynamicData + + Id string `xml:"id"` + Password string `xml:"password,omitempty"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["HostAccountSpec"] = reflect.TypeOf((*HostAccountSpec)(nil)).Elem() +} + +type HostActiveDirectory struct { + DynamicData + + ChangeOperation string `xml:"changeOperation"` + Spec *HostActiveDirectorySpec `xml:"spec,omitempty"` +} + +func init() { + t["HostActiveDirectory"] = reflect.TypeOf((*HostActiveDirectory)(nil)).Elem() +} + +type HostActiveDirectoryInfo struct { + HostDirectoryStoreInfo + + JoinedDomain string `xml:"joinedDomain,omitempty"` + TrustedDomain []string `xml:"trustedDomain,omitempty"` + DomainMembershipStatus string `xml:"domainMembershipStatus,omitempty"` + SmartCardAuthenticationEnabled *bool `xml:"smartCardAuthenticationEnabled"` +} + +func init() { + t["HostActiveDirectoryInfo"] = reflect.TypeOf((*HostActiveDirectoryInfo)(nil)).Elem() +} + +type HostActiveDirectorySpec struct { + DynamicData + + DomainName string `xml:"domainName,omitempty"` + UserName string `xml:"userName,omitempty"` + Password string `xml:"password,omitempty"` + CamServer string `xml:"camServer,omitempty"` + Thumbprint string `xml:"thumbprint,omitempty"` + SmartCardAuthenticationEnabled *bool `xml:"smartCardAuthenticationEnabled"` + SmartCardTrustAnchors []string `xml:"smartCardTrustAnchors,omitempty"` +} + +func init() { + t["HostActiveDirectorySpec"] = reflect.TypeOf((*HostActiveDirectorySpec)(nil)).Elem() +} + +type HostAddFailedEvent struct { + HostEvent + + Hostname string `xml:"hostname"` +} + +func init() { + t["HostAddFailedEvent"] = reflect.TypeOf((*HostAddFailedEvent)(nil)).Elem() +} + +type HostAddedEvent struct { + HostEvent +} + +func init() { + t["HostAddedEvent"] = reflect.TypeOf((*HostAddedEvent)(nil)).Elem() +} + +type HostAdminDisableEvent struct { + HostEvent +} + +func init() { + t["HostAdminDisableEvent"] = reflect.TypeOf((*HostAdminDisableEvent)(nil)).Elem() +} + +type HostAdminEnableEvent struct { + HostEvent +} + +func init() { + t["HostAdminEnableEvent"] = reflect.TypeOf((*HostAdminEnableEvent)(nil)).Elem() +} + +type HostApplyProfile struct { + ApplyProfile + + Memory *HostMemoryProfile `xml:"memory,omitempty"` + Storage *StorageProfile `xml:"storage,omitempty"` + Network *NetworkProfile `xml:"network,omitempty"` + Datetime *DateTimeProfile `xml:"datetime,omitempty"` + Firewall *FirewallProfile `xml:"firewall,omitempty"` + Security *SecurityProfile `xml:"security,omitempty"` + Service []ServiceProfile `xml:"service,omitempty"` + Option []OptionProfile `xml:"option,omitempty"` + UserAccount []UserProfile `xml:"userAccount,omitempty"` + UsergroupAccount []UserGroupProfile `xml:"usergroupAccount,omitempty"` + Authentication *AuthenticationProfile `xml:"authentication,omitempty"` +} + +func init() { + t["HostApplyProfile"] = reflect.TypeOf((*HostApplyProfile)(nil)).Elem() +} + +type HostAuthenticationManagerInfo struct { + DynamicData + + AuthConfig []BaseHostAuthenticationStoreInfo `xml:"authConfig,typeattr"` +} + +func init() { + t["HostAuthenticationManagerInfo"] = reflect.TypeOf((*HostAuthenticationManagerInfo)(nil)).Elem() +} + +type HostAuthenticationStoreInfo struct { + DynamicData + + Enabled bool `xml:"enabled"` +} + +func init() { + t["HostAuthenticationStoreInfo"] = reflect.TypeOf((*HostAuthenticationStoreInfo)(nil)).Elem() +} + +type HostAutoStartManagerConfig struct { + DynamicData + + Defaults *AutoStartDefaults `xml:"defaults,omitempty"` + PowerInfo []AutoStartPowerInfo `xml:"powerInfo,omitempty"` +} + +func init() { + t["HostAutoStartManagerConfig"] = reflect.TypeOf((*HostAutoStartManagerConfig)(nil)).Elem() +} + +type HostBIOSInfo struct { + DynamicData + + BiosVersion string `xml:"biosVersion,omitempty"` + ReleaseDate *time.Time `xml:"releaseDate"` +} + +func init() { + t["HostBIOSInfo"] = reflect.TypeOf((*HostBIOSInfo)(nil)).Elem() +} + +type HostBlockAdapterTargetTransport struct { + HostTargetTransport +} + +func init() { + t["HostBlockAdapterTargetTransport"] = reflect.TypeOf((*HostBlockAdapterTargetTransport)(nil)).Elem() +} + +type HostBlockHba struct { + HostHostBusAdapter +} + +func init() { + t["HostBlockHba"] = reflect.TypeOf((*HostBlockHba)(nil)).Elem() +} + +type HostBootDevice struct { + DynamicData + + Key string `xml:"key"` + Description string `xml:"description"` +} + +func init() { + t["HostBootDevice"] = reflect.TypeOf((*HostBootDevice)(nil)).Elem() +} + +type HostBootDeviceInfo struct { + DynamicData + + BootDevices []HostBootDevice `xml:"bootDevices,omitempty"` + CurrentBootDeviceKey string `xml:"currentBootDeviceKey,omitempty"` +} + +func init() { + t["HostBootDeviceInfo"] = reflect.TypeOf((*HostBootDeviceInfo)(nil)).Elem() +} + +type HostCacheConfigurationInfo struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + SwapSize int64 `xml:"swapSize"` +} + +func init() { + t["HostCacheConfigurationInfo"] = reflect.TypeOf((*HostCacheConfigurationInfo)(nil)).Elem() +} + +type HostCacheConfigurationSpec struct { + DynamicData + + Datastore ManagedObjectReference `xml:"datastore"` + SwapSize int64 `xml:"swapSize"` +} + +func init() { + t["HostCacheConfigurationSpec"] = reflect.TypeOf((*HostCacheConfigurationSpec)(nil)).Elem() +} + +type HostCapability struct { + DynamicData + + RecursiveResourcePoolsSupported bool `xml:"recursiveResourcePoolsSupported"` + CpuMemoryResourceConfigurationSupported bool `xml:"cpuMemoryResourceConfigurationSupported"` + RebootSupported bool `xml:"rebootSupported"` + ShutdownSupported bool `xml:"shutdownSupported"` + VmotionSupported bool `xml:"vmotionSupported"` + StandbySupported bool `xml:"standbySupported"` + IpmiSupported *bool `xml:"ipmiSupported"` + MaxSupportedVMs int32 `xml:"maxSupportedVMs,omitempty"` + MaxRunningVMs int32 `xml:"maxRunningVMs,omitempty"` + MaxSupportedVcpus int32 `xml:"maxSupportedVcpus,omitempty"` + MaxRegisteredVMs int32 `xml:"maxRegisteredVMs,omitempty"` + DatastorePrincipalSupported bool `xml:"datastorePrincipalSupported"` + SanSupported bool `xml:"sanSupported"` + NfsSupported bool `xml:"nfsSupported"` + IscsiSupported bool `xml:"iscsiSupported"` + VlanTaggingSupported bool `xml:"vlanTaggingSupported"` + NicTeamingSupported bool `xml:"nicTeamingSupported"` + HighGuestMemSupported bool `xml:"highGuestMemSupported"` + MaintenanceModeSupported bool `xml:"maintenanceModeSupported"` + SuspendedRelocateSupported bool `xml:"suspendedRelocateSupported"` + RestrictedSnapshotRelocateSupported bool `xml:"restrictedSnapshotRelocateSupported"` + PerVmSwapFiles bool `xml:"perVmSwapFiles"` + LocalSwapDatastoreSupported bool `xml:"localSwapDatastoreSupported"` + UnsharedSwapVMotionSupported bool `xml:"unsharedSwapVMotionSupported"` + BackgroundSnapshotsSupported bool `xml:"backgroundSnapshotsSupported"` + PreAssignedPCIUnitNumbersSupported bool `xml:"preAssignedPCIUnitNumbersSupported"` + ScreenshotSupported bool `xml:"screenshotSupported"` + ScaledScreenshotSupported bool `xml:"scaledScreenshotSupported"` + StorageVMotionSupported *bool `xml:"storageVMotionSupported"` + VmotionWithStorageVMotionSupported *bool `xml:"vmotionWithStorageVMotionSupported"` + VmotionAcrossNetworkSupported *bool `xml:"vmotionAcrossNetworkSupported"` + MaxNumDisksSVMotion int32 `xml:"maxNumDisksSVMotion,omitempty"` + HbrNicSelectionSupported *bool `xml:"hbrNicSelectionSupported"` + VrNfcNicSelectionSupported *bool `xml:"vrNfcNicSelectionSupported"` + RecordReplaySupported *bool `xml:"recordReplaySupported"` + FtSupported *bool `xml:"ftSupported"` + ReplayUnsupportedReason string `xml:"replayUnsupportedReason,omitempty"` + ReplayCompatibilityIssues []string `xml:"replayCompatibilityIssues,omitempty"` + SmpFtSupported *bool `xml:"smpFtSupported"` + FtCompatibilityIssues []string `xml:"ftCompatibilityIssues,omitempty"` + SmpFtCompatibilityIssues []string `xml:"smpFtCompatibilityIssues,omitempty"` + MaxVcpusPerFtVm int32 `xml:"maxVcpusPerFtVm,omitempty"` + LoginBySSLThumbprintSupported *bool `xml:"loginBySSLThumbprintSupported"` + CloneFromSnapshotSupported *bool `xml:"cloneFromSnapshotSupported"` + DeltaDiskBackingsSupported *bool `xml:"deltaDiskBackingsSupported"` + PerVMNetworkTrafficShapingSupported *bool `xml:"perVMNetworkTrafficShapingSupported"` + TpmSupported *bool `xml:"tpmSupported"` + SupportedCpuFeature []HostCpuIdInfo `xml:"supportedCpuFeature,omitempty"` + VirtualExecUsageSupported *bool `xml:"virtualExecUsageSupported"` + StorageIORMSupported *bool `xml:"storageIORMSupported"` + VmDirectPathGen2Supported *bool `xml:"vmDirectPathGen2Supported"` + VmDirectPathGen2UnsupportedReason []string `xml:"vmDirectPathGen2UnsupportedReason,omitempty"` + VmDirectPathGen2UnsupportedReasonExtended string `xml:"vmDirectPathGen2UnsupportedReasonExtended,omitempty"` + SupportedVmfsMajorVersion []int32 `xml:"supportedVmfsMajorVersion,omitempty"` + VStorageCapable *bool `xml:"vStorageCapable"` + SnapshotRelayoutSupported *bool `xml:"snapshotRelayoutSupported"` + FirewallIpRulesSupported *bool `xml:"firewallIpRulesSupported"` + ServicePackageInfoSupported *bool `xml:"servicePackageInfoSupported"` + MaxHostRunningVms int32 `xml:"maxHostRunningVms,omitempty"` + MaxHostSupportedVcpus int32 `xml:"maxHostSupportedVcpus,omitempty"` + VmfsDatastoreMountCapable *bool `xml:"vmfsDatastoreMountCapable"` + EightPlusHostVmfsSharedAccessSupported *bool `xml:"eightPlusHostVmfsSharedAccessSupported"` + NestedHVSupported *bool `xml:"nestedHVSupported"` + VPMCSupported *bool `xml:"vPMCSupported"` + InterVMCommunicationThroughVMCISupported *bool `xml:"interVMCommunicationThroughVMCISupported"` + ScheduledHardwareUpgradeSupported *bool `xml:"scheduledHardwareUpgradeSupported"` + FeatureCapabilitiesSupported *bool `xml:"featureCapabilitiesSupported"` + LatencySensitivitySupported *bool `xml:"latencySensitivitySupported"` + StoragePolicySupported *bool `xml:"storagePolicySupported"` + Accel3dSupported *bool `xml:"accel3dSupported"` + ReliableMemoryAware *bool `xml:"reliableMemoryAware"` + MultipleNetworkStackInstanceSupported *bool `xml:"multipleNetworkStackInstanceSupported"` + MessageBusProxySupported *bool `xml:"messageBusProxySupported"` + VsanSupported *bool `xml:"vsanSupported"` + VFlashSupported *bool `xml:"vFlashSupported"` + HostAccessManagerSupported *bool `xml:"hostAccessManagerSupported"` + ProvisioningNicSelectionSupported *bool `xml:"provisioningNicSelectionSupported"` + Nfs41Supported *bool `xml:"nfs41Supported"` + TurnDiskLocatorLedSupported *bool `xml:"turnDiskLocatorLedSupported"` + VirtualVolumeDatastoreSupported *bool `xml:"virtualVolumeDatastoreSupported"` + MarkAsSsdSupported *bool `xml:"markAsSsdSupported"` + MarkAsLocalSupported *bool `xml:"markAsLocalSupported"` + SmartCardAuthenticationSupported *bool `xml:"smartCardAuthenticationSupported"` +} + +func init() { + t["HostCapability"] = reflect.TypeOf((*HostCapability)(nil)).Elem() +} + +type HostCertificateManagerCertificateInfo struct { + DynamicData + + Issuer string `xml:"issuer,omitempty"` + NotBefore *time.Time `xml:"notBefore"` + NotAfter *time.Time `xml:"notAfter"` + Subject string `xml:"subject,omitempty"` + Status string `xml:"status"` +} + +func init() { + t["HostCertificateManagerCertificateInfo"] = reflect.TypeOf((*HostCertificateManagerCertificateInfo)(nil)).Elem() +} + +type HostCnxFailedAccountFailedEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedAccountFailedEvent"] = reflect.TypeOf((*HostCnxFailedAccountFailedEvent)(nil)).Elem() +} + +type HostCnxFailedAlreadyManagedEvent struct { + HostEvent + + ServerName string `xml:"serverName"` +} + +func init() { + t["HostCnxFailedAlreadyManagedEvent"] = reflect.TypeOf((*HostCnxFailedAlreadyManagedEvent)(nil)).Elem() +} + +type HostCnxFailedBadCcagentEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedBadCcagentEvent"] = reflect.TypeOf((*HostCnxFailedBadCcagentEvent)(nil)).Elem() +} + +type HostCnxFailedBadUsernameEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedBadUsernameEvent"] = reflect.TypeOf((*HostCnxFailedBadUsernameEvent)(nil)).Elem() +} + +type HostCnxFailedBadVersionEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedBadVersionEvent"] = reflect.TypeOf((*HostCnxFailedBadVersionEvent)(nil)).Elem() +} + +type HostCnxFailedCcagentUpgradeEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedCcagentUpgradeEvent"] = reflect.TypeOf((*HostCnxFailedCcagentUpgradeEvent)(nil)).Elem() +} + +type HostCnxFailedEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedEvent"] = reflect.TypeOf((*HostCnxFailedEvent)(nil)).Elem() +} + +type HostCnxFailedNetworkErrorEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedNetworkErrorEvent"] = reflect.TypeOf((*HostCnxFailedNetworkErrorEvent)(nil)).Elem() +} + +type HostCnxFailedNoAccessEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedNoAccessEvent"] = reflect.TypeOf((*HostCnxFailedNoAccessEvent)(nil)).Elem() +} + +type HostCnxFailedNoConnectionEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedNoConnectionEvent"] = reflect.TypeOf((*HostCnxFailedNoConnectionEvent)(nil)).Elem() +} + +type HostCnxFailedNoLicenseEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedNoLicenseEvent"] = reflect.TypeOf((*HostCnxFailedNoLicenseEvent)(nil)).Elem() +} + +type HostCnxFailedNotFoundEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedNotFoundEvent"] = reflect.TypeOf((*HostCnxFailedNotFoundEvent)(nil)).Elem() +} + +type HostCnxFailedTimeoutEvent struct { + HostEvent +} + +func init() { + t["HostCnxFailedTimeoutEvent"] = reflect.TypeOf((*HostCnxFailedTimeoutEvent)(nil)).Elem() +} + +type HostCommunication struct { + RuntimeFault +} + +func init() { + t["HostCommunication"] = reflect.TypeOf((*HostCommunication)(nil)).Elem() +} + +type HostCommunicationFault BaseHostCommunication + +func init() { + t["HostCommunicationFault"] = reflect.TypeOf((*HostCommunicationFault)(nil)).Elem() +} + +type HostComplianceCheckedEvent struct { + HostEvent + + Profile ProfileEventArgument `xml:"profile"` +} + +func init() { + t["HostComplianceCheckedEvent"] = reflect.TypeOf((*HostComplianceCheckedEvent)(nil)).Elem() +} + +type HostCompliantEvent struct { + HostEvent +} + +func init() { + t["HostCompliantEvent"] = reflect.TypeOf((*HostCompliantEvent)(nil)).Elem() +} + +type HostConfigAppliedEvent struct { + HostEvent +} + +func init() { + t["HostConfigAppliedEvent"] = reflect.TypeOf((*HostConfigAppliedEvent)(nil)).Elem() +} + +type HostConfigChange struct { + DynamicData +} + +func init() { + t["HostConfigChange"] = reflect.TypeOf((*HostConfigChange)(nil)).Elem() +} + +type HostConfigFailed struct { + HostConfigFault + + Failure []LocalizedMethodFault `xml:"failure"` +} + +func init() { + t["HostConfigFailed"] = reflect.TypeOf((*HostConfigFailed)(nil)).Elem() +} + +type HostConfigFailedFault HostConfigFailed + +func init() { + t["HostConfigFailedFault"] = reflect.TypeOf((*HostConfigFailedFault)(nil)).Elem() +} + +type HostConfigFault struct { + VimFault +} + +func init() { + t["HostConfigFault"] = reflect.TypeOf((*HostConfigFault)(nil)).Elem() +} + +type HostConfigFaultFault BaseHostConfigFault + +func init() { + t["HostConfigFaultFault"] = reflect.TypeOf((*HostConfigFaultFault)(nil)).Elem() +} + +type HostConfigInfo struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Product AboutInfo `xml:"product"` + HyperThread *HostHyperThreadScheduleInfo `xml:"hyperThread,omitempty"` + ConsoleReservation *ServiceConsoleReservationInfo `xml:"consoleReservation,omitempty"` + VirtualMachineReservation *VirtualMachineMemoryReservationInfo `xml:"virtualMachineReservation,omitempty"` + StorageDevice *HostStorageDeviceInfo `xml:"storageDevice,omitempty"` + MultipathState *HostMultipathStateInfo `xml:"multipathState,omitempty"` + FileSystemVolume *HostFileSystemVolumeInfo `xml:"fileSystemVolume,omitempty"` + SystemFile []string `xml:"systemFile,omitempty"` + Network *HostNetworkInfo `xml:"network,omitempty"` + Vmotion *HostVMotionInfo `xml:"vmotion,omitempty"` + VirtualNicManagerInfo *HostVirtualNicManagerInfo `xml:"virtualNicManagerInfo,omitempty"` + Capabilities *HostNetCapabilities `xml:"capabilities,omitempty"` + DatastoreCapabilities *HostDatastoreSystemCapabilities `xml:"datastoreCapabilities,omitempty"` + OffloadCapabilities *HostNetOffloadCapabilities `xml:"offloadCapabilities,omitempty"` + Service *HostServiceInfo `xml:"service,omitempty"` + Firewall *HostFirewallInfo `xml:"firewall,omitempty"` + AutoStart *HostAutoStartManagerConfig `xml:"autoStart,omitempty"` + ActiveDiagnosticPartition *HostDiagnosticPartition `xml:"activeDiagnosticPartition,omitempty"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` + OptionDef []OptionDef `xml:"optionDef,omitempty"` + DatastorePrincipal string `xml:"datastorePrincipal,omitempty"` + LocalSwapDatastore *ManagedObjectReference `xml:"localSwapDatastore,omitempty"` + SystemSwapConfiguration *HostSystemSwapConfiguration `xml:"systemSwapConfiguration,omitempty"` + SystemResources *HostSystemResourceInfo `xml:"systemResources,omitempty"` + DateTimeInfo *HostDateTimeInfo `xml:"dateTimeInfo,omitempty"` + Flags *HostFlagInfo `xml:"flags,omitempty"` + AdminDisabled *bool `xml:"adminDisabled"` + LockdownMode HostLockdownMode `xml:"lockdownMode,omitempty"` + Ipmi *HostIpmiInfo `xml:"ipmi,omitempty"` + SslThumbprintInfo *HostSslThumbprintInfo `xml:"sslThumbprintInfo,omitempty"` + SslThumbprintData []HostSslThumbprintInfo `xml:"sslThumbprintData,omitempty"` + Certificate []byte `xml:"certificate,omitempty"` + PciPassthruInfo []BaseHostPciPassthruInfo `xml:"pciPassthruInfo,omitempty,typeattr"` + AuthenticationManagerInfo *HostAuthenticationManagerInfo `xml:"authenticationManagerInfo,omitempty"` + FeatureVersion []HostFeatureVersionInfo `xml:"featureVersion,omitempty"` + PowerSystemCapability *PowerSystemCapability `xml:"powerSystemCapability,omitempty"` + PowerSystemInfo *PowerSystemInfo `xml:"powerSystemInfo,omitempty"` + CacheConfigurationInfo []HostCacheConfigurationInfo `xml:"cacheConfigurationInfo,omitempty"` + WakeOnLanCapable *bool `xml:"wakeOnLanCapable"` + FeatureCapability []HostFeatureCapability `xml:"featureCapability,omitempty"` + MaskedFeatureCapability []HostFeatureCapability `xml:"maskedFeatureCapability,omitempty"` + VFlashConfigInfo *HostVFlashManagerVFlashConfigInfo `xml:"vFlashConfigInfo,omitempty"` + VsanHostConfig *VsanHostConfigInfo `xml:"vsanHostConfig,omitempty"` + DomainList []string `xml:"domainList,omitempty"` + ScriptCheckSum []byte `xml:"scriptCheckSum,omitempty"` + HostConfigCheckSum []byte `xml:"hostConfigCheckSum,omitempty"` + GraphicsInfo []HostGraphicsInfo `xml:"graphicsInfo,omitempty"` + SharedPassthruGpuTypes []string `xml:"sharedPassthruGpuTypes,omitempty"` + IoFilterInfo []HostIoFilterInfo `xml:"ioFilterInfo,omitempty"` +} + +func init() { + t["HostConfigInfo"] = reflect.TypeOf((*HostConfigInfo)(nil)).Elem() +} + +type HostConfigManager struct { + DynamicData + + CpuScheduler *ManagedObjectReference `xml:"cpuScheduler,omitempty"` + DatastoreSystem *ManagedObjectReference `xml:"datastoreSystem,omitempty"` + MemoryManager *ManagedObjectReference `xml:"memoryManager,omitempty"` + StorageSystem *ManagedObjectReference `xml:"storageSystem,omitempty"` + NetworkSystem *ManagedObjectReference `xml:"networkSystem,omitempty"` + VmotionSystem *ManagedObjectReference `xml:"vmotionSystem,omitempty"` + VirtualNicManager *ManagedObjectReference `xml:"virtualNicManager,omitempty"` + ServiceSystem *ManagedObjectReference `xml:"serviceSystem,omitempty"` + FirewallSystem *ManagedObjectReference `xml:"firewallSystem,omitempty"` + AdvancedOption *ManagedObjectReference `xml:"advancedOption,omitempty"` + DiagnosticSystem *ManagedObjectReference `xml:"diagnosticSystem,omitempty"` + AutoStartManager *ManagedObjectReference `xml:"autoStartManager,omitempty"` + SnmpSystem *ManagedObjectReference `xml:"snmpSystem,omitempty"` + DateTimeSystem *ManagedObjectReference `xml:"dateTimeSystem,omitempty"` + PatchManager *ManagedObjectReference `xml:"patchManager,omitempty"` + ImageConfigManager *ManagedObjectReference `xml:"imageConfigManager,omitempty"` + BootDeviceSystem *ManagedObjectReference `xml:"bootDeviceSystem,omitempty"` + FirmwareSystem *ManagedObjectReference `xml:"firmwareSystem,omitempty"` + HealthStatusSystem *ManagedObjectReference `xml:"healthStatusSystem,omitempty"` + PciPassthruSystem *ManagedObjectReference `xml:"pciPassthruSystem,omitempty"` + LicenseManager *ManagedObjectReference `xml:"licenseManager,omitempty"` + KernelModuleSystem *ManagedObjectReference `xml:"kernelModuleSystem,omitempty"` + AuthenticationManager *ManagedObjectReference `xml:"authenticationManager,omitempty"` + PowerSystem *ManagedObjectReference `xml:"powerSystem,omitempty"` + CacheConfigurationManager *ManagedObjectReference `xml:"cacheConfigurationManager,omitempty"` + EsxAgentHostManager *ManagedObjectReference `xml:"esxAgentHostManager,omitempty"` + IscsiManager *ManagedObjectReference `xml:"iscsiManager,omitempty"` + VFlashManager *ManagedObjectReference `xml:"vFlashManager,omitempty"` + VsanSystem *ManagedObjectReference `xml:"vsanSystem,omitempty"` + MessageBusProxy *ManagedObjectReference `xml:"messageBusProxy,omitempty"` + UserDirectory *ManagedObjectReference `xml:"userDirectory,omitempty"` + AccountManager *ManagedObjectReference `xml:"accountManager,omitempty"` + HostAccessManager *ManagedObjectReference `xml:"hostAccessManager,omitempty"` + GraphicsManager *ManagedObjectReference `xml:"graphicsManager,omitempty"` + VsanInternalSystem *ManagedObjectReference `xml:"vsanInternalSystem,omitempty"` + CertificateManager *ManagedObjectReference `xml:"certificateManager,omitempty"` +} + +func init() { + t["HostConfigManager"] = reflect.TypeOf((*HostConfigManager)(nil)).Elem() +} + +type HostConfigSpec struct { + DynamicData + + NasDatastore []HostNasVolumeConfig `xml:"nasDatastore,omitempty"` + Network *HostNetworkConfig `xml:"network,omitempty"` + NicTypeSelection []HostVirtualNicManagerNicTypeSelection `xml:"nicTypeSelection,omitempty"` + Service []HostServiceConfig `xml:"service,omitempty"` + Firewall *HostFirewallConfig `xml:"firewall,omitempty"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` + DatastorePrincipal string `xml:"datastorePrincipal,omitempty"` + DatastorePrincipalPasswd string `xml:"datastorePrincipalPasswd,omitempty"` + Datetime *HostDateTimeConfig `xml:"datetime,omitempty"` + StorageDevice *HostStorageDeviceInfo `xml:"storageDevice,omitempty"` + License *HostLicenseSpec `xml:"license,omitempty"` + Security *HostSecuritySpec `xml:"security,omitempty"` + UserAccount []BaseHostAccountSpec `xml:"userAccount,omitempty,typeattr"` + UsergroupAccount []BaseHostAccountSpec `xml:"usergroupAccount,omitempty,typeattr"` + Memory *HostMemorySpec `xml:"memory,omitempty"` + ActiveDirectory []HostActiveDirectory `xml:"activeDirectory,omitempty"` + GenericConfig []KeyAnyValue `xml:"genericConfig,omitempty"` +} + +func init() { + t["HostConfigSpec"] = reflect.TypeOf((*HostConfigSpec)(nil)).Elem() +} + +type HostConfigSummary struct { + DynamicData + + Name string `xml:"name"` + Port int32 `xml:"port"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` + Product *AboutInfo `xml:"product,omitempty"` + VmotionEnabled bool `xml:"vmotionEnabled"` + FaultToleranceEnabled *bool `xml:"faultToleranceEnabled"` + FeatureVersion []HostFeatureVersionInfo `xml:"featureVersion,omitempty"` + AgentVmDatastore *ManagedObjectReference `xml:"agentVmDatastore,omitempty"` + AgentVmNetwork *ManagedObjectReference `xml:"agentVmNetwork,omitempty"` +} + +func init() { + t["HostConfigSummary"] = reflect.TypeOf((*HostConfigSummary)(nil)).Elem() +} + +type HostConfigVFlashCache HostConfigVFlashCacheRequestType + +func init() { + t["HostConfigVFlashCache"] = reflect.TypeOf((*HostConfigVFlashCache)(nil)).Elem() +} + +type HostConfigVFlashCacheRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostVFlashManagerVFlashCacheConfigSpec `xml:"spec"` +} + +func init() { + t["HostConfigVFlashCacheRequestType"] = reflect.TypeOf((*HostConfigVFlashCacheRequestType)(nil)).Elem() +} + +type HostConfigVFlashCacheResponse struct { +} + +type HostConfigureVFlashResource HostConfigureVFlashResourceRequestType + +func init() { + t["HostConfigureVFlashResource"] = reflect.TypeOf((*HostConfigureVFlashResource)(nil)).Elem() +} + +type HostConfigureVFlashResourceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostVFlashManagerVFlashResourceConfigSpec `xml:"spec"` +} + +func init() { + t["HostConfigureVFlashResourceRequestType"] = reflect.TypeOf((*HostConfigureVFlashResourceRequestType)(nil)).Elem() +} + +type HostConfigureVFlashResourceResponse struct { +} + +type HostConnectFault struct { + VimFault +} + +func init() { + t["HostConnectFault"] = reflect.TypeOf((*HostConnectFault)(nil)).Elem() +} + +type HostConnectFaultFault BaseHostConnectFault + +func init() { + t["HostConnectFaultFault"] = reflect.TypeOf((*HostConnectFaultFault)(nil)).Elem() +} + +type HostConnectInfo struct { + DynamicData + + ServerIp string `xml:"serverIp,omitempty"` + InDasCluster *bool `xml:"inDasCluster"` + Host HostListSummary `xml:"host"` + Vm []VirtualMachineSummary `xml:"vm,omitempty"` + VimAccountNameRequired *bool `xml:"vimAccountNameRequired"` + ClusterSupported *bool `xml:"clusterSupported"` + Network []BaseHostConnectInfoNetworkInfo `xml:"network,omitempty,typeattr"` + Datastore []BaseHostDatastoreConnectInfo `xml:"datastore,omitempty,typeattr"` + License *HostLicenseConnectInfo `xml:"license,omitempty"` + Capability *HostCapability `xml:"capability,omitempty"` +} + +func init() { + t["HostConnectInfo"] = reflect.TypeOf((*HostConnectInfo)(nil)).Elem() +} + +type HostConnectInfoNetworkInfo struct { + DynamicData + + Summary BaseNetworkSummary `xml:"summary,typeattr"` +} + +func init() { + t["HostConnectInfoNetworkInfo"] = reflect.TypeOf((*HostConnectInfoNetworkInfo)(nil)).Elem() +} + +type HostConnectSpec struct { + DynamicData + + HostName string `xml:"hostName,omitempty"` + Port int32 `xml:"port,omitempty"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` + UserName string `xml:"userName,omitempty"` + Password string `xml:"password,omitempty"` + VmFolder *ManagedObjectReference `xml:"vmFolder,omitempty"` + Force bool `xml:"force"` + VimAccountName string `xml:"vimAccountName,omitempty"` + VimAccountPassword string `xml:"vimAccountPassword,omitempty"` + ManagementIp string `xml:"managementIp,omitempty"` + LockdownMode HostLockdownMode `xml:"lockdownMode,omitempty"` + HostGateway *HostGatewaySpec `xml:"hostGateway,omitempty"` +} + +func init() { + t["HostConnectSpec"] = reflect.TypeOf((*HostConnectSpec)(nil)).Elem() +} + +type HostConnectedEvent struct { + HostEvent +} + +func init() { + t["HostConnectedEvent"] = reflect.TypeOf((*HostConnectedEvent)(nil)).Elem() +} + +type HostConnectionLostEvent struct { + HostEvent +} + +func init() { + t["HostConnectionLostEvent"] = reflect.TypeOf((*HostConnectionLostEvent)(nil)).Elem() +} + +type HostCpuIdInfo struct { + DynamicData + + Level int32 `xml:"level"` + Vendor string `xml:"vendor,omitempty"` + Eax string `xml:"eax,omitempty"` + Ebx string `xml:"ebx,omitempty"` + Ecx string `xml:"ecx,omitempty"` + Edx string `xml:"edx,omitempty"` +} + +func init() { + t["HostCpuIdInfo"] = reflect.TypeOf((*HostCpuIdInfo)(nil)).Elem() +} + +type HostCpuInfo struct { + DynamicData + + NumCpuPackages int16 `xml:"numCpuPackages"` + NumCpuCores int16 `xml:"numCpuCores"` + NumCpuThreads int16 `xml:"numCpuThreads"` + Hz int64 `xml:"hz"` +} + +func init() { + t["HostCpuInfo"] = reflect.TypeOf((*HostCpuInfo)(nil)).Elem() +} + +type HostCpuPackage struct { + DynamicData + + Index int16 `xml:"index"` + Vendor string `xml:"vendor"` + Hz int64 `xml:"hz"` + BusHz int64 `xml:"busHz"` + Description string `xml:"description"` + ThreadId []int16 `xml:"threadId"` + CpuFeature []HostCpuIdInfo `xml:"cpuFeature,omitempty"` +} + +func init() { + t["HostCpuPackage"] = reflect.TypeOf((*HostCpuPackage)(nil)).Elem() +} + +type HostCpuPowerManagementInfo struct { + DynamicData + + CurrentPolicy string `xml:"currentPolicy,omitempty"` + HardwareSupport string `xml:"hardwareSupport,omitempty"` +} + +func init() { + t["HostCpuPowerManagementInfo"] = reflect.TypeOf((*HostCpuPowerManagementInfo)(nil)).Elem() +} + +type HostDasDisabledEvent struct { + HostEvent +} + +func init() { + t["HostDasDisabledEvent"] = reflect.TypeOf((*HostDasDisabledEvent)(nil)).Elem() +} + +type HostDasDisablingEvent struct { + HostEvent +} + +func init() { + t["HostDasDisablingEvent"] = reflect.TypeOf((*HostDasDisablingEvent)(nil)).Elem() +} + +type HostDasEnabledEvent struct { + HostEvent +} + +func init() { + t["HostDasEnabledEvent"] = reflect.TypeOf((*HostDasEnabledEvent)(nil)).Elem() +} + +type HostDasEnablingEvent struct { + HostEvent +} + +func init() { + t["HostDasEnablingEvent"] = reflect.TypeOf((*HostDasEnablingEvent)(nil)).Elem() +} + +type HostDasErrorEvent struct { + HostEvent + + Message string `xml:"message,omitempty"` + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["HostDasErrorEvent"] = reflect.TypeOf((*HostDasErrorEvent)(nil)).Elem() +} + +type HostDasEvent struct { + HostEvent +} + +func init() { + t["HostDasEvent"] = reflect.TypeOf((*HostDasEvent)(nil)).Elem() +} + +type HostDasOkEvent struct { + HostEvent +} + +func init() { + t["HostDasOkEvent"] = reflect.TypeOf((*HostDasOkEvent)(nil)).Elem() +} + +type HostDatastoreBrowserSearchResults struct { + DynamicData + + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` + FolderPath string `xml:"folderPath,omitempty"` + File []BaseFileInfo `xml:"file,omitempty,typeattr"` +} + +func init() { + t["HostDatastoreBrowserSearchResults"] = reflect.TypeOf((*HostDatastoreBrowserSearchResults)(nil)).Elem() +} + +type HostDatastoreBrowserSearchSpec struct { + DynamicData + + Query []BaseFileQuery `xml:"query,omitempty,typeattr"` + Details *FileQueryFlags `xml:"details,omitempty"` + SearchCaseInsensitive *bool `xml:"searchCaseInsensitive"` + MatchPattern []string `xml:"matchPattern,omitempty"` + SortFoldersFirst *bool `xml:"sortFoldersFirst"` +} + +func init() { + t["HostDatastoreBrowserSearchSpec"] = reflect.TypeOf((*HostDatastoreBrowserSearchSpec)(nil)).Elem() +} + +type HostDatastoreConnectInfo struct { + DynamicData + + Summary DatastoreSummary `xml:"summary"` +} + +func init() { + t["HostDatastoreConnectInfo"] = reflect.TypeOf((*HostDatastoreConnectInfo)(nil)).Elem() +} + +type HostDatastoreExistsConnectInfo struct { + HostDatastoreConnectInfo + + NewDatastoreName string `xml:"newDatastoreName"` +} + +func init() { + t["HostDatastoreExistsConnectInfo"] = reflect.TypeOf((*HostDatastoreExistsConnectInfo)(nil)).Elem() +} + +type HostDatastoreNameConflictConnectInfo struct { + HostDatastoreConnectInfo + + NewDatastoreName string `xml:"newDatastoreName"` +} + +func init() { + t["HostDatastoreNameConflictConnectInfo"] = reflect.TypeOf((*HostDatastoreNameConflictConnectInfo)(nil)).Elem() +} + +type HostDatastoreSystemCapabilities struct { + DynamicData + + NfsMountCreationRequired bool `xml:"nfsMountCreationRequired"` + NfsMountCreationSupported bool `xml:"nfsMountCreationSupported"` + LocalDatastoreSupported bool `xml:"localDatastoreSupported"` + VmfsExtentExpansionSupported *bool `xml:"vmfsExtentExpansionSupported"` +} + +func init() { + t["HostDatastoreSystemCapabilities"] = reflect.TypeOf((*HostDatastoreSystemCapabilities)(nil)).Elem() +} + +type HostDatastoreSystemDatastoreResult struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HostDatastoreSystemDatastoreResult"] = reflect.TypeOf((*HostDatastoreSystemDatastoreResult)(nil)).Elem() +} + +type HostDatastoreSystemVvolDatastoreSpec struct { + DynamicData + + Name string `xml:"name"` + ScId string `xml:"scId"` +} + +func init() { + t["HostDatastoreSystemVvolDatastoreSpec"] = reflect.TypeOf((*HostDatastoreSystemVvolDatastoreSpec)(nil)).Elem() +} + +type HostDateTimeConfig struct { + DynamicData + + TimeZone string `xml:"timeZone,omitempty"` + NtpConfig *HostNtpConfig `xml:"ntpConfig,omitempty"` +} + +func init() { + t["HostDateTimeConfig"] = reflect.TypeOf((*HostDateTimeConfig)(nil)).Elem() +} + +type HostDateTimeInfo struct { + DynamicData + + TimeZone HostDateTimeSystemTimeZone `xml:"timeZone"` + NtpConfig *HostNtpConfig `xml:"ntpConfig,omitempty"` +} + +func init() { + t["HostDateTimeInfo"] = reflect.TypeOf((*HostDateTimeInfo)(nil)).Elem() +} + +type HostDateTimeSystemTimeZone struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name"` + Description string `xml:"description"` + GmtOffset int32 `xml:"gmtOffset"` +} + +func init() { + t["HostDateTimeSystemTimeZone"] = reflect.TypeOf((*HostDateTimeSystemTimeZone)(nil)).Elem() +} + +type HostDevice struct { + DynamicData + + DeviceName string `xml:"deviceName"` + DeviceType string `xml:"deviceType"` +} + +func init() { + t["HostDevice"] = reflect.TypeOf((*HostDevice)(nil)).Elem() +} + +type HostDhcpService struct { + DynamicData + + Key string `xml:"key"` + Spec HostDhcpServiceSpec `xml:"spec"` +} + +func init() { + t["HostDhcpService"] = reflect.TypeOf((*HostDhcpService)(nil)).Elem() +} + +type HostDhcpServiceConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Key string `xml:"key"` + Spec HostDhcpServiceSpec `xml:"spec"` +} + +func init() { + t["HostDhcpServiceConfig"] = reflect.TypeOf((*HostDhcpServiceConfig)(nil)).Elem() +} + +type HostDhcpServiceSpec struct { + DynamicData + + VirtualSwitch string `xml:"virtualSwitch"` + DefaultLeaseDuration int32 `xml:"defaultLeaseDuration"` + LeaseBeginIp string `xml:"leaseBeginIp"` + LeaseEndIp string `xml:"leaseEndIp"` + MaxLeaseDuration int32 `xml:"maxLeaseDuration"` + UnlimitedLease bool `xml:"unlimitedLease"` + IpSubnetAddr string `xml:"ipSubnetAddr"` + IpSubnetMask string `xml:"ipSubnetMask"` +} + +func init() { + t["HostDhcpServiceSpec"] = reflect.TypeOf((*HostDhcpServiceSpec)(nil)).Elem() +} + +type HostDiagnosticPartition struct { + DynamicData + + StorageType string `xml:"storageType"` + DiagnosticType string `xml:"diagnosticType"` + Slots int32 `xml:"slots"` + Id HostScsiDiskPartition `xml:"id"` +} + +func init() { + t["HostDiagnosticPartition"] = reflect.TypeOf((*HostDiagnosticPartition)(nil)).Elem() +} + +type HostDiagnosticPartitionCreateDescription struct { + DynamicData + + Layout HostDiskPartitionLayout `xml:"layout"` + DiskUuid string `xml:"diskUuid"` + Spec HostDiagnosticPartitionCreateSpec `xml:"spec"` +} + +func init() { + t["HostDiagnosticPartitionCreateDescription"] = reflect.TypeOf((*HostDiagnosticPartitionCreateDescription)(nil)).Elem() +} + +type HostDiagnosticPartitionCreateOption struct { + DynamicData + + StorageType string `xml:"storageType"` + DiagnosticType string `xml:"diagnosticType"` + Disk HostScsiDisk `xml:"disk"` +} + +func init() { + t["HostDiagnosticPartitionCreateOption"] = reflect.TypeOf((*HostDiagnosticPartitionCreateOption)(nil)).Elem() +} + +type HostDiagnosticPartitionCreateSpec struct { + DynamicData + + StorageType string `xml:"storageType"` + DiagnosticType string `xml:"diagnosticType"` + Id HostScsiDiskPartition `xml:"id"` + Partition HostDiskPartitionSpec `xml:"partition"` + Active *bool `xml:"active"` +} + +func init() { + t["HostDiagnosticPartitionCreateSpec"] = reflect.TypeOf((*HostDiagnosticPartitionCreateSpec)(nil)).Elem() +} + +type HostDigestInfo struct { + DynamicData + + DigestMethod string `xml:"digestMethod"` + DigestValue []byte `xml:"digestValue"` + ObjectName string `xml:"objectName,omitempty"` +} + +func init() { + t["HostDigestInfo"] = reflect.TypeOf((*HostDigestInfo)(nil)).Elem() +} + +type HostDirectoryStoreInfo struct { + HostAuthenticationStoreInfo +} + +func init() { + t["HostDirectoryStoreInfo"] = reflect.TypeOf((*HostDirectoryStoreInfo)(nil)).Elem() +} + +type HostDisconnectedEvent struct { + HostEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["HostDisconnectedEvent"] = reflect.TypeOf((*HostDisconnectedEvent)(nil)).Elem() +} + +type HostDiskConfigurationResult struct { + DynamicData + + DevicePath string `xml:"devicePath,omitempty"` + Success *bool `xml:"success"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HostDiskConfigurationResult"] = reflect.TypeOf((*HostDiskConfigurationResult)(nil)).Elem() +} + +type HostDiskDimensions struct { + DynamicData +} + +func init() { + t["HostDiskDimensions"] = reflect.TypeOf((*HostDiskDimensions)(nil)).Elem() +} + +type HostDiskDimensionsChs struct { + DynamicData + + Cylinder int64 `xml:"cylinder"` + Head int32 `xml:"head"` + Sector int32 `xml:"sector"` +} + +func init() { + t["HostDiskDimensionsChs"] = reflect.TypeOf((*HostDiskDimensionsChs)(nil)).Elem() +} + +type HostDiskDimensionsLba struct { + DynamicData + + BlockSize int32 `xml:"blockSize"` + Block int64 `xml:"block"` +} + +func init() { + t["HostDiskDimensionsLba"] = reflect.TypeOf((*HostDiskDimensionsLba)(nil)).Elem() +} + +type HostDiskMappingInfo struct { + DynamicData + + PhysicalPartition *HostDiskMappingPartitionInfo `xml:"physicalPartition,omitempty"` + Name string `xml:"name"` + Exclusive *bool `xml:"exclusive"` +} + +func init() { + t["HostDiskMappingInfo"] = reflect.TypeOf((*HostDiskMappingInfo)(nil)).Elem() +} + +type HostDiskMappingOption struct { + DynamicData + + PhysicalPartition []HostDiskMappingPartitionOption `xml:"physicalPartition,omitempty"` + Name string `xml:"name"` +} + +func init() { + t["HostDiskMappingOption"] = reflect.TypeOf((*HostDiskMappingOption)(nil)).Elem() +} + +type HostDiskMappingPartitionInfo struct { + DynamicData + + Name string `xml:"name"` + FileSystem string `xml:"fileSystem"` + CapacityInKb int64 `xml:"capacityInKb"` +} + +func init() { + t["HostDiskMappingPartitionInfo"] = reflect.TypeOf((*HostDiskMappingPartitionInfo)(nil)).Elem() +} + +type HostDiskMappingPartitionOption struct { + DynamicData + + Name string `xml:"name"` + FileSystem string `xml:"fileSystem"` + CapacityInKb int64 `xml:"capacityInKb"` +} + +func init() { + t["HostDiskMappingPartitionOption"] = reflect.TypeOf((*HostDiskMappingPartitionOption)(nil)).Elem() +} + +type HostDiskPartitionAttributes struct { + DynamicData + + Partition int32 `xml:"partition"` + StartSector int64 `xml:"startSector"` + EndSector int64 `xml:"endSector"` + Type string `xml:"type"` + Guid string `xml:"guid,omitempty"` + Logical bool `xml:"logical"` + Attributes byte `xml:"attributes"` + PartitionAlignment int64 `xml:"partitionAlignment,omitempty"` +} + +func init() { + t["HostDiskPartitionAttributes"] = reflect.TypeOf((*HostDiskPartitionAttributes)(nil)).Elem() +} + +type HostDiskPartitionBlockRange struct { + DynamicData + + Partition int32 `xml:"partition,omitempty"` + Type string `xml:"type"` + Start HostDiskDimensionsLba `xml:"start"` + End HostDiskDimensionsLba `xml:"end"` +} + +func init() { + t["HostDiskPartitionBlockRange"] = reflect.TypeOf((*HostDiskPartitionBlockRange)(nil)).Elem() +} + +type HostDiskPartitionInfo struct { + DynamicData + + DeviceName string `xml:"deviceName"` + Spec HostDiskPartitionSpec `xml:"spec"` + Layout HostDiskPartitionLayout `xml:"layout"` +} + +func init() { + t["HostDiskPartitionInfo"] = reflect.TypeOf((*HostDiskPartitionInfo)(nil)).Elem() +} + +type HostDiskPartitionLayout struct { + DynamicData + + Total *HostDiskDimensionsLba `xml:"total,omitempty"` + Partition []HostDiskPartitionBlockRange `xml:"partition"` +} + +func init() { + t["HostDiskPartitionLayout"] = reflect.TypeOf((*HostDiskPartitionLayout)(nil)).Elem() +} + +type HostDiskPartitionSpec struct { + DynamicData + + PartitionFormat string `xml:"partitionFormat,omitempty"` + Chs *HostDiskDimensionsChs `xml:"chs,omitempty"` + TotalSectors int64 `xml:"totalSectors,omitempty"` + Partition []HostDiskPartitionAttributes `xml:"partition,omitempty"` +} + +func init() { + t["HostDiskPartitionSpec"] = reflect.TypeOf((*HostDiskPartitionSpec)(nil)).Elem() +} + +type HostDnsConfig struct { + DynamicData + + Dhcp bool `xml:"dhcp"` + VirtualNicDevice string `xml:"virtualNicDevice,omitempty"` + HostName string `xml:"hostName"` + DomainName string `xml:"domainName"` + Address []string `xml:"address,omitempty"` + SearchDomain []string `xml:"searchDomain,omitempty"` +} + +func init() { + t["HostDnsConfig"] = reflect.TypeOf((*HostDnsConfig)(nil)).Elem() +} + +type HostDnsConfigSpec struct { + HostDnsConfig + + VirtualNicConnection *HostVirtualNicConnection `xml:"virtualNicConnection,omitempty"` +} + +func init() { + t["HostDnsConfigSpec"] = reflect.TypeOf((*HostDnsConfigSpec)(nil)).Elem() +} + +type HostEnableAdminFailedEvent struct { + HostEvent + + Permissions []Permission `xml:"permissions"` +} + +func init() { + t["HostEnableAdminFailedEvent"] = reflect.TypeOf((*HostEnableAdminFailedEvent)(nil)).Elem() +} + +type HostEsxAgentHostManagerConfigInfo struct { + DynamicData + + AgentVmDatastore *ManagedObjectReference `xml:"agentVmDatastore,omitempty"` + AgentVmNetwork *ManagedObjectReference `xml:"agentVmNetwork,omitempty"` +} + +func init() { + t["HostEsxAgentHostManagerConfigInfo"] = reflect.TypeOf((*HostEsxAgentHostManagerConfigInfo)(nil)).Elem() +} + +type HostEvent struct { + Event +} + +func init() { + t["HostEvent"] = reflect.TypeOf((*HostEvent)(nil)).Elem() +} + +type HostEventArgument struct { + EntityEventArgument + + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["HostEventArgument"] = reflect.TypeOf((*HostEventArgument)(nil)).Elem() +} + +type HostExtraNetworksEvent struct { + HostDasEvent + + Ips string `xml:"ips,omitempty"` +} + +func init() { + t["HostExtraNetworksEvent"] = reflect.TypeOf((*HostExtraNetworksEvent)(nil)).Elem() +} + +type HostFaultToleranceManagerComponentHealthInfo struct { + DynamicData + + IsStorageHealthy bool `xml:"isStorageHealthy"` + IsNetworkHealthy bool `xml:"isNetworkHealthy"` +} + +func init() { + t["HostFaultToleranceManagerComponentHealthInfo"] = reflect.TypeOf((*HostFaultToleranceManagerComponentHealthInfo)(nil)).Elem() +} + +type HostFeatureCapability struct { + DynamicData + + Key string `xml:"key"` + FeatureName string `xml:"featureName"` + Value string `xml:"value"` +} + +func init() { + t["HostFeatureCapability"] = reflect.TypeOf((*HostFeatureCapability)(nil)).Elem() +} + +type HostFeatureMask struct { + DynamicData + + Key string `xml:"key"` + FeatureName string `xml:"featureName"` + Value string `xml:"value"` +} + +func init() { + t["HostFeatureMask"] = reflect.TypeOf((*HostFeatureMask)(nil)).Elem() +} + +type HostFeatureVersionInfo struct { + DynamicData + + Key string `xml:"key"` + Value string `xml:"value"` +} + +func init() { + t["HostFeatureVersionInfo"] = reflect.TypeOf((*HostFeatureVersionInfo)(nil)).Elem() +} + +type HostFibreChannelHba struct { + HostHostBusAdapter + + PortWorldWideName int64 `xml:"portWorldWideName"` + NodeWorldWideName int64 `xml:"nodeWorldWideName"` + PortType FibreChannelPortType `xml:"portType"` + Speed int64 `xml:"speed"` +} + +func init() { + t["HostFibreChannelHba"] = reflect.TypeOf((*HostFibreChannelHba)(nil)).Elem() +} + +type HostFibreChannelOverEthernetHba struct { + HostFibreChannelHba + + UnderlyingNic string `xml:"underlyingNic"` + LinkInfo HostFibreChannelOverEthernetHbaLinkInfo `xml:"linkInfo"` + IsSoftwareFcoe bool `xml:"isSoftwareFcoe"` + MarkedForRemoval bool `xml:"markedForRemoval"` +} + +func init() { + t["HostFibreChannelOverEthernetHba"] = reflect.TypeOf((*HostFibreChannelOverEthernetHba)(nil)).Elem() +} + +type HostFibreChannelOverEthernetHbaLinkInfo struct { + DynamicData + + VnportMac string `xml:"vnportMac"` + FcfMac string `xml:"fcfMac"` + VlanId int32 `xml:"vlanId"` +} + +func init() { + t["HostFibreChannelOverEthernetHbaLinkInfo"] = reflect.TypeOf((*HostFibreChannelOverEthernetHbaLinkInfo)(nil)).Elem() +} + +type HostFibreChannelOverEthernetTargetTransport struct { + HostFibreChannelTargetTransport + + VnportMac string `xml:"vnportMac"` + FcfMac string `xml:"fcfMac"` + VlanId int32 `xml:"vlanId"` +} + +func init() { + t["HostFibreChannelOverEthernetTargetTransport"] = reflect.TypeOf((*HostFibreChannelOverEthernetTargetTransport)(nil)).Elem() +} + +type HostFibreChannelTargetTransport struct { + HostTargetTransport + + PortWorldWideName int64 `xml:"portWorldWideName"` + NodeWorldWideName int64 `xml:"nodeWorldWideName"` +} + +func init() { + t["HostFibreChannelTargetTransport"] = reflect.TypeOf((*HostFibreChannelTargetTransport)(nil)).Elem() +} + +type HostFileAccess struct { + DynamicData + + Who string `xml:"who"` + What string `xml:"what"` +} + +func init() { + t["HostFileAccess"] = reflect.TypeOf((*HostFileAccess)(nil)).Elem() +} + +type HostFileSystemMountInfo struct { + DynamicData + + MountInfo HostMountInfo `xml:"mountInfo"` + Volume BaseHostFileSystemVolume `xml:"volume,typeattr"` + VStorageSupport string `xml:"vStorageSupport,omitempty"` +} + +func init() { + t["HostFileSystemMountInfo"] = reflect.TypeOf((*HostFileSystemMountInfo)(nil)).Elem() +} + +type HostFileSystemVolume struct { + DynamicData + + Type string `xml:"type"` + Name string `xml:"name"` + Capacity int64 `xml:"capacity"` +} + +func init() { + t["HostFileSystemVolume"] = reflect.TypeOf((*HostFileSystemVolume)(nil)).Elem() +} + +type HostFileSystemVolumeInfo struct { + DynamicData + + VolumeTypeList []string `xml:"volumeTypeList,omitempty"` + MountInfo []HostFileSystemMountInfo `xml:"mountInfo,omitempty"` +} + +func init() { + t["HostFileSystemVolumeInfo"] = reflect.TypeOf((*HostFileSystemVolumeInfo)(nil)).Elem() +} + +type HostFirewallConfig struct { + DynamicData + + Rule []HostFirewallConfigRuleSetConfig `xml:"rule,omitempty"` + DefaultBlockingPolicy HostFirewallDefaultPolicy `xml:"defaultBlockingPolicy"` +} + +func init() { + t["HostFirewallConfig"] = reflect.TypeOf((*HostFirewallConfig)(nil)).Elem() +} + +type HostFirewallConfigRuleSetConfig struct { + DynamicData + + RulesetId string `xml:"rulesetId"` + Enabled bool `xml:"enabled"` + AllowedHosts *HostFirewallRulesetIpList `xml:"allowedHosts,omitempty"` +} + +func init() { + t["HostFirewallConfigRuleSetConfig"] = reflect.TypeOf((*HostFirewallConfigRuleSetConfig)(nil)).Elem() +} + +type HostFirewallDefaultPolicy struct { + DynamicData + + IncomingBlocked *bool `xml:"incomingBlocked"` + OutgoingBlocked *bool `xml:"outgoingBlocked"` +} + +func init() { + t["HostFirewallDefaultPolicy"] = reflect.TypeOf((*HostFirewallDefaultPolicy)(nil)).Elem() +} + +type HostFirewallInfo struct { + DynamicData + + DefaultPolicy HostFirewallDefaultPolicy `xml:"defaultPolicy"` + Ruleset []HostFirewallRuleset `xml:"ruleset,omitempty"` +} + +func init() { + t["HostFirewallInfo"] = reflect.TypeOf((*HostFirewallInfo)(nil)).Elem() +} + +type HostFirewallRule struct { + DynamicData + + Port int32 `xml:"port"` + EndPort int32 `xml:"endPort,omitempty"` + Direction HostFirewallRuleDirection `xml:"direction"` + PortType HostFirewallRulePortType `xml:"portType,omitempty"` + Protocol string `xml:"protocol"` +} + +func init() { + t["HostFirewallRule"] = reflect.TypeOf((*HostFirewallRule)(nil)).Elem() +} + +type HostFirewallRuleset struct { + DynamicData + + Key string `xml:"key"` + Label string `xml:"label"` + Required bool `xml:"required"` + Rule []HostFirewallRule `xml:"rule"` + Service string `xml:"service,omitempty"` + Enabled bool `xml:"enabled"` + AllowedHosts *HostFirewallRulesetIpList `xml:"allowedHosts,omitempty"` +} + +func init() { + t["HostFirewallRuleset"] = reflect.TypeOf((*HostFirewallRuleset)(nil)).Elem() +} + +type HostFirewallRulesetIpList struct { + DynamicData + + IpAddress []string `xml:"ipAddress,omitempty"` + IpNetwork []HostFirewallRulesetIpNetwork `xml:"ipNetwork,omitempty"` + AllIp bool `xml:"allIp"` +} + +func init() { + t["HostFirewallRulesetIpList"] = reflect.TypeOf((*HostFirewallRulesetIpList)(nil)).Elem() +} + +type HostFirewallRulesetIpNetwork struct { + DynamicData + + Network string `xml:"network"` + PrefixLength int32 `xml:"prefixLength"` +} + +func init() { + t["HostFirewallRulesetIpNetwork"] = reflect.TypeOf((*HostFirewallRulesetIpNetwork)(nil)).Elem() +} + +type HostFirewallRulesetRulesetSpec struct { + DynamicData + + AllowedHosts HostFirewallRulesetIpList `xml:"allowedHosts"` +} + +func init() { + t["HostFirewallRulesetRulesetSpec"] = reflect.TypeOf((*HostFirewallRulesetRulesetSpec)(nil)).Elem() +} + +type HostFlagInfo struct { + DynamicData + + BackgroundSnapshotsEnabled *bool `xml:"backgroundSnapshotsEnabled"` +} + +func init() { + t["HostFlagInfo"] = reflect.TypeOf((*HostFlagInfo)(nil)).Elem() +} + +type HostForceMountedInfo struct { + DynamicData + + Persist bool `xml:"persist"` + Mounted bool `xml:"mounted"` +} + +func init() { + t["HostForceMountedInfo"] = reflect.TypeOf((*HostForceMountedInfo)(nil)).Elem() +} + +type HostGatewaySpec struct { + DynamicData + + GatewayType string `xml:"gatewayType"` + GatewayId string `xml:"gatewayId,omitempty"` + TrustVerificationToken string `xml:"trustVerificationToken,omitempty"` + HostAuthParams []KeyValue `xml:"hostAuthParams,omitempty"` +} + +func init() { + t["HostGatewaySpec"] = reflect.TypeOf((*HostGatewaySpec)(nil)).Elem() +} + +type HostGetShortNameFailedEvent struct { + HostEvent +} + +func init() { + t["HostGetShortNameFailedEvent"] = reflect.TypeOf((*HostGetShortNameFailedEvent)(nil)).Elem() +} + +type HostGetVFlashModuleDefaultConfig HostGetVFlashModuleDefaultConfigRequestType + +func init() { + t["HostGetVFlashModuleDefaultConfig"] = reflect.TypeOf((*HostGetVFlashModuleDefaultConfig)(nil)).Elem() +} + +type HostGetVFlashModuleDefaultConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + VFlashModule string `xml:"vFlashModule"` +} + +func init() { + t["HostGetVFlashModuleDefaultConfigRequestType"] = reflect.TypeOf((*HostGetVFlashModuleDefaultConfigRequestType)(nil)).Elem() +} + +type HostGetVFlashModuleDefaultConfigResponse struct { + Returnval VirtualDiskVFlashCacheConfigInfo `xml:"returnval"` +} + +type HostGraphicsInfo struct { + DynamicData + + DeviceName string `xml:"deviceName"` + VendorName string `xml:"vendorName"` + PciId string `xml:"pciId"` + GraphicsType string `xml:"graphicsType"` + MemorySizeInKB int64 `xml:"memorySizeInKB"` + Vm []ManagedObjectReference `xml:"vm,omitempty"` +} + +func init() { + t["HostGraphicsInfo"] = reflect.TypeOf((*HostGraphicsInfo)(nil)).Elem() +} + +type HostHardwareElementInfo struct { + DynamicData + + Name string `xml:"name"` + Status BaseElementDescription `xml:"status,typeattr"` +} + +func init() { + t["HostHardwareElementInfo"] = reflect.TypeOf((*HostHardwareElementInfo)(nil)).Elem() +} + +type HostHardwareInfo struct { + DynamicData + + SystemInfo HostSystemInfo `xml:"systemInfo"` + CpuPowerManagementInfo *HostCpuPowerManagementInfo `xml:"cpuPowerManagementInfo,omitempty"` + CpuInfo HostCpuInfo `xml:"cpuInfo"` + CpuPkg []HostCpuPackage `xml:"cpuPkg"` + MemorySize int64 `xml:"memorySize"` + NumaInfo *HostNumaInfo `xml:"numaInfo,omitempty"` + SmcPresent *bool `xml:"smcPresent"` + PciDevice []HostPciDevice `xml:"pciDevice,omitempty"` + CpuFeature []HostCpuIdInfo `xml:"cpuFeature,omitempty"` + BiosInfo *HostBIOSInfo `xml:"biosInfo,omitempty"` + ReliableMemoryInfo *HostReliableMemoryInfo `xml:"reliableMemoryInfo,omitempty"` +} + +func init() { + t["HostHardwareInfo"] = reflect.TypeOf((*HostHardwareInfo)(nil)).Elem() +} + +type HostHardwareStatusInfo struct { + DynamicData + + MemoryStatusInfo []BaseHostHardwareElementInfo `xml:"memoryStatusInfo,omitempty,typeattr"` + CpuStatusInfo []BaseHostHardwareElementInfo `xml:"cpuStatusInfo,omitempty,typeattr"` + StorageStatusInfo []HostStorageElementInfo `xml:"storageStatusInfo,omitempty"` +} + +func init() { + t["HostHardwareStatusInfo"] = reflect.TypeOf((*HostHardwareStatusInfo)(nil)).Elem() +} + +type HostHardwareSummary struct { + DynamicData + + Vendor string `xml:"vendor"` + Model string `xml:"model"` + Uuid string `xml:"uuid"` + OtherIdentifyingInfo []HostSystemIdentificationInfo `xml:"otherIdentifyingInfo,omitempty"` + MemorySize int64 `xml:"memorySize"` + CpuModel string `xml:"cpuModel"` + CpuMhz int32 `xml:"cpuMhz"` + NumCpuPkgs int16 `xml:"numCpuPkgs"` + NumCpuCores int16 `xml:"numCpuCores"` + NumCpuThreads int16 `xml:"numCpuThreads"` + NumNics int32 `xml:"numNics"` + NumHBAs int32 `xml:"numHBAs"` +} + +func init() { + t["HostHardwareSummary"] = reflect.TypeOf((*HostHardwareSummary)(nil)).Elem() +} + +type HostHasComponentFailure struct { + VimFault + + HostName string `xml:"hostName"` + ComponentType string `xml:"componentType"` + ComponentName string `xml:"componentName"` +} + +func init() { + t["HostHasComponentFailure"] = reflect.TypeOf((*HostHasComponentFailure)(nil)).Elem() +} + +type HostHasComponentFailureFault HostHasComponentFailure + +func init() { + t["HostHasComponentFailureFault"] = reflect.TypeOf((*HostHasComponentFailureFault)(nil)).Elem() +} + +type HostHostBusAdapter struct { + DynamicData + + Key string `xml:"key,omitempty"` + Device string `xml:"device"` + Bus int32 `xml:"bus"` + Status string `xml:"status"` + Model string `xml:"model"` + Driver string `xml:"driver,omitempty"` + Pci string `xml:"pci,omitempty"` +} + +func init() { + t["HostHostBusAdapter"] = reflect.TypeOf((*HostHostBusAdapter)(nil)).Elem() +} + +type HostHyperThreadScheduleInfo struct { + DynamicData + + Available bool `xml:"available"` + Active bool `xml:"active"` + Config bool `xml:"config"` +} + +func init() { + t["HostHyperThreadScheduleInfo"] = reflect.TypeOf((*HostHyperThreadScheduleInfo)(nil)).Elem() +} + +type HostImageConfigGetAcceptance HostImageConfigGetAcceptanceRequestType + +func init() { + t["HostImageConfigGetAcceptance"] = reflect.TypeOf((*HostImageConfigGetAcceptance)(nil)).Elem() +} + +type HostImageConfigGetAcceptanceRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["HostImageConfigGetAcceptanceRequestType"] = reflect.TypeOf((*HostImageConfigGetAcceptanceRequestType)(nil)).Elem() +} + +type HostImageConfigGetAcceptanceResponse struct { + Returnval string `xml:"returnval"` +} + +type HostImageConfigGetProfile HostImageConfigGetProfileRequestType + +func init() { + t["HostImageConfigGetProfile"] = reflect.TypeOf((*HostImageConfigGetProfile)(nil)).Elem() +} + +type HostImageConfigGetProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["HostImageConfigGetProfileRequestType"] = reflect.TypeOf((*HostImageConfigGetProfileRequestType)(nil)).Elem() +} + +type HostImageConfigGetProfileResponse struct { + Returnval HostImageProfileSummary `xml:"returnval"` +} + +type HostImageProfileSummary struct { + DynamicData + + Name string `xml:"name"` + Vendor string `xml:"vendor"` +} + +func init() { + t["HostImageProfileSummary"] = reflect.TypeOf((*HostImageProfileSummary)(nil)).Elem() +} + +type HostInAuditModeEvent struct { + HostEvent +} + +func init() { + t["HostInAuditModeEvent"] = reflect.TypeOf((*HostInAuditModeEvent)(nil)).Elem() +} + +type HostInDomain struct { + HostConfigFault +} + +func init() { + t["HostInDomain"] = reflect.TypeOf((*HostInDomain)(nil)).Elem() +} + +type HostInDomainFault HostInDomain + +func init() { + t["HostInDomainFault"] = reflect.TypeOf((*HostInDomainFault)(nil)).Elem() +} + +type HostIncompatibleForFaultTolerance struct { + VmFaultToleranceIssue + + HostName string `xml:"hostName,omitempty"` + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["HostIncompatibleForFaultTolerance"] = reflect.TypeOf((*HostIncompatibleForFaultTolerance)(nil)).Elem() +} + +type HostIncompatibleForFaultToleranceFault HostIncompatibleForFaultTolerance + +func init() { + t["HostIncompatibleForFaultToleranceFault"] = reflect.TypeOf((*HostIncompatibleForFaultToleranceFault)(nil)).Elem() +} + +type HostIncompatibleForRecordReplay struct { + VimFault + + HostName string `xml:"hostName,omitempty"` + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["HostIncompatibleForRecordReplay"] = reflect.TypeOf((*HostIncompatibleForRecordReplay)(nil)).Elem() +} + +type HostIncompatibleForRecordReplayFault HostIncompatibleForRecordReplay + +func init() { + t["HostIncompatibleForRecordReplayFault"] = reflect.TypeOf((*HostIncompatibleForRecordReplayFault)(nil)).Elem() +} + +type HostInternetScsiHba struct { + HostHostBusAdapter + + IsSoftwareBased bool `xml:"isSoftwareBased"` + CanBeDisabled *bool `xml:"canBeDisabled"` + NetworkBindingSupport HostInternetScsiHbaNetworkBindingSupportType `xml:"networkBindingSupport,omitempty"` + DiscoveryCapabilities HostInternetScsiHbaDiscoveryCapabilities `xml:"discoveryCapabilities"` + DiscoveryProperties HostInternetScsiHbaDiscoveryProperties `xml:"discoveryProperties"` + AuthenticationCapabilities HostInternetScsiHbaAuthenticationCapabilities `xml:"authenticationCapabilities"` + AuthenticationProperties HostInternetScsiHbaAuthenticationProperties `xml:"authenticationProperties"` + DigestCapabilities *HostInternetScsiHbaDigestCapabilities `xml:"digestCapabilities,omitempty"` + DigestProperties *HostInternetScsiHbaDigestProperties `xml:"digestProperties,omitempty"` + IpCapabilities HostInternetScsiHbaIPCapabilities `xml:"ipCapabilities"` + IpProperties HostInternetScsiHbaIPProperties `xml:"ipProperties"` + SupportedAdvancedOptions []OptionDef `xml:"supportedAdvancedOptions,omitempty"` + AdvancedOptions []HostInternetScsiHbaParamValue `xml:"advancedOptions,omitempty"` + IScsiName string `xml:"iScsiName"` + IScsiAlias string `xml:"iScsiAlias,omitempty"` + ConfiguredSendTarget []HostInternetScsiHbaSendTarget `xml:"configuredSendTarget,omitempty"` + ConfiguredStaticTarget []HostInternetScsiHbaStaticTarget `xml:"configuredStaticTarget,omitempty"` + MaxSpeedMb int32 `xml:"maxSpeedMb,omitempty"` + CurrentSpeedMb int32 `xml:"currentSpeedMb,omitempty"` +} + +func init() { + t["HostInternetScsiHba"] = reflect.TypeOf((*HostInternetScsiHba)(nil)).Elem() +} + +type HostInternetScsiHbaAuthenticationCapabilities struct { + DynamicData + + ChapAuthSettable bool `xml:"chapAuthSettable"` + Krb5AuthSettable bool `xml:"krb5AuthSettable"` + SrpAuthSettable bool `xml:"srpAuthSettable"` + SpkmAuthSettable bool `xml:"spkmAuthSettable"` + MutualChapSettable *bool `xml:"mutualChapSettable"` + TargetChapSettable *bool `xml:"targetChapSettable"` + TargetMutualChapSettable *bool `xml:"targetMutualChapSettable"` +} + +func init() { + t["HostInternetScsiHbaAuthenticationCapabilities"] = reflect.TypeOf((*HostInternetScsiHbaAuthenticationCapabilities)(nil)).Elem() +} + +type HostInternetScsiHbaAuthenticationProperties struct { + DynamicData + + ChapAuthEnabled bool `xml:"chapAuthEnabled"` + ChapName string `xml:"chapName,omitempty"` + ChapSecret string `xml:"chapSecret,omitempty"` + ChapAuthenticationType string `xml:"chapAuthenticationType,omitempty"` + ChapInherited *bool `xml:"chapInherited"` + MutualChapName string `xml:"mutualChapName,omitempty"` + MutualChapSecret string `xml:"mutualChapSecret,omitempty"` + MutualChapAuthenticationType string `xml:"mutualChapAuthenticationType,omitempty"` + MutualChapInherited *bool `xml:"mutualChapInherited"` +} + +func init() { + t["HostInternetScsiHbaAuthenticationProperties"] = reflect.TypeOf((*HostInternetScsiHbaAuthenticationProperties)(nil)).Elem() +} + +type HostInternetScsiHbaDigestCapabilities struct { + DynamicData + + HeaderDigestSettable *bool `xml:"headerDigestSettable"` + DataDigestSettable *bool `xml:"dataDigestSettable"` + TargetHeaderDigestSettable *bool `xml:"targetHeaderDigestSettable"` + TargetDataDigestSettable *bool `xml:"targetDataDigestSettable"` +} + +func init() { + t["HostInternetScsiHbaDigestCapabilities"] = reflect.TypeOf((*HostInternetScsiHbaDigestCapabilities)(nil)).Elem() +} + +type HostInternetScsiHbaDigestProperties struct { + DynamicData + + HeaderDigestType string `xml:"headerDigestType,omitempty"` + HeaderDigestInherited *bool `xml:"headerDigestInherited"` + DataDigestType string `xml:"dataDigestType,omitempty"` + DataDigestInherited *bool `xml:"dataDigestInherited"` +} + +func init() { + t["HostInternetScsiHbaDigestProperties"] = reflect.TypeOf((*HostInternetScsiHbaDigestProperties)(nil)).Elem() +} + +type HostInternetScsiHbaDiscoveryCapabilities struct { + DynamicData + + ISnsDiscoverySettable bool `xml:"iSnsDiscoverySettable"` + SlpDiscoverySettable bool `xml:"slpDiscoverySettable"` + StaticTargetDiscoverySettable bool `xml:"staticTargetDiscoverySettable"` + SendTargetsDiscoverySettable bool `xml:"sendTargetsDiscoverySettable"` +} + +func init() { + t["HostInternetScsiHbaDiscoveryCapabilities"] = reflect.TypeOf((*HostInternetScsiHbaDiscoveryCapabilities)(nil)).Elem() +} + +type HostInternetScsiHbaDiscoveryProperties struct { + DynamicData + + ISnsDiscoveryEnabled bool `xml:"iSnsDiscoveryEnabled"` + ISnsDiscoveryMethod string `xml:"iSnsDiscoveryMethod,omitempty"` + ISnsHost string `xml:"iSnsHost,omitempty"` + SlpDiscoveryEnabled bool `xml:"slpDiscoveryEnabled"` + SlpDiscoveryMethod string `xml:"slpDiscoveryMethod,omitempty"` + SlpHost string `xml:"slpHost,omitempty"` + StaticTargetDiscoveryEnabled bool `xml:"staticTargetDiscoveryEnabled"` + SendTargetsDiscoveryEnabled bool `xml:"sendTargetsDiscoveryEnabled"` +} + +func init() { + t["HostInternetScsiHbaDiscoveryProperties"] = reflect.TypeOf((*HostInternetScsiHbaDiscoveryProperties)(nil)).Elem() +} + +type HostInternetScsiHbaIPCapabilities struct { + DynamicData + + AddressSettable bool `xml:"addressSettable"` + IpConfigurationMethodSettable bool `xml:"ipConfigurationMethodSettable"` + SubnetMaskSettable bool `xml:"subnetMaskSettable"` + DefaultGatewaySettable bool `xml:"defaultGatewaySettable"` + PrimaryDnsServerAddressSettable bool `xml:"primaryDnsServerAddressSettable"` + AlternateDnsServerAddressSettable bool `xml:"alternateDnsServerAddressSettable"` + Ipv6Supported *bool `xml:"ipv6Supported"` + ArpRedirectSettable *bool `xml:"arpRedirectSettable"` + MtuSettable *bool `xml:"mtuSettable"` + HostNameAsTargetAddress *bool `xml:"hostNameAsTargetAddress"` + NameAliasSettable *bool `xml:"nameAliasSettable"` + Ipv4EnableSettable *bool `xml:"ipv4EnableSettable"` + Ipv6EnableSettable *bool `xml:"ipv6EnableSettable"` + Ipv6PrefixLengthSettable *bool `xml:"ipv6PrefixLengthSettable"` + Ipv6PrefixLength int32 `xml:"ipv6PrefixLength,omitempty"` + Ipv6DhcpConfigurationSettable *bool `xml:"ipv6DhcpConfigurationSettable"` + Ipv6LinkLocalAutoConfigurationSettable *bool `xml:"ipv6LinkLocalAutoConfigurationSettable"` + Ipv6RouterAdvertisementConfigurationSettable *bool `xml:"ipv6RouterAdvertisementConfigurationSettable"` + Ipv6DefaultGatewaySettable *bool `xml:"ipv6DefaultGatewaySettable"` + Ipv6MaxStaticAddressesSupported int32 `xml:"ipv6MaxStaticAddressesSupported,omitempty"` +} + +func init() { + t["HostInternetScsiHbaIPCapabilities"] = reflect.TypeOf((*HostInternetScsiHbaIPCapabilities)(nil)).Elem() +} + +type HostInternetScsiHbaIPProperties struct { + DynamicData + + Mac string `xml:"mac,omitempty"` + Address string `xml:"address,omitempty"` + DhcpConfigurationEnabled bool `xml:"dhcpConfigurationEnabled"` + SubnetMask string `xml:"subnetMask,omitempty"` + DefaultGateway string `xml:"defaultGateway,omitempty"` + PrimaryDnsServerAddress string `xml:"primaryDnsServerAddress,omitempty"` + AlternateDnsServerAddress string `xml:"alternateDnsServerAddress,omitempty"` + Ipv6Address string `xml:"ipv6Address,omitempty"` + Ipv6SubnetMask string `xml:"ipv6SubnetMask,omitempty"` + Ipv6DefaultGateway string `xml:"ipv6DefaultGateway,omitempty"` + ArpRedirectEnabled *bool `xml:"arpRedirectEnabled"` + Mtu int32 `xml:"mtu,omitempty"` + JumboFramesEnabled *bool `xml:"jumboFramesEnabled"` + Ipv4Enabled *bool `xml:"ipv4Enabled"` + Ipv6Enabled *bool `xml:"ipv6Enabled"` + Ipv6properties *HostInternetScsiHbaIPv6Properties `xml:"ipv6properties,omitempty"` +} + +func init() { + t["HostInternetScsiHbaIPProperties"] = reflect.TypeOf((*HostInternetScsiHbaIPProperties)(nil)).Elem() +} + +type HostInternetScsiHbaIPv6Properties struct { + DynamicData + + IscsiIpv6Address []HostInternetScsiHbaIscsiIpv6Address `xml:"iscsiIpv6Address,omitempty"` + Ipv6DhcpConfigurationEnabled *bool `xml:"ipv6DhcpConfigurationEnabled"` + Ipv6LinkLocalAutoConfigurationEnabled *bool `xml:"ipv6LinkLocalAutoConfigurationEnabled"` + Ipv6RouterAdvertisementConfigurationEnabled *bool `xml:"ipv6RouterAdvertisementConfigurationEnabled"` + Ipv6DefaultGateway string `xml:"ipv6DefaultGateway,omitempty"` +} + +func init() { + t["HostInternetScsiHbaIPv6Properties"] = reflect.TypeOf((*HostInternetScsiHbaIPv6Properties)(nil)).Elem() +} + +type HostInternetScsiHbaIscsiIpv6Address struct { + DynamicData + + Address string `xml:"address"` + PrefixLength int32 `xml:"prefixLength"` + Origin string `xml:"origin"` + Operation string `xml:"operation,omitempty"` +} + +func init() { + t["HostInternetScsiHbaIscsiIpv6Address"] = reflect.TypeOf((*HostInternetScsiHbaIscsiIpv6Address)(nil)).Elem() +} + +type HostInternetScsiHbaParamValue struct { + OptionValue + + IsInherited *bool `xml:"isInherited"` +} + +func init() { + t["HostInternetScsiHbaParamValue"] = reflect.TypeOf((*HostInternetScsiHbaParamValue)(nil)).Elem() +} + +type HostInternetScsiHbaSendTarget struct { + DynamicData + + Address string `xml:"address"` + Port int32 `xml:"port,omitempty"` + AuthenticationProperties *HostInternetScsiHbaAuthenticationProperties `xml:"authenticationProperties,omitempty"` + DigestProperties *HostInternetScsiHbaDigestProperties `xml:"digestProperties,omitempty"` + SupportedAdvancedOptions []OptionDef `xml:"supportedAdvancedOptions,omitempty"` + AdvancedOptions []HostInternetScsiHbaParamValue `xml:"advancedOptions,omitempty"` + Parent string `xml:"parent,omitempty"` +} + +func init() { + t["HostInternetScsiHbaSendTarget"] = reflect.TypeOf((*HostInternetScsiHbaSendTarget)(nil)).Elem() +} + +type HostInternetScsiHbaStaticTarget struct { + DynamicData + + Address string `xml:"address"` + Port int32 `xml:"port,omitempty"` + IScsiName string `xml:"iScsiName"` + DiscoveryMethod string `xml:"discoveryMethod,omitempty"` + AuthenticationProperties *HostInternetScsiHbaAuthenticationProperties `xml:"authenticationProperties,omitempty"` + DigestProperties *HostInternetScsiHbaDigestProperties `xml:"digestProperties,omitempty"` + SupportedAdvancedOptions []OptionDef `xml:"supportedAdvancedOptions,omitempty"` + AdvancedOptions []HostInternetScsiHbaParamValue `xml:"advancedOptions,omitempty"` + Parent string `xml:"parent,omitempty"` +} + +func init() { + t["HostInternetScsiHbaStaticTarget"] = reflect.TypeOf((*HostInternetScsiHbaStaticTarget)(nil)).Elem() +} + +type HostInternetScsiHbaTargetSet struct { + DynamicData + + StaticTargets []HostInternetScsiHbaStaticTarget `xml:"staticTargets,omitempty"` + SendTargets []HostInternetScsiHbaSendTarget `xml:"sendTargets,omitempty"` +} + +func init() { + t["HostInternetScsiHbaTargetSet"] = reflect.TypeOf((*HostInternetScsiHbaTargetSet)(nil)).Elem() +} + +type HostInternetScsiTargetTransport struct { + HostTargetTransport + + IScsiName string `xml:"iScsiName"` + IScsiAlias string `xml:"iScsiAlias"` + Address []string `xml:"address,omitempty"` +} + +func init() { + t["HostInternetScsiTargetTransport"] = reflect.TypeOf((*HostInternetScsiTargetTransport)(nil)).Elem() +} + +type HostInventoryFull struct { + NotEnoughLicenses + + Capacity int32 `xml:"capacity"` +} + +func init() { + t["HostInventoryFull"] = reflect.TypeOf((*HostInventoryFull)(nil)).Elem() +} + +type HostInventoryFullEvent struct { + LicenseEvent + + Capacity int32 `xml:"capacity"` +} + +func init() { + t["HostInventoryFullEvent"] = reflect.TypeOf((*HostInventoryFullEvent)(nil)).Elem() +} + +type HostInventoryFullFault HostInventoryFull + +func init() { + t["HostInventoryFullFault"] = reflect.TypeOf((*HostInventoryFullFault)(nil)).Elem() +} + +type HostInventoryUnreadableEvent struct { + Event +} + +func init() { + t["HostInventoryUnreadableEvent"] = reflect.TypeOf((*HostInventoryUnreadableEvent)(nil)).Elem() +} + +type HostIoFilterInfo struct { + IoFilterInfo + + Available bool `xml:"available"` +} + +func init() { + t["HostIoFilterInfo"] = reflect.TypeOf((*HostIoFilterInfo)(nil)).Elem() +} + +type HostIpChangedEvent struct { + HostEvent + + OldIP string `xml:"oldIP"` + NewIP string `xml:"newIP"` +} + +func init() { + t["HostIpChangedEvent"] = reflect.TypeOf((*HostIpChangedEvent)(nil)).Elem() +} + +type HostIpConfig struct { + DynamicData + + Dhcp bool `xml:"dhcp"` + IpAddress string `xml:"ipAddress,omitempty"` + SubnetMask string `xml:"subnetMask,omitempty"` + IpV6Config *HostIpConfigIpV6AddressConfiguration `xml:"ipV6Config,omitempty"` +} + +func init() { + t["HostIpConfig"] = reflect.TypeOf((*HostIpConfig)(nil)).Elem() +} + +type HostIpConfigIpV6Address struct { + DynamicData + + IpAddress string `xml:"ipAddress"` + PrefixLength int32 `xml:"prefixLength"` + Origin string `xml:"origin,omitempty"` + DadState string `xml:"dadState,omitempty"` + Lifetime *time.Time `xml:"lifetime"` + Operation string `xml:"operation,omitempty"` +} + +func init() { + t["HostIpConfigIpV6Address"] = reflect.TypeOf((*HostIpConfigIpV6Address)(nil)).Elem() +} + +type HostIpConfigIpV6AddressConfiguration struct { + DynamicData + + IpV6Address []HostIpConfigIpV6Address `xml:"ipV6Address,omitempty"` + AutoConfigurationEnabled *bool `xml:"autoConfigurationEnabled"` + DhcpV6Enabled *bool `xml:"dhcpV6Enabled"` +} + +func init() { + t["HostIpConfigIpV6AddressConfiguration"] = reflect.TypeOf((*HostIpConfigIpV6AddressConfiguration)(nil)).Elem() +} + +type HostIpInconsistentEvent struct { + HostEvent + + IpAddress string `xml:"ipAddress"` + IpAddress2 string `xml:"ipAddress2"` +} + +func init() { + t["HostIpInconsistentEvent"] = reflect.TypeOf((*HostIpInconsistentEvent)(nil)).Elem() +} + +type HostIpRouteConfig struct { + DynamicData + + DefaultGateway string `xml:"defaultGateway,omitempty"` + GatewayDevice string `xml:"gatewayDevice,omitempty"` + IpV6DefaultGateway string `xml:"ipV6DefaultGateway,omitempty"` + IpV6GatewayDevice string `xml:"ipV6GatewayDevice,omitempty"` +} + +func init() { + t["HostIpRouteConfig"] = reflect.TypeOf((*HostIpRouteConfig)(nil)).Elem() +} + +type HostIpRouteConfigSpec struct { + HostIpRouteConfig + + GatewayDeviceConnection *HostVirtualNicConnection `xml:"gatewayDeviceConnection,omitempty"` + IpV6GatewayDeviceConnection *HostVirtualNicConnection `xml:"ipV6GatewayDeviceConnection,omitempty"` +} + +func init() { + t["HostIpRouteConfigSpec"] = reflect.TypeOf((*HostIpRouteConfigSpec)(nil)).Elem() +} + +type HostIpRouteEntry struct { + DynamicData + + Network string `xml:"network"` + PrefixLength int32 `xml:"prefixLength"` + Gateway string `xml:"gateway"` + DeviceName string `xml:"deviceName,omitempty"` +} + +func init() { + t["HostIpRouteEntry"] = reflect.TypeOf((*HostIpRouteEntry)(nil)).Elem() +} + +type HostIpRouteOp struct { + DynamicData + + ChangeOperation string `xml:"changeOperation"` + Route HostIpRouteEntry `xml:"route"` +} + +func init() { + t["HostIpRouteOp"] = reflect.TypeOf((*HostIpRouteOp)(nil)).Elem() +} + +type HostIpRouteTableConfig struct { + DynamicData + + IpRoute []HostIpRouteOp `xml:"ipRoute,omitempty"` + Ipv6Route []HostIpRouteOp `xml:"ipv6Route,omitempty"` +} + +func init() { + t["HostIpRouteTableConfig"] = reflect.TypeOf((*HostIpRouteTableConfig)(nil)).Elem() +} + +type HostIpRouteTableInfo struct { + DynamicData + + IpRoute []HostIpRouteEntry `xml:"ipRoute,omitempty"` + Ipv6Route []HostIpRouteEntry `xml:"ipv6Route,omitempty"` +} + +func init() { + t["HostIpRouteTableInfo"] = reflect.TypeOf((*HostIpRouteTableInfo)(nil)).Elem() +} + +type HostIpToShortNameFailedEvent struct { + HostEvent +} + +func init() { + t["HostIpToShortNameFailedEvent"] = reflect.TypeOf((*HostIpToShortNameFailedEvent)(nil)).Elem() +} + +type HostIpmiInfo struct { + DynamicData + + BmcIpAddress string `xml:"bmcIpAddress,omitempty"` + BmcMacAddress string `xml:"bmcMacAddress,omitempty"` + Login string `xml:"login,omitempty"` + Password string `xml:"password,omitempty"` +} + +func init() { + t["HostIpmiInfo"] = reflect.TypeOf((*HostIpmiInfo)(nil)).Elem() +} + +type HostIsolationIpPingFailedEvent struct { + HostDasEvent + + IsolationIp string `xml:"isolationIp"` +} + +func init() { + t["HostIsolationIpPingFailedEvent"] = reflect.TypeOf((*HostIsolationIpPingFailedEvent)(nil)).Elem() +} + +type HostLicensableResourceInfo struct { + DynamicData + + Resource []KeyAnyValue `xml:"resource"` +} + +func init() { + t["HostLicensableResourceInfo"] = reflect.TypeOf((*HostLicensableResourceInfo)(nil)).Elem() +} + +type HostLicenseConnectInfo struct { + DynamicData + + License LicenseManagerLicenseInfo `xml:"license"` + Evaluation LicenseManagerEvaluationInfo `xml:"evaluation"` + Resource *HostLicensableResourceInfo `xml:"resource,omitempty"` +} + +func init() { + t["HostLicenseConnectInfo"] = reflect.TypeOf((*HostLicenseConnectInfo)(nil)).Elem() +} + +type HostLicenseExpiredEvent struct { + LicenseEvent +} + +func init() { + t["HostLicenseExpiredEvent"] = reflect.TypeOf((*HostLicenseExpiredEvent)(nil)).Elem() +} + +type HostLicenseSpec struct { + DynamicData + + Source BaseLicenseSource `xml:"source,omitempty,typeattr"` + EditionKey string `xml:"editionKey,omitempty"` + DisabledFeatureKey []string `xml:"disabledFeatureKey,omitempty"` + EnabledFeatureKey []string `xml:"enabledFeatureKey,omitempty"` +} + +func init() { + t["HostLicenseSpec"] = reflect.TypeOf((*HostLicenseSpec)(nil)).Elem() +} + +type HostListSummary struct { + DynamicData + + Host *ManagedObjectReference `xml:"host,omitempty"` + Hardware *HostHardwareSummary `xml:"hardware,omitempty"` + Runtime *HostRuntimeInfo `xml:"runtime,omitempty"` + Config HostConfigSummary `xml:"config"` + QuickStats HostListSummaryQuickStats `xml:"quickStats"` + OverallStatus ManagedEntityStatus `xml:"overallStatus"` + RebootRequired bool `xml:"rebootRequired"` + CustomValue []BaseCustomFieldValue `xml:"customValue,omitempty,typeattr"` + ManagementServerIp string `xml:"managementServerIp,omitempty"` + MaxEVCModeKey string `xml:"maxEVCModeKey,omitempty"` + CurrentEVCModeKey string `xml:"currentEVCModeKey,omitempty"` + Gateway *HostListSummaryGatewaySummary `xml:"gateway,omitempty"` +} + +func init() { + t["HostListSummary"] = reflect.TypeOf((*HostListSummary)(nil)).Elem() +} + +type HostListSummaryGatewaySummary struct { + DynamicData + + GatewayType string `xml:"gatewayType"` + GatewayId string `xml:"gatewayId"` +} + +func init() { + t["HostListSummaryGatewaySummary"] = reflect.TypeOf((*HostListSummaryGatewaySummary)(nil)).Elem() +} + +type HostListSummaryQuickStats struct { + DynamicData + + OverallCpuUsage int32 `xml:"overallCpuUsage,omitempty"` + OverallMemoryUsage int32 `xml:"overallMemoryUsage,omitempty"` + DistributedCpuFairness int32 `xml:"distributedCpuFairness,omitempty"` + DistributedMemoryFairness int32 `xml:"distributedMemoryFairness,omitempty"` + Uptime int32 `xml:"uptime,omitempty"` +} + +func init() { + t["HostListSummaryQuickStats"] = reflect.TypeOf((*HostListSummaryQuickStats)(nil)).Elem() +} + +type HostLocalAuthenticationInfo struct { + HostAuthenticationStoreInfo +} + +func init() { + t["HostLocalAuthenticationInfo"] = reflect.TypeOf((*HostLocalAuthenticationInfo)(nil)).Elem() +} + +type HostLocalFileSystemVolume struct { + HostFileSystemVolume + + Device string `xml:"device"` +} + +func init() { + t["HostLocalFileSystemVolume"] = reflect.TypeOf((*HostLocalFileSystemVolume)(nil)).Elem() +} + +type HostLocalFileSystemVolumeSpec struct { + DynamicData + + Device string `xml:"device"` + LocalPath string `xml:"localPath"` +} + +func init() { + t["HostLocalFileSystemVolumeSpec"] = reflect.TypeOf((*HostLocalFileSystemVolumeSpec)(nil)).Elem() +} + +type HostLocalPortCreatedEvent struct { + DvsEvent + + HostLocalPort DVSHostLocalPortInfo `xml:"hostLocalPort"` +} + +func init() { + t["HostLocalPortCreatedEvent"] = reflect.TypeOf((*HostLocalPortCreatedEvent)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerDiskLayoutSpec struct { + DynamicData + + ControllerType string `xml:"controllerType"` + BusNumber int32 `xml:"busNumber"` + UnitNumber *int32 `xml:"unitNumber"` + SrcFilename string `xml:"srcFilename"` + DstFilename string `xml:"dstFilename"` +} + +func init() { + t["HostLowLevelProvisioningManagerDiskLayoutSpec"] = reflect.TypeOf((*HostLowLevelProvisioningManagerDiskLayoutSpec)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerFileDeleteResult struct { + DynamicData + + FileName string `xml:"fileName"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["HostLowLevelProvisioningManagerFileDeleteResult"] = reflect.TypeOf((*HostLowLevelProvisioningManagerFileDeleteResult)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerFileDeleteSpec struct { + DynamicData + + FileName string `xml:"fileName"` + FileType string `xml:"fileType"` +} + +func init() { + t["HostLowLevelProvisioningManagerFileDeleteSpec"] = reflect.TypeOf((*HostLowLevelProvisioningManagerFileDeleteSpec)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerFileReserveResult struct { + DynamicData + + BaseName string `xml:"baseName"` + ParentDir string `xml:"parentDir"` + ReservedName string `xml:"reservedName"` +} + +func init() { + t["HostLowLevelProvisioningManagerFileReserveResult"] = reflect.TypeOf((*HostLowLevelProvisioningManagerFileReserveResult)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerFileReserveSpec struct { + DynamicData + + BaseName string `xml:"baseName"` + ParentDir string `xml:"parentDir"` + FileType string `xml:"fileType"` + StorageProfile string `xml:"storageProfile"` +} + +func init() { + t["HostLowLevelProvisioningManagerFileReserveSpec"] = reflect.TypeOf((*HostLowLevelProvisioningManagerFileReserveSpec)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerSnapshotLayoutSpec struct { + DynamicData + + Id int32 `xml:"id"` + SrcFilename string `xml:"srcFilename"` + DstFilename string `xml:"dstFilename"` + Disk []HostLowLevelProvisioningManagerDiskLayoutSpec `xml:"disk,omitempty"` +} + +func init() { + t["HostLowLevelProvisioningManagerSnapshotLayoutSpec"] = reflect.TypeOf((*HostLowLevelProvisioningManagerSnapshotLayoutSpec)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerVmMigrationStatus struct { + DynamicData + + MigrationId int64 `xml:"migrationId"` + Type string `xml:"type"` + Source bool `xml:"source"` + ConsideredSuccessful bool `xml:"consideredSuccessful"` +} + +func init() { + t["HostLowLevelProvisioningManagerVmMigrationStatus"] = reflect.TypeOf((*HostLowLevelProvisioningManagerVmMigrationStatus)(nil)).Elem() +} + +type HostLowLevelProvisioningManagerVmRecoveryInfo struct { + DynamicData + + Version string `xml:"version"` + BiosUUID string `xml:"biosUUID"` + InstanceUUID string `xml:"instanceUUID"` + FtInfo BaseFaultToleranceConfigInfo `xml:"ftInfo,omitempty,typeattr"` +} + +func init() { + t["HostLowLevelProvisioningManagerVmRecoveryInfo"] = reflect.TypeOf((*HostLowLevelProvisioningManagerVmRecoveryInfo)(nil)).Elem() +} + +type HostMaintenanceSpec struct { + DynamicData + + VsanMode *VsanHostDecommissionMode `xml:"vsanMode,omitempty"` +} + +func init() { + t["HostMaintenanceSpec"] = reflect.TypeOf((*HostMaintenanceSpec)(nil)).Elem() +} + +type HostMemberHealthCheckResult struct { + DynamicData + + Summary string `xml:"summary,omitempty"` +} + +func init() { + t["HostMemberHealthCheckResult"] = reflect.TypeOf((*HostMemberHealthCheckResult)(nil)).Elem() +} + +type HostMemberRuntimeInfo struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Status string `xml:"status,omitempty"` + StatusDetail string `xml:"statusDetail,omitempty"` + HealthCheckResult []BaseHostMemberHealthCheckResult `xml:"healthCheckResult,omitempty,typeattr"` +} + +func init() { + t["HostMemberRuntimeInfo"] = reflect.TypeOf((*HostMemberRuntimeInfo)(nil)).Elem() +} + +type HostMemberUplinkHealthCheckResult struct { + HostMemberHealthCheckResult + + UplinkPortKey string `xml:"uplinkPortKey"` +} + +func init() { + t["HostMemberUplinkHealthCheckResult"] = reflect.TypeOf((*HostMemberUplinkHealthCheckResult)(nil)).Elem() +} + +type HostMemoryProfile struct { + ApplyProfile +} + +func init() { + t["HostMemoryProfile"] = reflect.TypeOf((*HostMemoryProfile)(nil)).Elem() +} + +type HostMemorySpec struct { + DynamicData + + ServiceConsoleReservation int64 `xml:"serviceConsoleReservation,omitempty"` +} + +func init() { + t["HostMemorySpec"] = reflect.TypeOf((*HostMemorySpec)(nil)).Elem() +} + +type HostMissingNetworksEvent struct { + HostDasEvent + + Ips string `xml:"ips,omitempty"` +} + +func init() { + t["HostMissingNetworksEvent"] = reflect.TypeOf((*HostMissingNetworksEvent)(nil)).Elem() +} + +type HostMonitoringStateChangedEvent struct { + ClusterEvent + + State string `xml:"state"` +} + +func init() { + t["HostMonitoringStateChangedEvent"] = reflect.TypeOf((*HostMonitoringStateChangedEvent)(nil)).Elem() +} + +type HostMountInfo struct { + DynamicData + + Path string `xml:"path,omitempty"` + AccessMode string `xml:"accessMode"` + Mounted *bool `xml:"mounted"` + Accessible *bool `xml:"accessible"` + InaccessibleReason string `xml:"inaccessibleReason,omitempty"` +} + +func init() { + t["HostMountInfo"] = reflect.TypeOf((*HostMountInfo)(nil)).Elem() +} + +type HostMultipathInfo struct { + DynamicData + + Lun []HostMultipathInfoLogicalUnit `xml:"lun,omitempty"` +} + +func init() { + t["HostMultipathInfo"] = reflect.TypeOf((*HostMultipathInfo)(nil)).Elem() +} + +type HostMultipathInfoFixedLogicalUnitPolicy struct { + HostMultipathInfoLogicalUnitPolicy + + Prefer string `xml:"prefer"` +} + +func init() { + t["HostMultipathInfoFixedLogicalUnitPolicy"] = reflect.TypeOf((*HostMultipathInfoFixedLogicalUnitPolicy)(nil)).Elem() +} + +type HostMultipathInfoLogicalUnit struct { + DynamicData + + Key string `xml:"key"` + Id string `xml:"id"` + Lun string `xml:"lun"` + Path []HostMultipathInfoPath `xml:"path"` + Policy BaseHostMultipathInfoLogicalUnitPolicy `xml:"policy,typeattr"` + StorageArrayTypePolicy *HostMultipathInfoLogicalUnitStorageArrayTypePolicy `xml:"storageArrayTypePolicy,omitempty"` +} + +func init() { + t["HostMultipathInfoLogicalUnit"] = reflect.TypeOf((*HostMultipathInfoLogicalUnit)(nil)).Elem() +} + +type HostMultipathInfoLogicalUnitPolicy struct { + DynamicData + + Policy string `xml:"policy"` +} + +func init() { + t["HostMultipathInfoLogicalUnitPolicy"] = reflect.TypeOf((*HostMultipathInfoLogicalUnitPolicy)(nil)).Elem() +} + +type HostMultipathInfoLogicalUnitStorageArrayTypePolicy struct { + DynamicData + + Policy string `xml:"policy"` +} + +func init() { + t["HostMultipathInfoLogicalUnitStorageArrayTypePolicy"] = reflect.TypeOf((*HostMultipathInfoLogicalUnitStorageArrayTypePolicy)(nil)).Elem() +} + +type HostMultipathInfoPath struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name"` + PathState string `xml:"pathState"` + State string `xml:"state,omitempty"` + IsWorkingPath *bool `xml:"isWorkingPath"` + Adapter string `xml:"adapter"` + Lun string `xml:"lun"` + Transport BaseHostTargetTransport `xml:"transport,omitempty,typeattr"` +} + +func init() { + t["HostMultipathInfoPath"] = reflect.TypeOf((*HostMultipathInfoPath)(nil)).Elem() +} + +type HostMultipathStateInfo struct { + DynamicData + + Path []HostMultipathStateInfoPath `xml:"path,omitempty"` +} + +func init() { + t["HostMultipathStateInfo"] = reflect.TypeOf((*HostMultipathStateInfo)(nil)).Elem() +} + +type HostMultipathStateInfoPath struct { + DynamicData + + Name string `xml:"name"` + PathState string `xml:"pathState"` +} + +func init() { + t["HostMultipathStateInfoPath"] = reflect.TypeOf((*HostMultipathStateInfoPath)(nil)).Elem() +} + +type HostNasVolume struct { + HostFileSystemVolume + + RemoteHost string `xml:"remoteHost"` + RemotePath string `xml:"remotePath"` + UserName string `xml:"userName,omitempty"` + RemoteHostNames []string `xml:"remoteHostNames,omitempty"` + SecurityType string `xml:"securityType,omitempty"` + ProtocolEndpoint *bool `xml:"protocolEndpoint"` +} + +func init() { + t["HostNasVolume"] = reflect.TypeOf((*HostNasVolume)(nil)).Elem() +} + +type HostNasVolumeConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Spec *HostNasVolumeSpec `xml:"spec,omitempty"` +} + +func init() { + t["HostNasVolumeConfig"] = reflect.TypeOf((*HostNasVolumeConfig)(nil)).Elem() +} + +type HostNasVolumeSpec struct { + DynamicData + + RemoteHost string `xml:"remoteHost"` + RemotePath string `xml:"remotePath"` + LocalPath string `xml:"localPath"` + AccessMode string `xml:"accessMode"` + Type string `xml:"type,omitempty"` + UserName string `xml:"userName,omitempty"` + Password string `xml:"password,omitempty"` + RemoteHostNames []string `xml:"remoteHostNames,omitempty"` + SecurityType string `xml:"securityType,omitempty"` +} + +func init() { + t["HostNasVolumeSpec"] = reflect.TypeOf((*HostNasVolumeSpec)(nil)).Elem() +} + +type HostNasVolumeUserInfo struct { + DynamicData + + User string `xml:"user"` +} + +func init() { + t["HostNasVolumeUserInfo"] = reflect.TypeOf((*HostNasVolumeUserInfo)(nil)).Elem() +} + +type HostNatService struct { + DynamicData + + Key string `xml:"key"` + Spec HostNatServiceSpec `xml:"spec"` +} + +func init() { + t["HostNatService"] = reflect.TypeOf((*HostNatService)(nil)).Elem() +} + +type HostNatServiceConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Key string `xml:"key"` + Spec HostNatServiceSpec `xml:"spec"` +} + +func init() { + t["HostNatServiceConfig"] = reflect.TypeOf((*HostNatServiceConfig)(nil)).Elem() +} + +type HostNatServiceNameServiceSpec struct { + DynamicData + + DnsAutoDetect bool `xml:"dnsAutoDetect"` + DnsPolicy string `xml:"dnsPolicy"` + DnsRetries int32 `xml:"dnsRetries"` + DnsTimeout int32 `xml:"dnsTimeout"` + DnsNameServer []string `xml:"dnsNameServer,omitempty"` + NbdsTimeout int32 `xml:"nbdsTimeout"` + NbnsRetries int32 `xml:"nbnsRetries"` + NbnsTimeout int32 `xml:"nbnsTimeout"` +} + +func init() { + t["HostNatServiceNameServiceSpec"] = reflect.TypeOf((*HostNatServiceNameServiceSpec)(nil)).Elem() +} + +type HostNatServicePortForwardSpec struct { + DynamicData + + Type string `xml:"type"` + Name string `xml:"name"` + HostPort int32 `xml:"hostPort"` + GuestPort int32 `xml:"guestPort"` + GuestIpAddress string `xml:"guestIpAddress"` +} + +func init() { + t["HostNatServicePortForwardSpec"] = reflect.TypeOf((*HostNatServicePortForwardSpec)(nil)).Elem() +} + +type HostNatServiceSpec struct { + DynamicData + + VirtualSwitch string `xml:"virtualSwitch"` + ActiveFtp bool `xml:"activeFtp"` + AllowAnyOui bool `xml:"allowAnyOui"` + ConfigPort bool `xml:"configPort"` + IpGatewayAddress string `xml:"ipGatewayAddress"` + UdpTimeout int32 `xml:"udpTimeout"` + PortForward []HostNatServicePortForwardSpec `xml:"portForward,omitempty"` + NameService *HostNatServiceNameServiceSpec `xml:"nameService,omitempty"` +} + +func init() { + t["HostNatServiceSpec"] = reflect.TypeOf((*HostNatServiceSpec)(nil)).Elem() +} + +type HostNetCapabilities struct { + DynamicData + + CanSetPhysicalNicLinkSpeed bool `xml:"canSetPhysicalNicLinkSpeed"` + SupportsNicTeaming bool `xml:"supportsNicTeaming"` + NicTeamingPolicy []string `xml:"nicTeamingPolicy,omitempty"` + SupportsVlan bool `xml:"supportsVlan"` + UsesServiceConsoleNic bool `xml:"usesServiceConsoleNic"` + SupportsNetworkHints bool `xml:"supportsNetworkHints"` + MaxPortGroupsPerVswitch int32 `xml:"maxPortGroupsPerVswitch,omitempty"` + VswitchConfigSupported bool `xml:"vswitchConfigSupported"` + VnicConfigSupported bool `xml:"vnicConfigSupported"` + IpRouteConfigSupported bool `xml:"ipRouteConfigSupported"` + DnsConfigSupported bool `xml:"dnsConfigSupported"` + DhcpOnVnicSupported bool `xml:"dhcpOnVnicSupported"` + IpV6Supported *bool `xml:"ipV6Supported"` +} + +func init() { + t["HostNetCapabilities"] = reflect.TypeOf((*HostNetCapabilities)(nil)).Elem() +} + +type HostNetOffloadCapabilities struct { + DynamicData + + CsumOffload *bool `xml:"csumOffload"` + TcpSegmentation *bool `xml:"tcpSegmentation"` + ZeroCopyXmit *bool `xml:"zeroCopyXmit"` +} + +func init() { + t["HostNetOffloadCapabilities"] = reflect.TypeOf((*HostNetOffloadCapabilities)(nil)).Elem() +} + +type HostNetStackInstance struct { + DynamicData + + Key string `xml:"key,omitempty"` + Name string `xml:"name,omitempty"` + DnsConfig BaseHostDnsConfig `xml:"dnsConfig,omitempty,typeattr"` + IpRouteConfig BaseHostIpRouteConfig `xml:"ipRouteConfig,omitempty,typeattr"` + RequestedMaxNumberOfConnections int32 `xml:"requestedMaxNumberOfConnections,omitempty"` + CongestionControlAlgorithm string `xml:"congestionControlAlgorithm,omitempty"` + IpV6Enabled *bool `xml:"ipV6Enabled"` + RouteTableConfig *HostIpRouteTableConfig `xml:"routeTableConfig,omitempty"` +} + +func init() { + t["HostNetStackInstance"] = reflect.TypeOf((*HostNetStackInstance)(nil)).Elem() +} + +type HostNetworkConfig struct { + DynamicData + + Vswitch []HostVirtualSwitchConfig `xml:"vswitch,omitempty"` + ProxySwitch []HostProxySwitchConfig `xml:"proxySwitch,omitempty"` + Portgroup []HostPortGroupConfig `xml:"portgroup,omitempty"` + Pnic []PhysicalNicConfig `xml:"pnic,omitempty"` + Vnic []HostVirtualNicConfig `xml:"vnic,omitempty"` + ConsoleVnic []HostVirtualNicConfig `xml:"consoleVnic,omitempty"` + DnsConfig BaseHostDnsConfig `xml:"dnsConfig,omitempty,typeattr"` + IpRouteConfig BaseHostIpRouteConfig `xml:"ipRouteConfig,omitempty,typeattr"` + ConsoleIpRouteConfig BaseHostIpRouteConfig `xml:"consoleIpRouteConfig,omitempty,typeattr"` + RouteTableConfig *HostIpRouteTableConfig `xml:"routeTableConfig,omitempty"` + Dhcp []HostDhcpServiceConfig `xml:"dhcp,omitempty"` + Nat []HostNatServiceConfig `xml:"nat,omitempty"` + IpV6Enabled *bool `xml:"ipV6Enabled"` + NetStackSpec []HostNetworkConfigNetStackSpec `xml:"netStackSpec,omitempty"` +} + +func init() { + t["HostNetworkConfig"] = reflect.TypeOf((*HostNetworkConfig)(nil)).Elem() +} + +type HostNetworkConfigNetStackSpec struct { + DynamicData + + NetStackInstance HostNetStackInstance `xml:"netStackInstance"` + Operation string `xml:"operation,omitempty"` +} + +func init() { + t["HostNetworkConfigNetStackSpec"] = reflect.TypeOf((*HostNetworkConfigNetStackSpec)(nil)).Elem() +} + +type HostNetworkConfigResult struct { + DynamicData + + VnicDevice []string `xml:"vnicDevice,omitempty"` + ConsoleVnicDevice []string `xml:"consoleVnicDevice,omitempty"` +} + +func init() { + t["HostNetworkConfigResult"] = reflect.TypeOf((*HostNetworkConfigResult)(nil)).Elem() +} + +type HostNetworkInfo struct { + DynamicData + + Vswitch []HostVirtualSwitch `xml:"vswitch,omitempty"` + ProxySwitch []HostProxySwitch `xml:"proxySwitch,omitempty"` + Portgroup []HostPortGroup `xml:"portgroup,omitempty"` + Pnic []PhysicalNic `xml:"pnic,omitempty"` + Vnic []HostVirtualNic `xml:"vnic,omitempty"` + ConsoleVnic []HostVirtualNic `xml:"consoleVnic,omitempty"` + DnsConfig BaseHostDnsConfig `xml:"dnsConfig,omitempty,typeattr"` + IpRouteConfig BaseHostIpRouteConfig `xml:"ipRouteConfig,omitempty,typeattr"` + ConsoleIpRouteConfig BaseHostIpRouteConfig `xml:"consoleIpRouteConfig,omitempty,typeattr"` + RouteTableInfo *HostIpRouteTableInfo `xml:"routeTableInfo,omitempty"` + Dhcp []HostDhcpService `xml:"dhcp,omitempty"` + Nat []HostNatService `xml:"nat,omitempty"` + IpV6Enabled *bool `xml:"ipV6Enabled"` + AtBootIpV6Enabled *bool `xml:"atBootIpV6Enabled"` + NetStackInstance []HostNetStackInstance `xml:"netStackInstance,omitempty"` + OpaqueSwitch []HostOpaqueSwitch `xml:"opaqueSwitch,omitempty"` + OpaqueNetwork []HostOpaqueNetworkInfo `xml:"opaqueNetwork,omitempty"` +} + +func init() { + t["HostNetworkInfo"] = reflect.TypeOf((*HostNetworkInfo)(nil)).Elem() +} + +type HostNetworkPolicy struct { + DynamicData + + Security *HostNetworkSecurityPolicy `xml:"security,omitempty"` + NicTeaming *HostNicTeamingPolicy `xml:"nicTeaming,omitempty"` + OffloadPolicy *HostNetOffloadCapabilities `xml:"offloadPolicy,omitempty"` + ShapingPolicy *HostNetworkTrafficShapingPolicy `xml:"shapingPolicy,omitempty"` +} + +func init() { + t["HostNetworkPolicy"] = reflect.TypeOf((*HostNetworkPolicy)(nil)).Elem() +} + +type HostNetworkResourceRuntime struct { + DynamicData + + PnicResourceInfo []HostPnicNetworkResourceInfo `xml:"pnicResourceInfo"` +} + +func init() { + t["HostNetworkResourceRuntime"] = reflect.TypeOf((*HostNetworkResourceRuntime)(nil)).Elem() +} + +type HostNetworkSecurityPolicy struct { + DynamicData + + AllowPromiscuous *bool `xml:"allowPromiscuous"` + MacChanges *bool `xml:"macChanges"` + ForgedTransmits *bool `xml:"forgedTransmits"` +} + +func init() { + t["HostNetworkSecurityPolicy"] = reflect.TypeOf((*HostNetworkSecurityPolicy)(nil)).Elem() +} + +type HostNetworkTrafficShapingPolicy struct { + DynamicData + + Enabled *bool `xml:"enabled"` + AverageBandwidth int64 `xml:"averageBandwidth,omitempty"` + PeakBandwidth int64 `xml:"peakBandwidth,omitempty"` + BurstSize int64 `xml:"burstSize,omitempty"` +} + +func init() { + t["HostNetworkTrafficShapingPolicy"] = reflect.TypeOf((*HostNetworkTrafficShapingPolicy)(nil)).Elem() +} + +type HostNewNetworkConnectInfo struct { + HostConnectInfoNetworkInfo +} + +func init() { + t["HostNewNetworkConnectInfo"] = reflect.TypeOf((*HostNewNetworkConnectInfo)(nil)).Elem() +} + +type HostNicFailureCriteria struct { + DynamicData + + CheckSpeed string `xml:"checkSpeed,omitempty"` + Speed int32 `xml:"speed,omitempty"` + CheckDuplex *bool `xml:"checkDuplex"` + FullDuplex *bool `xml:"fullDuplex"` + CheckErrorPercent *bool `xml:"checkErrorPercent"` + Percentage int32 `xml:"percentage,omitempty"` + CheckBeacon *bool `xml:"checkBeacon"` +} + +func init() { + t["HostNicFailureCriteria"] = reflect.TypeOf((*HostNicFailureCriteria)(nil)).Elem() +} + +type HostNicOrderPolicy struct { + DynamicData + + ActiveNic []string `xml:"activeNic,omitempty"` + StandbyNic []string `xml:"standbyNic,omitempty"` +} + +func init() { + t["HostNicOrderPolicy"] = reflect.TypeOf((*HostNicOrderPolicy)(nil)).Elem() +} + +type HostNicTeamingPolicy struct { + DynamicData + + Policy string `xml:"policy,omitempty"` + ReversePolicy *bool `xml:"reversePolicy"` + NotifySwitches *bool `xml:"notifySwitches"` + RollingOrder *bool `xml:"rollingOrder"` + FailureCriteria *HostNicFailureCriteria `xml:"failureCriteria,omitempty"` + NicOrder *HostNicOrderPolicy `xml:"nicOrder,omitempty"` +} + +func init() { + t["HostNicTeamingPolicy"] = reflect.TypeOf((*HostNicTeamingPolicy)(nil)).Elem() +} + +type HostNoAvailableNetworksEvent struct { + HostDasEvent + + Ips string `xml:"ips,omitempty"` +} + +func init() { + t["HostNoAvailableNetworksEvent"] = reflect.TypeOf((*HostNoAvailableNetworksEvent)(nil)).Elem() +} + +type HostNoHAEnabledPortGroupsEvent struct { + HostDasEvent +} + +func init() { + t["HostNoHAEnabledPortGroupsEvent"] = reflect.TypeOf((*HostNoHAEnabledPortGroupsEvent)(nil)).Elem() +} + +type HostNoRedundantManagementNetworkEvent struct { + HostDasEvent +} + +func init() { + t["HostNoRedundantManagementNetworkEvent"] = reflect.TypeOf((*HostNoRedundantManagementNetworkEvent)(nil)).Elem() +} + +type HostNonCompliantEvent struct { + HostEvent +} + +func init() { + t["HostNonCompliantEvent"] = reflect.TypeOf((*HostNonCompliantEvent)(nil)).Elem() +} + +type HostNotConnected struct { + HostCommunication +} + +func init() { + t["HostNotConnected"] = reflect.TypeOf((*HostNotConnected)(nil)).Elem() +} + +type HostNotConnectedFault HostNotConnected + +func init() { + t["HostNotConnectedFault"] = reflect.TypeOf((*HostNotConnectedFault)(nil)).Elem() +} + +type HostNotInClusterEvent struct { + HostDasEvent +} + +func init() { + t["HostNotInClusterEvent"] = reflect.TypeOf((*HostNotInClusterEvent)(nil)).Elem() +} + +type HostNotReachable struct { + HostCommunication +} + +func init() { + t["HostNotReachable"] = reflect.TypeOf((*HostNotReachable)(nil)).Elem() +} + +type HostNotReachableFault HostNotReachable + +func init() { + t["HostNotReachableFault"] = reflect.TypeOf((*HostNotReachableFault)(nil)).Elem() +} + +type HostNtpConfig struct { + DynamicData + + Server []string `xml:"server,omitempty"` + ConfigFile []string `xml:"configFile,omitempty"` +} + +func init() { + t["HostNtpConfig"] = reflect.TypeOf((*HostNtpConfig)(nil)).Elem() +} + +type HostNumaInfo struct { + DynamicData + + Type string `xml:"type"` + NumNodes int32 `xml:"numNodes"` + NumaNode []HostNumaNode `xml:"numaNode,omitempty"` +} + +func init() { + t["HostNumaInfo"] = reflect.TypeOf((*HostNumaInfo)(nil)).Elem() +} + +type HostNumaNode struct { + DynamicData + + TypeId byte `xml:"typeId"` + CpuID []int16 `xml:"cpuID"` + MemoryRangeBegin int64 `xml:"memoryRangeBegin"` + MemoryRangeLength int64 `xml:"memoryRangeLength"` +} + +func init() { + t["HostNumaNode"] = reflect.TypeOf((*HostNumaNode)(nil)).Elem() +} + +type HostNumericSensorInfo struct { + DynamicData + + Name string `xml:"name"` + HealthState BaseElementDescription `xml:"healthState,omitempty,typeattr"` + CurrentReading int64 `xml:"currentReading"` + UnitModifier int32 `xml:"unitModifier"` + BaseUnits string `xml:"baseUnits"` + RateUnits string `xml:"rateUnits,omitempty"` + SensorType string `xml:"sensorType"` +} + +func init() { + t["HostNumericSensorInfo"] = reflect.TypeOf((*HostNumericSensorInfo)(nil)).Elem() +} + +type HostOpaqueNetworkInfo struct { + DynamicData + + OpaqueNetworkId string `xml:"opaqueNetworkId"` + OpaqueNetworkName string `xml:"opaqueNetworkName"` + OpaqueNetworkType string `xml:"opaqueNetworkType"` + PnicZone []string `xml:"pnicZone,omitempty"` +} + +func init() { + t["HostOpaqueNetworkInfo"] = reflect.TypeOf((*HostOpaqueNetworkInfo)(nil)).Elem() +} + +type HostOpaqueSwitch struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name,omitempty"` + Pnic []string `xml:"pnic,omitempty"` + PnicZone []HostOpaqueSwitchPhysicalNicZone `xml:"pnicZone,omitempty"` + Status string `xml:"status,omitempty"` + Vtep []HostVirtualNic `xml:"vtep,omitempty"` +} + +func init() { + t["HostOpaqueSwitch"] = reflect.TypeOf((*HostOpaqueSwitch)(nil)).Elem() +} + +type HostOpaqueSwitchPhysicalNicZone struct { + DynamicData + + Key string `xml:"key"` + PnicDevice []string `xml:"pnicDevice,omitempty"` +} + +func init() { + t["HostOpaqueSwitchPhysicalNicZone"] = reflect.TypeOf((*HostOpaqueSwitchPhysicalNicZone)(nil)).Elem() +} + +type HostOvercommittedEvent struct { + ClusterOvercommittedEvent +} + +func init() { + t["HostOvercommittedEvent"] = reflect.TypeOf((*HostOvercommittedEvent)(nil)).Elem() +} + +type HostParallelScsiHba struct { + HostHostBusAdapter +} + +func init() { + t["HostParallelScsiHba"] = reflect.TypeOf((*HostParallelScsiHba)(nil)).Elem() +} + +type HostParallelScsiTargetTransport struct { + HostTargetTransport +} + +func init() { + t["HostParallelScsiTargetTransport"] = reflect.TypeOf((*HostParallelScsiTargetTransport)(nil)).Elem() +} + +type HostPatchManagerLocator struct { + DynamicData + + Url string `xml:"url"` + Proxy string `xml:"proxy,omitempty"` +} + +func init() { + t["HostPatchManagerLocator"] = reflect.TypeOf((*HostPatchManagerLocator)(nil)).Elem() +} + +type HostPatchManagerPatchManagerOperationSpec struct { + DynamicData + + Proxy string `xml:"proxy,omitempty"` + Port int32 `xml:"port,omitempty"` + UserName string `xml:"userName,omitempty"` + Password string `xml:"password,omitempty"` + CmdOption string `xml:"cmdOption,omitempty"` +} + +func init() { + t["HostPatchManagerPatchManagerOperationSpec"] = reflect.TypeOf((*HostPatchManagerPatchManagerOperationSpec)(nil)).Elem() +} + +type HostPatchManagerResult struct { + DynamicData + + Version string `xml:"version"` + Status []HostPatchManagerStatus `xml:"status,omitempty"` + XmlResult string `xml:"xmlResult,omitempty"` +} + +func init() { + t["HostPatchManagerResult"] = reflect.TypeOf((*HostPatchManagerResult)(nil)).Elem() +} + +type HostPatchManagerStatus struct { + DynamicData + + Id string `xml:"id"` + Applicable bool `xml:"applicable"` + Reason []string `xml:"reason,omitempty"` + Integrity string `xml:"integrity,omitempty"` + Installed bool `xml:"installed"` + InstallState []string `xml:"installState,omitempty"` + PrerequisitePatch []HostPatchManagerStatusPrerequisitePatch `xml:"prerequisitePatch,omitempty"` + RestartRequired bool `xml:"restartRequired"` + ReconnectRequired bool `xml:"reconnectRequired"` + VmOffRequired bool `xml:"vmOffRequired"` + SupersededPatchIds []string `xml:"supersededPatchIds,omitempty"` +} + +func init() { + t["HostPatchManagerStatus"] = reflect.TypeOf((*HostPatchManagerStatus)(nil)).Elem() +} + +type HostPatchManagerStatusPrerequisitePatch struct { + DynamicData + + Id string `xml:"id"` + InstallState []string `xml:"installState,omitempty"` +} + +func init() { + t["HostPatchManagerStatusPrerequisitePatch"] = reflect.TypeOf((*HostPatchManagerStatusPrerequisitePatch)(nil)).Elem() +} + +type HostPathSelectionPolicyOption struct { + DynamicData + + Policy BaseElementDescription `xml:"policy,typeattr"` +} + +func init() { + t["HostPathSelectionPolicyOption"] = reflect.TypeOf((*HostPathSelectionPolicyOption)(nil)).Elem() +} + +type HostPciDevice struct { + DynamicData + + Id string `xml:"id"` + ClassId int16 `xml:"classId"` + Bus byte `xml:"bus"` + Slot byte `xml:"slot"` + Function byte `xml:"function"` + VendorId int16 `xml:"vendorId"` + SubVendorId int16 `xml:"subVendorId"` + VendorName string `xml:"vendorName"` + DeviceId int16 `xml:"deviceId"` + SubDeviceId int16 `xml:"subDeviceId"` + ParentBridge string `xml:"parentBridge,omitempty"` + DeviceName string `xml:"deviceName"` +} + +func init() { + t["HostPciDevice"] = reflect.TypeOf((*HostPciDevice)(nil)).Elem() +} + +type HostPciPassthruConfig struct { + DynamicData + + Id string `xml:"id"` + PassthruEnabled bool `xml:"passthruEnabled"` +} + +func init() { + t["HostPciPassthruConfig"] = reflect.TypeOf((*HostPciPassthruConfig)(nil)).Elem() +} + +type HostPciPassthruInfo struct { + DynamicData + + Id string `xml:"id"` + DependentDevice string `xml:"dependentDevice"` + PassthruEnabled bool `xml:"passthruEnabled"` + PassthruCapable bool `xml:"passthruCapable"` + PassthruActive bool `xml:"passthruActive"` +} + +func init() { + t["HostPciPassthruInfo"] = reflect.TypeOf((*HostPciPassthruInfo)(nil)).Elem() +} + +type HostPlacedVirtualNicIdentifier struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + VnicKey string `xml:"vnicKey"` + Reservation int32 `xml:"reservation,omitempty"` +} + +func init() { + t["HostPlacedVirtualNicIdentifier"] = reflect.TypeOf((*HostPlacedVirtualNicIdentifier)(nil)).Elem() +} + +type HostPlugStoreTopology struct { + DynamicData + + Adapter []HostPlugStoreTopologyAdapter `xml:"adapter,omitempty"` + Path []HostPlugStoreTopologyPath `xml:"path,omitempty"` + Target []HostPlugStoreTopologyTarget `xml:"target,omitempty"` + Device []HostPlugStoreTopologyDevice `xml:"device,omitempty"` + Plugin []HostPlugStoreTopologyPlugin `xml:"plugin,omitempty"` +} + +func init() { + t["HostPlugStoreTopology"] = reflect.TypeOf((*HostPlugStoreTopology)(nil)).Elem() +} + +type HostPlugStoreTopologyAdapter struct { + DynamicData + + Key string `xml:"key"` + Adapter string `xml:"adapter"` + Path []string `xml:"path,omitempty"` +} + +func init() { + t["HostPlugStoreTopologyAdapter"] = reflect.TypeOf((*HostPlugStoreTopologyAdapter)(nil)).Elem() +} + +type HostPlugStoreTopologyDevice struct { + DynamicData + + Key string `xml:"key"` + Lun string `xml:"lun"` + Path []string `xml:"path,omitempty"` +} + +func init() { + t["HostPlugStoreTopologyDevice"] = reflect.TypeOf((*HostPlugStoreTopologyDevice)(nil)).Elem() +} + +type HostPlugStoreTopologyPath struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name"` + ChannelNumber int32 `xml:"channelNumber,omitempty"` + TargetNumber int32 `xml:"targetNumber,omitempty"` + LunNumber int32 `xml:"lunNumber,omitempty"` + Adapter string `xml:"adapter,omitempty"` + Target string `xml:"target,omitempty"` + Device string `xml:"device,omitempty"` +} + +func init() { + t["HostPlugStoreTopologyPath"] = reflect.TypeOf((*HostPlugStoreTopologyPath)(nil)).Elem() +} + +type HostPlugStoreTopologyPlugin struct { + DynamicData + + Key string `xml:"key"` + Name string `xml:"name"` + Device []string `xml:"device,omitempty"` + ClaimedPath []string `xml:"claimedPath,omitempty"` +} + +func init() { + t["HostPlugStoreTopologyPlugin"] = reflect.TypeOf((*HostPlugStoreTopologyPlugin)(nil)).Elem() +} + +type HostPlugStoreTopologyTarget struct { + DynamicData + + Key string `xml:"key"` + Transport BaseHostTargetTransport `xml:"transport,omitempty,typeattr"` +} + +func init() { + t["HostPlugStoreTopologyTarget"] = reflect.TypeOf((*HostPlugStoreTopologyTarget)(nil)).Elem() +} + +type HostPnicNetworkResourceInfo struct { + DynamicData + + PnicDevice string `xml:"pnicDevice"` + AvailableBandwidthForVMTraffic int64 `xml:"availableBandwidthForVMTraffic,omitempty"` + UnusedBandwidthForVMTraffic int64 `xml:"unusedBandwidthForVMTraffic,omitempty"` + PlacedVirtualNics []HostPlacedVirtualNicIdentifier `xml:"placedVirtualNics,omitempty"` +} + +func init() { + t["HostPnicNetworkResourceInfo"] = reflect.TypeOf((*HostPnicNetworkResourceInfo)(nil)).Elem() +} + +type HostPortGroup struct { + DynamicData + + Key string `xml:"key,omitempty"` + Port []HostPortGroupPort `xml:"port,omitempty"` + Vswitch string `xml:"vswitch,omitempty"` + ComputedPolicy HostNetworkPolicy `xml:"computedPolicy"` + Spec HostPortGroupSpec `xml:"spec"` +} + +func init() { + t["HostPortGroup"] = reflect.TypeOf((*HostPortGroup)(nil)).Elem() +} + +type HostPortGroupConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Spec *HostPortGroupSpec `xml:"spec,omitempty"` +} + +func init() { + t["HostPortGroupConfig"] = reflect.TypeOf((*HostPortGroupConfig)(nil)).Elem() +} + +type HostPortGroupPort struct { + DynamicData + + Key string `xml:"key,omitempty"` + Mac []string `xml:"mac,omitempty"` + Type string `xml:"type"` +} + +func init() { + t["HostPortGroupPort"] = reflect.TypeOf((*HostPortGroupPort)(nil)).Elem() +} + +type HostPortGroupProfile struct { + PortGroupProfile + + IpConfig IpAddressProfile `xml:"ipConfig"` +} + +func init() { + t["HostPortGroupProfile"] = reflect.TypeOf((*HostPortGroupProfile)(nil)).Elem() +} + +type HostPortGroupSpec struct { + DynamicData + + Name string `xml:"name"` + VlanId int32 `xml:"vlanId"` + VswitchName string `xml:"vswitchName"` + Policy HostNetworkPolicy `xml:"policy"` +} + +func init() { + t["HostPortGroupSpec"] = reflect.TypeOf((*HostPortGroupSpec)(nil)).Elem() +} + +type HostPosixAccountSpec struct { + HostAccountSpec + + PosixId int32 `xml:"posixId,omitempty"` + ShellAccess *bool `xml:"shellAccess"` +} + +func init() { + t["HostPosixAccountSpec"] = reflect.TypeOf((*HostPosixAccountSpec)(nil)).Elem() +} + +type HostPowerOpFailed struct { + VimFault +} + +func init() { + t["HostPowerOpFailed"] = reflect.TypeOf((*HostPowerOpFailed)(nil)).Elem() +} + +type HostPowerOpFailedFault BaseHostPowerOpFailed + +func init() { + t["HostPowerOpFailedFault"] = reflect.TypeOf((*HostPowerOpFailedFault)(nil)).Elem() +} + +type HostPowerPolicy struct { + DynamicData + + Key int32 `xml:"key"` + Name string `xml:"name"` + ShortName string `xml:"shortName"` + Description string `xml:"description"` +} + +func init() { + t["HostPowerPolicy"] = reflect.TypeOf((*HostPowerPolicy)(nil)).Elem() +} + +type HostPrimaryAgentNotShortNameEvent struct { + HostDasEvent + + PrimaryAgent string `xml:"primaryAgent"` +} + +func init() { + t["HostPrimaryAgentNotShortNameEvent"] = reflect.TypeOf((*HostPrimaryAgentNotShortNameEvent)(nil)).Elem() +} + +type HostProfileAppliedEvent struct { + HostEvent + + Profile ProfileEventArgument `xml:"profile"` +} + +func init() { + t["HostProfileAppliedEvent"] = reflect.TypeOf((*HostProfileAppliedEvent)(nil)).Elem() +} + +type HostProfileCompleteConfigSpec struct { + HostProfileConfigSpec + + ApplyProfile *HostApplyProfile `xml:"applyProfile,omitempty"` + CustomComplyProfile *ComplianceProfile `xml:"customComplyProfile,omitempty"` + DisabledExpressionListChanged bool `xml:"disabledExpressionListChanged"` + DisabledExpressionList []string `xml:"disabledExpressionList,omitempty"` + ValidatorHost *ManagedObjectReference `xml:"validatorHost,omitempty"` + Validating *bool `xml:"validating"` +} + +func init() { + t["HostProfileCompleteConfigSpec"] = reflect.TypeOf((*HostProfileCompleteConfigSpec)(nil)).Elem() +} + +type HostProfileConfigInfo struct { + ProfileConfigInfo + + ApplyProfile *HostApplyProfile `xml:"applyProfile,omitempty"` + DefaultComplyProfile *ComplianceProfile `xml:"defaultComplyProfile,omitempty"` + DefaultComplyLocator []ComplianceLocator `xml:"defaultComplyLocator,omitempty"` + CustomComplyProfile *ComplianceProfile `xml:"customComplyProfile,omitempty"` + DisabledExpressionList []string `xml:"disabledExpressionList,omitempty"` +} + +func init() { + t["HostProfileConfigInfo"] = reflect.TypeOf((*HostProfileConfigInfo)(nil)).Elem() +} + +type HostProfileConfigSpec struct { + ProfileCreateSpec +} + +func init() { + t["HostProfileConfigSpec"] = reflect.TypeOf((*HostProfileConfigSpec)(nil)).Elem() +} + +type HostProfileHostBasedConfigSpec struct { + HostProfileConfigSpec + + Host ManagedObjectReference `xml:"host"` + UseHostProfileEngine *bool `xml:"useHostProfileEngine"` +} + +func init() { + t["HostProfileHostBasedConfigSpec"] = reflect.TypeOf((*HostProfileHostBasedConfigSpec)(nil)).Elem() +} + +type HostProfileManagerConfigTaskList struct { + DynamicData + + ConfigSpec *HostConfigSpec `xml:"configSpec,omitempty"` + TaskDescription []LocalizableMessage `xml:"taskDescription,omitempty"` + TaskListRequirement []string `xml:"taskListRequirement,omitempty"` +} + +func init() { + t["HostProfileManagerConfigTaskList"] = reflect.TypeOf((*HostProfileManagerConfigTaskList)(nil)).Elem() +} + +type HostProfileSerializedHostProfileSpec struct { + ProfileSerializedCreateSpec + + ValidatorHost *ManagedObjectReference `xml:"validatorHost,omitempty"` + Validating *bool `xml:"validating"` +} + +func init() { + t["HostProfileSerializedHostProfileSpec"] = reflect.TypeOf((*HostProfileSerializedHostProfileSpec)(nil)).Elem() +} + +type HostProtocolEndpoint struct { + DynamicData + + PeType string `xml:"peType"` + Uuid string `xml:"uuid"` + HostKey []ManagedObjectReference `xml:"hostKey,omitempty"` + StorageArray string `xml:"storageArray,omitempty"` + NfsServer string `xml:"nfsServer,omitempty"` + NfsDir string `xml:"nfsDir,omitempty"` + DeviceId string `xml:"deviceId,omitempty"` +} + +func init() { + t["HostProtocolEndpoint"] = reflect.TypeOf((*HostProtocolEndpoint)(nil)).Elem() +} + +type HostProxySwitch struct { + DynamicData + + DvsUuid string `xml:"dvsUuid"` + DvsName string `xml:"dvsName"` + Key string `xml:"key"` + NumPorts int32 `xml:"numPorts"` + ConfigNumPorts int32 `xml:"configNumPorts,omitempty"` + NumPortsAvailable int32 `xml:"numPortsAvailable"` + UplinkPort []KeyValue `xml:"uplinkPort,omitempty"` + Mtu int32 `xml:"mtu,omitempty"` + Pnic []string `xml:"pnic,omitempty"` + Spec HostProxySwitchSpec `xml:"spec"` + HostLag []HostProxySwitchHostLagConfig `xml:"hostLag,omitempty"` + NetworkReservationSupported *bool `xml:"networkReservationSupported"` +} + +func init() { + t["HostProxySwitch"] = reflect.TypeOf((*HostProxySwitch)(nil)).Elem() +} + +type HostProxySwitchConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Uuid string `xml:"uuid"` + Spec *HostProxySwitchSpec `xml:"spec,omitempty"` +} + +func init() { + t["HostProxySwitchConfig"] = reflect.TypeOf((*HostProxySwitchConfig)(nil)).Elem() +} + +type HostProxySwitchHostLagConfig struct { + DynamicData + + LagKey string `xml:"lagKey"` + LagName string `xml:"lagName,omitempty"` + UplinkPort []KeyValue `xml:"uplinkPort,omitempty"` +} + +func init() { + t["HostProxySwitchHostLagConfig"] = reflect.TypeOf((*HostProxySwitchHostLagConfig)(nil)).Elem() +} + +type HostProxySwitchSpec struct { + DynamicData + + Backing BaseDistributedVirtualSwitchHostMemberBacking `xml:"backing,omitempty,typeattr"` +} + +func init() { + t["HostProxySwitchSpec"] = reflect.TypeOf((*HostProxySwitchSpec)(nil)).Elem() +} + +type HostReconnectionFailedEvent struct { + HostEvent +} + +func init() { + t["HostReconnectionFailedEvent"] = reflect.TypeOf((*HostReconnectionFailedEvent)(nil)).Elem() +} + +type HostReliableMemoryInfo struct { + DynamicData + + MemorySize int64 `xml:"memorySize"` +} + +func init() { + t["HostReliableMemoryInfo"] = reflect.TypeOf((*HostReliableMemoryInfo)(nil)).Elem() +} + +type HostRemoveVFlashResource HostRemoveVFlashResourceRequestType + +func init() { + t["HostRemoveVFlashResource"] = reflect.TypeOf((*HostRemoveVFlashResource)(nil)).Elem() +} + +type HostRemoveVFlashResourceRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["HostRemoveVFlashResourceRequestType"] = reflect.TypeOf((*HostRemoveVFlashResourceRequestType)(nil)).Elem() +} + +type HostRemoveVFlashResourceResponse struct { +} + +type HostRemovedEvent struct { + HostEvent +} + +func init() { + t["HostRemovedEvent"] = reflect.TypeOf((*HostRemovedEvent)(nil)).Elem() +} + +type HostResignatureRescanResult struct { + DynamicData + + Rescan []HostVmfsRescanResult `xml:"rescan,omitempty"` + Result ManagedObjectReference `xml:"result"` +} + +func init() { + t["HostResignatureRescanResult"] = reflect.TypeOf((*HostResignatureRescanResult)(nil)).Elem() +} + +type HostRuntimeInfo struct { + DynamicData + + ConnectionState HostSystemConnectionState `xml:"connectionState"` + PowerState HostSystemPowerState `xml:"powerState"` + StandbyMode string `xml:"standbyMode,omitempty"` + InMaintenanceMode bool `xml:"inMaintenanceMode"` + BootTime *time.Time `xml:"bootTime"` + HealthSystemRuntime *HealthSystemRuntime `xml:"healthSystemRuntime,omitempty"` + DasHostState *ClusterDasFdmHostState `xml:"dasHostState,omitempty"` + TpmPcrValues []HostTpmDigestInfo `xml:"tpmPcrValues,omitempty"` + VsanRuntimeInfo *VsanHostRuntimeInfo `xml:"vsanRuntimeInfo,omitempty"` + NetworkRuntimeInfo *HostRuntimeInfoNetworkRuntimeInfo `xml:"networkRuntimeInfo,omitempty"` + VFlashResourceRuntimeInfo *HostVFlashManagerVFlashResourceRunTimeInfo `xml:"vFlashResourceRuntimeInfo,omitempty"` + HostMaxVirtualDiskCapacity int64 `xml:"hostMaxVirtualDiskCapacity,omitempty"` +} + +func init() { + t["HostRuntimeInfo"] = reflect.TypeOf((*HostRuntimeInfo)(nil)).Elem() +} + +type HostRuntimeInfoNetStackInstanceRuntimeInfo struct { + DynamicData + + NetStackInstanceKey string `xml:"netStackInstanceKey"` + State string `xml:"state,omitempty"` + VmknicKeys []string `xml:"vmknicKeys,omitempty"` + MaxNumberOfConnections int32 `xml:"maxNumberOfConnections,omitempty"` + CurrentIpV6Enabled *bool `xml:"currentIpV6Enabled"` +} + +func init() { + t["HostRuntimeInfoNetStackInstanceRuntimeInfo"] = reflect.TypeOf((*HostRuntimeInfoNetStackInstanceRuntimeInfo)(nil)).Elem() +} + +type HostRuntimeInfoNetworkRuntimeInfo struct { + DynamicData + + NetStackInstanceRuntimeInfo []HostRuntimeInfoNetStackInstanceRuntimeInfo `xml:"netStackInstanceRuntimeInfo,omitempty"` + NetworkResourceRuntime *HostNetworkResourceRuntime `xml:"networkResourceRuntime,omitempty"` +} + +func init() { + t["HostRuntimeInfoNetworkRuntimeInfo"] = reflect.TypeOf((*HostRuntimeInfoNetworkRuntimeInfo)(nil)).Elem() +} + +type HostScsiDisk struct { + ScsiLun + + Capacity HostDiskDimensionsLba `xml:"capacity"` + DevicePath string `xml:"devicePath"` + Ssd *bool `xml:"ssd"` + LocalDisk *bool `xml:"localDisk"` + PhysicalLocation []string `xml:"physicalLocation,omitempty"` + EmulatedDIXDIFEnabled *bool `xml:"emulatedDIXDIFEnabled"` + VsanDiskInfo *VsanHostVsanDiskInfo `xml:"vsanDiskInfo,omitempty"` +} + +func init() { + t["HostScsiDisk"] = reflect.TypeOf((*HostScsiDisk)(nil)).Elem() +} + +type HostScsiDiskPartition struct { + DynamicData + + DiskName string `xml:"diskName"` + Partition int32 `xml:"partition"` +} + +func init() { + t["HostScsiDiskPartition"] = reflect.TypeOf((*HostScsiDiskPartition)(nil)).Elem() +} + +type HostScsiTopology struct { + DynamicData + + Adapter []HostScsiTopologyInterface `xml:"adapter,omitempty"` +} + +func init() { + t["HostScsiTopology"] = reflect.TypeOf((*HostScsiTopology)(nil)).Elem() +} + +type HostScsiTopologyInterface struct { + DynamicData + + Key string `xml:"key"` + Adapter string `xml:"adapter"` + Target []HostScsiTopologyTarget `xml:"target,omitempty"` +} + +func init() { + t["HostScsiTopologyInterface"] = reflect.TypeOf((*HostScsiTopologyInterface)(nil)).Elem() +} + +type HostScsiTopologyLun struct { + DynamicData + + Key string `xml:"key"` + Lun int32 `xml:"lun"` + ScsiLun string `xml:"scsiLun"` +} + +func init() { + t["HostScsiTopologyLun"] = reflect.TypeOf((*HostScsiTopologyLun)(nil)).Elem() +} + +type HostScsiTopologyTarget struct { + DynamicData + + Key string `xml:"key"` + Target int32 `xml:"target"` + Lun []HostScsiTopologyLun `xml:"lun,omitempty"` + Transport BaseHostTargetTransport `xml:"transport,omitempty,typeattr"` +} + +func init() { + t["HostScsiTopologyTarget"] = reflect.TypeOf((*HostScsiTopologyTarget)(nil)).Elem() +} + +type HostSecuritySpec struct { + DynamicData + + AdminPassword string `xml:"adminPassword,omitempty"` + RemovePermission []Permission `xml:"removePermission,omitempty"` + AddPermission []Permission `xml:"addPermission,omitempty"` +} + +func init() { + t["HostSecuritySpec"] = reflect.TypeOf((*HostSecuritySpec)(nil)).Elem() +} + +type HostService struct { + DynamicData + + Key string `xml:"key"` + Label string `xml:"label"` + Required bool `xml:"required"` + Uninstallable bool `xml:"uninstallable"` + Running bool `xml:"running"` + Ruleset []string `xml:"ruleset,omitempty"` + Policy string `xml:"policy"` + SourcePackage *HostServiceSourcePackage `xml:"sourcePackage,omitempty"` +} + +func init() { + t["HostService"] = reflect.TypeOf((*HostService)(nil)).Elem() +} + +type HostServiceConfig struct { + DynamicData + + ServiceId string `xml:"serviceId"` + StartupPolicy string `xml:"startupPolicy"` +} + +func init() { + t["HostServiceConfig"] = reflect.TypeOf((*HostServiceConfig)(nil)).Elem() +} + +type HostServiceInfo struct { + DynamicData + + Service []HostService `xml:"service,omitempty"` +} + +func init() { + t["HostServiceInfo"] = reflect.TypeOf((*HostServiceInfo)(nil)).Elem() +} + +type HostServiceSourcePackage struct { + DynamicData + + SourcePackageName string `xml:"sourcePackageName"` + Description string `xml:"description"` +} + +func init() { + t["HostServiceSourcePackage"] = reflect.TypeOf((*HostServiceSourcePackage)(nil)).Elem() +} + +type HostServiceTicket struct { + DynamicData + + Host string `xml:"host,omitempty"` + Port int32 `xml:"port,omitempty"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` + Service string `xml:"service"` + ServiceVersion string `xml:"serviceVersion"` + SessionId string `xml:"sessionId"` +} + +func init() { + t["HostServiceTicket"] = reflect.TypeOf((*HostServiceTicket)(nil)).Elem() +} + +type HostShortNameInconsistentEvent struct { + HostDasEvent + + ShortName string `xml:"shortName"` + ShortName2 string `xml:"shortName2"` +} + +func init() { + t["HostShortNameInconsistentEvent"] = reflect.TypeOf((*HostShortNameInconsistentEvent)(nil)).Elem() +} + +type HostShortNameToIpFailedEvent struct { + HostEvent + + ShortName string `xml:"shortName"` +} + +func init() { + t["HostShortNameToIpFailedEvent"] = reflect.TypeOf((*HostShortNameToIpFailedEvent)(nil)).Elem() +} + +type HostShutdownEvent struct { + HostEvent + + Reason string `xml:"reason"` +} + +func init() { + t["HostShutdownEvent"] = reflect.TypeOf((*HostShutdownEvent)(nil)).Elem() +} + +type HostSnmpConfigSpec struct { + DynamicData + + Enabled *bool `xml:"enabled"` + Port int32 `xml:"port,omitempty"` + ReadOnlyCommunities []string `xml:"readOnlyCommunities,omitempty"` + TrapTargets []HostSnmpDestination `xml:"trapTargets,omitempty"` + Option []KeyValue `xml:"option,omitempty"` +} + +func init() { + t["HostSnmpConfigSpec"] = reflect.TypeOf((*HostSnmpConfigSpec)(nil)).Elem() +} + +type HostSnmpDestination struct { + DynamicData + + HostName string `xml:"hostName"` + Port int32 `xml:"port"` + Community string `xml:"community"` +} + +func init() { + t["HostSnmpDestination"] = reflect.TypeOf((*HostSnmpDestination)(nil)).Elem() +} + +type HostSnmpSystemAgentLimits struct { + DynamicData + + MaxReadOnlyCommunities int32 `xml:"maxReadOnlyCommunities"` + MaxTrapDestinations int32 `xml:"maxTrapDestinations"` + MaxCommunityLength int32 `xml:"maxCommunityLength"` + MaxBufferSize int32 `xml:"maxBufferSize"` + Capability HostSnmpAgentCapability `xml:"capability,omitempty"` +} + +func init() { + t["HostSnmpSystemAgentLimits"] = reflect.TypeOf((*HostSnmpSystemAgentLimits)(nil)).Elem() +} + +type HostSriovConfig struct { + HostPciPassthruConfig + + SriovEnabled bool `xml:"sriovEnabled"` + NumVirtualFunction int32 `xml:"numVirtualFunction"` +} + +func init() { + t["HostSriovConfig"] = reflect.TypeOf((*HostSriovConfig)(nil)).Elem() +} + +type HostSriovInfo struct { + HostPciPassthruInfo + + SriovEnabled bool `xml:"sriovEnabled"` + SriovCapable bool `xml:"sriovCapable"` + SriovActive bool `xml:"sriovActive"` + NumVirtualFunctionRequested int32 `xml:"numVirtualFunctionRequested"` + NumVirtualFunction int32 `xml:"numVirtualFunction"` + MaxVirtualFunctionSupported int32 `xml:"maxVirtualFunctionSupported"` +} + +func init() { + t["HostSriovInfo"] = reflect.TypeOf((*HostSriovInfo)(nil)).Elem() +} + +type HostSslThumbprintInfo struct { + DynamicData + + Principal string `xml:"principal"` + OwnerTag string `xml:"ownerTag,omitempty"` + SslThumbprints []string `xml:"sslThumbprints,omitempty"` +} + +func init() { + t["HostSslThumbprintInfo"] = reflect.TypeOf((*HostSslThumbprintInfo)(nil)).Elem() +} + +type HostStatusChangedEvent struct { + ClusterStatusChangedEvent +} + +func init() { + t["HostStatusChangedEvent"] = reflect.TypeOf((*HostStatusChangedEvent)(nil)).Elem() +} + +type HostStorageArrayTypePolicyOption struct { + DynamicData + + Policy BaseElementDescription `xml:"policy,typeattr"` +} + +func init() { + t["HostStorageArrayTypePolicyOption"] = reflect.TypeOf((*HostStorageArrayTypePolicyOption)(nil)).Elem() +} + +type HostStorageDeviceInfo struct { + DynamicData + + HostBusAdapter []BaseHostHostBusAdapter `xml:"hostBusAdapter,omitempty,typeattr"` + ScsiLun []BaseScsiLun `xml:"scsiLun,omitempty,typeattr"` + ScsiTopology *HostScsiTopology `xml:"scsiTopology,omitempty"` + MultipathInfo *HostMultipathInfo `xml:"multipathInfo,omitempty"` + PlugStoreTopology *HostPlugStoreTopology `xml:"plugStoreTopology,omitempty"` + SoftwareInternetScsiEnabled bool `xml:"softwareInternetScsiEnabled"` +} + +func init() { + t["HostStorageDeviceInfo"] = reflect.TypeOf((*HostStorageDeviceInfo)(nil)).Elem() +} + +type HostStorageElementInfo struct { + HostHardwareElementInfo + + OperationalInfo []HostStorageOperationalInfo `xml:"operationalInfo,omitempty"` +} + +func init() { + t["HostStorageElementInfo"] = reflect.TypeOf((*HostStorageElementInfo)(nil)).Elem() +} + +type HostStorageOperationalInfo struct { + DynamicData + + Property string `xml:"property"` + Value string `xml:"value"` +} + +func init() { + t["HostStorageOperationalInfo"] = reflect.TypeOf((*HostStorageOperationalInfo)(nil)).Elem() +} + +type HostStorageSystemDiskLocatorLedResult struct { + DynamicData + + Key string `xml:"key"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["HostStorageSystemDiskLocatorLedResult"] = reflect.TypeOf((*HostStorageSystemDiskLocatorLedResult)(nil)).Elem() +} + +type HostStorageSystemScsiLunResult struct { + DynamicData + + Key string `xml:"key"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HostStorageSystemScsiLunResult"] = reflect.TypeOf((*HostStorageSystemScsiLunResult)(nil)).Elem() +} + +type HostStorageSystemVmfsVolumeResult struct { + DynamicData + + Key string `xml:"key"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HostStorageSystemVmfsVolumeResult"] = reflect.TypeOf((*HostStorageSystemVmfsVolumeResult)(nil)).Elem() +} + +type HostSyncFailedEvent struct { + HostEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["HostSyncFailedEvent"] = reflect.TypeOf((*HostSyncFailedEvent)(nil)).Elem() +} + +type HostSystemHealthInfo struct { + DynamicData + + NumericSensorInfo []HostNumericSensorInfo `xml:"numericSensorInfo,omitempty"` +} + +func init() { + t["HostSystemHealthInfo"] = reflect.TypeOf((*HostSystemHealthInfo)(nil)).Elem() +} + +type HostSystemIdentificationInfo struct { + DynamicData + + IdentifierValue string `xml:"identifierValue"` + IdentifierType BaseElementDescription `xml:"identifierType,typeattr"` +} + +func init() { + t["HostSystemIdentificationInfo"] = reflect.TypeOf((*HostSystemIdentificationInfo)(nil)).Elem() +} + +type HostSystemInfo struct { + DynamicData + + Vendor string `xml:"vendor"` + Model string `xml:"model"` + Uuid string `xml:"uuid"` + OtherIdentifyingInfo []HostSystemIdentificationInfo `xml:"otherIdentifyingInfo,omitempty"` +} + +func init() { + t["HostSystemInfo"] = reflect.TypeOf((*HostSystemInfo)(nil)).Elem() +} + +type HostSystemReconnectSpec struct { + DynamicData + + SyncState *bool `xml:"syncState"` +} + +func init() { + t["HostSystemReconnectSpec"] = reflect.TypeOf((*HostSystemReconnectSpec)(nil)).Elem() +} + +type HostSystemResourceInfo struct { + DynamicData + + Key string `xml:"key"` + Config *ResourceConfigSpec `xml:"config,omitempty"` + Child []HostSystemResourceInfo `xml:"child,omitempty"` +} + +func init() { + t["HostSystemResourceInfo"] = reflect.TypeOf((*HostSystemResourceInfo)(nil)).Elem() +} + +type HostSystemSwapConfiguration struct { + DynamicData + + Option []BaseHostSystemSwapConfigurationSystemSwapOption `xml:"option,omitempty,typeattr"` +} + +func init() { + t["HostSystemSwapConfiguration"] = reflect.TypeOf((*HostSystemSwapConfiguration)(nil)).Elem() +} + +type HostSystemSwapConfigurationDatastoreOption struct { + HostSystemSwapConfigurationSystemSwapOption + + Datastore string `xml:"datastore"` +} + +func init() { + t["HostSystemSwapConfigurationDatastoreOption"] = reflect.TypeOf((*HostSystemSwapConfigurationDatastoreOption)(nil)).Elem() +} + +type HostSystemSwapConfigurationDisabledOption struct { + HostSystemSwapConfigurationSystemSwapOption +} + +func init() { + t["HostSystemSwapConfigurationDisabledOption"] = reflect.TypeOf((*HostSystemSwapConfigurationDisabledOption)(nil)).Elem() +} + +type HostSystemSwapConfigurationHostCacheOption struct { + HostSystemSwapConfigurationSystemSwapOption +} + +func init() { + t["HostSystemSwapConfigurationHostCacheOption"] = reflect.TypeOf((*HostSystemSwapConfigurationHostCacheOption)(nil)).Elem() +} + +type HostSystemSwapConfigurationHostLocalSwapOption struct { + HostSystemSwapConfigurationSystemSwapOption +} + +func init() { + t["HostSystemSwapConfigurationHostLocalSwapOption"] = reflect.TypeOf((*HostSystemSwapConfigurationHostLocalSwapOption)(nil)).Elem() +} + +type HostSystemSwapConfigurationSystemSwapOption struct { + DynamicData + + Key int32 `xml:"key"` +} + +func init() { + t["HostSystemSwapConfigurationSystemSwapOption"] = reflect.TypeOf((*HostSystemSwapConfigurationSystemSwapOption)(nil)).Elem() +} + +type HostTargetTransport struct { + DynamicData +} + +func init() { + t["HostTargetTransport"] = reflect.TypeOf((*HostTargetTransport)(nil)).Elem() +} + +type HostTpmAttestationReport struct { + DynamicData + + TpmPcrValues []HostTpmDigestInfo `xml:"tpmPcrValues"` + TpmEvents []HostTpmEventLogEntry `xml:"tpmEvents"` + TpmLogReliable bool `xml:"tpmLogReliable"` +} + +func init() { + t["HostTpmAttestationReport"] = reflect.TypeOf((*HostTpmAttestationReport)(nil)).Elem() +} + +type HostTpmBootSecurityOptionEventDetails struct { + HostTpmEventDetails + + BootSecurityOption string `xml:"bootSecurityOption"` +} + +func init() { + t["HostTpmBootSecurityOptionEventDetails"] = reflect.TypeOf((*HostTpmBootSecurityOptionEventDetails)(nil)).Elem() +} + +type HostTpmCommandEventDetails struct { + HostTpmEventDetails + + CommandLine string `xml:"commandLine"` +} + +func init() { + t["HostTpmCommandEventDetails"] = reflect.TypeOf((*HostTpmCommandEventDetails)(nil)).Elem() +} + +type HostTpmDigestInfo struct { + HostDigestInfo + + PcrNumber int32 `xml:"pcrNumber"` +} + +func init() { + t["HostTpmDigestInfo"] = reflect.TypeOf((*HostTpmDigestInfo)(nil)).Elem() +} + +type HostTpmEventDetails struct { + DynamicData + + DataHash []byte `xml:"dataHash"` +} + +func init() { + t["HostTpmEventDetails"] = reflect.TypeOf((*HostTpmEventDetails)(nil)).Elem() +} + +type HostTpmEventLogEntry struct { + DynamicData + + PcrIndex int32 `xml:"pcrIndex"` + EventDetails BaseHostTpmEventDetails `xml:"eventDetails,typeattr"` +} + +func init() { + t["HostTpmEventLogEntry"] = reflect.TypeOf((*HostTpmEventLogEntry)(nil)).Elem() +} + +type HostTpmOptionEventDetails struct { + HostTpmEventDetails + + OptionsFileName string `xml:"optionsFileName"` + BootOptions []byte `xml:"bootOptions,omitempty"` +} + +func init() { + t["HostTpmOptionEventDetails"] = reflect.TypeOf((*HostTpmOptionEventDetails)(nil)).Elem() +} + +type HostTpmSoftwareComponentEventDetails struct { + HostTpmEventDetails + + ComponentName string `xml:"componentName"` + VibName string `xml:"vibName"` + VibVersion string `xml:"vibVersion"` + VibVendor string `xml:"vibVendor"` +} + +func init() { + t["HostTpmSoftwareComponentEventDetails"] = reflect.TypeOf((*HostTpmSoftwareComponentEventDetails)(nil)).Elem() +} + +type HostUnresolvedVmfsExtent struct { + DynamicData + + Device HostScsiDiskPartition `xml:"device"` + DevicePath string `xml:"devicePath"` + VmfsUuid string `xml:"vmfsUuid"` + IsHeadExtent bool `xml:"isHeadExtent"` + Ordinal int32 `xml:"ordinal"` + StartBlock int32 `xml:"startBlock"` + EndBlock int32 `xml:"endBlock"` + Reason string `xml:"reason"` +} + +func init() { + t["HostUnresolvedVmfsExtent"] = reflect.TypeOf((*HostUnresolvedVmfsExtent)(nil)).Elem() +} + +type HostUnresolvedVmfsResignatureSpec struct { + DynamicData + + ExtentDevicePath []string `xml:"extentDevicePath"` +} + +func init() { + t["HostUnresolvedVmfsResignatureSpec"] = reflect.TypeOf((*HostUnresolvedVmfsResignatureSpec)(nil)).Elem() +} + +type HostUnresolvedVmfsResolutionResult struct { + DynamicData + + Spec HostUnresolvedVmfsResolutionSpec `xml:"spec"` + Vmfs *HostVmfsVolume `xml:"vmfs,omitempty"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HostUnresolvedVmfsResolutionResult"] = reflect.TypeOf((*HostUnresolvedVmfsResolutionResult)(nil)).Elem() +} + +type HostUnresolvedVmfsResolutionSpec struct { + DynamicData + + ExtentDevicePath []string `xml:"extentDevicePath"` + UuidResolution string `xml:"uuidResolution"` +} + +func init() { + t["HostUnresolvedVmfsResolutionSpec"] = reflect.TypeOf((*HostUnresolvedVmfsResolutionSpec)(nil)).Elem() +} + +type HostUnresolvedVmfsVolume struct { + DynamicData + + Extent []HostUnresolvedVmfsExtent `xml:"extent"` + VmfsLabel string `xml:"vmfsLabel"` + VmfsUuid string `xml:"vmfsUuid"` + TotalBlocks int32 `xml:"totalBlocks"` + ResolveStatus HostUnresolvedVmfsVolumeResolveStatus `xml:"resolveStatus"` +} + +func init() { + t["HostUnresolvedVmfsVolume"] = reflect.TypeOf((*HostUnresolvedVmfsVolume)(nil)).Elem() +} + +type HostUnresolvedVmfsVolumeResolveStatus struct { + DynamicData + + Resolvable bool `xml:"resolvable"` + IncompleteExtents *bool `xml:"incompleteExtents"` + MultipleCopies *bool `xml:"multipleCopies"` +} + +func init() { + t["HostUnresolvedVmfsVolumeResolveStatus"] = reflect.TypeOf((*HostUnresolvedVmfsVolumeResolveStatus)(nil)).Elem() +} + +type HostUpgradeFailedEvent struct { + HostEvent +} + +func init() { + t["HostUpgradeFailedEvent"] = reflect.TypeOf((*HostUpgradeFailedEvent)(nil)).Elem() +} + +type HostUserWorldSwapNotEnabledEvent struct { + HostEvent +} + +func init() { + t["HostUserWorldSwapNotEnabledEvent"] = reflect.TypeOf((*HostUserWorldSwapNotEnabledEvent)(nil)).Elem() +} + +type HostVFlashManagerVFlashCacheConfigInfo struct { + DynamicData + + VFlashModuleConfigOption []HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption `xml:"vFlashModuleConfigOption,omitempty"` + DefaultVFlashModule string `xml:"defaultVFlashModule,omitempty"` + SwapCacheReservationInGB int64 `xml:"swapCacheReservationInGB,omitempty"` +} + +func init() { + t["HostVFlashManagerVFlashCacheConfigInfo"] = reflect.TypeOf((*HostVFlashManagerVFlashCacheConfigInfo)(nil)).Elem() +} + +type HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption struct { + DynamicData + + VFlashModule string `xml:"vFlashModule"` + VFlashModuleVersion string `xml:"vFlashModuleVersion"` + MinSupportedModuleVersion string `xml:"minSupportedModuleVersion"` + CacheConsistencyType ChoiceOption `xml:"cacheConsistencyType"` + CacheMode ChoiceOption `xml:"cacheMode"` + BlockSizeInKBOption LongOption `xml:"blockSizeInKBOption"` + ReservationInMBOption LongOption `xml:"reservationInMBOption"` + MaxDiskSizeInKB int64 `xml:"maxDiskSizeInKB"` +} + +func init() { + t["HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption"] = reflect.TypeOf((*HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption)(nil)).Elem() +} + +type HostVFlashManagerVFlashCacheConfigSpec struct { + DynamicData + + DefaultVFlashModule string `xml:"defaultVFlashModule"` + SwapCacheReservationInGB int64 `xml:"swapCacheReservationInGB"` +} + +func init() { + t["HostVFlashManagerVFlashCacheConfigSpec"] = reflect.TypeOf((*HostVFlashManagerVFlashCacheConfigSpec)(nil)).Elem() +} + +type HostVFlashManagerVFlashConfigInfo struct { + DynamicData + + VFlashResourceConfigInfo *HostVFlashManagerVFlashResourceConfigInfo `xml:"vFlashResourceConfigInfo,omitempty"` + VFlashCacheConfigInfo *HostVFlashManagerVFlashCacheConfigInfo `xml:"vFlashCacheConfigInfo,omitempty"` +} + +func init() { + t["HostVFlashManagerVFlashConfigInfo"] = reflect.TypeOf((*HostVFlashManagerVFlashConfigInfo)(nil)).Elem() +} + +type HostVFlashManagerVFlashResourceConfigInfo struct { + DynamicData + + Vffs *HostVffsVolume `xml:"vffs,omitempty"` + Capacity int64 `xml:"capacity"` +} + +func init() { + t["HostVFlashManagerVFlashResourceConfigInfo"] = reflect.TypeOf((*HostVFlashManagerVFlashResourceConfigInfo)(nil)).Elem() +} + +type HostVFlashManagerVFlashResourceConfigSpec struct { + DynamicData + + VffsUuid string `xml:"vffsUuid"` +} + +func init() { + t["HostVFlashManagerVFlashResourceConfigSpec"] = reflect.TypeOf((*HostVFlashManagerVFlashResourceConfigSpec)(nil)).Elem() +} + +type HostVFlashManagerVFlashResourceRunTimeInfo struct { + DynamicData + + Usage int64 `xml:"usage"` + Capacity int64 `xml:"capacity"` + Accessible bool `xml:"accessible"` + CapacityForVmCache int64 `xml:"capacityForVmCache"` + FreeForVmCache int64 `xml:"freeForVmCache"` +} + +func init() { + t["HostVFlashManagerVFlashResourceRunTimeInfo"] = reflect.TypeOf((*HostVFlashManagerVFlashResourceRunTimeInfo)(nil)).Elem() +} + +type HostVFlashResourceConfigurationResult struct { + DynamicData + + DevicePath []string `xml:"devicePath,omitempty"` + Vffs *HostVffsVolume `xml:"vffs,omitempty"` + DiskConfigurationResult []HostDiskConfigurationResult `xml:"diskConfigurationResult,omitempty"` +} + +func init() { + t["HostVFlashResourceConfigurationResult"] = reflect.TypeOf((*HostVFlashResourceConfigurationResult)(nil)).Elem() +} + +type HostVMotionCompatibility struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Compatibility []string `xml:"compatibility,omitempty"` +} + +func init() { + t["HostVMotionCompatibility"] = reflect.TypeOf((*HostVMotionCompatibility)(nil)).Elem() +} + +type HostVMotionConfig struct { + DynamicData + + VmotionNicKey string `xml:"vmotionNicKey,omitempty"` + Enabled bool `xml:"enabled"` +} + +func init() { + t["HostVMotionConfig"] = reflect.TypeOf((*HostVMotionConfig)(nil)).Elem() +} + +type HostVMotionInfo struct { + DynamicData + + NetConfig *HostVMotionNetConfig `xml:"netConfig,omitempty"` + IpConfig *HostIpConfig `xml:"ipConfig,omitempty"` +} + +func init() { + t["HostVMotionInfo"] = reflect.TypeOf((*HostVMotionInfo)(nil)).Elem() +} + +type HostVMotionNetConfig struct { + DynamicData + + CandidateVnic []HostVirtualNic `xml:"candidateVnic,omitempty"` + SelectedVnic string `xml:"selectedVnic,omitempty"` +} + +func init() { + t["HostVMotionNetConfig"] = reflect.TypeOf((*HostVMotionNetConfig)(nil)).Elem() +} + +type HostVfatVolume struct { + HostFileSystemVolume +} + +func init() { + t["HostVfatVolume"] = reflect.TypeOf((*HostVfatVolume)(nil)).Elem() +} + +type HostVffsSpec struct { + DynamicData + + DevicePath string `xml:"devicePath"` + Partition *HostDiskPartitionSpec `xml:"partition,omitempty"` + MajorVersion int32 `xml:"majorVersion"` + VolumeName string `xml:"volumeName"` +} + +func init() { + t["HostVffsSpec"] = reflect.TypeOf((*HostVffsSpec)(nil)).Elem() +} + +type HostVffsVolume struct { + HostFileSystemVolume + + MajorVersion int32 `xml:"majorVersion"` + Version string `xml:"version"` + Uuid string `xml:"uuid"` + Extent []HostScsiDiskPartition `xml:"extent"` +} + +func init() { + t["HostVffsVolume"] = reflect.TypeOf((*HostVffsVolume)(nil)).Elem() +} + +type HostVirtualNic struct { + DynamicData + + Device string `xml:"device"` + Key string `xml:"key"` + Portgroup string `xml:"portgroup"` + Spec HostVirtualNicSpec `xml:"spec"` + Port string `xml:"port,omitempty"` +} + +func init() { + t["HostVirtualNic"] = reflect.TypeOf((*HostVirtualNic)(nil)).Elem() +} + +type HostVirtualNicConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Device string `xml:"device,omitempty"` + Portgroup string `xml:"portgroup"` + Spec *HostVirtualNicSpec `xml:"spec,omitempty"` +} + +func init() { + t["HostVirtualNicConfig"] = reflect.TypeOf((*HostVirtualNicConfig)(nil)).Elem() +} + +type HostVirtualNicConnection struct { + DynamicData + + Portgroup string `xml:"portgroup,omitempty"` + DvPort *DistributedVirtualSwitchPortConnection `xml:"dvPort,omitempty"` +} + +func init() { + t["HostVirtualNicConnection"] = reflect.TypeOf((*HostVirtualNicConnection)(nil)).Elem() +} + +type HostVirtualNicManagerInfo struct { + DynamicData + + NetConfig []VirtualNicManagerNetConfig `xml:"netConfig,omitempty"` +} + +func init() { + t["HostVirtualNicManagerInfo"] = reflect.TypeOf((*HostVirtualNicManagerInfo)(nil)).Elem() +} + +type HostVirtualNicManagerNicTypeSelection struct { + DynamicData + + Vnic HostVirtualNicConnection `xml:"vnic"` + NicType []string `xml:"nicType,omitempty"` +} + +func init() { + t["HostVirtualNicManagerNicTypeSelection"] = reflect.TypeOf((*HostVirtualNicManagerNicTypeSelection)(nil)).Elem() +} + +type HostVirtualNicOpaqueNetworkSpec struct { + DynamicData + + OpaqueNetworkId string `xml:"opaqueNetworkId"` + OpaqueNetworkType string `xml:"opaqueNetworkType"` +} + +func init() { + t["HostVirtualNicOpaqueNetworkSpec"] = reflect.TypeOf((*HostVirtualNicOpaqueNetworkSpec)(nil)).Elem() +} + +type HostVirtualNicSpec struct { + DynamicData + + Ip *HostIpConfig `xml:"ip,omitempty"` + Mac string `xml:"mac,omitempty"` + DistributedVirtualPort *DistributedVirtualSwitchPortConnection `xml:"distributedVirtualPort,omitempty"` + Portgroup string `xml:"portgroup,omitempty"` + Mtu int32 `xml:"mtu,omitempty"` + TsoEnabled *bool `xml:"tsoEnabled"` + NetStackInstanceKey string `xml:"netStackInstanceKey,omitempty"` + OpaqueNetwork *HostVirtualNicOpaqueNetworkSpec `xml:"opaqueNetwork,omitempty"` + ExternalId string `xml:"externalId,omitempty"` + PinnedPnic string `xml:"pinnedPnic,omitempty"` +} + +func init() { + t["HostVirtualNicSpec"] = reflect.TypeOf((*HostVirtualNicSpec)(nil)).Elem() +} + +type HostVirtualSwitch struct { + DynamicData + + Name string `xml:"name"` + Key string `xml:"key"` + NumPorts int32 `xml:"numPorts"` + NumPortsAvailable int32 `xml:"numPortsAvailable"` + Mtu int32 `xml:"mtu,omitempty"` + Portgroup []string `xml:"portgroup,omitempty"` + Pnic []string `xml:"pnic,omitempty"` + Spec HostVirtualSwitchSpec `xml:"spec"` +} + +func init() { + t["HostVirtualSwitch"] = reflect.TypeOf((*HostVirtualSwitch)(nil)).Elem() +} + +type HostVirtualSwitchAutoBridge struct { + HostVirtualSwitchBridge + + ExcludedNicDevice []string `xml:"excludedNicDevice,omitempty"` +} + +func init() { + t["HostVirtualSwitchAutoBridge"] = reflect.TypeOf((*HostVirtualSwitchAutoBridge)(nil)).Elem() +} + +type HostVirtualSwitchBeaconConfig struct { + DynamicData + + Interval int32 `xml:"interval"` +} + +func init() { + t["HostVirtualSwitchBeaconConfig"] = reflect.TypeOf((*HostVirtualSwitchBeaconConfig)(nil)).Elem() +} + +type HostVirtualSwitchBondBridge struct { + HostVirtualSwitchBridge + + NicDevice []string `xml:"nicDevice"` + Beacon *HostVirtualSwitchBeaconConfig `xml:"beacon,omitempty"` + LinkDiscoveryProtocolConfig *LinkDiscoveryProtocolConfig `xml:"linkDiscoveryProtocolConfig,omitempty"` +} + +func init() { + t["HostVirtualSwitchBondBridge"] = reflect.TypeOf((*HostVirtualSwitchBondBridge)(nil)).Elem() +} + +type HostVirtualSwitchBridge struct { + DynamicData +} + +func init() { + t["HostVirtualSwitchBridge"] = reflect.TypeOf((*HostVirtualSwitchBridge)(nil)).Elem() +} + +type HostVirtualSwitchConfig struct { + DynamicData + + ChangeOperation string `xml:"changeOperation,omitempty"` + Name string `xml:"name"` + Spec *HostVirtualSwitchSpec `xml:"spec,omitempty"` +} + +func init() { + t["HostVirtualSwitchConfig"] = reflect.TypeOf((*HostVirtualSwitchConfig)(nil)).Elem() +} + +type HostVirtualSwitchSimpleBridge struct { + HostVirtualSwitchBridge + + NicDevice string `xml:"nicDevice"` +} + +func init() { + t["HostVirtualSwitchSimpleBridge"] = reflect.TypeOf((*HostVirtualSwitchSimpleBridge)(nil)).Elem() +} + +type HostVirtualSwitchSpec struct { + DynamicData + + NumPorts int32 `xml:"numPorts"` + Bridge BaseHostVirtualSwitchBridge `xml:"bridge,omitempty,typeattr"` + Policy *HostNetworkPolicy `xml:"policy,omitempty"` + Mtu int32 `xml:"mtu,omitempty"` +} + +func init() { + t["HostVirtualSwitchSpec"] = reflect.TypeOf((*HostVirtualSwitchSpec)(nil)).Elem() +} + +type HostVmciAccessManagerAccessSpec struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + Services []string `xml:"services,omitempty"` + Mode string `xml:"mode"` +} + +func init() { + t["HostVmciAccessManagerAccessSpec"] = reflect.TypeOf((*HostVmciAccessManagerAccessSpec)(nil)).Elem() +} + +type HostVmfsRescanResult struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HostVmfsRescanResult"] = reflect.TypeOf((*HostVmfsRescanResult)(nil)).Elem() +} + +type HostVmfsSpec struct { + DynamicData + + Extent HostScsiDiskPartition `xml:"extent"` + BlockSizeMb int32 `xml:"blockSizeMb,omitempty"` + MajorVersion int32 `xml:"majorVersion"` + VolumeName string `xml:"volumeName"` +} + +func init() { + t["HostVmfsSpec"] = reflect.TypeOf((*HostVmfsSpec)(nil)).Elem() +} + +type HostVmfsVolume struct { + HostFileSystemVolume + + BlockSizeMb int32 `xml:"blockSizeMb"` + MaxBlocks int32 `xml:"maxBlocks"` + MajorVersion int32 `xml:"majorVersion"` + Version string `xml:"version"` + Uuid string `xml:"uuid"` + Extent []HostScsiDiskPartition `xml:"extent"` + VmfsUpgradable bool `xml:"vmfsUpgradable"` + ForceMountedInfo *HostForceMountedInfo `xml:"forceMountedInfo,omitempty"` + Ssd *bool `xml:"ssd"` + Local *bool `xml:"local"` +} + +func init() { + t["HostVmfsVolume"] = reflect.TypeOf((*HostVmfsVolume)(nil)).Elem() +} + +type HostVnicConnectedToCustomizedDVPortEvent struct { + HostEvent + + Vnic VnicPortArgument `xml:"vnic"` +} + +func init() { + t["HostVnicConnectedToCustomizedDVPortEvent"] = reflect.TypeOf((*HostVnicConnectedToCustomizedDVPortEvent)(nil)).Elem() +} + +type HostVsanInternalSystemCmmdsQuery struct { + DynamicData + + Type string `xml:"type,omitempty"` + Uuid string `xml:"uuid,omitempty"` + Owner string `xml:"owner,omitempty"` +} + +func init() { + t["HostVsanInternalSystemCmmdsQuery"] = reflect.TypeOf((*HostVsanInternalSystemCmmdsQuery)(nil)).Elem() +} + +type HostVsanInternalSystemDeleteVsanObjectsResult struct { + DynamicData + + Uuid string `xml:"uuid"` + Success bool `xml:"success"` + FailureReason []LocalizableMessage `xml:"failureReason,omitempty"` +} + +func init() { + t["HostVsanInternalSystemDeleteVsanObjectsResult"] = reflect.TypeOf((*HostVsanInternalSystemDeleteVsanObjectsResult)(nil)).Elem() +} + +type HostVsanInternalSystemVsanObjectOperationResult struct { + DynamicData + + Uuid string `xml:"uuid"` + FailureReason []LocalizableMessage `xml:"failureReason,omitempty"` +} + +func init() { + t["HostVsanInternalSystemVsanObjectOperationResult"] = reflect.TypeOf((*HostVsanInternalSystemVsanObjectOperationResult)(nil)).Elem() +} + +type HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult struct { + DynamicData + + DiskUuid string `xml:"diskUuid"` + Success bool `xml:"success"` + FailureReason string `xml:"failureReason,omitempty"` +} + +func init() { + t["HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult"] = reflect.TypeOf((*HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult)(nil)).Elem() +} + +type HostVvolVolume struct { + HostFileSystemVolume + + ScId string `xml:"scId"` + HostPE []VVolHostPE `xml:"hostPE,omitempty"` + VasaProviderInfo []VimVasaProviderInfo `xml:"vasaProviderInfo,omitempty"` + StorageArray []VASAStorageArray `xml:"storageArray,omitempty"` +} + +func init() { + t["HostVvolVolume"] = reflect.TypeOf((*HostVvolVolume)(nil)).Elem() +} + +type HostVvolVolumeSpecification struct { + DynamicData + + MaxSizeInMB int64 `xml:"maxSizeInMB"` + VolumeName string `xml:"volumeName"` + VasaProviderInfo []VimVasaProviderInfo `xml:"vasaProviderInfo,omitempty"` + StorageArray []VASAStorageArray `xml:"storageArray,omitempty"` + Uuid string `xml:"uuid"` +} + +func init() { + t["HostVvolVolumeSpecification"] = reflect.TypeOf((*HostVvolVolumeSpecification)(nil)).Elem() +} + +type HostWwnChangedEvent struct { + HostEvent + + OldNodeWwns []int64 `xml:"oldNodeWwns,omitempty"` + OldPortWwns []int64 `xml:"oldPortWwns,omitempty"` + NewNodeWwns []int64 `xml:"newNodeWwns,omitempty"` + NewPortWwns []int64 `xml:"newPortWwns,omitempty"` +} + +func init() { + t["HostWwnChangedEvent"] = reflect.TypeOf((*HostWwnChangedEvent)(nil)).Elem() +} + +type HostWwnConflictEvent struct { + HostEvent + + ConflictedVms []VmEventArgument `xml:"conflictedVms,omitempty"` + ConflictedHosts []HostEventArgument `xml:"conflictedHosts,omitempty"` + Wwn int64 `xml:"wwn"` +} + +func init() { + t["HostWwnConflictEvent"] = reflect.TypeOf((*HostWwnConflictEvent)(nil)).Elem() +} + +type HotSnapshotMoveNotSupported struct { + SnapshotCopyNotSupported +} + +func init() { + t["HotSnapshotMoveNotSupported"] = reflect.TypeOf((*HotSnapshotMoveNotSupported)(nil)).Elem() +} + +type HotSnapshotMoveNotSupportedFault HotSnapshotMoveNotSupported + +func init() { + t["HotSnapshotMoveNotSupportedFault"] = reflect.TypeOf((*HotSnapshotMoveNotSupportedFault)(nil)).Elem() +} + +type HourlyTaskScheduler struct { + RecurrentTaskScheduler + + Minute int32 `xml:"minute"` +} + +func init() { + t["HourlyTaskScheduler"] = reflect.TypeOf((*HourlyTaskScheduler)(nil)).Elem() +} + +type HttpNfcLeaseAbort HttpNfcLeaseAbortRequestType + +func init() { + t["HttpNfcLeaseAbort"] = reflect.TypeOf((*HttpNfcLeaseAbort)(nil)).Elem() +} + +type HttpNfcLeaseAbortRequestType struct { + This ManagedObjectReference `xml:"_this"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["HttpNfcLeaseAbortRequestType"] = reflect.TypeOf((*HttpNfcLeaseAbortRequestType)(nil)).Elem() +} + +type HttpNfcLeaseAbortResponse struct { +} + +type HttpNfcLeaseComplete HttpNfcLeaseCompleteRequestType + +func init() { + t["HttpNfcLeaseComplete"] = reflect.TypeOf((*HttpNfcLeaseComplete)(nil)).Elem() +} + +type HttpNfcLeaseCompleteRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["HttpNfcLeaseCompleteRequestType"] = reflect.TypeOf((*HttpNfcLeaseCompleteRequestType)(nil)).Elem() +} + +type HttpNfcLeaseCompleteResponse struct { +} + +type HttpNfcLeaseDatastoreLeaseInfo struct { + DynamicData + + DatastoreKey string `xml:"datastoreKey"` + Hosts []HttpNfcLeaseHostInfo `xml:"hosts"` +} + +func init() { + t["HttpNfcLeaseDatastoreLeaseInfo"] = reflect.TypeOf((*HttpNfcLeaseDatastoreLeaseInfo)(nil)).Elem() +} + +type HttpNfcLeaseDeviceUrl struct { + DynamicData + + Key string `xml:"key"` + ImportKey string `xml:"importKey"` + Url string `xml:"url"` + SslThumbprint string `xml:"sslThumbprint"` + Disk *bool `xml:"disk"` + TargetId string `xml:"targetId,omitempty"` + DatastoreKey string `xml:"datastoreKey,omitempty"` + FileSize int64 `xml:"fileSize,omitempty"` +} + +func init() { + t["HttpNfcLeaseDeviceUrl"] = reflect.TypeOf((*HttpNfcLeaseDeviceUrl)(nil)).Elem() +} + +type HttpNfcLeaseGetManifest HttpNfcLeaseGetManifestRequestType + +func init() { + t["HttpNfcLeaseGetManifest"] = reflect.TypeOf((*HttpNfcLeaseGetManifest)(nil)).Elem() +} + +type HttpNfcLeaseGetManifestRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["HttpNfcLeaseGetManifestRequestType"] = reflect.TypeOf((*HttpNfcLeaseGetManifestRequestType)(nil)).Elem() +} + +type HttpNfcLeaseGetManifestResponse struct { + Returnval []HttpNfcLeaseManifestEntry `xml:"returnval,omitempty"` +} + +type HttpNfcLeaseHostInfo struct { + DynamicData + + Url string `xml:"url"` + SslThumbprint string `xml:"sslThumbprint"` +} + +func init() { + t["HttpNfcLeaseHostInfo"] = reflect.TypeOf((*HttpNfcLeaseHostInfo)(nil)).Elem() +} + +type HttpNfcLeaseInfo struct { + DynamicData + + Lease ManagedObjectReference `xml:"lease"` + Entity ManagedObjectReference `xml:"entity"` + DeviceUrl []HttpNfcLeaseDeviceUrl `xml:"deviceUrl,omitempty"` + TotalDiskCapacityInKB int64 `xml:"totalDiskCapacityInKB"` + LeaseTimeout int32 `xml:"leaseTimeout"` + HostMap []HttpNfcLeaseDatastoreLeaseInfo `xml:"hostMap,omitempty"` +} + +func init() { + t["HttpNfcLeaseInfo"] = reflect.TypeOf((*HttpNfcLeaseInfo)(nil)).Elem() +} + +type HttpNfcLeaseManifestEntry struct { + DynamicData + + Key string `xml:"key"` + Sha1 string `xml:"sha1"` + Size int64 `xml:"size"` + Disk bool `xml:"disk"` + Capacity int64 `xml:"capacity,omitempty"` + PopulatedSize int64 `xml:"populatedSize,omitempty"` +} + +func init() { + t["HttpNfcLeaseManifestEntry"] = reflect.TypeOf((*HttpNfcLeaseManifestEntry)(nil)).Elem() +} + +type HttpNfcLeaseProgress HttpNfcLeaseProgressRequestType + +func init() { + t["HttpNfcLeaseProgress"] = reflect.TypeOf((*HttpNfcLeaseProgress)(nil)).Elem() +} + +type HttpNfcLeaseProgressRequestType struct { + This ManagedObjectReference `xml:"_this"` + Percent int32 `xml:"percent"` +} + +func init() { + t["HttpNfcLeaseProgressRequestType"] = reflect.TypeOf((*HttpNfcLeaseProgressRequestType)(nil)).Elem() +} + +type HttpNfcLeaseProgressResponse struct { +} + +type IDEDiskNotSupported struct { + DiskNotSupported +} + +func init() { + t["IDEDiskNotSupported"] = reflect.TypeOf((*IDEDiskNotSupported)(nil)).Elem() +} + +type IDEDiskNotSupportedFault IDEDiskNotSupported + +func init() { + t["IDEDiskNotSupportedFault"] = reflect.TypeOf((*IDEDiskNotSupportedFault)(nil)).Elem() +} + +type IORMNotSupportedHostOnDatastore struct { + VimFault + + Datastore ManagedObjectReference `xml:"datastore"` + DatastoreName string `xml:"datastoreName"` + Host []ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["IORMNotSupportedHostOnDatastore"] = reflect.TypeOf((*IORMNotSupportedHostOnDatastore)(nil)).Elem() +} + +type IORMNotSupportedHostOnDatastoreFault IORMNotSupportedHostOnDatastore + +func init() { + t["IORMNotSupportedHostOnDatastoreFault"] = reflect.TypeOf((*IORMNotSupportedHostOnDatastoreFault)(nil)).Elem() +} + +type IScsiBootFailureEvent struct { + HostEvent +} + +func init() { + t["IScsiBootFailureEvent"] = reflect.TypeOf((*IScsiBootFailureEvent)(nil)).Elem() +} + +type ImpersonateUser ImpersonateUserRequestType + +func init() { + t["ImpersonateUser"] = reflect.TypeOf((*ImpersonateUser)(nil)).Elem() +} + +type ImpersonateUserRequestType struct { + This ManagedObjectReference `xml:"_this"` + UserName string `xml:"userName"` + Locale string `xml:"locale,omitempty"` +} + +func init() { + t["ImpersonateUserRequestType"] = reflect.TypeOf((*ImpersonateUserRequestType)(nil)).Elem() +} + +type ImpersonateUserResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type ImportCertificateForCAMRequestType struct { + This ManagedObjectReference `xml:"_this"` + CertPath string `xml:"certPath"` + CamServer string `xml:"camServer"` +} + +func init() { + t["ImportCertificateForCAMRequestType"] = reflect.TypeOf((*ImportCertificateForCAMRequestType)(nil)).Elem() +} + +type ImportCertificateForCAM_Task ImportCertificateForCAMRequestType + +func init() { + t["ImportCertificateForCAM_Task"] = reflect.TypeOf((*ImportCertificateForCAM_Task)(nil)).Elem() +} + +type ImportCertificateForCAM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ImportHostAddFailure struct { + DvsFault + + HostIp []string `xml:"hostIp"` +} + +func init() { + t["ImportHostAddFailure"] = reflect.TypeOf((*ImportHostAddFailure)(nil)).Elem() +} + +type ImportHostAddFailureFault ImportHostAddFailure + +func init() { + t["ImportHostAddFailureFault"] = reflect.TypeOf((*ImportHostAddFailureFault)(nil)).Elem() +} + +type ImportOperationBulkFault struct { + DvsFault + + ImportFaults []ImportOperationBulkFaultFaultOnImport `xml:"importFaults"` +} + +func init() { + t["ImportOperationBulkFault"] = reflect.TypeOf((*ImportOperationBulkFault)(nil)).Elem() +} + +type ImportOperationBulkFaultFault ImportOperationBulkFault + +func init() { + t["ImportOperationBulkFaultFault"] = reflect.TypeOf((*ImportOperationBulkFaultFault)(nil)).Elem() +} + +type ImportOperationBulkFaultFaultOnImport struct { + DynamicData + + EntityType string `xml:"entityType,omitempty"` + Key string `xml:"key,omitempty"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["ImportOperationBulkFaultFaultOnImport"] = reflect.TypeOf((*ImportOperationBulkFaultFaultOnImport)(nil)).Elem() +} + +type ImportSpec struct { + DynamicData + + EntityConfig *VAppEntityConfigInfo `xml:"entityConfig,omitempty"` + InstantiationOst *OvfConsumerOstNode `xml:"instantiationOst,omitempty"` +} + +func init() { + t["ImportSpec"] = reflect.TypeOf((*ImportSpec)(nil)).Elem() +} + +type ImportUnmanagedSnapshot ImportUnmanagedSnapshotRequestType + +func init() { + t["ImportUnmanagedSnapshot"] = reflect.TypeOf((*ImportUnmanagedSnapshot)(nil)).Elem() +} + +type ImportUnmanagedSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vdisk string `xml:"vdisk"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + VvolId string `xml:"vvolId"` +} + +func init() { + t["ImportUnmanagedSnapshotRequestType"] = reflect.TypeOf((*ImportUnmanagedSnapshotRequestType)(nil)).Elem() +} + +type ImportUnmanagedSnapshotResponse struct { +} + +type ImportVApp ImportVAppRequestType + +func init() { + t["ImportVApp"] = reflect.TypeOf((*ImportVApp)(nil)).Elem() +} + +type ImportVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec BaseImportSpec `xml:"spec,typeattr"` + Folder *ManagedObjectReference `xml:"folder,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["ImportVAppRequestType"] = reflect.TypeOf((*ImportVAppRequestType)(nil)).Elem() +} + +type ImportVAppResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type InUseFeatureManipulationDisallowed struct { + NotEnoughLicenses +} + +func init() { + t["InUseFeatureManipulationDisallowed"] = reflect.TypeOf((*InUseFeatureManipulationDisallowed)(nil)).Elem() +} + +type InUseFeatureManipulationDisallowedFault InUseFeatureManipulationDisallowed + +func init() { + t["InUseFeatureManipulationDisallowedFault"] = reflect.TypeOf((*InUseFeatureManipulationDisallowedFault)(nil)).Elem() +} + +type InaccessibleDatastore struct { + InvalidDatastore + + Detail string `xml:"detail,omitempty"` +} + +func init() { + t["InaccessibleDatastore"] = reflect.TypeOf((*InaccessibleDatastore)(nil)).Elem() +} + +type InaccessibleDatastoreFault BaseInaccessibleDatastore + +func init() { + t["InaccessibleDatastoreFault"] = reflect.TypeOf((*InaccessibleDatastoreFault)(nil)).Elem() +} + +type InaccessibleFTMetadataDatastore struct { + InaccessibleDatastore +} + +func init() { + t["InaccessibleFTMetadataDatastore"] = reflect.TypeOf((*InaccessibleFTMetadataDatastore)(nil)).Elem() +} + +type InaccessibleFTMetadataDatastoreFault InaccessibleFTMetadataDatastore + +func init() { + t["InaccessibleFTMetadataDatastoreFault"] = reflect.TypeOf((*InaccessibleFTMetadataDatastoreFault)(nil)).Elem() +} + +type InaccessibleVFlashSource struct { + VimFault + + HostName string `xml:"hostName"` +} + +func init() { + t["InaccessibleVFlashSource"] = reflect.TypeOf((*InaccessibleVFlashSource)(nil)).Elem() +} + +type InaccessibleVFlashSourceFault InaccessibleVFlashSource + +func init() { + t["InaccessibleVFlashSourceFault"] = reflect.TypeOf((*InaccessibleVFlashSourceFault)(nil)).Elem() +} + +type IncompatibleDefaultDevice struct { + MigrationFault + + Device string `xml:"device"` +} + +func init() { + t["IncompatibleDefaultDevice"] = reflect.TypeOf((*IncompatibleDefaultDevice)(nil)).Elem() +} + +type IncompatibleDefaultDeviceFault IncompatibleDefaultDevice + +func init() { + t["IncompatibleDefaultDeviceFault"] = reflect.TypeOf((*IncompatibleDefaultDeviceFault)(nil)).Elem() +} + +type IncompatibleHostForFtSecondary struct { + VmFaultToleranceIssue + + Host ManagedObjectReference `xml:"host"` + Error []LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["IncompatibleHostForFtSecondary"] = reflect.TypeOf((*IncompatibleHostForFtSecondary)(nil)).Elem() +} + +type IncompatibleHostForFtSecondaryFault IncompatibleHostForFtSecondary + +func init() { + t["IncompatibleHostForFtSecondaryFault"] = reflect.TypeOf((*IncompatibleHostForFtSecondaryFault)(nil)).Elem() +} + +type IncompatibleHostForVmReplication struct { + ReplicationFault + + VmName string `xml:"vmName"` + HostName string `xml:"hostName"` + Reason string `xml:"reason"` +} + +func init() { + t["IncompatibleHostForVmReplication"] = reflect.TypeOf((*IncompatibleHostForVmReplication)(nil)).Elem() +} + +type IncompatibleHostForVmReplicationFault IncompatibleHostForVmReplication + +func init() { + t["IncompatibleHostForVmReplicationFault"] = reflect.TypeOf((*IncompatibleHostForVmReplicationFault)(nil)).Elem() +} + +type IncompatibleSetting struct { + InvalidArgument + + ConflictingProperty string `xml:"conflictingProperty"` +} + +func init() { + t["IncompatibleSetting"] = reflect.TypeOf((*IncompatibleSetting)(nil)).Elem() +} + +type IncompatibleSettingFault IncompatibleSetting + +func init() { + t["IncompatibleSettingFault"] = reflect.TypeOf((*IncompatibleSettingFault)(nil)).Elem() +} + +type IncorrectFileType struct { + FileFault +} + +func init() { + t["IncorrectFileType"] = reflect.TypeOf((*IncorrectFileType)(nil)).Elem() +} + +type IncorrectFileTypeFault IncorrectFileType + +func init() { + t["IncorrectFileTypeFault"] = reflect.TypeOf((*IncorrectFileTypeFault)(nil)).Elem() +} + +type IncorrectHostInformation struct { + NotEnoughLicenses +} + +func init() { + t["IncorrectHostInformation"] = reflect.TypeOf((*IncorrectHostInformation)(nil)).Elem() +} + +type IncorrectHostInformationEvent struct { + LicenseEvent +} + +func init() { + t["IncorrectHostInformationEvent"] = reflect.TypeOf((*IncorrectHostInformationEvent)(nil)).Elem() +} + +type IncorrectHostInformationFault IncorrectHostInformation + +func init() { + t["IncorrectHostInformationFault"] = reflect.TypeOf((*IncorrectHostInformationFault)(nil)).Elem() +} + +type IndependentDiskVMotionNotSupported struct { + MigrationFeatureNotSupported +} + +func init() { + t["IndependentDiskVMotionNotSupported"] = reflect.TypeOf((*IndependentDiskVMotionNotSupported)(nil)).Elem() +} + +type IndependentDiskVMotionNotSupportedFault IndependentDiskVMotionNotSupported + +func init() { + t["IndependentDiskVMotionNotSupportedFault"] = reflect.TypeOf((*IndependentDiskVMotionNotSupportedFault)(nil)).Elem() +} + +type InflateVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["InflateVirtualDiskRequestType"] = reflect.TypeOf((*InflateVirtualDiskRequestType)(nil)).Elem() +} + +type InflateVirtualDisk_Task InflateVirtualDiskRequestType + +func init() { + t["InflateVirtualDisk_Task"] = reflect.TypeOf((*InflateVirtualDisk_Task)(nil)).Elem() +} + +type InflateVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type InfoUpgradeEvent struct { + UpgradeEvent +} + +func init() { + t["InfoUpgradeEvent"] = reflect.TypeOf((*InfoUpgradeEvent)(nil)).Elem() +} + +type InheritablePolicy struct { + DynamicData + + Inherited bool `xml:"inherited"` +} + +func init() { + t["InheritablePolicy"] = reflect.TypeOf((*InheritablePolicy)(nil)).Elem() +} + +type InitializeDisksRequestType struct { + This ManagedObjectReference `xml:"_this"` + Mapping []VsanHostDiskMapping `xml:"mapping"` +} + +func init() { + t["InitializeDisksRequestType"] = reflect.TypeOf((*InitializeDisksRequestType)(nil)).Elem() +} + +type InitializeDisks_Task InitializeDisksRequestType + +func init() { + t["InitializeDisks_Task"] = reflect.TypeOf((*InitializeDisks_Task)(nil)).Elem() +} + +type InitializeDisks_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type InitiateFileTransferFromGuest InitiateFileTransferFromGuestRequestType + +func init() { + t["InitiateFileTransferFromGuest"] = reflect.TypeOf((*InitiateFileTransferFromGuest)(nil)).Elem() +} + +type InitiateFileTransferFromGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + GuestFilePath string `xml:"guestFilePath"` +} + +func init() { + t["InitiateFileTransferFromGuestRequestType"] = reflect.TypeOf((*InitiateFileTransferFromGuestRequestType)(nil)).Elem() +} + +type InitiateFileTransferFromGuestResponse struct { + Returnval FileTransferInformation `xml:"returnval"` +} + +type InitiateFileTransferToGuest InitiateFileTransferToGuestRequestType + +func init() { + t["InitiateFileTransferToGuest"] = reflect.TypeOf((*InitiateFileTransferToGuest)(nil)).Elem() +} + +type InitiateFileTransferToGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + GuestFilePath string `xml:"guestFilePath"` + FileAttributes BaseGuestFileAttributes `xml:"fileAttributes,typeattr"` + FileSize int64 `xml:"fileSize"` + Overwrite bool `xml:"overwrite"` +} + +func init() { + t["InitiateFileTransferToGuestRequestType"] = reflect.TypeOf((*InitiateFileTransferToGuestRequestType)(nil)).Elem() +} + +type InitiateFileTransferToGuestResponse struct { + Returnval string `xml:"returnval"` +} + +type InstallHostPatchRequestType struct { + This ManagedObjectReference `xml:"_this"` + Repository HostPatchManagerLocator `xml:"repository"` + UpdateID string `xml:"updateID"` + Force *bool `xml:"force"` +} + +func init() { + t["InstallHostPatchRequestType"] = reflect.TypeOf((*InstallHostPatchRequestType)(nil)).Elem() +} + +type InstallHostPatchV2RequestType struct { + This ManagedObjectReference `xml:"_this"` + MetaUrls []string `xml:"metaUrls,omitempty"` + BundleUrls []string `xml:"bundleUrls,omitempty"` + VibUrls []string `xml:"vibUrls,omitempty"` + Spec *HostPatchManagerPatchManagerOperationSpec `xml:"spec,omitempty"` +} + +func init() { + t["InstallHostPatchV2RequestType"] = reflect.TypeOf((*InstallHostPatchV2RequestType)(nil)).Elem() +} + +type InstallHostPatchV2_Task InstallHostPatchV2RequestType + +func init() { + t["InstallHostPatchV2_Task"] = reflect.TypeOf((*InstallHostPatchV2_Task)(nil)).Elem() +} + +type InstallHostPatchV2_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type InstallHostPatch_Task InstallHostPatchRequestType + +func init() { + t["InstallHostPatch_Task"] = reflect.TypeOf((*InstallHostPatch_Task)(nil)).Elem() +} + +type InstallHostPatch_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type InstallIoFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` + VibUrl string `xml:"vibUrl"` + CompRes ManagedObjectReference `xml:"compRes"` +} + +func init() { + t["InstallIoFilterRequestType"] = reflect.TypeOf((*InstallIoFilterRequestType)(nil)).Elem() +} + +type InstallIoFilter_Task InstallIoFilterRequestType + +func init() { + t["InstallIoFilter_Task"] = reflect.TypeOf((*InstallIoFilter_Task)(nil)).Elem() +} + +type InstallIoFilter_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type InstallServerCertificate InstallServerCertificateRequestType + +func init() { + t["InstallServerCertificate"] = reflect.TypeOf((*InstallServerCertificate)(nil)).Elem() +} + +type InstallServerCertificateRequestType struct { + This ManagedObjectReference `xml:"_this"` + Cert string `xml:"cert"` +} + +func init() { + t["InstallServerCertificateRequestType"] = reflect.TypeOf((*InstallServerCertificateRequestType)(nil)).Elem() +} + +type InstallServerCertificateResponse struct { +} + +type InstallSmartCardTrustAnchor InstallSmartCardTrustAnchorRequestType + +func init() { + t["InstallSmartCardTrustAnchor"] = reflect.TypeOf((*InstallSmartCardTrustAnchor)(nil)).Elem() +} + +type InstallSmartCardTrustAnchorRequestType struct { + This ManagedObjectReference `xml:"_this"` + Cert string `xml:"cert"` +} + +func init() { + t["InstallSmartCardTrustAnchorRequestType"] = reflect.TypeOf((*InstallSmartCardTrustAnchorRequestType)(nil)).Elem() +} + +type InstallSmartCardTrustAnchorResponse struct { +} + +type InsufficientAgentVmsDeployed struct { + InsufficientResourcesFault + + HostName string `xml:"hostName"` + RequiredNumAgentVms int32 `xml:"requiredNumAgentVms"` + CurrentNumAgentVms int32 `xml:"currentNumAgentVms"` +} + +func init() { + t["InsufficientAgentVmsDeployed"] = reflect.TypeOf((*InsufficientAgentVmsDeployed)(nil)).Elem() +} + +type InsufficientAgentVmsDeployedFault InsufficientAgentVmsDeployed + +func init() { + t["InsufficientAgentVmsDeployedFault"] = reflect.TypeOf((*InsufficientAgentVmsDeployedFault)(nil)).Elem() +} + +type InsufficientCpuResourcesFault struct { + InsufficientResourcesFault + + Unreserved int64 `xml:"unreserved"` + Requested int64 `xml:"requested"` +} + +func init() { + t["InsufficientCpuResourcesFault"] = reflect.TypeOf((*InsufficientCpuResourcesFault)(nil)).Elem() +} + +type InsufficientCpuResourcesFaultFault InsufficientCpuResourcesFault + +func init() { + t["InsufficientCpuResourcesFaultFault"] = reflect.TypeOf((*InsufficientCpuResourcesFaultFault)(nil)).Elem() +} + +type InsufficientDisks struct { + VsanDiskFault +} + +func init() { + t["InsufficientDisks"] = reflect.TypeOf((*InsufficientDisks)(nil)).Elem() +} + +type InsufficientDisksFault InsufficientDisks + +func init() { + t["InsufficientDisksFault"] = reflect.TypeOf((*InsufficientDisksFault)(nil)).Elem() +} + +type InsufficientFailoverResourcesEvent struct { + ClusterEvent +} + +func init() { + t["InsufficientFailoverResourcesEvent"] = reflect.TypeOf((*InsufficientFailoverResourcesEvent)(nil)).Elem() +} + +type InsufficientFailoverResourcesFault struct { + InsufficientResourcesFault +} + +func init() { + t["InsufficientFailoverResourcesFault"] = reflect.TypeOf((*InsufficientFailoverResourcesFault)(nil)).Elem() +} + +type InsufficientFailoverResourcesFaultFault InsufficientFailoverResourcesFault + +func init() { + t["InsufficientFailoverResourcesFaultFault"] = reflect.TypeOf((*InsufficientFailoverResourcesFaultFault)(nil)).Elem() +} + +type InsufficientGraphicsResourcesFault struct { + InsufficientResourcesFault +} + +func init() { + t["InsufficientGraphicsResourcesFault"] = reflect.TypeOf((*InsufficientGraphicsResourcesFault)(nil)).Elem() +} + +type InsufficientGraphicsResourcesFaultFault InsufficientGraphicsResourcesFault + +func init() { + t["InsufficientGraphicsResourcesFaultFault"] = reflect.TypeOf((*InsufficientGraphicsResourcesFaultFault)(nil)).Elem() +} + +type InsufficientHostCapacityFault struct { + InsufficientResourcesFault + + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["InsufficientHostCapacityFault"] = reflect.TypeOf((*InsufficientHostCapacityFault)(nil)).Elem() +} + +type InsufficientHostCapacityFaultFault BaseInsufficientHostCapacityFault + +func init() { + t["InsufficientHostCapacityFaultFault"] = reflect.TypeOf((*InsufficientHostCapacityFaultFault)(nil)).Elem() +} + +type InsufficientHostCpuCapacityFault struct { + InsufficientHostCapacityFault + + Unreserved int64 `xml:"unreserved"` + Requested int64 `xml:"requested"` +} + +func init() { + t["InsufficientHostCpuCapacityFault"] = reflect.TypeOf((*InsufficientHostCpuCapacityFault)(nil)).Elem() +} + +type InsufficientHostCpuCapacityFaultFault InsufficientHostCpuCapacityFault + +func init() { + t["InsufficientHostCpuCapacityFaultFault"] = reflect.TypeOf((*InsufficientHostCpuCapacityFaultFault)(nil)).Elem() +} + +type InsufficientHostMemoryCapacityFault struct { + InsufficientHostCapacityFault + + Unreserved int64 `xml:"unreserved"` + Requested int64 `xml:"requested"` +} + +func init() { + t["InsufficientHostMemoryCapacityFault"] = reflect.TypeOf((*InsufficientHostMemoryCapacityFault)(nil)).Elem() +} + +type InsufficientHostMemoryCapacityFaultFault InsufficientHostMemoryCapacityFault + +func init() { + t["InsufficientHostMemoryCapacityFaultFault"] = reflect.TypeOf((*InsufficientHostMemoryCapacityFaultFault)(nil)).Elem() +} + +type InsufficientMemoryResourcesFault struct { + InsufficientResourcesFault + + Unreserved int64 `xml:"unreserved"` + Requested int64 `xml:"requested"` +} + +func init() { + t["InsufficientMemoryResourcesFault"] = reflect.TypeOf((*InsufficientMemoryResourcesFault)(nil)).Elem() +} + +type InsufficientMemoryResourcesFaultFault InsufficientMemoryResourcesFault + +func init() { + t["InsufficientMemoryResourcesFaultFault"] = reflect.TypeOf((*InsufficientMemoryResourcesFaultFault)(nil)).Elem() +} + +type InsufficientNetworkCapacity struct { + InsufficientResourcesFault +} + +func init() { + t["InsufficientNetworkCapacity"] = reflect.TypeOf((*InsufficientNetworkCapacity)(nil)).Elem() +} + +type InsufficientNetworkCapacityFault InsufficientNetworkCapacity + +func init() { + t["InsufficientNetworkCapacityFault"] = reflect.TypeOf((*InsufficientNetworkCapacityFault)(nil)).Elem() +} + +type InsufficientNetworkResourcePoolCapacity struct { + InsufficientResourcesFault + + DvsName string `xml:"dvsName"` + DvsUuid string `xml:"dvsUuid"` + ResourcePoolKey string `xml:"resourcePoolKey"` + Available int64 `xml:"available"` + Requested int64 `xml:"requested"` + Device []string `xml:"device"` +} + +func init() { + t["InsufficientNetworkResourcePoolCapacity"] = reflect.TypeOf((*InsufficientNetworkResourcePoolCapacity)(nil)).Elem() +} + +type InsufficientNetworkResourcePoolCapacityFault InsufficientNetworkResourcePoolCapacity + +func init() { + t["InsufficientNetworkResourcePoolCapacityFault"] = reflect.TypeOf((*InsufficientNetworkResourcePoolCapacityFault)(nil)).Elem() +} + +type InsufficientPerCpuCapacity struct { + InsufficientHostCapacityFault +} + +func init() { + t["InsufficientPerCpuCapacity"] = reflect.TypeOf((*InsufficientPerCpuCapacity)(nil)).Elem() +} + +type InsufficientPerCpuCapacityFault InsufficientPerCpuCapacity + +func init() { + t["InsufficientPerCpuCapacityFault"] = reflect.TypeOf((*InsufficientPerCpuCapacityFault)(nil)).Elem() +} + +type InsufficientResourcesFault struct { + VimFault +} + +func init() { + t["InsufficientResourcesFault"] = reflect.TypeOf((*InsufficientResourcesFault)(nil)).Elem() +} + +type InsufficientResourcesFaultFault BaseInsufficientResourcesFault + +func init() { + t["InsufficientResourcesFaultFault"] = reflect.TypeOf((*InsufficientResourcesFaultFault)(nil)).Elem() +} + +type InsufficientStandbyCpuResource struct { + InsufficientStandbyResource + + Available int64 `xml:"available"` + Requested int64 `xml:"requested"` +} + +func init() { + t["InsufficientStandbyCpuResource"] = reflect.TypeOf((*InsufficientStandbyCpuResource)(nil)).Elem() +} + +type InsufficientStandbyCpuResourceFault InsufficientStandbyCpuResource + +func init() { + t["InsufficientStandbyCpuResourceFault"] = reflect.TypeOf((*InsufficientStandbyCpuResourceFault)(nil)).Elem() +} + +type InsufficientStandbyMemoryResource struct { + InsufficientStandbyResource + + Available int64 `xml:"available"` + Requested int64 `xml:"requested"` +} + +func init() { + t["InsufficientStandbyMemoryResource"] = reflect.TypeOf((*InsufficientStandbyMemoryResource)(nil)).Elem() +} + +type InsufficientStandbyMemoryResourceFault InsufficientStandbyMemoryResource + +func init() { + t["InsufficientStandbyMemoryResourceFault"] = reflect.TypeOf((*InsufficientStandbyMemoryResourceFault)(nil)).Elem() +} + +type InsufficientStandbyResource struct { + InsufficientResourcesFault +} + +func init() { + t["InsufficientStandbyResource"] = reflect.TypeOf((*InsufficientStandbyResource)(nil)).Elem() +} + +type InsufficientStandbyResourceFault BaseInsufficientStandbyResource + +func init() { + t["InsufficientStandbyResourceFault"] = reflect.TypeOf((*InsufficientStandbyResourceFault)(nil)).Elem() +} + +type InsufficientStorageIops struct { + VimFault + + UnreservedIops int64 `xml:"unreservedIops"` + RequestedIops int64 `xml:"requestedIops"` + DatastoreName string `xml:"datastoreName"` +} + +func init() { + t["InsufficientStorageIops"] = reflect.TypeOf((*InsufficientStorageIops)(nil)).Elem() +} + +type InsufficientStorageIopsFault InsufficientStorageIops + +func init() { + t["InsufficientStorageIopsFault"] = reflect.TypeOf((*InsufficientStorageIopsFault)(nil)).Elem() +} + +type InsufficientStorageSpace struct { + InsufficientResourcesFault +} + +func init() { + t["InsufficientStorageSpace"] = reflect.TypeOf((*InsufficientStorageSpace)(nil)).Elem() +} + +type InsufficientStorageSpaceFault InsufficientStorageSpace + +func init() { + t["InsufficientStorageSpaceFault"] = reflect.TypeOf((*InsufficientStorageSpaceFault)(nil)).Elem() +} + +type InsufficientVFlashResourcesFault struct { + InsufficientResourcesFault + + FreeSpaceInMB int64 `xml:"freeSpaceInMB,omitempty"` + FreeSpace int64 `xml:"freeSpace"` + RequestedSpaceInMB int64 `xml:"requestedSpaceInMB,omitempty"` + RequestedSpace int64 `xml:"requestedSpace"` +} + +func init() { + t["InsufficientVFlashResourcesFault"] = reflect.TypeOf((*InsufficientVFlashResourcesFault)(nil)).Elem() +} + +type InsufficientVFlashResourcesFaultFault InsufficientVFlashResourcesFault + +func init() { + t["InsufficientVFlashResourcesFaultFault"] = reflect.TypeOf((*InsufficientVFlashResourcesFaultFault)(nil)).Elem() +} + +type IntExpression struct { + NegatableExpression + + Value int32 `xml:"value,omitempty"` +} + +func init() { + t["IntExpression"] = reflect.TypeOf((*IntExpression)(nil)).Elem() +} + +type IntOption struct { + OptionType + + Min int32 `xml:"min"` + Max int32 `xml:"max"` + DefaultValue int32 `xml:"defaultValue"` +} + +func init() { + t["IntOption"] = reflect.TypeOf((*IntOption)(nil)).Elem() +} + +type IntPolicy struct { + InheritablePolicy + + Value int32 `xml:"value,omitempty"` +} + +func init() { + t["IntPolicy"] = reflect.TypeOf((*IntPolicy)(nil)).Elem() +} + +type InvalidAffinitySettingFault struct { + VimFault +} + +func init() { + t["InvalidAffinitySettingFault"] = reflect.TypeOf((*InvalidAffinitySettingFault)(nil)).Elem() +} + +type InvalidAffinitySettingFaultFault InvalidAffinitySettingFault + +func init() { + t["InvalidAffinitySettingFaultFault"] = reflect.TypeOf((*InvalidAffinitySettingFaultFault)(nil)).Elem() +} + +type InvalidArgument struct { + RuntimeFault + + InvalidProperty string `xml:"invalidProperty,omitempty"` +} + +func init() { + t["InvalidArgument"] = reflect.TypeOf((*InvalidArgument)(nil)).Elem() +} + +type InvalidArgumentFault BaseInvalidArgument + +func init() { + t["InvalidArgumentFault"] = reflect.TypeOf((*InvalidArgumentFault)(nil)).Elem() +} + +type InvalidBmcRole struct { + VimFault +} + +func init() { + t["InvalidBmcRole"] = reflect.TypeOf((*InvalidBmcRole)(nil)).Elem() +} + +type InvalidBmcRoleFault InvalidBmcRole + +func init() { + t["InvalidBmcRoleFault"] = reflect.TypeOf((*InvalidBmcRoleFault)(nil)).Elem() +} + +type InvalidBundle struct { + PlatformConfigFault +} + +func init() { + t["InvalidBundle"] = reflect.TypeOf((*InvalidBundle)(nil)).Elem() +} + +type InvalidBundleFault InvalidBundle + +func init() { + t["InvalidBundleFault"] = reflect.TypeOf((*InvalidBundleFault)(nil)).Elem() +} + +type InvalidCAMCertificate struct { + InvalidCAMServer +} + +func init() { + t["InvalidCAMCertificate"] = reflect.TypeOf((*InvalidCAMCertificate)(nil)).Elem() +} + +type InvalidCAMCertificateFault InvalidCAMCertificate + +func init() { + t["InvalidCAMCertificateFault"] = reflect.TypeOf((*InvalidCAMCertificateFault)(nil)).Elem() +} + +type InvalidCAMServer struct { + ActiveDirectoryFault + + CamServer string `xml:"camServer"` +} + +func init() { + t["InvalidCAMServer"] = reflect.TypeOf((*InvalidCAMServer)(nil)).Elem() +} + +type InvalidCAMServerFault BaseInvalidCAMServer + +func init() { + t["InvalidCAMServerFault"] = reflect.TypeOf((*InvalidCAMServerFault)(nil)).Elem() +} + +type InvalidClientCertificate struct { + InvalidLogin +} + +func init() { + t["InvalidClientCertificate"] = reflect.TypeOf((*InvalidClientCertificate)(nil)).Elem() +} + +type InvalidClientCertificateFault InvalidClientCertificate + +func init() { + t["InvalidClientCertificateFault"] = reflect.TypeOf((*InvalidClientCertificateFault)(nil)).Elem() +} + +type InvalidCollectorVersion struct { + MethodFault +} + +func init() { + t["InvalidCollectorVersion"] = reflect.TypeOf((*InvalidCollectorVersion)(nil)).Elem() +} + +type InvalidCollectorVersionFault InvalidCollectorVersion + +func init() { + t["InvalidCollectorVersionFault"] = reflect.TypeOf((*InvalidCollectorVersionFault)(nil)).Elem() +} + +type InvalidController struct { + InvalidDeviceSpec + + ControllerKey int32 `xml:"controllerKey"` +} + +func init() { + t["InvalidController"] = reflect.TypeOf((*InvalidController)(nil)).Elem() +} + +type InvalidControllerFault InvalidController + +func init() { + t["InvalidControllerFault"] = reflect.TypeOf((*InvalidControllerFault)(nil)).Elem() +} + +type InvalidDasConfigArgument struct { + InvalidArgument + + Entry string `xml:"entry,omitempty"` + ClusterName string `xml:"clusterName,omitempty"` +} + +func init() { + t["InvalidDasConfigArgument"] = reflect.TypeOf((*InvalidDasConfigArgument)(nil)).Elem() +} + +type InvalidDasConfigArgumentFault InvalidDasConfigArgument + +func init() { + t["InvalidDasConfigArgumentFault"] = reflect.TypeOf((*InvalidDasConfigArgumentFault)(nil)).Elem() +} + +type InvalidDasRestartPriorityForFtVm struct { + InvalidArgument + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["InvalidDasRestartPriorityForFtVm"] = reflect.TypeOf((*InvalidDasRestartPriorityForFtVm)(nil)).Elem() +} + +type InvalidDasRestartPriorityForFtVmFault InvalidDasRestartPriorityForFtVm + +func init() { + t["InvalidDasRestartPriorityForFtVmFault"] = reflect.TypeOf((*InvalidDasRestartPriorityForFtVmFault)(nil)).Elem() +} + +type InvalidDatastore struct { + VimFault + + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` + Name string `xml:"name,omitempty"` +} + +func init() { + t["InvalidDatastore"] = reflect.TypeOf((*InvalidDatastore)(nil)).Elem() +} + +type InvalidDatastoreFault BaseInvalidDatastore + +func init() { + t["InvalidDatastoreFault"] = reflect.TypeOf((*InvalidDatastoreFault)(nil)).Elem() +} + +type InvalidDatastorePath struct { + InvalidDatastore + + DatastorePath string `xml:"datastorePath"` +} + +func init() { + t["InvalidDatastorePath"] = reflect.TypeOf((*InvalidDatastorePath)(nil)).Elem() +} + +type InvalidDatastorePathFault InvalidDatastorePath + +func init() { + t["InvalidDatastorePathFault"] = reflect.TypeOf((*InvalidDatastorePathFault)(nil)).Elem() +} + +type InvalidDatastoreState struct { + InvalidState + + DatastoreName string `xml:"datastoreName,omitempty"` +} + +func init() { + t["InvalidDatastoreState"] = reflect.TypeOf((*InvalidDatastoreState)(nil)).Elem() +} + +type InvalidDatastoreStateFault InvalidDatastoreState + +func init() { + t["InvalidDatastoreStateFault"] = reflect.TypeOf((*InvalidDatastoreStateFault)(nil)).Elem() +} + +type InvalidDeviceBacking struct { + InvalidDeviceSpec +} + +func init() { + t["InvalidDeviceBacking"] = reflect.TypeOf((*InvalidDeviceBacking)(nil)).Elem() +} + +type InvalidDeviceBackingFault InvalidDeviceBacking + +func init() { + t["InvalidDeviceBackingFault"] = reflect.TypeOf((*InvalidDeviceBackingFault)(nil)).Elem() +} + +type InvalidDeviceOperation struct { + InvalidDeviceSpec + + BadOp VirtualDeviceConfigSpecOperation `xml:"badOp,omitempty"` + BadFileOp VirtualDeviceConfigSpecFileOperation `xml:"badFileOp,omitempty"` +} + +func init() { + t["InvalidDeviceOperation"] = reflect.TypeOf((*InvalidDeviceOperation)(nil)).Elem() +} + +type InvalidDeviceOperationFault InvalidDeviceOperation + +func init() { + t["InvalidDeviceOperationFault"] = reflect.TypeOf((*InvalidDeviceOperationFault)(nil)).Elem() +} + +type InvalidDeviceSpec struct { + InvalidVmConfig + + DeviceIndex int32 `xml:"deviceIndex"` +} + +func init() { + t["InvalidDeviceSpec"] = reflect.TypeOf((*InvalidDeviceSpec)(nil)).Elem() +} + +type InvalidDeviceSpecFault BaseInvalidDeviceSpec + +func init() { + t["InvalidDeviceSpecFault"] = reflect.TypeOf((*InvalidDeviceSpecFault)(nil)).Elem() +} + +type InvalidDiskFormat struct { + InvalidFormat +} + +func init() { + t["InvalidDiskFormat"] = reflect.TypeOf((*InvalidDiskFormat)(nil)).Elem() +} + +type InvalidDiskFormatFault InvalidDiskFormat + +func init() { + t["InvalidDiskFormatFault"] = reflect.TypeOf((*InvalidDiskFormatFault)(nil)).Elem() +} + +type InvalidDrsBehaviorForFtVm struct { + InvalidArgument + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["InvalidDrsBehaviorForFtVm"] = reflect.TypeOf((*InvalidDrsBehaviorForFtVm)(nil)).Elem() +} + +type InvalidDrsBehaviorForFtVmFault InvalidDrsBehaviorForFtVm + +func init() { + t["InvalidDrsBehaviorForFtVmFault"] = reflect.TypeOf((*InvalidDrsBehaviorForFtVmFault)(nil)).Elem() +} + +type InvalidEditionEvent struct { + LicenseEvent + + Feature string `xml:"feature"` +} + +func init() { + t["InvalidEditionEvent"] = reflect.TypeOf((*InvalidEditionEvent)(nil)).Elem() +} + +type InvalidEditionLicense struct { + NotEnoughLicenses + + Feature string `xml:"feature"` +} + +func init() { + t["InvalidEditionLicense"] = reflect.TypeOf((*InvalidEditionLicense)(nil)).Elem() +} + +type InvalidEditionLicenseFault InvalidEditionLicense + +func init() { + t["InvalidEditionLicenseFault"] = reflect.TypeOf((*InvalidEditionLicenseFault)(nil)).Elem() +} + +type InvalidEvent struct { + VimFault +} + +func init() { + t["InvalidEvent"] = reflect.TypeOf((*InvalidEvent)(nil)).Elem() +} + +type InvalidEventFault InvalidEvent + +func init() { + t["InvalidEventFault"] = reflect.TypeOf((*InvalidEventFault)(nil)).Elem() +} + +type InvalidFolder struct { + VimFault + + Target ManagedObjectReference `xml:"target"` +} + +func init() { + t["InvalidFolder"] = reflect.TypeOf((*InvalidFolder)(nil)).Elem() +} + +type InvalidFolderFault BaseInvalidFolder + +func init() { + t["InvalidFolderFault"] = reflect.TypeOf((*InvalidFolderFault)(nil)).Elem() +} + +type InvalidFormat struct { + VmConfigFault +} + +func init() { + t["InvalidFormat"] = reflect.TypeOf((*InvalidFormat)(nil)).Elem() +} + +type InvalidFormatFault BaseInvalidFormat + +func init() { + t["InvalidFormatFault"] = reflect.TypeOf((*InvalidFormatFault)(nil)).Elem() +} + +type InvalidGuestLogin struct { + GuestOperationsFault +} + +func init() { + t["InvalidGuestLogin"] = reflect.TypeOf((*InvalidGuestLogin)(nil)).Elem() +} + +type InvalidGuestLoginFault InvalidGuestLogin + +func init() { + t["InvalidGuestLoginFault"] = reflect.TypeOf((*InvalidGuestLoginFault)(nil)).Elem() +} + +type InvalidHostConnectionState struct { + InvalidHostState +} + +func init() { + t["InvalidHostConnectionState"] = reflect.TypeOf((*InvalidHostConnectionState)(nil)).Elem() +} + +type InvalidHostConnectionStateFault InvalidHostConnectionState + +func init() { + t["InvalidHostConnectionStateFault"] = reflect.TypeOf((*InvalidHostConnectionStateFault)(nil)).Elem() +} + +type InvalidHostName struct { + HostConfigFault +} + +func init() { + t["InvalidHostName"] = reflect.TypeOf((*InvalidHostName)(nil)).Elem() +} + +type InvalidHostNameFault InvalidHostName + +func init() { + t["InvalidHostNameFault"] = reflect.TypeOf((*InvalidHostNameFault)(nil)).Elem() +} + +type InvalidHostState struct { + InvalidState + + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["InvalidHostState"] = reflect.TypeOf((*InvalidHostState)(nil)).Elem() +} + +type InvalidHostStateFault BaseInvalidHostState + +func init() { + t["InvalidHostStateFault"] = reflect.TypeOf((*InvalidHostStateFault)(nil)).Elem() +} + +type InvalidIndexArgument struct { + InvalidArgument + + Key string `xml:"key"` +} + +func init() { + t["InvalidIndexArgument"] = reflect.TypeOf((*InvalidIndexArgument)(nil)).Elem() +} + +type InvalidIndexArgumentFault InvalidIndexArgument + +func init() { + t["InvalidIndexArgumentFault"] = reflect.TypeOf((*InvalidIndexArgumentFault)(nil)).Elem() +} + +type InvalidIpfixConfig struct { + DvsFault + + Property string `xml:"property,omitempty"` +} + +func init() { + t["InvalidIpfixConfig"] = reflect.TypeOf((*InvalidIpfixConfig)(nil)).Elem() +} + +type InvalidIpfixConfigFault InvalidIpfixConfig + +func init() { + t["InvalidIpfixConfigFault"] = reflect.TypeOf((*InvalidIpfixConfigFault)(nil)).Elem() +} + +type InvalidIpmiLoginInfo struct { + VimFault +} + +func init() { + t["InvalidIpmiLoginInfo"] = reflect.TypeOf((*InvalidIpmiLoginInfo)(nil)).Elem() +} + +type InvalidIpmiLoginInfoFault InvalidIpmiLoginInfo + +func init() { + t["InvalidIpmiLoginInfoFault"] = reflect.TypeOf((*InvalidIpmiLoginInfoFault)(nil)).Elem() +} + +type InvalidIpmiMacAddress struct { + VimFault + + UserProvidedMacAddress string `xml:"userProvidedMacAddress"` + ObservedMacAddress string `xml:"observedMacAddress"` +} + +func init() { + t["InvalidIpmiMacAddress"] = reflect.TypeOf((*InvalidIpmiMacAddress)(nil)).Elem() +} + +type InvalidIpmiMacAddressFault InvalidIpmiMacAddress + +func init() { + t["InvalidIpmiMacAddressFault"] = reflect.TypeOf((*InvalidIpmiMacAddressFault)(nil)).Elem() +} + +type InvalidLicense struct { + VimFault + + LicenseContent string `xml:"licenseContent"` +} + +func init() { + t["InvalidLicense"] = reflect.TypeOf((*InvalidLicense)(nil)).Elem() +} + +type InvalidLicenseFault InvalidLicense + +func init() { + t["InvalidLicenseFault"] = reflect.TypeOf((*InvalidLicenseFault)(nil)).Elem() +} + +type InvalidLocale struct { + VimFault +} + +func init() { + t["InvalidLocale"] = reflect.TypeOf((*InvalidLocale)(nil)).Elem() +} + +type InvalidLocaleFault InvalidLocale + +func init() { + t["InvalidLocaleFault"] = reflect.TypeOf((*InvalidLocaleFault)(nil)).Elem() +} + +type InvalidLogin struct { + VimFault +} + +func init() { + t["InvalidLogin"] = reflect.TypeOf((*InvalidLogin)(nil)).Elem() +} + +type InvalidLoginFault BaseInvalidLogin + +func init() { + t["InvalidLoginFault"] = reflect.TypeOf((*InvalidLoginFault)(nil)).Elem() +} + +type InvalidName struct { + VimFault + + Name string `xml:"name"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["InvalidName"] = reflect.TypeOf((*InvalidName)(nil)).Elem() +} + +type InvalidNameFault InvalidName + +func init() { + t["InvalidNameFault"] = reflect.TypeOf((*InvalidNameFault)(nil)).Elem() +} + +type InvalidNasCredentials struct { + NasConfigFault + + UserName string `xml:"userName"` +} + +func init() { + t["InvalidNasCredentials"] = reflect.TypeOf((*InvalidNasCredentials)(nil)).Elem() +} + +type InvalidNasCredentialsFault InvalidNasCredentials + +func init() { + t["InvalidNasCredentialsFault"] = reflect.TypeOf((*InvalidNasCredentialsFault)(nil)).Elem() +} + +type InvalidNetworkInType struct { + VAppPropertyFault +} + +func init() { + t["InvalidNetworkInType"] = reflect.TypeOf((*InvalidNetworkInType)(nil)).Elem() +} + +type InvalidNetworkInTypeFault InvalidNetworkInType + +func init() { + t["InvalidNetworkInTypeFault"] = reflect.TypeOf((*InvalidNetworkInTypeFault)(nil)).Elem() +} + +type InvalidNetworkResource struct { + NasConfigFault + + RemoteHost string `xml:"remoteHost"` + RemotePath string `xml:"remotePath"` +} + +func init() { + t["InvalidNetworkResource"] = reflect.TypeOf((*InvalidNetworkResource)(nil)).Elem() +} + +type InvalidNetworkResourceFault InvalidNetworkResource + +func init() { + t["InvalidNetworkResourceFault"] = reflect.TypeOf((*InvalidNetworkResourceFault)(nil)).Elem() +} + +type InvalidOperationOnSecondaryVm struct { + VmFaultToleranceIssue + + InstanceUuid string `xml:"instanceUuid,omitempty"` +} + +func init() { + t["InvalidOperationOnSecondaryVm"] = reflect.TypeOf((*InvalidOperationOnSecondaryVm)(nil)).Elem() +} + +type InvalidOperationOnSecondaryVmFault InvalidOperationOnSecondaryVm + +func init() { + t["InvalidOperationOnSecondaryVmFault"] = reflect.TypeOf((*InvalidOperationOnSecondaryVmFault)(nil)).Elem() +} + +type InvalidPowerState struct { + InvalidState + + RequestedState VirtualMachinePowerState `xml:"requestedState,omitempty"` + ExistingState VirtualMachinePowerState `xml:"existingState"` +} + +func init() { + t["InvalidPowerState"] = reflect.TypeOf((*InvalidPowerState)(nil)).Elem() +} + +type InvalidPowerStateFault InvalidPowerState + +func init() { + t["InvalidPowerStateFault"] = reflect.TypeOf((*InvalidPowerStateFault)(nil)).Elem() +} + +type InvalidPrivilege struct { + VimFault + + Privilege string `xml:"privilege"` +} + +func init() { + t["InvalidPrivilege"] = reflect.TypeOf((*InvalidPrivilege)(nil)).Elem() +} + +type InvalidPrivilegeFault InvalidPrivilege + +func init() { + t["InvalidPrivilegeFault"] = reflect.TypeOf((*InvalidPrivilegeFault)(nil)).Elem() +} + +type InvalidProfileReferenceHost struct { + RuntimeFault + + Reason string `xml:"reason,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Profile *ManagedObjectReference `xml:"profile,omitempty"` +} + +func init() { + t["InvalidProfileReferenceHost"] = reflect.TypeOf((*InvalidProfileReferenceHost)(nil)).Elem() +} + +type InvalidProfileReferenceHostFault InvalidProfileReferenceHost + +func init() { + t["InvalidProfileReferenceHostFault"] = reflect.TypeOf((*InvalidProfileReferenceHostFault)(nil)).Elem() +} + +type InvalidProperty struct { + MethodFault + + Name string `xml:"name"` +} + +func init() { + t["InvalidProperty"] = reflect.TypeOf((*InvalidProperty)(nil)).Elem() +} + +type InvalidPropertyFault InvalidProperty + +func init() { + t["InvalidPropertyFault"] = reflect.TypeOf((*InvalidPropertyFault)(nil)).Elem() +} + +type InvalidPropertyType struct { + VAppPropertyFault +} + +func init() { + t["InvalidPropertyType"] = reflect.TypeOf((*InvalidPropertyType)(nil)).Elem() +} + +type InvalidPropertyTypeFault InvalidPropertyType + +func init() { + t["InvalidPropertyTypeFault"] = reflect.TypeOf((*InvalidPropertyTypeFault)(nil)).Elem() +} + +type InvalidPropertyValue struct { + VAppPropertyFault +} + +func init() { + t["InvalidPropertyValue"] = reflect.TypeOf((*InvalidPropertyValue)(nil)).Elem() +} + +type InvalidPropertyValueFault BaseInvalidPropertyValue + +func init() { + t["InvalidPropertyValueFault"] = reflect.TypeOf((*InvalidPropertyValueFault)(nil)).Elem() +} + +type InvalidRequest struct { + RuntimeFault +} + +func init() { + t["InvalidRequest"] = reflect.TypeOf((*InvalidRequest)(nil)).Elem() +} + +type InvalidRequestFault BaseInvalidRequest + +func init() { + t["InvalidRequestFault"] = reflect.TypeOf((*InvalidRequestFault)(nil)).Elem() +} + +type InvalidResourcePoolStructureFault struct { + InsufficientResourcesFault +} + +func init() { + t["InvalidResourcePoolStructureFault"] = reflect.TypeOf((*InvalidResourcePoolStructureFault)(nil)).Elem() +} + +type InvalidResourcePoolStructureFaultFault InvalidResourcePoolStructureFault + +func init() { + t["InvalidResourcePoolStructureFaultFault"] = reflect.TypeOf((*InvalidResourcePoolStructureFaultFault)(nil)).Elem() +} + +type InvalidSnapshotFormat struct { + InvalidFormat +} + +func init() { + t["InvalidSnapshotFormat"] = reflect.TypeOf((*InvalidSnapshotFormat)(nil)).Elem() +} + +type InvalidSnapshotFormatFault InvalidSnapshotFormat + +func init() { + t["InvalidSnapshotFormatFault"] = reflect.TypeOf((*InvalidSnapshotFormatFault)(nil)).Elem() +} + +type InvalidState struct { + VimFault +} + +func init() { + t["InvalidState"] = reflect.TypeOf((*InvalidState)(nil)).Elem() +} + +type InvalidStateFault BaseInvalidState + +func init() { + t["InvalidStateFault"] = reflect.TypeOf((*InvalidStateFault)(nil)).Elem() +} + +type InvalidType struct { + InvalidRequest + + Argument string `xml:"argument,omitempty"` +} + +func init() { + t["InvalidType"] = reflect.TypeOf((*InvalidType)(nil)).Elem() +} + +type InvalidTypeFault InvalidType + +func init() { + t["InvalidTypeFault"] = reflect.TypeOf((*InvalidTypeFault)(nil)).Elem() +} + +type InvalidVmConfig struct { + VmConfigFault + + Property string `xml:"property,omitempty"` +} + +func init() { + t["InvalidVmConfig"] = reflect.TypeOf((*InvalidVmConfig)(nil)).Elem() +} + +type InvalidVmConfigFault BaseInvalidVmConfig + +func init() { + t["InvalidVmConfigFault"] = reflect.TypeOf((*InvalidVmConfigFault)(nil)).Elem() +} + +type InventoryDescription struct { + DynamicData + + NumHosts int32 `xml:"numHosts"` + NumVirtualMachines int32 `xml:"numVirtualMachines"` + NumResourcePools int32 `xml:"numResourcePools,omitempty"` + NumClusters int32 `xml:"numClusters,omitempty"` + NumCpuDev int32 `xml:"numCpuDev,omitempty"` + NumNetDev int32 `xml:"numNetDev,omitempty"` + NumDiskDev int32 `xml:"numDiskDev,omitempty"` + NumvCpuDev int32 `xml:"numvCpuDev,omitempty"` + NumvNetDev int32 `xml:"numvNetDev,omitempty"` + NumvDiskDev int32 `xml:"numvDiskDev,omitempty"` +} + +func init() { + t["InventoryDescription"] = reflect.TypeOf((*InventoryDescription)(nil)).Elem() +} + +type InventoryHasStandardAloneHosts struct { + NotEnoughLicenses + + Hosts []string `xml:"hosts"` +} + +func init() { + t["InventoryHasStandardAloneHosts"] = reflect.TypeOf((*InventoryHasStandardAloneHosts)(nil)).Elem() +} + +type InventoryHasStandardAloneHostsFault InventoryHasStandardAloneHosts + +func init() { + t["InventoryHasStandardAloneHostsFault"] = reflect.TypeOf((*InventoryHasStandardAloneHostsFault)(nil)).Elem() +} + +type IoFilterHostIssue struct { + DynamicData + + Host ManagedObjectReference `xml:"host"` + Issue []LocalizedMethodFault `xml:"issue"` +} + +func init() { + t["IoFilterHostIssue"] = reflect.TypeOf((*IoFilterHostIssue)(nil)).Elem() +} + +type IoFilterInfo struct { + DynamicData + + Id string `xml:"id"` + Name string `xml:"name"` + Vendor string `xml:"vendor"` + Version string `xml:"version"` + Summary string `xml:"summary,omitempty"` + ReleaseDate string `xml:"releaseDate,omitempty"` +} + +func init() { + t["IoFilterInfo"] = reflect.TypeOf((*IoFilterInfo)(nil)).Elem() +} + +type IoFilterQueryIssueResult struct { + DynamicData + + OpType string `xml:"opType"` + HostIssue []IoFilterHostIssue `xml:"hostIssue,omitempty"` +} + +func init() { + t["IoFilterQueryIssueResult"] = reflect.TypeOf((*IoFilterQueryIssueResult)(nil)).Elem() +} + +type IpAddress struct { + NegatableExpression +} + +func init() { + t["IpAddress"] = reflect.TypeOf((*IpAddress)(nil)).Elem() +} + +type IpAddressProfile struct { + ApplyProfile +} + +func init() { + t["IpAddressProfile"] = reflect.TypeOf((*IpAddressProfile)(nil)).Elem() +} + +type IpHostnameGeneratorError struct { + CustomizationFault +} + +func init() { + t["IpHostnameGeneratorError"] = reflect.TypeOf((*IpHostnameGeneratorError)(nil)).Elem() +} + +type IpHostnameGeneratorErrorFault IpHostnameGeneratorError + +func init() { + t["IpHostnameGeneratorErrorFault"] = reflect.TypeOf((*IpHostnameGeneratorErrorFault)(nil)).Elem() +} + +type IpPool struct { + DynamicData + + Id int32 `xml:"id,omitempty"` + Name string `xml:"name,omitempty"` + Ipv4Config *IpPoolIpPoolConfigInfo `xml:"ipv4Config,omitempty"` + Ipv6Config *IpPoolIpPoolConfigInfo `xml:"ipv6Config,omitempty"` + DnsDomain string `xml:"dnsDomain,omitempty"` + DnsSearchPath string `xml:"dnsSearchPath,omitempty"` + HostPrefix string `xml:"hostPrefix,omitempty"` + HttpProxy string `xml:"httpProxy,omitempty"` + NetworkAssociation []IpPoolAssociation `xml:"networkAssociation,omitempty"` + AvailableIpv4Addresses int32 `xml:"availableIpv4Addresses,omitempty"` + AvailableIpv6Addresses int32 `xml:"availableIpv6Addresses,omitempty"` + AllocatedIpv4Addresses int32 `xml:"allocatedIpv4Addresses,omitempty"` + AllocatedIpv6Addresses int32 `xml:"allocatedIpv6Addresses,omitempty"` +} + +func init() { + t["IpPool"] = reflect.TypeOf((*IpPool)(nil)).Elem() +} + +type IpPoolAssociation struct { + DynamicData + + Network *ManagedObjectReference `xml:"network,omitempty"` + NetworkName string `xml:"networkName"` +} + +func init() { + t["IpPoolAssociation"] = reflect.TypeOf((*IpPoolAssociation)(nil)).Elem() +} + +type IpPoolIpPoolConfigInfo struct { + DynamicData + + SubnetAddress string `xml:"subnetAddress,omitempty"` + Netmask string `xml:"netmask,omitempty"` + Gateway string `xml:"gateway,omitempty"` + Range string `xml:"range,omitempty"` + Dns []string `xml:"dns,omitempty"` + DhcpServerAvailable *bool `xml:"dhcpServerAvailable"` + IpPoolEnabled *bool `xml:"ipPoolEnabled"` +} + +func init() { + t["IpPoolIpPoolConfigInfo"] = reflect.TypeOf((*IpPoolIpPoolConfigInfo)(nil)).Elem() +} + +type IpPoolManagerIpAllocation struct { + DynamicData + + IpAddress string `xml:"ipAddress"` + AllocationId string `xml:"allocationId"` +} + +func init() { + t["IpPoolManagerIpAllocation"] = reflect.TypeOf((*IpPoolManagerIpAllocation)(nil)).Elem() +} + +type IpRange struct { + IpAddress + + AddressPrefix string `xml:"addressPrefix"` + PrefixLength int32 `xml:"prefixLength,omitempty"` +} + +func init() { + t["IpRange"] = reflect.TypeOf((*IpRange)(nil)).Elem() +} + +type IpRouteProfile struct { + ApplyProfile + + StaticRoute []StaticRouteProfile `xml:"staticRoute,omitempty"` +} + +func init() { + t["IpRouteProfile"] = reflect.TypeOf((*IpRouteProfile)(nil)).Elem() +} + +type IsSharedGraphicsActive IsSharedGraphicsActiveRequestType + +func init() { + t["IsSharedGraphicsActive"] = reflect.TypeOf((*IsSharedGraphicsActive)(nil)).Elem() +} + +type IsSharedGraphicsActiveRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["IsSharedGraphicsActiveRequestType"] = reflect.TypeOf((*IsSharedGraphicsActiveRequestType)(nil)).Elem() +} + +type IsSharedGraphicsActiveResponse struct { + Returnval bool `xml:"returnval"` +} + +type IscsiDependencyEntity struct { + DynamicData + + PnicDevice string `xml:"pnicDevice"` + VnicDevice string `xml:"vnicDevice"` + VmhbaName string `xml:"vmhbaName"` +} + +func init() { + t["IscsiDependencyEntity"] = reflect.TypeOf((*IscsiDependencyEntity)(nil)).Elem() +} + +type IscsiFault struct { + VimFault +} + +func init() { + t["IscsiFault"] = reflect.TypeOf((*IscsiFault)(nil)).Elem() +} + +type IscsiFaultFault BaseIscsiFault + +func init() { + t["IscsiFaultFault"] = reflect.TypeOf((*IscsiFaultFault)(nil)).Elem() +} + +type IscsiFaultInvalidVnic struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultInvalidVnic"] = reflect.TypeOf((*IscsiFaultInvalidVnic)(nil)).Elem() +} + +type IscsiFaultInvalidVnicFault IscsiFaultInvalidVnic + +func init() { + t["IscsiFaultInvalidVnicFault"] = reflect.TypeOf((*IscsiFaultInvalidVnicFault)(nil)).Elem() +} + +type IscsiFaultPnicInUse struct { + IscsiFault + + PnicDevice string `xml:"pnicDevice"` +} + +func init() { + t["IscsiFaultPnicInUse"] = reflect.TypeOf((*IscsiFaultPnicInUse)(nil)).Elem() +} + +type IscsiFaultPnicInUseFault IscsiFaultPnicInUse + +func init() { + t["IscsiFaultPnicInUseFault"] = reflect.TypeOf((*IscsiFaultPnicInUseFault)(nil)).Elem() +} + +type IscsiFaultVnicAlreadyBound struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicAlreadyBound"] = reflect.TypeOf((*IscsiFaultVnicAlreadyBound)(nil)).Elem() +} + +type IscsiFaultVnicAlreadyBoundFault IscsiFaultVnicAlreadyBound + +func init() { + t["IscsiFaultVnicAlreadyBoundFault"] = reflect.TypeOf((*IscsiFaultVnicAlreadyBoundFault)(nil)).Elem() +} + +type IscsiFaultVnicHasActivePaths struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicHasActivePaths"] = reflect.TypeOf((*IscsiFaultVnicHasActivePaths)(nil)).Elem() +} + +type IscsiFaultVnicHasActivePathsFault IscsiFaultVnicHasActivePaths + +func init() { + t["IscsiFaultVnicHasActivePathsFault"] = reflect.TypeOf((*IscsiFaultVnicHasActivePathsFault)(nil)).Elem() +} + +type IscsiFaultVnicHasMultipleUplinks struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicHasMultipleUplinks"] = reflect.TypeOf((*IscsiFaultVnicHasMultipleUplinks)(nil)).Elem() +} + +type IscsiFaultVnicHasMultipleUplinksFault IscsiFaultVnicHasMultipleUplinks + +func init() { + t["IscsiFaultVnicHasMultipleUplinksFault"] = reflect.TypeOf((*IscsiFaultVnicHasMultipleUplinksFault)(nil)).Elem() +} + +type IscsiFaultVnicHasNoUplinks struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicHasNoUplinks"] = reflect.TypeOf((*IscsiFaultVnicHasNoUplinks)(nil)).Elem() +} + +type IscsiFaultVnicHasNoUplinksFault IscsiFaultVnicHasNoUplinks + +func init() { + t["IscsiFaultVnicHasNoUplinksFault"] = reflect.TypeOf((*IscsiFaultVnicHasNoUplinksFault)(nil)).Elem() +} + +type IscsiFaultVnicHasWrongUplink struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicHasWrongUplink"] = reflect.TypeOf((*IscsiFaultVnicHasWrongUplink)(nil)).Elem() +} + +type IscsiFaultVnicHasWrongUplinkFault IscsiFaultVnicHasWrongUplink + +func init() { + t["IscsiFaultVnicHasWrongUplinkFault"] = reflect.TypeOf((*IscsiFaultVnicHasWrongUplinkFault)(nil)).Elem() +} + +type IscsiFaultVnicInUse struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicInUse"] = reflect.TypeOf((*IscsiFaultVnicInUse)(nil)).Elem() +} + +type IscsiFaultVnicInUseFault IscsiFaultVnicInUse + +func init() { + t["IscsiFaultVnicInUseFault"] = reflect.TypeOf((*IscsiFaultVnicInUseFault)(nil)).Elem() +} + +type IscsiFaultVnicIsLastPath struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicIsLastPath"] = reflect.TypeOf((*IscsiFaultVnicIsLastPath)(nil)).Elem() +} + +type IscsiFaultVnicIsLastPathFault IscsiFaultVnicIsLastPath + +func init() { + t["IscsiFaultVnicIsLastPathFault"] = reflect.TypeOf((*IscsiFaultVnicIsLastPathFault)(nil)).Elem() +} + +type IscsiFaultVnicNotBound struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicNotBound"] = reflect.TypeOf((*IscsiFaultVnicNotBound)(nil)).Elem() +} + +type IscsiFaultVnicNotBoundFault IscsiFaultVnicNotBound + +func init() { + t["IscsiFaultVnicNotBoundFault"] = reflect.TypeOf((*IscsiFaultVnicNotBoundFault)(nil)).Elem() +} + +type IscsiFaultVnicNotFound struct { + IscsiFault + + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["IscsiFaultVnicNotFound"] = reflect.TypeOf((*IscsiFaultVnicNotFound)(nil)).Elem() +} + +type IscsiFaultVnicNotFoundFault IscsiFaultVnicNotFound + +func init() { + t["IscsiFaultVnicNotFoundFault"] = reflect.TypeOf((*IscsiFaultVnicNotFoundFault)(nil)).Elem() +} + +type IscsiMigrationDependency struct { + DynamicData + + MigrationAllowed bool `xml:"migrationAllowed"` + DisallowReason *IscsiStatus `xml:"disallowReason,omitempty"` + Dependency []IscsiDependencyEntity `xml:"dependency,omitempty"` +} + +func init() { + t["IscsiMigrationDependency"] = reflect.TypeOf((*IscsiMigrationDependency)(nil)).Elem() +} + +type IscsiPortInfo struct { + DynamicData + + VnicDevice string `xml:"vnicDevice,omitempty"` + Vnic *HostVirtualNic `xml:"vnic,omitempty"` + PnicDevice string `xml:"pnicDevice,omitempty"` + Pnic *PhysicalNic `xml:"pnic,omitempty"` + SwitchName string `xml:"switchName,omitempty"` + SwitchUuid string `xml:"switchUuid,omitempty"` + PortgroupName string `xml:"portgroupName,omitempty"` + PortgroupKey string `xml:"portgroupKey,omitempty"` + PortKey string `xml:"portKey,omitempty"` + ComplianceStatus *IscsiStatus `xml:"complianceStatus,omitempty"` + PathStatus string `xml:"pathStatus,omitempty"` +} + +func init() { + t["IscsiPortInfo"] = reflect.TypeOf((*IscsiPortInfo)(nil)).Elem() +} + +type IscsiStatus struct { + DynamicData + + Reason []LocalizedMethodFault `xml:"reason,omitempty"` +} + +func init() { + t["IscsiStatus"] = reflect.TypeOf((*IscsiStatus)(nil)).Elem() +} + +type IsoImageFileInfo struct { + FileInfo +} + +func init() { + t["IsoImageFileInfo"] = reflect.TypeOf((*IsoImageFileInfo)(nil)).Elem() +} + +type IsoImageFileQuery struct { + FileQuery +} + +func init() { + t["IsoImageFileQuery"] = reflect.TypeOf((*IsoImageFileQuery)(nil)).Elem() +} + +type JoinDomainRequestType struct { + This ManagedObjectReference `xml:"_this"` + DomainName string `xml:"domainName"` + UserName string `xml:"userName"` + Password string `xml:"password"` +} + +func init() { + t["JoinDomainRequestType"] = reflect.TypeOf((*JoinDomainRequestType)(nil)).Elem() +} + +type JoinDomainWithCAMRequestType struct { + This ManagedObjectReference `xml:"_this"` + DomainName string `xml:"domainName"` + CamServer string `xml:"camServer"` +} + +func init() { + t["JoinDomainWithCAMRequestType"] = reflect.TypeOf((*JoinDomainWithCAMRequestType)(nil)).Elem() +} + +type JoinDomainWithCAM_Task JoinDomainWithCAMRequestType + +func init() { + t["JoinDomainWithCAM_Task"] = reflect.TypeOf((*JoinDomainWithCAM_Task)(nil)).Elem() +} + +type JoinDomainWithCAM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type JoinDomain_Task JoinDomainRequestType + +func init() { + t["JoinDomain_Task"] = reflect.TypeOf((*JoinDomain_Task)(nil)).Elem() +} + +type JoinDomain_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type KernelModuleInfo struct { + DynamicData + + Id int32 `xml:"id"` + Name string `xml:"name"` + Version string `xml:"version"` + Filename string `xml:"filename"` + OptionString string `xml:"optionString"` + Loaded bool `xml:"loaded"` + Enabled bool `xml:"enabled"` + UseCount int32 `xml:"useCount"` + ReadOnlySection KernelModuleSectionInfo `xml:"readOnlySection"` + WritableSection KernelModuleSectionInfo `xml:"writableSection"` + TextSection KernelModuleSectionInfo `xml:"textSection"` + DataSection KernelModuleSectionInfo `xml:"dataSection"` + BssSection KernelModuleSectionInfo `xml:"bssSection"` +} + +func init() { + t["KernelModuleInfo"] = reflect.TypeOf((*KernelModuleInfo)(nil)).Elem() +} + +type KernelModuleSectionInfo struct { + DynamicData + + Address int64 `xml:"address"` + Length int32 `xml:"length,omitempty"` +} + +func init() { + t["KernelModuleSectionInfo"] = reflect.TypeOf((*KernelModuleSectionInfo)(nil)).Elem() +} + +type KeyAnyValue struct { + DynamicData + + Key string `xml:"key"` + Value AnyType `xml:"value,typeattr"` +} + +func init() { + t["KeyAnyValue"] = reflect.TypeOf((*KeyAnyValue)(nil)).Elem() +} + +type KeyValue struct { + DynamicData + + Key string `xml:"key"` + Value string `xml:"value"` +} + +func init() { + t["KeyValue"] = reflect.TypeOf((*KeyValue)(nil)).Elem() +} + +type LargeRDMConversionNotSupported struct { + MigrationFault + + Device string `xml:"device"` +} + +func init() { + t["LargeRDMConversionNotSupported"] = reflect.TypeOf((*LargeRDMConversionNotSupported)(nil)).Elem() +} + +type LargeRDMConversionNotSupportedFault LargeRDMConversionNotSupported + +func init() { + t["LargeRDMConversionNotSupportedFault"] = reflect.TypeOf((*LargeRDMConversionNotSupportedFault)(nil)).Elem() +} + +type LargeRDMNotSupportedOnDatastore struct { + VmConfigFault + + Device string `xml:"device"` + Datastore ManagedObjectReference `xml:"datastore"` + DatastoreName string `xml:"datastoreName"` +} + +func init() { + t["LargeRDMNotSupportedOnDatastore"] = reflect.TypeOf((*LargeRDMNotSupportedOnDatastore)(nil)).Elem() +} + +type LargeRDMNotSupportedOnDatastoreFault LargeRDMNotSupportedOnDatastore + +func init() { + t["LargeRDMNotSupportedOnDatastoreFault"] = reflect.TypeOf((*LargeRDMNotSupportedOnDatastoreFault)(nil)).Elem() +} + +type LatencySensitivity struct { + DynamicData + + Level LatencySensitivitySensitivityLevel `xml:"level"` + Sensitivity int32 `xml:"sensitivity,omitempty"` +} + +func init() { + t["LatencySensitivity"] = reflect.TypeOf((*LatencySensitivity)(nil)).Elem() +} + +type LeaveCurrentDomainRequestType struct { + This ManagedObjectReference `xml:"_this"` + Force bool `xml:"force"` +} + +func init() { + t["LeaveCurrentDomainRequestType"] = reflect.TypeOf((*LeaveCurrentDomainRequestType)(nil)).Elem() +} + +type LeaveCurrentDomain_Task LeaveCurrentDomainRequestType + +func init() { + t["LeaveCurrentDomain_Task"] = reflect.TypeOf((*LeaveCurrentDomain_Task)(nil)).Elem() +} + +type LeaveCurrentDomain_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type LegacyNetworkInterfaceInUse struct { + CannotAccessNetwork +} + +func init() { + t["LegacyNetworkInterfaceInUse"] = reflect.TypeOf((*LegacyNetworkInterfaceInUse)(nil)).Elem() +} + +type LegacyNetworkInterfaceInUseFault LegacyNetworkInterfaceInUse + +func init() { + t["LegacyNetworkInterfaceInUseFault"] = reflect.TypeOf((*LegacyNetworkInterfaceInUseFault)(nil)).Elem() +} + +type LicenseAssignmentFailed struct { + RuntimeFault + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["LicenseAssignmentFailed"] = reflect.TypeOf((*LicenseAssignmentFailed)(nil)).Elem() +} + +type LicenseAssignmentFailedFault LicenseAssignmentFailed + +func init() { + t["LicenseAssignmentFailedFault"] = reflect.TypeOf((*LicenseAssignmentFailedFault)(nil)).Elem() +} + +type LicenseAssignmentManagerLicenseAssignment struct { + DynamicData + + EntityId string `xml:"entityId"` + Scope string `xml:"scope,omitempty"` + EntityDisplayName string `xml:"entityDisplayName,omitempty"` + AssignedLicense LicenseManagerLicenseInfo `xml:"assignedLicense"` + Properties []KeyAnyValue `xml:"properties,omitempty"` +} + +func init() { + t["LicenseAssignmentManagerLicenseAssignment"] = reflect.TypeOf((*LicenseAssignmentManagerLicenseAssignment)(nil)).Elem() +} + +type LicenseAvailabilityInfo struct { + DynamicData + + Feature LicenseFeatureInfo `xml:"feature"` + Total int32 `xml:"total"` + Available int32 `xml:"available"` +} + +func init() { + t["LicenseAvailabilityInfo"] = reflect.TypeOf((*LicenseAvailabilityInfo)(nil)).Elem() +} + +type LicenseDiagnostics struct { + DynamicData + + SourceLastChanged time.Time `xml:"sourceLastChanged"` + SourceLost string `xml:"sourceLost"` + SourceLatency float32 `xml:"sourceLatency"` + LicenseRequests string `xml:"licenseRequests"` + LicenseRequestFailures string `xml:"licenseRequestFailures"` + LicenseFeatureUnknowns string `xml:"licenseFeatureUnknowns"` + OpState LicenseManagerState `xml:"opState"` + LastStatusUpdate time.Time `xml:"lastStatusUpdate"` + OpFailureMessage string `xml:"opFailureMessage"` +} + +func init() { + t["LicenseDiagnostics"] = reflect.TypeOf((*LicenseDiagnostics)(nil)).Elem() +} + +type LicenseDowngradeDisallowed struct { + NotEnoughLicenses + + Edition string `xml:"edition"` + EntityId string `xml:"entityId"` + Features []KeyAnyValue `xml:"features"` +} + +func init() { + t["LicenseDowngradeDisallowed"] = reflect.TypeOf((*LicenseDowngradeDisallowed)(nil)).Elem() +} + +type LicenseDowngradeDisallowedFault LicenseDowngradeDisallowed + +func init() { + t["LicenseDowngradeDisallowedFault"] = reflect.TypeOf((*LicenseDowngradeDisallowedFault)(nil)).Elem() +} + +type LicenseEntityNotFound struct { + VimFault + + EntityId string `xml:"entityId"` +} + +func init() { + t["LicenseEntityNotFound"] = reflect.TypeOf((*LicenseEntityNotFound)(nil)).Elem() +} + +type LicenseEntityNotFoundFault LicenseEntityNotFound + +func init() { + t["LicenseEntityNotFoundFault"] = reflect.TypeOf((*LicenseEntityNotFoundFault)(nil)).Elem() +} + +type LicenseEvent struct { + Event +} + +func init() { + t["LicenseEvent"] = reflect.TypeOf((*LicenseEvent)(nil)).Elem() +} + +type LicenseExpired struct { + NotEnoughLicenses + + LicenseKey string `xml:"licenseKey"` +} + +func init() { + t["LicenseExpired"] = reflect.TypeOf((*LicenseExpired)(nil)).Elem() +} + +type LicenseExpiredEvent struct { + Event + + Feature LicenseFeatureInfo `xml:"feature"` +} + +func init() { + t["LicenseExpiredEvent"] = reflect.TypeOf((*LicenseExpiredEvent)(nil)).Elem() +} + +type LicenseExpiredFault LicenseExpired + +func init() { + t["LicenseExpiredFault"] = reflect.TypeOf((*LicenseExpiredFault)(nil)).Elem() +} + +type LicenseFeatureInfo struct { + DynamicData + + Key string `xml:"key"` + FeatureName string `xml:"featureName"` + FeatureDescription string `xml:"featureDescription,omitempty"` + State LicenseFeatureInfoState `xml:"state,omitempty"` + CostUnit string `xml:"costUnit"` + SourceRestriction string `xml:"sourceRestriction,omitempty"` + DependentKey []string `xml:"dependentKey,omitempty"` + Edition *bool `xml:"edition"` + ExpiresOn *time.Time `xml:"expiresOn"` +} + +func init() { + t["LicenseFeatureInfo"] = reflect.TypeOf((*LicenseFeatureInfo)(nil)).Elem() +} + +type LicenseKeyEntityMismatch struct { + NotEnoughLicenses +} + +func init() { + t["LicenseKeyEntityMismatch"] = reflect.TypeOf((*LicenseKeyEntityMismatch)(nil)).Elem() +} + +type LicenseKeyEntityMismatchFault LicenseKeyEntityMismatch + +func init() { + t["LicenseKeyEntityMismatchFault"] = reflect.TypeOf((*LicenseKeyEntityMismatchFault)(nil)).Elem() +} + +type LicenseManagerEvaluationInfo struct { + DynamicData + + Properties []KeyAnyValue `xml:"properties"` +} + +func init() { + t["LicenseManagerEvaluationInfo"] = reflect.TypeOf((*LicenseManagerEvaluationInfo)(nil)).Elem() +} + +type LicenseManagerLicenseInfo struct { + DynamicData + + LicenseKey string `xml:"licenseKey"` + EditionKey string `xml:"editionKey"` + Name string `xml:"name"` + Total int32 `xml:"total"` + Used int32 `xml:"used,omitempty"` + CostUnit string `xml:"costUnit"` + Properties []KeyAnyValue `xml:"properties,omitempty"` + Labels []KeyValue `xml:"labels,omitempty"` +} + +func init() { + t["LicenseManagerLicenseInfo"] = reflect.TypeOf((*LicenseManagerLicenseInfo)(nil)).Elem() +} + +type LicenseNonComplianceEvent struct { + LicenseEvent + + Url string `xml:"url"` +} + +func init() { + t["LicenseNonComplianceEvent"] = reflect.TypeOf((*LicenseNonComplianceEvent)(nil)).Elem() +} + +type LicenseReservationInfo struct { + DynamicData + + Key string `xml:"key"` + State LicenseReservationInfoState `xml:"state"` + Required int32 `xml:"required"` +} + +func init() { + t["LicenseReservationInfo"] = reflect.TypeOf((*LicenseReservationInfo)(nil)).Elem() +} + +type LicenseRestricted struct { + NotEnoughLicenses +} + +func init() { + t["LicenseRestricted"] = reflect.TypeOf((*LicenseRestricted)(nil)).Elem() +} + +type LicenseRestrictedEvent struct { + LicenseEvent +} + +func init() { + t["LicenseRestrictedEvent"] = reflect.TypeOf((*LicenseRestrictedEvent)(nil)).Elem() +} + +type LicenseRestrictedFault LicenseRestricted + +func init() { + t["LicenseRestrictedFault"] = reflect.TypeOf((*LicenseRestrictedFault)(nil)).Elem() +} + +type LicenseServerAvailableEvent struct { + LicenseEvent + + LicenseServer string `xml:"licenseServer"` +} + +func init() { + t["LicenseServerAvailableEvent"] = reflect.TypeOf((*LicenseServerAvailableEvent)(nil)).Elem() +} + +type LicenseServerSource struct { + LicenseSource + + LicenseServer string `xml:"licenseServer"` +} + +func init() { + t["LicenseServerSource"] = reflect.TypeOf((*LicenseServerSource)(nil)).Elem() +} + +type LicenseServerUnavailable struct { + VimFault + + LicenseServer string `xml:"licenseServer"` +} + +func init() { + t["LicenseServerUnavailable"] = reflect.TypeOf((*LicenseServerUnavailable)(nil)).Elem() +} + +type LicenseServerUnavailableEvent struct { + LicenseEvent + + LicenseServer string `xml:"licenseServer"` +} + +func init() { + t["LicenseServerUnavailableEvent"] = reflect.TypeOf((*LicenseServerUnavailableEvent)(nil)).Elem() +} + +type LicenseServerUnavailableFault LicenseServerUnavailable + +func init() { + t["LicenseServerUnavailableFault"] = reflect.TypeOf((*LicenseServerUnavailableFault)(nil)).Elem() +} + +type LicenseSource struct { + DynamicData +} + +func init() { + t["LicenseSource"] = reflect.TypeOf((*LicenseSource)(nil)).Elem() +} + +type LicenseSourceUnavailable struct { + NotEnoughLicenses + + LicenseSource BaseLicenseSource `xml:"licenseSource,typeattr"` +} + +func init() { + t["LicenseSourceUnavailable"] = reflect.TypeOf((*LicenseSourceUnavailable)(nil)).Elem() +} + +type LicenseSourceUnavailableFault LicenseSourceUnavailable + +func init() { + t["LicenseSourceUnavailableFault"] = reflect.TypeOf((*LicenseSourceUnavailableFault)(nil)).Elem() +} + +type LicenseUsageInfo struct { + DynamicData + + Source BaseLicenseSource `xml:"source,typeattr"` + SourceAvailable bool `xml:"sourceAvailable"` + ReservationInfo []LicenseReservationInfo `xml:"reservationInfo,omitempty"` + FeatureInfo []LicenseFeatureInfo `xml:"featureInfo,omitempty"` +} + +func init() { + t["LicenseUsageInfo"] = reflect.TypeOf((*LicenseUsageInfo)(nil)).Elem() +} + +type LimitExceeded struct { + VimFault + + Property string `xml:"property,omitempty"` + Limit int32 `xml:"limit,omitempty"` +} + +func init() { + t["LimitExceeded"] = reflect.TypeOf((*LimitExceeded)(nil)).Elem() +} + +type LimitExceededFault LimitExceeded + +func init() { + t["LimitExceededFault"] = reflect.TypeOf((*LimitExceededFault)(nil)).Elem() +} + +type LinkDiscoveryProtocolConfig struct { + DynamicData + + Protocol string `xml:"protocol"` + Operation string `xml:"operation"` +} + +func init() { + t["LinkDiscoveryProtocolConfig"] = reflect.TypeOf((*LinkDiscoveryProtocolConfig)(nil)).Elem() +} + +type LinkLayerDiscoveryProtocolInfo struct { + DynamicData + + ChassisId string `xml:"chassisId"` + PortId string `xml:"portId"` + TimeToLive int32 `xml:"timeToLive"` + Parameter []KeyAnyValue `xml:"parameter,omitempty"` +} + +func init() { + t["LinkLayerDiscoveryProtocolInfo"] = reflect.TypeOf((*LinkLayerDiscoveryProtocolInfo)(nil)).Elem() +} + +type LinkProfile struct { + ApplyProfile +} + +func init() { + t["LinkProfile"] = reflect.TypeOf((*LinkProfile)(nil)).Elem() +} + +type LinuxVolumeNotClean struct { + CustomizationFault +} + +func init() { + t["LinuxVolumeNotClean"] = reflect.TypeOf((*LinuxVolumeNotClean)(nil)).Elem() +} + +type LinuxVolumeNotCleanFault LinuxVolumeNotClean + +func init() { + t["LinuxVolumeNotCleanFault"] = reflect.TypeOf((*LinuxVolumeNotCleanFault)(nil)).Elem() +} + +type ListCACertificateRevocationLists ListCACertificateRevocationListsRequestType + +func init() { + t["ListCACertificateRevocationLists"] = reflect.TypeOf((*ListCACertificateRevocationLists)(nil)).Elem() +} + +type ListCACertificateRevocationListsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ListCACertificateRevocationListsRequestType"] = reflect.TypeOf((*ListCACertificateRevocationListsRequestType)(nil)).Elem() +} + +type ListCACertificateRevocationListsResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type ListCACertificates ListCACertificatesRequestType + +func init() { + t["ListCACertificates"] = reflect.TypeOf((*ListCACertificates)(nil)).Elem() +} + +type ListCACertificatesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ListCACertificatesRequestType"] = reflect.TypeOf((*ListCACertificatesRequestType)(nil)).Elem() +} + +type ListCACertificatesResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type ListFilesInGuest ListFilesInGuestRequestType + +func init() { + t["ListFilesInGuest"] = reflect.TypeOf((*ListFilesInGuest)(nil)).Elem() +} + +type ListFilesInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + FilePath string `xml:"filePath"` + Index int32 `xml:"index,omitempty"` + MaxResults int32 `xml:"maxResults,omitempty"` + MatchPattern string `xml:"matchPattern,omitempty"` +} + +func init() { + t["ListFilesInGuestRequestType"] = reflect.TypeOf((*ListFilesInGuestRequestType)(nil)).Elem() +} + +type ListFilesInGuestResponse struct { + Returnval GuestListFileInfo `xml:"returnval"` +} + +type ListGuestAliases ListGuestAliasesRequestType + +func init() { + t["ListGuestAliases"] = reflect.TypeOf((*ListGuestAliases)(nil)).Elem() +} + +type ListGuestAliasesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Username string `xml:"username"` +} + +func init() { + t["ListGuestAliasesRequestType"] = reflect.TypeOf((*ListGuestAliasesRequestType)(nil)).Elem() +} + +type ListGuestAliasesResponse struct { + Returnval []GuestAliases `xml:"returnval,omitempty"` +} + +type ListGuestMappedAliases ListGuestMappedAliasesRequestType + +func init() { + t["ListGuestMappedAliases"] = reflect.TypeOf((*ListGuestMappedAliases)(nil)).Elem() +} + +type ListGuestMappedAliasesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` +} + +func init() { + t["ListGuestMappedAliasesRequestType"] = reflect.TypeOf((*ListGuestMappedAliasesRequestType)(nil)).Elem() +} + +type ListGuestMappedAliasesResponse struct { + Returnval []GuestMappedAliases `xml:"returnval,omitempty"` +} + +type ListProcessesInGuest ListProcessesInGuestRequestType + +func init() { + t["ListProcessesInGuest"] = reflect.TypeOf((*ListProcessesInGuest)(nil)).Elem() +} + +type ListProcessesInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Pids []int64 `xml:"pids,omitempty"` +} + +func init() { + t["ListProcessesInGuestRequestType"] = reflect.TypeOf((*ListProcessesInGuestRequestType)(nil)).Elem() +} + +type ListProcessesInGuestResponse struct { + Returnval []GuestProcessInfo `xml:"returnval,omitempty"` +} + +type ListRegistryKeysInGuest ListRegistryKeysInGuestRequestType + +func init() { + t["ListRegistryKeysInGuest"] = reflect.TypeOf((*ListRegistryKeysInGuest)(nil)).Elem() +} + +type ListRegistryKeysInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + KeyName GuestRegKeyNameSpec `xml:"keyName"` + Recursive bool `xml:"recursive"` + MatchPattern string `xml:"matchPattern,omitempty"` +} + +func init() { + t["ListRegistryKeysInGuestRequestType"] = reflect.TypeOf((*ListRegistryKeysInGuestRequestType)(nil)).Elem() +} + +type ListRegistryKeysInGuestResponse struct { + Returnval []GuestRegKeyRecordSpec `xml:"returnval,omitempty"` +} + +type ListRegistryValuesInGuest ListRegistryValuesInGuestRequestType + +func init() { + t["ListRegistryValuesInGuest"] = reflect.TypeOf((*ListRegistryValuesInGuest)(nil)).Elem() +} + +type ListRegistryValuesInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + KeyName GuestRegKeyNameSpec `xml:"keyName"` + ExpandStrings bool `xml:"expandStrings"` + MatchPattern string `xml:"matchPattern,omitempty"` +} + +func init() { + t["ListRegistryValuesInGuestRequestType"] = reflect.TypeOf((*ListRegistryValuesInGuestRequestType)(nil)).Elem() +} + +type ListRegistryValuesInGuestResponse struct { + Returnval []GuestRegValueSpec `xml:"returnval,omitempty"` +} + +type ListSmartCardTrustAnchors ListSmartCardTrustAnchorsRequestType + +func init() { + t["ListSmartCardTrustAnchors"] = reflect.TypeOf((*ListSmartCardTrustAnchors)(nil)).Elem() +} + +type ListSmartCardTrustAnchorsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ListSmartCardTrustAnchorsRequestType"] = reflect.TypeOf((*ListSmartCardTrustAnchorsRequestType)(nil)).Elem() +} + +type ListSmartCardTrustAnchorsResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type LocalDatastoreCreatedEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["LocalDatastoreCreatedEvent"] = reflect.TypeOf((*LocalDatastoreCreatedEvent)(nil)).Elem() +} + +type LocalDatastoreInfo struct { + DatastoreInfo + + Path string `xml:"path,omitempty"` +} + +func init() { + t["LocalDatastoreInfo"] = reflect.TypeOf((*LocalDatastoreInfo)(nil)).Elem() +} + +type LocalLicenseSource struct { + LicenseSource + + LicenseKeys string `xml:"licenseKeys"` +} + +func init() { + t["LocalLicenseSource"] = reflect.TypeOf((*LocalLicenseSource)(nil)).Elem() +} + +type LocalTSMEnabledEvent struct { + HostEvent +} + +func init() { + t["LocalTSMEnabledEvent"] = reflect.TypeOf((*LocalTSMEnabledEvent)(nil)).Elem() +} + +type LocalizableMessage struct { + DynamicData + + Key string `xml:"key"` + Arg []KeyAnyValue `xml:"arg,omitempty"` + Message string `xml:"message,omitempty"` +} + +func init() { + t["LocalizableMessage"] = reflect.TypeOf((*LocalizableMessage)(nil)).Elem() +} + +type LocalizationManagerMessageCatalog struct { + DynamicData + + ModuleName string `xml:"moduleName"` + CatalogName string `xml:"catalogName"` + Locale string `xml:"locale"` + CatalogUri string `xml:"catalogUri"` + LastModified *time.Time `xml:"lastModified"` + Md5sum string `xml:"md5sum,omitempty"` + Version string `xml:"version,omitempty"` +} + +func init() { + t["LocalizationManagerMessageCatalog"] = reflect.TypeOf((*LocalizationManagerMessageCatalog)(nil)).Elem() +} + +type LocalizedMethodFault struct { + DynamicData + + Fault BaseMethodFault `xml:"fault,typeattr"` + LocalizedMessage string `xml:"localizedMessage,omitempty"` +} + +func init() { + t["LocalizedMethodFault"] = reflect.TypeOf((*LocalizedMethodFault)(nil)).Elem() +} + +type LockerMisconfiguredEvent struct { + Event + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["LockerMisconfiguredEvent"] = reflect.TypeOf((*LockerMisconfiguredEvent)(nil)).Elem() +} + +type LockerReconfiguredEvent struct { + Event + + OldDatastore *DatastoreEventArgument `xml:"oldDatastore,omitempty"` + NewDatastore *DatastoreEventArgument `xml:"newDatastore,omitempty"` +} + +func init() { + t["LockerReconfiguredEvent"] = reflect.TypeOf((*LockerReconfiguredEvent)(nil)).Elem() +} + +type LogBundlingFailed struct { + VimFault +} + +func init() { + t["LogBundlingFailed"] = reflect.TypeOf((*LogBundlingFailed)(nil)).Elem() +} + +type LogBundlingFailedFault LogBundlingFailed + +func init() { + t["LogBundlingFailedFault"] = reflect.TypeOf((*LogBundlingFailedFault)(nil)).Elem() +} + +type LogUserEvent LogUserEventRequestType + +func init() { + t["LogUserEvent"] = reflect.TypeOf((*LogUserEvent)(nil)).Elem() +} + +type LogUserEventRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Msg string `xml:"msg"` +} + +func init() { + t["LogUserEventRequestType"] = reflect.TypeOf((*LogUserEventRequestType)(nil)).Elem() +} + +type LogUserEventResponse struct { +} + +type Login LoginRequestType + +func init() { + t["Login"] = reflect.TypeOf((*Login)(nil)).Elem() +} + +type LoginBySSPI LoginBySSPIRequestType + +func init() { + t["LoginBySSPI"] = reflect.TypeOf((*LoginBySSPI)(nil)).Elem() +} + +type LoginBySSPIRequestType struct { + This ManagedObjectReference `xml:"_this"` + Base64Token string `xml:"base64Token"` + Locale string `xml:"locale,omitempty"` +} + +func init() { + t["LoginBySSPIRequestType"] = reflect.TypeOf((*LoginBySSPIRequestType)(nil)).Elem() +} + +type LoginBySSPIResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type LoginByToken LoginByTokenRequestType + +func init() { + t["LoginByToken"] = reflect.TypeOf((*LoginByToken)(nil)).Elem() +} + +type LoginByTokenRequestType struct { + This ManagedObjectReference `xml:"_this"` + Locale string `xml:"locale,omitempty"` +} + +func init() { + t["LoginByTokenRequestType"] = reflect.TypeOf((*LoginByTokenRequestType)(nil)).Elem() +} + +type LoginByTokenResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type LoginExtensionByCertificate LoginExtensionByCertificateRequestType + +func init() { + t["LoginExtensionByCertificate"] = reflect.TypeOf((*LoginExtensionByCertificate)(nil)).Elem() +} + +type LoginExtensionByCertificateRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` + Locale string `xml:"locale,omitempty"` +} + +func init() { + t["LoginExtensionByCertificateRequestType"] = reflect.TypeOf((*LoginExtensionByCertificateRequestType)(nil)).Elem() +} + +type LoginExtensionByCertificateResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type LoginExtensionBySubjectName LoginExtensionBySubjectNameRequestType + +func init() { + t["LoginExtensionBySubjectName"] = reflect.TypeOf((*LoginExtensionBySubjectName)(nil)).Elem() +} + +type LoginExtensionBySubjectNameRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` + Locale string `xml:"locale,omitempty"` +} + +func init() { + t["LoginExtensionBySubjectNameRequestType"] = reflect.TypeOf((*LoginExtensionBySubjectNameRequestType)(nil)).Elem() +} + +type LoginExtensionBySubjectNameResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type LoginRequestType struct { + This ManagedObjectReference `xml:"_this"` + UserName string `xml:"userName"` + Password string `xml:"password"` + Locale string `xml:"locale,omitempty"` +} + +func init() { + t["LoginRequestType"] = reflect.TypeOf((*LoginRequestType)(nil)).Elem() +} + +type LoginResponse struct { + Returnval UserSession `xml:"returnval"` +} + +type Logout LogoutRequestType + +func init() { + t["Logout"] = reflect.TypeOf((*Logout)(nil)).Elem() +} + +type LogoutRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["LogoutRequestType"] = reflect.TypeOf((*LogoutRequestType)(nil)).Elem() +} + +type LogoutResponse struct { +} + +type LongOption struct { + OptionType + + Min int64 `xml:"min"` + Max int64 `xml:"max"` + DefaultValue int64 `xml:"defaultValue"` +} + +func init() { + t["LongOption"] = reflect.TypeOf((*LongOption)(nil)).Elem() +} + +type LongPolicy struct { + InheritablePolicy + + Value int64 `xml:"value,omitempty"` +} + +func init() { + t["LongPolicy"] = reflect.TypeOf((*LongPolicy)(nil)).Elem() +} + +type LookupDvPortGroup LookupDvPortGroupRequestType + +func init() { + t["LookupDvPortGroup"] = reflect.TypeOf((*LookupDvPortGroup)(nil)).Elem() +} + +type LookupDvPortGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + PortgroupKey string `xml:"portgroupKey"` +} + +func init() { + t["LookupDvPortGroupRequestType"] = reflect.TypeOf((*LookupDvPortGroupRequestType)(nil)).Elem() +} + +type LookupDvPortGroupResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type LookupVmOverheadMemory LookupVmOverheadMemoryRequestType + +func init() { + t["LookupVmOverheadMemory"] = reflect.TypeOf((*LookupVmOverheadMemory)(nil)).Elem() +} + +type LookupVmOverheadMemoryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["LookupVmOverheadMemoryRequestType"] = reflect.TypeOf((*LookupVmOverheadMemoryRequestType)(nil)).Elem() +} + +type LookupVmOverheadMemoryResponse struct { + Returnval int64 `xml:"returnval"` +} + +type MacAddress struct { + NegatableExpression +} + +func init() { + t["MacAddress"] = reflect.TypeOf((*MacAddress)(nil)).Elem() +} + +type MacRange struct { + MacAddress + + Address string `xml:"address"` + Mask string `xml:"mask"` +} + +func init() { + t["MacRange"] = reflect.TypeOf((*MacRange)(nil)).Elem() +} + +type MaintenanceModeFileMove struct { + MigrationFault +} + +func init() { + t["MaintenanceModeFileMove"] = reflect.TypeOf((*MaintenanceModeFileMove)(nil)).Elem() +} + +type MaintenanceModeFileMoveFault MaintenanceModeFileMove + +func init() { + t["MaintenanceModeFileMoveFault"] = reflect.TypeOf((*MaintenanceModeFileMoveFault)(nil)).Elem() +} + +type MakeDirectory MakeDirectoryRequestType + +func init() { + t["MakeDirectory"] = reflect.TypeOf((*MakeDirectory)(nil)).Elem() +} + +type MakeDirectoryInGuest MakeDirectoryInGuestRequestType + +func init() { + t["MakeDirectoryInGuest"] = reflect.TypeOf((*MakeDirectoryInGuest)(nil)).Elem() +} + +type MakeDirectoryInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + DirectoryPath string `xml:"directoryPath"` + CreateParentDirectories bool `xml:"createParentDirectories"` +} + +func init() { + t["MakeDirectoryInGuestRequestType"] = reflect.TypeOf((*MakeDirectoryInGuestRequestType)(nil)).Elem() +} + +type MakeDirectoryInGuestResponse struct { +} + +type MakeDirectoryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + CreateParentDirectories *bool `xml:"createParentDirectories"` +} + +func init() { + t["MakeDirectoryRequestType"] = reflect.TypeOf((*MakeDirectoryRequestType)(nil)).Elem() +} + +type MakeDirectoryResponse struct { +} + +type MakePrimaryVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` +} + +func init() { + t["MakePrimaryVMRequestType"] = reflect.TypeOf((*MakePrimaryVMRequestType)(nil)).Elem() +} + +type MakePrimaryVM_Task MakePrimaryVMRequestType + +func init() { + t["MakePrimaryVM_Task"] = reflect.TypeOf((*MakePrimaryVM_Task)(nil)).Elem() +} + +type MakePrimaryVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ManagedByInfo struct { + DynamicData + + ExtensionKey string `xml:"extensionKey"` + Type string `xml:"type"` +} + +func init() { + t["ManagedByInfo"] = reflect.TypeOf((*ManagedByInfo)(nil)).Elem() +} + +type ManagedEntityEventArgument struct { + EntityEventArgument + + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["ManagedEntityEventArgument"] = reflect.TypeOf((*ManagedEntityEventArgument)(nil)).Elem() +} + +type ManagedObjectNotFound struct { + RuntimeFault + + Obj ManagedObjectReference `xml:"obj"` +} + +func init() { + t["ManagedObjectNotFound"] = reflect.TypeOf((*ManagedObjectNotFound)(nil)).Elem() +} + +type ManagedObjectNotFoundFault ManagedObjectNotFound + +func init() { + t["ManagedObjectNotFoundFault"] = reflect.TypeOf((*ManagedObjectNotFoundFault)(nil)).Elem() +} + +type ManagedObjectReference struct { + Type string `xml:"type,attr"` + Value string `xml:",chardata"` +} + +func init() { + t["ManagedObjectReference"] = reflect.TypeOf((*ManagedObjectReference)(nil)).Elem() +} + +type MarkAsLocalRequestType struct { + This ManagedObjectReference `xml:"_this"` + ScsiDiskUuid string `xml:"scsiDiskUuid"` +} + +func init() { + t["MarkAsLocalRequestType"] = reflect.TypeOf((*MarkAsLocalRequestType)(nil)).Elem() +} + +type MarkAsLocal_Task MarkAsLocalRequestType + +func init() { + t["MarkAsLocal_Task"] = reflect.TypeOf((*MarkAsLocal_Task)(nil)).Elem() +} + +type MarkAsLocal_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MarkAsNonLocalRequestType struct { + This ManagedObjectReference `xml:"_this"` + ScsiDiskUuid string `xml:"scsiDiskUuid"` +} + +func init() { + t["MarkAsNonLocalRequestType"] = reflect.TypeOf((*MarkAsNonLocalRequestType)(nil)).Elem() +} + +type MarkAsNonLocal_Task MarkAsNonLocalRequestType + +func init() { + t["MarkAsNonLocal_Task"] = reflect.TypeOf((*MarkAsNonLocal_Task)(nil)).Elem() +} + +type MarkAsNonLocal_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MarkAsNonSsdRequestType struct { + This ManagedObjectReference `xml:"_this"` + ScsiDiskUuid string `xml:"scsiDiskUuid"` +} + +func init() { + t["MarkAsNonSsdRequestType"] = reflect.TypeOf((*MarkAsNonSsdRequestType)(nil)).Elem() +} + +type MarkAsNonSsd_Task MarkAsNonSsdRequestType + +func init() { + t["MarkAsNonSsd_Task"] = reflect.TypeOf((*MarkAsNonSsd_Task)(nil)).Elem() +} + +type MarkAsNonSsd_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MarkAsSsdRequestType struct { + This ManagedObjectReference `xml:"_this"` + ScsiDiskUuid string `xml:"scsiDiskUuid"` +} + +func init() { + t["MarkAsSsdRequestType"] = reflect.TypeOf((*MarkAsSsdRequestType)(nil)).Elem() +} + +type MarkAsSsd_Task MarkAsSsdRequestType + +func init() { + t["MarkAsSsd_Task"] = reflect.TypeOf((*MarkAsSsd_Task)(nil)).Elem() +} + +type MarkAsSsd_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MarkAsTemplate MarkAsTemplateRequestType + +func init() { + t["MarkAsTemplate"] = reflect.TypeOf((*MarkAsTemplate)(nil)).Elem() +} + +type MarkAsTemplateRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["MarkAsTemplateRequestType"] = reflect.TypeOf((*MarkAsTemplateRequestType)(nil)).Elem() +} + +type MarkAsTemplateResponse struct { +} + +type MarkAsVirtualMachine MarkAsVirtualMachineRequestType + +func init() { + t["MarkAsVirtualMachine"] = reflect.TypeOf((*MarkAsVirtualMachine)(nil)).Elem() +} + +type MarkAsVirtualMachineRequestType struct { + This ManagedObjectReference `xml:"_this"` + Pool ManagedObjectReference `xml:"pool"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["MarkAsVirtualMachineRequestType"] = reflect.TypeOf((*MarkAsVirtualMachineRequestType)(nil)).Elem() +} + +type MarkAsVirtualMachineResponse struct { +} + +type MarkForRemoval MarkForRemovalRequestType + +func init() { + t["MarkForRemoval"] = reflect.TypeOf((*MarkForRemoval)(nil)).Elem() +} + +type MarkForRemovalRequestType struct { + This ManagedObjectReference `xml:"_this"` + HbaName string `xml:"hbaName"` + Remove bool `xml:"remove"` +} + +func init() { + t["MarkForRemovalRequestType"] = reflect.TypeOf((*MarkForRemovalRequestType)(nil)).Elem() +} + +type MarkForRemovalResponse struct { +} + +type MemoryFileFormatNotSupportedByDatastore struct { + UnsupportedDatastore + + DatastoreName string `xml:"datastoreName"` + Type string `xml:"type"` +} + +func init() { + t["MemoryFileFormatNotSupportedByDatastore"] = reflect.TypeOf((*MemoryFileFormatNotSupportedByDatastore)(nil)).Elem() +} + +type MemoryFileFormatNotSupportedByDatastoreFault MemoryFileFormatNotSupportedByDatastore + +func init() { + t["MemoryFileFormatNotSupportedByDatastoreFault"] = reflect.TypeOf((*MemoryFileFormatNotSupportedByDatastoreFault)(nil)).Elem() +} + +type MemoryHotPlugNotSupported struct { + VmConfigFault +} + +func init() { + t["MemoryHotPlugNotSupported"] = reflect.TypeOf((*MemoryHotPlugNotSupported)(nil)).Elem() +} + +type MemoryHotPlugNotSupportedFault MemoryHotPlugNotSupported + +func init() { + t["MemoryHotPlugNotSupportedFault"] = reflect.TypeOf((*MemoryHotPlugNotSupportedFault)(nil)).Elem() +} + +type MemorySizeNotRecommended struct { + VirtualHardwareCompatibilityIssue + + MemorySizeMB int32 `xml:"memorySizeMB"` + MinMemorySizeMB int32 `xml:"minMemorySizeMB"` + MaxMemorySizeMB int32 `xml:"maxMemorySizeMB"` +} + +func init() { + t["MemorySizeNotRecommended"] = reflect.TypeOf((*MemorySizeNotRecommended)(nil)).Elem() +} + +type MemorySizeNotRecommendedFault MemorySizeNotRecommended + +func init() { + t["MemorySizeNotRecommendedFault"] = reflect.TypeOf((*MemorySizeNotRecommendedFault)(nil)).Elem() +} + +type MemorySizeNotSupported struct { + VirtualHardwareCompatibilityIssue + + MemorySizeMB int32 `xml:"memorySizeMB"` + MinMemorySizeMB int32 `xml:"minMemorySizeMB"` + MaxMemorySizeMB int32 `xml:"maxMemorySizeMB"` +} + +func init() { + t["MemorySizeNotSupported"] = reflect.TypeOf((*MemorySizeNotSupported)(nil)).Elem() +} + +type MemorySizeNotSupportedByDatastore struct { + VirtualHardwareCompatibilityIssue + + Datastore ManagedObjectReference `xml:"datastore"` + MemorySizeMB int32 `xml:"memorySizeMB"` + MaxMemorySizeMB int32 `xml:"maxMemorySizeMB"` +} + +func init() { + t["MemorySizeNotSupportedByDatastore"] = reflect.TypeOf((*MemorySizeNotSupportedByDatastore)(nil)).Elem() +} + +type MemorySizeNotSupportedByDatastoreFault MemorySizeNotSupportedByDatastore + +func init() { + t["MemorySizeNotSupportedByDatastoreFault"] = reflect.TypeOf((*MemorySizeNotSupportedByDatastoreFault)(nil)).Elem() +} + +type MemorySizeNotSupportedFault MemorySizeNotSupported + +func init() { + t["MemorySizeNotSupportedFault"] = reflect.TypeOf((*MemorySizeNotSupportedFault)(nil)).Elem() +} + +type MemorySnapshotOnIndependentDisk struct { + SnapshotFault +} + +func init() { + t["MemorySnapshotOnIndependentDisk"] = reflect.TypeOf((*MemorySnapshotOnIndependentDisk)(nil)).Elem() +} + +type MemorySnapshotOnIndependentDiskFault MemorySnapshotOnIndependentDisk + +func init() { + t["MemorySnapshotOnIndependentDiskFault"] = reflect.TypeOf((*MemorySnapshotOnIndependentDiskFault)(nil)).Elem() +} + +type MergeDvsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dvs ManagedObjectReference `xml:"dvs"` +} + +func init() { + t["MergeDvsRequestType"] = reflect.TypeOf((*MergeDvsRequestType)(nil)).Elem() +} + +type MergeDvs_Task MergeDvsRequestType + +func init() { + t["MergeDvs_Task"] = reflect.TypeOf((*MergeDvs_Task)(nil)).Elem() +} + +type MergeDvs_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MergePermissions MergePermissionsRequestType + +func init() { + t["MergePermissions"] = reflect.TypeOf((*MergePermissions)(nil)).Elem() +} + +type MergePermissionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + SrcRoleId int32 `xml:"srcRoleId"` + DstRoleId int32 `xml:"dstRoleId"` +} + +func init() { + t["MergePermissionsRequestType"] = reflect.TypeOf((*MergePermissionsRequestType)(nil)).Elem() +} + +type MergePermissionsResponse struct { +} + +type MethodAction struct { + Action + + Name string `xml:"name"` + Argument []MethodActionArgument `xml:"argument,omitempty"` +} + +func init() { + t["MethodAction"] = reflect.TypeOf((*MethodAction)(nil)).Elem() +} + +type MethodActionArgument struct { + DynamicData + + Value AnyType `xml:"value,omitempty,typeattr"` +} + +func init() { + t["MethodActionArgument"] = reflect.TypeOf((*MethodActionArgument)(nil)).Elem() +} + +type MethodAlreadyDisabledFault struct { + RuntimeFault + + SourceId string `xml:"sourceId"` +} + +func init() { + t["MethodAlreadyDisabledFault"] = reflect.TypeOf((*MethodAlreadyDisabledFault)(nil)).Elem() +} + +type MethodAlreadyDisabledFaultFault MethodAlreadyDisabledFault + +func init() { + t["MethodAlreadyDisabledFaultFault"] = reflect.TypeOf((*MethodAlreadyDisabledFaultFault)(nil)).Elem() +} + +type MethodDescription struct { + Description + + Key string `xml:"key"` +} + +func init() { + t["MethodDescription"] = reflect.TypeOf((*MethodDescription)(nil)).Elem() +} + +type MethodDisabled struct { + RuntimeFault + + Source string `xml:"source,omitempty"` +} + +func init() { + t["MethodDisabled"] = reflect.TypeOf((*MethodDisabled)(nil)).Elem() +} + +type MethodDisabledFault MethodDisabled + +func init() { + t["MethodDisabledFault"] = reflect.TypeOf((*MethodDisabledFault)(nil)).Elem() +} + +type MethodFault struct { + FaultCause *LocalizedMethodFault `xml:"faultCause,omitempty"` + FaultMessage []LocalizableMessage `xml:"faultMessage,omitempty"` +} + +func init() { + t["MethodFault"] = reflect.TypeOf((*MethodFault)(nil)).Elem() +} + +type MethodFaultFault BaseMethodFault + +func init() { + t["MethodFaultFault"] = reflect.TypeOf((*MethodFaultFault)(nil)).Elem() +} + +type MethodNotFound struct { + InvalidRequest + + Receiver ManagedObjectReference `xml:"receiver"` + Method string `xml:"method"` +} + +func init() { + t["MethodNotFound"] = reflect.TypeOf((*MethodNotFound)(nil)).Elem() +} + +type MethodNotFoundFault MethodNotFound + +func init() { + t["MethodNotFoundFault"] = reflect.TypeOf((*MethodNotFoundFault)(nil)).Elem() +} + +type MetricAlarmExpression struct { + AlarmExpression + + Operator MetricAlarmOperator `xml:"operator"` + Type string `xml:"type"` + Metric PerfMetricId `xml:"metric"` + Yellow int32 `xml:"yellow,omitempty"` + YellowInterval int32 `xml:"yellowInterval,omitempty"` + Red int32 `xml:"red,omitempty"` + RedInterval int32 `xml:"redInterval,omitempty"` +} + +func init() { + t["MetricAlarmExpression"] = reflect.TypeOf((*MetricAlarmExpression)(nil)).Elem() +} + +type MigrateVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Priority VirtualMachineMovePriority `xml:"priority"` + State VirtualMachinePowerState `xml:"state,omitempty"` +} + +func init() { + t["MigrateVMRequestType"] = reflect.TypeOf((*MigrateVMRequestType)(nil)).Elem() +} + +type MigrateVM_Task MigrateVMRequestType + +func init() { + t["MigrateVM_Task"] = reflect.TypeOf((*MigrateVM_Task)(nil)).Elem() +} + +type MigrateVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MigrationDisabled struct { + MigrationFault +} + +func init() { + t["MigrationDisabled"] = reflect.TypeOf((*MigrationDisabled)(nil)).Elem() +} + +type MigrationDisabledFault MigrationDisabled + +func init() { + t["MigrationDisabledFault"] = reflect.TypeOf((*MigrationDisabledFault)(nil)).Elem() +} + +type MigrationErrorEvent struct { + MigrationEvent +} + +func init() { + t["MigrationErrorEvent"] = reflect.TypeOf((*MigrationErrorEvent)(nil)).Elem() +} + +type MigrationEvent struct { + VmEvent + + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["MigrationEvent"] = reflect.TypeOf((*MigrationEvent)(nil)).Elem() +} + +type MigrationFault struct { + VimFault +} + +func init() { + t["MigrationFault"] = reflect.TypeOf((*MigrationFault)(nil)).Elem() +} + +type MigrationFaultFault BaseMigrationFault + +func init() { + t["MigrationFaultFault"] = reflect.TypeOf((*MigrationFaultFault)(nil)).Elem() +} + +type MigrationFeatureNotSupported struct { + MigrationFault + + AtSourceHost bool `xml:"atSourceHost"` + FailedHostName string `xml:"failedHostName"` + FailedHost ManagedObjectReference `xml:"failedHost"` +} + +func init() { + t["MigrationFeatureNotSupported"] = reflect.TypeOf((*MigrationFeatureNotSupported)(nil)).Elem() +} + +type MigrationFeatureNotSupportedFault BaseMigrationFeatureNotSupported + +func init() { + t["MigrationFeatureNotSupportedFault"] = reflect.TypeOf((*MigrationFeatureNotSupportedFault)(nil)).Elem() +} + +type MigrationHostErrorEvent struct { + MigrationEvent + + DstHost HostEventArgument `xml:"dstHost"` +} + +func init() { + t["MigrationHostErrorEvent"] = reflect.TypeOf((*MigrationHostErrorEvent)(nil)).Elem() +} + +type MigrationHostWarningEvent struct { + MigrationEvent + + DstHost HostEventArgument `xml:"dstHost"` +} + +func init() { + t["MigrationHostWarningEvent"] = reflect.TypeOf((*MigrationHostWarningEvent)(nil)).Elem() +} + +type MigrationNotReady struct { + MigrationFault + + Reason string `xml:"reason"` +} + +func init() { + t["MigrationNotReady"] = reflect.TypeOf((*MigrationNotReady)(nil)).Elem() +} + +type MigrationNotReadyFault MigrationNotReady + +func init() { + t["MigrationNotReadyFault"] = reflect.TypeOf((*MigrationNotReadyFault)(nil)).Elem() +} + +type MigrationResourceErrorEvent struct { + MigrationEvent + + DstPool ResourcePoolEventArgument `xml:"dstPool"` + DstHost HostEventArgument `xml:"dstHost"` +} + +func init() { + t["MigrationResourceErrorEvent"] = reflect.TypeOf((*MigrationResourceErrorEvent)(nil)).Elem() +} + +type MigrationResourceWarningEvent struct { + MigrationEvent + + DstPool ResourcePoolEventArgument `xml:"dstPool"` + DstHost HostEventArgument `xml:"dstHost"` +} + +func init() { + t["MigrationResourceWarningEvent"] = reflect.TypeOf((*MigrationResourceWarningEvent)(nil)).Elem() +} + +type MigrationWarningEvent struct { + MigrationEvent +} + +func init() { + t["MigrationWarningEvent"] = reflect.TypeOf((*MigrationWarningEvent)(nil)).Elem() +} + +type MismatchedBundle struct { + VimFault + + BundleUuid string `xml:"bundleUuid"` + HostUuid string `xml:"hostUuid"` + BundleBuildNumber int32 `xml:"bundleBuildNumber"` + HostBuildNumber int32 `xml:"hostBuildNumber"` +} + +func init() { + t["MismatchedBundle"] = reflect.TypeOf((*MismatchedBundle)(nil)).Elem() +} + +type MismatchedBundleFault MismatchedBundle + +func init() { + t["MismatchedBundleFault"] = reflect.TypeOf((*MismatchedBundleFault)(nil)).Elem() +} + +type MismatchedNetworkPolicies struct { + MigrationFault + + Device string `xml:"device"` + Backing string `xml:"backing"` + Connected bool `xml:"connected"` +} + +func init() { + t["MismatchedNetworkPolicies"] = reflect.TypeOf((*MismatchedNetworkPolicies)(nil)).Elem() +} + +type MismatchedNetworkPoliciesFault MismatchedNetworkPolicies + +func init() { + t["MismatchedNetworkPoliciesFault"] = reflect.TypeOf((*MismatchedNetworkPoliciesFault)(nil)).Elem() +} + +type MismatchedVMotionNetworkNames struct { + MigrationFault + + SourceNetwork string `xml:"sourceNetwork"` + DestNetwork string `xml:"destNetwork"` +} + +func init() { + t["MismatchedVMotionNetworkNames"] = reflect.TypeOf((*MismatchedVMotionNetworkNames)(nil)).Elem() +} + +type MismatchedVMotionNetworkNamesFault MismatchedVMotionNetworkNames + +func init() { + t["MismatchedVMotionNetworkNamesFault"] = reflect.TypeOf((*MismatchedVMotionNetworkNamesFault)(nil)).Elem() +} + +type MissingBmcSupport struct { + VimFault +} + +func init() { + t["MissingBmcSupport"] = reflect.TypeOf((*MissingBmcSupport)(nil)).Elem() +} + +type MissingBmcSupportFault MissingBmcSupport + +func init() { + t["MissingBmcSupportFault"] = reflect.TypeOf((*MissingBmcSupportFault)(nil)).Elem() +} + +type MissingController struct { + InvalidDeviceSpec +} + +func init() { + t["MissingController"] = reflect.TypeOf((*MissingController)(nil)).Elem() +} + +type MissingControllerFault MissingController + +func init() { + t["MissingControllerFault"] = reflect.TypeOf((*MissingControllerFault)(nil)).Elem() +} + +type MissingIpPool struct { + VAppPropertyFault +} + +func init() { + t["MissingIpPool"] = reflect.TypeOf((*MissingIpPool)(nil)).Elem() +} + +type MissingIpPoolFault MissingIpPool + +func init() { + t["MissingIpPoolFault"] = reflect.TypeOf((*MissingIpPoolFault)(nil)).Elem() +} + +type MissingLinuxCustResources struct { + CustomizationFault +} + +func init() { + t["MissingLinuxCustResources"] = reflect.TypeOf((*MissingLinuxCustResources)(nil)).Elem() +} + +type MissingLinuxCustResourcesFault MissingLinuxCustResources + +func init() { + t["MissingLinuxCustResourcesFault"] = reflect.TypeOf((*MissingLinuxCustResourcesFault)(nil)).Elem() +} + +type MissingNetworkIpConfig struct { + VAppPropertyFault +} + +func init() { + t["MissingNetworkIpConfig"] = reflect.TypeOf((*MissingNetworkIpConfig)(nil)).Elem() +} + +type MissingNetworkIpConfigFault MissingNetworkIpConfig + +func init() { + t["MissingNetworkIpConfigFault"] = reflect.TypeOf((*MissingNetworkIpConfigFault)(nil)).Elem() +} + +type MissingObject struct { + DynamicData + + Obj ManagedObjectReference `xml:"obj"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["MissingObject"] = reflect.TypeOf((*MissingObject)(nil)).Elem() +} + +type MissingPowerOffConfiguration struct { + VAppConfigFault +} + +func init() { + t["MissingPowerOffConfiguration"] = reflect.TypeOf((*MissingPowerOffConfiguration)(nil)).Elem() +} + +type MissingPowerOffConfigurationFault MissingPowerOffConfiguration + +func init() { + t["MissingPowerOffConfigurationFault"] = reflect.TypeOf((*MissingPowerOffConfigurationFault)(nil)).Elem() +} + +type MissingPowerOnConfiguration struct { + VAppConfigFault +} + +func init() { + t["MissingPowerOnConfiguration"] = reflect.TypeOf((*MissingPowerOnConfiguration)(nil)).Elem() +} + +type MissingPowerOnConfigurationFault MissingPowerOnConfiguration + +func init() { + t["MissingPowerOnConfigurationFault"] = reflect.TypeOf((*MissingPowerOnConfigurationFault)(nil)).Elem() +} + +type MissingProperty struct { + DynamicData + + Path string `xml:"path"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["MissingProperty"] = reflect.TypeOf((*MissingProperty)(nil)).Elem() +} + +type MissingWindowsCustResources struct { + CustomizationFault +} + +func init() { + t["MissingWindowsCustResources"] = reflect.TypeOf((*MissingWindowsCustResources)(nil)).Elem() +} + +type MissingWindowsCustResourcesFault MissingWindowsCustResources + +func init() { + t["MissingWindowsCustResourcesFault"] = reflect.TypeOf((*MissingWindowsCustResourcesFault)(nil)).Elem() +} + +type MksConnectionLimitReached struct { + InvalidState + + ConnectionLimit int32 `xml:"connectionLimit"` +} + +func init() { + t["MksConnectionLimitReached"] = reflect.TypeOf((*MksConnectionLimitReached)(nil)).Elem() +} + +type MksConnectionLimitReachedFault MksConnectionLimitReached + +func init() { + t["MksConnectionLimitReachedFault"] = reflect.TypeOf((*MksConnectionLimitReachedFault)(nil)).Elem() +} + +type ModeInfo struct { + DynamicData + + Browse string `xml:"browse,omitempty"` + Read string `xml:"read"` + Modify string `xml:"modify"` + Use string `xml:"use"` + Admin string `xml:"admin,omitempty"` + Full string `xml:"full"` +} + +func init() { + t["ModeInfo"] = reflect.TypeOf((*ModeInfo)(nil)).Elem() +} + +type ModifyListView ModifyListViewRequestType + +func init() { + t["ModifyListView"] = reflect.TypeOf((*ModifyListView)(nil)).Elem() +} + +type ModifyListViewRequestType struct { + This ManagedObjectReference `xml:"_this"` + Add []ManagedObjectReference `xml:"add,omitempty"` + Remove []ManagedObjectReference `xml:"remove,omitempty"` +} + +func init() { + t["ModifyListViewRequestType"] = reflect.TypeOf((*ModifyListViewRequestType)(nil)).Elem() +} + +type ModifyListViewResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type MonthlyByDayTaskScheduler struct { + MonthlyTaskScheduler + + Day int32 `xml:"day"` +} + +func init() { + t["MonthlyByDayTaskScheduler"] = reflect.TypeOf((*MonthlyByDayTaskScheduler)(nil)).Elem() +} + +type MonthlyByWeekdayTaskScheduler struct { + MonthlyTaskScheduler + + Offset WeekOfMonth `xml:"offset"` + Weekday DayOfWeek `xml:"weekday"` +} + +func init() { + t["MonthlyByWeekdayTaskScheduler"] = reflect.TypeOf((*MonthlyByWeekdayTaskScheduler)(nil)).Elem() +} + +type MonthlyTaskScheduler struct { + DailyTaskScheduler +} + +func init() { + t["MonthlyTaskScheduler"] = reflect.TypeOf((*MonthlyTaskScheduler)(nil)).Elem() +} + +type MountError struct { + CustomizationFault + + Vm ManagedObjectReference `xml:"vm"` + DiskIndex int32 `xml:"diskIndex"` +} + +func init() { + t["MountError"] = reflect.TypeOf((*MountError)(nil)).Elem() +} + +type MountErrorFault MountError + +func init() { + t["MountErrorFault"] = reflect.TypeOf((*MountErrorFault)(nil)).Elem() +} + +type MountToolsInstaller MountToolsInstallerRequestType + +func init() { + t["MountToolsInstaller"] = reflect.TypeOf((*MountToolsInstaller)(nil)).Elem() +} + +type MountToolsInstallerRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["MountToolsInstallerRequestType"] = reflect.TypeOf((*MountToolsInstallerRequestType)(nil)).Elem() +} + +type MountToolsInstallerResponse struct { +} + +type MountVffsVolume MountVffsVolumeRequestType + +func init() { + t["MountVffsVolume"] = reflect.TypeOf((*MountVffsVolume)(nil)).Elem() +} + +type MountVffsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` + VffsUuid string `xml:"vffsUuid"` +} + +func init() { + t["MountVffsVolumeRequestType"] = reflect.TypeOf((*MountVffsVolumeRequestType)(nil)).Elem() +} + +type MountVffsVolumeResponse struct { +} + +type MountVmfsVolume MountVmfsVolumeRequestType + +func init() { + t["MountVmfsVolume"] = reflect.TypeOf((*MountVmfsVolume)(nil)).Elem() +} + +type MountVmfsVolumeExRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid []string `xml:"vmfsUuid"` +} + +func init() { + t["MountVmfsVolumeExRequestType"] = reflect.TypeOf((*MountVmfsVolumeExRequestType)(nil)).Elem() +} + +type MountVmfsVolumeEx_Task MountVmfsVolumeExRequestType + +func init() { + t["MountVmfsVolumeEx_Task"] = reflect.TypeOf((*MountVmfsVolumeEx_Task)(nil)).Elem() +} + +type MountVmfsVolumeEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MountVmfsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid string `xml:"vmfsUuid"` +} + +func init() { + t["MountVmfsVolumeRequestType"] = reflect.TypeOf((*MountVmfsVolumeRequestType)(nil)).Elem() +} + +type MountVmfsVolumeResponse struct { +} + +type MoveDVPortRequestType struct { + This ManagedObjectReference `xml:"_this"` + PortKey []string `xml:"portKey"` + DestinationPortgroupKey string `xml:"destinationPortgroupKey,omitempty"` +} + +func init() { + t["MoveDVPortRequestType"] = reflect.TypeOf((*MoveDVPortRequestType)(nil)).Elem() +} + +type MoveDVPort_Task MoveDVPortRequestType + +func init() { + t["MoveDVPort_Task"] = reflect.TypeOf((*MoveDVPort_Task)(nil)).Elem() +} + +type MoveDVPort_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MoveDatastoreFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + SourceName string `xml:"sourceName"` + SourceDatacenter *ManagedObjectReference `xml:"sourceDatacenter,omitempty"` + DestinationName string `xml:"destinationName"` + DestinationDatacenter *ManagedObjectReference `xml:"destinationDatacenter,omitempty"` + Force *bool `xml:"force"` +} + +func init() { + t["MoveDatastoreFileRequestType"] = reflect.TypeOf((*MoveDatastoreFileRequestType)(nil)).Elem() +} + +type MoveDatastoreFile_Task MoveDatastoreFileRequestType + +func init() { + t["MoveDatastoreFile_Task"] = reflect.TypeOf((*MoveDatastoreFile_Task)(nil)).Elem() +} + +type MoveDatastoreFile_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MoveDirectoryInGuest MoveDirectoryInGuestRequestType + +func init() { + t["MoveDirectoryInGuest"] = reflect.TypeOf((*MoveDirectoryInGuest)(nil)).Elem() +} + +type MoveDirectoryInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + SrcDirectoryPath string `xml:"srcDirectoryPath"` + DstDirectoryPath string `xml:"dstDirectoryPath"` +} + +func init() { + t["MoveDirectoryInGuestRequestType"] = reflect.TypeOf((*MoveDirectoryInGuestRequestType)(nil)).Elem() +} + +type MoveDirectoryInGuestResponse struct { +} + +type MoveFileInGuest MoveFileInGuestRequestType + +func init() { + t["MoveFileInGuest"] = reflect.TypeOf((*MoveFileInGuest)(nil)).Elem() +} + +type MoveFileInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + SrcFilePath string `xml:"srcFilePath"` + DstFilePath string `xml:"dstFilePath"` + Overwrite bool `xml:"overwrite"` +} + +func init() { + t["MoveFileInGuestRequestType"] = reflect.TypeOf((*MoveFileInGuestRequestType)(nil)).Elem() +} + +type MoveFileInGuestResponse struct { +} + +type MoveHostIntoRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` + ResourcePool *ManagedObjectReference `xml:"resourcePool,omitempty"` +} + +func init() { + t["MoveHostIntoRequestType"] = reflect.TypeOf((*MoveHostIntoRequestType)(nil)).Elem() +} + +type MoveHostInto_Task MoveHostIntoRequestType + +func init() { + t["MoveHostInto_Task"] = reflect.TypeOf((*MoveHostInto_Task)(nil)).Elem() +} + +type MoveHostInto_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MoveIntoFolderRequestType struct { + This ManagedObjectReference `xml:"_this"` + List []ManagedObjectReference `xml:"list"` +} + +func init() { + t["MoveIntoFolderRequestType"] = reflect.TypeOf((*MoveIntoFolderRequestType)(nil)).Elem() +} + +type MoveIntoFolder_Task MoveIntoFolderRequestType + +func init() { + t["MoveIntoFolder_Task"] = reflect.TypeOf((*MoveIntoFolder_Task)(nil)).Elem() +} + +type MoveIntoFolder_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MoveIntoRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["MoveIntoRequestType"] = reflect.TypeOf((*MoveIntoRequestType)(nil)).Elem() +} + +type MoveIntoResourcePool MoveIntoResourcePoolRequestType + +func init() { + t["MoveIntoResourcePool"] = reflect.TypeOf((*MoveIntoResourcePool)(nil)).Elem() +} + +type MoveIntoResourcePoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + List []ManagedObjectReference `xml:"list"` +} + +func init() { + t["MoveIntoResourcePoolRequestType"] = reflect.TypeOf((*MoveIntoResourcePoolRequestType)(nil)).Elem() +} + +type MoveIntoResourcePoolResponse struct { +} + +type MoveInto_Task MoveIntoRequestType + +func init() { + t["MoveInto_Task"] = reflect.TypeOf((*MoveInto_Task)(nil)).Elem() +} + +type MoveInto_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MoveVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + SourceName string `xml:"sourceName"` + SourceDatacenter *ManagedObjectReference `xml:"sourceDatacenter,omitempty"` + DestName string `xml:"destName"` + DestDatacenter *ManagedObjectReference `xml:"destDatacenter,omitempty"` + Force *bool `xml:"force"` + Profile []BaseVirtualMachineProfileSpec `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["MoveVirtualDiskRequestType"] = reflect.TypeOf((*MoveVirtualDiskRequestType)(nil)).Elem() +} + +type MoveVirtualDisk_Task MoveVirtualDiskRequestType + +func init() { + t["MoveVirtualDisk_Task"] = reflect.TypeOf((*MoveVirtualDisk_Task)(nil)).Elem() +} + +type MoveVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type MtuMatchEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["MtuMatchEvent"] = reflect.TypeOf((*MtuMatchEvent)(nil)).Elem() +} + +type MtuMismatchEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["MtuMismatchEvent"] = reflect.TypeOf((*MtuMismatchEvent)(nil)).Elem() +} + +type MultiWriterNotSupported struct { + DeviceNotSupported +} + +func init() { + t["MultiWriterNotSupported"] = reflect.TypeOf((*MultiWriterNotSupported)(nil)).Elem() +} + +type MultiWriterNotSupportedFault MultiWriterNotSupported + +func init() { + t["MultiWriterNotSupportedFault"] = reflect.TypeOf((*MultiWriterNotSupportedFault)(nil)).Elem() +} + +type MultipleCertificatesVerifyFault struct { + HostConnectFault + + ThumbprintData []MultipleCertificatesVerifyFaultThumbprintData `xml:"thumbprintData"` +} + +func init() { + t["MultipleCertificatesVerifyFault"] = reflect.TypeOf((*MultipleCertificatesVerifyFault)(nil)).Elem() +} + +type MultipleCertificatesVerifyFaultFault MultipleCertificatesVerifyFault + +func init() { + t["MultipleCertificatesVerifyFaultFault"] = reflect.TypeOf((*MultipleCertificatesVerifyFaultFault)(nil)).Elem() +} + +type MultipleCertificatesVerifyFaultThumbprintData struct { + DynamicData + + Port int32 `xml:"port"` + Thumbprint string `xml:"thumbprint"` +} + +func init() { + t["MultipleCertificatesVerifyFaultThumbprintData"] = reflect.TypeOf((*MultipleCertificatesVerifyFaultThumbprintData)(nil)).Elem() +} + +type MultipleSnapshotsNotSupported struct { + SnapshotFault +} + +func init() { + t["MultipleSnapshotsNotSupported"] = reflect.TypeOf((*MultipleSnapshotsNotSupported)(nil)).Elem() +} + +type MultipleSnapshotsNotSupportedFault MultipleSnapshotsNotSupported + +func init() { + t["MultipleSnapshotsNotSupportedFault"] = reflect.TypeOf((*MultipleSnapshotsNotSupportedFault)(nil)).Elem() +} + +type NASDatastoreCreatedEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["NASDatastoreCreatedEvent"] = reflect.TypeOf((*NASDatastoreCreatedEvent)(nil)).Elem() +} + +type NamePasswordAuthentication struct { + GuestAuthentication + + Username string `xml:"username"` + Password string `xml:"password"` +} + +func init() { + t["NamePasswordAuthentication"] = reflect.TypeOf((*NamePasswordAuthentication)(nil)).Elem() +} + +type NamespaceFull struct { + VimFault + + Name string `xml:"name"` + CurrentMaxSize int64 `xml:"currentMaxSize"` + RequiredSize int64 `xml:"requiredSize,omitempty"` +} + +func init() { + t["NamespaceFull"] = reflect.TypeOf((*NamespaceFull)(nil)).Elem() +} + +type NamespaceFullFault NamespaceFull + +func init() { + t["NamespaceFullFault"] = reflect.TypeOf((*NamespaceFullFault)(nil)).Elem() +} + +type NamespaceLimitReached struct { + VimFault + + Limit int32 `xml:"limit,omitempty"` +} + +func init() { + t["NamespaceLimitReached"] = reflect.TypeOf((*NamespaceLimitReached)(nil)).Elem() +} + +type NamespaceLimitReachedFault NamespaceLimitReached + +func init() { + t["NamespaceLimitReachedFault"] = reflect.TypeOf((*NamespaceLimitReachedFault)(nil)).Elem() +} + +type NamespaceWriteProtected struct { + VimFault + + Name string `xml:"name"` +} + +func init() { + t["NamespaceWriteProtected"] = reflect.TypeOf((*NamespaceWriteProtected)(nil)).Elem() +} + +type NamespaceWriteProtectedFault NamespaceWriteProtected + +func init() { + t["NamespaceWriteProtectedFault"] = reflect.TypeOf((*NamespaceWriteProtectedFault)(nil)).Elem() +} + +type NasConfigFault struct { + HostConfigFault + + Name string `xml:"name"` +} + +func init() { + t["NasConfigFault"] = reflect.TypeOf((*NasConfigFault)(nil)).Elem() +} + +type NasConfigFaultFault BaseNasConfigFault + +func init() { + t["NasConfigFaultFault"] = reflect.TypeOf((*NasConfigFaultFault)(nil)).Elem() +} + +type NasConnectionLimitReached struct { + NasConfigFault + + RemoteHost string `xml:"remoteHost"` + RemotePath string `xml:"remotePath"` +} + +func init() { + t["NasConnectionLimitReached"] = reflect.TypeOf((*NasConnectionLimitReached)(nil)).Elem() +} + +type NasConnectionLimitReachedFault NasConnectionLimitReached + +func init() { + t["NasConnectionLimitReachedFault"] = reflect.TypeOf((*NasConnectionLimitReachedFault)(nil)).Elem() +} + +type NasDatastoreInfo struct { + DatastoreInfo + + Nas *HostNasVolume `xml:"nas,omitempty"` +} + +func init() { + t["NasDatastoreInfo"] = reflect.TypeOf((*NasDatastoreInfo)(nil)).Elem() +} + +type NasSessionCredentialConflict struct { + NasConfigFault + + RemoteHost string `xml:"remoteHost"` + RemotePath string `xml:"remotePath"` + UserName string `xml:"userName"` +} + +func init() { + t["NasSessionCredentialConflict"] = reflect.TypeOf((*NasSessionCredentialConflict)(nil)).Elem() +} + +type NasSessionCredentialConflictFault NasSessionCredentialConflict + +func init() { + t["NasSessionCredentialConflictFault"] = reflect.TypeOf((*NasSessionCredentialConflictFault)(nil)).Elem() +} + +type NasStorageProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["NasStorageProfile"] = reflect.TypeOf((*NasStorageProfile)(nil)).Elem() +} + +type NasVolumeNotMounted struct { + NasConfigFault + + RemoteHost string `xml:"remoteHost"` + RemotePath string `xml:"remotePath"` +} + +func init() { + t["NasVolumeNotMounted"] = reflect.TypeOf((*NasVolumeNotMounted)(nil)).Elem() +} + +type NasVolumeNotMountedFault NasVolumeNotMounted + +func init() { + t["NasVolumeNotMountedFault"] = reflect.TypeOf((*NasVolumeNotMountedFault)(nil)).Elem() +} + +type NegatableExpression struct { + DynamicData + + Negate *bool `xml:"negate"` +} + +func init() { + t["NegatableExpression"] = reflect.TypeOf((*NegatableExpression)(nil)).Elem() +} + +type NetBIOSConfigInfo struct { + DynamicData + + Mode string `xml:"mode"` +} + +func init() { + t["NetBIOSConfigInfo"] = reflect.TypeOf((*NetBIOSConfigInfo)(nil)).Elem() +} + +type NetDhcpConfigInfo struct { + DynamicData + + Ipv6 *NetDhcpConfigInfoDhcpOptions `xml:"ipv6,omitempty"` + Ipv4 *NetDhcpConfigInfoDhcpOptions `xml:"ipv4,omitempty"` +} + +func init() { + t["NetDhcpConfigInfo"] = reflect.TypeOf((*NetDhcpConfigInfo)(nil)).Elem() +} + +type NetDhcpConfigInfoDhcpOptions struct { + DynamicData + + Enable bool `xml:"enable"` + Config []KeyValue `xml:"config,omitempty"` +} + +func init() { + t["NetDhcpConfigInfoDhcpOptions"] = reflect.TypeOf((*NetDhcpConfigInfoDhcpOptions)(nil)).Elem() +} + +type NetDhcpConfigSpec struct { + DynamicData + + Ipv6 *NetDhcpConfigSpecDhcpOptionsSpec `xml:"ipv6,omitempty"` + Ipv4 *NetDhcpConfigSpecDhcpOptionsSpec `xml:"ipv4,omitempty"` +} + +func init() { + t["NetDhcpConfigSpec"] = reflect.TypeOf((*NetDhcpConfigSpec)(nil)).Elem() +} + +type NetDhcpConfigSpecDhcpOptionsSpec struct { + DynamicData + + Enable *bool `xml:"enable"` + Config []KeyValue `xml:"config"` + Operation string `xml:"operation"` +} + +func init() { + t["NetDhcpConfigSpecDhcpOptionsSpec"] = reflect.TypeOf((*NetDhcpConfigSpecDhcpOptionsSpec)(nil)).Elem() +} + +type NetDnsConfigInfo struct { + DynamicData + + Dhcp bool `xml:"dhcp"` + HostName string `xml:"hostName"` + DomainName string `xml:"domainName"` + IpAddress []string `xml:"ipAddress,omitempty"` + SearchDomain []string `xml:"searchDomain,omitempty"` +} + +func init() { + t["NetDnsConfigInfo"] = reflect.TypeOf((*NetDnsConfigInfo)(nil)).Elem() +} + +type NetDnsConfigSpec struct { + DynamicData + + Dhcp *bool `xml:"dhcp"` + HostName string `xml:"hostName,omitempty"` + DomainName string `xml:"domainName,omitempty"` + IpAddress []string `xml:"ipAddress,omitempty"` + SearchDomain []string `xml:"searchDomain,omitempty"` +} + +func init() { + t["NetDnsConfigSpec"] = reflect.TypeOf((*NetDnsConfigSpec)(nil)).Elem() +} + +type NetIpConfigInfo struct { + DynamicData + + IpAddress []NetIpConfigInfoIpAddress `xml:"ipAddress,omitempty"` + Dhcp *NetDhcpConfigInfo `xml:"dhcp,omitempty"` + AutoConfigurationEnabled *bool `xml:"autoConfigurationEnabled"` +} + +func init() { + t["NetIpConfigInfo"] = reflect.TypeOf((*NetIpConfigInfo)(nil)).Elem() +} + +type NetIpConfigInfoIpAddress struct { + DynamicData + + IpAddress string `xml:"ipAddress"` + PrefixLength int32 `xml:"prefixLength"` + Origin string `xml:"origin,omitempty"` + State string `xml:"state,omitempty"` + Lifetime *time.Time `xml:"lifetime"` +} + +func init() { + t["NetIpConfigInfoIpAddress"] = reflect.TypeOf((*NetIpConfigInfoIpAddress)(nil)).Elem() +} + +type NetIpConfigSpec struct { + DynamicData + + IpAddress []NetIpConfigSpecIpAddressSpec `xml:"ipAddress,omitempty"` + Dhcp *NetDhcpConfigSpec `xml:"dhcp,omitempty"` + AutoConfigurationEnabled *bool `xml:"autoConfigurationEnabled"` +} + +func init() { + t["NetIpConfigSpec"] = reflect.TypeOf((*NetIpConfigSpec)(nil)).Elem() +} + +type NetIpConfigSpecIpAddressSpec struct { + DynamicData + + IpAddress string `xml:"ipAddress"` + PrefixLength int32 `xml:"prefixLength"` + Operation string `xml:"operation"` +} + +func init() { + t["NetIpConfigSpecIpAddressSpec"] = reflect.TypeOf((*NetIpConfigSpecIpAddressSpec)(nil)).Elem() +} + +type NetIpRouteConfigInfo struct { + DynamicData + + IpRoute []NetIpRouteConfigInfoIpRoute `xml:"ipRoute,omitempty"` +} + +func init() { + t["NetIpRouteConfigInfo"] = reflect.TypeOf((*NetIpRouteConfigInfo)(nil)).Elem() +} + +type NetIpRouteConfigInfoGateway struct { + DynamicData + + IpAddress string `xml:"ipAddress,omitempty"` + Device string `xml:"device,omitempty"` +} + +func init() { + t["NetIpRouteConfigInfoGateway"] = reflect.TypeOf((*NetIpRouteConfigInfoGateway)(nil)).Elem() +} + +type NetIpRouteConfigInfoIpRoute struct { + DynamicData + + Network string `xml:"network"` + PrefixLength int32 `xml:"prefixLength"` + Gateway NetIpRouteConfigInfoGateway `xml:"gateway"` +} + +func init() { + t["NetIpRouteConfigInfoIpRoute"] = reflect.TypeOf((*NetIpRouteConfigInfoIpRoute)(nil)).Elem() +} + +type NetIpRouteConfigSpec struct { + DynamicData + + IpRoute []NetIpRouteConfigSpecIpRouteSpec `xml:"ipRoute,omitempty"` +} + +func init() { + t["NetIpRouteConfigSpec"] = reflect.TypeOf((*NetIpRouteConfigSpec)(nil)).Elem() +} + +type NetIpRouteConfigSpecGatewaySpec struct { + DynamicData + + IpAddress string `xml:"ipAddress,omitempty"` + Device string `xml:"device,omitempty"` +} + +func init() { + t["NetIpRouteConfigSpecGatewaySpec"] = reflect.TypeOf((*NetIpRouteConfigSpecGatewaySpec)(nil)).Elem() +} + +type NetIpRouteConfigSpecIpRouteSpec struct { + DynamicData + + Network string `xml:"network"` + PrefixLength int32 `xml:"prefixLength"` + Gateway NetIpRouteConfigSpecGatewaySpec `xml:"gateway"` + Operation string `xml:"operation"` +} + +func init() { + t["NetIpRouteConfigSpecIpRouteSpec"] = reflect.TypeOf((*NetIpRouteConfigSpecIpRouteSpec)(nil)).Elem() +} + +type NetIpStackInfo struct { + DynamicData + + Neighbor []NetIpStackInfoNetToMedia `xml:"neighbor,omitempty"` + DefaultRouter []NetIpStackInfoDefaultRouter `xml:"defaultRouter,omitempty"` +} + +func init() { + t["NetIpStackInfo"] = reflect.TypeOf((*NetIpStackInfo)(nil)).Elem() +} + +type NetIpStackInfoDefaultRouter struct { + DynamicData + + IpAddress string `xml:"ipAddress"` + Device string `xml:"device"` + Lifetime time.Time `xml:"lifetime"` + Preference string `xml:"preference"` +} + +func init() { + t["NetIpStackInfoDefaultRouter"] = reflect.TypeOf((*NetIpStackInfoDefaultRouter)(nil)).Elem() +} + +type NetIpStackInfoNetToMedia struct { + DynamicData + + IpAddress string `xml:"ipAddress"` + PhysicalAddress string `xml:"physicalAddress"` + Device string `xml:"device"` + Type string `xml:"type"` +} + +func init() { + t["NetIpStackInfoNetToMedia"] = reflect.TypeOf((*NetIpStackInfoNetToMedia)(nil)).Elem() +} + +type NetStackInstanceProfile struct { + ApplyProfile + + Key string `xml:"key"` + DnsConfig NetworkProfileDnsConfigProfile `xml:"dnsConfig"` + IpRouteConfig IpRouteProfile `xml:"ipRouteConfig"` +} + +func init() { + t["NetStackInstanceProfile"] = reflect.TypeOf((*NetStackInstanceProfile)(nil)).Elem() +} + +type NetworkCopyFault struct { + FileFault +} + +func init() { + t["NetworkCopyFault"] = reflect.TypeOf((*NetworkCopyFault)(nil)).Elem() +} + +type NetworkCopyFaultFault NetworkCopyFault + +func init() { + t["NetworkCopyFaultFault"] = reflect.TypeOf((*NetworkCopyFaultFault)(nil)).Elem() +} + +type NetworkDisruptedAndConfigRolledBack struct { + VimFault + + Host string `xml:"host"` +} + +func init() { + t["NetworkDisruptedAndConfigRolledBack"] = reflect.TypeOf((*NetworkDisruptedAndConfigRolledBack)(nil)).Elem() +} + +type NetworkDisruptedAndConfigRolledBackFault NetworkDisruptedAndConfigRolledBack + +func init() { + t["NetworkDisruptedAndConfigRolledBackFault"] = reflect.TypeOf((*NetworkDisruptedAndConfigRolledBackFault)(nil)).Elem() +} + +type NetworkEventArgument struct { + EntityEventArgument + + Network ManagedObjectReference `xml:"network"` +} + +func init() { + t["NetworkEventArgument"] = reflect.TypeOf((*NetworkEventArgument)(nil)).Elem() +} + +type NetworkInaccessible struct { + NasConfigFault +} + +func init() { + t["NetworkInaccessible"] = reflect.TypeOf((*NetworkInaccessible)(nil)).Elem() +} + +type NetworkInaccessibleFault NetworkInaccessible + +func init() { + t["NetworkInaccessibleFault"] = reflect.TypeOf((*NetworkInaccessibleFault)(nil)).Elem() +} + +type NetworkPolicyProfile struct { + ApplyProfile +} + +func init() { + t["NetworkPolicyProfile"] = reflect.TypeOf((*NetworkPolicyProfile)(nil)).Elem() +} + +type NetworkProfile struct { + ApplyProfile + + Vswitch []VirtualSwitchProfile `xml:"vswitch,omitempty"` + VmPortGroup []VmPortGroupProfile `xml:"vmPortGroup,omitempty"` + HostPortGroup []HostPortGroupProfile `xml:"hostPortGroup,omitempty"` + ServiceConsolePortGroup []ServiceConsolePortGroupProfile `xml:"serviceConsolePortGroup,omitempty"` + DnsConfig *NetworkProfileDnsConfigProfile `xml:"dnsConfig,omitempty"` + IpRouteConfig *IpRouteProfile `xml:"ipRouteConfig,omitempty"` + ConsoleIpRouteConfig *IpRouteProfile `xml:"consoleIpRouteConfig,omitempty"` + Pnic []PhysicalNicProfile `xml:"pnic,omitempty"` + Dvswitch []DvsProfile `xml:"dvswitch,omitempty"` + DvsServiceConsoleNic []DvsServiceConsoleVNicProfile `xml:"dvsServiceConsoleNic,omitempty"` + DvsHostNic []DvsHostVNicProfile `xml:"dvsHostNic,omitempty"` + NetStackInstance []NetStackInstanceProfile `xml:"netStackInstance,omitempty"` +} + +func init() { + t["NetworkProfile"] = reflect.TypeOf((*NetworkProfile)(nil)).Elem() +} + +type NetworkProfileDnsConfigProfile struct { + ApplyProfile +} + +func init() { + t["NetworkProfileDnsConfigProfile"] = reflect.TypeOf((*NetworkProfileDnsConfigProfile)(nil)).Elem() +} + +type NetworkRollbackEvent struct { + Event + + MethodName string `xml:"methodName"` + TransactionId string `xml:"transactionId"` +} + +func init() { + t["NetworkRollbackEvent"] = reflect.TypeOf((*NetworkRollbackEvent)(nil)).Elem() +} + +type NetworkSummary struct { + DynamicData + + Network *ManagedObjectReference `xml:"network,omitempty"` + Name string `xml:"name"` + Accessible bool `xml:"accessible"` + IpPoolName string `xml:"ipPoolName,omitempty"` + IpPoolId int32 `xml:"ipPoolId,omitempty"` +} + +func init() { + t["NetworkSummary"] = reflect.TypeOf((*NetworkSummary)(nil)).Elem() +} + +type NetworksMayNotBeTheSame struct { + MigrationFault + + Name string `xml:"name,omitempty"` +} + +func init() { + t["NetworksMayNotBeTheSame"] = reflect.TypeOf((*NetworksMayNotBeTheSame)(nil)).Elem() +} + +type NetworksMayNotBeTheSameFault NetworksMayNotBeTheSame + +func init() { + t["NetworksMayNotBeTheSameFault"] = reflect.TypeOf((*NetworksMayNotBeTheSameFault)(nil)).Elem() +} + +type NicSettingMismatch struct { + CustomizationFault + + NumberOfNicsInSpec int32 `xml:"numberOfNicsInSpec"` + NumberOfNicsInVM int32 `xml:"numberOfNicsInVM"` +} + +func init() { + t["NicSettingMismatch"] = reflect.TypeOf((*NicSettingMismatch)(nil)).Elem() +} + +type NicSettingMismatchFault NicSettingMismatch + +func init() { + t["NicSettingMismatchFault"] = reflect.TypeOf((*NicSettingMismatchFault)(nil)).Elem() +} + +type NoAccessUserEvent struct { + SessionEvent + + IpAddress string `xml:"ipAddress"` +} + +func init() { + t["NoAccessUserEvent"] = reflect.TypeOf((*NoAccessUserEvent)(nil)).Elem() +} + +type NoActiveHostInCluster struct { + InvalidState + + ComputeResource ManagedObjectReference `xml:"computeResource"` +} + +func init() { + t["NoActiveHostInCluster"] = reflect.TypeOf((*NoActiveHostInCluster)(nil)).Elem() +} + +type NoActiveHostInClusterFault NoActiveHostInCluster + +func init() { + t["NoActiveHostInClusterFault"] = reflect.TypeOf((*NoActiveHostInClusterFault)(nil)).Elem() +} + +type NoAvailableIp struct { + VAppPropertyFault + + Network ManagedObjectReference `xml:"network"` +} + +func init() { + t["NoAvailableIp"] = reflect.TypeOf((*NoAvailableIp)(nil)).Elem() +} + +type NoAvailableIpFault NoAvailableIp + +func init() { + t["NoAvailableIpFault"] = reflect.TypeOf((*NoAvailableIpFault)(nil)).Elem() +} + +type NoClientCertificate struct { + VimFault +} + +func init() { + t["NoClientCertificate"] = reflect.TypeOf((*NoClientCertificate)(nil)).Elem() +} + +type NoClientCertificateFault NoClientCertificate + +func init() { + t["NoClientCertificateFault"] = reflect.TypeOf((*NoClientCertificateFault)(nil)).Elem() +} + +type NoCompatibleDatastore struct { + VimFault +} + +func init() { + t["NoCompatibleDatastore"] = reflect.TypeOf((*NoCompatibleDatastore)(nil)).Elem() +} + +type NoCompatibleDatastoreFault NoCompatibleDatastore + +func init() { + t["NoCompatibleDatastoreFault"] = reflect.TypeOf((*NoCompatibleDatastoreFault)(nil)).Elem() +} + +type NoCompatibleHardAffinityHost struct { + VmConfigFault + + VmName string `xml:"vmName"` +} + +func init() { + t["NoCompatibleHardAffinityHost"] = reflect.TypeOf((*NoCompatibleHardAffinityHost)(nil)).Elem() +} + +type NoCompatibleHardAffinityHostFault NoCompatibleHardAffinityHost + +func init() { + t["NoCompatibleHardAffinityHostFault"] = reflect.TypeOf((*NoCompatibleHardAffinityHostFault)(nil)).Elem() +} + +type NoCompatibleHost struct { + VimFault + + Host []ManagedObjectReference `xml:"host,omitempty"` + Error []LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["NoCompatibleHost"] = reflect.TypeOf((*NoCompatibleHost)(nil)).Elem() +} + +type NoCompatibleHostFault BaseNoCompatibleHost + +func init() { + t["NoCompatibleHostFault"] = reflect.TypeOf((*NoCompatibleHostFault)(nil)).Elem() +} + +type NoCompatibleHostWithAccessToDevice struct { + NoCompatibleHost +} + +func init() { + t["NoCompatibleHostWithAccessToDevice"] = reflect.TypeOf((*NoCompatibleHostWithAccessToDevice)(nil)).Elem() +} + +type NoCompatibleHostWithAccessToDeviceFault NoCompatibleHostWithAccessToDevice + +func init() { + t["NoCompatibleHostWithAccessToDeviceFault"] = reflect.TypeOf((*NoCompatibleHostWithAccessToDeviceFault)(nil)).Elem() +} + +type NoCompatibleSoftAffinityHost struct { + VmConfigFault + + VmName string `xml:"vmName"` +} + +func init() { + t["NoCompatibleSoftAffinityHost"] = reflect.TypeOf((*NoCompatibleSoftAffinityHost)(nil)).Elem() +} + +type NoCompatibleSoftAffinityHostFault NoCompatibleSoftAffinityHost + +func init() { + t["NoCompatibleSoftAffinityHostFault"] = reflect.TypeOf((*NoCompatibleSoftAffinityHostFault)(nil)).Elem() +} + +type NoConnectedDatastore struct { + VimFault +} + +func init() { + t["NoConnectedDatastore"] = reflect.TypeOf((*NoConnectedDatastore)(nil)).Elem() +} + +type NoConnectedDatastoreFault NoConnectedDatastore + +func init() { + t["NoConnectedDatastoreFault"] = reflect.TypeOf((*NoConnectedDatastoreFault)(nil)).Elem() +} + +type NoDatastoresConfiguredEvent struct { + HostEvent +} + +func init() { + t["NoDatastoresConfiguredEvent"] = reflect.TypeOf((*NoDatastoresConfiguredEvent)(nil)).Elem() +} + +type NoDiskFound struct { + VimFault +} + +func init() { + t["NoDiskFound"] = reflect.TypeOf((*NoDiskFound)(nil)).Elem() +} + +type NoDiskFoundFault NoDiskFound + +func init() { + t["NoDiskFoundFault"] = reflect.TypeOf((*NoDiskFoundFault)(nil)).Elem() +} + +type NoDiskSpace struct { + FileFault + + Datastore string `xml:"datastore"` +} + +func init() { + t["NoDiskSpace"] = reflect.TypeOf((*NoDiskSpace)(nil)).Elem() +} + +type NoDiskSpaceFault NoDiskSpace + +func init() { + t["NoDiskSpaceFault"] = reflect.TypeOf((*NoDiskSpaceFault)(nil)).Elem() +} + +type NoDisksToCustomize struct { + CustomizationFault +} + +func init() { + t["NoDisksToCustomize"] = reflect.TypeOf((*NoDisksToCustomize)(nil)).Elem() +} + +type NoDisksToCustomizeFault NoDisksToCustomize + +func init() { + t["NoDisksToCustomizeFault"] = reflect.TypeOf((*NoDisksToCustomizeFault)(nil)).Elem() +} + +type NoGateway struct { + HostConfigFault +} + +func init() { + t["NoGateway"] = reflect.TypeOf((*NoGateway)(nil)).Elem() +} + +type NoGatewayFault NoGateway + +func init() { + t["NoGatewayFault"] = reflect.TypeOf((*NoGatewayFault)(nil)).Elem() +} + +type NoGuestHeartbeat struct { + MigrationFault +} + +func init() { + t["NoGuestHeartbeat"] = reflect.TypeOf((*NoGuestHeartbeat)(nil)).Elem() +} + +type NoGuestHeartbeatFault NoGuestHeartbeat + +func init() { + t["NoGuestHeartbeatFault"] = reflect.TypeOf((*NoGuestHeartbeatFault)(nil)).Elem() +} + +type NoHost struct { + HostConnectFault + + Name string `xml:"name,omitempty"` +} + +func init() { + t["NoHost"] = reflect.TypeOf((*NoHost)(nil)).Elem() +} + +type NoHostFault NoHost + +func init() { + t["NoHostFault"] = reflect.TypeOf((*NoHostFault)(nil)).Elem() +} + +type NoHostSuitableForFtSecondary struct { + VmFaultToleranceIssue + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` +} + +func init() { + t["NoHostSuitableForFtSecondary"] = reflect.TypeOf((*NoHostSuitableForFtSecondary)(nil)).Elem() +} + +type NoHostSuitableForFtSecondaryFault NoHostSuitableForFtSecondary + +func init() { + t["NoHostSuitableForFtSecondaryFault"] = reflect.TypeOf((*NoHostSuitableForFtSecondaryFault)(nil)).Elem() +} + +type NoLicenseEvent struct { + LicenseEvent + + Feature LicenseFeatureInfo `xml:"feature"` +} + +func init() { + t["NoLicenseEvent"] = reflect.TypeOf((*NoLicenseEvent)(nil)).Elem() +} + +type NoLicenseServerConfigured struct { + NotEnoughLicenses +} + +func init() { + t["NoLicenseServerConfigured"] = reflect.TypeOf((*NoLicenseServerConfigured)(nil)).Elem() +} + +type NoLicenseServerConfiguredFault NoLicenseServerConfigured + +func init() { + t["NoLicenseServerConfiguredFault"] = reflect.TypeOf((*NoLicenseServerConfiguredFault)(nil)).Elem() +} + +type NoMaintenanceModeDrsRecommendationForVM struct { + VmEvent +} + +func init() { + t["NoMaintenanceModeDrsRecommendationForVM"] = reflect.TypeOf((*NoMaintenanceModeDrsRecommendationForVM)(nil)).Elem() +} + +type NoPeerHostFound struct { + HostPowerOpFailed +} + +func init() { + t["NoPeerHostFound"] = reflect.TypeOf((*NoPeerHostFound)(nil)).Elem() +} + +type NoPeerHostFoundFault NoPeerHostFound + +func init() { + t["NoPeerHostFoundFault"] = reflect.TypeOf((*NoPeerHostFoundFault)(nil)).Elem() +} + +type NoPermission struct { + SecurityError + + Object ManagedObjectReference `xml:"object"` + PrivilegeId string `xml:"privilegeId"` +} + +func init() { + t["NoPermission"] = reflect.TypeOf((*NoPermission)(nil)).Elem() +} + +type NoPermissionFault BaseNoPermission + +func init() { + t["NoPermissionFault"] = reflect.TypeOf((*NoPermissionFault)(nil)).Elem() +} + +type NoPermissionOnAD struct { + ActiveDirectoryFault +} + +func init() { + t["NoPermissionOnAD"] = reflect.TypeOf((*NoPermissionOnAD)(nil)).Elem() +} + +type NoPermissionOnADFault NoPermissionOnAD + +func init() { + t["NoPermissionOnADFault"] = reflect.TypeOf((*NoPermissionOnADFault)(nil)).Elem() +} + +type NoPermissionOnHost struct { + HostConnectFault +} + +func init() { + t["NoPermissionOnHost"] = reflect.TypeOf((*NoPermissionOnHost)(nil)).Elem() +} + +type NoPermissionOnHostFault NoPermissionOnHost + +func init() { + t["NoPermissionOnHostFault"] = reflect.TypeOf((*NoPermissionOnHostFault)(nil)).Elem() +} + +type NoPermissionOnNasVolume struct { + NasConfigFault + + UserName string `xml:"userName,omitempty"` +} + +func init() { + t["NoPermissionOnNasVolume"] = reflect.TypeOf((*NoPermissionOnNasVolume)(nil)).Elem() +} + +type NoPermissionOnNasVolumeFault NoPermissionOnNasVolume + +func init() { + t["NoPermissionOnNasVolumeFault"] = reflect.TypeOf((*NoPermissionOnNasVolumeFault)(nil)).Elem() +} + +type NoSubjectName struct { + VimFault +} + +func init() { + t["NoSubjectName"] = reflect.TypeOf((*NoSubjectName)(nil)).Elem() +} + +type NoSubjectNameFault NoSubjectName + +func init() { + t["NoSubjectNameFault"] = reflect.TypeOf((*NoSubjectNameFault)(nil)).Elem() +} + +type NoVcManagedIpConfigured struct { + VAppPropertyFault +} + +func init() { + t["NoVcManagedIpConfigured"] = reflect.TypeOf((*NoVcManagedIpConfigured)(nil)).Elem() +} + +type NoVcManagedIpConfiguredFault NoVcManagedIpConfigured + +func init() { + t["NoVcManagedIpConfiguredFault"] = reflect.TypeOf((*NoVcManagedIpConfiguredFault)(nil)).Elem() +} + +type NoVirtualNic struct { + HostConfigFault +} + +func init() { + t["NoVirtualNic"] = reflect.TypeOf((*NoVirtualNic)(nil)).Elem() +} + +type NoVirtualNicFault NoVirtualNic + +func init() { + t["NoVirtualNicFault"] = reflect.TypeOf((*NoVirtualNicFault)(nil)).Elem() +} + +type NoVmInVApp struct { + VAppConfigFault +} + +func init() { + t["NoVmInVApp"] = reflect.TypeOf((*NoVmInVApp)(nil)).Elem() +} + +type NoVmInVAppFault NoVmInVApp + +func init() { + t["NoVmInVAppFault"] = reflect.TypeOf((*NoVmInVAppFault)(nil)).Elem() +} + +type NonADUserRequired struct { + ActiveDirectoryFault +} + +func init() { + t["NonADUserRequired"] = reflect.TypeOf((*NonADUserRequired)(nil)).Elem() +} + +type NonADUserRequiredFault NonADUserRequired + +func init() { + t["NonADUserRequiredFault"] = reflect.TypeOf((*NonADUserRequiredFault)(nil)).Elem() +} + +type NonHomeRDMVMotionNotSupported struct { + MigrationFeatureNotSupported + + Device string `xml:"device"` +} + +func init() { + t["NonHomeRDMVMotionNotSupported"] = reflect.TypeOf((*NonHomeRDMVMotionNotSupported)(nil)).Elem() +} + +type NonHomeRDMVMotionNotSupportedFault NonHomeRDMVMotionNotSupported + +func init() { + t["NonHomeRDMVMotionNotSupportedFault"] = reflect.TypeOf((*NonHomeRDMVMotionNotSupportedFault)(nil)).Elem() +} + +type NonPersistentDisksNotSupported struct { + DeviceNotSupported +} + +func init() { + t["NonPersistentDisksNotSupported"] = reflect.TypeOf((*NonPersistentDisksNotSupported)(nil)).Elem() +} + +type NonPersistentDisksNotSupportedFault NonPersistentDisksNotSupported + +func init() { + t["NonPersistentDisksNotSupportedFault"] = reflect.TypeOf((*NonPersistentDisksNotSupportedFault)(nil)).Elem() +} + +type NonVIWorkloadDetectedOnDatastoreEvent struct { + DatastoreEvent +} + +func init() { + t["NonVIWorkloadDetectedOnDatastoreEvent"] = reflect.TypeOf((*NonVIWorkloadDetectedOnDatastoreEvent)(nil)).Elem() +} + +type NonVmwareOuiMacNotSupportedHost struct { + NotSupportedHost + + HostName string `xml:"hostName"` +} + +func init() { + t["NonVmwareOuiMacNotSupportedHost"] = reflect.TypeOf((*NonVmwareOuiMacNotSupportedHost)(nil)).Elem() +} + +type NonVmwareOuiMacNotSupportedHostFault NonVmwareOuiMacNotSupportedHost + +func init() { + t["NonVmwareOuiMacNotSupportedHostFault"] = reflect.TypeOf((*NonVmwareOuiMacNotSupportedHostFault)(nil)).Elem() +} + +type NotADirectory struct { + FileFault +} + +func init() { + t["NotADirectory"] = reflect.TypeOf((*NotADirectory)(nil)).Elem() +} + +type NotADirectoryFault NotADirectory + +func init() { + t["NotADirectoryFault"] = reflect.TypeOf((*NotADirectoryFault)(nil)).Elem() +} + +type NotAFile struct { + FileFault +} + +func init() { + t["NotAFile"] = reflect.TypeOf((*NotAFile)(nil)).Elem() +} + +type NotAFileFault NotAFile + +func init() { + t["NotAFileFault"] = reflect.TypeOf((*NotAFileFault)(nil)).Elem() +} + +type NotAuthenticated struct { + NoPermission +} + +func init() { + t["NotAuthenticated"] = reflect.TypeOf((*NotAuthenticated)(nil)).Elem() +} + +type NotAuthenticatedFault NotAuthenticated + +func init() { + t["NotAuthenticatedFault"] = reflect.TypeOf((*NotAuthenticatedFault)(nil)).Elem() +} + +type NotEnoughCpus struct { + VirtualHardwareCompatibilityIssue + + NumCpuDest int32 `xml:"numCpuDest"` + NumCpuVm int32 `xml:"numCpuVm"` +} + +func init() { + t["NotEnoughCpus"] = reflect.TypeOf((*NotEnoughCpus)(nil)).Elem() +} + +type NotEnoughCpusFault BaseNotEnoughCpus + +func init() { + t["NotEnoughCpusFault"] = reflect.TypeOf((*NotEnoughCpusFault)(nil)).Elem() +} + +type NotEnoughLicenses struct { + RuntimeFault +} + +func init() { + t["NotEnoughLicenses"] = reflect.TypeOf((*NotEnoughLicenses)(nil)).Elem() +} + +type NotEnoughLicensesFault BaseNotEnoughLicenses + +func init() { + t["NotEnoughLicensesFault"] = reflect.TypeOf((*NotEnoughLicensesFault)(nil)).Elem() +} + +type NotEnoughLogicalCpus struct { + NotEnoughCpus + + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["NotEnoughLogicalCpus"] = reflect.TypeOf((*NotEnoughLogicalCpus)(nil)).Elem() +} + +type NotEnoughLogicalCpusFault NotEnoughLogicalCpus + +func init() { + t["NotEnoughLogicalCpusFault"] = reflect.TypeOf((*NotEnoughLogicalCpusFault)(nil)).Elem() +} + +type NotEnoughResourcesToStartVmEvent struct { + VmEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["NotEnoughResourcesToStartVmEvent"] = reflect.TypeOf((*NotEnoughResourcesToStartVmEvent)(nil)).Elem() +} + +type NotFound struct { + VimFault +} + +func init() { + t["NotFound"] = reflect.TypeOf((*NotFound)(nil)).Elem() +} + +type NotFoundFault NotFound + +func init() { + t["NotFoundFault"] = reflect.TypeOf((*NotFoundFault)(nil)).Elem() +} + +type NotImplemented struct { + RuntimeFault +} + +func init() { + t["NotImplemented"] = reflect.TypeOf((*NotImplemented)(nil)).Elem() +} + +type NotImplementedFault NotImplemented + +func init() { + t["NotImplementedFault"] = reflect.TypeOf((*NotImplementedFault)(nil)).Elem() +} + +type NotSupported struct { + RuntimeFault +} + +func init() { + t["NotSupported"] = reflect.TypeOf((*NotSupported)(nil)).Elem() +} + +type NotSupportedDeviceForFT struct { + VmFaultToleranceIssue + + Host ManagedObjectReference `xml:"host"` + HostName string `xml:"hostName,omitempty"` + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName,omitempty"` + DeviceType string `xml:"deviceType"` + DeviceLabel string `xml:"deviceLabel,omitempty"` +} + +func init() { + t["NotSupportedDeviceForFT"] = reflect.TypeOf((*NotSupportedDeviceForFT)(nil)).Elem() +} + +type NotSupportedDeviceForFTFault NotSupportedDeviceForFT + +func init() { + t["NotSupportedDeviceForFTFault"] = reflect.TypeOf((*NotSupportedDeviceForFTFault)(nil)).Elem() +} + +type NotSupportedFault BaseNotSupported + +func init() { + t["NotSupportedFault"] = reflect.TypeOf((*NotSupportedFault)(nil)).Elem() +} + +type NotSupportedHost struct { + HostConnectFault + + ProductName string `xml:"productName,omitempty"` + ProductVersion string `xml:"productVersion,omitempty"` +} + +func init() { + t["NotSupportedHost"] = reflect.TypeOf((*NotSupportedHost)(nil)).Elem() +} + +type NotSupportedHostFault BaseNotSupportedHost + +func init() { + t["NotSupportedHostFault"] = reflect.TypeOf((*NotSupportedHostFault)(nil)).Elem() +} + +type NotSupportedHostForChecksum struct { + VimFault +} + +func init() { + t["NotSupportedHostForChecksum"] = reflect.TypeOf((*NotSupportedHostForChecksum)(nil)).Elem() +} + +type NotSupportedHostForChecksumFault NotSupportedHostForChecksum + +func init() { + t["NotSupportedHostForChecksumFault"] = reflect.TypeOf((*NotSupportedHostForChecksumFault)(nil)).Elem() +} + +type NotSupportedHostForVFlash struct { + NotSupportedHost + + HostName string `xml:"hostName"` +} + +func init() { + t["NotSupportedHostForVFlash"] = reflect.TypeOf((*NotSupportedHostForVFlash)(nil)).Elem() +} + +type NotSupportedHostForVFlashFault NotSupportedHostForVFlash + +func init() { + t["NotSupportedHostForVFlashFault"] = reflect.TypeOf((*NotSupportedHostForVFlashFault)(nil)).Elem() +} + +type NotSupportedHostForVmcp struct { + NotSupportedHost + + HostName string `xml:"hostName"` +} + +func init() { + t["NotSupportedHostForVmcp"] = reflect.TypeOf((*NotSupportedHostForVmcp)(nil)).Elem() +} + +type NotSupportedHostForVmcpFault NotSupportedHostForVmcp + +func init() { + t["NotSupportedHostForVmcpFault"] = reflect.TypeOf((*NotSupportedHostForVmcpFault)(nil)).Elem() +} + +type NotSupportedHostForVmemFile struct { + NotSupportedHost + + HostName string `xml:"hostName"` +} + +func init() { + t["NotSupportedHostForVmemFile"] = reflect.TypeOf((*NotSupportedHostForVmemFile)(nil)).Elem() +} + +type NotSupportedHostForVmemFileFault NotSupportedHostForVmemFile + +func init() { + t["NotSupportedHostForVmemFileFault"] = reflect.TypeOf((*NotSupportedHostForVmemFileFault)(nil)).Elem() +} + +type NotSupportedHostForVsan struct { + NotSupportedHost + + HostName string `xml:"hostName"` +} + +func init() { + t["NotSupportedHostForVsan"] = reflect.TypeOf((*NotSupportedHostForVsan)(nil)).Elem() +} + +type NotSupportedHostForVsanFault NotSupportedHostForVsan + +func init() { + t["NotSupportedHostForVsanFault"] = reflect.TypeOf((*NotSupportedHostForVsanFault)(nil)).Elem() +} + +type NotSupportedHostInCluster struct { + NotSupportedHost +} + +func init() { + t["NotSupportedHostInCluster"] = reflect.TypeOf((*NotSupportedHostInCluster)(nil)).Elem() +} + +type NotSupportedHostInClusterFault BaseNotSupportedHostInCluster + +func init() { + t["NotSupportedHostInClusterFault"] = reflect.TypeOf((*NotSupportedHostInClusterFault)(nil)).Elem() +} + +type NotSupportedHostInDvs struct { + NotSupportedHost + + SwitchProductSpec DistributedVirtualSwitchProductSpec `xml:"switchProductSpec"` +} + +func init() { + t["NotSupportedHostInDvs"] = reflect.TypeOf((*NotSupportedHostInDvs)(nil)).Elem() +} + +type NotSupportedHostInDvsFault NotSupportedHostInDvs + +func init() { + t["NotSupportedHostInDvsFault"] = reflect.TypeOf((*NotSupportedHostInDvsFault)(nil)).Elem() +} + +type NotSupportedHostInHACluster struct { + NotSupportedHost + + HostName string `xml:"hostName"` + Build string `xml:"build"` +} + +func init() { + t["NotSupportedHostInHACluster"] = reflect.TypeOf((*NotSupportedHostInHACluster)(nil)).Elem() +} + +type NotSupportedHostInHAClusterFault NotSupportedHostInHACluster + +func init() { + t["NotSupportedHostInHAClusterFault"] = reflect.TypeOf((*NotSupportedHostInHAClusterFault)(nil)).Elem() +} + +type NotUserConfigurableProperty struct { + VAppPropertyFault +} + +func init() { + t["NotUserConfigurableProperty"] = reflect.TypeOf((*NotUserConfigurableProperty)(nil)).Elem() +} + +type NotUserConfigurablePropertyFault NotUserConfigurableProperty + +func init() { + t["NotUserConfigurablePropertyFault"] = reflect.TypeOf((*NotUserConfigurablePropertyFault)(nil)).Elem() +} + +type NumPortsProfile struct { + ApplyProfile +} + +func init() { + t["NumPortsProfile"] = reflect.TypeOf((*NumPortsProfile)(nil)).Elem() +} + +type NumVirtualCoresPerSocketNotSupported struct { + VirtualHardwareCompatibilityIssue + + MaxSupportedCoresPerSocketDest int32 `xml:"maxSupportedCoresPerSocketDest"` + NumCoresPerSocketVm int32 `xml:"numCoresPerSocketVm"` +} + +func init() { + t["NumVirtualCoresPerSocketNotSupported"] = reflect.TypeOf((*NumVirtualCoresPerSocketNotSupported)(nil)).Elem() +} + +type NumVirtualCoresPerSocketNotSupportedFault NumVirtualCoresPerSocketNotSupported + +func init() { + t["NumVirtualCoresPerSocketNotSupportedFault"] = reflect.TypeOf((*NumVirtualCoresPerSocketNotSupportedFault)(nil)).Elem() +} + +type NumVirtualCpusExceedsLimit struct { + InsufficientResourcesFault + + MaxSupportedVcpus int32 `xml:"maxSupportedVcpus"` +} + +func init() { + t["NumVirtualCpusExceedsLimit"] = reflect.TypeOf((*NumVirtualCpusExceedsLimit)(nil)).Elem() +} + +type NumVirtualCpusExceedsLimitFault NumVirtualCpusExceedsLimit + +func init() { + t["NumVirtualCpusExceedsLimitFault"] = reflect.TypeOf((*NumVirtualCpusExceedsLimitFault)(nil)).Elem() +} + +type NumVirtualCpusIncompatible struct { + VmConfigFault + + Reason string `xml:"reason"` + NumCpu int32 `xml:"numCpu"` +} + +func init() { + t["NumVirtualCpusIncompatible"] = reflect.TypeOf((*NumVirtualCpusIncompatible)(nil)).Elem() +} + +type NumVirtualCpusIncompatibleFault NumVirtualCpusIncompatible + +func init() { + t["NumVirtualCpusIncompatibleFault"] = reflect.TypeOf((*NumVirtualCpusIncompatibleFault)(nil)).Elem() +} + +type NumVirtualCpusNotSupported struct { + VirtualHardwareCompatibilityIssue + + MaxSupportedVcpusDest int32 `xml:"maxSupportedVcpusDest"` + NumCpuVm int32 `xml:"numCpuVm"` +} + +func init() { + t["NumVirtualCpusNotSupported"] = reflect.TypeOf((*NumVirtualCpusNotSupported)(nil)).Elem() +} + +type NumVirtualCpusNotSupportedFault NumVirtualCpusNotSupported + +func init() { + t["NumVirtualCpusNotSupportedFault"] = reflect.TypeOf((*NumVirtualCpusNotSupportedFault)(nil)).Elem() +} + +type NumericRange struct { + DynamicData + + Start int32 `xml:"start"` + End int32 `xml:"end"` +} + +func init() { + t["NumericRange"] = reflect.TypeOf((*NumericRange)(nil)).Elem() +} + +type ObjectContent struct { + DynamicData + + Obj ManagedObjectReference `xml:"obj"` + PropSet []DynamicProperty `xml:"propSet,omitempty"` + MissingSet []MissingProperty `xml:"missingSet,omitempty"` +} + +func init() { + t["ObjectContent"] = reflect.TypeOf((*ObjectContent)(nil)).Elem() +} + +type ObjectSpec struct { + DynamicData + + Obj ManagedObjectReference `xml:"obj"` + Skip *bool `xml:"skip"` + SelectSet []BaseSelectionSpec `xml:"selectSet,omitempty,typeattr"` +} + +func init() { + t["ObjectSpec"] = reflect.TypeOf((*ObjectSpec)(nil)).Elem() +} + +type ObjectUpdate struct { + DynamicData + + Kind ObjectUpdateKind `xml:"kind"` + Obj ManagedObjectReference `xml:"obj"` + ChangeSet []PropertyChange `xml:"changeSet,omitempty"` + MissingSet []MissingProperty `xml:"missingSet,omitempty"` +} + +func init() { + t["ObjectUpdate"] = reflect.TypeOf((*ObjectUpdate)(nil)).Elem() +} + +type OnceTaskScheduler struct { + TaskScheduler + + RunAt *time.Time `xml:"runAt"` +} + +func init() { + t["OnceTaskScheduler"] = reflect.TypeOf((*OnceTaskScheduler)(nil)).Elem() +} + +type OpaqueNetworkSummary struct { + NetworkSummary + + OpaqueNetworkId string `xml:"opaqueNetworkId"` + OpaqueNetworkType string `xml:"opaqueNetworkType"` +} + +func init() { + t["OpaqueNetworkSummary"] = reflect.TypeOf((*OpaqueNetworkSummary)(nil)).Elem() +} + +type OpaqueNetworkTargetInfo struct { + VirtualMachineTargetInfo + + Network OpaqueNetworkSummary `xml:"network"` + NetworkReservationSupported *bool `xml:"networkReservationSupported"` +} + +func init() { + t["OpaqueNetworkTargetInfo"] = reflect.TypeOf((*OpaqueNetworkTargetInfo)(nil)).Elem() +} + +type OpenInventoryViewFolder OpenInventoryViewFolderRequestType + +func init() { + t["OpenInventoryViewFolder"] = reflect.TypeOf((*OpenInventoryViewFolder)(nil)).Elem() +} + +type OpenInventoryViewFolderRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity []ManagedObjectReference `xml:"entity"` +} + +func init() { + t["OpenInventoryViewFolderRequestType"] = reflect.TypeOf((*OpenInventoryViewFolderRequestType)(nil)).Elem() +} + +type OpenInventoryViewFolderResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type OperationDisabledByGuest struct { + GuestOperationsFault +} + +func init() { + t["OperationDisabledByGuest"] = reflect.TypeOf((*OperationDisabledByGuest)(nil)).Elem() +} + +type OperationDisabledByGuestFault OperationDisabledByGuest + +func init() { + t["OperationDisabledByGuestFault"] = reflect.TypeOf((*OperationDisabledByGuestFault)(nil)).Elem() +} + +type OperationDisallowedOnHost struct { + RuntimeFault +} + +func init() { + t["OperationDisallowedOnHost"] = reflect.TypeOf((*OperationDisallowedOnHost)(nil)).Elem() +} + +type OperationDisallowedOnHostFault OperationDisallowedOnHost + +func init() { + t["OperationDisallowedOnHostFault"] = reflect.TypeOf((*OperationDisallowedOnHostFault)(nil)).Elem() +} + +type OperationNotSupportedByGuest struct { + GuestOperationsFault +} + +func init() { + t["OperationNotSupportedByGuest"] = reflect.TypeOf((*OperationNotSupportedByGuest)(nil)).Elem() +} + +type OperationNotSupportedByGuestFault OperationNotSupportedByGuest + +func init() { + t["OperationNotSupportedByGuestFault"] = reflect.TypeOf((*OperationNotSupportedByGuestFault)(nil)).Elem() +} + +type OptionDef struct { + ElementDescription + + OptionType BaseOptionType `xml:"optionType,typeattr"` +} + +func init() { + t["OptionDef"] = reflect.TypeOf((*OptionDef)(nil)).Elem() +} + +type OptionProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["OptionProfile"] = reflect.TypeOf((*OptionProfile)(nil)).Elem() +} + +type OptionType struct { + DynamicData + + ValueIsReadonly *bool `xml:"valueIsReadonly"` +} + +func init() { + t["OptionType"] = reflect.TypeOf((*OptionType)(nil)).Elem() +} + +type OptionValue struct { + DynamicData + + Key string `xml:"key"` + Value AnyType `xml:"value,omitempty,typeattr"` +} + +func init() { + t["OptionValue"] = reflect.TypeOf((*OptionValue)(nil)).Elem() +} + +type OrAlarmExpression struct { + AlarmExpression + + Expression []BaseAlarmExpression `xml:"expression,typeattr"` +} + +func init() { + t["OrAlarmExpression"] = reflect.TypeOf((*OrAlarmExpression)(nil)).Elem() +} + +type OutOfBounds struct { + VimFault + + ArgumentName string `xml:"argumentName"` +} + +func init() { + t["OutOfBounds"] = reflect.TypeOf((*OutOfBounds)(nil)).Elem() +} + +type OutOfBoundsFault OutOfBounds + +func init() { + t["OutOfBoundsFault"] = reflect.TypeOf((*OutOfBoundsFault)(nil)).Elem() +} + +type OutOfSyncDvsHost struct { + DvsEvent + + HostOutOfSync []DvsOutOfSyncHostArgument `xml:"hostOutOfSync"` +} + +func init() { + t["OutOfSyncDvsHost"] = reflect.TypeOf((*OutOfSyncDvsHost)(nil)).Elem() +} + +type OverwriteCustomizationSpec OverwriteCustomizationSpecRequestType + +func init() { + t["OverwriteCustomizationSpec"] = reflect.TypeOf((*OverwriteCustomizationSpec)(nil)).Elem() +} + +type OverwriteCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Item CustomizationSpecItem `xml:"item"` +} + +func init() { + t["OverwriteCustomizationSpecRequestType"] = reflect.TypeOf((*OverwriteCustomizationSpecRequestType)(nil)).Elem() +} + +type OverwriteCustomizationSpecResponse struct { +} + +type OvfAttribute struct { + OvfInvalidPackage + + ElementName string `xml:"elementName"` + AttributeName string `xml:"attributeName"` +} + +func init() { + t["OvfAttribute"] = reflect.TypeOf((*OvfAttribute)(nil)).Elem() +} + +type OvfAttributeFault BaseOvfAttribute + +func init() { + t["OvfAttributeFault"] = reflect.TypeOf((*OvfAttributeFault)(nil)).Elem() +} + +type OvfConnectedDevice struct { + OvfHardwareExport +} + +func init() { + t["OvfConnectedDevice"] = reflect.TypeOf((*OvfConnectedDevice)(nil)).Elem() +} + +type OvfConnectedDeviceFault BaseOvfConnectedDevice + +func init() { + t["OvfConnectedDeviceFault"] = reflect.TypeOf((*OvfConnectedDeviceFault)(nil)).Elem() +} + +type OvfConnectedDeviceFloppy struct { + OvfConnectedDevice + + Filename string `xml:"filename"` +} + +func init() { + t["OvfConnectedDeviceFloppy"] = reflect.TypeOf((*OvfConnectedDeviceFloppy)(nil)).Elem() +} + +type OvfConnectedDeviceFloppyFault OvfConnectedDeviceFloppy + +func init() { + t["OvfConnectedDeviceFloppyFault"] = reflect.TypeOf((*OvfConnectedDeviceFloppyFault)(nil)).Elem() +} + +type OvfConnectedDeviceIso struct { + OvfConnectedDevice + + Filename string `xml:"filename"` +} + +func init() { + t["OvfConnectedDeviceIso"] = reflect.TypeOf((*OvfConnectedDeviceIso)(nil)).Elem() +} + +type OvfConnectedDeviceIsoFault OvfConnectedDeviceIso + +func init() { + t["OvfConnectedDeviceIsoFault"] = reflect.TypeOf((*OvfConnectedDeviceIsoFault)(nil)).Elem() +} + +type OvfConstraint struct { + OvfInvalidPackage + + Name string `xml:"name"` +} + +func init() { + t["OvfConstraint"] = reflect.TypeOf((*OvfConstraint)(nil)).Elem() +} + +type OvfConstraintFault BaseOvfConstraint + +func init() { + t["OvfConstraintFault"] = reflect.TypeOf((*OvfConstraintFault)(nil)).Elem() +} + +type OvfConsumerCallbackFault struct { + OvfFault + + ExtensionKey string `xml:"extensionKey"` + ExtensionName string `xml:"extensionName"` +} + +func init() { + t["OvfConsumerCallbackFault"] = reflect.TypeOf((*OvfConsumerCallbackFault)(nil)).Elem() +} + +type OvfConsumerCallbackFaultFault BaseOvfConsumerCallbackFault + +func init() { + t["OvfConsumerCallbackFaultFault"] = reflect.TypeOf((*OvfConsumerCallbackFaultFault)(nil)).Elem() +} + +type OvfConsumerCommunicationError struct { + OvfConsumerCallbackFault + + Description string `xml:"description"` +} + +func init() { + t["OvfConsumerCommunicationError"] = reflect.TypeOf((*OvfConsumerCommunicationError)(nil)).Elem() +} + +type OvfConsumerCommunicationErrorFault OvfConsumerCommunicationError + +func init() { + t["OvfConsumerCommunicationErrorFault"] = reflect.TypeOf((*OvfConsumerCommunicationErrorFault)(nil)).Elem() +} + +type OvfConsumerFault struct { + OvfConsumerCallbackFault + + ErrorKey string `xml:"errorKey"` + Message string `xml:"message"` + Params []KeyValue `xml:"params,omitempty"` +} + +func init() { + t["OvfConsumerFault"] = reflect.TypeOf((*OvfConsumerFault)(nil)).Elem() +} + +type OvfConsumerFaultFault OvfConsumerFault + +func init() { + t["OvfConsumerFaultFault"] = reflect.TypeOf((*OvfConsumerFaultFault)(nil)).Elem() +} + +type OvfConsumerInvalidSection struct { + OvfConsumerCallbackFault + + LineNumber int32 `xml:"lineNumber"` + Description string `xml:"description"` +} + +func init() { + t["OvfConsumerInvalidSection"] = reflect.TypeOf((*OvfConsumerInvalidSection)(nil)).Elem() +} + +type OvfConsumerInvalidSectionFault OvfConsumerInvalidSection + +func init() { + t["OvfConsumerInvalidSectionFault"] = reflect.TypeOf((*OvfConsumerInvalidSectionFault)(nil)).Elem() +} + +type OvfConsumerOstNode struct { + DynamicData + + Id string `xml:"id"` + Type string `xml:"type"` + Section []OvfConsumerOvfSection `xml:"section,omitempty"` + Child []OvfConsumerOstNode `xml:"child,omitempty"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["OvfConsumerOstNode"] = reflect.TypeOf((*OvfConsumerOstNode)(nil)).Elem() +} + +type OvfConsumerOvfSection struct { + DynamicData + + LineNumber int32 `xml:"lineNumber"` + Xml string `xml:"xml"` +} + +func init() { + t["OvfConsumerOvfSection"] = reflect.TypeOf((*OvfConsumerOvfSection)(nil)).Elem() +} + +type OvfConsumerPowerOnFault struct { + InvalidState + + ExtensionKey string `xml:"extensionKey"` + ExtensionName string `xml:"extensionName"` + Description string `xml:"description"` +} + +func init() { + t["OvfConsumerPowerOnFault"] = reflect.TypeOf((*OvfConsumerPowerOnFault)(nil)).Elem() +} + +type OvfConsumerPowerOnFaultFault OvfConsumerPowerOnFault + +func init() { + t["OvfConsumerPowerOnFaultFault"] = reflect.TypeOf((*OvfConsumerPowerOnFaultFault)(nil)).Elem() +} + +type OvfConsumerUndeclaredSection struct { + OvfConsumerCallbackFault + + QualifiedSectionType string `xml:"qualifiedSectionType"` +} + +func init() { + t["OvfConsumerUndeclaredSection"] = reflect.TypeOf((*OvfConsumerUndeclaredSection)(nil)).Elem() +} + +type OvfConsumerUndeclaredSectionFault OvfConsumerUndeclaredSection + +func init() { + t["OvfConsumerUndeclaredSectionFault"] = reflect.TypeOf((*OvfConsumerUndeclaredSectionFault)(nil)).Elem() +} + +type OvfConsumerUndefinedPrefix struct { + OvfConsumerCallbackFault + + Prefix string `xml:"prefix"` +} + +func init() { + t["OvfConsumerUndefinedPrefix"] = reflect.TypeOf((*OvfConsumerUndefinedPrefix)(nil)).Elem() +} + +type OvfConsumerUndefinedPrefixFault OvfConsumerUndefinedPrefix + +func init() { + t["OvfConsumerUndefinedPrefixFault"] = reflect.TypeOf((*OvfConsumerUndefinedPrefixFault)(nil)).Elem() +} + +type OvfConsumerValidationFault struct { + VmConfigFault + + ExtensionKey string `xml:"extensionKey"` + ExtensionName string `xml:"extensionName"` + Message string `xml:"message"` +} + +func init() { + t["OvfConsumerValidationFault"] = reflect.TypeOf((*OvfConsumerValidationFault)(nil)).Elem() +} + +type OvfConsumerValidationFaultFault OvfConsumerValidationFault + +func init() { + t["OvfConsumerValidationFaultFault"] = reflect.TypeOf((*OvfConsumerValidationFaultFault)(nil)).Elem() +} + +type OvfCpuCompatibility struct { + OvfImport + + RegisterName string `xml:"registerName"` + Level int32 `xml:"level"` + RegisterValue string `xml:"registerValue"` + DesiredRegisterValue string `xml:"desiredRegisterValue"` +} + +func init() { + t["OvfCpuCompatibility"] = reflect.TypeOf((*OvfCpuCompatibility)(nil)).Elem() +} + +type OvfCpuCompatibilityCheckNotSupported struct { + OvfImport +} + +func init() { + t["OvfCpuCompatibilityCheckNotSupported"] = reflect.TypeOf((*OvfCpuCompatibilityCheckNotSupported)(nil)).Elem() +} + +type OvfCpuCompatibilityCheckNotSupportedFault OvfCpuCompatibilityCheckNotSupported + +func init() { + t["OvfCpuCompatibilityCheckNotSupportedFault"] = reflect.TypeOf((*OvfCpuCompatibilityCheckNotSupportedFault)(nil)).Elem() +} + +type OvfCpuCompatibilityFault OvfCpuCompatibility + +func init() { + t["OvfCpuCompatibilityFault"] = reflect.TypeOf((*OvfCpuCompatibilityFault)(nil)).Elem() +} + +type OvfCreateDescriptorParams struct { + DynamicData + + OvfFiles []OvfFile `xml:"ovfFiles,omitempty"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` + IncludeImageFiles *bool `xml:"includeImageFiles"` + ExportOption []string `xml:"exportOption,omitempty"` + Snapshot *ManagedObjectReference `xml:"snapshot,omitempty"` +} + +func init() { + t["OvfCreateDescriptorParams"] = reflect.TypeOf((*OvfCreateDescriptorParams)(nil)).Elem() +} + +type OvfCreateDescriptorResult struct { + DynamicData + + OvfDescriptor string `xml:"ovfDescriptor"` + Error []LocalizedMethodFault `xml:"error,omitempty"` + Warning []LocalizedMethodFault `xml:"warning,omitempty"` + IncludeImageFiles *bool `xml:"includeImageFiles"` +} + +func init() { + t["OvfCreateDescriptorResult"] = reflect.TypeOf((*OvfCreateDescriptorResult)(nil)).Elem() +} + +type OvfCreateImportSpecParams struct { + OvfManagerCommonParams + + EntityName string `xml:"entityName"` + HostSystem *ManagedObjectReference `xml:"hostSystem,omitempty"` + NetworkMapping []OvfNetworkMapping `xml:"networkMapping,omitempty"` + IpAllocationPolicy string `xml:"ipAllocationPolicy,omitempty"` + IpProtocol string `xml:"ipProtocol,omitempty"` + PropertyMapping []KeyValue `xml:"propertyMapping,omitempty"` + ResourceMapping []OvfResourceMap `xml:"resourceMapping,omitempty"` + DiskProvisioning string `xml:"diskProvisioning,omitempty"` + InstantiationOst *OvfConsumerOstNode `xml:"instantiationOst,omitempty"` +} + +func init() { + t["OvfCreateImportSpecParams"] = reflect.TypeOf((*OvfCreateImportSpecParams)(nil)).Elem() +} + +type OvfCreateImportSpecResult struct { + DynamicData + + ImportSpec BaseImportSpec `xml:"importSpec,omitempty,typeattr"` + FileItem []OvfFileItem `xml:"fileItem,omitempty"` + Warning []LocalizedMethodFault `xml:"warning,omitempty"` + Error []LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["OvfCreateImportSpecResult"] = reflect.TypeOf((*OvfCreateImportSpecResult)(nil)).Elem() +} + +type OvfDeploymentOption struct { + DynamicData + + Key string `xml:"key"` + Label string `xml:"label"` + Description string `xml:"description"` +} + +func init() { + t["OvfDeploymentOption"] = reflect.TypeOf((*OvfDeploymentOption)(nil)).Elem() +} + +type OvfDiskMappingNotFound struct { + OvfSystemFault + + DiskName string `xml:"diskName"` + VmName string `xml:"vmName"` +} + +func init() { + t["OvfDiskMappingNotFound"] = reflect.TypeOf((*OvfDiskMappingNotFound)(nil)).Elem() +} + +type OvfDiskMappingNotFoundFault OvfDiskMappingNotFound + +func init() { + t["OvfDiskMappingNotFoundFault"] = reflect.TypeOf((*OvfDiskMappingNotFoundFault)(nil)).Elem() +} + +type OvfDiskOrderConstraint struct { + OvfConstraint +} + +func init() { + t["OvfDiskOrderConstraint"] = reflect.TypeOf((*OvfDiskOrderConstraint)(nil)).Elem() +} + +type OvfDiskOrderConstraintFault OvfDiskOrderConstraint + +func init() { + t["OvfDiskOrderConstraintFault"] = reflect.TypeOf((*OvfDiskOrderConstraintFault)(nil)).Elem() +} + +type OvfDuplicateElement struct { + OvfElement +} + +func init() { + t["OvfDuplicateElement"] = reflect.TypeOf((*OvfDuplicateElement)(nil)).Elem() +} + +type OvfDuplicateElementFault OvfDuplicateElement + +func init() { + t["OvfDuplicateElementFault"] = reflect.TypeOf((*OvfDuplicateElementFault)(nil)).Elem() +} + +type OvfDuplicatedElementBoundary struct { + OvfElement + + Boundary string `xml:"boundary"` +} + +func init() { + t["OvfDuplicatedElementBoundary"] = reflect.TypeOf((*OvfDuplicatedElementBoundary)(nil)).Elem() +} + +type OvfDuplicatedElementBoundaryFault OvfDuplicatedElementBoundary + +func init() { + t["OvfDuplicatedElementBoundaryFault"] = reflect.TypeOf((*OvfDuplicatedElementBoundaryFault)(nil)).Elem() +} + +type OvfDuplicatedPropertyIdExport struct { + OvfExport + + Fqid string `xml:"fqid"` +} + +func init() { + t["OvfDuplicatedPropertyIdExport"] = reflect.TypeOf((*OvfDuplicatedPropertyIdExport)(nil)).Elem() +} + +type OvfDuplicatedPropertyIdExportFault OvfDuplicatedPropertyIdExport + +func init() { + t["OvfDuplicatedPropertyIdExportFault"] = reflect.TypeOf((*OvfDuplicatedPropertyIdExportFault)(nil)).Elem() +} + +type OvfDuplicatedPropertyIdImport struct { + OvfExport +} + +func init() { + t["OvfDuplicatedPropertyIdImport"] = reflect.TypeOf((*OvfDuplicatedPropertyIdImport)(nil)).Elem() +} + +type OvfDuplicatedPropertyIdImportFault OvfDuplicatedPropertyIdImport + +func init() { + t["OvfDuplicatedPropertyIdImportFault"] = reflect.TypeOf((*OvfDuplicatedPropertyIdImportFault)(nil)).Elem() +} + +type OvfElement struct { + OvfInvalidPackage + + Name string `xml:"name"` +} + +func init() { + t["OvfElement"] = reflect.TypeOf((*OvfElement)(nil)).Elem() +} + +type OvfElementFault BaseOvfElement + +func init() { + t["OvfElementFault"] = reflect.TypeOf((*OvfElementFault)(nil)).Elem() +} + +type OvfElementInvalidValue struct { + OvfElement + + Value string `xml:"value"` +} + +func init() { + t["OvfElementInvalidValue"] = reflect.TypeOf((*OvfElementInvalidValue)(nil)).Elem() +} + +type OvfElementInvalidValueFault OvfElementInvalidValue + +func init() { + t["OvfElementInvalidValueFault"] = reflect.TypeOf((*OvfElementInvalidValueFault)(nil)).Elem() +} + +type OvfExport struct { + OvfFault +} + +func init() { + t["OvfExport"] = reflect.TypeOf((*OvfExport)(nil)).Elem() +} + +type OvfExportFailed struct { + OvfExport +} + +func init() { + t["OvfExportFailed"] = reflect.TypeOf((*OvfExportFailed)(nil)).Elem() +} + +type OvfExportFailedFault OvfExportFailed + +func init() { + t["OvfExportFailedFault"] = reflect.TypeOf((*OvfExportFailedFault)(nil)).Elem() +} + +type OvfExportFault BaseOvfExport + +func init() { + t["OvfExportFault"] = reflect.TypeOf((*OvfExportFault)(nil)).Elem() +} + +type OvfFault struct { + VimFault +} + +func init() { + t["OvfFault"] = reflect.TypeOf((*OvfFault)(nil)).Elem() +} + +type OvfFaultFault BaseOvfFault + +func init() { + t["OvfFaultFault"] = reflect.TypeOf((*OvfFaultFault)(nil)).Elem() +} + +type OvfFile struct { + DynamicData + + DeviceId string `xml:"deviceId"` + Path string `xml:"path"` + CompressionMethod string `xml:"compressionMethod,omitempty"` + ChunkSize int64 `xml:"chunkSize,omitempty"` + Size int64 `xml:"size"` + Capacity int64 `xml:"capacity,omitempty"` + PopulatedSize int64 `xml:"populatedSize,omitempty"` +} + +func init() { + t["OvfFile"] = reflect.TypeOf((*OvfFile)(nil)).Elem() +} + +type OvfFileItem struct { + DynamicData + + DeviceId string `xml:"deviceId"` + Path string `xml:"path"` + CompressionMethod string `xml:"compressionMethod,omitempty"` + ChunkSize int64 `xml:"chunkSize,omitempty"` + Size int64 `xml:"size,omitempty"` + CimType int32 `xml:"cimType"` + Create bool `xml:"create"` +} + +func init() { + t["OvfFileItem"] = reflect.TypeOf((*OvfFileItem)(nil)).Elem() +} + +type OvfHardwareCheck struct { + OvfImport +} + +func init() { + t["OvfHardwareCheck"] = reflect.TypeOf((*OvfHardwareCheck)(nil)).Elem() +} + +type OvfHardwareCheckFault OvfHardwareCheck + +func init() { + t["OvfHardwareCheckFault"] = reflect.TypeOf((*OvfHardwareCheckFault)(nil)).Elem() +} + +type OvfHardwareExport struct { + OvfExport + + Device BaseVirtualDevice `xml:"device,omitempty,typeattr"` + VmPath string `xml:"vmPath"` +} + +func init() { + t["OvfHardwareExport"] = reflect.TypeOf((*OvfHardwareExport)(nil)).Elem() +} + +type OvfHardwareExportFault BaseOvfHardwareExport + +func init() { + t["OvfHardwareExportFault"] = reflect.TypeOf((*OvfHardwareExportFault)(nil)).Elem() +} + +type OvfHostResourceConstraint struct { + OvfConstraint + + Value string `xml:"value"` +} + +func init() { + t["OvfHostResourceConstraint"] = reflect.TypeOf((*OvfHostResourceConstraint)(nil)).Elem() +} + +type OvfHostResourceConstraintFault OvfHostResourceConstraint + +func init() { + t["OvfHostResourceConstraintFault"] = reflect.TypeOf((*OvfHostResourceConstraintFault)(nil)).Elem() +} + +type OvfHostValueNotParsed struct { + OvfSystemFault + + Property string `xml:"property"` + Value string `xml:"value"` +} + +func init() { + t["OvfHostValueNotParsed"] = reflect.TypeOf((*OvfHostValueNotParsed)(nil)).Elem() +} + +type OvfHostValueNotParsedFault OvfHostValueNotParsed + +func init() { + t["OvfHostValueNotParsedFault"] = reflect.TypeOf((*OvfHostValueNotParsedFault)(nil)).Elem() +} + +type OvfImport struct { + OvfFault +} + +func init() { + t["OvfImport"] = reflect.TypeOf((*OvfImport)(nil)).Elem() +} + +type OvfImportFailed struct { + OvfImport +} + +func init() { + t["OvfImportFailed"] = reflect.TypeOf((*OvfImportFailed)(nil)).Elem() +} + +type OvfImportFailedFault OvfImportFailed + +func init() { + t["OvfImportFailedFault"] = reflect.TypeOf((*OvfImportFailedFault)(nil)).Elem() +} + +type OvfImportFault BaseOvfImport + +func init() { + t["OvfImportFault"] = reflect.TypeOf((*OvfImportFault)(nil)).Elem() +} + +type OvfInternalError struct { + OvfSystemFault +} + +func init() { + t["OvfInternalError"] = reflect.TypeOf((*OvfInternalError)(nil)).Elem() +} + +type OvfInternalErrorFault OvfInternalError + +func init() { + t["OvfInternalErrorFault"] = reflect.TypeOf((*OvfInternalErrorFault)(nil)).Elem() +} + +type OvfInvalidPackage struct { + OvfFault + + LineNumber int32 `xml:"lineNumber"` +} + +func init() { + t["OvfInvalidPackage"] = reflect.TypeOf((*OvfInvalidPackage)(nil)).Elem() +} + +type OvfInvalidPackageFault BaseOvfInvalidPackage + +func init() { + t["OvfInvalidPackageFault"] = reflect.TypeOf((*OvfInvalidPackageFault)(nil)).Elem() +} + +type OvfInvalidValue struct { + OvfAttribute + + Value string `xml:"value"` +} + +func init() { + t["OvfInvalidValue"] = reflect.TypeOf((*OvfInvalidValue)(nil)).Elem() +} + +type OvfInvalidValueConfiguration struct { + OvfInvalidValue +} + +func init() { + t["OvfInvalidValueConfiguration"] = reflect.TypeOf((*OvfInvalidValueConfiguration)(nil)).Elem() +} + +type OvfInvalidValueConfigurationFault OvfInvalidValueConfiguration + +func init() { + t["OvfInvalidValueConfigurationFault"] = reflect.TypeOf((*OvfInvalidValueConfigurationFault)(nil)).Elem() +} + +type OvfInvalidValueEmpty struct { + OvfInvalidValue +} + +func init() { + t["OvfInvalidValueEmpty"] = reflect.TypeOf((*OvfInvalidValueEmpty)(nil)).Elem() +} + +type OvfInvalidValueEmptyFault OvfInvalidValueEmpty + +func init() { + t["OvfInvalidValueEmptyFault"] = reflect.TypeOf((*OvfInvalidValueEmptyFault)(nil)).Elem() +} + +type OvfInvalidValueFault BaseOvfInvalidValue + +func init() { + t["OvfInvalidValueFault"] = reflect.TypeOf((*OvfInvalidValueFault)(nil)).Elem() +} + +type OvfInvalidValueFormatMalformed struct { + OvfInvalidValue +} + +func init() { + t["OvfInvalidValueFormatMalformed"] = reflect.TypeOf((*OvfInvalidValueFormatMalformed)(nil)).Elem() +} + +type OvfInvalidValueFormatMalformedFault OvfInvalidValueFormatMalformed + +func init() { + t["OvfInvalidValueFormatMalformedFault"] = reflect.TypeOf((*OvfInvalidValueFormatMalformedFault)(nil)).Elem() +} + +type OvfInvalidValueReference struct { + OvfInvalidValue +} + +func init() { + t["OvfInvalidValueReference"] = reflect.TypeOf((*OvfInvalidValueReference)(nil)).Elem() +} + +type OvfInvalidValueReferenceFault OvfInvalidValueReference + +func init() { + t["OvfInvalidValueReferenceFault"] = reflect.TypeOf((*OvfInvalidValueReferenceFault)(nil)).Elem() +} + +type OvfInvalidVmName struct { + OvfUnsupportedPackage + + Name string `xml:"name"` +} + +func init() { + t["OvfInvalidVmName"] = reflect.TypeOf((*OvfInvalidVmName)(nil)).Elem() +} + +type OvfInvalidVmNameFault OvfInvalidVmName + +func init() { + t["OvfInvalidVmNameFault"] = reflect.TypeOf((*OvfInvalidVmNameFault)(nil)).Elem() +} + +type OvfManagerCommonParams struct { + DynamicData + + Locale string `xml:"locale"` + DeploymentOption string `xml:"deploymentOption"` + MsgBundle []KeyValue `xml:"msgBundle,omitempty"` + ImportOption []string `xml:"importOption,omitempty"` +} + +func init() { + t["OvfManagerCommonParams"] = reflect.TypeOf((*OvfManagerCommonParams)(nil)).Elem() +} + +type OvfMappedOsId struct { + OvfImport + + OvfId int32 `xml:"ovfId"` + OvfDescription string `xml:"ovfDescription"` + TargetDescription string `xml:"targetDescription"` +} + +func init() { + t["OvfMappedOsId"] = reflect.TypeOf((*OvfMappedOsId)(nil)).Elem() +} + +type OvfMappedOsIdFault OvfMappedOsId + +func init() { + t["OvfMappedOsIdFault"] = reflect.TypeOf((*OvfMappedOsIdFault)(nil)).Elem() +} + +type OvfMissingAttribute struct { + OvfAttribute +} + +func init() { + t["OvfMissingAttribute"] = reflect.TypeOf((*OvfMissingAttribute)(nil)).Elem() +} + +type OvfMissingAttributeFault OvfMissingAttribute + +func init() { + t["OvfMissingAttributeFault"] = reflect.TypeOf((*OvfMissingAttributeFault)(nil)).Elem() +} + +type OvfMissingElement struct { + OvfElement +} + +func init() { + t["OvfMissingElement"] = reflect.TypeOf((*OvfMissingElement)(nil)).Elem() +} + +type OvfMissingElementFault BaseOvfMissingElement + +func init() { + t["OvfMissingElementFault"] = reflect.TypeOf((*OvfMissingElementFault)(nil)).Elem() +} + +type OvfMissingElementNormalBoundary struct { + OvfMissingElement + + Boundary string `xml:"boundary"` +} + +func init() { + t["OvfMissingElementNormalBoundary"] = reflect.TypeOf((*OvfMissingElementNormalBoundary)(nil)).Elem() +} + +type OvfMissingElementNormalBoundaryFault OvfMissingElementNormalBoundary + +func init() { + t["OvfMissingElementNormalBoundaryFault"] = reflect.TypeOf((*OvfMissingElementNormalBoundaryFault)(nil)).Elem() +} + +type OvfMissingHardware struct { + OvfImport + + Name string `xml:"name"` + ResourceType int32 `xml:"resourceType"` +} + +func init() { + t["OvfMissingHardware"] = reflect.TypeOf((*OvfMissingHardware)(nil)).Elem() +} + +type OvfMissingHardwareFault OvfMissingHardware + +func init() { + t["OvfMissingHardwareFault"] = reflect.TypeOf((*OvfMissingHardwareFault)(nil)).Elem() +} + +type OvfNetworkInfo struct { + DynamicData + + Name string `xml:"name"` + Description string `xml:"description"` +} + +func init() { + t["OvfNetworkInfo"] = reflect.TypeOf((*OvfNetworkInfo)(nil)).Elem() +} + +type OvfNetworkMapping struct { + DynamicData + + Name string `xml:"name"` + Network ManagedObjectReference `xml:"network"` +} + +func init() { + t["OvfNetworkMapping"] = reflect.TypeOf((*OvfNetworkMapping)(nil)).Elem() +} + +type OvfNetworkMappingNotSupported struct { + OvfImport +} + +func init() { + t["OvfNetworkMappingNotSupported"] = reflect.TypeOf((*OvfNetworkMappingNotSupported)(nil)).Elem() +} + +type OvfNetworkMappingNotSupportedFault OvfNetworkMappingNotSupported + +func init() { + t["OvfNetworkMappingNotSupportedFault"] = reflect.TypeOf((*OvfNetworkMappingNotSupportedFault)(nil)).Elem() +} + +type OvfNoHostNic struct { + OvfUnsupportedPackage +} + +func init() { + t["OvfNoHostNic"] = reflect.TypeOf((*OvfNoHostNic)(nil)).Elem() +} + +type OvfNoHostNicFault OvfNoHostNic + +func init() { + t["OvfNoHostNicFault"] = reflect.TypeOf((*OvfNoHostNicFault)(nil)).Elem() +} + +type OvfNoSpaceOnController struct { + OvfUnsupportedElement + + Parent string `xml:"parent"` +} + +func init() { + t["OvfNoSpaceOnController"] = reflect.TypeOf((*OvfNoSpaceOnController)(nil)).Elem() +} + +type OvfNoSpaceOnControllerFault OvfNoSpaceOnController + +func init() { + t["OvfNoSpaceOnControllerFault"] = reflect.TypeOf((*OvfNoSpaceOnControllerFault)(nil)).Elem() +} + +type OvfNoSupportedHardwareFamily struct { + OvfUnsupportedPackage + + Version string `xml:"version"` +} + +func init() { + t["OvfNoSupportedHardwareFamily"] = reflect.TypeOf((*OvfNoSupportedHardwareFamily)(nil)).Elem() +} + +type OvfNoSupportedHardwareFamilyFault OvfNoSupportedHardwareFamily + +func init() { + t["OvfNoSupportedHardwareFamilyFault"] = reflect.TypeOf((*OvfNoSupportedHardwareFamilyFault)(nil)).Elem() +} + +type OvfOptionInfo struct { + DynamicData + + Option string `xml:"option"` + Description LocalizableMessage `xml:"description"` +} + +func init() { + t["OvfOptionInfo"] = reflect.TypeOf((*OvfOptionInfo)(nil)).Elem() +} + +type OvfParseDescriptorParams struct { + OvfManagerCommonParams +} + +func init() { + t["OvfParseDescriptorParams"] = reflect.TypeOf((*OvfParseDescriptorParams)(nil)).Elem() +} + +type OvfParseDescriptorResult struct { + DynamicData + + Eula []string `xml:"eula,omitempty"` + Network []OvfNetworkInfo `xml:"network,omitempty"` + IpAllocationScheme []string `xml:"ipAllocationScheme,omitempty"` + IpProtocols []string `xml:"ipProtocols,omitempty"` + Property []VAppPropertyInfo `xml:"property,omitempty"` + ProductInfo *VAppProductInfo `xml:"productInfo,omitempty"` + Annotation string `xml:"annotation"` + ApproximateDownloadSize int64 `xml:"approximateDownloadSize,omitempty"` + ApproximateFlatDeploymentSize int64 `xml:"approximateFlatDeploymentSize,omitempty"` + ApproximateSparseDeploymentSize int64 `xml:"approximateSparseDeploymentSize,omitempty"` + DefaultEntityName string `xml:"defaultEntityName"` + VirtualApp bool `xml:"virtualApp"` + DeploymentOption []OvfDeploymentOption `xml:"deploymentOption,omitempty"` + DefaultDeploymentOption string `xml:"defaultDeploymentOption"` + EntityName []KeyValue `xml:"entityName,omitempty"` + AnnotatedOst *OvfConsumerOstNode `xml:"annotatedOst,omitempty"` + Error []LocalizedMethodFault `xml:"error,omitempty"` + Warning []LocalizedMethodFault `xml:"warning,omitempty"` +} + +func init() { + t["OvfParseDescriptorResult"] = reflect.TypeOf((*OvfParseDescriptorResult)(nil)).Elem() +} + +type OvfProperty struct { + OvfInvalidPackage + + Type string `xml:"type"` + Value string `xml:"value"` +} + +func init() { + t["OvfProperty"] = reflect.TypeOf((*OvfProperty)(nil)).Elem() +} + +type OvfPropertyExport struct { + OvfExport + + Type string `xml:"type"` + Value string `xml:"value"` +} + +func init() { + t["OvfPropertyExport"] = reflect.TypeOf((*OvfPropertyExport)(nil)).Elem() +} + +type OvfPropertyExportFault OvfPropertyExport + +func init() { + t["OvfPropertyExportFault"] = reflect.TypeOf((*OvfPropertyExportFault)(nil)).Elem() +} + +type OvfPropertyFault BaseOvfProperty + +func init() { + t["OvfPropertyFault"] = reflect.TypeOf((*OvfPropertyFault)(nil)).Elem() +} + +type OvfPropertyNetwork struct { + OvfProperty +} + +func init() { + t["OvfPropertyNetwork"] = reflect.TypeOf((*OvfPropertyNetwork)(nil)).Elem() +} + +type OvfPropertyNetworkExport struct { + OvfExport + + Network string `xml:"network"` +} + +func init() { + t["OvfPropertyNetworkExport"] = reflect.TypeOf((*OvfPropertyNetworkExport)(nil)).Elem() +} + +type OvfPropertyNetworkExportFault OvfPropertyNetworkExport + +func init() { + t["OvfPropertyNetworkExportFault"] = reflect.TypeOf((*OvfPropertyNetworkExportFault)(nil)).Elem() +} + +type OvfPropertyNetworkFault OvfPropertyNetwork + +func init() { + t["OvfPropertyNetworkFault"] = reflect.TypeOf((*OvfPropertyNetworkFault)(nil)).Elem() +} + +type OvfPropertyQualifier struct { + OvfProperty + + Qualifier string `xml:"qualifier"` +} + +func init() { + t["OvfPropertyQualifier"] = reflect.TypeOf((*OvfPropertyQualifier)(nil)).Elem() +} + +type OvfPropertyQualifierDuplicate struct { + OvfProperty + + Qualifier string `xml:"qualifier"` +} + +func init() { + t["OvfPropertyQualifierDuplicate"] = reflect.TypeOf((*OvfPropertyQualifierDuplicate)(nil)).Elem() +} + +type OvfPropertyQualifierDuplicateFault OvfPropertyQualifierDuplicate + +func init() { + t["OvfPropertyQualifierDuplicateFault"] = reflect.TypeOf((*OvfPropertyQualifierDuplicateFault)(nil)).Elem() +} + +type OvfPropertyQualifierFault OvfPropertyQualifier + +func init() { + t["OvfPropertyQualifierFault"] = reflect.TypeOf((*OvfPropertyQualifierFault)(nil)).Elem() +} + +type OvfPropertyQualifierIgnored struct { + OvfProperty + + Qualifier string `xml:"qualifier"` +} + +func init() { + t["OvfPropertyQualifierIgnored"] = reflect.TypeOf((*OvfPropertyQualifierIgnored)(nil)).Elem() +} + +type OvfPropertyQualifierIgnoredFault OvfPropertyQualifierIgnored + +func init() { + t["OvfPropertyQualifierIgnoredFault"] = reflect.TypeOf((*OvfPropertyQualifierIgnoredFault)(nil)).Elem() +} + +type OvfPropertyType struct { + OvfProperty +} + +func init() { + t["OvfPropertyType"] = reflect.TypeOf((*OvfPropertyType)(nil)).Elem() +} + +type OvfPropertyTypeFault OvfPropertyType + +func init() { + t["OvfPropertyTypeFault"] = reflect.TypeOf((*OvfPropertyTypeFault)(nil)).Elem() +} + +type OvfPropertyValue struct { + OvfProperty +} + +func init() { + t["OvfPropertyValue"] = reflect.TypeOf((*OvfPropertyValue)(nil)).Elem() +} + +type OvfPropertyValueFault OvfPropertyValue + +func init() { + t["OvfPropertyValueFault"] = reflect.TypeOf((*OvfPropertyValueFault)(nil)).Elem() +} + +type OvfResourceMap struct { + DynamicData + + Source string `xml:"source"` + Parent *ManagedObjectReference `xml:"parent,omitempty"` + ResourceSpec *ResourceConfigSpec `xml:"resourceSpec,omitempty"` + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` +} + +func init() { + t["OvfResourceMap"] = reflect.TypeOf((*OvfResourceMap)(nil)).Elem() +} + +type OvfSystemFault struct { + OvfFault +} + +func init() { + t["OvfSystemFault"] = reflect.TypeOf((*OvfSystemFault)(nil)).Elem() +} + +type OvfSystemFaultFault BaseOvfSystemFault + +func init() { + t["OvfSystemFaultFault"] = reflect.TypeOf((*OvfSystemFaultFault)(nil)).Elem() +} + +type OvfToXmlUnsupportedElement struct { + OvfSystemFault + + Name string `xml:"name,omitempty"` +} + +func init() { + t["OvfToXmlUnsupportedElement"] = reflect.TypeOf((*OvfToXmlUnsupportedElement)(nil)).Elem() +} + +type OvfToXmlUnsupportedElementFault OvfToXmlUnsupportedElement + +func init() { + t["OvfToXmlUnsupportedElementFault"] = reflect.TypeOf((*OvfToXmlUnsupportedElementFault)(nil)).Elem() +} + +type OvfUnableToExportDisk struct { + OvfHardwareExport + + DiskName string `xml:"diskName"` +} + +func init() { + t["OvfUnableToExportDisk"] = reflect.TypeOf((*OvfUnableToExportDisk)(nil)).Elem() +} + +type OvfUnableToExportDiskFault OvfUnableToExportDisk + +func init() { + t["OvfUnableToExportDiskFault"] = reflect.TypeOf((*OvfUnableToExportDiskFault)(nil)).Elem() +} + +type OvfUnexpectedElement struct { + OvfElement +} + +func init() { + t["OvfUnexpectedElement"] = reflect.TypeOf((*OvfUnexpectedElement)(nil)).Elem() +} + +type OvfUnexpectedElementFault OvfUnexpectedElement + +func init() { + t["OvfUnexpectedElementFault"] = reflect.TypeOf((*OvfUnexpectedElementFault)(nil)).Elem() +} + +type OvfUnknownDevice struct { + OvfSystemFault + + Device BaseVirtualDevice `xml:"device,omitempty,typeattr"` + VmName string `xml:"vmName"` +} + +func init() { + t["OvfUnknownDevice"] = reflect.TypeOf((*OvfUnknownDevice)(nil)).Elem() +} + +type OvfUnknownDeviceBacking struct { + OvfHardwareExport + + Backing BaseVirtualDeviceBackingInfo `xml:"backing,typeattr"` +} + +func init() { + t["OvfUnknownDeviceBacking"] = reflect.TypeOf((*OvfUnknownDeviceBacking)(nil)).Elem() +} + +type OvfUnknownDeviceBackingFault OvfUnknownDeviceBacking + +func init() { + t["OvfUnknownDeviceBackingFault"] = reflect.TypeOf((*OvfUnknownDeviceBackingFault)(nil)).Elem() +} + +type OvfUnknownDeviceFault OvfUnknownDevice + +func init() { + t["OvfUnknownDeviceFault"] = reflect.TypeOf((*OvfUnknownDeviceFault)(nil)).Elem() +} + +type OvfUnknownEntity struct { + OvfSystemFault + + LineNumber int32 `xml:"lineNumber"` +} + +func init() { + t["OvfUnknownEntity"] = reflect.TypeOf((*OvfUnknownEntity)(nil)).Elem() +} + +type OvfUnknownEntityFault OvfUnknownEntity + +func init() { + t["OvfUnknownEntityFault"] = reflect.TypeOf((*OvfUnknownEntityFault)(nil)).Elem() +} + +type OvfUnsupportedAttribute struct { + OvfUnsupportedPackage + + ElementName string `xml:"elementName"` + AttributeName string `xml:"attributeName"` +} + +func init() { + t["OvfUnsupportedAttribute"] = reflect.TypeOf((*OvfUnsupportedAttribute)(nil)).Elem() +} + +type OvfUnsupportedAttributeFault BaseOvfUnsupportedAttribute + +func init() { + t["OvfUnsupportedAttributeFault"] = reflect.TypeOf((*OvfUnsupportedAttributeFault)(nil)).Elem() +} + +type OvfUnsupportedAttributeValue struct { + OvfUnsupportedAttribute + + Value string `xml:"value"` +} + +func init() { + t["OvfUnsupportedAttributeValue"] = reflect.TypeOf((*OvfUnsupportedAttributeValue)(nil)).Elem() +} + +type OvfUnsupportedAttributeValueFault OvfUnsupportedAttributeValue + +func init() { + t["OvfUnsupportedAttributeValueFault"] = reflect.TypeOf((*OvfUnsupportedAttributeValueFault)(nil)).Elem() +} + +type OvfUnsupportedDeviceBackingInfo struct { + OvfSystemFault + + ElementName string `xml:"elementName,omitempty"` + InstanceId string `xml:"instanceId,omitempty"` + DeviceName string `xml:"deviceName"` + BackingName string `xml:"backingName,omitempty"` +} + +func init() { + t["OvfUnsupportedDeviceBackingInfo"] = reflect.TypeOf((*OvfUnsupportedDeviceBackingInfo)(nil)).Elem() +} + +type OvfUnsupportedDeviceBackingInfoFault OvfUnsupportedDeviceBackingInfo + +func init() { + t["OvfUnsupportedDeviceBackingInfoFault"] = reflect.TypeOf((*OvfUnsupportedDeviceBackingInfoFault)(nil)).Elem() +} + +type OvfUnsupportedDeviceBackingOption struct { + OvfSystemFault + + ElementName string `xml:"elementName,omitempty"` + InstanceId string `xml:"instanceId,omitempty"` + DeviceName string `xml:"deviceName"` + BackingName string `xml:"backingName,omitempty"` +} + +func init() { + t["OvfUnsupportedDeviceBackingOption"] = reflect.TypeOf((*OvfUnsupportedDeviceBackingOption)(nil)).Elem() +} + +type OvfUnsupportedDeviceBackingOptionFault OvfUnsupportedDeviceBackingOption + +func init() { + t["OvfUnsupportedDeviceBackingOptionFault"] = reflect.TypeOf((*OvfUnsupportedDeviceBackingOptionFault)(nil)).Elem() +} + +type OvfUnsupportedDeviceExport struct { + OvfHardwareExport +} + +func init() { + t["OvfUnsupportedDeviceExport"] = reflect.TypeOf((*OvfUnsupportedDeviceExport)(nil)).Elem() +} + +type OvfUnsupportedDeviceExportFault OvfUnsupportedDeviceExport + +func init() { + t["OvfUnsupportedDeviceExportFault"] = reflect.TypeOf((*OvfUnsupportedDeviceExportFault)(nil)).Elem() +} + +type OvfUnsupportedDiskProvisioning struct { + OvfImport + + DiskProvisioning string `xml:"diskProvisioning"` + SupportedDiskProvisioning string `xml:"supportedDiskProvisioning"` +} + +func init() { + t["OvfUnsupportedDiskProvisioning"] = reflect.TypeOf((*OvfUnsupportedDiskProvisioning)(nil)).Elem() +} + +type OvfUnsupportedDiskProvisioningFault OvfUnsupportedDiskProvisioning + +func init() { + t["OvfUnsupportedDiskProvisioningFault"] = reflect.TypeOf((*OvfUnsupportedDiskProvisioningFault)(nil)).Elem() +} + +type OvfUnsupportedElement struct { + OvfUnsupportedPackage + + Name string `xml:"name"` +} + +func init() { + t["OvfUnsupportedElement"] = reflect.TypeOf((*OvfUnsupportedElement)(nil)).Elem() +} + +type OvfUnsupportedElementFault BaseOvfUnsupportedElement + +func init() { + t["OvfUnsupportedElementFault"] = reflect.TypeOf((*OvfUnsupportedElementFault)(nil)).Elem() +} + +type OvfUnsupportedElementValue struct { + OvfUnsupportedElement + + Value string `xml:"value"` +} + +func init() { + t["OvfUnsupportedElementValue"] = reflect.TypeOf((*OvfUnsupportedElementValue)(nil)).Elem() +} + +type OvfUnsupportedElementValueFault OvfUnsupportedElementValue + +func init() { + t["OvfUnsupportedElementValueFault"] = reflect.TypeOf((*OvfUnsupportedElementValueFault)(nil)).Elem() +} + +type OvfUnsupportedPackage struct { + OvfFault + + LineNumber int32 `xml:"lineNumber,omitempty"` +} + +func init() { + t["OvfUnsupportedPackage"] = reflect.TypeOf((*OvfUnsupportedPackage)(nil)).Elem() +} + +type OvfUnsupportedPackageFault BaseOvfUnsupportedPackage + +func init() { + t["OvfUnsupportedPackageFault"] = reflect.TypeOf((*OvfUnsupportedPackageFault)(nil)).Elem() +} + +type OvfUnsupportedSection struct { + OvfUnsupportedElement + + Info string `xml:"info"` +} + +func init() { + t["OvfUnsupportedSection"] = reflect.TypeOf((*OvfUnsupportedSection)(nil)).Elem() +} + +type OvfUnsupportedSectionFault OvfUnsupportedSection + +func init() { + t["OvfUnsupportedSectionFault"] = reflect.TypeOf((*OvfUnsupportedSectionFault)(nil)).Elem() +} + +type OvfUnsupportedSubType struct { + OvfUnsupportedPackage + + ElementName string `xml:"elementName"` + InstanceId string `xml:"instanceId"` + DeviceType int32 `xml:"deviceType"` + DeviceSubType string `xml:"deviceSubType"` +} + +func init() { + t["OvfUnsupportedSubType"] = reflect.TypeOf((*OvfUnsupportedSubType)(nil)).Elem() +} + +type OvfUnsupportedSubTypeFault OvfUnsupportedSubType + +func init() { + t["OvfUnsupportedSubTypeFault"] = reflect.TypeOf((*OvfUnsupportedSubTypeFault)(nil)).Elem() +} + +type OvfUnsupportedType struct { + OvfUnsupportedPackage + + Name string `xml:"name"` + InstanceId string `xml:"instanceId"` + DeviceType int32 `xml:"deviceType"` +} + +func init() { + t["OvfUnsupportedType"] = reflect.TypeOf((*OvfUnsupportedType)(nil)).Elem() +} + +type OvfUnsupportedTypeFault OvfUnsupportedType + +func init() { + t["OvfUnsupportedTypeFault"] = reflect.TypeOf((*OvfUnsupportedTypeFault)(nil)).Elem() +} + +type OvfValidateHostParams struct { + OvfManagerCommonParams +} + +func init() { + t["OvfValidateHostParams"] = reflect.TypeOf((*OvfValidateHostParams)(nil)).Elem() +} + +type OvfValidateHostResult struct { + DynamicData + + DownloadSize int64 `xml:"downloadSize,omitempty"` + FlatDeploymentSize int64 `xml:"flatDeploymentSize,omitempty"` + SparseDeploymentSize int64 `xml:"sparseDeploymentSize,omitempty"` + Error []LocalizedMethodFault `xml:"error,omitempty"` + Warning []LocalizedMethodFault `xml:"warning,omitempty"` + SupportedDiskProvisioning []string `xml:"supportedDiskProvisioning,omitempty"` +} + +func init() { + t["OvfValidateHostResult"] = reflect.TypeOf((*OvfValidateHostResult)(nil)).Elem() +} + +type OvfWrongElement struct { + OvfElement +} + +func init() { + t["OvfWrongElement"] = reflect.TypeOf((*OvfWrongElement)(nil)).Elem() +} + +type OvfWrongElementFault OvfWrongElement + +func init() { + t["OvfWrongElementFault"] = reflect.TypeOf((*OvfWrongElementFault)(nil)).Elem() +} + +type OvfWrongNamespace struct { + OvfInvalidPackage + + NamespaceName string `xml:"namespaceName"` +} + +func init() { + t["OvfWrongNamespace"] = reflect.TypeOf((*OvfWrongNamespace)(nil)).Elem() +} + +type OvfWrongNamespaceFault OvfWrongNamespace + +func init() { + t["OvfWrongNamespaceFault"] = reflect.TypeOf((*OvfWrongNamespaceFault)(nil)).Elem() +} + +type OvfXmlFormat struct { + OvfInvalidPackage + + Description string `xml:"description"` +} + +func init() { + t["OvfXmlFormat"] = reflect.TypeOf((*OvfXmlFormat)(nil)).Elem() +} + +type OvfXmlFormatFault OvfXmlFormat + +func init() { + t["OvfXmlFormatFault"] = reflect.TypeOf((*OvfXmlFormatFault)(nil)).Elem() +} + +type ParaVirtualSCSIController struct { + VirtualSCSIController +} + +func init() { + t["ParaVirtualSCSIController"] = reflect.TypeOf((*ParaVirtualSCSIController)(nil)).Elem() +} + +type ParaVirtualSCSIControllerOption struct { + VirtualSCSIControllerOption +} + +func init() { + t["ParaVirtualSCSIControllerOption"] = reflect.TypeOf((*ParaVirtualSCSIControllerOption)(nil)).Elem() +} + +type ParseDescriptor ParseDescriptorRequestType + +func init() { + t["ParseDescriptor"] = reflect.TypeOf((*ParseDescriptor)(nil)).Elem() +} + +type ParseDescriptorRequestType struct { + This ManagedObjectReference `xml:"_this"` + OvfDescriptor string `xml:"ovfDescriptor"` + Pdp OvfParseDescriptorParams `xml:"pdp"` +} + +func init() { + t["ParseDescriptorRequestType"] = reflect.TypeOf((*ParseDescriptorRequestType)(nil)).Elem() +} + +type ParseDescriptorResponse struct { + Returnval OvfParseDescriptorResult `xml:"returnval"` +} + +type PasswordField struct { + DynamicData + + Value string `xml:"value"` +} + +func init() { + t["PasswordField"] = reflect.TypeOf((*PasswordField)(nil)).Elem() +} + +type PatchAlreadyInstalled struct { + PatchNotApplicable +} + +func init() { + t["PatchAlreadyInstalled"] = reflect.TypeOf((*PatchAlreadyInstalled)(nil)).Elem() +} + +type PatchAlreadyInstalledFault PatchAlreadyInstalled + +func init() { + t["PatchAlreadyInstalledFault"] = reflect.TypeOf((*PatchAlreadyInstalledFault)(nil)).Elem() +} + +type PatchBinariesNotFound struct { + VimFault + + PatchID string `xml:"patchID"` + Binary []string `xml:"binary,omitempty"` +} + +func init() { + t["PatchBinariesNotFound"] = reflect.TypeOf((*PatchBinariesNotFound)(nil)).Elem() +} + +type PatchBinariesNotFoundFault PatchBinariesNotFound + +func init() { + t["PatchBinariesNotFoundFault"] = reflect.TypeOf((*PatchBinariesNotFoundFault)(nil)).Elem() +} + +type PatchInstallFailed struct { + PlatformConfigFault + + RolledBack bool `xml:"rolledBack"` +} + +func init() { + t["PatchInstallFailed"] = reflect.TypeOf((*PatchInstallFailed)(nil)).Elem() +} + +type PatchInstallFailedFault PatchInstallFailed + +func init() { + t["PatchInstallFailedFault"] = reflect.TypeOf((*PatchInstallFailedFault)(nil)).Elem() +} + +type PatchIntegrityError struct { + PlatformConfigFault +} + +func init() { + t["PatchIntegrityError"] = reflect.TypeOf((*PatchIntegrityError)(nil)).Elem() +} + +type PatchIntegrityErrorFault PatchIntegrityError + +func init() { + t["PatchIntegrityErrorFault"] = reflect.TypeOf((*PatchIntegrityErrorFault)(nil)).Elem() +} + +type PatchMetadataCorrupted struct { + PatchMetadataInvalid +} + +func init() { + t["PatchMetadataCorrupted"] = reflect.TypeOf((*PatchMetadataCorrupted)(nil)).Elem() +} + +type PatchMetadataCorruptedFault PatchMetadataCorrupted + +func init() { + t["PatchMetadataCorruptedFault"] = reflect.TypeOf((*PatchMetadataCorruptedFault)(nil)).Elem() +} + +type PatchMetadataInvalid struct { + VimFault + + PatchID string `xml:"patchID"` + MetaData []string `xml:"metaData,omitempty"` +} + +func init() { + t["PatchMetadataInvalid"] = reflect.TypeOf((*PatchMetadataInvalid)(nil)).Elem() +} + +type PatchMetadataInvalidFault BasePatchMetadataInvalid + +func init() { + t["PatchMetadataInvalidFault"] = reflect.TypeOf((*PatchMetadataInvalidFault)(nil)).Elem() +} + +type PatchMetadataNotFound struct { + PatchMetadataInvalid +} + +func init() { + t["PatchMetadataNotFound"] = reflect.TypeOf((*PatchMetadataNotFound)(nil)).Elem() +} + +type PatchMetadataNotFoundFault PatchMetadataNotFound + +func init() { + t["PatchMetadataNotFoundFault"] = reflect.TypeOf((*PatchMetadataNotFoundFault)(nil)).Elem() +} + +type PatchMissingDependencies struct { + PatchNotApplicable + + PrerequisitePatch []string `xml:"prerequisitePatch,omitempty"` + PrerequisiteLib []string `xml:"prerequisiteLib,omitempty"` +} + +func init() { + t["PatchMissingDependencies"] = reflect.TypeOf((*PatchMissingDependencies)(nil)).Elem() +} + +type PatchMissingDependenciesFault PatchMissingDependencies + +func init() { + t["PatchMissingDependenciesFault"] = reflect.TypeOf((*PatchMissingDependenciesFault)(nil)).Elem() +} + +type PatchNotApplicable struct { + VimFault + + PatchID string `xml:"patchID"` +} + +func init() { + t["PatchNotApplicable"] = reflect.TypeOf((*PatchNotApplicable)(nil)).Elem() +} + +type PatchNotApplicableFault BasePatchNotApplicable + +func init() { + t["PatchNotApplicableFault"] = reflect.TypeOf((*PatchNotApplicableFault)(nil)).Elem() +} + +type PatchSuperseded struct { + PatchNotApplicable + + Supersede []string `xml:"supersede,omitempty"` +} + +func init() { + t["PatchSuperseded"] = reflect.TypeOf((*PatchSuperseded)(nil)).Elem() +} + +type PatchSupersededFault PatchSuperseded + +func init() { + t["PatchSupersededFault"] = reflect.TypeOf((*PatchSupersededFault)(nil)).Elem() +} + +type PerfCompositeMetric struct { + DynamicData + + Entity BasePerfEntityMetricBase `xml:"entity,omitempty,typeattr"` + ChildEntity []BasePerfEntityMetricBase `xml:"childEntity,omitempty,typeattr"` +} + +func init() { + t["PerfCompositeMetric"] = reflect.TypeOf((*PerfCompositeMetric)(nil)).Elem() +} + +type PerfCounterInfo struct { + DynamicData + + Key int32 `xml:"key"` + NameInfo BaseElementDescription `xml:"nameInfo,typeattr"` + GroupInfo BaseElementDescription `xml:"groupInfo,typeattr"` + UnitInfo BaseElementDescription `xml:"unitInfo,typeattr"` + RollupType PerfSummaryType `xml:"rollupType"` + StatsType PerfStatsType `xml:"statsType"` + Level int32 `xml:"level,omitempty"` + PerDeviceLevel int32 `xml:"perDeviceLevel,omitempty"` + AssociatedCounterId []int32 `xml:"associatedCounterId,omitempty"` +} + +func init() { + t["PerfCounterInfo"] = reflect.TypeOf((*PerfCounterInfo)(nil)).Elem() +} + +type PerfEntityMetric struct { + PerfEntityMetricBase + + SampleInfo []PerfSampleInfo `xml:"sampleInfo,omitempty"` + Value []BasePerfMetricSeries `xml:"value,omitempty,typeattr"` +} + +func init() { + t["PerfEntityMetric"] = reflect.TypeOf((*PerfEntityMetric)(nil)).Elem() +} + +type PerfEntityMetricBase struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["PerfEntityMetricBase"] = reflect.TypeOf((*PerfEntityMetricBase)(nil)).Elem() +} + +type PerfEntityMetricCSV struct { + PerfEntityMetricBase + + SampleInfoCSV string `xml:"sampleInfoCSV"` + Value []PerfMetricSeriesCSV `xml:"value,omitempty"` +} + +func init() { + t["PerfEntityMetricCSV"] = reflect.TypeOf((*PerfEntityMetricCSV)(nil)).Elem() +} + +type PerfInterval struct { + DynamicData + + Key int32 `xml:"key"` + SamplingPeriod int32 `xml:"samplingPeriod"` + Name string `xml:"name"` + Length int32 `xml:"length"` + Level int32 `xml:"level,omitempty"` + Enabled bool `xml:"enabled"` +} + +func init() { + t["PerfInterval"] = reflect.TypeOf((*PerfInterval)(nil)).Elem() +} + +type PerfMetricId struct { + DynamicData + + CounterId int32 `xml:"counterId"` + Instance string `xml:"instance"` +} + +func init() { + t["PerfMetricId"] = reflect.TypeOf((*PerfMetricId)(nil)).Elem() +} + +type PerfMetricIntSeries struct { + PerfMetricSeries + + Value []int64 `xml:"value,omitempty"` +} + +func init() { + t["PerfMetricIntSeries"] = reflect.TypeOf((*PerfMetricIntSeries)(nil)).Elem() +} + +type PerfMetricSeries struct { + DynamicData + + Id PerfMetricId `xml:"id"` +} + +func init() { + t["PerfMetricSeries"] = reflect.TypeOf((*PerfMetricSeries)(nil)).Elem() +} + +type PerfMetricSeriesCSV struct { + PerfMetricSeries + + Value string `xml:"value,omitempty"` +} + +func init() { + t["PerfMetricSeriesCSV"] = reflect.TypeOf((*PerfMetricSeriesCSV)(nil)).Elem() +} + +type PerfProviderSummary struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` + CurrentSupported bool `xml:"currentSupported"` + SummarySupported bool `xml:"summarySupported"` + RefreshRate int32 `xml:"refreshRate,omitempty"` +} + +func init() { + t["PerfProviderSummary"] = reflect.TypeOf((*PerfProviderSummary)(nil)).Elem() +} + +type PerfQuerySpec struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` + StartTime *time.Time `xml:"startTime"` + EndTime *time.Time `xml:"endTime"` + MaxSample int32 `xml:"maxSample,omitempty"` + MetricId []PerfMetricId `xml:"metricId,omitempty"` + IntervalId int32 `xml:"intervalId,omitempty"` + Format string `xml:"format,omitempty"` +} + +func init() { + t["PerfQuerySpec"] = reflect.TypeOf((*PerfQuerySpec)(nil)).Elem() +} + +type PerfSampleInfo struct { + DynamicData + + Timestamp time.Time `xml:"timestamp"` + Interval int32 `xml:"interval"` +} + +func init() { + t["PerfSampleInfo"] = reflect.TypeOf((*PerfSampleInfo)(nil)).Elem() +} + +type PerformDvsProductSpecOperationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Operation string `xml:"operation"` + ProductSpec *DistributedVirtualSwitchProductSpec `xml:"productSpec,omitempty"` +} + +func init() { + t["PerformDvsProductSpecOperationRequestType"] = reflect.TypeOf((*PerformDvsProductSpecOperationRequestType)(nil)).Elem() +} + +type PerformDvsProductSpecOperation_Task PerformDvsProductSpecOperationRequestType + +func init() { + t["PerformDvsProductSpecOperation_Task"] = reflect.TypeOf((*PerformDvsProductSpecOperation_Task)(nil)).Elem() +} + +type PerformDvsProductSpecOperation_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PerformVsanUpgradePreflightCheck PerformVsanUpgradePreflightCheckRequestType + +func init() { + t["PerformVsanUpgradePreflightCheck"] = reflect.TypeOf((*PerformVsanUpgradePreflightCheck)(nil)).Elem() +} + +type PerformVsanUpgradePreflightCheckRequestType struct { + This ManagedObjectReference `xml:"_this"` + Cluster ManagedObjectReference `xml:"cluster"` + DowngradeFormat *bool `xml:"downgradeFormat"` +} + +func init() { + t["PerformVsanUpgradePreflightCheckRequestType"] = reflect.TypeOf((*PerformVsanUpgradePreflightCheckRequestType)(nil)).Elem() +} + +type PerformVsanUpgradePreflightCheckResponse struct { + Returnval VsanUpgradeSystemPreflightCheckResult `xml:"returnval"` +} + +type PerformVsanUpgradeRequestType struct { + This ManagedObjectReference `xml:"_this"` + Cluster ManagedObjectReference `xml:"cluster"` + PerformObjectUpgrade *bool `xml:"performObjectUpgrade"` + DowngradeFormat *bool `xml:"downgradeFormat"` + AllowReducedRedundancy *bool `xml:"allowReducedRedundancy"` + ExcludeHosts []ManagedObjectReference `xml:"excludeHosts,omitempty"` +} + +func init() { + t["PerformVsanUpgradeRequestType"] = reflect.TypeOf((*PerformVsanUpgradeRequestType)(nil)).Elem() +} + +type PerformVsanUpgrade_Task PerformVsanUpgradeRequestType + +func init() { + t["PerformVsanUpgrade_Task"] = reflect.TypeOf((*PerformVsanUpgrade_Task)(nil)).Elem() +} + +type PerformVsanUpgrade_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PerformanceDescription struct { + DynamicData + + CounterType []BaseElementDescription `xml:"counterType,typeattr"` + StatsType []BaseElementDescription `xml:"statsType,typeattr"` +} + +func init() { + t["PerformanceDescription"] = reflect.TypeOf((*PerformanceDescription)(nil)).Elem() +} + +type PerformanceManagerCounterLevelMapping struct { + DynamicData + + CounterId int32 `xml:"counterId"` + AggregateLevel int32 `xml:"aggregateLevel,omitempty"` + PerDeviceLevel int32 `xml:"perDeviceLevel,omitempty"` +} + +func init() { + t["PerformanceManagerCounterLevelMapping"] = reflect.TypeOf((*PerformanceManagerCounterLevelMapping)(nil)).Elem() +} + +type PerformanceStatisticsDescription struct { + DynamicData + + Intervals []PerfInterval `xml:"intervals,omitempty"` +} + +func init() { + t["PerformanceStatisticsDescription"] = reflect.TypeOf((*PerformanceStatisticsDescription)(nil)).Elem() +} + +type Permission struct { + DynamicData + + Entity *ManagedObjectReference `xml:"entity,omitempty"` + Principal string `xml:"principal"` + Group bool `xml:"group"` + RoleId int32 `xml:"roleId"` + Propagate bool `xml:"propagate"` +} + +func init() { + t["Permission"] = reflect.TypeOf((*Permission)(nil)).Elem() +} + +type PermissionAddedEvent struct { + PermissionEvent + + Role RoleEventArgument `xml:"role"` + Propagate bool `xml:"propagate"` +} + +func init() { + t["PermissionAddedEvent"] = reflect.TypeOf((*PermissionAddedEvent)(nil)).Elem() +} + +type PermissionEvent struct { + AuthorizationEvent + + Entity ManagedEntityEventArgument `xml:"entity"` + Principal string `xml:"principal"` + Group bool `xml:"group"` +} + +func init() { + t["PermissionEvent"] = reflect.TypeOf((*PermissionEvent)(nil)).Elem() +} + +type PermissionProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["PermissionProfile"] = reflect.TypeOf((*PermissionProfile)(nil)).Elem() +} + +type PermissionRemovedEvent struct { + PermissionEvent +} + +func init() { + t["PermissionRemovedEvent"] = reflect.TypeOf((*PermissionRemovedEvent)(nil)).Elem() +} + +type PermissionUpdatedEvent struct { + PermissionEvent + + Role RoleEventArgument `xml:"role"` + Propagate bool `xml:"propagate"` +} + +func init() { + t["PermissionUpdatedEvent"] = reflect.TypeOf((*PermissionUpdatedEvent)(nil)).Elem() +} + +type PhysCompatRDMNotSupported struct { + RDMNotSupported +} + +func init() { + t["PhysCompatRDMNotSupported"] = reflect.TypeOf((*PhysCompatRDMNotSupported)(nil)).Elem() +} + +type PhysCompatRDMNotSupportedFault PhysCompatRDMNotSupported + +func init() { + t["PhysCompatRDMNotSupportedFault"] = reflect.TypeOf((*PhysCompatRDMNotSupportedFault)(nil)).Elem() +} + +type PhysicalNic struct { + DynamicData + + Key string `xml:"key,omitempty"` + Device string `xml:"device"` + Pci string `xml:"pci"` + Driver string `xml:"driver,omitempty"` + LinkSpeed *PhysicalNicLinkInfo `xml:"linkSpeed,omitempty"` + ValidLinkSpecification []PhysicalNicLinkInfo `xml:"validLinkSpecification,omitempty"` + Spec PhysicalNicSpec `xml:"spec"` + WakeOnLanSupported bool `xml:"wakeOnLanSupported"` + Mac string `xml:"mac"` + FcoeConfiguration *FcoeConfig `xml:"fcoeConfiguration,omitempty"` + VmDirectPathGen2Supported *bool `xml:"vmDirectPathGen2Supported"` + VmDirectPathGen2SupportedMode string `xml:"vmDirectPathGen2SupportedMode,omitempty"` + ResourcePoolSchedulerAllowed *bool `xml:"resourcePoolSchedulerAllowed"` + ResourcePoolSchedulerDisallowedReason []string `xml:"resourcePoolSchedulerDisallowedReason,omitempty"` + AutoNegotiateSupported *bool `xml:"autoNegotiateSupported"` +} + +func init() { + t["PhysicalNic"] = reflect.TypeOf((*PhysicalNic)(nil)).Elem() +} + +type PhysicalNicCdpDeviceCapability struct { + DynamicData + + Router bool `xml:"router"` + TransparentBridge bool `xml:"transparentBridge"` + SourceRouteBridge bool `xml:"sourceRouteBridge"` + NetworkSwitch bool `xml:"networkSwitch"` + Host bool `xml:"host"` + IgmpEnabled bool `xml:"igmpEnabled"` + Repeater bool `xml:"repeater"` +} + +func init() { + t["PhysicalNicCdpDeviceCapability"] = reflect.TypeOf((*PhysicalNicCdpDeviceCapability)(nil)).Elem() +} + +type PhysicalNicCdpInfo struct { + DynamicData + + CdpVersion int32 `xml:"cdpVersion,omitempty"` + Timeout int32 `xml:"timeout,omitempty"` + Ttl int32 `xml:"ttl,omitempty"` + Samples int32 `xml:"samples,omitempty"` + DevId string `xml:"devId,omitempty"` + Address string `xml:"address,omitempty"` + PortId string `xml:"portId,omitempty"` + DeviceCapability *PhysicalNicCdpDeviceCapability `xml:"deviceCapability,omitempty"` + SoftwareVersion string `xml:"softwareVersion,omitempty"` + HardwarePlatform string `xml:"hardwarePlatform,omitempty"` + IpPrefix string `xml:"ipPrefix,omitempty"` + IpPrefixLen int32 `xml:"ipPrefixLen,omitempty"` + Vlan int32 `xml:"vlan,omitempty"` + FullDuplex *bool `xml:"fullDuplex"` + Mtu int32 `xml:"mtu,omitempty"` + SystemName string `xml:"systemName,omitempty"` + SystemOID string `xml:"systemOID,omitempty"` + MgmtAddr string `xml:"mgmtAddr,omitempty"` + Location string `xml:"location,omitempty"` +} + +func init() { + t["PhysicalNicCdpInfo"] = reflect.TypeOf((*PhysicalNicCdpInfo)(nil)).Elem() +} + +type PhysicalNicConfig struct { + DynamicData + + Device string `xml:"device"` + Spec PhysicalNicSpec `xml:"spec"` +} + +func init() { + t["PhysicalNicConfig"] = reflect.TypeOf((*PhysicalNicConfig)(nil)).Elem() +} + +type PhysicalNicHint struct { + DynamicData + + VlanId int32 `xml:"vlanId,omitempty"` +} + +func init() { + t["PhysicalNicHint"] = reflect.TypeOf((*PhysicalNicHint)(nil)).Elem() +} + +type PhysicalNicHintInfo struct { + DynamicData + + Device string `xml:"device"` + Subnet []PhysicalNicIpHint `xml:"subnet,omitempty"` + Network []PhysicalNicNameHint `xml:"network,omitempty"` + ConnectedSwitchPort *PhysicalNicCdpInfo `xml:"connectedSwitchPort,omitempty"` + LldpInfo *LinkLayerDiscoveryProtocolInfo `xml:"lldpInfo,omitempty"` +} + +func init() { + t["PhysicalNicHintInfo"] = reflect.TypeOf((*PhysicalNicHintInfo)(nil)).Elem() +} + +type PhysicalNicIpHint struct { + PhysicalNicHint + + IpSubnet string `xml:"ipSubnet"` +} + +func init() { + t["PhysicalNicIpHint"] = reflect.TypeOf((*PhysicalNicIpHint)(nil)).Elem() +} + +type PhysicalNicLinkInfo struct { + DynamicData + + SpeedMb int32 `xml:"speedMb"` + Duplex bool `xml:"duplex"` +} + +func init() { + t["PhysicalNicLinkInfo"] = reflect.TypeOf((*PhysicalNicLinkInfo)(nil)).Elem() +} + +type PhysicalNicNameHint struct { + PhysicalNicHint + + Network string `xml:"network"` +} + +func init() { + t["PhysicalNicNameHint"] = reflect.TypeOf((*PhysicalNicNameHint)(nil)).Elem() +} + +type PhysicalNicProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["PhysicalNicProfile"] = reflect.TypeOf((*PhysicalNicProfile)(nil)).Elem() +} + +type PhysicalNicSpec struct { + DynamicData + + Ip *HostIpConfig `xml:"ip,omitempty"` + LinkSpeed *PhysicalNicLinkInfo `xml:"linkSpeed,omitempty"` +} + +func init() { + t["PhysicalNicSpec"] = reflect.TypeOf((*PhysicalNicSpec)(nil)).Elem() +} + +type PlaceVm PlaceVmRequestType + +func init() { + t["PlaceVm"] = reflect.TypeOf((*PlaceVm)(nil)).Elem() +} + +type PlaceVmRequestType struct { + This ManagedObjectReference `xml:"_this"` + PlacementSpec PlacementSpec `xml:"placementSpec"` +} + +func init() { + t["PlaceVmRequestType"] = reflect.TypeOf((*PlaceVmRequestType)(nil)).Elem() +} + +type PlaceVmResponse struct { + Returnval PlacementResult `xml:"returnval"` +} + +type PlacementAction struct { + ClusterAction + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + TargetHost *ManagedObjectReference `xml:"targetHost,omitempty"` + RelocateSpec *VirtualMachineRelocateSpec `xml:"relocateSpec,omitempty"` +} + +func init() { + t["PlacementAction"] = reflect.TypeOf((*PlacementAction)(nil)).Elem() +} + +type PlacementAffinityRule struct { + DynamicData + + RuleType string `xml:"ruleType"` + RuleScope string `xml:"ruleScope"` + Vms []ManagedObjectReference `xml:"vms,omitempty"` + Keys []string `xml:"keys,omitempty"` +} + +func init() { + t["PlacementAffinityRule"] = reflect.TypeOf((*PlacementAffinityRule)(nil)).Elem() +} + +type PlacementRankResult struct { + DynamicData + + Key string `xml:"key"` + Candidate ManagedObjectReference `xml:"candidate"` + ReservedSpaceMB int64 `xml:"reservedSpaceMB"` + UsedSpaceMB int64 `xml:"usedSpaceMB"` + TotalSpaceMB int64 `xml:"totalSpaceMB"` + Utilization float64 `xml:"utilization"` + Faults []LocalizedMethodFault `xml:"faults,omitempty"` +} + +func init() { + t["PlacementRankResult"] = reflect.TypeOf((*PlacementRankResult)(nil)).Elem() +} + +type PlacementRankSpec struct { + DynamicData + + Specs []PlacementSpec `xml:"specs"` + Clusters []ManagedObjectReference `xml:"clusters"` + Rules []PlacementAffinityRule `xml:"rules,omitempty"` + PlacementRankByVm []StorageDrsPlacementRankVmSpec `xml:"placementRankByVm,omitempty"` +} + +func init() { + t["PlacementRankSpec"] = reflect.TypeOf((*PlacementRankSpec)(nil)).Elem() +} + +type PlacementResult struct { + DynamicData + + Recommendations []ClusterRecommendation `xml:"recommendations,omitempty"` + DrsFault *ClusterDrsFaults `xml:"drsFault,omitempty"` +} + +func init() { + t["PlacementResult"] = reflect.TypeOf((*PlacementResult)(nil)).Elem() +} + +type PlacementSpec struct { + DynamicData + + Priority VirtualMachineMovePriority `xml:"priority,omitempty"` + Vm *ManagedObjectReference `xml:"vm,omitempty"` + ConfigSpec *VirtualMachineConfigSpec `xml:"configSpec,omitempty"` + RelocateSpec *VirtualMachineRelocateSpec `xml:"relocateSpec,omitempty"` + Hosts []ManagedObjectReference `xml:"hosts,omitempty"` + Datastores []ManagedObjectReference `xml:"datastores,omitempty"` + StoragePods []ManagedObjectReference `xml:"storagePods,omitempty"` + DisallowPrerequisiteMoves *bool `xml:"disallowPrerequisiteMoves"` + Rules []BaseClusterRuleInfo `xml:"rules,omitempty,typeattr"` + Key string `xml:"key,omitempty"` + PlacementType string `xml:"placementType,omitempty"` + CloneSpec *VirtualMachineCloneSpec `xml:"cloneSpec,omitempty"` + CloneName string `xml:"cloneName,omitempty"` +} + +func init() { + t["PlacementSpec"] = reflect.TypeOf((*PlacementSpec)(nil)).Elem() +} + +type PlatformConfigFault struct { + HostConfigFault + + Text string `xml:"text"` +} + +func init() { + t["PlatformConfigFault"] = reflect.TypeOf((*PlatformConfigFault)(nil)).Elem() +} + +type PlatformConfigFaultFault BasePlatformConfigFault + +func init() { + t["PlatformConfigFaultFault"] = reflect.TypeOf((*PlatformConfigFaultFault)(nil)).Elem() +} + +type PnicUplinkProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["PnicUplinkProfile"] = reflect.TypeOf((*PnicUplinkProfile)(nil)).Elem() +} + +type PodDiskLocator struct { + DynamicData + + DiskId int32 `xml:"diskId"` + DiskMoveType string `xml:"diskMoveType,omitempty"` + DiskBackingInfo BaseVirtualDeviceBackingInfo `xml:"diskBackingInfo,omitempty,typeattr"` + Profile []BaseVirtualMachineProfileSpec `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["PodDiskLocator"] = reflect.TypeOf((*PodDiskLocator)(nil)).Elem() +} + +type PodStorageDrsEntry struct { + DynamicData + + StorageDrsConfig StorageDrsConfigInfo `xml:"storageDrsConfig"` + Recommendation []ClusterRecommendation `xml:"recommendation,omitempty"` + DrsFault []ClusterDrsFaults `xml:"drsFault,omitempty"` + ActionHistory []ClusterActionHistory `xml:"actionHistory,omitempty"` +} + +func init() { + t["PodStorageDrsEntry"] = reflect.TypeOf((*PodStorageDrsEntry)(nil)).Elem() +} + +type PolicyOption struct { + DynamicData + + Id string `xml:"id"` + Parameter []KeyAnyValue `xml:"parameter,omitempty"` +} + +func init() { + t["PolicyOption"] = reflect.TypeOf((*PolicyOption)(nil)).Elem() +} + +type PortGroupProfile struct { + ApplyProfile + + Key string `xml:"key"` + Name string `xml:"name"` + Vlan VlanProfile `xml:"vlan"` + Vswitch VirtualSwitchSelectionProfile `xml:"vswitch"` + NetworkPolicy NetworkPolicyProfile `xml:"networkPolicy"` +} + +func init() { + t["PortGroupProfile"] = reflect.TypeOf((*PortGroupProfile)(nil)).Elem() +} + +type PosixUserSearchResult struct { + UserSearchResult + + Id int32 `xml:"id"` + ShellAccess *bool `xml:"shellAccess"` +} + +func init() { + t["PosixUserSearchResult"] = reflect.TypeOf((*PosixUserSearchResult)(nil)).Elem() +} + +type PostEvent PostEventRequestType + +func init() { + t["PostEvent"] = reflect.TypeOf((*PostEvent)(nil)).Elem() +} + +type PostEventRequestType struct { + This ManagedObjectReference `xml:"_this"` + EventToPost BaseEvent `xml:"eventToPost,typeattr"` + TaskInfo *TaskInfo `xml:"taskInfo,omitempty"` +} + +func init() { + t["PostEventRequestType"] = reflect.TypeOf((*PostEventRequestType)(nil)).Elem() +} + +type PostEventResponse struct { +} + +type PowerDownHostToStandByRequestType struct { + This ManagedObjectReference `xml:"_this"` + TimeoutSec int32 `xml:"timeoutSec"` + EvacuatePoweredOffVms *bool `xml:"evacuatePoweredOffVms"` +} + +func init() { + t["PowerDownHostToStandByRequestType"] = reflect.TypeOf((*PowerDownHostToStandByRequestType)(nil)).Elem() +} + +type PowerDownHostToStandBy_Task PowerDownHostToStandByRequestType + +func init() { + t["PowerDownHostToStandBy_Task"] = reflect.TypeOf((*PowerDownHostToStandBy_Task)(nil)).Elem() +} + +type PowerDownHostToStandBy_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PowerOffVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` + Force bool `xml:"force"` +} + +func init() { + t["PowerOffVAppRequestType"] = reflect.TypeOf((*PowerOffVAppRequestType)(nil)).Elem() +} + +type PowerOffVApp_Task PowerOffVAppRequestType + +func init() { + t["PowerOffVApp_Task"] = reflect.TypeOf((*PowerOffVApp_Task)(nil)).Elem() +} + +type PowerOffVApp_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PowerOffVMRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["PowerOffVMRequestType"] = reflect.TypeOf((*PowerOffVMRequestType)(nil)).Elem() +} + +type PowerOffVM_Task PowerOffVMRequestType + +func init() { + t["PowerOffVM_Task"] = reflect.TypeOf((*PowerOffVM_Task)(nil)).Elem() +} + +type PowerOffVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PowerOnFtSecondaryFailed struct { + VmFaultToleranceIssue + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` + HostSelectionBy FtIssuesOnHostHostSelectionType `xml:"hostSelectionBy"` + HostErrors []LocalizedMethodFault `xml:"hostErrors,omitempty"` + RootCause LocalizedMethodFault `xml:"rootCause"` +} + +func init() { + t["PowerOnFtSecondaryFailed"] = reflect.TypeOf((*PowerOnFtSecondaryFailed)(nil)).Elem() +} + +type PowerOnFtSecondaryFailedFault PowerOnFtSecondaryFailed + +func init() { + t["PowerOnFtSecondaryFailedFault"] = reflect.TypeOf((*PowerOnFtSecondaryFailedFault)(nil)).Elem() +} + +type PowerOnFtSecondaryTimedout struct { + Timedout + + Vm ManagedObjectReference `xml:"vm"` + VmName string `xml:"vmName"` + Timeout int32 `xml:"timeout"` +} + +func init() { + t["PowerOnFtSecondaryTimedout"] = reflect.TypeOf((*PowerOnFtSecondaryTimedout)(nil)).Elem() +} + +type PowerOnFtSecondaryTimedoutFault PowerOnFtSecondaryTimedout + +func init() { + t["PowerOnFtSecondaryTimedoutFault"] = reflect.TypeOf((*PowerOnFtSecondaryTimedoutFault)(nil)).Elem() +} + +type PowerOnMultiVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm []ManagedObjectReference `xml:"vm"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` +} + +func init() { + t["PowerOnMultiVMRequestType"] = reflect.TypeOf((*PowerOnMultiVMRequestType)(nil)).Elem() +} + +type PowerOnMultiVM_Task PowerOnMultiVMRequestType + +func init() { + t["PowerOnMultiVM_Task"] = reflect.TypeOf((*PowerOnMultiVM_Task)(nil)).Elem() +} + +type PowerOnMultiVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PowerOnVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["PowerOnVAppRequestType"] = reflect.TypeOf((*PowerOnVAppRequestType)(nil)).Elem() +} + +type PowerOnVApp_Task PowerOnVAppRequestType + +func init() { + t["PowerOnVApp_Task"] = reflect.TypeOf((*PowerOnVApp_Task)(nil)).Elem() +} + +type PowerOnVApp_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PowerOnVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["PowerOnVMRequestType"] = reflect.TypeOf((*PowerOnVMRequestType)(nil)).Elem() +} + +type PowerOnVM_Task PowerOnVMRequestType + +func init() { + t["PowerOnVM_Task"] = reflect.TypeOf((*PowerOnVM_Task)(nil)).Elem() +} + +type PowerOnVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PowerSystemCapability struct { + DynamicData + + AvailablePolicy []HostPowerPolicy `xml:"availablePolicy"` +} + +func init() { + t["PowerSystemCapability"] = reflect.TypeOf((*PowerSystemCapability)(nil)).Elem() +} + +type PowerSystemInfo struct { + DynamicData + + CurrentPolicy HostPowerPolicy `xml:"currentPolicy"` +} + +func init() { + t["PowerSystemInfo"] = reflect.TypeOf((*PowerSystemInfo)(nil)).Elem() +} + +type PowerUpHostFromStandByRequestType struct { + This ManagedObjectReference `xml:"_this"` + TimeoutSec int32 `xml:"timeoutSec"` +} + +func init() { + t["PowerUpHostFromStandByRequestType"] = reflect.TypeOf((*PowerUpHostFromStandByRequestType)(nil)).Elem() +} + +type PowerUpHostFromStandBy_Task PowerUpHostFromStandByRequestType + +func init() { + t["PowerUpHostFromStandBy_Task"] = reflect.TypeOf((*PowerUpHostFromStandBy_Task)(nil)).Elem() +} + +type PowerUpHostFromStandBy_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PrivilegeAvailability struct { + DynamicData + + PrivId string `xml:"privId"` + IsGranted bool `xml:"isGranted"` +} + +func init() { + t["PrivilegeAvailability"] = reflect.TypeOf((*PrivilegeAvailability)(nil)).Elem() +} + +type PrivilegePolicyDef struct { + DynamicData + + CreatePrivilege string `xml:"createPrivilege"` + ReadPrivilege string `xml:"readPrivilege"` + UpdatePrivilege string `xml:"updatePrivilege"` + DeletePrivilege string `xml:"deletePrivilege"` +} + +func init() { + t["PrivilegePolicyDef"] = reflect.TypeOf((*PrivilegePolicyDef)(nil)).Elem() +} + +type ProductComponentInfo struct { + DynamicData + + Id string `xml:"id"` + Name string `xml:"name"` + Version string `xml:"version"` + Release int32 `xml:"release"` +} + +func init() { + t["ProductComponentInfo"] = reflect.TypeOf((*ProductComponentInfo)(nil)).Elem() +} + +type ProfileApplyProfileElement struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["ProfileApplyProfileElement"] = reflect.TypeOf((*ProfileApplyProfileElement)(nil)).Elem() +} + +type ProfileApplyProfileProperty struct { + DynamicData + + PropertyName string `xml:"propertyName"` + Array bool `xml:"array"` + Profile []BaseApplyProfile `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["ProfileApplyProfileProperty"] = reflect.TypeOf((*ProfileApplyProfileProperty)(nil)).Elem() +} + +type ProfileAssociatedEvent struct { + ProfileEvent +} + +func init() { + t["ProfileAssociatedEvent"] = reflect.TypeOf((*ProfileAssociatedEvent)(nil)).Elem() +} + +type ProfileChangedEvent struct { + ProfileEvent +} + +func init() { + t["ProfileChangedEvent"] = reflect.TypeOf((*ProfileChangedEvent)(nil)).Elem() +} + +type ProfileCompositeExpression struct { + ProfileExpression + + Operator string `xml:"operator"` + ExpressionName []string `xml:"expressionName"` +} + +func init() { + t["ProfileCompositeExpression"] = reflect.TypeOf((*ProfileCompositeExpression)(nil)).Elem() +} + +type ProfileCompositePolicyOptionMetadata struct { + ProfilePolicyOptionMetadata + + Option []string `xml:"option"` +} + +func init() { + t["ProfileCompositePolicyOptionMetadata"] = reflect.TypeOf((*ProfileCompositePolicyOptionMetadata)(nil)).Elem() +} + +type ProfileConfigInfo struct { + DynamicData + + Name string `xml:"name"` + Annotation string `xml:"annotation,omitempty"` + Enabled bool `xml:"enabled"` +} + +func init() { + t["ProfileConfigInfo"] = reflect.TypeOf((*ProfileConfigInfo)(nil)).Elem() +} + +type ProfileCreateSpec struct { + DynamicData + + Name string `xml:"name,omitempty"` + Annotation string `xml:"annotation,omitempty"` + Enabled *bool `xml:"enabled"` +} + +func init() { + t["ProfileCreateSpec"] = reflect.TypeOf((*ProfileCreateSpec)(nil)).Elem() +} + +type ProfileCreatedEvent struct { + ProfileEvent +} + +func init() { + t["ProfileCreatedEvent"] = reflect.TypeOf((*ProfileCreatedEvent)(nil)).Elem() +} + +type ProfileDeferredPolicyOptionParameter struct { + DynamicData + + InputPath ProfilePropertyPath `xml:"inputPath"` + Parameter []KeyAnyValue `xml:"parameter,omitempty"` +} + +func init() { + t["ProfileDeferredPolicyOptionParameter"] = reflect.TypeOf((*ProfileDeferredPolicyOptionParameter)(nil)).Elem() +} + +type ProfileDescription struct { + DynamicData + + Section []ProfileDescriptionSection `xml:"section"` +} + +func init() { + t["ProfileDescription"] = reflect.TypeOf((*ProfileDescription)(nil)).Elem() +} + +type ProfileDescriptionSection struct { + DynamicData + + Description ExtendedElementDescription `xml:"description"` + Message []LocalizableMessage `xml:"message,omitempty"` +} + +func init() { + t["ProfileDescriptionSection"] = reflect.TypeOf((*ProfileDescriptionSection)(nil)).Elem() +} + +type ProfileDissociatedEvent struct { + ProfileEvent +} + +func init() { + t["ProfileDissociatedEvent"] = reflect.TypeOf((*ProfileDissociatedEvent)(nil)).Elem() +} + +type ProfileEvent struct { + Event + + Profile ProfileEventArgument `xml:"profile"` +} + +func init() { + t["ProfileEvent"] = reflect.TypeOf((*ProfileEvent)(nil)).Elem() +} + +type ProfileEventArgument struct { + EventArgument + + Profile ManagedObjectReference `xml:"profile"` + Name string `xml:"name"` +} + +func init() { + t["ProfileEventArgument"] = reflect.TypeOf((*ProfileEventArgument)(nil)).Elem() +} + +type ProfileExecuteError struct { + DynamicData + + Path *ProfilePropertyPath `xml:"path,omitempty"` + Message LocalizableMessage `xml:"message"` +} + +func init() { + t["ProfileExecuteError"] = reflect.TypeOf((*ProfileExecuteError)(nil)).Elem() +} + +type ProfileExecuteResult struct { + DynamicData + + Status string `xml:"status"` + ConfigSpec *HostConfigSpec `xml:"configSpec,omitempty"` + InapplicablePath []string `xml:"inapplicablePath,omitempty"` + RequireInput []ProfileDeferredPolicyOptionParameter `xml:"requireInput,omitempty"` + Error []ProfileExecuteError `xml:"error,omitempty"` +} + +func init() { + t["ProfileExecuteResult"] = reflect.TypeOf((*ProfileExecuteResult)(nil)).Elem() +} + +type ProfileExpression struct { + DynamicData + + Id string `xml:"id"` + DisplayName string `xml:"displayName"` + Negated bool `xml:"negated"` +} + +func init() { + t["ProfileExpression"] = reflect.TypeOf((*ProfileExpression)(nil)).Elem() +} + +type ProfileExpressionMetadata struct { + DynamicData + + ExpressionId ExtendedElementDescription `xml:"expressionId"` + Parameter []ProfileParameterMetadata `xml:"parameter,omitempty"` +} + +func init() { + t["ProfileExpressionMetadata"] = reflect.TypeOf((*ProfileExpressionMetadata)(nil)).Elem() +} + +type ProfileMetadata struct { + DynamicData + + Key string `xml:"key"` + ProfileTypeName string `xml:"profileTypeName,omitempty"` + Description *ExtendedDescription `xml:"description,omitempty"` + SortSpec []ProfileMetadataProfileSortSpec `xml:"sortSpec,omitempty"` + ProfileCategory string `xml:"profileCategory,omitempty"` + ProfileComponent string `xml:"profileComponent,omitempty"` +} + +func init() { + t["ProfileMetadata"] = reflect.TypeOf((*ProfileMetadata)(nil)).Elem() +} + +type ProfileMetadataProfileSortSpec struct { + DynamicData + + PolicyId string `xml:"policyId"` + Parameter string `xml:"parameter"` +} + +func init() { + t["ProfileMetadataProfileSortSpec"] = reflect.TypeOf((*ProfileMetadataProfileSortSpec)(nil)).Elem() +} + +type ProfileParameterMetadata struct { + DynamicData + + Id ExtendedElementDescription `xml:"id"` + Type string `xml:"type"` + Optional bool `xml:"optional"` + DefaultValue AnyType `xml:"defaultValue,omitempty,typeattr"` +} + +func init() { + t["ProfileParameterMetadata"] = reflect.TypeOf((*ProfileParameterMetadata)(nil)).Elem() +} + +type ProfilePolicy struct { + DynamicData + + Id string `xml:"id"` + PolicyOption BasePolicyOption `xml:"policyOption,typeattr"` +} + +func init() { + t["ProfilePolicy"] = reflect.TypeOf((*ProfilePolicy)(nil)).Elem() +} + +type ProfilePolicyMetadata struct { + DynamicData + + Id ExtendedElementDescription `xml:"id"` + PossibleOption []BaseProfilePolicyOptionMetadata `xml:"possibleOption,typeattr"` +} + +func init() { + t["ProfilePolicyMetadata"] = reflect.TypeOf((*ProfilePolicyMetadata)(nil)).Elem() +} + +type ProfilePolicyOptionMetadata struct { + DynamicData + + Id ExtendedElementDescription `xml:"id"` + Parameter []ProfileParameterMetadata `xml:"parameter,omitempty"` +} + +func init() { + t["ProfilePolicyOptionMetadata"] = reflect.TypeOf((*ProfilePolicyOptionMetadata)(nil)).Elem() +} + +type ProfileProfileStructure struct { + DynamicData + + ProfileTypeName string `xml:"profileTypeName"` + Child []ProfileProfileStructureProperty `xml:"child,omitempty"` +} + +func init() { + t["ProfileProfileStructure"] = reflect.TypeOf((*ProfileProfileStructure)(nil)).Elem() +} + +type ProfileProfileStructureProperty struct { + DynamicData + + PropertyName string `xml:"propertyName"` + Array bool `xml:"array"` + Element ProfileProfileStructure `xml:"element"` +} + +func init() { + t["ProfileProfileStructureProperty"] = reflect.TypeOf((*ProfileProfileStructureProperty)(nil)).Elem() +} + +type ProfilePropertyPath struct { + DynamicData + + ProfilePath string `xml:"profilePath"` + PolicyId string `xml:"policyId,omitempty"` + ParameterId string `xml:"parameterId,omitempty"` +} + +func init() { + t["ProfilePropertyPath"] = reflect.TypeOf((*ProfilePropertyPath)(nil)).Elem() +} + +type ProfileReferenceHostChangedEvent struct { + ProfileEvent + + ReferenceHost *ManagedObjectReference `xml:"referenceHost,omitempty"` +} + +func init() { + t["ProfileReferenceHostChangedEvent"] = reflect.TypeOf((*ProfileReferenceHostChangedEvent)(nil)).Elem() +} + +type ProfileRemovedEvent struct { + ProfileEvent +} + +func init() { + t["ProfileRemovedEvent"] = reflect.TypeOf((*ProfileRemovedEvent)(nil)).Elem() +} + +type ProfileSerializedCreateSpec struct { + ProfileCreateSpec + + ProfileConfigString string `xml:"profileConfigString"` +} + +func init() { + t["ProfileSerializedCreateSpec"] = reflect.TypeOf((*ProfileSerializedCreateSpec)(nil)).Elem() +} + +type ProfileSimpleExpression struct { + ProfileExpression + + ExpressionType string `xml:"expressionType"` + Parameter []KeyAnyValue `xml:"parameter,omitempty"` +} + +func init() { + t["ProfileSimpleExpression"] = reflect.TypeOf((*ProfileSimpleExpression)(nil)).Elem() +} + +type ProfileUpdateFailed struct { + VimFault + + Failure []ProfileUpdateFailedUpdateFailure `xml:"failure"` +} + +func init() { + t["ProfileUpdateFailed"] = reflect.TypeOf((*ProfileUpdateFailed)(nil)).Elem() +} + +type ProfileUpdateFailedFault ProfileUpdateFailed + +func init() { + t["ProfileUpdateFailedFault"] = reflect.TypeOf((*ProfileUpdateFailedFault)(nil)).Elem() +} + +type ProfileUpdateFailedUpdateFailure struct { + DynamicData + + ProfilePath ProfilePropertyPath `xml:"profilePath"` + ErrMsg LocalizableMessage `xml:"errMsg"` +} + +func init() { + t["ProfileUpdateFailedUpdateFailure"] = reflect.TypeOf((*ProfileUpdateFailedUpdateFailure)(nil)).Elem() +} + +type PromoteDisksRequestType struct { + This ManagedObjectReference `xml:"_this"` + Unlink bool `xml:"unlink"` + Disks []VirtualDisk `xml:"disks,omitempty"` +} + +func init() { + t["PromoteDisksRequestType"] = reflect.TypeOf((*PromoteDisksRequestType)(nil)).Elem() +} + +type PromoteDisks_Task PromoteDisksRequestType + +func init() { + t["PromoteDisks_Task"] = reflect.TypeOf((*PromoteDisks_Task)(nil)).Elem() +} + +type PromoteDisks_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type PropertyChange struct { + DynamicData + + Name string `xml:"name"` + Op PropertyChangeOp `xml:"op"` + Val AnyType `xml:"val,omitempty,typeattr"` +} + +func init() { + t["PropertyChange"] = reflect.TypeOf((*PropertyChange)(nil)).Elem() +} + +type PropertyFilterSpec struct { + DynamicData + + PropSet []PropertySpec `xml:"propSet"` + ObjectSet []ObjectSpec `xml:"objectSet"` + ReportMissingObjectsInResults *bool `xml:"reportMissingObjectsInResults"` +} + +func init() { + t["PropertyFilterSpec"] = reflect.TypeOf((*PropertyFilterSpec)(nil)).Elem() +} + +type PropertyFilterUpdate struct { + DynamicData + + Filter ManagedObjectReference `xml:"filter"` + ObjectSet []ObjectUpdate `xml:"objectSet,omitempty"` + MissingSet []MissingObject `xml:"missingSet,omitempty"` +} + +func init() { + t["PropertyFilterUpdate"] = reflect.TypeOf((*PropertyFilterUpdate)(nil)).Elem() +} + +type PropertySpec struct { + DynamicData + + Type string `xml:"type"` + All *bool `xml:"all"` + PathSet []string `xml:"pathSet,omitempty"` +} + +func init() { + t["PropertySpec"] = reflect.TypeOf((*PropertySpec)(nil)).Elem() +} + +type QueryAnswerFileStatus QueryAnswerFileStatusRequestType + +func init() { + t["QueryAnswerFileStatus"] = reflect.TypeOf((*QueryAnswerFileStatus)(nil)).Elem() +} + +type QueryAnswerFileStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["QueryAnswerFileStatusRequestType"] = reflect.TypeOf((*QueryAnswerFileStatusRequestType)(nil)).Elem() +} + +type QueryAnswerFileStatusResponse struct { + Returnval []AnswerFileStatusResult `xml:"returnval,omitempty"` +} + +type QueryAssignedLicenses QueryAssignedLicensesRequestType + +func init() { + t["QueryAssignedLicenses"] = reflect.TypeOf((*QueryAssignedLicenses)(nil)).Elem() +} + +type QueryAssignedLicensesRequestType struct { + This ManagedObjectReference `xml:"_this"` + EntityId string `xml:"entityId,omitempty"` +} + +func init() { + t["QueryAssignedLicensesRequestType"] = reflect.TypeOf((*QueryAssignedLicensesRequestType)(nil)).Elem() +} + +type QueryAssignedLicensesResponse struct { + Returnval []LicenseAssignmentManagerLicenseAssignment `xml:"returnval"` +} + +type QueryAvailableDisksForVmfs QueryAvailableDisksForVmfsRequestType + +func init() { + t["QueryAvailableDisksForVmfs"] = reflect.TypeOf((*QueryAvailableDisksForVmfs)(nil)).Elem() +} + +type QueryAvailableDisksForVmfsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` +} + +func init() { + t["QueryAvailableDisksForVmfsRequestType"] = reflect.TypeOf((*QueryAvailableDisksForVmfsRequestType)(nil)).Elem() +} + +type QueryAvailableDisksForVmfsResponse struct { + Returnval []HostScsiDisk `xml:"returnval,omitempty"` +} + +type QueryAvailableDvsSpec QueryAvailableDvsSpecRequestType + +func init() { + t["QueryAvailableDvsSpec"] = reflect.TypeOf((*QueryAvailableDvsSpec)(nil)).Elem() +} + +type QueryAvailableDvsSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Recommended *bool `xml:"recommended"` +} + +func init() { + t["QueryAvailableDvsSpecRequestType"] = reflect.TypeOf((*QueryAvailableDvsSpecRequestType)(nil)).Elem() +} + +type QueryAvailableDvsSpecResponse struct { + Returnval []DistributedVirtualSwitchProductSpec `xml:"returnval,omitempty"` +} + +type QueryAvailablePartition QueryAvailablePartitionRequestType + +func init() { + t["QueryAvailablePartition"] = reflect.TypeOf((*QueryAvailablePartition)(nil)).Elem() +} + +type QueryAvailablePartitionRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryAvailablePartitionRequestType"] = reflect.TypeOf((*QueryAvailablePartitionRequestType)(nil)).Elem() +} + +type QueryAvailablePartitionResponse struct { + Returnval []HostDiagnosticPartition `xml:"returnval,omitempty"` +} + +type QueryAvailablePerfMetric QueryAvailablePerfMetricRequestType + +func init() { + t["QueryAvailablePerfMetric"] = reflect.TypeOf((*QueryAvailablePerfMetric)(nil)).Elem() +} + +type QueryAvailablePerfMetricRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + BeginTime *time.Time `xml:"beginTime"` + EndTime *time.Time `xml:"endTime"` + IntervalId int32 `xml:"intervalId,omitempty"` +} + +func init() { + t["QueryAvailablePerfMetricRequestType"] = reflect.TypeOf((*QueryAvailablePerfMetricRequestType)(nil)).Elem() +} + +type QueryAvailablePerfMetricResponse struct { + Returnval []PerfMetricId `xml:"returnval,omitempty"` +} + +type QueryAvailableSsds QueryAvailableSsdsRequestType + +func init() { + t["QueryAvailableSsds"] = reflect.TypeOf((*QueryAvailableSsds)(nil)).Elem() +} + +type QueryAvailableSsdsRequestType struct { + This ManagedObjectReference `xml:"_this"` + VffsPath string `xml:"vffsPath,omitempty"` +} + +func init() { + t["QueryAvailableSsdsRequestType"] = reflect.TypeOf((*QueryAvailableSsdsRequestType)(nil)).Elem() +} + +type QueryAvailableSsdsResponse struct { + Returnval []HostScsiDisk `xml:"returnval,omitempty"` +} + +type QueryAvailableTimeZones QueryAvailableTimeZonesRequestType + +func init() { + t["QueryAvailableTimeZones"] = reflect.TypeOf((*QueryAvailableTimeZones)(nil)).Elem() +} + +type QueryAvailableTimeZonesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryAvailableTimeZonesRequestType"] = reflect.TypeOf((*QueryAvailableTimeZonesRequestType)(nil)).Elem() +} + +type QueryAvailableTimeZonesResponse struct { + Returnval []HostDateTimeSystemTimeZone `xml:"returnval,omitempty"` +} + +type QueryBootDevices QueryBootDevicesRequestType + +func init() { + t["QueryBootDevices"] = reflect.TypeOf((*QueryBootDevices)(nil)).Elem() +} + +type QueryBootDevicesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryBootDevicesRequestType"] = reflect.TypeOf((*QueryBootDevicesRequestType)(nil)).Elem() +} + +type QueryBootDevicesResponse struct { + Returnval *HostBootDeviceInfo `xml:"returnval,omitempty"` +} + +type QueryBoundVnics QueryBoundVnicsRequestType + +func init() { + t["QueryBoundVnics"] = reflect.TypeOf((*QueryBoundVnics)(nil)).Elem() +} + +type QueryBoundVnicsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaName string `xml:"iScsiHbaName"` +} + +func init() { + t["QueryBoundVnicsRequestType"] = reflect.TypeOf((*QueryBoundVnicsRequestType)(nil)).Elem() +} + +type QueryBoundVnicsResponse struct { + Returnval []IscsiPortInfo `xml:"returnval,omitempty"` +} + +type QueryCandidateNics QueryCandidateNicsRequestType + +func init() { + t["QueryCandidateNics"] = reflect.TypeOf((*QueryCandidateNics)(nil)).Elem() +} + +type QueryCandidateNicsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaName string `xml:"iScsiHbaName"` +} + +func init() { + t["QueryCandidateNicsRequestType"] = reflect.TypeOf((*QueryCandidateNicsRequestType)(nil)).Elem() +} + +type QueryCandidateNicsResponse struct { + Returnval []IscsiPortInfo `xml:"returnval,omitempty"` +} + +type QueryChangedDiskAreas QueryChangedDiskAreasRequestType + +func init() { + t["QueryChangedDiskAreas"] = reflect.TypeOf((*QueryChangedDiskAreas)(nil)).Elem() +} + +type QueryChangedDiskAreasRequestType struct { + This ManagedObjectReference `xml:"_this"` + Snapshot *ManagedObjectReference `xml:"snapshot,omitempty"` + DeviceKey int32 `xml:"deviceKey"` + StartOffset int64 `xml:"startOffset"` + ChangeId string `xml:"changeId"` +} + +func init() { + t["QueryChangedDiskAreasRequestType"] = reflect.TypeOf((*QueryChangedDiskAreasRequestType)(nil)).Elem() +} + +type QueryChangedDiskAreasResponse struct { + Returnval DiskChangeInfo `xml:"returnval"` +} + +type QueryCmmds QueryCmmdsRequestType + +func init() { + t["QueryCmmds"] = reflect.TypeOf((*QueryCmmds)(nil)).Elem() +} + +type QueryCmmdsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Queries []HostVsanInternalSystemCmmdsQuery `xml:"queries"` +} + +func init() { + t["QueryCmmdsRequestType"] = reflect.TypeOf((*QueryCmmdsRequestType)(nil)).Elem() +} + +type QueryCmmdsResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryCompatibleHostForExistingDvs QueryCompatibleHostForExistingDvsRequestType + +func init() { + t["QueryCompatibleHostForExistingDvs"] = reflect.TypeOf((*QueryCompatibleHostForExistingDvs)(nil)).Elem() +} + +type QueryCompatibleHostForExistingDvsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Container ManagedObjectReference `xml:"container"` + Recursive bool `xml:"recursive"` + Dvs ManagedObjectReference `xml:"dvs"` +} + +func init() { + t["QueryCompatibleHostForExistingDvsRequestType"] = reflect.TypeOf((*QueryCompatibleHostForExistingDvsRequestType)(nil)).Elem() +} + +type QueryCompatibleHostForExistingDvsResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type QueryCompatibleHostForNewDvs QueryCompatibleHostForNewDvsRequestType + +func init() { + t["QueryCompatibleHostForNewDvs"] = reflect.TypeOf((*QueryCompatibleHostForNewDvs)(nil)).Elem() +} + +type QueryCompatibleHostForNewDvsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Container ManagedObjectReference `xml:"container"` + Recursive bool `xml:"recursive"` + SwitchProductSpec *DistributedVirtualSwitchProductSpec `xml:"switchProductSpec,omitempty"` +} + +func init() { + t["QueryCompatibleHostForNewDvsRequestType"] = reflect.TypeOf((*QueryCompatibleHostForNewDvsRequestType)(nil)).Elem() +} + +type QueryCompatibleHostForNewDvsResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type QueryComplianceStatus QueryComplianceStatusRequestType + +func init() { + t["QueryComplianceStatus"] = reflect.TypeOf((*QueryComplianceStatus)(nil)).Elem() +} + +type QueryComplianceStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + Profile []ManagedObjectReference `xml:"profile,omitempty"` + Entity []ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["QueryComplianceStatusRequestType"] = reflect.TypeOf((*QueryComplianceStatusRequestType)(nil)).Elem() +} + +type QueryComplianceStatusResponse struct { + Returnval []ComplianceResult `xml:"returnval,omitempty"` +} + +type QueryConfigOption QueryConfigOptionRequestType + +func init() { + t["QueryConfigOption"] = reflect.TypeOf((*QueryConfigOption)(nil)).Elem() +} + +type QueryConfigOptionDescriptor QueryConfigOptionDescriptorRequestType + +func init() { + t["QueryConfigOptionDescriptor"] = reflect.TypeOf((*QueryConfigOptionDescriptor)(nil)).Elem() +} + +type QueryConfigOptionDescriptorRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryConfigOptionDescriptorRequestType"] = reflect.TypeOf((*QueryConfigOptionDescriptorRequestType)(nil)).Elem() +} + +type QueryConfigOptionDescriptorResponse struct { + Returnval []VirtualMachineConfigOptionDescriptor `xml:"returnval,omitempty"` +} + +type QueryConfigOptionEx QueryConfigOptionExRequestType + +func init() { + t["QueryConfigOptionEx"] = reflect.TypeOf((*QueryConfigOptionEx)(nil)).Elem() +} + +type QueryConfigOptionExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec *EnvironmentBrowserConfigOptionQuerySpec `xml:"spec,omitempty"` +} + +func init() { + t["QueryConfigOptionExRequestType"] = reflect.TypeOf((*QueryConfigOptionExRequestType)(nil)).Elem() +} + +type QueryConfigOptionExResponse struct { + Returnval *VirtualMachineConfigOption `xml:"returnval,omitempty"` +} + +type QueryConfigOptionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key string `xml:"key,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QueryConfigOptionRequestType"] = reflect.TypeOf((*QueryConfigOptionRequestType)(nil)).Elem() +} + +type QueryConfigOptionResponse struct { + Returnval *VirtualMachineConfigOption `xml:"returnval,omitempty"` +} + +type QueryConfigTarget QueryConfigTargetRequestType + +func init() { + t["QueryConfigTarget"] = reflect.TypeOf((*QueryConfigTarget)(nil)).Elem() +} + +type QueryConfigTargetRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QueryConfigTargetRequestType"] = reflect.TypeOf((*QueryConfigTargetRequestType)(nil)).Elem() +} + +type QueryConfigTargetResponse struct { + Returnval *ConfigTarget `xml:"returnval,omitempty"` +} + +type QueryConfiguredModuleOptionString QueryConfiguredModuleOptionStringRequestType + +func init() { + t["QueryConfiguredModuleOptionString"] = reflect.TypeOf((*QueryConfiguredModuleOptionString)(nil)).Elem() +} + +type QueryConfiguredModuleOptionStringRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` +} + +func init() { + t["QueryConfiguredModuleOptionStringRequestType"] = reflect.TypeOf((*QueryConfiguredModuleOptionStringRequestType)(nil)).Elem() +} + +type QueryConfiguredModuleOptionStringResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryConnectionInfo QueryConnectionInfoRequestType + +func init() { + t["QueryConnectionInfo"] = reflect.TypeOf((*QueryConnectionInfo)(nil)).Elem() +} + +type QueryConnectionInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` + Hostname string `xml:"hostname"` + Port int32 `xml:"port"` + Username string `xml:"username"` + Password string `xml:"password"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` +} + +func init() { + t["QueryConnectionInfoRequestType"] = reflect.TypeOf((*QueryConnectionInfoRequestType)(nil)).Elem() +} + +type QueryConnectionInfoResponse struct { + Returnval HostConnectInfo `xml:"returnval"` +} + +type QueryConnectionInfoViaSpec QueryConnectionInfoViaSpecRequestType + +func init() { + t["QueryConnectionInfoViaSpec"] = reflect.TypeOf((*QueryConnectionInfoViaSpec)(nil)).Elem() +} + +type QueryConnectionInfoViaSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostConnectSpec `xml:"spec"` +} + +func init() { + t["QueryConnectionInfoViaSpecRequestType"] = reflect.TypeOf((*QueryConnectionInfoViaSpecRequestType)(nil)).Elem() +} + +type QueryConnectionInfoViaSpecResponse struct { + Returnval HostConnectInfo `xml:"returnval"` +} + +type QueryDatastorePerformanceSummary QueryDatastorePerformanceSummaryRequestType + +func init() { + t["QueryDatastorePerformanceSummary"] = reflect.TypeOf((*QueryDatastorePerformanceSummary)(nil)).Elem() +} + +type QueryDatastorePerformanceSummaryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["QueryDatastorePerformanceSummaryRequestType"] = reflect.TypeOf((*QueryDatastorePerformanceSummaryRequestType)(nil)).Elem() +} + +type QueryDatastorePerformanceSummaryResponse struct { + Returnval []StoragePerformanceSummary `xml:"returnval,omitempty"` +} + +type QueryDateTime QueryDateTimeRequestType + +func init() { + t["QueryDateTime"] = reflect.TypeOf((*QueryDateTime)(nil)).Elem() +} + +type QueryDateTimeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryDateTimeRequestType"] = reflect.TypeOf((*QueryDateTimeRequestType)(nil)).Elem() +} + +type QueryDateTimeResponse struct { + Returnval time.Time `xml:"returnval"` +} + +type QueryDescriptions QueryDescriptionsRequestType + +func init() { + t["QueryDescriptions"] = reflect.TypeOf((*QueryDescriptions)(nil)).Elem() +} + +type QueryDescriptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QueryDescriptionsRequestType"] = reflect.TypeOf((*QueryDescriptionsRequestType)(nil)).Elem() +} + +type QueryDescriptionsResponse struct { + Returnval []DiagnosticManagerLogDescriptor `xml:"returnval,omitempty"` +} + +type QueryDisksForVsan QueryDisksForVsanRequestType + +func init() { + t["QueryDisksForVsan"] = reflect.TypeOf((*QueryDisksForVsan)(nil)).Elem() +} + +type QueryDisksForVsanRequestType struct { + This ManagedObjectReference `xml:"_this"` + CanonicalName []string `xml:"canonicalName,omitempty"` +} + +func init() { + t["QueryDisksForVsanRequestType"] = reflect.TypeOf((*QueryDisksForVsanRequestType)(nil)).Elem() +} + +type QueryDisksForVsanResponse struct { + Returnval []VsanHostDiskResult `xml:"returnval,omitempty"` +} + +type QueryDisksUsingFilter QueryDisksUsingFilterRequestType + +func init() { + t["QueryDisksUsingFilter"] = reflect.TypeOf((*QueryDisksUsingFilter)(nil)).Elem() +} + +type QueryDisksUsingFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` + FilterId string `xml:"filterId"` + CompRes ManagedObjectReference `xml:"compRes"` +} + +func init() { + t["QueryDisksUsingFilterRequestType"] = reflect.TypeOf((*QueryDisksUsingFilterRequestType)(nil)).Elem() +} + +type QueryDisksUsingFilterResponse struct { + Returnval []VirtualDiskId `xml:"returnval"` +} + +type QueryDvsByUuid QueryDvsByUuidRequestType + +func init() { + t["QueryDvsByUuid"] = reflect.TypeOf((*QueryDvsByUuid)(nil)).Elem() +} + +type QueryDvsByUuidRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuid string `xml:"uuid"` +} + +func init() { + t["QueryDvsByUuidRequestType"] = reflect.TypeOf((*QueryDvsByUuidRequestType)(nil)).Elem() +} + +type QueryDvsByUuidResponse struct { + Returnval *ManagedObjectReference `xml:"returnval,omitempty"` +} + +type QueryDvsCheckCompatibility QueryDvsCheckCompatibilityRequestType + +func init() { + t["QueryDvsCheckCompatibility"] = reflect.TypeOf((*QueryDvsCheckCompatibility)(nil)).Elem() +} + +type QueryDvsCheckCompatibilityRequestType struct { + This ManagedObjectReference `xml:"_this"` + HostContainer DistributedVirtualSwitchManagerHostContainer `xml:"hostContainer"` + DvsProductSpec *DistributedVirtualSwitchManagerDvsProductSpec `xml:"dvsProductSpec,omitempty"` + HostFilterSpec []BaseDistributedVirtualSwitchManagerHostDvsFilterSpec `xml:"hostFilterSpec,omitempty,typeattr"` +} + +func init() { + t["QueryDvsCheckCompatibilityRequestType"] = reflect.TypeOf((*QueryDvsCheckCompatibilityRequestType)(nil)).Elem() +} + +type QueryDvsCheckCompatibilityResponse struct { + Returnval []DistributedVirtualSwitchManagerCompatibilityResult `xml:"returnval,omitempty"` +} + +type QueryDvsCompatibleHostSpec QueryDvsCompatibleHostSpecRequestType + +func init() { + t["QueryDvsCompatibleHostSpec"] = reflect.TypeOf((*QueryDvsCompatibleHostSpec)(nil)).Elem() +} + +type QueryDvsCompatibleHostSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + SwitchProductSpec *DistributedVirtualSwitchProductSpec `xml:"switchProductSpec,omitempty"` +} + +func init() { + t["QueryDvsCompatibleHostSpecRequestType"] = reflect.TypeOf((*QueryDvsCompatibleHostSpecRequestType)(nil)).Elem() +} + +type QueryDvsCompatibleHostSpecResponse struct { + Returnval []DistributedVirtualSwitchHostProductSpec `xml:"returnval,omitempty"` +} + +type QueryDvsConfigTarget QueryDvsConfigTargetRequestType + +func init() { + t["QueryDvsConfigTarget"] = reflect.TypeOf((*QueryDvsConfigTarget)(nil)).Elem() +} + +type QueryDvsConfigTargetRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Dvs *ManagedObjectReference `xml:"dvs,omitempty"` +} + +func init() { + t["QueryDvsConfigTargetRequestType"] = reflect.TypeOf((*QueryDvsConfigTargetRequestType)(nil)).Elem() +} + +type QueryDvsConfigTargetResponse struct { + Returnval DVSManagerDvsConfigTarget `xml:"returnval"` +} + +type QueryDvsFeatureCapability QueryDvsFeatureCapabilityRequestType + +func init() { + t["QueryDvsFeatureCapability"] = reflect.TypeOf((*QueryDvsFeatureCapability)(nil)).Elem() +} + +type QueryDvsFeatureCapabilityRequestType struct { + This ManagedObjectReference `xml:"_this"` + SwitchProductSpec *DistributedVirtualSwitchProductSpec `xml:"switchProductSpec,omitempty"` +} + +func init() { + t["QueryDvsFeatureCapabilityRequestType"] = reflect.TypeOf((*QueryDvsFeatureCapabilityRequestType)(nil)).Elem() +} + +type QueryDvsFeatureCapabilityResponse struct { + Returnval BaseDVSFeatureCapability `xml:"returnval,omitempty,typeattr"` +} + +type QueryEvents QueryEventsRequestType + +func init() { + t["QueryEvents"] = reflect.TypeOf((*QueryEvents)(nil)).Elem() +} + +type QueryEventsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Filter EventFilterSpec `xml:"filter"` +} + +func init() { + t["QueryEventsRequestType"] = reflect.TypeOf((*QueryEventsRequestType)(nil)).Elem() +} + +type QueryEventsResponse struct { + Returnval []BaseEvent `xml:"returnval,omitempty,typeattr"` +} + +type QueryExpressionMetadata QueryExpressionMetadataRequestType + +func init() { + t["QueryExpressionMetadata"] = reflect.TypeOf((*QueryExpressionMetadata)(nil)).Elem() +} + +type QueryExpressionMetadataRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExpressionName []string `xml:"expressionName,omitempty"` + Profile *ManagedObjectReference `xml:"profile,omitempty"` +} + +func init() { + t["QueryExpressionMetadataRequestType"] = reflect.TypeOf((*QueryExpressionMetadataRequestType)(nil)).Elem() +} + +type QueryExpressionMetadataResponse struct { + Returnval []ProfileExpressionMetadata `xml:"returnval,omitempty"` +} + +type QueryExtensionIpAllocationUsage QueryExtensionIpAllocationUsageRequestType + +func init() { + t["QueryExtensionIpAllocationUsage"] = reflect.TypeOf((*QueryExtensionIpAllocationUsage)(nil)).Elem() +} + +type QueryExtensionIpAllocationUsageRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKeys []string `xml:"extensionKeys,omitempty"` +} + +func init() { + t["QueryExtensionIpAllocationUsageRequestType"] = reflect.TypeOf((*QueryExtensionIpAllocationUsageRequestType)(nil)).Elem() +} + +type QueryExtensionIpAllocationUsageResponse struct { + Returnval []ExtensionManagerIpAllocationUsage `xml:"returnval,omitempty"` +} + +type QueryFaultToleranceCompatibility QueryFaultToleranceCompatibilityRequestType + +func init() { + t["QueryFaultToleranceCompatibility"] = reflect.TypeOf((*QueryFaultToleranceCompatibility)(nil)).Elem() +} + +type QueryFaultToleranceCompatibilityEx QueryFaultToleranceCompatibilityExRequestType + +func init() { + t["QueryFaultToleranceCompatibilityEx"] = reflect.TypeOf((*QueryFaultToleranceCompatibilityEx)(nil)).Elem() +} + +type QueryFaultToleranceCompatibilityExRequestType struct { + This ManagedObjectReference `xml:"_this"` + ForLegacyFt *bool `xml:"forLegacyFt"` +} + +func init() { + t["QueryFaultToleranceCompatibilityExRequestType"] = reflect.TypeOf((*QueryFaultToleranceCompatibilityExRequestType)(nil)).Elem() +} + +type QueryFaultToleranceCompatibilityExResponse struct { + Returnval []LocalizedMethodFault `xml:"returnval,omitempty"` +} + +type QueryFaultToleranceCompatibilityRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryFaultToleranceCompatibilityRequestType"] = reflect.TypeOf((*QueryFaultToleranceCompatibilityRequestType)(nil)).Elem() +} + +type QueryFaultToleranceCompatibilityResponse struct { + Returnval []LocalizedMethodFault `xml:"returnval,omitempty"` +} + +type QueryFirmwareConfigUploadURL QueryFirmwareConfigUploadURLRequestType + +func init() { + t["QueryFirmwareConfigUploadURL"] = reflect.TypeOf((*QueryFirmwareConfigUploadURL)(nil)).Elem() +} + +type QueryFirmwareConfigUploadURLRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryFirmwareConfigUploadURLRequestType"] = reflect.TypeOf((*QueryFirmwareConfigUploadURLRequestType)(nil)).Elem() +} + +type QueryFirmwareConfigUploadURLResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryHostConnectionInfo QueryHostConnectionInfoRequestType + +func init() { + t["QueryHostConnectionInfo"] = reflect.TypeOf((*QueryHostConnectionInfo)(nil)).Elem() +} + +type QueryHostConnectionInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryHostConnectionInfoRequestType"] = reflect.TypeOf((*QueryHostConnectionInfoRequestType)(nil)).Elem() +} + +type QueryHostConnectionInfoResponse struct { + Returnval HostConnectInfo `xml:"returnval"` +} + +type QueryHostPatchRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec *HostPatchManagerPatchManagerOperationSpec `xml:"spec,omitempty"` +} + +func init() { + t["QueryHostPatchRequestType"] = reflect.TypeOf((*QueryHostPatchRequestType)(nil)).Elem() +} + +type QueryHostPatch_Task QueryHostPatchRequestType + +func init() { + t["QueryHostPatch_Task"] = reflect.TypeOf((*QueryHostPatch_Task)(nil)).Elem() +} + +type QueryHostPatch_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type QueryHostProfileMetadata QueryHostProfileMetadataRequestType + +func init() { + t["QueryHostProfileMetadata"] = reflect.TypeOf((*QueryHostProfileMetadata)(nil)).Elem() +} + +type QueryHostProfileMetadataRequestType struct { + This ManagedObjectReference `xml:"_this"` + ProfileName []string `xml:"profileName,omitempty"` + Profile *ManagedObjectReference `xml:"profile,omitempty"` +} + +func init() { + t["QueryHostProfileMetadataRequestType"] = reflect.TypeOf((*QueryHostProfileMetadataRequestType)(nil)).Elem() +} + +type QueryHostProfileMetadataResponse struct { + Returnval []ProfileMetadata `xml:"returnval,omitempty"` +} + +type QueryHostStatus QueryHostStatusRequestType + +func init() { + t["QueryHostStatus"] = reflect.TypeOf((*QueryHostStatus)(nil)).Elem() +} + +type QueryHostStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryHostStatusRequestType"] = reflect.TypeOf((*QueryHostStatusRequestType)(nil)).Elem() +} + +type QueryHostStatusResponse struct { + Returnval VsanHostClusterStatus `xml:"returnval"` +} + +type QueryIORMConfigOption QueryIORMConfigOptionRequestType + +func init() { + t["QueryIORMConfigOption"] = reflect.TypeOf((*QueryIORMConfigOption)(nil)).Elem() +} + +type QueryIORMConfigOptionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["QueryIORMConfigOptionRequestType"] = reflect.TypeOf((*QueryIORMConfigOptionRequestType)(nil)).Elem() +} + +type QueryIORMConfigOptionResponse struct { + Returnval StorageIORMConfigOption `xml:"returnval"` +} + +type QueryIPAllocations QueryIPAllocationsRequestType + +func init() { + t["QueryIPAllocations"] = reflect.TypeOf((*QueryIPAllocations)(nil)).Elem() +} + +type QueryIPAllocationsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + PoolId int32 `xml:"poolId"` + ExtensionKey string `xml:"extensionKey"` +} + +func init() { + t["QueryIPAllocationsRequestType"] = reflect.TypeOf((*QueryIPAllocationsRequestType)(nil)).Elem() +} + +type QueryIPAllocationsResponse struct { + Returnval []IpPoolManagerIpAllocation `xml:"returnval"` +} + +type QueryIoFilterInfo QueryIoFilterInfoRequestType + +func init() { + t["QueryIoFilterInfo"] = reflect.TypeOf((*QueryIoFilterInfo)(nil)).Elem() +} + +type QueryIoFilterInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` + CompRes ManagedObjectReference `xml:"compRes"` +} + +func init() { + t["QueryIoFilterInfoRequestType"] = reflect.TypeOf((*QueryIoFilterInfoRequestType)(nil)).Elem() +} + +type QueryIoFilterInfoResponse struct { + Returnval []ClusterIoFilterInfo `xml:"returnval,omitempty"` +} + +type QueryIoFilterIssues QueryIoFilterIssuesRequestType + +func init() { + t["QueryIoFilterIssues"] = reflect.TypeOf((*QueryIoFilterIssues)(nil)).Elem() +} + +type QueryIoFilterIssuesRequestType struct { + This ManagedObjectReference `xml:"_this"` + FilterId string `xml:"filterId"` + CompRes ManagedObjectReference `xml:"compRes"` +} + +func init() { + t["QueryIoFilterIssuesRequestType"] = reflect.TypeOf((*QueryIoFilterIssuesRequestType)(nil)).Elem() +} + +type QueryIoFilterIssuesResponse struct { + Returnval IoFilterQueryIssueResult `xml:"returnval"` +} + +type QueryIpPools QueryIpPoolsRequestType + +func init() { + t["QueryIpPools"] = reflect.TypeOf((*QueryIpPools)(nil)).Elem() +} + +type QueryIpPoolsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` +} + +func init() { + t["QueryIpPoolsRequestType"] = reflect.TypeOf((*QueryIpPoolsRequestType)(nil)).Elem() +} + +type QueryIpPoolsResponse struct { + Returnval []IpPool `xml:"returnval,omitempty"` +} + +type QueryLicenseSourceAvailability QueryLicenseSourceAvailabilityRequestType + +func init() { + t["QueryLicenseSourceAvailability"] = reflect.TypeOf((*QueryLicenseSourceAvailability)(nil)).Elem() +} + +type QueryLicenseSourceAvailabilityRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QueryLicenseSourceAvailabilityRequestType"] = reflect.TypeOf((*QueryLicenseSourceAvailabilityRequestType)(nil)).Elem() +} + +type QueryLicenseSourceAvailabilityResponse struct { + Returnval []LicenseAvailabilityInfo `xml:"returnval,omitempty"` +} + +type QueryLicenseUsage QueryLicenseUsageRequestType + +func init() { + t["QueryLicenseUsage"] = reflect.TypeOf((*QueryLicenseUsage)(nil)).Elem() +} + +type QueryLicenseUsageRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QueryLicenseUsageRequestType"] = reflect.TypeOf((*QueryLicenseUsageRequestType)(nil)).Elem() +} + +type QueryLicenseUsageResponse struct { + Returnval LicenseUsageInfo `xml:"returnval"` +} + +type QueryLockdownExceptions QueryLockdownExceptionsRequestType + +func init() { + t["QueryLockdownExceptions"] = reflect.TypeOf((*QueryLockdownExceptions)(nil)).Elem() +} + +type QueryLockdownExceptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryLockdownExceptionsRequestType"] = reflect.TypeOf((*QueryLockdownExceptionsRequestType)(nil)).Elem() +} + +type QueryLockdownExceptionsResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type QueryManagedBy QueryManagedByRequestType + +func init() { + t["QueryManagedBy"] = reflect.TypeOf((*QueryManagedBy)(nil)).Elem() +} + +type QueryManagedByRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` +} + +func init() { + t["QueryManagedByRequestType"] = reflect.TypeOf((*QueryManagedByRequestType)(nil)).Elem() +} + +type QueryManagedByResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type QueryMemoryOverhead QueryMemoryOverheadRequestType + +func init() { + t["QueryMemoryOverhead"] = reflect.TypeOf((*QueryMemoryOverhead)(nil)).Elem() +} + +type QueryMemoryOverheadEx QueryMemoryOverheadExRequestType + +func init() { + t["QueryMemoryOverheadEx"] = reflect.TypeOf((*QueryMemoryOverheadEx)(nil)).Elem() +} + +type QueryMemoryOverheadExRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmConfigInfo VirtualMachineConfigInfo `xml:"vmConfigInfo"` +} + +func init() { + t["QueryMemoryOverheadExRequestType"] = reflect.TypeOf((*QueryMemoryOverheadExRequestType)(nil)).Elem() +} + +type QueryMemoryOverheadExResponse struct { + Returnval int64 `xml:"returnval"` +} + +type QueryMemoryOverheadRequestType struct { + This ManagedObjectReference `xml:"_this"` + MemorySize int64 `xml:"memorySize"` + VideoRamSize int32 `xml:"videoRamSize,omitempty"` + NumVcpus int32 `xml:"numVcpus"` +} + +func init() { + t["QueryMemoryOverheadRequestType"] = reflect.TypeOf((*QueryMemoryOverheadRequestType)(nil)).Elem() +} + +type QueryMemoryOverheadResponse struct { + Returnval int64 `xml:"returnval"` +} + +type QueryMigrationDependencies QueryMigrationDependenciesRequestType + +func init() { + t["QueryMigrationDependencies"] = reflect.TypeOf((*QueryMigrationDependencies)(nil)).Elem() +} + +type QueryMigrationDependenciesRequestType struct { + This ManagedObjectReference `xml:"_this"` + PnicDevice []string `xml:"pnicDevice"` +} + +func init() { + t["QueryMigrationDependenciesRequestType"] = reflect.TypeOf((*QueryMigrationDependenciesRequestType)(nil)).Elem() +} + +type QueryMigrationDependenciesResponse struct { + Returnval IscsiMigrationDependency `xml:"returnval"` +} + +type QueryModules QueryModulesRequestType + +func init() { + t["QueryModules"] = reflect.TypeOf((*QueryModules)(nil)).Elem() +} + +type QueryModulesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryModulesRequestType"] = reflect.TypeOf((*QueryModulesRequestType)(nil)).Elem() +} + +type QueryModulesResponse struct { + Returnval []KernelModuleInfo `xml:"returnval,omitempty"` +} + +type QueryNFSUser QueryNFSUserRequestType + +func init() { + t["QueryNFSUser"] = reflect.TypeOf((*QueryNFSUser)(nil)).Elem() +} + +type QueryNFSUserRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryNFSUserRequestType"] = reflect.TypeOf((*QueryNFSUserRequestType)(nil)).Elem() +} + +type QueryNFSUserResponse struct { + Returnval *HostNasVolumeUserInfo `xml:"returnval,omitempty"` +} + +type QueryNetConfig QueryNetConfigRequestType + +func init() { + t["QueryNetConfig"] = reflect.TypeOf((*QueryNetConfig)(nil)).Elem() +} + +type QueryNetConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + NicType string `xml:"nicType"` +} + +func init() { + t["QueryNetConfigRequestType"] = reflect.TypeOf((*QueryNetConfigRequestType)(nil)).Elem() +} + +type QueryNetConfigResponse struct { + Returnval *VirtualNicManagerNetConfig `xml:"returnval,omitempty"` +} + +type QueryNetworkHint QueryNetworkHintRequestType + +func init() { + t["QueryNetworkHint"] = reflect.TypeOf((*QueryNetworkHint)(nil)).Elem() +} + +type QueryNetworkHintRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device []string `xml:"device,omitempty"` +} + +func init() { + t["QueryNetworkHintRequestType"] = reflect.TypeOf((*QueryNetworkHintRequestType)(nil)).Elem() +} + +type QueryNetworkHintResponse struct { + Returnval []PhysicalNicHintInfo `xml:"returnval,omitempty"` +} + +type QueryObjectsOnPhysicalVsanDisk QueryObjectsOnPhysicalVsanDiskRequestType + +func init() { + t["QueryObjectsOnPhysicalVsanDisk"] = reflect.TypeOf((*QueryObjectsOnPhysicalVsanDisk)(nil)).Elem() +} + +type QueryObjectsOnPhysicalVsanDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Disks []string `xml:"disks"` +} + +func init() { + t["QueryObjectsOnPhysicalVsanDiskRequestType"] = reflect.TypeOf((*QueryObjectsOnPhysicalVsanDiskRequestType)(nil)).Elem() +} + +type QueryObjectsOnPhysicalVsanDiskResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryOptions QueryOptionsRequestType + +func init() { + t["QueryOptions"] = reflect.TypeOf((*QueryOptions)(nil)).Elem() +} + +type QueryOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name,omitempty"` +} + +func init() { + t["QueryOptionsRequestType"] = reflect.TypeOf((*QueryOptionsRequestType)(nil)).Elem() +} + +type QueryOptionsResponse struct { + Returnval []BaseOptionValue `xml:"returnval,omitempty,typeattr"` +} + +type QueryPartitionCreateDesc QueryPartitionCreateDescRequestType + +func init() { + t["QueryPartitionCreateDesc"] = reflect.TypeOf((*QueryPartitionCreateDesc)(nil)).Elem() +} + +type QueryPartitionCreateDescRequestType struct { + This ManagedObjectReference `xml:"_this"` + DiskUuid string `xml:"diskUuid"` + DiagnosticType string `xml:"diagnosticType"` +} + +func init() { + t["QueryPartitionCreateDescRequestType"] = reflect.TypeOf((*QueryPartitionCreateDescRequestType)(nil)).Elem() +} + +type QueryPartitionCreateDescResponse struct { + Returnval HostDiagnosticPartitionCreateDescription `xml:"returnval"` +} + +type QueryPartitionCreateOptions QueryPartitionCreateOptionsRequestType + +func init() { + t["QueryPartitionCreateOptions"] = reflect.TypeOf((*QueryPartitionCreateOptions)(nil)).Elem() +} + +type QueryPartitionCreateOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + StorageType string `xml:"storageType"` + DiagnosticType string `xml:"diagnosticType"` +} + +func init() { + t["QueryPartitionCreateOptionsRequestType"] = reflect.TypeOf((*QueryPartitionCreateOptionsRequestType)(nil)).Elem() +} + +type QueryPartitionCreateOptionsResponse struct { + Returnval []HostDiagnosticPartitionCreateOption `xml:"returnval,omitempty"` +} + +type QueryPathSelectionPolicyOptions QueryPathSelectionPolicyOptionsRequestType + +func init() { + t["QueryPathSelectionPolicyOptions"] = reflect.TypeOf((*QueryPathSelectionPolicyOptions)(nil)).Elem() +} + +type QueryPathSelectionPolicyOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryPathSelectionPolicyOptionsRequestType"] = reflect.TypeOf((*QueryPathSelectionPolicyOptionsRequestType)(nil)).Elem() +} + +type QueryPathSelectionPolicyOptionsResponse struct { + Returnval []HostPathSelectionPolicyOption `xml:"returnval,omitempty"` +} + +type QueryPerf QueryPerfRequestType + +func init() { + t["QueryPerf"] = reflect.TypeOf((*QueryPerf)(nil)).Elem() +} + +type QueryPerfComposite QueryPerfCompositeRequestType + +func init() { + t["QueryPerfComposite"] = reflect.TypeOf((*QueryPerfComposite)(nil)).Elem() +} + +type QueryPerfCompositeRequestType struct { + This ManagedObjectReference `xml:"_this"` + QuerySpec PerfQuerySpec `xml:"querySpec"` +} + +func init() { + t["QueryPerfCompositeRequestType"] = reflect.TypeOf((*QueryPerfCompositeRequestType)(nil)).Elem() +} + +type QueryPerfCompositeResponse struct { + Returnval PerfCompositeMetric `xml:"returnval"` +} + +type QueryPerfCounter QueryPerfCounterRequestType + +func init() { + t["QueryPerfCounter"] = reflect.TypeOf((*QueryPerfCounter)(nil)).Elem() +} + +type QueryPerfCounterByLevel QueryPerfCounterByLevelRequestType + +func init() { + t["QueryPerfCounterByLevel"] = reflect.TypeOf((*QueryPerfCounterByLevel)(nil)).Elem() +} + +type QueryPerfCounterByLevelRequestType struct { + This ManagedObjectReference `xml:"_this"` + Level int32 `xml:"level"` +} + +func init() { + t["QueryPerfCounterByLevelRequestType"] = reflect.TypeOf((*QueryPerfCounterByLevelRequestType)(nil)).Elem() +} + +type QueryPerfCounterByLevelResponse struct { + Returnval []PerfCounterInfo `xml:"returnval"` +} + +type QueryPerfCounterRequestType struct { + This ManagedObjectReference `xml:"_this"` + CounterId []int32 `xml:"counterId"` +} + +func init() { + t["QueryPerfCounterRequestType"] = reflect.TypeOf((*QueryPerfCounterRequestType)(nil)).Elem() +} + +type QueryPerfCounterResponse struct { + Returnval []PerfCounterInfo `xml:"returnval,omitempty"` +} + +type QueryPerfProviderSummary QueryPerfProviderSummaryRequestType + +func init() { + t["QueryPerfProviderSummary"] = reflect.TypeOf((*QueryPerfProviderSummary)(nil)).Elem() +} + +type QueryPerfProviderSummaryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["QueryPerfProviderSummaryRequestType"] = reflect.TypeOf((*QueryPerfProviderSummaryRequestType)(nil)).Elem() +} + +type QueryPerfProviderSummaryResponse struct { + Returnval PerfProviderSummary `xml:"returnval"` +} + +type QueryPerfRequestType struct { + This ManagedObjectReference `xml:"_this"` + QuerySpec []PerfQuerySpec `xml:"querySpec"` +} + +func init() { + t["QueryPerfRequestType"] = reflect.TypeOf((*QueryPerfRequestType)(nil)).Elem() +} + +type QueryPerfResponse struct { + Returnval []BasePerfEntityMetricBase `xml:"returnval,omitempty,typeattr"` +} + +type QueryPhysicalVsanDisks QueryPhysicalVsanDisksRequestType + +func init() { + t["QueryPhysicalVsanDisks"] = reflect.TypeOf((*QueryPhysicalVsanDisks)(nil)).Elem() +} + +type QueryPhysicalVsanDisksRequestType struct { + This ManagedObjectReference `xml:"_this"` + Props []string `xml:"props,omitempty"` +} + +func init() { + t["QueryPhysicalVsanDisksRequestType"] = reflect.TypeOf((*QueryPhysicalVsanDisksRequestType)(nil)).Elem() +} + +type QueryPhysicalVsanDisksResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryPnicStatus QueryPnicStatusRequestType + +func init() { + t["QueryPnicStatus"] = reflect.TypeOf((*QueryPnicStatus)(nil)).Elem() +} + +type QueryPnicStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + PnicDevice string `xml:"pnicDevice"` +} + +func init() { + t["QueryPnicStatusRequestType"] = reflect.TypeOf((*QueryPnicStatusRequestType)(nil)).Elem() +} + +type QueryPnicStatusResponse struct { + Returnval IscsiStatus `xml:"returnval"` +} + +type QueryPolicyMetadata QueryPolicyMetadataRequestType + +func init() { + t["QueryPolicyMetadata"] = reflect.TypeOf((*QueryPolicyMetadata)(nil)).Elem() +} + +type QueryPolicyMetadataRequestType struct { + This ManagedObjectReference `xml:"_this"` + PolicyName []string `xml:"policyName,omitempty"` + Profile *ManagedObjectReference `xml:"profile,omitempty"` +} + +func init() { + t["QueryPolicyMetadataRequestType"] = reflect.TypeOf((*QueryPolicyMetadataRequestType)(nil)).Elem() +} + +type QueryPolicyMetadataResponse struct { + Returnval []ProfilePolicyMetadata `xml:"returnval,omitempty"` +} + +type QueryProfileStructure QueryProfileStructureRequestType + +func init() { + t["QueryProfileStructure"] = reflect.TypeOf((*QueryProfileStructure)(nil)).Elem() +} + +type QueryProfileStructureRequestType struct { + This ManagedObjectReference `xml:"_this"` + Profile *ManagedObjectReference `xml:"profile,omitempty"` +} + +func init() { + t["QueryProfileStructureRequestType"] = reflect.TypeOf((*QueryProfileStructureRequestType)(nil)).Elem() +} + +type QueryProfileStructureResponse struct { + Returnval ProfileProfileStructure `xml:"returnval"` +} + +type QueryResourceConfigOption QueryResourceConfigOptionRequestType + +func init() { + t["QueryResourceConfigOption"] = reflect.TypeOf((*QueryResourceConfigOption)(nil)).Elem() +} + +type QueryResourceConfigOptionRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryResourceConfigOptionRequestType"] = reflect.TypeOf((*QueryResourceConfigOptionRequestType)(nil)).Elem() +} + +type QueryResourceConfigOptionResponse struct { + Returnval ResourceConfigOption `xml:"returnval"` +} + +type QueryServiceList QueryServiceListRequestType + +func init() { + t["QueryServiceList"] = reflect.TypeOf((*QueryServiceList)(nil)).Elem() +} + +type QueryServiceListRequestType struct { + This ManagedObjectReference `xml:"_this"` + ServiceName string `xml:"serviceName,omitempty"` + Location []string `xml:"location,omitempty"` +} + +func init() { + t["QueryServiceListRequestType"] = reflect.TypeOf((*QueryServiceListRequestType)(nil)).Elem() +} + +type QueryServiceListResponse struct { + Returnval []ServiceManagerServiceInfo `xml:"returnval,omitempty"` +} + +type QueryStorageArrayTypePolicyOptions QueryStorageArrayTypePolicyOptionsRequestType + +func init() { + t["QueryStorageArrayTypePolicyOptions"] = reflect.TypeOf((*QueryStorageArrayTypePolicyOptions)(nil)).Elem() +} + +type QueryStorageArrayTypePolicyOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryStorageArrayTypePolicyOptionsRequestType"] = reflect.TypeOf((*QueryStorageArrayTypePolicyOptionsRequestType)(nil)).Elem() +} + +type QueryStorageArrayTypePolicyOptionsResponse struct { + Returnval []HostStorageArrayTypePolicyOption `xml:"returnval,omitempty"` +} + +type QuerySupportedFeatures QuerySupportedFeaturesRequestType + +func init() { + t["QuerySupportedFeatures"] = reflect.TypeOf((*QuerySupportedFeatures)(nil)).Elem() +} + +type QuerySupportedFeaturesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QuerySupportedFeaturesRequestType"] = reflect.TypeOf((*QuerySupportedFeaturesRequestType)(nil)).Elem() +} + +type QuerySupportedFeaturesResponse struct { + Returnval []LicenseFeatureInfo `xml:"returnval,omitempty"` +} + +type QuerySyncingVsanObjects QuerySyncingVsanObjectsRequestType + +func init() { + t["QuerySyncingVsanObjects"] = reflect.TypeOf((*QuerySyncingVsanObjects)(nil)).Elem() +} + +type QuerySyncingVsanObjectsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids,omitempty"` +} + +func init() { + t["QuerySyncingVsanObjectsRequestType"] = reflect.TypeOf((*QuerySyncingVsanObjectsRequestType)(nil)).Elem() +} + +type QuerySyncingVsanObjectsResponse struct { + Returnval string `xml:"returnval"` +} + +type QuerySystemUsers QuerySystemUsersRequestType + +func init() { + t["QuerySystemUsers"] = reflect.TypeOf((*QuerySystemUsers)(nil)).Elem() +} + +type QuerySystemUsersRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QuerySystemUsersRequestType"] = reflect.TypeOf((*QuerySystemUsersRequestType)(nil)).Elem() +} + +type QuerySystemUsersResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type QueryTargetCapabilities QueryTargetCapabilitiesRequestType + +func init() { + t["QueryTargetCapabilities"] = reflect.TypeOf((*QueryTargetCapabilities)(nil)).Elem() +} + +type QueryTargetCapabilitiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["QueryTargetCapabilitiesRequestType"] = reflect.TypeOf((*QueryTargetCapabilitiesRequestType)(nil)).Elem() +} + +type QueryTargetCapabilitiesResponse struct { + Returnval *HostCapability `xml:"returnval,omitempty"` +} + +type QueryTpmAttestationReport QueryTpmAttestationReportRequestType + +func init() { + t["QueryTpmAttestationReport"] = reflect.TypeOf((*QueryTpmAttestationReport)(nil)).Elem() +} + +type QueryTpmAttestationReportRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryTpmAttestationReportRequestType"] = reflect.TypeOf((*QueryTpmAttestationReportRequestType)(nil)).Elem() +} + +type QueryTpmAttestationReportResponse struct { + Returnval *HostTpmAttestationReport `xml:"returnval,omitempty"` +} + +type QueryUnownedFiles QueryUnownedFilesRequestType + +func init() { + t["QueryUnownedFiles"] = reflect.TypeOf((*QueryUnownedFiles)(nil)).Elem() +} + +type QueryUnownedFilesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryUnownedFilesRequestType"] = reflect.TypeOf((*QueryUnownedFilesRequestType)(nil)).Elem() +} + +type QueryUnownedFilesResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type QueryUnresolvedVmfsVolume QueryUnresolvedVmfsVolumeRequestType + +func init() { + t["QueryUnresolvedVmfsVolume"] = reflect.TypeOf((*QueryUnresolvedVmfsVolume)(nil)).Elem() +} + +type QueryUnresolvedVmfsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryUnresolvedVmfsVolumeRequestType"] = reflect.TypeOf((*QueryUnresolvedVmfsVolumeRequestType)(nil)).Elem() +} + +type QueryUnresolvedVmfsVolumeResponse struct { + Returnval []HostUnresolvedVmfsVolume `xml:"returnval,omitempty"` +} + +type QueryUnresolvedVmfsVolumes QueryUnresolvedVmfsVolumesRequestType + +func init() { + t["QueryUnresolvedVmfsVolumes"] = reflect.TypeOf((*QueryUnresolvedVmfsVolumes)(nil)).Elem() +} + +type QueryUnresolvedVmfsVolumesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryUnresolvedVmfsVolumesRequestType"] = reflect.TypeOf((*QueryUnresolvedVmfsVolumesRequestType)(nil)).Elem() +} + +type QueryUnresolvedVmfsVolumesResponse struct { + Returnval []HostUnresolvedVmfsVolume `xml:"returnval,omitempty"` +} + +type QueryUsedVlanIdInDvs QueryUsedVlanIdInDvsRequestType + +func init() { + t["QueryUsedVlanIdInDvs"] = reflect.TypeOf((*QueryUsedVlanIdInDvs)(nil)).Elem() +} + +type QueryUsedVlanIdInDvsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["QueryUsedVlanIdInDvsRequestType"] = reflect.TypeOf((*QueryUsedVlanIdInDvsRequestType)(nil)).Elem() +} + +type QueryUsedVlanIdInDvsResponse struct { + Returnval []int32 `xml:"returnval,omitempty"` +} + +type QueryVMotionCompatibility QueryVMotionCompatibilityRequestType + +func init() { + t["QueryVMotionCompatibility"] = reflect.TypeOf((*QueryVMotionCompatibility)(nil)).Elem() +} + +type QueryVMotionCompatibilityExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm []ManagedObjectReference `xml:"vm"` + Host []ManagedObjectReference `xml:"host"` +} + +func init() { + t["QueryVMotionCompatibilityExRequestType"] = reflect.TypeOf((*QueryVMotionCompatibilityExRequestType)(nil)).Elem() +} + +type QueryVMotionCompatibilityEx_Task QueryVMotionCompatibilityExRequestType + +func init() { + t["QueryVMotionCompatibilityEx_Task"] = reflect.TypeOf((*QueryVMotionCompatibilityEx_Task)(nil)).Elem() +} + +type QueryVMotionCompatibilityEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type QueryVMotionCompatibilityRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Host []ManagedObjectReference `xml:"host"` + Compatibility []string `xml:"compatibility,omitempty"` +} + +func init() { + t["QueryVMotionCompatibilityRequestType"] = reflect.TypeOf((*QueryVMotionCompatibilityRequestType)(nil)).Elem() +} + +type QueryVMotionCompatibilityResponse struct { + Returnval []HostVMotionCompatibility `xml:"returnval,omitempty"` +} + +type QueryVirtualDiskFragmentation QueryVirtualDiskFragmentationRequestType + +func init() { + t["QueryVirtualDiskFragmentation"] = reflect.TypeOf((*QueryVirtualDiskFragmentation)(nil)).Elem() +} + +type QueryVirtualDiskFragmentationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["QueryVirtualDiskFragmentationRequestType"] = reflect.TypeOf((*QueryVirtualDiskFragmentationRequestType)(nil)).Elem() +} + +type QueryVirtualDiskFragmentationResponse struct { + Returnval int32 `xml:"returnval"` +} + +type QueryVirtualDiskGeometry QueryVirtualDiskGeometryRequestType + +func init() { + t["QueryVirtualDiskGeometry"] = reflect.TypeOf((*QueryVirtualDiskGeometry)(nil)).Elem() +} + +type QueryVirtualDiskGeometryRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["QueryVirtualDiskGeometryRequestType"] = reflect.TypeOf((*QueryVirtualDiskGeometryRequestType)(nil)).Elem() +} + +type QueryVirtualDiskGeometryResponse struct { + Returnval HostDiskDimensionsChs `xml:"returnval"` +} + +type QueryVirtualDiskUuid QueryVirtualDiskUuidRequestType + +func init() { + t["QueryVirtualDiskUuid"] = reflect.TypeOf((*QueryVirtualDiskUuid)(nil)).Elem() +} + +type QueryVirtualDiskUuidRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["QueryVirtualDiskUuidRequestType"] = reflect.TypeOf((*QueryVirtualDiskUuidRequestType)(nil)).Elem() +} + +type QueryVirtualDiskUuidResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryVmfsDatastoreCreateOptions QueryVmfsDatastoreCreateOptionsRequestType + +func init() { + t["QueryVmfsDatastoreCreateOptions"] = reflect.TypeOf((*QueryVmfsDatastoreCreateOptions)(nil)).Elem() +} + +type QueryVmfsDatastoreCreateOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + DevicePath string `xml:"devicePath"` + VmfsMajorVersion int32 `xml:"vmfsMajorVersion,omitempty"` +} + +func init() { + t["QueryVmfsDatastoreCreateOptionsRequestType"] = reflect.TypeOf((*QueryVmfsDatastoreCreateOptionsRequestType)(nil)).Elem() +} + +type QueryVmfsDatastoreCreateOptionsResponse struct { + Returnval []VmfsDatastoreOption `xml:"returnval,omitempty"` +} + +type QueryVmfsDatastoreExpandOptions QueryVmfsDatastoreExpandOptionsRequestType + +func init() { + t["QueryVmfsDatastoreExpandOptions"] = reflect.TypeOf((*QueryVmfsDatastoreExpandOptions)(nil)).Elem() +} + +type QueryVmfsDatastoreExpandOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["QueryVmfsDatastoreExpandOptionsRequestType"] = reflect.TypeOf((*QueryVmfsDatastoreExpandOptionsRequestType)(nil)).Elem() +} + +type QueryVmfsDatastoreExpandOptionsResponse struct { + Returnval []VmfsDatastoreOption `xml:"returnval,omitempty"` +} + +type QueryVmfsDatastoreExtendOptions QueryVmfsDatastoreExtendOptionsRequestType + +func init() { + t["QueryVmfsDatastoreExtendOptions"] = reflect.TypeOf((*QueryVmfsDatastoreExtendOptions)(nil)).Elem() +} + +type QueryVmfsDatastoreExtendOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` + DevicePath string `xml:"devicePath"` + SuppressExpandCandidates *bool `xml:"suppressExpandCandidates"` +} + +func init() { + t["QueryVmfsDatastoreExtendOptionsRequestType"] = reflect.TypeOf((*QueryVmfsDatastoreExtendOptionsRequestType)(nil)).Elem() +} + +type QueryVmfsDatastoreExtendOptionsResponse struct { + Returnval []VmfsDatastoreOption `xml:"returnval,omitempty"` +} + +type QueryVnicStatus QueryVnicStatusRequestType + +func init() { + t["QueryVnicStatus"] = reflect.TypeOf((*QueryVnicStatus)(nil)).Elem() +} + +type QueryVnicStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + VnicDevice string `xml:"vnicDevice"` +} + +func init() { + t["QueryVnicStatusRequestType"] = reflect.TypeOf((*QueryVnicStatusRequestType)(nil)).Elem() +} + +type QueryVnicStatusResponse struct { + Returnval IscsiStatus `xml:"returnval"` +} + +type QueryVsanObjectUuidsByFilter QueryVsanObjectUuidsByFilterRequestType + +func init() { + t["QueryVsanObjectUuidsByFilter"] = reflect.TypeOf((*QueryVsanObjectUuidsByFilter)(nil)).Elem() +} + +type QueryVsanObjectUuidsByFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids,omitempty"` + Limit int32 `xml:"limit,omitempty"` + Version int32 `xml:"version,omitempty"` +} + +func init() { + t["QueryVsanObjectUuidsByFilterRequestType"] = reflect.TypeOf((*QueryVsanObjectUuidsByFilterRequestType)(nil)).Elem() +} + +type QueryVsanObjectUuidsByFilterResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type QueryVsanObjects QueryVsanObjectsRequestType + +func init() { + t["QueryVsanObjects"] = reflect.TypeOf((*QueryVsanObjects)(nil)).Elem() +} + +type QueryVsanObjectsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids,omitempty"` +} + +func init() { + t["QueryVsanObjectsRequestType"] = reflect.TypeOf((*QueryVsanObjectsRequestType)(nil)).Elem() +} + +type QueryVsanObjectsResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryVsanStatistics QueryVsanStatisticsRequestType + +func init() { + t["QueryVsanStatistics"] = reflect.TypeOf((*QueryVsanStatistics)(nil)).Elem() +} + +type QueryVsanStatisticsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Labels []string `xml:"labels"` +} + +func init() { + t["QueryVsanStatisticsRequestType"] = reflect.TypeOf((*QueryVsanStatisticsRequestType)(nil)).Elem() +} + +type QueryVsanStatisticsResponse struct { + Returnval string `xml:"returnval"` +} + +type QueryVsanUpgradeStatus QueryVsanUpgradeStatusRequestType + +func init() { + t["QueryVsanUpgradeStatus"] = reflect.TypeOf((*QueryVsanUpgradeStatus)(nil)).Elem() +} + +type QueryVsanUpgradeStatusRequestType struct { + This ManagedObjectReference `xml:"_this"` + Cluster ManagedObjectReference `xml:"cluster"` +} + +func init() { + t["QueryVsanUpgradeStatusRequestType"] = reflect.TypeOf((*QueryVsanUpgradeStatusRequestType)(nil)).Elem() +} + +type QueryVsanUpgradeStatusResponse struct { + Returnval VsanUpgradeSystemUpgradeStatus `xml:"returnval"` +} + +type QuestionPending struct { + InvalidState + + Text string `xml:"text"` +} + +func init() { + t["QuestionPending"] = reflect.TypeOf((*QuestionPending)(nil)).Elem() +} + +type QuestionPendingFault QuestionPending + +func init() { + t["QuestionPendingFault"] = reflect.TypeOf((*QuestionPendingFault)(nil)).Elem() +} + +type QuiesceDatastoreIOForHAFailed struct { + ResourceInUse + + Host ManagedObjectReference `xml:"host"` + HostName string `xml:"hostName"` + Ds ManagedObjectReference `xml:"ds"` + DsName string `xml:"dsName"` +} + +func init() { + t["QuiesceDatastoreIOForHAFailed"] = reflect.TypeOf((*QuiesceDatastoreIOForHAFailed)(nil)).Elem() +} + +type QuiesceDatastoreIOForHAFailedFault QuiesceDatastoreIOForHAFailed + +func init() { + t["QuiesceDatastoreIOForHAFailedFault"] = reflect.TypeOf((*QuiesceDatastoreIOForHAFailedFault)(nil)).Elem() +} + +type RDMConversionNotSupported struct { + MigrationFault + + Device string `xml:"device"` +} + +func init() { + t["RDMConversionNotSupported"] = reflect.TypeOf((*RDMConversionNotSupported)(nil)).Elem() +} + +type RDMConversionNotSupportedFault RDMConversionNotSupported + +func init() { + t["RDMConversionNotSupportedFault"] = reflect.TypeOf((*RDMConversionNotSupportedFault)(nil)).Elem() +} + +type RDMNotPreserved struct { + MigrationFault + + Device string `xml:"device"` +} + +func init() { + t["RDMNotPreserved"] = reflect.TypeOf((*RDMNotPreserved)(nil)).Elem() +} + +type RDMNotPreservedFault RDMNotPreserved + +func init() { + t["RDMNotPreservedFault"] = reflect.TypeOf((*RDMNotPreservedFault)(nil)).Elem() +} + +type RDMNotSupported struct { + DeviceNotSupported +} + +func init() { + t["RDMNotSupported"] = reflect.TypeOf((*RDMNotSupported)(nil)).Elem() +} + +type RDMNotSupportedFault BaseRDMNotSupported + +func init() { + t["RDMNotSupportedFault"] = reflect.TypeOf((*RDMNotSupportedFault)(nil)).Elem() +} + +type RDMNotSupportedOnDatastore struct { + VmConfigFault + + Device string `xml:"device"` + Datastore ManagedObjectReference `xml:"datastore"` + DatastoreName string `xml:"datastoreName"` +} + +func init() { + t["RDMNotSupportedOnDatastore"] = reflect.TypeOf((*RDMNotSupportedOnDatastore)(nil)).Elem() +} + +type RDMNotSupportedOnDatastoreFault RDMNotSupportedOnDatastore + +func init() { + t["RDMNotSupportedOnDatastoreFault"] = reflect.TypeOf((*RDMNotSupportedOnDatastoreFault)(nil)).Elem() +} + +type RDMPointsToInaccessibleDisk struct { + CannotAccessVmDisk +} + +func init() { + t["RDMPointsToInaccessibleDisk"] = reflect.TypeOf((*RDMPointsToInaccessibleDisk)(nil)).Elem() +} + +type RDMPointsToInaccessibleDiskFault RDMPointsToInaccessibleDisk + +func init() { + t["RDMPointsToInaccessibleDiskFault"] = reflect.TypeOf((*RDMPointsToInaccessibleDiskFault)(nil)).Elem() +} + +type RawDiskNotSupported struct { + DeviceNotSupported +} + +func init() { + t["RawDiskNotSupported"] = reflect.TypeOf((*RawDiskNotSupported)(nil)).Elem() +} + +type RawDiskNotSupportedFault RawDiskNotSupported + +func init() { + t["RawDiskNotSupportedFault"] = reflect.TypeOf((*RawDiskNotSupportedFault)(nil)).Elem() +} + +type ReadEnvironmentVariableInGuest ReadEnvironmentVariableInGuestRequestType + +func init() { + t["ReadEnvironmentVariableInGuest"] = reflect.TypeOf((*ReadEnvironmentVariableInGuest)(nil)).Elem() +} + +type ReadEnvironmentVariableInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Names []string `xml:"names,omitempty"` +} + +func init() { + t["ReadEnvironmentVariableInGuestRequestType"] = reflect.TypeOf((*ReadEnvironmentVariableInGuestRequestType)(nil)).Elem() +} + +type ReadEnvironmentVariableInGuestResponse struct { + Returnval []string `xml:"returnval,omitempty"` +} + +type ReadHostResourcePoolTreeFailed struct { + HostConnectFault +} + +func init() { + t["ReadHostResourcePoolTreeFailed"] = reflect.TypeOf((*ReadHostResourcePoolTreeFailed)(nil)).Elem() +} + +type ReadHostResourcePoolTreeFailedFault ReadHostResourcePoolTreeFailed + +func init() { + t["ReadHostResourcePoolTreeFailedFault"] = reflect.TypeOf((*ReadHostResourcePoolTreeFailedFault)(nil)).Elem() +} + +type ReadNextEvents ReadNextEventsRequestType + +func init() { + t["ReadNextEvents"] = reflect.TypeOf((*ReadNextEvents)(nil)).Elem() +} + +type ReadNextEventsRequestType struct { + This ManagedObjectReference `xml:"_this"` + MaxCount int32 `xml:"maxCount"` +} + +func init() { + t["ReadNextEventsRequestType"] = reflect.TypeOf((*ReadNextEventsRequestType)(nil)).Elem() +} + +type ReadNextEventsResponse struct { + Returnval []BaseEvent `xml:"returnval,omitempty,typeattr"` +} + +type ReadNextTasks ReadNextTasksRequestType + +func init() { + t["ReadNextTasks"] = reflect.TypeOf((*ReadNextTasks)(nil)).Elem() +} + +type ReadNextTasksRequestType struct { + This ManagedObjectReference `xml:"_this"` + MaxCount int32 `xml:"maxCount"` +} + +func init() { + t["ReadNextTasksRequestType"] = reflect.TypeOf((*ReadNextTasksRequestType)(nil)).Elem() +} + +type ReadNextTasksResponse struct { + Returnval []TaskInfo `xml:"returnval,omitempty"` +} + +type ReadOnlyDisksWithLegacyDestination struct { + MigrationFault + + RoDiskCount int32 `xml:"roDiskCount"` + TimeoutDanger bool `xml:"timeoutDanger"` +} + +func init() { + t["ReadOnlyDisksWithLegacyDestination"] = reflect.TypeOf((*ReadOnlyDisksWithLegacyDestination)(nil)).Elem() +} + +type ReadOnlyDisksWithLegacyDestinationFault ReadOnlyDisksWithLegacyDestination + +func init() { + t["ReadOnlyDisksWithLegacyDestinationFault"] = reflect.TypeOf((*ReadOnlyDisksWithLegacyDestinationFault)(nil)).Elem() +} + +type ReadPreviousEvents ReadPreviousEventsRequestType + +func init() { + t["ReadPreviousEvents"] = reflect.TypeOf((*ReadPreviousEvents)(nil)).Elem() +} + +type ReadPreviousEventsRequestType struct { + This ManagedObjectReference `xml:"_this"` + MaxCount int32 `xml:"maxCount"` +} + +func init() { + t["ReadPreviousEventsRequestType"] = reflect.TypeOf((*ReadPreviousEventsRequestType)(nil)).Elem() +} + +type ReadPreviousEventsResponse struct { + Returnval []BaseEvent `xml:"returnval,omitempty,typeattr"` +} + +type ReadPreviousTasks ReadPreviousTasksRequestType + +func init() { + t["ReadPreviousTasks"] = reflect.TypeOf((*ReadPreviousTasks)(nil)).Elem() +} + +type ReadPreviousTasksRequestType struct { + This ManagedObjectReference `xml:"_this"` + MaxCount int32 `xml:"maxCount"` +} + +func init() { + t["ReadPreviousTasksRequestType"] = reflect.TypeOf((*ReadPreviousTasksRequestType)(nil)).Elem() +} + +type ReadPreviousTasksResponse struct { + Returnval []TaskInfo `xml:"returnval,omitempty"` +} + +type RebootGuest RebootGuestRequestType + +func init() { + t["RebootGuest"] = reflect.TypeOf((*RebootGuest)(nil)).Elem() +} + +type RebootGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RebootGuestRequestType"] = reflect.TypeOf((*RebootGuestRequestType)(nil)).Elem() +} + +type RebootGuestResponse struct { +} + +type RebootHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Force bool `xml:"force"` +} + +func init() { + t["RebootHostRequestType"] = reflect.TypeOf((*RebootHostRequestType)(nil)).Elem() +} + +type RebootHost_Task RebootHostRequestType + +func init() { + t["RebootHost_Task"] = reflect.TypeOf((*RebootHost_Task)(nil)).Elem() +} + +type RebootHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RebootRequired struct { + VimFault + + Patch string `xml:"patch,omitempty"` +} + +func init() { + t["RebootRequired"] = reflect.TypeOf((*RebootRequired)(nil)).Elem() +} + +type RebootRequiredFault RebootRequired + +func init() { + t["RebootRequiredFault"] = reflect.TypeOf((*RebootRequiredFault)(nil)).Elem() +} + +type RecommendDatastores RecommendDatastoresRequestType + +func init() { + t["RecommendDatastores"] = reflect.TypeOf((*RecommendDatastores)(nil)).Elem() +} + +type RecommendDatastoresRequestType struct { + This ManagedObjectReference `xml:"_this"` + StorageSpec StoragePlacementSpec `xml:"storageSpec"` +} + +func init() { + t["RecommendDatastoresRequestType"] = reflect.TypeOf((*RecommendDatastoresRequestType)(nil)).Elem() +} + +type RecommendDatastoresResponse struct { + Returnval StoragePlacementResult `xml:"returnval"` +} + +type RecommendHostsForVm RecommendHostsForVmRequestType + +func init() { + t["RecommendHostsForVm"] = reflect.TypeOf((*RecommendHostsForVm)(nil)).Elem() +} + +type RecommendHostsForVmRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` +} + +func init() { + t["RecommendHostsForVmRequestType"] = reflect.TypeOf((*RecommendHostsForVmRequestType)(nil)).Elem() +} + +type RecommendHostsForVmResponse struct { + Returnval []ClusterHostRecommendation `xml:"returnval,omitempty"` +} + +type RecommissionVsanNodeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RecommissionVsanNodeRequestType"] = reflect.TypeOf((*RecommissionVsanNodeRequestType)(nil)).Elem() +} + +type RecommissionVsanNode_Task RecommissionVsanNodeRequestType + +func init() { + t["RecommissionVsanNode_Task"] = reflect.TypeOf((*RecommissionVsanNode_Task)(nil)).Elem() +} + +type RecommissionVsanNode_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec VirtualMachineConfigSpec `xml:"spec"` +} + +func init() { + t["ReconfigVMRequestType"] = reflect.TypeOf((*ReconfigVMRequestType)(nil)).Elem() +} + +type ReconfigVM_Task ReconfigVMRequestType + +func init() { + t["ReconfigVM_Task"] = reflect.TypeOf((*ReconfigVM_Task)(nil)).Elem() +} + +type ReconfigVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigurationSatisfiable ReconfigurationSatisfiableRequestType + +func init() { + t["ReconfigurationSatisfiable"] = reflect.TypeOf((*ReconfigurationSatisfiable)(nil)).Elem() +} + +type ReconfigurationSatisfiableRequestType struct { + This ManagedObjectReference `xml:"_this"` + Pcbs []VsanPolicyChangeBatch `xml:"pcbs"` + IgnoreSatisfiability *bool `xml:"ignoreSatisfiability"` +} + +func init() { + t["ReconfigurationSatisfiableRequestType"] = reflect.TypeOf((*ReconfigurationSatisfiableRequestType)(nil)).Elem() +} + +type ReconfigurationSatisfiableResponse struct { + Returnval []VsanPolicySatisfiability `xml:"returnval"` +} + +type ReconfigureAlarm ReconfigureAlarmRequestType + +func init() { + t["ReconfigureAlarm"] = reflect.TypeOf((*ReconfigureAlarm)(nil)).Elem() +} + +type ReconfigureAlarmRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec BaseAlarmSpec `xml:"spec,typeattr"` +} + +func init() { + t["ReconfigureAlarmRequestType"] = reflect.TypeOf((*ReconfigureAlarmRequestType)(nil)).Elem() +} + +type ReconfigureAlarmResponse struct { +} + +type ReconfigureAutostart ReconfigureAutostartRequestType + +func init() { + t["ReconfigureAutostart"] = reflect.TypeOf((*ReconfigureAutostart)(nil)).Elem() +} + +type ReconfigureAutostartRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostAutoStartManagerConfig `xml:"spec"` +} + +func init() { + t["ReconfigureAutostartRequestType"] = reflect.TypeOf((*ReconfigureAutostartRequestType)(nil)).Elem() +} + +type ReconfigureAutostartResponse struct { +} + +type ReconfigureClusterRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec ClusterConfigSpec `xml:"spec"` + Modify bool `xml:"modify"` +} + +func init() { + t["ReconfigureClusterRequestType"] = reflect.TypeOf((*ReconfigureClusterRequestType)(nil)).Elem() +} + +type ReconfigureCluster_Task ReconfigureClusterRequestType + +func init() { + t["ReconfigureCluster_Task"] = reflect.TypeOf((*ReconfigureCluster_Task)(nil)).Elem() +} + +type ReconfigureCluster_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureComputeResourceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec BaseComputeResourceConfigSpec `xml:"spec,typeattr"` + Modify bool `xml:"modify"` +} + +func init() { + t["ReconfigureComputeResourceRequestType"] = reflect.TypeOf((*ReconfigureComputeResourceRequestType)(nil)).Elem() +} + +type ReconfigureComputeResource_Task ReconfigureComputeResourceRequestType + +func init() { + t["ReconfigureComputeResource_Task"] = reflect.TypeOf((*ReconfigureComputeResource_Task)(nil)).Elem() +} + +type ReconfigureComputeResource_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureDVPortRequestType struct { + This ManagedObjectReference `xml:"_this"` + Port []DVPortConfigSpec `xml:"port"` +} + +func init() { + t["ReconfigureDVPortRequestType"] = reflect.TypeOf((*ReconfigureDVPortRequestType)(nil)).Elem() +} + +type ReconfigureDVPort_Task ReconfigureDVPortRequestType + +func init() { + t["ReconfigureDVPort_Task"] = reflect.TypeOf((*ReconfigureDVPort_Task)(nil)).Elem() +} + +type ReconfigureDVPort_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureDVPortgroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec DVPortgroupConfigSpec `xml:"spec"` +} + +func init() { + t["ReconfigureDVPortgroupRequestType"] = reflect.TypeOf((*ReconfigureDVPortgroupRequestType)(nil)).Elem() +} + +type ReconfigureDVPortgroup_Task ReconfigureDVPortgroupRequestType + +func init() { + t["ReconfigureDVPortgroup_Task"] = reflect.TypeOf((*ReconfigureDVPortgroup_Task)(nil)).Elem() +} + +type ReconfigureDVPortgroup_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureDatacenterRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec DatacenterConfigSpec `xml:"spec"` + Modify bool `xml:"modify"` +} + +func init() { + t["ReconfigureDatacenterRequestType"] = reflect.TypeOf((*ReconfigureDatacenterRequestType)(nil)).Elem() +} + +type ReconfigureDatacenter_Task ReconfigureDatacenterRequestType + +func init() { + t["ReconfigureDatacenter_Task"] = reflect.TypeOf((*ReconfigureDatacenter_Task)(nil)).Elem() +} + +type ReconfigureDatacenter_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureDomObject ReconfigureDomObjectRequestType + +func init() { + t["ReconfigureDomObject"] = reflect.TypeOf((*ReconfigureDomObject)(nil)).Elem() +} + +type ReconfigureDomObjectRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuid string `xml:"uuid"` + Policy string `xml:"policy"` +} + +func init() { + t["ReconfigureDomObjectRequestType"] = reflect.TypeOf((*ReconfigureDomObjectRequestType)(nil)).Elem() +} + +type ReconfigureDomObjectResponse struct { +} + +type ReconfigureDvsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec BaseDVSConfigSpec `xml:"spec,typeattr"` +} + +func init() { + t["ReconfigureDvsRequestType"] = reflect.TypeOf((*ReconfigureDvsRequestType)(nil)).Elem() +} + +type ReconfigureDvs_Task ReconfigureDvsRequestType + +func init() { + t["ReconfigureDvs_Task"] = reflect.TypeOf((*ReconfigureDvs_Task)(nil)).Elem() +} + +type ReconfigureDvs_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureHostForDASRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ReconfigureHostForDASRequestType"] = reflect.TypeOf((*ReconfigureHostForDASRequestType)(nil)).Elem() +} + +type ReconfigureHostForDAS_Task ReconfigureHostForDASRequestType + +func init() { + t["ReconfigureHostForDAS_Task"] = reflect.TypeOf((*ReconfigureHostForDAS_Task)(nil)).Elem() +} + +type ReconfigureHostForDAS_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReconfigureScheduledTask ReconfigureScheduledTaskRequestType + +func init() { + t["ReconfigureScheduledTask"] = reflect.TypeOf((*ReconfigureScheduledTask)(nil)).Elem() +} + +type ReconfigureScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec BaseScheduledTaskSpec `xml:"spec,typeattr"` +} + +func init() { + t["ReconfigureScheduledTaskRequestType"] = reflect.TypeOf((*ReconfigureScheduledTaskRequestType)(nil)).Elem() +} + +type ReconfigureScheduledTaskResponse struct { +} + +type ReconfigureServiceConsoleReservation ReconfigureServiceConsoleReservationRequestType + +func init() { + t["ReconfigureServiceConsoleReservation"] = reflect.TypeOf((*ReconfigureServiceConsoleReservation)(nil)).Elem() +} + +type ReconfigureServiceConsoleReservationRequestType struct { + This ManagedObjectReference `xml:"_this"` + CfgBytes int64 `xml:"cfgBytes"` +} + +func init() { + t["ReconfigureServiceConsoleReservationRequestType"] = reflect.TypeOf((*ReconfigureServiceConsoleReservationRequestType)(nil)).Elem() +} + +type ReconfigureServiceConsoleReservationResponse struct { +} + +type ReconfigureSnmpAgent ReconfigureSnmpAgentRequestType + +func init() { + t["ReconfigureSnmpAgent"] = reflect.TypeOf((*ReconfigureSnmpAgent)(nil)).Elem() +} + +type ReconfigureSnmpAgentRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec HostSnmpConfigSpec `xml:"spec"` +} + +func init() { + t["ReconfigureSnmpAgentRequestType"] = reflect.TypeOf((*ReconfigureSnmpAgentRequestType)(nil)).Elem() +} + +type ReconfigureSnmpAgentResponse struct { +} + +type ReconfigureVirtualMachineReservation ReconfigureVirtualMachineReservationRequestType + +func init() { + t["ReconfigureVirtualMachineReservation"] = reflect.TypeOf((*ReconfigureVirtualMachineReservation)(nil)).Elem() +} + +type ReconfigureVirtualMachineReservationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec VirtualMachineMemoryReservationSpec `xml:"spec"` +} + +func init() { + t["ReconfigureVirtualMachineReservationRequestType"] = reflect.TypeOf((*ReconfigureVirtualMachineReservationRequestType)(nil)).Elem() +} + +type ReconfigureVirtualMachineReservationResponse struct { +} + +type ReconnectHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + CnxSpec *HostConnectSpec `xml:"cnxSpec,omitempty"` + ReconnectSpec *HostSystemReconnectSpec `xml:"reconnectSpec,omitempty"` +} + +func init() { + t["ReconnectHostRequestType"] = reflect.TypeOf((*ReconnectHostRequestType)(nil)).Elem() +} + +type ReconnectHost_Task ReconnectHostRequestType + +func init() { + t["ReconnectHost_Task"] = reflect.TypeOf((*ReconnectHost_Task)(nil)).Elem() +} + +type ReconnectHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RecordReplayDisabled struct { + VimFault +} + +func init() { + t["RecordReplayDisabled"] = reflect.TypeOf((*RecordReplayDisabled)(nil)).Elem() +} + +type RecordReplayDisabledFault RecordReplayDisabled + +func init() { + t["RecordReplayDisabledFault"] = reflect.TypeOf((*RecordReplayDisabledFault)(nil)).Elem() +} + +type RecoveryEvent struct { + DvsEvent + + HostName string `xml:"hostName"` + PortKey string `xml:"portKey"` + DvsUuid string `xml:"dvsUuid,omitempty"` + Vnic string `xml:"vnic,omitempty"` +} + +func init() { + t["RecoveryEvent"] = reflect.TypeOf((*RecoveryEvent)(nil)).Elem() +} + +type RectifyDvsHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Hosts []ManagedObjectReference `xml:"hosts,omitempty"` +} + +func init() { + t["RectifyDvsHostRequestType"] = reflect.TypeOf((*RectifyDvsHostRequestType)(nil)).Elem() +} + +type RectifyDvsHost_Task RectifyDvsHostRequestType + +func init() { + t["RectifyDvsHost_Task"] = reflect.TypeOf((*RectifyDvsHost_Task)(nil)).Elem() +} + +type RectifyDvsHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RectifyDvsOnHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["RectifyDvsOnHostRequestType"] = reflect.TypeOf((*RectifyDvsOnHostRequestType)(nil)).Elem() +} + +type RectifyDvsOnHost_Task RectifyDvsOnHostRequestType + +func init() { + t["RectifyDvsOnHost_Task"] = reflect.TypeOf((*RectifyDvsOnHost_Task)(nil)).Elem() +} + +type RectifyDvsOnHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RecurrentTaskScheduler struct { + TaskScheduler + + Interval int32 `xml:"interval"` +} + +func init() { + t["RecurrentTaskScheduler"] = reflect.TypeOf((*RecurrentTaskScheduler)(nil)).Elem() +} + +type Refresh RefreshRequestType + +func init() { + t["Refresh"] = reflect.TypeOf((*Refresh)(nil)).Elem() +} + +type RefreshDVPortState RefreshDVPortStateRequestType + +func init() { + t["RefreshDVPortState"] = reflect.TypeOf((*RefreshDVPortState)(nil)).Elem() +} + +type RefreshDVPortStateRequestType struct { + This ManagedObjectReference `xml:"_this"` + PortKeys []string `xml:"portKeys,omitempty"` +} + +func init() { + t["RefreshDVPortStateRequestType"] = reflect.TypeOf((*RefreshDVPortStateRequestType)(nil)).Elem() +} + +type RefreshDVPortStateResponse struct { +} + +type RefreshDatastore RefreshDatastoreRequestType + +func init() { + t["RefreshDatastore"] = reflect.TypeOf((*RefreshDatastore)(nil)).Elem() +} + +type RefreshDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshDatastoreRequestType"] = reflect.TypeOf((*RefreshDatastoreRequestType)(nil)).Elem() +} + +type RefreshDatastoreResponse struct { +} + +type RefreshDatastoreStorageInfo RefreshDatastoreStorageInfoRequestType + +func init() { + t["RefreshDatastoreStorageInfo"] = reflect.TypeOf((*RefreshDatastoreStorageInfo)(nil)).Elem() +} + +type RefreshDatastoreStorageInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshDatastoreStorageInfoRequestType"] = reflect.TypeOf((*RefreshDatastoreStorageInfoRequestType)(nil)).Elem() +} + +type RefreshDatastoreStorageInfoResponse struct { +} + +type RefreshDateTimeSystem RefreshDateTimeSystemRequestType + +func init() { + t["RefreshDateTimeSystem"] = reflect.TypeOf((*RefreshDateTimeSystem)(nil)).Elem() +} + +type RefreshDateTimeSystemRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshDateTimeSystemRequestType"] = reflect.TypeOf((*RefreshDateTimeSystemRequestType)(nil)).Elem() +} + +type RefreshDateTimeSystemResponse struct { +} + +type RefreshFirewall RefreshFirewallRequestType + +func init() { + t["RefreshFirewall"] = reflect.TypeOf((*RefreshFirewall)(nil)).Elem() +} + +type RefreshFirewallRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshFirewallRequestType"] = reflect.TypeOf((*RefreshFirewallRequestType)(nil)).Elem() +} + +type RefreshFirewallResponse struct { +} + +type RefreshGraphicsManager RefreshGraphicsManagerRequestType + +func init() { + t["RefreshGraphicsManager"] = reflect.TypeOf((*RefreshGraphicsManager)(nil)).Elem() +} + +type RefreshGraphicsManagerRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshGraphicsManagerRequestType"] = reflect.TypeOf((*RefreshGraphicsManagerRequestType)(nil)).Elem() +} + +type RefreshGraphicsManagerResponse struct { +} + +type RefreshHealthStatusSystem RefreshHealthStatusSystemRequestType + +func init() { + t["RefreshHealthStatusSystem"] = reflect.TypeOf((*RefreshHealthStatusSystem)(nil)).Elem() +} + +type RefreshHealthStatusSystemRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshHealthStatusSystemRequestType"] = reflect.TypeOf((*RefreshHealthStatusSystemRequestType)(nil)).Elem() +} + +type RefreshHealthStatusSystemResponse struct { +} + +type RefreshNetworkSystem RefreshNetworkSystemRequestType + +func init() { + t["RefreshNetworkSystem"] = reflect.TypeOf((*RefreshNetworkSystem)(nil)).Elem() +} + +type RefreshNetworkSystemRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshNetworkSystemRequestType"] = reflect.TypeOf((*RefreshNetworkSystemRequestType)(nil)).Elem() +} + +type RefreshNetworkSystemResponse struct { +} + +type RefreshRecommendation RefreshRecommendationRequestType + +func init() { + t["RefreshRecommendation"] = reflect.TypeOf((*RefreshRecommendation)(nil)).Elem() +} + +type RefreshRecommendationRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshRecommendationRequestType"] = reflect.TypeOf((*RefreshRecommendationRequestType)(nil)).Elem() +} + +type RefreshRecommendationResponse struct { +} + +type RefreshRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshRequestType"] = reflect.TypeOf((*RefreshRequestType)(nil)).Elem() +} + +type RefreshResponse struct { +} + +type RefreshRuntime RefreshRuntimeRequestType + +func init() { + t["RefreshRuntime"] = reflect.TypeOf((*RefreshRuntime)(nil)).Elem() +} + +type RefreshRuntimeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshRuntimeRequestType"] = reflect.TypeOf((*RefreshRuntimeRequestType)(nil)).Elem() +} + +type RefreshRuntimeResponse struct { +} + +type RefreshServices RefreshServicesRequestType + +func init() { + t["RefreshServices"] = reflect.TypeOf((*RefreshServices)(nil)).Elem() +} + +type RefreshServicesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshServicesRequestType"] = reflect.TypeOf((*RefreshServicesRequestType)(nil)).Elem() +} + +type RefreshServicesResponse struct { +} + +type RefreshStorageDrsRecommendation RefreshStorageDrsRecommendationRequestType + +func init() { + t["RefreshStorageDrsRecommendation"] = reflect.TypeOf((*RefreshStorageDrsRecommendation)(nil)).Elem() +} + +type RefreshStorageDrsRecommendationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Pod ManagedObjectReference `xml:"pod"` +} + +func init() { + t["RefreshStorageDrsRecommendationRequestType"] = reflect.TypeOf((*RefreshStorageDrsRecommendationRequestType)(nil)).Elem() +} + +type RefreshStorageDrsRecommendationResponse struct { +} + +type RefreshStorageInfo RefreshStorageInfoRequestType + +func init() { + t["RefreshStorageInfo"] = reflect.TypeOf((*RefreshStorageInfo)(nil)).Elem() +} + +type RefreshStorageInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshStorageInfoRequestType"] = reflect.TypeOf((*RefreshStorageInfoRequestType)(nil)).Elem() +} + +type RefreshStorageInfoResponse struct { +} + +type RefreshStorageSystem RefreshStorageSystemRequestType + +func init() { + t["RefreshStorageSystem"] = reflect.TypeOf((*RefreshStorageSystem)(nil)).Elem() +} + +type RefreshStorageSystemRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RefreshStorageSystemRequestType"] = reflect.TypeOf((*RefreshStorageSystemRequestType)(nil)).Elem() +} + +type RefreshStorageSystemResponse struct { +} + +type RegisterChildVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Path string `xml:"path"` + Name string `xml:"name,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["RegisterChildVMRequestType"] = reflect.TypeOf((*RegisterChildVMRequestType)(nil)).Elem() +} + +type RegisterChildVM_Task RegisterChildVMRequestType + +func init() { + t["RegisterChildVM_Task"] = reflect.TypeOf((*RegisterChildVM_Task)(nil)).Elem() +} + +type RegisterChildVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RegisterExtension RegisterExtensionRequestType + +func init() { + t["RegisterExtension"] = reflect.TypeOf((*RegisterExtension)(nil)).Elem() +} + +type RegisterExtensionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Extension Extension `xml:"extension"` +} + +func init() { + t["RegisterExtensionRequestType"] = reflect.TypeOf((*RegisterExtensionRequestType)(nil)).Elem() +} + +type RegisterExtensionResponse struct { +} + +type RegisterVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Path string `xml:"path"` + Name string `xml:"name,omitempty"` + AsTemplate bool `xml:"asTemplate"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["RegisterVMRequestType"] = reflect.TypeOf((*RegisterVMRequestType)(nil)).Elem() +} + +type RegisterVM_Task RegisterVMRequestType + +func init() { + t["RegisterVM_Task"] = reflect.TypeOf((*RegisterVM_Task)(nil)).Elem() +} + +type RegisterVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReleaseCredentialsInGuest ReleaseCredentialsInGuestRequestType + +func init() { + t["ReleaseCredentialsInGuest"] = reflect.TypeOf((*ReleaseCredentialsInGuest)(nil)).Elem() +} + +type ReleaseCredentialsInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` +} + +func init() { + t["ReleaseCredentialsInGuestRequestType"] = reflect.TypeOf((*ReleaseCredentialsInGuestRequestType)(nil)).Elem() +} + +type ReleaseCredentialsInGuestResponse struct { +} + +type ReleaseIpAllocation ReleaseIpAllocationRequestType + +func init() { + t["ReleaseIpAllocation"] = reflect.TypeOf((*ReleaseIpAllocation)(nil)).Elem() +} + +type ReleaseIpAllocationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + PoolId int32 `xml:"poolId"` + AllocationId string `xml:"allocationId"` +} + +func init() { + t["ReleaseIpAllocationRequestType"] = reflect.TypeOf((*ReleaseIpAllocationRequestType)(nil)).Elem() +} + +type ReleaseIpAllocationResponse struct { +} + +type Reload ReloadRequestType + +func init() { + t["Reload"] = reflect.TypeOf((*Reload)(nil)).Elem() +} + +type ReloadRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ReloadRequestType"] = reflect.TypeOf((*ReloadRequestType)(nil)).Elem() +} + +type ReloadResponse struct { +} + +type RelocateVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec VirtualMachineRelocateSpec `xml:"spec"` + Priority VirtualMachineMovePriority `xml:"priority,omitempty"` +} + +func init() { + t["RelocateVMRequestType"] = reflect.TypeOf((*RelocateVMRequestType)(nil)).Elem() +} + +type RelocateVM_Task RelocateVMRequestType + +func init() { + t["RelocateVM_Task"] = reflect.TypeOf((*RelocateVM_Task)(nil)).Elem() +} + +type RelocateVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RemoteDeviceNotSupported struct { + DeviceNotSupported +} + +func init() { + t["RemoteDeviceNotSupported"] = reflect.TypeOf((*RemoteDeviceNotSupported)(nil)).Elem() +} + +type RemoteDeviceNotSupportedFault RemoteDeviceNotSupported + +func init() { + t["RemoteDeviceNotSupportedFault"] = reflect.TypeOf((*RemoteDeviceNotSupportedFault)(nil)).Elem() +} + +type RemoteTSMEnabledEvent struct { + HostEvent +} + +func init() { + t["RemoteTSMEnabledEvent"] = reflect.TypeOf((*RemoteTSMEnabledEvent)(nil)).Elem() +} + +type RemoveAlarm RemoveAlarmRequestType + +func init() { + t["RemoveAlarm"] = reflect.TypeOf((*RemoveAlarm)(nil)).Elem() +} + +type RemoveAlarmRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RemoveAlarmRequestType"] = reflect.TypeOf((*RemoveAlarmRequestType)(nil)).Elem() +} + +type RemoveAlarmResponse struct { +} + +type RemoveAllSnapshotsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Consolidate *bool `xml:"consolidate"` +} + +func init() { + t["RemoveAllSnapshotsRequestType"] = reflect.TypeOf((*RemoveAllSnapshotsRequestType)(nil)).Elem() +} + +type RemoveAllSnapshots_Task RemoveAllSnapshotsRequestType + +func init() { + t["RemoveAllSnapshots_Task"] = reflect.TypeOf((*RemoveAllSnapshots_Task)(nil)).Elem() +} + +type RemoveAllSnapshots_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RemoveAssignedLicense RemoveAssignedLicenseRequestType + +func init() { + t["RemoveAssignedLicense"] = reflect.TypeOf((*RemoveAssignedLicense)(nil)).Elem() +} + +type RemoveAssignedLicenseRequestType struct { + This ManagedObjectReference `xml:"_this"` + EntityId string `xml:"entityId"` +} + +func init() { + t["RemoveAssignedLicenseRequestType"] = reflect.TypeOf((*RemoveAssignedLicenseRequestType)(nil)).Elem() +} + +type RemoveAssignedLicenseResponse struct { +} + +type RemoveAuthorizationRole RemoveAuthorizationRoleRequestType + +func init() { + t["RemoveAuthorizationRole"] = reflect.TypeOf((*RemoveAuthorizationRole)(nil)).Elem() +} + +type RemoveAuthorizationRoleRequestType struct { + This ManagedObjectReference `xml:"_this"` + RoleId int32 `xml:"roleId"` + FailIfUsed bool `xml:"failIfUsed"` +} + +func init() { + t["RemoveAuthorizationRoleRequestType"] = reflect.TypeOf((*RemoveAuthorizationRoleRequestType)(nil)).Elem() +} + +type RemoveAuthorizationRoleResponse struct { +} + +type RemoveCustomFieldDef RemoveCustomFieldDefRequestType + +func init() { + t["RemoveCustomFieldDef"] = reflect.TypeOf((*RemoveCustomFieldDef)(nil)).Elem() +} + +type RemoveCustomFieldDefRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key int32 `xml:"key"` +} + +func init() { + t["RemoveCustomFieldDefRequestType"] = reflect.TypeOf((*RemoveCustomFieldDefRequestType)(nil)).Elem() +} + +type RemoveCustomFieldDefResponse struct { +} + +type RemoveDatastore RemoveDatastoreRequestType + +func init() { + t["RemoveDatastore"] = reflect.TypeOf((*RemoveDatastore)(nil)).Elem() +} + +type RemoveDatastoreExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore []ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["RemoveDatastoreExRequestType"] = reflect.TypeOf((*RemoveDatastoreExRequestType)(nil)).Elem() +} + +type RemoveDatastoreEx_Task RemoveDatastoreExRequestType + +func init() { + t["RemoveDatastoreEx_Task"] = reflect.TypeOf((*RemoveDatastoreEx_Task)(nil)).Elem() +} + +type RemoveDatastoreEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RemoveDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore ManagedObjectReference `xml:"datastore"` +} + +func init() { + t["RemoveDatastoreRequestType"] = reflect.TypeOf((*RemoveDatastoreRequestType)(nil)).Elem() +} + +type RemoveDatastoreResponse struct { +} + +type RemoveDiskMappingRequestType struct { + This ManagedObjectReference `xml:"_this"` + Mapping []VsanHostDiskMapping `xml:"mapping"` + MaintenanceSpec *HostMaintenanceSpec `xml:"maintenanceSpec,omitempty"` + Timeout int32 `xml:"timeout,omitempty"` +} + +func init() { + t["RemoveDiskMappingRequestType"] = reflect.TypeOf((*RemoveDiskMappingRequestType)(nil)).Elem() +} + +type RemoveDiskMapping_Task RemoveDiskMappingRequestType + +func init() { + t["RemoveDiskMapping_Task"] = reflect.TypeOf((*RemoveDiskMapping_Task)(nil)).Elem() +} + +type RemoveDiskMapping_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RemoveDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Disk []HostScsiDisk `xml:"disk"` + MaintenanceSpec *HostMaintenanceSpec `xml:"maintenanceSpec,omitempty"` + Timeout int32 `xml:"timeout,omitempty"` +} + +func init() { + t["RemoveDiskRequestType"] = reflect.TypeOf((*RemoveDiskRequestType)(nil)).Elem() +} + +type RemoveDisk_Task RemoveDiskRequestType + +func init() { + t["RemoveDisk_Task"] = reflect.TypeOf((*RemoveDisk_Task)(nil)).Elem() +} + +type RemoveDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RemoveEntityPermission RemoveEntityPermissionRequestType + +func init() { + t["RemoveEntityPermission"] = reflect.TypeOf((*RemoveEntityPermission)(nil)).Elem() +} + +type RemoveEntityPermissionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + User string `xml:"user"` + IsGroup bool `xml:"isGroup"` +} + +func init() { + t["RemoveEntityPermissionRequestType"] = reflect.TypeOf((*RemoveEntityPermissionRequestType)(nil)).Elem() +} + +type RemoveEntityPermissionResponse struct { +} + +type RemoveFailed struct { + VimFault +} + +func init() { + t["RemoveFailed"] = reflect.TypeOf((*RemoveFailed)(nil)).Elem() +} + +type RemoveFailedFault RemoveFailed + +func init() { + t["RemoveFailedFault"] = reflect.TypeOf((*RemoveFailedFault)(nil)).Elem() +} + +type RemoveGroup RemoveGroupRequestType + +func init() { + t["RemoveGroup"] = reflect.TypeOf((*RemoveGroup)(nil)).Elem() +} + +type RemoveGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + GroupName string `xml:"groupName"` +} + +func init() { + t["RemoveGroupRequestType"] = reflect.TypeOf((*RemoveGroupRequestType)(nil)).Elem() +} + +type RemoveGroupResponse struct { +} + +type RemoveGuestAlias RemoveGuestAliasRequestType + +func init() { + t["RemoveGuestAlias"] = reflect.TypeOf((*RemoveGuestAlias)(nil)).Elem() +} + +type RemoveGuestAliasByCert RemoveGuestAliasByCertRequestType + +func init() { + t["RemoveGuestAliasByCert"] = reflect.TypeOf((*RemoveGuestAliasByCert)(nil)).Elem() +} + +type RemoveGuestAliasByCertRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Username string `xml:"username"` + Base64Cert string `xml:"base64Cert"` +} + +func init() { + t["RemoveGuestAliasByCertRequestType"] = reflect.TypeOf((*RemoveGuestAliasByCertRequestType)(nil)).Elem() +} + +type RemoveGuestAliasByCertResponse struct { +} + +type RemoveGuestAliasRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Username string `xml:"username"` + Base64Cert string `xml:"base64Cert"` + Subject BaseGuestAuthSubject `xml:"subject,typeattr"` +} + +func init() { + t["RemoveGuestAliasRequestType"] = reflect.TypeOf((*RemoveGuestAliasRequestType)(nil)).Elem() +} + +type RemoveGuestAliasResponse struct { +} + +type RemoveInternetScsiSendTargets RemoveInternetScsiSendTargetsRequestType + +func init() { + t["RemoveInternetScsiSendTargets"] = reflect.TypeOf((*RemoveInternetScsiSendTargets)(nil)).Elem() +} + +type RemoveInternetScsiSendTargetsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + Targets []HostInternetScsiHbaSendTarget `xml:"targets"` +} + +func init() { + t["RemoveInternetScsiSendTargetsRequestType"] = reflect.TypeOf((*RemoveInternetScsiSendTargetsRequestType)(nil)).Elem() +} + +type RemoveInternetScsiSendTargetsResponse struct { +} + +type RemoveInternetScsiStaticTargets RemoveInternetScsiStaticTargetsRequestType + +func init() { + t["RemoveInternetScsiStaticTargets"] = reflect.TypeOf((*RemoveInternetScsiStaticTargets)(nil)).Elem() +} + +type RemoveInternetScsiStaticTargetsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + Targets []HostInternetScsiHbaStaticTarget `xml:"targets"` +} + +func init() { + t["RemoveInternetScsiStaticTargetsRequestType"] = reflect.TypeOf((*RemoveInternetScsiStaticTargetsRequestType)(nil)).Elem() +} + +type RemoveInternetScsiStaticTargetsResponse struct { +} + +type RemoveLicense RemoveLicenseRequestType + +func init() { + t["RemoveLicense"] = reflect.TypeOf((*RemoveLicense)(nil)).Elem() +} + +type RemoveLicenseLabel RemoveLicenseLabelRequestType + +func init() { + t["RemoveLicenseLabel"] = reflect.TypeOf((*RemoveLicenseLabel)(nil)).Elem() +} + +type RemoveLicenseLabelRequestType struct { + This ManagedObjectReference `xml:"_this"` + LicenseKey string `xml:"licenseKey"` + LabelKey string `xml:"labelKey"` +} + +func init() { + t["RemoveLicenseLabelRequestType"] = reflect.TypeOf((*RemoveLicenseLabelRequestType)(nil)).Elem() +} + +type RemoveLicenseLabelResponse struct { +} + +type RemoveLicenseRequestType struct { + This ManagedObjectReference `xml:"_this"` + LicenseKey string `xml:"licenseKey"` +} + +func init() { + t["RemoveLicenseRequestType"] = reflect.TypeOf((*RemoveLicenseRequestType)(nil)).Elem() +} + +type RemoveLicenseResponse struct { +} + +type RemoveNetworkResourcePool RemoveNetworkResourcePoolRequestType + +func init() { + t["RemoveNetworkResourcePool"] = reflect.TypeOf((*RemoveNetworkResourcePool)(nil)).Elem() +} + +type RemoveNetworkResourcePoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key []string `xml:"key"` +} + +func init() { + t["RemoveNetworkResourcePoolRequestType"] = reflect.TypeOf((*RemoveNetworkResourcePoolRequestType)(nil)).Elem() +} + +type RemoveNetworkResourcePoolResponse struct { +} + +type RemovePerfInterval RemovePerfIntervalRequestType + +func init() { + t["RemovePerfInterval"] = reflect.TypeOf((*RemovePerfInterval)(nil)).Elem() +} + +type RemovePerfIntervalRequestType struct { + This ManagedObjectReference `xml:"_this"` + SamplePeriod int32 `xml:"samplePeriod"` +} + +func init() { + t["RemovePerfIntervalRequestType"] = reflect.TypeOf((*RemovePerfIntervalRequestType)(nil)).Elem() +} + +type RemovePerfIntervalResponse struct { +} + +type RemovePortGroup RemovePortGroupRequestType + +func init() { + t["RemovePortGroup"] = reflect.TypeOf((*RemovePortGroup)(nil)).Elem() +} + +type RemovePortGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + PgName string `xml:"pgName"` +} + +func init() { + t["RemovePortGroupRequestType"] = reflect.TypeOf((*RemovePortGroupRequestType)(nil)).Elem() +} + +type RemovePortGroupResponse struct { +} + +type RemoveScheduledTask RemoveScheduledTaskRequestType + +func init() { + t["RemoveScheduledTask"] = reflect.TypeOf((*RemoveScheduledTask)(nil)).Elem() +} + +type RemoveScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RemoveScheduledTaskRequestType"] = reflect.TypeOf((*RemoveScheduledTaskRequestType)(nil)).Elem() +} + +type RemoveScheduledTaskResponse struct { +} + +type RemoveServiceConsoleVirtualNic RemoveServiceConsoleVirtualNicRequestType + +func init() { + t["RemoveServiceConsoleVirtualNic"] = reflect.TypeOf((*RemoveServiceConsoleVirtualNic)(nil)).Elem() +} + +type RemoveServiceConsoleVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` +} + +func init() { + t["RemoveServiceConsoleVirtualNicRequestType"] = reflect.TypeOf((*RemoveServiceConsoleVirtualNicRequestType)(nil)).Elem() +} + +type RemoveServiceConsoleVirtualNicResponse struct { +} + +type RemoveSmartCardTrustAnchor RemoveSmartCardTrustAnchorRequestType + +func init() { + t["RemoveSmartCardTrustAnchor"] = reflect.TypeOf((*RemoveSmartCardTrustAnchor)(nil)).Elem() +} + +type RemoveSmartCardTrustAnchorByFingerprint RemoveSmartCardTrustAnchorByFingerprintRequestType + +func init() { + t["RemoveSmartCardTrustAnchorByFingerprint"] = reflect.TypeOf((*RemoveSmartCardTrustAnchorByFingerprint)(nil)).Elem() +} + +type RemoveSmartCardTrustAnchorByFingerprintRequestType struct { + This ManagedObjectReference `xml:"_this"` + Fingerprint string `xml:"fingerprint"` + Digest string `xml:"digest"` +} + +func init() { + t["RemoveSmartCardTrustAnchorByFingerprintRequestType"] = reflect.TypeOf((*RemoveSmartCardTrustAnchorByFingerprintRequestType)(nil)).Elem() +} + +type RemoveSmartCardTrustAnchorByFingerprintResponse struct { +} + +type RemoveSmartCardTrustAnchorRequestType struct { + This ManagedObjectReference `xml:"_this"` + Issuer string `xml:"issuer"` + Serial string `xml:"serial"` +} + +func init() { + t["RemoveSmartCardTrustAnchorRequestType"] = reflect.TypeOf((*RemoveSmartCardTrustAnchorRequestType)(nil)).Elem() +} + +type RemoveSmartCardTrustAnchorResponse struct { +} + +type RemoveSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` + RemoveChildren bool `xml:"removeChildren"` + Consolidate *bool `xml:"consolidate"` +} + +func init() { + t["RemoveSnapshotRequestType"] = reflect.TypeOf((*RemoveSnapshotRequestType)(nil)).Elem() +} + +type RemoveSnapshot_Task RemoveSnapshotRequestType + +func init() { + t["RemoveSnapshot_Task"] = reflect.TypeOf((*RemoveSnapshot_Task)(nil)).Elem() +} + +type RemoveSnapshot_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RemoveUser RemoveUserRequestType + +func init() { + t["RemoveUser"] = reflect.TypeOf((*RemoveUser)(nil)).Elem() +} + +type RemoveUserRequestType struct { + This ManagedObjectReference `xml:"_this"` + UserName string `xml:"userName"` +} + +func init() { + t["RemoveUserRequestType"] = reflect.TypeOf((*RemoveUserRequestType)(nil)).Elem() +} + +type RemoveUserResponse struct { +} + +type RemoveVirtualNic RemoveVirtualNicRequestType + +func init() { + t["RemoveVirtualNic"] = reflect.TypeOf((*RemoveVirtualNic)(nil)).Elem() +} + +type RemoveVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` +} + +func init() { + t["RemoveVirtualNicRequestType"] = reflect.TypeOf((*RemoveVirtualNicRequestType)(nil)).Elem() +} + +type RemoveVirtualNicResponse struct { +} + +type RemoveVirtualSwitch RemoveVirtualSwitchRequestType + +func init() { + t["RemoveVirtualSwitch"] = reflect.TypeOf((*RemoveVirtualSwitch)(nil)).Elem() +} + +type RemoveVirtualSwitchRequestType struct { + This ManagedObjectReference `xml:"_this"` + VswitchName string `xml:"vswitchName"` +} + +func init() { + t["RemoveVirtualSwitchRequestType"] = reflect.TypeOf((*RemoveVirtualSwitchRequestType)(nil)).Elem() +} + +type RemoveVirtualSwitchResponse struct { +} + +type RenameCustomFieldDef RenameCustomFieldDefRequestType + +func init() { + t["RenameCustomFieldDef"] = reflect.TypeOf((*RenameCustomFieldDef)(nil)).Elem() +} + +type RenameCustomFieldDefRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key int32 `xml:"key"` + Name string `xml:"name"` +} + +func init() { + t["RenameCustomFieldDefRequestType"] = reflect.TypeOf((*RenameCustomFieldDefRequestType)(nil)).Elem() +} + +type RenameCustomFieldDefResponse struct { +} + +type RenameCustomizationSpec RenameCustomizationSpecRequestType + +func init() { + t["RenameCustomizationSpec"] = reflect.TypeOf((*RenameCustomizationSpec)(nil)).Elem() +} + +type RenameCustomizationSpecRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + NewName string `xml:"newName"` +} + +func init() { + t["RenameCustomizationSpecRequestType"] = reflect.TypeOf((*RenameCustomizationSpecRequestType)(nil)).Elem() +} + +type RenameCustomizationSpecResponse struct { +} + +type RenameDatastore RenameDatastoreRequestType + +func init() { + t["RenameDatastore"] = reflect.TypeOf((*RenameDatastore)(nil)).Elem() +} + +type RenameDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + NewName string `xml:"newName"` +} + +func init() { + t["RenameDatastoreRequestType"] = reflect.TypeOf((*RenameDatastoreRequestType)(nil)).Elem() +} + +type RenameDatastoreResponse struct { +} + +type RenameRequestType struct { + This ManagedObjectReference `xml:"_this"` + NewName string `xml:"newName"` +} + +func init() { + t["RenameRequestType"] = reflect.TypeOf((*RenameRequestType)(nil)).Elem() +} + +type RenameSnapshot RenameSnapshotRequestType + +func init() { + t["RenameSnapshot"] = reflect.TypeOf((*RenameSnapshot)(nil)).Elem() +} + +type RenameSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["RenameSnapshotRequestType"] = reflect.TypeOf((*RenameSnapshotRequestType)(nil)).Elem() +} + +type RenameSnapshotResponse struct { +} + +type Rename_Task RenameRequestType + +func init() { + t["Rename_Task"] = reflect.TypeOf((*Rename_Task)(nil)).Elem() +} + +type Rename_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ReplaceCACertificatesAndCRLs ReplaceCACertificatesAndCRLsRequestType + +func init() { + t["ReplaceCACertificatesAndCRLs"] = reflect.TypeOf((*ReplaceCACertificatesAndCRLs)(nil)).Elem() +} + +type ReplaceCACertificatesAndCRLsRequestType struct { + This ManagedObjectReference `xml:"_this"` + CaCert []string `xml:"caCert"` + CaCrl []string `xml:"caCrl,omitempty"` +} + +func init() { + t["ReplaceCACertificatesAndCRLsRequestType"] = reflect.TypeOf((*ReplaceCACertificatesAndCRLsRequestType)(nil)).Elem() +} + +type ReplaceCACertificatesAndCRLsResponse struct { +} + +type ReplaceSmartCardTrustAnchors ReplaceSmartCardTrustAnchorsRequestType + +func init() { + t["ReplaceSmartCardTrustAnchors"] = reflect.TypeOf((*ReplaceSmartCardTrustAnchors)(nil)).Elem() +} + +type ReplaceSmartCardTrustAnchorsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Certs []string `xml:"certs,omitempty"` +} + +func init() { + t["ReplaceSmartCardTrustAnchorsRequestType"] = reflect.TypeOf((*ReplaceSmartCardTrustAnchorsRequestType)(nil)).Elem() +} + +type ReplaceSmartCardTrustAnchorsResponse struct { +} + +type ReplicationConfigFault struct { + ReplicationFault +} + +func init() { + t["ReplicationConfigFault"] = reflect.TypeOf((*ReplicationConfigFault)(nil)).Elem() +} + +type ReplicationConfigFaultFault BaseReplicationConfigFault + +func init() { + t["ReplicationConfigFaultFault"] = reflect.TypeOf((*ReplicationConfigFaultFault)(nil)).Elem() +} + +type ReplicationConfigSpec struct { + DynamicData + + Generation int64 `xml:"generation"` + VmReplicationId string `xml:"vmReplicationId"` + Destination string `xml:"destination"` + Port int32 `xml:"port"` + Rpo int64 `xml:"rpo"` + QuiesceGuestEnabled bool `xml:"quiesceGuestEnabled"` + Paused bool `xml:"paused"` + OppUpdatesEnabled bool `xml:"oppUpdatesEnabled"` + NetCompressionEnabled *bool `xml:"netCompressionEnabled"` + Disk []ReplicationInfoDiskSettings `xml:"disk,omitempty"` +} + +func init() { + t["ReplicationConfigSpec"] = reflect.TypeOf((*ReplicationConfigSpec)(nil)).Elem() +} + +type ReplicationDiskConfigFault struct { + ReplicationConfigFault + + Reason string `xml:"reason,omitempty"` + VmRef *ManagedObjectReference `xml:"vmRef,omitempty"` + Key int32 `xml:"key,omitempty"` +} + +func init() { + t["ReplicationDiskConfigFault"] = reflect.TypeOf((*ReplicationDiskConfigFault)(nil)).Elem() +} + +type ReplicationDiskConfigFaultFault ReplicationDiskConfigFault + +func init() { + t["ReplicationDiskConfigFaultFault"] = reflect.TypeOf((*ReplicationDiskConfigFaultFault)(nil)).Elem() +} + +type ReplicationFault struct { + VimFault +} + +func init() { + t["ReplicationFault"] = reflect.TypeOf((*ReplicationFault)(nil)).Elem() +} + +type ReplicationFaultFault BaseReplicationFault + +func init() { + t["ReplicationFaultFault"] = reflect.TypeOf((*ReplicationFaultFault)(nil)).Elem() +} + +type ReplicationIncompatibleWithFT struct { + ReplicationFault +} + +func init() { + t["ReplicationIncompatibleWithFT"] = reflect.TypeOf((*ReplicationIncompatibleWithFT)(nil)).Elem() +} + +type ReplicationIncompatibleWithFTFault ReplicationIncompatibleWithFT + +func init() { + t["ReplicationIncompatibleWithFTFault"] = reflect.TypeOf((*ReplicationIncompatibleWithFTFault)(nil)).Elem() +} + +type ReplicationInfoDiskSettings struct { + DynamicData + + Key int32 `xml:"key"` + DiskReplicationId string `xml:"diskReplicationId"` +} + +func init() { + t["ReplicationInfoDiskSettings"] = reflect.TypeOf((*ReplicationInfoDiskSettings)(nil)).Elem() +} + +type ReplicationInvalidOptions struct { + ReplicationFault + + Options string `xml:"options"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["ReplicationInvalidOptions"] = reflect.TypeOf((*ReplicationInvalidOptions)(nil)).Elem() +} + +type ReplicationInvalidOptionsFault ReplicationInvalidOptions + +func init() { + t["ReplicationInvalidOptionsFault"] = reflect.TypeOf((*ReplicationInvalidOptionsFault)(nil)).Elem() +} + +type ReplicationNotSupportedOnHost struct { + ReplicationFault +} + +func init() { + t["ReplicationNotSupportedOnHost"] = reflect.TypeOf((*ReplicationNotSupportedOnHost)(nil)).Elem() +} + +type ReplicationNotSupportedOnHostFault ReplicationNotSupportedOnHost + +func init() { + t["ReplicationNotSupportedOnHostFault"] = reflect.TypeOf((*ReplicationNotSupportedOnHostFault)(nil)).Elem() +} + +type ReplicationVmConfigFault struct { + ReplicationConfigFault + + Reason string `xml:"reason,omitempty"` + VmRef *ManagedObjectReference `xml:"vmRef,omitempty"` +} + +func init() { + t["ReplicationVmConfigFault"] = reflect.TypeOf((*ReplicationVmConfigFault)(nil)).Elem() +} + +type ReplicationVmConfigFaultFault ReplicationVmConfigFault + +func init() { + t["ReplicationVmConfigFaultFault"] = reflect.TypeOf((*ReplicationVmConfigFaultFault)(nil)).Elem() +} + +type ReplicationVmFault struct { + ReplicationFault + + Reason string `xml:"reason,omitempty"` + State string `xml:"state,omitempty"` + InstanceId string `xml:"instanceId,omitempty"` + Vm *ManagedObjectReference `xml:"vm,omitempty"` +} + +func init() { + t["ReplicationVmFault"] = reflect.TypeOf((*ReplicationVmFault)(nil)).Elem() +} + +type ReplicationVmFaultFault BaseReplicationVmFault + +func init() { + t["ReplicationVmFaultFault"] = reflect.TypeOf((*ReplicationVmFaultFault)(nil)).Elem() +} + +type ReplicationVmInProgressFault struct { + ReplicationVmFault + + RequestedActivity string `xml:"requestedActivity"` + InProgressActivity string `xml:"inProgressActivity"` +} + +func init() { + t["ReplicationVmInProgressFault"] = reflect.TypeOf((*ReplicationVmInProgressFault)(nil)).Elem() +} + +type ReplicationVmInProgressFaultFault ReplicationVmInProgressFault + +func init() { + t["ReplicationVmInProgressFaultFault"] = reflect.TypeOf((*ReplicationVmInProgressFaultFault)(nil)).Elem() +} + +type ReplicationVmProgressInfo struct { + DynamicData + + Progress int32 `xml:"progress"` + BytesTransferred int64 `xml:"bytesTransferred"` + BytesToTransfer int64 `xml:"bytesToTransfer"` + ChecksumTotalBytes int64 `xml:"checksumTotalBytes,omitempty"` + ChecksumComparedBytes int64 `xml:"checksumComparedBytes,omitempty"` +} + +func init() { + t["ReplicationVmProgressInfo"] = reflect.TypeOf((*ReplicationVmProgressInfo)(nil)).Elem() +} + +type RequestCanceled struct { + RuntimeFault +} + +func init() { + t["RequestCanceled"] = reflect.TypeOf((*RequestCanceled)(nil)).Elem() +} + +type RequestCanceledFault RequestCanceled + +func init() { + t["RequestCanceledFault"] = reflect.TypeOf((*RequestCanceledFault)(nil)).Elem() +} + +type RescanAllHba RescanAllHbaRequestType + +func init() { + t["RescanAllHba"] = reflect.TypeOf((*RescanAllHba)(nil)).Elem() +} + +type RescanAllHbaRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RescanAllHbaRequestType"] = reflect.TypeOf((*RescanAllHbaRequestType)(nil)).Elem() +} + +type RescanAllHbaResponse struct { +} + +type RescanHba RescanHbaRequestType + +func init() { + t["RescanHba"] = reflect.TypeOf((*RescanHba)(nil)).Elem() +} + +type RescanHbaRequestType struct { + This ManagedObjectReference `xml:"_this"` + HbaDevice string `xml:"hbaDevice"` +} + +func init() { + t["RescanHbaRequestType"] = reflect.TypeOf((*RescanHbaRequestType)(nil)).Elem() +} + +type RescanHbaResponse struct { +} + +type RescanVffs RescanVffsRequestType + +func init() { + t["RescanVffs"] = reflect.TypeOf((*RescanVffs)(nil)).Elem() +} + +type RescanVffsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RescanVffsRequestType"] = reflect.TypeOf((*RescanVffsRequestType)(nil)).Elem() +} + +type RescanVffsResponse struct { +} + +type RescanVmfs RescanVmfsRequestType + +func init() { + t["RescanVmfs"] = reflect.TypeOf((*RescanVmfs)(nil)).Elem() +} + +type RescanVmfsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RescanVmfsRequestType"] = reflect.TypeOf((*RescanVmfsRequestType)(nil)).Elem() +} + +type RescanVmfsResponse struct { +} + +type ResetCollector ResetCollectorRequestType + +func init() { + t["ResetCollector"] = reflect.TypeOf((*ResetCollector)(nil)).Elem() +} + +type ResetCollectorRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ResetCollectorRequestType"] = reflect.TypeOf((*ResetCollectorRequestType)(nil)).Elem() +} + +type ResetCollectorResponse struct { +} + +type ResetCounterLevelMapping ResetCounterLevelMappingRequestType + +func init() { + t["ResetCounterLevelMapping"] = reflect.TypeOf((*ResetCounterLevelMapping)(nil)).Elem() +} + +type ResetCounterLevelMappingRequestType struct { + This ManagedObjectReference `xml:"_this"` + Counters []int32 `xml:"counters"` +} + +func init() { + t["ResetCounterLevelMappingRequestType"] = reflect.TypeOf((*ResetCounterLevelMappingRequestType)(nil)).Elem() +} + +type ResetCounterLevelMappingResponse struct { +} + +type ResetEntityPermissions ResetEntityPermissionsRequestType + +func init() { + t["ResetEntityPermissions"] = reflect.TypeOf((*ResetEntityPermissions)(nil)).Elem() +} + +type ResetEntityPermissionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Permission []Permission `xml:"permission,omitempty"` +} + +func init() { + t["ResetEntityPermissionsRequestType"] = reflect.TypeOf((*ResetEntityPermissionsRequestType)(nil)).Elem() +} + +type ResetEntityPermissionsResponse struct { +} + +type ResetFirmwareToFactoryDefaults ResetFirmwareToFactoryDefaultsRequestType + +func init() { + t["ResetFirmwareToFactoryDefaults"] = reflect.TypeOf((*ResetFirmwareToFactoryDefaults)(nil)).Elem() +} + +type ResetFirmwareToFactoryDefaultsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ResetFirmwareToFactoryDefaultsRequestType"] = reflect.TypeOf((*ResetFirmwareToFactoryDefaultsRequestType)(nil)).Elem() +} + +type ResetFirmwareToFactoryDefaultsResponse struct { +} + +type ResetGuestInformation ResetGuestInformationRequestType + +func init() { + t["ResetGuestInformation"] = reflect.TypeOf((*ResetGuestInformation)(nil)).Elem() +} + +type ResetGuestInformationRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ResetGuestInformationRequestType"] = reflect.TypeOf((*ResetGuestInformationRequestType)(nil)).Elem() +} + +type ResetGuestInformationResponse struct { +} + +type ResetListView ResetListViewRequestType + +func init() { + t["ResetListView"] = reflect.TypeOf((*ResetListView)(nil)).Elem() +} + +type ResetListViewFromView ResetListViewFromViewRequestType + +func init() { + t["ResetListViewFromView"] = reflect.TypeOf((*ResetListViewFromView)(nil)).Elem() +} + +type ResetListViewFromViewRequestType struct { + This ManagedObjectReference `xml:"_this"` + View ManagedObjectReference `xml:"view"` +} + +func init() { + t["ResetListViewFromViewRequestType"] = reflect.TypeOf((*ResetListViewFromViewRequestType)(nil)).Elem() +} + +type ResetListViewFromViewResponse struct { +} + +type ResetListViewRequestType struct { + This ManagedObjectReference `xml:"_this"` + Obj []ManagedObjectReference `xml:"obj,omitempty"` +} + +func init() { + t["ResetListViewRequestType"] = reflect.TypeOf((*ResetListViewRequestType)(nil)).Elem() +} + +type ResetListViewResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type ResetSystemHealthInfo ResetSystemHealthInfoRequestType + +func init() { + t["ResetSystemHealthInfo"] = reflect.TypeOf((*ResetSystemHealthInfo)(nil)).Elem() +} + +type ResetSystemHealthInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ResetSystemHealthInfoRequestType"] = reflect.TypeOf((*ResetSystemHealthInfoRequestType)(nil)).Elem() +} + +type ResetSystemHealthInfoResponse struct { +} + +type ResetVMRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ResetVMRequestType"] = reflect.TypeOf((*ResetVMRequestType)(nil)).Elem() +} + +type ResetVM_Task ResetVMRequestType + +func init() { + t["ResetVM_Task"] = reflect.TypeOf((*ResetVM_Task)(nil)).Elem() +} + +type ResetVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ResignatureUnresolvedVmfsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` + ResolutionSpec HostUnresolvedVmfsResignatureSpec `xml:"resolutionSpec"` +} + +func init() { + t["ResignatureUnresolvedVmfsVolumeRequestType"] = reflect.TypeOf((*ResignatureUnresolvedVmfsVolumeRequestType)(nil)).Elem() +} + +type ResignatureUnresolvedVmfsVolume_Task ResignatureUnresolvedVmfsVolumeRequestType + +func init() { + t["ResignatureUnresolvedVmfsVolume_Task"] = reflect.TypeOf((*ResignatureUnresolvedVmfsVolume_Task)(nil)).Elem() +} + +type ResignatureUnresolvedVmfsVolume_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ResolveInstallationErrorsOnClusterRequestType struct { + This ManagedObjectReference `xml:"_this"` + FilterId string `xml:"filterId"` + Cluster ManagedObjectReference `xml:"cluster"` +} + +func init() { + t["ResolveInstallationErrorsOnClusterRequestType"] = reflect.TypeOf((*ResolveInstallationErrorsOnClusterRequestType)(nil)).Elem() +} + +type ResolveInstallationErrorsOnCluster_Task ResolveInstallationErrorsOnClusterRequestType + +func init() { + t["ResolveInstallationErrorsOnCluster_Task"] = reflect.TypeOf((*ResolveInstallationErrorsOnCluster_Task)(nil)).Elem() +} + +type ResolveInstallationErrorsOnCluster_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ResolveInstallationErrorsOnHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + FilterId string `xml:"filterId"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["ResolveInstallationErrorsOnHostRequestType"] = reflect.TypeOf((*ResolveInstallationErrorsOnHostRequestType)(nil)).Elem() +} + +type ResolveInstallationErrorsOnHost_Task ResolveInstallationErrorsOnHostRequestType + +func init() { + t["ResolveInstallationErrorsOnHost_Task"] = reflect.TypeOf((*ResolveInstallationErrorsOnHost_Task)(nil)).Elem() +} + +type ResolveInstallationErrorsOnHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ResolveMultipleUnresolvedVmfsVolumes ResolveMultipleUnresolvedVmfsVolumesRequestType + +func init() { + t["ResolveMultipleUnresolvedVmfsVolumes"] = reflect.TypeOf((*ResolveMultipleUnresolvedVmfsVolumes)(nil)).Elem() +} + +type ResolveMultipleUnresolvedVmfsVolumesExRequestType struct { + This ManagedObjectReference `xml:"_this"` + ResolutionSpec []HostUnresolvedVmfsResolutionSpec `xml:"resolutionSpec"` +} + +func init() { + t["ResolveMultipleUnresolvedVmfsVolumesExRequestType"] = reflect.TypeOf((*ResolveMultipleUnresolvedVmfsVolumesExRequestType)(nil)).Elem() +} + +type ResolveMultipleUnresolvedVmfsVolumesEx_Task ResolveMultipleUnresolvedVmfsVolumesExRequestType + +func init() { + t["ResolveMultipleUnresolvedVmfsVolumesEx_Task"] = reflect.TypeOf((*ResolveMultipleUnresolvedVmfsVolumesEx_Task)(nil)).Elem() +} + +type ResolveMultipleUnresolvedVmfsVolumesEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ResolveMultipleUnresolvedVmfsVolumesRequestType struct { + This ManagedObjectReference `xml:"_this"` + ResolutionSpec []HostUnresolvedVmfsResolutionSpec `xml:"resolutionSpec"` +} + +func init() { + t["ResolveMultipleUnresolvedVmfsVolumesRequestType"] = reflect.TypeOf((*ResolveMultipleUnresolvedVmfsVolumesRequestType)(nil)).Elem() +} + +type ResolveMultipleUnresolvedVmfsVolumesResponse struct { + Returnval []HostUnresolvedVmfsResolutionResult `xml:"returnval,omitempty"` +} + +type ResourceAllocationInfo struct { + DynamicData + + Reservation int64 `xml:"reservation,omitempty"` + ExpandableReservation *bool `xml:"expandableReservation"` + Limit int64 `xml:"limit,omitempty"` + Shares *SharesInfo `xml:"shares,omitempty"` + OverheadLimit int64 `xml:"overheadLimit,omitempty"` +} + +func init() { + t["ResourceAllocationInfo"] = reflect.TypeOf((*ResourceAllocationInfo)(nil)).Elem() +} + +type ResourceAllocationOption struct { + DynamicData + + SharesOption SharesOption `xml:"sharesOption"` +} + +func init() { + t["ResourceAllocationOption"] = reflect.TypeOf((*ResourceAllocationOption)(nil)).Elem() +} + +type ResourceConfigOption struct { + DynamicData + + CpuAllocationOption ResourceAllocationOption `xml:"cpuAllocationOption"` + MemoryAllocationOption ResourceAllocationOption `xml:"memoryAllocationOption"` +} + +func init() { + t["ResourceConfigOption"] = reflect.TypeOf((*ResourceConfigOption)(nil)).Elem() +} + +type ResourceConfigSpec struct { + DynamicData + + Entity *ManagedObjectReference `xml:"entity,omitempty"` + ChangeVersion string `xml:"changeVersion,omitempty"` + LastModified *time.Time `xml:"lastModified"` + CpuAllocation BaseResourceAllocationInfo `xml:"cpuAllocation,typeattr"` + MemoryAllocation BaseResourceAllocationInfo `xml:"memoryAllocation,typeattr"` +} + +func init() { + t["ResourceConfigSpec"] = reflect.TypeOf((*ResourceConfigSpec)(nil)).Elem() +} + +type ResourceInUse struct { + VimFault + + Type string `xml:"type,omitempty"` + Name string `xml:"name,omitempty"` +} + +func init() { + t["ResourceInUse"] = reflect.TypeOf((*ResourceInUse)(nil)).Elem() +} + +type ResourceInUseFault BaseResourceInUse + +func init() { + t["ResourceInUseFault"] = reflect.TypeOf((*ResourceInUseFault)(nil)).Elem() +} + +type ResourceNotAvailable struct { + VimFault + + ContainerType string `xml:"containerType,omitempty"` + ContainerName string `xml:"containerName,omitempty"` + Type string `xml:"type,omitempty"` +} + +func init() { + t["ResourceNotAvailable"] = reflect.TypeOf((*ResourceNotAvailable)(nil)).Elem() +} + +type ResourceNotAvailableFault ResourceNotAvailable + +func init() { + t["ResourceNotAvailableFault"] = reflect.TypeOf((*ResourceNotAvailableFault)(nil)).Elem() +} + +type ResourcePoolCreatedEvent struct { + ResourcePoolEvent + + Parent ResourcePoolEventArgument `xml:"parent"` +} + +func init() { + t["ResourcePoolCreatedEvent"] = reflect.TypeOf((*ResourcePoolCreatedEvent)(nil)).Elem() +} + +type ResourcePoolDestroyedEvent struct { + ResourcePoolEvent +} + +func init() { + t["ResourcePoolDestroyedEvent"] = reflect.TypeOf((*ResourcePoolDestroyedEvent)(nil)).Elem() +} + +type ResourcePoolEvent struct { + Event + + ResourcePool ResourcePoolEventArgument `xml:"resourcePool"` +} + +func init() { + t["ResourcePoolEvent"] = reflect.TypeOf((*ResourcePoolEvent)(nil)).Elem() +} + +type ResourcePoolEventArgument struct { + EntityEventArgument + + ResourcePool ManagedObjectReference `xml:"resourcePool"` +} + +func init() { + t["ResourcePoolEventArgument"] = reflect.TypeOf((*ResourcePoolEventArgument)(nil)).Elem() +} + +type ResourcePoolMovedEvent struct { + ResourcePoolEvent + + OldParent ResourcePoolEventArgument `xml:"oldParent"` + NewParent ResourcePoolEventArgument `xml:"newParent"` +} + +func init() { + t["ResourcePoolMovedEvent"] = reflect.TypeOf((*ResourcePoolMovedEvent)(nil)).Elem() +} + +type ResourcePoolQuickStats struct { + DynamicData + + OverallCpuUsage int64 `xml:"overallCpuUsage,omitempty"` + OverallCpuDemand int64 `xml:"overallCpuDemand,omitempty"` + GuestMemoryUsage int64 `xml:"guestMemoryUsage,omitempty"` + HostMemoryUsage int64 `xml:"hostMemoryUsage,omitempty"` + DistributedCpuEntitlement int64 `xml:"distributedCpuEntitlement,omitempty"` + DistributedMemoryEntitlement int64 `xml:"distributedMemoryEntitlement,omitempty"` + StaticCpuEntitlement int32 `xml:"staticCpuEntitlement,omitempty"` + StaticMemoryEntitlement int32 `xml:"staticMemoryEntitlement,omitempty"` + PrivateMemory int64 `xml:"privateMemory,omitempty"` + SharedMemory int64 `xml:"sharedMemory,omitempty"` + SwappedMemory int64 `xml:"swappedMemory,omitempty"` + BalloonedMemory int64 `xml:"balloonedMemory,omitempty"` + OverheadMemory int64 `xml:"overheadMemory,omitempty"` + ConsumedOverheadMemory int64 `xml:"consumedOverheadMemory,omitempty"` + CompressedMemory int64 `xml:"compressedMemory,omitempty"` +} + +func init() { + t["ResourcePoolQuickStats"] = reflect.TypeOf((*ResourcePoolQuickStats)(nil)).Elem() +} + +type ResourcePoolReconfiguredEvent struct { + ResourcePoolEvent +} + +func init() { + t["ResourcePoolReconfiguredEvent"] = reflect.TypeOf((*ResourcePoolReconfiguredEvent)(nil)).Elem() +} + +type ResourcePoolResourceUsage struct { + DynamicData + + ReservationUsed int64 `xml:"reservationUsed"` + ReservationUsedForVm int64 `xml:"reservationUsedForVm"` + UnreservedForPool int64 `xml:"unreservedForPool"` + UnreservedForVm int64 `xml:"unreservedForVm"` + OverallUsage int64 `xml:"overallUsage"` + MaxUsage int64 `xml:"maxUsage"` +} + +func init() { + t["ResourcePoolResourceUsage"] = reflect.TypeOf((*ResourcePoolResourceUsage)(nil)).Elem() +} + +type ResourcePoolRuntimeInfo struct { + DynamicData + + Memory ResourcePoolResourceUsage `xml:"memory"` + Cpu ResourcePoolResourceUsage `xml:"cpu"` + OverallStatus ManagedEntityStatus `xml:"overallStatus"` +} + +func init() { + t["ResourcePoolRuntimeInfo"] = reflect.TypeOf((*ResourcePoolRuntimeInfo)(nil)).Elem() +} + +type ResourcePoolSummary struct { + DynamicData + + Name string `xml:"name"` + Config ResourceConfigSpec `xml:"config"` + Runtime ResourcePoolRuntimeInfo `xml:"runtime"` + QuickStats *ResourcePoolQuickStats `xml:"quickStats,omitempty"` + ConfiguredMemoryMB int32 `xml:"configuredMemoryMB,omitempty"` +} + +func init() { + t["ResourcePoolSummary"] = reflect.TypeOf((*ResourcePoolSummary)(nil)).Elem() +} + +type ResourceViolatedEvent struct { + ResourcePoolEvent +} + +func init() { + t["ResourceViolatedEvent"] = reflect.TypeOf((*ResourceViolatedEvent)(nil)).Elem() +} + +type RestartService RestartServiceRequestType + +func init() { + t["RestartService"] = reflect.TypeOf((*RestartService)(nil)).Elem() +} + +type RestartServiceConsoleVirtualNic RestartServiceConsoleVirtualNicRequestType + +func init() { + t["RestartServiceConsoleVirtualNic"] = reflect.TypeOf((*RestartServiceConsoleVirtualNic)(nil)).Elem() +} + +type RestartServiceConsoleVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` +} + +func init() { + t["RestartServiceConsoleVirtualNicRequestType"] = reflect.TypeOf((*RestartServiceConsoleVirtualNicRequestType)(nil)).Elem() +} + +type RestartServiceConsoleVirtualNicResponse struct { +} + +type RestartServiceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` +} + +func init() { + t["RestartServiceRequestType"] = reflect.TypeOf((*RestartServiceRequestType)(nil)).Elem() +} + +type RestartServiceResponse struct { +} + +type RestoreFirmwareConfiguration RestoreFirmwareConfigurationRequestType + +func init() { + t["RestoreFirmwareConfiguration"] = reflect.TypeOf((*RestoreFirmwareConfiguration)(nil)).Elem() +} + +type RestoreFirmwareConfigurationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Force bool `xml:"force"` +} + +func init() { + t["RestoreFirmwareConfigurationRequestType"] = reflect.TypeOf((*RestoreFirmwareConfigurationRequestType)(nil)).Elem() +} + +type RestoreFirmwareConfigurationResponse struct { +} + +type RestrictedByAdministrator struct { + RuntimeFault + + Details string `xml:"details"` +} + +func init() { + t["RestrictedByAdministrator"] = reflect.TypeOf((*RestrictedByAdministrator)(nil)).Elem() +} + +type RestrictedByAdministratorFault RestrictedByAdministrator + +func init() { + t["RestrictedByAdministratorFault"] = reflect.TypeOf((*RestrictedByAdministratorFault)(nil)).Elem() +} + +type RestrictedVersion struct { + SecurityError +} + +func init() { + t["RestrictedVersion"] = reflect.TypeOf((*RestrictedVersion)(nil)).Elem() +} + +type RestrictedVersionFault RestrictedVersion + +func init() { + t["RestrictedVersionFault"] = reflect.TypeOf((*RestrictedVersionFault)(nil)).Elem() +} + +type RetrieveAllPermissions RetrieveAllPermissionsRequestType + +func init() { + t["RetrieveAllPermissions"] = reflect.TypeOf((*RetrieveAllPermissions)(nil)).Elem() +} + +type RetrieveAllPermissionsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveAllPermissionsRequestType"] = reflect.TypeOf((*RetrieveAllPermissionsRequestType)(nil)).Elem() +} + +type RetrieveAllPermissionsResponse struct { + Returnval []Permission `xml:"returnval,omitempty"` +} + +type RetrieveAnswerFile RetrieveAnswerFileRequestType + +func init() { + t["RetrieveAnswerFile"] = reflect.TypeOf((*RetrieveAnswerFile)(nil)).Elem() +} + +type RetrieveAnswerFileForProfile RetrieveAnswerFileForProfileRequestType + +func init() { + t["RetrieveAnswerFileForProfile"] = reflect.TypeOf((*RetrieveAnswerFileForProfile)(nil)).Elem() +} + +type RetrieveAnswerFileForProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` + ApplyProfile HostApplyProfile `xml:"applyProfile"` +} + +func init() { + t["RetrieveAnswerFileForProfileRequestType"] = reflect.TypeOf((*RetrieveAnswerFileForProfileRequestType)(nil)).Elem() +} + +type RetrieveAnswerFileForProfileResponse struct { + Returnval *AnswerFile `xml:"returnval,omitempty"` +} + +type RetrieveAnswerFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["RetrieveAnswerFileRequestType"] = reflect.TypeOf((*RetrieveAnswerFileRequestType)(nil)).Elem() +} + +type RetrieveAnswerFileResponse struct { + Returnval *AnswerFile `xml:"returnval,omitempty"` +} + +type RetrieveArgumentDescription RetrieveArgumentDescriptionRequestType + +func init() { + t["RetrieveArgumentDescription"] = reflect.TypeOf((*RetrieveArgumentDescription)(nil)).Elem() +} + +type RetrieveArgumentDescriptionRequestType struct { + This ManagedObjectReference `xml:"_this"` + EventTypeId string `xml:"eventTypeId"` +} + +func init() { + t["RetrieveArgumentDescriptionRequestType"] = reflect.TypeOf((*RetrieveArgumentDescriptionRequestType)(nil)).Elem() +} + +type RetrieveArgumentDescriptionResponse struct { + Returnval []EventArgDesc `xml:"returnval,omitempty"` +} + +type RetrieveDasAdvancedRuntimeInfo RetrieveDasAdvancedRuntimeInfoRequestType + +func init() { + t["RetrieveDasAdvancedRuntimeInfo"] = reflect.TypeOf((*RetrieveDasAdvancedRuntimeInfo)(nil)).Elem() +} + +type RetrieveDasAdvancedRuntimeInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveDasAdvancedRuntimeInfoRequestType"] = reflect.TypeOf((*RetrieveDasAdvancedRuntimeInfoRequestType)(nil)).Elem() +} + +type RetrieveDasAdvancedRuntimeInfoResponse struct { + Returnval BaseClusterDasAdvancedRuntimeInfo `xml:"returnval,omitempty,typeattr"` +} + +type RetrieveDescription RetrieveDescriptionRequestType + +func init() { + t["RetrieveDescription"] = reflect.TypeOf((*RetrieveDescription)(nil)).Elem() +} + +type RetrieveDescriptionRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveDescriptionRequestType"] = reflect.TypeOf((*RetrieveDescriptionRequestType)(nil)).Elem() +} + +type RetrieveDescriptionResponse struct { + Returnval *ProfileDescription `xml:"returnval,omitempty"` +} + +type RetrieveDiskPartitionInfo RetrieveDiskPartitionInfoRequestType + +func init() { + t["RetrieveDiskPartitionInfo"] = reflect.TypeOf((*RetrieveDiskPartitionInfo)(nil)).Elem() +} + +type RetrieveDiskPartitionInfoRequestType struct { + This ManagedObjectReference `xml:"_this"` + DevicePath []string `xml:"devicePath"` +} + +func init() { + t["RetrieveDiskPartitionInfoRequestType"] = reflect.TypeOf((*RetrieveDiskPartitionInfoRequestType)(nil)).Elem() +} + +type RetrieveDiskPartitionInfoResponse struct { + Returnval []HostDiskPartitionInfo `xml:"returnval,omitempty"` +} + +type RetrieveEntityPermissions RetrieveEntityPermissionsRequestType + +func init() { + t["RetrieveEntityPermissions"] = reflect.TypeOf((*RetrieveEntityPermissions)(nil)).Elem() +} + +type RetrieveEntityPermissionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Inherited bool `xml:"inherited"` +} + +func init() { + t["RetrieveEntityPermissionsRequestType"] = reflect.TypeOf((*RetrieveEntityPermissionsRequestType)(nil)).Elem() +} + +type RetrieveEntityPermissionsResponse struct { + Returnval []Permission `xml:"returnval,omitempty"` +} + +type RetrieveEntityScheduledTask RetrieveEntityScheduledTaskRequestType + +func init() { + t["RetrieveEntityScheduledTask"] = reflect.TypeOf((*RetrieveEntityScheduledTask)(nil)).Elem() +} + +type RetrieveEntityScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["RetrieveEntityScheduledTaskRequestType"] = reflect.TypeOf((*RetrieveEntityScheduledTaskRequestType)(nil)).Elem() +} + +type RetrieveEntityScheduledTaskResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type RetrieveHardwareUptime RetrieveHardwareUptimeRequestType + +func init() { + t["RetrieveHardwareUptime"] = reflect.TypeOf((*RetrieveHardwareUptime)(nil)).Elem() +} + +type RetrieveHardwareUptimeRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveHardwareUptimeRequestType"] = reflect.TypeOf((*RetrieveHardwareUptimeRequestType)(nil)).Elem() +} + +type RetrieveHardwareUptimeResponse struct { + Returnval int64 `xml:"returnval"` +} + +type RetrieveHostAccessControlEntries RetrieveHostAccessControlEntriesRequestType + +func init() { + t["RetrieveHostAccessControlEntries"] = reflect.TypeOf((*RetrieveHostAccessControlEntries)(nil)).Elem() +} + +type RetrieveHostAccessControlEntriesRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveHostAccessControlEntriesRequestType"] = reflect.TypeOf((*RetrieveHostAccessControlEntriesRequestType)(nil)).Elem() +} + +type RetrieveHostAccessControlEntriesResponse struct { + Returnval []HostAccessControlEntry `xml:"returnval,omitempty"` +} + +type RetrieveObjectScheduledTask RetrieveObjectScheduledTaskRequestType + +func init() { + t["RetrieveObjectScheduledTask"] = reflect.TypeOf((*RetrieveObjectScheduledTask)(nil)).Elem() +} + +type RetrieveObjectScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Obj *ManagedObjectReference `xml:"obj,omitempty"` +} + +func init() { + t["RetrieveObjectScheduledTaskRequestType"] = reflect.TypeOf((*RetrieveObjectScheduledTaskRequestType)(nil)).Elem() +} + +type RetrieveObjectScheduledTaskResponse struct { + Returnval []ManagedObjectReference `xml:"returnval,omitempty"` +} + +type RetrieveOptions struct { + DynamicData + + MaxObjects int32 `xml:"maxObjects,omitempty"` +} + +func init() { + t["RetrieveOptions"] = reflect.TypeOf((*RetrieveOptions)(nil)).Elem() +} + +type RetrieveProductComponents RetrieveProductComponentsRequestType + +func init() { + t["RetrieveProductComponents"] = reflect.TypeOf((*RetrieveProductComponents)(nil)).Elem() +} + +type RetrieveProductComponentsRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveProductComponentsRequestType"] = reflect.TypeOf((*RetrieveProductComponentsRequestType)(nil)).Elem() +} + +type RetrieveProductComponentsResponse struct { + Returnval []ProductComponentInfo `xml:"returnval,omitempty"` +} + +type RetrieveProperties RetrievePropertiesRequestType + +func init() { + t["RetrieveProperties"] = reflect.TypeOf((*RetrieveProperties)(nil)).Elem() +} + +type RetrievePropertiesEx RetrievePropertiesExRequestType + +func init() { + t["RetrievePropertiesEx"] = reflect.TypeOf((*RetrievePropertiesEx)(nil)).Elem() +} + +type RetrievePropertiesExRequestType struct { + This ManagedObjectReference `xml:"_this"` + SpecSet []PropertyFilterSpec `xml:"specSet"` + Options RetrieveOptions `xml:"options"` +} + +func init() { + t["RetrievePropertiesExRequestType"] = reflect.TypeOf((*RetrievePropertiesExRequestType)(nil)).Elem() +} + +type RetrievePropertiesExResponse struct { + Returnval *RetrieveResult `xml:"returnval,omitempty"` +} + +type RetrievePropertiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + SpecSet []PropertyFilterSpec `xml:"specSet"` +} + +func init() { + t["RetrievePropertiesRequestType"] = reflect.TypeOf((*RetrievePropertiesRequestType)(nil)).Elem() +} + +type RetrievePropertiesResponse struct { + Returnval []ObjectContent `xml:"returnval,omitempty"` +} + +type RetrieveResult struct { + DynamicData + + Token string `xml:"token,omitempty"` + Objects []ObjectContent `xml:"objects"` +} + +func init() { + t["RetrieveResult"] = reflect.TypeOf((*RetrieveResult)(nil)).Elem() +} + +type RetrieveRolePermissions RetrieveRolePermissionsRequestType + +func init() { + t["RetrieveRolePermissions"] = reflect.TypeOf((*RetrieveRolePermissions)(nil)).Elem() +} + +type RetrieveRolePermissionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + RoleId int32 `xml:"roleId"` +} + +func init() { + t["RetrieveRolePermissionsRequestType"] = reflect.TypeOf((*RetrieveRolePermissionsRequestType)(nil)).Elem() +} + +type RetrieveRolePermissionsResponse struct { + Returnval []Permission `xml:"returnval,omitempty"` +} + +type RetrieveServiceContent RetrieveServiceContentRequestType + +func init() { + t["RetrieveServiceContent"] = reflect.TypeOf((*RetrieveServiceContent)(nil)).Elem() +} + +type RetrieveServiceContentRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RetrieveServiceContentRequestType"] = reflect.TypeOf((*RetrieveServiceContentRequestType)(nil)).Elem() +} + +type RetrieveServiceContentResponse struct { + Returnval ServiceContent `xml:"returnval"` +} + +type RetrieveUserGroups RetrieveUserGroupsRequestType + +func init() { + t["RetrieveUserGroups"] = reflect.TypeOf((*RetrieveUserGroups)(nil)).Elem() +} + +type RetrieveUserGroupsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Domain string `xml:"domain,omitempty"` + SearchStr string `xml:"searchStr"` + BelongsToGroup string `xml:"belongsToGroup,omitempty"` + BelongsToUser string `xml:"belongsToUser,omitempty"` + ExactMatch bool `xml:"exactMatch"` + FindUsers bool `xml:"findUsers"` + FindGroups bool `xml:"findGroups"` +} + +func init() { + t["RetrieveUserGroupsRequestType"] = reflect.TypeOf((*RetrieveUserGroupsRequestType)(nil)).Elem() +} + +type RetrieveUserGroupsResponse struct { + Returnval []BaseUserSearchResult `xml:"returnval,omitempty,typeattr"` +} + +type RevertToCurrentSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + SuppressPowerOn *bool `xml:"suppressPowerOn"` +} + +func init() { + t["RevertToCurrentSnapshotRequestType"] = reflect.TypeOf((*RevertToCurrentSnapshotRequestType)(nil)).Elem() +} + +type RevertToCurrentSnapshot_Task RevertToCurrentSnapshotRequestType + +func init() { + t["RevertToCurrentSnapshot_Task"] = reflect.TypeOf((*RevertToCurrentSnapshot_Task)(nil)).Elem() +} + +type RevertToCurrentSnapshot_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RevertToSnapshotRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + SuppressPowerOn *bool `xml:"suppressPowerOn"` +} + +func init() { + t["RevertToSnapshotRequestType"] = reflect.TypeOf((*RevertToSnapshotRequestType)(nil)).Elem() +} + +type RevertToSnapshot_Task RevertToSnapshotRequestType + +func init() { + t["RevertToSnapshot_Task"] = reflect.TypeOf((*RevertToSnapshot_Task)(nil)).Elem() +} + +type RevertToSnapshot_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type RewindCollector RewindCollectorRequestType + +func init() { + t["RewindCollector"] = reflect.TypeOf((*RewindCollector)(nil)).Elem() +} + +type RewindCollectorRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RewindCollectorRequestType"] = reflect.TypeOf((*RewindCollectorRequestType)(nil)).Elem() +} + +type RewindCollectorResponse struct { +} + +type RoleAddedEvent struct { + RoleEvent + + PrivilegeList []string `xml:"privilegeList,omitempty"` +} + +func init() { + t["RoleAddedEvent"] = reflect.TypeOf((*RoleAddedEvent)(nil)).Elem() +} + +type RoleEvent struct { + AuthorizationEvent + + Role RoleEventArgument `xml:"role"` +} + +func init() { + t["RoleEvent"] = reflect.TypeOf((*RoleEvent)(nil)).Elem() +} + +type RoleEventArgument struct { + EventArgument + + RoleId int32 `xml:"roleId"` + Name string `xml:"name"` +} + +func init() { + t["RoleEventArgument"] = reflect.TypeOf((*RoleEventArgument)(nil)).Elem() +} + +type RoleRemovedEvent struct { + RoleEvent +} + +func init() { + t["RoleRemovedEvent"] = reflect.TypeOf((*RoleRemovedEvent)(nil)).Elem() +} + +type RoleUpdatedEvent struct { + RoleEvent + + PrivilegeList []string `xml:"privilegeList,omitempty"` +} + +func init() { + t["RoleUpdatedEvent"] = reflect.TypeOf((*RoleUpdatedEvent)(nil)).Elem() +} + +type RollbackEvent struct { + DvsEvent + + HostName string `xml:"hostName"` + MethodName string `xml:"methodName,omitempty"` +} + +func init() { + t["RollbackEvent"] = reflect.TypeOf((*RollbackEvent)(nil)).Elem() +} + +type RollbackFailure struct { + DvsFault + + EntityName string `xml:"entityName"` + EntityType string `xml:"entityType"` +} + +func init() { + t["RollbackFailure"] = reflect.TypeOf((*RollbackFailure)(nil)).Elem() +} + +type RollbackFailureFault RollbackFailure + +func init() { + t["RollbackFailureFault"] = reflect.TypeOf((*RollbackFailureFault)(nil)).Elem() +} + +type RuleViolation struct { + VmConfigFault + + Host *ManagedObjectReference `xml:"host,omitempty"` + Rule BaseClusterRuleInfo `xml:"rule,omitempty,typeattr"` +} + +func init() { + t["RuleViolation"] = reflect.TypeOf((*RuleViolation)(nil)).Elem() +} + +type RuleViolationFault RuleViolation + +func init() { + t["RuleViolationFault"] = reflect.TypeOf((*RuleViolationFault)(nil)).Elem() +} + +type RunScheduledTask RunScheduledTaskRequestType + +func init() { + t["RunScheduledTask"] = reflect.TypeOf((*RunScheduledTask)(nil)).Elem() +} + +type RunScheduledTaskRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["RunScheduledTaskRequestType"] = reflect.TypeOf((*RunScheduledTaskRequestType)(nil)).Elem() +} + +type RunScheduledTaskResponse struct { +} + +type RunScriptAction struct { + Action + + Script string `xml:"script"` +} + +func init() { + t["RunScriptAction"] = reflect.TypeOf((*RunScriptAction)(nil)).Elem() +} + +type RunVsanPhysicalDiskDiagnostics RunVsanPhysicalDiskDiagnosticsRequestType + +func init() { + t["RunVsanPhysicalDiskDiagnostics"] = reflect.TypeOf((*RunVsanPhysicalDiskDiagnostics)(nil)).Elem() +} + +type RunVsanPhysicalDiskDiagnosticsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Disks []string `xml:"disks,omitempty"` +} + +func init() { + t["RunVsanPhysicalDiskDiagnosticsRequestType"] = reflect.TypeOf((*RunVsanPhysicalDiskDiagnosticsRequestType)(nil)).Elem() +} + +type RunVsanPhysicalDiskDiagnosticsResponse struct { + Returnval []HostVsanInternalSystemVsanPhysicalDiskDiagnosticsResult `xml:"returnval"` +} + +type RuntimeFault struct { + MethodFault +} + +func init() { + t["RuntimeFault"] = reflect.TypeOf((*RuntimeFault)(nil)).Elem() +} + +type RuntimeFaultFault BaseRuntimeFault + +func init() { + t["RuntimeFaultFault"] = reflect.TypeOf((*RuntimeFaultFault)(nil)).Elem() +} + +type SAMLTokenAuthentication struct { + GuestAuthentication + + Token string `xml:"token"` + Username string `xml:"username,omitempty"` +} + +func init() { + t["SAMLTokenAuthentication"] = reflect.TypeOf((*SAMLTokenAuthentication)(nil)).Elem() +} + +type SSLDisabledFault struct { + HostConnectFault +} + +func init() { + t["SSLDisabledFault"] = reflect.TypeOf((*SSLDisabledFault)(nil)).Elem() +} + +type SSLDisabledFaultFault SSLDisabledFault + +func init() { + t["SSLDisabledFaultFault"] = reflect.TypeOf((*SSLDisabledFaultFault)(nil)).Elem() +} + +type SSLVerifyFault struct { + HostConnectFault + + SelfSigned bool `xml:"selfSigned"` + Thumbprint string `xml:"thumbprint"` +} + +func init() { + t["SSLVerifyFault"] = reflect.TypeOf((*SSLVerifyFault)(nil)).Elem() +} + +type SSLVerifyFaultFault SSLVerifyFault + +func init() { + t["SSLVerifyFaultFault"] = reflect.TypeOf((*SSLVerifyFaultFault)(nil)).Elem() +} + +type SSPIAuthentication struct { + GuestAuthentication + + SspiToken string `xml:"sspiToken"` +} + +func init() { + t["SSPIAuthentication"] = reflect.TypeOf((*SSPIAuthentication)(nil)).Elem() +} + +type SSPIChallenge struct { + VimFault + + Base64Token string `xml:"base64Token"` +} + +func init() { + t["SSPIChallenge"] = reflect.TypeOf((*SSPIChallenge)(nil)).Elem() +} + +type SSPIChallengeFault SSPIChallenge + +func init() { + t["SSPIChallengeFault"] = reflect.TypeOf((*SSPIChallengeFault)(nil)).Elem() +} + +type ScanHostPatchRequestType struct { + This ManagedObjectReference `xml:"_this"` + Repository HostPatchManagerLocator `xml:"repository"` + UpdateID []string `xml:"updateID,omitempty"` +} + +func init() { + t["ScanHostPatchRequestType"] = reflect.TypeOf((*ScanHostPatchRequestType)(nil)).Elem() +} + +type ScanHostPatchV2RequestType struct { + This ManagedObjectReference `xml:"_this"` + MetaUrls []string `xml:"metaUrls,omitempty"` + BundleUrls []string `xml:"bundleUrls,omitempty"` + Spec *HostPatchManagerPatchManagerOperationSpec `xml:"spec,omitempty"` +} + +func init() { + t["ScanHostPatchV2RequestType"] = reflect.TypeOf((*ScanHostPatchV2RequestType)(nil)).Elem() +} + +type ScanHostPatchV2_Task ScanHostPatchV2RequestType + +func init() { + t["ScanHostPatchV2_Task"] = reflect.TypeOf((*ScanHostPatchV2_Task)(nil)).Elem() +} + +type ScanHostPatchV2_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ScanHostPatch_Task ScanHostPatchRequestType + +func init() { + t["ScanHostPatch_Task"] = reflect.TypeOf((*ScanHostPatch_Task)(nil)).Elem() +} + +type ScanHostPatch_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ScheduledHardwareUpgradeInfo struct { + DynamicData + + UpgradePolicy string `xml:"upgradePolicy,omitempty"` + VersionKey string `xml:"versionKey,omitempty"` + ScheduledHardwareUpgradeStatus string `xml:"scheduledHardwareUpgradeStatus,omitempty"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["ScheduledHardwareUpgradeInfo"] = reflect.TypeOf((*ScheduledHardwareUpgradeInfo)(nil)).Elem() +} + +type ScheduledTaskCompletedEvent struct { + ScheduledTaskEvent +} + +func init() { + t["ScheduledTaskCompletedEvent"] = reflect.TypeOf((*ScheduledTaskCompletedEvent)(nil)).Elem() +} + +type ScheduledTaskCreatedEvent struct { + ScheduledTaskEvent +} + +func init() { + t["ScheduledTaskCreatedEvent"] = reflect.TypeOf((*ScheduledTaskCreatedEvent)(nil)).Elem() +} + +type ScheduledTaskDescription struct { + DynamicData + + Action []BaseTypeDescription `xml:"action,typeattr"` + SchedulerInfo []ScheduledTaskDetail `xml:"schedulerInfo"` + State []BaseElementDescription `xml:"state,typeattr"` + DayOfWeek []BaseElementDescription `xml:"dayOfWeek,typeattr"` + WeekOfMonth []BaseElementDescription `xml:"weekOfMonth,typeattr"` +} + +func init() { + t["ScheduledTaskDescription"] = reflect.TypeOf((*ScheduledTaskDescription)(nil)).Elem() +} + +type ScheduledTaskDetail struct { + TypeDescription + + Frequency string `xml:"frequency"` +} + +func init() { + t["ScheduledTaskDetail"] = reflect.TypeOf((*ScheduledTaskDetail)(nil)).Elem() +} + +type ScheduledTaskEmailCompletedEvent struct { + ScheduledTaskEvent + + To string `xml:"to"` +} + +func init() { + t["ScheduledTaskEmailCompletedEvent"] = reflect.TypeOf((*ScheduledTaskEmailCompletedEvent)(nil)).Elem() +} + +type ScheduledTaskEmailFailedEvent struct { + ScheduledTaskEvent + + To string `xml:"to"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["ScheduledTaskEmailFailedEvent"] = reflect.TypeOf((*ScheduledTaskEmailFailedEvent)(nil)).Elem() +} + +type ScheduledTaskEvent struct { + Event + + ScheduledTask ScheduledTaskEventArgument `xml:"scheduledTask"` + Entity ManagedEntityEventArgument `xml:"entity"` +} + +func init() { + t["ScheduledTaskEvent"] = reflect.TypeOf((*ScheduledTaskEvent)(nil)).Elem() +} + +type ScheduledTaskEventArgument struct { + EntityEventArgument + + ScheduledTask ManagedObjectReference `xml:"scheduledTask"` +} + +func init() { + t["ScheduledTaskEventArgument"] = reflect.TypeOf((*ScheduledTaskEventArgument)(nil)).Elem() +} + +type ScheduledTaskFailedEvent struct { + ScheduledTaskEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["ScheduledTaskFailedEvent"] = reflect.TypeOf((*ScheduledTaskFailedEvent)(nil)).Elem() +} + +type ScheduledTaskInfo struct { + ScheduledTaskSpec + + ScheduledTask ManagedObjectReference `xml:"scheduledTask"` + Entity ManagedObjectReference `xml:"entity"` + LastModifiedTime time.Time `xml:"lastModifiedTime"` + LastModifiedUser string `xml:"lastModifiedUser"` + NextRunTime *time.Time `xml:"nextRunTime"` + PrevRunTime *time.Time `xml:"prevRunTime"` + State TaskInfoState `xml:"state"` + Error *LocalizedMethodFault `xml:"error,omitempty"` + Result AnyType `xml:"result,omitempty,typeattr"` + Progress int32 `xml:"progress,omitempty"` + ActiveTask *ManagedObjectReference `xml:"activeTask,omitempty"` + TaskObject *ManagedObjectReference `xml:"taskObject,omitempty"` +} + +func init() { + t["ScheduledTaskInfo"] = reflect.TypeOf((*ScheduledTaskInfo)(nil)).Elem() +} + +type ScheduledTaskReconfiguredEvent struct { + ScheduledTaskEvent +} + +func init() { + t["ScheduledTaskReconfiguredEvent"] = reflect.TypeOf((*ScheduledTaskReconfiguredEvent)(nil)).Elem() +} + +type ScheduledTaskRemovedEvent struct { + ScheduledTaskEvent +} + +func init() { + t["ScheduledTaskRemovedEvent"] = reflect.TypeOf((*ScheduledTaskRemovedEvent)(nil)).Elem() +} + +type ScheduledTaskSpec struct { + DynamicData + + Name string `xml:"name"` + Description string `xml:"description"` + Enabled bool `xml:"enabled"` + Scheduler BaseTaskScheduler `xml:"scheduler,typeattr"` + Action BaseAction `xml:"action,typeattr"` + Notification string `xml:"notification,omitempty"` +} + +func init() { + t["ScheduledTaskSpec"] = reflect.TypeOf((*ScheduledTaskSpec)(nil)).Elem() +} + +type ScheduledTaskStartedEvent struct { + ScheduledTaskEvent +} + +func init() { + t["ScheduledTaskStartedEvent"] = reflect.TypeOf((*ScheduledTaskStartedEvent)(nil)).Elem() +} + +type ScsiLun struct { + HostDevice + + Key string `xml:"key,omitempty"` + Uuid string `xml:"uuid"` + Descriptor []ScsiLunDescriptor `xml:"descriptor,omitempty"` + CanonicalName string `xml:"canonicalName,omitempty"` + DisplayName string `xml:"displayName,omitempty"` + LunType string `xml:"lunType"` + Vendor string `xml:"vendor,omitempty"` + Model string `xml:"model,omitempty"` + Revision string `xml:"revision,omitempty"` + ScsiLevel int32 `xml:"scsiLevel,omitempty"` + SerialNumber string `xml:"serialNumber,omitempty"` + DurableName *ScsiLunDurableName `xml:"durableName,omitempty"` + AlternateName []ScsiLunDurableName `xml:"alternateName,omitempty"` + StandardInquiry []byte `xml:"standardInquiry,omitempty"` + QueueDepth int32 `xml:"queueDepth,omitempty"` + OperationalState []string `xml:"operationalState"` + Capabilities *ScsiLunCapabilities `xml:"capabilities,omitempty"` + VStorageSupport string `xml:"vStorageSupport,omitempty"` + ProtocolEndpoint *bool `xml:"protocolEndpoint"` +} + +func init() { + t["ScsiLun"] = reflect.TypeOf((*ScsiLun)(nil)).Elem() +} + +type ScsiLunCapabilities struct { + DynamicData + + UpdateDisplayNameSupported bool `xml:"updateDisplayNameSupported"` +} + +func init() { + t["ScsiLunCapabilities"] = reflect.TypeOf((*ScsiLunCapabilities)(nil)).Elem() +} + +type ScsiLunDescriptor struct { + DynamicData + + Quality string `xml:"quality"` + Id string `xml:"id"` +} + +func init() { + t["ScsiLunDescriptor"] = reflect.TypeOf((*ScsiLunDescriptor)(nil)).Elem() +} + +type ScsiLunDurableName struct { + DynamicData + + Namespace string `xml:"namespace"` + NamespaceId byte `xml:"namespaceId"` + Data []byte `xml:"data,omitempty"` +} + +func init() { + t["ScsiLunDurableName"] = reflect.TypeOf((*ScsiLunDurableName)(nil)).Elem() +} + +type SeSparseVirtualDiskSpec struct { + FileBackedVirtualDiskSpec + + GrainSizeKb int32 `xml:"grainSizeKb,omitempty"` +} + +func init() { + t["SeSparseVirtualDiskSpec"] = reflect.TypeOf((*SeSparseVirtualDiskSpec)(nil)).Elem() +} + +type SearchDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + DatastorePath string `xml:"datastorePath"` + SearchSpec *HostDatastoreBrowserSearchSpec `xml:"searchSpec,omitempty"` +} + +func init() { + t["SearchDatastoreRequestType"] = reflect.TypeOf((*SearchDatastoreRequestType)(nil)).Elem() +} + +type SearchDatastoreSubFoldersRequestType struct { + This ManagedObjectReference `xml:"_this"` + DatastorePath string `xml:"datastorePath"` + SearchSpec *HostDatastoreBrowserSearchSpec `xml:"searchSpec,omitempty"` +} + +func init() { + t["SearchDatastoreSubFoldersRequestType"] = reflect.TypeOf((*SearchDatastoreSubFoldersRequestType)(nil)).Elem() +} + +type SearchDatastoreSubFolders_Task SearchDatastoreSubFoldersRequestType + +func init() { + t["SearchDatastoreSubFolders_Task"] = reflect.TypeOf((*SearchDatastoreSubFolders_Task)(nil)).Elem() +} + +type SearchDatastoreSubFolders_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type SearchDatastore_Task SearchDatastoreRequestType + +func init() { + t["SearchDatastore_Task"] = reflect.TypeOf((*SearchDatastore_Task)(nil)).Elem() +} + +type SearchDatastore_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type SecondaryVmAlreadyDisabled struct { + VmFaultToleranceIssue + + InstanceUuid string `xml:"instanceUuid"` +} + +func init() { + t["SecondaryVmAlreadyDisabled"] = reflect.TypeOf((*SecondaryVmAlreadyDisabled)(nil)).Elem() +} + +type SecondaryVmAlreadyDisabledFault SecondaryVmAlreadyDisabled + +func init() { + t["SecondaryVmAlreadyDisabledFault"] = reflect.TypeOf((*SecondaryVmAlreadyDisabledFault)(nil)).Elem() +} + +type SecondaryVmAlreadyEnabled struct { + VmFaultToleranceIssue + + InstanceUuid string `xml:"instanceUuid"` +} + +func init() { + t["SecondaryVmAlreadyEnabled"] = reflect.TypeOf((*SecondaryVmAlreadyEnabled)(nil)).Elem() +} + +type SecondaryVmAlreadyEnabledFault SecondaryVmAlreadyEnabled + +func init() { + t["SecondaryVmAlreadyEnabledFault"] = reflect.TypeOf((*SecondaryVmAlreadyEnabledFault)(nil)).Elem() +} + +type SecondaryVmAlreadyRegistered struct { + VmFaultToleranceIssue + + InstanceUuid string `xml:"instanceUuid,omitempty"` +} + +func init() { + t["SecondaryVmAlreadyRegistered"] = reflect.TypeOf((*SecondaryVmAlreadyRegistered)(nil)).Elem() +} + +type SecondaryVmAlreadyRegisteredFault SecondaryVmAlreadyRegistered + +func init() { + t["SecondaryVmAlreadyRegisteredFault"] = reflect.TypeOf((*SecondaryVmAlreadyRegisteredFault)(nil)).Elem() +} + +type SecondaryVmNotRegistered struct { + VmFaultToleranceIssue + + InstanceUuid string `xml:"instanceUuid,omitempty"` +} + +func init() { + t["SecondaryVmNotRegistered"] = reflect.TypeOf((*SecondaryVmNotRegistered)(nil)).Elem() +} + +type SecondaryVmNotRegisteredFault SecondaryVmNotRegistered + +func init() { + t["SecondaryVmNotRegisteredFault"] = reflect.TypeOf((*SecondaryVmNotRegisteredFault)(nil)).Elem() +} + +type SecurityError struct { + RuntimeFault +} + +func init() { + t["SecurityError"] = reflect.TypeOf((*SecurityError)(nil)).Elem() +} + +type SecurityErrorFault BaseSecurityError + +func init() { + t["SecurityErrorFault"] = reflect.TypeOf((*SecurityErrorFault)(nil)).Elem() +} + +type SecurityProfile struct { + ApplyProfile + + Permission []PermissionProfile `xml:"permission,omitempty"` +} + +func init() { + t["SecurityProfile"] = reflect.TypeOf((*SecurityProfile)(nil)).Elem() +} + +type SelectActivePartition SelectActivePartitionRequestType + +func init() { + t["SelectActivePartition"] = reflect.TypeOf((*SelectActivePartition)(nil)).Elem() +} + +type SelectActivePartitionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Partition *HostScsiDiskPartition `xml:"partition,omitempty"` +} + +func init() { + t["SelectActivePartitionRequestType"] = reflect.TypeOf((*SelectActivePartitionRequestType)(nil)).Elem() +} + +type SelectActivePartitionResponse struct { +} + +type SelectVnic SelectVnicRequestType + +func init() { + t["SelectVnic"] = reflect.TypeOf((*SelectVnic)(nil)).Elem() +} + +type SelectVnicForNicType SelectVnicForNicTypeRequestType + +func init() { + t["SelectVnicForNicType"] = reflect.TypeOf((*SelectVnicForNicType)(nil)).Elem() +} + +type SelectVnicForNicTypeRequestType struct { + This ManagedObjectReference `xml:"_this"` + NicType string `xml:"nicType"` + Device string `xml:"device"` +} + +func init() { + t["SelectVnicForNicTypeRequestType"] = reflect.TypeOf((*SelectVnicForNicTypeRequestType)(nil)).Elem() +} + +type SelectVnicForNicTypeResponse struct { +} + +type SelectVnicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` +} + +func init() { + t["SelectVnicRequestType"] = reflect.TypeOf((*SelectVnicRequestType)(nil)).Elem() +} + +type SelectVnicResponse struct { +} + +type SelectionSet struct { + DynamicData +} + +func init() { + t["SelectionSet"] = reflect.TypeOf((*SelectionSet)(nil)).Elem() +} + +type SelectionSpec struct { + DynamicData + + Name string `xml:"name,omitempty"` +} + +func init() { + t["SelectionSpec"] = reflect.TypeOf((*SelectionSpec)(nil)).Elem() +} + +type SendEmailAction struct { + Action + + ToList string `xml:"toList"` + CcList string `xml:"ccList"` + Subject string `xml:"subject"` + Body string `xml:"body"` +} + +func init() { + t["SendEmailAction"] = reflect.TypeOf((*SendEmailAction)(nil)).Elem() +} + +type SendNMI SendNMIRequestType + +func init() { + t["SendNMI"] = reflect.TypeOf((*SendNMI)(nil)).Elem() +} + +type SendNMIRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["SendNMIRequestType"] = reflect.TypeOf((*SendNMIRequestType)(nil)).Elem() +} + +type SendNMIResponse struct { +} + +type SendSNMPAction struct { + Action +} + +func init() { + t["SendSNMPAction"] = reflect.TypeOf((*SendSNMPAction)(nil)).Elem() +} + +type SendTestNotification SendTestNotificationRequestType + +func init() { + t["SendTestNotification"] = reflect.TypeOf((*SendTestNotification)(nil)).Elem() +} + +type SendTestNotificationRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["SendTestNotificationRequestType"] = reflect.TypeOf((*SendTestNotificationRequestType)(nil)).Elem() +} + +type SendTestNotificationResponse struct { +} + +type ServerLicenseExpiredEvent struct { + LicenseEvent + + Product string `xml:"product"` +} + +func init() { + t["ServerLicenseExpiredEvent"] = reflect.TypeOf((*ServerLicenseExpiredEvent)(nil)).Elem() +} + +type ServerStartedSessionEvent struct { + SessionEvent +} + +func init() { + t["ServerStartedSessionEvent"] = reflect.TypeOf((*ServerStartedSessionEvent)(nil)).Elem() +} + +type ServiceConsolePortGroupProfile struct { + PortGroupProfile + + IpConfig IpAddressProfile `xml:"ipConfig"` +} + +func init() { + t["ServiceConsolePortGroupProfile"] = reflect.TypeOf((*ServiceConsolePortGroupProfile)(nil)).Elem() +} + +type ServiceConsoleReservationInfo struct { + DynamicData + + ServiceConsoleReservedCfg int64 `xml:"serviceConsoleReservedCfg"` + ServiceConsoleReserved int64 `xml:"serviceConsoleReserved"` + Unreserved int64 `xml:"unreserved"` +} + +func init() { + t["ServiceConsoleReservationInfo"] = reflect.TypeOf((*ServiceConsoleReservationInfo)(nil)).Elem() +} + +type ServiceContent struct { + DynamicData + + RootFolder ManagedObjectReference `xml:"rootFolder"` + PropertyCollector ManagedObjectReference `xml:"propertyCollector"` + ViewManager *ManagedObjectReference `xml:"viewManager,omitempty"` + About AboutInfo `xml:"about"` + Setting *ManagedObjectReference `xml:"setting,omitempty"` + UserDirectory *ManagedObjectReference `xml:"userDirectory,omitempty"` + SessionManager *ManagedObjectReference `xml:"sessionManager,omitempty"` + AuthorizationManager *ManagedObjectReference `xml:"authorizationManager,omitempty"` + ServiceManager *ManagedObjectReference `xml:"serviceManager,omitempty"` + PerfManager *ManagedObjectReference `xml:"perfManager,omitempty"` + ScheduledTaskManager *ManagedObjectReference `xml:"scheduledTaskManager,omitempty"` + AlarmManager *ManagedObjectReference `xml:"alarmManager,omitempty"` + EventManager *ManagedObjectReference `xml:"eventManager,omitempty"` + TaskManager *ManagedObjectReference `xml:"taskManager,omitempty"` + ExtensionManager *ManagedObjectReference `xml:"extensionManager,omitempty"` + CustomizationSpecManager *ManagedObjectReference `xml:"customizationSpecManager,omitempty"` + CustomFieldsManager *ManagedObjectReference `xml:"customFieldsManager,omitempty"` + AccountManager *ManagedObjectReference `xml:"accountManager,omitempty"` + DiagnosticManager *ManagedObjectReference `xml:"diagnosticManager,omitempty"` + LicenseManager *ManagedObjectReference `xml:"licenseManager,omitempty"` + SearchIndex *ManagedObjectReference `xml:"searchIndex,omitempty"` + FileManager *ManagedObjectReference `xml:"fileManager,omitempty"` + DatastoreNamespaceManager *ManagedObjectReference `xml:"datastoreNamespaceManager,omitempty"` + VirtualDiskManager *ManagedObjectReference `xml:"virtualDiskManager,omitempty"` + VirtualizationManager *ManagedObjectReference `xml:"virtualizationManager,omitempty"` + SnmpSystem *ManagedObjectReference `xml:"snmpSystem,omitempty"` + VmProvisioningChecker *ManagedObjectReference `xml:"vmProvisioningChecker,omitempty"` + VmCompatibilityChecker *ManagedObjectReference `xml:"vmCompatibilityChecker,omitempty"` + OvfManager *ManagedObjectReference `xml:"ovfManager,omitempty"` + IpPoolManager *ManagedObjectReference `xml:"ipPoolManager,omitempty"` + DvSwitchManager *ManagedObjectReference `xml:"dvSwitchManager,omitempty"` + HostProfileManager *ManagedObjectReference `xml:"hostProfileManager,omitempty"` + ClusterProfileManager *ManagedObjectReference `xml:"clusterProfileManager,omitempty"` + ComplianceManager *ManagedObjectReference `xml:"complianceManager,omitempty"` + LocalizationManager *ManagedObjectReference `xml:"localizationManager,omitempty"` + StorageResourceManager *ManagedObjectReference `xml:"storageResourceManager,omitempty"` + GuestOperationsManager *ManagedObjectReference `xml:"guestOperationsManager,omitempty"` + OverheadMemoryManager *ManagedObjectReference `xml:"overheadMemoryManager,omitempty"` + CertificateManager *ManagedObjectReference `xml:"certificateManager,omitempty"` + IoFilterManager *ManagedObjectReference `xml:"ioFilterManager,omitempty"` +} + +func init() { + t["ServiceContent"] = reflect.TypeOf((*ServiceContent)(nil)).Elem() +} + +type ServiceLocator struct { + DynamicData + + InstanceUuid string `xml:"instanceUuid"` + Url string `xml:"url"` + Credential BaseServiceLocatorCredential `xml:"credential,typeattr"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` +} + +func init() { + t["ServiceLocator"] = reflect.TypeOf((*ServiceLocator)(nil)).Elem() +} + +type ServiceLocatorCredential struct { + DynamicData +} + +func init() { + t["ServiceLocatorCredential"] = reflect.TypeOf((*ServiceLocatorCredential)(nil)).Elem() +} + +type ServiceLocatorNamePassword struct { + ServiceLocatorCredential + + Username string `xml:"username"` + Password string `xml:"password"` +} + +func init() { + t["ServiceLocatorNamePassword"] = reflect.TypeOf((*ServiceLocatorNamePassword)(nil)).Elem() +} + +type ServiceLocatorSAMLCredential struct { + ServiceLocatorCredential + + Token string `xml:"token,omitempty"` +} + +func init() { + t["ServiceLocatorSAMLCredential"] = reflect.TypeOf((*ServiceLocatorSAMLCredential)(nil)).Elem() +} + +type ServiceManagerServiceInfo struct { + DynamicData + + ServiceName string `xml:"serviceName"` + Location []string `xml:"location,omitempty"` + Service ManagedObjectReference `xml:"service"` + Description string `xml:"description"` +} + +func init() { + t["ServiceManagerServiceInfo"] = reflect.TypeOf((*ServiceManagerServiceInfo)(nil)).Elem() +} + +type ServiceProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["ServiceProfile"] = reflect.TypeOf((*ServiceProfile)(nil)).Elem() +} + +type SessionEvent struct { + Event +} + +func init() { + t["SessionEvent"] = reflect.TypeOf((*SessionEvent)(nil)).Elem() +} + +type SessionIsActive SessionIsActiveRequestType + +func init() { + t["SessionIsActive"] = reflect.TypeOf((*SessionIsActive)(nil)).Elem() +} + +type SessionIsActiveRequestType struct { + This ManagedObjectReference `xml:"_this"` + SessionID string `xml:"sessionID"` + UserName string `xml:"userName"` +} + +func init() { + t["SessionIsActiveRequestType"] = reflect.TypeOf((*SessionIsActiveRequestType)(nil)).Elem() +} + +type SessionIsActiveResponse struct { + Returnval bool `xml:"returnval"` +} + +type SessionManagerGenericServiceTicket struct { + DynamicData + + Id string `xml:"id"` + HostName string `xml:"hostName,omitempty"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` +} + +func init() { + t["SessionManagerGenericServiceTicket"] = reflect.TypeOf((*SessionManagerGenericServiceTicket)(nil)).Elem() +} + +type SessionManagerHttpServiceRequestSpec struct { + SessionManagerServiceRequestSpec + + Method string `xml:"method,omitempty"` + Url string `xml:"url"` +} + +func init() { + t["SessionManagerHttpServiceRequestSpec"] = reflect.TypeOf((*SessionManagerHttpServiceRequestSpec)(nil)).Elem() +} + +type SessionManagerLocalTicket struct { + DynamicData + + UserName string `xml:"userName"` + PasswordFilePath string `xml:"passwordFilePath"` +} + +func init() { + t["SessionManagerLocalTicket"] = reflect.TypeOf((*SessionManagerLocalTicket)(nil)).Elem() +} + +type SessionManagerServiceRequestSpec struct { + DynamicData +} + +func init() { + t["SessionManagerServiceRequestSpec"] = reflect.TypeOf((*SessionManagerServiceRequestSpec)(nil)).Elem() +} + +type SessionManagerVmomiServiceRequestSpec struct { + SessionManagerServiceRequestSpec + + Method string `xml:"method"` +} + +func init() { + t["SessionManagerVmomiServiceRequestSpec"] = reflect.TypeOf((*SessionManagerVmomiServiceRequestSpec)(nil)).Elem() +} + +type SessionTerminatedEvent struct { + SessionEvent + + SessionId string `xml:"sessionId"` + TerminatedUsername string `xml:"terminatedUsername"` +} + +func init() { + t["SessionTerminatedEvent"] = reflect.TypeOf((*SessionTerminatedEvent)(nil)).Elem() +} + +type SetCollectorPageSize SetCollectorPageSizeRequestType + +func init() { + t["SetCollectorPageSize"] = reflect.TypeOf((*SetCollectorPageSize)(nil)).Elem() +} + +type SetCollectorPageSizeRequestType struct { + This ManagedObjectReference `xml:"_this"` + MaxCount int32 `xml:"maxCount"` +} + +func init() { + t["SetCollectorPageSizeRequestType"] = reflect.TypeOf((*SetCollectorPageSizeRequestType)(nil)).Elem() +} + +type SetCollectorPageSizeResponse struct { +} + +type SetDisplayTopology SetDisplayTopologyRequestType + +func init() { + t["SetDisplayTopology"] = reflect.TypeOf((*SetDisplayTopology)(nil)).Elem() +} + +type SetDisplayTopologyRequestType struct { + This ManagedObjectReference `xml:"_this"` + Displays []VirtualMachineDisplayTopology `xml:"displays"` +} + +func init() { + t["SetDisplayTopologyRequestType"] = reflect.TypeOf((*SetDisplayTopologyRequestType)(nil)).Elem() +} + +type SetDisplayTopologyResponse struct { +} + +type SetEntityPermissions SetEntityPermissionsRequestType + +func init() { + t["SetEntityPermissions"] = reflect.TypeOf((*SetEntityPermissions)(nil)).Elem() +} + +type SetEntityPermissionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Permission []Permission `xml:"permission,omitempty"` +} + +func init() { + t["SetEntityPermissionsRequestType"] = reflect.TypeOf((*SetEntityPermissionsRequestType)(nil)).Elem() +} + +type SetEntityPermissionsResponse struct { +} + +type SetExtensionCertificate SetExtensionCertificateRequestType + +func init() { + t["SetExtensionCertificate"] = reflect.TypeOf((*SetExtensionCertificate)(nil)).Elem() +} + +type SetExtensionCertificateRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` + CertificatePem string `xml:"certificatePem,omitempty"` +} + +func init() { + t["SetExtensionCertificateRequestType"] = reflect.TypeOf((*SetExtensionCertificateRequestType)(nil)).Elem() +} + +type SetExtensionCertificateResponse struct { +} + +type SetField SetFieldRequestType + +func init() { + t["SetField"] = reflect.TypeOf((*SetField)(nil)).Elem() +} + +type SetFieldRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity ManagedObjectReference `xml:"entity"` + Key int32 `xml:"key"` + Value string `xml:"value"` +} + +func init() { + t["SetFieldRequestType"] = reflect.TypeOf((*SetFieldRequestType)(nil)).Elem() +} + +type SetFieldResponse struct { +} + +type SetLicenseEdition SetLicenseEditionRequestType + +func init() { + t["SetLicenseEdition"] = reflect.TypeOf((*SetLicenseEdition)(nil)).Elem() +} + +type SetLicenseEditionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` + FeatureKey string `xml:"featureKey,omitempty"` +} + +func init() { + t["SetLicenseEditionRequestType"] = reflect.TypeOf((*SetLicenseEditionRequestType)(nil)).Elem() +} + +type SetLicenseEditionResponse struct { +} + +type SetLocale SetLocaleRequestType + +func init() { + t["SetLocale"] = reflect.TypeOf((*SetLocale)(nil)).Elem() +} + +type SetLocaleRequestType struct { + This ManagedObjectReference `xml:"_this"` + Locale string `xml:"locale"` +} + +func init() { + t["SetLocaleRequestType"] = reflect.TypeOf((*SetLocaleRequestType)(nil)).Elem() +} + +type SetLocaleResponse struct { +} + +type SetMultipathLunPolicy SetMultipathLunPolicyRequestType + +func init() { + t["SetMultipathLunPolicy"] = reflect.TypeOf((*SetMultipathLunPolicy)(nil)).Elem() +} + +type SetMultipathLunPolicyRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunId string `xml:"lunId"` + Policy BaseHostMultipathInfoLogicalUnitPolicy `xml:"policy,typeattr"` +} + +func init() { + t["SetMultipathLunPolicyRequestType"] = reflect.TypeOf((*SetMultipathLunPolicyRequestType)(nil)).Elem() +} + +type SetMultipathLunPolicyResponse struct { +} + +type SetNFSUser SetNFSUserRequestType + +func init() { + t["SetNFSUser"] = reflect.TypeOf((*SetNFSUser)(nil)).Elem() +} + +type SetNFSUserRequestType struct { + This ManagedObjectReference `xml:"_this"` + User string `xml:"user"` + Password string `xml:"password"` +} + +func init() { + t["SetNFSUserRequestType"] = reflect.TypeOf((*SetNFSUserRequestType)(nil)).Elem() +} + +type SetNFSUserResponse struct { +} + +type SetPublicKey SetPublicKeyRequestType + +func init() { + t["SetPublicKey"] = reflect.TypeOf((*SetPublicKey)(nil)).Elem() +} + +type SetPublicKeyRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` + PublicKey string `xml:"publicKey"` +} + +func init() { + t["SetPublicKeyRequestType"] = reflect.TypeOf((*SetPublicKeyRequestType)(nil)).Elem() +} + +type SetPublicKeyResponse struct { +} + +type SetRegistryValueInGuest SetRegistryValueInGuestRequestType + +func init() { + t["SetRegistryValueInGuest"] = reflect.TypeOf((*SetRegistryValueInGuest)(nil)).Elem() +} + +type SetRegistryValueInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Value GuestRegValueSpec `xml:"value"` +} + +func init() { + t["SetRegistryValueInGuestRequestType"] = reflect.TypeOf((*SetRegistryValueInGuestRequestType)(nil)).Elem() +} + +type SetRegistryValueInGuestResponse struct { +} + +type SetScreenResolution SetScreenResolutionRequestType + +func init() { + t["SetScreenResolution"] = reflect.TypeOf((*SetScreenResolution)(nil)).Elem() +} + +type SetScreenResolutionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Width int32 `xml:"width"` + Height int32 `xml:"height"` +} + +func init() { + t["SetScreenResolutionRequestType"] = reflect.TypeOf((*SetScreenResolutionRequestType)(nil)).Elem() +} + +type SetScreenResolutionResponse struct { +} + +type SetTaskDescription SetTaskDescriptionRequestType + +func init() { + t["SetTaskDescription"] = reflect.TypeOf((*SetTaskDescription)(nil)).Elem() +} + +type SetTaskDescriptionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Description LocalizableMessage `xml:"description"` +} + +func init() { + t["SetTaskDescriptionRequestType"] = reflect.TypeOf((*SetTaskDescriptionRequestType)(nil)).Elem() +} + +type SetTaskDescriptionResponse struct { +} + +type SetTaskState SetTaskStateRequestType + +func init() { + t["SetTaskState"] = reflect.TypeOf((*SetTaskState)(nil)).Elem() +} + +type SetTaskStateRequestType struct { + This ManagedObjectReference `xml:"_this"` + State TaskInfoState `xml:"state"` + Result AnyType `xml:"result,omitempty,typeattr"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["SetTaskStateRequestType"] = reflect.TypeOf((*SetTaskStateRequestType)(nil)).Elem() +} + +type SetTaskStateResponse struct { +} + +type SetVirtualDiskUuid SetVirtualDiskUuidRequestType + +func init() { + t["SetVirtualDiskUuid"] = reflect.TypeOf((*SetVirtualDiskUuid)(nil)).Elem() +} + +type SetVirtualDiskUuidRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Uuid string `xml:"uuid"` +} + +func init() { + t["SetVirtualDiskUuidRequestType"] = reflect.TypeOf((*SetVirtualDiskUuidRequestType)(nil)).Elem() +} + +type SetVirtualDiskUuidResponse struct { +} + +type SharedBusControllerNotSupported struct { + DeviceNotSupported +} + +func init() { + t["SharedBusControllerNotSupported"] = reflect.TypeOf((*SharedBusControllerNotSupported)(nil)).Elem() +} + +type SharedBusControllerNotSupportedFault SharedBusControllerNotSupported + +func init() { + t["SharedBusControllerNotSupportedFault"] = reflect.TypeOf((*SharedBusControllerNotSupportedFault)(nil)).Elem() +} + +type SharesInfo struct { + DynamicData + + Shares int32 `xml:"shares"` + Level SharesLevel `xml:"level"` +} + +func init() { + t["SharesInfo"] = reflect.TypeOf((*SharesInfo)(nil)).Elem() +} + +type SharesOption struct { + DynamicData + + SharesOption IntOption `xml:"sharesOption"` + DefaultLevel SharesLevel `xml:"defaultLevel"` +} + +func init() { + t["SharesOption"] = reflect.TypeOf((*SharesOption)(nil)).Elem() +} + +type ShrinkDiskFault struct { + VimFault + + DiskId int32 `xml:"diskId,omitempty"` +} + +func init() { + t["ShrinkDiskFault"] = reflect.TypeOf((*ShrinkDiskFault)(nil)).Elem() +} + +type ShrinkDiskFaultFault ShrinkDiskFault + +func init() { + t["ShrinkDiskFaultFault"] = reflect.TypeOf((*ShrinkDiskFaultFault)(nil)).Elem() +} + +type ShrinkVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` + Copy *bool `xml:"copy"` +} + +func init() { + t["ShrinkVirtualDiskRequestType"] = reflect.TypeOf((*ShrinkVirtualDiskRequestType)(nil)).Elem() +} + +type ShrinkVirtualDisk_Task ShrinkVirtualDiskRequestType + +func init() { + t["ShrinkVirtualDisk_Task"] = reflect.TypeOf((*ShrinkVirtualDisk_Task)(nil)).Elem() +} + +type ShrinkVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type ShutdownGuest ShutdownGuestRequestType + +func init() { + t["ShutdownGuest"] = reflect.TypeOf((*ShutdownGuest)(nil)).Elem() +} + +type ShutdownGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["ShutdownGuestRequestType"] = reflect.TypeOf((*ShutdownGuestRequestType)(nil)).Elem() +} + +type ShutdownGuestResponse struct { +} + +type ShutdownHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Force bool `xml:"force"` +} + +func init() { + t["ShutdownHostRequestType"] = reflect.TypeOf((*ShutdownHostRequestType)(nil)).Elem() +} + +type ShutdownHost_Task ShutdownHostRequestType + +func init() { + t["ShutdownHost_Task"] = reflect.TypeOf((*ShutdownHost_Task)(nil)).Elem() +} + +type ShutdownHost_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type SingleIp struct { + IpAddress + + Address string `xml:"address"` +} + +func init() { + t["SingleIp"] = reflect.TypeOf((*SingleIp)(nil)).Elem() +} + +type SingleMac struct { + MacAddress + + Address string `xml:"address"` +} + +func init() { + t["SingleMac"] = reflect.TypeOf((*SingleMac)(nil)).Elem() +} + +type SnapshotCloneNotSupported struct { + SnapshotCopyNotSupported +} + +func init() { + t["SnapshotCloneNotSupported"] = reflect.TypeOf((*SnapshotCloneNotSupported)(nil)).Elem() +} + +type SnapshotCloneNotSupportedFault SnapshotCloneNotSupported + +func init() { + t["SnapshotCloneNotSupportedFault"] = reflect.TypeOf((*SnapshotCloneNotSupportedFault)(nil)).Elem() +} + +type SnapshotCopyNotSupported struct { + MigrationFault +} + +func init() { + t["SnapshotCopyNotSupported"] = reflect.TypeOf((*SnapshotCopyNotSupported)(nil)).Elem() +} + +type SnapshotCopyNotSupportedFault BaseSnapshotCopyNotSupported + +func init() { + t["SnapshotCopyNotSupportedFault"] = reflect.TypeOf((*SnapshotCopyNotSupportedFault)(nil)).Elem() +} + +type SnapshotDisabled struct { + SnapshotFault +} + +func init() { + t["SnapshotDisabled"] = reflect.TypeOf((*SnapshotDisabled)(nil)).Elem() +} + +type SnapshotDisabledFault SnapshotDisabled + +func init() { + t["SnapshotDisabledFault"] = reflect.TypeOf((*SnapshotDisabledFault)(nil)).Elem() +} + +type SnapshotFault struct { + VimFault +} + +func init() { + t["SnapshotFault"] = reflect.TypeOf((*SnapshotFault)(nil)).Elem() +} + +type SnapshotFaultFault BaseSnapshotFault + +func init() { + t["SnapshotFaultFault"] = reflect.TypeOf((*SnapshotFaultFault)(nil)).Elem() +} + +type SnapshotIncompatibleDeviceInVm struct { + SnapshotFault + + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["SnapshotIncompatibleDeviceInVm"] = reflect.TypeOf((*SnapshotIncompatibleDeviceInVm)(nil)).Elem() +} + +type SnapshotIncompatibleDeviceInVmFault SnapshotIncompatibleDeviceInVm + +func init() { + t["SnapshotIncompatibleDeviceInVmFault"] = reflect.TypeOf((*SnapshotIncompatibleDeviceInVmFault)(nil)).Elem() +} + +type SnapshotLocked struct { + SnapshotFault +} + +func init() { + t["SnapshotLocked"] = reflect.TypeOf((*SnapshotLocked)(nil)).Elem() +} + +type SnapshotLockedFault SnapshotLocked + +func init() { + t["SnapshotLockedFault"] = reflect.TypeOf((*SnapshotLockedFault)(nil)).Elem() +} + +type SnapshotMoveFromNonHomeNotSupported struct { + SnapshotCopyNotSupported +} + +func init() { + t["SnapshotMoveFromNonHomeNotSupported"] = reflect.TypeOf((*SnapshotMoveFromNonHomeNotSupported)(nil)).Elem() +} + +type SnapshotMoveFromNonHomeNotSupportedFault SnapshotMoveFromNonHomeNotSupported + +func init() { + t["SnapshotMoveFromNonHomeNotSupportedFault"] = reflect.TypeOf((*SnapshotMoveFromNonHomeNotSupportedFault)(nil)).Elem() +} + +type SnapshotMoveNotSupported struct { + SnapshotCopyNotSupported +} + +func init() { + t["SnapshotMoveNotSupported"] = reflect.TypeOf((*SnapshotMoveNotSupported)(nil)).Elem() +} + +type SnapshotMoveNotSupportedFault SnapshotMoveNotSupported + +func init() { + t["SnapshotMoveNotSupportedFault"] = reflect.TypeOf((*SnapshotMoveNotSupportedFault)(nil)).Elem() +} + +type SnapshotMoveToNonHomeNotSupported struct { + SnapshotCopyNotSupported +} + +func init() { + t["SnapshotMoveToNonHomeNotSupported"] = reflect.TypeOf((*SnapshotMoveToNonHomeNotSupported)(nil)).Elem() +} + +type SnapshotMoveToNonHomeNotSupportedFault SnapshotMoveToNonHomeNotSupported + +func init() { + t["SnapshotMoveToNonHomeNotSupportedFault"] = reflect.TypeOf((*SnapshotMoveToNonHomeNotSupportedFault)(nil)).Elem() +} + +type SnapshotNoChange struct { + SnapshotFault +} + +func init() { + t["SnapshotNoChange"] = reflect.TypeOf((*SnapshotNoChange)(nil)).Elem() +} + +type SnapshotNoChangeFault SnapshotNoChange + +func init() { + t["SnapshotNoChangeFault"] = reflect.TypeOf((*SnapshotNoChangeFault)(nil)).Elem() +} + +type SnapshotRevertIssue struct { + MigrationFault + + SnapshotName string `xml:"snapshotName,omitempty"` + Event []BaseEvent `xml:"event,omitempty,typeattr"` + Errors bool `xml:"errors"` +} + +func init() { + t["SnapshotRevertIssue"] = reflect.TypeOf((*SnapshotRevertIssue)(nil)).Elem() +} + +type SnapshotRevertIssueFault SnapshotRevertIssue + +func init() { + t["SnapshotRevertIssueFault"] = reflect.TypeOf((*SnapshotRevertIssueFault)(nil)).Elem() +} + +type SoftRuleVioCorrectionDisallowed struct { + VmConfigFault + + VmName string `xml:"vmName"` +} + +func init() { + t["SoftRuleVioCorrectionDisallowed"] = reflect.TypeOf((*SoftRuleVioCorrectionDisallowed)(nil)).Elem() +} + +type SoftRuleVioCorrectionDisallowedFault SoftRuleVioCorrectionDisallowed + +func init() { + t["SoftRuleVioCorrectionDisallowedFault"] = reflect.TypeOf((*SoftRuleVioCorrectionDisallowedFault)(nil)).Elem() +} + +type SoftRuleVioCorrectionImpact struct { + VmConfigFault + + VmName string `xml:"vmName"` +} + +func init() { + t["SoftRuleVioCorrectionImpact"] = reflect.TypeOf((*SoftRuleVioCorrectionImpact)(nil)).Elem() +} + +type SoftRuleVioCorrectionImpactFault SoftRuleVioCorrectionImpact + +func init() { + t["SoftRuleVioCorrectionImpactFault"] = reflect.TypeOf((*SoftRuleVioCorrectionImpactFault)(nil)).Elem() +} + +type SsdDiskNotAvailable struct { + VimFault + + DevicePath string `xml:"devicePath"` +} + +func init() { + t["SsdDiskNotAvailable"] = reflect.TypeOf((*SsdDiskNotAvailable)(nil)).Elem() +} + +type SsdDiskNotAvailableFault SsdDiskNotAvailable + +func init() { + t["SsdDiskNotAvailableFault"] = reflect.TypeOf((*SsdDiskNotAvailableFault)(nil)).Elem() +} + +type StageHostPatchRequestType struct { + This ManagedObjectReference `xml:"_this"` + MetaUrls []string `xml:"metaUrls,omitempty"` + BundleUrls []string `xml:"bundleUrls,omitempty"` + VibUrls []string `xml:"vibUrls,omitempty"` + Spec *HostPatchManagerPatchManagerOperationSpec `xml:"spec,omitempty"` +} + +func init() { + t["StageHostPatchRequestType"] = reflect.TypeOf((*StageHostPatchRequestType)(nil)).Elem() +} + +type StageHostPatch_Task StageHostPatchRequestType + +func init() { + t["StageHostPatch_Task"] = reflect.TypeOf((*StageHostPatch_Task)(nil)).Elem() +} + +type StageHostPatch_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type StampAllRulesWithUuidRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["StampAllRulesWithUuidRequestType"] = reflect.TypeOf((*StampAllRulesWithUuidRequestType)(nil)).Elem() +} + +type StampAllRulesWithUuid_Task StampAllRulesWithUuidRequestType + +func init() { + t["StampAllRulesWithUuid_Task"] = reflect.TypeOf((*StampAllRulesWithUuid_Task)(nil)).Elem() +} + +type StampAllRulesWithUuid_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type StandbyGuest StandbyGuestRequestType + +func init() { + t["StandbyGuest"] = reflect.TypeOf((*StandbyGuest)(nil)).Elem() +} + +type StandbyGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["StandbyGuestRequestType"] = reflect.TypeOf((*StandbyGuestRequestType)(nil)).Elem() +} + +type StandbyGuestResponse struct { +} + +type StartProgramInGuest StartProgramInGuestRequestType + +func init() { + t["StartProgramInGuest"] = reflect.TypeOf((*StartProgramInGuest)(nil)).Elem() +} + +type StartProgramInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Spec BaseGuestProgramSpec `xml:"spec,typeattr"` +} + +func init() { + t["StartProgramInGuestRequestType"] = reflect.TypeOf((*StartProgramInGuestRequestType)(nil)).Elem() +} + +type StartProgramInGuestResponse struct { + Returnval int64 `xml:"returnval"` +} + +type StartRecordingRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["StartRecordingRequestType"] = reflect.TypeOf((*StartRecordingRequestType)(nil)).Elem() +} + +type StartRecording_Task StartRecordingRequestType + +func init() { + t["StartRecording_Task"] = reflect.TypeOf((*StartRecording_Task)(nil)).Elem() +} + +type StartRecording_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type StartReplayingRequestType struct { + This ManagedObjectReference `xml:"_this"` + ReplaySnapshot ManagedObjectReference `xml:"replaySnapshot"` +} + +func init() { + t["StartReplayingRequestType"] = reflect.TypeOf((*StartReplayingRequestType)(nil)).Elem() +} + +type StartReplaying_Task StartReplayingRequestType + +func init() { + t["StartReplaying_Task"] = reflect.TypeOf((*StartReplaying_Task)(nil)).Elem() +} + +type StartReplaying_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type StartService StartServiceRequestType + +func init() { + t["StartService"] = reflect.TypeOf((*StartService)(nil)).Elem() +} + +type StartServiceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` +} + +func init() { + t["StartServiceRequestType"] = reflect.TypeOf((*StartServiceRequestType)(nil)).Elem() +} + +type StartServiceResponse struct { +} + +type StateAlarmExpression struct { + AlarmExpression + + Operator StateAlarmOperator `xml:"operator"` + Type string `xml:"type"` + StatePath string `xml:"statePath"` + Yellow string `xml:"yellow,omitempty"` + Red string `xml:"red,omitempty"` +} + +func init() { + t["StateAlarmExpression"] = reflect.TypeOf((*StateAlarmExpression)(nil)).Elem() +} + +type StaticRouteProfile struct { + ApplyProfile + + Key string `xml:"key,omitempty"` +} + +func init() { + t["StaticRouteProfile"] = reflect.TypeOf((*StaticRouteProfile)(nil)).Elem() +} + +type StopRecordingRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["StopRecordingRequestType"] = reflect.TypeOf((*StopRecordingRequestType)(nil)).Elem() +} + +type StopRecording_Task StopRecordingRequestType + +func init() { + t["StopRecording_Task"] = reflect.TypeOf((*StopRecording_Task)(nil)).Elem() +} + +type StopRecording_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type StopReplayingRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["StopReplayingRequestType"] = reflect.TypeOf((*StopReplayingRequestType)(nil)).Elem() +} + +type StopReplaying_Task StopReplayingRequestType + +func init() { + t["StopReplaying_Task"] = reflect.TypeOf((*StopReplaying_Task)(nil)).Elem() +} + +type StopReplaying_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type StopService StopServiceRequestType + +func init() { + t["StopService"] = reflect.TypeOf((*StopService)(nil)).Elem() +} + +type StopServiceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` +} + +func init() { + t["StopServiceRequestType"] = reflect.TypeOf((*StopServiceRequestType)(nil)).Elem() +} + +type StopServiceResponse struct { +} + +type StorageDrsAutomationConfig struct { + DynamicData + + SpaceLoadBalanceAutomationMode string `xml:"spaceLoadBalanceAutomationMode,omitempty"` + IoLoadBalanceAutomationMode string `xml:"ioLoadBalanceAutomationMode,omitempty"` + RuleEnforcementAutomationMode string `xml:"ruleEnforcementAutomationMode,omitempty"` + PolicyEnforcementAutomationMode string `xml:"policyEnforcementAutomationMode,omitempty"` + VmEvacuationAutomationMode string `xml:"vmEvacuationAutomationMode,omitempty"` +} + +func init() { + t["StorageDrsAutomationConfig"] = reflect.TypeOf((*StorageDrsAutomationConfig)(nil)).Elem() +} + +type StorageDrsCannotMoveDiskInMultiWriterMode struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveDiskInMultiWriterMode"] = reflect.TypeOf((*StorageDrsCannotMoveDiskInMultiWriterMode)(nil)).Elem() +} + +type StorageDrsCannotMoveDiskInMultiWriterModeFault StorageDrsCannotMoveDiskInMultiWriterMode + +func init() { + t["StorageDrsCannotMoveDiskInMultiWriterModeFault"] = reflect.TypeOf((*StorageDrsCannotMoveDiskInMultiWriterModeFault)(nil)).Elem() +} + +type StorageDrsCannotMoveFTVm struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveFTVm"] = reflect.TypeOf((*StorageDrsCannotMoveFTVm)(nil)).Elem() +} + +type StorageDrsCannotMoveFTVmFault StorageDrsCannotMoveFTVm + +func init() { + t["StorageDrsCannotMoveFTVmFault"] = reflect.TypeOf((*StorageDrsCannotMoveFTVmFault)(nil)).Elem() +} + +type StorageDrsCannotMoveIndependentDisk struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveIndependentDisk"] = reflect.TypeOf((*StorageDrsCannotMoveIndependentDisk)(nil)).Elem() +} + +type StorageDrsCannotMoveIndependentDiskFault StorageDrsCannotMoveIndependentDisk + +func init() { + t["StorageDrsCannotMoveIndependentDiskFault"] = reflect.TypeOf((*StorageDrsCannotMoveIndependentDiskFault)(nil)).Elem() +} + +type StorageDrsCannotMoveManuallyPlacedSwapFile struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveManuallyPlacedSwapFile"] = reflect.TypeOf((*StorageDrsCannotMoveManuallyPlacedSwapFile)(nil)).Elem() +} + +type StorageDrsCannotMoveManuallyPlacedSwapFileFault StorageDrsCannotMoveManuallyPlacedSwapFile + +func init() { + t["StorageDrsCannotMoveManuallyPlacedSwapFileFault"] = reflect.TypeOf((*StorageDrsCannotMoveManuallyPlacedSwapFileFault)(nil)).Elem() +} + +type StorageDrsCannotMoveManuallyPlacedVm struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveManuallyPlacedVm"] = reflect.TypeOf((*StorageDrsCannotMoveManuallyPlacedVm)(nil)).Elem() +} + +type StorageDrsCannotMoveManuallyPlacedVmFault StorageDrsCannotMoveManuallyPlacedVm + +func init() { + t["StorageDrsCannotMoveManuallyPlacedVmFault"] = reflect.TypeOf((*StorageDrsCannotMoveManuallyPlacedVmFault)(nil)).Elem() +} + +type StorageDrsCannotMoveSharedDisk struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveSharedDisk"] = reflect.TypeOf((*StorageDrsCannotMoveSharedDisk)(nil)).Elem() +} + +type StorageDrsCannotMoveSharedDiskFault StorageDrsCannotMoveSharedDisk + +func init() { + t["StorageDrsCannotMoveSharedDiskFault"] = reflect.TypeOf((*StorageDrsCannotMoveSharedDiskFault)(nil)).Elem() +} + +type StorageDrsCannotMoveTemplate struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveTemplate"] = reflect.TypeOf((*StorageDrsCannotMoveTemplate)(nil)).Elem() +} + +type StorageDrsCannotMoveTemplateFault StorageDrsCannotMoveTemplate + +func init() { + t["StorageDrsCannotMoveTemplateFault"] = reflect.TypeOf((*StorageDrsCannotMoveTemplateFault)(nil)).Elem() +} + +type StorageDrsCannotMoveVmInUserFolder struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveVmInUserFolder"] = reflect.TypeOf((*StorageDrsCannotMoveVmInUserFolder)(nil)).Elem() +} + +type StorageDrsCannotMoveVmInUserFolderFault StorageDrsCannotMoveVmInUserFolder + +func init() { + t["StorageDrsCannotMoveVmInUserFolderFault"] = reflect.TypeOf((*StorageDrsCannotMoveVmInUserFolderFault)(nil)).Elem() +} + +type StorageDrsCannotMoveVmWithMountedCDROM struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveVmWithMountedCDROM"] = reflect.TypeOf((*StorageDrsCannotMoveVmWithMountedCDROM)(nil)).Elem() +} + +type StorageDrsCannotMoveVmWithMountedCDROMFault StorageDrsCannotMoveVmWithMountedCDROM + +func init() { + t["StorageDrsCannotMoveVmWithMountedCDROMFault"] = reflect.TypeOf((*StorageDrsCannotMoveVmWithMountedCDROMFault)(nil)).Elem() +} + +type StorageDrsCannotMoveVmWithNoFilesInLayout struct { + VimFault +} + +func init() { + t["StorageDrsCannotMoveVmWithNoFilesInLayout"] = reflect.TypeOf((*StorageDrsCannotMoveVmWithNoFilesInLayout)(nil)).Elem() +} + +type StorageDrsCannotMoveVmWithNoFilesInLayoutFault StorageDrsCannotMoveVmWithNoFilesInLayout + +func init() { + t["StorageDrsCannotMoveVmWithNoFilesInLayoutFault"] = reflect.TypeOf((*StorageDrsCannotMoveVmWithNoFilesInLayoutFault)(nil)).Elem() +} + +type StorageDrsConfigInfo struct { + DynamicData + + PodConfig StorageDrsPodConfigInfo `xml:"podConfig"` + VmConfig []StorageDrsVmConfigInfo `xml:"vmConfig,omitempty"` +} + +func init() { + t["StorageDrsConfigInfo"] = reflect.TypeOf((*StorageDrsConfigInfo)(nil)).Elem() +} + +type StorageDrsConfigSpec struct { + DynamicData + + PodConfigSpec *StorageDrsPodConfigSpec `xml:"podConfigSpec,omitempty"` + VmConfigSpec []StorageDrsVmConfigSpec `xml:"vmConfigSpec,omitempty"` +} + +func init() { + t["StorageDrsConfigSpec"] = reflect.TypeOf((*StorageDrsConfigSpec)(nil)).Elem() +} + +type StorageDrsDatacentersCannotShareDatastore struct { + VimFault +} + +func init() { + t["StorageDrsDatacentersCannotShareDatastore"] = reflect.TypeOf((*StorageDrsDatacentersCannotShareDatastore)(nil)).Elem() +} + +type StorageDrsDatacentersCannotShareDatastoreFault StorageDrsDatacentersCannotShareDatastore + +func init() { + t["StorageDrsDatacentersCannotShareDatastoreFault"] = reflect.TypeOf((*StorageDrsDatacentersCannotShareDatastoreFault)(nil)).Elem() +} + +type StorageDrsDisabledOnVm struct { + VimFault +} + +func init() { + t["StorageDrsDisabledOnVm"] = reflect.TypeOf((*StorageDrsDisabledOnVm)(nil)).Elem() +} + +type StorageDrsDisabledOnVmFault StorageDrsDisabledOnVm + +func init() { + t["StorageDrsDisabledOnVmFault"] = reflect.TypeOf((*StorageDrsDisabledOnVmFault)(nil)).Elem() +} + +type StorageDrsHbrDiskNotMovable struct { + VimFault + + NonMovableDiskIds string `xml:"nonMovableDiskIds"` +} + +func init() { + t["StorageDrsHbrDiskNotMovable"] = reflect.TypeOf((*StorageDrsHbrDiskNotMovable)(nil)).Elem() +} + +type StorageDrsHbrDiskNotMovableFault StorageDrsHbrDiskNotMovable + +func init() { + t["StorageDrsHbrDiskNotMovableFault"] = reflect.TypeOf((*StorageDrsHbrDiskNotMovableFault)(nil)).Elem() +} + +type StorageDrsHmsMoveInProgress struct { + VimFault +} + +func init() { + t["StorageDrsHmsMoveInProgress"] = reflect.TypeOf((*StorageDrsHmsMoveInProgress)(nil)).Elem() +} + +type StorageDrsHmsMoveInProgressFault StorageDrsHmsMoveInProgress + +func init() { + t["StorageDrsHmsMoveInProgressFault"] = reflect.TypeOf((*StorageDrsHmsMoveInProgressFault)(nil)).Elem() +} + +type StorageDrsHmsUnreachable struct { + VimFault +} + +func init() { + t["StorageDrsHmsUnreachable"] = reflect.TypeOf((*StorageDrsHmsUnreachable)(nil)).Elem() +} + +type StorageDrsHmsUnreachableFault StorageDrsHmsUnreachable + +func init() { + t["StorageDrsHmsUnreachableFault"] = reflect.TypeOf((*StorageDrsHmsUnreachableFault)(nil)).Elem() +} + +type StorageDrsIoLoadBalanceConfig struct { + DynamicData + + ReservablePercentThreshold int32 `xml:"reservablePercentThreshold,omitempty"` + ReservableIopsThreshold int32 `xml:"reservableIopsThreshold,omitempty"` + ReservableThresholdMode string `xml:"reservableThresholdMode,omitempty"` + IoLatencyThreshold int32 `xml:"ioLatencyThreshold,omitempty"` + IoLoadImbalanceThreshold int32 `xml:"ioLoadImbalanceThreshold,omitempty"` +} + +func init() { + t["StorageDrsIoLoadBalanceConfig"] = reflect.TypeOf((*StorageDrsIoLoadBalanceConfig)(nil)).Elem() +} + +type StorageDrsIolbDisabledInternally struct { + VimFault +} + +func init() { + t["StorageDrsIolbDisabledInternally"] = reflect.TypeOf((*StorageDrsIolbDisabledInternally)(nil)).Elem() +} + +type StorageDrsIolbDisabledInternallyFault StorageDrsIolbDisabledInternally + +func init() { + t["StorageDrsIolbDisabledInternallyFault"] = reflect.TypeOf((*StorageDrsIolbDisabledInternallyFault)(nil)).Elem() +} + +type StorageDrsOptionSpec struct { + ArrayUpdateSpec + + Option BaseOptionValue `xml:"option,omitempty,typeattr"` +} + +func init() { + t["StorageDrsOptionSpec"] = reflect.TypeOf((*StorageDrsOptionSpec)(nil)).Elem() +} + +type StorageDrsPlacementRankVmSpec struct { + DynamicData + + VmPlacementSpec PlacementSpec `xml:"vmPlacementSpec"` + VmClusters []ManagedObjectReference `xml:"vmClusters"` +} + +func init() { + t["StorageDrsPlacementRankVmSpec"] = reflect.TypeOf((*StorageDrsPlacementRankVmSpec)(nil)).Elem() +} + +type StorageDrsPodConfigInfo struct { + DynamicData + + Enabled bool `xml:"enabled"` + IoLoadBalanceEnabled bool `xml:"ioLoadBalanceEnabled"` + DefaultVmBehavior string `xml:"defaultVmBehavior"` + LoadBalanceInterval int32 `xml:"loadBalanceInterval,omitempty"` + DefaultIntraVmAffinity *bool `xml:"defaultIntraVmAffinity"` + SpaceLoadBalanceConfig *StorageDrsSpaceLoadBalanceConfig `xml:"spaceLoadBalanceConfig,omitempty"` + IoLoadBalanceConfig *StorageDrsIoLoadBalanceConfig `xml:"ioLoadBalanceConfig,omitempty"` + AutomationOverrides *StorageDrsAutomationConfig `xml:"automationOverrides,omitempty"` + Rule []BaseClusterRuleInfo `xml:"rule,omitempty,typeattr"` + Option []BaseOptionValue `xml:"option,omitempty,typeattr"` +} + +func init() { + t["StorageDrsPodConfigInfo"] = reflect.TypeOf((*StorageDrsPodConfigInfo)(nil)).Elem() +} + +type StorageDrsPodConfigSpec struct { + DynamicData + + Enabled *bool `xml:"enabled"` + IoLoadBalanceEnabled *bool `xml:"ioLoadBalanceEnabled"` + DefaultVmBehavior string `xml:"defaultVmBehavior,omitempty"` + LoadBalanceInterval int32 `xml:"loadBalanceInterval,omitempty"` + DefaultIntraVmAffinity *bool `xml:"defaultIntraVmAffinity"` + SpaceLoadBalanceConfig *StorageDrsSpaceLoadBalanceConfig `xml:"spaceLoadBalanceConfig,omitempty"` + IoLoadBalanceConfig *StorageDrsIoLoadBalanceConfig `xml:"ioLoadBalanceConfig,omitempty"` + AutomationOverrides *StorageDrsAutomationConfig `xml:"automationOverrides,omitempty"` + Rule []ClusterRuleSpec `xml:"rule,omitempty"` + Option []StorageDrsOptionSpec `xml:"option,omitempty"` +} + +func init() { + t["StorageDrsPodConfigSpec"] = reflect.TypeOf((*StorageDrsPodConfigSpec)(nil)).Elem() +} + +type StorageDrsPodSelectionSpec struct { + DynamicData + + InitialVmConfig []VmPodConfigForPlacement `xml:"initialVmConfig,omitempty"` + StoragePod *ManagedObjectReference `xml:"storagePod,omitempty"` +} + +func init() { + t["StorageDrsPodSelectionSpec"] = reflect.TypeOf((*StorageDrsPodSelectionSpec)(nil)).Elem() +} + +type StorageDrsRelocateDisabled struct { + VimFault +} + +func init() { + t["StorageDrsRelocateDisabled"] = reflect.TypeOf((*StorageDrsRelocateDisabled)(nil)).Elem() +} + +type StorageDrsRelocateDisabledFault StorageDrsRelocateDisabled + +func init() { + t["StorageDrsRelocateDisabledFault"] = reflect.TypeOf((*StorageDrsRelocateDisabledFault)(nil)).Elem() +} + +type StorageDrsSpaceLoadBalanceConfig struct { + DynamicData + + SpaceThresholdMode string `xml:"spaceThresholdMode,omitempty"` + SpaceUtilizationThreshold int32 `xml:"spaceUtilizationThreshold,omitempty"` + FreeSpaceThresholdGB int32 `xml:"freeSpaceThresholdGB,omitempty"` + MinSpaceUtilizationDifference int32 `xml:"minSpaceUtilizationDifference,omitempty"` +} + +func init() { + t["StorageDrsSpaceLoadBalanceConfig"] = reflect.TypeOf((*StorageDrsSpaceLoadBalanceConfig)(nil)).Elem() +} + +type StorageDrsStaleHmsCollection struct { + VimFault +} + +func init() { + t["StorageDrsStaleHmsCollection"] = reflect.TypeOf((*StorageDrsStaleHmsCollection)(nil)).Elem() +} + +type StorageDrsStaleHmsCollectionFault StorageDrsStaleHmsCollection + +func init() { + t["StorageDrsStaleHmsCollectionFault"] = reflect.TypeOf((*StorageDrsStaleHmsCollectionFault)(nil)).Elem() +} + +type StorageDrsUnableToMoveFiles struct { + VimFault +} + +func init() { + t["StorageDrsUnableToMoveFiles"] = reflect.TypeOf((*StorageDrsUnableToMoveFiles)(nil)).Elem() +} + +type StorageDrsUnableToMoveFilesFault StorageDrsUnableToMoveFiles + +func init() { + t["StorageDrsUnableToMoveFilesFault"] = reflect.TypeOf((*StorageDrsUnableToMoveFilesFault)(nil)).Elem() +} + +type StorageDrsVmConfigInfo struct { + DynamicData + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + Enabled *bool `xml:"enabled"` + Behavior string `xml:"behavior,omitempty"` + IntraVmAffinity *bool `xml:"intraVmAffinity"` + IntraVmAntiAffinity *VirtualDiskAntiAffinityRuleSpec `xml:"intraVmAntiAffinity,omitempty"` +} + +func init() { + t["StorageDrsVmConfigInfo"] = reflect.TypeOf((*StorageDrsVmConfigInfo)(nil)).Elem() +} + +type StorageDrsVmConfigSpec struct { + ArrayUpdateSpec + + Info *StorageDrsVmConfigInfo `xml:"info,omitempty"` +} + +func init() { + t["StorageDrsVmConfigSpec"] = reflect.TypeOf((*StorageDrsVmConfigSpec)(nil)).Elem() +} + +type StorageIOAllocationInfo struct { + DynamicData + + Limit int64 `xml:"limit,omitempty"` + Shares *SharesInfo `xml:"shares,omitempty"` + Reservation int32 `xml:"reservation,omitempty"` +} + +func init() { + t["StorageIOAllocationInfo"] = reflect.TypeOf((*StorageIOAllocationInfo)(nil)).Elem() +} + +type StorageIOAllocationOption struct { + DynamicData + + LimitOption LongOption `xml:"limitOption"` + SharesOption SharesOption `xml:"sharesOption"` +} + +func init() { + t["StorageIOAllocationOption"] = reflect.TypeOf((*StorageIOAllocationOption)(nil)).Elem() +} + +type StorageIORMConfigOption struct { + DynamicData + + EnabledOption BoolOption `xml:"enabledOption"` + CongestionThresholdOption IntOption `xml:"congestionThresholdOption"` + StatsCollectionEnabledOption *BoolOption `xml:"statsCollectionEnabledOption,omitempty"` + ReservationEnabledOption *BoolOption `xml:"reservationEnabledOption,omitempty"` +} + +func init() { + t["StorageIORMConfigOption"] = reflect.TypeOf((*StorageIORMConfigOption)(nil)).Elem() +} + +type StorageIORMConfigSpec struct { + DynamicData + + Enabled *bool `xml:"enabled"` + CongestionThresholdMode string `xml:"congestionThresholdMode,omitempty"` + CongestionThreshold int32 `xml:"congestionThreshold,omitempty"` + PercentOfPeakThroughput int32 `xml:"percentOfPeakThroughput,omitempty"` + StatsCollectionEnabled *bool `xml:"statsCollectionEnabled"` + ReservationEnabled *bool `xml:"reservationEnabled"` + StatsAggregationDisabled *bool `xml:"statsAggregationDisabled"` + ReservableIopsThreshold int32 `xml:"reservableIopsThreshold,omitempty"` +} + +func init() { + t["StorageIORMConfigSpec"] = reflect.TypeOf((*StorageIORMConfigSpec)(nil)).Elem() +} + +type StorageIORMInfo struct { + DynamicData + + Enabled bool `xml:"enabled"` + CongestionThresholdMode string `xml:"congestionThresholdMode,omitempty"` + CongestionThreshold int32 `xml:"congestionThreshold"` + PercentOfPeakThroughput int32 `xml:"percentOfPeakThroughput,omitempty"` + StatsCollectionEnabled *bool `xml:"statsCollectionEnabled"` + ReservationEnabled *bool `xml:"reservationEnabled"` + StatsAggregationDisabled *bool `xml:"statsAggregationDisabled"` + ReservableIopsThreshold int32 `xml:"reservableIopsThreshold,omitempty"` +} + +func init() { + t["StorageIORMInfo"] = reflect.TypeOf((*StorageIORMInfo)(nil)).Elem() +} + +type StorageMigrationAction struct { + ClusterAction + + Vm ManagedObjectReference `xml:"vm"` + RelocateSpec VirtualMachineRelocateSpec `xml:"relocateSpec"` + Source ManagedObjectReference `xml:"source"` + Destination ManagedObjectReference `xml:"destination"` + SizeTransferred int64 `xml:"sizeTransferred"` + SpaceUtilSrcBefore float32 `xml:"spaceUtilSrcBefore,omitempty"` + SpaceUtilDstBefore float32 `xml:"spaceUtilDstBefore,omitempty"` + SpaceUtilSrcAfter float32 `xml:"spaceUtilSrcAfter,omitempty"` + SpaceUtilDstAfter float32 `xml:"spaceUtilDstAfter,omitempty"` + IoLatencySrcBefore float32 `xml:"ioLatencySrcBefore,omitempty"` + IoLatencyDstBefore float32 `xml:"ioLatencyDstBefore,omitempty"` +} + +func init() { + t["StorageMigrationAction"] = reflect.TypeOf((*StorageMigrationAction)(nil)).Elem() +} + +type StoragePerformanceSummary struct { + DynamicData + + Interval int32 `xml:"interval"` + Percentile []int32 `xml:"percentile"` + DatastoreReadLatency []float64 `xml:"datastoreReadLatency"` + DatastoreWriteLatency []float64 `xml:"datastoreWriteLatency"` + DatastoreVmLatency []float64 `xml:"datastoreVmLatency"` + DatastoreReadIops []float64 `xml:"datastoreReadIops"` + DatastoreWriteIops []float64 `xml:"datastoreWriteIops"` + SiocActivityDuration int32 `xml:"siocActivityDuration"` +} + +func init() { + t["StoragePerformanceSummary"] = reflect.TypeOf((*StoragePerformanceSummary)(nil)).Elem() +} + +type StoragePlacementAction struct { + ClusterAction + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + RelocateSpec VirtualMachineRelocateSpec `xml:"relocateSpec"` + Destination ManagedObjectReference `xml:"destination"` + SpaceUtilBefore float32 `xml:"spaceUtilBefore,omitempty"` + SpaceDemandBefore float32 `xml:"spaceDemandBefore,omitempty"` + SpaceUtilAfter float32 `xml:"spaceUtilAfter,omitempty"` + SpaceDemandAfter float32 `xml:"spaceDemandAfter,omitempty"` + IoLatencyBefore float32 `xml:"ioLatencyBefore,omitempty"` +} + +func init() { + t["StoragePlacementAction"] = reflect.TypeOf((*StoragePlacementAction)(nil)).Elem() +} + +type StoragePlacementResult struct { + DynamicData + + Recommendations []ClusterRecommendation `xml:"recommendations,omitempty"` + DrsFault *ClusterDrsFaults `xml:"drsFault,omitempty"` + Task *ManagedObjectReference `xml:"task,omitempty"` +} + +func init() { + t["StoragePlacementResult"] = reflect.TypeOf((*StoragePlacementResult)(nil)).Elem() +} + +type StoragePlacementSpec struct { + DynamicData + + Type string `xml:"type"` + Priority VirtualMachineMovePriority `xml:"priority,omitempty"` + Vm *ManagedObjectReference `xml:"vm,omitempty"` + PodSelectionSpec StorageDrsPodSelectionSpec `xml:"podSelectionSpec"` + CloneSpec *VirtualMachineCloneSpec `xml:"cloneSpec,omitempty"` + CloneName string `xml:"cloneName,omitempty"` + ConfigSpec *VirtualMachineConfigSpec `xml:"configSpec,omitempty"` + RelocateSpec *VirtualMachineRelocateSpec `xml:"relocateSpec,omitempty"` + ResourcePool *ManagedObjectReference `xml:"resourcePool,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Folder *ManagedObjectReference `xml:"folder,omitempty"` + DisallowPrerequisiteMoves *bool `xml:"disallowPrerequisiteMoves"` + ResourceLeaseDurationSec int32 `xml:"resourceLeaseDurationSec,omitempty"` +} + +func init() { + t["StoragePlacementSpec"] = reflect.TypeOf((*StoragePlacementSpec)(nil)).Elem() +} + +type StoragePodSummary struct { + DynamicData + + Name string `xml:"name"` + Capacity int64 `xml:"capacity"` + FreeSpace int64 `xml:"freeSpace"` +} + +func init() { + t["StoragePodSummary"] = reflect.TypeOf((*StoragePodSummary)(nil)).Elem() +} + +type StorageProfile struct { + ApplyProfile + + NasStorage []NasStorageProfile `xml:"nasStorage,omitempty"` +} + +func init() { + t["StorageProfile"] = reflect.TypeOf((*StorageProfile)(nil)).Elem() +} + +type StorageRequirement struct { + DynamicData + + Datastore ManagedObjectReference `xml:"datastore"` + FreeSpaceRequiredInKb int64 `xml:"freeSpaceRequiredInKb"` +} + +func init() { + t["StorageRequirement"] = reflect.TypeOf((*StorageRequirement)(nil)).Elem() +} + +type StorageResourceManagerStorageProfileStatistics struct { + DynamicData + + ProfileId string `xml:"profileId"` + TotalSpaceMB int64 `xml:"totalSpaceMB"` + UsedSpaceMB int64 `xml:"usedSpaceMB"` +} + +func init() { + t["StorageResourceManagerStorageProfileStatistics"] = reflect.TypeOf((*StorageResourceManagerStorageProfileStatistics)(nil)).Elem() +} + +type StorageVMotionNotSupported struct { + MigrationFeatureNotSupported +} + +func init() { + t["StorageVMotionNotSupported"] = reflect.TypeOf((*StorageVMotionNotSupported)(nil)).Elem() +} + +type StorageVMotionNotSupportedFault StorageVMotionNotSupported + +func init() { + t["StorageVMotionNotSupportedFault"] = reflect.TypeOf((*StorageVMotionNotSupportedFault)(nil)).Elem() +} + +type StorageVmotionIncompatible struct { + VirtualHardwareCompatibilityIssue + + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` +} + +func init() { + t["StorageVmotionIncompatible"] = reflect.TypeOf((*StorageVmotionIncompatible)(nil)).Elem() +} + +type StorageVmotionIncompatibleFault StorageVmotionIncompatible + +func init() { + t["StorageVmotionIncompatibleFault"] = reflect.TypeOf((*StorageVmotionIncompatibleFault)(nil)).Elem() +} + +type StringExpression struct { + NegatableExpression + + Value string `xml:"value,omitempty"` +} + +func init() { + t["StringExpression"] = reflect.TypeOf((*StringExpression)(nil)).Elem() +} + +type StringOption struct { + OptionType + + DefaultValue string `xml:"defaultValue"` + ValidCharacters string `xml:"validCharacters,omitempty"` +} + +func init() { + t["StringOption"] = reflect.TypeOf((*StringOption)(nil)).Elem() +} + +type StringPolicy struct { + InheritablePolicy + + Value string `xml:"value,omitempty"` +} + +func init() { + t["StringPolicy"] = reflect.TypeOf((*StringPolicy)(nil)).Elem() +} + +type SuspendVAppRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["SuspendVAppRequestType"] = reflect.TypeOf((*SuspendVAppRequestType)(nil)).Elem() +} + +type SuspendVApp_Task SuspendVAppRequestType + +func init() { + t["SuspendVApp_Task"] = reflect.TypeOf((*SuspendVApp_Task)(nil)).Elem() +} + +type SuspendVApp_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type SuspendVMRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["SuspendVMRequestType"] = reflect.TypeOf((*SuspendVMRequestType)(nil)).Elem() +} + +type SuspendVM_Task SuspendVMRequestType + +func init() { + t["SuspendVM_Task"] = reflect.TypeOf((*SuspendVM_Task)(nil)).Elem() +} + +type SuspendVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type SuspendedRelocateNotSupported struct { + MigrationFault +} + +func init() { + t["SuspendedRelocateNotSupported"] = reflect.TypeOf((*SuspendedRelocateNotSupported)(nil)).Elem() +} + +type SuspendedRelocateNotSupportedFault SuspendedRelocateNotSupported + +func init() { + t["SuspendedRelocateNotSupportedFault"] = reflect.TypeOf((*SuspendedRelocateNotSupportedFault)(nil)).Elem() +} + +type SwapDatastoreNotWritableOnHost struct { + DatastoreNotWritableOnHost +} + +func init() { + t["SwapDatastoreNotWritableOnHost"] = reflect.TypeOf((*SwapDatastoreNotWritableOnHost)(nil)).Elem() +} + +type SwapDatastoreNotWritableOnHostFault SwapDatastoreNotWritableOnHost + +func init() { + t["SwapDatastoreNotWritableOnHostFault"] = reflect.TypeOf((*SwapDatastoreNotWritableOnHostFault)(nil)).Elem() +} + +type SwapDatastoreUnset struct { + VimFault +} + +func init() { + t["SwapDatastoreUnset"] = reflect.TypeOf((*SwapDatastoreUnset)(nil)).Elem() +} + +type SwapDatastoreUnsetFault SwapDatastoreUnset + +func init() { + t["SwapDatastoreUnsetFault"] = reflect.TypeOf((*SwapDatastoreUnsetFault)(nil)).Elem() +} + +type SwapPlacementOverrideNotSupported struct { + InvalidVmConfig +} + +func init() { + t["SwapPlacementOverrideNotSupported"] = reflect.TypeOf((*SwapPlacementOverrideNotSupported)(nil)).Elem() +} + +type SwapPlacementOverrideNotSupportedFault SwapPlacementOverrideNotSupported + +func init() { + t["SwapPlacementOverrideNotSupportedFault"] = reflect.TypeOf((*SwapPlacementOverrideNotSupportedFault)(nil)).Elem() +} + +type SwitchIpUnset struct { + DvsFault +} + +func init() { + t["SwitchIpUnset"] = reflect.TypeOf((*SwitchIpUnset)(nil)).Elem() +} + +type SwitchIpUnsetFault SwitchIpUnset + +func init() { + t["SwitchIpUnsetFault"] = reflect.TypeOf((*SwitchIpUnsetFault)(nil)).Elem() +} + +type SwitchNotInUpgradeMode struct { + DvsFault +} + +func init() { + t["SwitchNotInUpgradeMode"] = reflect.TypeOf((*SwitchNotInUpgradeMode)(nil)).Elem() +} + +type SwitchNotInUpgradeModeFault SwitchNotInUpgradeMode + +func init() { + t["SwitchNotInUpgradeModeFault"] = reflect.TypeOf((*SwitchNotInUpgradeModeFault)(nil)).Elem() +} + +type SystemError struct { + RuntimeFault + + Reason string `xml:"reason"` +} + +func init() { + t["SystemError"] = reflect.TypeOf((*SystemError)(nil)).Elem() +} + +type SystemErrorFault SystemError + +func init() { + t["SystemErrorFault"] = reflect.TypeOf((*SystemErrorFault)(nil)).Elem() +} + +type Tag struct { + DynamicData + + Key string `xml:"key"` +} + +func init() { + t["Tag"] = reflect.TypeOf((*Tag)(nil)).Elem() +} + +type TaskDescription struct { + DynamicData + + MethodInfo []BaseElementDescription `xml:"methodInfo,typeattr"` + State []BaseElementDescription `xml:"state,typeattr"` + Reason []BaseTypeDescription `xml:"reason,typeattr"` +} + +func init() { + t["TaskDescription"] = reflect.TypeOf((*TaskDescription)(nil)).Elem() +} + +type TaskEvent struct { + Event + + Info TaskInfo `xml:"info"` +} + +func init() { + t["TaskEvent"] = reflect.TypeOf((*TaskEvent)(nil)).Elem() +} + +type TaskFilterSpec struct { + DynamicData + + Entity *TaskFilterSpecByEntity `xml:"entity,omitempty"` + Time *TaskFilterSpecByTime `xml:"time,omitempty"` + UserName *TaskFilterSpecByUsername `xml:"userName,omitempty"` + ActivationId []string `xml:"activationId,omitempty"` + State []TaskInfoState `xml:"state,omitempty"` + Alarm *ManagedObjectReference `xml:"alarm,omitempty"` + ScheduledTask *ManagedObjectReference `xml:"scheduledTask,omitempty"` + EventChainId []int32 `xml:"eventChainId,omitempty"` + Tag []string `xml:"tag,omitempty"` + ParentTaskKey []string `xml:"parentTaskKey,omitempty"` + RootTaskKey []string `xml:"rootTaskKey,omitempty"` +} + +func init() { + t["TaskFilterSpec"] = reflect.TypeOf((*TaskFilterSpec)(nil)).Elem() +} + +type TaskFilterSpecByEntity struct { + DynamicData + + Entity ManagedObjectReference `xml:"entity"` + Recursion TaskFilterSpecRecursionOption `xml:"recursion"` +} + +func init() { + t["TaskFilterSpecByEntity"] = reflect.TypeOf((*TaskFilterSpecByEntity)(nil)).Elem() +} + +type TaskFilterSpecByTime struct { + DynamicData + + TimeType TaskFilterSpecTimeOption `xml:"timeType"` + BeginTime *time.Time `xml:"beginTime"` + EndTime *time.Time `xml:"endTime"` +} + +func init() { + t["TaskFilterSpecByTime"] = reflect.TypeOf((*TaskFilterSpecByTime)(nil)).Elem() +} + +type TaskFilterSpecByUsername struct { + DynamicData + + SystemUser bool `xml:"systemUser"` + UserList []string `xml:"userList,omitempty"` +} + +func init() { + t["TaskFilterSpecByUsername"] = reflect.TypeOf((*TaskFilterSpecByUsername)(nil)).Elem() +} + +type TaskInProgress struct { + VimFault + + Task ManagedObjectReference `xml:"task"` +} + +func init() { + t["TaskInProgress"] = reflect.TypeOf((*TaskInProgress)(nil)).Elem() +} + +type TaskInProgressFault BaseTaskInProgress + +func init() { + t["TaskInProgressFault"] = reflect.TypeOf((*TaskInProgressFault)(nil)).Elem() +} + +type TaskInfo struct { + DynamicData + + Key string `xml:"key"` + Task ManagedObjectReference `xml:"task"` + Description *LocalizableMessage `xml:"description,omitempty"` + Name string `xml:"name,omitempty"` + DescriptionId string `xml:"descriptionId"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` + EntityName string `xml:"entityName,omitempty"` + Locked []ManagedObjectReference `xml:"locked,omitempty"` + State TaskInfoState `xml:"state"` + Cancelled bool `xml:"cancelled"` + Cancelable bool `xml:"cancelable"` + Error *LocalizedMethodFault `xml:"error,omitempty"` + Result AnyType `xml:"result,omitempty,typeattr"` + Progress int32 `xml:"progress,omitempty"` + Reason BaseTaskReason `xml:"reason,typeattr"` + QueueTime time.Time `xml:"queueTime"` + StartTime *time.Time `xml:"startTime"` + CompleteTime *time.Time `xml:"completeTime"` + EventChainId int32 `xml:"eventChainId"` + ChangeTag string `xml:"changeTag,omitempty"` + ParentTaskKey string `xml:"parentTaskKey,omitempty"` + RootTaskKey string `xml:"rootTaskKey,omitempty"` + ActivationId string `xml:"activationId,omitempty"` +} + +func init() { + t["TaskInfo"] = reflect.TypeOf((*TaskInfo)(nil)).Elem() +} + +type TaskReason struct { + DynamicData +} + +func init() { + t["TaskReason"] = reflect.TypeOf((*TaskReason)(nil)).Elem() +} + +type TaskReasonAlarm struct { + TaskReason + + AlarmName string `xml:"alarmName"` + Alarm ManagedObjectReference `xml:"alarm"` + EntityName string `xml:"entityName"` + Entity ManagedObjectReference `xml:"entity"` +} + +func init() { + t["TaskReasonAlarm"] = reflect.TypeOf((*TaskReasonAlarm)(nil)).Elem() +} + +type TaskReasonSchedule struct { + TaskReason + + Name string `xml:"name"` + ScheduledTask ManagedObjectReference `xml:"scheduledTask"` +} + +func init() { + t["TaskReasonSchedule"] = reflect.TypeOf((*TaskReasonSchedule)(nil)).Elem() +} + +type TaskReasonSystem struct { + TaskReason +} + +func init() { + t["TaskReasonSystem"] = reflect.TypeOf((*TaskReasonSystem)(nil)).Elem() +} + +type TaskReasonUser struct { + TaskReason + + UserName string `xml:"userName"` +} + +func init() { + t["TaskReasonUser"] = reflect.TypeOf((*TaskReasonUser)(nil)).Elem() +} + +type TaskScheduler struct { + DynamicData + + ActiveTime *time.Time `xml:"activeTime"` + ExpireTime *time.Time `xml:"expireTime"` +} + +func init() { + t["TaskScheduler"] = reflect.TypeOf((*TaskScheduler)(nil)).Elem() +} + +type TaskTimeoutEvent struct { + TaskEvent +} + +func init() { + t["TaskTimeoutEvent"] = reflect.TypeOf((*TaskTimeoutEvent)(nil)).Elem() +} + +type TeamingMatchEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["TeamingMatchEvent"] = reflect.TypeOf((*TeamingMatchEvent)(nil)).Elem() +} + +type TeamingMisMatchEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["TeamingMisMatchEvent"] = reflect.TypeOf((*TeamingMisMatchEvent)(nil)).Elem() +} + +type TemplateBeingUpgradedEvent struct { + TemplateUpgradeEvent +} + +func init() { + t["TemplateBeingUpgradedEvent"] = reflect.TypeOf((*TemplateBeingUpgradedEvent)(nil)).Elem() +} + +type TemplateConfigFileInfo struct { + VmConfigFileInfo +} + +func init() { + t["TemplateConfigFileInfo"] = reflect.TypeOf((*TemplateConfigFileInfo)(nil)).Elem() +} + +type TemplateConfigFileQuery struct { + VmConfigFileQuery +} + +func init() { + t["TemplateConfigFileQuery"] = reflect.TypeOf((*TemplateConfigFileQuery)(nil)).Elem() +} + +type TemplateUpgradeEvent struct { + Event + + LegacyTemplate string `xml:"legacyTemplate"` +} + +func init() { + t["TemplateUpgradeEvent"] = reflect.TypeOf((*TemplateUpgradeEvent)(nil)).Elem() +} + +type TemplateUpgradeFailedEvent struct { + TemplateUpgradeEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["TemplateUpgradeFailedEvent"] = reflect.TypeOf((*TemplateUpgradeFailedEvent)(nil)).Elem() +} + +type TemplateUpgradedEvent struct { + TemplateUpgradeEvent +} + +func init() { + t["TemplateUpgradedEvent"] = reflect.TypeOf((*TemplateUpgradedEvent)(nil)).Elem() +} + +type TerminateFaultTolerantVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm *ManagedObjectReference `xml:"vm,omitempty"` +} + +func init() { + t["TerminateFaultTolerantVMRequestType"] = reflect.TypeOf((*TerminateFaultTolerantVMRequestType)(nil)).Elem() +} + +type TerminateFaultTolerantVM_Task TerminateFaultTolerantVMRequestType + +func init() { + t["TerminateFaultTolerantVM_Task"] = reflect.TypeOf((*TerminateFaultTolerantVM_Task)(nil)).Elem() +} + +type TerminateFaultTolerantVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type TerminateProcessInGuest TerminateProcessInGuestRequestType + +func init() { + t["TerminateProcessInGuest"] = reflect.TypeOf((*TerminateProcessInGuest)(nil)).Elem() +} + +type TerminateProcessInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` + Pid int64 `xml:"pid"` +} + +func init() { + t["TerminateProcessInGuestRequestType"] = reflect.TypeOf((*TerminateProcessInGuestRequestType)(nil)).Elem() +} + +type TerminateProcessInGuestResponse struct { +} + +type TerminateSession TerminateSessionRequestType + +func init() { + t["TerminateSession"] = reflect.TypeOf((*TerminateSession)(nil)).Elem() +} + +type TerminateSessionRequestType struct { + This ManagedObjectReference `xml:"_this"` + SessionId []string `xml:"sessionId"` +} + +func init() { + t["TerminateSessionRequestType"] = reflect.TypeOf((*TerminateSessionRequestType)(nil)).Elem() +} + +type TerminateSessionResponse struct { +} + +type TerminateVM TerminateVMRequestType + +func init() { + t["TerminateVM"] = reflect.TypeOf((*TerminateVM)(nil)).Elem() +} + +type TerminateVMRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["TerminateVMRequestType"] = reflect.TypeOf((*TerminateVMRequestType)(nil)).Elem() +} + +type TerminateVMResponse struct { +} + +type ThirdPartyLicenseAssignmentFailed struct { + RuntimeFault + + Host ManagedObjectReference `xml:"host"` + Module string `xml:"module"` + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["ThirdPartyLicenseAssignmentFailed"] = reflect.TypeOf((*ThirdPartyLicenseAssignmentFailed)(nil)).Elem() +} + +type ThirdPartyLicenseAssignmentFailedFault ThirdPartyLicenseAssignmentFailed + +func init() { + t["ThirdPartyLicenseAssignmentFailedFault"] = reflect.TypeOf((*ThirdPartyLicenseAssignmentFailedFault)(nil)).Elem() +} + +type TicketedSessionAuthentication struct { + GuestAuthentication + + Ticket string `xml:"ticket"` +} + +func init() { + t["TicketedSessionAuthentication"] = reflect.TypeOf((*TicketedSessionAuthentication)(nil)).Elem() +} + +type TimedOutHostOperationEvent struct { + HostEvent +} + +func init() { + t["TimedOutHostOperationEvent"] = reflect.TypeOf((*TimedOutHostOperationEvent)(nil)).Elem() +} + +type Timedout struct { + VimFault +} + +func init() { + t["Timedout"] = reflect.TypeOf((*Timedout)(nil)).Elem() +} + +type TimedoutFault BaseTimedout + +func init() { + t["TimedoutFault"] = reflect.TypeOf((*TimedoutFault)(nil)).Elem() +} + +type TooManyConcurrentNativeClones struct { + FileFault +} + +func init() { + t["TooManyConcurrentNativeClones"] = reflect.TypeOf((*TooManyConcurrentNativeClones)(nil)).Elem() +} + +type TooManyConcurrentNativeClonesFault TooManyConcurrentNativeClones + +func init() { + t["TooManyConcurrentNativeClonesFault"] = reflect.TypeOf((*TooManyConcurrentNativeClonesFault)(nil)).Elem() +} + +type TooManyConsecutiveOverrides struct { + VimFault +} + +func init() { + t["TooManyConsecutiveOverrides"] = reflect.TypeOf((*TooManyConsecutiveOverrides)(nil)).Elem() +} + +type TooManyConsecutiveOverridesFault TooManyConsecutiveOverrides + +func init() { + t["TooManyConsecutiveOverridesFault"] = reflect.TypeOf((*TooManyConsecutiveOverridesFault)(nil)).Elem() +} + +type TooManyDevices struct { + InvalidVmConfig +} + +func init() { + t["TooManyDevices"] = reflect.TypeOf((*TooManyDevices)(nil)).Elem() +} + +type TooManyDevicesFault TooManyDevices + +func init() { + t["TooManyDevicesFault"] = reflect.TypeOf((*TooManyDevicesFault)(nil)).Elem() +} + +type TooManyDisksOnLegacyHost struct { + MigrationFault + + DiskCount int32 `xml:"diskCount"` + TimeoutDanger bool `xml:"timeoutDanger"` +} + +func init() { + t["TooManyDisksOnLegacyHost"] = reflect.TypeOf((*TooManyDisksOnLegacyHost)(nil)).Elem() +} + +type TooManyDisksOnLegacyHostFault TooManyDisksOnLegacyHost + +func init() { + t["TooManyDisksOnLegacyHostFault"] = reflect.TypeOf((*TooManyDisksOnLegacyHostFault)(nil)).Elem() +} + +type TooManyGuestLogons struct { + GuestOperationsFault +} + +func init() { + t["TooManyGuestLogons"] = reflect.TypeOf((*TooManyGuestLogons)(nil)).Elem() +} + +type TooManyGuestLogonsFault TooManyGuestLogons + +func init() { + t["TooManyGuestLogonsFault"] = reflect.TypeOf((*TooManyGuestLogonsFault)(nil)).Elem() +} + +type TooManyHosts struct { + HostConnectFault +} + +func init() { + t["TooManyHosts"] = reflect.TypeOf((*TooManyHosts)(nil)).Elem() +} + +type TooManyHostsFault TooManyHosts + +func init() { + t["TooManyHostsFault"] = reflect.TypeOf((*TooManyHostsFault)(nil)).Elem() +} + +type TooManyNativeCloneLevels struct { + FileFault +} + +func init() { + t["TooManyNativeCloneLevels"] = reflect.TypeOf((*TooManyNativeCloneLevels)(nil)).Elem() +} + +type TooManyNativeCloneLevelsFault TooManyNativeCloneLevels + +func init() { + t["TooManyNativeCloneLevelsFault"] = reflect.TypeOf((*TooManyNativeCloneLevelsFault)(nil)).Elem() +} + +type TooManyNativeClonesOnFile struct { + FileFault +} + +func init() { + t["TooManyNativeClonesOnFile"] = reflect.TypeOf((*TooManyNativeClonesOnFile)(nil)).Elem() +} + +type TooManyNativeClonesOnFileFault TooManyNativeClonesOnFile + +func init() { + t["TooManyNativeClonesOnFileFault"] = reflect.TypeOf((*TooManyNativeClonesOnFileFault)(nil)).Elem() +} + +type TooManySnapshotLevels struct { + SnapshotFault +} + +func init() { + t["TooManySnapshotLevels"] = reflect.TypeOf((*TooManySnapshotLevels)(nil)).Elem() +} + +type TooManySnapshotLevelsFault TooManySnapshotLevels + +func init() { + t["TooManySnapshotLevelsFault"] = reflect.TypeOf((*TooManySnapshotLevelsFault)(nil)).Elem() +} + +type ToolsAlreadyUpgraded struct { + VmToolsUpgradeFault +} + +func init() { + t["ToolsAlreadyUpgraded"] = reflect.TypeOf((*ToolsAlreadyUpgraded)(nil)).Elem() +} + +type ToolsAlreadyUpgradedFault ToolsAlreadyUpgraded + +func init() { + t["ToolsAlreadyUpgradedFault"] = reflect.TypeOf((*ToolsAlreadyUpgradedFault)(nil)).Elem() +} + +type ToolsAutoUpgradeNotSupported struct { + VmToolsUpgradeFault +} + +func init() { + t["ToolsAutoUpgradeNotSupported"] = reflect.TypeOf((*ToolsAutoUpgradeNotSupported)(nil)).Elem() +} + +type ToolsAutoUpgradeNotSupportedFault ToolsAutoUpgradeNotSupported + +func init() { + t["ToolsAutoUpgradeNotSupportedFault"] = reflect.TypeOf((*ToolsAutoUpgradeNotSupportedFault)(nil)).Elem() +} + +type ToolsConfigInfo struct { + DynamicData + + ToolsVersion int32 `xml:"toolsVersion,omitempty"` + AfterPowerOn *bool `xml:"afterPowerOn"` + AfterResume *bool `xml:"afterResume"` + BeforeGuestStandby *bool `xml:"beforeGuestStandby"` + BeforeGuestShutdown *bool `xml:"beforeGuestShutdown"` + BeforeGuestReboot *bool `xml:"beforeGuestReboot"` + ToolsUpgradePolicy string `xml:"toolsUpgradePolicy,omitempty"` + PendingCustomization string `xml:"pendingCustomization,omitempty"` + SyncTimeWithHost *bool `xml:"syncTimeWithHost"` + LastInstallInfo *ToolsConfigInfoToolsLastInstallInfo `xml:"lastInstallInfo,omitempty"` +} + +func init() { + t["ToolsConfigInfo"] = reflect.TypeOf((*ToolsConfigInfo)(nil)).Elem() +} + +type ToolsConfigInfoToolsLastInstallInfo struct { + DynamicData + + Counter int32 `xml:"counter"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["ToolsConfigInfoToolsLastInstallInfo"] = reflect.TypeOf((*ToolsConfigInfoToolsLastInstallInfo)(nil)).Elem() +} + +type ToolsImageCopyFailed struct { + VmToolsUpgradeFault +} + +func init() { + t["ToolsImageCopyFailed"] = reflect.TypeOf((*ToolsImageCopyFailed)(nil)).Elem() +} + +type ToolsImageCopyFailedFault ToolsImageCopyFailed + +func init() { + t["ToolsImageCopyFailedFault"] = reflect.TypeOf((*ToolsImageCopyFailedFault)(nil)).Elem() +} + +type ToolsImageNotAvailable struct { + VmToolsUpgradeFault +} + +func init() { + t["ToolsImageNotAvailable"] = reflect.TypeOf((*ToolsImageNotAvailable)(nil)).Elem() +} + +type ToolsImageNotAvailableFault ToolsImageNotAvailable + +func init() { + t["ToolsImageNotAvailableFault"] = reflect.TypeOf((*ToolsImageNotAvailableFault)(nil)).Elem() +} + +type ToolsImageSignatureCheckFailed struct { + VmToolsUpgradeFault +} + +func init() { + t["ToolsImageSignatureCheckFailed"] = reflect.TypeOf((*ToolsImageSignatureCheckFailed)(nil)).Elem() +} + +type ToolsImageSignatureCheckFailedFault ToolsImageSignatureCheckFailed + +func init() { + t["ToolsImageSignatureCheckFailedFault"] = reflect.TypeOf((*ToolsImageSignatureCheckFailedFault)(nil)).Elem() +} + +type ToolsInstallationInProgress struct { + MigrationFault +} + +func init() { + t["ToolsInstallationInProgress"] = reflect.TypeOf((*ToolsInstallationInProgress)(nil)).Elem() +} + +type ToolsInstallationInProgressFault ToolsInstallationInProgress + +func init() { + t["ToolsInstallationInProgressFault"] = reflect.TypeOf((*ToolsInstallationInProgressFault)(nil)).Elem() +} + +type ToolsUnavailable struct { + VimFault +} + +func init() { + t["ToolsUnavailable"] = reflect.TypeOf((*ToolsUnavailable)(nil)).Elem() +} + +type ToolsUnavailableFault ToolsUnavailable + +func init() { + t["ToolsUnavailableFault"] = reflect.TypeOf((*ToolsUnavailableFault)(nil)).Elem() +} + +type ToolsUpgradeCancelled struct { + VmToolsUpgradeFault +} + +func init() { + t["ToolsUpgradeCancelled"] = reflect.TypeOf((*ToolsUpgradeCancelled)(nil)).Elem() +} + +type ToolsUpgradeCancelledFault ToolsUpgradeCancelled + +func init() { + t["ToolsUpgradeCancelledFault"] = reflect.TypeOf((*ToolsUpgradeCancelledFault)(nil)).Elem() +} + +type TraversalSpec struct { + SelectionSpec + + Type string `xml:"type"` + Path string `xml:"path"` + Skip *bool `xml:"skip"` + SelectSet []BaseSelectionSpec `xml:"selectSet,omitempty,typeattr"` +} + +func init() { + t["TraversalSpec"] = reflect.TypeOf((*TraversalSpec)(nil)).Elem() +} + +type TurnDiskLocatorLedOffRequestType struct { + This ManagedObjectReference `xml:"_this"` + ScsiDiskUuids []string `xml:"scsiDiskUuids"` +} + +func init() { + t["TurnDiskLocatorLedOffRequestType"] = reflect.TypeOf((*TurnDiskLocatorLedOffRequestType)(nil)).Elem() +} + +type TurnDiskLocatorLedOff_Task TurnDiskLocatorLedOffRequestType + +func init() { + t["TurnDiskLocatorLedOff_Task"] = reflect.TypeOf((*TurnDiskLocatorLedOff_Task)(nil)).Elem() +} + +type TurnDiskLocatorLedOff_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type TurnDiskLocatorLedOnRequestType struct { + This ManagedObjectReference `xml:"_this"` + ScsiDiskUuids []string `xml:"scsiDiskUuids"` +} + +func init() { + t["TurnDiskLocatorLedOnRequestType"] = reflect.TypeOf((*TurnDiskLocatorLedOnRequestType)(nil)).Elem() +} + +type TurnDiskLocatorLedOn_Task TurnDiskLocatorLedOnRequestType + +func init() { + t["TurnDiskLocatorLedOn_Task"] = reflect.TypeOf((*TurnDiskLocatorLedOn_Task)(nil)).Elem() +} + +type TurnDiskLocatorLedOn_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type TurnOffFaultToleranceForVMRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["TurnOffFaultToleranceForVMRequestType"] = reflect.TypeOf((*TurnOffFaultToleranceForVMRequestType)(nil)).Elem() +} + +type TurnOffFaultToleranceForVM_Task TurnOffFaultToleranceForVMRequestType + +func init() { + t["TurnOffFaultToleranceForVM_Task"] = reflect.TypeOf((*TurnOffFaultToleranceForVM_Task)(nil)).Elem() +} + +type TurnOffFaultToleranceForVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type TypeDescription struct { + Description + + Key string `xml:"key"` +} + +func init() { + t["TypeDescription"] = reflect.TypeOf((*TypeDescription)(nil)).Elem() +} + +type UnSupportedDatastoreForVFlash struct { + UnsupportedDatastore + + DatastoreName string `xml:"datastoreName"` + Type string `xml:"type"` +} + +func init() { + t["UnSupportedDatastoreForVFlash"] = reflect.TypeOf((*UnSupportedDatastoreForVFlash)(nil)).Elem() +} + +type UnSupportedDatastoreForVFlashFault UnSupportedDatastoreForVFlash + +func init() { + t["UnSupportedDatastoreForVFlashFault"] = reflect.TypeOf((*UnSupportedDatastoreForVFlashFault)(nil)).Elem() +} + +type UnassignUserFromGroup UnassignUserFromGroupRequestType + +func init() { + t["UnassignUserFromGroup"] = reflect.TypeOf((*UnassignUserFromGroup)(nil)).Elem() +} + +type UnassignUserFromGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + User string `xml:"user"` + Group string `xml:"group"` +} + +func init() { + t["UnassignUserFromGroupRequestType"] = reflect.TypeOf((*UnassignUserFromGroupRequestType)(nil)).Elem() +} + +type UnassignUserFromGroupResponse struct { +} + +type UnbindVnic UnbindVnicRequestType + +func init() { + t["UnbindVnic"] = reflect.TypeOf((*UnbindVnic)(nil)).Elem() +} + +type UnbindVnicRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaName string `xml:"iScsiHbaName"` + VnicDevice string `xml:"vnicDevice"` + Force bool `xml:"force"` +} + +func init() { + t["UnbindVnicRequestType"] = reflect.TypeOf((*UnbindVnicRequestType)(nil)).Elem() +} + +type UnbindVnicResponse struct { +} + +type UncommittedUndoableDisk struct { + MigrationFault +} + +func init() { + t["UncommittedUndoableDisk"] = reflect.TypeOf((*UncommittedUndoableDisk)(nil)).Elem() +} + +type UncommittedUndoableDiskFault UncommittedUndoableDisk + +func init() { + t["UncommittedUndoableDiskFault"] = reflect.TypeOf((*UncommittedUndoableDiskFault)(nil)).Elem() +} + +type UnconfiguredPropertyValue struct { + InvalidPropertyValue +} + +func init() { + t["UnconfiguredPropertyValue"] = reflect.TypeOf((*UnconfiguredPropertyValue)(nil)).Elem() +} + +type UnconfiguredPropertyValueFault UnconfiguredPropertyValue + +func init() { + t["UnconfiguredPropertyValueFault"] = reflect.TypeOf((*UnconfiguredPropertyValueFault)(nil)).Elem() +} + +type UncustomizableGuest struct { + CustomizationFault + + UncustomizableGuestOS string `xml:"uncustomizableGuestOS"` +} + +func init() { + t["UncustomizableGuest"] = reflect.TypeOf((*UncustomizableGuest)(nil)).Elem() +} + +type UncustomizableGuestFault UncustomizableGuest + +func init() { + t["UncustomizableGuestFault"] = reflect.TypeOf((*UncustomizableGuestFault)(nil)).Elem() +} + +type UnexpectedCustomizationFault struct { + CustomizationFault +} + +func init() { + t["UnexpectedCustomizationFault"] = reflect.TypeOf((*UnexpectedCustomizationFault)(nil)).Elem() +} + +type UnexpectedCustomizationFaultFault UnexpectedCustomizationFault + +func init() { + t["UnexpectedCustomizationFaultFault"] = reflect.TypeOf((*UnexpectedCustomizationFaultFault)(nil)).Elem() +} + +type UnexpectedFault struct { + RuntimeFault + + FaultName string `xml:"faultName"` + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["UnexpectedFault"] = reflect.TypeOf((*UnexpectedFault)(nil)).Elem() +} + +type UnexpectedFaultFault UnexpectedFault + +func init() { + t["UnexpectedFaultFault"] = reflect.TypeOf((*UnexpectedFaultFault)(nil)).Elem() +} + +type UninstallHostPatchRequestType struct { + This ManagedObjectReference `xml:"_this"` + BulletinIds []string `xml:"bulletinIds,omitempty"` + Spec *HostPatchManagerPatchManagerOperationSpec `xml:"spec,omitempty"` +} + +func init() { + t["UninstallHostPatchRequestType"] = reflect.TypeOf((*UninstallHostPatchRequestType)(nil)).Elem() +} + +type UninstallHostPatch_Task UninstallHostPatchRequestType + +func init() { + t["UninstallHostPatch_Task"] = reflect.TypeOf((*UninstallHostPatch_Task)(nil)).Elem() +} + +type UninstallHostPatch_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UninstallIoFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` + FilterId string `xml:"filterId"` + CompRes ManagedObjectReference `xml:"compRes"` +} + +func init() { + t["UninstallIoFilterRequestType"] = reflect.TypeOf((*UninstallIoFilterRequestType)(nil)).Elem() +} + +type UninstallIoFilter_Task UninstallIoFilterRequestType + +func init() { + t["UninstallIoFilter_Task"] = reflect.TypeOf((*UninstallIoFilter_Task)(nil)).Elem() +} + +type UninstallIoFilter_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UninstallService UninstallServiceRequestType + +func init() { + t["UninstallService"] = reflect.TypeOf((*UninstallService)(nil)).Elem() +} + +type UninstallServiceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` +} + +func init() { + t["UninstallServiceRequestType"] = reflect.TypeOf((*UninstallServiceRequestType)(nil)).Elem() +} + +type UninstallServiceResponse struct { +} + +type UnlicensedVirtualMachinesEvent struct { + LicenseEvent + + Unlicensed int32 `xml:"unlicensed"` + Available int32 `xml:"available"` +} + +func init() { + t["UnlicensedVirtualMachinesEvent"] = reflect.TypeOf((*UnlicensedVirtualMachinesEvent)(nil)).Elem() +} + +type UnlicensedVirtualMachinesFoundEvent struct { + LicenseEvent + + Available int32 `xml:"available"` +} + +func init() { + t["UnlicensedVirtualMachinesFoundEvent"] = reflect.TypeOf((*UnlicensedVirtualMachinesFoundEvent)(nil)).Elem() +} + +type UnmapVmfsVolumeExRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid []string `xml:"vmfsUuid"` +} + +func init() { + t["UnmapVmfsVolumeExRequestType"] = reflect.TypeOf((*UnmapVmfsVolumeExRequestType)(nil)).Elem() +} + +type UnmapVmfsVolumeEx_Task UnmapVmfsVolumeExRequestType + +func init() { + t["UnmapVmfsVolumeEx_Task"] = reflect.TypeOf((*UnmapVmfsVolumeEx_Task)(nil)).Elem() +} + +type UnmapVmfsVolumeEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UnmountDiskMappingRequestType struct { + This ManagedObjectReference `xml:"_this"` + Mapping []VsanHostDiskMapping `xml:"mapping"` +} + +func init() { + t["UnmountDiskMappingRequestType"] = reflect.TypeOf((*UnmountDiskMappingRequestType)(nil)).Elem() +} + +type UnmountDiskMapping_Task UnmountDiskMappingRequestType + +func init() { + t["UnmountDiskMapping_Task"] = reflect.TypeOf((*UnmountDiskMapping_Task)(nil)).Elem() +} + +type UnmountDiskMapping_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UnmountForceMountedVmfsVolume UnmountForceMountedVmfsVolumeRequestType + +func init() { + t["UnmountForceMountedVmfsVolume"] = reflect.TypeOf((*UnmountForceMountedVmfsVolume)(nil)).Elem() +} + +type UnmountForceMountedVmfsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid string `xml:"vmfsUuid"` +} + +func init() { + t["UnmountForceMountedVmfsVolumeRequestType"] = reflect.TypeOf((*UnmountForceMountedVmfsVolumeRequestType)(nil)).Elem() +} + +type UnmountForceMountedVmfsVolumeResponse struct { +} + +type UnmountToolsInstaller UnmountToolsInstallerRequestType + +func init() { + t["UnmountToolsInstaller"] = reflect.TypeOf((*UnmountToolsInstaller)(nil)).Elem() +} + +type UnmountToolsInstallerRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["UnmountToolsInstallerRequestType"] = reflect.TypeOf((*UnmountToolsInstallerRequestType)(nil)).Elem() +} + +type UnmountToolsInstallerResponse struct { +} + +type UnmountVffsVolume UnmountVffsVolumeRequestType + +func init() { + t["UnmountVffsVolume"] = reflect.TypeOf((*UnmountVffsVolume)(nil)).Elem() +} + +type UnmountVffsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` + VffsUuid string `xml:"vffsUuid"` +} + +func init() { + t["UnmountVffsVolumeRequestType"] = reflect.TypeOf((*UnmountVffsVolumeRequestType)(nil)).Elem() +} + +type UnmountVffsVolumeResponse struct { +} + +type UnmountVmfsVolume UnmountVmfsVolumeRequestType + +func init() { + t["UnmountVmfsVolume"] = reflect.TypeOf((*UnmountVmfsVolume)(nil)).Elem() +} + +type UnmountVmfsVolumeExRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid []string `xml:"vmfsUuid"` +} + +func init() { + t["UnmountVmfsVolumeExRequestType"] = reflect.TypeOf((*UnmountVmfsVolumeExRequestType)(nil)).Elem() +} + +type UnmountVmfsVolumeEx_Task UnmountVmfsVolumeExRequestType + +func init() { + t["UnmountVmfsVolumeEx_Task"] = reflect.TypeOf((*UnmountVmfsVolumeEx_Task)(nil)).Elem() +} + +type UnmountVmfsVolumeEx_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UnmountVmfsVolumeRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsUuid string `xml:"vmfsUuid"` +} + +func init() { + t["UnmountVmfsVolumeRequestType"] = reflect.TypeOf((*UnmountVmfsVolumeRequestType)(nil)).Elem() +} + +type UnmountVmfsVolumeResponse struct { +} + +type UnrecognizedHost struct { + VimFault + + HostName string `xml:"hostName"` +} + +func init() { + t["UnrecognizedHost"] = reflect.TypeOf((*UnrecognizedHost)(nil)).Elem() +} + +type UnrecognizedHostFault UnrecognizedHost + +func init() { + t["UnrecognizedHostFault"] = reflect.TypeOf((*UnrecognizedHostFault)(nil)).Elem() +} + +type UnregisterAndDestroyRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["UnregisterAndDestroyRequestType"] = reflect.TypeOf((*UnregisterAndDestroyRequestType)(nil)).Elem() +} + +type UnregisterAndDestroy_Task UnregisterAndDestroyRequestType + +func init() { + t["UnregisterAndDestroy_Task"] = reflect.TypeOf((*UnregisterAndDestroy_Task)(nil)).Elem() +} + +type UnregisterAndDestroy_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UnregisterExtension UnregisterExtensionRequestType + +func init() { + t["UnregisterExtension"] = reflect.TypeOf((*UnregisterExtension)(nil)).Elem() +} + +type UnregisterExtensionRequestType struct { + This ManagedObjectReference `xml:"_this"` + ExtensionKey string `xml:"extensionKey"` +} + +func init() { + t["UnregisterExtensionRequestType"] = reflect.TypeOf((*UnregisterExtensionRequestType)(nil)).Elem() +} + +type UnregisterExtensionResponse struct { +} + +type UnregisterVM UnregisterVMRequestType + +func init() { + t["UnregisterVM"] = reflect.TypeOf((*UnregisterVM)(nil)).Elem() +} + +type UnregisterVMRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["UnregisterVMRequestType"] = reflect.TypeOf((*UnregisterVMRequestType)(nil)).Elem() +} + +type UnregisterVMResponse struct { +} + +type UnsharedSwapVMotionNotSupported struct { + MigrationFeatureNotSupported +} + +func init() { + t["UnsharedSwapVMotionNotSupported"] = reflect.TypeOf((*UnsharedSwapVMotionNotSupported)(nil)).Elem() +} + +type UnsharedSwapVMotionNotSupportedFault UnsharedSwapVMotionNotSupported + +func init() { + t["UnsharedSwapVMotionNotSupportedFault"] = reflect.TypeOf((*UnsharedSwapVMotionNotSupportedFault)(nil)).Elem() +} + +type UnsupportedDatastore struct { + VmConfigFault + + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` +} + +func init() { + t["UnsupportedDatastore"] = reflect.TypeOf((*UnsupportedDatastore)(nil)).Elem() +} + +type UnsupportedDatastoreFault BaseUnsupportedDatastore + +func init() { + t["UnsupportedDatastoreFault"] = reflect.TypeOf((*UnsupportedDatastoreFault)(nil)).Elem() +} + +type UnsupportedGuest struct { + InvalidVmConfig + + UnsupportedGuestOS string `xml:"unsupportedGuestOS"` +} + +func init() { + t["UnsupportedGuest"] = reflect.TypeOf((*UnsupportedGuest)(nil)).Elem() +} + +type UnsupportedGuestFault UnsupportedGuest + +func init() { + t["UnsupportedGuestFault"] = reflect.TypeOf((*UnsupportedGuestFault)(nil)).Elem() +} + +type UnsupportedVimApiVersion struct { + VimFault + + Version string `xml:"version,omitempty"` +} + +func init() { + t["UnsupportedVimApiVersion"] = reflect.TypeOf((*UnsupportedVimApiVersion)(nil)).Elem() +} + +type UnsupportedVimApiVersionFault UnsupportedVimApiVersion + +func init() { + t["UnsupportedVimApiVersionFault"] = reflect.TypeOf((*UnsupportedVimApiVersionFault)(nil)).Elem() +} + +type UnsupportedVmxLocation struct { + VmConfigFault +} + +func init() { + t["UnsupportedVmxLocation"] = reflect.TypeOf((*UnsupportedVmxLocation)(nil)).Elem() +} + +type UnsupportedVmxLocationFault UnsupportedVmxLocation + +func init() { + t["UnsupportedVmxLocationFault"] = reflect.TypeOf((*UnsupportedVmxLocationFault)(nil)).Elem() +} + +type UnusedVirtualDiskBlocksNotScrubbed struct { + DeviceBackingNotSupported +} + +func init() { + t["UnusedVirtualDiskBlocksNotScrubbed"] = reflect.TypeOf((*UnusedVirtualDiskBlocksNotScrubbed)(nil)).Elem() +} + +type UnusedVirtualDiskBlocksNotScrubbedFault UnusedVirtualDiskBlocksNotScrubbed + +func init() { + t["UnusedVirtualDiskBlocksNotScrubbedFault"] = reflect.TypeOf((*UnusedVirtualDiskBlocksNotScrubbedFault)(nil)).Elem() +} + +type UpdateAnswerFileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host ManagedObjectReference `xml:"host"` + ConfigSpec BaseAnswerFileCreateSpec `xml:"configSpec,typeattr"` +} + +func init() { + t["UpdateAnswerFileRequestType"] = reflect.TypeOf((*UpdateAnswerFileRequestType)(nil)).Elem() +} + +type UpdateAnswerFile_Task UpdateAnswerFileRequestType + +func init() { + t["UpdateAnswerFile_Task"] = reflect.TypeOf((*UpdateAnswerFile_Task)(nil)).Elem() +} + +type UpdateAnswerFile_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpdateAssignedLicense UpdateAssignedLicenseRequestType + +func init() { + t["UpdateAssignedLicense"] = reflect.TypeOf((*UpdateAssignedLicense)(nil)).Elem() +} + +type UpdateAssignedLicenseRequestType struct { + This ManagedObjectReference `xml:"_this"` + Entity string `xml:"entity"` + LicenseKey string `xml:"licenseKey"` + EntityDisplayName string `xml:"entityDisplayName,omitempty"` +} + +func init() { + t["UpdateAssignedLicenseRequestType"] = reflect.TypeOf((*UpdateAssignedLicenseRequestType)(nil)).Elem() +} + +type UpdateAssignedLicenseResponse struct { + Returnval LicenseManagerLicenseInfo `xml:"returnval"` +} + +type UpdateAuthorizationRole UpdateAuthorizationRoleRequestType + +func init() { + t["UpdateAuthorizationRole"] = reflect.TypeOf((*UpdateAuthorizationRole)(nil)).Elem() +} + +type UpdateAuthorizationRoleRequestType struct { + This ManagedObjectReference `xml:"_this"` + RoleId int32 `xml:"roleId"` + NewName string `xml:"newName"` + PrivIds []string `xml:"privIds,omitempty"` +} + +func init() { + t["UpdateAuthorizationRoleRequestType"] = reflect.TypeOf((*UpdateAuthorizationRoleRequestType)(nil)).Elem() +} + +type UpdateAuthorizationRoleResponse struct { +} + +type UpdateBootDevice UpdateBootDeviceRequestType + +func init() { + t["UpdateBootDevice"] = reflect.TypeOf((*UpdateBootDevice)(nil)).Elem() +} + +type UpdateBootDeviceRequestType struct { + This ManagedObjectReference `xml:"_this"` + Key string `xml:"key"` +} + +func init() { + t["UpdateBootDeviceRequestType"] = reflect.TypeOf((*UpdateBootDeviceRequestType)(nil)).Elem() +} + +type UpdateBootDeviceResponse struct { +} + +type UpdateChildResourceConfiguration UpdateChildResourceConfigurationRequestType + +func init() { + t["UpdateChildResourceConfiguration"] = reflect.TypeOf((*UpdateChildResourceConfiguration)(nil)).Elem() +} + +type UpdateChildResourceConfigurationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec []ResourceConfigSpec `xml:"spec"` +} + +func init() { + t["UpdateChildResourceConfigurationRequestType"] = reflect.TypeOf((*UpdateChildResourceConfigurationRequestType)(nil)).Elem() +} + +type UpdateChildResourceConfigurationResponse struct { +} + +type UpdateClusterProfile UpdateClusterProfileRequestType + +func init() { + t["UpdateClusterProfile"] = reflect.TypeOf((*UpdateClusterProfile)(nil)).Elem() +} + +type UpdateClusterProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config BaseClusterProfileConfigSpec `xml:"config,typeattr"` +} + +func init() { + t["UpdateClusterProfileRequestType"] = reflect.TypeOf((*UpdateClusterProfileRequestType)(nil)).Elem() +} + +type UpdateClusterProfileResponse struct { +} + +type UpdateConfig UpdateConfigRequestType + +func init() { + t["UpdateConfig"] = reflect.TypeOf((*UpdateConfig)(nil)).Elem() +} + +type UpdateConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name,omitempty"` + Config *ResourceConfigSpec `xml:"config,omitempty"` +} + +func init() { + t["UpdateConfigRequestType"] = reflect.TypeOf((*UpdateConfigRequestType)(nil)).Elem() +} + +type UpdateConfigResponse struct { +} + +type UpdateConsoleIpRouteConfig UpdateConsoleIpRouteConfigRequestType + +func init() { + t["UpdateConsoleIpRouteConfig"] = reflect.TypeOf((*UpdateConsoleIpRouteConfig)(nil)).Elem() +} + +type UpdateConsoleIpRouteConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config BaseHostIpRouteConfig `xml:"config,typeattr"` +} + +func init() { + t["UpdateConsoleIpRouteConfigRequestType"] = reflect.TypeOf((*UpdateConsoleIpRouteConfigRequestType)(nil)).Elem() +} + +type UpdateConsoleIpRouteConfigResponse struct { +} + +type UpdateCounterLevelMapping UpdateCounterLevelMappingRequestType + +func init() { + t["UpdateCounterLevelMapping"] = reflect.TypeOf((*UpdateCounterLevelMapping)(nil)).Elem() +} + +type UpdateCounterLevelMappingRequestType struct { + This ManagedObjectReference `xml:"_this"` + CounterLevelMap []PerformanceManagerCounterLevelMapping `xml:"counterLevelMap"` +} + +func init() { + t["UpdateCounterLevelMappingRequestType"] = reflect.TypeOf((*UpdateCounterLevelMappingRequestType)(nil)).Elem() +} + +type UpdateCounterLevelMappingResponse struct { +} + +type UpdateDVSHealthCheckConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + HealthCheckConfig []BaseDVSHealthCheckConfig `xml:"healthCheckConfig,typeattr"` +} + +func init() { + t["UpdateDVSHealthCheckConfigRequestType"] = reflect.TypeOf((*UpdateDVSHealthCheckConfigRequestType)(nil)).Elem() +} + +type UpdateDVSHealthCheckConfig_Task UpdateDVSHealthCheckConfigRequestType + +func init() { + t["UpdateDVSHealthCheckConfig_Task"] = reflect.TypeOf((*UpdateDVSHealthCheckConfig_Task)(nil)).Elem() +} + +type UpdateDVSHealthCheckConfig_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpdateDVSLacpGroupConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + LacpGroupSpec []VMwareDvsLacpGroupSpec `xml:"lacpGroupSpec"` +} + +func init() { + t["UpdateDVSLacpGroupConfigRequestType"] = reflect.TypeOf((*UpdateDVSLacpGroupConfigRequestType)(nil)).Elem() +} + +type UpdateDVSLacpGroupConfig_Task UpdateDVSLacpGroupConfigRequestType + +func init() { + t["UpdateDVSLacpGroupConfig_Task"] = reflect.TypeOf((*UpdateDVSLacpGroupConfig_Task)(nil)).Elem() +} + +type UpdateDVSLacpGroupConfig_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpdateDateTime UpdateDateTimeRequestType + +func init() { + t["UpdateDateTime"] = reflect.TypeOf((*UpdateDateTime)(nil)).Elem() +} + +type UpdateDateTimeConfig UpdateDateTimeConfigRequestType + +func init() { + t["UpdateDateTimeConfig"] = reflect.TypeOf((*UpdateDateTimeConfig)(nil)).Elem() +} + +type UpdateDateTimeConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config HostDateTimeConfig `xml:"config"` +} + +func init() { + t["UpdateDateTimeConfigRequestType"] = reflect.TypeOf((*UpdateDateTimeConfigRequestType)(nil)).Elem() +} + +type UpdateDateTimeConfigResponse struct { +} + +type UpdateDateTimeRequestType struct { + This ManagedObjectReference `xml:"_this"` + DateTime time.Time `xml:"dateTime"` +} + +func init() { + t["UpdateDateTimeRequestType"] = reflect.TypeOf((*UpdateDateTimeRequestType)(nil)).Elem() +} + +type UpdateDateTimeResponse struct { +} + +type UpdateDefaultPolicy UpdateDefaultPolicyRequestType + +func init() { + t["UpdateDefaultPolicy"] = reflect.TypeOf((*UpdateDefaultPolicy)(nil)).Elem() +} + +type UpdateDefaultPolicyRequestType struct { + This ManagedObjectReference `xml:"_this"` + DefaultPolicy HostFirewallDefaultPolicy `xml:"defaultPolicy"` +} + +func init() { + t["UpdateDefaultPolicyRequestType"] = reflect.TypeOf((*UpdateDefaultPolicyRequestType)(nil)).Elem() +} + +type UpdateDefaultPolicyResponse struct { +} + +type UpdateDiskPartitions UpdateDiskPartitionsRequestType + +func init() { + t["UpdateDiskPartitions"] = reflect.TypeOf((*UpdateDiskPartitions)(nil)).Elem() +} + +type UpdateDiskPartitionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + DevicePath string `xml:"devicePath"` + Spec HostDiskPartitionSpec `xml:"spec"` +} + +func init() { + t["UpdateDiskPartitionsRequestType"] = reflect.TypeOf((*UpdateDiskPartitionsRequestType)(nil)).Elem() +} + +type UpdateDiskPartitionsResponse struct { +} + +type UpdateDnsConfig UpdateDnsConfigRequestType + +func init() { + t["UpdateDnsConfig"] = reflect.TypeOf((*UpdateDnsConfig)(nil)).Elem() +} + +type UpdateDnsConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config BaseHostDnsConfig `xml:"config,typeattr"` +} + +func init() { + t["UpdateDnsConfigRequestType"] = reflect.TypeOf((*UpdateDnsConfigRequestType)(nil)).Elem() +} + +type UpdateDnsConfigResponse struct { +} + +type UpdateDvsCapability UpdateDvsCapabilityRequestType + +func init() { + t["UpdateDvsCapability"] = reflect.TypeOf((*UpdateDvsCapability)(nil)).Elem() +} + +type UpdateDvsCapabilityRequestType struct { + This ManagedObjectReference `xml:"_this"` + Capability DVSCapability `xml:"capability"` +} + +func init() { + t["UpdateDvsCapabilityRequestType"] = reflect.TypeOf((*UpdateDvsCapabilityRequestType)(nil)).Elem() +} + +type UpdateDvsCapabilityResponse struct { +} + +type UpdateExtension UpdateExtensionRequestType + +func init() { + t["UpdateExtension"] = reflect.TypeOf((*UpdateExtension)(nil)).Elem() +} + +type UpdateExtensionRequestType struct { + This ManagedObjectReference `xml:"_this"` + Extension Extension `xml:"extension"` +} + +func init() { + t["UpdateExtensionRequestType"] = reflect.TypeOf((*UpdateExtensionRequestType)(nil)).Elem() +} + +type UpdateExtensionResponse struct { +} + +type UpdateFlags UpdateFlagsRequestType + +func init() { + t["UpdateFlags"] = reflect.TypeOf((*UpdateFlags)(nil)).Elem() +} + +type UpdateFlagsRequestType struct { + This ManagedObjectReference `xml:"_this"` + FlagInfo HostFlagInfo `xml:"flagInfo"` +} + +func init() { + t["UpdateFlagsRequestType"] = reflect.TypeOf((*UpdateFlagsRequestType)(nil)).Elem() +} + +type UpdateFlagsResponse struct { +} + +type UpdateHostImageAcceptanceLevel UpdateHostImageAcceptanceLevelRequestType + +func init() { + t["UpdateHostImageAcceptanceLevel"] = reflect.TypeOf((*UpdateHostImageAcceptanceLevel)(nil)).Elem() +} + +type UpdateHostImageAcceptanceLevelRequestType struct { + This ManagedObjectReference `xml:"_this"` + NewAcceptanceLevel string `xml:"newAcceptanceLevel"` +} + +func init() { + t["UpdateHostImageAcceptanceLevelRequestType"] = reflect.TypeOf((*UpdateHostImageAcceptanceLevelRequestType)(nil)).Elem() +} + +type UpdateHostImageAcceptanceLevelResponse struct { +} + +type UpdateHostProfile UpdateHostProfileRequestType + +func init() { + t["UpdateHostProfile"] = reflect.TypeOf((*UpdateHostProfile)(nil)).Elem() +} + +type UpdateHostProfileRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config BaseHostProfileConfigSpec `xml:"config,typeattr"` +} + +func init() { + t["UpdateHostProfileRequestType"] = reflect.TypeOf((*UpdateHostProfileRequestType)(nil)).Elem() +} + +type UpdateHostProfileResponse struct { +} + +type UpdateInternetScsiAdvancedOptions UpdateInternetScsiAdvancedOptionsRequestType + +func init() { + t["UpdateInternetScsiAdvancedOptions"] = reflect.TypeOf((*UpdateInternetScsiAdvancedOptions)(nil)).Elem() +} + +type UpdateInternetScsiAdvancedOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + TargetSet *HostInternetScsiHbaTargetSet `xml:"targetSet,omitempty"` + Options []HostInternetScsiHbaParamValue `xml:"options"` +} + +func init() { + t["UpdateInternetScsiAdvancedOptionsRequestType"] = reflect.TypeOf((*UpdateInternetScsiAdvancedOptionsRequestType)(nil)).Elem() +} + +type UpdateInternetScsiAdvancedOptionsResponse struct { +} + +type UpdateInternetScsiAlias UpdateInternetScsiAliasRequestType + +func init() { + t["UpdateInternetScsiAlias"] = reflect.TypeOf((*UpdateInternetScsiAlias)(nil)).Elem() +} + +type UpdateInternetScsiAliasRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + IScsiAlias string `xml:"iScsiAlias"` +} + +func init() { + t["UpdateInternetScsiAliasRequestType"] = reflect.TypeOf((*UpdateInternetScsiAliasRequestType)(nil)).Elem() +} + +type UpdateInternetScsiAliasResponse struct { +} + +type UpdateInternetScsiAuthenticationProperties UpdateInternetScsiAuthenticationPropertiesRequestType + +func init() { + t["UpdateInternetScsiAuthenticationProperties"] = reflect.TypeOf((*UpdateInternetScsiAuthenticationProperties)(nil)).Elem() +} + +type UpdateInternetScsiAuthenticationPropertiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + AuthenticationProperties HostInternetScsiHbaAuthenticationProperties `xml:"authenticationProperties"` + TargetSet *HostInternetScsiHbaTargetSet `xml:"targetSet,omitempty"` +} + +func init() { + t["UpdateInternetScsiAuthenticationPropertiesRequestType"] = reflect.TypeOf((*UpdateInternetScsiAuthenticationPropertiesRequestType)(nil)).Elem() +} + +type UpdateInternetScsiAuthenticationPropertiesResponse struct { +} + +type UpdateInternetScsiDigestProperties UpdateInternetScsiDigestPropertiesRequestType + +func init() { + t["UpdateInternetScsiDigestProperties"] = reflect.TypeOf((*UpdateInternetScsiDigestProperties)(nil)).Elem() +} + +type UpdateInternetScsiDigestPropertiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + TargetSet *HostInternetScsiHbaTargetSet `xml:"targetSet,omitempty"` + DigestProperties HostInternetScsiHbaDigestProperties `xml:"digestProperties"` +} + +func init() { + t["UpdateInternetScsiDigestPropertiesRequestType"] = reflect.TypeOf((*UpdateInternetScsiDigestPropertiesRequestType)(nil)).Elem() +} + +type UpdateInternetScsiDigestPropertiesResponse struct { +} + +type UpdateInternetScsiDiscoveryProperties UpdateInternetScsiDiscoveryPropertiesRequestType + +func init() { + t["UpdateInternetScsiDiscoveryProperties"] = reflect.TypeOf((*UpdateInternetScsiDiscoveryProperties)(nil)).Elem() +} + +type UpdateInternetScsiDiscoveryPropertiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + DiscoveryProperties HostInternetScsiHbaDiscoveryProperties `xml:"discoveryProperties"` +} + +func init() { + t["UpdateInternetScsiDiscoveryPropertiesRequestType"] = reflect.TypeOf((*UpdateInternetScsiDiscoveryPropertiesRequestType)(nil)).Elem() +} + +type UpdateInternetScsiDiscoveryPropertiesResponse struct { +} + +type UpdateInternetScsiIPProperties UpdateInternetScsiIPPropertiesRequestType + +func init() { + t["UpdateInternetScsiIPProperties"] = reflect.TypeOf((*UpdateInternetScsiIPProperties)(nil)).Elem() +} + +type UpdateInternetScsiIPPropertiesRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + IpProperties HostInternetScsiHbaIPProperties `xml:"ipProperties"` +} + +func init() { + t["UpdateInternetScsiIPPropertiesRequestType"] = reflect.TypeOf((*UpdateInternetScsiIPPropertiesRequestType)(nil)).Elem() +} + +type UpdateInternetScsiIPPropertiesResponse struct { +} + +type UpdateInternetScsiName UpdateInternetScsiNameRequestType + +func init() { + t["UpdateInternetScsiName"] = reflect.TypeOf((*UpdateInternetScsiName)(nil)).Elem() +} + +type UpdateInternetScsiNameRequestType struct { + This ManagedObjectReference `xml:"_this"` + IScsiHbaDevice string `xml:"iScsiHbaDevice"` + IScsiName string `xml:"iScsiName"` +} + +func init() { + t["UpdateInternetScsiNameRequestType"] = reflect.TypeOf((*UpdateInternetScsiNameRequestType)(nil)).Elem() +} + +type UpdateInternetScsiNameResponse struct { +} + +type UpdateIpConfig UpdateIpConfigRequestType + +func init() { + t["UpdateIpConfig"] = reflect.TypeOf((*UpdateIpConfig)(nil)).Elem() +} + +type UpdateIpConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + IpConfig HostIpConfig `xml:"ipConfig"` +} + +func init() { + t["UpdateIpConfigRequestType"] = reflect.TypeOf((*UpdateIpConfigRequestType)(nil)).Elem() +} + +type UpdateIpConfigResponse struct { +} + +type UpdateIpPool UpdateIpPoolRequestType + +func init() { + t["UpdateIpPool"] = reflect.TypeOf((*UpdateIpPool)(nil)).Elem() +} + +type UpdateIpPoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + Dc ManagedObjectReference `xml:"dc"` + Pool IpPool `xml:"pool"` +} + +func init() { + t["UpdateIpPoolRequestType"] = reflect.TypeOf((*UpdateIpPoolRequestType)(nil)).Elem() +} + +type UpdateIpPoolResponse struct { +} + +type UpdateIpRouteConfig UpdateIpRouteConfigRequestType + +func init() { + t["UpdateIpRouteConfig"] = reflect.TypeOf((*UpdateIpRouteConfig)(nil)).Elem() +} + +type UpdateIpRouteConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config BaseHostIpRouteConfig `xml:"config,typeattr"` +} + +func init() { + t["UpdateIpRouteConfigRequestType"] = reflect.TypeOf((*UpdateIpRouteConfigRequestType)(nil)).Elem() +} + +type UpdateIpRouteConfigResponse struct { +} + +type UpdateIpRouteTableConfig UpdateIpRouteTableConfigRequestType + +func init() { + t["UpdateIpRouteTableConfig"] = reflect.TypeOf((*UpdateIpRouteTableConfig)(nil)).Elem() +} + +type UpdateIpRouteTableConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config HostIpRouteTableConfig `xml:"config"` +} + +func init() { + t["UpdateIpRouteTableConfigRequestType"] = reflect.TypeOf((*UpdateIpRouteTableConfigRequestType)(nil)).Elem() +} + +type UpdateIpRouteTableConfigResponse struct { +} + +type UpdateIpmi UpdateIpmiRequestType + +func init() { + t["UpdateIpmi"] = reflect.TypeOf((*UpdateIpmi)(nil)).Elem() +} + +type UpdateIpmiRequestType struct { + This ManagedObjectReference `xml:"_this"` + IpmiInfo HostIpmiInfo `xml:"ipmiInfo"` +} + +func init() { + t["UpdateIpmiRequestType"] = reflect.TypeOf((*UpdateIpmiRequestType)(nil)).Elem() +} + +type UpdateIpmiResponse struct { +} + +type UpdateLicense UpdateLicenseRequestType + +func init() { + t["UpdateLicense"] = reflect.TypeOf((*UpdateLicense)(nil)).Elem() +} + +type UpdateLicenseLabel UpdateLicenseLabelRequestType + +func init() { + t["UpdateLicenseLabel"] = reflect.TypeOf((*UpdateLicenseLabel)(nil)).Elem() +} + +type UpdateLicenseLabelRequestType struct { + This ManagedObjectReference `xml:"_this"` + LicenseKey string `xml:"licenseKey"` + LabelKey string `xml:"labelKey"` + LabelValue string `xml:"labelValue"` +} + +func init() { + t["UpdateLicenseLabelRequestType"] = reflect.TypeOf((*UpdateLicenseLabelRequestType)(nil)).Elem() +} + +type UpdateLicenseLabelResponse struct { +} + +type UpdateLicenseRequestType struct { + This ManagedObjectReference `xml:"_this"` + LicenseKey string `xml:"licenseKey"` + Labels []KeyValue `xml:"labels,omitempty"` +} + +func init() { + t["UpdateLicenseRequestType"] = reflect.TypeOf((*UpdateLicenseRequestType)(nil)).Elem() +} + +type UpdateLicenseResponse struct { + Returnval LicenseManagerLicenseInfo `xml:"returnval"` +} + +type UpdateLinkedChildren UpdateLinkedChildrenRequestType + +func init() { + t["UpdateLinkedChildren"] = reflect.TypeOf((*UpdateLinkedChildren)(nil)).Elem() +} + +type UpdateLinkedChildrenRequestType struct { + This ManagedObjectReference `xml:"_this"` + AddChangeSet []VirtualAppLinkInfo `xml:"addChangeSet,omitempty"` + RemoveSet []ManagedObjectReference `xml:"removeSet,omitempty"` +} + +func init() { + t["UpdateLinkedChildrenRequestType"] = reflect.TypeOf((*UpdateLinkedChildrenRequestType)(nil)).Elem() +} + +type UpdateLinkedChildrenResponse struct { +} + +type UpdateLocalSwapDatastore UpdateLocalSwapDatastoreRequestType + +func init() { + t["UpdateLocalSwapDatastore"] = reflect.TypeOf((*UpdateLocalSwapDatastore)(nil)).Elem() +} + +type UpdateLocalSwapDatastoreRequestType struct { + This ManagedObjectReference `xml:"_this"` + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` +} + +func init() { + t["UpdateLocalSwapDatastoreRequestType"] = reflect.TypeOf((*UpdateLocalSwapDatastoreRequestType)(nil)).Elem() +} + +type UpdateLocalSwapDatastoreResponse struct { +} + +type UpdateLockdownExceptions UpdateLockdownExceptionsRequestType + +func init() { + t["UpdateLockdownExceptions"] = reflect.TypeOf((*UpdateLockdownExceptions)(nil)).Elem() +} + +type UpdateLockdownExceptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Users []string `xml:"users,omitempty"` +} + +func init() { + t["UpdateLockdownExceptionsRequestType"] = reflect.TypeOf((*UpdateLockdownExceptionsRequestType)(nil)).Elem() +} + +type UpdateLockdownExceptionsResponse struct { +} + +type UpdateModuleOptionString UpdateModuleOptionStringRequestType + +func init() { + t["UpdateModuleOptionString"] = reflect.TypeOf((*UpdateModuleOptionString)(nil)).Elem() +} + +type UpdateModuleOptionStringRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Options string `xml:"options"` +} + +func init() { + t["UpdateModuleOptionStringRequestType"] = reflect.TypeOf((*UpdateModuleOptionStringRequestType)(nil)).Elem() +} + +type UpdateModuleOptionStringResponse struct { +} + +type UpdateNetworkConfig UpdateNetworkConfigRequestType + +func init() { + t["UpdateNetworkConfig"] = reflect.TypeOf((*UpdateNetworkConfig)(nil)).Elem() +} + +type UpdateNetworkConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config HostNetworkConfig `xml:"config"` + ChangeMode string `xml:"changeMode"` +} + +func init() { + t["UpdateNetworkConfigRequestType"] = reflect.TypeOf((*UpdateNetworkConfigRequestType)(nil)).Elem() +} + +type UpdateNetworkConfigResponse struct { + Returnval HostNetworkConfigResult `xml:"returnval"` +} + +type UpdateNetworkResourcePool UpdateNetworkResourcePoolRequestType + +func init() { + t["UpdateNetworkResourcePool"] = reflect.TypeOf((*UpdateNetworkResourcePool)(nil)).Elem() +} + +type UpdateNetworkResourcePoolRequestType struct { + This ManagedObjectReference `xml:"_this"` + ConfigSpec []DVSNetworkResourcePoolConfigSpec `xml:"configSpec"` +} + +func init() { + t["UpdateNetworkResourcePoolRequestType"] = reflect.TypeOf((*UpdateNetworkResourcePoolRequestType)(nil)).Elem() +} + +type UpdateNetworkResourcePoolResponse struct { +} + +type UpdateOptions UpdateOptionsRequestType + +func init() { + t["UpdateOptions"] = reflect.TypeOf((*UpdateOptions)(nil)).Elem() +} + +type UpdateOptionsRequestType struct { + This ManagedObjectReference `xml:"_this"` + ChangedValue []BaseOptionValue `xml:"changedValue,typeattr"` +} + +func init() { + t["UpdateOptionsRequestType"] = reflect.TypeOf((*UpdateOptionsRequestType)(nil)).Elem() +} + +type UpdateOptionsResponse struct { +} + +type UpdatePassthruConfig UpdatePassthruConfigRequestType + +func init() { + t["UpdatePassthruConfig"] = reflect.TypeOf((*UpdatePassthruConfig)(nil)).Elem() +} + +type UpdatePassthruConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config []BaseHostPciPassthruConfig `xml:"config,typeattr"` +} + +func init() { + t["UpdatePassthruConfigRequestType"] = reflect.TypeOf((*UpdatePassthruConfigRequestType)(nil)).Elem() +} + +type UpdatePassthruConfigResponse struct { +} + +type UpdatePerfInterval UpdatePerfIntervalRequestType + +func init() { + t["UpdatePerfInterval"] = reflect.TypeOf((*UpdatePerfInterval)(nil)).Elem() +} + +type UpdatePerfIntervalRequestType struct { + This ManagedObjectReference `xml:"_this"` + Interval PerfInterval `xml:"interval"` +} + +func init() { + t["UpdatePerfIntervalRequestType"] = reflect.TypeOf((*UpdatePerfIntervalRequestType)(nil)).Elem() +} + +type UpdatePerfIntervalResponse struct { +} + +type UpdatePhysicalNicLinkSpeed UpdatePhysicalNicLinkSpeedRequestType + +func init() { + t["UpdatePhysicalNicLinkSpeed"] = reflect.TypeOf((*UpdatePhysicalNicLinkSpeed)(nil)).Elem() +} + +type UpdatePhysicalNicLinkSpeedRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` + LinkSpeed *PhysicalNicLinkInfo `xml:"linkSpeed,omitempty"` +} + +func init() { + t["UpdatePhysicalNicLinkSpeedRequestType"] = reflect.TypeOf((*UpdatePhysicalNicLinkSpeedRequestType)(nil)).Elem() +} + +type UpdatePhysicalNicLinkSpeedResponse struct { +} + +type UpdatePortGroup UpdatePortGroupRequestType + +func init() { + t["UpdatePortGroup"] = reflect.TypeOf((*UpdatePortGroup)(nil)).Elem() +} + +type UpdatePortGroupRequestType struct { + This ManagedObjectReference `xml:"_this"` + PgName string `xml:"pgName"` + Portgrp HostPortGroupSpec `xml:"portgrp"` +} + +func init() { + t["UpdatePortGroupRequestType"] = reflect.TypeOf((*UpdatePortGroupRequestType)(nil)).Elem() +} + +type UpdatePortGroupResponse struct { +} + +type UpdateProgress UpdateProgressRequestType + +func init() { + t["UpdateProgress"] = reflect.TypeOf((*UpdateProgress)(nil)).Elem() +} + +type UpdateProgressRequestType struct { + This ManagedObjectReference `xml:"_this"` + PercentDone int32 `xml:"percentDone"` +} + +func init() { + t["UpdateProgressRequestType"] = reflect.TypeOf((*UpdateProgressRequestType)(nil)).Elem() +} + +type UpdateProgressResponse struct { +} + +type UpdateReferenceHost UpdateReferenceHostRequestType + +func init() { + t["UpdateReferenceHost"] = reflect.TypeOf((*UpdateReferenceHost)(nil)).Elem() +} + +type UpdateReferenceHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["UpdateReferenceHostRequestType"] = reflect.TypeOf((*UpdateReferenceHostRequestType)(nil)).Elem() +} + +type UpdateReferenceHostResponse struct { +} + +type UpdateRuleset UpdateRulesetRequestType + +func init() { + t["UpdateRuleset"] = reflect.TypeOf((*UpdateRuleset)(nil)).Elem() +} + +type UpdateRulesetRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` + Spec HostFirewallRulesetRulesetSpec `xml:"spec"` +} + +func init() { + t["UpdateRulesetRequestType"] = reflect.TypeOf((*UpdateRulesetRequestType)(nil)).Elem() +} + +type UpdateRulesetResponse struct { +} + +type UpdateScsiLunDisplayName UpdateScsiLunDisplayNameRequestType + +func init() { + t["UpdateScsiLunDisplayName"] = reflect.TypeOf((*UpdateScsiLunDisplayName)(nil)).Elem() +} + +type UpdateScsiLunDisplayNameRequestType struct { + This ManagedObjectReference `xml:"_this"` + LunUuid string `xml:"lunUuid"` + DisplayName string `xml:"displayName"` +} + +func init() { + t["UpdateScsiLunDisplayNameRequestType"] = reflect.TypeOf((*UpdateScsiLunDisplayNameRequestType)(nil)).Elem() +} + +type UpdateScsiLunDisplayNameResponse struct { +} + +type UpdateServiceConsoleVirtualNic UpdateServiceConsoleVirtualNicRequestType + +func init() { + t["UpdateServiceConsoleVirtualNic"] = reflect.TypeOf((*UpdateServiceConsoleVirtualNic)(nil)).Elem() +} + +type UpdateServiceConsoleVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` + Nic HostVirtualNicSpec `xml:"nic"` +} + +func init() { + t["UpdateServiceConsoleVirtualNicRequestType"] = reflect.TypeOf((*UpdateServiceConsoleVirtualNicRequestType)(nil)).Elem() +} + +type UpdateServiceConsoleVirtualNicResponse struct { +} + +type UpdateServiceMessage UpdateServiceMessageRequestType + +func init() { + t["UpdateServiceMessage"] = reflect.TypeOf((*UpdateServiceMessage)(nil)).Elem() +} + +type UpdateServiceMessageRequestType struct { + This ManagedObjectReference `xml:"_this"` + Message string `xml:"message"` +} + +func init() { + t["UpdateServiceMessageRequestType"] = reflect.TypeOf((*UpdateServiceMessageRequestType)(nil)).Elem() +} + +type UpdateServiceMessageResponse struct { +} + +type UpdateServicePolicy UpdateServicePolicyRequestType + +func init() { + t["UpdateServicePolicy"] = reflect.TypeOf((*UpdateServicePolicy)(nil)).Elem() +} + +type UpdateServicePolicyRequestType struct { + This ManagedObjectReference `xml:"_this"` + Id string `xml:"id"` + Policy string `xml:"policy"` +} + +func init() { + t["UpdateServicePolicyRequestType"] = reflect.TypeOf((*UpdateServicePolicyRequestType)(nil)).Elem() +} + +type UpdateServicePolicyResponse struct { +} + +type UpdateSet struct { + DynamicData + + Version string `xml:"version"` + FilterSet []PropertyFilterUpdate `xml:"filterSet,omitempty"` + Truncated *bool `xml:"truncated"` +} + +func init() { + t["UpdateSet"] = reflect.TypeOf((*UpdateSet)(nil)).Elem() +} + +type UpdateSoftwareInternetScsiEnabled UpdateSoftwareInternetScsiEnabledRequestType + +func init() { + t["UpdateSoftwareInternetScsiEnabled"] = reflect.TypeOf((*UpdateSoftwareInternetScsiEnabled)(nil)).Elem() +} + +type UpdateSoftwareInternetScsiEnabledRequestType struct { + This ManagedObjectReference `xml:"_this"` + Enabled bool `xml:"enabled"` +} + +func init() { + t["UpdateSoftwareInternetScsiEnabledRequestType"] = reflect.TypeOf((*UpdateSoftwareInternetScsiEnabledRequestType)(nil)).Elem() +} + +type UpdateSoftwareInternetScsiEnabledResponse struct { +} + +type UpdateSystemResources UpdateSystemResourcesRequestType + +func init() { + t["UpdateSystemResources"] = reflect.TypeOf((*UpdateSystemResources)(nil)).Elem() +} + +type UpdateSystemResourcesRequestType struct { + This ManagedObjectReference `xml:"_this"` + ResourceInfo HostSystemResourceInfo `xml:"resourceInfo"` +} + +func init() { + t["UpdateSystemResourcesRequestType"] = reflect.TypeOf((*UpdateSystemResourcesRequestType)(nil)).Elem() +} + +type UpdateSystemResourcesResponse struct { +} + +type UpdateSystemSwapConfiguration UpdateSystemSwapConfigurationRequestType + +func init() { + t["UpdateSystemSwapConfiguration"] = reflect.TypeOf((*UpdateSystemSwapConfiguration)(nil)).Elem() +} + +type UpdateSystemSwapConfigurationRequestType struct { + This ManagedObjectReference `xml:"_this"` + SysSwapConfig HostSystemSwapConfiguration `xml:"sysSwapConfig"` +} + +func init() { + t["UpdateSystemSwapConfigurationRequestType"] = reflect.TypeOf((*UpdateSystemSwapConfigurationRequestType)(nil)).Elem() +} + +type UpdateSystemSwapConfigurationResponse struct { +} + +type UpdateSystemUsers UpdateSystemUsersRequestType + +func init() { + t["UpdateSystemUsers"] = reflect.TypeOf((*UpdateSystemUsers)(nil)).Elem() +} + +type UpdateSystemUsersRequestType struct { + This ManagedObjectReference `xml:"_this"` + Users []string `xml:"users,omitempty"` +} + +func init() { + t["UpdateSystemUsersRequestType"] = reflect.TypeOf((*UpdateSystemUsersRequestType)(nil)).Elem() +} + +type UpdateSystemUsersResponse struct { +} + +type UpdateUser UpdateUserRequestType + +func init() { + t["UpdateUser"] = reflect.TypeOf((*UpdateUser)(nil)).Elem() +} + +type UpdateUserRequestType struct { + This ManagedObjectReference `xml:"_this"` + User BaseHostAccountSpec `xml:"user,typeattr"` +} + +func init() { + t["UpdateUserRequestType"] = reflect.TypeOf((*UpdateUserRequestType)(nil)).Elem() +} + +type UpdateUserResponse struct { +} + +type UpdateVAppConfig UpdateVAppConfigRequestType + +func init() { + t["UpdateVAppConfig"] = reflect.TypeOf((*UpdateVAppConfig)(nil)).Elem() +} + +type UpdateVAppConfigRequestType struct { + This ManagedObjectReference `xml:"_this"` + Spec VAppConfigSpec `xml:"spec"` +} + +func init() { + t["UpdateVAppConfigRequestType"] = reflect.TypeOf((*UpdateVAppConfigRequestType)(nil)).Elem() +} + +type UpdateVAppConfigResponse struct { +} + +type UpdateVirtualMachineFilesRequestType struct { + This ManagedObjectReference `xml:"_this"` + MountPathDatastoreMapping []DatastoreMountPathDatastorePair `xml:"mountPathDatastoreMapping"` +} + +func init() { + t["UpdateVirtualMachineFilesRequestType"] = reflect.TypeOf((*UpdateVirtualMachineFilesRequestType)(nil)).Elem() +} + +type UpdateVirtualMachineFilesResult struct { + DynamicData + + FailedVmFile []UpdateVirtualMachineFilesResultFailedVmFileInfo `xml:"failedVmFile,omitempty"` +} + +func init() { + t["UpdateVirtualMachineFilesResult"] = reflect.TypeOf((*UpdateVirtualMachineFilesResult)(nil)).Elem() +} + +type UpdateVirtualMachineFilesResultFailedVmFileInfo struct { + DynamicData + + VmFile string `xml:"vmFile"` + Fault LocalizedMethodFault `xml:"fault"` +} + +func init() { + t["UpdateVirtualMachineFilesResultFailedVmFileInfo"] = reflect.TypeOf((*UpdateVirtualMachineFilesResultFailedVmFileInfo)(nil)).Elem() +} + +type UpdateVirtualMachineFiles_Task UpdateVirtualMachineFilesRequestType + +func init() { + t["UpdateVirtualMachineFiles_Task"] = reflect.TypeOf((*UpdateVirtualMachineFiles_Task)(nil)).Elem() +} + +type UpdateVirtualMachineFiles_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpdateVirtualNic UpdateVirtualNicRequestType + +func init() { + t["UpdateVirtualNic"] = reflect.TypeOf((*UpdateVirtualNic)(nil)).Elem() +} + +type UpdateVirtualNicRequestType struct { + This ManagedObjectReference `xml:"_this"` + Device string `xml:"device"` + Nic HostVirtualNicSpec `xml:"nic"` +} + +func init() { + t["UpdateVirtualNicRequestType"] = reflect.TypeOf((*UpdateVirtualNicRequestType)(nil)).Elem() +} + +type UpdateVirtualNicResponse struct { +} + +type UpdateVirtualSwitch UpdateVirtualSwitchRequestType + +func init() { + t["UpdateVirtualSwitch"] = reflect.TypeOf((*UpdateVirtualSwitch)(nil)).Elem() +} + +type UpdateVirtualSwitchRequestType struct { + This ManagedObjectReference `xml:"_this"` + VswitchName string `xml:"vswitchName"` + Spec HostVirtualSwitchSpec `xml:"spec"` +} + +func init() { + t["UpdateVirtualSwitchRequestType"] = reflect.TypeOf((*UpdateVirtualSwitchRequestType)(nil)).Elem() +} + +type UpdateVirtualSwitchResponse struct { +} + +type UpdateVsanRequestType struct { + This ManagedObjectReference `xml:"_this"` + Config VsanHostConfigInfo `xml:"config"` +} + +func init() { + t["UpdateVsanRequestType"] = reflect.TypeOf((*UpdateVsanRequestType)(nil)).Elem() +} + +type UpdateVsan_Task UpdateVsanRequestType + +func init() { + t["UpdateVsan_Task"] = reflect.TypeOf((*UpdateVsan_Task)(nil)).Elem() +} + +type UpdateVsan_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpdatedAgentBeingRestartedEvent struct { + HostEvent +} + +func init() { + t["UpdatedAgentBeingRestartedEvent"] = reflect.TypeOf((*UpdatedAgentBeingRestartedEvent)(nil)).Elem() +} + +type UpgradeEvent struct { + Event + + Message string `xml:"message"` +} + +func init() { + t["UpgradeEvent"] = reflect.TypeOf((*UpgradeEvent)(nil)).Elem() +} + +type UpgradeIoFilterRequestType struct { + This ManagedObjectReference `xml:"_this"` + FilterId string `xml:"filterId"` + CompRes ManagedObjectReference `xml:"compRes"` + VibUrl string `xml:"vibUrl"` +} + +func init() { + t["UpgradeIoFilterRequestType"] = reflect.TypeOf((*UpgradeIoFilterRequestType)(nil)).Elem() +} + +type UpgradeIoFilter_Task UpgradeIoFilterRequestType + +func init() { + t["UpgradeIoFilter_Task"] = reflect.TypeOf((*UpgradeIoFilter_Task)(nil)).Elem() +} + +type UpgradeIoFilter_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpgradeToolsRequestType struct { + This ManagedObjectReference `xml:"_this"` + InstallerOptions string `xml:"installerOptions,omitempty"` +} + +func init() { + t["UpgradeToolsRequestType"] = reflect.TypeOf((*UpgradeToolsRequestType)(nil)).Elem() +} + +type UpgradeTools_Task UpgradeToolsRequestType + +func init() { + t["UpgradeTools_Task"] = reflect.TypeOf((*UpgradeTools_Task)(nil)).Elem() +} + +type UpgradeTools_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpgradeVMRequestType struct { + This ManagedObjectReference `xml:"_this"` + Version string `xml:"version,omitempty"` +} + +func init() { + t["UpgradeVMRequestType"] = reflect.TypeOf((*UpgradeVMRequestType)(nil)).Elem() +} + +type UpgradeVM_Task UpgradeVMRequestType + +func init() { + t["UpgradeVM_Task"] = reflect.TypeOf((*UpgradeVM_Task)(nil)).Elem() +} + +type UpgradeVM_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} + +type UpgradeVmLayout UpgradeVmLayoutRequestType + +func init() { + t["UpgradeVmLayout"] = reflect.TypeOf((*UpgradeVmLayout)(nil)).Elem() +} + +type UpgradeVmLayoutRequestType struct { + This ManagedObjectReference `xml:"_this"` +} + +func init() { + t["UpgradeVmLayoutRequestType"] = reflect.TypeOf((*UpgradeVmLayoutRequestType)(nil)).Elem() +} + +type UpgradeVmLayoutResponse struct { +} + +type UpgradeVmfs UpgradeVmfsRequestType + +func init() { + t["UpgradeVmfs"] = reflect.TypeOf((*UpgradeVmfs)(nil)).Elem() +} + +type UpgradeVmfsRequestType struct { + This ManagedObjectReference `xml:"_this"` + VmfsPath string `xml:"vmfsPath"` +} + +func init() { + t["UpgradeVmfsRequestType"] = reflect.TypeOf((*UpgradeVmfsRequestType)(nil)).Elem() +} + +type UpgradeVmfsResponse struct { +} + +type UpgradeVsanObjects UpgradeVsanObjectsRequestType + +func init() { + t["UpgradeVsanObjects"] = reflect.TypeOf((*UpgradeVsanObjects)(nil)).Elem() +} + +type UpgradeVsanObjectsRequestType struct { + This ManagedObjectReference `xml:"_this"` + Uuids []string `xml:"uuids"` + NewVersion int32 `xml:"newVersion"` +} + +func init() { + t["UpgradeVsanObjectsRequestType"] = reflect.TypeOf((*UpgradeVsanObjectsRequestType)(nil)).Elem() +} + +type UpgradeVsanObjectsResponse struct { + Returnval []HostVsanInternalSystemVsanObjectOperationResult `xml:"returnval,omitempty"` +} + +type UplinkPortMtuNotSupportEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["UplinkPortMtuNotSupportEvent"] = reflect.TypeOf((*UplinkPortMtuNotSupportEvent)(nil)).Elem() +} + +type UplinkPortMtuSupportEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["UplinkPortMtuSupportEvent"] = reflect.TypeOf((*UplinkPortMtuSupportEvent)(nil)).Elem() +} + +type UplinkPortVlanTrunkedEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["UplinkPortVlanTrunkedEvent"] = reflect.TypeOf((*UplinkPortVlanTrunkedEvent)(nil)).Elem() +} + +type UplinkPortVlanUntrunkedEvent struct { + DvsHealthStatusChangeEvent +} + +func init() { + t["UplinkPortVlanUntrunkedEvent"] = reflect.TypeOf((*UplinkPortVlanUntrunkedEvent)(nil)).Elem() +} + +type UserAssignedToGroup struct { + HostEvent + + UserLogin string `xml:"userLogin"` + Group string `xml:"group"` +} + +func init() { + t["UserAssignedToGroup"] = reflect.TypeOf((*UserAssignedToGroup)(nil)).Elem() +} + +type UserGroupProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["UserGroupProfile"] = reflect.TypeOf((*UserGroupProfile)(nil)).Elem() +} + +type UserInputRequiredParameterMetadata struct { + ProfilePolicyOptionMetadata + + UserInputParameter []ProfileParameterMetadata `xml:"userInputParameter,omitempty"` +} + +func init() { + t["UserInputRequiredParameterMetadata"] = reflect.TypeOf((*UserInputRequiredParameterMetadata)(nil)).Elem() +} + +type UserLoginSessionEvent struct { + SessionEvent + + IpAddress string `xml:"ipAddress"` + UserAgent string `xml:"userAgent,omitempty"` + Locale string `xml:"locale"` + SessionId string `xml:"sessionId"` +} + +func init() { + t["UserLoginSessionEvent"] = reflect.TypeOf((*UserLoginSessionEvent)(nil)).Elem() +} + +type UserLogoutSessionEvent struct { + SessionEvent + + IpAddress string `xml:"ipAddress,omitempty"` + UserAgent string `xml:"userAgent,omitempty"` + CallCount int64 `xml:"callCount,omitempty"` + SessionId string `xml:"sessionId,omitempty"` + LoginTime *time.Time `xml:"loginTime"` +} + +func init() { + t["UserLogoutSessionEvent"] = reflect.TypeOf((*UserLogoutSessionEvent)(nil)).Elem() +} + +type UserNotFound struct { + VimFault + + Principal string `xml:"principal"` + Unresolved bool `xml:"unresolved"` +} + +func init() { + t["UserNotFound"] = reflect.TypeOf((*UserNotFound)(nil)).Elem() +} + +type UserNotFoundFault UserNotFound + +func init() { + t["UserNotFoundFault"] = reflect.TypeOf((*UserNotFoundFault)(nil)).Elem() +} + +type UserPasswordChanged struct { + HostEvent + + UserLogin string `xml:"userLogin"` +} + +func init() { + t["UserPasswordChanged"] = reflect.TypeOf((*UserPasswordChanged)(nil)).Elem() +} + +type UserProfile struct { + ApplyProfile + + Key string `xml:"key"` +} + +func init() { + t["UserProfile"] = reflect.TypeOf((*UserProfile)(nil)).Elem() +} + +type UserSearchResult struct { + DynamicData + + Principal string `xml:"principal"` + FullName string `xml:"fullName,omitempty"` + Group bool `xml:"group"` +} + +func init() { + t["UserSearchResult"] = reflect.TypeOf((*UserSearchResult)(nil)).Elem() +} + +type UserSession struct { + DynamicData + + Key string `xml:"key"` + UserName string `xml:"userName"` + FullName string `xml:"fullName"` + LoginTime time.Time `xml:"loginTime"` + LastActiveTime time.Time `xml:"lastActiveTime"` + Locale string `xml:"locale"` + MessageLocale string `xml:"messageLocale"` + ExtensionSession *bool `xml:"extensionSession"` + IpAddress string `xml:"ipAddress,omitempty"` + UserAgent string `xml:"userAgent,omitempty"` + CallCount int64 `xml:"callCount,omitempty"` +} + +func init() { + t["UserSession"] = reflect.TypeOf((*UserSession)(nil)).Elem() +} + +type UserUnassignedFromGroup struct { + HostEvent + + UserLogin string `xml:"userLogin"` + Group string `xml:"group"` +} + +func init() { + t["UserUnassignedFromGroup"] = reflect.TypeOf((*UserUnassignedFromGroup)(nil)).Elem() +} + +type UserUpgradeEvent struct { + UpgradeEvent +} + +func init() { + t["UserUpgradeEvent"] = reflect.TypeOf((*UserUpgradeEvent)(nil)).Elem() +} + +type VASAStorageArray struct { + DynamicData + + Name string `xml:"name"` + Uuid string `xml:"uuid"` + VendorId string `xml:"vendorId"` + ModelId string `xml:"modelId"` +} + +func init() { + t["VASAStorageArray"] = reflect.TypeOf((*VASAStorageArray)(nil)).Elem() +} + +type VAppCloneSpec struct { + DynamicData + + Location ManagedObjectReference `xml:"location"` + Host *ManagedObjectReference `xml:"host,omitempty"` + ResourceSpec *ResourceConfigSpec `xml:"resourceSpec,omitempty"` + VmFolder *ManagedObjectReference `xml:"vmFolder,omitempty"` + NetworkMapping []VAppCloneSpecNetworkMappingPair `xml:"networkMapping,omitempty"` + Property []KeyValue `xml:"property,omitempty"` + ResourceMapping []VAppCloneSpecResourceMap `xml:"resourceMapping,omitempty"` + Provisioning string `xml:"provisioning,omitempty"` +} + +func init() { + t["VAppCloneSpec"] = reflect.TypeOf((*VAppCloneSpec)(nil)).Elem() +} + +type VAppCloneSpecNetworkMappingPair struct { + DynamicData + + Source ManagedObjectReference `xml:"source"` + Destination ManagedObjectReference `xml:"destination"` +} + +func init() { + t["VAppCloneSpecNetworkMappingPair"] = reflect.TypeOf((*VAppCloneSpecNetworkMappingPair)(nil)).Elem() +} + +type VAppCloneSpecResourceMap struct { + DynamicData + + Source ManagedObjectReference `xml:"source"` + Parent *ManagedObjectReference `xml:"parent,omitempty"` + ResourceSpec *ResourceConfigSpec `xml:"resourceSpec,omitempty"` + Location *ManagedObjectReference `xml:"location,omitempty"` +} + +func init() { + t["VAppCloneSpecResourceMap"] = reflect.TypeOf((*VAppCloneSpecResourceMap)(nil)).Elem() +} + +type VAppConfigFault struct { + VimFault +} + +func init() { + t["VAppConfigFault"] = reflect.TypeOf((*VAppConfigFault)(nil)).Elem() +} + +type VAppConfigFaultFault BaseVAppConfigFault + +func init() { + t["VAppConfigFaultFault"] = reflect.TypeOf((*VAppConfigFaultFault)(nil)).Elem() +} + +type VAppConfigInfo struct { + VmConfigInfo + + EntityConfig []VAppEntityConfigInfo `xml:"entityConfig,omitempty"` + Annotation string `xml:"annotation"` + InstanceUuid string `xml:"instanceUuid,omitempty"` + ManagedBy *ManagedByInfo `xml:"managedBy,omitempty"` +} + +func init() { + t["VAppConfigInfo"] = reflect.TypeOf((*VAppConfigInfo)(nil)).Elem() +} + +type VAppConfigSpec struct { + VmConfigSpec + + EntityConfig []VAppEntityConfigInfo `xml:"entityConfig,omitempty"` + Annotation string `xml:"annotation,omitempty"` + InstanceUuid string `xml:"instanceUuid,omitempty"` + ManagedBy *ManagedByInfo `xml:"managedBy,omitempty"` +} + +func init() { + t["VAppConfigSpec"] = reflect.TypeOf((*VAppConfigSpec)(nil)).Elem() +} + +type VAppEntityConfigInfo struct { + DynamicData + + Key *ManagedObjectReference `xml:"key,omitempty"` + Tag string `xml:"tag,omitempty"` + StartOrder int32 `xml:"startOrder,omitempty"` + StartDelay int32 `xml:"startDelay,omitempty"` + WaitingForGuest *bool `xml:"waitingForGuest"` + StartAction string `xml:"startAction,omitempty"` + StopDelay int32 `xml:"stopDelay,omitempty"` + StopAction string `xml:"stopAction,omitempty"` + DestroyWithParent *bool `xml:"destroyWithParent"` +} + +func init() { + t["VAppEntityConfigInfo"] = reflect.TypeOf((*VAppEntityConfigInfo)(nil)).Elem() +} + +type VAppIPAssignmentInfo struct { + DynamicData + + SupportedAllocationScheme []string `xml:"supportedAllocationScheme,omitempty"` + IpAllocationPolicy string `xml:"ipAllocationPolicy,omitempty"` + SupportedIpProtocol []string `xml:"supportedIpProtocol,omitempty"` + IpProtocol string `xml:"ipProtocol,omitempty"` +} + +func init() { + t["VAppIPAssignmentInfo"] = reflect.TypeOf((*VAppIPAssignmentInfo)(nil)).Elem() +} + +type VAppNotRunning struct { + VmConfigFault +} + +func init() { + t["VAppNotRunning"] = reflect.TypeOf((*VAppNotRunning)(nil)).Elem() +} + +type VAppNotRunningFault VAppNotRunning + +func init() { + t["VAppNotRunningFault"] = reflect.TypeOf((*VAppNotRunningFault)(nil)).Elem() +} + +type VAppOperationInProgress struct { + RuntimeFault +} + +func init() { + t["VAppOperationInProgress"] = reflect.TypeOf((*VAppOperationInProgress)(nil)).Elem() +} + +type VAppOperationInProgressFault VAppOperationInProgress + +func init() { + t["VAppOperationInProgressFault"] = reflect.TypeOf((*VAppOperationInProgressFault)(nil)).Elem() +} + +type VAppOvfSectionInfo struct { + DynamicData + + Key int32 `xml:"key,omitempty"` + Namespace string `xml:"namespace,omitempty"` + Type string `xml:"type,omitempty"` + AtEnvelopeLevel *bool `xml:"atEnvelopeLevel"` + Contents string `xml:"contents,omitempty"` +} + +func init() { + t["VAppOvfSectionInfo"] = reflect.TypeOf((*VAppOvfSectionInfo)(nil)).Elem() +} + +type VAppOvfSectionSpec struct { + ArrayUpdateSpec + + Info *VAppOvfSectionInfo `xml:"info,omitempty"` +} + +func init() { + t["VAppOvfSectionSpec"] = reflect.TypeOf((*VAppOvfSectionSpec)(nil)).Elem() +} + +type VAppProductInfo struct { + DynamicData + + Key int32 `xml:"key"` + ClassId string `xml:"classId,omitempty"` + InstanceId string `xml:"instanceId,omitempty"` + Name string `xml:"name,omitempty"` + Vendor string `xml:"vendor,omitempty"` + Version string `xml:"version,omitempty"` + FullVersion string `xml:"fullVersion,omitempty"` + VendorUrl string `xml:"vendorUrl,omitempty"` + ProductUrl string `xml:"productUrl,omitempty"` + AppUrl string `xml:"appUrl,omitempty"` +} + +func init() { + t["VAppProductInfo"] = reflect.TypeOf((*VAppProductInfo)(nil)).Elem() +} + +type VAppProductSpec struct { + ArrayUpdateSpec + + Info *VAppProductInfo `xml:"info,omitempty"` +} + +func init() { + t["VAppProductSpec"] = reflect.TypeOf((*VAppProductSpec)(nil)).Elem() +} + +type VAppPropertyFault struct { + VmConfigFault + + Id string `xml:"id"` + Category string `xml:"category"` + Label string `xml:"label"` + Type string `xml:"type"` + Value string `xml:"value"` +} + +func init() { + t["VAppPropertyFault"] = reflect.TypeOf((*VAppPropertyFault)(nil)).Elem() +} + +type VAppPropertyFaultFault BaseVAppPropertyFault + +func init() { + t["VAppPropertyFaultFault"] = reflect.TypeOf((*VAppPropertyFaultFault)(nil)).Elem() +} + +type VAppPropertyInfo struct { + DynamicData + + Key int32 `xml:"key"` + ClassId string `xml:"classId,omitempty"` + InstanceId string `xml:"instanceId,omitempty"` + Id string `xml:"id,omitempty"` + Category string `xml:"category,omitempty"` + Label string `xml:"label,omitempty"` + Type string `xml:"type,omitempty"` + TypeReference string `xml:"typeReference,omitempty"` + UserConfigurable *bool `xml:"userConfigurable"` + DefaultValue string `xml:"defaultValue,omitempty"` + Value string `xml:"value,omitempty"` + Description string `xml:"description,omitempty"` +} + +func init() { + t["VAppPropertyInfo"] = reflect.TypeOf((*VAppPropertyInfo)(nil)).Elem() +} + +type VAppPropertySpec struct { + ArrayUpdateSpec + + Info *VAppPropertyInfo `xml:"info,omitempty"` +} + +func init() { + t["VAppPropertySpec"] = reflect.TypeOf((*VAppPropertySpec)(nil)).Elem() +} + +type VAppTaskInProgress struct { + TaskInProgress +} + +func init() { + t["VAppTaskInProgress"] = reflect.TypeOf((*VAppTaskInProgress)(nil)).Elem() +} + +type VAppTaskInProgressFault VAppTaskInProgress + +func init() { + t["VAppTaskInProgressFault"] = reflect.TypeOf((*VAppTaskInProgressFault)(nil)).Elem() +} + +type VFlashCacheHotConfigNotSupported struct { + VmConfigFault +} + +func init() { + t["VFlashCacheHotConfigNotSupported"] = reflect.TypeOf((*VFlashCacheHotConfigNotSupported)(nil)).Elem() +} + +type VFlashCacheHotConfigNotSupportedFault VFlashCacheHotConfigNotSupported + +func init() { + t["VFlashCacheHotConfigNotSupportedFault"] = reflect.TypeOf((*VFlashCacheHotConfigNotSupportedFault)(nil)).Elem() +} + +type VFlashModuleNotSupported struct { + VmConfigFault + + VmName string `xml:"vmName"` + ModuleName string `xml:"moduleName"` + Reason string `xml:"reason"` + HostName string `xml:"hostName"` +} + +func init() { + t["VFlashModuleNotSupported"] = reflect.TypeOf((*VFlashModuleNotSupported)(nil)).Elem() +} + +type VFlashModuleNotSupportedFault VFlashModuleNotSupported + +func init() { + t["VFlashModuleNotSupportedFault"] = reflect.TypeOf((*VFlashModuleNotSupportedFault)(nil)).Elem() +} + +type VFlashModuleVersionIncompatible struct { + VimFault + + ModuleName string `xml:"moduleName"` + VmRequestModuleVersion string `xml:"vmRequestModuleVersion"` + HostMinSupportedVerson string `xml:"hostMinSupportedVerson"` + HostModuleVersion string `xml:"hostModuleVersion"` +} + +func init() { + t["VFlashModuleVersionIncompatible"] = reflect.TypeOf((*VFlashModuleVersionIncompatible)(nil)).Elem() +} + +type VFlashModuleVersionIncompatibleFault VFlashModuleVersionIncompatible + +func init() { + t["VFlashModuleVersionIncompatibleFault"] = reflect.TypeOf((*VFlashModuleVersionIncompatibleFault)(nil)).Elem() +} + +type VMFSDatastoreCreatedEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["VMFSDatastoreCreatedEvent"] = reflect.TypeOf((*VMFSDatastoreCreatedEvent)(nil)).Elem() +} + +type VMFSDatastoreExpandedEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["VMFSDatastoreExpandedEvent"] = reflect.TypeOf((*VMFSDatastoreExpandedEvent)(nil)).Elem() +} + +type VMFSDatastoreExtendedEvent struct { + HostEvent + + Datastore DatastoreEventArgument `xml:"datastore"` +} + +func init() { + t["VMFSDatastoreExtendedEvent"] = reflect.TypeOf((*VMFSDatastoreExtendedEvent)(nil)).Elem() +} + +type VMINotSupported struct { + DeviceNotSupported +} + +func init() { + t["VMINotSupported"] = reflect.TypeOf((*VMINotSupported)(nil)).Elem() +} + +type VMINotSupportedFault VMINotSupported + +func init() { + t["VMINotSupportedFault"] = reflect.TypeOf((*VMINotSupportedFault)(nil)).Elem() +} + +type VMOnConflictDVPort struct { + CannotAccessNetwork +} + +func init() { + t["VMOnConflictDVPort"] = reflect.TypeOf((*VMOnConflictDVPort)(nil)).Elem() +} + +type VMOnConflictDVPortFault VMOnConflictDVPort + +func init() { + t["VMOnConflictDVPortFault"] = reflect.TypeOf((*VMOnConflictDVPortFault)(nil)).Elem() +} + +type VMOnVirtualIntranet struct { + CannotAccessNetwork +} + +func init() { + t["VMOnVirtualIntranet"] = reflect.TypeOf((*VMOnVirtualIntranet)(nil)).Elem() +} + +type VMOnVirtualIntranetFault VMOnVirtualIntranet + +func init() { + t["VMOnVirtualIntranetFault"] = reflect.TypeOf((*VMOnVirtualIntranetFault)(nil)).Elem() +} + +type VMotionAcrossNetworkNotSupported struct { + MigrationFeatureNotSupported +} + +func init() { + t["VMotionAcrossNetworkNotSupported"] = reflect.TypeOf((*VMotionAcrossNetworkNotSupported)(nil)).Elem() +} + +type VMotionAcrossNetworkNotSupportedFault VMotionAcrossNetworkNotSupported + +func init() { + t["VMotionAcrossNetworkNotSupportedFault"] = reflect.TypeOf((*VMotionAcrossNetworkNotSupportedFault)(nil)).Elem() +} + +type VMotionInterfaceIssue struct { + MigrationFault + + AtSourceHost bool `xml:"atSourceHost"` + FailedHost string `xml:"failedHost"` + FailedHostEntity *ManagedObjectReference `xml:"failedHostEntity,omitempty"` +} + +func init() { + t["VMotionInterfaceIssue"] = reflect.TypeOf((*VMotionInterfaceIssue)(nil)).Elem() +} + +type VMotionInterfaceIssueFault BaseVMotionInterfaceIssue + +func init() { + t["VMotionInterfaceIssueFault"] = reflect.TypeOf((*VMotionInterfaceIssueFault)(nil)).Elem() +} + +type VMotionLicenseExpiredEvent struct { + LicenseEvent +} + +func init() { + t["VMotionLicenseExpiredEvent"] = reflect.TypeOf((*VMotionLicenseExpiredEvent)(nil)).Elem() +} + +type VMotionLinkCapacityLow struct { + VMotionInterfaceIssue + + Network string `xml:"network"` +} + +func init() { + t["VMotionLinkCapacityLow"] = reflect.TypeOf((*VMotionLinkCapacityLow)(nil)).Elem() +} + +type VMotionLinkCapacityLowFault VMotionLinkCapacityLow + +func init() { + t["VMotionLinkCapacityLowFault"] = reflect.TypeOf((*VMotionLinkCapacityLowFault)(nil)).Elem() +} + +type VMotionLinkDown struct { + VMotionInterfaceIssue + + Network string `xml:"network"` +} + +func init() { + t["VMotionLinkDown"] = reflect.TypeOf((*VMotionLinkDown)(nil)).Elem() +} + +type VMotionLinkDownFault VMotionLinkDown + +func init() { + t["VMotionLinkDownFault"] = reflect.TypeOf((*VMotionLinkDownFault)(nil)).Elem() +} + +type VMotionNotConfigured struct { + VMotionInterfaceIssue +} + +func init() { + t["VMotionNotConfigured"] = reflect.TypeOf((*VMotionNotConfigured)(nil)).Elem() +} + +type VMotionNotConfiguredFault VMotionNotConfigured + +func init() { + t["VMotionNotConfiguredFault"] = reflect.TypeOf((*VMotionNotConfiguredFault)(nil)).Elem() +} + +type VMotionNotLicensed struct { + VMotionInterfaceIssue +} + +func init() { + t["VMotionNotLicensed"] = reflect.TypeOf((*VMotionNotLicensed)(nil)).Elem() +} + +type VMotionNotLicensedFault VMotionNotLicensed + +func init() { + t["VMotionNotLicensedFault"] = reflect.TypeOf((*VMotionNotLicensedFault)(nil)).Elem() +} + +type VMotionNotSupported struct { + VMotionInterfaceIssue +} + +func init() { + t["VMotionNotSupported"] = reflect.TypeOf((*VMotionNotSupported)(nil)).Elem() +} + +type VMotionNotSupportedFault VMotionNotSupported + +func init() { + t["VMotionNotSupportedFault"] = reflect.TypeOf((*VMotionNotSupportedFault)(nil)).Elem() +} + +type VMotionProtocolIncompatible struct { + MigrationFault +} + +func init() { + t["VMotionProtocolIncompatible"] = reflect.TypeOf((*VMotionProtocolIncompatible)(nil)).Elem() +} + +type VMotionProtocolIncompatibleFault VMotionProtocolIncompatible + +func init() { + t["VMotionProtocolIncompatibleFault"] = reflect.TypeOf((*VMotionProtocolIncompatibleFault)(nil)).Elem() +} + +type VMwareDVSConfigInfo struct { + DVSConfigInfo + + VspanSession []VMwareVspanSession `xml:"vspanSession,omitempty"` + PvlanConfig []VMwareDVSPvlanMapEntry `xml:"pvlanConfig,omitempty"` + MaxMtu int32 `xml:"maxMtu"` + LinkDiscoveryProtocolConfig *LinkDiscoveryProtocolConfig `xml:"linkDiscoveryProtocolConfig,omitempty"` + IpfixConfig *VMwareIpfixConfig `xml:"ipfixConfig,omitempty"` + LacpGroupConfig []VMwareDvsLacpGroupConfig `xml:"lacpGroupConfig,omitempty"` + LacpApiVersion string `xml:"lacpApiVersion,omitempty"` + MulticastFilteringMode string `xml:"multicastFilteringMode,omitempty"` +} + +func init() { + t["VMwareDVSConfigInfo"] = reflect.TypeOf((*VMwareDVSConfigInfo)(nil)).Elem() +} + +type VMwareDVSConfigSpec struct { + DVSConfigSpec + + PvlanConfigSpec []VMwareDVSPvlanConfigSpec `xml:"pvlanConfigSpec,omitempty"` + VspanConfigSpec []VMwareDVSVspanConfigSpec `xml:"vspanConfigSpec,omitempty"` + MaxMtu int32 `xml:"maxMtu,omitempty"` + LinkDiscoveryProtocolConfig *LinkDiscoveryProtocolConfig `xml:"linkDiscoveryProtocolConfig,omitempty"` + IpfixConfig *VMwareIpfixConfig `xml:"ipfixConfig,omitempty"` + LacpApiVersion string `xml:"lacpApiVersion,omitempty"` + MulticastFilteringMode string `xml:"multicastFilteringMode,omitempty"` +} + +func init() { + t["VMwareDVSConfigSpec"] = reflect.TypeOf((*VMwareDVSConfigSpec)(nil)).Elem() +} + +type VMwareDVSFeatureCapability struct { + DVSFeatureCapability + + VspanSupported *bool `xml:"vspanSupported"` + LldpSupported *bool `xml:"lldpSupported"` + IpfixSupported *bool `xml:"ipfixSupported"` + IpfixCapability *VMwareDvsIpfixCapability `xml:"ipfixCapability,omitempty"` + MulticastSnoopingSupported *bool `xml:"multicastSnoopingSupported"` + VspanCapability *VMwareDVSVspanCapability `xml:"vspanCapability,omitempty"` + LacpCapability *VMwareDvsLacpCapability `xml:"lacpCapability,omitempty"` +} + +func init() { + t["VMwareDVSFeatureCapability"] = reflect.TypeOf((*VMwareDVSFeatureCapability)(nil)).Elem() +} + +type VMwareDVSHealthCheckCapability struct { + DVSHealthCheckCapability + + VlanMtuSupported bool `xml:"vlanMtuSupported"` + TeamingSupported bool `xml:"teamingSupported"` +} + +func init() { + t["VMwareDVSHealthCheckCapability"] = reflect.TypeOf((*VMwareDVSHealthCheckCapability)(nil)).Elem() +} + +type VMwareDVSHealthCheckConfig struct { + DVSHealthCheckConfig +} + +func init() { + t["VMwareDVSHealthCheckConfig"] = reflect.TypeOf((*VMwareDVSHealthCheckConfig)(nil)).Elem() +} + +type VMwareDVSMtuHealthCheckResult struct { + HostMemberUplinkHealthCheckResult + + MtuMismatch bool `xml:"mtuMismatch"` + VlanSupportSwitchMtu []NumericRange `xml:"vlanSupportSwitchMtu,omitempty"` + VlanNotSupportSwitchMtu []NumericRange `xml:"vlanNotSupportSwitchMtu,omitempty"` +} + +func init() { + t["VMwareDVSMtuHealthCheckResult"] = reflect.TypeOf((*VMwareDVSMtuHealthCheckResult)(nil)).Elem() +} + +type VMwareDVSPortSetting struct { + DVPortSetting + + Vlan BaseVmwareDistributedVirtualSwitchVlanSpec `xml:"vlan,omitempty,typeattr"` + QosTag *IntPolicy `xml:"qosTag,omitempty"` + UplinkTeamingPolicy *VmwareUplinkPortTeamingPolicy `xml:"uplinkTeamingPolicy,omitempty"` + SecurityPolicy *DVSSecurityPolicy `xml:"securityPolicy,omitempty"` + IpfixEnabled *BoolPolicy `xml:"ipfixEnabled,omitempty"` + TxUplink *BoolPolicy `xml:"txUplink,omitempty"` + LacpPolicy *VMwareUplinkLacpPolicy `xml:"lacpPolicy,omitempty"` +} + +func init() { + t["VMwareDVSPortSetting"] = reflect.TypeOf((*VMwareDVSPortSetting)(nil)).Elem() +} + +type VMwareDVSPortgroupPolicy struct { + DVPortgroupPolicy + + VlanOverrideAllowed bool `xml:"vlanOverrideAllowed"` + UplinkTeamingOverrideAllowed bool `xml:"uplinkTeamingOverrideAllowed"` + SecurityPolicyOverrideAllowed bool `xml:"securityPolicyOverrideAllowed"` + IpfixOverrideAllowed *bool `xml:"ipfixOverrideAllowed"` +} + +func init() { + t["VMwareDVSPortgroupPolicy"] = reflect.TypeOf((*VMwareDVSPortgroupPolicy)(nil)).Elem() +} + +type VMwareDVSPvlanConfigSpec struct { + DynamicData + + PvlanEntry VMwareDVSPvlanMapEntry `xml:"pvlanEntry"` + Operation string `xml:"operation"` +} + +func init() { + t["VMwareDVSPvlanConfigSpec"] = reflect.TypeOf((*VMwareDVSPvlanConfigSpec)(nil)).Elem() +} + +type VMwareDVSPvlanMapEntry struct { + DynamicData + + PrimaryVlanId int32 `xml:"primaryVlanId"` + SecondaryVlanId int32 `xml:"secondaryVlanId"` + PvlanType string `xml:"pvlanType"` +} + +func init() { + t["VMwareDVSPvlanMapEntry"] = reflect.TypeOf((*VMwareDVSPvlanMapEntry)(nil)).Elem() +} + +type VMwareDVSTeamingHealthCheckConfig struct { + VMwareDVSHealthCheckConfig +} + +func init() { + t["VMwareDVSTeamingHealthCheckConfig"] = reflect.TypeOf((*VMwareDVSTeamingHealthCheckConfig)(nil)).Elem() +} + +type VMwareDVSTeamingHealthCheckResult struct { + HostMemberHealthCheckResult + + TeamingStatus string `xml:"teamingStatus"` +} + +func init() { + t["VMwareDVSTeamingHealthCheckResult"] = reflect.TypeOf((*VMwareDVSTeamingHealthCheckResult)(nil)).Elem() +} + +type VMwareDVSVlanHealthCheckResult struct { + HostMemberUplinkHealthCheckResult + + TrunkedVlan []NumericRange `xml:"trunkedVlan,omitempty"` + UntrunkedVlan []NumericRange `xml:"untrunkedVlan,omitempty"` +} + +func init() { + t["VMwareDVSVlanHealthCheckResult"] = reflect.TypeOf((*VMwareDVSVlanHealthCheckResult)(nil)).Elem() +} + +type VMwareDVSVlanMtuHealthCheckConfig struct { + VMwareDVSHealthCheckConfig +} + +func init() { + t["VMwareDVSVlanMtuHealthCheckConfig"] = reflect.TypeOf((*VMwareDVSVlanMtuHealthCheckConfig)(nil)).Elem() +} + +type VMwareDVSVspanCapability struct { + DynamicData + + MixedDestSupported bool `xml:"mixedDestSupported"` + DvportSupported bool `xml:"dvportSupported"` + RemoteSourceSupported bool `xml:"remoteSourceSupported"` + RemoteDestSupported bool `xml:"remoteDestSupported"` + EncapRemoteSourceSupported bool `xml:"encapRemoteSourceSupported"` +} + +func init() { + t["VMwareDVSVspanCapability"] = reflect.TypeOf((*VMwareDVSVspanCapability)(nil)).Elem() +} + +type VMwareDVSVspanConfigSpec struct { + DynamicData + + VspanSession VMwareVspanSession `xml:"vspanSession"` + Operation string `xml:"operation"` +} + +func init() { + t["VMwareDVSVspanConfigSpec"] = reflect.TypeOf((*VMwareDVSVspanConfigSpec)(nil)).Elem() +} + +type VMwareDvsIpfixCapability struct { + DynamicData + + IpfixSupported *bool `xml:"ipfixSupported"` + Ipv6ForIpfixSupported *bool `xml:"ipv6ForIpfixSupported"` + ObservationDomainIdSupported *bool `xml:"observationDomainIdSupported"` +} + +func init() { + t["VMwareDvsIpfixCapability"] = reflect.TypeOf((*VMwareDvsIpfixCapability)(nil)).Elem() +} + +type VMwareDvsLacpCapability struct { + DynamicData + + LacpSupported *bool `xml:"lacpSupported"` + MultiLacpGroupSupported *bool `xml:"multiLacpGroupSupported"` +} + +func init() { + t["VMwareDvsLacpCapability"] = reflect.TypeOf((*VMwareDvsLacpCapability)(nil)).Elem() +} + +type VMwareDvsLacpGroupConfig struct { + DynamicData + + Key string `xml:"key,omitempty"` + Name string `xml:"name,omitempty"` + Mode string `xml:"mode,omitempty"` + UplinkNum int32 `xml:"uplinkNum,omitempty"` + LoadbalanceAlgorithm string `xml:"loadbalanceAlgorithm,omitempty"` + Vlan *VMwareDvsLagVlanConfig `xml:"vlan,omitempty"` + Ipfix *VMwareDvsLagIpfixConfig `xml:"ipfix,omitempty"` + UplinkName []string `xml:"uplinkName,omitempty"` + UplinkPortKey []string `xml:"uplinkPortKey,omitempty"` +} + +func init() { + t["VMwareDvsLacpGroupConfig"] = reflect.TypeOf((*VMwareDvsLacpGroupConfig)(nil)).Elem() +} + +type VMwareDvsLacpGroupSpec struct { + DynamicData + + LacpGroupConfig VMwareDvsLacpGroupConfig `xml:"lacpGroupConfig"` + Operation string `xml:"operation"` +} + +func init() { + t["VMwareDvsLacpGroupSpec"] = reflect.TypeOf((*VMwareDvsLacpGroupSpec)(nil)).Elem() +} + +type VMwareDvsLagIpfixConfig struct { + DynamicData + + IpfixEnabled *bool `xml:"ipfixEnabled"` +} + +func init() { + t["VMwareDvsLagIpfixConfig"] = reflect.TypeOf((*VMwareDvsLagIpfixConfig)(nil)).Elem() +} + +type VMwareDvsLagVlanConfig struct { + DynamicData + + VlanId []NumericRange `xml:"vlanId,omitempty"` +} + +func init() { + t["VMwareDvsLagVlanConfig"] = reflect.TypeOf((*VMwareDvsLagVlanConfig)(nil)).Elem() +} + +type VMwareIpfixConfig struct { + DynamicData + + CollectorIpAddress string `xml:"collectorIpAddress,omitempty"` + CollectorPort int32 `xml:"collectorPort,omitempty"` + ObservationDomainId int64 `xml:"observationDomainId,omitempty"` + ActiveFlowTimeout int32 `xml:"activeFlowTimeout"` + IdleFlowTimeout int32 `xml:"idleFlowTimeout"` + SamplingRate int32 `xml:"samplingRate"` + InternalFlowsOnly bool `xml:"internalFlowsOnly"` +} + +func init() { + t["VMwareIpfixConfig"] = reflect.TypeOf((*VMwareIpfixConfig)(nil)).Elem() +} + +type VMwareUplinkLacpPolicy struct { + InheritablePolicy + + Enable *BoolPolicy `xml:"enable,omitempty"` + Mode *StringPolicy `xml:"mode,omitempty"` +} + +func init() { + t["VMwareUplinkLacpPolicy"] = reflect.TypeOf((*VMwareUplinkLacpPolicy)(nil)).Elem() +} + +type VMwareUplinkPortOrderPolicy struct { + InheritablePolicy + + ActiveUplinkPort []string `xml:"activeUplinkPort,omitempty"` + StandbyUplinkPort []string `xml:"standbyUplinkPort,omitempty"` +} + +func init() { + t["VMwareUplinkPortOrderPolicy"] = reflect.TypeOf((*VMwareUplinkPortOrderPolicy)(nil)).Elem() +} + +type VMwareVspanPort struct { + DynamicData + + PortKey []string `xml:"portKey,omitempty"` + UplinkPortName []string `xml:"uplinkPortName,omitempty"` + WildcardPortConnecteeType []string `xml:"wildcardPortConnecteeType,omitempty"` + Vlans []int32 `xml:"vlans,omitempty"` + IpAddress []string `xml:"ipAddress,omitempty"` +} + +func init() { + t["VMwareVspanPort"] = reflect.TypeOf((*VMwareVspanPort)(nil)).Elem() +} + +type VMwareVspanSession struct { + DynamicData + + Key string `xml:"key,omitempty"` + Name string `xml:"name,omitempty"` + Description string `xml:"description,omitempty"` + Enabled bool `xml:"enabled"` + SourcePortTransmitted *VMwareVspanPort `xml:"sourcePortTransmitted,omitempty"` + SourcePortReceived *VMwareVspanPort `xml:"sourcePortReceived,omitempty"` + DestinationPort *VMwareVspanPort `xml:"destinationPort,omitempty"` + EncapsulationVlanId int32 `xml:"encapsulationVlanId,omitempty"` + StripOriginalVlan bool `xml:"stripOriginalVlan"` + MirroredPacketLength int32 `xml:"mirroredPacketLength,omitempty"` + NormalTrafficAllowed bool `xml:"normalTrafficAllowed"` + SessionType string `xml:"sessionType,omitempty"` + SamplingRate int32 `xml:"samplingRate,omitempty"` +} + +func init() { + t["VMwareVspanSession"] = reflect.TypeOf((*VMwareVspanSession)(nil)).Elem() +} + +type VRPEditSpec struct { + DynamicData + + VrpId string `xml:"vrpId"` + Description string `xml:"description,omitempty"` + CpuAllocation *VrpResourceAllocationInfo `xml:"cpuAllocation,omitempty"` + MemoryAllocation *VrpResourceAllocationInfo `xml:"memoryAllocation,omitempty"` + AddedHubs []ManagedObjectReference `xml:"addedHubs,omitempty"` + RemovedHubs []ManagedObjectReference `xml:"removedHubs,omitempty"` + ChangeVersion int64 `xml:"changeVersion,omitempty"` +} + +func init() { + t["VRPEditSpec"] = reflect.TypeOf((*VRPEditSpec)(nil)).Elem() +} + +type VVolHostPE struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + ProtocolEndpoint []HostProtocolEndpoint `xml:"protocolEndpoint"` +} + +func init() { + t["VVolHostPE"] = reflect.TypeOf((*VVolHostPE)(nil)).Elem() +} + +type ValidateCredentialsInGuest ValidateCredentialsInGuestRequestType + +func init() { + t["ValidateCredentialsInGuest"] = reflect.TypeOf((*ValidateCredentialsInGuest)(nil)).Elem() +} + +type ValidateCredentialsInGuestRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm ManagedObjectReference `xml:"vm"` + Auth BaseGuestAuthentication `xml:"auth,typeattr"` +} + +func init() { + t["ValidateCredentialsInGuestRequestType"] = reflect.TypeOf((*ValidateCredentialsInGuestRequestType)(nil)).Elem() +} + +type ValidateCredentialsInGuestResponse struct { +} + +type ValidateHost ValidateHostRequestType + +func init() { + t["ValidateHost"] = reflect.TypeOf((*ValidateHost)(nil)).Elem() +} + +type ValidateHostRequestType struct { + This ManagedObjectReference `xml:"_this"` + OvfDescriptor string `xml:"ovfDescriptor"` + Host ManagedObjectReference `xml:"host"` + Vhp OvfValidateHostParams `xml:"vhp"` +} + +func init() { + t["ValidateHostRequestType"] = reflect.TypeOf((*ValidateHostRequestType)(nil)).Elem() +} + +type ValidateHostResponse struct { + Returnval OvfValidateHostResult `xml:"returnval"` +} + +type ValidateMigration ValidateMigrationRequestType + +func init() { + t["ValidateMigration"] = reflect.TypeOf((*ValidateMigration)(nil)).Elem() +} + +type ValidateMigrationRequestType struct { + This ManagedObjectReference `xml:"_this"` + Vm []ManagedObjectReference `xml:"vm"` + State VirtualMachinePowerState `xml:"state,omitempty"` + TestType []string `xml:"testType,omitempty"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` +} + +func init() { + t["ValidateMigrationRequestType"] = reflect.TypeOf((*ValidateMigrationRequestType)(nil)).Elem() +} + +type ValidateMigrationResponse struct { + Returnval []BaseEvent `xml:"returnval,omitempty,typeattr"` +} + +type VasaProviderContainerSpec struct { + DynamicData + + VasaProviderInfo []VimVasaProviderInfo `xml:"vasaProviderInfo,omitempty"` + ScId string `xml:"scId"` + Deleted bool `xml:"deleted"` +} + +func init() { + t["VasaProviderContainerSpec"] = reflect.TypeOf((*VasaProviderContainerSpec)(nil)).Elem() +} + +type VcAgentUninstallFailedEvent struct { + HostEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["VcAgentUninstallFailedEvent"] = reflect.TypeOf((*VcAgentUninstallFailedEvent)(nil)).Elem() +} + +type VcAgentUninstalledEvent struct { + HostEvent +} + +func init() { + t["VcAgentUninstalledEvent"] = reflect.TypeOf((*VcAgentUninstalledEvent)(nil)).Elem() +} + +type VcAgentUpgradeFailedEvent struct { + HostEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["VcAgentUpgradeFailedEvent"] = reflect.TypeOf((*VcAgentUpgradeFailedEvent)(nil)).Elem() +} + +type VcAgentUpgradedEvent struct { + HostEvent +} + +func init() { + t["VcAgentUpgradedEvent"] = reflect.TypeOf((*VcAgentUpgradedEvent)(nil)).Elem() +} + +type VimAccountPasswordChangedEvent struct { + HostEvent +} + +func init() { + t["VimAccountPasswordChangedEvent"] = reflect.TypeOf((*VimAccountPasswordChangedEvent)(nil)).Elem() +} + +type VimFault struct { + MethodFault +} + +func init() { + t["VimFault"] = reflect.TypeOf((*VimFault)(nil)).Elem() +} + +type VimFaultFault BaseVimFault + +func init() { + t["VimFaultFault"] = reflect.TypeOf((*VimFaultFault)(nil)).Elem() +} + +type VimVasaProvider struct { + DynamicData + + Url string `xml:"url"` + Name string `xml:"name,omitempty"` + SelfSignedCertificate string `xml:"selfSignedCertificate,omitempty"` +} + +func init() { + t["VimVasaProvider"] = reflect.TypeOf((*VimVasaProvider)(nil)).Elem() +} + +type VimVasaProviderInfo struct { + DynamicData + + Provider VimVasaProvider `xml:"provider"` + ArrayState []VimVasaProviderStatePerArray `xml:"arrayState,omitempty"` +} + +func init() { + t["VimVasaProviderInfo"] = reflect.TypeOf((*VimVasaProviderInfo)(nil)).Elem() +} + +type VimVasaProviderStatePerArray struct { + DynamicData + + Priority int32 `xml:"priority"` + ArrayId string `xml:"arrayId"` + Active bool `xml:"active"` +} + +func init() { + t["VimVasaProviderStatePerArray"] = reflect.TypeOf((*VimVasaProviderStatePerArray)(nil)).Elem() +} + +type VirtualAHCIController struct { + VirtualSATAController +} + +func init() { + t["VirtualAHCIController"] = reflect.TypeOf((*VirtualAHCIController)(nil)).Elem() +} + +type VirtualAHCIControllerOption struct { + VirtualSATAControllerOption +} + +func init() { + t["VirtualAHCIControllerOption"] = reflect.TypeOf((*VirtualAHCIControllerOption)(nil)).Elem() +} + +type VirtualAppImportSpec struct { + ImportSpec + + Name string `xml:"name"` + VAppConfigSpec VAppConfigSpec `xml:"vAppConfigSpec"` + ResourcePoolSpec ResourceConfigSpec `xml:"resourcePoolSpec"` + Child []BaseImportSpec `xml:"child,omitempty,typeattr"` +} + +func init() { + t["VirtualAppImportSpec"] = reflect.TypeOf((*VirtualAppImportSpec)(nil)).Elem() +} + +type VirtualAppLinkInfo struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + DestroyWithParent *bool `xml:"destroyWithParent"` +} + +func init() { + t["VirtualAppLinkInfo"] = reflect.TypeOf((*VirtualAppLinkInfo)(nil)).Elem() +} + +type VirtualAppSummary struct { + ResourcePoolSummary + + Product *VAppProductInfo `xml:"product,omitempty"` + VAppState VirtualAppVAppState `xml:"vAppState,omitempty"` + Suspended *bool `xml:"suspended"` + InstallBootRequired *bool `xml:"installBootRequired"` + InstanceUuid string `xml:"instanceUuid,omitempty"` +} + +func init() { + t["VirtualAppSummary"] = reflect.TypeOf((*VirtualAppSummary)(nil)).Elem() +} + +type VirtualBusLogicController struct { + VirtualSCSIController +} + +func init() { + t["VirtualBusLogicController"] = reflect.TypeOf((*VirtualBusLogicController)(nil)).Elem() +} + +type VirtualBusLogicControllerOption struct { + VirtualSCSIControllerOption +} + +func init() { + t["VirtualBusLogicControllerOption"] = reflect.TypeOf((*VirtualBusLogicControllerOption)(nil)).Elem() +} + +type VirtualCdrom struct { + VirtualDevice +} + +func init() { + t["VirtualCdrom"] = reflect.TypeOf((*VirtualCdrom)(nil)).Elem() +} + +type VirtualCdromAtapiBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualCdromAtapiBackingInfo"] = reflect.TypeOf((*VirtualCdromAtapiBackingInfo)(nil)).Elem() +} + +type VirtualCdromAtapiBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualCdromAtapiBackingOption"] = reflect.TypeOf((*VirtualCdromAtapiBackingOption)(nil)).Elem() +} + +type VirtualCdromIsoBackingInfo struct { + VirtualDeviceFileBackingInfo +} + +func init() { + t["VirtualCdromIsoBackingInfo"] = reflect.TypeOf((*VirtualCdromIsoBackingInfo)(nil)).Elem() +} + +type VirtualCdromIsoBackingOption struct { + VirtualDeviceFileBackingOption +} + +func init() { + t["VirtualCdromIsoBackingOption"] = reflect.TypeOf((*VirtualCdromIsoBackingOption)(nil)).Elem() +} + +type VirtualCdromOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualCdromOption"] = reflect.TypeOf((*VirtualCdromOption)(nil)).Elem() +} + +type VirtualCdromPassthroughBackingInfo struct { + VirtualDeviceDeviceBackingInfo + + Exclusive bool `xml:"exclusive"` +} + +func init() { + t["VirtualCdromPassthroughBackingInfo"] = reflect.TypeOf((*VirtualCdromPassthroughBackingInfo)(nil)).Elem() +} + +type VirtualCdromPassthroughBackingOption struct { + VirtualDeviceDeviceBackingOption + + Exclusive BoolOption `xml:"exclusive"` +} + +func init() { + t["VirtualCdromPassthroughBackingOption"] = reflect.TypeOf((*VirtualCdromPassthroughBackingOption)(nil)).Elem() +} + +type VirtualCdromRemoteAtapiBackingInfo struct { + VirtualDeviceRemoteDeviceBackingInfo +} + +func init() { + t["VirtualCdromRemoteAtapiBackingInfo"] = reflect.TypeOf((*VirtualCdromRemoteAtapiBackingInfo)(nil)).Elem() +} + +type VirtualCdromRemoteAtapiBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualCdromRemoteAtapiBackingOption"] = reflect.TypeOf((*VirtualCdromRemoteAtapiBackingOption)(nil)).Elem() +} + +type VirtualCdromRemotePassthroughBackingInfo struct { + VirtualDeviceRemoteDeviceBackingInfo + + Exclusive bool `xml:"exclusive"` +} + +func init() { + t["VirtualCdromRemotePassthroughBackingInfo"] = reflect.TypeOf((*VirtualCdromRemotePassthroughBackingInfo)(nil)).Elem() +} + +type VirtualCdromRemotePassthroughBackingOption struct { + VirtualDeviceRemoteDeviceBackingOption + + Exclusive BoolOption `xml:"exclusive"` +} + +func init() { + t["VirtualCdromRemotePassthroughBackingOption"] = reflect.TypeOf((*VirtualCdromRemotePassthroughBackingOption)(nil)).Elem() +} + +type VirtualController struct { + VirtualDevice + + BusNumber int32 `xml:"busNumber"` + Device []int32 `xml:"device,omitempty"` +} + +func init() { + t["VirtualController"] = reflect.TypeOf((*VirtualController)(nil)).Elem() +} + +type VirtualControllerOption struct { + VirtualDeviceOption + + Devices IntOption `xml:"devices"` + SupportedDevice []string `xml:"supportedDevice,omitempty"` +} + +func init() { + t["VirtualControllerOption"] = reflect.TypeOf((*VirtualControllerOption)(nil)).Elem() +} + +type VirtualDevice struct { + DynamicData + + Key int32 `xml:"key"` + DeviceInfo BaseDescription `xml:"deviceInfo,omitempty,typeattr"` + Backing BaseVirtualDeviceBackingInfo `xml:"backing,omitempty,typeattr"` + Connectable *VirtualDeviceConnectInfo `xml:"connectable,omitempty"` + SlotInfo BaseVirtualDeviceBusSlotInfo `xml:"slotInfo,omitempty,typeattr"` + ControllerKey int32 `xml:"controllerKey,omitempty"` + UnitNumber *int32 `xml:"unitNumber"` +} + +func init() { + t["VirtualDevice"] = reflect.TypeOf((*VirtualDevice)(nil)).Elem() +} + +type VirtualDeviceBackingInfo struct { + DynamicData +} + +func init() { + t["VirtualDeviceBackingInfo"] = reflect.TypeOf((*VirtualDeviceBackingInfo)(nil)).Elem() +} + +type VirtualDeviceBackingOption struct { + DynamicData + + Type string `xml:"type"` +} + +func init() { + t["VirtualDeviceBackingOption"] = reflect.TypeOf((*VirtualDeviceBackingOption)(nil)).Elem() +} + +type VirtualDeviceBusSlotInfo struct { + DynamicData +} + +func init() { + t["VirtualDeviceBusSlotInfo"] = reflect.TypeOf((*VirtualDeviceBusSlotInfo)(nil)).Elem() +} + +type VirtualDeviceBusSlotOption struct { + DynamicData + + Type string `xml:"type"` +} + +func init() { + t["VirtualDeviceBusSlotOption"] = reflect.TypeOf((*VirtualDeviceBusSlotOption)(nil)).Elem() +} + +type VirtualDeviceConfigSpec struct { + DynamicData + + Operation VirtualDeviceConfigSpecOperation `xml:"operation,omitempty"` + FileOperation VirtualDeviceConfigSpecFileOperation `xml:"fileOperation,omitempty"` + Device BaseVirtualDevice `xml:"device,typeattr"` + Profile []BaseVirtualMachineProfileSpec `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["VirtualDeviceConfigSpec"] = reflect.TypeOf((*VirtualDeviceConfigSpec)(nil)).Elem() +} + +type VirtualDeviceConnectInfo struct { + DynamicData + + StartConnected bool `xml:"startConnected"` + AllowGuestControl bool `xml:"allowGuestControl"` + Connected bool `xml:"connected"` + Status string `xml:"status,omitempty"` +} + +func init() { + t["VirtualDeviceConnectInfo"] = reflect.TypeOf((*VirtualDeviceConnectInfo)(nil)).Elem() +} + +type VirtualDeviceConnectOption struct { + DynamicData + + StartConnected BoolOption `xml:"startConnected"` + AllowGuestControl BoolOption `xml:"allowGuestControl"` +} + +func init() { + t["VirtualDeviceConnectOption"] = reflect.TypeOf((*VirtualDeviceConnectOption)(nil)).Elem() +} + +type VirtualDeviceDeviceBackingInfo struct { + VirtualDeviceBackingInfo + + DeviceName string `xml:"deviceName"` + UseAutoDetect *bool `xml:"useAutoDetect"` +} + +func init() { + t["VirtualDeviceDeviceBackingInfo"] = reflect.TypeOf((*VirtualDeviceDeviceBackingInfo)(nil)).Elem() +} + +type VirtualDeviceDeviceBackingOption struct { + VirtualDeviceBackingOption + + AutoDetectAvailable BoolOption `xml:"autoDetectAvailable"` +} + +func init() { + t["VirtualDeviceDeviceBackingOption"] = reflect.TypeOf((*VirtualDeviceDeviceBackingOption)(nil)).Elem() +} + +type VirtualDeviceFileBackingInfo struct { + VirtualDeviceBackingInfo + + FileName string `xml:"fileName"` + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` + BackingObjectId string `xml:"backingObjectId,omitempty"` +} + +func init() { + t["VirtualDeviceFileBackingInfo"] = reflect.TypeOf((*VirtualDeviceFileBackingInfo)(nil)).Elem() +} + +type VirtualDeviceFileBackingOption struct { + VirtualDeviceBackingOption + + FileNameExtensions *ChoiceOption `xml:"fileNameExtensions,omitempty"` +} + +func init() { + t["VirtualDeviceFileBackingOption"] = reflect.TypeOf((*VirtualDeviceFileBackingOption)(nil)).Elem() +} + +type VirtualDeviceOption struct { + DynamicData + + Type string `xml:"type"` + ConnectOption *VirtualDeviceConnectOption `xml:"connectOption,omitempty"` + BusSlotOption *VirtualDeviceBusSlotOption `xml:"busSlotOption,omitempty"` + ControllerType string `xml:"controllerType,omitempty"` + AutoAssignController *BoolOption `xml:"autoAssignController,omitempty"` + BackingOption []BaseVirtualDeviceBackingOption `xml:"backingOption,omitempty,typeattr"` + DefaultBackingOptionIndex int32 `xml:"defaultBackingOptionIndex,omitempty"` + LicensingLimit []string `xml:"licensingLimit,omitempty"` + Deprecated bool `xml:"deprecated"` + PlugAndPlay bool `xml:"plugAndPlay"` + HotRemoveSupported *bool `xml:"hotRemoveSupported"` +} + +func init() { + t["VirtualDeviceOption"] = reflect.TypeOf((*VirtualDeviceOption)(nil)).Elem() +} + +type VirtualDevicePciBusSlotInfo struct { + VirtualDeviceBusSlotInfo + + PciSlotNumber int32 `xml:"pciSlotNumber"` +} + +func init() { + t["VirtualDevicePciBusSlotInfo"] = reflect.TypeOf((*VirtualDevicePciBusSlotInfo)(nil)).Elem() +} + +type VirtualDevicePipeBackingInfo struct { + VirtualDeviceBackingInfo + + PipeName string `xml:"pipeName"` +} + +func init() { + t["VirtualDevicePipeBackingInfo"] = reflect.TypeOf((*VirtualDevicePipeBackingInfo)(nil)).Elem() +} + +type VirtualDevicePipeBackingOption struct { + VirtualDeviceBackingOption +} + +func init() { + t["VirtualDevicePipeBackingOption"] = reflect.TypeOf((*VirtualDevicePipeBackingOption)(nil)).Elem() +} + +type VirtualDeviceRemoteDeviceBackingInfo struct { + VirtualDeviceBackingInfo + + DeviceName string `xml:"deviceName"` + UseAutoDetect *bool `xml:"useAutoDetect"` +} + +func init() { + t["VirtualDeviceRemoteDeviceBackingInfo"] = reflect.TypeOf((*VirtualDeviceRemoteDeviceBackingInfo)(nil)).Elem() +} + +type VirtualDeviceRemoteDeviceBackingOption struct { + VirtualDeviceBackingOption + + AutoDetectAvailable BoolOption `xml:"autoDetectAvailable"` +} + +func init() { + t["VirtualDeviceRemoteDeviceBackingOption"] = reflect.TypeOf((*VirtualDeviceRemoteDeviceBackingOption)(nil)).Elem() +} + +type VirtualDeviceURIBackingInfo struct { + VirtualDeviceBackingInfo + + ServiceURI string `xml:"serviceURI"` + Direction string `xml:"direction"` + ProxyURI string `xml:"proxyURI,omitempty"` +} + +func init() { + t["VirtualDeviceURIBackingInfo"] = reflect.TypeOf((*VirtualDeviceURIBackingInfo)(nil)).Elem() +} + +type VirtualDeviceURIBackingOption struct { + VirtualDeviceBackingOption + + Directions ChoiceOption `xml:"directions"` +} + +func init() { + t["VirtualDeviceURIBackingOption"] = reflect.TypeOf((*VirtualDeviceURIBackingOption)(nil)).Elem() +} + +type VirtualDisk struct { + VirtualDevice + + CapacityInKB int64 `xml:"capacityInKB"` + CapacityInBytes int64 `xml:"capacityInBytes,omitempty"` + Shares *SharesInfo `xml:"shares,omitempty"` + StorageIOAllocation *StorageIOAllocationInfo `xml:"storageIOAllocation,omitempty"` + DiskObjectId string `xml:"diskObjectId,omitempty"` + VFlashCacheConfigInfo *VirtualDiskVFlashCacheConfigInfo `xml:"vFlashCacheConfigInfo,omitempty"` + Iofilter []string `xml:"iofilter,omitempty"` +} + +func init() { + t["VirtualDisk"] = reflect.TypeOf((*VirtualDisk)(nil)).Elem() +} + +type VirtualDiskAntiAffinityRuleSpec struct { + ClusterRuleInfo + + DiskId []int32 `xml:"diskId"` +} + +func init() { + t["VirtualDiskAntiAffinityRuleSpec"] = reflect.TypeOf((*VirtualDiskAntiAffinityRuleSpec)(nil)).Elem() +} + +type VirtualDiskBlocksNotFullyProvisioned struct { + DeviceBackingNotSupported +} + +func init() { + t["VirtualDiskBlocksNotFullyProvisioned"] = reflect.TypeOf((*VirtualDiskBlocksNotFullyProvisioned)(nil)).Elem() +} + +type VirtualDiskBlocksNotFullyProvisionedFault VirtualDiskBlocksNotFullyProvisioned + +func init() { + t["VirtualDiskBlocksNotFullyProvisionedFault"] = reflect.TypeOf((*VirtualDiskBlocksNotFullyProvisionedFault)(nil)).Elem() +} + +type VirtualDiskConfigSpec struct { + VirtualDeviceConfigSpec + + DiskMoveType string `xml:"diskMoveType,omitempty"` + MigrateCache *bool `xml:"migrateCache"` +} + +func init() { + t["VirtualDiskConfigSpec"] = reflect.TypeOf((*VirtualDiskConfigSpec)(nil)).Elem() +} + +type VirtualDiskDeltaDiskFormatsSupported struct { + DynamicData + + DatastoreType string `xml:"datastoreType"` + DeltaDiskFormat ChoiceOption `xml:"deltaDiskFormat"` +} + +func init() { + t["VirtualDiskDeltaDiskFormatsSupported"] = reflect.TypeOf((*VirtualDiskDeltaDiskFormatsSupported)(nil)).Elem() +} + +type VirtualDiskFlatVer1BackingInfo struct { + VirtualDeviceFileBackingInfo + + DiskMode string `xml:"diskMode"` + Split *bool `xml:"split"` + WriteThrough *bool `xml:"writeThrough"` + ContentId string `xml:"contentId,omitempty"` + Parent *VirtualDiskFlatVer1BackingInfo `xml:"parent,omitempty"` +} + +func init() { + t["VirtualDiskFlatVer1BackingInfo"] = reflect.TypeOf((*VirtualDiskFlatVer1BackingInfo)(nil)).Elem() +} + +type VirtualDiskFlatVer1BackingOption struct { + VirtualDeviceFileBackingOption + + DiskMode ChoiceOption `xml:"diskMode"` + Split BoolOption `xml:"split"` + WriteThrough BoolOption `xml:"writeThrough"` + Growable bool `xml:"growable"` +} + +func init() { + t["VirtualDiskFlatVer1BackingOption"] = reflect.TypeOf((*VirtualDiskFlatVer1BackingOption)(nil)).Elem() +} + +type VirtualDiskFlatVer2BackingInfo struct { + VirtualDeviceFileBackingInfo + + DiskMode string `xml:"diskMode"` + Split *bool `xml:"split"` + WriteThrough *bool `xml:"writeThrough"` + ThinProvisioned *bool `xml:"thinProvisioned"` + EagerlyScrub *bool `xml:"eagerlyScrub"` + Uuid string `xml:"uuid,omitempty"` + ContentId string `xml:"contentId,omitempty"` + ChangeId string `xml:"changeId,omitempty"` + Parent *VirtualDiskFlatVer2BackingInfo `xml:"parent,omitempty"` + DeltaDiskFormat string `xml:"deltaDiskFormat,omitempty"` + DigestEnabled *bool `xml:"digestEnabled"` + DeltaGrainSize int32 `xml:"deltaGrainSize,omitempty"` + DeltaDiskFormatVariant string `xml:"deltaDiskFormatVariant,omitempty"` + Sharing string `xml:"sharing,omitempty"` +} + +func init() { + t["VirtualDiskFlatVer2BackingInfo"] = reflect.TypeOf((*VirtualDiskFlatVer2BackingInfo)(nil)).Elem() +} + +type VirtualDiskFlatVer2BackingOption struct { + VirtualDeviceFileBackingOption + + DiskMode ChoiceOption `xml:"diskMode"` + Split BoolOption `xml:"split"` + WriteThrough BoolOption `xml:"writeThrough"` + Growable bool `xml:"growable"` + HotGrowable bool `xml:"hotGrowable"` + Uuid bool `xml:"uuid"` + ThinProvisioned *BoolOption `xml:"thinProvisioned,omitempty"` + EagerlyScrub *BoolOption `xml:"eagerlyScrub,omitempty"` + DeltaDiskFormat *ChoiceOption `xml:"deltaDiskFormat,omitempty"` + DeltaDiskFormatsSupported []VirtualDiskDeltaDiskFormatsSupported `xml:"deltaDiskFormatsSupported,omitempty"` +} + +func init() { + t["VirtualDiskFlatVer2BackingOption"] = reflect.TypeOf((*VirtualDiskFlatVer2BackingOption)(nil)).Elem() +} + +type VirtualDiskId struct { + DynamicData + + Vm ManagedObjectReference `xml:"vm"` + DiskId int32 `xml:"diskId"` +} + +func init() { + t["VirtualDiskId"] = reflect.TypeOf((*VirtualDiskId)(nil)).Elem() +} + +type VirtualDiskModeNotSupported struct { + DeviceNotSupported + + Mode string `xml:"mode"` +} + +func init() { + t["VirtualDiskModeNotSupported"] = reflect.TypeOf((*VirtualDiskModeNotSupported)(nil)).Elem() +} + +type VirtualDiskModeNotSupportedFault VirtualDiskModeNotSupported + +func init() { + t["VirtualDiskModeNotSupportedFault"] = reflect.TypeOf((*VirtualDiskModeNotSupportedFault)(nil)).Elem() +} + +type VirtualDiskOption struct { + VirtualDeviceOption + + CapacityInKB LongOption `xml:"capacityInKB"` + IoAllocationOption *StorageIOAllocationOption `xml:"ioAllocationOption,omitempty"` + VFlashCacheConfigOption *VirtualDiskOptionVFlashCacheConfigOption `xml:"vFlashCacheConfigOption,omitempty"` +} + +func init() { + t["VirtualDiskOption"] = reflect.TypeOf((*VirtualDiskOption)(nil)).Elem() +} + +type VirtualDiskOptionVFlashCacheConfigOption struct { + DynamicData + + CacheConsistencyType ChoiceOption `xml:"cacheConsistencyType"` + CacheMode ChoiceOption `xml:"cacheMode"` + ReservationInMB LongOption `xml:"reservationInMB"` + BlockSizeInKB LongOption `xml:"blockSizeInKB"` +} + +func init() { + t["VirtualDiskOptionVFlashCacheConfigOption"] = reflect.TypeOf((*VirtualDiskOptionVFlashCacheConfigOption)(nil)).Elem() +} + +type VirtualDiskPartitionedRawDiskVer2BackingInfo struct { + VirtualDiskRawDiskVer2BackingInfo + + Partition []int32 `xml:"partition"` +} + +func init() { + t["VirtualDiskPartitionedRawDiskVer2BackingInfo"] = reflect.TypeOf((*VirtualDiskPartitionedRawDiskVer2BackingInfo)(nil)).Elem() +} + +type VirtualDiskPartitionedRawDiskVer2BackingOption struct { + VirtualDiskRawDiskVer2BackingOption +} + +func init() { + t["VirtualDiskPartitionedRawDiskVer2BackingOption"] = reflect.TypeOf((*VirtualDiskPartitionedRawDiskVer2BackingOption)(nil)).Elem() +} + +type VirtualDiskRawDiskMappingVer1BackingInfo struct { + VirtualDeviceFileBackingInfo + + LunUuid string `xml:"lunUuid,omitempty"` + DeviceName string `xml:"deviceName,omitempty"` + CompatibilityMode string `xml:"compatibilityMode,omitempty"` + DiskMode string `xml:"diskMode,omitempty"` + Uuid string `xml:"uuid,omitempty"` + ContentId string `xml:"contentId,omitempty"` + ChangeId string `xml:"changeId,omitempty"` + Parent *VirtualDiskRawDiskMappingVer1BackingInfo `xml:"parent,omitempty"` + Sharing string `xml:"sharing,omitempty"` +} + +func init() { + t["VirtualDiskRawDiskMappingVer1BackingInfo"] = reflect.TypeOf((*VirtualDiskRawDiskMappingVer1BackingInfo)(nil)).Elem() +} + +type VirtualDiskRawDiskMappingVer1BackingOption struct { + VirtualDeviceDeviceBackingOption + + DescriptorFileNameExtensions *ChoiceOption `xml:"descriptorFileNameExtensions,omitempty"` + CompatibilityMode ChoiceOption `xml:"compatibilityMode"` + DiskMode ChoiceOption `xml:"diskMode"` + Uuid bool `xml:"uuid"` +} + +func init() { + t["VirtualDiskRawDiskMappingVer1BackingOption"] = reflect.TypeOf((*VirtualDiskRawDiskMappingVer1BackingOption)(nil)).Elem() +} + +type VirtualDiskRawDiskVer2BackingInfo struct { + VirtualDeviceDeviceBackingInfo + + DescriptorFileName string `xml:"descriptorFileName"` + Uuid string `xml:"uuid,omitempty"` + ChangeId string `xml:"changeId,omitempty"` + Sharing string `xml:"sharing,omitempty"` +} + +func init() { + t["VirtualDiskRawDiskVer2BackingInfo"] = reflect.TypeOf((*VirtualDiskRawDiskVer2BackingInfo)(nil)).Elem() +} + +type VirtualDiskRawDiskVer2BackingOption struct { + VirtualDeviceDeviceBackingOption + + DescriptorFileNameExtensions ChoiceOption `xml:"descriptorFileNameExtensions"` + Uuid bool `xml:"uuid"` +} + +func init() { + t["VirtualDiskRawDiskVer2BackingOption"] = reflect.TypeOf((*VirtualDiskRawDiskVer2BackingOption)(nil)).Elem() +} + +type VirtualDiskSeSparseBackingInfo struct { + VirtualDeviceFileBackingInfo + + DiskMode string `xml:"diskMode"` + WriteThrough *bool `xml:"writeThrough"` + Uuid string `xml:"uuid,omitempty"` + ContentId string `xml:"contentId,omitempty"` + ChangeId string `xml:"changeId,omitempty"` + Parent *VirtualDiskSeSparseBackingInfo `xml:"parent,omitempty"` + DeltaDiskFormat string `xml:"deltaDiskFormat,omitempty"` + DigestEnabled *bool `xml:"digestEnabled"` + GrainSize int32 `xml:"grainSize,omitempty"` +} + +func init() { + t["VirtualDiskSeSparseBackingInfo"] = reflect.TypeOf((*VirtualDiskSeSparseBackingInfo)(nil)).Elem() +} + +type VirtualDiskSeSparseBackingOption struct { + VirtualDeviceFileBackingOption + + DiskMode ChoiceOption `xml:"diskMode"` + WriteThrough BoolOption `xml:"writeThrough"` + Growable bool `xml:"growable"` + HotGrowable bool `xml:"hotGrowable"` + Uuid bool `xml:"uuid"` + DeltaDiskFormatsSupported []VirtualDiskDeltaDiskFormatsSupported `xml:"deltaDiskFormatsSupported"` +} + +func init() { + t["VirtualDiskSeSparseBackingOption"] = reflect.TypeOf((*VirtualDiskSeSparseBackingOption)(nil)).Elem() +} + +type VirtualDiskSparseVer1BackingInfo struct { + VirtualDeviceFileBackingInfo + + DiskMode string `xml:"diskMode"` + Split *bool `xml:"split"` + WriteThrough *bool `xml:"writeThrough"` + SpaceUsedInKB int64 `xml:"spaceUsedInKB,omitempty"` + ContentId string `xml:"contentId,omitempty"` + Parent *VirtualDiskSparseVer1BackingInfo `xml:"parent,omitempty"` +} + +func init() { + t["VirtualDiskSparseVer1BackingInfo"] = reflect.TypeOf((*VirtualDiskSparseVer1BackingInfo)(nil)).Elem() +} + +type VirtualDiskSparseVer1BackingOption struct { + VirtualDeviceFileBackingOption + + DiskModes ChoiceOption `xml:"diskModes"` + Split BoolOption `xml:"split"` + WriteThrough BoolOption `xml:"writeThrough"` + Growable bool `xml:"growable"` +} + +func init() { + t["VirtualDiskSparseVer1BackingOption"] = reflect.TypeOf((*VirtualDiskSparseVer1BackingOption)(nil)).Elem() +} + +type VirtualDiskSparseVer2BackingInfo struct { + VirtualDeviceFileBackingInfo + + DiskMode string `xml:"diskMode"` + Split *bool `xml:"split"` + WriteThrough *bool `xml:"writeThrough"` + SpaceUsedInKB int64 `xml:"spaceUsedInKB,omitempty"` + Uuid string `xml:"uuid,omitempty"` + ContentId string `xml:"contentId,omitempty"` + ChangeId string `xml:"changeId,omitempty"` + Parent *VirtualDiskSparseVer2BackingInfo `xml:"parent,omitempty"` +} + +func init() { + t["VirtualDiskSparseVer2BackingInfo"] = reflect.TypeOf((*VirtualDiskSparseVer2BackingInfo)(nil)).Elem() +} + +type VirtualDiskSparseVer2BackingOption struct { + VirtualDeviceFileBackingOption + + DiskMode ChoiceOption `xml:"diskMode"` + Split BoolOption `xml:"split"` + WriteThrough BoolOption `xml:"writeThrough"` + Growable bool `xml:"growable"` + HotGrowable bool `xml:"hotGrowable"` + Uuid bool `xml:"uuid"` +} + +func init() { + t["VirtualDiskSparseVer2BackingOption"] = reflect.TypeOf((*VirtualDiskSparseVer2BackingOption)(nil)).Elem() +} + +type VirtualDiskSpec struct { + DynamicData + + DiskType string `xml:"diskType"` + AdapterType string `xml:"adapterType"` +} + +func init() { + t["VirtualDiskSpec"] = reflect.TypeOf((*VirtualDiskSpec)(nil)).Elem() +} + +type VirtualDiskVFlashCacheConfigInfo struct { + DynamicData + + VFlashModule string `xml:"vFlashModule,omitempty"` + ReservationInMB int64 `xml:"reservationInMB,omitempty"` + CacheConsistencyType string `xml:"cacheConsistencyType,omitempty"` + CacheMode string `xml:"cacheMode,omitempty"` + BlockSizeInKB int64 `xml:"blockSizeInKB,omitempty"` +} + +func init() { + t["VirtualDiskVFlashCacheConfigInfo"] = reflect.TypeOf((*VirtualDiskVFlashCacheConfigInfo)(nil)).Elem() +} + +type VirtualE1000 struct { + VirtualEthernetCard +} + +func init() { + t["VirtualE1000"] = reflect.TypeOf((*VirtualE1000)(nil)).Elem() +} + +type VirtualE1000Option struct { + VirtualEthernetCardOption +} + +func init() { + t["VirtualE1000Option"] = reflect.TypeOf((*VirtualE1000Option)(nil)).Elem() +} + +type VirtualE1000e struct { + VirtualEthernetCard +} + +func init() { + t["VirtualE1000e"] = reflect.TypeOf((*VirtualE1000e)(nil)).Elem() +} + +type VirtualE1000eOption struct { + VirtualEthernetCardOption +} + +func init() { + t["VirtualE1000eOption"] = reflect.TypeOf((*VirtualE1000eOption)(nil)).Elem() +} + +type VirtualEnsoniq1371 struct { + VirtualSoundCard +} + +func init() { + t["VirtualEnsoniq1371"] = reflect.TypeOf((*VirtualEnsoniq1371)(nil)).Elem() +} + +type VirtualEnsoniq1371Option struct { + VirtualSoundCardOption +} + +func init() { + t["VirtualEnsoniq1371Option"] = reflect.TypeOf((*VirtualEnsoniq1371Option)(nil)).Elem() +} + +type VirtualEthernetCard struct { + VirtualDevice + + AddressType string `xml:"addressType,omitempty"` + MacAddress string `xml:"macAddress,omitempty"` + WakeOnLanEnabled *bool `xml:"wakeOnLanEnabled"` + ResourceAllocation *VirtualEthernetCardResourceAllocation `xml:"resourceAllocation,omitempty"` + ExternalId string `xml:"externalId,omitempty"` + UptCompatibilityEnabled *bool `xml:"uptCompatibilityEnabled"` +} + +func init() { + t["VirtualEthernetCard"] = reflect.TypeOf((*VirtualEthernetCard)(nil)).Elem() +} + +type VirtualEthernetCardDVPortBackingOption struct { + VirtualDeviceBackingOption +} + +func init() { + t["VirtualEthernetCardDVPortBackingOption"] = reflect.TypeOf((*VirtualEthernetCardDVPortBackingOption)(nil)).Elem() +} + +type VirtualEthernetCardDistributedVirtualPortBackingInfo struct { + VirtualDeviceBackingInfo + + Port DistributedVirtualSwitchPortConnection `xml:"port"` +} + +func init() { + t["VirtualEthernetCardDistributedVirtualPortBackingInfo"] = reflect.TypeOf((*VirtualEthernetCardDistributedVirtualPortBackingInfo)(nil)).Elem() +} + +type VirtualEthernetCardLegacyNetworkBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualEthernetCardLegacyNetworkBackingInfo"] = reflect.TypeOf((*VirtualEthernetCardLegacyNetworkBackingInfo)(nil)).Elem() +} + +type VirtualEthernetCardLegacyNetworkBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualEthernetCardLegacyNetworkBackingOption"] = reflect.TypeOf((*VirtualEthernetCardLegacyNetworkBackingOption)(nil)).Elem() +} + +type VirtualEthernetCardNetworkBackingInfo struct { + VirtualDeviceDeviceBackingInfo + + Network *ManagedObjectReference `xml:"network,omitempty"` + InPassthroughMode *bool `xml:"inPassthroughMode"` +} + +func init() { + t["VirtualEthernetCardNetworkBackingInfo"] = reflect.TypeOf((*VirtualEthernetCardNetworkBackingInfo)(nil)).Elem() +} + +type VirtualEthernetCardNetworkBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualEthernetCardNetworkBackingOption"] = reflect.TypeOf((*VirtualEthernetCardNetworkBackingOption)(nil)).Elem() +} + +type VirtualEthernetCardNotSupported struct { + DeviceNotSupported +} + +func init() { + t["VirtualEthernetCardNotSupported"] = reflect.TypeOf((*VirtualEthernetCardNotSupported)(nil)).Elem() +} + +type VirtualEthernetCardNotSupportedFault VirtualEthernetCardNotSupported + +func init() { + t["VirtualEthernetCardNotSupportedFault"] = reflect.TypeOf((*VirtualEthernetCardNotSupportedFault)(nil)).Elem() +} + +type VirtualEthernetCardOpaqueNetworkBackingInfo struct { + VirtualDeviceBackingInfo + + OpaqueNetworkId string `xml:"opaqueNetworkId"` + OpaqueNetworkType string `xml:"opaqueNetworkType"` +} + +func init() { + t["VirtualEthernetCardOpaqueNetworkBackingInfo"] = reflect.TypeOf((*VirtualEthernetCardOpaqueNetworkBackingInfo)(nil)).Elem() +} + +type VirtualEthernetCardOpaqueNetworkBackingOption struct { + VirtualDeviceBackingOption +} + +func init() { + t["VirtualEthernetCardOpaqueNetworkBackingOption"] = reflect.TypeOf((*VirtualEthernetCardOpaqueNetworkBackingOption)(nil)).Elem() +} + +type VirtualEthernetCardOption struct { + VirtualDeviceOption + + SupportedOUI ChoiceOption `xml:"supportedOUI"` + MacType ChoiceOption `xml:"macType"` + WakeOnLanEnabled BoolOption `xml:"wakeOnLanEnabled"` + VmDirectPathGen2Supported *bool `xml:"vmDirectPathGen2Supported"` + UptCompatibilityEnabled *BoolOption `xml:"uptCompatibilityEnabled,omitempty"` +} + +func init() { + t["VirtualEthernetCardOption"] = reflect.TypeOf((*VirtualEthernetCardOption)(nil)).Elem() +} + +type VirtualEthernetCardResourceAllocation struct { + DynamicData + + Reservation int64 `xml:"reservation,omitempty"` + Share SharesInfo `xml:"share"` + Limit int64 `xml:"limit,omitempty"` +} + +func init() { + t["VirtualEthernetCardResourceAllocation"] = reflect.TypeOf((*VirtualEthernetCardResourceAllocation)(nil)).Elem() +} + +type VirtualFloppy struct { + VirtualDevice +} + +func init() { + t["VirtualFloppy"] = reflect.TypeOf((*VirtualFloppy)(nil)).Elem() +} + +type VirtualFloppyDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualFloppyDeviceBackingInfo"] = reflect.TypeOf((*VirtualFloppyDeviceBackingInfo)(nil)).Elem() +} + +type VirtualFloppyDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualFloppyDeviceBackingOption"] = reflect.TypeOf((*VirtualFloppyDeviceBackingOption)(nil)).Elem() +} + +type VirtualFloppyImageBackingInfo struct { + VirtualDeviceFileBackingInfo +} + +func init() { + t["VirtualFloppyImageBackingInfo"] = reflect.TypeOf((*VirtualFloppyImageBackingInfo)(nil)).Elem() +} + +type VirtualFloppyImageBackingOption struct { + VirtualDeviceFileBackingOption +} + +func init() { + t["VirtualFloppyImageBackingOption"] = reflect.TypeOf((*VirtualFloppyImageBackingOption)(nil)).Elem() +} + +type VirtualFloppyOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualFloppyOption"] = reflect.TypeOf((*VirtualFloppyOption)(nil)).Elem() +} + +type VirtualFloppyRemoteDeviceBackingInfo struct { + VirtualDeviceRemoteDeviceBackingInfo +} + +func init() { + t["VirtualFloppyRemoteDeviceBackingInfo"] = reflect.TypeOf((*VirtualFloppyRemoteDeviceBackingInfo)(nil)).Elem() +} + +type VirtualFloppyRemoteDeviceBackingOption struct { + VirtualDeviceRemoteDeviceBackingOption +} + +func init() { + t["VirtualFloppyRemoteDeviceBackingOption"] = reflect.TypeOf((*VirtualFloppyRemoteDeviceBackingOption)(nil)).Elem() +} + +type VirtualHardware struct { + DynamicData + + NumCPU int32 `xml:"numCPU"` + NumCoresPerSocket int32 `xml:"numCoresPerSocket,omitempty"` + MemoryMB int32 `xml:"memoryMB"` + VirtualICH7MPresent *bool `xml:"virtualICH7MPresent"` + VirtualSMCPresent *bool `xml:"virtualSMCPresent"` + Device []BaseVirtualDevice `xml:"device,omitempty,typeattr"` +} + +func init() { + t["VirtualHardware"] = reflect.TypeOf((*VirtualHardware)(nil)).Elem() +} + +type VirtualHardwareCompatibilityIssue struct { + VmConfigFault +} + +func init() { + t["VirtualHardwareCompatibilityIssue"] = reflect.TypeOf((*VirtualHardwareCompatibilityIssue)(nil)).Elem() +} + +type VirtualHardwareCompatibilityIssueFault BaseVirtualHardwareCompatibilityIssue + +func init() { + t["VirtualHardwareCompatibilityIssueFault"] = reflect.TypeOf((*VirtualHardwareCompatibilityIssueFault)(nil)).Elem() +} + +type VirtualHardwareOption struct { + DynamicData + + HwVersion int32 `xml:"hwVersion"` + VirtualDeviceOption []BaseVirtualDeviceOption `xml:"virtualDeviceOption,typeattr"` + DeviceListReadonly bool `xml:"deviceListReadonly"` + NumCPU []int32 `xml:"numCPU"` + NumCoresPerSocket *IntOption `xml:"numCoresPerSocket,omitempty"` + NumCpuReadonly bool `xml:"numCpuReadonly"` + MemoryMB LongOption `xml:"memoryMB"` + NumPCIControllers IntOption `xml:"numPCIControllers"` + NumIDEControllers IntOption `xml:"numIDEControllers"` + NumUSBControllers IntOption `xml:"numUSBControllers"` + NumUSBXHCIControllers *IntOption `xml:"numUSBXHCIControllers,omitempty"` + NumSIOControllers IntOption `xml:"numSIOControllers"` + NumPS2Controllers IntOption `xml:"numPS2Controllers"` + LicensingLimit []string `xml:"licensingLimit,omitempty"` + NumSupportedWwnPorts *IntOption `xml:"numSupportedWwnPorts,omitempty"` + NumSupportedWwnNodes *IntOption `xml:"numSupportedWwnNodes,omitempty"` + ResourceConfigOption *ResourceConfigOption `xml:"resourceConfigOption,omitempty"` +} + +func init() { + t["VirtualHardwareOption"] = reflect.TypeOf((*VirtualHardwareOption)(nil)).Elem() +} + +type VirtualHardwareVersionNotSupported struct { + VirtualHardwareCompatibilityIssue + + HostName string `xml:"hostName"` + Host ManagedObjectReference `xml:"host"` +} + +func init() { + t["VirtualHardwareVersionNotSupported"] = reflect.TypeOf((*VirtualHardwareVersionNotSupported)(nil)).Elem() +} + +type VirtualHardwareVersionNotSupportedFault VirtualHardwareVersionNotSupported + +func init() { + t["VirtualHardwareVersionNotSupportedFault"] = reflect.TypeOf((*VirtualHardwareVersionNotSupportedFault)(nil)).Elem() +} + +type VirtualHdAudioCard struct { + VirtualSoundCard +} + +func init() { + t["VirtualHdAudioCard"] = reflect.TypeOf((*VirtualHdAudioCard)(nil)).Elem() +} + +type VirtualHdAudioCardOption struct { + VirtualSoundCardOption +} + +func init() { + t["VirtualHdAudioCardOption"] = reflect.TypeOf((*VirtualHdAudioCardOption)(nil)).Elem() +} + +type VirtualIDEController struct { + VirtualController +} + +func init() { + t["VirtualIDEController"] = reflect.TypeOf((*VirtualIDEController)(nil)).Elem() +} + +type VirtualIDEControllerOption struct { + VirtualControllerOption + + NumIDEDisks IntOption `xml:"numIDEDisks"` + NumIDECdroms IntOption `xml:"numIDECdroms"` +} + +func init() { + t["VirtualIDEControllerOption"] = reflect.TypeOf((*VirtualIDEControllerOption)(nil)).Elem() +} + +type VirtualKeyboard struct { + VirtualDevice +} + +func init() { + t["VirtualKeyboard"] = reflect.TypeOf((*VirtualKeyboard)(nil)).Elem() +} + +type VirtualKeyboardOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualKeyboardOption"] = reflect.TypeOf((*VirtualKeyboardOption)(nil)).Elem() +} + +type VirtualLsiLogicController struct { + VirtualSCSIController +} + +func init() { + t["VirtualLsiLogicController"] = reflect.TypeOf((*VirtualLsiLogicController)(nil)).Elem() +} + +type VirtualLsiLogicControllerOption struct { + VirtualSCSIControllerOption +} + +func init() { + t["VirtualLsiLogicControllerOption"] = reflect.TypeOf((*VirtualLsiLogicControllerOption)(nil)).Elem() +} + +type VirtualLsiLogicSASController struct { + VirtualSCSIController +} + +func init() { + t["VirtualLsiLogicSASController"] = reflect.TypeOf((*VirtualLsiLogicSASController)(nil)).Elem() +} + +type VirtualLsiLogicSASControllerOption struct { + VirtualSCSIControllerOption +} + +func init() { + t["VirtualLsiLogicSASControllerOption"] = reflect.TypeOf((*VirtualLsiLogicSASControllerOption)(nil)).Elem() +} + +type VirtualMachineAffinityInfo struct { + DynamicData + + AffinitySet []int32 `xml:"affinitySet,omitempty"` +} + +func init() { + t["VirtualMachineAffinityInfo"] = reflect.TypeOf((*VirtualMachineAffinityInfo)(nil)).Elem() +} + +type VirtualMachineBootOptions struct { + DynamicData + + BootDelay int64 `xml:"bootDelay,omitempty"` + EnterBIOSSetup *bool `xml:"enterBIOSSetup"` + BootRetryEnabled *bool `xml:"bootRetryEnabled"` + BootRetryDelay int64 `xml:"bootRetryDelay,omitempty"` + BootOrder []BaseVirtualMachineBootOptionsBootableDevice `xml:"bootOrder,omitempty,typeattr"` + NetworkBootProtocol string `xml:"networkBootProtocol,omitempty"` +} + +func init() { + t["VirtualMachineBootOptions"] = reflect.TypeOf((*VirtualMachineBootOptions)(nil)).Elem() +} + +type VirtualMachineBootOptionsBootableCdromDevice struct { + VirtualMachineBootOptionsBootableDevice +} + +func init() { + t["VirtualMachineBootOptionsBootableCdromDevice"] = reflect.TypeOf((*VirtualMachineBootOptionsBootableCdromDevice)(nil)).Elem() +} + +type VirtualMachineBootOptionsBootableDevice struct { + DynamicData +} + +func init() { + t["VirtualMachineBootOptionsBootableDevice"] = reflect.TypeOf((*VirtualMachineBootOptionsBootableDevice)(nil)).Elem() +} + +type VirtualMachineBootOptionsBootableDiskDevice struct { + VirtualMachineBootOptionsBootableDevice + + DeviceKey int32 `xml:"deviceKey"` +} + +func init() { + t["VirtualMachineBootOptionsBootableDiskDevice"] = reflect.TypeOf((*VirtualMachineBootOptionsBootableDiskDevice)(nil)).Elem() +} + +type VirtualMachineBootOptionsBootableEthernetDevice struct { + VirtualMachineBootOptionsBootableDevice + + DeviceKey int32 `xml:"deviceKey"` +} + +func init() { + t["VirtualMachineBootOptionsBootableEthernetDevice"] = reflect.TypeOf((*VirtualMachineBootOptionsBootableEthernetDevice)(nil)).Elem() +} + +type VirtualMachineBootOptionsBootableFloppyDevice struct { + VirtualMachineBootOptionsBootableDevice +} + +func init() { + t["VirtualMachineBootOptionsBootableFloppyDevice"] = reflect.TypeOf((*VirtualMachineBootOptionsBootableFloppyDevice)(nil)).Elem() +} + +type VirtualMachineCapability struct { + DynamicData + + SnapshotOperationsSupported bool `xml:"snapshotOperationsSupported"` + MultipleSnapshotsSupported bool `xml:"multipleSnapshotsSupported"` + SnapshotConfigSupported bool `xml:"snapshotConfigSupported"` + PoweredOffSnapshotsSupported bool `xml:"poweredOffSnapshotsSupported"` + MemorySnapshotsSupported bool `xml:"memorySnapshotsSupported"` + RevertToSnapshotSupported bool `xml:"revertToSnapshotSupported"` + QuiescedSnapshotsSupported bool `xml:"quiescedSnapshotsSupported"` + DisableSnapshotsSupported bool `xml:"disableSnapshotsSupported"` + LockSnapshotsSupported bool `xml:"lockSnapshotsSupported"` + ConsolePreferencesSupported bool `xml:"consolePreferencesSupported"` + CpuFeatureMaskSupported bool `xml:"cpuFeatureMaskSupported"` + S1AcpiManagementSupported bool `xml:"s1AcpiManagementSupported"` + SettingScreenResolutionSupported bool `xml:"settingScreenResolutionSupported"` + ToolsAutoUpdateSupported bool `xml:"toolsAutoUpdateSupported"` + VmNpivWwnSupported bool `xml:"vmNpivWwnSupported"` + NpivWwnOnNonRdmVmSupported bool `xml:"npivWwnOnNonRdmVmSupported"` + VmNpivWwnDisableSupported *bool `xml:"vmNpivWwnDisableSupported"` + VmNpivWwnUpdateSupported *bool `xml:"vmNpivWwnUpdateSupported"` + SwapPlacementSupported bool `xml:"swapPlacementSupported"` + ToolsSyncTimeSupported bool `xml:"toolsSyncTimeSupported"` + VirtualMmuUsageSupported bool `xml:"virtualMmuUsageSupported"` + DiskSharesSupported bool `xml:"diskSharesSupported"` + BootOptionsSupported bool `xml:"bootOptionsSupported"` + BootRetryOptionsSupported *bool `xml:"bootRetryOptionsSupported"` + SettingVideoRamSizeSupported bool `xml:"settingVideoRamSizeSupported"` + SettingDisplayTopologySupported *bool `xml:"settingDisplayTopologySupported"` + RecordReplaySupported *bool `xml:"recordReplaySupported"` + ChangeTrackingSupported *bool `xml:"changeTrackingSupported"` + MultipleCoresPerSocketSupported *bool `xml:"multipleCoresPerSocketSupported"` + HostBasedReplicationSupported *bool `xml:"hostBasedReplicationSupported"` + GuestAutoLockSupported *bool `xml:"guestAutoLockSupported"` + MemoryReservationLockSupported *bool `xml:"memoryReservationLockSupported"` + FeatureRequirementSupported *bool `xml:"featureRequirementSupported"` + PoweredOnMonitorTypeChangeSupported *bool `xml:"poweredOnMonitorTypeChangeSupported"` + SeSparseDiskSupported *bool `xml:"seSparseDiskSupported"` + NestedHVSupported *bool `xml:"nestedHVSupported"` + VPMCSupported *bool `xml:"vPMCSupported"` +} + +func init() { + t["VirtualMachineCapability"] = reflect.TypeOf((*VirtualMachineCapability)(nil)).Elem() +} + +type VirtualMachineCdromInfo struct { + VirtualMachineTargetInfo +} + +func init() { + t["VirtualMachineCdromInfo"] = reflect.TypeOf((*VirtualMachineCdromInfo)(nil)).Elem() +} + +type VirtualMachineCloneSpec struct { + DynamicData + + Location VirtualMachineRelocateSpec `xml:"location"` + Template bool `xml:"template"` + Config *VirtualMachineConfigSpec `xml:"config,omitempty"` + Customization *CustomizationSpec `xml:"customization,omitempty"` + PowerOn bool `xml:"powerOn"` + Snapshot *ManagedObjectReference `xml:"snapshot,omitempty"` + Memory *bool `xml:"memory"` +} + +func init() { + t["VirtualMachineCloneSpec"] = reflect.TypeOf((*VirtualMachineCloneSpec)(nil)).Elem() +} + +type VirtualMachineConfigInfo struct { + DynamicData + + ChangeVersion string `xml:"changeVersion"` + Modified time.Time `xml:"modified"` + Name string `xml:"name"` + GuestFullName string `xml:"guestFullName"` + Version string `xml:"version"` + Uuid string `xml:"uuid"` + InstanceUuid string `xml:"instanceUuid,omitempty"` + NpivNodeWorldWideName []int64 `xml:"npivNodeWorldWideName,omitempty"` + NpivPortWorldWideName []int64 `xml:"npivPortWorldWideName,omitempty"` + NpivWorldWideNameType string `xml:"npivWorldWideNameType,omitempty"` + NpivDesiredNodeWwns int16 `xml:"npivDesiredNodeWwns,omitempty"` + NpivDesiredPortWwns int16 `xml:"npivDesiredPortWwns,omitempty"` + NpivTemporaryDisabled *bool `xml:"npivTemporaryDisabled"` + NpivOnNonRdmDisks *bool `xml:"npivOnNonRdmDisks"` + LocationId string `xml:"locationId,omitempty"` + Template bool `xml:"template"` + GuestId string `xml:"guestId"` + AlternateGuestName string `xml:"alternateGuestName"` + Annotation string `xml:"annotation,omitempty"` + Files VirtualMachineFileInfo `xml:"files"` + Tools *ToolsConfigInfo `xml:"tools,omitempty"` + Flags VirtualMachineFlagInfo `xml:"flags"` + ConsolePreferences *VirtualMachineConsolePreferences `xml:"consolePreferences,omitempty"` + DefaultPowerOps VirtualMachineDefaultPowerOpInfo `xml:"defaultPowerOps"` + Hardware VirtualHardware `xml:"hardware"` + CpuAllocation BaseResourceAllocationInfo `xml:"cpuAllocation,omitempty,typeattr"` + MemoryAllocation BaseResourceAllocationInfo `xml:"memoryAllocation,omitempty,typeattr"` + LatencySensitivity *LatencySensitivity `xml:"latencySensitivity,omitempty"` + MemoryHotAddEnabled *bool `xml:"memoryHotAddEnabled"` + CpuHotAddEnabled *bool `xml:"cpuHotAddEnabled"` + CpuHotRemoveEnabled *bool `xml:"cpuHotRemoveEnabled"` + HotPlugMemoryLimit int64 `xml:"hotPlugMemoryLimit,omitempty"` + HotPlugMemoryIncrementSize int64 `xml:"hotPlugMemoryIncrementSize,omitempty"` + CpuAffinity *VirtualMachineAffinityInfo `xml:"cpuAffinity,omitempty"` + MemoryAffinity *VirtualMachineAffinityInfo `xml:"memoryAffinity,omitempty"` + NetworkShaper *VirtualMachineNetworkShaperInfo `xml:"networkShaper,omitempty"` + ExtraConfig []BaseOptionValue `xml:"extraConfig,omitempty,typeattr"` + CpuFeatureMask []HostCpuIdInfo `xml:"cpuFeatureMask,omitempty"` + DatastoreUrl []VirtualMachineConfigInfoDatastoreUrlPair `xml:"datastoreUrl,omitempty"` + SwapPlacement string `xml:"swapPlacement,omitempty"` + BootOptions *VirtualMachineBootOptions `xml:"bootOptions,omitempty"` + FtInfo BaseFaultToleranceConfigInfo `xml:"ftInfo,omitempty,typeattr"` + RepConfig *ReplicationConfigSpec `xml:"repConfig,omitempty"` + VAppConfig BaseVmConfigInfo `xml:"vAppConfig,omitempty,typeattr"` + VAssertsEnabled *bool `xml:"vAssertsEnabled"` + ChangeTrackingEnabled *bool `xml:"changeTrackingEnabled"` + Firmware string `xml:"firmware,omitempty"` + MaxMksConnections int32 `xml:"maxMksConnections,omitempty"` + GuestAutoLockEnabled *bool `xml:"guestAutoLockEnabled"` + ManagedBy *ManagedByInfo `xml:"managedBy,omitempty"` + MemoryReservationLockedToMax *bool `xml:"memoryReservationLockedToMax"` + InitialOverhead *VirtualMachineConfigInfoOverheadInfo `xml:"initialOverhead,omitempty"` + NestedHVEnabled *bool `xml:"nestedHVEnabled"` + VPMCEnabled *bool `xml:"vPMCEnabled"` + ScheduledHardwareUpgradeInfo *ScheduledHardwareUpgradeInfo `xml:"scheduledHardwareUpgradeInfo,omitempty"` + ForkConfigInfo *VirtualMachineForkConfigInfo `xml:"forkConfigInfo,omitempty"` + VFlashCacheReservation int64 `xml:"vFlashCacheReservation,omitempty"` + VmxConfigChecksum []byte `xml:"vmxConfigChecksum,omitempty"` + MessageBusTunnelEnabled *bool `xml:"messageBusTunnelEnabled"` + VmStorageObjectId string `xml:"vmStorageObjectId,omitempty"` + SwapStorageObjectId string `xml:"swapStorageObjectId,omitempty"` +} + +func init() { + t["VirtualMachineConfigInfo"] = reflect.TypeOf((*VirtualMachineConfigInfo)(nil)).Elem() +} + +type VirtualMachineConfigInfoDatastoreUrlPair struct { + DynamicData + + Name string `xml:"name"` + Url string `xml:"url"` +} + +func init() { + t["VirtualMachineConfigInfoDatastoreUrlPair"] = reflect.TypeOf((*VirtualMachineConfigInfoDatastoreUrlPair)(nil)).Elem() +} + +type VirtualMachineConfigInfoOverheadInfo struct { + DynamicData + + InitialMemoryReservation int64 `xml:"initialMemoryReservation,omitempty"` + InitialSwapReservation int64 `xml:"initialSwapReservation,omitempty"` +} + +func init() { + t["VirtualMachineConfigInfoOverheadInfo"] = reflect.TypeOf((*VirtualMachineConfigInfoOverheadInfo)(nil)).Elem() +} + +type VirtualMachineConfigOption struct { + DynamicData + + Version string `xml:"version"` + Description string `xml:"description"` + GuestOSDescriptor []GuestOsDescriptor `xml:"guestOSDescriptor"` + GuestOSDefaultIndex int32 `xml:"guestOSDefaultIndex"` + HardwareOptions VirtualHardwareOption `xml:"hardwareOptions"` + Capabilities VirtualMachineCapability `xml:"capabilities"` + Datastore DatastoreOption `xml:"datastore"` + DefaultDevice []BaseVirtualDevice `xml:"defaultDevice,omitempty,typeattr"` + SupportedMonitorType []string `xml:"supportedMonitorType"` + SupportedOvfEnvironmentTransport []string `xml:"supportedOvfEnvironmentTransport,omitempty"` + SupportedOvfInstallTransport []string `xml:"supportedOvfInstallTransport,omitempty"` +} + +func init() { + t["VirtualMachineConfigOption"] = reflect.TypeOf((*VirtualMachineConfigOption)(nil)).Elem() +} + +type VirtualMachineConfigOptionDescriptor struct { + DynamicData + + Key string `xml:"key"` + Description string `xml:"description,omitempty"` + Host []ManagedObjectReference `xml:"host,omitempty"` + CreateSupported *bool `xml:"createSupported"` + DefaultConfigOption *bool `xml:"defaultConfigOption"` + RunSupported *bool `xml:"runSupported"` + UpgradeSupported *bool `xml:"upgradeSupported"` +} + +func init() { + t["VirtualMachineConfigOptionDescriptor"] = reflect.TypeOf((*VirtualMachineConfigOptionDescriptor)(nil)).Elem() +} + +type VirtualMachineConfigSpec struct { + DynamicData + + ChangeVersion string `xml:"changeVersion,omitempty"` + Name string `xml:"name,omitempty"` + Version string `xml:"version,omitempty"` + Uuid string `xml:"uuid,omitempty"` + InstanceUuid string `xml:"instanceUuid,omitempty"` + NpivNodeWorldWideName []int64 `xml:"npivNodeWorldWideName,omitempty"` + NpivPortWorldWideName []int64 `xml:"npivPortWorldWideName,omitempty"` + NpivWorldWideNameType string `xml:"npivWorldWideNameType,omitempty"` + NpivDesiredNodeWwns int16 `xml:"npivDesiredNodeWwns,omitempty"` + NpivDesiredPortWwns int16 `xml:"npivDesiredPortWwns,omitempty"` + NpivTemporaryDisabled *bool `xml:"npivTemporaryDisabled"` + NpivOnNonRdmDisks *bool `xml:"npivOnNonRdmDisks"` + NpivWorldWideNameOp string `xml:"npivWorldWideNameOp,omitempty"` + LocationId string `xml:"locationId,omitempty"` + GuestId string `xml:"guestId,omitempty"` + AlternateGuestName string `xml:"alternateGuestName,omitempty"` + Annotation string `xml:"annotation,omitempty"` + Files *VirtualMachineFileInfo `xml:"files,omitempty"` + Tools *ToolsConfigInfo `xml:"tools,omitempty"` + Flags *VirtualMachineFlagInfo `xml:"flags,omitempty"` + ConsolePreferences *VirtualMachineConsolePreferences `xml:"consolePreferences,omitempty"` + PowerOpInfo *VirtualMachineDefaultPowerOpInfo `xml:"powerOpInfo,omitempty"` + NumCPUs int32 `xml:"numCPUs,omitempty"` + NumCoresPerSocket int32 `xml:"numCoresPerSocket,omitempty"` + MemoryMB int64 `xml:"memoryMB,omitempty"` + MemoryHotAddEnabled *bool `xml:"memoryHotAddEnabled"` + CpuHotAddEnabled *bool `xml:"cpuHotAddEnabled"` + CpuHotRemoveEnabled *bool `xml:"cpuHotRemoveEnabled"` + VirtualICH7MPresent *bool `xml:"virtualICH7MPresent"` + VirtualSMCPresent *bool `xml:"virtualSMCPresent"` + DeviceChange []BaseVirtualDeviceConfigSpec `xml:"deviceChange,omitempty,typeattr"` + CpuAllocation BaseResourceAllocationInfo `xml:"cpuAllocation,omitempty,typeattr"` + MemoryAllocation BaseResourceAllocationInfo `xml:"memoryAllocation,omitempty,typeattr"` + LatencySensitivity *LatencySensitivity `xml:"latencySensitivity,omitempty"` + CpuAffinity *VirtualMachineAffinityInfo `xml:"cpuAffinity,omitempty"` + MemoryAffinity *VirtualMachineAffinityInfo `xml:"memoryAffinity,omitempty"` + NetworkShaper *VirtualMachineNetworkShaperInfo `xml:"networkShaper,omitempty"` + CpuFeatureMask []VirtualMachineCpuIdInfoSpec `xml:"cpuFeatureMask,omitempty"` + ExtraConfig []BaseOptionValue `xml:"extraConfig,omitempty,typeattr"` + SwapPlacement string `xml:"swapPlacement,omitempty"` + BootOptions *VirtualMachineBootOptions `xml:"bootOptions,omitempty"` + VAppConfig BaseVmConfigSpec `xml:"vAppConfig,omitempty,typeattr"` + FtInfo BaseFaultToleranceConfigInfo `xml:"ftInfo,omitempty,typeattr"` + RepConfig *ReplicationConfigSpec `xml:"repConfig,omitempty"` + VAppConfigRemoved *bool `xml:"vAppConfigRemoved"` + VAssertsEnabled *bool `xml:"vAssertsEnabled"` + ChangeTrackingEnabled *bool `xml:"changeTrackingEnabled"` + Firmware string `xml:"firmware,omitempty"` + MaxMksConnections int32 `xml:"maxMksConnections,omitempty"` + GuestAutoLockEnabled *bool `xml:"guestAutoLockEnabled"` + ManagedBy *ManagedByInfo `xml:"managedBy,omitempty"` + MemoryReservationLockedToMax *bool `xml:"memoryReservationLockedToMax"` + NestedHVEnabled *bool `xml:"nestedHVEnabled"` + VPMCEnabled *bool `xml:"vPMCEnabled"` + ScheduledHardwareUpgradeInfo *ScheduledHardwareUpgradeInfo `xml:"scheduledHardwareUpgradeInfo,omitempty"` + VmProfile []BaseVirtualMachineProfileSpec `xml:"vmProfile,omitempty,typeattr"` + MessageBusTunnelEnabled *bool `xml:"messageBusTunnelEnabled"` +} + +func init() { + t["VirtualMachineConfigSpec"] = reflect.TypeOf((*VirtualMachineConfigSpec)(nil)).Elem() +} + +type VirtualMachineConfigSummary struct { + DynamicData + + Name string `xml:"name"` + Template bool `xml:"template"` + VmPathName string `xml:"vmPathName"` + MemorySizeMB int32 `xml:"memorySizeMB,omitempty"` + CpuReservation int32 `xml:"cpuReservation,omitempty"` + MemoryReservation int32 `xml:"memoryReservation,omitempty"` + NumCpu int32 `xml:"numCpu,omitempty"` + NumEthernetCards int32 `xml:"numEthernetCards,omitempty"` + NumVirtualDisks int32 `xml:"numVirtualDisks,omitempty"` + Uuid string `xml:"uuid,omitempty"` + InstanceUuid string `xml:"instanceUuid,omitempty"` + GuestId string `xml:"guestId,omitempty"` + GuestFullName string `xml:"guestFullName,omitempty"` + Annotation string `xml:"annotation,omitempty"` + Product *VAppProductInfo `xml:"product,omitempty"` + InstallBootRequired *bool `xml:"installBootRequired"` + FtInfo BaseFaultToleranceConfigInfo `xml:"ftInfo,omitempty,typeattr"` + ManagedBy *ManagedByInfo `xml:"managedBy,omitempty"` +} + +func init() { + t["VirtualMachineConfigSummary"] = reflect.TypeOf((*VirtualMachineConfigSummary)(nil)).Elem() +} + +type VirtualMachineConsolePreferences struct { + DynamicData + + PowerOnWhenOpened *bool `xml:"powerOnWhenOpened"` + EnterFullScreenOnPowerOn *bool `xml:"enterFullScreenOnPowerOn"` + CloseOnPowerOffOrSuspend *bool `xml:"closeOnPowerOffOrSuspend"` +} + +func init() { + t["VirtualMachineConsolePreferences"] = reflect.TypeOf((*VirtualMachineConsolePreferences)(nil)).Elem() +} + +type VirtualMachineCpuIdInfoSpec struct { + ArrayUpdateSpec + + Info *HostCpuIdInfo `xml:"info,omitempty"` +} + +func init() { + t["VirtualMachineCpuIdInfoSpec"] = reflect.TypeOf((*VirtualMachineCpuIdInfoSpec)(nil)).Elem() +} + +type VirtualMachineCreateChildSpec struct { + DynamicData + + Location *VirtualMachineRelocateSpec `xml:"location,omitempty"` + Persistent bool `xml:"persistent"` + ConfigParams []BaseOptionValue `xml:"configParams,omitempty,typeattr"` +} + +func init() { + t["VirtualMachineCreateChildSpec"] = reflect.TypeOf((*VirtualMachineCreateChildSpec)(nil)).Elem() +} + +type VirtualMachineDatastoreInfo struct { + VirtualMachineTargetInfo + + Datastore DatastoreSummary `xml:"datastore"` + Capability DatastoreCapability `xml:"capability"` + MaxFileSize int64 `xml:"maxFileSize"` + MaxVirtualDiskCapacity int64 `xml:"maxVirtualDiskCapacity,omitempty"` + MaxPhysicalRDMFileSize int64 `xml:"maxPhysicalRDMFileSize,omitempty"` + MaxVirtualRDMFileSize int64 `xml:"maxVirtualRDMFileSize,omitempty"` + Mode string `xml:"mode"` + VStorageSupport string `xml:"vStorageSupport,omitempty"` +} + +func init() { + t["VirtualMachineDatastoreInfo"] = reflect.TypeOf((*VirtualMachineDatastoreInfo)(nil)).Elem() +} + +type VirtualMachineDatastoreVolumeOption struct { + DynamicData + + FileSystemType string `xml:"fileSystemType"` + MajorVersion int32 `xml:"majorVersion,omitempty"` +} + +func init() { + t["VirtualMachineDatastoreVolumeOption"] = reflect.TypeOf((*VirtualMachineDatastoreVolumeOption)(nil)).Elem() +} + +type VirtualMachineDefaultPowerOpInfo struct { + DynamicData + + PowerOffType string `xml:"powerOffType,omitempty"` + SuspendType string `xml:"suspendType,omitempty"` + ResetType string `xml:"resetType,omitempty"` + DefaultPowerOffType string `xml:"defaultPowerOffType,omitempty"` + DefaultSuspendType string `xml:"defaultSuspendType,omitempty"` + DefaultResetType string `xml:"defaultResetType,omitempty"` + StandbyAction string `xml:"standbyAction,omitempty"` +} + +func init() { + t["VirtualMachineDefaultPowerOpInfo"] = reflect.TypeOf((*VirtualMachineDefaultPowerOpInfo)(nil)).Elem() +} + +type VirtualMachineDefaultProfileSpec struct { + VirtualMachineProfileSpec +} + +func init() { + t["VirtualMachineDefaultProfileSpec"] = reflect.TypeOf((*VirtualMachineDefaultProfileSpec)(nil)).Elem() +} + +type VirtualMachineDefinedProfileSpec struct { + VirtualMachineProfileSpec + + ProfileId string `xml:"profileId"` + ProfileData *VirtualMachineProfileRawData `xml:"profileData,omitempty"` +} + +func init() { + t["VirtualMachineDefinedProfileSpec"] = reflect.TypeOf((*VirtualMachineDefinedProfileSpec)(nil)).Elem() +} + +type VirtualMachineDeviceRuntimeInfo struct { + DynamicData + + RuntimeState BaseVirtualMachineDeviceRuntimeInfoDeviceRuntimeState `xml:"runtimeState,typeattr"` + Key int32 `xml:"key"` +} + +func init() { + t["VirtualMachineDeviceRuntimeInfo"] = reflect.TypeOf((*VirtualMachineDeviceRuntimeInfo)(nil)).Elem() +} + +type VirtualMachineDeviceRuntimeInfoDeviceRuntimeState struct { + DynamicData +} + +func init() { + t["VirtualMachineDeviceRuntimeInfoDeviceRuntimeState"] = reflect.TypeOf((*VirtualMachineDeviceRuntimeInfoDeviceRuntimeState)(nil)).Elem() +} + +type VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeState struct { + VirtualMachineDeviceRuntimeInfoDeviceRuntimeState + + VmDirectPathGen2Active bool `xml:"vmDirectPathGen2Active"` + VmDirectPathGen2InactiveReasonVm []string `xml:"vmDirectPathGen2InactiveReasonVm,omitempty"` + VmDirectPathGen2InactiveReasonOther []string `xml:"vmDirectPathGen2InactiveReasonOther,omitempty"` + VmDirectPathGen2InactiveReasonExtended string `xml:"vmDirectPathGen2InactiveReasonExtended,omitempty"` + ReservationStatus string `xml:"reservationStatus,omitempty"` +} + +func init() { + t["VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeState"] = reflect.TypeOf((*VirtualMachineDeviceRuntimeInfoVirtualEthernetCardRuntimeState)(nil)).Elem() +} + +type VirtualMachineDiskDeviceInfo struct { + VirtualMachineTargetInfo + + Capacity int64 `xml:"capacity,omitempty"` + Vm []ManagedObjectReference `xml:"vm,omitempty"` +} + +func init() { + t["VirtualMachineDiskDeviceInfo"] = reflect.TypeOf((*VirtualMachineDiskDeviceInfo)(nil)).Elem() +} + +type VirtualMachineDisplayTopology struct { + DynamicData + + X int32 `xml:"x"` + Y int32 `xml:"y"` + Width int32 `xml:"width"` + Height int32 `xml:"height"` +} + +func init() { + t["VirtualMachineDisplayTopology"] = reflect.TypeOf((*VirtualMachineDisplayTopology)(nil)).Elem() +} + +type VirtualMachineEmptyProfileSpec struct { + VirtualMachineProfileSpec +} + +func init() { + t["VirtualMachineEmptyProfileSpec"] = reflect.TypeOf((*VirtualMachineEmptyProfileSpec)(nil)).Elem() +} + +type VirtualMachineFeatureRequirement struct { + DynamicData + + Key string `xml:"key"` + FeatureName string `xml:"featureName"` + Value string `xml:"value"` +} + +func init() { + t["VirtualMachineFeatureRequirement"] = reflect.TypeOf((*VirtualMachineFeatureRequirement)(nil)).Elem() +} + +type VirtualMachineFileInfo struct { + DynamicData + + VmPathName string `xml:"vmPathName,omitempty"` + SnapshotDirectory string `xml:"snapshotDirectory,omitempty"` + SuspendDirectory string `xml:"suspendDirectory,omitempty"` + LogDirectory string `xml:"logDirectory,omitempty"` + FtMetadataDirectory string `xml:"ftMetadataDirectory,omitempty"` +} + +func init() { + t["VirtualMachineFileInfo"] = reflect.TypeOf((*VirtualMachineFileInfo)(nil)).Elem() +} + +type VirtualMachineFileLayout struct { + DynamicData + + ConfigFile []string `xml:"configFile,omitempty"` + LogFile []string `xml:"logFile,omitempty"` + Disk []VirtualMachineFileLayoutDiskLayout `xml:"disk,omitempty"` + Snapshot []VirtualMachineFileLayoutSnapshotLayout `xml:"snapshot,omitempty"` + SwapFile string `xml:"swapFile,omitempty"` +} + +func init() { + t["VirtualMachineFileLayout"] = reflect.TypeOf((*VirtualMachineFileLayout)(nil)).Elem() +} + +type VirtualMachineFileLayoutDiskLayout struct { + DynamicData + + Key int32 `xml:"key"` + DiskFile []string `xml:"diskFile"` +} + +func init() { + t["VirtualMachineFileLayoutDiskLayout"] = reflect.TypeOf((*VirtualMachineFileLayoutDiskLayout)(nil)).Elem() +} + +type VirtualMachineFileLayoutEx struct { + DynamicData + + File []VirtualMachineFileLayoutExFileInfo `xml:"file,omitempty"` + Disk []VirtualMachineFileLayoutExDiskLayout `xml:"disk,omitempty"` + Snapshot []VirtualMachineFileLayoutExSnapshotLayout `xml:"snapshot,omitempty"` + Timestamp time.Time `xml:"timestamp"` +} + +func init() { + t["VirtualMachineFileLayoutEx"] = reflect.TypeOf((*VirtualMachineFileLayoutEx)(nil)).Elem() +} + +type VirtualMachineFileLayoutExDiskLayout struct { + DynamicData + + Key int32 `xml:"key"` + Chain []VirtualMachineFileLayoutExDiskUnit `xml:"chain,omitempty"` +} + +func init() { + t["VirtualMachineFileLayoutExDiskLayout"] = reflect.TypeOf((*VirtualMachineFileLayoutExDiskLayout)(nil)).Elem() +} + +type VirtualMachineFileLayoutExDiskUnit struct { + DynamicData + + FileKey []int32 `xml:"fileKey"` +} + +func init() { + t["VirtualMachineFileLayoutExDiskUnit"] = reflect.TypeOf((*VirtualMachineFileLayoutExDiskUnit)(nil)).Elem() +} + +type VirtualMachineFileLayoutExFileInfo struct { + DynamicData + + Key int32 `xml:"key"` + Name string `xml:"name"` + Type string `xml:"type"` + Size int64 `xml:"size"` + UniqueSize int64 `xml:"uniqueSize,omitempty"` + BackingObjectId string `xml:"backingObjectId,omitempty"` + Accessible *bool `xml:"accessible"` +} + +func init() { + t["VirtualMachineFileLayoutExFileInfo"] = reflect.TypeOf((*VirtualMachineFileLayoutExFileInfo)(nil)).Elem() +} + +type VirtualMachineFileLayoutExSnapshotLayout struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + DataKey int32 `xml:"dataKey"` + MemoryKey int32 `xml:"memoryKey,omitempty"` + Disk []VirtualMachineFileLayoutExDiskLayout `xml:"disk,omitempty"` +} + +func init() { + t["VirtualMachineFileLayoutExSnapshotLayout"] = reflect.TypeOf((*VirtualMachineFileLayoutExSnapshotLayout)(nil)).Elem() +} + +type VirtualMachineFileLayoutSnapshotLayout struct { + DynamicData + + Key ManagedObjectReference `xml:"key"` + SnapshotFile []string `xml:"snapshotFile"` +} + +func init() { + t["VirtualMachineFileLayoutSnapshotLayout"] = reflect.TypeOf((*VirtualMachineFileLayoutSnapshotLayout)(nil)).Elem() +} + +type VirtualMachineFlagInfo struct { + DynamicData + + DisableAcceleration *bool `xml:"disableAcceleration"` + EnableLogging *bool `xml:"enableLogging"` + UseToe *bool `xml:"useToe"` + RunWithDebugInfo *bool `xml:"runWithDebugInfo"` + MonitorType string `xml:"monitorType,omitempty"` + HtSharing string `xml:"htSharing,omitempty"` + SnapshotDisabled *bool `xml:"snapshotDisabled"` + SnapshotLocked *bool `xml:"snapshotLocked"` + DiskUuidEnabled *bool `xml:"diskUuidEnabled"` + VirtualMmuUsage string `xml:"virtualMmuUsage,omitempty"` + VirtualExecUsage string `xml:"virtualExecUsage,omitempty"` + SnapshotPowerOffBehavior string `xml:"snapshotPowerOffBehavior,omitempty"` + RecordReplayEnabled *bool `xml:"recordReplayEnabled"` + FaultToleranceType string `xml:"faultToleranceType,omitempty"` +} + +func init() { + t["VirtualMachineFlagInfo"] = reflect.TypeOf((*VirtualMachineFlagInfo)(nil)).Elem() +} + +type VirtualMachineFloppyInfo struct { + VirtualMachineTargetInfo +} + +func init() { + t["VirtualMachineFloppyInfo"] = reflect.TypeOf((*VirtualMachineFloppyInfo)(nil)).Elem() +} + +type VirtualMachineForkConfigInfo struct { + DynamicData + + ParentEnabled *bool `xml:"parentEnabled"` + ChildForkGroupId string `xml:"childForkGroupId,omitempty"` + ChildType string `xml:"childType,omitempty"` +} + +func init() { + t["VirtualMachineForkConfigInfo"] = reflect.TypeOf((*VirtualMachineForkConfigInfo)(nil)).Elem() +} + +type VirtualMachineGuestSummary struct { + DynamicData + + GuestId string `xml:"guestId,omitempty"` + GuestFullName string `xml:"guestFullName,omitempty"` + ToolsStatus VirtualMachineToolsStatus `xml:"toolsStatus,omitempty"` + ToolsVersionStatus string `xml:"toolsVersionStatus,omitempty"` + ToolsVersionStatus2 string `xml:"toolsVersionStatus2,omitempty"` + ToolsRunningStatus string `xml:"toolsRunningStatus,omitempty"` + HostName string `xml:"hostName,omitempty"` + IpAddress string `xml:"ipAddress,omitempty"` +} + +func init() { + t["VirtualMachineGuestSummary"] = reflect.TypeOf((*VirtualMachineGuestSummary)(nil)).Elem() +} + +type VirtualMachineIdeDiskDeviceInfo struct { + VirtualMachineDiskDeviceInfo + + PartitionTable []VirtualMachineIdeDiskDevicePartitionInfo `xml:"partitionTable,omitempty"` +} + +func init() { + t["VirtualMachineIdeDiskDeviceInfo"] = reflect.TypeOf((*VirtualMachineIdeDiskDeviceInfo)(nil)).Elem() +} + +type VirtualMachineIdeDiskDevicePartitionInfo struct { + DynamicData + + Id int32 `xml:"id"` + Capacity int32 `xml:"capacity"` +} + +func init() { + t["VirtualMachineIdeDiskDevicePartitionInfo"] = reflect.TypeOf((*VirtualMachineIdeDiskDevicePartitionInfo)(nil)).Elem() +} + +type VirtualMachineImportSpec struct { + ImportSpec + + ConfigSpec VirtualMachineConfigSpec `xml:"configSpec"` + ResPoolEntity *ManagedObjectReference `xml:"resPoolEntity,omitempty"` +} + +func init() { + t["VirtualMachineImportSpec"] = reflect.TypeOf((*VirtualMachineImportSpec)(nil)).Elem() +} + +type VirtualMachineLegacyNetworkSwitchInfo struct { + DynamicData + + Name string `xml:"name"` +} + +func init() { + t["VirtualMachineLegacyNetworkSwitchInfo"] = reflect.TypeOf((*VirtualMachineLegacyNetworkSwitchInfo)(nil)).Elem() +} + +type VirtualMachineMemoryReservationInfo struct { + DynamicData + + VirtualMachineMin int64 `xml:"virtualMachineMin"` + VirtualMachineMax int64 `xml:"virtualMachineMax"` + VirtualMachineReserved int64 `xml:"virtualMachineReserved"` + AllocationPolicy string `xml:"allocationPolicy"` +} + +func init() { + t["VirtualMachineMemoryReservationInfo"] = reflect.TypeOf((*VirtualMachineMemoryReservationInfo)(nil)).Elem() +} + +type VirtualMachineMemoryReservationSpec struct { + DynamicData + + VirtualMachineReserved int64 `xml:"virtualMachineReserved,omitempty"` + AllocationPolicy string `xml:"allocationPolicy,omitempty"` +} + +func init() { + t["VirtualMachineMemoryReservationSpec"] = reflect.TypeOf((*VirtualMachineMemoryReservationSpec)(nil)).Elem() +} + +type VirtualMachineMessage struct { + DynamicData + + Id string `xml:"id"` + Argument []AnyType `xml:"argument,omitempty,typeattr"` + Text string `xml:"text,omitempty"` +} + +func init() { + t["VirtualMachineMessage"] = reflect.TypeOf((*VirtualMachineMessage)(nil)).Elem() +} + +type VirtualMachineMetadataManagerVmMetadata struct { + DynamicData + + VmId string `xml:"vmId"` + Metadata string `xml:"metadata,omitempty"` +} + +func init() { + t["VirtualMachineMetadataManagerVmMetadata"] = reflect.TypeOf((*VirtualMachineMetadataManagerVmMetadata)(nil)).Elem() +} + +type VirtualMachineMetadataManagerVmMetadataInput struct { + DynamicData + + Operation string `xml:"operation"` + VmMetadata VirtualMachineMetadataManagerVmMetadata `xml:"vmMetadata"` +} + +func init() { + t["VirtualMachineMetadataManagerVmMetadataInput"] = reflect.TypeOf((*VirtualMachineMetadataManagerVmMetadataInput)(nil)).Elem() +} + +type VirtualMachineMetadataManagerVmMetadataOwner struct { + DynamicData + + Name string `xml:"name"` +} + +func init() { + t["VirtualMachineMetadataManagerVmMetadataOwner"] = reflect.TypeOf((*VirtualMachineMetadataManagerVmMetadataOwner)(nil)).Elem() +} + +type VirtualMachineMetadataManagerVmMetadataResult struct { + DynamicData + + VmMetadata VirtualMachineMetadataManagerVmMetadata `xml:"vmMetadata"` + Error *LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["VirtualMachineMetadataManagerVmMetadataResult"] = reflect.TypeOf((*VirtualMachineMetadataManagerVmMetadataResult)(nil)).Elem() +} + +type VirtualMachineMksTicket struct { + DynamicData + + Ticket string `xml:"ticket"` + CfgFile string `xml:"cfgFile"` + Host string `xml:"host,omitempty"` + Port int32 `xml:"port,omitempty"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` +} + +func init() { + t["VirtualMachineMksTicket"] = reflect.TypeOf((*VirtualMachineMksTicket)(nil)).Elem() +} + +type VirtualMachineNetworkInfo struct { + VirtualMachineTargetInfo + + Network BaseNetworkSummary `xml:"network,typeattr"` +} + +func init() { + t["VirtualMachineNetworkInfo"] = reflect.TypeOf((*VirtualMachineNetworkInfo)(nil)).Elem() +} + +type VirtualMachineNetworkShaperInfo struct { + DynamicData + + Enabled *bool `xml:"enabled"` + PeakBps int64 `xml:"peakBps,omitempty"` + AverageBps int64 `xml:"averageBps,omitempty"` + BurstSize int64 `xml:"burstSize,omitempty"` +} + +func init() { + t["VirtualMachineNetworkShaperInfo"] = reflect.TypeOf((*VirtualMachineNetworkShaperInfo)(nil)).Elem() +} + +type VirtualMachineParallelInfo struct { + VirtualMachineTargetInfo +} + +func init() { + t["VirtualMachineParallelInfo"] = reflect.TypeOf((*VirtualMachineParallelInfo)(nil)).Elem() +} + +type VirtualMachinePciPassthroughInfo struct { + VirtualMachineTargetInfo + + PciDevice HostPciDevice `xml:"pciDevice"` + SystemId string `xml:"systemId"` +} + +func init() { + t["VirtualMachinePciPassthroughInfo"] = reflect.TypeOf((*VirtualMachinePciPassthroughInfo)(nil)).Elem() +} + +type VirtualMachinePciSharedGpuPassthroughInfo struct { + VirtualMachineTargetInfo + + Vgpu string `xml:"vgpu"` +} + +func init() { + t["VirtualMachinePciSharedGpuPassthroughInfo"] = reflect.TypeOf((*VirtualMachinePciSharedGpuPassthroughInfo)(nil)).Elem() +} + +type VirtualMachineProfileRawData struct { + DynamicData + + ExtensionKey string `xml:"extensionKey"` + ObjectData string `xml:"objectData,omitempty"` +} + +func init() { + t["VirtualMachineProfileRawData"] = reflect.TypeOf((*VirtualMachineProfileRawData)(nil)).Elem() +} + +type VirtualMachineProfileSpec struct { + DynamicData +} + +func init() { + t["VirtualMachineProfileSpec"] = reflect.TypeOf((*VirtualMachineProfileSpec)(nil)).Elem() +} + +type VirtualMachineQuestionInfo struct { + DynamicData + + Id string `xml:"id"` + Text string `xml:"text"` + Choice ChoiceOption `xml:"choice"` + Message []VirtualMachineMessage `xml:"message,omitempty"` +} + +func init() { + t["VirtualMachineQuestionInfo"] = reflect.TypeOf((*VirtualMachineQuestionInfo)(nil)).Elem() +} + +type VirtualMachineQuickStats struct { + DynamicData + + OverallCpuUsage int32 `xml:"overallCpuUsage,omitempty"` + OverallCpuDemand int32 `xml:"overallCpuDemand,omitempty"` + GuestMemoryUsage int32 `xml:"guestMemoryUsage,omitempty"` + HostMemoryUsage int32 `xml:"hostMemoryUsage,omitempty"` + GuestHeartbeatStatus ManagedEntityStatus `xml:"guestHeartbeatStatus"` + DistributedCpuEntitlement int32 `xml:"distributedCpuEntitlement,omitempty"` + DistributedMemoryEntitlement int32 `xml:"distributedMemoryEntitlement,omitempty"` + StaticCpuEntitlement int32 `xml:"staticCpuEntitlement,omitempty"` + StaticMemoryEntitlement int32 `xml:"staticMemoryEntitlement,omitempty"` + PrivateMemory int32 `xml:"privateMemory,omitempty"` + SharedMemory int32 `xml:"sharedMemory,omitempty"` + SwappedMemory int32 `xml:"swappedMemory,omitempty"` + BalloonedMemory int32 `xml:"balloonedMemory,omitempty"` + ConsumedOverheadMemory int32 `xml:"consumedOverheadMemory,omitempty"` + FtLogBandwidth int32 `xml:"ftLogBandwidth,omitempty"` + FtSecondaryLatency int32 `xml:"ftSecondaryLatency,omitempty"` + FtLatencyStatus ManagedEntityStatus `xml:"ftLatencyStatus,omitempty"` + CompressedMemory int64 `xml:"compressedMemory,omitempty"` + UptimeSeconds int32 `xml:"uptimeSeconds,omitempty"` + SsdSwappedMemory int64 `xml:"ssdSwappedMemory,omitempty"` +} + +func init() { + t["VirtualMachineQuickStats"] = reflect.TypeOf((*VirtualMachineQuickStats)(nil)).Elem() +} + +type VirtualMachineRelocateSpec struct { + DynamicData + + Service *ServiceLocator `xml:"service,omitempty"` + Folder *ManagedObjectReference `xml:"folder,omitempty"` + Datastore *ManagedObjectReference `xml:"datastore,omitempty"` + DiskMoveType string `xml:"diskMoveType,omitempty"` + Pool *ManagedObjectReference `xml:"pool,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Disk []VirtualMachineRelocateSpecDiskLocator `xml:"disk,omitempty"` + Transform VirtualMachineRelocateTransformation `xml:"transform,omitempty"` + DeviceChange []BaseVirtualDeviceConfigSpec `xml:"deviceChange,omitempty,typeattr"` + Profile []BaseVirtualMachineProfileSpec `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["VirtualMachineRelocateSpec"] = reflect.TypeOf((*VirtualMachineRelocateSpec)(nil)).Elem() +} + +type VirtualMachineRelocateSpecDiskLocator struct { + DynamicData + + DiskId int32 `xml:"diskId"` + Datastore ManagedObjectReference `xml:"datastore"` + DiskMoveType string `xml:"diskMoveType,omitempty"` + DiskBackingInfo BaseVirtualDeviceBackingInfo `xml:"diskBackingInfo,omitempty,typeattr"` + Profile []BaseVirtualMachineProfileSpec `xml:"profile,omitempty,typeattr"` +} + +func init() { + t["VirtualMachineRelocateSpecDiskLocator"] = reflect.TypeOf((*VirtualMachineRelocateSpecDiskLocator)(nil)).Elem() +} + +type VirtualMachineRuntimeInfo struct { + DynamicData + + Device []VirtualMachineDeviceRuntimeInfo `xml:"device,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + ConnectionState VirtualMachineConnectionState `xml:"connectionState"` + PowerState VirtualMachinePowerState `xml:"powerState"` + FaultToleranceState VirtualMachineFaultToleranceState `xml:"faultToleranceState,omitempty"` + DasVmProtection *VirtualMachineRuntimeInfoDasProtectionState `xml:"dasVmProtection,omitempty"` + ToolsInstallerMounted bool `xml:"toolsInstallerMounted"` + SuspendTime *time.Time `xml:"suspendTime"` + BootTime *time.Time `xml:"bootTime"` + SuspendInterval int64 `xml:"suspendInterval,omitempty"` + Question *VirtualMachineQuestionInfo `xml:"question,omitempty"` + MemoryOverhead int64 `xml:"memoryOverhead,omitempty"` + MaxCpuUsage int32 `xml:"maxCpuUsage,omitempty"` + MaxMemoryUsage int32 `xml:"maxMemoryUsage,omitempty"` + NumMksConnections int32 `xml:"numMksConnections"` + RecordReplayState VirtualMachineRecordReplayState `xml:"recordReplayState,omitempty"` + CleanPowerOff *bool `xml:"cleanPowerOff"` + NeedSecondaryReason string `xml:"needSecondaryReason,omitempty"` + OnlineStandby *bool `xml:"onlineStandby"` + MinRequiredEVCModeKey string `xml:"minRequiredEVCModeKey,omitempty"` + ConsolidationNeeded *bool `xml:"consolidationNeeded"` + OfflineFeatureRequirement []VirtualMachineFeatureRequirement `xml:"offlineFeatureRequirement,omitempty"` + FeatureRequirement []VirtualMachineFeatureRequirement `xml:"featureRequirement,omitempty"` + FeatureMask []HostFeatureMask `xml:"featureMask,omitempty"` + VFlashCacheAllocation int64 `xml:"vFlashCacheAllocation,omitempty"` + Paused *bool `xml:"paused"` + SnapshotInBackground *bool `xml:"snapshotInBackground"` + QuiescedForkParent *bool `xml:"quiescedForkParent"` +} + +func init() { + t["VirtualMachineRuntimeInfo"] = reflect.TypeOf((*VirtualMachineRuntimeInfo)(nil)).Elem() +} + +type VirtualMachineRuntimeInfoDasProtectionState struct { + DynamicData + + DasProtected bool `xml:"dasProtected"` +} + +func init() { + t["VirtualMachineRuntimeInfoDasProtectionState"] = reflect.TypeOf((*VirtualMachineRuntimeInfoDasProtectionState)(nil)).Elem() +} + +type VirtualMachineScsiDiskDeviceInfo struct { + VirtualMachineDiskDeviceInfo + + Disk *HostScsiDisk `xml:"disk,omitempty"` + TransportHint string `xml:"transportHint,omitempty"` + LunNumber int32 `xml:"lunNumber,omitempty"` +} + +func init() { + t["VirtualMachineScsiDiskDeviceInfo"] = reflect.TypeOf((*VirtualMachineScsiDiskDeviceInfo)(nil)).Elem() +} + +type VirtualMachineScsiPassthroughInfo struct { + VirtualMachineTargetInfo + + ScsiClass string `xml:"scsiClass"` + Vendor string `xml:"vendor"` + PhysicalUnitNumber int32 `xml:"physicalUnitNumber"` +} + +func init() { + t["VirtualMachineScsiPassthroughInfo"] = reflect.TypeOf((*VirtualMachineScsiPassthroughInfo)(nil)).Elem() +} + +type VirtualMachineSerialInfo struct { + VirtualMachineTargetInfo +} + +func init() { + t["VirtualMachineSerialInfo"] = reflect.TypeOf((*VirtualMachineSerialInfo)(nil)).Elem() +} + +type VirtualMachineSnapshotInfo struct { + DynamicData + + CurrentSnapshot *ManagedObjectReference `xml:"currentSnapshot,omitempty"` + RootSnapshotList []VirtualMachineSnapshotTree `xml:"rootSnapshotList"` +} + +func init() { + t["VirtualMachineSnapshotInfo"] = reflect.TypeOf((*VirtualMachineSnapshotInfo)(nil)).Elem() +} + +type VirtualMachineSnapshotTree struct { + DynamicData + + Snapshot ManagedObjectReference `xml:"snapshot"` + Vm ManagedObjectReference `xml:"vm"` + Name string `xml:"name"` + Description string `xml:"description"` + Id int32 `xml:"id,omitempty"` + CreateTime time.Time `xml:"createTime"` + State VirtualMachinePowerState `xml:"state"` + Quiesced bool `xml:"quiesced"` + BackupManifest string `xml:"backupManifest,omitempty"` + ChildSnapshotList []VirtualMachineSnapshotTree `xml:"childSnapshotList,omitempty"` + ReplaySupported *bool `xml:"replaySupported"` +} + +func init() { + t["VirtualMachineSnapshotTree"] = reflect.TypeOf((*VirtualMachineSnapshotTree)(nil)).Elem() +} + +type VirtualMachineSoundInfo struct { + VirtualMachineTargetInfo +} + +func init() { + t["VirtualMachineSoundInfo"] = reflect.TypeOf((*VirtualMachineSoundInfo)(nil)).Elem() +} + +type VirtualMachineSriovInfo struct { + VirtualMachinePciPassthroughInfo + + VirtualFunction bool `xml:"virtualFunction"` + Pnic string `xml:"pnic,omitempty"` +} + +func init() { + t["VirtualMachineSriovInfo"] = reflect.TypeOf((*VirtualMachineSriovInfo)(nil)).Elem() +} + +type VirtualMachineStorageInfo struct { + DynamicData + + PerDatastoreUsage []VirtualMachineUsageOnDatastore `xml:"perDatastoreUsage,omitempty"` + Timestamp time.Time `xml:"timestamp"` +} + +func init() { + t["VirtualMachineStorageInfo"] = reflect.TypeOf((*VirtualMachineStorageInfo)(nil)).Elem() +} + +type VirtualMachineStorageSummary struct { + DynamicData + + Committed int64 `xml:"committed"` + Uncommitted int64 `xml:"uncommitted"` + Unshared int64 `xml:"unshared"` + Timestamp time.Time `xml:"timestamp"` +} + +func init() { + t["VirtualMachineStorageSummary"] = reflect.TypeOf((*VirtualMachineStorageSummary)(nil)).Elem() +} + +type VirtualMachineSummary struct { + DynamicData + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + Runtime VirtualMachineRuntimeInfo `xml:"runtime"` + Guest *VirtualMachineGuestSummary `xml:"guest,omitempty"` + Config VirtualMachineConfigSummary `xml:"config"` + Storage *VirtualMachineStorageSummary `xml:"storage,omitempty"` + QuickStats VirtualMachineQuickStats `xml:"quickStats"` + OverallStatus ManagedEntityStatus `xml:"overallStatus"` + CustomValue []BaseCustomFieldValue `xml:"customValue,omitempty,typeattr"` +} + +func init() { + t["VirtualMachineSummary"] = reflect.TypeOf((*VirtualMachineSummary)(nil)).Elem() +} + +type VirtualMachineTargetInfo struct { + DynamicData + + Name string `xml:"name"` + ConfigurationTag []string `xml:"configurationTag,omitempty"` +} + +func init() { + t["VirtualMachineTargetInfo"] = reflect.TypeOf((*VirtualMachineTargetInfo)(nil)).Elem() +} + +type VirtualMachineTicket struct { + DynamicData + + Ticket string `xml:"ticket"` + CfgFile string `xml:"cfgFile"` + Host string `xml:"host,omitempty"` + Port int32 `xml:"port,omitempty"` + SslThumbprint string `xml:"sslThumbprint,omitempty"` +} + +func init() { + t["VirtualMachineTicket"] = reflect.TypeOf((*VirtualMachineTicket)(nil)).Elem() +} + +type VirtualMachineUsageOnDatastore struct { + DynamicData + + Datastore ManagedObjectReference `xml:"datastore"` + Committed int64 `xml:"committed"` + Uncommitted int64 `xml:"uncommitted"` + Unshared int64 `xml:"unshared"` +} + +func init() { + t["VirtualMachineUsageOnDatastore"] = reflect.TypeOf((*VirtualMachineUsageOnDatastore)(nil)).Elem() +} + +type VirtualMachineUsbInfo struct { + VirtualMachineTargetInfo + + Description string `xml:"description"` + Vendor int32 `xml:"vendor"` + Product int32 `xml:"product"` + PhysicalPath string `xml:"physicalPath"` + Family []string `xml:"family,omitempty"` + Speed []string `xml:"speed,omitempty"` + Summary *VirtualMachineSummary `xml:"summary,omitempty"` +} + +func init() { + t["VirtualMachineUsbInfo"] = reflect.TypeOf((*VirtualMachineUsbInfo)(nil)).Elem() +} + +type VirtualMachineVFlashModuleInfo struct { + VirtualMachineTargetInfo + + VFlashModule HostVFlashManagerVFlashCacheConfigInfoVFlashModuleConfigOption `xml:"vFlashModule"` +} + +func init() { + t["VirtualMachineVFlashModuleInfo"] = reflect.TypeOf((*VirtualMachineVFlashModuleInfo)(nil)).Elem() +} + +type VirtualMachineVMCIDevice struct { + VirtualDevice + + Id int64 `xml:"id,omitempty"` + AllowUnrestrictedCommunication *bool `xml:"allowUnrestrictedCommunication"` + FilterEnable *bool `xml:"filterEnable"` + FilterInfo *VirtualMachineVMCIDeviceFilterInfo `xml:"filterInfo,omitempty"` +} + +func init() { + t["VirtualMachineVMCIDevice"] = reflect.TypeOf((*VirtualMachineVMCIDevice)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceFilterInfo struct { + DynamicData + + Filters []VirtualMachineVMCIDeviceFilterSpec `xml:"filters,omitempty"` +} + +func init() { + t["VirtualMachineVMCIDeviceFilterInfo"] = reflect.TypeOf((*VirtualMachineVMCIDeviceFilterInfo)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceFilterSpec struct { + DynamicData + + Rank int64 `xml:"rank"` + Action string `xml:"action"` + Protocol string `xml:"protocol"` + Direction string `xml:"direction"` + LowerDstPortBoundary int64 `xml:"lowerDstPortBoundary,omitempty"` + UpperDstPortBoundary int64 `xml:"upperDstPortBoundary,omitempty"` +} + +func init() { + t["VirtualMachineVMCIDeviceFilterSpec"] = reflect.TypeOf((*VirtualMachineVMCIDeviceFilterSpec)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceOption struct { + VirtualDeviceOption + + AllowUnrestrictedCommunication BoolOption `xml:"allowUnrestrictedCommunication"` + FilterSpecOption *VirtualMachineVMCIDeviceOptionFilterSpecOption `xml:"filterSpecOption,omitempty"` + FilterSupported *BoolOption `xml:"filterSupported,omitempty"` +} + +func init() { + t["VirtualMachineVMCIDeviceOption"] = reflect.TypeOf((*VirtualMachineVMCIDeviceOption)(nil)).Elem() +} + +type VirtualMachineVMCIDeviceOptionFilterSpecOption struct { + DynamicData + + Action ChoiceOption `xml:"action"` + Protocol ChoiceOption `xml:"protocol"` + Direction ChoiceOption `xml:"direction"` + LowerDstPortBoundary LongOption `xml:"lowerDstPortBoundary"` + UpperDstPortBoundary LongOption `xml:"upperDstPortBoundary"` +} + +func init() { + t["VirtualMachineVMCIDeviceOptionFilterSpecOption"] = reflect.TypeOf((*VirtualMachineVMCIDeviceOptionFilterSpecOption)(nil)).Elem() +} + +type VirtualMachineVMIROM struct { + VirtualDevice +} + +func init() { + t["VirtualMachineVMIROM"] = reflect.TypeOf((*VirtualMachineVMIROM)(nil)).Elem() +} + +type VirtualMachineVideoCard struct { + VirtualDevice + + VideoRamSizeInKB int64 `xml:"videoRamSizeInKB,omitempty"` + NumDisplays int32 `xml:"numDisplays,omitempty"` + UseAutoDetect *bool `xml:"useAutoDetect"` + Enable3DSupport *bool `xml:"enable3DSupport"` + Use3dRenderer string `xml:"use3dRenderer,omitempty"` + GraphicsMemorySizeInKB int64 `xml:"graphicsMemorySizeInKB,omitempty"` +} + +func init() { + t["VirtualMachineVideoCard"] = reflect.TypeOf((*VirtualMachineVideoCard)(nil)).Elem() +} + +type VirtualMachineWipeResult struct { + DynamicData + + DiskId int32 `xml:"diskId"` + ShrinkableDiskSpace int64 `xml:"shrinkableDiskSpace"` +} + +func init() { + t["VirtualMachineWipeResult"] = reflect.TypeOf((*VirtualMachineWipeResult)(nil)).Elem() +} + +type VirtualNicManagerNetConfig struct { + DynamicData + + NicType string `xml:"nicType"` + MultiSelectAllowed bool `xml:"multiSelectAllowed"` + CandidateVnic []HostVirtualNic `xml:"candidateVnic,omitempty"` + SelectedVnic []string `xml:"selectedVnic,omitempty"` +} + +func init() { + t["VirtualNicManagerNetConfig"] = reflect.TypeOf((*VirtualNicManagerNetConfig)(nil)).Elem() +} + +type VirtualPCIController struct { + VirtualController +} + +func init() { + t["VirtualPCIController"] = reflect.TypeOf((*VirtualPCIController)(nil)).Elem() +} + +type VirtualPCIControllerOption struct { + VirtualControllerOption + + NumSCSIControllers IntOption `xml:"numSCSIControllers"` + NumEthernetCards IntOption `xml:"numEthernetCards"` + NumVideoCards IntOption `xml:"numVideoCards"` + NumSoundCards IntOption `xml:"numSoundCards"` + NumVmiRoms IntOption `xml:"numVmiRoms"` + NumVmciDevices *IntOption `xml:"numVmciDevices,omitempty"` + NumPCIPassthroughDevices *IntOption `xml:"numPCIPassthroughDevices,omitempty"` + NumSasSCSIControllers *IntOption `xml:"numSasSCSIControllers,omitempty"` + NumVmxnet3EthernetCards *IntOption `xml:"numVmxnet3EthernetCards,omitempty"` + NumParaVirtualSCSIControllers *IntOption `xml:"numParaVirtualSCSIControllers,omitempty"` + NumSATAControllers *IntOption `xml:"numSATAControllers,omitempty"` +} + +func init() { + t["VirtualPCIControllerOption"] = reflect.TypeOf((*VirtualPCIControllerOption)(nil)).Elem() +} + +type VirtualPCIPassthrough struct { + VirtualDevice +} + +func init() { + t["VirtualPCIPassthrough"] = reflect.TypeOf((*VirtualPCIPassthrough)(nil)).Elem() +} + +type VirtualPCIPassthroughDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo + + Id string `xml:"id"` + DeviceId string `xml:"deviceId"` + SystemId string `xml:"systemId"` + VendorId int16 `xml:"vendorId"` +} + +func init() { + t["VirtualPCIPassthroughDeviceBackingInfo"] = reflect.TypeOf((*VirtualPCIPassthroughDeviceBackingInfo)(nil)).Elem() +} + +type VirtualPCIPassthroughDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualPCIPassthroughDeviceBackingOption"] = reflect.TypeOf((*VirtualPCIPassthroughDeviceBackingOption)(nil)).Elem() +} + +type VirtualPCIPassthroughOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualPCIPassthroughOption"] = reflect.TypeOf((*VirtualPCIPassthroughOption)(nil)).Elem() +} + +type VirtualPCIPassthroughPluginBackingInfo struct { + VirtualDeviceBackingInfo +} + +func init() { + t["VirtualPCIPassthroughPluginBackingInfo"] = reflect.TypeOf((*VirtualPCIPassthroughPluginBackingInfo)(nil)).Elem() +} + +type VirtualPCIPassthroughPluginBackingOption struct { + VirtualDeviceBackingOption +} + +func init() { + t["VirtualPCIPassthroughPluginBackingOption"] = reflect.TypeOf((*VirtualPCIPassthroughPluginBackingOption)(nil)).Elem() +} + +type VirtualPCIPassthroughVmiopBackingInfo struct { + VirtualPCIPassthroughPluginBackingInfo + + Vgpu string `xml:"vgpu,omitempty"` +} + +func init() { + t["VirtualPCIPassthroughVmiopBackingInfo"] = reflect.TypeOf((*VirtualPCIPassthroughVmiopBackingInfo)(nil)).Elem() +} + +type VirtualPCIPassthroughVmiopBackingOption struct { + VirtualPCIPassthroughPluginBackingOption + + Vgpu StringOption `xml:"vgpu"` + MaxInstances int32 `xml:"maxInstances"` +} + +func init() { + t["VirtualPCIPassthroughVmiopBackingOption"] = reflect.TypeOf((*VirtualPCIPassthroughVmiopBackingOption)(nil)).Elem() +} + +type VirtualPCNet32 struct { + VirtualEthernetCard +} + +func init() { + t["VirtualPCNet32"] = reflect.TypeOf((*VirtualPCNet32)(nil)).Elem() +} + +type VirtualPCNet32Option struct { + VirtualEthernetCardOption + + SupportsMorphing bool `xml:"supportsMorphing"` +} + +func init() { + t["VirtualPCNet32Option"] = reflect.TypeOf((*VirtualPCNet32Option)(nil)).Elem() +} + +type VirtualPS2Controller struct { + VirtualController +} + +func init() { + t["VirtualPS2Controller"] = reflect.TypeOf((*VirtualPS2Controller)(nil)).Elem() +} + +type VirtualPS2ControllerOption struct { + VirtualControllerOption + + NumKeyboards IntOption `xml:"numKeyboards"` + NumPointingDevices IntOption `xml:"numPointingDevices"` +} + +func init() { + t["VirtualPS2ControllerOption"] = reflect.TypeOf((*VirtualPS2ControllerOption)(nil)).Elem() +} + +type VirtualParallelPort struct { + VirtualDevice +} + +func init() { + t["VirtualParallelPort"] = reflect.TypeOf((*VirtualParallelPort)(nil)).Elem() +} + +type VirtualParallelPortDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualParallelPortDeviceBackingInfo"] = reflect.TypeOf((*VirtualParallelPortDeviceBackingInfo)(nil)).Elem() +} + +type VirtualParallelPortDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualParallelPortDeviceBackingOption"] = reflect.TypeOf((*VirtualParallelPortDeviceBackingOption)(nil)).Elem() +} + +type VirtualParallelPortFileBackingInfo struct { + VirtualDeviceFileBackingInfo +} + +func init() { + t["VirtualParallelPortFileBackingInfo"] = reflect.TypeOf((*VirtualParallelPortFileBackingInfo)(nil)).Elem() +} + +type VirtualParallelPortFileBackingOption struct { + VirtualDeviceFileBackingOption +} + +func init() { + t["VirtualParallelPortFileBackingOption"] = reflect.TypeOf((*VirtualParallelPortFileBackingOption)(nil)).Elem() +} + +type VirtualParallelPortOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualParallelPortOption"] = reflect.TypeOf((*VirtualParallelPortOption)(nil)).Elem() +} + +type VirtualPointingDevice struct { + VirtualDevice +} + +func init() { + t["VirtualPointingDevice"] = reflect.TypeOf((*VirtualPointingDevice)(nil)).Elem() +} + +type VirtualPointingDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption + + HostPointingDevice ChoiceOption `xml:"hostPointingDevice"` +} + +func init() { + t["VirtualPointingDeviceBackingOption"] = reflect.TypeOf((*VirtualPointingDeviceBackingOption)(nil)).Elem() +} + +type VirtualPointingDeviceDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo + + HostPointingDevice string `xml:"hostPointingDevice"` +} + +func init() { + t["VirtualPointingDeviceDeviceBackingInfo"] = reflect.TypeOf((*VirtualPointingDeviceDeviceBackingInfo)(nil)).Elem() +} + +type VirtualPointingDeviceOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualPointingDeviceOption"] = reflect.TypeOf((*VirtualPointingDeviceOption)(nil)).Elem() +} + +type VirtualResourcePoolSpec struct { + DynamicData + + VrpId string `xml:"vrpId,omitempty"` + VrpName string `xml:"vrpName,omitempty"` + Description string `xml:"description,omitempty"` + CpuAllocation VrpResourceAllocationInfo `xml:"cpuAllocation"` + MemoryAllocation VrpResourceAllocationInfo `xml:"memoryAllocation"` + RpList []ManagedObjectReference `xml:"rpList,omitempty"` + HubList []ManagedObjectReference `xml:"hubList,omitempty"` + RootVRP *bool `xml:"rootVRP"` + StaticVRP *bool `xml:"staticVRP"` + ChangeVersion int64 `xml:"changeVersion,omitempty"` +} + +func init() { + t["VirtualResourcePoolSpec"] = reflect.TypeOf((*VirtualResourcePoolSpec)(nil)).Elem() +} + +type VirtualResourcePoolUsage struct { + DynamicData + + VrpId string `xml:"vrpId"` + CpuReservationMhz int64 `xml:"cpuReservationMhz"` + MemReservationMB int64 `xml:"memReservationMB"` + CpuReservationUsedMhz int64 `xml:"cpuReservationUsedMhz"` + MemReservationUsedMB int64 `xml:"memReservationUsedMB"` +} + +func init() { + t["VirtualResourcePoolUsage"] = reflect.TypeOf((*VirtualResourcePoolUsage)(nil)).Elem() +} + +type VirtualSATAController struct { + VirtualController +} + +func init() { + t["VirtualSATAController"] = reflect.TypeOf((*VirtualSATAController)(nil)).Elem() +} + +type VirtualSATAControllerOption struct { + VirtualControllerOption + + NumSATADisks IntOption `xml:"numSATADisks"` + NumSATACdroms IntOption `xml:"numSATACdroms"` +} + +func init() { + t["VirtualSATAControllerOption"] = reflect.TypeOf((*VirtualSATAControllerOption)(nil)).Elem() +} + +type VirtualSCSIController struct { + VirtualController + + HotAddRemove *bool `xml:"hotAddRemove"` + SharedBus VirtualSCSISharing `xml:"sharedBus"` + ScsiCtlrUnitNumber int32 `xml:"scsiCtlrUnitNumber,omitempty"` +} + +func init() { + t["VirtualSCSIController"] = reflect.TypeOf((*VirtualSCSIController)(nil)).Elem() +} + +type VirtualSCSIControllerOption struct { + VirtualControllerOption + + NumSCSIDisks IntOption `xml:"numSCSIDisks"` + NumSCSICdroms IntOption `xml:"numSCSICdroms"` + NumSCSIPassthrough IntOption `xml:"numSCSIPassthrough"` + Sharing []VirtualSCSISharing `xml:"sharing"` + DefaultSharedIndex int32 `xml:"defaultSharedIndex"` + HotAddRemove BoolOption `xml:"hotAddRemove"` + ScsiCtlrUnitNumber int32 `xml:"scsiCtlrUnitNumber"` +} + +func init() { + t["VirtualSCSIControllerOption"] = reflect.TypeOf((*VirtualSCSIControllerOption)(nil)).Elem() +} + +type VirtualSCSIPassthrough struct { + VirtualDevice +} + +func init() { + t["VirtualSCSIPassthrough"] = reflect.TypeOf((*VirtualSCSIPassthrough)(nil)).Elem() +} + +type VirtualSCSIPassthroughDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualSCSIPassthroughDeviceBackingInfo"] = reflect.TypeOf((*VirtualSCSIPassthroughDeviceBackingInfo)(nil)).Elem() +} + +type VirtualSCSIPassthroughDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualSCSIPassthroughDeviceBackingOption"] = reflect.TypeOf((*VirtualSCSIPassthroughDeviceBackingOption)(nil)).Elem() +} + +type VirtualSCSIPassthroughOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualSCSIPassthroughOption"] = reflect.TypeOf((*VirtualSCSIPassthroughOption)(nil)).Elem() +} + +type VirtualSIOController struct { + VirtualController +} + +func init() { + t["VirtualSIOController"] = reflect.TypeOf((*VirtualSIOController)(nil)).Elem() +} + +type VirtualSIOControllerOption struct { + VirtualControllerOption + + NumFloppyDrives IntOption `xml:"numFloppyDrives"` + NumSerialPorts IntOption `xml:"numSerialPorts"` + NumParallelPorts IntOption `xml:"numParallelPorts"` +} + +func init() { + t["VirtualSIOControllerOption"] = reflect.TypeOf((*VirtualSIOControllerOption)(nil)).Elem() +} + +type VirtualSerialPort struct { + VirtualDevice + + YieldOnPoll bool `xml:"yieldOnPoll"` +} + +func init() { + t["VirtualSerialPort"] = reflect.TypeOf((*VirtualSerialPort)(nil)).Elem() +} + +type VirtualSerialPortDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualSerialPortDeviceBackingInfo"] = reflect.TypeOf((*VirtualSerialPortDeviceBackingInfo)(nil)).Elem() +} + +type VirtualSerialPortDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualSerialPortDeviceBackingOption"] = reflect.TypeOf((*VirtualSerialPortDeviceBackingOption)(nil)).Elem() +} + +type VirtualSerialPortFileBackingInfo struct { + VirtualDeviceFileBackingInfo +} + +func init() { + t["VirtualSerialPortFileBackingInfo"] = reflect.TypeOf((*VirtualSerialPortFileBackingInfo)(nil)).Elem() +} + +type VirtualSerialPortFileBackingOption struct { + VirtualDeviceFileBackingOption +} + +func init() { + t["VirtualSerialPortFileBackingOption"] = reflect.TypeOf((*VirtualSerialPortFileBackingOption)(nil)).Elem() +} + +type VirtualSerialPortOption struct { + VirtualDeviceOption + + YieldOnPoll BoolOption `xml:"yieldOnPoll"` +} + +func init() { + t["VirtualSerialPortOption"] = reflect.TypeOf((*VirtualSerialPortOption)(nil)).Elem() +} + +type VirtualSerialPortPipeBackingInfo struct { + VirtualDevicePipeBackingInfo + + Endpoint string `xml:"endpoint"` + NoRxLoss *bool `xml:"noRxLoss"` +} + +func init() { + t["VirtualSerialPortPipeBackingInfo"] = reflect.TypeOf((*VirtualSerialPortPipeBackingInfo)(nil)).Elem() +} + +type VirtualSerialPortPipeBackingOption struct { + VirtualDevicePipeBackingOption + + Endpoint ChoiceOption `xml:"endpoint"` + NoRxLoss BoolOption `xml:"noRxLoss"` +} + +func init() { + t["VirtualSerialPortPipeBackingOption"] = reflect.TypeOf((*VirtualSerialPortPipeBackingOption)(nil)).Elem() +} + +type VirtualSerialPortThinPrintBackingInfo struct { + VirtualDeviceBackingInfo +} + +func init() { + t["VirtualSerialPortThinPrintBackingInfo"] = reflect.TypeOf((*VirtualSerialPortThinPrintBackingInfo)(nil)).Elem() +} + +type VirtualSerialPortThinPrintBackingOption struct { + VirtualDeviceBackingOption +} + +func init() { + t["VirtualSerialPortThinPrintBackingOption"] = reflect.TypeOf((*VirtualSerialPortThinPrintBackingOption)(nil)).Elem() +} + +type VirtualSerialPortURIBackingInfo struct { + VirtualDeviceURIBackingInfo +} + +func init() { + t["VirtualSerialPortURIBackingInfo"] = reflect.TypeOf((*VirtualSerialPortURIBackingInfo)(nil)).Elem() +} + +type VirtualSerialPortURIBackingOption struct { + VirtualDeviceURIBackingOption +} + +func init() { + t["VirtualSerialPortURIBackingOption"] = reflect.TypeOf((*VirtualSerialPortURIBackingOption)(nil)).Elem() +} + +type VirtualSoundBlaster16 struct { + VirtualSoundCard +} + +func init() { + t["VirtualSoundBlaster16"] = reflect.TypeOf((*VirtualSoundBlaster16)(nil)).Elem() +} + +type VirtualSoundBlaster16Option struct { + VirtualSoundCardOption +} + +func init() { + t["VirtualSoundBlaster16Option"] = reflect.TypeOf((*VirtualSoundBlaster16Option)(nil)).Elem() +} + +type VirtualSoundCard struct { + VirtualDevice +} + +func init() { + t["VirtualSoundCard"] = reflect.TypeOf((*VirtualSoundCard)(nil)).Elem() +} + +type VirtualSoundCardDeviceBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualSoundCardDeviceBackingInfo"] = reflect.TypeOf((*VirtualSoundCardDeviceBackingInfo)(nil)).Elem() +} + +type VirtualSoundCardDeviceBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualSoundCardDeviceBackingOption"] = reflect.TypeOf((*VirtualSoundCardDeviceBackingOption)(nil)).Elem() +} + +type VirtualSoundCardOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualSoundCardOption"] = reflect.TypeOf((*VirtualSoundCardOption)(nil)).Elem() +} + +type VirtualSriovEthernetCard struct { + VirtualEthernetCard + + AllowGuestOSMtuChange *bool `xml:"allowGuestOSMtuChange"` + SriovBacking *VirtualSriovEthernetCardSriovBackingInfo `xml:"sriovBacking,omitempty"` +} + +func init() { + t["VirtualSriovEthernetCard"] = reflect.TypeOf((*VirtualSriovEthernetCard)(nil)).Elem() +} + +type VirtualSriovEthernetCardOption struct { + VirtualEthernetCardOption +} + +func init() { + t["VirtualSriovEthernetCardOption"] = reflect.TypeOf((*VirtualSriovEthernetCardOption)(nil)).Elem() +} + +type VirtualSriovEthernetCardSriovBackingInfo struct { + VirtualDeviceBackingInfo + + PhysicalFunctionBacking *VirtualPCIPassthroughDeviceBackingInfo `xml:"physicalFunctionBacking,omitempty"` + VirtualFunctionBacking *VirtualPCIPassthroughDeviceBackingInfo `xml:"virtualFunctionBacking,omitempty"` + VirtualFunctionIndex int32 `xml:"virtualFunctionIndex,omitempty"` +} + +func init() { + t["VirtualSriovEthernetCardSriovBackingInfo"] = reflect.TypeOf((*VirtualSriovEthernetCardSriovBackingInfo)(nil)).Elem() +} + +type VirtualSriovEthernetCardSriovBackingOption struct { + VirtualDeviceBackingOption +} + +func init() { + t["VirtualSriovEthernetCardSriovBackingOption"] = reflect.TypeOf((*VirtualSriovEthernetCardSriovBackingOption)(nil)).Elem() +} + +type VirtualSwitchProfile struct { + ApplyProfile + + Key string `xml:"key"` + Name string `xml:"name"` + Link LinkProfile `xml:"link"` + NumPorts NumPortsProfile `xml:"numPorts"` + NetworkPolicy NetworkPolicyProfile `xml:"networkPolicy"` +} + +func init() { + t["VirtualSwitchProfile"] = reflect.TypeOf((*VirtualSwitchProfile)(nil)).Elem() +} + +type VirtualSwitchSelectionProfile struct { + ApplyProfile +} + +func init() { + t["VirtualSwitchSelectionProfile"] = reflect.TypeOf((*VirtualSwitchSelectionProfile)(nil)).Elem() +} + +type VirtualUSB struct { + VirtualDevice + + Connected bool `xml:"connected"` + Vendor int32 `xml:"vendor,omitempty"` + Product int32 `xml:"product,omitempty"` + Family []string `xml:"family,omitempty"` + Speed []string `xml:"speed,omitempty"` +} + +func init() { + t["VirtualUSB"] = reflect.TypeOf((*VirtualUSB)(nil)).Elem() +} + +type VirtualUSBController struct { + VirtualController + + AutoConnectDevices *bool `xml:"autoConnectDevices"` + EhciEnabled *bool `xml:"ehciEnabled"` +} + +func init() { + t["VirtualUSBController"] = reflect.TypeOf((*VirtualUSBController)(nil)).Elem() +} + +type VirtualUSBControllerOption struct { + VirtualControllerOption + + AutoConnectDevices BoolOption `xml:"autoConnectDevices"` + EhciSupported BoolOption `xml:"ehciSupported"` + SupportedSpeeds []string `xml:"supportedSpeeds,omitempty"` +} + +func init() { + t["VirtualUSBControllerOption"] = reflect.TypeOf((*VirtualUSBControllerOption)(nil)).Elem() +} + +type VirtualUSBControllerPciBusSlotInfo struct { + VirtualDevicePciBusSlotInfo + + EhciPciSlotNumber int32 `xml:"ehciPciSlotNumber,omitempty"` +} + +func init() { + t["VirtualUSBControllerPciBusSlotInfo"] = reflect.TypeOf((*VirtualUSBControllerPciBusSlotInfo)(nil)).Elem() +} + +type VirtualUSBOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualUSBOption"] = reflect.TypeOf((*VirtualUSBOption)(nil)).Elem() +} + +type VirtualUSBRemoteClientBackingInfo struct { + VirtualDeviceRemoteDeviceBackingInfo + + Hostname string `xml:"hostname"` +} + +func init() { + t["VirtualUSBRemoteClientBackingInfo"] = reflect.TypeOf((*VirtualUSBRemoteClientBackingInfo)(nil)).Elem() +} + +type VirtualUSBRemoteClientBackingOption struct { + VirtualDeviceRemoteDeviceBackingOption +} + +func init() { + t["VirtualUSBRemoteClientBackingOption"] = reflect.TypeOf((*VirtualUSBRemoteClientBackingOption)(nil)).Elem() +} + +type VirtualUSBRemoteHostBackingInfo struct { + VirtualDeviceDeviceBackingInfo + + Hostname string `xml:"hostname"` +} + +func init() { + t["VirtualUSBRemoteHostBackingInfo"] = reflect.TypeOf((*VirtualUSBRemoteHostBackingInfo)(nil)).Elem() +} + +type VirtualUSBRemoteHostBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualUSBRemoteHostBackingOption"] = reflect.TypeOf((*VirtualUSBRemoteHostBackingOption)(nil)).Elem() +} + +type VirtualUSBUSBBackingInfo struct { + VirtualDeviceDeviceBackingInfo +} + +func init() { + t["VirtualUSBUSBBackingInfo"] = reflect.TypeOf((*VirtualUSBUSBBackingInfo)(nil)).Elem() +} + +type VirtualUSBUSBBackingOption struct { + VirtualDeviceDeviceBackingOption +} + +func init() { + t["VirtualUSBUSBBackingOption"] = reflect.TypeOf((*VirtualUSBUSBBackingOption)(nil)).Elem() +} + +type VirtualUSBXHCIController struct { + VirtualController + + AutoConnectDevices *bool `xml:"autoConnectDevices"` +} + +func init() { + t["VirtualUSBXHCIController"] = reflect.TypeOf((*VirtualUSBXHCIController)(nil)).Elem() +} + +type VirtualUSBXHCIControllerOption struct { + VirtualControllerOption + + AutoConnectDevices BoolOption `xml:"autoConnectDevices"` + SupportedSpeeds []string `xml:"supportedSpeeds"` +} + +func init() { + t["VirtualUSBXHCIControllerOption"] = reflect.TypeOf((*VirtualUSBXHCIControllerOption)(nil)).Elem() +} + +type VirtualVMIROMOption struct { + VirtualDeviceOption +} + +func init() { + t["VirtualVMIROMOption"] = reflect.TypeOf((*VirtualVMIROMOption)(nil)).Elem() +} + +type VirtualVideoCardOption struct { + VirtualDeviceOption + + VideoRamSizeInKB *LongOption `xml:"videoRamSizeInKB,omitempty"` + NumDisplays *IntOption `xml:"numDisplays,omitempty"` + UseAutoDetect *BoolOption `xml:"useAutoDetect,omitempty"` + Support3D *BoolOption `xml:"support3D,omitempty"` + Use3dRendererSupported *BoolOption `xml:"use3dRendererSupported,omitempty"` + GraphicsMemorySizeInKB *LongOption `xml:"graphicsMemorySizeInKB,omitempty"` + GraphicsMemorySizeSupported *BoolOption `xml:"graphicsMemorySizeSupported,omitempty"` +} + +func init() { + t["VirtualVideoCardOption"] = reflect.TypeOf((*VirtualVideoCardOption)(nil)).Elem() +} + +type VirtualVmxnet struct { + VirtualEthernetCard +} + +func init() { + t["VirtualVmxnet"] = reflect.TypeOf((*VirtualVmxnet)(nil)).Elem() +} + +type VirtualVmxnet2 struct { + VirtualVmxnet +} + +func init() { + t["VirtualVmxnet2"] = reflect.TypeOf((*VirtualVmxnet2)(nil)).Elem() +} + +type VirtualVmxnet2Option struct { + VirtualVmxnetOption +} + +func init() { + t["VirtualVmxnet2Option"] = reflect.TypeOf((*VirtualVmxnet2Option)(nil)).Elem() +} + +type VirtualVmxnet3 struct { + VirtualVmxnet +} + +func init() { + t["VirtualVmxnet3"] = reflect.TypeOf((*VirtualVmxnet3)(nil)).Elem() +} + +type VirtualVmxnet3Option struct { + VirtualVmxnetOption +} + +func init() { + t["VirtualVmxnet3Option"] = reflect.TypeOf((*VirtualVmxnet3Option)(nil)).Elem() +} + +type VirtualVmxnetOption struct { + VirtualEthernetCardOption +} + +func init() { + t["VirtualVmxnetOption"] = reflect.TypeOf((*VirtualVmxnetOption)(nil)).Elem() +} + +type VlanProfile struct { + ApplyProfile +} + +func init() { + t["VlanProfile"] = reflect.TypeOf((*VlanProfile)(nil)).Elem() +} + +type VmAcquiredMksTicketEvent struct { + VmEvent +} + +func init() { + t["VmAcquiredMksTicketEvent"] = reflect.TypeOf((*VmAcquiredMksTicketEvent)(nil)).Elem() +} + +type VmAcquiredTicketEvent struct { + VmEvent + + TicketType string `xml:"ticketType"` +} + +func init() { + t["VmAcquiredTicketEvent"] = reflect.TypeOf((*VmAcquiredTicketEvent)(nil)).Elem() +} + +type VmAlreadyExistsInDatacenter struct { + InvalidFolder + + Host ManagedObjectReference `xml:"host"` + Hostname string `xml:"hostname"` + Vm []ManagedObjectReference `xml:"vm"` +} + +func init() { + t["VmAlreadyExistsInDatacenter"] = reflect.TypeOf((*VmAlreadyExistsInDatacenter)(nil)).Elem() +} + +type VmAlreadyExistsInDatacenterFault VmAlreadyExistsInDatacenter + +func init() { + t["VmAlreadyExistsInDatacenterFault"] = reflect.TypeOf((*VmAlreadyExistsInDatacenterFault)(nil)).Elem() +} + +type VmAutoRenameEvent struct { + VmEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["VmAutoRenameEvent"] = reflect.TypeOf((*VmAutoRenameEvent)(nil)).Elem() +} + +type VmBeingClonedEvent struct { + VmCloneEvent + + DestFolder FolderEventArgument `xml:"destFolder"` + DestName string `xml:"destName"` + DestHost HostEventArgument `xml:"destHost"` +} + +func init() { + t["VmBeingClonedEvent"] = reflect.TypeOf((*VmBeingClonedEvent)(nil)).Elem() +} + +type VmBeingClonedNoFolderEvent struct { + VmCloneEvent + + DestName string `xml:"destName"` + DestHost HostEventArgument `xml:"destHost"` +} + +func init() { + t["VmBeingClonedNoFolderEvent"] = reflect.TypeOf((*VmBeingClonedNoFolderEvent)(nil)).Elem() +} + +type VmBeingCreatedEvent struct { + VmEvent + + ConfigSpec *VirtualMachineConfigSpec `xml:"configSpec,omitempty"` +} + +func init() { + t["VmBeingCreatedEvent"] = reflect.TypeOf((*VmBeingCreatedEvent)(nil)).Elem() +} + +type VmBeingDeployedEvent struct { + VmEvent + + SrcTemplate VmEventArgument `xml:"srcTemplate"` +} + +func init() { + t["VmBeingDeployedEvent"] = reflect.TypeOf((*VmBeingDeployedEvent)(nil)).Elem() +} + +type VmBeingHotMigratedEvent struct { + VmEvent + + DestHost HostEventArgument `xml:"destHost"` + DestDatacenter *DatacenterEventArgument `xml:"destDatacenter,omitempty"` + DestDatastore *DatastoreEventArgument `xml:"destDatastore,omitempty"` +} + +func init() { + t["VmBeingHotMigratedEvent"] = reflect.TypeOf((*VmBeingHotMigratedEvent)(nil)).Elem() +} + +type VmBeingMigratedEvent struct { + VmEvent + + DestHost HostEventArgument `xml:"destHost"` + DestDatacenter *DatacenterEventArgument `xml:"destDatacenter,omitempty"` + DestDatastore *DatastoreEventArgument `xml:"destDatastore,omitempty"` +} + +func init() { + t["VmBeingMigratedEvent"] = reflect.TypeOf((*VmBeingMigratedEvent)(nil)).Elem() +} + +type VmBeingRelocatedEvent struct { + VmRelocateSpecEvent + + DestHost HostEventArgument `xml:"destHost"` + DestDatacenter *DatacenterEventArgument `xml:"destDatacenter,omitempty"` + DestDatastore *DatastoreEventArgument `xml:"destDatastore,omitempty"` +} + +func init() { + t["VmBeingRelocatedEvent"] = reflect.TypeOf((*VmBeingRelocatedEvent)(nil)).Elem() +} + +type VmCloneEvent struct { + VmEvent +} + +func init() { + t["VmCloneEvent"] = reflect.TypeOf((*VmCloneEvent)(nil)).Elem() +} + +type VmCloneFailedEvent struct { + VmCloneEvent + + DestFolder FolderEventArgument `xml:"destFolder"` + DestName string `xml:"destName"` + DestHost HostEventArgument `xml:"destHost"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmCloneFailedEvent"] = reflect.TypeOf((*VmCloneFailedEvent)(nil)).Elem() +} + +type VmClonedEvent struct { + VmCloneEvent + + SourceVm VmEventArgument `xml:"sourceVm"` +} + +func init() { + t["VmClonedEvent"] = reflect.TypeOf((*VmClonedEvent)(nil)).Elem() +} + +type VmConfigFault struct { + VimFault +} + +func init() { + t["VmConfigFault"] = reflect.TypeOf((*VmConfigFault)(nil)).Elem() +} + +type VmConfigFaultFault BaseVmConfigFault + +func init() { + t["VmConfigFaultFault"] = reflect.TypeOf((*VmConfigFaultFault)(nil)).Elem() +} + +type VmConfigFileInfo struct { + FileInfo + + ConfigVersion int32 `xml:"configVersion,omitempty"` +} + +func init() { + t["VmConfigFileInfo"] = reflect.TypeOf((*VmConfigFileInfo)(nil)).Elem() +} + +type VmConfigFileQuery struct { + FileQuery + + Filter *VmConfigFileQueryFilter `xml:"filter,omitempty"` + Details *VmConfigFileQueryFlags `xml:"details,omitempty"` +} + +func init() { + t["VmConfigFileQuery"] = reflect.TypeOf((*VmConfigFileQuery)(nil)).Elem() +} + +type VmConfigFileQueryFilter struct { + DynamicData + + MatchConfigVersion []int32 `xml:"matchConfigVersion,omitempty"` +} + +func init() { + t["VmConfigFileQueryFilter"] = reflect.TypeOf((*VmConfigFileQueryFilter)(nil)).Elem() +} + +type VmConfigFileQueryFlags struct { + DynamicData + + ConfigVersion bool `xml:"configVersion"` +} + +func init() { + t["VmConfigFileQueryFlags"] = reflect.TypeOf((*VmConfigFileQueryFlags)(nil)).Elem() +} + +type VmConfigIncompatibleForFaultTolerance struct { + VmConfigFault + + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["VmConfigIncompatibleForFaultTolerance"] = reflect.TypeOf((*VmConfigIncompatibleForFaultTolerance)(nil)).Elem() +} + +type VmConfigIncompatibleForFaultToleranceFault VmConfigIncompatibleForFaultTolerance + +func init() { + t["VmConfigIncompatibleForFaultToleranceFault"] = reflect.TypeOf((*VmConfigIncompatibleForFaultToleranceFault)(nil)).Elem() +} + +type VmConfigIncompatibleForRecordReplay struct { + VmConfigFault + + Fault *LocalizedMethodFault `xml:"fault,omitempty"` +} + +func init() { + t["VmConfigIncompatibleForRecordReplay"] = reflect.TypeOf((*VmConfigIncompatibleForRecordReplay)(nil)).Elem() +} + +type VmConfigIncompatibleForRecordReplayFault VmConfigIncompatibleForRecordReplay + +func init() { + t["VmConfigIncompatibleForRecordReplayFault"] = reflect.TypeOf((*VmConfigIncompatibleForRecordReplayFault)(nil)).Elem() +} + +type VmConfigInfo struct { + DynamicData + + Product []VAppProductInfo `xml:"product,omitempty"` + Property []VAppPropertyInfo `xml:"property,omitempty"` + IpAssignment VAppIPAssignmentInfo `xml:"ipAssignment"` + Eula []string `xml:"eula,omitempty"` + OvfSection []VAppOvfSectionInfo `xml:"ovfSection,omitempty"` + OvfEnvironmentTransport []string `xml:"ovfEnvironmentTransport,omitempty"` + InstallBootRequired bool `xml:"installBootRequired"` + InstallBootStopDelay int32 `xml:"installBootStopDelay"` +} + +func init() { + t["VmConfigInfo"] = reflect.TypeOf((*VmConfigInfo)(nil)).Elem() +} + +type VmConfigMissingEvent struct { + VmEvent +} + +func init() { + t["VmConfigMissingEvent"] = reflect.TypeOf((*VmConfigMissingEvent)(nil)).Elem() +} + +type VmConfigSpec struct { + DynamicData + + Product []VAppProductSpec `xml:"product,omitempty"` + Property []VAppPropertySpec `xml:"property,omitempty"` + IpAssignment *VAppIPAssignmentInfo `xml:"ipAssignment,omitempty"` + Eula []string `xml:"eula,omitempty"` + OvfSection []VAppOvfSectionSpec `xml:"ovfSection,omitempty"` + OvfEnvironmentTransport []string `xml:"ovfEnvironmentTransport,omitempty"` + InstallBootRequired *bool `xml:"installBootRequired"` + InstallBootStopDelay int32 `xml:"installBootStopDelay,omitempty"` +} + +func init() { + t["VmConfigSpec"] = reflect.TypeOf((*VmConfigSpec)(nil)).Elem() +} + +type VmConnectedEvent struct { + VmEvent +} + +func init() { + t["VmConnectedEvent"] = reflect.TypeOf((*VmConnectedEvent)(nil)).Elem() +} + +type VmCreatedEvent struct { + VmEvent +} + +func init() { + t["VmCreatedEvent"] = reflect.TypeOf((*VmCreatedEvent)(nil)).Elem() +} + +type VmDasBeingResetEvent struct { + VmEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["VmDasBeingResetEvent"] = reflect.TypeOf((*VmDasBeingResetEvent)(nil)).Elem() +} + +type VmDasBeingResetWithScreenshotEvent struct { + VmDasBeingResetEvent + + ScreenshotFilePath string `xml:"screenshotFilePath"` +} + +func init() { + t["VmDasBeingResetWithScreenshotEvent"] = reflect.TypeOf((*VmDasBeingResetWithScreenshotEvent)(nil)).Elem() +} + +type VmDasResetFailedEvent struct { + VmEvent +} + +func init() { + t["VmDasResetFailedEvent"] = reflect.TypeOf((*VmDasResetFailedEvent)(nil)).Elem() +} + +type VmDasUpdateErrorEvent struct { + VmEvent +} + +func init() { + t["VmDasUpdateErrorEvent"] = reflect.TypeOf((*VmDasUpdateErrorEvent)(nil)).Elem() +} + +type VmDasUpdateOkEvent struct { + VmEvent +} + +func init() { + t["VmDasUpdateOkEvent"] = reflect.TypeOf((*VmDasUpdateOkEvent)(nil)).Elem() +} + +type VmDateRolledBackEvent struct { + VmEvent +} + +func init() { + t["VmDateRolledBackEvent"] = reflect.TypeOf((*VmDateRolledBackEvent)(nil)).Elem() +} + +type VmDeployFailedEvent struct { + VmEvent + + DestDatastore BaseEntityEventArgument `xml:"destDatastore,typeattr"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmDeployFailedEvent"] = reflect.TypeOf((*VmDeployFailedEvent)(nil)).Elem() +} + +type VmDeployedEvent struct { + VmEvent + + SrcTemplate VmEventArgument `xml:"srcTemplate"` +} + +func init() { + t["VmDeployedEvent"] = reflect.TypeOf((*VmDeployedEvent)(nil)).Elem() +} + +type VmDisconnectedEvent struct { + VmEvent +} + +func init() { + t["VmDisconnectedEvent"] = reflect.TypeOf((*VmDisconnectedEvent)(nil)).Elem() +} + +type VmDiscoveredEvent struct { + VmEvent +} + +func init() { + t["VmDiscoveredEvent"] = reflect.TypeOf((*VmDiscoveredEvent)(nil)).Elem() +} + +type VmDiskFailedEvent struct { + VmEvent + + Disk string `xml:"disk"` + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmDiskFailedEvent"] = reflect.TypeOf((*VmDiskFailedEvent)(nil)).Elem() +} + +type VmDiskFileInfo struct { + FileInfo + + DiskType string `xml:"diskType,omitempty"` + CapacityKb int64 `xml:"capacityKb,omitempty"` + HardwareVersion int32 `xml:"hardwareVersion,omitempty"` + ControllerType string `xml:"controllerType,omitempty"` + DiskExtents []string `xml:"diskExtents,omitempty"` + Thin *bool `xml:"thin"` +} + +func init() { + t["VmDiskFileInfo"] = reflect.TypeOf((*VmDiskFileInfo)(nil)).Elem() +} + +type VmDiskFileQuery struct { + FileQuery + + Filter *VmDiskFileQueryFilter `xml:"filter,omitempty"` + Details *VmDiskFileQueryFlags `xml:"details,omitempty"` +} + +func init() { + t["VmDiskFileQuery"] = reflect.TypeOf((*VmDiskFileQuery)(nil)).Elem() +} + +type VmDiskFileQueryFilter struct { + DynamicData + + DiskType []string `xml:"diskType,omitempty"` + MatchHardwareVersion []int32 `xml:"matchHardwareVersion,omitempty"` + ControllerType []string `xml:"controllerType,omitempty"` + Thin *bool `xml:"thin"` +} + +func init() { + t["VmDiskFileQueryFilter"] = reflect.TypeOf((*VmDiskFileQueryFilter)(nil)).Elem() +} + +type VmDiskFileQueryFlags struct { + DynamicData + + DiskType bool `xml:"diskType"` + CapacityKb bool `xml:"capacityKb"` + HardwareVersion bool `xml:"hardwareVersion"` + ControllerType *bool `xml:"controllerType"` + DiskExtents *bool `xml:"diskExtents"` + Thin *bool `xml:"thin"` +} + +func init() { + t["VmDiskFileQueryFlags"] = reflect.TypeOf((*VmDiskFileQueryFlags)(nil)).Elem() +} + +type VmEmigratingEvent struct { + VmEvent +} + +func init() { + t["VmEmigratingEvent"] = reflect.TypeOf((*VmEmigratingEvent)(nil)).Elem() +} + +type VmEndRecordingEvent struct { + VmEvent +} + +func init() { + t["VmEndRecordingEvent"] = reflect.TypeOf((*VmEndRecordingEvent)(nil)).Elem() +} + +type VmEndReplayingEvent struct { + VmEvent +} + +func init() { + t["VmEndReplayingEvent"] = reflect.TypeOf((*VmEndReplayingEvent)(nil)).Elem() +} + +type VmEvent struct { + Event + + Template bool `xml:"template"` +} + +func init() { + t["VmEvent"] = reflect.TypeOf((*VmEvent)(nil)).Elem() +} + +type VmEventArgument struct { + EntityEventArgument + + Vm ManagedObjectReference `xml:"vm"` +} + +func init() { + t["VmEventArgument"] = reflect.TypeOf((*VmEventArgument)(nil)).Elem() +} + +type VmFailedMigrateEvent struct { + VmEvent + + DestHost HostEventArgument `xml:"destHost"` + Reason LocalizedMethodFault `xml:"reason"` + DestDatacenter *DatacenterEventArgument `xml:"destDatacenter,omitempty"` + DestDatastore *DatastoreEventArgument `xml:"destDatastore,omitempty"` +} + +func init() { + t["VmFailedMigrateEvent"] = reflect.TypeOf((*VmFailedMigrateEvent)(nil)).Elem() +} + +type VmFailedRelayoutEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedRelayoutEvent"] = reflect.TypeOf((*VmFailedRelayoutEvent)(nil)).Elem() +} + +type VmFailedRelayoutOnVmfs2DatastoreEvent struct { + VmEvent +} + +func init() { + t["VmFailedRelayoutOnVmfs2DatastoreEvent"] = reflect.TypeOf((*VmFailedRelayoutOnVmfs2DatastoreEvent)(nil)).Elem() +} + +type VmFailedStartingSecondaryEvent struct { + VmEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["VmFailedStartingSecondaryEvent"] = reflect.TypeOf((*VmFailedStartingSecondaryEvent)(nil)).Elem() +} + +type VmFailedToPowerOffEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToPowerOffEvent"] = reflect.TypeOf((*VmFailedToPowerOffEvent)(nil)).Elem() +} + +type VmFailedToPowerOnEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToPowerOnEvent"] = reflect.TypeOf((*VmFailedToPowerOnEvent)(nil)).Elem() +} + +type VmFailedToRebootGuestEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToRebootGuestEvent"] = reflect.TypeOf((*VmFailedToRebootGuestEvent)(nil)).Elem() +} + +type VmFailedToResetEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToResetEvent"] = reflect.TypeOf((*VmFailedToResetEvent)(nil)).Elem() +} + +type VmFailedToShutdownGuestEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToShutdownGuestEvent"] = reflect.TypeOf((*VmFailedToShutdownGuestEvent)(nil)).Elem() +} + +type VmFailedToStandbyGuestEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToStandbyGuestEvent"] = reflect.TypeOf((*VmFailedToStandbyGuestEvent)(nil)).Elem() +} + +type VmFailedToSuspendEvent struct { + VmEvent + + Reason LocalizedMethodFault `xml:"reason"` +} + +func init() { + t["VmFailedToSuspendEvent"] = reflect.TypeOf((*VmFailedToSuspendEvent)(nil)).Elem() +} + +type VmFailedUpdatingSecondaryConfig struct { + VmEvent +} + +func init() { + t["VmFailedUpdatingSecondaryConfig"] = reflect.TypeOf((*VmFailedUpdatingSecondaryConfig)(nil)).Elem() +} + +type VmFailoverFailed struct { + VmEvent + + Reason *LocalizedMethodFault `xml:"reason,omitempty"` +} + +func init() { + t["VmFailoverFailed"] = reflect.TypeOf((*VmFailoverFailed)(nil)).Elem() +} + +type VmFaultToleranceConfigIssue struct { + VmFaultToleranceIssue + + Reason string `xml:"reason,omitempty"` + EntityName string `xml:"entityName,omitempty"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` +} + +func init() { + t["VmFaultToleranceConfigIssue"] = reflect.TypeOf((*VmFaultToleranceConfigIssue)(nil)).Elem() +} + +type VmFaultToleranceConfigIssueFault VmFaultToleranceConfigIssue + +func init() { + t["VmFaultToleranceConfigIssueFault"] = reflect.TypeOf((*VmFaultToleranceConfigIssueFault)(nil)).Elem() +} + +type VmFaultToleranceConfigIssueWrapper struct { + VmFaultToleranceIssue + + EntityName string `xml:"entityName,omitempty"` + Entity *ManagedObjectReference `xml:"entity,omitempty"` + Error *LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["VmFaultToleranceConfigIssueWrapper"] = reflect.TypeOf((*VmFaultToleranceConfigIssueWrapper)(nil)).Elem() +} + +type VmFaultToleranceConfigIssueWrapperFault VmFaultToleranceConfigIssueWrapper + +func init() { + t["VmFaultToleranceConfigIssueWrapperFault"] = reflect.TypeOf((*VmFaultToleranceConfigIssueWrapperFault)(nil)).Elem() +} + +type VmFaultToleranceInvalidFileBacking struct { + VmFaultToleranceIssue + + BackingType string `xml:"backingType,omitempty"` + BackingFilename string `xml:"backingFilename,omitempty"` +} + +func init() { + t["VmFaultToleranceInvalidFileBacking"] = reflect.TypeOf((*VmFaultToleranceInvalidFileBacking)(nil)).Elem() +} + +type VmFaultToleranceInvalidFileBackingFault VmFaultToleranceInvalidFileBacking + +func init() { + t["VmFaultToleranceInvalidFileBackingFault"] = reflect.TypeOf((*VmFaultToleranceInvalidFileBackingFault)(nil)).Elem() +} + +type VmFaultToleranceIssue struct { + VimFault +} + +func init() { + t["VmFaultToleranceIssue"] = reflect.TypeOf((*VmFaultToleranceIssue)(nil)).Elem() +} + +type VmFaultToleranceIssueFault BaseVmFaultToleranceIssue + +func init() { + t["VmFaultToleranceIssueFault"] = reflect.TypeOf((*VmFaultToleranceIssueFault)(nil)).Elem() +} + +type VmFaultToleranceOpIssuesList struct { + VmFaultToleranceIssue + + Errors []LocalizedMethodFault `xml:"errors,omitempty"` + Warnings []LocalizedMethodFault `xml:"warnings,omitempty"` +} + +func init() { + t["VmFaultToleranceOpIssuesList"] = reflect.TypeOf((*VmFaultToleranceOpIssuesList)(nil)).Elem() +} + +type VmFaultToleranceOpIssuesListFault VmFaultToleranceOpIssuesList + +func init() { + t["VmFaultToleranceOpIssuesListFault"] = reflect.TypeOf((*VmFaultToleranceOpIssuesListFault)(nil)).Elem() +} + +type VmFaultToleranceStateChangedEvent struct { + VmEvent + + OldState VirtualMachineFaultToleranceState `xml:"oldState"` + NewState VirtualMachineFaultToleranceState `xml:"newState"` +} + +func init() { + t["VmFaultToleranceStateChangedEvent"] = reflect.TypeOf((*VmFaultToleranceStateChangedEvent)(nil)).Elem() +} + +type VmFaultToleranceTooManyFtVcpusOnHost struct { + InsufficientResourcesFault + + HostName string `xml:"hostName,omitempty"` + MaxNumFtVcpus int32 `xml:"maxNumFtVcpus"` +} + +func init() { + t["VmFaultToleranceTooManyFtVcpusOnHost"] = reflect.TypeOf((*VmFaultToleranceTooManyFtVcpusOnHost)(nil)).Elem() +} + +type VmFaultToleranceTooManyFtVcpusOnHostFault VmFaultToleranceTooManyFtVcpusOnHost + +func init() { + t["VmFaultToleranceTooManyFtVcpusOnHostFault"] = reflect.TypeOf((*VmFaultToleranceTooManyFtVcpusOnHostFault)(nil)).Elem() +} + +type VmFaultToleranceTooManyVMsOnHost struct { + InsufficientResourcesFault + + HostName string `xml:"hostName,omitempty"` + MaxNumFtVms int32 `xml:"maxNumFtVms"` +} + +func init() { + t["VmFaultToleranceTooManyVMsOnHost"] = reflect.TypeOf((*VmFaultToleranceTooManyVMsOnHost)(nil)).Elem() +} + +type VmFaultToleranceTooManyVMsOnHostFault VmFaultToleranceTooManyVMsOnHost + +func init() { + t["VmFaultToleranceTooManyVMsOnHostFault"] = reflect.TypeOf((*VmFaultToleranceTooManyVMsOnHostFault)(nil)).Elem() +} + +type VmFaultToleranceTurnedOffEvent struct { + VmEvent +} + +func init() { + t["VmFaultToleranceTurnedOffEvent"] = reflect.TypeOf((*VmFaultToleranceTurnedOffEvent)(nil)).Elem() +} + +type VmFaultToleranceVmTerminatedEvent struct { + VmEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["VmFaultToleranceVmTerminatedEvent"] = reflect.TypeOf((*VmFaultToleranceVmTerminatedEvent)(nil)).Elem() +} + +type VmGuestOSCrashedEvent struct { + VmEvent +} + +func init() { + t["VmGuestOSCrashedEvent"] = reflect.TypeOf((*VmGuestOSCrashedEvent)(nil)).Elem() +} + +type VmGuestRebootEvent struct { + VmEvent +} + +func init() { + t["VmGuestRebootEvent"] = reflect.TypeOf((*VmGuestRebootEvent)(nil)).Elem() +} + +type VmGuestShutdownEvent struct { + VmEvent +} + +func init() { + t["VmGuestShutdownEvent"] = reflect.TypeOf((*VmGuestShutdownEvent)(nil)).Elem() +} + +type VmGuestStandbyEvent struct { + VmEvent +} + +func init() { + t["VmGuestStandbyEvent"] = reflect.TypeOf((*VmGuestStandbyEvent)(nil)).Elem() +} + +type VmHealthMonitoringStateChangedEvent struct { + ClusterEvent + + State string `xml:"state"` +} + +func init() { + t["VmHealthMonitoringStateChangedEvent"] = reflect.TypeOf((*VmHealthMonitoringStateChangedEvent)(nil)).Elem() +} + +type VmHostAffinityRuleViolation struct { + VmConfigFault + + VmName string `xml:"vmName"` + HostName string `xml:"hostName"` +} + +func init() { + t["VmHostAffinityRuleViolation"] = reflect.TypeOf((*VmHostAffinityRuleViolation)(nil)).Elem() +} + +type VmHostAffinityRuleViolationFault VmHostAffinityRuleViolation + +func init() { + t["VmHostAffinityRuleViolationFault"] = reflect.TypeOf((*VmHostAffinityRuleViolationFault)(nil)).Elem() +} + +type VmInstanceUuidAssignedEvent struct { + VmEvent + + InstanceUuid string `xml:"instanceUuid"` +} + +func init() { + t["VmInstanceUuidAssignedEvent"] = reflect.TypeOf((*VmInstanceUuidAssignedEvent)(nil)).Elem() +} + +type VmInstanceUuidChangedEvent struct { + VmEvent + + OldInstanceUuid string `xml:"oldInstanceUuid"` + NewInstanceUuid string `xml:"newInstanceUuid"` +} + +func init() { + t["VmInstanceUuidChangedEvent"] = reflect.TypeOf((*VmInstanceUuidChangedEvent)(nil)).Elem() +} + +type VmInstanceUuidConflictEvent struct { + VmEvent + + ConflictedVm VmEventArgument `xml:"conflictedVm"` + InstanceUuid string `xml:"instanceUuid"` +} + +func init() { + t["VmInstanceUuidConflictEvent"] = reflect.TypeOf((*VmInstanceUuidConflictEvent)(nil)).Elem() +} + +type VmLimitLicense struct { + NotEnoughLicenses + + Limit int32 `xml:"limit"` +} + +func init() { + t["VmLimitLicense"] = reflect.TypeOf((*VmLimitLicense)(nil)).Elem() +} + +type VmLimitLicenseFault VmLimitLicense + +func init() { + t["VmLimitLicenseFault"] = reflect.TypeOf((*VmLimitLicenseFault)(nil)).Elem() +} + +type VmLogFileInfo struct { + FileInfo +} + +func init() { + t["VmLogFileInfo"] = reflect.TypeOf((*VmLogFileInfo)(nil)).Elem() +} + +type VmLogFileQuery struct { + FileQuery +} + +func init() { + t["VmLogFileQuery"] = reflect.TypeOf((*VmLogFileQuery)(nil)).Elem() +} + +type VmMacAssignedEvent struct { + VmEvent + + Adapter string `xml:"adapter"` + Mac string `xml:"mac"` +} + +func init() { + t["VmMacAssignedEvent"] = reflect.TypeOf((*VmMacAssignedEvent)(nil)).Elem() +} + +type VmMacChangedEvent struct { + VmEvent + + Adapter string `xml:"adapter"` + OldMac string `xml:"oldMac"` + NewMac string `xml:"newMac"` +} + +func init() { + t["VmMacChangedEvent"] = reflect.TypeOf((*VmMacChangedEvent)(nil)).Elem() +} + +type VmMacConflictEvent struct { + VmEvent + + ConflictedVm VmEventArgument `xml:"conflictedVm"` + Mac string `xml:"mac"` +} + +func init() { + t["VmMacConflictEvent"] = reflect.TypeOf((*VmMacConflictEvent)(nil)).Elem() +} + +type VmMaxFTRestartCountReached struct { + VmEvent +} + +func init() { + t["VmMaxFTRestartCountReached"] = reflect.TypeOf((*VmMaxFTRestartCountReached)(nil)).Elem() +} + +type VmMaxRestartCountReached struct { + VmEvent +} + +func init() { + t["VmMaxRestartCountReached"] = reflect.TypeOf((*VmMaxRestartCountReached)(nil)).Elem() +} + +type VmMessageErrorEvent struct { + VmEvent + + Message string `xml:"message"` + MessageInfo []VirtualMachineMessage `xml:"messageInfo,omitempty"` +} + +func init() { + t["VmMessageErrorEvent"] = reflect.TypeOf((*VmMessageErrorEvent)(nil)).Elem() +} + +type VmMessageEvent struct { + VmEvent + + Message string `xml:"message"` + MessageInfo []VirtualMachineMessage `xml:"messageInfo,omitempty"` +} + +func init() { + t["VmMessageEvent"] = reflect.TypeOf((*VmMessageEvent)(nil)).Elem() +} + +type VmMessageWarningEvent struct { + VmEvent + + Message string `xml:"message"` + MessageInfo []VirtualMachineMessage `xml:"messageInfo,omitempty"` +} + +func init() { + t["VmMessageWarningEvent"] = reflect.TypeOf((*VmMessageWarningEvent)(nil)).Elem() +} + +type VmMetadataManagerFault struct { + VimFault +} + +func init() { + t["VmMetadataManagerFault"] = reflect.TypeOf((*VmMetadataManagerFault)(nil)).Elem() +} + +type VmMetadataManagerFaultFault VmMetadataManagerFault + +func init() { + t["VmMetadataManagerFaultFault"] = reflect.TypeOf((*VmMetadataManagerFaultFault)(nil)).Elem() +} + +type VmMigratedEvent struct { + VmEvent + + SourceHost HostEventArgument `xml:"sourceHost"` + SourceDatacenter *DatacenterEventArgument `xml:"sourceDatacenter,omitempty"` + SourceDatastore *DatastoreEventArgument `xml:"sourceDatastore,omitempty"` +} + +func init() { + t["VmMigratedEvent"] = reflect.TypeOf((*VmMigratedEvent)(nil)).Elem() +} + +type VmMonitorIncompatibleForFaultTolerance struct { + VimFault +} + +func init() { + t["VmMonitorIncompatibleForFaultTolerance"] = reflect.TypeOf((*VmMonitorIncompatibleForFaultTolerance)(nil)).Elem() +} + +type VmMonitorIncompatibleForFaultToleranceFault VmMonitorIncompatibleForFaultTolerance + +func init() { + t["VmMonitorIncompatibleForFaultToleranceFault"] = reflect.TypeOf((*VmMonitorIncompatibleForFaultToleranceFault)(nil)).Elem() +} + +type VmNoCompatibleHostForSecondaryEvent struct { + VmEvent +} + +func init() { + t["VmNoCompatibleHostForSecondaryEvent"] = reflect.TypeOf((*VmNoCompatibleHostForSecondaryEvent)(nil)).Elem() +} + +type VmNoNetworkAccessEvent struct { + VmEvent + + DestHost HostEventArgument `xml:"destHost"` +} + +func init() { + t["VmNoNetworkAccessEvent"] = reflect.TypeOf((*VmNoNetworkAccessEvent)(nil)).Elem() +} + +type VmNvramFileInfo struct { + FileInfo +} + +func init() { + t["VmNvramFileInfo"] = reflect.TypeOf((*VmNvramFileInfo)(nil)).Elem() +} + +type VmNvramFileQuery struct { + FileQuery +} + +func init() { + t["VmNvramFileQuery"] = reflect.TypeOf((*VmNvramFileQuery)(nil)).Elem() +} + +type VmOrphanedEvent struct { + VmEvent +} + +func init() { + t["VmOrphanedEvent"] = reflect.TypeOf((*VmOrphanedEvent)(nil)).Elem() +} + +type VmPodConfigForPlacement struct { + DynamicData + + StoragePod ManagedObjectReference `xml:"storagePod"` + Disk []PodDiskLocator `xml:"disk,omitempty"` + VmConfig *StorageDrsVmConfigInfo `xml:"vmConfig,omitempty"` + InterVmRule []BaseClusterRuleInfo `xml:"interVmRule,omitempty,typeattr"` +} + +func init() { + t["VmPodConfigForPlacement"] = reflect.TypeOf((*VmPodConfigForPlacement)(nil)).Elem() +} + +type VmPortGroupProfile struct { + PortGroupProfile +} + +func init() { + t["VmPortGroupProfile"] = reflect.TypeOf((*VmPortGroupProfile)(nil)).Elem() +} + +type VmPowerOffOnIsolationEvent struct { + VmPoweredOffEvent + + IsolatedHost HostEventArgument `xml:"isolatedHost"` +} + +func init() { + t["VmPowerOffOnIsolationEvent"] = reflect.TypeOf((*VmPowerOffOnIsolationEvent)(nil)).Elem() +} + +type VmPowerOnDisabled struct { + InvalidState +} + +func init() { + t["VmPowerOnDisabled"] = reflect.TypeOf((*VmPowerOnDisabled)(nil)).Elem() +} + +type VmPowerOnDisabledFault VmPowerOnDisabled + +func init() { + t["VmPowerOnDisabledFault"] = reflect.TypeOf((*VmPowerOnDisabledFault)(nil)).Elem() +} + +type VmPoweredOffEvent struct { + VmEvent +} + +func init() { + t["VmPoweredOffEvent"] = reflect.TypeOf((*VmPoweredOffEvent)(nil)).Elem() +} + +type VmPoweredOnEvent struct { + VmEvent +} + +func init() { + t["VmPoweredOnEvent"] = reflect.TypeOf((*VmPoweredOnEvent)(nil)).Elem() +} + +type VmPoweringOnWithCustomizedDVPortEvent struct { + VmEvent + + Vnic []VnicPortArgument `xml:"vnic"` +} + +func init() { + t["VmPoweringOnWithCustomizedDVPortEvent"] = reflect.TypeOf((*VmPoweringOnWithCustomizedDVPortEvent)(nil)).Elem() +} + +type VmPrimaryFailoverEvent struct { + VmEvent + + Reason string `xml:"reason,omitempty"` +} + +func init() { + t["VmPrimaryFailoverEvent"] = reflect.TypeOf((*VmPrimaryFailoverEvent)(nil)).Elem() +} + +type VmReconfiguredEvent struct { + VmEvent + + ConfigSpec VirtualMachineConfigSpec `xml:"configSpec"` +} + +func init() { + t["VmReconfiguredEvent"] = reflect.TypeOf((*VmReconfiguredEvent)(nil)).Elem() +} + +type VmRegisteredEvent struct { + VmEvent +} + +func init() { + t["VmRegisteredEvent"] = reflect.TypeOf((*VmRegisteredEvent)(nil)).Elem() +} + +type VmRelayoutSuccessfulEvent struct { + VmEvent +} + +func init() { + t["VmRelayoutSuccessfulEvent"] = reflect.TypeOf((*VmRelayoutSuccessfulEvent)(nil)).Elem() +} + +type VmRelayoutUpToDateEvent struct { + VmEvent +} + +func init() { + t["VmRelayoutUpToDateEvent"] = reflect.TypeOf((*VmRelayoutUpToDateEvent)(nil)).Elem() +} + +type VmReloadFromPathEvent struct { + VmEvent + + ConfigPath string `xml:"configPath"` +} + +func init() { + t["VmReloadFromPathEvent"] = reflect.TypeOf((*VmReloadFromPathEvent)(nil)).Elem() +} + +type VmReloadFromPathFailedEvent struct { + VmEvent + + ConfigPath string `xml:"configPath"` +} + +func init() { + t["VmReloadFromPathFailedEvent"] = reflect.TypeOf((*VmReloadFromPathFailedEvent)(nil)).Elem() +} + +type VmRelocateFailedEvent struct { + VmRelocateSpecEvent + + DestHost HostEventArgument `xml:"destHost"` + Reason LocalizedMethodFault `xml:"reason"` + DestDatacenter *DatacenterEventArgument `xml:"destDatacenter,omitempty"` + DestDatastore *DatastoreEventArgument `xml:"destDatastore,omitempty"` +} + +func init() { + t["VmRelocateFailedEvent"] = reflect.TypeOf((*VmRelocateFailedEvent)(nil)).Elem() +} + +type VmRelocateSpecEvent struct { + VmEvent +} + +func init() { + t["VmRelocateSpecEvent"] = reflect.TypeOf((*VmRelocateSpecEvent)(nil)).Elem() +} + +type VmRelocatedEvent struct { + VmRelocateSpecEvent + + SourceHost HostEventArgument `xml:"sourceHost"` + SourceDatacenter *DatacenterEventArgument `xml:"sourceDatacenter,omitempty"` + SourceDatastore *DatastoreEventArgument `xml:"sourceDatastore,omitempty"` +} + +func init() { + t["VmRelocatedEvent"] = reflect.TypeOf((*VmRelocatedEvent)(nil)).Elem() +} + +type VmRemoteConsoleConnectedEvent struct { + VmEvent +} + +func init() { + t["VmRemoteConsoleConnectedEvent"] = reflect.TypeOf((*VmRemoteConsoleConnectedEvent)(nil)).Elem() +} + +type VmRemoteConsoleDisconnectedEvent struct { + VmEvent +} + +func init() { + t["VmRemoteConsoleDisconnectedEvent"] = reflect.TypeOf((*VmRemoteConsoleDisconnectedEvent)(nil)).Elem() +} + +type VmRemovedEvent struct { + VmEvent +} + +func init() { + t["VmRemovedEvent"] = reflect.TypeOf((*VmRemovedEvent)(nil)).Elem() +} + +type VmRenamedEvent struct { + VmEvent + + OldName string `xml:"oldName"` + NewName string `xml:"newName"` +} + +func init() { + t["VmRenamedEvent"] = reflect.TypeOf((*VmRenamedEvent)(nil)).Elem() +} + +type VmRequirementsExceedCurrentEVCModeEvent struct { + VmEvent +} + +func init() { + t["VmRequirementsExceedCurrentEVCModeEvent"] = reflect.TypeOf((*VmRequirementsExceedCurrentEVCModeEvent)(nil)).Elem() +} + +type VmResettingEvent struct { + VmEvent +} + +func init() { + t["VmResettingEvent"] = reflect.TypeOf((*VmResettingEvent)(nil)).Elem() +} + +type VmResourcePoolMovedEvent struct { + VmEvent + + OldParent ResourcePoolEventArgument `xml:"oldParent"` + NewParent ResourcePoolEventArgument `xml:"newParent"` +} + +func init() { + t["VmResourcePoolMovedEvent"] = reflect.TypeOf((*VmResourcePoolMovedEvent)(nil)).Elem() +} + +type VmResourceReallocatedEvent struct { + VmEvent +} + +func init() { + t["VmResourceReallocatedEvent"] = reflect.TypeOf((*VmResourceReallocatedEvent)(nil)).Elem() +} + +type VmRestartedOnAlternateHostEvent struct { + VmPoweredOnEvent + + SourceHost HostEventArgument `xml:"sourceHost"` +} + +func init() { + t["VmRestartedOnAlternateHostEvent"] = reflect.TypeOf((*VmRestartedOnAlternateHostEvent)(nil)).Elem() +} + +type VmResumingEvent struct { + VmEvent +} + +func init() { + t["VmResumingEvent"] = reflect.TypeOf((*VmResumingEvent)(nil)).Elem() +} + +type VmSecondaryAddedEvent struct { + VmEvent +} + +func init() { + t["VmSecondaryAddedEvent"] = reflect.TypeOf((*VmSecondaryAddedEvent)(nil)).Elem() +} + +type VmSecondaryDisabledBySystemEvent struct { + VmEvent + + Reason *LocalizedMethodFault `xml:"reason,omitempty"` +} + +func init() { + t["VmSecondaryDisabledBySystemEvent"] = reflect.TypeOf((*VmSecondaryDisabledBySystemEvent)(nil)).Elem() +} + +type VmSecondaryDisabledEvent struct { + VmEvent +} + +func init() { + t["VmSecondaryDisabledEvent"] = reflect.TypeOf((*VmSecondaryDisabledEvent)(nil)).Elem() +} + +type VmSecondaryEnabledEvent struct { + VmEvent +} + +func init() { + t["VmSecondaryEnabledEvent"] = reflect.TypeOf((*VmSecondaryEnabledEvent)(nil)).Elem() +} + +type VmSecondaryStartedEvent struct { + VmEvent +} + +func init() { + t["VmSecondaryStartedEvent"] = reflect.TypeOf((*VmSecondaryStartedEvent)(nil)).Elem() +} + +type VmShutdownOnIsolationEvent struct { + VmPoweredOffEvent + + IsolatedHost HostEventArgument `xml:"isolatedHost"` + ShutdownResult string `xml:"shutdownResult,omitempty"` +} + +func init() { + t["VmShutdownOnIsolationEvent"] = reflect.TypeOf((*VmShutdownOnIsolationEvent)(nil)).Elem() +} + +type VmSmpFaultToleranceTooManyVMsOnHost struct { + InsufficientResourcesFault + + HostName string `xml:"hostName,omitempty"` + MaxNumSmpFtVms int32 `xml:"maxNumSmpFtVms"` +} + +func init() { + t["VmSmpFaultToleranceTooManyVMsOnHost"] = reflect.TypeOf((*VmSmpFaultToleranceTooManyVMsOnHost)(nil)).Elem() +} + +type VmSmpFaultToleranceTooManyVMsOnHostFault VmSmpFaultToleranceTooManyVMsOnHost + +func init() { + t["VmSmpFaultToleranceTooManyVMsOnHostFault"] = reflect.TypeOf((*VmSmpFaultToleranceTooManyVMsOnHostFault)(nil)).Elem() +} + +type VmSnapshotFileInfo struct { + FileInfo +} + +func init() { + t["VmSnapshotFileInfo"] = reflect.TypeOf((*VmSnapshotFileInfo)(nil)).Elem() +} + +type VmSnapshotFileQuery struct { + FileQuery +} + +func init() { + t["VmSnapshotFileQuery"] = reflect.TypeOf((*VmSnapshotFileQuery)(nil)).Elem() +} + +type VmStartRecordingEvent struct { + VmEvent +} + +func init() { + t["VmStartRecordingEvent"] = reflect.TypeOf((*VmStartRecordingEvent)(nil)).Elem() +} + +type VmStartReplayingEvent struct { + VmEvent +} + +func init() { + t["VmStartReplayingEvent"] = reflect.TypeOf((*VmStartReplayingEvent)(nil)).Elem() +} + +type VmStartingEvent struct { + VmEvent +} + +func init() { + t["VmStartingEvent"] = reflect.TypeOf((*VmStartingEvent)(nil)).Elem() +} + +type VmStartingSecondaryEvent struct { + VmEvent +} + +func init() { + t["VmStartingSecondaryEvent"] = reflect.TypeOf((*VmStartingSecondaryEvent)(nil)).Elem() +} + +type VmStaticMacConflictEvent struct { + VmEvent + + ConflictedVm VmEventArgument `xml:"conflictedVm"` + Mac string `xml:"mac"` +} + +func init() { + t["VmStaticMacConflictEvent"] = reflect.TypeOf((*VmStaticMacConflictEvent)(nil)).Elem() +} + +type VmStoppingEvent struct { + VmEvent +} + +func init() { + t["VmStoppingEvent"] = reflect.TypeOf((*VmStoppingEvent)(nil)).Elem() +} + +type VmSuspendedEvent struct { + VmEvent +} + +func init() { + t["VmSuspendedEvent"] = reflect.TypeOf((*VmSuspendedEvent)(nil)).Elem() +} + +type VmSuspendingEvent struct { + VmEvent +} + +func init() { + t["VmSuspendingEvent"] = reflect.TypeOf((*VmSuspendingEvent)(nil)).Elem() +} + +type VmTimedoutStartingSecondaryEvent struct { + VmEvent + + Timeout int64 `xml:"timeout,omitempty"` +} + +func init() { + t["VmTimedoutStartingSecondaryEvent"] = reflect.TypeOf((*VmTimedoutStartingSecondaryEvent)(nil)).Elem() +} + +type VmToolsUpgradeFault struct { + VimFault +} + +func init() { + t["VmToolsUpgradeFault"] = reflect.TypeOf((*VmToolsUpgradeFault)(nil)).Elem() +} + +type VmToolsUpgradeFaultFault BaseVmToolsUpgradeFault + +func init() { + t["VmToolsUpgradeFaultFault"] = reflect.TypeOf((*VmToolsUpgradeFaultFault)(nil)).Elem() +} + +type VmUnsupportedStartingEvent struct { + VmStartingEvent + + GuestId string `xml:"guestId"` +} + +func init() { + t["VmUnsupportedStartingEvent"] = reflect.TypeOf((*VmUnsupportedStartingEvent)(nil)).Elem() +} + +type VmUpgradeCompleteEvent struct { + VmEvent + + Version string `xml:"version"` +} + +func init() { + t["VmUpgradeCompleteEvent"] = reflect.TypeOf((*VmUpgradeCompleteEvent)(nil)).Elem() +} + +type VmUpgradeFailedEvent struct { + VmEvent +} + +func init() { + t["VmUpgradeFailedEvent"] = reflect.TypeOf((*VmUpgradeFailedEvent)(nil)).Elem() +} + +type VmUpgradingEvent struct { + VmEvent + + Version string `xml:"version"` +} + +func init() { + t["VmUpgradingEvent"] = reflect.TypeOf((*VmUpgradingEvent)(nil)).Elem() +} + +type VmUuidAssignedEvent struct { + VmEvent + + Uuid string `xml:"uuid"` +} + +func init() { + t["VmUuidAssignedEvent"] = reflect.TypeOf((*VmUuidAssignedEvent)(nil)).Elem() +} + +type VmUuidChangedEvent struct { + VmEvent + + OldUuid string `xml:"oldUuid"` + NewUuid string `xml:"newUuid"` +} + +func init() { + t["VmUuidChangedEvent"] = reflect.TypeOf((*VmUuidChangedEvent)(nil)).Elem() +} + +type VmUuidConflictEvent struct { + VmEvent + + ConflictedVm VmEventArgument `xml:"conflictedVm"` + Uuid string `xml:"uuid"` +} + +func init() { + t["VmUuidConflictEvent"] = reflect.TypeOf((*VmUuidConflictEvent)(nil)).Elem() +} + +type VmValidateMaxDevice struct { + VimFault + + Device string `xml:"device"` + Max int32 `xml:"max"` + Count int32 `xml:"count"` +} + +func init() { + t["VmValidateMaxDevice"] = reflect.TypeOf((*VmValidateMaxDevice)(nil)).Elem() +} + +type VmValidateMaxDeviceFault VmValidateMaxDevice + +func init() { + t["VmValidateMaxDeviceFault"] = reflect.TypeOf((*VmValidateMaxDeviceFault)(nil)).Elem() +} + +type VmVnicPoolReservationViolationClearEvent struct { + DvsEvent + + VmVnicResourcePoolKey string `xml:"vmVnicResourcePoolKey"` + VmVnicResourcePoolName string `xml:"vmVnicResourcePoolName,omitempty"` +} + +func init() { + t["VmVnicPoolReservationViolationClearEvent"] = reflect.TypeOf((*VmVnicPoolReservationViolationClearEvent)(nil)).Elem() +} + +type VmVnicPoolReservationViolationRaiseEvent struct { + DvsEvent + + VmVnicResourcePoolKey string `xml:"vmVnicResourcePoolKey"` + VmVnicResourcePoolName string `xml:"vmVnicResourcePoolName,omitempty"` +} + +func init() { + t["VmVnicPoolReservationViolationRaiseEvent"] = reflect.TypeOf((*VmVnicPoolReservationViolationRaiseEvent)(nil)).Elem() +} + +type VmWwnAssignedEvent struct { + VmEvent + + NodeWwns []int64 `xml:"nodeWwns"` + PortWwns []int64 `xml:"portWwns"` +} + +func init() { + t["VmWwnAssignedEvent"] = reflect.TypeOf((*VmWwnAssignedEvent)(nil)).Elem() +} + +type VmWwnChangedEvent struct { + VmEvent + + OldNodeWwns []int64 `xml:"oldNodeWwns,omitempty"` + OldPortWwns []int64 `xml:"oldPortWwns,omitempty"` + NewNodeWwns []int64 `xml:"newNodeWwns,omitempty"` + NewPortWwns []int64 `xml:"newPortWwns,omitempty"` +} + +func init() { + t["VmWwnChangedEvent"] = reflect.TypeOf((*VmWwnChangedEvent)(nil)).Elem() +} + +type VmWwnConflict struct { + InvalidVmConfig + + Vm *ManagedObjectReference `xml:"vm,omitempty"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Name string `xml:"name,omitempty"` + Wwn int64 `xml:"wwn,omitempty"` +} + +func init() { + t["VmWwnConflict"] = reflect.TypeOf((*VmWwnConflict)(nil)).Elem() +} + +type VmWwnConflictEvent struct { + VmEvent + + ConflictedVms []VmEventArgument `xml:"conflictedVms,omitempty"` + ConflictedHosts []HostEventArgument `xml:"conflictedHosts,omitempty"` + Wwn int64 `xml:"wwn"` +} + +func init() { + t["VmWwnConflictEvent"] = reflect.TypeOf((*VmWwnConflictEvent)(nil)).Elem() +} + +type VmWwnConflictFault VmWwnConflict + +func init() { + t["VmWwnConflictFault"] = reflect.TypeOf((*VmWwnConflictFault)(nil)).Elem() +} + +type VmfsAlreadyMounted struct { + VmfsMountFault +} + +func init() { + t["VmfsAlreadyMounted"] = reflect.TypeOf((*VmfsAlreadyMounted)(nil)).Elem() +} + +type VmfsAlreadyMountedFault VmfsAlreadyMounted + +func init() { + t["VmfsAlreadyMountedFault"] = reflect.TypeOf((*VmfsAlreadyMountedFault)(nil)).Elem() +} + +type VmfsAmbiguousMount struct { + VmfsMountFault +} + +func init() { + t["VmfsAmbiguousMount"] = reflect.TypeOf((*VmfsAmbiguousMount)(nil)).Elem() +} + +type VmfsAmbiguousMountFault VmfsAmbiguousMount + +func init() { + t["VmfsAmbiguousMountFault"] = reflect.TypeOf((*VmfsAmbiguousMountFault)(nil)).Elem() +} + +type VmfsDatastoreAllExtentOption struct { + VmfsDatastoreSingleExtentOption +} + +func init() { + t["VmfsDatastoreAllExtentOption"] = reflect.TypeOf((*VmfsDatastoreAllExtentOption)(nil)).Elem() +} + +type VmfsDatastoreBaseOption struct { + DynamicData + + Layout HostDiskPartitionLayout `xml:"layout"` + PartitionFormatChange *bool `xml:"partitionFormatChange"` +} + +func init() { + t["VmfsDatastoreBaseOption"] = reflect.TypeOf((*VmfsDatastoreBaseOption)(nil)).Elem() +} + +type VmfsDatastoreCreateSpec struct { + VmfsDatastoreSpec + + Partition HostDiskPartitionSpec `xml:"partition"` + Vmfs HostVmfsSpec `xml:"vmfs"` + Extent []HostScsiDiskPartition `xml:"extent,omitempty"` +} + +func init() { + t["VmfsDatastoreCreateSpec"] = reflect.TypeOf((*VmfsDatastoreCreateSpec)(nil)).Elem() +} + +type VmfsDatastoreExpandSpec struct { + VmfsDatastoreSpec + + Partition HostDiskPartitionSpec `xml:"partition"` + Extent HostScsiDiskPartition `xml:"extent"` +} + +func init() { + t["VmfsDatastoreExpandSpec"] = reflect.TypeOf((*VmfsDatastoreExpandSpec)(nil)).Elem() +} + +type VmfsDatastoreExtendSpec struct { + VmfsDatastoreSpec + + Partition HostDiskPartitionSpec `xml:"partition"` + Extent []HostScsiDiskPartition `xml:"extent"` +} + +func init() { + t["VmfsDatastoreExtendSpec"] = reflect.TypeOf((*VmfsDatastoreExtendSpec)(nil)).Elem() +} + +type VmfsDatastoreInfo struct { + DatastoreInfo + + MaxPhysicalRDMFileSize int64 `xml:"maxPhysicalRDMFileSize,omitempty"` + MaxVirtualRDMFileSize int64 `xml:"maxVirtualRDMFileSize,omitempty"` + Vmfs *HostVmfsVolume `xml:"vmfs,omitempty"` +} + +func init() { + t["VmfsDatastoreInfo"] = reflect.TypeOf((*VmfsDatastoreInfo)(nil)).Elem() +} + +type VmfsDatastoreMultipleExtentOption struct { + VmfsDatastoreBaseOption + + VmfsExtent []HostDiskPartitionBlockRange `xml:"vmfsExtent"` +} + +func init() { + t["VmfsDatastoreMultipleExtentOption"] = reflect.TypeOf((*VmfsDatastoreMultipleExtentOption)(nil)).Elem() +} + +type VmfsDatastoreOption struct { + DynamicData + + Info BaseVmfsDatastoreBaseOption `xml:"info,typeattr"` + Spec BaseVmfsDatastoreSpec `xml:"spec,typeattr"` +} + +func init() { + t["VmfsDatastoreOption"] = reflect.TypeOf((*VmfsDatastoreOption)(nil)).Elem() +} + +type VmfsDatastoreSingleExtentOption struct { + VmfsDatastoreBaseOption + + VmfsExtent HostDiskPartitionBlockRange `xml:"vmfsExtent"` +} + +func init() { + t["VmfsDatastoreSingleExtentOption"] = reflect.TypeOf((*VmfsDatastoreSingleExtentOption)(nil)).Elem() +} + +type VmfsDatastoreSpec struct { + DynamicData + + DiskUuid string `xml:"diskUuid"` +} + +func init() { + t["VmfsDatastoreSpec"] = reflect.TypeOf((*VmfsDatastoreSpec)(nil)).Elem() +} + +type VmfsMountFault struct { + HostConfigFault + + Uuid string `xml:"uuid"` +} + +func init() { + t["VmfsMountFault"] = reflect.TypeOf((*VmfsMountFault)(nil)).Elem() +} + +type VmfsMountFaultFault BaseVmfsMountFault + +func init() { + t["VmfsMountFaultFault"] = reflect.TypeOf((*VmfsMountFaultFault)(nil)).Elem() +} + +type VmotionInterfaceNotEnabled struct { + HostPowerOpFailed +} + +func init() { + t["VmotionInterfaceNotEnabled"] = reflect.TypeOf((*VmotionInterfaceNotEnabled)(nil)).Elem() +} + +type VmotionInterfaceNotEnabledFault VmotionInterfaceNotEnabled + +func init() { + t["VmotionInterfaceNotEnabledFault"] = reflect.TypeOf((*VmotionInterfaceNotEnabledFault)(nil)).Elem() +} + +type VmwareDistributedVirtualSwitchPvlanSpec struct { + VmwareDistributedVirtualSwitchVlanSpec + + PvlanId int32 `xml:"pvlanId"` +} + +func init() { + t["VmwareDistributedVirtualSwitchPvlanSpec"] = reflect.TypeOf((*VmwareDistributedVirtualSwitchPvlanSpec)(nil)).Elem() +} + +type VmwareDistributedVirtualSwitchTrunkVlanSpec struct { + VmwareDistributedVirtualSwitchVlanSpec + + VlanId []NumericRange `xml:"vlanId"` +} + +func init() { + t["VmwareDistributedVirtualSwitchTrunkVlanSpec"] = reflect.TypeOf((*VmwareDistributedVirtualSwitchTrunkVlanSpec)(nil)).Elem() +} + +type VmwareDistributedVirtualSwitchVlanIdSpec struct { + VmwareDistributedVirtualSwitchVlanSpec + + VlanId int32 `xml:"vlanId"` +} + +func init() { + t["VmwareDistributedVirtualSwitchVlanIdSpec"] = reflect.TypeOf((*VmwareDistributedVirtualSwitchVlanIdSpec)(nil)).Elem() +} + +type VmwareDistributedVirtualSwitchVlanSpec struct { + InheritablePolicy +} + +func init() { + t["VmwareDistributedVirtualSwitchVlanSpec"] = reflect.TypeOf((*VmwareDistributedVirtualSwitchVlanSpec)(nil)).Elem() +} + +type VmwareUplinkPortTeamingPolicy struct { + InheritablePolicy + + Policy *StringPolicy `xml:"policy,omitempty"` + ReversePolicy *BoolPolicy `xml:"reversePolicy,omitempty"` + NotifySwitches *BoolPolicy `xml:"notifySwitches,omitempty"` + RollingOrder *BoolPolicy `xml:"rollingOrder,omitempty"` + FailureCriteria *DVSFailureCriteria `xml:"failureCriteria,omitempty"` + UplinkPortOrder *VMwareUplinkPortOrderPolicy `xml:"uplinkPortOrder,omitempty"` +} + +func init() { + t["VmwareUplinkPortTeamingPolicy"] = reflect.TypeOf((*VmwareUplinkPortTeamingPolicy)(nil)).Elem() +} + +type VnicPortArgument struct { + DynamicData + + Vnic string `xml:"vnic"` + Port DistributedVirtualSwitchPortConnection `xml:"port"` +} + +func init() { + t["VnicPortArgument"] = reflect.TypeOf((*VnicPortArgument)(nil)).Elem() +} + +type VolumeEditorError struct { + CustomizationFault +} + +func init() { + t["VolumeEditorError"] = reflect.TypeOf((*VolumeEditorError)(nil)).Elem() +} + +type VolumeEditorErrorFault VolumeEditorError + +func init() { + t["VolumeEditorErrorFault"] = reflect.TypeOf((*VolumeEditorErrorFault)(nil)).Elem() +} + +type VramLimitLicense struct { + NotEnoughLicenses + + Limit int32 `xml:"limit"` +} + +func init() { + t["VramLimitLicense"] = reflect.TypeOf((*VramLimitLicense)(nil)).Elem() +} + +type VramLimitLicenseFault VramLimitLicense + +func init() { + t["VramLimitLicenseFault"] = reflect.TypeOf((*VramLimitLicenseFault)(nil)).Elem() +} + +type VrpResourceAllocationInfo struct { + ResourceAllocationInfo + + ReservationLimit int64 `xml:"reservationLimit,omitempty"` +} + +func init() { + t["VrpResourceAllocationInfo"] = reflect.TypeOf((*VrpResourceAllocationInfo)(nil)).Elem() +} + +type VsanClusterConfigInfo struct { + DynamicData + + Enabled *bool `xml:"enabled"` + DefaultConfig *VsanClusterConfigInfoHostDefaultInfo `xml:"defaultConfig,omitempty"` +} + +func init() { + t["VsanClusterConfigInfo"] = reflect.TypeOf((*VsanClusterConfigInfo)(nil)).Elem() +} + +type VsanClusterConfigInfoHostDefaultInfo struct { + DynamicData + + Uuid string `xml:"uuid,omitempty"` + AutoClaimStorage *bool `xml:"autoClaimStorage"` + ChecksumEnabled *bool `xml:"checksumEnabled"` +} + +func init() { + t["VsanClusterConfigInfoHostDefaultInfo"] = reflect.TypeOf((*VsanClusterConfigInfoHostDefaultInfo)(nil)).Elem() +} + +type VsanClusterUuidMismatch struct { + CannotMoveVsanEnabledHost + + HostClusterUuid string `xml:"hostClusterUuid"` + DestinationClusterUuid string `xml:"destinationClusterUuid"` +} + +func init() { + t["VsanClusterUuidMismatch"] = reflect.TypeOf((*VsanClusterUuidMismatch)(nil)).Elem() +} + +type VsanClusterUuidMismatchFault VsanClusterUuidMismatch + +func init() { + t["VsanClusterUuidMismatchFault"] = reflect.TypeOf((*VsanClusterUuidMismatchFault)(nil)).Elem() +} + +type VsanDiskFault struct { + VsanFault + + Device string `xml:"device,omitempty"` +} + +func init() { + t["VsanDiskFault"] = reflect.TypeOf((*VsanDiskFault)(nil)).Elem() +} + +type VsanDiskFaultFault BaseVsanDiskFault + +func init() { + t["VsanDiskFaultFault"] = reflect.TypeOf((*VsanDiskFaultFault)(nil)).Elem() +} + +type VsanFault struct { + VimFault +} + +func init() { + t["VsanFault"] = reflect.TypeOf((*VsanFault)(nil)).Elem() +} + +type VsanFaultFault BaseVsanFault + +func init() { + t["VsanFaultFault"] = reflect.TypeOf((*VsanFaultFault)(nil)).Elem() +} + +type VsanHostClusterStatus struct { + DynamicData + + Uuid string `xml:"uuid,omitempty"` + NodeUuid string `xml:"nodeUuid,omitempty"` + Health string `xml:"health"` + NodeState VsanHostClusterStatusState `xml:"nodeState"` + MemberUuid []string `xml:"memberUuid,omitempty"` +} + +func init() { + t["VsanHostClusterStatus"] = reflect.TypeOf((*VsanHostClusterStatus)(nil)).Elem() +} + +type VsanHostClusterStatusState struct { + DynamicData + + State string `xml:"state"` + Completion *VsanHostClusterStatusStateCompletionEstimate `xml:"completion,omitempty"` +} + +func init() { + t["VsanHostClusterStatusState"] = reflect.TypeOf((*VsanHostClusterStatusState)(nil)).Elem() +} + +type VsanHostClusterStatusStateCompletionEstimate struct { + DynamicData + + CompleteTime *time.Time `xml:"completeTime"` + PercentComplete int32 `xml:"percentComplete,omitempty"` +} + +func init() { + t["VsanHostClusterStatusStateCompletionEstimate"] = reflect.TypeOf((*VsanHostClusterStatusStateCompletionEstimate)(nil)).Elem() +} + +type VsanHostConfigInfo struct { + DynamicData + + Enabled *bool `xml:"enabled"` + HostSystem *ManagedObjectReference `xml:"hostSystem,omitempty"` + ClusterInfo *VsanHostConfigInfoClusterInfo `xml:"clusterInfo,omitempty"` + StorageInfo *VsanHostConfigInfoStorageInfo `xml:"storageInfo,omitempty"` + NetworkInfo *VsanHostConfigInfoNetworkInfo `xml:"networkInfo,omitempty"` + FaultDomainInfo *VsanHostFaultDomainInfo `xml:"faultDomainInfo,omitempty"` +} + +func init() { + t["VsanHostConfigInfo"] = reflect.TypeOf((*VsanHostConfigInfo)(nil)).Elem() +} + +type VsanHostConfigInfoClusterInfo struct { + DynamicData + + Uuid string `xml:"uuid,omitempty"` + NodeUuid string `xml:"nodeUuid,omitempty"` +} + +func init() { + t["VsanHostConfigInfoClusterInfo"] = reflect.TypeOf((*VsanHostConfigInfoClusterInfo)(nil)).Elem() +} + +type VsanHostConfigInfoNetworkInfo struct { + DynamicData + + Port []VsanHostConfigInfoNetworkInfoPortConfig `xml:"port,omitempty"` +} + +func init() { + t["VsanHostConfigInfoNetworkInfo"] = reflect.TypeOf((*VsanHostConfigInfoNetworkInfo)(nil)).Elem() +} + +type VsanHostConfigInfoNetworkInfoPortConfig struct { + DynamicData + + IpConfig *VsanHostIpConfig `xml:"ipConfig,omitempty"` + Device string `xml:"device"` +} + +func init() { + t["VsanHostConfigInfoNetworkInfoPortConfig"] = reflect.TypeOf((*VsanHostConfigInfoNetworkInfoPortConfig)(nil)).Elem() +} + +type VsanHostConfigInfoStorageInfo struct { + DynamicData + + AutoClaimStorage *bool `xml:"autoClaimStorage"` + DiskMapping []VsanHostDiskMapping `xml:"diskMapping,omitempty"` + DiskMapInfo []VsanHostDiskMapInfo `xml:"diskMapInfo,omitempty"` + ChecksumEnabled *bool `xml:"checksumEnabled"` +} + +func init() { + t["VsanHostConfigInfoStorageInfo"] = reflect.TypeOf((*VsanHostConfigInfoStorageInfo)(nil)).Elem() +} + +type VsanHostDecommissionMode struct { + DynamicData + + ObjectAction string `xml:"objectAction"` +} + +func init() { + t["VsanHostDecommissionMode"] = reflect.TypeOf((*VsanHostDecommissionMode)(nil)).Elem() +} + +type VsanHostDiskMapInfo struct { + DynamicData + + Mapping VsanHostDiskMapping `xml:"mapping"` + Mounted bool `xml:"mounted"` +} + +func init() { + t["VsanHostDiskMapInfo"] = reflect.TypeOf((*VsanHostDiskMapInfo)(nil)).Elem() +} + +type VsanHostDiskMapResult struct { + DynamicData + + Mapping VsanHostDiskMapping `xml:"mapping"` + DiskResult []VsanHostDiskResult `xml:"diskResult,omitempty"` + Error *LocalizedMethodFault `xml:"error,omitempty"` +} + +func init() { + t["VsanHostDiskMapResult"] = reflect.TypeOf((*VsanHostDiskMapResult)(nil)).Elem() +} + +type VsanHostDiskMapping struct { + DynamicData + + Ssd HostScsiDisk `xml:"ssd"` + NonSsd []HostScsiDisk `xml:"nonSsd"` +} + +func init() { + t["VsanHostDiskMapping"] = reflect.TypeOf((*VsanHostDiskMapping)(nil)).Elem() +} + +type VsanHostDiskResult struct { + DynamicData + + Disk HostScsiDisk `xml:"disk"` + State string `xml:"state"` + VsanUuid string `xml:"vsanUuid,omitempty"` + Error *LocalizedMethodFault `xml:"error,omitempty"` + Degraded *bool `xml:"degraded"` +} + +func init() { + t["VsanHostDiskResult"] = reflect.TypeOf((*VsanHostDiskResult)(nil)).Elem() +} + +type VsanHostFaultDomainInfo struct { + DynamicData + + Name string `xml:"name"` +} + +func init() { + t["VsanHostFaultDomainInfo"] = reflect.TypeOf((*VsanHostFaultDomainInfo)(nil)).Elem() +} + +type VsanHostIpConfig struct { + DynamicData + + UpstreamIpAddress string `xml:"upstreamIpAddress"` + DownstreamIpAddress string `xml:"downstreamIpAddress"` +} + +func init() { + t["VsanHostIpConfig"] = reflect.TypeOf((*VsanHostIpConfig)(nil)).Elem() +} + +type VsanHostMembershipInfo struct { + DynamicData + + NodeUuid string `xml:"nodeUuid"` + Hostname string `xml:"hostname"` +} + +func init() { + t["VsanHostMembershipInfo"] = reflect.TypeOf((*VsanHostMembershipInfo)(nil)).Elem() +} + +type VsanHostRuntimeInfo struct { + DynamicData + + MembershipList []VsanHostMembershipInfo `xml:"membershipList,omitempty"` + DiskIssues []VsanHostRuntimeInfoDiskIssue `xml:"diskIssues,omitempty"` + AccessGenNo int32 `xml:"accessGenNo,omitempty"` +} + +func init() { + t["VsanHostRuntimeInfo"] = reflect.TypeOf((*VsanHostRuntimeInfo)(nil)).Elem() +} + +type VsanHostRuntimeInfoDiskIssue struct { + DynamicData + + DiskId string `xml:"diskId"` + Issue string `xml:"issue"` +} + +func init() { + t["VsanHostRuntimeInfoDiskIssue"] = reflect.TypeOf((*VsanHostRuntimeInfoDiskIssue)(nil)).Elem() +} + +type VsanHostVsanDiskInfo struct { + DynamicData + + VsanUuid string `xml:"vsanUuid"` + FormatVersion int32 `xml:"formatVersion"` +} + +func init() { + t["VsanHostVsanDiskInfo"] = reflect.TypeOf((*VsanHostVsanDiskInfo)(nil)).Elem() +} + +type VsanIncompatibleDiskMapping struct { + VsanDiskFault +} + +func init() { + t["VsanIncompatibleDiskMapping"] = reflect.TypeOf((*VsanIncompatibleDiskMapping)(nil)).Elem() +} + +type VsanIncompatibleDiskMappingFault VsanIncompatibleDiskMapping + +func init() { + t["VsanIncompatibleDiskMappingFault"] = reflect.TypeOf((*VsanIncompatibleDiskMappingFault)(nil)).Elem() +} + +type VsanNewPolicyBatch struct { + DynamicData + + Size []int64 `xml:"size,omitempty"` + Policy string `xml:"policy,omitempty"` +} + +func init() { + t["VsanNewPolicyBatch"] = reflect.TypeOf((*VsanNewPolicyBatch)(nil)).Elem() +} + +type VsanPolicyChangeBatch struct { + DynamicData + + Uuid []string `xml:"uuid,omitempty"` + Policy string `xml:"policy,omitempty"` +} + +func init() { + t["VsanPolicyChangeBatch"] = reflect.TypeOf((*VsanPolicyChangeBatch)(nil)).Elem() +} + +type VsanPolicyCost struct { + DynamicData + + ChangeDataSize int64 `xml:"changeDataSize,omitempty"` + CurrentDataSize int64 `xml:"currentDataSize,omitempty"` + TempDataSize int64 `xml:"tempDataSize,omitempty"` + CopyDataSize int64 `xml:"copyDataSize,omitempty"` + ChangeFlashReadCacheSize int64 `xml:"changeFlashReadCacheSize,omitempty"` + CurrentFlashReadCacheSize int64 `xml:"currentFlashReadCacheSize,omitempty"` + CurrentDiskSpaceToAddressSpaceRatio float32 `xml:"currentDiskSpaceToAddressSpaceRatio,omitempty"` + DiskSpaceToAddressSpaceRatio float32 `xml:"diskSpaceToAddressSpaceRatio,omitempty"` +} + +func init() { + t["VsanPolicyCost"] = reflect.TypeOf((*VsanPolicyCost)(nil)).Elem() +} + +type VsanPolicySatisfiability struct { + DynamicData + + Uuid string `xml:"uuid,omitempty"` + IsSatisfiable bool `xml:"isSatisfiable"` + Reason *LocalizableMessage `xml:"reason,omitempty"` + Cost *VsanPolicyCost `xml:"cost,omitempty"` +} + +func init() { + t["VsanPolicySatisfiability"] = reflect.TypeOf((*VsanPolicySatisfiability)(nil)).Elem() +} + +type VsanUpgradeSystemAPIBrokenIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["VsanUpgradeSystemAPIBrokenIssue"] = reflect.TypeOf((*VsanUpgradeSystemAPIBrokenIssue)(nil)).Elem() +} + +type VsanUpgradeSystemAutoClaimEnabledOnHostsIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["VsanUpgradeSystemAutoClaimEnabledOnHostsIssue"] = reflect.TypeOf((*VsanUpgradeSystemAutoClaimEnabledOnHostsIssue)(nil)).Elem() +} + +type VsanUpgradeSystemHostsDisconnectedIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["VsanUpgradeSystemHostsDisconnectedIssue"] = reflect.TypeOf((*VsanUpgradeSystemHostsDisconnectedIssue)(nil)).Elem() +} + +type VsanUpgradeSystemMissingHostsInClusterIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["VsanUpgradeSystemMissingHostsInClusterIssue"] = reflect.TypeOf((*VsanUpgradeSystemMissingHostsInClusterIssue)(nil)).Elem() +} + +type VsanUpgradeSystemNetworkPartitionInfo struct { + DynamicData + + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["VsanUpgradeSystemNetworkPartitionInfo"] = reflect.TypeOf((*VsanUpgradeSystemNetworkPartitionInfo)(nil)).Elem() +} + +type VsanUpgradeSystemNetworkPartitionIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Partitions []VsanUpgradeSystemNetworkPartitionInfo `xml:"partitions"` +} + +func init() { + t["VsanUpgradeSystemNetworkPartitionIssue"] = reflect.TypeOf((*VsanUpgradeSystemNetworkPartitionIssue)(nil)).Elem() +} + +type VsanUpgradeSystemNotEnoughFreeCapacityIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + ReducedRedundancyUpgradePossible bool `xml:"reducedRedundancyUpgradePossible"` +} + +func init() { + t["VsanUpgradeSystemNotEnoughFreeCapacityIssue"] = reflect.TypeOf((*VsanUpgradeSystemNotEnoughFreeCapacityIssue)(nil)).Elem() +} + +type VsanUpgradeSystemPreflightCheckIssue struct { + DynamicData + + Msg string `xml:"msg"` +} + +func init() { + t["VsanUpgradeSystemPreflightCheckIssue"] = reflect.TypeOf((*VsanUpgradeSystemPreflightCheckIssue)(nil)).Elem() +} + +type VsanUpgradeSystemPreflightCheckResult struct { + DynamicData + + Issues []BaseVsanUpgradeSystemPreflightCheckIssue `xml:"issues,omitempty,typeattr"` + DiskMappingToRestore *VsanHostDiskMapping `xml:"diskMappingToRestore,omitempty"` +} + +func init() { + t["VsanUpgradeSystemPreflightCheckResult"] = reflect.TypeOf((*VsanUpgradeSystemPreflightCheckResult)(nil)).Elem() +} + +type VsanUpgradeSystemRogueHostsInClusterIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Uuids []string `xml:"uuids"` +} + +func init() { + t["VsanUpgradeSystemRogueHostsInClusterIssue"] = reflect.TypeOf((*VsanUpgradeSystemRogueHostsInClusterIssue)(nil)).Elem() +} + +type VsanUpgradeSystemUpgradeHistoryDiskGroupOp struct { + VsanUpgradeSystemUpgradeHistoryItem + + Operation string `xml:"operation"` + DiskMapping VsanHostDiskMapping `xml:"diskMapping"` +} + +func init() { + t["VsanUpgradeSystemUpgradeHistoryDiskGroupOp"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeHistoryDiskGroupOp)(nil)).Elem() +} + +type VsanUpgradeSystemUpgradeHistoryItem struct { + DynamicData + + Timestamp time.Time `xml:"timestamp"` + Host *ManagedObjectReference `xml:"host,omitempty"` + Message string `xml:"message"` + Task *ManagedObjectReference `xml:"task,omitempty"` +} + +func init() { + t["VsanUpgradeSystemUpgradeHistoryItem"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeHistoryItem)(nil)).Elem() +} + +type VsanUpgradeSystemUpgradeHistoryPreflightFail struct { + VsanUpgradeSystemUpgradeHistoryItem + + PreflightResult VsanUpgradeSystemPreflightCheckResult `xml:"preflightResult"` +} + +func init() { + t["VsanUpgradeSystemUpgradeHistoryPreflightFail"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeHistoryPreflightFail)(nil)).Elem() +} + +type VsanUpgradeSystemUpgradeStatus struct { + DynamicData + + InProgress bool `xml:"inProgress"` + History []BaseVsanUpgradeSystemUpgradeHistoryItem `xml:"history,omitempty,typeattr"` + Aborted *bool `xml:"aborted"` + Completed *bool `xml:"completed"` + Progress int32 `xml:"progress,omitempty"` +} + +func init() { + t["VsanUpgradeSystemUpgradeStatus"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeStatus)(nil)).Elem() +} + +type VsanUpgradeSystemV2ObjectsPresentDuringDowngradeIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Uuids []string `xml:"uuids"` +} + +func init() { + t["VsanUpgradeSystemV2ObjectsPresentDuringDowngradeIssue"] = reflect.TypeOf((*VsanUpgradeSystemV2ObjectsPresentDuringDowngradeIssue)(nil)).Elem() +} + +type VsanUpgradeSystemWrongEsxVersionIssue struct { + VsanUpgradeSystemPreflightCheckIssue + + Hosts []ManagedObjectReference `xml:"hosts"` +} + +func init() { + t["VsanUpgradeSystemWrongEsxVersionIssue"] = reflect.TypeOf((*VsanUpgradeSystemWrongEsxVersionIssue)(nil)).Elem() +} + +type VspanDestPortConflict struct { + DvsFault + + VspanSessionKey1 string `xml:"vspanSessionKey1"` + VspanSessionKey2 string `xml:"vspanSessionKey2"` + PortKey string `xml:"portKey"` +} + +func init() { + t["VspanDestPortConflict"] = reflect.TypeOf((*VspanDestPortConflict)(nil)).Elem() +} + +type VspanDestPortConflictFault VspanDestPortConflict + +func init() { + t["VspanDestPortConflictFault"] = reflect.TypeOf((*VspanDestPortConflictFault)(nil)).Elem() +} + +type VspanPortConflict struct { + DvsFault + + VspanSessionKey1 string `xml:"vspanSessionKey1"` + VspanSessionKey2 string `xml:"vspanSessionKey2"` + PortKey string `xml:"portKey"` +} + +func init() { + t["VspanPortConflict"] = reflect.TypeOf((*VspanPortConflict)(nil)).Elem() +} + +type VspanPortConflictFault VspanPortConflict + +func init() { + t["VspanPortConflictFault"] = reflect.TypeOf((*VspanPortConflictFault)(nil)).Elem() +} + +type VspanPortMoveFault struct { + DvsFault + + SrcPortgroupName string `xml:"srcPortgroupName"` + DestPortgroupName string `xml:"destPortgroupName"` + PortKey string `xml:"portKey"` +} + +func init() { + t["VspanPortMoveFault"] = reflect.TypeOf((*VspanPortMoveFault)(nil)).Elem() +} + +type VspanPortMoveFaultFault VspanPortMoveFault + +func init() { + t["VspanPortMoveFaultFault"] = reflect.TypeOf((*VspanPortMoveFaultFault)(nil)).Elem() +} + +type VspanPortPromiscChangeFault struct { + DvsFault + + PortKey string `xml:"portKey"` +} + +func init() { + t["VspanPortPromiscChangeFault"] = reflect.TypeOf((*VspanPortPromiscChangeFault)(nil)).Elem() +} + +type VspanPortPromiscChangeFaultFault VspanPortPromiscChangeFault + +func init() { + t["VspanPortPromiscChangeFaultFault"] = reflect.TypeOf((*VspanPortPromiscChangeFaultFault)(nil)).Elem() +} + +type VspanPortgroupPromiscChangeFault struct { + DvsFault + + PortgroupName string `xml:"portgroupName"` +} + +func init() { + t["VspanPortgroupPromiscChangeFault"] = reflect.TypeOf((*VspanPortgroupPromiscChangeFault)(nil)).Elem() +} + +type VspanPortgroupPromiscChangeFaultFault VspanPortgroupPromiscChangeFault + +func init() { + t["VspanPortgroupPromiscChangeFaultFault"] = reflect.TypeOf((*VspanPortgroupPromiscChangeFaultFault)(nil)).Elem() +} + +type VspanPortgroupTypeChangeFault struct { + DvsFault + + PortgroupName string `xml:"portgroupName"` +} + +func init() { + t["VspanPortgroupTypeChangeFault"] = reflect.TypeOf((*VspanPortgroupTypeChangeFault)(nil)).Elem() +} + +type VspanPortgroupTypeChangeFaultFault VspanPortgroupTypeChangeFault + +func init() { + t["VspanPortgroupTypeChangeFaultFault"] = reflect.TypeOf((*VspanPortgroupTypeChangeFaultFault)(nil)).Elem() +} + +type VspanPromiscuousPortNotSupported struct { + DvsFault + + VspanSessionKey string `xml:"vspanSessionKey"` + PortKey string `xml:"portKey"` +} + +func init() { + t["VspanPromiscuousPortNotSupported"] = reflect.TypeOf((*VspanPromiscuousPortNotSupported)(nil)).Elem() +} + +type VspanPromiscuousPortNotSupportedFault VspanPromiscuousPortNotSupported + +func init() { + t["VspanPromiscuousPortNotSupportedFault"] = reflect.TypeOf((*VspanPromiscuousPortNotSupportedFault)(nil)).Elem() +} + +type VspanSameSessionPortConflict struct { + DvsFault + + VspanSessionKey string `xml:"vspanSessionKey"` + PortKey string `xml:"portKey"` +} + +func init() { + t["VspanSameSessionPortConflict"] = reflect.TypeOf((*VspanSameSessionPortConflict)(nil)).Elem() +} + +type VspanSameSessionPortConflictFault VspanSameSessionPortConflict + +func init() { + t["VspanSameSessionPortConflictFault"] = reflect.TypeOf((*VspanSameSessionPortConflictFault)(nil)).Elem() +} + +type VvolDatastoreInfo struct { + DatastoreInfo + + VvolDS *HostVvolVolume `xml:"vvolDS,omitempty"` +} + +func init() { + t["VvolDatastoreInfo"] = reflect.TypeOf((*VvolDatastoreInfo)(nil)).Elem() +} + +type WaitForUpdates WaitForUpdatesRequestType + +func init() { + t["WaitForUpdates"] = reflect.TypeOf((*WaitForUpdates)(nil)).Elem() +} + +type WaitForUpdatesEx WaitForUpdatesExRequestType + +func init() { + t["WaitForUpdatesEx"] = reflect.TypeOf((*WaitForUpdatesEx)(nil)).Elem() +} + +type WaitForUpdatesExRequestType struct { + This ManagedObjectReference `xml:"_this"` + Version string `xml:"version,omitempty"` + Options *WaitOptions `xml:"options,omitempty"` +} + +func init() { + t["WaitForUpdatesExRequestType"] = reflect.TypeOf((*WaitForUpdatesExRequestType)(nil)).Elem() +} + +type WaitForUpdatesExResponse struct { + Returnval *UpdateSet `xml:"returnval,omitempty"` +} + +type WaitForUpdatesRequestType struct { + This ManagedObjectReference `xml:"_this"` + Version string `xml:"version,omitempty"` +} + +func init() { + t["WaitForUpdatesRequestType"] = reflect.TypeOf((*WaitForUpdatesRequestType)(nil)).Elem() +} + +type WaitForUpdatesResponse struct { + Returnval UpdateSet `xml:"returnval"` +} + +type WaitOptions struct { + DynamicData + + MaxWaitSeconds int32 `xml:"maxWaitSeconds,omitempty"` + MaxObjectUpdates int32 `xml:"maxObjectUpdates,omitempty"` +} + +func init() { + t["WaitOptions"] = reflect.TypeOf((*WaitOptions)(nil)).Elem() +} + +type WakeOnLanNotSupported struct { + VirtualHardwareCompatibilityIssue +} + +func init() { + t["WakeOnLanNotSupported"] = reflect.TypeOf((*WakeOnLanNotSupported)(nil)).Elem() +} + +type WakeOnLanNotSupportedByVmotionNIC struct { + HostPowerOpFailed +} + +func init() { + t["WakeOnLanNotSupportedByVmotionNIC"] = reflect.TypeOf((*WakeOnLanNotSupportedByVmotionNIC)(nil)).Elem() +} + +type WakeOnLanNotSupportedByVmotionNICFault WakeOnLanNotSupportedByVmotionNIC + +func init() { + t["WakeOnLanNotSupportedByVmotionNICFault"] = reflect.TypeOf((*WakeOnLanNotSupportedByVmotionNICFault)(nil)).Elem() +} + +type WakeOnLanNotSupportedFault WakeOnLanNotSupported + +func init() { + t["WakeOnLanNotSupportedFault"] = reflect.TypeOf((*WakeOnLanNotSupportedFault)(nil)).Elem() +} + +type WarningUpgradeEvent struct { + UpgradeEvent +} + +func init() { + t["WarningUpgradeEvent"] = reflect.TypeOf((*WarningUpgradeEvent)(nil)).Elem() +} + +type WeeklyTaskScheduler struct { + DailyTaskScheduler + + Sunday bool `xml:"sunday"` + Monday bool `xml:"monday"` + Tuesday bool `xml:"tuesday"` + Wednesday bool `xml:"wednesday"` + Thursday bool `xml:"thursday"` + Friday bool `xml:"friday"` + Saturday bool `xml:"saturday"` +} + +func init() { + t["WeeklyTaskScheduler"] = reflect.TypeOf((*WeeklyTaskScheduler)(nil)).Elem() +} + +type WillLoseHAProtection struct { + MigrationFault + + Resolution string `xml:"resolution"` +} + +func init() { + t["WillLoseHAProtection"] = reflect.TypeOf((*WillLoseHAProtection)(nil)).Elem() +} + +type WillLoseHAProtectionFault WillLoseHAProtection + +func init() { + t["WillLoseHAProtectionFault"] = reflect.TypeOf((*WillLoseHAProtectionFault)(nil)).Elem() +} + +type WillModifyConfigCpuRequirements struct { + MigrationFault +} + +func init() { + t["WillModifyConfigCpuRequirements"] = reflect.TypeOf((*WillModifyConfigCpuRequirements)(nil)).Elem() +} + +type WillModifyConfigCpuRequirementsFault WillModifyConfigCpuRequirements + +func init() { + t["WillModifyConfigCpuRequirementsFault"] = reflect.TypeOf((*WillModifyConfigCpuRequirementsFault)(nil)).Elem() +} + +type WillResetSnapshotDirectory struct { + MigrationFault +} + +func init() { + t["WillResetSnapshotDirectory"] = reflect.TypeOf((*WillResetSnapshotDirectory)(nil)).Elem() +} + +type WillResetSnapshotDirectoryFault WillResetSnapshotDirectory + +func init() { + t["WillResetSnapshotDirectoryFault"] = reflect.TypeOf((*WillResetSnapshotDirectoryFault)(nil)).Elem() +} + +type WinNetBIOSConfigInfo struct { + NetBIOSConfigInfo + + PrimaryWINS string `xml:"primaryWINS"` + SecondaryWINS string `xml:"secondaryWINS,omitempty"` +} + +func init() { + t["WinNetBIOSConfigInfo"] = reflect.TypeOf((*WinNetBIOSConfigInfo)(nil)).Elem() +} + +type WipeDiskFault struct { + VimFault +} + +func init() { + t["WipeDiskFault"] = reflect.TypeOf((*WipeDiskFault)(nil)).Elem() +} + +type WipeDiskFaultFault WipeDiskFault + +func init() { + t["WipeDiskFaultFault"] = reflect.TypeOf((*WipeDiskFaultFault)(nil)).Elem() +} + +type XmlToCustomizationSpecItem XmlToCustomizationSpecItemRequestType + +func init() { + t["XmlToCustomizationSpecItem"] = reflect.TypeOf((*XmlToCustomizationSpecItem)(nil)).Elem() +} + +type XmlToCustomizationSpecItemRequestType struct { + This ManagedObjectReference `xml:"_this"` + SpecItemXml string `xml:"specItemXml"` +} + +func init() { + t["XmlToCustomizationSpecItemRequestType"] = reflect.TypeOf((*XmlToCustomizationSpecItemRequestType)(nil)).Elem() +} + +type XmlToCustomizationSpecItemResponse struct { + Returnval CustomizationSpecItem `xml:"returnval"` +} + +type ZeroFillVirtualDiskRequestType struct { + This ManagedObjectReference `xml:"_this"` + Name string `xml:"name"` + Datacenter *ManagedObjectReference `xml:"datacenter,omitempty"` +} + +func init() { + t["ZeroFillVirtualDiskRequestType"] = reflect.TypeOf((*ZeroFillVirtualDiskRequestType)(nil)).Elem() +} + +type ZeroFillVirtualDisk_Task ZeroFillVirtualDiskRequestType + +func init() { + t["ZeroFillVirtualDisk_Task"] = reflect.TypeOf((*ZeroFillVirtualDisk_Task)(nil)).Elem() +} + +type ZeroFillVirtualDisk_TaskResponse struct { + Returnval ManagedObjectReference `xml:"returnval"` +} diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/LICENSE b/vendor/github.com/vmware/govmomi/vim25/xml/LICENSE new file mode 100644 index 0000000000..7448756763 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/xml/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/extras.go b/vendor/github.com/vmware/govmomi/vim25/xml/extras.go new file mode 100644 index 0000000000..9f1a764d58 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/xml/extras.go @@ -0,0 +1,93 @@ +/* +Copyright (c) 2014 VMware, 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 xml + +import ( + "reflect" + "time" +) + +var xmlSchemaInstance = Name{Space: "http://www.w3.org/2001/XMLSchema-instance", Local: "type"} + +var stringToTypeMap = map[string]reflect.Type{ + "xsd:boolean": reflect.TypeOf((*bool)(nil)).Elem(), + "xsd:byte": reflect.TypeOf((*int8)(nil)).Elem(), + "xsd:short": reflect.TypeOf((*int16)(nil)).Elem(), + "xsd:int": reflect.TypeOf((*int32)(nil)).Elem(), + "xsd:long": reflect.TypeOf((*int64)(nil)).Elem(), + "xsd:unsignedByte": reflect.TypeOf((*uint8)(nil)).Elem(), + "xsd:unsignedShort": reflect.TypeOf((*uint16)(nil)).Elem(), + "xsd:unsignedInt": reflect.TypeOf((*uint32)(nil)).Elem(), + "xsd:unsignedLong": reflect.TypeOf((*uint64)(nil)).Elem(), + "xsd:float": reflect.TypeOf((*float32)(nil)).Elem(), + "xsd:double": reflect.TypeOf((*float64)(nil)).Elem(), + "xsd:string": reflect.TypeOf((*string)(nil)).Elem(), + "xsd:dateTime": reflect.TypeOf((*time.Time)(nil)).Elem(), + "xsd:base64Binary": reflect.TypeOf((*[]byte)(nil)).Elem(), +} + +// Return a reflect.Type for the specified type. Nil if unknown. +func stringToType(s string) reflect.Type { + return stringToTypeMap[s] +} + +// Return a string for the specified reflect.Type. Panic if unknown. +func typeToString(typ reflect.Type) string { + switch typ.Kind() { + case reflect.Bool: + return "xsd:boolean" + case reflect.Int8: + return "xsd:byte" + case reflect.Int16: + return "xsd:short" + case reflect.Int32: + return "xsd:int" + case reflect.Int, reflect.Int64: + return "xsd:long" + case reflect.Uint8: + return "xsd:unsignedByte" + case reflect.Uint16: + return "xsd:unsignedShort" + case reflect.Uint32: + return "xsd:unsignedInt" + case reflect.Uint, reflect.Uint64: + return "xsd:unsignedLong" + case reflect.Float32: + return "xsd:float" + case reflect.Float64: + return "xsd:double" + case reflect.String: + return "xsd:string" + case reflect.Struct: + if typ == stringToTypeMap["xsd:dateTime"] { + return "xsd:dateTime" + } + + // Expect any other struct to be handled... + return typ.Name() + case reflect.Slice: + if typ.Elem().Kind() == reflect.Uint8 { + return "xsd:base64Binary" + } + case reflect.Array: + if typ.Elem().Kind() == reflect.Uint8 { + return "xsd:base64Binary" + } + } + + panic("don't know what to do for type: " + typ.String()) +} diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/marshal.go b/vendor/github.com/vmware/govmomi/vim25/xml/marshal.go new file mode 100644 index 0000000000..39bbac1d17 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/xml/marshal.go @@ -0,0 +1,949 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xml + +import ( + "bufio" + "bytes" + "encoding" + "fmt" + "io" + "reflect" + "strconv" + "strings" +) + +const ( + // A generic XML header suitable for use with the output of Marshal. + // This is not automatically added to any output of this package, + // it is provided as a convenience. + Header = `` + "\n" +) + +// Marshal returns the XML encoding of v. +// +// Marshal handles an array or slice by marshalling each of the elements. +// Marshal handles a pointer by marshalling the value it points at or, if the +// pointer is nil, by writing nothing. Marshal handles an interface value by +// marshalling the value it contains or, if the interface value is nil, by +// writing nothing. Marshal handles all other data by writing one or more XML +// elements containing the data. +// +// The name for the XML elements is taken from, in order of preference: +// - the tag on the XMLName field, if the data is a struct +// - the value of the XMLName field of type xml.Name +// - the tag of the struct field used to obtain the data +// - the name of the struct field used to obtain the data +// - the name of the marshalled type +// +// The XML element for a struct contains marshalled elements for each of the +// exported fields of the struct, with these exceptions: +// - the XMLName field, described above, is omitted. +// - a field with tag "-" is omitted. +// - a field with tag "name,attr" becomes an attribute with +// the given name in the XML element. +// - a field with tag ",attr" becomes an attribute with the +// field name in the XML element. +// - a field with tag ",chardata" is written as character data, +// not as an XML element. +// - a field with tag ",innerxml" is written verbatim, not subject +// to the usual marshalling procedure. +// - a field with tag ",comment" is written as an XML comment, not +// subject to the usual marshalling procedure. It must not contain +// the "--" string within it. +// - a field with a tag including the "omitempty" option is omitted +// if the field value is empty. The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or +// string of length zero. +// - an anonymous struct field is handled as if the fields of its +// value were part of the outer struct. +// +// If a field uses a tag "a>b>c", then the element c will be nested inside +// parent elements a and b. Fields that appear next to each other that name +// the same parent will be enclosed in one XML element. +// +// See MarshalIndent for an example. +// +// Marshal will return an error if asked to marshal a channel, function, or map. +func Marshal(v interface{}) ([]byte, error) { + var b bytes.Buffer + if err := NewEncoder(&b).Encode(v); err != nil { + return nil, err + } + return b.Bytes(), nil +} + +// Marshaler is the interface implemented by objects that can marshal +// themselves into valid XML elements. +// +// MarshalXML encodes the receiver as zero or more XML elements. +// By convention, arrays or slices are typically encoded as a sequence +// of elements, one per entry. +// Using start as the element tag is not required, but doing so +// will enable Unmarshal to match the XML elements to the correct +// struct field. +// One common implementation strategy is to construct a separate +// value with a layout corresponding to the desired XML and then +// to encode it using e.EncodeElement. +// Another common strategy is to use repeated calls to e.EncodeToken +// to generate the XML output one token at a time. +// The sequence of encoded tokens must make up zero or more valid +// XML elements. +type Marshaler interface { + MarshalXML(e *Encoder, start StartElement) error +} + +// MarshalerAttr is the interface implemented by objects that can marshal +// themselves into valid XML attributes. +// +// MarshalXMLAttr returns an XML attribute with the encoded value of the receiver. +// Using name as the attribute name is not required, but doing so +// will enable Unmarshal to match the attribute to the correct +// struct field. +// If MarshalXMLAttr returns the zero attribute Attr{}, no attribute +// will be generated in the output. +// MarshalXMLAttr is used only for struct fields with the +// "attr" option in the field tag. +type MarshalerAttr interface { + MarshalXMLAttr(name Name) (Attr, error) +} + +// MarshalIndent works like Marshal, but each XML element begins on a new +// indented line that starts with prefix and is followed by one or more +// copies of indent according to the nesting depth. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + var b bytes.Buffer + enc := NewEncoder(&b) + enc.Indent(prefix, indent) + if err := enc.Encode(v); err != nil { + return nil, err + } + return b.Bytes(), nil +} + +// An Encoder writes XML data to an output stream. +type Encoder struct { + p printer +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + e := &Encoder{printer{Writer: bufio.NewWriter(w)}} + e.p.encoder = e + return e +} + +// Indent sets the encoder to generate XML in which each element +// begins on a new indented line that starts with prefix and is followed by +// one or more copies of indent according to the nesting depth. +func (enc *Encoder) Indent(prefix, indent string) { + enc.p.prefix = prefix + enc.p.indent = indent +} + +// Encode writes the XML encoding of v to the stream. +// +// See the documentation for Marshal for details about the conversion +// of Go values to XML. +// +// Encode calls Flush before returning. +func (enc *Encoder) Encode(v interface{}) error { + err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil) + if err != nil { + return err + } + return enc.p.Flush() +} + +// EncodeElement writes the XML encoding of v to the stream, +// using start as the outermost tag in the encoding. +// +// See the documentation for Marshal for details about the conversion +// of Go values to XML. +// +// EncodeElement calls Flush before returning. +func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error { + err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start) + if err != nil { + return err + } + return enc.p.Flush() +} + +var ( + endComment = []byte("-->") + endProcInst = []byte("?>") + endDirective = []byte(">") +) + +// EncodeToken writes the given XML token to the stream. +// It returns an error if StartElement and EndElement tokens are not properly matched. +// +// EncodeToken does not call Flush, because usually it is part of a larger operation +// such as Encode or EncodeElement (or a custom Marshaler's MarshalXML invoked +// during those), and those will call Flush when finished. +// Callers that create an Encoder and then invoke EncodeToken directly, without +// using Encode or EncodeElement, need to call Flush when finished to ensure +// that the XML is written to the underlying writer. +// +// EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token +// in the stream. +func (enc *Encoder) EncodeToken(t Token) error { + p := &enc.p + switch t := t.(type) { + case StartElement: + if err := p.writeStart(&t); err != nil { + return err + } + case EndElement: + if err := p.writeEnd(t.Name); err != nil { + return err + } + case CharData: + EscapeText(p, t) + case Comment: + if bytes.Contains(t, endComment) { + return fmt.Errorf("xml: EncodeToken of Comment containing --> marker") + } + p.WriteString("") + return p.cachedWriteError() + case ProcInst: + // First token to be encoded which is also a ProcInst with target of xml + // is the xml declaration. The only ProcInst where target of xml is allowed. + if t.Target == "xml" && p.Buffered() != 0 { + return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded") + } + if !isNameString(t.Target) { + return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target") + } + if bytes.Contains(t.Inst, endProcInst) { + return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker") + } + p.WriteString(" 0 { + p.WriteByte(' ') + p.Write(t.Inst) + } + p.WriteString("?>") + case Directive: + if bytes.Contains(t, endDirective) { + return fmt.Errorf("xml: EncodeToken of Directive containing > marker") + } + p.WriteString("") + } + return p.cachedWriteError() +} + +// Flush flushes any buffered XML to the underlying writer. +// See the EncodeToken documentation for details about when it is necessary. +func (enc *Encoder) Flush() error { + return enc.p.Flush() +} + +type printer struct { + *bufio.Writer + encoder *Encoder + seq int + indent string + prefix string + depth int + indentedIn bool + putNewline bool + attrNS map[string]string // map prefix -> name space + attrPrefix map[string]string // map name space -> prefix + prefixes []string + tags []Name +} + +// createAttrPrefix finds the name space prefix attribute to use for the given name space, +// defining a new prefix if necessary. It returns the prefix. +func (p *printer) createAttrPrefix(url string) string { + if prefix := p.attrPrefix[url]; prefix != "" { + return prefix + } + + // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml" + // and must be referred to that way. + // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns", + // but users should not be trying to use that one directly - that's our job.) + if url == xmlURL { + return "xml" + } + + // Need to define a new name space. + if p.attrPrefix == nil { + p.attrPrefix = make(map[string]string) + p.attrNS = make(map[string]string) + } + + // Pick a name. We try to use the final element of the path + // but fall back to _. + prefix := strings.TrimRight(url, "/") + if i := strings.LastIndex(prefix, "/"); i >= 0 { + prefix = prefix[i+1:] + } + if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") { + prefix = "_" + } + if strings.HasPrefix(prefix, "xml") { + // xmlanything is reserved. + prefix = "_" + prefix + } + if p.attrNS[prefix] != "" { + // Name is taken. Find a better one. + for p.seq++; ; p.seq++ { + if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" { + prefix = id + break + } + } + } + + p.attrPrefix[url] = prefix + p.attrNS[prefix] = url + + p.WriteString(`xmlns:`) + p.WriteString(prefix) + p.WriteString(`="`) + EscapeText(p, []byte(url)) + p.WriteString(`" `) + + p.prefixes = append(p.prefixes, prefix) + + return prefix +} + +// deleteAttrPrefix removes an attribute name space prefix. +func (p *printer) deleteAttrPrefix(prefix string) { + delete(p.attrPrefix, p.attrNS[prefix]) + delete(p.attrNS, prefix) +} + +func (p *printer) markPrefix() { + p.prefixes = append(p.prefixes, "") +} + +func (p *printer) popPrefix() { + for len(p.prefixes) > 0 { + prefix := p.prefixes[len(p.prefixes)-1] + p.prefixes = p.prefixes[:len(p.prefixes)-1] + if prefix == "" { + break + } + p.deleteAttrPrefix(prefix) + } +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem() + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() +) + +// marshalValue writes one or more XML elements representing val. +// If val was obtained from a struct field, finfo must have its details. +func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error { + if startTemplate != nil && startTemplate.Name.Local == "" { + return fmt.Errorf("xml: EncodeElement of StartElement with missing name") + } + + if !val.IsValid() { + return nil + } + if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) { + return nil + } + + // Drill into interfaces and pointers. + // This can turn into an infinite loop given a cyclic chain, + // but it matches the Go 1 behavior. + for val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr { + if val.IsNil() { + return nil + } + val = val.Elem() + } + + kind := val.Kind() + typ := val.Type() + + // Check for marshaler. + if val.CanInterface() && typ.Implements(marshalerType) { + return p.marshalInterface(val.Interface().(Marshaler), defaultStart(typ, finfo, startTemplate)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(marshalerType) { + return p.marshalInterface(pv.Interface().(Marshaler), defaultStart(pv.Type(), finfo, startTemplate)) + } + } + + // Check for text marshaler. + if val.CanInterface() && typ.Implements(textMarshalerType) { + return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), defaultStart(typ, finfo, startTemplate)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), defaultStart(pv.Type(), finfo, startTemplate)) + } + } + + // Slices and arrays iterate over the elements. They do not have an enclosing tag. + if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 { + for i, n := 0, val.Len(); i < n; i++ { + if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil { + return err + } + } + return nil + } + + tinfo, err := getTypeInfo(typ) + if err != nil { + return err + } + + // Create start element. + // Precedence for the XML element name is: + // 0. startTemplate + // 1. XMLName field in underlying struct; + // 2. field name/tag in the struct field; and + // 3. type name + var start StartElement + + if startTemplate != nil { + start.Name = startTemplate.Name + start.Attr = append(start.Attr, startTemplate.Attr...) + } else if tinfo.xmlname != nil { + xmlname := tinfo.xmlname + if xmlname.name != "" { + start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name + } else if v, ok := xmlname.value(val).Interface().(Name); ok && v.Local != "" { + start.Name = v + } + } + if start.Name.Local == "" && finfo != nil { + start.Name.Space, start.Name.Local = finfo.xmlns, finfo.name + } + if start.Name.Local == "" { + name := typ.Name() + if name == "" { + return &UnsupportedTypeError{typ} + } + start.Name.Local = name + } + + // Add type attribute if necessary + if finfo != nil && finfo.flags&fTypeAttr != 0 { + start.Attr = append(start.Attr, Attr{xmlSchemaInstance, typeToString(typ)}) + } + + // Attributes + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fAttr == 0 { + continue + } + fv := finfo.value(val) + name := Name{Space: finfo.xmlns, Local: finfo.name} + + if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { + continue + } + + if fv.Kind() == reflect.Interface && fv.IsNil() { + continue + } + + if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) { + attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name) + if err != nil { + return err + } + if attr.Name.Local != "" { + start.Attr = append(start.Attr, attr) + } + continue + } + + if fv.CanAddr() { + pv := fv.Addr() + if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) { + attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name) + if err != nil { + return err + } + if attr.Name.Local != "" { + start.Attr = append(start.Attr, attr) + } + continue + } + } + + if fv.CanInterface() && fv.Type().Implements(textMarshalerType) { + text, err := fv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + start.Attr = append(start.Attr, Attr{name, string(text)}) + continue + } + + if fv.CanAddr() { + pv := fv.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + text, err := pv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + start.Attr = append(start.Attr, Attr{name, string(text)}) + continue + } + } + + // Dereference or skip nil pointer, interface values. + switch fv.Kind() { + case reflect.Ptr, reflect.Interface: + if fv.IsNil() { + continue + } + fv = fv.Elem() + } + + s, b, err := p.marshalSimple(fv.Type(), fv) + if err != nil { + return err + } + if b != nil { + s = string(b) + } + start.Attr = append(start.Attr, Attr{name, s}) + } + + if err := p.writeStart(&start); err != nil { + return err + } + + if val.Kind() == reflect.Struct { + err = p.marshalStruct(tinfo, val) + } else { + s, b, err1 := p.marshalSimple(typ, val) + if err1 != nil { + err = err1 + } else if b != nil { + EscapeText(p, b) + } else { + p.EscapeString(s) + } + } + if err != nil { + return err + } + + if err := p.writeEnd(start.Name); err != nil { + return err + } + + return p.cachedWriteError() +} + +// defaultStart returns the default start element to use, +// given the reflect type, field info, and start template. +func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement { + var start StartElement + // Precedence for the XML element name is as above, + // except that we do not look inside structs for the first field. + if startTemplate != nil { + start.Name = startTemplate.Name + start.Attr = append(start.Attr, startTemplate.Attr...) + } else if finfo != nil && finfo.name != "" { + start.Name.Local = finfo.name + start.Name.Space = finfo.xmlns + } else if typ.Name() != "" { + start.Name.Local = typ.Name() + } else { + // Must be a pointer to a named type, + // since it has the Marshaler methods. + start.Name.Local = typ.Elem().Name() + } + + // Add type attribute if necessary + if finfo != nil && finfo.flags&fTypeAttr != 0 { + start.Attr = append(start.Attr, Attr{xmlSchemaInstance, typeToString(typ)}) + } + + return start +} + +// marshalInterface marshals a Marshaler interface value. +func (p *printer) marshalInterface(val Marshaler, start StartElement) error { + // Push a marker onto the tag stack so that MarshalXML + // cannot close the XML tags that it did not open. + p.tags = append(p.tags, Name{}) + n := len(p.tags) + + err := val.MarshalXML(p.encoder, start) + if err != nil { + return err + } + + // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark. + if len(p.tags) > n { + return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local) + } + p.tags = p.tags[:n-1] + return nil +} + +// marshalTextInterface marshals a TextMarshaler interface value. +func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error { + if err := p.writeStart(&start); err != nil { + return err + } + text, err := val.MarshalText() + if err != nil { + return err + } + EscapeText(p, text) + return p.writeEnd(start.Name) +} + +// writeStart writes the given start element. +func (p *printer) writeStart(start *StartElement) error { + if start.Name.Local == "" { + return fmt.Errorf("xml: start tag with no name") + } + + p.tags = append(p.tags, start.Name) + p.markPrefix() + + p.writeIndent(1) + p.WriteByte('<') + p.WriteString(start.Name.Local) + + if start.Name.Space != "" { + p.WriteString(` xmlns="`) + p.EscapeString(start.Name.Space) + p.WriteByte('"') + } + + // Attributes + for _, attr := range start.Attr { + name := attr.Name + if name.Local == "" { + continue + } + p.WriteByte(' ') + if name.Space != "" { + p.WriteString(p.createAttrPrefix(name.Space)) + p.WriteByte(':') + } + p.WriteString(name.Local) + p.WriteString(`="`) + p.EscapeString(attr.Value) + p.WriteByte('"') + } + p.WriteByte('>') + return nil +} + +func (p *printer) writeEnd(name Name) error { + if name.Local == "" { + return fmt.Errorf("xml: end tag with no name") + } + if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" { + return fmt.Errorf("xml: end tag without start tag", name.Local) + } + if top := p.tags[len(p.tags)-1]; top != name { + if top.Local != name.Local { + return fmt.Errorf("xml: end tag does not match start tag <%s>", name.Local, top.Local) + } + return fmt.Errorf("xml: end tag in namespace %s does not match start tag <%s> in namespace %s", name.Local, name.Space, top.Local, top.Space) + } + p.tags = p.tags[:len(p.tags)-1] + + p.writeIndent(-1) + p.WriteByte('<') + p.WriteByte('/') + p.WriteString(name.Local) + p.WriteByte('>') + p.popPrefix() + return nil +} + +func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) { + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(val.Int(), 10), nil, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(val.Uint(), 10), nil, nil + case reflect.Float32, reflect.Float64: + return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil + case reflect.String: + return val.String(), nil, nil + case reflect.Bool: + return strconv.FormatBool(val.Bool()), nil, nil + case reflect.Array: + if typ.Elem().Kind() != reflect.Uint8 { + break + } + // [...]byte + var bytes []byte + if val.CanAddr() { + bytes = val.Slice(0, val.Len()).Bytes() + } else { + bytes = make([]byte, val.Len()) + reflect.Copy(reflect.ValueOf(bytes), val) + } + return "", bytes, nil + case reflect.Slice: + if typ.Elem().Kind() != reflect.Uint8 { + break + } + // []byte + return "", val.Bytes(), nil + } + return "", nil, &UnsupportedTypeError{typ} +} + +var ddBytes = []byte("--") + +func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { + s := parentStack{p: p} + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fAttr != 0 { + continue + } + vf := finfo.value(val) + + // Dereference or skip nil pointer, interface values. + switch vf.Kind() { + case reflect.Ptr, reflect.Interface: + if !vf.IsNil() { + vf = vf.Elem() + } + } + + switch finfo.flags & fMode { + case fCharData: + if vf.CanInterface() && vf.Type().Implements(textMarshalerType) { + data, err := vf.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + Escape(p, data) + continue + } + if vf.CanAddr() { + pv := vf.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + data, err := pv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + Escape(p, data) + continue + } + } + var scratch [64]byte + switch vf.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + Escape(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + Escape(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)) + case reflect.Float32, reflect.Float64: + Escape(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())) + case reflect.Bool: + Escape(p, strconv.AppendBool(scratch[:0], vf.Bool())) + case reflect.String: + if err := EscapeText(p, []byte(vf.String())); err != nil { + return err + } + case reflect.Slice: + if elem, ok := vf.Interface().([]byte); ok { + if err := EscapeText(p, elem); err != nil { + return err + } + } + } + continue + + case fComment: + k := vf.Kind() + if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) { + return fmt.Errorf("xml: bad type for comment field of %s", val.Type()) + } + if vf.Len() == 0 { + continue + } + p.writeIndent(0) + p.WriteString("" is invalid grammar. Make it "- -->" + p.WriteByte(' ') + } + p.WriteString("-->") + continue + + case fInnerXml: + iface := vf.Interface() + switch raw := iface.(type) { + case []byte: + p.Write(raw) + continue + case string: + p.WriteString(raw) + continue + } + + case fElement, fElement | fAny: + if err := s.trim(finfo.parents); err != nil { + return err + } + if len(finfo.parents) > len(s.stack) { + if vf.Kind() != reflect.Ptr && vf.Kind() != reflect.Interface || !vf.IsNil() { + if err := s.push(finfo.parents[len(s.stack):]); err != nil { + return err + } + } + } + } + if err := p.marshalValue(vf, finfo, nil); err != nil { + return err + } + } + s.trim(nil) + return p.cachedWriteError() +} + +// return the bufio Writer's cached write error +func (p *printer) cachedWriteError() error { + _, err := p.Write(nil) + return err +} + +func (p *printer) writeIndent(depthDelta int) { + if len(p.prefix) == 0 && len(p.indent) == 0 { + return + } + if depthDelta < 0 { + p.depth-- + if p.indentedIn { + p.indentedIn = false + return + } + p.indentedIn = false + } + if p.putNewline { + p.WriteByte('\n') + } else { + p.putNewline = true + } + if len(p.prefix) > 0 { + p.WriteString(p.prefix) + } + if len(p.indent) > 0 { + for i := 0; i < p.depth; i++ { + p.WriteString(p.indent) + } + } + if depthDelta > 0 { + p.depth++ + p.indentedIn = true + } +} + +type parentStack struct { + p *printer + stack []string +} + +// trim updates the XML context to match the longest common prefix of the stack +// and the given parents. A closing tag will be written for every parent +// popped. Passing a zero slice or nil will close all the elements. +func (s *parentStack) trim(parents []string) error { + split := 0 + for ; split < len(parents) && split < len(s.stack); split++ { + if parents[split] != s.stack[split] { + break + } + } + for i := len(s.stack) - 1; i >= split; i-- { + if err := s.p.writeEnd(Name{Local: s.stack[i]}); err != nil { + return err + } + } + s.stack = parents[:split] + return nil +} + +// push adds parent elements to the stack and writes open tags. +func (s *parentStack) push(parents []string) error { + for i := 0; i < len(parents); i++ { + if err := s.p.writeStart(&StartElement{Name: Name{Local: parents[i]}}); err != nil { + return err + } + } + s.stack = append(s.stack, parents...) + return nil +} + +// A MarshalXMLError is returned when Marshal encounters a type +// that cannot be converted into XML. +type UnsupportedTypeError struct { + Type reflect.Type +} + +func (e *UnsupportedTypeError) Error() string { + return "xml: unsupported type: " + e.Type.String() +} + +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/read.go b/vendor/github.com/vmware/govmomi/vim25/xml/read.go new file mode 100644 index 0000000000..5b407b7909 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/xml/read.go @@ -0,0 +1,779 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xml + +import ( + "bytes" + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" +) + +// BUG(rsc): Mapping between XML elements and data structures is inherently flawed: +// an XML element is an order-dependent collection of anonymous +// values, while a data structure is an order-independent collection +// of named values. +// See package json for a textual representation more suitable +// to data structures. + +// Unmarshal parses the XML-encoded data and stores the result in +// the value pointed to by v, which must be an arbitrary struct, +// slice, or string. Well-formed data that does not fit into v is +// discarded. +// +// Because Unmarshal uses the reflect package, it can only assign +// to exported (upper case) fields. Unmarshal uses a case-sensitive +// comparison to match XML element names to tag values and struct +// field names. +// +// Unmarshal maps an XML element to a struct using the following rules. +// In the rules, the tag of a field refers to the value associated with the +// key 'xml' in the struct field's tag (see the example above). +// +// * If the struct has a field of type []byte or string with tag +// ",innerxml", Unmarshal accumulates the raw XML nested inside the +// element in that field. The rest of the rules still apply. +// +// * If the struct has a field named XMLName of type xml.Name, +// Unmarshal records the element name in that field. +// +// * If the XMLName field has an associated tag of the form +// "name" or "namespace-URL name", the XML element must have +// the given name (and, optionally, name space) or else Unmarshal +// returns an error. +// +// * If the XML element has an attribute whose name matches a +// struct field name with an associated tag containing ",attr" or +// the explicit name in a struct field tag of the form "name,attr", +// Unmarshal records the attribute value in that field. +// +// * If the XML element contains character data, that data is +// accumulated in the first struct field that has tag ",chardata". +// The struct field may have type []byte or string. +// If there is no such field, the character data is discarded. +// +// * If the XML element contains comments, they are accumulated in +// the first struct field that has tag ",comment". The struct +// field may have type []byte or string. If there is no such +// field, the comments are discarded. +// +// * If the XML element contains a sub-element whose name matches +// the prefix of a tag formatted as "a" or "a>b>c", unmarshal +// will descend into the XML structure looking for elements with the +// given names, and will map the innermost elements to that struct +// field. A tag starting with ">" is equivalent to one starting +// with the field name followed by ">". +// +// * If the XML element contains a sub-element whose name matches +// a struct field's XMLName tag and the struct field has no +// explicit name tag as per the previous rule, unmarshal maps +// the sub-element to that struct field. +// +// * If the XML element contains a sub-element whose name matches a +// field without any mode flags (",attr", ",chardata", etc), Unmarshal +// maps the sub-element to that struct field. +// +// * If the XML element contains a sub-element that hasn't matched any +// of the above rules and the struct has a field with tag ",any", +// unmarshal maps the sub-element to that struct field. +// +// * An anonymous struct field is handled as if the fields of its +// value were part of the outer struct. +// +// * A struct field with tag "-" is never unmarshalled into. +// +// Unmarshal maps an XML element to a string or []byte by saving the +// concatenation of that element's character data in the string or +// []byte. The saved []byte is never nil. +// +// Unmarshal maps an attribute value to a string or []byte by saving +// the value in the string or slice. +// +// Unmarshal maps an XML element to a slice by extending the length of +// the slice and mapping the element to the newly created value. +// +// Unmarshal maps an XML element or attribute value to a bool by +// setting it to the boolean value represented by the string. +// +// Unmarshal maps an XML element or attribute value to an integer or +// floating-point field by setting the field to the result of +// interpreting the string value in decimal. There is no check for +// overflow. +// +// Unmarshal maps an XML element to an xml.Name by recording the +// element name. +// +// Unmarshal maps an XML element to a pointer by setting the pointer +// to a freshly allocated value and then mapping the element to that value. +// +func Unmarshal(data []byte, v interface{}) error { + return NewDecoder(bytes.NewReader(data)).Decode(v) +} + +// Decode works like xml.Unmarshal, except it reads the decoder +// stream to find the start element. +func (d *Decoder) Decode(v interface{}) error { + return d.DecodeElement(v, nil) +} + +// DecodeElement works like xml.Unmarshal except that it takes +// a pointer to the start XML element to decode into v. +// It is useful when a client reads some raw XML tokens itself +// but also wants to defer to Unmarshal for some elements. +func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error { + val := reflect.ValueOf(v) + if val.Kind() != reflect.Ptr { + return errors.New("non-pointer passed to Unmarshal") + } + return d.unmarshal(val.Elem(), start) +} + +// An UnmarshalError represents an error in the unmarshalling process. +type UnmarshalError string + +func (e UnmarshalError) Error() string { return string(e) } + +// Unmarshaler is the interface implemented by objects that can unmarshal +// an XML element description of themselves. +// +// UnmarshalXML decodes a single XML element +// beginning with the given start element. +// If it returns an error, the outer call to Unmarshal stops and +// returns that error. +// UnmarshalXML must consume exactly one XML element. +// One common implementation strategy is to unmarshal into +// a separate value with a layout matching the expected XML +// using d.DecodeElement, and then to copy the data from +// that value into the receiver. +// Another common strategy is to use d.Token to process the +// XML object one token at a time. +// UnmarshalXML may not use d.RawToken. +type Unmarshaler interface { + UnmarshalXML(d *Decoder, start StartElement) error +} + +// UnmarshalerAttr is the interface implemented by objects that can unmarshal +// an XML attribute description of themselves. +// +// UnmarshalXMLAttr decodes a single XML attribute. +// If it returns an error, the outer call to Unmarshal stops and +// returns that error. +// UnmarshalXMLAttr is used only for struct fields with the +// "attr" option in the field tag. +type UnmarshalerAttr interface { + UnmarshalXMLAttr(attr Attr) error +} + +// receiverType returns the receiver type to use in an expression like "%s.MethodName". +func receiverType(val interface{}) string { + t := reflect.TypeOf(val) + if t.Name() != "" { + return t.String() + } + return "(" + t.String() + ")" +} + +// unmarshalInterface unmarshals a single XML element into val. +// start is the opening tag of the element. +func (p *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error { + // Record that decoder must stop at end tag corresponding to start. + p.pushEOF() + + p.unmarshalDepth++ + err := val.UnmarshalXML(p, *start) + p.unmarshalDepth-- + if err != nil { + p.popEOF() + return err + } + + if !p.popEOF() { + return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local) + } + + return nil +} + +// unmarshalTextInterface unmarshals a single XML element into val. +// The chardata contained in the element (but not its children) +// is passed to the text unmarshaler. +func (p *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler, start *StartElement) error { + var buf []byte + depth := 1 + for depth > 0 { + t, err := p.Token() + if err != nil { + return err + } + switch t := t.(type) { + case CharData: + if depth == 1 { + buf = append(buf, t...) + } + case StartElement: + depth++ + case EndElement: + depth-- + } + } + return val.UnmarshalText(buf) +} + +// unmarshalAttr unmarshals a single XML attribute into val. +func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error { + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + + if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) { + return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) + } + } + + // Not an UnmarshalerAttr; try encoding.TextUnmarshaler. + if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) + } + } + + copyValue(val, []byte(attr.Value)) + return nil +} + +var ( + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) + +// Find reflect.Type for an element's type attribute. +func (p *Decoder) typeForElement(val reflect.Value, start *StartElement) reflect.Type { + t := "" + for i, a := range start.Attr { + if a.Name == xmlSchemaInstance { + t = a.Value + // HACK: ensure xsi:type is last in the list to avoid using that value for + // a "type" attribute, such as ManagedObjectReference.Type for example. + // Note that xsi:type is already the last attribute in VC/ESX responses. + // This is only an issue with govmomi simulator generated responses. + // Proper fix will require finding a few needles in this xml package haystack. + x := len(start.Attr) - 1 + if i != x { + start.Attr[i] = start.Attr[x] + start.Attr[x] = a + } + break + } + } + + if t == "" { + // No type attribute; fall back to looking up type by interface name. + t = val.Type().Name() + } + + // Maybe the type is a basic xsd:* type. + typ := stringToType(t) + if typ != nil { + return typ + } + + // Maybe the type is a custom type. + if p.TypeFunc != nil { + if typ, ok := p.TypeFunc(t); ok { + return typ + } + } + + return nil +} + +// Unmarshal a single XML element into val. +func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error { + // Find start element if we need it. + if start == nil { + for { + tok, err := p.Token() + if err != nil { + return err + } + if t, ok := tok.(StartElement); ok { + start = &t + break + } + } + } + + // Try to figure out type for empty interface values. + if val.Kind() == reflect.Interface && val.IsNil() { + typ := p.typeForElement(val, start) + if typ != nil { + pval := reflect.New(typ).Elem() + err := p.unmarshal(pval, start) + if err != nil { + return err + } + + for i := 0; i < 2; i++ { + if typ.Implements(val.Type()) { + val.Set(pval) + return nil + } + + typ = reflect.PtrTo(typ) + pval = pval.Addr() + } + + val.Set(pval) + return nil + } + } + + // Load value from interface, but only if the result will be + // usefully addressable. + if val.Kind() == reflect.Interface && !val.IsNil() { + e := val.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() { + val = e + } + } + + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + + if val.CanInterface() && val.Type().Implements(unmarshalerType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return p.unmarshalInterface(val.Interface().(Unmarshaler), start) + } + + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(unmarshalerType) { + return p.unmarshalInterface(pv.Interface().(Unmarshaler), start) + } + } + + if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { + return p.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler), start) + } + + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + return p.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler), start) + } + } + + var ( + data []byte + saveData reflect.Value + comment []byte + saveComment reflect.Value + saveXML reflect.Value + saveXMLIndex int + saveXMLData []byte + saveAny reflect.Value + sv reflect.Value + tinfo *typeInfo + err error + ) + + switch v := val; v.Kind() { + default: + return errors.New("unknown type " + v.Type().String()) + + case reflect.Interface: + // TODO: For now, simply ignore the field. In the near + // future we may choose to unmarshal the start + // element on it, if not nil. + return p.Skip() + + case reflect.Slice: + typ := v.Type() + if typ.Elem().Kind() == reflect.Uint8 { + // []byte + saveData = v + break + } + + // Slice of element values. + // Grow slice. + n := v.Len() + if n >= v.Cap() { + ncap := 2 * n + if ncap < 4 { + ncap = 4 + } + new := reflect.MakeSlice(typ, n, ncap) + reflect.Copy(new, v) + v.Set(new) + } + v.SetLen(n + 1) + + // Recur to read element into slice. + if err := p.unmarshal(v.Index(n), start); err != nil { + v.SetLen(n) + return err + } + return nil + + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String: + saveData = v + + case reflect.Struct: + typ := v.Type() + if typ == nameType { + v.Set(reflect.ValueOf(start.Name)) + break + } + + sv = v + tinfo, err = getTypeInfo(typ) + if err != nil { + return err + } + + // Validate and assign element name. + if tinfo.xmlname != nil { + finfo := tinfo.xmlname + if finfo.name != "" && finfo.name != start.Name.Local { + return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">") + } + if finfo.xmlns != "" && finfo.xmlns != start.Name.Space { + e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have " + if start.Name.Space == "" { + e += "no name space" + } else { + e += start.Name.Space + } + return UnmarshalError(e) + } + fv := finfo.value(sv) + if _, ok := fv.Interface().(Name); ok { + fv.Set(reflect.ValueOf(start.Name)) + } + } + + // Assign attributes. + // Also, determine whether we need to save character data or comments. + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + switch finfo.flags & fMode { + case fAttr: + strv := finfo.value(sv) + // Look for attribute. + for _, a := range start.Attr { + if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) { + if err := p.unmarshalAttr(strv, a); err != nil { + return err + } + break + } + } + + case fCharData: + if !saveData.IsValid() { + saveData = finfo.value(sv) + } + + case fComment: + if !saveComment.IsValid() { + saveComment = finfo.value(sv) + } + + case fAny, fAny | fElement: + if !saveAny.IsValid() { + saveAny = finfo.value(sv) + } + + case fInnerXml: + if !saveXML.IsValid() { + saveXML = finfo.value(sv) + if p.saved == nil { + saveXMLIndex = 0 + p.saved = new(bytes.Buffer) + } else { + saveXMLIndex = p.savedOffset() + } + } + } + } + } + + // Find end element. + // Process sub-elements along the way. +Loop: + for { + var savedOffset int + if saveXML.IsValid() { + savedOffset = p.savedOffset() + } + tok, err := p.Token() + if err != nil { + return err + } + switch t := tok.(type) { + case StartElement: + consumed := false + if sv.IsValid() { + consumed, err = p.unmarshalPath(tinfo, sv, nil, &t) + if err != nil { + return err + } + if !consumed && saveAny.IsValid() { + consumed = true + if err := p.unmarshal(saveAny, &t); err != nil { + return err + } + } + } + if !consumed { + if err := p.Skip(); err != nil { + return err + } + } + + case EndElement: + if saveXML.IsValid() { + saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset] + if saveXMLIndex == 0 { + p.saved = nil + } + } + break Loop + + case CharData: + if saveData.IsValid() { + data = append(data, t...) + } + + case Comment: + if saveComment.IsValid() { + comment = append(comment, t...) + } + } + } + + if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) { + if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return err + } + saveData = reflect.Value{} + } + + if saveData.IsValid() && saveData.CanAddr() { + pv := saveData.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return err + } + saveData = reflect.Value{} + } + } + + if err := copyValue(saveData, data); err != nil { + return err + } + + switch t := saveComment; t.Kind() { + case reflect.String: + t.SetString(string(comment)) + case reflect.Slice: + t.Set(reflect.ValueOf(comment)) + } + + switch t := saveXML; t.Kind() { + case reflect.String: + t.SetString(string(saveXMLData)) + case reflect.Slice: + t.Set(reflect.ValueOf(saveXMLData)) + } + + return nil +} + +func copyValue(dst reflect.Value, src []byte) (err error) { + dst0 := dst + + if dst.Kind() == reflect.Ptr { + if dst.IsNil() { + dst.Set(reflect.New(dst.Type().Elem())) + } + dst = dst.Elem() + } + + // Save accumulated data. + switch dst.Kind() { + case reflect.Invalid: + // Probably a comment. + default: + return errors.New("cannot unmarshal into " + dst0.Type().String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + dst.SetInt(itmp) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + var utmp uint64 + if len(src) > 0 && src[0] == '-' { + // Negative value for unsigned field. + // Assume it was serialized following two's complement. + itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + // Reinterpret value based on type width. + switch dst.Type().Bits() { + case 8: + utmp = uint64(uint8(itmp)) + case 16: + utmp = uint64(uint16(itmp)) + case 32: + utmp = uint64(uint32(itmp)) + case 64: + utmp = uint64(uint64(itmp)) + } + } else { + utmp, err = strconv.ParseUint(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + } + dst.SetUint(utmp) + case reflect.Float32, reflect.Float64: + ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits()) + if err != nil { + return err + } + dst.SetFloat(ftmp) + case reflect.Bool: + value, err := strconv.ParseBool(strings.TrimSpace(string(src))) + if err != nil { + return err + } + dst.SetBool(value) + case reflect.String: + dst.SetString(string(src)) + case reflect.Slice: + if len(src) == 0 { + // non-nil to flag presence + src = []byte{} + } + dst.SetBytes(src) + } + return nil +} + +// unmarshalPath walks down an XML structure looking for wanted +// paths, and calls unmarshal on them. +// The consumed result tells whether XML elements have been consumed +// from the Decoder until start's matching end element, or if it's +// still untouched because start is uninteresting for sv's fields. +func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) { + recurse := false +Loop: + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space { + continue + } + for j := range parents { + if parents[j] != finfo.parents[j] { + continue Loop + } + } + if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local { + // It's a perfect match, unmarshal the field. + return true, p.unmarshal(finfo.value(sv), start) + } + if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local { + // It's a prefix for the field. Break and recurse + // since it's not ok for one field path to be itself + // the prefix for another field path. + recurse = true + + // We can reuse the same slice as long as we + // don't try to append to it. + parents = finfo.parents[:len(parents)+1] + break + } + } + if !recurse { + // We have no business with this element. + return false, nil + } + // The element is not a perfect match for any field, but one + // or more fields have the path to this element as a parent + // prefix. Recurse and attempt to match these. + for { + var tok Token + tok, err = p.Token() + if err != nil { + return true, err + } + switch t := tok.(type) { + case StartElement: + consumed2, err := p.unmarshalPath(tinfo, sv, parents, &t) + if err != nil { + return true, err + } + if !consumed2 { + if err := p.Skip(); err != nil { + return true, err + } + } + case EndElement: + return true, nil + } + } +} + +// Skip reads tokens until it has consumed the end element +// matching the most recent start element already consumed. +// It recurs if it encounters a start element, so it can be used to +// skip nested structures. +// It returns nil if it finds an end element matching the start +// element; otherwise it returns an error describing the problem. +func (d *Decoder) Skip() error { + for { + tok, err := d.Token() + if err != nil { + return err + } + switch tok.(type) { + case StartElement: + if err := d.Skip(); err != nil { + return err + } + case EndElement: + return nil + } + } +} diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/typeinfo.go b/vendor/github.com/vmware/govmomi/vim25/xml/typeinfo.go new file mode 100644 index 0000000000..086e83b699 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/xml/typeinfo.go @@ -0,0 +1,366 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xml + +import ( + "fmt" + "reflect" + "strings" + "sync" +) + +// typeInfo holds details for the xml representation of a type. +type typeInfo struct { + xmlname *fieldInfo + fields []fieldInfo +} + +// fieldInfo holds details for the xml representation of a single field. +type fieldInfo struct { + idx []int + name string + xmlns string + flags fieldFlags + parents []string +} + +type fieldFlags int + +const ( + fElement fieldFlags = 1 << iota + fAttr + fCharData + fInnerXml + fComment + fAny + + fOmitEmpty + fTypeAttr + + fMode = fElement | fAttr | fCharData | fInnerXml | fComment | fAny +) + +var tinfoMap = make(map[reflect.Type]*typeInfo) +var tinfoLock sync.RWMutex + +var nameType = reflect.TypeOf(Name{}) + +// getTypeInfo returns the typeInfo structure with details necessary +// for marshalling and unmarshalling typ. +func getTypeInfo(typ reflect.Type) (*typeInfo, error) { + tinfoLock.RLock() + tinfo, ok := tinfoMap[typ] + tinfoLock.RUnlock() + if ok { + return tinfo, nil + } + tinfo = &typeInfo{} + if typ.Kind() == reflect.Struct && typ != nameType { + n := typ.NumField() + for i := 0; i < n; i++ { + f := typ.Field(i) + if f.PkgPath != "" || f.Tag.Get("xml") == "-" { + continue // Private field + } + + // For embedded structs, embed its fields. + if f.Anonymous { + t := f.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.Kind() == reflect.Struct { + inner, err := getTypeInfo(t) + if err != nil { + return nil, err + } + if tinfo.xmlname == nil { + tinfo.xmlname = inner.xmlname + } + for _, finfo := range inner.fields { + finfo.idx = append([]int{i}, finfo.idx...) + if err := addFieldInfo(typ, tinfo, &finfo); err != nil { + return nil, err + } + } + continue + } + } + + finfo, err := structFieldInfo(typ, &f) + if err != nil { + return nil, err + } + + if f.Name == "XMLName" { + tinfo.xmlname = finfo + continue + } + + // Add the field if it doesn't conflict with other fields. + if err := addFieldInfo(typ, tinfo, finfo); err != nil { + return nil, err + } + } + } + tinfoLock.Lock() + tinfoMap[typ] = tinfo + tinfoLock.Unlock() + return tinfo, nil +} + +// structFieldInfo builds and returns a fieldInfo for f. +func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, error) { + finfo := &fieldInfo{idx: f.Index} + + // Split the tag from the xml namespace if necessary. + tag := f.Tag.Get("xml") + if i := strings.Index(tag, " "); i >= 0 { + finfo.xmlns, tag = tag[:i], tag[i+1:] + } + + // Parse flags. + tokens := strings.Split(tag, ",") + if len(tokens) == 1 { + finfo.flags = fElement + } else { + tag = tokens[0] + for _, flag := range tokens[1:] { + switch flag { + case "attr": + finfo.flags |= fAttr + case "chardata": + finfo.flags |= fCharData + case "innerxml": + finfo.flags |= fInnerXml + case "comment": + finfo.flags |= fComment + case "any": + finfo.flags |= fAny + case "omitempty": + finfo.flags |= fOmitEmpty + case "typeattr": + finfo.flags |= fTypeAttr + } + } + + // Validate the flags used. + valid := true + switch mode := finfo.flags & fMode; mode { + case 0: + finfo.flags |= fElement + case fAttr, fCharData, fInnerXml, fComment, fAny: + if f.Name == "XMLName" || tag != "" && mode != fAttr { + valid = false + } + default: + // This will also catch multiple modes in a single field. + valid = false + } + if finfo.flags&fMode == fAny { + finfo.flags |= fElement + } + if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 { + valid = false + } + if !valid { + return nil, fmt.Errorf("xml: invalid tag in field %s of type %s: %q", + f.Name, typ, f.Tag.Get("xml")) + } + } + + // Use of xmlns without a name is not allowed. + if finfo.xmlns != "" && tag == "" { + return nil, fmt.Errorf("xml: namespace without name in field %s of type %s: %q", + f.Name, typ, f.Tag.Get("xml")) + } + + if f.Name == "XMLName" { + // The XMLName field records the XML element name. Don't + // process it as usual because its name should default to + // empty rather than to the field name. + finfo.name = tag + return finfo, nil + } + + if tag == "" { + // If the name part of the tag is completely empty, get + // default from XMLName of underlying struct if feasible, + // or field name otherwise. + if xmlname := lookupXMLName(f.Type); xmlname != nil { + finfo.xmlns, finfo.name = xmlname.xmlns, xmlname.name + } else { + finfo.name = f.Name + } + return finfo, nil + } + + // Prepare field name and parents. + parents := strings.Split(tag, ">") + if parents[0] == "" { + parents[0] = f.Name + } + if parents[len(parents)-1] == "" { + return nil, fmt.Errorf("xml: trailing '>' in field %s of type %s", f.Name, typ) + } + finfo.name = parents[len(parents)-1] + if len(parents) > 1 { + if (finfo.flags & fElement) == 0 { + return nil, fmt.Errorf("xml: %s chain not valid with %s flag", tag, strings.Join(tokens[1:], ",")) + } + finfo.parents = parents[:len(parents)-1] + } + + // If the field type has an XMLName field, the names must match + // so that the behavior of both marshalling and unmarshalling + // is straightforward and unambiguous. + if finfo.flags&fElement != 0 { + ftyp := f.Type + xmlname := lookupXMLName(ftyp) + if xmlname != nil && xmlname.name != finfo.name { + return nil, fmt.Errorf("xml: name %q in tag of %s.%s conflicts with name %q in %s.XMLName", + finfo.name, typ, f.Name, xmlname.name, ftyp) + } + } + return finfo, nil +} + +// lookupXMLName returns the fieldInfo for typ's XMLName field +// in case it exists and has a valid xml field tag, otherwise +// it returns nil. +func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) { + for typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + if typ.Kind() != reflect.Struct { + return nil + } + for i, n := 0, typ.NumField(); i < n; i++ { + f := typ.Field(i) + if f.Name != "XMLName" { + continue + } + finfo, err := structFieldInfo(typ, &f) + if finfo.name != "" && err == nil { + return finfo + } + // Also consider errors as a non-existent field tag + // and let getTypeInfo itself report the error. + break + } + return nil +} + +func min(a, b int) int { + if a <= b { + return a + } + return b +} + +// addFieldInfo adds finfo to tinfo.fields if there are no +// conflicts, or if conflicts arise from previous fields that were +// obtained from deeper embedded structures than finfo. In the latter +// case, the conflicting entries are dropped. +// A conflict occurs when the path (parent + name) to a field is +// itself a prefix of another path, or when two paths match exactly. +// It is okay for field paths to share a common, shorter prefix. +func addFieldInfo(typ reflect.Type, tinfo *typeInfo, newf *fieldInfo) error { + var conflicts []int +Loop: + // First, figure all conflicts. Most working code will have none. + for i := range tinfo.fields { + oldf := &tinfo.fields[i] + if oldf.flags&fMode != newf.flags&fMode { + continue + } + if oldf.xmlns != "" && newf.xmlns != "" && oldf.xmlns != newf.xmlns { + continue + } + minl := min(len(newf.parents), len(oldf.parents)) + for p := 0; p < minl; p++ { + if oldf.parents[p] != newf.parents[p] { + continue Loop + } + } + if len(oldf.parents) > len(newf.parents) { + if oldf.parents[len(newf.parents)] == newf.name { + conflicts = append(conflicts, i) + } + } else if len(oldf.parents) < len(newf.parents) { + if newf.parents[len(oldf.parents)] == oldf.name { + conflicts = append(conflicts, i) + } + } else { + if newf.name == oldf.name { + conflicts = append(conflicts, i) + } + } + } + // Without conflicts, add the new field and return. + if conflicts == nil { + tinfo.fields = append(tinfo.fields, *newf) + return nil + } + + // If any conflict is shallower, ignore the new field. + // This matches the Go field resolution on embedding. + for _, i := range conflicts { + if len(tinfo.fields[i].idx) < len(newf.idx) { + return nil + } + } + + // Otherwise, if any of them is at the same depth level, it's an error. + for _, i := range conflicts { + oldf := &tinfo.fields[i] + if len(oldf.idx) == len(newf.idx) { + f1 := typ.FieldByIndex(oldf.idx) + f2 := typ.FieldByIndex(newf.idx) + return &TagPathError{typ, f1.Name, f1.Tag.Get("xml"), f2.Name, f2.Tag.Get("xml")} + } + } + + // Otherwise, the new field is shallower, and thus takes precedence, + // so drop the conflicting fields from tinfo and append the new one. + for c := len(conflicts) - 1; c >= 0; c-- { + i := conflicts[c] + copy(tinfo.fields[i:], tinfo.fields[i+1:]) + tinfo.fields = tinfo.fields[:len(tinfo.fields)-1] + } + tinfo.fields = append(tinfo.fields, *newf) + return nil +} + +// A TagPathError represents an error in the unmarshalling process +// caused by the use of field tags with conflicting paths. +type TagPathError struct { + Struct reflect.Type + Field1, Tag1 string + Field2, Tag2 string +} + +func (e *TagPathError) Error() string { + return fmt.Sprintf("%s field %q with tag %q conflicts with field %q with tag %q", e.Struct, e.Field1, e.Tag1, e.Field2, e.Tag2) +} + +// value returns v's field value corresponding to finfo. +// It's equivalent to v.FieldByIndex(finfo.idx), but initializes +// and dereferences pointers as necessary. +func (finfo *fieldInfo) value(v reflect.Value) reflect.Value { + for i, x := range finfo.idx { + if i > 0 { + t := v.Type() + if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + } + v = v.Field(x) + } + return v +} diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/xml.go b/vendor/github.com/vmware/govmomi/vim25/xml/xml.go new file mode 100644 index 0000000000..6c6c5c8212 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/xml/xml.go @@ -0,0 +1,1939 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xml implements a simple XML 1.0 parser that +// understands XML name spaces. +package xml + +// References: +// Annotated XML spec: http://www.xml.com/axml/testaxml.htm +// XML name spaces: http://www.w3.org/TR/REC-xml-names/ + +// TODO(rsc): +// Test error handling. + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// A SyntaxError represents a syntax error in the XML input stream. +type SyntaxError struct { + Msg string + Line int +} + +func (e *SyntaxError) Error() string { + return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg +} + +// A Name represents an XML name (Local) annotated +// with a name space identifier (Space). +// In tokens returned by Decoder.Token, the Space identifier +// is given as a canonical URL, not the short prefix used +// in the document being parsed. +type Name struct { + Space, Local string +} + +// An Attr represents an attribute in an XML element (Name=Value). +type Attr struct { + Name Name + Value string +} + +// A Token is an interface holding one of the token types: +// StartElement, EndElement, CharData, Comment, ProcInst, or Directive. +type Token interface{} + +// A StartElement represents an XML start element. +type StartElement struct { + Name Name + Attr []Attr +} + +func (e StartElement) Copy() StartElement { + attrs := make([]Attr, len(e.Attr)) + copy(attrs, e.Attr) + e.Attr = attrs + return e +} + +// End returns the corresponding XML end element. +func (e StartElement) End() EndElement { + return EndElement{e.Name} +} + +// An EndElement represents an XML end element. +type EndElement struct { + Name Name +} + +// A CharData represents XML character data (raw text), +// in which XML escape sequences have been replaced by +// the characters they represent. +type CharData []byte + +func makeCopy(b []byte) []byte { + b1 := make([]byte, len(b)) + copy(b1, b) + return b1 +} + +func (c CharData) Copy() CharData { return CharData(makeCopy(c)) } + +// A Comment represents an XML comment of the form . +// The bytes do not include the comment markers. +type Comment []byte + +func (c Comment) Copy() Comment { return Comment(makeCopy(c)) } + +// A ProcInst represents an XML processing instruction of the form +type ProcInst struct { + Target string + Inst []byte +} + +func (p ProcInst) Copy() ProcInst { + p.Inst = makeCopy(p.Inst) + return p +} + +// A Directive represents an XML directive of the form . +// The bytes do not include the markers. +type Directive []byte + +func (d Directive) Copy() Directive { return Directive(makeCopy(d)) } + +// CopyToken returns a copy of a Token. +func CopyToken(t Token) Token { + switch v := t.(type) { + case CharData: + return v.Copy() + case Comment: + return v.Copy() + case Directive: + return v.Copy() + case ProcInst: + return v.Copy() + case StartElement: + return v.Copy() + } + return t +} + +// A Decoder represents an XML parser reading a particular input stream. +// The parser assumes that its input is encoded in UTF-8. +type Decoder struct { + // Strict defaults to true, enforcing the requirements + // of the XML specification. + // If set to false, the parser allows input containing common + // mistakes: + // * If an element is missing an end tag, the parser invents + // end tags as necessary to keep the return values from Token + // properly balanced. + // * In attribute values and character data, unknown or malformed + // character entities (sequences beginning with &) are left alone. + // + // Setting: + // + // d.Strict = false; + // d.AutoClose = HTMLAutoClose; + // d.Entity = HTMLEntity + // + // creates a parser that can handle typical HTML. + // + // Strict mode does not enforce the requirements of the XML name spaces TR. + // In particular it does not reject name space tags using undefined prefixes. + // Such tags are recorded with the unknown prefix as the name space URL. + Strict bool + + // When Strict == false, AutoClose indicates a set of elements to + // consider closed immediately after they are opened, regardless + // of whether an end element is present. + AutoClose []string + + // Entity can be used to map non-standard entity names to string replacements. + // The parser behaves as if these standard mappings are present in the map, + // regardless of the actual map content: + // + // "lt": "<", + // "gt": ">", + // "amp": "&", + // "apos": "'", + // "quot": `"`, + Entity map[string]string + + // CharsetReader, if non-nil, defines a function to generate + // charset-conversion readers, converting from the provided + // non-UTF-8 charset into UTF-8. If CharsetReader is nil or + // returns an error, parsing stops with an error. One of the + // the CharsetReader's result values must be non-nil. + CharsetReader func(charset string, input io.Reader) (io.Reader, error) + + // DefaultSpace sets the default name space used for unadorned tags, + // as if the entire XML stream were wrapped in an element containing + // the attribute xmlns="DefaultSpace". + DefaultSpace string + + // TypeFunc is used to map type names to actual types. + TypeFunc func(string) (reflect.Type, bool) + + r io.ByteReader + buf bytes.Buffer + saved *bytes.Buffer + stk *stack + free *stack + needClose bool + toClose Name + nextToken Token + nextByte int + ns map[string]string + err error + line int + unmarshalDepth int +} + +// NewDecoder creates a new XML parser reading from r. +// If r does not implement io.ByteReader, NewDecoder will +// do its own buffering. +func NewDecoder(r io.Reader) *Decoder { + d := &Decoder{ + ns: make(map[string]string), + nextByte: -1, + line: 1, + Strict: true, + } + d.switchToReader(r) + return d +} + +// Token returns the next XML token in the input stream. +// At the end of the input stream, Token returns nil, io.EOF. +// +// Slices of bytes in the returned token data refer to the +// parser's internal buffer and remain valid only until the next +// call to Token. To acquire a copy of the bytes, call CopyToken +// or the token's Copy method. +// +// Token expands self-closing elements such as
+// into separate start and end elements returned by successive calls. +// +// Token guarantees that the StartElement and EndElement +// tokens it returns are properly nested and matched: +// if Token encounters an unexpected end element, +// it will return an error. +// +// Token implements XML name spaces as described by +// http://www.w3.org/TR/REC-xml-names/. Each of the +// Name structures contained in the Token has the Space +// set to the URL identifying its name space when known. +// If Token encounters an unrecognized name space prefix, +// it uses the prefix as the Space rather than report an error. +func (d *Decoder) Token() (t Token, err error) { + if d.stk != nil && d.stk.kind == stkEOF { + err = io.EOF + return + } + if d.nextToken != nil { + t = d.nextToken + d.nextToken = nil + } else if t, err = d.rawToken(); err != nil { + return + } + + if !d.Strict { + if t1, ok := d.autoClose(t); ok { + d.nextToken = t + t = t1 + } + } + switch t1 := t.(type) { + case StartElement: + // In XML name spaces, the translations listed in the + // attributes apply to the element name and + // to the other attribute names, so process + // the translations first. + for _, a := range t1.Attr { + if a.Name.Space == "xmlns" { + v, ok := d.ns[a.Name.Local] + d.pushNs(a.Name.Local, v, ok) + d.ns[a.Name.Local] = a.Value + } + if a.Name.Space == "" && a.Name.Local == "xmlns" { + // Default space for untagged names + v, ok := d.ns[""] + d.pushNs("", v, ok) + d.ns[""] = a.Value + } + } + + d.translate(&t1.Name, true) + for i := range t1.Attr { + d.translate(&t1.Attr[i].Name, false) + } + d.pushElement(t1.Name) + t = t1 + + case EndElement: + d.translate(&t1.Name, true) + if !d.popElement(&t1) { + return nil, d.err + } + t = t1 + } + return +} + +const xmlURL = "http://www.w3.org/XML/1998/namespace" + +// Apply name space translation to name n. +// The default name space (for Space=="") +// applies only to element names, not to attribute names. +func (d *Decoder) translate(n *Name, isElementName bool) { + switch { + case n.Space == "xmlns": + return + case n.Space == "" && !isElementName: + return + case n.Space == "xml": + n.Space = xmlURL + case n.Space == "" && n.Local == "xmlns": + return + } + if v, ok := d.ns[n.Space]; ok { + n.Space = v + } else if n.Space == "" { + n.Space = d.DefaultSpace + } +} + +func (d *Decoder) switchToReader(r io.Reader) { + // Get efficient byte at a time reader. + // Assume that if reader has its own + // ReadByte, it's efficient enough. + // Otherwise, use bufio. + if rb, ok := r.(io.ByteReader); ok { + d.r = rb + } else { + d.r = bufio.NewReader(r) + } +} + +// Parsing state - stack holds old name space translations +// and the current set of open elements. The translations to pop when +// ending a given tag are *below* it on the stack, which is +// more work but forced on us by XML. +type stack struct { + next *stack + kind int + name Name + ok bool +} + +const ( + stkStart = iota + stkNs + stkEOF +) + +func (d *Decoder) push(kind int) *stack { + s := d.free + if s != nil { + d.free = s.next + } else { + s = new(stack) + } + s.next = d.stk + s.kind = kind + d.stk = s + return s +} + +func (d *Decoder) pop() *stack { + s := d.stk + if s != nil { + d.stk = s.next + s.next = d.free + d.free = s + } + return s +} + +// Record that after the current element is finished +// (that element is already pushed on the stack) +// Token should return EOF until popEOF is called. +func (d *Decoder) pushEOF() { + // Walk down stack to find Start. + // It might not be the top, because there might be stkNs + // entries above it. + start := d.stk + for start.kind != stkStart { + start = start.next + } + // The stkNs entries below a start are associated with that + // element too; skip over them. + for start.next != nil && start.next.kind == stkNs { + start = start.next + } + s := d.free + if s != nil { + d.free = s.next + } else { + s = new(stack) + } + s.kind = stkEOF + s.next = start.next + start.next = s +} + +// Undo a pushEOF. +// The element must have been finished, so the EOF should be at the top of the stack. +func (d *Decoder) popEOF() bool { + if d.stk == nil || d.stk.kind != stkEOF { + return false + } + d.pop() + return true +} + +// Record that we are starting an element with the given name. +func (d *Decoder) pushElement(name Name) { + s := d.push(stkStart) + s.name = name +} + +// Record that we are changing the value of ns[local]. +// The old value is url, ok. +func (d *Decoder) pushNs(local string, url string, ok bool) { + s := d.push(stkNs) + s.name.Local = local + s.name.Space = url + s.ok = ok +} + +// Creates a SyntaxError with the current line number. +func (d *Decoder) syntaxError(msg string) error { + return &SyntaxError{Msg: msg, Line: d.line} +} + +// Record that we are ending an element with the given name. +// The name must match the record at the top of the stack, +// which must be a pushElement record. +// After popping the element, apply any undo records from +// the stack to restore the name translations that existed +// before we saw this element. +func (d *Decoder) popElement(t *EndElement) bool { + s := d.pop() + name := t.Name + switch { + case s == nil || s.kind != stkStart: + d.err = d.syntaxError("unexpected end element ") + return false + case s.name.Local != name.Local: + if !d.Strict { + d.needClose = true + d.toClose = t.Name + t.Name = s.name + return true + } + d.err = d.syntaxError("element <" + s.name.Local + "> closed by ") + return false + case s.name.Space != name.Space: + d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space + + "closed by in space " + name.Space) + return false + } + + // Pop stack until a Start or EOF is on the top, undoing the + // translations that were associated with the element we just closed. + for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF { + s := d.pop() + if s.ok { + d.ns[s.name.Local] = s.name.Space + } else { + delete(d.ns, s.name.Local) + } + } + + return true +} + +// If the top element on the stack is autoclosing and +// t is not the end tag, invent the end tag. +func (d *Decoder) autoClose(t Token) (Token, bool) { + if d.stk == nil || d.stk.kind != stkStart { + return nil, false + } + name := strings.ToLower(d.stk.name.Local) + for _, s := range d.AutoClose { + if strings.ToLower(s) == name { + // This one should be auto closed if t doesn't close it. + et, ok := t.(EndElement) + if !ok || et.Name.Local != name { + return EndElement{d.stk.name}, true + } + break + } + } + return nil, false +} + +var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method") + +// RawToken is like Token but does not verify that +// start and end elements match and does not translate +// name space prefixes to their corresponding URLs. +func (d *Decoder) RawToken() (Token, error) { + if d.unmarshalDepth > 0 { + return nil, errRawToken + } + return d.rawToken() +} + +func (d *Decoder) rawToken() (Token, error) { + if d.err != nil { + return nil, d.err + } + if d.needClose { + // The last element we read was self-closing and + // we returned just the StartElement half. + // Return the EndElement half now. + d.needClose = false + return EndElement{d.toClose}, nil + } + + b, ok := d.getc() + if !ok { + return nil, d.err + } + + if b != '<' { + // Text section. + d.ungetc(b) + data := d.text(-1, false) + if data == nil { + return nil, d.err + } + return CharData(data), nil + } + + if b, ok = d.mustgetc(); !ok { + return nil, d.err + } + switch b { + case '/': + // ' { + d.err = d.syntaxError("invalid characters between ") + return nil, d.err + } + return EndElement{name}, nil + + case '?': + // ' { + break + } + b0 = b + } + data := d.buf.Bytes() + data = data[0 : len(data)-2] // chop ?> + + if target == "xml" { + enc := procInstEncoding(string(data)) + if enc != "" && enc != "utf-8" && enc != "UTF-8" { + if d.CharsetReader == nil { + d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc) + return nil, d.err + } + newr, err := d.CharsetReader(enc, d.r.(io.Reader)) + if err != nil { + d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err) + return nil, d.err + } + if newr == nil { + panic("CharsetReader returned a nil Reader for charset " + enc) + } + d.switchToReader(newr) + } + } + return ProcInst{target, data}, nil + + case '!': + // ' { + break + } + b0, b1 = b1, b + } + data := d.buf.Bytes() + data = data[0 : len(data)-3] // chop --> + return Comment(data), nil + + case '[': // . + data := d.text(-1, true) + if data == nil { + return nil, d.err + } + return CharData(data), nil + } + + // Probably a directive: , , etc. + // We don't care, but accumulate for caller. Quoted angle + // brackets do not count for nesting. + d.buf.Reset() + d.buf.WriteByte(b) + inquote := uint8(0) + depth := 0 + for { + if b, ok = d.mustgetc(); !ok { + return nil, d.err + } + if inquote == 0 && b == '>' && depth == 0 { + break + } + HandleB: + d.buf.WriteByte(b) + switch { + case b == inquote: + inquote = 0 + + case inquote != 0: + // in quotes, no special action + + case b == '\'' || b == '"': + inquote = b + + case b == '>' && inquote == 0: + depth-- + + case b == '<' && inquote == 0: + // Look for